Skip to content

perf: Faster advanceIfNeeded for Roaring iterators. - #20129

Open
gianm wants to merge 2 commits into
apache:masterfrom
gianm:roaring-seekable-iterator
Open

perf: Faster advanceIfNeeded for Roaring iterators.#20129
gianm wants to merge 2 commits into
apache:masterfrom
gianm:roaring-seekable-iterator

Conversation

@gianm

@gianm gianm commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

This patch adds SeekableRoaringIntIterator and uses it instead of ImmutableRoaringBitmap#getIntIterator in WrappedImmutableRoaringBitmap.

The seekable iterator performs better than the builtin iterator, because it uses PointableRoaringArray#advanceUntil to advance containers, which is capable of binary search.

This patch also updates various code paths that reset bitmap iterators in vectorized code paths to get them all using common logic: they should reset the iterator if the new start is prior to the old end, rather than comparing start-to-start or end-to-end.

This patch adds SeekableRoaringIntIterator and uses it instead of
ImmutableRoaringBitmap#getIntIterator in WrappedImmutableRoaringBitmap.

The seekable iterator performs better than the builtin iterator,
because it uses PointableRoaringArray#advanceUntil to advance containers,
which is capable of binary search.

This patch also updates various code paths that reset bitmap iterators
in vectorized code paths to get them all using common logic: they should
reset the iterator if the new start is prior to the old end, rather than
comparing start-to-start or end-to-end.
@gianm

gianm commented Aug 24, 2026

Copy link
Copy Markdown
Contributor Author

Benchmarks, using the newly added case in TimeseriesBenchmark. This one is designed such that the matcher in OrFilter#convertIndexToVectorValueMatcher needs to advance and (for descending order) reset a bitmap iterator.

ImmutableRoaringBitmap#getIntIterator

Benchmark                                      (descending)  (numSegments)  (queryGranularity)  (rowsPerSegment)            (schemaAndQuery)  (vectorize)  Mode  Cnt      Score      Error  Units
TimeseriesBenchmark.querySingleQueryableIndex          true              1                hour           5000000  basic.orFilterPartialIndex         true  avgt   15  95480.273 ± 1764.428  us/op
TimeseriesBenchmark.querySingleQueryableIndex         false              1                hour           5000000  basic.orFilterPartialIndex         true  avgt   15  85104.620 ±  735.264  us/op

SeekableRoaringIntIterator

Benchmark                                      (descending)  (numSegments)  (queryGranularity)  (rowsPerSegment)            (schemaAndQuery)  (vectorize)  Mode  Cnt      Score      Error  Units
TimeseriesBenchmark.querySingleQueryableIndex          true              1                hour           5000000  basic.orFilterPartialIndex         true  avgt   15  84235.616 ± 1213.012  us/op
TimeseriesBenchmark.querySingleQueryableIndex         false              1                hour           5000000  basic.orFilterPartialIndex         true  avgt   15  81231.637 ± 1409.373  us/op

.setSimpleTestingIndexSchema(schemaInfo.getAggsArray())
.setMaxRowCount(rowsPerSegment)
.build();
return DataSegment.builder()

@ParameterizedTest(name = "{0}")
@MethodSource("bitmaps")
public void testSequentialIteration(final String name, final ImmutableRoaringBitmap bitmap)

@ParameterizedTest(name = "{0}")
@MethodSource("bitmaps")
public void testPeekNextDoesNotAdvance(final String name, final ImmutableRoaringBitmap bitmap)

@ParameterizedTest(name = "{0}")
@MethodSource("bitmaps")
public void testRandomSeeksInBothDirections(final String name, final ImmutableRoaringBitmap bitmap)

@ParameterizedTest(name = "{0}")
@MethodSource("bitmaps")
public void testAscendingSeeks(final String name, final ImmutableRoaringBitmap bitmap)

@ParameterizedTest(name = "{0}")
@MethodSource("bitmaps")
public void testRandomOperationsMatchReference(final String name, final ImmutableRoaringBitmap bitmap)

@ParameterizedTest(name = "{0}")
@MethodSource("bitmaps")
public void testCloneIsIndependent(final String name, final ImmutableRoaringBitmap bitmap)

@ParameterizedTest(name = "{0}")
@MethodSource("bitmaps")
public void testCloneDoesNotShareCursor(final String name, final ImmutableRoaringBitmap bitmap)

@ParameterizedTest(name = "{0}")
@MethodSource("bitmaps")
public void testAdvanceIfNeededDoesNotMoveBackwards(final String name, final ImmutableRoaringBitmap bitmap)

@ParameterizedTest(name = "{0}")
@MethodSource("bitmaps")
public void testAdvanceIfNeededOnExhaustedIteratorIsANoOp(final String name, final ImmutableRoaringBitmap bitmap)

@FrankChen021 FrankChen021 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have reviewed the code for correctness, edge cases, concurrency, and integration risks; no issues found.

Reviewed 13 of 13 changed files.


This is an automated review by Codex GPT-5.6-Luna(max)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants