Add putIfAbsent on Cache abstraction
This commit adds a putIfAbsent method to the Cache interface. This method offers an atomic put if the key is not already associated in the cache. Issue: SPR-11400
This commit is contained in:
@@ -80,6 +80,33 @@ public interface Cache {
|
||||
*/
|
||||
void put(Object key, Object value);
|
||||
|
||||
/**
|
||||
* Atomically associate the specified value with the specified key in this cache if
|
||||
* it is not set already.
|
||||
* <p>This is equivalent to:
|
||||
* <pre><code>
|
||||
* Object existingValue = cache.get(key);
|
||||
* if (existingValue == null) {
|
||||
* cache.put(key, value);
|
||||
* return null;
|
||||
* } else {
|
||||
* return existingValue;
|
||||
* }
|
||||
* </code></pre>
|
||||
* except that the action is performed atomically. While all known providers are
|
||||
* able to perform the put atomically, the returned value may be retrieved after
|
||||
* the attempt to put (i.e. in a non atomic way). Check the documentation of
|
||||
* the native cache implementation that you are using for more details.
|
||||
* @param key the key with which the specified value is to be associated
|
||||
* @param value the value to be associated with the specified key
|
||||
* @return the value to which this cache maps the specified key (which may
|
||||
* be {@code null} itself), or also {@code null} if the cache did not contain
|
||||
* any mapping for that key prior to this call. Returning {@code null} is
|
||||
* therefore an indicator that the given {@code value} has been associated
|
||||
* with the key
|
||||
*/
|
||||
ValueWrapper putIfAbsent(Object key, Object value);
|
||||
|
||||
/**
|
||||
* Evict the mapping for this key from this cache if it is present.
|
||||
* @param key the key whose mapping is to be removed from the cache
|
||||
|
||||
@@ -103,7 +103,7 @@ public class ConcurrentMapCache implements Cache {
|
||||
@Override
|
||||
public ValueWrapper get(Object key) {
|
||||
Object value = this.store.get(key);
|
||||
return (value != null ? new SimpleValueWrapper(fromStoreValue(value)) : null);
|
||||
return toWrapper(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -121,6 +121,12 @@ public class ConcurrentMapCache implements Cache {
|
||||
this.store.put(key, toStoreValue(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueWrapper putIfAbsent(Object key, Object value) {
|
||||
Object existing = this.store.putIfAbsent(key, value);
|
||||
return toWrapper(existing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void evict(Object key) {
|
||||
this.store.remove(key);
|
||||
@@ -158,6 +164,9 @@ public class ConcurrentMapCache implements Cache {
|
||||
return userValue;
|
||||
}
|
||||
|
||||
private ValueWrapper toWrapper(Object value) {
|
||||
return (value != null ? new SimpleValueWrapper(fromStoreValue(value)) : null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
private static class NullHolder implements Serializable {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -34,6 +34,7 @@ import org.springframework.cache.CacheManager;
|
||||
* <p>Will simply accept any items into the cache not actually storing them.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author Stephane Nicoll
|
||||
* @since 3.1
|
||||
* @see CompositeCacheManager
|
||||
*/
|
||||
@@ -111,6 +112,11 @@ public class NoOpCacheManager implements CacheManager {
|
||||
@Override
|
||||
public void put(Object key, Object value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueWrapper putIfAbsent(Object key, Object value) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user