github.com/petermattis/pebble@v0.0.0-20190905164901-ab51a2166067/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/petermattis/pebble/internal/base"
    21  
    22  type splice struct {
    23  	prev uint32
    24  	next uint32
    25  }
    26  
    27  func (s *splice) init(prev, next uint32) {
    28  	s.prev = prev
    29  	s.next = next
    30  }
    31  
    32  // Iterator is an iterator over the skiplist object. Use Skiplist.NewIterator
    33  // to construct an iterator. The current state of the iterator can be cloned
    34  // by simply value copying the struct.
    35  type Iterator struct {
    36  	list  *Skiplist
    37  	nd    uint32
    38  	key   base.InternalKey
    39  	lower []byte
    40  	upper []byte
    41  }
    42  
    43  // Close resets the iterator.
    44  func (it *Iterator) Close() error {
    45  	it.list = nil
    46  	it.nd = 0
    47  	return nil
    48  }
    49  
    50  // SeekGE moves the iterator to the first entry whose key is greater than or
    51  // equal to the given key. Returns true if the iterator is pointing at a valid
    52  // entry and false otherwise. Note that SeekGE only checks the upper bound. It
    53  // is up to the caller to ensure that key is greater than or equal to the lower
    54  // bound.
    55  func (it *Iterator) SeekGE(key []byte) *base.InternalKey {
    56  	_, it.nd, _ = it.seekForBaseSplice(key, it.list.storage.AbbreviatedKey(key))
    57  	if it.nd == it.list.tail {
    58  		return nil
    59  	}
    60  	keyOffset := it.list.getKey(it.nd)
    61  	if it.upper != nil && it.list.storage.Compare(it.upper, keyOffset) <= 0 {
    62  		it.nd = it.list.tail
    63  		return nil
    64  	}
    65  	it.key = it.list.storage.Get(keyOffset)
    66  	return &it.key
    67  }
    68  
    69  // SeekLT moves the iterator to the last entry whose key is less the given
    70  // key. Returns true if the iterator is pointing at a valid entry and false
    71  // otherwise. Note that SeekLT only checks the lower bound. It is up to the
    72  // caller to ensure that key is less than the upper bound.
    73  func (it *Iterator) SeekLT(key []byte) *base.InternalKey {
    74  	it.nd, _, _ = it.seekForBaseSplice(key, it.list.storage.AbbreviatedKey(key))
    75  	if it.nd == it.list.head {
    76  		return nil
    77  	}
    78  	keyOffset := it.list.getKey(it.nd)
    79  	if it.lower != nil && it.list.storage.Compare(it.lower, it.list.getKey(it.nd)) > 0 {
    80  		it.nd = it.list.head
    81  		return nil
    82  	}
    83  	it.key = it.list.storage.Get(keyOffset)
    84  	return &it.key
    85  }
    86  
    87  // First seeks position at the first entry in list. Final state of iterator is
    88  // Valid() iff list is not empty. Note that First only checks the upper
    89  // bound. It is up to the caller to ensure that key is greater than or equal to
    90  // the lower bound (e.g. via a call to SeekGE(lower)).
    91  func (it *Iterator) First() *base.InternalKey {
    92  	it.nd = it.list.getNext(it.list.head, 0)
    93  	if it.nd == it.list.tail {
    94  		return nil
    95  	}
    96  	keyOffset := it.list.getKey(it.nd)
    97  	if it.upper != nil && it.list.storage.Compare(it.upper, keyOffset) <= 0 {
    98  		it.nd = it.list.tail
    99  		return nil
   100  	}
   101  	it.key = it.list.storage.Get(keyOffset)
   102  	return &it.key
   103  }
   104  
   105  // Last seeks position at the last entry in list. Final state of iterator is
   106  // Valid() iff list is not empty. Note that Last only checks the lower
   107  // bound. It is up to the caller to ensure that key is less than the upper
   108  // bound (e.g. via a call to SeekLT(upper)).
   109  func (it *Iterator) Last() *base.InternalKey {
   110  	it.nd = it.list.getPrev(it.list.tail, 0)
   111  	if it.nd == it.list.head {
   112  		return nil
   113  	}
   114  	keyOffset := it.list.getKey(it.nd)
   115  	if it.lower != nil && it.list.storage.Compare(it.lower, keyOffset) > 0 {
   116  		it.nd = it.list.head
   117  		return nil
   118  	}
   119  	it.key = it.list.storage.Get(keyOffset)
   120  	return &it.key
   121  }
   122  
   123  // Next advances to the next position. If there are no following nodes, then
   124  // Valid() will be false after this call.
   125  func (it *Iterator) Next() *base.InternalKey {
   126  	it.nd = it.list.getNext(it.nd, 0)
   127  	if it.nd == it.list.tail {
   128  		return nil
   129  	}
   130  	keyOffset := it.list.getKey(it.nd)
   131  	if it.upper != nil && it.list.storage.Compare(it.upper, keyOffset) <= 0 {
   132  		it.nd = it.list.tail
   133  		return nil
   134  	}
   135  	it.key = it.list.storage.Get(keyOffset)
   136  	return &it.key
   137  }
   138  
   139  // Prev moves to the previous position. If there are no previous nodes, then
   140  // Valid() will be false after this call.
   141  func (it *Iterator) Prev() *base.InternalKey {
   142  	it.nd = it.list.getPrev(it.nd, 0)
   143  	if it.nd == it.list.head {
   144  		return nil
   145  	}
   146  	keyOffset := it.list.getKey(it.nd)
   147  	if it.lower != nil && it.list.storage.Compare(it.lower, keyOffset) > 0 {
   148  		it.nd = it.list.head
   149  		return nil
   150  	}
   151  	it.key = it.list.storage.Get(keyOffset)
   152  	return &it.key
   153  }
   154  
   155  // Key returns the key at the current position.
   156  func (it *Iterator) Key() *base.InternalKey {
   157  	return &it.key
   158  }
   159  
   160  // KeyOffset returns the key offset at the current position.
   161  func (it *Iterator) KeyOffset() uint32 {
   162  	return it.list.getKey(it.nd)
   163  }
   164  
   165  // Head true iff the iterator is positioned at the sentinel head node.
   166  func (it *Iterator) Head() bool {
   167  	return it.nd == it.list.head
   168  }
   169  
   170  // Tail true iff the iterator is positioned at the sentinel tail node.
   171  func (it *Iterator) Tail() bool {
   172  	return it.nd == it.list.tail
   173  }
   174  
   175  // Valid returns nil iff the iterator is positioned at a valid node.
   176  func (it *Iterator) Valid() bool {
   177  	return it.list != nil && it.nd != it.list.head && it.nd != it.list.tail
   178  }
   179  
   180  // SetBounds sets the lower and upper bounds for the iterator. Note that the
   181  // result of Next and Prev will be undefined until the iterator has been
   182  // repositioned with SeekGE, SeekLT, First, or Last.
   183  func (it *Iterator) SetBounds(lower, upper []byte) {
   184  	it.lower = lower
   185  	it.upper = upper
   186  }
   187  
   188  func (it *Iterator) seekForBaseSplice(
   189  	key []byte, abbreviatedKey uint64,
   190  ) (prev, next uint32, found bool) {
   191  	prev = it.list.head
   192  	for level := it.list.height - 1; ; level-- {
   193  		prev, next, found = it.list.findSpliceForLevel(key, abbreviatedKey, level, prev)
   194  		if found {
   195  			if level != 0 {
   196  				// next is pointing at the target node, but we need to find previous on
   197  				// the bottom level.
   198  				prev = it.list.getPrev(next, 0)
   199  			}
   200  			break
   201  		}
   202  		if level == 0 {
   203  			break
   204  		}
   205  	}
   206  
   207  	return
   208  }