Skip to content

[pull] canary from vercel:canary#1504

Merged
pull[bot] merged 4 commits intoMLH-Fellowship:canaryfrom
vercel:canary
Mar 20, 2026
Merged

[pull] canary from vercel:canary#1504
pull[bot] merged 4 commits intoMLH-Fellowship:canaryfrom
vercel:canary

Conversation

@pull
Copy link

@pull pull bot commented Mar 20, 2026

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

lukesandberg and others added 4 commits March 19, 2026 22:10
## Summary

Optimizes the turbo-persistence compaction and iteration paths with several targeted improvements:

### Iterator optimizations

- **Flatten index block iteration** — The iterator previously used a `Vec<CurrentIndexBlock>` stack, but SST files have exactly one index level. Inline the index block fields (`index_entries`, `index_block_count`, `index_pos`) directly into `StaticSortedFileIter`, eliminating the stack allocation and `Option` overhead.

- **Non-optional `CurrentKeyBlock`** — Parse the first key block during `try_into_iter()` construction so `current_key_block` is always populated, removing the `Option<CurrentKeyBlock>` wrapper and its `take()`/`Some()` ceremony in the hot loop.

- **Replace `ReadBytesExt` with direct byte indexing** — In `handle_key_match`, `parse_key_block`, and `next_internal`, replace `val.read_u16::<BE>()` etc. with `u16::from_be_bytes(val[0..2].try_into().unwrap())`. This eliminates th mutable slice pointer advancement.

- **Extract `read_offset_entry` helper** — Read type + offset from the key block offset table in a single `u32` load + shift, replacing two separate `ReadBytesExt` calls.


### Refcounting optimization

- **Introduce `RcBytes`** — Thread-local byte slice type using `Rc` instead of `Arc`, eliminating atomic refcount overhead during single-threaded SST iteration. The iteration path (`StaticSortedFileIter`) now produces `RcBytes` slices backed by an `Rc<Mmap>`, so per-entry clone/drop operations are plain integer increments rather than atomic operations.


### Merge iterator simplification

- **Optimize `MergeIter::next`** — Replaced the straightforwards `pop/push` pattern with `PeekMut`-based replace-top pattern, which means we only need to adjust the heap once per iteration instead of twice.

## Benchmark results

### Compaction (`key_8/value_4/entries_16.00Mi/commits_128`)

| Benchmark | Canary | Optimized | Change |
|-----------|--------|-----------|--------|
| partial compaction | 1.949 s | 1.515 s | **-22%** |
| full compaction | 2.051 s | 1.542 s | **-25%** |

### Read path (`static_sorted_file_lookup/entries_1000.00Ki`)

No read regression — the branch is neutral to slightly faster:

| Benchmark | Canary | Optimized | Change |
|-----------|--------|-----------|--------|
| hit/uncached | 6.73 µs | 6.59 µs | **-2%** |
| hit/cached | 140.8 ns | 130.7 ns | **-7%** |
| miss/uncached | 5.10 µs | 5.02 µs | **-2%** |
| miss/cached | 230.1 ns | 233.1 ns | ~+1% (noise) |

## Test plan

- [x] `cargo test -p turbo-persistence` — 60/60 tests passing
- [x] Compaction benchmarks run and compared against canary baseline
- [x] Read path (lookup) benchmarks verified no regression
…ition (#91643)

The test was calling `createNext` inside each `it.each` test body, which
meant deployment setup time counted against the 60-second per-test
timeout introduced in #89929. In deploy mode, `createNext` deploys to
Vercel which can exceed 60 seconds. When the test timed out, the `next`
local variable was never assigned (the `await createNext(...)` hadn't
resolved), so the `afterEach` hook would throw a `TypeError` on
`next.destroy()`. This left the module-level `nextInstance` variable
pointing at the stale, half-initialized deploy instance. When the next
test case started, `createNext` saw the leftover `nextInstance` and
threw `"createNext called without destroying previous instance"`.

The test now uses `nextTestSetup`, which runs `createNext` in
`beforeAll` where it has the longer 120-second `setupTimeout`. Both API
route variants (`/api/single` and `/api/multiple`) are real fixture
files served from a single instance, so deployment only happens once.
…uide (#91698)

## What?

Fixes a broken link in the Preserving UI State guide:
https://nextjs.org/docs/app/guides/preserving-ui-state#examples

The "Activity Patterns demo" link currently points to a non-working URL.

## Why?

The demo link returns a 404 / invalid page, which makes the example
section confusing for readers.

## Changes

- Updated the Activity Patterns demo link to the correct URL.

## Notes

No functional changes, docs only.

@icyJoseph @delbaoliveira
@pull pull bot locked and limited conversation to collaborators Mar 20, 2026
@pull pull bot added the ⤵️ pull label Mar 20, 2026
@pull pull bot merged commit 883d93c into MLH-Fellowship:canary Mar 20, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants