Skip to content
This repository has been archived by the owner on Jun 8, 2018. It is now read-only.

Commit

Permalink
Begin Implementation of Cache
Browse files Browse the repository at this point in the history
This is the initial commit of cache interfaces and classes.
It's very rough, *everything* will probably change.
  • Loading branch information
AlexV committed Aug 26, 2011
1 parent 499c69d commit 7a2a8c8
Show file tree
Hide file tree
Showing 4 changed files with 198 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/main/java/us/harward/commons/cache/Cache.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package us.harward.commons.cache;

public interface Cache<K, V> {

void put(final K key, final V value);

V get(final K key);

V remove(final K key);
}
59 changes: 59 additions & 0 deletions src/main/java/us/harward/commons/cache/TTLCache.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package us.harward.commons.cache;

public class TTLCache<K, V> implements Cache<K, V> {

private final Cache<K, TTLCache.TTLEntry<V>> cache;
private final long defaultTTLMillis;

public TTLCache(final long defaultTTLMillis, final Cache<K, TTLCache.TTLEntry<V>> cache) {
this.cache = cache;
this.defaultTTLMillis = defaultTTLMillis;
}

@Override
public void put(final K key, final V value) {
final TTLEntry<V> e = new TTLEntry<V>(value, System.currentTimeMillis() + defaultTTLMillis);
cache.put(key, e);
}

public void put(final K key, final V value, final long ttlMillis) {
final TTLEntry<V> e = new TTLEntry<V>(value, System.currentTimeMillis() + ttlMillis);
cache.put(key, e);
}

@Override
public V get(final K key) {
final TTLEntry<V> e = cache.get(key);
return e != null && e.isValid() ? e.getValue() : null;
}

@Override
public V remove(K key) {
final TTLEntry<V> e = cache.remove(key);
return e != null && e.isValid() ? e.getValue() : null;
}

public static class TTLEntry<V> {

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();
}
}

}
97 changes: 97 additions & 0 deletions src/main/java/us/harward/commons/cache/heap/HeapCache.java
Original file line number Diff line number Diff line change
@@ -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 <K>
* @param <V>
*/
public class HeapCache<K, V> implements Cache<K, V> {

private final int maxSize;
private final ConcurrentHashMap<K, Entry<V>> map = new ConcurrentHashMap<K, Entry<V>>();

public HeapCache(int maxSize) {
super();
this.maxSize = maxSize;
}

@Override
public void put(K key, V value) {
final Entry<V> e = new Entry<V>(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<V> e = map.get(key);
if (e == null) {
return null;
} else {
e.recordHit();
return e.getValue();
}
}

@Override
public V remove(K key) {
Entry<V> e = map.remove(key);
return e == null ? null : e.getValue();
}

private static class Entry<V> {

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;
}

}

}
32 changes: 32 additions & 0 deletions src/main/java/us/harward/commons/cache/heap/SoftRefHeapCache.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package us.harward.commons.cache.heap;

import java.lang.ref.SoftReference;

import us.harward.commons.cache.Cache;

public class SoftRefHeapCache<K, V> implements Cache<K, V> {

private final HeapCache<K, SoftReference<V>> cache;

public SoftRefHeapCache(final int maxSize) {
this.cache = new HeapCache<K, SoftReference<V>>(maxSize);
}

@Override
public void put(K key, V value) {
cache.put(key, new SoftReference<V>(value));
}

@Override
public V get(K key) {
final SoftReference<V> ref = cache.get(key);
return ref == null ? null : ref.get();
}

@Override
public V remove(K key) {
final SoftReference<V> ref = cache.remove(key);
return ref == null ? null : ref.get();
}

}

1 comment on commit 7a2a8c8

@nharward
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sasha - what about the cache implementation in Guava? Looks very similar to our needs.

Please sign in to comment.