Skip to content

Commit bee32e6

Browse files
refactor(bench): isolate external engine comparisons (#8)
* refactor(bench): isolate external engine comparisons * ci(test): check dependency graph under all-features and switch to resolver v3 Cargo's resolver 2 unifies features across the default and all-features builds, so the CI leak check could miss external engines pulled in only under --all-features. Bumping to resolver 3 keeps builds isolated per feature set, and the workflow now runs the cargo-tree leak check against both the default and --all-features dependency graphs. --------- Co-authored-by: Farhan Syah <bizimpulse@gmail.com>
1 parent 66c5964 commit bee32e6

7 files changed

Lines changed: 85 additions & 60 deletions

File tree

.github/workflows/test.yml

Lines changed: 22 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -46,26 +46,31 @@ jobs:
4646
with:
4747
components: rustfmt, clippy
4848

49-
# The comparison benchmark links rocksdb (librocksdb-sys), whose build
50-
# runs bindgen and needs libclang. clippy --all-targets compiles it.
51-
- name: Install LLVM/Clang
52-
run: sudo apt-get update && sudo apt-get install -y clang libclang-dev
53-
5449
- uses: Swatinem/rust-cache@v2
5550
with:
5651
prefix-key: lint
5752

5853
- name: Check formatting
5954
run: cargo fmt --all --check
6055

56+
- name: Keep external engines out of the PageDB package
57+
run: |
58+
for features in "" "--all-features"; do
59+
if cargo tree -p pagedb $features --edges normal,build,dev --prefix none |
60+
rg -q '^(librocksdb-sys|libsqlite3-sys|redb|rocksdb|rusqlite) v'; then
61+
echo "::error::External comparison engine leaked into the pagedb dependency graph (${features:-default features})."
62+
exit 1
63+
fi
64+
done
65+
6166
- name: Clippy (all targets, all features)
62-
run: cargo clippy --all-targets --all-features -- -D warnings
67+
run: cargo clippy -p pagedb --all-targets --all-features -- -D warnings
6368

6469
- name: Build docs
65-
run: cargo doc --no-deps --all-features
70+
run: cargo doc -p pagedb --no-deps --all-features
6671

6772
- name: Run doctests
68-
run: cargo test --doc --all-features
73+
run: cargo test -p pagedb --doc --all-features
6974

7075
# Enforces the rule in CLAUDE.md: no checklist-letter or build-order
7176
# scaffolding may leak into source / Cargo.toml / README. Greps for
@@ -95,19 +100,6 @@ jobs:
95100
- name: Install Rust
96101
uses: dtolnay/rust-toolchain@stable
97102

98-
# nextest compiles the dev-dependency graph (incl. rocksdb →
99-
# librocksdb-sys → bindgen → libclang). Windows runner images ship LLVM;
100-
# Linux and macOS need it installed.
101-
- name: Install LLVM/Clang (Linux)
102-
if: runner.os == 'Linux'
103-
run: sudo apt-get update && sudo apt-get install -y clang libclang-dev
104-
105-
- name: Install LLVM/Clang (macOS)
106-
if: runner.os == 'macOS'
107-
run: |
108-
brew install llvm
109-
echo "LIBCLANG_PATH=$(brew --prefix llvm)/lib" >> "$GITHUB_ENV"
110-
111103
- uses: Swatinem/rust-cache@v2
112104
with:
113105
prefix-key: test-${{ matrix.os }}
@@ -120,7 +112,7 @@ jobs:
120112
# Always nextest — crash-recovery tests rely on the serial group in
121113
# .config/nextest.toml that `cargo test` ignores.
122114
- name: Run tests
123-
run: cargo nextest run --all-features --no-fail-fast
115+
run: cargo nextest run -p pagedb --all-features --no-fail-fast
124116

125117
- name: Upload nextest report
126118
if: always()
@@ -167,7 +159,7 @@ jobs:
167159
prefix-key: cross-${{ matrix.target }}
168160

169161
- name: cargo check --lib
170-
run: cargo check --target ${{ matrix.target }} --lib
162+
run: cargo check -p pagedb --target ${{ matrix.target }} --lib
171163

172164
# ─────────────────────────────────────────────────────────────────────────
173165
wasm:
@@ -196,7 +188,7 @@ jobs:
196188
prefix-key: wasm-${{ matrix.target }}
197189

198190
- name: cargo check --lib
199-
run: cargo check --target ${{ matrix.target }} --lib ${{ matrix.features }}
191+
run: cargo check -p pagedb --target ${{ matrix.target }} --lib ${{ matrix.features }}
200192

201193
# ─────────────────────────────────────────────────────────────────────────
202194
features:
@@ -216,17 +208,12 @@ jobs:
216208
- name: Install Rust
217209
uses: dtolnay/rust-toolchain@stable
218210

219-
# --benches compiles the comparison bench, which links rocksdb
220-
# (librocksdb-sys) — its build runs bindgen and needs libclang.
221-
- name: Install LLVM/Clang
222-
run: sudo apt-get update && sudo apt-get install -y clang libclang-dev
223-
224211
- uses: Swatinem/rust-cache@v2
225212
with:
226213
prefix-key: features
227214

228215
- name: cargo check
229-
run: cargo check --lib --bins --tests --benches ${{ matrix.flags }}
216+
run: cargo check -p pagedb --lib --bins --tests --benches ${{ matrix.flags }}
230217

231218
# ─────────────────────────────────────────────────────────────────────────
232219
bench:
@@ -238,8 +225,8 @@ jobs:
238225
- name: Install Rust
239226
uses: dtolnay/rust-toolchain@stable
240227

241-
# cargo bench builds the dev-dependency graph (rocksdb → librocksdb-sys
242-
# bindgen → libclang), even when only the btree/segment benches are named.
228+
# The isolated comparison package links RocksDB (librocksdb-sys), whose
229+
# build runs bindgen and needs libclang.
243230
- name: Install LLVM/Clang
244231
run: sudo apt-get update && sudo apt-get install -y clang libclang-dev
245232

@@ -251,7 +238,9 @@ jobs:
251238
# dispatched workflow so we don't pay the runtime on every PR. This
252239
# job catches "the bench no longer compiles" regressions.
253240
- name: Build benches
254-
run: cargo bench --no-run --bench btree --bench segment
241+
run: |
242+
cargo bench --no-run -p pagedb --bench segment
243+
cargo bench --no-run -p pagedb-engine-comparison --bench btree --bench comparison
255244
256245
# ─────────────────────────────────────────────────────────────────────────
257246
audit:

Cargo.lock

Lines changed: 14 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
[workspace]
2+
members = ["benchmarks/engine-comparison"]
3+
default-members = ["."]
4+
resolver = "3"
5+
16
[package]
27
name = "pagedb"
38
version = "0.1.0"
@@ -123,37 +128,22 @@ tokio = { version = "1", features = [
123128
"test-util",
124129
] }
125130
tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt"] }
126-
redb = "2"
127131
tempfile = "3"
128132
aes-gcm = "0.10"
129133
fluxbench = "0.1"
130-
rocksdb = { version = "0.24", default-features = false, features = ["lz4"] }
131-
rusqlite = { version = "0.40", features = ["bundled"] }
132-
fastrand = "2"
133134

134135
[[bin]]
135136
name = "pagedb-fsck"
136137
path = "src/bin/pagedb-fsck.rs"
137138

138-
# `test = false`: these are benchmarks, not tests. Without it, `cargo test`
139-
# (and nextest) compile every `harness = false` bench and run its `main` as a
140-
# test — pulling heavy dev-deps (rocksdb → libclang) into the test build on
141-
# every platform and executing benchmarks during the test run.
142-
[[bench]]
143-
name = "btree"
144-
harness = false
145-
test = false
146-
139+
# These are executable benchmarks, not test harnesses. The cross-engine suite
140+
# is a separate non-default workspace package so normal PageDB tests never
141+
# resolve its RocksDB, redb, or SQLite dependencies.
147142
[[bench]]
148143
name = "segment"
149144
harness = false
150145
test = false
151146

152-
[[bench]]
153-
name = "comparison"
154-
harness = false
155-
test = false
156-
157147
[profile.release]
158148
lto = "thin"
159149
codegen-units = 1

README.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,20 @@ pagedb's answer: **one substrate, two surfaces.** Engines that want their own fo
5757

5858
## Benchmarks
5959

60-
Measured on native NVMe, AES-NI host, single thread, via [`fluxbench`](./benches). Reproduce with:
60+
Measured on native NVMe, AES-NI host, single thread, via `fluxbench`. Reproduce the
61+
PageDB-owned benches and the isolated cross-engine suite with:
6162

6263
```bash
63-
cargo bench --bench btree
64-
cargo bench --bench comparison
6564
cargo bench --bench segment
65+
cargo bench -p pagedb-engine-comparison --bench btree
66+
cargo bench -p pagedb-engine-comparison --bench comparison
6667
```
6768

69+
The comparison suite is a non-default workspace package under
70+
[`benchmarks/engine-comparison`](./benchmarks/engine-comparison). Normal
71+
`cargo test` and `cargo nextest` runs for the `pagedb` package therefore do not
72+
resolve or compile RocksDB, redb, or SQLite.
73+
6874
### vs. redb (B+ tree, in-process)
6975

7076
| Workload | pagedb | redb | Speedup vs redb |
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
[package]
2+
name = "pagedb-engine-comparison"
3+
version = "0.0.0"
4+
edition = "2024"
5+
rust-version = "1.85"
6+
publish = false
7+
license = "MIT OR Apache-2.0"
8+
description = "Benchmark-only cross-engine comparison harness for PageDB"
9+
10+
[dev-dependencies]
11+
fastrand = "2"
12+
fluxbench = "0.1"
13+
pagedb = { path = "../.." }
14+
redb = "2"
15+
rocksdb = { version = "0.24", default-features = false, features = ["lz4"] }
16+
rusqlite = { version = "0.40", features = ["bundled"] }
17+
tempfile = "3"
18+
tokio = { version = "1", features = ["rt", "sync", "time"] }
19+
20+
[[bench]]
21+
name = "btree"
22+
path = "btree.rs"
23+
harness = false
24+
test = false
25+
26+
[[bench]]
27+
name = "comparison"
28+
path = "comparison.rs"
29+
harness = false
30+
test = false
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
//! of the threat model; comparing redb vs `pagedb-plain` isolates the
1010
//! structural cost (CoW shadow paging, AAD, MAC-only, durable reader pins).
1111
//!
12-
//! Run with: `cargo bench --bench btree`
12+
//! Run with: `cargo bench -p pagedb-engine-comparison --bench btree`
1313
1414
#![allow(dead_code)] // verify/synthetic/compare placeholder structs
1515

benches/comparison.rs renamed to benchmarks/engine-comparison/comparison.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//! - individual writes / batch writes: per-txn latency, many samples
1111
//! - random reads / range reads: per-op latency on a preloaded DB
1212
//!
13-
//! Run with: `cargo bench --bench comparison`
13+
//! Run with: `cargo bench -p pagedb-engine-comparison --bench comparison`
1414
1515
#![allow(dead_code)] // verify/synthetic/compare placeholder structs
1616

0 commit comments

Comments
 (0)