From 7a2a8c8f8d76a8e3dd511d84daf3cb5be8d15e49 Mon Sep 17 00:00:00 2001 From: AlexV Date: Fri, 26 Aug 2011 00:29:51 -0700 Subject: [PATCH] Begin Implementation of Cache This is the initial commit of cache interfaces and classes. It's very rough, *everything* will probably change. --- .../java/us/harward/commons/cache/Cache.java | 10 ++ .../us/harward/commons/cache/TTLCache.java | 59 +++++++++++ .../harward/commons/cache/heap/HeapCache.java | 97 +++++++++++++++++++ .../commons/cache/heap/SoftRefHeapCache.java | 32 ++++++ 4 files changed, 198 insertions(+) create mode 100644 src/main/java/us/harward/commons/cache/Cache.java create mode 100644 src/main/java/us/harward/commons/cache/TTLCache.java create mode 100644 src/main/java/us/harward/commons/cache/heap/HeapCache.java create mode 100644 src/main/java/us/harward/commons/cache/heap/SoftRefHeapCache.java diff --git a/src/main/java/us/harward/commons/cache/Cache.java b/src/main/java/us/harward/commons/cache/Cache.java new file mode 100644 index 0000000..4743480 --- /dev/null +++ b/src/main/java/us/harward/commons/cache/Cache.java @@ -0,0 +1,10 @@ +package us.harward.commons.cache; + +public interface Cache { + + void put(final K key, final V value); + + V get(final K key); + + V remove(final K key); +} diff --git a/src/main/java/us/harward/commons/cache/TTLCache.java b/src/main/java/us/harward/commons/cache/TTLCache.java new file mode 100644 index 0000000..b2981cc --- /dev/null +++ b/src/main/java/us/harward/commons/cache/TTLCache.java @@ -0,0 +1,59 @@ +package us.harward.commons.cache; + +public class TTLCache implements Cache { + + private final Cache> cache; + private final long defaultTTLMillis; + + public TTLCache(final long defaultTTLMillis, final Cache> cache) { + this.cache = cache; + this.defaultTTLMillis = defaultTTLMillis; + } + + @Override + public void put(final K key, final V value) { + final TTLEntry e = new TTLEntry(value, System.currentTimeMillis() + defaultTTLMillis); + cache.put(key, e); + } + + public void put(final K key, final V value, final long ttlMillis) { + final TTLEntry e = new TTLEntry(value, System.currentTimeMillis() + ttlMillis); + cache.put(key, e); + } + + @Override + public V get(final K key) { + final TTLEntry e = cache.get(key); + return e != null && e.isValid() ? e.getValue() : null; + } + + @Override + public V remove(K key) { + final TTLEntry e = cache.remove(key); + return e != null && e.isValid() ? e.getValue() : null; + } + + public static class TTLEntry { + + private final V value; + private final long expireMillis; + + public TTLEntry(final V value, final long expireMillis) { + this.value = value; + this.expireMillis = expireMillis; + } + + public V getValue() { + return value; + } + + public long getExpireMillis() { + return expireMillis; + } + + public boolean isValid() { + return expireMillis >= System.currentTimeMillis(); + } + } + +} diff --git a/src/main/java/us/harward/commons/cache/heap/HeapCache.java b/src/main/java/us/harward/commons/cache/heap/HeapCache.java new file mode 100644 index 0000000..f44d91e --- /dev/null +++ b/src/main/java/us/harward/commons/cache/heap/HeapCache.java @@ -0,0 +1,97 @@ +package us.harward.commons.cache.heap; + +import java.util.concurrent.ConcurrentHashMap; + +import us.harward.commons.cache.Cache; + +/** + * Enforces maximum number of entries + * + * @author alex + * @param + * @param + */ +public class HeapCache implements Cache { + + private final int maxSize; + private final ConcurrentHashMap> map = new ConcurrentHashMap>(); + + public HeapCache(int maxSize) { + super(); + this.maxSize = maxSize; + } + + @Override + public void put(K key, V value) { + final Entry e = new Entry(value); + map.put(key, e); + if (map.size() > maxSize) { + purge(); + } + } + + private void purge() { + // TODO Auto-generated method stub + } + + @Override + public V get(K key) { + final Entry e = map.get(key); + if (e == null) { + return null; + } else { + e.recordHit(); + return e.getValue(); + } + } + + @Override + public V remove(K key) { + Entry e = map.remove(key); + return e == null ? null : e.getValue(); + } + + private static class Entry { + + private final V value; + private final long createMillis; + private long accessMillis; + private long hitCount; + + protected Entry(final V value) { + this(value, System.currentTimeMillis(), 0, 0); + } + + protected Entry(V value, long createMillis, long accessMillis, long hitCount) { + this.value = value; + this.createMillis = createMillis; + this.accessMillis = accessMillis; + this.hitCount = hitCount; + } + + public void recordHit() { + synchronized (this) { + accessMillis = System.currentTimeMillis(); + hitCount++; + } + } + + public V getValue() { + return value; + } + + public long getCreateMillis() { + return createMillis; + } + + public long getAccessMillis() { + return accessMillis; + } + + public long getHitCount() { + return hitCount; + } + + } + +} diff --git a/src/main/java/us/harward/commons/cache/heap/SoftRefHeapCache.java b/src/main/java/us/harward/commons/cache/heap/SoftRefHeapCache.java new file mode 100644 index 0000000..45a0b49 --- /dev/null +++ b/src/main/java/us/harward/commons/cache/heap/SoftRefHeapCache.java @@ -0,0 +1,32 @@ +package us.harward.commons.cache.heap; + +import java.lang.ref.SoftReference; + +import us.harward.commons.cache.Cache; + +public class SoftRefHeapCache implements Cache { + + private final HeapCache> cache; + + public SoftRefHeapCache(final int maxSize) { + this.cache = new HeapCache>(maxSize); + } + + @Override + public void put(K key, V value) { + cache.put(key, new SoftReference(value)); + } + + @Override + public V get(K key) { + final SoftReference ref = cache.get(key); + return ref == null ? null : ref.get(); + } + + @Override + public V remove(K key) { + final SoftReference ref = cache.remove(key); + return ref == null ? null : ref.get(); + } + +}