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