github.com/gogf/gf/v2@v2.7.4/container/gtree/gtree_redblacktree.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/gogf/gf. 6 7 package gtree 8 9 import ( 10 "fmt" 11 12 "github.com/emirpasic/gods/trees/redblacktree" 13 "github.com/gogf/gf/v2/container/gvar" 14 "github.com/gogf/gf/v2/internal/json" 15 "github.com/gogf/gf/v2/internal/rwmutex" 16 "github.com/gogf/gf/v2/text/gstr" 17 "github.com/gogf/gf/v2/util/gconv" 18 "github.com/gogf/gf/v2/util/gutil" 19 ) 20 21 var _ iTree = (*RedBlackTree)(nil) 22 23 // RedBlackTree holds elements of the red-black tree. 24 type RedBlackTree struct { 25 mu rwmutex.RWMutex 26 comparator func(v1, v2 interface{}) int 27 tree *redblacktree.Tree 28 } 29 30 // RedBlackTreeNode is a single element within the tree. 31 type RedBlackTreeNode struct { 32 Key interface{} 33 Value interface{} 34 } 35 36 // NewRedBlackTree instantiates a red-black tree with the custom key comparator. 37 // The parameter `safe` is used to specify whether using tree in concurrent-safety, 38 // which is false in default. 39 func NewRedBlackTree(comparator func(v1, v2 interface{}) int, safe ...bool) *RedBlackTree { 40 return &RedBlackTree{ 41 mu: rwmutex.Create(safe...), 42 comparator: comparator, 43 tree: redblacktree.NewWith(comparator), 44 } 45 } 46 47 // NewRedBlackTreeFrom instantiates a red-black tree with the custom key comparator and `data` map. 48 // The parameter `safe` is used to specify whether using tree in concurrent-safety, 49 // which is false in default. 50 func NewRedBlackTreeFrom(comparator func(v1, v2 interface{}) int, data map[interface{}]interface{}, safe ...bool) *RedBlackTree { 51 tree := NewRedBlackTree(comparator, safe...) 52 for k, v := range data { 53 tree.doSet(k, v) 54 } 55 return tree 56 } 57 58 // SetComparator sets/changes the comparator for sorting. 59 func (tree *RedBlackTree) SetComparator(comparator func(a, b interface{}) int) { 60 tree.comparator = comparator 61 if tree.tree == nil { 62 tree.tree = redblacktree.NewWith(comparator) 63 } 64 size := tree.tree.Size() 65 if size > 0 { 66 m := tree.Map() 67 tree.Sets(m) 68 } 69 } 70 71 // Clone returns a new tree with a copy of current tree. 72 func (tree *RedBlackTree) Clone() *RedBlackTree { 73 newTree := NewRedBlackTree(tree.comparator, tree.mu.IsSafe()) 74 newTree.Sets(tree.Map()) 75 return newTree 76 } 77 78 // Set inserts node into the tree. 79 func (tree *RedBlackTree) Set(key interface{}, value interface{}) { 80 tree.mu.Lock() 81 defer tree.mu.Unlock() 82 tree.doSet(key, value) 83 } 84 85 // Sets batch sets key-values to the tree. 86 func (tree *RedBlackTree) Sets(data map[interface{}]interface{}) { 87 tree.mu.Lock() 88 defer tree.mu.Unlock() 89 for key, value := range data { 90 tree.doSet(key, value) 91 } 92 } 93 94 // SetIfNotExist sets `value` to the map if the `key` does not exist, and then returns true. 95 // It returns false if `key` exists, and `value` would be ignored. 96 func (tree *RedBlackTree) SetIfNotExist(key interface{}, value interface{}) bool { 97 tree.mu.Lock() 98 defer tree.mu.Unlock() 99 if _, ok := tree.doGet(key); !ok { 100 tree.doSet(key, value) 101 return true 102 } 103 return false 104 } 105 106 // SetIfNotExistFunc sets value with return value of callback function `f`, and then returns true. 107 // It returns false if `key` exists, and `value` would be ignored. 108 func (tree *RedBlackTree) SetIfNotExistFunc(key interface{}, f func() interface{}) bool { 109 tree.mu.Lock() 110 defer tree.mu.Unlock() 111 if _, ok := tree.doGet(key); !ok { 112 tree.doSet(key, f()) 113 return true 114 } 115 return false 116 } 117 118 // SetIfNotExistFuncLock sets value with return value of callback function `f`, and then returns true. 119 // It returns false if `key` exists, and `value` would be ignored. 120 // 121 // SetIfNotExistFuncLock differs with SetIfNotExistFunc function is that 122 // it executes function `f` with mutex.Lock of the hash map. 123 func (tree *RedBlackTree) SetIfNotExistFuncLock(key interface{}, f func() interface{}) bool { 124 tree.mu.Lock() 125 defer tree.mu.Unlock() 126 if _, ok := tree.doGet(key); !ok { 127 tree.doSet(key, f) 128 return true 129 } 130 return false 131 } 132 133 // Get searches the node in the tree by `key` and returns its value or nil if key is not found in tree. 134 func (tree *RedBlackTree) Get(key interface{}) (value interface{}) { 135 value, _ = tree.Search(key) 136 return 137 } 138 139 // GetOrSet returns the value by key, 140 // or sets value with given `value` if it does not exist and then returns this value. 141 func (tree *RedBlackTree) GetOrSet(key interface{}, value interface{}) interface{} { 142 tree.mu.Lock() 143 defer tree.mu.Unlock() 144 if v, ok := tree.doGet(key); !ok { 145 return tree.doSet(key, value) 146 } else { 147 return v 148 } 149 } 150 151 // GetOrSetFunc returns the value by key, 152 // or sets value with returned value of callback function `f` if it does not exist 153 // and then returns this value. 154 func (tree *RedBlackTree) GetOrSetFunc(key interface{}, f func() interface{}) interface{} { 155 tree.mu.Lock() 156 defer tree.mu.Unlock() 157 if v, ok := tree.doGet(key); !ok { 158 return tree.doSet(key, f()) 159 } else { 160 return v 161 } 162 } 163 164 // GetOrSetFuncLock returns the value by key, 165 // or sets value with returned value of callback function `f` if it does not exist 166 // and then returns this value. 167 // 168 // GetOrSetFuncLock differs with GetOrSetFunc function is that it executes function `f` 169 // with mutex.Lock of the hash map. 170 func (tree *RedBlackTree) GetOrSetFuncLock(key interface{}, f func() interface{}) interface{} { 171 tree.mu.Lock() 172 defer tree.mu.Unlock() 173 if v, ok := tree.doGet(key); !ok { 174 return tree.doSet(key, f) 175 } else { 176 return v 177 } 178 } 179 180 // GetVar returns a gvar.Var with the value by given `key`. 181 // The returned gvar.Var is un-concurrent safe. 182 func (tree *RedBlackTree) GetVar(key interface{}) *gvar.Var { 183 return gvar.New(tree.Get(key)) 184 } 185 186 // GetVarOrSet returns a gvar.Var with result from GetVarOrSet. 187 // The returned gvar.Var is un-concurrent safe. 188 func (tree *RedBlackTree) GetVarOrSet(key interface{}, value interface{}) *gvar.Var { 189 return gvar.New(tree.GetOrSet(key, value)) 190 } 191 192 // GetVarOrSetFunc returns a gvar.Var with result from GetOrSetFunc. 193 // The returned gvar.Var is un-concurrent safe. 194 func (tree *RedBlackTree) GetVarOrSetFunc(key interface{}, f func() interface{}) *gvar.Var { 195 return gvar.New(tree.GetOrSetFunc(key, f)) 196 } 197 198 // GetVarOrSetFuncLock returns a gvar.Var with result from GetOrSetFuncLock. 199 // The returned gvar.Var is un-concurrent safe. 200 func (tree *RedBlackTree) GetVarOrSetFuncLock(key interface{}, f func() interface{}) *gvar.Var { 201 return gvar.New(tree.GetOrSetFuncLock(key, f)) 202 } 203 204 // Search searches the tree with given `key`. 205 // Second return parameter `found` is true if key was found, otherwise false. 206 func (tree *RedBlackTree) Search(key interface{}) (value interface{}, found bool) { 207 tree.mu.RLock() 208 defer tree.mu.RUnlock() 209 if node, found := tree.doGet(key); found { 210 return node, true 211 } 212 return nil, false 213 } 214 215 // Contains checks whether `key` exists in the tree. 216 func (tree *RedBlackTree) Contains(key interface{}) bool { 217 tree.mu.RLock() 218 defer tree.mu.RUnlock() 219 _, ok := tree.doGet(key) 220 return ok 221 } 222 223 // Size returns number of nodes in the tree. 224 func (tree *RedBlackTree) Size() int { 225 tree.mu.RLock() 226 defer tree.mu.RUnlock() 227 return tree.tree.Size() 228 } 229 230 // IsEmpty returns true if tree does not contain any nodes. 231 func (tree *RedBlackTree) IsEmpty() bool { 232 tree.mu.RLock() 233 defer tree.mu.RUnlock() 234 return tree.tree.Size() == 0 235 } 236 237 // Remove removes the node from the tree by key. 238 // Key should adhere to the comparator's type assertion, otherwise method panics. 239 func (tree *RedBlackTree) Remove(key interface{}) (value interface{}) { 240 tree.mu.Lock() 241 defer tree.mu.Unlock() 242 return tree.doRemove(key) 243 } 244 245 // Removes batch deletes values of the tree by `keys`. 246 func (tree *RedBlackTree) Removes(keys []interface{}) { 247 tree.mu.Lock() 248 defer tree.mu.Unlock() 249 for _, key := range keys { 250 tree.doRemove(key) 251 } 252 } 253 254 // Clear removes all nodes from the tree. 255 func (tree *RedBlackTree) Clear() { 256 tree.mu.Lock() 257 defer tree.mu.Unlock() 258 tree.tree.Clear() 259 } 260 261 // Keys returns all keys in asc order. 262 func (tree *RedBlackTree) Keys() []interface{} { 263 tree.mu.RLock() 264 defer tree.mu.RUnlock() 265 return tree.tree.Keys() 266 } 267 268 // Values returns all values in asc order based on the key. 269 func (tree *RedBlackTree) Values() []interface{} { 270 tree.mu.RLock() 271 defer tree.mu.RUnlock() 272 return tree.tree.Values() 273 } 274 275 // Replace the data of the tree with given `data`. 276 func (tree *RedBlackTree) Replace(data map[interface{}]interface{}) { 277 tree.mu.Lock() 278 defer tree.mu.Unlock() 279 tree.tree.Clear() 280 for k, v := range data { 281 tree.doSet(k, v) 282 } 283 } 284 285 // Print prints the tree to stdout. 286 func (tree *RedBlackTree) Print() { 287 fmt.Println(tree.String()) 288 } 289 290 // String returns a string representation of container 291 func (tree *RedBlackTree) String() string { 292 tree.mu.RLock() 293 defer tree.mu.RUnlock() 294 return gstr.Replace(tree.tree.String(), "RedBlackTree\n", "") 295 } 296 297 // MarshalJSON implements the interface MarshalJSON for json.Marshal. 298 func (tree *RedBlackTree) MarshalJSON() (jsonBytes []byte, err error) { 299 tree.mu.RLock() 300 defer tree.mu.RUnlock() 301 return tree.tree.MarshalJSON() 302 } 303 304 // Map returns all key-value items as map. 305 func (tree *RedBlackTree) Map() map[interface{}]interface{} { 306 tree.mu.RLock() 307 defer tree.mu.RUnlock() 308 m := make(map[interface{}]interface{}, tree.Size()) 309 tree.IteratorAsc(func(key, value interface{}) bool { 310 m[key] = value 311 return true 312 }) 313 return m 314 } 315 316 // MapStrAny returns all key-value items as map[string]interface{}. 317 func (tree *RedBlackTree) MapStrAny() map[string]interface{} { 318 tree.mu.RLock() 319 defer tree.mu.RUnlock() 320 m := make(map[string]interface{}, tree.Size()) 321 tree.IteratorAsc(func(key, value interface{}) bool { 322 m[gconv.String(key)] = value 323 return true 324 }) 325 return m 326 } 327 328 // Iterator is alias of IteratorAsc. 329 func (tree *RedBlackTree) Iterator(f func(key, value interface{}) bool) { 330 tree.IteratorAsc(f) 331 } 332 333 // IteratorFrom is alias of IteratorAscFrom. 334 func (tree *RedBlackTree) IteratorFrom(key interface{}, match bool, f func(key, value interface{}) bool) { 335 tree.IteratorAscFrom(key, match, f) 336 } 337 338 // IteratorAsc iterates the tree readonly in ascending order with given callback function `f`. 339 // If `f` returns true, then it continues iterating; or false to stop. 340 func (tree *RedBlackTree) IteratorAsc(f func(key, value interface{}) bool) { 341 tree.mu.RLock() 342 defer tree.mu.RUnlock() 343 it := tree.tree.Iterator() 344 for it.Begin(); it.Next(); { 345 index, value := it.Key(), it.Value() 346 if ok := f(index, value); !ok { 347 break 348 } 349 } 350 } 351 352 // IteratorAscFrom iterates the tree readonly in ascending order with given callback function `f`. 353 // The parameter `key` specifies the start entry for iterating. The `match` specifies whether 354 // starting iterating if the `key` is fully matched, or else using index searching iterating. 355 // If `f` returns true, then it continues iterating; or false to stop. 356 func (tree *RedBlackTree) IteratorAscFrom(key interface{}, match bool, f func(key, value interface{}) bool) { 357 tree.mu.RLock() 358 defer tree.mu.RUnlock() 359 var keys = tree.tree.Keys() 360 index, isIterator := tree.iteratorFromGetIndex(key, keys, match) 361 if !isIterator { 362 return 363 } 364 for ; index < len(keys); index++ { 365 f(keys[index], tree.Get(keys[index])) 366 } 367 } 368 369 // IteratorDesc iterates the tree readonly in descending order with given callback function `f`. 370 // If `f` returns true, then it continues iterating; or false to stop. 371 func (tree *RedBlackTree) IteratorDesc(f func(key, value interface{}) bool) { 372 tree.mu.RLock() 373 defer tree.mu.RUnlock() 374 it := tree.tree.Iterator() 375 for it.End(); it.Prev(); { 376 index, value := it.Key(), it.Value() 377 if ok := f(index, value); !ok { 378 break 379 } 380 } 381 } 382 383 // IteratorDescFrom iterates the tree readonly in descending order with given callback function `f`. 384 // The parameter `key` specifies the start entry for iterating. The `match` specifies whether 385 // starting iterating if the `key` is fully matched, or else using index searching iterating. 386 // If `f` returns true, then it continues iterating; or false to stop. 387 func (tree *RedBlackTree) IteratorDescFrom(key interface{}, match bool, f func(key, value interface{}) bool) { 388 tree.mu.RLock() 389 defer tree.mu.RUnlock() 390 var keys = tree.tree.Keys() 391 index, isIterator := tree.iteratorFromGetIndex(key, keys, match) 392 if !isIterator { 393 return 394 } 395 for ; index >= 0; index-- { 396 f(keys[index], tree.Get(keys[index])) 397 } 398 } 399 400 // Left returns the minimum element of the AVL tree 401 // or nil if the tree is empty. 402 func (tree *RedBlackTree) Left() *RedBlackTreeNode { 403 tree.mu.RLock() 404 defer tree.mu.RUnlock() 405 node := tree.tree.Left() 406 if node == nil { 407 return nil 408 } 409 return &RedBlackTreeNode{ 410 Key: node.Key, 411 Value: node.Value, 412 } 413 } 414 415 // Right returns the maximum element of the AVL tree 416 // or nil if the tree is empty. 417 func (tree *RedBlackTree) Right() *RedBlackTreeNode { 418 tree.mu.RLock() 419 defer tree.mu.RUnlock() 420 node := tree.tree.Right() 421 if node == nil { 422 return nil 423 } 424 return &RedBlackTreeNode{ 425 Key: node.Key, 426 Value: node.Value, 427 } 428 } 429 430 // Floor Finds floor node of the input key, return the floor node or nil if no floor node is found. 431 // Second return parameter is true if floor was found, otherwise false. 432 // 433 // Floor node is defined as the largest node that is smaller than or equal to the given node. 434 // A floor node may not be found, either because the tree is empty, or because 435 // all nodes in the tree is larger than the given node. 436 // 437 // Key should adhere to the comparator's type assertion, otherwise method panics. 438 func (tree *RedBlackTree) Floor(key interface{}) (floor *RedBlackTreeNode, found bool) { 439 tree.mu.RLock() 440 defer tree.mu.RUnlock() 441 node, found := tree.tree.Floor(key) 442 if !found { 443 return nil, false 444 } 445 return &RedBlackTreeNode{ 446 Key: node.Key, 447 Value: node.Value, 448 }, true 449 } 450 451 // Ceiling finds ceiling node of the input key, return the ceiling node or nil if no ceiling node is found. 452 // Second return parameter is true if ceiling was found, otherwise false. 453 // 454 // Ceiling node is defined as the smallest node that is larger than or equal to the given node. 455 // A ceiling node may not be found, either because the tree is empty, or because 456 // all nodes in the tree is smaller than the given node. 457 // 458 // Key should adhere to the comparator's type assertion, otherwise method panics. 459 func (tree *RedBlackTree) Ceiling(key interface{}) (ceiling *RedBlackTreeNode, found bool) { 460 tree.mu.RLock() 461 defer tree.mu.RUnlock() 462 node, found := tree.tree.Ceiling(key) 463 if !found { 464 return nil, false 465 } 466 return &RedBlackTreeNode{ 467 Key: node.Key, 468 Value: node.Value, 469 }, true 470 } 471 472 // Flip exchanges key-value of the tree to value-key. 473 // Note that you should guarantee the value is the same type as key, 474 // or else the comparator would panic. 475 // 476 // If the type of value is different with key, you pass the new `comparator`. 477 func (tree *RedBlackTree) Flip(comparator ...func(v1, v2 interface{}) int) { 478 var t = new(RedBlackTree) 479 if len(comparator) > 0 { 480 t = NewRedBlackTree(comparator[0], tree.mu.IsSafe()) 481 } else { 482 t = NewRedBlackTree(tree.comparator, tree.mu.IsSafe()) 483 } 484 tree.IteratorAsc(func(key, value interface{}) bool { 485 t.doSet(value, key) 486 return true 487 }) 488 tree.Clear() 489 tree.Sets(t.Map()) 490 } 491 492 // UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal. 493 func (tree *RedBlackTree) UnmarshalJSON(b []byte) error { 494 tree.mu.Lock() 495 defer tree.mu.Unlock() 496 if tree.comparator == nil { 497 tree.comparator = gutil.ComparatorString 498 tree.tree = redblacktree.NewWith(tree.comparator) 499 } 500 var data map[string]interface{} 501 if err := json.UnmarshalUseNumber(b, &data); err != nil { 502 return err 503 } 504 for k, v := range data { 505 tree.doSet(k, v) 506 } 507 return nil 508 } 509 510 // UnmarshalValue is an interface implement which sets any type of value for map. 511 func (tree *RedBlackTree) UnmarshalValue(value interface{}) (err error) { 512 tree.mu.Lock() 513 defer tree.mu.Unlock() 514 if tree.comparator == nil { 515 tree.comparator = gutil.ComparatorString 516 tree.tree = redblacktree.NewWith(tree.comparator) 517 } 518 for k, v := range gconv.Map(value) { 519 tree.doSet(k, v) 520 } 521 return 522 } 523 524 // doSet sets key-value pair to the tree. 525 func (tree *RedBlackTree) doSet(key, value interface{}) interface{} { 526 if f, ok := value.(func() interface{}); ok { 527 value = f() 528 } 529 if value == nil { 530 return value 531 } 532 tree.tree.Put(key, value) 533 return value 534 } 535 536 // doGet retrieves and returns the value of given key from tree. 537 func (tree *RedBlackTree) doGet(key interface{}) (value interface{}, found bool) { 538 return tree.tree.Get(key) 539 } 540 541 // doRemove removes key from tree. 542 func (tree *RedBlackTree) doRemove(key interface{}) (value interface{}) { 543 value, _ = tree.tree.Get(key) 544 tree.tree.Remove(key) 545 return 546 } 547 548 // iteratorFromGetIndex returns the index of the key in the keys slice. 549 // The parameter `match` specifies whether starting iterating if the `key` is fully matched, 550 // or else using index searching iterating. 551 // If `isIterator` is true, iterator is available; or else not. 552 func (tree *RedBlackTree) iteratorFromGetIndex(key interface{}, keys []interface{}, match bool) (index int, isIterator bool) { 553 if match { 554 for i, k := range keys { 555 if k == key { 556 isIterator = true 557 index = i 558 } 559 } 560 } else { 561 if i, ok := key.(int); ok { 562 isIterator = true 563 index = i 564 } 565 } 566 return 567 }