Skip to content

symfonic.memory.backends.in_memory_deletion

in_memory_deletion

Atomic in-process deletion of a scope, its edges, and workset progress.

delete_subtree

delete_subtree(store: Any, scope: TenantScope) -> int

Erase every node at scope or below it, with its edges.

Atomic by construction: the whole sweep runs in one synchronous span with no await in it, so no concurrent write on this loop can land in a scope between its discovery and its deletion.

Source code in src/symfonic/memory/backends/in_memory_deletion.py
def delete_subtree(store: Any, scope: TenantScope) -> int:
    """Erase every node at ``scope`` or below it, with its edges.

    Atomic by construction: the whole sweep runs in one synchronous span
    with no ``await`` in it, so no concurrent write on this loop can land
    in a scope between its discovery and its deletion.
    """
    root = materialise_scope_path(scope)
    tenant_nodes = store._nodes.get(scope.tenant_id, {})
    doomed = [
        node_id
        for node_id, node in tenant_nodes.items()
        if is_in_subtree(stored_scope_path(node.properties, node.tenant_id), root)
    ]
    tenant_edges = store._edges.get(scope.tenant_id, {})
    doomed_set = set(doomed)
    for edge_id in [
        eid
        for eid, edge in tenant_edges.items()
        if str(edge.source) in doomed_set or str(edge.target) in doomed_set
    ]:
        del tenant_edges[edge_id]
    for node_id in doomed:
        del tenant_nodes[node_id]
    for key in tuple(store._workset_cursors):
        if is_in_subtree(key[0], root):
            del store._workset_cursors[key]
    return len(doomed)