github.com/petermattis/pebble@v0.0.0-20190905164901-ab51a2166067/internal/rangedel/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 rangedel
     6  
     7  import "github.com/petermattis/pebble/internal/base"
     8  
     9  // Iter is an iterator over a set of fragmented tombstones.
    10  type Iter struct {
    11  	cmp        base.Compare
    12  	tombstones []Tombstone
    13  	index      int
    14  }
    15  
    16  // NewIter returns a new iterator over a set of fragmented tombstones.
    17  func NewIter(cmp base.Compare, tombstones []Tombstone) *Iter {
    18  	return &Iter{
    19  		cmp:        cmp,
    20  		tombstones: tombstones,
    21  		index:      -1,
    22  	}
    23  }
    24  
    25  // SeekGE implements internalIterator.SeekGE, as documented in the pebble
    26  // package.
    27  func (i *Iter) SeekGE(key []byte) (*base.InternalKey, []byte) {
    28  	// NB: manually inlined sort.Seach is ~5% faster.
    29  	//
    30  	// Define f(-1) == false and f(n) == true.
    31  	// Invariant: f(index-1) == false, f(upper) == true.
    32  	ikey := base.MakeSearchKey(key)
    33  	i.index = 0
    34  	upper := len(i.tombstones)
    35  	for i.index < upper {
    36  		h := int(uint(i.index+upper) >> 1) // avoid overflow when computing h
    37  		// i.index ≤ h < upper
    38  		if base.InternalCompare(i.cmp, ikey, i.tombstones[h].Start) >= 0 {
    39  			i.index = h + 1 // preserves f(i-1) == false
    40  		} else {
    41  			upper = h // preserves f(j) == true
    42  		}
    43  	}
    44  	// i.index == upper, f(i.index-1) == false, and f(upper) (= f(i.index)) ==
    45  	// true => answer is i.index.
    46  	if i.index >= len(i.tombstones) {
    47  		return nil, nil
    48  	}
    49  	t := &i.tombstones[i.index]
    50  	return &t.Start, t.End
    51  }
    52  
    53  func (i *Iter) SeekPrefixGE(prefix, key []byte) (*base.InternalKey, []byte) {
    54  	// This should never be called as prefix iteration is only done for point records.
    55  	panic("pebble: SeekPrefixGE unimplemented")
    56  }
    57  
    58  // SeekLT implements internalIterator.SeekLT, as documented in the pebble
    59  // package.
    60  func (i *Iter) SeekLT(key []byte) (*base.InternalKey, []byte) {
    61  	// NB: manually inlined sort.Search is ~5% faster.
    62  	//
    63  	// Define f(-1) == false and f(n) == true.
    64  	// Invariant: f(index-1) == false, f(upper) == true.
    65  	ikey := base.MakeSearchKey(key)
    66  	i.index = 0
    67  	upper := len(i.tombstones)
    68  	for i.index < upper {
    69  		h := int(uint(i.index+upper) >> 1) // avoid overflow when computing h
    70  		// i.index ≤ h < upper
    71  		if base.InternalCompare(i.cmp, ikey, i.tombstones[h].Start) > 0 {
    72  			i.index = h + 1 // preserves f(i-1) == false
    73  		} else {
    74  			upper = h // preserves f(j) == true
    75  		}
    76  	}
    77  	// i.index == upper, f(i.index-1) == false, and f(upper) (= f(i.index)) ==
    78  	// true => answer is i.index.
    79  
    80  	// Since keys are strictly increasing, if i.index > 0 then i.index-1 will be
    81  	// the largest whose key is < the key sought.
    82  	i.index--
    83  	if i.index < 0 {
    84  		return nil, nil
    85  	}
    86  	t := &i.tombstones[i.index]
    87  	return &t.Start, t.End
    88  }
    89  
    90  // First implements internalIterator.First, as documented in the pebble
    91  // package.
    92  func (i *Iter) First() (*base.InternalKey, []byte) {
    93  	if len(i.tombstones) == 0 {
    94  		return nil, nil
    95  	}
    96  	i.index = 0
    97  	t := &i.tombstones[i.index]
    98  	return &t.Start, t.End
    99  }
   100  
   101  // Last implements internalIterator.Last, as documented in the pebble
   102  // package.
   103  func (i *Iter) Last() (*base.InternalKey, []byte) {
   104  	if len(i.tombstones) == 0 {
   105  		return nil, nil
   106  	}
   107  	i.index = len(i.tombstones) - 1
   108  	t := &i.tombstones[i.index]
   109  	return &t.Start, t.End
   110  }
   111  
   112  // Next implements internalIterator.Next, as documented in the pebble
   113  // package.
   114  func (i *Iter) Next() (*base.InternalKey, []byte) {
   115  	if i.index == len(i.tombstones) {
   116  		return nil, nil
   117  	}
   118  	i.index++
   119  	if i.index == len(i.tombstones) {
   120  		return nil, nil
   121  	}
   122  	t := &i.tombstones[i.index]
   123  	return &t.Start, t.End
   124  }
   125  
   126  // Prev implements internalIterator.Prev, as documented in the pebble
   127  // package.
   128  func (i *Iter) Prev() (*base.InternalKey, []byte) {
   129  	if i.index < 0 {
   130  		return nil, nil
   131  	}
   132  	i.index--
   133  	if i.index < 0 {
   134  		return nil, nil
   135  	}
   136  	t := &i.tombstones[i.index]
   137  	return &t.Start, t.End
   138  }
   139  
   140  // Key implements internalIterator.Key, as documented in the pebble
   141  // package.
   142  func (i *Iter) Key() *base.InternalKey {
   143  	return &i.tombstones[i.index].Start
   144  }
   145  
   146  // Value implements internalIterator.Value, as documented in the pebble
   147  // package.
   148  func (i *Iter) Value() []byte {
   149  	return i.tombstones[i.index].End
   150  }
   151  
   152  // Valid implements internalIterator.Valid, as documented in the pebble
   153  // package.
   154  func (i *Iter) Valid() bool {
   155  	return i.index >= 0 && i.index < len(i.tombstones)
   156  }
   157  
   158  // Error implements internalIterator.Error, as documented in the pebble
   159  // package.
   160  func (i *Iter) Error() error {
   161  	return nil
   162  }
   163  
   164  // Close implements internalIterator.Close, as documented in the pebble
   165  // package.
   166  func (i *Iter) Close() error {
   167  	return nil
   168  }
   169  
   170  // SetBounds implements internalIterator.SetBounds, as documented in the pebble
   171  // package.
   172  func (i *Iter) SetBounds(lower, upper []byte) {
   173  	// This should never be called as bounds are only used for point records.
   174  	panic("pebble: SetBounds unimplemented")
   175  }