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  }