1 package diskv
2
3 import (
4 "bytes"
5 "reflect"
6 "testing"
7 "time"
8 )
9
10 func strLess(a, b string) bool { return a < b }
11
12 func cmpStrings(a, b []string) bool {
13 if len(a) != len(b) {
14 return false
15 }
16 for i := 0; i < len(a); i++ {
17 if a[i] != b[i] {
18 return false
19 }
20 }
21 return true
22 }
23
24 func (d *Diskv) isIndexed(key string) bool {
25 if d.Index == nil {
26 return false
27 }
28
29 for _, got := range d.Index.Keys("", 1000) {
30 if got == key {
31 return true
32 }
33 }
34 return false
35 }
36
37 func TestIndexOrder(t *testing.T) {
38 d := New(Options{
39 BasePath: "index-test",
40 Transform: func(string) []string { return []string{} },
41 CacheSizeMax: 1024,
42 Index: &BTreeIndex{},
43 IndexLess: strLess,
44 })
45 defer d.EraseAll()
46
47 v := []byte{'1', '2', '3'}
48 d.Write("a", v)
49 if !d.isIndexed("a") {
50 t.Fatalf("'a' not indexed after write")
51 }
52 d.Write("1", v)
53 d.Write("m", v)
54 d.Write("-", v)
55 d.Write("A", v)
56
57 expectedKeys := []string{"-", "1", "A", "a", "m"}
58 keys := []string{}
59 for _, key := range d.Index.Keys("", 100) {
60 keys = append(keys, key)
61 }
62
63 if !cmpStrings(keys, expectedKeys) {
64 t.Fatalf("got %s, expected %s", keys, expectedKeys)
65 }
66 }
67
68 func TestIndexLoad(t *testing.T) {
69 d1 := New(Options{
70 BasePath: "index-test",
71 Transform: func(string) []string { return []string{} },
72 CacheSizeMax: 1024,
73 })
74 defer d1.EraseAll()
75
76 val := []byte{'1', '2', '3'}
77 keys := []string{"a", "b", "c", "d", "e", "f", "g"}
78 for _, key := range keys {
79 d1.Write(key, val)
80 }
81
82 d2 := New(Options{
83 BasePath: "index-test",
84 Transform: func(string) []string { return []string{} },
85 CacheSizeMax: 1024,
86 Index: &BTreeIndex{},
87 IndexLess: strLess,
88 })
89 defer d2.EraseAll()
90
91
92 for _, key := range keys {
93 if !d2.isIndexed(key) {
94 t.Fatalf("key '%s' not indexed on secondary", key)
95 }
96 }
97
98
99 if readValue, err := d2.Read(keys[0]); err != nil {
100 t.Fatalf("%s", err)
101 } else if bytes.Compare(val, readValue) != 0 {
102 t.Fatalf("%s: got %s, expected %s", keys[0], readValue, val)
103 }
104
105
106 for i := 0; i < 10 && !d2.isCached(keys[0]); i++ {
107 time.Sleep(10 * time.Millisecond)
108 }
109 if !d2.isCached(keys[0]) {
110 t.Fatalf("key '%s' not cached", keys[0])
111 }
112
113
114 d1.EraseAll()
115
116
117 if readValue, err := d2.Read(keys[0]); err != nil {
118 t.Fatalf("%s", err)
119 } else if bytes.Compare(val, readValue) != 0 {
120 t.Fatalf("%s: got %s, expected %s", keys[0], readValue, val)
121 }
122
123
124 if _, err := d1.Read(keys[0]); err == nil {
125 t.Fatalf("expected error reading from flushed store")
126 }
127 }
128
129 func TestIndexKeysEmptyFrom(t *testing.T) {
130 d := New(Options{
131 BasePath: "index-test",
132 Transform: func(string) []string { return []string{} },
133 CacheSizeMax: 1024,
134 Index: &BTreeIndex{},
135 IndexLess: strLess,
136 })
137 defer d.EraseAll()
138
139 for _, k := range []string{"a", "c", "z", "b", "x", "b", "y"} {
140 d.Write(k, []byte("1"))
141 }
142
143 want := []string{"a", "b", "c", "x", "y", "z"}
144 have := d.Index.Keys("", 99)
145 if !reflect.DeepEqual(want, have) {
146 t.Errorf("want %v, have %v", want, have)
147 }
148 }
149
View as plain text