Posted By


kubaitis on 11/01/10

Tagged


Statistics


Viewed 768 times
Favorited by 1 user(s)

ConcurrentCacheMap


/ Published in: Java
Save to your folder(s)

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.


Copy this code and paste it in your HTML
  1. import java.util.concurrent.ConcurrentMap;
  2. import java.util.concurrent.ConcurrentLinkedQueue;
  3. import java.util.concurrent.ConcurrentHashMap;
  4. import java.util.Set;
  5. import java.util.Collection;
  6. import java.util.Map;
  7. import java.io.Serializable;
  8. public class ConcurrentCacheMap<K,V> extends Thread implements ConcurrentMap<K,V>, Serializable {
  9. private ConcurrentLinkedQueue<K> queue;
  10. private ConcurrentHashMap<K,V> cache;
  11. private ConcurrentHashMap<K,Long> cacheDates;
  12. private Long lastSpringCleaning;
  13. private Long timeToLive;
  14. private Long springCleaningInterval;
  15. private Integer size;
  16. public ConcurrentCacheMap(){
  17. queue = new ConcurrentLinkedQueue<K>();
  18. cache = new ConcurrentHashMap<K,V>();
  19. size = 5000;
  20. lastSpringCleaning = System.currentTimeMillis();
  21. cacheDates = new ConcurrentHashMap<K,Long>();
  22. timeToLive = 1000L * 60L * 15L;
  23. springCleaningInterval = 1000L * 60L;
  24. }
  25. public ConcurrentCacheMap(int size){
  26. queue = new ConcurrentLinkedQueue<K>();
  27. cache = new ConcurrentHashMap<K,V>();
  28. this.size = size;
  29. lastSpringCleaning = System.currentTimeMillis();
  30. cacheDates = new ConcurrentHashMap<K,Long>();
  31. timeToLive = 1000L * 60L * 15L;
  32. springCleaningInterval = 1000L * 60L;
  33. }
  34. public ConcurrentCacheMap(int size,long timeToLive){
  35. queue = new ConcurrentLinkedQueue<K>();
  36. cache = new ConcurrentHashMap<K,V>();
  37. this.size = size;
  38. lastSpringCleaning = System.currentTimeMillis();
  39. cacheDates = new ConcurrentHashMap<K,Long>();
  40. this.timeToLive = timeToLive;
  41. springCleaningInterval = 1000L * 60L;
  42. }
  43. public ConcurrentCacheMap(int size,long timeToLive,long springCleaningInterval){
  44. queue = new ConcurrentLinkedQueue<K>();
  45. cache = new ConcurrentHashMap<K,V>();
  46. this.size = size;
  47. lastSpringCleaning = System.currentTimeMillis();
  48. cacheDates = new ConcurrentHashMap<K,Long>();
  49. this.timeToLive = timeToLive;
  50. this.springCleaningInterval = springCleaningInterval;
  51. }
  52. public V get(Object key){ V result = cache.get(key); housekeeping(); return result; }
  53. public boolean isCached(K key){ housekeeping(); return cache.containsKey(key);}
  54. public void clear(){ queue.clear(); cache.clear(); cacheDates.clear();}
  55. public Set<K> keySet(){ housekeeping(); return cache.keySet(); }
  56. public Collection<V> values(){ housekeeping(); return cache.values();}
  57. public Set<Map.Entry<K,V>> entrySet(){ housekeeping(); return cache.entrySet(); }
  58. public V replace(K key, V value){ housekeeping(); return cache.replace(key,value); }
  59. public boolean replace(K key, V oldValue,V newValue){ housekeeping(); return cache.replace(key,oldValue,newValue); }
  60. public void setMaxSize(Integer size){ this.size = size; }
  61. public void setTimeToLive(Long timeToLive){ this.timeToLive = timeToLive; }
  62. public void setSpringCleaningInterval(Long springCleaningInterval){ this.springCleaningInterval = springCleaningInterval; }
  63. public Integer getMaxSize(){ return size; }
  64. public Long getTimeToLive(){ return timeToLive; }
  65. public boolean containsKey(Object key){return cache.containsKey(key);}
  66. public boolean containsValue(Object value){return cache.containsValue(value);}
  67. public boolean isEmpty(){return cache.isEmpty();}
  68. public int size(){ return cache.size(); }
  69. public Long getSpringCleaningInterval(){ return springCleaningInterval; }
  70. public V remove(Object key){
  71. V result = cache.remove(key);
  72. queue.remove(key);
  73. cacheDates.remove(key);
  74. housekeeping();
  75. return result;
  76. }
  77. public boolean remove(Object key,Object value){
  78. boolean result = false;
  79. if(cache.get(key).equals(value)){
  80. result = cache.remove(key,value);
  81. queue.remove(key);
  82. cacheDates.remove(key);
  83. }
  84. housekeeping();
  85. return result;
  86. }
  87. public V putIfAbsent(K key,V value){
  88. V result = null;
  89. if(!cache.containsKey(key)){
  90. cache.put(key,value);
  91. queue.add(key);
  92. cacheDates.put(key,System.currentTimeMillis());
  93. } else { result = cache.get(key);}
  94. housekeeping();
  95. return result;
  96. }
  97. public V put(K key,V object){
  98. V result = null;
  99. if(!cache.containsKey(key)){
  100. cache.put((K)key,(V)object);
  101. queue.add((K)key);
  102. cacheDates.put((K)key,System.currentTimeMillis());
  103. } else {
  104. result = cache.get(key);
  105. cache.replace((K)key,(V)object);
  106. cacheDates.replace((K)key,System.currentTimeMillis());
  107. }
  108. housekeeping();
  109. return result;
  110. }
  111. public void putAll(Map<? extends K,? extends V> map){
  112. housekeeping();
  113. for(Object o : map.entrySet()){
  114. Map.Entry me = (Map.Entry) o;
  115. put((K)me.getKey(),(V)me.getValue());
  116. }
  117. }
  118. public void housekeeping(){
  119. Thread t = new Thread();
  120. t.start();
  121. }
  122. public void run(){
  123. while(queue.size() > size){
  124. Object key = queue.poll();
  125. if(key != null){
  126. cache.remove(key);
  127. queue.remove(key);
  128. cacheDates.remove(key);
  129. }
  130. }
  131. Long now = System.currentTimeMillis();
  132. if(lastSpringCleaning + springCleaningInterval < now){
  133. springCleaning(now);
  134. }
  135. }
  136. public void springCleaning(Long now){
  137. Object key;
  138. for(Map.Entry<? extends K,Long> me : cacheDates.entrySet()){
  139. if(me.getValue() + timeToLive < now){
  140. key = me.getKey();
  141. cache.remove(key);
  142. queue.remove(key);
  143. cacheDates.remove(key);
  144. }
  145. }
  146. }
  147. }

Report this snippet


Comments

RSS Icon Subscribe to comments

You need to login to post a comment.