Execution — db-22

How to run everything

# from db-22-performance-and-benchmarking/
bash scripts/verify.sh        # runs Rust, Go, and C++ unit tests
bash scripts/cross_test.sh    # builds 3 binaries, asserts byte-identical hashes

Both scripts end with === OK === or === ALL OK === respectively. They exit non-zero on any mismatch.

Per-language invocation

Rust

cd src/rust
cargo test --release --lib tests              # 9 tests
cargo build --release
./target/release/benchctl hash workload --seed 42 --ops 500 --keys 32 --scenario default
./target/release/benchctl bench workload --seed 1 --ops 100000 --keys 1024 --scenario default

The --release profile is important: the debug build of SplitMix64 is substantially slower because the multiplies aren't inlined.

Go

cd src/go
go test ./...                                 # 9 tests
go build -o /tmp/benchctl_go ./cmd/benchctl
/tmp/benchctl_go hash workload --seed 42 --ops 500 --keys 32 --scenario default
/tmp/benchctl_go bench workload --seed 1 --ops 100000 --keys 1024 --scenario default

C++

cd src/cpp
mkdir -p build && cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build .
./test_db22                                   # 9 tests
./benchctl hash workload --seed 42 --ops 500 --keys 32 --scenario default
./benchctl bench workload --seed 1 --ops 100000 --keys 1024 --scenario default

The CMake file defaults to Release with -O3 -DNDEBUG. The test binary #undefs NDEBUG so its assertions are not stripped.

What the scripts do, step by step

scripts/verify.sh

  1. cd into the lab root.
  2. Run the Rust unit tests under cargo test --release --lib tests. We pass --lib tests so cargo only loads the test module from the library crate; without it cargo prints "0 tests" because it tries to discover integration test binaries that don't exist.
  3. Run the Go unit tests with go test ./....
  4. Configure and build the C++ project under src/cpp/build and run ./test_db22.
  5. Print === OK === on success.

scripts/cross_test.sh

  1. Build all three release binaries.
  2. For each of two frozen scenarios, run benchctl hash workload … in all three implementations, capture stdout (no trailing newline), and compare:
    • The three implementations must agree with each other.
    • They must agree with the golden hash committed in the script.
  3. Print === ALL OK === on success.

CLI shape

benchctl hash  workload --seed N --ops N --keys N --scenario S
benchctl bench workload --seed N --ops N --keys N --scenario S
  • hash prints the SHA-256 hex digest of the final snapshot, with no trailing newline, on stdout.
  • bench writes one line to stderr describing the run; its stdout is empty.

Both commands accept identical flags. --scenario is currently a documentation tag — it does not change behavior but is reserved for future workload variants.

Reproducing the frozen hashes

$ ./target/release/benchctl hash workload --seed 42 --ops 500 --keys 32 --scenario default
4b72eab6cbc773ac9584104c5923a5139b34ab466052bdb8ceacb087c06a9015

$ ./target/release/benchctl hash workload --seed 7 --ops 5000 --keys 256 --scenario default
5c35e7b1507834fda4960246640e6fb0b194b75b9593bec87159eafcbc3876a1

If you ever see a different hash:

  1. Did you change MAGIC, the wire format, the workload mixing rule, or SplitMix64? Any of those will move every hash.
  2. Did you change the decrement semantics? See analysis.md.
  3. Are you iterating a HashMap or unordered_map instead of a sorted structure? That will give you a random hash run to run.