syncbase: syncQL: query optimization and regex rewrite
1. Optimization: examine fewer key values by using ranges rather
than prefixes. The query package was written with the
understanding that only prefixes could be specified when
fetching key/values from the store (e.g., for the where clause
expression 'k = "foo", all keys beginning with "foo" would be
returned. With this change, at most one key/value pair
will be examined for the above case.
2. Optimize like expressions that contain no wildcards to an
equal expression. If a like is used where not needed, the
expression is translated to an equals (escaped wildcard
characters are unescaped as the equals expression does not
expect escaped characters).
3. The computeRegularExpression function has been rewritten
because the author (that's me) found it confusing and
unmaintainable.
Change-Id: Ie66625f6af6baefd45f0292bbf0ac11b9f5d5d86
diff --git a/services/syncbase/server/nosql/database.go b/services/syncbase/server/nosql/database.go
index f2839d6..d18ab04 100644
--- a/services/syncbase/server/nosql/database.go
+++ b/services/syncbase/server/nosql/database.go
@@ -15,7 +15,6 @@
wire "v.io/syncbase/v23/services/syncbase/nosql"
"v.io/syncbase/v23/syncbase/nosql/query_db"
"v.io/syncbase/v23/syncbase/nosql/query_exec"
- prefixutil "v.io/syncbase/v23/syncbase/util"
"v.io/syncbase/x/ref/services/syncbase/server/interfaces"
"v.io/syncbase/x/ref/services/syncbase/server/util"
"v.io/syncbase/x/ref/services/syncbase/server/watchable"
@@ -404,20 +403,20 @@
req *tableReq
}
-func (t *tableDb) Scan(prefixes []string) (query_db.KeyValueStream, error) {
+func (t *tableDb) Scan(keyRanges query_db.KeyRanges) (query_db.KeyValueStream, error) {
return &kvs{
- t: t,
- prefixes: prefixes,
- curr: -1,
- validRow: false,
- it: nil,
- err: nil,
+ t: t,
+ keyRanges: keyRanges,
+ curr: -1,
+ validRow: false,
+ it: nil,
+ err: nil,
}, nil
}
type kvs struct {
t *tableDb
- prefixes []string
+ keyRanges query_db.KeyRanges
curr int // current index into prefixes, -1 at start
validRow bool
currKey string
@@ -433,11 +432,16 @@
if s.curr == -1 {
s.curr++
}
- for s.curr < len(s.prefixes) {
+ for s.curr < len(s.keyRanges) {
if s.it == nil {
- start := prefixutil.PrefixRangeStart(s.prefixes[s.curr])
- limit := prefixutil.PrefixRangeLimit(s.prefixes[s.curr])
- s.it = s.t.qdb.st.Scan(util.ScanRangeArgs(util.JoinKeyParts(util.RowPrefix, s.t.req.name), string(start), string(limit)))
+ start := s.keyRanges[s.curr].Start
+ limit := s.keyRanges[s.curr].Limit
+ // 0-255 means examine all rows
+ if start == string([]byte{0}) && limit == string([]byte{255}) {
+ start = ""
+ limit = ""
+ }
+ s.it = s.t.qdb.st.Scan(util.ScanRangeArgs(util.JoinKeyParts(util.RowPrefix, s.t.req.name), start, limit))
}
if s.it.Advance() {
// key
@@ -490,8 +494,8 @@
s.it.Cancel()
s.it = nil
}
- // set curr to end of prefixes so Advance will return false
- s.curr = len(s.prefixes)
+ // set curr to end of keyRanges so Advance will return false
+ s.curr = len(s.keyRanges)
}
////////////////////////////////////////