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