001 package net.minecraft.util; 002 003 public class LongHashMap 004 { 005 /** the array of all elements in the hash */ 006 private transient LongHashMapEntry[] hashArray = new LongHashMapEntry[16]; 007 008 /** the number of elements in the hash array */ 009 private transient int numHashElements; 010 011 /** 012 * the maximum amount of elements in the hash (probably 3/4 the size due to meh hashing function) 013 */ 014 private int capacity = 12; 015 016 /** 017 * percent of the hasharray that can be used without hash colliding probably 018 */ 019 private final float percentUseable = 0.75F; 020 021 /** count of times elements have been added/removed */ 022 private transient volatile int modCount; 023 024 /** 025 * returns the hashed key given the original key 026 */ 027 private static int getHashedKey(long par0) 028 { 029 return hash((int)(par0 ^ par0 >>> 32)); 030 } 031 032 /** 033 * the hash function 034 */ 035 private static int hash(int par0) 036 { 037 par0 ^= par0 >>> 20 ^ par0 >>> 12; 038 return par0 ^ par0 >>> 7 ^ par0 >>> 4; 039 } 040 041 /** 042 * gets the index in the hash given the array length and the hashed key 043 */ 044 private static int getHashIndex(int par0, int par1) 045 { 046 return par0 & par1 - 1; 047 } 048 049 public int getNumHashElements() 050 { 051 return this.numHashElements; 052 } 053 054 /** 055 * get the value from the map given the key 056 */ 057 public Object getValueByKey(long par1) 058 { 059 int var3 = getHashedKey(par1); 060 061 for (LongHashMapEntry var4 = this.hashArray[getHashIndex(var3, this.hashArray.length)]; var4 != null; var4 = var4.nextEntry) 062 { 063 if (var4.key == par1) 064 { 065 return var4.value; 066 } 067 } 068 069 return null; 070 } 071 072 public boolean containsItem(long par1) 073 { 074 return this.getEntry(par1) != null; 075 } 076 077 final LongHashMapEntry getEntry(long par1) 078 { 079 int var3 = getHashedKey(par1); 080 081 for (LongHashMapEntry var4 = this.hashArray[getHashIndex(var3, this.hashArray.length)]; var4 != null; var4 = var4.nextEntry) 082 { 083 if (var4.key == par1) 084 { 085 return var4; 086 } 087 } 088 089 return null; 090 } 091 092 /** 093 * Add a key-value pair. 094 */ 095 public void add(long par1, Object par3Obj) 096 { 097 int var4 = getHashedKey(par1); 098 int var5 = getHashIndex(var4, this.hashArray.length); 099 100 for (LongHashMapEntry var6 = this.hashArray[var5]; var6 != null; var6 = var6.nextEntry) 101 { 102 if (var6.key == par1) 103 { 104 var6.value = par3Obj; 105 return; 106 } 107 } 108 109 ++this.modCount; 110 this.createKey(var4, par1, par3Obj, var5); 111 } 112 113 /** 114 * resizes the table 115 */ 116 private void resizeTable(int par1) 117 { 118 LongHashMapEntry[] var2 = this.hashArray; 119 int var3 = var2.length; 120 121 if (var3 == 1073741824) 122 { 123 this.capacity = Integer.MAX_VALUE; 124 } 125 else 126 { 127 LongHashMapEntry[] var4 = new LongHashMapEntry[par1]; 128 this.copyHashTableTo(var4); 129 this.hashArray = var4; 130 this.capacity = (int)((float)par1 * this.percentUseable); 131 } 132 } 133 134 /** 135 * copies the hash table to the specified array 136 */ 137 private void copyHashTableTo(LongHashMapEntry[] par1ArrayOfLongHashMapEntry) 138 { 139 LongHashMapEntry[] var2 = this.hashArray; 140 int var3 = par1ArrayOfLongHashMapEntry.length; 141 142 for (int var4 = 0; var4 < var2.length; ++var4) 143 { 144 LongHashMapEntry var5 = var2[var4]; 145 146 if (var5 != null) 147 { 148 var2[var4] = null; 149 LongHashMapEntry var6; 150 151 do 152 { 153 var6 = var5.nextEntry; 154 int var7 = getHashIndex(var5.hash, var3); 155 var5.nextEntry = par1ArrayOfLongHashMapEntry[var7]; 156 par1ArrayOfLongHashMapEntry[var7] = var5; 157 var5 = var6; 158 } 159 while (var6 != null); 160 } 161 } 162 } 163 164 /** 165 * calls the removeKey method and returns removed object 166 */ 167 public Object remove(long par1) 168 { 169 LongHashMapEntry var3 = this.removeKey(par1); 170 return var3 == null ? null : var3.value; 171 } 172 173 /** 174 * removes the key from the hash linked list 175 */ 176 final LongHashMapEntry removeKey(long par1) 177 { 178 int var3 = getHashedKey(par1); 179 int var4 = getHashIndex(var3, this.hashArray.length); 180 LongHashMapEntry var5 = this.hashArray[var4]; 181 LongHashMapEntry var6; 182 LongHashMapEntry var7; 183 184 for (var6 = var5; var6 != null; var6 = var7) 185 { 186 var7 = var6.nextEntry; 187 188 if (var6.key == par1) 189 { 190 ++this.modCount; 191 --this.numHashElements; 192 193 if (var5 == var6) 194 { 195 this.hashArray[var4] = var7; 196 } 197 else 198 { 199 var5.nextEntry = var7; 200 } 201 202 return var6; 203 } 204 205 var5 = var6; 206 } 207 208 return var6; 209 } 210 211 /** 212 * creates the key in the hash table 213 */ 214 private void createKey(int par1, long par2, Object par4Obj, int par5) 215 { 216 LongHashMapEntry var6 = this.hashArray[par5]; 217 this.hashArray[par5] = new LongHashMapEntry(par1, par2, par4Obj, var6); 218 219 if (this.numHashElements++ >= this.capacity) 220 { 221 this.resizeTable(2 * this.hashArray.length); 222 } 223 } 224 225 /** 226 * public method to get the hashed key(hashCode) 227 */ 228 static int getHashCode(long par0) 229 { 230 return getHashedKey(par0); 231 } 232 }