github.com/matrixorigin/matrixone@v1.2.0/pkg/common/arenaskl/iterator.go (about)

     1  /*
     2   * Copyright 2017 Dgraph Labs, Inc. and Contributors
     3   * Modifications copyright (C) 2017 Andy Kimball and Contributors
     4   * and copyright (C) 2024 MatrixOrigin Inc.
     5   *
     6   * Licensed under the Apache License, Version 2.0 (the "License");
     7   * you may not use this file except in compliance with the License.
     8   * You may obtain a copy of the License at
     9   *
    10   *     http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing, software
    13   * distributed under the License is distributed on an "AS IS" BASIS,
    14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15   * See the License for the specific language governing permissions and
    16   * limitations under the License.
    17   */
    18  
    19  package arenaskl
    20  
    21  import (
    22  	"sync"
    23  )
    24  
    25  type splice struct {
    26  	prev *node
    27  	next *node
    28  }
    29  
    30  func (s *splice) init(prev, next *node) {
    31  	s.prev = prev
    32  	s.next = next
    33  }
    34  
    35  // Iterator is an iterator over the skiplist object. Use Skiplist.NewIter
    36  // to construct an iterator. The current state of the iterator can be cloned by
    37  // simply value copying the struct. All iterator methods are thread-safe.
    38  type Iterator struct {
    39  	list  *Skiplist
    40  	nd    *node
    41  	key   []byte
    42  	lower []byte
    43  	upper []byte
    44  }
    45  
    46  // Iterator implements the base.InternalIterator interface.
    47  // var _ base.InternalIterator = (*Iterator)(nil)
    48  
    49  var iterPool = sync.Pool{
    50  	New: func() interface{} {
    51  		return &Iterator{}
    52  	},
    53  }
    54  
    55  // Close resets the iterator.
    56  func (it *Iterator) Close() error {
    57  	it.list = nil
    58  	it.nd = nil
    59  	it.lower = nil
    60  	it.upper = nil
    61  	iterPool.Put(it)
    62  	return nil
    63  }
    64  
    65  func (it *Iterator) String() string {
    66  	return "memtable"
    67  }
    68  
    69  // Error returns any accumulated error.
    70  func (it *Iterator) Error() error {
    71  	return nil
    72  }
    73  
    74  // SeekGE moves the iterator to the first entry whose key is greater than or
    75  // equal to the given key. Returns the key and value if the iterator is
    76  // pointing at a valid entry, and (nil, nil) otherwise. Note that SeekGE only
    77  // checks the upper bound. It is up to the caller to ensure that key is greater
    78  // than or equal to the lower bound.
    79  func (it *Iterator) SeekGE(key []byte) (bool, []byte, []byte) {
    80  	_, it.nd, _ = it.seekForBaseSplice(key)
    81  	if it.nd == it.list.tail {
    82  		return false, nil, nil
    83  	}
    84  	it.decodeKey()
    85  	if it.upper != nil && it.list.cmp(it.upper, it.key) <= 0 {
    86  		it.nd = it.list.tail
    87  		return false, nil, nil
    88  	}
    89  	return true, it.key, it.value()
    90  }
    91  
    92  // SeekPrefixGE moves the iterator to the first entry whose key is greater than
    93  // or equal to the given key. This method is equivalent to SeekGE and is
    94  // provided so that an arenaskl.Iterator implements the
    95  // internal/base.InternalIterator interface.
    96  func (it *Iterator) SeekPrefixGE(
    97  	prefix, key []byte,
    98  ) (bool, []byte, []byte) {
    99  	return it.SeekGE(key)
   100  }
   101  
   102  // SeekLT moves the iterator to the last entry whose key is less than the given
   103  // key. Returns the key and value if the iterator is pointing at a valid entry,
   104  // and (nil, nil) otherwise. Note that SeekLT only checks the lower bound. It
   105  // is up to the caller to ensure that key is less than the upper bound.
   106  func (it *Iterator) SeekLT(key []byte) (bool, []byte, []byte) {
   107  	// NB: the top-level Iterator has already adjusted key based on
   108  	// the upper-bound.
   109  	it.nd, _, _ = it.seekForBaseSplice(key)
   110  	if it.nd == it.list.head {
   111  		return false, nil, nil
   112  	}
   113  	it.decodeKey()
   114  	if it.lower != nil && it.list.cmp(it.lower, it.key) > 0 {
   115  		it.nd = it.list.head
   116  		return false, nil, nil
   117  	}
   118  	return true, it.key, it.value()
   119  }
   120  
   121  // First seeks position at the first entry in list. Returns the key and value
   122  // if the iterator is pointing at a valid entry, and (nil, nil) otherwise. Note
   123  // that First only checks the upper bound. It is up to the caller to ensure
   124  // that key is greater than or equal to the lower bound (e.g. via a call to SeekGE(lower)).
   125  func (it *Iterator) First() (bool, []byte, []byte) {
   126  	it.nd = it.list.getNext(it.list.head, 0)
   127  	if it.nd == it.list.tail {
   128  		return false, nil, nil
   129  	}
   130  	it.decodeKey()
   131  	if it.upper != nil && it.list.cmp(it.upper, it.key) <= 0 {
   132  		it.nd = it.list.tail
   133  		return false, nil, nil
   134  	}
   135  	return true, it.key, it.value()
   136  }
   137  
   138  // Last seeks position at the last entry in list. Returns the key and value if
   139  // the iterator is pointing at a valid entry, and (nil, nil) otherwise. Note
   140  // that Last only checks the lower bound. It is up to the caller to ensure that
   141  // key is less than the upper bound (e.g. via a call to SeekLT(upper)).
   142  func (it *Iterator) Last() (bool, []byte, []byte) {
   143  	it.nd = it.list.getPrev(it.list.tail, 0)
   144  	if it.nd == it.list.head {
   145  		return false, nil, nil
   146  	}
   147  	it.decodeKey()
   148  	if it.lower != nil && it.list.cmp(it.lower, it.key) > 0 {
   149  		it.nd = it.list.head
   150  		return false, nil, nil
   151  	}
   152  	return true, it.key, it.value()
   153  }
   154  
   155  // Next advances to the next position. Returns the key and value if the
   156  // iterator is pointing at a valid entry, and (nil, nil) otherwise.
   157  // Note: flushIterator.Next mirrors the implementation of Iterator.Next
   158  // due to performance. Keep the two in sync.
   159  func (it *Iterator) Next() (bool, []byte, []byte) {
   160  	it.nd = it.list.getNext(it.nd, 0)
   161  	if it.nd == it.list.tail {
   162  		return false, nil, nil
   163  	}
   164  	it.decodeKey()
   165  	if it.upper != nil && it.list.cmp(it.upper, it.key) <= 0 {
   166  		it.nd = it.list.tail
   167  		return false, nil, nil
   168  	}
   169  	return true, it.key, it.value()
   170  }
   171  
   172  // Prev moves to the previous position. Returns the key and value if the
   173  // iterator is pointing at a valid entry, and (nil, nil) otherwise.
   174  func (it *Iterator) Prev() (bool, []byte, []byte) {
   175  	it.nd = it.list.getPrev(it.nd, 0)
   176  	if it.nd == it.list.head {
   177  		return false, nil, nil
   178  	}
   179  	it.decodeKey()
   180  	if it.lower != nil && it.list.cmp(it.lower, it.key) > 0 {
   181  		it.nd = it.list.head
   182  		return false, nil, nil
   183  	}
   184  	return true, it.key, it.value()
   185  }
   186  
   187  // value returns the value at the current position.
   188  func (it *Iterator) value() []byte {
   189  	return it.nd.getValue(it.list.arena)
   190  }
   191  
   192  // Head true iff the iterator is positioned at the sentinel head node.
   193  func (it *Iterator) Head() bool {
   194  	return it.nd == it.list.head
   195  }
   196  
   197  // Tail true iff the iterator is positioned at the sentinel tail node.
   198  func (it *Iterator) Tail() bool {
   199  	return it.nd == it.list.tail
   200  }
   201  
   202  // SetBounds sets the lower and upper bounds for the iterator. Note that the
   203  // result of Next and Prev will be undefined until the iterator has been
   204  // repositioned with SeekGE, SeekPrefixGE, SeekLT, First, or Last.
   205  func (it *Iterator) SetBounds(lower, upper []byte) {
   206  	it.lower = lower
   207  	it.upper = upper
   208  }
   209  
   210  func (it *Iterator) decodeKey() {
   211  	it.key = it.list.arena.getBytes(it.nd.keyOffset, it.nd.keySize)
   212  }
   213  
   214  func (it *Iterator) seekForBaseSplice(key []byte) (prev, next *node, found bool) {
   215  	level := int(it.list.Height() - 1)
   216  
   217  	prev = it.list.head
   218  	for {
   219  		prev, next, found = it.list.findSpliceForLevel(key, level, prev)
   220  
   221  		if found {
   222  			if level != 0 {
   223  				// next is pointing at the target node, but we need to find previous on
   224  				// the bottom level.
   225  				prev = it.list.getPrev(next, 0)
   226  			}
   227  			break
   228  		}
   229  
   230  		if level == 0 {
   231  			break
   232  		}
   233  
   234  		level--
   235  	}
   236  
   237  	return
   238  }