From fb2cbc892206268e0f7d2d825956fa2c5757fd2a Mon Sep 17 00:00:00 2001 From: Jonathan Ellis Date: Sat, 5 Dec 2009 14:22:25 +0000 Subject: [PATCH] remove dead Fast* classes git-svn-id: https://svn.apache.org/repos/asf/incubator/cassandra/trunk@887544 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/cassandra/utils/FastHash.java | 399 ------------ .../apache/cassandra/utils/FastHashMap.java | 600 ------------------ .../cassandra/utils/FastLinkedHashMap.java | 24 - .../cassandra/utils/FastObjectHash.java | 322 ---------- 4 files changed, 1345 deletions(-) delete mode 100644 src/java/org/apache/cassandra/utils/FastHash.java delete mode 100644 src/java/org/apache/cassandra/utils/FastHashMap.java delete mode 100644 src/java/org/apache/cassandra/utils/FastLinkedHashMap.java delete mode 100644 src/java/org/apache/cassandra/utils/FastObjectHash.java diff --git a/src/java/org/apache/cassandra/utils/FastHash.java b/src/java/org/apache/cassandra/utils/FastHash.java deleted file mode 100644 index 6056f4c543..0000000000 --- a/src/java/org/apache/cassandra/utils/FastHash.java +++ /dev/null @@ -1,399 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one -* or more contributor license agreements. See the NOTICE file -* distributed with this work for additional information -* regarding copyright ownership. The ASF licenses this file -* to you under the Apache License, Version 2.0 (the -* "License"); you may not use this file except in compliance -* with the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, -* software distributed under the License is distributed on an -* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -* KIND, either express or implied. See the License for the -* specific language governing permissions and limitations -* under the License. -*/ -package org.apache.cassandra.utils; - -import java.util.Random; - - -/** - * Base class for hashtables that use open addressing to resolve collisions. - */ - -abstract public class FastHash implements Cloneable -{ - /** the current number of occupied slots in the hash. */ - protected transient int size_; - - /** the current number of free slots in the hash. */ - protected transient int free_; - - /** the load above which rehashing occurs. */ - protected static final float DEFAULT_LOAD_FACTOR = 0.5f; - - /** - * the default initial capacity for the hash table. This is one less than a - * prime value because one is added to it when searching for a prime - * capacity to account for the free slot required by open addressing. Thus, - * the real default capacity is 11. - */ - protected static final int DEFAULT_INITIAL_CAPACITY = 10; - - /** - * Determines how full the internal table can become before rehashing is - * required. This must be a value in the range: 0.0 < loadFactor < 1.0. The - * default value is 0.5, which is about as large as you can get in open - * addressing without hurting performance. Cf. Knuth, Volume 3., Chapter 6. - */ - protected float loadFactor_; - - /** - * The maximum number of elements allowed without allocating more space. - */ - protected int maxSize_; - - /** - * The number of removes that should be performed before an auto-compaction - * occurs. - */ - protected int autoCompactRemovesRemaining_; - - /** - * The auto-compaction factor for the table. - * - * @see #setAutoCompactionFactor - */ - protected float autoCompactionFactor_; - - /** - * @see - */ - private boolean autoCompactTemporaryDisable_ = false; - - /** - * Creates a new THash instance with the default capacity and - * load factor. - */ - public FastHash() - { - this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR); - } - - /** - * Creates a new THash instance with a prime capacity at or - * near the specified capacity and with the default load factor. - * - * @param initialCapacity - * an int value - */ - public FastHash(int initialCapacity) - { - this(initialCapacity, DEFAULT_LOAD_FACTOR); - } - - /** - * Creates a new THash instance with a prime capacity at or - * near the minimum needed to hold initialCapacity elements with - * load factor loadFactor without triggering a rehash. - * - * @param initialCapacity - * an int value - * @param loadFactor - * a float value - */ - public FastHash(int initialCapacity, float loadFactor) - { - super(); - loadFactor_ = loadFactor; - - // Through testing, the load factor (especially the default load factor) - // has been - // found to be a pretty good starting auto-compaction factor. - autoCompactionFactor_ = loadFactor; - - setUp((int) Math.ceil(initialCapacity / loadFactor)); - } - - public Object clone() - { - try - { - return super.clone(); - } - catch (CloneNotSupportedException cnse) - { - return null; // it's supported - } - } - - /** - * Tells whether this set is currently holding any elements. - * - * @return a boolean value - */ - public boolean isEmpty() - { - return 0 == size_; - } - - /** - * Returns the number of distinct elements in this collection. - * - * @return an int value - */ - public int size() - { - return size_; - } - - /** - * @return the current physical capacity of the hash table. - */ - abstract protected int capacity(); - - /** - * Ensure that this hashtable has sufficient capacity to hold - * desiredCapacity additional elements without - * requiring a rehash. This is a tuning method you can call - * before doing a large insert. - * - * @param desiredCapacity an int value - */ - public void ensureCapacity(int desiredCapacity) - { - if (desiredCapacity > (maxSize_ - size())) - { - rehash(PrimeFinder.nextPrime((int) Math.ceil(desiredCapacity - + size() / loadFactor_) + 1)); - computeMaxSize(capacity()); - } - } - - /** - * Compresses the hashtable to the minimum prime size (as defined by - * PrimeFinder) that will hold all of the elements currently in the table. - * If you have done a lot of remove operations and plan to do a - * lot of queries or insertions or iteration, it is a good idea to invoke - * this method. Doing so will accomplish two things: - * - *
    - *
  1. You'll free memory allocated to the table but no longer needed - * because of the remove()s.
  2. - * - *
  3. You'll get better query/insert/iterator performance because there - * won't be any REMOVED slots to skip over when probing for - * indices in the table.
  4. - *
- */ - public void compact() - { - // need at least one free spot for open addressing - rehash(PrimeFinder.nextPrime((int) Math.ceil(size() / loadFactor_) + 1)); - computeMaxSize(capacity()); - - // If auto-compaction is enabled, re-determine the compaction interval - if (autoCompactionFactor_ != 0) - { - computeNextAutoCompactionAmount(size()); - } - } - - /** - * The auto-compaction factor controls whether and when a table performs a - * {@link #compact} automatically after a certain number of remove - * operations. If the value is non-zero, the number of removes that need to - * occur for auto-compaction is the size of table at the time of the - * previous compaction (or the initial capacity) multiplied by this factor. - *

- * Setting this value to zero will disable auto-compaction. - */ - public void setAutoCompactionFactor(float factor) - { - if (factor < 0) - { - throw new IllegalArgumentException("Factor must be >= 0: " + factor); - } - - autoCompactionFactor_ = factor; - } - - /** - * @see #setAutoCompactionFactor - */ - public float getAutoCompactionFactor() - { - return autoCompactionFactor_; - } - - /** - * This simply calls {@link #compact compact}. It is included for symmetry - * with other collection classes. Note that the name of this method is - * somewhat misleading (which is why we prefer compact) as the - * load factor may require capacity above and beyond the size of this - * collection. - * - * @see #compact - */ - public final void trimToSize() - { - compact(); - } - - /** - * Delete the record at index. Reduces the size of the - * collection by one. - * - * @param index - * an int value - */ - protected void removeAt(int index) - { - size_--; - - // If auto-compaction is enabled, see if we need to compact - if (autoCompactionFactor_ != 0) - { - autoCompactRemovesRemaining_--; - - if (!autoCompactTemporaryDisable_ - && autoCompactRemovesRemaining_ <= 0) - { - // Do the compact - // NOTE: this will cause the next compaction interval to be - // calculated - compact(); - } - } - } - - /** - * Empties the collection. - */ - public void clear() - { - size_ = 0; - free_ = capacity(); - } - - /** - * initializes the hashtable to a prime capacity which is at least - * initialCapacity + 1. - * - * @param initialCapacity - * an int value - * @return the actual capacity chosen - */ - protected int setUp(int initialCapacity) - { - int capacity; - - capacity = PrimeFinder.nextPrime(initialCapacity); - computeMaxSize(capacity); - computeNextAutoCompactionAmount(initialCapacity); - - return capacity; - } - - /** - * Rehashes the set. - * - * @param newCapacity - * an int value - */ - protected abstract void rehash(int newCapacity); - - /** - * Temporarily disables auto-compaction. MUST be followed by calling - * {@link #reenableAutoCompaction}. - */ - protected void tempDisableAutoCompaction() - { - autoCompactTemporaryDisable_ = true; - } - - /** - * Re-enable auto-compaction after it was disabled via - * {@link #tempDisableAutoCompaction()}. - * - * @param check_for_compaction - * True if compaction should be performed if needed before - * returning. If false, no compaction will be performed. - */ - protected void reenableAutoCompaction(boolean check_for_compaction) - { - autoCompactTemporaryDisable_ = false; - - if (check_for_compaction && autoCompactRemovesRemaining_ <= 0 - && autoCompactionFactor_ != 0) - { - - // Do the compact - // NOTE: this will cause the next compaction interval to be - // calculated - compact(); - } - } - - /** - * Computes the values of maxSize. There will always be at least one free - * slot required. - * - * @param capacity - * an int value - */ - private final void computeMaxSize(int capacity) - { - // need at least one free slot for open addressing - maxSize_ = Math.min(capacity - 1, (int) Math.floor(capacity - * loadFactor_)); - free_ = capacity - size_; // reset the free element count - } - - /** - * Computes the number of removes that need to happen before the next - * auto-compaction will occur. - */ - private void computeNextAutoCompactionAmount(int size) - { - if (autoCompactionFactor_ != 0) - { - autoCompactRemovesRemaining_ = Math.round(size - * autoCompactionFactor_); - } - } - - /** - * After an insert, this hook is called to adjust the size/free values of - * the set and to perform rehashing if necessary. - */ - protected final void postInsertHook(boolean usedFreeSlot) - { - if (usedFreeSlot) - { - free_--; - } - - // rehash whenever we exhaust the available space in the table - if (++size_ > maxSize_ || free_ == 0) - { - // choose a new capacity suited to the new state of the table - // if we've grown beyond our maximum size, double capacity; - // if we've exhausted the free spots, rehash to the same capacity, - // which will free up any stale removed slots for reuse. - int newCapacity = size_ > maxSize_ ? PrimeFinder - .nextPrime(capacity() << 1) : capacity(); - rehash(newCapacity); - computeMaxSize(capacity()); - } - } - - protected int calculateGrownCapacity() - { - return capacity() << 1; - } -}// THash diff --git a/src/java/org/apache/cassandra/utils/FastHashMap.java b/src/java/org/apache/cassandra/utils/FastHashMap.java deleted file mode 100644 index 39c8178aa4..0000000000 --- a/src/java/org/apache/cassandra/utils/FastHashMap.java +++ /dev/null @@ -1,600 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one -* or more contributor license agreements. See the NOTICE file -* distributed with this work for additional information -* regarding copyright ownership. The ASF licenses this file -* to you under the Apache License, Version 2.0 (the -* "License"); you may not use this file except in compliance -* with the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, -* software distributed under the License is distributed on an -* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -* KIND, either express or implied. See the License for the -* specific language governing permissions and limitations -* under the License. -*/ -package org.apache.cassandra.utils; - -import java.io.*; -import java.util.*; - -/** - * An implementation of the Map interface which uses an open addressed hash - * table to store its contents - */ -public class FastHashMap extends FastObjectHash implements Map, Serializable -{ - static final long serialVersionUID = 1L; - - /** the values of the map */ - protected transient V[] values_; - - /** - * Creates a new FastHashMap instance with the default capacity - * and load factor. - */ - public FastHashMap() - { - super(); - } - - /** - * Creates a new FastHashMap instance with a prime capacity - * equal to or greater than initialCapacity and with the default - * load factor. - * - * @param initialCapacity - * an int value - */ - public FastHashMap(int initialCapacity) - { - super(initialCapacity); - } - - /** - * Creates a new FastHashMap instance with a prime capacity - * equal to or greater than initialCapacity and with the - * specified load factor. - * - * @param initialCapacity - * an int value - * @param loadFactor - * a float value - */ - public FastHashMap(int initialCapacity, float loadFactor) - { - super(initialCapacity, loadFactor); - } - - /** - * Creates a new FastHashMap instance which contains the - * key/value pairs in map. - * - * @param map - * a Map value - */ - public FastHashMap(Map map) - { - this(map.size()); - putAll(map); - } - - /** - * @return a shallow clone of this collection - */ - public FastHashMap clone() - { - FastHashMap m = (FastHashMap) super.clone(); - m.values_ = this.values_.clone(); - return m; - } - - /** - * initialize the value array of the map. - * - * @param initialCapacity - * an int value - * @return an int value - */ - protected int setUp(int initialCapacity) - { - int capacity; - - capacity = super.setUp(initialCapacity); - values_ = (V[]) new Object[capacity]; - return capacity; - } - - void addEntry(Object key, int index) - { - } - - void removeEntry(Object key, int index) - { - } - - /** - * Inserts a key/value pair into the map. - * - * @param key - * an Object value - * @param value - * an Object value - * @return the previous value associated with key, or null if - * none was found. - */ - public V put(K key, V value) - { - V previous = null; - Object oldKey; - int index = insertionIndex(key); - boolean isNewMapping = true; - if (index < 0) - { - index = -index - 1; - previous = values_[index]; - isNewMapping = false; - } - oldKey = set_[index]; - - if ( oldKey == FREE ) - { - /* This is used as a hook to process new put() operations */ - addEntry(key, index); - } - - set_[index] = key; - values_[index] = value; - if (isNewMapping) - { - postInsertHook(oldKey == FREE); - } - - return previous; - } - - /** - * rehashes the map to the new capacity. - * - * @param newCapacity - * an int value - */ - protected void rehash(int newCapacity) - { - int oldCapacity = set_.length; - Object oldKeys[] = set_; - V oldVals[] = values_; - - set_ = new Object[newCapacity]; - Arrays.fill(set_, FREE); - values_ = (V[]) new Object[newCapacity]; - - for (int i = oldCapacity; i-- > 0;) - { - if (oldKeys[i] != FREE && oldKeys[i] != REMOVED) - { - Object o = oldKeys[i]; - int index = insertionIndex((K) o); - if (index < 0) - { - throwObjectContractViolation(set_[(-index - 1)], o); - } - set_[index] = o; - values_[index] = oldVals[i]; - } - } - } - - /** - * retrieves the value for key - * - * @param key - * an Object value - * @return the value of key or null if no such mapping exists. - */ - public V get(Object key) - { - int index = index((K) key); - return index < 0 ? null : values_[index]; - } - - /** - * Empties the map. - * - */ - public void clear() - { - if (size() == 0) - return; // optimization - - super.clear(); - Object[] keys = set_; - V[] vals = values_; - - for (int i = keys.length; i-- > 0;) - { - keys[i] = FREE; - vals[i] = null; - } - } - - /** - * Deletes a key/value pair from the map. - * - * @param key an Object value - * @return an Object value - */ - public V remove(Object key) - { - V prev = null; - int index = index((K)key); - if (index >= 0) - { - prev = values_[index]; - /* clear key,state; adjust size */ - removeAt(index); - /* This is used as hook to process deleted items */ - removeEntry(key, index); - } - return prev; - } - - /** - * removes the mapping at index from the map. - * - * @param index an int value - */ - protected void removeAt(int index) - { - values_[index] = null; - /* clear key, state; adjust size */ - super.removeAt(index); - } - - /** - * Returns a view on the values of the map. - * - * @return a Collection value - */ - public Collection values() - { - return Arrays.asList(values_); - } - - /** - * returns a Set view on the keys of the map. - * - * @return a Set value - */ - public Set keySet() - { - return new KeyView(); - } - - /** - * Returns a Set view on the entries of the map. - * - * @return a Set value - */ - public Set> entrySet() - { - throw new UnsupportedOperationException( - "This operation is currently not supported."); - } - - /** - * checks for the presence of val in the values of the map. - * - * @param val - * an Object value - * @return a boolean value - */ - public boolean containsValue(Object val) - { - Object[] set = set_; - V[] vals = values_; - - // special case null values so that we don't have to - // perform null checks before every call to equals() - if (null == val) - { - for (int i = vals.length; i-- > 0;) - { - if ((set[i] != FREE && set[i] != REMOVED) && val == vals[i]) - { - return true; - } - } - } - else - { - for (int i = vals.length; i-- > 0;) - { - if ((set[i] != FREE && set[i] != REMOVED) - && (val == vals[i] || val.equals(vals[i]))) - { - return true; - } - } - } // end of else - return false; - } - - /** - * checks for the present of key in the keys of the map. - * - * @param key - * an Object value - * @return a boolean value - */ - public boolean containsKey(Object key) - { - return contains(key); - } - - /** - * copies the key/value mappings in map into this map. - * - * @param map - * a Map value - */ - public void putAll(Map map) - { - ensureCapacity(map.size()); - // could optimize this for cases when map instanceof FastHashMap - for (Iterator> i = map - .entrySet().iterator(); i.hasNext();) - { - Map.Entry e = i.next(); - put(e.getKey(), e.getValue()); - } - } - - private abstract class MapBackedView extends AbstractSet implements Set, Iterable - { - public abstract Iterator iterator(); - public abstract boolean removeElement(E key); - public abstract boolean containsElement(E key); - - public boolean contains(Object key) - { - return containsElement((E) key); - } - - public boolean remove(Object o) - { - return removeElement((E) o); - } - - public boolean containsAll(Collection collection) - { - for (Iterator i = collection.iterator(); i.hasNext();) - { - if (!contains(i.next())) - { - return false; - } - } - return true; - } - - public void clear() - { - FastHashMap.this.clear(); - } - - public boolean add(E obj) - { - throw new UnsupportedOperationException(); - } - - public int size() - { - return FastHashMap.this.size(); - } - - public Object[] toArray() - { - Object[] result = new Object[size()]; - Iterator e = iterator(); - for (int i = 0; e.hasNext(); i++) - result[i] = e.next(); - return result; - } - - public T[] toArray(T[] a) - { - int size = size(); - if (a.length < size) - a = (T[]) java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), size); - - Iterator it = iterator(); - Object[] result = a; - for (int i = 0; i < size; i++) - { - result[i] = it.next(); - } - - if (a.length > size) - { - a[size] = null; - } - - return a; - } - - public boolean isEmpty() - { - return FastHashMap.this.isEmpty(); - } - - public boolean addAll(Collection collection) - { - throw new UnsupportedOperationException(); - } - - public boolean retainAll(Collection collection) - { - boolean changed = false; - Iterator i = iterator(); - while (i.hasNext()) - { - if (!collection.contains(i.next())) - { - i.remove(); - changed = true; - } - } - return changed; - } - } - - protected class FastHashMapIterator implements Iterator - { - private int nextIndex_; - private int expectedSize_; - private FastObjectHash tMap_; - - FastHashMapIterator(FastObjectHash tMap) - { - nextIndex_ = -1; - expectedSize_ = tMap.size(); - tMap_ = tMap; - } - - public boolean hasNext() - { - return (expectedSize_ > 0); - } - - public T next() - { - moveToNextIndex(); - int index = nextIndex_; - /* - * Decrement so that we can track how many - * elements we have already looked at. - */ - --expectedSize_; - return (T)tMap_.set_[index]; - } - - private void moveToNextIndex() - { - int i = nextIndex_ + 1; - for ( ; i < tMap_.set_.length; ++i ) - { - if ( tMap_.set_[i].equals(FREE) || tMap_.set_[i].equals(REMOVED) ) - { - continue; - } - else - { - break; - } - } - nextIndex_ = i; - } - - public void remove() - { - tMap_.removeAt(nextIndex_); - --expectedSize_; - } - } - - /** - * a view onto the keys of the map. - */ - protected class KeyView extends MapBackedView - { - public Iterator iterator() - { - return new FastHashMapIterator(FastHashMap.this); - } - - public boolean removeElement(K key) - { - return null != FastHashMap.this.remove(key); - } - - public boolean containsElement(K key) - { - return FastHashMap.this.contains(key); - } - } - - final class Entry implements Map.Entry - { - private K key; - private V val; - private final int index; - - Entry(final K key, V value, final int index) - { - this.key = key; - this.val = value; - this.index = index; - } - - void setKey(K aKey) - { - this.key = aKey; - } - - void setValue0(V aValue) - { - this.val = aValue; - } - - public K getKey() - { - return key; - } - - public V getValue() - { - return val; - } - - public V setValue(V o) - { - if (values_[index] != val) - { - throw new ConcurrentModificationException(); - } - values_[index] = o; - o = val; // need to return previous value - val = o; // update this entry's value, in case - // setValue is called again - return o; - } - - public boolean equals(Object o) - { - if (o instanceof Map.Entry) - { - Map.Entry e1 = this; - Map.Entry e2 = (Map.Entry) o; - return (e1.getKey() == null ? e2.getKey() == null : e1.getKey().equals(e2.getKey())) - && (e1.getValue() == null ? e2.getValue() == null : e1.getValue().equals(e2.getValue())); - } - return false; - } - - public int hashCode() - { - return (getKey() == null ? 0 : getKey().hashCode()) ^ (getValue() == null ? 0 : getValue().hashCode()); - } - } - - public static void main(String[] args) throws Throwable - { - Map map = new FastHashMap(); - map.put("Avinash", "Avinash"); - map.put("Avinash", "Srinivas"); - } -} diff --git a/src/java/org/apache/cassandra/utils/FastLinkedHashMap.java b/src/java/org/apache/cassandra/utils/FastLinkedHashMap.java deleted file mode 100644 index 1b11081f91..0000000000 --- a/src/java/org/apache/cassandra/utils/FastLinkedHashMap.java +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.cassandra.utils; - -public class FastLinkedHashMap extends FastHashMap -{ - -} diff --git a/src/java/org/apache/cassandra/utils/FastObjectHash.java b/src/java/org/apache/cassandra/utils/FastObjectHash.java deleted file mode 100644 index 7544670daa..0000000000 --- a/src/java/org/apache/cassandra/utils/FastObjectHash.java +++ /dev/null @@ -1,322 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one -* or more contributor license agreements. See the NOTICE file -* distributed with this work for additional information -* regarding copyright ownership. The ASF licenses this file -* to you under the Apache License, Version 2.0 (the -* "License"); you may not use this file except in compliance -* with the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, -* software distributed under the License is distributed on an -* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -* KIND, either express or implied. See the License for the -* specific language governing permissions and limitations -* under the License. -*/ -package org.apache.cassandra.utils; - -import java.util.Arrays; - -/** - * An open addressed hashing implementation for Object types. - */ -abstract public class FastObjectHash extends FastHash -{ - static final long serialVersionUID = -3461112548087185871L; - - /** the set of Objects */ - protected transient Object[] set_; - protected static final Object REMOVED = new Object(), FREE = new Object(); - - /** - * Creates a new TObjectHash instance with the default - * capacity and load factor. - */ - public FastObjectHash() - { - super(); - } - - /** - * Creates a new TObjectHash instance whose capacity is the - * next highest prime above initialCapacity + 1 unless that value - * is already prime. - * - * @param initialCapacity - * an int value - */ - public FastObjectHash(int initialCapacity) - { - super(initialCapacity); - } - - /** - * Creates a new TObjectHash instance with a prime value at - * or near the specified capacity and load factor. - * - * @param initialCapacity - * used to find a prime capacity for the table. - * @param loadFactor - * used to calculate the threshold over which rehashing takes - * place. - */ - public FastObjectHash(int initialCapacity, float loadFactor) - { - super(initialCapacity, loadFactor); - } - - /** - * @return a shallow clone of this collection - */ - public FastObjectHash clone() - { - FastObjectHash h = (FastObjectHash) super.clone(); - h.set_ = (Object[]) this.set_.clone(); - return h; - } - - /** - * This method is invoked every time a key is - * added into the Map. - * @param key key that is inserted - * @param index index position of the key being - * inserted - */ - abstract void addEntry(Object key, int index); - - /** - * This method is invoked every time a key is - * deleted from the Map. - * @param key key being deleted - * @param index index position of the key being - * deleted - */ - abstract void removeEntry(Object key, int index); - - protected int capacity() - { - return set_.length; - } - - protected void removeAt(int index) - { - set_[index] = REMOVED; - super.removeAt(index); - } - - /** - * initializes the Object set of this hash table. - * - * @param initialCapacity - * an int value - * @return an int value - */ - protected int setUp(int initialCapacity) - { - int capacity; - - capacity = super.setUp(initialCapacity); - set_ = new Object[capacity]; - Arrays.fill(set_, FREE); - return capacity; - } - - /** - * Searches the set for obj - * - * @param obj - * an Object value - * @return a boolean value - */ - public boolean contains(Object obj) - { - return index((T) obj) >= 0; - } - - /** - * Locates the index of obj. - * - * @param obj - * an Object value - * @return the index of obj or -1 if it isn't in the set. - */ - protected int index(Object obj) - { - final Object[] set = set_; - final int length = set.length; - final int hash = obj.hashCode() & 0x7fffffff; - int index = hash % length; - Object cur = set[index]; - - if (cur == FREE) - return -1; - - // NOTE: here it has to be REMOVED or FULL (some user-given value) - if (cur == REMOVED || cur.equals(obj)) - { - // see Knuth, p. 529 - final int probe = 1 + (hash % (length - 2)); - - while (cur != FREE&& (cur == REMOVED || !cur.equals(obj))) - { - index -= probe; - if (index < 0) - { - index += length; - } - cur = set[index]; - } - } - - return cur == FREE ? -1 : index; - } - - /** - * Locates the index at which obj can be inserted. if there is - * already a value equal()ing obj in the set, returns that - * value's index as -index - 1. - * - * @param obj - * an Object value - * @return the index of a FREE slot at which obj can be inserted or, if obj - * is already stored in the hash, the negative value of that index, - * minus 1: -index -1. - */ - protected int insertionIndex(T obj) - { - final Object[] set = set_; - final int length = set.length; - final int hash = obj.hashCode() & 0x7fffffff; - int index = hash % length; - Object cur = set[index]; - - if (cur == FREE) - { - return index; // empty, all done - } - else if (cur != REMOVED && cur.equals(obj)) - { - return -index - 1; // already stored - } - else - { // already FULL or REMOVED, must probe - // compute the double token - final int probe = 1 + (hash % (length - 2)); - - // if the slot we landed on is FULL (but not removed), probe - // until we find an empty slot, a REMOVED slot, or an element - // equal to the one we are trying to insert. - // finding an empty slot means that the value is not present - // and that we should use that slot as the insertion point; - // finding a REMOVED slot means that we need to keep searching, - // however we want to remember the offset of that REMOVED slot - // so we can reuse it in case a "new" insertion (i.e. not an update) - // is possible. - // finding a matching value means that we've found that our desired - // key is already in the table - if (cur != REMOVED) - { - // starting at the natural offset, probe until we find an - // offset that isn't full. - do - { - index -= probe; - if (index < 0) - { - index += length; - } - cur = set[index]; - } - while (cur != FREE && cur != REMOVED - && !cur.equals(obj)); - } - - // if the index we found was removed: continue probing until we - // locate a free location or an element which equal()s the - // one we have. - if (cur == REMOVED) - { - int firstRemoved = index; - while (cur != FREE - && (cur == REMOVED || !cur.equals(obj))) - { - index -= probe; - if (index < 0) - { - index += length; - } - cur = set[index]; - } - // NOTE: cur cannot == REMOVED in this block - return (cur != FREE) ? -index - 1 : firstRemoved; - } - // if it's full, the key is already stored - // NOTE: cur cannot equal REMOVE here (would have returned already - // (see above) - return (cur != FREE) ? -index - 1 : index; - } - } - - /** - * This is the default implementation of TObjectHashingStrategy: it - * delegates hashing to the Object's hashCode method. - * - * @param o - * for which the hashcode is to be computed - * @return the hashCode - * @see Object#hashCode() - */ - public final int computeHashCode(T o) - { - return o == null ? 0 : o.hashCode(); - } - - /** - * This is the default implementation of TObjectHashingStrategy: it - * delegates equality comparisons to the first parameter's equals() method. - * - * @param o1 - * an Object value - * @param o2 - * an Object value - * @return true if the objects are equal - * @see Object#equals(Object) - */ - public final boolean equals(T o1, T o2) - { - return o1 == null ? o2 == null : o1.equals(o2); - } - - /** - * Convenience methods for subclasses to use in throwing exceptions about - * badly behaved user objects employed as keys. We have to throw an - * IllegalArgumentException with a rather verbose message telling the user - * that they need to fix their object implementation to conform to the - * general contract for java.lang.Object. - * - * @param o1 - * the first of the equal elements with unequal hash codes. - * @param o2 - * the second of the equal elements with unequal hash codes. - * @exception IllegalArgumentException - * the whole point of this method. - */ - protected final void throwObjectContractViolation(Object o1, Object o2) - throws IllegalArgumentException - { - throw new IllegalArgumentException( - "Equal objects must have equal hashcodes. " - + "During rehashing, Trove discovered that " - + "the following two objects claim to be " - + "equal (as in java.lang.Object.equals()) " - + "but their hashCodes (or those calculated by " - + "your TObjectHashingStrategy) are not equal." - + "This violates the general contract of " - + "java.lang.Object.hashCode(). See bullet point two " - + "in that method's documentation. " + "object #1 =" - + o1 + "; object #2 =" + o2); - } -} // TObjectHash