1 19 package gnu.trove; 20 21 import java.util.Arrays ; 22 23 24 32 abstract public class TObjectHash<T> extends THash implements TObjectHashingStrategy<T> { 33 static final long serialVersionUID = -3461112548087185871L; 34 35 private static final boolean USE_EXPERIMENTAL_PROBE; 36 static { 37 boolean use_new_probe; 38 try { 39 use_new_probe = System.getProperty( "gnu.trove.use_experimatal_probe" ) != null; 40 } 41 catch( Exception ex ) { use_new_probe = false; 43 } 44 USE_EXPERIMENTAL_PROBE = use_new_probe; 45 } 46 47 48 49 protected transient Object [] _set; 50 51 52 protected TObjectHashingStrategy<T> _hashingStrategy; 53 54 protected static final Object REMOVED = new Object (), FREE = new Object (); 55 56 60 public TObjectHash() { 61 super(); 62 this._hashingStrategy = this; 63 } 64 65 71 public TObjectHash(TObjectHashingStrategy<T> strategy) { 72 super(); 73 this._hashingStrategy = strategy; 74 } 75 76 83 public TObjectHash(int initialCapacity) { 84 super(initialCapacity); 85 this._hashingStrategy = this; 86 } 87 88 97 public TObjectHash(int initialCapacity, TObjectHashingStrategy<T> strategy) { 98 super(initialCapacity); 99 this._hashingStrategy = strategy; 100 } 101 102 110 public TObjectHash(int initialCapacity, float loadFactor) { 111 super(initialCapacity, loadFactor); 112 this._hashingStrategy = this; 113 } 114 115 125 public TObjectHash(int initialCapacity, float loadFactor, TObjectHashingStrategy<T> strategy) { 126 super(initialCapacity, loadFactor); 127 this._hashingStrategy = strategy; 128 } 129 130 133 public TObjectHash<T> clone() { 134 TObjectHash<T> h = (TObjectHash<T>)super.clone(); 135 h._set = (Object [])this._set.clone(); 136 return h; 137 } 138 139 protected int capacity() { 140 return _set.length; 141 } 142 143 protected void removeAt(int index) { 144 _set[index] = REMOVED; 145 super.removeAt(index); 146 } 147 148 154 protected int setUp(int initialCapacity) { 155 int capacity; 156 157 capacity = super.setUp(initialCapacity); 158 _set = new Object [capacity]; 159 Arrays.fill(_set,FREE); 160 return capacity; 161 } 162 163 170 public boolean forEach(TObjectProcedure<T> procedure) { 171 Object [] set = _set; 172 for (int i = set.length; i-- > 0;) { 173 if (set[i] != FREE 174 && set[i] != REMOVED 175 && ! procedure.execute((T) set[i])) { 176 return false; 177 } 178 } 179 return true; 180 } 181 182 188 public boolean contains(Object obj) { 189 return index((T) obj) >= 0; 190 } 191 192 198 protected int index(T obj) { 199 int hash, probe, index, length; 200 Object [] set; 201 Object cur; 202 203 set = _set; 204 length = set.length; 205 hash = _hashingStrategy.computeHashCode(obj) & 0x7fffffff; 206 index = hash % length; 207 cur = set[index]; 208 209 if (cur != FREE 210 && (cur == REMOVED || ! _hashingStrategy.equals((T) cur, obj))) { 211 if ( USE_EXPERIMENTAL_PROBE ) probe = 1 + ((hash*9 & 0x7FFFFFFF) % (length - 2)); 213 else probe = 1 + (hash % (length - 2)); 214 215 do { 216 index -= probe; 217 if (index < 0) { 218 index += length; 219 } 220 cur = set[index]; 221 } while (cur != FREE 222 && (cur == REMOVED || ! _hashingStrategy.equals((T) cur, obj))); 223 } 224 225 return cur == FREE ? -1 : index; 226 } 227 228 238 protected int insertionIndex(T obj) { 239 int hash, probe, index, length; 240 Object [] set; 241 Object cur; 242 243 set = _set; 244 length = set.length; 245 hash = _hashingStrategy.computeHashCode(obj) & 0x7fffffff; 246 index = hash % length; 247 cur = set[index]; 248 249 if (cur == FREE) { 250 return index; } else if (_hashingStrategy.equals((T) cur, obj)) { 252 return -index -1; } else { if ( USE_EXPERIMENTAL_PROBE ) probe = 1 + ((hash*9 & 0x7FFFFFFF) % (length - 2)); 256 else probe = 1 + (hash % (length - 2)); 257 258 if (cur != REMOVED) { 270 do { 273 index -= probe; 274 if (index < 0) { 275 index += length; 276 } 277 cur = set[index]; 278 } while (cur != FREE 279 && cur != REMOVED 280 && ! _hashingStrategy.equals((T) cur, obj)); 281 } 282 283 if (cur == REMOVED) { 287 int firstRemoved = index; 288 while (cur != FREE 289 && (cur == REMOVED || ! _hashingStrategy.equals((T) cur, obj))) { 290 index -= probe; 291 if (index < 0) { 292 index += length; 293 } 294 cur = set[index]; 295 } 296 return (cur != FREE) ? -index -1 : firstRemoved; 298 } 299 return (cur != FREE) ? -index -1 : index; 302 } 303 } 304 305 313 public final int computeHashCode(T o) { 314 return o == null ? 0 : o.hashCode(); 315 } 316 317 327 public final boolean equals(T o1, T o2) { 328 return o1 == null ? o2 == null : o1.equals(o2); 329 } 330 331 342 protected final void throwObjectContractViolation(Object o1, Object o2) 343 throws IllegalArgumentException { 344 throw new IllegalArgumentException ("Equal objects must have equal hashcodes. " 345 + "During rehashing, Trove discovered that " 346 + "the following two objects claim to be " 347 + "equal (as in java.lang.Object.equals()) " 348 + "but their hashCodes (or those calculated by " 349 + "your TObjectHashingStrategy) are not equal." 350 + "This violates the general contract of " 351 + "java.lang.Object.hashCode(). See bullet point two " 352 + "in that method's documentation. " 353 + "object #1 =" + o1 354 + "; object #2 =" + o2); 355 } 356 } | Popular Tags |