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