Skip to content

chore: release v5.0.0#272

Open
sw-release-bot[bot] wants to merge 1 commit into
mainfrom
release-plz-2026-05-19T18-47-08Z
Open

chore: release v5.0.0#272
sw-release-bot[bot] wants to merge 1 commit into
mainfrom
release-plz-2026-05-19T18-47-08Z

Conversation

@sw-release-bot
Copy link
Copy Markdown

@sw-release-bot sw-release-bot Bot commented May 19, 2026

🤖 New release

  • coordinode-lsm-tree: 4.5.0 -> 5.0.0
Changelog

5.0.0 - 2026-05-27

Added

Documentation

  • add Manifest recovery modes section to README (#332)
  • (encryption) AAD-bound encrypted block wire format spec (#250) (#318)

Fixed

  • (table/index) default partitioned index ON at every level (#329) (#340)
  • (table) mirror meta block at mid-file for tail-corruption resilience (#295) (#314)

Performance

Refactored

Testing


This PR was generated with release-plz.

@polaz polaz force-pushed the release-plz-2026-05-19T18-47-08Z branch from 8b69d29 to 22132a5 Compare May 19, 2026 18:56
@polaz polaz changed the title chore: release v4.6.0 chore: release v5.0.0 May 19, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented May 19, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@sw-release-bot sw-release-bot Bot changed the title chore: release v5.0.0 chore: release v4.6.0 May 19, 2026
@sw-release-bot sw-release-bot Bot force-pushed the release-plz-2026-05-19T18-47-08Z branch from 22132a5 to 9333d1d Compare May 19, 2026 20:23
@sw-release-bot sw-release-bot Bot changed the title chore: release v4.6.0 chore: release v5.0.0 May 20, 2026
@sw-release-bot sw-release-bot Bot force-pushed the release-plz-2026-05-19T18-47-08Z branch 4 times, most recently from 537ad18 to 5fad0f0 Compare May 21, 2026 14:19
Copy link
Copy Markdown
Author

@sw-release-bot sw-release-bot Bot left a comment

Choose a reason for hiding this comment

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

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'lsm-tree db_bench'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.15.

Benchmark suite Current: 1c24a37 Previous: ce61479 Ratio
fillseq 929652.2170850233 ops/sec (normalized) 1203358.892593456 ops/sec (normalized) 1.29
fillrandom 485572.12090749916 ops/sec (normalized) 684004.055959021 ops/sec (normalized) 1.41
readrandom 249420.72751907416 ops/sec (normalized) 293185.8790669865 ops/sec (normalized) 1.18
overwrite 520188.67348067 ops/sec (normalized) 651165.60047447 ops/sec (normalized) 1.25
mergerandom 396090.88280023885 ops/sec (normalized) 466073.7463258474 ops/sec (normalized) 1.18

This comment was automatically generated by workflow using github-action-benchmark.

CC: @polaz

@sw-release-bot sw-release-bot Bot force-pushed the release-plz-2026-05-19T18-47-08Z branch 13 times, most recently from 1f6bceb to ca002fa Compare May 23, 2026 17:43
@sw-release-bot sw-release-bot Bot force-pushed the release-plz-2026-05-19T18-47-08Z branch 2 times, most recently from 4d67a8e to 6cb13ca Compare May 23, 2026 19:03
polaz added a commit that referenced this pull request May 23, 2026
…#133 phase 2) (#310)

## Summary

Foundation layer for `O_DIRECT` cache-bypass I/O. Two pieces:

1. **`AlignedBuf`** (`src/fs/aligned_buf.rs`) — heap-allocated byte
buffer with caller-specified alignment. `Vec<u8>` defaults to
`align_of::<u8>() = 1`, which violates `O_DIRECT`'s typical 4 KiB
userspace-buffer alignment (EINVAL on unaligned write/read).
`AlignedBuf` allocates via `Layout::from_size_align`, rounds capacity up
to a multiple of alignment, and exposes a `Vec`-like surface
(`len`/`capacity`/`as_slice`/`as_capacity_mut`/`set_len`/`clear`) + raw
ptr accessors for kernel handoff.

2. **`FsOpenOptions::direct_io`** — new `bool` field + builder method.
On Linux/Android (arches where `asm-generic/fcntl.h`'s `O_DIRECT =
0o40000` is the authoritative value: x86, x86_64, aarch64, riscv32/64,
loongarch64, s390x) the flag becomes a `custom_flags(O_DIRECT)` on the
std `OpenOptions` builder, in both `StdFs::open` and `IoUringFs::open`.

`O_DIRECT` is declared as a named constant rather than pulling in `libc`
— matches the existing `EXDEV` / `flock` pattern in `std_fs.rs`.
Architectures with a divergent `O_DIRECT` bit (arm `0o200000`, mips
`0o100000`, parisc, sparc) are not gated on purpose: emitting the wrong
bit silently would be worse than honouring the documented "`direct_io`
may be ignored" contract. macOS / Windows / other Unix targets fall
through to a cached open for the same reason — `F_NOCACHE` /
`FILE_FLAG_NO_BUFFERING` each need their own opt-in plumbing.

## Design choices (explicit so review does not re-raise)

- **`FsOpenOptions` is `#[non_exhaustive]`.** This is breaking
(struct-literal callers + exhaustive pattern matches stop compiling) but
only relative to the same release that introduces the new `direct_io`
field — which is already breaking for the same callers. Bundling both
changes in one release confines the break to a single semver-major bump
(v5.0.0, queued in PR #272) and lets every future field land as
semver-minor. Builder methods (`.read()`, `.write()`, … `.direct_io()`)
cover every field, so non-struct-literal callers are unaffected.

- **`fs::direct_io` submodule IS gated behind `#[cfg(feature =
"std")]`.** It uses `std::fs::OpenOptions` and is therefore std-only.
The gate is the first concrete step toward honestly feature-gating the
std backend per crate policy. However, it does NOT by itself unblock a
`no_std + alloc` build: the rest of the `fs::*` backend — the
`Fs`/`FsFile` trait *definitions* and all impls (`std_fs`,
`io_uring_fs`, even `MemFs`) — still references `std::io::{Read, Write,
Seek}` + `std::path::Path` directly, and those have no `core::*`
equivalents. Porting the trait surface off `std::io` / `std::path` is a
structural prerequisite tracked as a separate prerequisite issue (#311),
itself part of the no-std migration epic (#274). The `no-std-check` CI
job is `continue-on-error` for exactly this reason — net error count is
not changed by this PR.

## What's NOT in this PR

The Tree-level `Config::direct_io` knob and compaction-writer
integration are deferred to a follow-up. The current SST writer uses
`Vec<u8>` buffers and unaligned block sizes; wiring `direct_io` into
`Config` without an alignment-aware writer would EINVAL on first write.
Foundation lands here so the writer refactor can build on it.

## Test plan

- [x] 12 unit tests for `AlignedBuf` (alignment verification, capacity
rounding, zero init, rejects non-power-of-two / excessive alignment,
zero-capacity dangling sentinel, `set_len` growth + panic, `clear`,
`as_capacity_mut` writes, `Send`/`Sync` compile check, pointer
stability)
- [x] `fs_open_options_default` + `fs_open_options_builders` updated to
cover the new field
- [x] Full nextest suite: 1542 tests pass (1 slow), 6 skipped
- [x] cargo clippy all-features all-targets with -D warnings — clean
- [x] Doctest for `AlignedBuf::new_zeroed` example compiles and passes

## Related

- #311 — port `Fs`/`FsFile` traits off `std::io` + `std::path`
(prerequisite for the rest of `fs::*` to become honestly
feature-gateable)
- #274 — no-std migration epic (parent)
- #272 — release-plz v5.0.0 (semver-major bump that ships the breaking
changes here)

Part of #133
@sw-release-bot sw-release-bot Bot force-pushed the release-plz-2026-05-19T18-47-08Z branch 2 times, most recently from 8f95b2a to 310edff Compare May 24, 2026 00:19
@sw-release-bot sw-release-bot Bot force-pushed the release-plz-2026-05-19T18-47-08Z branch 2 times, most recently from a270353 to 40c8fd6 Compare May 24, 2026 18:19
@sw-release-bot sw-release-bot Bot force-pushed the release-plz-2026-05-19T18-47-08Z branch 17 times, most recently from f303ee5 to e5ddeca Compare May 26, 2026 17:44
@polaz
Copy link
Copy Markdown
Member

polaz commented May 26, 2026

Hold — V5 release batch coordination

This release-plz PR is held in open state pending completion of V5 format batch.

Rationale

Per Q-cycle release strategy decision: V5 will bundle several format-changing features so post-V5 manifests/blocks have a single coherent version step (no V5→V6 rapid succession that would penalize users with chained format migrations).

V5 batch contents (in addition to what's already in this PR)

Issue Status Wall time est.
#352 RuntimeConfig foundation Design complete (Q-cycle resolved); implementation pending ~2-3 days
#297 Manifest hardening Design complete (Q1-Q12 resolved); implementation pending ~1 week
#298 Per-KV protection Design complete (Q1-Q7 resolved); implementation pending ~1 week
#224 scan_since_seqno Design complete (Q1-Q9 resolved); implementation pending ~1 week (parallel with #297/#298)

Estimated total wall time: ~2-3 weeks from now.

Already in this PR (will ship as part of V5)

Action plan

  1. Hold this PR in open state (do not merge yet)
  2. Land feat(config): runtime-toggleable Tree::update_runtime_config foundation #352fix(table): sfa trailer / footer redundancy (single-bit-flip safeguard) #297 + feat(integrity): per-KV protection for memtable / WriteBatch / BlockBuilder (RAM bit-flip detection) #298 + feat: scan_since_seqno() — iterate entries modified after a given sequence number #224 (parallel worktrees) over the next 2-3 weeks
  3. release-plz auto-regenerates this PR contents on subsequent runs to include the batch
  4. Final review + merge → v5.0.0 ships with the complete integrity stack as one coherent release

If batch hits a blocker

Per-issue independence allows partial V5 ship — if e.g. #297 unexpectedly blocks, V5 ships with #352 + #298 + #224 only; #297 follows in V5.x (additive) or V6 if it requires format break.

Marketing pull-quote (target)

"V5: production-grade integrity stack — BuRR filter, Page ECC, AAD encryption, per-KV protection, block-level seqno bounds for CDC, manifest hardening, runtime-toggleable everything with zero-downtime migration via compaction."

When this resolves

polaz added a commit that referenced this pull request May 27, 2026
## Summary

V5-1 of the V5 release batch — foundation for live-toggleable
configuration that downstream V5 features (#297 manifest hardening, #298
per-KV protection, #224 scan_since_seqno) build on. Caller updates
settings via `Tree::update_runtime_config`; subsequent write paths load
the new snapshot lockless. Existing on-disk data stays in its original
format and reads transparently via per-block self-description.
Compaction acts as the live migration mechanism — source blocks
rewritten per the current snapshot over subsequent cycles, all data
converges without stop-the-world coordination.

Closes #352.

## Layered tier separation (no_std-aware)

| Module | Tier | Why |
|--------|------|-----|
| `runtime_config::types` | `alloc` (compiles on no_std + alloc) | Pure
data: `RuntimeConfig` + `ChecksumAlgorithm`. Reachable from no_std
consumers (block decoders, format constants). |
| `runtime_config::handle` | std-bound (`#[cfg(feature = "std")]`) |
`ArcSwap`-based snapshot. `load()` = single atomic load; `update(fn)` =
clone, mutate, atomic swap. |

## Public API

```rust
impl Tree {
    pub fn runtime_config(&self) -> Arc<RuntimeConfig>;
    pub fn update_runtime_config<F: FnOnce(&mut RuntimeConfig)>(&self, mutator: F);
}
```

## ChecksumAlgorithm

Used by downstream V5 features (#297, #298, #300) for block-level and
per-KV checksums. Stable `wire_tag()` / `from_wire_tag()` for on-disk
self-description so each block can dispatch verify per its own recorded
algorithm.

| Variant | Bytes | Speed | Notes |
|---------|-------|-------|-------|
| `Xxh3_64` (default) | 8 | ~50-100 GB/s SIMD | Default — matches
crate-wide XXH3 convention |
| `Xxh3Low32` | 4 | same as `Xxh3_64` | Per-entry use case where space
matters |
| `Crc32c` | 4 | ~30 GB/s HW | Mathematically-proven burst-error
detection |

## Tests

- **10 unit tests** in `runtime_config::types` +
`runtime_config::handle`:
  - digest sizes, wire-tag roundtrip, atomic swap visibility
- snapshot held during update is unchanged (compaction-as-migration
prerequisite)
- concurrent-reads-during-update consistent state (no torn reads under
stress)
  - multiple back-to-back updates: final-state observable
- **4 integration tests** in `tests/runtime_config_integration.rs`:
  - Tree starts at default
  - update visible on next load
  - snapshot outlives update with pre-update state
- runtime config resets to default on reopen (by design — caller
re-applies)

**Workspace: 1664/1664 tests pass** (+24 new vs prior baseline). Lints
clean across all-features lib + tests. Doc tests pass (43).

## Test plan

- [x] strict lints clean across all-features lib + tests
- [x] full nextest workspace: 1664/1664 pass
- [x] doc tests pass (43)
- [x] runtime_config unit tests pass (10/10)
- [x] runtime_config integration tests pass (4/4)
- [x] concurrent torn-read stress test passes (8 readers × 5000 reads +
writer)

## Dependency

`arc-swap = "1.9"` (std-bound; the `experimental-thread-local` no_std
mode is out of scope for now). Handle behind `#[cfg(feature = "std")]`;
future no_std consumers can use `spin::RwLock<RuntimeConfig>` as
alternative documented in code.

## V5 batch coordination

This is V5-1. After merge, V5-2 (#297), V5-3 (#298), V5-4 (#224) can
land in parallel worktrees consuming this foundation. release-plz PR
#272 stays held until full V5 batch lands — then v5.0.0 ships with the
complete integrity stack as one coherent release. See #215 ROADMAP for
full V5 plan.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added runtime-configurable checksum algorithms for block and key-value
integrity checks.
* New lockless, live configuration API to update and read runtime
settings without restarts.
* Configuration changes are isolated per tree session and reset to
defaults upon tree reopen.

* **Tests**
* Added integration and unit tests validating runtime configuration
updates, atomic snapshot semantics, and persistence behavior.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/structured-world/coordinode-lsm-tree/pull/355?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@sw-release-bot sw-release-bot Bot force-pushed the release-plz-2026-05-19T18-47-08Z branch from e5ddeca to 5e00028 Compare May 27, 2026 07:12
@sw-release-bot sw-release-bot Bot force-pushed the release-plz-2026-05-19T18-47-08Z branch from 5e00028 to 59e4a4f Compare May 27, 2026 07:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

perf(loser_tree): close 15-18% small-N regression vs BinaryHeap

1 participant