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