This is the heart of tracing collection - starting from a root, you follow references to find every object you can reach. Today you build that traversal and return the exact reachable set.
Compute the set of all objects reachable from a single root by following references.
Reachability is the definition of liveness a tracing collector uses: an object is
live if and only if there is a path to it from some root by following references.
Reachable computes that set directly - start at each root, follow Children, and
keep going, marking each object seen the first time you arrive so you never
process it twice. The seen set is both the answer and the guard against revisiting.
Depth-first or breadth-first does not matter for the set you end up with; both reach
exactly the same objects. What matters is that you follow every edge and stop at
objects already seen. The chain r to c to g pulls all three into the set, while u
// depth-first (or breadth-first) trace from the roots, following Childrenfunc (h *Heap) Reachable() map[Ref]bool {seen := map[Ref]bool{}var visit func(Ref)visit = func(r Ref) {if seen[r] { return } // already counted; avoids revisitingseen[r] = truefor _, c := range h.Children(r) { visit(c) }}for _, root := range h.Roots() { visit(root) }return seen}