I'm committing this one, that fixes a couple of "woops!" I did in the
last patch, as well as some other methods that were already broken
(read: not my fault :)

Now it should pass all the public domain tck166 tests, except for
subList.

Thanks,
Mario

2007-11-24  Mario Torre  <[EMAIL PROTECTED]>

        * java/util/concurrent/CopyOnWriteArrayList.java: 
        (addAll): fix implementation, now add elements in the correct position.
        (addAllAbsent): fixed typos (woops!).
        (remove(int)): fixed range in arraycopy that was causing for incorrect
        values to be inserted in the list. Refactored to give variables better
        names.
        (remove(Object)): refactored to give better names to variable.
        (listIterator): fix to set the starting index.
    (listIterator.previous): fix to decrement element position before
    returning the previous element in the iterator.  

-- 
Lima Software - http://www.limasoftware.net/
GNU Classpath Developer - http://www.classpath.org/
Fedora Ambassador - http://fedoraproject.org/wiki/MarioTorre
Jabber: [EMAIL PROTECTED]
pgp key: http://subkeys.pgp.net/ PGP Key ID: 80F240CF
Fingerprint: BA39 9666 94EC 8B73 27FA  FC7C 4086 63E3 80F2 40CF

Please, support open standards:
http://opendocumentfellowship.org/petition/
http://www.nosoftwarepatents.com/
### Eclipse Workspace Patch 1.0
#P classpath
Index: java/util/concurrent/CopyOnWriteArrayList.java
===================================================================
RCS file: /sources/classpath/classpath/java/util/concurrent/CopyOnWriteArrayList.java,v
retrieving revision 1.4
diff -u -r1.4 CopyOnWriteArrayList.java
--- java/util/concurrent/CopyOnWriteArrayList.java	23 Nov 2007 21:51:27 -0000	1.4
+++ java/util/concurrent/CopyOnWriteArrayList.java	24 Nov 2007 22:16:53 -0000
@@ -41,7 +41,9 @@
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.Serializable;
+
 import java.lang.reflect.Array;
+
 import java.util.AbstractList;
 import java.util.Collection;
 import java.util.Iterator;
@@ -395,15 +397,23 @@
    */
   public synchronized E remove(int index)
   {
-    E[] data = this.data;
-    E[] newData = (E[]) new Object[data.length - 1];
+    if (index < 0 || index >= this.size())
+      throw new IndexOutOfBoundsException("index = " +  index);
+    
+    E[] snapshot = this.data;
+    E[] newData = (E[]) new Object[snapshot.length - 1];
+    
+    E result = snapshot[index];
+    
     if (index > 0)
-      System.arraycopy(data, 0, newData, 0, index - 1);
-    System.arraycopy(data, index + 1, newData, index,
-                     data.length - index - 1);
-    E r = data[index];
+      System.arraycopy(snapshot, 0, newData, 0, index);
+    
+    System.arraycopy(snapshot, index + 1, newData, index,
+                     snapshot.length - index - 1);
+    
     this.data = newData;
-    return r;
+    
+    return result;
   }
 
   /**
@@ -417,32 +427,32 @@
    */
   public synchronized boolean remove(Object element)
   {
-    E[] data = this.data;
-    E[] newData = (E[]) new Object[data.length - 1];
+    E[] snapshot = this.data;
+    E[] newData = (E[]) new Object[snapshot.length - 1];
     
     // search the element to remove while filling the backup array
     // this way we can run this method in O(n)
     int elementIndex = -1;
-    for (int i = 0; i < this.data.length; i++)
+    for (int i = 0; i < snapshot.length; i++)
       {
-        if (equals(element, this.data[i]))
+        if (equals(element, snapshot[i]))
           {
             elementIndex = i;
             break;
           }
         
         if (i < newData.length)
-          newData[i] = this.data[i];
+          newData[i] = snapshot[i];
       }
     
     if (elementIndex < 0)
       return false;
-    
-    System.arraycopy(this.data, elementIndex + 1, newData, elementIndex,
-                     this.data.length - elementIndex - 1);
+     
+    System.arraycopy(snapshot, elementIndex + 1, newData, elementIndex,
+                     snapshot.length - elementIndex - 1);
     this.data = newData;
     
-    return false;
+    return true;
   }
   
   /**
@@ -575,18 +585,33 @@
    */
   public synchronized boolean addAll(int index, Collection< ? extends E> c)
   {
-    E[] data = this.data;
-    Iterator<? extends E> itr = c.iterator();
+    if (index < 0 || index > this.size())
+      throw new IndexOutOfBoundsException("index = " +  index);
+    
     int csize = c.size();
     if (csize == 0)
       return false;
-
+    
+    E[] data = this.data;
+    Iterator<? extends E> itr = c.iterator();
+    
     E[] newData = (E[]) new Object[data.length + csize];
-    System.arraycopy(data, 0, newData, 0, data.length);
-    int end = data.length;
+    
+    // avoid this call at all if we were asked to put the elements at the
+    // beginning of our storage
+    if (index != 0)
+      System.arraycopy(data, 0, newData, 0, index);
+    
+    int itemsLeft = index;
+    
     for (E value : c)
-      newData[end++] = value;
+      newData[index++] = value;
+    
+    // now copy the remaining elements
+    System.arraycopy(data, itemsLeft, newData, 0, data.length - itemsLeft);
+    
     this.data = newData;
+    
     return true;
   }
   
@@ -624,7 +649,7 @@
     size = 0;
     for (E val : c)
       {
-        if (this.contains(val))
+        if (!this.contains(val))
           storage[size++] = val;
       }
     
@@ -635,7 +660,9 @@
     E [] newData = (E[]) new Object[snapshot.length + size];
     
     System.arraycopy(snapshot, 0, newData, 0, snapshot.length);
-    System.arraycopy(storage, 0, newData, snapshot.length + 1, storage.length);
+    System.arraycopy(storage, 0, newData, snapshot.length, size);
+    
+    this.data = newData;
     
     return size;
   }
@@ -693,7 +720,7 @@
     return new ListIterator<E>()
     {
       E [] iteratorData = CopyOnWriteArrayList.this.data;
-      int currentElement = 0;
+      int currentElement = index;
       
       public void add(E o)
       {
@@ -730,7 +757,7 @@
         if (hasPrevious() == false)
           throw new java.util.NoSuchElementException();
         
-        return iteratorData[currentElement++];
+        return iteratorData[--currentElement];
       }
 
       public int previousIndex()

Reply via email to