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
parent
b36463efe5
commit
785deebd62
|
@ -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 {
|
func (rt *readTx) UnsafeForEach(bucketName []byte, visitor func(k, v []byte) error) error {
|
||||||
dups := make(map[string]struct{})
|
dups := make(map[string]struct{})
|
||||||
f1 := func(k, v []byte) error {
|
getDups := func(k, v []byte) error {
|
||||||
dups[string(k)] = struct{}{}
|
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 {
|
if _, ok := dups[string(k)]; ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return visitor(k, v)
|
return visitor(k, v)
|
||||||
}
|
}
|
||||||
if err := rt.buf.ForEach(bucketName, f1); err != nil {
|
if err := rt.buf.ForEach(bucketName, getDups); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
rt.txmu.Lock()
|
rt.txmu.Lock()
|
||||||
err := unsafeForEach(rt.tx, bucketName, f2)
|
err := unsafeForEach(rt.tx, bucketName, visitNoDup)
|
||||||
rt.txmu.Unlock()
|
rt.txmu.Unlock()
|
||||||
return err
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return rt.buf.ForEach(bucketName, visitor)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue