Merge branch 'flexiblehashmap' of github.com:sharwell/antlr4

This commit is contained in:
Terence Parr 2012-09-16 15:11:29 -07:00
commit ce38d61f3a
1 changed files with 38 additions and 30 deletions

View File

@ -15,9 +15,9 @@ public class FlexibleHashMap<K,V> implements EquivalenceMap<K,V> {
public static final int INITAL_BUCKET_CAPACITY = 8; public static final int INITAL_BUCKET_CAPACITY = 8;
public static final double LOAD_FACTOR = 0.75; public static final double LOAD_FACTOR = 0.75;
public class Entry { public static class Entry<K, V> {
K key; public final K key;
V value; public V value;
public Entry(K key, V value) { this.key = key; this.value = value; } public Entry(K key, V value) { this.key = key; this.value = value; }
@ -27,7 +27,7 @@ public class FlexibleHashMap<K,V> implements EquivalenceMap<K,V> {
} }
} }
protected LinkedList<Entry>[] buckets; protected LinkedList<Entry<K, V>>[] buckets;
/** How many elements in set */ /** How many elements in set */
protected int n = 0; protected int n = 0;
@ -42,13 +42,19 @@ public class FlexibleHashMap<K,V> implements EquivalenceMap<K,V> {
} }
public FlexibleHashMap(int initialCapacity, int initialBucketCapacity) { public FlexibleHashMap(int initialCapacity, int initialBucketCapacity) {
buckets = (LinkedList<Entry>[])new LinkedList[initialCapacity]; buckets = createEntryListArray(initialBucketCapacity);
this.initialBucketCapacity = initialBucketCapacity; this.initialBucketCapacity = initialBucketCapacity;
} }
private static <K, V> LinkedList<Entry<K, V>>[] createEntryListArray(int length) {
@SuppressWarnings("unchecked")
LinkedList<Entry<K, V>>[] result = (LinkedList<Entry<K, V>>[])new LinkedList<?>[length];
return result;
}
@Override @Override
public boolean equals(K a, K b) { public boolean equals(K keyA, K keyB) {
return a.equals(b); return keyA.equals(keyB);
} }
@Override @Override
@ -63,14 +69,15 @@ public class FlexibleHashMap<K,V> implements EquivalenceMap<K,V> {
} }
@Override @Override
public V get(Object o) { public V get(Object key) {
K key = (K)o; @SuppressWarnings("unchecked")
K typedKey = (K)key;
if ( key==null ) return null; if ( key==null ) return null;
int b = getBucket(key); int b = getBucket(typedKey);
LinkedList<Entry> bucket = buckets[b]; LinkedList<Entry<K, V>> bucket = buckets[b];
if ( bucket==null ) return null; // no bucket if ( bucket==null ) return null; // no bucket
for (Entry e : bucket) { for (Entry<K, V> e : bucket) {
if ( equals(e.key, key) ) return e.value; // use special equals if ( equals(e.key, typedKey) ) return e.value; // use special equals
} }
return null; return null;
} }
@ -80,11 +87,11 @@ public class FlexibleHashMap<K,V> implements EquivalenceMap<K,V> {
if ( key==null ) return null; if ( key==null ) return null;
if ( n > threshold ) expand(); if ( n > threshold ) expand();
int b = getBucket(key); int b = getBucket(key);
LinkedList<Entry> bucket = buckets[b]; LinkedList<Entry<K, V>> bucket = buckets[b];
if ( bucket==null ) { if ( bucket==null ) {
bucket = buckets[b] = new LinkedList<Entry>(); bucket = buckets[b] = new LinkedList<Entry<K, V>>();
} }
for (Entry e : bucket) { for (Entry<K, V> e : bucket) {
if ( equals(e.key, key) ) { if ( equals(e.key, key) ) {
V prev = e.value; V prev = e.value;
e.value = value; e.value = value;
@ -93,7 +100,7 @@ public class FlexibleHashMap<K,V> implements EquivalenceMap<K,V> {
} }
} }
// not there // not there
bucket.add(new Entry(key, value)); bucket.add(new Entry<K, V>(key, value));
n++; n++;
return null; return null;
} }
@ -116,9 +123,9 @@ public class FlexibleHashMap<K,V> implements EquivalenceMap<K,V> {
@Override @Override
public Collection<V> values() { public Collection<V> values() {
List<V> a = new ArrayList<V>(size()); List<V> a = new ArrayList<V>(size());
for (LinkedList<Entry> bucket : buckets) { for (LinkedList<Entry<K, V>> bucket : buckets) {
if ( bucket==null ) continue; if ( bucket==null ) continue;
for (Entry e : bucket) { for (Entry<K, V> e : bucket) {
a.add(e.value); a.add(e.value);
} }
} }
@ -143,9 +150,9 @@ public class FlexibleHashMap<K,V> implements EquivalenceMap<K,V> {
@Override @Override
public int hashCode() { public int hashCode() {
int h = 0; int h = 0;
for (LinkedList<Entry> bucket : buckets) { for (LinkedList<Entry<K, V>> bucket : buckets) {
if ( bucket==null ) continue; if ( bucket==null ) continue;
for (Entry e : bucket) { for (Entry<K, V> e : bucket) {
if ( e==null ) break; if ( e==null ) break;
h += hashCode(e.key); h += hashCode(e.key);
} }
@ -159,18 +166,18 @@ public class FlexibleHashMap<K,V> implements EquivalenceMap<K,V> {
} }
protected void expand() { protected void expand() {
LinkedList<Entry>[] old = buckets; LinkedList<Entry<K, V>>[] old = buckets;
currentPrime += 4; currentPrime += 4;
int newCapacity = buckets.length * 2; int newCapacity = buckets.length * 2;
LinkedList<Entry>[] newTable = (LinkedList<Entry>[])new LinkedList[newCapacity]; LinkedList<Entry<K, V>>[] newTable = createEntryListArray(newCapacity);
buckets = newTable; buckets = newTable;
threshold = (int)(newCapacity * LOAD_FACTOR); threshold = (int)(newCapacity * LOAD_FACTOR);
// System.out.println("new size="+newCapacity+", thres="+threshold); // System.out.println("new size="+newCapacity+", thres="+threshold);
// rehash all existing entries // rehash all existing entries
int oldSize = size(); int oldSize = size();
for (LinkedList<Entry> bucket : old) { for (LinkedList<Entry<K, V>> bucket : old) {
if ( bucket==null ) continue; if ( bucket==null ) continue;
for (Entry e : bucket) { for (Entry<K, V> e : bucket) {
if ( e==null ) break; if ( e==null ) break;
put(e.key, e.value); put(e.key, e.value);
} }
@ -190,19 +197,20 @@ public class FlexibleHashMap<K,V> implements EquivalenceMap<K,V> {
@Override @Override
public void clear() { public void clear() {
buckets = (LinkedList<Entry>[])new LinkedList[INITAL_CAPACITY]; buckets = createEntryListArray(INITAL_CAPACITY);
n = 0; n = 0;
} }
@Override
public String toString() { public String toString() {
if ( size()==0 ) return "{}"; if ( size()==0 ) return "{}";
StringBuilder buf = new StringBuilder(); StringBuilder buf = new StringBuilder();
buf.append('{'); buf.append('{');
boolean first = true; boolean first = true;
for (LinkedList<Entry> bucket : buckets) { for (LinkedList<Entry<K, V>> bucket : buckets) {
if ( bucket==null ) continue; if ( bucket==null ) continue;
for (Entry e : bucket) { for (Entry<K, V> e : bucket) {
if ( e==null ) break; if ( e==null ) break;
if ( first ) first=false; if ( first ) first=false;
else buf.append(", "); else buf.append(", ");
@ -215,14 +223,14 @@ public class FlexibleHashMap<K,V> implements EquivalenceMap<K,V> {
public String toTableString() { public String toTableString() {
StringBuilder buf = new StringBuilder(); StringBuilder buf = new StringBuilder();
for (LinkedList<Entry> bucket : buckets) { for (LinkedList<Entry<K, V>> bucket : buckets) {
if ( bucket==null ) { if ( bucket==null ) {
buf.append("null\n"); buf.append("null\n");
continue; continue;
} }
buf.append('['); buf.append('[');
boolean first = true; boolean first = true;
for (Entry e : bucket) { for (Entry<K, V> e : bucket) {
if ( first ) first=false; if ( first ) first=false;
else buf.append(" "); else buf.append(" ");
if ( e==null ) buf.append("_"); if ( e==null ) buf.append("_");