OLD | NEW |
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 memory | 5 package memory |
6 | 6 |
7 import ( | 7 import ( |
8 "bytes" | 8 "bytes" |
9 "errors" | 9 "errors" |
10 "fmt" | 10 "fmt" |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 return nil | 92 return nil |
93 } | 93 } |
94 return s.cb(key, nil, gc) | 94 return s.cb(key, nil, gc) |
95 } | 95 } |
96 | 96 |
97 type normalStrategy struct { | 97 type normalStrategy struct { |
98 cb ds.RawRunCB | 98 cb ds.RawRunCB |
99 | 99 |
100 aid string | 100 aid string |
101 ns string | 101 ns string |
102 » head *memCollection | 102 » head memCollection |
103 dedup stringset.Set | 103 dedup stringset.Set |
104 } | 104 } |
105 | 105 |
106 func newNormalStrategy(aid, ns string, cb ds.RawRunCB, head *memStore) queryStra
tegy { | 106 func newNormalStrategy(aid, ns string, cb ds.RawRunCB, head memStore) queryStrat
egy { |
107 coll := head.GetCollection("ents:" + ns) | 107 coll := head.GetCollection("ents:" + ns) |
108 if coll == nil { | 108 if coll == nil { |
109 return nil | 109 return nil |
110 } | 110 } |
111 return &normalStrategy{cb, aid, ns, coll, stringset.New(0)} | 111 return &normalStrategy{cb, aid, ns, coll, stringset.New(0)} |
112 } | 112 } |
113 | 113 |
114 func (s *normalStrategy) handle(rawData [][]byte, _ []ds.Property, key *ds.Key,
gc func() (ds.Cursor, error)) error { | 114 func (s *normalStrategy) handle(rawData [][]byte, _ []ds.Property, key *ds.Key,
gc func() (ds.Cursor, error)) error { |
115 rawKey := rawData[len(rawData)-1] | 115 rawKey := rawData[len(rawData)-1] |
116 if !s.dedup.Add(string(rawKey)) { | 116 if !s.dedup.Add(string(rawKey)) { |
117 return nil | 117 return nil |
118 } | 118 } |
119 | 119 |
120 rawEnt := s.head.Get(rawKey) | 120 rawEnt := s.head.Get(rawKey) |
121 if rawEnt == nil { | 121 if rawEnt == nil { |
122 // entity doesn't exist at head | 122 // entity doesn't exist at head |
123 return nil | 123 return nil |
124 } | 124 } |
125 pm, err := serialize.ReadPropertyMap(bytes.NewBuffer(rawEnt), serialize.
WithoutContext, s.aid, s.ns) | 125 pm, err := serialize.ReadPropertyMap(bytes.NewBuffer(rawEnt), serialize.
WithoutContext, s.aid, s.ns) |
126 memoryCorruption(err) | 126 memoryCorruption(err) |
127 | 127 |
128 return s.cb(key, pm, gc) | 128 return s.cb(key, pm, gc) |
129 } | 129 } |
130 | 130 |
131 func pickQueryStrategy(fq *ds.FinalizedQuery, rq *reducedQuery, cb ds.RawRunCB,
head *memStore) queryStrategy { | 131 func pickQueryStrategy(fq *ds.FinalizedQuery, rq *reducedQuery, cb ds.RawRunCB,
head memStore) queryStrategy { |
132 if fq.KeysOnly() { | 132 if fq.KeysOnly() { |
133 return &keysOnlyStrategy{cb, stringset.New(0)} | 133 return &keysOnlyStrategy{cb, stringset.New(0)} |
134 } | 134 } |
135 if len(fq.Project()) > 0 { | 135 if len(fq.Project()) > 0 { |
136 return newProjectionStrategy(fq, rq, cb) | 136 return newProjectionStrategy(fq, rq, cb) |
137 } | 137 } |
138 return newNormalStrategy(rq.aid, rq.ns, cb, head) | 138 return newNormalStrategy(rq.aid, rq.ns, cb, head) |
139 } | 139 } |
140 | 140 |
141 func parseSuffix(aid, ns string, suffixFormat []ds.IndexColumn, suffix []byte, c
ount int) (raw [][]byte, decoded []ds.Property) { | 141 func parseSuffix(aid, ns string, suffixFormat []ds.IndexColumn, suffix []byte, c
ount int) (raw [][]byte, decoded []ds.Property) { |
(...skipping 16 matching lines...) Expand all Loading... |
158 raw[i] = suffix[:offset] | 158 raw[i] = suffix[:offset] |
159 suffix = suffix[offset:] | 159 suffix = suffix[offset:] |
160 if needInvert { | 160 if needInvert { |
161 raw[i] = serialize.Invert(raw[i]) | 161 raw[i] = serialize.Invert(raw[i]) |
162 } | 162 } |
163 } | 163 } |
164 | 164 |
165 return | 165 return |
166 } | 166 } |
167 | 167 |
168 func countQuery(fq *ds.FinalizedQuery, aid, ns string, isTxn bool, idx, head *me
mStore) (ret int64, err error) { | 168 func countQuery(fq *ds.FinalizedQuery, aid, ns string, isTxn bool, idx, head mem
Store) (ret int64, err error) { |
169 if len(fq.Project()) == 0 && !fq.KeysOnly() { | 169 if len(fq.Project()) == 0 && !fq.KeysOnly() { |
170 fq, err = fq.Original().KeysOnly(true).Finalize() | 170 fq, err = fq.Original().KeysOnly(true).Finalize() |
171 if err != nil { | 171 if err != nil { |
172 return | 172 return |
173 } | 173 } |
174 } | 174 } |
175 err = executeQuery(fq, aid, ns, isTxn, idx, head, func(_ *ds.Key, _ ds.P
ropertyMap, _ ds.CursorCB) error { | 175 err = executeQuery(fq, aid, ns, isTxn, idx, head, func(_ *ds.Key, _ ds.P
ropertyMap, _ ds.CursorCB) error { |
176 ret++ | 176 ret++ |
177 return nil | 177 return nil |
178 }) | 178 }) |
179 return | 179 return |
180 } | 180 } |
181 | 181 |
182 func executeNamespaceQuery(fq *ds.FinalizedQuery, aid string, head *memStore, cb
ds.RawRunCB) error { | 182 func executeNamespaceQuery(fq *ds.FinalizedQuery, aid string, head memStore, cb
ds.RawRunCB) error { |
183 // these objects have no properties, so any filters on properties cause
an | 183 // these objects have no properties, so any filters on properties cause
an |
184 // empty result. | 184 // empty result. |
185 if len(fq.EqFilters()) > 0 || len(fq.Project()) > 0 || len(fq.Orders())
> 1 { | 185 if len(fq.EqFilters()) > 0 || len(fq.Project()) > 0 || len(fq.Orders())
> 1 { |
186 return nil | 186 return nil |
187 } | 187 } |
188 if !(fq.IneqFilterProp() == "" || fq.IneqFilterProp() == "__key__") { | 188 if !(fq.IneqFilterProp() == "" || fq.IneqFilterProp() == "__key__") { |
189 return nil | 189 return nil |
190 } | 190 } |
191 limit, hasLimit := fq.Limit() | 191 limit, hasLimit := fq.Limit() |
192 offset, hasOffset := fq.Offset() | 192 offset, hasOffset := fq.Offset() |
(...skipping 23 matching lines...) Expand all Loading... |
216 } else { | 216 } else { |
217 k = ds.MakeKey(aid, "", "__namespace__", ns) | 217 k = ds.MakeKey(aid, "", "__namespace__", ns) |
218 } | 218 } |
219 if err := cb(k, nil, cursFn); err != nil { | 219 if err := cb(k, nil, cursFn); err != nil { |
220 return err | 220 return err |
221 } | 221 } |
222 } | 222 } |
223 return nil | 223 return nil |
224 } | 224 } |
225 | 225 |
226 func executeQuery(fq *ds.FinalizedQuery, aid, ns string, isTxn bool, idx, head *
memStore, cb ds.RawRunCB) error { | 226 func executeQuery(fq *ds.FinalizedQuery, aid, ns string, isTxn bool, idx, head m
emStore, cb ds.RawRunCB) error { |
227 rq, err := reduce(fq, aid, ns, isTxn) | 227 rq, err := reduce(fq, aid, ns, isTxn) |
228 if err == ds.ErrNullQuery { | 228 if err == ds.ErrNullQuery { |
229 return nil | 229 return nil |
230 } | 230 } |
231 if err != nil { | 231 if err != nil { |
232 return err | 232 return err |
233 } | 233 } |
234 | 234 |
235 if rq.kind == "__namespace__" { | 235 if rq.kind == "__namespace__" { |
236 return executeNamespaceQuery(fq, aid, head, cb) | 236 return executeNamespaceQuery(fq, aid, head, cb) |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 keyProp := decodedProps[len(decodedProps)-1] | 291 keyProp := decodedProps[len(decodedProps)-1] |
292 if keyProp.Type() != ds.PTKey { | 292 if keyProp.Type() != ds.PTKey { |
293 impossible(fmt.Errorf("decoded index row doesn't end wit
h a Key: %#v", keyProp)) | 293 impossible(fmt.Errorf("decoded index row doesn't end wit
h a Key: %#v", keyProp)) |
294 } | 294 } |
295 | 295 |
296 return strategy.handle( | 296 return strategy.handle( |
297 rawData, decodedProps, keyProp.Value().(*ds.Key), | 297 rawData, decodedProps, keyProp.Value().(*ds.Key), |
298 getCursorFn(suffix)) | 298 getCursorFn(suffix)) |
299 }) | 299 }) |
300 } | 300 } |
OLD | NEW |