| Index: impl/memory/datastore_data.go
|
| diff --git a/impl/memory/datastore_data.go b/impl/memory/datastore_data.go
|
| index a17283ac702fd3ab40c0eba8c5c17969aa562666..a3bbda7074f61d34b15ddd8a7dbb63d33e36687d 100644
|
| --- a/impl/memory/datastore_data.go
|
| +++ b/impl/memory/datastore_data.go
|
| @@ -30,6 +30,10 @@ type dataStoreData struct {
|
| // true means that queries with insufficent indexes will pause to add them
|
| // and then continue instead of failing.
|
| autoIndex bool
|
| + // true means that all of the __...__ keys which are normally automatically
|
| + // maintained will be omitted. This also means that Put with an incomplete
|
| + // key will become an error.
|
| + disableSpecialEntities bool
|
| }
|
|
|
| var (
|
| @@ -102,6 +106,18 @@ func (d *dataStoreData) maybeAutoIndex(err error) bool {
|
| return true
|
| }
|
|
|
| +func (d *dataStoreData) setDisableSpecialEntities(enabled bool) {
|
| + d.Lock()
|
| + defer d.Unlock()
|
| + d.disableSpecialEntities = true
|
| +}
|
| +
|
| +func (d *dataStoreData) getDisableSpecialEntities() bool {
|
| + d.rwlock.RLock()
|
| + defer d.rwlock.RUnlock()
|
| + return d.disableSpecialEntities
|
| +}
|
| +
|
| func (d *dataStoreData) getQuerySnaps(consistent bool) (idx, head *memStore) {
|
| d.rwlock.RLock()
|
| defer d.rwlock.RUnlock()
|
| @@ -200,7 +216,7 @@ func (d *dataStoreData) mutableEnts(ns string) *memCollection {
|
| return ents
|
| }
|
|
|
| -func (d *dataStoreData) allocateIDs(incomplete *ds.Key, n int) int64 {
|
| +func (d *dataStoreData) allocateIDs(incomplete *ds.Key, n int) (int64, error) {
|
| ents := d.mutableEnts(incomplete.Namespace())
|
|
|
| d.Lock()
|
| @@ -208,22 +224,29 @@ func (d *dataStoreData) allocateIDs(incomplete *ds.Key, n int) int64 {
|
| return d.allocateIDsLocked(ents, incomplete, n)
|
| }
|
|
|
| -func (d *dataStoreData) allocateIDsLocked(ents *memCollection, incomplete *ds.Key, n int) int64 {
|
| +func (d *dataStoreData) allocateIDsLocked(ents *memCollection, incomplete *ds.Key, n int) (int64, error) {
|
| + if d.disableSpecialEntities {
|
| + return 0, errors.New("disableSpecialEntities is true so allocateIDs is disabled")
|
| + }
|
| +
|
| idKey := []byte(nil)
|
| if incomplete.Parent() == nil {
|
| idKey = rootIDsKey(incomplete.Kind())
|
| } else {
|
| idKey = groupIDsKey(incomplete)
|
| }
|
| - return incrementLocked(ents, idKey, n)
|
| + return incrementLocked(ents, idKey, n), nil
|
| }
|
|
|
| -func (d *dataStoreData) fixKeyLocked(ents *memCollection, key *ds.Key) *ds.Key {
|
| +func (d *dataStoreData) fixKeyLocked(ents *memCollection, key *ds.Key) (*ds.Key, error) {
|
| if key.Incomplete() {
|
| - id := d.allocateIDsLocked(ents, key, 1)
|
| + id, err := d.allocateIDsLocked(ents, key, 1)
|
| + if err != nil {
|
| + return key, err
|
| + }
|
| key = ds.NewKey(key.AppID(), key.Namespace(), key.Kind(), "", id, key.Parent())
|
| }
|
| - return key
|
| + return key, nil
|
| }
|
|
|
| func (d *dataStoreData) putMulti(keys []*ds.Key, vals []ds.PropertyMap, cb ds.PutMultiCB) {
|
| @@ -238,8 +261,13 @@ func (d *dataStoreData) putMulti(keys []*ds.Key, vals []ds.PropertyMap, cb ds.Pu
|
| d.Lock()
|
| defer d.Unlock()
|
|
|
| - ret = d.fixKeyLocked(ents, k)
|
| - incrementLocked(ents, groupMetaKey(ret), 1)
|
| + ret, err = d.fixKeyLocked(ents, k)
|
| + if err != nil {
|
| + return
|
| + }
|
| + if !d.disableSpecialEntities {
|
| + incrementLocked(ents, groupMetaKey(ret), 1)
|
| + }
|
|
|
| old := ents.Get(keyBytes(ret))
|
| oldPM := ds.PropertyMap(nil)
|
| @@ -304,7 +332,9 @@ func (d *dataStoreData) delMulti(keys []*ds.Key, cb ds.DeleteMultiCB) {
|
| d.Lock()
|
| defer d.Unlock()
|
|
|
| - incrementLocked(ents, groupMetaKey(k), 1)
|
| + if !d.disableSpecialEntities {
|
| + incrementLocked(ents, groupMetaKey(k), 1)
|
| + }
|
| if old := ents.Get(kb); old != nil {
|
| oldPM, err := rpmWoCtx(old, ns)
|
| if err != nil {
|
| @@ -484,12 +514,15 @@ func (td *txnDataStoreData) putMulti(keys []*ds.Key, vals []ds.PropertyMap, cb d
|
| ents := td.parent.mutableEnts(keys[0].Namespace())
|
|
|
| for i, k := range keys {
|
| - func() {
|
| + err := func() (err error) {
|
| td.parent.Lock()
|
| defer td.parent.Unlock()
|
| - k = td.parent.fixKeyLocked(ents, k)
|
| + k, err = td.parent.fixKeyLocked(ents, k)
|
| + return
|
| }()
|
| - err := td.writeMutation(false, k, vals[i])
|
| + if err == nil {
|
| + err = td.writeMutation(false, k, vals[i])
|
| + }
|
| if cb != nil {
|
| cb(k, err)
|
| }
|
|
|