Skip to content

Add range mark query APIs to BitMap - #884

Merged
jt2594838 merged 2 commits into
developfrom
add_bitmap_interface
Jul 31, 2026
Merged

Add range mark query APIs to BitMap#884
jt2594838 merged 2 commits into
developfrom
add_bitmap_interface

Conversation

@jt2594838

Copy link
Copy Markdown
Contributor

Summary

  • add isRangeAnyMarked(int start, int length) to detect whether a range contains a marked bit
  • add isRangeAllMarked(int start, int length) to detect whether every bit in a range is marked
  • add isRangeNoneMarked(int start, int length) to detect whether a range contains no marked bits
  • share the implementation across long-backed and byte-array-backed bitmaps
  • add exhaustive range and invalid-argument coverage

Semantics

  • empty ranges return false for isRangeAnyMarked
  • empty ranges return true for isRangeAllMarked and isRangeNoneMarked
  • negative or out-of-bounds ranges throw IndexOutOfBoundsException
  • range checks process up to 64 bits per iteration

Verification

  • mvn -P with-java -pl java/tsfile -am -Dtest=BitMapTest -Dsurefire.failIfNoSpecifiedTests=false test
  • 18 tests passed with no failures or errors
  • Checkstyle and Spotless passed

*
* @throws IndexOutOfBoundsException if the range is outside this bitmap
*/
public boolean isRangeAnyMarked(int start, int length) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

These public APIs distinguish any, all, and none semantics without forcing callers to scan individual bits. The Javadocs explicitly define empty-range results and preserve the existing bitmap range-error convention for invalid input.


abstract boolean isMarked(int position);

boolean isRangeAnyMarked(int start, int length) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The shared implementation keeps long-backed and byte-array-backed bitmaps behaviorally identical by reusing extractBits in batches of up to 64 bits. Range validation uses start > size - length instead of start + length > size so an overflowing sum cannot bypass the bounds check.

}

@Test
public void testRangeMarkedQueries() {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This test checks every valid subrange against a per-bit oracle for empty, array-backed, and long-backed bitmaps, including ranges that cross byte and 64-bit boundaries. It also verifies negative, out-of-bounds, and integer-overflow arguments.

@codecov-commenter

codecov-commenter commented Jul 30, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 54 lines in your changes missing coverage. Please review.
✅ Project coverage is 60.46%. Comparing base (46cf0a1) to head (031dead).

Files with missing lines Patch % Lines
.../java/org/apache/tsfile/utils/BitMapArrayImpl.java 0.00% 39 Missing ⚠️
...n/java/org/apache/tsfile/utils/BitMapLongImpl.java 0.00% 8 Missing ⚠️
.../main/java/org/apache/tsfile/utils/BitMapImpl.java 0.00% 4 Missing ⚠️
.../src/main/java/org/apache/tsfile/utils/BitMap.java 0.00% 3 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop     #884      +/-   ##
===========================================
- Coverage    60.51%   60.46%   -0.06%     
===========================================
  Files          744      744              
  Lines        49081    49125      +44     
  Branches      7797     7816      +19     
===========================================
+ Hits         29703    29704       +1     
- Misses       17978    18019      +41     
- Partials      1400     1402       +2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Caideyipi Caideyipi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I reviewed the range semantics and ran the new API against the current IoTDB byte-scanning helper on Windows/JDK 17, using 64 rotating bitmaps and current-thread CPU/allocation metrics.

Correctness looks good: the exhaustive range test passes locally (18/18 BitMapTest methods), overflow-safe range validation is sound, and the public empty-range semantics are clear.

There is one performance concern with sharing the extractBits implementation across both bitmap representations. Representative results for isRangeAnyMarked on 64-bit ranges were:

representation / range current IoTDB helper new API
array-backed prefix 4.688 ns, 0 B 7.813 ns, 0 B
array-backed partial 4.688 ns, 0 B 7.813 ns, 0 B
array-backed next block 3.125 ns, 0 B 7.813 ns, 0 B
long-backed prefix 3.125 ns, 0 B 1.563 ns, 0 B
long-backed partial 10.938 ns, 32 B 3.125 ns, 0 B

So the API is a clear win for the long-backed implementation, especially because it eliminates getByteArray() allocation for non-prefix ranges, but the generic extractBits path is about 1.7-2.5x slower for array-backed bitmaps. The latter matters for IoTDB tablets larger than 64 rows, where 64-row block checks commonly operate on an array-backed input bitmap.

Could we keep the public API/range validation here, but provide representation-specific fast paths?

  • BitMapLongImpl: shifted value + lowerBitsMask(length) for any/all/none.
  • BitMapArrayImpl: first/last byte masks plus direct scanning of complete middle bytes, avoiding reconstruction of a long.
  • Add a small performance comparison covering long/array-backed bitmaps at (0, 64), (1, 63), and (64, 64).

It would also be useful to add a true full-64-bit isRangeAllMarked case and an all-marked range crossing a 64-bit boundary; the current patterned oracle is exhaustive over ranges but does not exercise those results as true for a complete batch.

@jt2594838

Copy link
Copy Markdown
Contributor Author

Thanks for the detailed analysis. Addressed in 031dead:

  • moved the range-query implementations into BitMapLongImpl and BitMapArrayImpl, keeping shared range validation in BitMapImpl
  • added the long shifted-mask path and array first/last-byte plus complete-middle-byte scan
  • added the requested (0, 64), (1, 63), and (64, 64) range benchmark cases
  • added explicit full-64-bit and 64-bit-boundary-crossing isRangeAllMarked cases

I reran:

mvn -P with-java -pl java/tsfile -am -Dtest=BitMapPerformanceTest#testRangeMarkedQueryImplementations -Dtsfile.runPerformanceTests=true -Dsurefire.failIfNoSpecifiedTests=false test

The Maven configuration runs the selected test twice. Both runs showed:

representation / range current helper new API
array-backed prefix 3.125 ns/op, 0 B/op 3.125 ns/op, 0 B/op
array-backed partial 3.125 ns/op, 0 B/op 3.125 ns/op, 0 B/op
array-backed next block 3.125 ns/op, 0 B/op 3.125 ns/op, 0 B/op
long-backed prefix 1.563 ns/op, 0 B/op 1.563 ns/op, 0 B/op
long-backed partial 6.250-7.813 ns/op, 32 B/op 1.563 ns/op, 0 B/op

@Caideyipi Caideyipi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Re-reviewed the updated implementation at 031dead. The representation-specific fast paths address the previous array-backed regression: local targeted runs showed array-backed performance at parity with the current IoTDB helper, while the long-backed path retained its speedup and eliminated the 32 B/op allocation. BitMapTest passed 18/18, including the added full-64-bit and boundary-crossing cases.

@jt2594838
jt2594838 merged commit 3c831b7 into develop Jul 31, 2026
14 checks passed
@jt2594838
jt2594838 deleted the add_bitmap_interface branch July 31, 2026 04:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants