1 22 23 package com.sosnoski.util; 24 25 import java.lang.reflect.Array ; 26 27 60 61 public abstract class ObjectHashBase 62 { 63 64 public static final String STANDARD_HASH = "base"; 65 66 67 public static final String IDENTITY_COMP = "comp"; 68 69 70 public static final String IDENTITY_HASH = "ident"; 71 72 73 protected static final double DEFAULT_FILL = 0.3d; 74 75 76 protected static final int MINIMUM_SIZE = 31; 77 78 79 protected final boolean m_identHash; 80 81 82 protected final boolean m_identCompare; 83 84 85 protected final double m_fillFraction; 86 87 88 protected int m_entryCount; 89 90 91 protected int m_entryLimit; 92 93 94 protected int m_arraySize; 95 96 97 protected int m_hitOffset; 98 99 108 109 public ObjectHashBase(int count, double fill, Class type, Object tech) { 110 111 if (fill <= 0.0d || fill >= 1.0d) { 113 throw new IllegalArgumentException ("fill value out of range"); 114 } 115 m_fillFraction = fill; 116 117 if (tech == STANDARD_HASH) { 119 m_identHash = false; 120 m_identCompare = false; 121 } else if (tech == IDENTITY_COMP) { 122 m_identHash = false; 123 m_identCompare = true; 124 } else if (tech == IDENTITY_HASH) { 125 m_identHash = true; 126 m_identCompare = true; 127 } else { 128 throw new IllegalArgumentException 129 ("Unknown hash technique specifier"); 130 } 131 132 m_arraySize = Math.max((int) (count / m_fillFraction), MINIMUM_SIZE); 134 m_arraySize += (m_arraySize + 1) % 2; 135 136 m_entryLimit = (int) (m_arraySize * m_fillFraction); 138 m_hitOffset = m_arraySize / 2; 139 setKeyArray(Array.newInstance(type, m_arraySize)); 140 } 141 142 147 148 public ObjectHashBase(ObjectHashBase base) { 149 150 m_fillFraction = base.m_fillFraction; 152 m_entryCount = base.m_entryCount; 153 m_entryLimit = base.m_entryLimit; 154 m_arraySize = base.m_arraySize; 155 m_hitOffset = base.m_hitOffset; 156 m_identHash = base.m_identHash; 157 m_identCompare = base.m_identCompare; 158 159 Class type = base.getKeyArray().getClass().getComponentType(); 161 Object copy = Array.newInstance(type, m_arraySize); 162 System.arraycopy(base.getKeyArray(), 0, copy, 0, m_arraySize); 163 setKeyArray(copy); 164 } 165 166 171 172 public final int size() { 173 return m_entryCount; 174 } 175 176 183 184 protected abstract Object [] getKeyArray(); 185 186 193 194 protected abstract void setKeyArray(Object array); 195 196 204 205 protected abstract void reallocate(int size); 206 207 213 214 protected void growCapacity(int min) { 215 216 int size = m_arraySize; 218 int limit = m_entryLimit; 219 while (limit < min) { 220 size = size * 2 + 1; 221 limit = (int) (size * m_fillFraction); 222 } 223 224 m_arraySize = size; 226 m_entryLimit = limit; 227 m_hitOffset = size / 2; 228 229 reallocate(size); 231 } 232 233 239 240 public final void ensureCapacity(int min) { 241 if (min > m_entryLimit) { 242 growCapacity(min); 243 } 244 } 245 246 251 252 public void clear() { 253 Object [] items = getKeyArray(); 254 for (int i = 0; i < m_arraySize; i++) { 255 items[i] = null; 256 } 257 m_entryCount = 0; 258 } 259 260 267 268 protected final int stepSlot(int slot) { 269 return (slot + m_hitOffset) % m_arraySize; 270 } 271 272 281 282 protected final int freeSlot(int slot) { 283 Object [] items = getKeyArray(); 284 while (items[slot] != null) { 285 slot = stepSlot(slot); 286 } 287 return slot; 288 } 289 290 303 304 protected final int standardSlot(Object key) { 305 return ((m_identHash ? System.identityHashCode(key) : key.hashCode()) & 306 Integer.MAX_VALUE) % m_arraySize; 307 } 308 309 324 325 protected int standardFind(Object key) { 326 327 int slot = standardSlot(key); 329 330 Object keys[] = getKeyArray(); 332 if (m_identCompare) { 333 while (keys[slot] != null) { 334 335 if (keys[slot] == key) { 337 return slot; 338 } else { 339 slot = stepSlot(slot); 340 } 341 342 } 343 } else { 344 while (keys[slot] != null) { 345 346 if (keys[slot].equals(key)) { 348 return slot; 349 } else { 350 slot = stepSlot(slot); 351 } 352 353 } 354 } 355 return -slot-1; 356 } 357 } 358 | Popular Tags |