github.com/matrixorigin/matrixone@v1.2.0/pkg/common/arenaskl/iterator.go (about) 1 /* 2 * Copyright 2017 Dgraph Labs, Inc. and Contributors 3 * Modifications copyright (C) 2017 Andy Kimball and Contributors 4 * and copyright (C) 2024 MatrixOrigin Inc. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package arenaskl 20 21 import ( 22 "sync" 23 ) 24 25 type splice struct { 26 prev *node 27 next *node 28 } 29 30 func (s *splice) init(prev, next *node) { 31 s.prev = prev 32 s.next = next 33 } 34 35 // Iterator is an iterator over the skiplist object. Use Skiplist.NewIter 36 // to construct an iterator. The current state of the iterator can be cloned by 37 // simply value copying the struct. All iterator methods are thread-safe. 38 type Iterator struct { 39 list *Skiplist 40 nd *node 41 key []byte 42 lower []byte 43 upper []byte 44 } 45 46 // Iterator implements the base.InternalIterator interface. 47 // var _ base.InternalIterator = (*Iterator)(nil) 48 49 var iterPool = sync.Pool{ 50 New: func() interface{} { 51 return &Iterator{} 52 }, 53 } 54 55 // Close resets the iterator. 56 func (it *Iterator) Close() error { 57 it.list = nil 58 it.nd = nil 59 it.lower = nil 60 it.upper = nil 61 iterPool.Put(it) 62 return nil 63 } 64 65 func (it *Iterator) String() string { 66 return "memtable" 67 } 68 69 // Error returns any accumulated error. 70 func (it *Iterator) Error() error { 71 return nil 72 } 73 74 // SeekGE moves the iterator to the first entry whose key is greater than or 75 // equal to the given key. Returns the key and value if the iterator is 76 // pointing at a valid entry, and (nil, nil) otherwise. Note that SeekGE only 77 // checks the upper bound. It is up to the caller to ensure that key is greater 78 // than or equal to the lower bound. 79 func (it *Iterator) SeekGE(key []byte) (bool, []byte, []byte) { 80 _, it.nd, _ = it.seekForBaseSplice(key) 81 if it.nd == it.list.tail { 82 return false, nil, nil 83 } 84 it.decodeKey() 85 if it.upper != nil && it.list.cmp(it.upper, it.key) <= 0 { 86 it.nd = it.list.tail 87 return false, nil, nil 88 } 89 return true, it.key, it.value() 90 } 91 92 // SeekPrefixGE moves the iterator to the first entry whose key is greater than 93 // or equal to the given key. This method is equivalent to SeekGE and is 94 // provided so that an arenaskl.Iterator implements the 95 // internal/base.InternalIterator interface. 96 func (it *Iterator) SeekPrefixGE( 97 prefix, key []byte, 98 ) (bool, []byte, []byte) { 99 return it.SeekGE(key) 100 } 101 102 // SeekLT moves the iterator to the last entry whose key is less than the given 103 // key. Returns the key and value if the iterator is pointing at a valid entry, 104 // and (nil, nil) otherwise. Note that SeekLT only checks the lower bound. It 105 // is up to the caller to ensure that key is less than the upper bound. 106 func (it *Iterator) SeekLT(key []byte) (bool, []byte, []byte) { 107 // NB: the top-level Iterator has already adjusted key based on 108 // the upper-bound. 109 it.nd, _, _ = it.seekForBaseSplice(key) 110 if it.nd == it.list.head { 111 return false, nil, nil 112 } 113 it.decodeKey() 114 if it.lower != nil && it.list.cmp(it.lower, it.key) > 0 { 115 it.nd = it.list.head 116 return false, nil, nil 117 } 118 return true, it.key, it.value() 119 } 120 121 // First seeks position at the first entry in list. Returns the key and value 122 // if the iterator is pointing at a valid entry, and (nil, nil) otherwise. Note 123 // that First only checks the upper bound. It is up to the caller to ensure 124 // that key is greater than or equal to the lower bound (e.g. via a call to SeekGE(lower)). 125 func (it *Iterator) First() (bool, []byte, []byte) { 126 it.nd = it.list.getNext(it.list.head, 0) 127 if it.nd == it.list.tail { 128 return false, nil, nil 129 } 130 it.decodeKey() 131 if it.upper != nil && it.list.cmp(it.upper, it.key) <= 0 { 132 it.nd = it.list.tail 133 return false, nil, nil 134 } 135 return true, it.key, it.value() 136 } 137 138 // Last seeks position at the last entry in list. Returns the key and value if 139 // the iterator is pointing at a valid entry, and (nil, nil) otherwise. Note 140 // that Last only checks the lower bound. It is up to the caller to ensure that 141 // key is less than the upper bound (e.g. via a call to SeekLT(upper)). 142 func (it *Iterator) Last() (bool, []byte, []byte) { 143 it.nd = it.list.getPrev(it.list.tail, 0) 144 if it.nd == it.list.head { 145 return false, nil, nil 146 } 147 it.decodeKey() 148 if it.lower != nil && it.list.cmp(it.lower, it.key) > 0 { 149 it.nd = it.list.head 150 return false, nil, nil 151 } 152 return true, it.key, it.value() 153 } 154 155 // Next advances to the next position. Returns the key and value if the 156 // iterator is pointing at a valid entry, and (nil, nil) otherwise. 157 // Note: flushIterator.Next mirrors the implementation of Iterator.Next 158 // due to performance. Keep the two in sync. 159 func (it *Iterator) Next() (bool, []byte, []byte) { 160 it.nd = it.list.getNext(it.nd, 0) 161 if it.nd == it.list.tail { 162 return false, nil, nil 163 } 164 it.decodeKey() 165 if it.upper != nil && it.list.cmp(it.upper, it.key) <= 0 { 166 it.nd = it.list.tail 167 return false, nil, nil 168 } 169 return true, it.key, it.value() 170 } 171 172 // Prev moves to the previous position. Returns the key and value if the 173 // iterator is pointing at a valid entry, and (nil, nil) otherwise. 174 func (it *Iterator) Prev() (bool, []byte, []byte) { 175 it.nd = it.list.getPrev(it.nd, 0) 176 if it.nd == it.list.head { 177 return false, nil, nil 178 } 179 it.decodeKey() 180 if it.lower != nil && it.list.cmp(it.lower, it.key) > 0 { 181 it.nd = it.list.head 182 return false, nil, nil 183 } 184 return true, it.key, it.value() 185 } 186 187 // value returns the value at the current position. 188 func (it *Iterator) value() []byte { 189 return it.nd.getValue(it.list.arena) 190 } 191 192 // Head true iff the iterator is positioned at the sentinel head node. 193 func (it *Iterator) Head() bool { 194 return it.nd == it.list.head 195 } 196 197 // Tail true iff the iterator is positioned at the sentinel tail node. 198 func (it *Iterator) Tail() bool { 199 return it.nd == it.list.tail 200 } 201 202 // SetBounds sets the lower and upper bounds for the iterator. Note that the 203 // result of Next and Prev will be undefined until the iterator has been 204 // repositioned with SeekGE, SeekPrefixGE, SeekLT, First, or Last. 205 func (it *Iterator) SetBounds(lower, upper []byte) { 206 it.lower = lower 207 it.upper = upper 208 } 209 210 func (it *Iterator) decodeKey() { 211 it.key = it.list.arena.getBytes(it.nd.keyOffset, it.nd.keySize) 212 } 213 214 func (it *Iterator) seekForBaseSplice(key []byte) (prev, next *node, found bool) { 215 level := int(it.list.Height() - 1) 216 217 prev = it.list.head 218 for { 219 prev, next, found = it.list.findSpliceForLevel(key, level, prev) 220 221 if found { 222 if level != 0 { 223 // next is pointing at the target node, but we need to find previous on 224 // the bottom level. 225 prev = it.list.getPrev(next, 0) 226 } 227 break 228 } 229 230 if level == 0 { 231 break 232 } 233 234 level-- 235 } 236 237 return 238 }