From d5132a9eae6e4c0b455fe2078d051123524f509d Mon Sep 17 00:00:00 2001 From: Alex Roitman Date: Wed, 25 Mar 2020 11:53:44 -0700 Subject: [PATCH] Map field names to array indices in scanwriter, once per query. --- internal/server/scanner.go | 33 +++++++++++++++++++-------------- internal/server/scanner_test.go | 8 ++++---- internal/server/token.go | 6 ++++-- 3 files changed, 27 insertions(+), 20 deletions(-) diff --git a/internal/server/scanner.go b/internal/server/scanner.go index df5cfbf6..30c21076 100644 --- a/internal/server/scanner.go +++ b/internal/server/scanner.go @@ -97,8 +97,6 @@ func (s *Server) newScanWriter( msg: msg, cursor: cursor, limit: limit, - wheres: wheres, - whereins: whereins, whereevals: whereevals, output: output, nofields: nofields, @@ -117,6 +115,19 @@ func (s *Server) newScanWriter( if sw.col != nil { sw.fmap = sw.col.FieldMap() sw.farr = sw.col.FieldArr() + // This fills index value in wheres/whereins + // so we don't have to map string field names for each tested object + var ok bool + for _, where := range wheres { + if where.index, ok = sw.fmap[where.field]; ok { + sw.wheres = append(sw.wheres, where) + } + } + for _, wherein := range whereins { + if wherein.index, ok = sw.fmap[wherein.field]; ok { + sw.whereins = append(sw.whereins, wherein) + } + } } sw.fvals = make([]float64, len(sw.farr)) return sw, nil @@ -212,11 +223,8 @@ func (sw *scanWriter) fieldMatch(fields []float64, o geojson.Object) (fvals []fl continue } var value float64 - idx, ok := sw.fmap[where.field] - if ok { - if len(fields) > idx { - value = fields[idx] - } + if len(fields) > where.index { + value = fields[where.index] } if !where.match(value) { return @@ -224,11 +232,8 @@ func (sw *scanWriter) fieldMatch(fields []float64, o geojson.Object) (fvals []fl } for _, wherein := range sw.whereins { var value float64 - idx, ok := sw.fmap[wherein.field] - if ok { - if len(fields) > idx { - value = fields[idx] - } + if len(fields) > wherein.index { + value = fields[wherein.index] } if !wherein.match(value) { return @@ -265,13 +270,13 @@ func (sw *scanWriter) fieldMatch(fields []float64, o geojson.Object) (fvals []fl } continue } - value := sw.fvals[sw.fmap[where.field]] + value := sw.fvals[where.index] if !where.match(value) { return } } for _, wherein := range sw.whereins { - value := sw.fvals[sw.fmap[wherein.field]] + value := sw.fvals[wherein.index] if !wherein.match(value) { return } diff --git a/internal/server/scanner_test.go b/internal/server/scanner_test.go index 013d1d0a..31f186a2 100644 --- a/internal/server/scanner_test.go +++ b/internal/server/scanner_test.go @@ -31,12 +31,12 @@ func BenchmarkFieldMatch(t *testing.B) { } sw := &scanWriter{ wheres: []whereT{ - {"foo", false, 1, false, 3}, - {"bar", false, 10, false, 30}, + {"foo", 0, false, 1, false, 3}, + {"bar", 1, false, 10, false, 30}, }, whereins: []whereinT{ - {"foo", []float64{1, 2}}, - {"bar", []float64{11, 25}}, + {"foo", 0, []float64{1, 2}}, + {"bar", 1, []float64{11, 25}}, }, fmap: map[string]int{"foo": 0, "bar": 1}, farr: []string{"bar", "foo"}, diff --git a/internal/server/token.go b/internal/server/token.go index 75cca315..6b471b0c 100644 --- a/internal/server/token.go +++ b/internal/server/token.go @@ -116,6 +116,7 @@ func lc(s1, s2 string) bool { type whereT struct { field string + index int minx bool min float64 maxx bool @@ -159,6 +160,7 @@ func zMinMaxFromWheres(wheres []whereT) (minZ, maxZ float64) { type whereinT struct { field string + index int valArr []float64 } @@ -328,7 +330,7 @@ func (s *Server) parseSearchScanBaseTokens( return } } - t.wheres = append(t.wheres, whereT{field, minx, min, maxx, max}) + t.wheres = append(t.wheres, whereT{field, -1, minx, min, maxx, max}) continue case "wherein": vs = nvs @@ -359,7 +361,7 @@ func (s *Server) parseSearchScanBaseTokens( } valArr = append(valArr, val) } - t.whereins = append(t.whereins, whereinT{field, valArr}) + t.whereins = append(t.whereins, whereinT{field, -1, valArr}) continue case "whereevalsha": fallthrough