This commit is contained in:
John Lancaster
2026-02-20 23:07:15 -06:00
parent 56763014c1
commit 9d1a0e50e6
2 changed files with 13 additions and 13 deletions

View File

@@ -4,12 +4,12 @@ from collections import defaultdict
from collections.abc import Iterable, Iterator, MutableMapping, MutableSet from collections.abc import Iterable, Iterator, MutableMapping, MutableSet
from typing import DefaultDict, Generic, Set, TypeVar from typing import DefaultDict, Generic, Set, TypeVar
from .set import _AdjView from .set import DAGSet
T = TypeVar("T") T = TypeVar("T")
class DagAdj(Generic[T], MutableMapping[T, MutableSet[T]]): class DAG(Generic[T], MutableMapping[T, MutableSet[T]]):
""" """
DAG adjacency map: DAG adjacency map:
- g[u] -> mutable set-like view of successors of u - g[u] -> mutable set-like view of successors of u
@@ -28,10 +28,10 @@ class DagAdj(Generic[T], MutableMapping[T, MutableSet[T]]):
def __getitem__(self, u: T) -> MutableSet[T]: def __getitem__(self, u: T) -> MutableSet[T]:
# defaultdict semantics: touch key # defaultdict semantics: touch key
_ = self._succ[u] _ = self._succ[u]
return _AdjView(self, u) return DAGSet(self, u)
def __setitem__(self, u: T, vs: Iterable[T]) -> None: def __setitem__(self, u: T, vs: Iterable[T]) -> None:
view = _AdjView(self, u) view = DAGSet(self, u)
view.clear() view.clear()
view |= vs # uses our in-place operator view |= vs # uses our in-place operator

View File

@@ -4,15 +4,15 @@ from collections.abc import Iterable, Iterator, MutableSet, Set
from typing import TYPE_CHECKING, TypeVar from typing import TYPE_CHECKING, TypeVar
if TYPE_CHECKING: if TYPE_CHECKING:
from .dag import DagAdj from .dag import DAG
T = TypeVar("T") T = TypeVar("T")
class _AdjView(MutableSet[T]): class DAGSet(MutableSet[T]):
""" """
A mutable set-like view onto DagAdj._succ[u], with reverse-index maintenance. A mutable set-like view onto DAG._succ[u], with reverse-index maintenance.
Supports all set update operators: Supports all set update operators:
- |= (union_update) - |= (union_update)
@@ -24,7 +24,7 @@ class _AdjView(MutableSet[T]):
__slots__ = ("_g", "_u") __slots__ = ("_g", "_u")
def __init__(self, g: DagAdj[T], u: T) -> None: def __init__(self, g: DAG[T], u: T) -> None:
self._g = g self._g = g
self._u = u self._u = u
@@ -63,12 +63,12 @@ class _AdjView(MutableSet[T]):
# --- in-place operator support --- # --- in-place operator support ---
def __ior__(self, other: Iterable[T]) -> _AdjView[T]: def __ior__(self, other: Iterable[T]) -> DAGSet[T]:
# a |= b => add everything in other # a |= b => add everything in other
self.update(other) self.update(other)
return self return self
def __iand__(self, other: Iterable[T]) -> _AdjView[T]: def __iand__(self, other: Iterable[T]) -> DAGSet[T]:
# a &= b => keep only those also in other # a &= b => keep only those also in other
other_set = set(other) other_set = set(other)
for v in list(self._raw()): for v in list(self._raw()):
@@ -76,13 +76,13 @@ class _AdjView(MutableSet[T]):
self._g.remove_edge(self._u, v, missing_ok=True) self._g.remove_edge(self._u, v, missing_ok=True)
return self return self
def __isub__(self, other: Iterable[T]) -> _AdjView[T]: def __isub__(self, other: Iterable[T]) -> DAGSet[T]:
# a -= b => remove those in other # a -= b => remove those in other
for v in other: for v in other:
self._g.remove_edge(self._u, v, missing_ok=True) self._g.remove_edge(self._u, v, missing_ok=True)
return self return self
def __ixor__(self, other: Iterable[T]) -> _AdjView[T]: def __ixor__(self, other: Iterable[T]) -> DAGSet[T]:
# a ^= b => symmetric difference update # a ^= b => symmetric difference update
other_set = set(other) other_set = set(other)
raw = self._raw() raw = self._raw()
@@ -95,7 +95,7 @@ class _AdjView(MutableSet[T]):
self._g.add_edge(self._u, v) self._g.add_edge(self._u, v)
return self return self
def __iadd__(self, other: Iterable[T]) -> _AdjView[T]: def __iadd__(self, other: Iterable[T]) -> DAGSet[T]:
""" """
Built-in set doesn't define +=, but many folks expect it. Built-in set doesn't define +=, but many folks expect it.
Treat it as 'update' (extend). Treat it as 'update' (extend).