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

     1  /*
     2   * Copyright 2017 Dgraph Labs, Inc. and Contributors
     3   * Modifications copyright (C) 2017 Andy Kimball and Contributors
     4   *
     5   * Licensed under the Apache License, Version 2.0 (the "License");
     6   * you may not use this file except in compliance with the License.
     7   * You may obtain a copy of the License at
     8   *
     9   *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17  
    18  package batchskl
    19  
    20  import "github.com/zuoyebang/bitalostable/internal/base"
    21  
    22  type splice struct {
    23  	prev uint32
    24  	next uint32
    25  }
    26  
    27  // Iterator is an iterator over the skiplist object. Use Skiplist.NewIter
    28  // to construct an iterator. The current state of the iterator can be cloned
    29  // by simply value copying the struct.
    30  type Iterator struct {
    31  	list  *Skiplist
    32  	nd    uint32
    33  	key   base.InternalKey
    34  	lower []byte
    35  	upper []byte
    36  }
    37  
    38  // Close resets the iterator.
    39  func (it *Iterator) Close() error {
    40  	it.list = nil
    41  	it.nd = 0
    42  	return nil
    43  }
    44  
    45  // SeekGE moves the iterator to the first entry whose key is greater than or
    46  // equal to the given key. Returns true if the iterator is pointing at a valid
    47  // entry and false otherwise. Note that SeekGE only checks the upper bound. It
    48  // is up to the caller to ensure that key is greater than or equal to the lower
    49  // bound.
    50  func (it *Iterator) SeekGE(key []byte) *base.InternalKey {
    51  	_, it.nd = it.seekForBaseSplice(key, it.list.abbreviatedKey(key))
    52  	if it.nd == it.list.tail {
    53  		return nil
    54  	}
    55  	nodeKey := it.list.getKey(it.nd)
    56  	if it.upper != nil && it.list.cmp(it.upper, nodeKey.UserKey) <= 0 {
    57  		it.nd = it.list.tail
    58  		return nil
    59  	}
    60  	it.key = nodeKey
    61  	return &it.key
    62  }
    63  
    64  // SeekLT moves the iterator to the last entry whose key is less the given
    65  // key. Returns true if the iterator is pointing at a valid entry and false
    66  // otherwise. Note that SeekLT only checks the lower bound. It is up to the
    67  // caller to ensure that key is less than the upper bound.
    68  func (it *Iterator) SeekLT(key []byte) *base.InternalKey {
    69  	it.nd, _ = it.seekForBaseSplice(key, it.list.abbreviatedKey(key))
    70  	if it.nd == it.list.head {
    71  		return nil
    72  	}
    73  	nodeKey := it.list.getKey(it.nd)
    74  	if it.lower != nil && it.list.cmp(it.lower, nodeKey.UserKey) > 0 {
    75  		it.nd = it.list.head
    76  		return nil
    77  	}
    78  	it.key = nodeKey
    79  	return &it.key
    80  }
    81  
    82  // First seeks position at the first entry in list. Final state of iterator is
    83  // Valid() iff list is not empty. Note that First only checks the upper
    84  // bound. It is up to the caller to ensure that key is greater than or equal to
    85  // the lower bound (e.g. via a call to SeekGE(lower)).
    86  func (it *Iterator) First() *base.InternalKey {
    87  	it.nd = it.list.getNext(it.list.head, 0)
    88  	if it.nd == it.list.tail {
    89  		return nil
    90  	}
    91  	nodeKey := it.list.getKey(it.nd)
    92  	if it.upper != nil && it.list.cmp(it.upper, nodeKey.UserKey) <= 0 {
    93  		it.nd = it.list.tail
    94  		return nil
    95  	}
    96  	it.key = nodeKey
    97  	return &it.key
    98  }
    99  
   100  // Last seeks position at the last entry in list. Final state of iterator is
   101  // Valid() iff list is not empty. Note that Last only checks the lower
   102  // bound. It is up to the caller to ensure that key is less than the upper
   103  // bound (e.g. via a call to SeekLT(upper)).
   104  func (it *Iterator) Last() *base.InternalKey {
   105  	it.nd = it.list.getPrev(it.list.tail, 0)
   106  	if it.nd == it.list.head {
   107  		return nil
   108  	}
   109  	nodeKey := it.list.getKey(it.nd)
   110  	if it.lower != nil && it.list.cmp(it.lower, nodeKey.UserKey) > 0 {
   111  		it.nd = it.list.head
   112  		return nil
   113  	}
   114  	it.key = nodeKey
   115  	return &it.key
   116  }
   117  
   118  // Next advances to the next position. If there are no following nodes, then
   119  // Valid() will be false after this call.
   120  func (it *Iterator) Next() *base.InternalKey {
   121  	it.nd = it.list.getNext(it.nd, 0)
   122  	if it.nd == it.list.tail {
   123  		return nil
   124  	}
   125  	nodeKey := it.list.getKey(it.nd)
   126  	if it.upper != nil && it.list.cmp(it.upper, nodeKey.UserKey) <= 0 {
   127  		it.nd = it.list.tail
   128  		return nil
   129  	}
   130  	it.key = nodeKey
   131  	return &it.key
   132  }
   133  
   134  // Prev moves to the previous position. If there are no previous nodes, then
   135  // Valid() will be false after this call.
   136  func (it *Iterator) Prev() *base.InternalKey {
   137  	it.nd = it.list.getPrev(it.nd, 0)
   138  	if it.nd == it.list.head {
   139  		return nil
   140  	}
   141  	nodeKey := it.list.getKey(it.nd)
   142  	if it.lower != nil && it.list.cmp(it.lower, nodeKey.UserKey) > 0 {
   143  		it.nd = it.list.head
   144  		return nil
   145  	}
   146  	it.key = nodeKey
   147  	return &it.key
   148  }
   149  
   150  // Key returns the key at the current position.
   151  func (it *Iterator) Key() *base.InternalKey {
   152  	return &it.key
   153  }
   154  
   155  // KeyInfo returns the offset of the start of the record, the start of the key,
   156  // and the end of the key.
   157  func (it *Iterator) KeyInfo() (offset, keyStart, keyEnd uint32) {
   158  	n := it.list.node(it.nd)
   159  	return n.offset, n.keyStart, n.keyEnd
   160  }
   161  
   162  // Head true iff the iterator is positioned at the sentinel head node.
   163  func (it *Iterator) Head() bool {
   164  	return it.nd == it.list.head
   165  }
   166  
   167  // Tail true iff the iterator is positioned at the sentinel tail node.
   168  func (it *Iterator) Tail() bool {
   169  	return it.nd == it.list.tail
   170  }
   171  
   172  // Valid returns nil iff the iterator is positioned at a valid node.
   173  func (it *Iterator) Valid() bool {
   174  	return it.list != nil && it.nd != it.list.head && it.nd != it.list.tail
   175  }
   176  
   177  func (it *Iterator) String() string {
   178  	return "batch"
   179  }
   180  
   181  // SetBounds sets the lower and upper bounds for the iterator. Note that the
   182  // result of Next and Prev will be undefined until the iterator has been
   183  // repositioned with SeekGE, SeekLT, First, or Last.
   184  func (it *Iterator) SetBounds(lower, upper []byte) {
   185  	it.lower = lower
   186  	it.upper = upper
   187  }
   188  
   189  func (it *Iterator) seekForBaseSplice(key []byte, abbreviatedKey uint64) (prev, next uint32) {
   190  	prev = it.list.head
   191  	for level := it.list.height - 1; ; level-- {
   192  		prev, next = it.list.findSpliceForLevel(key, abbreviatedKey, level, prev)
   193  		if level == 0 {
   194  			break
   195  		}
   196  	}
   197  
   198  	return
   199  }