)]}'
{"doc/source/tutorial/hashring.rst":[{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"65bdc697c3f92284ef160aa35ff3adfafe0e4603","unresolved":false,"context_lines":[{"line_number":1,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":2,"context_line":" Hashring"},{"line_number":3,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":4,"context_line":""},{"line_number":5,"context_line":"Tooz provides a consistent hashring implementation. It allows to map objects"}],"source_content_type":"text/x-rst","patch_set":18,"id":"3a71b18c_55e7dfe3","line":2,"updated":"2016-12-01 21:06:14.000000000","message":"Grammatically, I think it is \u0027hash ring\u0027 (two words).\nbut maybe you want this to be \u0027Hashring\u0027 to reflect the name of the file.","commit_id":"e2b9a0333a9e36fa0a4293cebd3a65190a71e3ae"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"4eada0d4bcdabd883574c76bdd6e6e112eb1dba4","unresolved":false,"context_lines":[{"line_number":1,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":2,"context_line":" Hashring"},{"line_number":3,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":4,"context_line":""},{"line_number":5,"context_line":"Tooz provides a consistent hashring implementation. It allows to map objects"}],"source_content_type":"text/x-rst","patch_set":18,"id":"3a71b18c_adfe0a36","line":2,"in_reply_to":"3a71b18c_55e7dfe3","updated":"2016-12-02 12:47:54.000000000","message":"nah i\u0027m good with grammar, let\u0027s fix it.","commit_id":"e2b9a0333a9e36fa0a4293cebd3a65190a71e3ae"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"65bdc697c3f92284ef160aa35ff3adfafe0e4603","unresolved":false,"context_lines":[{"line_number":2,"context_line":" Hashring"},{"line_number":3,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":4,"context_line":""},{"line_number":5,"context_line":"Tooz provides a consistent hashring implementation. It allows to map objects"},{"line_number":6,"context_line":"(represented via binary keys) to one or several nodes. When the node list"},{"line_number":7,"context_line":"changes, the rebalancing of objects across the ring is kept minimal."},{"line_number":8,"context_line":""}],"source_content_type":"text/x-rst","patch_set":18,"id":"3a71b18c_3530a356","line":5,"updated":"2016-12-01 21:06:14.000000000","message":"s/hashring/hash ring/\n\nmaybe s/It allows to/It can be used to/","commit_id":"e2b9a0333a9e36fa0a4293cebd3a65190a71e3ae"}],"examples/hashring.py":[{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"65bdc697c3f92284ef160aa35ff3adfafe0e4603","unresolved":false,"context_lines":[{"line_number":2,"context_line":""},{"line_number":3,"context_line":"hashring \u003d hashring.HashRing({\u0027node1\u0027, \u0027node2\u0027, \u0027node3\u0027})"},{"line_number":4,"context_line":"nodes_for_foo \u003d hashring[b\u0027foo\u0027]"},{"line_number":5,"context_line":"# Returns set([\u0027node2\u0027])"},{"line_number":6,"context_line":"nodes_for_foo_with_replicas \u003d hashring.get_nodes(b\u0027foo\u0027,"},{"line_number":7,"context_line":"                                                 replicas\u003d2)"},{"line_number":8,"context_line":"# Returns set([\u0027node2\u0027, \u0027node3\u0027])"}],"source_content_type":"text/x-python","patch_set":18,"id":"3a71b18c_556d1f03","line":5,"updated":"2016-12-01 21:06:14.000000000","message":"I\u0027m not an oslo person and maybe oslo has a convention about this. Does this line refer to the line above or to the line below? I think above. If so, what do you think about adding a blank line after this, to make that more obvious?","commit_id":"e2b9a0333a9e36fa0a4293cebd3a65190a71e3ae"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"4eada0d4bcdabd883574c76bdd6e6e112eb1dba4","unresolved":false,"context_lines":[{"line_number":2,"context_line":""},{"line_number":3,"context_line":"hashring \u003d hashring.HashRing({\u0027node1\u0027, \u0027node2\u0027, \u0027node3\u0027})"},{"line_number":4,"context_line":"nodes_for_foo \u003d hashring[b\u0027foo\u0027]"},{"line_number":5,"context_line":"# Returns set([\u0027node2\u0027])"},{"line_number":6,"context_line":"nodes_for_foo_with_replicas \u003d hashring.get_nodes(b\u0027foo\u0027,"},{"line_number":7,"context_line":"                                                 replicas\u003d2)"},{"line_number":8,"context_line":"# Returns set([\u0027node2\u0027, \u0027node3\u0027])"}],"source_content_type":"text/x-python","patch_set":18,"id":"3a71b18c_a8e35804","line":5,"in_reply_to":"3a71b18c_556d1f03","updated":"2016-12-02 12:47:54.000000000","message":"There\u0027s no convention. I\u0027ll change that.\nActually it\u0027s more obvious to me to have it on right or before, not after. Don\u0027t know why I did that in the first place :(","commit_id":"e2b9a0333a9e36fa0a4293cebd3a65190a71e3ae"}],"releasenotes/notes/hashring-0470f9119ef63d49.yaml":[{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"65bdc697c3f92284ef160aa35ff3adfafe0e4603","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - Add `tooz.hashring`, a consistent hashring implementation."}],"source_content_type":"text/x-yaml","patch_set":18,"id":"3a71b18c_95541755","line":3,"updated":"2016-12-01 21:06:14.000000000","message":"nit: s/hashring/hash ring/","commit_id":"e2b9a0333a9e36fa0a4293cebd3a65190a71e3ae"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"4eada0d4bcdabd883574c76bdd6e6e112eb1dba4","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - Add `tooz.hashring`, a consistent hashring implementation."}],"source_content_type":"text/x-yaml","patch_set":18,"id":"3a71b18c_e8ee30b3","line":3,"in_reply_to":"3a71b18c_95541755","updated":"2016-12-02 12:47:54.000000000","message":"Done","commit_id":"e2b9a0333a9e36fa0a4293cebd3a65190a71e3ae"}],"tooz/hashring.py":[{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"35683b48e60e0c4de612956f35b3ef0fee331167","unresolved":false,"context_lines":[{"line_number":42,"context_line":"        :param node: Node to add."},{"line_number":43,"context_line":"        \"\"\""},{"line_number":44,"context_line":"        key \u003d str(node).encode(\u0027utf-8\u0027)"},{"line_number":45,"context_line":"        key_hash \u003d hashlib.md5(key)"},{"line_number":46,"context_line":"        for r in six.moves.range(self._partition_number):"},{"line_number":47,"context_line":"            key_hash.update(key)"},{"line_number":48,"context_line":"            self._ring[self._hash2int(key_hash)] \u003d node"}],"source_content_type":"text/x-python","patch_set":8,"id":"7a77a97e_982a4e7d","line":45,"updated":"2016-11-16 16:51:06.000000000","message":"Curious why md5 (likely doesn\u0027t matter for this use-case, but just wondering).\n\nPerhaps it should be a class var:\n\n  hash_algo \u003d \u0027md5\u0027\n\nThen just use:\n\n  hasher \u003d hashlib.new(self.hash_algo)\n\n?","commit_id":"13082276534f155c84511606db425c8003184b27"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"94a022248fdd6ca40456787213a7b7d8832a1020","unresolved":false,"context_lines":[{"line_number":42,"context_line":"        :param node: Node to add."},{"line_number":43,"context_line":"        \"\"\""},{"line_number":44,"context_line":"        key \u003d str(node).encode(\u0027utf-8\u0027)"},{"line_number":45,"context_line":"        key_hash \u003d hashlib.md5(key)"},{"line_number":46,"context_line":"        for r in six.moves.range(self._partition_number):"},{"line_number":47,"context_line":"            key_hash.update(key)"},{"line_number":48,"context_line":"            self._ring[self._hash2int(key_hash)] \u003d node"}],"source_content_type":"text/x-python","patch_set":8,"id":"7a77a97e_f01eeb61","line":45,"in_reply_to":"7a77a97e_5f0975dc","updated":"2016-11-16 22:14:03.000000000","message":"I\u0027ll let that as an implementation detail then, since I don\u0027t think anyone will have a good reason to change it. We can still add an option later if needed :)","commit_id":"13082276534f155c84511606db425c8003184b27"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"1d6ac5146fea7e94cc57f9527dfb1d02c0781599","unresolved":false,"context_lines":[{"line_number":42,"context_line":"        :param node: Node to add."},{"line_number":43,"context_line":"        \"\"\""},{"line_number":44,"context_line":"        key \u003d str(node).encode(\u0027utf-8\u0027)"},{"line_number":45,"context_line":"        key_hash \u003d hashlib.md5(key)"},{"line_number":46,"context_line":"        for r in six.moves.range(self._partition_number):"},{"line_number":47,"context_line":"            key_hash.update(key)"},{"line_number":48,"context_line":"            self._ring[self._hash2int(key_hash)] \u003d node"}],"source_content_type":"text/x-python","patch_set":8,"id":"7a77a97e_f34c4344","line":45,"in_reply_to":"7a77a97e_982a4e7d","updated":"2016-11-16 17:10:00.000000000","message":"sure, good idea\n\nI picked md5 because everybody picked it, I don\u0027t think it really matters","commit_id":"13082276534f155c84511606db425c8003184b27"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"5d1663f481d0dce66e3ba258e156ffe2f39d87fb","unresolved":false,"context_lines":[{"line_number":42,"context_line":"        :param node: Node to add."},{"line_number":43,"context_line":"        \"\"\""},{"line_number":44,"context_line":"        key \u003d str(node).encode(\u0027utf-8\u0027)"},{"line_number":45,"context_line":"        key_hash \u003d hashlib.md5(key)"},{"line_number":46,"context_line":"        for r in six.moves.range(self._partition_number):"},{"line_number":47,"context_line":"            key_hash.update(key)"},{"line_number":48,"context_line":"            self._ring[self._hash2int(key_hash)] \u003d node"}],"source_content_type":"text/x-python","patch_set":8,"id":"7a77a97e_5f0975dc","line":45,"in_reply_to":"7a77a97e_f34c4344","updated":"2016-11-16 19:54:14.000000000","message":"Yeah, I think md5 is fine. It\u0027s probably one of the faster choices here, is the reason it was picked.","commit_id":"13082276534f155c84511606db425c8003184b27"},{"author":{"_account_id":10343,"name":"Jim Rollenhagen","email":"jim@jimrollenhagen.com","username":"jimrollenhagen"},"change_message_id":"5d1663f481d0dce66e3ba258e156ffe2f39d87fb","unresolved":false,"context_lines":[{"line_number":68,"context_line":"    def _hash2int(key):"},{"line_number":69,"context_line":"        return int(key.hexdigest(), 16)"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"    def _get_partition(self, data):"},{"line_number":72,"context_line":"        hashed_key \u003d self._hash2int(hashlib.md5(data))"},{"line_number":73,"context_line":"        position \u003d bisect.bisect(self._partitions, hashed_key)"},{"line_number":74,"context_line":"        return position if position \u003c len(self._partitions) else 0"}],"source_content_type":"text/x-python","patch_set":8,"id":"7a77a97e_ffc5e13b","line":71,"updated":"2016-11-16 19:54:14.000000000","message":"ironic\u0027s hash ring begins this with:\n\n    if six.PY3 and data is not None:\n        data \u003d data.encode(\u0027utf-8\u0027)\n\nNot sure if/why that was added, but wanted to point it out.","commit_id":"13082276534f155c84511606db425c8003184b27"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"94a022248fdd6ca40456787213a7b7d8832a1020","unresolved":false,"context_lines":[{"line_number":68,"context_line":"    def _hash2int(key):"},{"line_number":69,"context_line":"        return int(key.hexdigest(), 16)"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"    def _get_partition(self, data):"},{"line_number":72,"context_line":"        hashed_key \u003d self._hash2int(hashlib.md5(data))"},{"line_number":73,"context_line":"        position \u003d bisect.bisect(self._partitions, hashed_key)"},{"line_number":74,"context_line":"        return position if position \u003c len(self._partitions) else 0"}],"source_content_type":"text/x-python","patch_set":8,"id":"7a77a97e_b0147344","line":71,"in_reply_to":"7a77a97e_ffc5e13b","updated":"2016-11-16 22:14:03.000000000","message":"Yeah I noticed there was some. It\u0027s generally bad practice to do that in lib, I prefer for the app to be responsible to pass \"bytes\", that\u0027s what we do in tooz everywhere, we expect bytes everywhere. :)","commit_id":"13082276534f155c84511606db425c8003184b27"},{"author":{"_account_id":12853,"name":"Kevin Quick","email":"quick@sparq.org"},"change_message_id":"39a6257d6d0b16c68c315ab642d76788d6afc341","unresolved":false,"context_lines":[{"line_number":94,"context_line":"        nodes \u003d set()"},{"line_number":95,"context_line":"        for replica in six.moves.range(0, replicas):"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"            if len(nodes) \u003d\u003d len(candidates):"},{"line_number":98,"context_line":"                # Prevent infinite loop, cannot allocate more replicas"},{"line_number":99,"context_line":"                break"},{"line_number":100,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"7a77a97e_8c956988","line":97,"updated":"2016-11-17 22:04:05.000000000","message":"As I understand this code, the danger of an infinite loop is actually in the while loop below at line 102 (exhausting the set of unique nodes retrievable by walking the partitions), but the min setting of replicas in line 92 should ensure that there\u0027s always a node for the while loop to find.  If my understanding is correct, the location of this if statement is misleading and it\u0027s probably unnecessary; can it be removed?","commit_id":"c197234b2164e85880703c3f79d473d14a6a6aba"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"6299c93e0b72f1f559db939b312e05fd97f824fb","unresolved":false,"context_lines":[{"line_number":94,"context_line":"        nodes \u003d set()"},{"line_number":95,"context_line":"        for replica in six.moves.range(0, replicas):"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"            if len(nodes) \u003d\u003d len(candidates):"},{"line_number":98,"context_line":"                # Prevent infinite loop, cannot allocate more replicas"},{"line_number":99,"context_line":"                break"},{"line_number":100,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"7a77a97e_9f28119c","line":97,"in_reply_to":"7a77a97e_8c956988","updated":"2016-11-18 13:26:27.000000000","message":"Good catch, indeed it seems this not necessary. :) Removed.","commit_id":"c197234b2164e85880703c3f79d473d14a6a6aba"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"983942dfee26dd8734493791baca599bbe78453a","unresolved":false,"context_lines":[{"line_number":41,"context_line":""},{"line_number":42,"context_line":"        :param node: Node to add."},{"line_number":43,"context_line":"        \"\"\""},{"line_number":44,"context_line":"        key \u003d str(node).encode(\u0027utf-8\u0027)"},{"line_number":45,"context_line":"        key_hash \u003d hashlib.md5(key)"},{"line_number":46,"context_line":"        for r in six.moves.range(self._partition_number):"},{"line_number":47,"context_line":"            key_hash.update(key)"}],"source_content_type":"text/x-python","patch_set":13,"id":"7a77a97e_9270f873","line":44,"updated":"2016-11-18 18:59:55.000000000","message":"Why not just call bytes(node)?\n\nOr look for some kind of hash attribute on a object, and if that doesn\u0027t exist, then fallback to this?","commit_id":"fbb35d0cef77abac2b7914b831a568f08a9b7097"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"cbf1a849705802e0e0f11670842a4201199b2542","unresolved":false,"context_lines":[{"line_number":41,"context_line":""},{"line_number":42,"context_line":"        :param node: Node to add."},{"line_number":43,"context_line":"        \"\"\""},{"line_number":44,"context_line":"        key \u003d str(node).encode(\u0027utf-8\u0027)"},{"line_number":45,"context_line":"        key_hash \u003d hashlib.md5(key)"},{"line_number":46,"context_line":"        for r in six.moves.range(self._partition_number):"},{"line_number":47,"context_line":"            key_hash.update(key)"}],"source_content_type":"text/x-python","patch_set":13,"id":"7a77a97e_cce70845","line":44,"in_reply_to":"7a77a97e_9270f873","updated":"2016-11-21 12:01:34.000000000","message":"bytes(node) does not work if node is a string, you need an encoding – that\u0027s what this line does.\n\nWe can build a hash… if the object is bytes, ha! that\u0027s the whole point of this line :p","commit_id":"fbb35d0cef77abac2b7914b831a568f08a9b7097"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"78c6ff71e68ee46c9e8aa6aec0e53e422b93c4c0","unresolved":false,"context_lines":[{"line_number":91,"context_line":""},{"line_number":92,"context_line":"        replicas \u003d min(replicas, len(candidates))"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"        nodes \u003d set()"},{"line_number":95,"context_line":"        for replica in six.moves.range(0, replicas):"},{"line_number":96,"context_line":"            node \u003d self._get_node(partition)"},{"line_number":97,"context_line":"            while node in nodes or node in ignore_nodes:"}],"source_content_type":"text/x-python","patch_set":13,"id":"5a74a57a_7b4a0585","line":94,"updated":"2016-11-23 21:50:19.000000000","message":"Should this be a list?, docstring says its a list and a set :-P","commit_id":"fbb35d0cef77abac2b7914b831a568f08a9b7097"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"cb5fa35d179e159ffcf41fc714e2fff746f0a116","unresolved":false,"context_lines":[{"line_number":91,"context_line":""},{"line_number":92,"context_line":"        replicas \u003d min(replicas, len(candidates))"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"        nodes \u003d set()"},{"line_number":95,"context_line":"        for replica in six.moves.range(0, replicas):"},{"line_number":96,"context_line":"            node \u003d self._get_node(partition)"},{"line_number":97,"context_line":"            while node in nodes or node in ignore_nodes:"}],"source_content_type":"text/x-python","patch_set":13,"id":"5a74a57a_1f51e60e","line":94,"in_reply_to":"5a74a57a_7b4a0585","updated":"2016-11-24 09:26:37.000000000","message":"Done","commit_id":"fbb35d0cef77abac2b7914b831a568f08a9b7097"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"65bdc697c3f92284ef160aa35ff3adfafe0e4603","unresolved":false,"context_lines":[{"line_number":48,"context_line":"            self._ring[self._hash2int(key_hash)] \u003d node"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"        self.nodes.add(node)"},{"line_number":51,"context_line":"        self._partitions \u003d sorted(self._ring.keys())"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    def remove_node(self, node):"},{"line_number":54,"context_line":"        \"\"\"Remove a node from the hashring."}],"source_content_type":"text/x-python","patch_set":18,"id":"3a71b18c_f81d42be","line":51,"updated":"2016-12-01 21:06:14.000000000","message":"I can see why this is here, and it is probably fine. I was just wondering, though, if someone would use this hashring with large N of nodes, or large number of partitions. When initializing a HashRing, we\u0027re going to be sorting these (sub)lists N times, but only want the final sorted list.","commit_id":"e2b9a0333a9e36fa0a4293cebd3a65190a71e3ae"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"4eada0d4bcdabd883574c76bdd6e6e112eb1dba4","unresolved":false,"context_lines":[{"line_number":48,"context_line":"            self._ring[self._hash2int(key_hash)] \u003d node"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"        self.nodes.add(node)"},{"line_number":51,"context_line":"        self._partitions \u003d sorted(self._ring.keys())"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    def remove_node(self, node):"},{"line_number":54,"context_line":"        \"\"\"Remove a node from the hashring."}],"source_content_type":"text/x-python","patch_set":18,"id":"3a71b18c_08bd2c68","line":51,"in_reply_to":"3a71b18c_5007e61b","updated":"2016-12-02 12:47:54.000000000","message":"Done","commit_id":"e2b9a0333a9e36fa0a4293cebd3a65190a71e3ae"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"5a2130bae754d60e12681f0c61c18889597e9c06","unresolved":false,"context_lines":[{"line_number":48,"context_line":"            self._ring[self._hash2int(key_hash)] \u003d node"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"        self.nodes.add(node)"},{"line_number":51,"context_line":"        self._partitions \u003d sorted(self._ring.keys())"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    def remove_node(self, node):"},{"line_number":54,"context_line":"        \"\"\"Remove a node from the hashring."}],"source_content_type":"text/x-python","patch_set":18,"id":"3a71b18c_5007e61b","line":51,"in_reply_to":"3a71b18c_909b3ec9","updated":"2016-12-02 00:17:07.000000000","message":"++","commit_id":"e2b9a0333a9e36fa0a4293cebd3a65190a71e3ae"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"1e1e890dcf558cee5819411cb7f3804a8fba286e","unresolved":false,"context_lines":[{"line_number":48,"context_line":"            self._ring[self._hash2int(key_hash)] \u003d node"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"        self.nodes.add(node)"},{"line_number":51,"context_line":"        self._partitions \u003d sorted(self._ring.keys())"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    def remove_node(self, node):"},{"line_number":54,"context_line":"        \"\"\"Remove a node from the hashring."}],"source_content_type":"text/x-python","patch_set":18,"id":"3a71b18c_909b3ec9","line":51,"in_reply_to":"3a71b18c_f81d42be","updated":"2016-12-01 23:44:22.000000000","message":"Good idea, perhaps better to have a _add_node function that doesn\u0027t do the sorting, then call it from this method, and call it (then do the one final sort) in the __init__?","commit_id":"e2b9a0333a9e36fa0a4293cebd3a65190a71e3ae"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"65bdc697c3f92284ef160aa35ff3adfafe0e4603","unresolved":false,"context_lines":[{"line_number":59,"context_line":"        key_hash \u003d hashlib.md5(key)"},{"line_number":60,"context_line":"        for r in six.moves.range(self._partition_number):"},{"line_number":61,"context_line":"            key_hash.update(key)"},{"line_number":62,"context_line":"            del self._ring[self._hash2int(key_hash)]"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"        self.nodes.remove(node)"},{"line_number":65,"context_line":"        self._partitions \u003d sorted(self._ring.keys())"}],"source_content_type":"text/x-python","patch_set":18,"id":"3a71b18c_f3ad6389","line":62,"updated":"2016-12-01 21:06:14.000000000","message":"What should this method do if the node isn\u0027t/wasn\u0027t in the hash ring?","commit_id":"e2b9a0333a9e36fa0a4293cebd3a65190a71e3ae"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"4eada0d4bcdabd883574c76bdd6e6e112eb1dba4","unresolved":false,"context_lines":[{"line_number":59,"context_line":"        key_hash \u003d hashlib.md5(key)"},{"line_number":60,"context_line":"        for r in six.moves.range(self._partition_number):"},{"line_number":61,"context_line":"            key_hash.update(key)"},{"line_number":62,"context_line":"            del self._ring[self._hash2int(key_hash)]"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"        self.nodes.remove(node)"},{"line_number":65,"context_line":"        self._partitions \u003d sorted(self._ring.keys())"}],"source_content_type":"text/x-python","patch_set":18,"id":"3a71b18c_eeb63989","line":62,"in_reply_to":"3a71b18c_f3ad6389","updated":"2016-12-02 12:47:54.000000000","message":"Done","commit_id":"e2b9a0333a9e36fa0a4293cebd3a65190a71e3ae"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"65bdc697c3f92284ef160aa35ff3adfafe0e4603","unresolved":false,"context_lines":[{"line_number":77,"context_line":"        return self._ring[self._partitions[partition]]"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"    def get_nodes(self, data, ignore_nodes\u003dNone, replicas\u003d1):"},{"line_number":80,"context_line":"        \"\"\"Get the set of nodes which the supplied key maps onto."},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"        :param data: A byte identifier to be mapped across the ring."},{"line_number":83,"context_line":"        :param ignore_nodes: Set of nodes to ignore."}],"source_content_type":"text/x-python","patch_set":18,"id":"3a71b18c_18bcbe6b","line":80,"updated":"2016-12-01 21:06:14.000000000","message":"by \u0027key\u0027, you mean \u0027data\u0027, right?","commit_id":"e2b9a0333a9e36fa0a4293cebd3a65190a71e3ae"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"4eada0d4bcdabd883574c76bdd6e6e112eb1dba4","unresolved":false,"context_lines":[{"line_number":77,"context_line":"        return self._ring[self._partitions[partition]]"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"    def get_nodes(self, data, ignore_nodes\u003dNone, replicas\u003d1):"},{"line_number":80,"context_line":"        \"\"\"Get the set of nodes which the supplied key maps onto."},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"        :param data: A byte identifier to be mapped across the ring."},{"line_number":83,"context_line":"        :param ignore_nodes: Set of nodes to ignore."}],"source_content_type":"text/x-python","patch_set":18,"id":"3a71b18c_d1b91ccd","line":80,"in_reply_to":"3a71b18c_18bcbe6b","updated":"2016-12-02 12:47:54.000000000","message":"Done","commit_id":"e2b9a0333a9e36fa0a4293cebd3a65190a71e3ae"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"65bdc697c3f92284ef160aa35ff3adfafe0e4603","unresolved":false,"context_lines":[{"line_number":87,"context_line":"        partition \u003d self._get_partition(data)"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"        ignore_nodes \u003d set(ignore_nodes) if ignore_nodes else set()"},{"line_number":90,"context_line":"        candidates \u003d self.nodes - set(ignore_nodes)"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"        replicas \u003d min(replicas, len(candidates))"},{"line_number":93,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"3a71b18c_d806c61f","line":90,"updated":"2016-12-01 21:06:14.000000000","message":"nit: ignore_nodes is already a set","commit_id":"e2b9a0333a9e36fa0a4293cebd3a65190a71e3ae"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"4eada0d4bcdabd883574c76bdd6e6e112eb1dba4","unresolved":false,"context_lines":[{"line_number":87,"context_line":"        partition \u003d self._get_partition(data)"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"        ignore_nodes \u003d set(ignore_nodes) if ignore_nodes else set()"},{"line_number":90,"context_line":"        candidates \u003d self.nodes - set(ignore_nodes)"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"        replicas \u003d min(replicas, len(candidates))"},{"line_number":93,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"3a71b18c_51c6ec49","line":90,"in_reply_to":"3a71b18c_d806c61f","updated":"2016-12-02 12:47:54.000000000","message":"Done","commit_id":"e2b9a0333a9e36fa0a4293cebd3a65190a71e3ae"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"0dff70ea6d879159628a628f446db9d2ae0356f7","unresolved":false,"context_lines":[{"line_number":24,"context_line":"class UnknownNode(tooz.ToozError):"},{"line_number":25,"context_line":"    \"\"\"Node is unknown.\"\"\""},{"line_number":26,"context_line":"    def __init__(self, node):"},{"line_number":27,"context_line":"        super(UnknownNode, self).__init__(\"Unknown node `%s\u0027\" % node)"},{"line_number":28,"context_line":"        self.node \u003d node"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"3a71b18c_cd1c9f6c","line":27,"updated":"2016-12-06 15:37:30.000000000","message":"not sure, but it looks like you have two diff kinds of \u0027single\u0027 quotations surrounding %s.","commit_id":"2b7245c897551af76173c20d41a1d2e7d6478c76"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"542c980b18da6be79a9337d839d98b7ff8af6de5","unresolved":false,"context_lines":[{"line_number":24,"context_line":"class UnknownNode(tooz.ToozError):"},{"line_number":25,"context_line":"    \"\"\"Node is unknown.\"\"\""},{"line_number":26,"context_line":"    def __init__(self, node):"},{"line_number":27,"context_line":"        super(UnknownNode, self).__init__(\"Unknown node `%s\u0027\" % node)"},{"line_number":28,"context_line":"        self.node \u003d node"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"3a71b18c_590e838c","line":27,"in_reply_to":"3a71b18c_39aaa785","updated":"2016-12-06 21:01:58.000000000","message":"I\u0027m young and people use Lisp for real :p\n\nI can fix it though it\u0027s not broken to me, unless there\u0027s some convention around I ignore in Python or something?","commit_id":"2b7245c897551af76173c20d41a1d2e7d6478c76"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"aa9e294064b24568d415e3fed134cbbe642ecc7f","unresolved":false,"context_lines":[{"line_number":24,"context_line":"class UnknownNode(tooz.ToozError):"},{"line_number":25,"context_line":"    \"\"\"Node is unknown.\"\"\""},{"line_number":26,"context_line":"    def __init__(self, node):"},{"line_number":27,"context_line":"        super(UnknownNode, self).__init__(\"Unknown node `%s\u0027\" % node)"},{"line_number":28,"context_line":"        self.node \u003d node"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"3a71b18c_24643eb7","line":27,"in_reply_to":"3a71b18c_590e838c","updated":"2016-12-06 21:20:36.000000000","message":"Cool (that Lisp is still being used). I didn\u0027t look at the string to see how it appears. If you don\u0027t think it is broken, then fine with me.","commit_id":"2b7245c897551af76173c20d41a1d2e7d6478c76"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"3d646f1eec986b41726364216b81b29251a1685f","unresolved":false,"context_lines":[{"line_number":24,"context_line":"class UnknownNode(tooz.ToozError):"},{"line_number":25,"context_line":"    \"\"\"Node is unknown.\"\"\""},{"line_number":26,"context_line":"    def __init__(self, node):"},{"line_number":27,"context_line":"        super(UnknownNode, self).__init__(\"Unknown node `%s\u0027\" % node)"},{"line_number":28,"context_line":"        self.node \u003d node"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"3a71b18c_39aaa785","line":27,"in_reply_to":"3a71b18c_b3aee02b","updated":"2016-12-06 20:55:41.000000000","message":"Do people still use Lisp? (Or are you old-ish?)\n\nI thought you would fix this if you did another patch set :-(","commit_id":"2b7245c897551af76173c20d41a1d2e7d6478c76"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"bb1206d0c2272c1593fc3fe502efc3c978177d31","unresolved":false,"context_lines":[{"line_number":24,"context_line":"class UnknownNode(tooz.ToozError):"},{"line_number":25,"context_line":"    \"\"\"Node is unknown.\"\"\""},{"line_number":26,"context_line":"    def __init__(self, node):"},{"line_number":27,"context_line":"        super(UnknownNode, self).__init__(\"Unknown node `%s\u0027\" % node)"},{"line_number":28,"context_line":"        self.node \u003d node"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"3a71b18c_b3aee02b","line":27,"in_reply_to":"3a71b18c_cd1c9f6c","updated":"2016-12-06 16:39:02.000000000","message":"You\u0027re right, it\u0027s a reminiscence of my Lisp hat. :)","commit_id":"2b7245c897551af76173c20d41a1d2e7d6478c76"}]}
