Skip to content

Instantly share code, notes, and snippets.

@sunetos
Created July 6, 2011 21:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sunetos/1068329 to your computer and use it in GitHub Desktop.
Save sunetos/1068329 to your computer and use it in GitHub Desktop.
Simple Python ID Allocation Pool
__author__ = 'Adam R. Smith'
class IDPool(object):
'''
Create a pool of IDs to allow reuse. The "new_id" function generates the next
valid ID from the previous one. If not given, defaults to incrementing an integer.
'''
def __init__(self, new_id=None):
if new_id is None: new_id = lambda x: x + 1
self.ids_in_use = set()
self.ids_free = set()
self.new_id = new_id
self.last_id = 0
def get_id(self):
if len(self.ids_free) > 0:
return self.ids_free.pop()
self.last_id = id_ = self.new_id(self.last_id)
self.ids_in_use.add(id_)
return id_
def release_id(self, the_id):
if the_id in self.ids_in_use:
self.ids_in_use.remove(the_id)
self.ids_free.add(the_id)
if __name__ == '__main__':
pool = IDPool()
for i in xrange(5):
print 'got id: %d' % pool.get_id()
print 'releasing id 3'
pool.release_id(3)
print 'got id: %d' % pool.get_id()
print 'got id: %d' % pool.get_id()
@simonzhu24
Copy link

simonzhu24 commented Dec 5, 2017

@sunetos, great work! I enjoyed reading your code 👍

I am a little new to the idea of an id allocation, could you help explain it a little to me? It seems to me that this is similar to the idea of a threadpool, there is a pool of id's and initially they all need to be released so the user can then use them one at a time. So there are 2 API's:

int get_id(self)
void release_id(self, id)

I understand that you are using 2 Sets to represent a pool of available id's and a pool of unavailable id's. When you release an id, you check if its unavailable, then remove it from the pool of unavailable and put it into the available. However, when you get an id, you check the available pool (which makes sense) and remove it from there and return. However, don't you also need to put that ID into the unavailable pool so you can correctly process it next time you call release_id()?

When you call get_id() but an id is not available, I understand that you increment a counter to keep track. I have seen in other online codes use an int id to keep track of count when an id is not available. But don't fully understand its purpose. Can you help me explain a little? Like what does the counter represent and how is it useful?

Also, why use an anonymous function new_id = lambda x: x + 1 to keep track of the count? Can we just use a global / instance / class variable instead? In the function, then you can just do x++; :)

Haha, sorry to post such a long comment, but I am really trying to understand the full meaning behind this code as I have an interview coming up. What is the purpose of:
self.last_id = id_ = self.new_id(self.last_id), you don't use id_ anywhere else except to return. Can't you just call self.last_id = self.new_id(self.last_id) and then return self.last_id? Or is there some restrictions in python preventing you from doing so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment