github.com/pingcap/badger@v1.5.1-0.20230103063557-828f39b09b6d/table/merge_iterator.go (about)

     1  package table
     2  
     3  import (
     4  	"bytes"
     5  
     6  	"github.com/pingcap/badger/y"
     7  )
     8  
     9  // MergeTowIterator is a specialized MergeIterator that only merge tow iterators.
    10  // It is an optimization for compaction.
    11  type MergeIterator struct {
    12  	smaller *mergeIteratorChild
    13  	bigger  *mergeIteratorChild
    14  
    15  	// when the two iterators has the same value, the value in the second iterator is ignored.
    16  	second  y.Iterator
    17  	reverse bool
    18  	sameKey bool
    19  }
    20  
    21  type mergeIteratorChild struct {
    22  	valid bool
    23  	key   y.Key
    24  	iter  y.Iterator
    25  
    26  	// The two iterators are type asserted from `y.Iterator`, used to inline more function calls.
    27  	merge  *MergeIterator
    28  	concat *ConcatIterator
    29  }
    30  
    31  func (child *mergeIteratorChild) setIterator(iter y.Iterator) {
    32  	child.iter = iter
    33  	child.merge, _ = iter.(*MergeIterator)
    34  	child.concat, _ = iter.(*ConcatIterator)
    35  }
    36  
    37  func (child *mergeIteratorChild) reset() {
    38  	if child.merge != nil {
    39  		child.valid = child.merge.smaller.valid
    40  		if child.valid {
    41  			child.key = child.merge.smaller.key
    42  		}
    43  	} else if child.concat != nil {
    44  		child.valid = child.concat.Valid()
    45  		if child.valid {
    46  			child.key = child.concat.Key()
    47  		}
    48  	} else {
    49  		child.valid = child.iter.Valid()
    50  		if child.valid {
    51  			child.key = child.iter.Key()
    52  		}
    53  	}
    54  }
    55  
    56  func (mt *MergeIterator) fix() {
    57  	if !mt.bigger.valid {
    58  		return
    59  	}
    60  	for mt.smaller.valid {
    61  		cmp := bytes.Compare(mt.smaller.key.UserKey, mt.bigger.key.UserKey)
    62  		if cmp == 0 {
    63  			mt.sameKey = true
    64  			if mt.smaller.iter == mt.second {
    65  				mt.swap()
    66  			}
    67  			return
    68  		}
    69  		mt.sameKey = false
    70  		if mt.reverse {
    71  			if cmp < 0 {
    72  				mt.swap()
    73  			}
    74  		} else {
    75  			if cmp > 0 {
    76  				mt.swap()
    77  			}
    78  		}
    79  		return
    80  	}
    81  	mt.swap()
    82  }
    83  
    84  func (mt *MergeIterator) swap() {
    85  	mt.smaller, mt.bigger = mt.bigger, mt.smaller
    86  }
    87  
    88  // Next returns the next element. If it is the same as the current key, ignore it.
    89  func (mt *MergeIterator) Next() {
    90  	if mt.smaller.merge != nil {
    91  		mt.smaller.merge.Next()
    92  	} else if mt.smaller.concat != nil {
    93  		mt.smaller.concat.Next()
    94  	} else {
    95  		mt.smaller.iter.Next()
    96  	}
    97  	mt.smaller.reset()
    98  	if mt.sameKey && mt.bigger.valid {
    99  		if mt.bigger.merge != nil {
   100  			mt.bigger.merge.Next()
   101  		} else if mt.bigger.concat != nil {
   102  			mt.bigger.concat.Next()
   103  		} else {
   104  			mt.bigger.iter.Next()
   105  		}
   106  		mt.bigger.reset()
   107  	}
   108  	mt.fix()
   109  }
   110  
   111  func (mt *MergeIterator) NextVersion() bool {
   112  	if mt.smaller.iter.NextVersion() {
   113  		mt.smaller.reset()
   114  		return true
   115  	}
   116  	if !mt.sameKey {
   117  		return false
   118  	}
   119  	if !mt.bigger.valid {
   120  		return false
   121  	}
   122  	if mt.smaller.key.Version < mt.bigger.key.Version {
   123  		// The smaller is second iterator, the bigger is first iterator.
   124  		// We have swapped already, no more versions.
   125  		return false
   126  	}
   127  	if mt.smaller.key.Version == mt.bigger.key.Version {
   128  		// have duplicated key in the two iterators.
   129  		if mt.bigger.iter.NextVersion() {
   130  			mt.bigger.reset()
   131  			mt.swap()
   132  			return true
   133  		}
   134  		return false
   135  	}
   136  	mt.swap()
   137  	return true
   138  }
   139  
   140  // Rewind seeks to first element (or last element for reverse iterator).
   141  func (mt *MergeIterator) Rewind() {
   142  	mt.smaller.iter.Rewind()
   143  	mt.smaller.reset()
   144  	mt.bigger.iter.Rewind()
   145  	mt.bigger.reset()
   146  	mt.fix()
   147  }
   148  
   149  // Seek brings us to element with key >= given key.
   150  func (mt *MergeIterator) Seek(key []byte) {
   151  	mt.smaller.iter.Seek(key)
   152  	mt.smaller.reset()
   153  	mt.bigger.iter.Seek(key)
   154  	mt.bigger.reset()
   155  	mt.fix()
   156  }
   157  
   158  // Valid returns whether the MergeIterator is at a valid element.
   159  func (mt *MergeIterator) Valid() bool {
   160  	return mt.smaller.valid
   161  }
   162  
   163  // Key returns the key associated with the current iterator
   164  func (mt *MergeIterator) Key() y.Key {
   165  	return mt.smaller.key
   166  }
   167  
   168  // Value returns the value associated with the iterator.
   169  func (mt *MergeIterator) Value() y.ValueStruct {
   170  	return mt.smaller.iter.Value()
   171  }
   172  
   173  func (mt *MergeIterator) FillValue(vs *y.ValueStruct) {
   174  	if mt.smaller.merge != nil {
   175  		mt.smaller.merge.FillValue(vs)
   176  	} else if mt.smaller.concat != nil {
   177  		mt.smaller.concat.FillValue(vs)
   178  	} else {
   179  		mt.smaller.iter.FillValue(vs)
   180  	}
   181  }
   182  
   183  // Close implements y.Iterator.
   184  func (mt *MergeIterator) Close() error {
   185  	smallerErr := mt.smaller.iter.Close()
   186  	biggerErr := mt.bigger.iter.Close()
   187  	if smallerErr != nil {
   188  		return y.Wrapf(smallerErr, "MergeIterator")
   189  	}
   190  	if biggerErr != nil {
   191  		return y.Wrapf(biggerErr, "MergeIterator")
   192  	}
   193  	return nil
   194  }
   195  
   196  // NewMergeIterator creates a merge iterator
   197  func NewMergeIterator(iters []y.Iterator, reverse bool) y.Iterator {
   198  	if len(iters) == 0 {
   199  		return &EmptyIterator{}
   200  	} else if len(iters) == 1 {
   201  		return iters[0]
   202  	} else if len(iters) == 2 {
   203  		mi := &MergeIterator{
   204  			second:  iters[1],
   205  			reverse: reverse,
   206  			smaller: new(mergeIteratorChild),
   207  			bigger:  new(mergeIteratorChild),
   208  		}
   209  		mi.smaller.setIterator(iters[0])
   210  		mi.bigger.setIterator(iters[1])
   211  		return mi
   212  	}
   213  	mid := len(iters) / 2
   214  	return NewMergeIterator([]y.Iterator{NewMergeIterator(iters[:mid], reverse), NewMergeIterator(iters[mid:], reverse)}, reverse)
   215  }
   216  
   217  type EmptyIterator struct{}
   218  
   219  func (e *EmptyIterator) Next() {}
   220  
   221  func (e *EmptyIterator) NextVersion() bool {
   222  	return false
   223  }
   224  
   225  func (e *EmptyIterator) Rewind() {}
   226  
   227  func (e *EmptyIterator) Seek(key []byte) {}
   228  
   229  func (e *EmptyIterator) Key() y.Key {
   230  	return y.Key{}
   231  }
   232  
   233  func (e *EmptyIterator) Value() y.ValueStruct {
   234  	return y.ValueStruct{}
   235  }
   236  
   237  func (e *EmptyIterator) FillValue(vs *y.ValueStruct) {}
   238  
   239  func (e *EmptyIterator) Valid() bool {
   240  	return false
   241  }
   242  
   243  func (e *EmptyIterator) Close() error {
   244  	return nil
   245  }