浏览代码

Add support for key hash tags in redis-cluster (Redis 3.0.0b1).

Multi-keys operations are not allowed even when keys generate the same
hash but this will probably be supported in later betas of Redis which
means we will basically end up reusing the whole strategy used for
client-side sharding.

Ported from the v0.8 branch.
Daniele Alessandri 11 年之前
父节点
当前提交
26289f47ec
共有 2 个文件被更改,包括 27 次插入6 次删除
  1. 22 1
      lib/Predis/Cluster/RedisStrategy.php
  2. 5 5
      tests/Predis/Cluster/RedisStrategyTest.php

+ 22 - 1
lib/Predis/Cluster/RedisStrategy.php

@@ -289,6 +289,27 @@ class RedisStrategy implements StrategyInterface
      */
     public function getKeyHash($key)
     {
-        return $this->hashGenerator->hash($key);
+        $key = $this->extractKeyTag($key);
+        $hash = $this->hashGenerator->hash($key);
+
+        return $hash;
+    }
+
+    /**
+     * Returns only the hashable part of a key (delimited by "{...}"), or the
+     * whole key if a key tag is not found in the string.
+     *
+     * @param  string $key A key.
+     * @return string
+     */
+    protected function extractKeyTag($key)
+    {
+        if (false !== $start = strpos($key, '{')) {
+            if (false !== $end = strpos($key, '}', $start)) {
+                $key = substr($key, ++$start, $end - $start);
+            }
+        }
+
+        return $key;
     }
 }

+ 5 - 5
tests/Predis/Cluster/RedisStrategyTest.php

@@ -22,14 +22,14 @@ class RedisStrategyTest extends PredisTestCase
     /**
      * @group disconnected
      */
-    public function testDoesNotSupportKeyTags()
+    public function testSupportsKeyTags()
     {
         $strategy = $this->getClusterStrategy();
 
-        $this->assertSame(35910, $strategy->getKeyHash('{foo}'));
-        $this->assertSame(60032, $strategy->getKeyHash('{foo}:bar'));
-        $this->assertSame(27528, $strategy->getKeyHash('{foo}:baz'));
-        $this->assertSame(34064, $strategy->getKeyHash('bar:{foo}:bar'));
+        $this->assertSame(44950, $strategy->getKeyHash('{foo}'));
+        $this->assertSame(44950, $strategy->getKeyHash('{foo}:bar'));
+        $this->assertSame(44950, $strategy->getKeyHash('{foo}:baz'));
+        $this->assertSame(44950, $strategy->getKeyHash('bar:{foo}:bar'));
     }
 
     /**