Chromium Code Reviews| Index: impl/memory/datastore_data.go |
| diff --git a/impl/memory/datastore_data.go b/impl/memory/datastore_data.go |
| index f563b4ba1e230c5b789facb5c1f2b45ea1485470..95fe0daf8e6279311ae2e82e2fda84346648cab2 100644 |
| --- a/impl/memory/datastore_data.go |
| +++ b/impl/memory/datastore_data.go |
| @@ -25,6 +25,8 @@ type dataStoreData struct { |
| snap *memStore |
| // For testing, see SetTransactionRetryCount. |
| txnFakeRetry int |
| + // true means that head always == snap |
| + consistent bool |
| } |
| var ( |
| @@ -48,9 +50,30 @@ func (d *dataStoreData) Unlock() { |
| d.rwlock.Unlock() |
| } |
| +func (d *dataStoreData) setTxnRetry(count int) { |
| + d.Lock() |
|
Vadim Sh.
2015/09/24 18:40:11
oops.. didn't know it's under lock
iannucci
2015/09/24 18:59:30
is ok :)
|
| + defer d.Unlock() |
| + d.txnFakeRetry = count |
| +} |
| + |
| +func (d *dataStoreData) setConsistent(always bool) { |
| + d.Lock() |
| + defer d.Unlock() |
| + |
| + d.consistent = always |
| + if d.consistent { |
| + d.snap = d.head.Snapshot() |
| + } |
| +} |
| + |
| func (d *dataStoreData) getQuerySnaps(consistent bool) (idx, head *memStore) { |
| d.rwlock.RLock() |
| defer d.rwlock.RUnlock() |
| + if d.consistent { |
| + // snap is already a consistent snapshot of head |
| + return d.snap, d.snap |
| + } |
| + |
| head = d.head.Snapshot() |
| if consistent { |
| idx = head |
| @@ -63,18 +86,27 @@ func (d *dataStoreData) getQuerySnaps(consistent bool) (idx, head *memStore) { |
| func (d *dataStoreData) takeSnapshot() *memStore { |
| d.rwlock.RLock() |
| defer d.rwlock.RUnlock() |
| + if d.consistent { |
| + return d.snap |
| + } |
| return d.head.Snapshot() |
| } |
| func (d *dataStoreData) setSnapshot(snap *memStore) { |
| d.rwlock.Lock() |
| defer d.rwlock.Unlock() |
| + if d.consistent { |
| + return |
| + } |
| d.snap = snap |
| } |
| func (d *dataStoreData) catchupIndexes() { |
| d.rwlock.Lock() |
| defer d.rwlock.Unlock() |
| + if d.consistent { |
| + return |
| + } |
| d.snap = d.head.Snapshot() |
| } |
| @@ -159,7 +191,8 @@ func (d *dataStoreData) fixKeyLocked(ents *memCollection, key *ds.Key) *ds.Key { |
| } |
| func (d *dataStoreData) putMulti(keys []*ds.Key, vals []ds.PropertyMap, cb ds.PutMultiCB) { |
| - ents := d.mutableEnts(keys[0].Namespace()) |
| + ns := keys[0].Namespace() |
| + ents := d.mutableEnts(ns) |
| for i, k := range keys { |
| pmap, _ := vals[i].Save(false) |
| @@ -175,12 +208,15 @@ func (d *dataStoreData) putMulti(keys []*ds.Key, vals []ds.PropertyMap, cb ds.Pu |
| old := ents.Get(keyBytes(ret)) |
| oldPM := ds.PropertyMap(nil) |
| if old != nil { |
| - if oldPM, err = rpmWoCtx(old, ret.Namespace()); err != nil { |
| + if oldPM, err = rpmWoCtx(old, ns); err != nil { |
| return |
| } |
| } |
| updateIndexes(d.head, ret, oldPM, pmap) |
| ents.Set(keyBytes(ret), dataBytes) |
| + if d.consistent { |
| + d.snap = d.head.Snapshot() |
| + } |
| return |
| }() |
| if cb != nil { |
| @@ -221,36 +257,35 @@ func (d *dataStoreData) getMulti(keys []*ds.Key, cb ds.GetMultiCB) error { |
| } |
| func (d *dataStoreData) delMulti(keys []*ds.Key, cb ds.DeleteMultiCB) { |
| - toDel := make([][]byte, 0, len(keys)) |
| - for _, k := range keys { |
| - toDel = append(toDel, keyBytes(k)) |
| - } |
| ns := keys[0].Namespace() |
| + ents := d.mutableEnts(ns) |
| - d.rwlock.Lock() |
| - defer d.rwlock.Unlock() |
| - |
| - ents := d.head.GetCollection("ents:" + ns) |
| - |
| - for i, k := range keys { |
| - if ents != nil { |
| - incrementLocked(ents, groupMetaKey(k), 1) |
| - kb := toDel[i] |
| - if old := ents.Get(kb); old != nil { |
| - oldPM, err := rpmWoCtx(old, ns) |
| - if err != nil { |
| - if cb != nil { |
| - cb(err) |
| + if ents != nil { |
| + for _, k := range keys { |
| + err := func() error { |
| + kb := keyBytes(k) |
| + |
| + d.Lock() |
| + defer d.Unlock() |
| + |
| + incrementLocked(ents, groupMetaKey(k), 1) |
| + if old := ents.Get(kb); old != nil { |
| + oldPM, err := rpmWoCtx(old, ns) |
| + if err != nil { |
| + return err |
| + } |
| + updateIndexes(d.head, k, oldPM, nil) |
| + ents.Delete(kb) |
| + if d.consistent { |
| + d.snap = d.head.Snapshot() |
| } |
| - continue |
| } |
| - updateIndexes(d.head, k, oldPM, nil) |
| - ents.Delete(kb) |
| + return nil |
| + }() |
| + if cb != nil { |
|
Vadim Sh.
2015/09/24 18:40:11
I think you need to call cb() len(keys) number of
iannucci
2015/09/24 18:59:30
oh, good catch.
|
| + cb(err) |
| } |
| } |
| - if cb != nil { |
| - cb(nil) |
| - } |
| } |
| } |