github.com/zuoyebang/bitalosdb@v1.1.1-0.20240516111551-79a8c4d8ce20/bitpage/merging_iter.go (about) 1 // Copyright 2021 The Bitalosdb author(hustxrb@163.com) and other contributors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package bitpage 16 17 import ( 18 "bytes" 19 "errors" 20 "fmt" 21 "runtime/debug" 22 23 "github.com/zuoyebang/bitalosdb/internal/base" 24 "github.com/zuoyebang/bitalosdb/internal/invariants" 25 "github.com/zuoyebang/bitalosdb/internal/utils" 26 ) 27 28 type mergingIterLevel struct { 29 iter internalIterator 30 iterKey *internalKey 31 iterValue []byte 32 } 33 34 type mergingIter struct { 35 logger base.Logger 36 dir int 37 levels []mergingIterLevel 38 heap mergingIterHeap 39 err error 40 prefix []byte 41 lower []byte 42 upper []byte 43 } 44 45 var _ base.InternalIterator = (*mergingIter)(nil) 46 47 func newMergingIter( 48 logger base.Logger, cmp base.Compare, iters ...internalIterator, 49 ) *mergingIter { 50 m := &mergingIter{} 51 levels := make([]mergingIterLevel, len(iters)) 52 for i := range levels { 53 levels[i].iter = iters[i] 54 } 55 m.Init(&iterOptions{Logger: logger}, cmp, levels...) 56 return m 57 } 58 59 func (m *mergingIter) Init( 60 opts *iterOptions, cmp base.Compare, levels ...mergingIterLevel, 61 ) { 62 m.err = nil 63 m.logger = opts.GetLogger() 64 if opts != nil { 65 m.lower = opts.LowerBound 66 m.upper = opts.UpperBound 67 } 68 m.levels = levels 69 m.heap.cmp = cmp 70 if cap(m.heap.items) < len(levels) { 71 m.heap.items = make([]mergingIterItem, 0, len(levels)) 72 } else { 73 m.heap.items = m.heap.items[:0] 74 } 75 } 76 77 func (m *mergingIter) initHeap() { 78 m.heap.items = m.heap.items[:0] 79 for i := range m.levels { 80 if l := &m.levels[i]; l.iterKey != nil { 81 m.heap.items = append(m.heap.items, mergingIterItem{ 82 index: i, 83 key: *l.iterKey, 84 value: l.iterValue, 85 }) 86 } else { 87 m.err = utils.FirstError(m.err, l.iter.Error()) 88 if m.err != nil { 89 return 90 } 91 } 92 } 93 m.heap.init() 94 } 95 96 func (m *mergingIter) initMinHeap() { 97 m.dir = 1 98 m.heap.reverse = false 99 m.initHeap() 100 } 101 102 func (m *mergingIter) initMaxHeap() { 103 m.dir = -1 104 m.heap.reverse = true 105 m.initHeap() 106 } 107 108 func (m *mergingIter) switchToMinHeap() { 109 if m.heap.len() == 0 { 110 if m.lower != nil { 111 m.SeekGE(m.lower) 112 } else { 113 m.First() 114 } 115 return 116 } 117 118 key := m.heap.items[0].key 119 cur := &m.levels[m.heap.items[0].index] 120 121 for i := range m.levels { 122 l := &m.levels[i] 123 if l == cur { 124 continue 125 } 126 127 if l.iterKey == nil { 128 if m.lower != nil { 129 l.iterKey, l.iterValue = l.iter.SeekGE(m.lower) 130 } else { 131 l.iterKey, l.iterValue = l.iter.First() 132 } 133 } 134 for ; l.iterKey != nil; l.iterKey, l.iterValue = l.iter.Next() { 135 if base.InternalCompare(m.heap.cmp, key, *l.iterKey) < 0 { 136 break 137 } 138 } 139 } 140 141 cur.iterKey, cur.iterValue = cur.iter.Next() 142 m.initMinHeap() 143 } 144 145 func (m *mergingIter) switchToMaxHeap() { 146 if m.heap.len() == 0 { 147 if m.upper != nil { 148 m.SeekLT(m.upper) 149 } else { 150 m.Last() 151 } 152 return 153 } 154 155 key := m.heap.items[0].key 156 cur := &m.levels[m.heap.items[0].index] 157 158 for i := range m.levels { 159 l := &m.levels[i] 160 if l == cur { 161 continue 162 } 163 164 if l.iterKey == nil { 165 if m.upper != nil { 166 l.iterKey, l.iterValue = l.iter.SeekLT(m.upper) 167 } else { 168 l.iterKey, l.iterValue = l.iter.Last() 169 } 170 } 171 for ; l.iterKey != nil; l.iterKey, l.iterValue = l.iter.Prev() { 172 if base.InternalCompare(m.heap.cmp, key, *l.iterKey) > 0 { 173 break 174 } 175 } 176 } 177 178 cur.iterKey, cur.iterValue = cur.iter.Prev() 179 m.initMaxHeap() 180 } 181 182 func (m *mergingIter) nextEntry(item *mergingIterItem) { 183 l := &m.levels[item.index] 184 if l.iterKey, l.iterValue = l.iter.Next(); l.iterKey != nil { 185 item.key, item.value = *l.iterKey, l.iterValue 186 if m.heap.len() > 1 { 187 m.heap.fix(0) 188 } 189 } else { 190 m.err = l.iter.Error() 191 if m.err == nil { 192 m.heap.pop() 193 } 194 } 195 } 196 197 func (m *mergingIter) findNextEntry() (*internalKey, []byte) { 198 for m.heap.len() > 0 && m.err == nil { 199 item := &m.heap.items[0] 200 return &item.key, item.value 201 } 202 return nil, nil 203 } 204 205 func (m *mergingIter) prevEntry(item *mergingIterItem) { 206 l := &m.levels[item.index] 207 if l.iterKey, l.iterValue = l.iter.Prev(); l.iterKey != nil { 208 item.key, item.value = *l.iterKey, l.iterValue 209 if m.heap.len() > 1 { 210 m.heap.fix(0) 211 } 212 } else { 213 m.err = l.iter.Error() 214 if m.err == nil { 215 m.heap.pop() 216 } 217 } 218 } 219 220 func (m *mergingIter) findPrevEntry() (*internalKey, []byte) { 221 for m.heap.len() > 0 && m.err == nil { 222 item := &m.heap.items[0] 223 return &item.key, item.value 224 } 225 return nil, nil 226 } 227 228 func (m *mergingIter) seekGE(key []byte, level int, trySeekUsingNext bool) { 229 for ; level < len(m.levels); level++ { 230 if invariants.Enabled && m.lower != nil && m.heap.cmp(key, m.lower) < 0 { 231 m.logger.Fatalf("mergingIter: lower bound violation: %s < %s\n%s", key, m.lower, debug.Stack()) 232 } 233 234 l := &m.levels[level] 235 if m.prefix != nil { 236 l.iterKey, l.iterValue = l.iter.SeekPrefixGE(m.prefix, key, trySeekUsingNext) 237 } else { 238 l.iterKey, l.iterValue = l.iter.SeekGE(key) 239 } 240 } 241 242 m.initMinHeap() 243 } 244 245 func (m *mergingIter) String() string { 246 return "merging" 247 } 248 249 func (m *mergingIter) SeekGE(key []byte) (*internalKey, []byte) { 250 m.err = nil 251 m.prefix = nil 252 m.seekGE(key, 0, false) 253 return m.findNextEntry() 254 } 255 256 func (m *mergingIter) SeekPrefixGE( 257 prefix, key []byte, trySeekUsingNext bool, 258 ) (*base.InternalKey, []byte) { 259 m.err = nil 260 m.prefix = prefix 261 m.seekGE(key, 0, trySeekUsingNext) 262 return m.findNextEntry() 263 } 264 265 func (m *mergingIter) seekLT(key []byte, level int) { 266 m.prefix = nil 267 for ; level < len(m.levels); level++ { 268 if invariants.Enabled && m.upper != nil && m.heap.cmp(key, m.upper) > 0 { 269 m.logger.Fatalf("mergingIter: upper bound violation: %s > %s\n%s", key, m.upper, debug.Stack()) 270 } 271 272 l := &m.levels[level] 273 l.iterKey, l.iterValue = l.iter.SeekLT(key) 274 } 275 276 m.initMaxHeap() 277 } 278 279 func (m *mergingIter) SeekLT(key []byte) (*internalKey, []byte) { 280 m.err = nil 281 m.prefix = nil 282 m.seekLT(key, 0) 283 return m.findPrevEntry() 284 } 285 286 func (m *mergingIter) First() (*internalKey, []byte) { 287 m.err = nil 288 m.prefix = nil 289 m.heap.items = m.heap.items[:0] 290 for i := range m.levels { 291 l := &m.levels[i] 292 l.iterKey, l.iterValue = l.iter.First() 293 } 294 m.initMinHeap() 295 return m.findNextEntry() 296 } 297 298 func (m *mergingIter) Last() (*internalKey, []byte) { 299 m.err = nil 300 m.prefix = nil 301 for i := range m.levels { 302 l := &m.levels[i] 303 l.iterKey, l.iterValue = l.iter.Last() 304 } 305 m.initMaxHeap() 306 return m.findPrevEntry() 307 } 308 309 func (m *mergingIter) Next() (*internalKey, []byte) { 310 if m.err != nil { 311 return nil, nil 312 } 313 314 if m.dir != 1 { 315 m.switchToMinHeap() 316 return m.findNextEntry() 317 } 318 319 if m.heap.len() == 0 { 320 return nil, nil 321 } 322 323 m.nextEntry(&m.heap.items[0]) 324 return m.findNextEntry() 325 } 326 327 func (m *mergingIter) Prev() (*internalKey, []byte) { 328 if m.err != nil { 329 return nil, nil 330 } 331 332 if m.dir != -1 { 333 if m.prefix != nil { 334 m.err = errors.New("bitalosdb: unsupported reverse prefix iteration") 335 return nil, nil 336 } 337 m.switchToMaxHeap() 338 return m.findPrevEntry() 339 } 340 341 if m.heap.len() == 0 { 342 return nil, nil 343 } 344 345 m.prevEntry(&m.heap.items[0]) 346 return m.findPrevEntry() 347 } 348 349 func (m *mergingIter) Error() error { 350 if m.heap.len() == 0 || m.err != nil { 351 return m.err 352 } 353 return m.levels[m.heap.items[0].index].iter.Error() 354 } 355 356 func (m *mergingIter) Close() error { 357 for i := range m.levels { 358 iter := m.levels[i].iter 359 if err := iter.Close(); err != nil && m.err == nil { 360 m.err = err 361 } 362 } 363 m.levels = nil 364 m.heap.items = m.heap.items[:0] 365 return m.err 366 } 367 368 func (m *mergingIter) SetBounds(lower, upper []byte) { 369 m.prefix = nil 370 m.lower = lower 371 m.upper = upper 372 for i := range m.levels { 373 m.levels[i].iter.SetBounds(lower, upper) 374 } 375 m.heap.clear() 376 } 377 378 func (m *mergingIter) DebugString() string { 379 var buf bytes.Buffer 380 sep := "" 381 for m.heap.len() > 0 { 382 item := m.heap.pop() 383 fmt.Fprintf(&buf, "%s%s", sep, item.key) 384 sep = " " 385 } 386 if m.dir == 1 { 387 m.initMinHeap() 388 } else { 389 m.initMaxHeap() 390 } 391 return buf.String() 392 }