Commit a607451
feat(s3): implement bucket versioning (per-key version tree) (#66)
* feat(s3): implement bucket versioning (per-key version tree)
Implements docs/s3-versioning.md: the ObjectLeaf/VersionNode data model
with a per-key prev MST (newest-first by inverted seq), per-bucket seq
allocation under the commit lock, strict ULID version ids carrying the
seq in the low 64 entropy bits, the §5 write rule behind PUT / Copy /
CompleteMultipartUpload / delete-marker insertion, version resolution
for reads with marker 404/405 semantics and x-amz-delete-marker
emission, version-scoped deletes with promotion, DeleteObjects dispatch,
per-version blob_refs claims, ListObjectVersions with pagination,
resumption, and delimiter grouping, Put/GetBucketVersioning, and the
versioned DeleteBucket guard.
Response version ids gate on the versioning state read under the commit
lock, so a racing PutBucketVersioning cannot mint an id the response
then omits.
Tests: unit coverage for token classification, every displacement row,
prev-null eviction, promotion, per-version claim add/release, list
pagination and delimiter grouping, and the bare-leaf invariant; itest
gains the versioning conformance categories (pass/xfail-ratcheted, run
with the versioned teardown conf) plus the never-versioned VD listing
group.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* itest: promote the versioning partition to pass (delete-release era)
With the full release chain in place — ingot /blob/remove (FIL-588),
hilt#37's blob.Remove write-set grant, and smelt#19's piri blob/release
+ blob/reject seed delegations — every body-storing versioning row
passes its bucket teardown. The unexpected-pass ratchet flagged all 40:
the 7 ListObjectVersions rows, the VD listing row, and 32 Versioning
rows move to the pass tables. The one remaining XFail
(DeleteObject_non_existing_objects) needs object-lock-enabled bucket
creation, which ingot does not model.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* feat(s3): store single-version keys as bare manifests behind a value union
Adopt the revised design of docs/s3-versioning.md: the top-MST value is a
keyed union. A key holding one version stores its ObjectManifest CID
directly — the pre-versioning one-block layout — and gains an ObjectLeaf,
wrapped in a "/objectleaf/0" envelope, at its first retained supersession,
keeping it from then on (invariant 6). Unversioned keys never pay the leaf
indirection, and readers dispatch on the envelope exactly: an unknown
envelope key is an error, never a zero-filled cross-type decode.
bucket gains the hand-written envelope codec (EnvelopedLeaf) and the
read-side dispatch (ObjectValue); commitVersion, resolveVersion, the
scoped and unversioned deletes, listWalk, and ListObjectVersions all
handle both value forms; displaced/displacement becomes superseded/
supersession to match the spec. The rewritten bare-key structural test
now asserts the value form through ObjectValue — the old direct
ObjectLeaf decode would zero-fill a manifest and pass vacuously.
Verified: unit suite, go vet, make gen no-op, and the full itest
conformance partition against the smelt stack.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* feat(s3): encode catalog values as a cborgen keyed union
Adopt the revised §2.1: every value block is the keyed union — manifests
under "/objectmanifest/0", leaves under "/objectleaf/0" — replacing the
hand-written envelope codec and the bare-manifest fallback. ValueUnion is
cborgen-generated from omitempty pointer arms; the strict ObjectValue /
EnvelopedManifest / EnvelopedLeaf wrappers require exactly one arm, so a
block carrying no known union key (a newer format, or a pre-union bare
manifest) fails loudly instead of zero-fill decoding. Every manifest
block read/write goes through the enveloped form, keeping a version's
identity CID one encoding everywhere it appears. The ListObjectVersions
resumption comment now spells out why token markers need no existence
check (their seq is a position; only positionless null markers fall back
to re-emission).
Verified: unit suite (union round-trip, unknown-key and pre-union-block
rejection), go vet, stable make gen, and the full itest conformance
partition against the smelt stack.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>1 parent 6a7d9e6 commit a607451
26 files changed
Lines changed: 3286 additions & 295 deletions
File tree
- bucket
- gen
- inmem
- itest
- migrations/sql
- registry
- s3frontend
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
172 | 172 | | |
173 | 173 | | |
174 | 174 | | |
175 | | - | |
176 | | - | |
| 175 | + | |
| 176 | + | |
177 | 177 | | |
178 | 178 | | |
179 | 179 | | |
| |||
0 commit comments