Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(287)

Unified Diff: service/datastore/index.go

Issue 1292913002: Split off serialization and key functions to their own packages. (Closed) Base URL: https://github.com/luci/gae.git@make_queries_better
Patch Set: rebase Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « service/datastore/generic_key.go ('k') | service/datastore/index_test.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: service/datastore/index.go
diff --git a/service/datastore/index.go b/service/datastore/index.go
index c9589f662abb904bfa27664356846313dda127e1..0f1aaca469903e6cef8ba46bda5073dbb22f61f9 100644
--- a/service/datastore/index.go
+++ b/service/datastore/index.go
@@ -8,6 +8,8 @@ import (
"bytes"
)
+const MaxIndexColumns = 64
+
type IndexDirection bool
const (
@@ -21,25 +23,91 @@ type IndexColumn struct {
Direction IndexDirection
}
+func (i IndexColumn) cmp(o IndexColumn) int {
+ // sort ascending first
+ if i.Direction == ASCENDING && o.Direction == DESCENDING {
+ return -1
+ } else if i.Direction == DESCENDING && o.Direction == ASCENDING {
+ return 1
+ }
+ return cmpString(i.Property, o.Property)()
+}
+
type IndexDefinition struct {
Kind string
Ancestor bool
SortBy []IndexColumn
}
+// Yeah who needs templates, right?
+// <flames>This is fine.</flames>
+
+func cmpBool(a, b bool) func() int {
+ return func() int {
+ if a == b {
+ return 0
+ }
+ if a && !b { // >
+ return 1
+ }
+ return -1
+ }
+}
+
+func cmpInt(a, b int) func() int {
+ return func() int {
+ if a == b {
+ return 0
+ }
+ if a > b {
+ return 1
+ }
+ return -1
+ }
+}
+
+func cmpString(a, b string) func() int {
+ return func() int {
+ if a == b {
+ return 0
+ }
+ if a > b {
+ return 1
+ }
+ return -1
+ }
+}
+
func (i *IndexDefinition) Less(o *IndexDefinition) bool {
- // yes, this is inefficient.... however I'm disinclined to care, because the
- // actual comparison function is really ugly, and sorting IndexDefintions is
- // not performance critical. If you're here because you profiled this and
- // determined that it's a bottleneck, then feel free to rewrite :).
- //
- // At the time of writing, this function is only used during the tests of
- // impl/memory and this package.
- ibuf, obuf := &bytes.Buffer{}, &bytes.Buffer{}
- // we know these can't return an error because we're using bytes.Buffer
- _ = i.Write(ibuf)
- _ = o.Write(obuf)
- return bytes.Compare(ibuf.Bytes(), obuf.Bytes()) < 0
+ decide := func(v int) (ret, keepGoing bool) {
+ if v > 0 {
+ return false, false
+ }
+ if v < 0 {
+ return true, false
+ }
+ return false, true
+ }
+
+ factors := []func() int{
+ cmpBool(i.Builtin(), o.Builtin()),
+ cmpString(i.Kind, o.Kind),
+ cmpBool(i.Ancestor, o.Ancestor),
+ cmpInt(len(i.SortBy), len(o.SortBy)),
+ }
+ for _, f := range factors {
+ ret, keepGoing := decide(f())
+ if !keepGoing {
+ return ret
+ }
+ }
+ for idx := range i.SortBy {
+ ret, keepGoing := decide(i.SortBy[idx].cmp(o.SortBy[idx]))
+ if !keepGoing {
+ return ret
+ }
+ }
+ return false
}
func (i *IndexDefinition) Builtin() bool {
« no previous file with comments | « service/datastore/generic_key.go ('k') | service/datastore/index_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698