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  }