implements RMapCac
Collections.singletonList(optionsName), maxSize, mode);
}
+ @Override
+ public V computeIfAbsent(K key, Duration ttl, Function super K, ? extends V> mappingFunction) {
+ checkNotBatch();
+
+ checkKey(key);
+ Objects.requireNonNull(mappingFunction);
+
+ V value = get(key);
+ if (value != null) {
+ return value;
+ }
+ RLock lock = getLock(key);
+ lock.lock();
+ try {
+ value = get(key);
+ if (value == null) {
+ V newValue = mappingFunction.apply(key);
+ if (newValue != null) {
+ fastPut(key, newValue, ttl.toMillis(), TimeUnit.MILLISECONDS);
+ return newValue;
+ }
+ return null;
+ }
+ return value;
+ } finally {
+ lock.unlock();
+ }
+ }
+
@Override
public void setMaxSize(int maxSize) {
get(setMaxSizeAsync(maxSize));
diff --git a/redisson/src/main/java/org/redisson/api/RMapCache.java b/redisson/src/main/java/org/redisson/api/RMapCache.java
index 559980090..f3c31d0bc 100644
--- a/redisson/src/main/java/org/redisson/api/RMapCache.java
+++ b/redisson/src/main/java/org/redisson/api/RMapCache.java
@@ -23,6 +23,7 @@ import java.time.Duration;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
/**
* Map-based cache with ability to set TTL for each entry via
@@ -81,7 +82,20 @@ public interface RMapCache extends RMap, RMapCacheAsync {
* @return true
if max size has been successfully set, otherwise false
.
*/
boolean trySetMaxSize(int maxSize, EvictionMode mode);
-
+ /**
+ * If the specified key is not already associated
+ * with a value, attempts to compute its value using the given mapping function and enters it into this map .
+ *
+ * Stores value mapped by key with specified time to live.
+ * Entry expires after specified time to live.
+ *
+ * @param key - map key
+ * @param ttl - time to live for key\value entry.
+ * If 0
then stores infinitely.
+ * @param mappingFunction the mapping function to compute a value
+ * @return current associated value
+ */
+ V computeIfAbsent(K key, Duration ttl, Function super K, ? extends V> mappingFunction);
/**
* If the specified key is not already associated
* with a value, associate it with the given value.
diff --git a/redisson/src/main/java/org/redisson/api/RMapCacheReactive.java b/redisson/src/main/java/org/redisson/api/RMapCacheReactive.java
index 3ffafdd0f..937637b16 100644
--- a/redisson/src/main/java/org/redisson/api/RMapCacheReactive.java
+++ b/redisson/src/main/java/org/redisson/api/RMapCacheReactive.java
@@ -24,6 +24,7 @@ import java.time.Duration;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
/**
*
Map-based cache with ability to set TTL for each entry via
@@ -126,7 +127,20 @@ public interface RMapCacheReactive extends RMapReactive, RDestroyabl
* @return previous associated value
*/
Mono putIfAbsent(K key, V value, long ttl, TimeUnit ttlUnit, long maxIdleTime, TimeUnit maxIdleUnit);
-
+ /**
+ * If the specified key is not already associated
+ * with a value, attempts to compute its value using the given mapping function and enters it into this map .
+ *
+ * Stores value mapped by key with specified time to live.
+ * Entry expires after specified time to live.
+ *
+ * @param key - map key
+ * @param ttl - time to live for key\value entry.
+ * If 0
then stores infinitely.
+ * @param mappingFunction the mapping function to compute a value
+ * @return current associated value
+ */
+ Mono computeIfAbsentAsync(K key, Duration ttl, Function super K, ? extends V> mappingFunction);
/**
* Stores value mapped by key with specified time to live.
* Entry expires after specified time to live.
diff --git a/redisson/src/main/java/org/redisson/api/RMapCacheRx.java b/redisson/src/main/java/org/redisson/api/RMapCacheRx.java
index c65a81716..810391b22 100644
--- a/redisson/src/main/java/org/redisson/api/RMapCacheRx.java
+++ b/redisson/src/main/java/org/redisson/api/RMapCacheRx.java
@@ -26,6 +26,7 @@ import java.time.Duration;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
/**
* Map-based cache with ability to set TTL for each entry via
@@ -128,7 +129,20 @@ public interface RMapCacheRx extends RMapRx, RDestroyable {
* @return previous associated value
*/
Maybe putIfAbsent(K key, V value, long ttl, TimeUnit ttlUnit, long maxIdleTime, TimeUnit maxIdleUnit);
-
+ /**
+ * If the specified key is not already associated
+ * with a value, attempts to compute its value using the given mapping function and enters it into this map .
+ *
+ * Stores value mapped by key with specified time to live.
+ * Entry expires after specified time to live.
+ *
+ * @param key - map key
+ * @param ttl - time to live for key\value entry.
+ * If 0
then stores infinitely.
+ * @param mappingFunction the mapping function to compute a value
+ * @return current associated value
+ */
+ Maybe computeIfAbsentAsync(K key, Duration ttl, Function super K, ? extends V> mappingFunction);
/**
* Stores value mapped by key with specified time to live.
* Entry expires after specified time to live.
diff --git a/redisson/src/test/java/org/redisson/RedissonMapCacheTest.java b/redisson/src/test/java/org/redisson/RedissonMapCacheTest.java
index 3802e0e42..ab22cca34 100644
--- a/redisson/src/test/java/org/redisson/RedissonMapCacheTest.java
+++ b/redisson/src/test/java/org/redisson/RedissonMapCacheTest.java
@@ -1470,5 +1470,21 @@ public class RedissonMapCacheTest extends BaseMapTest {
map.destroy();
}
+
+ @Test
+ public void testComputeIfAbsentWithTTL() throws Exception{
+ RMapCache map = redisson.getMapCache("testMap");
+ map.delete();
+ Duration duration = Duration.ofSeconds(1);
+ String value = map.computeIfAbsent("key1",duration, (t1) -> "value1");
+ assertThat("value1".equals(value)).isTrue();
+ value = map.computeIfAbsent("key1", duration, (t1) -> "value2");
+ assertThat("value2".equals(value)).isFalse();
+ Thread.sleep(1100);
+ value = map.computeIfAbsent("key1", duration, (t1) -> "value3");
+ assertThat("value3".equals(value)).isTrue();
+ map.destroy();
+
+ }
}