From a174cc029ea3d65216b9153ef87328bc303b6546 Mon Sep 17 00:00:00 2001 From: Alan Protasio Date: Wed, 17 May 2023 23:39:05 -0700 Subject: [PATCH] Optimizing "grafana generated" regex matchers (#6376) * Opmizing Group Regex Signed-off-by: Alan Protasio * fixing native histogram tests Signed-off-by: Alan Protasio --------- Signed-off-by: Alan Protasio --- pkg/store/bucket_test.go | 45 ++++++++++++++++++++-------- pkg/store/opts.go | 9 +++++- pkg/store/opts_test.go | 13 ++++++++ pkg/store/storepb/testutil/series.go | 4 +-- 4 files changed, 56 insertions(+), 15 deletions(-) diff --git a/pkg/store/bucket_test.go b/pkg/store/bucket_test.go index 90ba08feef6..2f1eb8ef938 100644 --- a/pkg/store/bucket_test.go +++ b/pkg/store/bucket_test.go @@ -1384,19 +1384,40 @@ func benchBucketSeries(t testutil.TB, sampleType chunkenc.ValueType, skipChunk b seriesCut = expectedSamples / samplesPerSeriesPerBlock } - bCases = append(bCases, &storetestutil.SeriesCase{ - Name: fmt.Sprintf("%dof%d", expectedSamples, totalSeries*samplesPerSeries), - Req: &storepb.SeriesRequest{ - MinTime: 0, - MaxTime: int64(expectedSamples) - 1, - Matchers: []storepb.LabelMatcher{ - {Type: storepb.LabelMatcher_EQ, Name: "foo", Value: "bar"}, + matchersCase := []*labels.Matcher{ + labels.MustNewMatcher(labels.MatchEqual, "foo", "bar"), + labels.MustNewMatcher(labels.MatchNotEqual, "foo", "bar"), + labels.MustNewMatcher(labels.MatchRegexp, "j", "(0|1)"), + labels.MustNewMatcher(labels.MatchRegexp, "j", "0|1"), + labels.MustNewMatcher(labels.MatchNotRegexp, "j", "(0|1)"), + labels.MustNewMatcher(labels.MatchNotRegexp, "j", "0|1"), + } + + for _, lm := range matchersCase { + var expectedSeries []*storepb.Series + m, err := storepb.PromMatchersToMatchers(lm) + testutil.Ok(t, err) + + // seriesCut does not cut chunks properly, but those are assured against for non benchmarks only, where we use 100% case only. + for _, s := range series[:seriesCut] { + for _, label := range s.Labels { + if label.Name == lm.Name && lm.Matches(label.Value) { + expectedSeries = append(expectedSeries, s) + break + } + } + } + bCases = append(bCases, &storetestutil.SeriesCase{ + Name: fmt.Sprintf("%dof%d[%s]", expectedSamples, totalSeries*samplesPerSeries, lm.String()), + Req: &storepb.SeriesRequest{ + MinTime: 0, + MaxTime: int64(expectedSamples) - 1, + Matchers: m, + SkipChunks: skipChunk, }, - SkipChunks: skipChunk, - }, - // This does not cut chunks properly, but those are assured against for non benchmarks only, where we use 100% case only. - ExpectedSeries: series[:seriesCut], - }) + ExpectedSeries: expectedSeries, + }) + } } storetestutil.TestServerSeries(t, st, bCases...) diff --git a/pkg/store/opts.go b/pkg/store/opts.go index e95a623a706..e7d2dd83669 100644 --- a/pkg/store/opts.go +++ b/pkg/store/opts.go @@ -27,7 +27,14 @@ func init() { func findSetMatches(pattern string) []string { escaped := false sets := []*strings.Builder{{}} - for i := 0; i < len(pattern); i++ { + init := 0 + end := len(pattern) + // If the regex is wrapped in a group we can remove the first and last parentheses + if pattern[init] == '(' && pattern[end-1] == ')' { + init++ + end-- + } + for i := init; i < end; i++ { if escaped { switch { case isRegexMetaCharacter(pattern[i]): diff --git a/pkg/store/opts_test.go b/pkg/store/opts_test.go index 50d629f4cfd..414b1cc569d 100644 --- a/pkg/store/opts_test.go +++ b/pkg/store/opts_test.go @@ -24,6 +24,15 @@ func TestFindSetMatches(t *testing.T) { "baz", }, }, + // Simple sets with group wrapper. + { + pattern: "(foo|bar|baz)", + exp: []string{ + "foo", + "bar", + "baz", + }, + }, // Simple sets containing escaped characters. { pattern: "fo\\.o|bar\\?|\\^baz", @@ -38,6 +47,10 @@ func TestFindSetMatches(t *testing.T) { pattern: "fo.o|bar?|^baz", exp: nil, }, + { + pattern: "(fool|bar)|(baz)", + exp: nil, + }, { pattern: "foo\\|bar\\|baz", exp: []string{ diff --git a/pkg/store/storepb/testutil/series.go b/pkg/store/storepb/testutil/series.go index aa70498aea9..047f942c2be 100644 --- a/pkg/store/storepb/testutil/series.go +++ b/pkg/store/storepb/testutil/series.go @@ -167,7 +167,7 @@ func ReadSeriesFromBlock(t testing.TB, h tsdb.BlockReader, extLabels labels.Labe func appendFloatSamples(t testing.TB, app storage.Appender, tsLabel int, opts HeadGenOptions) { ref, err := app.Append( 0, - labels.FromStrings("foo", "bar", "i", fmt.Sprintf("%07d%s", tsLabel, LabelLongSuffix)), + labels.FromStrings("foo", "bar", "i", fmt.Sprintf("%07d%s", tsLabel, LabelLongSuffix), "j", fmt.Sprintf("%v", tsLabel)), int64(tsLabel)*opts.ScrapeInterval.Milliseconds(), opts.Random.Float64(), ) @@ -195,7 +195,7 @@ func appendHistogramSamples(t testing.TB, app storage.Appender, tsLabel int, opt ref, err := app.AppendHistogram( 0, - labels.FromStrings("foo", "bar", "i", fmt.Sprintf("%07d%s", tsLabel, LabelLongSuffix)), + labels.FromStrings("foo", "bar", "i", fmt.Sprintf("%07d%s", tsLabel, LabelLongSuffix), "j", fmt.Sprintf("%v", tsLabel)), int64(tsLabel)*opts.ScrapeInterval.Milliseconds(), sample, nil,