Repository navigation
compactHistory: retention policies that keep chosen versions exactly - #32
Merged
Merged
Conversation
A pure, deterministic compaction of a history: keepAll, keepSince, uniform, tiered, latestOnly and union. Heads and their merge bases are always kept; every kept version is a diff from its nearest kept ancestors (merges record their merged value), roots become snapshots, dropped patches are squashed into their kept descendants with meta.squashed authorship, and untouched records are kept as they were (idempotent). Never larger than the input; an operation budget (diffs and size diffed) returns the input unchanged when exceeded. Property and fuzz tests over random concurrent text and db histories check: kept versions exact, newest value unchanged, valid and deterministic history, idempotence, authorship, monotone size; plus a scale test and pnpm bench:compact. README documents the record format a host must store.
Contributor
Author
|
@codex review |
…set of merge bases @review (#32): - A kept record reused unchanged (e.g. the root snapshot) kept the old history's seqInfo (and source): the new history's first record then claimed an old stream position. Reused records drop seqInfo and source. - mergeBases recursed only when a base was new, so a set of bases whose members were all seen before (in other sets) was not itself merged from its own bases, and those were not kept (the final check then returned the input). Recurse once per set of bases. Regression tests for both (each fails before). README: an identity result means write nothing; no record carries seqInfo or source.
Contributor
Author
|
@codex review |
Contributor
Author
|
@codex review |
Merged
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.
What
compactHistory({ patches, codec, policy, now, budget })is a pure, deterministic compaction of a patchflow history for retention strategies. It was requested by William; the brief is from @ops3. Supported policies:keepAll,keepSince(since),uniform(interval),tiered(tiers),latestOnlyandunion(policies). It returns the new history, the kept versions, and stats: versions and encoded bytes before and after,identity,overBudget, and the work done (diffs,diffSize).How (src/compact-history.ts)
mergeParent/mergePatch, as Session does), so values never depend on futuremerge3changes.meta.squashed = { users (in order), start, end, count }.maxDiffs,maxDiffSize). The same input and budget always give the same result.merge3.Tests (src/compact-history.test.ts)
Property and fuzz tests over 240 random concurrent histories, text and db (up to 3 clients, catch-ups, merge commits with and without a recorded merged value). Each runs a random policy and checks:
Also: unit tests for every policy and selectVersions, a history that starts at a snapshot, refusal of incomplete histories, budget tests, and a 10k-patch scale test. Results: patchflow 241/241 tests pass; oxlint and the build are clean.
Benchmark (
pnpm bench:compact 50000 500 300)50k one-line edits to a 500 KB text, with a snapshot every 300 patches as CoCalc stores them (79 MB). Peak RSS was 762 MB including generating the input; nothing was retained.
Without intermediate snapshots, every value replays from the root (27–70 s for 50k).
Found on the way (not fixed here; in PLAN.md)
With
@cocalc/diff-match-patch1.1.0 andDIFF_WORK_LIMIT25M (#30, released in 0.15.0), a one-line edit to a text of about 800 KB or more gives a patch that replaces the whole text:It looks like charges such as
2 * (len1 + len2)are made before the common prefix and suffix are removed. This affects every commit to such a text, so CoCalc should not move to 0.15 until it's fixed (CoCalc main is on 0.13). It's also whyuniform/tiereddiffs over many edits of the 500 KB benchmark text are whole-text replacements, about 950 KB each.Record format for hosts
See the README section "History compaction", "Storing a compacted history":
parents: [], nopatch,hash, and noseqInfo;userIdandwall, plushash, and for a mergemergeParent/mergePatch;meta.squashedmust be stored;snapshotplusparents.— @ops1