Concurrency Model
Overview
SegmentIndex is thread-safe and does not use a global read/write lock. Sync operations execute on the caller thread; concurrency is controlled by per-segment state machines and minimal shared-structure locks (mapping, registry).
Segment-level concurrency does not require external locks. SegmentImpl
enforces its own lock-free admission gate (see
docs/architecture/segment/segment-concurrency.md).
Concurrency Invariants (Target Design)
These invariants must hold for the current per-segment concurrency design:
- Mapping integrity: the key→segment map must always point to an existing segment; updates are atomic and visible to readers.
- Split atomicity: a segment split must either be fully applied (new segments + updated map) or not applied at all.
- Cache visibility: reads observe the latest cached writes (read-after-write visibility) and flushes operate on a consistent snapshot.
- Lifecycle linearity: once close starts, no new operations are accepted; operations in flight either complete before close returns or fail deterministically.
- No use-after-close: evicted/closed segment data must not be accessed by concurrent readers.
- Stats consistency: counters reflect all completed operations (exact or eventually consistent by design).
Shared State That Must Be Protected
These structures are shared across threads and require synchronization:
UniqueCache(index write buffer)KeyToSegmentMap(key→segment map)SegmentRegistryandSegmentDataCache(segment lookup + cached data)SegmentSplitCoordinator(topology updates)IndexState(open/close state) andStats(counters)- Any
TypeDescriptorimplementation with mutable internal state
Ordering
- With multiple threads, operation order is not guaranteed.
- If strict ordering is required, apply external synchronization at the caller level.
- Across segments, operations can complete in any order.
Threads
- Sync operations run on caller threads.
- Async operations run on background threads via
IndexAsyncAdapter. - Segment maintenance runs on the segment-index maintenance executor.
Implications
- Write/write and read/write conflicts are handled by per-segment state machines and shared-structure locks, not a global lock.
- Read-heavy workloads benefit from parallelism.
- Callers should not rely on global ordering across keys.