Fix lost handlers in skeleton index
This commit is contained in:
parent
274f0429de
commit
f695092ae8
|
@ -74,18 +74,20 @@ type
|
||||||
cachedCaptures: Bag[seq[Value]]
|
cachedCaptures: Bag[seq[Value]]
|
||||||
callbacks: HashSet[HandlerCallback]
|
callbacks: HashSet[HandlerCallback]
|
||||||
|
|
||||||
|
AssertionCache = HashSet[Value]
|
||||||
|
|
||||||
Leaf = ref object
|
Leaf = ref object
|
||||||
cachedAssertions: HashSet[Value]
|
cachedAssertions: AssertionCache
|
||||||
handlerMap: Table[seq[Path], Handler]
|
handlerMap: Table[seq[Path], Handler]
|
||||||
|
|
||||||
Continuation = ref object
|
Continuation = ref object
|
||||||
cachedAssertions: HashSet[Value]
|
cachedAssertions: AssertionCache
|
||||||
leafMap: Table[seq[Path], TableRef[seq[Value], Leaf]] # TODO: not TableRef?
|
leafMap: Table[seq[Path], TableRef[seq[Value], Leaf]] # TODO: not TableRef?
|
||||||
|
|
||||||
Selector = tuple[popCount: int; index: int]
|
Selector = tuple[popCount: int; index: int]
|
||||||
|
|
||||||
Node = ref object
|
Node = ref object
|
||||||
edges: Table[Selector, Table[string, Node]]
|
edges: Table[Selector, TableRef[string, Node]]
|
||||||
continuation: Continuation
|
continuation: Continuation
|
||||||
|
|
||||||
using
|
using
|
||||||
|
@ -162,37 +164,39 @@ proc modify(node; operation: EventKind; outerValue: Value;
|
||||||
stack.prepend(@[outerValue])
|
stack.prepend(@[outerValue])
|
||||||
walkNode(node, stack)
|
walkNode(node, stack)
|
||||||
|
|
||||||
proc extend*[Shape](node; skeleton: Skeleton[Shape]): Continuation =
|
proc extend[Shape](node; skeleton: Skeleton[Shape]): Continuation =
|
||||||
var path: Path
|
var path: Path
|
||||||
proc walkNode(node: Node; popCount, index: int; skeleton: Skeleton[Shape]): tuple[popCount: int, node: Node] =
|
|
||||||
|
proc walkNode(node; popCount, index: int; skeleton: Skeleton[Shape]): tuple[popCount: int, node: Node] =
|
||||||
assert(not node.isNil)
|
assert(not node.isNil)
|
||||||
if skeleton.isNone:
|
if skeleton.isNone:
|
||||||
return (popCount, node)
|
return (popCount, node)
|
||||||
else:
|
else:
|
||||||
|
let selector: Selector = (popCount, index)
|
||||||
var
|
var
|
||||||
cls = skeleton.get.shape
|
cls = skeleton.get.shape
|
||||||
table: Table[string, Node]
|
var
|
||||||
nextNode: Node
|
table = node.edges.getOrDefault(selector)
|
||||||
discard node.edges.pop((popCount, index), table)
|
if table.isNil:
|
||||||
if not table.pop(cls, nextNode):
|
table = newTable[string, Node]()
|
||||||
|
node.edges[selector] = table
|
||||||
|
var nextNode = table.getOrDefault(cls)
|
||||||
|
if nextNode.isNil:
|
||||||
nextNode = Node(continuation: Continuation())
|
nextNode = Node(continuation: Continuation())
|
||||||
|
table[cls] = nextNode
|
||||||
for a in node.continuation.cachedAssertions:
|
for a in node.continuation.cachedAssertions:
|
||||||
if $classOf(projectPath(a, path)) == cls:
|
if $classOf(projectPath(a, path)) == cls:
|
||||||
nextNode.continuation.cachedAssertions.incl(a)
|
nextNode.continuation.cachedAssertions.incl(a)
|
||||||
block:
|
block:
|
||||||
var
|
var popCount, index: int
|
||||||
popCount = 0
|
|
||||||
index = 0
|
|
||||||
path.add(index)
|
path.add(index)
|
||||||
for member in skeleton.get.members:
|
for member in skeleton.get.members:
|
||||||
(popCount, nextNode) = walkNode(nextNode, popCount, index, member)
|
(popCount, nextNode) = walkNode(nextNode, result.popCount, index, member)
|
||||||
inc(index)
|
inc(index)
|
||||||
discard path.pop()
|
discard path.pop()
|
||||||
path.add(index)
|
path.add(index)
|
||||||
discard path.pop()
|
discard path.pop()
|
||||||
result = (popCount.succ, nextNode)
|
result = (popCount.succ, nextNode)
|
||||||
table[cls] = nextNode
|
|
||||||
node.edges[(popCount, index)] = table
|
|
||||||
walkNode(node, 0, 0, skeleton).node.continuation
|
walkNode(node, 0, 0, skeleton).node.continuation
|
||||||
|
|
||||||
type
|
type
|
||||||
|
@ -216,17 +220,17 @@ proc addHandler*(index; res: Analysis; callback: HandlerCallback) =
|
||||||
constVals = res.constVals
|
constVals = res.constVals
|
||||||
capturePaths = res.capturePaths
|
capturePaths = res.capturePaths
|
||||||
continuation = index.root.extend(res.skeleton)
|
continuation = index.root.extend(res.skeleton)
|
||||||
assert(not continuation.isNil)
|
|
||||||
var constValMap = continuation.leafMap.getOrDefault(constPaths)
|
var constValMap = continuation.leafMap.getOrDefault(constPaths)
|
||||||
if constValMap.isNil:
|
if constValMap.isNil:
|
||||||
constValMap = newTable[seq[Value], Leaf]()
|
constValMap = newTable[seq[Value], Leaf]()
|
||||||
for a in continuation.cachedAssertions:
|
|
||||||
var leaf: Leaf
|
|
||||||
if not constValMap.pop(a.sequence, leaf):
|
|
||||||
new leaf
|
|
||||||
leaf.cachedAssertions.incl(a)
|
|
||||||
constValMap[a.sequence] = leaf
|
|
||||||
continuation.leafMap[constPaths] = constValMap
|
continuation.leafMap[constPaths] = constValMap
|
||||||
|
for a in continuation.cachedAssertions:
|
||||||
|
let key = projectPaths(a, constPaths)
|
||||||
|
var leaf = constValMap.getOrDefault(key)
|
||||||
|
if leaf.isNil:
|
||||||
|
new leaf
|
||||||
|
constValMap[key] = leaf
|
||||||
|
leaf.cachedAssertions.incl(a)
|
||||||
var leaf = constValMap.getOrDefault(constVals)
|
var leaf = constValMap.getOrDefault(constVals)
|
||||||
if leaf.isNil:
|
if leaf.isNil:
|
||||||
new leaf
|
new leaf
|
||||||
|
@ -234,11 +238,11 @@ proc addHandler*(index; res: Analysis; callback: HandlerCallback) =
|
||||||
var handler = leaf.handlerMap.getOrDefault(capturePaths)
|
var handler = leaf.handlerMap.getOrDefault(capturePaths)
|
||||||
if handler.isNil:
|
if handler.isNil:
|
||||||
new handler
|
new handler
|
||||||
|
leaf.handlerMap[capturePaths] = handler
|
||||||
for a in leaf.cachedAssertions:
|
for a in leaf.cachedAssertions:
|
||||||
let a = projectPaths(a, capturePaths)
|
let a = projectPaths(a, capturePaths)
|
||||||
if handler.cachedCaptures.contains(a):
|
if handler.cachedCaptures.contains(a):
|
||||||
discard handler.cachedCaptures.change(a, +1)
|
discard handler.cachedCaptures.change(a, +1)
|
||||||
leaf.handlerMap[capturePaths] = handler
|
|
||||||
handler.callbacks.incl(callback)
|
handler.callbacks.incl(callback)
|
||||||
for captures, count in handler.cachedCaptures.pairs:
|
for captures, count in handler.cachedCaptures.pairs:
|
||||||
callback(addedEvent, captures)
|
callback(addedEvent, captures)
|
||||||
|
|
Loading…
Reference in New Issue