From Mike Thomas: IntIntMap now grows and shrinks.
git-svn-id: https://samskivert.googlecode.com/svn/trunk@1734 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
@@ -46,14 +46,32 @@ public class IntIntMap
|
||||
|
||||
public final static int DEFAULT_BUCKETS = 64;
|
||||
|
||||
public IntIntMap (int buckets)
|
||||
/**
|
||||
* The default load factor.
|
||||
*/
|
||||
public final static float DEFAULT_LOAD_FACTOR = 1.75f;
|
||||
|
||||
/**
|
||||
* The shrink factor.
|
||||
* When the number of elements multiplied by this number is less
|
||||
* than the size of the array, we shrink the array by half.
|
||||
*/
|
||||
protected static final int SHRINK_FACTOR = 8;
|
||||
|
||||
public IntIntMap (int buckets, float loadFactor)
|
||||
{
|
||||
_buckets = new Record[buckets];
|
||||
_loadFactor = loadFactor;
|
||||
}
|
||||
|
||||
public IntIntMap (int buckets)
|
||||
{
|
||||
this(buckets, DEFAULT_LOAD_FACTOR);
|
||||
}
|
||||
|
||||
public IntIntMap ()
|
||||
{
|
||||
this(DEFAULT_BUCKETS);
|
||||
this(DEFAULT_BUCKETS, DEFAULT_LOAD_FACTOR);
|
||||
}
|
||||
|
||||
public int size ()
|
||||
@@ -65,7 +83,10 @@ public class IntIntMap
|
||||
{
|
||||
_modCount++;
|
||||
|
||||
int index = Math.abs(key)%_buckets.length;
|
||||
// check to see if we've passed our load factor, if so: resize
|
||||
checkGrow();
|
||||
|
||||
int index = Math.abs(key)%_buckets.length;
|
||||
Record rec = _buckets[index];
|
||||
|
||||
// either we start a new chain
|
||||
@@ -133,7 +154,9 @@ public class IntIntMap
|
||||
public int remove (int key)
|
||||
{
|
||||
_modCount++;
|
||||
return removeImpl(key);
|
||||
int removed = removeImpl(key);
|
||||
checkShrink();
|
||||
return removed;
|
||||
}
|
||||
|
||||
protected int removeImpl (int key)
|
||||
@@ -170,6 +193,53 @@ public class IntIntMap
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if we want to shrink the table.
|
||||
*/
|
||||
protected void checkShrink ()
|
||||
{
|
||||
if ((_buckets.length > DEFAULT_BUCKETS) &&
|
||||
(_size * SHRINK_FACTOR < _buckets.length)) {
|
||||
resizeBuckets(_buckets.length >> 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if we want to grow the table.
|
||||
*/
|
||||
protected void checkGrow ()
|
||||
{
|
||||
if (_size > (int) (_buckets.length * _loadFactor)) {
|
||||
resizeBuckets(_buckets.length << 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resize the hashtable.
|
||||
*
|
||||
* @param newsize The new number of buckets to allocate.
|
||||
*/
|
||||
protected void resizeBuckets (int newsize)
|
||||
{
|
||||
Record[] oldbuckets = _buckets;
|
||||
_buckets = new Record[newsize];
|
||||
|
||||
// we shuffle the records around without allocating new ones
|
||||
int index = oldbuckets.length;
|
||||
while (index-- > 0) {
|
||||
Record oldrec = oldbuckets[index];
|
||||
while (oldrec != null) {
|
||||
Record newrec = oldrec;
|
||||
oldrec = oldrec.next;
|
||||
|
||||
// always put the newrec at the start of a chain
|
||||
int newdex = Math.abs(newrec.key)%_buckets.length;
|
||||
newrec.next = _buckets[newdex];
|
||||
_buckets[newdex] = newrec;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Interator keys ()
|
||||
{
|
||||
return new KeyValueInterator(true);
|
||||
@@ -416,5 +486,7 @@ public class IntIntMap
|
||||
private Record[] _buckets;
|
||||
private int _size;
|
||||
|
||||
protected float _loadFactor;
|
||||
|
||||
protected int _modCount = 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user