Fixed issues with StatList#add and StatList#ensureCapacity

Add functions now validate they are adding to same stat, else they put a new one
Moved arraycopy copies into static function
StatList#ensureCapacity will correctly copy arrays
Moved any offsets modification operations into StatList#ensureCapacity
This commit is contained in:
Collin Smith
2020-09-04 18:29:48 -07:00
parent db04f49fba
commit 2fd51347bf

View File

@ -113,10 +113,12 @@ public final class StatList {
public void clearList(int list) { public void clearList(int list) {
assertMutable(); assertMutable();
size -= size(list); final int listSize = size(list);
size -= listSize;
assert size >= 0; assert size >= 0;
final int offset = list << 1; final int offset = list << 1;
final byte[] offsets = this.offsets; final byte[] offsets = this.offsets;
if (offsets[offset + 1] == tail) tail -= listSize;
offsets[offset + 1] = offsets[offset]; offsets[offset + 1] = offsets[offset];
} }
@ -148,36 +150,61 @@ public final class StatList {
return new StatListBuilder(this, newList(capacity)); return new StatListBuilder(this, newList(capacity));
} }
public void ensureCapacity(int list, int index, int capacity) { private void arraycopy(int srcIndex, int dstIndex, int length) {
log.traceEntry("arraycopy(srcIndex: {}, dstIndex: {}, length: {})", srcIndex, dstIndex, length);
arraycopy(this, srcIndex, this, dstIndex, length);
}
private static void arraycopy(
final StatList src, final int srcIndex,
final StatList dst, final int dstIndex,
final int length) {
log.traceEntry(
"arraycopy(src: {}, srcIndex: {}, dst: {}, dstIndex: {}, length: {})",
src, srcIndex, dst, dstIndex, length);
System.arraycopy(src.ids, srcIndex, dst.ids, dstIndex, length);
System.arraycopy(src.params, srcIndex, dst.params, dstIndex, length);
System.arraycopy(src.values, srcIndex, dst.values, dstIndex, length);
System.arraycopy(src.flags, srcIndex, dst.flags, dstIndex, length);
}
public void ensureCapacity(final int list, final int index, final int capacity) {
log.traceEntry("ensureCapacity(list: {}, index: {}, capacity: {})", list, index, capacity);
assertMutable(); assertMutable();
final int startOffset = startingOffset(list);
final int endOffset = endingOffset(list); final int endOffset = endingOffset(list);
final int shiftLength = endOffset - index;
final int newEndOffset = endOffset + capacity;
final int nextStartOffset = (list + 1) < numLists ? startingOffset(list + 1) : MAX_STATS; final int nextStartOffset = (list + 1) < numLists ? startingOffset(list + 1) : MAX_STATS;
if (nextStartOffset - startOffset > capacity) { final int listsSize = numLists << 1;
if (tail == endOffset) { final byte[] offsets = this.offsets;
if (tail + capacity >= MAX_STATS) throw new IllegalArgumentException( assert shiftLength >= 0
"capacity(" + capacity + ") would exceed MAX_STATS(" + MAX_STATS + ")"); : "shiftLength(" + shiftLength + ") < " + 0 + ": cannot ensure capacity ahead of end offset";
tail += capacity; if (shiftLength > 0 && newEndOffset < nextStartOffset) {
} if (newEndOffset >= MAX_STATS) throw new IllegalArgumentException(
"capacity(" + capacity + ") would exceed MAX_STATS(" + MAX_STATS + ")");
arraycopy(index, index + capacity, shiftLength);
if (tail == endOffset) tail = newEndOffset;
offsets[(list << 1) + 1] = (byte) newEndOffset;
assert isSorted(offsets, 0, listsSize)
: "offsets(" + ByteBufUtil.hexDump(offsets, 0, listsSize) + ") contains property lists that are out of order";
return; return;
} }
final int additionalCapacity = capacity - (nextStartOffset - endOffset); final int additionalCapacity = newEndOffset - nextStartOffset;
if (tail + additionalCapacity >= MAX_STATS) throw new IllegalArgumentException( if (tail + additionalCapacity >= MAX_STATS) throw new IllegalArgumentException(
"capacity(" + capacity + ") would exceed MAX_STATS(" + MAX_STATS + ")"); "capacity(" + capacity + ") would exceed MAX_STATS(" + MAX_STATS + ")");
final int dstOffset = index + additionalCapacity; arraycopy(index, index + capacity, tail - index);
final int length = tail - index; if (additionalCapacity > 0) {
System.arraycopy(ids, index, ids, dstOffset, length); tail += additionalCapacity;
System.arraycopy(params, index, params, dstOffset, length); for (int i = ((list + 1) << 1); i < listsSize; i++) {
System.arraycopy(values, index, values, dstOffset, length); offsets[i] += additionalCapacity;
System.arraycopy(flags, index, flags, dstOffset, length); }
tail += additionalCapacity; assert isSorted(offsets, 0, listsSize) : "offsets(" + ByteBufUtil.hexDump(offsets, 0, listsSize) + ") contains property lists that are out of order";
} else if (tail == endOffset) {
final byte[] offsets = this.offsets; tail = offsets[(list << 1) + 1] = (byte) newEndOffset;
final int listsSize = numLists << 1; }
for (int i = ((list + 1) << 1); i < listsSize; i++) offsets[i] += additionalCapacity;
assert isSorted(offsets, 0, listsSize) : "offsets(" + ByteBufUtil.hexDump(offsets, 0, listsSize) + ") contains property lists that are out of order";
} }
public StatList copy(int list, StatList src, int srcList) { public StatList copy(int list, StatList src, int srcList) {
@ -187,15 +214,9 @@ public final class StatList {
ensureCapacity(list, dstListStart, length); ensureCapacity(list, dstListStart, length);
final int srcListStart = src.startingOffset(srcList); final int srcListStart = src.startingOffset(srcList);
System.arraycopy(src.ids, srcListStart, this.ids, dstListStart, length); arraycopy(src, srcListStart, this, dstListStart, length);
System.arraycopy(src.params, srcListStart, this.params, dstListStart, length);
System.arraycopy(src.values, srcListStart, this.values, dstListStart, length);
System.arraycopy(src.flags, srcListStart, this.flags, dstListStart, length);
size += length; size += length;
if (log.debugEnabled()) log.debug(listDebugString(list));
final byte[] offsets = this.offsets;
offsets[(list << 1) + 1] += length;
assert isSorted(offsets, 0, numLists << 1) : "offsets(" + ByteBufUtil.hexDump(offsets, 0, numLists << 1) + ") contains property lists that are out of order";
return this; return this;
} }
@ -209,12 +230,8 @@ public final class StatList {
public StatList setAll(StatList src) { public StatList setAll(StatList src) {
assertMutable(); assertMutable();
clear(); clear();
final int length = src.tail;
System.arraycopy(src.offsets, 0, this.offsets, 0, src.numLists() << 1); System.arraycopy(src.offsets, 0, this.offsets, 0, src.numLists() << 1);
System.arraycopy(src.ids, 0, this.ids, 0, length); arraycopy(src, 0, this, 0, src.tail);
System.arraycopy(src.params, 0, this.params, 0, length);
System.arraycopy(src.values, 0, this.values, 0, length);
System.arraycopy(src.flags, 0, this.flags, 0, length);
size = src.size; size = src.size;
tail = src.tail; tail = src.tail;
numLists = src.numLists; numLists = src.numLists;
@ -262,7 +279,7 @@ public final class StatList {
if (log.debugEnabled()) log.debug( if (log.debugEnabled()) log.debug(
"add(stat: {} ({}), this: {}, src: {})", "add(stat: {} ({}), this: {}, src: {})",
stat, entry(stat), index >= 0 ? asString(index) : "null", src.asString(otherIndex)); stat, entry(stat), index >= 0 ? asString(index) : "null", src.asString(otherIndex));
if (index >= 0) { if (index >= 0 && ids[index] == stat) {
values[index] += src.values[otherIndex]; values[index] += src.values[otherIndex];
return index; return index;
} else { } else {
@ -281,7 +298,7 @@ public final class StatList {
if (log.debugEnabled()) log.debug( if (log.debugEnabled()) log.debug(
"add(stat: {} ({}), this: {}, src: {})", "add(stat: {} ({}), this: {}, src: {})",
stat, entry(stat), index >= 0 ? asString(index) : "null", src.debugString()); stat, entry(stat), index >= 0 ? asString(index) : "null", src.debugString());
if (index >= 0) { if (index >= 0 && ids[index] == stat) {
values[index] += src.value(); values[index] += src.value();
return index; return index;
} else { } else {
@ -354,7 +371,7 @@ public final class StatList {
"stat: {} ({}) has unsupported encoding({})", stat, entry, encoding); "stat: {} ({}) has unsupported encoding({})", stat, entry, encoding);
final int index = indexOf(list, stat, param); final int index = indexOf(list, stat, param);
if (index >= 0) { if (index >= 0 && ids[index] == stat && params[index] == param) {
set(index, stat, param, value, entry); set(index, stat, param, value, entry);
if (log.debugEnabled()) log.debug(indexDebugString(index)); if (log.debugEnabled()) log.debug(indexDebugString(index));
return index; return index;
@ -629,11 +646,6 @@ public final class StatList {
set(index, stat, param, value, entry); set(index, stat, param, value, entry);
size++; size++;
final byte[] offsets = this.offsets;
offsets[(list << 1) + 1]++;
final int listsSize = numLists << 1;
for (int i = ((list + 1) << 1); i < listsSize; i++) offsets[i]++;
assert isSorted(offsets, 0, listsSize) : "offsets(" + Arrays.toString(offsets) + ") contains property lists that are out of order";
if (log.debugEnabled()) log.debug(listDebugString(list)); if (log.debugEnabled()) log.debug(listDebugString(list));
} }