Skip to content

Commit d65332f

Browse files
committed
Merge branch 'cp/unit-test-reftable-pq'
The tests for "pq" part of reftable library got rewritten to use the unit test framework. * cp/unit-test-reftable-pq: t-reftable-pq: add tests for merged_iter_pqueue_top() t-reftable-pq: add test for index based comparison t-reftable-pq: make merged_iter_pqueue_check() callable by reference t-reftable-pq: make merged_iter_pqueue_check() static t: move reftable/pq_test.c to the unit testing framework reftable: change the type of array indices to 'size_t' in reftable/pq.c reftable: remove unnecessary curly braces in reftable/pq.c
2 parents 6c3c451 + 0dc84a8 commit d65332f

File tree

7 files changed

+163
-97
lines changed

7 files changed

+163
-97
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1341,6 +1341,7 @@ UNIT_TEST_PROGRAMS += t-oidtree
13411341
UNIT_TEST_PROGRAMS += t-prio-queue
13421342
UNIT_TEST_PROGRAMS += t-reftable-basics
13431343
UNIT_TEST_PROGRAMS += t-reftable-merged
1344+
UNIT_TEST_PROGRAMS += t-reftable-pq
13441345
UNIT_TEST_PROGRAMS += t-reftable-record
13451346
UNIT_TEST_PROGRAMS += t-strbuf
13461347
UNIT_TEST_PROGRAMS += t-strcmp-offset
@@ -2681,7 +2682,6 @@ REFTABLE_OBJS += reftable/writer.o
26812682

26822683
REFTABLE_TEST_OBJS += reftable/block_test.o
26832684
REFTABLE_TEST_OBJS += reftable/dump.o
2684-
REFTABLE_TEST_OBJS += reftable/pq_test.o
26852685
REFTABLE_TEST_OBJS += reftable/readwrite_test.o
26862686
REFTABLE_TEST_OBJS += reftable/stack_test.o
26872687
REFTABLE_TEST_OBJS += reftable/test_framework.o

reftable/pq.c

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,27 +22,21 @@ int pq_less(struct pq_entry *a, struct pq_entry *b)
2222

2323
struct pq_entry merged_iter_pqueue_remove(struct merged_iter_pqueue *pq)
2424
{
25-
int i = 0;
25+
size_t i = 0;
2626
struct pq_entry e = pq->heap[0];
2727
pq->heap[0] = pq->heap[pq->len - 1];
2828
pq->len--;
2929

30-
i = 0;
3130
while (i < pq->len) {
32-
int min = i;
33-
int j = 2 * i + 1;
34-
int k = 2 * i + 2;
35-
if (j < pq->len && pq_less(&pq->heap[j], &pq->heap[i])) {
31+
size_t min = i;
32+
size_t j = 2 * i + 1;
33+
size_t k = 2 * i + 2;
34+
if (j < pq->len && pq_less(&pq->heap[j], &pq->heap[i]))
3635
min = j;
37-
}
38-
if (k < pq->len && pq_less(&pq->heap[k], &pq->heap[min])) {
36+
if (k < pq->len && pq_less(&pq->heap[k], &pq->heap[min]))
3937
min = k;
40-
}
41-
42-
if (min == i) {
38+
if (min == i)
4339
break;
44-
}
45-
4640
SWAP(pq->heap[i], pq->heap[min]);
4741
i = min;
4842
}
@@ -52,20 +46,17 @@ struct pq_entry merged_iter_pqueue_remove(struct merged_iter_pqueue *pq)
5246

5347
void merged_iter_pqueue_add(struct merged_iter_pqueue *pq, const struct pq_entry *e)
5448
{
55-
int i = 0;
49+
size_t i = 0;
5650

5751
REFTABLE_ALLOC_GROW(pq->heap, pq->len + 1, pq->cap);
5852
pq->heap[pq->len++] = *e;
5953

6054
i = pq->len - 1;
6155
while (i > 0) {
62-
int j = (i - 1) / 2;
63-
if (pq_less(&pq->heap[j], &pq->heap[i])) {
56+
size_t j = (i - 1) / 2;
57+
if (pq_less(&pq->heap[j], &pq->heap[i]))
6458
break;
65-
}
66-
6759
SWAP(pq->heap[j], pq->heap[i]);
68-
6960
i = j;
7061
}
7162
}

reftable/pq.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ struct merged_iter_pqueue {
2222
size_t cap;
2323
};
2424

25-
void merged_iter_pqueue_check(struct merged_iter_pqueue pq);
2625
struct pq_entry merged_iter_pqueue_remove(struct merged_iter_pqueue *pq);
2726
void merged_iter_pqueue_add(struct merged_iter_pqueue *pq, const struct pq_entry *e);
2827
void merged_iter_pqueue_release(struct merged_iter_pqueue *pq);

reftable/pq_test.c

Lines changed: 0 additions & 74 deletions
This file was deleted.

reftable/reftable-tests.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ license that can be found in the LICENSE file or at
1111

1212
int basics_test_main(int argc, const char **argv);
1313
int block_test_main(int argc, const char **argv);
14-
int pq_test_main(int argc, const char **argv);
1514
int record_test_main(int argc, const char **argv);
1615
int readwrite_test_main(int argc, const char **argv);
1716
int stack_test_main(int argc, const char **argv);

t/helper/test-reftable.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ int cmd__reftable(int argc, const char **argv)
77
/* test from simple to complex. */
88
block_test_main(argc, argv);
99
tree_test_main(argc, argv);
10-
pq_test_main(argc, argv);
1110
readwrite_test_main(argc, argv);
1211
stack_test_main(argc, argv);
1312
return 0;

t/unit-tests/t-reftable-pq.c

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
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 "test-lib.h"
10+
#include "reftable/constants.h"
11+
#include "reftable/pq.h"
12+
13+
static void merged_iter_pqueue_check(const struct merged_iter_pqueue *pq)
14+
{
15+
for (size_t i = 1; i < pq->len; i++) {
16+
size_t parent = (i - 1) / 2;
17+
check(pq_less(&pq->heap[parent], &pq->heap[i]));
18+
}
19+
}
20+
21+
static int pq_entry_equal(struct pq_entry *a, struct pq_entry *b)
22+
{
23+
return !reftable_record_cmp(a->rec, b->rec) && (a->index == b->index);
24+
}
25+
26+
static void t_pq_record(void)
27+
{
28+
struct merged_iter_pqueue pq = { 0 };
29+
struct reftable_record recs[54];
30+
size_t N = ARRAY_SIZE(recs) - 1, i;
31+
char *last = NULL;
32+
33+
for (i = 0; i < N; i++) {
34+
reftable_record_init(&recs[i], BLOCK_TYPE_REF);
35+
recs[i].u.ref.refname = xstrfmt("%02"PRIuMAX, (uintmax_t)i);
36+
}
37+
38+
i = 1;
39+
do {
40+
struct pq_entry e = {
41+
.rec = &recs[i],
42+
};
43+
44+
merged_iter_pqueue_add(&pq, &e);
45+
merged_iter_pqueue_check(&pq);
46+
i = (i * 7) % N;
47+
} while (i != 1);
48+
49+
while (!merged_iter_pqueue_is_empty(pq)) {
50+
struct pq_entry top = merged_iter_pqueue_top(pq);
51+
struct pq_entry e = merged_iter_pqueue_remove(&pq);
52+
merged_iter_pqueue_check(&pq);
53+
54+
check(pq_entry_equal(&top, &e));
55+
check(reftable_record_type(e.rec) == BLOCK_TYPE_REF);
56+
if (last)
57+
check_int(strcmp(last, e.rec->u.ref.refname), <, 0);
58+
last = e.rec->u.ref.refname;
59+
}
60+
61+
for (i = 0; i < N; i++)
62+
reftable_record_release(&recs[i]);
63+
merged_iter_pqueue_release(&pq);
64+
}
65+
66+
static void t_pq_index(void)
67+
{
68+
struct merged_iter_pqueue pq = { 0 };
69+
struct reftable_record recs[13];
70+
char *last = NULL;
71+
size_t N = ARRAY_SIZE(recs), i;
72+
73+
for (i = 0; i < N; i++) {
74+
reftable_record_init(&recs[i], BLOCK_TYPE_REF);
75+
recs[i].u.ref.refname = (char *) "refs/heads/master";
76+
}
77+
78+
i = 1;
79+
do {
80+
struct pq_entry e = {
81+
.rec = &recs[i],
82+
.index = i,
83+
};
84+
85+
merged_iter_pqueue_add(&pq, &e);
86+
merged_iter_pqueue_check(&pq);
87+
i = (i * 7) % N;
88+
} while (i != 1);
89+
90+
for (i = N - 1; i > 0; i--) {
91+
struct pq_entry top = merged_iter_pqueue_top(pq);
92+
struct pq_entry e = merged_iter_pqueue_remove(&pq);
93+
merged_iter_pqueue_check(&pq);
94+
95+
check(pq_entry_equal(&top, &e));
96+
check(reftable_record_type(e.rec) == BLOCK_TYPE_REF);
97+
check_int(e.index, ==, i);
98+
if (last)
99+
check_str(last, e.rec->u.ref.refname);
100+
last = e.rec->u.ref.refname;
101+
}
102+
103+
merged_iter_pqueue_release(&pq);
104+
}
105+
106+
static void t_merged_iter_pqueue_top(void)
107+
{
108+
struct merged_iter_pqueue pq = { 0 };
109+
struct reftable_record recs[13];
110+
size_t N = ARRAY_SIZE(recs), i;
111+
112+
for (i = 0; i < N; i++) {
113+
reftable_record_init(&recs[i], BLOCK_TYPE_REF);
114+
recs[i].u.ref.refname = (char *) "refs/heads/master";
115+
}
116+
117+
i = 1;
118+
do {
119+
struct pq_entry e = {
120+
.rec = &recs[i],
121+
.index = i,
122+
};
123+
124+
merged_iter_pqueue_add(&pq, &e);
125+
merged_iter_pqueue_check(&pq);
126+
i = (i * 7) % N;
127+
} while (i != 1);
128+
129+
for (i = N - 1; i > 0; i--) {
130+
struct pq_entry top = merged_iter_pqueue_top(pq);
131+
struct pq_entry e = merged_iter_pqueue_remove(&pq);
132+
133+
merged_iter_pqueue_check(&pq);
134+
check(pq_entry_equal(&top, &e));
135+
check(reftable_record_equal(top.rec, &recs[i], GIT_SHA1_RAWSZ));
136+
for (size_t j = 0; i < pq.len; j++) {
137+
check(pq_less(&top, &pq.heap[j]));
138+
check_int(top.index, >, j);
139+
}
140+
}
141+
142+
merged_iter_pqueue_release(&pq);
143+
}
144+
145+
int cmd_main(int argc, const char *argv[])
146+
{
147+
TEST(t_pq_record(), "pq works with record-based comparison");
148+
TEST(t_pq_index(), "pq works with index-based comparison");
149+
TEST(t_merged_iter_pqueue_top(), "merged_iter_pqueue_top works");
150+
151+
return test_done();
152+
}

0 commit comments

Comments
 (0)