Merge branch 'master' of github.com:redisson/redisson

pull/3048/head
Nikita Koksharov 5 years ago
commit 348c2ace60

@ -66,7 +66,7 @@ public class RedissonBloomFilter<T> extends RedissonExpirable implements RBloomF
private volatile int hashIterations;
private final CommandExecutor commandExecutor;
private final String configName;
private String configName;
protected RedissonBloomFilter(CommandExecutor commandExecutor, String name) {
super(commandExecutor, name);
@ -327,6 +327,42 @@ public class RedissonBloomFilter<T> extends RedissonExpirable implements RBloomF
return check(result);
}
@Override
public RFuture<Void> renameAsync(String newName) {
String newConfigName = suffixName(newName, "config");
RFuture<Void> f = commandExecutor.evalWriteAsync(getName(), StringCodec.INSTANCE, RedisCommands.EVAL_VOID,
"redis.call('rename', KEYS[1], ARGV[1]); "
+ " return redis.call('rename', KEYS[2], ARGV[2]); ",
Arrays.<Object>asList(getName(), configName), newName, newConfigName);
f.onComplete((value, e) -> {
if (e == null) {
this.name = newName;
this.configName = newConfigName;
}
});
return f;
}
@Override
public RFuture<Boolean> renamenxAsync(String newName) {
String newConfigName = suffixName(newName, "config");
RFuture<Boolean> f = commandExecutor.evalWriteAsync(getName(), StringCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,
"local r = redis.call('renamenx', KEYS[1], ARGV[1]); "
+ "if r == 0 then "
+ " return 0; "
+ "else "
+ " return redis.call('renamenx', KEYS[2], ARGV[2]); "
+ "end; ",
Arrays.<Object>asList(getName(), configName), newName, newConfigName);
f.onComplete((value, e) -> {
if (e == null && value) {
this.name = newName;
this.configName = newConfigName;
}
});
return f;
}
private <V> V check(V result) {
if (result == null) {
throw new IllegalStateException("Bloom filter is not initialized!");

@ -15,20 +15,6 @@
*/
package org.redisson;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.stream.Stream;
import org.redisson.api.RFuture;
import org.redisson.api.RScoredSortedSet;
import org.redisson.api.RedissonClient;
@ -37,6 +23,7 @@ import org.redisson.api.mapreduce.RCollectionMapReduce;
import org.redisson.client.RedisClient;
import org.redisson.client.codec.Codec;
import org.redisson.client.codec.DoubleCodec;
import org.redisson.client.codec.IntegerCodec;
import org.redisson.client.codec.LongCodec;
import org.redisson.client.codec.StringCodec;
import org.redisson.client.protocol.RedisCommand;
@ -48,6 +35,20 @@ import org.redisson.iterator.RedissonBaseIterator;
import org.redisson.mapreduce.RedissonCollectionMapReduce;
import org.redisson.misc.RedissonPromise;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.stream.Stream;
/**
*
* @author Nikita Koksharov
@ -204,6 +205,11 @@ public class RedissonScoredSortedSet<V> extends RedissonExpirable implements RSc
return get(addAndGetRevRankAsync(score, object));
}
@Override
public List<Integer> addAndGetRevRank(Map<? extends V, Double> map) {
return get(addAndGetRevRankAsync(map));
}
@Override
public RFuture<Integer> addAndGetRevRankAsync(double score, V object) {
return commandExecutor.evalWriteAsync(getName(), LongCodec.INSTANCE, RedisCommands.EVAL_INTEGER,
@ -212,6 +218,36 @@ public class RedissonScoredSortedSet<V> extends RedissonExpirable implements RSc
Collections.<Object>singletonList(getName()), new BigDecimal(score).toPlainString(), encode(object));
}
@Override
public RFuture<List<Integer>> addAndGetRevRankAsync(Map<? extends V, Double> map) {
final List<Object> params = new ArrayList<Object>(map.size() * 2);
for (java.util.Map.Entry<? extends V, Double> t : map.entrySet()) {
if (t.getKey() == null) {
throw new NullPointerException("map key can't be null");
}
if (t.getValue() == null) {
throw new NullPointerException("map value can't be null");
}
params.add(encode(t.getKey()));
params.add(BigDecimal.valueOf(t.getValue()).toPlainString());
}
return commandExecutor.evalWriteAsync((String) null, IntegerCodec.INSTANCE, RedisCommands.EVAL_INT_LIST,
"local r = {} " +
"for i, v in ipairs(ARGV) do " +
"if i % 2 == 0 then " +
"redis.call('zadd', KEYS[1], ARGV[i], ARGV[i-1]); " +
"end; " +
"end;" +
"for i, v in ipairs(ARGV) do " +
"if i % 2 == 0 then " +
"r[#r+1] = redis.call('zrevrank', KEYS[1], ARGV[i-1]); " +
"end; " +
"end;" +
"return r;",
Collections.singletonList(getName()), params.toArray());
}
@Override
public boolean tryAdd(double score, V object) {
return get(tryAddAsync(score, object));
@ -372,11 +408,27 @@ public class RedissonScoredSortedSet<V> extends RedissonExpirable implements RSc
return get(getScoreAsync(o));
}
@Override
public List<Double> getScore(List<V> keys) {
return get(getScoreAsync(keys));
}
@Override
public RFuture<Double> getScoreAsync(V o) {
return commandExecutor.readAsync(getName(), StringCodec.INSTANCE, RedisCommands.ZSCORE, getName(), encode(o));
}
@Override
public RFuture<List<Double>> getScoreAsync(Collection<V> elements) {
return commandExecutor.evalReadAsync((String) null, DoubleCodec.INSTANCE, RedisCommands.EVAL_LIST,
"local r = {} " +
"for i, v in ipairs(ARGV) do " +
"r[#r+1] = redis.call('ZSCORE', KEYS[1], ARGV[i]); " +
"end;" +
"return r;",
Collections.singletonList(getName()), encode(elements).toArray());
}
@Override
public Integer rank(V o) {
return get(rankAsync(o));
@ -699,6 +751,22 @@ public class RedissonScoredSortedSet<V> extends RedissonExpirable implements RSc
return get(revRankAsync(o));
}
@Override
public RFuture<List<Integer>> revRankAsync(Collection<V> elements) {
return commandExecutor.evalReadAsync((String) null, IntegerCodec.INSTANCE, RedisCommands.EVAL_INT_LIST,
"local r = {} " +
"for i, v in ipairs(ARGV) do " +
"r[#r+1] = redis.call('zrevrank', KEYS[1], ARGV[i]); " +
"end;" +
"return r;",
Collections.singletonList(getName()), encode(elements).toArray());
}
@Override
public List<Integer> revRank(Collection<V> elements) {
return get(revRankAsync(elements));
}
@Override
public int count(double startScore, boolean startScoreInclusive, double endScore, boolean endScoreInclusive) {
return get(countAsync(startScore, startScoreInclusive, endScore, endScoreInclusive));

@ -17,6 +17,7 @@ package org.redisson.api;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@ -254,6 +255,14 @@ public interface RScoredSortedSet<V> extends RScoredSortedSetAsync<V>, Iterable<
*/
Integer revRank(V o);
/**
* Returns ranks of elements, with the scores ordered from high to low.
*
* @param elements - elements
* @return ranks or <code>null</code> if value does not exist
*/
List<Integer> revRank(Collection<V> elements);
/**
* Returns score of element or <code>null</code> if it doesn't exist.
*
@ -262,6 +271,14 @@ public interface RScoredSortedSet<V> extends RScoredSortedSetAsync<V>, Iterable<
*/
Double getScore(V o);
/**
* Returns scores of elements.
*
* @param elements - elements
* @return element scores
*/
List<Double> getScore(List<V> elements);
/**
* Adds element to this set, overrides previous score if it has been already added.
*
@ -289,6 +306,14 @@ public interface RScoredSortedSet<V> extends RScoredSortedSetAsync<V>, Iterable<
*/
Integer addAndGetRevRank(double score, V object);
/**
* Adds elements to this set, overrides previous score if it has been already added.
* Finally returns reverse rank list of the items
* @param map - map of object and scores, make sure to use an ordered map
* @return collection of reverse ranks
*/
List<Integer> addAndGetRevRank(Map<? extends V, Double> map);
/**
* Adds element to this set only if has not been added before.
* <p>

@ -16,6 +16,7 @@
package org.redisson.api;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@ -215,6 +216,14 @@ public interface RScoredSortedSetAsync<V> extends RExpirableAsync, RSortableAsyn
*/
RFuture<Integer> revRankAsync(V o);
/**
* Returns ranks of elements, with the scores ordered from high to low.
*
* @param elements - elements
* @return ranks or <code>null</code> if value does not exist
*/
RFuture<List<Integer>> revRankAsync(Collection<V> elements);
/**
* Returns score of element or <code>null</code> if it doesn't exist.
*
@ -223,6 +232,14 @@ public interface RScoredSortedSetAsync<V> extends RExpirableAsync, RSortableAsyn
*/
RFuture<Double> getScoreAsync(V o);
/**
* Returns scores of elements.
*
* @param elements - elements
* @return element scores
*/
RFuture<List<Double>> getScoreAsync(Collection<V> elements);
/**
* Adds element to this set, overrides previous score if it has been already added.
*
@ -250,6 +267,14 @@ public interface RScoredSortedSetAsync<V> extends RExpirableAsync, RSortableAsyn
*/
RFuture<Integer> addAndGetRevRankAsync(double score, V object);
/**
* Adds elements to this set, overrides previous score if it has been already added.
* Finally returns reverse rank list of the items
* @param map - map of object and scores, make sure to use an ordered map
* @return collection of reverse ranks
*/
RFuture<List<Integer>> addAndGetRevRankAsync(Map<? extends V, Double> map);
/**
* Adds element to this set only if has not been added before.
* <p>

@ -16,6 +16,7 @@
package org.redisson.api;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@ -227,6 +228,14 @@ public interface RScoredSortedSetReactive<V> extends RExpirableReactive, RSortab
*/
Mono<Integer> revRank(V o);
/**
* Returns ranks of elements, with the scores ordered from high to low.
*
* @param elements - elements
* @return ranks or <code>null</code> if value does not exist
*/
Mono<List<Integer>> revRankAsync(Collection<V> elements);
/**
* Returns score of element or <code>null</code> if it doesn't exist.
*
@ -235,6 +244,14 @@ public interface RScoredSortedSetReactive<V> extends RExpirableReactive, RSortab
*/
Mono<Double> getScore(V o);
/**
* Returns scores of elements.
*
* @param elements - elements
* @return element scores
*/
Mono<List<Double>> getScore(Collection<V> elements);
/**
* Adds element to this set, overrides previous score if it has been already added.
*
@ -273,6 +290,14 @@ public interface RScoredSortedSetReactive<V> extends RExpirableReactive, RSortab
*/
Mono<Integer> addAndGetRevRank(double score, V object);
/**
* Adds elements to this set, overrides previous score if it has been already added.
* Finally returns reverse rank list of the items
* @param map - map of object and scores, make sure to use an ordered map
* @return collection of reverse ranks
*/
Mono<List<Integer>> addAndGetRevRank(Map<? extends V, Double> map);
/**
* Adds element to this set only if has not been added before.
* <p>

@ -16,6 +16,7 @@
package org.redisson.api;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@ -228,6 +229,14 @@ public interface RScoredSortedSetRx<V> extends RExpirableRx, RSortableRx<Set<V>>
*/
Maybe<Integer> revRank(V o);
/**
* Returns ranks of elements, with the scores ordered from high to low.
*
* @param elements - elements
* @return ranks or <code>null</code> if value does not exist
*/
Single<List<Integer>> revRank(Collection<V> elements);
/**
* Returns score of element or <code>null</code> if it doesn't exist.
*
@ -236,6 +245,14 @@ public interface RScoredSortedSetRx<V> extends RExpirableRx, RSortableRx<Set<V>>
*/
Maybe<Double> getScore(V o);
/**
* Returns scores of elements.
*
* @param elements - elements
* @return element scores
*/
Single<List<Double>> getScore(Collection<V> elements);
/**
* Adds element to this set, overrides previous score if it has been already added.
*
@ -274,6 +291,14 @@ public interface RScoredSortedSetRx<V> extends RExpirableRx, RSortableRx<Set<V>>
*/
Single<Integer> addAndGetRevRank(double score, V object);
/**
* Adds elements to this set, overrides previous score if it has been already added.
* Finally returns reverse rank list of the items
* @param map - map of object and scores, make sure to use an ordered map
* @return collection of reverse ranks
*/
Single<List<Integer>> addAndGetRevRank(Map<? extends V, Double> map);
/**
* Adds element to this set only if has not been added before.
* <p>

@ -20,14 +20,71 @@ import org.redisson.api.StreamInfo;
import org.redisson.api.StreamMessageId;
import org.redisson.client.codec.StringCodec;
import org.redisson.client.protocol.RedisCommand.ValueType;
import org.redisson.client.protocol.convertor.*;
import org.redisson.client.protocol.decoder.*;
import org.redisson.client.protocol.convertor.BitsSizeReplayConvertor;
import org.redisson.client.protocol.convertor.BooleanAmountReplayConvertor;
import org.redisson.client.protocol.convertor.BooleanNotNullReplayConvertor;
import org.redisson.client.protocol.convertor.BooleanNullReplayConvertor;
import org.redisson.client.protocol.convertor.BooleanNullSafeReplayConvertor;
import org.redisson.client.protocol.convertor.BooleanNumberReplayConvertor;
import org.redisson.client.protocol.convertor.BooleanReplayConvertor;
import org.redisson.client.protocol.convertor.ByteReplayConvertor;
import org.redisson.client.protocol.convertor.DoubleNullSafeReplayConvertor;
import org.redisson.client.protocol.convertor.DoubleReplayConvertor;
import org.redisson.client.protocol.convertor.IntegerReplayConvertor;
import org.redisson.client.protocol.convertor.LongReplayConvertor;
import org.redisson.client.protocol.convertor.ShortReplayConvertor;
import org.redisson.client.protocol.convertor.StreamIdConvertor;
import org.redisson.client.protocol.convertor.StringToListConvertor;
import org.redisson.client.protocol.convertor.TimeObjectDecoder;
import org.redisson.client.protocol.convertor.TrueReplayConvertor;
import org.redisson.client.protocol.convertor.TypeConvertor;
import org.redisson.client.protocol.convertor.VoidReplayConvertor;
import org.redisson.client.protocol.decoder.ClusterNodesDecoder;
import org.redisson.client.protocol.decoder.InetSocketAddressDecoder;
import org.redisson.client.protocol.decoder.ListFirstObjectDecoder;
import org.redisson.client.protocol.decoder.ListMultiDecoder2;
import org.redisson.client.protocol.decoder.ListObjectDecoder;
import org.redisson.client.protocol.decoder.ListResultReplayDecoder;
import org.redisson.client.protocol.decoder.ListScanResult;
import org.redisson.client.protocol.decoder.ListScanResultReplayDecoder;
import org.redisson.client.protocol.decoder.Long2MultiDecoder;
import org.redisson.client.protocol.decoder.MapScanResult;
import org.redisson.client.protocol.decoder.MapScanResultReplayDecoder;
import org.redisson.client.protocol.decoder.ObjectDecoder;
import org.redisson.client.protocol.decoder.ObjectFirstScoreReplayDecoder;
import org.redisson.client.protocol.decoder.ObjectListReplayDecoder;
import org.redisson.client.protocol.decoder.ObjectMapEntryReplayDecoder;
import org.redisson.client.protocol.decoder.ObjectMapReplayDecoder;
import org.redisson.client.protocol.decoder.ObjectMapReplayDecoder2;
import org.redisson.client.protocol.decoder.ObjectSetReplayDecoder;
import org.redisson.client.protocol.decoder.PendingEntryDecoder;
import org.redisson.client.protocol.decoder.PendingResultDecoder;
import org.redisson.client.protocol.decoder.ScoredSortedSetPolledObjectDecoder;
import org.redisson.client.protocol.decoder.ScoredSortedSetReplayDecoder;
import org.redisson.client.protocol.decoder.ScoredSortedSetScanDecoder;
import org.redisson.client.protocol.decoder.ScoredSortedSetScanReplayDecoder;
import org.redisson.client.protocol.decoder.SlotsDecoder;
import org.redisson.client.protocol.decoder.StreamConsumerInfoDecoder;
import org.redisson.client.protocol.decoder.StreamGroupInfoDecoder;
import org.redisson.client.protocol.decoder.StreamIdDecoder;
import org.redisson.client.protocol.decoder.StreamIdListDecoder;
import org.redisson.client.protocol.decoder.StreamObjectMapReplayDecoder;
import org.redisson.client.protocol.decoder.StreamResultDecoder;
import org.redisson.client.protocol.decoder.StringDataDecoder;
import org.redisson.client.protocol.decoder.StringListReplayDecoder;
import org.redisson.client.protocol.decoder.StringMapDataDecoder;
import org.redisson.client.protocol.decoder.StringReplayDecoder;
import org.redisson.client.protocol.decoder.TimeLongObjectDecoder;
import org.redisson.client.protocol.pubsub.PubSubStatusDecoder;
import org.redisson.cluster.ClusterNodeInfo;
import java.net.InetSocketAddress;
import java.util.*;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
/**
*
@ -215,6 +272,7 @@ public interface RedisCommands {
RedisCommand<Object> EVAL_FIRST_LIST = new RedisCommand<Object>("EVAL", new ListFirstObjectDecoder());
RedisCommand<List<Object>> EVAL_LIST = new RedisCommand<List<Object>>("EVAL", new ObjectListReplayDecoder<Object>());
RedisCommand<List<Object>> EVAL_LIST_REVERSE = new RedisCommand<List<Object>>("EVAL", new ObjectListReplayDecoder<>(true));
RedisCommand<List<Integer>> EVAL_INT_LIST = new RedisCommand("EVAL", new ObjectListReplayDecoder<Integer>(), new IntegerReplayConvertor());
RedisCommand<Set<Object>> EVAL_SET = new RedisCommand<Set<Object>>("EVAL", new ObjectSetReplayDecoder<Object>());
RedisCommand<Object> EVAL_OBJECT = new RedisCommand<Object>("EVAL");
RedisCommand<Object> EVAL_MAP_VALUE = new RedisCommand<Object>("EVAL", ValueType.MAP_VALUE);

@ -718,7 +718,9 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager {
int start = indexOf(key, (byte) '{');
if (start != -1) {
int end = indexOf(key, (byte) '}');
key = Arrays.copyOfRange(key, start+1, end);
if (end != -1 && start + 1 < end) {
key = Arrays.copyOfRange(key, start + 1, end);
}
}
int result = CRC16.crc16(key) % MAX_SLOT;
@ -734,7 +736,9 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager {
int start = key.indexOf('{');
if (start != -1) {
int end = key.indexOf('}');
key = key.substring(start+1, end);
if (end != -1 && start + 1 < end) {
key = key.substring(start + 1, end);
}
}
int result = CRC16.crc16(key.getBytes()) % MAX_SLOT;

@ -85,4 +85,40 @@ public class RedissonBloomFilterTest extends BaseTest {
assertThat(filter.count()).isEqualTo(2);
}
@Test
public void testRename() {
RBloomFilter<String> filter = redisson.getBloomFilter("filter");
filter.tryInit(550000000L, 0.03);
assertThat(filter.add("123")).isTrue();
filter.rename("new_filter");
RBloomFilter<String> filter2 = redisson.getBloomFilter("new_filter");
assertThat(filter2.count()).isEqualTo(1);
RBloomFilter<String> filter3 = redisson.getBloomFilter("filter");
assertThat(filter3.isExists()).isFalse();
}
@Test
public void testRenamenx() {
RBloomFilter<String> filter = redisson.getBloomFilter("filter");
filter.tryInit(550000000L, 0.03);
assertThat(filter.add("123")).isTrue();
assertThat(filter.contains("123")).isTrue();
RBloomFilter<String> filter2 = redisson.getBloomFilter("filter2");
filter2.tryInit(550000000L, 0.03);
assertThat(filter2.add("234")).isTrue();
assertThat(filter.renamenx("filter2")).isFalse();
assertThat(filter.count()).isEqualTo(1);
assertThat(filter.renamenx("new_filter")).isTrue();
RBloomFilter<String> oldFilter = redisson.getBloomFilter("filter");
assertThat(oldFilter.isExists()).isFalse();
RBloomFilter<String> newFilter = redisson.getBloomFilter("new_filter");
assertThat(newFilter.count()).isEqualTo(1);
assertThat(newFilter.contains("123")).isTrue();
}
}

@ -7,6 +7,7 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
@ -594,6 +595,7 @@ public class RedissonScoredSortedSetTest extends BaseTest {
set.add(0.7, "g");
assertThat(set.revRank("d")).isEqualTo(3);
assertThat(set.revRank(Arrays.asList("d", "a", "g", "abc", "f"))).isEqualTo(Arrays.asList(3, 6, 0, null, 1));
assertThat(set.rank("abc")).isNull();
}
@ -1227,6 +1229,21 @@ public class RedissonScoredSortedSetTest extends BaseTest {
Assert.assertTrue(new Double(112.3).compareTo(res2) == 0);
}
@Test
public void testAddAndGetAll() throws InterruptedException {
RScoredSortedSet<String> set = redisson.getScoredSortedSet("simple");
set.add(100.2, "1");
Double res2 = set.addScore("1", new Double(12.1));
Assert.assertTrue(new Double(112.3).compareTo(res2) == 0);
res2 = set.getScore("1");
Assert.assertTrue(new Double(112.3).compareTo(res2) == 0);
Collection<Double> res = set.getScore(Arrays.asList("1", "42", "100"));
Assert.assertArrayEquals(new Double[] {112.3d, null, null},
res.toArray());
}
@Test
public void testAddScoreAndGetRank() throws InterruptedException {
RScoredSortedSet<String> set = redisson.getScoredSortedSet("simple");
@ -1265,7 +1282,20 @@ public class RedissonScoredSortedSetTest extends BaseTest {
assertThat(score).isEqualTo(14);
}
@Test
public void testAddAndGetRevRankCollection() throws InterruptedException {
RScoredSortedSet<String> set = redisson.getScoredSortedSet("simple", StringCodec.INSTANCE);
Map<String, Double> map = new LinkedHashMap<>();
map.put("one", 1d);
map.put("three", 3d);
map.put("two", 2d);
Collection<Integer> res = set.addAndGetRevRank(map);
Assert.assertArrayEquals(new Integer[]{2, 0, 1}, res.toArray());
assertThat(set.revRank("one")).isEqualTo(2);
assertThat(set.revRank("two")).isEqualTo(1);
assertThat(set.revRank("three")).isEqualTo(0);
}
@Test
public void testIntersection() {

@ -530,7 +530,7 @@ public class RedissonSetTest extends BaseTest {
RedissonClient redisson = Redisson.create(config);
int size = 10000;
RSet<String> set = redisson.getSet("test");
RSet<String> set = redisson.getSet("{test");
for (int i = 0; i < size; i++) {
set.add("" + i);
}

Loading…
Cancel
Save