Skip to content

Commit

Permalink
Merge pull request #8323 from fanminshi/fix_TestV3HashKV_Hash_MisMatch
Browse files Browse the repository at this point in the history
integeration: fix TestV3HashKV hash mismatch
  • Loading branch information
heyitsanthony committed Jul 28, 2017
2 parents b36463e + 451b062 commit ca58614
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 6 deletions.
50 changes: 50 additions & 0 deletions mvcc/backend/backend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,56 @@ func TestBackendWriteback(t *testing.T) {
}
}

// TestBackendWritebackForEach checks that partially written / buffered
// data is visited in the same order as fully committed data.
func TestBackendWritebackForEach(t *testing.T) {
b, tmpPath := NewTmpBackend(time.Hour, 10000)
defer cleanup(b, tmpPath)

tx := b.BatchTx()
tx.Lock()
tx.UnsafeCreateBucket([]byte("key"))
for i := 0; i < 5; i++ {
k := []byte(fmt.Sprintf("%04d", i))
tx.UnsafePut([]byte("key"), k, []byte("bar"))
}
tx.Unlock()

// writeback
b.ForceCommit()

tx.Lock()
tx.UnsafeCreateBucket([]byte("key"))
for i := 5; i < 20; i++ {
k := []byte(fmt.Sprintf("%04d", i))
tx.UnsafePut([]byte("key"), k, []byte("bar"))
}
tx.Unlock()

seq := ""
getSeq := func(k, v []byte) error {
seq += string(k)
return nil
}
rtx := b.ReadTx()
rtx.Lock()
rtx.UnsafeForEach([]byte("key"), getSeq)
rtx.Unlock()

partialSeq := seq

seq = ""
b.ForceCommit()

tx.Lock()
tx.UnsafeForEach([]byte("key"), getSeq)
tx.Unlock()

if seq != partialSeq {
t.Fatalf("expected %q, got %q", seq, partialSeq)
}
}

func cleanup(b Backend, path string) {
b.Close()
os.Remove(path)
Expand Down
15 changes: 9 additions & 6 deletions mvcc/backend/read_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

0 comments on commit ca58614

Please sign in to comment.