Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
149 commits
Select commit Hold shift + click to select a range
89382f4
Require arctic 0.1.11 and ps-reclaim 0.1.4
Sep 7, 2026
93b938e
Write down what a data page has to say about itself
Sep 7, 2026
5dcbf21
Map paper two onto evidence that already exists
Sep 7, 2026
1cd8301
Cut the page run with as_chunks, which is what CI's clippy asks for
Sep 7, 2026
440c452
Run the formatting check CI was missing
Sep 7, 2026
89b5860
Backfill the change log to 0.3.10
Sep 7, 2026
cce51f6
Name the cause of a persistence event gap, not only its symptom
Sep 7, 2026
f6447e9
Acknowledge orphaned index events before propagating the error
Sep 7, 2026
670fca9
Stop copying the page list every time a page is appended
Sep 8, 2026
08cc865
Let the page directory reach past 64 MiB, and measure the insert path
Sep 8, 2026
c852f95
Measure insert latency as two populations, not one distribution
Sep 8, 2026
db5e283
Borrow the page on the link read instead of cloning its Arc
Sep 8, 2026
f30eff4
Call the insert benchmark what it measures
Sep 8, 2026
ac66ae0
Take WorkTable off tokio::fs, let a persisted table choose its page size
Sep 9, 2026
bb495f9
Take WorkTable off tokio's sync, time and vacuum spawn
Sep 9, 2026
6301d1a
Take the parking_lot fork, not vanilla
Sep 9, 2026
36bec76
Take the last of tokio out, and stop shipping it in the macro
Sep 9, 2026
d5f2981
Say where vanilla parking_lot actually comes from now
Sep 9, 2026
2702c06
Stop two tests sharing one table directory, and let the watermark say…
Sep 9, 2026
e201de2
feat: add columnar fields and clustered indexes
Aug 5, 2026
c495ace
fix: harden columnar side-index design
Aug 6, 2026
0f023d0
fix: land the columnar work on the post-off-tokio tree
Sep 9, 2026
c3de262
fix: keep the columnar work inside the no_std boundary
Sep 9, 2026
030f2ac
Format the two files the tokio removal left unformatted
Sep 9, 2026
26e6ce0
Add the RuntimeBackend model
Sep 9, 2026
acec196
Parse the runtime section and its section annotation
Sep 9, 2026
9539166
Record the runtime profile a query section names
Sep 9, 2026
f4a7cc0
Accept runtime in the free-order section loop
Sep 9, 2026
b74d810
Add a Runtime trait with nagoya and tokio backends
Sep 9, 2026
e5409cc
Add a compile-fail harness for the rules `worktable!` refuses
Sep 9, 2026
2330055
Add draft compile-fail cases for the runtime backend contract
Sep 9, 2026
d6fe47e
Turn the declared runtime into the type the table names
Sep 9, 2026
098d6f1
Say where two expansions differ, not just that they do
Sep 9, 2026
57f869c
Reconcile the runtime lanes that were built in parallel
Sep 9, 2026
ae07c98
Add the runtimes! profile macro and its backend marker
Sep 9, 2026
292e72a
Add .runtime() to the builder-returning selects
Sep 9, 2026
10ad846
Let a tokio profile need the tokio backend to be in the graph
Sep 9, 2026
368c2bf
Keep the compile-fail corpus out of the round-trip scan
Sep 9, 2026
02cd7d0
Let a no_std build name a runtime it cannot spawn on
Sep 9, 2026
f51097c
Make the runtime backend support policy a test
Sep 9, 2026
d1ade6f
Fail the build when a new test spawns tokio tasks on one thread
Sep 9, 2026
9914d41
Write down the whole worktable! DSL, and the runtime syntax proposed …
Sep 9, 2026
f9aadd2
Stop emitting a runtime type into a build that has no runtime
Sep 9, 2026
976915a
Call this 1.9.0-alpha1
Sep 9, 2026
5691cef
Take the patch block out and require the versions by caret
Sep 9, 2026
a4c8753
Prove what a columnar capacity failure leaves behind
Sep 10, 2026
a69afe5
Let `check` read a columnar declaration
Sep 10, 2026
4a421cc
Make a flavor a byte, and look its pool up by index
Sep 10, 2026
97f7e3e
Let a schema name every flavor the registry has
Sep 10, 2026
f9be54a
Add the flavors the sweep found, and the knobs that found them
Sep 10, 2026
6f253e4
Settle the default, and give the read-mostly shape a flavor
Sep 10, 2026
d1ecb3f
Make the default the flavor that cannot collapse
Sep 10, 2026
fe44120
Name the tuning overrides instead of positioning them
Sep 10, 2026
5fa24e1
Stop depending on the queues underneath nagoya
Sep 10, 2026
4f70454
Pin the persisted batch save bug with a failing test
Sep 10, 2026
ed0368c
Expose the pool for one flavor, so per-class routing can be measured
Sep 10, 2026
362471a
Close the page gap that made the batch save parse a hole
Sep 10, 2026
c9c51bf
Stop sleeping 500ms on a collection retry that needs no wait
Sep 10, 2026
6419899
Select batch operations in event order, not page order
Sep 10, 2026
d4e1345
Un-ignore the concurrent persisted upsert test
Sep 10, 2026
304934e
Run the eight spawning tests on a real multi-thread runtime
Sep 10, 2026
3eaa641
Replace the retry-sleep timing test with the predicate it guards
Sep 10, 2026
354e614
Bound every test failure at 5 seconds
Sep 10, 2026
2e82902
Stop the macro emitting std-only names into a no_std consumer
Sep 10, 2026
8390ba4
Add the no_std verifier, and fix the four holes it found
Sep 10, 2026
2123a96
Prove the no_std operations compile, not just the declaration
Sep 10, 2026
84fe98e
Carry columnar through the schema type and the emitter
Sep 10, 2026
810e6e4
Skip the refusal corpus when dumping schemas
Sep 10, 2026
27a0952
Bring the user guide up to 1.9
Sep 10, 2026
dea24f6
Rewrite the guide around worked examples
Sep 10, 2026
1704409
Stop tracking generated PDFs
Sep 10, 2026
cb31c6a
Say what 1.9 changed, in the three places that never mentioned it
Sep 10, 2026
dd6ab91
Generate a Vec-backed table from the same declaration
Sep 10, 2026
df2e0cf
Honour the index backend in worktable_vec!, and default it to arctic
Sep 10, 2026
26b3dcd
Refuse a duplicate in one traversal, and stop refusing congee
Sep 10, 2026
c3fd94c
Stop this test claiming to measure parity, which it cannot
Sep 10, 2026
0f18ff0
Stop claiming the two macros are interchangeable, because they are not
Sep 10, 2026
a46fca3
Give the Vec row its own name, so both macros can declare one table
Sep 10, 2026
e98154a
Fold the Vec table into worktable! as `storage: vec`, and give it hyd…
Sep 10, 2026
9634999
Close the mutation and capacity gaps a Vec table still had
Sep 10, 2026
b23519e
Fold PR 105's review findings, minus the one already fixed here
Sep 10, 2026
8de0ae7
Stop making four crates part of the macro's contract
Sep 10, 2026
6735b82
Spell it `vec: true`, and forbid `persist` beside it
Sep 10, 2026
b76a1bd
Write down where an index stops paying for itself
Sep 11, 2026
3216266
Finish deleting worktable_vec!
Sep 11, 2026
077585b
Take the lint the newest stable added
Sep 11, 2026
fc610b6
Require partition_max_size beside partition_by
Sep 11, 2026
b93e729
Format the nine files that had drifted
Sep 11, 2026
2459be1
Let a vec: true table be partitioned
Sep 11, 2026
29a4fe5
Generate a dense table for a narrow partition_max_size
Sep 11, 2026
d363974
Lint a narrow key off a partition, and model the dense one under loom
Sep 11, 2026
8776ee1
Port AtomicKeyTable, the last thing only worktable-vec had
Sep 11, 2026
9a61b84
Make the checker accept a storage the macro already does
Sep 11, 2026
0ba49fa
Propagate 1.9 into the guide, and write the partition comparison
Sep 11, 2026
f802ddd
Put the WTI leaf width on the call site
Sep 11, 2026
c18b9e4
Give the Vec table the two things its index was already doing
Sep 11, 2026
a95c8b0
Survey which declarations could take a hash index, and find none
Sep 11, 2026
1c785a1
Record the inline collect spike where the next audit will find it
Sep 11, 2026
ef383a0
Wire a hash index backend, on the one table shape that can take it
Sep 11, 2026
ffdf9a5
Name the hash backend in the README
Sep 11, 2026
dd58363
Write down what an update and a delete actually do, per shape
Sep 11, 2026
eb130d1
Make the S3 path blocking, and take tokio out of the build
Sep 11, 2026
18ccb13
Record the Vec persistence design, and correct a blocker that was not…
Sep 11, 2026
4779e96
Generate declared queries for a Vec table
Sep 11, 2026
5ce8a71
Record the reopen page-size defect the full tier found
Sep 11, 2026
6f8b26c
Read persisted pages with payload capacity rather than stride
Sep 11, 2026
855a91e
Expose vacuum pacing at generated Rust call sites
Sep 11, 2026
72cce25
Preserve S3 schema version and satisfy current stable lint
Sep 11, 2026
6f0f6c5
Complete the user callsite guide and qualify the paper evidence
Sep 11, 2026
8630638
Complete the coordinated v3 persistence cutover and release checks
Sep 11, 2026
b4762aa
Preserve Vec mutation invariants and follow relocated unique-index rows
Sep 11, 2026
54e6b01
Validate columnar schemas and classify storage-layout changes
Sep 11, 2026
2e938a9
Document the remaining per-query runtime execution gate
Sep 11, 2026
39ab608
Execute query profiles through owned cancellable runtime tasks
Sep 11, 2026
04d8ad3
Detach owned select futures from iterator lifetimes
Sep 11, 2026
bb1c709
Allow callsite tuning within a runtime backend family
Sep 11, 2026
eba38bc
Clarify runtime flavor locality and displacement behavior
Sep 11, 2026
85113ce
Select short-idle locality as the default table runtime
Sep 11, 2026
ddab440
Keep archived row locks unique across released collisions
Sep 11, 2026
ab486b9
Preserve lock dependency identity when diagnostic labels wrap
Sep 11, 2026
eb1171d
Isolate allocation accounting between concurrent tests
Sep 11, 2026
a01680c
Require the reviewed Nagoya runtime release
Sep 11, 2026
958c1b6
Describe the shipped runtime callsites and idle budget
Sep 11, 2026
f4cb799
Use caret requirements for the DSL and release documentation
Sep 11, 2026
b759541
Make the complete WorkTable target graph build without std
Sep 11, 2026
757e9d5
Keep archived row locks fast and collision safe
Sep 11, 2026
9d3df67
Commit S3 tables through reusable immutable chunks
Sep 11, 2026
eeb879b
Measure incremental S3 payload on a real table
Sep 11, 2026
07e0688
Reject ambiguous S3 manifest file sets
Sep 11, 2026
23c9e9b
Ship the measured WTI search default
Sep 11, 2026
8d99714
Document the measured WTI default tradeoff
Sep 11, 2026
ad32149
Keep owned dependencies on compatible release lines
Sep 12, 2026
f3294ba
Make SpaceIndex tests clean-checkout safe
Sep 12, 2026
722e4e0
Order durable row writes by index events
Sep 12, 2026
4f8eb8a
Use Cargo metadata for release publication
Sep 12, 2026
81d34de
Allow cold release matrices to finish
Sep 12, 2026
144f796
Use the broad Nagoya release family
Sep 12, 2026
b912b59
Allow cold all-feature CI to complete
Sep 12, 2026
0b541b9
Design remote page stores and partial hydration
Sep 12, 2026
61aabe7
Record the remote storage provider decision
Sep 12, 2026
8a4cda0
Qualify remote read-cache evidence
Sep 12, 2026
2196795
Settle the R2 provider decision
Sep 12, 2026
5474ea8
Run the Vec timing guard manually
Sep 12, 2026
4e01926
Reduce S3 mutation uploads to changed pages
Sep 12, 2026
0501c56
Add database-wide S3 persistence catalog
Sep 12, 2026
f5eb6f0
Fix release review correctness gaps
Sep 12, 2026
6227123
Restore scalable archived-row locks
Sep 12, 2026
71507ec
Keep cell write ownership on its thread
Sep 12, 2026
46fb7ba
Test the complete vacuum wake path
Sep 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.pdf binary
100 changes: 87 additions & 13 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,25 @@ permissions:
contents: read

jobs:
# `scripts/ci-local.sh` runs `cargo fmt --all --check` as its first step. CI
# did not, which made the script stricter than CI instead of equal to it, and
# formatting drift reached master unnoticed. Same command, same arguments.
fmt:
name: Formatting
runs-on: ubicloud-standard-2
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- name: Formatting (cargo fmt --all --check)
run: cargo fmt --all --check

build:
name: Build and test (${{ matrix.name }})
runs-on: ubicloud-standard-2
timeout-minutes: 15
# A cold all-target workspace build plus compile-fail's nested Cargo checks
# exceeded 30 minutes when GitHub's cache service was unavailable. Keep
# enough room for a real from-scratch release gate.
timeout-minutes: 45
strategy:
fail-fast: false
matrix:
Expand Down Expand Up @@ -62,6 +77,42 @@ jobs:
- name: Clippy (deny warnings)
run: cargo clippy --workspace --all-targets ${{ matrix.args }} -- -D warnings

cell_lock_models:
name: Archived-row lock concurrency models
runs-on: ubicloud-standard-2
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- run: cargo test --release --lib cell_lock_models
env:
RUSTFLAGS: --cfg wt_loom
CARGO_TARGET_DIR: target/cell-lock-loom

no_default_features:
name: Library without default features
runs-on: ubicloud-standard-2
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- run: sh scripts/check-no-std.sh -p worktable --lib --no-default-features
- run: sh scripts/check-no-std.sh --manifest-path tests/nostd-consumer/Cargo.toml
- run: cargo test --manifest-path tests/nostd-consumer/Cargo.toml
- run: rustup target add x86_64-pc-windows-gnu
- run: sh scripts/check-no-std.sh -p worktable --lib --no-default-features
env:
NO_STD_TARGET: x86_64-pc-windows-gnu
CARGO_TARGET_DIR: target/no-std-cross
- name: Portable search feature combinations
run: |
for search in wti-predictable-search wti-hybrid-search wti-std-search; do
sh scripts/check-no-std.sh -p worktable --lib --no-default-features --features "$search,logical-index-persistence,versioned-row-publication,runtime-backends"
done
- run: cargo clippy -p worktable --lib --no-default-features -- -D warnings

duplicate_index_crates:
name: One version of each shared index crate
runs-on: ubicloud-standard-2
Expand Down Expand Up @@ -91,14 +142,14 @@ jobs:
echo "$duplicates"
echo
echo "WorkTablesIndex, data_bucket and worktable move as one train."
echo "Publish them in lockstep, or pin them to agree."
echo "Publish compatible releases in dependency order."
exit 1
fi
echo "one version of each: ok"

publish:
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
needs: [build, clippy_check, duplicate_index_crates]
needs: [fmt, build, clippy_check, cell_lock_models, no_default_features, duplicate_index_crates]
runs-on: ubicloud-standard-2
timeout-minutes: 45
steps:
Expand All @@ -109,26 +160,49 @@ jobs:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: |
set -euo pipefail
if [ -z "${CARGO_REGISTRY_TOKEN:-}" ]; then echo "CARGO_REGISTRY_TOKEN not set; skipping publish"; exit 0; fi
if [ -z "${CARGO_REGISTRY_TOKEN:-}" ]; then
echo "CARGO_REGISTRY_TOKEN is not set on this repository" >&2
exit 1
fi

# Publish in dependency order. worktable_codegen depends on
# worktable_dsl and worktable depends on worktable_codegen, both by
# path with an exact version, so each must be on the registry before
# path with a caret requirement, so each must be on the registry before
# the next is packaged. Omitting worktable_dsl here is what made
# `cargo publish -p worktable_codegen` fail with "no matching package
# named `worktable_dsl` found" the moment the DSL extraction landed.
manifest_version() {
cargo read-manifest --manifest-path "$1" | jq -er '.version'
}

is_published() {
cargo info --registry crates-io "$1@$2" >/dev/null 2>&1
}

wait_until_published() {
package=$1
version=$2
for _ in $(seq 1 60); do
if is_published "$package" "$version"; then
return 0
fi
sleep 5
done
echo "$package $version did not appear on crates.io in five minutes" >&2
return 1
}

publish_if_new() {
crate="$1"
package="$1"
manifest="$2"
version=$(sed -n 's/^version = "\(.*\)"$/\1/p' "$manifest" | head -1)
# crates.io index paths: four or more characters is {first two}/{next two}/{name}.
if curl -fsSL "https://index.crates.io/wo/rk/$crate" \
| sed -n 's/.*"vers":"\([^"]*\)".*/\1/p' | grep -qx "$version"; then
echo "$crate $version is already on crates.io; skipping"
version=$(manifest_version "$manifest")
if is_published "$package" "$version"; then
echo "$package $version is already on crates.io; skipping"
return 0
fi
echo "publishing $crate $version"
cargo publish -p "$crate"
echo "publishing $package $version"
cargo publish -p "$package"
wait_until_published "$package" "$version"
}

publish_if_new worktable_dsl dsl/Cargo.toml
Expand Down
9 changes: 8 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,17 @@ Cargo.lock
*.DS_Store
tests/data/*
!tests/data/expected/
!tests/data/persist_index_table_of_contents.wt.idx
tests/non-existent/

/.claude/settings.local.json

# cargo-mutants run output
/mutants.out/
/mutants.out.old/

# Generated documents. `docs/wt-user-guide.typ` and the columnar guide are the
# sources; the PDFs are build output and were tracked, so every edit to a guide
# put a new binary blob in the history. Rebuild with:
# typst compile docs/wt-user-guide.typ docs/wt-user-guide.pdf
*.pdf
.DS_Store
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ natively, and Claude Code loads it through the `@AGENTS.md` import in
- **Keep `cargo fmt` and `cargo clippy --workspace --all-targets -- -D warnings` clean.** Lint failures are part of the build here, not advisory. Note `--workspace`: without it `worktable_codegen` is never linted, and note `-D warnings`, because CI denies what your terminal merely prints.
- **Shell scripts are POSIX `sh`.** `#!/bin/sh`, and none of `[[ ]]`, arrays, `echo -e`, process substitution or `pipefail`. Check with `sh -n` before committing. Bash is not guaranteed to be the system shell, and a script that only runs on one machine is not a check.
- **Publishing to crates.io is irreversible.** A version number can never be reused, and yanking does not delete. Run `cargo publish --dry-run` first, publish from the merged default branch, and tag the release.
- **A pre-release version (`-alpha`, `-beta`) needs an exact dependency pin.** A plain `"2.0"` requirement will not match `2.0.0-alpha.1`, so consumers must be bumped deliberately.
- **Use caret dependency requirements, including our prerelease packages.** Name the prerelease explicitly, for example `^1.0.0-beta.19`; `^1.0` alone does not opt into prereleases. Do not introduce exact pins. Record resolved versions in release and benchmark evidence.
- **Docs describe what is true now.** If you change behaviour, update the README and any affected doc in the same change.

## Build & test
Expand Down
Loading
Loading