H7: adjacency streams — per-(node,kind) edge reads, no more full kv scans (TDD)

Failing tests first (2 red: relate! wrote no adjacency streams). Every edge write now maintains
per-pair event streams (rel:src|kind ← {:dst}, rin:dst|kind ← {:src}); host/blog-out/-in/--out-raw
(+ new --in-raw) fold ONLY the pair's stream — O(edges of that node under that kind) instead of
O(all kv keys) per read. Append-only ⇒ no read-modify-write race (duplicate :adds fold to a set).
The edge:* kv rows remain (whole-graph consumers: subtype-closure, relations admin block) and feed
host/blog-reindex-edges! — the idempotent boot migration serve.sh now runs, so pre-H7 live stores
read correctly. Collapsed host/blog--add-edge-kv! into add-edge! (the type-algebra conj/disj edges
were bypassing the streams — caught by the existing algebra tests going red).

blog suite 256/256 (+6); FULL conformance 658/658.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-03 10:53:32 +00:00
parent f8b96b3d81
commit 99401ae21e
3 changed files with 78 additions and 24 deletions

View File

@@ -1534,6 +1534,32 @@
(len (filter (fn (e) (= (get e "verb") "h6-ping")) host/blog--flow-log)))
2)
;; ── HARDENING H7: adjacency STREAMS — per-(node,kind) reads, not full kv scans ────────────
;; relate!/unrelate! maintain per-pair event streams (rel:src|kind ← {:dst}, rin:dst|kind ←
;; {:src}); out/in/out-raw fold ONLY the pair's stream (O(edges of that node), not O(all keys)).
;; Legacy stores migrate via host/blog-reindex-edges! at boot.
(host/blog-use-store! (persist/open))
(host/blog-put! "h7a" "a" "(article (h1 \"a\"))" "published")
(host/blog-put! "h7b" "b" "(article (h1 \"b\"))" "published")
(host/blog-relate! "h7a" "h7b" "h7k")
(host-bl-test "H7: relate! writes the forward adjacency stream rel:src|kind"
(>= (len (persist/read host/blog-store "rel:h7a|h7k")) 1) true)
(host-bl-test "H7: relate! writes the reverse adjacency stream rin:dst|kind"
(>= (len (persist/read host/blog-store "rin:h7b|h7k")) 1) true)
(host-bl-test "H7: out-raw reads through (regression)"
(host/blog--out-raw "h7a" "h7k") (list "h7b"))
(host-bl-test "H7: in reads through (regression)"
(host/blog-in "h7b" "h7k") (list "h7a"))
(host-bl-test "H7: unrelate! removes from both directions (regression)"
(begin (host/blog-unrelate! "h7a" "h7b" "h7k")
(list (host/blog--out-raw "h7a" "h7k") (host/blog-in "h7b" "h7k")))
(list (list) (list)))
(host-bl-test "H7: re-relate after remove works (add/del/add folds correctly)"
(begin (host/blog-relate! "h7a" "h7b" "h7k")
(host/blog--out-raw "h7a" "h7k"))
(list "h7b"))
(define
host-bl-tests-run!
(fn ()