github.com/scottcagno/storage@v1.8.0/pkg/_junk/_index/rbtree/rbtree.go (about)

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