You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by ma...@tumbleweed.com on 2001/11/01 03:01:06 UTC
Re: Fast Collection Classes
The collections classes have been moved to Jakarta Commons, so you might
want to suggest your changes there (commons-dev@jakarta.apache.org).
Also, as James mentioned, attaching the changes in the form of a diff ('cvs
diff -u' is the preferred form) will help people understand what you are
proposing.
--
Martin Cooper
At 11:15 AM 10/31/01, Elie Levy wrote:
>I have done some changes to the FastHashMap class implementation.
>
>
>The modification that I have done only makes it easier to understand and to
>mantain the code for me. The same change can be applied to all the Fast
>Collection Classes, please tell me if you want me to do that.
>
>I would like to know what do you think about it.
>
>
>
>This is the first time that I send something to this list. I don't know if
>this is the way of doing it. Please let me know if this way is fine.
>
>Regards,
>
>
>
>
>
>eL.
>
>
>/*
> * $Header:
>/home/cvs/jakarta-struts/src/share/org/apache/struts/util/FastHashMap.java,v
>1.4.2.1 2001/05/20 21:06:43 craigmcc Exp $
> * $Revision: 1.4.2.1 $
> * $Date: 2001/05/20 21:06:43 $
> *
> * ====================================================================
> *
> * The Apache Software License, Version 1.1
> *
> * Copyright (c) 1999-2001 The Apache Software Foundation. All rights
> * reserved.
> *
> * Redistribution and use in source and binary forms, with or without
> * modification, are permitted provided that the following conditions
> * are met:
> *
> * 1. Redistributions of source code must retain the above copyright
> * notice, this list of conditions and the following disclaimer.
> *
> * 2. Redistributions in binary form must reproduce the above copyright
> * notice, this list of conditions and the following disclaimer in
> * the documentation and/or other materials provided with the
> * distribution.
> *
> * 3. The end-user documentation included with the redistribution, if
> * any, must include the following acknowlegement:
> * "This product includes software developed by the
> * Apache Software Foundation (http://www.apache.org/)."
> * Alternately, this acknowlegement may appear in the software itself,
> * if and wherever such third-party acknowlegements normally appear.
> *
> * 4. The names "The Jakarta Project", "Struts", and "Apache Software
> * Foundation" must not be used to endorse or promote products derived
> * from this software without prior written permission. For written
> * permission, please contact apache@apache.org.
> *
> * 5. Products derived from this software may not be called "Apache"
> * nor may "Apache" appear in their names without prior written
> * permission of the Apache Group.
> *
> * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
> * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
> * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
> * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
> * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
> * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
> * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> * SUCH DAMAGE.
> * ====================================================================
> *
> * This software consists of voluntary contributions made by many
> * individuals on behalf of the Apache Software Foundation. For more
> * information on the Apache Software Foundation, please see
> * <http://www.apache.org/>.
> *
> */
>
>
>package org.apache.struts.util;
>
>
>import java.io.Serializable;
>import java.util.Collection;
>import java.util.HashMap;
>import java.util.Iterator;
>import java.util.Map;
>import java.util.Map.Entry;
>import java.util.Set;
>
>
>/**
> * <p>A customized implementation of <code>java.util.HashMap</code> designed
> * to operate in a multithreaded environment where the large majority of
> * method calls are read-only, instead of structural changes. When operating
> * in "fast" mode, read calls are non-synchronized and write calls perform
>the
> * following steps:</p>
> * <ul>
> * <li>Clone the existing collection
> * <li>Perform the modification on the clone
> * <li>Replace the existing collection with the (modified) clone
> * </ul>
> * <p>When first created, objects of this class default to "slow" mode, where
> * all accesses of any type are synchronized but no cloning takes place.
>This
> * is appropriate for initially populating the collection, followed by a
>switch
> * to "fast" mode (by calling <code>setFast(true)</code>) after
>initialization
> * is complete.</p>
> *
> * <p><strong>NOTE</strong>: If you are creating and accessing a
> * <code>HashMap</code> only within a single thread, you should use
> * <code>java.util.HashMap</code> directly (with no synchronization), for
> * maximum performance.</p>
> *
> * @deprecated At some point after Struts 1.0 final, will be replaced by
> * an equivalent class in the Jakarta Commons Collections package.
> *
> * @author Craig R. McClanahan
> * @version $Revision: 1.4.2.1 $ $Date: 2001/05/20 21:06:43 $
> */
>
>public class FastHashMap extends HashMap {
>
>
> // -----------------------------------------------------------
>Constructors
>
>
> /**
> * Construct a an empty map.
> */
> public FastHashMap() {
>
> super();
> this.map = new HashMap();
>
> }
>
>
> /**
> * Construct an empty map with the specified capacity.
> *
> * @param capacity The initial capacity of the empty map
> */
> public FastHashMap(int capacity) {
>
> super();
> this.map = new HashMap(capacity);
>
> }
>
>
> /**
> * Construct an empty map with the specified capacity and load factor.
> *
> * @param capacity The initial capacity of the empty map
> * @param factor The load factor of the new map
> */
> public FastHashMap(int capacity, float factor) {
>
> super();
> this.map = new HashMap(capacity, factor);
>
> }
>
>
> /**
> * Construct a new map with the same mappings as the specified map.
> *
> * @param map The map whose mappings are to be copied
> */
> public FastHashMap(Map map) {
>
> super();
> this.map = new HashMap(map);
>
> }
>
>
> // ----------------------------------------------------- Instance
>Variables
>
>
> /**
> * The underlying map we are managing.
> */
> protected HashMap map = null;
>
>
> // -------------------------------------------------------------
>Properties
>
>
> /**
> * Are we operating in "fast" mode?
> */
> protected boolean fast = false;
>
> public boolean getFast() {
> return (this.fast);
> }
>
> public void setFast(boolean fast) {
> this.fast = fast;
> }
>
>
> // --------------------------------------------------------- Public
>Methods
>
>
> /**
> * Remove all mappings from this map.
> */
> public void clear() {
>
> if (fast) {
> synchronized (this) {
> HashMap temp = (HashMap) map.clone();
> temp.clear();
> map = temp;
> }
> } else {
> synchronized (map) {
> map.clear();
> }
> }
>
> }
>
>
> /**
> * Return a shallow copy of this <code>FastHashMap</code> instance.
> * The keys and values themselves are not copied.
> */
> public Object clone() {
>
> FastHashMap results = null;
> if (fast) {
> results = new FastHashMap(map);
> } else {
> synchronized (map) {
> results = new FastHashMap(map);
> }
> }
> results.setFast(getFast());
> return (results);
>
> }
>
>
> /**
> * Return <code>true</code> if this map contains a mapping for the
> * specified key.
> *
> * @param key Key to be searched for
> */
> public boolean containsKey(Object key) {
>
> if (fast) {
> return (map.containsKey(key));
> } else {
> synchronized (map) {
> return (map.containsKey(key));
> }
> }
>
> }
>
>
> /**
> * Return <code>true</code> if this map contains one or more keys mapping
> * to the specified value.
> *
> * @param value Value to be searched for
> */
> public boolean containsValue(Object value) {
>
> if (fast) {
> return (map.containsValue(value));
> } else {
> synchronized (map) {
> return (map.containsValue(value));
> }
> }
>
> }
>
>
> /**
> * Return a collection view of the mappings contained in this map. Each
> * element in the returned collection is a <code>Map.Entry</code>.
> */
> public Set entrySet() {
>
> if (fast) {
> return (map.entrySet());
> } else {
> synchronized (map) {
> return (map.entrySet());
> }
> }
>
> }
>
>
> /**
> * Compare the specified object with this list for equality. This
> * implementation uses exactly the code that is used to define the
> * list equals function in the documentation for the
> * <code>Map.equals</code> method.
> *
> * @param o Object to be compared to this list
> */
> public boolean equals(Object o) {
>
> // Simple tests that require no synchronization
> if (o == this)
> return (true);
> else if (!(o instanceof Map))
> return (false);
> Map mo = (Map) o;
>
> // Compare the two maps for equality
> return (fast)?stdEquals(o):synchEquals(o);
> }
>
> /**
> * Compare the specified object with this list for equality. This
> * is a helper method for the public implementation. It is used when not
>in
> * fast mode.
> *
> * @param o Object to be compared to this list
> */
> private boolean synchEquals(Object o) {
> synchronized (map) {
> return stdEquals(o);
> }
> }
>
> /**
> * Compare the specified object with this list for equality. This
> * is a helper method for the public implementation.
> *
> * @param o Object to be compared to this list
> */
> private boolean stdEquals(Object object) {
>
> if (mo.size() != map.size())
> return (false);
> java.util.Iterator i = map.entrySet().iterator();
> while (i.hasNext()) {
> Map.Entry e = (Map.Entry) i.next();
> Object key = e.getKey();
> Object value = e.getValue();
> if (value == null) {
> if (!(mo.get(key) == null && mo.containsKey(key)))
> return (false);
> } else {
> if (!value.equals(mo.get(key)))
> return (false);
> }
> }
> return (true);
>
> }
>
> /**
> * Return the value to which this map maps the specified key. Returns
> * <code>null</code> if the map contains no mapping for this key, or if
> * there is a mapping with a value of <code>null</code>. Use the
> * <code>containsKey()</code> method to disambiguate these cases.
> *
> * @param key Key whose value is to be returned
> */
> public Object get(Object key) {
>
> if (fast) {
> return (map.get(key));
> } else {
> synchronized (map) {
> return (map.get(key));
> }
> }
>
> }
>
>
> /**
> * Return the hash code value for this map. This implementation uses
> * exactly the code that is used to define the list hash function in the
> * documentation for the <code>Map.hashCode</code> method.
> */
> public int hashCode() {
> return (fast)?stdHashCode():synchHashCode();
> }
>
> /**
> * Returns the hash code value for htis map. This implementation is
> * a helper method for the public interface
> */
> private int synchHashCode() {
>
> synchronized (map) {
> return stdHashCode();
> }
>
> }
>
> /**
> * Return the hash code value for this map. This implementation
> * is a helper method for the public interface
> */
> private int stdHashCode() {
>
> int h = 0;
> java.util.Iterator i = map.entrySet().iterator();
> while (i.hasNext())
> h += i.next().hashCode();
> return (h);
>
> }
>
> /**
> * Return <code>true</code> if this map contains no mappings.
> */
> public boolean isEmpty() {
>
> if (fast) {
> return (map.isEmpty());
> } else {
> synchronized (map) {
> return (map.isEmpty());
> }
> }
>
> }
>
>
> /**
> * Return a set view of the keys contained in this map.
> */
> public Set keySet() {
>
> if (fast) {
> return (map.keySet());
> } else {
> synchronized (map) {
> return (map.keySet());
> }
> }
>
> }
>
>
> /**
> * Associate the specified value with the specified key in this map.
> * If the map previously contained a mapping for this key, the old
> * value is replaced and returned.
> *
> * @param key The key with which the value is to be associated
> * @param value The value to be associated with this key
> */
> public Object put(Object key, Object value) {
>
> if (fast) {
> synchronized (this) {
> HashMap temp = (HashMap) map.clone();
> Object result = temp.put(key, value);
> map = temp;
> return (result);
> }
> } else {
> synchronized (map) {
> return (map.put(key, value));
> }
> }
>
> }
>
>
> /**
> * Copy all of the mappings from the specified map to this one, replacing
> * any mappings with the same keys.
> *
> * @param in Map whose mappings are to be copied
> */
> public void putAll(Map in) {
>
> if (fast) {
> synchronized (this) {
> HashMap temp = (HashMap) map.clone();
> temp.putAll(in);
> map = temp;
> }
> } else {
> synchronized (map) {
> map.putAll(in);
> }
> }
>
> }
>
>
> /**
> * Remove any mapping for this key, and return any previously
> * mapped value.
> *
> * @param key Key whose mapping is to be removed
> */
> public Object remove(Object key) {
>
> if (fast) {
> synchronized (this) {
> HashMap temp = (HashMap) map.clone();
> Object result = temp.remove(key);
> map = temp;
> return (result);
> }
> } else {
> synchronized (map) {
> return (map.remove(key));
> }
> }
> }
>
>
> /**
> * Return the number of key-value mappings in this map.
> */
> public int size() {
>
> if (fast) {
> return (map.size());
> } else {
> synchronized (map) {
> return (map.size());
> }
> }
> }
>
>
> /**
> * Return a collection view of the values contained in this map.
> */
> public Collection values() {
>
> if (fast) {
> return (map.values());
> } else {
> synchronized (map) {
> return (map.values());
> }
> }
> }
>}
>
>
>--
>To unsubscribe, e-mail: <ma...@jakarta.apache.org>
>For additional commands, e-mail: <ma...@jakarta.apache.org>
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>