Updated size of internal HashMap and rotation threshold to avoid

rehashing to take place in internal maps.

Provided setCapacity() method to change cache capacity during runtime.
This commit is contained in:
hns 2002-09-17 22:43:19 +00:00
parent d4f379a54d
commit 2dda7607c5

View file

@ -44,9 +44,6 @@ import java.util.HashMap;
public class CacheMap {
// Number of buckets.
private static final int nBuckets = 2;
// Load factor.
private float loadFactor;
@ -82,11 +79,17 @@ public class CacheMap {
if ( initialCapacity <= 0 || loadFactor <= 0.0 )
throw new IllegalArgumentException();
this.loadFactor = loadFactor;
threshold = (int) (initialCapacity * loadFactor) - 1;
eachCapacity = initialCapacity / nBuckets + 1;
oldTable = new HashMap (eachCapacity, loadFactor);
// table rotation threshold: we allow each table to gain
// initialCapacity/2 entries.
threshold = initialCapacity / 2;
// We deliberately choose the initial capacity of tables large
// enough that it can hold threshold entries without being rehashed,
// in other words, make sure our threshold for table rotation is lower
// than that of the underlying HashMap for table rehashing.
eachCapacity = (int) (threshold / loadFactor) + 2;
// create tables
oldTable = new HashMap ();
newTable = new HashMap (eachCapacity, loadFactor);
// System.out.println ("CREATED NEW CACHEMAP: CAP="+initialCapacity+" EACH="+eachCapacity+" THRES="+threshold);
}
/// Constructs a new, empty hashtable with the specified initial
@ -109,6 +112,28 @@ public class CacheMap {
}
/// Set the capacity of the CacheMap
public void setCapacity(int capacity) {
// table rotation threshold: we allow each table to gain
// initialCapacity/2 entries.
int newThreshold = capacity / 2;
if (newThreshold != threshold) {
if (logger != null)
logger.log ("Setting cache capacity to "+capacity);
updateThreshold (newThreshold);
}
}
private synchronized void updateThreshold (int newThreshold) {
threshold = newThreshold;
eachCapacity = (int) (threshold / loadFactor) + 2;
// if newtable is larger than threshold, rotate.
if (newTable.size() > threshold) {
oldTable = newTable;
newTable = new HashMap (eachCapacity, loadFactor);
}
}
/// Returns true if the specified object is an element of the hashtable.
// This operation is more expensive than the containsKey() method.
// @param value the value that we are looking for
@ -207,7 +232,7 @@ public class CacheMap {
if (oldValue != null)
oldTable.remove( key );
else {
if (newTable.size() >= eachCapacity) {
if (newTable.size() >= threshold) {
// Rotate the tables.
if (logger != null)
logger.log ("Rotating Cache tables at "+newTable.size()+"/"+oldTable.size()+" (new/old)");