github.com/cockroachdb/pebble@v1.1.1-0.20240513155919-3622ade60459/get_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 pebble 6 7 import ( 8 "context" 9 "fmt" 10 11 "github.com/cockroachdb/pebble/internal/base" 12 "github.com/cockroachdb/pebble/internal/keyspan" 13 "github.com/cockroachdb/pebble/internal/manifest" 14 ) 15 16 // getIter is an internal iterator used to perform gets. It iterates through 17 // the values for a particular key, level by level. It is not a general purpose 18 // internalIterator, but specialized for Get operations so that it loads data 19 // lazily. 20 type getIter struct { 21 logger Logger 22 comparer *Comparer 23 newIters tableNewIters 24 snapshot uint64 25 key []byte 26 iter internalIterator 27 rangeDelIter keyspan.FragmentIterator 28 tombstone *keyspan.Span 29 levelIter levelIter 30 level int 31 batch *Batch 32 mem flushableList 33 l0 []manifest.LevelSlice 34 version *version 35 iterKey *InternalKey 36 iterValue base.LazyValue 37 err error 38 } 39 40 // TODO(sumeer): CockroachDB code doesn't use getIter, but, for completeness, 41 // make this implement InternalIteratorWithStats. 42 43 // getIter implements the base.InternalIterator interface. 44 var _ base.InternalIterator = (*getIter)(nil) 45 46 func (g *getIter) String() string { 47 return fmt.Sprintf("len(l0)=%d, len(mem)=%d, level=%d", len(g.l0), len(g.mem), g.level) 48 } 49 50 func (g *getIter) SeekGE(key []byte, flags base.SeekGEFlags) (*InternalKey, base.LazyValue) { 51 panic("pebble: SeekGE unimplemented") 52 } 53 54 func (g *getIter) SeekPrefixGE( 55 prefix, key []byte, flags base.SeekGEFlags, 56 ) (*base.InternalKey, base.LazyValue) { 57 panic("pebble: SeekPrefixGE unimplemented") 58 } 59 60 func (g *getIter) SeekLT(key []byte, flags base.SeekLTFlags) (*InternalKey, base.LazyValue) { 61 panic("pebble: SeekLT unimplemented") 62 } 63 64 func (g *getIter) First() (*InternalKey, base.LazyValue) { 65 return g.Next() 66 } 67 68 func (g *getIter) Last() (*InternalKey, base.LazyValue) { 69 panic("pebble: Last unimplemented") 70 } 71 72 func (g *getIter) Next() (*InternalKey, base.LazyValue) { 73 if g.iter != nil { 74 g.iterKey, g.iterValue = g.iter.Next() 75 } 76 77 for { 78 if g.iter != nil { 79 // We have to check rangeDelIter on each iteration because a single 80 // user-key can be spread across multiple tables in a level. A range 81 // tombstone will appear in the table corresponding to its start 82 // key. Every call to levelIter.Next() potentially switches to a new 83 // table and thus reinitializes rangeDelIter. 84 if g.rangeDelIter != nil { 85 g.tombstone = keyspan.Get(g.comparer.Compare, g.rangeDelIter, g.key) 86 if g.err = g.rangeDelIter.Close(); g.err != nil { 87 return nil, base.LazyValue{} 88 } 89 g.rangeDelIter = nil 90 } 91 92 if g.iterKey != nil { 93 key := g.iterKey 94 if g.tombstone != nil && g.tombstone.CoversAt(g.snapshot, key.SeqNum()) { 95 // We have a range tombstone covering this key. Rather than return a 96 // point or range deletion here, we return false and close our 97 // internal iterator which will make Valid() return false, 98 // effectively stopping iteration. 99 g.err = g.iter.Close() 100 g.iter = nil 101 return nil, base.LazyValue{} 102 } 103 if g.comparer.Equal(g.key, key.UserKey) { 104 if !key.Visible(g.snapshot, base.InternalKeySeqNumMax) { 105 g.iterKey, g.iterValue = g.iter.Next() 106 continue 107 } 108 return g.iterKey, g.iterValue 109 } 110 } 111 // We've advanced the iterator passed the desired key. Move on to the 112 // next memtable / level. 113 g.err = g.iter.Close() 114 g.iter = nil 115 if g.err != nil { 116 return nil, base.LazyValue{} 117 } 118 } 119 120 // Create an iterator from the batch. 121 if g.batch != nil { 122 if g.batch.index == nil { 123 g.err = ErrNotIndexed 124 g.iterKey, g.iterValue = nil, base.LazyValue{} 125 return nil, base.LazyValue{} 126 } 127 g.iter = g.batch.newInternalIter(nil) 128 g.rangeDelIter = g.batch.newRangeDelIter( 129 nil, 130 // Get always reads the entirety of the batch's history, so no 131 // batch keys should be filtered. 132 base.InternalKeySeqNumMax, 133 ) 134 g.iterKey, g.iterValue = g.iter.SeekGE(g.key, base.SeekGEFlagsNone) 135 g.batch = nil 136 continue 137 } 138 139 // If we have a tombstone from a previous level it is guaranteed to delete 140 // keys in lower levels. 141 if g.tombstone != nil && g.tombstone.VisibleAt(g.snapshot) { 142 return nil, base.LazyValue{} 143 } 144 145 // Create iterators from memtables from newest to oldest. 146 if n := len(g.mem); n > 0 { 147 m := g.mem[n-1] 148 g.iter = m.newIter(nil) 149 g.rangeDelIter = m.newRangeDelIter(nil) 150 g.mem = g.mem[:n-1] 151 g.iterKey, g.iterValue = g.iter.SeekGE(g.key, base.SeekGEFlagsNone) 152 continue 153 } 154 155 if g.level == 0 { 156 // Create iterators from L0 from newest to oldest. 157 if n := len(g.l0); n > 0 { 158 files := g.l0[n-1].Iter() 159 g.l0 = g.l0[:n-1] 160 iterOpts := IterOptions{logger: g.logger, snapshotForHideObsoletePoints: g.snapshot} 161 g.levelIter.init(context.Background(), iterOpts, g.comparer, g.newIters, 162 files, manifest.L0Sublevel(n), internalIterOpts{}) 163 g.levelIter.initRangeDel(&g.rangeDelIter) 164 bc := levelIterBoundaryContext{} 165 g.levelIter.initBoundaryContext(&bc) 166 g.iter = &g.levelIter 167 168 // Compute the key prefix for bloom filtering if split function is 169 // specified, or use the user key as default. 170 prefix := g.key 171 if g.comparer.Split != nil { 172 prefix = g.key[:g.comparer.Split(g.key)] 173 } 174 g.iterKey, g.iterValue = g.iter.SeekPrefixGE(prefix, g.key, base.SeekGEFlagsNone) 175 if bc.isSyntheticIterBoundsKey || bc.isIgnorableBoundaryKey { 176 g.iterKey = nil 177 g.iterValue = base.LazyValue{} 178 } 179 continue 180 } 181 g.level++ 182 } 183 184 if g.level >= numLevels { 185 return nil, base.LazyValue{} 186 } 187 if g.version.Levels[g.level].Empty() { 188 g.level++ 189 continue 190 } 191 192 iterOpts := IterOptions{logger: g.logger, snapshotForHideObsoletePoints: g.snapshot} 193 g.levelIter.init(context.Background(), iterOpts, g.comparer, g.newIters, 194 g.version.Levels[g.level].Iter(), manifest.Level(g.level), internalIterOpts{}) 195 g.levelIter.initRangeDel(&g.rangeDelIter) 196 bc := levelIterBoundaryContext{} 197 g.levelIter.initBoundaryContext(&bc) 198 g.level++ 199 g.iter = &g.levelIter 200 201 // Compute the key prefix for bloom filtering if split function is 202 // specified, or use the user key as default. 203 prefix := g.key 204 if g.comparer.Split != nil { 205 prefix = g.key[:g.comparer.Split(g.key)] 206 } 207 g.iterKey, g.iterValue = g.iter.SeekPrefixGE(prefix, g.key, base.SeekGEFlagsNone) 208 if bc.isSyntheticIterBoundsKey || bc.isIgnorableBoundaryKey { 209 g.iterKey = nil 210 g.iterValue = base.LazyValue{} 211 } 212 } 213 } 214 215 func (g *getIter) Prev() (*InternalKey, base.LazyValue) { 216 panic("pebble: Prev unimplemented") 217 } 218 219 func (g *getIter) NextPrefix([]byte) (*InternalKey, base.LazyValue) { 220 panic("pebble: NextPrefix unimplemented") 221 } 222 223 func (g *getIter) Valid() bool { 224 return g.iterKey != nil && g.err == nil 225 } 226 227 func (g *getIter) Error() error { 228 return g.err 229 } 230 231 func (g *getIter) Close() error { 232 if g.iter != nil { 233 if err := g.iter.Close(); err != nil && g.err == nil { 234 g.err = err 235 } 236 g.iter = nil 237 } 238 return g.err 239 } 240 241 func (g *getIter) SetBounds(lower, upper []byte) { 242 panic("pebble: SetBounds unimplemented") 243 }