skeletons: early conversion of seq[Value] to Value

This commit is contained in:
Emery Hemingway 2024-02-24 16:54:46 +00:00
parent 9f59bb1e94
commit f54d9ae402
1 changed files with 17 additions and 17 deletions

View File

@ -45,8 +45,8 @@ type
AssertionCache = HashSet[Value] AssertionCache = HashSet[Value]
ObserverGroup = ref object # Endpoints ObserverGroup = ref object # Endpoints
cachedCaptures: Bag[Captures] cachedCaptures: Bag[Value]
observers: Table[Cap, TableRef[Captures, Handle]] observers: Table[Cap, TableRef[Value, Handle]]
Leaf = ref object Leaf = ref object
cache: AssertionCache cache: AssertionCache
@ -67,7 +67,7 @@ func isEmpty(cont: Continuation): bool =
type type
ContinuationProc = proc (c: Continuation; v: Value) {.closure.} ContinuationProc = proc (c: Continuation; v: Value) {.closure.}
LeafProc = proc (l: Leaf; v: Value) {.closure.} LeafProc = proc (l: Leaf; v: Value) {.closure.}
ObserverProc = proc (group: ObserverGroup; vs: seq[Value]) {.closure.} ObserverProc = proc (group: ObserverGroup; vs: Value) {.closure.}
proc getLeaves(cont: Continuation; constPaths: Paths): LeafMap = proc getLeaves(cont: Continuation; constPaths: Paths): LeafMap =
result = cont.leafMap.getOrDefault(constPaths) result = cont.leafMap.getOrDefault(constPaths)
@ -76,7 +76,7 @@ proc getLeaves(cont: Continuation; constPaths: Paths): LeafMap =
cont.leafMap[constPaths] = result cont.leafMap[constPaths] = result
assert not cont.isEmpty assert not cont.isEmpty
for ass in cont.cache: for ass in cont.cache:
let key = projectPaths(ass, constPaths) var key = projectPaths(ass, constPaths)
if key.isSome: if key.isSome:
var leaf = result.getOrDefault(get key) var leaf = result.getOrDefault(get key)
if leaf.isNil: if leaf.isNil:
@ -120,24 +120,24 @@ proc modify(node: Node; outerValue: Value; event: EventKind;
proc walk(cont: Continuation) = proc walk(cont: Continuation) =
modCont(cont, outerValue) modCont(cont, outerValue)
for constPaths, constValMap in cont.leafMap.pairs: for constPaths, constValMap in cont.leafMap.pairs:
let constVals = projectPaths(outerValue, constPaths) var constVals = projectPaths(outerValue, constPaths)
if constVals.isSome: if constVals.isSome:
case event case event
of addedEvent, messageEvent: of addedEvent, messageEvent:
let leaf = constValMap.getLeaf(get constVals) let leaf = constValMap.getLeaf(get constVals)
modLeaf(leaf, outerValue) modLeaf(leaf, outerValue)
for capturePaths, observerGroup in leaf.observerGroups.pairs: for capturePaths, observerGroup in leaf.observerGroups.pairs:
let captures = projectPaths(outerValue, capturePaths) var captures = projectPaths(outerValue, capturePaths)
if captures.isSome: if captures.isSome:
modObs(observerGroup, get captures) modObs(observerGroup, captures.get.toPreserves)
of removedEvent: of removedEvent:
let leaf = constValMap.getOrDefault(get constVals) let leaf = constValMap.getOrDefault(get constVals)
if not leaf.isNil: if not leaf.isNil:
modLeaf(leaf, outerValue) modLeaf(leaf, outerValue)
for capturePaths, observerGroup in leaf.observerGroups.pairs: for capturePaths, observerGroup in leaf.observerGroups.pairs:
let captures = projectPaths(outerValue, capturePaths) var captures = projectPaths(outerValue, capturePaths)
if captures.isSome: if captures.isSome:
modObs(observerGroup, get captures) modObs(observerGroup, captures.get.toPreserves)
if leaf.isEmpty: if leaf.isEmpty:
constValMap.del(get constVals) constValMap.del(get constVals)
@ -223,9 +223,9 @@ proc getEndpoints(leaf: Leaf; capturePaths: Paths): ObserverGroup =
leaf.observerGroups[capturePaths] = result leaf.observerGroups[capturePaths] = result
for term in leaf.cache: for term in leaf.cache:
# leaf.cache would be empty if observers come before assertions # leaf.cache would be empty if observers come before assertions
let captures = projectPaths(term, capturePaths) var captures = projectPaths(term, capturePaths)
if captures.isSome: if captures.isSome:
discard result.cachedCaptures.change(get captures, +1) discard result.cachedCaptures.change(captures.get.toPreserves, +1)
proc add*(index: var Index; pattern: Pattern; observer: Cap) = proc add*(index: var Index; pattern: Pattern; observer: Cap) =
let let
@ -235,7 +235,7 @@ proc add*(index: var Index; pattern: Pattern; observer: Cap) =
leaf = constValMap.getLeaf(analysis.constValues) leaf = constValMap.getLeaf(analysis.constValues)
endpoints = leaf.getEndpoints(analysis.capturePaths) endpoints = leaf.getEndpoints(analysis.capturePaths)
# TODO if endpoints.cachedCaptures.len > 0: # TODO if endpoints.cachedCaptures.len > 0:
var captureMap = newTable[seq[Value], Handle]() var captureMap = newTable[Value, Handle]()
for capture in endpoints.cachedCaptures.items: for capture in endpoints.cachedCaptures.items:
captureMap[capture] = publish(observer, capture.toPreserves) captureMap[capture] = publish(observer, capture.toPreserves)
endpoints.observers[observer] = captureMap endpoints.observers[observer] = captureMap
@ -250,7 +250,7 @@ proc remove*(index: var Index; pattern: Pattern; observer: Cap) =
if not leaf.isNil: if not leaf.isNil:
let endpoints = leaf.observerGroups.getOrDefault(analysis.capturePaths) let endpoints = leaf.observerGroups.getOrDefault(analysis.capturePaths)
if not endpoints.isNil: if not endpoints.isNil:
var captureMap: TableRef[seq[Value], Handle] var captureMap: TableRef[Value, Handle]
if endpoints.observers.pop(observer, captureMap): if endpoints.observers.pop(observer, captureMap):
for handle in captureMap.values: retract(observer, handle) for handle in captureMap.values: retract(observer, handle)
if endpoints.observers.len == 0: if endpoints.observers.len == 0:
@ -268,7 +268,7 @@ proc adjustAssertion(index: var Index; outerValue: Value; delta: int): bool =
c.cache.incl(v) c.cache.incl(v)
proc modLeaf(l: Leaf; v: Value) = proc modLeaf(l: Leaf; v: Value) =
l.cache.incl(v) l.cache.incl(v)
proc modObserver(group: ObserverGroup; vs: seq[Value]) = proc modObserver(group: ObserverGroup; vs: Value) =
let change = group.cachedCaptures.change(vs, +1) let change = group.cachedCaptures.change(vs, +1)
if change == cdAbsentToPresent: if change == cdAbsentToPresent:
for (observer, captureMap) in group.observers.pairs: for (observer, captureMap) in group.observers.pairs:
@ -281,7 +281,7 @@ proc adjustAssertion(index: var Index; outerValue: Value; delta: int): bool =
c.cache.excl(v) c.cache.excl(v)
proc modLeaf(l: Leaf; v: Value) = proc modLeaf(l: Leaf; v: Value) =
l.cache.excl(v) l.cache.excl(v)
proc modObserver(group: ObserverGroup; vs: seq[Value]) = proc modObserver(group: ObserverGroup; vs: Value) =
if group.cachedCaptures.change(vs, -1) == cdPresentToAbsent: if group.cachedCaptures.change(vs, -1) == cdPresentToAbsent:
for (observer, captureMap) in group.observers.pairs: for (observer, captureMap) in group.observers.pairs:
var h: Handle var h: Handle
@ -299,6 +299,6 @@ proc remove*(index: var Index; v: Value): bool =
adjustAssertion(index, v, -1) adjustAssertion(index, v, -1)
proc deliverMessage*(index: var Index; v: Value) = proc deliverMessage*(index: var Index; v: Value) =
proc observersCb(group: ObserverGroup; vs: seq[Value]) = proc observersCb(group: ObserverGroup; vs: Value) =
for observer in group.observers.keys: message(observer, vs.toPreserves) for observer in group.observers.keys: message(observer, vs)
index.root.modify(v, messageEvent, continuationNoop, leafNoop, observersCb) index.root.modify(v, messageEvent, continuationNoop, leafNoop, observersCb)