Skip to content

Commit 6b4e1af

Browse files
authored
Merge pull request #9 from letterbeezps/dev
support tx iterator
2 parents 0e25b4a + a59470e commit 6b4e1af

File tree

10 files changed

+336
-41
lines changed

10 files changed

+336
-41
lines changed

README.md

+38-6
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,50 @@ import (
2929

3030
func main() {
3131
db := mv.NewMVCC()
32-
tx, err := db.Begin()
32+
tx1, err := db.Begin(false)
3333
if err != nil {
34-
log.Fatal(err)
34+
log.Fatal(err)
3535
}
36-
err = tx.Set("a", []byte("abdc"))
36+
err = tx1.Set("a", []byte("abdc"))
3737
if err != nil {
38-
log.Fatal(err)
38+
log.Fatal(err)
3939
}
40-
ret, err := tx.Get("a")
40+
ret, err := tx1.Get("a")
4141
if err != nil {
42-
log.Fatal(err)
42+
log.Fatal(err)
4343
}
4444
fmt.Println(ret)
45+
if err := tx1.Commit(); err != nil {
46+
log.Fatal(err)
47+
}
48+
49+
tx2, err := db.Begin(false)
50+
if err != nil {
51+
log.Fatal(err)
52+
}
53+
for _, c := range []string{"b", "c"} {
54+
err := tx2.Set(c, []byte(c+"_2"))
55+
if err != nil {
56+
log.Fatal(err)
57+
}
58+
}
59+
if err := tx2.Commit(); err != nil {
60+
log.Fatal(err)
61+
}
62+
tx3, err := db.Begin(true)
63+
if err != nil {
64+
log.Fatal(err)
65+
}
66+
iter, err := tx3.Iter("a", "c")
67+
if err != nil {
68+
log.Fatal(err)
69+
}
70+
for iter.IsValid() {
71+
fmt.Println(iter.Key())
72+
fmt.Println(string(iter.Value()))
73+
if err := iter.Next(); err != nil {
74+
log.Fatal(err)
75+
}
76+
}
4577
}
4678
```

cmd/example/mvcc/main.go

+35-3
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,49 @@ import (
99

1010
func main() {
1111
db := mv.NewMVCC()
12-
tx, err := db.Begin(false)
12+
tx1, err := db.Begin(false)
1313
if err != nil {
1414
log.Fatal(err)
1515
}
16-
err = tx.Set("a", []byte("abdc"))
16+
err = tx1.Set("a", []byte("abdc"))
1717
if err != nil {
1818
log.Fatal(err)
1919
}
20-
ret, err := tx.Get("a")
20+
ret, err := tx1.Get("a")
2121
if err != nil {
2222
log.Fatal(err)
2323
}
2424
fmt.Println(ret)
25+
if err := tx1.Commit(); err != nil {
26+
log.Fatal(err)
27+
}
28+
29+
tx2, err := db.Begin(false)
30+
if err != nil {
31+
log.Fatal(err)
32+
}
33+
for _, c := range []string{"b", "c"} {
34+
err := tx2.Set(c, []byte(c+"_2"))
35+
if err != nil {
36+
log.Fatal(err)
37+
}
38+
}
39+
if err := tx2.Commit(); err != nil {
40+
log.Fatal(err)
41+
}
42+
tx3, err := db.Begin(true)
43+
if err != nil {
44+
log.Fatal(err)
45+
}
46+
iter, err := tx3.Iter("a", "c")
47+
if err != nil {
48+
log.Fatal(err)
49+
}
50+
for iter.IsValid() {
51+
fmt.Println(iter.Key())
52+
fmt.Println(string(iter.Value()))
53+
if err := iter.Next(); err != nil {
54+
log.Fatal(err)
55+
}
56+
}
2557
}

engine/engine.go

+17-26
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"testing"
55

66
internal "github.com/letterbeezps/miniKV/internal"
7+
iface "github.com/letterbeezps/miniKV/internal/iface"
78
"github.com/stretchr/testify/assert"
89
)
910

@@ -18,26 +19,16 @@ type Engine interface {
1819
Delete(key string)
1920

2021
// option
21-
Scan(start, end internal.Bound, iter func(key string, value []byte) bool)
22+
// Scan(start, end internal.Bound, iter func(key string, value []byte) bool)
2223

2324
// option
24-
Reverse(start, end internal.Bound, iter func(key string, value []byte) bool)
25+
// Reverse(start, end internal.Bound, iter func(key string, value []byte) bool)
2526

2627
// requested
27-
Iter(start, end internal.Bound) Iterator
28+
Iter(start, end internal.Bound) iface.Iterator
2829

2930
// option
30-
ReverseIter(start, end internal.Bound) Iterator
31-
}
32-
33-
type Iterator interface {
34-
Value() []byte
35-
36-
Key() string
37-
38-
IsValid() bool
39-
40-
Next()
31+
// ReverseIter(start, end internal.Bound) Iterator
4132
}
4233

4334
//////// test ////////////
@@ -295,16 +286,16 @@ func ReverseScanTest(engine Engine, t *testing.T) {
295286

296287
////////////////////////// reverse iter//////////////////
297288

298-
iterator := engine.ReverseIter(
299-
internal.NewBound("", internal.NoBound),
300-
internal.NewBound("", internal.NoBound),
301-
)
302-
i := len(datas) - 1
303-
for iterator.IsValid() {
304-
assert.Equal(t, datas[i].key, iterator.Key())
305-
assert.Equal(t, datas[i].val, iterator.Value())
306-
// t.Log("key: ", iterator.Key(), " value: ", iterator.Value())
307-
iterator.Next()
308-
i--
309-
}
289+
// iterator := engine.ReverseIter(
290+
// internal.NewBound("", internal.NoBound),
291+
// internal.NewBound("", internal.NoBound),
292+
// )
293+
// i := len(datas) - 1
294+
// for iterator.IsValid() {
295+
// assert.Equal(t, datas[i].key, iterator.Key())
296+
// assert.Equal(t, datas[i].val, iterator.Value())
297+
// // t.Log("key: ", iterator.Key(), " value: ", iterator.Value())
298+
// iterator.Next()
299+
// i--
300+
// }
310301
}

engine/memory/iterator.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,11 @@ func (iter *MemoryIterator) prev() {
6565
}
6666
}
6767

68-
func (iter *MemoryIterator) Next() {
68+
func (iter *MemoryIterator) Next() error {
6969
if !iter.IsReverse {
7070
iter.next()
7171
} else {
7272
iter.prev()
7373
}
74+
return nil
7475
}

engine/memory/memory.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package memory
33
import (
44
"github.com/letterbeezps/miniKV/engine"
55
internal "github.com/letterbeezps/miniKV/internal"
6+
iface "github.com/letterbeezps/miniKV/internal/iface"
67
"github.com/tidwall/btree"
78
)
89

@@ -85,7 +86,7 @@ func (m *Memory) Reverse(start, end internal.Bound, iter func(key string, value
8586
}
8687
}
8788

88-
func (m *Memory) Iter(start, end internal.Bound) engine.Iterator {
89+
func (m *Memory) Iter(start, end internal.Bound) iface.Iterator {
8990
iter := m.Data.Iter()
9091
key, value := "", []byte{}
9192
valid := true
@@ -119,7 +120,7 @@ func (m *Memory) Iter(start, end internal.Bound) engine.Iterator {
119120
}
120121

121122
// todo : fix bug
122-
func (m *Memory) ReverseIter(start, end internal.Bound) engine.Iterator {
123+
func (m *Memory) ReverseIter(start, end internal.Bound) iface.Iterator {
123124
iter := m.Data.Iter()
124125
key, value := "", []byte{}
125126
valid := true

internal/iface/iterator.go

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package iface
2+
3+
type Iterator interface {
4+
Value() []byte
5+
6+
Key() string
7+
8+
IsValid() bool
9+
10+
Next() error
11+
}

mvcc/error.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package mvcc
33
import "errors"
44

55
var (
6-
ErrorSerialization = errors.New("serialization")
7-
ErrorReadOnly = errors.New("can't update with read only tx")
6+
ErrorSerialization = errors.New("serialization")
7+
ErrorReadOnly = errors.New("can't update with read only tx")
8+
ErrorNotSupportNoBound = errors.New("tx iterator not support NoBound")
89
)

mvcc/iterator.go

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package mvcc
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/letterbeezps/miniKV/internal/iface"
7+
"github.com/pkg/errors"
8+
)
9+
10+
type TXIterator struct {
11+
State *TxState
12+
Start string
13+
End string
14+
LastK string
15+
K string
16+
V []byte
17+
EngineIterator iface.Iterator
18+
}
19+
20+
func (iter *TXIterator) Value() []byte {
21+
if len(iter.V) == 0 {
22+
return []byte{}
23+
}
24+
return iter.V
25+
}
26+
27+
func (iter *TXIterator) Key() string {
28+
return iter.K
29+
}
30+
31+
func (iter *TXIterator) IsValid() bool {
32+
return iter.K != ""
33+
}
34+
35+
func (iter *TXIterator) Next() error {
36+
var nextK string
37+
var nextV []byte
38+
for iter.EngineIterator.IsValid() {
39+
check_id, origin_key, err := decodeTxKey(iter.EngineIterator.Key())
40+
if err != nil {
41+
return errors.Wrap(err, fmt.Sprintf("got bad txKey: %s", iter.Key()))
42+
}
43+
if (!iter.State.IsVisible(check_id)) || (iter.LastK != "" && iter.LastK == origin_key) {
44+
err := iter.EngineIterator.Next()
45+
if err != nil {
46+
return errors.Wrap(err, "EngineIterator.Next()")
47+
}
48+
continue
49+
}
50+
if origin_key > iter.End {
51+
break
52+
}
53+
iter.LastK = origin_key
54+
nextK = origin_key
55+
nextV = iter.EngineIterator.Value()
56+
break
57+
}
58+
iter.K = nextK
59+
iter.V = nextV
60+
return nil
61+
}

0 commit comments

Comments
 (0)