Improve performance of clear()

Update licence
Javadoc and formatting


git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/collections/trunk@130958 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Stephen Colebourne 2003-01-18 14:03:28 +00:00
parent a790423ef1
commit c07fc446f6
1 changed files with 319 additions and 339 deletions

View File

@ -1,13 +1,10 @@
/*
* $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/FastTreeMap.java,v 1.10 2002/10/12 22:15:18 scolebourne Exp $
* $Revision: 1.10 $
* $Date: 2002/10/12 22:15:18 $
*
* $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/FastTreeMap.java,v 1.11 2003/01/18 14:03:28 scolebourne Exp $
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2002 The Apache Software Foundation. All rights
* Copyright (c) 1999-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -23,11 +20,11 @@
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* any, must include the following acknowledgment:
* "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.
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
@ -36,7 +33,7 @@
*
* 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.
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@ -58,11 +55,8 @@
* <http://www.apache.org/>.
*
*/
package org.apache.commons.collections;
import java.util.Collection;
import java.util.Comparator;
import java.util.ConcurrentModificationException;
@ -72,7 +66,6 @@ import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
/**
* <p>A customized implementation of <code>java.util.TreeMap</code> designed
* to operate in a multithreaded environment where the large majority of
@ -108,86 +101,71 @@ import java.util.TreeMap;
* Double-Checked Locking Idiom Is Broken Declartion</A>.</P>
*
* @since 1.0
* @version $Revision: 1.11 $ $Date: 2003/01/18 14:03:28 $
*
* @author Craig R. McClanahan
* @version $Revision: 1.10 $ $Date: 2002/10/12 22:15:18 $
* @author Stephen Colebourne
*/
public class FastTreeMap extends TreeMap {
// ----------------------------------------------------------- Constructors
/**
* Construct a an empty map.
*/
public FastTreeMap() {
super();
this.map = new TreeMap();
}
/**
* Construct an empty map with the specified comparator.
*
* @param comparator The comparator to use for ordering tree elements
*/
public FastTreeMap(Comparator comparator) {
super();
this.map = new TreeMap(comparator);
}
/**
* Construct a new map with the same mappings as the specified map,
* sorted according to the keys's natural order
*
* @param map The map whose mappings are to be copied
*/
public FastTreeMap(Map map) {
super();
this.map = new TreeMap(map);
}
/**
* Construct a new map with the same mappings as the specified map,
* sorted according to the same ordering
*
* @param map The map whose mappings are to be copied
*/
public FastTreeMap(SortedMap map) {
super();
this.map = new TreeMap(map);
}
// ----------------------------------------------------- Instance Variables
/**
* The underlying map we are managing.
*/
protected TreeMap map = null;
// ------------------------------------------------------------- Properties
/**
* Are we operating in "fast" mode?
*/
protected boolean fast = false;
// Constructors
// ----------------------------------------------------------------------
/**
* Construct a an empty map.
*/
public FastTreeMap() {
super();
this.map = new TreeMap();
}
/**
* Construct an empty map with the specified comparator.
*
* @param comparator the comparator to use for ordering tree elements
*/
public FastTreeMap(Comparator comparator) {
super();
this.map = new TreeMap(comparator);
}
/**
* Construct a new map with the same mappings as the specified map,
* sorted according to the keys's natural order
*
* @param map the map whose mappings are to be copied
*/
public FastTreeMap(Map map) {
super();
this.map = new TreeMap(map);
}
/**
* Construct a new map with the same mappings as the specified map,
* sorted according to the same ordering
*
* @param map the map whose mappings are to be copied
*/
public FastTreeMap(SortedMap map) {
super();
this.map = new TreeMap(map);
}
// Property access
// ----------------------------------------------------------------------
/**
* Returns true if this map is operating in fast mode.
*
@ -207,187 +185,10 @@ public class FastTreeMap extends TreeMap {
}
// --------------------------------------------------------- Public Methods
/**
* Remove all mappings from this map.
*/
public void clear() {
if (fast) {
synchronized (this) {
TreeMap temp = (TreeMap) map.clone();
temp.clear();
map = temp;
}
} else {
synchronized (map) {
map.clear();
}
}
}
/**
* Return a shallow copy of this <code>FastTreeMap</code> instance.
* The keys and values themselves are not copied.
*/
public Object clone() {
FastTreeMap results = null;
if (fast) {
results = new FastTreeMap(map);
} else {
synchronized (map) {
results = new FastTreeMap(map);
}
}
results.setFast(getFast());
return (results);
}
/**
* Return the comparator used to order this map, or <code>null</code>
* if this map uses its keys' natural order.
*/
public Comparator comparator() {
if (fast) {
return (map.comparator());
} else {
synchronized (map) {
return (map.comparator());
}
}
}
/**
* 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() {
return new 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
if (fast) {
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);
} else {
synchronized (map) {
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 first (lowest) key currently in this sorted map.
*/
public Object firstKey() {
if (fast) {
return (map.firstKey());
} else {
synchronized (map) {
return (map.firstKey());
}
}
}
// Map access
// ----------------------------------------------------------------------
// These methods can forward straight to the wrapped Map in 'fast' mode.
// (because they are query methods)
/**
* Return the value to which this map maps the specified key. Returns
@ -395,10 +196,10 @@ public class FastTreeMap extends TreeMap {
* 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
* @param key the key whose value is to be returned
* @return the value mapped to that key, or null
*/
public Object get(Object key) {
if (fast) {
return (map.get(key));
} else {
@ -406,60 +207,29 @@ public class FastTreeMap extends TreeMap {
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.
* Return the number of key-value mappings in this map.
*
* @return the current size of the map
*/
public int hashCode() {
public int size() {
if (fast) {
int h = 0;
java.util.Iterator i = map.entrySet().iterator();
while (i.hasNext())
h += i.next().hashCode();
return (h);
return (map.size());
} else {
synchronized (map) {
int h = 0;
java.util.Iterator i = map.entrySet().iterator();
while (i.hasNext())
h += i.next().hashCode();
return (h);
return (map.size());
}
}
}
/**
* Return a view of the portion of this map whose keys are strictly
* less than the specified key.
*
* @param key Key higher than any in the returned map
*/
public SortedMap headMap(Object key) {
if (fast) {
return (map.headMap(key));
} else {
synchronized (map) {
return (map.headMap(key));
}
}
}
/**
* Test if this list has no elements.
* Return <code>true</code> if this map contains no mappings.
*
* @return is the map currently empty
*/
public boolean isEmpty() {
if (fast) {
return (map.isEmpty());
} else {
@ -467,23 +237,79 @@ public class FastTreeMap extends TreeMap {
return (map.isEmpty());
}
}
}
/**
* Return a set view of the keys contained in this map.
* Return <code>true</code> if this map contains a mapping for the
* specified key.
*
* @param key the key to be searched for
* @return true if the map contains the key
*/
public Set keySet() {
return new KeySet();
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 the value to be searched for
* @return true if the map contains the value
*/
public boolean containsValue(Object value) {
if (fast) {
return (map.containsValue(value));
} else {
synchronized (map) {
return (map.containsValue(value));
}
}
}
/**
* Return the comparator used to order this map, or <code>null</code>
* if this map uses its keys' natural order.
*
* @return the comparator used to order the map, or null if natural order
*/
public Comparator comparator() {
if (fast) {
return (map.comparator());
} else {
synchronized (map) {
return (map.comparator());
}
}
}
/**
* Return the first (lowest) key currently in this sorted map.
*
* @return the first key in the map
*/
public Object firstKey() {
if (fast) {
return (map.firstKey());
} else {
synchronized (map) {
return (map.firstKey());
}
}
}
/**
* Return the last (highest) key currently in this sorted map.
*
* @return the last key in the map
*/
public Object lastKey() {
if (fast) {
return (map.lastKey());
} else {
@ -491,20 +317,25 @@ public class FastTreeMap extends TreeMap {
return (map.lastKey());
}
}
}
// Map modification
// ----------------------------------------------------------------------
// These methods perform special behaviour in 'fast' mode.
// The map is cloned, updated and then assigned back.
// See the comments at the top as to why this won't always work.
/**
* 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
* @param key the key with which the value is to be associated
* @param value the value to be associated with this key
* @return the value previously mapped to the key, or null
*/
public Object put(Object key, Object value) {
if (fast) {
synchronized (this) {
TreeMap temp = (TreeMap) map.clone();
@ -517,18 +348,15 @@ public class FastTreeMap extends TreeMap {
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
* @param in the map whose mappings are to be copied
*/
public void putAll(Map in) {
if (fast) {
synchronized (this) {
TreeMap temp = (TreeMap) map.clone();
@ -540,18 +368,16 @@ public class FastTreeMap extends TreeMap {
map.putAll(in);
}
}
}
/**
* Remove any mapping for this key, and return any previously
* mapped value.
*
* @param key Key whose mapping is to be removed
* @param key the key whose mapping is to be removed
* @return the value removed, or null
*/
public Object remove(Object key) {
if (fast) {
synchronized (this) {
TreeMap temp = (TreeMap) map.clone();
@ -564,25 +390,157 @@ public class FastTreeMap extends TreeMap {
return (map.remove(key));
}
}
}
/**
* Return the number of key-value mappings in this map.
* Remove all mappings from this map.
*/
public int size() {
public void clear() {
if (fast) {
return (map.size());
synchronized (this) {
map = new TreeMap();
}
} else {
synchronized (map) {
return (map.size());
map.clear();
}
}
}
// Basic object methods
// ----------------------------------------------------------------------
/**
* 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 the object to be compared to this list
* @return true if the two maps are equal
*/
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
if (fast) {
if (mo.size() != map.size()) {
return (false);
}
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);
} else {
synchronized (map) {
if (mo.size() != map.size()) {
return (false);
}
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 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.
*
* @return a suitable integer hashcode
*/
public int hashCode() {
if (fast) {
int h = 0;
Iterator i = map.entrySet().iterator();
while (i.hasNext()) {
h += i.next().hashCode();
}
return (h);
} else {
synchronized (map) {
int h = 0;
Iterator i = map.entrySet().iterator();
while (i.hasNext()) {
h += i.next().hashCode();
}
return (h);
}
}
}
/**
* Return a shallow copy of this <code>FastTreeMap</code> instance.
* The keys and values themselves are not copied.
*
* @return a clone of this map
*/
public Object clone() {
FastTreeMap results = null;
if (fast) {
results = new FastTreeMap(map);
} else {
synchronized (map) {
results = new FastTreeMap(map);
}
}
results.setFast(getFast());
return (results);
}
// Sub map views
// ----------------------------------------------------------------------
/**
* Return a view of the portion of this map whose keys are strictly
* less than the specified key.
*
* @param key Key higher than any in the returned map
* @return a head map
*/
public SortedMap headMap(Object key) {
if (fast) {
return (map.headMap(key));
} else {
synchronized (map) {
return (map.headMap(key));
}
}
}
/**
* Return a view of the portion of this map whose keys are in the
@ -590,9 +548,9 @@ public class FastTreeMap extends TreeMap {
*
* @param fromKey Lower limit of keys for the returned map
* @param toKey Upper limit of keys for the returned map
* @return a sub map
*/
public SortedMap subMap(Object fromKey, Object toKey) {
if (fast) {
return (map.subMap(fromKey, toKey));
} else {
@ -600,18 +558,16 @@ public class FastTreeMap extends TreeMap {
return (map.subMap(fromKey, toKey));
}
}
}
/**
* Return a view of the portion of this map whose keys are greater than
* or equal to the specified key.
*
* @param key Key less than or equal to any in the returned map
* @return a tail map
*/
public SortedMap tailMap(Object key) {
if (fast) {
return (map.tailMap(key));
} else {
@ -619,10 +575,27 @@ public class FastTreeMap extends TreeMap {
return (map.tailMap(key));
}
}
}
// Map views
// ----------------------------------------------------------------------
/**
* 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() {
return new EntrySet();
}
/**
* Return a set view of the keys contained in this map.
*/
public Set keySet() {
return new KeySet();
}
/**
* Return a collection view of the values contained in this map.
*/
@ -630,8 +603,12 @@ public class FastTreeMap extends TreeMap {
return new Values();
}
// Map view inner classes
// ----------------------------------------------------------------------
/**
* Abstract collection implementation shared by ketSet(), values() and entrySet().
*/
private abstract class CollectionView implements Collection {
public CollectionView() {
@ -644,9 +621,7 @@ public class FastTreeMap extends TreeMap {
public void clear() {
if (fast) {
synchronized (FastTreeMap.this) {
TreeMap temp = (TreeMap) map.clone();
get(temp).clear();
map = temp;
map = new TreeMap();
}
} else {
synchronized (map) {
@ -842,7 +817,9 @@ public class FastTreeMap extends TreeMap {
}
}
/**
* Set implementation over the keys of the FastTreeMap
*/
private class KeySet extends CollectionView implements Set {
protected Collection get(Map map) {
@ -855,7 +832,9 @@ public class FastTreeMap extends TreeMap {
}
/**
* Collection implementation over the values of the FastTreeMap
*/
private class Values extends CollectionView {
protected Collection get(Map map) {
@ -867,7 +846,9 @@ public class FastTreeMap extends TreeMap {
}
}
/**
* Set implementation over the entries of the FastTreeMap
*/
private class EntrySet extends CollectionView implements Set {
protected Collection get(Map map) {
@ -881,5 +862,4 @@ public class FastTreeMap extends TreeMap {
}
}