github.com/zuoyebang/bitalostable@v1.0.1-0.20240229032404-e3b99a834294/internal/keyspan/iter.go (about) 1 // Copyright 2018 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 keyspan 6 7 import ( 8 "github.com/zuoyebang/bitalostable/internal/base" 9 "github.com/zuoyebang/bitalostable/internal/manifest" 10 ) 11 12 // FragmentIterator defines an iterator interface over spans. The spans 13 // surfaced by a FragmentIterator must be non-overlapping. This is achieved by 14 // fragmenting spans at overlap points (see Fragmenter). 15 // 16 // A Span returned by a FragmentIterator is only valid until the next 17 // positioning method. Some implementations (eg, keyspan.Iter) may provide 18 // longer lifetimes but implementations need only guarantee stability until the 19 // next positioning method. 20 type FragmentIterator interface { 21 // SeekGE moves the iterator to the first span whose start key is greater 22 // than or equal to the given key. 23 SeekGE(key []byte) *Span 24 25 // SeekLT moves the iterator to the last span whose start key is less than 26 // the given key. 27 SeekLT(key []byte) *Span 28 29 // First moves the iterator to the first span. 30 First() *Span 31 32 // Last moves the iterator to the last span. 33 Last() *Span 34 35 // Next moves the iterator to the next span. 36 // 37 // It is valid to call Next when the iterator is positioned before the first 38 // key/value pair due to either a prior call to SeekLT or Prev which 39 // returned an invalid span. It is not allowed to call Next when the 40 // previous call to SeekGE, SeekPrefixGE or Next returned an invalid span. 41 Next() *Span 42 43 // Prev moves the iterator to the previous span. 44 // 45 // It is valid to call Prev when the iterator is positioned after the last 46 // key/value pair due to either a prior call to SeekGE or Next which 47 // returned an invalid span. It is not allowed to call Prev when the 48 // previous call to SeekLT or Prev returned an invalid span. 49 Prev() *Span 50 51 // Error returns any accumulated error. 52 Error() error 53 54 // Close closes the iterator and returns any accumulated error. Exhausting 55 // the iterator is not considered to be an error. It is valid to call Close 56 // multiple times. Other methods should not be called after the iterator has 57 // been closed. 58 Close() error 59 } 60 61 // TableNewSpanIter creates a new iterator for spans for the given file. 62 type TableNewSpanIter func(file *manifest.FileMetadata, iterOptions *SpanIterOptions) (FragmentIterator, error) 63 64 // SpanIterOptions is a subset of IterOptions that are necessary to instantiate 65 // per-sstable span iterators. 66 type SpanIterOptions struct { 67 // RangeKeyFilters can be used to avoid scanning tables and blocks in tables 68 // when iterating over range keys. 69 RangeKeyFilters []base.BlockPropertyFilter 70 } 71 72 // Iter is an iterator over a set of fragmented spans. 73 type Iter struct { 74 cmp base.Compare 75 spans []Span 76 index int 77 } 78 79 // Iter implements the FragmentIterator interface. 80 var _ FragmentIterator = (*Iter)(nil) 81 82 // NewIter returns a new iterator over a set of fragmented spans. 83 func NewIter(cmp base.Compare, spans []Span) *Iter { 84 i := &Iter{} 85 i.Init(cmp, spans) 86 return i 87 } 88 89 // Count returns the number of spans contained by Iter. 90 func (i *Iter) Count() int { 91 return len(i.spans) 92 } 93 94 // Init initializes an Iter with the provided spans. 95 func (i *Iter) Init(cmp base.Compare, spans []Span) { 96 *i = Iter{ 97 cmp: cmp, 98 spans: spans, 99 index: -1, 100 } 101 } 102 103 // SeekGE implements FragmentIterator.SeekGE. 104 func (i *Iter) SeekGE(key []byte) *Span { 105 // NB: manually inlined sort.Search is ~5% faster. 106 // 107 // Define f(-1) == false and f(n) == true. 108 // Invariant: f(index-1) == false, f(upper) == true. 109 i.index = 0 110 upper := len(i.spans) 111 for i.index < upper { 112 h := int(uint(i.index+upper) >> 1) // avoid overflow when computing h 113 // i.index ≤ h < upper 114 if i.cmp(key, i.spans[h].Start) > 0 { 115 i.index = h + 1 // preserves f(i-1) == false 116 } else { 117 upper = h // preserves f(j) == true 118 } 119 } 120 // i.index == upper, f(i.index-1) == false, and f(upper) (= f(i.index)) == 121 // true => answer is i.index. 122 if i.index >= len(i.spans) { 123 return nil 124 } 125 return &i.spans[i.index] 126 } 127 128 // SeekLT implements FragmentIterator.SeekLT. 129 func (i *Iter) SeekLT(key []byte) *Span { 130 // NB: manually inlined sort.Search is ~5% faster. 131 // 132 // Define f(-1) == false and f(n) == true. 133 // Invariant: f(index-1) == false, f(upper) == true. 134 i.index = 0 135 upper := len(i.spans) 136 for i.index < upper { 137 h := int(uint(i.index+upper) >> 1) // avoid overflow when computing h 138 // i.index ≤ h < upper 139 if i.cmp(key, i.spans[h].Start) > 0 { 140 i.index = h + 1 // preserves f(i-1) == false 141 } else { 142 upper = h // preserves f(j) == true 143 } 144 } 145 // i.index == upper, f(i.index-1) == false, and f(upper) (= f(i.index)) == 146 // true => answer is i.index. 147 148 // Since keys are strictly increasing, if i.index > 0 then i.index-1 will be 149 // the largest whose key is < the key sought. 150 i.index-- 151 if i.index < 0 { 152 return nil 153 } 154 return &i.spans[i.index] 155 } 156 157 // First implements FragmentIterator.First. 158 func (i *Iter) First() *Span { 159 if len(i.spans) == 0 { 160 return nil 161 } 162 i.index = 0 163 return &i.spans[i.index] 164 } 165 166 // Last implements FragmentIterator.Last. 167 func (i *Iter) Last() *Span { 168 if len(i.spans) == 0 { 169 return nil 170 } 171 i.index = len(i.spans) - 1 172 return &i.spans[i.index] 173 } 174 175 // Next implements FragmentIterator.Next. 176 func (i *Iter) Next() *Span { 177 if i.index >= len(i.spans) { 178 return nil 179 } 180 i.index++ 181 if i.index >= len(i.spans) { 182 return nil 183 } 184 return &i.spans[i.index] 185 } 186 187 // Prev implements FragmentIterator.Prev. 188 func (i *Iter) Prev() *Span { 189 if i.index < 0 { 190 return nil 191 } 192 i.index-- 193 if i.index < 0 { 194 return nil 195 } 196 return &i.spans[i.index] 197 } 198 199 // Error implements FragmentIterator.Error. 200 func (i *Iter) Error() error { 201 return nil 202 } 203 204 // Close implements FragmentIterator.Close. 205 func (i *Iter) Close() error { 206 return nil 207 } 208 209 func (i *Iter) String() string { 210 return "fragmented-spans" 211 }