mirror of
https://github.com/ClusterCockpit/cc-metric-store.git
synced 2024-09-19 23:27:24 +02:00
156 lines
4.1 KiB
Go
156 lines
4.1 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"log"
|
|
)
|
|
|
|
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) findLevel(selector []string) *level {
|
|
if len(selector) == 0 {
|
|
return l
|
|
}
|
|
|
|
l.lock.RLock()
|
|
defer l.lock.RUnlock()
|
|
|
|
lvl := l.children[selector[0]]
|
|
if lvl == nil {
|
|
return nil
|
|
}
|
|
|
|
return lvl.findLevel(selector[1:])
|
|
}
|
|
|
|
func (l *level) findBuffers(selector Selector, offset int, f func(b *buffer) error) error {
|
|
l.lock.RLock()
|
|
defer l.lock.RUnlock()
|
|
|
|
log.Printf(">>>> HELLO FINDBUFFERS <<<<")
|
|
log.Printf(">>>> FINDBUFFERS : FOR SELECTOR >>>> %v", selector)
|
|
// log.Printf(">>>> FINDBUFFERS : FOR OFFSET >>>> %d", offset)
|
|
|
|
if len(selector) == 0 {
|
|
b := l.metrics[offset]
|
|
if b != nil {
|
|
log.Printf(">>>> FINDBUFFERS : SELECTOR ARRAY EMPTY >>>> FOUND BUFFER AT METRICS OFFSET %d", offset)
|
|
log.Printf(">>>> FINDBUFFERS : END RECURSIVE FINDBUFFERS >>>> RETURN BUFFER")
|
|
return f(b)
|
|
}
|
|
|
|
for _, lvl := range l.children {
|
|
log.Printf(">>>> FINDBUFFERS : SELECTOR ARRAY EMPTY >>>> ITERATING LEVEL >>>> %v", lvl)
|
|
err := lvl.findBuffers(nil, offset, f)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
log.Printf(">>>> FINDBUFFERS : SELECTOR ARRAY EMPTY >>>> NO BUFFER MATCHED")
|
|
log.Printf(">>>> FINDBUFFERS : END RECURSIVE FINDBUFFERS >>>> RETURN NIL")
|
|
return nil
|
|
}
|
|
|
|
sel := selector[0]
|
|
|
|
log.Printf(">>>> FINDBUFFERS : LEVEL CHILDREN >>>> NOT NIL : %v", (l.children != nil))
|
|
// log.Printf(">>>> FINDBUFFERS : SELECTOR ELEMENT @ INDEX 0 >>>> %v", sel)
|
|
|
|
log.Printf(">>>> FINDBUFFERS : SELECTOR ELEMENT >>>> STRING : %s", sel.String)
|
|
if len(sel.String) != 0 && l.children != nil {
|
|
// log.Printf(">>>> FINDBUFFERS : NAMED SELECTOR && CHILDREN AVAILABLE")
|
|
lvl, ok := l.children[sel.String]
|
|
if ok {
|
|
log.Printf(">>>> FINDBUFFERS : NAMED >>>> LOOKUP CHILDREN")
|
|
log.Printf(">>>> FINDBUFFERS : NAMED >>>> DO RECURSIVE FINDBUFFERS")
|
|
err := lvl.findBuffers(selector[1:], offset, f)
|
|
if err != nil {
|
|
log.Printf(">>>> FINDBUFFERS : NAMED >>>> RECURSIVE ERROR >>>> $s", err)
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
log.Printf(">>>> FINDBUFFERS : SELECTOR ELEMENT >>>> GROUP : %v", sel.Group)
|
|
if sel.Group != nil && l.children != nil {
|
|
// log.Printf(">>>> FINDBUFFERS : GROUP && CHILDREN AVAILABLE")
|
|
for _, key := range sel.Group {
|
|
lvl, ok := l.children[key]
|
|
if ok {
|
|
log.Printf(">>>> FINDBUFFERS : GROUP >>>> LOOKUP CHILDREN FOR GROUPKEY >>>> %s", key)
|
|
log.Printf(">>>> FINDBUFFERS : GROUP >>>> DO RECURSIVE FINDBUFFERS")
|
|
err := lvl.findBuffers(selector[1:], offset, f)
|
|
if err != nil {
|
|
log.Printf(">>>> FINDBUFFERS : GROUP >>>> RECURSIVE ERROR >>>> $s", err)
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
log.Printf(">>>> FINDBUFFERS : GROUP >>>> RETURN NIL")
|
|
return nil
|
|
}
|
|
|
|
log.Printf(">>>> FINDBUFFERS : SELECTOR ELEMENT >>>> IS ANY : %v", sel.Any)
|
|
if sel.Any && l.children != nil {
|
|
// log.Printf(">>>> FINDBUFFERS : ENABLED ANY && CHILDREN AVAILABLE")
|
|
for _, lvl := range l.children {
|
|
log.Printf(">>>> FINDBUFFERS : ANY >>>> DO RECURSIVE FINDBUFFERS")
|
|
if err := lvl.findBuffers(selector[1:], offset, f); err != nil {
|
|
log.Printf(">>>> FINDBUFFERS : ANY >>>> RECURSIVE ERROR >>>> $s", err)
|
|
return err
|
|
}
|
|
}
|
|
log.Printf(">>>> FINDBUFFERS : ANY >>>> RETURN NIL")
|
|
return nil
|
|
}
|
|
|
|
log.Printf(">>>> FINDBUFFERS : NO MATCHED CASE >>>> RETURN NIL")
|
|
return nil
|
|
}
|