Commit 1eea06ba authored by Alex Wenckus's avatar Alex Wenckus Committed by alex

Generalized the Cache. JM-597

git-svn-id: http://svn.igniterealtime.org/svn/repos/wildfire/trunk@3612 b35dd754-fafc-0310-a699-88a17e54d16e
parent 32867543
...@@ -41,12 +41,12 @@ import java.util.*; ...@@ -41,12 +41,12 @@ import java.util.*;
* *
* @author Matt Tucker * @author Matt Tucker
*/ */
public class Cache implements Map { public class Cache<K, V> implements Map<K, V> {
/** /**
* The map the keys and values are stored in. * The map the keys and values are stored in.
*/ */
protected Map map; protected Map<K, CacheObject<V>> map;
/** /**
* Linked list to maintain order that cache objects are accessed * Linked list to maintain order that cache objects are accessed
...@@ -107,13 +107,13 @@ public class Cache implements Map { ...@@ -107,13 +107,13 @@ public class Cache implements Map {
// Our primary data structure is a HashMap. The default capacity of 11 // Our primary data structure is a HashMap. The default capacity of 11
// is too small in almost all cases, so we set it bigger. // is too small in almost all cases, so we set it bigger.
map = new HashMap(103); map = new HashMap<K, CacheObject<V>>(103);
lastAccessedList = new LinkedList(); lastAccessedList = new LinkedList();
ageList = new LinkedList(); ageList = new LinkedList();
} }
public synchronized Object put(Object key, Object value) { public synchronized V put(K key, V value) {
// Delete an old entry if it exists. // Delete an old entry if it exists.
remove(key); remove(key);
...@@ -126,7 +126,7 @@ public class Cache implements Map { ...@@ -126,7 +126,7 @@ public class Cache implements Map {
return value; return value;
} }
cacheSize += objectSize; cacheSize += objectSize;
CacheObject cacheObject = new CacheObject(value, objectSize); CacheObject<V> cacheObject = new CacheObject<V>(value, objectSize);
map.put(key, cacheObject); map.put(key, cacheObject);
// Make an entry into the cache order list. // Make an entry into the cache order list.
LinkedListNode lastAccessedNode = lastAccessedList.addFirst(key); LinkedListNode lastAccessedNode = lastAccessedList.addFirst(key);
...@@ -147,12 +147,12 @@ public class Cache implements Map { ...@@ -147,12 +147,12 @@ public class Cache implements Map {
return value; return value;
} }
public synchronized Object get(Object key) { public synchronized V get(Object key) {
// First, clear all entries that have been in cache longer than the // First, clear all entries that have been in cache longer than the
// maximum defined age. // maximum defined age.
deleteExpiredEntries(); deleteExpiredEntries();
CacheObject cacheObject = (CacheObject)map.get(key); CacheObject<V> cacheObject = map.get(key);
if (cacheObject == null) { if (cacheObject == null) {
// The object didn't exist in cache, so increment cache misses. // The object didn't exist in cache, so increment cache misses.
cacheMisses++; cacheMisses++;
...@@ -172,8 +172,8 @@ public class Cache implements Map { ...@@ -172,8 +172,8 @@ public class Cache implements Map {
return cacheObject.object; return cacheObject.object;
} }
public synchronized Object remove(Object key) { public synchronized V remove(Object key) {
CacheObject cacheObject = (CacheObject)map.get(key); CacheObject<V> cacheObject = map.get(key);
// If the object is not in cache, stop trying to remove it. // If the object is not in cache, stop trying to remove it.
if (cacheObject == null) { if (cacheObject == null) {
return null; return null;
...@@ -225,17 +225,111 @@ public class Cache implements Map { ...@@ -225,17 +225,111 @@ public class Cache implements Map {
return map.isEmpty(); return map.isEmpty();
} }
public Collection values() { public Collection<V> values() {
// First, clear all entries that have been in cache longer than the // First, clear all entries that have been in cache longer than the
// maximum defined age. // maximum defined age.
deleteExpiredEntries(); deleteExpiredEntries();
return new CacheObjectCollection(map.values());
}
/**
* Wraps a cached object collection to return a view of its inner objects
*/
private final class CacheObjectCollection<V> implements Collection<V> {
private Collection<CacheObject<V>> cachedObjects;
private CacheObjectCollection(Collection<CacheObject<V>> cachedObjects) {
this.cachedObjects = new ArrayList<CacheObject<V>>(cachedObjects);
}
public int size() {
return cachedObjects.size();
}
public boolean isEmpty() {
return size() == 0;
}
public boolean contains(Object o) {
Iterator<V> it = iterator();
while (it.hasNext()) {
if (it.next().equals(o)) {
return true;
}
}
return false;
}
public Iterator<V> iterator() {
return new Iterator<V>() {
private final Iterator<CacheObject<V>> it = cachedObjects.iterator();
public boolean hasNext() {
return it.hasNext();
}
public V next() {
return it.next().object;
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
public Object[] toArray() {
Object[] array = new Object[size()];
Iterator it = iterator();
int i = 0;
while (it.hasNext()) {
array[i] = it.next();
}
return array;
}
public <V>V[] toArray(V[] a) {
Iterator<V> it = (Iterator<V>) iterator();
int i = 0;
while (it.hasNext()) {
a[i++] = it.next();
}
return a;
}
public boolean containsAll(Collection<?> c) {
Iterator it = c.iterator();
while(it.hasNext()) {
if(!contains(it.next())) {
return false;
}
}
return true;
}
public boolean add(V o) {
throw new UnsupportedOperationException();
}
public boolean remove(Object o) {
throw new UnsupportedOperationException();
}
public boolean addAll(Collection<? extends V> coll) {
throw new UnsupportedOperationException();
}
public boolean removeAll(Collection<?> coll) {
throw new UnsupportedOperationException();
}
public boolean retainAll(Collection<?> coll) {
throw new UnsupportedOperationException();
}
Object[] cacheObjects = map.values().toArray(); public void clear() {
Object[] values = new Object[cacheObjects.length]; throw new UnsupportedOperationException();
for (int i = 0; i < cacheObjects.length; i++) {
values[i] = ((CacheObject)cacheObjects[i]).object;
} }
return Collections.unmodifiableList(Arrays.asList(values));
} }
public boolean containsKey(Object key) { public boolean containsKey(Object key) {
...@@ -246,10 +340,10 @@ public class Cache implements Map { ...@@ -246,10 +340,10 @@ public class Cache implements Map {
return map.containsKey(key); return map.containsKey(key);
} }
public void putAll(Map map) { public void putAll(Map<? extends K, ? extends V> map) {
for (Iterator i = map.keySet().iterator(); i.hasNext();) { for (Iterator<? extends K> i = map.keySet().iterator(); i.hasNext();) {
Object key = i.next(); K key = i.next();
Object value = map.get(key); V value = map.get(key);
put(key, value); put(key, value);
} }
} }
...@@ -272,7 +366,7 @@ public class Cache implements Map { ...@@ -272,7 +366,7 @@ public class Cache implements Map {
return Collections.unmodifiableSet(map.entrySet()); return Collections.unmodifiableSet(map.entrySet());
} }
public Set keySet() { public Set<K> keySet() {
// First, clear all entries that have been in cache longer than the // First, clear all entries that have been in cache longer than the
// maximum defined age. // maximum defined age.
deleteExpiredEntries(); deleteExpiredEntries();
...@@ -489,12 +583,12 @@ public class Cache implements Map { ...@@ -489,12 +583,12 @@ public class Cache implements Map {
* references to the linked lists that maintain the creation time of the object * references to the linked lists that maintain the creation time of the object
* and the ordering of the most used objects. * and the ordering of the most used objects.
*/ */
private static class CacheObject { private static class CacheObject<V> {
/** /**
* Underlying object wrapped by the CacheObject. * Underlying object wrapped by the CacheObject.
*/ */
public Object object; public V object;
/** /**
* The size of the Cacheable object. The size of the Cacheable * The size of the Cacheable object. The size of the Cacheable
...@@ -532,7 +626,7 @@ public class Cache implements Map { ...@@ -532,7 +626,7 @@ public class Cache implements Map {
* @param object the underlying Object to wrap. * @param object the underlying Object to wrap.
* @param size the size of the Cachable object in bytes. * @param size the size of the Cachable object in bytes.
*/ */
public CacheObject(Object object, int size) { public CacheObject(V object, int size) {
this.object = object; this.object = object;
this.size = size; this.size = size;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment