github.com/petermattis/pebble@v0.0.0-20190905164901-ab51a2166067/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/petermattis/pebble/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.NewIterator
    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  var iterPool = sync.Pool{
    49  	New: func() interface{} {
    50  		return &Iterator{}
    51  	},
    52  }
    53  
    54  // Close resets the iterator.
    55  func (it *Iterator) Close() error {
    56  	it.list = nil
    57  	it.nd = nil
    58  	it.lower = nil
    59  	it.upper = nil
    60  	iterPool.Put(it)
    61  	return nil
    62  }
    63  
    64  // Error returns any accumulated error.
    65  func (it *Iterator) Error() error {
    66  	return nil
    67  }
    68  
    69  // SeekGE moves the iterator to the first entry whose key is greater than or
    70  // equal to the given key. Returns the key and value if the iterator is
    71  // pointing at a valid entry, and (nil, nil) otherwise. Note that SeekGE only
    72  // checks the upper bound. It is up to the caller to ensure that key is greater
    73  // than or equal to the lower bound.
    74  func (it *Iterator) SeekGE(key []byte) (*base.InternalKey, []byte) {
    75  	_, it.nd, _ = it.seekForBaseSplice(key)
    76  	if it.nd == it.list.tail {
    77  		return nil, nil
    78  	}
    79  	it.decodeKey()
    80  	if it.upper != nil && it.list.cmp(it.upper, it.key.UserKey) <= 0 {
    81  		it.nd = it.list.tail
    82  		return nil, nil
    83  	}
    84  	return &it.key, it.Value()
    85  }
    86  
    87  func (it *Iterator) SeekPrefixGE(prefix, key []byte) (*base.InternalKey, []byte) {
    88  	return it.SeekGE(key)
    89  }
    90  
    91  // SeekLT moves the iterator to the last entry whose key is less than the given
    92  // key. Returns the key and value if the iterator is pointing at a valid entry,
    93  // and (nil, nil) otherwise. Note that SeekLT only checks the lower bound. It
    94  // is up to the caller to ensure that key is less than the upper bound.
    95  func (it *Iterator) SeekLT(key []byte) (*base.InternalKey, []byte) {
    96  	// NB: the top-level Iterator has already adjusted key based on
    97  	// the upper-bound.
    98  	it.nd, _, _ = it.seekForBaseSplice(key)
    99  	if it.nd == it.list.head {
   100  		return nil, nil
   101  	}
   102  	it.decodeKey()
   103  	if it.lower != nil && it.list.cmp(it.lower, it.key.UserKey) > 0 {
   104  		it.nd = it.list.head
   105  		return nil, nil
   106  	}
   107  	return &it.key, it.Value()
   108  }
   109  
   110  // First seeks position at the first entry in list. Returns the key and value
   111  // if the iterator is pointing at a valid entry, and (nil, nil) otherwise. Note
   112  // that First only checks the upper bound. It is up to the caller to ensure
   113  // that key is greater than or equal to the lower bound (e.g. via a call to SeekGE(lower)).
   114  func (it *Iterator) First() (*base.InternalKey, []byte) {
   115  	it.nd = it.list.getNext(it.list.head, 0)
   116  	if it.nd == it.list.tail {
   117  		return nil, nil
   118  	}
   119  	it.decodeKey()
   120  	if it.upper != nil && it.list.cmp(it.upper, it.key.UserKey) <= 0 {
   121  		it.nd = it.list.tail
   122  		return nil, nil
   123  	}
   124  	return &it.key, it.Value()
   125  }
   126  
   127  // Last seeks position at the last entry in list. Returns the key and value if
   128  // the iterator is pointing at a valid entry, and (nil, nil) otherwise. Note
   129  // that Last only checks the lower bound. It is up to the caller to ensure that
   130  // key is less than the upper bound (e.g. via a call to SeekLT(upper)).
   131  func (it *Iterator) Last() (*base.InternalKey, []byte) {
   132  	it.nd = it.list.getPrev(it.list.tail, 0)
   133  	if it.nd == it.list.head {
   134  		return nil, nil
   135  	}
   136  	it.decodeKey()
   137  	if it.lower != nil && it.list.cmp(it.lower, it.key.UserKey) > 0 {
   138  		it.nd = it.list.head
   139  		return nil, nil
   140  	}
   141  	return &it.key, it.Value()
   142  }
   143  
   144  // Next advances to the next position. Returns the key and value if the
   145  // iterator is pointing at a valid entry, and (nil, nil) otherwise.
   146  // Note: flushIterator.Next mirrors the implementation of Iterator.Next
   147  // due to performance. Keep the two in sync.
   148  func (it *Iterator) Next() (*base.InternalKey, []byte) {
   149  	it.nd = it.list.getNext(it.nd, 0)
   150  	if it.nd == it.list.tail {
   151  		return nil, nil
   152  	}
   153  	it.decodeKey()
   154  	if it.upper != nil && it.list.cmp(it.upper, it.key.UserKey) <= 0 {
   155  		it.nd = it.list.tail
   156  		return nil, nil
   157  	}
   158  	return &it.key, it.Value()
   159  }
   160  
   161  // Prev moves to the previous position. Returns the key and value if the
   162  // iterator is pointing at a valid entry, and (nil, nil) otherwise.
   163  func (it *Iterator) Prev() (*base.InternalKey, []byte) {
   164  	it.nd = it.list.getPrev(it.nd, 0)
   165  	if it.nd == it.list.head {
   166  		return nil, nil
   167  	}
   168  	it.decodeKey()
   169  	if it.lower != nil && it.list.cmp(it.lower, it.key.UserKey) > 0 {
   170  		it.nd = it.list.head
   171  		return nil, nil
   172  	}
   173  	return &it.key, it.Value()
   174  }
   175  
   176  // Key returns the key at the current position.
   177  func (it *Iterator) Key() *base.InternalKey {
   178  	return &it.key
   179  }
   180  
   181  // Value returns the value at the current position.
   182  func (it *Iterator) Value() []byte {
   183  	return it.nd.getValue(it.list.arena)
   184  }
   185  
   186  // Head true iff the iterator is positioned at the sentinel head node.
   187  func (it *Iterator) Head() bool {
   188  	return it.nd == it.list.head
   189  }
   190  
   191  // Tail true iff the iterator is positioned at the sentinel tail node.
   192  func (it *Iterator) Tail() bool {
   193  	return it.nd == it.list.tail
   194  }
   195  
   196  // Valid returns true iff the iterator is positioned at a valid node.
   197  func (it *Iterator) Valid() bool {
   198  	return it.nd != it.list.head && it.nd != it.list.tail
   199  }
   200  
   201  // SetBounds sets the lower and upper bounds for the iterator. Note that the
   202  // result of Next and Prev will be undefined until the iterator has been
   203  // repositioned with SeekGE, SeekPrefixGE, SeekLT, First, or Last.
   204  func (it *Iterator) SetBounds(lower, upper []byte) {
   205  	it.lower = lower
   206  	it.upper = upper
   207  }
   208  
   209  func (it *Iterator) decodeKey() {
   210  	b := it.list.arena.getBytes(it.nd.keyOffset, it.nd.keySize)
   211  	// This is a manual inline of base.DecodeInternalKey, because the Go compiler
   212  	// seems to refuse to automatically inline it currently.
   213  	l := len(b) - 8
   214  	if l >= 0 {
   215  		it.key.Trailer = binary.LittleEndian.Uint64(b[l:])
   216  		it.key.UserKey = b[:l:l]
   217  	} else {
   218  		it.key.Trailer = uint64(base.InternalKeyKindInvalid)
   219  		it.key.UserKey = nil
   220  	}
   221  }
   222  
   223  func (it *Iterator) seekForBaseSplice(key []byte) (prev, next *node, found bool) {
   224  	ikey := base.MakeSearchKey(key)
   225  	level := int(it.list.Height() - 1)
   226  
   227  	prev = it.list.head
   228  	for {
   229  		prev, next, found = it.list.findSpliceForLevel(ikey, level, prev)
   230  
   231  		if found {
   232  			if level != 0 {
   233  				// next is pointing at the target node, but we need to find previous on
   234  				// the bottom level.
   235  				prev = it.list.getPrev(next, 0)
   236  			}
   237  			break
   238  		}
   239  
   240  		if level == 0 {
   241  			break
   242  		}
   243  
   244  		level--
   245  	}
   246  
   247  	return
   248  }