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  }