KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > logicalcobwebs > proxool > util > FastArrayList


1 /*
2  * This software is released under a licence similar to the Apache Software Licence.
3  * See org.logicalcobwebs.proxool.package.html for details.
4  * The latest version is available at http://proxool.sourceforge.net
5  *
6  * THIS CLASS WAS COPIED FROM THE JAKARTA COMMONS COLLECTIONS
7  * VERSION 2.1. WE ARE GRATEFUL FOR THEIR CONTRIBUTION. We decided
8  * not to introduce the whole library as a dependency at this stage but might decide
9  * to at a later date.
10  */

11
12 /*
13  * $Header: /cvsroot/proxool/proxool/src/java/org/logicalcobwebs/proxool/util/FastArrayList.java,v 1.4 2003/03/10 23:43:18 billhorsman Exp $
14  * $Revision: 1.4 $
15  * $Date: 2003/03/10 23:43:18 $
16  *
17  * ====================================================================
18  *
19  * The Apache Software License, Version 1.1
20  *
21  * Copyright (c) 1999-2002 The Apache Software Foundation. All rights
22  * reserved.
23  *
24  * Redistribution and use in source and binary forms, with or without
25  * modification, are permitted provided that the following conditions
26  * are met:
27  *
28  * 1. Redistributions of source code must retain the above copyright
29  * notice, this list of conditions and the following disclaimer.
30  *
31  * 2. Redistributions in binary form must reproduce the above copyright
32  * notice, this list of conditions and the following disclaimer in
33  * the documentation and/or other materials provided with the
34  * distribution.
35  *
36  * 3. The end-user documentation included with the redistribution, if
37  * any, must include the following acknowlegement:
38  * "This product includes software developed by the
39  * Apache Software Foundation (http://www.apache.org/)."
40  * Alternately, this acknowlegement may appear in the software itself,
41  * if and wherever such third-party acknowlegements normally appear.
42  *
43  * 4. The names "The Jakarta Project", "Commons", and "Apache Software
44  * Foundation" must not be used to endorse or promote products derived
45  * from this software without prior written permission. For written
46  * permission, please contact apache@apache.org.
47  *
48  * 5. Products derived from this software may not be called "Apache"
49  * nor may "Apache" appear in their names without prior written
50  * permission of the Apache Group.
51  *
52  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
53  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
54  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
55  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
56  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
57  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
58  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
59  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
60  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
61  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
62  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63  * SUCH DAMAGE.
64  * ====================================================================
65  *
66  * This software consists of voluntary contributions made by many
67  * individuals on behalf of the Apache Software Foundation. For more
68  * information on the Apache Software Foundation, please see
69  * <http://www.apache.org/>.
70  *
71  */

72
73
74 package org.logicalcobwebs.proxool.util;
75
76
77 import java.util.ArrayList JavaDoc;
78 import java.util.Collection JavaDoc;
79 import java.util.ConcurrentModificationException JavaDoc;
80 import java.util.Iterator JavaDoc;
81 import java.util.List JavaDoc;
82 import java.util.ListIterator JavaDoc;
83
84
85 /**
86  * <p>A customized implementation of <code>java.util.ArrayList</code> designed
87  * to operate in a multithreaded environment where the large majority of
88  * method calls are read-only, instead of structural changes. When operating
89  * in "fast" mode, read calls are non-synchronized and write calls perform the
90  * following steps:</p>
91  * <ul>
92  * <li>Clone the existing collection
93  * <li>Perform the modification on the clone
94  * <li>Replace the existing collection with the (modified) clone
95  * </ul>
96  * <p>When first created, objects of this class default to "slow" mode, where
97  * all accesses of any type are synchronized but no cloning takes place. This
98  * is appropriate for initially populating the collection, followed by a switch
99  * to "fast" mode (by calling <code>setFast(true)</code>) after initialization
100  * is complete.</p>
101  *
102  * <p><strong>NOTE</strong>: If you are creating and accessing an
103  * <code>ArrayList</code> only within a single thread, you should use
104  * <code>java.util.ArrayList</code> directly (with no synchronization), for
105  * maximum performance.</p>
106  *
107  * <P><strong>NOTE</strong>: <I>This class is not cross-platform.
108  * Using it may cause unexpected failures on some architectures.</I>
109  * It suffers from the same problems as the double-checked locking idiom.
110  * In particular, the instruction that clones the internal collection and the
111  * instruction that sets the internal reference to the clone can be executed
112  * or perceived out-of-order. This means that any read operation might fail
113  * unexpectedly, as it may be reading the state of the internal collection
114  * before the internal collection is fully formed.
115  * For more information on the double-checked locking idiom, see the
116  * <A Href="http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html">
117  * Double-Checked Locking Idiom Is Broken Declartion</A>.</P>
118  *
119  * @since Proxool 0.6
120  * @author Craig R. McClanahan
121  * @author $Author: billhorsman $ (current maintainer)
122  * @version $Revision: 1.4 $ $Date: 2003/03/10 23:43:18 $
123  */

124
125 public class FastArrayList extends ArrayList JavaDoc {
126
127
128     // ----------------------------------------------------------- Constructors
129

130
131     /**
132      * Construct a an empty list.
133      */

134     public FastArrayList() {
135
136         super();
137         this.list = new ArrayList JavaDoc();
138
139     }
140
141
142     /**
143      * Construct an empty list with the specified capacity.
144      *
145      * @param capacity The initial capacity of the empty list
146      */

147     public FastArrayList(int capacity) {
148
149         super();
150         this.list = new ArrayList JavaDoc(capacity);
151
152     }
153
154
155     /**
156      * Construct a list containing the elements of the specified collection,
157      * in the order they are returned by the collection's iterator.
158      *
159      * @param collection The collection whose elements initialize the contents
160      * of this list
161      */

162     public FastArrayList(Collection JavaDoc collection) {
163
164         super();
165         this.list = new ArrayList JavaDoc(collection);
166
167     }
168
169
170     // ----------------------------------------------------- Instance Variables
171

172
173     /**
174      * The underlying list we are managing.
175      */

176     private ArrayList JavaDoc list = null;
177
178
179     // ------------------------------------------------------------- Properties
180

181
182     /**
183      * Are we operating in "fast" mode?
184      */

185     private boolean fast = false;
186
187
188     /**
189      * Returns true if this list is operating in fast mode.
190      *
191      * @return true if this list is operating in fast mode
192      */

193     public boolean getFast() {
194         return (this.fast);
195     }
196
197     /**
198      * Sets whether this list will operate in fast mode.
199      *
200      * @param fast true if the list should operate in fast mode
201      */

202     public void setFast(boolean fast) {
203         this.fast = fast;
204     }
205
206
207     // --------------------------------------------------------- Public Methods
208

209
210     /**
211      * Appends the specified element to the end of this list.
212      *
213      * @param element The element to be appended
214      */

215     public boolean add(Object JavaDoc element) {
216
217         if (fast) {
218             synchronized (this) {
219                 ArrayList JavaDoc temp = (ArrayList JavaDoc) list.clone();
220                 boolean result = temp.add(element);
221                 list = temp;
222                 return (result);
223             }
224         } else {
225             synchronized (list) {
226                 return (list.add(element));
227             }
228         }
229
230     }
231
232
233     /**
234      * Insert the specified element at the specified position in this list,
235      * and shift all remaining elements up one position.
236      *
237      * @param index Index at which to insert this element
238      * @param element The element to be inserted
239      *
240      * @exception java.lang.IndexOutOfBoundsException if the index is out of range
241      */

242     public void add(int index, Object JavaDoc element) {
243
244         if (fast) {
245             synchronized (this) {
246                 ArrayList JavaDoc temp = (ArrayList JavaDoc) list.clone();
247                 temp.add(index, element);
248                 list = temp;
249             }
250         } else {
251             synchronized (list) {
252                 list.add(index, element);
253             }
254         }
255
256     }
257
258
259     /**
260      * Append all of the elements in the specified Collection to the end
261      * of this list, in the order that they are returned by the specified
262      * Collection's Iterator.
263      *
264      * @param collection The collection to be appended
265      */

266     public boolean addAll(Collection JavaDoc collection) {
267
268         if (fast) {
269             synchronized (this) {
270                 ArrayList JavaDoc temp = (ArrayList JavaDoc) list.clone();
271                 boolean result = temp.addAll(collection);
272                 list = temp;
273                 return (result);
274             }
275         } else {
276             synchronized (list) {
277                 return (list.addAll(collection));
278             }
279         }
280
281     }
282
283
284     /**
285      * Insert all of the elements in the specified Collection at the specified
286      * position in this list, and shift any previous elements upwards as
287      * needed.
288      *
289      * @param index Index at which insertion takes place
290      * @param collection The collection to be added
291      *
292      * @exception java.lang.IndexOutOfBoundsException if the index is out of range
293      */

294     public boolean addAll(int index, Collection JavaDoc collection) {
295
296         if (fast) {
297             synchronized (this) {
298                 ArrayList JavaDoc temp = (ArrayList JavaDoc) list.clone();
299                 boolean result = temp.addAll(index, collection);
300                 list = temp;
301                 return (result);
302             }
303         } else {
304             synchronized (list) {
305                 return (list.addAll(index, collection));
306             }
307         }
308
309     }
310
311
312     /**
313      * Remove all of the elements from this list. The list will be empty
314      * after this call returns.
315      *
316      * @exception java.lang.UnsupportedOperationException if <code>clear()</code>
317      * is not supported by this list
318      */

319     public void clear() {
320
321         if (fast) {
322             synchronized (this) {
323                 ArrayList JavaDoc temp = (ArrayList JavaDoc) list.clone();
324                 temp.clear();
325                 list = temp;
326             }
327         } else {
328             synchronized (list) {
329                 list.clear();
330             }
331         }
332
333     }
334
335
336     /**
337      * Return a shallow copy of this <code>FastArrayList</code> instance.
338      * The elements themselves are not copied.
339      */

340     public Object JavaDoc clone() {
341
342         FastArrayList results = null;
343         if (fast) {
344             results = new FastArrayList(list);
345         } else {
346             synchronized (list) {
347                 results = new FastArrayList(list);
348             }
349         }
350         results.setFast(getFast());
351         return (results);
352
353     }
354
355
356     /**
357      * Return <code>true</code> if this list contains the specified element.
358      *
359      * @param element The element to test for
360      */

361     public boolean contains(Object JavaDoc element) {
362
363         if (fast) {
364             return (list.contains(element));
365         } else {
366             synchronized (list) {
367                 return (list.contains(element));
368             }
369         }
370
371     }
372
373
374     /**
375      * Return <code>true</code> if this list contains all of the elements
376      * in the specified Collection.
377      *
378      * @param collection Collection whose elements are to be checked
379      */

380     public boolean containsAll(Collection JavaDoc collection) {
381
382         if (fast) {
383             return (list.containsAll(collection));
384         } else {
385             synchronized (list) {
386                 return (list.containsAll(collection));
387             }
388         }
389
390     }
391
392
393     /**
394      * Increase the capacity of this <code>ArrayList</code> instance, if
395      * necessary, to ensure that it can hold at least the number of elements
396      * specified by the minimum capacity argument.
397      *
398      * @param capacity The new minimum capacity
399      */

400     public void ensureCapacity(int capacity) {
401
402         if (fast) {
403             synchronized (this) {
404                 ArrayList JavaDoc temp = (ArrayList JavaDoc) list.clone();
405                 temp.ensureCapacity(capacity);
406                 list = temp;
407             }
408         } else {
409             synchronized (list) {
410                 list.ensureCapacity(capacity);
411             }
412         }
413
414     }
415
416
417     /**
418      * Compare the specified object with this list for equality. This
419      * implementation uses exactly the code that is used to define the
420      * list equals function in the documentation for the
421      * <code>List.equals</code> method.
422      *
423      * @param o Object to be compared to this list
424      */

425     public boolean equals(Object JavaDoc o) {
426
427         // Simple tests that require no synchronization
428
if (o == this) {
429             return (true);
430         } else if (!(o instanceof List JavaDoc)) {
431             return (false);
432         }
433         List JavaDoc lo = (List JavaDoc) o;
434
435         // Compare the sets of elements for equality
436
if (fast) {
437             ListIterator JavaDoc li1 = list.listIterator();
438             ListIterator JavaDoc li2 = lo.listIterator();
439             while (li1.hasNext() && li2.hasNext()) {
440                 Object JavaDoc o1 = li1.next();
441                 Object JavaDoc o2 = li2.next();
442                 if (!(o1 == null ? o2 == null : o1.equals(o2))) {
443                     return (false);
444                 }
445             }
446             return (!(li1.hasNext() || li2.hasNext()));
447         } else {
448             synchronized (list) {
449                 ListIterator JavaDoc li1 = list.listIterator();
450                 ListIterator JavaDoc li2 = lo.listIterator();
451                 while (li1.hasNext() && li2.hasNext()) {
452                     Object JavaDoc o1 = li1.next();
453                     Object JavaDoc o2 = li2.next();
454                     if (!(o1 == null ? o2 == null : o1.equals(o2))) {
455                         return (false);
456                     }
457                 }
458                 return (!(li1.hasNext() || li2.hasNext()));
459             }
460         }
461
462     }
463
464
465     /**
466      * Return the element at the specified position in the list.
467      *
468      * @param index The index of the element to return
469      *
470      * @exception java.lang.IndexOutOfBoundsException if the index is out of range
471      */

472     public Object JavaDoc get(int index) {
473
474         if (fast) {
475             return (list.get(index));
476         } else {
477             synchronized (list) {
478                 return (list.get(index));
479             }
480         }
481
482     }
483
484
485     /**
486      * Return the hash code value for this list. This implementation uses
487      * exactly the code that is used to define the list hash function in the
488      * documentation for the <code>List.hashCode</code> method.
489      */

490     public int hashCode() {
491
492         if (fast) {
493             int hashCode = 1;
494             java.util.Iterator JavaDoc i = list.iterator();
495             while (i.hasNext()) {
496                 Object JavaDoc o = i.next();
497                 hashCode = 31 * hashCode + (o == null ? 0 : o.hashCode());
498             }
499             return (hashCode);
500         } else {
501             synchronized (list) {
502                 int hashCode = 1;
503                 java.util.Iterator JavaDoc i = list.iterator();
504                 while (i.hasNext()) {
505                     Object JavaDoc o = i.next();
506                     hashCode = 31 * hashCode + (o == null ? 0 : o.hashCode());
507                 }
508                 return (hashCode);
509             }
510         }
511
512     }
513
514
515     /**
516      * Search for the first occurrence of the given argument, testing
517      * for equality using the <code>equals()</code> method, and return
518      * the corresponding index, or -1 if the object is not found.
519      *
520      * @param element The element to search for
521      */

522     public int indexOf(Object JavaDoc element) {
523
524         if (fast) {
525             return (list.indexOf(element));
526         } else {
527             synchronized (list) {
528                 return (list.indexOf(element));
529             }
530         }
531
532     }
533
534
535     /**
536      * Test if this list has no elements.
537      */

538     public boolean isEmpty() {
539
540         if (fast) {
541             return (list.isEmpty());
542         } else {
543             synchronized (list) {
544                 return (list.isEmpty());
545             }
546         }
547
548     }
549
550
551     /**
552      * Return an iterator over the elements in this list in proper sequence.
553      * <br><br>
554      * <strong>IMPLEMENTATION NOTE</strong> - If the list is operating in fast
555      * mode, an Iterator is returned, and a structural modification to the
556      * list is made, then the Iterator will continue over the previous contents
557      * of the list (at the time that the Iterator was created), rather than
558      * failing due to concurrent modifications.
559      */

560     public Iterator JavaDoc iterator() {
561         if (fast) {
562             return new ListIter(0);
563         } else {
564             return list.iterator();
565         }
566     }
567
568
569     /**
570      * Search for the last occurrence of the given argument, testing
571      * for equality using the <code>equals()</code> method, and return
572      * the corresponding index, or -1 if the object is not found.
573      *
574      * @param element The element to search for
575      */

576     public int lastIndexOf(Object JavaDoc element) {
577
578         if (fast) {
579             return (list.lastIndexOf(element));
580         } else {
581             synchronized (list) {
582                 return (list.lastIndexOf(element));
583             }
584         }
585
586     }
587
588
589     /**
590      * Return an iterator of the elements of this list, in proper sequence.
591      * See the implementation note on <code>iterator()</code>.
592      */

593     public ListIterator JavaDoc listIterator() {
594         if (fast) {
595             return new ListIter(0);
596         } else {
597             return list.listIterator();
598         }
599     }
600
601
602     /**
603      * Return an iterator of the elements of this list, in proper sequence,
604      * starting at the specified position.
605      * See the implementation note on <code>iterator()</code>.
606      *
607      * @param index The starting position of the iterator to return
608      *
609      * @exception java.lang.IndexOutOfBoundsException if the index is out of range
610      */

611     public ListIterator JavaDoc listIterator(int index) {
612         if (fast) {
613             return new ListIter(index);
614         } else {
615             return list.listIterator(index);
616         }
617     }
618
619
620     /**
621      * Remove the element at the specified position in the list, and shift
622      * any subsequent elements down one position.
623      *
624      * @param index Index of the element to be removed
625      *
626      * @exception java.lang.IndexOutOfBoundsException if the index is out of range
627      */

628     public Object JavaDoc remove(int index) {
629
630         if (fast) {
631             synchronized (this) {
632                 ArrayList JavaDoc temp = (ArrayList JavaDoc) list.clone();
633                 Object JavaDoc result = temp.remove(index);
634                 list = temp;
635                 return (result);
636             }
637         } else {
638             synchronized (list) {
639                 return (list.remove(index));
640             }
641         }
642
643     }
644
645
646     /**
647      * Remove the first occurrence of the specified element from the list,
648      * and shift any subsequent elements down one position.
649      *
650      * @param element Element to be removed
651      */

652     public boolean remove(Object JavaDoc element) {
653
654         if (fast) {
655             synchronized (this) {
656                 ArrayList JavaDoc temp = (ArrayList JavaDoc) list.clone();
657                 boolean result = temp.remove(element);
658                 list = temp;
659                 return (result);
660             }
661         } else {
662             synchronized (list) {
663                 return (list.remove(element));
664             }
665         }
666
667     }
668
669
670     /**
671      * Remove from this collection all of its elements that are contained
672      * in the specified collection.
673      *
674      * @param collection Collection containing elements to be removed
675      *
676      * @exception java.lang.UnsupportedOperationException if this optional operation
677      * is not supported by this list
678      */

679     public boolean removeAll(Collection JavaDoc collection) {
680
681         if (fast) {
682             synchronized (this) {
683                 ArrayList JavaDoc temp = (ArrayList JavaDoc) list.clone();
684                 boolean result = temp.removeAll(collection);
685                 list = temp;
686                 return (result);
687             }
688         } else {
689             synchronized (list) {
690                 return (list.removeAll(collection));
691             }
692         }
693
694     }
695
696
697     /**
698      * Remove from this collection all of its elements except those that are
699      * contained in the specified collection.
700      *
701      * @param collection Collection containing elements to be retained
702      *
703      * @exception java.lang.UnsupportedOperationException if this optional operation
704      * is not supported by this list
705      */

706     public boolean retainAll(Collection JavaDoc collection) {
707
708         if (fast) {
709             synchronized (this) {
710                 ArrayList JavaDoc temp = (ArrayList JavaDoc) list.clone();
711                 boolean result = temp.retainAll(collection);
712                 list = temp;
713                 return (result);
714             }
715         } else {
716             synchronized (list) {
717                 return (list.retainAll(collection));
718             }
719         }
720
721     }
722
723
724     /**
725      * Replace the element at the specified position in this list with
726      * the specified element. Returns the previous object at that position.
727      * <br><br>
728      * <strong>IMPLEMENTATION NOTE</strong> - This operation is specifically
729      * documented to not be a structural change, so it is safe to be performed
730      * without cloning.
731      *
732      * @param index Index of the element to replace
733      * @param element The new element to be stored
734      *
735      * @exception java.lang.IndexOutOfBoundsException if the index is out of range
736      */

737     public Object JavaDoc set(int index, Object JavaDoc element) {
738
739         if (fast) {
740             return (list.set(index, element));
741         } else {
742             synchronized (list) {
743                 return (list.set(index, element));
744             }
745         }
746
747     }
748
749
750     /**
751      * Return the number of elements in this list.
752      */

753     public int size() {
754
755         if (fast) {
756             return (list.size());
757         } else {
758             synchronized (list) {
759                 return (list.size());
760             }
761         }
762
763     }
764
765
766     /**
767      * Return a view of the portion of this list between fromIndex
768      * (inclusive) and toIndex (exclusive). The returned list is backed
769      * by this list, so non-structural changes in the returned list are
770      * reflected in this list. The returned list supports
771      * all of the optional list operations supported by this list.
772      *
773      * @param fromIndex The starting index of the sublist view
774      * @param toIndex The index after the end of the sublist view
775      *
776      * @exception java.lang.IndexOutOfBoundsException if an index is out of range
777      */

778     public List JavaDoc subList(int fromIndex, int toIndex) {
779         if (fast) {
780             return new SubList(fromIndex, toIndex);
781         } else {
782             return list.subList(fromIndex, toIndex);
783         }
784     }
785
786
787     /**
788      * Return an array containing all of the elements in this list in the
789      * correct order.
790      */

791     public Object JavaDoc[] toArray() {
792
793         if (fast) {
794             return (list.toArray());
795         } else {
796             synchronized (list) {
797                 return (list.toArray());
798             }
799         }
800
801     }
802
803
804     /**
805      * Return an array containing all of the elements in this list in the
806      * correct order. The runtime type of the returned array is that of
807      * the specified array. If the list fits in the specified array, it is
808      * returned therein. Otherwise, a new array is allocated with the
809      * runtime type of the specified array, and the size of this list.
810      *
811      * @param array Array defining the element type of the returned list
812      *
813      * @exception java.lang.ArrayStoreException if the runtime type of <code>array</code>
814      * is not a supertype of the runtime type of every element in this list
815      */

816     public Object JavaDoc[] toArray(Object JavaDoc array[]) {
817
818         if (fast) {
819             return (list.toArray(array));
820         } else {
821             synchronized (list) {
822                 return (list.toArray(array));
823             }
824         }
825
826     }
827
828
829     /**
830      * Return a String representation of this object.
831      */

832     public String JavaDoc toString() {
833
834         StringBuffer JavaDoc sb = new StringBuffer JavaDoc("FastArrayList[");
835         sb.append(list.toString());
836         sb.append("]");
837         return (sb.toString());
838
839     }
840
841
842     /**
843      * Trim the capacity of this <code>ArrayList</code> instance to be the
844      * list's current size. An application can use this operation to minimize
845      * the storage of an <code>ArrayList</code> instance.
846      */

847     public void trimToSize() {
848
849         if (fast) {
850             synchronized (this) {
851                 ArrayList JavaDoc temp = (ArrayList JavaDoc) list.clone();
852                 temp.trimToSize();
853                 list = temp;
854             }
855         } else {
856             synchronized (list) {
857                 list.trimToSize();
858             }
859         }
860
861     }
862
863
864     private class SubList implements List JavaDoc {
865
866         private int first;
867         private int last;
868         private List JavaDoc expected;
869
870
871         public SubList(int first, int last) {
872             this.first = first;
873             this.last = last;
874             this.expected = list;
875         }
876
877         private List JavaDoc get(List JavaDoc l) {
878             if (list != expected) {
879                 throw new ConcurrentModificationException JavaDoc();
880             }
881             return l.subList(first, last);
882         }
883
884         public void clear() {
885             if (fast) {
886                 synchronized (FastArrayList.this) {
887                     ArrayList JavaDoc temp = (ArrayList JavaDoc) list.clone();
888                     get(temp).clear();
889                     last = first;
890                     list = temp;
891                     expected = temp;
892                 }
893             } else {
894                 synchronized (list) {
895                     get(expected).clear();
896                 }
897             }
898         }
899
900         public boolean remove(Object JavaDoc o) {
901             if (fast) {
902                 synchronized (FastArrayList.this) {
903                     ArrayList JavaDoc temp = (ArrayList JavaDoc) list.clone();
904                     boolean r = get(temp).remove(o);
905                     if (r) {
906                         last--;
907                     }
908                     list = temp;
909                     expected = temp;
910                     return r;
911                 }
912             } else {
913                 synchronized (list) {
914                     return get(expected).remove(o);
915                 }
916             }
917         }
918
919         public boolean removeAll(Collection JavaDoc o) {
920             if (fast) {
921                 synchronized (FastArrayList.this) {
922                     ArrayList JavaDoc temp = (ArrayList JavaDoc) list.clone();
923                     List JavaDoc sub = get(temp);
924                     boolean r = sub.removeAll(o);
925                     if (r) {
926                         last = first + sub.size();
927                     }
928                     list = temp;
929                     expected = temp;
930                     return r;
931                 }
932             } else {
933                 synchronized (list) {
934                     return get(expected).removeAll(o);
935                 }
936             }
937         }
938
939         public boolean retainAll(Collection JavaDoc o) {
940             if (fast) {
941                 synchronized (FastArrayList.this) {
942                     ArrayList JavaDoc temp = (ArrayList JavaDoc) list.clone();
943                     List JavaDoc sub = get(temp);
944                     boolean r = sub.retainAll(o);
945                     if (r) {
946                         last = first + sub.size();
947                     }
948                     list = temp;
949                     expected = temp;
950                     return r;
951                 }
952             } else {
953                 synchronized (list) {
954                     return get(expected).retainAll(o);
955                 }
956             }
957         }
958
959         public int size() {
960             if (fast) {
961                 return get(expected).size();
962             } else {
963                 synchronized (list) {
964                     return get(expected).size();
965                 }
966             }
967         }
968
969
970         public boolean isEmpty() {
971             if (fast) {
972                 return get(expected).isEmpty();
973             } else {
974                 synchronized (list) {
975                     return get(expected).isEmpty();
976                 }
977             }
978         }
979
980         public boolean contains(Object JavaDoc o) {
981             if (fast) {
982                 return get(expected).contains(o);
983             } else {
984                 synchronized (list) {
985                     return get(expected).contains(o);
986                 }
987             }
988         }
989
990         public boolean containsAll(Collection JavaDoc o) {
991             if (fast) {
992                 return get(expected).containsAll(o);
993             } else {
994                 synchronized (list) {
995                     return get(expected).containsAll(o);
996                 }
997             }
998         }
999
1000        public Object JavaDoc[] toArray(Object JavaDoc[] o) {
1001            if (fast) {
1002                return get(expected).toArray(o);
1003            } else {
1004                synchronized (list) {
1005                    return get(expected).toArray(o);
1006                }
1007            }
1008        }
1009
1010        public Object JavaDoc[] toArray() {
1011            if (fast) {
1012                return get(expected).toArray();
1013            } else {
1014                synchronized (list) {
1015                    return get(expected).toArray();
1016                }
1017            }
1018        }
1019
1020
1021        public boolean equals(Object JavaDoc o) {
1022            if (o == this) {
1023                return true;
1024            }
1025            if (fast) {
1026                return get(expected).equals(o);
1027            } else {
1028                synchronized (list) {
1029                    return get(expected).equals(o);
1030                }
1031            }
1032        }
1033
1034        public int hashCode() {
1035            if (fast) {
1036                return get(expected).hashCode();
1037            } else {
1038                synchronized (list) {
1039                    return get(expected).hashCode();
1040                }
1041            }
1042        }
1043
1044        public boolean add(Object JavaDoc o) {
1045            if (fast) {
1046                synchronized (FastArrayList.this) {
1047                    ArrayList JavaDoc temp = (ArrayList JavaDoc) list.clone();
1048                    boolean r = get(temp).add(o);
1049                    if (r) {
1050                        last++;
1051                    }
1052                    list = temp;
1053                    expected = temp;
1054                    return r;
1055                }
1056            } else {
1057                synchronized (list) {
1058                    return get(expected).add(o);
1059                }
1060            }
1061        }
1062
1063        public boolean addAll(Collection JavaDoc o) {
1064            if (fast) {
1065                synchronized (FastArrayList.this) {
1066                    ArrayList JavaDoc temp = (ArrayList JavaDoc) list.clone();
1067                    boolean r = get(temp).addAll(o);
1068                    if (r) {
1069                        last += o.size();
1070                    }
1071                    list = temp;
1072                    expected = temp;
1073                    return r;
1074                }
1075            } else {
1076                synchronized (list) {
1077                    return get(expected).addAll(o);
1078                }
1079            }
1080        }
1081
1082        public void add(int i, Object JavaDoc o) {
1083            if (fast) {
1084                synchronized (FastArrayList.this) {
1085                    ArrayList JavaDoc temp = (ArrayList JavaDoc) list.clone();
1086                    get(temp).add(i, o);
1087                    last++;
1088                    list = temp;
1089                    expected = temp;
1090                }
1091            } else {
1092                synchronized (list) {
1093                    get(expected).add(i, o);
1094                }
1095            }
1096        }
1097
1098        public boolean addAll(int i, Collection JavaDoc o) {
1099            if (fast) {
1100                synchronized (FastArrayList.this) {
1101                    ArrayList JavaDoc temp = (ArrayList JavaDoc) list.clone();
1102                    boolean r = get(temp).addAll(i, o);
1103                    list = temp;
1104                    if (r) {
1105                        last += o.size();
1106                    }
1107                    expected = temp;
1108                    return r;
1109                }
1110            } else {
1111                synchronized (list) {
1112                    return get(expected).addAll(i, o);
1113                }
1114            }
1115        }
1116
1117        public Object JavaDoc remove(int i) {
1118            if (fast) {
1119                synchronized (FastArrayList.this) {
1120                    ArrayList JavaDoc temp = (ArrayList JavaDoc) list.clone();
1121                    Object JavaDoc o = get(temp).remove(i);
1122                    last--;
1123                    list = temp;
1124                    expected = temp;
1125                    return o;
1126                }
1127            } else {
1128                synchronized (list) {
1129                    return get(expected).remove(i);
1130                }
1131            }
1132        }
1133
1134        public Object JavaDoc set(int i, Object JavaDoc a) {
1135            if (fast) {
1136                synchronized (FastArrayList.this) {
1137                    ArrayList JavaDoc temp = (ArrayList JavaDoc) list.clone();
1138                    Object JavaDoc o = get(temp).set(i, a);
1139                    list = temp;
1140                    expected = temp;
1141                    return o;
1142                }
1143            } else {
1144                synchronized (list) {
1145                    return get(expected).set(i, a);
1146                }
1147            }
1148        }
1149
1150
1151        public Iterator JavaDoc iterator() {
1152            return new SubListIter(0);
1153        }
1154
1155        public ListIterator JavaDoc listIterator() {
1156            return new SubListIter(0);
1157        }
1158
1159        public ListIterator JavaDoc listIterator(int i) {
1160            return new SubListIter(i);
1161        }
1162
1163
1164        public Object JavaDoc get(int i) {
1165            if (fast) {
1166                return get(expected).get(i);
1167            } else {
1168                synchronized (list) {
1169                    return get(expected).get(i);
1170                }
1171            }
1172        }
1173
1174        public int indexOf(Object JavaDoc o) {
1175            if (fast) {
1176                return get(expected).indexOf(o);
1177            } else {
1178                synchronized (list) {
1179                    return get(expected).indexOf(o);
1180                }
1181            }
1182        }
1183
1184
1185        public int lastIndexOf(Object JavaDoc o) {
1186            if (fast) {
1187                return get(expected).lastIndexOf(o);
1188            } else {
1189                synchronized (list) {
1190                    return get(expected).lastIndexOf(o);
1191                }
1192            }
1193        }
1194
1195
1196        public List JavaDoc subList(int f, int l) {
1197            if (list != expected) {
1198                throw new ConcurrentModificationException JavaDoc();
1199            }
1200            return new SubList(first + f, f + l);
1201        }
1202
1203
1204        private class SubListIter implements ListIterator JavaDoc {
1205
1206            private List JavaDoc expected;
1207            private ListIterator JavaDoc iter;
1208            private int lastReturnedIndex = -1;
1209
1210
1211            public SubListIter(int i) {
1212                this.expected = list;
1213                this.iter = SubList.this.get(expected).listIterator(i);
1214            }
1215
1216            private void checkMod() {
1217                if (list != expected) {
1218                    throw new ConcurrentModificationException JavaDoc();
1219                }
1220            }
1221
1222            List JavaDoc get() {
1223                return SubList.this.get(expected);
1224            }
1225
1226            public boolean hasNext() {
1227                checkMod();
1228                return iter.hasNext();
1229            }
1230
1231            public Object JavaDoc next() {
1232                checkMod();
1233                lastReturnedIndex = iter.nextIndex();
1234                return iter.next();
1235            }
1236
1237            public boolean hasPrevious() {
1238                checkMod();
1239                return iter.hasPrevious();
1240            }
1241
1242            public Object JavaDoc previous() {
1243                checkMod();
1244                lastReturnedIndex = iter.previousIndex();
1245                return iter.previous();
1246            }
1247
1248            public int previousIndex() {
1249                checkMod();
1250                return iter.previousIndex();
1251            }
1252
1253            public int nextIndex() {
1254                checkMod();
1255                return iter.nextIndex();
1256            }
1257
1258            public void remove() {
1259                checkMod();
1260                if (lastReturnedIndex < 0) {
1261                    throw new IllegalStateException JavaDoc();
1262                }
1263                get().remove(lastReturnedIndex);
1264                last--;
1265                expected = list;
1266                iter = get().listIterator(previousIndex());
1267                lastReturnedIndex = -1;
1268            }
1269
1270            public void set(Object JavaDoc o) {
1271                checkMod();
1272                if (lastReturnedIndex < 0) {
1273                    throw new IllegalStateException JavaDoc();
1274                }
1275                get().set(lastReturnedIndex, o);
1276                expected = list;
1277                iter = get().listIterator(previousIndex() + 1);
1278            }
1279
1280            public void add(Object JavaDoc o) {
1281                checkMod();
1282                int i = nextIndex();
1283                get().add(i, o);
1284                last++;
1285                iter = get().listIterator(i + 1);
1286                lastReturnedIndex = 1;
1287            }
1288
1289        }
1290
1291
1292    }
1293
1294
1295    private class ListIter implements ListIterator JavaDoc {
1296
1297        private List JavaDoc expected;
1298        private ListIterator JavaDoc iter;
1299        private int lastReturnedIndex = -1;
1300
1301
1302        public ListIter(int i) {
1303            this.expected = list;
1304            this.iter = get().listIterator(i);
1305        }
1306
1307        private void checkMod() {
1308            if (list != expected) {
1309                throw new ConcurrentModificationException JavaDoc();
1310            }
1311        }
1312
1313        List JavaDoc get() {
1314            return expected;
1315        }
1316
1317        public boolean hasNext() {
1318            checkMod();
1319            return iter.hasNext();
1320        }
1321
1322        public Object JavaDoc next() {
1323            checkMod();
1324            lastReturnedIndex = iter.nextIndex();
1325            return iter.next();
1326        }
1327
1328        public boolean hasPrevious() {
1329            checkMod();
1330            return iter.hasPrevious();
1331        }
1332
1333        public Object JavaDoc previous() {
1334            checkMod();
1335            lastReturnedIndex = iter.previousIndex();
1336            return iter.previous();
1337        }
1338
1339        public int previousIndex() {
1340            checkMod();
1341            return iter.previousIndex();
1342        }
1343
1344        public int nextIndex() {
1345            checkMod();
1346            return iter.nextIndex();
1347        }
1348
1349        public void remove() {
1350            checkMod();
1351            if (lastReturnedIndex < 0) {
1352                throw new IllegalStateException JavaDoc();
1353            }
1354            get().remove(lastReturnedIndex);
1355            expected = list;
1356            iter = get().listIterator(previousIndex());
1357            lastReturnedIndex = -1;
1358        }
1359
1360        public void set(Object JavaDoc o) {
1361            checkMod();
1362            if (lastReturnedIndex < 0) {
1363                throw new IllegalStateException JavaDoc();
1364            }
1365            get().set(lastReturnedIndex, o);
1366            expected = list;
1367            iter = get().listIterator(previousIndex() + 1);
1368        }
1369
1370        public void add(Object JavaDoc o) {
1371            checkMod();
1372            int i = nextIndex();
1373            get().add(i, o);
1374            iter = get().listIterator(i + 1);
1375            lastReturnedIndex = 1;
1376        }
1377
1378    }
1379}
1380
1381/*
1382 Revision history:
1383 $Log: FastArrayList.java,v $
1384 Revision 1.4 2003/03/10 23:43:18 billhorsman
1385 reapplied checkstyle that i'd inadvertently let
1386 IntelliJ change...
1387
1388 Revision 1.3 2003/03/10 15:27:00 billhorsman
1389 refactoringn of concurrency stuff (and some import
1390 optimisation)
1391
1392 Revision 1.2 2003/03/03 11:12:02 billhorsman
1393 fixed licence
1394
1395 Revision 1.1 2003/02/07 01:40:34 chr32
1396 Ok. Now *really* moving in from main proxool package.
1397
1398 Revision 1.4 2003/02/07 01:34:17 chr32
1399 Made class public.
1400
1401 Revision 1.3 2003/02/07 01:33:31 chr32
1402 Moved in from main proxool package.
1403
1404 Revision 1.2 2003/01/15 14:51:14 billhorsman
1405 checkstyle
1406
1407 */

1408
Popular Tags