github.com/zuoyebang/bitalostable@v1.0.1-0.20240229032404-e3b99a834294/internal/keyspan/interleaving_iter.go (about)

     1  // Copyright 2021 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  	"fmt"
     9  
    10  	"github.com/zuoyebang/bitalostable/internal/base"
    11  	"github.com/zuoyebang/bitalostable/internal/invariants"
    12  )
    13  
    14  // A SpanMask may be used to configure an interleaving iterator to skip point
    15  // keys that fall within the bounds of some spans.
    16  type SpanMask interface {
    17  	// SpanChanged is invoked by an interleaving iterator whenever the current
    18  	// span changes. As the iterator passes into or out of a Span, it invokes
    19  	// SpanChanged, passing the new Span. When the iterator passes out of a
    20  	// span's boundaries and is no longer covered by any span, SpanChanged is
    21  	// invoked with a nil span.
    22  	//
    23  	// SpanChanged is invoked before SkipPoint, and callers may use SpanChanged
    24  	// to recalculate state used by SkipPoint for masking.
    25  	//
    26  	// SpanChanged may be invoked consecutively with identical spans under some
    27  	// circumstances, such as repeatedly absolutely positioning an iterator to
    28  	// positions covered by the same span, or while changing directions.
    29  	SpanChanged(*Span)
    30  	// SkipPoint is invoked by the interleaving iterator whenever the iterator
    31  	// encounters a point key covered by a Span. If SkipPoint returns true, the
    32  	// interleaving iterator skips the point key without returning it. This is
    33  	// used during range key iteration to skip over point keys 'masked' by range
    34  	// keys.
    35  	SkipPoint(userKey []byte) bool
    36  }
    37  
    38  // InterleavingIter combines an iterator over point keys with an iterator over
    39  // key spans.
    40  //
    41  // Throughout Pebble, some keys apply at single discrete points within the user
    42  // keyspace. Other keys apply over continuous spans of the user key space.
    43  // Internally, iterators over point keys adhere to the base.InternalIterator
    44  // interface, and iterators over spans adhere to the keyspan.FragmentIterator
    45  // interface. The InterleavingIterator wraps a point iterator and span iterator,
    46  // providing access to all the elements of both iterators.
    47  //
    48  // The InterleavingIterator implements the point base.InternalIterator
    49  // interface. After any of the iterator's methods return a key, a caller may
    50  // call Span to retrieve the span covering the returned key, if any.  A span is
    51  // considered to 'cover' a returned key if the span's [start, end) bounds
    52  // include the key's user key.
    53  //
    54  // In addition to tracking the current covering span, InterleavingIter returns a
    55  // special InternalKey at span start boundaries. Start boundaries are surfaced
    56  // as a synthetic span marker: an InternalKey with the boundary as the user key,
    57  // the infinite sequence number and a key kind selected from an arbitrary key
    58  // the infinite sequence number and an arbitrary contained key's kind. Since
    59  // which of the Span's key's kind is surfaced is undefined, the caller should
    60  // not use the InternalKey's kind. The caller should only rely on the `Span`
    61  // method for retrieving information about spanning keys. The interleaved
    62  // synthetic keys have the infinite sequence number so that they're interleaved
    63  // before any point keys with the same user key when iterating forward and after
    64  // when iterating backward.
    65  //
    66  // Interleaving the synthetic start key boundaries at the maximum sequence
    67  // number provides an opportunity for the higher-level, public Iterator to
    68  // observe the Span, even if no live points keys exist within the boudns of the
    69  // Span.
    70  //
    71  // When returning a synthetic marker key for a start boundary, InterleavingIter
    72  // will truncate the span's start bound to the SeekGE or SeekPrefixGE search
    73  // key. For example, a SeekGE("d") that finds a span [a, z) may return a
    74  // synthetic span marker key `d#72057594037927935,21`.
    75  //
    76  // If bounds have been applied to the iterator through SetBounds,
    77  // InterleavingIter will truncate the bounds of spans returned through Span to
    78  // the set bounds. The bounds returned through Span are not truncated by a
    79  // SeekGE or SeekPrefixGE search key. Consider, for example SetBounds('c', 'e'),
    80  // with an iterator containing the Span [a,z):
    81  //
    82  //	First()     = `c#72057594037927935,21`        Span() = [c,e)
    83  //	SeekGE('d') = `d#72057594037927935,21`        Span() = [c,e)
    84  //
    85  // InterleavedIter does not interleave synthetic markers for spans that do not
    86  // contain any keys.
    87  //
    88  // # SpanMask
    89  //
    90  // InterelavingIter takes a SpanMask parameter that may be used to configure the
    91  // behavior of the iterator. See the documentation on the SpanMask type.
    92  //
    93  // All spans containing keys are exposed during iteration.
    94  type InterleavingIter struct {
    95  	cmp         base.Compare
    96  	comparer    *base.Comparer
    97  	pointIter   base.InternalIterator
    98  	keyspanIter FragmentIterator
    99  	mask        SpanMask
   100  
   101  	// lower and upper hold the iteration bounds set through SetBounds.
   102  	lower, upper []byte
   103  	// keyBuf is used to copy SeekGE or SeekPrefixGE arguments when they're used
   104  	// to truncate a span. The byte slices backing a SeekGE/SeekPrefixGE search
   105  	// keys can come directly from the end user, so they're copied into keyBuf
   106  	// to ensure key stability.
   107  	keyBuf []byte
   108  	// nextPrefixBuf is used during SeekPrefixGE calls to store the truncated
   109  	// upper bound of the returned spans. SeekPrefixGE truncates the returned
   110  	// spans to an upper bound of the seeked prefix's immediate successor.
   111  	nextPrefixBuf []byte
   112  	pointKey      *base.InternalKey
   113  	pointVal      []byte
   114  	// span holds the span at the keyspanIter's current position. If the span is
   115  	// wholly contained within the iterator bounds, this span is directly
   116  	// returned to the iterator consumer through Span(). If either bound needed
   117  	// to be truncated to the iterator bounds, then truncated is set to true and
   118  	// Span() must return a pointer to truncatedSpan.
   119  	span *Span
   120  	// spanMarker holds the synthetic key that is returned when the iterator
   121  	// passes over a key span's start bound.
   122  	spanMarker base.InternalKey
   123  	// truncated indicates whether or not the span at the current position
   124  	// needed to be truncated. If it did, truncatedSpan holds the truncated
   125  	// span that should be returned.
   126  	truncatedSpan Span
   127  	truncated     bool
   128  
   129  	// Keeping all of the bools together reduces the sizeof the struct.
   130  
   131  	// spanCoversKey indicates whether the current span covers the last-returned
   132  	// key.
   133  	spanCoversKey bool
   134  	// pointKeyInterleaved indicates whether the current point key has been
   135  	// interleaved in the current direction.
   136  	pointKeyInterleaved bool
   137  	// keyspanInterleaved indicates whether or not the current span has been
   138  	// interleaved at its start key in the current direction. A span marker is
   139  	// interleaved when first passing over the start key.
   140  	//
   141  	// When iterating in the forward direction, the span start key is
   142  	// interleaved when the span first begins to cover the current iterator
   143  	// position. The keyspan iterator isn't advanced until the
   144  	// InterleavingIterator moves beyond the current span's end key. This field
   145  	// is used to remember that the span has already been interleaved and
   146  	// shouldn't be interleaved again.
   147  	//
   148  	// When iterating in the reverse direction, the span start key is
   149  	// interleaved immediately before the iterator will move to a key no longer
   150  	// be covered by the span. This field behaves analagously to
   151  	// pointKeyInterleaved and if true signals that we must Prev the keyspan
   152  	// iterator on the next Prev call.
   153  	keyspanInterleaved bool
   154  	// spanMarkerTruncated is set by SeekGE/SeekPrefixGE calls that truncate a
   155  	// span's start bound marker to the search key. It's returned to false on
   156  	// the next repositioning of the keyspan iterator.
   157  	spanMarkerTruncated bool
   158  	// maskSpanChangedCalled records whether or not the last call to
   159  	// SpanMask.SpanChanged provided the current span (i.span) or not.
   160  	maskSpanChangedCalled bool
   161  	// prefix records whether the iteator is in prefix mode. During prefix mode,
   162  	// Pebble will truncate spans to the next prefix. If the iterator
   163  	// subsequently leaves prefix mode, the existing span cached in i.span must
   164  	// be invalidated because its bounds do not reflect the original span's true
   165  	// bounds.
   166  	prefix bool
   167  	// dir indicates the direction of iteration: forward (+1) or backward (-1)
   168  	dir int8
   169  }
   170  
   171  // Assert that *InterleavingIter implements the InternalIterator interface.
   172  var _ base.InternalIterator = &InterleavingIter{}
   173  
   174  // Init initializes the InterleavingIter to interleave point keys from pointIter
   175  // with key spans from keyspanIter.
   176  //
   177  // The point iterator must already have the provided bounds. Init does not
   178  // propagate the bounds down the iterator stack.
   179  func (i *InterleavingIter) Init(
   180  	comparer *base.Comparer,
   181  	pointIter base.InternalIterator,
   182  	keyspanIter FragmentIterator,
   183  	mask SpanMask,
   184  	lowerBound, upperBound []byte,
   185  ) {
   186  	*i = InterleavingIter{
   187  		cmp:         comparer.Compare,
   188  		comparer:    comparer,
   189  		pointIter:   pointIter,
   190  		keyspanIter: keyspanIter,
   191  		mask:        mask,
   192  		lower:       lowerBound,
   193  		upper:       upperBound,
   194  	}
   195  }
   196  
   197  // InitSeekGE may be called after Init but before any positioning method.
   198  // InitSeekGE initializes the current position of the point iterator and then
   199  // performs a SeekGE on the keyspan iterator using the provided key. InitSeekGE
   200  // returns whichever point or keyspan key is smaller. After InitSeekGE, the
   201  // iterator is positioned and may be repositioned using relative positioning
   202  // methods.
   203  //
   204  // This method is used specifically for lazily constructing combined iterators.
   205  // It allows for seeding the iterator with the current position of the point
   206  // iterator.
   207  func (i *InterleavingIter) InitSeekGE(
   208  	prefix, key []byte, pointKey *base.InternalKey, pointValue []byte,
   209  ) (*base.InternalKey, []byte) {
   210  	i.dir = +1
   211  	i.clearMask()
   212  	i.prefix = prefix != nil
   213  	i.pointKey, i.pointVal = pointKey, pointValue
   214  	i.pointKeyInterleaved = false
   215  	// NB: This keyspanSeekGE call will truncate the span to the seek key if
   216  	// necessary. This truncation is important for cases where a switch to
   217  	// combined iteration is made during a user-initiated SeekGE.
   218  	i.keyspanSeekGE(key, prefix)
   219  	return i.interleaveForward(key, prefix)
   220  }
   221  
   222  // InitSeekLT may be called after Init but before any positioning method.
   223  // InitSeekLT initializes the current position of the point iterator and then
   224  // performs a SeekLT on the keyspan iterator using the provided key. InitSeekLT
   225  // returns whichever point or keyspan key is larger. After InitSeekLT, the
   226  // iterator is positioned and may be repositioned using relative positioning
   227  // methods.
   228  //
   229  // This method is used specifically for lazily constructing combined iterators.
   230  // It allows for seeding the iterator with the current position of the point
   231  // iterator.
   232  func (i *InterleavingIter) InitSeekLT(
   233  	key []byte, pointKey *base.InternalKey, pointValue []byte,
   234  ) (*base.InternalKey, []byte) {
   235  	i.dir = -1
   236  	i.clearMask()
   237  	i.pointKey, i.pointVal = pointKey, pointValue
   238  	i.pointKeyInterleaved = false
   239  	i.keyspanSeekLT(key)
   240  	return i.interleaveBackward()
   241  }
   242  
   243  // SeekGE implements (base.InternalIterator).SeekGE.
   244  //
   245  // If there exists a span with a start key ≤ the first matching point key,
   246  // SeekGE will return a synthetic span marker key for the span. If this span's
   247  // start key is less than key, the returned marker will be truncated to key.
   248  // Note that this search-key truncation of the marker's key is not applied to
   249  // the span returned by Span.
   250  //
   251  // NB: In accordance with the base.InternalIterator contract:
   252  //
   253  //	i.lower ≤ key
   254  func (i *InterleavingIter) SeekGE(key []byte, flags base.SeekGEFlags) (*base.InternalKey, []byte) {
   255  	i.clearMask()
   256  	i.disablePrefixMode()
   257  	i.pointKey, i.pointVal = i.pointIter.SeekGE(key, flags)
   258  	i.pointKeyInterleaved = false
   259  
   260  	// We need to seek the keyspan iterator too. If the keyspan iterator was
   261  	// already positioned at a span, we might be able to avoid the seek if the
   262  	// seek key falls within the existing span's bounds.
   263  	if i.span != nil && i.cmp(key, i.span.End) < 0 && i.cmp(key, i.span.Start) >= 0 {
   264  		// We're seeking within the existing span's bounds. We still might need
   265  		// truncate the span to the iterator's bounds.
   266  		i.checkForwardBound(nil /* prefix */)
   267  		i.savedKeyspan()
   268  	} else {
   269  		i.keyspanSeekGE(key, nil /* prefix */)
   270  	}
   271  
   272  	i.dir = +1
   273  	return i.interleaveForward(key, nil /* prefix */)
   274  }
   275  
   276  // SeekPrefixGE implements (base.InternalIterator).SeekPrefixGE.
   277  //
   278  // If there exists a span with a start key ≤ the first matching point key,
   279  // SeekPrefixGE will return a synthetic span marker key for the span. If this
   280  // span's start key is less than key, the returned marker will be truncated to
   281  // key. Note that this search-key truncation of the marker's key is not applied
   282  // to the span returned by Span.
   283  //
   284  // NB: In accordance with the base.InternalIterator contract:
   285  //
   286  //	i.lower ≤ key
   287  func (i *InterleavingIter) SeekPrefixGE(
   288  	prefix, key []byte, flags base.SeekGEFlags,
   289  ) (*base.InternalKey, []byte) {
   290  	i.clearMask()
   291  	i.pointKey, i.pointVal = i.pointIter.SeekPrefixGE(prefix, key, flags)
   292  	i.pointKeyInterleaved = false
   293  	i.prefix = true
   294  
   295  	// We need to seek the keyspan iterator too. If the keyspan iterator was
   296  	// already positioned at a span, we might be able to avoid the seek if the
   297  	// entire seek prefix key falls within the existing span's bounds.
   298  	//
   299  	// During a SeekPrefixGE, Pebble defragments range keys within the bounds of
   300  	// the prefix. For example, a SeekPrefixGE('c', 'c@8') must defragment the
   301  	// any overlapping range keys within the bounds of [c,c\00).
   302  	//
   303  	// If range keys are fragmented within a prefix (eg, because a version
   304  	// within a prefix was chosen as an sstable boundary), then it's possible
   305  	// the seek key falls into the current i.span, but the current i.span does
   306  	// not wholly cover the seek prefix.
   307  	//
   308  	// For example, a SeekPrefixGE('d@5') may only defragment a range key to
   309  	// the bounds of [c@2,e). A subsequent SeekPrefixGE('c@0') must re-seek the
   310  	// keyspan iterator, because although 'c@0' is contained within [c@2,e), the
   311  	// full span of the prefix is not.
   312  	//
   313  	// Similarly, a SeekPrefixGE('a@3') may only defragment a range key to the
   314  	// bounds [a,c@8). A subsequent SeekPrefixGE('c@10') must re-seek the
   315  	// keyspan iterator, because although 'c@10' is contained within [a,c@8),
   316  	// the full span of the prefix is not.
   317  	seekKeyspanIter := true
   318  	if i.span != nil && i.cmp(prefix, i.span.Start) >= 0 {
   319  		if ei := i.comparer.Split(i.span.End); i.cmp(prefix, i.span.End[:ei]) < 0 {
   320  			// We're seeking within the existing span's bounds. We still might need
   321  			// truncate the span to the iterator's bounds.
   322  			i.checkForwardBound(prefix)
   323  			i.savedKeyspan()
   324  			seekKeyspanIter = false
   325  		}
   326  	}
   327  	if seekKeyspanIter {
   328  		i.keyspanSeekGE(key, prefix)
   329  	}
   330  
   331  	i.dir = +1
   332  	return i.interleaveForward(key, prefix)
   333  }
   334  
   335  // SeekLT implements (base.InternalIterator).SeekLT.
   336  func (i *InterleavingIter) SeekLT(key []byte, flags base.SeekLTFlags) (*base.InternalKey, []byte) {
   337  	i.clearMask()
   338  	i.disablePrefixMode()
   339  	i.pointKey, i.pointVal = i.pointIter.SeekLT(key, flags)
   340  	i.pointKeyInterleaved = false
   341  
   342  	// We need to seek the keyspan iterator too. If the keyspan iterator was
   343  	// already positioned at a span, we might be able to avoid the seek if the
   344  	// seek key falls within the existing span's bounds.
   345  	if i.span != nil && i.cmp(key, i.span.Start) > 0 && i.cmp(key, i.span.End) < 0 {
   346  		// We're seeking within the existing span's bounds. We still might need
   347  		// truncate the span to the iterator's bounds.
   348  		i.checkBackwardBound()
   349  		// The span's start key is still not guaranteed to be less than key,
   350  		// because of the bounds enforcement. Consider the following example:
   351  		//
   352  		// Bounds are set to [d,e). The user performs a SeekLT(d). The
   353  		// FragmentIterator.SeekLT lands on a span [b,f). This span has a start
   354  		// key less than d, as expected. Above, checkBackwardBound truncates the
   355  		// span to match the iterator's current bounds, modifying the span to
   356  		// [d,e), which does not overlap the search space of [-∞, d).
   357  		//
   358  		// This problem is a consequence of the SeekLT's exclusive search key
   359  		// and the fact that we don't perform bounds truncation at every leaf
   360  		// iterator.
   361  		if i.span != nil && i.truncated && i.cmp(i.truncatedSpan.Start, key) >= 0 {
   362  			i.span = nil
   363  		}
   364  		i.savedKeyspan()
   365  	} else {
   366  		i.keyspanSeekLT(key)
   367  	}
   368  
   369  	i.dir = -1
   370  	return i.interleaveBackward()
   371  }
   372  
   373  // First implements (base.InternalIterator).First.
   374  func (i *InterleavingIter) First() (*base.InternalKey, []byte) {
   375  	i.clearMask()
   376  	i.disablePrefixMode()
   377  	i.pointKey, i.pointVal = i.pointIter.First()
   378  	i.pointKeyInterleaved = false
   379  	i.span = i.keyspanIter.First()
   380  	i.checkForwardBound(nil /* prefix */)
   381  	i.savedKeyspan()
   382  	i.dir = +1
   383  	return i.interleaveForward(i.lower, nil /* prefix */)
   384  }
   385  
   386  // Last implements (base.InternalIterator).Last.
   387  func (i *InterleavingIter) Last() (*base.InternalKey, []byte) {
   388  	i.clearMask()
   389  	i.disablePrefixMode()
   390  	i.pointKey, i.pointVal = i.pointIter.Last()
   391  	i.pointKeyInterleaved = false
   392  	i.span = i.keyspanIter.Last()
   393  	i.checkBackwardBound()
   394  	i.savedKeyspan()
   395  	i.dir = -1
   396  	return i.interleaveBackward()
   397  }
   398  
   399  // Next implements (base.InternalIterator).Next.
   400  func (i *InterleavingIter) Next() (*base.InternalKey, []byte) {
   401  	if i.dir == -1 {
   402  		// Switching directions.
   403  		i.dir = +1
   404  
   405  		if i.mask != nil {
   406  			// Clear the mask while we reposition the point iterator. While
   407  			// switching directions, we may move the point iterator outside of
   408  			// i.span's bounds.
   409  			i.clearMask()
   410  		}
   411  
   412  		// The existing point key (denoted below with *) is either the last
   413  		// key we returned (the current iterator position):
   414  		//   points:    x     (y*)    z
   415  		// or the upcoming point key in the backward direction if we just
   416  		// returned a span start boundary key:
   417  		//   points:    x*            z
   418  		//    spans:        ([y-?))
   419  		// direction. Either way, we must move to the next point key.
   420  		switch {
   421  		case i.pointKey == nil && i.lower == nil:
   422  			i.pointKey, i.pointVal = i.pointIter.First()
   423  		case i.pointKey == nil && i.lower != nil:
   424  			i.pointKey, i.pointVal = i.pointIter.SeekGE(i.lower, base.SeekGEFlagsNone)
   425  		default:
   426  			i.pointKey, i.pointVal = i.pointIter.Next()
   427  		}
   428  		i.pointKeyInterleaved = false
   429  
   430  		if i.span == nil {
   431  			// There was no span in the reverse direction, but there may be
   432  			// a span in the forward direction.
   433  			i.span = i.keyspanIter.Next()
   434  			i.checkForwardBound(nil /* prefix */)
   435  			i.savedKeyspan()
   436  		} else {
   437  			// Regardless of the current iterator state, we mark any existing
   438  			// span as interleaved when switching to forward iteration,
   439  			// justified below.
   440  			//
   441  			// If the point key is the last key returned:
   442  			//   pointIter   :         ... (y)   z ...
   443  			//   keyspanIter : ... ([x -               )) ...
   444  			//                              ^
   445  			// The span's start key must be ≤ the point key, otherwise we'd have
   446  			// interleaved the span's start key. From a forward-iteration
   447  			// perspective, the span's start key is in the past and should be
   448  			// considered already-interleaved.
   449  			//
   450  			// If the span start boundary key is the last key returned:
   451  			//   pointIter   : ... (x)       z ...
   452  			//   keyspanIter :     ... ([y -        )) ...
   453  			//                           ^
   454  			// i.span.Start is the key we last returned during reverse
   455  			// iteration. From the perspective of forward-iteration, its start
   456  			// key was just visited.
   457  			i.keyspanInterleaved = true
   458  		}
   459  	}
   460  
   461  	// Refresh the point key if the current point key has already been
   462  	// interleaved.
   463  	if i.pointKeyInterleaved {
   464  		i.pointKey, i.pointVal = i.pointIter.Next()
   465  		i.pointKeyInterleaved = false
   466  	}
   467  	// If we already interleaved the current span start key, and the point key
   468  	// is ≥ the span's end key, move to the next span.
   469  	if i.keyspanInterleaved && i.pointKey != nil && i.span != nil &&
   470  		i.cmp(i.pointKey.UserKey, i.span.End) >= 0 {
   471  		i.span = i.keyspanIter.Next()
   472  		i.checkForwardBound(nil /* prefix */)
   473  		i.savedKeyspan()
   474  	}
   475  	return i.interleaveForward(i.lower, nil /* prefix */)
   476  }
   477  
   478  // Prev implements (base.InternalIterator).Prev.
   479  func (i *InterleavingIter) Prev() (*base.InternalKey, []byte) {
   480  	if i.dir == +1 {
   481  		// Switching directions.
   482  		i.dir = -1
   483  
   484  		if i.mask != nil {
   485  			// Clear the mask while we reposition the point iterator. While
   486  			// switching directions, we may move the point iterator outside of
   487  			// i.span's bounds.
   488  			i.clearMask()
   489  		}
   490  
   491  		if i.keyspanInterleaved {
   492  			// The current span's start key has already been interleaved in the
   493  			// forward direction. The start key may have been interleaved a
   494  			// while ago, or it might've been interleaved at the current
   495  			// iterator position. If it was interleaved a while ago, the current
   496  			// span is still relevant and we should not move the keyspan
   497  			// iterator.
   498  			//
   499  			// If it was just interleaved at the current iterator position, the
   500  			// span start was the last key returned to the user. We should
   501  			// prev past it so we don't return it again, with an exception.
   502  			// Consider span [a, z) and this sequence of iterator calls:
   503  			//
   504  			//   SeekGE('c') = c.RANGEKEYSET#72057594037927935
   505  			//   Prev()      = a.RANGEKEYSET#72057594037927935
   506  			//
   507  			// If the current span's start key was last surfaced truncated due
   508  			// to a SeekGE or SeekPrefixGE call, then it's still relevant in the
   509  			// reverse direction with an untruncated start key.
   510  			//
   511  			// We can determine whether the last key returned was a point key by
   512  			// checking i.pointKeyInterleaved, because every Next/Prev will
   513  			// advance the point iterator and reset pointKeyInterleaved if it
   514  			// was.
   515  			if i.pointKeyInterleaved || i.spanMarkerTruncated {
   516  				// The last returned key was a point key, OR a truncated span
   517  				// marker key. Don't move, but re-save the span because it
   518  				// should no longer be considered truncated or interleaved.
   519  				i.savedKeyspan()
   520  			} else {
   521  				// The last returned key is this key's start boundary, so Prev
   522  				// past it so we don't return it again.
   523  				i.span = i.keyspanIter.Prev()
   524  				i.checkBackwardBound()
   525  				i.savedKeyspan()
   526  			}
   527  		} else {
   528  			// If the current span's start key has not been interleaved, then
   529  			// the span's start key is greater than the current iterator
   530  			// position (denoted in parenthesis), and the current span's start
   531  			// key is ahead of our iterator position. Move it to the previous
   532  			// span:
   533  			//  points:    (x*)
   534  			//    span:          [y-z)*
   535  			i.span = i.keyspanIter.Prev()
   536  			i.checkBackwardBound()
   537  			i.savedKeyspan()
   538  		}
   539  
   540  		// The existing point key (denoted below with *) is either the last
   541  		// key we returned (the current iterator position):
   542  		//   points:    x     (y*)    z
   543  		// or the upcoming point key in the forward direction if we just
   544  		// returned a span start boundary key :
   545  		//   points:    x             z*
   546  		//    spans:        ([y-?))
   547  		// direction. Either way, we must move the point iterator backwards.
   548  		switch {
   549  		case i.pointKey == nil && i.upper == nil:
   550  			i.pointKey, i.pointVal = i.pointIter.Last()
   551  		case i.pointKey == nil && i.upper != nil:
   552  			i.pointKey, i.pointVal = i.pointIter.SeekLT(i.upper, base.SeekLTFlagsNone)
   553  		default:
   554  			i.pointKey, i.pointVal = i.pointIter.Prev()
   555  		}
   556  		i.pointKeyInterleaved = false
   557  	}
   558  
   559  	// Refresh the point key if we just returned the current point key.
   560  	if i.pointKeyInterleaved {
   561  		i.pointKey, i.pointVal = i.pointIter.Prev()
   562  		i.pointKeyInterleaved = false
   563  	}
   564  	// Refresh the span if we just returned the span's start boundary key.
   565  	if i.keyspanInterleaved {
   566  		i.span = i.keyspanIter.Prev()
   567  		i.checkBackwardBound()
   568  		i.savedKeyspan()
   569  	}
   570  	return i.interleaveBackward()
   571  }
   572  
   573  func (i *InterleavingIter) interleaveForward(
   574  	lowerBound []byte, prefix []byte,
   575  ) (*base.InternalKey, []byte) {
   576  	// This loop determines whether a point key or a span marker key should be
   577  	// interleaved on each iteration. If masking is disabled and the span is
   578  	// nonempty, this loop executes for exactly one iteration. If masking is
   579  	// enabled and a masked key is determined to be interleaved next, this loop
   580  	// continues until the interleaved key is unmasked. If a span's start key
   581  	// should be interleaved next, but the span is empty, the loop continues to
   582  	// the next key.
   583  	for {
   584  		// Check invariants.
   585  		if invariants.Enabled {
   586  			// INVARIANT: !pointKeyInterleaved
   587  			if i.pointKeyInterleaved {
   588  				panic("bitalostable: invariant violation: point key interleaved")
   589  			}
   590  			switch {
   591  			case i.span == nil:
   592  			case i.pointKey == nil:
   593  			default:
   594  				// INVARIANT: !keyspanInterleaved || pointKey < span.End
   595  				// The caller is responsible for advancing this span if it's already
   596  				// been interleaved and the span ends before the point key.
   597  				// Absolute positioning methods will never have already interleaved
   598  				// the span's start key, so only Next needs to handle the case where
   599  				// pointKey >= span.End.
   600  				if i.keyspanInterleaved && i.cmp(i.pointKey.UserKey, i.span.End) >= 0 {
   601  					panic("bitalostable: invariant violation: span interleaved, but point key >= span end")
   602  				}
   603  			}
   604  		}
   605  
   606  		// Interleave.
   607  		switch {
   608  		case i.span == nil:
   609  			// If we're out of spans, just return the point key.
   610  			return i.yieldPointKey(false /* covered */)
   611  		case i.pointKey == nil:
   612  			if i.pointKeyInterleaved {
   613  				panic("bitalostable: invariant violation: point key already interleaved")
   614  			}
   615  			// If we're out of point keys, we need to return a span marker. If
   616  			// the current span has already been interleaved, advance it. Since
   617  			// there are no more point keys, we don't need to worry about
   618  			// advancing past the current point key.
   619  			if i.keyspanInterleaved {
   620  				i.span = i.keyspanIter.Next()
   621  				i.checkForwardBound(prefix)
   622  				i.savedKeyspan()
   623  				if i.span == nil {
   624  					return i.yieldNil()
   625  				}
   626  			}
   627  			if i.span.Empty() {
   628  				i.keyspanInterleaved = true
   629  				continue
   630  			}
   631  			return i.yieldSyntheticSpanMarker(lowerBound)
   632  		default:
   633  			if i.cmp(i.pointKey.UserKey, i.startKey()) >= 0 {
   634  				// The span start key lies before the point key. If we haven't
   635  				// interleaved it, we should.
   636  				if !i.keyspanInterleaved {
   637  					if i.span.Empty() {
   638  						if i.pointKey != nil && i.cmp(i.pointKey.UserKey, i.span.End) >= 0 {
   639  							// Advance the keyspan iterator, as just flipping
   640  							// keyspanInterleaved would likely trip up the invariant check
   641  							// above.
   642  							i.span = i.keyspanIter.Next()
   643  							i.checkForwardBound(prefix)
   644  							i.savedKeyspan()
   645  						} else {
   646  							i.keyspanInterleaved = true
   647  						}
   648  						continue
   649  					}
   650  					return i.yieldSyntheticSpanMarker(lowerBound)
   651  				}
   652  
   653  				// Otherwise, the span's start key is already interleaved and we
   654  				// need to return the point key. The current span necessarily
   655  				// must cover the point key:
   656  				//
   657  				// Since the span's start is less than or equal to the point
   658  				// key, the only way for this span to not cover the point would
   659  				// be if the span's end is less than or equal to the point.
   660  				// (For example span = [a, b), point key = c).
   661  				//
   662  				// However, the invariant at the beginning of the function
   663  				// guarantees that if:
   664  				//  * we have both a point key and a span
   665  				//  * and the span has already been interleaved
   666  				// => then the point key must be less than the span's end, and
   667  				//    the point key must be covered by the current span.
   668  
   669  				// The span covers the point key. If a SkipPoint hook is
   670  				// configured, ask it if we should skip this point key.
   671  				//
   672  				// But first, we may need to update the mask to the current span
   673  				// if we have stepped outside of the span last saved as a mask,
   674  				// so that the decision to skip is made with the correct
   675  				// knowledge of the covering span.
   676  				i.maybeUpdateMask(true /*covered */)
   677  
   678  				if i.mask != nil && i.mask.SkipPoint(i.pointKey.UserKey) {
   679  					i.pointKey, i.pointVal = i.pointIter.Next()
   680  					// We may have just invalidated the invariant that
   681  					// ensures the span's End is > the point key, so
   682  					// reestablish it before the next iteration.
   683  					if i.pointKey != nil && i.cmp(i.pointKey.UserKey, i.span.End) >= 0 {
   684  						i.span = i.keyspanIter.Next()
   685  						i.checkForwardBound(prefix)
   686  						i.savedKeyspan()
   687  					}
   688  					continue
   689  				}
   690  
   691  				// Point key is unmasked but covered.
   692  				return i.yieldPointKey(true /* covered */)
   693  			}
   694  			return i.yieldPointKey(false /* covered */)
   695  		}
   696  	}
   697  }
   698  
   699  func (i *InterleavingIter) interleaveBackward() (*base.InternalKey, []byte) {
   700  	// This loop determines whether a point key or a span's start key should be
   701  	// interleaved on each iteration. If masking is disabled and the span is
   702  	// nonempty, this loop executes for exactly one iteration. If masking is
   703  	// enabled and a masked key is determined to be interleaved next, this loop
   704  	// continues until the interleaved key is unmasked. If a span's start key
   705  	// should be interleaved next, but the span is empty, the loop continues to
   706  	// the next key.
   707  	for {
   708  		// Check invariants.
   709  		if invariants.Enabled {
   710  			// INVARIANT: !pointKeyInterleaved
   711  			if i.pointKeyInterleaved {
   712  				panic("bitalostable: invariant violation: point key interleaved")
   713  			}
   714  		}
   715  
   716  		// Interleave.
   717  		switch {
   718  		case i.span == nil:
   719  			// If we're out of spans, just return the point key.
   720  			return i.yieldPointKey(false /* covered */)
   721  		case i.pointKey == nil:
   722  			// If we're out of point keys, we need to return a span marker.
   723  			if i.span.Empty() {
   724  				i.span = i.keyspanIter.Prev()
   725  				i.checkBackwardBound()
   726  				i.savedKeyspan()
   727  				continue
   728  			}
   729  			return i.yieldSyntheticSpanMarker(i.lower)
   730  		default:
   731  			// If the span's start key is greater than the point key, return a
   732  			// marker for the span.
   733  			if i.cmp(i.startKey(), i.pointKey.UserKey) > 0 {
   734  				if i.span.Empty() {
   735  					i.span = i.keyspanIter.Prev()
   736  					i.checkBackwardBound()
   737  					i.savedKeyspan()
   738  					continue
   739  				}
   740  				return i.yieldSyntheticSpanMarker(i.lower)
   741  			}
   742  			// We have a span but it has not been interleaved and begins at a
   743  			// key equal to or before the current point key. The point key
   744  			// should be interleaved next, if it's not masked.
   745  			if i.cmp(i.pointKey.UserKey, i.span.End) < 0 {
   746  				// The span covers the point key. The point key might be masked
   747  				// too if masking is enabled.
   748  				//
   749  				// The span may have changed since the last time we updated the
   750  				// mask. Consider the following range-key masking scenario:
   751  				//
   752  				//     |--------------) [b,d)@5
   753  				//            . c@4          . e@9
   754  				//
   755  				// During reverse iteration when we step from e@9 to c@4, we
   756  				// enter the span [b,d)@5. Since end boundaries are not
   757  				// interleaved, the mask hasn't been updated with the span
   758  				// [b,d)@5 yet.  We must update the mask before calling
   759  				// SkipPoint(c@4) to maintain the SpanMask contract and give the
   760  				// mask implementation an opportunity to build the state
   761  				// necessary to be able to determine whether [b,d)@5 masks c@4.
   762  				i.maybeUpdateMask(true /* covered */)
   763  
   764  				// The span covers the point key. If a SkipPoint hook is
   765  				// configured, ask it if we should skip this point key.
   766  				if i.mask != nil && i.mask.SkipPoint(i.pointKey.UserKey) {
   767  					i.pointKey, i.pointVal = i.pointIter.Prev()
   768  					continue
   769  				}
   770  
   771  				// Point key is unmasked but covered.
   772  				return i.yieldPointKey(true /* covered */)
   773  			}
   774  			return i.yieldPointKey(false /* covered */)
   775  		}
   776  	}
   777  }
   778  
   779  // keyspanSeekGE seeks the keyspan iterator to the first span covering k ≥ key.
   780  // Note that this differs from the FragmentIterator.SeekGE semantics, which
   781  // seek to the first span with a start key ≥ key.
   782  func (i *InterleavingIter) keyspanSeekGE(key []byte, prefix []byte) {
   783  	// Seek using SeekLT to look for a span that starts before key, with an end
   784  	// boundary extending beyond key.
   785  	i.span = i.keyspanIter.SeekLT(key)
   786  	if i.span == nil || i.cmp(i.span.End, key) <= 0 {
   787  		// The iterator is exhausted in the reverse direction, or the span we
   788  		// found ends before key. Next to the first key with a start ≥ key.
   789  		i.span = i.keyspanIter.Next()
   790  	}
   791  	i.checkForwardBound(prefix)
   792  	i.savedKeyspan()
   793  }
   794  
   795  // keyspanSeekLT seeks the keyspan iterator to the last span covering k < key.
   796  // Note that this differs from the FragmentIterator.SeekLT semantics, which
   797  // seek to the last span with a start key < key.
   798  func (i *InterleavingIter) keyspanSeekLT(key []byte) {
   799  	i.span = i.keyspanIter.SeekLT(key)
   800  	i.checkBackwardBound()
   801  	// The current span's start key is not guaranteed to be less than key,
   802  	// because of the bounds enforcement. Consider the following example:
   803  	//
   804  	// Bounds are set to [d,e). The user performs a SeekLT(d). The
   805  	// FragmentIterator.SeekLT lands on a span [b,f). This span has a start key
   806  	// less than d, as expected. Above, checkBackwardBound truncates the span to
   807  	// match the iterator's current bounds, modifying the span to [d,e), which
   808  	// does not overlap the search space of [-∞, d).
   809  	//
   810  	// This problem is a consequence of the SeekLT's exclusive search key and
   811  	// the fact that we don't perform bounds truncation at every leaf iterator.
   812  	if i.span != nil && i.truncated && i.cmp(i.truncatedSpan.Start, key) >= 0 {
   813  		i.span = nil
   814  	}
   815  	i.savedKeyspan()
   816  }
   817  
   818  func (i *InterleavingIter) checkForwardBound(prefix []byte) {
   819  	i.truncated = false
   820  	i.truncatedSpan = Span{}
   821  	if i.span == nil {
   822  		return
   823  	}
   824  	// Check the upper bound if we have one.
   825  	if i.upper != nil && i.cmp(i.span.Start, i.upper) >= 0 {
   826  		i.span = nil
   827  		return
   828  	}
   829  
   830  	// TODO(jackson): The key comparisons below truncate bounds whenever the
   831  	// keyspan iterator is repositioned. We could perform this lazily, and do it
   832  	// the first time the user actually asks for this span's bounds in
   833  	// SpanBounds. This would reduce work in the case where there's no span
   834  	// covering the point and the keyspan iterator is non-empty.
   835  
   836  	// NB: These truncations don't require setting `keyspanMarkerTruncated`:
   837  	// That flag only applies to truncated span marker keys.
   838  	if i.lower != nil && i.cmp(i.span.Start, i.lower) < 0 {
   839  		i.truncated = true
   840  		i.truncatedSpan = *i.span
   841  		i.truncatedSpan.Start = i.lower
   842  	}
   843  	if i.upper != nil && i.cmp(i.upper, i.span.End) < 0 {
   844  		if !i.truncated {
   845  			i.truncated = true
   846  			i.truncatedSpan = *i.span
   847  		}
   848  		i.truncatedSpan.End = i.upper
   849  	}
   850  	// If this is a part of a SeekPrefixGE call, we may also need to truncate to
   851  	// the prefix's bounds.
   852  	if prefix != nil {
   853  		if !i.truncated {
   854  			i.truncated = true
   855  			i.truncatedSpan = *i.span
   856  		}
   857  		if i.cmp(prefix, i.truncatedSpan.Start) > 0 {
   858  			i.truncatedSpan.Start = prefix
   859  		}
   860  		i.nextPrefixBuf = i.comparer.ImmediateSuccessor(i.nextPrefixBuf[:0], prefix)
   861  		if i.truncated && i.cmp(i.nextPrefixBuf, i.truncatedSpan.End) < 0 {
   862  			i.truncatedSpan.End = i.nextPrefixBuf
   863  		}
   864  	}
   865  
   866  	if i.truncated && i.comparer.Equal(i.truncatedSpan.Start, i.truncatedSpan.End) {
   867  		i.span = nil
   868  	}
   869  }
   870  
   871  func (i *InterleavingIter) checkBackwardBound() {
   872  	i.truncated = false
   873  	i.truncatedSpan = Span{}
   874  	if i.span == nil {
   875  		return
   876  	}
   877  	// Check the lower bound if we have one.
   878  	if i.lower != nil && i.cmp(i.span.End, i.lower) <= 0 {
   879  		i.span = nil
   880  		return
   881  	}
   882  
   883  	// TODO(jackson): The key comparisons below truncate bounds whenever the
   884  	// keyspan iterator is repositioned. We could perform this lazily, and do it
   885  	// the first time the user actually asks for this span's bounds in
   886  	// SpanBounds. This would reduce work in the case where there's no span
   887  	// covering the point and the keyspan iterator is non-empty.
   888  
   889  	// NB: These truncations don't require setting `keyspanMarkerTruncated`:
   890  	// That flag only applies to truncated span marker keys.
   891  	if i.lower != nil && i.cmp(i.span.Start, i.lower) < 0 {
   892  		i.truncated = true
   893  		i.truncatedSpan = *i.span
   894  		i.truncatedSpan.Start = i.lower
   895  	}
   896  	if i.upper != nil && i.cmp(i.upper, i.span.End) < 0 {
   897  		if !i.truncated {
   898  			i.truncated = true
   899  			i.truncatedSpan = *i.span
   900  		}
   901  		i.truncatedSpan.End = i.upper
   902  	}
   903  	if i.truncated && i.comparer.Equal(i.truncatedSpan.Start, i.truncatedSpan.End) {
   904  		i.span = nil
   905  	}
   906  }
   907  
   908  func (i *InterleavingIter) yieldNil() (*base.InternalKey, []byte) {
   909  	i.spanCoversKey = false
   910  	i.clearMask()
   911  	return i.verify(nil, nil)
   912  }
   913  
   914  func (i *InterleavingIter) yieldPointKey(covered bool) (*base.InternalKey, []byte) {
   915  	i.pointKeyInterleaved = true
   916  	i.spanCoversKey = covered
   917  	i.maybeUpdateMask(covered)
   918  	return i.verify(i.pointKey, i.pointVal)
   919  }
   920  
   921  func (i *InterleavingIter) yieldSyntheticSpanMarker(lowerBound []byte) (*base.InternalKey, []byte) {
   922  	i.spanMarker.UserKey = i.startKey()
   923  	i.spanMarker.Trailer = base.MakeTrailer(base.InternalKeySeqNumMax, i.span.Keys[0].Kind())
   924  	i.keyspanInterleaved = true
   925  	i.spanCoversKey = true
   926  
   927  	// Truncate the key we return to our lower bound if we have one. Note that
   928  	// we use the lowerBound function parameter, not i.lower. The lowerBound
   929  	// argument is guaranteed to be ≥ i.lower. It may be equal to the SetBounds
   930  	// lower bound, or it could come from a SeekGE or SeekPrefixGE search key.
   931  	if lowerBound != nil && i.cmp(lowerBound, i.startKey()) > 0 {
   932  		// Truncating to the lower bound may violate the upper bound if
   933  		// lowerBound == i.upper. For example, a SeekGE(k) uses k as a lower
   934  		// bound for truncating a span. The span a-z will be truncated to [k,
   935  		// z). If i.upper == k, we'd mistakenly try to return a span [k, k), an
   936  		// invariant violation.
   937  		if i.comparer.Equal(lowerBound, i.upper) {
   938  			return i.yieldNil()
   939  		}
   940  
   941  		// If the lowerBound argument came from a SeekGE or SeekPrefixGE
   942  		// call, and it may be backed by a user-provided byte slice that is not
   943  		// guaranteed to be stable.
   944  		//
   945  		// If the lowerBound argument is the lower bound set by SetBounds,
   946  		// Pebble owns the slice's memory. However, consider two successive
   947  		// calls to SetBounds(). The second may overwrite the lower bound.
   948  		// Although the external contract requires a seek after a SetBounds,
   949  		// Pebble's tests don't always. For this reason and to simplify
   950  		// reasoning around lifetimes, always copy the bound into keyBuf when
   951  		// truncating.
   952  		i.keyBuf = append(i.keyBuf[:0], lowerBound...)
   953  		i.spanMarker.UserKey = i.keyBuf
   954  		i.spanMarkerTruncated = true
   955  	}
   956  	i.maybeUpdateMask(true /* covered */)
   957  	return i.verify(&i.spanMarker, nil)
   958  }
   959  
   960  func (i *InterleavingIter) disablePrefixMode() {
   961  	if i.prefix {
   962  		i.prefix = false
   963  		// Clear the existing span. It may not hold the true end bound of the
   964  		// underlying span.
   965  		i.span = nil
   966  	}
   967  }
   968  
   969  func (i *InterleavingIter) verify(k *base.InternalKey, v []byte) (*base.InternalKey, []byte) {
   970  	// Wrap the entire function body in the invariants build tag, so that
   971  	// production builds elide this entire function.
   972  	if invariants.Enabled {
   973  		switch {
   974  		case k != nil && !i.keyspanInterleaved && !i.pointKeyInterleaved:
   975  			panic("bitalostable: invariant violation: both keys marked as noninterleaved")
   976  		case i.dir == -1 && k != nil && i.keyspanInterleaved == i.pointKeyInterleaved:
   977  			// During reverse iteration, if we're returning a key, either the span's
   978  			// start key must have been interleaved OR the current point key value
   979  			// is being returned, not both.
   980  			//
   981  			// This invariant holds because in reverse iteration the start key of the
   982  			// span behaves like a point. Once the start key is interleaved, we move
   983  			// the keyspan iterator to the previous span.
   984  			panic(fmt.Sprintf("bitalostable: invariant violation: interleaving (point %t, span %t)",
   985  				i.pointKeyInterleaved, i.keyspanInterleaved))
   986  		case i.dir == -1 && i.spanMarkerTruncated:
   987  			panic("bitalostable: invariant violation: truncated span key in reverse iteration")
   988  		case k != nil && i.lower != nil && i.cmp(k.UserKey, i.lower) < 0:
   989  			panic("bitalostable: invariant violation: key < lower bound")
   990  		case k != nil && i.upper != nil && i.cmp(k.UserKey, i.upper) >= 0:
   991  			panic("bitalostable: invariant violation: key ≥ upper bound")
   992  		case i.span != nil && k != nil && i.mask != nil && i.pointKeyInterleaved &&
   993  			i.cmp(k.UserKey, i.span.Start) >= 0 && i.cmp(k.UserKey, i.span.End) < 0 && i.mask.SkipPoint(k.UserKey):
   994  			panic("bitalostable: invariant violation: point key eligible for skipping returned")
   995  		}
   996  	}
   997  	return k, v
   998  }
   999  
  1000  func (i *InterleavingIter) savedKeyspan() {
  1001  	i.keyspanInterleaved = false
  1002  	i.spanMarkerTruncated = false
  1003  	i.maskSpanChangedCalled = false
  1004  }
  1005  
  1006  // maybeUpdateMask updates the current mask, if a mask is configured and
  1007  // the mask hasn't been updated with the current keyspan yet.
  1008  func (i *InterleavingIter) maybeUpdateMask(covered bool) {
  1009  	if i.mask != nil {
  1010  		if !covered || i.span.Empty() {
  1011  			i.clearMask()
  1012  		} else if !i.maskSpanChangedCalled {
  1013  			if i.truncated {
  1014  				i.mask.SpanChanged(&i.truncatedSpan)
  1015  			} else {
  1016  				i.mask.SpanChanged(i.span)
  1017  			}
  1018  			i.maskSpanChangedCalled = true
  1019  		}
  1020  	}
  1021  }
  1022  
  1023  // clearMask clears the current mask, if a mask is configured and no mask should
  1024  // be active.
  1025  func (i *InterleavingIter) clearMask() {
  1026  	if i.mask != nil {
  1027  		i.maskSpanChangedCalled = false
  1028  		i.mask.SpanChanged(nil)
  1029  	}
  1030  }
  1031  
  1032  func (i *InterleavingIter) startKey() []byte {
  1033  	if i.truncated {
  1034  		return i.truncatedSpan.Start
  1035  	}
  1036  	return i.span.Start
  1037  }
  1038  
  1039  // Span returns the span covering the last key returned, if any. A span key is
  1040  // considered to 'cover' a key if the key falls within the span's user key
  1041  // bounds. The returned span is owned by the InterleavingIter. The caller is
  1042  // responsible for copying if stability is required.
  1043  //
  1044  // Span will never return an invalid or empty span.
  1045  func (i *InterleavingIter) Span() *Span {
  1046  	if !i.spanCoversKey || i.span.Empty() {
  1047  		return nil
  1048  	} else if i.truncated {
  1049  		return &i.truncatedSpan
  1050  	} else {
  1051  		return i.span
  1052  	}
  1053  }
  1054  
  1055  // SetBounds implements (base.InternalIterator).SetBounds.
  1056  func (i *InterleavingIter) SetBounds(lower, upper []byte) {
  1057  	i.lower, i.upper = lower, upper
  1058  	i.pointIter.SetBounds(lower, upper)
  1059  	i.Invalidate()
  1060  }
  1061  
  1062  // Invalidate invalidates the interleaving iterator's current position, clearing
  1063  // its state. This prevents optimizations such as reusing the current span on
  1064  // seek.
  1065  func (i *InterleavingIter) Invalidate() {
  1066  	i.span = nil
  1067  	i.pointKey = nil
  1068  	i.pointVal = nil
  1069  }
  1070  
  1071  // Error implements (base.InternalIterator).Error.
  1072  func (i *InterleavingIter) Error() error {
  1073  	return firstError(i.pointIter.Error(), i.keyspanIter.Error())
  1074  }
  1075  
  1076  // Close implements (base.InternalIterator).Close.
  1077  func (i *InterleavingIter) Close() error {
  1078  	perr := i.pointIter.Close()
  1079  	rerr := i.keyspanIter.Close()
  1080  	return firstError(perr, rerr)
  1081  }
  1082  
  1083  // String implements (base.InternalIterator).String.
  1084  func (i *InterleavingIter) String() string {
  1085  	return fmt.Sprintf("keyspan-interleaving(%q)", i.pointIter.String())
  1086  }
  1087  
  1088  func firstError(err0, err1 error) error {
  1089  	if err0 != nil {
  1090  		return err0
  1091  	}
  1092  	return err1
  1093  }