github.com/zuoyebang/bitalostable@v1.0.1-0.20240229032404-e3b99a834294/internal/arenaskl/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 arenaskl
    19  
    20  import (
    21  	"encoding/binary"
    22  	"sync"
    23  
    24  	"github.com/zuoyebang/bitalostable/internal/base"
    25  )
    26  
    27  type splice struct {
    28  	prev *node
    29  	next *node
    30  }
    31  
    32  func (s *splice) init(prev, next *node) {
    33  	s.prev = prev
    34  	s.next = next
    35  }
    36  
    37  // Iterator is an iterator over the skiplist object. Use Skiplist.NewIter
    38  // to construct an iterator. The current state of the iterator can be cloned by
    39  // simply value copying the struct. All iterator methods are thread-safe.
    40  type Iterator struct {
    41  	list  *Skiplist
    42  	nd    *node
    43  	key   base.InternalKey
    44  	lower []byte
    45  	upper []byte
    46  }
    47  
    48  // Iterator implements the base.InternalIterator interface.
    49  var _ base.InternalIterator = (*Iterator)(nil)
    50  
    51  var iterPool = sync.Pool{
    52  	New: func() interface{} {
    53  		return &Iterator{}
    54  	},
    55  }
    56  
    57  // Close resets the iterator.
    58  func (it *Iterator) Close() error {
    59  	it.list = nil
    60  	it.nd = nil
    61  	it.lower = nil
    62  	it.upper = nil
    63  	iterPool.Put(it)
    64  	return nil
    65  }
    66  
    67  func (it *Iterator) String() string {
    68  	return "memtable"
    69  }
    70  
    71  // Error returns any accumulated error.
    72  func (it *Iterator) Error() error {
    73  	return nil
    74  }
    75  
    76  // SeekGE moves the iterator to the first entry whose key is greater than or
    77  // equal to the given key. Returns the key and value if the iterator is
    78  // pointing at a valid entry, and (nil, nil) otherwise. Note that SeekGE only
    79  // checks the upper bound. It is up to the caller to ensure that key is greater
    80  // than or equal to the lower bound.
    81  func (it *Iterator) SeekGE(key []byte, flags base.SeekGEFlags) (*base.InternalKey, []byte) {
    82  	if flags.TrySeekUsingNext() {
    83  		if it.nd == it.list.tail {
    84  			// Iterator is done.
    85  			return nil, nil
    86  		}
    87  		less := it.list.cmp(it.key.UserKey, key) < 0
    88  		// Arbitrary constant. By measuring the seek cost as a function of the
    89  		// number of elements in the skip list, and fitting to a model, we
    90  		// could adjust the number of nexts based on the current size of the
    91  		// skip list.
    92  		const numNexts = 5
    93  		for i := 0; less && i < numNexts; i++ {
    94  			k, _ := it.Next()
    95  			if k == nil {
    96  				// Iterator is done.
    97  				return nil, nil
    98  			}
    99  			less = it.list.cmp(it.key.UserKey, key) < 0
   100  		}
   101  		if !less {
   102  			return &it.key, it.value()
   103  		}
   104  	}
   105  	_, it.nd, _ = it.seekForBaseSplice(key)
   106  	if it.nd == it.list.tail {
   107  		return nil, nil
   108  	}
   109  	it.decodeKey()
   110  	if it.upper != nil && it.list.cmp(it.upper, it.key.UserKey) <= 0 {
   111  		it.nd = it.list.tail
   112  		return nil, nil
   113  	}
   114  	return &it.key, it.value()
   115  }
   116  
   117  // SeekPrefixGE moves the iterator to the first entry whose key is greater than
   118  // or equal to the given key. This method is equivalent to SeekGE and is
   119  // provided so that an arenaskl.Iterator implements the
   120  // internal/base.InternalIterator interface.
   121  func (it *Iterator) SeekPrefixGE(
   122  	prefix, key []byte, flags base.SeekGEFlags,
   123  ) (*base.InternalKey, []byte) {
   124  	return it.SeekGE(key, flags)
   125  }
   126  
   127  // SeekLT moves the iterator to the last entry whose key is less than the given
   128  // key. Returns the key and value if the iterator is pointing at a valid entry,
   129  // and (nil, nil) otherwise. Note that SeekLT only checks the lower bound. It
   130  // is up to the caller to ensure that key is less than the upper bound.
   131  func (it *Iterator) SeekLT(key []byte, flags base.SeekLTFlags) (*base.InternalKey, []byte) {
   132  	// NB: the top-level Iterator has already adjusted key based on
   133  	// the upper-bound.
   134  	it.nd, _, _ = it.seekForBaseSplice(key)
   135  	if it.nd == it.list.head {
   136  		return nil, nil
   137  	}
   138  	it.decodeKey()
   139  	if it.lower != nil && it.list.cmp(it.lower, it.key.UserKey) > 0 {
   140  		it.nd = it.list.head
   141  		return nil, nil
   142  	}
   143  	return &it.key, it.value()
   144  }
   145  
   146  // First seeks position at the first entry in list. Returns the key and value
   147  // if the iterator is pointing at a valid entry, and (nil, nil) otherwise. Note
   148  // that First only checks the upper bound. It is up to the caller to ensure
   149  // that key is greater than or equal to the lower bound (e.g. via a call to SeekGE(lower)).
   150  func (it *Iterator) First() (*base.InternalKey, []byte) {
   151  	it.nd = it.list.getNext(it.list.head, 0)
   152  	if it.nd == it.list.tail {
   153  		return nil, nil
   154  	}
   155  	it.decodeKey()
   156  	if it.upper != nil && it.list.cmp(it.upper, it.key.UserKey) <= 0 {
   157  		it.nd = it.list.tail
   158  		return nil, nil
   159  	}
   160  	return &it.key, it.value()
   161  }
   162  
   163  // Last seeks position at the last entry in list. Returns the key and value if
   164  // the iterator is pointing at a valid entry, and (nil, nil) otherwise. Note
   165  // that Last only checks the lower bound. It is up to the caller to ensure that
   166  // key is less than the upper bound (e.g. via a call to SeekLT(upper)).
   167  func (it *Iterator) Last() (*base.InternalKey, []byte) {
   168  	it.nd = it.list.getPrev(it.list.tail, 0)
   169  	if it.nd == it.list.head {
   170  		return nil, nil
   171  	}
   172  	it.decodeKey()
   173  	if it.lower != nil && it.list.cmp(it.lower, it.key.UserKey) > 0 {
   174  		it.nd = it.list.head
   175  		return nil, nil
   176  	}
   177  	return &it.key, it.value()
   178  }
   179  
   180  // Next advances to the next position. Returns the key and value if the
   181  // iterator is pointing at a valid entry, and (nil, nil) otherwise.
   182  // Note: flushIterator.Next mirrors the implementation of Iterator.Next
   183  // due to performance. Keep the two in sync.
   184  func (it *Iterator) Next() (*base.InternalKey, []byte) {
   185  	it.nd = it.list.getSkipNext(it.nd)
   186  	if it.nd == it.list.tail {
   187  		return nil, nil
   188  	}
   189  	it.decodeKey()
   190  	if it.upper != nil && it.list.cmp(it.upper, it.key.UserKey) <= 0 {
   191  		it.nd = it.list.tail
   192  		return nil, nil
   193  	}
   194  	return &it.key, it.value()
   195  }
   196  
   197  // Prev moves to the previous position. Returns the key and value if the
   198  // iterator is pointing at a valid entry, and (nil, nil) otherwise.
   199  func (it *Iterator) Prev() (*base.InternalKey, []byte) {
   200  	it.nd = it.list.getSkipPrev(it.nd)
   201  	if it.nd == it.list.head {
   202  		return nil, nil
   203  	}
   204  	it.decodeKey()
   205  	if it.lower != nil && it.list.cmp(it.lower, it.key.UserKey) > 0 {
   206  		it.nd = it.list.head
   207  		return nil, nil
   208  	}
   209  	return &it.key, it.value()
   210  }
   211  
   212  // value returns the value at the current position.
   213  func (it *Iterator) value() []byte {
   214  	return it.nd.getValue(it.list.arena)
   215  }
   216  
   217  // Head true iff the iterator is positioned at the sentinel head node.
   218  func (it *Iterator) Head() bool {
   219  	return it.nd == it.list.head
   220  }
   221  
   222  // Tail true iff the iterator is positioned at the sentinel tail node.
   223  func (it *Iterator) Tail() bool {
   224  	return it.nd == it.list.tail
   225  }
   226  
   227  // SetBounds sets the lower and upper bounds for the iterator. Note that the
   228  // result of Next and Prev will be undefined until the iterator has been
   229  // repositioned with SeekGE, SeekPrefixGE, SeekLT, First, or Last.
   230  func (it *Iterator) SetBounds(lower, upper []byte) {
   231  	it.lower = lower
   232  	it.upper = upper
   233  }
   234  
   235  func (it *Iterator) decodeKey() {
   236  	b := it.list.arena.getBytes(it.nd.keyOffset, it.nd.keySize)
   237  	// This is a manual inline of base.DecodeInternalKey, because the Go compiler
   238  	// seems to refuse to automatically inline it currently.
   239  	l := len(b) - 8
   240  	if l >= 0 {
   241  		it.key.Trailer = binary.LittleEndian.Uint64(b[l:])
   242  		it.key.UserKey = b[:l:l]
   243  	} else {
   244  		it.key.Trailer = uint64(base.InternalKeyKindInvalid)
   245  		it.key.UserKey = nil
   246  	}
   247  }
   248  
   249  func (it *Iterator) seekForBaseSplice(key []byte) (prev, next *node, found bool) {
   250  	ikey := base.MakeSearchKey(key)
   251  	level := int(it.list.Height() - 1)
   252  
   253  	prev = it.list.head
   254  	for {
   255  		prev, next, found = it.list.findSpliceForLevel(ikey, level, prev)
   256  
   257  		if found {
   258  			if level != 0 {
   259  				// next is pointing at the target node, but we need to find previous on
   260  				// the bottom level.
   261  				prev = it.list.getPrev(next, 0)
   262  			}
   263  			break
   264  		}
   265  
   266  		if level == 0 {
   267  			break
   268  		}
   269  
   270  		level--
   271  	}
   272  
   273  	return
   274  }