Skip to content

refactor(bench): isolate external engine comparisons - #8

Merged
farhan-syah merged 2 commits into
NodeDB-Lab:mainfrom
presempathy-awb:fix/isolate-comparison-benchmark
Jul 21, 2026
Merged

refactor(bench): isolate external engine comparisons#8
farhan-syah merged 2 commits into
NodeDB-Lab:mainfrom
presempathy-awb:fix/isolate-comparison-benchmark

Conversation

@presempathy-awb

Copy link
Copy Markdown
Contributor

Summary

This PR moves the native cross-engine benchmarks into an opt-in workspace package so PageDB's ordinary development, test, feature, documentation, and cross-target jobs no longer resolve or compile RocksDB, redb, or SQLite.

PageDB itself keeps the native segment benchmark. The existing btree and comparison workloads remain available under benchmarks/engine-comparison and continue to compare the same engines with the same workload parameters. This is a packaging and CI-boundary change, not a benchmark rewrite.

Problem

The three external engines were unconditional root dev-dependencies. Cargo includes root dev-dependencies in test and benchmark dependency resolution, so commands such as cargo nextest run, cargo clippy --all-targets, and feature-matrix checks pulled in librocksdb-sys even when no comparison benchmark was requested.

That had several undesirable effects:

  • normal PageDB tests paid the RocksDB native build cost;
  • unrelated CI jobs needed Clang/libclang solely because RocksDB's bindings use bindgen;
  • platform and WASM-oriented PageDB checks were coupled to a native comparison dependency they do not exercise;
  • test = false prevented benchmark executables from running as tests, but it could not remove their root dev-dependencies from Cargo's package graph;
  • a future failure in an external comparison engine could block validation of PageDB core behavior.

Design

The root manifest is now a workspace with two deliberately different package boundaries:

  1. pagedb remains the default workspace member and owns the library, tests, binaries, and PageDB-only segment benchmark.
  2. pagedb-engine-comparison is a non-publishable, non-default package that owns the btree and four-engine comparison benchmarks plus their benchmark-only dependencies.

The comparison package declares PageDB, fluxbench, fastrand, tempfile, Tokio, redb, RocksDB, and rusqlite as dev-dependencies. It has no library or production target and is only selected when its benchmark package is named explicitly.

This keeps two distinct concerns visible:

  • PageDB correctness and portability checks validate PageDB without an unrelated native database toolchain.
  • Raw native engine comparisons remain reproducible and reviewable in-tree, but they are opt-in.

Protocol-level, browser-runtime, or storage-plugin comparisons are different semantic workloads and should remain in their respective integration harnesses rather than being conflated with this raw embedded-engine suite.

Changes

Cargo boundary

  • Add a workspace with default-members = ["."].
  • Add the non-publishable benchmarks/engine-comparison package.
  • Move btree.rs and comparison.rs into that package.
  • Remove redb, rocksdb, rusqlite, and the benchmark-only direct fastrand dependency from PageDB's root dev-dependencies.
  • Keep segment.rs as PageDB's only root benchmark target.
  • Update Cargo.lock so the external engines belong to pagedb-engine-comparison, not pagedb.

CI boundary

  • Scope all core lint, documentation, nextest, cross-target, WASM/WASI, feature-matrix, and segment-benchmark commands explicitly to -p pagedb.
  • Remove Clang/libclang installation from lint, test, and feature jobs.
  • Keep Clang/libclang only in the benchmark job that explicitly builds the comparison package.
  • Add a dependency-tree gate that fails if RocksDB, redb, SQLite, or their native sys crates leak back into the PageDB package graph.
  • Continue compiling all three benchmark programs in CI: PageDB's segment plus the isolated btree and comparison targets.

Documentation

  • Update the benchmark reproduction commands.
  • Document why the comparison suite is opt-in and why ordinary PageDB test commands no longer compile the external engines.

Workload preservation

No benchmark case, parameter, engine adapter, comparison group, or measurement configuration was removed.

Both moved Rust files are byte-for-byte identical to upstream after accounting for one documentation-only change in each file: the run command now includes -p pagedb-engine-comparison. Git detects both moves as 99% renames.

The following remain unchanged:

  • B+ tree substrate/security/workload variants;
  • redb parity cases;
  • the PageDB/redb/RocksDB/SQLite phase matrix;
  • preload sizes, key/value sizes, RNG seed, batch size, and scan length;
  • fluxbench annotations and comparison groups;
  • fair-comparison PageDB options and engine setup/teardown behavior.

Verification

Dependency and source-boundary checks:

  • cargo metadata --locked --format-version 1
  • cargo tree -p pagedb --edges normal,build,dev — no RocksDB, redb, rusqlite, librocksdb-sys, or libsqlite3-sys
  • the same gate with all PageDB features — no external-engine matches
  • isolated comparison package tree — all three external engines present as intended
  • clean core target artifact scan — zero RocksDB/redb/SQLite artifacts
  • exact source comparison against upstream after substituting only the documented run command — no diff for either moved benchmark
  • cargo package -p pagedb --allow-dirty --no-verify --list — root package contains benches/segment.rs and excludes the nested comparison package

Core validation:

  • cargo fmt --all --check
  • git diff --check
  • actionlint .github/workflows/test.yml
  • cargo test -p pagedb --lib — 133 passed
  • cargo nextest run -p pagedb --all-features --no-fail-fast — 388 passed
  • feature checks for default, no-default, compression, and all-features — passed
  • cargo doc -p pagedb --no-deps --all-features — passed
  • cargo test -p pagedb --doc --all-features — passed
  • cargo deny --exclude-dev check — passed
  • cargo check -p pagedb --target wasm32-unknown-unknown --lib --features opfs — passed
  • cargo check -p pagedb --target wasm32-wasip1 --lib — passed

Benchmark compilation:

  • cargo bench --no-run -p pagedb --bench segment — passed
  • cargo bench --no-run -p pagedb-engine-comparison --bench btree --bench comparison — passed

Review notes

The PR intentionally does not change benchmark numbers or claim new performance results. Existing tables remain descriptions of the existing workloads; this change only gives those workloads an honest dependency boundary.

The new CI gate is meant to make the architectural constraint durable. If a future PageDB feature genuinely needs one of these engines in core, that should be an explicit design decision accompanied by removal or revision of the gate, rather than an accidental dev-dependency leak.

presempathy-awb and others added 2 commits July 21, 2026 07:15
…olver 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.

@farhan-syah farhan-syah left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solid refactor — gives the comparison engines an honest dependency boundary without touching any workload. Verified the two things a mechanical move could silently break:

  • fastrand removal is safe (dev-only, unused in src/ and in the retained segment bench);
  • the moved benches' tokio runtime features (sync/time/fs for .enable_all() + tokio::sync::Mutex) survive via feature unification through the pagedb path-dep, so no runtime regression despite --no-run.

I pushed one fixup commit (a48863f) with two small hardenings:

  • the leak-check gate now runs cargo tree under both default and --all-features, so a feature-gated engine leak can't slip past;
  • resolver = "3" to match the edition-2024 default (MSRV-aware); cargo metadata --locked confirms Cargo.lock is unchanged.

Gate passes clean locally for both feature sets; cargo fmt --all --check and YAML parse both pass.

@farhan-syah
farhan-syah marked this pull request as ready for review July 21, 2026 13:51
@farhan-syah
farhan-syah merged commit bee32e6 into NodeDB-Lab:main Jul 21, 2026
18 of 19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants