1 // Copyright (c) 2014, Suryandaru Triandana <syndtr@gmail.com>
2 // All rights reserved.
4 // Use of this source code is governed by a BSD-style license that can be
5 // found in the LICENSE file.
12 . "github.com/onsi/ginkgo"
13 . "github.com/onsi/gomega"
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"
22 type tableWrapper struct {
26 func (t tableWrapper) TestFind(key []byte) (rkey, rvalue []byte, err error) {
27 return t.Reader.Find(key, false, nil)
30 func (t tableWrapper) TestGet(key []byte) (value []byte, err error) {
31 return t.Reader.Get(key, nil)
34 func (t tableWrapper) TestNewIterator(slice *util.Range) iterator.Iterator {
35 return t.Reader.NewIterator(slice, nil)
38 var _ = testutil.Defer(func() {
39 Describe("Table", func() {
40 Describe("approximate offset test", func() {
45 Compression: opt.NoCompression,
49 // Building the table.
50 tw := NewWriter(buf, o)
51 tw.Append([]byte("k01"), []byte("hello"))
52 tw.Append([]byte("k02"), []byte("hello2"))
53 tw.Append([]byte("k03"), bytes.Repeat([]byte{'x'}, 10000))
54 tw.Append([]byte("k04"), bytes.Repeat([]byte{'x'}, 200000))
55 tw.Append([]byte("k05"), bytes.Repeat([]byte{'x'}, 300000))
56 tw.Append([]byte("k06"), []byte("hello3"))
57 tw.Append([]byte("k07"), bytes.Repeat([]byte{'x'}, 100000))
60 It("Should be able to approximate offset of a key correctly", func() {
61 Expect(err).ShouldNot(HaveOccurred())
63 tr, err := NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len()), storage.FileDesc{}, nil, nil, o)
64 Expect(err).ShouldNot(HaveOccurred())
65 CheckOffset := func(key string, expect, threshold int) {
66 offset, err := tr.OffsetOf([]byte(key))
67 Expect(err).ShouldNot(HaveOccurred())
68 Expect(offset).Should(BeNumerically("~", expect, threshold), "Offset of key %q", key)
71 CheckOffset("k0", 0, 0)
72 CheckOffset("k01a", 0, 0)
73 CheckOffset("k02", 0, 0)
74 CheckOffset("k03", 0, 0)
75 CheckOffset("k04", 10000, 1000)
76 CheckOffset("k04a", 210000, 1000)
77 CheckOffset("k05", 210000, 1000)
78 CheckOffset("k06", 510000, 1000)
79 CheckOffset("k07", 510000, 1000)
80 CheckOffset("xyz", 610000, 2000)
84 Describe("read test", func() {
85 Build := func(kv testutil.KeyValue) testutil.DB {
88 BlockRestartInterval: 3,
90 buf := &bytes.Buffer{}
92 // Building the table.
93 tw := NewWriter(buf, o)
94 kv.Iterate(func(i int, key, value []byte) {
100 tr, _ := NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len()), storage.FileDesc{}, nil, nil, o)
101 return tableWrapper{tr}
103 Test := func(kv *testutil.KeyValue, body func(r *Reader)) func() {
107 body(db.(tableWrapper).Reader)
109 testutil.KeyValueTesting(nil, *kv, db, nil, nil)
113 testutil.AllKeyValueTesting(nil, Build, nil, nil)
114 Describe("with one key per block", Test(testutil.KeyValue_Generate(nil, 9, 1, 1, 10, 512, 512), func(r *Reader) {
115 It("should have correct blocks number", func() {
116 indexBlock, err := r.readBlock(r.indexBH, true)
117 Expect(err).To(BeNil())
118 Expect(indexBlock.restartsLen).Should(Equal(9))