Skip to content

Commit 3763030

Browse files
committed
search: Add tests.
1 parent dd00a76 commit 3763030

File tree

2 files changed

+109
-0
lines changed

2 files changed

+109
-0
lines changed

test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ set(tests_c
2020
# rng_mt_test.c
2121
runif_getf_test.c
2222
runif_geti_test.c
23+
search_test.c
2324
time_test1.c
2425
util_test0.c
2526
x_asprintf_test.c

test/search_test.c

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/* Tests for the Bsearch and Lsearch macros */
2+
3+
#include <stdio.h>
4+
#include <stdlib.h>
5+
#include <inttypes.h>
6+
7+
#define CSNIP_SHORT_NAMES
8+
#include <csnip/mem.h>
9+
#include <csnip/search.h>
10+
#include <csnip/sort.h>
11+
#include <csnip/util.h>
12+
13+
static uint32_t rnext(uint64_t* pstate)
14+
{
15+
*pstate *= UINT64_C(6364136223846793005);
16+
*pstate += 1;
17+
18+
return (uint32_t)(*pstate >> 32);
19+
}
20+
21+
static uint32_t reduce_to_bits(int n_bits, uint32_t v)
22+
{
23+
if (n_bits == 0)
24+
return 0;
25+
return v >> (32 - n_bits);
26+
}
27+
28+
int main(int argc, char** argv)
29+
{
30+
uint64_t rstate = 1234;
31+
const int Ns[] = { 0, 1, 2, 3, 10, 100, 1000 };
32+
const int bs[] = { 0, 1, 2, 3, 4, 8, 16, 32 };
33+
int k = 3;
34+
35+
for (int Ni = 0; Ni < Static_len(Ns); ++Ni) {
36+
const int N = Ns[Ni];
37+
printf("N = %d\n", N);
38+
39+
/* Create the instance */
40+
uint32_t* a;
41+
mem_Alloc(N, a, _);
42+
for (int i = 0; i < N; ++i) {
43+
a[i] = rnext(&rstate);
44+
}
45+
Qsort(u, v, a[u] < a[v], Tswap(uint32_t, a[u], a[v]), N);
46+
47+
/* Check with different bit widths.
48+
*
49+
* The point here is that down projecting to a fixed
50+
* number of bits causes progressively more comparisons
51+
* to the same values, which changes the nature of the
52+
* search.
53+
*/
54+
for (int bi = 0; bi < Static_len(bs); ++bi) {
55+
const int b = bs[bi];
56+
printf(" b = %d\n", b);
57+
for (int i = 0; i < k; ++i) {
58+
int idx;
59+
#define red(x) reduce_to_bits(b, (x))
60+
uint32_t d = red(rnext(&rstate));
61+
62+
/* Variant 1: smallest i s.t. a[i] >= key */
63+
Bsearch(int, u, red(a[u]) < d, N, idx);
64+
printf(" d = %"PRIu32" -> V1_idx = %d ", d, idx);
65+
if (idx < 0 || idx > N) {
66+
fprintf(stderr, "Error: Result out "
67+
"of range (N = %d): %d\n", N, idx);
68+
return 1;
69+
}
70+
if (idx < N && red(a[idx]) < d) {
71+
fprintf(stderr, "Error: V1 constraint "
72+
"not met.\n");
73+
return 1;
74+
}
75+
if (idx > 0 && red(a[idx - 1]) >= d) {
76+
fprintf(stderr, "Error: V1 minimality "
77+
"not satisfied.\n");
78+
return 1;
79+
}
80+
81+
/* Variant 2: lowest i s.t. a[i] > key */
82+
Bsearch(int, u, red(a[u]) <= d, N, idx);
83+
printf("V2_idx = %d ", idx);
84+
if (idx < 0 || idx > N) {
85+
fprintf(stderr, "Error: Result out "
86+
"of range (N = %d): %d\n", N, idx);
87+
return 1;
88+
}
89+
if (idx < N && red(a[idx]) <= d) {
90+
fprintf(stderr, "Error: V2 constraint "
91+
"not met.\n");
92+
return 1;
93+
}
94+
if (idx > 0 && red(a[idx - 1]) > d) {
95+
fprintf(stderr, "Error: V2 minimality "
96+
"not satisfied.\n");
97+
return 1;
98+
}
99+
#undef red
100+
101+
putchar('\n');
102+
}
103+
104+
printf(" All checks pass.\n");
105+
}
106+
}
107+
return 0;
108+
}

0 commit comments

Comments
 (0)