github.com/zuoyebang/bitalosdb@v1.1.1-0.20240516111551-79a8c4d8ce20/bitpage/merging_iter.go (about)

     1  // Copyright 2021 The Bitalosdb author(hustxrb@163.com) and other contributors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package bitpage
    16  
    17  import (
    18  	"bytes"
    19  	"errors"
    20  	"fmt"
    21  	"runtime/debug"
    22  
    23  	"github.com/zuoyebang/bitalosdb/internal/base"
    24  	"github.com/zuoyebang/bitalosdb/internal/invariants"
    25  	"github.com/zuoyebang/bitalosdb/internal/utils"
    26  )
    27  
    28  type mergingIterLevel struct {
    29  	iter      internalIterator
    30  	iterKey   *internalKey
    31  	iterValue []byte
    32  }
    33  
    34  type mergingIter struct {
    35  	logger base.Logger
    36  	dir    int
    37  	levels []mergingIterLevel
    38  	heap   mergingIterHeap
    39  	err    error
    40  	prefix []byte
    41  	lower  []byte
    42  	upper  []byte
    43  }
    44  
    45  var _ base.InternalIterator = (*mergingIter)(nil)
    46  
    47  func newMergingIter(
    48  	logger base.Logger, cmp base.Compare, iters ...internalIterator,
    49  ) *mergingIter {
    50  	m := &mergingIter{}
    51  	levels := make([]mergingIterLevel, len(iters))
    52  	for i := range levels {
    53  		levels[i].iter = iters[i]
    54  	}
    55  	m.Init(&iterOptions{Logger: logger}, cmp, levels...)
    56  	return m
    57  }
    58  
    59  func (m *mergingIter) Init(
    60  	opts *iterOptions, cmp base.Compare, levels ...mergingIterLevel,
    61  ) {
    62  	m.err = nil
    63  	m.logger = opts.GetLogger()
    64  	if opts != nil {
    65  		m.lower = opts.LowerBound
    66  		m.upper = opts.UpperBound
    67  	}
    68  	m.levels = levels
    69  	m.heap.cmp = cmp
    70  	if cap(m.heap.items) < len(levels) {
    71  		m.heap.items = make([]mergingIterItem, 0, len(levels))
    72  	} else {
    73  		m.heap.items = m.heap.items[:0]
    74  	}
    75  }
    76  
    77  func (m *mergingIter) initHeap() {
    78  	m.heap.items = m.heap.items[:0]
    79  	for i := range m.levels {
    80  		if l := &m.levels[i]; l.iterKey != nil {
    81  			m.heap.items = append(m.heap.items, mergingIterItem{
    82  				index: i,
    83  				key:   *l.iterKey,
    84  				value: l.iterValue,
    85  			})
    86  		} else {
    87  			m.err = utils.FirstError(m.err, l.iter.Error())
    88  			if m.err != nil {
    89  				return
    90  			}
    91  		}
    92  	}
    93  	m.heap.init()
    94  }
    95  
    96  func (m *mergingIter) initMinHeap() {
    97  	m.dir = 1
    98  	m.heap.reverse = false
    99  	m.initHeap()
   100  }
   101  
   102  func (m *mergingIter) initMaxHeap() {
   103  	m.dir = -1
   104  	m.heap.reverse = true
   105  	m.initHeap()
   106  }
   107  
   108  func (m *mergingIter) switchToMinHeap() {
   109  	if m.heap.len() == 0 {
   110  		if m.lower != nil {
   111  			m.SeekGE(m.lower)
   112  		} else {
   113  			m.First()
   114  		}
   115  		return
   116  	}
   117  
   118  	key := m.heap.items[0].key
   119  	cur := &m.levels[m.heap.items[0].index]
   120  
   121  	for i := range m.levels {
   122  		l := &m.levels[i]
   123  		if l == cur {
   124  			continue
   125  		}
   126  
   127  		if l.iterKey == nil {
   128  			if m.lower != nil {
   129  				l.iterKey, l.iterValue = l.iter.SeekGE(m.lower)
   130  			} else {
   131  				l.iterKey, l.iterValue = l.iter.First()
   132  			}
   133  		}
   134  		for ; l.iterKey != nil; l.iterKey, l.iterValue = l.iter.Next() {
   135  			if base.InternalCompare(m.heap.cmp, key, *l.iterKey) < 0 {
   136  				break
   137  			}
   138  		}
   139  	}
   140  
   141  	cur.iterKey, cur.iterValue = cur.iter.Next()
   142  	m.initMinHeap()
   143  }
   144  
   145  func (m *mergingIter) switchToMaxHeap() {
   146  	if m.heap.len() == 0 {
   147  		if m.upper != nil {
   148  			m.SeekLT(m.upper)
   149  		} else {
   150  			m.Last()
   151  		}
   152  		return
   153  	}
   154  
   155  	key := m.heap.items[0].key
   156  	cur := &m.levels[m.heap.items[0].index]
   157  
   158  	for i := range m.levels {
   159  		l := &m.levels[i]
   160  		if l == cur {
   161  			continue
   162  		}
   163  
   164  		if l.iterKey == nil {
   165  			if m.upper != nil {
   166  				l.iterKey, l.iterValue = l.iter.SeekLT(m.upper)
   167  			} else {
   168  				l.iterKey, l.iterValue = l.iter.Last()
   169  			}
   170  		}
   171  		for ; l.iterKey != nil; l.iterKey, l.iterValue = l.iter.Prev() {
   172  			if base.InternalCompare(m.heap.cmp, key, *l.iterKey) > 0 {
   173  				break
   174  			}
   175  		}
   176  	}
   177  
   178  	cur.iterKey, cur.iterValue = cur.iter.Prev()
   179  	m.initMaxHeap()
   180  }
   181  
   182  func (m *mergingIter) nextEntry(item *mergingIterItem) {
   183  	l := &m.levels[item.index]
   184  	if l.iterKey, l.iterValue = l.iter.Next(); l.iterKey != nil {
   185  		item.key, item.value = *l.iterKey, l.iterValue
   186  		if m.heap.len() > 1 {
   187  			m.heap.fix(0)
   188  		}
   189  	} else {
   190  		m.err = l.iter.Error()
   191  		if m.err == nil {
   192  			m.heap.pop()
   193  		}
   194  	}
   195  }
   196  
   197  func (m *mergingIter) findNextEntry() (*internalKey, []byte) {
   198  	for m.heap.len() > 0 && m.err == nil {
   199  		item := &m.heap.items[0]
   200  		return &item.key, item.value
   201  	}
   202  	return nil, nil
   203  }
   204  
   205  func (m *mergingIter) prevEntry(item *mergingIterItem) {
   206  	l := &m.levels[item.index]
   207  	if l.iterKey, l.iterValue = l.iter.Prev(); l.iterKey != nil {
   208  		item.key, item.value = *l.iterKey, l.iterValue
   209  		if m.heap.len() > 1 {
   210  			m.heap.fix(0)
   211  		}
   212  	} else {
   213  		m.err = l.iter.Error()
   214  		if m.err == nil {
   215  			m.heap.pop()
   216  		}
   217  	}
   218  }
   219  
   220  func (m *mergingIter) findPrevEntry() (*internalKey, []byte) {
   221  	for m.heap.len() > 0 && m.err == nil {
   222  		item := &m.heap.items[0]
   223  		return &item.key, item.value
   224  	}
   225  	return nil, nil
   226  }
   227  
   228  func (m *mergingIter) seekGE(key []byte, level int, trySeekUsingNext bool) {
   229  	for ; level < len(m.levels); level++ {
   230  		if invariants.Enabled && m.lower != nil && m.heap.cmp(key, m.lower) < 0 {
   231  			m.logger.Fatalf("mergingIter: lower bound violation: %s < %s\n%s", key, m.lower, debug.Stack())
   232  		}
   233  
   234  		l := &m.levels[level]
   235  		if m.prefix != nil {
   236  			l.iterKey, l.iterValue = l.iter.SeekPrefixGE(m.prefix, key, trySeekUsingNext)
   237  		} else {
   238  			l.iterKey, l.iterValue = l.iter.SeekGE(key)
   239  		}
   240  	}
   241  
   242  	m.initMinHeap()
   243  }
   244  
   245  func (m *mergingIter) String() string {
   246  	return "merging"
   247  }
   248  
   249  func (m *mergingIter) SeekGE(key []byte) (*internalKey, []byte) {
   250  	m.err = nil
   251  	m.prefix = nil
   252  	m.seekGE(key, 0, false)
   253  	return m.findNextEntry()
   254  }
   255  
   256  func (m *mergingIter) SeekPrefixGE(
   257  	prefix, key []byte, trySeekUsingNext bool,
   258  ) (*base.InternalKey, []byte) {
   259  	m.err = nil
   260  	m.prefix = prefix
   261  	m.seekGE(key, 0, trySeekUsingNext)
   262  	return m.findNextEntry()
   263  }
   264  
   265  func (m *mergingIter) seekLT(key []byte, level int) {
   266  	m.prefix = nil
   267  	for ; level < len(m.levels); level++ {
   268  		if invariants.Enabled && m.upper != nil && m.heap.cmp(key, m.upper) > 0 {
   269  			m.logger.Fatalf("mergingIter: upper bound violation: %s > %s\n%s", key, m.upper, debug.Stack())
   270  		}
   271  
   272  		l := &m.levels[level]
   273  		l.iterKey, l.iterValue = l.iter.SeekLT(key)
   274  	}
   275  
   276  	m.initMaxHeap()
   277  }
   278  
   279  func (m *mergingIter) SeekLT(key []byte) (*internalKey, []byte) {
   280  	m.err = nil
   281  	m.prefix = nil
   282  	m.seekLT(key, 0)
   283  	return m.findPrevEntry()
   284  }
   285  
   286  func (m *mergingIter) First() (*internalKey, []byte) {
   287  	m.err = nil
   288  	m.prefix = nil
   289  	m.heap.items = m.heap.items[:0]
   290  	for i := range m.levels {
   291  		l := &m.levels[i]
   292  		l.iterKey, l.iterValue = l.iter.First()
   293  	}
   294  	m.initMinHeap()
   295  	return m.findNextEntry()
   296  }
   297  
   298  func (m *mergingIter) Last() (*internalKey, []byte) {
   299  	m.err = nil
   300  	m.prefix = nil
   301  	for i := range m.levels {
   302  		l := &m.levels[i]
   303  		l.iterKey, l.iterValue = l.iter.Last()
   304  	}
   305  	m.initMaxHeap()
   306  	return m.findPrevEntry()
   307  }
   308  
   309  func (m *mergingIter) Next() (*internalKey, []byte) {
   310  	if m.err != nil {
   311  		return nil, nil
   312  	}
   313  
   314  	if m.dir != 1 {
   315  		m.switchToMinHeap()
   316  		return m.findNextEntry()
   317  	}
   318  
   319  	if m.heap.len() == 0 {
   320  		return nil, nil
   321  	}
   322  
   323  	m.nextEntry(&m.heap.items[0])
   324  	return m.findNextEntry()
   325  }
   326  
   327  func (m *mergingIter) Prev() (*internalKey, []byte) {
   328  	if m.err != nil {
   329  		return nil, nil
   330  	}
   331  
   332  	if m.dir != -1 {
   333  		if m.prefix != nil {
   334  			m.err = errors.New("bitalosdb: unsupported reverse prefix iteration")
   335  			return nil, nil
   336  		}
   337  		m.switchToMaxHeap()
   338  		return m.findPrevEntry()
   339  	}
   340  
   341  	if m.heap.len() == 0 {
   342  		return nil, nil
   343  	}
   344  
   345  	m.prevEntry(&m.heap.items[0])
   346  	return m.findPrevEntry()
   347  }
   348  
   349  func (m *mergingIter) Error() error {
   350  	if m.heap.len() == 0 || m.err != nil {
   351  		return m.err
   352  	}
   353  	return m.levels[m.heap.items[0].index].iter.Error()
   354  }
   355  
   356  func (m *mergingIter) Close() error {
   357  	for i := range m.levels {
   358  		iter := m.levels[i].iter
   359  		if err := iter.Close(); err != nil && m.err == nil {
   360  			m.err = err
   361  		}
   362  	}
   363  	m.levels = nil
   364  	m.heap.items = m.heap.items[:0]
   365  	return m.err
   366  }
   367  
   368  func (m *mergingIter) SetBounds(lower, upper []byte) {
   369  	m.prefix = nil
   370  	m.lower = lower
   371  	m.upper = upper
   372  	for i := range m.levels {
   373  		m.levels[i].iter.SetBounds(lower, upper)
   374  	}
   375  	m.heap.clear()
   376  }
   377  
   378  func (m *mergingIter) DebugString() string {
   379  	var buf bytes.Buffer
   380  	sep := ""
   381  	for m.heap.len() > 0 {
   382  		item := m.heap.pop()
   383  		fmt.Fprintf(&buf, "%s%s", sep, item.key)
   384  		sep = " "
   385  	}
   386  	if m.dir == 1 {
   387  		m.initMinHeap()
   388  	} else {
   389  		m.initMaxHeap()
   390  	}
   391  	return buf.String()
   392  }