001: //$Id: FastHashMap.java 3890 2004-06-03 16:31:32Z steveebersole $
002: /*
003: * ====================================================================
004: *
005: * The Apache Software License, Version 1.1
006: *
007: * Copyright (c) 1999-2002 The Apache Software Foundation. All rights
008: * reserved.
009: *
010: * Redistribution and use in source and binary forms, with or without
011: * modification, are permitted provided that the following conditions
012: * are met:
013: *
014: * 1. Redistributions of source code must retain the above copyright
015: * notice, this list of conditions and the following disclaimer.
016: *
017: * 2. Redistributions in binary form must reproduce the above copyright
018: * notice, this list of conditions and the following disclaimer in
019: * the documentation and/or other materials provided with the
020: * distribution.
021: *
022: * 3. The end-user documentation included with the redistribution, if
023: * any, must include the following acknowlegement:
024: * "This product includes software developed by the
025: * Apache Software Foundation (http://www.apache.org/)."
026: * Alternately, this acknowlegement may appear in the software itself,
027: * if and wherever such third-party acknowlegements normally appear.
028: *
029: * 4. The names "The Jakarta Project", "Commons", and "Apache Software
030: * Foundation" must not be used to endorse or promote products derived
031: * from this software without prior written permission. For written
032: * permission, please contact apache@apache.org.
033: *
034: * 5. Products derived from this software may not be called "Apache"
035: * nor may "Apache" appear in their names without prior written
036: * permission of the Apache Group.
037: *
038: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
039: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
040: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
041: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
042: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
043: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
044: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
045: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
046: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
047: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
048: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
049: * SUCH DAMAGE.
050: * ====================================================================
051: *
052: * This software consists of voluntary contributions made by many
053: * individuals on behalf of the Apache Software Foundation. For more
054: * information on the Apache Software Foundation, please see
055: * <http://www.apache.org/>.
056: *
057: */
058:
059: // This class was taken from Apache commons-collections -
060: // I made it final + removed the "slow" mode...
061: package org.hibernate.util;
062:
063: import java.io.Serializable;
064: import java.util.Collection;
065: import java.util.HashMap;
066: import java.util.Map;
067: import java.util.Set;
068:
069: /**
070: * <p>A customized implementation of <code>java.util.HashMap</code> designed
071: * to operate in a multithreaded environment where the large majority of
072: * method calls are read-only, instead of structural changes.
073: * Read calls are non-synchronized and write calls perform the
074: * following steps:</p>
075: * <ul>
076: * <li>Clone the existing collection
077: * <li>Perform the modification on the clone
078: * <li>Replace the existing collection with the (modified) clone
079: * </ul>
080: * <p><strong>NOTE</strong>: If you are creating and accessing a
081: * <code>HashMap</code> only within a single thread, you should use
082: * <code>java.util.HashMap</code> directly (with no synchronization), for
083: * maximum performance.</p>
084: *
085: */
086:
087: public final class FastHashMap implements Map, Serializable {
088:
089: // ----------------------------------------------------------- Constructors
090:
091: /**
092: * Construct a an empty map.
093: */
094: public FastHashMap() {
095:
096: super ();
097: this .map = new HashMap();
098:
099: }
100:
101: /**
102: * Construct an empty map with the specified capacity.
103: *
104: * @param capacity The initial capacity of the empty map
105: */
106: public FastHashMap(int capacity) {
107:
108: super ();
109: this .map = new HashMap(capacity);
110:
111: }
112:
113: /**
114: * Construct an empty map with the specified capacity and load factor.
115: *
116: * @param capacity The initial capacity of the empty map
117: * @param factor The load factor of the new map
118: */
119: public FastHashMap(int capacity, float factor) {
120:
121: super ();
122: this .map = new HashMap(capacity, factor);
123:
124: }
125:
126: /**
127: * Construct a new map with the same mappings as the specified map.
128: *
129: * @param map The map whose mappings are to be copied
130: */
131: public FastHashMap(Map map) {
132:
133: super ();
134: this .map = new HashMap(map);
135:
136: }
137:
138: // ----------------------------------------------------- Instance Variables
139:
140: /**
141: * The underlying map we are managing.
142: */
143: private HashMap map = null;
144:
145: // --------------------------------------------------------- Public Methods
146:
147: /**
148: * Remove all mappings from this map.
149: */
150: public void clear() {
151:
152: synchronized (this ) {
153: HashMap temp = (HashMap) map.clone();
154: temp.clear();
155: map = temp;
156: }
157:
158: }
159:
160: /**
161: * Return a shallow copy of this <code>FastHashMap</code> instance.
162: * The keys and values themselves are not copied.
163: */
164: public Object clone() {
165:
166: return new FastHashMap(map);
167:
168: }
169:
170: /**
171: * Return <code>true</code> if this map contains a mapping for the
172: * specified key.
173: *
174: * @param key Key to be searched for
175: */
176: public boolean containsKey(Object key) {
177:
178: return map.containsKey(key);
179:
180: }
181:
182: /**
183: * Return <code>true</code> if this map contains one or more keys mapping
184: * to the specified value.
185: *
186: * @param value Value to be searched for
187: */
188: public boolean containsValue(Object value) {
189:
190: return map.containsValue(value);
191:
192: }
193:
194: /**
195: * Return a collection view of the mappings contained in this map. Each
196: * element in the returned collection is a <code>Map.Entry</code>.
197: */
198: public Set entrySet() {
199:
200: return map.entrySet();
201:
202: }
203:
204: /**
205: * Compare the specified object with this list for equality. This
206: * implementation uses exactly the code that is used to define the
207: * list equals function in the documentation for the
208: * <code>Map.equals</code> method.
209: *
210: * @param o Object to be compared to this list
211: */
212: public boolean equals(Object o) {
213:
214: // Simple tests that require no synchronization
215: if (o == this )
216: return true;
217: else if (!(o instanceof Map))
218: return false;
219: Map mo = (Map) o;
220:
221: // Compare the two maps for equality
222:
223: if (mo.size() != map.size())
224: return false;
225: java.util.Iterator i = map.entrySet().iterator();
226: while (i.hasNext()) {
227: Map.Entry e = (Map.Entry) i.next();
228: Object key = e.getKey();
229: Object value = e.getValue();
230: if (value == null) {
231: if (!(mo.get(key) == null && mo.containsKey(key)))
232: return false;
233: } else {
234: if (!value.equals(mo.get(key)))
235: return false;
236: }
237: }
238: return true;
239:
240: }
241:
242: /**
243: * Return the value to which this map maps the specified key. Returns
244: * <code>null</code> if the map contains no mapping for this key, or if
245: * there is a mapping with a value of <code>null</code>. Use the
246: * <code>containsKey()</code> method to disambiguate these cases.
247: *
248: * @param key Key whose value is to be returned
249: */
250: public Object get(Object key) {
251:
252: return map.get(key);
253:
254: }
255:
256: /**
257: * Return the hash code value for this map. This implementation uses
258: * exactly the code that is used to define the list hash function in the
259: * documentation for the <code>Map.hashCode</code> method.
260: */
261: public int hashCode() {
262:
263: int h = 0;
264: java.util.Iterator i = map.entrySet().iterator();
265: while (i.hasNext())
266: h += i.next().hashCode();
267: return h;
268:
269: }
270:
271: /**
272: * Return <code>true</code> if this map contains no mappings.
273: */
274: public boolean isEmpty() {
275:
276: return map.isEmpty();
277:
278: }
279:
280: /**
281: * Return a set view of the keys contained in this map.
282: */
283: public Set keySet() {
284:
285: return map.keySet();
286:
287: }
288:
289: /**
290: * Associate the specified value with the specified key in this map.
291: * If the map previously contained a mapping for this key, the old
292: * value is replaced and returned.
293: *
294: * @param key The key with which the value is to be associated
295: * @param value The value to be associated with this key
296: */
297: public Object put(Object key, Object value) {
298:
299: synchronized (this ) {
300: HashMap temp = (HashMap) map.clone();
301: Object result = temp.put(key, value);
302: map = temp;
303: return (result);
304: }
305:
306: }
307:
308: /**
309: * Copy all of the mappings from the specified map to this one, replacing
310: * any mappings with the same keys.
311: *
312: * @param in Map whose mappings are to be copied
313: */
314: public void putAll(Map in) {
315:
316: synchronized (this ) {
317: HashMap temp = (HashMap) map.clone();
318: temp.putAll(in);
319: map = temp;
320: }
321:
322: }
323:
324: /**
325: * Remove any mapping for this key, and return any previously
326: * mapped value.
327: *
328: * @param key Key whose mapping is to be removed
329: */
330: public Object remove(Object key) {
331:
332: synchronized (this ) {
333: HashMap temp = (HashMap) map.clone();
334: Object result = temp.remove(key);
335: map = temp;
336: return (result);
337: }
338:
339: }
340:
341: /**
342: * Return the number of key-value mappings in this map.
343: */
344: public int size() {
345:
346: return map.size();
347:
348: }
349:
350: /**
351: * Return a collection view of the values contained in this map.
352: */
353: public Collection values() {
354:
355: return map.values();
356:
357: }
358:
359: public String toString() {
360: return map.toString();
361: }
362:
363: }
|