浏览代码

Bugfix: wrap-around differences for HashRing and KetamaPureRing.

Daniele Alessandri 15 年之前
父节点
当前提交
1ba033879a
共有 1 个文件被更改,包括 15 次插入4 次删除
  1. 15 4
      lib/Predis.php

+ 15 - 4
lib/Predis.php

@@ -1463,9 +1463,6 @@ class HashRing implements IRing {
     }
 
     private function getNodeKey($key) {
-        // NOTE: binary search for the last item in _ringkeys with a value
-        //       less or equal to the key. If no such item exists, return the 
-        //       last item.
         $this->initialize();
         $ringKeys = $this->_ringKeys;
         $upper = count($ringKeys) - 1;
@@ -1484,7 +1481,14 @@ class HashRing implements IRing {
                 return $item;
             }
         }
-        return $ringKeys[$lower < count($ringKeys) ? $lower : 0];
+        return $ringKeys[$this->wrapAroundStrategy($upper, $lower, count($ringKeys))];
+    }
+
+    protected function wrapAroundStrategy($upper, $lower, $ringKeysCount) {
+        // NOTE: binary search for the last item in _ringkeys with a value 
+        //       less or equal to the key. If no such item exists, return the 
+        //       last item.
+        return $upper >= 0 ? $upper : $ringKeysCount - 1;
     }
 }
 
@@ -1511,6 +1515,13 @@ class KetamaPureRing extends HashRing {
         $hash = unpack('V', md5($value, true));
         return $hash[1];
     }
+
+    protected function wrapAroundStrategy($upper, $lower, $ringKeysCount) {
+        // NOTE: binary search for the first item in _ringkeys with a value 
+        //       greater or equal to the key. If no such item exists, return the 
+        //       first item.
+        return $lower < $ringKeysCount ? $lower : 0;
+    }
 }
 
 abstract class MultiBulkResponseIteratorBase implements \Iterator, \Countable {