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]
|
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)
|
||||||
|
|
Loading…
Reference in New Issue