diff --git a/src/GameCult.Caching/Contracts/cultcache-store-composition.md b/src/GameCult.Caching/Contracts/cultcache-store-composition.md index 93bcd5f5..e23d491f 100644 --- a/src/GameCult.Caching/Contracts/cultcache-store-composition.md +++ b/src/GameCult.Caching/Contracts/cultcache-store-composition.md @@ -227,13 +227,14 @@ against what is durably on disk at that moment: `(key, schemaId, storedAt)`. Any insert, delete or replace fails it. Record identity for conditions is `(schemaId, storedAt)`, where `schemaId` is -the id the record is persisted under (`CultStoredDocument.PersistedSchemaId`), +the id the record is persisted under (the internal `CultStoredDocument.PersistedSchemaId`), not the one this cache decodes it as. A value change mints a `storedAt` strictly later than the record it replaces; writers bump a minted timestamp by one tick when it is not later. An entry loaded under compatible schema drift keeps its persisted id until its store rewrites it; a store records each -record its completed write rewrote with the protected instance method -`CacheBackingStore.MarkWritten`, which refuses an entry that is not the one +record its completed write rewrote with the internal instance method +`CacheBackingStore.MarkWritten` (the shipped stores call it; it is not part of +the public API), which refuses an entry that is not the one the store holds in its own `Entries` at that key. That guards against a store marking by mistake an entry it never held; a store that writes another copy into its own `Entries` and then marks it is trusted to have rewritten that diff --git a/src/GameCult.Caching/CultCache.cs b/src/GameCult.Caching/CultCache.cs index bc95ace9..124bea21 100644 --- a/src/GameCult.Caching/CultCache.cs +++ b/src/GameCult.Caching/CultCache.cs @@ -394,9 +394,9 @@ namespace GameCult.Caching /// The schema id this record is durably stored under, as its backing store last read or wrote it. It differs from /// only for a record loaded under compatible schema drift that its /// store has not rewritten since; a store records its rewrite of an entry it holds with . - /// Conditional commit compares this id and with the disk. + /// Conditional commit compares this id and with the disk. Internal to the shipped stores. /// - public string PersistedSchemaId => _persisted.SchemaId; + internal string PersistedSchemaId => _persisted.SchemaId; // The complete document. For a variant, the resolved view: derived, never written back. public object Document => _document ?? @@ -3333,7 +3333,7 @@ namespace GameCult.Caching /// /// is not the entry this store holds in /// at its key: a store marks only its own rewrite. - protected void MarkWritten(CultStoredDocument entry) + internal void MarkWritten(CultStoredDocument entry) { if (entry == null) throw new ArgumentNullException(nameof(entry)); diff --git a/src/GameCult.Caching/GameCult.Caching.csproj b/src/GameCult.Caching/GameCult.Caching.csproj index 7bc41ccc..c3ec80ae 100644 --- a/src/GameCult.Caching/GameCult.Caching.csproj +++ b/src/GameCult.Caching/GameCult.Caching.csproj @@ -9,5 +9,6 @@ + \ No newline at end of file diff --git a/unity/org.gamecult.cultlib/CHANGELOG.md b/unity/org.gamecult.cultlib/CHANGELOG.md index 90b8e819..c5b33142 100644 --- a/unity/org.gamecult.cultlib/CHANGELOG.md +++ b/unity/org.gamecult.cultlib/CHANGELOG.md @@ -76,20 +76,14 @@ All notable changes to this package are documented in this file. reading it. A store with no variant stays `cultcache.store.v1`, byte-identical to 1.0.x. CultMesh single-file reads, the directory store and CultNet refuse a variant record by name; only the C# CultCache resolves variants. +- `CultMesh.WriteSingleFileDocument` and `WriteSingleFileDocumentPayload` read the + file they replace, under the store's `.lock`, and refuse (without touching + it) a file this runtime cannot read, a store stamped with a newer format version, + or one holding any record besides the key being written. They used to replace the + file whole. Write to a store that holds several records through a `CultCache`. ### Added -- `CultStoredDocument.PersistedSchemaId`: the schema id a record is durably - stored under, as its backing store last read or wrote it. It differs from - `Descriptor.SchemaId` only for a record loaded under compatible schema drift - that its store has not rewritten since. -- `CacheBackingStore.MarkWritten(CultStoredDocument)` (protected instance - method): a backing store records that its completed durable write stored a - record under its descriptor, so `PersistedSchemaId` follows the rewrite. It - throws `ArgumentException` for an entry that is not the one the store holds - in its own `Entries`. The single-file and directory stores mark every record - they rewrite; a custom store calls it for each record its own write rewrote. - - Variants: a record that stores only its difference from a base record, resolved in memory when the cache admits it (`cultcache.store.v2`; see the persistence-format contract). A plain write at a variant's key is refused, and `Flatten` replaces a