From fe056c1b06398fa844fac47d18b859ca22883692 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Wed, 24 Jun 2020 16:57:38 -0300 Subject: [PATCH] Some fixes to bitset --- src/cmc/bitset.h | 44 ++++++++++++++++---------------------- src/cor/bitset.h | 16 ++++++++++++++ tests/include/cmc/bitset.h | 9 +------- tests/src/cmc/bitset.c | 26 +++++++++++----------- tests/unt/cmc/bitset.h | 30 +++++++++++++------------- 5 files changed, 63 insertions(+), 62 deletions(-) diff --git a/src/cmc/bitset.h b/src/cmc/bitset.h index 9dff4a7..796d016 100644 --- a/src/cmc/bitset.h +++ b/src/cmc/bitset.h @@ -85,6 +85,11 @@ \ /* Current array capacity */ \ size_t capacity; \ +\ + /* Currently used bits */\ + /* This should always be true: */\ + /* capacity - count < sizeof(cmc_bitset_word) * CHAR_BIT */\ + size_t count;\ \ /* Flags indicating errors or success */ \ int flag; \ @@ -152,19 +157,6 @@ /* Iterator State */ \ /* Iterator Movement */ \ /* Iterator Access */ \ -\ - /* Utility Methods */ \ - /* Translates a bit index to a word index */ \ - static inline size_t CMC_(PFX, _bit_to_index)(size_t idx) \ - { \ - /* Calculate how many shifts based on the size of cmc_bitset_word */ \ - static const size_t shift = \ - ((sizeof(cmc_bitset_word) * 8) >> 6) > 0 \ - ? 6 \ - : ((sizeof(cmc_bitset_word) * 8) >> 5) > 0 ? 5 : ((sizeof(cmc_bitset_word) * 8) >> 4) > 0 ? 4 : 3; \ -\ - return idx >> shift; \ - } /* ------------------------------------------------------------------------- * Source @@ -190,7 +182,7 @@ if (!alloc) \ alloc = &cmc_alloc_node_default; \ \ - size_t capacity = CMC_(PFX, _bit_to_index)(n_bits - 1) + 1; \ + size_t capacity = cmc_bidx_to_widx(n_bits - 1) + 1; \ \ struct SNAME *_bitset_ = alloc->malloc(sizeof(struct SNAME)); \ \ @@ -231,7 +223,7 @@ if (!alloc) \ alloc = &cmc_alloc_node_default; \ \ - size_t capacity = CMC_(PFX, _bit_to_index)(n_bits - 1) + 1; \ + size_t capacity = cmc_bidx_to_widx(n_bits - 1) + 1; \ \ _bitset_.buffer = alloc->calloc(capacity, sizeof(cmc_bitset_word)); \ \ @@ -280,7 +272,7 @@ /* How many bits in a word */ \ const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ \ - size_t i = CMC_(PFX, _bit_to_index)(bit_index); \ + size_t i = cmc_bidx_to_widx(bit_index); \ \ _bitset_->buffer[i] |= ((cmc_bitset_word)1) << (bit_index % bits); \ \ @@ -302,8 +294,8 @@ if (!CMC_(PFX, _impl_resize)(_bitset_, to + 1, false)) \ return false; \ \ - size_t start_index = CMC_(PFX, _bit_to_index)(from); \ - size_t end_index = CMC_(PFX, _bit_to_index)(to); \ + size_t start_index = cmc_bidx_to_widx(from); \ + size_t end_index = cmc_bidx_to_widx(to); \ \ /* How many bits in a word */ \ const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ @@ -346,7 +338,7 @@ /* How many bits in a word */ \ const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ \ - size_t i = CMC_(PFX, _bit_to_index)(bit_index); \ + size_t i = cmc_bidx_to_widx(bit_index); \ \ _bitset_->buffer[i] &= ~(((cmc_bitset_word)1) << (bit_index % bits)); \ \ @@ -368,8 +360,8 @@ if (!CMC_(PFX, _impl_resize)(_bitset_, to + 1, false)) \ return false; \ \ - size_t start_index = CMC_(PFX, _bit_to_index)(from); \ - size_t end_index = CMC_(PFX, _bit_to_index)(to); \ + size_t start_index = cmc_bidx_to_widx(from); \ + size_t end_index = cmc_bidx_to_widx(to); \ \ /* How many bits in a word */ \ const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ @@ -412,7 +404,7 @@ /* How many bits in a word */ \ const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ \ - size_t i = CMC_(PFX, _bit_to_index)(bit_index); \ + size_t i = cmc_bidx_to_widx(bit_index); \ \ _bitset_->buffer[i] ^= ((cmc_bitset_word)1) << (bit_index % bits); \ \ @@ -434,8 +426,8 @@ if (!CMC_(PFX, _impl_resize)(_bitset_, to + 1, false)) \ return false; \ \ - size_t start_index = CMC_(PFX, _bit_to_index)(from); \ - size_t end_index = CMC_(PFX, _bit_to_index)(to); \ + size_t start_index = cmc_bidx_to_widx(from); \ + size_t end_index = cmc_bidx_to_widx(to); \ \ /* How many bits in a word */ \ const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ @@ -527,7 +519,7 @@ /* How many bits in a word */ \ const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ \ - cmc_bitset_word w = _bitset_->buffer[CMC_(PFX, _bit_to_index)(bit_index)]; \ + cmc_bitset_word w = _bitset_->buffer[cmc_bidx_to_widx(bit_index)]; \ \ return w & ((cmc_bitset_word)1 << (bit_index % bits)); \ } \ @@ -549,7 +541,7 @@ \ /* -1 because n_bits is 1-based and we need to pass a 0-based index */ \ /* +1 to have a 1-based result */ \ - size_t words = CMC_(PFX, _bit_to_index)(n_bits - 1) + 1; \ + size_t words = cmc_bidx_to_widx(n_bits - 1) + 1; \ \ /* Be sure we are not always shrinking when we just want to make */ \ /* sure that we have enough size for n_bits */ \ diff --git a/src/cor/bitset.h b/src/cor/bitset.h index 29901a5..9f793af 100644 --- a/src/cor/bitset.h +++ b/src/cor/bitset.h @@ -25,4 +25,20 @@ typedef CMC_BITSET_WORD_TYPE cmc_bitset_word; +/** + * cmc_bit_to_index + * + * Translates a bit index to a word index + */ +static inline size_t cmc_bidx_to_widx(size_t idx) +{ + /* Calculate how many shifts based on the size of cmc_bitset_word */ + static const size_t shift = + ((sizeof(cmc_bitset_word) * 8) >> 6) > 0 + ? 6 + : ((sizeof(cmc_bitset_word) * 8) >> 5) > 0 ? 5 : ((sizeof(cmc_bitset_word) * 8) >> 4) > 0 ? 4 : 3; + + return idx >> shift; +} + #endif /* CMC_COR_BITSET_H */ diff --git a/tests/include/cmc/bitset.h b/tests/include/cmc/bitset.h index 0918550..0c693e0 100644 --- a/tests/include/cmc/bitset.h +++ b/tests/include/cmc/bitset.h @@ -8,6 +8,7 @@ struct bitset { cmc_bitset_word *buffer; size_t capacity; + size_t count; int flag; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; @@ -39,13 +40,5 @@ _Bool bs_clear_all(struct bitset *_bitset_); _Bool bs_flip_all(struct bitset *_bitset_); _Bool bs_get(struct bitset *_bitset_, size_t bit_index); _Bool bs_resize(struct bitset *_bitset_, size_t n_bits); -static inline size_t bs_bit_to_index(size_t idx) -{ - static const size_t shift = - ((sizeof(cmc_bitset_word) * 8) >> 6) > 0 - ? 6 - : ((sizeof(cmc_bitset_word) * 8) >> 5) > 0 ? 5 : ((sizeof(cmc_bitset_word) * 8) >> 4) > 0 ? 4 : 3; - return idx >> shift; -} #endif /* CMC_CMC_BITSET_TEST_H */ diff --git a/tests/src/cmc/bitset.c b/tests/src/cmc/bitset.c index 68baf71..39865ba 100644 --- a/tests/src/cmc/bitset.c +++ b/tests/src/cmc/bitset.c @@ -13,7 +13,7 @@ struct bitset *bs_new_custom(size_t n_bits, struct cmc_alloc_node *alloc, struct return ((void *)0); if (!alloc) alloc = &cmc_alloc_node_default; - size_t capacity = bs_bit_to_index(n_bits - 1) + 1; + size_t capacity = cmc_bidx_to_widx(n_bits - 1) + 1; struct bitset *_bitset_ = alloc->malloc(sizeof(struct bitset)); if (!_bitset_) return ((void *)0); @@ -42,7 +42,7 @@ struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node *alloc, return _bitset_; if (!alloc) alloc = &cmc_alloc_node_default; - size_t capacity = bs_bit_to_index(n_bits - 1) + 1; + size_t capacity = cmc_bidx_to_widx(n_bits - 1) + 1; _bitset_.buffer = alloc->calloc(capacity, sizeof(cmc_bitset_word)); if (!_bitset_.buffer) return _bitset_; @@ -76,7 +76,7 @@ _Bool bs_set(struct bitset *_bitset_, size_t bit_index) if (!bs_impl_resize(_bitset_, bit_index + 1, 0)) return 0; const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; - size_t i = bs_bit_to_index(bit_index); + size_t i = cmc_bidx_to_widx(bit_index); _bitset_->buffer[i] |= ((cmc_bitset_word)1) << (bit_index % bits); _bitset_->flag = CMC_FLAG_OK; if ((_bitset_)->callbacks && (_bitset_)->callbacks->create) @@ -93,8 +93,8 @@ _Bool bs_set_range(struct bitset *_bitset_, size_t from, size_t to) } if (!bs_impl_resize(_bitset_, to + 1, 0)) return 0; - size_t start_index = bs_bit_to_index(from); - size_t end_index = bs_bit_to_index(to); + size_t start_index = cmc_bidx_to_widx(from); + size_t end_index = cmc_bidx_to_widx(to); const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; const cmc_bitset_word ones = ~((cmc_bitset_word)0); cmc_bitset_word shift_start = from % bits; @@ -123,7 +123,7 @@ _Bool bs_clear(struct bitset *_bitset_, size_t bit_index) if (!bs_impl_resize(_bitset_, bit_index + 1, 0)) return 0; const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; - size_t i = bs_bit_to_index(bit_index); + size_t i = cmc_bidx_to_widx(bit_index); _bitset_->buffer[i] &= ~(((cmc_bitset_word)1) << (bit_index % bits)); _bitset_->flag = CMC_FLAG_OK; if ((_bitset_)->callbacks && (_bitset_)->callbacks->delete) @@ -140,8 +140,8 @@ _Bool bs_clear_range(struct bitset *_bitset_, size_t from, size_t to) } if (!bs_impl_resize(_bitset_, to + 1, 0)) return 0; - size_t start_index = bs_bit_to_index(from); - size_t end_index = bs_bit_to_index(to); + size_t start_index = cmc_bidx_to_widx(from); + size_t end_index = cmc_bidx_to_widx(to); const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; const cmc_bitset_word ones = ~((cmc_bitset_word)0); cmc_bitset_word shift_start = from % bits; @@ -170,7 +170,7 @@ _Bool bs_flip(struct bitset *_bitset_, size_t bit_index) if (!bs_impl_resize(_bitset_, bit_index + 1, 0)) return 0; const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; - size_t i = bs_bit_to_index(bit_index); + size_t i = cmc_bidx_to_widx(bit_index); _bitset_->buffer[i] ^= ((cmc_bitset_word)1) << (bit_index % bits); _bitset_->flag = CMC_FLAG_OK; if ((_bitset_)->callbacks && (_bitset_)->callbacks->update) @@ -187,8 +187,8 @@ _Bool bs_flip_range(struct bitset *_bitset_, size_t from, size_t to) } if (!bs_impl_resize(_bitset_, to + 1, 0)) return 0; - size_t start_index = bs_bit_to_index(from); - size_t end_index = bs_bit_to_index(to); + size_t start_index = cmc_bidx_to_widx(from); + size_t end_index = cmc_bidx_to_widx(to); const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; const cmc_bitset_word ones = ~((cmc_bitset_word)0); cmc_bitset_word shift_start = from % bits; @@ -259,7 +259,7 @@ _Bool bs_flip_all(struct bitset *_bitset_) _Bool bs_get(struct bitset *_bitset_, size_t bit_index) { const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; - cmc_bitset_word w = _bitset_->buffer[bs_bit_to_index(bit_index)]; + cmc_bitset_word w = _bitset_->buffer[cmc_bidx_to_widx(bit_index)]; return w & ((cmc_bitset_word)1 << (bit_index % bits)); } _Bool bs_resize(struct bitset *_bitset_, size_t n_bits) @@ -273,7 +273,7 @@ _Bool bs_impl_resize(struct bitset *_bitset_, size_t n_bits, _Bool do_resize) _bitset_->flag = CMC_FLAG_INVALID; return 0; } - size_t words = bs_bit_to_index(n_bits - 1) + 1; + size_t words = cmc_bidx_to_widx(n_bits - 1) + 1; if (!do_resize && words <= _bitset_->capacity) return 1; cmc_bitset_word *new_buffer = realloc(_bitset_->buffer, words * sizeof(cmc_bitset_word)); diff --git a/tests/unt/cmc/bitset.h b/tests/unt/cmc/bitset.h index 41f490e..daf9757 100644 --- a/tests/unt/cmc/bitset.h +++ b/tests/unt/cmc/bitset.h @@ -20,7 +20,7 @@ CMC_CREATE_UNIT(CMCBitSet, true, { cmc_assert_not_equals(ptr, NULL, bs); cmc_assert_not_equals(ptr, NULL, bs->buffer); - cmc_assert_equals(size_t, bs_bit_to_index(63) + 1, bs->capacity); + cmc_assert_equals(size_t, cmc_bidx_to_widx(63) + 1, bs->capacity); cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, bs->alloc->malloc); cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, bs->alloc->calloc); cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, bs->alloc->realloc); @@ -31,7 +31,7 @@ CMC_CREATE_UNIT(CMCBitSet, true, { bs = bs_new(129); - cmc_assert_equals(size_t, bs_bit_to_index(128) + 1, bs->capacity); + cmc_assert_equals(size_t, cmc_bidx_to_widx(128) + 1, bs->capacity); bs_free(bs); @@ -45,7 +45,7 @@ CMC_CREATE_UNIT(CMCBitSet, true, { cmc_assert_not_equals(ptr, NULL, bs); cmc_assert_not_equals(ptr, NULL, bs->buffer); - cmc_assert_equals(size_t, bs_bit_to_index(63) + 1, bs->capacity); + cmc_assert_equals(size_t, cmc_bidx_to_widx(63) + 1, bs->capacity); cmc_assert_equals(ptr, bs_alloc_node, bs->alloc); cmc_assert_equals(ptr, callbacks, bs->callbacks); @@ -53,7 +53,7 @@ CMC_CREATE_UNIT(CMCBitSet, true, { bs = bs_new_custom(129, NULL, NULL); - cmc_assert_equals(size_t, bs_bit_to_index(128) + 1, bs->capacity); + cmc_assert_equals(size_t, cmc_bidx_to_widx(128) + 1, bs->capacity); bs_free(bs); bs = bs_new_custom(0, bs_alloc_node, callbacks); @@ -65,7 +65,7 @@ CMC_CREATE_UNIT(CMCBitSet, true, { struct bitset bs = bs_init(64); cmc_assert_not_equals(ptr, NULL, bs.buffer); - cmc_assert_equals(size_t, bs_bit_to_index(63) + 1, bs.capacity); + cmc_assert_equals(size_t, cmc_bidx_to_widx(63) + 1, bs.capacity); cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, bs.alloc->malloc); cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, bs.alloc->calloc); cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, bs.alloc->realloc); @@ -76,7 +76,7 @@ CMC_CREATE_UNIT(CMCBitSet, true, { bs = bs_init(129); - cmc_assert_equals(size_t, bs_bit_to_index(128) + 1, bs.capacity); + cmc_assert_equals(size_t, cmc_bidx_to_widx(128) + 1, bs.capacity); bs_release(bs); @@ -89,7 +89,7 @@ CMC_CREATE_UNIT(CMCBitSet, true, { struct bitset bs = bs_init_custom(64, bs_alloc_node, callbacks); cmc_assert_not_equals(ptr, NULL, bs.buffer); - cmc_assert_equals(size_t, bs_bit_to_index(63) + 1, bs.capacity); + cmc_assert_equals(size_t, cmc_bidx_to_widx(63) + 1, bs.capacity); cmc_assert_equals(ptr, bs_alloc_node, bs.alloc); cmc_assert_equals(ptr, callbacks, bs.callbacks); @@ -97,7 +97,7 @@ CMC_CREATE_UNIT(CMCBitSet, true, { bs = bs_init_custom(129, NULL, NULL); - cmc_assert_equals(size_t, bs_bit_to_index(128) + 1, bs.capacity); + cmc_assert_equals(size_t, cmc_bidx_to_widx(128) + 1, bs.capacity); bs_release(bs); @@ -149,11 +149,11 @@ CMC_CREATE_UNIT(CMCBitSet, true, { cmc_assert(bs_set(bs, word_bits * 8 - 1)); cmc_assert_equals(CMC_BITSET_WORD_TYPE, ((cmc_bitset_word)1 << (word_bits - 1)), - bs->buffer[bs_bit_to_index(word_bits * 8 - 1)]); + bs->buffer[cmc_bidx_to_widx(word_bits * 8 - 1)]); cmc_assert(bs_set(bs, word_bits * 18 - 2)); cmc_assert_equals(CMC_BITSET_WORD_TYPE, ((cmc_bitset_word)1 << (word_bits - 2)), - bs->buffer[bs_bit_to_index(word_bits * 18 - 2)]); + bs->buffer[cmc_bidx_to_widx(word_bits * 18 - 2)]); bs_free(bs); }); @@ -182,16 +182,16 @@ CMC_CREATE_UNIT(CMCBitSet, true, { cmc_assert(bs_set_range(bs, word_bits * 6 - 2, word_bits * 6 - 2)); cmc_assert_equals(CMC_BITSET_WORD_TYPE, ((cmc_bitset_word)1 << (word_bits - 2)), - bs->buffer[bs_bit_to_index(word_bits * 6 - 2)]); + bs->buffer[cmc_bidx_to_widx(word_bits * 6 - 2)]); // Make sure we have at least word_bits * 40 slots bs_set(bs, word_bits * 40); cmc_assert(bs_set_range(bs, word_bits * 20, word_bits * 21 - 1)); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, (~(cmc_bitset_word)0), bs->buffer[bs_bit_to_index(word_bits * 20)]); + cmc_assert_equals(CMC_BITSET_WORD_TYPE, (~(cmc_bitset_word)0), bs->buffer[cmc_bidx_to_widx(word_bits * 20)]); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[bs_bit_to_index(word_bits * 20 - 1)]); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[bs_bit_to_index(word_bits * 21 + 1)]); + cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[cmc_bidx_to_widx(word_bits * 20 - 1)]); + cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[cmc_bidx_to_widx(word_bits * 21 + 1)]); cmc_assert(bs_set_range(bs, 0, word_bits * 100 - 1)); cmc_assert_equals(size_t, 100, bs->capacity); @@ -238,7 +238,7 @@ CMC_CREATE_UNIT(CMCBitSet, true, { cmc_assert(bs_set_range(bs, word_bits * 20, word_bits * 21 - 1)); cmc_assert(bs_clear_range(bs, word_bits * 20, word_bits * 21 - 1)); - cmc_assert_equals(uint32_t, 0, bs->buffer[bs_bit_to_index(word_bits * 20)]); + cmc_assert_equals(uint32_t, 0, bs->buffer[cmc_bidx_to_widx(word_bits * 20)]); for (size_t i = 0; i < bs->capacity; i++) bs->buffer[i] = ~((cmc_bitset_word)0);