annotate agent/src/share/classes/sun/jvm/hotspot/debugger/LongHashMap.java @ 1913:3b2dea75431e

6984311: JSR 292 needs optional bootstrap method parameters Summary: Allow CONSTANT_InvokeDynamic nodes to have any number of extra operands. Reviewed-by: twisti
author jrose
date Sat, 30 Oct 2010 13:08:23 -0700
parents c18cbe5936b8
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
2 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 package sun.jvm.hotspot.debugger;
a61af66fc99e Initial load
duke
parents:
diff changeset
26
a61af66fc99e Initial load
duke
parents:
diff changeset
27 import java.util.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
28
a61af66fc99e Initial load
duke
parents:
diff changeset
29 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
30 * This is a copy of java.util.HashMap which uses longs as keys
a61af66fc99e Initial load
duke
parents:
diff changeset
31 * instead of Objects. It turns out that using this in the PageCache
a61af66fc99e Initial load
duke
parents:
diff changeset
32 * implementation speeds up heap traversals by a factor of three.
a61af66fc99e Initial load
duke
parents:
diff changeset
33 *
a61af66fc99e Initial load
duke
parents:
diff changeset
34 * @author Josh Bloch
a61af66fc99e Initial load
duke
parents:
diff changeset
35 * @author Arthur van Hoff
a61af66fc99e Initial load
duke
parents:
diff changeset
36 */
a61af66fc99e Initial load
duke
parents:
diff changeset
37
a61af66fc99e Initial load
duke
parents:
diff changeset
38 public class LongHashMap
a61af66fc99e Initial load
duke
parents:
diff changeset
39 {
a61af66fc99e Initial load
duke
parents:
diff changeset
40 static class Entry {
a61af66fc99e Initial load
duke
parents:
diff changeset
41 private int hash;
a61af66fc99e Initial load
duke
parents:
diff changeset
42 private long key;
a61af66fc99e Initial load
duke
parents:
diff changeset
43 private Object value;
a61af66fc99e Initial load
duke
parents:
diff changeset
44 private Entry next;
a61af66fc99e Initial load
duke
parents:
diff changeset
45
a61af66fc99e Initial load
duke
parents:
diff changeset
46 Entry(int hash, long key, Object value, Entry next) {
a61af66fc99e Initial load
duke
parents:
diff changeset
47 this.hash = hash;
a61af66fc99e Initial load
duke
parents:
diff changeset
48 this.key = key;
a61af66fc99e Initial load
duke
parents:
diff changeset
49 this.value = value;
a61af66fc99e Initial load
duke
parents:
diff changeset
50 this.next = next;
a61af66fc99e Initial load
duke
parents:
diff changeset
51 }
a61af66fc99e Initial load
duke
parents:
diff changeset
52
a61af66fc99e Initial load
duke
parents:
diff changeset
53 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
54 * Returns the key corresponding to this entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
55 *
a61af66fc99e Initial load
duke
parents:
diff changeset
56 * @return the key corresponding to this entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
57 */
a61af66fc99e Initial load
duke
parents:
diff changeset
58 long getKey() { return key; }
a61af66fc99e Initial load
duke
parents:
diff changeset
59
a61af66fc99e Initial load
duke
parents:
diff changeset
60 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
61 * Returns the value corresponding to this entry. If the mapping
a61af66fc99e Initial load
duke
parents:
diff changeset
62 * has been removed from the backing map (by the iterator's
a61af66fc99e Initial load
duke
parents:
diff changeset
63 * <tt>remove</tt> operation), the results of this call are undefined.
a61af66fc99e Initial load
duke
parents:
diff changeset
64 *
a61af66fc99e Initial load
duke
parents:
diff changeset
65 * @return the value corresponding to this entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
66 */
a61af66fc99e Initial load
duke
parents:
diff changeset
67 Object getValue() { return value; }
a61af66fc99e Initial load
duke
parents:
diff changeset
68
a61af66fc99e Initial load
duke
parents:
diff changeset
69 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
70 * Replaces the value corresponding to this entry with the specified
a61af66fc99e Initial load
duke
parents:
diff changeset
71 * value (optional operation). (Writes through to the map.) The
a61af66fc99e Initial load
duke
parents:
diff changeset
72 * behavior of this call is undefined if the mapping has already been
a61af66fc99e Initial load
duke
parents:
diff changeset
73 * removed from the map (by the iterator's <tt>remove</tt> operation).
a61af66fc99e Initial load
duke
parents:
diff changeset
74 *
a61af66fc99e Initial load
duke
parents:
diff changeset
75 * @param value new value to be stored in this entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
76 * @return old value corresponding to the entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
77 *
a61af66fc99e Initial load
duke
parents:
diff changeset
78 * @throws UnsupportedOperationException if the <tt>put</tt> operation
a61af66fc99e Initial load
duke
parents:
diff changeset
79 * is not supported by the backing map.
a61af66fc99e Initial load
duke
parents:
diff changeset
80 * @throws ClassCastException if the class of the specified value
a61af66fc99e Initial load
duke
parents:
diff changeset
81 * prevents it from being stored in the backing map.
a61af66fc99e Initial load
duke
parents:
diff changeset
82 * @throws IllegalArgumentException if some aspect of this value
a61af66fc99e Initial load
duke
parents:
diff changeset
83 * prevents it from being stored in the backing map.
a61af66fc99e Initial load
duke
parents:
diff changeset
84 * @throws NullPointerException the backing map does not permit
a61af66fc99e Initial load
duke
parents:
diff changeset
85 * <tt>null</tt> values, and the specified value is
a61af66fc99e Initial load
duke
parents:
diff changeset
86 * <tt>null</tt>.
a61af66fc99e Initial load
duke
parents:
diff changeset
87 */
a61af66fc99e Initial load
duke
parents:
diff changeset
88 Object setValue(Object value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
89 Object oldValue = this.value;
a61af66fc99e Initial load
duke
parents:
diff changeset
90 this.value = value;
a61af66fc99e Initial load
duke
parents:
diff changeset
91 return oldValue;
a61af66fc99e Initial load
duke
parents:
diff changeset
92 }
a61af66fc99e Initial load
duke
parents:
diff changeset
93
a61af66fc99e Initial load
duke
parents:
diff changeset
94 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
95 * Compares the specified object with this entry for equality.
a61af66fc99e Initial load
duke
parents:
diff changeset
96 * Returns <tt>true</tt> if the given object is also a map entry and
a61af66fc99e Initial load
duke
parents:
diff changeset
97 * the two entries represent the same mapping. More formally, two
a61af66fc99e Initial load
duke
parents:
diff changeset
98 * entries <tt>e1</tt> and <tt>e2</tt> represent the same mapping
a61af66fc99e Initial load
duke
parents:
diff changeset
99 * if<pre>
a61af66fc99e Initial load
duke
parents:
diff changeset
100 * (e1.getKey()==null ?
a61af66fc99e Initial load
duke
parents:
diff changeset
101 * e2.getKey()==null : e1.getKey().equals(e2.getKey())) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
102 * (e1.getValue()==null ?
a61af66fc99e Initial load
duke
parents:
diff changeset
103 * e2.getValue()==null : e1.getValue().equals(e2.getValue()))
a61af66fc99e Initial load
duke
parents:
diff changeset
104 * </pre>
a61af66fc99e Initial load
duke
parents:
diff changeset
105 * This ensures that the <tt>equals</tt> method works properly across
a61af66fc99e Initial load
duke
parents:
diff changeset
106 * different implementations of the <tt>Map.Entry</tt> interface.
a61af66fc99e Initial load
duke
parents:
diff changeset
107 *
a61af66fc99e Initial load
duke
parents:
diff changeset
108 * @param o object to be compared for equality with this map entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
109 * @return <tt>true</tt> if the specified object is equal to this map
a61af66fc99e Initial load
duke
parents:
diff changeset
110 * entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
111 */
a61af66fc99e Initial load
duke
parents:
diff changeset
112 public boolean equals(Object o) {
a61af66fc99e Initial load
duke
parents:
diff changeset
113 if (!(o instanceof Entry))
a61af66fc99e Initial load
duke
parents:
diff changeset
114 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
115 Entry e = (Entry)o;
a61af66fc99e Initial load
duke
parents:
diff changeset
116 return (key == e.getKey()) && eq(value, e.getValue());
a61af66fc99e Initial load
duke
parents:
diff changeset
117 }
a61af66fc99e Initial load
duke
parents:
diff changeset
118
a61af66fc99e Initial load
duke
parents:
diff changeset
119 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
120 * Returns the hash code value for this map entry. The hash code
a61af66fc99e Initial load
duke
parents:
diff changeset
121 * of a map entry <tt>e</tt> is defined to be: <pre>
a61af66fc99e Initial load
duke
parents:
diff changeset
122 * (e.getKey()==null ? 0 : e.getKey().hashCode()) ^
a61af66fc99e Initial load
duke
parents:
diff changeset
123 * (e.getValue()==null ? 0 : e.getValue().hashCode())
a61af66fc99e Initial load
duke
parents:
diff changeset
124 * </pre>
a61af66fc99e Initial load
duke
parents:
diff changeset
125 * This ensures that <tt>e1.equals(e2)</tt> implies that
a61af66fc99e Initial load
duke
parents:
diff changeset
126 * <tt>e1.hashCode()==e2.hashCode()</tt> for any two Entries
a61af66fc99e Initial load
duke
parents:
diff changeset
127 * <tt>e1</tt> and <tt>e2</tt>, as required by the general
a61af66fc99e Initial load
duke
parents:
diff changeset
128 * contract of <tt>Object.hashCode</tt>.
a61af66fc99e Initial load
duke
parents:
diff changeset
129 *
a61af66fc99e Initial load
duke
parents:
diff changeset
130 * @return the hash code value for this map entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
131 * @see Object#hashCode()
a61af66fc99e Initial load
duke
parents:
diff changeset
132 * @see Object#equals(Object)
a61af66fc99e Initial load
duke
parents:
diff changeset
133 * @see #equals(Object)
a61af66fc99e Initial load
duke
parents:
diff changeset
134 */
a61af66fc99e Initial load
duke
parents:
diff changeset
135 public int hashCode() {
a61af66fc99e Initial load
duke
parents:
diff changeset
136 return hash ^ (value==null ? 0 : value.hashCode());
a61af66fc99e Initial load
duke
parents:
diff changeset
137 }
a61af66fc99e Initial load
duke
parents:
diff changeset
138 }
a61af66fc99e Initial load
duke
parents:
diff changeset
139
a61af66fc99e Initial load
duke
parents:
diff changeset
140 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
141 * The hash table data.
a61af66fc99e Initial load
duke
parents:
diff changeset
142 */
a61af66fc99e Initial load
duke
parents:
diff changeset
143 transient Entry table[];
a61af66fc99e Initial load
duke
parents:
diff changeset
144
a61af66fc99e Initial load
duke
parents:
diff changeset
145 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
146 * The total number of mappings in the hash table.
a61af66fc99e Initial load
duke
parents:
diff changeset
147 */
a61af66fc99e Initial load
duke
parents:
diff changeset
148 transient int size;
a61af66fc99e Initial load
duke
parents:
diff changeset
149
a61af66fc99e Initial load
duke
parents:
diff changeset
150 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
151 * The table is rehashed when its size exceeds this threshold. (The
a61af66fc99e Initial load
duke
parents:
diff changeset
152 * value of this field is (int)(capacity * loadFactor).)
a61af66fc99e Initial load
duke
parents:
diff changeset
153 *
a61af66fc99e Initial load
duke
parents:
diff changeset
154 * @serial
a61af66fc99e Initial load
duke
parents:
diff changeset
155 */
a61af66fc99e Initial load
duke
parents:
diff changeset
156 int threshold;
a61af66fc99e Initial load
duke
parents:
diff changeset
157
a61af66fc99e Initial load
duke
parents:
diff changeset
158 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
159 * The load factor for the hash table.
a61af66fc99e Initial load
duke
parents:
diff changeset
160 *
a61af66fc99e Initial load
duke
parents:
diff changeset
161 * @serial
a61af66fc99e Initial load
duke
parents:
diff changeset
162 */
a61af66fc99e Initial load
duke
parents:
diff changeset
163 final float loadFactor;
a61af66fc99e Initial load
duke
parents:
diff changeset
164
a61af66fc99e Initial load
duke
parents:
diff changeset
165 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
166 * The number of times this HashMap has been structurally modified
a61af66fc99e Initial load
duke
parents:
diff changeset
167 * Structural modifications are those that change the number of mappings in
a61af66fc99e Initial load
duke
parents:
diff changeset
168 * the HashMap or otherwise modify its internal structure (e.g.,
a61af66fc99e Initial load
duke
parents:
diff changeset
169 * rehash). This field is used to make iterators on Collection-views of
a61af66fc99e Initial load
duke
parents:
diff changeset
170 * the HashMap fail-fast. (See ConcurrentModificationException).
a61af66fc99e Initial load
duke
parents:
diff changeset
171 */
a61af66fc99e Initial load
duke
parents:
diff changeset
172 transient int modCount = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
173
a61af66fc99e Initial load
duke
parents:
diff changeset
174 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
175 * Constructs a new, empty map with the specified initial
a61af66fc99e Initial load
duke
parents:
diff changeset
176 * capacity and the specified load factor.
a61af66fc99e Initial load
duke
parents:
diff changeset
177 *
a61af66fc99e Initial load
duke
parents:
diff changeset
178 * @param initialCapacity the initial capacity of the HashMap.
a61af66fc99e Initial load
duke
parents:
diff changeset
179 * @param loadFactor the load factor of the HashMap
a61af66fc99e Initial load
duke
parents:
diff changeset
180 * @throws IllegalArgumentException if the initial capacity is less
a61af66fc99e Initial load
duke
parents:
diff changeset
181 * than zero, or if the load factor is nonpositive.
a61af66fc99e Initial load
duke
parents:
diff changeset
182 */
a61af66fc99e Initial load
duke
parents:
diff changeset
183 public LongHashMap(int initialCapacity, float loadFactor) {
a61af66fc99e Initial load
duke
parents:
diff changeset
184 if (initialCapacity < 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
185 throw new IllegalArgumentException("Illegal Initial Capacity: "+
a61af66fc99e Initial load
duke
parents:
diff changeset
186 initialCapacity);
a61af66fc99e Initial load
duke
parents:
diff changeset
187 if (loadFactor <= 0 || Float.isNaN(loadFactor))
a61af66fc99e Initial load
duke
parents:
diff changeset
188 throw new IllegalArgumentException("Illegal Load factor: "+
a61af66fc99e Initial load
duke
parents:
diff changeset
189 loadFactor);
a61af66fc99e Initial load
duke
parents:
diff changeset
190 if (initialCapacity==0)
a61af66fc99e Initial load
duke
parents:
diff changeset
191 initialCapacity = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
192 this.loadFactor = loadFactor;
a61af66fc99e Initial load
duke
parents:
diff changeset
193 table = new Entry[initialCapacity];
a61af66fc99e Initial load
duke
parents:
diff changeset
194 threshold = (int)(initialCapacity * loadFactor);
a61af66fc99e Initial load
duke
parents:
diff changeset
195 }
a61af66fc99e Initial load
duke
parents:
diff changeset
196
a61af66fc99e Initial load
duke
parents:
diff changeset
197 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
198 * Constructs a new, empty map with the specified initial capacity
a61af66fc99e Initial load
duke
parents:
diff changeset
199 * and default load factor, which is <tt>0.75</tt>.
a61af66fc99e Initial load
duke
parents:
diff changeset
200 *
a61af66fc99e Initial load
duke
parents:
diff changeset
201 * @param initialCapacity the initial capacity of the HashMap.
a61af66fc99e Initial load
duke
parents:
diff changeset
202 * @throws IllegalArgumentException if the initial capacity is less
a61af66fc99e Initial load
duke
parents:
diff changeset
203 * than zero.
a61af66fc99e Initial load
duke
parents:
diff changeset
204 */
a61af66fc99e Initial load
duke
parents:
diff changeset
205 public LongHashMap(int initialCapacity) {
a61af66fc99e Initial load
duke
parents:
diff changeset
206 this(initialCapacity, 0.75f);
a61af66fc99e Initial load
duke
parents:
diff changeset
207 }
a61af66fc99e Initial load
duke
parents:
diff changeset
208
a61af66fc99e Initial load
duke
parents:
diff changeset
209 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
210 * Constructs a new, empty map with a default capacity and load
a61af66fc99e Initial load
duke
parents:
diff changeset
211 * factor, which is <tt>0.75</tt>.
a61af66fc99e Initial load
duke
parents:
diff changeset
212 */
a61af66fc99e Initial load
duke
parents:
diff changeset
213 public LongHashMap() {
a61af66fc99e Initial load
duke
parents:
diff changeset
214 this(11, 0.75f);
a61af66fc99e Initial load
duke
parents:
diff changeset
215 }
a61af66fc99e Initial load
duke
parents:
diff changeset
216
a61af66fc99e Initial load
duke
parents:
diff changeset
217 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
218 * Returns the number of key-value mappings in this map.
a61af66fc99e Initial load
duke
parents:
diff changeset
219 *
a61af66fc99e Initial load
duke
parents:
diff changeset
220 * @return the number of key-value mappings in this map.
a61af66fc99e Initial load
duke
parents:
diff changeset
221 */
a61af66fc99e Initial load
duke
parents:
diff changeset
222 public int size() {
a61af66fc99e Initial load
duke
parents:
diff changeset
223 return size;
a61af66fc99e Initial load
duke
parents:
diff changeset
224 }
a61af66fc99e Initial load
duke
parents:
diff changeset
225
a61af66fc99e Initial load
duke
parents:
diff changeset
226 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
227 * Returns <tt>true</tt> if this map contains no key-value mappings.
a61af66fc99e Initial load
duke
parents:
diff changeset
228 *
a61af66fc99e Initial load
duke
parents:
diff changeset
229 * @return <tt>true</tt> if this map contains no key-value mappings.
a61af66fc99e Initial load
duke
parents:
diff changeset
230 */
a61af66fc99e Initial load
duke
parents:
diff changeset
231 public boolean isEmpty() {
a61af66fc99e Initial load
duke
parents:
diff changeset
232 return size == 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
233 }
a61af66fc99e Initial load
duke
parents:
diff changeset
234
a61af66fc99e Initial load
duke
parents:
diff changeset
235 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
236 * Returns the value to which this map maps the specified key. Returns
a61af66fc99e Initial load
duke
parents:
diff changeset
237 * <tt>null</tt> if the map contains no mapping for this key. A return
a61af66fc99e Initial load
duke
parents:
diff changeset
238 * value of <tt>null</tt> does not <i>necessarily</i> indicate that the
a61af66fc99e Initial load
duke
parents:
diff changeset
239 * map contains no mapping for the key; it's also possible that the map
a61af66fc99e Initial load
duke
parents:
diff changeset
240 * explicitly maps the key to <tt>null</tt>. The <tt>containsKey</tt>
a61af66fc99e Initial load
duke
parents:
diff changeset
241 * operation may be used to distinguish these two cases.
a61af66fc99e Initial load
duke
parents:
diff changeset
242 *
a61af66fc99e Initial load
duke
parents:
diff changeset
243 * @return the value to which this map maps the specified key.
a61af66fc99e Initial load
duke
parents:
diff changeset
244 * @param key key whose associated value is to be returned.
a61af66fc99e Initial load
duke
parents:
diff changeset
245 */
a61af66fc99e Initial load
duke
parents:
diff changeset
246 public Object get(long key) {
a61af66fc99e Initial load
duke
parents:
diff changeset
247 Entry e = getEntry(key);
a61af66fc99e Initial load
duke
parents:
diff changeset
248 return (e == null ? null : e.value);
a61af66fc99e Initial load
duke
parents:
diff changeset
249 }
a61af66fc99e Initial load
duke
parents:
diff changeset
250
a61af66fc99e Initial load
duke
parents:
diff changeset
251 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
252 * Returns <tt>true</tt> if this map contains a mapping for the specified
a61af66fc99e Initial load
duke
parents:
diff changeset
253 * key.
a61af66fc99e Initial load
duke
parents:
diff changeset
254 *
a61af66fc99e Initial load
duke
parents:
diff changeset
255 * @return <tt>true</tt> if this map contains a mapping for the specified
a61af66fc99e Initial load
duke
parents:
diff changeset
256 * key.
a61af66fc99e Initial load
duke
parents:
diff changeset
257 * @param key key whose presence in this Map is to be tested.
a61af66fc99e Initial load
duke
parents:
diff changeset
258 */
a61af66fc99e Initial load
duke
parents:
diff changeset
259 public boolean containsKey(long key) {
a61af66fc99e Initial load
duke
parents:
diff changeset
260 return getEntry(key) != null;
a61af66fc99e Initial load
duke
parents:
diff changeset
261 }
a61af66fc99e Initial load
duke
parents:
diff changeset
262
a61af66fc99e Initial load
duke
parents:
diff changeset
263 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
264 * Returns the entry associated with the specified key in the
a61af66fc99e Initial load
duke
parents:
diff changeset
265 * HashMap. Returns null if the HashMap contains no mapping
a61af66fc99e Initial load
duke
parents:
diff changeset
266 * for this key.
a61af66fc99e Initial load
duke
parents:
diff changeset
267 */
a61af66fc99e Initial load
duke
parents:
diff changeset
268 Entry getEntry(long key) {
a61af66fc99e Initial load
duke
parents:
diff changeset
269 Entry tab[] = table;
a61af66fc99e Initial load
duke
parents:
diff changeset
270 int hash = (int) key;
a61af66fc99e Initial load
duke
parents:
diff changeset
271 int index = (hash & 0x7FFFFFFF) % tab.length;
a61af66fc99e Initial load
duke
parents:
diff changeset
272
a61af66fc99e Initial load
duke
parents:
diff changeset
273 for (Entry e = tab[index]; e != null; e = e.next)
a61af66fc99e Initial load
duke
parents:
diff changeset
274 if (e.hash == hash && e.key ==key)
a61af66fc99e Initial load
duke
parents:
diff changeset
275 return e;
a61af66fc99e Initial load
duke
parents:
diff changeset
276
a61af66fc99e Initial load
duke
parents:
diff changeset
277 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
278 }
a61af66fc99e Initial load
duke
parents:
diff changeset
279
a61af66fc99e Initial load
duke
parents:
diff changeset
280 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
281 * Returns <tt>true</tt> if this map maps one or more keys to the
a61af66fc99e Initial load
duke
parents:
diff changeset
282 * specified value.
a61af66fc99e Initial load
duke
parents:
diff changeset
283 *
a61af66fc99e Initial load
duke
parents:
diff changeset
284 * @param value value whose presence in this map is to be tested.
a61af66fc99e Initial load
duke
parents:
diff changeset
285 * @return <tt>true</tt> if this map maps one or more keys to the
a61af66fc99e Initial load
duke
parents:
diff changeset
286 * specified value.
a61af66fc99e Initial load
duke
parents:
diff changeset
287 */
a61af66fc99e Initial load
duke
parents:
diff changeset
288 public boolean containsValue(Object value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
289 Entry tab[] = table;
a61af66fc99e Initial load
duke
parents:
diff changeset
290
a61af66fc99e Initial load
duke
parents:
diff changeset
291 if (value==null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
292 for (int i = tab.length ; i-- > 0 ;)
a61af66fc99e Initial load
duke
parents:
diff changeset
293 for (Entry e = tab[i] ; e != null ; e = e.next)
a61af66fc99e Initial load
duke
parents:
diff changeset
294 if (e.value==null)
a61af66fc99e Initial load
duke
parents:
diff changeset
295 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
296 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
297 for (int i = tab.length ; i-- > 0 ;)
a61af66fc99e Initial load
duke
parents:
diff changeset
298 for (Entry e = tab[i] ; e != null ; e = e.next)
a61af66fc99e Initial load
duke
parents:
diff changeset
299 if (value.equals(e.value))
a61af66fc99e Initial load
duke
parents:
diff changeset
300 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
301 }
a61af66fc99e Initial load
duke
parents:
diff changeset
302
a61af66fc99e Initial load
duke
parents:
diff changeset
303 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
304 }
a61af66fc99e Initial load
duke
parents:
diff changeset
305
a61af66fc99e Initial load
duke
parents:
diff changeset
306 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
307 * Associates the specified value with the specified key in this map.
a61af66fc99e Initial load
duke
parents:
diff changeset
308 * If the map previously contained a mapping for this key, the old
a61af66fc99e Initial load
duke
parents:
diff changeset
309 * value is replaced.
a61af66fc99e Initial load
duke
parents:
diff changeset
310 *
a61af66fc99e Initial load
duke
parents:
diff changeset
311 * @param key key with which the specified value is to be associated.
a61af66fc99e Initial load
duke
parents:
diff changeset
312 * @param value value to be associated with the specified key.
a61af66fc99e Initial load
duke
parents:
diff changeset
313 * @return previous value associated with specified key, or <tt>null</tt>
a61af66fc99e Initial load
duke
parents:
diff changeset
314 * if there was no mapping for key. A <tt>null</tt> return can
a61af66fc99e Initial load
duke
parents:
diff changeset
315 * also indicate that the HashMap previously associated
a61af66fc99e Initial load
duke
parents:
diff changeset
316 * <tt>null</tt> with the specified key.
a61af66fc99e Initial load
duke
parents:
diff changeset
317 */
a61af66fc99e Initial load
duke
parents:
diff changeset
318 public Object put(long key, Object value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
319 Entry tab[] = table;
a61af66fc99e Initial load
duke
parents:
diff changeset
320 int hash = (int) key;
a61af66fc99e Initial load
duke
parents:
diff changeset
321 int index = (hash & 0x7FFFFFFF) % tab.length;
a61af66fc99e Initial load
duke
parents:
diff changeset
322
a61af66fc99e Initial load
duke
parents:
diff changeset
323 // Look for entry in hash table
a61af66fc99e Initial load
duke
parents:
diff changeset
324 for (Entry e = tab[index] ; e != null ; e = e.next) {
a61af66fc99e Initial load
duke
parents:
diff changeset
325 if (e.hash == hash && e.key == key) {
a61af66fc99e Initial load
duke
parents:
diff changeset
326 Object oldValue = e.value;
a61af66fc99e Initial load
duke
parents:
diff changeset
327 e.value = value;
a61af66fc99e Initial load
duke
parents:
diff changeset
328 return oldValue;
a61af66fc99e Initial load
duke
parents:
diff changeset
329 }
a61af66fc99e Initial load
duke
parents:
diff changeset
330 }
a61af66fc99e Initial load
duke
parents:
diff changeset
331
a61af66fc99e Initial load
duke
parents:
diff changeset
332 // It's not there; grow the hash table if necessary...
a61af66fc99e Initial load
duke
parents:
diff changeset
333 modCount++;
a61af66fc99e Initial load
duke
parents:
diff changeset
334 if (size >= threshold) {
a61af66fc99e Initial load
duke
parents:
diff changeset
335 rehash();
a61af66fc99e Initial load
duke
parents:
diff changeset
336 tab = table;
a61af66fc99e Initial load
duke
parents:
diff changeset
337 index = (hash & 0x7FFFFFFF) % tab.length;
a61af66fc99e Initial load
duke
parents:
diff changeset
338 }
a61af66fc99e Initial load
duke
parents:
diff changeset
339
a61af66fc99e Initial load
duke
parents:
diff changeset
340 // ...and add the entry
a61af66fc99e Initial load
duke
parents:
diff changeset
341 size++;
a61af66fc99e Initial load
duke
parents:
diff changeset
342 tab[index] = newEntry(hash, key, value, tab[index]);
a61af66fc99e Initial load
duke
parents:
diff changeset
343 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
344 }
a61af66fc99e Initial load
duke
parents:
diff changeset
345
a61af66fc99e Initial load
duke
parents:
diff changeset
346 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
347 * Removes the mapping for this key from this map if present.
a61af66fc99e Initial load
duke
parents:
diff changeset
348 *
a61af66fc99e Initial load
duke
parents:
diff changeset
349 * @param key key whose mapping is to be removed from the map.
a61af66fc99e Initial load
duke
parents:
diff changeset
350 * @return previous value associated with specified key, or <tt>null</tt>
a61af66fc99e Initial load
duke
parents:
diff changeset
351 * if there was no mapping for key. A <tt>null</tt> return can
a61af66fc99e Initial load
duke
parents:
diff changeset
352 * also indicate that the map previously associated <tt>null</tt>
a61af66fc99e Initial load
duke
parents:
diff changeset
353 * with the specified key.
a61af66fc99e Initial load
duke
parents:
diff changeset
354 */
a61af66fc99e Initial load
duke
parents:
diff changeset
355 public Object remove(long key) {
a61af66fc99e Initial load
duke
parents:
diff changeset
356 Entry e = removeEntryForKey(key);
a61af66fc99e Initial load
duke
parents:
diff changeset
357 return (e == null ? null : e.value);
a61af66fc99e Initial load
duke
parents:
diff changeset
358 }
a61af66fc99e Initial load
duke
parents:
diff changeset
359
a61af66fc99e Initial load
duke
parents:
diff changeset
360 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
361 * Removes and returns the entry associated with the specified key
a61af66fc99e Initial load
duke
parents:
diff changeset
362 * in the HashMap. Returns null if the HashMap contains no mapping
a61af66fc99e Initial load
duke
parents:
diff changeset
363 * for this key.
a61af66fc99e Initial load
duke
parents:
diff changeset
364 */
a61af66fc99e Initial load
duke
parents:
diff changeset
365 Entry removeEntryForKey(long key) {
a61af66fc99e Initial load
duke
parents:
diff changeset
366 Entry tab[] = table;
a61af66fc99e Initial load
duke
parents:
diff changeset
367 int hash = (int) key;
a61af66fc99e Initial load
duke
parents:
diff changeset
368 int index = (hash & 0x7FFFFFFF) % tab.length;
a61af66fc99e Initial load
duke
parents:
diff changeset
369
a61af66fc99e Initial load
duke
parents:
diff changeset
370 for (Entry e = tab[index], prev = null; e != null;
a61af66fc99e Initial load
duke
parents:
diff changeset
371 prev = e, e = e.next) {
a61af66fc99e Initial load
duke
parents:
diff changeset
372 if (e.hash == hash && e.key == key) {
a61af66fc99e Initial load
duke
parents:
diff changeset
373 modCount++;
a61af66fc99e Initial load
duke
parents:
diff changeset
374 if (prev != null)
a61af66fc99e Initial load
duke
parents:
diff changeset
375 prev.next = e.next;
a61af66fc99e Initial load
duke
parents:
diff changeset
376 else
a61af66fc99e Initial load
duke
parents:
diff changeset
377 tab[index] = e.next;
a61af66fc99e Initial load
duke
parents:
diff changeset
378
a61af66fc99e Initial load
duke
parents:
diff changeset
379 size--;
a61af66fc99e Initial load
duke
parents:
diff changeset
380 return e;
a61af66fc99e Initial load
duke
parents:
diff changeset
381 }
a61af66fc99e Initial load
duke
parents:
diff changeset
382 }
a61af66fc99e Initial load
duke
parents:
diff changeset
383
a61af66fc99e Initial load
duke
parents:
diff changeset
384 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
385 }
a61af66fc99e Initial load
duke
parents:
diff changeset
386
a61af66fc99e Initial load
duke
parents:
diff changeset
387 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
388 * Removes the specified entry from this HashMap (and increments modCount).
a61af66fc99e Initial load
duke
parents:
diff changeset
389 *
a61af66fc99e Initial load
duke
parents:
diff changeset
390 * @throws ConcurrentModificationException if the entry is not in the Map
a61af66fc99e Initial load
duke
parents:
diff changeset
391 */
a61af66fc99e Initial load
duke
parents:
diff changeset
392 void removeEntry(Entry doomed) {
a61af66fc99e Initial load
duke
parents:
diff changeset
393 Entry[] tab = table;
a61af66fc99e Initial load
duke
parents:
diff changeset
394 int index = (doomed.hash & 0x7FFFFFFF) % tab.length;
a61af66fc99e Initial load
duke
parents:
diff changeset
395
a61af66fc99e Initial load
duke
parents:
diff changeset
396 for (Entry e = tab[index], prev = null; e != null;
a61af66fc99e Initial load
duke
parents:
diff changeset
397 prev = e, e = e.next) {
a61af66fc99e Initial load
duke
parents:
diff changeset
398 if (e == doomed) {
a61af66fc99e Initial load
duke
parents:
diff changeset
399 modCount++;
a61af66fc99e Initial load
duke
parents:
diff changeset
400 if (prev == null)
a61af66fc99e Initial load
duke
parents:
diff changeset
401 tab[index] = e.next;
a61af66fc99e Initial load
duke
parents:
diff changeset
402 else
a61af66fc99e Initial load
duke
parents:
diff changeset
403 prev.next = e.next;
a61af66fc99e Initial load
duke
parents:
diff changeset
404 size--;
a61af66fc99e Initial load
duke
parents:
diff changeset
405 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
406 }
a61af66fc99e Initial load
duke
parents:
diff changeset
407 }
a61af66fc99e Initial load
duke
parents:
diff changeset
408 throw new ConcurrentModificationException();
a61af66fc99e Initial load
duke
parents:
diff changeset
409 }
a61af66fc99e Initial load
duke
parents:
diff changeset
410
a61af66fc99e Initial load
duke
parents:
diff changeset
411 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
412 * Removes all mappings from this map.
a61af66fc99e Initial load
duke
parents:
diff changeset
413 */
a61af66fc99e Initial load
duke
parents:
diff changeset
414 public void clear() {
a61af66fc99e Initial load
duke
parents:
diff changeset
415 Entry tab[] = table;
a61af66fc99e Initial load
duke
parents:
diff changeset
416 modCount++;
a61af66fc99e Initial load
duke
parents:
diff changeset
417 for (int index = tab.length; --index >= 0; )
a61af66fc99e Initial load
duke
parents:
diff changeset
418 tab[index] = null;
a61af66fc99e Initial load
duke
parents:
diff changeset
419 size = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
420 }
a61af66fc99e Initial load
duke
parents:
diff changeset
421
a61af66fc99e Initial load
duke
parents:
diff changeset
422 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
423 * Rehashes the contents of this map into a new <tt>HashMap</tt> instance
a61af66fc99e Initial load
duke
parents:
diff changeset
424 * with a larger capacity. This method is called automatically when the
a61af66fc99e Initial load
duke
parents:
diff changeset
425 * number of keys in this map exceeds its capacity and load factor.
a61af66fc99e Initial load
duke
parents:
diff changeset
426 */
a61af66fc99e Initial load
duke
parents:
diff changeset
427 void rehash() {
a61af66fc99e Initial load
duke
parents:
diff changeset
428 Entry oldTable[] = table;
a61af66fc99e Initial load
duke
parents:
diff changeset
429 int oldCapacity = oldTable.length;
a61af66fc99e Initial load
duke
parents:
diff changeset
430 int newCapacity = oldCapacity * 2 + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
431 Entry newTable[] = new Entry[newCapacity];
a61af66fc99e Initial load
duke
parents:
diff changeset
432
a61af66fc99e Initial load
duke
parents:
diff changeset
433 modCount++;
a61af66fc99e Initial load
duke
parents:
diff changeset
434 threshold = (int)(newCapacity * loadFactor);
a61af66fc99e Initial load
duke
parents:
diff changeset
435 table = newTable;
a61af66fc99e Initial load
duke
parents:
diff changeset
436
a61af66fc99e Initial load
duke
parents:
diff changeset
437 for (int i = oldCapacity ; i-- > 0 ;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
438 for (Entry old = oldTable[i] ; old != null ; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
439 Entry e = old;
a61af66fc99e Initial load
duke
parents:
diff changeset
440 old = old.next;
a61af66fc99e Initial load
duke
parents:
diff changeset
441
a61af66fc99e Initial load
duke
parents:
diff changeset
442 int index = (e.hash & 0x7FFFFFFF) % newCapacity;
a61af66fc99e Initial load
duke
parents:
diff changeset
443 e.next = newTable[index];
a61af66fc99e Initial load
duke
parents:
diff changeset
444 newTable[index] = e;
a61af66fc99e Initial load
duke
parents:
diff changeset
445 }
a61af66fc99e Initial load
duke
parents:
diff changeset
446 }
a61af66fc99e Initial load
duke
parents:
diff changeset
447 }
a61af66fc99e Initial load
duke
parents:
diff changeset
448
a61af66fc99e Initial load
duke
parents:
diff changeset
449 static boolean eq(Object o1, Object o2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
450 return (o1==null ? o2==null : o1.equals(o2));
a61af66fc99e Initial load
duke
parents:
diff changeset
451 }
a61af66fc99e Initial load
duke
parents:
diff changeset
452
a61af66fc99e Initial load
duke
parents:
diff changeset
453 Entry newEntry(int hash, long key, Object value, Entry next) {
a61af66fc99e Initial load
duke
parents:
diff changeset
454 return new Entry(hash, key, value, next);
a61af66fc99e Initial load
duke
parents:
diff changeset
455 }
a61af66fc99e Initial load
duke
parents:
diff changeset
456
a61af66fc99e Initial load
duke
parents:
diff changeset
457 int capacity() {
a61af66fc99e Initial load
duke
parents:
diff changeset
458 return table.length;
a61af66fc99e Initial load
duke
parents:
diff changeset
459 }
a61af66fc99e Initial load
duke
parents:
diff changeset
460
a61af66fc99e Initial load
duke
parents:
diff changeset
461 float loadFactor() {
a61af66fc99e Initial load
duke
parents:
diff changeset
462 return loadFactor;
a61af66fc99e Initial load
duke
parents:
diff changeset
463 }
a61af66fc99e Initial load
duke
parents:
diff changeset
464 }