Adding upstream version 1.34.4.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
e393c3af3f
commit
4978089aab
4963 changed files with 677545 additions and 0 deletions
140
filter/filter.go
Normal file
140
filter/filter.go
Normal file
|
@ -0,0 +1,140 @@
|
|||
package filter
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/gobwas/glob"
|
||||
)
|
||||
|
||||
type Filter interface {
|
||||
Match(string) bool
|
||||
}
|
||||
|
||||
// Compile takes a list of string filters and returns a Filter interface
|
||||
// for matching a given string against the filter list. The filter list
|
||||
// supports glob matching with separators too, ie:
|
||||
//
|
||||
// f, _ := Compile([]string{"cpu", "mem", "net*"})
|
||||
// f.Match("cpu") // true
|
||||
// f.Match("network") // true
|
||||
// f.Match("memory") // false
|
||||
//
|
||||
// separators are only to be used for globbing filters, ie:
|
||||
//
|
||||
// f, _ := Compile([]string{"cpu.*.count"}, '.')
|
||||
// f.Match("cpu.count") // false
|
||||
// f.Match("cpu.measurement.count") // true
|
||||
// f.Match("cpu.field.measurement.count") // false
|
||||
//
|
||||
// Compile will return nil if the filter list is empty.
|
||||
func Compile(filters []string, separators ...rune) (Filter, error) {
|
||||
// return if there is nothing to compile
|
||||
if len(filters) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// check if we can compile a non-glob filter
|
||||
noGlob := len(separators) == 0
|
||||
for _, filter := range filters {
|
||||
if hasMeta(filter) {
|
||||
noGlob = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
switch {
|
||||
case noGlob:
|
||||
// return non-globbing filter if not needed.
|
||||
return compileFilterNoGlob(filters), nil
|
||||
case len(filters) == 1:
|
||||
return glob.Compile(filters[0], separators...)
|
||||
default:
|
||||
return glob.Compile("{"+strings.Join(filters, ",")+"}", separators...)
|
||||
}
|
||||
}
|
||||
|
||||
func MustCompile(filters []string, separators ...rune) Filter {
|
||||
f, err := Compile(filters, separators...)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
// hasMeta reports whether path contains any magic glob characters.
|
||||
func hasMeta(s string) bool {
|
||||
return strings.ContainsAny(s, "*?[")
|
||||
}
|
||||
|
||||
type filter struct {
|
||||
m map[string]struct{}
|
||||
}
|
||||
|
||||
func (f *filter) Match(s string) bool {
|
||||
_, ok := f.m[s]
|
||||
return ok
|
||||
}
|
||||
|
||||
type filtersingle struct {
|
||||
s string
|
||||
}
|
||||
|
||||
func (f *filtersingle) Match(s string) bool {
|
||||
return f.s == s
|
||||
}
|
||||
|
||||
func compileFilterNoGlob(filters []string) Filter {
|
||||
if len(filters) == 1 {
|
||||
return &filtersingle{s: filters[0]}
|
||||
}
|
||||
out := filter{m: make(map[string]struct{})}
|
||||
for _, filter := range filters {
|
||||
out.m[filter] = struct{}{}
|
||||
}
|
||||
return &out
|
||||
}
|
||||
|
||||
type IncludeExcludeFilter struct {
|
||||
include Filter
|
||||
exclude Filter
|
||||
includeDefault bool
|
||||
excludeDefault bool
|
||||
}
|
||||
|
||||
func NewIncludeExcludeFilter(include, exclude []string) (Filter, error) {
|
||||
return NewIncludeExcludeFilterDefaults(include, exclude, true, false)
|
||||
}
|
||||
|
||||
func NewIncludeExcludeFilterDefaults(include, exclude []string, includeDefault, excludeDefault bool) (Filter, error) {
|
||||
in, err := Compile(include)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ex, err := Compile(exclude)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &IncludeExcludeFilter{in, ex, includeDefault, excludeDefault}, nil
|
||||
}
|
||||
|
||||
func (f *IncludeExcludeFilter) Match(s string) bool {
|
||||
if f.include != nil {
|
||||
if !f.include.Match(s) {
|
||||
return false
|
||||
}
|
||||
} else if !f.includeDefault {
|
||||
return false
|
||||
}
|
||||
|
||||
if f.exclude != nil {
|
||||
if f.exclude.Match(s) {
|
||||
return false
|
||||
}
|
||||
} else if f.excludeDefault {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
132
filter/filter_test.go
Normal file
132
filter/filter_test.go
Normal file
|
@ -0,0 +1,132 @@
|
|||
package filter
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestCompile(t *testing.T) {
|
||||
f, err := Compile(nil)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, f)
|
||||
|
||||
f, err = Compile([]string{"cpu"})
|
||||
require.NoError(t, err)
|
||||
require.True(t, f.Match("cpu"))
|
||||
require.False(t, f.Match("cpu0"))
|
||||
require.False(t, f.Match("mem"))
|
||||
|
||||
f, err = Compile([]string{"cpu*"})
|
||||
require.NoError(t, err)
|
||||
require.True(t, f.Match("cpu"))
|
||||
require.True(t, f.Match("cpu0"))
|
||||
require.False(t, f.Match("mem"))
|
||||
|
||||
f, err = Compile([]string{"cpu", "mem"})
|
||||
require.NoError(t, err)
|
||||
require.True(t, f.Match("cpu"))
|
||||
require.False(t, f.Match("cpu0"))
|
||||
require.True(t, f.Match("mem"))
|
||||
|
||||
f, err = Compile([]string{"cpu", "mem", "net*"})
|
||||
require.NoError(t, err)
|
||||
require.True(t, f.Match("cpu"))
|
||||
require.False(t, f.Match("cpu0"))
|
||||
require.True(t, f.Match("mem"))
|
||||
require.True(t, f.Match("network"))
|
||||
|
||||
f, err = Compile([]string{"cpu.*.count"}, '.')
|
||||
require.NoError(t, err)
|
||||
require.False(t, f.Match("cpu.count"))
|
||||
require.True(t, f.Match("cpu.measurement.count"))
|
||||
require.False(t, f.Match("cpu.field.measurement.count"))
|
||||
|
||||
f, err = Compile([]string{"cpu.*.count"}, '.', ',')
|
||||
require.NoError(t, err)
|
||||
require.True(t, f.Match("cpu.measurement.count"))
|
||||
require.False(t, f.Match("cpu.,.count")) // ',' is not considered under * as it is specified as a separator
|
||||
require.False(t, f.Match("cpu.field,measurement.count"))
|
||||
}
|
||||
|
||||
func TestIncludeExclude(t *testing.T) {
|
||||
labels := []string{"best", "com_influxdata", "timeseries", "com_influxdata_telegraf", "ever"}
|
||||
tags := make([]string, 0, len(labels))
|
||||
|
||||
filter, err := NewIncludeExcludeFilter(nil, []string{"com_influx*"})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create include/exclude filter - %v", err)
|
||||
}
|
||||
|
||||
for i := range labels {
|
||||
if filter.Match(labels[i]) {
|
||||
tags = append(tags, labels[i])
|
||||
}
|
||||
}
|
||||
|
||||
require.Equal(t, []string{"best", "timeseries", "ever"}, tags)
|
||||
}
|
||||
|
||||
var benchbool bool
|
||||
|
||||
func BenchmarkFilterSingleNoGlobFalse(b *testing.B) {
|
||||
f, err := Compile([]string{"cpu"})
|
||||
require.NoError(b, err)
|
||||
var tmp bool
|
||||
for n := 0; n < b.N; n++ {
|
||||
tmp = f.Match("network")
|
||||
}
|
||||
benchbool = tmp
|
||||
}
|
||||
|
||||
func BenchmarkFilterSingleNoGlobTrue(b *testing.B) {
|
||||
f, err := Compile([]string{"cpu"})
|
||||
require.NoError(b, err)
|
||||
var tmp bool
|
||||
for n := 0; n < b.N; n++ {
|
||||
tmp = f.Match("cpu")
|
||||
}
|
||||
benchbool = tmp
|
||||
}
|
||||
|
||||
func BenchmarkFilter(b *testing.B) {
|
||||
f, err := Compile([]string{"cpu", "mem", "net*"})
|
||||
require.NoError(b, err)
|
||||
var tmp bool
|
||||
for n := 0; n < b.N; n++ {
|
||||
tmp = f.Match("network")
|
||||
}
|
||||
benchbool = tmp
|
||||
}
|
||||
|
||||
func BenchmarkFilterNoGlob(b *testing.B) {
|
||||
f, err := Compile([]string{"cpu", "mem", "net"})
|
||||
require.NoError(b, err)
|
||||
var tmp bool
|
||||
for n := 0; n < b.N; n++ {
|
||||
tmp = f.Match("net")
|
||||
}
|
||||
benchbool = tmp
|
||||
}
|
||||
|
||||
func BenchmarkFilter2(b *testing.B) {
|
||||
f, err := Compile([]string{"aa", "bb", "c", "ad", "ar", "at", "aq",
|
||||
"aw", "az", "axxx", "ab", "cpu", "mem", "net*"})
|
||||
require.NoError(b, err)
|
||||
var tmp bool
|
||||
for n := 0; n < b.N; n++ {
|
||||
tmp = f.Match("network")
|
||||
}
|
||||
benchbool = tmp
|
||||
}
|
||||
|
||||
func BenchmarkFilter2NoGlob(b *testing.B) {
|
||||
f, err := Compile([]string{"aa", "bb", "c", "ad", "ar", "at", "aq",
|
||||
"aw", "az", "axxx", "ab", "cpu", "mem", "net"})
|
||||
require.NoError(b, err)
|
||||
var tmp bool
|
||||
for n := 0; n < b.N; n++ {
|
||||
tmp = f.Match("net")
|
||||
}
|
||||
benchbool = tmp
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue