Merge changes I0d797533,I128522af,I6dd076eb,Ief6f81b9,I83d01e5c

* changes:
  ObjectIdSubclassMap: Avoid field loads in inner loops
  ObjectIdSubclassMap: Manually inline index()
  ObjectIdSubclassMap: Change initial size to 2048
  ObjectIdSubclassMap: Grow before insertions
  ObjectIdSubclassMap: Use & rather than % for hashing
This commit is contained in:
Shawn O. Pearce 2011-03-10 13:02:59 -05:00 committed by Code Review
commit 42f0b11153
1 changed files with 34 additions and 22 deletions

View File

@ -63,19 +63,25 @@
* type of subclass of ObjectId that will be stored in the map. * type of subclass of ObjectId that will be stored in the map.
*/ */
public class ObjectIdSubclassMap<V extends ObjectId> implements Iterable<V> { public class ObjectIdSubclassMap<V extends ObjectId> implements Iterable<V> {
private static final int INITIAL_TABLE_SIZE = 2048;
private int size; private int size;
private int grow;
private int mask;
private V[] table; private V[] table;
/** Create an empty map. */ /** Create an empty map. */
public ObjectIdSubclassMap() { public ObjectIdSubclassMap() {
table = createArray(32); initTable(INITIAL_TABLE_SIZE);
} }
/** Remove all entries from this map. */ /** Remove all entries from this map. */
public void clear() { public void clear() {
size = 0; size = 0;
table = createArray(32); initTable(INITIAL_TABLE_SIZE);
} }
/** /**
@ -86,13 +92,15 @@ public void clear() {
* @return the instance mapped to toFind, or null if no mapping exists. * @return the instance mapped to toFind, or null if no mapping exists.
*/ */
public V get(final AnyObjectId toFind) { public V get(final AnyObjectId toFind) {
int i = index(toFind); int i = toFind.w1 & mask;
final V[] tbl = table;
final int end = tbl.length;
V obj; V obj;
while ((obj = table[i]) != null) { while ((obj = tbl[i]) != null) {
if (AnyObjectId.equals(obj, toFind)) if (AnyObjectId.equals(obj, toFind))
return obj; return obj;
if (++i == table.length) if (++i == end)
i = 0; i = 0;
} }
return null; return null;
@ -123,10 +131,9 @@ public boolean contains(final AnyObjectId toFind) {
* type of instance to store. * type of instance to store.
*/ */
public <Q extends V> void add(final Q newValue) { public <Q extends V> void add(final Q newValue) {
if (table.length - 1 <= size * 2) if (++size == grow)
grow(); grow();
insert(newValue); insert(newValue);
size++;
} }
/** /**
@ -150,23 +157,24 @@ public <Q extends V> void add(final Q newValue) {
* type of instance to store. * type of instance to store.
*/ */
public <Q extends V> V addIfAbsent(final Q newValue) { public <Q extends V> V addIfAbsent(final Q newValue) {
int i = index(newValue); int i = newValue.w1 & mask;
final V[] tbl = table;
final int end = tbl.length;
V obj; V obj;
while ((obj = table[i]) != null) { while ((obj = tbl[i]) != null) {
if (AnyObjectId.equals(obj, newValue)) if (AnyObjectId.equals(obj, newValue))
return obj; return obj;
if (++i == table.length) if (++i == end)
i = 0; i = 0;
} }
if (table.length - 1 <= size * 2) { if (++size == grow) {
grow(); grow();
insert(newValue); insert(newValue);
} else { } else {
table[i] = newValue; tbl[i] = newValue;
} }
size++;
return newValue; return newValue;
} }
@ -209,24 +217,22 @@ public void remove() {
}; };
} }
private final int index(final AnyObjectId id) {
return (id.w1 >>> 1) % table.length;
}
private void insert(final V newValue) { private void insert(final V newValue) {
int j = index(newValue); int j = newValue.w1 & mask;
while (table[j] != null) { final V[] tbl = table;
if (++j >= table.length) final int end = tbl.length;
while (tbl[j] != null) {
if (++j == end)
j = 0; j = 0;
} }
table[j] = newValue; tbl[j] = newValue;
} }
private void grow() { private void grow() {
final V[] oldTable = table; final V[] oldTable = table;
final int oldSize = table.length; final int oldSize = table.length;
table = createArray(2 * oldSize); initTable(oldSize << 1);
for (int i = 0; i < oldSize; i++) { for (int i = 0; i < oldSize; i++) {
final V obj = oldTable[i]; final V obj = oldTable[i];
if (obj != null) if (obj != null)
@ -234,6 +240,12 @@ private void grow() {
} }
} }
private void initTable(int sz) {
grow = sz >> 1;
mask = sz - 1;
table = createArray(sz);
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private final V[] createArray(final int sz) { private final V[] createArray(final int sz) {
return (V[]) new ObjectId[sz]; return (V[]) new ObjectId[sz];