Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package reghzy.api.utils;
- import java.util.Map;
- import java.util.Objects;
- import java.util.function.Function;
- /**
- * A helper class for caching map entries. This is only really intended to be used if the map isn't modified often
- * @param <K> The key
- * @param <V> The value
- * @author REghZy
- */
- public abstract class KVObjectCache<K, V> {
- private K lastAccessedKey;
- private V lastAccessedValue;
- /**
- * Gets the cached value if it isn't null, and the key is equal to this cache's cached key. Otherwise, it calls {@link KVObjectCache#getValue(Object)}
- * @param key
- * @return
- */
- public V get(K key) {
- V value;
- if (Objects.equals(this.lastAccessedKey, key)) {
- // possibly increases odds of reference equality passing, skipping the equals() invocation
- this.lastAccessedKey = key;
- if ((value = this.lastAccessedValue) == null) {
- this.lastAccessedValue = value = getValue(key);
- }
- }
- else {
- // assign to local variable first, to avoid key/value de-synchronization if getValue() throws
- value = getValue(key);
- this.lastAccessedKey = key;
- this.lastAccessedValue = value;
- }
- return value;
- // older version, where if getValue() throws, it will corrupt the KVObjectCache (new key paired with old value)
- // V value;
- // if (Objects.equals(key, this.lastAccessedKey)) {
- // this.lastAccessedKey = key;
- // if ((value = this.lastAccessedValue) == null) {
- // return this.lastAccessedValue = getValue(key);
- // }
- //
- // return value;
- // }
- // else {
- // return this.lastAccessedValue = getValue(this.lastAccessedKey = key);
- // }
- }
- /**
- * An abstract method for getting the value from a key. This should usually not be called as it won't check the cached keys. Instead, use {@link KVObjectCache#get(Object)}
- * @param key The key
- * @return The value
- */
- public abstract V getValue(K key);
- // Removed because it's simply pointless in most cases, and won't work for null-values
- // /**
- // * A delegation method if this cache is used with a map. By default, this will do:
- // * <p>
- // * <code>{@link KVObjectCache#get(Object)} != null</code>
- // * </p>
- // * @param key The key to check
- // */
- // public boolean containsKey(K key) {
- // return this.get(key) != null;
- // }
- /**
- * Clears the cached key and value
- */
- public void clear() {
- this.lastAccessedKey = null;
- this.lastAccessedValue = null;
- }
- /**
- * Invalidates the currently held cached object, if the given key matches this cache's key
- */
- public void invalidate(K key) {
- if (Objects.equals(key, this.lastAccessedKey)) {
- this.lastAccessedKey = null;
- this.lastAccessedValue = null;
- }
- }
- /**
- * If the given key is equal to this cache's key, then this cache's value will be set to the given
- * value. This should usually be called after adding/putting a value into a map
- * @param key The key to check the invalidation of
- * @param value The value to set as this cache's value if the keys match
- */
- public void invalidateWithNewValue(K key, V value) {
- if (Objects.equals(key, this.lastAccessedKey)) {
- this.lastAccessedKey = key;
- this.lastAccessedValue = value;
- }
- }
- /**
- * Returns the last accessed key
- */
- public K getLastAccessedKey() {
- return this.lastAccessedKey;
- }
- /**
- * Returns the last accessed value
- */
- public V getLastAccessedValue() {
- return this.lastAccessedValue;
- }
- public static class MapWrapper<K, V> extends KVObjectCache<K, V> {
- protected final Map<K, V> map;
- public MapWrapper(Map<K, V> map) {
- this.map = map;
- }
- @Override
- public V getValue(K key) {
- return this.map.get(key);
- }
- public Map<K, V> getMap() {
- return this.map;
- }
- }
- public static class LambdaProvider<K, V> extends KVObjectCache<K, V> {
- protected final Function<K, V> supplier;
- public LambdaProvider(Function<K, V> supplier) {
- this.supplier = supplier;
- }
- @Override
- public V getValue(K key) {
- return this.supplier.apply(key);
- }
- public Function<K, V> getSupplier() {
- return this.supplier;
- }
- }
- }
Add Comment
Please, Sign In to add comment