You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

139 lines
3.5 KiB

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