Line data Source code
1 : // Copyright 2024 The LevelDB-Go and Pebble Authors. All rights reserved. Use 2 : // of this source code is governed by a BSD-style license that can be found in 3 : // the LICENSE file. 4 : 5 : package rowblk 6 : 7 : import ( 8 : "github.com/cockroachdb/pebble/internal/base" 9 : "github.com/cockroachdb/pebble/sstable/block" 10 : ) 11 : 12 : // IndexIter is a lightweight adapter that implements block.IndexIterator for a 13 : // row-based index block. 14 : type IndexIter struct { 15 : iter Iter 16 : } 17 : 18 : // Assert that IndexIter satisfies the block.IndexBlockIterator constraint. 19 : var _ = satisfiesIndexBlock[IndexIter, *IndexIter](IndexIter{}) 20 : 21 1 : func satisfiesIndexBlock[T any, PT block.IndexBlockIterator[T]](indexBlock T) PT { 22 1 : return &indexBlock 23 1 : } 24 : 25 : // InitHandle initializes an iterator from the provided block handle. 26 : func (i *IndexIter) InitHandle( 27 : cmp base.Compare, split base.Split, block block.BufferHandle, transforms block.IterTransforms, 28 1 : ) error { 29 1 : return i.iter.InitHandle(cmp, split, block, transforms) 30 1 : } 31 : 32 : // ResetForReuse resets the index iterator for reuse, retaining buffers to avoid 33 : // future allocations. 34 1 : func (i *IndexIter) ResetForReuse() IndexIter { 35 1 : return IndexIter{iter: i.iter.ResetForReuse()} 36 1 : } 37 : 38 : // Valid returns true if the iterator is currently positioned at a valid block 39 : // handle. 40 1 : func (i *IndexIter) Valid() bool { 41 1 : return i.iter.offset >= 0 && i.iter.offset < i.iter.restarts 42 1 : } 43 : 44 : // IsDataInvalidated returns true when the blockIter has been invalidated 45 : // using an invalidate call. NB: this is different from blockIter.Valid 46 : // which is part of the InternalIterator implementation. 47 1 : func (i *IndexIter) IsDataInvalidated() bool { 48 1 : return i.iter.IsDataInvalidated() 49 1 : } 50 : 51 : // Invalidate invalidates the block iterator, removing references to the block 52 : // it was initialized with. 53 1 : func (i *IndexIter) Invalidate() { 54 1 : i.iter.Invalidate() 55 1 : } 56 : 57 : // Handle returns the underlying block buffer handle, if the iterator was 58 : // initialized with one. 59 1 : func (i *IndexIter) Handle() block.BufferHandle { 60 1 : return i.iter.handle 61 1 : } 62 : 63 : // Separator returns the separator at the iterator's current position. The 64 : // iterator must be positioned at a valid row. A Separator is a user key 65 : // guaranteed to be greater than or equal to every key contained within the 66 : // referenced block(s). 67 1 : func (i *IndexIter) Separator() []byte { 68 1 : return i.iter.ikv.K.UserKey 69 1 : } 70 : 71 : // BlockHandleWithProperties decodes the block handle with any encoded 72 : // properties at the iterator's current position. 73 1 : func (i *IndexIter) BlockHandleWithProperties() (block.HandleWithProperties, error) { 74 1 : return block.DecodeHandleWithProperties(i.iter.ikv.V.ValueOrHandle) 75 1 : } 76 : 77 : // SeekGE seeks the index iterator to the first block entry with a separator key 78 : // greater or equal to the given key. If it returns true, the iterator is 79 : // positioned over the first block that might contain the key [key], and 80 : // following blocks have keys ≥ Separator(). It returns false if the seek key is 81 : // greater than all index block separators. 82 1 : func (i *IndexIter) SeekGE(key []byte) bool { 83 1 : return i.iter.SeekGE(key, base.SeekGEFlagsNone) != nil 84 1 : } 85 : 86 : // First seeks index iterator to the first block entry. It returns false if 87 : // the index block is empty. 88 1 : func (i *IndexIter) First() bool { 89 1 : return i.iter.First() != nil 90 1 : } 91 : 92 : // Last seeks index iterator to the last block entry. It returns false if 93 : // the index block is empty. 94 1 : func (i *IndexIter) Last() bool { 95 1 : return i.iter.Last() != nil 96 1 : } 97 : 98 : // Next steps the index iterator to the next block entry. It returns false 99 : // if the index block is exhausted. 100 1 : func (i *IndexIter) Next() bool { 101 1 : return i.iter.Next() != nil 102 1 : } 103 : 104 : // Prev steps the index iterator to the previous block entry. It returns 105 : // false if the index block is exhausted. 106 1 : func (i *IndexIter) Prev() bool { 107 1 : return i.iter.Prev() != nil 108 1 : } 109 : 110 : // Close closes the iterator, releasing any resources it holds. 111 1 : func (i *IndexIter) Close() error { 112 1 : return i.iter.Close() 113 1 : }