Repository navigation
DDIR: a chunk's rows as compressed pages, with lightweight codecs - #1073
Draft
frankmcsherry wants to merge 1 commit into
Draft
frankmcsherry wants to merge 1 commit into
frankmcsherry wants to merge 1 commit into
Conversation
Adds `runtime::pages`: encode a chunk's keys, values, times and diffs into pages of about 16 KiB of uncompressed bytes, and decode a run of pages, for all columns or a subset, back into corgi columns equal to the original rows. Nothing in the engine uses it yet. A page never splits a row, and prefers to end where the identifier changes when that is in the last quarter of the target. A resident index holds each page's first identifier, first row, byte start, and each column's start within the page. Each column of each page is coded by the smallest of raw, frame of reference with bit-packing, a dictionary, or, for eight-byte values, the high and low 32 bits coded apart. Every corgi shape is paged: products by field, lists as lengths and elements, sums as tags and each variant's rows, units as a count, and references as the rows they reference, carried by value. Column subsets are corgi `Demand`s, and decode as `Demand::project` would project them. On the SF1 chunks after the LDBC replay, 3,345.4 MB of resident bytes become 647.0 MB of pages plus 16.1 MB of index. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H6wB4H99TLw4tqu4x48pXL
frankmcsherry
marked this pull request as draft
November 4, 2026 03:55
This branch has not been deployed
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.
A new module,
runtime::pages, encodes a chunk's keys, values, times and diffs as pages of about 16 KiB of uncompressed bytes, and decodes a run of pages back into corgi columns equal to the original rows, for all columns or a chosen subset.Nothing in the engine uses it yet; it is the first step toward chunks compressed at
settle,restrict(#1072) decoding only the pages it needs, and a pager.On the SF1 chunks after the LDBC replay, 3,345.4 MB become 647.0 MB of pages plus 16.1 MB of index.
What changes
Pages::encode(keys, vals, times, diffs, target)cuts rows into pages and codes each column of each page on its own.Pages::decode(pages, &Select)decodes a run of pages into one set of columns.Selecttakes a corgiDemandfor the keys and for the values, plus whether to decode times and diffs; the result equalsDemand::projecton those rows.Pages::pages_for(id)names the pages that may hold an identifier.x ^ 2^63, and floats as their total-order keys.unsafeand no new dependency.Why
A chunk is one set of contiguous columns, so a reader of a few keys pays for all of them, and nothing can be compressed or paged out.
Pages that decode independently let a reader bring in only the pages its keys can be in, and only the columns it reads.
The codecs are lightweight only, pure Rust with no new dependencies; general-purpose compressors are a separate, later decision.
Splitting 64-bit integers into halves matters on LDBC, whose identifiers carry few distinct high halves.
Measurements
The 580 chunks of every live arrangement after the 808-tick LDBC SF1 replay, captured by the compressed-pages spike; one thread, mini-00.
Open questions
usize;u32would take the index from 16.1 to 8.9 MB.2751e04made the encoder take long ways round:Value::as_u8is crate-private, so a byte leaf is read throughas_i64, a copy widened toi64s;as_f64andValue::f64, a pass and a copy each way;Primisn't exported, so a leaf's storage is inferred from its shape;Bounds::len,spanandtotalare crate-private, and sums can be built only fromusizetags.Tests
Demand::project.cargo test -p interactive: 298 passed, 0 failed, 9 ignored; no warnings.Implemented and measured by a Claude Opus subagent; reviewed and opened by Claude Code.
🤖 Generated with Claude Code
https://claude.ai/code/session_01H6wB4H99TLw4tqu4x48pXL