/ Published in: Java
Great for just about any kind of key/value in-memory caching... scales up to the limitations of the JVM, so it's about as good as it gets without clustering.
Expand |
Embed | Plain Text
Copy this code and paste it in your HTML
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentHashMap; import java.util.Set; import java.util.Collection; import java.util.Map; import java.io.Serializable; private ConcurrentLinkedQueue<K> queue; private ConcurrentHashMap<K,V> cache; private ConcurrentHashMap<K,Long> cacheDates; public ConcurrentCacheMap(){ queue = new ConcurrentLinkedQueue<K>(); cache = new ConcurrentHashMap<K,V>(); size = 5000; cacheDates = new ConcurrentHashMap<K,Long>(); timeToLive = 1000L * 60L * 15L; springCleaningInterval = 1000L * 60L; } public ConcurrentCacheMap(int size){ queue = new ConcurrentLinkedQueue<K>(); cache = new ConcurrentHashMap<K,V>(); this.size = size; cacheDates = new ConcurrentHashMap<K,Long>(); timeToLive = 1000L * 60L * 15L; springCleaningInterval = 1000L * 60L; } public ConcurrentCacheMap(int size,long timeToLive){ queue = new ConcurrentLinkedQueue<K>(); cache = new ConcurrentHashMap<K,V>(); this.size = size; cacheDates = new ConcurrentHashMap<K,Long>(); this.timeToLive = timeToLive; springCleaningInterval = 1000L * 60L; } public ConcurrentCacheMap(int size,long timeToLive,long springCleaningInterval){ queue = new ConcurrentLinkedQueue<K>(); cache = new ConcurrentHashMap<K,V>(); this.size = size; cacheDates = new ConcurrentHashMap<K,Long>(); this.timeToLive = timeToLive; this.springCleaningInterval = springCleaningInterval; } public boolean isCached(K key){ housekeeping(); return cache.containsKey(key);} public void clear(){ queue.clear(); cache.clear(); cacheDates.clear();} public Set<K> keySet(){ housekeeping(); return cache.keySet(); } public Collection<V> values(){ housekeeping(); return cache.values();} public V replace(K key, V value){ housekeeping(); return cache.replace(key,value); } public boolean replace(K key, V oldValue,V newValue){ housekeeping(); return cache.replace(key,oldValue,newValue); } public void setSpringCleaningInterval(Long springCleaningInterval){ this.springCleaningInterval = springCleaningInterval; } public boolean isEmpty(){return cache.isEmpty();} public int size(){ return cache.size(); } V result = cache.remove(key); queue.remove(key); cacheDates.remove(key); housekeeping(); return result; } boolean result = false; if(cache.get(key).equals(value)){ result = cache.remove(key,value); queue.remove(key); cacheDates.remove(key); } housekeeping(); return result; } public V putIfAbsent(K key,V value){ V result = null; if(!cache.containsKey(key)){ cache.put(key,value); queue.add(key); } else { result = cache.get(key);} housekeeping(); return result; } public V put(K key,V object){ V result = null; if(!cache.containsKey(key)){ cache.put((K)key,(V)object); queue.add((K)key); } else { result = cache.get(key); cache.replace((K)key,(V)object); } housekeeping(); return result; } public void putAll(Map<? extends K,? extends V> map){ housekeeping(); put((K)me.getKey(),(V)me.getValue()); } } public void housekeeping(){ t.start(); } public void run(){ while(queue.size() > size){ if(key != null){ cache.remove(key); queue.remove(key); cacheDates.remove(key); } } if(lastSpringCleaning + springCleaningInterval < now){ springCleaning(now); } } Object key; if(me.getValue() + timeToLive < now){ key = me.getKey(); cache.remove(key); queue.remove(key); cacheDates.remove(key); } } } }