Browse Source

RTList #addAll - improved performance

Ranides Atterwim 10 years ago
parent
commit
5a7e3993be
1 changed files with 61 additions and 5 deletions
  1. 61 5
      assira/src/main/java/net/ranides/assira/collection/lists/RTList.java

+ 61 - 5
assira/src/main/java/net/ranides/assira/collection/lists/RTList.java

@@ -71,13 +71,40 @@ public class RTList<T> extends AbstractList<T> implements RandomAccess, Serializ
 
     @Override
     public void add(int index, T element) {
-        if(index > content.length) {
-            throw new IndexOutOfBoundsException(index + " out of bound " + content.length);
-        }
+        checkIndex(index);
         if(content == EMPTY) {
             content = new Object[]{ element };
             return;
         }
+        merge(index, element);
+    }
+
+    @Override
+    public boolean addAll(int index, Collection<? extends T> c) {
+        checkIndex(index);
+        if(c.isEmpty()) {
+            return false;
+        }
+        if(content == EMPTY) {
+            content = c.toArray();
+            return true;
+        }
+        return merge(index, c.toArray());
+    }
+    
+    public boolean addAll(int index, T[] array) {
+        checkIndex(index);
+        if(0 == array.length) {
+            return false;
+        }
+        if(content == EMPTY) {
+            content = ArrayUtils.copy(array);
+            return true;
+        }
+        return merge(index, array);
+    }
+    
+    private void merge(int index, T element) {
         Object[] buffer = new Object[content.length + 1];
         if(index > 0) {
             System.arraycopy(content, 0, buffer, 0, index);
@@ -89,11 +116,40 @@ public class RTList<T> extends AbstractList<T> implements RandomAccess, Serializ
         content = buffer;
     }
 
-    @Override
-    public T remove(int index) {
+    private boolean merge(int index, Object[] array) {
+        int n = array.length;
+        Object[] buffer = new Object[content.length + n];
+        
+        if(index > 0) {
+            System.arraycopy(content, 0, buffer, 0, index);
+        }
+        int tail = content.length - index;
+        if(tail > 0) {
+            System.arraycopy(content, index, buffer, index+n, tail);
+        }
+        System.arraycopy(array, 0, buffer, index, n);
+        content = buffer;
+        return true;
+    }
+    
+    private void checkIndex(int index) throws IndexOutOfBoundsException {
         if(index > content.length) {
             throw new IndexOutOfBoundsException(index + " out of bound " + content.length);
         }
+    }
+
+    @Override
+    public boolean addAll(Collection<? extends T> values) {
+        return addAll(content.length, values);
+    }
+    
+    public boolean addAll(T[] values) {
+        return addAll(content.length, values);
+    }
+
+    @Override
+    public T remove(int index) {
+        checkIndex(index);
         T prev = (T)content[index];
         if(content.length == 1) {
             content = EMPTY;