1/*
2 * container_comparison_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/containers/bitset.h>
12#include <roaring/containers/containers.h>
13#include <roaring/containers/mixed_equal.h>
14#include <roaring/containers/mixed_subset.h>
15#include <roaring/containers/run.h>
16
17#include "test.h"
18
19static inline void container_checked_add(void *container, uint16_t val,
20 uint8_t typecode) {
21 uint8_t new_type;
22 void *new_container = container_add(container, val, typecode, &new_type);
23 assert_int_equal(typecode, new_type);
24 assert_true(container == new_container);
25}
26
27static inline void delegated_add(void *container, uint8_t typecode,
28 uint16_t val) {
29 switch(typecode) {
30 case BITSET_CONTAINER_TYPE_CODE:
31 bitset_container_add((bitset_container_t*)container, val);
32 break;
33 case ARRAY_CONTAINER_TYPE_CODE:
34 array_container_add((array_container_t*)container, val);
35 break;
36 case RUN_CONTAINER_TYPE_CODE:
37 run_container_add((run_container_t*)container, val);
38 break;
39 default:
40 assert(false);
41 __builtin_unreachable();
42 }
43}
44
45static inline void *container_create(uint8_t typecode) {
46 void *result = NULL;
47 switch (typecode) {
48 case BITSET_CONTAINER_TYPE_CODE:
49 result = bitset_container_create();
50 break;
51 case ARRAY_CONTAINER_TYPE_CODE:
52 result = array_container_create();
53 break;
54 case RUN_CONTAINER_TYPE_CODE:
55 result = run_container_create();
56 break;
57 default:
58 assert(false);
59 __builtin_unreachable();
60 }
61 assert_non_null(result);
62 return result;
63}
64
65void generic_equal_test(uint8_t type1, uint8_t type2) {
66 void *container1 = container_create(type1);
67 void *container2 = container_create(type2);
68 assert_true(container_equals(container1, type1, container2, type2));
69 for (int i = 0; i < 100; i++) {
70 container_checked_add(container1, i * 10, type1);
71 container_checked_add(container2, i * 10, type2);
72 assert_true(container_equals(container1, type1, container2, type2));
73 }
74 container_checked_add(container1, 273, type1);
75 assert_false(container_equals(container1, type1, container2, type2));
76 container_checked_add(container2, 854, type2);
77 assert_false(container_equals(container1, type1, container2, type2));
78 container_checked_add(container1, 854, type1);
79 assert_false(container_equals(container1, type1, container2, type2));
80 container_checked_add(container2, 273, type2);
81 assert_true(container_equals(container1, type1, container2, type2));
82 container_free(container1, type1);
83 container_free(container2, type2);
84
85 // full container
86 container1 = container_create(type1);
87 container2 = container_create(type2);
88 for (uint32_t i = 0; i < 65536; i++) {
89 delegated_add(container1, type1, i);
90 delegated_add(container2, type2, i);
91 }
92 assert_true(container_equals(container1, type1, container2, type2));
93 container_free(container1, type1);
94 container_free(container2, type2);
95
96 // first elements differ
97 container1 = container_create(type1);
98 container2 = container_create(type2);
99 for (int i = 0; i < 65536; i++) {
100 if (i != 0) delegated_add(container1, type1, i);
101 if (i != 1) delegated_add(container2, type2, i);
102 }
103 assert_false(container_equals(container1, type1, container2, type2));
104 container_free(container1, type1);
105 container_free(container2, type2);
106
107 // last elements differ
108 container1 = container_create(type1);
109 container2 = container_create(type2);
110 for (int i = 0; i < 65536; i++) {
111 if (i != 65534) delegated_add(container1, type1, i);
112 if (i != 65535) delegated_add(container2, type2, i);
113 }
114 assert_false(container_equals(container1, type1, container2, type2));
115 container_free(container1, type1);
116 container_free(container2, type2);
117}
118
119void equal_array_array_test() {
120 generic_equal_test(ARRAY_CONTAINER_TYPE_CODE, ARRAY_CONTAINER_TYPE_CODE);
121}
122
123void equal_bitset_bitset_test() {
124 generic_equal_test(BITSET_CONTAINER_TYPE_CODE, BITSET_CONTAINER_TYPE_CODE);
125}
126
127void equal_run_run_test() {
128 generic_equal_test(RUN_CONTAINER_TYPE_CODE, RUN_CONTAINER_TYPE_CODE);
129}
130
131void equal_array_bitset_test() {
132 generic_equal_test(ARRAY_CONTAINER_TYPE_CODE, BITSET_CONTAINER_TYPE_CODE);
133}
134
135void equal_bitset_array_test() {
136 generic_equal_test(BITSET_CONTAINER_TYPE_CODE, ARRAY_CONTAINER_TYPE_CODE);
137}
138
139void equal_array_run_test() {
140 generic_equal_test(ARRAY_CONTAINER_TYPE_CODE, RUN_CONTAINER_TYPE_CODE);
141}
142
143void equal_run_array_test() {
144 generic_equal_test(RUN_CONTAINER_TYPE_CODE, ARRAY_CONTAINER_TYPE_CODE);
145}
146
147void equal_bitset_run_test() {
148 generic_equal_test(BITSET_CONTAINER_TYPE_CODE, RUN_CONTAINER_TYPE_CODE);
149}
150
151void equal_run_bitset_test() {
152 generic_equal_test(RUN_CONTAINER_TYPE_CODE, BITSET_CONTAINER_TYPE_CODE);
153}
154
155void generic_subset_test(uint8_t type1, uint8_t type2) {
156 void *container1 = container_create(type1);
157 void *container2 = container_create(type2);
158 assert_true(container_is_subset(container1, type1, container2, type2));
159 for (int i = 0; i < 100; i++) {
160 container_checked_add(container1, i * 11, type1);
161 container_checked_add(container2, i * 11, type2);
162 assert_true(container_is_subset(container1, type1, container2, type2));
163 }
164 for (int i = 0; i < 100; i++) {
165 container_checked_add(container2, i * 7, type2);
166 assert_true(container_is_subset(container1, type1, container2, type2));
167 }
168 for (int i = 0; i < 100; i++) {
169 if (i % 7 == 0 || i % 11 == 0) continue;
170 container_checked_add(container1, i * 5, type1);
171 assert_false(container_is_subset(container1, type1, container2, type2));
172 container_checked_add(container2, i * 5, type2);
173 assert_true(container_is_subset(container1, type1, container2, type2));
174 }
175 container_free(container1, type1);
176 container_free(container2, type2);
177}
178
179void subset_array_array_test() {
180 generic_subset_test(ARRAY_CONTAINER_TYPE_CODE, ARRAY_CONTAINER_TYPE_CODE);
181}
182
183void subset_bitset_bitset_test() {
184 generic_subset_test(BITSET_CONTAINER_TYPE_CODE, BITSET_CONTAINER_TYPE_CODE);
185}
186
187void subset_run_run_test() {
188 generic_subset_test(RUN_CONTAINER_TYPE_CODE, RUN_CONTAINER_TYPE_CODE);
189}
190
191void subset_array_bitset_test() {
192 generic_subset_test(ARRAY_CONTAINER_TYPE_CODE, BITSET_CONTAINER_TYPE_CODE);
193}
194
195void subset_array_run_test() {
196 generic_subset_test(ARRAY_CONTAINER_TYPE_CODE, RUN_CONTAINER_TYPE_CODE);
197}
198
199void subset_run_array_test() {
200 generic_subset_test(RUN_CONTAINER_TYPE_CODE, ARRAY_CONTAINER_TYPE_CODE);
201}
202
203void subset_bitset_run_test() {
204 generic_subset_test(BITSET_CONTAINER_TYPE_CODE, RUN_CONTAINER_TYPE_CODE);
205}
206
207void subset_run_bitset_test() {
208 generic_subset_test(RUN_CONTAINER_TYPE_CODE, BITSET_CONTAINER_TYPE_CODE);
209}
210
211int main() {
212 const struct CMUnitTest tests[] = {
213 cmocka_unit_test(equal_array_array_test),
214 cmocka_unit_test(equal_bitset_bitset_test),
215 cmocka_unit_test(equal_run_run_test),
216 cmocka_unit_test(equal_array_bitset_test),
217 cmocka_unit_test(equal_bitset_array_test),
218 cmocka_unit_test(equal_array_run_test),
219 cmocka_unit_test(equal_run_array_test),
220 cmocka_unit_test(equal_bitset_run_test),
221 cmocka_unit_test(equal_run_bitset_test),
222 cmocka_unit_test(subset_array_array_test),
223 cmocka_unit_test(subset_bitset_bitset_test),
224 cmocka_unit_test(subset_run_run_test),
225 cmocka_unit_test(subset_array_bitset_test),
226 cmocka_unit_test(subset_array_run_test),
227 cmocka_unit_test(subset_run_array_test),
228 cmocka_unit_test(subset_bitset_run_test),
229 cmocka_unit_test(subset_run_bitset_test),
230 };
231
232 return cmocka_run_group_tests(tests, NULL, NULL);
233}
234