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 }