Skip to content

Instantly share code, notes, and snippets.

@kurtbrose
Last active August 29, 2015 14:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kurtbrose/25b48114de216a5e55df to your computer and use it in GitHub Desktop.
Save kurtbrose/25b48114de216a5e55df to your computer and use it in GitHub Desktop.
Assigns arbitrary weakref-able objects the smallest possible unique integer IDs, such that no two objects have the same ID at the same time.
import weakref
import heapq
class Aliaser(object):
'''
Assigns arbitrary weakref-able objects the smallest possible unique
integer IDs, such that no two objects have the same ID at the same
time.
'''
def __init__(self):
self.mapping = weakref.WeakKeyDictionary()
self.ref_map = {}
self.free = []
def get(self, a):
if a in self.mapping: # if mapping exists, return it
return self.mapping[a][0]
if self.free: # if there are any free numbers, use the smallest
nxt = heapq.heappop(self.free)
else: # if there are no free numbers, use the next highest number
nxt = len(self.mapping)
ref = weakref.ref(a, self._clean)
self.mapping[a] = (nxt, ref)
self.ref_map[ref] = nxt
return nxt
def drop(self, a):
freed, ref = self.mapping[a]
del self.mapping[a]
del self.ref_map[ref]
heapq.heappush(self.free, freed)
def _clean(self, ref):
heapq.heappush(self.free, self.ref_map[ref])
del self.ref_map[ref]
def __contains__(self, a):
return a in self.mapping
def __iter__(self):
return self.mapping.itervalues()
def __len__(self):
return self.mapping.__len__()
def iteritems(self):
return self.mapping.iteritems()
def test():
aliaser = Aliaser()
class Foo(object): pass
# use this circular array to have them periodically collected
ref_wheel = [None, None, None]
for i in range(1000):
nxt = Foo()
ref_wheel[i % len(ref_wheel)] = nxt
assert aliaser.get(nxt) <= len(ref_wheel)
if i % 10 == 0:
aliaser.drop(nxt)
if __name__ == "__main__":
test()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment