in accord-core/src/main/java/accord/utils/ReducingRangeMap.java [291:345]
private <V2, P1, P2> V2 foldlWithDefault(AbstractRanges ranges, ReduceFunction<V, V2, P1, P2> fold, V defaultValue, V2 accumulator, P1 p1, P2 p2, Predicate<V2> terminate)
{
if (ranges.isEmpty())
return accumulator;
if (values.length == 0)
return fold.apply(defaultValue, accumulator, p1, p2, 0, ranges.size(), 0);
int j = ranges.find(starts[0], FAST);
if (j < 0) j = -1 - j;
else if (inclusiveEnds && ranges.get(j).end().equals(starts[0])) ++j;
if (j > 0 || starts[0].compareTo(ranges.get(0).start()) > 0)
accumulator = fold.apply(defaultValue, accumulator, p1, p2, 0, j, 0);
int i = 0;
while (j < ranges.size())
{
// TODO (desired): first search should be binarySearch
int nexti = exponentialSearch(starts, i, starts.length, ranges.get(j).start());
if (nexti < 0) i = Math.max(i, -2 - nexti);
else if (nexti > i && inclusiveEnds) i = nexti - 1;
else i = nexti;
if (i >= values.length)
return fold.apply(defaultValue, accumulator, p1, p2, j, ranges.size(), i);
int toj, nextj = ranges.findNext(j, starts[i + 1], FAST);
if (nextj < 0)
{
toj = nextj = -1 -nextj;
}
else
{
toj = nextj + 1;
if (inclusiveEnds && ranges.get(nextj).end().equals(starts[i + 1]))
++nextj;
}
if (toj > j)
{
V value = values[i];
if (value == null)
value = defaultValue;
accumulator = fold.apply(value, accumulator, p1, p2, j, toj, i);
if (terminate.test(accumulator))
return accumulator;
}
++i;
j = nextj;
}
return accumulator;
}