Class SoftReferenceCache

java.lang.Object
io.fluxzero.sdk.persisting.caching.SoftReferenceCache
All Implemented Interfaces:
Cache, AutoCloseable

public class SoftReferenceCache extends Object implements Cache, AutoCloseable
Cache implementation using key-level synchronized access and soft references for value storage.

This cache is optimized for concurrent environments and provides built-in support for:

  • Automatic eviction based on max size (LRU policy)
  • Reference-based eviction when values are no longer strongly reachable (via SoftReference)
  • Expiration after a configurable duration
  • Eviction notification via registered CacheEviction listeners

The cache ensures thread safety through synchronized access on its internal LinkedHashMap and striped locking for computations. Equal keys always use the same stripe, preserving atomic updates without allocating or globally interning a lock value for every cache operation.

Threading: Eviction listeners and expiration polling run on background threads. The valueMap itself is backed by a synchronized LinkedHashMap with LRU eviction behavior.

See Also:
  • Constructor Details

    • SoftReferenceCache

      public SoftReferenceCache()
      Constructs a cache with a default maximum size of 1,000,000 entries and no expiration.
    • SoftReferenceCache

      public SoftReferenceCache(int maxSize)
      Constructs a cache with a specified max size and no expiration.
    • SoftReferenceCache

      public SoftReferenceCache(int maxSize, Duration expiry)
      Constructs a cache with specified size and expiration. Uses a single-threaded executor for eviction notifications.
    • SoftReferenceCache

      public SoftReferenceCache(int maxSize, Executor evictionNotifier, Duration expiry)
      Constructs a cache with specified size, executor for eviction notifications and expiration.
    • SoftReferenceCache

      public SoftReferenceCache(int maxSize, Executor evictionNotifier, Duration expiry, Duration expiryCheckDelay, boolean softReferences)
      Constructs a cache with full configuration of size, eviction executor, expiration delay, and expiration check frequency.
    • SoftReferenceCache

      protected SoftReferenceCache(int maxSize, Executor evictionNotifier, Duration expiry, Duration expiryCheckDelay, boolean softReferences, Clock clock)
  • Method Details

    • compute

      public <T> T compute(Object id, BiFunction<? super Object, ? super T, ? extends T> mappingFunction)
      Returns a synchronized computation that adds, removes, or updates a cache entry. A fixed hash stripe preserves per-key atomicity without allocating and globally interning a mutex String for every cache operation.
      Specified by:
      compute in interface Cache
      Type Parameters:
      T - the expected type of the value
      Parameters:
      id - the key to compute for
      mappingFunction - the function to compute a new value
      Returns:
      the newly computed value, or null if the mapping function returned null
    • mergeAll

      public <T> void mergeAll(Map<?, ? extends T> values, BiFunction<? super T, ? super T, ? extends T> mergeFunction)
      Description copied from interface: Cache
      Merges a bounded group of candidate values into this cache.

      The default implementation preserves the ordinary per-key Cache.compute(Object, BiFunction) contract. Implementations may override this method to reduce lock transitions while retaining the same per-key merge semantics. The group as a whole is not an atomic transaction.

      Specified by:
      mergeAll in interface Cache
      Type Parameters:
      T - value type
      Parameters:
      values - candidate value by cache key
      mergeFunction - selects the retained value from the current and candidate value
    • updateAll

      public <T> void updateAll(Map<?, ? extends Function<? super T, ? extends T>> updates)
      Description copied from interface: Cache
      Applies independent per-key update functions as one bounded cache operation.

      The default implementation preserves the ordinary per-key Cache.compute(Object, BiFunction) contract. Implementations may override this method to amortize shared bookkeeping or lock transitions. The group as a whole is not an atomic transaction.

      Specified by:
      updateAll in interface Cache
      Type Parameters:
      T - value type
      Parameters:
      updates - update function by cache key
    • modifyEach

      public <T> void modifyEach(BiFunction<? super Object, ? super T, ? extends T> modifierFunction)
      Description copied from interface: Cache
      Applies the given modifier function to all values currently in the cache.

      This is useful for bulk modifications, e.g. adjusting internal state after a system-wide change.

      Specified by:
      modifyEach in interface Cache
      Type Parameters:
      T - the expected type of the values
      Parameters:
      modifierFunction - the function to apply to each entry
    • put

      public Object put(Object id, Object value)
      Description copied from interface: Cache
      Puts a value in the cache for the given id, overwriting any existing value.
      Specified by:
      put in interface Cache
      Parameters:
      id - the key with which the specified value is to be associated
      value - the value to be associated with the specified key
      Returns:
      the previous value associated with the id, or null if none
    • putIfAbsent

      public Object putIfAbsent(Object id, Object value)
      Description copied from interface: Cache
      Associates the specified value with the given id only if no value is currently associated.
      Specified by:
      putIfAbsent in interface Cache
      Parameters:
      id - the key to check for presence
      value - the value to associate if absent
      Returns:
      the existing value associated with the key, or null if the new value was successfully put
    • computeIfAbsent

      public <T> T computeIfAbsent(Object id, Function<? super Object, T> mappingFunction)
      Description copied from interface: Cache
      If a value is not already associated with the given id, computes and stores one using the given function.
      Specified by:
      computeIfAbsent in interface Cache
      Type Parameters:
      T - the expected type of the value
      Parameters:
      id - the key to check or compute
      mappingFunction - the function to compute a value if absent
      Returns:
      the current or newly computed value
    • computeIfPresent

      public <T> T computeIfPresent(Object id, BiFunction<? super Object, ? super T, ? extends T> mappingFunction)
      Description copied from interface: Cache
      If a value is already associated with the given id, computes a new value using the provided function and replaces the old one.
      Specified by:
      computeIfPresent in interface Cache
      Type Parameters:
      T - the expected type of the value
      Parameters:
      id - the key to compute for
      mappingFunction - the function to compute a new value from the current one
      Returns:
      the newly computed value, or null if the mapping function returned null
    • remove

      public <T> T remove(Object id)
      Description copied from interface: Cache
      Removes the entry associated with the given id, if present.
      Specified by:
      remove in interface Cache
      Type Parameters:
      T - the expected type of the removed value
      Parameters:
      id - the key to remove
      Returns:
      the removed value, or null if no value was associated with the key
    • get

      public <T> T get(Object id)
      Description copied from interface: Cache
      Retrieves the value associated with the given id, or null if not found.
      Specified by:
      get in interface Cache
      Type Parameters:
      T - the expected type of the value
      Parameters:
      id - the key to retrieve
      Returns:
      the cached value, or null if absent
    • containsKey

      public boolean containsKey(Object id)
      Description copied from interface: Cache
      Checks whether the cache contains an entry for the given id.
      Specified by:
      containsKey in interface Cache
      Parameters:
      id - the key to check
      Returns:
      true if the key exists in the cache, false otherwise
    • clear

      public void clear()
      Description copied from interface: Cache
      Removes all entries from the cache.
      Specified by:
      clear in interface Cache
    • size

      public int size()
      Description copied from interface: Cache
      Returns the number of entries currently stored in the cache.
      Specified by:
      size in interface Cache
      Returns:
      the number of entries
    • registerEvictionListener

      public Registration registerEvictionListener(Consumer<CacheEviction> listener)
      Description copied from interface: Cache
      Registers a listener to be notified whenever a cache entry is evicted or removed.
      Specified by:
      registerEvictionListener in interface Cache
      Parameters:
      listener - a function that consumes CacheEvictions
      Returns:
      a registration that can be used to cancel the listener
    • rebuild

      public Cache rebuild()
      Description copied from interface: Cache
      Returns a fresh cache instance with the same configuration and no stored entries.
      Specified by:
      rebuild in interface Cache
    • close

      public void close()
      Description copied from interface: Cache
      Closes the cache and releases all associated resources.
      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface Cache
    • wrap

      protected SoftReferenceCache.CacheReference wrap(Object id, Object value)
    • unwrap

      protected <T> T unwrap(SoftReferenceCache.CacheReference ref)
    • pollReferenceQueue

      protected void pollReferenceQueue()
    • removeExpiredReferences

      protected void removeExpiredReferences()
    • registerEviction

      protected void registerEviction(SoftReferenceCache.CacheReference reference, CacheEviction.Reason reason)