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); }
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; }