Package ghidra.async

# Class AsyncLazyMap<K,V>

java.lang.Object
ghidra.async.AsyncLazyMap<K,V>

Type Parameters:
  `K` - the type of keys
  `V` - the type of values

public class AsyncLazyMap<K,V> extends Object
A map of cached values computed upon the first request, asynchronously

Each key present in the cache behaves similarly to `AsyncLazyValue`. The cache starts empty. Whenever a key is requested, a computation for that key is started, but a future is immediately returned. If the computation succeeds, the completed future is cached indefinitely, and the result is recorded. Any subsequent requests for the same key return the same future, even if the computation for that key has not yet completed. Thus, when it completes, all requests for that key will be fulfilled by the result of the first request. If the computation completes exceptionally, the key is optionally removed from the cache. Thus, a subsequent request for a failed key may retry the computation.

Values can also be provided "out of band." That is, they may be provided by an alternative computation. This is accomplished using `get(Object, Function)`, `put(Object)` or `put(Object, Object)`. The last immediately provides a value and completes any outstanding requests, even if there was an active computation for the key. The first claims the key and promises to provide the value at a later time.

At any point, an unmodifiable view of the completed, cached values may be obtained.

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Class
  Description
  `static class`
  `AsyncLazyMap.KeyedFuture<K,V>`

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `protected BiPredicate<? super K,? super Throwable>`
  `forgetErrors`
  `protected BiPredicate<? super K,? super V>`
  `forgetValues`
  `protected final Function<K,CompletableFuture<V>>`
  `function`
  `protected final Map<K,AsyncLazyMap.KeyedFuture<K,V>>`
  `futures`
  `protected final Map<K,V>`
  `map`
  `protected final Map<K,V>`
  `unmodifiable`

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `AsyncLazyMap(Map<K,V> map, Function<K,CompletableFuture<V>> function)`
  Construct a lazy map for the given function

- ## Method Summary

  Modifier and Type
  Method
  Description
  `void`
  `clear()`
  Clear the lazy map, including pending requests
  `boolean`
  `containsKey(K key)`
  Check if a given key is in the map, pending or completed
  `CompletableFuture<V>`
  `forget(K key)`
  Remove a key from the map, without canceling any pending computation
  `AsyncLazyMap<K,V>`
  `forgetErrors(BiPredicate<? super K,? super Throwable> predicate)`
  Sets a predicate to determine which errors to forget (i.e., retry)
  `AsyncLazyMap<K,V>`
  `forgetValues(BiPredicate<? super K,? super V> predicate)`
  Sets a predicate to determine which values to forget
  `AsyncLazyMap.KeyedFuture<K,V>`
  `get(K key)`
  Request the value for a given key
  `AsyncLazyMap.KeyedFuture<K,V>`
  `get(K key, Function<K,CompletableFuture<V>> func)`
  Request the value for a given key, using an alternative computation
  `Map<K,V>`
  `getCompletedMap()`
  Get a view of completed keys with values
  `Set<K>`
  `getPendingKeySet()`
  Get a copy of the keys which are requested but not completed
  `AsyncLazyMap.KeyedFuture<K,V>`
  `put(K key)`
  Provide an out-of-band value for a given key
  `boolean`
  `put(K key, V value)`
  Immediately provide an out-of-band value for a given key
  `protected void`
  `putFuture(K key, AsyncLazyMap.KeyedFuture<K,V> future)`
  `AsyncLazyMap<K,V>`
  `rememberErrors(BiPredicate<? super K,? super Throwable> predicate)`
  Sets a predicate to determine which errors to remember
  `AsyncLazyMap<K,V>`
  `rememberValues(BiPredicate<? super K,? super V> predicate)`
  Sets a predicate to determine which values to remember
  `V`
  `remove(K key)`
  Remove a key from the map, canceling any pending computation
  `void`
  `retainKeys(Collection<K> keys)`
  Retain only those entries whose keys appear in the given collection

  ### Methods inherited from class java.lang.Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- ## Field Details

  - ### futures

    protected final Map<K,AsyncLazyMap.KeyedFuture<K,V>> futures

  - ### map

    protected final Map<K,V> map

  - ### unmodifiable

    protected final Map<K,V> unmodifiable

  - ### function

    protected final Function<K,CompletableFuture<V>> function

  - ### forgetErrors

    protected BiPredicate<? super K,? super Throwable> forgetErrors

  - ### forgetValues

    protected BiPredicate<? super K,? super V> forgetValues

- ## Constructor Details

  - ### AsyncLazyMap

    public AsyncLazyMap(Map<K,V> map, Function<K,CompletableFuture<V>> function)
    Construct a lazy map for the given function
    Parameters:
      `map` - the backing map. The lazy map ought to have an exclusive reference to this map. Mutations to the map outside of those caused by the lazy map may cause undefined behavior.
      `function` - specifies the computation, given a key

- ## Method Details

  - ### putFuture

    protected void putFuture(K key, AsyncLazyMap.KeyedFuture<K,V> future)

  - ### forgetErrors

    public AsyncLazyMap<K,V> forgetErrors(BiPredicate<? super K,? super Throwable> predicate)
    Sets a predicate to determine which errors to forget (i.e., retry)

    A request resulting in an error that is remembered will not be retried until the cache is invalidated. For a forgotten error, the request is retried if re-requested later.

    This will replace the behavior of any previous error-testing predicate.

    Parameters:
      `predicate` - the predicate
    Returns:
      this lazy map

  - ### rememberErrors

    public AsyncLazyMap<K,V> rememberErrors(BiPredicate<? super K,? super Throwable> predicate)
    Sets a predicate to determine which errors to remember
    Parameters:
      `predicate` - the predicate
    Returns:
      this lazy map
    See Also:
      - `forgetErrors(BiPredicate)`

  - ### forgetValues

    public AsyncLazyMap<K,V> forgetValues(BiPredicate<? super K,? super V> predicate)
    Sets a predicate to determine which values to forget

    The predicate is applied to a cached entry when its key is re-requested. If forgotten, the request will launch a fresh computation. The predicate is also applied at the time a computation is completed. An entry that is forgotten still completes normally; however, it never enters the cache, thus a subsequent request for the same key will launch a fresh computation.

    This will replace the behavior of any previous value-testing predicate.

    Parameters:
      `predicate` - the rule for forgetting entries
    Returns:
      this lazy map

  - ### rememberValues

    public AsyncLazyMap<K,V> rememberValues(BiPredicate<? super K,? super V> predicate)
    Sets a predicate to determine which values to remember
    Parameters:
      `predicate` - the rule for not forgetting entries
    Returns:
      this lazy map
    See Also:
      - `forgetValues(BiPredicate)`

  - ### get

    public AsyncLazyMap.KeyedFuture<K,V> get(K key, Function<K,CompletableFuture<V>> func)
    Request the value for a given key, using an alternative computation

    If this is called before any other get or put, the given function is launched for the given key. A `CompletableFuture` is returned immediately. Subsequent gets or puts on the same key will return the same future without starting any new computation.

    Parameters:
      `key` - the key
      `func` - an alternative computation function, given a key
    Returns:
      a future, possibly already completed, for the key's value

  - ### get

    public AsyncLazyMap.KeyedFuture<K,V> get(K key)
    Request the value for a given key

    If this is called before any other get or put, the computation given at construction is launched for the given key. A `CompletableFuture` is returned immediately. Subsequent calls gets or puts on the same key return the same future without starting any new computation.

    Parameters:
      `key` - the key
    Returns:
      a future, possible already completed, for the key's value

  - ### put

    public boolean put(K key, V value)
    Immediately provide an out-of-band value for a given key

    On occasion, the value for a key may become known outside of the specified computation. This method circumvents the function given during construction by providing the value for a key. If there is an outstanding request for the key's value -- a rare occasion -- it is completed immediately with the provided value. Calling this method for a key that has already completed has no effect.

    This is equivalent to the code `map.put(k).complete(value)`, but atomic.

    Parameters:
      `key` - the key whose value to provide
      `value` - the provided value
    Returns:
      true if the key was completed by this call, false if the key had already been completed

  - ### put

    public AsyncLazyMap.KeyedFuture<K,V> put(K key)
    Provide an out-of-band value for a given key

    If this is called before `get(Object)`, the computation given at construction is ignored for the given key. A new `CompletableFuture` is returned instead. The caller must see to this future's completion. Subsequent calls to either `get(Object)` or `put(Object)` on the same key return this same future without starting any computation.

    Under normal circumstances, the caller cannot determine whether or not it has "claimed" the computation for the key. If the usual computation is already running, then the computations are essentially in a race. As such, it is essential that alternative computations result in the same value for a given key as the usual computation. In other words, the functions must not differ, but the means of computation can differ. Otherwise, race conditions may arise.

    Parameters:
      `key` - the key whose value to provide
    Returns:
      a promise that the caller must fulfill or arrange to have fulfilled

  - ### forget

    public CompletableFuture<V> forget(K key)
    Remove a key from the map, without canceling any pending computation

    If the removed future has not yet completed, its value will never be added to the map of values. Subsequent gets or puts to the invalidated key will behave as if the key had never been requested.

    Parameters:
      `key` - the key to remove
    Returns:
      the invalidated future

  - ### remove

    public V remove(K key)
    Remove a key from the map, canceling any pending computation
    Parameters:
      `key` - the key to remove
    Returns:
      the previous value, if completed

  - ### getCompletedMap

    public Map<K,V> getCompletedMap()
    Get a view of completed keys with values

    The view is unmodifiable, but the backing map may still be modified as more keys are completed. Thus, access to the view ought to be synchronized on this lazy map.

    Returns:
      a map view of keys to values

  - ### getPendingKeySet

    public Set<K> getPendingKeySet()
    Get a copy of the keys which are requested but not completed

    This should only be used for diagnostics.

    Returns:
      a copy of the pending key set

  - ### clear

    public void clear()
    Clear the lazy map, including pending requests

    Pending requests will be cancelled

  - ### retainKeys

    public void retainKeys(Collection<K> keys)
    Retain only those entries whose keys appear in the given collection

    All removed entries with pending computations will be canceled

    Parameters:
      `keys` - the keys to retain

  - ### containsKey

    public boolean containsKey(K key)
    Check if a given key is in the map, pending or completed
    Parameters:
      `key` - the key to check
    Returns:
      true if present, false otherwise