private int forEach()

in accord-core/src/main/java/accord/utils/SearchableRangeList.java [207:293]


    private <P1, P2, P3> int forEach(int start, int end, int floor, RoutableKey startBound,
                                     IndexedTriConsumer<P1, P2, P3> forEachScanOrCheckpoint, IndexedRangeTriConsumer<P1, P2, P3> forEachRange,
                                     P1 p1, P2 p2, P3 p3, int minIndex)
    {
        if (start < minIndex) start = minIndex;

        // find the checkpoint array, so we know how far to step back
        int checkpoint = Arrays.binarySearch(lowerBounds, floor);
        if (checkpoint < 0) checkpoint = -2 - checkpoint;
        if (checkpoint < 0) return end;

        int headerBaseIndex = (checkpoint / 4) * 5;
        int headerSubIndex = checkpoint & 3;
        int headerListIndex = headerBaseIndex + 1 + headerSubIndex;

        int scanDistance = (headers[headerBaseIndex] >>> (8 * headerSubIndex)) & 0xff;
        int checkpointStart = headers[headerListIndex];
        int checkpointEnd = headers[headerListIndex + (headerSubIndex + 5)/4]; // skip the next header

        if (scanDistance == MAX_SCAN_DISTANCE)
        {
            scanDistance = -checkpointLists[checkpointStart++];
            Invariants.checkState(scanDistance >= MAX_SCAN_DISTANCE);
        }

        // NOTE: we visit in approximately ascending order, and this is a requirement for correctness of RangeDeps builders
        //       Only the checkpoint is visited in uncertain order, but it is visited entirely, before the scan matches
        //       and the range matches
        int minScanIndex = Math.max(floor - scanDistance, minIndex);
        for (int i = checkpointStart; i < checkpointEnd ; ++i)
        {
            int ri = checkpointLists[i];
            if (ri < 0)
            {
                int subStart, subEnd;
                if ((ri & BIT30) != 0)
                {
                    subStart = ri & 0xfffff;
                    subEnd = subStart + ((ri >>> 20) & 0x1ff);
                }
                else if ((ri & BIT29) != 0)
                {
                    subStart = ri & 0x1fffffff;
                    subEnd = Integer.MAX_VALUE;
                }
                else
                {
                    int length = ri & 0x1fffffff;
                    subStart = checkpointLists[++i];
                    subEnd = subStart + length;
                }

                for (int j = subStart ; j < subEnd ; ++j)
                {
                    ri = checkpointLists[j];
                    if (ri < 0)
                        continue;

                    if (ranges[ri].end().compareTo(startBound) <= 0)
                        break;

                    if (ri >= minIndex && ri < minScanIndex)
                        forEachScanOrCheckpoint.accept(p1, p2, p3, ri);
                }
            }
            else
            {
                // if startBound is key, we cannot be equal to it;
                // if startBound is a Range start, we also cannot be equal to it due to the requirement that
                // endInclusive() != startInclusive(), so equality really means inequality
                if (ranges[ri].end().compareTo(startBound) <= 0)
                    break;

                if (ri >= minIndex && ri < minScanIndex)
                    forEachScanOrCheckpoint.accept(p1, p2, p3, ri);
            }
        }

        for (int i = minScanIndex; i < floor ; ++i)
        {
            if (ranges[i].end().compareTo(startBound) > 0)
                forEachScanOrCheckpoint.accept(p1, p2, p3, i);
        }

        forEachRange.accept(p1, p2, p3, start, end);
        return end;
    }