Class JsonFileAnnotationLayer
- Namespace
- Kuestenlogik.Bowire.Semantics
- Assembly
- Kuestenlogik.Bowire.dll
File-backed annotation layer. Loads and persists a single
bowire.schema-hints.json file (project or user scope — same
format) and exposes the parsed entries via the same
AnnotationKey / SemanticTag surface as
InMemoryAnnotationLayer.
public sealed class JsonFileAnnotationLayer : IDisposable
- Inheritance
-
JsonFileAnnotationLayer
- Implements
- Inherited Members
Remarks
Reads are cached in-memory after the first LoadAsync(CancellationToken); subsequent Entries reads hit the cache. Writes (SaveAsync(CancellationToken)) go through a write-to-temp-then-rename sequence so a concurrent reader never sees a half-written file — the same atomic-replacement pattern the rest of Bowire's disk-sync layers use.
Concurrency: a per-instance SemaphoreSlim serialises writes against one another. Two JsonFileAnnotationLayer instances writing to the same file path defend against corruption via the atomic rename — the last writer wins the file, intermediate states are never observable on disk.
Constructors
JsonFileAnnotationLayer(string)
Construct a layer pointing at filePath. The
file does not have to exist — a missing file is treated as an
empty layer and is only written on the first
SaveAsync(CancellationToken).
public JsonFileAnnotationLayer(string filePath)
Parameters
filePathstring
Properties
Count
Number of entries currently cached.
public int Count { get; }
Property Value
Entries
Snapshot of every cached entry.
public IReadOnlyCollection<KeyValuePair<AnnotationKey, SemanticTag>> Entries { get; }
Property Value
FilePath
Absolute or relative path the layer reads from / writes to.
public string FilePath { get; }
Property Value
IsLoaded
True after LoadAsync(CancellationToken) has completed at least once.
public bool IsLoaded { get; }
Property Value
Methods
Dispose()
public void Dispose()
Get(AnnotationKey)
Get the raw tag at key (no priority resolution).
public SemanticTag? Get(AnnotationKey key)
Parameters
keyAnnotationKey
Returns
LoadAsync(CancellationToken)
Load (or reload) the file into the in-memory cache. Idempotent: reload clears the cache before re-parsing. A missing file resets the cache to empty and is not an error — that is the "nothing persisted yet" steady state.
public Task LoadAsync(CancellationToken ct = default)
Parameters
Returns
Remove(AnnotationKey)
Remove the entry at key. Returns true
when an entry was actually removed. Touches only the in-memory
cache; call SaveAsync(CancellationToken) to persist the deletion.
public bool Remove(AnnotationKey key)
Parameters
keyAnnotationKey
Returns
Replace(IEnumerable<KeyValuePair<AnnotationKey, SemanticTag>>)
Replace the cache content with entries. Does
not touch disk; call SaveAsync(CancellationToken) separately to
persist. Use this to push a freshly-edited set of annotations
into the layer before saving.
public void Replace(IEnumerable<KeyValuePair<AnnotationKey, SemanticTag>> entries)
Parameters
entriesIEnumerable<KeyValuePair<AnnotationKey, SemanticTag>>
SaveAsync(CancellationToken)
Persist the current cache to FilePath. Writes go
through a FilePath + ".tmp" file that is then atomically
renamed over the destination, so concurrent readers never see a
half-written document. Parent directories are created on
demand.
public Task SaveAsync(CancellationToken ct = default)
Parameters
Returns
Set(AnnotationKey, SemanticTag)
Insert or replace the tag at key. Touches only
the in-memory cache; call SaveAsync(CancellationToken) to persist.
public JsonFileAnnotationLayer Set(AnnotationKey key, SemanticTag tag)
Parameters
keyAnnotationKeytagSemanticTag
Returns
Remarks
Phase 4 — the right-click UI's "Persist for user / project" path lands here. The session-tier layer uses Set(AnnotationKey, SemanticTag) directly; this method is the file-tier mirror so all three tiers share a single write surface from the caller's perspective.