pull/488/head
jackygurui 9 years ago
commit 855a39f263

@ -2,6 +2,16 @@ Redisson Releases History
================================
####Please Note: trunk is current development branch.
####30-Apr-2016 - version 2.2.13 released
Feature - `RSet.diff` and `RSet.intersection` methods added
Imporovement - `RScoredSortedSet`.`containsAll`, `removeAll` and `retainAll` methods speed optimization
Imporovement - `RSetCache` memory and speed optimization
Imporovement - `RSet`.`retainAll`, `containsAll`, `removeAll` methods speed optimized up to 100x
Fixed - possible infinity `RLock` expiration renewal process
Fixed - error during `RSetCache.readAll` invocation.
Fixed - expiration override wasn't work in `RSetCache.add`
####22-Apr-2016 - version 2.2.12 released
Imporovement - Replaying phase handling in CommandDecoder

@ -82,12 +82,12 @@ Include the following to your dependency list:
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>2.2.12</version>
<version>2.2.13</version>
</dependency>
### Gradle
compile 'org.redisson:redisson:2.2.12'
compile 'org.redisson:redisson:2.2.13'
### Supported by

@ -3,7 +3,7 @@
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>2.2.13-SNAPSHOT</version>
<version>2.2.14-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>Redisson</name>

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

@ -263,6 +263,58 @@ public class RedissonSet<V> extends RedissonExpirable implements RSet<V> {
return commandExecutor.writeAsync(getName(), codec, RedisCommands.SUNION, args.toArray());
}
@Override
public int diff(String... names) {
return get(diffAsync(names));
}
@Override
public Future<Integer> diffAsync(String... names) {
List<Object> args = new ArrayList<Object>(names.length + 1);
args.add(getName());
args.addAll(Arrays.asList(names));
return commandExecutor.writeAsync(getName(), codec, RedisCommands.SDIFFSTORE_INT, args.toArray());
}
@Override
public Set<V> readDiff(String... names) {
return get(readDiffAsync(names));
}
@Override
public Future<Set<V>> readDiffAsync(String... names) {
List<Object> args = new ArrayList<Object>(names.length + 1);
args.add(getName());
args.addAll(Arrays.asList(names));
return commandExecutor.writeAsync(getName(), codec, RedisCommands.SDIFF, args.toArray());
}
@Override
public int intersection(String... names) {
return get(intersectionAsync(names));
}
@Override
public Future<Integer> intersectionAsync(String... names) {
List<Object> args = new ArrayList<Object>(names.length + 1);
args.add(getName());
args.addAll(Arrays.asList(names));
return commandExecutor.writeAsync(getName(), codec, RedisCommands.SINTERSTORE_INT, args.toArray());
}
@Override
public Set<V> readIntersection(String... names) {
return get(readIntersectionAsync(names));
}
@Override
public Future<Set<V>> readIntersectionAsync(String... names) {
List<Object> args = new ArrayList<Object>(names.length + 1);
args.add(getName());
args.addAll(Arrays.asList(names));
return commandExecutor.writeAsync(getName(), codec, RedisCommands.SINTER, args.toArray());
}
@Override
public void clear() {
delete();

@ -394,4 +394,56 @@ public class RedissonSetMultimapValues<V> extends RedissonExpirable implements R
delete();
}
@Override
public int diff(String... names) {
return get(diffAsync(names));
}
@Override
public Future<Integer> diffAsync(String... names) {
List<Object> args = new ArrayList<Object>(names.length + 1);
args.add(getName());
args.addAll(Arrays.asList(names));
return commandExecutor.writeAsync(getName(), codec, RedisCommands.SDIFFSTORE_INT, args.toArray());
}
@Override
public Set<V> readDiff(String... names) {
return get(readDiffAsync(names));
}
@Override
public Future<Set<V>> readDiffAsync(String... names) {
List<Object> args = new ArrayList<Object>(names.length + 1);
args.add(getName());
args.addAll(Arrays.asList(names));
return commandExecutor.writeAsync(getName(), codec, RedisCommands.SDIFF, args.toArray());
}
@Override
public int intersection(String... names) {
return get(intersectionAsync(names));
}
@Override
public Future<Integer> intersectionAsync(String... names) {
List<Object> args = new ArrayList<Object>(names.length + 1);
args.add(getName());
args.addAll(Arrays.asList(names));
return commandExecutor.writeAsync(getName(), codec, RedisCommands.SINTERSTORE_INT, args.toArray());
}
@Override
public Set<V> readIntersection(String... names) {
return get(readIntersectionAsync(names));
}
@Override
public Future<Set<V>> readIntersectionAsync(String... names) {
List<Object> args = new ArrayList<Object>(names.length + 1);
args.add(getName());
args.addAll(Arrays.asList(names));
return commandExecutor.writeAsync(getName(), codec, RedisCommands.SINTER, args.toArray());
}
}

@ -101,6 +101,7 @@ public interface RedisCommands {
RedisCommand<Set<Object>> ZRANGEBYSCORE = new RedisCommand<Set<Object>>("ZRANGEBYSCORE", new ObjectSetReplayDecoder<Object>());
RedisCommand<List<Object>> ZRANGEBYSCORE_LIST = new RedisCommand<List<Object>>("ZRANGEBYSCORE", new ObjectListReplayDecoder<Object>());
RedisCommand<List<Object>> ZREVRANGEBYSCORE = new RedisCommand<List<Object>>("ZREVRANGEBYSCORE", new ObjectListReplayDecoder<Object>());
RedisCommand<List<ScoredEntry<Object>>> ZREVRANGEBYSCORE_ENTRY = new RedisCommand<List<ScoredEntry<Object>>>("ZREVRANGEBYSCORE", new ScoredSortedSetReplayDecoder<Object>());
RedisCommand<List<ScoredEntry<Object>>> ZRANGE_ENTRY = new RedisCommand<List<ScoredEntry<Object>>>("ZRANGE", new ScoredSortedSetReplayDecoder<Object>());
RedisCommand<List<ScoredEntry<Object>>> ZRANGEBYSCORE_ENTRY = new RedisCommand<List<ScoredEntry<Object>>>("ZRANGEBYSCORE", new ScoredSortedSetReplayDecoder<Object>());
RedisCommand<ListScanResult<Object>> ZSCAN = new RedisCommand<ListScanResult<Object>>("ZSCAN", new NestedMultiDecoder(new ScoredSortedSetScanDecoder<Object>(), new ScoredSortedSetScanReplayDecoder()), ValueType.OBJECT);
@ -129,8 +130,12 @@ public interface RedisCommands {
RedisStrictCommand<Integer> SCARD_INT = new RedisStrictCommand<Integer>("SCARD", new IntegerReplayConvertor());
RedisStrictCommand<Long> SCARD = new RedisStrictCommand<Long>("SCARD");
RedisStrictCommand<Integer> SUNIONSTORE_INT = new RedisStrictCommand<Integer>("SUNIONSTORE", new IntegerReplayConvertor());
RedisStrictCommand<Integer> SDIFFSTORE_INT = new RedisStrictCommand<Integer>("SDIFFSTORE", new IntegerReplayConvertor());
RedisStrictCommand<Integer> SINTERSTORE_INT = new RedisStrictCommand<Integer>("SINTERSTORE", new IntegerReplayConvertor());
RedisStrictCommand<Long> SUNIONSTORE = new RedisStrictCommand<Long>("SUNIONSTORE");
RedisCommand<Set<Object>> SUNION = new RedisCommand<Set<Object>>("SUNION", new ObjectSetReplayDecoder<Object>());
RedisCommand<Set<Object>> SDIFF = new RedisCommand<Set<Object>>("SDIFF", new ObjectSetReplayDecoder<Object>());
RedisCommand<Set<Object>> SINTER = new RedisCommand<Set<Object>>("SINTER", new ObjectSetReplayDecoder<Object>());
RedisCommand<Void> LSET = new RedisCommand<Void>("LSET", new VoidReplayConvertor(), 3);
RedisCommand<Object> LPOP = new RedisCommand<Object>("LPOP");

@ -20,6 +20,29 @@ import java.util.Set;
public interface RLexSortedSet extends RLexSortedSetAsync, Set<String>, RExpirable {
String pollFirst();
String pollLast();
String first();
String last();
/**
* Returns rank of value, with the scores ordered from high to low.
*
* @param o
* @return rank or <code>null</code> if value does not exist
*/
Integer revRank(String o);
/**
* Read all values at once.
*
* @return
*/
Collection<String> readAll();
int removeRangeTail(String fromElement, boolean fromInclusive);
/**

@ -21,6 +21,21 @@ import io.netty.util.concurrent.Future;
public interface RLexSortedSetAsync extends RCollectionAsync<String> {
Future<String> pollLastAsync();
Future<String> pollFirstAsync();
Future<String> firstAsync();
Future<String> lastAsync();
/**
* Read all values at once.
*
* @return
*/
Future<Collection<String>> readAllAsync();
Future<Integer> removeRangeAsync(String fromElement, boolean fromInclusive, String toElement, boolean toInclusive);
/**
@ -126,5 +141,13 @@ public interface RLexSortedSetAsync extends RCollectionAsync<String> {
*/
@Deprecated
Future<Collection<String>> valueRangeAsync(int startIndex, int endIndex);
/**
* Returns rank of value, with the scores ordered from high to low.
*
* @param o
* @return rank or <code>null</code> if value does not exist
*/
Future<Integer> revRankAsync(String o);
}

@ -112,4 +112,13 @@ public interface RScoredSortedSet<V> extends RScoredSortedSetAsync<V>, Iterable<
Collection<ScoredEntry<V>> entryRange(double startScore, boolean startScoreInclusive, double endScore, boolean endScoreInclusive, int offset, int count);
Collection<ScoredEntry<V>> entryRangeReversed(double startScore, boolean startScoreInclusive, double endScore, boolean endScoreInclusive, int offset, int count);
/**
* Read all values at once.
*
* @return
*/
Collection<V> readAll();
}

@ -94,4 +94,13 @@ public interface RScoredSortedSetAsync<V> extends RExpirableAsync {
Future<Collection<ScoredEntry<V>>> entryRangeAsync(double startScore, boolean startScoreInclusive, double endScore, boolean endScoreInclusive, int offset, int count);
Future<Collection<ScoredEntry<V>>> entryRangeReversedAsync(double startScore, boolean startScoreInclusive, double endScore, boolean endScoreInclusive, int offset, int count);
/**
* Read all values at once.
*
* @return
*/
Future<Collection<V>> readAllAsync();
}

@ -68,4 +68,40 @@ public interface RSet<V> extends Set<V>, RExpirable, RSetAsync<V> {
*/
Set<V> readUnion(String... names);
/**
* Diff sets specified by name and write to current set.
* If current set already exists, it is overwritten.
*
* @param names
* @return
*/
int diff(String... names);
/**
* Diff sets specified by name with current set.
* Without current set state change.
*
* @param names
* @return
*/
Set<V> readDiff(String... names);
/**
* Intersection sets specified by name and write to current set.
* If current set already exists, it is overwritten.
*
* @param names
* @return
*/
int intersection(String... names);
/**
* Intersection sets specified by name with current set.
* Without current set state change.
*
* @param names
* @return
*/
Set<V> readIntersection(String... names);
}

@ -71,4 +71,40 @@ public interface RSetAsync<V> extends RCollectionAsync<V> {
*/
Future<Set<V>> readUnionAsync(String... keys);
/**
* Diff sets specified by name and write to current set.
* If current set already exists, it is overwritten.
*
* @param names
* @return
*/
Future<Integer> diffAsync(String... keys);
/**
* Diff sets specified by name with current set.
* Without current set state change.
*
* @param names
* @return
*/
Future<Set<V>> readDiffAsync(String... keys);
/**
* Intersection sets specified by name and write to current set.
* If current set already exists, it is overwritten.
*
* @param names
* @return
*/
Future<Integer> intersectionAsync(String... keys);
/**
* Intersection sets specified by name with current set.
* Without current set state change.
*
* @param names
* @return
*/
Future<Set<V>> readIntersectionAsync(String... keys);
}

@ -19,10 +19,7 @@ import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* <p>Set-based cache with ability to set TTL for each entry via
* {@link #put(Object, Object, long, TimeUnit)} method.
* And therefore has an complex lua-scripts inside.
* Uses map(value_hash, value) to tie with sorted set which contains expiration record for every value with TTL.
* <p>Set-based cache with ability to set TTL for each object.
* </p>
*
* <p>Current Redis implementation doesn't have set entry eviction functionality.

@ -1,12 +1,53 @@
package org.redisson;
import static org.assertj.core.api.Assertions.*;
import static org.assertj.core.api.Assertions.assertThat;
import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Test;
import org.redisson.core.RLexSortedSet;
public class RedissonLexSortedSetTest extends BaseTest {
@Test
public void testPollLast() {
RLexSortedSet set = redisson.getLexSortedSet("simple");
Assert.assertNull(set.pollLast());
set.add("a");
set.add("b");
set.add("c");
Assert.assertEquals("c", set.pollLast());
MatcherAssert.assertThat(set, Matchers.contains("a", "b"));
}
@Test
public void testPollFirst() {
RLexSortedSet set = redisson.getLexSortedSet("simple");
Assert.assertNull(set.pollFirst());
set.add("a");
set.add("b");
set.add("c");
Assert.assertEquals("a", set.pollFirst());
MatcherAssert.assertThat(set, Matchers.contains("b", "c"));
}
@Test
public void testFirstLast() {
RLexSortedSet set = redisson.getLexSortedSet("simple");
set.add("a");
set.add("b");
set.add("c");
set.add("d");
Assert.assertEquals("a", set.first());
Assert.assertEquals("d", set.last());
}
@Test
public void testRemoveLexRangeTail() {
RLexSortedSet set = redisson.getLexSortedSet("simple");

@ -27,6 +27,18 @@ import io.netty.util.concurrent.Future;
public class RedissonScoredSortedSetTest extends BaseTest {
@Test
public void testReadAll() {
RScoredSortedSet<String> set = redisson.getScoredSortedSet("simple");
set.add(0, "1");
set.add(1, "4");
set.add(2, "2");
set.add(3, "5");
set.add(4, "3");
assertThat(set.readAll()).containsOnly("1", "2", "4", "5", "3");
}
@Test
public void testAddAll() {
RScoredSortedSet<String> set = redisson.getScoredSortedSet("simple");
@ -288,6 +300,8 @@ public class RedissonScoredSortedSetTest extends BaseTest {
Assert.assertTrue(set.retainAll(Arrays.asList(1, 2)));
Assert.assertThat(set, Matchers.containsInAnyOrder(1, 2));
Assert.assertEquals(2, set.size());
assertThat(set.getScore(1)).isEqualTo(10);
assertThat(set.getScore(2)).isEqualTo(20);
}
@Test
@ -651,12 +665,32 @@ public class RedissonScoredSortedSetTest extends BaseTest {
set.add(4, "e");
Collection<ScoredEntry<String>> r = set.entryRange(1, true, 4, false, 1, 2);
Assert.assertEquals(2, r.size());
ScoredEntry<String>[] a = r.toArray(new ScoredEntry[0]);
Assert.assertEquals(2d, a[0].getScore(), 0);
Assert.assertEquals(3d, a[1].getScore(), 0);
Assert.assertEquals("c", a[0].getValue());
Assert.assertEquals("d", a[1].getValue());
}
@Test
public void testScoredSortedSetEntryRangeReversed() {
RScoredSortedSet<String> set = redisson.getScoredSortedSet("simple");
set.add(0, "a");
set.add(1, "b");
set.add(2, "c");
set.add(3, "d");
set.add(4, "e");
Collection<ScoredEntry<String>> r = set.entryRangeReversed(1, true, 4, false, 1, 2);
Assert.assertEquals(2, r.size());
ScoredEntry<String>[] a = r.toArray(new ScoredEntry[0]);
Assert.assertEquals(2d, a[0].getScore(), 0);
Assert.assertEquals(1d, a[1].getScore(), 0);
Assert.assertEquals("c", a[0].getValue());
Assert.assertEquals("b", a[1].getValue());
}
@Test
public void testScoredSortedSetEntryRangeNegativeInf() {

@ -334,7 +334,81 @@ public class RedissonSetTest extends BaseTest {
assertThat(set).containsOnly(5, 6);
}
@Test
public void testDiff() {
RSet<Integer> set = redisson.getSet("set");
set.add(5);
set.add(6);
RSet<Integer> set1 = redisson.getSet("set1");
set1.add(1);
set1.add(2);
set1.add(3);
RSet<Integer> set2 = redisson.getSet("set2");
set2.add(3);
set2.add(4);
set2.add(5);
assertThat(set.diff("set1", "set2")).isEqualTo(2);
assertThat(set).containsOnly(1, 2);
}
@Test
public void testReadDiff() {
RSet<Integer> set = redisson.getSet("set");
set.add(5);
set.add(7);
set.add(6);
RSet<Integer> set1 = redisson.getSet("set1");
set1.add(1);
set1.add(2);
set1.add(5);
RSet<Integer> set2 = redisson.getSet("set2");
set2.add(3);
set2.add(4);
set2.add(5);
assertThat(set.readDiff("set1", "set2")).containsOnly(7, 6);
assertThat(set).containsOnly(6, 5, 7);
}
@Test
public void testIntersection() {
RSet<Integer> set = redisson.getSet("set");
set.add(5);
set.add(6);
RSet<Integer> set1 = redisson.getSet("set1");
set1.add(1);
set1.add(2);
set1.add(3);
RSet<Integer> set2 = redisson.getSet("set2");
set2.add(3);
set2.add(4);
set2.add(5);
assertThat(set.intersection("set1", "set2")).isEqualTo(1);
assertThat(set).containsOnly(3);
}
@Test
public void testReadIntersection() {
RSet<Integer> set = redisson.getSet("set");
set.add(5);
set.add(7);
set.add(6);
RSet<Integer> set1 = redisson.getSet("set1");
set1.add(1);
set1.add(2);
set1.add(5);
RSet<Integer> set2 = redisson.getSet("set2");
set2.add(3);
set2.add(4);
set2.add(5);
assertThat(set.readIntersection("set1", "set2")).containsOnly(5);
assertThat(set).containsOnly(6, 5, 7);
}
@Test
public void testMove() throws Exception {
RSet<Integer> set = redisson.getSet("set");

Loading…
Cancel
Save