Key tags support made optional.

The regular expression in the key tags code leads to a 20% performance hit,
so it's disabled by default.
This commit is contained in:
Murilo Queiroz
2010-09-30 18:14:32 -03:00
parent 6da1852d0d
commit 39618506e4
3 changed files with 33 additions and 8 deletions

View File

@@ -4,6 +4,7 @@ import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern;
import redis.clients.jedis.Client.LIST_POSITION; import redis.clients.jedis.Client.LIST_POSITION;
import redis.clients.util.Hashing; import redis.clients.util.Hashing;
@@ -19,6 +20,14 @@ public class ShardedJedis extends Sharded<Jedis,JedisShardInfo> {
super(shards, algo); super(shards, algo);
} }
public ShardedJedis(List<JedisShardInfo> shards, Pattern keyTagPattern) {
super(shards, keyTagPattern);
}
public ShardedJedis(List<JedisShardInfo> shards, Hashing algo, Pattern keyTagPattern) {
super(shards, algo, keyTagPattern);
}
public String set(String key, String value) { public String set(String key, String value) {
Jedis j = getShard(key); Jedis j = getShard(key);
return j.set(key, value); return j.set(key, value);

View File

@@ -8,15 +8,19 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
public class Sharded<R, S extends ShardInfo<R>> { public class Sharded<R, S extends ShardInfo<R>> {
public static final int DEFAULT_WEIGHT = 1;
public static final int DEFAULT_WEIGHT = 1;
private TreeMap<Long, S> nodes; private TreeMap<Long, S> nodes;
private final Hashing algo; private final Hashing algo;
/** /**
* The default pattern used for extracting a key tag. * The default pattern used for extracting a key tag.
* The pattern must have a group (between parenthesis), which delimits the tag to be hashed. * The pattern must have a group (between parenthesis), which delimits the tag to be hashed.
* A null pattern avoids applying the regular expression for each lookup, improving performance a little bit
* is key tags aren't being used.
*/ */
private Pattern tagPattern = Pattern.compile("\\{(.+?)\\}"); // the tag is anything between {} private Pattern tagPattern = null;
public static final Pattern DEFAULT_KEY_TAG_PATTERN = Pattern.compile("\\{(.+?)\\}"); // the tag is anything between {}
public Sharded(List<S> shards) { public Sharded(List<S> shards) {
this(shards, Hashing.MURMUR_HASH); // MD5 is really not good as we works with 64-bits not 128 this(shards, Hashing.MURMUR_HASH); // MD5 is really not good as we works with 64-bits not 128
@@ -74,9 +78,11 @@ public class Sharded<R, S extends ShardInfo<R>> {
* @return The tag if it exists, or the original key * @return The tag if it exists, or the original key
*/ */
public String getKeyTag(String key){ public String getKeyTag(String key){
Matcher m = tagPattern.matcher(key); if (tagPattern != null){
if (m.find()) Matcher m = tagPattern.matcher(key);
return m.group(1); if (m.find())
return m.group(1);
}
return key; return key;
} }

View File

@@ -13,6 +13,7 @@ import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.tests.HostAndPortUtil.HostAndPort; import redis.clients.jedis.tests.HostAndPortUtil.HostAndPort;
import redis.clients.util.Hashing; import redis.clients.util.Hashing;
import redis.clients.util.ShardInfo; import redis.clients.util.ShardInfo;
import redis.clients.util.Sharded;
public class ShardedJedisTest extends Assert { public class ShardedJedisTest extends Assert {
private static HostAndPort redis1 = HostAndPortUtil.getRedisServers().get(0); private static HostAndPort redis1 = HostAndPortUtil.getRedisServers().get(0);
@@ -90,7 +91,7 @@ public class ShardedJedisTest extends Assert {
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>(); List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
shards.add(new JedisShardInfo(redis1.host, redis1.port)); shards.add(new JedisShardInfo(redis1.host, redis1.port));
shards.add(new JedisShardInfo(redis2.host, redis2.port)); shards.add(new JedisShardInfo(redis2.host, redis2.port));
ShardedJedis jedis = new ShardedJedis(shards); ShardedJedis jedis = new ShardedJedis(shards, ShardedJedis.DEFAULT_KEY_TAG_PATTERN);
assertEquals(jedis.getKeyTag("foo"),"foo"); assertEquals(jedis.getKeyTag("foo"),"foo");
assertEquals(jedis.getKeyTag("foo{bar}"),"bar"); assertEquals(jedis.getKeyTag("foo{bar}"),"bar");
@@ -98,13 +99,22 @@ public class ShardedJedisTest extends Assert {
assertEquals(jedis.getKeyTag("{bar}foo"),"bar"); // Key tag may appear anywhere assertEquals(jedis.getKeyTag("{bar}foo"),"bar"); // Key tag may appear anywhere
assertEquals(jedis.getKeyTag("f{bar}oo"),"bar"); // Key tag may appear anywhere assertEquals(jedis.getKeyTag("f{bar}oo"),"bar"); // Key tag may appear anywhere
ShardInfo s1 = jedis.getShardInfo("a{bar}"); ShardInfo s1 = jedis.getShardInfo("abc{bar}");
ShardInfo s2 = jedis.getShardInfo("b{bar}"); ShardInfo s2 = jedis.getShardInfo("foo{bar}");
assertSame(s1, s2); assertSame(s1, s2);
ShardInfo s3 = jedis.getShardInfo("a"); ShardInfo s3 = jedis.getShardInfo("a");
ShardInfo s4 = jedis.getShardInfo("b"); ShardInfo s4 = jedis.getShardInfo("b");
assertNotSame(s3, s4); assertNotSame(s3, s4);
ShardedJedis jedis2 = new ShardedJedis(shards);
assertEquals(jedis2.getKeyTag("foo"),"foo");
assertNotSame(jedis2.getKeyTag("foo{bar}"),"bar");
ShardInfo s5 = jedis2.getShardInfo("foo{bar}");
ShardInfo s6 = jedis2.getShardInfo("abc{bar}");
assertNotSame(s5, s6);
} }
} }