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

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

Issue 2007123002: datastore: Update AllocateIDs to take keys. (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/gae@master
Patch Set: Rebase, comments. Created 4 years, 6 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 LUCI Authors. All rights reserved. 1 // Copyright 2015 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0 2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file. 3 // that can be 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 "strings" 10 "strings"
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 if amt <= 0 { 208 if amt <= 0 {
209 panic(fmt.Errorf("incrementLocked called with bad `amt`: %d", am t)) 209 panic(fmt.Errorf("incrementLocked called with bad `amt`: %d", am t))
210 } 210 }
211 ret := curVersion(ents, key) + 1 211 ret := curVersion(ents, key) + 1
212 ents.Set(key, serialize.ToBytes(ds.PropertyMap{ 212 ents.Set(key, serialize.ToBytes(ds.PropertyMap{
213 "__version__": {ds.MkPropertyNI(ret + int64(amt-1))}, 213 "__version__": {ds.MkPropertyNI(ret + int64(amt-1))},
214 })) 214 }))
215 return ret 215 return ret
216 } 216 }
217 217
218 func (d *dataStoreData) allocateIDs(incomplete *ds.Key, n int) (int64, error) { 218 func (d *dataStoreData) allocateIDs(keys []*ds.Key, cb ds.NewKeyCB) error {
219 » d.Lock() 219 » // Map keys by entity type.
220 » defer d.Unlock() 220 » entityMap := make(map[string][]int)
221 » for i, key := range keys {
222 » » ks := key.String()
223 » » entityMap[ks] = append(entityMap[ks], i)
224 » }
221 225
222 » ents := d.head.GetOrCreateCollection("ents:" + incomplete.Namespace()) 226 » // Allocate IDs for our keys. We use an inline function so we can ensure that
223 » return d.allocateIDsLocked(ents, incomplete, n) 227 » // the lock is released.
228 » err := func() error {
229 » » d.Lock()
230 » » defer d.Unlock()
231
232 » » for _, idxs := range entityMap {
233 » » » baseKey := keys[idxs[0]]
234
235 » » » ents := d.head.GetOrCreateCollection("ents:" + baseKey.N amespace())
236
237 » » » // Allocate IDs. The only possible error is when disable SpecialEntities is
238 » » » // true, in which case we will return a full method erro r instead of
239 » » » // individual callback errors.
240 » » » start, err := d.allocateIDsLocked(ents, baseKey, len(idx s))
241 » » » if err != nil {
242 » » » » return err
243 » » » }
244
245 » » » for i, idx := range idxs {
246 » » » » keys[idx] = baseKey.WithID("", start+int64(i))
247 » » » }
248 » » }
249 » » return nil
250 » }()
251 » if err != nil {
252 » » return err
253 » }
254
255 » // Execute Callbacks.
256 » for _, key := range keys {
257 » » cb(key, nil)
258 » }
259 » return nil
224 } 260 }
225 261
226 func (d *dataStoreData) allocateIDsLocked(ents memCollection, incomplete *ds.Key , n int) (int64, error) { 262 func (d *dataStoreData) allocateIDsLocked(ents memCollection, incomplete *ds.Key , n int) (int64, error) {
227 if d.disableSpecialEntities { 263 if d.disableSpecialEntities {
228 return 0, errors.New("disableSpecialEntities is true so allocate IDs is disabled") 264 return 0, errors.New("disableSpecialEntities is true so allocate IDs is disabled")
229 } 265 }
230 266
231 idKey := []byte(nil) 267 idKey := []byte(nil)
232 if incomplete.Parent() == nil { 268 if incomplete.Parent() == nil {
233 idKey = rootIDsKey(incomplete.Kind()) 269 idKey = rootIDsKey(incomplete.Kind())
234 } else { 270 } else {
235 idKey = groupIDsKey(incomplete) 271 idKey = groupIDsKey(incomplete)
236 } 272 }
237 return incrementLocked(ents, idKey, n), nil 273 return incrementLocked(ents, idKey, n), nil
238 } 274 }
239 275
240 func (d *dataStoreData) fixKeyLocked(ents memCollection, key *ds.Key) (*ds.Key, error) { 276 func (d *dataStoreData) fixKeyLocked(ents memCollection, key *ds.Key) (*ds.Key, error) {
241 » if key.Incomplete() { 277 » if key.IsIncomplete() {
242 id, err := d.allocateIDsLocked(ents, key, 1) 278 id, err := d.allocateIDsLocked(ents, key, 1)
243 if err != nil { 279 if err != nil {
244 return key, err 280 return key, err
245 } 281 }
246 key = ds.NewKey(key.AppID(), key.Namespace(), key.Kind(), "", id , key.Parent()) 282 key = ds.NewKey(key.AppID(), key.Namespace(), key.Kind(), "", id , key.Parent())
247 } 283 }
248 return key, nil 284 return key, nil
249 } 285 }
250 286
251 func (d *dataStoreData) putMulti(keys []*ds.Key, vals []ds.PropertyMap, cb ds.Pu tMultiCB) error { 287 func (d *dataStoreData) putMulti(keys []*ds.Key, vals []ds.PropertyMap, cb ds.Ne wKeyCB) error {
252 ns := keys[0].Namespace() 288 ns := keys[0].Namespace()
253 289
254 for i, k := range keys { 290 for i, k := range keys {
255 pmap, _ := vals[i].Save(false) 291 pmap, _ := vals[i].Save(false)
256 dataBytes := serialize.ToBytes(pmap) 292 dataBytes := serialize.ToBytes(pmap)
257 293
258 k, err := func() (ret *ds.Key, err error) { 294 k, err := func() (ret *ds.Key, err error) {
259 d.Lock() 295 d.Lock()
260 defer d.Unlock() 296 defer d.Unlock()
261 297
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 } 546 }
511 td.muts[rk] = []txnMutation{} 547 td.muts[rk] = []txnMutation{}
512 } 548 }
513 if !getOnly { 549 if !getOnly {
514 td.muts[rk] = append(td.muts[rk], txnMutation{key, data}) 550 td.muts[rk] = append(td.muts[rk], txnMutation{key, data})
515 } 551 }
516 552
517 return nil 553 return nil
518 } 554 }
519 555
520 func (td *txnDataStoreData) putMulti(keys []*ds.Key, vals []ds.PropertyMap, cb d s.PutMultiCB) { 556 func (td *txnDataStoreData) putMulti(keys []*ds.Key, vals []ds.PropertyMap, cb d s.NewKeyCB) {
521 ns := keys[0].Namespace() 557 ns := keys[0].Namespace()
522 558
523 for i, k := range keys { 559 for i, k := range keys {
524 err := func() (err error) { 560 err := func() (err error) {
525 td.parent.Lock() 561 td.parent.Lock()
526 defer td.parent.Unlock() 562 defer td.parent.Unlock()
527 ents := td.parent.head.GetOrCreateCollection("ents:" + n s) 563 ents := td.parent.head.GetOrCreateCollection("ents:" + n s)
528 564
529 k, err = td.parent.fixKeyLocked(ents, k) 565 k, err = td.parent.fixKeyLocked(ents, k)
530 return 566 return
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
584 } 620 }
585 return namespaces 621 return namespaces
586 } 622 }
587 623
588 func trimPrefix(v, p string) (string, bool) { 624 func trimPrefix(v, p string) (string, bool) {
589 if strings.HasPrefix(v, p) { 625 if strings.HasPrefix(v, p) {
590 return v[len(p):], true 626 return v[len(p):], true
591 } 627 }
592 return v, false 628 return v, false
593 } 629 }
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