array.c:array_container_size_in_bytes:
  210|   657k|    const array_container_t *container) {
  211|   657k|    return container->cardinality * sizeof(uint16_t);
  212|   657k|}

bitset.c:bitset_container_size_in_bytes:
  447|    424|    const bitset_container_t *container) {
  448|    424|    (void)container;
  449|    424|    return BITSET_CONTAINER_SIZE_IN_WORDS * sizeof(uint64_t);
  450|    424|}

run.c:run_container_serialized_size_in_bytes:
  441|  30.0k|static inline int32_t run_container_serialized_size_in_bytes(int32_t num_runs) {
  442|  30.0k|    return sizeof(uint16_t) +
  443|  30.0k|           sizeof(rle16_t) * num_runs;  // each run requires 2 2-byte entries.
  444|  30.0k|}
run.c:run_container_size_in_bytes:
  477|  30.0k|    const run_container_t *container) {
  478|  30.0k|    return run_container_serialized_size_in_bytes(container->n_runs);
  479|  30.0k|}

roaring.c:roaring_bitmap_set_copy_on_write:
   80|    647|                                                    bool cow) {
   81|    647|    if (cow) {
  ------------------
  |  Branch (81:9): [True: 0, False: 647]
  ------------------
   82|      0|        r->high_low_container.flags |= ROARING_FLAG_COW;
  ------------------
  |  |   37|      0|#define ROARING_FLAG_COW UINT8_C(0x1)
  ------------------
   83|    647|    } else {
   84|    647|        r->high_low_container.flags &= ~ROARING_FLAG_COW;
  ------------------
  |  |   37|    647|#define ROARING_FLAG_COW UINT8_C(0x1)
  ------------------
   85|    647|    }
   86|    647|}

array_container_create_given_capacity:
   31|   657k|array_container_t *array_container_create_given_capacity(int32_t size) {
   32|   657k|    array_container_t *container;
   33|       |
   34|   657k|    if ((container = (array_container_t *)roaring_malloc(sizeof(array_container_t))) ==
  ------------------
  |  Branch (34:9): [True: 0, False: 657k]
  ------------------
   35|   657k|        NULL) {
   36|      0|        return NULL;
   37|      0|    }
   38|       |
   39|   657k|    if( size <= 0 ) { // we don't want to rely on malloc(0)
  ------------------
  |  Branch (39:9): [True: 0, False: 657k]
  ------------------
   40|      0|        container->array = NULL;
   41|   657k|    } else if ((container->array = (uint16_t *)roaring_malloc(sizeof(uint16_t) * size)) ==
  ------------------
  |  Branch (41:16): [True: 0, False: 657k]
  ------------------
   42|   657k|        NULL) {
   43|      0|        roaring_free(container);
   44|      0|        return NULL;
   45|      0|    }
   46|       |
   47|   657k|    container->capacity = size;
   48|   657k|    container->cardinality = 0;
   49|       |
   50|   657k|    return container;
   51|   657k|}
array_container_free:
  127|   657k|void array_container_free(array_container_t *arr) {
  128|   657k|    if(arr->array != NULL) {// Jon Strabala reports that some tools complain otherwise
  ------------------
  |  Branch (128:8): [True: 657k, False: 0]
  ------------------
  129|   657k|        roaring_free(arr->array);
  130|   657k|      arr->array = NULL; // pedantic
  131|   657k|    }
  132|   657k|    roaring_free(arr);
  133|   657k|}
array_container_read:
  463|   657k|                             const char *buf) {
  464|   657k|    if (container->capacity < cardinality) {
  ------------------
  |  Branch (464:9): [True: 0, False: 657k]
  ------------------
  465|      0|        array_container_grow(container, cardinality, false);
  466|      0|    }
  467|   657k|    container->cardinality = cardinality;
  468|   657k|    memcpy(container->array, buf, container->cardinality * sizeof(uint16_t));
  469|       |
  470|   657k|    return array_container_size_in_bytes(container);
  471|   657k|}

bitset_container_clear:
   35|    424|void bitset_container_clear(bitset_container_t *bitset) {
   36|    424|    memset(bitset->words, 0, sizeof(uint64_t) * BITSET_CONTAINER_SIZE_IN_WORDS);
   37|    424|    bitset->cardinality = 0;
   38|    424|}
bitset_container_create:
   49|    424|bitset_container_t *bitset_container_create(void) {
   50|    424|    bitset_container_t *bitset =
   51|    424|        (bitset_container_t *)roaring_malloc(sizeof(bitset_container_t));
   52|       |
   53|    424|    if (!bitset) {
  ------------------
  |  Branch (53:9): [True: 0, False: 424]
  ------------------
   54|      0|        return NULL;
   55|      0|    }
   56|       |    // sizeof(__m256i) == 32
   57|    424|    bitset->words = (uint64_t *)roaring_aligned_malloc(
   58|    424|        32, sizeof(uint64_t) * BITSET_CONTAINER_SIZE_IN_WORDS);
   59|    424|    if (!bitset->words) {
  ------------------
  |  Branch (59:9): [True: 0, False: 424]
  ------------------
   60|      0|        roaring_free(bitset);
   61|      0|        return NULL;
   62|      0|    }
   63|    424|    bitset_container_clear(bitset);
   64|    424|    return bitset;
   65|    424|}
bitset_container_free:
  104|    424|void bitset_container_free(bitset_container_t *bitset) {
  105|    424|    if(bitset->words != NULL) {// Jon Strabala reports that some tools complain otherwise
  ------------------
  |  Branch (105:8): [True: 424, False: 0]
  ------------------
  106|    424|      roaring_aligned_free(bitset->words);
  107|    424|      bitset->words = NULL; // pedantic
  108|    424|    }
  109|    424|    roaring_free(bitset);
  110|    424|}
bitset_container_read:
  783|    424|		const char *buf)  {
  784|    424|	container->cardinality = cardinality;
  785|    424|	memcpy(container->words, buf, BITSET_CONTAINER_SIZE_IN_WORDS * sizeof(uint64_t));
  786|    424|	return bitset_container_size_in_bytes(container);
  787|    424|}

container_free:
   38|   687k|void container_free(container_t *c, uint8_t type) {
   39|   687k|    switch (type) {
   40|    424|        case BITSET_CONTAINER_TYPE:
  ------------------
  |  |   34|    424|#define BITSET_CONTAINER_TYPE 1
  ------------------
  |  Branch (40:9): [True: 424, False: 687k]
  ------------------
   41|    424|            bitset_container_free(CAST_bitset(c));
  ------------------
  |  |   42|    424|#define CAST_bitset(c)         CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   93|    424|    #define CAST(type,value)            ((type)value)
  |  |  ------------------
  ------------------
   42|    424|            break;
   43|   657k|        case ARRAY_CONTAINER_TYPE:
  ------------------
  |  |   35|   657k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  |  Branch (43:9): [True: 657k, False: 30.4k]
  ------------------
   44|   657k|            array_container_free(CAST_array(c));
  ------------------
  |  |   44|   657k|#define CAST_array(c)         CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   93|   657k|    #define CAST(type,value)            ((type)value)
  |  |  ------------------
  ------------------
   45|   657k|            break;
   46|  30.0k|        case RUN_CONTAINER_TYPE:
  ------------------
  |  |   36|  30.0k|#define RUN_CONTAINER_TYPE 3
  ------------------
  |  Branch (46:9): [True: 30.0k, False: 657k]
  ------------------
   47|  30.0k|            run_container_free(CAST_run(c));
  ------------------
  |  |   67|  30.0k|#define CAST_run(c)         CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   93|  30.0k|    #define CAST(type,value)            ((type)value)
  |  |  ------------------
  ------------------
   48|  30.0k|            break;
   49|      0|        case SHARED_CONTAINER_TYPE:
  ------------------
  |  |   37|      0|#define SHARED_CONTAINER_TYPE 4
  ------------------
  |  Branch (49:9): [True: 0, False: 687k]
  ------------------
   50|      0|            shared_container_free(CAST_shared(c));
  ------------------
  |  |   67|      0|#define CAST_shared(c)         CAST(shared_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   93|      0|    #define CAST(type,value)            ((type)value)
  |  |  ------------------
  ------------------
   51|      0|            break;
   52|      0|        default:
  ------------------
  |  Branch (52:9): [True: 0, False: 687k]
  ------------------
   53|      0|            assert(false);
   54|      0|            __builtin_unreachable();
   55|   687k|    }
   56|   687k|}

run_container_create_given_capacity:
   77|  30.0k|run_container_t *run_container_create_given_capacity(int32_t size) {
   78|  30.0k|    run_container_t *run;
   79|       |    /* Allocate the run container itself. */
   80|  30.0k|    if ((run = (run_container_t *)roaring_malloc(sizeof(run_container_t))) == NULL) {
  ------------------
  |  Branch (80:9): [True: 0, False: 30.0k]
  ------------------
   81|      0|        return NULL;
   82|      0|    }
   83|  30.0k|    if (size <= 0 ) { // we don't want to rely on malloc(0)
  ------------------
  |  Branch (83:9): [True: 30.0k, False: 0]
  ------------------
   84|  30.0k|        run->runs = NULL;
   85|  30.0k|    } else if ((run->runs = (rle16_t *)roaring_malloc(sizeof(rle16_t) * size)) == NULL) {
  ------------------
  |  Branch (85:16): [True: 0, False: 0]
  ------------------
   86|      0|        roaring_free(run);
   87|      0|        return NULL;
   88|      0|    }
   89|  30.0k|    run->capacity = size;
   90|  30.0k|    run->n_runs = 0;
   91|  30.0k|    return run;
   92|  30.0k|}
run_container_create:
  104|  30.0k|run_container_t *run_container_create(void) {
  105|  30.0k|    return run_container_create_given_capacity(RUN_DEFAULT_INIT_SIZE);
  106|  30.0k|}
run_container_free:
  175|  30.0k|void run_container_free(run_container_t *run) {
  176|  30.0k|    if(run->runs != NULL) {// Jon Strabala reports that some tools complain otherwise
  ------------------
  |  Branch (176:8): [True: 295, False: 29.7k]
  ------------------
  177|    295|      roaring_free(run->runs);
  178|    295|      run->runs = NULL;  // pedantic
  179|    295|    }
  180|  30.0k|    roaring_free(run);
  181|  30.0k|}
run_container_grow:
  183|    295|void run_container_grow(run_container_t *run, int32_t min, bool copy) {
  184|    295|    int32_t newCapacity =
  185|    295|        (run->capacity == 0)
  ------------------
  |  Branch (185:9): [True: 295, False: 0]
  ------------------
  186|    295|            ? RUN_DEFAULT_INIT_SIZE
  187|    295|            : run->capacity < 64 ? run->capacity * 2
  ------------------
  |  Branch (187:15): [True: 0, False: 0]
  ------------------
  188|      0|                                 : run->capacity < 1024 ? run->capacity * 3 / 2
  ------------------
  |  Branch (188:36): [True: 0, False: 0]
  ------------------
  189|      0|                                                        : run->capacity * 5 / 4;
  190|    295|    if (newCapacity < min) newCapacity = min;
  ------------------
  |  Branch (190:9): [True: 295, False: 0]
  ------------------
  191|    295|    run->capacity = newCapacity;
  192|    295|    assert(run->capacity >= min);
  193|    295|    if (copy) {
  ------------------
  |  Branch (193:9): [True: 0, False: 295]
  ------------------
  194|      0|        rle16_t *oldruns = run->runs;
  195|      0|        run->runs =
  196|      0|            (rle16_t *)roaring_realloc(oldruns, run->capacity * sizeof(rle16_t));
  197|      0|        if (run->runs == NULL) roaring_free(oldruns);
  ------------------
  |  Branch (197:13): [True: 0, False: 0]
  ------------------
  198|    295|    } else {
  199|       |        // Jon Strabala reports that some tools complain otherwise
  200|    295|        if (run->runs != NULL) {
  ------------------
  |  Branch (200:13): [True: 0, False: 295]
  ------------------
  201|      0|          roaring_free(run->runs);
  202|      0|        }
  203|    295|        run->runs = (rle16_t *)roaring_malloc(run->capacity * sizeof(rle16_t));
  204|    295|    }
  205|       |    // handle the case where realloc fails
  206|    295|    if (run->runs == NULL) {
  ------------------
  |  Branch (206:9): [True: 0, False: 295]
  ------------------
  207|      0|      fprintf(stderr, "could not allocate memory\n");
  208|      0|    }
  209|    295|    assert(run->runs != NULL);
  210|    295|}
run_container_read:
  684|  30.0k|                           const char *buf) {
  685|  30.0k|    (void)cardinality;
  686|  30.0k|    memcpy(&container->n_runs, buf, sizeof(uint16_t));
  687|  30.0k|    if (container->n_runs > container->capacity)
  ------------------
  |  Branch (687:9): [True: 295, False: 29.7k]
  ------------------
  688|    295|        run_container_grow(container, container->n_runs, false);
  689|  30.0k|    if(container->n_runs > 0) {
  ------------------
  |  Branch (689:8): [True: 295, False: 29.7k]
  ------------------
  690|    295|      memcpy(container->runs, buf + sizeof(uint16_t),
  691|    295|           container->n_runs * sizeof(rle16_t));
  692|    295|    }
  693|  30.0k|    return run_container_size_in_bytes(container);
  694|  30.0k|}

roaring_malloc:
   47|  1.34M|void* roaring_malloc(size_t n) {
   48|  1.34M|    return global_memory_hook.malloc(n);
   49|  1.34M|}
roaring_free:
   59|  1.34M|void roaring_free(void* p) {
   60|  1.34M|    global_memory_hook.free(p);
   61|  1.34M|}
roaring_aligned_malloc:
   63|    424|void* roaring_aligned_malloc(size_t alignment, size_t size) {
   64|    424|    return global_memory_hook.aligned_malloc(alignment, size);
   65|    424|}
roaring_aligned_free:
   67|    424|void roaring_aligned_free(void* p) {
   68|    424|    global_memory_hook.aligned_free(p);
   69|    424|}
memory.c:roaring_bitmap_aligned_malloc:
   10|    424|static void *roaring_bitmap_aligned_malloc(size_t alignment, size_t size) {
   11|    424|    void *p;
   12|       |#ifdef _MSC_VER
   13|       |    p = _aligned_malloc(size, alignment);
   14|       |#elif defined(__MINGW32__) || defined(__MINGW64__)
   15|       |    p = __mingw_aligned_malloc(size, alignment);
   16|       |#else
   17|       |    // somehow, if this is used before including "x86intrin.h", it creates an
   18|       |    // implicit defined warning.
   19|    424|    if (posix_memalign(&p, alignment, size) != 0) return NULL;
  ------------------
  |  Branch (19:9): [True: 0, False: 424]
  ------------------
   20|    424|#endif
   21|    424|    return p;
   22|    424|}
memory.c:roaring_bitmap_aligned_free:
   24|    424|static void roaring_bitmap_aligned_free(void *memblock) {
   25|       |#ifdef _MSC_VER
   26|       |    _aligned_free(memblock);
   27|       |#elif defined(__MINGW32__) || defined(__MINGW64__)
   28|       |    __mingw_aligned_free(memblock);
   29|       |#else
   30|    424|    free(memblock);
   31|    424|#endif
   32|    424|}

roaring_bitmap_free:
  456|    122|void roaring_bitmap_free(const roaring_bitmap_t *r) {
  457|    122|    if (!is_frozen(r)) {
  ------------------
  |  Branch (457:9): [True: 122, False: 0]
  ------------------
  458|    122|      ra_clear((roaring_array_t*)&r->high_low_container);
  459|    122|    }
  460|    122|    roaring_free((roaring_bitmap_t*)r);
  461|    122|}
roaring_bitmap_portable_deserialize_safe:
 1428|    647|roaring_bitmap_t *roaring_bitmap_portable_deserialize_safe(const char *buf, size_t maxbytes) {
 1429|    647|    roaring_bitmap_t *ans =
 1430|    647|        (roaring_bitmap_t *)roaring_malloc(sizeof(roaring_bitmap_t));
 1431|    647|    if (ans == NULL) {
  ------------------
  |  Branch (1431:9): [True: 0, False: 647]
  ------------------
 1432|      0|        return NULL;
 1433|      0|    }
 1434|    647|    size_t bytesread;
 1435|    647|    bool is_ok = ra_portable_deserialize(&ans->high_low_container, buf, maxbytes, &bytesread);
 1436|    647|    if(is_ok) assert(bytesread <= maxbytes);
  ------------------
  |  Branch (1436:8): [True: 122, False: 525]
  ------------------
 1437|    647|    roaring_bitmap_set_copy_on_write(ans, false);
 1438|    647|    if (!is_ok) {
  ------------------
  |  Branch (1438:9): [True: 525, False: 122]
  ------------------
 1439|    525|        roaring_free(ans);
 1440|    525|        return NULL;
 1441|    525|    }
 1442|    122|    return ans;
 1443|    647|}
roaring.c:is_frozen:
   30|    122|static inline bool is_frozen(const roaring_bitmap_t *r) {
   31|    122|    return r->high_low_container.flags & ROARING_FLAG_FROZEN;
  ------------------
  |  |   38|    122|#define ROARING_FLAG_FROZEN UINT8_C(0x2)
  ------------------
   32|    122|}

ra_init_with_capacity:
   75|    444|bool ra_init_with_capacity(roaring_array_t *new_ra, uint32_t cap) {
   76|    444|    if (!new_ra) return false;
  ------------------
  |  Branch (76:9): [True: 0, False: 444]
  ------------------
   77|    444|    ra_init(new_ra);
   78|       |
   79|    444|    if (cap > INT32_MAX) { return false; }
  ------------------
  |  Branch (79:9): [True: 0, False: 444]
  ------------------
   80|       |
   81|    444|    if(cap > 0) {
  ------------------
  |  Branch (81:8): [True: 420, False: 24]
  ------------------
   82|    420|      void *bigalloc = roaring_malloc(cap *
   83|    420|                (sizeof(uint16_t) + sizeof(container_t *) + sizeof(uint8_t)));
   84|    420|      if( bigalloc == NULL ) return false;
  ------------------
  |  Branch (84:11): [True: 0, False: 420]
  ------------------
   85|    420|      new_ra->containers = (container_t **)bigalloc;
   86|    420|      new_ra->keys = (uint16_t *)(new_ra->containers + cap);
   87|    420|      new_ra->typecodes = (uint8_t *)(new_ra->keys + cap);
   88|       |      // Narrowing is safe because of above check
   89|    420|      new_ra->allocation_size = (int32_t)cap;
   90|    420|    }
   91|    444|    return true;
   92|    444|}
ra_init:
  104|    444|void ra_init(roaring_array_t *new_ra) {
  105|    444|    if (!new_ra) { return; }
  ------------------
  |  Branch (105:9): [True: 0, False: 444]
  ------------------
  106|    444|    new_ra->keys = NULL;
  107|    444|    new_ra->containers = NULL;
  108|    444|    new_ra->typecodes = NULL;
  109|       |
  110|    444|    new_ra->allocation_size = 0;
  111|    444|    new_ra->size = 0;
  112|    444|    new_ra->flags = 0;
  113|    444|}
ra_clear_containers:
  158|    444|void ra_clear_containers(roaring_array_t *ra) {
  159|   687k|    for (int32_t i = 0; i < ra->size; ++i) {
  ------------------
  |  Branch (159:25): [True: 687k, False: 444]
  ------------------
  160|   687k|        container_free(ra->containers[i], ra->typecodes[i]);
  161|   687k|    }
  162|    444|}
ra_clear_without_containers:
  170|    444|void ra_clear_without_containers(roaring_array_t *ra) {
  171|    444|    roaring_free(ra->containers);    // keys and typecodes are allocated with containers
  172|    444|    ra->size = 0;
  173|    444|    ra->allocation_size = 0;
  174|    444|    ra->containers = NULL;
  175|    444|    ra->keys = NULL;
  176|    444|    ra->typecodes = NULL;
  177|    444|}
ra_clear:
  179|    444|void ra_clear(roaring_array_t *ra) {
  180|    444|    ra_clear_containers(ra);
  181|    444|    ra_clear_without_containers(ra);
  182|    444|}
ra_portable_deserialize:
  697|    647|bool ra_portable_deserialize(roaring_array_t *answer, const char *buf, const size_t maxbytes, size_t * readbytes) {
  698|    647|    *readbytes = sizeof(int32_t);// for cookie
  699|    647|    if(*readbytes > maxbytes) {
  ------------------
  |  Branch (699:8): [True: 2, False: 645]
  ------------------
  700|      2|      fprintf(stderr, "Ran out of bytes while reading first 4 bytes.\n");
  701|      2|      return false;
  702|      2|    }
  703|    645|    uint32_t cookie;
  704|    645|    memcpy(&cookie, buf, sizeof(int32_t));
  705|    645|    buf += sizeof(uint32_t);
  706|    645|    if ((cookie & 0xFFFF) != SERIAL_COOKIE &&
  ------------------
  |  Branch (706:9): [True: 289, False: 356]
  ------------------
  707|    645|        cookie != SERIAL_COOKIE_NO_RUNCONTAINER) {
  ------------------
  |  Branch (707:9): [True: 60, False: 229]
  ------------------
  708|     60|        fprintf(stderr, "I failed to find one of the right cookies. Found %" PRIu32 "\n",
  709|     60|                cookie);
  710|     60|        return false;
  711|     60|    }
  712|    585|    int32_t size;
  713|       |
  714|    585|    if ((cookie & 0xFFFF) == SERIAL_COOKIE)
  ------------------
  |  Branch (714:9): [True: 356, False: 229]
  ------------------
  715|    356|        size = (cookie >> 16) + 1;
  716|    229|    else {
  717|    229|        *readbytes += sizeof(int32_t);
  718|    229|        if(*readbytes > maxbytes) {
  ------------------
  |  Branch (718:12): [True: 3, False: 226]
  ------------------
  719|      3|          fprintf(stderr, "Ran out of bytes while reading second part of the cookie.\n");
  720|      3|          return false;
  721|      3|        }
  722|    226|        memcpy(&size, buf, sizeof(int32_t));
  723|    226|        buf += sizeof(uint32_t);
  724|    226|    }
  725|    582|    if (size < 0) {
  ------------------
  |  Branch (725:9): [True: 39, False: 543]
  ------------------
  726|     39|       fprintf(stderr, "You cannot have a negative number of containers, the data must be corrupted: %" PRId32 "\n",
  727|     39|                size);
  728|     39|       return false; // logically impossible
  729|     39|    }
  730|    543|    if (size > (1<<16)) {
  ------------------
  |  Branch (730:9): [True: 25, False: 518]
  ------------------
  731|     25|       fprintf(stderr, "You cannot have so many containers, the data must be corrupted: %" PRId32 "\n",
  732|     25|                size);
  733|     25|       return false; // logically impossible
  734|     25|    }
  735|    518|    const char *bitmapOfRunContainers = NULL;
  736|    518|    bool hasrun = (cookie & 0xFFFF) == SERIAL_COOKIE;
  737|    518|    if (hasrun) {
  ------------------
  |  Branch (737:9): [True: 356, False: 162]
  ------------------
  738|    356|        int32_t s = (size + 7) / 8;
  739|    356|        *readbytes += s;
  740|    356|        if(*readbytes > maxbytes) {// data is corrupted?
  ------------------
  |  Branch (740:12): [True: 24, False: 332]
  ------------------
  741|     24|          fprintf(stderr, "Ran out of bytes while reading run bitmap.\n");
  742|     24|          return false;
  743|     24|        }
  744|    332|        bitmapOfRunContainers = buf;
  745|    332|        buf += s;
  746|    332|    }
  747|    494|    uint16_t *keyscards = (uint16_t *)buf;
  748|       |
  749|    494|    *readbytes += size * 2 * sizeof(uint16_t);
  750|    494|    if(*readbytes > maxbytes) {
  ------------------
  |  Branch (750:8): [True: 50, False: 444]
  ------------------
  751|     50|      fprintf(stderr, "Ran out of bytes while reading key-cardinality array.\n");
  752|     50|      return false;
  753|     50|    }
  754|    444|    buf += size * 2 * sizeof(uint16_t);
  755|       |
  756|    444|    bool is_ok = ra_init_with_capacity(answer, size);
  757|    444|    if (!is_ok) {
  ------------------
  |  Branch (757:9): [True: 0, False: 444]
  ------------------
  758|      0|        fprintf(stderr, "Failed to allocate memory for roaring array. Bailing out.\n");
  759|      0|        return false;
  760|      0|    }
  761|       |
  762|  1.76M|    for (int32_t k = 0; k < size; ++k) {
  ------------------
  |  Branch (762:25): [True: 1.75M, False: 444]
  ------------------
  763|  1.75M|        uint16_t tmp;
  764|  1.75M|        memcpy(&tmp, keyscards + 2*k, sizeof(tmp));
  765|  1.75M|        answer->keys[k] = tmp;
  766|  1.75M|    }
  767|    444|    if ((!hasrun) || (size >= NO_OFFSET_THRESHOLD)) {
  ------------------
  |  Branch (767:9): [True: 126, False: 318]
  |  Branch (767:22): [True: 159, False: 159]
  ------------------
  768|    285|        *readbytes += size * 4;
  769|    285|        if(*readbytes > maxbytes) {// data is corrupted?
  ------------------
  |  Branch (769:12): [True: 88, False: 197]
  ------------------
  770|     88|          fprintf(stderr, "Ran out of bytes while reading offsets.\n");
  771|     88|          ra_clear(answer);// we need to clear the containers already allocated, and the roaring array
  772|     88|          return false;
  773|     88|        }
  774|       |
  775|       |        // skipping the offsets
  776|    197|        buf += size * 4;
  777|    197|    }
  778|       |    // Reading the containers
  779|   687k|    for (int32_t k = 0; k < size; ++k) {
  ------------------
  |  Branch (779:25): [True: 687k, False: 122]
  ------------------
  780|   687k|        uint16_t tmp;
  781|   687k|        memcpy(&tmp, keyscards + 2*k+1, sizeof(tmp));
  782|   687k|        uint32_t thiscard = tmp + 1;
  783|   687k|        bool isbitmap = (thiscard > DEFAULT_MAX_SIZE);
  784|   687k|        bool isrun = false;
  785|   687k|        if(hasrun) {
  ------------------
  |  Branch (785:12): [True: 428k, False: 259k]
  ------------------
  786|   428k|          if((bitmapOfRunContainers[k / 8] & (1 << (k % 8))) != 0) {
  ------------------
  |  Branch (786:14): [True: 30.1k, False: 397k]
  ------------------
  787|  30.1k|            isbitmap = false;
  788|  30.1k|            isrun = true;
  789|  30.1k|          }
  790|   428k|        }
  791|   687k|        if (isbitmap) {
  ------------------
  |  Branch (791:13): [True: 480, False: 687k]
  ------------------
  792|       |            // we check that the read is allowed
  793|    480|            size_t containersize = BITSET_CONTAINER_SIZE_IN_WORDS * sizeof(uint64_t);
  794|    480|            *readbytes += containersize;
  795|    480|            if(*readbytes > maxbytes) {
  ------------------
  |  Branch (795:16): [True: 56, False: 424]
  ------------------
  796|     56|              fprintf(stderr, "Running out of bytes while reading a bitset container.\n");
  797|     56|              ra_clear(answer);// we need to clear the containers already allocated, and the roaring array
  798|     56|              return false;
  799|     56|            }
  800|       |            // it is now safe to read
  801|    424|            bitset_container_t *c = bitset_container_create();
  802|    424|            if(c == NULL) {// memory allocation failure
  ------------------
  |  Branch (802:16): [True: 0, False: 424]
  ------------------
  803|      0|              fprintf(stderr, "Failed to allocate memory for a bitset container.\n");
  804|      0|              ra_clear(answer);// we need to clear the containers already allocated, and the roaring array
  805|      0|              return false;
  806|      0|            }
  807|    424|            answer->size++;
  808|    424|            buf += bitset_container_read(thiscard, c, buf);
  809|    424|            answer->containers[k] = c;
  810|    424|            answer->typecodes[k] = BITSET_CONTAINER_TYPE;
  ------------------
  |  |   34|    424|#define BITSET_CONTAINER_TYPE 1
  ------------------
  811|   687k|        } else if (isrun) {
  ------------------
  |  Branch (811:20): [True: 30.1k, False: 657k]
  ------------------
  812|       |            // we check that the read is allowed
  813|  30.1k|            *readbytes += sizeof(uint16_t);
  814|  30.1k|            if(*readbytes > maxbytes) {
  ------------------
  |  Branch (814:16): [True: 46, False: 30.0k]
  ------------------
  815|     46|              fprintf(stderr, "Running out of bytes while reading a run container (header).\n");
  816|     46|              ra_clear(answer);// we need to clear the containers already allocated, and the roaring array
  817|     46|              return false;
  818|     46|            }
  819|  30.0k|            uint16_t n_runs;
  820|  30.0k|            memcpy(&n_runs, buf, sizeof(uint16_t));
  821|  30.0k|            size_t containersize = n_runs * sizeof(rle16_t);
  822|  30.0k|            *readbytes += containersize;
  823|  30.0k|            if(*readbytes > maxbytes) {// data is corrupted?
  ------------------
  |  Branch (823:16): [True: 61, False: 30.0k]
  ------------------
  824|     61|              fprintf(stderr, "Running out of bytes while reading a run container.\n");
  825|     61|              ra_clear(answer);// we need to clear the containers already allocated, and the roaring array
  826|     61|              return false;
  827|     61|            }
  828|       |            // it is now safe to read
  829|       |
  830|  30.0k|            run_container_t *c = run_container_create();
  831|  30.0k|            if(c == NULL) {// memory allocation failure
  ------------------
  |  Branch (831:16): [True: 0, False: 30.0k]
  ------------------
  832|      0|              fprintf(stderr, "Failed to allocate memory for a run container.\n");
  833|      0|              ra_clear(answer);// we need to clear the containers already allocated, and the roaring array
  834|      0|              return false;
  835|      0|            }
  836|  30.0k|            answer->size++;
  837|  30.0k|            buf += run_container_read(thiscard, c, buf);
  838|  30.0k|            answer->containers[k] = c;
  839|  30.0k|            answer->typecodes[k] = RUN_CONTAINER_TYPE;
  ------------------
  |  |   36|  30.0k|#define RUN_CONTAINER_TYPE 3
  ------------------
  840|   657k|        } else {
  841|       |            // we check that the read is allowed
  842|   657k|            size_t containersize = thiscard * sizeof(uint16_t);
  843|   657k|            *readbytes += containersize;
  844|   657k|            if(*readbytes > maxbytes) {// data is corrupted?
  ------------------
  |  Branch (844:16): [True: 71, False: 657k]
  ------------------
  845|     71|              fprintf(stderr, "Running out of bytes while reading an array container.\n");
  846|     71|              ra_clear(answer);// we need to clear the containers already allocated, and the roaring array
  847|     71|              return false;
  848|     71|            }
  849|       |            // it is now safe to read
  850|   657k|            array_container_t *c =
  851|   657k|                array_container_create_given_capacity(thiscard);
  852|   657k|            if(c == NULL) {// memory allocation failure
  ------------------
  |  Branch (852:16): [True: 0, False: 657k]
  ------------------
  853|      0|              fprintf(stderr, "Failed to allocate memory for an array container.\n");
  854|      0|              ra_clear(answer);// we need to clear the containers already allocated, and the roaring array
  855|      0|              return false;
  856|      0|            }
  857|   657k|            answer->size++;
  858|   657k|            buf += array_container_read(thiscard, c, buf);
  859|   657k|            answer->containers[k] = c;
  860|   657k|            answer->typecodes[k] = ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   35|   657k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  861|   657k|        }
  862|   687k|    }
  863|    122|    return true;
  864|    356|}

LLVMFuzzerTestOneInput:
   22|    647|int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size){
   23|    647|    roaring_statistics_t stats;
   24|    647|    bool answer = true;
   25|    647|    roaring_bitmap_t* bitmap = roaring_bitmap_portable_deserialize_safe(data, size);
   26|    647|    if(bitmap) {
  ------------------
  |  Branch (26:8): [True: 122, False: 525]
  ------------------
   27|       |        /*
   28|       |        uint64_t card1 = roaring_bitmap_get_cardinality(bitmap);
   29|       |        roaring_bitmap_statistics(bitmap, &stats);
   30|       |        unsigned universe_size = stats.max_value + 1;
   31|       |        roaring_bitmap_t *inverted = roaring_bitmap_flip(bitmap, 0U, universe_size);
   32|       |        if(inverted) {
   33|       |            roaring_bitmap_t *double_inverted = roaring_bitmap_flip(inverted, 0U, universe_size);
   34|       |            if(double_inverted)
   35|       |            {
   36|       |                answer = (roaring_bitmap_get_cardinality(inverted) + roaring_bitmap_get_cardinality(bitmap) == universe_size);
   37|       |                if (answer) answer = roaring_bitmap_equals(bitmap, double_inverted);
   38|       |                if (!answer) {
   39|       |                    printf("Bad flip\n\nbitmap1:\n");
   40|       |                    roaring_bitmap_printf_describe(bitmap);  // debug
   41|       |                    printf("\n\nflipped:\n");
   42|       |                    roaring_bitmap_printf_describe(inverted);  // debug
   43|       |                }
   44|       |                roaring_bitmap_free(double_inverted);
   45|       |            }
   46|       |            roaring_bitmap_free(inverted);
   47|       |        }*/
   48|    122|        roaring_bitmap_free(bitmap);
   49|    122|    }
   50|    647|    return 0;
   51|    647|}

