bitset_countn_t *bitset_countn_new(unsigned n, size_t size) { bitset_countn_t *counter = bitset_malloc(sizeof(bitset_countn_t)); if (!counter) { bitset_oom(); } assert(n); counter->n = n; size = (size_t)(size / BITSET_LITERAL_LENGTH) + 1; size_t pow2; BITSET_NEXT_POW2(pow2, size); counter->size = pow2; counter->words = bitset_malloc(sizeof(bitset_word *) * (counter->n + 1)); if (!counter->words) { bitset_oom(); } //Create N+1 uncompressed bitsets size_t i; for ( i = 0; i <= n; i++) { counter->words[i] = bitset_calloc(1, counter->size * sizeof(bitset_word)); if (!counter->words[i]) { bitset_oom(); } } return counter; }
bitset_vector_t *bitset_vector_new() { bitset_vector_t *vector = bitset_malloc(sizeof(bitset_vector_t)); if (!vector) { bitset_oom(); } vector->buffer = bitset_malloc(sizeof(char)); if (!vector->buffer) { bitset_oom(); } vector->tail_offset = 0; vector->size = 1; vector->length = 0; return vector; }
bitset_linear_t *bitset_linear_new(size_t size) { bitset_linear_t *counter = bitset_malloc(sizeof(bitset_linear_t)); if (!counter) { bitset_oom(); } counter->count = 0; size = (size_t)(size / BITSET_LITERAL_LENGTH) + 1; size_t pow2; BITSET_NEXT_POW2(pow2, size); counter->size = pow2; counter->words = bitset_calloc(1, counter->size * sizeof(bitset_word)); if (!counter->words) { bitset_oom(); } return counter; }
unsigned *bitset_countn_count_mask(const bitset_countn_t *counter, const bitset_t *mask) { bitset_word *mask_words = bitset_calloc(1, counter->size * sizeof(bitset_word)); if (!mask_words) { bitset_oom(); } bitset_offset offset = 0; bitset_word word, mask_word; unsigned position; size_t i; for ( i = 0; i < mask->length; i++) { mask_word = mask->buffer[i]; if (BITSET_IS_FILL_WORD(mask_word)) { offset += BITSET_GET_LENGTH(mask_word); if (offset >= counter->size) { offset %= counter->size; } position = BITSET_GET_POSITION(mask_word); if (!position) { continue; } mask_word = BITSET_CREATE_LITERAL(position - 1); } mask_words[offset] |= mask_word; offset++; if (offset >= counter->size) { offset -= counter->size; } } unsigned *counts = bitset_calloc(1, sizeof(unsigned) * counter->n); if (!counts) { bitset_oom(); } size_t offset2,n; for ( offset2 = 0; offset2 < counter->size; offset2++) { for (n = 1; n <= counter->n; n++) { word = counter->words[n-1][offset2] & ~counter->words[n][offset2]; word &= mask_words[offset2]; BITSET_POP_COUNT(counts[n-1], word); } } bitset_malloc_free(mask_words); return counts; }
bitset_vector_t *bitset_vector_copy(const bitset_vector_t *vector) { bitset_vector_t *copy = bitset_vector_new(); if (vector->length) { copy->buffer = bitset_realloc(copy->buffer, sizeof(char) * vector->length); if (!copy->buffer) { bitset_oom(); } memcpy(copy->buffer, vector->buffer, vector->length); copy->length = copy->size = vector->length; copy->tail_offset = vector->tail_offset; } return copy; }
void bitset_vector_resize(bitset_vector_t *vector, size_t length) { size_t new_size = vector->size; while (new_size < length) { new_size *= 2; } if (new_size > vector->size) { vector->buffer = bitset_realloc(vector->buffer, new_size * sizeof(char)); if (!vector->buffer) { bitset_oom(); } vector->size = new_size; } vector->length = length; }
unsigned *bitset_countn_count_all(const bitset_countn_t *counter) { unsigned *counts = bitset_calloc(1, sizeof(unsigned) * counter->n); if (!counts) { bitset_oom(); } bitset_word word; size_t offset,n; for ( offset = 0; offset < counter->size; offset++) { for (n = 1; n <= counter->n; n++) { word = counter->words[n-1][offset] & ~counter->words[n][offset]; if (word) { BITSET_POP_COUNT(counts[n-1], word); } } } return counts; }