// returns 0 on error, 1 if ok. int and_or_test() { bitset_container_t* B1 = bitset_container_create(); bitset_container_t* B2 = bitset_container_create(); bitset_container_t* BI = bitset_container_create(); bitset_container_t* BO = bitset_container_create(); int x, c, ci, co; printf("[%s] %s\n", __FILE__, __func__); if ((B1 == NULL) || (B2 == NULL) || (BO == NULL) || (BI == NULL)) { printf("Bug %s, line %d \n", __FILE__, __LINE__); return 0; } for (x = 0; x < (1 << 16); x += 3) { bitset_container_set(B1, (uint16_t)x); bitset_container_set(BI, (uint16_t)x); } for (x = 0; x < (1 << 16); x += 62) { // important: 62 is not divisible by 3 bitset_container_set(B2, (uint16_t)x); bitset_container_set(BI, (uint16_t)x); } for (x = 0; x < (1 << 16); x += 62 * 3) { bitset_container_set(BO, (uint16_t)x); } // we interleave O and I on purpose (to trigger bugs!) ci = bitset_container_compute_cardinality(BO); // expected intersection co = bitset_container_compute_cardinality(BI); // expected union bitset_container_and_nocard(B1, B2, BI); c = bitset_container_compute_cardinality(BI); if (c != ci) { printf("Bug %s, line %d \n", __FILE__, __LINE__); return 0; } c = bitset_container_and(B1, B2, BI); ; if (c != ci) { printf("Bug %s, line %d \n", __FILE__, __LINE__); return 0; } bitset_container_or_nocard(B1, B2, BO); c = bitset_container_compute_cardinality(BO); if (c != co) { printf("Bug %s, line %d \n", __FILE__, __LINE__); return 0; } c = bitset_container_or(B1, B2, BO); if (c != co) { printf("Bug %s, line %d \n", __FILE__, __LINE__); return 0; } bitset_container_free(B1); bitset_container_free(B2); bitset_container_free(BI); bitset_container_free(BO); return 1; }
bool bitset_bitset_container_intersection_inplace( bitset_container_t *src_1, const bitset_container_t *src_2, void **dst) { const int newCardinality = bitset_container_and_justcard(src_1, src_2); if (newCardinality > DEFAULT_MAX_SIZE) { *dst = src_1; bitset_container_and_nocard(src_1, src_2, src_1); ((bitset_container_t *)*dst)->cardinality = newCardinality; return true; // it is a bitset } *dst = array_container_create_given_capacity(newCardinality); if (*dst != NULL) { ((array_container_t *)*dst)->cardinality = newCardinality; bitset_extract_intersection_setbits_uint16( ((bitset_container_t *)src_1)->array, ((bitset_container_t *)src_2)->array, BITSET_CONTAINER_SIZE_IN_WORDS, ((array_container_t *)*dst)->array, 0); } return false; // not a bitset }
int main() { int repeat = 500; int size = (1 << 16) / 3; tellmeall(); printf("bitset container benchmarks\n"); bitset_container_t* B = bitset_container_create(); BEST_TIME(set_test(B), 0, repeat, size); int answer = get_test(B); size = 1 << 16; BEST_TIME(get_test(B), answer, repeat, size); BEST_TIME(bitset_container_cardinality(B), answer, repeat, 1); BEST_TIME(bitset_container_compute_cardinality(B), answer, repeat, BITSET_CONTAINER_SIZE_IN_WORDS); size = (1 << 16) / 3; BEST_TIME(unset_test(B), 0, repeat, size); bitset_container_free(B); for (int howmany = 4096; howmany <= (1 << 16); howmany *= 2) { bitset_container_t* Bt = bitset_container_create(); while (bitset_container_cardinality(Bt) < howmany) { bitset_container_set(Bt, (uint16_t)pcg32_random()); } size_t nbrtestvalues = 1024; uint16_t* testvalues = malloc(nbrtestvalues * sizeof(uint16_t)); printf("\n number of values in container = %d\n", bitset_container_cardinality(Bt)); int card = bitset_container_cardinality(Bt); uint32_t* out = malloc(sizeof(uint32_t) * (unsigned)card + 32); BEST_TIME(bitset_container_to_uint32_array(out, Bt, 1234), card, repeat, card); free(out); BEST_TIME_PRE_ARRAY(Bt, bitset_container_get, bitset_cache_prefetch, testvalues, nbrtestvalues); BEST_TIME_PRE_ARRAY(Bt, bitset_container_get, bitset_cache_flush, testvalues, nbrtestvalues); free(testvalues); bitset_container_free(Bt); } printf("\n"); bitset_container_t* B1 = bitset_container_create(); for (int x = 0; x < 1 << 16; x += 3) { bitset_container_set(B1, (uint16_t)x); } bitset_container_t* B2 = bitset_container_create(); for (int x = 0; x < 1 << 16; x += 5) { bitset_container_set(B2, (uint16_t)x); } bitset_container_t* BO = bitset_container_create(); BEST_TIME(bitset_container_or_nocard(B1, B2, BO), -1, repeat, BITSET_CONTAINER_SIZE_IN_WORDS); answer = bitset_container_compute_cardinality(BO); BEST_TIME(bitset_container_or(B1, B2, BO), answer, repeat, BITSET_CONTAINER_SIZE_IN_WORDS); BEST_TIME(bitset_container_cardinality(BO), answer, repeat, 1); BEST_TIME(bitset_container_compute_cardinality(BO), answer, repeat, BITSET_CONTAINER_SIZE_IN_WORDS); BEST_TIME(bitset_container_and_nocard(B1, B2, BO), -1, repeat, BITSET_CONTAINER_SIZE_IN_WORDS); answer = bitset_container_compute_cardinality(BO); BEST_TIME(bitset_container_and(B1, B2, BO), answer, repeat, BITSET_CONTAINER_SIZE_IN_WORDS); BEST_TIME(bitset_container_cardinality(BO), answer, repeat, 1); BEST_TIME(bitset_container_compute_cardinality(BO), answer, repeat, BITSET_CONTAINER_SIZE_IN_WORDS); // next we are going to benchmark conversion from bitset to array (an // important step) bitset_container_clear(B1); for (int k = 0; k < 4096; ++k) { bitset_container_set(B1, (uint16_t)ranged_random(1 << 16)); } answer = get_cardinality_through_conversion_to_array(B1); BEST_TIME(get_cardinality_through_conversion_to_array(B1), answer, repeat, BITSET_CONTAINER_SIZE_IN_WORDS); bitset_container_free(BO); bitset_container_free(B1); bitset_container_free(B2); return 0; }