github.com/zuoyebang/bitalostable@v1.0.1-0.20240229032404-e3b99a834294/internal/keyspan/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 keyspan
     6  
     7  import (
     8  	"github.com/zuoyebang/bitalostable/internal/base"
     9  	"github.com/zuoyebang/bitalostable/internal/manifest"
    10  )
    11  
    12  // FragmentIterator defines an iterator interface over spans. The spans
    13  // surfaced by a FragmentIterator must be non-overlapping. This is achieved by
    14  // fragmenting spans at overlap points (see Fragmenter).
    15  //
    16  // A Span returned by a FragmentIterator is only valid until the next
    17  // positioning method. Some implementations (eg, keyspan.Iter) may provide
    18  // longer lifetimes but implementations need only guarantee stability until the
    19  // next positioning method.
    20  type FragmentIterator interface {
    21  	// SeekGE moves the iterator to the first span whose start key is greater
    22  	// than or equal to the given key.
    23  	SeekGE(key []byte) *Span
    24  
    25  	// SeekLT moves the iterator to the last span whose start key is less than
    26  	// the given key.
    27  	SeekLT(key []byte) *Span
    28  
    29  	// First moves the iterator to the first span.
    30  	First() *Span
    31  
    32  	// Last moves the iterator to the last span.
    33  	Last() *Span
    34  
    35  	// Next moves the iterator to the next span.
    36  	//
    37  	// It is valid to call Next when the iterator is positioned before the first
    38  	// key/value pair due to either a prior call to SeekLT or Prev which
    39  	// returned an invalid span. It is not allowed to call Next when the
    40  	// previous call to SeekGE, SeekPrefixGE or Next returned an invalid span.
    41  	Next() *Span
    42  
    43  	// Prev moves the iterator to the previous span.
    44  	//
    45  	// It is valid to call Prev when the iterator is positioned after the last
    46  	// key/value pair due to either a prior call to SeekGE or Next which
    47  	// returned an invalid span. It is not allowed to call Prev when the
    48  	// previous call to SeekLT or Prev returned an invalid span.
    49  	Prev() *Span
    50  
    51  	// Error returns any accumulated error.
    52  	Error() error
    53  
    54  	// Close closes the iterator and returns any accumulated error. Exhausting
    55  	// the iterator is not considered to be an error. It is valid to call Close
    56  	// multiple times. Other methods should not be called after the iterator has
    57  	// been closed.
    58  	Close() error
    59  }
    60  
    61  // TableNewSpanIter creates a new iterator for spans for the given file.
    62  type TableNewSpanIter func(file *manifest.FileMetadata, iterOptions *SpanIterOptions) (FragmentIterator, error)
    63  
    64  // SpanIterOptions is a subset of IterOptions that are necessary to instantiate
    65  // per-sstable span iterators.
    66  type SpanIterOptions struct {
    67  	// RangeKeyFilters can be used to avoid scanning tables and blocks in tables
    68  	// when iterating over range keys.
    69  	RangeKeyFilters []base.BlockPropertyFilter
    70  }
    71  
    72  // Iter is an iterator over a set of fragmented spans.
    73  type Iter struct {
    74  	cmp   base.Compare
    75  	spans []Span
    76  	index int
    77  }
    78  
    79  // Iter implements the FragmentIterator interface.
    80  var _ FragmentIterator = (*Iter)(nil)
    81  
    82  // NewIter returns a new iterator over a set of fragmented spans.
    83  func NewIter(cmp base.Compare, spans []Span) *Iter {
    84  	i := &Iter{}
    85  	i.Init(cmp, spans)
    86  	return i
    87  }
    88  
    89  // Count returns the number of spans contained by Iter.
    90  func (i *Iter) Count() int {
    91  	return len(i.spans)
    92  }
    93  
    94  // Init initializes an Iter with the provided spans.
    95  func (i *Iter) Init(cmp base.Compare, spans []Span) {
    96  	*i = Iter{
    97  		cmp:   cmp,
    98  		spans: spans,
    99  		index: -1,
   100  	}
   101  }
   102  
   103  // SeekGE implements FragmentIterator.SeekGE.
   104  func (i *Iter) SeekGE(key []byte) *Span {
   105  	// NB: manually inlined sort.Search is ~5% faster.
   106  	//
   107  	// Define f(-1) == false and f(n) == true.
   108  	// Invariant: f(index-1) == false, f(upper) == true.
   109  	i.index = 0
   110  	upper := len(i.spans)
   111  	for i.index < upper {
   112  		h := int(uint(i.index+upper) >> 1) // avoid overflow when computing h
   113  		// i.index ≤ h < upper
   114  		if i.cmp(key, i.spans[h].Start) > 0 {
   115  			i.index = h + 1 // preserves f(i-1) == false
   116  		} else {
   117  			upper = h // preserves f(j) == true
   118  		}
   119  	}
   120  	// i.index == upper, f(i.index-1) == false, and f(upper) (= f(i.index)) ==
   121  	// true => answer is i.index.
   122  	if i.index >= len(i.spans) {
   123  		return nil
   124  	}
   125  	return &i.spans[i.index]
   126  }
   127  
   128  // SeekLT implements FragmentIterator.SeekLT.
   129  func (i *Iter) SeekLT(key []byte) *Span {
   130  	// NB: manually inlined sort.Search is ~5% faster.
   131  	//
   132  	// Define f(-1) == false and f(n) == true.
   133  	// Invariant: f(index-1) == false, f(upper) == true.
   134  	i.index = 0
   135  	upper := len(i.spans)
   136  	for i.index < upper {
   137  		h := int(uint(i.index+upper) >> 1) // avoid overflow when computing h
   138  		// i.index ≤ h < upper
   139  		if i.cmp(key, i.spans[h].Start) > 0 {
   140  			i.index = h + 1 // preserves f(i-1) == false
   141  		} else {
   142  			upper = h // preserves f(j) == true
   143  		}
   144  	}
   145  	// i.index == upper, f(i.index-1) == false, and f(upper) (= f(i.index)) ==
   146  	// true => answer is i.index.
   147  
   148  	// Since keys are strictly increasing, if i.index > 0 then i.index-1 will be
   149  	// the largest whose key is < the key sought.
   150  	i.index--
   151  	if i.index < 0 {
   152  		return nil
   153  	}
   154  	return &i.spans[i.index]
   155  }
   156  
   157  // First implements FragmentIterator.First.
   158  func (i *Iter) First() *Span {
   159  	if len(i.spans) == 0 {
   160  		return nil
   161  	}
   162  	i.index = 0
   163  	return &i.spans[i.index]
   164  }
   165  
   166  // Last implements FragmentIterator.Last.
   167  func (i *Iter) Last() *Span {
   168  	if len(i.spans) == 0 {
   169  		return nil
   170  	}
   171  	i.index = len(i.spans) - 1
   172  	return &i.spans[i.index]
   173  }
   174  
   175  // Next implements FragmentIterator.Next.
   176  func (i *Iter) Next() *Span {
   177  	if i.index >= len(i.spans) {
   178  		return nil
   179  	}
   180  	i.index++
   181  	if i.index >= len(i.spans) {
   182  		return nil
   183  	}
   184  	return &i.spans[i.index]
   185  }
   186  
   187  // Prev implements FragmentIterator.Prev.
   188  func (i *Iter) Prev() *Span {
   189  	if i.index < 0 {
   190  		return nil
   191  	}
   192  	i.index--
   193  	if i.index < 0 {
   194  		return nil
   195  	}
   196  	return &i.spans[i.index]
   197  }
   198  
   199  // Error implements FragmentIterator.Error.
   200  func (i *Iter) Error() error {
   201  	return nil
   202  }
   203  
   204  // Close implements FragmentIterator.Close.
   205  func (i *Iter) Close() error {
   206  	return nil
   207  }
   208  
   209  func (i *Iter) String() string {
   210  	return "fragmented-spans"
   211  }