public V2 foldl()

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;
    }