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>
This commit is contained in:
Shawn O. Pearce 2011-03-18 09:07:25 -07:00
parent 48fb404a3f
commit 62fe7c7313
2 changed files with 64 additions and 0 deletions

View File

@ -281,6 +281,24 @@ public void testAddRemoveAdd() {
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);

View File

@ -141,6 +141,52 @@ public T set(int index, T element) {
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;