package org.lodder.subtools.sublibrary.cache; import java.util.ArrayList; import org.apache.commons.collections4.MapIterator; import org.apache.commons.collections4.map.LRUMap; /** * @author Crunchify.com */ public class InMemoryCache<K, T> { private long timeToLive; @SuppressWarnings("rawtypes") protected LRUMap cacheMap; @SuppressWarnings("rawtypes") public InMemoryCache(long crunchifyTimeToLive, final long crunchifyTimerInterval, int maxItems) { this.timeToLive = crunchifyTimeToLive * 1000; cacheMap = new LRUMap(maxItems); if (timeToLive > 0 && crunchifyTimerInterval > 0) { createCleanUpThread(crunchifyTimerInterval); } } private void createCleanUpThread(final long timerInterval) { Thread t = new Thread(new Runnable() { public void run() { while (true) { try { Thread.sleep(timerInterval * 1000); } catch (InterruptedException ex) {} cleanup(); } } }); t.setDaemon(true); t.start(); } @SuppressWarnings("unchecked") public void put(K key, T value) { synchronized (cacheMap) { cacheMap.put(key, new CacheObject<K, T>(value)); } } public boolean exists(K key) { synchronized (cacheMap) { return cacheMap.containsKey(key); } } @SuppressWarnings("unchecked") public T get(K key) { synchronized (cacheMap) { CacheObject<K, T> c = (CacheObject<K, T>) cacheMap.get(key); if (c == null) return null; else { c.lastAccessed = System.currentTimeMillis(); return c.value; } } } public void remove(K key) { synchronized (cacheMap) { cacheMap.remove(key); } } public int size() { synchronized (cacheMap) { return cacheMap.size(); } } @SuppressWarnings({"unchecked", "rawtypes"}) public void cleanup() { long now = System.currentTimeMillis(); ArrayList<K> deleteKey = null; synchronized (cacheMap) { MapIterator itr = cacheMap.mapIterator(); deleteKey = new ArrayList<K>((cacheMap.size() / 2) + 1); K key = null; CacheObject<K, T> c = null; while (itr.hasNext()) { key = (K) itr.next(); c = (CacheObject<K, T>) itr.getValue(); if (c != null && (now > (timeToLive + c.created))) { deleteKey.add(key); } } } for (K key : deleteKey) { synchronized (cacheMap) { cacheMap.remove(key); } Thread.yield(); } } }