feat(btreemap): allow choosing the page size of a new StableBTreeMap - #442
Open
hpeebles wants to merge 1 commit into
Open
feat(btreemap): allow choosing the page size of a new StableBTreeMap#442hpeebles wants to merge 1 commit into
hpeebles wants to merge 1 commit into
Conversation
A map whose keys or values are unbounded stores its nodes in 1024-byte pages. When entries are typically small that wastes most of each page: a full node of ~20-byte entries (key and value combined) needs ~420 bytes, and most nodes aren't full. Inserting 100k such entries uses 13.4 MiB with the default page size, against 5.2 MiB (-61%) with 384-byte pages, for ~0.2% more stable memory reads per `get`. Add `BTreeMap::new_with_page_size` and `BTreeMap::init_with_page_size` so that users can pick a page size to fit their entries. Nodes that outgrow their page already continue into overflow pages, so entries of any size remain supported at any page size. No change to the memory layout is needed: the V2 header already stores an arbitrary page size, which `load` reads back. The page size is fixed once a map is created, so `init_with_page_size` ignores its argument when loading an existing map. Page sizes below the existing 128-byte minimum are rejected up front with a clear message. New proptest variants cover random operations and memory leaks with 128-byte pages, where nodes routinely spill into overflow pages. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
|
|
|
|
Contributor
Author
schneiderstefan
approved these changes
Sep 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Within OpenChat we have a a few large maps where the entries are unbounded but are ~20 bytes the vast majority of the time. A map whose keys or values are unbounded stores its nodes in 1024-byte pages. When entries are typically small that wastes most of each page: a full node of ~20-byte entries needs ~420 bytes, and most nodes aren't full. Inserting 100k such entries uses 13.4 MiB with the default page size, against 5.2 MiB (-61%) with 384-byte pages, for ~0.2% more stable memory reads per
get.This PR add
BTreeMap::new_with_page_sizeandBTreeMap::init_with_page_sizeso that users can pick a page size to fit their entries. Nodes that outgrow their page already continue into overflow pages, so entries of any size remain supported at any page size.The V2 header already stores an arbitrary page size, which
loadreads back. The page size is fixed once a map is created, soinit_with_page_sizeignores its argument when loading an existing map. Page sizes below the existing 128-byte minimum are rejected up front with a clear message.New proptest variants cover random operations and memory leaks with 128-byte pages, where nodes routinely spill into overflow pages.