You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
perf(btree): make the reused-page sink a set so the free-time check is O(1)
The free-time eligibility test introduced with `freed_reusable` still scanned
`free_page_consumed` linearly, and a copy-on-write free of a pre-existing page
is below the reuse threshold by construction — so the dominant case in a flush
kept paying O(frees x |consumed|), with |consumed| bounded by the free-list
window rather than by anything small. Making the shared sink an FxHashSet drops
that to O(1) per free: the commit path already collapsed it into a set and only
tests membership, begin_write only clears it, and nothing reads its order.
The hang detector now seeds `consumed` at window scale
(WINDOW_PAGES x chain_capacity(page_size)) instead of a token 500 entries; at
the old size it could not observe this term at all.
set_reuse_threshold now debug_asserts that nothing has been freed yet, as do
the two sibling setters, since eligibility is decided at free time and a
threshold arriving afterwards would judge already-classified pages against the
wrong one. That makes the previous re-partition branch unreachable, so it and
the test covering it are gone rather than left as dead code.
Also drops the `reuse_threshold == 0` disjunct, which never decided anything:
every page id is >= 0.
Copy file name to clipboardExpand all lines: CHANGELOG.md
-6Lines changed: 0 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,12 +2,6 @@
2
2
3
3
All notable changes to this project are documented here. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
4
4
5
-
## [Unreleased]
6
-
7
-
### Fixed
8
-
9
-
-**Page allocation no longer rescans the freed list.**`allocate_page` decided in-session reuse eligibility per call, scanning every page freed so far and, for each, every page drawn from the shared free-page cache — both `Vec<u64>`, so the membership test was linear. Since the reuse threshold is the session-start `next_page_id`, every page freed during a transaction fell below it and took the slow arm, making allocation quadratic in the pages a flush touches: a flush large enough would occupy a core indefinitely without completing. Eligibility is now decided once, when the page is freed, and allocation is a pop. Behaviour is unchanged — both inputs to the decision are monotonic within a session, so deciding early is equivalent.
10
-
11
5
## [0.1.0] - 2026-07-28
12
6
13
7
The first release. Pre-releases were published as `0.1.0-beta.N`; the entries below describe `0.1.0` as a whole rather than deltas against a shipped version, since none exists yet.
0 commit comments