/*
 * Copyright Terracotta, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.ehcache.core.spi.store;

import org.ehcache.Cache;
import org.ehcache.config.EvictionAdvisor;
import org.ehcache.config.ResourcePools;
import org.ehcache.config.ResourceType;
import org.ehcache.core.spi.store.events.StoreEventSource;
import org.ehcache.expiry.ExpiryPolicy;
import org.ehcache.spi.loaderwriter.CacheLoaderWriter;
import org.ehcache.spi.resilience.StoreAccessException;
import org.ehcache.spi.serialization.Serializer;
import org.ehcache.spi.service.PluralService;
import org.ehcache.spi.service.Service;
import org.ehcache.spi.service.ServiceConfiguration;

import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

import javax.annotation.Nonnull;

The Store interface represents the backing storage of a Cache. It abstracts the support for multiple tiers, eventing, eviction and expiry.

It maps key of type K to value holder which contains value of type V and associated metadata.

Store implementations must not handle null keys or values.

Type parameters:
  • <K> – the key type
  • <V> – the value type
/** * The {@code Store} interface represents the backing storage of a {@link Cache}. It abstracts the support for multiple * tiers, eventing, eviction and expiry. * <p> * It maps key of type {@code K} to {@link ValueHolder value holder} which contains value of type {@code V} and * associated metadata. * <p> * Store implementations must not handle {@code null} keys or values. * * @param <K> the key type * @param <V> the value type */
public interface Store<K, V> extends ConfigurationChangeSupport {
Returns the ValueHolder to which the specified key is mapped, or null if this store contains no mapping for the key or if it was evicted (or became expired) since it was initially installed.

More formally, if this store contains a non-expired mapping from a key k to a ValueHolder v such that key.equals(k), then this method returns v; otherwise it returns null. (There can be at most one such mapping.)

The key cannot be null.

Params:
  • key – the key of the mapping to lookup
Throws:
Returns:the value mapped to this key or null if no mapping exists or is expired
/** * Returns the {@link Store.ValueHolder ValueHolder} to * which the specified key is mapped, or {@code null} if this store contains no * mapping for the key or if it was evicted (or became expired) since it was * initially installed. * <p> * More formally, if this store contains a non-expired mapping from a key * {@code k} to a {@link Store.ValueHolder ValueHolder} * {@code v} such that {@code key.equals(k)}, * then this method returns {@code v}; otherwise it returns * {@code null}. (There can be at most one such mapping.) * <p> * The key cannot be {@code null}. * * @param key the key of the mapping to lookup * @return the value mapped to this key or {@code null} if no mapping exists or is expired * * @throws NullPointerException if the argument is {@code null} * @throws ClassCastException if the specified key is not an instance of {@code K} * @throws StoreAccessException if the mapping can't be retrieved */
ValueHolder<V> get(K key) throws StoreAccessException;
Returns true if this store contains the specified key and the entry is not expired.

More formally, returns true if and only if this store contains a key k such that (o.equals(k)).

The key cannot be null.

Params:
  • key – key whose presence in this store is to be tested
Throws:
Returns:true if this store contains the specified non-expired element, false otherwise
/** * Returns {@code true} if this store contains the specified key * and the entry is not expired. * <p> * More formally, returns {@code true} if and only if this store * contains a key {@code k} such that {@code (o.equals(k))}. * <p> * The key cannot be {@code null}. * * @param key key whose presence in this store is to be tested * @return {@code true} if this store contains the specified non-expired element, {@code false} otherwise * * @throws NullPointerException if the argument is {@code null} * @throws ClassCastException if the specified key is not an instance of {@code K} * @throws StoreAccessException if the presence can't be tested for */
boolean containsKey(K key) throws StoreAccessException;
Maps the specified key to the specified value in this store. Neither the key nor the value can be null.

The ValueHolder can be retrieved by calling the get method with a key that is equal to the original key.

Neither the key nor the value can be null.

Params:
  • key – key with which the specified value is to be associated
  • value – value to be associated with the specified key
Throws:
Returns:PutStatus based on the result of the operation in store
/** * Maps the specified key to the specified value in this store. * Neither the key nor the value can be null. * <p> * The ValueHolder can be retrieved by calling the {@code get} method * with a key that is equal to the original key. * <p> * Neither the key nor the value can be {@code null}. * * @param key key with which the specified value is to be associated * @param value value to be associated with the specified key * @return {@link PutStatus} based on the result of the operation in store * * @throws NullPointerException if any of the arguments is {@code null} * @throws ClassCastException if the specified key or value are not of the correct types ({@code K} or {@code V}) * @throws StoreAccessException if the mapping can't be installed */
PutStatus put(K key, V value) throws StoreAccessException;
Maps the specified key to the specified value in this store, unless a non-expired mapping already exists.

This is equivalent to

  if (!store.containsKey(key))
      store.put(key, value);
      return null;
  else
      return store.get(key);
except that the action is performed atomically.

The ValueHolder can be retrieved by calling the get method with a key that is equal to the original key.

Neither the key nor the value can be null.

Params:
  • key – key with which the specified value is to be associated
  • value – value to be associated with the specified key
  • put – lambda to be consumed if value has been put
Throws:
See Also:
Returns:the ValueHolder to which the specified key was previously mapped, or null if no such mapping existed or the mapping was expired
/** * Maps the specified key to the specified value in this store, unless a non-expired mapping * already exists. * <p> * This is equivalent to * <pre> * if (!store.containsKey(key)) * store.put(key, value); * return null; * else * return store.get(key); * </pre> * except that the action is performed atomically. * <p> * The ValueHolder can be retrieved by calling the {@code get} method * with a key that is equal to the original key. * <p> * Neither the key nor the value can be {@code null}. * * @param key key with which the specified value is to be associated * @param value value to be associated with the specified key * @param put lambda to be consumed if value has been put * @return the {@link Store.ValueHolder ValueHolder} to * which the specified key was previously mapped, or {@code null} if no such mapping existed or the mapping was expired * * @throws NullPointerException if any of the arguments is {@code null} * @throws ClassCastException if the specified key or value are not of the correct types ({@code K} or {@code V}) * @throws StoreAccessException if the mapping can't be installed * * @see #replace(Object, Object) */
ValueHolder<V> putIfAbsent(K key, V value, Consumer<Boolean> put) throws StoreAccessException;
Removes the key (and its corresponding value) from this store. This method does nothing if the key is not mapped.

The key cannot be null.

Params:
  • key – the key that needs to be removed
Throws:
Returns:true if the mapping existed and was successfully removed, false otherwise
/** * Removes the key (and its corresponding value) from this store. * This method does nothing if the key is not mapped. * <p> * The key cannot be {@code null}. * * @param key the key that needs to be removed * @return {@code true} if the mapping existed and was successfully removed, {@code false} otherwise * * @throws NullPointerException if the specified key is null * @throws NullPointerException if the argument is {@code null} * @throws StoreAccessException if the mapping can't be removed */
boolean remove(K key) throws StoreAccessException;
Removes the entry for a key only if currently mapped to the given value and the entry is not expired.

This is equivalent to

  if (store.containsKey(key)) {
    if (store.get(key).equals(value)) {
      store.remove(key);
      return REMOVED;
    } else return KEY_PRESENT;
  } else return KEY_MISSING;
except that the action is performed atomically.

The key cannot be null.

Params:
  • key – key with which the specified value is associated
  • value – value expected to be associated with the specified key
Throws:
Returns:RemoveStatus based on the result of the remove operation in store
/** * Removes the entry for a key only if currently mapped to the given value * and the entry is not expired. * <p> * This is equivalent to * <pre> * if (store.containsKey(key)) { * if (store.get(key).equals(value)) { * store.remove(key); * return REMOVED; * } else return KEY_PRESENT; * } else return KEY_MISSING;</pre> * except that the action is performed atomically. * <p> * The key cannot be {@code null}. * * @param key key with which the specified value is associated * @param value value expected to be associated with the specified key * @return {@link RemoveStatus} based on the result of the remove operation in store * * @throws ClassCastException if the specified key or value are not of the correct types ({@code K} or {@code V}) * @throws NullPointerException if any of the arguments is {@code null} * @throws StoreAccessException if the mapping can't be removed */
RemoveStatus remove(K key, V value) throws StoreAccessException;
Replaces the entry for a key only if currently mapped to some value and the entry is not expired.

This is equivalent to

  ValueHolder<V> oldValue = store.get(key);
  if (oldValue != null) {
    store.put(key, value);
  }
  return oldValue; 
except that the action is performed atomically.

Neither the key nor the value can be null.

Params:
  • key – key with which the specified value is associated
  • value – value expected to be associated with the specified key
Throws:
Returns:the ValueHolder to which the specified key was previously mapped, or null if no such mapping existed
/** * Replaces the entry for a key only if currently mapped to some value and the entry is not expired. * <p> * This is equivalent to * <pre> * ValueHolder&lt;V&gt; oldValue = store.get(key); * if (oldValue != null) { * store.put(key, value); * } * return oldValue; </pre> * except that the action is performed atomically. * <p> * Neither the key nor the value can be {@code null}. * * @param key key with which the specified value is associated * @param value value expected to be associated with the specified key * @return the {@link Store.ValueHolder ValueHolder} to which the specified key was previously mapped, * or {@code null} if no such mapping existed * * @throws ClassCastException if the specified key or value are not of the correct types ({@code K} or {@code V}) * @throws NullPointerException if any of the arguments is {@code null} * @throws StoreAccessException if the mapping can't be replaced */
ValueHolder<V> replace(K key, V value) throws StoreAccessException;
Replaces the entry for a key only if currently mapped to the given value and the entry is not expired.

This is equivalent to

  if (store.containsKey(key)) {
    if (store.get(key).equals(oldValue)) {
      store.put(key, newValue);
      return HIT;
    } else {
      return MISS_PRESENT;
    }
  } else {
    return MISS_NOT_PRESENT;
  }
except that the action is performed atomically.

Neither the key nor the value can be null.

Params:
  • key – key with which the specified value is associated
  • oldValue – value expected to be associated with the specified key
  • newValue – value to be associated with the specified key
Throws:
Returns:ReplaceStatus based on the result of the replace operation in store
/** * Replaces the entry for a key only if currently mapped to the given value * and the entry is not expired. * <p> * This is equivalent to * <pre> * if (store.containsKey(key)) { * if (store.get(key).equals(oldValue)) { * store.put(key, newValue); * return HIT; * } else { * return MISS_PRESENT; * } * } else { * return MISS_NOT_PRESENT; * }</pre> * except that the action is performed atomically. * <p> * Neither the key nor the value can be {@code null}. * * @param key key with which the specified value is associated * @param oldValue value expected to be associated with the specified key * @param newValue value to be associated with the specified key * @return {@link ReplaceStatus} based on the result of the replace operation in store * * @throws ClassCastException if the specified key or values are not of the correct types ({@code K} or {@code V}) * @throws NullPointerException if any of the arguments is {@code null} * @throws StoreAccessException if the mapping can't be replaced */
ReplaceStatus replace(K key, V oldValue, V newValue) throws StoreAccessException;
Removes all of the mappings from this Store.

This method provides no guarantee of atomicity.

Throws:
/** * Removes all of the mappings from this {@code Store}. * <p> * This method provides no guarantee of atomicity. * * @throws StoreAccessException if the store couldn't be partially or entirely be cleared. */
void clear() throws StoreAccessException;
Exposes the Store eventing system to allow configuration and registration of listeners.
Returns:the StoreEventSource of this Store
/** * Exposes the {@code Store} eventing system to allow configuration and registration of listeners. * * @return the {@code StoreEventSource} of this {@code Store} */
StoreEventSource<K, V> getStoreEventSource();
Returns an iterator over the elements in this store.

The elements are returned in no particular order.

Returns:an iterator over the mappings in this Store
/** * Returns an iterator over the elements in this store. * <p> * The elements are returned in no particular order. * * @return an iterator over the mappings in this Store */
Store.Iterator<Cache.Entry<K, ValueHolder<V>>> iterator();
Compute the value for the given key by invoking the given function to produce the value.

The function will be supplied with the key and existing value (or null if no entry exists) as parameters. The function should return the desired new value for the entry or null to remove the entry. If the function throws an unchecked exception the Store will not be modified and a StoreAccessException will be thrown.

This is equivalent to

  V oldValue = store.get(key;
  V newValue = mappingFunction.apply(key, oldValue);
  if (newValue != null) {
    store.put(key, newValue);
  } else {
    store.remove(key);
  }
  return oldValue;
except that the action is performed atomically. Neither the key nor the function can be null
Params:
  • key – the key to update the mapping for
  • mappingFunction – the function that will produce the new value.
Throws:
Returns:the existing value associated with the key or null if none
/** * Compute the value for the given key by invoking the given function to produce the value. * <p> * The function will be supplied with the key and existing value (or {@code null} if no entry exists) as parameters. * The function should return the desired new value for the entry or {@code null} to remove the entry. * If the function throws an unchecked exception the Store will not be modified and a {@link StoreAccessException} will * be thrown. * <p> * This is equivalent to * <pre> * V oldValue = store.get(key; * V newValue = mappingFunction.apply(key, oldValue); * if (newValue != null) { * store.put(key, newValue); * } else { * store.remove(key); * } * return oldValue; * </pre> * except that the action is performed atomically. * Neither the key nor the function can be {@code null} * * @param key the key to update the mapping for * @param mappingFunction the function that will produce the new value. * @return the existing value associated with the key or {@code null} if none * * @throws ClassCastException if the specified key is not of the correct type {@code K} * @throws NullPointerException if any of the arguments is {@code null} * @throws StoreAccessException if the mapping can't be changed * */
ValueHolder<V> getAndCompute(K key, BiFunction<? super K, ? super V, ? extends V> mappingFunction) throws StoreAccessException;
Compute the value for the given key by invoking the given function to produce the value.

The mappingFunction will be supplied with the key and existing value (or null if no entry exists) as parameters. The mappingFunction should return the desired new value for the entry or null to remove the entry.

The replaceEqual function will be invoked if the mappingFunction returns a value that is equal to the existing value. If the replaceEqual function returns false then the existing mapping will not be replaced and will have its metadata updated.

If either function throws an unchecked exception the Store will not be modified and a StoreAccessException will be thrown.

This is equivalent to

  V oldValue = store.get(key);
  V newValue = mappingFunction.apply(key, oldValue);
  if (newValue != null) {
    if (!newValue.equals(oldValue) || replaceEqual.apply()) {
      store.put(key, newValue);
    }
  } else {
    store.remove(key);
  }
  return newValue;
except that the action is performed atomically.

Neither the key nor the functions can be null

Params:
  • key – the key to operate on
  • mappingFunction – the function that will produce the new value.
  • replaceEqual – indicates if an equal value replaces the existing one
  • invokeWriter – indicates if the writer should be invoked
Throws:
Returns:the new value associated with the key or null if none
/** * Compute the value for the given key by invoking the given function to produce the value. * <p> * The {@code mappingFunction} will be supplied with the key and existing value (or {@code null} if no entry exists) as parameters. * The {@code mappingFunction} should return the desired new value for the entry or {@code null} to remove the entry. * <p> * The {@code replaceEqual} function will be invoked if the {@code mappingFunction} returns a value that is * {@link Object#equals(Object) equal} to the existing value. If the {@code replaceEqual} function returns * {@code false} then the existing mapping will not be replaced and will have its metadata updated. * <p> * If either function throws an unchecked exception the {@code Store} will not be modified and a {@link StoreAccessException} * will be thrown. * <p> * This is equivalent to * <pre> * V oldValue = store.get(key); * V newValue = mappingFunction.apply(key, oldValue); * if (newValue != null) { * if (!newValue.equals(oldValue) || replaceEqual.apply()) { * store.put(key, newValue); * } * } else { * store.remove(key); * } * return newValue; * </pre> * except that the action is performed atomically. * <p> * Neither the key nor the functions can be {@code null} * * @param key the key to operate on * @param mappingFunction the function that will produce the new value. * @param replaceEqual indicates if an equal value replaces the existing one * @param invokeWriter indicates if the writer should be invoked * @return the new value associated with the key or {@code null} if none * * @throws ClassCastException if the specified key is not of the correct type {@code K} * @throws NullPointerException if any of the arguments is {@code null} * @throws StoreAccessException if the mapping can't be changed * */
ValueHolder<V> computeAndGet(K key, BiFunction<? super K, ? super V, ? extends V> mappingFunction, Supplier<Boolean> replaceEqual, Supplier<Boolean> invokeWriter) throws StoreAccessException;
Compute the value for the given key (only if absent or expired) by invoking the given function to produce the value.

The function will be supplied with the key only if no mapping exists. The function should return the desired new value for the entry. null will result in a no-op. If the function throws an unchecked exception the Store will not be modified and a StoreAccessException will be thrown.

This is equivalent to

  if (!store.containsKey(key)) {
    V newValue = mappingFunction.apply(key);
    if (newValue != null) {
      store.put(key, newValue);
    }
    return newValue;
  }
  return store.get(key);
except that the action is performed atomically.

Neither the key nor the function can be null

Params:
  • key – the key to operate on
  • mappingFunction – the function that will produce the value.
Throws:
Returns:the new value associated with the key or null if none
/** * Compute the value for the given key (only if absent or expired) by invoking the given function to produce the value. * <p> * The function will be supplied with the key only if no mapping exists. * The function should return the desired new value for the entry. {@code null} will result in a no-op. * If the function throws an unchecked exception the Store will not be modified and a {@link StoreAccessException} * will be thrown. * <p> * This is equivalent to * <pre> * if (!store.containsKey(key)) { * V newValue = mappingFunction.apply(key); * if (newValue != null) { * store.put(key, newValue); * } * return newValue; * } * return store.get(key); * </pre> * except that the action is performed atomically. * <p> * Neither the key nor the function can be {@code null} * * @param key the key to operate on * @param mappingFunction the function that will produce the value. * @return the new value associated with the key or {@code null} if none * * @throws ClassCastException If the specified key is not of the correct type ({@code K}) or if the * function returns a value that is not of type ({@code V}) * @throws NullPointerException if any of the arguments is {@code null} * @throws StoreAccessException if the mapping can't be changed */
ValueHolder<V> computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) throws StoreAccessException;
Compute a value for every key passed in the Set keys argument, using the remappingFunction to compute the value.

The function gets an Iterable of Entry key/value pairs, where each entry's value is its currently stored value, or null if nothing is stored under the key. It is expected that the function returns an Iterable of Entry key/value pairs containing an entry for each key that was passed to it. This returned Iterable should also iterate in the same order as the input Iterable. If an entry's value is null, its mapping will be removed from the store.

Note that the remapping function can be invoked multiple times with key subsets but that it will never the see the same key in different invocations.

Behaviour is equivalent to compute invocations in an external loop. There is no cross key atomicity guarantee / requirement. Implementations may provide coarser grained guarantees.

This is equivalent to calling bulkCompute(Set, Function, Supplier) with a "replaceEquals" function that returns true

Params:
  • keys – the set of keys on which to compute values
  • remappingFunction – the function that generates new values
Throws:
Returns:a Map of key/value pairs for each key in keys to the value computed.
/** * Compute a value for every key passed in the {@link Set} {@code keys} argument, using the {@code remappingFunction} to compute the value. * <p> * The function gets an {@link Iterable} of {@link java.util.Map.Entry} key/value pairs, where each entry's value is its currently stored value, * or null if nothing is stored under the key. It is expected that the function returns an {@link Iterable} of {@link java.util.Map.Entry} * key/value pairs containing an entry for each key that was passed to it. This returned {@link Iterable} should also iterate in the same order as the input {@link Iterable}. * If an entry's value is null, its mapping will be removed from the store. * <p> * Note that the remapping function can be invoked multiple times with key subsets but that it will never the see * the same key in different invocations. * <p> * Behaviour is equivalent to compute invocations in an external loop. There is no cross key atomicity * guarantee / requirement. Implementations may provide coarser grained guarantees. * <p> * This is equivalent to calling {@link Store#bulkCompute(Set, Function, Supplier)} * with a "replaceEquals" function that returns {@link Boolean#TRUE true} * * @param keys the set of keys on which to compute values * @param remappingFunction the function that generates new values * @return a {@link Map} of key/value pairs for each key in {@code keys} to the value computed. * * @throws ClassCastException if the specified key(s) are not of the correct type ({@code K}). Also thrown if the * given function produces entries with either incorrect key or value types * @throws NullPointerException if any of the arguments is null * @throws StoreAccessException if mappings can't be changed */
Map<K, ValueHolder<V>> bulkCompute(Set<? extends K> keys, Function<Iterable<? extends Map.Entry<? extends K, ? extends V>>, Iterable<? extends Map.Entry<? extends K, ? extends V>>> remappingFunction) throws StoreAccessException;
Compute a value for every key passed in the Set keys argument, using the remappingFunction to compute the value.

The function gets an Iterable of Entry key/value pairs, where each entry's value is its currently stored value, or null if nothing is stored under the key. It is expected that the function returns an Iterable of Entry key/value pairs containing an entry for each key that was passed to it. This returned Iterable should also iterate in the same order as the input Iterable. If an entry's value is null, its mapping will be removed from the store.

Note that the remapping function can be invoked multiple times with key subsets but that it will never the see the same key in different invocations.

Behaviour is equivalent to compute invocations in an external loop. There is no cross key atomicity guarantee / requirement. Implementations may provide coarser grained guarantees.

Params:
  • keys – the set of keys on which to compute values
  • remappingFunction – the function that generates new values
  • replaceEqual – If the existing value in the store is Object.equals(Object) to the value returned from the mappingFunction this function will be invoked. If this function returns Boolean.FALSE then the existing entry in the store will not be replaced with a new entry and the existing entry will have its access time updated
Throws:
Returns:a Map of key/value pairs for each key in keys to the value computed.
/** * Compute a value for every key passed in the {@link Set} {@code keys} argument, using the {@code remappingFunction} to compute the value. * <p> * The function gets an {@link Iterable} of {@link java.util.Map.Entry} key/value pairs, where each entry's value is its currently stored value, * or null if nothing is stored under the key. It is expected that the function returns an {@link Iterable} of {@link java.util.Map.Entry} * key/value pairs containing an entry for each key that was passed to it. This returned {@link Iterable} should also iterate in the same order as the input {@link Iterable}. * If an entry's value is null, its mapping will be removed from the store. * <p> * Note that the remapping function can be invoked multiple times with key subsets but that it will never the see * the same key in different invocations. * <p> * Behaviour is equivalent to compute invocations in an external loop. There is no cross key atomicity * guarantee / requirement. Implementations may provide coarser grained guarantees. * * @param keys the set of keys on which to compute values * @param remappingFunction the function that generates new values * @param replaceEqual If the existing value in the store is {@link java.lang.Object#equals(Object)} to * the value returned from the mappingFunction this function will be invoked. If this function * returns {@link java.lang.Boolean#FALSE} then the existing entry in the store will not be replaced * with a new entry and the existing entry will have its access time updated * @return a {@link Map} of key/value pairs for each key in {@code keys} to the value computed. * * @throws ClassCastException if the specified key(s) are not of the correct type ({@code K}). Also thrown if the given function produces * entries with either incorrect key or value types * @throws NullPointerException if any of the arguments is null * @throws StoreAccessException if mappings can't be changed */
Map<K, ValueHolder<V>> bulkCompute(Set<? extends K> keys, Function<Iterable<? extends Map.Entry<? extends K, ? extends V>>, Iterable<? extends Map.Entry<? extends K, ? extends V>>> remappingFunction, Supplier<Boolean> replaceEqual) throws StoreAccessException;
Compute a value for every key passed in the Set keys argument using the mappingFunction to compute the value.

The function gets an Iterable of Entry key/value pairs, where each entry's value is its currently stored value for each key that is not mapped in the store. It is expected that the function returns an Iterable of Entry key/value pairs containing an entry for each key that was passed to it. This returned Iterable should also iterate in the same order as the input Iterable.

The function may be called multiple times per bulkComputeIfAbsent call, depending on how the store wants or does not want to batch computations.

Note: This method guarantees atomicity of computations for each individual key in keys. Implementations may choose to provide coarser grained atomicity.

Params:
  • keys – the keys to compute a new value for, if they're not in the store.
  • mappingFunction – the function that generates new values.
Throws:
  • ClassCastException – if the specified key(s) are not of the correct type (K). Also thrown if the given function produces entries with either incorrect key or value types
  • StoreAccessException – when a failure occurs when accessing the store
Returns:a Map of key/value pairs for each key in keys to the previously missing value.
/** * Compute a value for every key passed in the {@link Set} <code>keys</code> argument using the <code>mappingFunction</code> * to compute the value. * <p> * The function gets an {@link Iterable} of {@link java.util.Map.Entry} key/value pairs, where each entry's value is its currently stored value * for each key that is not mapped in the store. It is expected that the function returns an {@link Iterable} of {@link java.util.Map.Entry} * key/value pairs containing an entry for each key that was passed to it. This returned {@link Iterable} should also iterate in the same order as the input {@link Iterable}. * <p> * The function may be called multiple times per <code>bulkComputeIfAbsent</code> call, depending on how the store wants or does not want to batch computations. * <p> * Note: This method guarantees atomicity of computations for each individual key in {@code keys}. Implementations may choose to provide coarser grained atomicity. * * @param keys the keys to compute a new value for, if they're not in the store. * @param mappingFunction the function that generates new values. * @return a {@link Map} of key/value pairs for each key in <code>keys</code> to the previously missing value. * @throws ClassCastException if the specified key(s) are not of the correct type ({@code K}). Also thrown if the given function produces * entries with either incorrect key or value types * @throws StoreAccessException when a failure occurs when accessing the store */
Map<K, ValueHolder<V>> bulkComputeIfAbsent(Set<? extends K> keys, Function<Iterable<? extends K>, Iterable<? extends Map.Entry<? extends K, ? extends V>>> mappingFunction) throws StoreAccessException;
Holds both a value, and all the metadata associated with a mapping in a Store.
Type parameters:
  • <V> – the value type
/** * Holds both a value, and all the metadata associated with a mapping in a Store. * * @param <V> the value type */
interface ValueHolder<V> extends Supplier<V> {
Constant value indicating no expiration - an eternal mapping.
/** * Constant value indicating no expiration - an eternal mapping. */
long NO_EXPIRE = -1;
Accessor to the creation time of this ValueHolder
Returns:the creation time in milliseconds
/** * Accessor to the creation time of this ValueHolder * * @return the creation time in milliseconds */
long creationTime();
Accessor to the expiration time of this ValueHolder
Returns:the expiration time in milliseconds. A value of ValueHolder<V>.NO_EXPIRE means that the ValueHolder will never expire.
/** * Accessor to the expiration time of this ValueHolder * * @return the expiration time in milliseconds. A value of {@link #NO_EXPIRE} means that the ValueHolder will never expire. */
long expirationTime();
Check if the ValueHolder is expired relative to the specified time
Params:
  • expirationTime – the expiration time (in ms) relative to which the expiry check must be made
Returns:true if the ValueHolder expired relative to the given expiration time
/** * Check if the ValueHolder is expired relative to the specified time * * @param expirationTime the expiration time (in ms) relative to which the expiry check must be made * @return true if the ValueHolder expired relative to the given expiration time */
boolean isExpired(long expirationTime);
Accessor to the last access time of the Value held in this ValueHolder
Returns:the last access time in milliseconds
/** * Accessor to the last access time of the Value held in this ValueHolder * * @return the last access time in milliseconds */
long lastAccessTime();
The combination of this identifier and the key that ValueHolder is mapped to should to be unique at a given time.
Returns:a unique identifier
/** * The combination of this identifier and the <code>key</code> that ValueHolder is mapped to should to be * unique at a given time. * * @return a unique identifier * */
long getId();
Returns the value held by this value holder. This value can't be null.
Returns:the value held
/** * Returns the value held by this value holder. This value can't be {@code null}. * * @return the value held */
@Nonnull @Override V get(); }
The Service used to create Stores. Implementation of Provider have to be thread-safe.
/** * The Service used to create Stores. * Implementation of {@link Provider} have to be thread-safe. */
@PluralService interface Provider extends Service {
Creates a new Store instance
Params:
  • storeConfig – the basic configuration for the Store
  • serviceConfigs – the configurations the Provider may need to configure the Store
Returns:the Store honoring the configurations passed in
/** * Creates a new Store instance * * @param storeConfig the basic configuration for the Store * @param serviceConfigs the configurations the Provider may need to configure the Store * @return the Store honoring the configurations passed in */
<K, V> Store<K, V> createStore(Configuration<K, V> storeConfig, ServiceConfiguration<?>... serviceConfigs);
Informs this Provider, a Store it created is being disposed (i.e. closed)
Params:
  • resource – the store to release
/** * Informs this Provider, a Store it created is being disposed (i.e. closed) * @param resource the store to release */
void releaseStore(Store<?, ?> resource);
Informs this Provider, a Store it created is being initialized
Params:
  • resource – the store to initialize
/** * Informs this Provider, a Store it created is being initialized * @param resource the store to initialize */
void initStore(Store<?, ?> resource);
Gets the internal ranking for the Store instances provided by this Provider of the store's ability to handle the specified resources. A higher rank value indicates a more capable Store.
Params:
  • resourceTypes – the set of ResourceTypes for the store to handle
  • serviceConfigs – the collection of ServiceConfiguration instances that may contribute to the ranking
Returns:a non-negative rank indicating the ability of a Store created by this Provider to handle the resource types specified by resourceTypes; a rank of 0 indicates the store can not handle all types specified in resourceTypes
/** * Gets the internal ranking for the {@link Store} instances provided by this {@code Provider} of the store's * ability to handle the specified resources. A higher rank value indicates a more capable {@code Store}. * * @param resourceTypes the set of {@code ResourceType}s for the store to handle * @param serviceConfigs the collection of {@code ServiceConfiguration} instances that may contribute * to the ranking * * @return a non-negative rank indicating the ability of a {@code Store} created by this {@code Provider} * to handle the resource types specified by {@code resourceTypes}; a rank of 0 indicates the store * can not handle all types specified in {@code resourceTypes} */
int rank(Set<ResourceType<?>> resourceTypes, Collection<ServiceConfiguration<?>> serviceConfigs); }
The basic configuration for a Store.
Type parameters:
  • <K> – key type
  • <V> – value type
/** * The basic configuration for a Store. * * @param <K> key type * @param <V> value type */
interface Configuration<K, V> {
The type of the keys that a Store will hold.
Returns:the key type
/** * The {@link java.lang.Class type} of the keys that a Store will hold. * * @return the key type */
Class<K> getKeyType();
The type of the values that a Store will hold.
Returns:the value type
/** * The {@link java.lang.Class type} of the values that a Store will hold. * * @return the value type */
Class<V> getValueType();
The EvictionAdvisor indicates if mappings should be advised against eviction.

The Store will use best effort to prevent eviction of advised mappings.

Returns:the eviction advisor
/** * The {@link EvictionAdvisor} indicates if mappings should be advised against eviction. * <p> * The {@code Store} will use best effort to prevent eviction of advised mappings. * * @return the eviction advisor */
EvictionAdvisor<? super K, ? super V> getEvictionAdvisor();
The Classloader for this store. This classloader will be used to deserialize cache entries when required
/** * The Classloader for this store. This classloader will be used to deserialize cache entries when required */
ClassLoader getClassLoader();
The expiration policy instance for this store
/** * The expiration policy instance for this store */
ExpiryPolicy<? super K, ? super V> getExpiry();
The resource pools this store can make use of
/** * The resource pools this store can make use of */
ResourcePools getResourcePools();
The serializer for key instances
/** * The serializer for key instances */
Serializer<K> getKeySerializer();
The serializer for value instances
/** * The serializer for value instances */
Serializer<V> getValueSerializer();
The concurrency level of the dispatcher that processes events
/** * The concurrency level of the dispatcher that processes events */
int getDispatcherConcurrency();
If operation statistics (e.g. get/put count) should be enabled. It is a default method to keep the original behavior which was enabled all the time.
/** * If operation statistics (e.g. get/put count) should be enabled. It is * a default method to keep the original behavior which was enabled all the time. */
default boolean isOperationStatisticsEnabled() { return true; }
Cache Loader-Writer for the store
/** * * Cache Loader-Writer for the store * */
CacheLoaderWriter<? super K, V> getCacheLoaderWriter();
Whether Store should use loader-writer in atomic ops or not
/** * Whether Store should use loader-writer in atomic ops or not */
default boolean useLoaderInAtomics() { return false; } }
An iterator over a Store.
Type parameters:
  • <T> – the type of the elements iterated over
/** * An iterator over a Store. * @param <T> the type of the elements iterated over */
interface Iterator<T> {
Returns true if the iteration has more elements. (In other words, returns true if next would return an element rather than throwing a NoSuchElementException.)
Returns:true if the iterator has more elements.
/** * Returns <tt>true</tt> if the iteration has more elements. (In other * words, returns <tt>true</tt> if <tt>next</tt> would return an element * rather than throwing a {@link java.util.NoSuchElementException}.) * * @return <tt>true</tt> if the iterator has more elements. */
boolean hasNext();
Returns the next element in the iteration.
Throws:
Returns:the next element in the iteration.
/** * Returns the next element in the iteration. * * @return the next element in the iteration. * @throws java.util.NoSuchElementException iteration has no more elements. * @throws StoreAccessException if accessing the next element failed */
T next() throws StoreAccessException; }
Put operation status
/** * Put operation status */
enum PutStatus {
Value was put
/** * Value was put */
PUT,
New value was dropped
/** * New value was dropped */
NOOP }
Conditional Remove operation status
/** * Conditional Remove operation status */
enum RemoveStatus {
Mapping was removed
/** * Mapping was removed */
REMOVED,
Mapping was not removed although there was one
/** * Mapping was not removed although there was one */
KEY_PRESENT,
Mapping was not remove as there was no mapping
/** * Mapping was not remove as there was no mapping */
KEY_MISSING }
Conditional Replace operation status
/** * Conditional Replace operation status */
enum ReplaceStatus {
Mapping was replaced
/** * Mapping was replaced */
HIT,
Mapping was not replaced although there was one
/** * Mapping was not replaced although there was one */
MISS_PRESENT,
Mapping was not replace as there was no mapping
/** * Mapping was not replace as there was no mapping */
MISS_NOT_PRESENT } }