* Introduce createTable() method in CacheMap to make internal table implementation

overrideable for subclasses.
* Add new WeakCacheMap class that uses java.util.WeakHashMap internally.
This commit is contained in:
hns 2006-04-03 13:27:04 +00:00
parent f759dbfa91
commit a90c2e6615
2 changed files with 69 additions and 9 deletions

View file

@ -29,6 +29,7 @@
// Moved to helma.util to use java.util.HashMap instead of java.util.Hashtable // Moved to helma.util to use java.util.HashMap instead of java.util.Hashtable
package helma.util; package helma.util;
import java.util.Map;
import java.util.HashMap; import java.util.HashMap;
import java.util.Properties; import java.util.Properties;
@ -59,8 +60,8 @@ public class CacheMap implements ObjectCache {
private int eachCapacity; private int eachCapacity;
// The tables. // The tables.
private HashMap oldTable; private Map oldTable;
private HashMap newTable; private Map newTable;
// the application to output messages to // the application to output messages to
private Application app = null; private Application app = null;
@ -100,9 +101,10 @@ public class CacheMap implements ObjectCache {
// in other words, make sure our threshold for table rotation is lower // in other words, make sure our threshold for table rotation is lower
// than that of the underlying HashMap for table rehashing. // than that of the underlying HashMap for table rehashing.
eachCapacity = (int) (threshold / loadFactor) + 2; eachCapacity = (int) (threshold / loadFactor) + 2;
// create tables // create tables - we'll never insert into the initial oldTable,
// it's a dummy that will be lost on the first cache rotation.
oldTable = new HashMap(); oldTable = new HashMap();
newTable = new HashMap(eachCapacity, loadFactor); newTable = createTable(eachCapacity, loadFactor);
} }
/// Constructs a new, empty hashtable with the specified initial /// Constructs a new, empty hashtable with the specified initial
@ -143,7 +145,7 @@ public class CacheMap implements ObjectCache {
// if newtable is larger than threshold, rotate. // if newtable is larger than threshold, rotate.
if (newTable.size() > threshold) { if (newTable.size() > threshold) {
oldTable = newTable; oldTable = newTable;
newTable = new HashMap(eachCapacity, loadFactor); newTable = createTable(eachCapacity, loadFactor);
} }
} }
@ -184,7 +186,7 @@ public class CacheMap implements ObjectCache {
return false; return false;
} }
/// Returns the number of keys in object array <code>keys</code> that /// Returns the number of keys in object array <code>keys</code> that
// were not found in the Map. // were not found in the Map.
// Those keys that are contained in the Map are nulled out in the array. // Those keys that are contained in the Map are nulled out in the array.
// @param keys an array of key objects we are looking for // @param keys an array of key objects we are looking for
@ -229,10 +231,10 @@ public class CacheMap implements ObjectCache {
/// Puts the specified element into the hashtable, using the specified /// Puts the specified element into the hashtable, using the specified
// key. The element may be retrieved by doing a get() with the same key. // key. The element may be retrieved by doing a get() with the same key.
// The key and the element cannot be null. // The key and the element cannot be null.
// @param key the specified key in the hashtable // @param key the specified key in the hashtable
// @param value the specified element // @param value the specified element
// @exception NullPointerException If the value of the element // @exception NullPointerException If the value of the element
// is equal to null. // is equal to null.
// @see LruHashtable#get // @see LruHashtable#get
// @return the old value of the key, or null if it did not have one. // @return the old value of the key, or null if it did not have one.
@ -252,7 +254,7 @@ public class CacheMap implements ObjectCache {
app.logEvent("Rotating Cache tables at " + newTable.size() + app.logEvent("Rotating Cache tables at " + newTable.size() +
"/" + oldTable.size() + " (new/old)"); "/" + oldTable.size() + " (new/old)");
oldTable = newTable; oldTable = newTable;
newTable = new HashMap(eachCapacity, loadFactor); newTable = createTable(eachCapacity, loadFactor);
} }
return oldValue; return oldValue;
} }
@ -307,6 +309,18 @@ public class CacheMap implements ObjectCache {
return newTable.toString() + oldTable.toString() + hashCode(); return newTable.toString() + oldTable.toString() + hashCode();
} }
/**
* Override this method to use custom Map implementations. The
* default implementation returns a java.util.HashMap instance.
*
* @param capacity the initial capacity
* @param loadFactor the load factor
* @return a new Map used for internal caching
*/
protected Map createTable(int capacity, float loadFactor) {
return new HashMap(capacity, loadFactor);
}
} }

View file

@ -0,0 +1,46 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.util;
import java.util.Map;
import java.util.WeakHashMap;
/**
* A CacheMap subclass that uses WeakHashMaps internally for its
* rotating tables.
*/
public class WeakCacheMap extends CacheMap {
public WeakCacheMap(int capacity) {
super(capacity);
}
public WeakCacheMap(int capacity, float loadFactor) {
super(capacity, loadFactor);
}
/**
* Overridden to return a java.util.WeakHashMap instance.
*
* @param capacity the initial capacity
* @param loadFactor the load factor
* @return a new Map used for internal caching
*/
protected Map createTable(int capacity, float loadFactor) {
return new WeakHashMap(capacity, loadFactor);
}
}