Skip to content

Commit 66d4247

Browse files
committed
Revise design documentation for high-performance caches
- Updated terminology to reflect broader application beyond DBMS, emphasizing the importance of workload modeling and memory layout. - Clarified access patterns and cache policies, including roadmap mentions for LRU-K, 2Q, and ARC. - Enhanced sections on concurrency strategy, eviction paths, and scan resistance, aligning with performance goals and design principles. - Improved overall readability and consistency throughout the document.
1 parent 959b037 commit 66d4247

1 file changed

Lines changed: 21 additions & 21 deletions

File tree

docs/design.md

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
Designing high-performance caches for a DBMS in Rust is a multi-disciplinary problem: data structures, memory layout, concurrency, workload modeling, and systems-level performance all matter. The points below reflect what moves the needle in practice.
1+
Designing high-performance caches in Rust is a multi-disciplinary problem: data structures, memory layout, concurrency, workload modeling, and systems-level performance all matter. The points below reflect what moves the needle in practice across systems, services, and libraries.
22

33
## 1. Workload First, Policy Second
44

55
Cache policy only matters relative to workload.
66

77
Identify access patterns:
8-
- OLTP: skewed, hot keys, high churn.
9-
- OLAP: scans, large working sets, weak locality.
10-
- Mixed: bursts of hot data over large cold sets.
8+
- Hotset-heavy traffic: skewed keys, high churn.
9+
- Scan-heavy traffic: large working sets, weak locality.
10+
- Mixed traffic: bursts of hot data over large cold sets.
1111

1212
Measure:
1313
- Reuse distance / stack distance.
@@ -16,14 +16,14 @@ Measure:
1616

1717
Choose policies accordingly:
1818
- LRU: good for temporal locality, bad for scans.
19-
- LRU-K / 2Q: better at filtering one-off accesses.
20-
- Clock / ARC: lower overhead, more adaptive.
19+
- LRU-K / 2Q (roadmap): better at filtering one-off accesses.
20+
- Clock / ARC (roadmap): lower overhead, more adaptive.
2121

22-
Never design a "general purpose" cache first, design for the workload you expect.
22+
Never design a "general purpose" cache first; design for the workload you expect.
2323

2424
## 2. Memory Layout Matters More Than Algorithms
2525

26-
In a DBMS cache, memory layout often dominates policy.
26+
In a cache, memory layout often dominates policy.
2727

2828
Prefer:
2929
- Contiguous storage (Vec, slabs, arenas).
@@ -38,7 +38,7 @@ Techniques:
3838
- Separate hot metadata from cold payloads.
3939
- Use slab allocators for fixed-size entries.
4040

41-
Cache misses caused by your own data structure are as bad as disk misses.
41+
Cache misses caused by your own data structure are as bad as upstream misses.
4242

4343
## 3. Concurrency Strategy Is Core Design, Not a Wrapper
4444

@@ -50,7 +50,7 @@ Options:
5050
- Lock-free or mostly-lock-free: hard in Rust, only worth it if contention dominates.
5151

5252
Rust-specific notes:
53-
- Prefer parking_lot locks over std.
53+
- When `std` is available, prefer `parking_lot` locks over `std::sync` for lower overhead and better ergonomics.
5454
- Avoid Arc<Mutex<...>> in hot paths.
5555
- Consider per-thread caches with periodic merge.
5656
- Consider RCU-style read paths for read-heavy caches.
@@ -80,9 +80,9 @@ If malloc shows up in your flamegraph, your cache is already slow.
8080

8181
Eviction is the critical slow path.
8282

83-
O(1) eviction is mandatory.
83+
O(1) eviction is the goal.
8484

85-
No tree walks, no scanning.
85+
Avoid unbounded tree walks or scans in eviction paths.
8686

8787
Maintain:
8888
- Direct pointers/indices to eviction candidates.
@@ -103,7 +103,7 @@ Track at least:
103103
- Eviction count and reason.
104104
- Insert/update rate.
105105
- Scan pollution rate.
106-
- Lock contention or wait time.
106+
- Lock contention or wait time (roadmap).
107107

108108
Expose:
109109
- Lightweight counters in hot path.
@@ -115,8 +115,8 @@ Metrics should guide design decisions, not justify them afterward.
115115

116116
Design in layers:
117117
- Storage layer: how entries live in memory, allocation, layout, indexing.
118-
- Policy layer: LRU, FIFO, Clock, ARC, etc; only manipulates metadata and ordering.
119-
- Integration layer: ties DB pages, tuples, or segments into cache entries.
118+
- Policy layer: LRU, FIFO, LFU, LRU-K (roadmap: Clock/ARC/2Q, etc; see `docs/policies/roadmap/README.md`); only manipulates metadata and ordering.
119+
- Integration layer: ties application objects, payloads, or IDs into cache entries.
120120

121121
Related docs:
122122
- Policy summaries: `docs/policies.md`
@@ -147,18 +147,18 @@ You can wrap fast internals in nice APIs at the edges.
147147

148148
## 9. Scans Are the Enemy of Caches
149149

150-
In DBMS workloads:
150+
In scan-heavy workloads:
151151

152-
Large table scans destroy LRU-style caches.
152+
Large sequential reads destroy LRU-style caches.
153153

154154
Solutions:
155-
- Scan-resistant policies (2Q, LRU-K, ARC).
156-
- Explicit "scan mode" hints from query planner.
155+
- Scan-resistant policies (LRU-K, 2Q/ARC are roadmap).
156+
- Explicit "scan mode" hints from the caller or workload layer.
157157
- Bypass cache for known one-shot reads.
158158

159159
If you ignore scans, your cache will look great in microbenchmarks and terrible in production.
160160

161-
## 10. Benchmark Like a Database, Not a Library
161+
## 10. Benchmark Like a System, Not a Library
162162

163163
Do not rely on random key benchmarks.
164164

@@ -207,7 +207,7 @@ A cache that collapses under stress is worse than no cache.
207207

208208
## Bottom Line
209209

210-
High-performance DBMS caches are not about clever algorithms—they are about:
210+
High-performance caches are not about clever algorithms—they are about:
211211
- Memory layout.
212212
- Allocation discipline.
213213
- Contention control.

0 commit comments

Comments
 (0)