Parents and children of check-in [b43fd24a1f]
|
2026-10-23
| ||
| 05:29 |
perf(serve): send a clone's delta chains once
A clone round sends each row with its delta chain, source first, but only remembered what it sent within the round. fossil deltifies each version of a file against the next, so the rows of a file's versions come in rid order, each a delta on a later one: the oldest version's round sent the whole history, and each later version's row, reached in a later round, sent the rest of it again. Cloning the Fossil repository received 333,063 delta cards by round 64 for 22,353 new artifacts, each checked again by the client. The origin now infers what earlier rounds sent: a row below the cursor that its round sent as itself reaches, through sources this clone forwards, every node of its chain. sentEarlier walks down the delta table from a row or a chain source, at most 256 rows, and a row it finds sent is skipped like one sent earlier in the round, and a chain stops at a source it finds sent. Not finding one sends again, which is only redundant. A row below the cursor filled or published after its round passed it is taken as sent; rows below the cursor are not sent again in any case. check-in: 07b30dccde user: [email protected] tags: feat/horizon-cones, trunk | |
| 05:28 |
perf(sync): check received deltas against a cached basis
The real-repository gate found a dense clone of the Fossil repository CPU-bound past an hour, in delta.Checksum and chain expansion. checkDelta rebuilt each received delta's basis from the root of its chain with content.ExpandUnchecked, after walking the chain for availability; a file's history arrives as one chain of hundreds or thousands of deltas, so the cost was quadratic in its depth, as Repo.Verify's was before 1a5abca. A receive pass now rebuilds the basis through an unchecked content cache (content.NewUncheckedCache): from the deepest node of the chain it holds, keeping each node it rebuilds, and it remembers every artifact a card stored and verified once the card's savepoint commits. A clone keeps one such cache across its rounds and clears it when a round rolls back. A basis the cache holds, or one dangling in the pass, needs no availability walk, and the clone's check for a basis to request uses the same knowledge. The cache holds what each row rebuilds to, unchecked as checkDelta's basis always was, so every verdict is unchanged; a verified delta's target also goes to the receive linker, which no longer expands it again. TestCorpusClone (LIBFOSSIL_CORPUS) clones a copy of a repository from an in-process server for profiling. check-in: b43fd24a1f user: [email protected] tags: feat/horizon-cones, trunk | |
| 05:07 |
fix(serve): serve reading requests in a read transaction
Every request ran in a write transaction (BEGIN IMMEDIATE) for as long as it was served, a horizon request read the classification memo in another, and each request created the table-sync schema on a repository without it. A clone arriving while another request was served waited for the write lock past the 5s busy timeout and got HTTP 500 "database is locked (SQLITE_BUSY)"; its client gave up after four attempts. The real-repository gate hit it with a horizon clone beside a dense one. A request none of whose cards can write now runs in a read transaction (db.WithBoundReadTx), which takes a snapshot without the write lock; the memo read does too; loading synced tables only reads, and a schema card creates the schema it registers into. Requests that write keep their write transaction. v0.14.0 has the same write transaction per request: a clone from its server fails the same way while another connection holds the lock. check-in: f8bb98e196 user: [email protected] tags: feat/horizon-cones, trunk | |