github.com/scottcagno/storage@v1.8.0/pkg/lsmt/trees/rbtree/rbtree.go (about)

     1  package rbtree
     2  
     3  import (
     4  	"runtime"
     5  	"strings"
     6  	"sync"
     7  )
     8  
     9  type RBEntry interface {
    10  	Compare(that RBEntry) int
    11  	Size() int
    12  	String() string
    13  }
    14  
    15  var empty = *new(RBEntry)
    16  
    17  func compare(this, that RBEntry) int {
    18  	return this.Compare(that)
    19  }
    20  
    21  const (
    22  	RED   = 0
    23  	BLACK = 1
    24  )
    25  
    26  type rbNode struct {
    27  	left   *rbNode
    28  	right  *rbNode
    29  	parent *rbNode
    30  	color  uint
    31  	entry  RBEntry
    32  }
    33  
    34  type RBTree = rbTree
    35  
    36  // rbTree is a struct representing a rbTree
    37  type rbTree struct {
    38  	lock  sync.RWMutex
    39  	NIL   *rbNode
    40  	root  *rbNode
    41  	count int
    42  	size  int64
    43  }
    44  
    45  func NewRBTree() *rbTree {
    46  	return newRBTree()
    47  }
    48  
    49  // NewTree creates and returns a new rbTree
    50  func newRBTree() *rbTree {
    51  	n := &rbNode{
    52  		left:   nil,
    53  		right:  nil,
    54  		parent: nil,
    55  		color:  BLACK,
    56  		entry:  empty,
    57  	}
    58  	return &rbTree{
    59  		NIL:   n,
    60  		root:  n,
    61  		count: 0,
    62  	}
    63  }
    64  
    65  func (t *rbTree) GetClone() *rbTree {
    66  	t.Lock()
    67  	defer t.Unlock()
    68  	clone := newRBTree()
    69  	t.cloneEntries(clone)
    70  	return clone
    71  }
    72  
    73  func (t *rbTree) Lock() {
    74  	t.lock.Lock()
    75  }
    76  
    77  func (t *rbTree) Unlock() {
    78  	t.lock.Unlock()
    79  }
    80  
    81  func (t *rbTree) RLock() {
    82  	t.lock.RLock()
    83  }
    84  
    85  func (t *rbTree) RUnlock() {
    86  	t.lock.RUnlock()
    87  }
    88  
    89  // Has tests and returns a boolean value if the
    90  // provided key exists in the tree
    91  func (t *rbTree) Has(entry RBEntry) bool {
    92  	_, ok := t.getInternal(entry)
    93  	return ok
    94  }
    95  
    96  // Add adds the provided key and value only if it does not
    97  // already exist in the tree. It returns false if the key and
    98  // value was not able to be added, and true if it was added
    99  // successfully
   100  func (t *rbTree) Add(entry RBEntry) bool {
   101  	_, ok := t.getInternal(entry)
   102  	if ok {
   103  		// key already exists, so we are not adding
   104  		return false
   105  	}
   106  	t.putInternal(entry)
   107  	return true
   108  }
   109  
   110  func (t *rbTree) Put(entry RBEntry) (RBEntry, bool) {
   111  	return t.putInternal(entry)
   112  }
   113  
   114  func (t *rbTree) putInternal(entry RBEntry) (RBEntry, bool) {
   115  	if entry == nil {
   116  		return nil, false
   117  	}
   118  	// insert returns the node inserted
   119  	// and if the node returned already
   120  	// existed and/or was updated
   121  	ret, ok := t.insert(&rbNode{
   122  		left:   t.NIL,
   123  		right:  t.NIL,
   124  		parent: t.NIL,
   125  		color:  RED,
   126  		entry:  entry,
   127  	})
   128  	return ret.entry, ok
   129  }
   130  
   131  func (t *rbTree) Get(entry RBEntry) (RBEntry, bool) {
   132  	return t.getInternal(entry)
   133  }
   134  
   135  // GetNearMin performs an approximate search for the specified key
   136  // and returns the closest key that is less than (the predecessor)
   137  // to the searched key as well as a boolean reporting true if an
   138  // exact match was found for the key, and false if it is unknown
   139  // or and exact match was not found
   140  func (t *rbTree) GetNearMin(entry RBEntry) (RBEntry, bool) {
   141  	if entry == nil {
   142  		return nil, false
   143  	}
   144  	ret := t.searchApprox(&rbNode{
   145  		left:   t.NIL,
   146  		right:  t.NIL,
   147  		parent: t.NIL,
   148  		color:  RED,
   149  		entry:  entry,
   150  	})
   151  	prev := t.predecessor(ret).entry
   152  	if prev == nil {
   153  		prev, _ = t.Min()
   154  	}
   155  	return prev, ret.entry.Compare(entry) == 0
   156  }
   157  
   158  // GetNearMax performs an approximate search for the specified key
   159  // and returns the closest key that is greater than (the successor)
   160  // to the searched key as well as a boolean reporting true if an
   161  // exact match was found for the key, and false if it is unknown or
   162  // and exact match was not found
   163  func (t *rbTree) GetNearMax(entry RBEntry) (RBEntry, bool) {
   164  	if entry == nil {
   165  		return nil, false
   166  	}
   167  	ret := t.searchApprox(&rbNode{
   168  		left:   t.NIL,
   169  		right:  t.NIL,
   170  		parent: t.NIL,
   171  		color:  RED,
   172  		entry:  entry,
   173  	})
   174  	return t.successor(ret).entry, ret.entry.Compare(entry) == 0
   175  }
   176  
   177  // GetApproxPrevNext performs an approximate search for the specified key
   178  // and returns the searched key, the predecessor, and the successor and a
   179  // boolean reporting true if an exact match was found for the key, and false
   180  // if it is unknown or and exact match was not found
   181  func (t *rbTree) GetApproxPrevNext(entry RBEntry) (RBEntry, RBEntry, RBEntry, bool) {
   182  	if entry == nil {
   183  		return nil, nil, nil, false
   184  	}
   185  	ret := t.searchApprox(&rbNode{
   186  		left:   t.NIL,
   187  		right:  t.NIL,
   188  		parent: t.NIL,
   189  		color:  RED,
   190  		entry:  entry,
   191  	})
   192  	return ret.entry, t.predecessor(ret).entry, t.successor(ret).entry,
   193  		ret.entry.Compare(entry) == 0
   194  }
   195  
   196  func (t *rbTree) getInternal(entry RBEntry) (RBEntry, bool) {
   197  	if entry == nil {
   198  		return nil, false
   199  	}
   200  	ret := t.search(&rbNode{
   201  		left:   t.NIL,
   202  		right:  t.NIL,
   203  		parent: t.NIL,
   204  		color:  RED,
   205  		entry:  entry,
   206  	})
   207  	return ret.entry, ret.entry != nil
   208  }
   209  
   210  func (t *rbTree) Del(entry RBEntry) (RBEntry, bool) {
   211  	return t.delInternal(entry)
   212  }
   213  
   214  func (t *rbTree) delInternal(entry RBEntry) (RBEntry, bool) {
   215  	if entry == nil {
   216  		return nil, false
   217  	}
   218  	cnt := t.count
   219  	ret := t.delete(&rbNode{
   220  		left:   t.NIL,
   221  		right:  t.NIL,
   222  		parent: t.NIL,
   223  		color:  RED,
   224  		entry:  entry,
   225  	})
   226  	return ret.entry, cnt == t.count+1
   227  }
   228  
   229  func (t *rbTree) Len() int {
   230  	return t.count
   231  }
   232  
   233  // Size returns the size in bytes
   234  func (t *rbTree) Size() int64 {
   235  	return t.size
   236  }
   237  
   238  func (t *rbTree) Min() (RBEntry, bool) {
   239  	x := t.min(t.root)
   240  	if x == t.NIL {
   241  		return nil, false
   242  	}
   243  	return x.entry, true
   244  }
   245  
   246  func (t *rbTree) Max() (RBEntry, bool) {
   247  	x := t.max(t.root)
   248  	if x == t.NIL {
   249  		return nil, false
   250  	}
   251  	return x.entry, true
   252  }
   253  
   254  // helper function for clone
   255  func (t *rbTree) cloneEntries(t2 *rbTree) {
   256  	t.ascend(t.root, t.min(t.root).entry, func(e RBEntry) bool {
   257  		t2.putInternal(e)
   258  		return true
   259  	})
   260  }
   261  
   262  type Iterator func(entry RBEntry) bool
   263  
   264  func (t *rbTree) Scan(iter Iterator) {
   265  	t.ascend(t.root, t.min(t.root).entry, iter)
   266  }
   267  
   268  func (t *rbTree) ScanBack(iter Iterator) {
   269  	t.descend(t.root, t.max(t.root).entry, iter)
   270  }
   271  
   272  func (t *rbTree) ScanRange(start, end RBEntry, iter Iterator) {
   273  	t.ascendRange(t.root, start, end, iter)
   274  }
   275  
   276  func (t *rbTree) String() string {
   277  	var sb strings.Builder
   278  	t.ascend(t.root, t.min(t.root).entry, func(entry RBEntry) bool {
   279  		sb.WriteString(entry.String())
   280  		return true
   281  	})
   282  	return sb.String()
   283  }
   284  
   285  func (t *rbTree) Close() {
   286  	t.NIL = nil
   287  	t.root = nil
   288  	t.count = 0
   289  	return
   290  }
   291  
   292  func (t *rbTree) Reset() {
   293  	t.NIL = nil
   294  	t.root = nil
   295  	t.count = 0
   296  	runtime.GC()
   297  	n := &rbNode{
   298  		left:   nil,
   299  		right:  nil,
   300  		parent: nil,
   301  		color:  BLACK,
   302  		entry:  empty,
   303  	}
   304  	t.NIL = n
   305  	t.root = n
   306  	t.count = 0
   307  	t.size = 0
   308  }
   309  
   310  func (t *rbTree) insert(z *rbNode) (*rbNode, bool) {
   311  	x := t.root
   312  	y := t.NIL
   313  	for x != t.NIL {
   314  		y = x
   315  		if compare(z.entry, x.entry) == -1 {
   316  			x = x.left
   317  		} else if compare(x.entry, z.entry) == -1 {
   318  			x = x.right
   319  		} else {
   320  			t.size -= int64(x.entry.Size())
   321  			t.size += int64(z.entry.Size())
   322  			// originally we were just returning x
   323  			// without updating the RBEntry, but if we
   324  			// want it to have similar behavior to
   325  			// a hashmap then we need to update any
   326  			// entries that already exist in the tree
   327  			x.entry = z.entry
   328  			return x, true // true means an existing
   329  			// value was found and updated. It should
   330  			// be noted that we don't need to re-balance
   331  			// the tree because they keys are not changing
   332  			// and the tree is balance is maintained by
   333  			// the keys and not their values.
   334  		}
   335  	}
   336  	z.parent = y
   337  	if y == t.NIL {
   338  		t.root = z
   339  	} else if compare(z.entry, y.entry) == -1 {
   340  		y.left = z
   341  	} else {
   342  		y.right = z
   343  	}
   344  	t.count++
   345  	t.size += int64(z.entry.Size())
   346  	t.insertFixup(z)
   347  	return z, false
   348  }
   349  
   350  func (t *rbTree) leftRotate(x *rbNode) {
   351  	if x.right == t.NIL {
   352  		return
   353  	}
   354  	y := x.right
   355  	x.right = y.left
   356  	if y.left != t.NIL {
   357  		y.left.parent = x
   358  	}
   359  	y.parent = x.parent
   360  	if x.parent == t.NIL {
   361  		t.root = y
   362  	} else if x == x.parent.left {
   363  		x.parent.left = y
   364  	} else {
   365  		x.parent.right = y
   366  	}
   367  	y.left = x
   368  	x.parent = y
   369  }
   370  
   371  func (t *rbTree) rightRotate(x *rbNode) {
   372  	if x.left == t.NIL {
   373  		return
   374  	}
   375  	y := x.left
   376  	x.left = y.right
   377  	if y.right != t.NIL {
   378  		y.right.parent = x
   379  	}
   380  	y.parent = x.parent
   381  
   382  	if x.parent == t.NIL {
   383  		t.root = y
   384  	} else if x == x.parent.left {
   385  		x.parent.left = y
   386  	} else {
   387  		x.parent.right = y
   388  	}
   389  
   390  	y.right = x
   391  	x.parent = y
   392  }
   393  
   394  func (t *rbTree) insertFixup(z *rbNode) {
   395  	for z.parent.color == RED {
   396  		if z.parent == z.parent.parent.left {
   397  			y := z.parent.parent.right
   398  			if y.color == RED {
   399  				z.parent.color = BLACK
   400  				y.color = BLACK
   401  				z.parent.parent.color = RED
   402  				z = z.parent.parent
   403  			} else {
   404  				if z == z.parent.right {
   405  					z = z.parent
   406  					t.leftRotate(z)
   407  				}
   408  				z.parent.color = BLACK
   409  				z.parent.parent.color = RED
   410  				t.rightRotate(z.parent.parent)
   411  			}
   412  		} else {
   413  			y := z.parent.parent.left
   414  			if y.color == RED {
   415  				z.parent.color = BLACK
   416  				y.color = BLACK
   417  				z.parent.parent.color = RED
   418  				z = z.parent.parent
   419  			} else {
   420  				if z == z.parent.left {
   421  					z = z.parent
   422  					t.rightRotate(z)
   423  				}
   424  				z.parent.color = BLACK
   425  				z.parent.parent.color = RED
   426  				t.leftRotate(z.parent.parent)
   427  			}
   428  		}
   429  	}
   430  	t.root.color = BLACK
   431  }
   432  
   433  // trying out a slightly different search method
   434  // that (hopefully) will not return nil values and
   435  // instead will return approximate node matches
   436  func (t *rbTree) searchApprox(x *rbNode) *rbNode {
   437  	p := t.root
   438  	for p != t.NIL {
   439  		if compare(p.entry, x.entry) == -1 {
   440  			if p.right == t.NIL {
   441  				break
   442  			}
   443  			p = p.right
   444  		} else if compare(x.entry, p.entry) == -1 {
   445  			if p.left == t.NIL {
   446  				break
   447  			}
   448  			p = p.left
   449  		} else {
   450  			break
   451  		}
   452  	}
   453  	return p
   454  }
   455  
   456  func (t *rbTree) search(x *rbNode) *rbNode {
   457  	p := t.root
   458  	for p != t.NIL {
   459  		if compare(p.entry, x.entry) == -1 {
   460  			p = p.right
   461  		} else if compare(x.entry, p.entry) == -1 {
   462  			p = p.left
   463  		} else {
   464  			break
   465  		}
   466  	}
   467  	return p
   468  }
   469  
   470  // min traverses from root to left recursively until left is NIL
   471  func (t *rbTree) min(x *rbNode) *rbNode {
   472  	if x == t.NIL {
   473  		return t.NIL
   474  	}
   475  	for x.left != t.NIL {
   476  		x = x.left
   477  	}
   478  	return x
   479  }
   480  
   481  // max traverses from root to right recursively until right is NIL
   482  func (t *rbTree) max(x *rbNode) *rbNode {
   483  	if x == t.NIL {
   484  		return t.NIL
   485  	}
   486  	for x.right != t.NIL {
   487  		x = x.right
   488  	}
   489  	return x
   490  }
   491  
   492  func (t *rbTree) predecessor(x *rbNode) *rbNode {
   493  	if x == t.NIL {
   494  		return t.NIL
   495  	}
   496  	if x.left != t.NIL {
   497  		return t.max(x.left)
   498  	}
   499  	y := x.parent
   500  	for y != t.NIL && x == y.left {
   501  		x = y
   502  		y = y.parent
   503  	}
   504  	return y
   505  }
   506  
   507  func (t *rbTree) successor(x *rbNode) *rbNode {
   508  	if x == t.NIL {
   509  		return t.NIL
   510  	}
   511  	if x.right != t.NIL {
   512  		return t.min(x.right)
   513  	}
   514  	y := x.parent
   515  	for y != t.NIL && x == y.right {
   516  		x = y
   517  		y = y.parent
   518  	}
   519  	return y
   520  }
   521  
   522  func (t *rbTree) delete(key *rbNode) *rbNode {
   523  	z := t.search(key)
   524  	if z == t.NIL {
   525  		return t.NIL
   526  	}
   527  	ret := &rbNode{t.NIL, t.NIL, t.NIL, z.color, z.entry}
   528  	var y *rbNode
   529  	var x *rbNode
   530  	if z.left == t.NIL || z.right == t.NIL {
   531  		y = z
   532  	} else {
   533  		y = t.successor(z)
   534  	}
   535  	if y.left != t.NIL {
   536  		x = y.left
   537  	} else {
   538  		x = y.right
   539  	}
   540  	x.parent = y.parent
   541  
   542  	if y.parent == t.NIL {
   543  		t.root = x
   544  	} else if y == y.parent.left {
   545  		y.parent.left = x
   546  	} else {
   547  		y.parent.right = x
   548  	}
   549  	if y != z {
   550  		z.entry = y.entry
   551  	}
   552  	if y.color == BLACK {
   553  		t.deleteFixup(x)
   554  	}
   555  	t.size -= int64(ret.entry.Size())
   556  	t.count--
   557  	return ret
   558  }
   559  
   560  func (t *rbTree) deleteFixup(x *rbNode) {
   561  	for x != t.root && x.color == BLACK {
   562  		if x == x.parent.left {
   563  			w := x.parent.right
   564  			if w.color == RED {
   565  				w.color = BLACK
   566  				x.parent.color = RED
   567  				t.leftRotate(x.parent)
   568  				w = x.parent.right
   569  			}
   570  			if w.left.color == BLACK && w.right.color == BLACK {
   571  				w.color = RED
   572  				x = x.parent
   573  			} else {
   574  				if w.right.color == BLACK {
   575  					w.left.color = BLACK
   576  					w.color = RED
   577  					t.rightRotate(w)
   578  					w = x.parent.right
   579  				}
   580  				w.color = x.parent.color
   581  				x.parent.color = BLACK
   582  				w.right.color = BLACK
   583  				t.leftRotate(x.parent)
   584  				// this is to exit while loop
   585  				x = t.root
   586  			}
   587  		} else {
   588  			w := x.parent.left
   589  			if w.color == RED {
   590  				w.color = BLACK
   591  				x.parent.color = RED
   592  				t.rightRotate(x.parent)
   593  				w = x.parent.left
   594  			}
   595  			if w.left.color == BLACK && w.right.color == BLACK {
   596  				w.color = RED
   597  				x = x.parent
   598  			} else {
   599  				if w.left.color == BLACK {
   600  					w.right.color = BLACK
   601  					w.color = RED
   602  					t.leftRotate(w)
   603  					w = x.parent.left
   604  				}
   605  				w.color = x.parent.color
   606  				x.parent.color = BLACK
   607  				w.left.color = BLACK
   608  				t.rightRotate(x.parent)
   609  				x = t.root
   610  			}
   611  		}
   612  	}
   613  	x.color = BLACK
   614  }
   615  
   616  func (t *rbTree) ascend(x *rbNode, entry RBEntry, iter Iterator) bool {
   617  	if x == t.NIL {
   618  		return true
   619  	}
   620  	if !(compare(x.entry, entry) == -1) {
   621  		if !t.ascend(x.left, entry, iter) {
   622  			return false
   623  		}
   624  		if !iter(x.entry) {
   625  			return false
   626  		}
   627  	}
   628  	return t.ascend(x.right, entry, iter)
   629  }
   630  
   631  func (t *rbTree) __Descend(pivot RBEntry, iter Iterator) {
   632  	t.descend(t.root, pivot, iter)
   633  }
   634  
   635  func (t *rbTree) descend(x *rbNode, pivot RBEntry, iter Iterator) bool {
   636  	if x == t.NIL {
   637  		return true
   638  	}
   639  	if !(compare(pivot, x.entry) == -1) {
   640  		if !t.descend(x.right, pivot, iter) {
   641  			return false
   642  		}
   643  		if !iter(x.entry) {
   644  			return false
   645  		}
   646  	}
   647  	return t.descend(x.left, pivot, iter)
   648  }
   649  
   650  func (t *rbTree) ascendRange(x *rbNode, inf, sup RBEntry, iter Iterator) bool {
   651  	if x == t.NIL {
   652  		return true
   653  	}
   654  	if !(compare(x.entry, sup) == -1) {
   655  		return t.ascendRange(x.left, inf, sup, iter)
   656  	}
   657  	if compare(x.entry, inf) == -1 {
   658  		return t.ascendRange(x.right, inf, sup, iter)
   659  	}
   660  	if !t.ascendRange(x.left, inf, sup, iter) {
   661  		return false
   662  	}
   663  	if !iter(x.entry) {
   664  		return false
   665  	}
   666  	return t.ascendRange(x.right, inf, sup, iter)
   667  }