SimpleCache.java
package space.sunqian.common.cache;
import space.sunqian.annotations.Nonnull;
import space.sunqian.annotations.Nullable;
import space.sunqian.annotations.ThreadSafe;
import space.sunqian.common.base.value.Val;
import java.lang.ref.PhantomReference;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.Map;
import java.util.function.Function;
/**
* This interface is a simplified key-value pair cache interface (implementations must be thread-safe). It only provides
* get, put, remove and clean operations, and supports null value but does not allow null key. It is suitable for
* scenarios that require simple cache operations and do not care about the cache lifecycle.
* <p>
* It is recommended to use the skeletal implementation: {@link AbstractSimpleCache}.
*
* @param <K> the key type
* @param <V> the value type
* @author sunqian
* @see AbstractSimpleCache
*/
@ThreadSafe
public interface SimpleCache<K, V> {
/**
* Returns a new {@link SimpleCache} based on {@link WeakReference}. The values of the returned cache will be
* automatically collected by the garbage collection based on the characteristics of {@link WeakReference}. Its
* {@link #clean()} method releases all entries of which values are collected, and this method is automatically
* invoked once every time another method is executed.
*
* @param <K> the key type
* @param <V> the value type
* @return a new {@link SimpleCache} based on {@link WeakReference}
*/
static <K, V> @Nonnull SimpleCache<K, V> ofWeak() {
return CacheBack.ofWeak();
}
/**
* Returns a new {@link SimpleCache} based on {@link SoftReference}. The values of the returned cache will be
* automatically collected by the garbage collection based on the characteristics of {@link SoftReference}. Its
* {@link #clean()} method releases all entries of which values are collected, and this method is automatically
* invoked once every time another method is executed.
*
* @param <K> the key type
* @param <V> the value type
* @return a new {@link SimpleCache} based on {@link SoftReference}
*/
static <K, V> @Nonnull SimpleCache<K, V> ofSoft() {
return CacheBack.ofSoft();
}
/**
* Returns a new {@link SimpleCache} based on {@link PhantomReference}. The values of the returned cache will be
* automatically collected by the garbage collection based on the characteristics of {@link PhantomReference}. Its
* {@link #clean()} method releases all entries of which values are collected, and this method is automatically
* invoked once every time another method is executed.
*
* @param <K> the key type
* @param <V> the value type
* @return a new {@link SimpleCache} based on {@link PhantomReference}
*/
static <K, V> @Nonnull SimpleCache<K, V> ofPhantom() {
return CacheBack.ofPhantom();
}
/**
* Returns a new {@link SimpleCache} based on strong reference. The values of the returned cache will never
* automatically be invalid, and its {@link #clean()} method does nothing. The behavior of the returned cache is
* just like a regular {@link Map}.
*
* @param <K> the key type
* @param <V> the value type
* @return a new {@link SimpleCache} based on strong reference
*/
static <K, V> @Nonnull SimpleCache<K, V> ofStrong() {
return CacheBack.ofStrong();
}
/**
* Returns the value for the specified key, or {@code null} if the value is invalid or is {@code null} itself. Use
* {@link #getVal(Object)} to distinguish between these cases.
*
* @param key the specified key
* @return the value for the specified key, or {@code null} if the value is invalid or is {@code null} itself
*/
@Nullable
V get(@Nonnull K key);
/**
* Returns the value wrapped by {@link Val} for the specified key, or {@code null} if the value is invalid.
*
* @param key the specified key
* @return the value wrapped by {@link Val} for the specified key, or {@code null} if the value is invalid
*/
@Nullable
Val<@Nullable V> getVal(@Nonnull K key);
/**
* Returns the value for the specified key. If the value is invalid, the {@code producer} will be called to generate
* a new value, and the new value will be cached and returned. If an exception is thrown during the generation, the
* exception will be thrown directly. This operation is atomic.
* <p>
* Any value, including {@code null}, generated by the {@code producer} will be cached. To distinguish between
* {@code null} value or no-cached, try {@link #getVal(Object, Function)}.
*
* @param key the specified key
* @param producer the producer to generate new value
* @return the value for the specified key, including {@code null}
*/
V get(@Nonnull K key, @Nonnull Function<? super @Nonnull K, ? extends @Nullable V> producer);
/**
* Returns the value wrapped by {@link Val} for the specified key. If the value is invalid, the {@code producer}
* will be called to generate a new value wrapped by {@link Val}, and the new value will be cached and returned. If
* an exception is thrown during the generation, the exception will be thrown directly. This operation is atomic.
* <p>
* If the {@code producer} generates a {@code null}, no value will be cached, and this method will return null.
*
* @param key the specified key
* @param producer the producer to generate new value wrapped by {@link Val}
* @return the value wrapped by {@link Val} for the specified key, or {@code null} if the {@code producer} generates
* a {@code null}
*/
@Nullable
Val<@Nullable V> getVal(
@Nonnull K key,
@Nonnull Function<? super @Nonnull K, ? extends @Nullable Val<? extends @Nullable V>> producer
);
/**
* Puts the key mapping the value into this cache.
*
* @param key the key
* @param value the value
*/
void put(@Nonnull K key, @Nullable V value);
/**
* Removes the value mapped by the key from this cache.
*
* @param key the key
*/
void remove(@Nonnull K key);
/**
* Returns the current size of this cache.
*
* @return the current size of this cache
*/
int size();
/**
* Removes all entries from this cache.
*/
void clear();
/**
* Tries to release invalid entries from this cache.
*/
void clean();
}