-
Notifications
You must be signed in to change notification settings - Fork 5
/
mvdata_test.go
111 lines (93 loc) · 3.5 KB
/
mvdata_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package block_stm
import (
"errors"
"fmt"
"testing"
"github.com/test-go/testify/require"
)
func TestEmptyMVData(t *testing.T) {
data := NewMVData()
value, _, estimate := data.Read([]byte("a"), 1)
require.False(t, estimate)
require.Nil(t, value)
}
func TestMVData(t *testing.T) {
data := NewMVData()
// read closest version
data.Write([]byte("a"), []byte("1"), TxnVersion{Index: 1, Incarnation: 1})
data.Write([]byte("a"), []byte("2"), TxnVersion{Index: 2, Incarnation: 1})
data.Write([]byte("a"), []byte("3"), TxnVersion{Index: 3, Incarnation: 1})
data.Write([]byte("b"), []byte("2"), TxnVersion{Index: 2, Incarnation: 1})
// read closest version
value, _, estimate := data.Read([]byte("a"), 1)
require.False(t, estimate)
require.Nil(t, value)
// read closest version
value, version, estimate := data.Read([]byte("a"), 4)
require.False(t, estimate)
require.Equal(t, []byte([]byte("3")), value)
require.Equal(t, TxnVersion{Index: 3, Incarnation: 1}, version)
// read closest version
value, version, estimate = data.Read([]byte("a"), 3)
require.False(t, estimate)
require.Equal(t, []byte([]byte("2")), value)
require.Equal(t, TxnVersion{Index: 2, Incarnation: 1}, version)
// read closest version
value, version, estimate = data.Read([]byte("b"), 3)
require.False(t, estimate)
require.Equal(t, []byte([]byte("2")), value)
require.Equal(t, TxnVersion{Index: 2, Incarnation: 1}, version)
// new incarnation overrides old
data.Write([]byte("a"), []byte("3-2"), TxnVersion{Index: 3, Incarnation: 2})
value, version, estimate = data.Read([]byte("a"), 4)
require.False(t, estimate)
require.Equal(t, []byte([]byte("3-2")), value)
require.Equal(t, TxnVersion{Index: 3, Incarnation: 2}, version)
// read estimate
data.WriteEstimate([]byte("a"), 3)
_, version, estimate = data.Read([]byte("a"), 4)
require.True(t, estimate)
require.Equal(t, TxnIndex(3), version.Index)
// delete value
data.Delete([]byte("a"), 3)
value, version, estimate = data.Read([]byte("a"), 4)
require.False(t, estimate)
require.Equal(t, []byte([]byte("2")), value)
require.Equal(t, TxnVersion{Index: 2, Incarnation: 1}, version)
data.Delete([]byte("b"), 2)
value, _, estimate = data.Read([]byte("b"), 4)
require.False(t, estimate)
require.Nil(t, value)
}
func TestReadErrConversion(t *testing.T) {
err := fmt.Errorf("wrap: %w", ErrReadError{BlockingTxn: 1})
var readErr ErrReadError
require.True(t, errors.As(err, &readErr))
require.Equal(t, TxnIndex(1), readErr.BlockingTxn)
}
func TestSnapshot(t *testing.T) {
storage := NewMemDB()
// initial value
storage.Set([]byte("a"), []byte("0"))
storage.Set([]byte("d"), []byte("0"))
data := NewMVData()
// read closest version
data.Write([]byte("a"), []byte("1"), TxnVersion{Index: 1, Incarnation: 1})
data.Write([]byte("a"), []byte("2"), TxnVersion{Index: 2, Incarnation: 1})
data.Write([]byte("a"), []byte("3"), TxnVersion{Index: 3, Incarnation: 1})
data.Write([]byte("b"), []byte("2"), TxnVersion{Index: 2, Incarnation: 1})
data.Write([]byte("d"), []byte("1"), TxnVersion{Index: 2, Incarnation: 1})
// delete the key "d" in tx 3
data.Write([]byte("d"), nil, TxnVersion{Index: 3, Incarnation: 1})
data.WriteEstimate([]byte("c"), 2)
require.Equal(t, []KVPair{
{[]byte("a"), []byte("3")},
{[]byte("b"), []byte("2")},
{[]byte("d"), nil},
}, data.Snapshot())
data.SnapshotToStore(storage)
require.Equal(t, []byte("3"), storage.Get([]byte("a")))
require.Equal(t, []byte("2"), storage.Get([]byte("b")))
require.Nil(t, storage.Get([]byte("d")))
require.Equal(t, 2, storage.Len())
}