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:
parent
d4f379a54d
commit
2dda7607c5
1 changed files with 37 additions and 12 deletions
|
@ -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)");
|
||||
|
|
Loading…
Add table
Reference in a new issue