Class AbstractInternalDataContainer<K,V>

java.lang.Object
org.infinispan.container.impl.AbstractInternalDataContainer<K,V>
All Implemented Interfaces:
Iterable<InternalCacheEntry<K,V>>, DataContainer<K,V>, InternalDataContainer<K,V>
Direct Known Subclasses:
DefaultDataContainer, DefaultSegmentedDataContainer, OffHeapDataContainer

public abstract class AbstractInternalDataContainer<K,V> extends Object implements InternalDataContainer<K,V>
Abstract class implemenation for a segmented data container. All methods delegate to getSegmentForKey(Object) for methods that don't provide a segment and implementors can provide what map we should look into for a given segment via getMapForSegment(int).
Since:
9.3
Author:
wburns
  • Field Details

  • Constructor Details

    • AbstractInternalDataContainer

      public AbstractInternalDataContainer()
  • Method Details

    • getMapForSegment

      protected abstract PeekableTouchableMap<K,V> getMapForSegment(int segment)
    • getSegmentForKey

      protected abstract int getSegmentForKey(Object key)
    • get

      public InternalCacheEntry<K,V> get(int segment, Object k)
      Description copied from interface: InternalDataContainer
      Same as DataContainer.get(Object) except that the segment of the key can provided to lookup entries without calculating the segment for the given key
      Specified by:
      get in interface InternalDataContainer<K,V>
      Parameters:
      segment - segment for the key
      k - key under which entry is stored
      Returns:
      entry, if it exists and has not expired, or null if not
    • get

      public InternalCacheEntry<K,V> get(Object k)
      Description copied from interface: InternalDataContainer
      Retrieves a cached entry

      We should only ever be using the non blocking variant InternalDataContainer.peek(int, Object) in Infinispan

      Specified by:
      get in interface DataContainer<K,V>
      Specified by:
      get in interface InternalDataContainer<K,V>
      Parameters:
      k - key under which entry is stored
      Returns:
      entry, if it exists and has not expired, or null if not
    • peek

      public InternalCacheEntry<K,V> peek(int segment, Object k)
      Description copied from interface: InternalDataContainer
      Same as DataContainer.peek(Object) except that the segment of the key can provided to lookup entries without calculating the segment for the given key
      Specified by:
      peek in interface InternalDataContainer<K,V>
      Parameters:
      segment - segment for the key
      k - key under which entry is stored
      Returns:
      entry, if it exists, or null if not
    • peek

      public InternalCacheEntry<K,V> peek(Object k)
      Description copied from interface: DataContainer
      Retrieves a cache entry in the same way as DataContainer.get(Object)} except that it does not update or reorder any of the internal constructs. I.e., expiration does not happen, and in the case of the LRU container, the entry is not moved to the end of the chain.

      This method should be used instead of DataContainer.get(Object)} when called while iterating through the data container using methods like DataContainer.iterator() to avoid changing the underlying collection's order.

      Specified by:
      peek in interface DataContainer<K,V>
      Parameters:
      k - key under which entry is stored
      Returns:
      entry, if it exists, or null if not
    • touch

      public boolean touch(int segment, Object k, long currentTimeMillis)
      Description copied from interface: InternalDataContainer
      Touches an entry in the data container. This will update the last access time of the entry as well as count this as a access for eviction based recency.
      Specified by:
      touch in interface InternalDataContainer<K,V>
      Parameters:
      segment - segment for the key
      k - key under which entry is stored
      currentTimeMillis - the current time in milliseconds to touch the entry with
      Returns:
      true if the entry timestamp was touched
    • put

      public void put(int segment, K k, V v, Metadata metadata, PrivateMetadata internalMetadata, long createdTimestamp, long lastUseTimestamp)
      Description copied from interface: InternalDataContainer
      Same as DataContainer.put(Object, Object, Metadata) except that the segment of the key can provided to write/lookup entries without calculating the segment for the given key.

      Note: The timestamps ignored if the entry already exists in the data container.

      Specified by:
      put in interface InternalDataContainer<K,V>
      Parameters:
      segment - segment for the key
      k - key under which to store entry
      v - value to store
      metadata - metadata of the entry
      createdTimestamp - creation timestamp, or -1 to use the current time
      lastUseTimestamp - last use timestamp, or -1 to use the current time
    • put

      public void put(K k, V v, Metadata metadata)
      Description copied from interface: DataContainer
      Puts an entry in the cache along with metadata adding information such lifespan of entry, max idle time, version information...etc.
      Specified by:
      put in interface DataContainer<K,V>
      Parameters:
      k - key under which to store entry
      v - value to store
      metadata - metadata of the entry
    • containsKey

      public boolean containsKey(int segment, Object k)
      Description copied from interface: InternalDataContainer
      Same as DataContainer.containsKey(Object) except that the segment of the key can provided to lookup if the entry exists without calculating the segment for the given key.
      Specified by:
      containsKey in interface InternalDataContainer<K,V>
      Parameters:
      segment - segment for the key
      k - key under which entry is stored
      Returns:
      true if entry exists and has not expired; false otherwise
    • containsKey

      public boolean containsKey(Object k)
      Description copied from interface: DataContainer
      Tests whether an entry exists in the container
      Specified by:
      containsKey in interface DataContainer<K,V>
      Parameters:
      k - key to test
      Returns:
      true if entry exists and has not expired; false otherwise
    • remove

      public InternalCacheEntry<K,V> remove(int segment, Object k)
      Description copied from interface: InternalDataContainer
      Same as DataContainer.remove(Object) except that the segment of the key can provided to remove the entry without calculating the segment for the given key.
      Specified by:
      remove in interface InternalDataContainer<K,V>
      Parameters:
      segment - segment for the key
      k - key to remove
      Returns:
      entry removed, or null if it didn't exist or had expired
    • remove

      public InternalCacheEntry<K,V> remove(Object k)
      Description copied from interface: DataContainer
      Removes an entry from the cache
      Specified by:
      remove in interface DataContainer<K,V>
      Parameters:
      k - key to remove
      Returns:
      entry removed, or null if it didn't exist or had expired
    • evict

      public CompletionStage<Void> evict(int segment, K key)
      Description copied from interface: InternalDataContainer
      Same as DataContainer.evict(Object) except that the segment of the key can provided to remove the entry without calculating the segment for the given key.
      Specified by:
      evict in interface InternalDataContainer<K,V>
      Parameters:
      segment - segment for the key
      key - The key to evict.
    • evict

      public void evict(K key)
      Description copied from interface: DataContainer
      Atomically, it removes the key from DataContainer and passivates it to persistence.

      The passivation must be done by invoking the method PassivationManager.passivateAsync(InternalCacheEntry).

      Specified by:
      evict in interface DataContainer<K,V>
      Parameters:
      key - The key to evict.
    • compute

      public InternalCacheEntry<K,V> compute(int segment, K key, DataContainer.ComputeAction<K,V> action)
      Description copied from interface: InternalDataContainer
      Same as DataContainer.compute(Object, ComputeAction) except that the segment of the key can provided to update entries without calculating the segment for the given key.
      Specified by:
      compute in interface InternalDataContainer<K,V>
      Parameters:
      segment - segment for the key
      key - The key.
      action - The action that will compute the new value.
      Returns:
      The InternalCacheEntry associated to the key.
    • compute

      public InternalCacheEntry<K,V> compute(K key, DataContainer.ComputeAction<K,V> action)
      Description copied from interface: DataContainer
      Computes the new value for the key.

      See DataContainer.ComputeAction.compute(Object, org.infinispan.container.entries.InternalCacheEntry, InternalEntryFactory).

      Note the entry provided to DataContainer.ComputeAction may be expired as these entries are not filtered as many other methods do.

      Specified by:
      compute in interface DataContainer<K,V>
      Parameters:
      key - The key.
      action - The action that will compute the new value.
      Returns:
      The InternalCacheEntry associated to the key.
    • clear

      public void clear(IntSet segments)
      Description copied from interface: InternalDataContainer
      Removes entries from the container whose key maps to one of the provided segments
      Specified by:
      clear in interface InternalDataContainer<K,V>
      Parameters:
      segments - segments of entries to remove
    • computeEntryWritten

      protected void computeEntryWritten(K key, InternalCacheEntry<K,V> value)
      This method is invoked every time an entry is written inside a compute block
      Parameters:
      key - key passed to compute method
      value - the new value
    • computeEntryRemoved

      protected void computeEntryRemoved(K key, InternalCacheEntry<K,V> value)
      This method is invoked every time an entry is removed inside a compute block
      Parameters:
      key - key passed to compute method
      value - the old value
    • putEntryInMap

      protected void putEntryInMap(PeekableTouchableMap<K,V> map, int segment, K key, InternalCacheEntry<K,V> ice)
    • removeEntryInMap

      protected InternalCacheEntry<K,V> removeEntryInMap(PeekableTouchableMap<K,V> map, int segment, Object key)
    • addRemovalListener

      public void addRemovalListener(Consumer<Iterable<InternalCacheEntry<K,V>>> listener)
      Description copied from interface: InternalDataContainer
      Adds a listener that is invoked whenever InternalDataContainer.removeSegments(IntSet) is invoked providing a way for the listener to see what actual entries were removed from the container.
      Specified by:
      addRemovalListener in interface InternalDataContainer<K,V>
      Parameters:
      listener - listener that invoked of removed entries
    • removeRemovalListener

      public void removeRemovalListener(Object listener)
      Description copied from interface: InternalDataContainer
      Removes a previously registered listener via InternalDataContainer.addRemovalListener(Consumer).
      Specified by:
      removeRemovalListener in interface InternalDataContainer<K,V>
      Parameters:
      listener - the listener to remove
    • hasExpirable

      public boolean hasExpirable()
      Description copied from interface: InternalDataContainer
      Verify if the container has entries that can expire. This is __not__ the same thing as verifying for expired entries. This method can return true even if entries are not expired.
      Specified by:
      hasExpirable in interface InternalDataContainer<K,V>
      Returns:
      true if any entry can expire, false otherwise.
    • entryAdded

      protected final void entryAdded(InternalCacheEntry<K,V> ice)
    • entryUpdated

      protected final void entryUpdated(InternalCacheEntry<K,V> curr, InternalCacheEntry<K,V> prev)
    • entryRemoved

      protected final void entryRemoved(InternalCacheEntry<K,V> ice)
    • segmentRemoved

      protected final void segmentRemoved(Map<K,InternalCacheEntry<K,V>> segment)
    • applyListener

      protected com.github.benmanes.caffeine.cache.Caffeine<K,InternalCacheEntry<K,V>> applyListener(com.github.benmanes.caffeine.cache.Caffeine<K,InternalCacheEntry<K,V>> caffeine, AbstractInternalDataContainer<K,V>.org.infinispan.container.impl.AbstractInternalDataContainer.DefaultEvictionListener listener)
    • handleEviction

      public static <K, V> CompletionStage<Void> handleEviction(InternalCacheEntry<K,V> entry, DataOperationOrderer orderer, PassivationManager passivator, EvictionManager<K,V> evictionManager, DataContainer<K,V> dataContainer, Executor nonBlockingExecutor, CompletionStage<Void> selfDelay)
      Performs the eviction logic, except it doesn't actually remove the entry from the data container. It will acquire the orderer for the key if necessary (not null), passivate the entry, and notify the listeners, all in a non blocking fashion. The caller MUST hold the data container key lock. If the orderer is null, it means a concurrent write/remove is impossible, so we always passivate and notify the listeners. If the orderer is non-null and the self delay is null, when the orderer stage completes we know both the eviction operation removed the entry from the data container and the other operation removed/updated/inserted the entry, but we don't know the order. We don't care about the order for removals, we always skip passivation. We don't care about the order for activations/other evictions (READ) either, we always perform passivation. For writes we want to passivate only if the entry is no longer in the data container, i.e. the eviction removed the entry last. If the self delay is non-null, we may also acquire the orderer before the eviction operation removes the entry. We have to wait for the delay to complete before passivating the entry, but the scenarios are the same. It doesn't make sense to have a null orderer and a non-null self delay.
      Type Parameters:
      K - key type of the entry
      V - value type of the entry
      Parameters:
      entry - evicted entry
      orderer - used to guarantee ordering between other operations. May be null when an operation is already ordered
      passivator - Passivates the entry to the store if necessary
      evictionManager - Handles additional eviction logic. May be null if eviction is also not required
      dataContainer - container to check if the key has already been removed
      nonBlockingExecutor - executor to use to run code that may not be able to be ran while holding the write lock
      selfDelay - if null, the entry was already removed; if non-null, completes after the eviction finishes removing the entry
      Returns:
      stage that when complete all of the eviction logic is complete
    • filterExpiredEntries

      protected Spliterator<InternalCacheEntry<K,V>> filterExpiredEntries(Spliterator<InternalCacheEntry<K,V>> spliterator)
      Returns a new spliterator that will not return entries that have expired.
      Parameters:
      spliterator - the spliterator to filter expired entries out of
      Returns:
      new spliterator with expired entries filtered
    • expiredIterationPredicate

      protected Predicate<InternalCacheEntry<K,V>> expiredIterationPredicate(long accessTime)
      Returns a predicate that will return false when an entry is expired. This predicate assumes this is invoked from an iteration process.
      Parameters:
      accessTime - the access time to base expiration off of
      Returns:
      predicate that returns true if an entry is not expired