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  }