github.com/petermattis/pebble@v0.0.0-20190905164901-ab51a2166067/level_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  	"sort"
     9  )
    10  
    11  // tableNewIters creates a new point and range-del iterator for the given file
    12  // number. If bytesIterated is specified, it is incremented as the given file is
    13  // iterated through.
    14  type tableNewIters func(
    15  	meta *fileMetadata, opts *IterOptions, bytesIterated *uint64,
    16  ) (internalIterator, internalIterator, error)
    17  
    18  // levelIter provides a merged view of the sstables in a level.
    19  //
    20  // levelIter is used during compaction and as part of the Iterator
    21  // implementation. When used as part of the Iterator implementation, level
    22  // iteration needs to "pause" at sstable boundaries if a range deletion
    23  // tombstone is the source of that boundary. We know if a range tombstone is
    24  // the smallest or largest key in a file because the kind will be
    25  // InternalKeyKindRangeDeletion. If the boundary key is a range deletion
    26  // tombstone, we materialize a fake entry to return from levelIter. This
    27  // prevents mergingIter from advancing past the sstable until the sstable
    28  // contains the smallest (or largest for reverse iteration) key in the merged
    29  // heap. Note that Iterator treat a range deletion tombstone as a no-op and
    30  // processes range deletions via mergingIter.
    31  type levelIter struct {
    32  	opts      *IterOptions
    33  	tableOpts IterOptions
    34  	cmp       Compare
    35  	index     int
    36  	// The key to return when iterating past an sstable boundary and that
    37  	// boundary is a range deletion tombstone. Note that if boundary != nil, then
    38  	// iter == nil, and if iter != nil, then boundary == nil.
    39  	boundary     *InternalKey
    40  	iter         internalIterator
    41  	newIters     tableNewIters
    42  	rangeDelIter *internalIterator
    43  	files        []fileMetadata
    44  	err          error
    45  	// Pointer into this level's entry in `mergingIter::largestUserKeys`. We populate it
    46  	// with the largest user key for the currently opened file. It is used to limit the optimization
    47  	// that seeks lower-level iterators past keys shadowed by a range tombstone. Limiting this
    48  	// seek to the file upper-bound is necessary since range tombstones are stored untruncated,
    49  	// while they only apply to keys within their containing file's boundaries. For a detailed
    50  	// example, see comment above `mergingIter`.
    51  	//
    52  	// This field differs from the `boundary` field in a few ways:
    53  	// - `boundary` is only populated when the iterator is positioned exactly on the sentinel key.
    54  	// - `boundary` can hold either the lower- or upper-bound, depending on the iterator direction.
    55  	// - `boundary` is not exposed to the next higher-level iterator, i.e., `mergingIter`.
    56  	largestUserKey *[]byte
    57  	// bytesIterated keeps track of the number of bytes iterated during compaction.
    58  	bytesIterated *uint64
    59  }
    60  
    61  // levelIter implements the internalIterator interface.
    62  var _ internalIterator = (*levelIter)(nil)
    63  
    64  func newLevelIter(
    65  	opts *IterOptions,
    66  	cmp Compare,
    67  	newIters tableNewIters,
    68  	files []fileMetadata,
    69  	bytesIterated *uint64,
    70  ) *levelIter {
    71  	l := &levelIter{}
    72  	l.init(opts, cmp, newIters, files, bytesIterated)
    73  	return l
    74  }
    75  
    76  func (l *levelIter) init(
    77  	opts *IterOptions,
    78  	cmp Compare,
    79  	newIters tableNewIters,
    80  	files []fileMetadata,
    81  	bytesIterated *uint64,
    82  ) {
    83  	l.opts = opts
    84  	if l.opts != nil {
    85  		l.tableOpts.TableFilter = l.opts.TableFilter
    86  	}
    87  	l.cmp = cmp
    88  	l.index = -1
    89  	l.newIters = newIters
    90  	l.files = files
    91  	l.bytesIterated = bytesIterated
    92  }
    93  
    94  func (l *levelIter) initRangeDel(rangeDelIter *internalIterator) {
    95  	l.rangeDelIter = rangeDelIter
    96  }
    97  
    98  func (l *levelIter) initLargestUserKey(largestUserKey *[]byte) {
    99  	l.largestUserKey = largestUserKey
   100  }
   101  
   102  func (l *levelIter) findFileGE(key []byte) int {
   103  	// Find the earliest file whose largest key is >= ikey. Note that the range
   104  	// deletion sentinel key is handled specially and a search for K will not
   105  	// find a table where K<range-del-sentinel> is the largest key. This prevents
   106  	// loading untruncated range deletions from a table which can't possibly
   107  	// contain the target key and is required for correctness by DB.Get.
   108  	//
   109  	// TODO(peter): inline the binary search.
   110  	return sort.Search(len(l.files), func(i int) bool {
   111  		largest := &l.files[i].Largest
   112  		c := l.cmp(largest.UserKey, key)
   113  		if c > 0 {
   114  			return true
   115  		}
   116  		return c == 0 && largest.Trailer != InternalKeyRangeDeleteSentinel
   117  	})
   118  }
   119  
   120  func (l *levelIter) findFileLT(key []byte) int {
   121  	// Find the last file whose smallest key is < ikey.
   122  	index := sort.Search(len(l.files), func(i int) bool {
   123  		return l.cmp(l.files[i].Smallest.UserKey, key) >= 0
   124  	})
   125  	return index - 1
   126  }
   127  
   128  func (l *levelIter) loadFile(index, dir int) bool {
   129  	l.boundary = nil
   130  	if l.index == index {
   131  		return l.iter != nil
   132  	}
   133  	if l.iter != nil {
   134  		l.err = l.iter.Close()
   135  		if l.err != nil {
   136  			return false
   137  		}
   138  		l.iter = nil
   139  	}
   140  	if l.rangeDelIter != nil {
   141  		*l.rangeDelIter = nil
   142  	}
   143  
   144  	for ; ; index += dir {
   145  		l.index = index
   146  		if l.index < 0 || l.index >= len(l.files) {
   147  			return false
   148  		}
   149  
   150  		f := &l.files[l.index]
   151  		l.tableOpts.LowerBound = l.opts.GetLowerBound()
   152  		if l.tableOpts.LowerBound != nil {
   153  			if l.cmp(f.Largest.UserKey, l.tableOpts.LowerBound) < 0 {
   154  				// The largest key in the sstable is smaller than the lower bound.
   155  				if dir < 0 {
   156  					return false
   157  				}
   158  				continue
   159  			}
   160  			if l.cmp(l.tableOpts.LowerBound, f.Smallest.UserKey) < 0 {
   161  				// The lower bound is smaller than the smallest key in the
   162  				// table. Iteration within the table does not need to check the lower
   163  				// bound.
   164  				l.tableOpts.LowerBound = nil
   165  			}
   166  		}
   167  		l.tableOpts.UpperBound = l.opts.GetUpperBound()
   168  		if l.tableOpts.UpperBound != nil {
   169  			if l.cmp(f.Smallest.UserKey, l.tableOpts.UpperBound) >= 0 {
   170  				// The smallest key in the sstable is greater than or equal to the
   171  				// lower bound.
   172  				if dir > 0 {
   173  					return false
   174  				}
   175  				continue
   176  			}
   177  			if l.cmp(l.tableOpts.UpperBound, f.Largest.UserKey) > 0 {
   178  				// The upper bound is greater than the largest key in the
   179  				// table. Iteration within the table does not need to check the upper
   180  				// bound.
   181  				l.tableOpts.UpperBound = nil
   182  			}
   183  		}
   184  
   185  		var rangeDelIter internalIterator
   186  		l.iter, rangeDelIter, l.err = l.newIters(f, &l.tableOpts, l.bytesIterated)
   187  		if l.err != nil || l.iter == nil {
   188  			return false
   189  		}
   190  		if l.rangeDelIter != nil {
   191  			*l.rangeDelIter = rangeDelIter
   192  		}
   193  		if l.largestUserKey != nil {
   194  			*l.largestUserKey = f.Largest.UserKey
   195  		}
   196  		return true
   197  	}
   198  }
   199  
   200  func (l *levelIter) SeekGE(key []byte) (*InternalKey, []byte) {
   201  	// NB: the top-level Iterator has already adjusted key based on
   202  	// IterOptions.LowerBound.
   203  	if !l.loadFile(l.findFileGE(key), 1) {
   204  		return nil, nil
   205  	}
   206  	if key, val := l.iter.SeekGE(key); key != nil {
   207  		return key, val
   208  	}
   209  	return l.skipEmptyFileForward()
   210  }
   211  
   212  func (l *levelIter) SeekPrefixGE(prefix, key []byte) (*InternalKey, []byte) {
   213  	// NB: the top-level Iterator has already adjusted key based on
   214  	// IterOptions.LowerBound.
   215  	if !l.loadFile(l.findFileGE(key), 1) {
   216  		return nil, nil
   217  	}
   218  	if key, val := l.iter.SeekPrefixGE(prefix, key); key != nil {
   219  		return key, val
   220  	}
   221  	return l.skipEmptyFileForward()
   222  }
   223  
   224  func (l *levelIter) SeekLT(key []byte) (*InternalKey, []byte) {
   225  	// NB: the top-level Iterator has already adjusted key based on
   226  	// IterOptions.UpperBound.
   227  	if !l.loadFile(l.findFileLT(key), -1) {
   228  		return nil, nil
   229  	}
   230  	if key, val := l.iter.SeekLT(key); key != nil {
   231  		return key, val
   232  	}
   233  	return l.skipEmptyFileBackward()
   234  }
   235  
   236  func (l *levelIter) First() (*InternalKey, []byte) {
   237  	// NB: the top-level Iterator will call SeekGE if IterOptions.LowerBound is
   238  	// set.
   239  	if !l.loadFile(0, 1) {
   240  		return nil, nil
   241  	}
   242  	if key, val := l.iter.First(); key != nil {
   243  		return key, val
   244  	}
   245  	return l.skipEmptyFileForward()
   246  }
   247  
   248  func (l *levelIter) Last() (*InternalKey, []byte) {
   249  	// NB: the top-level Iterator will call SeekLT if IterOptions.UpperBound is
   250  	// set.
   251  	if !l.loadFile(len(l.files)-1, -1) {
   252  		return nil, nil
   253  	}
   254  	if key, val := l.iter.Last(); key != nil {
   255  		return key, val
   256  	}
   257  	return l.skipEmptyFileBackward()
   258  }
   259  
   260  func (l *levelIter) Next() (*InternalKey, []byte) {
   261  	if l.err != nil {
   262  		return nil, nil
   263  	}
   264  
   265  	if l.iter == nil {
   266  		if l.boundary != nil {
   267  			if l.loadFile(l.index+1, 1) {
   268  				if key, val := l.iter.First(); key != nil {
   269  					return key, val
   270  				}
   271  				return l.skipEmptyFileForward()
   272  			}
   273  			return nil, nil
   274  		}
   275  		if l.index == -1 && l.loadFile(0, 1) {
   276  			// The iterator was positioned off the beginning of the level. Position
   277  			// at the first entry.
   278  			if key, val := l.iter.First(); key != nil {
   279  				return key, val
   280  			}
   281  			return l.skipEmptyFileForward()
   282  		}
   283  		return nil, nil
   284  	}
   285  
   286  	if key, val := l.iter.Next(); key != nil {
   287  		return key, val
   288  	}
   289  	return l.skipEmptyFileForward()
   290  }
   291  
   292  func (l *levelIter) Prev() (*InternalKey, []byte) {
   293  	if l.err != nil {
   294  		return nil, nil
   295  	}
   296  
   297  	if l.iter == nil {
   298  		if l.boundary != nil {
   299  			if l.loadFile(l.index-1, -1) {
   300  				if key, val := l.iter.Last(); key != nil {
   301  					return key, val
   302  				}
   303  				return l.skipEmptyFileBackward()
   304  			}
   305  			return nil, nil
   306  		}
   307  		if n := len(l.files); l.index == n && l.loadFile(n-1, -1) {
   308  			// The iterator was positioned off the end of the level. Position at the
   309  			// last entry.
   310  			if key, val := l.iter.Last(); key != nil {
   311  				return key, val
   312  			}
   313  			return l.skipEmptyFileBackward()
   314  		}
   315  		return nil, nil
   316  	}
   317  
   318  	if key, val := l.iter.Prev(); key != nil {
   319  		return key, val
   320  	}
   321  	return l.skipEmptyFileBackward()
   322  }
   323  
   324  func (l *levelIter) skipEmptyFileForward() (*InternalKey, []byte) {
   325  	var key *InternalKey
   326  	var val []byte
   327  	for ; key == nil; key, val = l.iter.First() {
   328  		if l.err = l.iter.Close(); l.err != nil {
   329  			return nil, nil
   330  		}
   331  		l.iter = nil
   332  
   333  		if l.rangeDelIter != nil {
   334  			// We're being used as part of an Iterator and we've reached the end of
   335  			// the sstable. If the boundary is a range deletion tombstone, return
   336  			// that key.
   337  			if f := &l.files[l.index]; f.Largest.Kind() == InternalKeyKindRangeDelete {
   338  				l.boundary = &f.Largest
   339  				return l.boundary, nil
   340  			}
   341  			*l.rangeDelIter = nil
   342  		}
   343  
   344  		// Current file was exhausted. Move to the next file.
   345  		if !l.loadFile(l.index+1, 1) {
   346  			return nil, nil
   347  		}
   348  	}
   349  	return key, val
   350  }
   351  
   352  func (l *levelIter) skipEmptyFileBackward() (*InternalKey, []byte) {
   353  	var key *InternalKey
   354  	var val []byte
   355  	for ; key == nil; key, val = l.iter.Last() {
   356  		if l.err = l.iter.Close(); l.err != nil {
   357  			return nil, nil
   358  		}
   359  		l.iter = nil
   360  
   361  		if l.rangeDelIter != nil {
   362  			// We're being used as part of an Iterator and we've reached the end of
   363  			// the sstable. If the boundary is a range deletion tombstone, return
   364  			// that key.
   365  			if f := &l.files[l.index]; f.Smallest.Kind() == InternalKeyKindRangeDelete {
   366  				l.boundary = &f.Smallest
   367  				return l.boundary, nil
   368  			}
   369  			*l.rangeDelIter = nil
   370  		}
   371  
   372  		// Current file was exhausted. Move to the previous file.
   373  		if !l.loadFile(l.index-1, -1) {
   374  			return nil, nil
   375  		}
   376  	}
   377  	return key, val
   378  }
   379  
   380  func (l *levelIter) Key() *InternalKey {
   381  	if l.iter == nil {
   382  		if l.boundary != nil {
   383  			return l.boundary
   384  		}
   385  		return nil
   386  	}
   387  	return l.iter.Key()
   388  }
   389  
   390  func (l *levelIter) Value() []byte {
   391  	if l.iter == nil {
   392  		return nil
   393  	}
   394  	return l.iter.Value()
   395  }
   396  
   397  func (l *levelIter) Valid() bool {
   398  	if l.iter == nil {
   399  		return l.boundary != nil
   400  	}
   401  	return l.iter.Valid()
   402  }
   403  
   404  func (l *levelIter) Error() error {
   405  	if l.err != nil || l.iter == nil {
   406  		return l.err
   407  	}
   408  	return l.iter.Error()
   409  }
   410  
   411  func (l *levelIter) Close() error {
   412  	if l.iter != nil {
   413  		l.err = l.iter.Close()
   414  		l.iter = nil
   415  	}
   416  	if l.rangeDelIter != nil {
   417  		if t := *l.rangeDelIter; t != nil {
   418  			if err := t.Close(); err != nil && l.err == nil {
   419  				l.err = err
   420  			}
   421  		}
   422  		*l.rangeDelIter = nil
   423  	}
   424  	return l.err
   425  }
   426  
   427  func (l *levelIter) SetBounds(lower, upper []byte) {
   428  	l.opts.LowerBound = lower
   429  	l.opts.UpperBound = upper
   430  	if l.iter != nil {
   431  		l.iter.SetBounds(lower, upper)
   432  	}
   433  }