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 interface. 19 : var _ block.IndexBlockIterator = (*IndexIter)(nil) 20 : 21 : // Init initializes an iterator from the provided block data slice. 22 : func (i *IndexIter) Init( 23 : cmp base.Compare, split base.Split, blk []byte, transforms block.IterTransforms, 24 1 : ) error { 25 1 : return i.iter.Init(cmp, split, blk, transforms) 26 1 : } 27 : 28 : // InitHandle initializes an iterator from the provided block handle. 29 : func (i *IndexIter) InitHandle( 30 : cmp base.Compare, split base.Split, block block.BufferHandle, transforms block.IterTransforms, 31 1 : ) error { 32 1 : return i.iter.InitHandle(cmp, split, block, transforms) 33 1 : } 34 : 35 : // Valid returns true if the iterator is currently positioned at a valid block 36 : // handle. 37 1 : func (i *IndexIter) Valid() bool { 38 1 : return i.iter.offset >= 0 && i.iter.offset < i.iter.restarts 39 1 : } 40 : 41 : // IsDataInvalidated returns true when the blockIter has been invalidated 42 : // using an invalidate call. NB: this is different from blockIter.Valid 43 : // which is part of the InternalIterator implementation. 44 1 : func (i *IndexIter) IsDataInvalidated() bool { 45 1 : return i.iter.IsDataInvalidated() 46 1 : } 47 : 48 : // Invalidate invalidates the block iterator, removing references to the block 49 : // it was initialized with. 50 1 : func (i *IndexIter) Invalidate() { 51 1 : i.iter.Invalidate() 52 1 : } 53 : 54 : // Handle returns the underlying block buffer handle, if the iterator was 55 : // initialized with one. 56 1 : func (i *IndexIter) Handle() block.BufferHandle { 57 1 : return i.iter.handle 58 1 : } 59 : 60 : // Separator returns the separator at the iterator's current position. The 61 : // iterator must be positioned at a valid row. A Separator is a user key 62 : // guaranteed to be greater than or equal to every key contained within the 63 : // referenced block(s). 64 1 : func (i *IndexIter) Separator() []byte { 65 1 : return i.iter.ikv.K.UserKey 66 1 : } 67 : 68 : // SeparatorLT returns true if the separator at the iterator's current 69 : // position is strictly less than the provided key. 70 1 : func (i *IndexIter) SeparatorLT(key []byte) bool { 71 1 : return i.iter.cmp(i.iter.ikv.K.UserKey, key) < 0 72 1 : } 73 : 74 : // SeparatorGT returns true if the separator at the iterator's current position 75 : // is strictly greater than (or equal, if orEqual=true) the provided key. 76 1 : func (i *IndexIter) SeparatorGT(key []byte, inclusively bool) bool { 77 1 : cmp := i.iter.cmp(i.iter.ikv.K.UserKey, key) 78 1 : return cmp > 0 || (cmp == 0 && inclusively) 79 1 : } 80 : 81 : // BlockHandleWithProperties decodes the block handle with any encoded 82 : // properties at the iterator's current position. 83 1 : func (i *IndexIter) BlockHandleWithProperties() (block.HandleWithProperties, error) { 84 1 : return block.DecodeHandleWithProperties(i.iter.ikv.V.ValueOrHandle) 85 1 : } 86 : 87 : // SeekGE seeks the index iterator to the first block entry with a separator key 88 : // greater or equal to the given key. If it returns true, the iterator is 89 : // positioned over the first block that might contain the key [key], and 90 : // following blocks have keys ≥ Separator(). It returns false if the seek key is 91 : // greater than all index block separators. 92 1 : func (i *IndexIter) SeekGE(key []byte) bool { 93 1 : return i.iter.SeekGE(key, base.SeekGEFlagsNone) != nil 94 1 : } 95 : 96 : // First seeks index iterator to the first block entry. It returns false if 97 : // the index block is empty. 98 1 : func (i *IndexIter) First() bool { 99 1 : return i.iter.First() != nil 100 1 : } 101 : 102 : // Last seeks index iterator to the last block entry. It returns false if 103 : // the index block is empty. 104 1 : func (i *IndexIter) Last() bool { 105 1 : return i.iter.Last() != nil 106 1 : } 107 : 108 : // Next steps the index iterator to the next block entry. It returns false 109 : // if the index block is exhausted. 110 1 : func (i *IndexIter) Next() bool { 111 1 : return i.iter.Next() != nil 112 1 : } 113 : 114 : // Prev steps the index iterator to the previous block entry. It returns 115 : // false if the index block is exhausted. 116 1 : func (i *IndexIter) Prev() bool { 117 1 : return i.iter.Prev() != nil 118 1 : } 119 : 120 : // Close closes the iterator, releasing any resources it holds. 121 1 : func (i *IndexIter) Close() error { 122 1 : return i.iter.Close() 123 1 : }