diff --git a/.claude/board/entries/2026-11-03-d-global-where-p0.md b/.claude/board/entries/2026-11-03-d-global-where-p0.md new file mode 100644 index 000000000..e1b587d1f --- /dev/null +++ b/.claude/board/entries/2026-11-03-d-global-where-p0.md @@ -0,0 +1,24 @@ +# D-GLOBAL-WHERE P0: direct-routed virtual SoA views across selections, plus the DuckDB parity gate + +**Status:** MEASURED, lab only. No production change. +**Probe:** `.claude/probes/2026-11-03-d-global-where/` (`REPORT.md`; `probe/` with binaries `falsify` and `bench`; `duckdb/` scripts; `results/`). + +**Falsifier: 21/21 checks.** The F4 (DR alignment) and F6 (presence clear) guards were each disabled and turned red. +- Production dt64 DR routing (`LocalMap`, `MapTable::{map, map_at, locate}`, `Frame`) reconciles two selections holding the same global id at different local positions. +- A join on local indices gives 32 against an oracle of 14. +- Deleting an edge leaves the identity resolvable and turns the answer false. +- The XOR consistency check detects a single flipped bit. +- Folds allocate 0 bytes. +- `where_dr3::LocalSelection` projects bit-identically for two methods. Its `SchemaChanged` on a second method is a coupling, not a correctness need; Scope refuses on its own. + +**DuckDB 2.0.0 gate:** 336/336 answers agree; 8 workloads × DR64 / DR256 / multi-tile (16×DR256) × sparse / medium / dense / skewed, at threads 1 and 4. +- Warm best arm: 12/0/0 W/P/L for every workload. +- But DuckDB's fixed per-query cost (~600 µs; 703 µs at 65,536 rows against 12,106 µs at 10M) dominates most warm rows. Those are not claimed as algorithmic wins. +- Work-avoided rows: W4 3-hop on `multi_dense` is 131 µs against 1,500,724 µs; on `multi_skewed` 89 µs against 57,066 µs, where DuckDB builds 3,726,779 join rows for a 1,164 answer. +- Losses: cold on every `multi_*` dataset, and W7 per-call routing. Both come from addressing: `MapTable::locate` reads every listed tile per id. Routing once and reusing costs 5 µs against 650–970 µs. +- Plan choice by cost: `csr` wins W3 everywhere. For W4, `csr` wins on small or sparse data and `front` on medium, dense and skewed. Tile-first never won. + +**OPEN:** +- Scale ≥10M rows, unmeasured on our side. +- Owner: may one selection serve several MethodRefs under one Scope (EXO-46)? +- Owner: is a global → tile index wanted beside `locate`'s ambiguity scan? diff --git a/.claude/board/entries/README.md b/.claude/board/entries/README.md index 04714380d..d052509f5 100644 --- a/.claude/board/entries/README.md +++ b/.claude/board/entries/README.md @@ -25,11 +25,12 @@ index row, (3) no duplicate entry id. Checks 1 and 2 are deliberately opposite directions; the stranding this convention prevents shows up in exactly one of them, never both. -564 entries, 2026-08-06 .. 2026-11-03. +565 entries, 2026-08-06 .. 2026-11-03. | date | entry id | finding | file | |---|---|---|---| | 2026-11-03 | `D-XLOG-META-WIRE-P0` | | [2026-11-03-d-xlog-meta-wire-p0.md](2026-11-03-d-xlog-meta-wire-p0.md) | +| 2026-11-03 | `D-GLOBAL-WHERE` | | [2026-11-03-d-global-where-p0.md](2026-11-03-d-global-where-p0.md) | | 2026-11-03 | `D-DR-FOLD-MAP` | | [2026-11-03-d-dr-fold-map.md](2026-11-03-d-dr-fold-map.md) | | 2026-11-03 | `D-COGNITIVE-POLYFILL` | | [2026-11-03-d-cognitive-polyfill-p0.md](2026-11-03-d-cognitive-polyfill-p0.md) | | 2026-11-03 | `D-BAG-FOLD` | | [2026-11-03-d-bag-fold-witnessed-existential.md](2026-11-03-d-bag-fold-witnessed-existential.md) | diff --git a/.claude/probes/2026-11-03-d-global-where/REPORT.md b/.claude/probes/2026-11-03-d-global-where/REPORT.md new file mode 100644 index 000000000..5a94fe345 --- /dev/null +++ b/.claude/probes/2026-11-03-d-global-where/REPORT.md @@ -0,0 +1,160 @@ +# D-GLOBAL-WHERE P0: direct-routed virtual SoA views across selections + +**Status:** MEASURED, lab only. +- Falsifier `falsify`: 21/21 checks. Two guards were disabled to prove they carry weight: F4 and F6 both go red. +- Benchmark against DuckDB 2.0.0: all 336 answer comparisons agree (168 of ours × threads 1 and 4). +- No production change. dt64, Quack, mask-risc and ndarray are used unchanged. No Gather, no new identity table, no witness store, no per-object allocation. + +Machine: 4 vCPU Intel Xeon @ 2.10 GHz, rustc 1.99.0 release, DuckDB 2.0.0 (Python). + +```sh +cd .claude/probes/2026-11-03-d-global-where/probe +cargo +1.99.0 run --release -q --bin falsify # exit 1 on any failed check +cargo +1.99.0 run --release -q --bin bench -- $OUT # writes datasets + ours.json +python3 -I ../duckdb/bench_duckdb.py $OUT --threads 1,4 --runs 201 +python3 -I ../duckdb/compare.py $OUT # exit 1 on any answer mismatch +``` + +Results are in `results/`: `falsify.log`, `bench.log`, `ours.json`, `duckdb.json`, `compare.log` (full tables), and `explain/` (EXPLAIN ANALYZE for `dr256_medium` and `multi_skewed`). The datasets are deterministic (SplitMix64) and are regenerated by `bench`, not committed. + +## 1. Routing contract: what exists + +| concern | mechanism | where | class | +|---|---|---|---| +| global → local, local → global | `LocalMap::local` (counted binary search) / `LocalMap::global` (pointer-table read) | `dt64/src/dr.rs:604-616` | PRODUCTION | +| a bijection within one tile | `LocalMap::prepare` refuses `Duplicate` and `TooMany` | `dr.rs:567-587` | PRODUCTION | +| identity across tiles | `MapTable::locate(frame, tiles, g)` reads EVERY listed tile and refuses an id held twice (`Ambiguous`) | `dr.rs:950-975` | PRODUCTION | +| tile width from the survivor count | `Axis::for_survivors` (DR64 up to 64, DR256 up to 256, then ⌈n/256⌉ DR256) | `dr.rs:63-69` | PRODUCTION | +| version and frame | `MapTable::map(frame)` replays the layout the frame was sealed under; foreign frame → `Stale(ForeignFrame)`; `map_at` future → `FutureVersion` | `dr.rs:909-930` | PRODUCTION | +| frame currency | `FrameStore::check` names the first revision that moved | `dr.rs:442-462` | PRODUCTION | +| relation presence, one shared map | `xlog::Cube` (`new`, `new_tiled`, `add_edge`/`retire_edge` through a `DeltaLog`) | `xlog/src/cube.rs` | PRODUCTION crate, lab callers | +| Scope / Focus | `Scope { id }`: "Policy, checked as its own guard; never part of frame identity"; `Focus { revision }` | `dr.rs:493-505` | PRODUCTION | +| WHERE → one frame, admission | `where_dr3::project` / `LocalSelection::admit` | `dr-math-binding-probe/src/where_dr3.rs:176, 225` | LAB | +| RelationshipMap / MapPalette / ThoughtMapPaletteBinding | no Rust type with these names (`lance-graph/src/config.rs::RelationshipMapping` is the unrelated Cypher config) | plans D-RMAP-1A | PROPOSED | + +**Answer to the operator's model:** DR already owns exact, bidirectional, versioned routing, and the cross-selection join needs nothing beyond it. +- Two selections that hold the same global Y at different local positions are reconciled through the global id: `global()` on one side, then `local()` or `locate` on the other. +- Comparing local indices directly is wrong. F4 measures it: 32 by local coincidence against an oracle of 14. + +## 2. Falsifier (Case A and Case B), `falsify` + +Fixture: +- A universe of 65,536 ids. +- A relation domain D of 512 ids over two DR256 tiles (the R frame). +- Selection tiles 10 (A, descending order) and 11 (B, ascending order). +- A presence plane over R coordinates. + +| # | check | result | +|---|---|---| +| F0 | Quack `Keep` (`a<50`) = lane oracle at all 65,536 ids | PASS (\|A\|=3296, \|B\|=19584) | +| F1/F2 | G→L→G and L→G→L for 714 ids/locals of tiles 0, 1, 10, 11 | PASS | +| F3 | the same global y has local 1 under A and 156 under B; 14 ids shared | PASS | +| F4 | local-coincidence join = 32 (wrong); DR-aligned = 14 = oracle | PASS; **disable (join by local index) → FAIL** | +| F5/F18 | Case B: x ∈ A in R tile 0, y ∈ B in R tile 1; `row[x] & selB_R ≠ 0` true = oracle; Q (x ∈ A with a B-neighbour) = 23 = oracle | PASS | +| F6 | clear that edge's presence bit: `locate(y)` still Ok, answer false, Q 23 → 22 = oracle | PASS; **disable (bit not cleared) → FAIL** | +| F7 | clear an unrelated edge: Q unchanged | PASS | +| F8/F9 | forward plane XOR transpose(reverse) = 0; one flipped bit → exactly one differing position, at that edge | PASS | +| F10 | historical frame: after a tile-10 replacement, f1 reads the old locals and f2 the new (snapshot replay); coordinates revision moved | PASS | +| F11 | foreign frame → `Stale(ForeignFrame)`; future version → `FutureVersion`; `locate` of the shared id in [10, 11] → `Ambiguous`; one tile → Ok | PASS | +| F12 | foreign-class row axis → `AxisMismatch` | PASS | +| F13a | M1's selection admitted against M2's register (same axis) → `SchemaChanged` | PASS | +| F13b | the projections for M1 and for M2 are bit-identical (truth and slots) | PASS | +| F13c | same method, another Scope → `ScopeChanged` | PASS | +| F14/F15 | the folds of F5 and F7 allocate 0 bytes in 0 calls; no tuple vector | PASS | +| F16 | probe types: no identity store besides MapTable/LocalMap (manual) | PASS (manual) | +| F17 | Boolean one-hop distinct 156 ≠ Bag 2-path count 1095, both = oracle; `bind_dr64(Bag)` → `BagNeedsMultiplicity` | PASS | + +**F13 settles the operator's coupling question.** +- `LocalSelection` couples two concerns: its projected bits depend only on (map, WHERE mask, frame) (13b), yet `admit` also compares the full `MethodSignature` (13a). +- The authorization guard is separate, and the method check is not needed to enforce it: Scope refuses on its own (13c). +- So `SchemaChanged` on a second method over the same axis is an unnecessary coupling for correctness. Whether two MethodRefs may share one selection stays an authorization decision, which Scope already expresses. +- **Caveat:** this is the lab `LocalSelection`; production has no selection type at all (§1). + +## 3. DuckDB parity gate + +**Gate:** parity or better on clearly identified workloads with exact semantic equivalence; every losing workload is recorded with its cause. +- Answers: 336/336 agree. +- DuckDB runs with its normal optimizer at threads 1 and 4, PREPARE/EXECUTE, 201 warm runs. The Python call floor (median 179 µs, `PREPARE f AS SELECT 1`) is subtracted. +- Ours is single-threaded; "warm" includes the WHERE evaluation and the fold. + +### 3.1 What the warm numbers do and do not show + +**DuckDB's fixed cost per query dominates every warm comparison at these sizes.** Measured on the same connection (wall, Python included): +- `SELECT 1`: 93 µs +- `count(*) FROM nodes` (65,536 rows): 297 µs +- `count(*) … WHERE a<50` over 65,536 rows: 703 µs +- the same over 10,000,000 rows: 12,106 µs + +That is roughly 600 µs fixed per query and about 1.2 ns per filtered row. Our W1 (Quack `Count` over the same 65,536-row lane) is 5.7–10.2 µs, about 0.15 ns/row. + +So most warm "wins" (W1, W2, W5a, W7, W7i, W8 on every dataset; most workloads on DR64/DR256) are DuckDB's per-query overhead against an in-process fold. **They are not evidence of algorithmic superiority, and are not claimed as such.** The domain here is at most 4,096 nodes; nothing was measured at the scale where DuckDB's per-row throughput dominates. At 10M rows, our side was not measured (PROBE). + +### 3.2 Where the difference is work avoided, not overhead + +Rows where DuckDB's own engine time is far above its fixed cost. Warm, µs, DuckDB minus floor: + +| dataset | workload | ours (best arm) | DuckDB t=1 | DuckDB t=4 | DuckDB intermediate | +|---|---|---|---|---|---| +| multi_dense (503,921 edges) | W4 3-hop distinct | 130.7 (`front`) | 1,500,724 | 418,289 | — | +| multi_skewed (32,648 edges) | W4 3-hop distinct | 89.2 (`front`) | 57,066 | 56,569 | 3,726,779 join rows for a 1,164 answer (`explain/multi_skewed_W4.txt`) | +| multi_dense | W3 2-hop EXISTS | 7.7 (`csr`) | 29,097 | 17,989 | — | +| multi_dense | W6 bag 2-paths (3,382,676) | 119.3 | 22,726 | 11,379 | — | +| multi_skewed | W3 | 7.6 (`csr`) | 6,767 | 6,391 | — | + +Here the frontier masks never materialize the join, while DuckDB builds and aggregates the intermediate. This is the intended win: work the query never needed. + +### 3.3 Losing workloads and their cause (all recorded) + +| workload | where | ours | DuckDB | cause | +|---|---|---|---|---| +| **cold** (prep + first query) | all 4 `multi_*` datasets, every workload except W1 (counts 8/0/4 and 9/0/3) | 8,746 – 519,891 µs | 1,852 – 35,491 µs (PREPARE + first EXECUTE; load is separate, 40,000 – 117,000 µs) | **addressing**: the presence plane is built with `MapTable::locate` per edge endpoint. `locate` reads every listed tile (16 here) to refuse duplicates, so it costs O(tiles) per id. On `multi_dense` that is about 1M endpoints × 16 binary searches. Including DuckDB's load, ours is lower on sparse/medium/skewed and higher on dense (516 ms vs 98 + 7 ms). | +| W7 `route_each` | `multi_*` | 650 – 970 µs (FAILED-GATE at ≥1000 µs on `multi_skewed`) | 1,488 – 3,328 µs | **addressing**: routing selB (~1,181 ids) costs one `locate` × 16 tiles per id. Routing once and reusing it (`reuse` arm) takes 4.5 – 6.4 µs; that is the arm counted. | +| update (W8 delete) | `multi_dense` (5,039 edges) | 4,822 µs FAILED-GATE (not a loss to DuckDB) | DELETE 9,685 µs (t=1) / 5,787 µs (t=4) | **addressing**: the same per-edge `locate`; over the workspace's 1 ms gate | +| W4 `csr` arm | `multi_dense` | 1,127 µs (FAILED-GATE) | — | **plan choice**: indexed navigation loses to frontier masks on dense data; `front` (131 µs) is the counted arm | + +No warm best-arm workload lost to DuckDB (W/P/L 12/0/0 for every workload at both thread counts). Given §3.1, this does **not** establish general superiority. + +### 3.4 Plan choice by measured cost + +- **W3 (EXISTS 2-hop):** `csr` (indexed DFS with early exit) is fastest on every dataset (0.3 – 10.6 µs). `back` (selection-first backward mask) and `tile` (per-x 2-hop row) are 2 – 60× slower. +- **W4 (3-hop distinct):** `csr` wins on DR64/DR256 and `multi_sparse`. Selection-first frontier masks (`front`) win on `multi_medium`/`multi_dense`/`multi_skewed` (110/131/89 µs against csr 2–14× slower). +- So the operator's three plans each win somewhere, and the choice must be made by measured cost. + - The crossover is fan-out × frontier width. + - Tile-first (`tile`) never won here. + +### 3.5 Allocation and memory + +- `alloc_query` is 0 bytes for every warm arm (`ours.json`). +- The presence plane costs n²/8 bytes: 2 MiB for 4,096 nodes, built at cold time. +- Peak bytes per dataset are in `ours.json`; DuckDB `duckdb_memory()` totals are in `duckdb.json` `mem_bytes`. + +## 4. Verdict + +**ALREADY WORKS** +- Production DR provides exact, bidirectional, versioned, multi-tile routing: `LocalMap`, `MapTable::{map, map_at, locate}`, `Frame`/`FrameStore`, `Axis::for_survivors`. +- A cross-selection reference resolves through the global id with no copied object, no new relation table and no new identity store. Measured: F1–F5, F10, F11, F18. +- Presence change through the relation plane works: F6, F7. +- XOR consistency checking works: F8, F9. +- Quack WHERE → Keep is exact (F0). +- Folds allocate nothing (F14, F15). + +**WIRE NOW** (lab-proven, small) +- Route a selection into the relation frame ONCE per frame and reuse it. +- Every multi-tile loss above is per-id `locate`, never the fold. Routing once is what `reuse` (5 µs vs 650–970 µs) and the Cube's "each id looked up once at construction" already do. + +**OWNER DECISION** +- (a) The coupling in `LocalSelection::admit` (`where_dr3.rs:244`): F13 shows the projection is method-independent and Scope already refuses separately. May one admitted selection serve several MethodRefs under one Scope? (EXO-46) +- (b) Whether a global → tile index (one lookup instead of reading every listed tile) is wanted beside `locate`'s ambiguity scan. + - `locate`'s O(tiles) read is deliberate: it refuses an id held twice. + - The cost it puts on multi-tile cold paths is measured above. +- (c) No production type yet holds a relation presence plane whose two axes come from one frame, outside `Cube` internals. + +**PROBE** +- Throughput at a scale where DuckDB's per-row cost dominates (≥10M rows, wider domains). This is the gate that remains unanswered. +- DR256 multi-tile plane build via `Cube::new_tiled` instead of the probe's own `Plane`. + +**PARK** +- General recursion (EXO-73), non-Boolean Bag expansion beyond the W6 degree product (EXO-108), physical disk prefetch, unrelated runtime work. + +**SKIP** +- Duplicate witnesses, per-object allocation, a second routing store, mask transfers across programs, new Gather operators, complete executor migration. diff --git a/.claude/probes/2026-11-03-d-global-where/SPEC.md b/.claude/probes/2026-11-03-d-global-where/SPEC.md new file mode 100644 index 000000000..800c4676d --- /dev/null +++ b/.claude/probes/2026-11-03-d-global-where/SPEC.md @@ -0,0 +1,215 @@ +# D-GLOBAL-WHERE P0 probe spec (lab only) + +Written by the orchestrator, implemented by workers. Every path is relative to +`/home/user/lg-gw` (worktree on branch `ccr-85acaff0-oszq40-global-where`, cut +from `origin/main` `fb5e2d35b`). No file outside +`.claude/probes/2026-11-03-d-global-where/` may be edited. + +## Hard rules + +- No production change. Consume `lance-graph-dt64`, `lance-graph-quack`, + `lance-graph-mask-risc`, `ndarray::simd` and (for checks 12/13 only) + `dr-math-binding-probe` unchanged. +- No tuple materialization in any fold path. No per-object structs. No new + identity table. No witness store. Probe-local code is labelled LAB. +- Every timing in µs or ns. Our side: any warm or query value >= 1000 µs prints + `FAILED-GATE` beside it (workspace rule). Cold preparation is reported in µs, + and also flagged if >= 1000 µs. +- Deterministic data (SplitMix64, seed 0x9E3779B97F4A7C15). +- Exit status 1 if any falsifier check fails or any answer disagrees with the + scalar oracle. + +## Part 1. `probe/` crate (own `[workspace]`), binary `falsify` + +`probe/Cargo.toml`: package `d-global-where-probe`, edition 2021, `[workspace]` +empty table. Deps (path is from `probe/` to repo `crates/`, i.e. `../../../../crates/...`): +lance-graph-contract, lance-graph-dt64, lance-graph-quack, lance-graph-mask-risc, +dr-math-binding-probe; `ndarray = { git = "https://github.com/AdaWorldAPI/ndarray", +branch = "master", default-features = false, features = ["std"] }`. +Patches exactly as in +`.claude/probes/2026-11-03-d-xlog-meta-wire/probe/Cargo.toml` on branch +`meta-wire-local` (read it with `git show meta-wire-local:`): +`[patch."https://github.com/AdaWorldAPI/lance-graph"] lance-graph-contract = path`, +`[patch."https://github.com/AdaWorldAPI/ndarray"] ndarray = { path = "../../../../../ndarray" }` +(adjust the relative depth: the ndarray checkout is `/home/user/ndarray`). +`[profile.release] debug = 0`. + +A counting global allocator (pattern: `crates/lance-graph-quack/tests/duckdb_differential.rs` +lines 49-75) counting bytes and allocation calls, plus a peak tracker. + +### Fixture + +- Universe: 65,536 global ids. Lanes `a: Vec`, `b: Vec` of length + 65,536, values uniform in 0..1000. +- Selection A = `a < 50` (WHERE(A)), selection B = `b < 300` (WHERE(B)), + evaluated by Quack: `Query { filter: Filter::Cmp(Col(0), Cmp::LtI32(50)), agg: Agg::Rows }` + lowered with `lance_graph_quack::lower`, executed with + `lance_graph_mask_risc::execute_into` over `Planes { n_rows: 65536, masks: &[&live], lanes: &[LaneRef::I32(&a)] }`; + the Keep mask is read from `Scratch::slot` or the Plane per the returned + `Value::Mask(Operand)`. See `crates/lance-graph-xlog/src/lib.rs` `run_lanes`. +- Relation domain D: 512 global ids (two DR256 tiles), chosen pseudo-randomly + from the universe. Edges E: directed set over D, average out-degree 6, no + duplicates. +- `MapTable` (`lance_graph_dt64::dr`): tile 0 and tile 1 hold D split in + halves (relation frame R, `Width::W256`). Tile 10 = selection-A tile: + the members of D with a<50, in DESCENDING global order. Tile 11 = + selection-B tile: members of D with b<300, in ASCENDING global order. + Ensure at least one global id y is in both A and B (force it by setting + lanes for one chosen id) and that its local positions in tiles 10 and 11 + differ (assert). +- Presence plane (LAB): one row mask per R-coordinate (wide coordinate + `ordinal*256 + local` as in `xlog::Cube::new_tiled`), 8 words per row, built + from E via `MapTable::locate(frame, &[0,1], g)`. Also a reverse plane + (column storage of the same edges) for the XOR checks. + +### Checks (print `Fn PASS/FAIL detail`) + +1. G->L->G: for every id in tiles 0, 1, 10, 11: `global(local(g)) == g`. +2. L->G->L: for every local l of each tile: `local(global(l)) == l`. +3. the shared y has different locals in tile 10 vs 11. +4. Local-coincidence join (treat B-local bit l as R... no: treat A-local and + B-local positions as one domain, i.e. intersect the tile-10 local mask with + the tile-11 local mask bitwise) gives a count != oracle |A ∩ B ∩ D|; the + DR-aligned path (B-local -> global via tile 11 -> tile 10 local via + `local()`) gives the oracle. Assert both. +5. Case B: pick x in A, y in B with edge (x,y) in E (force one). Route x via + R frame, route B's selection into R coordinates (B-local -> global -> + `locate`), answer `row[x] & selB_R != 0` is true; oracle agrees. +6. Clear that edge's presence bit (LAB plane update, one word): `locate` of y + still Ok, answer now false (when y was x's only B-neighbour; construct the + fixture so it is). Oracle over E minus that edge agrees. +7. Clear an unrelated edge (both endpoints outside A and B): answer of a + fixed query set (count of x in A with a B-neighbour) unchanged. +8. Forward plane XOR transpose(reverse plane) == 0 over all words. +9. Flip one bit in the reverse plane: XOR != 0 and the differing position is + exactly that edge. +10. Historical frame: seal frame f1, then `MapTable::advance` replacing tile 10 + with a reordered map (a replacement, new generation). `map(&f1, 10)` + still returns the OLD locals (snapshot replay), `map(&f2, 10)` the new; + `FrameStore`-style currency: `table.revisions()` coordinates changed. +11. Stale/foreign: a frame sealed by a second MapTable read against the first + -> `MapRead::Stale(ForeignFrame)`; `map_at(future version)` -> + `FutureVersion`; `locate` of an id in two listed tiles -> `Ambiguous` + (list tiles 10 and 11 with the shared y). +12+13. Using `dr_math_binding_probe::where_dr3` with its own 64-slot + `hhtl16::LocalMap` and `FrameStore`s (read that module and + `crates/dr-math-binding-probe/tests/` for how a test builds `Under`, + `Guards`, `BoundDr64` via `bind_dr64`): + project one global WHERE mask once for method M1 (owner class C, + ordinal 1) and once for M2 (class C, ordinal 2, same row axis). + (12) admit with a register of a foreign class on the row axis -> + `AxisMismatch`; (13a) admit M1's selection against M2's register -> + `SchemaChanged`; (13b) the two projections' `Admitted::truth()` and + `slots()` are identical bit for bit (projection does not depend on the + method); (13c) admit with a different `Scope` -> `ScopeChanged` + (the authorization guard exists independently of the method check). +14. Fold path allocation: around the check-5 and check-7 folds (after + preparation), allocated bytes == 0 and no tuple vector exists. Report. +15. Same measurement documents "no per-object allocation". +16. Structural: print the list of types the probe defines; assert none stores + identities except via `LocalMap`/`MapTable` (manual: print only). +17. Boolean vs bag: on E, `count distinct y reachable from A in one hop` + (popcount of OR of A rows) differs from bag count of 2-paths from A + (Σ_y indegA[y]·outdeg[y], `ndarray::simd::checked_binary_i64` or checked + i64), both equal their oracles; `bind_dr64` with + `Population::Bag` -> `BagNeedsMultiplicity`. +18. Multi-tile: the R frame spans 2 DR256 tiles; check 5 must have x and y in + different R tiles (assert ordinals differ). + +Print a census line: per check, lookups (`TileMap::lookups`), bytes allocated. + +## Part 2. binary `bench` (same crate) + +Generate datasets and write them to `$OUT` (arg 1, a directory) as CSV, then +run our side and write `$OUT/ours.json`. + +Datasets: for each `size` in {dr64: 64, dr256: 256, multi: 4096 (16 DR256 tiles)} +× `dist` in {sparse: out-degree ~1 uniform, medium: ~8 uniform, +dense: p = 0.25 for dr64/dr256 and p = 0.03 for multi (state this), +skewed: Zipf-like, node i (by a random rank) gets out-degree ∝ 1/(rank+1) +scaled to total 8·n, targets drawn with the same Zipf bias}. +Domain ids: `size` pseudo-random globals from 0..65536. Universe nodes table: +65,536 rows `id,a,b` (a,b uniform 0..1000; same lanes for every dataset is +fine). Edges only inside the domain. + +Files per dataset `_`: `nodes.csv` (shared, written once: +`id,a,b`), `_edges.csv` (`src,dst`), `_selA.csv`, `_selB.csv` +(id lists: domain members with a<50 resp. b<300, written in the order of their +selection tiles), `_delete.csv` (the 1% edges deleted in W8, at least 1). + +Workloads and their exact SQL semantics (the Python side uses identical SQL): +- W1 `SELECT count(*) FROM nodes WHERE a < 50` +- W2 `SELECT count(*) FROM nodes n WHERE n.a < 50 AND EXISTS (SELECT 1 FROM edges e JOIN nodes m ON m.id = e.dst WHERE e.src = n.id AND m.b < 300)` +- W3 `SELECT count(*) FROM nodes n WHERE n.a < 50 AND EXISTS (SELECT 1 FROM edges e1 JOIN edges e2 ON e2.src = e1.dst JOIN nodes m ON m.id = e2.dst WHERE e1.src = n.id AND m.b < 300)` +- W4 `SELECT count(DISTINCT e3.dst) FROM nodes n JOIN edges e1 ON e1.src = n.id JOIN edges e2 ON e2.src = e1.dst JOIN edges e3 ON e3.src = e2.dst JOIN nodes m ON m.id = e3.dst WHERE n.a < 50 AND m.b < 300` +- W5a `SELECT count(DISTINCT e.dst) FROM edges e JOIN nodes n ON n.id = e.src WHERE n.a < 50` +- W6 `SELECT count(*) FROM edges e1 JOIN edges e2 ON e2.src = e1.dst JOIN nodes n ON n.id = e1.src WHERE n.a < 50` +- W7 `SELECT count(*) FROM selA s WHERE EXISTS (SELECT 1 FROM edges e JOIN selB t ON t.id = e.dst WHERE e.src = s.id)` plus W7i `SELECT count(*) FROM selA JOIN selB USING (id)` +- W8: W2 repeated, then delete the rows of `delete.csv`, then W2 again. + +Our side per dataset, single thread: +- cold: build `MapTable` tiles over the domain (`Axis::for_survivors(size)`), + presence plane (forward rows), outdeg (popcount per row); time it. +- WHERE: two arms, timed separately: (W-q) Quack Keep over the 65,536-row lane + then project to domain coordinates via `TileMap::globals()` (size probes); + (W-v) virtual: test the predicate only at the domain's globals + (`a[g] < 50` for g in the map), building the domain mask directly. Assert + equal masks. W1 uses Quack `Agg::Count` over the full lane. +- Fold per workload, plans as named arms where more than one exists: + W2: any(row[x] & selB) per x in selA. + W3: `back` (selection-first backward: Yb = {y : row[y] & selB != 0}, then + count x in A with row[x] & Yb != 0), `tile` (per x in A: R2 = OR of rows of + row[x]'s members, test & selB), `csr` (CSR adjacency built at cold time, + DFS with early exit). + W4: `front` (frontier F=selA; 3× F = OR rows of F; popcount(F & selB)), + `csr` (BFS over CSR with a visited bitmap per level). + W5: support = popcount(OR rows of A). + W6: indegA[y] via per-row bit iteration over x in A, Σ indegA·outdeg, checked i64. + W7: route selB (tile-11 local order) -> domain coordinates via global id + (`global()` then `local()`/`locate`), time routing separately and as warm + reuse (routing done once, reused); then W2-style fold; W7i = popcount of the + intersection after routing. + W8: warm W2 median; update = clear presence bits for delete.csv (time it); + re-run W2. +- Warm: median and p10/p90 of 201 runs each (std::hint::black_box). Cold: + first-run time of prep + WHERE + fold. Record allocation bytes per stage. +- Correctness: every answer checked against a scalar oracle over the edge + list (HashSet-based is fine in the oracle only). + +`ours.json`: array of records +`{dataset, size, dist, edges, workload, arm, answer, cold_us, warm_med_us, +warm_p10_us, warm_p90_us, where_q_us, where_v_us, route_us, fold_us, +update_us, alloc_bytes_prep, alloc_bytes_query, peak_bytes, interm_cardinality}` +(null where not applicable). + +## Part 3. `duckdb/bench_duckdb.py` (lab script, Python, run with `python3 -I`) + +Arg 1: the `$OUT` directory. For each dataset: fresh in-memory connection; +`SET threads=T` for T in {1, 4}; load CSVs into tables `nodes`, `edges`, +`selA`, `selB` with `read_csv` and explicit types (INTEGER). Normal optimizer +(no pragmas disabling anything). + +Per workload: `PREPARE q AS `; cold = wall time of PREPARE + first +`EXECUTE q` (perf_counter_ns); warm = median/p10/p90 of 201 `EXECUTE q` +fetching the scalar. Also with `PRAGMA enable_profiling='json'` + +`PRAGMA profiling_output=''` on ONE extra execution, read `latency` +(seconds) from the JSON for the engine-side time. Measure the Python floor: +median of 201 `EXECUTE` of `PREPARE f AS SELECT 1`. Save +`EXPLAIN ANALYZE ` text for every workload of the `dr256_medium` and +`multi_skewed` datasets at T=1 to `$OUT/explain/`. W8: DELETE via +`DELETE FROM edges WHERE (src,dst) IN (SELECT src,dst FROM del)` timed, then +re-execute. Peak memory: `SELECT sum(memory_usage_bytes) FROM duckdb_memory()` +after each workload. + +Write `$OUT/duckdb.json` with records `{dataset, threads, workload, answer, +cold_us, warm_med_us, warm_p10_us, warm_p90_us, engine_us, floor_us, +update_us, mem_bytes}`. + +## Part 4. `duckdb/compare.py` + +Join ours.json and duckdb.json on (dataset, workload); assert answers equal +(exit 1 otherwise); for each ours arm and DuckDB T in {1,4} print a Markdown +table: warm ours (best arm and each arm), DuckDB warm wall, DuckDB warm minus +floor, DuckDB engine latency, ratio DuckDB/ours (>1 = ours faster), cold both +sides, and a verdict column WIN / PARITY (within ±10%) / LOSS. Write +`$OUT/compare.md`. diff --git a/.claude/probes/2026-11-03-d-global-where/duckdb/bench_duckdb.py b/.claude/probes/2026-11-03-d-global-where/duckdb/bench_duckdb.py new file mode 100644 index 000000000..7ac315f0e --- /dev/null +++ b/.claude/probes/2026-11-03-d-global-where/duckdb/bench_duckdb.py @@ -0,0 +1,255 @@ +#!/usr/bin/env python3 +"""D-GLOBAL-WHERE P0 probe, DuckDB side (Part 3 of SPEC.md). + +LAB SCRIPT. Not production code, not part of any build or CI gate. It measures +DuckDB (python package, in-memory, normal optimizer, no disabled passes) on the +same datasets and the same SQL as the Rust `bench` binary, and writes +`$OUT/duckdb.json` for `compare.py`. + +Run: python3 -I bench_duckdb.py [--threads 1,4] [--runs 201] + [--datasets dr64_sparse,dr256_medium] + +Procedure (one fresh in-memory connection per dataset x threads x workload, so +every cold figure is a real cold one and W8's DELETE cannot leak into other +workloads): + 1. `SET threads=T`; load nodes/edges/selA/selB/del from the CSVs with + `read_csv` and explicit INTEGER types; `ANALYZE` (supported by DuckDB 2.0.0). + load_us = CSV load + ANALYZE, reported separately from cold. + 2. cold_us = wall time of `PREPARE q AS ` + first `EXECUTE q` (fetchone). + 3. warm = median / p10 / p90 of RUNS (default 201) `EXECUTE q` + fetchone(). + 4. engine_us: one extra EXECUTE with JSON profiling on; the value is + `query.total_time` (seconds) converted to microseconds. DuckDB 2.0.0 has + NO top-level `latency` field in its JSON profile (top-level keys are io, + operator, optimizer, physical_planner, planner, query, system), so + `query.total_time` is the whole-statement engine time, found by inspecting + a real profile file. + 5. floor_us = median of RUNS `EXECUTE f` for `PREPARE f AS SELECT 1` + (python call + fetch overhead, measured on the same connection). + 6. mem_bytes = sum(memory_usage_bytes) FROM duckdb_memory() after the workload. + 7. T=1 only, datasets dr256_medium and multi_skewed: `EXPLAIN ANALYZE ` + text goes to $OUT/explain/_.txt. + 8. W8: warm W2, time `DELETE FROM edges WHERE (src, dst) IN (SELECT src, dst + FROM del)` (update_us), warm W2 again. Record "W8" (before delete, with + update_us) and "W8_after". + +All times are microseconds. CSV header detection is automatic (first token of +the first line non-numeric => header=true). +""" +import json +import os +import statistics +import sys +import tempfile +import time + +import duckdb + +# Exact SQL from SPEC.md Part 2; quoted verbatim by the report. +SQL = { + "W1": "SELECT count(*) FROM nodes WHERE a < 50", + "W2": "SELECT count(*) FROM nodes n WHERE n.a < 50 AND EXISTS (SELECT 1 FROM edges e JOIN nodes m ON m.id = e.dst WHERE e.src = n.id AND m.b < 300)", + "W3": "SELECT count(*) FROM nodes n WHERE n.a < 50 AND EXISTS (SELECT 1 FROM edges e1 JOIN edges e2 ON e2.src = e1.dst JOIN nodes m ON m.id = e2.dst WHERE e1.src = n.id AND m.b < 300)", + "W4": "SELECT count(DISTINCT e3.dst) FROM nodes n JOIN edges e1 ON e1.src = n.id JOIN edges e2 ON e2.src = e1.dst JOIN edges e3 ON e3.src = e2.dst JOIN nodes m ON m.id = e3.dst WHERE n.a < 50 AND m.b < 300", + "W5a": "SELECT count(DISTINCT e.dst) FROM edges e JOIN nodes n ON n.id = e.src WHERE n.a < 50", + "W6": "SELECT count(*) FROM edges e1 JOIN edges e2 ON e2.src = e1.dst JOIN nodes n ON n.id = e1.src WHERE n.a < 50", + "W7": "SELECT count(*) FROM selA s WHERE EXISTS (SELECT 1 FROM edges e JOIN selB t ON t.id = e.dst WHERE e.src = s.id)", + "W7i": "SELECT count(*) FROM selA JOIN selB USING (id)", +} +DELETE_SQL = "DELETE FROM edges WHERE (src, dst) IN (SELECT src, dst FROM del)" +# W8 uses the W2 text; its SQL is SQL["W2"] plus DELETE_SQL. +WORKLOADS = ["W1", "W2", "W3", "W4", "W5a", "W6", "W7", "W7i", "W8"] +EXPLAIN_DATASETS = {"dr256_medium", "multi_skewed"} + + +def us(ns): + return round(ns / 1000.0, 3) + + +def pct(sorted_vals, p): + i = min(len(sorted_vals) - 1, max(0, int(round(p * (len(sorted_vals) - 1))))) + return sorted_vals[i] + + +def stats(vals): + s = sorted(vals) + return statistics.median(s), pct(s, 0.10), pct(s, 0.90) + + +def has_header(path): + with open(path) as f: + first = f.readline().split(",")[0].strip() + try: + int(first) + return False + except ValueError: + return True + + +def q(path): + return path.replace("'", "''") + + +def load(con, out, ds): + """Create the five tables; returns load time in microseconds (incl. ANALYZE).""" + t0 = time.perf_counter_ns() + nodes = os.path.join(out, "nodes.csv") + spec = [ + ("nodes", nodes, "{'id':'INTEGER','a':'INTEGER','b':'INTEGER'}"), + ("edges", os.path.join(out, f"{ds}_edges.csv"), "{'src':'INTEGER','dst':'INTEGER'}"), + ("selA", os.path.join(out, f"{ds}_selA.csv"), "{'id':'INTEGER'}"), + ("selB", os.path.join(out, f"{ds}_selB.csv"), "{'id':'INTEGER'}"), + ("del", os.path.join(out, f"{ds}_delete.csv"), "{'src':'INTEGER','dst':'INTEGER'}"), + ] + for name, path, cols in spec: + hdr = "true" if has_header(path) else "false" + con.execute( + f"CREATE TABLE {name} AS SELECT * FROM read_csv('{q(path)}', header={hdr}, columns={cols})" + ) + con.execute("ANALYZE") + return us(time.perf_counter_ns() - t0) + + +def mem_bytes(con): + r = con.execute("SELECT sum(memory_usage_bytes) FROM duckdb_memory()").fetchone()[0] + return int(r) if r is not None else None + + +def timed_exec(con, name, runs): + """`runs` timed EXECUTEs; returns (answer, [ns]).""" + out = [] + ans = None + stmt = f"EXECUTE {name}" + for _ in range(runs): + t0 = time.perf_counter_ns() + ans = con.execute(stmt).fetchone()[0] + out.append(time.perf_counter_ns() - t0) + return ans, out + + +def engine_us(con, name, tmpdir): + path = os.path.join(tmpdir, "profile.json") + if os.path.exists(path): + os.remove(path) + con.execute("PRAGMA enable_profiling='json'") + con.execute(f"PRAGMA profiling_output='{q(path)}'") + con.execute(f"EXECUTE {name}").fetchone() + con.execute("PRAGMA disable_profiling") + with open(path) as f: + prof = json.load(f) + return round(prof["query"]["total_time"] * 1e6, 3) + + +def floor_us(con, runs): + con.execute("PREPARE f AS SELECT 1") + _, ns = timed_exec(con, "f", runs) + con.execute("DEALLOCATE f") + return us(statistics.median(ns)) + + +def measure(con, sql, runs, tmpdir): + """cold + warm + engine for one SQL on an already loaded connection.""" + t0 = time.perf_counter_ns() + con.execute(f"PREPARE q AS {sql}") + ans = con.execute("EXECUTE q").fetchone()[0] + cold = us(time.perf_counter_ns() - t0) + ans2, ns = timed_exec(con, "q", runs) + assert ans == ans2, f"answer changed between cold and warm: {ans} vs {ans2}" + med, p10, p90 = stats(ns) + eng = engine_us(con, "q", tmpdir) + return ans, cold, us(med), us(p10), us(p90), eng + + +def warm_only(con, sql, runs, tmpdir, name): + con.execute(f"PREPARE {name} AS {sql}") + t0 = time.perf_counter_ns() + first = con.execute(f"EXECUTE {name}").fetchone()[0] + cold = us(time.perf_counter_ns() - t0) + ans, ns = timed_exec(con, name, runs) + assert first == ans + med, p10, p90 = stats(ns) + return ans, cold, us(med), us(p10), us(p90), engine_us(con, name, tmpdir) + + +def rec(ds, T, wl, vals, floor, upd, mem, load_us): + ans, cold, med, p10, p90, eng = vals + return { + "dataset": ds, "threads": T, "workload": wl, "answer": ans, + "cold_us": cold, "warm_med_us": med, "warm_p10_us": p10, "warm_p90_us": p90, + "engine_us": eng, "floor_us": floor, "update_us": upd, "mem_bytes": mem, + "load_us": load_us, + } + + +def run_one(out, ds, T, wl, runs, tmpdir): + con = duckdb.connect(":memory:") + con.execute(f"SET threads={T}") + load_us = load(con, out, ds) + records = [] + if wl != "W8": + sql = SQL[wl] + if T == 1 and ds in EXPLAIN_DATASETS: + txt = con.execute(f"EXPLAIN ANALYZE {sql}").fetchall()[0][1] + os.makedirs(os.path.join(out, "explain"), exist_ok=True) + with open(os.path.join(out, "explain", f"{ds}_{wl}.txt"), "w") as f: + f.write(f"-- {sql}\n{txt}\n") + vals = measure(con, sql, runs, tmpdir) + fl = floor_us(con, runs) + records.append(rec(ds, T, wl, vals, fl, None, mem_bytes(con), load_us)) + else: + sql = SQL["W2"] + vals = measure(con, sql, runs, tmpdir) + t0 = time.perf_counter_ns() + con.execute(DELETE_SQL) + upd = us(time.perf_counter_ns() - t0) + fl = floor_us(con, runs) + records.append(rec(ds, T, "W8", vals, fl, upd, mem_bytes(con), load_us)) + after = warm_only(con, sql, runs, tmpdir, "q_after") + records.append(rec(ds, T, "W8_after", after, fl, None, mem_bytes(con), load_us)) + con.close() + return records + + +def discover(out): + names = sorted(f[: -len("_edges.csv")] for f in os.listdir(out) if f.endswith("_edges.csv")) + return names + + +def main(argv): + if len(argv) < 2 or argv[1].startswith("-"): + print(__doc__) + return 2 + out = argv[1] + threads = [1, 4] + runs = 201 + only = None + i = 2 + while i < len(argv): + if argv[i] == "--threads": + threads = [int(x) for x in argv[i + 1].split(",")] + elif argv[i] == "--runs": + runs = int(argv[i + 1]) + elif argv[i] == "--datasets": + only = set(argv[i + 1].split(",")) + else: + print("unknown arg", argv[i]) + return 2 + i += 2 + datasets = [d for d in discover(out) if only is None or d in only] + if not datasets: + print("no *_edges.csv found in", out) + return 2 + records = [] + with tempfile.TemporaryDirectory() as tmpdir: + for ds in datasets: + for T in threads: + for wl in WORKLOADS: + records.extend(run_one(out, ds, T, wl, runs, tmpdir)) + print(f"{ds} threads={T} done", flush=True) + with open(os.path.join(out, "duckdb.json"), "w") as f: + json.dump(records, f, indent=1) + print(f"wrote {len(records)} records to {os.path.join(out, 'duckdb.json')}") + return 0 + + +if __name__ == "__main__": + sys.exit(main(sys.argv)) diff --git a/.claude/probes/2026-11-03-d-global-where/duckdb/compare.py b/.claude/probes/2026-11-03-d-global-where/duckdb/compare.py new file mode 100644 index 000000000..13bb9dfc1 --- /dev/null +++ b/.claude/probes/2026-11-03-d-global-where/duckdb/compare.py @@ -0,0 +1,181 @@ +#!/usr/bin/env python3 +"""D-GLOBAL-WHERE P0 probe: join ours.json with duckdb.json (Part 4 of SPEC.md). + +LAB SCRIPT. Not production code. + +Run: python3 -I compare.py (reads ours.json + duckdb.json, + writes compare.md, prints it) + +Exit status 1 if any answer disagrees (every ours arm vs DuckDB at both thread +counts), with the mismatching rows printed. Exit 2 on unreadable input. + +All times are microseconds. Ratios are DuckDB / ours, so > 1 means ours is +faster. Verdict thresholds on the ratio: WIN > 1.10, PARITY 0.90..1.10, +LOSS < 0.90. + * wall verdict : (duckdb warm - python floor) / ours warm median + * engine verdict : duckdb engine latency (profile query.total_time) / ours warm median + * cold verdict : duckdb cold (PREPARE + first EXECUTE) / ours cold. DuckDB's + load_us (CSV load + ANALYZE) is reported separately in its own column and + is NOT part of the cold comparison; ours cold is prep + WHERE + fold. +Ours warm values >= 1000 us carry FAILED-GATE (workspace rule: no ms results). +Workload names are identical in both files (W1 W2 W3 W4 W5a W6 W7 W7i W8 W8_after). +""" +import json +import os +import sys +from collections import defaultdict + + +def load(path): + try: + with open(path) as f: + return json.load(f) + except (OSError, ValueError) as e: + print(f"cannot read {path}: {e}", file=sys.stderr) + sys.exit(2) + + +def verdict(ratio): + if ratio is None: + return "n/a" + if ratio > 1.10: + return "WIN" + if ratio >= 0.90: + return "PARITY" + return "LOSS" + + +def ratio(num, den): + if num is None or den is None or den <= 0: + return None + return num / den + + +def fmt(v, gate=False): + if v is None: + return "-" + s = f"{v:.1f}" + if gate and v >= 1000: + s += " FAILED-GATE" + return s + + +def fr(r): + return "-" if r is None else f"{r:.2f}" + + +def wl_order(w): + order = ["W1", "W2", "W3", "W4", "W5a", "W6", "W7", "W7i", "W8", "W8_after"] + return order.index(w) if w in order else len(order) + + +def main(argv): + if len(argv) != 2: + print(__doc__) + return 2 + out = argv[1] + ours = load(os.path.join(out, "ours.json")) + dd = load(os.path.join(out, "duckdb.json")) + + ours_by = defaultdict(list) # (dataset, workload) -> [arm records] + for r in ours: + ours_by[(r["dataset"], r["workload"])].append(r) + dd_by = {(r["dataset"], r["threads"], r["workload"]): r for r in dd} + threads = sorted({r["threads"] for r in dd}) + + mismatches = [] + notes = [] + rows = defaultdict(list) # threads -> table rows + summary = defaultdict(lambda: defaultdict(lambda: defaultdict(int))) + # summary[(threads, kind)][workload][verdict] + + keys = sorted({(r["dataset"], r["workload"]) for r in dd}, + key=lambda k: (k[0], wl_order(k[1]))) + for ds, wl in keys: + arms = ours_by.get((ds, wl)) + if not arms: + notes.append(f"no ours record for {ds} {wl}") + continue + for T in threads: + d = dd_by.get((ds, T, wl)) + if d is None: + notes.append(f"no duckdb record for {ds} threads={T} {wl}") + continue + for a in arms: + if a.get("answer") is None: + notes.append(f"ours answer missing: {ds} {wl} arm={a.get('arm')}") + elif a["answer"] != d["answer"]: + mismatches.append((ds, wl, a.get("arm"), T, a["answer"], d["answer"])) + floor = d.get("floor_us") or 0.0 + net = max(d["warm_med_us"] - floor, 0.0) + best = min(arms, key=lambda a: a["warm_med_us"]) + candidates = [(a.get("arm"), a) for a in arms] + if len(arms) > 1: + candidates.append(("best:" + str(best.get("arm")), best)) + for label, a in candidates: + o = a["warm_med_us"] + r_wall = ratio(net, o) + r_eng = ratio(d.get("engine_us"), o) + r_cold = ratio(d.get("cold_us"), a.get("cold_us")) + rows[T].append((ds, wl, label, a, d, net, r_wall, r_eng, r_cold)) + if label == candidates[-1][0]: + # summary uses the best arm (the only arm if single) + summary[(T, "wall")][wl][verdict(r_wall)] += 1 + summary[(T, "engine")][wl][verdict(r_eng)] += 1 + summary[(T, "cold")][wl][verdict(r_cold)] += 1 + + lines = ["# D-GLOBAL-WHERE: ours vs DuckDB", "", + "Microseconds throughout. Ratio = DuckDB / ours (> 1 means ours faster). " + "WIN > 1.10, PARITY 0.90..1.10, LOSS < 0.90. " + "`ours warm` >= 1000 us is flagged FAILED-GATE. " + "DuckDB `load` (CSV load + ANALYZE) is reported separately and is not part of the cold ratio.", ""] + hdr = ("| dataset | workload | ours arm | ours warm med | ours cold | DuckDB warm | DuckDB warm-floor " + "| DuckDB engine | DuckDB cold | DuckDB load | ratio wall | verdict wall " + "| ratio engine | verdict engine | ratio cold | verdict cold |") + sep = "|" + "---|" * 16 + for T in threads: + lines += [f"## DuckDB threads={T}", "", hdr, sep] + for ds, wl, label, a, d, net, rw, re_, rc in rows[T]: + lines.append( + f"| {ds} | {wl} | {label} | {fmt(a['warm_med_us'], True)} | {fmt(a.get('cold_us'))} " + f"| {fmt(d['warm_med_us'])} | {fmt(net)} | {fmt(d.get('engine_us'))} " + f"| {fmt(d.get('cold_us'))} | {fmt(d.get('load_us'))} " + f"| {fr(rw)} | {verdict(rw)} | {fr(re_)} | {verdict(re_)} | {fr(rc)} | {verdict(rc)} |") + lines.append("") + + lines += ["## Summary: verdict counts across datasets (best arm per workload)", ""] + for T in threads: + lines += [f"### threads={T}", "", "| workload | wall W/P/L | engine W/P/L | cold W/P/L |", "|---|---|---|---|"] + wls = sorted({w for k in summary if k[0] == T for w in summary[k]}, key=wl_order) + for w in wls: + cells = [] + for kind in ("wall", "engine", "cold"): + c = summary[(T, kind)][w] + cells.append(f"{c['WIN']}/{c['PARITY']}/{c['LOSS']}") + lines.append(f"| {w} | " + " | ".join(cells) + " |") + lines.append("") + + if notes: + lines += ["## Notes", ""] + [f"- {n}" for n in notes] + [""] + if mismatches: + lines += ["## ANSWER MISMATCHES", "", "| dataset | workload | ours arm | duckdb threads | ours answer | duckdb answer |", "|---|---|---|---|---|---|"] + for m in mismatches: + lines.append("| " + " | ".join(str(x) for x in m) + " |") + lines.append("") + else: + lines += ["All compared answers agree.", ""] + + text = "\n".join(lines) + with open(os.path.join(out, "compare.md"), "w") as f: + f.write(text) + print(text) + if mismatches: + print(f"\nFAIL: {len(mismatches)} answer mismatch(es)", file=sys.stderr) + for m in mismatches: + print("MISMATCH dataset=%s workload=%s arm=%s duckdb_threads=%s ours=%s duckdb=%s" % m, file=sys.stderr) + return 1 + return 0 + + +if __name__ == "__main__": + sys.exit(main(sys.argv)) diff --git a/.claude/probes/2026-11-03-d-global-where/probe/Cargo.toml b/.claude/probes/2026-11-03-d-global-where/probe/Cargo.toml new file mode 100644 index 000000000..c52fca021 --- /dev/null +++ b/.claude/probes/2026-11-03-d-global-where/probe/Cargo.toml @@ -0,0 +1,27 @@ +# D-GLOBAL-WHERE P0 probe: global WHERE selections, DR-routed folds. +# Lab only. Own [workspace]; the root workspace never builds it. Consumes +# dt64, quack, mask-risc and dr-math-binding-probe unchanged. +[package] +name = "d-global-where-probe" +version = "0.0.0" +edition = "2021" +publish = false + +[dependencies] +lance-graph-contract = { path = "../../../../crates/lance-graph-contract" } +lance-graph-dt64 = { path = "../../../../crates/lance-graph-dt64" } +lance-graph-quack = { path = "../../../../crates/lance-graph-quack" } +lance-graph-mask-risc = { path = "../../../../crates/lance-graph-mask-risc" } +dr-math-binding-probe = { path = "../../../../crates/dr-math-binding-probe" } +ndarray = { git = "https://github.com/AdaWorldAPI/ndarray", branch = "master", default-features = false, features = ["std"] } + +[patch."https://github.com/AdaWorldAPI/lance-graph"] +lance-graph-contract = { path = "../../../../crates/lance-graph-contract" } + +[patch."https://github.com/AdaWorldAPI/ndarray"] +ndarray = { path = "../../../../../ndarray" } + +[profile.release] +debug = 0 + +[workspace] diff --git a/.claude/probes/2026-11-03-d-global-where/probe/src/bin/bench.rs b/.claude/probes/2026-11-03-d-global-where/probe/src/bin/bench.rs new file mode 100644 index 000000000..8f2fa7e5c --- /dev/null +++ b/.claude/probes/2026-11-03-d-global-where/probe/src/bin/bench.rs @@ -0,0 +1,854 @@ +//! LAB: D-GLOBAL-WHERE P0 bench (Part 2 of SPEC.md): our side. +//! +//! Usage: `bench `. Writes the datasets as CSV into `` and our +//! timings to `/ours.json`. Single thread. Every timing is in +//! microseconds; a warm or query value >= 1000 us prints FAILED-GATE; cold +//! preparation is reported and flagged COLD-FLAG when >= 1000 us (reported, +//! not a gate). Exit status 1 if any answer disagrees with the scalar oracle. +//! +//! Dense edges: Bernoulli p = 0.25 for dr64 and dr256, p = 0.03 for multi. + +use std::fs::{self, File}; +use std::hint::black_box; +use std::io::{BufWriter, Write}; +use std::path::{Path, PathBuf}; +use std::time::Instant; + +use d_global_where_probe::{ + alloc_bytes, bit, coord_of, for_each_bit, gen_edges, gen_lanes, live_bytes, oracle, + peak_bytes, pick_domain, popcount, project_keep, reset_peak, route_selection, set_bit, stats, + time_runs, virtual_where, CountingAlloc, Dist, Lanes, Oracle, Plane, Prepared, Rng, A_LT, + B_LT, SEED, UNIVERSE, UNIVERSE_WORDS, +}; +use lance_graph_dt64::dr::{Axis as ResAxis, LocalMap, MapTable, TileId, TileMap}; +use lance_graph_quack::{Agg, Cmp}; +use ndarray::simd::{checked_binary_i64, mask_and, mask_any, mask_or_assign, I64Op}; + +#[global_allocator] +static ALLOC: CountingAlloc = CountingAlloc; + +const RUNS: usize = 201; + +// --------------------------------------------------------------------------- +// records and json +// --------------------------------------------------------------------------- + +struct Rec { + dataset: String, + size: usize, + dist: &'static str, + edges: usize, + workload: &'static str, + arm: &'static str, + answer: i64, + cold_us: f64, + warm_med_us: f64, + warm_p10_us: f64, + warm_p90_us: f64, + where_q_us: Option, + where_v_us: Option, + route_us: Option, + fold_us: Option, + update_us: Option, + alloc_bytes_prep: usize, + alloc_bytes_query: usize, + peak_bytes: usize, + interm: Option, +} + +fn jf(o: Option) -> String { + match o { + Some(v) => format!("{v:.3}"), + None => "null".to_string(), + } +} + +fn ji(o: Option) -> String { + match o { + Some(v) => v.to_string(), + None => "null".to_string(), + } +} + +fn write_json(path: &Path, recs: &[Rec]) { + let mut w = BufWriter::new(File::create(path).expect("ours.json")); + writeln!(w, "[").unwrap(); + for (i, r) in recs.iter().enumerate() { + write!( + w, + " {{\"dataset\": \"{}\", \"size\": {}, \"dist\": \"{}\", \"edges\": {}, \"workload\": \"{}\", \"arm\": \"{}\", \"answer\": {}, \"cold_us\": {:.3}, \"warm_med_us\": {:.3}, \"warm_p10_us\": {:.3}, \"warm_p90_us\": {:.3}, \"where_q_us\": {}, \"where_v_us\": {}, \"route_us\": {}, \"fold_us\": {}, \"update_us\": {}, \"alloc_bytes_prep\": {}, \"alloc_bytes_query\": {}, \"peak_bytes\": {}, \"interm_cardinality\": {}}}", + r.dataset, + r.size, + r.dist, + r.edges, + r.workload, + r.arm, + r.answer, + r.cold_us, + r.warm_med_us, + r.warm_p10_us, + r.warm_p90_us, + jf(r.where_q_us), + jf(r.where_v_us), + jf(r.route_us), + jf(r.fold_us), + jf(r.update_us), + r.alloc_bytes_prep, + r.alloc_bytes_query, + r.peak_bytes, + ji(r.interm), + ) + .unwrap(); + writeln!(w, "{}", if i + 1 < recs.len() { "," } else { "" }).unwrap(); + } + writeln!(w, "]").unwrap(); +} + +// --------------------------------------------------------------------------- +// csv +// --------------------------------------------------------------------------- + +fn write_pairs(path: &Path, header: &str, rows: &[(u32, u32)]) { + let mut w = BufWriter::new(File::create(path).expect("csv")); + writeln!(w, "{header}").unwrap(); + for &(a, b) in rows { + writeln!(w, "{a},{b}").unwrap(); + } +} + +fn write_ids(path: &Path, ids: &[u64]) { + let mut w = BufWriter::new(File::create(path).expect("csv")); + writeln!(w, "id").unwrap(); + for &g in ids { + writeln!(w, "{g}").unwrap(); + } +} + +fn write_nodes(path: &Path, lanes: &Lanes) { + let mut w = BufWriter::new(File::create(path).expect("nodes.csv")); + writeln!(w, "id,a,b").unwrap(); + for g in 0..UNIVERSE { + writeln!(w, "{g},{},{}", lanes.a[g], lanes.b[g]).unwrap(); + } +} + +// --------------------------------------------------------------------------- +// folds over the presence plane (coordinates, masks; no tuples) +// --------------------------------------------------------------------------- + +/// W2: any(row[x] & selB) for every x in selA. +fn fold_w2(plane: &Plane, a: &[u64], b: &[u64], tmp: &mut [u64]) -> i64 { + let mut n = 0i64; + for_each_bit(a, |x| { + mask_and(plane.row(x), b, tmp); + if mask_any(tmp) { + n += 1; + } + }); + n +} + +/// W3 `back`: Yb = {y : row[y] & selB != 0}, then count x in A with row[x] & Yb != 0. +fn fold_w3_back(plane: &Plane, a: &[u64], b: &[u64], yb: &mut [u64], tmp: &mut [u64]) -> i64 { + yb.fill(0); + for y in 0..plane.coords { + mask_and(plane.row(y), b, tmp); + if mask_any(tmp) { + set_bit(yb, y); + } + } + let mut n = 0i64; + for_each_bit(a, |x| { + mask_and(plane.row(x), yb, tmp); + if mask_any(tmp) { + n += 1; + } + }); + n +} + +/// W3 `tile`: per x in A, R2 = OR of the rows of row[x]'s members, test & selB. +fn fold_w3_tile(plane: &Plane, a: &[u64], b: &[u64], acc: &mut [u64], tmp: &mut [u64]) -> i64 { + let mut n = 0i64; + for_each_bit(a, |x| { + acc.fill(0); + for_each_bit(plane.row(x), |y| mask_or_assign(acc, plane.row(y))); + mask_and(acc, b, tmp); + if mask_any(tmp) { + n += 1; + } + }); + n +} + +fn adj<'a>(off: &'a [u32], adjv: &'a [u32], x: usize) -> &'a [u32] { + &adjv[off[x] as usize..off[x + 1] as usize] +} + +/// W3 `csr`: DFS over the CSR with early exit. +fn fold_w3_csr(off: &[u32], adjv: &[u32], a: &[u64], b: &[u64]) -> i64 { + let mut n = 0i64; + for_each_bit(a, |x| { + 'found: for &y in adj(off, adjv, x) { + for &z in adj(off, adjv, y as usize) { + if bit(b, z as usize) { + n += 1; + break 'found; + } + } + } + }); + n +} + +/// W4 `front`: F = selA; three times F = OR rows of F; popcount(F & selB). +fn fold_w4_front(plane: &Plane, a: &[u64], b: &[u64], f: &mut [u64], g: &mut [u64]) -> i64 { + f.copy_from_slice(a); + for _ in 0..3 { + g.fill(0); + for_each_bit(f, |x| mask_or_assign(g, plane.row(x))); + f.copy_from_slice(g); + } + mask_and(f, b, g); + popcount(g) as i64 +} + +/// W4 `csr`: BFS over the CSR with a visited bitmap per level. +#[allow(clippy::too_many_arguments)] +fn fold_w4_csr( + off: &[u32], + adjv: &[u32], + a: &[u64], + b: &[u64], + cur: &mut Vec, + next: &mut Vec, + visited: &mut [u64], +) -> i64 { + cur.clear(); + for_each_bit(a, |x| cur.push(x as u32)); + for _ in 0..3 { + visited.fill(0); + next.clear(); + for &x in cur.iter() { + for &y in adj(off, adjv, x as usize) { + if !bit(visited, y as usize) { + set_bit(visited, y as usize); + next.push(y); + } + } + } + std::mem::swap(cur, next); + } + cur.iter().filter(|&&z| bit(b, z as usize)).count() as i64 +} + +/// W5: support = popcount(OR rows of A). +fn fold_w5(plane: &Plane, a: &[u64], acc: &mut [u64]) -> i64 { + acc.fill(0); + for_each_bit(a, |x| mask_or_assign(acc, plane.row(x))); + popcount(acc) as i64 +} + +/// W6: indegA[y] by per-row bit iteration over x in A; sum of indegA * outdeg, checked i64. +fn fold_w6(plane: &Plane, a: &[u64], outdeg: &[i64], indeg: &mut [i64], prod: &mut [i64]) -> i64 { + indeg.fill(0); + for_each_bit(a, |x| { + for_each_bit(plane.row(x), |y| indeg[y] += 1); + }); + checked_binary_i64(I64Op::Mul, indeg, outdeg, prod).expect("2-path counts fit i64"); + let mut s = 0i64; + for &p in prod.iter() { + s = s.checked_add(p).expect("2-path sum fits i64"); + } + s +} + +/// W7i: popcount of the routed intersection. +fn fold_w7i(a: &[u64], b: &[u64], tmp: &mut [u64]) -> i64 { + mask_and(a, b, tmp); + popcount(tmp) as i64 +} + +// --------------------------------------------------------------------------- +// one arm +// --------------------------------------------------------------------------- + +struct Meta { + dataset: String, + size: usize, + dist: &'static str, + edges: usize, +} + +/// Shared preparation cost charged to an arm's cold figure. +#[derive(Clone, Copy, Default)] +struct Cost { + prep_us: f64, + alloc_prep: usize, + peak_prep: usize, +} + +fn flag(v: f64) -> &'static str { + if v >= 1000.0 { + " FAILED-GATE" + } else { + "" + } +} + +/// Run one arm. `f(true)` runs the whole query (WHERE or routing, then the +/// fold); `f(false)` runs the fold alone over the masks the last `f(true)` +/// left in place. Cold = preparation + the first `f(true)`. Warm = 201 runs +/// of `f(warm_flag)`. The fold-only column = 201 runs of `f(false)`. +#[allow(clippy::too_many_arguments)] +fn run_arm( + m: &Meta, + cost: Cost, + workload: &'static str, + arm: &'static str, + warm_flag: bool, + expected: i64, + cols: (Option, Option, Option), + f: &mut dyn FnMut(bool) -> i64, +) -> (Rec, bool) { + reset_peak(); + let live0 = live_bytes(); + let t = Instant::now(); + let answer = black_box(f(true)); + let cold_run_us = t.elapsed().as_nanos() as f64 / 1000.0; + let run_peak = peak_bytes().saturating_sub(live0); + + let ab = alloc_bytes(); + black_box(f(warm_flag)); + let alloc_query = alloc_bytes() - ab; + + let warm_samples = time_runs(RUNS, || { + black_box(f(warm_flag)); + }); + let (med, p10, p90) = stats(&warm_samples); + let fold_samples = time_runs(RUNS, || { + black_box(f(false)); + }); + let (fold_med, _, _) = stats(&fold_samples); + + let cold_us = cost.prep_us + cold_run_us; + let ok = answer == expected; + let mut notes = String::new(); + for v in [med, p10, p90, fold_med, cols.0.unwrap_or(0.0), cols.1.unwrap_or(0.0), cols.2.unwrap_or(0.0)] { + if v >= 1000.0 { + notes.push_str(flag(v)); + break; + } + } + if cost.prep_us >= 1000.0 { + notes.push_str(" COLD-FLAG"); + } + if !ok { + notes.push_str(&format!(" MISMATCH(expected {expected})")); + } + println!( + "{:<13} {:<4} {:<10} ans={:<9} warm {:>9.3} us (p10 {:>9.3}, p90 {:>9.3}) fold {:>9.3} us cold {:>11.3} us alloc_query {}{}", + m.dataset, workload, arm, answer, med, p10, p90, fold_med, cold_us, alloc_query, notes + ); + ( + Rec { + dataset: m.dataset.clone(), + size: m.size, + dist: m.dist, + edges: m.edges, + workload, + arm, + answer, + cold_us, + warm_med_us: med, + warm_p10_us: p10, + warm_p90_us: p90, + where_q_us: cols.0, + where_v_us: cols.1, + route_us: cols.2, + fold_us: Some(fold_med), + update_us: None, + alloc_bytes_prep: cost.alloc_prep, + alloc_bytes_query: alloc_query, + peak_bytes: cost.peak_prep.max(run_peak), + interm: None, + }, + ok, + ) +} + +// --------------------------------------------------------------------------- +// one dataset +// --------------------------------------------------------------------------- + +struct Data<'a> { + meta: Meta, + lanes: &'a Lanes, + dom: &'a [u64], + edges: &'a [(u32, u32)], + deleted: &'a [(u32, u32)], + oracle: &'a Oracle, +} + +fn push(recs: &mut Vec, all_ok: &mut bool, r: (Rec, bool), interm: Option) { + let (mut rec, ok) = r; + rec.interm = interm; + *all_ok &= ok; + recs.push(rec); +} + +fn median(v: &[f64]) -> f64 { + stats(v).0 +} + +fn run_dataset(recs: &mut Vec, d: &Data<'_>) -> bool { + let mut all_ok = true; + let lanes = d.lanes; + let size = d.dom.len(); + let live = vec![u64::MAX; UNIVERSE_WORDS]; + let mut keep_a = vec![0u64; UNIVERSE_WORDS]; + let mut keep_b = vec![0u64; UNIVERSE_WORDS]; + + // ---- W1 preparation (lower once, scratch carved) ------------------- + let ab = alloc_bytes(); + let t = Instant::now(); + let mut q1 = Prepared::new(Cmp::LtI32(A_LT), Agg::Count, UNIVERSE); + let w1_prep = Cost { + prep_us: t.elapsed().as_nanos() as f64 / 1000.0, + alloc_prep: alloc_bytes() - ab, + peak_prep: 0, + }; + let mut qa = Prepared::new(Cmp::LtI32(A_LT), Agg::Rows, UNIVERSE); + let mut qb = Prepared::new(Cmp::LtI32(B_LT), Agg::Rows, UNIVERSE); + + // ---- cold preparation: tiles, presence plane, outdeg --------------- + let live_before = live_bytes(); + reset_peak(); + let ab_base = alloc_bytes(); + let t_base = Instant::now(); + let axis = ResAxis::for_survivors(size); + let tw = axis.tile.positions(); + let ntiles = axis.tiles as usize; + let coords = ntiles * tw; + let wpr = coords.div_ceil(64); + let r_tiles: Vec = (0..ntiles as u32).collect(); + let mut table = MapTable::new(1, 1); + { + let mut changes: Vec<(TileId, Option)> = Vec::new(); + for (t, chunk) in d.dom.chunks(tw).enumerate() { + changes.push(( + t as TileId, + Some(LocalMap::prepare(axis.tile, chunk).expect("R tile")), + )); + } + table.advance(1, 1, changes); + } + let r_us = t_base.elapsed().as_nanos() as f64 / 1000.0; + + // ---- selection tiles (used by W7 only): A descending, B ascending --- + let ab_sel = alloc_bytes(); + let t_sel = Instant::now(); + let mut a_ids: Vec = d + .dom + .iter() + .copied() + .filter(|&g| lanes.a[g as usize] < A_LT) + .collect(); + a_ids.sort_unstable_by(|p, q| q.cmp(p)); + let mut b_ids: Vec = d + .dom + .iter() + .copied() + .filter(|&g| lanes.b[g as usize] < B_LT) + .collect(); + b_ids.sort_unstable(); + let mut a_tile_ids: Vec = Vec::new(); + let mut b_tile_ids: Vec = Vec::new(); + { + let a_axis = ResAxis::for_survivors(a_ids.len()); + let b_axis = ResAxis::for_survivors(b_ids.len()); + let mut changes: Vec<(TileId, Option)> = Vec::new(); + for (k, chunk) in a_ids.chunks(a_axis.tile.positions()).enumerate() { + let id = 100 + k as TileId; + a_tile_ids.push(id); + changes.push((id, Some(LocalMap::prepare(a_axis.tile, chunk).expect("A tile")))); + } + for (k, chunk) in b_ids.chunks(b_axis.tile.positions()).enumerate() { + let id = 200 + k as TileId; + b_tile_ids.push(id); + changes.push((id, Some(LocalMap::prepare(b_axis.tile, chunk).expect("B tile")))); + } + table.advance(1, 1, changes); + } + let sel_prep_us = t_sel.elapsed().as_nanos() as f64 / 1000.0; + let sel_alloc = alloc_bytes() - ab_sel; + + // ---- frame, tile views, plane, outdeg ------------------------------- + let t_plane = Instant::now(); + let frame = table.seal(); + let tiles: Vec> = r_tiles + .iter() + .map(|&t| table.map(&frame, t).expect("R tile readable")) + .collect(); + let mut plane = Plane::new(coords); + for &(s, dd) in d.edges { + let cx = coord_of(&table, &frame, &r_tiles, tw, u64::from(s)).expect("src in domain"); + let cy = coord_of(&table, &frame, &r_tiles, tw, u64::from(dd)).expect("dst in domain"); + plane.set(cx, cy); + } + let outdeg: Vec = (0..coords).map(|c| popcount(plane.row(c)) as i64).collect(); + let mut sel_a = vec![0u64; wpr]; + let mut sel_b = vec![0u64; wpr]; + let mut tmp = vec![0u64; wpr]; + let mut acc = vec![0u64; wpr]; + let mut yb = vec![0u64; wpr]; + let mut ff = vec![0u64; wpr]; + let mut gg = vec![0u64; wpr]; + let mut visited = vec![0u64; wpr]; + let mut indeg = vec![0i64; coords]; + let mut prod = vec![0i64; coords]; + let mut cur: Vec = Vec::with_capacity(coords); + let mut next: Vec = Vec::with_capacity(coords); + let plane_us = t_plane.elapsed().as_nanos() as f64 / 1000.0; + let base = Cost { + prep_us: r_us + plane_us, + alloc_prep: (alloc_bytes() - ab_base).saturating_sub(sel_alloc), + peak_prep: peak_bytes().saturating_sub(live_before), + }; + let with_sel = Cost { + prep_us: base.prep_us + sel_prep_us, + alloc_prep: base.alloc_prep + sel_alloc, + ..base + }; + + // ---- CSR (cold, only the csr arms are charged) ----------------------- + let ab_csr = alloc_bytes(); + let t_csr = Instant::now(); + let mut csr_off: Vec = Vec::with_capacity(coords + 1); + let mut csr_adj: Vec = Vec::with_capacity(d.edges.len()); + csr_off.push(0); + for x in 0..coords { + for_each_bit(plane.row(x), |y| csr_adj.push(y as u32)); + csr_off.push(csr_adj.len() as u32); + } + let with_csr = Cost { + prep_us: base.prep_us + t_csr.elapsed().as_nanos() as f64 / 1000.0, + alloc_prep: base.alloc_prep + (alloc_bytes() - ab_csr), + ..base + }; + + if base.prep_us >= 1000.0 { + println!( + "{:<13} prep (tiles + plane + outdeg) {:.3} us COLD-FLAG (reported, not gate); selection tiles {:.3} us; csr {:.3} us", + d.meta.dataset, + base.prep_us, + sel_prep_us, + with_csr.prep_us - base.prep_us + ); + } + + // ---- WHERE arms, timed separately; masks must agree ------------------- + virtual_where(&tiles, tw, &lanes.a, A_LT, &mut sel_a); + virtual_where(&tiles, tw, &lanes.b, B_LT, &mut sel_b); + qa.keep(&lanes.a, &live, &mut keep_a); + qb.keep(&lanes.b, &live, &mut keep_b); + project_keep(&tiles, tw, &keep_a, &mut tmp); + let a_agree = tmp == sel_a; + project_keep(&tiles, tw, &keep_b, &mut tmp); + let b_agree = tmp == sel_b; + if !(a_agree && b_agree) { + println!("{:<13} WHERE arms DISAGREE (A {a_agree}, B {b_agree})", d.meta.dataset); + all_ok = false; + } + let wq_a = median(&time_runs(RUNS, || { + qa.keep(&lanes.a, &live, &mut keep_a); + project_keep(&tiles, tw, &keep_a, &mut sel_a); + })); + let wq_b = median(&time_runs(RUNS, || { + qb.keep(&lanes.b, &live, &mut keep_b); + project_keep(&tiles, tw, &keep_b, &mut sel_b); + })); + let wv_a = median(&time_runs(RUNS, || { + virtual_where(&tiles, tw, &lanes.a, A_LT, &mut sel_a); + })); + let wv_b = median(&time_runs(RUNS, || { + virtual_where(&tiles, tw, &lanes.b, B_LT, &mut sel_b); + })); + let cols_ab = (Some(wq_a + wq_b), Some(wv_a + wv_b), None); + let cols_a = (Some(wq_a), Some(wv_a), None); + for (what, v) in [("where_q A+B", wq_a + wq_b), ("where_v A+B", wv_a + wv_b)] { + if v >= 1000.0 { + println!("{:<13} {what} {v:.3} us{}", d.meta.dataset, flag(v)); + } + } + + let o = d.oracle; + let meta = &d.meta; + + // ---- W1: SELECT count(*) FROM nodes WHERE a < 50 ---------------------- + { + let r = run_arm(meta, w1_prep, "W1", "quack_count", true, o.w1, (None, None, None), &mut |_w| { + q1.count(&lanes.a, &live) as i64 + }); + push(recs, &mut all_ok, r, None); + } + + // ---- W2 ---------------------------------------------------------------- + { + let r = run_arm(meta, base, "W2", "fold", true, o.w2, cols_ab, &mut |w| { + if w { + virtual_where(&tiles, tw, &lanes.a, A_LT, &mut sel_a); + virtual_where(&tiles, tw, &lanes.b, B_LT, &mut sel_b); + } + fold_w2(&plane, &sel_a, &sel_b, &mut tmp) + }); + push(recs, &mut all_ok, r, Some(o.sel_a as i64)); + } + + // ---- W3: back, tile, csr ----------------------------------------------- + { + let r = run_arm(meta, base, "W3", "back", true, o.w3, cols_ab, &mut |w| { + if w { + virtual_where(&tiles, tw, &lanes.a, A_LT, &mut sel_a); + virtual_where(&tiles, tw, &lanes.b, B_LT, &mut sel_b); + } + fold_w3_back(&plane, &sel_a, &sel_b, &mut yb, &mut tmp) + }); + let yb_n = popcount(&yb) as i64; + push(recs, &mut all_ok, r, Some(yb_n)); + let r = run_arm(meta, base, "W3", "tile", true, o.w3, cols_ab, &mut |w| { + if w { + virtual_where(&tiles, tw, &lanes.a, A_LT, &mut sel_a); + virtual_where(&tiles, tw, &lanes.b, B_LT, &mut sel_b); + } + fold_w3_tile(&plane, &sel_a, &sel_b, &mut acc, &mut tmp) + }); + push(recs, &mut all_ok, r, None); + let r = run_arm(meta, with_csr, "W3", "csr", true, o.w3, cols_ab, &mut |w| { + if w { + virtual_where(&tiles, tw, &lanes.a, A_LT, &mut sel_a); + virtual_where(&tiles, tw, &lanes.b, B_LT, &mut sel_b); + } + fold_w3_csr(&csr_off, &csr_adj, &sel_a, &sel_b) + }); + push(recs, &mut all_ok, r, None); + } + + // ---- W4: front, csr ----------------------------------------------------- + { + let r = run_arm(meta, base, "W4", "front", true, o.w4, cols_ab, &mut |w| { + if w { + virtual_where(&tiles, tw, &lanes.a, A_LT, &mut sel_a); + virtual_where(&tiles, tw, &lanes.b, B_LT, &mut sel_b); + } + fold_w4_front(&plane, &sel_a, &sel_b, &mut ff, &mut gg) + }); + let front_n = popcount(&ff) as i64; + push(recs, &mut all_ok, r, Some(front_n)); + let r = run_arm(meta, with_csr, "W4", "csr", true, o.w4, cols_ab, &mut |w| { + if w { + virtual_where(&tiles, tw, &lanes.a, A_LT, &mut sel_a); + virtual_where(&tiles, tw, &lanes.b, B_LT, &mut sel_b); + } + fold_w4_csr(&csr_off, &csr_adj, &sel_a, &sel_b, &mut cur, &mut next, &mut visited) + }); + let csr_front = cur.len() as i64; + push(recs, &mut all_ok, r, Some(csr_front)); + } + + // ---- W5a ------------------------------------------------------------------ + { + let r = run_arm(meta, base, "W5a", "fold", true, o.w5, cols_a, &mut |w| { + if w { + virtual_where(&tiles, tw, &lanes.a, A_LT, &mut sel_a); + } + fold_w5(&plane, &sel_a, &mut acc) + }); + push(recs, &mut all_ok, r, Some(o.w5)); + } + + // ---- W6 ------------------------------------------------------------------- + { + let r = run_arm(meta, base, "W6", "fold", true, o.w6, cols_a, &mut |w| { + if w { + virtual_where(&tiles, tw, &lanes.a, A_LT, &mut sel_a); + } + fold_w6(&plane, &sel_a, &outdeg, &mut indeg, &mut prod) + }); + push(recs, &mut all_ok, r, None); + } + + // ---- W7 / W7i: route the selection tiles into domain coordinates ---------- + { + let route_us = median(&time_runs(RUNS, || { + route_selection(&table, &frame, &r_tiles, tw, &a_tile_ids, &mut sel_a); + route_selection(&table, &frame, &r_tiles, tw, &b_tile_ids, &mut sel_b); + })); + if route_us >= 1000.0 { + println!("{:<13} route A+B {route_us:.3} us{}", meta.dataset, flag(route_us)); + } + let cols = (None, None, Some(route_us)); + for (arm, warm_flag) in [("route_each", true), ("reuse", false)] { + let r = run_arm(meta, with_sel, "W7", arm, warm_flag, o.w2, cols, &mut |w| { + if w { + route_selection(&table, &frame, &r_tiles, tw, &a_tile_ids, &mut sel_a); + route_selection(&table, &frame, &r_tiles, tw, &b_tile_ids, &mut sel_b); + } + fold_w2(&plane, &sel_a, &sel_b, &mut tmp) + }); + push(recs, &mut all_ok, r, Some(o.sel_a as i64)); + let r = run_arm(meta, with_sel, "W7i", arm, warm_flag, o.w7i, cols, &mut |w| { + if w { + route_selection(&table, &frame, &r_tiles, tw, &a_tile_ids, &mut sel_a); + route_selection(&table, &frame, &r_tiles, tw, &b_tile_ids, &mut sel_b); + } + fold_w7i(&sel_a, &sel_b, &mut tmp) + }); + push(recs, &mut all_ok, r, None); + } + } + + // ---- W8: W2, delete 1% of the edges, W2 again ------------------------------- + // The update clears the forward presence bits (ids -> coordinates through + // `locate`, then one bit per edge); outdeg and the CSR are not touched, W2 + // reads neither. Each timing run starts from the full plane (restored + // untimed), so the median is of 201 clears. + { + let mut samples: Vec = Vec::with_capacity(RUNS); + for _ in 0..RUNS { + let t = Instant::now(); + for &(s, dd) in d.deleted { + let cx = coord_of(&table, &frame, &r_tiles, tw, u64::from(s)).expect("src"); + let cy = coord_of(&table, &frame, &r_tiles, tw, u64::from(dd)).expect("dst"); + plane.clear(cx, cy); + } + samples.push(t.elapsed().as_nanos() as f64 / 1000.0); + for &(s, dd) in d.deleted { + let cx = coord_of(&table, &frame, &r_tiles, tw, u64::from(s)).expect("src"); + let cy = coord_of(&table, &frame, &r_tiles, tw, u64::from(dd)).expect("dst"); + plane.set(cx, cy); + } + } + let update_us = median(&samples); + for &(s, dd) in d.deleted { + let cx = coord_of(&table, &frame, &r_tiles, tw, u64::from(s)).expect("src"); + let cy = coord_of(&table, &frame, &r_tiles, tw, u64::from(dd)).expect("dst"); + plane.clear(cx, cy); + } + let r = run_arm(meta, base, "W8_after", "after_delete", true, o.w8, cols_ab, &mut |w| { + if w { + virtual_where(&tiles, tw, &lanes.a, A_LT, &mut sel_a); + virtual_where(&tiles, tw, &lanes.b, B_LT, &mut sel_b); + } + fold_w2(&plane, &sel_a, &sel_b, &mut tmp) + }); + let (mut rec, ok) = r; + rec.update_us = Some(update_us); + rec.interm = Some(d.deleted.len() as i64); + all_ok &= ok; + if update_us >= 1000.0 { + println!("{:<13} update {update_us:.3} us{}", meta.dataset, flag(update_us)); + } + recs.push(rec); + } + + all_ok +} + +// --------------------------------------------------------------------------- +// main +// --------------------------------------------------------------------------- + +fn main() { + let out: PathBuf = match std::env::args().nth(1) { + Some(p) => PathBuf::from(p), + None => { + eprintln!("usage: bench "); + std::process::exit(2); + } + }; + fs::create_dir_all(&out).expect("create OUT"); + println!("dense edges: p = 0.25 for dr64 and dr256, p = 0.03 for multi (4096 nodes)"); + + let mut rng = Rng::new(SEED); + let mut lanes = gen_lanes(&mut rng); + let sizes: [(&str, usize); 3] = [("dr64", 64), ("dr256", 256), ("multi", 4096)]; + let mut domains: Vec> = Vec::new(); + for &(_, size) in &sizes { + let dom = pick_domain(&mut Rng::new(SEED ^ size as u64), size); + // Keep every selection non-empty: the first domain ids are in A and B, + // the third in B (a few ids of 65,536; the lanes stay uniform). + lanes.a[dom[0] as usize] = 0; + lanes.b[dom[0] as usize] = 0; + lanes.a[dom[1] as usize] = 0; + lanes.b[dom[2] as usize] = 0; + domains.push(dom); + } + write_nodes(&out.join("nodes.csv"), &lanes); + + let mut recs: Vec = Vec::new(); + let mut all_ok = true; + for (si, &(sname, size)) in sizes.iter().enumerate() { + let dom = &domains[si]; + let p = if size == 4096 { 0.03 } else { 0.25 }; + for dist in Dist::ALL { + let ds = format!("{sname}_{}", dist.name()); + let mut er = Rng::new(SEED ^ ((size as u64) << 8) ^ (dist as u64 + 1)); + let edges = gen_edges(&mut er, dom, dist, p); + let k = (edges.len() / 100).max(1); + let mut idx: Vec = (0..edges.len()).collect(); + for i in 0..k { + let j = i + er.below((idx.len() - i) as u64) as usize; + idx.swap(i, j); + } + let deleted: Vec<(u32, u32)> = idx[..k].iter().map(|&i| edges[i]).collect(); + + let mut a_ids: Vec = dom + .iter() + .copied() + .filter(|&g| lanes.a[g as usize] < A_LT) + .collect(); + a_ids.sort_unstable_by(|x, y| y.cmp(x)); + let mut b_ids: Vec = dom + .iter() + .copied() + .filter(|&g| lanes.b[g as usize] < B_LT) + .collect(); + b_ids.sort_unstable(); + write_pairs(&out.join(format!("{ds}_edges.csv")), "src,dst", &edges); + write_ids(&out.join(format!("{ds}_selA.csv")), &a_ids); + write_ids(&out.join(format!("{ds}_selB.csv")), &b_ids); + write_pairs(&out.join(format!("{ds}_delete.csv")), "src,dst", &deleted); + + let orc = oracle(&lanes, dom, &edges, &deleted); + println!( + "== {ds}: {} nodes, {} edges, |A|={}, |B|={}, deleting {}", + size, + edges.len(), + orc.sel_a, + orc.sel_b, + deleted.len() + ); + let data = Data { + meta: Meta { + dataset: ds.clone(), + size, + dist: dist.name(), + edges: edges.len(), + }, + lanes: &lanes, + dom, + edges: &edges, + deleted: &deleted, + oracle: &orc, + }; + all_ok &= run_dataset(&mut recs, &data); + } + } + write_json(&out.join("ours.json"), &recs); + println!("wrote {} records to {}", recs.len(), out.join("ours.json").display()); + if !all_ok { + eprintln!("bench: at least one answer disagreed with the scalar oracle"); + std::process::exit(1); + } +} diff --git a/.claude/probes/2026-11-03-d-global-where/probe/src/bin/falsify.rs b/.claude/probes/2026-11-03-d-global-where/probe/src/bin/falsify.rs new file mode 100644 index 000000000..aa1131f27 --- /dev/null +++ b/.claude/probes/2026-11-03-d-global-where/probe/src/bin/falsify.rs @@ -0,0 +1,780 @@ +//! LAB: D-GLOBAL-WHERE P0 falsifier (Part 1 of SPEC.md). +//! +//! One global WHERE (Quack `Keep` over 65,536 ids) is routed into DR tiles +//! through `lance_graph_dt64::dr::MapTable`, and folded over a presence plane +//! of a relation. The checks ask where local coordinates stop meaning the same +//! thing as global ids, and whether the guards of `dr-math-binding-probe` fire +//! where they must. Exit status 1 if any check fails. + +use std::collections::{HashMap, HashSet}; + +use d_global_where_probe::{ + alloc_bytes, alloc_calls, bit, coord_of, for_each_bit, gen_lanes, pick_domain, popcount, + prefix_mask, route_selection, Lanes, Plane, Prepared, Rng, A_LT, B_LT, SEED, UNIVERSE, + UNIVERSE_WORDS, +}; +use d_global_where_probe::CountingAlloc; +use dr_math_binding_probe as drp; +use dr_math_binding_probe::hhtl16::LocalMap as HLocalMap; +use dr_math_binding_probe::where_dr3::{project, Criteria, LocalSelection, ReuseRefusal, Under}; +use lance_graph_dt64::dr::{ + Axis as ResAxis, FrameRefusal, LocalMap, LocateRefusal, MapRead, MapTable, RouteVersion, + TileId, Width, +}; +use lance_graph_quack::{Agg, Cmp}; +use ndarray::simd::{checked_binary_i64, mask_and, mask_any, mask_or_assign, mask_xor, I64Op}; + +#[global_allocator] +static ALLOC: CountingAlloc = CountingAlloc; + +/// Wide coordinates: two DR256 tiles of the relation frame R. +const TW: usize = 256; +const COORDS: usize = 512; +const WPR: usize = COORDS / 64; +const R_TILES: [TileId; 2] = [0, 1]; + +struct Report { + lines: Vec<(u32, String)>, + census: Vec<(u32, i64, usize)>, + fails: u32, +} + +impl Report { + fn check(&mut self, n: u32, ok: bool, detail: String) { + if !ok { + self.fails += 1; + } + self.lines.push(( + n, + format!("F{n:<2} {} {detail}", if ok { "PASS" } else { "FAIL" }), + )); + } + fn census(&mut self, n: u32, lookups: i64, bytes: usize) { + self.census.push((n, lookups, bytes)); + } +} + +/// Lookups served so far by the maps of the four fixture tiles, read at the +/// table's current seal (after F10 the replaced tile restarts at zero). +fn look(table: &MapTable) -> u64 { + let f = table.seal(); + [0u32, 1, 10, 11] + .iter() + .map(|&t| table.map(&f, t).map(|m| m.lookups()).unwrap_or(0)) + .sum() +} + +/// Count of x in A with a B-neighbour: any(row[x] & selB) for every x in selA. +fn q_fold(plane: &Plane, sel_a: &[u64], sel_b: &[u64], tmp: &mut [u64]) -> i64 { + let mut n = 0i64; + for_each_bit(sel_a, |x| { + mask_and(plane.row(x), sel_b, tmp); + if mask_any(tmp) { + n += 1; + } + }); + n +} + +/// The same count from the edge list (oracle). +fn q_oracle(lanes: &Lanes, edges: &[(u64, u64)]) -> i64 { + let mut xs: HashSet = HashSet::new(); + for &(s, d) in edges { + if lanes.a[s as usize] < A_LT && lanes.b[d as usize] < B_LT { + xs.insert(s); + } + } + xs.len() as i64 +} + +fn bind_reg<'a>( + lst: &drp::FrameStore, + g: &drp::Guards, + m: drp::MethodSignature, + rows: &'a [u64; 64], +) -> drp::BoundDr64<'a> { + drp::bind_dr64( + lst, + m, + m, + g, + (g.focus, g.scope), + drp::Operand { + rows, + validity: None, + }, + ) + .expect("register binds") +} + +#[allow(clippy::too_many_arguments)] +fn project_sel( + map: &HLocalMap, + truth: &[u64], + gst: &drp::FrameStore, + gseal: &drp::Frame, + lst: &drp::FrameStore, + guards: &drp::Guards, + axis: drp::Axis, + method: drp::MethodSignature, + criteria: Criteria, +) -> LocalSelection { + project( + map, + truth, + Under { + global_store: gst, + global: gseal, + local_store: lst, + guards, + axis, + method, + criteria, + }, + ) + .expect("projection") +} + +fn main() { + let mut rep = Report { + lines: Vec::new(), + census: Vec::new(), + fails: 0, + }; + + // ------------------------------------------------------------------ + // fixture + // ------------------------------------------------------------------ + let mut rng = Rng::new(SEED); + let mut lanes = gen_lanes(&mut rng); + let dom = pick_domain(&mut rng, 512); + // x in A routed through R tile 0, y in B through R tile 1; three ids in + // A and B both. + let x = dom[0]; + let y = dom[256]; + let forced_shared = [dom[1], dom[100], dom[400]]; + lanes.a[x as usize] = 0; + lanes.b[y as usize] = 0; + for &z in &forced_shared { + lanes.a[z as usize] = 0; + lanes.b[z as usize] = 0; + } + // Edges over D: out-degree uniform in 0..=12 (average 6), no duplicates, + // no self loops. x keeps exactly one out-edge, to y. + let mut edges: Vec<(u64, u64)> = Vec::new(); + for i in 0..512usize { + let deg = rng.below(13) as usize; + let mut seen: HashSet = HashSet::new(); + while seen.len() < deg { + let j = rng.below(512) as usize; + if j != i && seen.insert(j) { + edges.push((dom[i], dom[j])); + } + } + } + edges.retain(|&(s, _)| s != x); + edges.push((x, y)); + + // WHERE through Quack: Keep masks over the whole universe. + let live = vec![u64::MAX; UNIVERSE_WORDS]; + let mut pa = Prepared::new(Cmp::LtI32(A_LT), Agg::Rows, UNIVERSE); + let mut pb = Prepared::new(Cmp::LtI32(B_LT), Agg::Rows, UNIVERSE); + let mut keep_a = vec![0u64; UNIVERSE_WORDS]; + let mut keep_b = vec![0u64; UNIVERSE_WORDS]; + pa.keep(&lanes.a, &live, &mut keep_a); + pb.keep(&lanes.b, &live, &mut keep_b); + + // F0 (preamble): the Keep masks equal the scalar lane test at every id. + { + let mut bad = 0usize; + let (mut na, mut nb) = (0usize, 0usize); + for g in 0..UNIVERSE { + let (ta, tb) = (lanes.a[g] < A_LT, lanes.b[g] < B_LT); + na += usize::from(ta); + nb += usize::from(tb); + if bit(&keep_a, g) != ta || bit(&keep_b, g) != tb { + bad += 1; + } + } + let ok = bad == 0 + && popcount(&keep_a) as usize == na + && popcount(&keep_b) as usize == nb + && na > 1000 + && nb > 1000; + rep.check( + 0, + ok, + format!("Quack Keep == lane oracle at all {UNIVERSE} ids (|A|={na}, |B|={nb}, mismatches={bad})"), + ); + } + + // Selection tiles: A descending global order, B ascending. + let mut a_ids: Vec = dom + .iter() + .copied() + .filter(|&g| bit(&keep_a, g as usize)) + .collect(); + a_ids.sort_unstable_by(|p, q| q.cmp(p)); + let mut b_ids: Vec = dom + .iter() + .copied() + .filter(|&g| bit(&keep_b, g as usize)) + .collect(); + b_ids.sort_unstable(); + assert!(a_ids.len() <= 256 && b_ids.len() <= 256, "selection tiles hold <= 256"); + let wa = ResAxis::for_survivors(a_ids.len()).tile; + let wb = ResAxis::for_survivors(b_ids.len()).tile; + + let mut table = MapTable::new(1, 1); + table.advance( + 1, + 1, + vec![ + (0, Some(LocalMap::prepare(Width::W256, &dom[0..256]).expect("tile 0"))), + (1, Some(LocalMap::prepare(Width::W256, &dom[256..512]).expect("tile 1"))), + (10, Some(LocalMap::prepare(wa, &a_ids).expect("tile 10"))), + (11, Some(LocalMap::prepare(wb, &b_ids).expect("tile 11"))), + ], + ); + let frame = table.seal(); + + let shared: Vec = a_ids + .iter() + .copied() + .filter(|g| b_ids.binary_search(g).is_ok()) + .collect(); + let y_sh: Option = { + let ta = table.map(&frame, 10).expect("tile 10"); + let tb = table.map(&frame, 11).expect("tile 11"); + let found = shared + .iter() + .copied() + .find(|&g| ta.local(g).ok() != tb.local(g).ok()); + found + }; + + // Presence planes (forward, and the column storage of the same edges). + let mut fwd = Plane::new(COORDS); + let mut rev = Plane::new(COORDS); + for &(s, d) in &edges { + let cx = coord_of(&table, &frame, &R_TILES, TW, s).expect("src in R"); + let cy = coord_of(&table, &frame, &R_TILES, TW, d).expect("dst in R"); + fwd.set(cx, cy); + rev.set(cy, cx); + } + let mut sel_a_r = vec![0u64; WPR]; + let mut sel_b_r = vec![0u64; WPR]; + route_selection(&table, &frame, &R_TILES, TW, &[10], &mut sel_a_r); + route_selection(&table, &frame, &R_TILES, TW, &[11], &mut sel_b_r); + + // ------------------------------------------------------------------ + // F1, F2: G->L->G and L->G->L, every id of tiles 0, 1, 10, 11 + // ------------------------------------------------------------------ + { + let (l0, b0) = (look(&table), alloc_bytes()); + let (mut n1, mut bad1, mut n2, mut bad2) = (0usize, 0usize, 0usize, 0usize); + for t in [0u32, 1, 10, 11] { + let tm = table.map(&frame, t).expect("tile"); + for &g in tm.globals() { + n1 += 1; + match tm.local(g) { + Ok(l) if tm.global(l) == Some(g) => {} + _ => bad1 += 1, + } + } + for l in 0..tm.len() { + let l8 = l as u8; + n2 += 1; + match tm.global(l8) { + Some(g) if tm.local(g) == Ok(l8) => {} + _ => bad2 += 1, + } + } + } + rep.check(1, bad1 == 0 && n1 > 500, format!("global(local(g))==g for {n1} ids of tiles 0,1,10,11")); + rep.check(2, bad2 == 0 && n2 == n1, format!("local(global(l))==l for {n2} locals")); + rep.census(1, look(&table) as i64 - l0 as i64, alloc_bytes() - b0); + rep.census(2, 0, 0); + } + + // ------------------------------------------------------------------ + // F3: the shared id has different locals in tile 10 and tile 11 + // ------------------------------------------------------------------ + { + let (l0, b0) = (look(&table), alloc_bytes()); + let detail = match y_sh { + Some(g) => { + let ta = table.map(&frame, 10).expect("tile 10"); + let tb = table.map(&frame, 11).expect("tile 11"); + format!( + "id {g}: local {:?} in tile 10 (A, descending), {:?} in tile 11 (B, ascending); {} ids shared", + ta.local(g).ok(), + tb.local(g).ok(), + shared.len() + ) + } + None => "no shared id with differing locals".to_string(), + }; + rep.check(3, y_sh.is_some() && shared.len() >= 3, detail); + rep.census(3, look(&table) as i64 - l0 as i64, alloc_bytes() - b0); + } + + // ------------------------------------------------------------------ + // F4: local-coincidence join vs the DR-aligned path + // ------------------------------------------------------------------ + { + let (l0, b0) = (look(&table), alloc_bytes()); + let ta = table.map(&frame, 10).expect("tile 10"); + let tb = table.map(&frame, 11).expect("tile 11"); + // Treat the two local position spaces as one domain: AND the tile-10 + // local mask with the tile-11 local mask. + let ma = prefix_mask(4, ta.len()); + let mb = prefix_mask(4, tb.len()); + let mut both = vec![0u64; 4]; + mask_and(&ma, &mb, &mut both); + let coincident = popcount(&both) as usize; + // DR-aligned: B local -> global (tile 11) -> tile 10 local via local(). + let mut aligned = 0usize; + for l in 0..tb.len() { + let g = tb.global(l as u8).expect("local in range"); + if ta.local(g).is_ok() { + aligned += 1; + } + } + let oracle = dom + .iter() + .filter(|&&g| lanes.a[g as usize] < A_LT && lanes.b[g as usize] < B_LT) + .count(); + rep.check( + 4, + aligned == oracle && coincident != oracle && oracle >= 3, + format!( + "oracle |A&B&D|={oracle}, DR-aligned={aligned}, local-coincidence={coincident} (tile lens {} and {})", + ta.len(), + tb.len() + ), + ); + rep.census(4, look(&table) as i64 - l0 as i64, alloc_bytes() - b0); + } + + // ------------------------------------------------------------------ + // F5, F18: Case B over the R frame; x and y in different R tiles + // ------------------------------------------------------------------ + let mut tmp = [0u64; WPR]; + let cx = coord_of(&table, &frame, &R_TILES, TW, x).expect("x in R"); + let cy = coord_of(&table, &frame, &R_TILES, TW, y).expect("y in R"); + let q0; + let (f5_bytes, f5_calls); + { + let (l0, b0) = (look(&table), alloc_bytes()); + // The measured fold: row[x] & selB_R != 0. + let (fb0, fc0) = (alloc_bytes(), alloc_calls()); + mask_and(fwd.row(cx), &sel_b_r, &mut tmp); + let ans5 = mask_any(&tmp); + f5_bytes = alloc_bytes() - fb0; + f5_calls = alloc_calls() - fc0; + let oracle5 = edges + .iter() + .any(|&(s, d)| s == x && lanes.b[d as usize] < B_LT); + q0 = q_fold(&fwd, &sel_a_r, &sel_b_r, &mut tmp); + let q0_oracle = q_oracle(&lanes, &edges); + let (ox, oy) = (cx / TW, cy / TW); + let ok = ans5 + && oracle5 + && bit(&sel_a_r, cx) + && bit(&sel_b_r, cy) + && q0 == q0_oracle + && q0 > 0; + rep.check( + 5, + ok, + format!( + "x={x} (R ordinal {ox}, coord {cx}) -> y={y} (R ordinal {oy}, coord {cy}): row[x]&selB_R != 0 is {ans5}, oracle {oracle5}; Q0 (x in A with a B-neighbour) = {q0} == oracle {q0_oracle}" + ), + ); + rep.check( + 18, + ox != oy && ox < 2 && oy < 2, + format!("R spans 2 DR256 tiles; x in ordinal {ox}, y in ordinal {oy}"), + ); + rep.census(5, look(&table) as i64 - l0 as i64, alloc_bytes() - b0); + rep.census(18, 0, 0); + } + + // ------------------------------------------------------------------ + // F6: clear the edge's presence bit; locate still Ok; answer false + // ------------------------------------------------------------------ + let q1; + { + let (l0, b0) = (look(&table), alloc_bytes()); + fwd.clear(cx, cy); + rev.clear(cy, cx); + edges.retain(|&e| e != (x, y)); + mask_and(fwd.row(cx), &sel_b_r, &mut tmp); + let ans6 = mask_any(&tmp); + let oracle6 = edges + .iter() + .any(|&(s, d)| s == x && lanes.b[d as usize] < B_LT); + let located = table.locate(&frame, &R_TILES, y).is_ok(); + q1 = q_fold(&fwd, &sel_a_r, &sel_b_r, &mut tmp); + let q1_oracle = q_oracle(&lanes, &edges); + rep.check( + 6, + !ans6 && !oracle6 && located && q1 == q1_oracle && q1 == q0 - 1, + format!( + "edge ({x},{y}) cleared (one word per plane): locate(y) still Ok={located}, answer now {ans6} (oracle {oracle6}); Q {q0} -> {q1} (oracle {q1_oracle})" + ), + ); + rep.census(6, look(&table) as i64 - l0 as i64, alloc_bytes() - b0); + } + + // ------------------------------------------------------------------ + // F7: clear an unrelated edge; the fixed query is unchanged + // ------------------------------------------------------------------ + let (f7_bytes, f7_calls); + { + let (l0, b0) = (look(&table), alloc_bytes()); + let out = |g: u64| lanes.a[g as usize] >= A_LT && lanes.b[g as usize] >= B_LT; + let (u, v) = edges + .iter() + .copied() + .find(|&(s, d)| out(s) && out(d)) + .expect("an edge outside A and B exists"); + let cu = coord_of(&table, &frame, &R_TILES, TW, u).expect("u in R"); + let cv = coord_of(&table, &frame, &R_TILES, TW, v).expect("v in R"); + fwd.clear(cu, cv); + rev.clear(cv, cu); + edges.retain(|&e| e != (u, v)); + let (fb0, fc0) = (alloc_bytes(), alloc_calls()); + let q2 = q_fold(&fwd, &sel_a_r, &sel_b_r, &mut tmp); + f7_bytes = alloc_bytes() - fb0; + f7_calls = alloc_calls() - fc0; + let q2_oracle = q_oracle(&lanes, &edges); + rep.check( + 7, + q2 == q1 && q2 == q2_oracle, + format!("edge ({u},{v}) outside A and B cleared: Q stays {q2} (was {q1}, oracle {q2_oracle})"), + ); + rep.census(7, look(&table) as i64 - l0 as i64, alloc_bytes() - b0); + } + + // ------------------------------------------------------------------ + // F8, F9: forward plane XOR transpose(reverse plane) + // ------------------------------------------------------------------ + { + let (l0, b0) = (look(&table), alloc_bytes()); + let t = rev.transpose(); + let mut xr = vec![0u64; fwd.rows.len()]; + mask_xor(&fwd.rows, &t.rows, &mut xr); + let set_bits = popcount(&fwd.rows) as usize; + rep.check( + 8, + !mask_any(&xr) && set_bits == edges.len() && set_bits > 1000, + format!("fwd XOR transpose(rev) == 0 over {} words; {set_bits} edges set", xr.len()), + ); + // Flip one bit of the reverse plane (an existing edge): XOR != 0 and + // the differing position is exactly that edge. + let (s, d) = edges[0]; + let cs = coord_of(&table, &frame, &R_TILES, TW, s).expect("s in R"); + let cd = coord_of(&table, &frame, &R_TILES, TW, d).expect("d in R"); + let mut rev2 = rev.clone(); + rev2.clear(cd, cs); + let t2 = rev2.transpose(); + mask_xor(&fwd.rows, &t2.rows, &mut xr); + let mut pos: Vec = Vec::new(); + for_each_bit(&xr, |p| pos.push(p)); + let want = cs * fwd.wpr * 64 + cd; + rep.check( + 9, + mask_any(&xr) && pos.len() == 1 && pos[0] == want, + format!( + "one reverse bit flipped for edge ({s},{d}) = coords ({cs},{cd}): {} differing position(s), first {:?}, expected {want}", + pos.len(), + pos.first() + ), + ); + rep.census(8, look(&table) as i64 - l0 as i64, alloc_bytes() - b0); + rep.census(9, 0, 0); + } + + // ------------------------------------------------------------------ + // F14, F15: allocation around the F5 and F7 folds + // ------------------------------------------------------------------ + rep.check( + 14, + f5_bytes == 0 && f7_bytes == 0, + format!("fold bytes allocated: check-5 fold {f5_bytes}, check-7 fold {f7_bytes}; no tuple vector (folds read Plane rows and two 8-word masks)"), + ); + rep.check( + 15, + f5_calls == 0 && f7_calls == 0, + format!("fold allocation calls: check-5 {f5_calls}, check-7 {f7_calls}; no per-object allocation"), + ); + rep.census(14, 0, f5_bytes + f7_bytes); + rep.census(15, 0, 0); + + // ------------------------------------------------------------------ + // F12, F13: guards of dr-math-binding-probe::where_dr3 over a 64-slot map + // ------------------------------------------------------------------ + { + let (l0, b0) = (look(&table), alloc_bytes()); + let hmap = HLocalMap::prepare(&dom[0..64]).expect("64-slot map"); + let gst = drp::FrameStore::new(drp::FrameRevisions { + source: 1, + relation_map: 0, + coordinates: 1, + }); + let lst = drp::FrameStore::new(drp::FrameRevisions { + source: 1, + relation_map: 1, + coordinates: hmap.digest(), + }); + let gseal = gst.seal(); + let guards = drp::Guards { + frame: lst.seal(), + focus: drp::Focus { revision: 1 }, + scope: drp::Scope { id: 7 }, + }; + let criteria = Criteria { id: 0xC1 }; + let class_c: u16 = 21; + let row_axis = drp::Axis { + class: class_c, + kind: drp::AxisKind::Identity, + }; + let col_axis = drp::Axis { + class: class_c, + kind: drp::AxisKind::Property, + }; + let m1 = drp::MethodSignature::presence(class_c, 1, row_axis, col_axis); + let m2 = drp::MethodSignature::presence(class_c, 2, row_axis, col_axis); + let rows = [0u64; 64]; + + let sel1 = project_sel(&hmap, &keep_a, &gst, &gseal, &lst, &guards, row_axis, m1, criteria); + let sel2 = project_sel(&hmap, &keep_a, &gst, &gseal, &lst, &guards, row_axis, m2, criteria); + + // F12: a register of a foreign class on the row axis. + let foreign_row = drp::Axis { + class: 22, + kind: drp::AxisKind::Identity, + }; + let foreign_col = drp::Axis { + class: 22, + kind: drp::AxisKind::Property, + }; + let mf = drp::MethodSignature::presence(22, 1, foreign_row, foreign_col); + let reg_f = bind_reg(&lst, &guards, mf, &rows); + let r12 = sel1.admit(&gst, &lst, ®_f, criteria); + rep.check( + 12, + matches!(r12, Err(ReuseRefusal::AxisMismatch)), + format!("foreign-class row axis -> {:?}", r12.as_ref().err()), + ); + + // F13a: M1's selection against M2's register. + let reg1 = bind_reg(&lst, &guards, m1, &rows); + let reg2 = bind_reg(&lst, &guards, m2, &rows); + let r13a = sel1.admit(&gst, &lst, ®2, criteria); + let twin = sel1.admit(&gst, &lst, ®1, criteria); + rep.check( + 13, + matches!(r13a, Err(ReuseRefusal::SchemaChanged)) && twin.is_ok(), + format!( + "13a M1 selection vs M2 register -> {:?}; silence twin (M1 vs M1) ok={}", + r13a.as_ref().err(), + twin.is_ok() + ), + ); + + // F13b: the two projections are bit for bit the same selection. + let a1 = sel1.admit(&gst, &lst, ®1, criteria).expect("M1 admits"); + let a2 = sel2.admit(&gst, &lst, ®2, criteria).expect("M2 admits"); + let same = a1.truth() == a2.truth() && a1.slots() == a2.slots(); + rep.check( + 13, + same && a1.truth() != 0 && a1.slots() == u64::MAX, + format!( + "13b truth M1={:#x} M2={:#x}, slots M1={:#x} M2={:#x} (projection does not depend on the method; truth non-empty)", + a1.truth(), + a2.truth(), + a1.slots(), + a2.slots() + ), + ); + + // F13c: a different Scope refuses on its own. + let guards_s = drp::Guards { + scope: drp::Scope { id: 8 }, + ..guards.clone() + }; + let reg_s = bind_reg(&lst, &guards_s, m1, &rows); + let r13c = sel1.admit(&gst, &lst, ®_s, criteria); + rep.check( + 13, + matches!(r13c, Err(ReuseRefusal::ScopeChanged)), + format!("13c scope 7 selection vs scope 8 register (same method) -> {:?}", r13c.as_ref().err()), + ); + rep.census(12, look(&table) as i64 - l0 as i64, alloc_bytes() - b0); + rep.census(13, 0, 0); + + // ------------------------------------------------------------ + // F17: Boolean vs bag on the current edge set + // ------------------------------------------------------------ + let (l1, b1) = (look(&table), alloc_bytes()); + let mut or_acc = [0u64; WPR]; + for_each_bit(&sel_a_r, |xc| mask_or_assign(&mut or_acc, fwd.row(xc))); + let distinct = popcount(&or_acc) as i64; + let mut indeg = vec![0i64; COORDS]; + for_each_bit(&sel_a_r, |xc| { + for_each_bit(fwd.row(xc), |yc| indeg[yc] += 1); + }); + let outdeg: Vec = (0..COORDS).map(|c| popcount(fwd.row(c)) as i64).collect(); + let mut prod = vec![0i64; COORDS]; + checked_binary_i64(I64Op::Mul, &indeg, &outdeg, &mut prod).expect("no overflow"); + let mut bag = 0i64; + for &p in &prod { + bag = bag.checked_add(p).expect("no overflow"); + } + let mut out_count: HashMap = HashMap::new(); + for &(s, _) in &edges { + *out_count.entry(s).or_insert(0) += 1; + } + let mut reach: HashSet = HashSet::new(); + let mut bag_o = 0i64; + for &(s, d) in &edges { + if lanes.a[s as usize] < A_LT { + reach.insert(d); + bag_o += out_count.get(&d).copied().unwrap_or(0); + } + } + let declared = drp::MethodSignature { + population: drp::Population::Bag, + ..m1 + }; + let r_bag = drp::bind_dr64( + &lst, + declared, + declared, + &guards, + (guards.focus, guards.scope), + drp::Operand { + rows: &rows, + validity: None, + }, + ); + rep.check( + 17, + distinct == reach.len() as i64 + && bag == bag_o + && distinct != bag + && matches!(r_bag, Err(drp::Refusal::BagNeedsMultiplicity)), + format!( + "one-hop distinct from A = {distinct} (oracle {}), 2-path bag from A = {bag} (oracle {bag_o}); Population::Bag -> {:?}", + reach.len(), + r_bag.as_ref().err() + ), + ); + rep.census(17, look(&table) as i64 - l1 as i64, alloc_bytes() - b1); + } + + // ------------------------------------------------------------------ + // F11: stale / foreign frame, future version, ambiguous locate + // ------------------------------------------------------------------ + { + let (l0, b0) = (look(&table), alloc_bytes()); + let mut t2 = MapTable::new(1, 1); + t2.advance( + 1, + 1, + vec![(0, Some(LocalMap::prepare(Width::W256, &dom[0..256]).expect("tile")))], + ); + let f_other = t2.seal(); + let foreign = table.map(&f_other, 0); + let foreign_ok = matches!(foreign, Err(MapRead::Stale(FrameRefusal::ForeignFrame))); + let future = table.map_at(RouteVersion(table.current_version().0 + 7), 0); + let future_ok = matches!(future, Err(MapRead::FutureVersion { .. })); + let now = table.seal(); + let ambiguous = y_sh.map(|g| table.locate(&now, &[10, 11], g)); + let ambiguous_ok = matches!(ambiguous, Some(Err(LocateRefusal::Ambiguous))); + let twin_ok = y_sh.is_some_and(|g| { + table.locate(&now, &[10], g).is_ok() && table.locate(&now, &R_TILES, g).is_ok() + }); + rep.check( + 11, + foreign_ok && future_ok && ambiguous_ok && twin_ok, + format!( + "foreign frame -> Stale(ForeignFrame)={foreign_ok}; future version -> FutureVersion={future_ok}; locate in [10,11] of the shared id -> Ambiguous={ambiguous_ok}; silence twin (single tile) Ok={twin_ok}" + ), + ); + rep.census(11, look(&table) as i64 - l0 as i64, alloc_bytes() - b0); + } + + // ------------------------------------------------------------------ + // F10: historical frame replays; a replacement is a new generation + // ------------------------------------------------------------------ + { + let (l0, b0) = (look(&table), alloc_bytes()); + let f1 = table.seal(); + let old_globals: Vec = table.map(&f1, 10).expect("tile 10 at f1").globals().to_vec(); + let rev_before = table.revisions(); + let mut reordered = old_globals.clone(); + reordered.reverse(); + let reordered_differs = reordered != old_globals; + table.advance( + 1, + 1, + vec![(10, Some(LocalMap::prepare(wa, &reordered).expect("replacement")))], + ); + let f2 = table.seal(); + let at_f1: Vec = table.map(&f1, 10).expect("tile 10 at f1").globals().to_vec(); + let at_f2: Vec = table.map(&f2, 10).expect("tile 10 at f2").globals().to_vec(); + let rev_after = table.revisions(); + let first_old = old_globals.first().copied(); + let local_old = first_old.and_then(|g| table.map(&f1, 10).ok().and_then(|m| m.local(g).ok())); + let local_new = first_old.and_then(|g| table.map(&f2, 10).ok().and_then(|m| m.local(g).ok())); + let gens = table.generation_count(10); + rep.check( + 10, + reordered_differs + && at_f1 == old_globals + && at_f2 == reordered + && local_old != local_new + && rev_before.coordinates != rev_after.coordinates + && gens == 2, + format!( + "f1 still reads the old tile 10 (first id local {local_old:?}); f2 reads the new (local {local_new:?}); coordinates revision {:#x} -> {:#x}; generations of tile 10 = {gens}", + rev_before.coordinates, rev_after.coordinates + ), + ); + rep.census(10, look(&table) as i64 - l0 as i64, alloc_bytes() - b0); + } + + // ------------------------------------------------------------------ + // F16: structure (manual) + // ------------------------------------------------------------------ + rep.check( + 16, + true, + "types defined by the probe: CountingAlloc, Rng, Lanes, Plane (bit matrix over DR coordinates), Prepared (lowered Quack program + scratch), Report (LAB); identities only via MapTable/LocalMap; id lists (dom, a_ids, b_ids, edges) are fixture/oracle input, read by no fold [manual]".to_string(), + ); + + // ------------------------------------------------------------------ + // report + // ------------------------------------------------------------------ + rep.lines.sort_by_key(|(n, _)| *n); + for (_, line) in &rep.lines { + println!("{line}"); + } + rep.census.sort_by_key(|(n, _, _)| *n); + println!("--- census (per check: TileMap lookups on tiles 0,1,10,11; bytes allocated incl. fixture and formatting) ---"); + for (n, lookups, bytes) in &rep.census { + println!("census F{n:<2} lookups={lookups} bytes={bytes}"); + } + let total = rep.lines.len(); + println!( + "falsify: {} of {total} checks failed", + rep.fails + ); + if rep.fails > 0 { + std::process::exit(1); + } +} diff --git a/.claude/probes/2026-11-03-d-global-where/probe/src/lib.rs b/.claude/probes/2026-11-03-d-global-where/probe/src/lib.rs new file mode 100644 index 000000000..638e8967d --- /dev/null +++ b/.claude/probes/2026-11-03-d-global-where/probe/src/lib.rs @@ -0,0 +1,582 @@ +//! LAB: shared helpers of the D-GLOBAL-WHERE P0 probe (falsify + bench). +//! +//! Lab only. Nothing here is production, and nothing is a new identity table: +//! identities live in `lance_graph_dt64::dr::{MapTable, LocalMap}`. The types +//! defined here are positional only (`Plane` is a bit matrix over DR +//! coordinates, `Prepared` is a lowered Quack program plus its scratch, `Rng` +//! and `CountingAlloc` are instruments). The id lists (`Vec`, edge +//! `(u32, u32)` lists) are FIXTURE and ORACLE inputs only; no timed fold reads +//! one. +//! +//! The global allocator is declared by each binary (`#[global_allocator]`), +//! not here; this crate only supplies the counting implementation and the +//! counters. + +use std::alloc::{GlobalAlloc, Layout, System}; +use std::collections::{HashMap, HashSet}; +use std::sync::atomic::{AtomicUsize, Ordering::Relaxed}; +use std::time::Instant; + +use lance_graph_dt64::dr::{Frame, LocateRefusal, MapTable, TileId, TileMap}; +use lance_graph_mask_risc::{execute_into, Foreign, LaneRef, Out, Planes, Program, Scratch, Value}; +use lance_graph_quack::{lower, Agg, Cmp, Col, Filter, Query}; + +// --------------------------------------------------------------------------- +// counting allocator (the binaries declare the #[global_allocator] static) +// --------------------------------------------------------------------------- + +/// A pass-through allocator that counts bytes, calls, live bytes and the peak. +pub struct CountingAlloc; + +static ALLOC_BYTES: AtomicUsize = AtomicUsize::new(0); +static ALLOC_CALLS: AtomicUsize = AtomicUsize::new(0); +static LIVE_BYTES: AtomicUsize = AtomicUsize::new(0); +static PEAK_BYTES: AtomicUsize = AtomicUsize::new(0); + +// SAFETY: a pure pass-through to `System`; the atomics are the only addition. +// `realloc` and `alloc_zeroed` use the trait defaults, which go through +// `alloc` and `dealloc`, so they are counted too. +unsafe impl GlobalAlloc for CountingAlloc { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + ALLOC_BYTES.fetch_add(layout.size(), Relaxed); + ALLOC_CALLS.fetch_add(1, Relaxed); + let live = LIVE_BYTES.fetch_add(layout.size(), Relaxed) + layout.size(); + PEAK_BYTES.fetch_max(live, Relaxed); + // SAFETY: same layout, same contract as the caller's. + unsafe { System.alloc(layout) } + } + unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { + LIVE_BYTES.fetch_sub(layout.size(), Relaxed); + // SAFETY: `ptr` came from `alloc` above with this `layout`. + unsafe { System.dealloc(ptr, layout) } + } +} + +/// Total bytes handed out so far (never decreases). +pub fn alloc_bytes() -> usize { + ALLOC_BYTES.load(Relaxed) +} +/// Total allocation calls so far (never decreases). +pub fn alloc_calls() -> usize { + ALLOC_CALLS.load(Relaxed) +} +/// Bytes currently live. +pub fn live_bytes() -> usize { + LIVE_BYTES.load(Relaxed) +} +/// Highest live-byte count since the last [`reset_peak`]. +pub fn peak_bytes() -> usize { + PEAK_BYTES.load(Relaxed) +} +/// Restart peak tracking from the current live bytes. +pub fn reset_peak() { + PEAK_BYTES.store(LIVE_BYTES.load(Relaxed), Relaxed); +} + +// --------------------------------------------------------------------------- +// deterministic data +// --------------------------------------------------------------------------- + +/// The probe's seed. +pub const SEED: u64 = 0x9E37_79B9_7F4A_7C15; + +/// SplitMix64. +pub struct Rng(pub u64); + +impl Rng { + pub fn new(seed: u64) -> Rng { + Rng(seed) + } + pub fn next_u64(&mut self) -> u64 { + self.0 = self.0.wrapping_add(0x9E37_79B9_7F4A_7C15); + let mut z = self.0; + z = (z ^ (z >> 30)).wrapping_mul(0xBF58_476D_1CE4_E5B9); + z = (z ^ (z >> 27)).wrapping_mul(0x94D0_49BB_1331_11EB); + z ^ (z >> 31) + } + pub fn below(&mut self, n: u64) -> u64 { + self.next_u64() % n + } + /// Uniform in `[0, 1)`. + pub fn unit(&mut self) -> f64 { + (self.next_u64() >> 11) as f64 / (1u64 << 53) as f64 + } +} + +/// Global ids in the universe (two DR256 axes' worth). +pub const UNIVERSE: usize = 65_536; +/// `u64` words of a mask over the universe. +pub const UNIVERSE_WORDS: usize = UNIVERSE / 64; +/// Selection A is `a < A_LT`. +pub const A_LT: i32 = 50; +/// Selection B is `b < B_LT`. +pub const B_LT: i32 = 300; + +/// The two value lanes over the universe, uniform in `0..1000`. +pub struct Lanes { + pub a: Vec, + pub b: Vec, +} + +pub fn gen_lanes(rng: &mut Rng) -> Lanes { + let a = (0..UNIVERSE).map(|_| rng.below(1000) as i32).collect(); + let b = (0..UNIVERSE).map(|_| rng.below(1000) as i32).collect(); + Lanes { a, b } +} + +/// `n` distinct pseudo-random global ids from the universe. +pub fn pick_domain(rng: &mut Rng, n: usize) -> Vec { + let mut all: Vec = (0..UNIVERSE as u32).collect(); + for i in 0..n { + let j = i + rng.below((UNIVERSE - i) as u64) as usize; + all.swap(i, j); + } + all[..n].iter().map(|&g| u64::from(g)).collect() +} + +/// Edge distributions of the bench. +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub enum Dist { + Sparse, + Medium, + Dense, + Skewed, +} + +impl Dist { + pub const ALL: [Dist; 4] = [Dist::Sparse, Dist::Medium, Dist::Dense, Dist::Skewed]; + pub fn name(self) -> &'static str { + match self { + Dist::Sparse => "sparse", + Dist::Medium => "medium", + Dist::Dense => "dense", + Dist::Skewed => "skewed", + } + } +} + +/// A directed edge set over the domain `dom` (global ids), no self loops, no +/// duplicates. `dense_p` is the Bernoulli probability of the dense case. +/// FIXTURE/ORACLE input: a tuple list, never read by a timed fold. +pub fn gen_edges(rng: &mut Rng, dom: &[u64], dist: Dist, dense_p: f64) -> Vec<(u32, u32)> { + let n = dom.len(); + let g = |i: usize| dom[i] as u32; + let mut e: Vec<(u32, u32)> = Vec::new(); + match dist { + Dist::Sparse => { + for i in 0..n { + let mut j = rng.below(n as u64) as usize; + if j == i { + j = (j + 1) % n; + } + e.push((g(i), g(j))); + } + } + Dist::Medium => { + let k = 8.min(n - 1); + for i in 0..n { + let mut seen: Vec = Vec::with_capacity(k); + while seen.len() < k { + let j = rng.below(n as u64) as usize; + if j != i && !seen.contains(&j) { + seen.push(j); + e.push((g(i), g(j))); + } + } + } + } + Dist::Dense => { + for i in 0..n { + for j in 0..n { + if i != j && rng.unit() < dense_p { + e.push((g(i), g(j))); + } + } + } + } + Dist::Skewed => { + // node `perm[r]` has rank r; weight 1/(r+1); total degree ~ 8n. + let mut perm: Vec = (0..n).collect(); + for i in (1..n).rev() { + let j = rng.below(i as u64 + 1) as usize; + perm.swap(i, j); + } + let mut cum: Vec = Vec::with_capacity(n); + let mut total = 0.0f64; + for r in 0..n { + total += 1.0 / (r as f64 + 1.0); + cum.push(total); + } + for r in 0..n { + let w = 1.0 / (r as f64 + 1.0); + let want = ((8.0 * n as f64) * w / total).round() as usize; + let want = want.min(n - 1); + let src = perm[r]; + let mut seen: HashSet = HashSet::new(); + let mut draws = 0usize; + while seen.len() < want && draws < want * 20 + 50 { + draws += 1; + let u = rng.unit() * total; + let rank = cum.partition_point(|&c| c < u).min(n - 1); + let dst = perm[rank]; + if dst != src && seen.insert(dst) { + e.push((g(src), g(dst))); + } + } + } + } + } + e +} + +// --------------------------------------------------------------------------- +// bit helpers +// --------------------------------------------------------------------------- + +#[inline] +pub fn bit(m: &[u64], i: usize) -> bool { + (m[i >> 6] >> (i & 63)) & 1 == 1 +} +#[inline] +pub fn set_bit(m: &mut [u64], i: usize) { + m[i >> 6] |= 1u64 << (i & 63); +} +#[inline] +pub fn clear_bit(m: &mut [u64], i: usize) { + m[i >> 6] &= !(1u64 << (i & 63)); +} +/// Set bits of a mask: `ndarray::simd::popcount_batch_u64`. +#[inline] +pub fn popcount(m: &[u64]) -> u64 { + ndarray::simd::popcount_batch_u64(m) +} +/// Call `f` with the index of every set bit, in ascending order. No allocation. +#[inline] +pub fn for_each_bit(m: &[u64], mut f: impl FnMut(usize)) { + for (w, &word) in m.iter().enumerate() { + let mut bits = word; + while bits != 0 { + f(w * 64 + bits.trailing_zeros() as usize); + bits &= bits - 1; + } + } +} +/// A mask of `len` low local positions set (a selection tile's local mask). +pub fn prefix_mask(words: usize, len: usize) -> Vec { + let mut m = vec![0u64; words]; + for i in 0..len { + set_bit(&mut m, i); + } + m +} + +// --------------------------------------------------------------------------- +// presence plane over DR coordinates (LAB) +// --------------------------------------------------------------------------- + +/// A square bit matrix over `coords` DR coordinates: row `x` holds the set of +/// coordinates `y` with an edge `x -> y`. The wide coordinate is +/// `ordinal * tile_width + local`. Positional only; it holds no identity. +#[derive(Clone)] +pub struct Plane { + pub rows: Vec, + pub coords: usize, + pub wpr: usize, +} + +impl Plane { + pub fn new(coords: usize) -> Plane { + let wpr = coords.div_ceil(64); + Plane { + rows: vec![0u64; coords * wpr], + coords, + wpr, + } + } + #[inline] + pub fn row(&self, x: usize) -> &[u64] { + &self.rows[x * self.wpr..(x + 1) * self.wpr] + } + #[inline] + pub fn set(&mut self, x: usize, y: usize) { + let wpr = self.wpr; + set_bit(&mut self.rows[x * wpr..(x + 1) * wpr], y); + } + #[inline] + pub fn clear(&mut self, x: usize, y: usize) { + let wpr = self.wpr; + clear_bit(&mut self.rows[x * wpr..(x + 1) * wpr], y); + } + #[inline] + pub fn get(&self, x: usize, y: usize) -> bool { + bit(self.row(x), y) + } + /// The transposed plane (an address map written out, for the XOR check). + pub fn transpose(&self) -> Plane { + let mut t = Plane::new(self.coords); + for x in 0..self.coords { + for_each_bit(self.row(x), |y| t.set(y, x)); + } + t + } +} + +/// The wide coordinate of `global` in the frame tiles `tiles` (each `tw` +/// positions wide): `locate`, then `ordinal * tw + local`. +pub fn coord_of( + table: &MapTable, + frame: &Frame, + tiles: &[TileId], + tw: usize, + global: u64, +) -> Result { + let (ordinal, local) = table.locate(frame, tiles, global)?; + Ok(ordinal as usize * tw + usize::from(local)) +} + +/// Route a selection tile set into the R frame's coordinates: for every local +/// of every selection tile, local -> global (the pointer table), then +/// `locate` into the R tiles. Writes the domain mask into `out`. +pub fn route_selection( + table: &MapTable, + frame: &Frame, + r_tiles: &[TileId], + tw: usize, + sel_tiles: &[TileId], + out: &mut [u64], +) { + out.fill(0); + for &st in sel_tiles { + let tm = table.map(frame, st).expect("selection tile readable"); + for l in 0..tm.len() { + let g = tm.global(l as u8).expect("local in range"); + let c = coord_of(table, frame, r_tiles, tw, g).expect("id in R frame"); + set_bit(out, c); + } + } +} + +/// Project a global Keep mask (one bit per universe id) into domain +/// coordinates: one probe per domain position, read through the R tiles' +/// `globals()` pointer tables. +pub fn project_keep(tiles: &[TileMap<'_>], tw: usize, keep: &[u64], out: &mut [u64]) { + out.fill(0); + for (t, tm) in tiles.iter().enumerate() { + for (l, &g) in tm.globals().iter().enumerate() { + if bit(keep, g as usize) { + set_bit(out, t * tw + l); + } + } + } +} + +/// The virtual WHERE: test the predicate only at the domain's globals and +/// build the domain mask directly. +pub fn virtual_where(tiles: &[TileMap<'_>], tw: usize, lane: &[i32], lt: i32, out: &mut [u64]) { + out.fill(0); + for (t, tm) in tiles.iter().enumerate() { + for (l, &g) in tm.globals().iter().enumerate() { + if lane[g as usize] < lt { + set_bit(out, t * tw + l); + } + } + } +} + +// --------------------------------------------------------------------------- +// Quack WHERE over the universe (prepared: lowered once, scratch reused) +// --------------------------------------------------------------------------- + +/// One Quack query over one `i32` lane of `n_rows` rows, lowered once. +pub struct Prepared { + program: Program, + scratch: Scratch<'static>, + n_rows: usize, +} + +impl Prepared { + /// `Query { filter: lane0 , agg }` lowered and scratch-carved. + pub fn new(cmp: Cmp, agg: Agg, n_rows: usize) -> Prepared { + let q = Query { + filter: Filter::cmp(Col(0), cmp), + agg, + }; + let program = lower(&q).expect("quack lowers"); + let scratch = Scratch::for_program(&program, n_rows).expect("scratch carves"); + Prepared { + program, + scratch, + n_rows, + } + } + + /// `Agg::Rows`: the kept mask lands in `out` (`words_for(n_rows)` long). + pub fn keep(&mut self, lane: &[i32], live: &[u64], out: &mut [u64]) { + let masks: [&[u64]; 1] = [live]; + let lanes = [LaneRef::I32(lane)]; + let planes = Planes { + n_rows: self.n_rows, + masks: &masks, + lanes: &lanes, + }; + execute_into( + &self.program, + &planes, + &Foreign::NONE, + &mut self.scratch, + Out::Mask(out), + ) + .expect("mask-risc runs"); + } + + /// `Agg::Count`. + pub fn count(&mut self, lane: &[i32], live: &[u64]) -> usize { + let masks: [&[u64]; 1] = [live]; + let lanes = [LaneRef::I32(lane)]; + let planes = Planes { + n_rows: self.n_rows, + masks: &masks, + lanes: &lanes, + }; + match execute_into( + &self.program, + &planes, + &Foreign::NONE, + &mut self.scratch, + Out::None, + ) + .expect("mask-risc runs") + { + Value::Count(c) => c, + other => panic!("expected Value::Count, got {other:?}"), + } + } +} + +// --------------------------------------------------------------------------- +// timing +// --------------------------------------------------------------------------- + +/// Run `f` `runs` times, returning each wall time in microseconds. +pub fn time_runs(runs: usize, mut f: impl FnMut()) -> Vec { + let mut out = Vec::with_capacity(runs); + for _ in 0..runs { + let t = Instant::now(); + f(); + out.push(t.elapsed().as_nanos() as f64 / 1000.0); + } + out +} + +/// `(median, p10, p90)` of a sample (sorts a copy). +pub fn stats(samples: &[f64]) -> (f64, f64, f64) { + let mut s = samples.to_vec(); + s.sort_by(|a, b| a.partial_cmp(b).unwrap()); + let at = |p: f64| s[(((s.len() - 1) as f64) * p).round() as usize]; + (at(0.5), at(0.1), at(0.9)) +} + +// --------------------------------------------------------------------------- +// scalar oracle (HashSet-based; oracle only) +// --------------------------------------------------------------------------- + +/// Answers of every workload from the edge list, with plain sets. +pub struct Oracle { + pub w1: i64, + pub w2: i64, + pub w3: i64, + pub w4: i64, + pub w5: i64, + pub w6: i64, + pub w7i: i64, + pub w8: i64, + pub sel_a: usize, + pub sel_b: usize, +} + +pub fn adjacency(edges: &[(u32, u32)]) -> HashMap> { + let mut m: HashMap> = HashMap::new(); + for &(s, d) in edges { + m.entry(s).or_default().push(d); + } + m +} + +fn w2_over(lanes: &Lanes, adj: &HashMap>) -> i64 { + adj.iter() + .filter(|&(&x, _)| lanes.a[x as usize] < A_LT) + .filter(|&(_, ys)| ys.iter().any(|&y| lanes.b[y as usize] < B_LT)) + .count() as i64 +} + +pub fn oracle(lanes: &Lanes, dom: &[u64], edges: &[(u32, u32)], deleted: &[(u32, u32)]) -> Oracle { + let adj = adjacency(edges); + let w1 = lanes.a.iter().filter(|&&v| v < A_LT).count() as i64; + let w2 = w2_over(lanes, &adj); + let w3 = adj + .iter() + .filter(|&(&x, _)| lanes.a[x as usize] < A_LT) + .filter(|&(_, ys)| { + ys.iter().any(|y| { + adj.get(y) + .is_some_and(|zs| zs.iter().any(|&z| lanes.b[z as usize] < B_LT)) + }) + }) + .count() as i64; + let mut front: HashSet = adj + .keys() + .copied() + .filter(|&x| lanes.a[x as usize] < A_LT) + .collect(); + for _ in 0..3 { + let mut next: HashSet = HashSet::new(); + for x in &front { + if let Some(ys) = adj.get(x) { + next.extend(ys.iter().copied()); + } + } + front = next; + } + let w4 = front + .iter() + .filter(|&&z| lanes.b[z as usize] < B_LT) + .count() as i64; + let mut reach: HashSet = HashSet::new(); + let mut w6 = 0i64; + for (&x, ys) in &adj { + if lanes.a[x as usize] < A_LT { + for &y in ys { + reach.insert(y); + w6 += adj.get(&y).map_or(0, |zs| zs.len() as i64); + } + } + } + let w5 = reach.len() as i64; + let sel_a = dom + .iter() + .filter(|&&g| lanes.a[g as usize] < A_LT) + .count(); + let sel_b = dom + .iter() + .filter(|&&g| lanes.b[g as usize] < B_LT) + .count(); + let w7i = dom + .iter() + .filter(|&&g| lanes.a[g as usize] < A_LT && lanes.b[g as usize] < B_LT) + .count() as i64; + let del: HashSet<(u32, u32)> = deleted.iter().copied().collect(); + let kept: Vec<(u32, u32)> = edges.iter().copied().filter(|e| !del.contains(e)).collect(); + let w8 = w2_over(lanes, &adjacency(&kept)); + Oracle { + w1, + w2, + w3, + w4, + w5, + w6, + w7i, + w8, + sel_a, + sel_b, + } +} diff --git a/.claude/probes/2026-11-03-d-global-where/results/duckdb.json b/.claude/probes/2026-11-03-d-global-where/results/duckdb.json new file mode 100644 index 000000000..cda8ecd1d --- /dev/null +++ b/.claude/probes/2026-11-03-d-global-where/results/duckdb.json @@ -0,0 +1,3602 @@ +[ + { + "dataset": "dr256_dense", + "threads": 1, + "workload": "W1", + "answer": 3296, + "cold_us": 4204.42, + "warm_med_us": 571.021, + "warm_p10_us": 524.337, + "warm_p90_us": 674.507, + "engine_us": 725.336, + "floor_us": 81.971, + "update_us": null, + "mem_bytes": 1916720, + "load_us": 48784.919 + }, + { + "dataset": "dr256_dense", + "threads": 1, + "workload": "W2", + "answer": 17, + "cold_us": 5134.506, + "warm_med_us": 2539.758, + "warm_p10_us": 2444.053, + "warm_p90_us": 2871.968, + "engine_us": 2681.859, + "floor_us": 78.067, + "update_us": null, + "mem_bytes": 1916720, + "load_us": 45242.792 + }, + { + "dataset": "dr256_dense", + "threads": 1, + "workload": "W3", + "answer": 17, + "cold_us": 5976.887, + "warm_med_us": 3643.872, + "warm_p10_us": 3450.596, + "warm_p90_us": 5192.543, + "engine_us": 3824.687, + "floor_us": 82.365, + "update_us": null, + "mem_bytes": 1916720, + "load_us": 43233.412 + }, + { + "dataset": "dr256_dense", + "threads": 1, + "workload": "W4", + "answer": 77, + "cold_us": 24915.557, + "warm_med_us": 21226.871, + "warm_p10_us": 20323.494, + "warm_p90_us": 24018.574, + "engine_us": 24739.333, + "floor_us": 114.251, + "update_us": null, + "mem_bytes": 1916720, + "load_us": 47771.602 + }, + { + "dataset": "dr256_dense", + "threads": 1, + "workload": "W5a", + "answer": 253, + "cold_us": 5945.926, + "warm_med_us": 2321.169, + "warm_p10_us": 1985.681, + "warm_p90_us": 2409.505, + "engine_us": 2575.282, + "floor_us": 92.433, + "update_us": null, + "mem_bytes": 1916720, + "load_us": 45831.1 + }, + { + "dataset": "dr256_dense", + "threads": 1, + "workload": "W6", + "answer": 71273, + "cold_us": 3704.641, + "warm_med_us": 2289.27, + "warm_p10_us": 2202.584, + "warm_p90_us": 2587.953, + "engine_us": 2946.473, + "floor_us": 97.91, + "update_us": null, + "mem_bytes": 1916720, + "load_us": 40022.993 + }, + { + "dataset": "dr256_dense", + "threads": 1, + "workload": "W7", + "answer": 17, + "cold_us": 3285.236, + "warm_med_us": 1594.853, + "warm_p10_us": 1500.892, + "warm_p90_us": 1737.349, + "engine_us": 1803.331, + "floor_us": 82.737, + "update_us": null, + "mem_bytes": 1916720, + "load_us": 41100.618 + }, + { + "dataset": "dr256_dense", + "threads": 1, + "workload": "W7i", + "answer": 4, + "cold_us": 1993.816, + "warm_med_us": 1008.102, + "warm_p10_us": 914.584, + "warm_p90_us": 1371.903, + "engine_us": 1391.144, + "floor_us": 76.123, + "update_us": null, + "mem_bytes": 1916720, + "load_us": 42128.511 + }, + { + "dataset": "dr256_dense", + "threads": 1, + "workload": "W8", + "answer": 17, + "cold_us": 5055.307, + "warm_med_us": 2705.832, + "warm_p10_us": 2530.487, + "warm_p90_us": 3468.443, + "engine_us": 3768.969, + "floor_us": 139.405, + "update_us": 3344.296, + "mem_bytes": 2178864, + "load_us": 47162.861 + }, + { + "dataset": "dr256_dense", + "threads": 1, + "workload": "W8_after", + "answer": 17, + "cold_us": 4223.703, + "warm_med_us": 2637.19, + "warm_p10_us": 2528.072, + "warm_p90_us": 3466.865, + "engine_us": 2864.182, + "floor_us": 139.405, + "update_us": null, + "mem_bytes": 2178864, + "load_us": 47162.861 + }, + { + "dataset": "dr256_dense", + "threads": 4, + "workload": "W1", + "answer": 3296, + "cold_us": 1843.096, + "warm_med_us": 815.346, + "warm_p10_us": 717.798, + "warm_p90_us": 1002.428, + "engine_us": 1092.048, + "floor_us": 240.791, + "update_us": null, + "mem_bytes": 1916720, + "load_us": 45543.439 + }, + { + "dataset": "dr256_dense", + "threads": 4, + "workload": "W2", + "answer": 17, + "cold_us": 6640.284, + "warm_med_us": 3507.473, + "warm_p10_us": 3197.868, + "warm_p90_us": 4101.717, + "engine_us": 4166.353, + "floor_us": 199.423, + "update_us": null, + "mem_bytes": 1916720, + "load_us": 44315.959 + }, + { + "dataset": "dr256_dense", + "threads": 4, + "workload": "W3", + "answer": 17, + "cold_us": 7729.946, + "warm_med_us": 4432.759, + "warm_p10_us": 4005.609, + "warm_p90_us": 5141.993, + "engine_us": 8382.845, + "floor_us": 194.824, + "update_us": null, + "mem_bytes": 1916720, + "load_us": 57441.514 + }, + { + "dataset": "dr256_dense", + "threads": 4, + "workload": "W4", + "answer": 77, + "cold_us": 29101.66, + "warm_med_us": 21478.641, + "warm_p10_us": 20446.37, + "warm_p90_us": 24631.207, + "engine_us": 21841.11, + "floor_us": 219.207, + "update_us": null, + "mem_bytes": 1916720, + "load_us": 51001.64 + }, + { + "dataset": "dr256_dense", + "threads": 4, + "workload": "W5a", + "answer": 253, + "cold_us": 4168.689, + "warm_med_us": 2343.907, + "warm_p10_us": 2125.534, + "warm_p90_us": 2830.11, + "engine_us": 2625.138, + "floor_us": 211.936, + "update_us": null, + "mem_bytes": 1916720, + "load_us": 45461.804 + }, + { + "dataset": "dr256_dense", + "threads": 4, + "workload": "W6", + "answer": 71273, + "cold_us": 4628.052, + "warm_med_us": 3269.189, + "warm_p10_us": 2915.303, + "warm_p90_us": 3902.3, + "engine_us": 3418.571, + "floor_us": 209.917, + "update_us": null, + "mem_bytes": 1916720, + "load_us": 45783.947 + }, + { + "dataset": "dr256_dense", + "threads": 4, + "workload": "W7", + "answer": 17, + "cold_us": 4387.819, + "warm_med_us": 2077.281, + "warm_p10_us": 1886.08, + "warm_p90_us": 2383.631, + "engine_us": 2268.114, + "floor_us": 195.555, + "update_us": null, + "mem_bytes": 1916720, + "load_us": 49910.34 + }, + { + "dataset": "dr256_dense", + "threads": 4, + "workload": "W7i", + "answer": 4, + "cold_us": 2419.578, + "warm_med_us": 1360.896, + "warm_p10_us": 1210.309, + "warm_p90_us": 1597.916, + "engine_us": 1832.979, + "floor_us": 199.517, + "update_us": null, + "mem_bytes": 1916720, + "load_us": 48345.029 + }, + { + "dataset": "dr256_dense", + "threads": 4, + "workload": "W8", + "answer": 17, + "cold_us": 6635.118, + "warm_med_us": 3764.62, + "warm_p10_us": 3390.893, + "warm_p90_us": 4397.527, + "engine_us": 3105.376, + "floor_us": 199.428, + "update_us": 2111.221, + "mem_bytes": 2178864, + "load_us": 49133.129 + }, + { + "dataset": "dr256_dense", + "threads": 4, + "workload": "W8_after", + "answer": 17, + "cold_us": 4791.22, + "warm_med_us": 4043.247, + "warm_p10_us": 3508.474, + "warm_p90_us": 5056.155, + "engine_us": 4412.08, + "floor_us": 199.428, + "update_us": null, + "mem_bytes": 2178864, + "load_us": 49133.129 + }, + { + "dataset": "dr256_medium", + "threads": 1, + "workload": "W1", + "answer": 3296, + "cold_us": 1279.411, + "warm_med_us": 633.392, + "warm_p10_us": 536.172, + "warm_p90_us": 852.405, + "engine_us": 749.27, + "floor_us": 82.886, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 40558.021 + }, + { + "dataset": "dr256_medium", + "threads": 1, + "workload": "W2", + "answer": 17, + "cold_us": 4000.862, + "warm_med_us": 2144.481, + "warm_p10_us": 2033.991, + "warm_p90_us": 2808.174, + "engine_us": 3148.895, + "floor_us": 152.474, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 35811.691 + }, + { + "dataset": "dr256_medium", + "threads": 1, + "workload": "W3", + "answer": 17, + "cold_us": 4257.76, + "warm_med_us": 2836.698, + "warm_p10_us": 2586.32, + "warm_p90_us": 3664.888, + "engine_us": 4144.852, + "floor_us": 137.683, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 37030.978 + }, + { + "dataset": "dr256_medium", + "threads": 1, + "workload": "W4", + "answer": 77, + "cold_us": 5976.233, + "warm_med_us": 3355.698, + "warm_p10_us": 3098.288, + "warm_p90_us": 4351.197, + "engine_us": 3498.273, + "floor_us": 110.746, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 51674.454 + }, + { + "dataset": "dr256_medium", + "threads": 1, + "workload": "W5a", + "answer": 109, + "cold_us": 3014.468, + "warm_med_us": 1747.831, + "warm_p10_us": 1623.008, + "warm_p90_us": 2111.902, + "engine_us": 2455.033, + "floor_us": 148.426, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 37431.79 + }, + { + "dataset": "dr256_medium", + "threads": 1, + "workload": "W6", + "answer": 1088, + "cold_us": 2838.465, + "warm_med_us": 1676.874, + "warm_p10_us": 1593.898, + "warm_p90_us": 1782.374, + "engine_us": 1822.886, + "floor_us": 85.834, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 38241.569 + }, + { + "dataset": "dr256_medium", + "threads": 1, + "workload": "W7", + "answer": 17, + "cold_us": 2846.298, + "warm_med_us": 2069.385, + "warm_p10_us": 1493.967, + "warm_p90_us": 2251.163, + "engine_us": 2298.205, + "floor_us": 138.049, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 42374.51 + }, + { + "dataset": "dr256_medium", + "threads": 1, + "workload": "W7i", + "answer": 4, + "cold_us": 2487.319, + "warm_med_us": 1283.04, + "warm_p10_us": 1027.095, + "warm_p90_us": 1452.763, + "engine_us": 1182.234, + "floor_us": 106.78, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 53909.894 + }, + { + "dataset": "dr256_medium", + "threads": 1, + "workload": "W8", + "answer": 17, + "cold_us": 3984.111, + "warm_med_us": 2161.605, + "warm_p10_us": 2006.843, + "warm_p90_us": 2874.802, + "engine_us": 2197.58, + "floor_us": 84.332, + "update_us": 1409.109, + "mem_bytes": 2170688, + "load_us": 39719.336 + }, + { + "dataset": "dr256_medium", + "threads": 1, + "workload": "W8_after", + "answer": 17, + "cold_us": 2294.872, + "warm_med_us": 2231.789, + "warm_p10_us": 2115.634, + "warm_p90_us": 2952.464, + "engine_us": 2389.968, + "floor_us": 84.332, + "update_us": null, + "mem_bytes": 2170688, + "load_us": 39719.336 + }, + { + "dataset": "dr256_medium", + "threads": 4, + "workload": "W1", + "answer": 3296, + "cold_us": 3151.674, + "warm_med_us": 762.673, + "warm_p10_us": 675.527, + "warm_p90_us": 951.122, + "engine_us": 822.967, + "floor_us": 178.499, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 41591.766 + }, + { + "dataset": "dr256_medium", + "threads": 4, + "workload": "W2", + "answer": 17, + "cold_us": 4758.581, + "warm_med_us": 2989.447, + "warm_p10_us": 2608.935, + "warm_p90_us": 3517.803, + "engine_us": 3018.159, + "floor_us": 218.376, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 38067.052 + }, + { + "dataset": "dr256_medium", + "threads": 4, + "workload": "W3", + "answer": 17, + "cold_us": 7220.084, + "warm_med_us": 3860.282, + "warm_p10_us": 3388.738, + "warm_p90_us": 4620.498, + "engine_us": 3664.371, + "floor_us": 193.316, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 41287.199 + }, + { + "dataset": "dr256_medium", + "threads": 4, + "workload": "W4", + "answer": 77, + "cold_us": 6291.796, + "warm_med_us": 3569.955, + "warm_p10_us": 3265.977, + "warm_p90_us": 4047.364, + "engine_us": 3722.008, + "floor_us": 183.919, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 40380.446 + }, + { + "dataset": "dr256_medium", + "threads": 4, + "workload": "W5a", + "answer": 109, + "cold_us": 4280.954, + "warm_med_us": 2234.714, + "warm_p10_us": 1974.133, + "warm_p90_us": 2624.387, + "engine_us": 3595.344, + "floor_us": 250.324, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 38050.978 + }, + { + "dataset": "dr256_medium", + "threads": 4, + "workload": "W6", + "answer": 1088, + "cold_us": 4968.253, + "warm_med_us": 2506.489, + "warm_p10_us": 2203.386, + "warm_p90_us": 3034.689, + "engine_us": 2544.04, + "floor_us": 204.247, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 40221.526 + }, + { + "dataset": "dr256_medium", + "threads": 4, + "workload": "W7", + "answer": 17, + "cold_us": 4231.845, + "warm_med_us": 2073.364, + "warm_p10_us": 1850.073, + "warm_p90_us": 2427.518, + "engine_us": 2505.176, + "floor_us": 199.328, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 39417.88 + }, + { + "dataset": "dr256_medium", + "threads": 4, + "workload": "W7i", + "answer": 4, + "cold_us": 2849.479, + "warm_med_us": 1646.79, + "warm_p10_us": 1343.236, + "warm_p90_us": 2299.147, + "engine_us": 1921.198, + "floor_us": 292.755, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 58251.659 + }, + { + "dataset": "dr256_medium", + "threads": 4, + "workload": "W8", + "answer": 17, + "cold_us": 6538.0, + "warm_med_us": 2870.013, + "warm_p10_us": 2609.981, + "warm_p90_us": 3377.435, + "engine_us": 3417.675, + "floor_us": 196.325, + "update_us": 1822.249, + "mem_bytes": 2170688, + "load_us": 51965.176 + }, + { + "dataset": "dr256_medium", + "threads": 4, + "workload": "W8_after", + "answer": 17, + "cold_us": 6769.933, + "warm_med_us": 3060.686, + "warm_p10_us": 2659.257, + "warm_p90_us": 5099.785, + "engine_us": 7467.986, + "floor_us": 196.325, + "update_us": null, + "mem_bytes": 2170688, + "load_us": 51965.176 + }, + { + "dataset": "dr256_skewed", + "threads": 1, + "workload": "W1", + "answer": 3296, + "cold_us": 1263.099, + "warm_med_us": 648.076, + "warm_p10_us": 523.329, + "warm_p90_us": 1197.953, + "engine_us": 654.744, + "floor_us": 164.053, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 50428.666 + }, + { + "dataset": "dr256_skewed", + "threads": 1, + "workload": "W2", + "answer": 9, + "cold_us": 6364.627, + "warm_med_us": 3004.576, + "warm_p10_us": 2052.801, + "warm_p90_us": 4505.489, + "engine_us": 3323.61, + "floor_us": 83.144, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 43251.55 + }, + { + "dataset": "dr256_skewed", + "threads": 1, + "workload": "W3", + "answer": 15, + "cold_us": 5368.092, + "warm_med_us": 3734.753, + "warm_p10_us": 2877.999, + "warm_p90_us": 5947.944, + "engine_us": 3384.418, + "floor_us": 183.512, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 50460.937 + }, + { + "dataset": "dr256_skewed", + "threads": 1, + "workload": "W4", + "answer": 77, + "cold_us": 9900.52, + "warm_med_us": 5410.404, + "warm_p10_us": 3584.047, + "warm_p90_us": 6908.188, + "engine_us": 4528.874, + "floor_us": 91.797, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 52574.229 + }, + { + "dataset": "dr256_skewed", + "threads": 1, + "workload": "W5a", + "answer": 50, + "cold_us": 6621.234, + "warm_med_us": 2097.008, + "warm_p10_us": 1638.842, + "warm_p90_us": 3235.587, + "engine_us": 2164.544, + "floor_us": 90.186, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 51337.419 + }, + { + "dataset": "dr256_skewed", + "threads": 1, + "workload": "W6", + "answer": 3459, + "cold_us": 3382.967, + "warm_med_us": 1767.62, + "warm_p10_us": 1642.685, + "warm_p90_us": 2705.202, + "engine_us": 1857.894, + "floor_us": 91.259, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 41586.052 + }, + { + "dataset": "dr256_skewed", + "threads": 1, + "workload": "W7", + "answer": 9, + "cold_us": 2885.015, + "warm_med_us": 1657.027, + "warm_p10_us": 1416.73, + "warm_p90_us": 3054.689, + "engine_us": 2427.019, + "floor_us": 99.566, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 47262.972 + }, + { + "dataset": "dr256_skewed", + "threads": 1, + "workload": "W7i", + "answer": 4, + "cold_us": 1879.001, + "warm_med_us": 1009.591, + "warm_p10_us": 894.038, + "warm_p90_us": 1541.925, + "engine_us": 1099.797, + "floor_us": 83.744, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 42870.943 + }, + { + "dataset": "dr256_skewed", + "threads": 1, + "workload": "W8", + "answer": 9, + "cold_us": 6194.412, + "warm_med_us": 2238.972, + "warm_p10_us": 2018.505, + "warm_p90_us": 3649.675, + "engine_us": 2899.196, + "floor_us": 171.525, + "update_us": 1781.082, + "mem_bytes": 2170688, + "load_us": 48615.328 + }, + { + "dataset": "dr256_skewed", + "threads": 1, + "workload": "W8_after", + "answer": 9, + "cold_us": 2919.618, + "warm_med_us": 2202.788, + "warm_p10_us": 2049.548, + "warm_p90_us": 3037.704, + "engine_us": 2307.272, + "floor_us": 171.525, + "update_us": null, + "mem_bytes": 2170688, + "load_us": 48615.328 + }, + { + "dataset": "dr256_skewed", + "threads": 4, + "workload": "W1", + "answer": 3296, + "cold_us": 1539.419, + "warm_med_us": 723.253, + "warm_p10_us": 645.772, + "warm_p90_us": 833.566, + "engine_us": 943.408, + "floor_us": 173.688, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 40104.355 + }, + { + "dataset": "dr256_skewed", + "threads": 4, + "workload": "W2", + "answer": 9, + "cold_us": 4922.038, + "warm_med_us": 2863.938, + "warm_p10_us": 2595.168, + "warm_p90_us": 3407.994, + "engine_us": 2880.433, + "floor_us": 183.037, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 40320.263 + }, + { + "dataset": "dr256_skewed", + "threads": 4, + "workload": "W3", + "answer": 15, + "cold_us": 7003.124, + "warm_med_us": 4160.939, + "warm_p10_us": 3661.415, + "warm_p90_us": 4909.35, + "engine_us": 4848.039, + "floor_us": 192.035, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 57129.459 + }, + { + "dataset": "dr256_skewed", + "threads": 4, + "workload": "W4", + "answer": 77, + "cold_us": 6796.63, + "warm_med_us": 3664.421, + "warm_p10_us": 3432.34, + "warm_p90_us": 4353.767, + "engine_us": 3985.923, + "floor_us": 206.292, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 41001.336 + }, + { + "dataset": "dr256_skewed", + "threads": 4, + "workload": "W5a", + "answer": 50, + "cold_us": 3795.742, + "warm_med_us": 2244.579, + "warm_p10_us": 1992.939, + "warm_p90_us": 2761.911, + "engine_us": 2525.382, + "floor_us": 198.925, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 43071.796 + }, + { + "dataset": "dr256_skewed", + "threads": 4, + "workload": "W6", + "answer": 3459, + "cold_us": 4538.073, + "warm_med_us": 2494.969, + "warm_p10_us": 2234.742, + "warm_p90_us": 2885.562, + "engine_us": 2595.589, + "floor_us": 183.883, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 42632.294 + }, + { + "dataset": "dr256_skewed", + "threads": 4, + "workload": "W7", + "answer": 9, + "cold_us": 3765.635, + "warm_med_us": 1941.93, + "warm_p10_us": 1798.667, + "warm_p90_us": 2240.414, + "engine_us": 2062.978, + "floor_us": 177.314, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 41133.231 + }, + { + "dataset": "dr256_skewed", + "threads": 4, + "workload": "W7i", + "answer": 4, + "cold_us": 2799.271, + "warm_med_us": 1380.978, + "warm_p10_us": 1212.652, + "warm_p90_us": 1641.415, + "engine_us": 1899.005, + "floor_us": 210.454, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 40607.329 + }, + { + "dataset": "dr256_skewed", + "threads": 4, + "workload": "W8", + "answer": 9, + "cold_us": 4828.575, + "warm_med_us": 2949.82, + "warm_p10_us": 2605.77, + "warm_p90_us": 3417.469, + "engine_us": 3461.787, + "floor_us": 233.016, + "update_us": 2437.018, + "mem_bytes": 2170688, + "load_us": 41232.484 + }, + { + "dataset": "dr256_skewed", + "threads": 4, + "workload": "W8_after", + "answer": 9, + "cold_us": 3269.8, + "warm_med_us": 2928.156, + "warm_p10_us": 2638.284, + "warm_p90_us": 3360.928, + "engine_us": 3114.32, + "floor_us": 233.016, + "update_us": null, + "mem_bytes": 2170688, + "load_us": 41232.484 + }, + { + "dataset": "dr256_sparse", + "threads": 1, + "workload": "W1", + "answer": 3296, + "cold_us": 1841.672, + "warm_med_us": 557.153, + "warm_p10_us": 492.28, + "warm_p90_us": 694.64, + "engine_us": 663.479, + "floor_us": 85.065, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 40289.051 + }, + { + "dataset": "dr256_sparse", + "threads": 1, + "workload": "W2", + "answer": 9, + "cold_us": 3736.809, + "warm_med_us": 2071.18, + "warm_p10_us": 1907.016, + "warm_p90_us": 2979.251, + "engine_us": 2068.918, + "floor_us": 81.1, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 34611.07 + }, + { + "dataset": "dr256_sparse", + "threads": 1, + "workload": "W3", + "answer": 4, + "cold_us": 6288.944, + "warm_med_us": 2451.604, + "warm_p10_us": 2307.29, + "warm_p90_us": 2743.543, + "engine_us": 2919.497, + "floor_us": 96.546, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 45401.11 + }, + { + "dataset": "dr256_sparse", + "threads": 1, + "workload": "W4", + "answer": 2, + "cold_us": 6585.233, + "warm_med_us": 3056.843, + "warm_p10_us": 2877.459, + "warm_p90_us": 3865.084, + "engine_us": 5010.635, + "floor_us": 178.701, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 35538.078 + }, + { + "dataset": "dr256_sparse", + "threads": 1, + "workload": "W5a", + "answer": 17, + "cold_us": 5010.647, + "warm_med_us": 1569.461, + "warm_p10_us": 1479.541, + "warm_p90_us": 1754.328, + "engine_us": 1592.681, + "floor_us": 76.788, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 36645.976 + }, + { + "dataset": "dr256_sparse", + "threads": 1, + "workload": "W6", + "answer": 17, + "cold_us": 3181.196, + "warm_med_us": 1586.619, + "warm_p10_us": 1487.633, + "warm_p90_us": 1876.218, + "engine_us": 1646.666, + "floor_us": 77.17, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 33711.447 + }, + { + "dataset": "dr256_sparse", + "threads": 1, + "workload": "W7", + "answer": 9, + "cold_us": 3016.308, + "warm_med_us": 1510.943, + "warm_p10_us": 1397.519, + "warm_p90_us": 1897.831, + "engine_us": 2367.825, + "floor_us": 146.033, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 34062.371 + }, + { + "dataset": "dr256_sparse", + "threads": 1, + "workload": "W7i", + "answer": 4, + "cold_us": 1899.979, + "warm_med_us": 908.93, + "warm_p10_us": 867.938, + "warm_p90_us": 973.906, + "engine_us": 1037.993, + "floor_us": 76.795, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 35911.929 + }, + { + "dataset": "dr256_sparse", + "threads": 1, + "workload": "W8", + "answer": 9, + "cold_us": 3560.838, + "warm_med_us": 1951.893, + "warm_p10_us": 1892.527, + "warm_p90_us": 2052.47, + "engine_us": 2045.306, + "floor_us": 78.824, + "update_us": 1336.124, + "mem_bytes": 1908544, + "load_us": 34073.786 + }, + { + "dataset": "dr256_sparse", + "threads": 1, + "workload": "W8_after", + "answer": 9, + "cold_us": 2055.637, + "warm_med_us": 2171.873, + "warm_p10_us": 1993.154, + "warm_p90_us": 2630.81, + "engine_us": 2541.114, + "floor_us": 78.824, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 34073.786 + }, + { + "dataset": "dr256_sparse", + "threads": 4, + "workload": "W1", + "answer": 3296, + "cold_us": 1851.637, + "warm_med_us": 768.049, + "warm_p10_us": 682.263, + "warm_p90_us": 916.382, + "engine_us": 922.886, + "floor_us": 211.511, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 35701.141 + }, + { + "dataset": "dr256_sparse", + "threads": 4, + "workload": "W2", + "answer": 9, + "cold_us": 4514.823, + "warm_med_us": 3014.728, + "warm_p10_us": 2645.804, + "warm_p90_us": 3547.637, + "engine_us": 2819.08, + "floor_us": 178.772, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 50188.817 + }, + { + "dataset": "dr256_sparse", + "threads": 4, + "workload": "W3", + "answer": 4, + "cold_us": 5972.607, + "warm_med_us": 3381.564, + "warm_p10_us": 3033.775, + "warm_p90_us": 4133.706, + "engine_us": 3778.11, + "floor_us": 204.125, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 37882.688 + }, + { + "dataset": "dr256_sparse", + "threads": 4, + "workload": "W4", + "answer": 2, + "cold_us": 7531.815, + "warm_med_us": 3443.303, + "warm_p10_us": 3169.731, + "warm_p90_us": 4162.535, + "engine_us": 3525.187, + "floor_us": 192.074, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 47701.201 + }, + { + "dataset": "dr256_sparse", + "threads": 4, + "workload": "W5a", + "answer": 17, + "cold_us": 3703.098, + "warm_med_us": 2388.845, + "warm_p10_us": 1989.691, + "warm_p90_us": 2726.435, + "engine_us": 2242.178, + "floor_us": 218.65, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 35724.709 + }, + { + "dataset": "dr256_sparse", + "threads": 4, + "workload": "W6", + "answer": 17, + "cold_us": 4892.226, + "warm_med_us": 2364.99, + "warm_p10_us": 2121.779, + "warm_p90_us": 2768.103, + "engine_us": 2631.206, + "floor_us": 220.673, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 36559.397 + }, + { + "dataset": "dr256_sparse", + "threads": 4, + "workload": "W7", + "answer": 9, + "cold_us": 3761.796, + "warm_med_us": 1985.073, + "warm_p10_us": 1807.532, + "warm_p90_us": 2397.722, + "engine_us": 1974.391, + "floor_us": 213.782, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 36752.976 + }, + { + "dataset": "dr256_sparse", + "threads": 4, + "workload": "W7i", + "answer": 4, + "cold_us": 2344.682, + "warm_med_us": 1397.553, + "warm_p10_us": 1199.861, + "warm_p90_us": 1665.397, + "engine_us": 1368.606, + "floor_us": 178.22, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 39005.654 + }, + { + "dataset": "dr256_sparse", + "threads": 4, + "workload": "W8", + "answer": 9, + "cold_us": 4816.634, + "warm_med_us": 2910.2, + "warm_p10_us": 2475.679, + "warm_p90_us": 3613.426, + "engine_us": 3590.212, + "floor_us": 230.797, + "update_us": 2098.361, + "mem_bytes": 1908544, + "load_us": 35648.115 + }, + { + "dataset": "dr256_sparse", + "threads": 4, + "workload": "W8_after", + "answer": 9, + "cold_us": 3648.003, + "warm_med_us": 2823.58, + "warm_p10_us": 2444.057, + "warm_p90_us": 3661.458, + "engine_us": 2897.865, + "floor_us": 230.797, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 35648.115 + }, + { + "dataset": "dr64_dense", + "threads": 1, + "workload": "W1", + "answer": 3296, + "cold_us": 1297.87, + "warm_med_us": 522.677, + "warm_p10_us": 473.12, + "warm_p90_us": 592.284, + "engine_us": 898.89, + "floor_us": 197.273, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 35584.939 + }, + { + "dataset": "dr64_dense", + "threads": 1, + "workload": "W2", + "answer": 5, + "cold_us": 4051.197, + "warm_med_us": 2029.379, + "warm_p10_us": 1934.551, + "warm_p90_us": 2252.078, + "engine_us": 2189.893, + "floor_us": 85.298, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 35807.094 + }, + { + "dataset": "dr64_dense", + "threads": 1, + "workload": "W3", + "answer": 5, + "cold_us": 4722.546, + "warm_med_us": 2890.128, + "warm_p10_us": 2545.212, + "warm_p90_us": 3528.25, + "engine_us": 5146.582, + "floor_us": 82.357, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 41327.898 + }, + { + "dataset": "dr64_dense", + "threads": 1, + "workload": "W4", + "answer": 23, + "cold_us": 6783.905, + "warm_med_us": 3247.669, + "warm_p10_us": 3071.093, + "warm_p90_us": 3811.712, + "engine_us": 3465.351, + "floor_us": 81.044, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 38489.445 + }, + { + "dataset": "dr64_dense", + "threads": 1, + "workload": "W5a", + "answer": 50, + "cold_us": 4168.606, + "warm_med_us": 1644.503, + "warm_p10_us": 1537.806, + "warm_p90_us": 2213.633, + "engine_us": 1845.588, + "floor_us": 89.691, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 38049.126 + }, + { + "dataset": "dr64_dense", + "threads": 1, + "workload": "W6", + "answer": 1261, + "cold_us": 3007.072, + "warm_med_us": 1738.917, + "warm_p10_us": 1622.946, + "warm_p90_us": 1997.95, + "engine_us": 1914.674, + "floor_us": 86.745, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 35940.494 + }, + { + "dataset": "dr64_dense", + "threads": 1, + "workload": "W7", + "answer": 5, + "cold_us": 3762.213, + "warm_med_us": 1547.624, + "warm_p10_us": 1398.735, + "warm_p90_us": 2008.014, + "engine_us": 2089.06, + "floor_us": 123.003, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 39644.033 + }, + { + "dataset": "dr64_dense", + "threads": 1, + "workload": "W7i", + "answer": 3, + "cold_us": 1806.323, + "warm_med_us": 898.889, + "warm_p10_us": 846.169, + "warm_p90_us": 1016.381, + "engine_us": 1126.746, + "floor_us": 81.325, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 36252.244 + }, + { + "dataset": "dr64_dense", + "threads": 1, + "workload": "W8", + "answer": 5, + "cold_us": 3793.522, + "warm_med_us": 2053.522, + "warm_p10_us": 1955.796, + "warm_p90_us": 2410.551, + "engine_us": 2986.746, + "floor_us": 81.933, + "update_us": 1792.513, + "mem_bytes": 2170688, + "load_us": 37004.623 + }, + { + "dataset": "dr64_dense", + "threads": 1, + "workload": "W8_after", + "answer": 5, + "cold_us": 2087.221, + "warm_med_us": 2095.408, + "warm_p10_us": 1991.103, + "warm_p90_us": 2780.883, + "engine_us": 2500.838, + "floor_us": 81.933, + "update_us": null, + "mem_bytes": 2170688, + "load_us": 37004.623 + }, + { + "dataset": "dr64_dense", + "threads": 4, + "workload": "W1", + "answer": 3296, + "cold_us": 1485.632, + "warm_med_us": 830.274, + "warm_p10_us": 699.898, + "warm_p90_us": 1104.932, + "engine_us": 878.982, + "floor_us": 203.747, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 39279.174 + }, + { + "dataset": "dr64_dense", + "threads": 4, + "workload": "W2", + "answer": 5, + "cold_us": 4739.82, + "warm_med_us": 2867.246, + "warm_p10_us": 2512.85, + "warm_p90_us": 3470.287, + "engine_us": 3001.209, + "floor_us": 210.667, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 44441.757 + }, + { + "dataset": "dr64_dense", + "threads": 4, + "workload": "W3", + "answer": 5, + "cold_us": 5671.483, + "warm_med_us": 3594.221, + "warm_p10_us": 3165.628, + "warm_p90_us": 4495.213, + "engine_us": 3744.4, + "floor_us": 219.103, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 38570.678 + }, + { + "dataset": "dr64_dense", + "threads": 4, + "workload": "W4", + "answer": 23, + "cold_us": 6254.091, + "warm_med_us": 3611.079, + "warm_p10_us": 3245.719, + "warm_p90_us": 4318.75, + "engine_us": 4368.129, + "floor_us": 207.385, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 37021.986 + }, + { + "dataset": "dr64_dense", + "threads": 4, + "workload": "W5a", + "answer": 50, + "cold_us": 4045.798, + "warm_med_us": 2181.789, + "warm_p10_us": 1960.346, + "warm_p90_us": 2601.283, + "engine_us": 2321.217, + "floor_us": 252.705, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 37472.581 + }, + { + "dataset": "dr64_dense", + "threads": 4, + "workload": "W6", + "answer": 1261, + "cold_us": 4351.248, + "warm_med_us": 2639.634, + "warm_p10_us": 2173.961, + "warm_p90_us": 2959.063, + "engine_us": 2931.294, + "floor_us": 190.486, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 38298.558 + }, + { + "dataset": "dr64_dense", + "threads": 4, + "workload": "W7", + "answer": 5, + "cold_us": 3552.67, + "warm_med_us": 2292.877, + "warm_p10_us": 1857.582, + "warm_p90_us": 2508.302, + "engine_us": 2215.871, + "floor_us": 186.742, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 40025.202 + }, + { + "dataset": "dr64_dense", + "threads": 4, + "workload": "W7i", + "answer": 3, + "cold_us": 3200.616, + "warm_med_us": 1309.417, + "warm_p10_us": 1184.213, + "warm_p90_us": 1555.461, + "engine_us": 2019.543, + "floor_us": 318.334, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 41311.873 + }, + { + "dataset": "dr64_dense", + "threads": 4, + "workload": "W8", + "answer": 5, + "cold_us": 5848.981, + "warm_med_us": 2956.245, + "warm_p10_us": 2533.264, + "warm_p90_us": 3452.448, + "engine_us": 2565.263, + "floor_us": 201.289, + "update_us": 1960.55, + "mem_bytes": 2170688, + "load_us": 39866.549 + }, + { + "dataset": "dr64_dense", + "threads": 4, + "workload": "W8_after", + "answer": 5, + "cold_us": 3221.557, + "warm_med_us": 2871.628, + "warm_p10_us": 2579.139, + "warm_p90_us": 3382.797, + "engine_us": 4108.125, + "floor_us": 201.289, + "update_us": null, + "mem_bytes": 2170688, + "load_us": 39866.549 + }, + { + "dataset": "dr64_medium", + "threads": 1, + "workload": "W1", + "answer": 3296, + "cold_us": 1346.091, + "warm_med_us": 564.224, + "warm_p10_us": 488.416, + "warm_p90_us": 835.963, + "engine_us": 820.779, + "floor_us": 87.548, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 36388.708 + }, + { + "dataset": "dr64_medium", + "threads": 1, + "workload": "W2", + "answer": 5, + "cold_us": 3709.323, + "warm_med_us": 2029.948, + "warm_p10_us": 1907.92, + "warm_p90_us": 2497.118, + "engine_us": 2174.251, + "floor_us": 81.726, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 36640.82 + }, + { + "dataset": "dr64_medium", + "threads": 1, + "workload": "W3", + "answer": 5, + "cold_us": 4093.904, + "warm_med_us": 2392.22, + "warm_p10_us": 2291.179, + "warm_p90_us": 2615.016, + "engine_us": 2650.401, + "floor_us": 81.367, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 33131.218 + }, + { + "dataset": "dr64_medium", + "threads": 1, + "workload": "W4", + "answer": 23, + "cold_us": 6243.305, + "warm_med_us": 2985.501, + "warm_p10_us": 2889.234, + "warm_p90_us": 3151.657, + "engine_us": 3249.258, + "floor_us": 83.228, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 34333.377 + }, + { + "dataset": "dr64_medium", + "threads": 1, + "workload": "W5a", + "answer": 31, + "cold_us": 3688.572, + "warm_med_us": 1596.296, + "warm_p10_us": 1515.151, + "warm_p90_us": 1682.759, + "engine_us": 1942.918, + "floor_us": 84.854, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 33967.309 + }, + { + "dataset": "dr64_medium", + "threads": 1, + "workload": "W6", + "answer": 320, + "cold_us": 3025.081, + "warm_med_us": 1668.403, + "warm_p10_us": 1570.469, + "warm_p90_us": 1838.268, + "engine_us": 1742.068, + "floor_us": 80.3, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 35487.472 + }, + { + "dataset": "dr64_medium", + "threads": 1, + "workload": "W7", + "answer": 5, + "cold_us": 2857.818, + "warm_med_us": 1407.963, + "warm_p10_us": 1345.683, + "warm_p90_us": 1483.898, + "engine_us": 1522.235, + "floor_us": 77.702, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 52002.857 + }, + { + "dataset": "dr64_medium", + "threads": 1, + "workload": "W7i", + "answer": 3, + "cold_us": 1848.308, + "warm_med_us": 865.92, + "warm_p10_us": 814.57, + "warm_p90_us": 1160.352, + "engine_us": 1007.687, + "floor_us": 80.48, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 34624.176 + }, + { + "dataset": "dr64_medium", + "threads": 1, + "workload": "W8", + "answer": 5, + "cold_us": 3534.706, + "warm_med_us": 2031.902, + "warm_p10_us": 1922.221, + "warm_p90_us": 2285.009, + "engine_us": 2111.312, + "floor_us": 91.432, + "update_us": 1389.506, + "mem_bytes": 2170688, + "load_us": 33797.172 + }, + { + "dataset": "dr64_medium", + "threads": 1, + "workload": "W8_after", + "answer": 5, + "cold_us": 3256.773, + "warm_med_us": 2099.44, + "warm_p10_us": 1967.979, + "warm_p90_us": 2755.157, + "engine_us": 2177.797, + "floor_us": 91.432, + "update_us": null, + "mem_bytes": 2170688, + "load_us": 33797.172 + }, + { + "dataset": "dr64_medium", + "threads": 4, + "workload": "W1", + "answer": 3296, + "cold_us": 1878.677, + "warm_med_us": 762.674, + "warm_p10_us": 678.095, + "warm_p90_us": 899.121, + "engine_us": 891.843, + "floor_us": 189.366, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 36992.681 + }, + { + "dataset": "dr64_medium", + "threads": 4, + "workload": "W2", + "answer": 5, + "cold_us": 5266.168, + "warm_med_us": 3068.456, + "warm_p10_us": 2624.762, + "warm_p90_us": 3569.497, + "engine_us": 3798.742, + "floor_us": 346.853, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 37836.954 + }, + { + "dataset": "dr64_medium", + "threads": 4, + "workload": "W3", + "answer": 5, + "cold_us": 5755.882, + "warm_med_us": 3441.242, + "warm_p10_us": 3056.179, + "warm_p90_us": 4250.744, + "engine_us": 3664.506, + "floor_us": 228.193, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 37925.983 + }, + { + "dataset": "dr64_medium", + "threads": 4, + "workload": "W4", + "answer": 23, + "cold_us": 7371.757, + "warm_med_us": 3506.128, + "warm_p10_us": 3203.993, + "warm_p90_us": 3965.772, + "engine_us": 4269.491, + "floor_us": 211.679, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 40461.74 + }, + { + "dataset": "dr64_medium", + "threads": 4, + "workload": "W5a", + "answer": 31, + "cold_us": 4049.382, + "warm_med_us": 2313.603, + "warm_p10_us": 1931.447, + "warm_p90_us": 2632.128, + "engine_us": 2533.743, + "floor_us": 249.946, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 39667.774 + }, + { + "dataset": "dr64_medium", + "threads": 4, + "workload": "W6", + "answer": 320, + "cold_us": 4529.971, + "warm_med_us": 2612.655, + "warm_p10_us": 2224.092, + "warm_p90_us": 3113.062, + "engine_us": 2444.487, + "floor_us": 178.52, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 36976.718 + }, + { + "dataset": "dr64_medium", + "threads": 4, + "workload": "W7", + "answer": 5, + "cold_us": 4032.59, + "warm_med_us": 1947.312, + "warm_p10_us": 1777.771, + "warm_p90_us": 2277.126, + "engine_us": 2603.939, + "floor_us": 260.468, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 37382.672 + }, + { + "dataset": "dr64_medium", + "threads": 4, + "workload": "W7i", + "answer": 3, + "cold_us": 3357.808, + "warm_med_us": 1423.105, + "warm_p10_us": 1202.098, + "warm_p90_us": 1815.425, + "engine_us": 1559.764, + "floor_us": 196.31, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 43001.241 + }, + { + "dataset": "dr64_medium", + "threads": 4, + "workload": "W8", + "answer": 5, + "cold_us": 5036.127, + "warm_med_us": 2926.385, + "warm_p10_us": 2524.497, + "warm_p90_us": 3403.201, + "engine_us": 4257.542, + "floor_us": 226.924, + "update_us": 2187.404, + "mem_bytes": 2170688, + "load_us": 37937.729 + }, + { + "dataset": "dr64_medium", + "threads": 4, + "workload": "W8_after", + "answer": 5, + "cold_us": 3639.092, + "warm_med_us": 2923.343, + "warm_p10_us": 2570.782, + "warm_p90_us": 3474.163, + "engine_us": 3308.679, + "floor_us": 226.924, + "update_us": null, + "mem_bytes": 2170688, + "load_us": 37937.729 + }, + { + "dataset": "dr64_skewed", + "threads": 1, + "workload": "W1", + "answer": 3296, + "cold_us": 1301.071, + "warm_med_us": 520.058, + "warm_p10_us": 465.425, + "warm_p90_us": 595.632, + "engine_us": 641.772, + "floor_us": 82.876, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 34310.298 + }, + { + "dataset": "dr64_skewed", + "threads": 1, + "workload": "W2", + "answer": 4, + "cold_us": 3834.691, + "warm_med_us": 1983.992, + "warm_p10_us": 1929.487, + "warm_p90_us": 2126.649, + "engine_us": 2156.047, + "floor_us": 81.632, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 34475.934 + }, + { + "dataset": "dr64_skewed", + "threads": 1, + "workload": "W3", + "answer": 5, + "cold_us": 4463.994, + "warm_med_us": 2463.164, + "warm_p10_us": 2329.753, + "warm_p90_us": 3152.355, + "engine_us": 2479.899, + "floor_us": 83.407, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 35936.015 + }, + { + "dataset": "dr64_skewed", + "threads": 1, + "workload": "W4", + "answer": 23, + "cold_us": 6753.709, + "warm_med_us": 3302.256, + "warm_p10_us": 3004.552, + "warm_p90_us": 4567.712, + "engine_us": 3500.248, + "floor_us": 83.422, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 34816.225 + }, + { + "dataset": "dr64_skewed", + "threads": 1, + "workload": "W5a", + "answer": 27, + "cold_us": 3919.971, + "warm_med_us": 1609.223, + "warm_p10_us": 1516.314, + "warm_p90_us": 1885.293, + "engine_us": 1865.398, + "floor_us": 86.334, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 34964.338 + }, + { + "dataset": "dr64_skewed", + "threads": 1, + "workload": "W6", + "answer": 528, + "cold_us": 3653.644, + "warm_med_us": 1668.252, + "warm_p10_us": 1564.815, + "warm_p90_us": 1865.689, + "engine_us": 1848.034, + "floor_us": 80.775, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 36034.361 + }, + { + "dataset": "dr64_skewed", + "threads": 1, + "workload": "W7", + "answer": 4, + "cold_us": 3208.22, + "warm_med_us": 1483.602, + "warm_p10_us": 1382.85, + "warm_p90_us": 1732.261, + "engine_us": 1623.119, + "floor_us": 76.668, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 35154.587 + }, + { + "dataset": "dr64_skewed", + "threads": 1, + "workload": "W7i", + "answer": 3, + "cold_us": 2097.926, + "warm_med_us": 966.348, + "warm_p10_us": 859.196, + "warm_p90_us": 1314.457, + "engine_us": 1367.624, + "floor_us": 131.058, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 36084.374 + }, + { + "dataset": "dr64_skewed", + "threads": 1, + "workload": "W8", + "answer": 4, + "cold_us": 3681.172, + "warm_med_us": 2120.966, + "warm_p10_us": 1909.461, + "warm_p90_us": 2819.89, + "engine_us": 2195.553, + "floor_us": 81.817, + "update_us": 1373.41, + "mem_bytes": 1908544, + "load_us": 34849.702 + }, + { + "dataset": "dr64_skewed", + "threads": 1, + "workload": "W8_after", + "answer": 4, + "cold_us": 2289.714, + "warm_med_us": 2125.915, + "warm_p10_us": 1995.489, + "warm_p90_us": 3020.121, + "engine_us": 2666.246, + "floor_us": 81.817, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 34849.702 + }, + { + "dataset": "dr64_skewed", + "threads": 4, + "workload": "W1", + "answer": 3296, + "cold_us": 1862.115, + "warm_med_us": 834.283, + "warm_p10_us": 679.729, + "warm_p90_us": 1116.474, + "engine_us": 868.8, + "floor_us": 202.629, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 52489.284 + }, + { + "dataset": "dr64_skewed", + "threads": 4, + "workload": "W2", + "answer": 4, + "cold_us": 5094.473, + "warm_med_us": 2775.153, + "warm_p10_us": 2419.216, + "warm_p90_us": 3243.21, + "engine_us": 2674.845, + "floor_us": 205.836, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 47081.845 + }, + { + "dataset": "dr64_skewed", + "threads": 4, + "workload": "W3", + "answer": 5, + "cold_us": 7069.502, + "warm_med_us": 3482.058, + "warm_p10_us": 3060.815, + "warm_p90_us": 4077.718, + "engine_us": 3554.206, + "floor_us": 199.253, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 40063.336 + }, + { + "dataset": "dr64_skewed", + "threads": 4, + "workload": "W4", + "answer": 23, + "cold_us": 6559.575, + "warm_med_us": 3657.712, + "warm_p10_us": 3235.726, + "warm_p90_us": 4278.526, + "engine_us": 3334.313, + "floor_us": 200.48, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 38531.519 + }, + { + "dataset": "dr64_skewed", + "threads": 4, + "workload": "W5a", + "answer": 27, + "cold_us": 3933.002, + "warm_med_us": 2432.946, + "warm_p10_us": 2029.011, + "warm_p90_us": 2889.238, + "engine_us": 2451.252, + "floor_us": 198.46, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 42212.087 + }, + { + "dataset": "dr64_skewed", + "threads": 4, + "workload": "W6", + "answer": 528, + "cold_us": 4236.488, + "warm_med_us": 2662.783, + "warm_p10_us": 2151.238, + "warm_p90_us": 3034.854, + "engine_us": 2144.537, + "floor_us": 229.905, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 35967.827 + }, + { + "dataset": "dr64_skewed", + "threads": 4, + "workload": "W7", + "answer": 4, + "cold_us": 3989.032, + "warm_med_us": 1962.665, + "warm_p10_us": 1757.712, + "warm_p90_us": 2304.276, + "engine_us": 2183.004, + "floor_us": 208.837, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 37624.878 + }, + { + "dataset": "dr64_skewed", + "threads": 4, + "workload": "W7i", + "answer": 3, + "cold_us": 2884.754, + "warm_med_us": 1356.918, + "warm_p10_us": 1197.574, + "warm_p90_us": 1691.159, + "engine_us": 1739.514, + "floor_us": 302.372, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 47037.085 + }, + { + "dataset": "dr64_skewed", + "threads": 4, + "workload": "W8", + "answer": 4, + "cold_us": 6361.621, + "warm_med_us": 3062.876, + "warm_p10_us": 2549.646, + "warm_p90_us": 3592.475, + "engine_us": 3430.159, + "floor_us": 198.86, + "update_us": 2047.311, + "mem_bytes": 1908544, + "load_us": 49253.937 + }, + { + "dataset": "dr64_skewed", + "threads": 4, + "workload": "W8_after", + "answer": 4, + "cold_us": 3257.749, + "warm_med_us": 2999.314, + "warm_p10_us": 2692.724, + "warm_p90_us": 3467.354, + "engine_us": 3179.452, + "floor_us": 198.86, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 49253.937 + }, + { + "dataset": "dr64_sparse", + "threads": 1, + "workload": "W1", + "answer": 3296, + "cold_us": 1239.427, + "warm_med_us": 538.593, + "warm_p10_us": 485.611, + "warm_p90_us": 632.943, + "engine_us": 602.081, + "floor_us": 80.605, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 32569.537 + }, + { + "dataset": "dr64_sparse", + "threads": 1, + "workload": "W2", + "answer": 0, + "cold_us": 4347.853, + "warm_med_us": 2896.504, + "warm_p10_us": 2623.511, + "warm_p90_us": 3039.116, + "engine_us": 2238.948, + "floor_us": 75.575, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 37069.343 + }, + { + "dataset": "dr64_sparse", + "threads": 1, + "workload": "W3", + "answer": 0, + "cold_us": 4296.125, + "warm_med_us": 2514.476, + "warm_p10_us": 2341.993, + "warm_p90_us": 2956.346, + "engine_us": 3931.926, + "floor_us": 146.674, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 32943.585 + }, + { + "dataset": "dr64_sparse", + "threads": 1, + "workload": "W4", + "answer": 1, + "cold_us": 6009.561, + "warm_med_us": 2888.275, + "warm_p10_us": 2801.18, + "warm_p90_us": 3162.055, + "engine_us": 3195.067, + "floor_us": 79.391, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 34003.914 + }, + { + "dataset": "dr64_sparse", + "threads": 1, + "workload": "W5a", + "answer": 5, + "cold_us": 3928.861, + "warm_med_us": 1570.747, + "warm_p10_us": 1470.541, + "warm_p90_us": 1938.582, + "engine_us": 1725.377, + "floor_us": 78.122, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 33281.022 + }, + { + "dataset": "dr64_sparse", + "threads": 1, + "workload": "W6", + "answer": 5, + "cold_us": 3034.59, + "warm_med_us": 1580.216, + "warm_p10_us": 1474.242, + "warm_p90_us": 1780.173, + "engine_us": 1827.097, + "floor_us": 78.431, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 33665.723 + }, + { + "dataset": "dr64_sparse", + "threads": 1, + "workload": "W7", + "answer": 0, + "cold_us": 2934.695, + "warm_med_us": 1418.65, + "warm_p10_us": 1332.207, + "warm_p90_us": 1525.551, + "engine_us": 1469.743, + "floor_us": 76.835, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 37997.863 + }, + { + "dataset": "dr64_sparse", + "threads": 1, + "workload": "W7i", + "answer": 3, + "cold_us": 1988.812, + "warm_med_us": 876.984, + "warm_p10_us": 819.18, + "warm_p90_us": 960.576, + "engine_us": 1028.109, + "floor_us": 79.956, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 33434.823 + }, + { + "dataset": "dr64_sparse", + "threads": 1, + "workload": "W8", + "answer": 0, + "cold_us": 3774.719, + "warm_med_us": 2425.73, + "warm_p10_us": 1958.221, + "warm_p90_us": 2987.731, + "engine_us": 2464.148, + "floor_us": 81.166, + "update_us": 1318.201, + "mem_bytes": 1908544, + "load_us": 36868.918 + }, + { + "dataset": "dr64_sparse", + "threads": 1, + "workload": "W8_after", + "answer": 0, + "cold_us": 2331.586, + "warm_med_us": 2099.582, + "warm_p10_us": 1998.032, + "warm_p90_us": 2546.345, + "engine_us": 2285.225, + "floor_us": 81.166, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 36868.918 + }, + { + "dataset": "dr64_sparse", + "threads": 4, + "workload": "W1", + "answer": 3296, + "cold_us": 1641.935, + "warm_med_us": 775.643, + "warm_p10_us": 677.042, + "warm_p90_us": 936.011, + "engine_us": 854.077, + "floor_us": 179.414, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 36669.391 + }, + { + "dataset": "dr64_sparse", + "threads": 4, + "workload": "W2", + "answer": 0, + "cold_us": 5010.143, + "warm_med_us": 2911.125, + "warm_p10_us": 2563.012, + "warm_p90_us": 3522.233, + "engine_us": 3069.906, + "floor_us": 234.569, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 36183.71 + }, + { + "dataset": "dr64_sparse", + "threads": 4, + "workload": "W3", + "answer": 0, + "cold_us": 6652.842, + "warm_med_us": 3479.647, + "warm_p10_us": 3027.958, + "warm_p90_us": 4221.247, + "engine_us": 4345.656, + "floor_us": 196.469, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 40255.658 + }, + { + "dataset": "dr64_sparse", + "threads": 4, + "workload": "W4", + "answer": 1, + "cold_us": 5878.703, + "warm_med_us": 3534.205, + "warm_p10_us": 3175.327, + "warm_p90_us": 4310.303, + "engine_us": 3606.393, + "floor_us": 238.615, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 36619.285 + }, + { + "dataset": "dr64_sparse", + "threads": 4, + "workload": "W5a", + "answer": 5, + "cold_us": 3415.134, + "warm_med_us": 2079.262, + "warm_p10_us": 1844.957, + "warm_p90_us": 2617.268, + "engine_us": 2524.024, + "floor_us": 242.42, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 37150.57 + }, + { + "dataset": "dr64_sparse", + "threads": 4, + "workload": "W6", + "answer": 5, + "cold_us": 4729.899, + "warm_med_us": 2359.08, + "warm_p10_us": 2057.436, + "warm_p90_us": 2842.214, + "engine_us": 2550.004, + "floor_us": 203.573, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 42040.708 + }, + { + "dataset": "dr64_sparse", + "threads": 4, + "workload": "W7", + "answer": 0, + "cold_us": 4396.966, + "warm_med_us": 1962.276, + "warm_p10_us": 1773.011, + "warm_p90_us": 2424.197, + "engine_us": 7155.796, + "floor_us": 207.363, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 39529.36 + }, + { + "dataset": "dr64_sparse", + "threads": 4, + "workload": "W7i", + "answer": 3, + "cold_us": 2280.731, + "warm_med_us": 1290.258, + "warm_p10_us": 1168.809, + "warm_p90_us": 1427.314, + "engine_us": 1484.903, + "floor_us": 258.163, + "update_us": null, + "mem_bytes": 1646400, + "load_us": 36862.291 + }, + { + "dataset": "dr64_sparse", + "threads": 4, + "workload": "W8", + "answer": 0, + "cold_us": 4568.791, + "warm_med_us": 2865.222, + "warm_p10_us": 2486.767, + "warm_p90_us": 3477.714, + "engine_us": 2970.512, + "floor_us": 228.461, + "update_us": 1863.847, + "mem_bytes": 1908544, + "load_us": 34874.573 + }, + { + "dataset": "dr64_sparse", + "threads": 4, + "workload": "W8_after", + "answer": 0, + "cold_us": 3075.892, + "warm_med_us": 2711.569, + "warm_p10_us": 2479.013, + "warm_p90_us": 3005.606, + "engine_us": 3072.389, + "floor_us": 228.461, + "update_us": null, + "mem_bytes": 1908544, + "load_us": 34874.573 + }, + { + "dataset": "multi_dense", + "threads": 1, + "workload": "W1", + "answer": 3296, + "cold_us": 1259.613, + "warm_med_us": 581.002, + "warm_p10_us": 500.541, + "warm_p90_us": 879.903, + "engine_us": 685.951, + "floor_us": 79.964, + "update_us": null, + "mem_bytes": 6888960, + "load_us": 99286.639 + }, + { + "dataset": "multi_dense", + "threads": 1, + "workload": "W2", + "answer": 223, + "cold_us": 6748.353, + "warm_med_us": 4256.453, + "warm_p10_us": 4057.743, + "warm_p90_us": 5597.716, + "engine_us": 4395.798, + "floor_us": 78.204, + "update_us": null, + "mem_bytes": 6888960, + "load_us": 97909.085 + }, + { + "dataset": "multi_dense", + "threads": 1, + "workload": "W3", + "answer": 223, + "cold_us": 35491.175, + "warm_med_us": 29181.54, + "warm_p10_us": 27059.364, + "warm_p90_us": 38088.266, + "engine_us": 30325.997, + "floor_us": 84.88, + "update_us": null, + "mem_bytes": 6888960, + "load_us": 96120.239 + }, + { + "dataset": "multi_dense", + "threads": 1, + "workload": "W4", + "answer": 1181, + "cold_us": 1556062.941, + "warm_med_us": 1500810.989, + "warm_p10_us": 1400407.931, + "warm_p90_us": 1640764.105, + "engine_us": 1575040.891, + "floor_us": 87.415, + "update_us": null, + "mem_bytes": 6888960, + "load_us": 110549.033 + }, + { + "dataset": "multi_dense", + "threads": 1, + "workload": "W5a", + "answer": 4088, + "cold_us": 6162.43, + "warm_med_us": 3522.957, + "warm_p10_us": 3405.488, + "warm_p90_us": 3877.299, + "engine_us": 3843.895, + "floor_us": 77.338, + "update_us": null, + "mem_bytes": 6888960, + "load_us": 98209.696 + }, + { + "dataset": "multi_dense", + "threads": 1, + "workload": "W6", + "answer": 3382676, + "cold_us": 23977.346, + "warm_med_us": 22810.24, + "warm_p10_us": 21777.748, + "warm_p90_us": 28844.693, + "engine_us": 25040.614, + "floor_us": 84.772, + "update_us": null, + "mem_bytes": 6888960, + "load_us": 94480.645 + }, + { + "dataset": "multi_dense", + "threads": 1, + "workload": "W7", + "answer": 223, + "cold_us": 5470.919, + "warm_med_us": 3413.757, + "warm_p10_us": 3289.716, + "warm_p90_us": 3696.58, + "engine_us": 3675.733, + "floor_us": 85.743, + "update_us": null, + "mem_bytes": 6888960, + "load_us": 98382.759 + }, + { + "dataset": "multi_dense", + "threads": 1, + "workload": "W7i", + "answer": 77, + "cold_us": 1852.346, + "warm_med_us": 1003.246, + "warm_p10_us": 913.744, + "warm_p90_us": 1265.89, + "engine_us": 1028.374, + "floor_us": 77.293, + "update_us": null, + "mem_bytes": 6888960, + "load_us": 101171.767 + }, + { + "dataset": "multi_dense", + "threads": 1, + "workload": "W8", + "answer": 223, + "cold_us": 6445.218, + "warm_med_us": 4136.655, + "warm_p10_us": 4019.951, + "warm_p90_us": 4416.164, + "engine_us": 4399.539, + "floor_us": 81.181, + "update_us": 9685.406, + "mem_bytes": 11345408, + "load_us": 117057.352 + }, + { + "dataset": "multi_dense", + "threads": 1, + "workload": "W8_after", + "answer": 223, + "cold_us": 5713.633, + "warm_med_us": 4941.109, + "warm_p10_us": 4820.753, + "warm_p90_us": 5403.444, + "engine_us": 4938.276, + "floor_us": 81.181, + "update_us": null, + "mem_bytes": 11345408, + "load_us": 117057.352 + }, + { + "dataset": "multi_dense", + "threads": 4, + "workload": "W1", + "answer": 3296, + "cold_us": 1611.656, + "warm_med_us": 818.03, + "warm_p10_us": 718.842, + "warm_p90_us": 993.994, + "engine_us": 1014.758, + "floor_us": 206.703, + "update_us": null, + "mem_bytes": 6888960, + "load_us": 94927.496 + }, + { + "dataset": "multi_dense", + "threads": 4, + "workload": "W2", + "answer": 223, + "cold_us": 7666.015, + "warm_med_us": 4033.178, + "warm_p10_us": 3600.226, + "warm_p90_us": 4659.469, + "engine_us": 4930.824, + "floor_us": 236.278, + "update_us": null, + "mem_bytes": 6888960, + "load_us": 121143.417 + }, + { + "dataset": "multi_dense", + "threads": 4, + "workload": "W3", + "answer": 223, + "cold_us": 22632.831, + "warm_med_us": 18214.673, + "warm_p10_us": 15577.243, + "warm_p90_us": 20896.634, + "engine_us": 17804.159, + "floor_us": 225.533, + "update_us": null, + "mem_bytes": 6888960, + "load_us": 126650.019 + }, + { + "dataset": "multi_dense", + "threads": 4, + "workload": "W4", + "answer": 1181, + "cold_us": 426431.234, + "warm_med_us": 418475.917, + "warm_p10_us": 376202.893, + "warm_p90_us": 494155.433, + "engine_us": 432082.692, + "floor_us": 187.173, + "update_us": null, + "mem_bytes": 6888960, + "load_us": 116276.309 + }, + { + "dataset": "multi_dense", + "threads": 4, + "workload": "W5a", + "answer": 4088, + "cold_us": 5895.387, + "warm_med_us": 3676.483, + "warm_p10_us": 3160.296, + "warm_p90_us": 4108.393, + "engine_us": 4321.588, + "floor_us": 269.757, + "update_us": null, + "mem_bytes": 6888960, + "load_us": 101128.408 + }, + { + "dataset": "multi_dense", + "threads": 4, + "workload": "W6", + "answer": 3382676, + "cold_us": 14918.35, + "warm_med_us": 11563.663, + "warm_p10_us": 9152.996, + "warm_p90_us": 12667.195, + "engine_us": 11408.479, + "floor_us": 184.42, + "update_us": null, + "mem_bytes": 6888960, + "load_us": 109062.879 + }, + { + "dataset": "multi_dense", + "threads": 4, + "workload": "W7", + "answer": 223, + "cold_us": 5188.17, + "warm_med_us": 3023.142, + "warm_p10_us": 2377.772, + "warm_p90_us": 3628.104, + "engine_us": 3691.4, + "floor_us": 307.835, + "update_us": null, + "mem_bytes": 6888960, + "load_us": 99036.158 + }, + { + "dataset": "multi_dense", + "threads": 4, + "workload": "W7i", + "answer": 77, + "cold_us": 2921.31, + "warm_med_us": 1357.688, + "warm_p10_us": 1180.214, + "warm_p90_us": 1640.662, + "engine_us": 1758.43, + "floor_us": 215.19, + "update_us": null, + "mem_bytes": 6888960, + "load_us": 112034.426 + }, + { + "dataset": "multi_dense", + "threads": 4, + "workload": "W8", + "answer": 223, + "cold_us": 6401.298, + "warm_med_us": 4060.908, + "warm_p10_us": 3588.437, + "warm_p90_us": 4706.583, + "engine_us": 4949.11, + "floor_us": 312.635, + "update_us": 5787.432, + "mem_bytes": 11345408, + "load_us": 105338.441 + }, + { + "dataset": "multi_dense", + "threads": 4, + "workload": "W8_after", + "answer": 223, + "cold_us": 5433.234, + "warm_med_us": 4256.778, + "warm_p10_us": 3830.913, + "warm_p90_us": 4971.949, + "engine_us": 4949.687, + "floor_us": 312.635, + "update_us": null, + "mem_bytes": 11345408, + "load_us": 105338.441 + }, + { + "dataset": "multi_medium", + "threads": 1, + "workload": "W1", + "answer": 3296, + "cold_us": 1400.626, + "warm_med_us": 587.751, + "warm_p10_us": 498.716, + "warm_p90_us": 735.684, + "engine_us": 656.858, + "floor_us": 82.846, + "update_us": null, + "mem_bytes": 2441008, + "load_us": 50159.118 + }, + { + "dataset": "multi_medium", + "threads": 1, + "workload": "W2", + "answer": 211, + "cold_us": 4901.583, + "warm_med_us": 2877.759, + "warm_p10_us": 2713.956, + "warm_p90_us": 3817.273, + "engine_us": 3062.932, + "floor_us": 85.713, + "update_us": null, + "mem_bytes": 2441008, + "load_us": 52478.449 + }, + { + "dataset": "multi_medium", + "threads": 1, + "workload": "W3", + "answer": 223, + "cold_us": 8657.067, + "warm_med_us": 4257.49, + "warm_p10_us": 3570.232, + "warm_p90_us": 5258.869, + "engine_us": 3864.418, + "floor_us": 80.621, + "update_us": null, + "mem_bytes": 2441008, + "load_us": 59718.45 + }, + { + "dataset": "multi_medium", + "threads": 1, + "workload": "W4", + "answer": 1181, + "cold_us": 10517.962, + "warm_med_us": 6015.021, + "warm_p10_us": 5283.467, + "warm_p90_us": 7934.819, + "engine_us": 7502.063, + "floor_us": 104.977, + "update_us": null, + "mem_bytes": 2441008, + "load_us": 54815.647 + }, + { + "dataset": "multi_medium", + "threads": 1, + "workload": "W5a", + "answer": 1448, + "cold_us": 6089.337, + "warm_med_us": 1888.307, + "warm_p10_us": 1778.712, + "warm_p90_us": 2231.625, + "engine_us": 2137.81, + "floor_us": 80.785, + "update_us": null, + "mem_bytes": 2441008, + "load_us": 76966.125 + }, + { + "dataset": "multi_medium", + "threads": 1, + "workload": "W6", + "answer": 14272, + "cold_us": 3762.844, + "warm_med_us": 2354.635, + "warm_p10_us": 2167.355, + "warm_p90_us": 3440.77, + "engine_us": 3633.844, + "floor_us": 129.982, + "update_us": null, + "mem_bytes": 2441008, + "load_us": 46598.381 + }, + { + "dataset": "multi_medium", + "threads": 1, + "workload": "W7", + "answer": 211, + "cold_us": 4324.563, + "warm_med_us": 1821.951, + "warm_p10_us": 1629.513, + "warm_p90_us": 2388.567, + "engine_us": 2767.643, + "floor_us": 141.118, + "update_us": null, + "mem_bytes": 2441008, + "load_us": 60586.209 + }, + { + "dataset": "multi_medium", + "threads": 1, + "workload": "W7i", + "answer": 77, + "cold_us": 2545.601, + "warm_med_us": 918.387, + "warm_p10_us": 875.29, + "warm_p90_us": 1033.654, + "engine_us": 1056.427, + "floor_us": 76.547, + "update_us": null, + "mem_bytes": 2441008, + "load_us": 58429.505 + }, + { + "dataset": "multi_medium", + "threads": 1, + "workload": "W8", + "answer": 211, + "cold_us": 4945.219, + "warm_med_us": 2794.708, + "warm_p10_us": 2674.046, + "warm_p90_us": 3109.857, + "engine_us": 3003.234, + "floor_us": 80.612, + "update_us": 1860.099, + "mem_bytes": 2965296, + "load_us": 47164.779 + }, + { + "dataset": "multi_medium", + "threads": 1, + "workload": "W8_after", + "answer": 209, + "cold_us": 3119.99, + "warm_med_us": 2932.679, + "warm_p10_us": 2815.525, + "warm_p90_us": 3195.291, + "engine_us": 3447.048, + "floor_us": 80.612, + "update_us": null, + "mem_bytes": 2965296, + "load_us": 47164.779 + }, + { + "dataset": "multi_medium", + "threads": 4, + "workload": "W1", + "answer": 3296, + "cold_us": 1688.604, + "warm_med_us": 824.661, + "warm_p10_us": 727.258, + "warm_p90_us": 1003.405, + "engine_us": 1208.444, + "floor_us": 235.31, + "update_us": null, + "mem_bytes": 2441008, + "load_us": 51578.862 + }, + { + "dataset": "multi_medium", + "threads": 4, + "workload": "W2", + "answer": 211, + "cold_us": 7342.112, + "warm_med_us": 4100.088, + "warm_p10_us": 3574.204, + "warm_p90_us": 4658.569, + "engine_us": 4886.941, + "floor_us": 255.377, + "update_us": null, + "mem_bytes": 2441008, + "load_us": 53951.358 + }, + { + "dataset": "multi_medium", + "threads": 4, + "workload": "W3", + "answer": 223, + "cold_us": 11989.559, + "warm_med_us": 4910.585, + "warm_p10_us": 4260.493, + "warm_p90_us": 5678.892, + "engine_us": 5314.391, + "floor_us": 231.116, + "update_us": null, + "mem_bytes": 2441008, + "load_us": 55873.43 + }, + { + "dataset": "multi_medium", + "threads": 4, + "workload": "W4", + "answer": 1181, + "cold_us": 9476.33, + "warm_med_us": 6310.614, + "warm_p10_us": 5516.048, + "warm_p90_us": 7532.441, + "engine_us": 7502.427, + "floor_us": 316.063, + "update_us": null, + "mem_bytes": 2441008, + "load_us": 73015.623 + }, + { + "dataset": "multi_medium", + "threads": 4, + "workload": "W5a", + "answer": 1448, + "cold_us": 6232.026, + "warm_med_us": 2750.593, + "warm_p10_us": 2374.537, + "warm_p90_us": 3324.825, + "engine_us": 3044.023, + "floor_us": 307.233, + "update_us": null, + "mem_bytes": 2441008, + "load_us": 57980.535 + }, + { + "dataset": "multi_medium", + "threads": 4, + "workload": "W6", + "answer": 14272, + "cold_us": 5576.189, + "warm_med_us": 3482.665, + "warm_p10_us": 2906.966, + "warm_p90_us": 3975.203, + "engine_us": 3945.107, + "floor_us": 229.307, + "update_us": null, + "mem_bytes": 2441008, + "load_us": 60149.886 + }, + { + "dataset": "multi_medium", + "threads": 4, + "workload": "W7", + "answer": 211, + "cold_us": 4303.453, + "warm_med_us": 2193.272, + "warm_p10_us": 2027.192, + "warm_p90_us": 2658.607, + "engine_us": 2416.154, + "floor_us": 197.751, + "update_us": null, + "mem_bytes": 2441008, + "load_us": 53131.952 + }, + { + "dataset": "multi_medium", + "threads": 4, + "workload": "W7i", + "answer": 77, + "cold_us": 2726.45, + "warm_med_us": 1615.385, + "warm_p10_us": 1357.848, + "warm_p90_us": 1888.298, + "engine_us": 1649.326, + "floor_us": 206.197, + "update_us": null, + "mem_bytes": 2441008, + "load_us": 57845.054 + }, + { + "dataset": "multi_medium", + "threads": 4, + "workload": "W8", + "answer": 211, + "cold_us": 6863.79, + "warm_med_us": 4596.472, + "warm_p10_us": 3979.937, + "warm_p90_us": 5232.085, + "engine_us": 4554.434, + "floor_us": 259.347, + "update_us": 2607.774, + "mem_bytes": 2965296, + "load_us": 51867.172 + }, + { + "dataset": "multi_medium", + "threads": 4, + "workload": "W8_after", + "answer": 209, + "cold_us": 4081.658, + "warm_med_us": 4522.562, + "warm_p10_us": 4150.627, + "warm_p90_us": 5092.54, + "engine_us": 4842.745, + "floor_us": 259.347, + "update_us": null, + "mem_bytes": 2965296, + "load_us": 51867.172 + }, + { + "dataset": "multi_skewed", + "threads": 1, + "workload": "W1", + "answer": 3296, + "cold_us": 1222.44, + "warm_med_us": 724.577, + "warm_p10_us": 559.879, + "warm_p90_us": 819.621, + "engine_us": 791.956, + "floor_us": 131.709, + "update_us": null, + "mem_bytes": 2441008, + "load_us": 76234.596 + }, + { + "dataset": "multi_skewed", + "threads": 1, + "workload": "W2", + "answer": 100, + "cold_us": 4443.505, + "warm_med_us": 3134.968, + "warm_p10_us": 2750.886, + "warm_p90_us": 4076.798, + "engine_us": 4514.796, + "floor_us": 136.07, + "update_us": null, + "mem_bytes": 2441008, + "load_us": 49061.622 + }, + { + "dataset": "multi_skewed", + "threads": 1, + "workload": "W3", + "answer": 209, + "cold_us": 10282.077, + "warm_med_us": 6951.048, + "warm_p10_us": 5703.641, + "warm_p90_us": 8204.517, + "engine_us": 8045.757, + "floor_us": 183.796, + "update_us": null, + "mem_bytes": 2441008, + "load_us": 59294.607 + }, + { + "dataset": "multi_skewed", + "threads": 1, + "workload": "W4", + "answer": 1164, + "cold_us": 87807.314, + "warm_med_us": 57161.812, + "warm_p10_us": 52935.725, + "warm_p90_us": 79569.829, + "engine_us": 56044.293, + "floor_us": 96.288, + "update_us": null, + "mem_bytes": 2441008, + "load_us": 70594.018 + }, + { + "dataset": "multi_skewed", + "threads": 1, + "workload": "W5a", + "answer": 636, + "cold_us": 5093.623, + "warm_med_us": 1828.63, + "warm_p10_us": 1744.309, + "warm_p90_us": 2633.849, + "engine_us": 1960.175, + "floor_us": 79.345, + "update_us": null, + "mem_bytes": 2441008, + "load_us": 79972.705 + }, + { + "dataset": "multi_skewed", + "threads": 1, + "workload": "W6", + "answer": 428569, + "cold_us": 5085.961, + "warm_med_us": 5558.173, + "warm_p10_us": 3967.832, + "warm_p90_us": 5871.947, + "engine_us": 5977.194, + "floor_us": 128.988, + "update_us": null, + "mem_bytes": 2441008, + "load_us": 45669.369 + }, + { + "dataset": "multi_skewed", + "threads": 1, + "workload": "W7", + "answer": 100, + "cold_us": 3237.112, + "warm_med_us": 1806.613, + "warm_p10_us": 1568.846, + "warm_p90_us": 2427.459, + "engine_us": 2086.532, + "floor_us": 96.82, + "update_us": null, + "mem_bytes": 2441008, + "load_us": 51854.294 + }, + { + "dataset": "multi_skewed", + "threads": 1, + "workload": "W7i", + "answer": 77, + "cold_us": 2446.581, + "warm_med_us": 1023.295, + "warm_p10_us": 903.43, + "warm_p90_us": 1236.427, + "engine_us": 1193.14, + "floor_us": 131.582, + "update_us": null, + "mem_bytes": 2441008, + "load_us": 51200.513 + }, + { + "dataset": "multi_skewed", + "threads": 1, + "workload": "W8", + "answer": 100, + "cold_us": 5088.035, + "warm_med_us": 2853.558, + "warm_p10_us": 2662.874, + "warm_p90_us": 4012.033, + "engine_us": 2945.035, + "floor_us": 81.664, + "update_us": 1718.07, + "mem_bytes": 2965296, + "load_us": 62955.698 + }, + { + "dataset": "multi_skewed", + "threads": 1, + "workload": "W8_after", + "answer": 99, + "cold_us": 3004.059, + "warm_med_us": 2956.967, + "warm_p10_us": 2778.441, + "warm_p90_us": 4022.714, + "engine_us": 3394.837, + "floor_us": 81.664, + "update_us": null, + "mem_bytes": 2965296, + "load_us": 62955.698 + }, + { + "dataset": "multi_skewed", + "threads": 4, + "workload": "W1", + "answer": 3296, + "cold_us": 1698.913, + "warm_med_us": 825.781, + "warm_p10_us": 700.878, + "warm_p90_us": 1033.613, + "engine_us": 927.207, + "floor_us": 200.857, + "update_us": null, + "mem_bytes": 2441008, + "load_us": 52958.025 + }, + { + "dataset": "multi_skewed", + "threads": 4, + "workload": "W2", + "answer": 100, + "cold_us": 6312.07, + "warm_med_us": 3896.02, + "warm_p10_us": 3451.864, + "warm_p90_us": 4619.561, + "engine_us": 3894.716, + "floor_us": 241.259, + "update_us": null, + "mem_bytes": 2441008, + "load_us": 53221.404 + }, + { + "dataset": "multi_skewed", + "threads": 4, + "workload": "W3", + "answer": 209, + "cold_us": 9623.579, + "warm_med_us": 6613.908, + "warm_p10_us": 5941.144, + "warm_p90_us": 8284.705, + "engine_us": 6421.35, + "floor_us": 223.417, + "update_us": null, + "mem_bytes": 2441008, + "load_us": 51909.53 + }, + { + "dataset": "multi_skewed", + "threads": 4, + "workload": "W4", + "answer": 1164, + "cold_us": 79898.543, + "warm_med_us": 56783.213, + "warm_p10_us": 53713.304, + "warm_p90_us": 69434.999, + "engine_us": 62738.259, + "floor_us": 214.292, + "update_us": null, + "mem_bytes": 2441008, + "load_us": 53290.367 + }, + { + "dataset": "multi_skewed", + "threads": 4, + "workload": "W5a", + "answer": 636, + "cold_us": 5275.308, + "warm_med_us": 2732.708, + "warm_p10_us": 2316.199, + "warm_p90_us": 3176.11, + "engine_us": 2488.971, + "floor_us": 194.777, + "update_us": null, + "mem_bytes": 2441008, + "load_us": 64431.109 + }, + { + "dataset": "multi_skewed", + "threads": 4, + "workload": "W6", + "answer": 428569, + "cold_us": 7600.756, + "warm_med_us": 5282.431, + "warm_p10_us": 4674.513, + "warm_p90_us": 6784.527, + "engine_us": 4892.977, + "floor_us": 198.279, + "update_us": null, + "mem_bytes": 2441008, + "load_us": 54672.241 + }, + { + "dataset": "multi_skewed", + "threads": 4, + "workload": "W7", + "answer": 100, + "cold_us": 4158.534, + "warm_med_us": 2212.59, + "warm_p10_us": 1998.629, + "warm_p90_us": 2598.064, + "engine_us": 2804.949, + "floor_us": 314.465, + "update_us": null, + "mem_bytes": 2441008, + "load_us": 73630.541 + }, + { + "dataset": "multi_skewed", + "threads": 4, + "workload": "W7i", + "answer": 77, + "cold_us": 2872.892, + "warm_med_us": 1576.082, + "warm_p10_us": 1290.969, + "warm_p90_us": 1837.884, + "engine_us": 1885.612, + "floor_us": 232.661, + "update_us": null, + "mem_bytes": 2441008, + "load_us": 54426.816 + }, + { + "dataset": "multi_skewed", + "threads": 4, + "workload": "W8", + "answer": 100, + "cold_us": 5980.385, + "warm_med_us": 4369.036, + "warm_p10_us": 3731.693, + "warm_p90_us": 5144.902, + "engine_us": 5007.179, + "floor_us": 207.236, + "update_us": 3105.672, + "mem_bytes": 2965296, + "load_us": 52170.924 + }, + { + "dataset": "multi_skewed", + "threads": 4, + "workload": "W8_after", + "answer": 99, + "cold_us": 4267.318, + "warm_med_us": 4026.165, + "warm_p10_us": 3600.791, + "warm_p90_us": 4672.605, + "engine_us": 7894.121, + "floor_us": 207.236, + "update_us": null, + "mem_bytes": 2965296, + "load_us": 52170.924 + }, + { + "dataset": "multi_sparse", + "threads": 1, + "workload": "W1", + "answer": 3296, + "cold_us": 1777.93, + "warm_med_us": 787.012, + "warm_p10_us": 752.33, + "warm_p90_us": 844.478, + "engine_us": 832.637, + "floor_us": 131.836, + "update_us": null, + "mem_bytes": 2170688, + "load_us": 58651.887 + }, + { + "dataset": "multi_sparse", + "threads": 1, + "workload": "W2", + "answer": 61, + "cold_us": 4129.904, + "warm_med_us": 2224.176, + "warm_p10_us": 2111.776, + "warm_p90_us": 2454.13, + "engine_us": 3616.498, + "floor_us": 140.355, + "update_us": null, + "mem_bytes": 2170688, + "load_us": 41008.631 + }, + { + "dataset": "multi_sparse", + "threads": 1, + "workload": "W3", + "answer": 59, + "cold_us": 5246.723, + "warm_med_us": 2616.495, + "warm_p10_us": 2509.222, + "warm_p90_us": 3426.898, + "engine_us": 2846.789, + "floor_us": 79.751, + "update_us": null, + "mem_bytes": 2170688, + "load_us": 54525.434 + }, + { + "dataset": "multi_sparse", + "threads": 1, + "workload": "W4", + "answer": 64, + "cold_us": 6158.216, + "warm_med_us": 3175.981, + "warm_p10_us": 3006.267, + "warm_p90_us": 3511.843, + "engine_us": 3476.284, + "floor_us": 85.93, + "update_us": null, + "mem_bytes": 2170688, + "load_us": 40129.41 + }, + { + "dataset": "multi_sparse", + "threads": 1, + "workload": "W5a", + "answer": 222, + "cold_us": 4438.52, + "warm_med_us": 1720.78, + "warm_p10_us": 1563.136, + "warm_p90_us": 2202.58, + "engine_us": 2502.969, + "floor_us": 128.736, + "update_us": null, + "mem_bytes": 2170688, + "load_us": 39847.338 + }, + { + "dataset": "multi_sparse", + "threads": 1, + "workload": "W6", + "answer": 223, + "cold_us": 3427.52, + "warm_med_us": 1742.934, + "warm_p10_us": 1631.168, + "warm_p90_us": 1921.88, + "engine_us": 1708.355, + "floor_us": 82.032, + "update_us": null, + "mem_bytes": 2170688, + "load_us": 44578.275 + }, + { + "dataset": "multi_sparse", + "threads": 1, + "workload": "W7", + "answer": 61, + "cold_us": 3163.549, + "warm_med_us": 1624.546, + "warm_p10_us": 1453.236, + "warm_p90_us": 2154.795, + "engine_us": 2187.521, + "floor_us": 136.897, + "update_us": null, + "mem_bytes": 2170688, + "load_us": 40133.127 + }, + { + "dataset": "multi_sparse", + "threads": 1, + "workload": "W7i", + "answer": 77, + "cold_us": 2055.4, + "warm_med_us": 984.163, + "warm_p10_us": 898.784, + "warm_p90_us": 1233.956, + "engine_us": 1097.354, + "floor_us": 77.555, + "update_us": null, + "mem_bytes": 2170688, + "load_us": 53256.013 + }, + { + "dataset": "multi_sparse", + "threads": 1, + "workload": "W8", + "answer": 61, + "cold_us": 8612.852, + "warm_med_us": 2304.026, + "warm_p10_us": 2132.663, + "warm_p90_us": 3003.324, + "engine_us": 3626.676, + "floor_us": 95.764, + "update_us": 2135.898, + "mem_bytes": 2432832, + "load_us": 41098.796 + }, + { + "dataset": "multi_sparse", + "threads": 1, + "workload": "W8_after", + "answer": 61, + "cold_us": 2322.621, + "warm_med_us": 2367.158, + "warm_p10_us": 2222.063, + "warm_p90_us": 2868.939, + "engine_us": 2475.845, + "floor_us": 95.764, + "update_us": null, + "mem_bytes": 2432832, + "load_us": 41098.796 + }, + { + "dataset": "multi_sparse", + "threads": 4, + "workload": "W1", + "answer": 3296, + "cold_us": 1570.602, + "warm_med_us": 750.214, + "warm_p10_us": 665.288, + "warm_p90_us": 846.468, + "engine_us": 916.712, + "floor_us": 188.483, + "update_us": null, + "mem_bytes": 2170688, + "load_us": 41591.338 + }, + { + "dataset": "multi_sparse", + "threads": 4, + "workload": "W2", + "answer": 61, + "cold_us": 6112.878, + "warm_med_us": 3106.081, + "warm_p10_us": 2699.234, + "warm_p90_us": 3568.788, + "engine_us": 3843.606, + "floor_us": 207.564, + "update_us": null, + "mem_bytes": 2170688, + "load_us": 42264.914 + }, + { + "dataset": "multi_sparse", + "threads": 4, + "workload": "W3", + "answer": 59, + "cold_us": 7549.272, + "warm_med_us": 3768.697, + "warm_p10_us": 3298.819, + "warm_p90_us": 4417.503, + "engine_us": 4838.596, + "floor_us": 227.225, + "update_us": null, + "mem_bytes": 2170688, + "load_us": 45042.349 + }, + { + "dataset": "multi_sparse", + "threads": 4, + "workload": "W4", + "answer": 64, + "cold_us": 7227.773, + "warm_med_us": 4542.857, + "warm_p10_us": 3937.058, + "warm_p90_us": 5384.953, + "engine_us": 5406.375, + "floor_us": 191.69, + "update_us": null, + "mem_bytes": 2170688, + "load_us": 42340.195 + }, + { + "dataset": "multi_sparse", + "threads": 4, + "workload": "W5a", + "answer": 222, + "cold_us": 4715.704, + "warm_med_us": 2293.06, + "warm_p10_us": 1984.785, + "warm_p90_us": 2763.794, + "engine_us": 2665.569, + "floor_us": 240.624, + "update_us": null, + "mem_bytes": 2170688, + "load_us": 44652.684 + }, + { + "dataset": "multi_sparse", + "threads": 4, + "workload": "W6", + "answer": 223, + "cold_us": 4686.309, + "warm_med_us": 2473.788, + "warm_p10_us": 2204.656, + "warm_p90_us": 3011.697, + "engine_us": 2714.932, + "floor_us": 200.768, + "update_us": null, + "mem_bytes": 2170688, + "load_us": 54278.476 + }, + { + "dataset": "multi_sparse", + "threads": 4, + "workload": "W7", + "answer": 61, + "cold_us": 3670.697, + "warm_med_us": 2129.342, + "warm_p10_us": 1897.879, + "warm_p90_us": 2440.389, + "engine_us": 3708.908, + "floor_us": 197.595, + "update_us": null, + "mem_bytes": 2170688, + "load_us": 48285.269 + }, + { + "dataset": "multi_sparse", + "threads": 4, + "workload": "W7i", + "answer": 77, + "cold_us": 2390.19, + "warm_med_us": 1393.735, + "warm_p10_us": 1241.048, + "warm_p90_us": 1648.275, + "engine_us": 1635.871, + "floor_us": 242.034, + "update_us": null, + "mem_bytes": 2170688, + "load_us": 41906.891 + }, + { + "dataset": "multi_sparse", + "threads": 4, + "workload": "W8", + "answer": 61, + "cold_us": 4687.348, + "warm_med_us": 3483.009, + "warm_p10_us": 2882.476, + "warm_p90_us": 3957.828, + "engine_us": 3838.329, + "floor_us": 209.635, + "update_us": 2373.841, + "mem_bytes": 2432832, + "load_us": 42391.962 + }, + { + "dataset": "multi_sparse", + "threads": 4, + "workload": "W8_after", + "answer": 61, + "cold_us": 3802.615, + "warm_med_us": 3102.381, + "warm_p10_us": 2747.393, + "warm_p90_us": 3696.553, + "engine_us": 3073.675, + "floor_us": 209.635, + "update_us": null, + "mem_bytes": 2432832, + "load_us": 42391.962 + } +] \ No newline at end of file diff --git a/.claude/probes/2026-11-03-d-global-where/results/explain/dr256_medium_W1.txt b/.claude/probes/2026-11-03-d-global-where/results/explain/dr256_medium_W1.txt new file mode 100644 index 000000000..9be1843fc --- /dev/null +++ b/.claude/probes/2026-11-03-d-global-where/results/explain/dr256_medium_W1.txt @@ -0,0 +1,16 @@ +-- SELECT count(*) FROM nodes WHERE a < 50 +╭─ Summary ───────────╮ +│ Total Time: 0.0007s │ +╰─────────────────────╯ +╭─ Ungrouped Aggregate ─────╮ +│ Aggregates: count_star() │ +│ 1 row 0µs │ +╰─────────────┒┎────────────╯ +╭─ Table Scan ┚┖────────────╮ +│ Table: memory.main.nodes │ +│ Type: Sequential Scan │ +│ Filters: a < 50 │ +│ Row Groups Scanned: 1 / 1 │ +│ 3,296 rows 0µs │ +╰───────────────────────────╯ + diff --git a/.claude/probes/2026-11-03-d-global-where/results/explain/dr256_medium_W2.txt b/.claude/probes/2026-11-03-d-global-where/results/explain/dr256_medium_W2.txt new file mode 100644 index 000000000..6d057958a --- /dev/null +++ b/.claude/probes/2026-11-03-d-global-where/results/explain/dr256_medium_W2.txt @@ -0,0 +1,39 @@ +-- SELECT count(*) FROM nodes n WHERE n.a < 50 AND EXISTS (SELECT 1 FROM edges e JOIN nodes m ON m.id = e.dst WHERE e.src = n.id AND m.b < 300) +╭─ Summary ───────────╮ +│ Total Time: 0.0026s │ +╰─────────────────────╯ +╭─ Ungrouped Aggregate ────────────────────╮ +│ Aggregates: count_star() │ +│ 1 row 0µs │ +╰─────────────────────┬────────────────────╯ +╭─ Hash Join ─────────┴────────────────────╮ +│ Join Type: SEMI │ +│ Conditions: id = id │ +│ 17 rows 0µs │ +╰─────────────────────┬────────────────────╯ + ├──────────────────────────────────────────╮ +╭─ Filter ────────────┴────────────────────╮ ╭─ Projection ─────┴──────────────────╮ +│ Expression: id BETWEEN 89 AND 65181 │ │ Projections: id │ +│ 17 rows 0µs │ │ 610 rows 0µs │ +╰─────────────────────┬────────────────────╯ ╰──────────────────┬──────────────────╯ +╭─ Table Scan ────────┴────────────────────╮ ╭─ Hash Join ──────┴──────────────────╮ +│ Table: memory.main.nodes │ │ Join Type: INNER │ +│ Type: Sequential Scan │ │ Conditions: id = dst │ +│ Projections: id │ │ 610 rows 0µs │ +│ Filters: a < 50 │ ╰──────────────────┬──────────────────╯ +│ Dynamic Filters: optional: id IN PRF(id) │ ├───────────────────────────────────┰┒ +│ Row Groups Scanned: 1 / 1 │ ╭─ Filter ─────────┴──────────────────╮ ╭─ Table Scan ┚┖────────────╮ +│ 17 rows 0µs │ │ Expression: id BETWEEN 89 AND 65181 │ │ Table: memory.main.edges │ +╰──────────────────────────────────────────╯ │ 77 rows 0µs │ │ Type: Sequential Scan │ + ╰──────────────────┬──────────────────╯ │ Projections: dst, src │ + ╭─ Table Scan ─────┴──────────────────╮ │ Row Groups Scanned: 1 / 1 │ + │ Table: memory.main.nodes │ │ 2,048 rows 0µs │ + │ Type: Sequential Scan │ ╰───────────────────────────╯ + │ Projections: id │ + │ Filters: b < 300 │ + │ Dynamic Filters: │ + │ optional: id IN PRF(dst) │ + │ Row Groups Scanned: 1 / 1 │ + │ 77 rows 0µs │ + ╰─────────────────────────────────────╯ + diff --git a/.claude/probes/2026-11-03-d-global-where/results/explain/dr256_medium_W3.txt b/.claude/probes/2026-11-03-d-global-where/results/explain/dr256_medium_W3.txt new file mode 100644 index 000000000..9c32dc025 --- /dev/null +++ b/.claude/probes/2026-11-03-d-global-where/results/explain/dr256_medium_W3.txt @@ -0,0 +1,45 @@ +-- SELECT count(*) FROM nodes n WHERE n.a < 50 AND EXISTS (SELECT 1 FROM edges e1 JOIN edges e2 ON e2.src = e1.dst JOIN nodes m ON m.id = e2.dst WHERE e1.src = n.id AND m.b < 300) +╭─ Summary ───────────╮ +│ Total Time: 0.0030s │ +╰─────────────────────╯ +╭─ Ungrouped Aggregate ────────────────────╮ +│ Aggregates: count_star() │ +│ 1 row 0µs │ +╰─────────────────────┬────────────────────╯ +╭─ Hash Join ─────────┴────────────────────╮ +│ Join Type: SEMI │ +│ Conditions: id = id │ +│ 17 rows 0µs │ +╰─────────────────────┬────────────────────╯ + ├────────────────────────────────────────┰┒ +╭─ Filter ────────────┴────────────────────╮ ╭─ Projection ───┚┖──────────────╮ +│ Expression: id BETWEEN 89 AND 65181 │ │ Projections: id │ +│ 17 rows 0µs │ │ 4,850 rows 0µs │ +╰─────────────────────┬────────────────────╯ ╰────────────────┒┎──────────────╯ +╭─ Table Scan ────────┴────────────────────╮ ╭─ Hash Join ────┚┖──────────────╮ +│ Table: memory.main.nodes │ │ Join Type: INNER │ +│ Type: Sequential Scan │ │ Conditions: dst = src │ +│ Projections: id │ │ 4,850 rows 0µs │ +│ Filters: a < 50 │ ╰────────────────┬───────────────╯ +│ Dynamic Filters: optional: id IN PRF(id) │ ┟─────────────────────────────────────╮ +│ Row Groups Scanned: 1 / 1 │ ╭─ Table Scan ───┸───────────────╮ ╭─ Hash Join ──────┴──────────────────╮ +│ 17 rows 0µs │ │ Table: memory.main.edges │ │ Join Type: INNER │ +╰──────────────────────────────────────────╯ │ Type: Sequential Scan │ │ Conditions: id = dst │ + │ Projections: dst, src │ │ 610 rows 0µs │ + │ Dynamic Filters: │ ╰──────────────────┬──────────────────╯ + │ optional: dst IN PRF(src) │ ├───────────────────────────────────┒ + │ Row Groups Scanned: 1 / 1 │ ╭─ Filter ─────────┴──────────────────╮ ╭─ Table Scan ┸─────────────╮ + │ 1,930 rows 0µs │ │ Expression: id BETWEEN 89 AND 65181 │ │ Table: memory.main.edges │ + ╰────────────────────────────────╯ │ 77 rows 0µs │ │ Type: Sequential Scan │ + ╰──────────────────┬──────────────────╯ │ Projections: src, dst │ + ╭─ Table Scan ─────┴──────────────────╮ │ Row Groups Scanned: 1 / 1 │ + │ Table: memory.main.nodes │ │ 2,048 rows 0µs │ + │ Type: Sequential Scan │ ╰───────────────────────────╯ + │ Projections: id │ + │ Filters: b < 300 │ + │ Dynamic Filters: │ + │ optional: id IN PRF(dst) │ + │ Row Groups Scanned: 1 / 1 │ + │ 77 rows 0µs │ + ╰─────────────────────────────────────╯ + diff --git a/.claude/probes/2026-11-03-d-global-where/results/explain/dr256_medium_W4.txt b/.claude/probes/2026-11-03-d-global-where/results/explain/dr256_medium_W4.txt new file mode 100644 index 000000000..e06133be4 --- /dev/null +++ b/.claude/probes/2026-11-03-d-global-where/results/explain/dr256_medium_W4.txt @@ -0,0 +1,57 @@ +-- SELECT count(DISTINCT e3.dst) FROM nodes n JOIN edges e1 ON e1.src = n.id JOIN edges e2 ON e2.src = e1.dst JOIN edges e3 ON e3.src = e2.dst JOIN nodes m ON m.id = e3.dst WHERE n.a < 50 AND m.b < 300 +╭─ Summary ───────────╮ +│ Total Time: 0.0070s │ +╰─────────────────────╯ +╭─ Ungrouped Aggregate ──────────────╮ +│ Aggregates: count_star() │ +│ 1 row 0µs │ +╰──────────────────┬─────────────────╯ +╭─ Projection ─────┴─────────────────╮ +│ Projections: 42 │ +│ 77 rows 0µs │ +╰──────────────────┬─────────────────╯ +╭─ Hash Group By ──┴─────────────────╮ +│ Groups: #0 │ +│ 77 rows 0µs │ +╰──────────────────┒┎────────────────╯ +╭─ Projection ─────┚┖────────────────╮ +│ Projections: dst │ +│ 2,638 rows 0µs │ +╰──────────────────┒┎────────────────╯ +╭─ Projection ─────┚┖────────────────╮ +│ Projections: CAST(#0 AS USMALLINT) │ +│ 2,638 rows 0µs │ +╰──────────────────┒┎────────────────╯ +╭─ Hash Join ──────┚┖────────────────╮ +│ Join Type: INNER │ +│ Conditions: src = dst │ +│ 2,638 rows 0µs │ +╰──────────────────┰┰────────────────╯ + ┃┠──────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +╭─ Hash Join ──────┚┖────────────────╮ ╭─ Hash Join ──────┴──────────────────╮ +│ Join Type: INNER │ │ Join Type: INNER │ +│ Conditions: dst = src │ │ Conditions: id = src │ +│ 2,090 rows 0µs │ │ 136 rows 0µs │ +╰──────────────────┬─────────────────╯ ╰──────────────────┬──────────────────╯ + ├───────────────────────────────────────╮ ├───────────────────────────────────┰┒ +╭─ Table Scan ─────┴─────────────────╮ ╭─ Hash Join ──────┴──────────────────╮ ╭─ Filter ─────────┴──────────────────╮ ╭─ Table Scan ┚┖────────────╮ +│ Table: memory.main.edges │ │ Join Type: INNER │ │ Expression: id BETWEEN 89 AND 65181 │ │ Table: memory.main.edges │ +│ Type: Sequential Scan │ │ Conditions: id = dst │ │ 17 rows 0µs │ │ Type: Sequential Scan │ +│ Projections: src, dst │ │ 610 rows 0µs │ ╰──────────────────┬──────────────────╯ │ Projections: src, dst │ +│ Dynamic Filters: │ ╰──────────────────┬──────────────────╯ ╭─ Table Scan ─────┴──────────────────╮ │ Row Groups Scanned: 1 / 1 │ +│ optional: src IN PRF(dst), │ ├───────────────────────────────────┰┒ │ Table: memory.main.nodes │ │ 2,048 rows 0µs │ +│ optional: dst IN PRF(src) │ ╭─ Filter ─────────┴──────────────────╮ ╭─ Table Scan ┚┖────────────╮ │ Type: Sequential Scan │ ╰───────────────────────────╯ +│ Row Groups Scanned: 1 / 1 │ │ Expression: id BETWEEN 89 AND 65181 │ │ Table: memory.main.edges │ │ Projections: id │ +│ 825 rows 0µs │ │ 77 rows 0µs │ │ Type: Sequential Scan │ │ Filters: a < 50 │ +╰────────────────────────────────────╯ ╰──────────────────┬──────────────────╯ │ Projections: src, dst │ │ Dynamic Filters: │ + ╭─ Table Scan ─────┴──────────────────╮ │ Row Groups Scanned: 1 / 1 │ │ optional: id IN PRF(src) │ + │ Table: memory.main.nodes │ │ 2,048 rows 0µs │ │ Row Groups Scanned: 1 / 1 │ + │ Type: Sequential Scan │ ╰───────────────────────────╯ │ 17 rows 0µs │ + │ Projections: id │ ╰─────────────────────────────────────╯ + │ Filters: b < 300 │ + │ Dynamic Filters: │ + │ optional: id IN PRF(dst) │ + │ Row Groups Scanned: 1 / 1 │ + │ 77 rows 0µs │ + ╰─────────────────────────────────────╯ + diff --git a/.claude/probes/2026-11-03-d-global-where/results/explain/dr256_medium_W5a.txt b/.claude/probes/2026-11-03-d-global-where/results/explain/dr256_medium_W5a.txt new file mode 100644 index 000000000..5904e02bc --- /dev/null +++ b/.claude/probes/2026-11-03-d-global-where/results/explain/dr256_medium_W5a.txt @@ -0,0 +1,45 @@ +-- SELECT count(DISTINCT e.dst) FROM edges e JOIN nodes n ON n.id = e.src WHERE n.a < 50 +╭─ Summary ───────────╮ +│ Total Time: 0.0033s │ +╰─────────────────────╯ +╭─ Ungrouped Aggregate ───────────────╮ +│ Aggregates: count_star() │ +│ 1 row 0µs │ +╰──────────────────┬──────────────────╯ +╭─ Projection ─────┴──────────────────╮ +│ Projections: 42 │ +│ 109 rows 0µs │ +╰──────────────────┬──────────────────╯ +╭─ Hash Group By ──┴──────────────────╮ +│ Groups: #0 │ +│ 109 rows 0µs │ +╰──────────────────┬──────────────────╯ +╭─ Projection ─────┴──────────────────╮ +│ Projections: dst │ +│ 136 rows 0µs │ +╰──────────────────┬──────────────────╯ +╭─ Projection ─────┴──────────────────╮ +│ Projections: CAST(#1 AS USMALLINT) │ +│ 136 rows 0µs │ +╰──────────────────┬──────────────────╯ +╭─ Hash Join ──────┴──────────────────╮ +│ Join Type: INNER │ +│ Conditions: id = src │ +│ 136 rows 0µs │ +╰──────────────────┬──────────────────╯ + ├───────────────────────────────────┰┒ +╭─ Filter ─────────┴──────────────────╮ ╭─ Table Scan ┚┖────────────╮ +│ Expression: id BETWEEN 89 AND 65181 │ │ Table: memory.main.edges │ +│ 17 rows 0µs │ │ Type: Sequential Scan │ +╰──────────────────┬──────────────────╯ │ Projections: src, dst │ +╭─ Table Scan ─────┴──────────────────╮ │ Row Groups Scanned: 1 / 1 │ +│ Table: memory.main.nodes │ │ 2,048 rows 0µs │ +│ Type: Sequential Scan │ ╰───────────────────────────╯ +│ Projections: id │ +│ Filters: a < 50 │ +│ Dynamic Filters: │ +│ optional: id IN PRF(src) │ +│ Row Groups Scanned: 1 / 1 │ +│ 17 rows 0µs │ +╰─────────────────────────────────────╯ + diff --git a/.claude/probes/2026-11-03-d-global-where/results/explain/dr256_medium_W6.txt b/.claude/probes/2026-11-03-d-global-where/results/explain/dr256_medium_W6.txt new file mode 100644 index 000000000..8574e4dce --- /dev/null +++ b/.claude/probes/2026-11-03-d-global-where/results/explain/dr256_medium_W6.txt @@ -0,0 +1,35 @@ +-- SELECT count(*) FROM edges e1 JOIN edges e2 ON e2.src = e1.dst JOIN nodes n ON n.id = e1.src WHERE n.a < 50 +╭─ Summary ───────────╮ +│ Total Time: 0.0022s │ +╰─────────────────────╯ +╭─ Ungrouped Aggregate ──────────╮ +│ Aggregates: count_star() │ +│ 1 row 0µs │ +╰────────────────┰───────────────╯ +╭─ Hash Join ────┸───────────────╮ +│ Join Type: INNER │ +│ Conditions: src = dst │ +│ 1,088 rows 0µs │ +╰────────────────┬───────────────╯ + ┟─────────────────────────────────────╮ +╭─ Table Scan ───┸───────────────╮ ╭─ Hash Join ──────┴──────────────────╮ +│ Table: memory.main.edges │ │ Join Type: INNER │ +│ Type: Sequential Scan │ │ Conditions: id = src │ +│ Projections: src │ │ 136 rows 0µs │ +│ Dynamic Filters: │ ╰──────────────────┬──────────────────╯ +│ optional: src IN PRF(dst) │ ├───────────────────────────────────┰┒ +│ Row Groups Scanned: 1 / 1 │ ╭─ Filter ─────────┴──────────────────╮ ╭─ Table Scan ┚┖────────────╮ +│ 872 rows 0µs │ │ Expression: id BETWEEN 89 AND 65181 │ │ Table: memory.main.edges │ +╰────────────────────────────────╯ │ 17 rows 0µs │ │ Type: Sequential Scan │ + ╰──────────────────┬──────────────────╯ │ Projections: dst, src │ + ╭─ Table Scan ─────┴──────────────────╮ │ Row Groups Scanned: 1 / 1 │ + │ Table: memory.main.nodes │ │ 2,048 rows 0µs │ + │ Type: Sequential Scan │ ╰───────────────────────────╯ + │ Projections: id │ + │ Filters: a < 50 │ + │ Dynamic Filters: │ + │ optional: id IN PRF(src) │ + │ Row Groups Scanned: 1 / 1 │ + │ 17 rows 0µs │ + ╰─────────────────────────────────────╯ + diff --git a/.claude/probes/2026-11-03-d-global-where/results/explain/dr256_medium_W7.txt b/.claude/probes/2026-11-03-d-global-where/results/explain/dr256_medium_W7.txt new file mode 100644 index 000000000..23ab8cfc6 --- /dev/null +++ b/.claude/probes/2026-11-03-d-global-where/results/explain/dr256_medium_W7.txt @@ -0,0 +1,36 @@ +-- SELECT count(*) FROM selA s WHERE EXISTS (SELECT 1 FROM edges e JOIN selB t ON t.id = e.dst WHERE e.src = s.id) +╭─ Summary ───────────╮ +│ Total Time: 0.0021s │ +╰─────────────────────╯ +╭─ Ungrouped Aggregate ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ Aggregates: count_star() │ +│ 1 row 0µs │ +╰───────────────────────────────────────────────────────────────────────────────────┬──────────────────────────────────────────────────────────────────────────────────╯ +╭─ Hash Join ───────────────────────────────────────────────────────────────────────┴──────────────────────────────────────────────────────────────────────────────────╮ +│ Join Type: RIGHT_SEMI │ +│ Conditions: id = id │ +│ 17 rows 0µs │ +╰───────────────────────────────────────────────────────────────────────────────────┰┰─────────────────────────────────────────────────────────────────────────────────╯ + ┃┠──────────────────────────────────────────────────────────────────────────────────────────────────╮ +╭─ Projection ──────────────────────────────────────────────────────────────────────┚┖─────────────────────────────────────────────────────────────────────────────────╮ ╭─ Table Scan ┴─────────────╮ +│ Projections: id │ │ Table: memory.main.selA │ +│ 51 rows 0µs │ │ Type: Sequential Scan │ +╰───────────────────────────────────────────────────────────────────────────────────┒┎─────────────────────────────────────────────────────────────────────────────────╯ │ Projections: id │ +╭─ Hash Join ───────────────────────────────────────────────────────────────────────┚┖─────────────────────────────────────────────────────────────────────────────────╮ │ Row Groups Scanned: 1 / 1 │ +│ Join Type: INNER │ │ 17 rows 0µs │ +│ Conditions: dst = id │ ╰───────────────────────────╯ +│ 51 rows 0µs │ +╰───────────────────────────────────────────────────────────────────────────────────┰┰─────────────────────────────────────────────────────────────────────────────────╯ + ┃┠──────────────────────────────────────────────────────────────────────────────────────────────────┰┒ +╭─ Table Scan ──────────────────────────────────────────────────────────────────────┚┖─────────────────────────────────────────────────────────────────────────────────╮ ╭─ Table Scan ┚┖────────────╮ +│ Table: memory.main.edges │ │ Table: memory.main.selB │ +│ Type: Sequential Scan │ │ Type: Sequential Scan │ +│ Projections: dst, src │ │ Projections: id │ +│ Filters: (dst >= 491) AND (dst <= 63797) │ │ Row Groups Scanned: 1 / 1 │ +│ Dynamic Filters: │ │ 77 rows 0µs │ +│ optional: dst IN PRF(id), │ ╰───────────────────────────╯ +│ optional: (src IN (799, 9218, 9716, 14837, 15908, 17342, 19960, 21127, 22344, 28092, 30601, 35552, 35793, 39592, 40952, 51823, 53561)) AND optional: src IN PRF(id) │ +│ Row Groups Scanned: 1 / 1 │ +│ 51 rows 0µs │ +╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ + diff --git a/.claude/probes/2026-11-03-d-global-where/results/explain/dr256_medium_W7i.txt b/.claude/probes/2026-11-03-d-global-where/results/explain/dr256_medium_W7i.txt new file mode 100644 index 000000000..49721de12 --- /dev/null +++ b/.claude/probes/2026-11-03-d-global-where/results/explain/dr256_medium_W7i.txt @@ -0,0 +1,25 @@ +-- SELECT count(*) FROM selA JOIN selB USING (id) +╭─ Summary ───────────╮ +│ Total Time: 0.0016s │ +╰─────────────────────╯ +╭─ Ungrouped Aggregate ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ Aggregates: count_star() │ +│ 1 row 0µs │ +╰─────────────────────────────────────────────────────────────────────────────────┬─────────────────────────────────────────────────────────────────────────────────╯ +╭─ Hash Join ─────────────────────────────────────────────────────────────────────┴─────────────────────────────────────────────────────────────────────────────────╮ +│ Join Type: INNER │ +│ Conditions: id = id │ +│ 4 rows 0µs │ +╰─────────────────────────────────────────────────────────────────────────────────┬─────────────────────────────────────────────────────────────────────────────────╯ + ├──────────────────────────────────────────────────────────────────────────────────────────────────┰┒ +╭─ Table Scan ────────────────────────────────────────────────────────────────────┴─────────────────────────────────────────────────────────────────────────────────╮ ╭─ Table Scan ┚┖────────────╮ +│ Table: memory.main.selB │ │ Table: memory.main.selA │ +│ Type: Sequential Scan │ │ Type: Sequential Scan │ +│ Projections: id │ │ Projections: id │ +│ Filters: (id >= 799) AND (id <= 53561) │ │ Row Groups Scanned: 1 / 1 │ +│ Dynamic Filters: │ │ 17 rows 0µs │ +│ optional: (id IN (799, 9218, 9716, 14837, 15908, 17342, 19960, 21127, 22344, 28092, 30601, 35552, 35793, 39592, 40952, 51823, 53561)) AND optional: id IN PRF(id) │ ╰───────────────────────────╯ +│ Row Groups Scanned: 1 / 1 │ +│ 4 rows 0µs │ +╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ + diff --git a/.claude/probes/2026-11-03-d-global-where/results/explain/multi_skewed_W1.txt b/.claude/probes/2026-11-03-d-global-where/results/explain/multi_skewed_W1.txt new file mode 100644 index 000000000..c24824c5c --- /dev/null +++ b/.claude/probes/2026-11-03-d-global-where/results/explain/multi_skewed_W1.txt @@ -0,0 +1,16 @@ +-- SELECT count(*) FROM nodes WHERE a < 50 +╭─ Summary ───────────╮ +│ Total Time: 0.0008s │ +╰─────────────────────╯ +╭─ Ungrouped Aggregate ─────╮ +│ Aggregates: count_star() │ +│ 1 row 0µs │ +╰─────────────┒┎────────────╯ +╭─ Table Scan ┚┖────────────╮ +│ Table: memory.main.nodes │ +│ Type: Sequential Scan │ +│ Filters: a < 50 │ +│ Row Groups Scanned: 1 / 1 │ +│ 3,296 rows 0µs │ +╰───────────────────────────╯ + diff --git a/.claude/probes/2026-11-03-d-global-where/results/explain/multi_skewed_W2.txt b/.claude/probes/2026-11-03-d-global-where/results/explain/multi_skewed_W2.txt new file mode 100644 index 000000000..f584e881e --- /dev/null +++ b/.claude/probes/2026-11-03-d-global-where/results/explain/multi_skewed_W2.txt @@ -0,0 +1,37 @@ +-- SELECT count(*) FROM nodes n WHERE n.a < 50 AND EXISTS (SELECT 1 FROM edges e JOIN nodes m ON m.id = e.dst WHERE e.src = n.id AND m.b < 300) +╭─ Summary ───────────╮ +│ Total Time: 0.0037s │ +╰─────────────────────╯ +╭─ Ungrouped Aggregate ────────────────────╮ +│ Aggregates: count_star() │ +│ 1 row 0µs │ +╰─────────────────────┬────────────────────╯ +╭─ Hash Join ─────────┴────────────────────╮ +│ Join Type: SEMI │ +│ Conditions: id = id │ +│ 100 rows 0µs │ +╰─────────────────────┬────────────────────╯ + ├────────────────────────────────────────┒ +╭─ Filter ────────────┴────────────────────╮ ╭─ Projection ───┸───────────────╮ +│ Expression: id BETWEEN 20 AND 65510 │ │ Projections: id │ +│ 100 rows 0µs │ │ 8,257 rows 0µs │ +╰─────────────────────┬────────────────────╯ ╰────────────────┰───────────────╯ +╭─ Table Scan ────────┴────────────────────╮ ╭─ Hash Join ────┸───────────────╮ +│ Table: memory.main.nodes │ │ Join Type: INNER │ +│ Type: Sequential Scan │ │ Conditions: dst = id │ +│ Projections: id │ │ 8,257 rows 0µs │ +│ Filters: a < 50 │ ╰────────────────┬───────────────╯ +│ Dynamic Filters: optional: id IN PRF(id) │ ┟─────────────────────────────────────┰┒ +│ Row Groups Scanned: 1 / 1 │ ╭─ Table Scan ───┸───────────────╮ ╭─ Filter ─────────┚┖─────────────────╮ +│ 100 rows 0µs │ │ Table: memory.main.edges │ │ Expression: id BETWEEN 20 AND 65510 │ +╰──────────────────────────────────────────╯ │ Type: Sequential Scan │ │ 19,573 rows 0µs │ + │ Projections: dst, src │ ╰──────────────────┒┎─────────────────╯ + │ Dynamic Filters: │ ╭─ Table Scan ─────┚┖─────────────────╮ + │ optional: dst IN PRF(id) │ │ Table: memory.main.nodes │ + │ Row Groups Scanned: 1 / 1 │ │ Type: Sequential Scan │ + │ 8,257 rows 0µs │ │ Projections: id │ + ╰────────────────────────────────╯ │ Filters: b < 300 │ + │ Row Groups Scanned: 1 / 1 │ + │ 19,585 rows 0µs │ + ╰─────────────────────────────────────╯ + diff --git a/.claude/probes/2026-11-03-d-global-where/results/explain/multi_skewed_W3.txt b/.claude/probes/2026-11-03-d-global-where/results/explain/multi_skewed_W3.txt new file mode 100644 index 000000000..5a84cd3bc --- /dev/null +++ b/.claude/probes/2026-11-03-d-global-where/results/explain/multi_skewed_W3.txt @@ -0,0 +1,43 @@ +-- SELECT count(*) FROM nodes n WHERE n.a < 50 AND EXISTS (SELECT 1 FROM edges e1 JOIN edges e2 ON e2.src = e1.dst JOIN nodes m ON m.id = e2.dst WHERE e1.src = n.id AND m.b < 300) +╭─ Summary ───────────╮ +│ Total Time: 0.0075s │ +╰─────────────────────╯ +╭─ Ungrouped Aggregate ──────────╮ +│ Aggregates: count_star() │ +│ 1 row 0µs │ +╰────────────────┬───────────────╯ +╭─ Hash Join ────┴───────────────╮ +│ Join Type: RIGHT_SEMI │ +│ Conditions: id = id │ +│ 209 rows 0µs │ +╰────────────────┰┰──────────────╯ + ┃┠───────────────────────────────╮ +╭─ Projection ───┚┖──────────────╮ ╭─ Table Scan ┴─────────────╮ +│ Projections: id │ │ Table: memory.main.nodes │ +│ 122,182 rows 0µs │ │ Type: Sequential Scan │ +╰────────────────┒┎──────────────╯ │ Projections: id │ +╭─ Hash Join ────┚┖──────────────╮ │ Filters: a < 50 │ +│ Join Type: INNER │ │ Row Groups Scanned: 1 / 1 │ +│ Conditions: dst = src │ │ 3,296 rows 0µs │ +│ 122,182 rows 0µs │ ╰───────────────────────────╯ +╰────────────────┬───────────────╯ + ├───────────────────────────────────╮ +╭─ Table Scan ───┴───────────────╮ ╭─ Hash Join ────┴───────────────╮ +│ Table: memory.main.edges │ │ Join Type: INNER │ +│ Type: Sequential Scan │ │ Conditions: dst = id │ +│ Projections: dst, src │ │ 8,257 rows 0µs │ +│ Dynamic Filters: │ ╰────────────────┬───────────────╯ +│ optional: dst IN PRF(src), │ ├─────────────────────────────────────╮ +│ optional: src IN PRF(id) │ ╭─ Table Scan ───┴───────────────╮ ╭─ Filter ─────────┴──────────────────╮ +│ Row Groups Scanned: 1 / 1 │ │ Table: memory.main.edges │ │ Expression: id BETWEEN 20 AND 65510 │ +│ 1,117 rows 0µs │ │ Type: Sequential Scan │ │ 19,573 rows 0µs │ +╰────────────────────────────────╯ │ Projections: src, dst │ ╰──────────────────┬──────────────────╯ + │ Dynamic Filters: │ ╭─ Table Scan ─────┴──────────────────╮ + │ optional: dst IN PRF(id) │ │ Table: memory.main.nodes │ + │ Row Groups Scanned: 1 / 1 │ │ Type: Sequential Scan │ + │ 8,257 rows 0µs │ │ Projections: id │ + ╰────────────────────────────────╯ │ Filters: b < 300 │ + │ Row Groups Scanned: 1 / 1 │ + │ 19,585 rows 0µs │ + ╰─────────────────────────────────────╯ + diff --git a/.claude/probes/2026-11-03-d-global-where/results/explain/multi_skewed_W4.txt b/.claude/probes/2026-11-03-d-global-where/results/explain/multi_skewed_W4.txt new file mode 100644 index 000000000..a94f4b388 --- /dev/null +++ b/.claude/probes/2026-11-03-d-global-where/results/explain/multi_skewed_W4.txt @@ -0,0 +1,55 @@ +-- SELECT count(DISTINCT e3.dst) FROM nodes n JOIN edges e1 ON e1.src = n.id JOIN edges e2 ON e2.src = e1.dst JOIN edges e3 ON e3.src = e2.dst JOIN nodes m ON m.id = e3.dst WHERE n.a < 50 AND m.b < 300 +╭─ Summary ───────────╮ +│ Total Time: 0.0845s │ +╰─────────────────────╯ +╭─ Ungrouped Aggregate ──────────────╮ +│ Aggregates: count_star() │ +│ 1 row 0µs │ +╰──────────────────┬─────────────────╯ +╭─ Projection ─────┴─────────────────╮ +│ Projections: 42 │ +│ 1,164 rows 0µs │ +╰──────────────────┬─────────────────╯ +╭─ Hash Group By ──┴─────────────────╮ +│ Groups: #0 │ +│ 1,164 rows 30.0ms │ +╰──────────────────┒┎────────────────╯ +╭─ Projection ─────┚┖────────────────╮ +│ Projections: dst │ +│ 3,726,779 rows 0µs │ +╰──────────────────┒┎────────────────╯ +╭─ Projection ─────┚┖────────────────╮ +│ Projections: CAST(#0 AS USMALLINT) │ +│ 3,726,779 rows 0µs │ +╰──────────────────┒┎────────────────╯ +╭─ Hash Join ──────┚┖────────────────╮ +│ Join Type: INNER │ +│ Conditions: src = dst │ +│ 3,726,779 rows 30.0ms │ +╰──────────────────┬─────────────────╯ + ├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +╭─ Hash Join ──────┴─────────────────╮ ╭─ Hash Join ────┴───────────────╮ +│ Join Type: INNER │ │ Join Type: INNER │ +│ Conditions: dst = src │ │ Conditions: src = id │ +│ 983,021 rows 10.0ms │ │ 1,250 rows 0µs │ +╰──────────────────┬─────────────────╯ ╰────────────────┬───────────────╯ + ├─────────────────────────────────────╮ ├─────────────────────────────────────╮ +╭─ Table Scan ─────┴─────────────────╮ ╭─ Hash Join ────┴───────────────╮ ╭─ Table Scan ───┴───────────────╮ ╭─ Filter ─────────┴──────────────────╮ +│ Table: memory.main.edges │ │ Join Type: INNER │ │ Table: memory.main.edges │ │ Expression: id BETWEEN 20 AND 65510 │ +│ Type: Sequential Scan │ │ Conditions: dst = id │ │ Type: Sequential Scan │ │ 3,295 rows 0µs │ +│ Projections: src, dst │ │ 8,257 rows 0µs │ │ Projections: src, dst │ ╰──────────────────┬──────────────────╯ +│ Dynamic Filters: │ ╰────────────────┬───────────────╯ │ Dynamic Filters: │ ╭─ Table Scan ─────┴──────────────────╮ +│ optional: src IN PRF(dst), │ ├─────────────────────────────────────╮ │ optional: src IN PRF(id) │ │ Table: memory.main.nodes │ +│ optional: dst IN PRF(src) │ ╭─ Table Scan ───┴───────────────╮ ╭─ Filter ─────────┴──────────────────╮ │ Row Groups Scanned: 1 / 1 │ │ Type: Sequential Scan │ +│ Row Groups Scanned: 1 / 1 │ │ Table: memory.main.edges │ │ Expression: id BETWEEN 20 AND 65510 │ │ 1,250 rows 0µs │ │ Projections: id │ +│ 18,470 rows 0µs │ │ Type: Sequential Scan │ │ 19,573 rows 0µs │ ╰────────────────────────────────╯ │ Filters: a < 50 │ +╰────────────────────────────────────╯ │ Projections: src, dst │ ╰──────────────────┬──────────────────╯ │ Row Groups Scanned: 1 / 1 │ + │ Dynamic Filters: │ ╭─ Table Scan ─────┴──────────────────╮ │ 3,296 rows 0µs │ + │ optional: dst IN PRF(id) │ │ Table: memory.main.nodes │ ╰─────────────────────────────────────╯ + │ Row Groups Scanned: 1 / 1 │ │ Type: Sequential Scan │ + │ 8,257 rows 0µs │ │ Projections: id │ + ╰────────────────────────────────╯ │ Filters: b < 300 │ + │ Row Groups Scanned: 1 / 1 │ + │ 19,585 rows 0µs │ + ╰─────────────────────────────────────╯ + diff --git a/.claude/probes/2026-11-03-d-global-where/results/explain/multi_skewed_W5a.txt b/.claude/probes/2026-11-03-d-global-where/results/explain/multi_skewed_W5a.txt new file mode 100644 index 000000000..41ebc737c --- /dev/null +++ b/.claude/probes/2026-11-03-d-global-where/results/explain/multi_skewed_W5a.txt @@ -0,0 +1,43 @@ +-- SELECT count(DISTINCT e.dst) FROM edges e JOIN nodes n ON n.id = e.src WHERE n.a < 50 +╭─ Summary ───────────╮ +│ Total Time: 0.0048s │ +╰─────────────────────╯ +╭─ Ungrouped Aggregate ──────────────╮ +│ Aggregates: count_star() │ +│ 1 row 0µs │ +╰──────────────────┬─────────────────╯ +╭─ Projection ─────┴─────────────────╮ +│ Projections: 42 │ +│ 636 rows 0µs │ +╰──────────────────┬─────────────────╯ +╭─ Hash Group By ──┴─────────────────╮ +│ Groups: #0 │ +│ 636 rows 0µs │ +╰──────────────────┰─────────────────╯ +╭─ Projection ─────┸─────────────────╮ +│ Projections: dst │ +│ 1,250 rows 0µs │ +╰──────────────────┰─────────────────╯ +╭─ Projection ─────┸─────────────────╮ +│ Projections: CAST(#0 AS USMALLINT) │ +│ 1,250 rows 0µs │ +╰──────────────────┰─────────────────╯ +╭─ Hash Join ──────┸─────────────────╮ +│ Join Type: INNER │ +│ Conditions: src = id │ +│ 1,250 rows 0µs │ +╰──────────────────┬─────────────────╯ + ┟───────────────────────────────────────┰┒ +╭─ Table Scan ─────┸─────────────────╮ ╭─ Filter ─────────┚┖─────────────────╮ +│ Table: memory.main.edges │ │ Expression: id BETWEEN 20 AND 65510 │ +│ Type: Sequential Scan │ │ 3,295 rows 0µs │ +│ Projections: src, dst │ ╰──────────────────┒┎─────────────────╯ +│ Dynamic Filters: │ ╭─ Table Scan ─────┚┖─────────────────╮ +│ optional: src IN PRF(id) │ │ Table: memory.main.nodes │ +│ Row Groups Scanned: 1 / 1 │ │ Type: Sequential Scan │ +│ 1,250 rows 0µs │ │ Projections: id │ +╰────────────────────────────────────╯ │ Filters: a < 50 │ + │ Row Groups Scanned: 1 / 1 │ + │ 3,296 rows 0µs │ + ╰─────────────────────────────────────╯ + diff --git a/.claude/probes/2026-11-03-d-global-where/results/explain/multi_skewed_W6.txt b/.claude/probes/2026-11-03-d-global-where/results/explain/multi_skewed_W6.txt new file mode 100644 index 000000000..48634a7d1 --- /dev/null +++ b/.claude/probes/2026-11-03-d-global-where/results/explain/multi_skewed_W6.txt @@ -0,0 +1,33 @@ +-- SELECT count(*) FROM edges e1 JOIN edges e2 ON e2.src = e1.dst JOIN nodes n ON n.id = e1.src WHERE n.a < 50 +╭─ Summary ───────────╮ +│ Total Time: 0.0045s │ +╰─────────────────────╯ +╭─ Ungrouped Aggregate ──────────╮ +│ Aggregates: count_star() │ +│ 1 row 0µs │ +╰────────────────┒┎──────────────╯ +╭─ Hash Join ────┚┖──────────────╮ +│ Join Type: INNER │ +│ Conditions: src = dst │ +│ 428,569 rows 0µs │ +╰────────────────┬───────────────╯ + ├───────────────────────────────────╮ +╭─ Table Scan ───┴───────────────╮ ╭─ Hash Join ────┴───────────────╮ +│ Table: memory.main.edges │ │ Join Type: INNER │ +│ Type: Sequential Scan │ │ Conditions: src = id │ +│ Projections: src │ │ 1,250 rows 0µs │ +│ Dynamic Filters: │ ╰────────────────┬───────────────╯ +│ optional: src IN PRF(dst) │ ├─────────────────────────────────────╮ +│ Row Groups Scanned: 1 / 1 │ ╭─ Table Scan ───┴───────────────╮ ╭─ Filter ─────────┴──────────────────╮ +│ 23,640 rows 0µs │ │ Table: memory.main.edges │ │ Expression: id BETWEEN 20 AND 65510 │ +╰────────────────────────────────╯ │ Type: Sequential Scan │ │ 3,295 rows 0µs │ + │ Projections: dst, src │ ╰──────────────────┬──────────────────╯ + │ Dynamic Filters: │ ╭─ Table Scan ─────┴──────────────────╮ + │ optional: src IN PRF(id) │ │ Table: memory.main.nodes │ + │ Row Groups Scanned: 1 / 1 │ │ Type: Sequential Scan │ + │ 1,250 rows 0µs │ │ Projections: id │ + ╰────────────────────────────────╯ │ Filters: a < 50 │ + │ Row Groups Scanned: 1 / 1 │ + │ 3,296 rows 0µs │ + ╰─────────────────────────────────────╯ + diff --git a/.claude/probes/2026-11-03-d-global-where/results/explain/multi_skewed_W7.txt b/.claude/probes/2026-11-03-d-global-where/results/explain/multi_skewed_W7.txt new file mode 100644 index 000000000..3cc2046d7 --- /dev/null +++ b/.claude/probes/2026-11-03-d-global-where/results/explain/multi_skewed_W7.txt @@ -0,0 +1,36 @@ +-- SELECT count(*) FROM selA s WHERE EXISTS (SELECT 1 FROM edges e JOIN selB t ON t.id = e.dst WHERE e.src = s.id) +╭─ Summary ───────────╮ +│ Total Time: 0.0025s │ +╰─────────────────────╯ +╭─ Ungrouped Aggregate ────────────────────╮ +│ Aggregates: count_star() │ +│ 1 row 0µs │ +╰─────────────────────┬────────────────────╯ +╭─ Hash Join ─────────┴────────────────────╮ +│ Join Type: RIGHT_SEMI │ +│ Conditions: id = id │ +│ 100 rows 0µs │ +╰─────────────────────┬────────────────────╯ + ├─────────────────────────────────────╮ +╭─ Projection ────────┴────────────────────╮ ╭─ Table Scan ┴─────────────╮ +│ Projections: id │ │ Table: memory.main.selA │ +│ 321 rows 0µs │ │ Type: Sequential Scan │ +╰─────────────────────┬────────────────────╯ │ Projections: id │ +╭─ Hash Join ─────────┴────────────────────╮ │ Row Groups Scanned: 1 / 1 │ +│ Join Type: INNER │ │ 223 rows 0µs │ +│ Conditions: dst = id │ ╰───────────────────────────╯ +│ 321 rows 0µs │ +╰─────────────────────┬────────────────────╯ + ├─────────────────────────────────────┰┒ +╭─ Table Scan ────────┴────────────────────╮ ╭─ Table Scan ┚┖────────────╮ +│ Table: memory.main.edges │ │ Table: memory.main.selB │ +│ Type: Sequential Scan │ │ Type: Sequential Scan │ +│ Projections: dst, src │ │ Projections: id │ +│ Filters: (dst >= 164) AND (dst <= 65465) │ │ Row Groups Scanned: 1 / 1 │ +│ Dynamic Filters: │ │ 1,181 rows 0µs │ +│ optional: dst IN PRF(id), │ ╰───────────────────────────╯ +│ optional: src IN PRF(id) │ +│ Row Groups Scanned: 1 / 1 │ +│ 321 rows 0µs │ +╰──────────────────────────────────────────╯ + diff --git a/.claude/probes/2026-11-03-d-global-where/results/explain/multi_skewed_W7i.txt b/.claude/probes/2026-11-03-d-global-where/results/explain/multi_skewed_W7i.txt new file mode 100644 index 000000000..177e28d8d --- /dev/null +++ b/.claude/probes/2026-11-03-d-global-where/results/explain/multi_skewed_W7i.txt @@ -0,0 +1,24 @@ +-- SELECT count(*) FROM selA JOIN selB USING (id) +╭─ Summary ───────────╮ +│ Total Time: 0.0015s │ +╰─────────────────────╯ +╭─ Ungrouped Aggregate ────────────────────╮ +│ Aggregates: count_star() │ +│ 1 row 0µs │ +╰─────────────────────┰────────────────────╯ +╭─ Hash Join ─────────┸────────────────────╮ +│ Join Type: INNER │ +│ Conditions: id = id │ +│ 77 rows 0µs │ +╰─────────────────────┬────────────────────╯ + ┟─────────────────────────────────────┰┒ +╭─ Table Scan ────────┸────────────────────╮ ╭─ Table Scan ┚┖────────────╮ +│ Table: memory.main.selB │ │ Table: memory.main.selA │ +│ Type: Sequential Scan │ │ Type: Sequential Scan │ +│ Projections: id │ │ Projections: id │ +│ Filters: (id >= 165) AND (id <= 65192) │ │ Row Groups Scanned: 1 / 1 │ +│ Dynamic Filters: optional: id IN PRF(id) │ │ 223 rows 0µs │ +│ Row Groups Scanned: 1 / 1 │ ╰───────────────────────────╯ +│ 77 rows 0µs │ +╰──────────────────────────────────────────╯ + diff --git a/.claude/probes/2026-11-03-d-global-where/results/ours.json b/.claude/probes/2026-11-03-d-global-where/results/ours.json new file mode 100644 index 000000000..1a0e435cc --- /dev/null +++ b/.claude/probes/2026-11-03-d-global-where/results/ours.json @@ -0,0 +1,170 @@ +[ + {"dataset": "dr64_sparse", "size": 64, "dist": "sparse", "edges": 64, "workload": "W1", "arm": "quack_count", "answer": 3296, "cold_us": 25.862, "warm_med_us": 10.402, "warm_p10_us": 9.631, "warm_p90_us": 10.810, "where_q_us": null, "where_v_us": null, "route_us": null, "fold_us": 9.847, "update_us": null, "alloc_bytes_prep": 2248, "alloc_bytes_query": 0, "peak_bytes": 0, "interm_cardinality": null}, + {"dataset": "dr64_sparse", "size": 64, "dist": "sparse", "edges": 64, "workload": "W2", "arm": "fold", "answer": 0, "cold_us": 41.175, "warm_med_us": 0.349, "warm_p10_us": 0.326, "warm_p90_us": 0.379, "where_q_us": 21.072, "where_v_us": 0.275, "route_us": null, "fold_us": 0.180, "update_us": null, "alloc_bytes_prep": 5300, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": 5}, + {"dataset": "dr64_sparse", "size": 64, "dist": "sparse", "edges": 64, "workload": "W3", "arm": "back", "answer": 0, "cold_us": 41.858, "warm_med_us": 2.072, "warm_p10_us": 1.998, "warm_p90_us": 2.146, "where_q_us": 21.072, "where_v_us": 0.275, "route_us": null, "fold_us": 1.846, "update_us": null, "alloc_bytes_prep": 5300, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": 17}, + {"dataset": "dr64_sparse", "size": 64, "dist": "sparse", "edges": 64, "workload": "W3", "arm": "tile", "answer": 0, "cold_us": 40.435, "warm_med_us": 0.523, "warm_p10_us": 0.499, "warm_p90_us": 0.567, "where_q_us": 21.072, "where_v_us": 0.275, "route_us": null, "fold_us": 0.335, "update_us": null, "alloc_bytes_prep": 5300, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": null}, + {"dataset": "dr64_sparse", "size": 64, "dist": "sparse", "edges": 64, "workload": "W3", "arm": "csr", "answer": 0, "cold_us": 40.901, "warm_med_us": 0.249, "warm_p10_us": 0.224, "warm_p90_us": 0.272, "where_q_us": 21.072, "where_v_us": 0.275, "route_us": null, "fold_us": 0.078, "update_us": null, "alloc_bytes_prep": 5816, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": null}, + {"dataset": "dr64_sparse", "size": 64, "dist": "sparse", "edges": 64, "workload": "W4", "arm": "front", "answer": 1, "cold_us": 40.542, "warm_med_us": 0.635, "warm_p10_us": 0.607, "warm_p90_us": 0.680, "where_q_us": 21.072, "where_v_us": 0.275, "route_us": null, "fold_us": 0.450, "update_us": null, "alloc_bytes_prep": 5300, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": 5}, + {"dataset": "dr64_sparse", "size": 64, "dist": "sparse", "edges": 64, "workload": "W4", "arm": "csr", "answer": 1, "cold_us": 40.733, "warm_med_us": 0.339, "warm_p10_us": 0.322, "warm_p90_us": 0.365, "where_q_us": 21.072, "where_v_us": 0.275, "route_us": null, "fold_us": 0.152, "update_us": null, "alloc_bytes_prep": 5816, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": 5}, + {"dataset": "dr64_sparse", "size": 64, "dist": "sparse", "edges": 64, "workload": "W5a", "arm": "fold", "answer": 5, "cold_us": 39.479, "warm_med_us": 0.253, "warm_p10_us": 0.244, "warm_p90_us": 0.263, "where_q_us": 10.353, "where_v_us": 0.128, "route_us": null, "fold_us": 0.172, "update_us": null, "alloc_bytes_prep": 5300, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": 5}, + {"dataset": "dr64_sparse", "size": 64, "dist": "sparse", "edges": 64, "workload": "W6", "arm": "fold", "answer": 5, "cold_us": 39.855, "warm_med_us": 0.449, "warm_p10_us": 0.416, "warm_p90_us": 0.485, "where_q_us": 10.353, "where_v_us": 0.128, "route_us": null, "fold_us": 0.360, "update_us": null, "alloc_bytes_prep": 5300, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": null}, + {"dataset": "dr64_sparse", "size": 64, "dist": "sparse", "edges": 64, "workload": "W7", "arm": "route_each", "answer": 0, "cold_us": 46.847, "warm_med_us": 1.352, "warm_p10_us": 1.268, "warm_p90_us": 1.406, "where_q_us": null, "where_v_us": null, "route_us": 1.186, "fold_us": 0.183, "update_us": null, "alloc_bytes_prep": 7768, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": 5}, + {"dataset": "dr64_sparse", "size": 64, "dist": "sparse", "edges": 64, "workload": "W7i", "arm": "route_each", "answer": 3, "cold_us": 46.536, "warm_med_us": 1.235, "warm_p10_us": 1.186, "warm_p90_us": 1.279, "where_q_us": null, "where_v_us": null, "route_us": 1.186, "fold_us": 0.071, "update_us": null, "alloc_bytes_prep": 7768, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": null}, + {"dataset": "dr64_sparse", "size": 64, "dist": "sparse", "edges": 64, "workload": "W7", "arm": "reuse", "answer": 0, "cold_us": 46.520, "warm_med_us": 0.184, "warm_p10_us": 0.176, "warm_p90_us": 0.194, "where_q_us": null, "where_v_us": null, "route_us": 1.186, "fold_us": 0.186, "update_us": null, "alloc_bytes_prep": 7768, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": 5}, + {"dataset": "dr64_sparse", "size": 64, "dist": "sparse", "edges": 64, "workload": "W7i", "arm": "reuse", "answer": 3, "cold_us": 64.601, "warm_med_us": 0.068, "warm_p10_us": 0.065, "warm_p90_us": 0.074, "where_q_us": null, "where_v_us": null, "route_us": 1.186, "fold_us": 0.070, "update_us": null, "alloc_bytes_prep": 7768, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": null}, + {"dataset": "dr64_sparse", "size": 64, "dist": "sparse", "edges": 64, "workload": "W8_after", "arm": "after_delete", "answer": 0, "cold_us": 40.276, "warm_med_us": 0.356, "warm_p10_us": 0.329, "warm_p90_us": 0.379, "where_q_us": 21.072, "where_v_us": 0.275, "route_us": null, "fold_us": 0.184, "update_us": 0.131, "alloc_bytes_prep": 5300, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": 1}, + {"dataset": "dr64_medium", "size": 64, "dist": "medium", "edges": 512, "workload": "W1", "arm": "quack_count", "answer": 3296, "cold_us": 16.922, "warm_med_us": 10.129, "warm_p10_us": 9.081, "warm_p90_us": 10.457, "where_q_us": null, "where_v_us": null, "route_us": null, "fold_us": 10.259, "update_us": null, "alloc_bytes_prep": 2248, "alloc_bytes_query": 0, "peak_bytes": 0, "interm_cardinality": null}, + {"dataset": "dr64_medium", "size": 64, "dist": "medium", "edges": 512, "workload": "W2", "arm": "fold", "answer": 5, "cold_us": 54.906, "warm_med_us": 0.391, "warm_p10_us": 0.366, "warm_p90_us": 0.409, "where_q_us": 20.741, "where_v_us": 0.257, "route_us": null, "fold_us": 0.201, "update_us": null, "alloc_bytes_prep": 5300, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": 5}, + {"dataset": "dr64_medium", "size": 64, "dist": "medium", "edges": 512, "workload": "W3", "arm": "back", "answer": 5, "cold_us": 93.190, "warm_med_us": 2.193, "warm_p10_us": 2.113, "warm_p90_us": 2.256, "where_q_us": 20.741, "where_v_us": 0.257, "route_us": null, "fold_us": 1.943, "update_us": null, "alloc_bytes_prep": 5300, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": 63}, + {"dataset": "dr64_medium", "size": 64, "dist": "medium", "edges": 512, "workload": "W3", "arm": "tile", "answer": 5, "cold_us": 55.676, "warm_med_us": 1.444, "warm_p10_us": 1.381, "warm_p90_us": 1.489, "where_q_us": 20.741, "where_v_us": 0.257, "route_us": null, "fold_us": 1.206, "update_us": null, "alloc_bytes_prep": 5300, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": null}, + {"dataset": "dr64_medium", "size": 64, "dist": "medium", "edges": 512, "workload": "W3", "arm": "csr", "answer": 5, "cold_us": 55.926, "warm_med_us": 0.283, "warm_p10_us": 0.270, "warm_p90_us": 0.306, "where_q_us": 20.741, "where_v_us": 0.257, "route_us": null, "fold_us": 0.091, "update_us": null, "alloc_bytes_prep": 7608, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": null}, + {"dataset": "dr64_medium", "size": 64, "dist": "medium", "edges": 512, "workload": "W4", "arm": "front", "answer": 23, "cold_us": 56.906, "warm_med_us": 2.807, "warm_p10_us": 2.717, "warm_p90_us": 2.869, "where_q_us": 20.741, "where_v_us": 0.257, "route_us": null, "fold_us": 2.559, "update_us": null, "alloc_bytes_prep": 5300, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": 64}, + {"dataset": "dr64_medium", "size": 64, "dist": "medium", "edges": 512, "workload": "W4", "arm": "csr", "answer": 23, "cold_us": 60.505, "warm_med_us": 2.001, "warm_p10_us": 1.862, "warm_p90_us": 2.172, "where_q_us": 20.741, "where_v_us": 0.257, "route_us": null, "fold_us": 1.762, "update_us": null, "alloc_bytes_prep": 7608, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": 64}, + {"dataset": "dr64_medium", "size": 64, "dist": "medium", "edges": 512, "workload": "W5a", "arm": "fold", "answer": 31, "cold_us": 53.717, "warm_med_us": 0.255, "warm_p10_us": 0.245, "warm_p90_us": 0.268, "where_q_us": 10.265, "where_v_us": 0.121, "route_us": null, "fold_us": 0.172, "update_us": null, "alloc_bytes_prep": 5300, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": 31}, + {"dataset": "dr64_medium", "size": 64, "dist": "medium", "edges": 512, "workload": "W6", "arm": "fold", "answer": 320, "cold_us": 54.514, "warm_med_us": 0.488, "warm_p10_us": 0.469, "warm_p90_us": 0.515, "where_q_us": 10.265, "where_v_us": 0.121, "route_us": null, "fold_us": 0.401, "update_us": null, "alloc_bytes_prep": 5300, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": null}, + {"dataset": "dr64_medium", "size": 64, "dist": "medium", "edges": 512, "workload": "W7", "arm": "route_each", "answer": 5, "cold_us": 61.571, "warm_med_us": 1.353, "warm_p10_us": 1.247, "warm_p90_us": 1.412, "where_q_us": null, "where_v_us": null, "route_us": 1.213, "fold_us": 0.184, "update_us": null, "alloc_bytes_prep": 7768, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": 5}, + {"dataset": "dr64_medium", "size": 64, "dist": "medium", "edges": 512, "workload": "W7i", "arm": "route_each", "answer": 3, "cold_us": 60.983, "warm_med_us": 1.242, "warm_p10_us": 1.202, "warm_p90_us": 1.296, "where_q_us": null, "where_v_us": null, "route_us": 1.213, "fold_us": 0.070, "update_us": null, "alloc_bytes_prep": 7768, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": null}, + {"dataset": "dr64_medium", "size": 64, "dist": "medium", "edges": 512, "workload": "W7", "arm": "reuse", "answer": 5, "cold_us": 61.159, "warm_med_us": 0.182, "warm_p10_us": 0.173, "warm_p90_us": 0.194, "where_q_us": null, "where_v_us": null, "route_us": 1.213, "fold_us": 0.180, "update_us": null, "alloc_bytes_prep": 7768, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": 5}, + {"dataset": "dr64_medium", "size": 64, "dist": "medium", "edges": 512, "workload": "W7i", "arm": "reuse", "answer": 3, "cold_us": 61.098, "warm_med_us": 0.071, "warm_p10_us": 0.066, "warm_p90_us": 0.076, "where_q_us": null, "where_v_us": null, "route_us": 1.213, "fold_us": 0.071, "update_us": null, "alloc_bytes_prep": 7768, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": null}, + {"dataset": "dr64_medium", "size": 64, "dist": "medium", "edges": 512, "workload": "W8_after", "arm": "after_delete", "answer": 5, "cold_us": 54.817, "warm_med_us": 0.365, "warm_p10_us": 0.351, "warm_p90_us": 0.389, "where_q_us": 20.741, "where_v_us": 0.257, "route_us": null, "fold_us": 0.183, "update_us": 0.472, "alloc_bytes_prep": 5300, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": 5}, + {"dataset": "dr64_dense", "size": 64, "dist": "dense", "edges": 1032, "workload": "W1", "arm": "quack_count", "answer": 3296, "cold_us": 19.969, "warm_med_us": 10.110, "warm_p10_us": 8.932, "warm_p90_us": 10.453, "where_q_us": null, "where_v_us": null, "route_us": null, "fold_us": 10.064, "update_us": null, "alloc_bytes_prep": 2248, "alloc_bytes_query": 0, "peak_bytes": 0, "interm_cardinality": null}, + {"dataset": "dr64_dense", "size": 64, "dist": "dense", "edges": 1032, "workload": "W2", "arm": "fold", "answer": 5, "cold_us": 94.013, "warm_med_us": 0.362, "warm_p10_us": 0.343, "warm_p90_us": 0.393, "where_q_us": 20.759, "where_v_us": 0.275, "route_us": null, "fold_us": 0.182, "update_us": null, "alloc_bytes_prep": 5300, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": 5}, + {"dataset": "dr64_dense", "size": 64, "dist": "dense", "edges": 1032, "workload": "W3", "arm": "back", "answer": 5, "cold_us": 94.979, "warm_med_us": 2.048, "warm_p10_us": 1.947, "warm_p90_us": 2.104, "where_q_us": 20.759, "where_v_us": 0.275, "route_us": null, "fold_us": 1.818, "update_us": null, "alloc_bytes_prep": 5300, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": 64}, + {"dataset": "dr64_dense", "size": 64, "dist": "dense", "edges": 1032, "workload": "W3", "arm": "tile", "answer": 5, "cold_us": 94.983, "warm_med_us": 2.251, "warm_p10_us": 2.180, "warm_p90_us": 2.310, "where_q_us": 20.759, "where_v_us": 0.275, "route_us": null, "fold_us": 2.022, "update_us": null, "alloc_bytes_prep": 5300, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": null}, + {"dataset": "dr64_dense", "size": 64, "dist": "dense", "edges": 1032, "workload": "W3", "arm": "csr", "answer": 5, "cold_us": 96.425, "warm_med_us": 0.270, "warm_p10_us": 0.257, "warm_p90_us": 0.291, "where_q_us": 20.759, "where_v_us": 0.275, "route_us": null, "fold_us": 0.087, "update_us": null, "alloc_bytes_prep": 9688, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": null}, + {"dataset": "dr64_dense", "size": 64, "dist": "dense", "edges": 1032, "workload": "W4", "arm": "front", "answer": 23, "cold_us": 95.901, "warm_med_us": 3.042, "warm_p10_us": 2.928, "warm_p90_us": 3.105, "where_q_us": 20.759, "where_v_us": 0.275, "route_us": null, "fold_us": 2.809, "update_us": null, "alloc_bytes_prep": 5300, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": 64}, + {"dataset": "dr64_dense", "size": 64, "dist": "dense", "edges": 1032, "workload": "W4", "arm": "csr", "answer": 23, "cold_us": 106.935, "warm_med_us": 3.644, "warm_p10_us": 3.472, "warm_p90_us": 3.948, "where_q_us": 20.759, "where_v_us": 0.275, "route_us": null, "fold_us": 3.387, "update_us": null, "alloc_bytes_prep": 9688, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": 64}, + {"dataset": "dr64_dense", "size": 64, "dist": "dense", "edges": 1032, "workload": "W5a", "arm": "fold", "answer": 50, "cold_us": 92.803, "warm_med_us": 0.250, "warm_p10_us": 0.231, "warm_p90_us": 0.265, "where_q_us": 10.377, "where_v_us": 0.141, "route_us": null, "fold_us": 0.170, "update_us": null, "alloc_bytes_prep": 5300, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": 50}, + {"dataset": "dr64_dense", "size": 64, "dist": "dense", "edges": 1032, "workload": "W6", "arm": "fold", "answer": 1261, "cold_us": 93.461, "warm_med_us": 0.529, "warm_p10_us": 0.472, "warm_p90_us": 0.564, "where_q_us": 10.377, "where_v_us": 0.141, "route_us": null, "fold_us": 0.430, "update_us": null, "alloc_bytes_prep": 5300, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": null}, + {"dataset": "dr64_dense", "size": 64, "dist": "dense", "edges": 1032, "workload": "W7", "arm": "route_each", "answer": 5, "cold_us": 100.048, "warm_med_us": 1.360, "warm_p10_us": 1.330, "warm_p90_us": 1.402, "where_q_us": null, "where_v_us": null, "route_us": 1.214, "fold_us": 0.189, "update_us": null, "alloc_bytes_prep": 7768, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": 5}, + {"dataset": "dr64_dense", "size": 64, "dist": "dense", "edges": 1032, "workload": "W7i", "arm": "route_each", "answer": 3, "cold_us": 99.803, "warm_med_us": 1.240, "warm_p10_us": 1.182, "warm_p90_us": 1.283, "where_q_us": null, "where_v_us": null, "route_us": 1.214, "fold_us": 0.072, "update_us": null, "alloc_bytes_prep": 7768, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": null}, + {"dataset": "dr64_dense", "size": 64, "dist": "dense", "edges": 1032, "workload": "W7", "arm": "reuse", "answer": 5, "cold_us": 99.843, "warm_med_us": 0.188, "warm_p10_us": 0.180, "warm_p90_us": 0.199, "where_q_us": null, "where_v_us": null, "route_us": 1.214, "fold_us": 0.187, "update_us": null, "alloc_bytes_prep": 7768, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": 5}, + {"dataset": "dr64_dense", "size": 64, "dist": "dense", "edges": 1032, "workload": "W7i", "arm": "reuse", "answer": 3, "cold_us": 99.739, "warm_med_us": 0.065, "warm_p10_us": 0.057, "warm_p90_us": 0.075, "where_q_us": null, "where_v_us": null, "route_us": 1.214, "fold_us": 0.072, "update_us": null, "alloc_bytes_prep": 7768, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": null}, + {"dataset": "dr64_dense", "size": 64, "dist": "dense", "edges": 1032, "workload": "W8_after", "arm": "after_delete", "answer": 5, "cold_us": 92.959, "warm_med_us": 0.366, "warm_p10_us": 0.351, "warm_p90_us": 0.381, "where_q_us": 20.759, "where_v_us": 0.275, "route_us": null, "fold_us": 0.185, "update_us": 0.890, "alloc_bytes_prep": 5300, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": 10}, + {"dataset": "dr64_skewed", "size": 64, "dist": "skewed", "edges": 467, "workload": "W1", "arm": "quack_count", "answer": 3296, "cold_us": 16.671, "warm_med_us": 10.075, "warm_p10_us": 9.323, "warm_p90_us": 10.347, "where_q_us": null, "where_v_us": null, "route_us": null, "fold_us": 10.023, "update_us": null, "alloc_bytes_prep": 2248, "alloc_bytes_query": 0, "peak_bytes": 0, "interm_cardinality": null}, + {"dataset": "dr64_skewed", "size": 64, "dist": "skewed", "edges": 467, "workload": "W2", "arm": "fold", "answer": 4, "cold_us": 46.970, "warm_med_us": 0.363, "warm_p10_us": 0.346, "warm_p90_us": 0.397, "where_q_us": 20.702, "where_v_us": 0.259, "route_us": null, "fold_us": 0.185, "update_us": null, "alloc_bytes_prep": 5300, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": 5}, + {"dataset": "dr64_skewed", "size": 64, "dist": "skewed", "edges": 467, "workload": "W3", "arm": "back", "answer": 5, "cold_us": 48.139, "warm_med_us": 2.115, "warm_p10_us": 2.045, "warm_p90_us": 2.168, "where_q_us": 20.702, "where_v_us": 0.259, "route_us": null, "fold_us": 1.884, "update_us": null, "alloc_bytes_prep": 5300, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": 51}, + {"dataset": "dr64_skewed", "size": 64, "dist": "skewed", "edges": 467, "workload": "W3", "arm": "tile", "answer": 5, "cold_us": 47.395, "warm_med_us": 1.262, "warm_p10_us": 1.218, "warm_p90_us": 1.300, "where_q_us": 20.702, "where_v_us": 0.259, "route_us": null, "fold_us": 1.034, "update_us": null, "alloc_bytes_prep": 5300, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": null}, + {"dataset": "dr64_skewed", "size": 64, "dist": "skewed", "edges": 467, "workload": "W3", "arm": "csr", "answer": 5, "cold_us": 48.518, "warm_med_us": 0.254, "warm_p10_us": 0.231, "warm_p90_us": 0.280, "where_q_us": 20.702, "where_v_us": 0.259, "route_us": null, "fold_us": 0.077, "update_us": null, "alloc_bytes_prep": 7428, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": null}, + {"dataset": "dr64_skewed", "size": 64, "dist": "skewed", "edges": 467, "workload": "W4", "arm": "front", "answer": 23, "cold_us": 48.609, "warm_med_us": 2.519, "warm_p10_us": 2.380, "warm_p90_us": 2.578, "where_q_us": 20.702, "where_v_us": 0.259, "route_us": null, "fold_us": 2.284, "update_us": null, "alloc_bytes_prep": 5300, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": 64}, + {"dataset": "dr64_skewed", "size": 64, "dist": "skewed", "edges": 467, "workload": "W4", "arm": "csr", "answer": 23, "cold_us": 52.766, "warm_med_us": 1.971, "warm_p10_us": 1.776, "warm_p90_us": 2.104, "where_q_us": 20.702, "where_v_us": 0.259, "route_us": null, "fold_us": 1.736, "update_us": null, "alloc_bytes_prep": 7428, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": 64}, + {"dataset": "dr64_skewed", "size": 64, "dist": "skewed", "edges": 467, "workload": "W5a", "arm": "fold", "answer": 27, "cold_us": 45.764, "warm_med_us": 0.249, "warm_p10_us": 0.235, "warm_p90_us": 0.264, "where_q_us": 10.314, "where_v_us": 0.123, "route_us": null, "fold_us": 0.167, "update_us": null, "alloc_bytes_prep": 5300, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": 27}, + {"dataset": "dr64_skewed", "size": 64, "dist": "skewed", "edges": 467, "workload": "W6", "arm": "fold", "answer": 528, "cold_us": 46.420, "warm_med_us": 0.481, "warm_p10_us": 0.456, "warm_p90_us": 0.512, "where_q_us": 10.314, "where_v_us": 0.123, "route_us": null, "fold_us": 0.383, "update_us": null, "alloc_bytes_prep": 5300, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": null}, + {"dataset": "dr64_skewed", "size": 64, "dist": "skewed", "edges": 467, "workload": "W7", "arm": "route_each", "answer": 4, "cold_us": 53.248, "warm_med_us": 1.364, "warm_p10_us": 1.330, "warm_p90_us": 1.414, "where_q_us": null, "where_v_us": null, "route_us": 1.227, "fold_us": 0.183, "update_us": null, "alloc_bytes_prep": 7768, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": 5}, + {"dataset": "dr64_skewed", "size": 64, "dist": "skewed", "edges": 467, "workload": "W7i", "arm": "route_each", "answer": 3, "cold_us": 52.967, "warm_med_us": 1.250, "warm_p10_us": 1.192, "warm_p90_us": 1.291, "where_q_us": null, "where_v_us": null, "route_us": 1.227, "fold_us": 0.071, "update_us": null, "alloc_bytes_prep": 7768, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": null}, + {"dataset": "dr64_skewed", "size": 64, "dist": "skewed", "edges": 467, "workload": "W7", "arm": "reuse", "answer": 4, "cold_us": 53.013, "warm_med_us": 0.183, "warm_p10_us": 0.177, "warm_p90_us": 0.192, "where_q_us": null, "where_v_us": null, "route_us": 1.227, "fold_us": 0.182, "update_us": null, "alloc_bytes_prep": 7768, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": 5}, + {"dataset": "dr64_skewed", "size": 64, "dist": "skewed", "edges": 467, "workload": "W7i", "arm": "reuse", "answer": 3, "cold_us": 52.784, "warm_med_us": 0.072, "warm_p10_us": 0.068, "warm_p90_us": 0.079, "where_q_us": null, "where_v_us": null, "route_us": 1.227, "fold_us": 0.072, "update_us": null, "alloc_bytes_prep": 7768, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": null}, + {"dataset": "dr64_skewed", "size": 64, "dist": "skewed", "edges": 467, "workload": "W8_after", "arm": "after_delete", "answer": 4, "cold_us": 46.165, "warm_med_us": 0.369, "warm_p10_us": 0.355, "warm_p90_us": 0.385, "where_q_us": 20.702, "where_v_us": 0.259, "route_us": null, "fold_us": 0.185, "update_us": 0.388, "alloc_bytes_prep": 5300, "alloc_bytes_query": 0, "peak_bytes": 6664, "interm_cardinality": 4}, + {"dataset": "dr256_sparse", "size": 256, "dist": "sparse", "edges": 256, "workload": "W1", "arm": "quack_count", "answer": 3296, "cold_us": 22.556, "warm_med_us": 10.031, "warm_p10_us": 9.122, "warm_p90_us": 10.322, "where_q_us": null, "where_v_us": null, "route_us": null, "fold_us": 10.206, "update_us": null, "alloc_bytes_prep": 2248, "alloc_bytes_query": 0, "peak_bytes": 0, "interm_cardinality": null}, + {"dataset": "dr256_sparse", "size": 256, "dist": "sparse", "edges": 256, "workload": "W2", "arm": "fold", "answer": 9, "cold_us": 50.675, "warm_med_us": 1.844, "warm_p10_us": 1.773, "warm_p90_us": 1.985, "where_q_us": 21.110, "where_v_us": 0.726, "route_us": null, "fold_us": 1.092, "update_us": null, "alloc_bytes_prep": 22580, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": 17}, + {"dataset": "dr256_sparse", "size": 256, "dist": "sparse", "edges": 256, "workload": "W3", "arm": "back", "answer": 4, "cold_us": 65.326, "warm_med_us": 17.452, "warm_p10_us": 16.649, "warm_p90_us": 18.286, "where_q_us": 21.110, "where_v_us": 0.726, "route_us": null, "fold_us": 16.047, "update_us": null, "alloc_bytes_prep": 22580, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": 75}, + {"dataset": "dr256_sparse", "size": 256, "dist": "sparse", "edges": 256, "workload": "W3", "arm": "tile", "answer": 4, "cold_us": 50.311, "warm_med_us": 2.343, "warm_p10_us": 2.144, "warm_p90_us": 2.451, "where_q_us": 21.110, "where_v_us": 0.726, "route_us": null, "fold_us": 1.584, "update_us": null, "alloc_bytes_prep": 22580, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": null}, + {"dataset": "dr256_sparse", "size": 256, "dist": "sparse", "edges": 256, "workload": "W3", "arm": "csr", "answer": 4, "cold_us": 54.536, "warm_med_us": 0.825, "warm_p10_us": 0.788, "warm_p90_us": 0.861, "where_q_us": 21.110, "where_v_us": 0.726, "route_us": null, "fold_us": 0.152, "update_us": null, "alloc_bytes_prep": 24632, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": null}, + {"dataset": "dr256_sparse", "size": 256, "dist": "sparse", "edges": 256, "workload": "W4", "arm": "front", "answer": 2, "cold_us": 48.957, "warm_med_us": 2.049, "warm_p10_us": 1.932, "warm_p90_us": 2.154, "where_q_us": 21.110, "where_v_us": 0.726, "route_us": null, "fold_us": 1.291, "update_us": null, "alloc_bytes_prep": 22580, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": 16}, + {"dataset": "dr256_sparse", "size": 256, "dist": "sparse", "edges": 256, "workload": "W4", "arm": "csr", "answer": 2, "cold_us": 54.781, "warm_med_us": 1.062, "warm_p10_us": 0.962, "warm_p90_us": 1.205, "where_q_us": 21.110, "where_v_us": 0.726, "route_us": null, "fold_us": 0.376, "update_us": null, "alloc_bytes_prep": 24632, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": 16}, + {"dataset": "dr256_sparse", "size": 256, "dist": "sparse", "edges": 256, "workload": "W5a", "arm": "fold", "answer": 17, "cold_us": 47.026, "warm_med_us": 0.760, "warm_p10_us": 0.730, "warm_p90_us": 0.796, "where_q_us": 10.380, "where_v_us": 0.334, "route_us": null, "fold_us": 0.447, "update_us": null, "alloc_bytes_prep": 22580, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": 17}, + {"dataset": "dr256_sparse", "size": 256, "dist": "sparse", "edges": 256, "workload": "W6", "arm": "fold", "answer": 17, "cold_us": 49.379, "warm_med_us": 1.721, "warm_p10_us": 1.635, "warm_p90_us": 1.806, "where_q_us": 10.380, "where_v_us": 0.334, "route_us": null, "fold_us": 1.348, "update_us": null, "alloc_bytes_prep": 22580, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": null}, + {"dataset": "dr256_sparse", "size": 256, "dist": "sparse", "edges": 256, "workload": "W7", "arm": "route_each", "answer": 9, "cold_us": 65.663, "warm_med_us": 5.279, "warm_p10_us": 5.152, "warm_p90_us": 5.387, "where_q_us": null, "where_v_us": null, "route_us": 4.244, "fold_us": 1.019, "update_us": null, "alloc_bytes_prep": 28090, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": 17}, + {"dataset": "dr256_sparse", "size": 256, "dist": "sparse", "edges": 256, "workload": "W7i", "arm": "route_each", "answer": 4, "cold_us": 64.566, "warm_med_us": 4.345, "warm_p10_us": 4.210, "warm_p90_us": 4.432, "where_q_us": null, "where_v_us": null, "route_us": 4.244, "fold_us": 0.104, "update_us": null, "alloc_bytes_prep": 28090, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": null}, + {"dataset": "dr256_sparse", "size": 256, "dist": "sparse", "edges": 256, "workload": "W7", "arm": "reuse", "answer": 9, "cold_us": 65.436, "warm_med_us": 1.021, "warm_p10_us": 0.992, "warm_p90_us": 1.040, "where_q_us": null, "where_v_us": null, "route_us": 4.244, "fold_us": 1.016, "update_us": null, "alloc_bytes_prep": 28090, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": 17}, + {"dataset": "dr256_sparse", "size": 256, "dist": "sparse", "edges": 256, "workload": "W7i", "arm": "reuse", "answer": 4, "cold_us": 64.722, "warm_med_us": 0.104, "warm_p10_us": 0.098, "warm_p90_us": 0.111, "where_q_us": null, "where_v_us": null, "route_us": 4.244, "fold_us": 0.100, "update_us": null, "alloc_bytes_prep": 28090, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": null}, + {"dataset": "dr256_sparse", "size": 256, "dist": "sparse", "edges": 256, "workload": "W8_after", "arm": "after_delete", "answer": 9, "cold_us": 49.195, "warm_med_us": 1.694, "warm_p10_us": 1.541, "warm_p90_us": 1.844, "where_q_us": 21.110, "where_v_us": 0.726, "route_us": null, "fold_us": 1.020, "update_us": 0.233, "alloc_bytes_prep": 22580, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": 2}, + {"dataset": "dr256_medium", "size": 256, "dist": "medium", "edges": 2048, "workload": "W1", "arm": "quack_count", "answer": 3296, "cold_us": 14.897, "warm_med_us": 10.166, "warm_p10_us": 9.093, "warm_p90_us": 10.464, "where_q_us": null, "where_v_us": null, "route_us": null, "fold_us": 10.570, "update_us": null, "alloc_bytes_prep": 2248, "alloc_bytes_query": 0, "peak_bytes": 0, "interm_cardinality": null}, + {"dataset": "dr256_medium", "size": 256, "dist": "medium", "edges": 2048, "workload": "W2", "arm": "fold", "answer": 17, "cold_us": 215.772, "warm_med_us": 1.289, "warm_p10_us": 1.181, "warm_p90_us": 1.440, "where_q_us": 21.744, "where_v_us": 0.728, "route_us": null, "fold_us": 0.582, "update_us": null, "alloc_bytes_prep": 22580, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": 17}, + {"dataset": "dr256_medium", "size": 256, "dist": "medium", "edges": 2048, "workload": "W3", "arm": "back", "answer": 17, "cold_us": 222.098, "warm_med_us": 9.642, "warm_p10_us": 9.000, "warm_p90_us": 9.850, "where_q_us": 21.744, "where_v_us": 0.728, "route_us": null, "fold_us": 8.281, "update_us": null, "alloc_bytes_prep": 22580, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": 242}, + {"dataset": "dr256_medium", "size": 256, "dist": "medium", "edges": 2048, "workload": "W3", "arm": "tile", "answer": 17, "cold_us": 217.542, "warm_med_us": 4.720, "warm_p10_us": 4.565, "warm_p90_us": 4.827, "where_q_us": 21.744, "where_v_us": 0.728, "route_us": null, "fold_us": 3.923, "update_us": null, "alloc_bytes_prep": 22580, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": null}, + {"dataset": "dr256_medium", "size": 256, "dist": "medium", "edges": 2048, "workload": "W3", "arm": "csr", "answer": 17, "cold_us": 231.427, "warm_med_us": 0.879, "warm_p10_us": 0.847, "warm_p90_us": 0.905, "where_q_us": 21.744, "where_v_us": 0.728, "route_us": null, "fold_us": 0.185, "update_us": null, "alloc_bytes_prep": 31800, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": null}, + {"dataset": "dr256_medium", "size": 256, "dist": "medium", "edges": 2048, "workload": "W4", "arm": "front", "answer": 77, "cold_us": 222.040, "warm_med_us": 9.665, "warm_p10_us": 9.381, "warm_p90_us": 9.816, "where_q_us": 21.744, "where_v_us": 0.728, "route_us": null, "fold_us": 8.794, "update_us": null, "alloc_bytes_prep": 22580, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": 255}, + {"dataset": "dr256_medium", "size": 256, "dist": "medium", "edges": 2048, "workload": "W4", "arm": "csr", "answer": 77, "cold_us": 247.657, "warm_med_us": 7.374, "warm_p10_us": 7.011, "warm_p90_us": 7.972, "where_q_us": 21.744, "where_v_us": 0.728, "route_us": null, "fold_us": 6.295, "update_us": null, "alloc_bytes_prep": 31800, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": 255}, + {"dataset": "dr256_medium", "size": 256, "dist": "medium", "edges": 2048, "workload": "W5a", "arm": "fold", "answer": 109, "cold_us": 212.990, "warm_med_us": 0.749, "warm_p10_us": 0.723, "warm_p90_us": 0.787, "where_q_us": 10.781, "where_v_us": 0.342, "route_us": null, "fold_us": 0.446, "update_us": null, "alloc_bytes_prep": 22580, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": 109}, + {"dataset": "dr256_medium", "size": 256, "dist": "medium", "edges": 2048, "workload": "W6", "arm": "fold", "answer": 1088, "cold_us": 215.426, "warm_med_us": 1.813, "warm_p10_us": 1.664, "warm_p90_us": 1.897, "where_q_us": 10.781, "where_v_us": 0.342, "route_us": null, "fold_us": 1.469, "update_us": null, "alloc_bytes_prep": 22580, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": null}, + {"dataset": "dr256_medium", "size": 256, "dist": "medium", "edges": 2048, "workload": "W7", "arm": "route_each", "answer": 17, "cold_us": 230.809, "warm_med_us": 4.777, "warm_p10_us": 4.614, "warm_p90_us": 4.883, "where_q_us": null, "where_v_us": null, "route_us": 4.284, "fold_us": 0.544, "update_us": null, "alloc_bytes_prep": 28090, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": 17}, + {"dataset": "dr256_medium", "size": 256, "dist": "medium", "edges": 2048, "workload": "W7i", "arm": "route_each", "answer": 4, "cold_us": 229.572, "warm_med_us": 4.262, "warm_p10_us": 4.124, "warm_p90_us": 4.377, "where_q_us": null, "where_v_us": null, "route_us": 4.284, "fold_us": 0.077, "update_us": null, "alloc_bytes_prep": 28090, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": null}, + {"dataset": "dr256_medium", "size": 256, "dist": "medium", "edges": 2048, "workload": "W7", "arm": "reuse", "answer": 17, "cold_us": 230.295, "warm_med_us": 0.557, "warm_p10_us": 0.545, "warm_p90_us": 0.569, "where_q_us": null, "where_v_us": null, "route_us": 4.284, "fold_us": 0.553, "update_us": null, "alloc_bytes_prep": 28090, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": 17}, + {"dataset": "dr256_medium", "size": 256, "dist": "medium", "edges": 2048, "workload": "W7i", "arm": "reuse", "answer": 4, "cold_us": 229.551, "warm_med_us": 0.076, "warm_p10_us": 0.072, "warm_p90_us": 0.082, "where_q_us": null, "where_v_us": null, "route_us": 4.284, "fold_us": 0.077, "update_us": null, "alloc_bytes_prep": 28090, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": null}, + {"dataset": "dr256_medium", "size": 256, "dist": "medium", "edges": 2048, "workload": "W8_after", "arm": "after_delete", "answer": 17, "cold_us": 215.599, "warm_med_us": 1.038, "warm_p10_us": 0.958, "warm_p90_us": 1.257, "where_q_us": 21.744, "where_v_us": 0.728, "route_us": null, "fold_us": 0.549, "update_us": 1.933, "alloc_bytes_prep": 22580, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": 20}, + {"dataset": "dr256_dense", "size": 256, "dist": "dense", "edges": 16256, "workload": "W1", "arm": "quack_count", "answer": 3296, "cold_us": 18.393, "warm_med_us": 10.046, "warm_p10_us": 9.058, "warm_p90_us": 10.472, "where_q_us": null, "where_v_us": null, "route_us": null, "fold_us": 9.919, "update_us": null, "alloc_bytes_prep": 2248, "alloc_bytes_query": 0, "peak_bytes": 0, "interm_cardinality": null}, + {"dataset": "dr256_dense", "size": 256, "dist": "dense", "edges": 16256, "workload": "W2", "arm": "fold", "answer": 17, "cold_us": 1562.967, "warm_med_us": 1.253, "warm_p10_us": 1.134, "warm_p90_us": 1.379, "where_q_us": 21.501, "where_v_us": 0.727, "route_us": null, "fold_us": 0.571, "update_us": null, "alloc_bytes_prep": 22580, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": 17}, + {"dataset": "dr256_dense", "size": 256, "dist": "dense", "edges": 16256, "workload": "W3", "arm": "back", "answer": 17, "cold_us": 1570.396, "warm_med_us": 9.149, "warm_p10_us": 9.014, "warm_p90_us": 9.275, "where_q_us": 21.501, "where_v_us": 0.727, "route_us": null, "fold_us": 8.331, "update_us": null, "alloc_bytes_prep": 22580, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": 256}, + {"dataset": "dr256_dense", "size": 256, "dist": "dense", "edges": 16256, "workload": "W3", "arm": "tile", "answer": 17, "cold_us": 1588.870, "warm_med_us": 26.352, "warm_p10_us": 26.096, "warm_p90_us": 27.594, "where_q_us": 21.501, "where_v_us": 0.727, "route_us": null, "fold_us": 26.297, "update_us": null, "alloc_bytes_prep": 22580, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": null}, + {"dataset": "dr256_dense", "size": 256, "dist": "dense", "edges": 16256, "workload": "W3", "arm": "csr", "answer": 17, "cold_us": 1613.796, "warm_med_us": 0.848, "warm_p10_us": 0.811, "warm_p90_us": 0.898, "where_q_us": 21.501, "where_v_us": 0.727, "route_us": null, "fold_us": 0.178, "update_us": null, "alloc_bytes_prep": 88632, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": null}, + {"dataset": "dr256_dense", "size": 256, "dist": "dense", "edges": 16256, "workload": "W4", "arm": "front", "answer": 77, "cold_us": 1574.758, "warm_med_us": 13.400, "warm_p10_us": 13.077, "warm_p90_us": 13.583, "where_q_us": 21.501, "where_v_us": 0.727, "route_us": null, "fold_us": 12.558, "update_us": null, "alloc_bytes_prep": 22580, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": 256}, + {"dataset": "dr256_dense", "size": 256, "dist": "dense", "edges": 16256, "workload": "W4", "arm": "csr", "answer": 77, "cold_us": 1682.470, "warm_med_us": 54.435, "warm_p10_us": 52.443, "warm_p90_us": 59.145, "where_q_us": 21.501, "where_v_us": 0.727, "route_us": null, "fold_us": 53.673, "update_us": null, "alloc_bytes_prep": 88632, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": 256}, + {"dataset": "dr256_dense", "size": 256, "dist": "dense", "edges": 16256, "workload": "W5a", "arm": "fold", "answer": 253, "cold_us": 1562.843, "warm_med_us": 0.758, "warm_p10_us": 0.718, "warm_p90_us": 0.799, "where_q_us": 10.664, "where_v_us": 0.340, "route_us": null, "fold_us": 0.449, "update_us": null, "alloc_bytes_prep": 22580, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": 253}, + {"dataset": "dr256_dense", "size": 256, "dist": "dense", "edges": 16256, "workload": "W6", "arm": "fold", "answer": 71273, "cold_us": 1564.596, "warm_med_us": 2.812, "warm_p10_us": 2.572, "warm_p90_us": 2.913, "where_q_us": 10.664, "where_v_us": 0.340, "route_us": null, "fold_us": 2.436, "update_us": null, "alloc_bytes_prep": 22580, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": null}, + {"dataset": "dr256_dense", "size": 256, "dist": "dense", "edges": 16256, "workload": "W7", "arm": "route_each", "answer": 17, "cold_us": 1579.467, "warm_med_us": 4.787, "warm_p10_us": 4.656, "warm_p90_us": 4.897, "where_q_us": null, "where_v_us": null, "route_us": 4.270, "fold_us": 0.548, "update_us": null, "alloc_bytes_prep": 28090, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": 17}, + {"dataset": "dr256_dense", "size": 256, "dist": "dense", "edges": 16256, "workload": "W7i", "arm": "route_each", "answer": 4, "cold_us": 1578.147, "warm_med_us": 4.292, "warm_p10_us": 4.149, "warm_p90_us": 4.394, "where_q_us": null, "where_v_us": null, "route_us": 4.270, "fold_us": 0.076, "update_us": null, "alloc_bytes_prep": 28090, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": null}, + {"dataset": "dr256_dense", "size": 256, "dist": "dense", "edges": 16256, "workload": "W7", "arm": "reuse", "answer": 17, "cold_us": 1578.762, "warm_med_us": 0.554, "warm_p10_us": 0.541, "warm_p90_us": 0.580, "where_q_us": null, "where_v_us": null, "route_us": 4.270, "fold_us": 0.544, "update_us": null, "alloc_bytes_prep": 28090, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": 17}, + {"dataset": "dr256_dense", "size": 256, "dist": "dense", "edges": 16256, "workload": "W7i", "arm": "reuse", "answer": 4, "cold_us": 1577.826, "warm_med_us": 0.074, "warm_p10_us": 0.070, "warm_p90_us": 0.080, "where_q_us": null, "where_v_us": null, "route_us": 4.270, "fold_us": 0.075, "update_us": null, "alloc_bytes_prep": 28090, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": null}, + {"dataset": "dr256_dense", "size": 256, "dist": "dense", "edges": 16256, "workload": "W8_after", "arm": "after_delete", "answer": 17, "cold_us": 1565.109, "warm_med_us": 1.212, "warm_p10_us": 1.136, "warm_p90_us": 1.351, "where_q_us": 21.501, "where_v_us": 0.727, "route_us": null, "fold_us": 0.554, "update_us": 15.139, "alloc_bytes_prep": 22580, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": 162}, + {"dataset": "dr256_skewed", "size": 256, "dist": "skewed", "edges": 1968, "workload": "W1", "arm": "quack_count", "answer": 3296, "cold_us": 24.797, "warm_med_us": 10.073, "warm_p10_us": 8.960, "warm_p90_us": 10.507, "where_q_us": null, "where_v_us": null, "route_us": null, "fold_us": 10.411, "update_us": null, "alloc_bytes_prep": 2248, "alloc_bytes_query": 0, "peak_bytes": 0, "interm_cardinality": null}, + {"dataset": "dr256_skewed", "size": 256, "dist": "skewed", "edges": 1968, "workload": "W2", "arm": "fold", "answer": 9, "cold_us": 213.077, "warm_med_us": 1.298, "warm_p10_us": 1.242, "warm_p90_us": 1.424, "where_q_us": 21.454, "where_v_us": 0.712, "route_us": null, "fold_us": 0.594, "update_us": null, "alloc_bytes_prep": 22580, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": 17}, + {"dataset": "dr256_skewed", "size": 256, "dist": "skewed", "edges": 1968, "workload": "W3", "arm": "back", "answer": 15, "cold_us": 221.444, "warm_med_us": 9.929, "warm_p10_us": 9.591, "warm_p90_us": 10.134, "where_q_us": 21.454, "where_v_us": 0.712, "route_us": null, "fold_us": 8.381, "update_us": null, "alloc_bytes_prep": 22580, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": 134}, + {"dataset": "dr256_skewed", "size": 256, "dist": "skewed", "edges": 1968, "workload": "W3", "arm": "tile", "answer": 15, "cold_us": 214.331, "warm_med_us": 3.123, "warm_p10_us": 2.956, "warm_p90_us": 3.248, "where_q_us": 21.454, "where_v_us": 0.712, "route_us": null, "fold_us": 2.332, "update_us": null, "alloc_bytes_prep": 22580, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": null}, + {"dataset": "dr256_skewed", "size": 256, "dist": "skewed", "edges": 1968, "workload": "W3", "arm": "csr", "answer": 15, "cold_us": 229.699, "warm_med_us": 0.880, "warm_p10_us": 0.810, "warm_p90_us": 0.925, "where_q_us": 21.454, "where_v_us": 0.712, "route_us": null, "fold_us": 0.204, "update_us": null, "alloc_bytes_prep": 31480, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": null}, + {"dataset": "dr256_skewed", "size": 256, "dist": "skewed", "edges": 1968, "workload": "W4", "arm": "front", "answer": 77, "cold_us": 223.633, "warm_med_us": 8.375, "warm_p10_us": 8.213, "warm_p90_us": 8.498, "where_q_us": 21.454, "where_v_us": 0.712, "route_us": null, "fold_us": 7.272, "update_us": null, "alloc_bytes_prep": 22580, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": 256}, + {"dataset": "dr256_skewed", "size": 256, "dist": "skewed", "edges": 1968, "workload": "W4", "arm": "csr", "answer": 77, "cold_us": 245.678, "warm_med_us": 7.125, "warm_p10_us": 6.720, "warm_p90_us": 7.384, "where_q_us": 21.454, "where_v_us": 0.712, "route_us": null, "fold_us": 6.320, "update_us": null, "alloc_bytes_prep": 31480, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": 256}, + {"dataset": "dr256_skewed", "size": 256, "dist": "skewed", "edges": 1968, "workload": "W5a", "arm": "fold", "answer": 50, "cold_us": 210.126, "warm_med_us": 0.735, "warm_p10_us": 0.703, "warm_p90_us": 0.771, "where_q_us": 10.653, "where_v_us": 0.325, "route_us": null, "fold_us": 0.448, "update_us": null, "alloc_bytes_prep": 22580, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": 50}, + {"dataset": "dr256_skewed", "size": 256, "dist": "skewed", "edges": 1968, "workload": "W6", "arm": "fold", "answer": 3459, "cold_us": 213.186, "warm_med_us": 1.727, "warm_p10_us": 1.602, "warm_p90_us": 1.840, "where_q_us": 10.653, "where_v_us": 0.325, "route_us": null, "fold_us": 1.403, "update_us": null, "alloc_bytes_prep": 22580, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": null}, + {"dataset": "dr256_skewed", "size": 256, "dist": "skewed", "edges": 1968, "workload": "W7", "arm": "route_each", "answer": 9, "cold_us": 228.540, "warm_med_us": 4.686, "warm_p10_us": 4.551, "warm_p90_us": 4.795, "where_q_us": null, "where_v_us": null, "route_us": 4.117, "fold_us": 0.551, "update_us": null, "alloc_bytes_prep": 28090, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": 17}, + {"dataset": "dr256_skewed", "size": 256, "dist": "skewed", "edges": 1968, "workload": "W7i", "arm": "route_each", "answer": 4, "cold_us": 228.093, "warm_med_us": 4.206, "warm_p10_us": 4.079, "warm_p90_us": 4.315, "where_q_us": null, "where_v_us": null, "route_us": 4.117, "fold_us": 0.075, "update_us": null, "alloc_bytes_prep": 28090, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": null}, + {"dataset": "dr256_skewed", "size": 256, "dist": "skewed", "edges": 1968, "workload": "W7", "arm": "reuse", "answer": 9, "cold_us": 228.341, "warm_med_us": 0.548, "warm_p10_us": 0.537, "warm_p90_us": 0.562, "where_q_us": null, "where_v_us": null, "route_us": 4.117, "fold_us": 0.555, "update_us": null, "alloc_bytes_prep": 28090, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": 17}, + {"dataset": "dr256_skewed", "size": 256, "dist": "skewed", "edges": 1968, "workload": "W7i", "arm": "reuse", "answer": 4, "cold_us": 227.847, "warm_med_us": 0.076, "warm_p10_us": 0.071, "warm_p90_us": 0.082, "where_q_us": null, "where_v_us": null, "route_us": 4.117, "fold_us": 0.074, "update_us": null, "alloc_bytes_prep": 28090, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": null}, + {"dataset": "dr256_skewed", "size": 256, "dist": "skewed", "edges": 1968, "workload": "W8_after", "arm": "after_delete", "answer": 9, "cold_us": 212.402, "warm_med_us": 1.205, "warm_p10_us": 1.156, "warm_p90_us": 1.329, "where_q_us": 21.454, "where_v_us": 0.712, "route_us": null, "fold_us": 0.554, "update_us": 1.794, "alloc_bytes_prep": 22580, "alloc_bytes_query": 0, "peak_bytes": 26026, "interm_cardinality": 19}, + {"dataset": "multi_sparse", "size": 4096, "dist": "sparse", "edges": 4096, "workload": "W1", "arm": "quack_count", "answer": 3296, "cold_us": 25.163, "warm_med_us": 5.862, "warm_p10_us": 5.821, "warm_p90_us": 5.978, "where_q_us": null, "where_v_us": null, "route_us": null, "fold_us": 5.864, "update_us": null, "alloc_bytes_prep": 2248, "alloc_bytes_query": 0, "peak_bytes": 0, "interm_cardinality": null}, + {"dataset": "multi_sparse", "size": 4096, "dist": "sparse", "edges": 4096, "workload": "W2", "arm": "fold", "answer": 61, "cold_us": 8745.856, "warm_med_us": 10.395, "warm_p10_us": 10.331, "warm_p90_us": 10.483, "where_q_us": 33.764, "where_v_us": 10.383, "route_us": null, "fold_us": 3.618, "update_us": null, "alloc_bytes_prep": 2314608, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": 223}, + {"dataset": "multi_sparse", "size": 4096, "dist": "sparse", "edges": 4096, "workload": "W3", "arm": "back", "answer": 59, "cold_us": 8877.541, "warm_med_us": 109.617, "warm_p10_us": 104.866, "warm_p90_us": 124.599, "where_q_us": 33.764, "where_v_us": 10.383, "route_us": null, "fold_us": 89.223, "update_us": null, "alloc_bytes_prep": 2314608, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": 1192}, + {"dataset": "multi_sparse", "size": 4096, "dist": "sparse", "edges": 4096, "workload": "W3", "arm": "tile", "answer": 59, "cold_us": 8798.195, "warm_med_us": 21.085, "warm_p10_us": 20.743, "warm_p90_us": 42.600, "where_q_us": 33.764, "where_v_us": 10.383, "route_us": null, "fold_us": 14.752, "update_us": null, "alloc_bytes_prep": 2314608, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": null}, + {"dataset": "multi_sparse", "size": 4096, "dist": "sparse", "edges": 4096, "workload": "W3", "arm": "csr", "answer": 59, "cold_us": 9130.509, "warm_med_us": 7.092, "warm_p10_us": 7.028, "warm_p90_us": 7.318, "where_q_us": 33.764, "where_v_us": 10.383, "route_us": null, "fold_us": 0.872, "update_us": null, "alloc_bytes_prep": 2347380, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": null}, + {"dataset": "multi_sparse", "size": 4096, "dist": "sparse", "edges": 4096, "workload": "W4", "arm": "front", "answer": 64, "cold_us": 8782.995, "warm_med_us": 14.306, "warm_p10_us": 14.220, "warm_p90_us": 15.881, "where_q_us": 33.764, "where_v_us": 10.383, "route_us": null, "fold_us": 8.125, "update_us": null, "alloc_bytes_prep": 2314608, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": 210}, + {"dataset": "multi_sparse", "size": 4096, "dist": "sparse", "edges": 4096, "workload": "W4", "arm": "csr", "answer": 64, "cold_us": 9120.139, "warm_med_us": 8.410, "warm_p10_us": 8.352, "warm_p90_us": 8.497, "where_q_us": 33.764, "where_v_us": 10.383, "route_us": null, "fold_us": 2.255, "update_us": null, "alloc_bytes_prep": 2347380, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": 210}, + {"dataset": "multi_sparse", "size": 4096, "dist": "sparse", "edges": 4096, "workload": "W5a", "arm": "fold", "answer": 222, "cold_us": 8727.264, "warm_med_us": 5.866, "warm_p10_us": 5.822, "warm_p90_us": 5.929, "where_q_us": 16.477, "where_v_us": 4.819, "route_us": null, "fold_us": 3.139, "update_us": null, "alloc_bytes_prep": 2314608, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": 222}, + {"dataset": "multi_sparse", "size": 4096, "dist": "sparse", "edges": 4096, "workload": "W6", "arm": "fold", "answer": 223, "cold_us": 8757.728, "warm_med_us": 21.159, "warm_p10_us": 20.951, "warm_p90_us": 22.321, "where_q_us": 16.477, "where_v_us": 4.819, "route_us": null, "fold_us": 18.232, "update_us": null, "alloc_bytes_prep": 2314608, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": null}, + {"dataset": "multi_sparse", "size": 4096, "dist": "sparse", "edges": 4096, "workload": "W7", "arm": "route_each", "answer": 61, "cold_us": 9574.752, "warm_med_us": 664.614, "warm_p10_us": 641.680, "warm_p90_us": 834.310, "where_q_us": null, "where_v_us": null, "route_us": 653.296, "fold_us": 3.893, "update_us": null, "alloc_bytes_prep": 2379996, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": 223}, + {"dataset": "multi_sparse", "size": 4096, "dist": "sparse", "edges": 4096, "workload": "W7i", "arm": "route_each", "answer": 77, "cold_us": 9647.766, "warm_med_us": 686.962, "warm_p10_us": 657.337, "warm_p90_us": 865.595, "where_q_us": null, "where_v_us": null, "route_us": 653.296, "fold_us": 0.051, "update_us": null, "alloc_bytes_prep": 2379996, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": null}, + {"dataset": "multi_sparse", "size": 4096, "dist": "sparse", "edges": 4096, "workload": "W7", "arm": "reuse", "answer": 61, "cold_us": 9752.101, "warm_med_us": 4.823, "warm_p10_us": 4.508, "warm_p90_us": 6.131, "where_q_us": null, "where_v_us": null, "route_us": 653.296, "fold_us": 4.841, "update_us": null, "alloc_bytes_prep": 2379996, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": 223}, + {"dataset": "multi_sparse", "size": 4096, "dist": "sparse", "edges": 4096, "workload": "W7i", "arm": "reuse", "answer": 77, "cold_us": 9955.045, "warm_med_us": 0.063, "warm_p10_us": 0.057, "warm_p90_us": 0.070, "where_q_us": null, "where_v_us": null, "route_us": 653.296, "fold_us": 0.062, "update_us": null, "alloc_bytes_prep": 2379996, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": null}, + {"dataset": "multi_sparse", "size": 4096, "dist": "sparse", "edges": 4096, "workload": "W8_after", "arm": "after_delete", "answer": 61, "cold_us": 8858.552, "warm_med_us": 17.289, "warm_p10_us": 14.752, "warm_p90_us": 19.053, "where_q_us": 33.764, "where_v_us": 10.383, "route_us": null, "fold_us": 4.367, "update_us": 65.981, "alloc_bytes_prep": 2314608, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": 40}, + {"dataset": "multi_medium", "size": 4096, "dist": "medium", "edges": 32768, "workload": "W1", "arm": "quack_count", "answer": 3296, "cold_us": 43.308, "warm_med_us": 9.426, "warm_p10_us": 5.857, "warm_p90_us": 10.086, "where_q_us": null, "where_v_us": null, "route_us": null, "fold_us": 5.867, "update_us": null, "alloc_bytes_prep": 2248, "alloc_bytes_query": 0, "peak_bytes": 0, "interm_cardinality": null}, + {"dataset": "multi_medium", "size": 4096, "dist": "medium", "edges": 32768, "workload": "W2", "arm": "fold", "answer": 211, "cold_us": 40536.975, "warm_med_us": 11.335, "warm_p10_us": 11.275, "warm_p90_us": 14.898, "where_q_us": 26.279, "where_v_us": 9.780, "route_us": null, "fold_us": 4.820, "update_us": null, "alloc_bytes_prep": 2314608, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": 223}, + {"dataset": "multi_medium", "size": 4096, "dist": "medium", "edges": 32768, "workload": "W3", "arm": "back", "answer": 223, "cold_us": 40661.415, "warm_med_us": 112.181, "warm_p10_us": 108.729, "warm_p90_us": 137.538, "where_q_us": 26.279, "where_v_us": 9.780, "route_us": null, "fold_us": 88.801, "update_us": null, "alloc_bytes_prep": 2314608, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": 3824}, + {"dataset": "multi_medium", "size": 4096, "dist": "medium", "edges": 32768, "workload": "W3", "arm": "tile", "answer": 223, "cold_us": 40584.717, "warm_med_us": 45.734, "warm_p10_us": 44.405, "warm_p90_us": 62.137, "where_q_us": 26.279, "where_v_us": 9.780, "route_us": null, "fold_us": 35.804, "update_us": null, "alloc_bytes_prep": 2314608, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": null}, + {"dataset": "multi_medium", "size": 4096, "dist": "medium", "edges": 32768, "workload": "W3", "arm": "csr", "answer": 223, "cold_us": 41152.615, "warm_med_us": 10.598, "warm_p10_us": 7.418, "warm_p90_us": 12.220, "where_q_us": 26.279, "where_v_us": 9.780, "route_us": null, "fold_us": 1.400, "update_us": null, "alloc_bytes_prep": 2462068, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": null}, + {"dataset": "multi_medium", "size": 4096, "dist": "medium", "edges": 32768, "workload": "W4", "arm": "front", "answer": 1181, "cold_us": 40610.257, "warm_med_us": 110.259, "warm_p10_us": 101.949, "warm_p90_us": 144.087, "where_q_us": 26.279, "where_v_us": 9.780, "route_us": null, "fold_us": 85.474, "update_us": null, "alloc_bytes_prep": 2314608, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": 4092}, + {"dataset": "multi_medium", "size": 4096, "dist": "medium", "edges": 32768, "workload": "W4", "arm": "csr", "answer": 1181, "cold_us": 41288.386, "warm_med_us": 152.290, "warm_p10_us": 129.800, "warm_p90_us": 194.860, "where_q_us": 26.279, "where_v_us": 9.780, "route_us": null, "fold_us": 143.080, "update_us": null, "alloc_bytes_prep": 2462068, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": 4092}, + {"dataset": "multi_medium", "size": 4096, "dist": "medium", "edges": 32768, "workload": "W5a", "arm": "fold", "answer": 1448, "cold_us": 40547.601, "warm_med_us": 5.943, "warm_p10_us": 5.805, "warm_p90_us": 7.751, "where_q_us": 10.186, "where_v_us": 4.505, "route_us": null, "fold_us": 3.137, "update_us": null, "alloc_bytes_prep": 2314608, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": 1448}, + {"dataset": "multi_medium", "size": 4096, "dist": "medium", "edges": 32768, "workload": "W6", "arm": "fold", "answer": 14272, "cold_us": 40549.722, "warm_med_us": 34.342, "warm_p10_us": 30.841, "warm_p90_us": 41.499, "where_q_us": 10.186, "where_v_us": 4.505, "route_us": null, "fold_us": 29.208, "update_us": null, "alloc_bytes_prep": 2314608, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": null}, + {"dataset": "multi_medium", "size": 4096, "dist": "medium", "edges": 32768, "workload": "W7", "arm": "route_each", "answer": 211, "cold_us": 41531.854, "warm_med_us": 679.548, "warm_p10_us": 650.822, "warm_p90_us": 722.478, "where_q_us": null, "where_v_us": null, "route_us": 678.506, "fold_us": 4.816, "update_us": null, "alloc_bytes_prep": 2379996, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": 223}, + {"dataset": "multi_medium", "size": 4096, "dist": "medium", "edges": 32768, "workload": "W7i", "arm": "route_each", "answer": 77, "cold_us": 41385.717, "warm_med_us": 697.754, "warm_p10_us": 652.339, "warm_p90_us": 914.909, "where_q_us": null, "where_v_us": null, "route_us": 678.506, "fold_us": 0.058, "update_us": null, "alloc_bytes_prep": 2379996, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": null}, + {"dataset": "multi_medium", "size": 4096, "dist": "medium", "edges": 32768, "workload": "W7", "arm": "reuse", "answer": 211, "cold_us": 41790.088, "warm_med_us": 5.227, "warm_p10_us": 4.843, "warm_p90_us": 5.807, "where_q_us": null, "where_v_us": null, "route_us": 678.506, "fold_us": 5.048, "update_us": null, "alloc_bytes_prep": 2379996, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": 223}, + {"dataset": "multi_medium", "size": 4096, "dist": "medium", "edges": 32768, "workload": "W7i", "arm": "reuse", "answer": 77, "cold_us": 41806.136, "warm_med_us": 0.067, "warm_p10_us": 0.060, "warm_p90_us": 0.070, "where_q_us": null, "where_v_us": null, "route_us": 678.506, "fold_us": 0.066, "update_us": null, "alloc_bytes_prep": 2379996, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": null}, + {"dataset": "multi_medium", "size": 4096, "dist": "medium", "edges": 32768, "workload": "W8_after", "arm": "after_delete", "answer": 209, "cold_us": 40599.929, "warm_med_us": 15.581, "warm_p10_us": 14.606, "warm_p90_us": 20.040, "where_q_us": 26.279, "where_v_us": 9.780, "route_us": null, "fold_us": 4.905, "update_us": 489.080, "alloc_bytes_prep": 2314608, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": 327}, + {"dataset": "multi_dense", "size": 4096, "dist": "dense", "edges": 503921, "workload": "W1", "arm": "quack_count", "answer": 3296, "cold_us": 15.520, "warm_med_us": 5.778, "warm_p10_us": 5.740, "warm_p90_us": 6.027, "where_q_us": null, "where_v_us": null, "route_us": null, "fold_us": 5.769, "update_us": null, "alloc_bytes_prep": 2248, "alloc_bytes_query": 0, "peak_bytes": 0, "interm_cardinality": null}, + {"dataset": "multi_dense", "size": 4096, "dist": "dense", "edges": 503921, "workload": "W2", "arm": "fold", "answer": 223, "cold_us": 516128.942, "warm_med_us": 12.412, "warm_p10_us": 11.550, "warm_p90_us": 12.522, "where_q_us": 19.428, "where_v_us": 6.103, "route_us": null, "fold_us": 5.579, "update_us": null, "alloc_bytes_prep": 2314608, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": 223}, + {"dataset": "multi_dense", "size": 4096, "dist": "dense", "edges": 503921, "workload": "W3", "arm": "back", "answer": 223, "cold_us": 516262.917, "warm_med_us": 128.439, "warm_p10_us": 119.666, "warm_p90_us": 152.872, "where_q_us": 19.428, "where_v_us": 6.103, "route_us": null, "fold_us": 108.323, "update_us": null, "alloc_bytes_prep": 2314608, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": 4096}, + {"dataset": "multi_dense", "size": 4096, "dist": "dense", "edges": 503921, "workload": "W3", "arm": "tile", "answer": 223, "cold_us": 516615.801, "warm_med_us": 519.088, "warm_p10_us": 500.862, "warm_p90_us": 559.023, "where_q_us": 19.428, "where_v_us": 6.103, "route_us": null, "fold_us": 498.582, "update_us": null, "alloc_bytes_prep": 2314608, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": null}, + {"dataset": "multi_dense", "size": 4096, "dist": "dense", "edges": 503921, "workload": "W3", "arm": "csr", "answer": 223, "cold_us": 519890.835, "warm_med_us": 7.670, "warm_p10_us": 7.609, "warm_p90_us": 7.844, "where_q_us": 19.428, "where_v_us": 6.103, "route_us": null, "fold_us": 1.345, "update_us": null, "alloc_bytes_prep": 4346680, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": null}, + {"dataset": "multi_dense", "size": 4096, "dist": "dense", "edges": 503921, "workload": "W4", "arm": "front", "answer": 1181, "cold_us": 516240.578, "warm_med_us": 130.706, "warm_p10_us": 127.914, "warm_p90_us": 161.554, "where_q_us": 19.428, "where_v_us": 6.103, "route_us": null, "fold_us": 104.875, "update_us": null, "alloc_bytes_prep": 2314608, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": 4096}, + {"dataset": "multi_dense", "size": 4096, "dist": "dense", "edges": 503921, "workload": "W4", "arm": "csr", "answer": 1181, "cold_us": 521590.898, "warm_med_us": 1126.888, "warm_p10_us": 1077.877, "warm_p90_us": 1267.857, "where_q_us": 19.428, "where_v_us": 6.103, "route_us": null, "fold_us": 1089.671, "update_us": null, "alloc_bytes_prep": 4346680, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": 4096}, + {"dataset": "multi_dense", "size": 4096, "dist": "dense", "edges": 503921, "workload": "W5a", "arm": "fold", "answer": 4088, "cold_us": 516157.273, "warm_med_us": 5.857, "warm_p10_us": 5.815, "warm_p90_us": 6.242, "where_q_us": 9.358, "where_v_us": 2.773, "route_us": null, "fold_us": 3.155, "update_us": null, "alloc_bytes_prep": 2314608, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": 4088}, + {"dataset": "multi_dense", "size": 4096, "dist": "dense", "edges": 503921, "workload": "W6", "arm": "fold", "answer": 3382676, "cold_us": 516266.897, "warm_med_us": 119.290, "warm_p10_us": 114.552, "warm_p90_us": 138.126, "where_q_us": 9.358, "where_v_us": 2.773, "route_us": null, "fold_us": 112.510, "update_us": null, "alloc_bytes_prep": 2314608, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": null}, + {"dataset": "multi_dense", "size": 4096, "dist": "dense", "edges": 503921, "workload": "W7", "arm": "route_each", "answer": 223, "cold_us": 516932.259, "warm_med_us": 681.268, "warm_p10_us": 646.842, "warm_p90_us": 883.472, "where_q_us": null, "where_v_us": null, "route_us": 702.295, "fold_us": 6.325, "update_us": null, "alloc_bytes_prep": 2379996, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": 223}, + {"dataset": "multi_dense", "size": 4096, "dist": "dense", "edges": 503921, "workload": "W7i", "arm": "route_each", "answer": 77, "cold_us": 517261.319, "warm_med_us": 652.816, "warm_p10_us": 630.556, "warm_p90_us": 698.415, "where_q_us": null, "where_v_us": null, "route_us": 702.295, "fold_us": 0.063, "update_us": null, "alloc_bytes_prep": 2379996, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": null}, + {"dataset": "multi_dense", "size": 4096, "dist": "dense", "edges": 503921, "workload": "W7", "arm": "reuse", "answer": 223, "cold_us": 516939.629, "warm_med_us": 5.587, "warm_p10_us": 5.564, "warm_p90_us": 5.605, "where_q_us": null, "where_v_us": null, "route_us": 702.295, "fold_us": 5.593, "update_us": null, "alloc_bytes_prep": 2379996, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": 223}, + {"dataset": "multi_dense", "size": 4096, "dist": "dense", "edges": 503921, "workload": "W7i", "arm": "reuse", "answer": 77, "cold_us": 516920.034, "warm_med_us": 0.062, "warm_p10_us": 0.061, "warm_p90_us": 0.063, "where_q_us": null, "where_v_us": null, "route_us": 702.295, "fold_us": 0.063, "update_us": null, "alloc_bytes_prep": 2379996, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": null}, + {"dataset": "multi_dense", "size": 4096, "dist": "dense", "edges": 503921, "workload": "W8_after", "arm": "after_delete", "answer": 223, "cold_us": 516183.326, "warm_med_us": 11.658, "warm_p10_us": 11.520, "warm_p90_us": 15.128, "where_q_us": 19.428, "where_v_us": 6.103, "route_us": null, "fold_us": 5.575, "update_us": 4822.454, "alloc_bytes_prep": 2314608, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": 5039}, + {"dataset": "multi_skewed", "size": 4096, "dist": "skewed", "edges": 32648, "workload": "W1", "arm": "quack_count", "answer": 3296, "cold_us": 14.969, "warm_med_us": 5.782, "warm_p10_us": 5.737, "warm_p90_us": 5.843, "where_q_us": null, "where_v_us": null, "route_us": null, "fold_us": 5.781, "update_us": null, "alloc_bytes_prep": 2248, "alloc_bytes_query": 0, "peak_bytes": 0, "interm_cardinality": null}, + {"dataset": "multi_skewed", "size": 4096, "dist": "skewed", "edges": 32648, "workload": "W2", "arm": "fold", "answer": 100, "cold_us": 36369.290, "warm_med_us": 12.736, "warm_p10_us": 11.851, "warm_p90_us": 15.458, "where_q_us": 19.399, "where_v_us": 6.032, "route_us": null, "fold_us": 5.959, "update_us": null, "alloc_bytes_prep": 2314608, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": 223}, + {"dataset": "multi_skewed", "size": 4096, "dist": "skewed", "edges": 32648, "workload": "W3", "arm": "back", "answer": 209, "cold_us": 36545.362, "warm_med_us": 169.203, "warm_p10_us": 164.569, "warm_p90_us": 188.199, "where_q_us": 19.399, "where_v_us": 6.032, "route_us": null, "fold_us": 152.045, "update_us": null, "alloc_bytes_prep": 2314608, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": 1827}, + {"dataset": "multi_skewed", "size": 4096, "dist": "skewed", "edges": 32648, "workload": "W3", "arm": "tile", "answer": 209, "cold_us": 36406.314, "warm_med_us": 31.079, "warm_p10_us": 30.706, "warm_p90_us": 34.389, "where_q_us": 19.399, "where_v_us": 6.032, "route_us": null, "fold_us": 24.410, "update_us": null, "alloc_bytes_prep": 2314608, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": null}, + {"dataset": "multi_skewed", "size": 4096, "dist": "skewed", "edges": 32648, "workload": "W3", "arm": "csr", "answer": 209, "cold_us": 36831.234, "warm_med_us": 7.633, "warm_p10_us": 7.570, "warm_p90_us": 7.790, "where_q_us": 19.399, "where_v_us": 6.032, "route_us": null, "fold_us": 1.344, "update_us": null, "alloc_bytes_prep": 2461588, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": null}, + {"dataset": "multi_skewed", "size": 4096, "dist": "skewed", "edges": 32648, "workload": "W4", "arm": "front", "answer": 1164, "cold_us": 36441.590, "warm_med_us": 89.182, "warm_p10_us": 87.776, "warm_p90_us": 105.619, "where_q_us": 19.399, "where_v_us": 6.032, "route_us": null, "fold_us": 68.602, "update_us": null, "alloc_bytes_prep": 2314608, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": 4020}, + {"dataset": "multi_skewed", "size": 4096, "dist": "skewed", "edges": 32648, "workload": "W4", "arm": "csr", "answer": 1164, "cold_us": 37012.626, "warm_med_us": 170.971, "warm_p10_us": 151.093, "warm_p90_us": 232.828, "where_q_us": 19.399, "where_v_us": 6.032, "route_us": null, "fold_us": 124.704, "update_us": null, "alloc_bytes_prep": 2461588, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": 4020}, + {"dataset": "multi_skewed", "size": 4096, "dist": "skewed", "edges": 32648, "workload": "W5a", "arm": "fold", "answer": 636, "cold_us": 36384.675, "warm_med_us": 5.449, "warm_p10_us": 5.359, "warm_p90_us": 5.538, "where_q_us": 9.317, "where_v_us": 2.726, "route_us": null, "fold_us": 2.617, "update_us": null, "alloc_bytes_prep": 2314608, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": 636}, + {"dataset": "multi_skewed", "size": 4096, "dist": "skewed", "edges": 32648, "workload": "W6", "arm": "fold", "answer": 428569, "cold_us": 36389.437, "warm_med_us": 21.072, "warm_p10_us": 20.885, "warm_p90_us": 24.327, "where_q_us": 9.317, "where_v_us": 2.726, "route_us": null, "fold_us": 18.323, "update_us": null, "alloc_bytes_prep": 2314608, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": null}, + {"dataset": "multi_skewed", "size": 4096, "dist": "skewed", "edges": 32648, "workload": "W7", "arm": "route_each", "answer": 100, "cold_us": 37263.840, "warm_med_us": 767.773, "warm_p10_us": 736.460, "warm_p90_us": 837.815, "where_q_us": null, "where_v_us": null, "route_us": 740.635, "fold_us": 5.943, "update_us": null, "alloc_bytes_prep": 2379996, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": 223}, + {"dataset": "multi_skewed", "size": 4096, "dist": "skewed", "edges": 32648, "workload": "W7i", "arm": "route_each", "answer": 77, "cold_us": 37204.982, "warm_med_us": 799.079, "warm_p10_us": 732.125, "warm_p90_us": 984.212, "where_q_us": null, "where_v_us": null, "route_us": 740.635, "fold_us": 0.063, "update_us": null, "alloc_bytes_prep": 2379996, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": null}, + {"dataset": "multi_skewed", "size": 4096, "dist": "skewed", "edges": 32648, "workload": "W7", "arm": "reuse", "answer": 100, "cold_us": 37469.373, "warm_med_us": 5.934, "warm_p10_us": 5.889, "warm_p90_us": 6.363, "where_q_us": null, "where_v_us": null, "route_us": 740.635, "fold_us": 5.952, "update_us": null, "alloc_bytes_prep": 2379996, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": 223}, + {"dataset": "multi_skewed", "size": 4096, "dist": "skewed", "edges": 32648, "workload": "W7i", "arm": "reuse", "answer": 77, "cold_us": 37234.028, "warm_med_us": 0.062, "warm_p10_us": 0.061, "warm_p90_us": 0.063, "where_q_us": null, "where_v_us": null, "route_us": 740.635, "fold_us": 0.063, "update_us": null, "alloc_bytes_prep": 2379996, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": null}, + {"dataset": "multi_skewed", "size": 4096, "dist": "skewed", "edges": 32648, "workload": "W8_after", "arm": "after_delete", "answer": 99, "cold_us": 36430.973, "warm_med_us": 11.875, "warm_p10_us": 11.805, "warm_p90_us": 12.691, "where_q_us": 19.399, "where_v_us": 6.032, "route_us": null, "fold_us": 5.946, "update_us": 350.327, "alloc_bytes_prep": 2314608, "alloc_bytes_query": 0, "peak_bytes": 2357692, "interm_cardinality": 326} +]