diff --git a/src/main/java/org/redisson/RedissonListMultimap.java b/src/main/java/org/redisson/RedissonListMultimap.java index d2e9db44e..5fd88ac8e 100644 --- a/src/main/java/org/redisson/RedissonListMultimap.java +++ b/src/main/java/org/redisson/RedissonListMultimap.java @@ -65,6 +65,8 @@ public class RedissonListMultimap extends RedissonMultimap implement "return size; ", Arrays.asList(getName())); } + + public Future containsKeyAsync(Object key) { try { diff --git a/src/main/java/org/redisson/RedissonMultimap.java b/src/main/java/org/redisson/RedissonMultimap.java index 602fa3cec..0d02efcf0 100644 --- a/src/main/java/org/redisson/RedissonMultimap.java +++ b/src/main/java/org/redisson/RedissonMultimap.java @@ -66,6 +66,11 @@ public abstract class RedissonMultimap extends RedissonExpirable implement public int size() { return get(sizeAsync()); } + + @Override + public int keySize() { + return get(keySizeAsync()); + } @Override public boolean isEmpty() { @@ -237,8 +242,12 @@ public abstract class RedissonMultimap extends RedissonExpirable implement "return redis.call('persist', KEYS[1]); ", Arrays.asList(getName())); } - - + + public Future keySizeAsync() { + return commandExecutor.readAsync(getName(), LongCodec.INSTANCE, RedisCommands.HLEN, getName()); + } + + MapScanResult scanIterator(InetSocketAddress client, long startPos) { Future> f = commandExecutor.readAsync(client, getName(), new ScanCodec(codec, StringCodec.INSTANCE), RedisCommands.HSCAN, getName(), startPos); return get(f); @@ -272,7 +281,7 @@ public abstract class RedissonMultimap extends RedissonExpirable implement @Override public int size() { - return RedissonMultimap.this.size(); + return RedissonMultimap.this.keySize(); } @Override diff --git a/src/main/java/org/redisson/RedissonSetMultimap.java b/src/main/java/org/redisson/RedissonSetMultimap.java index 3989bb762..74ee7a333 100644 --- a/src/main/java/org/redisson/RedissonSetMultimap.java +++ b/src/main/java/org/redisson/RedissonSetMultimap.java @@ -69,6 +69,8 @@ public class RedissonSetMultimap extends RedissonMultimap implements Arrays.asList(getName())); } + + public Future containsKeyAsync(Object key) { try { byte[] keyState = codec.getMapKeyEncoder().encode(key); diff --git a/src/main/java/org/redisson/connection/MasterSlaveEntry.java b/src/main/java/org/redisson/connection/MasterSlaveEntry.java index 0fe9871a0..1e3cdefff 100644 --- a/src/main/java/org/redisson/connection/MasterSlaveEntry.java +++ b/src/main/java/org/redisson/connection/MasterSlaveEntry.java @@ -291,8 +291,10 @@ public class MasterSlaveEntry { this.config.getSlaveSubscriptionConnectionMinimumIdleSize(), this.config.getSlaveSubscriptionConnectionPoolSize(), connectionManager, mode); if (freezed) { - entry.setFreezed(freezed); - entry.setFreezeReason(FreezeReason.SYSTEM); + synchronized (entry) { + entry.setFreezed(freezed); + entry.setFreezeReason(FreezeReason.SYSTEM); + } } return slaveBalancer.add(entry); } @@ -350,8 +352,10 @@ public class MasterSlaveEntry { public void unfreeze() { masterEntry.resetFailedAttempts(); - masterEntry.setFreezed(false); - masterEntry.setFreezeReason(null); + synchronized (masterEntry) { + masterEntry.setFreezed(false); + masterEntry.setFreezeReason(null); + } } public void shutdownMasterAsync() { diff --git a/src/main/java/org/redisson/core/RMultimap.java b/src/main/java/org/redisson/core/RMultimap.java index 7f39b53ce..338bcc9c6 100644 --- a/src/main/java/org/redisson/core/RMultimap.java +++ b/src/main/java/org/redisson/core/RMultimap.java @@ -162,6 +162,11 @@ public interface RMultimap extends RExpirable, RMultimapAsync { * vice versa. However, adding to the returned set is not possible. */ Set keySet(); + + /** + * Returns the count of distinct keys in this multimap. + */ + int keySize(); /** * Returns a view collection containing the value from each key-value diff --git a/src/main/java/org/redisson/core/RMultimapAsync.java b/src/main/java/org/redisson/core/RMultimapAsync.java index 5c64da558..b9710df71 100644 --- a/src/main/java/org/redisson/core/RMultimapAsync.java +++ b/src/main/java/org/redisson/core/RMultimapAsync.java @@ -123,6 +123,14 @@ public interface RMultimapAsync extends RExpirableAsync { Future> removeAllAsync(Object key); Future> getAllAsync(K key); + + + /** + * Returns the number of key-value pairs in this multimap. + * + * @return + */ + Future keySizeAsync(); /** * Removes keys from map by one operation diff --git a/src/main/java/org/redisson/spring/cache/RedissonCache.java b/src/main/java/org/redisson/spring/cache/RedissonCache.java index 5c17e466d..31efe95a9 100644 --- a/src/main/java/org/redisson/spring/cache/RedissonCache.java +++ b/src/main/java/org/redisson/spring/cache/RedissonCache.java @@ -17,13 +17,8 @@ package org.redisson.spring.cache; import java.io.IOException; import java.lang.reflect.Constructor; -import java.util.Map; import java.util.concurrent.Callable; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; import java.util.concurrent.TimeUnit; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; import org.redisson.RedissonClient; import org.redisson.core.RLock; @@ -40,8 +35,6 @@ import org.springframework.cache.support.SimpleValueWrapper; */ public class RedissonCache implements Cache { - private final ConcurrentMap valueLoaderLocks = new ConcurrentHashMap(); - private RMapCache mapCache; private final RMap map; @@ -130,18 +123,6 @@ public class RedissonCache implements Cache { return new SimpleValueWrapper(value); } - public Lock getLock(Object key) { - Lock lock = valueLoaderLocks.get(key); - if (lock == null) { - Lock newlock = new ReentrantLock(); - lock = valueLoaderLocks.putIfAbsent(key, newlock); - if (lock == null) { - lock = newlock; - } - } - return lock; - } - public T get(Object key, Callable valueLoader) { Object value = map.get(key); if (value == null) { diff --git a/src/test/java/org/redisson/RedissonListMultimapTest.java b/src/test/java/org/redisson/RedissonListMultimapTest.java index e6f6eeec0..b541bd405 100644 --- a/src/test/java/org/redisson/RedissonListMultimapTest.java +++ b/src/test/java/org/redisson/RedissonListMultimapTest.java @@ -131,6 +131,23 @@ public class RedissonListMultimapTest extends BaseTest { assertThat(s).isEmpty(); assertThat(map.size()).isEqualTo(1); } + + @Test + public void testKeySize() { + RListMultimap map = redisson.getListMultimap("test1"); + map.put(new SimpleKey("0"), new SimpleValue("1")); + map.put(new SimpleKey("0"), new SimpleValue("2")); + map.put(new SimpleKey("1"), new SimpleValue("4")); + + assertThat(map.keySize()).isEqualTo(2); + + assertThat(map.fastRemove(new SimpleKey("0"))).isEqualTo(1); + + List s = map.get(new SimpleKey("0")); + assertThat(s).isEmpty(); + assertThat(map.size()).isEqualTo(1); + } + @Test public void testPut() { diff --git a/src/test/java/org/redisson/RedissonSetMultimapTest.java b/src/test/java/org/redisson/RedissonSetMultimapTest.java index c30256c53..8780503a0 100644 --- a/src/test/java/org/redisson/RedissonSetMultimapTest.java +++ b/src/test/java/org/redisson/RedissonSetMultimapTest.java @@ -131,6 +131,22 @@ public class RedissonSetMultimapTest extends BaseTest { assertThat(s).isEmpty(); assertThat(map.size()).isEqualTo(0); } + + @Test + public void testKeySize() { + RSetMultimap map = redisson.getSetMultimap("test1"); + map.put(new SimpleKey("0"), new SimpleValue("1")); + map.put(new SimpleKey("0"), new SimpleValue("2")); + map.put(new SimpleKey("1"), new SimpleValue("3")); + + assertThat(map.size()).isEqualTo(2); + + map.fastRemove(new SimpleKey("0")); + + Set s = map.get(new SimpleKey("0")); + assertThat(s).isEmpty(); + assertThat(map.size()).isEqualTo(1); + } @Test public void testPut() {