github.com/weaviate/weaviate@v1.24.6/adapters/repos/db/roaringset/binary_search_tree_cursor.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/entities/lsmkv" 18 ) 19 20 type BinarySearchTreeCursor struct { 21 nodes []*BinarySearchNode 22 nextNodePos int 23 } 24 25 func NewBinarySearchTreeCursor(bst *BinarySearchTree) *BinarySearchTreeCursor { 26 return &BinarySearchTreeCursor{nodes: bst.FlattenInOrder()} 27 } 28 29 func (c *BinarySearchTreeCursor) First() ([]byte, BitmapLayer, error) { 30 c.nextNodePos = 0 31 return c.Next() 32 } 33 34 func (c *BinarySearchTreeCursor) Next() ([]byte, BitmapLayer, error) { 35 if c.nextNodePos >= len(c.nodes) { 36 return nil, BitmapLayer{}, nil 37 } 38 39 pos := c.nextNodePos 40 c.nextNodePos++ 41 return c.nodes[pos].Key, c.nodes[pos].Value, nil 42 } 43 44 func (c *BinarySearchTreeCursor) Seek(key []byte) ([]byte, BitmapLayer, error) { 45 pos := c.posKeyGreaterThanEqual(key) 46 if pos == -1 { 47 return nil, BitmapLayer{}, lsmkv.NotFound 48 } 49 c.nextNodePos = pos 50 return c.Next() 51 } 52 53 func (c *BinarySearchTreeCursor) posKeyGreaterThanEqual(key []byte) int { 54 // seek from the end, return position of first (from the beginning) node with key >= given key 55 // if key > node_key return previous pos 56 // if key == node_key return current pos 57 // if key < node_key continue or return current pos if all nodes checked 58 pos := -1 59 for i := len(c.nodes) - 1; i >= 0; i-- { 60 if cmp := bytes.Compare(key, c.nodes[i].Key); cmp > 0 { 61 break 62 } else if cmp == 0 { 63 pos = i 64 break 65 } 66 pos = i 67 } 68 return pos 69 }