github.com/gogf/gf/v2@v2.7.4/container/gtree/gtree_btree.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/btree" 13 "github.com/gogf/gf/v2/container/gvar" 14 "github.com/gogf/gf/v2/internal/rwmutex" 15 "github.com/gogf/gf/v2/text/gstr" 16 "github.com/gogf/gf/v2/util/gconv" 17 ) 18 19 var _ iTree = (*BTree)(nil) 20 21 // BTree holds elements of the B-tree. 22 type BTree struct { 23 mu rwmutex.RWMutex 24 comparator func(v1, v2 interface{}) int 25 m int // order (maximum number of children) 26 tree *btree.Tree 27 } 28 29 // BTreeEntry represents the key-value pair contained within nodes. 30 type BTreeEntry struct { 31 Key interface{} 32 Value interface{} 33 } 34 35 // NewBTree instantiates a B-tree with `m` (maximum number of children) and a custom key comparator. 36 // The parameter `safe` is used to specify whether using tree in concurrent-safety, 37 // which is false in default. 38 // Note that the `m` must be greater or equal than 3, or else it panics. 39 func NewBTree(m int, comparator func(v1, v2 interface{}) int, safe ...bool) *BTree { 40 return &BTree{ 41 mu: rwmutex.Create(safe...), 42 m: m, 43 comparator: comparator, 44 tree: btree.NewWith(m, comparator), 45 } 46 } 47 48 // NewBTreeFrom instantiates a B-tree with `m` (maximum number of children), a custom key comparator and data map. 49 // The parameter `safe` is used to specify whether using tree in concurrent-safety, 50 // which is false in default. 51 func NewBTreeFrom(m int, comparator func(v1, v2 interface{}) int, data map[interface{}]interface{}, safe ...bool) *BTree { 52 tree := NewBTree(m, comparator, safe...) 53 for k, v := range data { 54 tree.doSet(k, v) 55 } 56 return tree 57 } 58 59 // Clone returns a new tree with a copy of current tree. 60 func (tree *BTree) Clone() *BTree { 61 newTree := NewBTree(tree.m, tree.comparator, tree.mu.IsSafe()) 62 newTree.Sets(tree.Map()) 63 return newTree 64 } 65 66 // Set inserts key-value item into the tree. 67 func (tree *BTree) Set(key interface{}, value interface{}) { 68 tree.mu.Lock() 69 defer tree.mu.Unlock() 70 tree.doSet(key, value) 71 } 72 73 // Sets batch sets key-values to the tree. 74 func (tree *BTree) Sets(data map[interface{}]interface{}) { 75 tree.mu.Lock() 76 defer tree.mu.Unlock() 77 for k, v := range data { 78 tree.doSet(k, v) 79 } 80 } 81 82 // SetIfNotExist sets `value` to the map if the `key` does not exist, and then returns true. 83 // It returns false if `key` exists, and `value` would be ignored. 84 func (tree *BTree) SetIfNotExist(key interface{}, value interface{}) bool { 85 tree.mu.Lock() 86 defer tree.mu.Unlock() 87 if _, ok := tree.doGet(key); !ok { 88 tree.doSet(key, value) 89 return true 90 } 91 return false 92 } 93 94 // SetIfNotExistFunc sets value with return value of callback function `f`, and then returns true. 95 // It returns false if `key` exists, and `value` would be ignored. 96 func (tree *BTree) SetIfNotExistFunc(key interface{}, f func() interface{}) bool { 97 tree.mu.Lock() 98 defer tree.mu.Unlock() 99 if _, ok := tree.doGet(key); !ok { 100 tree.doSet(key, f()) 101 return true 102 } 103 return false 104 } 105 106 // SetIfNotExistFuncLock 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 // 109 // SetIfNotExistFuncLock differs with SetIfNotExistFunc function is that 110 // it executes function `f` with mutex.Lock of the hash map. 111 func (tree *BTree) SetIfNotExistFuncLock(key interface{}, f func() interface{}) bool { 112 tree.mu.Lock() 113 defer tree.mu.Unlock() 114 if _, ok := tree.doGet(key); !ok { 115 tree.doSet(key, f) 116 return true 117 } 118 return false 119 } 120 121 // Get searches the node in the tree by `key` and returns its value or nil if key is not found in tree. 122 func (tree *BTree) Get(key interface{}) (value interface{}) { 123 tree.mu.Lock() 124 defer tree.mu.Unlock() 125 value, _ = tree.doGet(key) 126 return 127 } 128 129 // GetOrSet returns the value by key, 130 // or sets value with given `value` if it does not exist and then returns this value. 131 func (tree *BTree) GetOrSet(key interface{}, value interface{}) interface{} { 132 tree.mu.Lock() 133 defer tree.mu.Unlock() 134 if v, ok := tree.doGet(key); !ok { 135 return tree.doSet(key, value) 136 } else { 137 return v 138 } 139 } 140 141 // GetOrSetFunc returns the value by key, 142 // or sets value with returned value of callback function `f` if it does not exist 143 // and then returns this value. 144 func (tree *BTree) GetOrSetFunc(key interface{}, f func() interface{}) interface{} { 145 tree.mu.Lock() 146 defer tree.mu.Unlock() 147 if v, ok := tree.doGet(key); !ok { 148 return tree.doSet(key, f()) 149 } else { 150 return v 151 } 152 } 153 154 // GetOrSetFuncLock returns the value by key, 155 // or sets value with returned value of callback function `f` if it does not exist 156 // and then returns this value. 157 // 158 // GetOrSetFuncLock differs with GetOrSetFunc function is that it executes function `f` 159 // with mutex.Lock of the hash map. 160 func (tree *BTree) GetOrSetFuncLock(key interface{}, f func() interface{}) interface{} { 161 tree.mu.Lock() 162 defer tree.mu.Unlock() 163 if v, ok := tree.doGet(key); !ok { 164 return tree.doSet(key, f) 165 } else { 166 return v 167 } 168 } 169 170 // GetVar returns a gvar.Var with the value by given `key`. 171 // The returned gvar.Var is un-concurrent safe. 172 func (tree *BTree) GetVar(key interface{}) *gvar.Var { 173 return gvar.New(tree.Get(key)) 174 } 175 176 // GetVarOrSet returns a gvar.Var with result from GetVarOrSet. 177 // The returned gvar.Var is un-concurrent safe. 178 func (tree *BTree) GetVarOrSet(key interface{}, value interface{}) *gvar.Var { 179 return gvar.New(tree.GetOrSet(key, value)) 180 } 181 182 // GetVarOrSetFunc returns a gvar.Var with result from GetOrSetFunc. 183 // The returned gvar.Var is un-concurrent safe. 184 func (tree *BTree) GetVarOrSetFunc(key interface{}, f func() interface{}) *gvar.Var { 185 return gvar.New(tree.GetOrSetFunc(key, f)) 186 } 187 188 // GetVarOrSetFuncLock returns a gvar.Var with result from GetOrSetFuncLock. 189 // The returned gvar.Var is un-concurrent safe. 190 func (tree *BTree) GetVarOrSetFuncLock(key interface{}, f func() interface{}) *gvar.Var { 191 return gvar.New(tree.GetOrSetFuncLock(key, f)) 192 } 193 194 // Search searches the tree with given `key`. 195 // Second return parameter `found` is true if key was found, otherwise false. 196 func (tree *BTree) Search(key interface{}) (value interface{}, found bool) { 197 tree.mu.RLock() 198 defer tree.mu.RUnlock() 199 return tree.tree.Get(key) 200 } 201 202 // Contains checks whether `key` exists in the tree. 203 func (tree *BTree) Contains(key interface{}) bool { 204 tree.mu.RLock() 205 defer tree.mu.RUnlock() 206 _, ok := tree.doGet(key) 207 return ok 208 } 209 210 // Size returns number of nodes in the tree. 211 func (tree *BTree) Size() int { 212 tree.mu.RLock() 213 defer tree.mu.RUnlock() 214 return tree.tree.Size() 215 } 216 217 // IsEmpty returns true if tree does not contain any nodes 218 func (tree *BTree) IsEmpty() bool { 219 tree.mu.RLock() 220 defer tree.mu.RUnlock() 221 return tree.tree.Size() == 0 222 } 223 224 // Remove removes the node from the tree by `key`. 225 func (tree *BTree) Remove(key interface{}) (value interface{}) { 226 tree.mu.Lock() 227 defer tree.mu.Unlock() 228 return tree.doRemove(key) 229 } 230 231 // Removes batch deletes values of the tree by `keys`. 232 func (tree *BTree) Removes(keys []interface{}) { 233 tree.mu.Lock() 234 defer tree.mu.Unlock() 235 for _, key := range keys { 236 tree.doRemove(key) 237 } 238 } 239 240 // Clear removes all nodes from the tree. 241 func (tree *BTree) Clear() { 242 tree.mu.Lock() 243 defer tree.mu.Unlock() 244 tree.tree.Clear() 245 } 246 247 // Keys returns all keys in asc order. 248 func (tree *BTree) Keys() []interface{} { 249 tree.mu.RLock() 250 defer tree.mu.RUnlock() 251 return tree.tree.Keys() 252 } 253 254 // Values returns all values in asc order based on the key. 255 func (tree *BTree) Values() []interface{} { 256 tree.mu.RLock() 257 defer tree.mu.RUnlock() 258 return tree.tree.Values() 259 } 260 261 // Replace the data of the tree with given `data`. 262 func (tree *BTree) Replace(data map[interface{}]interface{}) { 263 tree.mu.Lock() 264 defer tree.mu.Unlock() 265 tree.tree.Clear() 266 for k, v := range data { 267 tree.doSet(k, v) 268 } 269 } 270 271 // Map returns all key-value items as map. 272 func (tree *BTree) Map() map[interface{}]interface{} { 273 tree.mu.RLock() 274 defer tree.mu.RUnlock() 275 m := make(map[interface{}]interface{}, tree.Size()) 276 tree.IteratorAsc(func(key, value interface{}) bool { 277 m[key] = value 278 return true 279 }) 280 return m 281 } 282 283 // MapStrAny returns all key-value items as map[string]interface{}. 284 func (tree *BTree) MapStrAny() map[string]interface{} { 285 tree.mu.RLock() 286 defer tree.mu.RUnlock() 287 m := make(map[string]interface{}, tree.Size()) 288 tree.IteratorAsc(func(key, value interface{}) bool { 289 m[gconv.String(key)] = value 290 return true 291 }) 292 return m 293 } 294 295 // Print prints the tree to stdout. 296 func (tree *BTree) Print() { 297 fmt.Println(tree.String()) 298 } 299 300 // String returns a string representation of container (for debugging purposes) 301 func (tree *BTree) String() string { 302 tree.mu.RLock() 303 defer tree.mu.RUnlock() 304 return gstr.Replace(tree.tree.String(), "BTree\n", "") 305 } 306 307 // MarshalJSON implements the interface MarshalJSON for json.Marshal. 308 func (tree *BTree) MarshalJSON() (jsonBytes []byte, err error) { 309 tree.mu.RLock() 310 defer tree.mu.RUnlock() 311 return tree.tree.MarshalJSON() 312 } 313 314 // Iterator is alias of IteratorAsc. 315 func (tree *BTree) Iterator(f func(key, value interface{}) bool) { 316 tree.IteratorAsc(f) 317 } 318 319 // IteratorFrom is alias of IteratorAscFrom. 320 func (tree *BTree) IteratorFrom(key interface{}, match bool, f func(key, value interface{}) bool) { 321 tree.IteratorAscFrom(key, match, f) 322 } 323 324 // IteratorAsc iterates the tree readonly in ascending order with given callback function `f`. 325 // If `f` returns true, then it continues iterating; or false to stop. 326 func (tree *BTree) IteratorAsc(f func(key, value interface{}) bool) { 327 tree.mu.RLock() 328 defer tree.mu.RUnlock() 329 it := tree.tree.Iterator() 330 for it.Begin(); it.Next(); { 331 index, value := it.Key(), it.Value() 332 if ok := f(index, value); !ok { 333 break 334 } 335 } 336 } 337 338 // IteratorAscFrom iterates the tree readonly in ascending order with given callback function `f`. 339 // The parameter `key` specifies the start entry for iterating. The `match` specifies whether 340 // starting iterating if the `key` is fully matched, or else using index searching iterating. 341 // If `f` returns true, then it continues iterating; or false to stop. 342 func (tree *BTree) IteratorAscFrom(key interface{}, match bool, f func(key, value interface{}) bool) { 343 tree.mu.RLock() 344 defer tree.mu.RUnlock() 345 var keys = tree.tree.Keys() 346 index, isIterator := tree.iteratorFromGetIndex(key, keys, match) 347 if !isIterator { 348 return 349 } 350 for ; index < len(keys); index++ { 351 f(keys[index], tree.Get(keys[index])) 352 } 353 } 354 355 // IteratorDesc iterates the tree readonly in descending order with given callback function `f`. 356 // If `f` returns true, then it continues iterating; or false to stop. 357 func (tree *BTree) IteratorDesc(f func(key, value interface{}) bool) { 358 tree.mu.RLock() 359 defer tree.mu.RUnlock() 360 it := tree.tree.Iterator() 361 for it.End(); it.Prev(); { 362 index, value := it.Key(), it.Value() 363 if ok := f(index, value); !ok { 364 break 365 } 366 } 367 } 368 369 // IteratorDescFrom iterates the tree readonly in descending order with given callback function `f`. 370 // The parameter `key` specifies the start entry for iterating. The `match` specifies whether 371 // starting iterating if the `key` is fully matched, or else using index searching iterating. 372 // If `f` returns true, then it continues iterating; or false to stop. 373 func (tree *BTree) IteratorDescFrom(key interface{}, match bool, f func(key, value interface{}) bool) { 374 tree.mu.RLock() 375 defer tree.mu.RUnlock() 376 var keys = tree.tree.Keys() 377 index, isIterator := tree.iteratorFromGetIndex(key, keys, match) 378 if !isIterator { 379 return 380 } 381 for ; index >= 0; index-- { 382 f(keys[index], tree.Get(keys[index])) 383 } 384 } 385 386 // Height returns the height of the tree. 387 func (tree *BTree) Height() int { 388 tree.mu.RLock() 389 defer tree.mu.RUnlock() 390 return tree.tree.Height() 391 } 392 393 // Left returns the left-most (min) entry or nil if tree is empty. 394 func (tree *BTree) Left() *BTreeEntry { 395 tree.mu.RLock() 396 defer tree.mu.RUnlock() 397 node := tree.tree.Left() 398 if node == nil || node.Entries == nil || len(node.Entries) == 0 { 399 return nil 400 } 401 return &BTreeEntry{ 402 Key: node.Entries[0].Key, 403 Value: node.Entries[0].Value, 404 } 405 } 406 407 // Right returns the right-most (max) entry or nil if tree is empty. 408 func (tree *BTree) Right() *BTreeEntry { 409 tree.mu.RLock() 410 defer tree.mu.RUnlock() 411 node := tree.tree.Right() 412 if node == nil || node.Entries == nil || len(node.Entries) == 0 { 413 return nil 414 } 415 return &BTreeEntry{ 416 Key: node.Entries[len(node.Entries)-1].Key, 417 Value: node.Entries[len(node.Entries)-1].Value, 418 } 419 } 420 421 // doSet inserts key-value pair node into the tree. 422 // If key already exists, then its value is updated with the new value. 423 // If `value` is type of <func() interface {}>, 424 // it will be executed and its return value will be set to the map with `key`. 425 // 426 // It returns value with given `key`. 427 func (tree *BTree) doSet(key interface{}, value interface{}) interface{} { 428 if f, ok := value.(func() interface{}); ok { 429 value = f() 430 } 431 if value == nil { 432 return value 433 } 434 tree.tree.Put(key, value) 435 return value 436 } 437 438 // doGet get the value from the tree by key. 439 func (tree *BTree) doGet(key interface{}) (value interface{}, ok bool) { 440 return tree.tree.Get(key) 441 } 442 443 // doRemove removes the node from the tree by key. 444 // Key should adhere to the comparator's type assertion, otherwise method panics. 445 func (tree *BTree) doRemove(key interface{}) (value interface{}) { 446 value, _ = tree.tree.Get(key) 447 tree.tree.Remove(key) 448 return 449 } 450 451 // iteratorFromGetIndex returns the index of the key in the keys slice. 452 // The parameter `match` specifies whether starting iterating if the `key` is fully matched, 453 // or else using index searching iterating. 454 // If `isIterator` is true, iterator is available; or else not. 455 func (tree *BTree) iteratorFromGetIndex(key interface{}, keys []interface{}, match bool) (index int, isIterator bool) { 456 if match { 457 for i, k := range keys { 458 if k == key { 459 isIterator = true 460 index = i 461 } 462 } 463 } else { 464 if i, ok := key.(int); ok { 465 isIterator = true 466 index = i 467 } 468 } 469 return 470 }