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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « service/datastore/generic_key.go ('k') | service/datastore/index_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package datastore 5 package datastore
6 6
7 import ( 7 import (
8 "bytes" 8 "bytes"
9 ) 9 )
10 10
11 const MaxIndexColumns = 64
12
11 type IndexDirection bool 13 type IndexDirection bool
12 14
13 const ( 15 const (
14 // ASCENDING is false so that it's the default (zero) value. 16 // ASCENDING is false so that it's the default (zero) value.
15 ASCENDING IndexDirection = false 17 ASCENDING IndexDirection = false
16 DESCENDING = true 18 DESCENDING = true
17 ) 19 )
18 20
19 type IndexColumn struct { 21 type IndexColumn struct {
20 Property string 22 Property string
21 Direction IndexDirection 23 Direction IndexDirection
22 } 24 }
23 25
26 func (i IndexColumn) cmp(o IndexColumn) int {
27 // sort ascending first
28 if i.Direction == ASCENDING && o.Direction == DESCENDING {
29 return -1
30 } else if i.Direction == DESCENDING && o.Direction == ASCENDING {
31 return 1
32 }
33 return cmpString(i.Property, o.Property)()
34 }
35
24 type IndexDefinition struct { 36 type IndexDefinition struct {
25 Kind string 37 Kind string
26 Ancestor bool 38 Ancestor bool
27 SortBy []IndexColumn 39 SortBy []IndexColumn
28 } 40 }
29 41
42 // Yeah who needs templates, right?
43 // <flames>This is fine.</flames>
44
45 func cmpBool(a, b bool) func() int {
46 return func() int {
47 if a == b {
48 return 0
49 }
50 if a && !b { // >
51 return 1
52 }
53 return -1
54 }
55 }
56
57 func cmpInt(a, b int) func() int {
58 return func() int {
59 if a == b {
60 return 0
61 }
62 if a > b {
63 return 1
64 }
65 return -1
66 }
67 }
68
69 func cmpString(a, b string) func() int {
70 return func() int {
71 if a == b {
72 return 0
73 }
74 if a > b {
75 return 1
76 }
77 return -1
78 }
79 }
80
30 func (i *IndexDefinition) Less(o *IndexDefinition) bool { 81 func (i *IndexDefinition) Less(o *IndexDefinition) bool {
31 » // yes, this is inefficient.... however I'm disinclined to care, because the 82 » decide := func(v int) (ret, keepGoing bool) {
32 » // actual comparison function is really ugly, and sorting IndexDefintion s is 83 » » if v > 0 {
33 » // not performance critical. If you're here because you profiled this an d 84 » » » return false, false
34 » // determined that it's a bottleneck, then feel free to rewrite :). 85 » » }
35 » // 86 » » if v < 0 {
36 » // At the time of writing, this function is only used during the tests o f 87 » » » return true, false
37 » // impl/memory and this package. 88 » » }
38 » ibuf, obuf := &bytes.Buffer{}, &bytes.Buffer{} 89 » » return false, true
39 » // we know these can't return an error because we're using bytes.Buffer 90 » }
40 » _ = i.Write(ibuf) 91
41 » _ = o.Write(obuf) 92 » factors := []func() int{
42 » return bytes.Compare(ibuf.Bytes(), obuf.Bytes()) < 0 93 » » cmpBool(i.Builtin(), o.Builtin()),
94 » » cmpString(i.Kind, o.Kind),
95 » » cmpBool(i.Ancestor, o.Ancestor),
96 » » cmpInt(len(i.SortBy), len(o.SortBy)),
97 » }
98 » for _, f := range factors {
99 » » ret, keepGoing := decide(f())
100 » » if !keepGoing {
101 » » » return ret
102 » » }
103 » }
104 » for idx := range i.SortBy {
105 » » ret, keepGoing := decide(i.SortBy[idx].cmp(o.SortBy[idx]))
106 » » if !keepGoing {
107 » » » return ret
108 » » }
109 » }
110 » return false
43 } 111 }
44 112
45 func (i *IndexDefinition) Builtin() bool { 113 func (i *IndexDefinition) Builtin() bool {
46 return !i.Ancestor && len(i.SortBy) <= 1 114 return !i.Ancestor && len(i.SortBy) <= 1
47 } 115 }
48 116
49 func (i *IndexDefinition) Compound() bool { 117 func (i *IndexDefinition) Compound() bool {
50 if i.Kind == "" || len(i.SortBy) <= 1 { 118 if i.Kind == "" || len(i.SortBy) <= 1 {
51 return false 119 return false
52 } 120 }
(...skipping 27 matching lines...) Expand all
80 return ret.String() 148 return ret.String()
81 } 149 }
82 150
83 func IndexBuiltinQueryPrefix() []byte { 151 func IndexBuiltinQueryPrefix() []byte {
84 return []byte{0} 152 return []byte{0}
85 } 153 }
86 154
87 func IndexComplexQueryPrefix() []byte { 155 func IndexComplexQueryPrefix() []byte {
88 return []byte{1} 156 return []byte{1}
89 } 157 }
OLDNEW
« 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