diff --git a/docs/deployment.md b/docs/deployment.md index aec27ad..a9ff136 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -40,6 +40,7 @@ pass its own paths. .log.trunk the data — chunked zstd frames .log.rings the write-time index (per-chunk time bounds) .log.grain optional token index (present with --index) + .log.grain.commit where the grain ends; a hint, safe to delete .log.bark JSON manifest: durable identity + retention .log.sap optional write-ahead sidecar (present with --wal; always, for the acking network intakes) diff --git a/docs/design.md b/docs/design.md index d4efcb8..85a59b7 100644 --- a/docs/design.md +++ b/docs/design.md @@ -358,6 +358,14 @@ append-only entry per chunk. Three rules: source and re-check it after loading the grain, dropping the grain (and scanning) rather than trusting a mismatched pair. +The grain states neither how many records it holds nor where the last one +ends, so a write that had to find out would read it whole. `.grain.commit` +records both after each completed write, bound to the grain's inode and the +bytes at its two ends, so a grain replaced or rebased by anyone else is walked +once instead of trusted. Whatever lies past the committed end is a torn write +and is cut before the next append. It is a hint under rule 1: delete it and the +next write walks the grain once. + Consequences worth knowing: chunk size is an index-selectivity knob (smaller chunks → sharper lookups, more overhead), the grain trails a live writer by at most its once-a-second maintenance tick (lagging entries just diff --git a/packaging/timberfs.1 b/packaging/timberfs.1 index 7c4fb53..2ca4553 100644 --- a/packaging/timberfs.1 +++ b/packaging/timberfs.1 @@ -3069,6 +3069,8 @@ nothing says so. .TP .BR .grain ", " .rings ", " .trunk " and " .sap are derived or are the data itself. +.B .grain.commit +beside the grain is a hint about where it ends; deleting it costs one walk. .B reindex rebuilds the first; .B identity