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

Side by Side Diff: impl/memory/datastore_data.go

Issue 1372473002: Add the ability to disable special automatic entities in impl/memory (Closed) Base URL: https://github.com/luci/gae.git@master
Patch Set: add more docstring Created 5 years, 2 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 | « impl/memory/datastore.go ('k') | impl/memory/datastore_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 memory 5 package memory
6 6
7 import ( 7 import (
8 "bytes" 8 "bytes"
9 "fmt" 9 "fmt"
10 "sync" 10 "sync"
(...skipping 12 matching lines...) Expand all
23 // See README.md for head schema. 23 // See README.md for head schema.
24 head *memStore 24 head *memStore
25 snap *memStore 25 snap *memStore
26 // For testing, see SetTransactionRetryCount. 26 // For testing, see SetTransactionRetryCount.
27 txnFakeRetry int 27 txnFakeRetry int
28 // true means that head always == snap 28 // true means that head always == snap
29 consistent bool 29 consistent bool
30 // true means that queries with insufficent indexes will pause to add th em 30 // true means that queries with insufficent indexes will pause to add th em
31 // and then continue instead of failing. 31 // and then continue instead of failing.
32 autoIndex bool 32 autoIndex bool
33 // true means that all of the __...__ keys which are normally automatica lly
34 // maintained will be omitted. This also means that Put with an incomple te
35 // key will become an error.
36 disableSpecialEntities bool
33 } 37 }
34 38
35 var ( 39 var (
36 _ = memContextObj((*dataStoreData)(nil)) 40 _ = memContextObj((*dataStoreData)(nil))
37 _ = sync.Locker((*dataStoreData)(nil)) 41 _ = sync.Locker((*dataStoreData)(nil))
38 ) 42 )
39 43
40 func newDataStoreData() *dataStoreData { 44 func newDataStoreData() *dataStoreData {
41 head := newMemStore() 45 head := newMemStore()
42 return &dataStoreData{ 46 return &dataStoreData{
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 d.rwlock.RUnlock() 99 d.rwlock.RUnlock()
96 100
97 if !ai { 101 if !ai {
98 return false 102 return false
99 } 103 }
100 104
101 d.addIndexes(mi.ns, []*ds.IndexDefinition{mi.Missing}) 105 d.addIndexes(mi.ns, []*ds.IndexDefinition{mi.Missing})
102 return true 106 return true
103 } 107 }
104 108
109 func (d *dataStoreData) setDisableSpecialEntities(enabled bool) {
110 d.Lock()
111 defer d.Unlock()
112 d.disableSpecialEntities = true
113 }
114
115 func (d *dataStoreData) getDisableSpecialEntities() bool {
116 d.rwlock.RLock()
117 defer d.rwlock.RUnlock()
118 return d.disableSpecialEntities
119 }
120
105 func (d *dataStoreData) getQuerySnaps(consistent bool) (idx, head *memStore) { 121 func (d *dataStoreData) getQuerySnaps(consistent bool) (idx, head *memStore) {
106 d.rwlock.RLock() 122 d.rwlock.RLock()
107 defer d.rwlock.RUnlock() 123 defer d.rwlock.RUnlock()
108 if d.consistent { 124 if d.consistent {
109 // snap is already a consistent snapshot of head 125 // snap is already a consistent snapshot of head
110 return d.snap, d.snap 126 return d.snap, d.snap
111 } 127 }
112 128
113 head = d.head.Snapshot() 129 head = d.head.Snapshot()
114 if consistent { 130 if consistent {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 defer d.Unlock() 209 defer d.Unlock()
194 210
195 coll := "ents:" + ns 211 coll := "ents:" + ns
196 ents := d.head.GetCollection(coll) 212 ents := d.head.GetCollection(coll)
197 if ents == nil { 213 if ents == nil {
198 ents = d.head.SetCollection(coll, nil) 214 ents = d.head.SetCollection(coll, nil)
199 } 215 }
200 return ents 216 return ents
201 } 217 }
202 218
203 func (d *dataStoreData) allocateIDs(incomplete *ds.Key, n int) int64 { 219 func (d *dataStoreData) allocateIDs(incomplete *ds.Key, n int) (int64, error) {
204 ents := d.mutableEnts(incomplete.Namespace()) 220 ents := d.mutableEnts(incomplete.Namespace())
205 221
206 d.Lock() 222 d.Lock()
207 defer d.Unlock() 223 defer d.Unlock()
208 return d.allocateIDsLocked(ents, incomplete, n) 224 return d.allocateIDsLocked(ents, incomplete, n)
209 } 225 }
210 226
211 func (d *dataStoreData) allocateIDsLocked(ents *memCollection, incomplete *ds.Ke y, n int) int64 { 227 func (d *dataStoreData) allocateIDsLocked(ents *memCollection, incomplete *ds.Ke y, n int) (int64, error) {
228 » if d.disableSpecialEntities {
229 » » return 0, errors.New("disableSpecialEntities is true so allocate IDs is disabled")
230 » }
231
212 idKey := []byte(nil) 232 idKey := []byte(nil)
213 if incomplete.Parent() == nil { 233 if incomplete.Parent() == nil {
214 idKey = rootIDsKey(incomplete.Kind()) 234 idKey = rootIDsKey(incomplete.Kind())
215 } else { 235 } else {
216 idKey = groupIDsKey(incomplete) 236 idKey = groupIDsKey(incomplete)
217 } 237 }
218 » return incrementLocked(ents, idKey, n) 238 » return incrementLocked(ents, idKey, n), nil
219 } 239 }
220 240
221 func (d *dataStoreData) fixKeyLocked(ents *memCollection, key *ds.Key) *ds.Key { 241 func (d *dataStoreData) fixKeyLocked(ents *memCollection, key *ds.Key) (*ds.Key, error) {
222 if key.Incomplete() { 242 if key.Incomplete() {
223 » » id := d.allocateIDsLocked(ents, key, 1) 243 » » id, err := d.allocateIDsLocked(ents, key, 1)
244 » » if err != nil {
245 » » » return key, err
246 » » }
224 key = ds.NewKey(key.AppID(), key.Namespace(), key.Kind(), "", id , key.Parent()) 247 key = ds.NewKey(key.AppID(), key.Namespace(), key.Kind(), "", id , key.Parent())
225 } 248 }
226 » return key 249 » return key, nil
227 } 250 }
228 251
229 func (d *dataStoreData) putMulti(keys []*ds.Key, vals []ds.PropertyMap, cb ds.Pu tMultiCB) { 252 func (d *dataStoreData) putMulti(keys []*ds.Key, vals []ds.PropertyMap, cb ds.Pu tMultiCB) {
230 ns := keys[0].Namespace() 253 ns := keys[0].Namespace()
231 ents := d.mutableEnts(ns) 254 ents := d.mutableEnts(ns)
232 255
233 for i, k := range keys { 256 for i, k := range keys {
234 pmap, _ := vals[i].Save(false) 257 pmap, _ := vals[i].Save(false)
235 dataBytes := serialize.ToBytes(pmap) 258 dataBytes := serialize.ToBytes(pmap)
236 259
237 k, err := func() (ret *ds.Key, err error) { 260 k, err := func() (ret *ds.Key, err error) {
238 d.Lock() 261 d.Lock()
239 defer d.Unlock() 262 defer d.Unlock()
240 263
241 » » » ret = d.fixKeyLocked(ents, k) 264 » » » ret, err = d.fixKeyLocked(ents, k)
242 » » » incrementLocked(ents, groupMetaKey(ret), 1) 265 » » » if err != nil {
266 » » » » return
267 » » » }
268 » » » if !d.disableSpecialEntities {
269 » » » » incrementLocked(ents, groupMetaKey(ret), 1)
270 » » » }
243 271
244 old := ents.Get(keyBytes(ret)) 272 old := ents.Get(keyBytes(ret))
245 oldPM := ds.PropertyMap(nil) 273 oldPM := ds.PropertyMap(nil)
246 if old != nil { 274 if old != nil {
247 if oldPM, err = rpmWoCtx(old, ns); err != nil { 275 if oldPM, err = rpmWoCtx(old, ns); err != nil {
248 return 276 return
249 } 277 }
250 } 278 }
251 updateIndexes(d.head, ret, oldPM, pmap) 279 updateIndexes(d.head, ret, oldPM, pmap)
252 ents.Set(keyBytes(ret), dataBytes) 280 ents.Set(keyBytes(ret), dataBytes)
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 ents := d.mutableEnts(ns) 325 ents := d.mutableEnts(ns)
298 326
299 if ents != nil { 327 if ents != nil {
300 for _, k := range keys { 328 for _, k := range keys {
301 err := func() error { 329 err := func() error {
302 kb := keyBytes(k) 330 kb := keyBytes(k)
303 331
304 d.Lock() 332 d.Lock()
305 defer d.Unlock() 333 defer d.Unlock()
306 334
307 » » » » incrementLocked(ents, groupMetaKey(k), 1) 335 » » » » if !d.disableSpecialEntities {
336 » » » » » incrementLocked(ents, groupMetaKey(k), 1 )
337 » » » » }
308 if old := ents.Get(kb); old != nil { 338 if old := ents.Get(kb); old != nil {
309 oldPM, err := rpmWoCtx(old, ns) 339 oldPM, err := rpmWoCtx(old, ns)
310 if err != nil { 340 if err != nil {
311 return err 341 return err
312 } 342 }
313 updateIndexes(d.head, k, oldPM, nil) 343 updateIndexes(d.head, k, oldPM, nil)
314 ents.Delete(kb) 344 ents.Delete(kb)
315 if d.consistent { 345 if d.consistent {
316 d.snap = d.head.Snapshot() 346 d.snap = d.head.Snapshot()
317 } 347 }
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 td.muts[rk] = append(td.muts[rk], txnMutation{key, data}) 507 td.muts[rk] = append(td.muts[rk], txnMutation{key, data})
478 } 508 }
479 509
480 return nil 510 return nil
481 } 511 }
482 512
483 func (td *txnDataStoreData) putMulti(keys []*ds.Key, vals []ds.PropertyMap, cb d s.PutMultiCB) { 513 func (td *txnDataStoreData) putMulti(keys []*ds.Key, vals []ds.PropertyMap, cb d s.PutMultiCB) {
484 ents := td.parent.mutableEnts(keys[0].Namespace()) 514 ents := td.parent.mutableEnts(keys[0].Namespace())
485 515
486 for i, k := range keys { 516 for i, k := range keys {
487 » » func() { 517 » » err := func() (err error) {
488 td.parent.Lock() 518 td.parent.Lock()
489 defer td.parent.Unlock() 519 defer td.parent.Unlock()
490 » » » k = td.parent.fixKeyLocked(ents, k) 520 » » » k, err = td.parent.fixKeyLocked(ents, k)
521 » » » return
491 }() 522 }()
492 » » err := td.writeMutation(false, k, vals[i]) 523 » » if err == nil {
524 » » » err = td.writeMutation(false, k, vals[i])
525 » » }
493 if cb != nil { 526 if cb != nil {
494 cb(k, err) 527 cb(k, err)
495 } 528 }
496 } 529 }
497 } 530 }
498 531
499 func (td *txnDataStoreData) getMulti(keys []*ds.Key, cb ds.GetMultiCB) error { 532 func (td *txnDataStoreData) getMulti(keys []*ds.Key, cb ds.GetMultiCB) error {
500 return getMultiInner(keys, cb, func() (*memCollection, error) { 533 return getMultiInner(keys, cb, func() (*memCollection, error) {
501 err := error(nil) 534 err := error(nil)
502 for _, key := range keys { 535 for _, key := range keys {
(...skipping 22 matching lines...) Expand all
525 558
526 func rpmWoCtx(data []byte, ns string) (ds.PropertyMap, error) { 559 func rpmWoCtx(data []byte, ns string) (ds.PropertyMap, error) {
527 return serialize.ReadPropertyMap(bytes.NewBuffer(data), 560 return serialize.ReadPropertyMap(bytes.NewBuffer(data),
528 serialize.WithoutContext, globalAppID, ns) 561 serialize.WithoutContext, globalAppID, ns)
529 } 562 }
530 563
531 func rpm(data []byte) (ds.PropertyMap, error) { 564 func rpm(data []byte) (ds.PropertyMap, error) {
532 return serialize.ReadPropertyMap(bytes.NewBuffer(data), 565 return serialize.ReadPropertyMap(bytes.NewBuffer(data),
533 serialize.WithContext, "", "") 566 serialize.WithContext, "", "")
534 } 567 }
OLDNEW
« no previous file with comments | « impl/memory/datastore.go ('k') | impl/memory/datastore_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698