package net.minecraft.util; public class LongHashMap { /** the array of all elements in the hash */ private transient LongHashMapEntry[] hashArray = new LongHashMapEntry[16]; /** the number of elements in the hash array */ private transient int numHashElements; /** * the maximum amount of elements in the hash (probably 3/4 the size due to meh hashing function) */ private int capacity = 12; /** * percent of the hasharray that can be used without hash colliding probably */ private final float percentUseable = 0.75F; /** count of times elements have been added/removed */ private transient volatile int modCount; /** * returns the hashed key given the original key */ private static int getHashedKey(long par0) { return hash((int)(par0 ^ par0 >>> 32)); } /** * the hash function */ private static int hash(int par0) { par0 ^= par0 >>> 20 ^ par0 >>> 12; return par0 ^ par0 >>> 7 ^ par0 >>> 4; } /** * gets the index in the hash given the array length and the hashed key */ private static int getHashIndex(int par0, int par1) { return par0 & par1 - 1; } public int getNumHashElements() { return this.numHashElements; } /** * get the value from the map given the key */ public Object getValueByKey(long par1) { int j = getHashedKey(par1); for (LongHashMapEntry longhashmapentry = this.hashArray[getHashIndex(j, this.hashArray.length)]; longhashmapentry != null; longhashmapentry = longhashmapentry.nextEntry) { if (longhashmapentry.key == par1) { return longhashmapentry.value; } } return null; } public boolean containsItem(long par1) { return this.getEntry(par1) != null; } final LongHashMapEntry getEntry(long par1) { int j = getHashedKey(par1); for (LongHashMapEntry longhashmapentry = this.hashArray[getHashIndex(j, this.hashArray.length)]; longhashmapentry != null; longhashmapentry = longhashmapentry.nextEntry) { if (longhashmapentry.key == par1) { return longhashmapentry; } } return null; } /** * Add a key-value pair. */ public void add(long par1, Object par3Obj) { int j = getHashedKey(par1); int k = getHashIndex(j, this.hashArray.length); for (LongHashMapEntry longhashmapentry = this.hashArray[k]; longhashmapentry != null; longhashmapentry = longhashmapentry.nextEntry) { if (longhashmapentry.key == par1) { longhashmapentry.value = par3Obj; return; } } ++this.modCount; this.createKey(j, par1, par3Obj, k); } /** * resizes the table */ private void resizeTable(int par1) { LongHashMapEntry[] alonghashmapentry = this.hashArray; int j = alonghashmapentry.length; if (j == 1073741824) { this.capacity = Integer.MAX_VALUE; } else { LongHashMapEntry[] alonghashmapentry1 = new LongHashMapEntry[par1]; this.copyHashTableTo(alonghashmapentry1); this.hashArray = alonghashmapentry1; this.capacity = (int)((float)par1 * this.percentUseable); } } /** * copies the hash table to the specified array */ private void copyHashTableTo(LongHashMapEntry[] par1ArrayOfLongHashMapEntry) { LongHashMapEntry[] alonghashmapentry1 = this.hashArray; int i = par1ArrayOfLongHashMapEntry.length; for (int j = 0; j < alonghashmapentry1.length; ++j) { LongHashMapEntry longhashmapentry = alonghashmapentry1[j]; if (longhashmapentry != null) { alonghashmapentry1[j] = null; LongHashMapEntry longhashmapentry1; do { longhashmapentry1 = longhashmapentry.nextEntry; int k = getHashIndex(longhashmapentry.hash, i); longhashmapentry.nextEntry = par1ArrayOfLongHashMapEntry[k]; par1ArrayOfLongHashMapEntry[k] = longhashmapentry; longhashmapentry = longhashmapentry1; } while (longhashmapentry1 != null); } } } /** * calls the removeKey method and returns removed object */ public Object remove(long par1) { LongHashMapEntry longhashmapentry = this.removeKey(par1); return longhashmapentry == null ? null : longhashmapentry.value; } /** * removes the key from the hash linked list */ final LongHashMapEntry removeKey(long par1) { int j = getHashedKey(par1); int k = getHashIndex(j, this.hashArray.length); LongHashMapEntry longhashmapentry = this.hashArray[k]; LongHashMapEntry longhashmapentry1; LongHashMapEntry longhashmapentry2; for (longhashmapentry1 = longhashmapentry; longhashmapentry1 != null; longhashmapentry1 = longhashmapentry2) { longhashmapentry2 = longhashmapentry1.nextEntry; if (longhashmapentry1.key == par1) { ++this.modCount; --this.numHashElements; if (longhashmapentry == longhashmapentry1) { this.hashArray[k] = longhashmapentry2; } else { longhashmapentry.nextEntry = longhashmapentry2; } return longhashmapentry1; } longhashmapentry = longhashmapentry1; } return longhashmapentry1; } /** * creates the key in the hash table */ private void createKey(int par1, long par2, Object par4Obj, int par5) { LongHashMapEntry longhashmapentry = this.hashArray[par5]; this.hashArray[par5] = new LongHashMapEntry(par1, par2, par4Obj, longhashmapentry); if (this.numHashElements++ >= this.capacity) { this.resizeTable(2 * this.hashArray.length); } } /** * public method to get the hashed key(hashCode) */ static int getHashCode(long par0) { return getHashedKey(par0); } }