Skip to content

Instantly share code, notes, and snippets.

@poros
Last active October 30, 2015 01:40
Show Gist options
  • Save poros/9376ab678f404a0f6e9d to your computer and use it in GitHub Desktop.
Save poros/9376ab678f404a0f6e9d to your computer and use it in GitHub Desktop.
Containers and magic methods
from md5 import md5
class FakeHashRing(object):
def __init__(self, nodes):
self.nodes = list(nodes)
def _hash(self, key):
return int(md5(str(key).encode('utf-8')).hexdigest(), 16) % len(self.nodes)
def __len__(self):
return len(self.nodes)
def __getitem__(self, key):
return self.nodes[self._hash(key)]
def __setitem__(self, key, value):
self.nodes[self._hash(key)] = value
def __delitem__(self, key):
self.nodes.remove(self._hash(key))
def __iter__(self):
return iter(self.nodes)
def __contains__(self, node):
return node in self.nodes
def remove(self, node):
if node not in self:
raise ValueError("node not in the ring")
self.nodes.remove(node)
def add(self, node):
self.nodes.append(node)
h = FakeHashRing(["what", "a", "wonderful", "hash", "ring"])
# __len__
len(h) # 5
# __getitem__
h["foo"] # 'what'
h["bar"] # 'what'
h["baz"] # 'ring'
h[17] # 'wonderful'
# __contains__ (but __iter__ seems enough)
"what" in h
True
"bar" in h
False
# __len__ and __iter__
# (__getitem__ can substitute __iter__,
# but here we have an infinite loop because it never raises IndexError)
for node in h:
print node
# "what", "a", "wonderful", "hash", "ring"
# __setitem__
h["foo"] = "lupo"
# __delitem__
del h["foo"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment