diff --git a/redisson/src/main/java/org/redisson/RedissonRx.java b/redisson/src/main/java/org/redisson/RedissonRx.java index 1cf607c61..163701edf 100644 --- a/redisson/src/main/java/org/redisson/RedissonRx.java +++ b/redisson/src/main/java/org/redisson/RedissonRx.java @@ -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 RStreamReactive getStream(String name) { -// return ReactiveProxyBuilder.create(commandExecutor, new RedissonStream(commandExecutor, name), RStreamReactive.class); -// } -// -// @Override -// public RStreamReactive getStream(String name, Codec codec) { -// return ReactiveProxyBuilder.create(commandExecutor, new RedissonStream(codec, commandExecutor, name), RStreamReactive.class); -// } -// -// @Override -// public RGeoReactive getGeo(String name) { -// return ReactiveProxyBuilder.create(commandExecutor, new RedissonGeo(commandExecutor, name, null), -// new RedissonScoredSortedSetReactive(commandExecutor, name), RGeoReactive.class); -// } -// -// @Override -// public RGeoReactive getGeo(String name, Codec codec) { -// return ReactiveProxyBuilder.create(commandExecutor, new RedissonGeo(codec, commandExecutor, name, null), -// new RedissonScoredSortedSetReactive(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 RStreamRx getStream(String name) { + return RxProxyBuilder.create(commandExecutor, new RedissonStream(commandExecutor, name), RStreamRx.class); + } + + @Override + public RStreamRx getStream(String name, Codec codec) { + return RxProxyBuilder.create(commandExecutor, new RedissonStream(codec, commandExecutor, name), RStreamRx.class); + } + + @Override + public RGeoRx getGeo(String name) { + RedissonScoredSortedSet set = new RedissonScoredSortedSet(commandExecutor, name, null); + return RxProxyBuilder.create(commandExecutor, new RedissonGeo(commandExecutor, name, null), + new RedissonScoredSortedSetRx(set), RGeoRx.class); + } + + @Override + public RGeoRx getGeo(String name, Codec codec) { + RedissonScoredSortedSet set = new RedissonScoredSortedSet(codec, commandExecutor, name, null); + return RxProxyBuilder.create(commandExecutor, new RedissonGeo(codec, commandExecutor, name, null), + new RedissonScoredSortedSetRx(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 RMapCacheRx getMapCache(String name, Codec codec) { RedissonMapCache map = new RedissonMapCache(codec, evictionScheduler, commandExecutor, name, null, null); @@ -143,65 +169,53 @@ public class RedissonRx implements RedissonRxClient { return RxProxyBuilder.create(commandExecutor, new RedissonBucket(codec, commandExecutor, name), RBucketRx.class); } -// @Override -// public List> findBuckets(String pattern) { -// RKeys redissonKeys = new RedissonKeys(commandExecutor); -// Iterable keys = redissonKeys.getKeysByPattern(pattern); -// -// List> buckets = new ArrayList>(); -// for (Object key : keys) { -// if(key != null) { -// buckets.add(this.getBucket(key.toString())); -// } -// } -// return buckets; -// } -// -// @Override -// public RHyperLogLogReactive getHyperLogLog(String name) { -// return ReactiveProxyBuilder.create(commandExecutor, new RedissonHyperLogLog(commandExecutor, name), RHyperLogLogReactive.class); -// } -// -// @Override -// public RHyperLogLogReactive getHyperLogLog(String name, Codec codec) { -// return ReactiveProxyBuilder.create(commandExecutor, new RedissonHyperLogLog(codec, commandExecutor, name), RHyperLogLogReactive.class); -// } -// -// @Override -// public RListReactive getList(String name) { -// return ReactiveProxyBuilder.create(commandExecutor, new RedissonList(commandExecutor, name, null), -// new RedissonListReactive(commandExecutor, name), RListReactive.class); -// } -// -// @Override -// public RListReactive getList(String name, Codec codec) { -// return ReactiveProxyBuilder.create(commandExecutor, new RedissonList(codec, commandExecutor, name, null), -// new RedissonListReactive(codec, commandExecutor, name), RListReactive.class); -// } -// -// @Override -// public RListMultimapReactive getListMultimap(String name) { -// return ReactiveProxyBuilder.create(commandExecutor, new RedissonListMultimap(commandExecutor, name), -// new RedissonListMultimapReactive(commandExecutor, name), RListMultimapReactive.class); -// } -// -// @Override -// public RListMultimapReactive getListMultimap(String name, Codec codec) { -// return ReactiveProxyBuilder.create(commandExecutor, new RedissonListMultimap(codec, commandExecutor, name), -// new RedissonListMultimapReactive(codec, commandExecutor, name), RListMultimapReactive.class); -// } -// -// @Override -// public RSetMultimapReactive getSetMultimap(String name) { -// return ReactiveProxyBuilder.create(commandExecutor, new RedissonSetMultimap(commandExecutor, name), -// new RedissonSetMultimapReactive(commandExecutor, name), RSetMultimapReactive.class); -// } -// -// @Override -// public RSetMultimapReactive getSetMultimap(String name, Codec codec) { -// return ReactiveProxyBuilder.create(commandExecutor, new RedissonSetMultimap(codec, commandExecutor, name), -// new RedissonSetMultimapReactive(codec, commandExecutor, name), RSetMultimapReactive.class); -// } + @Override + public RHyperLogLogRx getHyperLogLog(String name) { + return RxProxyBuilder.create(commandExecutor, new RedissonHyperLogLog(commandExecutor, name), RHyperLogLogRx.class); + } + + @Override + public RHyperLogLogRx getHyperLogLog(String name, Codec codec) { + return RxProxyBuilder.create(commandExecutor, new RedissonHyperLogLog(codec, commandExecutor, name), RHyperLogLogRx.class); + } + + @Override + public RListRx getList(String name) { + RedissonList list = new RedissonList(commandExecutor, name, null); + return RxProxyBuilder.create(commandExecutor, list, + new RedissonListRx(list), RListRx.class); + } + + @Override + public RListRx getList(String name, Codec codec) { + RedissonList list = new RedissonList(codec, commandExecutor, name, null); + return RxProxyBuilder.create(commandExecutor, list, + new RedissonListRx(list), RListRx.class); + } + + @Override + public RListMultimapRx getListMultimap(String name) { + return RxProxyBuilder.create(commandExecutor, new RedissonListMultimap(commandExecutor, name), + new RedissonListMultimapRx(commandExecutor, name), RListMultimapRx.class); + } + + @Override + public RListMultimapRx getListMultimap(String name, Codec codec) { + return RxProxyBuilder.create(commandExecutor, new RedissonListMultimap(codec, commandExecutor, name), + new RedissonListMultimapRx(codec, commandExecutor, name), RListMultimapRx.class); + } + + @Override + public RSetMultimapRx getSetMultimap(String name) { + return RxProxyBuilder.create(commandExecutor, new RedissonSetMultimap(commandExecutor, name), + new RedissonSetMultimapRx(commandExecutor, name), RSetMultimapRx.class); + } + + @Override + public RSetMultimapRx getSetMultimap(String name, Codec codec) { + return RxProxyBuilder.create(commandExecutor, new RedissonSetMultimap(codec, commandExecutor, name), + new RedissonSetMultimapRx(codec, commandExecutor, name), RSetMultimapRx.class); + } @Override public RMapRx getMap(String name) { @@ -231,18 +245,20 @@ public class RedissonRx implements RedissonRxClient { new RedissonSetRx(set), RSetRx.class); } -// @Override -// public RScoredSortedSetReactive getScoredSortedSet(String name) { -// return ReactiveProxyBuilder.create(commandExecutor, new RedissonScoredSortedSet(commandExecutor, name, null), -// new RedissonScoredSortedSetReactive(commandExecutor, name), RScoredSortedSetReactive.class); -// } -// -// @Override -// public RScoredSortedSetReactive getScoredSortedSet(String name, Codec codec) { -// return ReactiveProxyBuilder.create(commandExecutor, new RedissonScoredSortedSet(codec, commandExecutor, name, null), -// new RedissonScoredSortedSetReactive(codec, commandExecutor, name), RScoredSortedSetReactive.class); -// } -// + @Override + public RScoredSortedSetRx getScoredSortedSet(String name) { + RedissonScoredSortedSet set = new RedissonScoredSortedSet(commandExecutor, name, null); + return RxProxyBuilder.create(commandExecutor, set, + new RedissonScoredSortedSetRx(set), RScoredSortedSetRx.class); + } + + @Override + public RScoredSortedSetRx getScoredSortedSet(String name, Codec codec) { + RedissonScoredSortedSet set = new RedissonScoredSortedSet(codec, commandExecutor, name, null); + return RxProxyBuilder.create(commandExecutor, set, + new RedissonScoredSortedSetRx(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(codec, commandExecutor, name, null), // new RedissonListReactive(codec, commandExecutor, name), RDequeReactive.class); // } -// -// @Override -// public RSetCacheReactive getSetCache(String name) { -// RSetCache set = new RedissonSetCache(evictionScheduler, commandExecutor, name, null); -// return ReactiveProxyBuilder.create(commandExecutor, set, -// new RedissonSetCacheReactive(set), RSetCacheReactive.class); -// } -// -// @Override -// public RSetCacheReactive getSetCache(String name, Codec codec) { -// RSetCache set = new RedissonSetCache(codec, evictionScheduler, commandExecutor, name, null); -// return ReactiveProxyBuilder.create(commandExecutor, set, -// new RedissonSetCacheReactive(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 RSetCacheRx getSetCache(String name) { + RSetCache set = new RedissonSetCache(evictionScheduler, commandExecutor, name, null); + return RxProxyBuilder.create(commandExecutor, set, + new RedissonSetCacheRx(set), RSetCacheRx.class); + } + + @Override + public RSetCacheRx getSetCache(String name, Codec codec) { + RSetCache set = new RedissonSetCache(codec, evictionScheduler, commandExecutor, name, null); + return RxProxyBuilder.create(commandExecutor, set, + new RedissonSetCacheRx(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); diff --git a/redisson/src/main/java/org/redisson/api/RAtomicDoubleRx.java b/redisson/src/main/java/org/redisson/api/RAtomicDoubleRx.java new file mode 100644 index 000000000..fb07c95b5 --- /dev/null +++ b/redisson/src/main/java/org/redisson/api/RAtomicDoubleRx.java @@ -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 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 addAndGet(double delta); + + /** + * Atomically decrements the current value by one. + * + * @return the updated value + */ + Publisher decrementAndGet(); + + /** + * Returns current value. + * + * @return current value + */ + Publisher get(); + + /** + * Returns and deletes object + * + * @return the current value + */ + Publisher getAndDelete(); + + /** + * Atomically adds the given value to the current value. + * + * @param delta the value to add + * @return the updated value + */ + Publisher getAndAdd(double delta); + + /** + * Atomically sets the given value and returns the old value. + * + * @param newValue the new value + * @return the old value + */ + Publisher getAndSet(double newValue); + + /** + * Atomically increments the current value by one. + * + * @return the updated value + */ + Publisher incrementAndGet(); + + /** + * Atomically increments the current value by one. + * + * @return the old value + */ + Publisher getAndIncrement(); + + /** + * Atomically decrements by one the current value. + * + * @return the previous value + */ + Publisher getAndDecrement(); + + /** + * Atomically sets the given value. + * + * @param newValue the new value + * @return void + */ + Publisher set(double newValue); + +} diff --git a/redisson/src/main/java/org/redisson/api/RAtomicLongRx.java b/redisson/src/main/java/org/redisson/api/RAtomicLongRx.java new file mode 100644 index 000000000..f7926e0ea --- /dev/null +++ b/redisson/src/main/java/org/redisson/api/RAtomicLongRx.java @@ -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 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 addAndGet(long delta); + + /** + * Atomically decrements the current value by one. + * + * @return the updated value + */ + Flowable decrementAndGet(); + + /** + * Returns current value. + * + * @return the current value + */ + Flowable get(); + + /** + * Returns and deletes object + * + * @return the current value + */ + Flowable getAndDelete(); + + /** + * Atomically adds the given value to the current value. + * + * @param delta the value to add + * @return the old value before the add + */ + Flowable getAndAdd(long delta); + + /** + * Atomically sets the given value and returns the old value. + * + * @param newValue the new value + * @return the old value + */ + Flowable getAndSet(long newValue); + + /** + * Atomically increments the current value by one. + * + * @return the updated value + */ + Flowable incrementAndGet(); + + /** + * Atomically increments the current value by one. + * + * @return the old value + */ + Flowable getAndIncrement(); + + /** + * Atomically decrements by one the current value. + * + * @return the previous value + */ + Flowable getAndDecrement(); + + /** + * Atomically sets the given value. + * + * @param newValue the new value + * @return void + */ + Flowable set(long newValue); + +} diff --git a/redisson/src/main/java/org/redisson/api/RBatchRx.java b/redisson/src/main/java/org/redisson/api/RBatchRx.java new file mode 100644 index 000000000..4735bd809 --- /dev/null +++ b/redisson/src/main/java/org/redisson/api/RBatchRx.java @@ -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. + *

+ * All method invocations on objects + * from this interface are batched to separate queue and could be executed later + * with execute() method. + * + * + * @author Nikita Koksharov + * + */ +public interface RBatchRx { + + /** + * Returns stream instance by name + *

+ * Requires Redis 5.0.0 and higher. + * + * @param type of key + * @param type of value + * @param name of stream + * @return RStream object + */ + RStreamRx getStream(String name); + + /** + * Returns stream instance by name + * using provided codec for entries. + *

+ * Requires Redis 5.0.0 and higher. + * + * @param type of key + * @param type of value + * @param name - name of stream + * @param codec - codec for entry + * @return RStream object + */ + RStreamRx getStream(String name, Codec codec); + + /** + * Returns geospatial items holder instance by name. + * + * @param type of value + * @param name - name of object + * @return Geo object + */ + RGeoRx getGeo(String name); + + /** + * Returns geospatial items holder instance by name + * using provided codec for geospatial members. + * + * @param type of value + * @param name - name of object + * @param codec - codec for value + * @return Geo object + */ + RGeoRx getGeo(String name, Codec codec); + + /** + * Returns Set based Multimap instance by name. + * + * @param type of key + * @param type of value + * @param name - name of object + * @return SetMultimap object + */ + RSetMultimapReactive getSetMultimap(String name); + + /** + * Returns Set based Multimap instance by name + * using provided codec for both map keys and values. + * + * @param type of key + * @param type of value + * @param name - name of object + * @param codec - codec for keys and values + * @return SetMultimap object + */ + RSetMultimapReactive getSetMultimap(String name, Codec codec); + + /** + * Returns set-based cache instance by name. + * Uses map (value_hash, value) under the hood for minimal memory consumption. + * Supports value eviction with a given TTL value. + * + *

If eviction is not required then it's better to use regular map {@link #getSet(String, Codec)}.

+ * + * @param type of value + * @param name - name of object + * @return SetCache object + */ + RSetCacheReactive getSetCache(String name); + + /** + * Returns set-based cache instance by name + * using provided codec for values. + * Uses map (value_hash, value) under the hood for minimal memory consumption. + * Supports value eviction with a given TTL value. + * + *

If eviction is not required then it's better to use regular map {@link #getSet(String, Codec)}.

+ * + * @param type of value + * @param name - name of object + * @param codec - codec for values + * @return SetCache object + */ + RSetCacheReactive getSetCache(String name, Codec codec); + + /** + * Returns map-based cache instance by name + * using provided codec for both cache keys and values. + * Supports entry eviction with a given TTL value. + * + *

If eviction is not required then it's better to use regular map {@link #getMap(String, Codec)}.

+ * + * @param type of key + * @param type of value + * @param name - name of object + * @param codec - codec for keys and values + * @return MapCache object + */ + RMapCacheReactive getMapCache(String name, Codec codec); + + /** + * Returns map-based cache instance by name. + * Supports entry eviction with a given TTL value. + * + *

If eviction is not required then it's better to use regular map {@link #getMap(String)}.

+ * + * @param type of key + * @param type of value + * @param name - name of object + * @return MapCache object + */ + RMapCacheReactive getMapCache(String name); + + /** + * Returns object holder by name + * + * @param type of value + * @param name - name of object + * @return Bucket object + */ + RBucketReactive getBucket(String name); + + RBucketReactive getBucket(String name, Codec codec); + + /** + * Returns HyperLogLog object by name + * + * @param type of value + * @param name - name of object + * @return HyperLogLog object + */ + RHyperLogLogReactive getHyperLogLog(String name); + + RHyperLogLogReactive getHyperLogLog(String name, Codec codec); + + /** + * Returns list instance by name. + * + * @param type of value + * @param name - name of object + * @return List object + */ + RListReactive getList(String name); + + RListReactive getList(String name, Codec codec); + + /** + * Returns List based MultiMap instance by name. + * + * @param type of key + * @param type of value + * @param name - name of object + * @return ListMultimap object + */ + RListMultimapReactive getListMultimap(String name); + + /** + * Returns List based MultiMap instance by name + * using provided codec for both map keys and values. + * + * @param type of key + * @param type of value + * @param name - name of object + * @param codec - codec for keys and values + * @return ListMultimap object + */ + RListMultimapReactive getListMultimap(String name, Codec codec); + + /** + * Returns map instance by name. + * + * @param type of key + * @param type of value + * @param name - name of object + * @return Map object + */ + RMapReactive getMap(String name); + + RMapReactive getMap(String name, Codec codec); + + /** + * Returns set instance by name. + * + * @param type of value + * @param name - name of object + * @return Set object + */ + RSetReactive getSet(String name); + + RSetReactive getSet(String name, Codec codec); + + /** + * Returns topic instance by name. + * + * @param type of message + * @param name - name of object + * @return Topic object + */ + RTopicReactive getTopic(String name); + + RTopicReactive getTopic(String name, Codec codec); + + /** + * Returns queue instance by name. + * + * @param type of value + * @param name - name of object + * @return Queue object + */ + RQueueReactive getQueue(String name); + + RQueueReactive getQueue(String name, Codec codec); + + /** + * Returns blocking queue instance by name. + * + * @param type of value + * @param name - name of object + * @return BlockingQueue object + */ + RBlockingQueueReactive getBlockingQueue(String name); + + RBlockingQueueReactive getBlockingQueue(String name, Codec codec); + + /** + * Returns blocking deque instance by name. + * + * @param type of value + * @param name - name of object + * @return BlockingDeque object + */ + RBlockingDequeReactive getBlockingDeque(String name); + + RBlockingDequeReactive getBlockingDeque(String name, Codec codec); + + /** + * Returns deque instance by name. + * + * @param type of value + * @param name - name of object + * @return Deque object + */ + RDequeReactive getDequeReactive(String name); + + RDequeReactive 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 type of value + * @param name - name of object + * @return ScoredSortedSet object + */ + RScoredSortedSetReactive getScoredSortedSet(String name); + + RScoredSortedSetReactive 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> 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); + +} diff --git a/redisson/src/main/java/org/redisson/api/RBitSetRx.java b/redisson/src/main/java/org/redisson/api/RBitSetRx.java new file mode 100644 index 000000000..521439421 --- /dev/null +++ b/redisson/src/main/java/org/redisson/api/RBitSetRx.java @@ -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 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 length(); + + /** + * Set all bits to value from fromIndex (inclusive) to toIndex (exclusive) + * + * @param fromIndex inclusive + * @param toIndex exclusive + * @param value true = 1, false = 0 + * @return void + * + */ + Flowable set(long fromIndex, long toIndex, boolean value); + + /** + * Set all bits to zero from fromIndex (inclusive) to toIndex (exclusive) + * + * @param fromIndex inclusive + * @param toIndex exclusive + * @return void + * + */ + Flowable clear(long fromIndex, long toIndex); + + /** + * Copy bits state of source BitSet object to this object + * + * @param bs - BitSet source + * @return void + */ + Flowable set(BitSet bs); + + /** + * Executes NOT operation over all bits + * + * @return void + */ + Flowable not(); + + /** + * Set all bits to one from fromIndex (inclusive) to toIndex (exclusive) + * + * @param fromIndex inclusive + * @param toIndex exclusive + * @return void + */ + Flowable set(long fromIndex, long toIndex); + + /** + * Returns number of set bits. + * + * @return number of set bits. + */ + Flowable size(); + + /** + * Returns true if bit set to one and false overwise. + * + * @param bitIndex - index of bit + * @return true if bit set to one and false overwise. + */ + Flowable get(long bitIndex); + + /** + * Set bit to one at specified bitIndex + * + * @param bitIndex - index of bit + * @return true - if previous value was true, + * false - if previous value was false + */ + Flowable set(long bitIndex); + + /** + * Set bit to value at specified bitIndex + * + * @param bitIndex - index of bit + * @param value true = 1, false = 0 + * @return true - if previous value was true, + * false - if previous value was false + */ + Flowable set(long bitIndex, boolean value); + + /** + * Returns the number of bits set to one. + * + * @return number of bits + */ + Flowable cardinality(); + + /** + * Set bit to zero at specified bitIndex + * + * @param bitIndex - index of bit + * @return true - if previous value was true, + * false - if previous value was false + */ + Flowable clear(long bitIndex); + + /** + * Set all bits to zero + * + * @return void + */ + Flowable clear(); + + /** + * Executes OR operation over this object and specified bitsets. + * Stores result into this object. + * + * @param bitSetNames - name of stored bitsets + * @return void + */ + Flowable 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 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 xor(String... bitSetNames); + +} diff --git a/redisson/src/main/java/org/redisson/api/RGeoRx.java b/redisson/src/main/java/org/redisson/api/RGeoRx.java new file mode 100644 index 000000000..8285f48ff --- /dev/null +++ b/redisson/src/main/java/org/redisson/api/RGeoRx.java @@ -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 type of value + */ +public interface RGeoRx extends RScoredSortedSetRx { + + /** + * 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 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 add(GeoEntry... entries); + + /** + * Returns distance between members in GeoUnit units. + * + * @param firstMember - first object + * @param secondMember - second object + * @param geoUnit - geo unit + * @return distance + */ + Flowable 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> hash(V... members); + + /** + * Returns geo-position mapped by defined member. + * + * @param members - objects + * @return geo position mapped by object + */ + Flowable> 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 GeoUnit 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> 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 GeoUnit 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> 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 GeoUnit units with GeoOrder + * + * @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> 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 GeoUnit units with GeoOrder + * 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> 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 GeoUnit 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> 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 GeoUnit 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> 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 GeoUnit units with GeoOrder + * + * @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> 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 GeoUnit units with GeoOrder + * 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> 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 GeoUnit 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> 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 GeoUnit 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> 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 GeoUnit units with GeoOrder + * + * @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> 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 GeoUnit units with GeoOrder + * 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> 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 GeoUnit units. + * + * @param member - object + * @param radius - radius in geo units + * @param geoUnit - geo unit + * @return list of objects + */ + Flowable> 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 GeoUnit 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> 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 GeoUnit units with GeoOrder + * + * @param member - object + * @param radius - radius in geo units + * @param geoUnit - geo unit + * @param geoOrder - geo order + * @return list of objects + */ + Flowable> 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 GeoUnit units with GeoOrder + * + * @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> 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 GeoUnit units. + * + * @param member - object + * @param radius - radius in geo units + * @param geoUnit - geo unit + * @return distance mapped by object + */ + Flowable> 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 GeoUnit 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> 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 GeoUnit units with GeoOrder + * + * @param member - object + * @param radius - radius in geo units + * @param geoUnit - geo unit + * @param geoOrder - geo + * @return distance mapped by object + */ + Flowable> 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 GeoUnit units with GeoOrder + * 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> 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 GeoUnit units. + * + * @param member - object + * @param radius - radius in geo units + * @param geoUnit - geo unit + * @return geo position mapped by object + */ + Flowable> 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 GeoUnit 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> 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 GeoUnit units with GeoOrder + * + * @param member - object + * @param radius - radius in geo units + * @param geoUnit - geo unit + * @param geoOrder - geo order + * @return geo position mapped by object + */ + Flowable> 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 GeoUnit units with GeoOrder + * 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> 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 GeoUnit units. + * Store result to destName. + * + * @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 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 GeoUnit units and limited by count + * Store result to destName. + * + * @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 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 GeoUnit units with GeoOrder + * and limited by count + * Store result to destName. + * + * @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 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 GeoUnit units. + * Store result to destName. + * + * @param destName - Geo object destination + * @param member - object + * @param radius - radius in geo units + * @param geoUnit - geo unit + * @return length of result + */ + Flowable 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 GeoUnit units and limited by count + * Store result to destName. + * + * @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 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 GeoUnit units with GeoOrder + * Store result to destName. + * + * @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 radiusStoreTo(String destName, V member, double radius, GeoUnit geoUnit, GeoOrder geoOrder, int count); + +} diff --git a/redisson/src/main/java/org/redisson/api/RHyperLogLogRx.java b/redisson/src/main/java/org/redisson/api/RHyperLogLogRx.java new file mode 100644 index 000000000..342faf433 --- /dev/null +++ b/redisson/src/main/java/org/redisson/api/RHyperLogLogRx.java @@ -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 type of stored values + */ +public interface RHyperLogLogRx extends RExpirableRx { + + /** + * Adds element into this structure. + * + * @param obj - element to add + * @return true if object has been added + * or false if it was already added + */ + Flowable add(V obj); + + /** + * Adds all elements contained in objects collection into this structure + * + * @param objects - elements to add + * @return true if at least one object has been added + * or false if all were already added + */ + Flowable addAll(Collection objects); + + /** + * Returns approximated number of unique elements added into this structure. + * + * @return approximated number of unique elements added into this structure + */ + Flowable count(); + + /** + * Returns approximated number of unique elements + * added into this instances and other instances defined through otherLogNames. + * + * @param otherLogNames - name of instances + * @return + */ + Flowable countWith(String ... otherLogNames); + + /** + * Merges multiple instances into this instance. + * + * @param otherLogNames - name of instances + */ + Flowable mergeWith(String ... otherLogNames); + +} diff --git a/redisson/src/main/java/org/redisson/api/RListMultimapRx.java b/redisson/src/main/java/org/redisson/api/RListMultimapRx.java new file mode 100644 index 000000000..ba3f1ca45 --- /dev/null +++ b/redisson/src/main/java/org/redisson/api/RListMultimapRx.java @@ -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 key type + * @param value type + */ +public interface RListMultimapRx extends RMultimapRx { + + /** + * 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}. + * + *

Changes to the returned collection will update the underlying multimap, + * and vice versa. + * + * @param key - map key + * @return list of values + */ + RListRx get(K key); + + /** + * Returns all elements at once. Result Set is NOT backed by map, + * so changes are not reflected in map. + * + * @param key - map key + * @return list of values + */ + Flowable> getAll(K key); + + /** + * Removes all values associated with the key {@code key}. + * + *

Once this method returns, {@code key} will not be mapped to any values + *

Use {@link RMultimapReactive#fastRemove} if values are not needed.

+ * + * @param key - map key + * @return the values that were removed (possibly empty). The returned + * list may be modifiable, but updating it will have no + * effect on the multimap. + */ + Flowable> removeAll(Object key); + + /** + * Stores a collection of values with the same key, replacing any existing + * values for that key. + * + *

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 + * may be modifiable, but updating it will have no effect on the + * multimap. + */ + Flowable> replaceValues(K key, Iterable values); + +} diff --git a/redisson/src/main/java/org/redisson/api/RListRx.java b/redisson/src/main/java/org/redisson/api/RListRx.java new file mode 100644 index 000000000..3363b438f --- /dev/null +++ b/redisson/src/main/java/org/redisson/api/RListRx.java @@ -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 the type of elements held in this collection + */ +// TODO add sublist support +public interface RListRx extends RCollectionRx, RSortableRx> { + + /** + * Loads elements by specified indexes + * + * @param indexes of elements + * @return elements + */ + Flowable> get(int ...indexes); + + /** + * Add element after elementToFind + * + * @param elementToFind - object to find + * @param element - object to add + * @return new list size + */ + Flowable addAfter(V elementToFind, V element); + + /** + * Add element before elementToFind + * + * @param elementToFind - object to find + * @param element - object to add + * @return new list size + */ + Flowable addBefore(V elementToFind, V element); + + Flowable descendingIterator(); + + Flowable descendingIterator(int startIndex); + + Flowable iterator(int startIndex); + + Flowable lastIndexOf(Object o); + + Flowable indexOf(Object o); + + Flowable add(int index, V element); + + Flowable addAll(int index, Collection coll); + + Flowable fastSet(int index, V element); + + Flowable set(int index, V element); + + Flowable get(int index); + + Flowable remove(int index); + + /** + * Read all elements at once + * + * @return list of values + */ + Flowable> readAll(); + + /** + * Trim list and remains elements only in specified range + * fromIndex, inclusive, and toIndex, inclusive. + * + * @param fromIndex - from index + * @param toIndex - to index + * @return void + */ + Flowable trim(int fromIndex, int toIndex); + + /** + * Remove object by specified index + * + * @param index - index of object + * @return void + */ + Flowable fastRemove(int index); + +} diff --git a/redisson/src/main/java/org/redisson/api/RLockRx.java b/redisson/src/main/java/org/redisson/api/RLockRx.java new file mode 100644 index 000000000..84cde0069 --- /dev/null +++ b/redisson/src/main/java/org/redisson/api/RLockRx.java @@ -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 forceUnlock(); + + Flowable unlock(); + + Flowable unlock(long threadId); + + Flowable tryLock(); + + Flowable lock(); + + Flowable lock(long threadId); + + Flowable lock(long leaseTime, TimeUnit unit); + + Flowable lock(long leaseTime, TimeUnit unit, long threadId); + + Flowable tryLock(long threadId); + + Flowable tryLock(long waitTime, TimeUnit unit); + + Flowable tryLock(long waitTime, long leaseTime, TimeUnit unit); + + Flowable tryLock(long waitTime, long leaseTime, TimeUnit unit, long threadId); + + +} diff --git a/redisson/src/main/java/org/redisson/api/RMultimapRx.java b/redisson/src/main/java/org/redisson/api/RMultimapRx.java new file mode 100644 index 000000000..30c82355c --- /dev/null +++ b/redisson/src/main/java/org/redisson/api/RMultimapRx.java @@ -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 key type + * @param value type + */ +public interface RMultimapRx extends RExpirableRx { + + /** + * Returns the number of key-value pairs in this multimap. + * + * @return size of multimap + */ + Flowable size(); + + /** + * Returns {@code true} if this multimap contains at least one key-value pair + * with the key {@code key}. + * + * @param key - map key + * @return true if contains a key + */ + Flowable 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 true if contains a value + */ + Flowable 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 true if contains an entry + */ + Flowable containsEntry(Object key, Object value); + + /** + * Stores a key-value pair in this multimap. + * + *

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 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 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):

   {@code
+     *
+     *   for (V value : values) {
+     *     put(key, value);
+     *   }}
+ * + *

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 putAll(K key, Iterable values); + + /** + * Returns the number of key-value pairs in this multimap. + * + * @return keys amount + */ + Flowable keySize(); + + /** + * Removes keys from map by one operation + * + * Works faster than RMultimap.remove but not returning + * the value associated with key + * + * @param keys - map keys + * @return the number of keys that were removed from the hash, not including specified but non existing keys + */ + Flowable fastRemove(K ... keys); + + /** + * Read all keys at once + * + * @return keys + */ + Flowable> readAllKeySet(); + + +} diff --git a/redisson/src/main/java/org/redisson/api/RPermitExpirableSemaphoreRx.java b/redisson/src/main/java/org/redisson/api/RPermitExpirableSemaphoreRx.java new file mode 100644 index 000000000..b4a3f2601 --- /dev/null +++ b/redisson/src/main/java/org/redisson/api/RPermitExpirableSemaphoreRx.java @@ -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. + * + *

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. + * + *

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}. + * + *

Acquires a permit, if one is available and returns its id, + * reducing the number of available permits by one. + * + *

If no permit is available then the current thread becomes + * disabled for thread scheduling purposes and lies dormant until + * one of two things happens: + *

    + *
  • Some other thread invokes the {@link #release(String)} method for this + * semaphore and the current thread is next to be assigned a permit; or + *
  • Some other thread {@linkplain Thread#interrupt interrupts} + * the current thread. + *
+ * + * @return permit id + */ + Flowable acquire(); + + /** + * Acquires a permit with defined lease time from this semaphore, + * blocking until one is available, + * or the thread is {@linkplain Thread#interrupt interrupted}. + * + *

Acquires a permit, if one is available and returns its id, + * reducing the number of available permits by one. + * + *

If no permit is available then the current thread becomes + * disabled for thread scheduling purposes and lies dormant until + * one of two things happens: + *

    + *
  • Some other thread invokes the {@link #release} method for this + * semaphore and the current thread is next to be assigned a permit; or + *
  • Some other thread {@linkplain Thread#interrupt interrupts} + * the current thread. + *
+ * + * @param leaseTime - permit lease time + * @param unit - time unit + * @return permit id + */ + Flowable acquire(long leaseTime, TimeUnit unit); + + /** + * Acquires a permit only if one is available at the + * time of invocation. + * + *

Acquires a permit, if one is available and returns immediately, + * with the permit id, + * reducing the number of available permits by one. + * + *

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 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}. + * + *

Acquires a permit, if one is available and returns immediately, + * with the permit id, + * reducing the number of available permits by one. + * + *

If no permit is available then the current thread becomes + * disabled for thread scheduling purposes and lies dormant until + * one of three things happens: + *

    + *
  • Some other thread invokes the {@link #release(String)} method for this + * semaphore and the current thread is next to be assigned a permit; or + *
  • Some other thread {@linkplain Thread#interrupt interrupts} + * the current thread; or + *
  • The specified waiting time elapses. + *
+ * + *

If a permit is acquired then the permit id is returned. + * + *

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 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}. + * + *

Acquires a permit, if one is available and returns immediately, + * with the permit id, + * reducing the number of available permits by one. + * + *

If no permit is available then the current thread becomes + * disabled for thread scheduling purposes and lies dormant until + * one of three things happens: + *

    + *
  • Some other thread invokes the {@link #release(String)} method for this + * semaphore and the current thread is next to be assigned a permit; or + *
  • Some other thread {@linkplain Thread#interrupt interrupts} + * the current thread; or + *
  • The specified waiting time elapses. + *
+ * + *

If a permit is acquired then the permit id is returned. + * + *

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 tryAcquire(long waitTime, long leaseTime, TimeUnit unit); + + /** + * Releases a permit by its id, returning it to the semaphore. + * + *

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. + * + *

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 tryRelease(String permitId); + + /** + * Releases a permit by its id, returning it to the semaphore. + * + *

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. + * + *

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. + * + *

Throws an exception if permit id doesn't exist or has already been release + * + * @param permitId - permit id + * @return void + */ + Flowable release(String permitId); + + /** + * Returns the current number of available permits. + * + * @return number of available permits + */ + Flowable availablePermits(); + + /** + * Sets number of permits. + * + * @param permits - number of permits + * @return true if permits has been set successfully, otherwise false. + */ + Flowable 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 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 true if permits has been updated successfully, otherwise false. + */ + Flowable updateLeaseTime(String permitId, long leaseTime, TimeUnit unit); + +} diff --git a/redisson/src/main/java/org/redisson/api/RRateLimiterRx.java b/redisson/src/main/java/org/redisson/api/RRateLimiterRx.java new file mode 100644 index 000000000..df381b5eb --- /dev/null +++ b/redisson/src/main/java/org/redisson/api/RRateLimiterRx.java @@ -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 trySetRate(RateType mode, long rate, long rateInterval, RateIntervalUnit rateIntervalUnit); + + /** + * Acquires a permit only if one is available at the + * time of invocation. + * + *

Acquires a permit, if one is available and returns immediately, + * with the value {@code true}, + * reducing the number of available permits by one. + * + *

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 tryAcquire(); + + /** + * Acquires the given number of permits only if all are available at the + * time of invocation. + * + *

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. + * + *

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 tryAcquire(long permits); + + /** + * Acquires a permit from this RateLimiter, blocking until one is available. + * + *

Acquires a permit, if one is available and returns immediately, + * reducing the number of available permits by one. + * + */ + Flowable acquire(); + + /** + * Acquires a specified permits from this RateLimiter, + * blocking until one is available. + * + *

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 acquire(long permits); + + /** + * Acquires a permit from this RateLimiter, if one becomes available + * within the given waiting time. + * + *

Acquires a permit, if one is available and returns immediately, + * with the value {@code true}, + * reducing the number of available permits by one. + * + *

If no permit is available then the current thread becomes + * disabled for thread scheduling purposes and lies dormant until + * specified waiting time elapses. + * + *

If a permit is acquired then the value {@code true} is returned. + * + *

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 tryAcquire(long timeout, TimeUnit unit); + + /** + * Acquires the given number of permits only if all are available + * within the given waiting time. + * + *

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. + * + *

If no permit is available then the current thread becomes + * disabled for thread scheduling purposes and lies dormant until + * the specified waiting time elapses. + * + *

If a permits is acquired then the value {@code true} is returned. + * + *

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 tryAcquire(long permits, long timeout, TimeUnit unit); + +} diff --git a/redisson/src/main/java/org/redisson/api/RReadWriteLockRx.java b/redisson/src/main/java/org/redisson/api/RReadWriteLockRx.java new file mode 100644 index 000000000..2d15da03b --- /dev/null +++ b/redisson/src/main/java/org/redisson/api/RReadWriteLockRx.java @@ -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(); + +} diff --git a/redisson/src/main/java/org/redisson/api/RScoredSortedSetRx.java b/redisson/src/main/java/org/redisson/api/RScoredSortedSetRx.java new file mode 100644 index 000000000..c2610bbdb --- /dev/null +++ b/redisson/src/main/java/org/redisson/api/RScoredSortedSetRx.java @@ -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 value type + */ +public interface RScoredSortedSetRx extends RExpirableRx, RSortableRx> { + + /** + * Removes and returns first available tail element of any sorted set, + * waiting up to the specified wait time if necessary for an element to become available + * in any of defined sorted sets including this one. + *

+ * Requires Redis 5.0.0 and higher. + * + * @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 pollLastFromAny(long timeout, TimeUnit unit, String ... queueNames); + + /** + * Removes and returns first available head element of any sorted set, + * waiting up to the specified wait time if necessary for an element to become available + * in any of defined sorted sets including this one. + *

+ * Requires Redis 5.0.0 and higher. + * + * @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 pollFirstFromAny(long timeout, TimeUnit unit, String ... queueNames); + + /** + * Removes and returns the head element or {@code null} if this sorted set is empty. + *

+ * Requires Redis 5.0.0 and higher. + * + * @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 pollFirst(long timeout, TimeUnit unit); + + /** + * Removes and returns the tail element or {@code null} if this sorted set is empty. + *

+ * Requires Redis 5.0.0 and higher. + * + * @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 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> 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> 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 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 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 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 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 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 lastScore(); + + /** + * Returns an iterator over elements in this set. + * If pattern is not null then only elements match this pattern are loaded. + * + * @param pattern - search pattern + * @return iterator + */ + Flowable iterator(String pattern); + + /** + * Returns an iterator over elements in this set. + * Elements are loaded in batch. Batch size is defined by count param. + * + * @param count - size of elements batch + * @return iterator + */ + Flowable iterator(int count); + + /** + * Returns an iterator over elements in this set. + * Elements are loaded in batch. Batch size is defined by count 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 iterator(String pattern, int count); + + Flowable iterator(); + + Flowable removeRangeByScore(double startScore, boolean startScoreInclusive, double endScore, boolean endScoreInclusive); + + Flowable removeRangeByRank(int startIndex, int endIndex); + + /** + * Returns rank of value, with the scores ordered from low to high. + * + * @param o - object + * @return rank or null if value does not exist + */ + Flowable rank(V o); + + /** + * Returns rank of value, with the scores ordered from high to low. + * + * @param o - object + * @return rank or null if value does not exist + */ + Flowable revRank(V o); + + Flowable 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 true if element has added and false if not. + */ + Flowable add(double score, V object); + + Flowable addAll(Map 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 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 addAndGetRevRank(double score, V object); + + /** + * Adds element to this set only if has not been added before. + *

+ * Requires Redis 3.0.2 and higher. + * + * @param score - object score + * @param object - object itself + * @return true if element has added and false if not. + */ + Flowable tryAdd(double score, V object); + + Flowable remove(V object); + + Flowable size(); + + Flowable contains(V o); + + Flowable containsAll(Collection c); + + Flowable removeAll(Collection c); + + Flowable retainAll(Collection c); + + Flowable 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 addScoreAndGetRevRank(V object, Number value); + + /** + * Adds score to element and returns its rank + * + * @param object - object itself + * @param value - object score + * @return rank + */ + Flowable addScoreAndGetRank(V object, Number value); + + Flowable> valueRange(int startIndex, int endIndex); + + Flowable>> entryRange(int startIndex, int endIndex); + + Flowable> valueRange(double startScore, boolean startScoreInclusive, double endScore, boolean endScoreInclusive); + + Flowable>> entryRange(double startScore, boolean startScoreInclusive, double endScore, boolean endScoreInclusive); + + Flowable> valueRange(double startScore, boolean startScoreInclusive, double endScore, boolean endScoreInclusive, int offset, int count); + + Flowable>> entryRange(double startScore, boolean startScoreInclusive, double endScore, boolean endScoreInclusive, int offset, int count); + + Flowable> valueRangeReversed(int startIndex, int endIndex); + + /** + * Returns all values between startScore and endScore in reversed order. + * + * @param startScore - start score. + * Use Double.POSITIVE_INFINITY or Double.NEGATIVE_INFINITY + * to define infinity numbers + * @param startScoreInclusive - start score inclusive + * @param endScore - end score + * Use Double.POSITIVE_INFINITY or Double.NEGATIVE_INFINITY + * to define infinity numbers + * + * @param endScoreInclusive - end score inclusive + * @return values + */ + Flowable> valueRangeReversed(double startScore, boolean startScoreInclusive, double endScore, boolean endScoreInclusive); + + Flowable> valueRangeReversed(double startScore, boolean startScoreInclusive, double endScore, boolean endScoreInclusive, int offset, int count); + + Flowable>> entryRangeReversed(int startIndex, int endIndex); + + Flowable>> entryRangeReversed(double startScore, boolean startScoreInclusive, double endScore, boolean endScoreInclusive); + + Flowable>> entryRangeReversed(double startScore, boolean startScoreInclusive, double endScore, boolean endScoreInclusive, int offset, int count); + + + /** + * Returns the number of elements with a score between startScore and endScore. + * + * @param startScore - start score + * @param startScoreInclusive - start score inclusive + * @param endScore - end score + * @param endScoreInclusive - end score inclusive + * @return count + */ + Flowable count(double startScore, boolean startScoreInclusive, double endScore, boolean endScoreInclusive); + + /** + * Read all values at once. + * + * @return values + */ + Flowable> readAll(); + + /** + * Intersect provided ScoredSortedSets + * and store result to current ScoredSortedSet + * + * @param names - names of ScoredSortedSet + * @return length of intersection + */ + Flowable 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 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 intersection(Map 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 intersection(Aggregate aggregate, Map nameWithWeight); + + /** + * Union provided ScoredSortedSets + * and store result to current ScoredSortedSet + * + * @param names - names of ScoredSortedSet + * @return length of union + */ + Flowable 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 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 union(Map 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 union(Aggregate aggregate, Map nameWithWeight); + + +} diff --git a/redisson/src/main/java/org/redisson/api/RScriptRx.java b/redisson/src/main/java/org/redisson/api/RScriptRx.java new file mode 100644 index 000000000..521c49cf2 --- /dev/null +++ b/redisson/src/main/java/org/redisson/api/RScriptRx.java @@ -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 scriptFlush(); + + Flowable evalSha(Mode mode, String shaDigest, ReturnType returnType, List keys, Object... values); + + Flowable evalSha(Mode mode, Codec codec, String shaDigest, ReturnType returnType, List keys, Object... values); + + Flowable evalSha(Mode mode, String shaDigest, ReturnType returnType); + + Flowable evalSha(Mode mode, Codec codec, String shaDigest, ReturnType returnType); + + Flowable eval(Mode mode, String luaScript, ReturnType returnType, List keys, Object... values); + + Flowable eval(Mode mode, Codec codec, String luaScript, ReturnType returnType, List keys, Object... values); + + Flowable eval(Mode mode, String luaScript, ReturnType returnType); + + Flowable eval(Mode mode, Codec codec, String luaScript, ReturnType returnType); + + Flowable scriptLoad(String luaScript); + + Flowable> scriptExists(String ... shaDigests); + + Flowable scriptKill(); + +} diff --git a/redisson/src/main/java/org/redisson/api/RSemaphoreRx.java b/redisson/src/main/java/org/redisson/api/RSemaphoreRx.java new file mode 100644 index 000000000..bc1c38d6d --- /dev/null +++ b/redisson/src/main/java/org/redisson/api/RSemaphoreRx.java @@ -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. + * + *

Acquires a permit, if one is available and returns immediately, + * with the value {@code true}, + * reducing the number of available permits by one. + * + *

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 tryAcquire(); + + /** + * Acquires the given number of permits only if all are available at the + * time of invocation. + * + *

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. + * + *

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 tryAcquire(int permits); + + /** + * Acquires a permit from this semaphore. + * + *

Acquires a permit, if one is available and returns immediately, + * reducing the number of available permits by one. + * + * @return void + * + */ + Publisher 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 acquire(int permits); + + /** + * Releases a permit, returning it to the semaphore. + * + *

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. + * + *

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 release(); + + /** + * Releases the given number of permits, returning them to the semaphore. + * + *

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. + * + *

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 release(int permits); + + /** + * Sets number of permits. + * + * @param permits - number of permits + * @return true if permits has been set successfully, otherwise false. + */ + Publisher trySetPermits(int permits); + + /** + *

Acquires a permit, if one is available and returns immediately, + * with the value {@code true}, + * reducing the number of available permits by one. + * + *

If a permit is acquired then the value {@code true} is returned. + * + *

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 tryAcquire(long waitTime, TimeUnit unit); + + /** + * Acquires the given number of permits only if all are available + * within the given waiting time. + * + *

Acquires a permits, if all are available and returns immediately, + * with the value {@code true}, + * reducing the number of available permits by one. + * + *

If a permits is acquired then the value {@code true} is returned. + * + *

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 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 reducePermits(int permits); + + +} diff --git a/redisson/src/main/java/org/redisson/api/RSetCacheRx.java b/redisson/src/main/java/org/redisson/api/RSetCacheRx.java new file mode 100644 index 000000000..b4a39eb9e --- /dev/null +++ b/redisson/src/main/java/org/redisson/api/RSetCacheRx.java @@ -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 value + */ +public interface RSetCacheRx extends RCollectionRx { + + Flowable 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 size(); + + /** + * Read all elements at once + * + * @return values + */ + Flowable> readAll(); + +} diff --git a/redisson/src/main/java/org/redisson/api/RSetMultimapRx.java b/redisson/src/main/java/org/redisson/api/RSetMultimapRx.java new file mode 100644 index 000000000..4e4725a82 --- /dev/null +++ b/redisson/src/main/java/org/redisson/api/RSetMultimapRx.java @@ -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 key type + * @param value type + */ +public interface RSetMultimapRx extends RMultimapRx { + + /** + * 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}. + * + *

Changes to the returned collection will update the underlying multimap, + * and vice versa. + * + * @param key - map key + * @return set of values + */ + RSetRx get(K key); + + /** + * Returns all elements at once. Result Set is NOT backed by map, + * so changes are not reflected in map. + * + * @param key - map key + * @return set of values + */ + Flowable> getAll(K key); + + /** + * Removes all values associated with the key {@code key}. + * + *

Once this method returns, {@code key} will not be mapped to any values + *

Use {@link RMultimapReactive#fastRemove} if values are not needed.

+ * + * @param key - map key + * @return the values that were removed (possibly empty). The returned + * set may be modifiable, but updating it will have no + * effect on the multimap. + */ + Flowable> removeAll(Object key); + + /** + * Stores a collection of values with the same key, replacing any existing + * values for that key. + * + *

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 + * may be modifiable, but updating it will have no effect on the + * multimap. + */ + Flowable> replaceValues(K key, Iterable values); + +} diff --git a/redisson/src/main/java/org/redisson/api/RSortableRx.java b/redisson/src/main/java/org/redisson/api/RSortableRx.java index 44cecc369..551125d5d 100644 --- a/redisson/src/main/java/org/redisson/api/RSortableRx.java +++ b/redisson/src/main/java/org/redisson/api/RSortableRx.java @@ -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 { * @param order for sorted data * @return sorted collection */ - Single readSorted(SortOrder order); + Flowable readSorted(SortOrder order); /** * Read data in sorted view @@ -44,7 +44,7 @@ public interface RSortableRx { * @param count of sorted data * @return sorted collection */ - Single readSorted(SortOrder order, int offset, int count); + Flowable readSorted(SortOrder order, int offset, int count); /** * Read data in sorted view @@ -53,7 +53,7 @@ public interface RSortableRx { * @param order for sorted data * @return sorted collection */ - Single readSorted(String byPattern, SortOrder order); + Flowable readSorted(String byPattern, SortOrder order); /** * Read data in sorted view @@ -64,7 +64,7 @@ public interface RSortableRx { * @param count of sorted data * @return sorted collection */ - Single readSorted(String byPattern, SortOrder order, int offset, int count); + Flowable readSorted(String byPattern, SortOrder order, int offset, int count); /** * Read data in sorted view @@ -75,7 +75,7 @@ public interface RSortableRx { * @param order for sorted data * @return sorted collection */ - Single> readSorted(String byPattern, List getPatterns, SortOrder order); + Flowable> readSorted(String byPattern, List getPatterns, SortOrder order); /** * Read data in sorted view @@ -88,7 +88,7 @@ public interface RSortableRx { * @param count of sorted data * @return sorted collection */ - Single> readSorted(String byPattern, List getPatterns, SortOrder order, int offset, int count); + Flowable> readSorted(String byPattern, List getPatterns, SortOrder order, int offset, int count); /** * Sort data and store to destName list @@ -97,7 +97,7 @@ public interface RSortableRx { * @param order for sorted data * @return length of sorted data */ - Single sortTo(String destName, SortOrder order); + Flowable sortTo(String destName, SortOrder order); /** * Sort data and store to destName list @@ -108,7 +108,7 @@ public interface RSortableRx { * @param count of sorted data * @return length of sorted data */ - Single sortTo(String destName, SortOrder order, int offset, int count); + Flowable sortTo(String destName, SortOrder order, int offset, int count); /** * Sort data and store to destName list @@ -118,7 +118,7 @@ public interface RSortableRx { * @param order for sorted data * @return length of sorted data */ - Single sortTo(String destName, String byPattern, SortOrder order); + Flowable sortTo(String destName, String byPattern, SortOrder order); /** * Sort data and store to destName list @@ -130,7 +130,7 @@ public interface RSortableRx { * @param count of sorted data * @return length of sorted data */ - Single sortTo(String destName, String byPattern, SortOrder order, int offset, int count); + Flowable sortTo(String destName, String byPattern, SortOrder order, int offset, int count); /** * Sort data and store to destName list @@ -141,7 +141,7 @@ public interface RSortableRx { * @param order for sorted data * @return length of sorted data */ - Single sortTo(String destName, String byPattern, List getPatterns, SortOrder order); + Flowable sortTo(String destName, String byPattern, List getPatterns, SortOrder order); /** * Sort data and store to destName list @@ -154,6 +154,6 @@ public interface RSortableRx { * @param count of sorted data * @return length of sorted data */ - Single sortTo(String destName, String byPattern, List getPatterns, SortOrder order, int offset, int count); + Flowable sortTo(String destName, String byPattern, List getPatterns, SortOrder order, int offset, int count); } diff --git a/redisson/src/main/java/org/redisson/api/RStreamRx.java b/redisson/src/main/java/org/redisson/api/RStreamRx.java new file mode 100644 index 000000000..fff57ac68 --- /dev/null +++ b/redisson/src/main/java/org/redisson/api/RStreamRx.java @@ -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. + *

+ * Requires Redis 5.0.0 and higher. + * + * @author Nikita Koksharov + * + * @param key type + * @param value type + */ +public interface RStreamRx extends RExpirableRx { + + /** + * Creates consumer group by name. + * + * @param groupName - name of group + * @return void + */ + Flowable createGroup(String groupName); + + /** + * Creates consumer group by name and stream id. + * Only new messages after defined stream id will be available for consumers of this group. + *

+ * {@link StreamId#NEWEST} is used for messages arrived since the moment of group creating + * + * @param groupName - name of group + * @return void + */ + Flowable createGroup(String groupName, StreamId id); + + /** + * Marks pending messages by group name and stream ids as correctly processed. + * + * @param groupName - name of group + * @param ids - stream ids + * @return marked messages amount + */ + Flowable ack(String groupName, StreamId... ids); + + /** + * Returns pending messages by group name + * + * @param groupName - name of group + * @return result object + */ + Flowable listPending(String groupName); + + /** + * Returns list of pending messages by group name. + * Limited by start stream id and end stream id and count. + *

+ * {@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> 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. + *

+ * {@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> 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>> claim(String groupName, String consumerName, long idleTime, TimeUnit idleTimeUnit, StreamId ... ids); + + /** + * Read stream data from groupName by consumerName and specified collection of Stream IDs. + * + * @param ids - collection of Stream IDs + * @return stream data mapped by Stream ID + */ + Flowable>> readGroup(String groupName, String consumerName, StreamId ... ids); + + /** + * Read stream data from groupName by consumerName 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>> readGroup(String groupName, String consumerName, int count, StreamId ... ids); + + /** + * Read stream data from groupName by consumerName and specified collection of Stream IDs. + * Wait for stream data availability for specified timeout 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>> readGroup(String groupName, String consumerName, long timeout, TimeUnit unit, StreamId ... ids); + + /** + * Read stream data from groupName by consumerName and specified collection of Stream IDs. + * Wait for stream data availability for specified timeout 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>> readGroup(String groupName, String consumerName, int count, long timeout, TimeUnit unit, StreamId ... ids); + + + /** + * Returns number of entries in stream + * + * @return size of stream + */ + Flowable size(); + + /** + * Appends a new entry and returns generated Stream ID + * + * @param key - key of entry + * @param value - value of entry + * @return Stream ID + */ + Flowable 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 add(StreamId id, K key, V value); + + /** + * Appends a new entry and returns generated Stream ID. + * Trims stream to a specified trimLen size. + * If trimStrict is false 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 false then trims to few tens of entries more than specified length to trim + * @return Stream ID + */ + Flowable add(K key, V value, int trimLen, boolean trimStrict); + + /** + * Appends a new entry by specified Stream ID. + * Trims stream to a specified trimLen size. + * If trimStrict is false 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 false then trims to few tens of entries more than specified length to trim + * @return void + */ + Flowable 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 addAll(Map entries); + + /** + * Appends new entries by specified Stream ID + * + * @param id - Stream ID + * @param entries - entries to add + * @return void + */ + Flowable addAll(StreamId id, Map entries); + + /** + * Appends new entries and returns generated Stream ID. + * Trims stream to a specified trimLen size. + * If trimStrict is false 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 false then trims to few tens of entries more than specified length to trim + * @return Stream ID + */ + Flowable addAll(Map entries, int trimLen, boolean trimStrict); + + /** + * Appends new entries by specified Stream ID. + * Trims stream to a specified trimLen size. + * If trimStrict is false 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 false then trims to few tens of entries more than specified length to trim + * @return void + */ + Flowable addAll(StreamId id, Map 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>> 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>> read(int count, StreamId ... ids); + + /** + * Read stream data by specified collection of Stream IDs. + * Wait for stream data availability for specified timeout 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>> read(long timeout, TimeUnit unit, StreamId ... ids); + + /** + * Read stream data by specified collection of Stream IDs. + * Wait for stream data availability for specified timeout 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>> 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>>> 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>>> 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>>> read(StreamId id, Map 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>>> 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>>> 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>>> read(int count, StreamId id, Map nameToId); + + /** + * Read stream data by specified stream name including this stream. + * Wait for the first stream data availability for specified timeout 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>>> 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 timeout 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>>> 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 timeout 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>>> read(long timeout, TimeUnit unit, StreamId id, Map nameToId); + + /** + * Read stream data by specified stream name including this stream. + * Wait for the first stream data availability for specified timeout 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>>> 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 timeout 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>>> 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 timeout 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>>> read(int count, long timeout, TimeUnit unit, StreamId id, Map 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>> 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>> 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>> 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>> rangeReversed(int count, StreamId startId, StreamId endId); + +} diff --git a/redisson/src/main/java/org/redisson/api/RedissonRxClient.java b/redisson/src/main/java/org/redisson/api/RedissonRxClient.java index 661ea2ab4..29fe6e58a 100644 --- a/redisson/src/main/java/org/redisson/api/RedissonRxClient.java +++ b/redisson/src/main/java/org/redisson/api/RedissonRxClient.java @@ -28,130 +28,130 @@ import org.redisson.config.Config; */ public interface RedissonRxClient { -// /** -// * Returns stream instance by name -// *

-// * Requires Redis 5.0.0 and higher. -// * -// * @param type of key -// * @param type of value -// * @param name of stream -// * @return RStream object -// */ -// RStreamReactive getStream(String name); -// -// /** -// * Returns stream instance by name -// * using provided codec for entries. -// *

-// * Requires Redis 5.0.0 and higher. -// * -// * @param type of key -// * @param type of value -// * @param name - name of stream -// * @param codec - codec for entry -// * @return RStream object -// */ -// RStreamReactive getStream(String name, Codec codec); -// -// /** -// * Returns geospatial items holder instance by name. -// * -// * @param type of value -// * @param name - name of object -// * @return Geo object -// */ -// RGeoReactive getGeo(String name); -// -// /** -// * Returns geospatial items holder instance by name -// * using provided codec for geospatial members. -// * -// * @param type of value -// * @param name - name of object -// * @param codec - codec for value -// * @return Geo object -// */ -// RGeoReactive getGeo(String name, Codec codec); -// -// /** -// * Returns rate limiter instance by name -// * -// * @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. -// *

-// * Implements a fair 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. -// *

-// * Implements a non-fair 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 name. -// * Supports value eviction with a given TTL value. -// * -// *

If eviction is not required then it's better to use regular map {@link #getSet(String, Codec)}.

-// * -// * @param type of values -// * @param name - name of object -// * @return SetCache object -// */ -// RSetCacheReactive getSetCache(String name); -// -// /** -// * Returns set-based cache instance by name. -// * Supports value eviction with a given TTL value. -// * -// *

If eviction is not required then it's better to use regular map {@link #getSet(String, Codec)}.

-// * -// * @param type of values -// * @param name - name of object -// * @param codec - codec for values -// * @return SetCache object -// */ -// RSetCacheReactive getSetCache(String name, Codec codec); -// + /** + * Returns stream instance by name + *

+ * Requires Redis 5.0.0 and higher. + * + * @param type of key + * @param type of value + * @param name of stream + * @return RStream object + */ + RStreamRx getStream(String name); + + /** + * Returns stream instance by name + * using provided codec for entries. + *

+ * Requires Redis 5.0.0 and higher. + * + * @param type of key + * @param type of value + * @param name - name of stream + * @param codec - codec for entry + * @return RStream object + */ + RStreamRx getStream(String name, Codec codec); + + /** + * Returns geospatial items holder instance by name. + * + * @param type of value + * @param name - name of object + * @return Geo object + */ + RGeoRx getGeo(String name); + + /** + * Returns geospatial items holder instance by name + * using provided codec for geospatial members. + * + * @param type of value + * @param name - name of object + * @param codec - codec for value + * @return Geo object + */ + RGeoRx getGeo(String name, Codec codec); + + /** + * Returns rate limiter instance by name + * + * @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. + *

+ * Implements a fair 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. + *

+ * Implements a non-fair 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 name. + * Supports value eviction with a given TTL value. + * + *

If eviction is not required then it's better to use regular map {@link #getSet(String, Codec)}.

+ * + * @param type of values + * @param name - name of object + * @return SetCache object + */ + RSetCacheRx getSetCache(String name); + + /** + * Returns set-based cache instance by name. + * Supports value eviction with a given TTL value. + * + *

If eviction is not required then it's better to use regular map {@link #getSet(String, Codec)}.

+ * + * @param type of values + * @param name - name of object + * @param codec - codec for values + * @return SetCache object + */ + RSetCacheRx 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 { */ RBucketRx getBucket(String name, Codec codec); -// /** -// * Returns a list of object holder instances by a key pattern -// * -// * @param type of value -// * @param pattern - pattern for name of buckets -// * @return list of buckets -// */ -// List> findBuckets(String pattern); -// -// /** -// * Returns HyperLogLog instance by name. -// * -// * @param type of values -// * @param name - name of object -// * @return HyperLogLog object -// */ -// RHyperLogLogReactive getHyperLogLog(String name); -// -// /** -// * Returns HyperLogLog instance by name -// * using provided codec for hll objects. -// * -// * @param type of values -// * @param name - name of object -// * @param codec - codec of values -// * @return HyperLogLog object -// */ -// RHyperLogLogReactive getHyperLogLog(String name, Codec codec); -// -// /** -// * Returns list instance by name. -// * -// * @param type of values -// * @param name - name of object -// * @return List object -// */ -// RListReactive getList(String name); -// -// /** -// * Returns list instance by name -// * using provided codec for list objects. -// * -// * @param type of values -// * @param name - name of object -// * @param codec - codec for values -// * @return List object -// */ -// RListReactive getList(String name, Codec codec); -// -// /** -// * Returns List based Multimap instance by name. -// * -// * @param type of key -// * @param type of value -// * @param name - name of object -// * @return ListMultimap object -// */ -// RListMultimapReactive getListMultimap(String name); -// -// /** -// * Returns List based Multimap instance by name -// * using provided codec for both map keys and values. -// * -// * @param type of key -// * @param type of value -// * @param name - name of object -// * @param codec - codec for keys and values -// * @return RListMultimapReactive object -// */ -// RListMultimapReactive getListMultimap(String name, Codec codec); -// -// /** -// * Returns Set based Multimap instance by name. -// * -// * @param type of key -// * @param type of value -// * @param name - name of object -// * @return SetMultimap object -// */ -// RSetMultimapReactive getSetMultimap(String name); -// -// /** -// * Returns Set based Multimap instance by name -// * using provided codec for both map keys and values. -// * -// * @param type of key -// * @param type of value -// * @param name - name of object -// * @param codec - codec for keys and values -// * @return SetMultimap object -// */ -// RSetMultimapReactive getSetMultimap(String name, Codec codec); -// + /** + * Returns HyperLogLog instance by name. + * + * @param type of values + * @param name - name of object + * @return HyperLogLog object + */ + RHyperLogLogRx getHyperLogLog(String name); + + /** + * Returns HyperLogLog instance by name + * using provided codec for hll objects. + * + * @param type of values + * @param name - name of object + * @param codec - codec of values + * @return HyperLogLog object + */ + RHyperLogLogRx getHyperLogLog(String name, Codec codec); + + /** + * Returns list instance by name. + * + * @param type of values + * @param name - name of object + * @return List object + */ + RListRx getList(String name); + + /** + * Returns list instance by name + * using provided codec for list objects. + * + * @param type of values + * @param name - name of object + * @param codec - codec for values + * @return List object + */ + RListRx getList(String name, Codec codec); + + /** + * Returns List based Multimap instance by name. + * + * @param type of key + * @param type of value + * @param name - name of object + * @return ListMultimap object + */ + RListMultimapRx getListMultimap(String name); + + /** + * Returns List based Multimap instance by name + * using provided codec for both map keys and values. + * + * @param type of key + * @param type of value + * @param name - name of object + * @param codec - codec for keys and values + * @return RListMultimapReactive object + */ + RListMultimapRx getListMultimap(String name, Codec codec); + + /** + * Returns Set based Multimap instance by name. + * + * @param type of key + * @param type of value + * @param name - name of object + * @return SetMultimap object + */ + RSetMultimapRx getSetMultimap(String name); + + /** + * Returns Set based Multimap instance by name + * using provided codec for both map keys and values. + * + * @param type of key + * @param type of value + * @param name - name of object + * @param codec - codec for keys and values + * @return SetMultimap object + */ + RSetMultimapRx getSetMultimap(String name, Codec codec); /** * Returns map instance by name. @@ -390,28 +380,28 @@ public interface RedissonRxClient { */ RSetRx getSet(String name, Codec codec); -// /** -// * Returns Redis Sorted Set instance by name. -// * This sorted set sorts objects by object score. -// * -// * @param type of values -// * @param name of scored sorted set -// * @return ScoredSortedSet object -// */ -// RScoredSortedSetReactive 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 type of values -// * @param name - name of scored sorted set -// * @param codec - codec for values -// * @return ScoredSortedSet object -// */ -// RScoredSortedSetReactive getScoredSortedSet(String name, Codec codec); -// + /** + * Returns Redis Sorted Set instance by name. + * This sorted set sorts objects by object score. + * + * @param type of values + * @param name of scored sorted set + * @return ScoredSortedSet object + */ + RScoredSortedSetRx 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 type of values + * @param name - name of scored sorted set + * @param codec - codec for values + * @return ScoredSortedSet object + */ + RScoredSortedSetRx 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 // */ // RDequeReactive 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 READ_COMMITTED 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. diff --git a/redisson/src/main/java/org/redisson/rx/RedissonListMultimapRx.java b/redisson/src/main/java/org/redisson/rx/RedissonListMultimapRx.java new file mode 100644 index 000000000..15ae461c3 --- /dev/null +++ b/redisson/src/main/java/org/redisson/rx/RedissonListMultimapRx.java @@ -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 key type + * @param value type + */ +public class RedissonListMultimapRx { + + private CommandRxExecutor commandExecutor; + private RedissonListMultimap instance; + + public RedissonListMultimapRx(CommandRxExecutor commandExecutor, String name) { + this.instance = new RedissonListMultimap(commandExecutor, name); + } + + public RedissonListMultimapRx(Codec codec, CommandRxExecutor commandExecutor, String name) { + this.instance = new RedissonListMultimap(codec, commandExecutor, name); + } + + public RListRx get(K key) { + RedissonList list = (RedissonList) ((RListMultimap)instance).get(key); + return RxProxyBuilder.create(commandExecutor, instance, + new RedissonListRx(list), RListRx.class); + } + +} diff --git a/redisson/src/main/java/org/redisson/rx/RedissonListRx.java b/redisson/src/main/java/org/redisson/rx/RedissonListRx.java new file mode 100644 index 000000000..24b8d2004 --- /dev/null +++ b/redisson/src/main/java/org/redisson/rx/RedissonListRx.java @@ -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 the type of elements held in this collection + */ +public class RedissonListRx { + + private final RedissonList instance; + + public RedissonListRx(RedissonList instance) { + this.instance = instance; + } + + public Publisher descendingIterator() { + return iterator(-1, false); + } + + public Publisher iterator() { + return iterator(0, true); + } + + public Publisher descendingIterator(int startIndex) { + return iterator(startIndex, false); + } + + public Publisher iterator(int startIndex) { + return iterator(startIndex, true); + } + + private Publisher iterator(final int startIndex, final boolean forward) { + final ReplayProcessor 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() { + @Override + public void operationComplete(Future 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 addAll(Publisher c) { + return new PublisherAdder() { + + @Override + public RFuture add(Object o) { + return instance.addAsync((V)o); + } + + }.addAll(c); + } + +} diff --git a/redisson/src/main/java/org/redisson/rx/RedissonReadWriteLockRx.java b/redisson/src/main/java/org/redisson/rx/RedissonReadWriteLockRx.java new file mode 100644 index 000000000..bdacc0c66 --- /dev/null +++ b/redisson/src/main/java/org/redisson/rx/RedissonReadWriteLockRx.java @@ -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); + } + + +} diff --git a/redisson/src/main/java/org/redisson/rx/RedissonScoredSortedSetRx.java b/redisson/src/main/java/org/redisson/rx/RedissonScoredSortedSetRx.java new file mode 100644 index 000000000..ad06baff7 --- /dev/null +++ b/redisson/src/main/java/org/redisson/rx/RedissonScoredSortedSetRx.java @@ -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 value type + */ +public class RedissonScoredSortedSetRx { + + private final RScoredSortedSetAsync instance; + + public RedissonScoredSortedSetRx(RScoredSortedSetAsync instance) { + this.instance = instance; + } + + private Flowable scanIteratorReactive(final String pattern, final int count) { + return new SetRxIterator() { + @Override + protected RFuture> scanIterator(final RedisClient client, final long nextIterPos) { + return ((RedissonScoredSortedSet)instance).scanIteratorAsync(client, nextIterPos, pattern, count); + } + }.create(); + } + + public String getName() { + return ((RedissonScoredSortedSet)instance).getName(); + } + + public Publisher iterator() { + return scanIteratorReactive(null, 10); + } + + public Publisher iterator(String pattern) { + return scanIteratorReactive(pattern, 10); + } + + public Publisher iterator(int count) { + return scanIteratorReactive(null, count); + } + + public Publisher iterator(String pattern, int count) { + return scanIteratorReactive(pattern, count); + } + +} diff --git a/redisson/src/main/java/org/redisson/rx/RedissonSetCacheRx.java b/redisson/src/main/java/org/redisson/rx/RedissonSetCacheRx.java new file mode 100644 index 000000000..d5ba58e5e --- /dev/null +++ b/redisson/src/main/java/org/redisson/rx/RedissonSetCacheRx.java @@ -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 value + */ +public class RedissonSetCacheRx { + + private final RSetCache instance; + + public RedissonSetCacheRx(RSetCache instance) { + this.instance = instance; + } + + public Publisher iterator() { + return new SetRxIterator() { + @Override + protected RFuture> scanIterator(RedisClient client, long nextIterPos) { + return ((ScanIterator)instance).scanIteratorAsync(instance.getName(), client, nextIterPos, null, 10); + } + }.create(); + } + + public Publisher addAll(Publisher c) { + return new PublisherAdder() { + @Override + public RFuture add(Object o) { + return instance.addAsync((V)o); + } + }.addAll(c); + } + +} diff --git a/redisson/src/main/java/org/redisson/rx/RedissonSetMultimapRx.java b/redisson/src/main/java/org/redisson/rx/RedissonSetMultimapRx.java new file mode 100644 index 000000000..dfb8b33fc --- /dev/null +++ b/redisson/src/main/java/org/redisson/rx/RedissonSetMultimapRx.java @@ -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 key type + * @param value type + */ +public class RedissonSetMultimapRx { + + private CommandRxExecutor commandExecutor; + private RedissonListMultimap instance; + + public RedissonSetMultimapRx(CommandRxExecutor commandExecutor, String name) { + this.instance = new RedissonListMultimap(commandExecutor, name); + } + + public RedissonSetMultimapRx(Codec codec, CommandRxExecutor commandExecutor, String name) { + this.instance = new RedissonListMultimap(codec, commandExecutor, name); + } + + public RSetReactive get(K key) { + RedissonSet set = (RedissonSet) ((RSetMultimap)instance).get(key); + return RxProxyBuilder.create(commandExecutor, set, + new RedissonSetRx(set), RSetReactive.class); + } + +} diff --git a/redisson/src/test/java/org/redisson/rx/RedissonListRxTest.java b/redisson/src/test/java/org/redisson/rx/RedissonListRxTest.java new file mode 100644 index 000000000..4d01f00ed --- /dev/null +++ b/redisson/src/test/java/org/redisson/rx/RedissonListRxTest.java @@ -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 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 test2 = redisson.getList("test2"); + sync(test2.add("foo")); + sync(test2.add(0, "bar")); + + assertThat(sync(test2)).containsExactly("bar", "foo"); + } + + @Test + public void testAddAllReactive() { + RListRx 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 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 list = redisson.getList("list"); + final CountDownLatch latch = new CountDownLatch(1); + list.addAll(Arrays.asList(1L, 2L, 3L)).subscribe(new Promise() { + + @Override + public void onNext(Boolean element) { + list.addAll(Arrays.asList(1L, 24L, 3L)).subscribe(new Promise() { + @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 list = redisson.getList("list"); + final CountDownLatch latch = new CountDownLatch(1); + list.add(1L).subscribe(new Promise() { + @Override + public void onNext(Boolean value) { + list.add(2L).subscribe(new Promise() { + @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 list = redisson.getList("list"); + sync(list.add(1L)); + sync(list.add(2L)); + + assertThat(sync(list)).containsExactly(1L, 2L); + } + + @Test + public void testListIteratorIndex() { + RListRx 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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.emptyList()))); + Assert.assertEquals(0, sync(list.size()).intValue()); + } + + @Test + public void testRetainAllNoModify() { + RListRx 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 list = redisson.getList("list"); + sync(list.addAll(2, Arrays.asList(7, 8, 9))); + } + + @Test + public void testAddAllIndex() { + RListRx 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 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 list = redisson.getList("list"); + Assert.assertEquals(false, sync(list.addAll(Collections.emptyList()))); + Assert.assertEquals(0, sync(list.size()).intValue()); + } + + @Test + public void testContainsAll() { + RListRx 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 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 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 list) { + int iteration = 0; + for (Iterator 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 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 list = redisson.getList("list"); +// +// sync(list.get(0)); +// } + + @Test + public void testAddGet() { + RListRx 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 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 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 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"); + } +} diff --git a/redisson/src/test/java/org/redisson/rx/RedissonScoredSortedSetRxTest.java b/redisson/src/test/java/org/redisson/rx/RedissonScoredSortedSetRxTest.java new file mode 100644 index 000000000..a92581927 --- /dev/null +++ b/redisson/src/test/java/org/redisson/rx/RedissonScoredSortedSetRxTest.java @@ -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 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 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 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 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 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 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 set = redisson.getScoredSortedSet("simple"); + sync(set.add(1, "1")); + sync(set.add(2, "4")); + + Iterator iter = toIterator(set.iterator()); + Assert.assertEquals("1", iter.next()); + Assert.assertEquals("4", iter.next()); + Assert.assertFalse(iter.hasNext()); + } + + @Test + public void testIteratorSequence() { + RScoredSortedSetRx set = redisson.getScoredSortedSet("simple"); + for (int i = 0; i < 1000; i++) { + sync(set.add(i, Integer.valueOf(i))); + } + + Set setCopy = new HashSet(); + for (int i = 0; i < 1000; i++) { + setCopy.add(Integer.valueOf(i)); + } + + checkIterator(set, setCopy); + } + + private void checkIterator(RScoredSortedSetRx set, Set setCopy) { + for (Iterator 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 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 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 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 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 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 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 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 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 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 vals = sync(set.valueRange(0, -1)); + assertThat(sync(set)).containsExactly(1, 2, 3, 4, 5); + } + + @Test + public void testEntryRange() { + RScoredSortedSetRx 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> vals = sync(set.entryRange(0, -1)); + assertThat(vals).contains(new ScoredEntry(10D, 1), + new ScoredEntry(20D, 2), + new ScoredEntry(30D, 3), + new ScoredEntry(40D, 4), + new ScoredEntry(50D, 5)); + } + + @Test + public void testScoredSortedSetValueRange() { + RScoredSortedSetRx set = redisson.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 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 set = redisson.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> r = sync(set.entryRange(1, true, 4, false, 1, 2)); + ScoredEntry[] 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 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 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); + } + +}