Browse Source

BlockList: Micro-optimize appending from another BlockList

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>
stable-0.12
Shawn O. Pearce 14 years ago
parent
commit
62fe7c7313
  1. 18
      org.eclipse.jgit.test/tst/org/eclipse/jgit/util/BlockListTest.java
  2. 46
      org.eclipse.jgit/src/org/eclipse/jgit/util/BlockList.java

18
org.eclipse.jgit.test/tst/org/eclipse/jgit/util/BlockListTest.java

@ -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);

46
org.eclipse.jgit/src/org/eclipse/jgit/util/BlockList.java

@ -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;

Loading…
Cancel
Save