cc-metric-store/selector.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
}