| Index: impl/memory/datastore_data.go
|
| diff --git a/impl/memory/datastore_data.go b/impl/memory/datastore_data.go
|
| index 68a1642bd86ef9f6daa926a9118552b570e5636d..ad8515ee62919e1cf7a84fe942870127170a4043 100644
|
| --- a/impl/memory/datastore_data.go
|
| +++ b/impl/memory/datastore_data.go
|
| @@ -215,12 +215,48 @@ func incrementLocked(ents memCollection, key []byte, amt int) int64 {
|
| return ret
|
| }
|
|
|
| -func (d *dataStoreData) allocateIDs(incomplete *ds.Key, n int) (int64, error) {
|
| - d.Lock()
|
| - defer d.Unlock()
|
| +func (d *dataStoreData) allocateIDs(keys []*ds.Key, cb ds.NewKeyCB) error {
|
| + // Map keys by entity type.
|
| + entityMap := make(map[string][]int)
|
| + for i, key := range keys {
|
| + ks := key.String()
|
| + entityMap[ks] = append(entityMap[ks], i)
|
| + }
|
| +
|
| + // Allocate IDs for our keys. We use an inline function so we can ensure that
|
| + // the lock is released.
|
| + err := func() error {
|
| + d.Lock()
|
| + defer d.Unlock()
|
| +
|
| + for _, idxs := range entityMap {
|
| + baseKey := keys[idxs[0]]
|
| +
|
| + ents := d.head.GetOrCreateCollection("ents:" + baseKey.Namespace())
|
| +
|
| + // Allocate IDs. The only possible error is when disableSpecialEntities is
|
| + // true, in which case we will return a full method error instead of
|
| + // individual callback errors.
|
| + start, err := d.allocateIDsLocked(ents, baseKey, len(idxs))
|
| + if err != nil {
|
| + return err
|
| + }
|
|
|
| - ents := d.head.GetOrCreateCollection("ents:" + incomplete.Namespace())
|
| - return d.allocateIDsLocked(ents, incomplete, n)
|
| + for i, idx := range idxs {
|
| + keys[idx] = baseKey.WithID("", start+int64(i))
|
| + }
|
| + }
|
| + return nil
|
| + }()
|
| + if err != nil {
|
| + return err
|
| + }
|
| +
|
| + // Execute Callbacks.
|
| + for _, key := range keys {
|
| + cb(key, nil)
|
| + }
|
| + return nil
|
| }
|
|
|
| func (d *dataStoreData) allocateIDsLocked(ents memCollection, incomplete *ds.Key, n int) (int64, error) {
|
| @@ -238,7 +274,7 @@ func (d *dataStoreData) allocateIDsLocked(ents memCollection, incomplete *ds.Key
|
| }
|
|
|
| func (d *dataStoreData) fixKeyLocked(ents memCollection, key *ds.Key) (*ds.Key, error) {
|
| - if key.Incomplete() {
|
| + if key.IsIncomplete() {
|
| id, err := d.allocateIDsLocked(ents, key, 1)
|
| if err != nil {
|
| return key, err
|
| @@ -248,7 +284,7 @@ func (d *dataStoreData) fixKeyLocked(ents memCollection, key *ds.Key) (*ds.Key,
|
| return key, nil
|
| }
|
|
|
| -func (d *dataStoreData) putMulti(keys []*ds.Key, vals []ds.PropertyMap, cb ds.PutMultiCB) error {
|
| +func (d *dataStoreData) putMulti(keys []*ds.Key, vals []ds.PropertyMap, cb ds.NewKeyCB) error {
|
| ns := keys[0].Namespace()
|
|
|
| for i, k := range keys {
|
| @@ -517,7 +553,7 @@ func (td *txnDataStoreData) writeMutation(getOnly bool, key *ds.Key, data ds.Pro
|
| return nil
|
| }
|
|
|
| -func (td *txnDataStoreData) putMulti(keys []*ds.Key, vals []ds.PropertyMap, cb ds.PutMultiCB) {
|
| +func (td *txnDataStoreData) putMulti(keys []*ds.Key, vals []ds.PropertyMap, cb ds.NewKeyCB) {
|
| ns := keys[0].Namespace()
|
|
|
| for i, k := range keys {
|
|
|