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