github.com/weaviate/weaviate@v1.24.6/adapters/repos/db/lsmkv/cursor_segment_replace.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 lsmkv 13 14 import ( 15 "github.com/weaviate/weaviate/entities/lsmkv" 16 "github.com/weaviate/weaviate/usecases/byteops" 17 ) 18 19 type segmentCursorReplace struct { 20 segment *segment 21 nextOffset uint64 22 reusableNode *segmentReplaceNode 23 reusableBORW byteops.ReadWriter 24 } 25 26 func (s *segment) newCursor() *segmentCursorReplace { 27 return &segmentCursorReplace{ 28 segment: s, 29 reusableNode: &segmentReplaceNode{}, 30 reusableBORW: byteops.NewReadWriter(nil), 31 } 32 } 33 34 func (sg *SegmentGroup) newCursors() ([]innerCursorReplace, func()) { 35 sg.maintenanceLock.RLock() 36 out := make([]innerCursorReplace, len(sg.segments)) 37 38 for i, segment := range sg.segments { 39 out[i] = segment.newCursor() 40 } 41 42 return out, sg.maintenanceLock.RUnlock 43 } 44 45 func (s *segmentCursorReplace) seek(key []byte) ([]byte, []byte, error) { 46 node, err := s.segment.index.Seek(key) 47 if err != nil { 48 return nil, nil, err 49 } 50 51 err = s.parseReplaceNodeInto(nodeOffset{start: node.Start, end: node.End}, 52 s.segment.contents[node.Start:node.End]) 53 // make sure to set the next offset before checking the error. The error 54 // could be 'Deleted' which would require that the offset is still advanced 55 // for the next cycle 56 s.nextOffset = node.End 57 58 if err != nil { 59 return s.reusableNode.primaryKey, nil, err 60 } 61 62 return s.reusableNode.primaryKey, s.reusableNode.value, nil 63 } 64 65 func (s *segmentCursorReplace) next() ([]byte, []byte, error) { 66 if s.nextOffset >= s.segment.dataEndPos { 67 return nil, nil, lsmkv.NotFound 68 } 69 70 err := s.parseReplaceNodeInto(nodeOffset{start: s.nextOffset}, 71 s.segment.contents[s.nextOffset:]) 72 // make sure to set the next offset before checking the error. The error 73 // could be 'Deleted' which would require that the offset is still advanced 74 // for the next cycle 75 s.nextOffset = s.nextOffset + uint64(s.reusableNode.offset) 76 if err != nil { 77 return s.reusableNode.primaryKey, nil, err 78 } 79 80 return s.reusableNode.primaryKey, s.reusableNode.value, nil 81 } 82 83 func (s *segmentCursorReplace) first() ([]byte, []byte, error) { 84 s.nextOffset = s.segment.dataStartPos 85 err := s.parseReplaceNodeInto(nodeOffset{start: s.nextOffset}, 86 s.segment.contents[s.nextOffset:]) 87 // make sure to set the next offset before checking the error. The error 88 // could be 'Deleted' which would require that the offset is still advanced 89 // for the next cycle 90 s.nextOffset = s.nextOffset + uint64(s.reusableNode.offset) 91 if err != nil { 92 return s.reusableNode.primaryKey, nil, err 93 } 94 95 return s.reusableNode.primaryKey, s.reusableNode.value, nil 96 } 97 98 func (s *segmentCursorReplace) nextWithAllKeys() (segmentReplaceNode, error) { 99 out := segmentReplaceNode{} 100 if s.nextOffset >= s.segment.dataEndPos { 101 return out, lsmkv.NotFound 102 } 103 104 parsed, err := s.parseReplaceNode(nodeOffset{start: s.nextOffset}) 105 // make sure to set the next offset before checking the error. The error 106 // could be 'Deleted' which would require that the offset is still advanced 107 // for the next cycle 108 s.nextOffset = s.nextOffset + uint64(parsed.offset) 109 if err != nil { 110 return parsed, err 111 } 112 113 return parsed, nil 114 } 115 116 func (s *segmentCursorReplace) firstWithAllKeys() (segmentReplaceNode, error) { 117 s.nextOffset = s.segment.dataStartPos 118 parsed, err := s.parseReplaceNode(nodeOffset{start: s.nextOffset}) 119 // make sure to set the next offset before checking the error. The error 120 // could be 'Deleted' which would require that the offset is still advanced 121 // for the next cycle 122 s.nextOffset = s.nextOffset + uint64(parsed.offset) 123 if err != nil { 124 return parsed, err 125 } 126 127 return parsed, nil 128 } 129 130 func (s *segmentCursorReplace) parseReplaceNode(offset nodeOffset) (segmentReplaceNode, error) { 131 r, err := s.segment.newNodeReader(offset) 132 if err != nil { 133 return segmentReplaceNode{}, err 134 } 135 out, err := ParseReplaceNode(r, s.segment.secondaryIndexCount) 136 if out.tombstone { 137 return out, lsmkv.Deleted 138 } 139 return out, err 140 } 141 142 func (s *segmentCursorReplace) parseReplaceNodeInto(offset nodeOffset, buf []byte) error { 143 if s.segment.mmapContents { 144 return s.parse(buf) 145 } 146 147 r, err := s.segment.newNodeReader(offset) 148 if err != nil { 149 return err 150 } 151 152 err = ParseReplaceNodeIntoPread(r, s.segment.secondaryIndexCount, s.reusableNode) 153 if err != nil { 154 return err 155 } 156 157 if s.reusableNode.tombstone { 158 return lsmkv.Deleted 159 } 160 161 return nil 162 } 163 164 func (s *segmentCursorReplace) parse(in []byte) error { 165 if len(in) == 0 { 166 return lsmkv.NotFound 167 } 168 169 s.reusableBORW.ResetBuffer(in) 170 171 err := ParseReplaceNodeIntoMMAP(&s.reusableBORW, s.segment.secondaryIndexCount, 172 s.reusableNode) 173 if err != nil { 174 return err 175 } 176 177 if s.reusableNode.tombstone { 178 return lsmkv.Deleted 179 } 180 181 return nil 182 }