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  }