package layoutgraph

// connectedOwners stores the usual single parent without a slice allocation.
// Additional runtime ownership views are retained, rather than assuming that
// Node.Container fully describes graph-owned container/cluster membership.
type connectedOwners struct {
	first map[*Node]*Node
	more  map[*Node][]*Node
}

func ( *connectedOwners) (,  *Node) {
	if .first[] == nil {
		.first[] = 
		return
	}
	if .more == nil {
		.more = make(map[*Node][]*Node)
	}
	.more[] = append(.more[], )
}

// ConnectedNodeSet returns the same reachable set as ConnectedNodes, with no
// traversal-order guarantee. Use it only when all members are treated equally;
// order-sensitive nearest-node tie breaking must continue using ConnectedNodes.
func ( *Node) ( []*Node,  *Graph) []*Node {
	// Tiny graphs and flat graphs have too little ownership scanning to amortize
	// an index. Keep their existing traversal.
	if len(.Nodes) < 32 || len(.Clusters) == 0 && len(.Containers) <= 1 {
		return .connectedNodes(, )
	}
	 := make(map[*Node]bool, len())
	for ,  := range  {
		[] = true
	}
	 := make(map[*Node]bool)
	 := connectedOwners{first: make(map[*Node]*Node)}
	for ,  := range .Containers {
		if  == nil {
			continue
		}
		 := false
		for ,  := range  {
			if [] {
				 = true
				break
			}
		}
		[] = 
		if  || [] {
			continue
		}
		for ,  := range  {
			.add(, )
		}
	}
	for ,  := range .Clusters {
		for ,  := range .Nodes {
			if !.isContainer || [] {
				continue
			}
			for ,  := range .Containers[] {
				.add(, )
			}
		}
	}
	 := make([]*Node, 0)
	 := []*Node{}
	 := map[*Node]bool{: true}
	 := func( *Node) {
		if ![] {
			[] = true
			 = append(, )
		}
	}
	for  := 0;  < len(); ++ {
		 := []
		 := false
		for ,  := range  {
			if .isDescendantOf() || .isDescendantOf() && !.isDescendantOf() {
				 = true
				break
			}
		}
		if  {
			continue
		}
		 = append(, )
		for ,  := range .Edges {
			 := .adjacent()
			if ![] {
				()
			}
		}
		if .isClusterVessel {
			for ,  := range .Clusters[].Nodes {
				if .isContainer {
					for ,  := range .Containers[] {
						()
					}
				}
			}
		}
		if  := .first[];  != nil {
			()
		}
		for ,  := range .more[] {
			()
		}
		if  != nil && ![] && ![] {
			for ,  := range .Containers[] {
				()
			}
		}
	}
	return 
}