mirror of
https://github.com/weaveworks/scope.git
synced 2026-03-02 17:50:39 +00:00
95 lines
2.3 KiB
Go
95 lines
2.3 KiB
Go
package report
|
|
|
|
import (
|
|
"sort"
|
|
)
|
|
|
|
// NodeSet is a sorted set of nodes keyed on (Topology, ID). Clients must use
|
|
// the Add method to add nodes
|
|
type NodeSet []Node
|
|
|
|
// MakeNodeSet makes a new NodeSet with the given nodes.
|
|
func MakeNodeSet(nodes ...Node) NodeSet {
|
|
if len(nodes) <= 0 {
|
|
return nil
|
|
}
|
|
result := make(NodeSet, len(nodes))
|
|
copy(result, nodes)
|
|
sort.Sort(result)
|
|
for i := 1; i < len(result); { // remove any duplicates
|
|
if result[i-1].Equal(result[i]) {
|
|
result = append(result[:i-1], result[i:]...)
|
|
continue
|
|
}
|
|
i++
|
|
}
|
|
return result
|
|
}
|
|
|
|
// Implementation of sort.Interface
|
|
func (n NodeSet) Len() int { return len(n) }
|
|
func (n NodeSet) Swap(i, j int) { n[i], n[j] = n[j], n[i] }
|
|
func (n NodeSet) Less(i, j int) bool { return n[i].Before(n[j]) }
|
|
|
|
// Add adds the nodes to the NodeSet. Add is the only valid way to grow a
|
|
// NodeSet. Add returns the NodeSet to enable chaining.
|
|
func (n NodeSet) Add(nodes ...Node) NodeSet {
|
|
for _, node := range nodes {
|
|
i := sort.Search(len(n), func(i int) bool {
|
|
return n[i].Topology >= node.Topology && n[i].ID >= node.ID
|
|
})
|
|
if i < len(n) && n[i].Topology == node.Topology && n[i].ID == node.ID {
|
|
// The list already has the element.
|
|
continue
|
|
}
|
|
// It a new element, insert it in order.
|
|
n = append(n, Node{})
|
|
copy(n[i+1:], n[i:])
|
|
n[i] = node
|
|
}
|
|
return n
|
|
}
|
|
|
|
// Merge combines the two NodeSets and returns a new result.
|
|
func (n NodeSet) Merge(other NodeSet) NodeSet {
|
|
switch {
|
|
case len(other) <= 0: // Optimise special case, to avoid allocating
|
|
return n // (note unit test DeepEquals breaks if we don't do this)
|
|
case len(n) <= 0:
|
|
return other
|
|
}
|
|
|
|
result := make([]Node, 0, len(n)+len(other))
|
|
for len(n) > 0 || len(other) > 0 {
|
|
switch {
|
|
case len(n) == 0:
|
|
return append(result, other...)
|
|
case len(other) == 0:
|
|
return append(result, n...)
|
|
case n[0].Before(other[0]):
|
|
result = append(result, n[0])
|
|
n = n[1:]
|
|
case n[0].After(other[0]):
|
|
result = append(result, other[0])
|
|
other = other[1:]
|
|
default: // equal
|
|
result = append(result, other[0])
|
|
n = n[1:]
|
|
other = other[1:]
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
// Copy returns a value copy of the NodeSet.
|
|
func (n NodeSet) Copy() NodeSet {
|
|
if n == nil {
|
|
return n
|
|
}
|
|
result := make(NodeSet, len(n))
|
|
for i, node := range n {
|
|
result[i] = node
|
|
}
|
|
return result
|
|
}
|