Index: src/org/apache/taglibs/standard/extra/collections/iterators/EmptyMapIterator.java =================================================================== --- src/org/apache/taglibs/standard/extra/collections/iterators/EmptyMapIterator.java (revision 581727) +++ src/org/apache/taglibs/standard/extra/collections/iterators/EmptyMapIterator.java (working copy) @@ -22,7 +22,7 @@ * Provides an implementation of an empty map iterator. * * @since Commons Collections 3.1 - * @version $Revision: 218351 $ $Date: 2004-10-20 17:58:23 -0700 (Wed, 20 Oct 2004) $ + * @version $Revision: 155406 $ $Date: 2005-02-26 12:55:26 +0000 (Sat, 26 Feb 2005) $ * * @author Stephen Colebourne */ Index: src/org/apache/taglibs/standard/extra/collections/iterators/EmptyIterator.java =================================================================== --- src/org/apache/taglibs/standard/extra/collections/iterators/EmptyIterator.java (revision 581727) +++ src/org/apache/taglibs/standard/extra/collections/iterators/EmptyIterator.java (working copy) @@ -27,7 +27,7 @@ * 2.1.1 and 3.1 due to issues with IteratorUtils. * * @since Commons Collections 2.1.1 and 3.1 - * @version $Revision: 218351 $ $Date: 2004-10-20 17:58:23 -0700 (Wed, 20 Oct 2004) $ + * @version $Revision: 155406 $ $Date: 2005-02-26 12:55:26 +0000 (Sat, 26 Feb 2005) $ * * @author Stephen Colebourne */ Index: src/org/apache/taglibs/standard/extra/collections/iterators/EmptyOrderedMapIterator.java =================================================================== --- src/org/apache/taglibs/standard/extra/collections/iterators/EmptyOrderedMapIterator.java (revision 581727) +++ src/org/apache/taglibs/standard/extra/collections/iterators/EmptyOrderedMapIterator.java (working copy) @@ -22,7 +22,7 @@ * Provides an implementation of an empty ordered map iterator. * * @since Commons Collections 3.1 - * @version $Revision: 218351 $ $Date: 2004-10-20 17:58:23 -0700 (Wed, 20 Oct 2004) $ + * @version $Revision: 155406 $ $Date: 2005-02-26 12:55:26 +0000 (Sat, 26 Feb 2005) $ * * @author Stephen Colebourne */ Index: src/org/apache/taglibs/standard/extra/collections/iterators/AbstractEmptyIterator.java =================================================================== --- src/org/apache/taglibs/standard/extra/collections/iterators/AbstractEmptyIterator.java (revision 581727) +++ src/org/apache/taglibs/standard/extra/collections/iterators/AbstractEmptyIterator.java (working copy) @@ -21,7 +21,7 @@ * Provides an implementation of an empty iterator. * * @since Commons Collections 3.1 - * @version $Revision: 218351 $ $Date: 2004-10-20 17:58:23 -0700 (Wed, 20 Oct 2004) $ + * @version $Revision: 155406 $ $Date: 2005-02-26 12:55:26 +0000 (Sat, 26 Feb 2005) $ * * @author Stephen Colebourne */ Index: src/org/apache/taglibs/standard/extra/collections/iterators/EmptyOrderedIterator.java =================================================================== --- src/org/apache/taglibs/standard/extra/collections/iterators/EmptyOrderedIterator.java (revision 581727) +++ src/org/apache/taglibs/standard/extra/collections/iterators/EmptyOrderedIterator.java (working copy) @@ -22,7 +22,7 @@ * Provides an implementation of an empty ordered iterator. * * @since Commons Collections 3.1 - * @version $Revision: 218351 $ $Date: 2004-10-20 17:58:23 -0700 (Wed, 20 Oct 2004) $ + * @version $Revision: 155406 $ $Date: 2005-02-26 12:55:26 +0000 (Sat, 26 Feb 2005) $ * * @author Stephen Colebourne */ Index: src/org/apache/taglibs/standard/extra/collections/map/LRUMap.java =================================================================== --- src/org/apache/taglibs/standard/extra/collections/map/LRUMap.java (revision 581727) +++ src/org/apache/taglibs/standard/extra/collections/map/LRUMap.java (working copy) @@ -1,5 +1,5 @@ /* - * Copyright 2001-2004 The Apache Software Foundation + * Copyright 2001-2005 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,9 +39,15 @@ *

* All the available iterators can be reset back to the start by casting to * ResettableIterator and calling reset(). - * + *

+ * Note that LRUMap is not synchronized and is not thread-safe. + * If you wish to use this map from multiple threads concurrently, you must use + * appropriate synchronization. The simplest approach is to wrap this map + * using {@link java.util.Collections#synchronizedMap(Map)}. This class may throw + * NullPointerException's when accessed by concurrent threads. + * * @since Commons Collections 3.0 (previously in main package v1.0) - * @version $Revision: 218351 $ $Date: 2004-10-20 17:58:23 -0700 (Wed, 20 Oct 2004) $ + * @version $Revision: 348299 $ $Date: 2005-11-22 23:51:45 +0000 (Tue, 22 Nov 2005) $ * * @author James Strachan * @author Morgan Delagrange @@ -53,7 +59,7 @@ extends AbstractLinkedMap implements BoundedMap, Serializable, Cloneable { /** Serialisation version */ - static final long serialVersionUID = -612114643488955218L; + private static final long serialVersionUID = -612114643488955218L; /** Default maximum size */ protected static final int DEFAULT_MAX_SIZE = 100; @@ -191,6 +197,9 @@ entry.before = header.before; header.before.after = entry; header.before = entry; + } else if (entry == header) { + throw new IllegalStateException("Can't move header to MRU" + + " (please report this to commons-dev@jakarta.apache.org)"); } } @@ -228,18 +237,32 @@ LinkEntry reuse = header.after; boolean removeLRUEntry = false; if (scanUntilRemovable) { - while (reuse != header) { + while (reuse != header && reuse != null) { if (removeLRU(reuse)) { removeLRUEntry = true; break; } reuse = reuse.after; } + if (reuse == null) { + throw new IllegalStateException( + "Entry.after=null, header.after" + header.after + " header.before" + header.before + + " key=" + key + " value=" + value + " size=" + size + " maxSize=" + maxSize + + " Please check that your keys are immutable, and that you have used synchronization properly." + + " If so, then please report this to commons-dev@jakarta.apache.org as a bug."); + } } else { removeLRUEntry = removeLRU(reuse); } if (removeLRUEntry) { + if (reuse == null) { + throw new IllegalStateException( + "reuse=null, header.after=" + header.after + " header.before" + header.before + + " key=" + key + " value=" + value + " size=" + size + " maxSize=" + maxSize + + " Please check that your keys are immutable, and that you have used synchronization properly." + + " If so, then please report this to commons-dev@jakarta.apache.org as a bug."); + } reuseMapping(reuse, hashIndex, hashCode, key, value); } else { super.addMapping(hashIndex, hashCode, key, value); @@ -264,19 +287,35 @@ // find the entry before the entry specified in the hash table // remember that the parameters (except the first) refer to the new entry, // not the old one - int removeIndex = hashIndex(entry.hashCode, data.length); - HashEntry loop = data[removeIndex]; - HashEntry previous = null; - while (loop != entry) { - previous = loop; - loop = loop.next; + try { + int removeIndex = hashIndex(entry.hashCode, data.length); + HashEntry[] tmp = data; // may protect against some sync issues + HashEntry loop = tmp[removeIndex]; + HashEntry previous = null; + while (loop != entry && loop != null) { + previous = loop; + loop = loop.next; + } + if (loop == null) { + throw new IllegalStateException( + "Entry.next=null, data[removeIndex]=" + data[removeIndex] + " previous=" + previous + + " key=" + key + " value=" + value + " size=" + size + " maxSize=" + maxSize + + " Please check that your keys are immutable, and that you have used synchronization properly." + + " If so, then please report this to commons-dev@jakarta.apache.org as a bug."); + } + + // reuse the entry + modCount++; + removeEntry(entry, removeIndex, previous); + reuseEntry(entry, hashIndex, hashCode, key, value); + addEntry(entry, hashIndex); + } catch (NullPointerException ex) { + throw new IllegalStateException( + "NPE, entry=" + entry + " entryIsHeader=" + (entry==header) + + " key=" + key + " value=" + value + " size=" + size + " maxSize=" + maxSize + + " Please check that your keys are immutable, and that you have used synchronization properly." + + " If so, then please report this to commons-dev@jakarta.apache.org as a bug."); } - - // reuse the entry - modCount++; - removeEntry(entry, removeIndex, previous); - reuseEntry(entry, hashIndex, hashCode, key, value); - addEntry(entry, hashIndex); } /** Index: src/org/apache/taglibs/standard/extra/collections/map/AbstractLinkedMap.java =================================================================== --- src/org/apache/taglibs/standard/extra/collections/map/AbstractLinkedMap.java (revision 581727) +++ src/org/apache/taglibs/standard/extra/collections/map/AbstractLinkedMap.java (working copy) @@ -57,7 +57,7 @@ * methods exposed. * * @since Commons Collections 3.0 - * @version $Revision: 218351 $ $Date: 2004-10-20 17:58:23 -0700 (Wed, 20 Oct 2004) $ + * @version $Revision: 158688 $ $Date: 2005-03-22 22:14:15 +0000 (Tue, 22 Mar 2005) $ * * @author java util LinkedHashMap * @author Stephen Colebourne @@ -120,9 +120,13 @@ /** * Initialise this subclass during construction. + *

+ * NOTE: As from v3.2 this method calls + * {@link #createEntry(HashEntry, int, Object, Object)} to create + * the map entry object. */ protected void init() { - header = new LinkEntry(null, -1, null, null); + header = (LinkEntry) createEntry(null, -1, null, null); header.before = header.after = header; } Index: src/org/apache/taglibs/standard/extra/collections/map/AbstractHashedMap.java =================================================================== --- src/org/apache/taglibs/standard/extra/collections/map/AbstractHashedMap.java (revision 581727) +++ src/org/apache/taglibs/standard/extra/collections/map/AbstractHashedMap.java (working copy) @@ -1,5 +1,5 @@ /* - * Copyright 2003-2004 The Apache Software Foundation + * Copyright 2003-2005 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,10 +52,11 @@ * This extends clause will be removed in v4.0. * * @since Commons Collections 3.0 - * @version $Revision: 218351 $ $Date: 2004-10-20 17:58:23 -0700 (Wed, 20 Oct 2004) $ + * @version $Revision: 171349 $ $Date: 2005-05-22 18:48:56 +0100 (Sun, 22 May 2005) $ * * @author java util HashMap * @author Stephen Colebourne + * @author Christian Siefkes */ public class AbstractHashedMap extends AbstractMap implements IterableMap { @@ -145,8 +146,8 @@ throw new IllegalArgumentException("Load factor must be greater than 0"); } this.loadFactor = loadFactor; + initialCapacity = calculateNewCapacity(initialCapacity); this.threshold = calculateThreshold(initialCapacity, loadFactor); - initialCapacity = calculateNewCapacity(initialCapacity); this.data = new HashEntry[initialCapacity]; init(); } @@ -1204,13 +1205,13 @@ int capacity = in.readInt(); int size = in.readInt(); init(); + threshold = calculateThreshold(capacity, loadFactor); data = new HashEntry[capacity]; for (int i = 0; i < size; i++) { Object key = in.readObject(); Object value = in.readObject(); put(key, value); } - threshold = calculateThreshold(data.length, loadFactor); } //-----------------------------------------------------------------------