RedissonSortedSet added

pull/6/head
Nikita 11 years ago
parent 72317ec32a
commit ed22318874

@ -26,11 +26,14 @@ import org.redisson.core.RLock;
import org.redisson.core.RMap;
import org.redisson.core.RQueue;
import org.redisson.core.RSet;
import org.redisson.core.RSortedSet;
import org.redisson.core.RTopic;
import org.redisson.misc.ReferenceMap;
import org.redisson.misc.ReferenceMap.ReferenceType;
import org.redisson.misc.ReferenceMap.RemoveValueListener;
import com.lambdaworks.redis.RedisConnection;
/**
* Main infrastructure class allows to get access
* to all Redisson objects on top of Redis server.
@ -58,6 +61,7 @@ public class Redisson {
private final ConcurrentMap<String, RedissonAtomicLong> atomicLongsMap = new ReferenceMap<String, RedissonAtomicLong>(ReferenceType.STRONG, ReferenceType.SOFT);
private final ConcurrentMap<String, RedissonQueue> queuesMap = new ReferenceMap<String, RedissonQueue>(ReferenceType.STRONG, ReferenceType.SOFT);
private final ConcurrentMap<String, RedissonSet> setsMap = new ReferenceMap<String, RedissonSet>(ReferenceType.STRONG, ReferenceType.SOFT);
private final ConcurrentMap<String, RedissonSortedSet> sortedSetMap = new ReferenceMap<String, RedissonSortedSet>(ReferenceType.STRONG, ReferenceType.SOFT);
private final ConcurrentMap<String, RedissonList> listsMap = new ReferenceMap<String, RedissonList>(ReferenceType.STRONG, ReferenceType.SOFT);
private final ConcurrentMap<String, RedissonMap> mapsMap = new ReferenceMap<String, RedissonMap>(ReferenceType.STRONG, ReferenceType.SOFT);
@ -170,6 +174,25 @@ public class Redisson {
return set;
}
/**
* Returns distributed sorted set instance by name.
*
* @param name of the distributed set
* @return distributed set
*/
public <V> RSortedSet<V> getSortedSet(String name) {
RedissonSortedSet<V> set = sortedSetMap.get(name);
if (set == null) {
set = new RedissonSortedSet<V>(connectionManager, name);
RedissonSortedSet<V> oldSet = sortedSetMap.putIfAbsent(name, set);
if (oldSet != null) {
set = oldSet;
}
}
return set;
}
/**
* Returns distributed topic instance by name.
*

@ -0,0 +1,462 @@
package org.redisson;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.SortedSet;
import org.redisson.connection.ConnectionManager;
import org.redisson.core.RSortedSet;
import com.lambdaworks.redis.RedisConnection;
import com.lambdaworks.redis.ScoredValue;
/**
*
* @author Nikita Koksharov
*
* @param <V>
*/
public class RedissonSortedSet<V> extends RedissonObject implements RSortedSet<V> {
public static class BinarySearchResult<V> {
private V value;
private Double score;
private int index;
public BinarySearchResult(V value, double score) {
super();
this.value = value;
this.score = score;
}
public BinarySearchResult() {
}
public void setIndex(int index) {
this.index = index;
}
public int getIndex() {
return index;
}
public V getValue() {
return value;
}
public Double getScore() {
return score;
}
}
private final ConnectionManager connectionManager;
private final Comparator<V> comparator = Collections.<V>reverseOrder(Collections.<V>reverseOrder());
RedissonSortedSet(ConnectionManager connectionManager, String name) {
super(name);
this.connectionManager = connectionManager;
}
@Override
public int size() {
RedisConnection<Object, V> connection = connectionManager.connection();
try {
return size(connection);
} finally {
connectionManager.release(connection);
}
}
private int size(RedisConnection<Object, V> connection) {
return connection.zcard(getName()).intValue();
}
@Override
public boolean isEmpty() {
return size() == 0;
}
@Override
public boolean contains(Object o) {
RedisConnection<Object, V> connection = connectionManager.connection();
try {
return binarySearch((V)o, connection).getIndex() >= 0;
} finally {
connectionManager.release(connection);
}
}
public Iterator<V> iterator() {
double startScore;
RedisConnection<Object, V> connection = connectionManager.connection();
try {
startScore = getScoreAtIndex(0, connection);
} finally {
connectionManager.release(connection);
}
return iterator(startScore, Double.MAX_VALUE);
}
public Iterator<V> iterator(final double startScore, final double endScore) {
return new Iterator<V>() {
private double currentScore = startScore;
private boolean removeExecuted;
private V value;
@Override
public boolean hasNext() {
RedisConnection<Object, V> connection = connectionManager.connection();
try {
Long remains = connection.zcount(getName(), currentScore, endScore);
return remains > 0;
} finally {
connectionManager.release(connection);
}
}
@Override
public V next() {
if (!hasNext()) {
throw new NoSuchElementException("No such element at index " + currentScore);
}
removeExecuted = false;
RedisConnection<Object, V> connection = connectionManager.connection();
try {
double lastScore = getScoreAtIndex(-1, connection);
double scoreDiff = lastScore - currentScore;
Long remains = connection.zcount(getName(), currentScore, lastScore);
if (remains == 0) {
throw new NoSuchElementException("No more elements!");
}
// TODO don't load whole set in memory
// if (remains < 50) {
List<ScoredValue<V>> values = connection.zrangebyscoreWithScores(getName(), currentScore, Double.MAX_VALUE);
if (values.isEmpty()) {
throw new NoSuchElementException("No more elements!");
}
ScoredValue<V> val = values.get(0);
value = val.value;
if (values.size() > 1) {
ScoredValue<V> nextVal = values.get(1);
currentScore = nextVal.score;
} else {
currentScore = endScore;
}
return value;
// }
} finally {
connectionManager.release(connection);
}
}
@Override
public void remove() {
if (removeExecuted) {
throw new IllegalStateException("Element been already deleted");
}
RedissonSortedSet.this.remove(value);
removeExecuted = true;
}
};
}
@Override
public Object[] toArray() {
RedisConnection<Object, Object> connection = connectionManager.connection();
try {
return connection.zrange(getName(), 0, -1).toArray();
} finally {
connectionManager.release(connection);
}
}
@Override
public <T> T[] toArray(T[] a) {
RedisConnection<Object, Object> connection = connectionManager.connection();
try {
return connection.zrange(getName(), 0, -1).toArray(a);
} finally {
connectionManager.release(connection);
}
}
@Override
public boolean add(V value) {
RedisConnection<Object, V> connection = connectionManager.connection();
try {
while (true) {
connection.watch(getName());
BinarySearchResult<V> res = binarySearch(value, connection);
if (res.getIndex() < 0) {
double score = calcNewScore(res.getIndex(), connection);
connection.multi();
connection.zadd(getName(), score, value);
List<Object> re = connection.exec();
if (re.size() == 1) {
Object val = re.iterator().next();
return val != null && ((Number)val).intValue() > 0;
}
} else {
connection.unwatch();
return false;
}
}
} finally {
connectionManager.release(connection);
}
}
/**
* score for entry added before head = head / 2
* score for entry added after tail = tail + 1000000
* score for entry inserted between head and tail = head + (tail - head) / 2
*
* @param index
* @param connection
* @return score for index
*/
public double calcNewScore(int index, RedisConnection<Object, V> connection) {
if (index >= 0) {
throw new IllegalStateException("index should be negative, but value is " + index);
}
index = -(index + 1);
double score = getScoreAtIndex(index, connection);
if (index == 0) {
if (score < 0) {
score = 1000000;
} else {
score /= 2;
}
} else {
double beginScore = getScoreAtIndex(index-1, connection);
if (score < 0) {
score = beginScore + 1000000;
} else {
score = beginScore + (score - beginScore) / 2;
}
}
return score;
}
@Override
public boolean remove(Object value) {
RedisConnection<Object, V> connection = connectionManager.connection();
try {
BinarySearchResult<V> res = binarySearch((V) value, connection);
if (res.getIndex() < 0) {
return false;
}
return connection.zremrangebyscore(getName(), res.getScore(), res.getScore()) > 0;
} finally {
connectionManager.release(connection);
}
}
@Override
public boolean containsAll(Collection<?> c) {
for (Object object : c) {
if (!contains(object)) {
return false;
}
}
return true;
}
@Override
public boolean addAll(Collection<? extends V> c) {
boolean changed = false;
for (V v : c) {
if (add(v)) {
changed = true;
}
}
return changed;
}
@Override
public boolean retainAll(Collection<?> c) {
boolean changed = false;
for (Object object : this) {
if (!c.contains(object)) {
remove(object);
changed = true;
}
}
return changed;
}
@Override
public boolean removeAll(Collection<?> c) {
boolean changed = false;
for (Object obj : c) {
if (remove(obj)) {
changed = true;
}
}
return changed;
}
@Override
public void clear() {
RedisConnection<Object, Object> connection = connectionManager.connection();
try {
connection.del(getName());
} finally {
connectionManager.release(connection);
}
}
@Override
public Comparator<? super V> comparator() {
// TODO Auto-generated method stub
return null;
}
@Override
public SortedSet<V> subSet(V fromElement, V toElement) {
return new RedissonSubSortedSet<V>(this, connectionManager, fromElement, toElement);
}
@Override
public SortedSet<V> headSet(V toElement) {
return subSet(null, toElement);
}
@Override
public SortedSet<V> tailSet(V fromElement) {
return subSet(fromElement, null);
}
@Override
public V first() {
RedisConnection<Object, V> connection = connectionManager.connection();
try {
BinarySearchResult<V> res = getAtIndex(0, connection);
if (res.getScore() == null) {
throw new NoSuchElementException();
}
return res.getValue();
} finally {
connectionManager.release(connection);
}
}
@Override
public V last() {
RedisConnection<Object, V> connection = connectionManager.connection();
try {
BinarySearchResult<V> res = getAtIndex(-1, connection);
if (res.getScore() == null) {
throw new NoSuchElementException();
}
return res.getValue();
} finally {
connectionManager.release(connection);
}
}
@Override
public boolean trySetComparator(Comparator<V> comparator) {
// TODO Auto-generated method stub
return false;
}
private double getScoreAtIndex(int index, RedisConnection<Object, V> connection) {
List<ScoredValue<V>> res = connection.zrangeWithScores(getName(), index, index);
if (res.isEmpty()) {
return -1;
}
return res.get(0).score;
}
private BinarySearchResult<V> getAtIndex(int index, RedisConnection<Object, V> connection) {
List<ScoredValue<V>> res = connection.zrangeWithScores(getName(), index, index);
if (res.isEmpty()) {
return new BinarySearchResult<V>();
}
return new BinarySearchResult<V>(res.get(0).value, res.get(0).score);
}
/**
* Binary search algorithm
*
* @param value
* @param connection
* @param lowerIndex
* @param upperIndex
* @return
*/
public BinarySearchResult<V> binarySearch(V value, RedisConnection<Object, V> connection, int lowerIndex, int upperIndex) {
while (lowerIndex <= upperIndex) {
int index = lowerIndex + (upperIndex - lowerIndex) / 2;
BinarySearchResult<V> indexRes = getAtIndex(index, connection);
int cmp = comparator.compare(value, indexRes.getValue());
if (cmp == 0) {
indexRes.setIndex(index);
return indexRes;
} else if (cmp < 0) {
upperIndex = index - 1;
} else {
lowerIndex = index + 1;
}
}
BinarySearchResult<V> indexRes = new BinarySearchResult<V>();
indexRes.setIndex(-(lowerIndex + 1));
return indexRes;
}
public BinarySearchResult<V> binarySearch(V value, RedisConnection<Object, V> connection) {
int upperIndex = size(connection) - 1;
return binarySearch(value, connection, 0, upperIndex);
}
public double score(V value, RedisConnection<Object, V> connection, int indexDiff, boolean tail) {
BinarySearchResult<V> res = binarySearch(value, connection);
if (res.getIndex() < 0) {
BinarySearchResult<V> element = getAtIndex(-res.getIndex() + indexDiff, connection);
return element.getScore();
}
int ind = res.getIndex();
if (tail) {
ind = res.getIndex() - indexDiff;
}
BinarySearchResult<V> element = getAtIndex(ind, connection);
return element.getScore();
}
public String toString() {
Iterator<V> it = iterator();
if (! it.hasNext())
return "[]";
StringBuilder sb = new StringBuilder();
sb.append('[');
for (;;) {
V e = it.next();
sb.append(e == this ? "(this Collection)" : e);
if (! it.hasNext())
return sb.append(']').toString();
sb.append(',').append(' ');
}
}
}

@ -0,0 +1,304 @@
package org.redisson;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.SortedSet;
import org.redisson.RedissonSortedSet.BinarySearchResult;
import org.redisson.connection.ConnectionManager;
import com.lambdaworks.redis.RedisConnection;
/**
*
* @author Nikita Koksharov
*
* @param <V>
*/
class RedissonSubSortedSet<V> implements SortedSet<V> {
private ConnectionManager connectionManager;
private RedissonSortedSet<V> redissonSortedSet;
private V headValue;
private V tailValue;
public RedissonSubSortedSet(RedissonSortedSet<V> redissonSortedSet, ConnectionManager connectionManager, V headValue, V tailValue) {
super();
this.headValue = headValue;
this.tailValue = tailValue;
this.connectionManager = connectionManager;
this.redissonSortedSet = redissonSortedSet;
}
@Override
public int size() {
RedisConnection<Object, V> connection = connectionManager.connection();
try {
double headScore = getHeadScore(connection);
double tailScore = getTailScore(connection);
return connection.zcount(redissonSortedSet.getName(), headScore, tailScore).intValue();
} finally {
connectionManager.release(connection);
}
}
private double getTailScore(RedisConnection<Object, V> connection) {
if (tailValue != null) {
return redissonSortedSet.score(tailValue, connection, 0, true);
}
return Double.MAX_VALUE;
}
private double getHeadScore(RedisConnection<Object, V> connection) {
if (headValue != null) {
return redissonSortedSet.score(headValue, connection, -1, false);
}
return 0;
}
@Override
public boolean isEmpty() {
return size() == 0;
}
@Override
public boolean contains(Object o) {
RedisConnection<Object, V> connection = connectionManager.connection();
try {
double headScore = getHeadScore(connection);
double tailScore = getTailScore(connection);
BinarySearchResult<V> res = redissonSortedSet.binarySearch((V)o, connection);
return res.getScore() < tailScore && res.getScore() > headScore;
} finally {
connectionManager.release(connection);
}
}
@Override
public Iterator<V> iterator() {
RedisConnection<Object, V> connection = connectionManager.connection();
try {
double headScore = getHeadScore(connection);
double tailScore = getTailScore(connection);
return redissonSortedSet.iterator(headScore, tailScore);
} finally {
connectionManager.release(connection);
}
}
@Override
public Object[] toArray() {
RedisConnection<Object, V> connection = connectionManager.connection();
try {
double headScore = getHeadScore(connection);
double tailScore = getTailScore(connection);
return connection.zrangebyscore(redissonSortedSet.getName(), headScore, tailScore).toArray();
} finally {
connectionManager.release(connection);
}
}
@Override
public <T> T[] toArray(T[] a) {
RedisConnection<Object, V> connection = connectionManager.connection();
try {
double headScore = getHeadScore(connection);
double tailScore = getTailScore(connection);
return connection.zrangebyscore(redissonSortedSet.getName(), headScore, tailScore).toArray(a);
} finally {
connectionManager.release(connection);
}
}
@Override
public boolean add(V e) {
RedisConnection<Object, V> connection = connectionManager.connection();
try {
double headScore = getHeadScore(connection);
double tailScore = getTailScore(connection);
BinarySearchResult<V> res = redissonSortedSet.binarySearch(e, connection);
if (res.getScore() == null) {
double score = redissonSortedSet.calcNewScore(res.getIndex(), connection);
if (score < tailScore && score > headScore) {
return redissonSortedSet.add(e);
} else {
throw new IllegalArgumentException("value out of range");
}
}
return false;
} finally {
connectionManager.release(connection);
}
}
@Override
public boolean remove(Object o) {
RedisConnection<Object, V> connection = connectionManager.connection();
try {
double headScore = getHeadScore(connection);
double tailScore = getTailScore(connection);
BinarySearchResult<V> res = redissonSortedSet.binarySearch((V)o, connection);
if (res.getScore() != null && res.getScore() < tailScore && res.getScore() > headScore) {
return redissonSortedSet.remove(o);
}
return false;
} finally {
connectionManager.release(connection);
}
}
@Override
public boolean containsAll(Collection<?> c) {
for (Object object : c) {
if (!contains(object)) {
return false;
}
}
return true;
}
@Override
public boolean addAll(Collection<? extends V> c) {
boolean changed = false;
for (V v : c) {
if (add(v)) {
changed = true;
}
}
return changed;
}
@Override
public boolean retainAll(Collection<?> c) {
boolean changed = false;
for (Object object : this) {
if (!c.contains(object)) {
remove(object);
changed = true;
}
}
return changed;
}
@Override
public boolean removeAll(Collection<?> c) {
boolean changed = false;
for (Object obj : c) {
if (remove(obj)) {
changed = true;
}
}
return changed;
}
@Override
public void clear() {
RedisConnection<Object, V> connection = connectionManager.connection();
try {
double headScore = getHeadScore(connection);
double tailScore = getTailScore(connection);
connection.zremrangebyscore(redissonSortedSet.getName(), headScore, tailScore);
} finally {
connectionManager.release(connection);
}
}
@Override
public Comparator<? super V> comparator() {
return redissonSortedSet.comparator();
}
@Override
public SortedSet<V> subSet(V fromElement, V toElement) {
// TODO check bounds
if (fromElement == null) {
fromElement = headValue;
}
if (toElement == null) {
toElement = tailValue;
}
return new RedissonSubSortedSet<V>(redissonSortedSet, connectionManager, fromElement, toElement);
}
@Override
public SortedSet<V> headSet(V toElement) {
return subSet(null, toElement);
}
@Override
public SortedSet<V> tailSet(V fromElement) {
return subSet(fromElement, null);
}
@Override
public V first() {
RedisConnection<Object, V> connection = connectionManager.connection();
try {
if (headValue != null) {
BinarySearchResult<V> res = redissonSortedSet.binarySearch(headValue, connection);
if (res.getIndex() < 0) {
double headScore = redissonSortedSet.calcNewScore(res.getIndex(), connection);
double tailScore = getTailScore(connection);
List<V> vals = connection.zrangebyscore(redissonSortedSet.getName(), headScore, tailScore);
if (vals.isEmpty()) {
throw new NoSuchElementException();
}
return vals.get(0);
}
return res.getValue();
}
return redissonSortedSet.first();
} finally {
connectionManager.release(connection);
}
}
@Override
public V last() {
RedisConnection<Object, V> connection = connectionManager.connection();
try {
if (tailValue != null) {
BinarySearchResult<V> res = redissonSortedSet.binarySearch(tailValue, connection);
if (res.getIndex() < 0) {
double tailScore = redissonSortedSet.calcNewScore(res.getIndex(), connection);
double headScore = getHeadScore(connection);
List<V> vals = connection.zrangebyscore(redissonSortedSet.getName(), headScore, tailScore);
if (vals.isEmpty()) {
throw new NoSuchElementException();
}
return vals.get(0);
}
return res.getValue();
}
return redissonSortedSet.last();
} finally {
connectionManager.release(connection);
}
}
public String toString() {
Iterator<V> it = iterator();
if (! it.hasNext())
return "[]";
StringBuilder sb = new StringBuilder();
sb.append('[');
for (;;) {
V e = it.next();
sb.append(e == this ? "(this Collection)" : e);
if (! it.hasNext())
return sb.append(']').toString();
sb.append(',').append(' ');
}
}
}

@ -0,0 +1,10 @@
package org.redisson.core;
import java.util.Comparator;
import java.util.SortedSet;
public interface RSortedSet<V> extends SortedSet<V>, RObject {
boolean trySetComparator(Comparator<V> comparator);
}

@ -0,0 +1,257 @@
package org.redisson;
import java.util.Arrays;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.redisson.core.RSortedSet;
public class RedissonSortedSetTest extends BaseTest {
Redisson redisson;
@Before
public void before() {
redisson = Redisson.create();
}
@After
public void after() {
redisson.flushdb();
redisson.shutdown();
}
@Test
public void testOrder2() {
TreeSet<Integer> set = new TreeSet<Integer>();
set.add(1);
set.add(2);
set.add(3);
set.add(4);
set.add(5);
SortedSet<Integer> hs = set.headSet(6);
}
// @Test(expected = IllegalArgumentException.class)
public void testTailSet() {
RSortedSet<Integer> set = redisson.getSortedSet("set");
set.add(1);
set.add(2);
set.add(3);
set.add(4);
set.add(5);
SortedSet<Integer> hs = set.tailSet(3);
hs.add(10);
MatcherAssert.assertThat(hs, Matchers.contains(3, 4, 5, 10));
set.remove(4);
MatcherAssert.assertThat(hs, Matchers.contains(3, 5, 10));
set.remove(3);
MatcherAssert.assertThat(hs, Matchers.contains(5, 10));
hs.add(-1);
}
// @Test(expected = IllegalArgumentException.class)
public void testHeadSet() {
RSortedSet<Integer> set = redisson.getSortedSet("set");
set.add(1);
set.add(2);
set.add(3);
set.add(4);
set.add(5);
SortedSet<Integer> hs = set.headSet(3);
hs.add(0);
MatcherAssert.assertThat(hs, Matchers.contains(0, 1, 2));
set.remove(2);
MatcherAssert.assertThat(hs, Matchers.contains(0, 1));
set.remove(3);
hs.add(7);
}
@Test(expected = IllegalArgumentException.class)
public void testTailSetTreeSet() {
TreeSet<Integer> set = new TreeSet<Integer>();
set.add(1);
set.add(2);
set.add(3);
set.add(4);
set.add(5);
SortedSet<Integer> hs = set.tailSet(3);
hs.add(10);
MatcherAssert.assertThat(hs, Matchers.contains(3, 4, 5, 10));
set.remove(4);
MatcherAssert.assertThat(hs, Matchers.contains(3, 5, 10));
set.remove(3);
MatcherAssert.assertThat(hs, Matchers.contains(5, 10));
hs.add(-1);
}
@Test(expected = IllegalArgumentException.class)
public void testHeadSetTreeSet() {
TreeSet<Integer> set = new TreeSet<Integer>();
set.add(1);
set.add(2);
set.add(3);
set.add(4);
set.add(5);
SortedSet<Integer> hs = set.headSet(3);
hs.add(0);
MatcherAssert.assertThat(hs, Matchers.contains(0, 1, 2));
set.remove(2);
MatcherAssert.assertThat(hs, Matchers.contains(0, 1));
set.remove(3);
hs.add(7);
}
@Test
public void testSort() {
RSortedSet<Integer> set = redisson.getSortedSet("set");
Assert.assertTrue(set.add(2));
Assert.assertTrue(set.add(3));
Assert.assertTrue(set.add(1));
Assert.assertTrue(set.add(4));
Assert.assertTrue(set.add(10));
Assert.assertTrue(set.add(-1));
Assert.assertTrue(set.add(0));
MatcherAssert.assertThat(set, Matchers.contains(-1, 0, 1, 2, 3, 4, 10));
Assert.assertEquals(-1, (int)set.first());
Assert.assertEquals(10, (int)set.last());
}
@Test
public void testRemove() {
RSortedSet<Integer> set = redisson.getSortedSet("set");
set.add(5);
set.add(3);
set.add(1);
set.add(2);
set.add(4);
Assert.assertFalse(set.remove(0));
Assert.assertTrue(set.remove(3));
Assert.assertThat(set, Matchers.contains(1, 2, 4, 5));
}
@Test
public void testRetainAll() {
Set<Integer> set = redisson.getSortedSet("set");
for (int i = 0; i < 200; i++) {
set.add(i);
}
Assert.assertTrue(set.retainAll(Arrays.asList(1, 2)));
Assert.assertEquals(2, set.size());
}
@Test
public void testContainsAll() {
Set<Integer> set = redisson.getSortedSet("set");
for (int i = 0; i < 200; i++) {
set.add(i);
}
Assert.assertTrue(set.containsAll(Arrays.asList(30, 11)));
Assert.assertFalse(set.containsAll(Arrays.asList(30, 711, 11)));
}
@Test
public void testToArray() {
Set<String> set = redisson.getSortedSet("set");
set.add("1");
set.add("4");
set.add("2");
set.add("5");
set.add("3");
MatcherAssert.assertThat(Arrays.asList(set.toArray()), Matchers.<Object>containsInAnyOrder("1", "2", "4", "5", "3"));
String[] strs = set.toArray(new String[0]);
MatcherAssert.assertThat(Arrays.asList(strs), Matchers.containsInAnyOrder("1", "4", "2", "5", "3"));
}
@Test
public void testContains() {
Set<TestObject> set = redisson.getSortedSet("set");
set.add(new TestObject("1", "2"));
set.add(new TestObject("1", "2"));
set.add(new TestObject("2", "3"));
set.add(new TestObject("3", "4"));
set.add(new TestObject("5", "6"));
Assert.assertTrue(set.contains(new TestObject("2", "3")));
Assert.assertTrue(set.contains(new TestObject("1", "2")));
Assert.assertFalse(set.contains(new TestObject("1", "9")));
}
@Test
public void testDuplicates() {
Set<TestObject> set = redisson.getSortedSet("set");
set.add(new TestObject("1", "2"));
set.add(new TestObject("1", "2"));
set.add(new TestObject("2", "3"));
set.add(new TestObject("3", "4"));
set.add(new TestObject("5", "6"));
Assert.assertEquals(4, set.size());
}
@Test
public void testSize() {
Set<Integer> set = redisson.getSortedSet("set");
set.add(1);
set.add(2);
set.add(3);
set.add(3);
set.add(4);
set.add(5);
set.add(5);
Assert.assertEquals(5, set.size());
}
}

@ -1,6 +1,6 @@
package org.redisson;
public class TestObject {
public class TestObject implements Comparable<TestObject> {
private String name;
private String value;
@ -22,4 +22,15 @@ public class TestObject {
return value;
}
@Override
public int compareTo(TestObject o) {
int res = name.compareTo(o.name);
if (res == 0) {
return value.compareTo(o.value);
}
return res;
}
}

Loading…
Cancel
Save