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  }