Artifact 4d9e7574978e02507a68c9de32b47bb5dc75574bbf4e706c25a012d4dc382d84:
- File
internal/content/export_test.go
— part of check-in
[13f8021952]
at
2026-10-23 02:24:20
on branch feat/horizon-cones
— perf(content): keep the trees a horizon's walk reads in the memo
draft-fossil-horizon-00 ยง6.2 asks an origin to read each structural artifact's references once per store and classify every cone over that graph. The memo did so for kinds and P, B, S and A cards, but the F cards of a horizon's trees were walked from the store by the first classification of each horizon, so a second horizon under another C or rule re-read every tree it shared with the first.
The memo now keeps, per store lineage, each manifest, baseline and node a walk read: its own F-card targets and its B and S references, so a delta manifest shares its baseline's entry. A view stages what it reads and the memo takes it on Publish, so a request that rolls back leaves nothing; a kept piece serves a view only when its rid is held at that view's prefix, and its size is charged as a read would charge it, so budgets fail where a fresh walk fails. Names are interned and the cache is capped at 64MiB with LRU eviction: fossil-scm's history names about 21M F entries, over 300MiB uncapped.
On a copy of a 21k-check-in fossil repository, horizon B (2000 check-ins back) classified after horizon A (1000 back) took 2.5-3.0s and now 1.6s, reading 995 trees instead of 1995; A is unchanged at about 1.3-1.6s. (user: [email protected], size: 1311) [annotate] [blame] [check-ins using] [more...]
package content import ( "context" "maps" "slices" "github.com/danmestas/go-libfossil/db" ) // LoadAbsencesWithin is LoadAbsencesContext under injected budgets, and // reports what classification read. The tests that use it are an external // package: their fixtures need the manifest writer, which imports this one. func LoadAbsencesWithin( ctx context.Context, q db.Querier, refs ReferenceBudget, treePerCheckin int64, ) (*Absences, ReferenceWork, error) { treeMax := treePerCheckin << 10 if treeMax > defaultReferenceLimits.treeMax { treeMax = defaultReferenceLimits.treeMax } a, err := loadAbsences(ctx, q, referenceLimits{ refs: refs, treePerCheckin: treePerCheckin, treeMax: treeMax, }) if a == nil { return nil, ReferenceWork{}, err } return a, a.work, err } // LoadAbsencesWork is LoadAbsencesContext, reporting what classification // read under the default budgets. func LoadAbsencesWork(ctx context.Context, q db.Querier) (*Absences, ReferenceWork, error) { limits := defaultReferenceLimits return LoadAbsencesWithin(ctx, q, limits.refs, limits.treePerCheckin) } // TreesRead names the trees v's horizon walks read from the store, and // counts the reads. func (v *MemoView) TreesRead() (names []string, reads int) { return slices.Collect(maps.Keys(v.trees)), v.treeReads }