github.com/zuoyebang/bitalosdb@v1.1.1-0.20240516111551-79a8c4d8ce20/bitpage/merging_iter_heap.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 "github.com/zuoyebang/bitalosdb/internal/base" 18 19 type mergingIterItem struct { 20 index int 21 key internalKey 22 value []byte 23 } 24 25 type mergingIterHeap struct { 26 cmp base.Compare 27 reverse bool 28 items []mergingIterItem 29 } 30 31 func (h *mergingIterHeap) len() int { 32 return len(h.items) 33 } 34 35 func (h *mergingIterHeap) clear() { 36 h.items = h.items[:0] 37 } 38 39 func (h *mergingIterHeap) less(i, j int) bool { 40 ikey, jkey := h.items[i].key, h.items[j].key 41 if c := h.cmp(ikey.UserKey, jkey.UserKey); c != 0 { 42 if h.reverse { 43 return c > 0 44 } 45 return c < 0 46 } 47 if h.reverse { 48 return ikey.Trailer < jkey.Trailer 49 } 50 return ikey.Trailer > jkey.Trailer 51 } 52 53 func (h *mergingIterHeap) swap(i, j int) { 54 h.items[i], h.items[j] = h.items[j], h.items[i] 55 } 56 57 func (h *mergingIterHeap) init() { 58 n := h.len() 59 for i := n/2 - 1; i >= 0; i-- { 60 h.down(i, n) 61 } 62 } 63 64 func (h *mergingIterHeap) fix(i int) { 65 if !h.down(i, h.len()) { 66 h.up(i) 67 } 68 } 69 70 func (h *mergingIterHeap) pop() *mergingIterItem { 71 n := h.len() - 1 72 h.swap(0, n) 73 h.down(0, n) 74 item := &h.items[n] 75 h.items = h.items[:n] 76 return item 77 } 78 79 func (h *mergingIterHeap) up(j int) { 80 for { 81 i := (j - 1) / 2 // parent 82 if i == j || !h.less(j, i) { 83 break 84 } 85 h.swap(i, j) 86 j = i 87 } 88 } 89 90 func (h *mergingIterHeap) down(i0, n int) bool { 91 i := i0 92 for { 93 j1 := 2*i + 1 94 if j1 >= n || j1 < 0 { 95 break 96 } 97 j := j1 98 if j2 := j1 + 1; j2 < n && h.less(j2, j1) { 99 j = j2 100 } 101 if !h.less(j, i) { 102 break 103 } 104 h.swap(i, j) 105 i = j 106 } 107 return i > i0 108 }