bobmarley12345

KVObjectCache

Jul 18th, 2022 (edited)
930
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 4.71 KB | None | 0 0
  1. package reghzy.api.utils;
  2.  
  3.  
  4. import java.util.Map;
  5. import java.util.Objects;
  6. import java.util.function.Function;
  7.  
  8. /**
  9.  * A helper class for caching map entries. This is only really intended to be used if the map isn't modified often
  10.  * @param <K> The key
  11.  * @param <V> The value
  12.  * @author REghZy
  13.  */
  14. public abstract class KVObjectCache<K, V> {
  15.     private K lastAccessedKey;
  16.     private V lastAccessedValue;
  17.  
  18.     /**
  19.      * 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)}
  20.      * @param key
  21.      * @return
  22.      */
  23.     public V get(K key) {
  24.         V value;
  25.         if (Objects.equals(this.lastAccessedKey, key)) {
  26.             // possibly increases odds of reference equality passing, skipping the equals() invocation
  27.             this.lastAccessedKey = key;
  28.             if ((value = this.lastAccessedValue) == null) {
  29.                 this.lastAccessedValue = value = getValue(key);
  30.             }
  31.         }
  32.         else {
  33.             // assign to local variable first, to avoid key/value de-synchronization if getValue() throws
  34.             value = getValue(key);
  35.             this.lastAccessedKey = key;
  36.             this.lastAccessedValue = value;
  37.         }
  38.  
  39.         return value;
  40.  
  41.         // older version, where if getValue() throws, it will corrupt the KVObjectCache (new key paired with old value)
  42.         // V value;
  43.         // if (Objects.equals(key, this.lastAccessedKey)) {
  44.         //     this.lastAccessedKey = key;
  45.         //     if ((value = this.lastAccessedValue) == null) {
  46.         //         return this.lastAccessedValue = getValue(key);
  47.         //     }
  48.         //
  49.         //     return value;
  50.         // }
  51.         // else {
  52.         //     return this.lastAccessedValue = getValue(this.lastAccessedKey = key);
  53.         // }
  54.     }
  55.  
  56.     /**
  57.      * 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)}
  58.      * @param key The key
  59.      * @return The value
  60.      */
  61.     public abstract V getValue(K key);
  62.  
  63.     // Removed because it's simply pointless in most cases, and won't work for null-values
  64.     // /**
  65.     //  * A delegation method if this cache is used with a map. By default, this will do:
  66.     //  * <p>
  67.     //  *     <code>{@link KVObjectCache#get(Object)} != null</code>
  68.     //  * </p>
  69.     //  * @param key The key to check
  70.     //  */
  71.     // public boolean containsKey(K key) {
  72.     //     return this.get(key) != null;
  73.     // }
  74.  
  75.     /**
  76.      * Clears the cached key and value
  77.      */
  78.     public void clear() {
  79.         this.lastAccessedKey = null;
  80.         this.lastAccessedValue = null;
  81.     }
  82.  
  83.     /**
  84.      * Invalidates the currently held cached object, if the given key matches this cache's key
  85.      */
  86.     public void invalidate(K key) {
  87.         if (Objects.equals(key, this.lastAccessedKey)) {
  88.             this.lastAccessedKey = null;
  89.             this.lastAccessedValue = null;
  90.         }
  91.     }
  92.  
  93.     /**
  94.      * If the given key is equal to this cache's key, then this cache's value will be set to the given
  95.      * value. This should usually be called after adding/putting a value into a map
  96.      * @param key The key to check the invalidation of
  97.      * @param value The value to set as this cache's value if the keys match
  98.      */
  99.     public void invalidateWithNewValue(K key, V value) {
  100.         if (Objects.equals(key, this.lastAccessedKey)) {
  101.             this.lastAccessedKey = key;
  102.             this.lastAccessedValue = value;
  103.         }
  104.     }
  105.  
  106.     /**
  107.      * Returns the last accessed key
  108.      */
  109.     public K getLastAccessedKey() {
  110.         return this.lastAccessedKey;
  111.     }
  112.  
  113.     /**
  114.      * Returns the last accessed value
  115.      */
  116.     public V getLastAccessedValue() {
  117.         return this.lastAccessedValue;
  118.     }
  119.  
  120.     public static class MapWrapper<K, V> extends KVObjectCache<K, V> {
  121.         protected final Map<K, V> map;
  122.  
  123.         public MapWrapper(Map<K, V> map) {
  124.             this.map = map;
  125.         }
  126.  
  127.         @Override
  128.         public V getValue(K key) {
  129.             return this.map.get(key);
  130.         }
  131.  
  132.         public Map<K, V> getMap() {
  133.             return this.map;
  134.         }
  135.     }
  136.  
  137.     public static class LambdaProvider<K, V> extends KVObjectCache<K, V> {
  138.         protected final Function<K, V> supplier;
  139.  
  140.         public LambdaProvider(Function<K, V> supplier) {
  141.             this.supplier = supplier;
  142.         }
  143.  
  144.         @Override
  145.         public V getValue(K key) {
  146.             return this.supplier.apply(key);
  147.         }
  148.  
  149.         public Function<K, V> getSupplier() {
  150.             return this.supplier;
  151.         }
  152.     }
  153. }
  154.  
Add Comment
Please, Sign In to add comment