You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tea/selection.go

74 lines
1.9 KiB
Go

package tea
func NewSelection(test Test) Selection {
node := newLNode(test, Selection{})
return Selection{nodes: []*lnode{node}}
}
// Selection represents a set of nodes in our graph.
type Selection struct {
nodes []*lnode
}
func (s Selection) Child(test Test) Selection {
node := newLNode(test, s)
return Selection{nodes: []*lnode{node}}
}
func (s Selection) And(other Selection) Selection {
included := make(map[int]bool)
out := make([]*lnode, 0, len(s.nodes)+len(other.nodes))
for _, n := range append(s.nodes, other.nodes...) {
if !included[n.id] {
out = append(out, n)
included[n.id] = true
}
}
return Selection{nodes: out}
}
// xnodes represents all xnodes in the selected lnodes
func (s Selection) xnodes() []*xnode {
xnodes := make([]*xnode, 0, s.countXNodes())
for _, L := range s.nodes {
for i, _ := range L.xnodes {
xnodes = append(xnodes, &L.xnodes[i])
}
}
return xnodes
}
func (s Selection) countXNodes() int {
total := 0
for _, child := range s.nodes {
total += len(child.xnodes)
}
return total
}
// xleaves looks at all of the selected xnodes, and for every selected xnode,
// traverses the x graph until we arrive at the set of all leaf nodes that have
// a selected ancestor. If the selection consists of the root node, the xleaves
// are all of the leaves of the x graph.
func (s *Selection) xleaves() []*xnode {
// honestly think that by definition every xnode in the selection has a
// non-overlapping set of leaves but thinking about this shit is extremely
// starting to hurt my brain so I'm going to write this in a way that's
// maybe very redundant.
seen := make(map[string]bool)
var leaves []*xnode
for _, x := range s.xnodes() {
for _, leaf := range x.leaves() {
if seen[leaf.label()] {
panic("double-counting leaves somehow")
}
seen[leaf.label()] = true
leaves = append(leaves, leaf)
}
}
return leaves
}