mirror of
https://github.com/ClusterCockpit/cc-metric-store.git
synced 2024-11-10 05:07:25 +01:00
118 lines
2.0 KiB
Go
118 lines
2.0 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
)
|
|
|
|
type SelectorElement struct {
|
|
Any bool
|
|
String string
|
|
Group []string
|
|
}
|
|
|
|
func (se *SelectorElement) UnmarshalJSON(input []byte) error {
|
|
if input[0] == '"' {
|
|
if err := json.Unmarshal(input, &se.String); err != nil {
|
|
return err
|
|
}
|
|
|
|
if se.String == "*" {
|
|
se.Any = true
|
|
se.String = ""
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
if input[0] == '[' {
|
|
return json.Unmarshal(input, &se.Group)
|
|
}
|
|
|
|
return errors.New("the Go SelectorElement type can only be a string or an array of strings")
|
|
}
|
|
|
|
func (se *SelectorElement) MarshalJSON() ([]byte, error) {
|
|
if se.Any {
|
|
return []byte("\"*\""), nil
|
|
}
|
|
|
|
if se.String != "" {
|
|
return json.Marshal(se.String)
|
|
}
|
|
|
|
if se.Group != nil {
|
|
return json.Marshal(se.Group)
|
|
}
|
|
|
|
return nil, errors.New("a Go Selector must be a non-empty string or a non-empty slice of strings")
|
|
}
|
|
|
|
type Selector []SelectorElement
|
|
|
|
func (l *level) findBuffers(selector Selector, offset int, f func(b *buffer) error) error {
|
|
l.lock.RLock()
|
|
defer l.lock.RUnlock()
|
|
|
|
if len(selector) == 0 {
|
|
if offset == -1 {
|
|
for _, b := range l.metrics {
|
|
if b != nil {
|
|
err := f(b)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
b := l.metrics[offset]
|
|
if b != nil {
|
|
return f(b)
|
|
}
|
|
}
|
|
|
|
for _, lvl := range l.children {
|
|
err := lvl.findBuffers(nil, offset, f)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
sel := selector[0]
|
|
if len(sel.String) != 0 && l.children != nil {
|
|
lvl, ok := l.children[sel.String]
|
|
if ok {
|
|
err := lvl.findBuffers(selector[1:], offset, f)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
if sel.Group != nil && l.children != nil {
|
|
for _, key := range sel.Group {
|
|
lvl, ok := l.children[key]
|
|
if ok {
|
|
err := lvl.findBuffers(selector[1:], offset, f)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
if sel.Any && l.children != nil {
|
|
for _, lvl := range l.children {
|
|
if err := lvl.findBuffers(selector[1:], offset, f); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
|
|
panic("impossible")
|
|
}
|