in accord-core/src/main/java/accord/utils/BTreeReducingRangeMap.java [104:157]
public <V2, P1, P2> V2 foldl(AbstractRanges ranges, QuadFunction<V, V2, P1, P2, V2> fold, V2 accumulator, P1 p1, P2 p2, Predicate<V2> terminate)
{
if (isEmpty())
return accumulator;
int treeSize = BTree.size(tree),
rangesSize = ranges.size();
RoutingKey start = startAt(0);
int i = ranges.find(start, FAST);
if (i < 0) i = -1 - i;
else if (inclusiveEnds && ranges.get(i).end().equals(start)) ++i;
while (i < rangesSize)
{
Range range = ranges.get(i++);
int startIdx = findIndex(range.start());
int startPos = startIdx < 0 ? (-1 - startIdx) : startIdx;
if (startIdx == treeSize - 1 || startPos == treeSize)
return accumulator; // is last or out of bounds -> we are done
if (startIdx < 0) startPos = Math.max(0, startPos - 1); // inclusive
int endIdx = findIndex(range.end());
int endPos = endIdx < 0 ? (-1 - endIdx) : endIdx;
if (endPos == 0)
continue; // is first or out of bounds -> continue
endPos = Math.min(endPos - 1, treeSize - 2); // inclusive
Iterator<Entry<RoutingKey,V>> iterator =
BTree.iterator(tree, startPos, endPos, BTree.Dir.ASC);
while (iterator.hasNext())
{
Entry<RoutingKey, V> entry = iterator.next();
if (entry.hasValue() && entry.value() != null)
{
accumulator = fold.apply(entry.value(), accumulator, p1, p2);
if (terminate.test(accumulator))
return accumulator;
}
}
if (endPos >= treeSize - 2)
return accumulator;
RoutingKey nextStart = startAt(endPos + 1);
i = ranges.findNext(i, nextStart, FAST);
if (i < 0) i = -1 - i;
else if (inclusiveEnds && ranges.get(i).end().equals(nextStart)) ++i;
}
return accumulator;
}