Add MessageList.array() / Rewrite MessageList.add(T[], int, int)

- MessageList.array() should give better performance + concise code
- MessageList.add(T[], int, int) iterated over the source array 3 times at worst case. This commit reduces that to 1 time.
This commit is contained in:
Trustin Lee 2013-06-28 20:47:19 +09:00
parent 0dcf352f4c
commit 7cf88a1a3c

View File

@ -119,7 +119,7 @@ public final class MessageList<T> implements Iterable<T> {
public boolean releaseAll() { public boolean releaseAll() {
boolean releasedAll = true; boolean releasedAll = true;
int size = this.size; int size = this.size;
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i ++) {
releasedAll &= ReferenceCountUtil.release(elements[i]); releasedAll &= ReferenceCountUtil.release(elements[i]);
} }
return releasedAll; return releasedAll;
@ -132,7 +132,7 @@ public final class MessageList<T> implements Iterable<T> {
public boolean releaseAll(int decrement) { public boolean releaseAll(int decrement) {
boolean releasedAll = true; boolean releasedAll = true;
int size = this.size; int size = this.size;
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i ++) {
releasedAll &= ReferenceCountUtil.release(elements[i], decrement); releasedAll &= ReferenceCountUtil.release(elements[i], decrement);
} }
return releasedAll; return releasedAll;
@ -226,7 +226,7 @@ public final class MessageList<T> implements Iterable<T> {
if (value == null) { if (value == null) {
throw new NullPointerException("value"); throw new NullPointerException("value");
} }
modifications++; modifications ++;
int oldSize = size; int oldSize = size;
int newSize = oldSize + 1; int newSize = oldSize + 1;
ensureCapacity(newSize); ensureCapacity(newSize);
@ -253,23 +253,53 @@ public final class MessageList<T> implements Iterable<T> {
* and return itself. * and return itself.
*/ */
public MessageList<T> add(T[] src, int srcIdx, int srcLen) { public MessageList<T> add(T[] src, int srcIdx, int srcLen) {
checkElements(src, srcIdx, srcLen); if (src == null) {
throw new NullPointerException("src");
}
modifications++; modifications ++;
int oldSize = size;
int newSize = oldSize + srcLen; int dstIdx = size;
final int newSize = dstIdx + srcLen;
ensureCapacity(newSize); ensureCapacity(newSize);
System.arraycopy(src, srcIdx, elements, oldSize, srcLen);
size = newSize; final int srcEndIdx = srcIdx + srcLen;
int i = srcIdx;
try {
if (byteBufsOnly) { if (byteBufsOnly) {
for (int i = srcIdx; i < srcIdx; i++) { for (; i < srcEndIdx; i ++) {
if (!(src[i] instanceof ByteBuf)) { T m = src[srcIdx];
if (m == null) {
throw new NullPointerException("src[" + srcIdx + ']');
}
elements[dstIdx ++] = m;
if (!(m instanceof ByteBuf)) {
byteBufsOnly = false; byteBufsOnly = false;
break; break;
} }
} }
} }
for (; i < srcEndIdx; i ++) {
T m = src[srcIdx];
if (m == null) {
throw new NullPointerException("src[" + srcIdx + ']');
}
elements[dstIdx ++] = m;
}
} finally {
if (dstIdx != newSize) {
// Could not finish iteration.
Arrays.fill(elements, size, dstIdx, null);
}
}
assert dstIdx == newSize;
size = newSize;
return this; return this;
} }
@ -292,7 +322,7 @@ public final class MessageList<T> implements Iterable<T> {
* Clear all messages and return itself. * Clear all messages and return itself.
*/ */
public MessageList<T> clear() { public MessageList<T> clear() {
modifications++; modifications ++;
Arrays.fill(elements, 0, size, null); Arrays.fill(elements, 0, size, null);
byteBufsOnly = true; byteBufsOnly = true;
size = 0; size = 0;
@ -413,6 +443,23 @@ public final class MessageList<T> implements Iterable<T> {
return new MessageListIterator(); return new MessageListIterator();
} }
/**
* Returns the backing array of this list. Use this array when you want to iterate over the list fast:
* <pre>
* {@link MessageList} list = ...;
* for (Object m: list.array()) {
* if (m == null) {
* break;
* }
*
* handleMessage(m);
* }
* </pre>
*/
public T[] array() {
return elements;
}
/** /**
* Returns {@code true} if all messages contained in this {@link MessageList} are assignment-compatible with the * Returns {@code true} if all messages contained in this {@link MessageList} are assignment-compatible with the
* object represented by this {@link Class}. * object represented by this {@link Class}.
@ -474,18 +521,6 @@ public final class MessageList<T> implements Iterable<T> {
} }
} }
private void checkElements(T[] src, int srcIdx, int srcLen) {
if (src == null) {
throw new NullPointerException("src");
}
int end = srcIdx + srcLen;
for (int i = srcIdx; i < end; i ++) {
if (src[i] == null) {
throw new NullPointerException("src[" + i + ']');
}
}
}
private final class MessageListIterator implements Iterator<T> { private final class MessageListIterator implements Iterator<T> {
private int index; private int index;
private int expectedModifications = modifications; private int expectedModifications = modifications;
@ -508,7 +543,7 @@ public final class MessageList<T> implements Iterable<T> {
public T next() { public T next() {
checkConcurrentModifications(); checkConcurrentModifications();
if (hasNext()) { if (hasNext()) {
return elements[index++]; return elements[index ++];
} }
throw new NoSuchElementException(); throw new NoSuchElementException();
} }