forked from jasder/antlr
Merge branch 'flexiblehashmap' of github.com:sharwell/antlr4
This commit is contained in:
commit
ce38d61f3a
|
@ -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("_");
|
||||||
|
|
Loading…
Reference in New Issue