|
|
@ -19,6 +19,7 @@ import java.io.IOException;
|
|
|
|
import java.math.BigDecimal;
|
|
|
|
import java.math.BigDecimal;
|
|
|
|
import java.net.InetSocketAddress;
|
|
|
|
import java.net.InetSocketAddress;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
|
|
|
import java.util.Arrays;
|
|
|
|
import java.util.Collection;
|
|
|
|
import java.util.Collection;
|
|
|
|
import java.util.Collections;
|
|
|
|
import java.util.Collections;
|
|
|
|
import java.util.Iterator;
|
|
|
|
import java.util.Iterator;
|
|
|
@ -29,8 +30,11 @@ import java.util.Map.Entry;
|
|
|
|
import org.redisson.client.codec.Codec;
|
|
|
|
import org.redisson.client.codec.Codec;
|
|
|
|
import org.redisson.client.codec.ScoredCodec;
|
|
|
|
import org.redisson.client.codec.ScoredCodec;
|
|
|
|
import org.redisson.client.codec.StringCodec;
|
|
|
|
import org.redisson.client.codec.StringCodec;
|
|
|
|
|
|
|
|
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.ScoredEntry;
|
|
|
|
|
|
|
|
import org.redisson.client.protocol.RedisCommand.ValueType;
|
|
|
|
|
|
|
|
import org.redisson.client.protocol.convertor.BooleanReplayConvertor;
|
|
|
|
import org.redisson.client.protocol.decoder.ListScanResult;
|
|
|
|
import org.redisson.client.protocol.decoder.ListScanResult;
|
|
|
|
import org.redisson.command.CommandAsyncExecutor;
|
|
|
|
import org.redisson.command.CommandAsyncExecutor;
|
|
|
|
import org.redisson.core.RScoredSortedSet;
|
|
|
|
import org.redisson.core.RScoredSortedSet;
|
|
|
@ -47,6 +51,16 @@ public class RedissonScoredSortedSet<V> extends RedissonExpirable implements RSc
|
|
|
|
super(codec, commandExecutor, name);
|
|
|
|
super(codec, commandExecutor, name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public Collection<V> readAll() {
|
|
|
|
|
|
|
|
return get(readAllAsync());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public Future<Collection<V>> readAllAsync() {
|
|
|
|
|
|
|
|
return valueRangeAsync(0, -1);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public V pollFirst() {
|
|
|
|
public V pollFirst() {
|
|
|
|
return get(pollFirstAsync());
|
|
|
|
return get(pollFirstAsync());
|
|
|
@ -278,27 +292,32 @@ public class RedissonScoredSortedSet<V> extends RedissonExpirable implements RSc
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public Future<Boolean> containsAllAsync(Collection<?> c) {
|
|
|
|
public Future<Boolean> containsAllAsync(Collection<?> c) {
|
|
|
|
return commandExecutor.evalReadAsync(getName(), codec, RedisCommands.EVAL_BOOLEAN_WITH_VALUES,
|
|
|
|
if (c.isEmpty()) {
|
|
|
|
"local s = redis.call('zrange', KEYS[1], 0, -1);" +
|
|
|
|
return newSucceededFuture(true);
|
|
|
|
"for i = 1, #s, 1 do " +
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return commandExecutor.evalReadAsync(getName(), codec, new RedisCommand<Boolean>("EVAL", new BooleanReplayConvertor(), 4, ValueType.OBJECTS),
|
|
|
|
"for j = 1, #ARGV, 1 do "
|
|
|
|
"for j = 1, #ARGV, 1 do "
|
|
|
|
+ "if ARGV[j] == s[i] "
|
|
|
|
+ "local expireDateScore = redis.call('zscore', KEYS[1], ARGV[j]) "
|
|
|
|
+ "then table.remove(ARGV, j) end "
|
|
|
|
+ "if expireDateScore == false then "
|
|
|
|
|
|
|
|
+ "return 0;"
|
|
|
|
|
|
|
|
+ "end; "
|
|
|
|
+ "end; "
|
|
|
|
+ "end; "
|
|
|
|
+ "end;"
|
|
|
|
+ "return 1; ",
|
|
|
|
+ "return #ARGV == 0 and 1 or 0; ",
|
|
|
|
|
|
|
|
Collections.<Object>singletonList(getName()), c.toArray());
|
|
|
|
Collections.<Object>singletonList(getName()), c.toArray());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public Future<Boolean> removeAllAsync(Collection<?> c) {
|
|
|
|
public Future<Boolean> removeAllAsync(Collection<?> c) {
|
|
|
|
return commandExecutor.evalWriteAsync(getName(), codec, RedisCommands.EVAL_BOOLEAN_WITH_VALUES,
|
|
|
|
if (c.isEmpty()) {
|
|
|
|
"local v = 0;"
|
|
|
|
return newSucceededFuture(false);
|
|
|
|
+ "for i=1, #ARGV, 5000 do "
|
|
|
|
}
|
|
|
|
+ "v = v + redis.call('zrem', KEYS[1], unpack(ARGV, i, math.min(i+4999, #ARGV))); "
|
|
|
|
|
|
|
|
+ "end "
|
|
|
|
List<Object> params = new ArrayList<Object>(c.size()+1);
|
|
|
|
+ "return v > 0;",
|
|
|
|
params.add(getName());
|
|
|
|
Collections.<Object>singletonList(getName()), c.toArray());
|
|
|
|
params.addAll(c);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return commandExecutor.writeAsync(getName(), codec, RedisCommands.ZREM, params.toArray());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
@ -310,30 +329,34 @@ public class RedissonScoredSortedSet<V> extends RedissonExpirable implements RSc
|
|
|
|
public boolean retainAll(Collection<?> c) {
|
|
|
|
public boolean retainAll(Collection<?> c) {
|
|
|
|
return get(retainAllAsync(c));
|
|
|
|
return get(retainAllAsync(c));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private byte[] encode(V value) {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
return codec.getValueEncoder().encode(value);
|
|
|
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
|
|
|
throw new IllegalArgumentException(e);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public Future<Boolean> retainAllAsync(Collection<?> c) {
|
|
|
|
public Future<Boolean> retainAllAsync(Collection<?> c) {
|
|
|
|
return commandExecutor.evalWriteAsync(getName(), codec, RedisCommands.EVAL_BOOLEAN_WITH_VALUES,
|
|
|
|
if (c.isEmpty()) {
|
|
|
|
"local changed = 0 " +
|
|
|
|
return deleteAsync();
|
|
|
|
"local s = redis.call('zrange', KEYS[1], 0, -1) "
|
|
|
|
}
|
|
|
|
+ "local i = 1 "
|
|
|
|
|
|
|
|
+ "while i <= #s do "
|
|
|
|
List<Object> params = new ArrayList<Object>(c.size()*2);
|
|
|
|
+ "local element = s[i] "
|
|
|
|
for (Object object : c) {
|
|
|
|
+ "local isInAgrs = false "
|
|
|
|
params.add(0);
|
|
|
|
+ "for j = 1, #ARGV, 1 do "
|
|
|
|
params.add(encode((V)object));
|
|
|
|
+ "if ARGV[j] == element then "
|
|
|
|
}
|
|
|
|
+ "isInAgrs = true "
|
|
|
|
|
|
|
|
+ "break "
|
|
|
|
return commandExecutor.evalWriteAsync(getName(), codec, RedisCommands.EVAL_BOOLEAN,
|
|
|
|
+ "end "
|
|
|
|
"redis.call('zadd', KEYS[2], unpack(ARGV)); "
|
|
|
|
+ "end "
|
|
|
|
+ "local prevSize = redis.call('zcard', KEYS[1]); "
|
|
|
|
+ "if isInAgrs == false then "
|
|
|
|
+ "local size = redis.call('zinterstore', KEYS[1], 2, KEYS[1], KEYS[2], 'aggregate', 'sum');"
|
|
|
|
+ "redis.call('zrem', KEYS[1], element) "
|
|
|
|
+ "redis.call('del', KEYS[2]); "
|
|
|
|
+ "changed = 1 "
|
|
|
|
+ "return size ~= prevSize and 1 or 0; ",
|
|
|
|
+ "end "
|
|
|
|
Arrays.<Object>asList(getName(), "redisson_temp__{" + getName() + "}"), params.toArray());
|
|
|
|
+ "i = i + 1 "
|
|
|
|
|
|
|
|
+ "end "
|
|
|
|
|
|
|
|
+ "return changed ",
|
|
|
|
|
|
|
|
Collections.<Object>singletonList(getName()), c.toArray());
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
@ -435,6 +458,11 @@ public class RedissonScoredSortedSet<V> extends RedissonExpirable implements RSc
|
|
|
|
return get(entryRangeAsync(startScore, startScoreInclusive, endScore, endScoreInclusive, offset, count));
|
|
|
|
return get(entryRangeAsync(startScore, startScoreInclusive, endScore, endScoreInclusive, offset, count));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public Collection<ScoredEntry<V>> entryRangeReversed(double startScore, boolean startScoreInclusive, double endScore, boolean endScoreInclusive, int offset, int count) {
|
|
|
|
|
|
|
|
return get(entryRangeReversedAsync(startScore, startScoreInclusive, endScore, endScoreInclusive, offset, count));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public Future<Collection<ScoredEntry<V>>> entryRangeAsync(double startScore, boolean startScoreInclusive, double endScore, boolean endScoreInclusive, int offset, int count) {
|
|
|
|
public Future<Collection<ScoredEntry<V>>> entryRangeAsync(double startScore, boolean startScoreInclusive, double endScore, boolean endScoreInclusive, int offset, int count) {
|
|
|
|
String startValue = value(startScore, startScoreInclusive);
|
|
|
|
String startValue = value(startScore, startScoreInclusive);
|
|
|
@ -442,6 +470,13 @@ public class RedissonScoredSortedSet<V> extends RedissonExpirable implements RSc
|
|
|
|
return commandExecutor.readAsync(getName(), codec, RedisCommands.ZRANGEBYSCORE_ENTRY, getName(), startValue, endValue, "WITHSCORES", "LIMIT", offset, count);
|
|
|
|
return commandExecutor.readAsync(getName(), codec, RedisCommands.ZRANGEBYSCORE_ENTRY, getName(), startValue, endValue, "WITHSCORES", "LIMIT", offset, count);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public Future<Collection<ScoredEntry<V>>> entryRangeReversedAsync(double startScore, boolean startScoreInclusive, double endScore, boolean endScoreInclusive, int offset, int count) {
|
|
|
|
|
|
|
|
String startValue = value(startScore, startScoreInclusive);
|
|
|
|
|
|
|
|
String endValue = value(endScore, endScoreInclusive);
|
|
|
|
|
|
|
|
return commandExecutor.readAsync(getName(), codec, RedisCommands.ZREVRANGEBYSCORE_ENTRY, getName(), endValue, startValue, "WITHSCORES", "LIMIT", offset, count);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public Future<Integer> revRankAsync(V o) {
|
|
|
|
public Future<Integer> revRankAsync(V o) {
|
|
|
|
return commandExecutor.readAsync(getName(), codec, RedisCommands.ZREVRANK_INT, getName(), o);
|
|
|
|
return commandExecutor.readAsync(getName(), codec, RedisCommands.ZREVRANK_INT, getName(), o);
|
|
|
|