github.com/go-ego/cedar@v0.10.2/dict_test.go (about) 1 package cedar 2 3 import ( 4 "bufio" 5 "fmt" 6 "io" 7 "log" 8 "os" 9 "testing" 10 ) 11 12 type item struct { 13 key []byte 14 value int 15 } 16 17 var ( 18 dict []item 19 20 trie = New() 21 ) 22 23 func loadDict() []item { 24 testFile := "testdata/dict.txt" 25 f, err := os.Open(testFile) 26 if err != nil { 27 log.Fatal("failed to open ", testFile) 28 } 29 defer f.Close() 30 31 in := bufio.NewReader(f) 32 added := make(map[string]struct{}) 33 34 var ( 35 key string 36 freq int 37 pos string 38 ) 39 40 for { 41 _, err := fmt.Fscanln(in, &key, &freq, &pos) 42 if err == io.EOF { 43 break 44 } 45 46 if _, ok := added[string(key)]; !ok { 47 dict = append(dict, item{[]byte(key), freq}) 48 added[string(key)] = struct{}{} 49 } 50 } 51 52 return dict 53 } 54 55 func exist(i int) { 56 item := dict[i] 57 // fmt.Println(i, string(item.key)) 58 id, err := trie.Jump(item.key, 0) 59 failIfError(err) 60 61 key, err := trie.Key(id) 62 failIfError(err) 63 64 value, err := trie.Value(id) 65 failIfError(err) 66 67 if string(key) != string(item.key) || value != item.value { 68 v, _ := trie.Get(item.key) 69 fmt.Println("exist but no equal: ", i, string(key), string(item.key), value, item.value, v) 70 panic("large dict test fail: no equal") 71 } 72 } 73 74 func notExist(i int) { 75 _, err := trie.Get(dict[i].key) 76 // fmt.Println(i, err) 77 if err != ErrNoPath && err != ErrNoValue { 78 panic("large dict test fail: should not exist") 79 } 80 } 81 82 func checkSize(exp int) { 83 if keys, _, _, _ := trie.Status(); keys != exp { 84 panic("not correct status") 85 } 86 } 87 88 func insertDict(size int) { 89 // Insert the first half of the dict. 90 for i := 0; i < size/2; i++ { 91 item := dict[i] 92 if i%2 == 0 { 93 if err := trie.Insert(item.key, item.value); err != nil { 94 panic(err) 95 } 96 } else { 97 if err := trie.Update(item.key, item.value); err != nil { 98 panic(err) 99 } 100 } 101 } 102 checkSize(size / 2) 103 } 104 105 func checkDict(size int) { 106 // Check the first half of the dict. 107 for i := 0; i < size/2; i++ { 108 exist(i) 109 } 110 log.Println("first half OK") 111 112 // Delete even items in the first half. 113 for i := 0; i < size/2; i += 2 { 114 err := trie.Delete(dict[i].key) 115 failIfError(err) 116 } 117 checkSize(size / 2 / 2) 118 119 // Make sure even items were deleted, and the rest are fine. 120 for i := 0; i < size/2; i++ { 121 if i%2 == 0 { 122 notExist(i) 123 } else { 124 exist(i) 125 } 126 } 127 log.Println("first half odd OK") 128 129 // Insert the second half of the dict. 130 for i := size / 2; i < size; i++ { 131 item := dict[i] 132 trie.Insert(item.key, item.value) 133 } 134 checkSize(size/2/2 + (size - size/2)) 135 } 136 137 func odd(size int) { 138 for i := 0; i < size/2; i++ { 139 if i%2 == 0 { 140 notExist(i) 141 } else { 142 exist(i) 143 } 144 } 145 log.Println("first half odd still OK") 146 147 // Delete even items in the second half. 148 half := size / 2 149 if half%2 == 1 { 150 half++ 151 } 152 153 for i := half; i < size; i += 2 { 154 err := trie.Delete(dict[i].key) 155 failIfError(err) 156 } 157 158 // Make sure even items were deleted, and the rest are fine. 159 for i := 0; i < size; i++ { 160 if i%2 == 0 { 161 notExist(i) 162 } else { 163 exist(i) 164 } 165 } 166 167 log.Println("odd OK") 168 } 169 170 func even(size int) { 171 // Insert all even terms. 172 for i := 0; i < size; i += 2 { 173 item := dict[i] 174 notExist(i) 175 trie.Update([]byte(item.key), item.value) 176 } 177 178 for i := 0; i < size; i++ { 179 exist(i) 180 } 181 log.Println("all OK") 182 183 // Insert every item again, should be fine. 184 for i := 1; i < size; i++ { 185 item := dict[i] 186 trie.Insert([]byte(item.key), item.value) 187 } 188 189 for i := 1; i < size; i += 2 { 190 exist(i) 191 } 192 log.Println("still OK") 193 } 194 195 func TestLargeDict(t *testing.T) { 196 loadDict() 197 size := len(dict) 198 log.Println("dict size:", size) 199 200 insertDict(size) 201 checkDict(size) 202 203 odd(size) 204 even(size) 205 } 206 207 func failIfError(err error) { 208 if err != nil { 209 panic(err) 210 } 211 }