Skip to content

Document that copy-on-write bitmaps need synchronization even for Clone - #595

Merged
lemire merged 1 commit into
masterfrom
doc-cow-concurrency
Nov 12, 2026
Merged

lemire merged 1 commit into
masterfrom
doc-cow-concurrency

Conversation

@lemire

@lemire lemire commented Nov 12, 2026

Copy link
Copy Markdown
Member

Description

With copy-on-write enabled, some operations that leave a bitmap's values unchanged still write its internal sharing flags (needCopyOnWrite):

  • rb.Clone() marks every container of rb as shared.
  • x.Or(rb) and x.Xor(rb) mark the containers of rb they share with x, when x also uses copy-on-write.

So two goroutines that only call rb.Clone() on the same copy-on-write bitmap race (#528). Static operations such as Or(x1, x2), Flip and FastOr only read these flags, so they still race with a concurrent Clone().

The existing doc comment already said that copy-on-write "requires extra care in a threaded context", and the README already says bitmaps are not synchronized. This PR states the specific case plainly instead of adding locking to the hot paths. Adding a lock to Clone alone (as in #574) would leave the other paths racing. Locking every flag write would slow down the binary operations for all copy-on-write users.

Changes Made

  • SetCopyOnWrite and Clone doc comments in roaring.go and roaring64/roaring64.go now explain which operations write the flags, and that concurrent use (even only Clone) needs external synchronization.
  • The README "Goroutine safety" section gets the same note.

No code changes.

Testing

Documentation only. go test ./... passes. I checked with go test -race that concurrent Clone/Clone and Clone/Or on a copy-on-write bitmap race on master. I checked that Clone, x.Or(rb) and x.Xor(rb) set rb's flags in both the 32-bit and 64-bit packages.

Related Issues

Closes #528

With copy-on-write enabled, rb.Clone() marks the containers of rb as
shared, and x.Or(rb) / x.Xor(rb) do the same when x also uses
copy-on-write. These calls look read-only but write internal flags of
rb, so concurrent use from several goroutines is a data race. State
this in the SetCopyOnWrite and Clone doc comments (32-bit and 64-bit)
and in the README goroutine-safety section.

Closes #528
@lemire lemire closed this Nov 12, 2026
@lemire lemire reopened this Nov 12, 2026
@lemire
lemire merged commit a0d470f into master Nov 12, 2026
21 checks passed
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.

Bitmap.Clone() data race on copy-on-write bitmaps (no writers)

1 participant