github.com/searKing/golang/go@v1.2.117/container/trie_tree/ternary_search_tree/node.go (about) 1 // Copyright 2020 The searKing Author. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package ternary_search_tree 6 7 import ( 8 "fmt" 9 "strings" 10 11 "github.com/searKing/golang/go/container/traversal" 12 ) 13 14 const ( 15 NilKey = 0 16 ) 17 18 type node struct { 19 prefix []byte 20 key byte 21 hasKey bool 22 value any 23 hasValue bool 24 25 left, middle, right *node 26 tree *TernarySearchTree 27 } 28 29 func (n *node) LeftNodes() []any { 30 left := n.Left() 31 if left == nil { 32 return nil 33 } 34 return []any{left} 35 } 36 37 func (n *node) MiddleNodes() []any { 38 middle := n.Middle() 39 if middle == nil { 40 return nil 41 } 42 return []any{middle} 43 } 44 45 func (n *node) RightNodes() []any { 46 right := n.Right() 47 if right == nil { 48 return nil 49 } 50 return []any{right} 51 } 52 53 // Left returns the left list node or nil. 54 func (n *node) Left() *node { 55 if p := n.left; n.tree != nil && p != &n.tree.root { 56 return p 57 } 58 return nil 59 } 60 61 // Middle returns the middle list node or nil. 62 func (n *node) Middle() *node { 63 if p := n.middle; n.tree != nil && p != &n.tree.root { 64 return p 65 } 66 return nil 67 } 68 69 // Right returns the right list node or nil. 70 func (n *node) Right() *node { 71 if p := n.right; n.tree != nil && p != &n.tree.root { 72 return p 73 } 74 return nil 75 } 76 77 func (n *node) Traversal(order traversal.Order, handler Handler) { 78 if handler == nil { 79 return 80 } 81 if !n.hasKey { 82 return 83 } 84 order(n, traversal.HandlerFunc(func(ele any, depth int) (goon bool) { 85 currentNode := ele.(*node) 86 if !currentNode.hasKey || !currentNode.hasValue { 87 return true 88 } 89 return handler.Handle(currentNode.prefix, currentNode.value) 90 })) 91 return 92 } 93 94 func (n *node) Follow(prefix []byte) (key []byte, value any, ok bool) { 95 graph := n.follow(prefix) 96 if len(graph) == 0 { 97 return nil, nil, false 98 } 99 tail := graph[len(graph)-1] 100 return tail.prefix, tail.value, tail.hasValue 101 } 102 103 func (n *node) Load(prefix []byte) (value any, ok bool) { 104 cur, _, _, has := n.search(prefix) 105 if !has { 106 return nil, false 107 } 108 return cur.value, cur.hasValue 109 } 110 111 func (n *node) ContainsPrefix(prefix []byte) bool { 112 cur, _, _, has := n.search(prefix) 113 if !has { 114 return false 115 } 116 return cur.hasKey 117 } 118 119 func (n *node) Contains(prefix []byte) bool { 120 _, ok := n.Load(prefix) 121 return ok 122 } 123 124 type pos int 125 126 const ( 127 posNotFound pos = iota // Root's middle, default 128 posLeft 129 posMiddle 130 posRight 131 posRoot 132 ) 133 134 func (n *node) Store(prefix []byte, value any) { 135 // force update 136 n.CAS(prefix, nil, value, func(x, y any) int { return 0 }) 137 } 138 139 func (n *node) remove(prefix []byte, shrinkToFit bool, omitMiddle bool) (old any, ok bool) { 140 cur, last, lastPos, has := n.search(prefix) 141 if !has { 142 return nil, false 143 } 144 // shrinkToFit if cur's children are empty 145 if shrinkToFit { 146 cur.shrinkToFit(last, lastPos, omitMiddle) 147 } 148 149 if !cur.hasValue { 150 return nil, false 151 } 152 cur.hasValue = false 153 // all matched, goto remove the old 154 return cur.value, true 155 } 156 157 func (n *node) Remove(prefix []byte, shrinkToFit bool) (old any, ok bool) { 158 return n.remove(prefix, shrinkToFit, false) 159 } 160 161 func (n *node) RemoveAll(prefix []byte) (value any, ok bool) { 162 return n.remove(prefix, true, true) 163 } 164 165 func (n *node) String() string { 166 s := "" 167 n.Traversal(traversal.Inorder, HandlerFunc(func(prefix []byte, value any) (goon bool) { 168 s += fmt.Sprintf("%s:%v\n", string(prefix), value) 169 return true 170 })) 171 172 return strings.TrimRight(s, "\n") 173 } 174 175 func (n *node) CAS(prefix []byte, old, new any, cmps ...func(x, y any) int) bool { 176 newElement := func(prefix []byte, hasKey bool, key byte, hasValue bool, value any) *node { 177 var p = make([]byte, len(prefix)) 178 copy(p, prefix) 179 return &node{ 180 prefix: p, 181 key: key, 182 hasKey: hasKey, 183 value: value, 184 hasValue: hasValue, 185 left: &n.tree.root, 186 middle: &n.tree.root, 187 right: &n.tree.root, 188 tree: n.tree, 189 } 190 } 191 192 cur := n 193 for idx := 0; idx < len(prefix); { 194 // create the idx layer if not exist 195 // otherwise, step to the next layer 196 k := prefix[idx] 197 if !cur.hasKey { 198 cur.key = k 199 cur.hasKey = true 200 cur.prefix = prefix[:idx+1] 201 } 202 // goto left 203 if k < cur.key { 204 left := cur.Left() 205 if left == nil { 206 cur.left = newElement(prefix[:idx+1], true, k, false, nil) 207 } 208 cur = cur.left 209 continue 210 } 211 // goto right 212 if k > cur.key { 213 right := cur.Right() 214 if right == nil { 215 cur.right = newElement(prefix[:idx+1], true, k, false, nil) 216 } 217 cur = cur.right 218 continue 219 } 220 // key match, goto match next layer 221 idx++ 222 // all matched, goto set the value 223 if idx == len(prefix) { 224 // no old 225 if !cur.hasValue { 226 cur.value = new 227 cur.hasValue = true 228 return true 229 } 230 var cmp func(x, y any) int 231 if len(cmps) > 0 { 232 cmp = cmps[0] 233 } 234 if cmp == nil { 235 cmp = func(x, y any) int { 236 if x == y { 237 return 0 238 } 239 return -1 240 } 241 } 242 if cmp(cur.value, old) == 0 { 243 cur.value = new 244 cur.hasValue = true 245 return true 246 } 247 return false 248 } 249 // partial matched, goto middle on next layer 250 middle := cur.Middle() 251 if middle == nil { 252 cur.middle = newElement(nil, false, NilKey, false, nil) 253 } 254 cur = cur.middle 255 } 256 // never reach 257 return false 258 } 259 260 // Depth return max len of all prefixs 261 func (n *node) Depth() int { 262 var depth int 263 n.Traversal(traversal.Preorder, HandlerFunc(func(prefix []byte, value any) (goon bool) { 264 if depth < len(prefix) { 265 depth = len(prefix) 266 } 267 return true 268 })) 269 return depth 270 } 271 272 // shrinkToFit cutoff last node's children nodes if all children nodes are empty 273 func (n *node) shrinkToFit(last *node, lastPos pos, omitMiddle bool) { 274 var has bool 275 n.Traversal(traversal.Preorder, HandlerFunc(func(prefix []byte, value any) (goon bool) { 276 has = true 277 return false 278 })) 279 if !has { 280 return 281 } 282 283 // match 284 switch lastPos { 285 case posLeft: 286 n.shrinkLeft(last, omitMiddle) 287 case posMiddle: 288 n.shrinkMiddle(last, omitMiddle) 289 case posRight: 290 n.shrinkRight(last, omitMiddle) 291 case posRoot: 292 n.shrinkRoot(last, omitMiddle) 293 } 294 } 295 296 // return node graph until prefix matched 297 func (n *node) follow(prefix []byte) (graph []*node) { 298 cur := n 299 300 for idx := 0; idx < len(prefix); { 301 // return if nilKey has been meet 302 if !cur.hasKey { 303 return 304 } 305 // create the idx layer if not exist 306 // otherwise, step to the next layer 307 k := prefix[idx] 308 if k < cur.key { 309 left := cur.Left() 310 if left == nil { 311 return 312 } 313 cur = left 314 continue 315 } 316 if k > cur.key { 317 right := cur.Right() 318 if right == nil { 319 return 320 } 321 cur = right 322 continue 323 } 324 if cur.hasValue { 325 graph = append(graph, cur) 326 } 327 // key match, goto match next layer 328 idx++ 329 // all matched, goto remove the value 330 if idx == len(prefix) { 331 // match 332 return 333 } 334 // partial matched, goto middle on next layer 335 middle := cur.Middle() 336 if middle == nil { 337 return 338 } 339 cur = middle 340 } 341 return 342 } 343 344 // return true if prefix matches, no matter value exists 345 func (n *node) search(prefix []byte) (cur, last *node, lastPos pos, has bool) { 346 cur = n 347 last = n 348 349 lastPos = posNotFound 350 for idx := 0; idx < len(prefix); { 351 // return if nilKey has been met 352 if !cur.hasKey { 353 return 354 } 355 // create the idx layer if not exist 356 // otherwise, step to the next layer 357 k := prefix[idx] 358 if k < cur.key { 359 left := cur.Left() 360 if left == nil { 361 return 362 } 363 last = cur 364 lastPos = posLeft 365 cur = left 366 continue 367 } 368 if k > cur.key { 369 right := cur.Right() 370 if right == nil { 371 return 372 } 373 last = cur 374 lastPos = posRight 375 cur = right 376 continue 377 } 378 // key match, goto match next layer 379 idx++ 380 // all matched, goto remove the value 381 if idx == len(prefix) { 382 // match 383 // Special case: prefix is Root node 384 if idx == 1 { 385 lastPos = posRoot 386 } 387 return cur, last, lastPos, true 388 } 389 // partial matched, goto middle on next layer 390 middle := cur.Middle() 391 if middle == nil { 392 return 393 } 394 last = cur 395 lastPos = posMiddle 396 cur = middle 397 } 398 return 399 } 400 401 func (n *node) IsLeaf() bool { 402 if !n.hasKey { 403 return false 404 } 405 if n.Left() != nil { 406 return false 407 } 408 if n.Middle() != nil { 409 return false 410 } 411 if n.Right() != nil { 412 return false 413 } 414 return false 415 } 416 417 func (n *node) shrinkLeft(last *node, omitMiddle bool) { 418 cur := last.left 419 if omitMiddle { 420 cur.middle = &n.tree.root 421 } 422 // L M R empty 423 // remove current node if all children nodes of current node are empty 424 if cur.Left() == nil && cur.Right() == nil && cur.Middle() == nil { 425 last.right = &n.tree.root 426 return 427 } 428 429 // M nonempty 430 if cur.Middle() != nil { 431 return 432 } 433 // M is empty below 434 435 // reconnect only one nonempty child[L|R] to be Parent Node's left node 436 if cur.Left() == nil { 437 last.left = cur.right 438 return 439 } 440 if cur.Right() == nil { 441 last.left = cur.left 442 return 443 } 444 445 // L|R both nonempty, M empty 446 447 // Step1. merge L onto R's left most node 448 node := cur.right 449 for { 450 if node.Left() == nil { 451 node.left = cur.left 452 break 453 } 454 node = node.left 455 } 456 // Step1. move R to be Parent Node's left node 457 last.left = cur.right 458 } 459 460 func (n *node) shrinkRight(last *node, omitMiddle bool) { 461 cur := last.middle 462 if omitMiddle { 463 cur.middle = &n.tree.root 464 } 465 // remove current node if all children nodes of current node are empty 466 if cur.Left() == nil && cur.Right() == nil && cur.Middle() == nil { 467 last.middle = &n.tree.root 468 return 469 } 470 // M nonempty 471 if cur.Middle() != nil { 472 return 473 } 474 // M is empty below 475 476 // reconnect only one nonempty child[L|R] to be Parent Node's middle node 477 if cur.Left() == nil { 478 last.middle = cur.right 479 return 480 } 481 if cur.Right() == nil { 482 last.middle = cur.left 483 return 484 } 485 486 // L|R both nonempty, M empty 487 488 // Step1. merge R onto L's right most node 489 node := cur.left 490 for { 491 if node.Right() == nil { 492 node.right = cur.right 493 break 494 } 495 node = node.right 496 } 497 // Step1. move L to be Parent Node's middle node 498 last.middle = cur.left 499 } 500 501 func (n *node) shrinkMiddle(last *node, omitMiddle bool) { 502 cur := last.middle 503 if omitMiddle { 504 cur.middle = &n.tree.root 505 } 506 // remove current node if all children nodes of current node are empty 507 if cur.Left() == nil && cur.Right() == nil && cur.Middle() == nil { 508 last.middle = &n.tree.root 509 return 510 } 511 // M nonempty 512 if cur.Middle() != nil { 513 return 514 } 515 // M is empty below 516 517 // reconnect only one nonempty child[L|R] to be Parent Node's middle node 518 if cur.Left() == nil { 519 last.middle = cur.right 520 return 521 } 522 if cur.Right() == nil { 523 last.middle = cur.left 524 return 525 } 526 527 // L|R both nonempty, M empty 528 529 // Step1. merge R onto L's right most node 530 node := cur.left 531 for { 532 if node.Right() == nil { 533 node.right = cur.right 534 break 535 } 536 node = node.right 537 } 538 // Step1. move L to be Parent Node's middle node 539 last.middle = cur.left 540 } 541 542 func (n *node) shrinkRoot(last *node, omitMiddle bool) { 543 cur := last 544 if omitMiddle { 545 cur.middle = &n.tree.root 546 } 547 // nop if all children nodes of current node are empty 548 if cur.Left() == nil && cur.Right() == nil && cur.Middle() == nil { 549 return 550 } 551 // M nonempty 552 if cur.Middle() != nil { 553 return 554 } 555 // M is empty below 556 557 // reconnect only one nonempty child[L|R] to be Parent Node 558 if cur.Left() == nil { 559 last = cur.right 560 return 561 } 562 if cur.Right() == nil { 563 last.middle = cur.left 564 return 565 } 566 567 // L|R both nonempty, M empty 568 569 // Step1. merge R onto L's right most node 570 node := cur.left 571 for { 572 if node.Right() == nil { 573 node.right = cur.right 574 break 575 } 576 node = node.right 577 } 578 // Step1. move L to be Parent Node 579 last = cur.left 580 }