bool serialize_correctly(roaring_bitmap_t *r) { uint32_t expectedsize = roaring_bitmap_portable_size_in_bytes(r); char *serialized = malloc(expectedsize); if (serialized == NULL) { printf("failure to allocate memory!\n"); return false; } uint32_t serialize_len = roaring_bitmap_portable_serialize(r, serialized); if (serialize_len != expectedsize) { printf("Bad serialized size!\n"); free(serialized); return false; } roaring_bitmap_t *r2 = roaring_bitmap_portable_deserialize(serialized); free(serialized); if (!roaring_bitmap_equals(r, r2)) { printf("Won't recover original bitmap!\n"); roaring_bitmap_free(r2); return false; } if (!roaring_bitmap_equals(r2, r)) { printf("Won't recover original bitmap!\n"); roaring_bitmap_free(r2); return false; } roaring_bitmap_free(r2); return true; }
bool is_negation_correct(roaring_bitmap_t *bitmap) { roaring_statistics_t stats; bool answer = true; roaring_bitmap_statistics(bitmap, &stats); unsigned universe_size = stats.max_value + 1; roaring_bitmap_t *inverted = roaring_bitmap_flip(bitmap, 0U, universe_size); roaring_bitmap_t *double_inverted = roaring_bitmap_flip(inverted, 0U, universe_size); answer = (roaring_bitmap_get_cardinality(inverted) + roaring_bitmap_get_cardinality(bitmap) == universe_size); if (answer) answer = roaring_bitmap_equals(bitmap, double_inverted); if (!answer) { printf("Bad flip\n\nbitmap1:\n"); show_structure(bitmap->high_low_container); // debug printf("\n\nflipped:\n"); show_structure(inverted->high_low_container); // debug } roaring_bitmap_free(double_inverted); roaring_bitmap_free(inverted); return answer; }
bool compare_andnots(roaring_bitmap_t **rnorun, roaring_bitmap_t **rruns, size_t count) { roaring_bitmap_t *tempornorun; roaring_bitmap_t *temporruns; for (size_t i = 0; i + 1 < count; ++i) { tempornorun = roaring_bitmap_andnot(rnorun[i], rnorun[i + 1]); if (!is_andnot_correct(rnorun[i], rnorun[i + 1])) { printf("no-run andnot incorrect\n"); return false; } temporruns = roaring_bitmap_andnot(rruns[i], rruns[i + 1]); if (!is_andnot_correct(rruns[i], rruns[i + 1])) { printf("runs andnots incorrect\n"); return false; } if (!slow_bitmap_equals(tempornorun, temporruns)) { printf("Andnots don't agree! (slow) \n"); return false; } if (!roaring_bitmap_equals(tempornorun, temporruns)) { printf("Andnots don't agree!\n"); printf("\n\nbitmap1:\n"); show_structure(tempornorun->high_low_container); // debug printf("\n\nbitmap2:\n"); show_structure(temporruns->high_low_container); // debug return false; } roaring_bitmap_free(tempornorun); roaring_bitmap_free(temporruns); tempornorun = inplace_andnot(rnorun[i], rnorun[i + 1]); if (!is_andnot_correct(rnorun[i], rnorun[i + 1])) { printf("[inplace] no-run andnot incorrect\n"); return false; } temporruns = inplace_andnot(rruns[i], rruns[i + 1]); if (!is_andnot_correct(rruns[i], rruns[i + 1])) { printf("[inplace] runs andnots incorrect\n"); return false; } if (!slow_bitmap_equals(tempornorun, temporruns)) { printf("[inplace] Andnots don't agree! (slow) \n"); return false; } if (!roaring_bitmap_equals(tempornorun, temporruns)) { printf("[inplace] Andnots don't agree!\n"); printf("\n\nbitmap1:\n"); show_structure(tempornorun->high_low_container); // debug printf("\n\nbitmap2:\n"); show_structure(temporruns->high_low_container); // debug return false; } roaring_bitmap_free(tempornorun); roaring_bitmap_free(temporruns); } return true; }
bool is_xor_correct(roaring_bitmap_t *bitmap1, roaring_bitmap_t *bitmap2) { roaring_bitmap_t *temp = roaring_bitmap_xor(bitmap1, bitmap2); roaring_bitmap_t *expected = synthesized_xor(bitmap1, bitmap2); bool answer = roaring_bitmap_equals(temp, expected); if (!answer) { printf("Bad XOR\n\nbitmap1:\n"); show_structure(bitmap1->high_low_container); // debug printf("\n\nbitmap2:\n"); show_structure(bitmap2->high_low_container); // debug printf("\n\nresult:\n"); show_structure(temp->high_low_container); // debug printf("\n\ncorrect result:\n"); show_structure(expected->high_low_container); // debug } roaring_bitmap_free(temp); roaring_bitmap_free(expected); return answer; }
// function copy-pasted from toplevel_unit.c static roaring_bitmap_t *synthesized_xor(roaring_bitmap_t *r1, roaring_bitmap_t *r2) { unsigned universe_size = 0; roaring_statistics_t stats; roaring_bitmap_statistics(r1, &stats); universe_size = stats.max_value; roaring_bitmap_statistics(r2, &stats); if (stats.max_value > universe_size) universe_size = stats.max_value; roaring_bitmap_t *r1_or_r2 = roaring_bitmap_or(r1, r2); roaring_bitmap_t *r1_and_r2 = roaring_bitmap_and(r1, r2); roaring_bitmap_t *r1_nand_r2 = roaring_bitmap_flip(r1_and_r2, 0U, universe_size + 1U); roaring_bitmap_t *r1_xor_r2 = roaring_bitmap_and(r1_or_r2, r1_nand_r2); roaring_bitmap_free(r1_or_r2); roaring_bitmap_free(r1_and_r2); roaring_bitmap_free(r1_nand_r2); return r1_xor_r2; }
bool is_andnot_correct(roaring_bitmap_t *bitmap1, roaring_bitmap_t *bitmap2) { roaring_bitmap_t *temp = roaring_bitmap_andnot(bitmap1, bitmap2); roaring_bitmap_t *expected = synthesized_andnot(bitmap1, bitmap2); bool answer = roaring_bitmap_equals(temp, expected); if (!answer) { printf("Bad ANDNOT\n\nbitmap1:\n"); show_structure(bitmap1->high_low_container); // debug // print_container(3, bitmap1); printf("\n\nbitmap2:\n"); show_structure(bitmap2->high_low_container); // debug printf("\n\nresult:\n"); show_structure(temp->high_low_container); // debug printf("\n\ncorrect result:\n"); show_structure(expected->high_low_container); // debug printf("difference is "); roaring_bitmap_printf(roaring_bitmap_xor(temp, expected)); } roaring_bitmap_free(temp); roaring_bitmap_free(expected); return answer; }
// see https://github.com/saulius/croaring-rs/issues/6#issuecomment-243341270 int main() { size_t N = 1000000; uint64_t cycles_start, cycles_final; RDTSC_START(cycles_start); for(size_t i = 0; i < N; i++) { roaring_bitmap_t * bm = roaring_bitmap_create(); roaring_bitmap_free(bm); } RDTSC_FINAL(cycles_final); printf("%f cycles per object created \n",(cycles_final-cycles_start)*1.0/N); return 0; }
bool compare_wide_xors(roaring_bitmap_t **rnorun, roaring_bitmap_t **rruns, size_t count) { roaring_bitmap_t *tempornorun = roaring_bitmap_xor_many(count, (const roaring_bitmap_t **)rnorun); roaring_bitmap_t *temporruns = roaring_bitmap_xor_many(count, (const roaring_bitmap_t **)rruns); if (!slow_bitmap_equals(tempornorun, temporruns)) { printf("[compare_wide_xors] Xors don't agree! (fast run-norun) \n"); return false; } assert(roaring_bitmap_equals(tempornorun, temporruns)); roaring_bitmap_t *longtempornorun; roaring_bitmap_t *longtemporruns; if (count == 1) { longtempornorun = rnorun[0]; longtemporruns = rruns[0]; } else { assert(roaring_bitmap_equals(rnorun[0], rruns[0])); assert(roaring_bitmap_equals(rnorun[1], rruns[1])); longtempornorun = roaring_bitmap_xor(rnorun[0], rnorun[1]); longtemporruns = roaring_bitmap_xor(rruns[0], rruns[1]); assert(roaring_bitmap_equals(longtempornorun, longtemporruns)); for (int i = 2; i < (int)count; ++i) { assert(roaring_bitmap_equals(rnorun[i], rruns[i])); assert(roaring_bitmap_equals(longtempornorun, longtemporruns)); roaring_bitmap_t *t1 = roaring_bitmap_xor(rnorun[i], longtempornorun); roaring_bitmap_t *t2 = roaring_bitmap_xor(rruns[i], longtemporruns); assert(roaring_bitmap_equals(t1, t2)); roaring_bitmap_free(longtempornorun); longtempornorun = t1; roaring_bitmap_free(longtemporruns); longtemporruns = t2; assert(roaring_bitmap_equals(longtempornorun, longtemporruns)); } } if (!slow_bitmap_equals(longtempornorun, tempornorun)) { printf("[compare_wide_xors] Xors don't agree! (regular) \n"); return false; } if (!slow_bitmap_equals(temporruns, longtemporruns)) { printf("[compare_wide_xors] Xors don't agree! (runs) \n"); return false; } roaring_bitmap_free(tempornorun); roaring_bitmap_free(temporruns); roaring_bitmap_free(longtempornorun); roaring_bitmap_free(longtemporruns); return true; }
bool is_intersection_correct(roaring_bitmap_t *bitmap1, roaring_bitmap_t *bitmap2) { roaring_bitmap_t *temp = roaring_bitmap_and(bitmap1, bitmap2); uint64_t card1, card2, card; card1 = roaring_bitmap_get_cardinality(bitmap1); card2 = roaring_bitmap_get_cardinality(bitmap2); card = roaring_bitmap_get_cardinality(temp); uint32_t *arr1 = (uint32_t *)malloc(card1 * sizeof(uint32_t)); uint32_t *arr2 = (uint32_t *)malloc(card2 * sizeof(uint32_t)); uint32_t *arr = (uint32_t *)malloc(card * sizeof(uint32_t)); if ((arr1 == NULL) || (arr2 == NULL) || (arr == NULL)) { free(arr1); free(arr2); free(arr); return false; } roaring_bitmap_to_uint32_array(bitmap1, arr1); roaring_bitmap_to_uint32_array(bitmap2, arr2); roaring_bitmap_to_uint32_array(temp, arr); uint32_t *buffer = (uint32_t *)malloc(sizeof(uint32_t) * (card1 + card2)); size_t cardtrue = intersection_uint32(arr1, card1, arr2, card2, buffer); bool answer = array_equals(arr, card, buffer, cardtrue); if (!answer) { printf("\n\nbitmap1:\n"); show_structure(bitmap1->high_low_container); // debug printf("\n\nbitmap2:\n"); show_structure(bitmap2->high_low_container); // debug printf("\n\nresult:\n"); show_structure(temp->high_low_container); // debug roaring_bitmap_t *ca = roaring_bitmap_of_ptr(cardtrue, buffer); printf("\n\ncorrect result:\n"); show_structure(ca->high_low_container); // debug free(ca); } free(buffer); free(arr1); free(arr2); free(arr); roaring_bitmap_free(temp); return answer; }
void test_example(bool copy_on_write) { // create a new empty bitmap roaring_bitmap_t *r1 = roaring_bitmap_create(); r1->copy_on_write = copy_on_write; assert_ptr_not_equal(r1, NULL); // then we can add values for (uint32_t i = 100; i < 1000; i++) { roaring_bitmap_add(r1, i); } // check whether a value is contained assert_true(roaring_bitmap_contains(r1, 500)); // compute how many bits there are: uint32_t cardinality = roaring_bitmap_get_cardinality(r1); printf("Cardinality = %d \n", cardinality); assert_int_equal(900, cardinality); // if your bitmaps have long runs, you can compress them by calling // run_optimize uint32_t size = roaring_bitmap_portable_size_in_bytes(r1); roaring_bitmap_run_optimize(r1); uint32_t compact_size = roaring_bitmap_portable_size_in_bytes(r1); printf("size before run optimize %d bytes, and after %d bytes\n", size, compact_size); // create a new bitmap with varargs roaring_bitmap_t *r2 = roaring_bitmap_of(5, 1, 2, 3, 5, 6); assert_ptr_not_equal(r2, NULL); roaring_bitmap_printf(r2); printf("\n"); // we can also create a bitmap from a pointer to 32-bit integers const uint32_t values[] = {2, 3, 4}; roaring_bitmap_t *r3 = roaring_bitmap_of_ptr(3, values); r3->copy_on_write = copy_on_write; // we can also go in reverse and go from arrays to bitmaps uint64_t card1 = roaring_bitmap_get_cardinality(r1); uint32_t *arr1 = new uint32_t[card1]; assert_ptr_not_equal(arr1, NULL); roaring_bitmap_to_uint32_array(r1, arr1); roaring_bitmap_t *r1f = roaring_bitmap_of_ptr(card1, arr1); delete[] arr1; assert_ptr_not_equal(r1f, NULL); // bitmaps shall be equal assert_true(roaring_bitmap_equals(r1, r1f)); roaring_bitmap_free(r1f); // we can copy and compare bitmaps roaring_bitmap_t *z = roaring_bitmap_copy(r3); z->copy_on_write = copy_on_write; assert_true(roaring_bitmap_equals(r3, z)); roaring_bitmap_free(z); // we can compute union two-by-two roaring_bitmap_t *r1_2_3 = roaring_bitmap_or(r1, r2); r1_2_3->copy_on_write = copy_on_write; roaring_bitmap_or_inplace(r1_2_3, r3); // we can compute a big union const roaring_bitmap_t *allmybitmaps[] = {r1, r2, r3}; roaring_bitmap_t *bigunion = roaring_bitmap_or_many(3, allmybitmaps); assert_true(roaring_bitmap_equals(r1_2_3, bigunion)); roaring_bitmap_t *bigunionheap = roaring_bitmap_or_many_heap(3, allmybitmaps); assert_true(roaring_bitmap_equals(r1_2_3, bigunionheap)); roaring_bitmap_free(r1_2_3); roaring_bitmap_free(bigunion); roaring_bitmap_free(bigunionheap); // we can compute intersection two-by-two roaring_bitmap_t *i1_2 = roaring_bitmap_and(r1, r2); roaring_bitmap_free(i1_2); // we can write a bitmap to a pointer and recover it later uint32_t expectedsize = roaring_bitmap_portable_size_in_bytes(r1); char *serializedbytes = (char *)malloc(expectedsize); roaring_bitmap_portable_serialize(r1, serializedbytes); roaring_bitmap_t *t = roaring_bitmap_portable_deserialize(serializedbytes); assert_true(expectedsize == roaring_bitmap_portable_size_in_bytes(t)); assert_true(roaring_bitmap_equals(r1, t)); roaring_bitmap_free(t); free(serializedbytes); // we can iterate over all values using custom functions uint32_t counter = 0; roaring_iterate(r1, roaring_iterator_sumall, &counter); /** * void roaring_iterator_sumall(uint32_t value, void *param) { * *(uint32_t *) param += value; * } * */ roaring_bitmap_free(r1); roaring_bitmap_free(r2); roaring_bitmap_free(r3); }
int main(int argc, char **argv) { int c; const char *extension = ".txt"; bool copy_on_write = false; bool runoptimize = true; while ((c = getopt(argc, argv, "e:h")) != -1) switch (c) { case 'e': extension = optarg; break; case 'h': printusage(argv[0]); return 0; default: abort(); } if (optind >= argc) { printusage(argv[0]); return -1; } char *dirname = argv[optind]; size_t count; size_t *howmany = NULL; uint32_t **numbers = read_all_integer_files(dirname, extension, &howmany, &count); if (numbers == NULL) { printf( "I could not find or load any data file with extension %s in " "directory %s.\n", extension, dirname); return -1; } uint64_t cycles_start = 0, cycles_final = 0; RDTSC_START(cycles_start); roaring_bitmap_t **bitmaps = create_all_bitmaps(howmany, numbers, count, runoptimize, copy_on_write); RDTSC_FINAL(cycles_final); if (bitmaps == NULL) return -1; printf("Loaded %d bitmaps from directory %s \n", (int)count, dirname); printf("Creating %zu bitmaps took %" PRIu64 " cycles\n", count, cycles_final - cycles_start); if(count == 0) return -1; uint32_t maxvalue = roaring_bitmap_maximum(bitmaps[0]); for (int i = 1; i < (int)count; i ++) { uint32_t thismax = roaring_bitmap_maximum(bitmaps[0]); if(thismax > maxvalue) maxvalue = thismax; } const int quartile_test_repetitions = 1000; uint64_t quartcount; uint64_t cycles; STARTBEST(quartile_test_repetitions) quartcount = 0; for (size_t i = 0; i < count ; ++i) { quartcount += roaring_bitmap_contains(bitmaps[i],maxvalue/4); quartcount += roaring_bitmap_contains(bitmaps[i],maxvalue/2); quartcount += roaring_bitmap_contains(bitmaps[i],3*maxvalue/4); } ENDBEST(cycles) printf("Quartile queries on %zu bitmaps took %" PRIu64 " cycles\n", count, cycles); for (int i = 0; i < (int)count; ++i) { free(numbers[i]); numbers[i] = NULL; // paranoid roaring_bitmap_free(bitmaps[i]); bitmaps[i] = NULL; // paranoid } free(bitmaps); free(howmany); free(numbers); return (int) quartcount; }
// this function consumes and frees the inputs static roaring_bitmap_t *lazy_or_from_lazy_inputs(roaring_bitmap_t *x1, roaring_bitmap_t *x2) { uint8_t container_result_type = 0; const int length1 = ra_get_size(&x1->high_low_container), length2 = ra_get_size(&x2->high_low_container); if (0 == length1) { roaring_bitmap_free(x1); return x2; } if (0 == length2) { roaring_bitmap_free(x2); return x1; } uint32_t neededcap = length1 > length2 ? length2 : length1; roaring_bitmap_t *answer = roaring_bitmap_create_with_capacity(neededcap); int pos1 = 0, pos2 = 0; uint8_t container_type_1, container_type_2; uint16_t s1 = ra_get_key_at_index(&x1->high_low_container, pos1); uint16_t s2 = ra_get_key_at_index(&x2->high_low_container, pos2); while (true) { if (s1 == s2) { // todo: unsharing can be inefficient as it may create a clone where // none // is needed, but it has the benefit of being easy to reason about. ra_unshare_container_at_index(&x1->high_low_container, pos1); void *c1 = ra_get_container_at_index(&x1->high_low_container, pos1, &container_type_1); assert(container_type_1 != SHARED_CONTAINER_TYPE_CODE); ra_unshare_container_at_index(&x2->high_low_container, pos2); void *c2 = ra_get_container_at_index(&x2->high_low_container, pos2, &container_type_2); assert(container_type_2 != SHARED_CONTAINER_TYPE_CODE); void *c; if ((container_type_2 == BITSET_CONTAINER_TYPE_CODE) && (container_type_1 != BITSET_CONTAINER_TYPE_CODE)) { c = container_lazy_ior(c2, container_type_2, c1, container_type_1, &container_result_type); container_free(c1, container_type_1); if (c != c2) { container_free(c2, container_type_2); } } else { c = container_lazy_ior(c1, container_type_1, c2, container_type_2, &container_result_type); container_free(c2, container_type_2); if (c != c1) { container_free(c1, container_type_1); } } // since we assume that the initial containers are non-empty, the // result here // can only be non-empty ra_append(&answer->high_low_container, s1, c, container_result_type); ++pos1; ++pos2; if (pos1 == length1) break; if (pos2 == length2) break; s1 = ra_get_key_at_index(&x1->high_low_container, pos1); s2 = ra_get_key_at_index(&x2->high_low_container, pos2); } else if (s1 < s2) { // s1 < s2 void *c1 = ra_get_container_at_index(&x1->high_low_container, pos1, &container_type_1); ra_append(&answer->high_low_container, s1, c1, container_type_1); pos1++; if (pos1 == length1) break; s1 = ra_get_key_at_index(&x1->high_low_container, pos1); } else { // s1 > s2 void *c2 = ra_get_container_at_index(&x2->high_low_container, pos2, &container_type_2); ra_append(&answer->high_low_container, s2, c2, container_type_2); pos2++; if (pos2 == length2) break; s2 = ra_get_key_at_index(&x2->high_low_container, pos2); } } if (pos1 == length1) { ra_append_move_range(&answer->high_low_container, &x2->high_low_container, pos2, length2); } else if (pos2 == length2) { ra_append_move_range(&answer->high_low_container, &x1->high_low_container, pos1, length1); } ra_clear_without_containers(&x1->high_low_container); ra_clear_without_containers(&x2->high_low_container); free(x1); free(x2); return answer; }
bool loadAndCheckAll(const char *dirname, bool copy_on_write) { printf("[%s] %s datadir=%s %s\n", __FILE__, __func__, dirname, copy_on_write ? "copy-on-write" : "hard-copies"); char *extension = ".txt"; size_t count; size_t *howmany = NULL; uint32_t **numbers = read_all_integer_files(dirname, extension, &howmany, &count); if (numbers == NULL) { printf( "I could not find or load any data file with extension %s in " "directory %s.\n", extension, dirname); return false; } roaring_bitmap_t **bitmaps = create_all_bitmaps(howmany, numbers, count, copy_on_write); for (size_t i = 0; i < count; i++) { if (!is_bitmap_equal_to_array(bitmaps[i], numbers[i], howmany[i])) { printf("arrays don't agree with set values\n"); return false; } } roaring_bitmap_t **bitmapswrun = malloc(sizeof(roaring_bitmap_t *) * count); for (int i = 0; i < (int)count; i++) { bitmapswrun[i] = roaring_bitmap_copy(bitmaps[i]); roaring_bitmap_run_optimize(bitmapswrun[i]); if (roaring_bitmap_get_cardinality(bitmaps[i]) != roaring_bitmap_get_cardinality(bitmapswrun[i])) { printf("cardinality change due to roaring_bitmap_run_optimize\n"); return false; } } for (size_t i = 0; i < count; i++) { if (!is_bitmap_equal_to_array(bitmapswrun[i], numbers[i], howmany[i])) { printf("arrays don't agree with set values\n"); return false; } } for (int i = 0; i < (int)count; i++) { if (!serialize_correctly(bitmaps[i])) { return false; // memory leaks } if (!serialize_correctly(bitmapswrun[i])) { return false; // memory leaks } } if (!compare_intersections(bitmaps, bitmapswrun, count)) { return false; // memory leaks } if (!compare_unions(bitmaps, bitmapswrun, count)) { return false; // memory leaks } if (!compare_wide_unions(bitmaps, bitmapswrun, count)) { return false; // memory leaks } if (!compare_negations(bitmaps, bitmapswrun, count)) { return false; // memory leaks } if (!compare_xors(bitmaps, bitmapswrun, count)) { return false; // memory leaks } if (!compare_andnots(bitmaps, bitmapswrun, count)) { return false; // memory leaks } if (!compare_wide_xors(bitmaps, bitmapswrun, count)) { return false; // memory leaks } for (int i = 0; i < (int)count; ++i) { free(numbers[i]); numbers[i] = NULL; // paranoid roaring_bitmap_free(bitmaps[i]); bitmaps[i] = NULL; // paranoid roaring_bitmap_free(bitmapswrun[i]); bitmapswrun[i] = NULL; // paranoid } free(bitmapswrun); free(bitmaps); free(howmany); free(numbers); return true; }
int main(int argc, char **argv) { int c; char *extension = ".txt"; bool copy_on_write = false; while ((c = getopt(argc, argv, "e:h")) != -1) switch (c) { case 'e': extension = optarg; break; case 'h': printusage(argv[0]); return 0; default: abort(); } if (optind >= argc) { printusage(argv[0]); return -1; } char *dirname = argv[optind]; size_t count; size_t *howmany = NULL; uint32_t **numbers = read_all_integer_files(dirname, extension, &howmany, &count); if (numbers == NULL) { printf( "I could not find or load any data file with extension %s in " "directory %s.\n", extension, dirname); return -1; } uint64_t cycles_start = 0, cycles_final = 0; RDTSC_START(cycles_start); roaring_bitmap_t **bitmaps = create_all_bitmaps(howmany, numbers, count, copy_on_write); RDTSC_FINAL(cycles_final); if (bitmaps == NULL) return -1; printf("Loaded %d bitmaps from directory %s \n", (int)count, dirname); printf("Creating %zu bitmaps took %" PRIu64 " cycles\n", count, cycles_final - cycles_start); RDTSC_START(cycles_start); for (int i = 0; i < (int)count; i += 2) { roaring_bitmap_t *CI = roaring_bitmap_copy( bitmaps[i]); // to test the inplace version we create a copy roaring_bitmap_free(CI); } RDTSC_FINAL(cycles_final); printf("Copying and freeing %zu bitmaps took %" PRIu64 " cycles\n", count, cycles_final - cycles_start); uint64_t successive_and = 0; uint64_t successive_or = 0; // try ANDing and ORing together consecutive pairs for (int i = 0; i < (int)count - 1; ++i) { uint32_t c1 = roaring_bitmap_get_cardinality(bitmaps[i]); uint32_t c2 = roaring_bitmap_get_cardinality(bitmaps[i + 1]); RDTSC_START(cycles_start); roaring_bitmap_t *tempand = roaring_bitmap_and(bitmaps[i], bitmaps[i + 1]); RDTSC_FINAL(cycles_final); successive_and += cycles_final - cycles_start; uint32_t ci = roaring_bitmap_get_cardinality(tempand); roaring_bitmap_free(tempand); RDTSC_START(cycles_start); roaring_bitmap_t *tempor = roaring_bitmap_or(bitmaps[i], bitmaps[i + 1]); RDTSC_FINAL(cycles_final); successive_or += cycles_final - cycles_start; uint32_t co = roaring_bitmap_get_cardinality(tempor); roaring_bitmap_free(tempor); if (c1 + c2 != co + ci) { printf(KRED "cardinalities are wrong somehow\n"); printf("c1 = %d, c2 = %d, co = %d, ci = %d\n", c1, c2, co, ci); return -1; } } printf(" %zu successive bitmaps intersections took %" PRIu64 " cycles\n", count - 1, successive_and); printf(" %zu successive bitmaps unions took %" PRIu64 " cycles\n", count - 1, successive_or); roaring_bitmap_t **copyofr = malloc(sizeof(roaring_bitmap_t *) * count); for (int i = 0; i < (int)count; i++) { copyofr[i] = roaring_bitmap_copy(bitmaps[i]); } RDTSC_START(cycles_start); for (int i = 0; i < (int)count - 1; i++) { roaring_bitmap_and_inplace(copyofr[i], bitmaps[i + 1]); } RDTSC_FINAL(cycles_final); printf(" %zu successive in-place bitmaps intersections took %" PRIu64 " cycles\n", count - 1, cycles_final - cycles_start); free(copyofr); copyofr = malloc(sizeof(roaring_bitmap_t *) * count); for (int i = 0; i < (int)count; i++) { copyofr[i] = roaring_bitmap_copy(bitmaps[i]); } RDTSC_START(cycles_start); for (int i = 0; i < (int)count - 1; i++) { roaring_bitmap_or_inplace(copyofr[i], bitmaps[i + 1]); } RDTSC_FINAL(cycles_final); printf(" %zu successive in-place bitmaps unions took %" PRIu64 " cycles\n", count - 1, cycles_final - cycles_start); for (int i = 0; i < (int)count; ++i) { free(numbers[i]); numbers[i] = NULL; // paranoid roaring_bitmap_free(bitmaps[i]); bitmaps[i] = NULL; // paranoid } free(bitmaps); free(howmany); free(numbers); return 0; }