Class LoadingMap<K,V>
- java.lang.Object
-
- org.apache.cassandra.utils.concurrent.LoadingMap<K,V>
-
- Type Parameters:
K
-V
-
public class LoadingMap<K,V> extends java.lang.Object
An extension ofNonBlockingHashMap
where all values are wrapped byFuture
.The main purpose of this class is to provide the functionality of concurrent hash map which may perform operations like
ConcurrentHashMap.computeIfAbsent(Object, Function)
andConcurrentHashMap.computeIfPresent(Object, BiFunction)
with synchronization scope reduced to the single key - that is, when dealing with a single key, unlikeConcurrentHashMap
we do not lock the whole map for the time the mapping function is running. This may help to avoid the case when we want to load/unload a value for a key K1 while loading/unloading a value for a key K2. Such scenario is forbidden in case ofConcurrentHashMap
and leads to a deadlock. On the other hand,NonBlockingHashMap
does not guarantee at-most-once semantics of running the mapping function for a single key.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
LoadingMap.UnloadExecutionException
Thrown when unloading a value failed.
-
Constructor Summary
Constructors Constructor Description LoadingMap()
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description V
blockingLoadIfAbsent(K key, java.util.function.Supplier<? extends V> loadFunction)
If the value for the given key is missing, execute a load function to obtain a value and put it into the map.V
blockingUnloadIfPresent(K key, java.util.function.Consumer<? super V> unloadFunction)
If a value for the given key is present, unload function is run and the value is removed from the map.V
getIfReady(K key)
Get a value for a given key.
-
-
-
Method Detail
-
getIfReady
public V getIfReady(K key)
Get a value for a given key. Returns a non-null object only if there is a successfully initialized value associated, with the provided key. It returnsnull
if there is no value for the key, or the value is being initialized or removed. It does not throw if the last attempt to initialize the value failed.
-
blockingLoadIfAbsent
public V blockingLoadIfAbsent(K key, java.util.function.Supplier<? extends V> loadFunction) throws java.lang.RuntimeException
If the value for the given key is missing, execute a load function to obtain a value and put it into the map. It is guaranteed that the loading and unloading a value for a single key are executed serially. It is also guaranteed that the load function is executed exactly once to load a value into the map (regardless of the concurrent attempts). In case there is a concurrent attempt to load a value for this key, this attempt waits until the concurrent attempt is done and returns its result (if succeeded). If the concurrent attempt fails, this attempt is retried. However, if this attempt fails, it is not retried and the exception is rethrown. In case there is a concurrent attempt to unload a value for this key, this attempt waits until the concurrent attempt is done and retries loading. When the mapping function returnsnull
,NullPointerException
is thrown. When the mapping function throws exception, it is rethrown by this method. In both cases nothing gets added to the map. It is allowed to nest loading for a different key, though nested loading for the same key results in a deadlock.- Throws:
java.lang.RuntimeException
-
blockingUnloadIfPresent
public V blockingUnloadIfPresent(K key, java.util.function.Consumer<? super V> unloadFunction) throws LoadingMap.UnloadExecutionException
If a value for the given key is present, unload function is run and the value is removed from the map. Similarly toblockingLoadIfAbsent(Object, Supplier)
at-most-once semantics is guaranteed for unload function. When unload function fails, the value is removed from the map anyway and the failure is rethrown. When the key was not found, the method returnsnull
.- Throws:
LoadingMap.UnloadExecutionException
- when the unloading failed to complete - this is checked exception because the value is removed from the map regardless of the result of unloading; therefore if the unloading failed, the caller is responsible for handling that
-
-