Revision: 34996
Updated Code
at November 1, 2010 03:13 by kubaitis
Updated Code
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; public class ConcurrentCacheMap<K,V> extends Thread implements ConcurrentMap<K,V>, Serializable { private ConcurrentLinkedQueue<K> queue; private ConcurrentHashMap<K,V> cache; private ConcurrentHashMap<K,Long> cacheDates; private Long lastSpringCleaning; private Long timeToLive; private Long springCleaningInterval; private Integer size; public ConcurrentCacheMap(){ queue = new ConcurrentLinkedQueue<K>(); cache = new ConcurrentHashMap<K,V>(); size = 5000; lastSpringCleaning = System.currentTimeMillis(); 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; lastSpringCleaning = System.currentTimeMillis(); 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; lastSpringCleaning = System.currentTimeMillis(); 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; lastSpringCleaning = System.currentTimeMillis(); cacheDates = new ConcurrentHashMap<K,Long>(); this.timeToLive = timeToLive; this.springCleaningInterval = springCleaningInterval; } public V get(Object key){ V result = cache.get(key); housekeeping(); return result; } 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 Set<Map.Entry<K,V>> entrySet(){ housekeeping(); return cache.entrySet(); } 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 setMaxSize(Integer size){ this.size = size; } public void setTimeToLive(Long timeToLive){ this.timeToLive = timeToLive; } public void setSpringCleaningInterval(Long springCleaningInterval){ this.springCleaningInterval = springCleaningInterval; } public Integer getMaxSize(){ return size; } public Long getTimeToLive(){ return timeToLive; } public boolean containsKey(Object key){return cache.containsKey(key);} public boolean containsValue(Object value){return cache.containsValue(value);} public boolean isEmpty(){return cache.isEmpty();} public int size(){ return cache.size(); } public Long getSpringCleaningInterval(){ return springCleaningInterval; } public V remove(Object key){ V result = cache.remove(key); queue.remove(key); cacheDates.remove(key); housekeeping(); return result; } public boolean remove(Object key,Object value){ 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); cacheDates.put(key,System.currentTimeMillis()); } 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); cacheDates.put((K)key,System.currentTimeMillis()); } else { result = cache.get(key); cache.replace((K)key,(V)object); cacheDates.replace((K)key,System.currentTimeMillis()); } housekeeping(); return result; } public void putAll(Map<? extends K,? extends V> map){ housekeeping(); for(Object o : map.entrySet()){ Map.Entry me = (Map.Entry) o; put((K)me.getKey(),(V)me.getValue()); } } public void housekeeping(){ Thread t = new Thread(); t.start(); } public void run(){ while(queue.size() > size){ Object key = queue.poll(); if(key != null){ cache.remove(key); queue.remove(key); cacheDates.remove(key); } } Long now = System.currentTimeMillis(); if(lastSpringCleaning + springCleaningInterval < now){ springCleaning(now); } } public void springCleaning(Long now){ Object key; for(Map.Entry<? extends K,Long> me : cacheDates.entrySet()){ if(me.getValue() + timeToLive < now){ key = me.getKey(); cache.remove(key); queue.remove(key); cacheDates.remove(key); } } } }
Revision: 34995
Initial Code
Initial URL
Initial Description
Initial Title
Initial Tags
Initial Language
at November 1, 2010 03:11 by kubaitis
Initial Code
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; public class ConcurrentCacheMap<K,V> extends Thread implements ConcurrentMap<K,V>, Serializable { private ConcurrentLinkedQueue<K> queue; private ConcurrentHashMap<K,V> cache; private ConcurrentHashMap<K,Long> cacheDates; private Long lastSpringCleaning; private Long timeToLive; private Long springCleaningInterval; private Integer size; public ConcurrentCacheMap(){ System.out.println("ConcurrentCacheMap(): a."); queue = new ConcurrentLinkedQueue<K>(); cache = new ConcurrentHashMap<K,V>(); size = 5000; lastSpringCleaning = System.currentTimeMillis(); cacheDates = new ConcurrentHashMap<K,Long>(); timeToLive = 1000L * 60L * 15L; springCleaningInterval = 1000L * 60L; } public ConcurrentCacheMap(int size){ System.out.println("ConcurrentCacheMap(): b."); queue = new ConcurrentLinkedQueue<K>(); cache = new ConcurrentHashMap<K,V>(); this.size = size; lastSpringCleaning = System.currentTimeMillis(); cacheDates = new ConcurrentHashMap<K,Long>(); timeToLive = 1000L * 60L * 15L; springCleaningInterval = 1000L * 60L; } public ConcurrentCacheMap(int size,long timeToLive){ System.out.println("ConcurrentCacheMap(): c."); queue = new ConcurrentLinkedQueue<K>(); cache = new ConcurrentHashMap<K,V>(); this.size = size; lastSpringCleaning = System.currentTimeMillis(); cacheDates = new ConcurrentHashMap<K,Long>(); this.timeToLive = timeToLive; springCleaningInterval = 1000L * 60L; } public ConcurrentCacheMap(int size,long timeToLive,long springCleaningInterval){ System.out.println("ConcurrentCacheMap(): d."); queue = new ConcurrentLinkedQueue<K>(); cache = new ConcurrentHashMap<K,V>(); this.size = size; lastSpringCleaning = System.currentTimeMillis(); cacheDates = new ConcurrentHashMap<K,Long>(); this.timeToLive = timeToLive; this.springCleaningInterval = springCleaningInterval; } public V get(Object key){ V result = cache.get(key); housekeeping(); return result; } 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 Set<Map.Entry<K,V>> entrySet(){ housekeeping(); return cache.entrySet(); } 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 setMaxSize(Integer size){ this.size = size; } public void setTimeToLive(Long timeToLive){ this.timeToLive = timeToLive; } public void setSpringCleaningInterval(Long springCleaningInterval){ this.springCleaningInterval = springCleaningInterval; } public Integer getMaxSize(){ return size; } public Long getTimeToLive(){ return timeToLive; } public boolean containsKey(Object key){return cache.containsKey(key);} public boolean containsValue(Object value){return cache.containsValue(value);} public boolean isEmpty(){return cache.isEmpty();} public int size(){ return cache.size(); } public Long getSpringCleaningInterval(){ return springCleaningInterval; } public V remove(Object key){ V result = cache.remove(key); queue.remove(key); cacheDates.remove(key); housekeeping(); return result; } public boolean remove(Object key,Object value){ 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); cacheDates.put(key,System.currentTimeMillis()); } 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); cacheDates.put((K)key,System.currentTimeMillis()); } else { result = cache.get(key); cache.replace((K)key,(V)object); cacheDates.replace((K)key,System.currentTimeMillis()); } housekeeping(); return result; } public void putAll(Map<? extends K,? extends V> map){ housekeeping(); for(Object o : map.entrySet()){ Map.Entry me = (Map.Entry) o; put((K)me.getKey(),(V)me.getValue()); } } public void housekeeping(){ Thread t = new Thread(); t.start(); } public void run(){ while(queue.size() > size){ Object key = queue.poll(); if(key != null){ cache.remove(key); queue.remove(key); cacheDates.remove(key); } } Long now = System.currentTimeMillis(); if(lastSpringCleaning + springCleaningInterval < now){ springCleaning(now); } } public void springCleaning(Long now){ Object key; for(Map.Entry<? extends K,Long> me : cacheDates.entrySet()){ if(me.getValue() + timeToLive < now){ key = me.getKey(); cache.remove(key); queue.remove(key); cacheDates.remove(key); } } } }
Initial URL
Initial Description
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.
Initial Title
ConcurrentCacheMap
Initial Tags
cache
Initial Language
Java