github.com/peterbourgon/diskv@v2.0.1+incompatible/index_test.go (about) 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 // check d2 has properly loaded existing d1 data 92 for _, key := range keys { 93 if !d2.isIndexed(key) { 94 t.Fatalf("key '%s' not indexed on secondary", key) 95 } 96 } 97 98 // cache one 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 // make sure it got cached 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 // kill the disk 114 d1.EraseAll() 115 116 // cached value should still be there in the second 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 // but not in the original 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 }