KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > corba > se > impl > util > IdentityHashtable


1 /*
2  * @(#)IdentityHashtable.java 1.14 04/03/02
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 /*
9  * Licensed Materials - Property of IBM
10  * RMI-IIOP v1.0
11  * Copyright IBM Corp. 1998 1999 All Rights Reserved
12  *
13  * US Government Users Restricted Rights - Use, duplication or
14  * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
15  */

16
17 package com.sun.corba.se.impl.util;
18
19 import java.util.Dictionary JavaDoc;
20 import java.util.Enumeration JavaDoc;
21 import java.util.NoSuchElementException JavaDoc;
22
23 /**
24  * IdentityHashtable is a modified copy of the 1.1.6 Hashtable class which
25  * does not rely on the hashCode() and equals() methods of the key or value;
26  * instead, it uses the System.identityHashcode() method and pointer comparison.
27  * In addition, all synchronization has been removed.
28  */

29 /**
30  * IdentityHashtable collision list.
31  */

32 class IdentityHashtableEntry {
33     int hash;
34     Object JavaDoc key;
35     Object JavaDoc value;
36     IdentityHashtableEntry next;
37 }
38
39 public final class IdentityHashtable extends Dictionary JavaDoc {
40     /**
41      * The hash table data.
42      */

43     private transient IdentityHashtableEntry table[];
44
45     /**
46      * The total number of entries in the hash table.
47      */

48     private transient int count;
49
50     /**
51      * Rehashes the table when count exceeds this threshold.
52      */

53     private int threshold;
54
55     /**
56      * The load factor for the hashtable.
57      */

58     private float loadFactor;
59
60     /**
61      * Constructs a new, empty hashtable with the specified initial
62      * capacity and the specified load factor.
63      *
64      * @param initialCapacity the initial capacity of the hashtable.
65      * @param loadFactor a number between 0.0 and 1.0.
66      * @exception IllegalArgumentException if the initial capacity is less
67      * than or equal to zero, or if the load factor is less than
68      * or equal to zero.
69      * @since JDK1.0
70      */

71     public IdentityHashtable(int initialCapacity, float loadFactor) {
72     if ((initialCapacity <= 0) || (loadFactor <= 0.0)) {
73         throw new IllegalArgumentException JavaDoc();
74     }
75     this.loadFactor = loadFactor;
76     table = new IdentityHashtableEntry[initialCapacity];
77     threshold = (int)(initialCapacity * loadFactor);
78     }
79
80     /**
81      * Constructs a new, empty hashtable with the specified initial capacity
82      * and default load factor.
83      *
84      * @param initialCapacity the initial capacity of the hashtable.
85      * @since JDK1.0
86      */

87     public IdentityHashtable(int initialCapacity) {
88     this(initialCapacity, 0.75f);
89     }
90
91     /**
92      * Constructs a new, empty hashtable with a default capacity and load
93      * factor.
94      *
95      * @since JDK1.0
96      */

97     public IdentityHashtable() {
98     this(101, 0.75f);
99     }
100
101     /**
102      * Returns the number of keys in this hashtable.
103      *
104      * @return the number of keys in this hashtable.
105      * @since JDK1.0
106      */

107     public int size() {
108     return count;
109     }
110
111     /**
112      * Tests if this hashtable maps no keys to values.
113      *
114      * @return <code>true</code> if this hashtable maps no keys to values;
115      * <code>false</code> otherwise.
116      * @since JDK1.0
117      */

118     public boolean isEmpty() {
119     return count == 0;
120     }
121
122     /**
123      * Returns an enumeration of the keys in this hashtable.
124      *
125      * @return an enumeration of the keys in this hashtable.
126      * @see java.util.Enumeration
127      * @see java.util.Hashtable#elements()
128      * @since JDK1.0
129      */

130     public Enumeration JavaDoc keys() {
131     return new IdentityHashtableEnumerator(table, true);
132     }
133
134     /**
135      * Returns an enumeration of the values in this hashtable.
136      * Use the Enumeration methods on the returned object to fetch the elements
137      * sequentially.
138      *
139      * @return an enumeration of the values in this hashtable.
140      * @see java.util.Enumeration
141      * @see java.util.Hashtable#keys()
142      * @since JDK1.0
143      */

144     public Enumeration JavaDoc elements() {
145     return new IdentityHashtableEnumerator(table, false);
146     }
147
148     /**
149      * Tests if some key maps into the specified value in this hashtable.
150      * This operation is more expensive than the <code>containsKey</code>
151      * method.
152      *
153      * @param value a value to search for.
154      * @return <code>true</code> if some key maps to the
155      * <code>value</code> argument in this hashtable;
156      * <code>false</code> otherwise.
157      * @exception NullPointerException if the value is <code>null</code>.
158      * @see java.util.Hashtable#containsKey(java.lang.Object)
159      * @since JDK1.0
160      */

161     public boolean contains(Object JavaDoc value) {
162     if (value == null) {
163         throw new NullPointerException JavaDoc();
164     }
165
166     IdentityHashtableEntry tab[] = table;
167     for (int i = tab.length ; i-- > 0 ;) {
168         for (IdentityHashtableEntry e = tab[i] ; e != null ; e = e.next) {
169         if (e.value == value) {
170             return true;
171         }
172         }
173     }
174     return false;
175     }
176
177     /**
178      * Tests if the specified object is a key in this hashtable.
179      *
180      * @param key possible key.
181      * @return <code>true</code> if the specified object is a key in this
182      * hashtable; <code>false</code> otherwise.
183      * @see java.util.Hashtable#contains(java.lang.Object)
184      * @since JDK1.0
185      */

186     public boolean containsKey(Object JavaDoc key) {
187     IdentityHashtableEntry tab[] = table;
188     int hash = System.identityHashCode(key);
189     int index = (hash & 0x7FFFFFFF) % tab.length;
190     for (IdentityHashtableEntry e = tab[index] ; e != null ; e = e.next) {
191         if ((e.hash == hash) && e.key == key) {
192         return true;
193         }
194     }
195     return false;
196     }
197
198     /**
199      * Returns the value to which the specified key is mapped in this hashtable.
200      *
201      * @param key a key in the hashtable.
202      * @return the value to which the key is mapped in this hashtable;
203      * <code>null</code> if the key is not mapped to any value in
204      * this hashtable.
205      * @see java.util.Hashtable#put(java.lang.Object, java.lang.Object)
206      * @since JDK1.0
207      */

208     public Object JavaDoc get(Object JavaDoc key) {
209     IdentityHashtableEntry tab[] = table;
210     int hash = System.identityHashCode(key);
211     int index = (hash & 0x7FFFFFFF) % tab.length;
212     for (IdentityHashtableEntry e = tab[index] ; e != null ; e = e.next) {
213         if ((e.hash == hash) && e.key == key) {
214         return e.value;
215         }
216     }
217     return null;
218     }
219
220     /**
221      * Rehashes the contents of the hashtable into a hashtable with a
222      * larger capacity. This method is called automatically when the
223      * number of keys in the hashtable exceeds this hashtable's capacity
224      * and load factor.
225      *
226      * @since JDK1.0
227      */

228     protected void rehash() {
229     int oldCapacity = table.length;
230     IdentityHashtableEntry oldTable[] = table;
231
232     int newCapacity = oldCapacity * 2 + 1;
233     IdentityHashtableEntry newTable[] = new IdentityHashtableEntry[newCapacity];
234
235     threshold = (int)(newCapacity * loadFactor);
236     table = newTable;
237
238     //System.out.println("rehash old=" + oldCapacity + ", new=" + newCapacity + ", thresh=" + threshold + ", count=" + count);
239

240     for (int i = oldCapacity ; i-- > 0 ;) {
241         for (IdentityHashtableEntry old = oldTable[i] ; old != null ; ) {
242         IdentityHashtableEntry e = old;
243         old = old.next;
244
245         int index = (e.hash & 0x7FFFFFFF) % newCapacity;
246         e.next = newTable[index];
247         newTable[index] = e;
248         }
249     }
250     }
251
252     /**
253      * Maps the specified <code>key</code> to the specified
254      * <code>value</code> in this hashtable. Neither the key nor the
255      * value can be <code>null</code>.
256      * <p>
257      * The value can be retrieved by calling the <code>get</code> method
258      * with a key that is equal to the original key.
259      *
260      * @param key the hashtable key.
261      * @param value the value.
262      * @return the previous value of the specified key in this hashtable,
263      * or <code>null</code> if it did not have one.
264      * @exception NullPointerException if the key or value is
265      * <code>null</code>.
266      * @see java.util.Hashtable#get(java.lang.Object)
267      * @since JDK1.0
268      */

269     public Object JavaDoc put(Object JavaDoc key, Object JavaDoc value) {
270     // Make sure the value is not null
271
if (value == null) {
272         throw new NullPointerException JavaDoc();
273     }
274
275     // Makes sure the key is not already in the hashtable.
276
IdentityHashtableEntry tab[] = table;
277     int hash = System.identityHashCode(key);
278     int index = (hash & 0x7FFFFFFF) % tab.length;
279     for (IdentityHashtableEntry e = tab[index] ; e != null ; e = e.next) {
280         if ((e.hash == hash) && e.key == key) {
281         Object JavaDoc old = e.value;
282         e.value = value;
283         return old;
284         }
285     }
286
287     if (count >= threshold) {
288         // Rehash the table if the threshold is exceeded
289
rehash();
290         return put(key, value);
291     }
292
293     // Creates the new entry.
294
IdentityHashtableEntry e = new IdentityHashtableEntry();
295     e.hash = hash;
296     e.key = key;
297     e.value = value;
298     e.next = tab[index];
299     tab[index] = e;
300     count++;
301     return null;
302     }
303
304     /**
305      * Removes the key (and its corresponding value) from this
306      * hashtable. This method does nothing if the key is not in the hashtable.
307      *
308      * @param key the key that needs to be removed.
309      * @return the value to which the key had been mapped in this hashtable,
310      * or <code>null</code> if the key did not have a mapping.
311      * @since JDK1.0
312      */

313     public Object JavaDoc remove(Object JavaDoc key) {
314     IdentityHashtableEntry tab[] = table;
315     int hash = System.identityHashCode(key);
316     int index = (hash & 0x7FFFFFFF) % tab.length;
317     for (IdentityHashtableEntry e = tab[index], prev = null ; e != null ; prev = e, e = e.next) {
318         if ((e.hash == hash) && e.key == key) {
319         if (prev != null) {
320             prev.next = e.next;
321         } else {
322             tab[index] = e.next;
323         }
324         count--;
325         return e.value;
326         }
327     }
328     return null;
329     }
330
331     /**
332      * Clears this hashtable so that it contains no keys.
333      *
334      * @since JDK1.0
335      */

336     public void clear() {
337     IdentityHashtableEntry tab[] = table;
338     for (int index = tab.length; --index >= 0; )
339         tab[index] = null;
340     count = 0;
341     }
342
343     /**
344      * Returns a rather long string representation of this hashtable.
345      *
346      * @return a string representation of this hashtable.
347      * @since JDK1.0
348      */

349     public String JavaDoc toString() {
350     int max = size() - 1;
351     StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
352     Enumeration JavaDoc k = keys();
353     Enumeration JavaDoc e = elements();
354     buf.append("{");
355
356     for (int i = 0; i <= max; i++) {
357         String JavaDoc s1 = k.nextElement().toString();
358         String JavaDoc s2 = e.nextElement().toString();
359         buf.append(s1 + "=" + s2);
360         if (i < max) {
361         buf.append(", ");
362         }
363     }
364     buf.append("}");
365     return buf.toString();
366     }
367 }
368
Popular Tags