1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2001, Eric D. Friedman All Rights Reserved.
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 ///////////////////////////////////////////////////////////////////////////////
21 import java.io.IOException;
22 import java.io.ObjectInput;
23 import java.io.ObjectOutput;
24 import java.io.Externalizable;
25 import java.util.Arrays;
28 //////////////////////////////////////////////////
29 // THIS IS A GENERATED CLASS. DO NOT HAND EDIT! //
30 //////////////////////////////////////////////////
34 * An open addressed Map implementation for int keys and Object values.
36 * Created: Sun Nov 4 08:52:45 2001
38 * @author Eric D. Friedman
40 @SuppressWarnings({"unchecked", "rawtypes", "unused"})
41 public class TIntObjectHashMap<V> extends TIntHash implements Externalizable {
42 static final long serialVersionUID = 1L;
44 private final TIntObjectProcedure<V> PUT_ALL_PROC = new TIntObjectProcedure<V>() {
45 public boolean execute(int key, V value) {
52 /** the values of the map */
53 protected transient V[] _values;
56 * Creates a new <code>TIntObjectHashMap</code> instance with the default
57 * capacity and load factor.
59 public TIntObjectHashMap() {
64 * Creates a new <code>TIntObjectHashMap</code> instance with a prime
65 * capacity equal to or greater than <tt>initialCapacity</tt> and
66 * with the default load factor.
68 * @param initialCapacity an <code>int</code> value
70 public TIntObjectHashMap(int initialCapacity) {
71 super(initialCapacity);
75 * Creates a new <code>TIntObjectHashMap</code> instance with a prime
76 * capacity equal to or greater than <tt>initialCapacity</tt> and
77 * with the specified load factor.
79 * @param initialCapacity an <code>int</code> value
80 * @param loadFactor a <code>float</code> value
82 public TIntObjectHashMap(int initialCapacity, float loadFactor) {
83 super(initialCapacity, loadFactor);
87 * Creates a new <code>TIntObjectHashMap</code> instance with the default
88 * capacity and load factor.
89 * @param strategy used to compute hash codes and to compare keys.
91 public TIntObjectHashMap(TIntHashingStrategy strategy) {
96 * Creates a new <code>TIntObjectHashMap</code> instance whose capacity
97 * is the next highest prime above <tt>initialCapacity + 1</tt>
98 * unless that value is already prime.
100 * @param initialCapacity an <code>int</code> value
101 * @param strategy used to compute hash codes and to compare keys.
103 public TIntObjectHashMap(int initialCapacity, TIntHashingStrategy strategy) {
104 super(initialCapacity, strategy);
108 * Creates a new <code>TIntObjectHashMap</code> instance with a prime
109 * value at or near the specified capacity and load factor.
111 * @param initialCapacity used to find a prime capacity for the table.
112 * @param loadFactor used to calculate the threshold over which
113 * rehashing takes place.
114 * @param strategy used to compute hash codes and to compare keys.
116 public TIntObjectHashMap(int initialCapacity, float loadFactor, TIntHashingStrategy strategy) {
117 super(initialCapacity, loadFactor, strategy);
121 * @return a deep clone of this collection
123 public TIntObjectHashMap<V> clone() {
124 TIntObjectHashMap<V> m = (TIntObjectHashMap<V>)super.clone();
125 m._values = (V[]) this._values.clone();
130 * @return a TIntObjectIterator with access to this map's keys and values
132 public TIntObjectIterator<V> iterator() {
133 return new TIntObjectIterator<V>(this);
137 * initializes the hashtable to a prime capacity which is at least
138 * <tt>initialCapacity + 1</tt>.
140 * @param initialCapacity an <code>int</code> value
141 * @return the actual capacity chosen
143 protected int setUp(int initialCapacity) {
146 capacity = super.setUp(initialCapacity);
147 _values = (V[]) new Object[capacity];
152 * Inserts a key/value pair into the map.
154 * @param key an <code>int</code> value
155 * @param value an <code>Object</code> value
156 * @return the previous value associated with <tt>key</tt>,
157 * or {@code null} if none was found.
159 public V put(int key, V value) {
160 int index = insertionIndex(key);
161 return doPut(key, value, index);
165 * Inserts a key/value pair into the map if the specified key is not already
166 * associated with a value.
168 * @param key an <code>int</code> value
169 * @param value an <code>Object</code> value
170 * @return the previous value associated with <tt>key</tt>,
171 * or {@code null} if none was found.
173 public V putIfAbsent(int key, V value) {
174 int index = insertionIndex(key);
176 return _values[-index - 1];
177 return doPut(key, value, index);
180 private V doPut(int key, V value, int index) {
183 boolean isNewMapping = true;
186 previous = _values[index];
187 isNewMapping = false;
189 previousState = _states[index];
191 _states[index] = FULL;
192 _values[index] = value;
194 postInsertHook(previousState == FREE);
202 * Put all the entries from the given map into this map.
204 * @param map The map from which entries will be obtained to put into this map.
206 public void putAll(TIntObjectHashMap<V> map){
207 map.forEachEntry(PUT_ALL_PROC);
212 * rehashes the map to the new capacity.
214 * @param newCapacity an <code>int</code> value
216 protected void rehash(int newCapacity) {
217 int oldCapacity = _set.length;
218 int oldKeys[] = _set;
219 V oldVals[] = _values;
220 byte oldStates[] = _states;
222 _set = new int[newCapacity];
223 _values = (V[]) new Object[newCapacity];
224 _states = new byte[newCapacity];
226 for (int i = oldCapacity; i-- > 0;) {
227 if(oldStates[i] == FULL) {
229 int index = insertionIndex(o);
231 _values[index] = oldVals[i];
232 _states[index] = FULL;
238 * retrieves the value for <tt>key</tt>
240 * @param key an <code>int</code> value
241 * @return the value of <tt>key</tt> or (int)0 if no such mapping exists.
243 public V get(int key) {
244 int index = index(key);
245 return index < 0 ? null : _values[index];
252 public void clear() {
255 Object[] vals = _values;
256 byte[] states = _states;
258 Arrays.fill(_set, 0, _set.length, (int) 0);
259 Arrays.fill(_values, 0, _values.length, null);
260 Arrays.fill(_states, 0, _states.length, FREE);
264 * Deletes a key/value pair from the map.
266 * @param key an <code>int</code> value
267 * @return an <code>Object</code> value or (int)0 if no such mapping exists.
269 public V remove(int key) {
271 int index = index(key);
273 prev = _values[index];
274 removeAt(index); // clear key,state; adjust size
280 * Compares this map with another map for equality of their stored
283 * @param other an <code>Object</code> value
284 * @return a <code>boolean</code> value
286 public boolean equals(Object other) {
287 if (! (other instanceof TIntObjectHashMap)) {
290 TIntObjectHashMap that = (TIntObjectHashMap)other;
291 if (that.size() != this.size()) {
294 return forEachEntry(new EqProcedure(that));
297 public int hashCode() {
298 HashProcedure p = new HashProcedure();
300 return p.getHashCode();
303 private final class HashProcedure implements TIntObjectProcedure {
306 public int getHashCode() {
310 public final boolean execute(int key, Object value) {
311 h += (_hashingStrategy.computeHashCode(key) ^ HashFunctions.hash(value));
316 private static final class EqProcedure implements TIntObjectProcedure {
317 private final TIntObjectHashMap _otherMap;
319 EqProcedure(TIntObjectHashMap otherMap) {
320 _otherMap = otherMap;
323 public final boolean execute(int key, Object value) {
324 int index = _otherMap.index(key);
325 if (index >= 0 && eq(value, _otherMap.get(key))) {
332 * Compare two objects for equality.
334 private final boolean eq(Object o1, Object o2) {
335 return o1 == o2 || ((o1 != null) && o1.equals(o2));
341 * removes the mapping at <tt>index</tt> from the map.
343 * @param index an <code>int</code> value
345 protected void removeAt(int index) {
346 _values[index] = null;
347 super.removeAt(index); // clear key, state; adjust size
351 * Returns the values of the map.
353 * @return a <code>Collection</code> value
355 * @see #getValues(Object[])
357 public Object[] getValues() {
358 Object[] vals = new Object[size()];
360 byte[] states = _states;
362 for (int i = v.length, j = 0; i-- > 0;) {
363 if (states[i] == FULL) {
371 * Return the values of the map; the runtime type of the returned array is that of
372 * the specified array.
374 * @param a the array into which the elements of this collection are to be
375 * stored, if it is big enough; otherwise, a new array of the same
376 * runtime type is allocated for this purpose.
377 * @return an array containing the elements of this collection
379 * @throws ArrayStoreException the runtime type of the specified array is
380 * not a supertype of the runtime type of every element in this
382 * @throws NullPointerException if the specified array is <tt>null</tt>.
386 public <T> T[] getValues( T[] a ) {
387 if (a.length < _size) {
388 a = (T[])java.lang.reflect.Array.newInstance(a.getClass().getComponentType(),
393 byte[] states = _states;
395 for (int i = v.length, j = 0; i-- > 0;) {
396 if (states[i] == FULL) {
404 * returns the keys of the map.
406 * @return a <code>Set</code> value
408 public int[] keys() {
409 int[] keys = new int[size()];
411 byte[] states = _states;
413 for (int i = k.length, j = 0; i-- > 0;) {
414 if (states[i] == FULL) {
422 * returns the keys of the map.
424 * @param a the array into which the elements of the list are to
425 * be stored, if it is big enough; otherwise, a new array of the
426 * same type is allocated for this purpose.
427 * @return a <code>Set</code> value
429 public int[] keys(int[] a) {
431 if (a.length < size) {
432 a = (int[]) java.lang.reflect.Array.newInstance(
433 a.getClass().getComponentType(), size);
436 int[] k = (int[]) _set;
437 byte[] states = _states;
439 for (int i = k.length, j = 0; i-- > 0;) {
440 if (states[i] == FULL) {
448 * checks for the presence of <tt>val</tt> in the values of the map.
450 * @param val an <code>Object</code> value
451 * @return a <code>boolean</code> value
453 public boolean containsValue(V val) {
454 byte[] states = _states;
457 // special case null values so that we don't have to
458 // perform null checks before every call to equals()
460 for (int i = vals.length; i-- > 0;) {
461 if (states[i] == FULL &&
467 for (int i = vals.length; i-- > 0;) {
468 if (states[i] == FULL &&
469 (val == vals[i] || val.equals(vals[i]))) {
479 * checks for the present of <tt>key</tt> in the keys of the map.
481 * @param key an <code>int</code> value
482 * @return a <code>boolean</code> value
484 public boolean containsKey(int key) {
485 return contains(key);
489 * Executes <tt>procedure</tt> for each key in the map.
491 * @param procedure a <code>TIntProcedure</code> value
492 * @return false if the loop over the keys terminated because
493 * the procedure returned false for some key.
495 public boolean forEachKey(TIntProcedure procedure) {
496 return forEach(procedure);
500 * Executes <tt>procedure</tt> for each value in the map.
502 * @param procedure a <code>TObjectProcedure</code> value
503 * @return false if the loop over the values terminated because
504 * the procedure returned false for some value.
506 public boolean forEachValue(TObjectProcedure<V> procedure) {
507 byte[] states = _states;
508 V[] values = _values;
509 for (int i = values.length; i-- > 0;) {
510 if (states[i] == FULL && ! procedure.execute(values[i])) {
518 * Executes <tt>procedure</tt> for each key/value entry in the
521 * @param procedure a <code>TOIntObjectProcedure</code> value
522 * @return false if the loop over the entries terminated because
523 * the procedure returned false for some entry.
525 public boolean forEachEntry(TIntObjectProcedure<V> procedure) {
526 byte[] states = _states;
528 V[] values = _values;
529 for (int i = keys.length; i-- > 0;) {
530 if (states[i] == FULL && ! procedure.execute(keys[i],values[i])) {
538 * Retains only those entries in the map for which the procedure
539 * returns a true value.
541 * @param procedure determines which entries to keep
542 * @return true if the map was modified.
544 public boolean retainEntries(TIntObjectProcedure<V> procedure) {
545 boolean modified = false;
546 byte[] states = _states;
548 V[] values = _values;
550 // Temporarily disable compaction. This is a fix for bug #1738760
551 tempDisableAutoCompaction();
553 for (int i = keys.length; i-- > 0;) {
554 if (states[i] == FULL && ! procedure.execute(keys[i],values[i])) {
561 reenableAutoCompaction(true);
568 * Transform the values in this map using <tt>function</tt>.
570 * @param function a <code>TObjectFunction</code> value
572 public void transformValues(TObjectFunction<V,V> function) {
573 byte[] states = _states;
574 V[] values = _values;
575 for (int i = values.length; i-- > 0;) {
576 if (states[i] == FULL) {
577 values[i] = function.execute(values[i]);
585 public void writeExternal( ObjectOutput out ) throws IOException {
590 out.writeInt( _size );
593 SerializationProcedure writeProcedure = new SerializationProcedure( out );
594 if (! forEachEntry(writeProcedure)) {
595 throw writeProcedure.exception;
599 public void readExternal( ObjectInput in )
600 throws IOException, ClassNotFoundException {
606 int size = in.readInt();
611 int key = in.readInt();
612 V val = (V) in.readObject();
617 public String toString() {
618 final StringBuilder buf = new StringBuilder("{");
619 forEachEntry(new TIntObjectProcedure<V>() {
620 private boolean first = true;
621 public boolean execute(int key, Object value) {
622 if ( first ) first = false;
623 else buf.append( "," );
632 return buf.toString();
634 } // TIntObjectHashMap