Coverage Report

Created: 2020-05-07 18:36

/proc/self/cwd/c/pq.c
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
}