1
2
3
4
5
6
7 package table
8
9 import (
10 "bytes"
11
12 . "github.com/onsi/ginkgo"
13 . "github.com/onsi/gomega"
14
15 "github.com/syndtr/goleveldb/leveldb/iterator"
16 "github.com/syndtr/goleveldb/leveldb/opt"
17 "github.com/syndtr/goleveldb/leveldb/storage"
18 "github.com/syndtr/goleveldb/leveldb/testutil"
19 "github.com/syndtr/goleveldb/leveldb/util"
20 )
21
22 type tableWrapper struct {
23 *Reader
24 }
25
26 func (t tableWrapper) TestFind(key []byte) (rkey, rvalue []byte, err error) {
27 return t.Reader.Find(key, false, nil)
28 }
29
30 func (t tableWrapper) TestGet(key []byte) (value []byte, err error) {
31 return t.Reader.Get(key, nil)
32 }
33
34 func (t tableWrapper) TestNewIterator(slice *util.Range) iterator.Iterator {
35 return t.Reader.NewIterator(slice, nil)
36 }
37
38 var _ = testutil.Defer(func() {
39 Describe("Table", func() {
40 Describe("approximate offset test", func() {
41 var (
42 buf = &bytes.Buffer{}
43 o = &opt.Options{
44 BlockSize: 1024,
45 Compression: opt.NoCompression,
46 }
47 )
48
49
50 tw := NewWriter(buf, o, nil, 0)
51 err := tw.Append([]byte("k01"), []byte("hello"))
52 Expect(err).ShouldNot(HaveOccurred())
53 err = tw.Append([]byte("k02"), []byte("hello2"))
54 Expect(err).ShouldNot(HaveOccurred())
55 err = tw.Append([]byte("k03"), bytes.Repeat([]byte{'x'}, 10000))
56 Expect(err).ShouldNot(HaveOccurred())
57 err = tw.Append([]byte("k04"), bytes.Repeat([]byte{'x'}, 200000))
58 Expect(err).ShouldNot(HaveOccurred())
59 err = tw.Append([]byte("k05"), bytes.Repeat([]byte{'x'}, 300000))
60 Expect(err).ShouldNot(HaveOccurred())
61 err = tw.Append([]byte("k06"), []byte("hello3"))
62 Expect(err).ShouldNot(HaveOccurred())
63 err = tw.Append([]byte("k07"), bytes.Repeat([]byte{'x'}, 100000))
64 Expect(err).ShouldNot(HaveOccurred())
65
66 err = tw.Close()
67
68 It("Should be able to approximate offset of a key correctly", func() {
69 Expect(err).ShouldNot(HaveOccurred())
70
71 tr, err := NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len()), storage.FileDesc{}, nil, nil, o)
72 Expect(err).ShouldNot(HaveOccurred())
73 CheckOffset := func(key string, expect, threshold int) {
74 offset, err := tr.OffsetOf([]byte(key))
75 Expect(err).ShouldNot(HaveOccurred())
76 Expect(offset).Should(BeNumerically("~", expect, threshold), "Offset of key %q", key)
77 }
78
79 CheckOffset("k0", 0, 0)
80 CheckOffset("k01a", 0, 0)
81 CheckOffset("k02", 0, 0)
82 CheckOffset("k03", 0, 0)
83 CheckOffset("k04", 10000, 1000)
84 CheckOffset("k04a", 210000, 1000)
85 CheckOffset("k05", 210000, 1000)
86 CheckOffset("k06", 510000, 1000)
87 CheckOffset("k07", 510000, 1000)
88 CheckOffset("xyz", 610000, 2000)
89 })
90 })
91
92 Describe("read test", func() {
93 Build := func(kv testutil.KeyValue) testutil.DB {
94 o := &opt.Options{
95 BlockSize: 512,
96 BlockRestartInterval: 3,
97 }
98 buf := &bytes.Buffer{}
99
100
101 tw := NewWriter(buf, o, nil, 0)
102 kv.Iterate(func(i int, key, value []byte) {
103 Expect(tw.Append(key, value)).ShouldNot(HaveOccurred())
104 })
105 tw.Close()
106
107
108 tr, _ := NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len()), storage.FileDesc{}, nil, nil, o)
109 return tableWrapper{tr}
110 }
111 Test := func(kv *testutil.KeyValue, body func(r *Reader)) func() {
112 return func() {
113 db := Build(*kv)
114 if body != nil {
115 body(db.(tableWrapper).Reader)
116 }
117 testutil.KeyValueTesting(nil, *kv, db, nil, nil)
118 }
119 }
120
121 testutil.AllKeyValueTesting(nil, Build, nil, nil)
122 Describe("with one key per block", Test(testutil.KeyValue_Generate(nil, 9, 1, 1, 10, 512, 512), func(r *Reader) {
123 It("should have correct blocks number", func() {
124 indexBlock, err := r.readBlock(r.indexBH, true)
125 Expect(err).To(BeNil())
126 Expect(indexBlock.restartsLen).Should(Equal(9))
127 })
128 }))
129 })
130 })
131 })
132
View as plain text