private CharKeyOpenHashMap( CharHashFunction keyhash, int capacity, int growthPolicy, double growthFactor, int growthChunk, double loadFactor) { if (keyhash == null) Exceptions.nullArgument("hash function"); if (capacity < 0) Exceptions.negativeArgument("capacity", String.valueOf(capacity)); if (growthFactor <= 0.0) Exceptions.negativeOrZeroArgument("growthFactor", String.valueOf(growthFactor)); if (growthChunk <= 0) Exceptions.negativeOrZeroArgument("growthChunk", String.valueOf(growthChunk)); if (loadFactor <= 0.0) Exceptions.negativeOrZeroArgument("loadFactor", String.valueOf(loadFactor)); this.keyhash = keyhash; capacity = Primes.nextPrime(capacity); keys = new char[capacity]; values = (Object[]) new Object[capacity]; this.states = new byte[capacity]; size = 0; expandAt = (int) Math.round(loadFactor * capacity); this.used = 0; this.growthPolicy = growthPolicy; this.growthFactor = growthFactor; this.growthChunk = growthChunk; this.loadFactor = loadFactor; }
private void ensureCapacity(int elements) { if (elements >= expandAt) { int newcapacity; if (growthPolicy == GROWTH_POLICY_RELATIVE) newcapacity = (int) (keys.length * (1.0 + growthFactor)); else newcapacity = keys.length + growthChunk; if (newcapacity * loadFactor < elements) newcapacity = (int) Math.round(((double) elements / loadFactor)); newcapacity = Primes.nextPrime(newcapacity); expandAt = (int) Math.round(loadFactor * newcapacity); char[] newkeys = new char[newcapacity]; Object[] newvalues = (Object[]) new Object[newcapacity]; byte[] newstates = new byte[newcapacity]; used = 0; // re-hash for (int i = 0; i < keys.length; i++) { if (states[i] == OCCUPIED) { used++; char k = keys[i]; Object v = values[i]; // first hash int h = Math.abs(keyhash.hash(k)); int n = h % newcapacity; if (newstates[n] == OCCUPIED) { // second hash int c = 1 + (h % (newcapacity - 2)); for (; ; ) { n -= c; if (n < 0) n += newcapacity; if (newstates[n] == EMPTY) break; } } newstates[n] = OCCUPIED; newvalues[n] = v; newkeys[n] = k; } } keys = newkeys; values = newvalues; states = newstates; } }