mvcc/backend: enforce ordering for UnsafeForEach in read_tx.go

This pr changes  UnsafeForEach to traverse on boltdb before on the buffer.
This ordering guarantees that UnsafeForEach traverses in the same order
before or after the commit of buffer.
release-3.3
fanmin shi 2017-07-27 17:42:19 -07:00
parent b36463efe5
commit 785deebd62
1 changed files with 9 additions and 6 deletions

View File

@ -70,21 +70,24 @@ func (rt *readTx) UnsafeRange(bucketName, key, endKey []byte, limit int64) ([][]
func (rt *readTx) UnsafeForEach(bucketName []byte, visitor func(k, v []byte) error) error {
dups := make(map[string]struct{})
f1 := func(k, v []byte) error {
getDups := func(k, v []byte) error {
dups[string(k)] = struct{}{}
return visitor(k, v)
return nil
}
f2 := func(k, v []byte) error {
visitNoDup := func(k, v []byte) error {
if _, ok := dups[string(k)]; ok {
return nil
}
return visitor(k, v)
}
if err := rt.buf.ForEach(bucketName, f1); err != nil {
if err := rt.buf.ForEach(bucketName, getDups); err != nil {
return err
}
rt.txmu.Lock()
err := unsafeForEach(rt.tx, bucketName, f2)
err := unsafeForEach(rt.tx, bucketName, visitNoDup)
rt.txmu.Unlock()
return err
if err != nil {
return err
}
return rt.buf.ForEach(bucketName, visitor)
}