allNodes.addAll(nonLeaves);
allNodes.addAll(leaves);
columnNodeWriters = Lists.newArrayListWithCapacity(CollectionUtils.nullSafeSize(allNodes));
for (int i = 0; i < allNodes.size(); ++i) {
TokenizerNode node = allNodes.get(i);
columnNodeWriters.add(new ColumnNodeWriter(blockMeta, node, this.nodeType));
}
// leaf widths are known at this point, so add them up
int totalBytesWithoutOffsets = 0;
for (int i = allNodes.size() - 1; i >= 0; --i) {
ColumnNodeWriter columnNodeWriter = columnNodeWriters.get(i);
// leaves store all but their first token byte
totalBytesWithoutOffsets += columnNodeWriter.getWidthUsingPlaceholderForOffsetWidth(0);
}
// figure out how wide our offset FInts are
int parentOffsetWidth = 0;
while (true) {
++parentOffsetWidth;
int numBytesFinder = totalBytesWithoutOffsets + parentOffsetWidth * allNodes.size();
if (numBytesFinder < UFIntTool.maxValueForNumBytes(parentOffsetWidth)) {
numBytes = numBytesFinder;
break;
}// it fits
}
if (this.nodeType == ColumnNodeType.FAMILY) {
blockMeta.setFamilyOffsetWidth(parentOffsetWidth);
} else if (this.nodeType == ColumnNodeType.QUALIFIER) {
blockMeta.setQualifierOffsetWidth(parentOffsetWidth);
} else {
blockMeta.setTagsOffsetWidth(parentOffsetWidth);
}
int forwardIndex = 0;
for (int i = 0; i < allNodes.size(); ++i) {
TokenizerNode node = allNodes.get(i);
ColumnNodeWriter columnNodeWriter = columnNodeWriters.get(i);
int fullNodeWidth = columnNodeWriter
.getWidthUsingPlaceholderForOffsetWidth(parentOffsetWidth);
node.setOutputArrayOffset(forwardIndex);
columnNodeWriter.setTokenBytes(node.getToken());
if (node.isRoot()) {
columnNodeWriter.setParentStartPosition(0);
} else {
columnNodeWriter.setParentStartPosition(node.getParent().getOutputArrayOffset());
}
forwardIndex += fullNodeWidth;
}
tokenizer.appendOutputArrayOffsets(outputArrayOffsets);