Skip to content

Commit

Permalink
RScoredSortedSet rank and lexCount functions added. #143
Browse files Browse the repository at this point in the history
  • Loading branch information
Nikita committed Sep 12, 2015
1 parent 664e890 commit 803ca44
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 16 deletions.
47 changes: 42 additions & 5 deletions src/main/java/org/redisson/RedissonScoredSortedSet.java
Expand Up @@ -26,9 +26,9 @@
import org.redisson.client.codec.StringCodec; import org.redisson.client.codec.StringCodec;
import org.redisson.client.protocol.RedisCommand; import org.redisson.client.protocol.RedisCommand;
import org.redisson.client.protocol.RedisCommands; import org.redisson.client.protocol.RedisCommands;
import org.redisson.client.protocol.ScoredEntry;
import org.redisson.client.protocol.convertor.BooleanReplayConvertor; import org.redisson.client.protocol.convertor.BooleanReplayConvertor;
import org.redisson.client.protocol.decoder.ListScanResult; import org.redisson.client.protocol.decoder.ListScanResult;
import org.redisson.client.protocol.decoder.ScoredEntry;
import org.redisson.core.RScoredSortedSet; import org.redisson.core.RScoredSortedSet;


import io.netty.util.concurrent.Future; import io.netty.util.concurrent.Future;
Expand All @@ -46,6 +46,10 @@ public boolean add(double score, V object) {


@Override @Override
public Future<Boolean> addAsync(double score, V object) { public Future<Boolean> addAsync(double score, V object) {
// String should be encoded as String to let lex functions work properly
if (object instanceof String) {
return commandExecutor.writeAsync(getName(), StringCodec.INSTANCE, RedisCommands.ZADD, getName(), BigDecimal.valueOf(score).toPlainString(), object);
}
return commandExecutor.writeAsync(getName(), RedisCommands.ZADD, getName(), BigDecimal.valueOf(score).toPlainString(), object); return commandExecutor.writeAsync(getName(), RedisCommands.ZADD, getName(), BigDecimal.valueOf(score).toPlainString(), object);
} }


Expand Down Expand Up @@ -90,15 +94,25 @@ public Future<Boolean> containsAsync(Object o) {
} }


@Override @Override
public Double getScore(Object o) { public Double getScore(V o) {
return get(getScoreAsync(o)); return get(getScoreAsync(o));
} }


@Override @Override
public Future<Double> getScoreAsync(Object o) { public Future<Double> getScoreAsync(V o) {
return commandExecutor.readAsync(getName(), RedisCommands.ZSCORE, getName(), o); return commandExecutor.readAsync(getName(), RedisCommands.ZSCORE, getName(), o);
} }


@Override
public Integer rank(V o) {
return get(rankAsync(o));
}

@Override
public Future<Integer> rankAsync(V o) {
return commandExecutor.readAsync(getName(), RedisCommands.ZRANK, getName(), o);
}

private ListScanResult<V> scanIterator(RedisClient client, long startPos) { private ListScanResult<V> scanIterator(RedisClient client, long startPos) {
return commandExecutor.read(client, getName(), RedisCommands.ZSCAN, getName(), startPos); return commandExecutor.read(client, getName(), RedisCommands.ZSCAN, getName(), startPos);
} }
Expand Down Expand Up @@ -259,9 +273,32 @@ public Collection<ScoredEntry<V>> entryRange(int startIndex, int endIndex) {
} }


@Override @Override
public Future<Collection<ScoredEntry<V>>> entryRangeAsync(int startIndex, public Future<Collection<ScoredEntry<V>>> entryRangeAsync(int startIndex, int endIndex) {
int endIndex) {
return commandExecutor.readAsync(getName(), RedisCommands.ZRANGE_ENTRY, getName(), startIndex, endIndex, "WITHSCORES"); return commandExecutor.readAsync(getName(), RedisCommands.ZRANGE_ENTRY, getName(), startIndex, endIndex, "WITHSCORES");
} }


@Override
public Integer lexCount(V fromElement, boolean fromInclusive, V toElement, boolean toInclusive) {
return get(lexCountAsync(fromElement, fromInclusive, toElement, toInclusive));
}

@Override
public Future<Integer> lexCountAsync(V fromElement, boolean fromInclusive, V toElement, boolean toInclusive) {
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);
}

} }
Expand Up @@ -37,7 +37,6 @@
import org.redisson.client.protocol.decoder.ObjectListReplayDecoder; import org.redisson.client.protocol.decoder.ObjectListReplayDecoder;
import org.redisson.client.protocol.decoder.ObjectMapReplayDecoder; import org.redisson.client.protocol.decoder.ObjectMapReplayDecoder;
import org.redisson.client.protocol.decoder.ObjectSetReplayDecoder; import org.redisson.client.protocol.decoder.ObjectSetReplayDecoder;
import org.redisson.client.protocol.decoder.ScoredEntry;
import org.redisson.client.protocol.decoder.ScoredSortedSetReplayDecoder; import org.redisson.client.protocol.decoder.ScoredSortedSetReplayDecoder;
import org.redisson.client.protocol.decoder.ScoredSortedSetScanReplayDecoder; import org.redisson.client.protocol.decoder.ScoredSortedSetScanReplayDecoder;
import org.redisson.client.protocol.decoder.StringDataDecoder; import org.redisson.client.protocol.decoder.StringDataDecoder;
Expand All @@ -52,8 +51,10 @@ public interface RedisCommands {
RedisCommand<Boolean> ZADD = new RedisCommand<Boolean>("ZADD", new BooleanAmountReplayConvertor(), 3); RedisCommand<Boolean> ZADD = new RedisCommand<Boolean>("ZADD", new BooleanAmountReplayConvertor(), 3);
RedisCommand<Boolean> ZREM = new RedisCommand<Boolean>("ZREM", new BooleanAmountReplayConvertor(), 2); RedisCommand<Boolean> ZREM = new RedisCommand<Boolean>("ZREM", new BooleanAmountReplayConvertor(), 2);
RedisStrictCommand<Integer> ZCARD = new RedisStrictCommand<Integer>("ZCARD", new IntegerReplayConvertor()); RedisStrictCommand<Integer> ZCARD = new RedisStrictCommand<Integer>("ZCARD", new IntegerReplayConvertor());
RedisStrictCommand<Integer> ZLEXCOUNT = new RedisStrictCommand<Integer>("ZLEXCOUNT", new IntegerReplayConvertor());
RedisCommand<Boolean> ZSCORE_CONTAINS = new RedisCommand<Boolean>("ZSCORE", new BooleanNotNullReplayConvertor(), 2); RedisCommand<Boolean> ZSCORE_CONTAINS = new RedisCommand<Boolean>("ZSCORE", new BooleanNotNullReplayConvertor(), 2);
RedisStrictCommand<Double> ZSCORE = new RedisStrictCommand<Double>("ZSCORE", new DoubleReplayConvertor()); RedisStrictCommand<Double> ZSCORE = new RedisStrictCommand<Double>("ZSCORE", new DoubleReplayConvertor());
RedisStrictCommand<Integer> ZRANK = new RedisStrictCommand<Integer>("ZRANK", new IntegerReplayConvertor());
RedisCommand<List<Object>> ZRANGE = new RedisCommand<List<Object>>("ZRANGE", new ObjectListReplayDecoder<Object>()); RedisCommand<List<Object>> ZRANGE = new RedisCommand<List<Object>>("ZRANGE", new ObjectListReplayDecoder<Object>());
RedisCommand<List<ScoredEntry<Object>>> ZRANGE_ENTRY = new RedisCommand<List<ScoredEntry<Object>>>("ZRANGE", new ScoredSortedSetReplayDecoder<Object>()); RedisCommand<List<ScoredEntry<Object>>> ZRANGE_ENTRY = new RedisCommand<List<ScoredEntry<Object>>>("ZRANGE", new ScoredSortedSetReplayDecoder<Object>());
RedisCommand<ListScanResult<Object>> ZSCAN = new RedisCommand<ListScanResult<Object>>("ZSCAN", new NestedMultiDecoder(new ObjectListReplayDecoder<Object>(), new ScoredSortedSetScanReplayDecoder()), ValueType.OBJECT); RedisCommand<ListScanResult<Object>> ZSCAN = new RedisCommand<ListScanResult<Object>>("ZSCAN", new NestedMultiDecoder(new ObjectListReplayDecoder<Object>(), new ScoredSortedSetScanReplayDecoder()), ValueType.OBJECT);
Expand Down
Expand Up @@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.redisson.client.protocol.decoder; package org.redisson.client.protocol;


public class ScoredEntry<V> { public class ScoredEntry<V> {


Expand Down
Expand Up @@ -19,6 +19,7 @@
import java.util.List; import java.util.List;


import org.redisson.client.handler.State; import org.redisson.client.handler.State;
import org.redisson.client.protocol.ScoredEntry;


import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;


Expand Down
8 changes: 6 additions & 2 deletions src/main/java/org/redisson/core/RScoredSortedSet.java
Expand Up @@ -17,11 +17,15 @@


import java.util.Collection; import java.util.Collection;


import org.redisson.client.protocol.decoder.ScoredEntry; import org.redisson.client.protocol.ScoredEntry;


public interface RScoredSortedSet<V> extends RScoredSortedSetAsync<V>, Iterable<V>, RExpirable { public interface RScoredSortedSet<V> extends RScoredSortedSetAsync<V>, Iterable<V>, RExpirable {


Double getScore(Object o); Integer lexCount(V fromElement, boolean fromInclusive, V toElement, boolean toInclusive);

Integer rank(V o);

Double getScore(V o);


boolean add(double score, V object); boolean add(double score, V object);


Expand Down
8 changes: 6 additions & 2 deletions src/main/java/org/redisson/core/RScoredSortedSetAsync.java
Expand Up @@ -17,13 +17,17 @@


import java.util.Collection; import java.util.Collection;


import org.redisson.client.protocol.decoder.ScoredEntry; import org.redisson.client.protocol.ScoredEntry;


import io.netty.util.concurrent.Future; import io.netty.util.concurrent.Future;


public interface RScoredSortedSetAsync<V> extends RExpirableAsync { public interface RScoredSortedSetAsync<V> extends RExpirableAsync {


Future<Double> getScoreAsync(Object o); Future<Integer> lexCountAsync(V fromElement, boolean fromInclusive, V toElement, boolean toInclusive);

Future<Integer> rankAsync(V o);

Future<Double> getScoreAsync(V o);


Future<Boolean> addAsync(double score, V object); Future<Boolean> addAsync(double score, V object);


Expand Down
37 changes: 32 additions & 5 deletions src/test/java/org/redisson/RedissonScoredSortedSetTest.java
@@ -1,10 +1,7 @@
package org.redisson; package org.redisson;


import io.netty.util.concurrent.Future;

import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.Set; import java.util.Set;
Expand All @@ -16,13 +13,43 @@
import org.hamcrest.Matchers; import org.hamcrest.Matchers;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.redisson.client.protocol.decoder.ScoredEntry; import org.redisson.client.protocol.ScoredEntry;
import org.redisson.core.RMap;
import org.redisson.core.RScoredSortedSet; import org.redisson.core.RScoredSortedSet;
import org.redisson.core.RSortedSet; import org.redisson.core.RSortedSet;


import io.netty.util.concurrent.Future;

public class RedissonScoredSortedSetTest extends BaseTest { public class RedissonScoredSortedSetTest extends BaseTest {


@Test
public void testRank() {
RScoredSortedSet<String> set = redisson.getScoredSortedSet("simple");
set.add(0.1, "a");
set.add(0.2, "b");
set.add(0.3, "c");
set.add(0.4, "d");
set.add(0.5, "e");
set.add(0.6, "f");
set.add(0.7, "g");

Assert.assertEquals(3, (int)set.rank("d"));
}

@Test
public void testLexCount() {
RScoredSortedSet<String> 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");

Assert.assertEquals(5, (int)set.lexCount("b", true, "f", true));
Assert.assertEquals(3, (int)set.lexCount("b", false, "f", false));
}

@Test @Test
public void testAddAsync() throws InterruptedException, ExecutionException { public void testAddAsync() throws InterruptedException, ExecutionException {
RScoredSortedSet<Integer> set = redisson.getScoredSortedSet("simple"); RScoredSortedSet<Integer> set = redisson.getScoredSortedSet("simple");
Expand Down

0 comments on commit 803ca44

Please sign in to comment.