Merge branch 'master' into 3.0.0

# Conflicts:
#	pom.xml
#	redisson-all/pom.xml
#	redisson-tomcat/pom.xml
#	redisson-tomcat/redisson-tomcat-6/pom.xml
#	redisson-tomcat/redisson-tomcat-7/pom.xml
#	redisson-tomcat/redisson-tomcat-8/pom.xml
#	redisson-tomcat/redisson-tomcat-9/pom.xml
#	redisson/pom.xml
#	redisson/src/test/java/org/redisson/RedissonMapTest.java
pull/1303/head
Nikita 7 years ago
commit a74bac17cc

@ -4,6 +4,34 @@ Redisson Releases History
Try __[Redisson PRO](https://redisson.pro)__ version.
### 29-Jan-2018 - versions 2.11.0 and 3.6.0 released
Feature - __`atomic` setting added to RBatch object__ Please read [documentation](https://github.com/redisson/redisson/wiki/10.-additional-features#103-execution-batches-of-commands) for more details
Feature - __`updateMode` setting added to Tomcat Redis Session Manager__ Please read [documentation](https://github.com/redisson/redisson/wiki/14.-Integration-with-frameworks#145-tomcat-redis-session-manager) for more details
Feature - __`RateLimiter` object added__ Please read [documentation](https://github.com/redisson/redisson/wiki/6.-distributed-objects/#612-ratelimiter) for more details
Feature - __`RClusteredBloomFilter` object added__ Please read [documentation](https://github.com/redisson/redisson/wiki/6.-Distributed-objects#681-bloom-filter-data-partitioning) for more details
Feature - __`KQueue` support added__ Please read [documentation](https://github.com/redisson/redisson/wiki/2.-Configuration#eventloopgroup) for more details
Feature - __`Tomcat 9` support added__ Please read [documentation](https://github.com/redisson/redisson/wiki/14.-Integration-with-frameworks#145-tomcat-redis-session-manager) for more details
Feature - __`RPriorityBlockingQueue` object added__ Please read [documentation](https://github.com/redisson/redisson/wiki/7.-distributed-collections/#718-priority-blocking-queue) for more details
Feature - __`RPriorityBlockingDeque` object added__ Please read [documentation](https://github.com/redisson/redisson/wiki/7.-distributed-collections/#719-priority-blocking-deque) for more details
Feature - __`RLongAdder` object added__ Please read [documentation](https://github.com/redisson/redisson/wiki/6.-distributed-objects/#610-longadder) for more details
Feature - __`DoubleAdder` object added__ Please read [documentation](https://github.com/redisson/redisson/wiki/6.-distributed-objects/#611-doubleadder) for more details
Feature - `RBucket.getAndDelete`, `RAtomicLong.getAndDelete` and `RAtomicDouble.getAndDelete` methods added
Feature - __`RAtomicDoubleReactive` object added__
Feature - `RPriorityQueue.pollLastAndOfferFirstTo` method added
Improvement - support single config endpoint node for cluster mode
Improvement - hash functions replaced with https://github.com/google/highwayhash
Fixed - JDK 1.6+ compatibility for RemoteService
Fixed - `setDnsMonitoringInterval(-1)` doesn't disable DNS monitoring
Fixed - `RLocalCachedMap.putAll` gets stuck if map passed as parameter contains > 10000 elements
Fixed - `RLocalCachedMap.put` value encoding
Fixed - `RKeys.countExists` and `RKeys.touch` return wrong result in cluster mode
Fixed - Wrong parsing of RScript.ReturnType.MULTI result
Fixed - RedissonReadLock by name with colon couldn't be unlocked properly
Fixed - `rg.springframework.cache.Cache$ValueRetrievalException`shouldn't be wrapped by IllegalStateException
Fixed - `RMapCache` listeners are not working on cross-platform environment
Fixed - JsonJacksonCoded shouldn't override provided objectMapper settings (thanks to @gzeskas)
### 25-Dec-2017 - versions 2.10.7 and 3.5.7 released
Feature - __`RClusteredBitSet` object added__ Please read [documentation](https://github.com/redisson/redisson/wiki/6.-Distributed-objects/#641-bitset-data-partitioning) for more details

@ -1,13 +1,13 @@
Redisson: Redis based In-Memory Data Grid for Java.
====
[Quick start](https://github.com/redisson/redisson#quick-start) | [Documentation](https://github.com/redisson/redisson/wiki) | [Javadocs](http://www.javadoc.io/doc/org.redisson/redisson/3.5.6) | [Changelog](https://github.com/redisson/redisson/blob/master/CHANGELOG.md) | [Code examples](https://github.com/redisson/redisson-examples) | [Support chat](https://gitter.im/mrniko/redisson) | **[PRO version](https://redisson.pro)**
[Quick start](https://github.com/redisson/redisson#quick-start) | [Documentation](https://github.com/redisson/redisson/wiki) | [Javadocs](http://www.javadoc.io/doc/org.redisson/redisson/3.5.7) | [Changelog](https://github.com/redisson/redisson/blob/master/CHANGELOG.md) | [Code examples](https://github.com/redisson/redisson-examples) | [Support chat](https://gitter.im/mrniko/redisson) | **[PRO version](https://redisson.pro)**
Based on high-performance async and lock-free Java Redis client and [Netty](http://netty.io) framework.
| Stable <br/> Release Version | Release Date | JDK Version<br/> compatibility | `CompletionStage` <br/> support | `ProjectReactor` version<br/> compatibility |
| ------------- | ------------- | ------------| -----------| -----------|
| 3.5.7 | 25.12.2017 | 1.8+ | Yes | 3.1.x |
| 2.10.7 | 25.12.2017 | 1.6, 1.7, 1.8 and Android | No | 2.0.8 |
| 3.6.0 | 29.01.2018 | 1.8+ | Yes | 3.1.x |
| 2.11.0 | 29.01.2018 | 1.6, 1.7, 1.8 and Android | No | 2.0.8 |
Features
@ -87,23 +87,23 @@ Quick start
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.5.7</version>
<version>3.6.0</version>
</dependency>
<!-- JDK 1.6+ compatible -->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>2.10.7</version>
<version>2.11.0</version>
</dependency>
#### Gradle
// JDK 1.8+ compatible
compile 'org.redisson:redisson:3.5.7'
compile 'org.redisson:redisson:3.6.0'
// JDK 1.6+ compatible
compile 'org.redisson:redisson:2.10.7'
compile 'org.redisson:redisson:2.11.0'
#### Java
@ -128,11 +128,11 @@ RExecutorService executor = redisson.getExecutorService("myExecutorService");
Downloads
===============================
[Redisson 3.5.7](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson&v=3.5.7&e=jar),
[Redisson node 3.5.7](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-all&v=3.5.7&e=jar)
[Redisson 3.6.0](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson&v=3.6.0&e=jar),
[Redisson node 3.6.0](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-all&v=3.6.0&e=jar)
[Redisson 2.10.7](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson&v=2.10.7&e=jar),
[Redisson node 2.10.7](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-all&v=2.10.7&e=jar)
[Redisson 2.11.0](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson&v=2.11.0&e=jar),
[Redisson node 2.11.0](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-all&v=2.11.0&e=jar)
### Supported by

@ -216,7 +216,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.4</version>
<version>3.0.0</version>
<executions>
<execution>
<phase>package</phase>

@ -17,34 +17,39 @@ Usage
```xml
<Manager className="org.redisson.tomcat.RedissonSessionManager"
configPath="${catalina.base}/redisson.conf" />
configPath="${catalina.base}/redisson.conf" readMode="MEMORY" updateMode="DEFAULT"/>
```
`readMode` - read attributes mode. Two modes are available: `MEMORY` and `REDIS`.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`MEMORY` - read attributes stored in local Tomcat Session.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`REDIS` - read directly from Redis.
`readMode` - read attributes mode. Two modes are available:
* `MEMORY` - read attributes stored in local Tomcat Session. Default mode.
* `REDIS` - read directly from Redis.
`updateMode` - attributes update mode. Two modes are available:
* `DEFAULT` - session attributes are stored into Redis only through setAttribute method. Default mode.
* `AFTER_REQUEST` - all session attributes are stored into Redis after each request.
`configPath` - path to Redisson JSON or YAML config. See [configuration wiki page](https://github.com/redisson/redisson/wiki/2.-Configuration) for more details.
**2** Copy two jars into `TOMCAT_BASE/lib` directory:
1. __For JDK 1.8+__
[redisson-all-3.5.6.jar](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-all&v=3.5.6&e=jar)
[redisson-all-3.6.0.jar](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-all&v=3.6.0&e=jar)
for Tomcat 6.x
[redisson-tomcat-6-3.5.6.jar](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-tomcat-6&v=3.5.6&e=jar)
[redisson-tomcat-6-3.6.0.jar](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-tomcat-6&v=3.6.0&e=jar)
for Tomcat 7.x
[redisson-tomcat-7-3.5.6.jar](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-tomcat-7&v=3.5.6&e=jar)
[redisson-tomcat-7-3.6.0.jar](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-tomcat-7&v=3.6.0&e=jar)
for Tomcat 8.x
[redisson-tomcat-8-3.5.6.jar](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-tomcat-8&v=3.5.6&e=jar)
[redisson-tomcat-8-3.6.0.jar](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-tomcat-8&v=3.6.0&e=jar)
for Tomcat 9.x
[redisson-tomcat-9-3.6.0.jar](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-tomcat-9&v=3.6.0&e=jar)
2. __For JDK 1.6+__
[redisson-all-2.10.6.jar](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-all&v=2.10.6&e=jar)
[redisson-all-2.11.0.jar](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-all&v=2.11.0&e=jar)
for Tomcat 6.x
[redisson-tomcat-6-2.10.6.jar](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-tomcat-6&v=2.10.6&e=jar)
[redisson-tomcat-6-2.11.0.jar](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-tomcat-6&v=2.11.0&e=jar)
for Tomcat 7.x
[redisson-tomcat-7-2.10.6.jar](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-tomcat-7&v=2.10.6&e=jar)
[redisson-tomcat-7-2.11.0.jar](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-tomcat-7&v=2.11.0&e=jar)

@ -50,7 +50,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.4</version>
<version>3.0.0</version>
<executions>
<execution>
<id>attach-javadocs</id>

@ -305,7 +305,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.4</version>
<version>3.0.0</version>
<executions>
<execution>
<id>attach-javadocs</id>

@ -30,11 +30,16 @@ import org.redisson.api.RFuture;
import org.redisson.client.codec.Codec;
import org.redisson.client.codec.DelegateDecoderCodec;
import org.redisson.client.protocol.RedisCommand;
import org.redisson.client.protocol.RedisCommand.ValueType;
import org.redisson.client.protocol.RedisCommands;
import org.redisson.command.CommandExecutor;
import org.redisson.connection.decoder.MapGetAllDecoder;
import org.redisson.misc.RedissonPromise;
/**
*
* @author Nikita Koksharov
*
*/
public class RedissonBuckets implements RBuckets {
private final Codec codec;
@ -67,19 +72,36 @@ public class RedissonBuckets implements RBuckets {
@Override
public <V> Map<String, V> get(String... keys) {
RFuture<Map<String, V>> future = getAsync(keys);
return commandExecutor.get(future);
}
@Override
public boolean trySet(Map<String, ?> buckets) {
RFuture<Boolean> future = trySetAsync(buckets);
return commandExecutor.get(future);
}
@Override
public void set(Map<String, ?> buckets) {
commandExecutor.get(setAsync(buckets));
}
@Override
public <V> RFuture<Map<String, V>> getAsync(String... keys) {
if (keys.length == 0) {
return Collections.emptyMap();
Map<String, V> emptyMap = Collections.emptyMap();
return RedissonPromise.<Map<String, V>>newSucceededFuture(emptyMap);
}
RedisCommand<Map<Object, Object>> command = new RedisCommand<Map<Object, Object>>("MGET", new MapGetAllDecoder(Arrays.<Object>asList(keys), 0));
RFuture<Map<String, V>> future = commandExecutor.readAsync(keys[0], new DelegateDecoderCodec(codec), command, keys);
return commandExecutor.get(future);
return commandExecutor.readAsync(keys[0], new DelegateDecoderCodec(codec), command, keys);
}
@Override
public boolean trySet(Map<String, ?> buckets) {
public RFuture<Boolean> trySetAsync(Map<String, ?> buckets) {
if (buckets.isEmpty()) {
return false;
return RedissonPromise.newSucceededFuture(false);
}
List<Object> params = new ArrayList<Object>(buckets.size());
@ -92,13 +114,13 @@ public class RedissonBuckets implements RBuckets {
}
}
return commandExecutor.write(params.get(0).toString(), RedisCommands.MSETNX, params.toArray());
return commandExecutor.writeAsync(params.get(0).toString(), RedisCommands.MSETNX, params.toArray());
}
@Override
public void set(Map<String, ?> buckets) {
public RFuture<Void> setAsync(Map<String, ?> buckets) {
if (buckets.isEmpty()) {
return;
return RedissonPromise.newSucceededFuture(null);
}
List<Object> params = new ArrayList<Object>(buckets.size());
@ -111,7 +133,7 @@ public class RedissonBuckets implements RBuckets {
}
}
commandExecutor.write(params.get(0).toString(), RedisCommands.MSET, params.toArray());
return commandExecutor.writeAsync(params.get(0).toString(), RedisCommands.MSET, params.toArray());
}
}

@ -149,6 +149,82 @@ public class RedissonLexSortedSet extends RedissonScoredSortedSet<String> implem
return commandExecutor.readAsync(getName(), StringCodec.INSTANCE, RedisCommands.ZRANGEBYLEX, getName(), fromValue, toValue, "LIMIT", offset, count);
}
@Override
public Collection<String> rangeTailReversed(String fromElement, boolean fromInclusive) {
return get(rangeTailReversedAsync(fromElement, fromInclusive));
}
@Override
public Collection<String> rangeHeadReversed(String toElement, boolean toInclusive) {
return get(rangeHeadReversedAsync(toElement, toInclusive));
}
@Override
public Collection<String> rangeReversed(String fromElement, boolean fromInclusive, String toElement,
boolean toInclusive) {
return get(rangeReversedAsync(fromElement, fromInclusive, toElement, toInclusive));
}
@Override
public Collection<String> rangeTailReversed(String fromElement, boolean fromInclusive, int offset, int count) {
return get(rangeTailReversedAsync(fromElement, fromInclusive, offset, count));
}
@Override
public Collection<String> rangeHeadReversed(String toElement, boolean toInclusive, int offset, int count) {
return get(rangeHeadReversedAsync(toElement, toInclusive, offset, count));
}
@Override
public Collection<String> rangeReversed(String fromElement, boolean fromInclusive, String toElement,
boolean toInclusive, int offset, int count) {
return get(rangeReversedAsync(fromElement, fromInclusive, toElement, toInclusive, offset, count));
}
@Override
public RFuture<Collection<String>> rangeTailReversedAsync(String fromElement, boolean fromInclusive) {
String fromValue = value(fromElement, fromInclusive);
return commandExecutor.readAsync(getName(), StringCodec.INSTANCE, RedisCommands.ZREVRANGEBYLEX, getName(), "+", fromValue);
}
@Override
public RFuture<Collection<String>> rangeHeadReversedAsync(String toElement, boolean toInclusive) {
String toValue = value(toElement, toInclusive);
return commandExecutor.readAsync(getName(), StringCodec.INSTANCE, RedisCommands.ZREVRANGEBYLEX, getName(), toValue, "-");
}
@Override
public RFuture<Collection<String>> rangeReversedAsync(String fromElement, boolean fromInclusive, String toElement,
boolean toInclusive) {
String fromValue = value(fromElement, fromInclusive);
String toValue = value(toElement, toInclusive);
return commandExecutor.readAsync(getName(), StringCodec.INSTANCE, RedisCommands.ZREVRANGEBYLEX, getName(), toValue, fromValue);
}
@Override
public RFuture<Collection<String>> rangeTailReversedAsync(String fromElement, boolean fromInclusive, int offset,
int count) {
String fromValue = value(fromElement, fromInclusive);
return commandExecutor.readAsync(getName(), StringCodec.INSTANCE, RedisCommands.ZREVRANGEBYLEX, getName(), "+", fromValue, "LIMIT", offset, count);
}
@Override
public RFuture<Collection<String>> rangeHeadReversedAsync(String toElement, boolean toInclusive, int offset,
int count) {
String toValue = value(toElement, toInclusive);
return commandExecutor.readAsync(getName(), StringCodec.INSTANCE, RedisCommands.ZREVRANGEBYLEX, getName(), toValue, "-", "LIMIT", offset, count);
}
@Override
public RFuture<Collection<String>> rangeReversedAsync(String fromElement, boolean fromInclusive, String toElement,
boolean toInclusive, int offset, int count) {
String fromValue = value(fromElement, fromInclusive);
String toValue = value(toElement, toInclusive);
return commandExecutor.readAsync(getName(), StringCodec.INSTANCE, RedisCommands.ZREVRANGEBYLEX, getName(), toValue, fromValue, "LIMIT", offset, count);
}
@Override
public int countTail(String fromElement, boolean fromInclusive) {
return get(countTailAsync(fromElement, fromInclusive));

@ -18,9 +18,7 @@ package org.redisson;
import java.io.IOException;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.AbstractCollection;
import java.util.AbstractMap;
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@ -29,7 +27,6 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@ -680,266 +677,6 @@ public class RedissonLocalCachedMap<K, V> extends RedissonMap<K, V> implements R
msgEncoded, invalidateEntryOnChange);
}
@Override
public Set<K> keySet(String pattern) {
return new KeySet(pattern);
}
@Override
public Collection<V> values(String keyPattern) {
return new Values(keyPattern);
}
@Override
public Set<java.util.Map.Entry<K, V>> entrySet(String keyPattern) {
return new EntrySet(keyPattern);
}
private Iterator<Map.Entry<K,V>> cacheEntrySetIterator() {
final Iterator<Map.Entry<CacheKey, CacheValue>> iter = cache.entrySet().iterator();
return new Iterator<Map.Entry<K,V>>() {
@Override
public boolean hasNext() {
return iter.hasNext();
}
@Override
public java.util.Map.Entry<K, V> next() {
Map.Entry<CacheKey, CacheValue> entry = iter.next();
return new AbstractMap.SimpleEntry(entry.getValue().getKey(), entry.getValue().getValue());
}
@Override
public void remove() {
iter.remove();
}
};
}
private Iterator<K> cacheKeySetIterator() {
final Iterator<CacheValue> iter = cache.values().iterator();
return new Iterator<K>() {
@Override
public boolean hasNext() {
return iter.hasNext();
}
@Override
public K next() {
CacheValue value = iter.next();
return (K) value.getKey();
}
@Override
public void remove() {
iter.remove();
}
};
}
final class KeySet extends AbstractSet<K> {
private final String pattern;
public KeySet(String pattern) {
this.pattern = pattern;
}
@Override
public Iterator<K> iterator() {
return new CompositeIterable<K>(cacheKeySetIterator(), RedissonLocalCachedMap.super.keySet(pattern).iterator()) {
@Override
boolean isCacheContains(Object object) {
CacheKey cacheKey = toCacheKey(object);
return cache.containsKey(cacheKey);
}
};
}
@Override
public boolean contains(Object o) {
return RedissonLocalCachedMap.this.containsKey(o);
}
@Override
public boolean remove(Object o) {
return RedissonLocalCachedMap.this.remove(o) != null;
}
@Override
public int size() {
return RedissonLocalCachedMap.this.size();
}
@Override
public void clear() {
RedissonLocalCachedMap.this.clear();
}
}
final class Values extends AbstractCollection<V> {
private final String keyPattern;
public Values(String keyPattern) {
this.keyPattern = keyPattern;
}
@Override
public Iterator<V> iterator() {
final Iterator<Map.Entry<K, V>> iter = RedissonLocalCachedMap.this.entrySet(keyPattern).iterator();
return new Iterator<V>() {
@Override
public boolean hasNext() {
return iter.hasNext();
}
@Override
public V next() {
return iter.next().getValue();
}
@Override
public void remove() {
iter.remove();
}
};
}
@Override
public boolean contains(Object o) {
return RedissonLocalCachedMap.this.containsValue(o);
}
@Override
public int size() {
return RedissonLocalCachedMap.this.size();
}
@Override
public void clear() {
RedissonLocalCachedMap.this.clear();
}
}
final class EntrySet extends AbstractSet<Map.Entry<K,V>> {
private final String keyPattern;
public EntrySet(String keyPattern) {
this.keyPattern = keyPattern;
}
public final Iterator<Map.Entry<K,V>> iterator() {
return new CompositeIterable<Map.Entry<K,V>>(cacheEntrySetIterator(), RedissonLocalCachedMap.super.entrySet(keyPattern).iterator()) {
@Override
boolean isCacheContains(Map.Entry<K,V> entry) {
CacheKey cacheKey = toCacheKey(entry.getKey());
return cache.containsKey(cacheKey);
}
};
}
public final boolean contains(Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry<?,?> e = (Map.Entry<?,?>) o;
Object key = e.getKey();
V value = get(key);
return value != null && value.equals(e);
}
public final boolean remove(Object o) {
if (o instanceof Map.Entry) {
Map.Entry<?,?> e = (Map.Entry<?,?>) o;
Object key = e.getKey();
Object value = e.getValue();
return RedissonLocalCachedMap.super.remove(key, value);
}
return false;
}
public final int size() {
return RedissonLocalCachedMap.this.size();
}
public final void clear() {
RedissonLocalCachedMap.this.clear();
}
}
abstract class CompositeIterable<T> implements Iterator<T> {
private T currentObject;
private Iterator<T> cacheIterator;
private Iterator<T> mapIterator;
public CompositeIterable(Iterator<T> cacheIterator, Iterator<T> mapIterator) {
this.cacheIterator = cacheIterator;
this.mapIterator = mapIterator;
}
@Override
public boolean hasNext() {
if (!cacheIterator.hasNext()) {
while (true) {
if (mapIterator.hasNext()) {
currentObject = mapIterator.next();
if (!isCacheContains(currentObject)) {
return true;
}
} else {
break;
}
}
return false;
}
return true;
}
abstract boolean isCacheContains(T object);
@Override
public T next() {
if (currentObject != null) {
T val = currentObject;
currentObject = null;
return val;
}
if (!hasNext()) {
throw new NoSuchElementException();
}
return cacheIterator.next();
}
@Override
public void remove() {
if (currentObject != null) {
mapIterator.remove();
currentObject = null;
return;
}
cacheIterator.remove();
}
}
@Override
public RFuture<Map<K, V>> getAllAsync(Set<K> keys) {
final Map<K, V> result = new HashMap<K, V>();
@ -1339,8 +1076,7 @@ public class RedissonLocalCachedMap<K, V> extends RedissonMap<K, V> implements R
@Override
public RFuture<Boolean> replaceAsync(final K key, V oldValue, final V newValue) {
final ByteBuf keyState = encodeMapKey(key);
final CacheKey cacheKey = toCacheKey(keyState);
final CacheKey cacheKey = toCacheKey(key);
RFuture<Boolean> future = super.replaceAsync(key, oldValue, newValue);
future.addListener(new FutureListener<Boolean>() {
@ -1386,8 +1122,7 @@ public class RedissonLocalCachedMap<K, V> extends RedissonMap<K, V> implements R
@Override
public RFuture<Boolean> removeAsync(Object key, Object value) {
final ByteBuf keyState = encodeMapKey(key);
final CacheKey cacheKey = toCacheKey(keyState);
final CacheKey cacheKey = toCacheKey(key);
RFuture<Boolean> future = super.removeAsync(key, value);
future.addListener(new FutureListener<Boolean>() {

@ -151,8 +151,6 @@ public class RedissonMapCache<K, V> extends RedissonMap<K, V> implements RMapCac
" local expireIdle = redis.call('zscore', KEYS[3], ARGV[2]); " +
" if expireIdle ~= false then " +
" if tonumber(expireIdle) > tonumber(ARGV[1]) then " +
" local value = struct.pack('dLc0', t, string.len(val), val); " +
" redis.call('hset', KEYS[1], ARGV[2], value); " +
" redis.call('zadd', KEYS[3], t + tonumber(ARGV[1]), ARGV[2]); " +
" end ;" +
" expireDate = math.min(expireDate, tonumber(expireIdle)) " +
@ -194,8 +192,6 @@ public class RedissonMapCache<K, V> extends RedissonMap<K, V> implements RMapCac
" local expireIdle = redis.call('zscore', KEYS[3], key); " +
" if expireIdle ~= false then " +
" if tonumber(expireIdle) > tonumber(ARGV[1]) then " +
" local value = struct.pack('dLc0', t, string.len(val), val); " +
" redis.call('hset', KEYS[1], key, value); " +
" redis.call('zadd', KEYS[3], t + tonumber(ARGV[1]), key); " +
" end; " +
" expireDate = math.min(expireDate, tonumber(expireIdle)) " +
@ -250,8 +246,6 @@ public class RedissonMapCache<K, V> extends RedissonMap<K, V> implements RMapCac
" local expireIdle = redis.call('zscore', KEYS[3], key); " +
" if expireIdle ~= false then " +
" if tonumber(expireIdle) > currentTime then " +
" local value = struct.pack('dLc0', t, string.len(val), val); " +
" redis.call('hset', KEYS[1], key, value); " +
" redis.call('zadd', KEYS[3], t + currentTime, key); " +
" else " +
" map[i] = false; " +
@ -472,8 +466,6 @@ public class RedissonMapCache<K, V> extends RedissonMap<K, V> implements RMapCac
+ "local expireIdle = redis.call('zscore', KEYS[3], ARGV[2]); "
+ "if expireIdle ~= false then "
+ "if tonumber(expireIdle) > tonumber(ARGV[1]) then "
+ "local value = struct.pack('dLc0', t, string.len(val), val); "
+ "redis.call('hset', KEYS[1], ARGV[2], value); "
+ "redis.call('zadd', KEYS[3], t + tonumber(ARGV[1]), ARGV[2]); "
+ "end; "
+ "expireDate = math.min(expireDate, tonumber(expireIdle)) "
@ -646,8 +638,6 @@ public class RedissonMapCache<K, V> extends RedissonMap<K, V> implements RMapCac
+ "local expireIdle = redis.call('zscore', KEYS[3], ARGV[2]); "
+ "if expireIdle ~= false then "
+ "if tonumber(expireIdle) > tonumber(ARGV[1]) then "
+ "local value = struct.pack('dLc0', t, string.len(val), val); "
+ "redis.call('hset', KEYS[1], ARGV[2], value); "
+ "redis.call('zadd', KEYS[3], t + tonumber(ARGV[1]), ARGV[2]); "
+ "end; "
+ "expireDate = math.min(expireDate, tonumber(expireIdle)) "
@ -665,7 +655,7 @@ public class RedissonMapCache<K, V> extends RedissonMap<K, V> implements RMapCac
+ "local msg = struct.pack('Lc0Lc0', string.len(ARGV[2]), ARGV[2], string.len(ARGV[3]), ARGV[3]); "
+ "redis.call('publish', KEYS[4], msg); "
+ "end; "
+ "local newValuePack = struct.pack('dLc0', t + tonumber(ARGV[1]), string.len(newValue), newValue); "
+ "local newValuePack = struct.pack('dLc0', t, string.len(newValue), newValue); "
+ "redis.call('hset', KEYS[1], ARGV[2], newValuePack); "
// last access time
@ -1250,8 +1240,6 @@ public class RedissonMapCache<K, V> extends RedissonMap<K, V> implements RMapCac
+ "local expireIdle = redis.call('zscore', KEYS[2], key); "
+ "if expireIdle ~= false then "
+ "if tonumber(expireIdle) > currentTime then "
+ "local value = struct.pack('dLc0', t, string.len(val), val); "
+ "redis.call('hset', KEYS[1], key, value); "
+ "redis.call('zadd', KEYS[2], t + currentTime, key); "
+ "end; "
+ "end; "
@ -1386,8 +1374,6 @@ public class RedissonMapCache<K, V> extends RedissonMap<K, V> implements RMapCac
+ "local expireIdle = redis.call('zscore', KEYS[3], ARGV[2]); "
+ "if expireIdle ~= false then "
+ "if tonumber(expireIdle) > tonumber(ARGV[1]) then "
+ "local value = struct.pack('dLc0', t, string.len(val), val); "
+ "redis.call('hset', KEYS[1], ARGV[2], value); "
+ "redis.call('zadd', KEYS[3], t + tonumber(ARGV[1]), ARGV[2]); "
+ "end; "
+ "expireDate = math.min(expireDate, tonumber(expireIdle)) "
@ -1850,8 +1836,6 @@ public class RedissonMapCache<K, V> extends RedissonMap<K, V> implements RMapCac
+ "local expireIdle = redis.call('zscore', KEYS[3], key); "
+ "if expireIdle ~= false then "
+ "if tonumber(expireIdle) > tonumber(ARGV[1]) then "
+ "local value = struct.pack('dLc0', t, string.len(val), val); "
+ "redis.call('hset', KEYS[1], key, value); "
+ "redis.call('zadd', KEYS[3], t + tonumber(ARGV[1]), key); "
+ "if maxSize ~= nil and maxSize ~= 0 then "
+ " redis.call('zadd', KEYS[4], tonumber(ARGV[1]), key); "
@ -1893,8 +1877,6 @@ public class RedissonMapCache<K, V> extends RedissonMap<K, V> implements RMapCac
+ "local expireIdle = redis.call('zscore', KEYS[3], key); "
+ "if expireIdle ~= false then "
+ "if tonumber(expireIdle) > tonumber(ARGV[1]) then "
+ "local value = struct.pack('dLc0', t, string.len(val), val); "
+ "redis.call('hset', KEYS[1], key, value); "
+ "redis.call('zadd', KEYS[3], t + tonumber(ARGV[1]), key); "
+ "if maxSize ~= nil and maxSize ~= 0 then "
+ " redis.call('zadd', KEYS[4], tonumber(ARGV[1]), key); "
@ -1939,8 +1921,6 @@ public class RedissonMapCache<K, V> extends RedissonMap<K, V> implements RMapCac
+ "local expireIdle = redis.call('zscore', KEYS[3], key); "
+ "if expireIdle ~= false then "
+ "if tonumber(expireIdle) > tonumber(ARGV[1]) then "
+ "local value = struct.pack('dLc0', t, string.len(val), val); "
+ "redis.call('hset', KEYS[1], key, value); "
+ "redis.call('zadd', KEYS[3], t + tonumber(ARGV[1]), key); "
+ "if maxSize ~= nil and maxSize ~= 0 then "
+ " redis.call('zadd', KEYS[4], tonumber(ARGV[1]), key); "

@ -18,23 +18,17 @@ package org.redisson.api;
import java.util.List;
import java.util.Map;
public interface RBuckets {
/**
*
* @author Nikita Koksharov
*
*/
public interface RBuckets extends RBucketsAsync {
/**
* <p>Returns a list of object holder instances by a key pattern.
*
* <pre>Supported glob-style patterns:
* h?llo subscribes to hello, hallo and hxllo
* h*llo subscribes to hllo and heeeello
* h[ae]llo subscribes to hello and hallo, but not hillo
* h[^e]llo matches hallo, hbllo, ... but not hello
* h[a-b]llo matches hallo and hbllo</pre>
* <p>Use \ to escape special characters if you want to match them verbatim.
*
* @param <V> type of value
* @param pattern - pattern of key
* @return List of bucket objects
/*
* Use RKeys.findKeysByPattern method instead
*/
@Deprecated
<V> List<RBucket<V>> find(String pattern);
/**

@ -0,0 +1,54 @@
/**
* Copyright 2016 Nikita Koksharov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.redisson.api;
import java.util.Map;
/**
*
* @author Nikita Koksharov
*
*/
public interface RBucketsAsync {
/**
* Returns Redis object mapped by key. Result Map is not contains
* key-value entry for null values.
*
* @param <V> type of value
* @param keys - keys
* @return Map with name of bucket as key and bucket as value
*/
<V> RFuture<Map<String, V>> getAsync(String ... keys);
/**
* Try to save objects mapped by Redis key.
* If at least one of them is already exist then
* don't set none of them.
*
* @param buckets - map of buckets
* @return <code>true</code> if object has been set overwise <code>false</code>
*/
RFuture<Boolean> trySetAsync(Map<String, ?> buckets);
/**
* Saves objects mapped by Redis key.
*
* @param buckets - map of buckets
*/
RFuture<Void> setAsync(Map<String, ?> buckets);
}

@ -16,16 +16,36 @@
package org.redisson.api;
/**
* Live Object cascade type.
*
* @author Nikita Koksharov
*
*/
public enum RCascadeType {
/**
* Includes all cascade types.
*/
ALL,
/**
* Cascade persist operation during {@link RLiveObjectService#persist} method invocation.
*/
PERSIST,
/**
* Cascade detach operation during {@link RLiveObjectService#detach} method invocation.
*/
DETACH,
/**
* Cascade merge operation during {@link RLiveObjectService#merge} method invocation.
*/
MERGE,
/**
* Cascade delete operation during {@link RLiveObjectService#delete} method invocation.
*/
DELETE

@ -59,6 +59,18 @@ public interface RLexSortedSet extends RLexSortedSetAsync, RSortedSet<String>, R
Collection<String> range(String fromElement, boolean fromInclusive, String toElement, boolean toInclusive, int offset, int count);
Collection<String> rangeTailReversed(String fromElement, boolean fromInclusive);
Collection<String> rangeHeadReversed(String toElement, boolean toInclusive);
Collection<String> rangeReversed(String fromElement, boolean fromInclusive, String toElement, boolean toInclusive);
Collection<String> rangeTailReversed(String fromElement, boolean fromInclusive, int offset, int count);
Collection<String> rangeHeadReversed(String toElement, boolean toInclusive, int offset, int count);
Collection<String> rangeReversed(String fromElement, boolean fromInclusive, String toElement, boolean toInclusive, int offset, int count);
int count(String fromElement, boolean fromInclusive, String toElement, boolean toInclusive);
Integer rank(String o);

@ -61,6 +61,18 @@ public interface RLexSortedSetAsync extends RCollectionAsync<String> {
RFuture<Collection<String>> rangeHeadAsync(String toElement, boolean toInclusive, int offset, int count);
RFuture<Collection<String>> rangeAsync(String fromElement, boolean fromInclusive, String toElement, boolean toInclusive, int offset, int count);
RFuture<Collection<String>> rangeTailReversedAsync(String fromElement, boolean fromInclusive);
RFuture<Collection<String>> rangeHeadReversedAsync(String toElement, boolean toInclusive);
RFuture<Collection<String>> rangeReversedAsync(String fromElement, boolean fromInclusive, String toElement, boolean toInclusive);
RFuture<Collection<String>> rangeTailReversedAsync(String fromElement, boolean fromInclusive, int offset, int count);
RFuture<Collection<String>> rangeHeadReversedAsync(String toElement, boolean toInclusive, int offset, int count);
RFuture<Collection<String>> rangeReversedAsync(String fromElement, boolean fromInclusive, String toElement, boolean toInclusive, int offset, int count);
RFuture<Integer> countAsync(String fromElement, boolean fromInclusive, String toElement, boolean toInclusive);

@ -23,6 +23,7 @@ import java.lang.annotation.Target;
import org.redisson.api.RCascadeType;
/**
* Specifies that the defined cascade types are applied to the object/objects contained in Live Object field.
*
* @author Nikita Koksharov
*
@ -31,6 +32,11 @@ import org.redisson.api.RCascadeType;
@Target({ElementType.FIELD})
public @interface RCascade {
/**
* List of applied cascade types.
*
* @return value
*/
RCascadeType[] value();
}

@ -25,6 +25,7 @@ import org.redisson.client.codec.Codec;
import org.redisson.codec.JsonJacksonCodec;
/**
* Specifies that the class is a Live Object.
*
* @author Rui Gu (https://github.com/jackygurui)
*/
@ -33,13 +34,34 @@ import org.redisson.codec.JsonJacksonCodec;
public @interface REntity {
public enum TransformationMode {
IMPLEMENTATION_BASED, ANNOTATION_BASED
IMPLEMENTATION_BASED,
ANNOTATION_BASED
}
/**
* (Optional) Live Object naming scheme. Defines how to assign key names for each instance of this class.
* Used to create a reference to an existing Live Object and materialising a new one in redis.
* Defaults to {@link DefaultNamingScheme} implementation.
*
* @return value
*/
Class<? extends NamingScheme> namingScheme() default DefaultNamingScheme.class;
/**
* (Optional) Live Object state codec. Defaults to {@link JsonJacksonCodec}.
*
* @return value
*/
Class<? extends Codec> codec() default JsonJacksonCodec.class;
/**
* (Optional) Live Object field transformation.
* Defaults to {@link TransformationMode#ANNOTATION_BASED}
*
* @return value
*/
TransformationMode fieldTransformation() default TransformationMode.ANNOTATION_BASED;
}

@ -21,6 +21,19 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Specifies that the method is a field accessor for Live Object.
* Example:
* <pre>
* &#064;RFieldAccessor
* public void set(String field, T value) {
* }
*
* &#064;RFieldAccessor
* public Object get(String field) {
* return null;
* }
* </pre>
*
*
* @author Rui Gu (https://github.com/jackygurui)
*/

@ -20,10 +20,14 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.redisson.liveobject.resolver.LongGenerator;
import org.redisson.liveobject.resolver.RIdResolver;
import org.redisson.liveobject.resolver.RequiredIdResolver;
import org.redisson.liveobject.resolver.UUIDGenerator;
/**
* Specifies that the field is a Live Object's id field.
* Only single field could be specified per class.
*
* @author Rui Gu (https://github.com/jackygurui)
*/
@ -31,6 +35,12 @@ import org.redisson.liveobject.resolver.RequiredIdResolver;
@Target({ElementType.FIELD})
public @interface RId {
/**
* (Optional) Live Object id generator. By default id is required to be fill during object creation.
*
* @see UUIDGenerator
* @see LongGenerator
*/
Class<? extends RIdResolver> generator() default RequiredIdResolver.class;
}

@ -21,6 +21,7 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Specifies that the field value is filled up with RedissonClient instance.
*
* @author Nikita Koksharov
*

@ -25,6 +25,11 @@ import org.redisson.client.codec.Codec;
import org.redisson.codec.JsonJacksonCodec;
/**
* By default <code>namingScheme</code> and/or <code>codec</code> parameters specified in {@link REntity}
* are applied for each Live Object field.
*
* This annotation allows to specify custom <code>namingScheme</code> and/or <code>codec</code> parameters
* for any Live Object field except that marked with {@link RId}.
*
* @author Rui Gu (https://github.com/jackygurui)
*/
@ -32,8 +37,16 @@ import org.redisson.codec.JsonJacksonCodec;
@Target({ElementType.FIELD})
public @interface RObjectField{
/**
* (Optional) Live Object naming scheme. Defines how to assign key names for each instance of this class.
* Used to create a reference to an existing Live Object and materialising a new one in redis.
* Defaults to {@link DefaultNamingScheme} implementation.
*/
Class<? extends NamingScheme> namingScheme() default DefaultNamingScheme.class;
/**
* (Optional) Live Object state codec. Defaults to {@link JsonJacksonCodec}.
*/
Class<? extends Codec> codec() default JsonJacksonCodec.class;
}

@ -125,6 +125,7 @@ public interface RedisCommands {
RedisStrictCommand<Integer> ZREMRANGEBYSCORE = new RedisStrictCommand<Integer>("ZREMRANGEBYSCORE", new IntegerReplayConvertor());
RedisStrictCommand<Integer> ZREMRANGEBYLEX = new RedisStrictCommand<Integer>("ZREMRANGEBYLEX", new IntegerReplayConvertor());
RedisCommand<List<Object>> ZRANGEBYLEX = new RedisCommand<List<Object>>("ZRANGEBYLEX", new ObjectListReplayDecoder<Object>());
RedisCommand<List<Object>> ZREVRANGEBYLEX = new RedisCommand<List<Object>>("ZREVRANGEBYLEX", new ObjectListReplayDecoder<Object>());
RedisCommand<Set<Object>> ZRANGEBYSCORE = new RedisCommand<Set<Object>>("ZRANGEBYSCORE", new ObjectSetReplayDecoder<Object>());
RedisCommand<List<Object>> ZRANGEBYSCORE_LIST = new RedisCommand<List<Object>>("ZRANGEBYSCORE", new ObjectListReplayDecoder<Object>());
RedisCommand<List<Object>> ZREVRANGE = new RedisCommand<List<Object>>("ZREVRANGE", new ObjectListReplayDecoder<Object>());

@ -15,7 +15,6 @@
*/
package org.redisson.command;
import java.net.InetSocketAddress;
import java.util.List;
import org.redisson.api.RFuture;
@ -32,10 +31,6 @@ public interface CommandSyncExecutor {
<V> V get(RFuture<V> future);
<T, R> R write(String key, Codec codec, RedisCommand<T> command, Object ... params);
<T, R> R write(String key, RedisCommand<T> command, Object ... params);
<T, R> R read(String key, RedisCommand<T> command, Object ... params);
<T, R> R read(String key, Codec codec, RedisCommand<T> command, Object ... params);

@ -15,7 +15,6 @@
*/
package org.redisson.command;
import java.net.InetSocketAddress;
import java.util.List;
import org.redisson.api.RFuture;
@ -71,16 +70,4 @@ public class CommandSyncService extends CommandAsyncService implements CommandEx
return get(res);
}
@Override
public <T, R> R write(String key, Codec codec, RedisCommand<T> command, Object ... params) {
RFuture<R> res = writeAsync(key, codec, command, params);
return get(res);
}
@Override
public <T, R> R write(String key, RedisCommand<T> command, Object ... params) {
RFuture<R> res = writeAsync(key, command, params);
return get(res);
}
}

@ -56,7 +56,7 @@ public class FieldAccessorInterceptor {
}
}
}
throw new NoSuchMethodException(method.getName() + " called with wrong signature");
throw new NoSuchMethodException(method.getName() + " has wrong signature");
}
}

@ -2,19 +2,845 @@ package org.redisson;
import static org.assertj.core.api.Assertions.assertThat;
import java.io.Serializable;
import java.util.AbstractMap;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadLocalRandom;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Test;
import org.redisson.api.RLocalCachedMap;
import org.redisson.api.RMap;
import org.redisson.api.RMapCache;
import org.redisson.api.RedissonClient;
import org.redisson.api.map.MapLoader;
import org.redisson.api.map.MapWriter;
import org.redisson.client.codec.Codec;
import org.redisson.client.codec.StringCodec;
import org.redisson.codec.JsonJacksonCodec;
import org.redisson.config.Config;
public abstract class BaseMapTest extends BaseTest {
public static class SimpleKey implements Serializable {
private String key;
public SimpleKey() {
}
public SimpleKey(String field) {
this.key = field;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
@Override
public String toString() {
return "key: " + key;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((key == null) ? 0 : key.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
SimpleKey other = (SimpleKey) obj;
if (key == null) {
if (other.key != null)
return false;
} else if (!key.equals(other.key))
return false;
return true;
}
}
public static class SimpleValue implements Serializable {
private String value;
public SimpleValue() {
}
public SimpleValue(String field) {
this.value = field;
}
public void setValue(String field) {
this.value = field;
}
public String getValue() {
return value;
}
@Override
public String toString() {
return "value: " + value;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((value == null) ? 0 : value.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
SimpleValue other = (SimpleValue) obj;
if (value == null) {
if (other.value != null)
return false;
} else if (!value.equals(other.value))
return false;
return true;
}
}
@Test
public void testGetAllWithStringKeys() {
RMap<String, Integer> map = getMap("getAllStrings");
map.put("A", 100);
map.put("B", 200);
map.put("C", 300);
map.put("D", 400);
Map<String, Integer> filtered = map.getAll(new HashSet<String>(Arrays.asList("B", "C", "E")));
Map<String, Integer> expectedMap = new HashMap<String, Integer>();
expectedMap.put("B", 200);
expectedMap.put("C", 300);
assertThat(filtered).isEqualTo(expectedMap);
}
@Test
public void testStringCodec() {
Config config = createConfig();
config.setCodec(StringCodec.INSTANCE);
RedissonClient redisson = Redisson.create(config);
RMap<String, String> rmap = redisson.getMap("TestRMap01");
rmap.put("A", "1");
rmap.put("B", "2");
Iterator<Map.Entry<String, String>> iterator = rmap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> next = iterator.next();
assertThat(next).isIn(new AbstractMap.SimpleEntry("A", "1"), new AbstractMap.SimpleEntry("B", "2"));
}
redisson.shutdown();
}
@Test
public void testInteger() {
Map<Integer, Integer> map = getMap("test_int");
map.put(1, 2);
map.put(3, 4);
assertThat(map.size()).isEqualTo(2);
Integer val = map.get(1);
assertThat(val).isEqualTo(2);
Integer val2 = map.get(3);
assertThat(val2).isEqualTo(4);
}
@Test
public void testLong() {
Map<Long, Long> map = getMap("test_long");
map.put(1L, 2L);
map.put(3L, 4L);
assertThat(map.size()).isEqualTo(2);
Long val = map.get(1L);
assertThat(val).isEqualTo(2);
Long val2 = map.get(3L);
assertThat(val2).isEqualTo(4);
}
@Test
public void testIterator() {
RMap<Integer, Integer> rMap = getMap("123");
int size = 1000;
for (int i = 0; i < size; i++) {
rMap.put(i, i);
}
assertThat(rMap.size()).isEqualTo(1000);
int counter = 0;
for (Integer key : rMap.keySet()) {
counter++;
}
assertThat(counter).isEqualTo(size);
counter = 0;
for (Integer value : rMap.values()) {
counter++;
}
assertThat(counter).isEqualTo(size);
counter = 0;
for (Entry<Integer, Integer> entry : rMap.entrySet()) {
counter++;
}
assertThat(counter).isEqualTo(size);
}
@Test
public void testOrdering() {
Map<String, String> map = new LinkedHashMap<String, String>();
// General player data
map.put("name", "123");
map.put("ip", "4124");
map.put("rank", "none");
map.put("tokens", "0");
map.put("coins", "0");
// Arsenal player statistics
map.put("ar_score", "0");
map.put("ar_gameswon", "0");
map.put("ar_gameslost", "0");
map.put("ar_kills", "0");
map.put("ar_deaths", "0");
RMap<String, String> rmap = getMap("123");
Assume.assumeTrue(!(rmap instanceof RLocalCachedMap));
rmap.putAll(map);
assertThat(rmap.keySet()).containsExactlyElementsOf(map.keySet());
assertThat(rmap.readAllKeySet()).containsExactlyElementsOf(map.keySet());
assertThat(rmap.values()).containsExactlyElementsOf(map.values());
assertThat(rmap.readAllValues()).containsExactlyElementsOf(map.values());
assertThat(rmap.entrySet()).containsExactlyElementsOf(map.entrySet());
assertThat(rmap.readAllEntrySet()).containsExactlyElementsOf(map.entrySet());
}
@Test(expected = NullPointerException.class)
public void testNullValue() {
Map<Integer, String> map = getMap("simple12");
map.put(1, null);
}
@Test(expected = NullPointerException.class)
public void testNullKey() {
Map<Integer, String> map = getMap("simple12");
map.put(null, "1");
}
@Test
public void testSize() {
Map<SimpleKey, SimpleValue> map = getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
map.put(new SimpleKey("3"), new SimpleValue("4"));
map.put(new SimpleKey("5"), new SimpleValue("6"));
Assert.assertEquals(3, map.size());
map.put(new SimpleKey("1"), new SimpleValue("2"));
map.put(new SimpleKey("3"), new SimpleValue("4"));
Assert.assertEquals(3, map.size());
map.put(new SimpleKey("1"), new SimpleValue("21"));
map.put(new SimpleKey("3"), new SimpleValue("41"));
Assert.assertEquals(3, map.size());
map.put(new SimpleKey("51"), new SimpleValue("6"));
Assert.assertEquals(4, map.size());
map.remove(new SimpleKey("3"));
Assert.assertEquals(3, map.size());
}
@Test
public void testEmptyRemove() {
RMap<Integer, Integer> map = getMap("simple");
Assert.assertFalse(map.remove(1, 3));
map.put(4, 5);
Assert.assertTrue(map.remove(4, 5));
}
public void testFastPutIfAbsent() throws Exception {
RMap<SimpleKey, SimpleValue> map = getMap("simple");
SimpleKey key = new SimpleKey("1");
SimpleValue value = new SimpleValue("2");
map.put(key, value);
assertThat(map.fastPutIfAbsent(key, new SimpleValue("3"))).isFalse();
assertThat(map.get(key)).isEqualTo(value);
SimpleKey key1 = new SimpleKey("2");
SimpleValue value1 = new SimpleValue("4");
assertThat(map.fastPutIfAbsent(key1, value1)).isTrue();
assertThat(map.get(key1)).isEqualTo(value1);
}
@Test
public void testPutAll() {
Map<Integer, String> map = getMap("simple");
map.put(1, "1");
map.put(2, "2");
map.put(3, "3");
Map<Integer, String> joinMap = new HashMap<Integer, String>();
joinMap.put(4, "4");
joinMap.put(5, "5");
joinMap.put(6, "6");
map.putAll(joinMap);
assertThat(map.keySet()).containsOnly(1, 2, 3, 4, 5, 6);
}
@Test
public void testPutAllBig() {
Map<Integer, String> joinMap = new HashMap<Integer, String>();
for (int i = 0; i < 100000; i++) {
joinMap.put(i, "" + i);
}
Map<Integer, String> map = getMap("simple");
map.putAll(joinMap);
assertThat(map.size()).isEqualTo(joinMap.size());
}
@Test
public void testPutGet() {
Map<SimpleKey, SimpleValue> map = getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
map.put(new SimpleKey("33"), new SimpleValue("44"));
map.put(new SimpleKey("5"), new SimpleValue("6"));
SimpleValue val1 = map.get(new SimpleKey("33"));
Assert.assertEquals("44", val1.getValue());
SimpleValue val2 = map.get(new SimpleKey("5"));
Assert.assertEquals("6", val2.getValue());
}
@Test
public void testPutIfAbsent() throws Exception {
ConcurrentMap<SimpleKey, SimpleValue> map = getMap("simple");
SimpleKey key = new SimpleKey("1");
SimpleValue value = new SimpleValue("2");
map.put(key, value);
Assert.assertEquals(value, map.putIfAbsent(key, new SimpleValue("3")));
Assert.assertEquals(value, map.get(key));
SimpleKey key1 = new SimpleKey("2");
SimpleValue value1 = new SimpleValue("4");
Assert.assertNull(map.putIfAbsent(key1, value1));
Assert.assertEquals(value1, map.get(key1));
}
@Test(timeout = 5000)
public void testDeserializationErrorReturnsErrorImmediately() throws Exception {
redisson.getConfig().setCodec(new JsonJacksonCodec());
RMap<String, SimpleObjectWithoutDefaultConstructor> map = getMap("deserializationFailure");
Assume.assumeTrue(!(map instanceof RLocalCachedMap));
SimpleObjectWithoutDefaultConstructor object = new SimpleObjectWithoutDefaultConstructor("test-val");
Assert.assertEquals("test-val", object.getTestField());
map.put("test-key", object);
try {
map.get("test-key");
Assert.fail("Expected exception from map.get() call");
} catch (Exception e) {
e.printStackTrace();
}
}
public static class SimpleObjectWithoutDefaultConstructor {
private String testField;
SimpleObjectWithoutDefaultConstructor(String testField) {
this.testField = testField;
}
public String getTestField() {
return testField;
}
public void setTestField(String testField) {
this.testField = testField;
}
}
@Test
public void testReplaceOldValueFail() {
ConcurrentMap<SimpleKey, SimpleValue> map = getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
boolean res = map.replace(new SimpleKey("1"), new SimpleValue("43"), new SimpleValue("31"));
Assert.assertFalse(res);
SimpleValue val1 = map.get(new SimpleKey("1"));
Assert.assertEquals("2", val1.getValue());
}
@Test
public void testReplaceOldValueSuccess() {
ConcurrentMap<SimpleKey, SimpleValue> map = getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
boolean res = map.replace(new SimpleKey("1"), new SimpleValue("2"), new SimpleValue("3"));
Assert.assertTrue(res);
boolean res1 = map.replace(new SimpleKey("1"), new SimpleValue("2"), new SimpleValue("3"));
Assert.assertFalse(res1);
SimpleValue val1 = map.get(new SimpleKey("1"));
Assert.assertEquals("3", val1.getValue());
}
@Test
public void testReplaceValue() {
ConcurrentMap<SimpleKey, SimpleValue> map = getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
SimpleValue res = map.replace(new SimpleKey("1"), new SimpleValue("3"));
Assert.assertEquals("2", res.getValue());
SimpleValue val1 = map.get(new SimpleKey("1"));
Assert.assertEquals("3", val1.getValue());
}
@Test
public void testReplace() {
Map<SimpleKey, SimpleValue> map = getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
map.put(new SimpleKey("33"), new SimpleValue("44"));
map.put(new SimpleKey("5"), new SimpleValue("6"));
SimpleValue val1 = map.get(new SimpleKey("33"));
Assert.assertEquals("44", val1.getValue());
map.put(new SimpleKey("33"), new SimpleValue("abc"));
SimpleValue val2 = map.get(new SimpleKey("33"));
Assert.assertEquals("abc", val2.getValue());
}
@Test
public void testContainsValue() {
Map<SimpleKey, SimpleValue> map = getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
map.put(new SimpleKey("33"), new SimpleValue("44"));
map.put(new SimpleKey("5"), new SimpleValue("6"));
Assert.assertTrue(map.containsValue(new SimpleValue("2")));
Assert.assertFalse(map.containsValue(new SimpleValue("441")));
Assert.assertFalse(map.containsValue(new SimpleKey("5")));
}
@Test
public void testContainsKey() {
Map<SimpleKey, SimpleValue> map = getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
map.put(new SimpleKey("33"), new SimpleValue("44"));
map.put(new SimpleKey("5"), new SimpleValue("6"));
Assert.assertTrue(map.containsKey(new SimpleKey("33")));
Assert.assertFalse(map.containsKey(new SimpleKey("34")));
}
@Test
public void testRemoveValueFail() {
ConcurrentMap<SimpleKey, SimpleValue> map = getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
boolean res = map.remove(new SimpleKey("2"), new SimpleValue("1"));
Assert.assertFalse(res);
boolean res1 = map.remove(new SimpleKey("1"), new SimpleValue("3"));
Assert.assertFalse(res1);
SimpleValue val1 = map.get(new SimpleKey("1"));
Assert.assertEquals("2", val1.getValue());
}
@Test
public void testRemoveValue() {
ConcurrentMap<SimpleKey, SimpleValue> map = getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
boolean res = map.remove(new SimpleKey("1"), new SimpleValue("2"));
Assert.assertTrue(res);
SimpleValue val1 = map.get(new SimpleKey("1"));
Assert.assertNull(val1);
Assert.assertEquals(0, map.size());
}
@Test
public void testRemoveObject() {
Map<SimpleKey, SimpleValue> map = getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
map.put(new SimpleKey("33"), new SimpleValue("44"));
map.put(new SimpleKey("5"), new SimpleValue("6"));
assertThat(map.remove(new SimpleKey("33"))).isEqualTo(new SimpleValue("44"));
assertThat(map.remove(new SimpleKey("5"))).isEqualTo(new SimpleValue("6"));
assertThat(map.remove(new SimpleKey("11"))).isNull();
assertThat(map.size()).isEqualTo(1);
}
@Test
public void testRemove() {
RMap<Integer, Integer> map = getMap("simple");
map.put(1, 3);
map.put(3, 5);
map.put(7, 8);
assertThat(map.remove(1)).isEqualTo(3);
assertThat(map.remove(3)).isEqualTo(5);
assertThat(map.remove(10)).isNull();
assertThat(map.remove(7)).isEqualTo(8);
}
@Test
public void testFastRemove() throws InterruptedException, ExecutionException {
RMap<Integer, Integer> map = getMap("simple");
map.put(1, 3);
map.put(3, 5);
map.put(4, 6);
map.put(7, 8);
assertThat(map.fastRemove(1, 3, 7)).isEqualTo(3);
Thread.sleep(1);
assertThat(map.size()).isEqualTo(1);
}
@Test
public void testValueIterator() {
RMap<Integer, Integer> map = getMap("simple");
map.put(1, 0);
map.put(3, 5);
map.put(4, 6);
map.put(7, 8);
Collection<Integer> values = map.values();
assertThat(values).containsOnly(0, 5, 6, 8);
for (Iterator<Integer> iterator = map.values().iterator(); iterator.hasNext();) {
Integer value = iterator.next();
if (!values.remove(value)) {
Assert.fail();
}
}
assertThat(values.size()).isEqualTo(0);
}
@Test
public void testFastPut() throws Exception {
RMap<Integer, Integer> map = getMap("simple");
Assert.assertTrue(map.fastPut(1, 2));
assertThat(map.get(1)).isEqualTo(2);
Assert.assertFalse(map.fastPut(1, 3));
assertThat(map.get(1)).isEqualTo(3);
Assert.assertEquals(1, map.size());
}
@Test
public void testEquals() {
RMap<String, String> map = getMap("simple");
map.put("1", "7");
map.put("2", "4");
map.put("3", "5");
Map<String, String> testMap = new HashMap<String, String>();
testMap.put("1", "7");
testMap.put("2", "4");
testMap.put("3", "5");
assertThat(map).isEqualTo(testMap);
assertThat(testMap.hashCode()).isEqualTo(map.hashCode());
}
@Test
public void testFastRemoveEmpty() throws Exception {
RMap<Integer, Integer> map = getMap("simple");
map.put(1, 3);
assertThat(map.fastRemove()).isZero();
assertThat(map.size()).isEqualTo(1);
}
@Test
public void testKeySetByPattern() {
RMap<String, String> map = getMap("simple", StringCodec.INSTANCE);
map.put("10", "100");
map.put("20", "200");
map.put("30", "300");
assertThat(map.keySet("?0")).containsExactly("10", "20", "30");
assertThat(map.keySet("1")).isEmpty();
assertThat(map.keySet("10")).containsExactly("10");
}
@Test
public void testValuesByPattern() {
RMap<String, String> map = getMap("simple", StringCodec.INSTANCE);
map.put("10", "100");
map.put("20", "200");
map.put("30", "300");
assertThat(map.values("?0")).containsExactly("100", "200", "300");
assertThat(map.values("1")).isEmpty();
assertThat(map.values("10")).containsExactly("100");
}
@Test
public void testEntrySetByPattern() {
RMap<String, String> map = getMap("simple", StringCodec.INSTANCE);
map.put("10", "100");
map.put("20", "200");
map.put("30", "300");
assertThat(map.entrySet("?0")).containsExactly(new AbstractMap.SimpleEntry("10", "100"), new AbstractMap.SimpleEntry("20", "200"), new AbstractMap.SimpleEntry("30", "300"));
assertThat(map.entrySet("1")).isEmpty();
assertThat(map.entrySet("10")).containsExactly(new AbstractMap.SimpleEntry("10", "100"));
}
@Test
public void testReadAllKeySet() {
RMap<SimpleKey, SimpleValue> map = getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
map.put(new SimpleKey("33"), new SimpleValue("44"));
map.put(new SimpleKey("5"), new SimpleValue("6"));
assertThat(map.readAllKeySet().size()).isEqualTo(3);
Map<SimpleKey, SimpleValue> testMap = new HashMap<>(map);
assertThat(map.readAllKeySet()).containsOnlyElementsOf(testMap.keySet());
}
@Test
public void testEntrySetIteratorRemoveHighVolume() throws InterruptedException {
RMap<Integer, Integer> map = getMap("simpleMap");
for (int i = 0; i < 10000; i++) {
map.put(i, i*10);
}
int cnt = 0;
Iterator<Entry<Integer, Integer>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Entry<Integer, Integer> entry = iterator.next();
iterator.remove();
cnt++;
}
Assert.assertEquals(10000, cnt);
assertThat(map).isEmpty();
Assert.assertEquals(0, map.size());
}
@Test
public void testEntrySetIteratorRandomRemoveHighVolume() throws InterruptedException {
RMap<Integer, Integer> map = getMap("simpleMap");
for (int i = 0; i < 10000; i++) {
map.put(i, i*10);
}
int cnt = 0;
int removed = 0;
Iterator<Entry<Integer, Integer>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Entry<Integer, Integer> entry = iterator.next();
if (ThreadLocalRandom.current().nextBoolean()) {
iterator.remove();
removed++;
}
cnt++;
}
Assert.assertEquals(10000, cnt);
assertThat(map.size()).isEqualTo(cnt - removed);
}
@Test
public void testKeySetIteratorRemoveHighVolume() throws InterruptedException {
RMap<Integer, Integer> map = getMap("simpleMap");
for (int i = 0; i < 10000; i++) {
map.put(i, i*10);
}
int cnt = 0;
Iterator<Integer> iterator = map.keySet().iterator();
while (iterator.hasNext()) {
Integer integer = iterator.next();
iterator.remove();
cnt++;
}
Assert.assertEquals(10000, cnt);
assertThat(map).isEmpty();
Assert.assertEquals(0, map.size());
}
@Test
public void testReadAllKeySetHighAmount() {
RMap<SimpleKey, SimpleValue> map = getMap("simple");
for (int i = 0; i < 1000; i++) {
map.put(new SimpleKey("" + i), new SimpleValue("" + i));
}
assertThat(map.readAllKeySet().size()).isEqualTo(1000);
Map<SimpleKey, SimpleValue> testMap = new HashMap<>(map);
assertThat(map.readAllKeySet()).containsOnlyElementsOf(testMap.keySet());
}
@Test
public void testReadAllValues() {
RMap<SimpleKey, SimpleValue> map = getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
map.put(new SimpleKey("33"), new SimpleValue("44"));
map.put(new SimpleKey("5"), new SimpleValue("6"));
assertThat(map.readAllValues().size()).isEqualTo(3);
Map<SimpleKey, SimpleValue> testMap = new HashMap<>(map);
assertThat(map.readAllValues()).containsOnlyElementsOf(testMap.values());
}
@Test
public void testGetAllBig() {
Map<Integer, String> joinMap = new HashMap<Integer, String>();
for (int i = 0; i < 10000; i++) {
joinMap.put(i, "" + i);
}
RMap<Integer, String> map = getMap("simple");
map.putAll(joinMap);
Map<Integer, String> s = map.getAll(joinMap.keySet());
assertThat(s).isEqualTo(joinMap);
assertThat(map.size()).isEqualTo(joinMap.size());
}
@Test
public void testGetAll() {
RMap<Integer, Integer> map = getMap("getAll");
map.put(1, 100);
map.put(2, 200);
map.put(3, 300);
map.put(4, 400);
Map<Integer, Integer> filtered = map.getAll(new HashSet<Integer>(Arrays.asList(2, 3, 5)));
Map<Integer, Integer> expectedMap = new HashMap<Integer, Integer>();
expectedMap.put(2, 200);
expectedMap.put(3, 300);
assertThat(filtered).isEqualTo(expectedMap);
}
@Test
public void testValueSize() {
Assume.assumeTrue(RedisRunner.getDefaultRedisServerInstance().getRedisVersion().compareTo("3.2.0") > 0);
RMap<String, String> map = getMap("getAll");
Assume.assumeTrue(!(map instanceof RMapCache));
map.put("1", "1234");
assertThat(map.valueSize("4")).isZero();
assertThat(map.valueSize("1")).isEqualTo(6);
}
@Test
public void testGetAllOrder() {
RMap<Integer, Integer> map = getMap("getAll");
map.put(1, 100);
map.put(2, 200);
map.put(3, 300);
map.put(4, 400);
map.put(5, 500);
map.put(6, 600);
map.put(7, 700);
map.put(8, 800);
Map<Integer, Integer> filtered = map.getAll(new HashSet<Integer>(Arrays.asList(2, 3, 5, 1, 7, 8)));
Map<Integer, Integer> expectedMap = new LinkedHashMap<Integer, Integer>();
expectedMap.put(1, 100);
expectedMap.put(2, 200);
expectedMap.put(3, 300);
expectedMap.put(5, 500);
expectedMap.put(7, 700);
expectedMap.put(8, 800);
assertThat(filtered.entrySet()).containsExactlyElementsOf(expectedMap.entrySet());
}
@Test
public void testAddAndGet() throws InterruptedException {
RMap<Integer, Integer> map = getMap("getAll");
map.put(1, 100);
Integer res = map.addAndGet(1, 12);
assertThat(res).isEqualTo(112);
res = map.get(1);
assertThat(res).isEqualTo(112);
RMap<Integer, Double> map2 = getMap("getAll2");
map2.put(1, new Double(100.2));
Double res2 = map2.addAndGet(1, new Double(12.1));
assertThat(res2).isEqualTo(112.3);
res2 = map2.get(1);
assertThat(res2).isEqualTo(112.3);
RMap<String, Integer> mapStr = getMap("mapStr");
assertThat(mapStr.put("1", 100)).isNull();
assertThat(mapStr.addAndGet("1", 12)).isEqualTo(112);
assertThat(mapStr.get("1")).isEqualTo(112);
}
protected abstract <K, V> RMap<K, V> getMap(String name);
protected abstract <K, V> RMap<K, V> getMap(String name, Codec codec);
protected abstract <K, V> RMap<K, V> getWriterTestMap(String name, Map<K, V> map);
protected abstract <K, V> RMap<K, V> getLoaderTestMap(String name, Map<K, V> map);

@ -1,13 +1,10 @@
package org.redisson;
import java.util.Arrays;
import java.util.Collection;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.assertj.core.api.Assertions.*;
import org.junit.Assert;
import org.junit.Test;
import org.redisson.api.RBucket;
@ -29,26 +26,6 @@ public class RedissonBucketsTest extends BaseTest {
Assert.assertEquals(expected, result);
}
@Test
public void testFind() {
Collection<String> names = Arrays.asList("test:testGetPattern:one", "test:testGetPattern:two");
Collection<String> vals = Arrays.asList("one-val", "two-val");
redisson.getBucket("test:testGetPattern:one").set("one-val");
redisson.getBucket("test:testGetPattern:two").set("two-val");
List<RBucket<String>> buckets = redisson.getBuckets().find("test:testGetPattern:*");
Assert.assertEquals(2, buckets.size());
Assert.assertTrue(names.contains(buckets.get(0).getName()));
Assert.assertTrue(names.contains(buckets.get(1).getName()));
Assert.assertTrue(vals.contains(buckets.get(0).get()));
Assert.assertTrue(vals.contains(buckets.get(1).get()));
for (RBucket<String> bucket : buckets) {
bucket.delete();
}
}
@Test
public void testSet() {
Map<String, Integer> buckets = new HashMap<String, Integer>();

@ -125,6 +125,9 @@ public class RedissonLexSortedSetTest extends BaseTest {
assertThat(set.rangeTail("c", false)).containsExactly("d", "e", "f", "g");
assertThat(set.rangeTail("c", true)).containsExactly("c", "d", "e", "f", "g");
assertThat(set.rangeTail("c", false, 1, 2)).containsExactly("e", "f");
assertThat(set.rangeTail("c", true, 1, 3)).containsExactly("d", "e", "f");
}
@ -141,6 +144,9 @@ public class RedissonLexSortedSetTest extends BaseTest {
assertThat(set.rangeHead("c", false)).containsExactly("a", "b");
assertThat(set.rangeHead("c", true)).containsExactly("a", "b", "c");
assertThat(set.rangeHead("c", false, 1, 1)).containsExactly("b");
assertThat(set.rangeHead("c", true, 1, 2)).containsExactly("b", "c");
}
@ -156,8 +162,64 @@ public class RedissonLexSortedSetTest extends BaseTest {
set.add("g");
assertThat(set.range("aaa", true, "g", false)).containsExactly("b", "c", "d", "e", "f");
assertThat(set.range("aaa", true, "g", false, 2, 3)).containsExactly("d", "e", "f");
}
@Test
public void testLexRangeTailReversed() {
RLexSortedSet set = redisson.getLexSortedSet("simple");
Assert.assertTrue(set.add("a"));
Assert.assertFalse(set.add("a"));
Assert.assertTrue(set.add("b"));
Assert.assertTrue(set.add("c"));
Assert.assertTrue(set.add("d"));
Assert.assertTrue(set.add("e"));
Assert.assertTrue(set.add("f"));
Assert.assertTrue(set.add("g"));
assertThat(set.rangeTailReversed("c", false)).containsExactly("g", "f", "e", "d");
assertThat(set.rangeTailReversed("c", true)).containsExactly("g", "f", "e", "d", "c");
assertThat(set.rangeTailReversed("c", false, 1, 2)).containsExactly("f", "e");
assertThat(set.rangeTailReversed("c", true, 2, 2)).containsExactly("e", "d");
}
@Test
public void testLexRangeHeadReversed() {
RLexSortedSet set = redisson.getLexSortedSet("simple");
set.add("a");
set.add("b");
set.add("c");
set.add("d");
set.add("e");
set.add("f");
set.add("g");
assertThat(set.rangeHeadReversed("c", false)).containsExactly("b", "a");
assertThat(set.rangeHeadReversed("c", true)).containsExactly("c", "b", "a");
assertThat(set.rangeHeadReversed("c", false, 1, 1)).containsExactly("a");
assertThat(set.rangeHeadReversed("c", true, 1, 2)).containsExactly("b", "a");
}
@Test
public void testLexRangeReversed() {
RLexSortedSet set = redisson.getLexSortedSet("simple");
set.add("a");
set.add("b");
set.add("c");
set.add("d");
set.add("e");
set.add("f");
set.add("g");
assertThat(set.rangeReversed("aaa", true, "g", false)).containsExactly("f", "e", "d", "c", "b");
assertThat(set.rangeReversed("aaa", true, "g", false, 1, 2)).containsExactly("e", "d");
}
@Test
public void testLexCount() {
RLexSortedSet set = redisson.getLexSortedSet("simple");

@ -13,8 +13,6 @@ import org.junit.Assert;
import org.junit.Test;
import org.redisson.RedissonLocalCachedMap.CacheKey;
import org.redisson.RedissonLocalCachedMap.CacheValue;
import org.redisson.RedissonMapTest.SimpleKey;
import org.redisson.RedissonMapTest.SimpleValue;
import org.redisson.api.LocalCachedMapOptions;
import org.redisson.api.LocalCachedMapOptions.EvictionPolicy;
import org.redisson.api.LocalCachedMapOptions.ReconnectionStrategy;
@ -22,6 +20,7 @@ import org.redisson.api.LocalCachedMapOptions.SyncStrategy;
import org.redisson.api.RLocalCachedMap;
import org.redisson.api.RMap;
import org.redisson.cache.Cache;
import org.redisson.client.codec.Codec;
import org.redisson.client.codec.StringCodec;
import mockit.Deencapsulation;
@ -114,16 +113,26 @@ public class RedissonLocalCachedMapTest extends BaseMapTest {
}
@Override
protected <K, V> RMap<K, V> getMap(String name) {
return redisson.getLocalCachedMap(name, LocalCachedMapOptions.<K, V>defaults());
}
@Override
protected <K, V> RMap<K, V> getMap(String name, Codec codec) {
return redisson.getLocalCachedMap(name, codec, LocalCachedMapOptions.<K, V>defaults());
}
@Override
protected <K, V> RMap<K, V> getWriterTestMap(String name, Map<K, V> map) {
LocalCachedMapOptions<K, V> options = LocalCachedMapOptions.<K, V>defaults().writer(createMapWriter(map));
return redisson.getLocalCachedMap("test", options);
return redisson.getLocalCachedMap(name, options);
}
@Override
protected <K, V> RMap<K, V> getLoaderTestMap(String name, Map<K, V> map) {
LocalCachedMapOptions<K, V> options = LocalCachedMapOptions.<K, V>defaults().loader(createMapLoader(map));
return redisson.getLocalCachedMap("test", options);
return redisson.getLocalCachedMap(name, options);
}
@Test
@ -375,7 +384,7 @@ public class RedissonLocalCachedMapTest extends BaseMapTest {
}
@Test
public void testSize() {
public void testSizeCache() {
RLocalCachedMap<String, Integer> map = redisson.getLocalCachedMap("test", LocalCachedMapOptions.defaults());
Cache<CacheKey, CacheValue> cache = Deencapsulation.getField(map, "cache");
@ -404,7 +413,7 @@ public class RedissonLocalCachedMapTest extends BaseMapTest {
}
@Test
public void testPut() {
public void testPutGetCache() {
RLocalCachedMap<String, Integer> map = redisson.getLocalCachedMap("test", LocalCachedMapOptions.defaults());
Cache<CacheKey, CacheValue> cache = Deencapsulation.getField(map, "cache");
@ -425,7 +434,7 @@ public class RedissonLocalCachedMapTest extends BaseMapTest {
}
@Test
public void testGetAll() {
public void testGetAllCache() {
RMap<String, Integer> map = redisson.getLocalCachedMap("getAll", LocalCachedMapOptions.defaults());
Cache<CacheKey, CacheValue> cache = Deencapsulation.getField(map, "cache");
map.put("1", 100);
@ -468,7 +477,7 @@ public class RedissonLocalCachedMapTest extends BaseMapTest {
@Test
public void testPutAll() throws InterruptedException {
public void testPutAllCache() throws InterruptedException {
Map<Integer, String> map = redisson.getLocalCachedMap("simple", LocalCachedMapOptions.defaults());
Map<Integer, String> map1 = redisson.getLocalCachedMap("simple", LocalCachedMapOptions.defaults());
Cache<CacheKey, CacheValue> cache = Deencapsulation.getField(map, "cache");

@ -1,19 +1,17 @@
package org.redisson;
import static org.assertj.core.api.Assertions.assertThat;
import static org.awaitility.Awaitility.await;
import java.io.Serializable;
import java.util.AbstractMap;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
@ -23,7 +21,6 @@ import org.awaitility.Duration;
import org.junit.Assert;
import org.junit.Test;
import org.redisson.api.MapOptions;
import org.redisson.api.RFuture;
import org.redisson.api.RMap;
import org.redisson.api.RMapCache;
import org.redisson.api.map.event.EntryCreatedListener;
@ -31,116 +28,21 @@ import org.redisson.api.map.event.EntryEvent;
import org.redisson.api.map.event.EntryExpiredListener;
import org.redisson.api.map.event.EntryRemovedListener;
import org.redisson.api.map.event.EntryUpdatedListener;
import org.redisson.client.codec.Codec;
import org.redisson.client.codec.DoubleCodec;
import org.redisson.client.codec.LongCodec;
import org.redisson.client.codec.StringCodec;
import org.redisson.codec.JsonJacksonCodec;
import org.redisson.codec.MsgPackJacksonCodec;
import static org.awaitility.Awaitility.*;
public class RedissonMapCacheTest extends BaseMapTest {
public static class SimpleKey implements Serializable {
private String key;
public SimpleKey() {
}
public SimpleKey(String field) {
this.key = field;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
@Override
public String toString() {
return "key: " + key;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((key == null) ? 0 : key.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
SimpleKey other = (SimpleKey) obj;
if (key == null) {
if (other.key != null)
return false;
} else if (!key.equals(other.key))
return false;
return true;
}
@Override
protected <K, V> RMap<K, V> getMap(String name) {
return redisson.getMapCache(name);
}
public static class SimpleValue implements Serializable {
private String value;
public SimpleValue() {
}
public SimpleValue(String field) {
this.value = field;
}
public void setValue(String field) {
this.value = field;
}
public String getValue() {
return value;
}
@Override
public String toString() {
return "value: " + value;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((value == null) ? 0 : value.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
SimpleValue other = (SimpleValue) obj;
if (value == null) {
if (other.value != null)
return false;
} else if (!value.equals(other.value))
return false;
return true;
}
@Override
protected <K, V> RMap<K, V> getMap(String name, Codec codec) {
return redisson.getMapCache(name, codec);
}
@Override
@ -156,7 +58,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
}
@Test
public void testWriterPutIfAbsent() {
public void testWriterPutIfAbsentTTL() {
Map<String, String> store = new HashMap<>();
RMapCache<String, String> map = (RMapCache<String, String>) getWriterTestMap("test", store);
@ -365,37 +267,6 @@ public class RedissonMapCacheTest extends BaseMapTest {
}
@Test
public void testOrdering() {
Map<String, String> map = new LinkedHashMap<String, String>();
// General player data
map.put("name", "123");
map.put("ip", "4124");
map.put("rank", "none");
map.put("tokens", "0");
map.put("coins", "0");
// Arsenal player statistics
map.put("ar_score", "0");
map.put("ar_gameswon", "0");
map.put("ar_gameslost", "0");
map.put("ar_kills", "0");
map.put("ar_deaths", "0");
RMap<String, String> rmap = redisson.getMapCache("123");
rmap.putAll(map);
assertThat(rmap.keySet()).containsExactlyElementsOf(map.keySet());
assertThat(rmap.readAllKeySet()).containsExactlyElementsOf(map.keySet());
assertThat(rmap.values()).containsExactlyElementsOf(map.values());
assertThat(rmap.readAllValues()).containsExactlyElementsOf(map.values());
assertThat(rmap.entrySet()).containsExactlyElementsOf(map.entrySet());
assertThat(rmap.readAllEntrySet()).containsExactlyElementsOf(map.entrySet());
}
@Test
public void testCacheValues() {
final RMapCache<String, String> map = redisson.getMapCache("testRMapCacheValues");
@ -404,24 +275,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
}
@Test
public void testGetAllBig() {
Map<Integer, String> joinMap = new HashMap<Integer, String>();
for (int i = 0; i < 10000; i++) {
joinMap.put(i, "" + i);
}
RMap<Integer, String> map = redisson.getMapCache("simple");
map.putAll(joinMap);
Map<Integer, String> s = map.getAll(joinMap.keySet());
assertThat(s).isEqualTo(joinMap);
assertThat(map.size()).isEqualTo(joinMap.size());
}
@Test
public void testGetAll() throws InterruptedException {
public void testGetAllTTL() throws InterruptedException {
RMapCache<Integer, Integer> map = redisson.getMapCache("getAll");
map.put(1, 100);
map.put(2, 200, 1, TimeUnit.SECONDS);
@ -494,70 +348,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
Assert.assertEquals(0, cache.size());
}
@Test
public void testIteratorRemoveHighVolume() throws InterruptedException {
RMapCache<Integer, Integer> map = redisson.getMapCache("simpleMap");
for (int i = 0; i < 10000; i++) {
map.put(i, i*10);
}
int cnt = 0;
Iterator<Entry<Integer, Integer>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Entry<Integer, Integer> entry = iterator.next();
iterator.remove();
cnt++;
}
Assert.assertEquals(10000, cnt);
assertThat(map).isEmpty();
Assert.assertEquals(0, map.size());
}
@Test
public void testIteratorRandomRemoveFirst() throws InterruptedException {
RMapCache<Integer, Integer> map = redisson.getMapCache("simpleMap");
for (int i = 0; i < 1000; i++) {
map.put(i, i*10);
}
int cnt = 0;
int removed = 0;
Iterator<Entry<Integer, Integer>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Entry<Integer, Integer> entry = iterator.next();
if (cnt < 20) {
iterator.remove();
removed++;
}
cnt++;
}
Assert.assertEquals(1000, cnt);
assertThat(map.size()).isEqualTo(cnt - removed);
}
@Test
public void testIteratorRandomRemoveHighVolume() throws InterruptedException {
RMapCache<Integer, Integer> map = redisson.getMapCache("simpleMap");
for (int i = 0; i < 10000; i++) {
map.put(i, i*10);
}
int cnt = 0;
int removed = 0;
Iterator<Entry<Integer, Integer>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Entry<Integer, Integer> entry = iterator.next();
if (ThreadLocalRandom.current().nextBoolean()) {
iterator.remove();
removed++;
}
cnt++;
}
Assert.assertEquals(10000, cnt);
assertThat(map.size()).isEqualTo(cnt - removed);
}
@Test
public void testClearExpire() throws InterruptedException {
RMapCache<String, String> cache = redisson.getMapCache("simple");
@ -586,49 +377,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
assertThat(map.entrySet()).containsAll(expected.entrySet());
assertThat(map).hasSize(3);
}
@Test
public void testRemove() {
Map<SimpleKey, SimpleValue> map = redisson.getMapCache("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
map.put(new SimpleKey("33"), new SimpleValue("44"));
map.put(new SimpleKey("5"), new SimpleValue("6"));
map.remove(new SimpleKey("33"));
map.remove(new SimpleKey("5"));
Assert.assertEquals(1, map.size());
}
@Test
public void testPutAllBig() {
Map<Integer, String> joinMap = new HashMap<Integer, String>();
for (int i = 0; i < 100000; i++) {
joinMap.put(i, "" + i);
}
Map<Integer, String> map = redisson.getMapCache("simple");
map.putAll(joinMap);
assertThat(map.size()).isEqualTo(joinMap.size());
}
@Test
public void testPutAll() {
Map<Integer, String> map = redisson.getMapCache("simple");
map.put(1, "1");
map.put(2, "2");
map.put(3, "3");
Map<Integer, String> joinMap = new HashMap<Integer, String>();
joinMap.put(4, "4");
joinMap.put(5, "5");
joinMap.put(6, "6");
map.putAll(joinMap);
assertThat(map.keySet()).containsOnly(1, 2, 3, 4, 5, 6);
}
@Test
public void testKeySet() throws InterruptedException {
RMapCache<SimpleKey, SimpleValue> map = redisson.getMapCache("simple03");
@ -664,7 +413,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
}
@Test
public void testKeySetByPattern() {
public void testKeySetByPatternTTL() {
RMapCache<String, String> map = redisson.getMapCache("simple", StringCodec.INSTANCE);
map.put("10", "100");
map.put("20", "200", 1, TimeUnit.MINUTES);
@ -676,7 +425,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
}
@Test
public void testValuesByPattern() {
public void testValuesByPatternTTL() {
RMapCache<String, String> map = redisson.getMapCache("simple", StringCodec.INSTANCE);
map.put("10", "100");
map.put("20", "200", 1, TimeUnit.MINUTES);
@ -688,7 +437,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
}
@Test
public void testEntrySetByPattern() {
public void testEntrySetByPatternTTL() {
RMapCache<String, String> map = redisson.getMapCache("simple", StringCodec.INSTANCE);
map.put("10", "100");
map.put("20", "200", 1, TimeUnit.MINUTES);
@ -701,8 +450,8 @@ public class RedissonMapCacheTest extends BaseMapTest {
@Test
public void testContainsValue() throws InterruptedException {
RMapCache<SimpleKey, SimpleValue> map = redisson.getMapCache("simple01", new MsgPackJacksonCodec());
public void testContainsValueTTL() throws InterruptedException {
RMapCache<SimpleKey, SimpleValue> map = redisson.getMapCache("simple01");
Assert.assertFalse(map.containsValue(new SimpleValue("34")));
map.put(new SimpleKey("33"), new SimpleValue("44"), 1, TimeUnit.SECONDS);
@ -715,7 +464,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
}
@Test
public void testContainsKey() throws InterruptedException {
public void testContainsKeyTTL() throws InterruptedException {
RMapCache<SimpleKey, SimpleValue> map = redisson.getMapCache("simple30");
map.put(new SimpleKey("33"), new SimpleValue("44"), 1, TimeUnit.SECONDS);
@ -728,7 +477,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
}
@Test
public void testRemoveValue() {
public void testRemoveValueTTL() throws InterruptedException {
RMapCache<SimpleKey, SimpleValue> map = redisson.getMapCache("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"), 1, TimeUnit.SECONDS);
@ -739,23 +488,16 @@ public class RedissonMapCacheTest extends BaseMapTest {
Assert.assertNull(val1);
Assert.assertEquals(0, map.size());
}
@Test
public void testRemoveValueTTL() throws InterruptedException {
RMapCache<SimpleKey, SimpleValue> map = redisson.getMapCache("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"), 1, TimeUnit.SECONDS);
map.put(new SimpleKey("3"), new SimpleValue("4"), 1, TimeUnit.SECONDS);
Thread.sleep(1000);
boolean res = map.remove(new SimpleKey("1"), new SimpleValue("2"));
Assert.assertFalse(res);
assertThat(map.remove(new SimpleKey("3"), new SimpleValue("4"))).isFalse();
SimpleValue val1 = map.get(new SimpleKey("1"));
Assert.assertNull(val1);
assertThat(map.get(new SimpleKey("3"))).isNull();
}
@Test
public void testRemoveValueFail() {
ConcurrentMap<SimpleKey, SimpleValue> map = redisson.getMapCache("simple");
@ -799,18 +541,6 @@ public class RedissonMapCacheTest extends BaseMapTest {
Assert.assertEquals("3", val1.getValue());
}
@Test
public void testReplaceValue() throws InterruptedException {
RMapCache<SimpleKey, SimpleValue> map = redisson.getMapCache("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
SimpleValue res = map.replace(new SimpleKey("1"), new SimpleValue("3"));
Assert.assertEquals("2", res.getValue());
SimpleValue val1 = map.get(new SimpleKey("1"));
Assert.assertEquals("3", val1.getValue());
}
@Test
public void testReplaceValueTTL() throws InterruptedException {
RMapCache<SimpleKey, SimpleValue> map = redisson.getMapCache("simple");
@ -825,24 +555,9 @@ public class RedissonMapCacheTest extends BaseMapTest {
assertThat(val1).isNull();
}
@Test
public void testReplace() {
Map<SimpleKey, SimpleValue> map = redisson.getMapCache("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
map.put(new SimpleKey("33"), new SimpleValue("44"));
map.put(new SimpleKey("5"), new SimpleValue("6"));
SimpleValue val1 = map.get(new SimpleKey("33"));
Assert.assertEquals("44", val1.getValue());
map.put(new SimpleKey("33"), new SimpleValue("abc"));
SimpleValue val2 = map.get(new SimpleKey("33"));
Assert.assertEquals("abc", val2.getValue());
}
@Test
public void testScheduler() throws InterruptedException {
RMapCache<SimpleKey, SimpleValue> map = redisson.getMapCache("simple3", new MsgPackJacksonCodec());
RMapCache<SimpleKey, SimpleValue> map = redisson.getMapCache("simple3");
Assert.assertNull(map.get(new SimpleKey("33")));
map.put(new SimpleKey("33"), new SimpleValue("44"), 5, TimeUnit.SECONDS);
@ -858,8 +573,8 @@ public class RedissonMapCacheTest extends BaseMapTest {
}
@Test
public void testPutGet() throws InterruptedException {
RMapCache<SimpleKey, SimpleValue> map = redisson.getMapCache("simple04", new MsgPackJacksonCodec());
public void testPutGetTTL() throws InterruptedException {
RMapCache<SimpleKey, SimpleValue> map = redisson.getMapCache("simple04");
Assert.assertNull(map.get(new SimpleKey("33")));
map.put(new SimpleKey("33"), new SimpleValue("44"), 2, TimeUnit.SECONDS);
@ -880,7 +595,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
}
@Test
public void testPutIfAbsent() throws Exception {
public void testPutIfAbsentTTL() throws Exception {
RMapCache<SimpleKey, SimpleValue> map = redisson.getMapCache("simple");
SimpleKey key = new SimpleKey("1");
SimpleValue value = new SimpleValue("2");
@ -907,79 +622,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
}
@Test
public void testSize() {
Map<SimpleKey, SimpleValue> map = redisson.getMapCache("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
map.put(new SimpleKey("3"), new SimpleValue("4"));
map.put(new SimpleKey("5"), new SimpleValue("6"));
Assert.assertEquals(3, map.size());
map.put(new SimpleKey("1"), new SimpleValue("2"));
map.put(new SimpleKey("3"), new SimpleValue("4"));
Assert.assertEquals(3, map.size());
map.put(new SimpleKey("1"), new SimpleValue("21"));
map.put(new SimpleKey("3"), new SimpleValue("41"));
Assert.assertEquals(3, map.size());
map.put(new SimpleKey("51"), new SimpleValue("6"));
Assert.assertEquals(4, map.size());
map.remove(new SimpleKey("3"));
Assert.assertEquals(3, map.size());
}
@Test
public void testEmptyRemove() {
RMapCache<Integer, Integer> map = redisson.getMapCache("simple");
Assert.assertFalse(map.remove(1, 3));
map.put(4, 5);
Assert.assertTrue(map.remove(4, 5));
}
@Test
public void testPutAsync() throws InterruptedException, ExecutionException {
RMapCache<Integer, Integer> map = redisson.getMapCache("simple");
RFuture<Integer> future = map.putAsync(2, 3);
Assert.assertNull(future.get());
Assert.assertEquals((Integer) 3, map.get(2));
RFuture<Integer> future1 = map.putAsync(2, 4);
Assert.assertEquals((Integer) 3, future1.get());
Assert.assertEquals((Integer) 4, map.get(2));
}
@Test
public void testRemoveAsync() throws InterruptedException, ExecutionException {
RMapCache<Integer, Integer> map = redisson.getMapCache("simple");
map.put(1, 3);
map.put(3, 5);
map.put(7, 8);
Assert.assertEquals((Integer) 3, map.removeAsync(1).get());
Assert.assertEquals((Integer) 5, map.removeAsync(3).get());
Assert.assertNull(map.removeAsync(10).get());
Assert.assertEquals((Integer) 8, map.removeAsync(7).get());
}
@Test
public void testFastRemoveAsync() throws InterruptedException, ExecutionException {
RMapCache<Integer, Integer> map = redisson.getMapCache("simple");
map.put(1, 3);
map.put(3, 5);
map.put(4, 6);
map.put(7, 8);
Assert.assertEquals((Long) 3L, map.fastRemoveAsync(1, 3, 7).get());
Thread.sleep(1);
Assert.assertEquals(1, map.size());
}
@Test
public void testFastPutIfAbsent() throws Exception {
public void testFastPutIfAbsentTTL() throws Exception {
RMapCache<SimpleKey, SimpleValue> map = redisson.getMapCache("simple");
SimpleKey key = new SimpleKey("1");
SimpleValue value = new SimpleValue("2");
@ -1152,17 +795,6 @@ public class RedissonMapCacheTest extends BaseMapTest {
map.removeListener(createListener1);
}
@Test
public void testFastPut() throws Exception {
RMapCache<Integer, Integer> map = redisson.getMapCache("simple");
Assert.assertTrue(map.fastPut(1, 2));
assertThat(map.get(1)).isEqualTo(2);
Assert.assertFalse(map.fastPut(1, 3));
assertThat(map.get(1)).isEqualTo(3);
Assert.assertEquals(1, map.size());
}
@Test
public void testIdle() throws InterruptedException {
testIdleExpiration(map -> {
@ -1271,24 +903,6 @@ public class RedissonMapCacheTest extends BaseMapTest {
map.clear();
}
@Test
public void testEquals() {
RMapCache<String, String> map = redisson.getMapCache("simple");
map.put("1", "7");
map.put("2", "4");
map.put("3", "5");
Map<String, String> testMap = new HashMap<String, String>();
testMap.put("1", "7");
testMap.put("2", "4");
testMap.put("3", "5");
Assert.assertEquals(testMap, map);
Assert.assertEquals(testMap.hashCode(), map.hashCode());
}
@Test
public void testExpireOverwrite() throws InterruptedException, ExecutionException {
RMapCache<String, Integer> set = redisson.getMapCache("simple");
@ -1306,34 +920,6 @@ public class RedissonMapCacheTest extends BaseMapTest {
Assert.assertFalse(set.containsKey("123"));
}
@Test
public void testFastRemoveEmpty() throws Exception {
RMapCache<Integer, Integer> map = redisson.getMapCache("simple");
map.put(1, 3);
Assert.assertEquals(0, map.fastRemove());
Assert.assertEquals(1, map.size());
}
@Test(timeout = 5000)
public void testDeserializationErrorReturnsErrorImmediately() throws Exception {
redisson.getConfig().setCodec(new JsonJacksonCodec());
RMapCache<String, SimpleObjectWithoutDefaultConstructor> map = redisson.getMapCache("deserializationFailure");
SimpleObjectWithoutDefaultConstructor object = new SimpleObjectWithoutDefaultConstructor("test-val");
Assert.assertEquals("test-val", object.getTestField());
map.put("test-key", object);
try {
map.get("test-key");
Assert.fail("Expected exception from map.get() call");
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void testRMapCacheValues() {
final RMapCache<String, String> map = redisson.getMapCache("testRMapCacheValues");
@ -1351,33 +937,15 @@ public class RedissonMapCacheTest extends BaseMapTest {
assertThat(map.readAllEntrySet()).isEqualTo(map.entrySet());
}
@Test
public void testReadAllValues() {
public void testReadAllValuesTTL() {
final RMapCache<String, String> map = redisson.getMapCache("testRMapCacheAllValues");
map.put("1234", "5678", 1, TimeUnit.MINUTES, 60, TimeUnit.MINUTES);
assertThat(map.readAllValues()).containsOnly("5678");
}
public static class SimpleObjectWithoutDefaultConstructor {
private String testField;
SimpleObjectWithoutDefaultConstructor(String testField) {
this.testField = testField;
}
public String getTestField() {
return testField;
}
public void setTestField(String testField) {
this.testField = testField;
}
}
@Test
public void testAddAndGet() {
public void testAddAndGetTTL() {
RMapCache<String, Object> mapCache = redisson.getMapCache("test_put_if_absent", LongCodec.INSTANCE);
assertThat(mapCache.putIfAbsent("4", 0L, 10000L, TimeUnit.SECONDS)).isNull();
assertThat(mapCache.addAndGet("4", 1L)).isEqualTo(1L);

@ -2,138 +2,32 @@ package org.redisson;
import static org.assertj.core.api.Assertions.assertThat;
import java.io.Serializable;
import java.util.AbstractMap;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Test;
import org.redisson.api.MapOptions;
import org.redisson.api.RFuture;
import org.redisson.api.RMap;
import org.redisson.client.codec.Codec;
import org.redisson.api.RedissonClient;
import org.redisson.client.codec.StringCodec;
import org.redisson.codec.JsonJacksonCodec;
import org.redisson.config.Config;
import net.bytebuddy.utility.RandomString;
public class RedissonMapTest extends BaseMapTest {
public static class SimpleKey implements Serializable {
private String key;
public SimpleKey() {
}
public SimpleKey(String field) {
this.key = field;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
@Override
public String toString() {
return "key: " + key;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((key == null) ? 0 : key.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
SimpleKey other = (SimpleKey) obj;
if (key == null) {
if (other.key != null)
return false;
} else if (!key.equals(other.key))
return false;
return true;
}
}
public static class SimpleValue implements Serializable {
private String value;
public SimpleValue() {
}
public SimpleValue(String field) {
this.value = field;
}
public void setValue(String field) {
this.value = field;
}
public String getValue() {
return value;
}
@Override
public String toString() {
return "value: " + value;
protected <K, V> RMap<K, V> getMap(String name) {
return redisson.getMap(name);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((value == null) ? 0 : value.hashCode());
return result;
protected <K, V> RMap<K, V> getMap(String name, Codec codec) {
return redisson.getMap(name, codec);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
SimpleValue other = (SimpleValue) obj;
if (value == null) {
if (other.value != null)
return false;
} else if (!value.equals(other.value))
return false;
return true;
}
}
@Override
protected <K, V> RMap<K, V> getLoaderTestMap(String name, Map<K, V> map) {
MapOptions<K, V> options = MapOptions.<K, V>defaults().loader(createMapLoader(map));
return redisson.getMap("test", options);
@ -145,204 +39,6 @@ public class RedissonMapTest extends BaseMapTest {
return redisson.getMap("test", options);
}
@Test
public void testAddAndGet() throws InterruptedException {
RMap<Integer, Integer> map = redisson.getMap("getAll");
map.put(1, 100);
Integer res = map.addAndGet(1, 12);
assertThat(res).isEqualTo(112);
res = map.get(1);
assertThat(res).isEqualTo(112);
RMap<Integer, Double> map2 = redisson.getMap("getAll2");
map2.put(1, new Double(100.2));
Double res2 = map2.addAndGet(1, new Double(12.1));
assertThat(res2).isEqualTo(112.3);
res2 = map2.get(1);
assertThat(res2).isEqualTo(112.3);
RMap<String, Integer> mapStr = redisson.getMap("mapStr");
assertThat(mapStr.put("1", 100)).isNull();
assertThat(mapStr.addAndGet("1", 12)).isEqualTo(112);
assertThat(mapStr.get("1")).isEqualTo(112);
}
@Test
public void testValueSize() {
Assume.assumeTrue(RedisRunner.getDefaultRedisServerInstance().getRedisVersion().compareTo("3.2.0") > 0);
RMap<String, String> map = redisson.getMap("getAll");
map.put("1", "1234");
assertThat(map.valueSize("4")).isZero();
assertThat(map.valueSize("1")).isEqualTo(6);
}
@Test
public void testGetAllOrder() {
RMap<Integer, Integer> map = redisson.getMap("getAll");
map.put(1, 100);
map.put(2, 200);
map.put(3, 300);
map.put(4, 400);
map.put(5, 500);
map.put(6, 600);
map.put(7, 700);
map.put(8, 800);
Map<Integer, Integer> filtered = map.getAll(new HashSet<Integer>(Arrays.asList(2, 3, 5, 1, 7, 8)));
Map<Integer, Integer> expectedMap = new LinkedHashMap<Integer, Integer>();
expectedMap.put(1, 100);
expectedMap.put(2, 200);
expectedMap.put(3, 300);
expectedMap.put(5, 500);
expectedMap.put(7, 700);
expectedMap.put(8, 800);
assertThat(filtered.entrySet()).containsExactlyElementsOf(expectedMap.entrySet());
}
@Test
public void testGetAll() {
RMap<Integer, Integer> map = redisson.getMap("getAll");
map.put(1, 100);
map.put(2, 200);
map.put(3, 300);
map.put(4, 400);
Map<Integer, Integer> filtered = map.getAll(new HashSet<Integer>(Arrays.asList(2, 3, 5)));
Map<Integer, Integer> expectedMap = new HashMap<Integer, Integer>();
expectedMap.put(2, 200);
expectedMap.put(3, 300);
assertThat(filtered).isEqualTo(expectedMap);
}
@Test
public void testGetAllWithStringKeys() {
RMap<String, Integer> map = redisson.getMap("getAllStrings");
map.put("A", 100);
map.put("B", 200);
map.put("C", 300);
map.put("D", 400);
Map<String, Integer> filtered = map.getAll(new HashSet<String>(Arrays.asList("B", "C", "E")));
Map<String, Integer> expectedMap = new HashMap<String, Integer>();
expectedMap.put("B", 200);
expectedMap.put("C", 300);
assertThat(filtered).isEqualTo(expectedMap);
}
@Test
public void testStringCodec() {
Config config = createConfig();
config.setCodec(StringCodec.INSTANCE);
RedissonClient redisson = Redisson.create(config);
RMap<String, String> rmap = redisson.getMap("TestRMap01");
rmap.put("A", "1");
rmap.put("B", "2");
Iterator<Map.Entry<String, String>> iterator = rmap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> next = iterator.next();
assertThat(next).isIn(new AbstractMap.SimpleEntry("A", "1"), new AbstractMap.SimpleEntry("B", "2"));
}
redisson.shutdown();
}
@Test
public void testInteger() {
Map<Integer, Integer> map = redisson.getMap("test_int");
map.put(1, 2);
map.put(3, 4);
assertThat(map.size()).isEqualTo(2);
Integer val = map.get(1);
assertThat(val).isEqualTo(2);
Integer val2 = map.get(3);
assertThat(val2).isEqualTo(4);
}
@Test
public void testLong() {
Map<Long, Long> map = redisson.getMap("test_long");
map.put(1L, 2L);
map.put(3L, 4L);
assertThat(map.size()).isEqualTo(2);
Long val = map.get(1L);
assertThat(val).isEqualTo(2);
Long val2 = map.get(3L);
assertThat(val2).isEqualTo(4);
}
@Test
public void testIteratorRemoveHighVolume() throws InterruptedException {
RMap<Integer, Integer> map = redisson.getMap("simpleMap");
for (int i = 0; i < 10000; i++) {
map.put(i, i*10);
}
int cnt = 0;
Iterator<Integer> iterator = map.keySet().iterator();
while (iterator.hasNext()) {
Integer integer = iterator.next();
iterator.remove();
cnt++;
}
Assert.assertEquals(10000, cnt);
assertThat(map).isEmpty();
Assert.assertEquals(0, map.size());
}
@Test
public void testIterator() {
RMap<Integer, Integer> rMap = redisson.getMap("123");
int size = 1000;
for (int i = 0; i < size; i++) {
rMap.put(i,i);
}
assertThat(rMap.size()).isEqualTo(1000);
int counter = 0;
for (Integer key : rMap.keySet()) {
counter++;
}
assertThat(counter).isEqualTo(size);
counter = 0;
for (Integer value : rMap.values()) {
counter++;
}
assertThat(counter).isEqualTo(size);
counter = 0;
for (Entry<Integer, Integer> entry : rMap.entrySet()) {
counter++;
}
assertThat(counter).isEqualTo(size);
}
@Test(expected = NullPointerException.class)
public void testNullValue() {
Map<Integer, String> map = redisson.getMap("simple12");
map.put(1, null);
}
@Test(expected = NullPointerException.class)
public void testNullKey() {
Map<Integer, String> map = redisson.getMap("simple12");
map.put(null, "1");
}
@Test
public void testEntrySet() {
@ -379,76 +75,6 @@ public class RedissonMapTest extends BaseMapTest {
assertThat(val).isEqualTo("33");
}
@Test
public void testRemove() {
Map<SimpleKey, SimpleValue> map = redisson.getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
map.put(new SimpleKey("33"), new SimpleValue("44"));
map.put(new SimpleKey("5"), new SimpleValue("6"));
map.remove(new SimpleKey("33"));
map.remove(new SimpleKey("5"));
assertThat(map.size()).isEqualTo(1);
}
@Test
public void testOrdering() {
Map<String, String> map = new LinkedHashMap<String, String>();
// General player data
map.put("name", "123");
map.put("ip", "4124");
map.put("rank", "none");
map.put("tokens", "0");
map.put("coins", "0");
// Arsenal player statistics
map.put("ar_score", "0");
map.put("ar_gameswon", "0");
map.put("ar_gameslost", "0");
map.put("ar_kills", "0");
map.put("ar_deaths", "0");
RMap<String, String> rmap = redisson.getMap("123");
rmap.putAll(map);
assertThat(rmap.keySet()).containsExactlyElementsOf(map.keySet());
assertThat(rmap.readAllKeySet()).containsExactlyElementsOf(map.keySet());
assertThat(rmap.values()).containsExactlyElementsOf(map.values());
assertThat(rmap.readAllValues()).containsExactlyElementsOf(map.values());
assertThat(rmap.entrySet()).containsExactlyElementsOf(map.entrySet());
assertThat(rmap.readAllEntrySet()).containsExactlyElementsOf(map.entrySet());
}
@Test
public void testWriteTimeout() {
Map<String, String> map = redisson.getMap("simple");
Map<String, String> joinMap = new HashMap<>();
for (int i = 0; i < 200000; i++) {
joinMap.put(RandomString.make(1024), RandomString.make(1024));
}
map.putAll(joinMap);
}
@Test
public void testPutAll() {
Map<Integer, String> map = redisson.getMap("simple");
map.put(1, "1");
map.put(2, "2");
map.put(3, "3");
Map<Integer, String> joinMap = new HashMap<Integer, String>();
joinMap.put(4, "4");
joinMap.put(5, "5");
joinMap.put(6, "6");
map.putAll(joinMap);
assertThat(map.keySet()).containsOnly(1, 2, 3, 4, 5, 6);
}
@Test
public void testKeySet() {
Map<SimpleKey, SimpleValue> map = redisson.getMap("simple");
@ -460,308 +86,6 @@ public class RedissonMapTest extends BaseMapTest {
Assert.assertFalse(map.keySet().contains(new SimpleKey("44")));
}
@Test
public void testKeySetByPattern() {
RMap<String, String> map = redisson.getMap("simple", StringCodec.INSTANCE);
map.put("10", "100");
map.put("20", "200");
map.put("30", "300");
assertThat(map.keySet("?0")).containsExactly("10", "20", "30");
assertThat(map.keySet("1")).isEmpty();
assertThat(map.keySet("10")).containsExactly("10");
}
@Test
public void testValuesByPattern() {
RMap<String, String> map = redisson.getMap("simple", StringCodec.INSTANCE);
map.put("10", "100");
map.put("20", "200");
map.put("30", "300");
assertThat(map.values("?0")).containsExactly("100", "200", "300");
assertThat(map.values("1")).isEmpty();
assertThat(map.values("10")).containsExactly("100");
}
@Test
public void testEntrySetByPattern() {
RMap<String, String> map = redisson.getMap("simple", StringCodec.INSTANCE);
map.put("10", "100");
map.put("20", "200");
map.put("30", "300");
assertThat(map.entrySet("?0")).containsExactly(new AbstractMap.SimpleEntry("10", "100"), new AbstractMap.SimpleEntry("20", "200"), new AbstractMap.SimpleEntry("30", "300"));
assertThat(map.entrySet("1")).isEmpty();
assertThat(map.entrySet("10")).containsExactly(new AbstractMap.SimpleEntry("10", "100"));
}
@Test
public void testReadAllKeySet() {
RMap<SimpleKey, SimpleValue> map = redisson.getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
map.put(new SimpleKey("33"), new SimpleValue("44"));
map.put(new SimpleKey("5"), new SimpleValue("6"));
assertThat(map.readAllKeySet().size()).isEqualTo(3);
Map<SimpleKey, SimpleValue> testMap = new HashMap<>(map);
assertThat(map.readAllKeySet()).containsOnlyElementsOf(testMap.keySet());
}
@Test
public void testReadAllKeySetHighAmount() {
RMap<SimpleKey, SimpleValue> map = redisson.getMap("simple");
for (int i = 0; i < 1000; i++) {
map.put(new SimpleKey("" + i), new SimpleValue("" + i));
}
assertThat(map.readAllKeySet().size()).isEqualTo(1000);
Map<SimpleKey, SimpleValue> testMap = new HashMap<>(map);
assertThat(map.readAllKeySet()).containsOnlyElementsOf(testMap.keySet());
}
@Test
public void testReadAllValues() {
RMap<SimpleKey, SimpleValue> map = redisson.getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
map.put(new SimpleKey("33"), new SimpleValue("44"));
map.put(new SimpleKey("5"), new SimpleValue("6"));
assertThat(map.readAllValues().size()).isEqualTo(3);
Map<SimpleKey, SimpleValue> testMap = new HashMap<>(map);
assertThat(map.readAllValues()).containsOnlyElementsOf(testMap.values());
}
@Test
public void testContainsValue() {
Map<SimpleKey, SimpleValue> map = redisson.getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
map.put(new SimpleKey("33"), new SimpleValue("44"));
map.put(new SimpleKey("5"), new SimpleValue("6"));
Assert.assertTrue(map.containsValue(new SimpleValue("2")));
Assert.assertFalse(map.containsValue(new SimpleValue("441")));
Assert.assertFalse(map.containsValue(new SimpleKey("5")));
}
@Test
public void testContainsKey() {
Map<SimpleKey, SimpleValue> map = redisson.getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
map.put(new SimpleKey("33"), new SimpleValue("44"));
map.put(new SimpleKey("5"), new SimpleValue("6"));
Assert.assertTrue(map.containsKey(new SimpleKey("33")));
Assert.assertFalse(map.containsKey(new SimpleKey("34")));
}
@Test
public void testRemoveValue() {
ConcurrentMap<SimpleKey, SimpleValue> map = redisson.getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
boolean res = map.remove(new SimpleKey("1"), new SimpleValue("2"));
Assert.assertTrue(res);
SimpleValue val1 = map.get(new SimpleKey("1"));
Assert.assertNull(val1);
Assert.assertEquals(0, map.size());
}
@Test
public void testRemoveValueFail() {
ConcurrentMap<SimpleKey, SimpleValue> map = redisson.getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
boolean res = map.remove(new SimpleKey("2"), new SimpleValue("1"));
Assert.assertFalse(res);
boolean res1 = map.remove(new SimpleKey("1"), new SimpleValue("3"));
Assert.assertFalse(res1);
SimpleValue val1 = map.get(new SimpleKey("1"));
Assert.assertEquals("2", val1.getValue());
}
@Test
public void testReplaceOldValueFail() {
ConcurrentMap<SimpleKey, SimpleValue> map = redisson.getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
boolean res = map.replace(new SimpleKey("1"), new SimpleValue("43"), new SimpleValue("31"));
Assert.assertFalse(res);
SimpleValue val1 = map.get(new SimpleKey("1"));
Assert.assertEquals("2", val1.getValue());
}
@Test
public void testReplaceOldValueSuccess() {
ConcurrentMap<SimpleKey, SimpleValue> map = redisson.getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
boolean res = map.replace(new SimpleKey("1"), new SimpleValue("2"), new SimpleValue("3"));
Assert.assertTrue(res);
boolean res1 = map.replace(new SimpleKey("1"), new SimpleValue("2"), new SimpleValue("3"));
Assert.assertFalse(res1);
SimpleValue val1 = map.get(new SimpleKey("1"));
Assert.assertEquals("3", val1.getValue());
}
@Test
public void testReplaceValue() {
ConcurrentMap<SimpleKey, SimpleValue> map = redisson.getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
SimpleValue res = map.replace(new SimpleKey("1"), new SimpleValue("3"));
Assert.assertEquals("2", res.getValue());
SimpleValue val1 = map.get(new SimpleKey("1"));
Assert.assertEquals("3", val1.getValue());
}
@Test
public void testReplace() {
Map<SimpleKey, SimpleValue> map = redisson.getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
map.put(new SimpleKey("33"), new SimpleValue("44"));
map.put(new SimpleKey("5"), new SimpleValue("6"));
SimpleValue val1 = map.get(new SimpleKey("33"));
Assert.assertEquals("44", val1.getValue());
map.put(new SimpleKey("33"), new SimpleValue("abc"));
SimpleValue val2 = map.get(new SimpleKey("33"));
Assert.assertEquals("abc", val2.getValue());
}
@Test
public void testPutGet() {
Map<SimpleKey, SimpleValue> map = redisson.getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
map.put(new SimpleKey("33"), new SimpleValue("44"));
map.put(new SimpleKey("5"), new SimpleValue("6"));
SimpleValue val1 = map.get(new SimpleKey("33"));
Assert.assertEquals("44", val1.getValue());
SimpleValue val2 = map.get(new SimpleKey("5"));
Assert.assertEquals("6", val2.getValue());
}
@Test
public void testPutIfAbsent() throws Exception {
ConcurrentMap<SimpleKey, SimpleValue> map = redisson.getMap("simple");
SimpleKey key = new SimpleKey("1");
SimpleValue value = new SimpleValue("2");
map.put(key, value);
Assert.assertEquals(value, map.putIfAbsent(key, new SimpleValue("3")));
Assert.assertEquals(value, map.get(key));
SimpleKey key1 = new SimpleKey("2");
SimpleValue value1 = new SimpleValue("4");
Assert.assertNull(map.putIfAbsent(key1, value1));
Assert.assertEquals(value1, map.get(key1));
}
@Test
public void testFastPutIfAbsent() throws Exception {
RMap<SimpleKey, SimpleValue> map = redisson.getMap("simple");
SimpleKey key = new SimpleKey("1");
SimpleValue value = new SimpleValue("2");
map.put(key, value);
assertThat(map.fastPutIfAbsent(key, new SimpleValue("3"))).isFalse();
assertThat(map.get(key)).isEqualTo(value);
SimpleKey key1 = new SimpleKey("2");
SimpleValue value1 = new SimpleValue("4");
assertThat(map.fastPutIfAbsent(key1, value1)).isTrue();
assertThat(map.get(key1)).isEqualTo(value1);
}
@Test
public void testSize() {
Map<SimpleKey, SimpleValue> map = redisson.getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
map.put(new SimpleKey("3"), new SimpleValue("4"));
map.put(new SimpleKey("5"), new SimpleValue("6"));
Assert.assertEquals(3, map.size());
map.put(new SimpleKey("1"), new SimpleValue("2"));
map.put(new SimpleKey("3"), new SimpleValue("4"));
Assert.assertEquals(3, map.size());
map.put(new SimpleKey("1"), new SimpleValue("21"));
map.put(new SimpleKey("3"), new SimpleValue("41"));
Assert.assertEquals(3, map.size());
map.put(new SimpleKey("51"), new SimpleValue("6"));
Assert.assertEquals(4, map.size());
map.remove(new SimpleKey("3"));
Assert.assertEquals(3, map.size());
}
@Test
public void testEmptyRemove() {
RMap<Integer, Integer> map = redisson.getMap("simple");
Assert.assertFalse(map.remove(1, 3));
map.put(4, 5);
Assert.assertTrue(map.remove(4, 5));
}
@Test
public void testPutAsync() throws InterruptedException, ExecutionException {
RMap<Integer, Integer> map = redisson.getMap("simple");
RFuture<Integer> future = map.putAsync(2, 3);
Assert.assertNull(future.get());
Assert.assertEquals((Integer) 3, map.get(2));
RFuture<Integer> future1 = map.putAsync(2, 4);
Assert.assertEquals((Integer) 3, future1.get());
Assert.assertEquals((Integer) 4, map.get(2));
}
@Test
public void testRemoveAsync() throws InterruptedException, ExecutionException {
RMap<Integer, Integer> map = redisson.getMap("simple");
map.put(1, 3);
map.put(3, 5);
map.put(7, 8);
assertThat(map.removeAsync(1).get()).isEqualTo(3);
assertThat(map.removeAsync(3).get()).isEqualTo(5);
assertThat(map.removeAsync(10).get()).isNull();
assertThat(map.removeAsync(7).get()).isEqualTo(8);
}
@Test
public void testFastRemoveAsync() throws InterruptedException, ExecutionException {
RMap<Integer, Integer> map = redisson.getMap("simple");
map.put(1, 3);
map.put(3, 5);
map.put(4, 6);
map.put(7, 8);
CountDownLatch l = new CountDownLatch(1);
RFuture<Long> future = map.fastRemoveAsync(1, 3, 7);
future.handle((r, ex) -> {
assertThat(r).isEqualTo(3);
l.countDown();
return this;
});
assertThat(future.get()).isEqualTo(3);
assertThat(map.size()).isEqualTo(1);
}
@Test
public void testKeyIterator() {
RMap<Integer, Integer> map = redisson.getMap("simple");
@ -782,91 +106,4 @@ public class RedissonMapTest extends BaseMapTest {
assertThat(keys.size()).isEqualTo(0);
}
@Test
public void testValueIterator() {
RMap<Integer, Integer> map = redisson.getMap("simple");
map.put(1, 0);
map.put(3, 5);
map.put(4, 6);
map.put(7, 8);
Collection<Integer> values = map.values();
assertThat(values).containsOnly(0, 5, 6, 8);
for (Iterator<Integer> iterator = map.values().iterator(); iterator.hasNext();) {
Integer value = iterator.next();
if (!values.remove(value)) {
Assert.fail();
}
}
assertThat(values.size()).isEqualTo(0);
}
@Test
public void testFastPut() throws Exception {
RMap<Integer, Integer> map = redisson.getMap("simple");
Assert.assertTrue(map.fastPut(1, 2));
Assert.assertFalse(map.fastPut(1, 3));
Assert.assertEquals(1, map.size());
}
@Test
public void testEquals() {
RMap<String, String> map = redisson.getMap("simple");
map.put("1", "7");
map.put("2", "4");
map.put("3", "5");
Map<String, String> testMap = new HashMap<String, String>();
testMap.put("1", "7");
testMap.put("2", "4");
testMap.put("3", "5");
assertThat(map).isEqualTo(testMap);
assertThat(testMap.hashCode()).isEqualTo(map.hashCode());
}
@Test
public void testFastRemoveEmpty() throws Exception {
RMap<Integer, Integer> map = redisson.getMap("simple");
map.put(1, 3);
assertThat(map.fastRemove()).isZero();
assertThat(map.size()).isEqualTo(1);
}
@Test(timeout = 5000)
public void testDeserializationErrorReturnsErrorImmediately() throws Exception {
redisson.getConfig().setCodec(new JsonJacksonCodec());
RMap<String, SimpleObjectWithoutDefaultConstructor> map = redisson.getMap("deserializationFailure");
SimpleObjectWithoutDefaultConstructor object = new SimpleObjectWithoutDefaultConstructor("test-val");
Assert.assertEquals("test-val", object.getTestField());
map.put("test-key", object);
try {
map.get("test-key");
Assert.fail("Expected exception from map.get() call");
} catch (Exception e) {
e.printStackTrace();
}
}
public static class SimpleObjectWithoutDefaultConstructor {
private String testField;
SimpleObjectWithoutDefaultConstructor(String testField) {
this.testField = testField;
}
public String getTestField() {
return testField;
}
public void setTestField(String testField) {
this.testField = testField;
}
}
}

Loading…
Cancel
Save