]> source.dussan.org Git - jgit.git/commitdiff
BlockList: Micro-optimize appending from another BlockList 74/2774/1
authorShawn O. Pearce <spearce@spearce.org>
Fri, 18 Mar 2011 16:07:25 +0000 (09:07 -0700)
committerShawn O. Pearce <spearce@spearce.org>
Fri, 18 Mar 2011 16:11:56 +0000 (09:11 -0700)
Simple variant of addAll() that knows how to copy large segments
quickly using System.arraycopy() rather than looping through with
an Iterator object.

Change-Id: Icb50a8f87fe9180ea28b6920f473bb9e70c300f1
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
org.eclipse.jgit.test/tst/org/eclipse/jgit/util/BlockListTest.java
org.eclipse.jgit/src/org/eclipse/jgit/util/BlockList.java

index 7151af156a085f67ce09710336223c822ebd7b90..8b042bd67c07e23867e007b239ddb0ba60a185f0 100644 (file)
@@ -281,6 +281,24 @@ public class BlockListTest {
                assertEquals(Integer.valueOf(1), list.get(list.size() - 1));
        }
 
+       @Test
+       public void testAddAllFromOtherList() {
+               BlockList<Integer> src = new BlockList<Integer>(4);
+               int cnt = BlockList.BLOCK_SIZE * 2;
+
+               for (int i = 0; i < cnt; i++)
+                       src.add(Integer.valueOf(42 + i));
+               src.add(Integer.valueOf(1));
+
+               BlockList<Integer> dst = new BlockList<Integer>(4);
+               dst.add(Integer.valueOf(255));
+               dst.addAll(src);
+               assertEquals(cnt + 2, dst.size());
+               for (int i = 0; i < cnt; i++)
+                       assertEquals(Integer.valueOf(42 + i), dst.get(i + 1));
+               assertEquals(Integer.valueOf(1), dst.get(dst.size() - 1));
+       }
+
        @Test
        public void testFastIterator() {
                BlockList<Integer> list = new BlockList<Integer>(4);
index ac29771d807dbe61c9193dafdb2e3aeb05df8526..50715acb2cf9fa48ec340540190a9940d9195eee 100644 (file)
@@ -141,6 +141,52 @@ public class BlockList<T> extends AbstractList<T> {
                return old;
        }
 
+       /**
+        * Quickly append all elements of another BlockList.
+        *
+        * @param src
+        *            the list to copy elements from.
+        */
+       public void addAll(BlockList<T> src) {
+               if (src.size == 0)
+                       return;
+
+               int srcDirIdx = 0;
+               for (; srcDirIdx < src.tailDirIdx; srcDirIdx++)
+                       addAll(src.directory[srcDirIdx], 0, BLOCK_SIZE);
+               if (src.tailBlkIdx != 0)
+                       addAll(src.tailBlock, 0, src.tailBlkIdx);
+       }
+
+       /**
+        * Quickly append all elements from an array.
+        *
+        * @param src
+        *            the source array.
+        * @param srcIdx
+        *            first index to copy.
+        * @param srcCnt
+        *            number of elements to copy.
+        */
+       public void addAll(T[] src, int srcIdx, int srcCnt) {
+               while (0 < srcCnt) {
+                       int i = tailBlkIdx;
+                       int n = Math.min(srcCnt, BLOCK_SIZE - i);
+                       if (n == 0) {
+                               // Our tail is full, expand by one.
+                               add(src[srcIdx++]);
+                               srcCnt--;
+                               continue;
+                       }
+
+                       System.arraycopy(src, srcIdx, tailBlock, i, n);
+                       tailBlkIdx += n;
+                       size += n;
+                       srcIdx += n;
+                       srcCnt -= n;
+               }
+       }
+
        @Override
        public boolean add(T element) {
                int i = tailBlkIdx;