Line | Count | Source |
1 | | /* |
2 | | Copyright 2020 Google LLC |
3 | | |
4 | | Use of this source code is governed by a BSD-style |
5 | | license that can be found in the LICENSE file or at |
6 | | https://developers.google.com/open-source/licenses/bsd |
7 | | */ |
8 | | |
9 | | #include "pq.h" |
10 | | |
11 | | #include "system.h" |
12 | | |
13 | | int pq_less(struct pq_entry a, struct pq_entry b) |
14 | 2.73k | { |
15 | 2.73k | struct slice ak = { 0 }; |
16 | 2.73k | struct slice bk = { 0 }; |
17 | 2.73k | int cmp = 0; |
18 | 2.73k | record_key(a.rec, &ak); |
19 | 2.73k | record_key(b.rec, &bk); |
20 | 2.73k | |
21 | 2.73k | cmp = slice_compare(ak, bk); |
22 | 2.73k | |
23 | 2.73k | slice_clear(&ak); |
24 | 2.73k | slice_clear(&bk); |
25 | 2.73k | |
26 | 2.73k | if (cmp == 0) { |
27 | 6 | return a.index > b.index; |
28 | 6 | } |
29 | 2.72k | |
30 | 2.72k | return cmp < 0; |
31 | 2.72k | } |
32 | | |
33 | | struct pq_entry merged_iter_pqueue_top(struct merged_iter_pqueue pq) |
34 | 592 | { |
35 | 592 | return pq.heap[0]; |
36 | 592 | } |
37 | | |
38 | | bool merged_iter_pqueue_is_empty(struct merged_iter_pqueue pq) |
39 | 2.27k | { |
40 | 2.27k | return pq.len == 0; |
41 | 2.27k | } |
42 | | |
43 | | void merged_iter_pqueue_check(struct merged_iter_pqueue pq) |
44 | 52 | { |
45 | 52 | int i = 0; |
46 | 677 | for (i = 1; i < pq.len; i++) { |
47 | 625 | int parent = (i - 1) / 2; |
48 | 625 | |
49 | 625 | assert(pq_less(pq.heap[parent], pq.heap[i])); |
50 | 625 | } |
51 | 52 | } |
52 | | |
53 | | struct pq_entry merged_iter_pqueue_remove(struct merged_iter_pqueue *pq) |
54 | 696 | { |
55 | 696 | int i = 0; |
56 | 696 | struct pq_entry e = pq->heap[0]; |
57 | 696 | pq->heap[0] = pq->heap[pq->len - 1]; |
58 | 696 | pq->len--; |
59 | 696 | |
60 | 696 | i = 0; |
61 | 1.15k | while (i < pq->len) { |
62 | 1.03k | int min = i; |
63 | 1.03k | int j = 2 * i + 1; |
64 | 1.03k | int k = 2 * i + 2; |
65 | 1.03k | if (j < pq->len && pq_less(pq->heap[j], pq->heap[i])) { |
66 | 374 | min = j; |
67 | 374 | } |
68 | 1.03k | if (k < pq->len && pq_less(pq->heap[k], pq->heap[min])) { |
69 | 138 | min = k; |
70 | 138 | } |
71 | 1.03k | |
72 | 1.03k | if (min == i) { |
73 | 577 | break; |
74 | 577 | } |
75 | 454 | |
76 | 908 | SWAP(pq->heap[i], pq->heap[min]); |
77 | 908 | i = min; |
78 | 908 | } |
79 | 696 | |
80 | 696 | return e; |
81 | 696 | } |
82 | | |
83 | | void merged_iter_pqueue_add(struct merged_iter_pqueue *pq, struct pq_entry e) |
84 | 1.00k | { |
85 | 1.00k | int i = 0; |
86 | 1.00k | if (pq->len == pq->cap) { |
87 | 393 | pq->cap = 2 * pq->cap + 1; |
88 | 393 | pq->heap = reftable_realloc(pq->heap, |
89 | 393 | pq->cap * sizeof(struct pq_entry)); |
90 | 393 | } |
91 | 1.00k | |
92 | 1.00k | pq->heap[pq->len++] = e; |
93 | 1.00k | i = pq->len - 1; |
94 | 1.73k | while (i > 0) { |
95 | 1.08k | int j = (i - 1) / 2; |
96 | 1.08k | if (pq_less(pq->heap[j], pq->heap[i])) { |
97 | 348 | break; |
98 | 348 | } |
99 | 737 | |
100 | 1.47k | SWAP(pq->heap[j], pq->heap[i]); |
101 | 1.47k | |
102 | 1.47k | i = j; |
103 | 1.47k | } |
104 | 1.00k | } |
105 | | |
106 | | void merged_iter_pqueue_clear(struct merged_iter_pqueue *pq) |
107 | 365 | { |
108 | 365 | int i = 0; |
109 | 671 | for (i = 0; i < pq->len; i++) { |
110 | 306 | record_destroy(&pq->heap[i].rec); |
111 | 306 | } |
112 | 365 | FREE_AND_NULL(pq->heap); |
113 | 365 | pq->len = pq->cap = 0; |
114 | 365 | } |