Skip to content

feat(util): add Mumbling bitmap reader - #1126

Open
xndai wants to merge 2 commits into
apache:mainfrom
xndai:xndai/iceberg-cpp/B1
Open

xndai wants to merge 2 commits into
apache:mainfrom
xndai:xndai/iceberg-cpp/B1

Conversation

@xndai

@xndai xndai commented Nov 14, 2026 •

Copy link
Copy Markdown

Closes #1125. Part of #1107.

Adds an internal reader for the Mumbling bitmap format (a draft spec, apache/iceberg#16518), which v4 manifest deletion vectors use (manifest_info.dv, tracking.deleted_positions and tracking.replaced_positions). Because the spec is a draft, the header is util/mumbling_bitmap_internal.h and isn't installed.

MumblingBitmapView::Make() wraps the serialized bytes without copying them. In scan planning those bytes belong to the root manifest entry, which outlives the planning of its leaf manifest. Make() checks the header, the PFOR-encoded descriptor array (Appendix A), the descriptor types, and the container sizes against the buffer, so Contains() never reads out of bounds. Like the Java reader, it doesn't validate container contents. Sparse-container lookups use SSE2 on x86-64 and a portable SWAR search elsewhere; no compiler flags are added.

Tests cover the spec examples, malformed input (including the vectors from Java's TestMumblingBitmap), and the Java-generated fixtures from apache/iceberg-go#1750. mumbling_bitmap_benchmark (built with -DICEBERG_BUILD_BENCHMARKS=ON) measures decoding and lookups.

Benchmark against the Java reader on the same input bytes (Release; gcc-14 with Google Benchmark, JDK 17 with JMH; Xeon Platinum 8175M):

Operation C++ Java
Decode 8,192 PFOR-encoded descriptors 0.35–3.1 µs 1.3–12.4 µs
Make, 100,000 random positions 13.3 µs 29.2 µs
Make, all 2,097,152 positions 9.4 µs 14.2 µs
Contains, 4,096 probes, 100,000 random positions 23.7 µs 83.5 µs
Contains, 4,096 probes, all positions 14.6 µs 24.1 µs

Test:

  • New unit tests in util_test (mumbling_bitmap_internal_test.cc) cover
    the spec examples, Java-generated fixtures and malformed input.
  • The full test suite passes on both the SSE2 and the portable lookup
    path, and the new tests pass under ASan and UBSan.
  • New microbenchmarks in src/iceberg/benchmark
    (mumbling_bitmap_benchmark, built with -DICEBERG_BUILD_BENCHMARKS=ON).

Add an internal reader for the Mumbling bitmap format, which v4
manifest deletion vectors use (manifest_info.dv,
tracking.deleted_positions and tracking.replaced_positions). The spec
is still a draft, so the header is internal and not installed.

MumblingBitmapView wraps the serialized bytes without copying them and
supports Contains() and Cardinality(). Make() validates everything that
memory safety depends on, so lookups never read out of bounds.

Test:
- New unit tests in util_test (mumbling_bitmap_internal_test.cc) cover
  the spec examples, Java-generated fixtures and malformed input.
- The full test suite passes on both the SSE2 and the portable lookup
  path, and the new tests pass under ASan and UBSan.
- New microbenchmarks in src/iceberg/benchmark
  (mumbling_bitmap_benchmark, built with -DICEBERG_BUILD_BENCHMARKS=ON).
@xndai
xndai force-pushed the xndai/iceberg-cpp/B1 branch from ce1a7d1 to b11c29a Compare November 14, 2026 19:36
Use KeepRunning() loops and an explicit main() in the benchmark (as in
benchmark_smoke.cc), std::cmp_less for signed/unsigned comparisons,
and std::array instead of a C array in the test.

This branch has not been deployed

No deployments
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.

Add a Mumbling bitmap reader for v4 manifest deletion vectors

1 participant