History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/util/PreHashedMap.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/util/PreHashedMap.java+289−0
@@ -0,0 +1,289 @@
1/*
2 * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package sun.util;
27
28import java.util.Iterator;
29import java.util.Map;
30import java.util.Set;
31import java.util.AbstractMap;
32import java.util.AbstractSet;
33import java.util.NoSuchElementException;
34
35
36/**
37 * A precomputed hash map.
38 *
39 * <p> Subclasses of this class are of the following form:
40 *
41 * <blockquote><pre>
42 * class FooMap
43 * extends sun.util.PreHashedMap&lt;String&gt;
44 * {
45 *
46 * private FooMap() {
47 * super(ROWS, SIZE, SHIFT, MASK);
48 * }
49 *
50 * protected void init(Object[] ht) {
51 * ht[0] = new Object[] { "key-1", value_1 };
52 * ht[1] = new Object[] { "key-2", value_2,
53 * new Object { "key-3", value_3 } };
54 * ...
55 * }
56 *
57 * }</pre></blockquote>
58 *
59 * <p> The <tt>init</tt> method is invoked by the <tt>PreHashedMap</tt>
60 * constructor with an object array long enough for the map's rows. The method
61 * must construct the hash chain for each row and store it in the appropriate
62 * element of the array.
63 *
64 * <p> Each entry in the map is represented by a unique hash-chain node. The
65 * final node of a hash chain is a two-element object array whose first element
66 * is the entry's key and whose second element is the entry's value. A
67 * non-final node of a hash chain is a three-element object array whose first
68 * two elements are the entry's key and value and whose third element is the
69 * next node in the chain.
70 *
71 * <p> Instances of this class are mutable and are not safe for concurrent
72 * access. They may be made immutable and thread-safe via the appropriate
73 * methods in the {@link java.util.Collections} utility class.
74 *
75 * <p> In the JDK build, subclasses of this class are typically created via the
76 * <tt>Hasher</tt> program in the <tt>make/tools/Hasher</tt> directory.
77 *
78 * @author Mark Reinhold
79 * @since 1.5
80 *
81 * @see java.util.AbstractMap
82 */
83
84public abstract class PreHashedMap<V>
85 extends AbstractMap<String,V>
86{
87
88 private final int rows;
89 private final int size;
90 private final int shift;
91 private final int mask;
92 private final Object[] ht;
93
94 /**
95 * Creates a new map.
96 *
97 * <p> This constructor invokes the {@link #init init} method, passing it a
98 * newly-constructed row array that is <tt>rows</tt> elements long.
99 *
100 * @param rows
101 * The number of rows in the map
102 * @param size
103 * The number of entries in the map
104 * @param shift
105 * The value by which hash codes are right-shifted
106 * @param mask
107 * The value with which hash codes are masked after being shifted
108 */
109 protected PreHashedMap(int rows, int size, int shift, int mask) {
110 this.rows = rows;
111 this.size = size;
112 this.shift = shift;
113 this.mask = mask;
114 this.ht = new Object[rows];
115 init(ht);
116 }
117
118 /**
119 * Initializes this map.
120 *
121 * <p> This method must construct the map's hash chains and store them into
122 * the appropriate elements of the given hash-table row array.
123 *
124 * @param rows
125 * The row array to be initialized
126 */
127 protected abstract void init(Object[] ht);
128
129 // @SuppressWarnings("unchecked")
130 private V toV(Object x) {
131 return (V)x;
132 }
133
134 public V get(Object k) {
135 int h = (k.hashCode() >> shift) & mask;
136 Object[] a = (Object[])ht[h];
137 if (a == null) return null;
138 for (;;) {
139 if (a[0].equals(k))
140 return toV(a[1]);
141 if (a.length < 3)
142 return null;
143 a = (Object[])a[2];
144 }
145 }
146
147 /**
148 * @throws UnsupportedOperationException
149 * If the given key is not part of this map's initial key set
150 */
151 public V put(String k, V v) {
152 int h = (k.hashCode() >> shift) & mask;
153 Object[] a = (Object[])ht[h];
154 if (a == null)
155 throw new UnsupportedOperationException(k);
156 for (;;) {
157 if (a[0].equals(k)) {
158 V ov = toV(a[1]);
159 a[1] = v;
160 return ov;
161 }
162 if (a.length < 3)
163 throw new UnsupportedOperationException(k);
164 a = (Object[])a[2];
165 }
166 }
167
168 public Set<String> keySet() {
169 return new AbstractSet<String> () {
170
171 public int size() {
172 return size;
173 }
174
175 public Iterator<String> iterator() {
176 return new Iterator<String>() {
177 private int i = -1;
178 Object[] a = null;
179 String cur = null;
180
181 private boolean findNext() {
182 if (a != null) {
183 if (a.length == 3) {
184 a = (Object[])a[2];
185 cur = (String)a[0];
186 return true;
187 }
188 i++;
189 a = null;
190 }
191 cur = null;
192 if (i >= rows)
193 return false;
194 if (i < 0 || ht[i] == null) {
195 do {
196 if (++i >= rows)
197 return false;
198 } while (ht[i] == null);
199 }
200 a = (Object[])ht[i];
201 cur = (String)a[0];
202 return true;
203 }
204
205 public boolean hasNext() {
206 if (cur != null)
207 return true;
208 return findNext();
209 }
210
211 public String next() {
212 if (cur == null) {
213 if (!findNext())
214 throw new NoSuchElementException();
215 }
216 String s = cur;
217 cur = null;
218 return s;
219 }
220
221 public void remove() {
222 throw new UnsupportedOperationException();
223 }
224
225 };
226 }
227 };
228 }
229
230 public Set<Map.Entry<String,V>> entrySet() {
231 return new AbstractSet<Map.Entry<String,V>> () {
232
233 public int size() {
234 return size;
235 }
236
237 public Iterator<Map.Entry<String,V>> iterator() {
238 return new Iterator<Map.Entry<String,V>>() {
239 final Iterator<String> i = keySet().iterator();
240
241 public boolean hasNext() {
242 return i.hasNext();
243 }
244
245 public Map.Entry<String,V> next() {
246 return new Map.Entry<String,V>() {
247 String k = i.next();
248 public String getKey() { return k; }
249 public V getValue() { return get(k); }
250 public int hashCode() {
251 V v = get(k);
252 return (k.hashCode()
253 + (v == null
254 ? 0
255 : v.hashCode()));
256 }
257 public boolean equals(Object ob) {
258 if (ob == this)
259 return true;
260 if (!(ob instanceof Map.Entry))
261 return false;
262 Map.Entry<String,V> that
263 = (Map.Entry<String,V>)ob;
264 return ((this.getKey() == null
265 ? that.getKey() == null
266 : this.getKey()
267 .equals(that.getKey()))
268 &&
269 (this.getValue() == null
270 ? that.getValue() == null
271 : this.getValue()
272 .equals(that.getValue())));
273 }
274 public V setValue(V v) {
275 throw new UnsupportedOperationException();
276 }
277 };
278 }
279
280 public void remove() {
281 throw new UnsupportedOperationException();
282 }
283
284 };
285 }
286 };
287 }
288
289}