RxJava 2 support #1177

pull/1705/head
Nikita 6 years ago
parent 2bb9277e0a
commit d70ad09a03

@ -19,11 +19,29 @@ import org.redisson.api.ClusterNode;
import org.redisson.api.MapOptions;
import org.redisson.api.Node;
import org.redisson.api.NodesGroup;
import org.redisson.api.RAtomicDoubleRx;
import org.redisson.api.RAtomicLongRx;
import org.redisson.api.RBitSetRx;
import org.redisson.api.RBucketRx;
import org.redisson.api.RGeoRx;
import org.redisson.api.RHyperLogLogRx;
import org.redisson.api.RKeysRx;
import org.redisson.api.RListMultimapRx;
import org.redisson.api.RListRx;
import org.redisson.api.RLockRx;
import org.redisson.api.RMapCacheRx;
import org.redisson.api.RMapRx;
import org.redisson.api.RPermitExpirableSemaphoreRx;
import org.redisson.api.RRateLimiterRx;
import org.redisson.api.RReadWriteLockRx;
import org.redisson.api.RScoredSortedSetRx;
import org.redisson.api.RScriptRx;
import org.redisson.api.RSemaphoreRx;
import org.redisson.api.RSetCache;
import org.redisson.api.RSetCacheRx;
import org.redisson.api.RSetMultimapRx;
import org.redisson.api.RSetRx;
import org.redisson.api.RStreamRx;
import org.redisson.api.RedissonRxClient;
import org.redisson.client.codec.Codec;
import org.redisson.codec.ReferenceCodecProvider;
@ -35,8 +53,14 @@ import org.redisson.pubsub.SemaphorePubSub;
import org.redisson.rx.CommandRxExecutor;
import org.redisson.rx.CommandRxService;
import org.redisson.rx.RedissonKeysRx;
import org.redisson.rx.RedissonListMultimapRx;
import org.redisson.rx.RedissonListRx;
import org.redisson.rx.RedissonMapCacheRx;
import org.redisson.rx.RedissonMapRx;
import org.redisson.rx.RedissonReadWriteLockRx;
import org.redisson.rx.RedissonScoredSortedSetRx;
import org.redisson.rx.RedissonSetCacheRx;
import org.redisson.rx.RedissonSetMultimapRx;
import org.redisson.rx.RedissonSetRx;
import org.redisson.rx.RxProxyBuilder;
@ -67,58 +91,60 @@ public class RedissonRx implements RedissonRxClient {
codecProvider = config.getReferenceCodecProvider();
}
// @Override
// public <K, V> RStreamReactive<K, V> getStream(String name) {
// return ReactiveProxyBuilder.create(commandExecutor, new RedissonStream<K, V>(commandExecutor, name), RStreamReactive.class);
// }
//
// @Override
// public <K, V> RStreamReactive<K, V> getStream(String name, Codec codec) {
// return ReactiveProxyBuilder.create(commandExecutor, new RedissonStream<K, V>(codec, commandExecutor, name), RStreamReactive.class);
// }
//
// @Override
// public <V> RGeoReactive<V> getGeo(String name) {
// return ReactiveProxyBuilder.create(commandExecutor, new RedissonGeo<V>(commandExecutor, name, null),
// new RedissonScoredSortedSetReactive<V>(commandExecutor, name), RGeoReactive.class);
// }
//
// @Override
// public <V> RGeoReactive<V> getGeo(String name, Codec codec) {
// return ReactiveProxyBuilder.create(commandExecutor, new RedissonGeo<V>(codec, commandExecutor, name, null),
// new RedissonScoredSortedSetReactive<V>(codec, commandExecutor, name), RGeoReactive.class);
// }
//
// @Override
// public RLockReactive getFairLock(String name) {
// return ReactiveProxyBuilder.create(commandExecutor, new RedissonFairLock(commandExecutor, name), RLockReactive.class);
// }
//
// @Override
// public RRateLimiterReactive getRateLimiter(String name) {
// return ReactiveProxyBuilder.create(commandExecutor, new RedissonRateLimiter(commandExecutor, name), RRateLimiterReactive.class);
// }
//
// @Override
// public RSemaphoreReactive getSemaphore(String name) {
// return ReactiveProxyBuilder.create(commandExecutor, new RedissonSemaphore(commandExecutor, name, semaphorePubSub), RSemaphoreReactive.class);
// }
//
// @Override
// public RPermitExpirableSemaphoreReactive getPermitExpirableSemaphore(String name) {
// return ReactiveProxyBuilder.create(commandExecutor, new RedissonPermitExpirableSemaphore(commandExecutor, name, semaphorePubSub), RPermitExpirableSemaphoreReactive.class);
// }
//
// @Override
// public RReadWriteLockReactive getReadWriteLock(String name) {
// return new RedissonReadWriteLockReactive(commandExecutor, name);
// }
//
// @Override
// public RLockReactive getLock(String name) {
// return ReactiveProxyBuilder.create(commandExecutor, new RedissonLock(commandExecutor, name), RLockReactive.class);
// }
//
@Override
public <K, V> RStreamRx<K, V> getStream(String name) {
return RxProxyBuilder.create(commandExecutor, new RedissonStream<K, V>(commandExecutor, name), RStreamRx.class);
}
@Override
public <K, V> RStreamRx<K, V> getStream(String name, Codec codec) {
return RxProxyBuilder.create(commandExecutor, new RedissonStream<K, V>(codec, commandExecutor, name), RStreamRx.class);
}
@Override
public <V> RGeoRx<V> getGeo(String name) {
RedissonScoredSortedSet<V> set = new RedissonScoredSortedSet<V>(commandExecutor, name, null);
return RxProxyBuilder.create(commandExecutor, new RedissonGeo<V>(commandExecutor, name, null),
new RedissonScoredSortedSetRx<V>(set), RGeoRx.class);
}
@Override
public <V> RGeoRx<V> getGeo(String name, Codec codec) {
RedissonScoredSortedSet<V> set = new RedissonScoredSortedSet<V>(codec, commandExecutor, name, null);
return RxProxyBuilder.create(commandExecutor, new RedissonGeo<V>(codec, commandExecutor, name, null),
new RedissonScoredSortedSetRx<V>(set), RGeoRx.class);
}
@Override
public RLockRx getFairLock(String name) {
return RxProxyBuilder.create(commandExecutor, new RedissonFairLock(commandExecutor, name), RLockRx.class);
}
@Override
public RRateLimiterRx getRateLimiter(String name) {
return RxProxyBuilder.create(commandExecutor, new RedissonRateLimiter(commandExecutor, name), RRateLimiterRx.class);
}
@Override
public RSemaphoreRx getSemaphore(String name) {
return RxProxyBuilder.create(commandExecutor, new RedissonSemaphore(commandExecutor, name, semaphorePubSub), RSemaphoreRx.class);
}
@Override
public RPermitExpirableSemaphoreRx getPermitExpirableSemaphore(String name) {
return RxProxyBuilder.create(commandExecutor, new RedissonPermitExpirableSemaphore(commandExecutor, name, semaphorePubSub), RPermitExpirableSemaphoreRx.class);
}
@Override
public RReadWriteLockRx getReadWriteLock(String name) {
return new RedissonReadWriteLockRx(commandExecutor, name);
}
@Override
public RLockRx getLock(String name) {
return RxProxyBuilder.create(commandExecutor, new RedissonLock(commandExecutor, name), RLockRx.class);
}
@Override
public <K, V> RMapCacheRx<K, V> getMapCache(String name, Codec codec) {
RedissonMapCache<K, V> map = new RedissonMapCache<K, V>(codec, evictionScheduler, commandExecutor, name, null, null);
@ -143,65 +169,53 @@ public class RedissonRx implements RedissonRxClient {
return RxProxyBuilder.create(commandExecutor, new RedissonBucket<V>(codec, commandExecutor, name), RBucketRx.class);
}
// @Override
// public <V> List<RBucketReactive<V>> findBuckets(String pattern) {
// RKeys redissonKeys = new RedissonKeys(commandExecutor);
// Iterable<String> keys = redissonKeys.getKeysByPattern(pattern);
//
// List<RBucketReactive<V>> buckets = new ArrayList<RBucketReactive<V>>();
// for (Object key : keys) {
// if(key != null) {
// buckets.add(this.<V>getBucket(key.toString()));
// }
// }
// return buckets;
// }
//
// @Override
// public <V> RHyperLogLogReactive<V> getHyperLogLog(String name) {
// return ReactiveProxyBuilder.create(commandExecutor, new RedissonHyperLogLog<V>(commandExecutor, name), RHyperLogLogReactive.class);
// }
//
// @Override
// public <V> RHyperLogLogReactive<V> getHyperLogLog(String name, Codec codec) {
// return ReactiveProxyBuilder.create(commandExecutor, new RedissonHyperLogLog<V>(codec, commandExecutor, name), RHyperLogLogReactive.class);
// }
//
// @Override
// public <V> RListReactive<V> getList(String name) {
// return ReactiveProxyBuilder.create(commandExecutor, new RedissonList<V>(commandExecutor, name, null),
// new RedissonListReactive<V>(commandExecutor, name), RListReactive.class);
// }
//
// @Override
// public <V> RListReactive<V> getList(String name, Codec codec) {
// return ReactiveProxyBuilder.create(commandExecutor, new RedissonList<V>(codec, commandExecutor, name, null),
// new RedissonListReactive<V>(codec, commandExecutor, name), RListReactive.class);
// }
//
// @Override
// public <K, V> RListMultimapReactive<K, V> getListMultimap(String name) {
// return ReactiveProxyBuilder.create(commandExecutor, new RedissonListMultimap<K, V>(commandExecutor, name),
// new RedissonListMultimapReactive<K, V>(commandExecutor, name), RListMultimapReactive.class);
// }
//
// @Override
// public <K, V> RListMultimapReactive<K, V> getListMultimap(String name, Codec codec) {
// return ReactiveProxyBuilder.create(commandExecutor, new RedissonListMultimap<K, V>(codec, commandExecutor, name),
// new RedissonListMultimapReactive<K, V>(codec, commandExecutor, name), RListMultimapReactive.class);
// }
//
// @Override
// public <K, V> RSetMultimapReactive<K, V> getSetMultimap(String name) {
// return ReactiveProxyBuilder.create(commandExecutor, new RedissonSetMultimap<K, V>(commandExecutor, name),
// new RedissonSetMultimapReactive<K, V>(commandExecutor, name), RSetMultimapReactive.class);
// }
//
// @Override
// public <K, V> RSetMultimapReactive<K, V> getSetMultimap(String name, Codec codec) {
// return ReactiveProxyBuilder.create(commandExecutor, new RedissonSetMultimap<K, V>(codec, commandExecutor, name),
// new RedissonSetMultimapReactive<K, V>(codec, commandExecutor, name), RSetMultimapReactive.class);
// }
@Override
public <V> RHyperLogLogRx<V> getHyperLogLog(String name) {
return RxProxyBuilder.create(commandExecutor, new RedissonHyperLogLog<V>(commandExecutor, name), RHyperLogLogRx.class);
}
@Override
public <V> RHyperLogLogRx<V> getHyperLogLog(String name, Codec codec) {
return RxProxyBuilder.create(commandExecutor, new RedissonHyperLogLog<V>(codec, commandExecutor, name), RHyperLogLogRx.class);
}
@Override
public <V> RListRx<V> getList(String name) {
RedissonList<V> list = new RedissonList<V>(commandExecutor, name, null);
return RxProxyBuilder.create(commandExecutor, list,
new RedissonListRx<V>(list), RListRx.class);
}
@Override
public <V> RListRx<V> getList(String name, Codec codec) {
RedissonList<V> list = new RedissonList<V>(codec, commandExecutor, name, null);
return RxProxyBuilder.create(commandExecutor, list,
new RedissonListRx<V>(list), RListRx.class);
}
@Override
public <K, V> RListMultimapRx<K, V> getListMultimap(String name) {
return RxProxyBuilder.create(commandExecutor, new RedissonListMultimap<K, V>(commandExecutor, name),
new RedissonListMultimapRx<K, V>(commandExecutor, name), RListMultimapRx.class);
}
@Override
public <K, V> RListMultimapRx<K, V> getListMultimap(String name, Codec codec) {
return RxProxyBuilder.create(commandExecutor, new RedissonListMultimap<K, V>(codec, commandExecutor, name),
new RedissonListMultimapRx<K, V>(codec, commandExecutor, name), RListMultimapRx.class);
}
@Override
public <K, V> RSetMultimapRx<K, V> getSetMultimap(String name) {
return RxProxyBuilder.create(commandExecutor, new RedissonSetMultimap<K, V>(commandExecutor, name),
new RedissonSetMultimapRx<K, V>(commandExecutor, name), RSetMultimapRx.class);
}
@Override
public <K, V> RSetMultimapRx<K, V> getSetMultimap(String name, Codec codec) {
return RxProxyBuilder.create(commandExecutor, new RedissonSetMultimap<K, V>(codec, commandExecutor, name),
new RedissonSetMultimapRx<K, V>(codec, commandExecutor, name), RSetMultimapRx.class);
}
@Override
public <K, V> RMapRx<K, V> getMap(String name) {
@ -231,18 +245,20 @@ public class RedissonRx implements RedissonRxClient {
new RedissonSetRx<V>(set), RSetRx.class);
}
// @Override
// public <V> RScoredSortedSetReactive<V> getScoredSortedSet(String name) {
// return ReactiveProxyBuilder.create(commandExecutor, new RedissonScoredSortedSet<V>(commandExecutor, name, null),
// new RedissonScoredSortedSetReactive<V>(commandExecutor, name), RScoredSortedSetReactive.class);
// }
//
// @Override
// public <V> RScoredSortedSetReactive<V> getScoredSortedSet(String name, Codec codec) {
// return ReactiveProxyBuilder.create(commandExecutor, new RedissonScoredSortedSet<V>(codec, commandExecutor, name, null),
// new RedissonScoredSortedSetReactive<V>(codec, commandExecutor, name), RScoredSortedSetReactive.class);
// }
//
@Override
public <V> RScoredSortedSetRx<V> getScoredSortedSet(String name) {
RedissonScoredSortedSet<V> set = new RedissonScoredSortedSet<V>(commandExecutor, name, null);
return RxProxyBuilder.create(commandExecutor, set,
new RedissonScoredSortedSetRx<V>(set), RScoredSortedSetRx.class);
}
@Override
public <V> RScoredSortedSetRx<V> getScoredSortedSet(String name, Codec codec) {
RedissonScoredSortedSet<V> set = new RedissonScoredSortedSet<V>(codec, commandExecutor, name, null);
return RxProxyBuilder.create(commandExecutor, set,
new RedissonScoredSortedSetRx<V>(set), RScoredSortedSetRx.class);
}
// @Override
// public RLexSortedSetReactive getLexSortedSet(String name) {
// RedissonLexSortedSet set = new RedissonLexSortedSet(commandExecutor, name, null);
@ -306,41 +322,41 @@ public class RedissonRx implements RedissonRxClient {
// return ReactiveProxyBuilder.create(commandExecutor, new RedissonDeque<V>(codec, commandExecutor, name, null),
// new RedissonListReactive<V>(codec, commandExecutor, name), RDequeReactive.class);
// }
//
// @Override
// public <V> RSetCacheReactive<V> getSetCache(String name) {
// RSetCache<V> set = new RedissonSetCache<V>(evictionScheduler, commandExecutor, name, null);
// return ReactiveProxyBuilder.create(commandExecutor, set,
// new RedissonSetCacheReactive<V>(set), RSetCacheReactive.class);
// }
//
// @Override
// public <V> RSetCacheReactive<V> getSetCache(String name, Codec codec) {
// RSetCache<V> set = new RedissonSetCache<V>(codec, evictionScheduler, commandExecutor, name, null);
// return ReactiveProxyBuilder.create(commandExecutor, set,
// new RedissonSetCacheReactive<V>(set), RSetCacheReactive.class);
// }
//
// @Override
// public RAtomicLongReactive getAtomicLong(String name) {
// return ReactiveProxyBuilder.create(commandExecutor, new RedissonAtomicLong(commandExecutor, name), RAtomicLongReactive.class);
// }
//
// @Override
// public RAtomicDoubleReactive getAtomicDouble(String name) {
// return ReactiveProxyBuilder.create(commandExecutor, new RedissonAtomicDouble(commandExecutor, name), RAtomicDoubleReactive.class);
// }
//
// @Override
// public RBitSetReactive getBitSet(String name) {
// return ReactiveProxyBuilder.create(commandExecutor, new RedissonBitSet(commandExecutor, name), RBitSetReactive.class);
// }
//
// @Override
// public RScriptReactive getScript() {
// return ReactiveProxyBuilder.create(commandExecutor, new RedissonScript(commandExecutor), RScriptReactive.class);
// }
//
@Override
public <V> RSetCacheRx<V> getSetCache(String name) {
RSetCache<V> set = new RedissonSetCache<V>(evictionScheduler, commandExecutor, name, null);
return RxProxyBuilder.create(commandExecutor, set,
new RedissonSetCacheRx<V>(set), RSetCacheRx.class);
}
@Override
public <V> RSetCacheRx<V> getSetCache(String name, Codec codec) {
RSetCache<V> set = new RedissonSetCache<V>(codec, evictionScheduler, commandExecutor, name, null);
return RxProxyBuilder.create(commandExecutor, set,
new RedissonSetCacheRx<V>(set), RSetCacheRx.class);
}
@Override
public RAtomicLongRx getAtomicLong(String name) {
return RxProxyBuilder.create(commandExecutor, new RedissonAtomicLong(commandExecutor, name), RAtomicLongRx.class);
}
@Override
public RAtomicDoubleRx getAtomicDouble(String name) {
return RxProxyBuilder.create(commandExecutor, new RedissonAtomicDouble(commandExecutor, name), RAtomicDoubleRx.class);
}
@Override
public RBitSetRx getBitSet(String name) {
return RxProxyBuilder.create(commandExecutor, new RedissonBitSet(commandExecutor, name), RBitSetRx.class);
}
@Override
public RScriptRx getScript() {
return RxProxyBuilder.create(commandExecutor, new RedissonScript(commandExecutor), RScriptRx.class);
}
// @Override
// public RBatchReactive createBatch(BatchOptions options) {
// RedissonBatchReactive batch = new RedissonBatchReactive(evictionScheduler, connectionManager, options);

@ -0,0 +1,113 @@
/**
* Copyright 2018 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 org.reactivestreams.Publisher;
/**
* Reactive interface for AtomicDouble object
*
* @author Nikita Koksharov
*
*/
public interface RAtomicDoubleRx extends RExpirableRx {
/**
* Atomically sets the value to the given updated value
* only if the current value {@code ==} the expected value.
*
* @param expect the expected value
* @param update the new value
* @return true if successful; or false if the actual value
* was not equal to the expected value.
*/
Publisher<Boolean> compareAndSet(double expect, double update);
/**
* Atomically adds the given value to the current value.
*
* @param delta the value to add
* @return the updated value
*/
Publisher<Double> addAndGet(double delta);
/**
* Atomically decrements the current value by one.
*
* @return the updated value
*/
Publisher<Double> decrementAndGet();
/**
* Returns current value.
*
* @return current value
*/
Publisher<Double> get();
/**
* Returns and deletes object
*
* @return the current value
*/
Publisher<Double> getAndDelete();
/**
* Atomically adds the given value to the current value.
*
* @param delta the value to add
* @return the updated value
*/
Publisher<Double> getAndAdd(double delta);
/**
* Atomically sets the given value and returns the old value.
*
* @param newValue the new value
* @return the old value
*/
Publisher<Double> getAndSet(double newValue);
/**
* Atomically increments the current value by one.
*
* @return the updated value
*/
Publisher<Double> incrementAndGet();
/**
* Atomically increments the current value by one.
*
* @return the old value
*/
Publisher<Double> getAndIncrement();
/**
* Atomically decrements by one the current value.
*
* @return the previous value
*/
Publisher<Double> getAndDecrement();
/**
* Atomically sets the given value.
*
* @param newValue the new value
* @return void
*/
Publisher<Void> set(double newValue);
}

@ -0,0 +1,113 @@
/**
* Copyright 2018 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 io.reactivex.Flowable;
/**
* RxJava2 interface for AtomicLong object
*
* @author Nikita Koksharov
*
*/
public interface RAtomicLongRx extends RExpirableRx {
/**
* Atomically sets the value to the given updated value
* only if the current value {@code ==} the expected value.
*
* @param expect the expected value
* @param update the new value
* @return true if successful; or false if the actual value
* was not equal to the expected value.
*/
Flowable<Boolean> compareAndSet(long expect, long update);
/**
* Atomically adds the given value to the current value.
*
* @param delta the value to add
* @return the updated value
*/
Flowable<Long> addAndGet(long delta);
/**
* Atomically decrements the current value by one.
*
* @return the updated value
*/
Flowable<Long> decrementAndGet();
/**
* Returns current value.
*
* @return the current value
*/
Flowable<Long> get();
/**
* Returns and deletes object
*
* @return the current value
*/
Flowable<Long> getAndDelete();
/**
* Atomically adds the given value to the current value.
*
* @param delta the value to add
* @return the old value before the add
*/
Flowable<Long> getAndAdd(long delta);
/**
* Atomically sets the given value and returns the old value.
*
* @param newValue the new value
* @return the old value
*/
Flowable<Long> getAndSet(long newValue);
/**
* Atomically increments the current value by one.
*
* @return the updated value
*/
Flowable<Long> incrementAndGet();
/**
* Atomically increments the current value by one.
*
* @return the old value
*/
Flowable<Long> getAndIncrement();
/**
* Atomically decrements by one the current value.
*
* @return the previous value
*/
Flowable<Long> getAndDecrement();
/**
* Atomically sets the given value.
*
* @param newValue the new value
* @return void
*/
Flowable<Void> set(long newValue);
}

@ -0,0 +1,399 @@
/**
* Copyright 2018 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.concurrent.TimeUnit;
import org.reactivestreams.Publisher;
import org.redisson.client.codec.Codec;
/**
* Reactive interface for Redis pipeline feature.
* <p>
* All method invocations on objects
* from this interface are batched to separate queue and could be executed later
* with <code>execute()</code> method.
*
*
* @author Nikita Koksharov
*
*/
public interface RBatchRx {
/**
* Returns stream instance by <code>name</code>
* <p>
* Requires <b>Redis 5.0.0 and higher.</b>
*
* @param <K> type of key
* @param <V> type of value
* @param name of stream
* @return RStream object
*/
<K, V> RStreamRx<K, V> getStream(String name);
/**
* Returns stream instance by <code>name</code>
* using provided <code>codec</code> for entries.
* <p>
* Requires <b>Redis 5.0.0 and higher.</b>
*
* @param <K> type of key
* @param <V> type of value
* @param name - name of stream
* @param codec - codec for entry
* @return RStream object
*/
<K, V> RStreamRx<K, V> getStream(String name, Codec codec);
/**
* Returns geospatial items holder instance by <code>name</code>.
*
* @param <V> type of value
* @param name - name of object
* @return Geo object
*/
<V> RGeoRx<V> getGeo(String name);
/**
* Returns geospatial items holder instance by <code>name</code>
* using provided codec for geospatial members.
*
* @param <V> type of value
* @param name - name of object
* @param codec - codec for value
* @return Geo object
*/
<V> RGeoRx<V> getGeo(String name, Codec codec);
/**
* Returns Set based Multimap instance by name.
*
* @param <K> type of key
* @param <V> type of value
* @param name - name of object
* @return SetMultimap object
*/
<K, V> RSetMultimapReactive<K, V> getSetMultimap(String name);
/**
* Returns Set based Multimap instance by name
* using provided codec for both map keys and values.
*
* @param <K> type of key
* @param <V> type of value
* @param name - name of object
* @param codec - codec for keys and values
* @return SetMultimap object
*/
<K, V> RSetMultimapReactive<K, V> getSetMultimap(String name, Codec codec);
/**
* Returns set-based cache instance by <code>name</code>.
* Uses map (value_hash, value) under the hood for minimal memory consumption.
* Supports value eviction with a given TTL value.
*
* <p>If eviction is not required then it's better to use regular map {@link #getSet(String, Codec)}.</p>
*
* @param <V> type of value
* @param name - name of object
* @return SetCache object
*/
<V> RSetCacheReactive<V> getSetCache(String name);
/**
* Returns set-based cache instance by <code>name</code>
* using provided <code>codec</code> for values.
* Uses map (value_hash, value) under the hood for minimal memory consumption.
* Supports value eviction with a given TTL value.
*
* <p>If eviction is not required then it's better to use regular map {@link #getSet(String, Codec)}.</p>
*
* @param <V> type of value
* @param name - name of object
* @param codec - codec for values
* @return SetCache object
*/
<V> RSetCacheReactive<V> getSetCache(String name, Codec codec);
/**
* Returns map-based cache instance by <code>name</code>
* using provided <code>codec</code> for both cache keys and values.
* Supports entry eviction with a given TTL value.
*
* <p>If eviction is not required then it's better to use regular map {@link #getMap(String, Codec)}.</p>
*
* @param <K> type of key
* @param <V> type of value
* @param name - name of object
* @param codec - codec for keys and values
* @return MapCache object
*/
<K, V> RMapCacheReactive<K, V> getMapCache(String name, Codec codec);
/**
* Returns map-based cache instance by <code>name</code>.
* Supports entry eviction with a given TTL value.
*
* <p>If eviction is not required then it's better to use regular map {@link #getMap(String)}.</p>
*
* @param <K> type of key
* @param <V> type of value
* @param name - name of object
* @return MapCache object
*/
<K, V> RMapCacheReactive<K, V> getMapCache(String name);
/**
* Returns object holder by name
*
* @param <V> type of value
* @param name - name of object
* @return Bucket object
*/
<V> RBucketReactive<V> getBucket(String name);
<V> RBucketReactive<V> getBucket(String name, Codec codec);
/**
* Returns HyperLogLog object by name
*
* @param <V> type of value
* @param name - name of object
* @return HyperLogLog object
*/
<V> RHyperLogLogReactive<V> getHyperLogLog(String name);
<V> RHyperLogLogReactive<V> getHyperLogLog(String name, Codec codec);
/**
* Returns list instance by name.
*
* @param <V> type of value
* @param name - name of object
* @return List object
*/
<V> RListReactive<V> getList(String name);
<V> RListReactive<V> getList(String name, Codec codec);
/**
* Returns List based MultiMap instance by name.
*
* @param <K> type of key
* @param <V> type of value
* @param name - name of object
* @return ListMultimap object
*/
<K, V> RListMultimapReactive<K, V> getListMultimap(String name);
/**
* Returns List based MultiMap instance by name
* using provided codec for both map keys and values.
*
* @param <K> type of key
* @param <V> type of value
* @param name - name of object
* @param codec - codec for keys and values
* @return ListMultimap object
*/
<K, V> RListMultimapReactive<K, V> getListMultimap(String name, Codec codec);
/**
* Returns map instance by name.
*
* @param <K> type of key
* @param <V> type of value
* @param name - name of object
* @return Map object
*/
<K, V> RMapReactive<K, V> getMap(String name);
<K, V> RMapReactive<K, V> getMap(String name, Codec codec);
/**
* Returns set instance by name.
*
* @param <V> type of value
* @param name - name of object
* @return Set object
*/
<V> RSetReactive<V> getSet(String name);
<V> RSetReactive<V> getSet(String name, Codec codec);
/**
* Returns topic instance by name.
*
* @param <M> type of message
* @param name - name of object
* @return Topic object
*/
<M> RTopicReactive<M> getTopic(String name);
<M> RTopicReactive<M> getTopic(String name, Codec codec);
/**
* Returns queue instance by name.
*
* @param <V> type of value
* @param name - name of object
* @return Queue object
*/
<V> RQueueReactive<V> getQueue(String name);
<V> RQueueReactive<V> getQueue(String name, Codec codec);
/**
* Returns blocking queue instance by name.
*
* @param <V> type of value
* @param name - name of object
* @return BlockingQueue object
*/
<V> RBlockingQueueReactive<V> getBlockingQueue(String name);
<V> RBlockingQueueReactive<V> getBlockingQueue(String name, Codec codec);
/**
* Returns blocking deque instance by name.
*
* @param <V> type of value
* @param name - name of object
* @return BlockingDeque object
*/
<V> RBlockingDequeReactive<V> getBlockingDeque(String name);
<V> RBlockingDequeReactive<V> getBlockingDeque(String name, Codec codec);
/**
* Returns deque instance by name.
*
* @param <V> type of value
* @param name - name of object
* @return Deque object
*/
<V> RDequeReactive<V> getDequeReactive(String name);
<V> RDequeReactive<V> getDequeReactive(String name, Codec codec);
/**
* Returns "atomic long" instance by name.
*
* @param name - name of object
* @return AtomicLong object
*/
RAtomicLongReactive getAtomicLongReactive(String name);
/**
* Returns atomicDouble instance by name.
*
* @param name - name of object
* @return AtomicDouble object
*/
RAtomicDoubleReactive getAtomicDouble(String name);
/**
* Returns Redis Sorted Set instance by name
*
* @param <V> type of value
* @param name - name of object
* @return ScoredSortedSet object
*/
<V> RScoredSortedSetReactive<V> getScoredSortedSet(String name);
<V> RScoredSortedSetReactive<V> getScoredSortedSet(String name, Codec codec);
/**
* Returns String based Redis Sorted Set instance by name
* All elements are inserted with the same score during addition,
* in order to force lexicographical ordering
*
* @param name - name of object
* @return LexSortedSet object
*/
RLexSortedSetReactive getLexSortedSet(String name);
/**
* Returns bitSet instance by name.
*
* @param name of bitSet
* @return BitSet object
*/
RBitSetReactive getBitSet(String name);
/**
* Returns script operations object
*
* @return Script object
*/
RScriptReactive getScript();
/**
* Returns keys operations.
* Each of Redis/Redisson object associated with own key
*
* @return Keys object
*/
RKeysReactive getKeys();
/**
* Executes all operations accumulated during Reactive methods invocations Reactivehronously.
*
* In cluster configurations operations grouped by slot ids
* so may be executed on different servers. Thus command execution order could be changed
*
* @return List with result object for each command
*/
Publisher<BatchResult<?>> execute();
/*
* Use BatchOptions#atomic
*/
@Deprecated
RBatchRx atomic();
/*
* Use BatchOptions#skipResult
*/
@Deprecated
RBatchRx skipResult();
/*
* Use BatchOptions#syncSlaves
*/
@Deprecated
RBatchRx syncSlaves(int slaves, long timeout, TimeUnit unit);
/*
* Use BatchOptions#responseTimeout
*/
@Deprecated
RBatchRx timeout(long timeout, TimeUnit unit);
/*
* Use BatchOptions#retryInterval
*/
@Deprecated
RBatchRx retryInterval(long retryInterval, TimeUnit unit);
/*
* Use BatchOptions#retryAttempts
*/
@Deprecated
RBatchRx retryAttempts(int retryAttempts);
}

@ -0,0 +1,169 @@
/**
* Copyright 2018 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.BitSet;
import io.reactivex.Flowable;
/**
* RxJava2 interface for BitSet object
*
* @author Nikita Koksharov
*
*/
public interface RBitSetRx extends RExpirableRx {
Flowable<byte[]> toByteArray();
/**
* Returns "logical size" = index of highest set bit plus one.
* Returns zero if there are no any set bit.
*
* @return "logical size" = index of highest set bit plus one
*/
Flowable<Long> length();
/**
* Set all bits to <code>value</code> from <code>fromIndex</code> (inclusive) to <code>toIndex</code> (exclusive)
*
* @param fromIndex inclusive
* @param toIndex exclusive
* @param value true = 1, false = 0
* @return void
*
*/
Flowable<Void> set(long fromIndex, long toIndex, boolean value);
/**
* Set all bits to zero from <code>fromIndex</code> (inclusive) to <code>toIndex</code> (exclusive)
*
* @param fromIndex inclusive
* @param toIndex exclusive
* @return void
*
*/
Flowable<Void> clear(long fromIndex, long toIndex);
/**
* Copy bits state of source BitSet object to this object
*
* @param bs - BitSet source
* @return void
*/
Flowable<Void> set(BitSet bs);
/**
* Executes NOT operation over all bits
*
* @return void
*/
Flowable<Void> not();
/**
* Set all bits to one from <code>fromIndex</code> (inclusive) to <code>toIndex</code> (exclusive)
*
* @param fromIndex inclusive
* @param toIndex exclusive
* @return void
*/
Flowable<Void> set(long fromIndex, long toIndex);
/**
* Returns number of set bits.
*
* @return number of set bits.
*/
Flowable<Long> size();
/**
* Returns <code>true</code> if bit set to one and <code>false</code> overwise.
*
* @param bitIndex - index of bit
* @return <code>true</code> if bit set to one and <code>false</code> overwise.
*/
Flowable<Boolean> get(long bitIndex);
/**
* Set bit to one at specified bitIndex
*
* @param bitIndex - index of bit
* @return <code>true</code> - if previous value was true,
* <code>false</code> - if previous value was false
*/
Flowable<Boolean> set(long bitIndex);
/**
* Set bit to <code>value</code> at specified <code>bitIndex</code>
*
* @param bitIndex - index of bit
* @param value true = 1, false = 0
* @return <code>true</code> - if previous value was true,
* <code>false</code> - if previous value was false
*/
Flowable<Boolean> set(long bitIndex, boolean value);
/**
* Returns the number of bits set to one.
*
* @return number of bits
*/
Flowable<Long> cardinality();
/**
* Set bit to zero at specified <code>bitIndex</code>
*
* @param bitIndex - index of bit
* @return <code>true</code> - if previous value was true,
* <code>false</code> - if previous value was false
*/
Flowable<Boolean> clear(long bitIndex);
/**
* Set all bits to zero
*
* @return void
*/
Flowable<Void> clear();
/**
* Executes OR operation over this object and specified bitsets.
* Stores result into this object.
*
* @param bitSetNames - name of stored bitsets
* @return void
*/
Flowable<Void> or(String... bitSetNames);
/**
* Executes AND operation over this object and specified bitsets.
* Stores result into this object.
*
* @param bitSetNames - name of stored bitsets
* @return void
*/
Flowable<Void> and(String... bitSetNames);
/**
* Executes XOR operation over this object and specified bitsets.
* Stores result into this object.
*
* @param bitSetNames - name of stored bitsets
* @return void
*/
Flowable<Void> xor(String... bitSetNames);
}

@ -0,0 +1,549 @@
/**
* Copyright 2018 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.List;
import java.util.Map;
import io.reactivex.Flowable;
/**
* Geospatial items holder. Reactive interface.
*
* @author Nikita Koksharov
*
* @param <V> type of value
*/
public interface RGeoRx<V> extends RScoredSortedSetRx<V> {
/**
* Adds geospatial member.
*
* @param longitude - longitude of object
* @param latitude - latitude of object
* @param member - object itself
* @return number of elements added to the sorted set,
* not including elements already existing for which
* the score was updated
*/
Flowable<Long> add(double longitude, double latitude, V member);
/**
* Adds geospatial members.
*
* @param entries - objects
* @return number of elements added to the sorted set,
* not including elements already existing for which
* the score was updated
*/
Flowable<Long> add(GeoEntry... entries);
/**
* Returns distance between members in <code>GeoUnit</code> units.
*
* @param firstMember - first object
* @param secondMember - second object
* @param geoUnit - geo unit
* @return distance
*/
Flowable<Double> dist(V firstMember, V secondMember, GeoUnit geoUnit);
/**
* Returns 11 characters Geohash string mapped by defined member.
*
* @param members - objects
* @return hash mapped by object
*/
Flowable<Map<V, String>> hash(V... members);
/**
* Returns geo-position mapped by defined member.
*
* @param members - objects
* @return geo position mapped by object
*/
Flowable<Map<V, GeoPosition>> pos(V... members);
/**
* Returns the members of a sorted set, which are within the
* borders of the area specified with the center location
* and the maximum distance from the center (the radius)
* in <code>GeoUnit</code> units.
*
* @param longitude - longitude of object
* @param latitude - latitude of object
* @param radius - radius in geo units
* @param geoUnit - geo unit
* @return list of objects
*/
Flowable<List<V>> radius(double longitude, double latitude, double radius, GeoUnit geoUnit);
/**
* Returns the members of a sorted set, which are within the
* borders of the area specified with the center location
* and the maximum distance from the center (the radius)
* in <code>GeoUnit</code> units and limited by count
*
* @param longitude - longitude of object
* @param latitude - latitude of object
* @param radius - radius in geo units
* @param geoUnit - geo unit
* @param count - result limit
* @return list of objects
*/
Flowable<List<V>> radius(double longitude, double latitude, double radius, GeoUnit geoUnit, int count);
/**
* Returns the members of a sorted set, which are within the
* borders of the area specified with the center location
* and the maximum distance from the center (the radius)
* in <code>GeoUnit</code> units with <code>GeoOrder</code>
*
* @param longitude - longitude of object
* @param latitude - latitude of object
* @param radius - radius in geo units
* @param geoUnit - geo unit
* @param geoOrder - order of result
* @return list of objects
*/
Flowable<List<V>> radius(double longitude, double latitude, double radius, GeoUnit geoUnit, GeoOrder geoOrder);
/**
* Returns the members of a sorted set, which are within the
* borders of the area specified with the center location
* and the maximum distance from the center (the radius)
* in <code>GeoUnit</code> units with <code>GeoOrder</code>
* and limited by count
*
* @param longitude - longitude of object
* @param latitude - latitude of object
* @param radius - radius in geo units
* @param geoUnit - geo unit
* @param geoOrder - order of result
* @param count - result limit
* @return list of objects
*/
Flowable<List<V>> radius(double longitude, double latitude, double radius, GeoUnit geoUnit, GeoOrder geoOrder, int count);
/**
* Returns the distance mapped by member, distance between member and the location.
* Members of a sorted set, which are within the
* borders of the area specified with the center location
* and the maximum distance from the center (the radius)
* in <code>GeoUnit</code> units.
*
* @param longitude - longitude of object
* @param latitude - latitude of object
* @param radius - radius in geo units
* @param geoUnit - geo unit
* @return distance mapped by object
*/
Flowable<Map<V, Double>> radiusWithDistance(double longitude, double latitude, double radius, GeoUnit geoUnit);
/**
* Returns the distance mapped by member, distance between member and the location.
* Members of a sorted set, which are within the
* borders of the area specified with the center location
* and the maximum distance from the center (the radius)
* in <code>GeoUnit</code> units and limited by count.
*
* @param longitude - longitude of object
* @param latitude - latitude of object
* @param radius - radius in geo units
* @param geoUnit - geo unit
* @param count - result limit
* @return distance mapped by object
*/
Flowable<Map<V, Double>> radiusWithDistance(double longitude, double latitude, double radius, GeoUnit geoUnit, int count);
/**
* Returns the distance mapped by member, distance between member and the location.
* Members of a sorted set, which are within the
* borders of the area specified with the center location
* and the maximum distance from the center (the radius)
* in <code>GeoUnit</code> units with <code>GeoOrder</code>
*
* @param longitude - longitude of object
* @param latitude - latitude of object
* @param radius - radius in geo units
* @param geoUnit - geo unit
* @param geoOrder - order of result
* @return distance mapped by object
*/
Flowable<Map<V, Double>> radiusWithDistance(double longitude, double latitude, double radius, GeoUnit geoUnit, GeoOrder geoOrder);
/**
* Returns the distance mapped by member, distance between member and the location.
* Members of a sorted set, which are within the
* borders of the area specified with the center location
* and the maximum distance from the center (the radius)
* in <code>GeoUnit</code> units with <code>GeoOrder</code>
* and limited by count
*
* @param longitude - longitude of object
* @param latitude - latitude of object
* @param radius - radius in geo units
* @param geoUnit - geo unit
* @param geoOrder - order of result
* @param count - result limit
* @return distance mapped by object
*/
Flowable<Map<V, Double>> radiusWithDistance(double longitude, double latitude, double radius, GeoUnit geoUnit, GeoOrder geoOrder, int count);
/**
* Returns the geo-position mapped by member.
* Members of a sorted set, which are within the
* borders of the area specified with the center location
* and the maximum distance from the center (the radius)
* in <code>GeoUnit</code> units.
*
* @param longitude - longitude of object
* @param latitude - latitude of object
* @param radius - radius in geo units
* @param geoUnit - geo unit
* @return geo position mapped by object
*/
Flowable<Map<V, GeoPosition>> radiusWithPosition(double longitude, double latitude, double radius, GeoUnit geoUnit);
/**
* Returns the geo-position mapped by member.
* Members of a sorted set, which are within the
* borders of the area specified with the center location
* and the maximum distance from the center (the radius)
* in <code>GeoUnit</code> units and limited by count
*
* @param longitude - longitude of object
* @param latitude - latitude of object
* @param radius - radius in geo units
* @param geoUnit - geo unit
* @param count - result limit
* @return geo position mapped by object
*/
Flowable<Map<V, GeoPosition>> radiusWithPosition(double longitude, double latitude, double radius, GeoUnit geoUnit, int count);
/**
* Returns the geo-position mapped by member.
* Members of a sorted set, which are within the
* borders of the area specified with the center location
* and the maximum distance from the center (the radius)
* in <code>GeoUnit</code> units with <code>GeoOrder</code>
*
* @param longitude - longitude of object
* @param latitude - latitude of object
* @param radius - radius in geo units
* @param geoUnit - geo unit
* @param geoOrder - geo order
* @return geo position mapped by object
*/
Flowable<Map<V, GeoPosition>> radiusWithPosition(double longitude, double latitude, double radius, GeoUnit geoUnit, GeoOrder geoOrder);
/**
* Returns the geo-position mapped by member.
* Members of a sorted set, which are within the
* borders of the area specified with the center location
* and the maximum distance from the center (the radius)
* in <code>GeoUnit</code> units with <code>GeoOrder</code>
* and limited by count
*
* @param longitude - longitude of object
* @param latitude - latitude of object
* @param radius - radius in geo units
* @param geoUnit - geo unit
* @param geoOrder - geo order
* @param count - result limit
* @return geo position mapped by object
*/
Flowable<Map<V, GeoPosition>> radiusWithPosition(double longitude, double latitude, double radius, GeoUnit geoUnit, GeoOrder geoOrder, int count);
/**
* Returns the members of a sorted set, which are within the
* borders of the area specified with the defined member location
* and the maximum distance from the defined member location (the radius)
* in <code>GeoUnit</code> units.
*
* @param member - object
* @param radius - radius in geo units
* @param geoUnit - geo unit
* @return list of objects
*/
Flowable<List<V>> radius(V member, double radius, GeoUnit geoUnit);
/**
* Returns the members of a sorted set, which are within the
* borders of the area specified with the defined member location
* and the maximum distance from the defined member location (the radius)
* in <code>GeoUnit</code> units and limited by count
*
* @param member - object
* @param radius - radius in geo units
* @param geoUnit - geo unit
* @param count - result limit
* @return list of objects
*/
Flowable<List<V>> radius(V member, double radius, GeoUnit geoUnit, int count);
/**
* Returns the members of a sorted set, which are within the
* borders of the area specified with the defined member location
* and the maximum distance from the defined member location (the radius)
* in <code>GeoUnit</code> units with <code>GeoOrder</code>
*
* @param member - object
* @param radius - radius in geo units
* @param geoUnit - geo unit
* @param geoOrder - geo order
* @return list of objects
*/
Flowable<List<V>> radius(V member, double radius, GeoUnit geoUnit, GeoOrder geoOrder);
/**
* Returns the members of a sorted set, which are within the
* borders of the area specified with the defined member location
* and the maximum distance from the defined member location (the radius)
* in <code>GeoUnit</code> units with <code>GeoOrder</code>
*
* @param member - object
* @param radius - radius in geo units
* @param geoUnit - geo unit
* @param geoOrder - geo order
* @param count - result limit
* @return list of objects
*/
Flowable<List<V>> radius(V member, double radius, GeoUnit geoUnit, GeoOrder geoOrder, int count);
/**
* Returns the distance mapped by member, distance between member and the defined member location.
* Members of a sorted set, which are within the
* borders of the area specified with the defined member location
* and the maximum distance from the defined member location (the radius)
* in <code>GeoUnit</code> units.
*
* @param member - object
* @param radius - radius in geo units
* @param geoUnit - geo unit
* @return distance mapped by object
*/
Flowable<Map<V, Double>> radiusWithDistance(V member, double radius, GeoUnit geoUnit);
/**
* Returns the distance mapped by member, distance between member and the defined member location.
* Members of a sorted set, which are within the
* borders of the area specified with the defined member location
* and the maximum distance from the defined member location (the radius)
* in <code>GeoUnit</code> units and limited by count
*
* @param member - object
* @param radius - radius in geo units
* @param geoUnit - geo unit
* @param count - result limit
* @return distance mapped by object
*/
Flowable<Map<V, Double>> radiusWithDistance(V member, double radius, GeoUnit geoUnit, int count);
/**
* Returns the distance mapped by member, distance between member and the defined member location.
* Members of a sorted set, which are within the
* borders of the area specified with the defined member location
* and the maximum distance from the defined member location (the radius)
* in <code>GeoUnit</code> units with <code>GeoOrder</code>
*
* @param member - object
* @param radius - radius in geo units
* @param geoUnit - geo unit
* @param geoOrder - geo
* @return distance mapped by object
*/
Flowable<Map<V, Double>> radiusWithDistance(V member, double radius, GeoUnit geoUnit, GeoOrder geoOrder);
/**
* Returns the distance mapped by member, distance between member and the defined member location.
* Members of a sorted set, which are within the
* borders of the area specified with the defined member location
* and the maximum distance from the defined member location (the radius)
* in <code>GeoUnit</code> units with <code>GeoOrder</code>
* and limited by count
*
* @param member - object
* @param radius - radius in geo units
* @param geoUnit - geo unit
* @param geoOrder - geo
* @param count - result limit
* @return distance mapped by object
*/
Flowable<Map<V, Double>> radiusWithDistance(V member, double radius, GeoUnit geoUnit, GeoOrder geoOrder, int count);
/**
* Returns the geo-position mapped by member.
* Members of a sorted set, which are within the
* borders of the area specified with the defined member location
* and the maximum distance from the defined member location (the radius)
* in <code>GeoUnit</code> units.
*
* @param member - object
* @param radius - radius in geo units
* @param geoUnit - geo unit
* @return geo position mapped by object
*/
Flowable<Map<V, GeoPosition>> radiusWithPosition(V member, double radius, GeoUnit geoUnit);
/**
* Returns the geo-position mapped by member.
* Members of a sorted set, which are within the
* borders of the area specified with the defined member location
* and the maximum distance from the defined member location (the radius)
* in <code>GeoUnit</code> units and limited by count
*
* @param member - object
* @param radius - radius in geo units
* @param geoUnit - geo unit
* @param count - result limit
* @return geo position mapped by object
*/
Flowable<Map<V, GeoPosition>> radiusWithPosition(V member, double radius, GeoUnit geoUnit, int count);
/**
* Returns the geo-position mapped by member.
* Members of a sorted set, which are within the
* borders of the area specified with the defined member location
* and the maximum distance from the defined member location (the radius)
* in <code>GeoUnit</code> units with <code>GeoOrder</code>
*
* @param member - object
* @param radius - radius in geo units
* @param geoUnit - geo unit
* @param geoOrder - geo order
* @return geo position mapped by object
*/
Flowable<Map<V, GeoPosition>> radiusWithPosition(V member, double radius, GeoUnit geoUnit, GeoOrder geoOrder);
/**
* Returns the geo-position mapped by member.
* Members of a sorted set, which are within the
* borders of the area specified with the defined member location
* and the maximum distance from the defined member location (the radius)
* in <code>GeoUnit</code> units with <code>GeoOrder</code>
* and limited by count
*
* @param member - object
* @param radius - radius in geo units
* @param geoUnit - geo unit
* @param geoOrder - geo order
* @param count - result limit
* @return geo position mapped by object
*/
Flowable<Map<V, GeoPosition>> radiusWithPosition(V member, double radius, GeoUnit geoUnit, GeoOrder geoOrder, int count);
/**
* Finds the members of a sorted set, which are within the
* borders of the area specified with the center location
* and the maximum distance from the center (the radius)
* in <code>GeoUnit</code> units.
* Store result to <code>destName</code>.
*
* @param destName - Geo object destination
* @param longitude - longitude of object
* @param latitude - latitude of object
* @param radius - radius in geo units
* @param geoUnit - geo unit
* @return length of result
*/
Flowable<Long> radiusStoreTo(String destName, double longitude, double latitude, double radius, GeoUnit geoUnit);
/**
* Finds the members of a sorted set, which are within the
* borders of the area specified with the center location
* and the maximum distance from the center (the radius)
* in <code>GeoUnit</code> units and limited by count
* Store result to <code>destName</code>.
*
* @param destName - Geo object destination
* @param longitude - longitude of object
* @param latitude - latitude of object
* @param radius - radius in geo units
* @param geoUnit - geo unit
* @param count - result limit
* @return length of result
*/
Flowable<Long> radiusStoreTo(String destName, double longitude, double latitude, double radius, GeoUnit geoUnit, int count);
/**
* Finds the members of a sorted set, which are within the
* borders of the area specified with the center location
* and the maximum distance from the center (the radius)
* in <code>GeoUnit</code> units with <code>GeoOrder</code>
* and limited by count
* Store result to <code>destName</code>.
*
* @param destName - Geo object destination
* @param longitude - longitude of object
* @param latitude - latitude of object
* @param radius - radius in geo units
* @param geoUnit - geo unit
* @param geoOrder - order of result
* @param count - result limit
* @return length of result
*/
Flowable<Long> radiusStoreTo(String destName, double longitude, double latitude, double radius, GeoUnit geoUnit, GeoOrder geoOrder, int count);
/**
* Finds the members of a sorted set, which are within the
* borders of the area specified with the defined member location
* and the maximum distance from the defined member location (the radius)
* in <code>GeoUnit</code> units.
* Store result to <code>destName</code>.
*
* @param destName - Geo object destination
* @param member - object
* @param radius - radius in geo units
* @param geoUnit - geo unit
* @return length of result
*/
Flowable<Long> radiusStoreTo(String destName, V member, double radius, GeoUnit geoUnit);
/**
* Finds the members of a sorted set, which are within the
* borders of the area specified with the defined member location
* and the maximum distance from the defined member location (the radius)
* in <code>GeoUnit</code> units and limited by count
* Store result to <code>destName</code>.
*
* @param destName - Geo object destination
* @param member - object
* @param radius - radius in geo units
* @param geoUnit - geo unit
* @param count - result limit
* @return length of result
*/
Flowable<Long> radiusStoreTo(String destName, V member, double radius, GeoUnit geoUnit, int count);
/**
* Finds the members of a sorted set, which are within the
* borders of the area specified with the defined member location
* and the maximum distance from the defined member location (the radius)
* in <code>GeoUnit</code> units with <code>GeoOrder</code>
* Store result to <code>destName</code>.
*
* @param destName - Geo object destination
* @param member - object
* @param radius - radius in geo units
* @param geoUnit - geo unit
* @param geoOrder - geo order
* @param count - result limit
* @return length of result
*/
Flowable<Long> radiusStoreTo(String destName, V member, double radius, GeoUnit geoUnit, GeoOrder geoOrder, int count);
}

@ -0,0 +1,73 @@
/**
* Copyright 2018 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 io.reactivex.Flowable;
/**
* Probabilistic data structure that lets you maintain counts of millions of items with extreme space efficiency.
* RxJava2 interface.
*
* @author Nikita Koksharov
*
* @param <V> type of stored values
*/
public interface RHyperLogLogRx<V> extends RExpirableRx {
/**
* Adds element into this structure.
*
* @param obj - element to add
* @return <code>true</code> if object has been added
* or <code>false</code> if it was already added
*/
Flowable<Boolean> add(V obj);
/**
* Adds all elements contained in <code>objects</code> collection into this structure
*
* @param objects - elements to add
* @return <code>true</code> if at least one object has been added
* or <code>false</code> if all were already added
*/
Flowable<Boolean> addAll(Collection<V> objects);
/**
* Returns approximated number of unique elements added into this structure.
*
* @return approximated number of unique elements added into this structure
*/
Flowable<Long> count();
/**
* Returns approximated number of unique elements
* added into this instances and other instances defined through <code>otherLogNames</code>.
*
* @param otherLogNames - name of instances
* @return
*/
Flowable<Long> countWith(String ... otherLogNames);
/**
* Merges multiple instances into this instance.
*
* @param otherLogNames - name of instances
*/
Flowable<Void> mergeWith(String ... otherLogNames);
}

@ -0,0 +1,83 @@
/**
* Copyright 2018 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.List;
import io.reactivex.Flowable;
/**
* RxJava2 interface for List based Multimap object
*
* @author Nikita Koksharov
*
* @param <K> key type
* @param <V> value type
*/
public interface RListMultimapRx<K, V> extends RMultimapRx<K, V> {
/**
* Returns a view List of the values associated with {@code key} in this
* multimap, if any. Note that when {@code containsKey(key)} is false, this
* returns an empty collection, not {@code null}.
*
* <p>Changes to the returned collection will update the underlying multimap,
* and vice versa.
*
* @param key - map key
* @return list of values
*/
RListRx<V> get(K key);
/**
* Returns all elements at once. Result Set is <b>NOT</b> backed by map,
* so changes are not reflected in map.
*
* @param key - map key
* @return list of values
*/
Flowable<List<V>> getAll(K key);
/**
* Removes all values associated with the key {@code key}.
*
* <p>Once this method returns, {@code key} will not be mapped to any values
* <p>Use {@link RMultimapReactive#fastRemove} if values are not needed.</p>
*
* @param key - map key
* @return the values that were removed (possibly empty). The returned
* list <i>may</i> be modifiable, but updating it will have no
* effect on the multimap.
*/
Flowable<List<V>> removeAll(Object key);
/**
* Stores a collection of values with the same key, replacing any existing
* values for that key.
*
* <p>If {@code values} is empty, this is equivalent to
* {@link #removeAll(Object)}.
*
* @param key - map key
* @param values - map values
* @return list of replaced values, or an empty collection if no
* values were previously associated with the key. List
* <i>may</i> be modifiable, but updating it will have no effect on the
* multimap.
*/
Flowable<List<V>> replaceValues(K key, Iterable<? extends V> values);
}

@ -0,0 +1,106 @@
/**
* Copyright 2018 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;
import io.reactivex.Flowable;
/**
* list functions
*
* @author Nikita Koksharov
*
* @param <V> the type of elements held in this collection
*/
// TODO add sublist support
public interface RListRx<V> extends RCollectionRx<V>, RSortableRx<List<V>> {
/**
* Loads elements by specified <code>indexes</code>
*
* @param indexes of elements
* @return elements
*/
Flowable<List<V>> get(int ...indexes);
/**
* Add <code>element</code> after <code>elementToFind</code>
*
* @param elementToFind - object to find
* @param element - object to add
* @return new list size
*/
Flowable<Integer> addAfter(V elementToFind, V element);
/**
* Add <code>element</code> before <code>elementToFind</code>
*
* @param elementToFind - object to find
* @param element - object to add
* @return new list size
*/
Flowable<Integer> addBefore(V elementToFind, V element);
Flowable<V> descendingIterator();
Flowable<V> descendingIterator(int startIndex);
Flowable<V> iterator(int startIndex);
Flowable<Integer> lastIndexOf(Object o);
Flowable<Integer> indexOf(Object o);
Flowable<Void> add(int index, V element);
Flowable<Boolean> addAll(int index, Collection<? extends V> coll);
Flowable<Void> fastSet(int index, V element);
Flowable<V> set(int index, V element);
Flowable<V> get(int index);
Flowable<V> remove(int index);
/**
* Read all elements at once
*
* @return list of values
*/
Flowable<List<V>> readAll();
/**
* Trim list and remains elements only in specified range
* <code>fromIndex</code>, inclusive, and <code>toIndex</code>, inclusive.
*
* @param fromIndex - from index
* @param toIndex - to index
* @return void
*/
Flowable<Void> trim(int fromIndex, int toIndex);
/**
* Remove object by specified index
*
* @param index - index of object
* @return void
*/
Flowable<Void> fastRemove(int index);
}

@ -0,0 +1,55 @@
/**
* Copyright 2018 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.concurrent.TimeUnit;
import io.reactivex.Flowable;
/**
* RxJava2 interface for Lock object
*
* @author Nikita Koksharov
*
*/
public interface RLockRx extends RExpirableRx {
Flowable<Boolean> forceUnlock();
Flowable<Void> unlock();
Flowable<Void> unlock(long threadId);
Flowable<Boolean> tryLock();
Flowable<Void> lock();
Flowable<Void> lock(long threadId);
Flowable<Void> lock(long leaseTime, TimeUnit unit);
Flowable<Void> lock(long leaseTime, TimeUnit unit, long threadId);
Flowable<Boolean> tryLock(long threadId);
Flowable<Boolean> tryLock(long waitTime, TimeUnit unit);
Flowable<Boolean> tryLock(long waitTime, long leaseTime, TimeUnit unit);
Flowable<Boolean> tryLock(long waitTime, long leaseTime, TimeUnit unit, long threadId);
}

@ -0,0 +1,140 @@
/**
* Copyright 2018 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.Set;
import io.reactivex.Flowable;
/**
* Base RxJava2 interface for Multimap object
*
* @author Nikita Koksharov
*
* @param <K> key type
* @param <V> value type
*/
public interface RMultimapRx<K, V> extends RExpirableRx {
/**
* Returns the number of key-value pairs in this multimap.
*
* @return size of multimap
*/
Flowable<Integer> size();
/**
* Returns {@code true} if this multimap contains at least one key-value pair
* with the key {@code key}.
*
* @param key - map key
* @return <code>true</code> if contains a key
*/
Flowable<Boolean> containsKey(Object key);
/**
* Returns {@code true} if this multimap contains at least one key-value pair
* with the value {@code value}.
*
* @param value - map value
* @return <code>true</code> if contains a value
*/
Flowable<Boolean> containsValue(Object value);
/**
* Returns {@code true} if this multimap contains at least one key-value pair
* with the key {@code key} and the value {@code value}.
*
* @param key - map key
* @param value - map value
* @return <code>true</code> if contains an entry
*/
Flowable<Boolean> containsEntry(Object key, Object value);
/**
* Stores a key-value pair in this multimap.
*
* <p>Some multimap implementations allow duplicate key-value pairs, in which
* case {@code put} always adds a new key-value pair and increases the
* multimap size by 1. Other implementations prohibit duplicates, and storing
* a key-value pair that's already in the multimap has no effect.
*
* @param key - map key
* @param value - map value
* @return {@code true} if the method increased the size of the multimap, or
* {@code false} if the multimap already contained the key-value pair and
* doesn't allow duplicates
*/
Flowable<Boolean> put(K key, V value);
/**
* Removes a single key-value pair with the key {@code key} and the value
* {@code value} from this multimap, if such exists. If multiple key-value
* pairs in the multimap fit this description, which one is removed is
* unspecified.
*
* @param key - map key
* @param value - map value
* @return {@code true} if the multimap changed
*/
Flowable<Boolean> remove(Object key, Object value);
// Bulk Operations
/**
* Stores a key-value pair in this multimap for each of {@code values}, all
* using the same key, {@code key}. Equivalent to (but expected to be more
* efficient than): <pre> {@code
*
* for (V value : values) {
* put(key, value);
* }}</pre>
*
* <p>In particular, this is a no-op if {@code values} is empty.
*
* @param key - map key
* @param values - map values
* @return {@code true} if the multimap changed
*/
Flowable<Boolean> putAll(K key, Iterable<? extends V> values);
/**
* Returns the number of key-value pairs in this multimap.
*
* @return keys amount
*/
Flowable<Integer> keySize();
/**
* Removes <code>keys</code> from map by one operation
*
* Works faster than <code>RMultimap.remove</code> but not returning
* the value associated with <code>key</code>
*
* @param keys - map keys
* @return the number of keys that were removed from the hash, not including specified but non existing keys
*/
Flowable<Long> fastRemove(K ... keys);
/**
* Read all keys at once
*
* @return keys
*/
Flowable<Set<K>> readAllKeySet();
}

@ -0,0 +1,234 @@
/**
* Copyright 2018 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.concurrent.TimeUnit;
import io.reactivex.Flowable;
/**
* RxJava2 interface for Semaphore object with support of lease time parameter for each acquired permit.
*
* <p>Each permit identified by own id and could be released only using its id.
* Permit id is a 128-bits unique random identifier generated each time during acquiring.
*
* <p>Works in non-fair mode. Therefore order of acquiring is unpredictable.
*
* @author Nikita Koksharov
*
*/
public interface RPermitExpirableSemaphoreRx extends RExpirableRx {
/**
* Acquires a permit from this semaphore, blocking until one is
* available, or the thread is {@linkplain Thread#interrupt interrupted}.
*
* <p>Acquires a permit, if one is available and returns its id,
* reducing the number of available permits by one.
*
* <p>If no permit is available then the current thread becomes
* disabled for thread scheduling purposes and lies dormant until
* one of two things happens:
* <ul>
* <li>Some other thread invokes the {@link #release(String)} method for this
* semaphore and the current thread is next to be assigned a permit; or
* <li>Some other thread {@linkplain Thread#interrupt interrupts}
* the current thread.
* </ul>
*
* @return permit id
*/
Flowable<String> acquire();
/**
* Acquires a permit with defined lease time from this semaphore,
* blocking until one is available,
* or the thread is {@linkplain Thread#interrupt interrupted}.
*
* <p>Acquires a permit, if one is available and returns its id,
* reducing the number of available permits by one.
*
* <p>If no permit is available then the current thread becomes
* disabled for thread scheduling purposes and lies dormant until
* one of two things happens:
* <ul>
* <li>Some other thread invokes the {@link #release} method for this
* semaphore and the current thread is next to be assigned a permit; or
* <li>Some other thread {@linkplain Thread#interrupt interrupts}
* the current thread.
* </ul>
*
* @param leaseTime - permit lease time
* @param unit - time unit
* @return permit id
*/
Flowable<String> acquire(long leaseTime, TimeUnit unit);
/**
* Acquires a permit only if one is available at the
* time of invocation.
*
* <p>Acquires a permit, if one is available and returns immediately,
* with the permit id,
* reducing the number of available permits by one.
*
* <p>If no permit is available then this method will return
* immediately with the value {@code null}.
*
* @return permit id if a permit was acquired and {@code null}
* otherwise
*/
Flowable<String> tryAcquire();
/**
* Acquires a permit from this semaphore, if one becomes available
* within the given waiting time and the current thread has not
* been {@linkplain Thread#interrupt interrupted}.
*
* <p>Acquires a permit, if one is available and returns immediately,
* with the permit id,
* reducing the number of available permits by one.
*
* <p>If no permit is available then the current thread becomes
* disabled for thread scheduling purposes and lies dormant until
* one of three things happens:
* <ul>
* <li>Some other thread invokes the {@link #release(String)} method for this
* semaphore and the current thread is next to be assigned a permit; or
* <li>Some other thread {@linkplain Thread#interrupt interrupts}
* the current thread; or
* <li>The specified waiting time elapses.
* </ul>
*
* <p>If a permit is acquired then the permit id is returned.
*
* <p>If the specified waiting time elapses then the value {@code null}
* is returned. If the time is less than or equal to zero, the method
* will not wait at all.
*
* @param waitTime the maximum time to wait for a permit
* @param unit the time unit of the {@code timeout} argument
* @return permit id if a permit was acquired and {@code null}
* if the waiting time elapsed before a permit was acquired
*/
Flowable<String> tryAcquire(long waitTime, TimeUnit unit);
/**
* Acquires a permit with defined lease time from this semaphore,
* if one becomes available
* within the given waiting time and the current thread has not
* been {@linkplain Thread#interrupt interrupted}.
*
* <p>Acquires a permit, if one is available and returns immediately,
* with the permit id,
* reducing the number of available permits by one.
*
* <p>If no permit is available then the current thread becomes
* disabled for thread scheduling purposes and lies dormant until
* one of three things happens:
* <ul>
* <li>Some other thread invokes the {@link #release(String)} method for this
* semaphore and the current thread is next to be assigned a permit; or
* <li>Some other thread {@linkplain Thread#interrupt interrupts}
* the current thread; or
* <li>The specified waiting time elapses.
* </ul>
*
* <p>If a permit is acquired then the permit id is returned.
*
* <p>If the specified waiting time elapses then the value {@code null}
* is returned. If the time is less than or equal to zero, the method
* will not wait at all.
*
* @param waitTime the maximum time to wait for a permit
* @param leaseTime permit lease time
* @param unit the time unit of the {@code timeout} argument
* @return permit id if a permit was acquired and {@code null}
* if the waiting time elapsed before a permit was acquired
*/
Flowable<String> tryAcquire(long waitTime, long leaseTime, TimeUnit unit);
/**
* Releases a permit by its id, returning it to the semaphore.
*
* <p>Releases a permit, increasing the number of available permits by
* one. If any threads of Redisson client are trying to acquire a permit,
* then one is selected and given the permit that was just released.
*
* <p>There is no requirement that a thread that releases a permit must
* have acquired that permit by calling {@link #acquire()}.
* Correct usage of a semaphore is established by programming convention
* in the application.
*
* @param permitId - permit id
* @return {@code true} if a permit has been released and {@code false}
* otherwise
*/
Flowable<Boolean> tryRelease(String permitId);
/**
* Releases a permit by its id, returning it to the semaphore.
*
* <p>Releases a permit, increasing the number of available permits by
* one. If any threads of Redisson client are trying to acquire a permit,
* then one is selected and given the permit that was just released.
*
* <p>There is no requirement that a thread that releases a permit must
* have acquired that permit by calling {@link #acquire()}.
* Correct usage of a semaphore is established by programming convention
* in the application.
*
* <p>Throws an exception if permit id doesn't exist or has already been release
*
* @param permitId - permit id
* @return void
*/
Flowable<Void> release(String permitId);
/**
* Returns the current number of available permits.
*
* @return number of available permits
*/
Flowable<Integer> availablePermits();
/**
* Sets number of permits.
*
* @param permits - number of permits
* @return <code>true</code> if permits has been set successfully, otherwise <code>false</code>.
*/
Flowable<Boolean> trySetPermits(int permits);
/**
* Increases or decreases the number of available permits by defined value.
*
* @param permits - number of permits to add/remove
* @return void
*/
Flowable<Void> addPermits(int permits);
/**
* Overrides and updates lease time for defined permit id.
*
* @param permitId - permit id
* @param leaseTime - permit lease time, use -1 to make it permanent
* @param unit - the time unit of the {@code timeout} argument
* @return <code>true</code> if permits has been updated successfully, otherwise <code>false</code>.
*/
Flowable<Boolean> updateLeaseTime(String permitId, long leaseTime, TimeUnit unit);
}

@ -0,0 +1,145 @@
/**
* Copyright 2018 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.concurrent.TimeUnit;
import io.reactivex.Flowable;
/**
* RxJava2 interface for Rate Limiter object
*
* @author Nikita Koksharov
*
*/
public interface RRateLimiterRx extends RObjectRx {
/**
* Initializes RateLimiter's state and stores config to Redis server.
*
* @param mode - rate mode
* @param rate - rate
* @param rateInterval - rate time interval
* @param rateIntervalUnit - rate time interval unit
* @return
*/
Flowable<Boolean> trySetRate(RateType mode, long rate, long rateInterval, RateIntervalUnit rateIntervalUnit);
/**
* Acquires a permit only if one is available at the
* time of invocation.
*
* <p>Acquires a permit, if one is available and returns immediately,
* with the value {@code true},
* reducing the number of available permits by one.
*
* <p>If no permit is available then this method will return
* immediately with the value {@code false}.
*
* @return {@code true} if a permit was acquired and {@code false}
* otherwise
*/
Flowable<Boolean> tryAcquire();
/**
* Acquires the given number of <code>permits</code> only if all are available at the
* time of invocation.
*
* <p>Acquires a permits, if all are available and returns immediately,
* with the value {@code true},
* reducing the number of available permits by given number of permits.
*
* <p>If no permits are available then this method will return
* immediately with the value {@code false}.
*
* @param permits the number of permits to acquire
* @return {@code true} if a permit was acquired and {@code false}
* otherwise
*/
Flowable<Boolean> tryAcquire(long permits);
/**
* Acquires a permit from this RateLimiter, blocking until one is available.
*
* <p>Acquires a permit, if one is available and returns immediately,
* reducing the number of available permits by one.
*
*/
Flowable<Void> acquire();
/**
* Acquires a specified <code>permits</code> from this RateLimiter,
* blocking until one is available.
*
* <p>Acquires the given number of permits, if they are available
* and returns immediately, reducing the number of available permits
* by the given amount.
*
* @param permits
*/
Flowable<Void> acquire(long permits);
/**
* Acquires a permit from this RateLimiter, if one becomes available
* within the given waiting time.
*
* <p>Acquires a permit, if one is available and returns immediately,
* with the value {@code true},
* reducing the number of available permits by one.
*
* <p>If no permit is available then the current thread becomes
* disabled for thread scheduling purposes and lies dormant until
* specified waiting time elapses.
*
* <p>If a permit is acquired then the value {@code true} is returned.
*
* <p>If the specified waiting time elapses then the value {@code false}
* is returned. If the time is less than or equal to zero, the method
* will not wait at all.
*
* @param timeout the maximum time to wait for a permit
* @param unit the time unit of the {@code timeout} argument
* @return {@code true} if a permit was acquired and {@code false}
* if the waiting time elapsed before a permit was acquired
*/
Flowable<Boolean> tryAcquire(long timeout, TimeUnit unit);
/**
* Acquires the given number of <code>permits</code> only if all are available
* within the given waiting time.
*
* <p>Acquires the given number of permits, if all are available and returns immediately,
* with the value {@code true}, reducing the number of available permits by one.
*
* <p>If no permit is available then the current thread becomes
* disabled for thread scheduling purposes and lies dormant until
* the specified waiting time elapses.
*
* <p>If a permits is acquired then the value {@code true} is returned.
*
* <p>If the specified waiting time elapses then the value {@code false}
* is returned. If the time is less than or equal to zero, the method
* will not wait at all.
*
* @param permits amount
* @param timeout the maximum time to wait for a permit
* @param unit the time unit of the {@code timeout} argument
* @return {@code true} if a permit was acquired and {@code false}
* if the waiting time elapsed before a permit was acquired
*/
Flowable<Boolean> tryAcquire(long permits, long timeout, TimeUnit unit);
}

@ -0,0 +1,49 @@
/**
* Copyright 2018 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.concurrent.locks.Lock;
/**
* A {@code ReadWriteLock} maintains a pair of associated {@link
* Lock locks}, one for read-only operations and one for writing.
* The {@link #readLock read lock} may be held simultaneously by
* multiple reader threads, so long as there are no writers. The
* {@link #writeLock write lock} is exclusive.
*
* Works in non-fair mode. Therefore order of read and write
* locking is unspecified.
*
* @author Nikita Koksharov
*
*/
public interface RReadWriteLockRx {
/**
* Returns the lock used for reading.
*
* @return the lock used for reading
*/
RLockRx readLock();
/**
* Returns the lock used for writing.
*
* @return the lock used for writing
*/
RLockRx writeLock();
}

@ -0,0 +1,420 @@
/**
* Copyright 2018 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.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.redisson.api.RScoredSortedSet.Aggregate;
import org.redisson.client.protocol.ScoredEntry;
import io.reactivex.Flowable;
/**
* RxJava2 interface for scored sorted set data structure.
*
* @author Nikita Koksharov
*
* @param <V> value type
*/
public interface RScoredSortedSetRx<V> extends RExpirableRx, RSortableRx<Set<V>> {
/**
* Removes and returns first available tail element of <b>any</b> sorted set,
* waiting up to the specified wait time if necessary for an element to become available
* in any of defined sorted sets <b>including</b> this one.
* <p>
* Requires <b>Redis 5.0.0 and higher.</b>
*
* @param queueNames - names of queue
* @param timeout how long to wait before giving up, in units of
* {@code unit}
* @param unit a {@code TimeUnit} determining how to interpret the
* {@code timeout} parameter
* @return the tail element, or {@code null} if all sorted sets are empty
*/
Flowable<V> pollLastFromAny(long timeout, TimeUnit unit, String ... queueNames);
/**
* Removes and returns first available head element of <b>any</b> sorted set,
* waiting up to the specified wait time if necessary for an element to become available
* in any of defined sorted sets <b>including</b> this one.
* <p>
* Requires <b>Redis 5.0.0 and higher.</b>
*
* @param queueNames - names of queue
* @param timeout how long to wait before giving up, in units of
* {@code unit}
* @param unit a {@code TimeUnit} determining how to interpret the
* {@code timeout} parameter
* @return the head element, or {@code null} if all sorted sets are empty
*
*/
Flowable<V> pollFirstFromAny(long timeout, TimeUnit unit, String ... queueNames);
/**
* Removes and returns the head element or {@code null} if this sorted set is empty.
* <p>
* Requires <b>Redis 5.0.0 and higher.</b>
*
* @param timeout how long to wait before giving up, in units of
* {@code unit}
* @param unit a {@code TimeUnit} determining how to interpret the
* {@code timeout} parameter
* @return the head element,
* or {@code null} if this sorted set is empty
*/
Flowable<V> pollFirst(long timeout, TimeUnit unit);
/**
* Removes and returns the tail element or {@code null} if this sorted set is empty.
* <p>
* Requires <b>Redis 5.0.0 and higher.</b>
*
* @param timeout how long to wait before giving up, in units of
* {@code unit}
* @param unit a {@code TimeUnit} determining how to interpret the
* {@code timeout} parameter
* @return the tail element or {@code null} if this sorted set is empty
*/
Flowable<V> pollLast(long timeout, TimeUnit unit);
/**
* Removes and returns the head elements or {@code null} if this sorted set is empty.
*
* @param count - elements amount
* @return the head element,
* or {@code null} if this sorted set is empty
*/
Flowable<Collection<V>> pollFirst(int count);
/**
* Removes and returns the tail elements or {@code null} if this sorted set is empty.
*
* @param count - elements amount
* @return the tail element or {@code null} if this sorted set is empty
*/
Flowable<Collection<V>> pollLast(int count);
/**
* Removes and returns the head element or {@code null} if this sorted set is empty.
*
* @return the head element,
* or {@code null} if this sorted set is empty
*/
Flowable<V> pollFirst();
/**
* Removes and returns the tail element or {@code null} if this sorted set is empty.
*
* @return the tail element or {@code null} if this sorted set is empty
*/
Flowable<V> pollLast();
/**
* Returns the head element or {@code null} if this sorted set is empty.
*
* @return the head element or {@code null} if this sorted set is empty
*/
Flowable<V> first();
/**
* Returns the tail element or {@code null} if this sorted set is empty.
*
* @return the tail element or {@code null} if this sorted set is empty
*/
Flowable<V> last();
/**
* Returns score of the head element or returns {@code null} if this sorted set is empty.
*
* @return the tail element or {@code null} if this sorted set is empty
*/
Flowable<Double> firstScore();
/**
* Returns score of the tail element or returns {@code null} if this sorted set is empty.
*
* @return the tail element or {@code null} if this sorted set is empty
*/
Flowable<Double> lastScore();
/**
* Returns an iterator over elements in this set.
* If <code>pattern</code> is not null then only elements match this pattern are loaded.
*
* @param pattern - search pattern
* @return iterator
*/
Flowable<V> iterator(String pattern);
/**
* Returns an iterator over elements in this set.
* Elements are loaded in batch. Batch size is defined by <code>count</code> param.
*
* @param count - size of elements batch
* @return iterator
*/
Flowable<V> iterator(int count);
/**
* Returns an iterator over elements in this set.
* Elements are loaded in batch. Batch size is defined by <code>count</code> param.
* If pattern is not null then only elements match this pattern are loaded.
*
* @param pattern - search pattern
* @param count - size of elements batch
* @return iterator
*/
Flowable<V> iterator(String pattern, int count);
Flowable<V> iterator();
Flowable<Integer> removeRangeByScore(double startScore, boolean startScoreInclusive, double endScore, boolean endScoreInclusive);
Flowable<Integer> removeRangeByRank(int startIndex, int endIndex);
/**
* Returns rank of value, with the scores ordered from low to high.
*
* @param o - object
* @return rank or <code>null</code> if value does not exist
*/
Flowable<Integer> rank(V o);
/**
* Returns rank of value, with the scores ordered from high to low.
*
* @param o - object
* @return rank or <code>null</code> if value does not exist
*/
Flowable<Integer> revRank(V o);
Flowable<Double> getScore(V o);
/**
* Adds element to this set, overrides previous score if it has been already added.
*
* @param score - object score
* @param object - object itself
* @return <code>true</code> if element has added and <code>false</code> if not.
*/
Flowable<Boolean> add(double score, V object);
Flowable<Long> addAll(Map<V, Double> objects);
/**
* Adds element to this set, overrides previous score if it has been already added.
* Finally return the rank of the item
*
* @param score - object score
* @param object - object itself
* @return rank
*/
Flowable<Integer> addAndGetRank(double score, V object);
/**
* Adds element to this set, overrides previous score if it has been already added.
* Finally return the reverse rank of the item
*
* @param score - object score
* @param object - object itself
* @return reverse rank
*/
Flowable<Integer> addAndGetRevRank(double score, V object);
/**
* Adds element to this set only if has not been added before.
* <p>
* Requires <b>Redis 3.0.2 and higher.</b>
*
* @param score - object score
* @param object - object itself
* @return <code>true</code> if element has added and <code>false</code> if not.
*/
Flowable<Boolean> tryAdd(double score, V object);
Flowable<Boolean> remove(V object);
Flowable<Integer> size();
Flowable<Boolean> contains(V o);
Flowable<Boolean> containsAll(Collection<?> c);
Flowable<Boolean> removeAll(Collection<?> c);
Flowable<Boolean> retainAll(Collection<?> c);
Flowable<Double> addScore(V object, Number value);
/**
* Adds score to element and returns its reverse rank
*
* @param object - object itself
* @param value - object score
* @return reverse rank
*/
Flowable<Integer> addScoreAndGetRevRank(V object, Number value);
/**
* Adds score to element and returns its rank
*
* @param object - object itself
* @param value - object score
* @return rank
*/
Flowable<Integer> addScoreAndGetRank(V object, Number value);
Flowable<Collection<V>> valueRange(int startIndex, int endIndex);
Flowable<Collection<ScoredEntry<V>>> entryRange(int startIndex, int endIndex);
Flowable<Collection<V>> valueRange(double startScore, boolean startScoreInclusive, double endScore, boolean endScoreInclusive);
Flowable<Collection<ScoredEntry<V>>> entryRange(double startScore, boolean startScoreInclusive, double endScore, boolean endScoreInclusive);
Flowable<Collection<V>> valueRange(double startScore, boolean startScoreInclusive, double endScore, boolean endScoreInclusive, int offset, int count);
Flowable<Collection<ScoredEntry<V>>> entryRange(double startScore, boolean startScoreInclusive, double endScore, boolean endScoreInclusive, int offset, int count);
Flowable<Collection<V>> valueRangeReversed(int startIndex, int endIndex);
/**
* Returns all values between <code>startScore</code> and <code>endScore</code> in reversed order.
*
* @param startScore - start score.
* Use <code>Double.POSITIVE_INFINITY</code> or <code>Double.NEGATIVE_INFINITY</code>
* to define infinity numbers
* @param startScoreInclusive - start score inclusive
* @param endScore - end score
* Use <code>Double.POSITIVE_INFINITY</code> or <code>Double.NEGATIVE_INFINITY</code>
* to define infinity numbers
*
* @param endScoreInclusive - end score inclusive
* @return values
*/
Flowable<Collection<V>> valueRangeReversed(double startScore, boolean startScoreInclusive, double endScore, boolean endScoreInclusive);
Flowable<Collection<V>> valueRangeReversed(double startScore, boolean startScoreInclusive, double endScore, boolean endScoreInclusive, int offset, int count);
Flowable<Collection<ScoredEntry<V>>> entryRangeReversed(int startIndex, int endIndex);
Flowable<Collection<ScoredEntry<V>>> entryRangeReversed(double startScore, boolean startScoreInclusive, double endScore, boolean endScoreInclusive);
Flowable<Collection<ScoredEntry<V>>> entryRangeReversed(double startScore, boolean startScoreInclusive, double endScore, boolean endScoreInclusive, int offset, int count);
/**
* Returns the number of elements with a score between <code>startScore</code> and <code>endScore</code>.
*
* @param startScore - start score
* @param startScoreInclusive - start score inclusive
* @param endScore - end score
* @param endScoreInclusive - end score inclusive
* @return count
*/
Flowable<Long> count(double startScore, boolean startScoreInclusive, double endScore, boolean endScoreInclusive);
/**
* Read all values at once.
*
* @return values
*/
Flowable<Collection<V>> readAll();
/**
* Intersect provided ScoredSortedSets
* and store result to current ScoredSortedSet
*
* @param names - names of ScoredSortedSet
* @return length of intersection
*/
Flowable<Integer> intersection(String... names);
/**
* Intersect provided ScoredSortedSets with defined aggregation method
* and store result to current ScoredSortedSet
*
* @param aggregate - score aggregation mode
* @param names - names of ScoredSortedSet
* @return length of intersection
*/
Flowable<Integer> intersection(Aggregate aggregate, String... names);
/**
* Intersect provided ScoredSortedSets mapped to weight multiplier
* and store result to current ScoredSortedSet
*
* @param nameWithWeight - name of ScoredSortedSet mapped to weight multiplier
* @return length of intersection
*/
Flowable<Integer> intersection(Map<String, Double> nameWithWeight);
/**
* Intersect provided ScoredSortedSets mapped to weight multiplier
* with defined aggregation method
* and store result to current ScoredSortedSet
*
* @param aggregate - score aggregation mode
* @param nameWithWeight - name of ScoredSortedSet mapped to weight multiplier
* @return length of intersection
*/
Flowable<Integer> intersection(Aggregate aggregate, Map<String, Double> nameWithWeight);
/**
* Union provided ScoredSortedSets
* and store result to current ScoredSortedSet
*
* @param names - names of ScoredSortedSet
* @return length of union
*/
Flowable<Integer> union(String... names);
/**
* Union provided ScoredSortedSets with defined aggregation method
* and store result to current ScoredSortedSet
*
* @param aggregate - score aggregation mode
* @param names - names of ScoredSortedSet
* @return length of union
*/
Flowable<Integer> union(Aggregate aggregate, String... names);
/**
* Union provided ScoredSortedSets mapped to weight multiplier
* and store result to current ScoredSortedSet
*
* @param nameWithWeight - name of ScoredSortedSet mapped to weight multiplier
* @return length of union
*/
Flowable<Integer> union(Map<String, Double> nameWithWeight);
/**
* Union provided ScoredSortedSets mapped to weight multiplier
* with defined aggregation method
* and store result to current ScoredSortedSet
*
* @param aggregate - score aggregation mode
* @param nameWithWeight - name of ScoredSortedSet mapped to weight multiplier
* @return length of union
*/
Flowable<Integer> union(Aggregate aggregate, Map<String, Double> nameWithWeight);
}

@ -0,0 +1,58 @@
/**
* Copyright 2018 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.List;
import org.redisson.api.RScript.Mode;
import org.redisson.api.RScript.ReturnType;
import org.redisson.client.codec.Codec;
import io.reactivex.Flowable;
/**
* RxJava2 interface for Redis Script feature
*
* @author Nikita Koksharov
*
*/
public interface RScriptRx {
Flowable<Void> scriptFlush();
<R> Flowable<R> evalSha(Mode mode, String shaDigest, ReturnType returnType, List<Object> keys, Object... values);
<R> Flowable<R> evalSha(Mode mode, Codec codec, String shaDigest, ReturnType returnType, List<Object> keys, Object... values);
<R> Flowable<R> evalSha(Mode mode, String shaDigest, ReturnType returnType);
<R> Flowable<R> evalSha(Mode mode, Codec codec, String shaDigest, ReturnType returnType);
<R> Flowable<R> eval(Mode mode, String luaScript, ReturnType returnType, List<Object> keys, Object... values);
<R> Flowable<R> eval(Mode mode, Codec codec, String luaScript, ReturnType returnType, List<Object> keys, Object... values);
<R> Flowable<R> eval(Mode mode, String luaScript, ReturnType returnType);
<R> Flowable<R> eval(Mode mode, Codec codec, String luaScript, ReturnType returnType);
Flowable<String> scriptLoad(String luaScript);
Flowable<List<Boolean>> scriptExists(String ... shaDigests);
Flowable<Void> scriptKill();
}

@ -0,0 +1,180 @@
/**
* Copyright 2018 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.concurrent.TimeUnit;
import org.reactivestreams.Publisher;
/**
* RxJava2 interface for Semaphore object
*
* @author Nikita Koksharov
*
*/
public interface RSemaphoreRx extends RExpirableRx {
/**
* Acquires a permit only if one is available at the
* time of invocation.
*
* <p>Acquires a permit, if one is available and returns immediately,
* with the value {@code true},
* reducing the number of available permits by one.
*
* <p>If no permit is available then this method will return
* immediately with the value {@code false}.
*
* @return {@code true} if a permit was acquired and {@code false}
* otherwise
*/
Publisher<Boolean> tryAcquire();
/**
* Acquires the given number of permits only if all are available at the
* time of invocation.
*
* <p>Acquires a permits, if all are available and returns immediately,
* with the value {@code true},
* reducing the number of available permits by given number of permits.
*
* <p>If no permits are available then this method will return
* immediately with the value {@code false}.
*
* @param permits the number of permits to acquire
* @return {@code true} if a permit was acquired and {@code false}
* otherwise
*/
Publisher<Boolean> tryAcquire(int permits);
/**
* Acquires a permit from this semaphore.
*
* <p>Acquires a permit, if one is available and returns immediately,
* reducing the number of available permits by one.
*
* @return void
*
*/
Publisher<Void> acquire();
/**
* Acquires the given number of permits, if they are available,
* and returns immediately, reducing the number of available permits
* by the given amount.
*
* @param permits the number of permits to acquire
* @throws IllegalArgumentException if {@code permits} is negative
* @return void
*/
Publisher<Void> acquire(int permits);
/**
* Releases a permit, returning it to the semaphore.
*
* <p>Releases a permit, increasing the number of available permits by
* one. If any threads of Redisson client are trying to acquire a permit,
* then one is selected and given the permit that was just released.
*
* <p>There is no requirement that a thread that releases a permit must
* have acquired that permit by calling {@link #acquire()}.
* Correct usage of a semaphore is established by programming convention
* in the application.
*
* @return void
*/
Publisher<Void> release();
/**
* Releases the given number of permits, returning them to the semaphore.
*
* <p>Releases the given number of permits, increasing the number of available permits by
* the given number of permits. If any threads of Redisson client are trying to
* acquire a permits, then next threads is selected and tries to acquire the permits that was just released.
*
* <p>There is no requirement that a thread that releases a permits must
* have acquired that permit by calling {@link #acquire()}.
* Correct usage of a semaphore is established by programming convention
* in the application.
*
* @param permits amount
* @return void
*/
Publisher<Void> release(int permits);
/**
* Sets number of permits.
*
* @param permits - number of permits
* @return <code>true</code> if permits has been set successfully, otherwise <code>false</code>.
*/
Publisher<Boolean> trySetPermits(int permits);
/**
* <p>Acquires a permit, if one is available and returns immediately,
* with the value {@code true},
* reducing the number of available permits by one.
*
* <p>If a permit is acquired then the value {@code true} is returned.
*
* <p>If the specified waiting time elapses then the value {@code false}
* is returned. If the time is less than or equal to zero, the method
* will not wait at all.
*
* @param waitTime the maximum time to wait for a permit
* @param unit the time unit of the {@code timeout} argument
* @return {@code true} if a permit was acquired and {@code false}
* if the waiting time elapsed before a permit was acquired
*/
Publisher<Boolean> tryAcquire(long waitTime, TimeUnit unit);
/**
* Acquires the given number of permits only if all are available
* within the given waiting time.
*
* <p>Acquires a permits, if all are available and returns immediately,
* with the value {@code true},
* reducing the number of available permits by one.
*
* <p>If a permits is acquired then the value {@code true} is returned.
*
* <p>If the specified waiting time elapses then the value {@code false}
* is returned. If the time is less than or equal to zero, the method
* will not wait at all.
*
* @param permits amount
* @param waitTime the maximum time to wait for a available permits
* @param unit the time unit of the {@code timeout} argument
* @return {@code true} if a permit was acquired and {@code false}
* if the waiting time elapsed before a permit was acquired
*/
Publisher<Boolean> tryAcquire(int permits, long waitTime, TimeUnit unit);
/**
* Shrinks the number of available permits by the indicated
* reduction. This method can be useful in subclasses that use
* semaphores to track resources that become unavailable. This
* method differs from {@link #acquire()} in that it does not block
* waiting for permits to become available.
*
* @param permits - reduction the number of permits to remove
* @return void
* @throws IllegalArgumentException if {@code reduction} is negative
*/
Publisher<Void> reducePermits(int permits);
}

@ -0,0 +1,50 @@
/**
* Copyright 2018 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.Set;
import java.util.concurrent.TimeUnit;
import io.reactivex.Flowable;
/**
* Async set functions
*
* @author Nikita Koksharov
*
* @param <V> value
*/
public interface RSetCacheRx<V> extends RCollectionRx<V> {
Flowable<Boolean> add(V value, long ttl, TimeUnit unit);
/**
* Returns the number of elements in cache.
* This number can reflects expired elements too
* due to non realtime cleanup process.
*
*/
@Override
Flowable<Integer> size();
/**
* Read all elements at once
*
* @return values
*/
Flowable<Set<V>> readAll();
}

@ -0,0 +1,83 @@
/**
* Copyright 2018 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.Set;
import io.reactivex.Flowable;
/**
* RxJava2 interface for Set based Multimap
*
* @author Nikita Koksharov
*
* @param <K> key type
* @param <V> value type
*/
public interface RSetMultimapRx<K, V> extends RMultimapRx<K, V> {
/**
* Returns a view Set of the values associated with {@code key} in this
* multimap, if any. Note that when {@code containsKey(key)} is false, this
* returns an empty collection, not {@code null}.
*
* <p>Changes to the returned collection will update the underlying multimap,
* and vice versa.
*
* @param key - map key
* @return set of values
*/
RSetRx<V> get(K key);
/**
* Returns all elements at once. Result Set is <b>NOT</b> backed by map,
* so changes are not reflected in map.
*
* @param key - map key
* @return set of values
*/
Flowable<Set<V>> getAll(K key);
/**
* Removes all values associated with the key {@code key}.
*
* <p>Once this method returns, {@code key} will not be mapped to any values
* <p>Use {@link RMultimapReactive#fastRemove} if values are not needed.</p>
*
* @param key - map key
* @return the values that were removed (possibly empty). The returned
* set <i>may</i> be modifiable, but updating it will have no
* effect on the multimap.
*/
Flowable<Set<V>> removeAll(Object key);
/**
* Stores a collection of values with the same key, replacing any existing
* values for that key.
*
* <p>If {@code values} is empty, this is equivalent to
* {@link #removeAll(Object)}.
*
* @param key - map key
* @param values - map values
* @return set of replaced values, or an empty collection if no
* values were previously associated with the key. Set
* <i>may</i> be modifiable, but updating it will have no effect on the
* multimap.
*/
Flowable<Set<V>> replaceValues(K key, Iterable<? extends V> values);
}

@ -18,7 +18,7 @@ package org.redisson.api;
import java.util.Collection;
import java.util.List;
import io.reactivex.Single;
import io.reactivex.Flowable;
/**
*
@ -34,7 +34,7 @@ public interface RSortableRx<V> {
* @param order for sorted data
* @return sorted collection
*/
Single<V> readSorted(SortOrder order);
Flowable<V> readSorted(SortOrder order);
/**
* Read data in sorted view
@ -44,7 +44,7 @@ public interface RSortableRx<V> {
* @param count of sorted data
* @return sorted collection
*/
Single<V> readSorted(SortOrder order, int offset, int count);
Flowable<V> readSorted(SortOrder order, int offset, int count);
/**
* Read data in sorted view
@ -53,7 +53,7 @@ public interface RSortableRx<V> {
* @param order for sorted data
* @return sorted collection
*/
Single<V> readSorted(String byPattern, SortOrder order);
Flowable<V> readSorted(String byPattern, SortOrder order);
/**
* Read data in sorted view
@ -64,7 +64,7 @@ public interface RSortableRx<V> {
* @param count of sorted data
* @return sorted collection
*/
Single<V> readSorted(String byPattern, SortOrder order, int offset, int count);
Flowable<V> readSorted(String byPattern, SortOrder order, int offset, int count);
/**
* Read data in sorted view
@ -75,7 +75,7 @@ public interface RSortableRx<V> {
* @param order for sorted data
* @return sorted collection
*/
<T> Single<Collection<T>> readSorted(String byPattern, List<String> getPatterns, SortOrder order);
<T> Flowable<Collection<T>> readSorted(String byPattern, List<String> getPatterns, SortOrder order);
/**
* Read data in sorted view
@ -88,7 +88,7 @@ public interface RSortableRx<V> {
* @param count of sorted data
* @return sorted collection
*/
<T> Single<Collection<T>> readSorted(String byPattern, List<String> getPatterns, SortOrder order, int offset, int count);
<T> Flowable<Collection<T>> readSorted(String byPattern, List<String> getPatterns, SortOrder order, int offset, int count);
/**
* Sort data and store to <code>destName</code> list
@ -97,7 +97,7 @@ public interface RSortableRx<V> {
* @param order for sorted data
* @return length of sorted data
*/
Single<Integer> sortTo(String destName, SortOrder order);
Flowable<Integer> sortTo(String destName, SortOrder order);
/**
* Sort data and store to <code>destName</code> list
@ -108,7 +108,7 @@ public interface RSortableRx<V> {
* @param count of sorted data
* @return length of sorted data
*/
Single<Integer> sortTo(String destName, SortOrder order, int offset, int count);
Flowable<Integer> sortTo(String destName, SortOrder order, int offset, int count);
/**
* Sort data and store to <code>destName</code> list
@ -118,7 +118,7 @@ public interface RSortableRx<V> {
* @param order for sorted data
* @return length of sorted data
*/
Single<Integer> sortTo(String destName, String byPattern, SortOrder order);
Flowable<Integer> sortTo(String destName, String byPattern, SortOrder order);
/**
* Sort data and store to <code>destName</code> list
@ -130,7 +130,7 @@ public interface RSortableRx<V> {
* @param count of sorted data
* @return length of sorted data
*/
Single<Integer> sortTo(String destName, String byPattern, SortOrder order, int offset, int count);
Flowable<Integer> sortTo(String destName, String byPattern, SortOrder order, int offset, int count);
/**
* Sort data and store to <code>destName</code> list
@ -141,7 +141,7 @@ public interface RSortableRx<V> {
* @param order for sorted data
* @return length of sorted data
*/
Single<Integer> sortTo(String destName, String byPattern, List<String> getPatterns, SortOrder order);
Flowable<Integer> sortTo(String destName, String byPattern, List<String> getPatterns, SortOrder order);
/**
* Sort data and store to <code>destName</code> list
@ -154,6 +154,6 @@ public interface RSortableRx<V> {
* @param count of sorted data
* @return length of sorted data
*/
Single<Integer> sortTo(String destName, String byPattern, List<String> getPatterns, SortOrder order, int offset, int count);
Flowable<Integer> sortTo(String destName, String byPattern, List<String> getPatterns, SortOrder order, int offset, int count);
}

@ -0,0 +1,478 @@
/**
* Copyright 2018 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.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import io.reactivex.Flowable;
/**
* Reactive interface for Redis Stream object.
* <p>
* Requires <b>Redis 5.0.0 and higher.</b>
*
* @author Nikita Koksharov
*
* @param <K> key type
* @param <V> value type
*/
public interface RStreamRx<K, V> extends RExpirableRx {
/**
* Creates consumer group by name.
*
* @param groupName - name of group
* @return void
*/
Flowable<Void> createGroup(String groupName);
/**
* Creates consumer group by name and stream id.
* Only new messages after defined stream <code>id</code> will be available for consumers of this group.
* <p>
* {@link StreamId#NEWEST} is used for messages arrived since the moment of group creating
*
* @param groupName - name of group
* @return void
*/
Flowable<Void> createGroup(String groupName, StreamId id);
/**
* Marks pending messages by group name and stream <code>ids</code> as correctly processed.
*
* @param groupName - name of group
* @param ids - stream ids
* @return marked messages amount
*/
Flowable<Long> ack(String groupName, StreamId... ids);
/**
* Returns pending messages by group name
*
* @param groupName - name of group
* @return result object
*/
Flowable<PendingResult> listPending(String groupName);
/**
* Returns list of pending messages by group name.
* Limited by start stream id and end stream id and count.
* <p>
* {@link StreamId#MAX} is used as max stream id
* {@link StreamId#MIN} is used as min stream id
*
* @param groupName - name of group
* @param startId - start stream id
* @param endId - end stream id
* @param count - amount of messages
* @return list
*/
Flowable<List<PendingEntry>> listPending(String groupName, StreamId startId, StreamId endId, int count);
/**
* Returns list of pending messages by group name and consumer name.
* Limited by start stream id and end stream id and count.
* <p>
* {@link StreamId#MAX} is used as max stream id
* {@link StreamId#MIN} is used as min stream id
*
* @param consumerName - name of consumer
* @param groupName - name of group
* @param startId - start stream id
* @param endId - end stream id
* @param count - amount of messages
* @return list
*/
Flowable<List<PendingEntry>> listPending(String groupName, StreamId startId, StreamId endId, int count, String consumerName);
/**
* Transfers ownership of pending messages by id to a new consumer
* by name if idle time of messages is greater than defined value.
*
* @param groupName - name of group
* @param consumerName - name of consumer
* @param idleTime - minimum idle time of messages
* @param idleTimeUnit - idle time unit
* @param ids - stream ids
* @return
*/
Flowable<Map<StreamId, Map<K, V>>> claim(String groupName, String consumerName, long idleTime, TimeUnit idleTimeUnit, StreamId ... ids);
/**
* Read stream data from <code>groupName</code> by <code>consumerName</code> and specified collection of Stream IDs.
*
* @param ids - collection of Stream IDs
* @return stream data mapped by Stream ID
*/
Flowable<Map<StreamId, Map<K, V>>> readGroup(String groupName, String consumerName, StreamId ... ids);
/**
* Read stream data from <code>groupName</code> by <code>consumerName</code> and specified collection of Stream IDs.
*
* @param count - stream data size limit
* @param ids - collection of Stream IDs
* @return stream data mapped by Stream ID
*/
Flowable<Map<StreamId, Map<K, V>>> readGroup(String groupName, String consumerName, int count, StreamId ... ids);
/**
* Read stream data from <code>groupName</code> by <code>consumerName</code> and specified collection of Stream IDs.
* Wait for stream data availability for specified <code>timeout</code> interval.
*
* @param timeout - time interval to wait for stream data availability
* @param unit - time interval unit
* @param ids - collection of Stream IDs
* @return stream data mapped by Stream ID
*/
Flowable<Map<StreamId, Map<K, V>>> readGroup(String groupName, String consumerName, long timeout, TimeUnit unit, StreamId ... ids);
/**
* Read stream data from <code>groupName</code> by <code>consumerName</code> and specified collection of Stream IDs.
* Wait for stream data availability for specified <code>timeout</code> interval.
*
* @param count - stream data size limit
* @param timeout - time interval to wait for stream data availability
* @param unit - time interval unit
* @param ids - collection of Stream IDs
* @return stream data mapped by Stream ID
*/
Flowable<Map<StreamId, Map<K, V>>> readGroup(String groupName, String consumerName, int count, long timeout, TimeUnit unit, StreamId ... ids);
/**
* Returns number of entries in stream
*
* @return size of stream
*/
Flowable<Long> size();
/**
* Appends a new entry and returns generated Stream ID
*
* @param key - key of entry
* @param value - value of entry
* @return Stream ID
*/
Flowable<StreamId> add(K key, V value);
/**
* Appends a new entry by specified Stream ID
*
* @param id - Stream ID
* @param key - key of entry
* @param value - value of entry
* @return void
*/
Flowable<Void> add(StreamId id, K key, V value);
/**
* Appends a new entry and returns generated Stream ID.
* Trims stream to a specified <code>trimLen</code> size.
* If <code>trimStrict</code> is <code>false</code> then trims to few tens of entries more than specified length to trim.
*
* @param key - key of entry
* @param value - value of entry
* @param trimLen - length to trim
* @param trimStrict - if <code>false</code> then trims to few tens of entries more than specified length to trim
* @return Stream ID
*/
Flowable<StreamId> add(K key, V value, int trimLen, boolean trimStrict);
/**
* Appends a new entry by specified Stream ID.
* Trims stream to a specified <code>trimLen</code> size.
* If <code>trimStrict</code> is <code>false</code> then trims to few tens of entries more than specified length to trim.
*
* @param id - Stream ID
* @param key - key of entry
* @param value - value of entry
* @param trimLen - length to trim
* @param trimStrict - if <code>false</code> then trims to few tens of entries more than specified length to trim
* @return void
*/
Flowable<Void> add(StreamId id, K key, V value, int trimLen, boolean trimStrict);
/**
* Appends new entries and returns generated Stream ID
*
* @param entries - entries to add
* @return Stream ID
*/
Flowable<StreamId> addAll(Map<K, V> entries);
/**
* Appends new entries by specified Stream ID
*
* @param id - Stream ID
* @param entries - entries to add
* @return void
*/
Flowable<Void> addAll(StreamId id, Map<K, V> entries);
/**
* Appends new entries and returns generated Stream ID.
* Trims stream to a specified <code>trimLen</code> size.
* If <code>trimStrict</code> is <code>false</code> then trims to few tens of entries more than specified length to trim.
*
* @param entries - entries to add
* @param trimLen - length to trim
* @param trimStrict - if <code>false</code> then trims to few tens of entries more than specified length to trim
* @return Stream ID
*/
Flowable<StreamId> addAll(Map<K, V> entries, int trimLen, boolean trimStrict);
/**
* Appends new entries by specified Stream ID.
* Trims stream to a specified <code>trimLen</code> size.
* If <code>trimStrict</code> is <code>false</code> then trims to few tens of entries more than specified length to trim.
*
* @param id - Stream ID
* @param entries - entries to add
* @param trimLen - length to trim
* @param trimStrict - if <code>false</code> then trims to few tens of entries more than specified length to trim
* @return void
*/
Flowable<Void> addAll(StreamId id, Map<K, V> entries, int trimLen, boolean trimStrict);
/**
* Read stream data by specified collection of Stream IDs.
*
* @param ids - collection of Stream IDs
* @return stream data mapped by Stream ID
*/
Flowable<Map<StreamId, Map<K, V>>> read(StreamId ... ids);
/**
* Read stream data by specified collection of Stream IDs.
*
* @param count - stream data size limit
* @param ids - collection of Stream IDs
* @return stream data mapped by Stream ID
*/
Flowable<Map<StreamId, Map<K, V>>> read(int count, StreamId ... ids);
/**
* Read stream data by specified collection of Stream IDs.
* Wait for stream data availability for specified <code>timeout</code> interval.
*
* @param timeout - time interval to wait for stream data availability
* @param unit - time interval unit
* @param ids - collection of Stream IDs
* @return stream data mapped by Stream ID
*/
Flowable<Map<StreamId, Map<K, V>>> read(long timeout, TimeUnit unit, StreamId ... ids);
/**
* Read stream data by specified collection of Stream IDs.
* Wait for stream data availability for specified <code>timeout</code> interval.
*
* @param count - stream data size limit
* @param timeout - time interval to wait for stream data availability
* @param unit - time interval unit
* @param ids - collection of Stream IDs
* @return stream data mapped by Stream ID
*/
Flowable<Map<StreamId, Map<K, V>>> read(int count, long timeout, TimeUnit unit, StreamId ... ids);
/**
* Read stream data by specified stream name including this stream.
*
* @param id - id of this stream
* @param name2 - name of second stream
* @param id2 - id of second stream
* @return stream data mapped by key and Stream ID
*/
Flowable<Map<String, Map<StreamId, Map<K, V>>>> read(StreamId id, String name2, StreamId id2);
/**
* Read stream data by specified stream names including this stream.
*
* @param id - id of this stream
* @param name2 - name of second stream
* @param id2 - id of second stream
* @param name3 - name of third stream
* @param id3 - id of third stream
* @return stream data mapped by key and Stream ID
*/
Flowable<Map<String, Map<StreamId, Map<K, V>>>> read(StreamId id, String name2, StreamId id2, String name3, StreamId id3);
/**
* Read stream data by specified stream id mapped by name including this stream.
*
* @param id - id of this stream
* @param nameToId - stream id mapped by name
* @return stream data mapped by key and Stream ID
*/
Flowable<Map<String, Map<StreamId, Map<K, V>>>> read(StreamId id, Map<String, StreamId> nameToId);
/**
* Read stream data by specified stream name including this stream.
*
* @param count - stream data size limit
* @param id - id of this stream
* @param name2 - name of second stream
* @param id2 - id of second stream
* @return stream data mapped by key and Stream ID
*/
Flowable<Map<String, Map<StreamId, Map<K, V>>>> read(int count, StreamId id, String name2, StreamId id2);
/**
* Read stream data by specified stream names including this stream.
*
* @param count - stream data size limit
* @param id - id of this stream
* @param name2 - name of second stream
* @param id2 - id of second stream
* @param name3 - name of third stream
* @param id3 - id of third stream
* @return stream data mapped by key and Stream ID
*/
Flowable<Map<String, Map<StreamId, Map<K, V>>>> read(int count, StreamId id, String name2, StreamId id2, String name3, StreamId id3);
/**
* Read stream data by specified stream id mapped by name including this stream.
*
* @param count - stream data size limit
* @param id - id of this stream
* @param nameToId - stream id mapped by name
* @return stream data mapped by key and Stream ID
*/
Flowable<Map<String, Map<StreamId, Map<K, V>>>> read(int count, StreamId id, Map<String, StreamId> nameToId);
/**
* Read stream data by specified stream name including this stream.
* Wait for the first stream data availability for specified <code>timeout</code> interval.
*
* @param timeout - time interval to wait for stream data availability
* @param unit - time interval unit
* @param id - id of this stream
* @param name2 - name of second stream
* @param id2 - id of second stream
* @return stream data mapped by key and Stream ID
*/
Flowable<Map<String, Map<StreamId, Map<K, V>>>> read(long timeout, TimeUnit unit, StreamId id, String name2, StreamId id2);
/**
* Read stream data by specified stream names including this stream.
* Wait for the first stream data availability for specified <code>timeout</code> interval.
*
* @param timeout - time interval to wait for stream data availability
* @param unit - time interval unit
* @param id - id of this stream
* @param name2 - name of second stream
* @param id2 - id of second stream
* @param name3 - name of third stream
* @param id3 - id of third stream
* @return stream data mapped by key and Stream ID
*/
Flowable<Map<String, Map<StreamId, Map<K, V>>>> read(long timeout, TimeUnit unit, StreamId id, String name2, StreamId id2, String name3, StreamId id3);
/**
* Read stream data by specified stream id mapped by name including this stream.
* Wait for the first stream data availability for specified <code>timeout</code> interval.
*
* @param timeout - time interval to wait for stream data availability
* @param unit - time interval unit
* @param id - id of this stream
* @param nameToId - stream id mapped by name
* @return stream data mapped by key and Stream ID
*/
Flowable<Map<String, Map<StreamId, Map<K, V>>>> read(long timeout, TimeUnit unit, StreamId id, Map<String, StreamId> nameToId);
/**
* Read stream data by specified stream name including this stream.
* Wait for the first stream data availability for specified <code>timeout</code> interval.
*
* @param count - stream data size limit
* @param timeout - time interval to wait for stream data availability
* @param unit - time interval unit
* @param id - id of this stream
* @param name2 - name of second stream
* @param id2 - id of second stream
* @return stream data mapped by key and Stream ID
*/
Flowable<Map<String, Map<StreamId, Map<K, V>>>> read(int count, long timeout, TimeUnit unit, StreamId id, String name2, StreamId id2);
/**
* Read stream data by specified stream names including this stream.
* Wait for the first stream data availability for specified <code>timeout</code> interval.
*
* @param count - stream data size limit
* @param timeout - time interval to wait for stream data availability
* @param unit - time interval unit
* @param id - id of this stream
* @param name2 - name of second stream
* @param id2 - id of second stream
* @param name3 - name of third stream
* @param id3 - id of third stream
* @return stream data mapped by key and Stream ID
*/
Flowable<Map<String, Map<StreamId, Map<K, V>>>> read(int count, long timeout, TimeUnit unit, StreamId id, String name2, StreamId id2, String name3, StreamId id3);
/**
* Read stream data by specified stream id mapped by name including this stream.
* Wait for the first stream data availability for specified <code>timeout</code> interval.
*
* @param count - stream data size limit
* @param timeout - time interval to wait for stream data availability
* @param unit - time interval unit
* @param id - id of this stream
* @param nameToId - stream id mapped by name
* @return stream data mapped by key and Stream ID
*/
Flowable<Map<String, Map<StreamId, Map<K, V>>>> read(int count, long timeout, TimeUnit unit, StreamId id, Map<String, StreamId> nameToId);
/**
* Read stream data in range by specified start Stream ID (included) and end Stream ID (included).
*
* @param startId - start Stream ID
* @param endId - end Stream ID
* @return stream data mapped by Stream ID
*/
Flowable<Map<StreamId, Map<K, V>>> range(StreamId startId, StreamId endId);
/**
* Read stream data in range by specified start Stream ID (included) and end Stream ID (included).
*
* @param count - stream data size limit
* @param startId - start Stream ID
* @param endId - end Stream ID
* @return stream data mapped by Stream ID
*/
Flowable<Map<StreamId, Map<K, V>>> range(int count, StreamId startId, StreamId endId);
/**
* Read stream data in reverse order in range by specified start Stream ID (included) and end Stream ID (included).
*
* @param startId - start Stream ID
* @param endId - end Stream ID
* @return stream data mapped by Stream ID
*/
Flowable<Map<StreamId, Map<K, V>>> rangeReversed(StreamId startId, StreamId endId);
/**
* Read stream data in reverse order in range by specified start Stream ID (included) and end Stream ID (included).
*
* @param count - stream data size limit
* @param startId - start Stream ID
* @param endId - end Stream ID
* @return stream data mapped by Stream ID
*/
Flowable<Map<StreamId, Map<K, V>>> rangeReversed(int count, StreamId startId, StreamId endId);
}

@ -28,130 +28,130 @@ import org.redisson.config.Config;
*/
public interface RedissonRxClient {
// /**
// * Returns stream instance by <code>name</code>
// * <p>
// * Requires <b>Redis 5.0.0 and higher.</b>
// *
// * @param <K> type of key
// * @param <V> type of value
// * @param name of stream
// * @return RStream object
// */
// <K, V> RStreamReactive<K, V> getStream(String name);
//
// /**
// * Returns stream instance by <code>name</code>
// * using provided <code>codec</code> for entries.
// * <p>
// * Requires <b>Redis 5.0.0 and higher.</b>
// *
// * @param <K> type of key
// * @param <V> type of value
// * @param name - name of stream
// * @param codec - codec for entry
// * @return RStream object
// */
// <K, V> RStreamReactive<K, V> getStream(String name, Codec codec);
//
// /**
// * Returns geospatial items holder instance by <code>name</code>.
// *
// * @param <V> type of value
// * @param name - name of object
// * @return Geo object
// */
// <V> RGeoReactive<V> getGeo(String name);
//
// /**
// * Returns geospatial items holder instance by <code>name</code>
// * using provided codec for geospatial members.
// *
// * @param <V> type of value
// * @param name - name of object
// * @param codec - codec for value
// * @return Geo object
// */
// <V> RGeoReactive<V> getGeo(String name, Codec codec);
//
// /**
// * Returns rate limiter instance by <code>name</code>
// *
// * @param name of rate limiter
// * @return RateLimiter object
// */
// RRateLimiterReactive getRateLimiter(String name);
//
// /**
// * Returns semaphore instance by name
// *
// * @param name - name of object
// * @return Semaphore object
// */
// RSemaphoreReactive getSemaphore(String name);
//
// /**
// * Returns semaphore instance by name.
// * Supports lease time parameter for each acquired permit.
// *
// * @param name - name of object
// * @return PermitExpirableSemaphore object
// */
// RPermitExpirableSemaphoreReactive getPermitExpirableSemaphore(String name);
//
// /**
// * Returns readWriteLock instance by name.
// *
// * @param name - name of object
// * @return Lock object
// */
// RReadWriteLockReactive getReadWriteLock(String name);
//
// /**
// * Returns lock instance by name.
// * <p>
// * Implements a <b>fair</b> locking so it guarantees an acquire order by threads.
// *
// * @param name - name of object
// * @return Lock object
// */
// RLockReactive getFairLock(String name);
//
// /**
// * Returns lock instance by name.
// * <p>
// * Implements a <b>non-fair</b> locking so doesn't guarantee an acquire order by threads.
// *
// * @param name - name of object
// * @return Lock object
// */
// RLockReactive getLock(String name);
//
// /**
// * Returns set-based cache instance by <code>name</code>.
// * Supports value eviction with a given TTL value.
// *
// * <p>If eviction is not required then it's better to use regular map {@link #getSet(String, Codec)}.</p>
// *
// * @param <V> type of values
// * @param name - name of object
// * @return SetCache object
// */
// <V> RSetCacheReactive<V> getSetCache(String name);
//
// /**
// * Returns set-based cache instance by <code>name</code>.
// * Supports value eviction with a given TTL value.
// *
// * <p>If eviction is not required then it's better to use regular map {@link #getSet(String, Codec)}.</p>
// *
// * @param <V> type of values
// * @param name - name of object
// * @param codec - codec for values
// * @return SetCache object
// */
// <V> RSetCacheReactive<V> getSetCache(String name, Codec codec);
//
/**
* Returns stream instance by <code>name</code>
* <p>
* Requires <b>Redis 5.0.0 and higher.</b>
*
* @param <K> type of key
* @param <V> type of value
* @param name of stream
* @return RStream object
*/
<K, V> RStreamRx<K, V> getStream(String name);
/**
* Returns stream instance by <code>name</code>
* using provided <code>codec</code> for entries.
* <p>
* Requires <b>Redis 5.0.0 and higher.</b>
*
* @param <K> type of key
* @param <V> type of value
* @param name - name of stream
* @param codec - codec for entry
* @return RStream object
*/
<K, V> RStreamRx<K, V> getStream(String name, Codec codec);
/**
* Returns geospatial items holder instance by <code>name</code>.
*
* @param <V> type of value
* @param name - name of object
* @return Geo object
*/
<V> RGeoRx<V> getGeo(String name);
/**
* Returns geospatial items holder instance by <code>name</code>
* using provided codec for geospatial members.
*
* @param <V> type of value
* @param name - name of object
* @param codec - codec for value
* @return Geo object
*/
<V> RGeoRx<V> getGeo(String name, Codec codec);
/**
* Returns rate limiter instance by <code>name</code>
*
* @param name of rate limiter
* @return RateLimiter object
*/
RRateLimiterRx getRateLimiter(String name);
/**
* Returns semaphore instance by name
*
* @param name - name of object
* @return Semaphore object
*/
RSemaphoreRx getSemaphore(String name);
/**
* Returns semaphore instance by name.
* Supports lease time parameter for each acquired permit.
*
* @param name - name of object
* @return PermitExpirableSemaphore object
*/
RPermitExpirableSemaphoreRx getPermitExpirableSemaphore(String name);
/**
* Returns readWriteLock instance by name.
*
* @param name - name of object
* @return Lock object
*/
RReadWriteLockRx getReadWriteLock(String name);
/**
* Returns lock instance by name.
* <p>
* Implements a <b>fair</b> locking so it guarantees an acquire order by threads.
*
* @param name - name of object
* @return Lock object
*/
RLockRx getFairLock(String name);
/**
* Returns lock instance by name.
* <p>
* Implements a <b>non-fair</b> locking so doesn't guarantee an acquire order by threads.
*
* @param name - name of object
* @return Lock object
*/
RLockRx getLock(String name);
/**
* Returns set-based cache instance by <code>name</code>.
* Supports value eviction with a given TTL value.
*
* <p>If eviction is not required then it's better to use regular map {@link #getSet(String, Codec)}.</p>
*
* @param <V> type of values
* @param name - name of object
* @return SetCache object
*/
<V> RSetCacheRx<V> getSetCache(String name);
/**
* Returns set-based cache instance by <code>name</code>.
* Supports value eviction with a given TTL value.
*
* <p>If eviction is not required then it's better to use regular map {@link #getSet(String, Codec)}.</p>
*
* @param <V> type of values
* @param name - name of object
* @param codec - codec for values
* @return SetCache object
*/
<V> RSetCacheRx<V> getSetCache(String name, Codec codec);
/**
* Returns map-based cache instance by name
* using provided codec for both cache keys and values.
@ -230,99 +230,89 @@ public interface RedissonRxClient {
*/
<V> RBucketRx<V> getBucket(String name, Codec codec);
// /**
// * Returns a list of object holder instances by a key pattern
// *
// * @param <V> type of value
// * @param pattern - pattern for name of buckets
// * @return list of buckets
// */
// <V> List<RBucketReactive<V>> findBuckets(String pattern);
//
// /**
// * Returns HyperLogLog instance by name.
// *
// * @param <V> type of values
// * @param name - name of object
// * @return HyperLogLog object
// */
// <V> RHyperLogLogReactive<V> getHyperLogLog(String name);
//
// /**
// * Returns HyperLogLog instance by name
// * using provided codec for hll objects.
// *
// * @param <V> type of values
// * @param name - name of object
// * @param codec - codec of values
// * @return HyperLogLog object
// */
// <V> RHyperLogLogReactive<V> getHyperLogLog(String name, Codec codec);
//
// /**
// * Returns list instance by name.
// *
// * @param <V> type of values
// * @param name - name of object
// * @return List object
// */
// <V> RListReactive<V> getList(String name);
//
// /**
// * Returns list instance by name
// * using provided codec for list objects.
// *
// * @param <V> type of values
// * @param name - name of object
// * @param codec - codec for values
// * @return List object
// */
// <V> RListReactive<V> getList(String name, Codec codec);
//
// /**
// * Returns List based Multimap instance by name.
// *
// * @param <K> type of key
// * @param <V> type of value
// * @param name - name of object
// * @return ListMultimap object
// */
// <K, V> RListMultimapReactive<K, V> getListMultimap(String name);
//
// /**
// * Returns List based Multimap instance by name
// * using provided codec for both map keys and values.
// *
// * @param <K> type of key
// * @param <V> type of value
// * @param name - name of object
// * @param codec - codec for keys and values
// * @return RListMultimapReactive object
// */
// <K, V> RListMultimapReactive<K, V> getListMultimap(String name, Codec codec);
//
// /**
// * Returns Set based Multimap instance by name.
// *
// * @param <K> type of key
// * @param <V> type of value
// * @param name - name of object
// * @return SetMultimap object
// */
// <K, V> RSetMultimapReactive<K, V> getSetMultimap(String name);
//
// /**
// * Returns Set based Multimap instance by name
// * using provided codec for both map keys and values.
// *
// * @param <K> type of key
// * @param <V> type of value
// * @param name - name of object
// * @param codec - codec for keys and values
// * @return SetMultimap object
// */
// <K, V> RSetMultimapReactive<K, V> getSetMultimap(String name, Codec codec);
//
/**
* Returns HyperLogLog instance by name.
*
* @param <V> type of values
* @param name - name of object
* @return HyperLogLog object
*/
<V> RHyperLogLogRx<V> getHyperLogLog(String name);
/**
* Returns HyperLogLog instance by name
* using provided codec for hll objects.
*
* @param <V> type of values
* @param name - name of object
* @param codec - codec of values
* @return HyperLogLog object
*/
<V> RHyperLogLogRx<V> getHyperLogLog(String name, Codec codec);
/**
* Returns list instance by name.
*
* @param <V> type of values
* @param name - name of object
* @return List object
*/
<V> RListRx<V> getList(String name);
/**
* Returns list instance by name
* using provided codec for list objects.
*
* @param <V> type of values
* @param name - name of object
* @param codec - codec for values
* @return List object
*/
<V> RListRx<V> getList(String name, Codec codec);
/**
* Returns List based Multimap instance by name.
*
* @param <K> type of key
* @param <V> type of value
* @param name - name of object
* @return ListMultimap object
*/
<K, V> RListMultimapRx<K, V> getListMultimap(String name);
/**
* Returns List based Multimap instance by name
* using provided codec for both map keys and values.
*
* @param <K> type of key
* @param <V> type of value
* @param name - name of object
* @param codec - codec for keys and values
* @return RListMultimapReactive object
*/
<K, V> RListMultimapRx<K, V> getListMultimap(String name, Codec codec);
/**
* Returns Set based Multimap instance by name.
*
* @param <K> type of key
* @param <V> type of value
* @param name - name of object
* @return SetMultimap object
*/
<K, V> RSetMultimapRx<K, V> getSetMultimap(String name);
/**
* Returns Set based Multimap instance by name
* using provided codec for both map keys and values.
*
* @param <K> type of key
* @param <V> type of value
* @param name - name of object
* @param codec - codec for keys and values
* @return SetMultimap object
*/
<K, V> RSetMultimapRx<K, V> getSetMultimap(String name, Codec codec);
/**
* Returns map instance by name.
@ -390,28 +380,28 @@ public interface RedissonRxClient {
*/
<V> RSetRx<V> getSet(String name, Codec codec);
// /**
// * Returns Redis Sorted Set instance by name.
// * This sorted set sorts objects by object score.
// *
// * @param <V> type of values
// * @param name of scored sorted set
// * @return ScoredSortedSet object
// */
// <V> RScoredSortedSetReactive<V> getScoredSortedSet(String name);
//
// /**
// * Returns Redis Sorted Set instance by name
// * using provided codec for sorted set objects.
// * This sorted set sorts objects by object score.
// *
// * @param <V> type of values
// * @param name - name of scored sorted set
// * @param codec - codec for values
// * @return ScoredSortedSet object
// */
// <V> RScoredSortedSetReactive<V> getScoredSortedSet(String name, Codec codec);
//
/**
* Returns Redis Sorted Set instance by name.
* This sorted set sorts objects by object score.
*
* @param <V> type of values
* @param name of scored sorted set
* @return ScoredSortedSet object
*/
<V> RScoredSortedSetRx<V> getScoredSortedSet(String name);
/**
* Returns Redis Sorted Set instance by name
* using provided codec for sorted set objects.
* This sorted set sorts objects by object score.
*
* @param <V> type of values
* @param name - name of scored sorted set
* @param codec - codec for values
* @return ScoredSortedSet object
*/
<V> RScoredSortedSetRx<V> getScoredSortedSet(String name, Codec codec);
// /**
// * Returns String based Redis Sorted Set instance by name
// * All elements are inserted with the same score during addition,
@ -551,38 +541,38 @@ public interface RedissonRxClient {
// * @return Deque object
// */
// <V> RDequeReactive<V> getDeque(String name, Codec codec);
//
// /**
// * Returns "atomic long" instance by name.
// *
// * @param name of the "atomic long"
// * @return AtomicLong object
// */
// RAtomicLongReactive getAtomicLong(String name);
//
// /**
// * Returns "atomic double" instance by name.
// *
// * @param name of the "atomic double"
// * @return AtomicLong object
// */
// RAtomicDoubleReactive getAtomicDouble(String name);
//
// /**
// * Returns bitSet instance by name.
// *
// * @param name - name of object
// * @return BitSet object
// */
// RBitSetReactive getBitSet(String name);
//
// /**
// * Returns script operations object
// *
// * @return Script object
// */
// RScriptReactive getScript();
//
/**
* Returns "atomic long" instance by name.
*
* @param name of the "atomic long"
* @return AtomicLong object
*/
RAtomicLongRx getAtomicLong(String name);
/**
* Returns "atomic double" instance by name.
*
* @param name of the "atomic double"
* @return AtomicLong object
*/
RAtomicDoubleRx getAtomicDouble(String name);
/**
* Returns bitSet instance by name.
*
* @param name - name of object
* @return BitSet object
*/
RBitSetRx getBitSet(String name);
/**
* Returns script operations object
*
* @return Script object
*/
RScriptRx getScript();
// /**
// * Creates transaction with <b>READ_COMMITTED</b> isolation level.
// *
@ -590,7 +580,7 @@ public interface RedissonRxClient {
// * @return Transaction object
// */
// RTransactionReactive createTransaction(TransactionOptions options);
//
// /**
// * Return batch object which executes group of
// * command in pipeline.

@ -0,0 +1,50 @@
/**
* Copyright 2018 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.rx;
import org.redisson.RedissonList;
import org.redisson.RedissonListMultimap;
import org.redisson.api.RListMultimap;
import org.redisson.api.RListRx;
import org.redisson.client.codec.Codec;
/**
*
* @author Nikita Koksharov
*
* @param <K> key type
* @param <V> value type
*/
public class RedissonListMultimapRx<K, V> {
private CommandRxExecutor commandExecutor;
private RedissonListMultimap<K, V> instance;
public RedissonListMultimapRx(CommandRxExecutor commandExecutor, String name) {
this.instance = new RedissonListMultimap<K, V>(commandExecutor, name);
}
public RedissonListMultimapRx(Codec codec, CommandRxExecutor commandExecutor, String name) {
this.instance = new RedissonListMultimap<K, V>(codec, commandExecutor, name);
}
public RListRx<V> get(K key) {
RedissonList<V> list = (RedissonList<V>) ((RListMultimap<K, V>)instance).get(key);
return RxProxyBuilder.create(commandExecutor, instance,
new RedissonListRx<V>(list), RListRx.class);
}
}

@ -0,0 +1,109 @@
/**
* Copyright 2018 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.rx;
import org.reactivestreams.Publisher;
import org.redisson.RedissonList;
import org.redisson.api.RFuture;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.FutureListener;
import io.reactivex.functions.LongConsumer;
import io.reactivex.processors.ReplayProcessor;
/**
* Distributed and concurrent implementation of {@link java.util.List}
*
* @author Nikita Koksharov
*
* @param <V> the type of elements held in this collection
*/
public class RedissonListRx<V> {
private final RedissonList<V> instance;
public RedissonListRx(RedissonList<V> instance) {
this.instance = instance;
}
public Publisher<V> descendingIterator() {
return iterator(-1, false);
}
public Publisher<V> iterator() {
return iterator(0, true);
}
public Publisher<V> descendingIterator(int startIndex) {
return iterator(startIndex, false);
}
public Publisher<V> iterator(int startIndex) {
return iterator(startIndex, true);
}
private Publisher<V> iterator(final int startIndex, final boolean forward) {
final ReplayProcessor<V> p = ReplayProcessor.create();
return p.doOnRequest(new LongConsumer() {
private int currentIndex = startIndex;
@Override
public void accept(final long n) throws Exception {
instance.getAsync(currentIndex).addListener(new FutureListener<V>() {
@Override
public void operationComplete(Future<V> future) throws Exception {
if (!future.isSuccess()) {
p.onError(future.cause());
return;
}
V value = future.getNow();
if (value != null) {
p.onNext(value);
if (forward) {
currentIndex++;
} else {
currentIndex--;
}
}
if (value == null) {
p.onComplete();
return;
}
if (n-1 == 0) {
return;
}
accept(n-1);
}
});
}
});
}
public Publisher<Boolean> addAll(Publisher<? extends V> c) {
return new PublisherAdder<V>() {
@Override
public RFuture<Boolean> add(Object o) {
return instance.addAsync((V)o);
}
}.addAll(c);
}
}

@ -0,0 +1,49 @@
/**
* Copyright 2018 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.rx;
import org.redisson.RedissonReadWriteLock;
import org.redisson.api.RLockRx;
import org.redisson.api.RReadWriteLock;
import org.redisson.api.RReadWriteLockRx;
/**
*
* @author Nikita Koksharov
*
*/
public class RedissonReadWriteLockRx implements RReadWriteLockRx {
private final RReadWriteLock instance;
private final CommandRxExecutor commandExecutor;
public RedissonReadWriteLockRx(CommandRxExecutor commandExecutor, String name) {
this.commandExecutor = commandExecutor;
this.instance = new RedissonReadWriteLock(commandExecutor, name);
}
@Override
public RLockRx readLock() {
return RxProxyBuilder.create(commandExecutor, instance.readLock(), RLockRx.class);
}
@Override
public RLockRx writeLock() {
return RxProxyBuilder.create(commandExecutor, instance.writeLock(), RLockRx.class);
}
}

@ -0,0 +1,70 @@
/**
* Copyright 2018 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.rx;
import org.reactivestreams.Publisher;
import org.redisson.RedissonScoredSortedSet;
import org.redisson.api.RFuture;
import org.redisson.api.RScoredSortedSetAsync;
import org.redisson.client.RedisClient;
import org.redisson.client.protocol.decoder.ListScanResult;
import io.reactivex.Flowable;
/**
*
* @author Nikita Koksharov
*
* @param <V> value type
*/
public class RedissonScoredSortedSetRx<V> {
private final RScoredSortedSetAsync<V> instance;
public RedissonScoredSortedSetRx(RScoredSortedSetAsync<V> instance) {
this.instance = instance;
}
private Flowable<V> scanIteratorReactive(final String pattern, final int count) {
return new SetRxIterator<V>() {
@Override
protected RFuture<ListScanResult<Object>> scanIterator(final RedisClient client, final long nextIterPos) {
return ((RedissonScoredSortedSet<V>)instance).scanIteratorAsync(client, nextIterPos, pattern, count);
}
}.create();
}
public String getName() {
return ((RedissonScoredSortedSet<V>)instance).getName();
}
public Publisher<V> iterator() {
return scanIteratorReactive(null, 10);
}
public Publisher<V> iterator(String pattern) {
return scanIteratorReactive(pattern, 10);
}
public Publisher<V> iterator(int count) {
return scanIteratorReactive(null, count);
}
public Publisher<V> iterator(String pattern, int count) {
return scanIteratorReactive(pattern, count);
}
}

@ -0,0 +1,57 @@
/**
* Copyright 2018 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.rx;
import org.reactivestreams.Publisher;
import org.redisson.ScanIterator;
import org.redisson.api.RFuture;
import org.redisson.api.RSetCache;
import org.redisson.client.RedisClient;
import org.redisson.client.protocol.decoder.ListScanResult;
/**
*
* @author Nikita Koksharov
*
* @param <V> value
*/
public class RedissonSetCacheRx<V> {
private final RSetCache<V> instance;
public RedissonSetCacheRx(RSetCache<V> instance) {
this.instance = instance;
}
public Publisher<V> iterator() {
return new SetRxIterator<V>() {
@Override
protected RFuture<ListScanResult<Object>> scanIterator(RedisClient client, long nextIterPos) {
return ((ScanIterator)instance).scanIteratorAsync(instance.getName(), client, nextIterPos, null, 10);
}
}.create();
}
public Publisher<Boolean> addAll(Publisher<? extends V> c) {
return new PublisherAdder<V>() {
@Override
public RFuture<Boolean> add(Object o) {
return instance.addAsync((V)o);
}
}.addAll(c);
}
}

@ -0,0 +1,50 @@
/**
* Copyright 2018 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.rx;
import org.redisson.RedissonListMultimap;
import org.redisson.RedissonSet;
import org.redisson.api.RSetMultimap;
import org.redisson.api.RSetReactive;
import org.redisson.client.codec.Codec;
/**
*
* @author Nikita Koksharov
*
* @param <K> key type
* @param <V> value type
*/
public class RedissonSetMultimapRx<K, V> {
private CommandRxExecutor commandExecutor;
private RedissonListMultimap<K, V> instance;
public RedissonSetMultimapRx(CommandRxExecutor commandExecutor, String name) {
this.instance = new RedissonListMultimap<K, V>(commandExecutor, name);
}
public RedissonSetMultimapRx(Codec codec, CommandRxExecutor commandExecutor, String name) {
this.instance = new RedissonListMultimap<K, V>(codec, commandExecutor, name);
}
public RSetReactive<V> get(K key) {
RedissonSet<V> set = (RedissonSet<V>) ((RSetMultimap<K, V>)instance).get(key);
return RxProxyBuilder.create(commandExecutor, set,
new RedissonSetRx<V>(set), RSetReactive.class);
}
}

@ -0,0 +1,571 @@
package org.redisson.rx;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.concurrent.CountDownLatch;
import org.junit.Assert;
import org.junit.Test;
import org.redisson.TestObject;
import org.redisson.api.RListRx;
import org.redisson.client.RedisException;
import reactor.rx.Promise;
public class RedissonListRxTest extends BaseRxTest {
@Test
public void testHashCode() throws InterruptedException {
RListRx<String> list = redisson.getList("list");
sync(list.add("a"));
sync(list.add("b"));
sync(list.add("c"));
Assert.assertEquals(126145, list.hashCode());
}
@Test
public void testAddByIndex() {
RListRx<String> test2 = redisson.getList("test2");
sync(test2.add("foo"));
sync(test2.add(0, "bar"));
assertThat(sync(test2)).containsExactly("bar", "foo");
}
@Test
public void testAddAllReactive() {
RListRx<Integer> list = redisson.getList("list");
sync(list.add(1));
sync(list.add(2));
sync(list.add(3));
sync(list.add(4));
sync(list.add(5));
RListRx<Integer> list2 = redisson.getList("list2");
Assert.assertEquals(true, sync(list2.addAll(list.iterator())));
Assert.assertEquals(5, sync(list2.size()).intValue());
}
@Test
public void testAddAllWithIndex() throws InterruptedException {
final RListRx<Long> list = redisson.getList("list");
final CountDownLatch latch = new CountDownLatch(1);
list.addAll(Arrays.asList(1L, 2L, 3L)).subscribe(new Promise<Boolean>() {
@Override
public void onNext(Boolean element) {
list.addAll(Arrays.asList(1L, 24L, 3L)).subscribe(new Promise<Boolean>() {
@Override
public void onNext(Boolean value) {
latch.countDown();
}
@Override
public void onError(Throwable error) {
Assert.fail(error.getMessage());
}
});
}
@Override
public void onError(Throwable error) {
Assert.fail(error.getMessage());
}
});
latch.await();
assertThat(sync(list)).containsExactly(1L, 2L, 3L, 1L, 24L, 3L);
}
@Test
public void testAdd() throws InterruptedException {
final RListRx<Long> list = redisson.getList("list");
final CountDownLatch latch = new CountDownLatch(1);
list.add(1L).subscribe(new Promise<Boolean>() {
@Override
public void onNext(Boolean value) {
list.add(2L).subscribe(new Promise<Boolean>() {
@Override
public void onNext(Boolean value) {
latch.countDown();
}
@Override
public void onError(Throwable error) {
Assert.fail(error.getMessage());
}
});
}
@Override
public void onError(Throwable error) {
Assert.fail(error.getMessage());
}
});
latch.await();
assertThat(sync(list)).containsExactly(1L, 2L);
}
@Test
public void testLong() {
RListRx<Long> list = redisson.getList("list");
sync(list.add(1L));
sync(list.add(2L));
assertThat(sync(list)).containsExactly(1L, 2L);
}
@Test
public void testListIteratorIndex() {
RListRx<Integer> list = redisson.getList("list2");
sync(list.add(1));
sync(list.add(2));
sync(list.add(3));
sync(list.add(4));
sync(list.add(5));
sync(list.add(0));
sync(list.add(7));
sync(list.add(8));
sync(list.add(0));
sync(list.add(10));
Iterator<Integer> iterator = toIterator(list.iterator());
Assert.assertTrue(1 == iterator.next());
Assert.assertTrue(2 == iterator.next());
Assert.assertTrue(3 == iterator.next());
Assert.assertTrue(4 == iterator.next());
Assert.assertTrue(5 == iterator.next());
Assert.assertTrue(0 == iterator.next());
Assert.assertTrue(7 == iterator.next());
Assert.assertTrue(8 == iterator.next());
Assert.assertTrue(0 == iterator.next());
Assert.assertTrue(10 == iterator.next());
Assert.assertFalse(iterator.hasNext());
}
@Test
public void testListIteratorPrevious() {
RListRx<Integer> list = redisson.getList("list");
sync(list.add(1));
sync(list.add(2));
sync(list.add(3));
sync(list.add(4));
sync(list.add(5));
sync(list.add(0));
sync(list.add(7));
sync(list.add(8));
sync(list.add(0));
sync(list.add(10));
Iterator<Integer> iterator = toIterator(list.descendingIterator());
Assert.assertTrue(10 == iterator.next());
Assert.assertTrue(0 == iterator.next());
Assert.assertTrue(8 == iterator.next());
Assert.assertTrue(7 == iterator.next());
Assert.assertTrue(0 == iterator.next());
Assert.assertTrue(5 == iterator.next());
Assert.assertTrue(4 == iterator.next());
Assert.assertTrue(3 == iterator.next());
Assert.assertTrue(2 == iterator.next());
Assert.assertTrue(1 == iterator.next());
Assert.assertFalse(iterator.hasNext());
}
@Test
public void testLastIndexOfNone() {
RListRx<Integer> list = redisson.getList("list");
sync(list.add(1));
sync(list.add(2));
sync(list.add(3));
sync(list.add(4));
sync(list.add(5));
Assert.assertEquals(-1, sync(list.lastIndexOf(10)).intValue());
}
@Test
public void testLastIndexOf2() {
RListRx<Integer> list = redisson.getList("list");
sync(list.add(1));
sync(list.add(2));
sync(list.add(3));
sync(list.add(4));
sync(list.add(5));
sync(list.add(0));
sync(list.add(7));
sync(list.add(8));
sync(list.add(0));
sync(list.add(10));
long index = sync(list.lastIndexOf(3));
Assert.assertEquals(2, index);
}
@Test
public void testLastIndexOf1() {
RListRx<Integer> list = redisson.getList("list");
sync(list.add(1));
sync(list.add(2));
sync(list.add(3));
sync(list.add(4));
sync(list.add(5));
sync(list.add(3));
sync(list.add(7));
sync(list.add(8));
sync(list.add(0));
sync(list.add(10));
long index = sync(list.lastIndexOf(3));
Assert.assertEquals(5, index);
}
@Test
public void testLastIndexOf() {
RListRx<Integer> list = redisson.getList("list");
sync(list.add(1));
sync(list.add(2));
sync(list.add(3));
sync(list.add(4));
sync(list.add(5));
sync(list.add(3));
sync(list.add(7));
sync(list.add(8));
sync(list.add(3));
sync(list.add(10));
int index = sync(list.lastIndexOf(3));
Assert.assertEquals(8, index);
}
@Test
public void testIndexOf() {
RListRx<Integer> list = redisson.getList("list");
for (int i = 1; i < 200; i++) {
sync(list.add(i));
}
Assert.assertTrue(55 == sync(list.indexOf(56)));
Assert.assertTrue(99 == sync(list.indexOf(100)));
Assert.assertTrue(-1 == sync(list.indexOf(200)));
Assert.assertTrue(-1 == sync(list.indexOf(0)));
}
@Test
public void testRemove() {
RListRx<Integer> list = redisson.getList("list");
sync(list.add(1));
sync(list.add(2));
sync(list.add(3));
sync(list.add(4));
sync(list.add(5));
Integer val = sync(list.remove(0));
Assert.assertTrue(1 == val);
assertThat(sync(list)).containsExactly(2, 3, 4, 5);
}
@Test
public void testSet() {
RListRx<Integer> list = redisson.getList("list");
sync(list.add(1));
sync(list.add(2));
sync(list.add(3));
sync(list.add(4));
sync(list.add(5));
sync(list.set(4, 6));
assertThat(sync(list)).containsExactly(1, 2, 3, 4, 6);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testSetFail() throws InterruptedException {
RListRx<Integer> list = redisson.getList("list");
sync(list.add(1));
sync(list.add(2));
sync(list.add(3));
sync(list.add(4));
sync(list.add(5));
sync(list.set(5, 6));
}
@Test
public void testRemoveAllEmpty() {
RListRx<Integer> list = redisson.getList("list");
sync(list.add(1));
sync(list.add(2));
sync(list.add(3));
sync(list.add(4));
sync(list.add(5));
Assert.assertFalse(sync(list.removeAll(Collections.emptyList())));
Assert.assertFalse(Arrays.asList(1).removeAll(Collections.emptyList()));
}
@Test
public void testRemoveAll() {
RListRx<Integer> list = redisson.getList("list");
sync(list.add(1));
sync(list.add(2));
sync(list.add(3));
sync(list.add(4));
sync(list.add(5));
Assert.assertFalse(sync(list.removeAll(Collections.emptyList())));
Assert.assertTrue(sync(list.removeAll(Arrays.asList(3, 2, 10, 6))));
assertThat(sync(list)).containsExactly(1, 4, 5);
Assert.assertTrue(sync(list.removeAll(Arrays.asList(4))));
assertThat(sync(list)).containsExactly(1, 5);
Assert.assertTrue(sync(list.removeAll(Arrays.asList(1, 5, 1, 5))));
Assert.assertEquals(0, sync(list.size()).longValue());
}
@Test
public void testRetainAll() {
RListRx<Integer> list = redisson.getList("list");
sync(list.add(1));
sync(list.add(2));
sync(list.add(3));
sync(list.add(4));
sync(list.add(5));
Assert.assertTrue(sync(list.retainAll(Arrays.asList(3, 2, 10, 6))));
assertThat(sync(list)).containsExactly(2, 3);
Assert.assertEquals(2, sync(list.size()).longValue());
}
@Test
public void testFastSet() {
RListRx<Integer> list = redisson.getList("list");
sync(list.add(1));
sync(list.add(2));
sync(list.fastSet(0, 3));
Assert.assertEquals(3, (int)sync(list.get(0)));
}
@Test
public void testRetainAllEmpty() {
RListRx<Integer> list = redisson.getList("list");
sync(list.add(1));
sync(list.add(2));
sync(list.add(3));
sync(list.add(4));
sync(list.add(5));
Assert.assertTrue(sync(list.retainAll(Collections.<Integer>emptyList())));
Assert.assertEquals(0, sync(list.size()).intValue());
}
@Test
public void testRetainAllNoModify() {
RListRx<Integer> list = redisson.getList("list");
sync(list.add(1));
sync(list.add(2));
Assert.assertFalse(sync(list.retainAll(Arrays.asList(1, 2)))); // nothing changed
assertThat(sync(list)).containsExactly(1, 2);
}
@Test(expected = RedisException.class)
public void testAddAllIndexError() {
RListRx<Integer> list = redisson.getList("list");
sync(list.addAll(2, Arrays.asList(7, 8, 9)));
}
@Test
public void testAddAllIndex() {
RListRx<Integer> list = redisson.getList("list");
sync(list.add(1));
sync(list.add(2));
sync(list.add(3));
sync(list.add(4));
sync(list.add(5));
Assert.assertEquals(true, sync(list.addAll(2, Arrays.asList(7, 8, 9))));
assertThat(sync(list)).containsExactly(1, 2, 7, 8, 9, 3, 4, 5);
sync(list.addAll(sync(list.size())-1, Arrays.asList(9, 1, 9)));
assertThat(sync(list)).containsExactly(1, 2, 7, 8, 9, 3, 4, 9, 1, 9, 5);
sync(list.addAll(sync(list.size()), Arrays.asList(0, 5)));
assertThat(sync(list)).containsExactly(1, 2, 7, 8, 9, 3, 4, 9, 1, 9, 5, 0, 5);
Assert.assertEquals(true, sync(list.addAll(0, Arrays.asList(6, 7))));
assertThat(sync(list)).containsExactly(6,7,1, 2, 7, 8, 9, 3, 4, 9, 1, 9, 5, 0, 5);
}
@Test
public void testAddAll() {
RListRx<Integer> list = redisson.getList("list");
sync(list.add(1));
sync(list.add(2));
sync(list.add(3));
sync(list.add(4));
sync(list.add(5));
Assert.assertEquals(true, sync(list.addAll(Arrays.asList(7, 8, 9))));
Assert.assertEquals(true, sync(list.addAll(Arrays.asList(9, 1, 9))));
assertThat(sync(list)).containsExactly(1, 2, 3, 4, 5, 7, 8, 9, 9, 1, 9);
}
@Test
public void testAddAllEmpty() {
RListRx<Integer> list = redisson.getList("list");
Assert.assertEquals(false, sync(list.addAll(Collections.<Integer>emptyList())));
Assert.assertEquals(0, sync(list.size()).intValue());
}
@Test
public void testContainsAll() {
RListRx<Integer> list = redisson.getList("list");
for (int i = 0; i < 200; i++) {
sync(list.add(i));
}
Assert.assertTrue(sync(list.containsAll(Arrays.asList(30, 11))));
Assert.assertFalse(sync(list.containsAll(Arrays.asList(30, 711, 11))));
Assert.assertTrue(sync(list.containsAll(Arrays.asList(30))));
}
@Test
public void testContainsAllEmpty() {
RListRx<Integer> list = redisson.getList("list");
for (int i = 0; i < 200; i++) {
sync(list.add(i));
}
Assert.assertTrue(sync(list.containsAll(Collections.emptyList())));
Assert.assertTrue(Arrays.asList(1).containsAll(Collections.emptyList()));
}
@Test
public void testIteratorSequence() {
RListRx<String> list = redisson.getList("list2");
sync(list.add("1"));
sync(list.add("4"));
sync(list.add("2"));
sync(list.add("5"));
sync(list.add("3"));
checkIterator(list);
// to test "memory effect" absence
checkIterator(list);
}
private void checkIterator(RListRx<String> list) {
int iteration = 0;
for (Iterator<String> iterator = toIterator(list.iterator()); iterator.hasNext();) {
String value = iterator.next();
String val = sync(list.get(iteration));
Assert.assertEquals(val, value);
iteration++;
}
Assert.assertEquals(sync(list.size()).intValue(), iteration);
}
@Test
public void testContains() {
RListRx<String> list = redisson.getList("list");
sync(list.add("1"));
sync(list.add("4"));
sync(list.add("2"));
sync(list.add("5"));
sync(list.add("3"));
Assert.assertTrue(sync(list.contains("3")));
Assert.assertFalse(sync(list.contains("31")));
Assert.assertTrue(sync(list.contains("1")));
}
// @Test(expected = RedisException.class)
// public void testGetFail() {
// RListRx<String> list = redisson.getList("list");
//
// sync(list.get(0));
// }
@Test
public void testAddGet() {
RListRx<String> list = redisson.getList("list");
sync(list.add("1"));
sync(list.add("4"));
sync(list.add("2"));
sync(list.add("5"));
sync(list.add("3"));
String val1 = sync(list.get(0));
Assert.assertEquals("1", val1);
String val2 = sync(list.get(3));
Assert.assertEquals("5", val2);
}
@Test
public void testDuplicates() {
RListRx<TestObject> list = redisson.getList("list");
sync(list.add(new TestObject("1", "2")));
sync(list.add(new TestObject("1", "2")));
sync(list.add(new TestObject("2", "3")));
sync(list.add(new TestObject("3", "4")));
sync(list.add(new TestObject("5", "6")));
Assert.assertEquals(5, sync(list.size()).intValue());
}
@Test
public void testSize() {
RListRx<String> list = redisson.getList("list");
sync(list.add("1"));
sync(list.add("2"));
sync(list.add("3"));
sync(list.add("4"));
sync(list.add("5"));
sync(list.add("6"));
assertThat(sync(list)).containsExactly("1", "2", "3", "4", "5", "6");
sync(list.remove("2"));
assertThat(sync(list)).containsExactly("1", "3", "4", "5", "6");
sync(list.remove("4"));
assertThat(sync(list)).containsExactly("1", "3", "5", "6");
}
@Test
public void testCodec() {
RListRx<Object> list = redisson.getList("list");
sync(list.add(1));
sync(list.add(2L));
sync(list.add("3"));
sync(list.add("e"));
assertThat(sync(list)).containsExactly(1, 2L, "3", "e");
}
}

@ -0,0 +1,337 @@
package org.redisson.rx;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import org.junit.Assert;
import org.junit.Test;
import org.redisson.TestObject;
import org.redisson.api.RScoredSortedSetRx;
import org.redisson.client.codec.StringCodec;
import org.redisson.client.protocol.ScoredEntry;
public class RedissonScoredSortedSetRxTest extends BaseRxTest {
@Test
public void testFirstLast() {
RScoredSortedSetRx<String> set = redisson.getScoredSortedSet("simple");
sync(set.add(0.1, "a"));
sync(set.add(0.2, "b"));
sync(set.add(0.3, "c"));
sync(set.add(0.4, "d"));
Assert.assertEquals("a", sync(set.first()));
Assert.assertEquals("d", sync(set.last()));
}
@Test
public void testRemoveRangeByScore() {
RScoredSortedSetRx<String> set = redisson.getScoredSortedSet("simple");
sync(set.add(0.1, "a"));
sync(set.add(0.2, "b"));
sync(set.add(0.3, "c"));
sync(set.add(0.4, "d"));
sync(set.add(0.5, "e"));
sync(set.add(0.6, "f"));
sync(set.add(0.7, "g"));
Assert.assertEquals(2, sync(set.removeRangeByScore(0.1, false, 0.3, true)).intValue());
assertThat(sync(set)).containsOnly("a", "d", "e", "f", "g");
}
@Test
public void testRemoveRangeByRank() {
RScoredSortedSetRx<String> set = redisson.getScoredSortedSet("simple");
sync(set.add(0.1, "a"));
sync(set.add(0.2, "b"));
sync(set.add(0.3, "c"));
sync(set.add(0.4, "d"));
sync(set.add(0.5, "e"));
sync(set.add(0.6, "f"));
sync(set.add(0.7, "g"));
Assert.assertEquals(2, sync(set.removeRangeByRank(0, 1)).intValue());
assertThat(sync(set)).containsOnly("c", "d", "e", "f", "g");
}
@Test
public void testRank() {
RScoredSortedSetRx<String> set = redisson.getScoredSortedSet("simple");
sync(set.add(0.1, "a"));
sync(set.add(0.2, "b"));
sync(set.add(0.3, "c"));
sync(set.add(0.4, "d"));
sync(set.add(0.5, "e"));
sync(set.add(0.6, "f"));
sync(set.add(0.7, "g"));
Assert.assertEquals(3, sync(set.rank("d")).intValue());
}
@Test
public void testAddAsync() throws InterruptedException, ExecutionException {
RScoredSortedSetRx<Integer> set = redisson.getScoredSortedSet("simple");
Assert.assertTrue(sync(set.add(0.323, 2)));
Assert.assertFalse(sync(set.add(0.323, 2)));
Assert.assertTrue(sync(set.contains(2)));
}
@Test
public void testRemoveAsync() throws InterruptedException, ExecutionException {
RScoredSortedSetRx<Integer> set = redisson.getScoredSortedSet("simple");
sync(set.add(0.11, 1));
sync(set.add(0.22, 3));
sync(set.add(0.33, 7));
Assert.assertTrue(sync(set.remove(1)));
Assert.assertFalse(sync(set.contains(1)));
assertThat(sync(set)).containsExactly(3, 7);
Assert.assertFalse(sync(set.remove(1)));
assertThat(sync(set)).containsExactly(3, 7);
sync(set.remove(3));
Assert.assertFalse(sync(set.contains(3)));
assertThat(sync(set)).containsExactly(7);
}
@Test
public void testIteratorNextNext() {
RScoredSortedSetRx<String> set = redisson.getScoredSortedSet("simple");
sync(set.add(1, "1"));
sync(set.add(2, "4"));
Iterator<String> iter = toIterator(set.iterator());
Assert.assertEquals("1", iter.next());
Assert.assertEquals("4", iter.next());
Assert.assertFalse(iter.hasNext());
}
@Test
public void testIteratorSequence() {
RScoredSortedSetRx<Integer> set = redisson.getScoredSortedSet("simple");
for (int i = 0; i < 1000; i++) {
sync(set.add(i, Integer.valueOf(i)));
}
Set<Integer> setCopy = new HashSet<Integer>();
for (int i = 0; i < 1000; i++) {
setCopy.add(Integer.valueOf(i));
}
checkIterator(set, setCopy);
}
private void checkIterator(RScoredSortedSetRx<Integer> set, Set<Integer> setCopy) {
for (Iterator<Integer> iterator = toIterator(set.iterator()); iterator.hasNext();) {
Integer value = iterator.next();
if (!setCopy.remove(value)) {
Assert.fail();
}
}
Assert.assertEquals(0, setCopy.size());
}
@Test
public void testRetainAll() {
RScoredSortedSetRx<Integer> set = redisson.getScoredSortedSet("simple");
for (int i = 0; i < 20000; i++) {
sync(set.add(i, i));
}
Assert.assertTrue(sync(set.retainAll(Arrays.asList(1, 2))));
assertThat(sync(set)).contains(1, 2);
Assert.assertEquals(2, sync(set.size()).intValue());
}
@Test
public void testRemoveAll() {
RScoredSortedSetRx<Integer> set = redisson.getScoredSortedSet("simple");
sync(set.add(0.1, 1));
sync(set.add(0.2, 2));
sync(set.add(0.3, 3));
Assert.assertTrue(sync(set.removeAll(Arrays.asList(1, 2))));
assertThat(sync(set)).contains(3);
Assert.assertEquals(1, sync(set.size()).intValue());
}
@Test
public void testSort() {
RScoredSortedSetRx<Integer> set = redisson.getScoredSortedSet("simple");
Assert.assertTrue(sync(set.add(4, 2)));
Assert.assertTrue(sync(set.add(5, 3)));
Assert.assertTrue(sync(set.add(3, 1)));
Assert.assertTrue(sync(set.add(6, 4)));
Assert.assertTrue(sync(set.add(1000, 10)));
Assert.assertTrue(sync(set.add(1, -1)));
Assert.assertTrue(sync(set.add(2, 0)));
assertThat(sync(set)).containsExactly(-1, 0, 1, 2, 3, 4, 10);
Assert.assertEquals(-1, (int)sync(set.first()));
Assert.assertEquals(10, (int)sync(set.last()));
}
@Test
public void testRemove() {
RScoredSortedSetRx<Integer> set = redisson.getScoredSortedSet("simple");
sync(set.add(4, 5));
sync(set.add(2, 3));
sync(set.add(0, 1));
sync(set.add(1, 2));
sync(set.add(3, 4));
Assert.assertFalse(sync(set.remove(0)));
Assert.assertTrue(sync(set.remove(3)));
assertThat(sync(set)).containsExactly(1, 2, 4, 5);
}
@Test
public void testContainsAll() {
RScoredSortedSetRx<Integer> set = redisson.getScoredSortedSet("simple");
for (int i = 0; i < 200; i++) {
sync(set.add(i, i));
}
Assert.assertTrue(sync(set.containsAll(Arrays.asList(30, 11))));
Assert.assertFalse(sync(set.containsAll(Arrays.asList(30, 711, 11))));
}
@Test
public void testContains() {
RScoredSortedSetRx<TestObject> set = redisson.getScoredSortedSet("simple");
sync(set.add(0, new TestObject("1", "2")));
sync(set.add(1, new TestObject("1", "2")));
sync(set.add(2, new TestObject("2", "3")));
sync(set.add(3, new TestObject("3", "4")));
sync(set.add(4, new TestObject("5", "6")));
Assert.assertTrue(sync(set.contains(new TestObject("2", "3"))));
Assert.assertTrue(sync(set.contains(new TestObject("1", "2"))));
Assert.assertFalse(sync(set.contains(new TestObject("1", "9"))));
}
@Test
public void testDuplicates() {
RScoredSortedSetRx<TestObject> set = redisson.getScoredSortedSet("simple");
Assert.assertTrue(sync(set.add(0, new TestObject("1", "2"))));
Assert.assertFalse(sync(set.add(0, new TestObject("1", "2"))));
Assert.assertTrue(sync(set.add(2, new TestObject("2", "3"))));
Assert.assertTrue(sync(set.add(3, new TestObject("3", "4"))));
Assert.assertTrue(sync(set.add(4, new TestObject("5", "6"))));
Assert.assertEquals(4, sync(set.size()).intValue());
}
@Test
public void testSize() {
RScoredSortedSetRx<Integer> set = redisson.getScoredSortedSet("simple");
sync(set.add(0, 1));
sync(set.add(1, 2));
sync(set.add(2, 3));
sync(set.add(2, 3));
sync(set.add(3, 4));
sync(set.add(4, 5));
sync(set.add(4, 5));
Assert.assertEquals(5, sync(set.size()).intValue());
}
@Test
public void testValueRange() {
RScoredSortedSetRx<Integer> set = redisson.getScoredSortedSet("simple");
sync(set.add(0, 1));
sync(set.add(1, 2));
sync(set.add(2, 3));
sync(set.add(3, 4));
sync(set.add(4, 5));
sync(set.add(4, 5));
Collection<Integer> vals = sync(set.valueRange(0, -1));
assertThat(sync(set)).containsExactly(1, 2, 3, 4, 5);
}
@Test
public void testEntryRange() {
RScoredSortedSetRx<Integer> set = redisson.getScoredSortedSet("simple");
sync(set.add(10, 1));
sync(set.add(20, 2));
sync(set.add(30, 3));
sync(set.add(40, 4));
sync(set.add(50, 5));
Collection<ScoredEntry<Integer>> vals = sync(set.entryRange(0, -1));
assertThat(vals).contains(new ScoredEntry<Integer>(10D, 1),
new ScoredEntry<Integer>(20D, 2),
new ScoredEntry<Integer>(30D, 3),
new ScoredEntry<Integer>(40D, 4),
new ScoredEntry<Integer>(50D, 5));
}
@Test
public void testScoredSortedSetValueRange() {
RScoredSortedSetRx<String> set = redisson.<String>getScoredSortedSet("simple");
sync(set.add(0, "a"));
sync(set.add(1, "b"));
sync(set.add(2, "c"));
sync(set.add(3, "d"));
sync(set.add(4, "e"));
Collection<String> r = sync(set.valueRange(1, true, 4, false, 1, 2));
String[] a = r.toArray(new String[0]);
Assert.assertArrayEquals(new String[]{"c", "d"}, a);
}
@Test
public void testScoredSortedSetEntryRange() {
RScoredSortedSetRx<String> set = redisson.<String>getScoredSortedSet("simple");
sync(set.add(0, "a"));
sync(set.add(1, "b"));
sync(set.add(2, "c"));
sync(set.add(3, "d"));
sync(set.add(4, "e"));
Collection<ScoredEntry<String>> r = sync(set.entryRange(1, true, 4, false, 1, 2));
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 testAddAndGet() throws InterruptedException {
RScoredSortedSetRx<Integer> set = redisson.getScoredSortedSet("simple", StringCodec.INSTANCE);
sync(set.add(1, 100));
Double res = sync(set.addScore(100, 11));
Assert.assertEquals(12, (double)res, 0);
Double score = sync(set.getScore(100));
Assert.assertEquals(12, (double)score, 0);
RScoredSortedSetRx<Integer> set2 = redisson.getScoredSortedSet("simple", StringCodec.INSTANCE);
sync(set2.add(100.2, 1));
Double res2 = sync(set2.addScore(1, new Double(12.1)));
Assert.assertTrue(new Double(112.3).compareTo(res2) == 0);
res2 = sync(set2.getScore(1));
Assert.assertTrue(new Double(112.3).compareTo(res2) == 0);
}
}
Loading…
Cancel
Save