1
0
mirror of https://github.com/facebook/rocksdb.git synced 2026-10-23 08:09:02 +03:00
Files
rocksdb/cache
Peter Dillinger bcda8c4b1a Fix Cache::ApplyToAllEntries ignoring average_entries_per_lock (#15186)
Summary:
`ShardedCache::ApplyToAllEntries()` clamped `average_entries_per_lock` with `std::min(aepl, 1)`, forcing every positive value (including the default 256) down to 1. The intent was a floor of 1 (`std::max`); `ApplyToSomeEntries` even asserts the value is > 0. As a result a full cache traversal advanced a single hash-table slot per iteration step instead of batching ~256, so the documented 256 default never actually took effect. The bug dates to the original API (https://github.com/facebook/rocksdb/issues/8225) and was carried through the ShardedCache refactor (https://github.com/facebook/rocksdb/issues/10801) unchanged, so the intended default was never exercised: in hindsight the "gather stats" latency in the https://github.com/facebook/rocksdb/issues/8225 test plan is a batch-size-1 measurement.

Despite its name, `average_entries_per_lock` is really a batch size for iterating the cache, not something specific to locking: it bounds the work done per uninterrupted step. For a lock-based cache (LRUCache) a shard mutex is held for each batch, so single-entry batches mean many extra lock acquire/release cycles; but lock-free implementations (HyperClockCache) also pay fixed per-batch overhead and benefit from the fix as well. This is a control-path cost (e.g. periodic block cache stats via DumpStats -> CollectCacheEntryStats), not hot-path read/write, so the practical impact is usually minor. The option's doc comment is updated to describe it as a batch size; the field is not renamed given how obscure the option is.

Pull Request resolved: https://github.com/facebook/rocksdb/pull/15186

Test Plan:
No unit test: asserting on batch/lock-acquisition counts would be intrusive/awkward, and LRUCache is disfavored (though not deprecated).

Measured with release-mode cache_bench, comparing the binary built before (`std::min`) vs after (`std::max`); 4 GiB cache, 1 KiB values, ~3.7M entries, default gather_stats_entries_per_lock=256. Average full ApplyToAllEntries traversal latency:

| cache_type              | before  | after   | speedup |
|-------------------------|---------|---------|---------|
| lru_cache               | 2.69 s  | 0.64 s  | ~4.2x   |
| fixed_hyper_clock_cache | 0.441 s | 0.138 s | ~3.2x   |
| auto_hyper_clock_cache  | 0.264 s | 0.136 s | ~1.9x   |

All implementations improve; LRUCache most, due to per-batch mutex acquire/release. HCC traversals are already ~6-10x cheaper than LRU in absolute terms, and entries visited are identical before and after.

Reviewed By: rban1

Differential Revision: D119256456

Pulled By: pdillinger

fbshipit-source-id: e58f7f97d47d8970ebc8c3ab786199132ce6340d
2026-09-09 09:41:06 -07:00
..
2026-02-13 11:56:22 -08:00
2025-10-03 14:28:37 -07:00