1
2
3
4
5
6
7 package table
8
9 import (
10 "encoding/binary"
11 "fmt"
12
13 . "github.com/onsi/ginkgo"
14 . "github.com/onsi/gomega"
15
16 "github.com/syndtr/goleveldb/leveldb/comparer"
17 "github.com/syndtr/goleveldb/leveldb/iterator"
18 "github.com/syndtr/goleveldb/leveldb/testutil"
19 "github.com/syndtr/goleveldb/leveldb/util"
20 )
21
22 type blockTesting struct {
23 tr *Reader
24 b *block
25 }
26
27 func (t *blockTesting) TestNewIterator(slice *util.Range) iterator.Iterator {
28 return t.tr.newBlockIter(t.b, nil, slice, false)
29 }
30
31 var _ = testutil.Defer(func() {
32 Describe("Block", func() {
33 Build := func(kv *testutil.KeyValue, restartInterval int) *blockTesting {
34
35 bw := &blockWriter{
36 restartInterval: restartInterval,
37 scratch: make([]byte, 30),
38 }
39 kv.Iterate(func(i int, key, value []byte) {
40 Expect(bw.append(key, value)).ShouldNot(HaveOccurred())
41 })
42 Expect(bw.finish()).ShouldNot(HaveOccurred())
43
44
45 data := bw.buf.Bytes()
46 restartsLen := int(binary.LittleEndian.Uint32(data[len(data)-4:]))
47 return &blockTesting{
48 tr: &Reader{cmp: comparer.DefaultComparer},
49 b: &block{
50 data: data,
51 restartsLen: restartsLen,
52 restartsOffset: len(data) - (restartsLen+1)*4,
53 },
54 }
55 }
56
57 Describe("read test", func() {
58 for restartInterval := 1; restartInterval <= 5; restartInterval++ {
59 Describe(fmt.Sprintf("with restart interval of %d", restartInterval), func() {
60 kv := &testutil.KeyValue{}
61 Text := func() string {
62 return fmt.Sprintf("and %d keys", kv.Len())
63 }
64
65 Test := func() {
66
67 br := Build(kv, restartInterval)
68
69 testutil.KeyValueTesting(nil, kv.Clone(), br, nil, nil)
70 }
71
72 Describe(Text(), Test)
73
74 kv.PutString("", "empty")
75 Describe(Text(), Test)
76
77 kv.PutString("a1", "foo")
78 Describe(Text(), Test)
79
80 kv.PutString("a2", "v")
81 Describe(Text(), Test)
82
83 kv.PutString("a3qqwrkks", "hello")
84 Describe(Text(), Test)
85
86 kv.PutString("a4", "bar")
87 Describe(Text(), Test)
88
89 kv.PutString("a5111111", "v5")
90 kv.PutString("a6", "")
91 kv.PutString("a7", "v7")
92 kv.PutString("a8", "vvvvvvvvvvvvvvvvvvvvvv8")
93 kv.PutString("b", "v9")
94 kv.PutString("c9", "v9")
95 kv.PutString("c91", "v9")
96 kv.PutString("d0", "v9")
97 Describe(Text(), Test)
98 })
99 }
100 })
101
102 Describe("out-of-bound slice test", func() {
103 kv := &testutil.KeyValue{}
104 kv.PutString("k1", "v1")
105 kv.PutString("k2", "v2")
106 kv.PutString("k3abcdefgg", "v3")
107 kv.PutString("k4", "v4")
108 kv.PutString("k5", "v5")
109 for restartInterval := 1; restartInterval <= 5; restartInterval++ {
110 Describe(fmt.Sprintf("with restart interval of %d", restartInterval), func() {
111
112 bt := Build(kv, restartInterval)
113
114 Test := func(r *util.Range) func(done Done) {
115 return func(done Done) {
116 iter := bt.TestNewIterator(r)
117 Expect(iter.Error()).ShouldNot(HaveOccurred())
118
119 t := testutil.IteratorTesting{
120 KeyValue: kv.Clone(),
121 Iter: iter,
122 }
123
124 testutil.DoIteratorTesting(&t)
125 iter.Release()
126 done <- true
127 }
128 }
129
130 It("Should do iterations and seeks correctly #0",
131 Test(&util.Range{Start: []byte("k0"), Limit: []byte("k6")}), 2.0)
132
133 It("Should do iterations and seeks correctly #1",
134 Test(&util.Range{Start: []byte(""), Limit: []byte("zzzzzzz")}), 2.0)
135 })
136 }
137 })
138 })
139 })
140
View as plain text