|
|
// Copyright (c) 2014, Suryandaru Triandana <syndtr@gmail.com>
// All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package table
import ( "encoding/binary" "fmt"
. "github.com/onsi/ginkgo" . "github.com/onsi/gomega"
"github.com/syndtr/goleveldb/leveldb/comparer" "github.com/syndtr/goleveldb/leveldb/iterator" "github.com/syndtr/goleveldb/leveldb/testutil" "github.com/syndtr/goleveldb/leveldb/util" )
type blockTesting struct { tr *Reader b *block }
func (t *blockTesting) TestNewIterator(slice *util.Range) iterator.Iterator { return t.tr.newBlockIter(t.b, nil, slice, false) }
var _ = testutil.Defer(func() { Describe("Block", func() { Build := func(kv *testutil.KeyValue, restartInterval int) *blockTesting { // Building the block.
bw := &blockWriter{ restartInterval: restartInterval, scratch: make([]byte, 30), } kv.Iterate(func(i int, key, value []byte) { bw.append(key, value) }) bw.finish()
// Opening the block.
data := bw.buf.Bytes() restartsLen := int(binary.LittleEndian.Uint32(data[len(data)-4:])) return &blockTesting{ tr: &Reader{cmp: comparer.DefaultComparer}, b: &block{ data: data, restartsLen: restartsLen, restartsOffset: len(data) - (restartsLen+1)*4, }, } }
Describe("read test", func() { for restartInterval := 1; restartInterval <= 5; restartInterval++ { Describe(fmt.Sprintf("with restart interval of %d", restartInterval), func() { kv := &testutil.KeyValue{} Text := func() string { return fmt.Sprintf("and %d keys", kv.Len()) }
Test := func() { // Make block.
br := Build(kv, restartInterval) // Do testing.
testutil.KeyValueTesting(nil, kv.Clone(), br, nil, nil) }
Describe(Text(), Test)
kv.PutString("", "empty") Describe(Text(), Test)
kv.PutString("a1", "foo") Describe(Text(), Test)
kv.PutString("a2", "v") Describe(Text(), Test)
kv.PutString("a3qqwrkks", "hello") Describe(Text(), Test)
kv.PutString("a4", "bar") Describe(Text(), Test)
kv.PutString("a5111111", "v5") kv.PutString("a6", "") kv.PutString("a7", "v7") kv.PutString("a8", "vvvvvvvvvvvvvvvvvvvvvv8") kv.PutString("b", "v9") kv.PutString("c9", "v9") kv.PutString("c91", "v9") kv.PutString("d0", "v9") Describe(Text(), Test) }) } })
Describe("out-of-bound slice test", func() { kv := &testutil.KeyValue{} kv.PutString("k1", "v1") kv.PutString("k2", "v2") kv.PutString("k3abcdefgg", "v3") kv.PutString("k4", "v4") kv.PutString("k5", "v5") for restartInterval := 1; restartInterval <= 5; restartInterval++ { Describe(fmt.Sprintf("with restart interval of %d", restartInterval), func() { // Make block.
bt := Build(kv, restartInterval)
Test := func(r *util.Range) func(done Done) { return func(done Done) { iter := bt.TestNewIterator(r) Expect(iter.Error()).ShouldNot(HaveOccurred())
t := testutil.IteratorTesting{ KeyValue: kv.Clone(), Iter: iter, }
testutil.DoIteratorTesting(&t) iter.Release() done <- true } }
It("Should do iterations and seeks correctly #0", Test(&util.Range{Start: []byte("k0"), Limit: []byte("k6")}), 2.0)
It("Should do iterations and seeks correctly #1", Test(&util.Range{Start: []byte(""), Limit: []byte("zzzzzzz")}), 2.0) }) } }) }) })
|