Last active
February 12, 2024 05:15
-
-
Save jridgewell/ef8a674291f8f7419a2bea0448c3b0eb to your computer and use it in GitHub Desktop.
Flatten unobservable AsyncContext.Variable values from all living snapshot chains
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Flattens all "snapshots", removing unobservable nodes so they may free their | |
* values. | |
* | |
* "snapshots" here is all Snapshot instances, every created | |
* Generator/AsyncGenerator, every stored Job, etc. | |
*/ | |
function flatten(snapshots: Snapshot[]) { | |
const current = new Map<Variable>(); | |
const maybe = new Map<LinkNode, LinkNode>(); | |
const seen = new Set<LinkNode>(); | |
for (const snapshot of snapshots) { | |
let c = snapshot.[[AsyncContextLinkNode]]; | |
let parent; | |
while (c) { | |
// If we've already seen this variable in this linked-list chain, then it's an unobservable | |
const variable = c.[[AsyncContextVariable]]; | |
if (current.has(variable)) { | |
if (!seen.has(c)) { | |
maybe.set(c, parent); | |
} | |
} else { | |
maybe.delete(c); | |
} | |
seen.add(c); | |
current.add(variable); | |
parent = c; | |
c = c.[[AsyncContextLinkNode]]; | |
} | |
current.clear(); | |
} | |
// Anything still in maybe is unreachable across all snapshots. | |
for (const [node, parent] of maybe) { | |
parent.[[AsyncContextLinkNode]] = node.[[AsyncContextLinkNode]]; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment