LCOV - code coverage report
Current view: top level - pebble/internal/arenaskl - iterator.go (source / functions) Hit Total Coverage
Test: 2023-09-30 08:18Z aa077af6 - meta test only.lcov Lines: 137 152 90.1 %
Date: 2023-09-30 08:19:25 Functions: 0 0 -

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

Generated by: LCOV version 1.14