mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2025-01-20 07:19:17 +01:00
lib/storage: optimize convert multiple values regexp filter to composite tag filter (#1610)
* lib/storage: optimize convert multiple values regexp filter to composite tag filter * Apply suggestions from code review Co-authored-by: Aliaksandr Valialkin <valyala@gmail.com>
This commit is contained in:
parent
bc2d05be8e
commit
00cbb099b6
@ -18,34 +18,58 @@ import (
|
|||||||
//
|
//
|
||||||
// This converts `foo{bar="baz",x=~"a.+"}` to `{foo=bar="baz",foo=x=~"a.+"} filter.
|
// This converts `foo{bar="baz",x=~"a.+"}` to `{foo=bar="baz",foo=x=~"a.+"} filter.
|
||||||
func convertToCompositeTagFilterss(tfss []*TagFilters) []*TagFilters {
|
func convertToCompositeTagFilterss(tfss []*TagFilters) []*TagFilters {
|
||||||
tfssNew := make([]*TagFilters, len(tfss))
|
tfssNew := make([]*TagFilters, 0, len(tfss))
|
||||||
for i, tfs := range tfss {
|
for _, tfs := range tfss {
|
||||||
tfssNew[i] = convertToCompositeTagFilters(tfs)
|
tfssNew = append(tfss, convertToCompositeTagFilters(tfs)...)
|
||||||
}
|
}
|
||||||
return tfssNew
|
return tfssNew
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertToCompositeTagFilters(tfs *TagFilters) *TagFilters {
|
func convertToCompositeTagFilters(tfs *TagFilters) []*TagFilters {
|
||||||
// Search for metric name filter, which must be used for creating composite filters.
|
tfssCompiled := make([]*TagFilters, 0)
|
||||||
var name []byte
|
|
||||||
|
// Search for filters on metric name, which will be used for creating composite filters.
|
||||||
|
var names [][]byte
|
||||||
hasPositiveFilter := false
|
hasPositiveFilter := false
|
||||||
for _, tf := range tfs.tfs {
|
for _, tf := range tfs.tfs {
|
||||||
if len(tf.key) == 0 && !tf.isNegative && !tf.isRegexp {
|
if len(tf.key) == 0 && !tf.isNegative && !tf.isRegexp {
|
||||||
name = tf.value
|
names = [][]byte{tf.value}
|
||||||
|
} else if len(tf.key) == 0 && !tf.isNegative && tf.isRegexp && len(tf.orSuffixes) > 0 {
|
||||||
|
// Split the filter {__name__=~"name1|...|nameN", other_filters}
|
||||||
|
// into `name1{other_filters}`, ..., `nameN{other_filters}`
|
||||||
|
// and generate composite filters for each of them
|
||||||
|
names = names[:0]
|
||||||
|
for _, orSuffix := range tf.orSuffixes {
|
||||||
|
names = append(names, []byte(orSuffix))
|
||||||
|
}
|
||||||
} else if !tf.isNegative && !tf.isEmptyMatch {
|
} else if !tf.isNegative && !tf.isEmptyMatch {
|
||||||
hasPositiveFilter = true
|
hasPositiveFilter = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(name) == 0 {
|
if len(names) == 0 {
|
||||||
|
tfssCompiled = append(tfssCompiled, tfs)
|
||||||
atomic.AddUint64(&compositeFilterMissingConversions, 1)
|
atomic.AddUint64(&compositeFilterMissingConversions, 1)
|
||||||
return tfs
|
return tfssCompiled
|
||||||
}
|
}
|
||||||
tfsNew := make([]tagFilter, 0, len(tfs.tfs))
|
|
||||||
var compositeKey []byte
|
var compositeKey []byte
|
||||||
compositeFilters := 0
|
compositeFilters := 0
|
||||||
|
for _, name := range names {
|
||||||
|
tfsNew := make([]tagFilter, 0, len(tfs.tfs))
|
||||||
for _, tf := range tfs.tfs {
|
for _, tf := range tfs.tfs {
|
||||||
if len(tf.key) == 0 {
|
if len(tf.key) == 0 {
|
||||||
if !hasPositiveFilter || tf.isNegative || tf.isRegexp || string(tf.value) != string(name) {
|
sameOrSuffixes := true
|
||||||
|
if len(names) != len(tf.orSuffixes) {
|
||||||
|
sameOrSuffixes = false
|
||||||
|
} else {
|
||||||
|
for i, orSuffix := range tf.orSuffixes {
|
||||||
|
if string(names[i]) != orSuffix {
|
||||||
|
sameOrSuffixes = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !hasPositiveFilter || tf.isNegative || tf.isRegexp && !sameOrSuffixes || !tf.isRegexp && string(tf.value) != string(name) {
|
||||||
tfsNew = append(tfsNew, tf)
|
tfsNew = append(tfsNew, tf)
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
@ -54,6 +78,7 @@ func convertToCompositeTagFilters(tfs *TagFilters) *TagFilters {
|
|||||||
tfsNew = append(tfsNew, tf)
|
tfsNew = append(tfsNew, tf)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
compositeKey = marshalCompositeTagKey(compositeKey[:0], name, tf.key)
|
compositeKey = marshalCompositeTagKey(compositeKey[:0], name, tf.key)
|
||||||
var tfNew tagFilter
|
var tfNew tagFilter
|
||||||
if err := tfNew.Init(tfs.commonPrefix, compositeKey, tf.value, tf.isNegative, tf.isRegexp); err != nil {
|
if err := tfNew.Init(tfs.commonPrefix, compositeKey, tf.value, tf.isNegative, tf.isRegexp); err != nil {
|
||||||
@ -62,14 +87,17 @@ func convertToCompositeTagFilters(tfs *TagFilters) *TagFilters {
|
|||||||
tfsNew = append(tfsNew, tfNew)
|
tfsNew = append(tfsNew, tfNew)
|
||||||
compositeFilters++
|
compositeFilters++
|
||||||
}
|
}
|
||||||
if compositeFilters == 0 {
|
|
||||||
atomic.AddUint64(&compositeFilterMissingConversions, 1)
|
|
||||||
return tfs
|
|
||||||
}
|
|
||||||
tfsCompiled := NewTagFilters()
|
tfsCompiled := NewTagFilters()
|
||||||
tfsCompiled.tfs = tfsNew
|
tfsCompiled.tfs = tfsNew
|
||||||
|
tfssCompiled = append(tfssCompiled, tfsCompiled)
|
||||||
|
}
|
||||||
|
if compositeFilters == 0 {
|
||||||
|
tfssCompiled = append(tfssCompiled[:0], tfs)
|
||||||
|
atomic.AddUint64(&compositeFilterMissingConversions, 1)
|
||||||
|
return tfssCompiled
|
||||||
|
}
|
||||||
atomic.AddUint64(&compositeFilterSuccessConversions, 1)
|
atomic.AddUint64(&compositeFilterSuccessConversions, 1)
|
||||||
return tfsCompiled
|
return tfssCompiled
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestConvertToCompositeTagFilters(t *testing.T) {
|
func TestConvertToCompositeTagFilters(t *testing.T) {
|
||||||
f := func(tfs, resultExpected []TagFilter) {
|
f := func(tfs []TagFilter, resultExpected [][]TagFilter) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
tfsCompiled := NewTagFilters()
|
tfsCompiled := NewTagFilters()
|
||||||
for _, tf := range tfs {
|
for _, tf := range tfs {
|
||||||
@ -15,23 +15,27 @@ func TestConvertToCompositeTagFilters(t *testing.T) {
|
|||||||
t.Fatalf("cannot add tf=%s: %s", tf.String(), err)
|
t.Fatalf("cannot add tf=%s: %s", tf.String(), err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
resultCompiled := convertToCompositeTagFilters(tfsCompiled)
|
resultCompileds := convertToCompositeTagFilters(tfsCompiled)
|
||||||
result := make([]TagFilter, len(resultCompiled.tfs))
|
result := make([][]TagFilter, len(resultCompileds))
|
||||||
|
for i, resultCompiled := range resultCompileds {
|
||||||
|
tfs := make([]TagFilter, len(resultCompiled.tfs))
|
||||||
for i, tf := range resultCompiled.tfs {
|
for i, tf := range resultCompiled.tfs {
|
||||||
result[i] = TagFilter{
|
tfs[i] = TagFilter{
|
||||||
Key: tf.key,
|
Key: tf.key,
|
||||||
Value: tf.value,
|
Value: tf.value,
|
||||||
IsNegative: tf.isNegative,
|
IsNegative: tf.isNegative,
|
||||||
IsRegexp: tf.isRegexp,
|
IsRegexp: tf.isRegexp,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
result[i] = tfs
|
||||||
|
}
|
||||||
if !reflect.DeepEqual(result, resultExpected) {
|
if !reflect.DeepEqual(result, resultExpected) {
|
||||||
t.Fatalf("unexpected result;\ngot\n%+v\nwant\n%+v", result, resultExpected)
|
t.Fatalf("unexpected result;\ngot\n%+v\nwant\n%+v", result, resultExpected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Empty filters
|
// Empty filters
|
||||||
f(nil, []TagFilter{})
|
f(nil, [][]TagFilter{{}})
|
||||||
|
|
||||||
// A single non-name filter
|
// A single non-name filter
|
||||||
f([]TagFilter{
|
f([]TagFilter{
|
||||||
@ -41,13 +45,15 @@ func TestConvertToCompositeTagFilters(t *testing.T) {
|
|||||||
IsNegative: false,
|
IsNegative: false,
|
||||||
IsRegexp: false,
|
IsRegexp: false,
|
||||||
},
|
},
|
||||||
}, []TagFilter{
|
}, [][]TagFilter{
|
||||||
|
{
|
||||||
{
|
{
|
||||||
Key: []byte("foo"),
|
Key: []byte("foo"),
|
||||||
Value: []byte("bar"),
|
Value: []byte("bar"),
|
||||||
IsNegative: false,
|
IsNegative: false,
|
||||||
IsRegexp: false,
|
IsRegexp: false,
|
||||||
},
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// Multiple non-name filters
|
// Multiple non-name filters
|
||||||
@ -64,7 +70,8 @@ func TestConvertToCompositeTagFilters(t *testing.T) {
|
|||||||
IsNegative: true,
|
IsNegative: true,
|
||||||
IsRegexp: false,
|
IsRegexp: false,
|
||||||
},
|
},
|
||||||
}, []TagFilter{
|
}, [][]TagFilter{
|
||||||
|
{
|
||||||
{
|
{
|
||||||
Key: []byte("foo"),
|
Key: []byte("foo"),
|
||||||
Value: []byte("bar"),
|
Value: []byte("bar"),
|
||||||
@ -77,6 +84,7 @@ func TestConvertToCompositeTagFilters(t *testing.T) {
|
|||||||
IsNegative: true,
|
IsNegative: true,
|
||||||
IsRegexp: false,
|
IsRegexp: false,
|
||||||
},
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// A single name filter
|
// A single name filter
|
||||||
@ -87,13 +95,15 @@ func TestConvertToCompositeTagFilters(t *testing.T) {
|
|||||||
IsNegative: false,
|
IsNegative: false,
|
||||||
IsRegexp: false,
|
IsRegexp: false,
|
||||||
},
|
},
|
||||||
}, []TagFilter{
|
}, [][]TagFilter{
|
||||||
|
{
|
||||||
{
|
{
|
||||||
Key: nil,
|
Key: nil,
|
||||||
Value: []byte("bar"),
|
Value: []byte("bar"),
|
||||||
IsNegative: false,
|
IsNegative: false,
|
||||||
IsRegexp: false,
|
IsRegexp: false,
|
||||||
},
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// Two name filters
|
// Two name filters
|
||||||
@ -110,7 +120,8 @@ func TestConvertToCompositeTagFilters(t *testing.T) {
|
|||||||
IsNegative: false,
|
IsNegative: false,
|
||||||
IsRegexp: false,
|
IsRegexp: false,
|
||||||
},
|
},
|
||||||
}, []TagFilter{
|
}, [][]TagFilter{
|
||||||
|
{
|
||||||
{
|
{
|
||||||
Key: nil,
|
Key: nil,
|
||||||
Value: []byte("bar"),
|
Value: []byte("bar"),
|
||||||
@ -123,6 +134,7 @@ func TestConvertToCompositeTagFilters(t *testing.T) {
|
|||||||
IsNegative: false,
|
IsNegative: false,
|
||||||
IsRegexp: false,
|
IsRegexp: false,
|
||||||
},
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// A name filter with non-name filter.
|
// A name filter with non-name filter.
|
||||||
@ -139,13 +151,15 @@ func TestConvertToCompositeTagFilters(t *testing.T) {
|
|||||||
IsNegative: false,
|
IsNegative: false,
|
||||||
IsRegexp: false,
|
IsRegexp: false,
|
||||||
},
|
},
|
||||||
}, []TagFilter{
|
}, [][]TagFilter{
|
||||||
|
{
|
||||||
{
|
{
|
||||||
Key: []byte("\xfe\x03barfoo"),
|
Key: []byte("\xfe\x03barfoo"),
|
||||||
Value: []byte("abc"),
|
Value: []byte("abc"),
|
||||||
IsNegative: false,
|
IsNegative: false,
|
||||||
IsRegexp: false,
|
IsRegexp: false,
|
||||||
},
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// A name filter with a single negative filter
|
// A name filter with a single negative filter
|
||||||
@ -162,7 +176,8 @@ func TestConvertToCompositeTagFilters(t *testing.T) {
|
|||||||
IsNegative: true,
|
IsNegative: true,
|
||||||
IsRegexp: false,
|
IsRegexp: false,
|
||||||
},
|
},
|
||||||
}, []TagFilter{
|
}, [][]TagFilter{
|
||||||
|
{
|
||||||
{
|
{
|
||||||
Key: nil,
|
Key: nil,
|
||||||
Value: []byte("bar"),
|
Value: []byte("bar"),
|
||||||
@ -175,6 +190,7 @@ func TestConvertToCompositeTagFilters(t *testing.T) {
|
|||||||
IsNegative: true,
|
IsNegative: true,
|
||||||
IsRegexp: false,
|
IsRegexp: false,
|
||||||
},
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// A name filter with a negative and a positive filter
|
// A name filter with a negative and a positive filter
|
||||||
@ -197,7 +213,8 @@ func TestConvertToCompositeTagFilters(t *testing.T) {
|
|||||||
IsNegative: false,
|
IsNegative: false,
|
||||||
IsRegexp: true,
|
IsRegexp: true,
|
||||||
},
|
},
|
||||||
}, []TagFilter{
|
}, [][]TagFilter{
|
||||||
|
{
|
||||||
{
|
{
|
||||||
Key: []byte("\xfe\x03barfoo"),
|
Key: []byte("\xfe\x03barfoo"),
|
||||||
Value: []byte("abc"),
|
Value: []byte("abc"),
|
||||||
@ -210,6 +227,7 @@ func TestConvertToCompositeTagFilters(t *testing.T) {
|
|||||||
IsNegative: false,
|
IsNegative: false,
|
||||||
IsRegexp: true,
|
IsRegexp: true,
|
||||||
},
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// Two name filters with non-name filter.
|
// Two name filters with non-name filter.
|
||||||
@ -232,7 +250,8 @@ func TestConvertToCompositeTagFilters(t *testing.T) {
|
|||||||
IsNegative: false,
|
IsNegative: false,
|
||||||
IsRegexp: false,
|
IsRegexp: false,
|
||||||
},
|
},
|
||||||
}, []TagFilter{
|
}, [][]TagFilter{
|
||||||
|
{
|
||||||
{
|
{
|
||||||
Key: nil,
|
Key: nil,
|
||||||
Value: []byte("bar"),
|
Value: []byte("bar"),
|
||||||
@ -245,6 +264,7 @@ func TestConvertToCompositeTagFilters(t *testing.T) {
|
|||||||
IsNegative: false,
|
IsNegative: false,
|
||||||
IsRegexp: false,
|
IsRegexp: false,
|
||||||
},
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// A name filter with regexp non-name filter, which can be converted to non-regexp.
|
// A name filter with regexp non-name filter, which can be converted to non-regexp.
|
||||||
@ -261,13 +281,15 @@ func TestConvertToCompositeTagFilters(t *testing.T) {
|
|||||||
IsNegative: false,
|
IsNegative: false,
|
||||||
IsRegexp: true,
|
IsRegexp: true,
|
||||||
},
|
},
|
||||||
}, []TagFilter{
|
}, [][]TagFilter{
|
||||||
|
{
|
||||||
{
|
{
|
||||||
Key: []byte("\xfe\x03barfoo"),
|
Key: []byte("\xfe\x03barfoo"),
|
||||||
Value: []byte("abc"),
|
Value: []byte("abc"),
|
||||||
IsNegative: false,
|
IsNegative: false,
|
||||||
IsRegexp: false,
|
IsRegexp: false,
|
||||||
},
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// A name filter with regexp non-name filter.
|
// A name filter with regexp non-name filter.
|
||||||
@ -284,13 +306,15 @@ func TestConvertToCompositeTagFilters(t *testing.T) {
|
|||||||
IsNegative: false,
|
IsNegative: false,
|
||||||
IsRegexp: true,
|
IsRegexp: true,
|
||||||
},
|
},
|
||||||
}, []TagFilter{
|
}, [][]TagFilter{
|
||||||
|
{
|
||||||
{
|
{
|
||||||
Key: []byte("\xfe\x03barfoo"),
|
Key: []byte("\xfe\x03barfoo"),
|
||||||
Value: []byte("abc.+"),
|
Value: []byte("abc.+"),
|
||||||
IsNegative: false,
|
IsNegative: false,
|
||||||
IsRegexp: true,
|
IsRegexp: true,
|
||||||
},
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// A name filter with graphite filter.
|
// A name filter with graphite filter.
|
||||||
@ -307,7 +331,8 @@ func TestConvertToCompositeTagFilters(t *testing.T) {
|
|||||||
IsNegative: false,
|
IsNegative: false,
|
||||||
IsRegexp: false,
|
IsRegexp: false,
|
||||||
},
|
},
|
||||||
}, []TagFilter{
|
}, [][]TagFilter{
|
||||||
|
{
|
||||||
{
|
{
|
||||||
Key: nil,
|
Key: nil,
|
||||||
Value: []byte("bar"),
|
Value: []byte("bar"),
|
||||||
@ -320,6 +345,7 @@ func TestConvertToCompositeTagFilters(t *testing.T) {
|
|||||||
IsNegative: false,
|
IsNegative: false,
|
||||||
IsRegexp: false,
|
IsRegexp: false,
|
||||||
},
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// A name filter with non-name filter and a graphite filter.
|
// A name filter with non-name filter and a graphite filter.
|
||||||
@ -342,7 +368,8 @@ func TestConvertToCompositeTagFilters(t *testing.T) {
|
|||||||
IsNegative: false,
|
IsNegative: false,
|
||||||
IsRegexp: false,
|
IsRegexp: false,
|
||||||
},
|
},
|
||||||
}, []TagFilter{
|
}, [][]TagFilter{
|
||||||
|
{
|
||||||
{
|
{
|
||||||
Key: []byte("\xfe\x03barfoo"),
|
Key: []byte("\xfe\x03barfoo"),
|
||||||
Value: []byte("abc"),
|
Value: []byte("abc"),
|
||||||
@ -355,6 +382,7 @@ func TestConvertToCompositeTagFilters(t *testing.T) {
|
|||||||
IsNegative: false,
|
IsNegative: false,
|
||||||
IsRegexp: false,
|
IsRegexp: false,
|
||||||
},
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// Regexp name filter, which can be converted to non-regexp, with non-name filter.
|
// Regexp name filter, which can be converted to non-regexp, with non-name filter.
|
||||||
@ -371,13 +399,144 @@ func TestConvertToCompositeTagFilters(t *testing.T) {
|
|||||||
IsNegative: false,
|
IsNegative: false,
|
||||||
IsRegexp: false,
|
IsRegexp: false,
|
||||||
},
|
},
|
||||||
}, []TagFilter{
|
}, [][]TagFilter{
|
||||||
|
{
|
||||||
{
|
{
|
||||||
Key: []byte("\xfe\x03barfoo"),
|
Key: []byte("\xfe\x03barfoo"),
|
||||||
Value: []byte("abc"),
|
Value: []byte("abc"),
|
||||||
IsNegative: false,
|
IsNegative: false,
|
||||||
IsRegexp: false,
|
IsRegexp: false,
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// Multiple values regexp filter, which can be converted to non-regexp, with non-name filter.
|
||||||
|
f([]TagFilter{
|
||||||
|
{
|
||||||
|
Key: nil,
|
||||||
|
Value: []byte("bar|foo"),
|
||||||
|
IsNegative: false,
|
||||||
|
IsRegexp: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: []byte("foo"),
|
||||||
|
Value: []byte("abc"),
|
||||||
|
IsNegative: false,
|
||||||
|
IsRegexp: false,
|
||||||
|
},
|
||||||
|
}, [][]TagFilter{
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Key: []byte("\xfe\x03barfoo"),
|
||||||
|
Value: []byte("abc"),
|
||||||
|
IsNegative: false,
|
||||||
|
IsRegexp: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Key: []byte("\xfe\x03foofoo"),
|
||||||
|
Value: []byte("abc"),
|
||||||
|
IsNegative: false,
|
||||||
|
IsRegexp: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// Two multiple values regexp filter, which can be converted to non-regexp, with non-name filter.
|
||||||
|
f([]TagFilter{
|
||||||
|
{
|
||||||
|
Key: nil,
|
||||||
|
Value: []byte("bar|foo"),
|
||||||
|
IsNegative: false,
|
||||||
|
IsRegexp: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: nil,
|
||||||
|
Value: []byte("abc|def"),
|
||||||
|
IsNegative: false,
|
||||||
|
IsRegexp: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: []byte("face"),
|
||||||
|
Value: []byte("air"),
|
||||||
|
IsNegative: false,
|
||||||
|
IsRegexp: false,
|
||||||
|
},
|
||||||
|
}, [][]TagFilter{
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Key: nil,
|
||||||
|
Value: []byte("bar|foo"),
|
||||||
|
IsNegative: false,
|
||||||
|
IsRegexp: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: []byte("\xfe\x03abcface"),
|
||||||
|
Value: []byte("air"),
|
||||||
|
IsNegative: false,
|
||||||
|
IsRegexp: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Key: nil,
|
||||||
|
Value: []byte("bar|foo"),
|
||||||
|
IsNegative: false,
|
||||||
|
IsRegexp: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: []byte("\xfe\x03defface"),
|
||||||
|
Value: []byte("air"),
|
||||||
|
IsNegative: false,
|
||||||
|
IsRegexp: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// Multiple values regexp filter with a single negative filter
|
||||||
|
f([]TagFilter{
|
||||||
|
{
|
||||||
|
Key: nil,
|
||||||
|
Value: []byte("bar|foo"),
|
||||||
|
IsNegative: false,
|
||||||
|
IsRegexp: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: []byte("foo"),
|
||||||
|
Value: []byte("abc"),
|
||||||
|
IsNegative: true,
|
||||||
|
IsRegexp: false,
|
||||||
|
},
|
||||||
|
}, [][]TagFilter{
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Key: nil,
|
||||||
|
Value: []byte("bar|foo"),
|
||||||
|
IsNegative: false,
|
||||||
|
IsRegexp: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: []byte("\xfe\x03barfoo"),
|
||||||
|
Value: []byte("abc"),
|
||||||
|
IsNegative: true,
|
||||||
|
IsRegexp: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Key: nil,
|
||||||
|
Value: []byte("bar|foo"),
|
||||||
|
IsNegative: false,
|
||||||
|
IsRegexp: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: []byte("\xfe\x03foofoo"),
|
||||||
|
Value: []byte("abc"),
|
||||||
|
IsNegative: true,
|
||||||
|
IsRegexp: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// Regexp name filter with non-name filter.
|
// Regexp name filter with non-name filter.
|
||||||
@ -394,7 +553,8 @@ func TestConvertToCompositeTagFilters(t *testing.T) {
|
|||||||
IsNegative: true,
|
IsNegative: true,
|
||||||
IsRegexp: false,
|
IsRegexp: false,
|
||||||
},
|
},
|
||||||
}, []TagFilter{
|
}, [][]TagFilter{
|
||||||
|
{
|
||||||
{
|
{
|
||||||
Key: nil,
|
Key: nil,
|
||||||
Value: []byte("bar.+"),
|
Value: []byte("bar.+"),
|
||||||
@ -407,6 +567,7 @@ func TestConvertToCompositeTagFilters(t *testing.T) {
|
|||||||
IsNegative: true,
|
IsNegative: true,
|
||||||
IsRegexp: false,
|
IsRegexp: false,
|
||||||
},
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// Regexp non-name filter, which matches anything.
|
// Regexp non-name filter, which matches anything.
|
||||||
@ -423,13 +584,15 @@ func TestConvertToCompositeTagFilters(t *testing.T) {
|
|||||||
IsNegative: false,
|
IsNegative: false,
|
||||||
IsRegexp: true,
|
IsRegexp: true,
|
||||||
},
|
},
|
||||||
}, []TagFilter{
|
}, [][]TagFilter{
|
||||||
|
{
|
||||||
{
|
{
|
||||||
Key: nil,
|
Key: nil,
|
||||||
Value: []byte("bar"),
|
Value: []byte("bar"),
|
||||||
IsNegative: false,
|
IsNegative: false,
|
||||||
IsRegexp: false,
|
IsRegexp: false,
|
||||||
},
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user