mirror of
https://github.com/weaveworks/scope.git
synced 2026-05-16 06:07:41 +00:00
The rendering code checks whether endpoint IPs are part of cluster-local networks. Due to the prevalence of endpoints - medium sized reports can contain many thousands of endpoints - this is performance critical. Alas the existing code performs the check via a linear scan of a list of networks. That is slow when there are more than a few, which will be the case in the context of k8s, since there the probes register service IPs as local /32 networks. Here we change representation of the set of networks to a prefix tree (aka trie), which is well-suited for IP network membership checks since networks are in fact a bitstring prefixes. The specific representation is a crit-bit tree, but that choice was purely based on implementation convenience - the chosen library is the only one I could find that directly supports IP networks.
58 lines
1.3 KiB
Go
58 lines
1.3 KiB
Go
package critbitgo
|
|
|
|
import (
|
|
"unsafe"
|
|
)
|
|
|
|
// The map is sorted according to the natural ordering of its keys
|
|
type SortedMap struct {
|
|
trie *Trie
|
|
}
|
|
|
|
func (m *SortedMap) Contains(key string) bool {
|
|
return m.trie.Contains(*(*[]byte)(unsafe.Pointer(&key)))
|
|
}
|
|
|
|
func (m *SortedMap) Get(key string) (value interface{}, ok bool) {
|
|
return m.trie.Get(*(*[]byte)(unsafe.Pointer(&key)))
|
|
}
|
|
|
|
func (m *SortedMap) Set(key string, value interface{}) {
|
|
m.trie.Set([]byte(key), value)
|
|
}
|
|
|
|
func (m *SortedMap) Delete(key string) (value interface{}, ok bool) {
|
|
return m.trie.Delete(*(*[]byte)(unsafe.Pointer(&key)))
|
|
}
|
|
|
|
func (m *SortedMap) Clear() {
|
|
m.trie.Clear()
|
|
}
|
|
|
|
func (m *SortedMap) Size() int {
|
|
return m.trie.Size()
|
|
}
|
|
|
|
// Returns a slice of sorted keys
|
|
func (m *SortedMap) Keys() []string {
|
|
keys := make([]string, 0, m.Size())
|
|
m.trie.Allprefixed([]byte{}, func(k []byte, v interface{}) bool {
|
|
keys = append(keys, string(k))
|
|
return true
|
|
})
|
|
return keys
|
|
}
|
|
|
|
// Executes a provided function for each element that has a given prefix.
|
|
// if handle returns `false`, the iteration is aborted.
|
|
func (m *SortedMap) Each(prefix string, handle func(key string, value interface{}) bool) bool {
|
|
return m.trie.Allprefixed([]byte(prefix), func(k []byte, v interface{}) bool {
|
|
return handle(string(k), v)
|
|
})
|
|
}
|
|
|
|
// Create a SortedMap
|
|
func NewSortedMap() *SortedMap {
|
|
return &SortedMap{NewTrie()}
|
|
}
|