Skip to content

[improve][broker] Optimize bucket delayed-delivery bitmap point operations#26205

Merged
nodece merged 2 commits into
apache:masterfrom
nodece:optimize-bucket-bitmap-point-ops
Jul 20, 2026
Merged

[improve][broker] Optimize bucket delayed-delivery bitmap point operations#26205
nodece merged 2 commits into
apache:masterfrom
nodece:optimize-bucket-bitmap-point-ops

Conversation

@nodece

@nodece nodece commented Jul 17, 2026

Copy link
Copy Markdown
Member

Motivation

The bucket delayed-delivery code was using range-overload bitmap operations to manipulate individual entries — add(entryId, entryId + 1), remove(entryId, entryId + 1), contains(entryId, entryId + 1). These are semantically equivalent to the single-value overloads (half-open [v, v+1) contains exactly v, verified at the RoaringBitmap 1.6.9 source level), but incur unnecessary overhead: range validation, half-open arithmetic, and iteration setup.

Bucket.removeIndexBit was the more impactful case — it called contains(v) then remove(v) separately, acquiring two StampedLocks (read then write) and traversing the RoaringBitmap twice per ack. The remove(v) return value can carry the "was present" signal in a single atomic operation, eliminating the redundant lookup.

Modifications

  • LongBitmap / ConcurrentRoaringBitmap: remove(long) and remove(long, long) now return boolean, mirroring the existing checkedAdd pattern. Single-value uses MutableRoaringBitmap.checkedRemove; range uses cardinality diff to compute the boolean return and only bumps removesSinceTrim when something was actually removed (previously it bumped by the range upper bound unconditionally).
  • Bucket: All point operations switched to single-value overloads. removeIndexBit now uses the boolean return from remove directly, eliminating the redundant contains check — saving one StampedLock acquisition and one RoaringBitmap container lookup per ack on the delayed-delivery hot path.
  • MutableBucket: Snapshot-build path switched from add(entryId, entryId + 1) to add(entryId).

Performance

Local JMH measurement on LongBitmapBenchmark (single-threaded, point-remove pattern with bitmap size 1k and 100k) shows ~22–27% throughput improvement for remove returning boolean vs contains + remove:

bitmap size contains + remove remove (boolean) speedup
1,000 4.167 ± 0.108 ops/μs 5.097 ± 0.358 ops/μs +22%
100,000 11.113 ± 1.463 ops/μs 14.160 ± 1.360 ops/μs +27%

@void-ptr974 void-ptr974 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.

Nice optimization for the point operations.

In remove(from, to), removesSinceTrim now only increases by 1 even when the range removes many values. This does not affect correctness, but it can delay trim() and retain extra bitmap memory longer for large non-empty range removals.

Please keep accounting by the removed count instead.

@nodece
nodece merged commit c886c07 into apache:master Jul 20, 2026
43 checks passed
@nodece
nodece deleted the optimize-bucket-bitmap-point-ops branch July 20, 2026 06:42
@nodece nodece added this to the 5.0.0-M2 milestone Jul 20, 2026
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