Follow-up cleanup pass over the previous commit, removing dispatch
machinery that became trivial once `KeeperStorage` stopped being a
template:
- Unwrap the always-true `if constexpr (std::is_same_v<KeeperStorage,
KeeperStorage>)` in `KeeperStateMachine::apply_snapshot` and drop the
now-dead RocksDB snapshot-apply branch. De-templating had reduced the
former `std::is_same_v<Storage, KeeperMemoryStorage>` to a degenerate
comparison.
- Merge `IKeeperStateMachine` into `KeeperStateMachine`. The abstract
base existed only to hide the `KeeperStorage` template parameter behind
a non-templated interface; with a single storage type it is pointless.
`KeeperStateMachine` now derives from `nuraft::state_machine` directly
and the former pure-virtual methods become plain members.
- Remove the storage template parameter from the Coordination unit-test
fixture: `TestParam` and `CoordinationTest` no longer carry a `Storage`
type (only the compression flag), and the `addNode` / `getUncommittedACLs`
helpers take `KeeperStorage` directly. Also drop the unused
`CompressionParam`.
- Fix `keeper-bench`'s `StorageRunner`, which still referenced the
removed `KeeperMemoryStorage` typedef and `KeeperContext::setRocksDBOptions`.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
New `--storage` flag switches keeper-bench into an in-process mode that exercises
`KeeperStorage` directly, without the rest of the keeper server (no network, no
raft, no state machine).
Threading model mirrors a simplified Keeper commit path:
* N generator threads (`--concurrency`, default 4) produce requests using the
existing `Generator` (so `setup` + `generator` config is reused).
* One "preprocess" thread calls `preprocessRequest` for every write (stands in
for the path that, in real keeper, runs under `raft_server::lock_`).
* One "commit" thread calls `processRequest` for writes. After each committed
write, with probability `1/writes_per_read_batch` it drains the pending read
queue and processes it in one `processLocalRequests` batch.
Inter-thread queues are `NonblockingBoundedQueue` (copied from commit
6a91c30115) with 100µs polling — no condition
variables. The preprocess->commit queue has a small configurable bound
(`storage.preprocess_commit_queue_size`, default 32).
Periodic reports include (for the period): committed writes/s and reads/s,
preprocess / commit-write / commit-read thread utilization, znode count, RSS,
snapshot-mode flag, and per-op-num average preprocess/process ns and ns-per-
list-name.
Every `storage.snapshot_toggle_periods` periods the runner toggles
`enableSnapshotMode`/`disableSnapshotMode` + `clearGarbageAfterSnapshot`, so the
snapshot overhead shows up in the timings.
Refactoring: `Generator`/`PathGetter` previously took a `Coordination::ZooKeeper
&` to resolve `children_of` paths. They now take a `ListChildrenFn` callback;
the existing Runner passes a lambda wrapping the ZooKeeper client, the new
StorageRunner passes a lambda that calls `KeeperStorage::processLocalRequests`.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>