content: snapshot cache over op-log replay (snapshot.sx) + 20 tests (338/338)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 30s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 30s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
90
lib/content/snapshot.sx
Normal file
90
lib/content/snapshot.sx
Normal file
@@ -0,0 +1,90 @@
|
||||
;; content-on-sx — snapshot cache over the op-log replay.
|
||||
;;
|
||||
;; Snapshots are a CACHE, never primary state: the op log stays the source of
|
||||
;; truth. A snapshot stores a materialised document at a sequence in the persist
|
||||
;; KV; cached reads start from it and replay only the tail of ops, so they return
|
||||
;; a document IDENTICAL to a full replay — just faster. Drop the snapshot and
|
||||
;; nothing is lost.
|
||||
;;
|
||||
;; Requires (loaded by harness): store.sx (+ doc.sx, persist event/log/kv/api).
|
||||
|
||||
(define content/-snap-key (fn (doc-id) (str "content-snap:" doc-id)))
|
||||
|
||||
;; take a snapshot of the current head at the current version. Returns the seq.
|
||||
(define
|
||||
content/snapshot!
|
||||
(fn
|
||||
(b doc-id)
|
||||
(let
|
||||
((seq (content/version-count b doc-id)))
|
||||
(begin (persist/kv-put b (content/-snap-key doc-id) {:doc (content/head b doc-id) :seq seq}) seq))))
|
||||
|
||||
(define
|
||||
content/-snapshot
|
||||
(fn
|
||||
(b doc-id)
|
||||
(if
|
||||
(persist/kv-has? b (content/-snap-key doc-id))
|
||||
(persist/kv-get b (content/-snap-key doc-id))
|
||||
nil)))
|
||||
|
||||
(define
|
||||
content/snapshot-seq
|
||||
(fn
|
||||
(b doc-id)
|
||||
(let
|
||||
((s (content/-snapshot b doc-id)))
|
||||
(if (= s nil) 0 (get s :seq)))))
|
||||
|
||||
(define
|
||||
content/has-snapshot?
|
||||
(fn (b doc-id) (persist/kv-has? b (content/-snap-key doc-id))))
|
||||
|
||||
(define
|
||||
content/drop-snapshot!
|
||||
(fn (b doc-id) (persist/kv-delete b (content/-snap-key doc-id))))
|
||||
|
||||
;; ── cached reads (transparent: identical result to store.sx replay) ──
|
||||
(define
|
||||
content/-tail-ops
|
||||
(fn
|
||||
(b doc-id from to)
|
||||
(map
|
||||
(fn (ev) (persist/event-data ev))
|
||||
(filter
|
||||
(fn
|
||||
(ev)
|
||||
(and
|
||||
(> (persist/event-seq ev) from)
|
||||
(<= (persist/event-seq ev) to)))
|
||||
(content/log b doc-id)))))
|
||||
|
||||
(define
|
||||
content/head-cached
|
||||
(fn
|
||||
(b doc-id)
|
||||
(let
|
||||
((snap (content/-snapshot b doc-id)))
|
||||
(if
|
||||
(= snap nil)
|
||||
(content/head b doc-id)
|
||||
(doc-apply-all
|
||||
(get snap :doc)
|
||||
(content/-tail-ops
|
||||
b
|
||||
doc-id
|
||||
(get snap :seq)
|
||||
(content/version-count b doc-id)))))))
|
||||
|
||||
(define
|
||||
content/at-cached
|
||||
(fn
|
||||
(b doc-id seq)
|
||||
(let
|
||||
((snap (content/-snapshot b doc-id)))
|
||||
(if
|
||||
(or (= snap nil) (< seq (get snap :seq)))
|
||||
(content/at b doc-id seq)
|
||||
(doc-apply-all
|
||||
(get snap :doc)
|
||||
(content/-tail-ops b doc-id (get snap :seq) seq))))))
|
||||
Reference in New Issue
Block a user