int partitionSize = facetArrays.getArraysLength();
int endOffset = offset + partitionSize;
ChildrenArrays childrenArray = taxonomyReader.getChildrenArrays();
int[] youngestChild = childrenArray.getYoungestChildArray();
int[] olderSibling = childrenArray.getOlderSiblingArray();
FacetResultNode reusable = null;
int localDepth = 0;
int depth = facetRequest.getDepth();
int[] ordinalStack = new int[2+Math.min(Short.MAX_VALUE, depth)];
int childrenCounter = 0;
int tosOrdinal; // top of stack element
int yc = youngestChild[ordinal];
while (yc >= endOffset) {
yc = olderSibling[yc];
}
// make use of the fact that TaxonomyReader.INVALID_ORDINAL == -1, < endOffset
// and it, too, can stop the loop.
ordinalStack[++localDepth] = yc;
/*
* stack holds input parameter ordinal in position 0.
* Other elements are < endoffset.
* Only top of stack can be TaxonomyReader.INVALID_ORDINAL, and this if and only if
* the element below it exhausted all its children: has them all processed.
*
* stack elements are processed (counted and accumulated) only if they
* belong to current partition (between offset and endoffset) and first time
* they are on top of stack
*
* loop as long as stack is not empty of elements other than input ordinal, or for a little while -- it sibling
*/
while (localDepth > 0) {
tosOrdinal = ordinalStack[localDepth];
if (tosOrdinal == TaxonomyReader.INVALID_ORDINAL) {
// element below tos has all its children, and itself, all processed
// need to proceed to its sibling
localDepth--;
// change element now on top of stack to its sibling.
ordinalStack[localDepth] = olderSibling[ordinalStack[localDepth]];
continue;
}
// top of stack is not invalid, this is the first time we see it on top of stack.
// collect it, if belongs to current partition, and then push its kids on itself, if applicable
if (tosOrdinal >= offset) { // tosOrdinal resides in current partition
int relativeOrdinal = tosOrdinal % partitionSize;
double value = facetRequest.getValueOf(facetArrays, relativeOrdinal);
if (value != 0 && !Double.isNaN(value)) {
// Count current ordinal -- the TOS
if (reusable == null) {
reusable = new MutableFacetResultNode(tosOrdinal, value);
} else {
// it is safe to cast since reusable was created here.
((MutableFacetResultNode)reusable).reset(tosOrdinal, value);
}
++childrenCounter;
reusable = pq.insertWithOverflow(reusable);
if (reusable != null) {
// TODO (Facet): is other logic (not add) needed, per aggregator?
parentResultNode.increaseResidue(reusable.getValue());
}
}
}
if (localDepth < depth) {
// push kid of current tos