From 48771521905b4e3f2ac95e628e4bc18832dbd8d8 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sat, 12 Sep 2015 19:28:56 +0300 Subject: [PATCH] lexRange, lexRangeHead and lexRangeTail methods added. #135 --- .../org/redisson/RedissonScoredSortedSet.java | 53 +++++++++++++++---- .../client/protocol/RedisCommands.java | 1 + .../org/redisson/core/RScoredSortedSet.java | 6 +++ .../redisson/core/RScoredSortedSetAsync.java | 6 +++ .../redisson/RedissonScoredSortedSetTest.java | 46 ++++++++++++++++ 5 files changed, 103 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/redisson/RedissonScoredSortedSet.java b/src/main/java/org/redisson/RedissonScoredSortedSet.java index 8c51b17b5..92ef84920 100644 --- a/src/main/java/org/redisson/RedissonScoredSortedSet.java +++ b/src/main/java/org/redisson/RedissonScoredSortedSet.java @@ -277,6 +277,42 @@ public class RedissonScoredSortedSet extends RedissonExpirable implements RSc return commandExecutor.readAsync(getName(), RedisCommands.ZRANGE_ENTRY, getName(), startIndex, endIndex, "WITHSCORES"); } + @Override + public Collection lexRange(V fromElement, boolean fromInclusive, V toElement, boolean toInclusive) { + return get(lexRangeAsync(fromElement, fromInclusive, toElement, toInclusive)); + } + + @Override + public Collection lexRangeHead(V toElement, boolean toInclusive) { + return get(lexRangeHeadAsync(toElement, toInclusive)); + } + + @Override + public Future> lexRangeHeadAsync(V toElement, boolean toInclusive) { + String toValue = value(toElement, toInclusive); + return commandExecutor.readAsync(getName(), StringCodec.INSTANCE, RedisCommands.ZRANGEBYLEX, getName(), "-", toValue); + } + + @Override + public Collection lexRangeTail(V fromElement, boolean fromInclusive) { + return get(lexRangeTailAsync(fromElement, fromInclusive)); + } + + @Override + public Future> lexRangeTailAsync(V fromElement, boolean fromInclusive) { + String fromValue = value(fromElement, fromInclusive); + return commandExecutor.readAsync(getName(), StringCodec.INSTANCE, RedisCommands.ZRANGEBYLEX, getName(), fromValue, "+"); + } + + + @Override + public Future> lexRangeAsync(V fromElement, boolean fromInclusive, V toElement, boolean toInclusive) { + String fromValue = value(fromElement, fromInclusive); + String toValue = value(toElement, toInclusive); + + return commandExecutor.readAsync(getName(), StringCodec.INSTANCE, RedisCommands.ZRANGEBYLEX, getName(), fromValue, toValue); + } + @Override public Integer lexCount(V fromElement, boolean fromInclusive, V toElement, boolean toInclusive) { return get(lexCountAsync(fromElement, fromInclusive, toElement, toInclusive)); @@ -284,21 +320,20 @@ public class RedissonScoredSortedSet extends RedissonExpirable implements RSc @Override public Future lexCountAsync(V fromElement, boolean fromInclusive, V toElement, boolean toInclusive) { + String fromValue = value(fromElement, fromInclusive); + String toValue = value(toElement, toInclusive); + + return commandExecutor.readAsync(getName(), RedisCommands.ZLEXCOUNT, getName(), fromValue, toValue); + } + + private String value(V fromElement, boolean fromInclusive) { String fromValue = fromElement.toString(); if (fromInclusive) { fromValue = "[" + fromValue; } else { fromValue = "(" + fromValue; } - - String toValue = toElement.toString(); - if (toInclusive) { - toValue = "[" + toValue; - } else { - toValue = "(" + toValue; - } - - return commandExecutor.readAsync(getName(), RedisCommands.ZLEXCOUNT, getName(), fromValue, toValue); + return fromValue; } } diff --git a/src/main/java/org/redisson/client/protocol/RedisCommands.java b/src/main/java/org/redisson/client/protocol/RedisCommands.java index 4d9000830..0fc389ce5 100644 --- a/src/main/java/org/redisson/client/protocol/RedisCommands.java +++ b/src/main/java/org/redisson/client/protocol/RedisCommands.java @@ -56,6 +56,7 @@ public interface RedisCommands { RedisStrictCommand ZSCORE = new RedisStrictCommand("ZSCORE", new DoubleReplayConvertor()); RedisStrictCommand ZRANK = new RedisStrictCommand("ZRANK", new IntegerReplayConvertor()); RedisCommand> ZRANGE = new RedisCommand>("ZRANGE", new ObjectListReplayDecoder()); + RedisCommand> ZRANGEBYLEX = new RedisCommand>("ZRANGEBYLEX", new ObjectListReplayDecoder()); RedisCommand>> ZRANGE_ENTRY = new RedisCommand>>("ZRANGE", new ScoredSortedSetReplayDecoder()); RedisCommand> ZSCAN = new RedisCommand>("ZSCAN", new NestedMultiDecoder(new ObjectListReplayDecoder(), new ScoredSortedSetScanReplayDecoder()), ValueType.OBJECT); RedisStrictCommand ZINCRBY = new RedisStrictCommand("ZINCRBY", new DoubleReplayConvertor()); diff --git a/src/main/java/org/redisson/core/RScoredSortedSet.java b/src/main/java/org/redisson/core/RScoredSortedSet.java index 12bb19aef..0bd11216f 100644 --- a/src/main/java/org/redisson/core/RScoredSortedSet.java +++ b/src/main/java/org/redisson/core/RScoredSortedSet.java @@ -21,6 +21,12 @@ import org.redisson.client.protocol.ScoredEntry; public interface RScoredSortedSet extends RScoredSortedSetAsync, Iterable, RExpirable { + Collection lexRangeTail(V fromElement, boolean fromInclusive); + + Collection lexRangeHead(V toElement, boolean toInclusive); + + Collection lexRange(V fromElement, boolean fromInclusive, V toElement, boolean toInclusive); + Integer lexCount(V fromElement, boolean fromInclusive, V toElement, boolean toInclusive); Integer rank(V o); diff --git a/src/main/java/org/redisson/core/RScoredSortedSetAsync.java b/src/main/java/org/redisson/core/RScoredSortedSetAsync.java index 8802fa45f..5e9b7f013 100644 --- a/src/main/java/org/redisson/core/RScoredSortedSetAsync.java +++ b/src/main/java/org/redisson/core/RScoredSortedSetAsync.java @@ -23,6 +23,12 @@ import io.netty.util.concurrent.Future; public interface RScoredSortedSetAsync extends RExpirableAsync { + Future> lexRangeTailAsync(V fromElement, boolean fromInclusive); + + Future> lexRangeHeadAsync(V toElement, boolean toInclusive); + + Future> lexRangeAsync(V fromElement, boolean fromInclusive, V toElement, boolean toInclusive); + Future lexCountAsync(V fromElement, boolean fromInclusive, V toElement, boolean toInclusive); Future rankAsync(V o); diff --git a/src/test/java/org/redisson/RedissonScoredSortedSetTest.java b/src/test/java/org/redisson/RedissonScoredSortedSetTest.java index f64096ff5..33319a425 100644 --- a/src/test/java/org/redisson/RedissonScoredSortedSetTest.java +++ b/src/test/java/org/redisson/RedissonScoredSortedSetTest.java @@ -21,6 +21,52 @@ import io.netty.util.concurrent.Future; public class RedissonScoredSortedSetTest extends BaseTest { + @Test + public void testLexRangeTail() { + RScoredSortedSet set = redisson.getScoredSortedSet("simple"); + set.add(0, "a"); + set.add(0, "b"); + set.add(0, "c"); + set.add(0, "d"); + set.add(0, "e"); + set.add(0, "f"); + set.add(0, "g"); + + MatcherAssert.assertThat(set.lexRangeTail("c", false), Matchers.contains("d", "e", "f", "g")); + MatcherAssert.assertThat(set.lexRangeTail("c", true), Matchers.contains("c", "d", "e", "f", "g")); + } + + + @Test + public void testLexRangeHead() { + RScoredSortedSet set = redisson.getScoredSortedSet("simple"); + set.add(0, "a"); + set.add(0, "b"); + set.add(0, "c"); + set.add(0, "d"); + set.add(0, "e"); + set.add(0, "f"); + set.add(0, "g"); + + MatcherAssert.assertThat(set.lexRangeHead("c", false), Matchers.contains("a", "b")); + MatcherAssert.assertThat(set.lexRangeHead("c", true), Matchers.contains("a", "b", "c")); + } + + + @Test + public void testLexRange() { + RScoredSortedSet set = redisson.getScoredSortedSet("simple"); + set.add(0, "a"); + set.add(0, "b"); + set.add(0, "c"); + set.add(0, "d"); + set.add(0, "e"); + set.add(0, "f"); + set.add(0, "g"); + + MatcherAssert.assertThat(set.lexRange("aaa", true, "g", false), Matchers.contains("b", "c", "d", "e", "f")); + } + @Test public void testRank() { RScoredSortedSet set = redisson.getScoredSortedSet("simple");