From 0ad7aaf535fd49c9ab9a6e50d777961248095398 Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Wed, 1 Apr 2020 17:40:18 +0300 Subject: [PATCH] lib/storage: add missing reset for tagFilter.matchesEmptyValue on tagFilter.Init --- lib/storage/index_db.go | 9 +++-- lib/storage/index_db_test.go | 73 +++++++++++++++++++++++++++++++++++- lib/storage/tag_filters.go | 1 + 3 files changed, 78 insertions(+), 5 deletions(-) diff --git a/lib/storage/index_db.go b/lib/storage/index_db.go index 219d94107a..b5fddec761 100644 --- a/lib/storage/index_db.go +++ b/lib/storage/index_db.go @@ -1735,10 +1735,6 @@ func (is *indexSearch) searchMetricIDs(tfss []*TagFilters, tr TimeRange, maxMetr } func (is *indexSearch) updateMetricIDsForTagFilters(metricIDs *uint64set.Set, tfs *TagFilters, tr TimeRange, maxMetrics int) error { - // Sort tag filters for faster ts.Seek below. - sort.Slice(tfs.tfs, func(i, j int) bool { - return tfs.tfs[i].Less(&tfs.tfs[j]) - }) err := is.tryUpdatingMetricIDsForDateRange(metricIDs, tfs, tr, maxMetrics) if err == nil { // Fast path: found metricIDs by date range. @@ -1749,6 +1745,11 @@ func (is *indexSearch) updateMetricIDsForTagFilters(metricIDs *uint64set.Set, tf } // Slow path - try searching over the whole inverted index. + + // Sort tag filters for faster ts.Seek below. + sort.Slice(tfs.tfs, func(i, j int) bool { + return tfs.tfs[i].Less(&tfs.tfs[j]) + }) minTf, minMetricIDs, err := is.getTagFilterWithMinMetricIDsCountOptimized(tfs, tr, maxMetrics) if err != nil { return err diff --git a/lib/storage/index_db_test.go b/lib/storage/index_db_test.go index fd11a5f31e..4f72560b02 100644 --- a/lib/storage/index_db_test.go +++ b/lib/storage/index_db_test.go @@ -1119,6 +1119,17 @@ func TestMatchTagFilters(t *testing.T) { if ok { t.Fatalf("Shouldn't match") } + tfs.Reset(mn.AccountID, mn.ProjectID) + if err := tfs.Add(nil, []byte(".+"), true, true); err != nil { + t.Fatalf("cannot add regexp, negative filter: %s", err) + } + ok, err = matchTagFilters(&mn, toTFPointers(tfs.tfs), &bb) + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + if ok { + t.Fatalf("Shouldn't match") + } // Positive match by MetricGroup tfs.Reset(mn.AccountID, mn.ProjectID) @@ -1165,6 +1176,17 @@ func TestMatchTagFilters(t *testing.T) { if !ok { t.Fatalf("Should match") } + tfs.Reset(mn.AccountID, mn.ProjectID) + if err := tfs.Add(nil, []byte(".+"), false, true); err != nil { + t.Fatalf("cannot add regexp, positive filter: %s", err) + } + ok, err = matchTagFilters(&mn, toTFPointers(tfs.tfs), &bb) + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + if !ok { + t.Fatalf("Should match") + } // Negative match by non-existing tag tfs.Reset(mn.AccountID, mn.ProjectID) @@ -1222,6 +1244,17 @@ func TestMatchTagFilters(t *testing.T) { if !ok { t.Fatalf("Should match") } + tfs.Reset(mn.AccountID, mn.ProjectID) + if err := tfs.Add([]byte("non-existing-tag"), []byte(".+"), false, true); err != nil { + t.Fatalf("cannot add regexp, non-negative filter: %s", err) + } + ok, err = matchTagFilters(&mn, toTFPointers(tfs.tfs), &bb) + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + if ok { + t.Fatalf("Shouldn't match") + } // Negative match by existing tag tfs.Reset(mn.AccountID, mn.ProjectID) @@ -1268,6 +1301,17 @@ func TestMatchTagFilters(t *testing.T) { if ok { t.Fatalf("Shouldn't match") } + tfs.Reset(mn.AccountID, mn.ProjectID) + if err := tfs.Add([]byte("key 3"), []byte(".+"), true, true); err != nil { + t.Fatalf("cannot add regexp, negative filter: %s", err) + } + ok, err = matchTagFilters(&mn, toTFPointers(tfs.tfs), &bb) + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + if ok { + t.Fatalf("Shouldn't match") + } // Positive match by existing tag tfs.Reset(mn.AccountID, mn.ProjectID) @@ -1304,7 +1348,7 @@ func TestMatchTagFilters(t *testing.T) { t.Fatalf("Should match") } tfs.Reset(mn.AccountID, mn.ProjectID) - if err := tfs.Add([]byte("key 3"), []byte("v.+lue 2"), true, true); err != nil { + if err := tfs.Add([]byte("key 3"), []byte("v.+lue 2|"), true, true); err != nil { t.Fatalf("cannot add regexp, negative filter: %s", err) } ok, err = matchTagFilters(&mn, toTFPointers(tfs.tfs), &bb) @@ -1325,6 +1369,17 @@ func TestMatchTagFilters(t *testing.T) { if !ok { t.Fatalf("Should match") } + tfs.Reset(mn.AccountID, mn.ProjectID) + if err := tfs.Add([]byte("key 3"), []byte(".+"), false, true); err != nil { + t.Fatalf("cannot add regexp, non-negative filter: %s", err) + } + ok, err = matchTagFilters(&mn, toTFPointers(tfs.tfs), &bb) + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + if !ok { + t.Fatalf("Should match") + } // Positive match by multiple tags and MetricGroup tfs.Reset(mn.AccountID, mn.ProjectID) @@ -1396,6 +1451,22 @@ func TestMatchTagFilters(t *testing.T) { if ok { t.Fatalf("Shouldn't match") } + + // Negative match for multiple non-regexp positive filters + tfs.Reset(mn.AccountID, mn.ProjectID) + if err := tfs.Add(nil, []byte("foobar_metric"), false, false); err != nil { + t.Fatalf("cannot add non-regexp positive filter for MetricGroup: %s", err) + } + if err := tfs.Add([]byte("non-existing-metric"), []byte("foobar"), false, false); err != nil { + t.Fatalf("cannot add non-regexp positive filter for non-existing tag: %s", err) + } + ok, err = matchTagFilters(&mn, toTFPointers(tfs.tfs), &bb) + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + if ok { + t.Fatalf("Shouldn't match") + } } func TestSearchTSIDWithTimeRange(t *testing.T) { diff --git a/lib/storage/tag_filters.go b/lib/storage/tag_filters.go index 7aa7ba6958..51f3704945 100644 --- a/lib/storage/tag_filters.go +++ b/lib/storage/tag_filters.go @@ -242,6 +242,7 @@ func (tf *tagFilter) Init(commonPrefix, key, value []byte, isNegative, isRegexp tf.orSuffixes = tf.orSuffixes[:0] tf.reSuffixMatch = nil + tf.matchesEmptyValue = false tf.prefix = append(tf.prefix, commonPrefix...) tf.prefix = marshalTagValue(tf.prefix, key)