| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |