github.com/weaviate/weaviate@v1.24.6/adapters/repos/db/roaringset/segment_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 "github.com/weaviate/weaviate/adapters/repos/db/lsmkv/segmentindex" 16 ) 17 18 type Seeker interface { 19 Seek(key []byte) (segmentindex.Node, error) 20 } 21 22 // A SegmentCursor iterates over all key-value pairs in a single disk segment. 23 // You can either start at the beginning using [*SegmentCursor.First] or start 24 // at an arbitrary key that you may find using [*SegmentCursor.Seek] 25 type SegmentCursor struct { 26 index Seeker 27 data []byte 28 nextOffset uint64 29 } 30 31 // NewSegmentCursor creates a cursor for a single disk segment. Make sure that 32 // the data buf is already sliced correctly to start at the payload, as calling 33 // [*SegmentCursor.First] will start reading at offset 0 relative to the passed 34 // in buffer. Similarly, the buffer may only contain payloads, as the buffer end 35 // is used to determine if more keys can be found. 36 // 37 // Therefore if the payload is part of a longer continuous buffer, the cursor 38 // should be initialized with data[payloadStartPos:payloadEndPos] 39 func NewSegmentCursor(data []byte, index Seeker) *SegmentCursor { 40 return &SegmentCursor{index: index, data: data, nextOffset: 0} 41 } 42 43 func (c *SegmentCursor) Next() ([]byte, BitmapLayer, error) { 44 if c.nextOffset >= uint64(len(c.data)) { 45 return nil, BitmapLayer{}, nil 46 } 47 48 sn := NewSegmentNodeFromBuffer(c.data[c.nextOffset:]) 49 c.nextOffset += sn.Len() 50 layer := BitmapLayer{ 51 Additions: sn.Additions(), 52 Deletions: sn.Deletions(), 53 } 54 return sn.PrimaryKey(), layer, nil 55 } 56 57 func (c *SegmentCursor) First() ([]byte, BitmapLayer, error) { 58 c.nextOffset = 0 59 return c.Next() 60 } 61 62 func (c *SegmentCursor) Seek(key []byte) ([]byte, BitmapLayer, error) { 63 node, err := c.index.Seek(key) 64 if err != nil { 65 return nil, BitmapLayer{}, err 66 } 67 c.nextOffset = node.Start 68 return c.Next() 69 }