Class LoadingMap<K,​V>

  • Type Parameters:
    K -
    V -

    public class LoadingMap<K,​V>
    extends java.lang.Object
    An extension of NonBlockingHashMap where all values are wrapped by Future.

    The main purpose of this class is to provide the functionality of concurrent hash map which may perform operations like ConcurrentHashMap.computeIfAbsent(Object, Function) and ConcurrentHashMap.computeIfPresent(Object, BiFunction) with synchronization scope reduced to the single key - that is, when dealing with a single key, unlike ConcurrentHashMap 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 of ConcurrentHashMap 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.

    • 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.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Constructor Detail

      • LoadingMap

        public LoadingMap()
    • 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 returns null 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 returns null, 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 to blockingLoadIfAbsent(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 returns null.

        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