skeletons: early conversion of seq[Value] to Value
This commit is contained in:
parent
9f59bb1e94
commit
f54d9ae402
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue