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 }