| Index: impl/memory/raw_datastore_data.go
|
| diff --git a/impl/memory/raw_datastore_data.go b/impl/memory/raw_datastore_data.go
|
| index 93a6bcb94f61961c9fea944812caa65786de1fe1..9b9b059db3b3c59fb151310e70225550afe8881b 100644
|
| --- a/impl/memory/raw_datastore_data.go
|
| +++ b/impl/memory/raw_datastore_data.go
|
| @@ -107,46 +107,14 @@ func (d *dataStoreData) entsKeyLocked(key rds.Key) (*memCollection, rds.Key) {
|
| return ents, key
|
| }
|
|
|
| -func (d *dataStoreData) put(ns string, key rds.Key, pls rds.PropertyLoadSaver) (rds.Key, error) {
|
| - keys, errs := d.putMulti(ns, []rds.Key{key}, []rds.PropertyLoadSaver{pls})
|
| - if errs == nil {
|
| - return keys[0], nil
|
| - }
|
| - return nil, errors.SingleError(errs)
|
| -}
|
| -
|
| -func (d *dataStoreData) putMulti(ns string, keys []rds.Key, plss []rds.PropertyLoadSaver) ([]rds.Key, error) {
|
| - pmaps, err := putMultiPrelim(ns, keys, plss)
|
| - if err != nil {
|
| - return nil, err
|
| - }
|
| - return d.putMultiInner(keys, pmaps)
|
| -}
|
| -
|
| -func putMultiPrelim(ns string, keys []rds.Key, plss []rds.PropertyLoadSaver) ([]rds.PropertyMap, error) {
|
| - err := multiValid(keys, plss, ns, true, false)
|
| - if err != nil {
|
| - return nil, err
|
| - }
|
| - pmaps := make([]rds.PropertyMap, len(keys))
|
| - lme := errors.LazyMultiError{Size: len(keys)}
|
| - for i, pls := range plss {
|
| - pm, err := pls.Save(false)
|
| - lme.Assign(i, err)
|
| - pmaps[i] = pm
|
| - }
|
| - return pmaps, lme.Get()
|
| -}
|
| -
|
| -func (d *dataStoreData) putMultiInner(keys []rds.Key, data []rds.PropertyMap) ([]rds.Key, error) {
|
| - retKeys := make([]rds.Key, len(keys))
|
| - lme := errors.LazyMultiError{Size: len(keys)}
|
| +func (d *dataStoreData) putMulti(keys []rds.Key, vals []rds.PropertyLoadSaver, cb rds.PutMultiCB) {
|
| for i, k := range keys {
|
| buf := &bytes.Buffer{}
|
| - data[i].Write(buf, rds.WithoutContext)
|
| + pmap := vals[i].(rds.PropertyMap)
|
| + pmap.Write(buf, rds.WithoutContext)
|
| dataBytes := buf.Bytes()
|
|
|
| - rKey, err := func() (ret rds.Key, err error) {
|
| + k, err := func() (ret rds.Key, err error) {
|
| d.rwlock.Lock()
|
| defer d.rwlock.Unlock()
|
|
|
| @@ -160,108 +128,82 @@ func (d *dataStoreData) putMultiInner(keys []rds.Key, data []rds.PropertyMap) ([
|
| return
|
| }
|
| }
|
| - updateIndicies(d.store, ret, oldPM, data[i])
|
| + updateIndicies(d.store, ret, oldPM, pmap)
|
| ents.Set(keyBytes(rds.WithoutContext, ret), dataBytes)
|
| return
|
| }()
|
| - lme.Assign(i, err)
|
| - retKeys[i] = rKey
|
| + if cb != nil {
|
| + cb(k, err)
|
| + }
|
| }
|
| - return retKeys, lme.Get()
|
| }
|
|
|
| -func getMultiInner(ns string, keys []rds.Key, plss []rds.PropertyLoadSaver, getColl func() (*memCollection, error)) error {
|
| - if err := multiValid(keys, plss, ns, false, true); err != nil {
|
| - return err
|
| - }
|
| -
|
| - lme := errors.LazyMultiError{Size: len(keys)}
|
| -
|
| +func getMultiInner(keys []rds.Key, cb rds.GetMultiCB, getColl func() (*memCollection, error)) error {
|
| ents, err := getColl()
|
| if err != nil {
|
| return err
|
| }
|
| if ents == nil {
|
| - for i := range keys {
|
| - lme.Assign(i, rds.ErrNoSuchEntity)
|
| + for range keys {
|
| + cb(nil, rds.ErrNoSuchEntity)
|
| }
|
| - return lme.Get()
|
| + return nil
|
| }
|
|
|
| - for i, k := range keys {
|
| + for _, k := range keys {
|
| pdata := ents.Get(keyBytes(rds.WithoutContext, k))
|
| if pdata == nil {
|
| - lme.Assign(i, rds.ErrNoSuchEntity)
|
| + cb(nil, rds.ErrNoSuchEntity)
|
| continue
|
| }
|
| -
|
| - got, err := rpmWoCtx(pdata, ns)
|
| - if err != nil {
|
| - lme.Assign(i, err)
|
| - continue
|
| - }
|
| -
|
| - lme.Assign(i, plss[i].Load(got))
|
| + cb(rpmWoCtx(pdata, k.Namespace()))
|
| }
|
| - return lme.Get()
|
| -}
|
| -
|
| -func (d *dataStoreData) get(ns string, key rds.Key, pls rds.PropertyLoadSaver) error {
|
| - return errors.SingleError(d.getMulti(ns, []rds.Key{key}, []rds.PropertyLoadSaver{pls}))
|
| + return nil
|
| }
|
|
|
| -func (d *dataStoreData) getMulti(ns string, keys []rds.Key, plss []rds.PropertyLoadSaver) error {
|
| - return getMultiInner(ns, keys, plss, func() (*memCollection, error) {
|
| +func (d *dataStoreData) getMulti(keys []rds.Key, cb rds.GetMultiCB) error {
|
| + getMultiInner(keys, cb, func() (*memCollection, error) {
|
| d.rwlock.RLock()
|
| s := d.store.Snapshot()
|
| d.rwlock.RUnlock()
|
|
|
| - return s.GetCollection("ents:" + ns), nil
|
| + return s.GetCollection("ents:" + keys[0].Namespace()), nil
|
| })
|
| + return nil
|
| }
|
|
|
| -func (d *dataStoreData) del(ns string, key rds.Key) (err error) {
|
| - return errors.SingleError(d.delMulti(ns, []rds.Key{key}))
|
| -}
|
| -
|
| -func (d *dataStoreData) delMulti(ns string, keys []rds.Key) error {
|
| - lme := errors.LazyMultiError{Size: len(keys)}
|
| +func (d *dataStoreData) delMulti(keys []rds.Key, cb rds.DeleteMultiCB) {
|
| toDel := make([][]byte, 0, len(keys))
|
| - for i, k := range keys {
|
| - if !rds.KeyValid(k, ns, false) {
|
| - lme.Assign(i, rds.ErrInvalidKey)
|
| - continue
|
| - }
|
| + for _, k := range keys {
|
| toDel = append(toDel, keyBytes(rds.WithoutContext, k))
|
| }
|
| - err := lme.Get()
|
| - if err != nil {
|
| - return err
|
| - }
|
| + ns := keys[0].Namespace()
|
|
|
| d.rwlock.Lock()
|
| defer d.rwlock.Unlock()
|
|
|
| ents := d.store.GetCollection("ents:" + ns)
|
| - if ents == nil {
|
| - return nil
|
| - }
|
|
|
| for i, k := range keys {
|
| - incrementLocked(ents, groupMetaKey(k))
|
| - kb := toDel[i]
|
| - old := ents.Get(kb)
|
| - oldPM := rds.PropertyMap(nil)
|
| - if old != nil {
|
| - if oldPM, err = rpmWoCtx(old, ns); err != nil {
|
| - lme.Assign(i, err)
|
| - continue
|
| + if ents != nil {
|
| + incrementLocked(ents, groupMetaKey(k))
|
| + kb := toDel[i]
|
| + if old := ents.Get(kb); old != nil {
|
| + oldPM, err := rpmWoCtx(old, ns)
|
| + if err != nil {
|
| + if cb != nil {
|
| + cb(err)
|
| + }
|
| + continue
|
| + }
|
| + updateIndicies(d.store, k, oldPM, nil)
|
| + ents.Delete(kb)
|
| }
|
| }
|
| - updateIndicies(d.store, k, oldPM, nil)
|
| - ents.Delete(kb)
|
| + if cb != nil {
|
| + cb(nil)
|
| + }
|
| }
|
| - return lme.Get()
|
| }
|
|
|
| func (d *dataStoreData) canApplyTxn(obj memContextObj) bool {
|
| @@ -296,13 +238,18 @@ func (d *dataStoreData) applyTxn(c context.Context, obj memContextObj) {
|
| if len(muts) == 0 { // read-only
|
| continue
|
| }
|
| + // TODO(riannucci): refactor to do just 1 putMulti, and 1 delMulti
|
| for _, m := range muts {
|
| err := error(nil)
|
| + k := m.key
|
| if m.data == nil {
|
| - err = d.del(m.key.Namespace(), m.key)
|
| + d.delMulti([]rds.Key{k},
|
| + func(e error) { err = e })
|
| } else {
|
| - _, err = d.put(m.key.Namespace(), m.key, m.data)
|
| + d.putMulti([]rds.Key{m.key}, []rds.PropertyLoadSaver{m.data},
|
| + func(_ rds.Key, e error) { err = e })
|
| }
|
| + err = errors.SingleError(err)
|
| if err != nil {
|
| panic(err)
|
| }
|
| @@ -412,63 +359,41 @@ func (td *txnDataStoreData) writeMutation(getOnly bool, key rds.Key, data rds.Pr
|
| return nil
|
| }
|
|
|
| -func (td *txnDataStoreData) put(ns string, key rds.Key, pls rds.PropertyLoadSaver) (rds.Key, error) {
|
| - keys, errs := td.putMulti(ns, []rds.Key{key}, []rds.PropertyLoadSaver{pls})
|
| - if errs == nil {
|
| - return keys[0], nil
|
| - }
|
| - return nil, errors.SingleError(errs)
|
| -}
|
| -
|
| -func (td *txnDataStoreData) putMulti(ns string, keys []rds.Key, plss []rds.PropertyLoadSaver) ([]rds.Key, error) {
|
| - pmaps, err := putMultiPrelim(ns, keys, plss)
|
| - if err != nil {
|
| - return nil, err
|
| - }
|
| -
|
| - retKeys := make([]rds.Key, len(keys))
|
| - lme := errors.LazyMultiError{Size: len(keys)}
|
| +func (td *txnDataStoreData) putMulti(keys []rds.Key, vals []rds.PropertyLoadSaver, cb rds.PutMultiCB) {
|
| for i, k := range keys {
|
| func() {
|
| td.parent.Lock()
|
| defer td.parent.Unlock()
|
| _, k = td.parent.entsKeyLocked(k)
|
| }()
|
| - lme.Assign(i, td.writeMutation(false, k, pmaps[i]))
|
| - retKeys[i] = k
|
| + err := td.writeMutation(false, k, vals[i].(rds.PropertyMap))
|
| + if cb != nil {
|
| + cb(k, err)
|
| + }
|
| }
|
| -
|
| - return retKeys, lme.Get()
|
| -}
|
| -
|
| -func (td *txnDataStoreData) get(ns string, key rds.Key, pls rds.PropertyLoadSaver) error {
|
| - return errors.SingleError(td.getMulti(ns, []rds.Key{key}, []rds.PropertyLoadSaver{pls}))
|
| }
|
|
|
| -func (td *txnDataStoreData) getMulti(ns string, keys []rds.Key, plss []rds.PropertyLoadSaver) error {
|
| - return getMultiInner(ns, keys, plss, func() (*memCollection, error) {
|
| - lme := errors.LazyMultiError{Size: len(keys)}
|
| - for i, k := range keys {
|
| - lme.Assign(i, td.writeMutation(true, k, nil))
|
| +func (td *txnDataStoreData) getMulti(keys []rds.Key, cb rds.GetMultiCB) error {
|
| + return getMultiInner(keys, cb, func() (*memCollection, error) {
|
| + err := error(nil)
|
| + for _, key := range keys {
|
| + err = td.writeMutation(true, key, nil)
|
| + if err != nil {
|
| + return nil, err
|
| + }
|
| }
|
| - return td.snap.GetCollection("ents:" + ns), lme.Get()
|
| + return td.snap.GetCollection("ents:" + keys[0].Namespace()), nil
|
| })
|
| }
|
|
|
| -func (td *txnDataStoreData) del(ns string, key rds.Key) error {
|
| - return errors.SingleError(td.delMulti(ns, []rds.Key{key}))
|
| -}
|
| -
|
| -func (td *txnDataStoreData) delMulti(ns string, keys []rds.Key) error {
|
| - lme := errors.LazyMultiError{Size: len(keys)}
|
| - for i, k := range keys {
|
| - if !rds.KeyValid(k, ns, false) {
|
| - lme.Assign(i, rds.ErrInvalidKey)
|
| - } else {
|
| - lme.Assign(i, td.writeMutation(false, k, nil))
|
| +func (td *txnDataStoreData) delMulti(keys []rds.Key, cb rds.DeleteMultiCB) error {
|
| + for _, k := range keys {
|
| + err := td.writeMutation(false, k, nil)
|
| + if cb != nil {
|
| + cb(err)
|
| }
|
| }
|
| - return lme.Get()
|
| + return nil
|
| }
|
|
|
| func keyBytes(ctx rds.KeyContext, key rds.Key) []byte {
|
| @@ -489,31 +414,6 @@ func rpm(data []byte) (rds.PropertyMap, error) {
|
| return ret, err
|
| }
|
|
|
| -func multiValid(keys []rds.Key, plss []rds.PropertyLoadSaver, ns string, potentialKey, allowSpecial bool) error {
|
| - vfn := func(k rds.Key) bool {
|
| - return !rds.KeyIncomplete(k) && rds.KeyValid(k, ns, allowSpecial)
|
| - }
|
| - if potentialKey {
|
| - vfn = func(k rds.Key) bool {
|
| - // adds an id to k if it's incomplete.
|
| - if rds.KeyIncomplete(k) {
|
| - k = rds.NewKey(k.AppID(), k.Namespace(), k.Kind(), "", 1, k.Parent())
|
| - }
|
| - return rds.KeyValid(k, ns, allowSpecial)
|
| - }
|
| - }
|
| -
|
| - if keys == nil || plss == nil {
|
| - return errors.New("gae: key or plss slices were nil")
|
| - }
|
| - if len(keys) != len(plss) {
|
| - return errors.New("gae: key and dst slices have different length")
|
| - }
|
| - lme := errors.LazyMultiError{Size: len(keys)}
|
| - for i, k := range keys {
|
| - if !vfn(k) {
|
| - lme.Assign(i, rds.ErrInvalidKey)
|
| - }
|
| - }
|
| - return lme.Get()
|
| +type keyitem interface {
|
| + Key() rds.Key
|
| }
|
|
|