github.com/petermattis/pebble@v0.0.0-20190905164901-ab51a2166067/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 "github.com/petermattis/pebble/internal/rangedel" 9 ) 10 11 // getIter is an internal iterator used to perform gets. It iterates through 12 // the values for a particular key, level by level. It is not a general purpose 13 // internalIterator, but specialized for Get operations so that it loads data 14 // lazily. 15 type getIter struct { 16 cmp Compare 17 equal Equal 18 newIters tableNewIters 19 snapshot uint64 20 key []byte 21 iter internalIterator 22 rangeDelIter internalIterator 23 tombstone rangedel.Tombstone 24 levelIter levelIter 25 level int 26 batch *Batch 27 mem []flushable 28 l0 []fileMetadata 29 version *version 30 iterKey *InternalKey 31 iterValue []byte 32 err error 33 } 34 35 // getIter implements the internalIterator interface. 36 var _ internalIterator = (*getIter)(nil) 37 38 func (g *getIter) SeekGE(key []byte) (*InternalKey, []byte) { 39 panic("pebble: SeekGE unimplemented") 40 } 41 42 func (g *getIter) SeekPrefixGE(prefix, key []byte) (*InternalKey, []byte) { 43 panic("pebble: SeekPrefixGE unimplemented") 44 } 45 46 func (g *getIter) SeekLT(key []byte) (*InternalKey, []byte) { 47 panic("pebble: SeekLT unimplemented") 48 } 49 50 func (g *getIter) First() (*InternalKey, []byte) { 51 return g.Next() 52 } 53 54 func (g *getIter) Last() (*InternalKey, []byte) { 55 panic("pebble: Last unimplemented") 56 } 57 58 func (g *getIter) Next() (*InternalKey, []byte) { 59 if g.iter != nil { 60 g.iterKey, g.iterValue = g.iter.Next() 61 } 62 63 for { 64 if g.iter != nil { 65 // We have to check rangeDelIter on each iteration because a single 66 // user-key can be spread across multiple tables in a level. A range 67 // tombstone will appear in the table corresponding to its start 68 // key. Every call to levelIter.Next() potentially switches to a new 69 // table and thus reinitializes rangeDelIter. 70 if g.rangeDelIter != nil { 71 g.tombstone = rangedel.Get(g.cmp, g.rangeDelIter, g.key, g.snapshot) 72 if g.err = g.rangeDelIter.Close(); g.err != nil { 73 return nil, nil 74 } 75 g.rangeDelIter = nil 76 } 77 78 if g.iterKey != nil { 79 key := g.iterKey 80 if g.tombstone.Deletes(key.SeqNum()) { 81 // We have a range tombstone covering this key. Rather than return a 82 // point or range deletion here, we return false and close our 83 // internal iterator which will make Valid() return false, 84 // effectively stopping iteration. 85 g.err = g.iter.Close() 86 g.iter = nil 87 return nil, nil 88 } 89 if g.equal(g.key, key.UserKey) { 90 if !key.Visible(g.snapshot) { 91 g.iterKey, g.iterValue = g.iter.Next() 92 continue 93 } 94 return g.iterKey, g.iterValue 95 } 96 } 97 // We've advanced the iterator passed the desired key. Move on to the 98 // next memtable / level. 99 g.err = g.iter.Close() 100 g.iter = nil 101 if g.err != nil { 102 return nil, nil 103 } 104 } 105 106 // Create an iterator from the batch. 107 if g.batch != nil { 108 g.iter = g.batch.newInternalIter(nil) 109 g.rangeDelIter = g.batch.newRangeDelIter(nil) 110 g.batch = nil 111 g.iterKey, g.iterValue = g.iter.SeekGE(g.key) 112 continue 113 } 114 115 // If we have a tombstone from a previous level it is guaranteed to delete 116 // keys in lower levels. 117 if !g.tombstone.Empty() { 118 return nil, nil 119 } 120 121 // Create iterators from memtables from newest to oldest. 122 if n := len(g.mem); n > 0 { 123 m := g.mem[n-1] 124 g.iter = m.newIter(nil) 125 g.rangeDelIter = m.newRangeDelIter(nil) 126 g.mem = g.mem[:n-1] 127 g.iterKey, g.iterValue = g.iter.SeekGE(g.key) 128 continue 129 } 130 131 if g.level == 0 { 132 // Create iterators from L0 from newest to oldest. 133 if n := len(g.l0); n > 0 { 134 l := &g.l0[n-1] 135 g.iter, g.rangeDelIter, g.err = g.newIters( 136 l, 137 nil, /* iter options */ 138 nil /* bytes iterated */) 139 if g.err != nil { 140 return nil, nil 141 } 142 g.l0 = g.l0[:n-1] 143 g.iterKey, g.iterValue = g.iter.SeekGE(g.key) 144 continue 145 } 146 g.level++ 147 } 148 149 if g.level >= numLevels { 150 return nil, nil 151 } 152 if len(g.version.Files[g.level]) == 0 { 153 g.level++ 154 continue 155 } 156 157 g.levelIter.init(nil, g.cmp, g.newIters, g.version.Files[g.level], nil) 158 g.levelIter.initRangeDel(&g.rangeDelIter) 159 g.level++ 160 g.iter = &g.levelIter 161 g.iterKey, g.iterValue = g.iter.SeekGE(g.key) 162 } 163 } 164 165 func (g *getIter) Prev() (*InternalKey, []byte) { 166 panic("pebble: Prev unimplemented") 167 } 168 169 func (g *getIter) Key() *InternalKey { 170 return g.iterKey 171 } 172 173 func (g *getIter) Value() []byte { 174 return g.iterValue 175 } 176 177 func (g *getIter) Valid() bool { 178 return g.iterKey != nil && g.err == nil 179 } 180 181 func (g *getIter) Error() error { 182 return g.err 183 } 184 185 func (g *getIter) Close() error { 186 if g.iter != nil { 187 if err := g.iter.Close(); err != nil && g.err == nil { 188 g.err = err 189 } 190 g.iter = nil 191 } 192 return g.err 193 } 194 195 func (g *getIter) SetBounds(lower, upper []byte) { 196 panic("pebble: SetBounds unimplemented") 197 }