RList implements RSortable interface #703

pull/748/head
Nikita 8 years ago
parent 802e48c621
commit 7013dfebca

@ -34,6 +34,7 @@ import java.util.NoSuchElementException;
import org.redisson.api.RFuture;
import org.redisson.api.RList;
import org.redisson.api.SortOrder;
import org.redisson.client.codec.Codec;
import org.redisson.client.protocol.RedisCommand;
import org.redisson.client.protocol.RedisCommand.ValueType;
@ -446,7 +447,7 @@ public class RedissonList<V> extends RedissonExpirable implements RList<V> {
}
@Override
public RFuture<Void> trimAsync(long fromIndex, long toIndex) {
public RFuture<Void> trimAsync(int fromIndex, int toIndex) {
return commandExecutor.writeAsync(getName(), codec, RedisCommands.LTRIM, getName(), fromIndex, toIndex);
}
@ -619,13 +620,177 @@ public class RedissonList<V> extends RedissonExpirable implements RList<V> {
}
@Override
public Integer addAfter(V elementToFind, V element) {
public int addAfter(V elementToFind, V element) {
return get(addAfterAsync(elementToFind, element));
}
@Override
public Integer addBefore(V elementToFind, V element) {
public int addBefore(V elementToFind, V element) {
return get(addBeforeAsync(elementToFind, element));
}
@Override
public List<V> readSort(SortOrder order) {
return get(readSortAsync(order));
}
@Override
public RFuture<List<V>> readSortAsync(SortOrder order) {
return commandExecutor.readAsync(getName(), codec, RedisCommands.SORT, getName(), order);
}
@Override
public List<V> readSort(SortOrder order, int offset, int count) {
return get(readSortAsync(order, offset, count));
}
@Override
public RFuture<List<V>> readSortAsync(SortOrder order, int offset, int count) {
return commandExecutor.readAsync(getName(), codec, RedisCommands.SORT, getName(), "LIMIT", offset, count, order);
}
@Override
public List<V> readSort(String byPattern, SortOrder order) {
return get(readSortAsync(byPattern, order));
}
@Override
public RFuture<List<V>> readSortAsync(String byPattern, SortOrder order) {
return commandExecutor.readAsync(getName(), codec, RedisCommands.SORT, getName(), "BY", byPattern, order);
}
@Override
public List<V> readSort(String byPattern, SortOrder order, int offset, int count) {
return get(readSortAsync(byPattern, order, offset, count));
}
@Override
public RFuture<List<V>> readSortAsync(String byPattern, SortOrder order, int offset, int count) {
return commandExecutor.readAsync(getName(), codec, RedisCommands.SORT, getName(), "BY", byPattern, "LIMIT", offset, count, order);
}
@Override
public <T> Collection<T> readSort(String byPattern, List<String> getPatterns, SortOrder order) {
return (Collection<T>)get(readSortAsync(byPattern, getPatterns, order));
}
@Override
public <T> RFuture<Collection<T>> readSortAsync(String byPattern, List<String> getPatterns, SortOrder order) {
return readSortAsync(byPattern, getPatterns, order, -1, -1);
}
@Override
public <T> Collection<T> readSort(String byPattern, List<String> getPatterns, SortOrder order, int offset, int count) {
return (Collection<T>)get(readSortAsync(byPattern, getPatterns, order, offset, count));
}
@Override
public <T> RFuture<Collection<T>> readSortAsync(String byPattern, List<String> getPatterns, SortOrder order, int offset, int count) {
List<Object> params = new ArrayList<Object>();
params.add(getName());
if (byPattern != null) {
params.add("BY");
params.add(byPattern);
}
if (offset != -1 && count != -1) {
params.add("LIMIT");
}
if (offset != -1) {
params.add(offset);
}
if (count != -1) {
params.add(count);
}
for (String pattern : getPatterns) {
params.add("GET");
params.add(pattern);
}
params.add(order);
return commandExecutor.readAsync(getName(), codec, RedisCommands.SORT, params.toArray());
}
@Override
public int sortTo(String destName, SortOrder order) {
return get(sortToAsync(destName, order));
}
@Override
public RFuture<Integer> sortToAsync(String destName, SortOrder order) {
return sortToAsync(destName, null, Collections.<String>emptyList(), order, -1, -1);
}
@Override
public int sortTo(String destName, SortOrder order, int offset, int count) {
return get(sortToAsync(destName, order, offset, count));
}
@Override
public RFuture<Integer> sortToAsync(String destName, SortOrder order, int offset, int count) {
return sortToAsync(destName, null, Collections.<String>emptyList(), order, offset, count);
}
@Override
public int sortTo(String destName, String byPattern, SortOrder order, int offset, int count) {
return get(sortToAsync(destName, byPattern, order, offset, count));
}
@Override
public int sortTo(String destName, String byPattern, SortOrder order) {
return get(sortToAsync(destName, byPattern, order));
}
@Override
public RFuture<Integer> sortToAsync(String destName, String byPattern, SortOrder order) {
return sortToAsync(destName, byPattern, Collections.<String>emptyList(), order, -1, -1);
}
@Override
public RFuture<Integer> sortToAsync(String destName, String byPattern, SortOrder order, int offset, int count) {
return sortToAsync(destName, byPattern, Collections.<String>emptyList(), order, offset, count);
}
@Override
public int sortTo(String destName, String byPattern, List<String> getPatterns, SortOrder order) {
return get(sortToAsync(destName, byPattern, getPatterns, order));
}
@Override
public RFuture<Integer> sortToAsync(String destName, String byPattern, List<String> getPatterns, SortOrder order) {
return sortToAsync(destName, byPattern, getPatterns, order, -1, -1);
}
@Override
public int sortTo(String destName, String byPattern, List<String> getPatterns, SortOrder order, int offset, int count) {
return get(sortToAsync(destName, byPattern, getPatterns, order, offset, count));
}
@Override
public RFuture<Integer> sortToAsync(String destName, String byPattern, List<String> getPatterns, SortOrder order, int offset, int count) {
List<Object> params = new ArrayList<Object>();
params.add(getName());
if (byPattern != null) {
params.add("BY");
params.add(byPattern);
}
if (offset != -1 && count != -1) {
params.add("LIMIT");
}
if (offset != -1) {
params.add(offset);
}
if (count != -1) {
params.add(count);
}
for (String pattern : getPatterns) {
params.add("GET");
params.add(pattern);
}
params.add(order);
params.add("STORE");
params.add(destName);
return commandExecutor.readAsync(getName(), codec, RedisCommands.SORT_TO, params.toArray());
}
}

@ -15,11 +15,6 @@
*/
package org.redisson;
import static org.redisson.client.protocol.RedisCommands.EVAL_OBJECT;
import static org.redisson.client.protocol.RedisCommands.LPOP;
import static org.redisson.client.protocol.RedisCommands.LPUSH_BOOLEAN;
import static org.redisson.client.protocol.RedisCommands.RPUSH_BOOLEAN;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
@ -34,6 +29,7 @@ import java.util.concurrent.TimeUnit;
import org.redisson.api.RFuture;
import org.redisson.api.RList;
import org.redisson.api.SortOrder;
import org.redisson.client.codec.Codec;
import org.redisson.client.protocol.RedisCommand;
import org.redisson.client.protocol.RedisCommand.ValueType;
@ -64,6 +60,7 @@ public class RedissonListMultimapValues<V> extends RedissonExpirable implements
public static final RedisCommand<Boolean> EVAL_BOOLEAN_ARGS2 = new RedisCommand<Boolean>("EVAL", new BooleanReplayConvertor(), 5, ValueType.OBJECTS);
private final RList<V> list;
private final Object key;
private final String timeoutSetName;
@ -71,6 +68,7 @@ public class RedissonListMultimapValues<V> extends RedissonExpirable implements
super(codec, commandExecutor, name);
this.timeoutSetName = timeoutSetName;
this.key = key;
this.list = new RedissonList<V>(codec, commandExecutor, name);
}
@Override
@ -189,12 +187,12 @@ public class RedissonListMultimapValues<V> extends RedissonExpirable implements
@Override
public boolean add(V e) {
return get(addAsync(e));
return list.add(e);
}
@Override
public RFuture<Boolean> addAsync(V e) {
return commandExecutor.writeAsync(getName(), codec, RPUSH_BOOLEAN, getName(), e);
return list.addAsync(e);
}
@Override
@ -265,62 +263,22 @@ public class RedissonListMultimapValues<V> extends RedissonExpirable implements
@Override
public boolean addAll(Collection<? extends V> c) {
return get(addAllAsync(c));
return list.addAll(c);
}
@Override
public RFuture<Boolean> addAllAsync(final Collection<? extends V> c) {
if (c.isEmpty()) {
return newSucceededFuture(false);
}
List<Object> args = new ArrayList<Object>(c.size() + 1);
args.add(getName());
args.addAll(c);
return commandExecutor.writeAsync(getName(), codec, RPUSH_BOOLEAN, args.toArray());
return list.addAllAsync(c);
}
@Override
public RFuture<Boolean> addAllAsync(int index, Collection<? extends V> coll) {
if (index < 0) {
throw new IndexOutOfBoundsException("index: " + index);
}
if (coll.isEmpty()) {
return newSucceededFuture(false);
}
if (index == 0) { // prepend elements to list
List<Object> elements = new ArrayList<Object>(coll);
Collections.reverse(elements);
elements.add(0, getName());
return commandExecutor.writeAsync(getName(), codec, LPUSH_BOOLEAN, elements.toArray());
}
List<Object> args = new ArrayList<Object>(coll.size() + 1);
args.add(index);
args.addAll(coll);
return commandExecutor.evalWriteAsync(getName(), codec, EVAL_BOOLEAN_ARGS2,
"local ind = table.remove(ARGV, 1); " + // index is the first parameter
"local size = redis.call('llen', KEYS[1]); " +
"assert(tonumber(ind) <= size, 'index: ' .. ind .. ' but current size: ' .. size); " +
"local tail = redis.call('lrange', KEYS[1], ind, -1); " +
"redis.call('ltrim', KEYS[1], 0, ind - 1); " +
"for i=1, #ARGV, 5000 do "
+ "redis.call('rpush', KEYS[1], unpack(ARGV, i, math.min(i+4999, #ARGV))); "
+ "end " +
"if #tail > 0 then " +
"for i=1, #tail, 5000 do "
+ "redis.call('rpush', KEYS[1], unpack(tail, i, math.min(i+4999, #tail))); "
+ "end "
+ "end;" +
"return 1;",
Collections.<Object>singletonList(getName()), args.toArray());
return list.addAllAsync(index, coll);
}
@Override
public boolean addAll(int index, Collection<? extends V> coll) {
return get(addAllAsync(index, coll));
return list.addAll(index, coll);
}
@Override
@ -451,27 +409,22 @@ public class RedissonListMultimapValues<V> extends RedissonExpirable implements
@Override
public V set(int index, V element) {
checkIndex(index);
return get(setAsync(index, element));
return list.set(index, element);
}
@Override
public RFuture<V> setAsync(int index, V element) {
return commandExecutor.evalWriteAsync(getName(), codec, new RedisCommand<Object>("EVAL", 5),
"local v = redis.call('lindex', KEYS[1], ARGV[1]); " +
"redis.call('lset', KEYS[1], ARGV[1], ARGV[2]); " +
"return v",
Collections.<Object>singletonList(getName()), index, element);
return list.setAsync(index, element);
}
@Override
public void fastSet(int index, V element) {
get(fastSetAsync(index, element));
list.fastSet(index, element);
}
@Override
public RFuture<Void> fastSetAsync(int index, V element) {
return commandExecutor.writeAsync(getName(), codec, RedisCommands.LSET, getName(), index, element);
return list.fastSetAsync(index, element);
}
@Override
@ -481,34 +434,22 @@ public class RedissonListMultimapValues<V> extends RedissonExpirable implements
@Override
public V remove(int index) {
return get(removeAsync(index));
return list.remove(index);
}
@Override
public RFuture<V> removeAsync(long index) {
if (index == 0) {
return commandExecutor.writeAsync(getName(), codec, LPOP, getName());
}
return commandExecutor.evalWriteAsync(getName(), codec, EVAL_OBJECT,
"local v = redis.call('lindex', KEYS[1], ARGV[1]); " +
"redis.call('lset', KEYS[1], ARGV[1], 'DELETED_BY_REDISSON');" +
"redis.call('lrem', KEYS[1], 1, 'DELETED_BY_REDISSON');" +
"return v",
Collections.<Object>singletonList(getName()), index);
return list.removeAsync(index);
}
@Override
public void fastRemove(int index) {
get(fastRemoveAsync((long)index));
list.fastRemove(index);
}
@Override
public RFuture<Void> fastRemoveAsync(long index) {
return commandExecutor.evalWriteAsync(getName(), codec, RedisCommands.EVAL_VOID,
"redis.call('lset', KEYS[1], ARGV[1], 'DELETED_BY_REDISSON');" +
"redis.call('lrem', KEYS[1], 1, 'DELETED_BY_REDISSON');",
Collections.<Object>singletonList(getName()), index);
return list.fastRemoveAsync(index);
}
@Override
@ -576,12 +517,12 @@ public class RedissonListMultimapValues<V> extends RedissonExpirable implements
@Override
public void trim(int fromIndex, int toIndex) {
get(trimAsync(fromIndex, toIndex));
list.trim(fromIndex, toIndex);
}
@Override
public RFuture<Void> trimAsync(long fromIndex, long toIndex) {
return commandExecutor.writeAsync(getName(), codec, RedisCommands.LTRIM, getName(), fromIndex, toIndex);
public RFuture<Void> trimAsync(int fromIndex, int toIndex) {
return list.trimAsync(fromIndex, toIndex);
}
@Override
@ -699,6 +640,7 @@ public class RedissonListMultimapValues<V> extends RedissonExpirable implements
return new RedissonSubList<V>(codec, commandExecutor, getName(), fromIndex, toIndex);
}
@Override
public String toString() {
Iterator<V> it = iterator();
if (! it.hasNext())
@ -744,22 +686,135 @@ public class RedissonListMultimapValues<V> extends RedissonExpirable implements
@Override
public RFuture<Integer> addAfterAsync(V elementToFind, V element) {
return commandExecutor.writeAsync(getName(), codec, RedisCommands.LINSERT, getName(), "AFTER", elementToFind, element);
return list.addAfterAsync(elementToFind, element);
}
@Override
public RFuture<Integer> addBeforeAsync(V elementToFind, V element) {
return commandExecutor.writeAsync(getName(), codec, RedisCommands.LINSERT, getName(), "BEFORE", elementToFind, element);
return list.addBeforeAsync(elementToFind, element);
}
@Override
public int addAfter(V elementToFind, V element) {
return list.addAfter(elementToFind, element);
}
@Override
public int addBefore(V elementToFind, V element) {
return list.addBefore(elementToFind, element);
}
@Override
public RFuture<List<V>> readSortAsync(SortOrder order) {
return list.readSortAsync(order);
}
@Override
public Integer addAfter(V elementToFind, V element) {
return get(addAfterAsync(elementToFind, element));
public List<V> readSort(SortOrder order) {
return list.readSort(order);
}
@Override
public Integer addBefore(V elementToFind, V element) {
return get(addBeforeAsync(elementToFind, element));
public RFuture<List<V>> readSortAsync(SortOrder order, int offset, int count) {
return list.readSortAsync(order, offset, count);
}
@Override
public List<V> readSort(SortOrder order, int offset, int count) {
return list.readSort(order, offset, count);
}
@Override
public List<V> readSort(String byPattern, SortOrder order, int offset, int count) {
return list.readSort(byPattern, order, offset, count);
}
@Override
public RFuture<List<V>> readSortAsync(String byPattern, SortOrder order, int offset, int count) {
return list.readSortAsync(byPattern, order, offset, count);
}
@Override
public <T> Collection<T> readSort(String byPattern, List<String> getPatterns, SortOrder order, int offset, int count) {
return list.readSort(byPattern, getPatterns, order, offset, count);
}
@Override
public <T> RFuture<Collection<T>> readSortAsync(String byPattern, List<String> getPatterns, SortOrder order, int offset,
int count) {
return list.readSortAsync(byPattern, getPatterns, order, offset, count);
}
@Override
public int sortTo(String destName, SortOrder order) {
return list.sortTo(destName, order);
}
@Override
public RFuture<Integer> sortToAsync(String destName, SortOrder order) {
return list.sortToAsync(destName, order);
}
public List<V> readSort(String byPattern, SortOrder order) {
return list.readSort(byPattern, order);
}
public RFuture<List<V>> readSortAsync(String byPattern, SortOrder order) {
return list.readSortAsync(byPattern, order);
}
public <T> Collection<T> readSort(String byPattern, List<String> getPatterns, SortOrder order) {
return list.readSort(byPattern, getPatterns, order);
}
public <T> RFuture<Collection<T>> readSortAsync(String byPattern, List<String> getPatterns, SortOrder order) {
return list.readSortAsync(byPattern, getPatterns, order);
}
public int sortTo(String destName, SortOrder order, int offset, int count) {
return list.sortTo(destName, order, offset, count);
}
public int sortTo(String destName, String byPattern, SortOrder order) {
return list.sortTo(destName, byPattern, order);
}
public RFuture<Integer> sortToAsync(String destName, SortOrder order, int offset, int count) {
return list.sortToAsync(destName, order, offset, count);
}
public int sortTo(String destName, String byPattern, SortOrder order, int offset, int count) {
return list.sortTo(destName, byPattern, order, offset, count);
}
public RFuture<Integer> sortToAsync(String destName, String byPattern, SortOrder order) {
return list.sortToAsync(destName, byPattern, order);
}
public int sortTo(String destName, String byPattern, List<String> getPatterns, SortOrder order) {
return list.sortTo(destName, byPattern, getPatterns, order);
}
public RFuture<Integer> sortToAsync(String destName, String byPattern, SortOrder order, int offset,
int count) {
return list.sortToAsync(destName, byPattern, order, offset, count);
}
public int sortTo(String destName, String byPattern, List<String> getPatterns, SortOrder order, int offset,
int count) {
return list.sortTo(destName, byPattern, getPatterns, order, offset, count);
}
public RFuture<Integer> sortToAsync(String destName, String byPattern, List<String> getPatterns,
SortOrder order) {
return list.sortToAsync(destName, byPattern, getPatterns, order);
}
public RFuture<Integer> sortToAsync(String destName, String byPattern, List<String> getPatterns,
SortOrder order, int offset, int count) {
return list.sortToAsync(destName, byPattern, getPatterns, order, offset, count);
}
}

@ -470,7 +470,7 @@ public class RedissonSubList<V> extends RedissonList<V> implements RList<V> {
}
@Override
public RFuture<Void> trimAsync(long fromIndex, long toIndex) {
public RFuture<Void> trimAsync(int fromIndex, int toIndex) {
if (fromIndex < this.fromIndex || toIndex >= this.toIndex.get()) {
throw new IndexOutOfBoundsException("fromIndex: " + fromIndex + " toIndex: " + toIndex);
}

@ -25,7 +25,7 @@ import java.util.RandomAccess;
*
* @param <V> the type of elements held in this collection
*/
public interface RList<V> extends List<V>, RExpirable, RListAsync<V>, RandomAccess {
public interface RList<V> extends List<V>, RExpirable, RListAsync<V>, RSortable<List<V>>, RandomAccess {
/**
* Add <code>element</code> after <code>elementToFind</code>
@ -34,7 +34,7 @@ public interface RList<V> extends List<V>, RExpirable, RListAsync<V>, RandomAcce
* @param element - object to add
* @return new list size
*/
Integer addAfter(V elementToFind, V element);
int addAfter(V elementToFind, V element);
/**
* Add <code>element</code> before <code>elementToFind</code>
@ -43,7 +43,7 @@ public interface RList<V> extends List<V>, RExpirable, RListAsync<V>, RandomAcce
* @param element - object to add
* @return new list size
*/
Integer addBefore(V elementToFind, V element);
int addBefore(V elementToFind, V element);
/**
* Set <code>element</code> at <code>index</code>.

@ -26,7 +26,7 @@ import java.util.RandomAccess;
*
* @param <V> the type of elements held in this collection
*/
public interface RListAsync<V> extends RCollectionAsync<V>, RandomAccess {
public interface RListAsync<V> extends RCollectionAsync<V>, RSortableAsync<List<V>>, RandomAccess {
/**
* Add <code>element</code> after <code>elementToFind</code>
@ -82,7 +82,7 @@ public interface RListAsync<V> extends RCollectionAsync<V>, RandomAccess {
* @param toIndex - to index
* @return void
*/
RFuture<Void> trimAsync(long fromIndex, long toIndex);
RFuture<Void> trimAsync(int fromIndex, int toIndex);
RFuture<Void> fastRemoveAsync(long index);

@ -0,0 +1,154 @@
/**
* Copyright 2016 Nikita Koksharov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.redisson.api;
import java.util.Collection;
import java.util.List;
/**
*
* @author Nikita Koksharov
*
*/
public interface RSortable<V> extends RSortableAsync<V> {
/**
* Read data in sorted view
*
* @param order for sorted data
* @return sorted collection
*/
V readSort(SortOrder order);
/**
* Read data in sorted view
*
* @param order for sorted data
* @param offset of sorted data
* @param count of sorted data
* @return sorted collection
*/
V readSort(SortOrder order, int offset, int count);
/**
* Read data in sorted view
*
* @param byPattern that is used to generate the keys that are used for sorting
* @param order for sorted data
* @return sorted collection
*/
V readSort(String byPattern, SortOrder order);
/**
* Read data in sorted view
*
* @param byPattern that is used to generate the keys that are used for sorting
* @param order for sorted data
* @param offset of sorted data
* @param count of sorted data
* @return sorted collection
*/
V readSort(String byPattern, SortOrder order, int offset, int count);
/**
* Read data in sorted view
*
* @param byPattern that is used to generate the keys that are used for sorting
* @param getPatterns that is used to load values by keys in sorted view
* @param order for sorted data
* @return sorted collection
*/
<T> Collection<T> readSort(String byPattern, List<String> getPatterns, SortOrder order);
/**
* Read data in sorted view
*
* @param byPattern that is used to generate the keys that are used for sorting
* @param getPatterns that is used to load values by keys in sorted view
* @param order for sorted data
* @param offset of sorted data
* @param count of sorted data
* @return sorted collection
*/
<T> Collection<T> readSort(String byPattern, List<String> getPatterns, SortOrder order, int offset, int count);
/**
* Sort data and store to <code>destName</code> list
*
* @param destName list object destination
* @param order for sorted data
* @return length of sorted data
*/
int sortTo(String destName, SortOrder order);
/**
* Sort data and store to <code>destName</code> list
*
* @param destName list object destination
* @param order for sorted data
* @param offset of sorted data
* @param count of sorted data
* @return length of sorted data
*/
int sortTo(String destName, SortOrder order, int offset, int count);
/**
* Sort data and store to <code>destName</code> list
*
* @param destName list object destination
* @param byPattern that is used to generate the keys that are used for sorting
* @param order for sorted data
* @return length of sorted data
*/
int sortTo(String destName, String byPattern, SortOrder order);
/**
* Sort data and store to <code>destName</code> list
*
* @param destName list object destination
* @param byPattern that is used to generate the keys that are used for sorting
* @param order for sorted data
* @param offset of sorted data
* @param count of sorted data
* @return length of sorted data
*/
int sortTo(String destName, String byPattern, SortOrder order, int offset, int count);
/**
* Sort data and store to <code>destName</code> list
*
* @param destName list object destination
* @param byPattern that is used to generate the keys that are used for sorting
* @param getPatterns that is used to load values by keys in sorted view
* @param order for sorted data
* @return length of sorted data
*/
int sortTo(String destName, String byPattern, List<String> getPatterns, SortOrder order);
/**
* Sort data and store to <code>destName</code> list
*
* @param destName list object destination
* @param byPattern that is used to generate the keys that are used for sorting
* @param getPatterns that is used to load values by keys in sorted view
* @param order for sorted data
* @param offset of sorted data
* @param count of sorted data
* @return length of sorted data
*/
int sortTo(String destName, String byPattern, List<String> getPatterns, SortOrder order, int offset, int count);
}

@ -0,0 +1,154 @@
/**
* Copyright 2016 Nikita Koksharov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.redisson.api;
import java.util.Collection;
import java.util.List;
/**
*
* @author Nikita Koksharov
*
*/
public interface RSortableAsync<V> {
/**
* Read data in sorted view
*
* @param order for sorted data
* @return sorted collection
*/
RFuture<V> readSortAsync(SortOrder order);
/**
* Read data in sorted view
*
* @param order for sorted data
* @param offset of sorted data
* @param count of sorted data
* @return sorted collection
*/
RFuture<V> readSortAsync(SortOrder order, int offset, int count);
/**
* Read data in sorted view
*
* @param byPattern that is used to generate the keys that are used for sorting
* @param order for sorted data
* @return sorted collection
*/
RFuture<V> readSortAsync(String byPattern, SortOrder order);
/**
* Read data in sorted view
*
* @param byPattern that is used to generate the keys that are used for sorting
* @param order for sorted data
* @param offset of sorted data
* @param count of sorted data
* @return sorted collection
*/
RFuture<V> readSortAsync(String byPattern, SortOrder order, int offset, int count);
/**
* Read data in sorted view
*
* @param byPattern that is used to generate the keys that are used for sorting
* @param getPatterns that is used to load values by keys in sorted view
* @param order for sorted data
* @return sorted collection
*/
<T> RFuture<Collection<T>> readSortAsync(String byPattern, List<String> getPatterns, SortOrder order);
/**
* Read data in sorted view
*
* @param byPattern that is used to generate the keys that are used for sorting
* @param getPatterns that is used to load values by keys in sorted view
* @param order for sorted data
* @param offset of sorted data
* @param count of sorted data
* @return sorted collection
*/
<T> RFuture<Collection<T>> readSortAsync(String byPattern, List<String> getPatterns, SortOrder order, int offset, int count);
/**
* Sort data and store to <code>destName</code> list
*
* @param destName list object destination
* @param order for sorted data
* @return length of sorted data
*/
RFuture<Integer> sortToAsync(String destName, SortOrder order);
/**
* Sort data and store to <code>destName</code> list
*
* @param destName list object destination
* @param order for sorted data
* @param offset of sorted data
* @param count of sorted data
* @return length of sorted data
*/
RFuture<Integer> sortToAsync(String destName, SortOrder order, int offset, int count);
/**
* Sort data and store to <code>destName</code> list
*
* @param destName list object destination
* @param byPattern that is used to generate the keys that are used for sorting
* @param order for sorted data
* @return length of sorted data
*/
RFuture<Integer> sortToAsync(String destName, String byPattern, SortOrder order);
/**
* Sort data and store to <code>destName</code> list
*
* @param destName list object destination
* @param byPattern that is used to generate the keys that are used for sorting
* @param order for sorted data
* @param offset of sorted data
* @param count of sorted data
* @return length of sorted data
*/
RFuture<Integer> sortToAsync(String destName, String byPattern, SortOrder order, int offset, int count);
/**
* Sort data and store to <code>destName</code> list
*
* @param destName list object destination
* @param byPattern that is used to generate the keys that are used for sorting
* @param getPatterns that is used to load values by keys in sorted view
* @param order for sorted data
* @return length of sorted data
*/
RFuture<Integer> sortToAsync(String destName, String byPattern, List<String> getPatterns, SortOrder order);
/**
* Sort data and store to <code>destName</code> list
*
* @param destName list object destination
* @param byPattern that is used to generate the keys that are used for sorting
* @param getPatterns that is used to load values by keys in sorted view
* @param order for sorted data
* @param offset of sorted data
* @param count of sorted data
* @return length of sorted data
*/
RFuture<Integer> sortToAsync(String destName, String byPattern, List<String> getPatterns, SortOrder order, int offset, int count);
}

@ -0,0 +1,25 @@
/**
* Copyright 2016 Nikita Koksharov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.redisson.api;
/**
*
* @author Nikita Koksharov
*
*/
public enum SortOrder {
ASC, DESC
}

@ -184,6 +184,9 @@ public interface RedisCommands {
RedisStrictCommand<Long> PFCOUNT = new RedisStrictCommand<Long>("PFCOUNT");
RedisStrictCommand<Void> PFMERGE = new RedisStrictCommand<Void>("PFMERGE", new VoidReplayConvertor());
RedisCommand<List<Object>> SORT = new RedisCommand<List<Object>>("SORT", new ObjectListReplayDecoder<Object>());
RedisCommand<Integer> SORT_TO = new RedisCommand<Integer>("SORT", new IntegerReplayConvertor());
RedisStrictCommand<Long> RPOP = new RedisStrictCommand<Long>("RPOP");
RedisStrictCommand<Long> LPUSH = new RedisStrictCommand<Long>("LPUSH", 2, ValueType.OBJECTS);
RedisCommand<Boolean> LPUSH_BOOLEAN = new RedisCommand<Boolean>("LPUSH", new TrueReplayConvertor(), 2, ValueType.OBJECTS);

@ -4,6 +4,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
@ -13,10 +14,174 @@ import java.util.ListIterator;
import org.junit.Assert;
import org.junit.Test;
import org.redisson.api.RList;
import org.redisson.api.SortOrder;
import org.redisson.client.RedisException;
import org.redisson.client.codec.IntegerCodec;
import org.redisson.client.codec.StringCodec;
public class RedissonListTest extends BaseTest {
@Test
public void testSortOrder() {
RList<Integer> list = redisson.getList("list", IntegerCodec.INSTANCE);
list.add(1);
list.add(2);
list.add(3);
List<Integer> descSort = list.readSort(SortOrder.DESC);
assertThat(descSort).containsExactly(3, 2, 1);
List<Integer> ascSort = list.readSort(SortOrder.ASC);
assertThat(ascSort).containsExactly(1, 2, 3);
}
@Test
public void testSortOrderLimit() {
RList<Integer> list = redisson.getList("list", IntegerCodec.INSTANCE);
list.add(1);
list.add(2);
list.add(3);
List<Integer> descSort = list.readSort(SortOrder.DESC, 1, 2);
assertThat(descSort).containsExactly(2, 1);
List<Integer> ascSort = list.readSort(SortOrder.ASC, 1, 2);
assertThat(ascSort).containsExactly(2, 3);
}
@Test
public void testSortOrderByPattern() {
RList<Integer> list = redisson.getList("list", IntegerCodec.INSTANCE);
list.add(1);
list.add(2);
list.add(3);
redisson.getBucket("test1", IntegerCodec.INSTANCE).set(3);
redisson.getBucket("test2", IntegerCodec.INSTANCE).set(2);
redisson.getBucket("test3", IntegerCodec.INSTANCE).set(1);
List<Integer> descSort = list.readSort("test*", SortOrder.DESC);
assertThat(descSort).containsExactly(1, 2, 3);
List<Integer> ascSort = list.readSort("test*", SortOrder.ASC);
assertThat(ascSort).containsExactly(3, 2, 1);
}
@Test
public void testSortOrderByPatternLimit() {
RList<Integer> list = redisson.getList("list", IntegerCodec.INSTANCE);
list.add(1);
list.add(2);
list.add(3);
redisson.getBucket("test1", IntegerCodec.INSTANCE).set(3);
redisson.getBucket("test2", IntegerCodec.INSTANCE).set(2);
redisson.getBucket("test3", IntegerCodec.INSTANCE).set(1);
List<Integer> descSort = list.readSort("test*", SortOrder.DESC, 1, 2);
assertThat(descSort).containsExactly(2, 3);
List<Integer> ascSort = list.readSort("test*", SortOrder.ASC, 1, 2);
assertThat(ascSort).containsExactly(2, 1);
}
@Test
public void testSortOrderByPatternGet() {
RList<String> list = redisson.getList("list", StringCodec.INSTANCE);
list.add("1");
list.add("2");
list.add("3");
redisson.getBucket("test1", IntegerCodec.INSTANCE).set(1);
redisson.getBucket("test2", IntegerCodec.INSTANCE).set(2);
redisson.getBucket("test3", IntegerCodec.INSTANCE).set(3);
redisson.getBucket("tester1", StringCodec.INSTANCE).set("obj1");
redisson.getBucket("tester2", StringCodec.INSTANCE).set("obj2");
redisson.getBucket("tester3", StringCodec.INSTANCE).set("obj3");
Collection<String> descSort = list.readSort("test*", Arrays.asList("tester*"), SortOrder.DESC);
assertThat(descSort).containsExactly("obj3", "obj2", "obj1");
Collection<String> ascSort = list.readSort("test*", Arrays.asList("tester*"), SortOrder.ASC);
assertThat(ascSort).containsExactly("obj1", "obj2", "obj3");
}
@Test
public void testSortOrderByPatternGetLimit() {
RList<String> list = redisson.getList("list", StringCodec.INSTANCE);
list.add("1");
list.add("2");
list.add("3");
redisson.getBucket("test1", IntegerCodec.INSTANCE).set(1);
redisson.getBucket("test2", IntegerCodec.INSTANCE).set(2);
redisson.getBucket("test3", IntegerCodec.INSTANCE).set(3);
redisson.getBucket("tester1", StringCodec.INSTANCE).set("obj1");
redisson.getBucket("tester2", StringCodec.INSTANCE).set("obj2");
redisson.getBucket("tester3", StringCodec.INSTANCE).set("obj3");
Collection<String> descSort = list.readSort("test*", Arrays.asList("tester*"), SortOrder.DESC, 1, 2);
assertThat(descSort).containsExactly("obj2", "obj1");
Collection<String> ascSort = list.readSort("test*", Arrays.asList("tester*"), SortOrder.ASC, 1, 2);
assertThat(ascSort).containsExactly("obj2", "obj3");
}
@Test
public void testSortTo() {
RList<String> list = redisson.getList("list", IntegerCodec.INSTANCE);
list.add("1");
list.add("2");
list.add("3");
assertThat(list.sortTo("test3", SortOrder.DESC)).isEqualTo(3);
RList<String> list2 = redisson.getList("test3", StringCodec.INSTANCE);
assertThat(list2).containsExactly("3", "2", "1");
assertThat(list.sortTo("test4", SortOrder.ASC)).isEqualTo(3);
RList<String> list3 = redisson.getList("test4", StringCodec.INSTANCE);
assertThat(list3).containsExactly("1", "2", "3");
}
@Test
public void testSortToLimit() {
RList<Integer> list = redisson.getList("list", IntegerCodec.INSTANCE);
list.add(1);
list.add(2);
list.add(3);
assertThat(list.sortTo("test3", SortOrder.DESC, 1, 2)).isEqualTo(2);
RList<String> list2 = redisson.getList("test3", StringCodec.INSTANCE);
assertThat(list2).containsExactly("2", "1");
assertThat(list.sortTo("test4", SortOrder.ASC, 1, 2)).isEqualTo(2);
RList<String> list3 = redisson.getList("test4", StringCodec.INSTANCE);
assertThat(list3).containsExactly("2", "3");
}
@Test
public void testSortToByPattern() {
RList<Integer> list = redisson.getList("list", IntegerCodec.INSTANCE);
list.add(1);
list.add(2);
list.add(3);
redisson.getBucket("test1", IntegerCodec.INSTANCE).set(3);
redisson.getBucket("test2", IntegerCodec.INSTANCE).set(2);
redisson.getBucket("test3", IntegerCodec.INSTANCE).set(1);
assertThat(list.sortTo("tester3", "test*", SortOrder.DESC, 1, 2)).isEqualTo(2);
RList<String> list2 = redisson.getList("tester3", StringCodec.INSTANCE);
assertThat(list2).containsExactly("2", "3");
assertThat(list.sortTo("tester4", "test*", SortOrder.ASC, 1, 2)).isEqualTo(2);
RList<String> list3 = redisson.getList("tester4", StringCodec.INSTANCE);
assertThat(list3).containsExactly("2", "1");
}
@Test
public void testAddBefore() {
RList<String> list = redisson.getList("list");

Loading…
Cancel
Save