github.com/weaviate/weaviate@v1.24.6/adapters/repos/db/roaringset/binary_search_tree.go (about)

     1  //                           _       _
     2  // __      _____  __ ___   ___  __ _| |_ ___
     3  // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \
     4  //  \ V  V /  __/ (_| |\ V /| | (_| | ||  __/
     5  //   \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___|
     6  //
     7  //  Copyright © 2016 - 2024 Weaviate B.V. All rights reserved.
     8  //
     9  //  CONTACT: hello@weaviate.io
    10  //
    11  
    12  package roaringset
    13  
    14  import (
    15  	"bytes"
    16  
    17  	"github.com/weaviate/weaviate/adapters/repos/db/lsmkv/rbtree"
    18  	"github.com/weaviate/weaviate/entities/lsmkv"
    19  )
    20  
    21  type BinarySearchTree struct {
    22  	root *BinarySearchNode
    23  }
    24  
    25  type Insert struct {
    26  	Additions []uint64
    27  	Deletions []uint64
    28  }
    29  
    30  func (t *BinarySearchTree) Insert(key []byte, values Insert) {
    31  	if t.root == nil {
    32  		t.root = &BinarySearchNode{
    33  			Key: key,
    34  			Value: BitmapLayer{
    35  				Additions: NewBitmap(values.Additions...),
    36  				Deletions: NewBitmap(values.Deletions...),
    37  			},
    38  			colourIsRed: false, // root node is always black
    39  		}
    40  		return
    41  	}
    42  
    43  	if newRoot := t.root.insert(key, values); newRoot != nil {
    44  		t.root = newRoot
    45  	}
    46  	t.root.colourIsRed = false // Can be flipped in the process of balancing, but root is always black
    47  }
    48  
    49  // Get creates copies of underlying bitmaps to prevent future (concurrent)
    50  // read and writes after layer being returned
    51  func (t *BinarySearchTree) Get(key []byte) (BitmapLayer, error) {
    52  	if t.root == nil {
    53  		return BitmapLayer{}, lsmkv.NotFound
    54  	}
    55  
    56  	return t.root.get(key)
    57  }
    58  
    59  // FlattenInOrder creates list of ordered copies of bst nodes
    60  // Only Key and Value fields are populated
    61  func (t *BinarySearchTree) FlattenInOrder() []*BinarySearchNode {
    62  	if t.root == nil {
    63  		return nil
    64  	}
    65  
    66  	return t.root.flattenInOrder()
    67  }
    68  
    69  type BinarySearchNode struct {
    70  	Key         []byte
    71  	Value       BitmapLayer
    72  	left        *BinarySearchNode
    73  	right       *BinarySearchNode
    74  	parent      *BinarySearchNode
    75  	colourIsRed bool
    76  }
    77  
    78  func (n *BinarySearchNode) Parent() rbtree.Node {
    79  	if n == nil {
    80  		return nil
    81  	}
    82  	return n.parent
    83  }
    84  
    85  func (n *BinarySearchNode) SetParent(parent rbtree.Node) {
    86  	if n == nil {
    87  		addNewSearchNodeRoaringSetReceiver(&n)
    88  	}
    89  
    90  	if parent == nil {
    91  		n.parent = nil
    92  		return
    93  	}
    94  
    95  	n.parent = parent.(*BinarySearchNode)
    96  }
    97  
    98  func (n *BinarySearchNode) Left() rbtree.Node {
    99  	if n == nil {
   100  		return nil
   101  	}
   102  	return n.left
   103  }
   104  
   105  func (n *BinarySearchNode) SetLeft(left rbtree.Node) {
   106  	if n == nil {
   107  		addNewSearchNodeRoaringSetReceiver(&n)
   108  	}
   109  
   110  	if left == nil {
   111  		n.left = nil
   112  		return
   113  	}
   114  
   115  	n.left = left.(*BinarySearchNode)
   116  }
   117  
   118  func (n *BinarySearchNode) Right() rbtree.Node {
   119  	if n == nil {
   120  		return nil
   121  	}
   122  	return n.right
   123  }
   124  
   125  func (n *BinarySearchNode) SetRight(right rbtree.Node) {
   126  	if n == nil {
   127  		addNewSearchNodeRoaringSetReceiver(&n)
   128  	}
   129  
   130  	if right == nil {
   131  		n.right = nil
   132  		return
   133  	}
   134  
   135  	n.right = right.(*BinarySearchNode)
   136  }
   137  
   138  func (n *BinarySearchNode) IsRed() bool {
   139  	if n == nil {
   140  		return false
   141  	}
   142  	return n.colourIsRed
   143  }
   144  
   145  func (n *BinarySearchNode) SetRed(isRed bool) {
   146  	n.colourIsRed = isRed
   147  }
   148  
   149  func (n *BinarySearchNode) IsNil() bool {
   150  	return n == nil
   151  }
   152  
   153  func addNewSearchNodeRoaringSetReceiver(nodePtr **BinarySearchNode) {
   154  	*nodePtr = &BinarySearchNode{}
   155  }
   156  
   157  func (n *BinarySearchNode) insert(key []byte, values Insert) *BinarySearchNode {
   158  	if bytes.Equal(key, n.Key) {
   159  		// Merging the new additions and deletions into the existing ones is a
   160  		// four-step process:
   161  		//
   162  		// 1. make sure anything that's added is not part of the deleted list, in
   163  		//    case it was previously deleted
   164  		// 2. actually add the new entries to additions
   165  		// 3. make sure anything that's deleted is not part of the additions list,
   166  		//    in case it was recently added
   167  		// 4. actually add the new entries to deletions (this step is vital in case
   168  		//    a delete points to an entry of a previous segment that's not added in
   169  		//    this memtable)
   170  		for _, x := range values.Additions {
   171  			n.Value.Deletions.Remove(x)
   172  			n.Value.Additions.Set(x)
   173  		}
   174  
   175  		for _, x := range values.Deletions {
   176  			n.Value.Additions.Remove(x)
   177  			n.Value.Deletions.Set(x)
   178  		}
   179  
   180  		return nil
   181  	}
   182  
   183  	if bytes.Compare(key, n.Key) < 0 {
   184  		if n.left != nil {
   185  			return n.left.insert(key, values)
   186  		} else {
   187  			n.left = &BinarySearchNode{
   188  				Key: key,
   189  				Value: BitmapLayer{
   190  					Additions: NewBitmap(values.Additions...),
   191  					Deletions: NewBitmap(values.Deletions...),
   192  				},
   193  				parent:      n,
   194  				colourIsRed: true,
   195  			}
   196  			return BinarySearchNodeFromRB(rbtree.Rebalance(n.left))
   197  		}
   198  	} else {
   199  		if n.right != nil {
   200  			return n.right.insert(key, values)
   201  		} else {
   202  			n.right = &BinarySearchNode{
   203  				Key: key,
   204  				Value: BitmapLayer{
   205  					Additions: NewBitmap(values.Additions...),
   206  					Deletions: NewBitmap(values.Deletions...),
   207  				},
   208  				parent:      n,
   209  				colourIsRed: true,
   210  			}
   211  			return BinarySearchNodeFromRB(rbtree.Rebalance(n.right))
   212  		}
   213  	}
   214  }
   215  
   216  func (n *BinarySearchNode) get(key []byte) (BitmapLayer, error) {
   217  	if bytes.Equal(n.Key, key) {
   218  		return n.Value.Clone(), nil
   219  	}
   220  
   221  	if bytes.Compare(key, n.Key) < 0 {
   222  		if n.left == nil {
   223  			return BitmapLayer{}, lsmkv.NotFound
   224  		}
   225  
   226  		return n.left.get(key)
   227  	} else {
   228  		if n.right == nil {
   229  			return BitmapLayer{}, lsmkv.NotFound
   230  		}
   231  
   232  		return n.right.get(key)
   233  	}
   234  }
   235  
   236  func BinarySearchNodeFromRB(rbNode rbtree.Node) (bsNode *BinarySearchNode) {
   237  	if rbNode == nil {
   238  		bsNode = nil
   239  		return
   240  	}
   241  	bsNode = rbNode.(*BinarySearchNode)
   242  	return
   243  }
   244  
   245  func (n *BinarySearchNode) flattenInOrder() []*BinarySearchNode {
   246  	var left []*BinarySearchNode
   247  	var right []*BinarySearchNode
   248  
   249  	if n.left != nil {
   250  		left = n.left.flattenInOrder()
   251  	}
   252  
   253  	if n.right != nil {
   254  		right = n.right.flattenInOrder()
   255  	}
   256  
   257  	key := make([]byte, len(n.Key))
   258  	copy(key, n.Key)
   259  
   260  	right = append([]*BinarySearchNode{{
   261  		Key: key,
   262  		Value: BitmapLayer{
   263  			Additions: Condense(n.Value.Additions),
   264  			Deletions: Condense(n.Value.Deletions),
   265  		},
   266  	}}, right...)
   267  	return append(left, right...)
   268  }