All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.snapscript.common.CopyOnWriteCache Maven / Gradle / Ivy

package org.snapscript.common;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class CopyOnWriteCache implements Cache {

   private volatile MapUpdater updater;
   private volatile Map cache;
   
   public CopyOnWriteCache() {
      this(16);
   }
   
   public CopyOnWriteCache(int size) {
      this(16, 0.5f);
   }
   
   public CopyOnWriteCache(int size, float density) {
      this.updater = new MapUpdater(size, density);
      this.cache = new HashMap();
   }

   @Override
   public Set keySet() {
      return cache.keySet();
   }

   @Override
   public V take(K key) {
      return updater.take(key);
   }

   @Override
   public V fetch(K key) {
      return cache.get(key);
   }

   @Override
   public boolean isEmpty() {
      return cache.isEmpty();
   }

   @Override
   public boolean contains(K key) {
      return cache.containsKey(key);
   }
   
   @Override
   public void cache(K key, V value) {
      updater.cache(key, value);
   }

   @Override
   public void clear() {
      updater.clear();
   }

   @Override
   public int size() {
      return cache.size();
   }
   
   private class MapUpdater {
      
      private final Map empty;
      private final float density;
      private final int size;
      
      public MapUpdater(int size, float density) {
         this.empty = new HashMap();
         this.density = density;
         this.size = size;
      }

      public synchronized void cache(K key, V value) {
         V existing = cache.get(key);
         
         if(existing != value) { // reduce churn
            Map copy = new HashMap(size, density);
            
            copy.putAll(cache);
            copy.put(key, value);
            cache = copy;
         }
      }
      
      public synchronized V take(K key) {
         V existing = cache.get(key);
         
         if(existing != null) {
            Map copy = new HashMap(size, density);
            
            copy.putAll(cache);
            copy.remove(key);
            cache = copy;
         }
         return existing;
      }
      
      public synchronized void clear() {
         cache = empty;
      }
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy