Summary
RootMeta::compression_ is a std::shared_ptr<compression::DictCompression>, so every copy of it pays an atomic refcount operation. But like the page mapping, this dictionary is only ever accessed on the owning shard's thread (shard-thread affinity — all async completions re-enter through the shard's ready queues, never touch shard-owned state on a foreign thread). The atomic refcount is therefore unnecessary overhead.
The page mapping already avoids this: MappingSnapshot uses a plain non-atomic ref_cnt_ (MappingSnapshot::Ref, include/storage/page_mapper.h). compression_ could use the same single-threaded non-atomic ref-counting scheme for consistency and to drop the atomics.
Motivation
The read path now captures the compression dictionary as a shared_ptr copy for the duration of the read (so a concurrent reopen that replaces meta->compression_ cannot make the read decode with the wrong/freed dictionary — see the reopen-clear COW fix). That capture is one atomic increment/decrement per read. Converting compression_ to a non-atomic ref-counted pointer removes those atomics and matches how the mapping snapshot is already handled.
Scope
This is a performance/consistency refactor, not a correctness fix. It touches the type and every assign/copy/access site:
RootMeta::compression_ type (include/storage/root_meta.h)
PageManager::MakeCowRoot (shares the same object across the CoW meta)
PageManager::InstallExternalSnapshot, InstallEmptyRoot
PageManager::FindRoot (load_meta), UpdateRoot
- read path capture in
src/tasks/read_task.cpp
- write path uses in
src/tasks/write_task.cpp / batch_write_task.cpp
Priority
Low. The atomic is uncontended and dwarfed by the per-read IO (FindRoot + SeekIndex + LoadDataPage), so the expected win is marginal. Worth doing for consistency with MappingSnapshot::Ref and if profiling ever flags it.
Summary
RootMeta::compression_is astd::shared_ptr<compression::DictCompression>, so every copy of it pays an atomic refcount operation. But like the page mapping, this dictionary is only ever accessed on the owning shard's thread (shard-thread affinity — all async completions re-enter through the shard's ready queues, never touch shard-owned state on a foreign thread). The atomic refcount is therefore unnecessary overhead.The page mapping already avoids this:
MappingSnapshotuses a plain non-atomicref_cnt_(MappingSnapshot::Ref,include/storage/page_mapper.h).compression_could use the same single-threaded non-atomic ref-counting scheme for consistency and to drop the atomics.Motivation
The read path now captures the compression dictionary as a
shared_ptrcopy for the duration of the read (so a concurrent reopen that replacesmeta->compression_cannot make the read decode with the wrong/freed dictionary — see the reopen-clear COW fix). That capture is one atomic increment/decrement per read. Convertingcompression_to a non-atomic ref-counted pointer removes those atomics and matches how the mapping snapshot is already handled.Scope
This is a performance/consistency refactor, not a correctness fix. It touches the type and every assign/copy/access site:
RootMeta::compression_type (include/storage/root_meta.h)PageManager::MakeCowRoot(shares the same object across the CoW meta)PageManager::InstallExternalSnapshot,InstallEmptyRootPageManager::FindRoot(load_meta),UpdateRootsrc/tasks/read_task.cppsrc/tasks/write_task.cpp/batch_write_task.cppPriority
Low. The atomic is uncontended and dwarfed by the per-read IO (FindRoot + SeekIndex + LoadDataPage), so the expected win is marginal. Worth doing for consistency with
MappingSnapshot::Refand if profiling ever flags it.