1/*
2 * array_container_unit.c
3 *
4 */
5
6#include <stdint.h>
7#include <stdio.h>
8#include <stdlib.h>
9
10#include <roaring/containers/array.h>
11#include <roaring/misc/configreport.h>
12
13#include "test.h"
14
15void printf_test() {
16 array_container_t* B = array_container_create();
17 assert_non_null(B);
18
19 array_container_add(B, 1U);
20 array_container_add(B, 2U);
21 array_container_add(B, 3U);
22 array_container_add(B, 10U);
23 array_container_add(B, 10000U);
24
25 array_container_printf(B);
26 printf("\n");
27
28 array_container_free(B);
29}
30
31void add_contains_test() {
32 array_container_t* B = array_container_create();
33 assert_non_null(B);
34
35 int expected_card = 0;
36
37 for (size_t x = 0; x < 1 << 16; x += 3) {
38 assert_true(array_container_add(B, x));
39 assert_true(array_container_contains(B, x));
40 assert_int_equal(B->cardinality, ++expected_card);
41 assert_false(B->cardinality > B->capacity);
42 }
43
44 for (size_t x = 0; x < 1 << 16; x++) {
45 assert_int_equal(array_container_contains(B, x), (x / 3 * 3 == x));
46 }
47
48 assert_int_equal(array_container_cardinality(B), (1 << 16) / 3 + 1);
49
50 for (size_t x = 0; x < 1 << 16; x += 3) {
51 assert_true(array_container_contains(B, x));
52 assert_true(array_container_remove(B, x));
53 assert_int_equal(B->cardinality, --expected_card);
54 assert_false(array_container_contains(B, x));
55 }
56
57 assert_int_equal(array_container_cardinality(B), 0);
58
59 for (int x = 65535; x >= 0; x -= 3) {
60 assert_true(array_container_add(B, x));
61 assert_true(array_container_contains(B, x));
62 assert_int_equal(B->cardinality, ++expected_card);
63 assert_false(B->cardinality > B->capacity);
64 }
65
66 assert_int_equal(array_container_cardinality(B), expected_card);
67
68 for (size_t x = 0; x < 1 << 16; x++) {
69 assert_int_equal(array_container_contains(B, x), (x / 3 * 3 == x));
70 }
71
72 for (size_t x = 0; x < 1 << 16; x += 3) {
73 assert_true(array_container_contains(B, x));
74 assert_true(array_container_remove(B, x));
75 assert_int_equal(B->cardinality, --expected_card);
76 assert_false(array_container_contains(B, x));
77 }
78
79 array_container_free(B);
80}
81
82void and_or_test() {
83 DESCRIBE_TEST;
84
85 array_container_t* B1 = array_container_create();
86 array_container_t* B2 = array_container_create();
87 array_container_t* BI = array_container_create();
88 array_container_t* BO = array_container_create();
89 array_container_t* TMP = array_container_create();
90
91 assert_non_null(B1);
92 assert_non_null(B2);
93 assert_non_null(BI);
94 assert_non_null(BO);
95 assert_non_null(TMP);
96
97 for (size_t x = 0; x < (1 << 16); x += 17) {
98 array_container_add(B1, x);
99 array_container_add(BI, x);
100 }
101
102 // important: 62 is not divisible by 3
103 for (size_t x = 0; x < (1 << 16); x += 62) {
104 array_container_add(B2, x);
105 array_container_add(BI, x);
106 }
107
108 for (size_t x = 0; x < (1 << 16); x += 62 * 17) {
109 array_container_add(BO, x);
110 }
111
112 const int card_inter = array_container_cardinality(BO);
113 const int card_union = array_container_cardinality(BI);
114
115 array_container_intersection(B1, B2, TMP);
116 assert_int_equal(card_inter, array_container_cardinality(TMP));
117 assert_true(array_container_equals(BO, TMP));
118
119 array_container_union(B1, B2, TMP);
120 assert_int_equal(card_union, array_container_cardinality(TMP));
121 assert_true(array_container_equals(BI, TMP));
122
123 array_container_free(B1);
124 array_container_free(B2);
125 array_container_free(BI);
126 array_container_free(BO);
127 array_container_free(TMP);
128}
129
130void to_uint32_array_test() {
131 for (size_t offset = 1; offset < 128; offset *= 2) {
132 array_container_t* B = array_container_create();
133 assert_non_null(B);
134
135 for (size_t k = 0; k < (1 << 16); k += offset) {
136 assert_true(array_container_add(B, k));
137 }
138
139 int card = array_container_cardinality(B);
140 uint32_t* out = malloc(sizeof(uint32_t) * card);
141 assert_non_null(out);
142 int nc = array_container_to_uint32_array(out, B, 0);
143
144 assert_int_equal(card, nc);
145
146 for (int k = 1; k < nc; ++k) {
147 assert_int_equal(out[k], offset + out[k - 1]);
148 }
149
150 free(out);
151 array_container_free(B);
152 }
153}
154
155void select_test() {
156 array_container_t* B = array_container_create();
157 assert_non_null(B);
158 uint16_t base = 27;
159 for (uint16_t value = base; value < base + 200; value += 5) {
160 array_container_add(B, value);
161 }
162 uint32_t i = 0;
163 uint32_t element = 0;
164 uint32_t start_rank;
165 for (uint16_t value = base; value < base + 200; value += 5) {
166 start_rank = 12;
167 assert_true(array_container_select(B, &start_rank, i + 12, &element));
168 assert_int_equal(element, value);
169 i++;
170 }
171 start_rank = 12;
172 assert_false(array_container_select(B, &start_rank, i + 12, &element));
173 assert_int_equal(start_rank, i + 12);
174 array_container_free(B);
175}
176
177void capacity_test() {
178 array_container_t* array = array_container_create();
179 for (uint32_t i = 0; i < DEFAULT_MAX_SIZE; i++) {
180 array_container_add(array, (uint16_t)i);
181 assert_true(array->capacity <= DEFAULT_MAX_SIZE);
182 }
183 for (uint32_t i = DEFAULT_MAX_SIZE; i < 65536; i++) {
184 array_container_add(array, (uint16_t)i);
185 assert_true(array->capacity <= 65536);
186 }
187 array_container_free(array);
188}
189
190int main() {
191 const struct CMUnitTest tests[] = {
192 cmocka_unit_test(printf_test), cmocka_unit_test(add_contains_test),
193 cmocka_unit_test(and_or_test), cmocka_unit_test(to_uint32_array_test),
194 cmocka_unit_test(select_test),
195 cmocka_unit_test(capacity_test)
196 };
197
198 return cmocka_run_group_tests(tests, NULL, NULL);
199}
200