github.com/sunvim/utils@v0.1.0/patricia/children.go (about) 1 // Copyright (c) 2014 The go-patricia AUTHORS 2 // 3 // Use of this source code is governed by The MIT License 4 // that can be found in the LICENSE file. 5 6 package patricia 7 8 import ( 9 "fmt" 10 "io" 11 "sort" 12 ) 13 14 type childList interface { 15 length() int 16 head() *Trie 17 add(child *Trie) childList 18 remove(b byte) 19 replace(b byte, child *Trie) 20 next(b byte) *Trie 21 walk(prefix *Prefix, visitor VisitorFunc) error 22 print(w io.Writer, indent int) 23 clone() childList 24 total() int 25 } 26 27 type tries []*Trie 28 29 func (t tries) Len() int { 30 return len(t) 31 } 32 33 func (t tries) Less(i, j int) bool { 34 strings := sort.StringSlice{string(t[i].prefix), string(t[j].prefix)} 35 return strings.Less(0, 1) 36 } 37 38 func (t tries) Swap(i, j int) { 39 t[i], t[j] = t[j], t[i] 40 } 41 42 type sparseChildList struct { 43 children tries 44 } 45 46 func newSparseChildList(maxChildrenPerSparseNode int) childList { 47 return &sparseChildList{ 48 children: make(tries, 0, maxChildrenPerSparseNode), 49 } 50 } 51 52 func (list *sparseChildList) length() int { 53 return len(list.children) 54 } 55 56 func (list *sparseChildList) head() *Trie { 57 return list.children[0] 58 } 59 60 func (list *sparseChildList) add(child *Trie) childList { 61 // Search for an empty spot and insert the child if possible. 62 if len(list.children) != cap(list.children) { 63 list.children = append(list.children, child) 64 return list 65 } 66 67 // Otherwise we have to transform to the dense list type. 68 return newDenseChildList(list, child) 69 } 70 71 func (list *sparseChildList) remove(b byte) { 72 for i, node := range list.children { 73 if node.prefix[0] == b { 74 list.children[i] = list.children[len(list.children)-1] 75 list.children[len(list.children)-1] = nil 76 list.children = list.children[:len(list.children)-1] 77 return 78 } 79 } 80 81 // This is not supposed to be reached. 82 panic("removing non-existent child") 83 } 84 85 func (list *sparseChildList) replace(b byte, child *Trie) { 86 // Make a consistency check. 87 if p0 := child.prefix[0]; p0 != b { 88 panic(fmt.Errorf("child prefix mismatch: %v != %v", p0, b)) 89 } 90 91 // Seek the child and replace it. 92 for i, node := range list.children { 93 if node.prefix[0] == b { 94 list.children[i] = child 95 return 96 } 97 } 98 } 99 100 func (list *sparseChildList) next(b byte) *Trie { 101 for _, child := range list.children { 102 if child.prefix[0] == b { 103 return child 104 } 105 } 106 return nil 107 } 108 109 func (list *sparseChildList) walk(prefix *Prefix, visitor VisitorFunc) error { 110 111 sort.Sort(list.children) 112 113 for _, child := range list.children { 114 *prefix = append(*prefix, child.prefix...) 115 if child.item != nil { 116 err := visitor(*prefix, child.item) 117 if err != nil { 118 if err == SkipSubtree { 119 *prefix = (*prefix)[:len(*prefix)-len(child.prefix)] 120 continue 121 } 122 *prefix = (*prefix)[:len(*prefix)-len(child.prefix)] 123 return err 124 } 125 } 126 127 err := child.children.walk(prefix, visitor) 128 *prefix = (*prefix)[:len(*prefix)-len(child.prefix)] 129 if err != nil { 130 return err 131 } 132 } 133 134 return nil 135 } 136 137 func (list *sparseChildList) total() int { 138 tot := 0 139 for _, child := range list.children { 140 if child != nil { 141 tot = tot + child.total() 142 } 143 } 144 return tot 145 } 146 147 func (list *sparseChildList) clone() childList { 148 clones := make(tries, len(list.children), cap(list.children)) 149 for i, child := range list.children { 150 clones[i] = child.Clone() 151 } 152 153 return &sparseChildList{ 154 children: clones, 155 } 156 } 157 158 func (list *sparseChildList) print(w io.Writer, indent int) { 159 for _, child := range list.children { 160 if child != nil { 161 child.print(w, indent) 162 } 163 } 164 } 165 166 type denseChildList struct { 167 min int 168 max int 169 numChildren int 170 headIndex int 171 children []*Trie 172 } 173 174 func newDenseChildList(list *sparseChildList, child *Trie) childList { 175 var ( 176 min int = 255 177 max int = 0 178 ) 179 for _, child := range list.children { 180 b := int(child.prefix[0]) 181 if b < min { 182 min = b 183 } 184 if b > max { 185 max = b 186 } 187 } 188 189 b := int(child.prefix[0]) 190 if b < min { 191 min = b 192 } 193 if b > max { 194 max = b 195 } 196 197 children := make([]*Trie, max-min+1) 198 for _, child := range list.children { 199 children[int(child.prefix[0])-min] = child 200 } 201 children[int(child.prefix[0])-min] = child 202 203 return &denseChildList{ 204 min: min, 205 max: max, 206 numChildren: list.length() + 1, 207 headIndex: 0, 208 children: children, 209 } 210 } 211 212 func (list *denseChildList) length() int { 213 return list.numChildren 214 } 215 216 func (list *denseChildList) head() *Trie { 217 return list.children[list.headIndex] 218 } 219 220 func (list *denseChildList) add(child *Trie) childList { 221 b := int(child.prefix[0]) 222 var i int 223 224 switch { 225 case list.min <= b && b <= list.max: 226 if list.children[b-list.min] != nil { 227 panic("dense child list collision detected") 228 } 229 i = b - list.min 230 list.children[i] = child 231 232 case b < list.min: 233 children := make([]*Trie, list.max-b+1) 234 i = 0 235 children[i] = child 236 copy(children[list.min-b:], list.children) 237 list.children = children 238 list.min = b 239 240 default: // b > list.max 241 children := make([]*Trie, b-list.min+1) 242 i = b - list.min 243 children[i] = child 244 copy(children, list.children) 245 list.children = children 246 list.max = b 247 } 248 249 list.numChildren++ 250 if i < list.headIndex { 251 list.headIndex = i 252 } 253 return list 254 } 255 256 func (list *denseChildList) remove(b byte) { 257 i := int(b) - list.min 258 if list.children[i] == nil { 259 // This is not supposed to be reached. 260 panic("removing non-existent child") 261 } 262 list.numChildren-- 263 list.children[i] = nil 264 265 // Update head index. 266 if i == list.headIndex { 267 for ; i < len(list.children); i++ { 268 if list.children[i] != nil { 269 list.headIndex = i 270 return 271 } 272 } 273 } 274 } 275 276 func (list *denseChildList) replace(b byte, child *Trie) { 277 // Make a consistency check. 278 if p0 := child.prefix[0]; p0 != b { 279 panic(fmt.Errorf("child prefix mismatch: %v != %v", p0, b)) 280 } 281 282 // Replace the child. 283 list.children[int(b)-list.min] = child 284 } 285 286 func (list *denseChildList) next(b byte) *Trie { 287 i := int(b) 288 if i < list.min || list.max < i { 289 return nil 290 } 291 return list.children[i-list.min] 292 } 293 294 func (list *denseChildList) walk(prefix *Prefix, visitor VisitorFunc) error { 295 for _, child := range list.children { 296 if child == nil { 297 continue 298 } 299 *prefix = append(*prefix, child.prefix...) 300 if child.item != nil { 301 if err := visitor(*prefix, child.item); err != nil { 302 if err == SkipSubtree { 303 *prefix = (*prefix)[:len(*prefix)-len(child.prefix)] 304 continue 305 } 306 *prefix = (*prefix)[:len(*prefix)-len(child.prefix)] 307 return err 308 } 309 } 310 311 err := child.children.walk(prefix, visitor) 312 *prefix = (*prefix)[:len(*prefix)-len(child.prefix)] 313 if err != nil { 314 return err 315 } 316 } 317 318 return nil 319 } 320 321 func (list *denseChildList) print(w io.Writer, indent int) { 322 for _, child := range list.children { 323 if child != nil { 324 child.print(w, indent) 325 } 326 } 327 } 328 329 func (list *denseChildList) clone() childList { 330 clones := make(tries, cap(list.children)) 331 332 if list.numChildren != 0 { 333 clonedCount := 0 334 for i := list.headIndex; i < len(list.children); i++ { 335 child := list.children[i] 336 if child != nil { 337 clones[i] = child.Clone() 338 clonedCount++ 339 if clonedCount == list.numChildren { 340 break 341 } 342 } 343 } 344 } 345 346 return &denseChildList{ 347 min: list.min, 348 max: list.max, 349 numChildren: list.numChildren, 350 headIndex: list.headIndex, 351 children: clones, 352 } 353 } 354 355 func (list *denseChildList) total() int { 356 tot := 0 357 for _, child := range list.children { 358 if child != nil { 359 tot = tot + child.total() 360 } 361 } 362 return tot 363 }