Adding bitset checkpoint

This commit is contained in:
Leonardo committed 2020-05-01 15:52:37 -03:00
1 parent 53f6202709
commit 7ad2462254
4 files changed
+869

No files matched your search

+3
View File
@@ -1,6 +1,7 @@
#include "utl/timer.h"
#include "unt/bidimap.c"
#include "unt/bitset.c"
#include "unt/deque.c"
#include "unt/hashmap.c"
#include "unt/hashset.c"
@@ -47,6 +48,8 @@ int main(void)
uintmax_t tests = 0, units = 0;
cmc_run(BidiMap, units, tests);
cmc_run(BitSet, units, tests);
cmc_run(BitSetIter, units, tests);
cmc_run(Deque, units, tests);
cmc_run(DequeIter, units, tests);
cmc_run(HashMap, units, tests);
+232
View File
@@ -0,0 +1,232 @@
#include "cmc/bitset.h"
struct bitset
{
cmc_bitset_word *buffer;
size_t capacity;
int flag;
struct cmc_alloc_node *alloc;
struct cmc_callbacks *callbacks;
};
struct bitset_iter
{
struct bitset *target;
cmc_bitset_word cursor;
_Bool start;
_Bool end;
};
struct bitset *bs_new(size_t n_bits);
struct bitset *bs_new_custom(size_t n_bits, struct cmc_alloc_node *alloc,
struct cmc_callbacks *callbacks);
struct bitset bs_init(size_t n_bits);
struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node *alloc,
struct cmc_callbacks *callbacks);
void bs_free(struct bitset *_bitset_);
void bs_release(struct bitset _bitset_);
void bs_customize(struct bitset *_bitset_, struct cmc_alloc_node *alloc,
struct cmc_callbacks *callbacks);
_Bool bs_set(struct bitset *_bitset_, size_t bit_index);
_Bool bs_set_range(struct bitset *_bitset_, size_t from, size_t to);
_Bool bs_clear(struct bitset *_bitset_, size_t bit_index);
_Bool bs_clear_range(struct bitset *_bitset_, size_t from, size_t to);
_Bool bs_flip(struct bitset *_bitset_, size_t bit_index);
_Bool bs_flip_range(struct bitset *_bitset_, size_t from, size_t to);
_Bool bs_put(struct bitset *_bitset_, size_t bit_index);
_Bool bs_put_range(struct bitset *_bitset_, size_t from, size_t to);
_Bool bs_fill(struct bitset *_bitset_);
_Bool bs_empty(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 cmc_bitset_word bs_bit_to_index(cmc_bitset_word idx)
{
static const cmc_bitset_word 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;
}
_Bool bs_impl_resize(struct bitset *_bitset_, size_t n_bits, _Bool do_resize);
struct bitset *bs_new(size_t n_bits)
{
return bs_new_custom(n_bits, ((void *)0), ((void *)0));
}
struct bitset *bs_new_custom(size_t n_bits, struct cmc_alloc_node *alloc,
struct cmc_callbacks *callbacks)
{
if (n_bits < 1)
return ((void *)0);
if (!alloc)
alloc = &cmc_alloc_node_default;
size_t capacity = bs_bit_to_index(n_bits - 1) + 1;
struct bitset *_bitset_ = alloc->malloc(sizeof(struct bitset));
if (!_bitset_)
return ((void *)0);
_bitset_->buffer = alloc->calloc(capacity, sizeof(cmc_bitset_word));
if (!_bitset_->buffer)
{
alloc->free(_bitset_);
return ((void *)0);
}
_bitset_->capacity = capacity;
_bitset_->flag = cmc_flags.OK;
_bitset_->alloc = alloc;
_bitset_->callbacks = callbacks;
return _bitset_;
}
struct bitset bs_init(size_t n_bits)
{
return bs_init_custom(n_bits, ((void *)0), ((void *)0));
}
struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node *alloc,
struct cmc_callbacks *callbacks)
{
struct bitset _bitset_ = { 0 };
if (n_bits < 1)
return _bitset_;
if (!alloc)
alloc = &cmc_alloc_node_default;
size_t capacity = bs_bit_to_index(n_bits - 1) + 1;
_bitset_.buffer = alloc->calloc(capacity, sizeof(cmc_bitset_word));
if (!_bitset_.buffer)
return _bitset_;
_bitset_.capacity = capacity;
_bitset_.flag = cmc_flags.OK;
_bitset_.alloc = alloc;
_bitset_.callbacks = callbacks;
return _bitset_;
}
void bs_free(struct bitset *_bitset_)
{
free(_bitset_->buffer);
free(_bitset_);
}
void bs_release(struct bitset _bitset_)
{
free(_bitset_.buffer);
}
void bs_customize(struct bitset *_bitset_, struct cmc_alloc_node *alloc,
struct cmc_callbacks *callbacks)
{
if (!alloc)
_bitset_->alloc = &cmc_alloc_node_default;
else
_bitset_->alloc = alloc;
_bitset_->callbacks = callbacks;
_bitset_->flag = cmc_flags.OK;
}
_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);
_bitset_->buffer[i] |= ((cmc_bitset_word)1) << (bit_index % bits);
_bitset_->flag = cmc_flags.OK;
if (_bitset_->callbacks && _bitset_->callbacks->create)
_bitset_->callbacks->create();
return 1;
}
_Bool bs_set_range(struct bitset *_bitset_, size_t from, size_t to)
{
if (to < from)
{
_bitset_->flag = cmc_flags.INVALID;
return 0;
}
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);
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;
cmc_bitset_word shift_end = (cmc_bitset_word)(-(to + 1)) % bits;
cmc_bitset_word start_mask = ones << shift_start;
cmc_bitset_word end_mask = ones >> shift_end;
if (start_index == end_index)
{
_bitset_->buffer[end_index] |= (start_mask & end_mask);
}
else
{
_bitset_->buffer[start_index] |= start_mask;
for (size_t i = start_index + 1; i < end_index; i++)
_bitset_->buffer[i] |= ~((cmc_bitset_word)0);
_bitset_->buffer[end_index] |= end_mask;
}
_bitset_->flag = cmc_flags.OK;
if (_bitset_->callbacks && _bitset_->callbacks->create)
_bitset_->callbacks->create();
return 1;
}
_Bool bs_clear(struct bitset *_bitset_, size_t bit_index)
{
return 1;
}
_Bool bs_clear_range(struct bitset *_bitset_, size_t from, size_t to)
{
return 1;
}
_Bool bs_flip(struct bitset *_bitset_, size_t bit_index)
{
return 1;
}
_Bool bs_flip_range(struct bitset *_bitset_, size_t from, size_t to)
{
return 1;
}
_Bool bs_put(struct bitset *_bitset_, size_t bit_index)
{
return 1;
}
_Bool bs_put_range(struct bitset *_bitset_, size_t from, size_t to)
{
return 1;
}
_Bool bs_fill(struct bitset *_bitset_)
{
return 1;
}
_Bool bs_empty(struct bitset *_bitset_)
{
return 1;
}
_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)];
return w & ((cmc_bitset_word)1 << (bit_index % bits));
}
_Bool bs_resize(struct bitset *_bitset_, size_t n_bits)
{
return bs_impl_resize(_bitset_, n_bits, 1);
}
_Bool bs_impl_resize(struct bitset *_bitset_, size_t n_bits, _Bool do_resize)
{
if (n_bits == 0)
{
_bitset_->flag = cmc_flags.INVALID;
return 0;
}
size_t words = bs_bit_to_index(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));
if (!new_buffer)
{
_bitset_->flag = cmc_flags.ALLOC;
return 0;
}
_bitset_->buffer = new_buffer;
if (_bitset_->capacity < words)
memset(_bitset_->buffer + _bitset_->capacity, 0,
(words - _bitset_->capacity) * sizeof(cmc_bitset_word));
_bitset_->capacity = words;
if (_bitset_->callbacks && _bitset_->callbacks->resize)
_bitset_->callbacks->resize();
_bitset_->flag = cmc_flags.OK;
return 1;
}
+222
View File
@@ -0,0 +1,222 @@
#include "utl.c"
#include "utl/assert.h"
#include "utl/test.h"
#include "../src/bitset.c"
struct cmc_alloc_node *bs_alloc_node = &(struct cmc_alloc_node){
.malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free
};
CMC_CREATE_UNIT(BitSet, true, {
const size_t word_bytes = sizeof(cmc_bitset_word);
const size_t word_bits = sizeof(cmc_bitset_word) * CHAR_BIT;
CMC_CREATE_TEST(PFX##_new(), {
struct bitset *bs = bs_new(64);
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(ptr, &cmc_alloc_node_default, bs->alloc);
cmc_assert_equals(ptr, NULL, bs->callbacks);
bs_free(bs);
bs = bs_new(129);
cmc_assert_equals(size_t, bs_bit_to_index(128) + 1, bs->capacity);
bs_free(bs);
bs = bs_new(0);
cmc_assert_equals(ptr, NULL, bs);
});
CMC_CREATE_TEST(PFX##_new_custom(), {
struct bitset *bs = bs_new_custom(64, bs_alloc_node, callbacks);
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(ptr, bs_alloc_node, bs->alloc);
cmc_assert_equals(ptr, callbacks, bs->callbacks);
bs_free(bs);
bs = bs_new_custom(129, NULL, NULL);
cmc_assert_equals(size_t, bs_bit_to_index(128) + 1, bs->capacity);
bs_free(bs);
bs = bs_new_custom(0, bs_alloc_node, callbacks);
cmc_assert_equals(ptr, NULL, bs);
});
CMC_CREATE_TEST(PFX##_init(), {
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(ptr, &cmc_alloc_node_default, bs.alloc);
cmc_assert_equals(ptr, NULL, bs.callbacks);
bs_release(bs);
bs = bs_init(129);
cmc_assert_equals(size_t, bs_bit_to_index(128) + 1, bs.capacity);
bs_release(bs);
bs = bs_init(0);
cmc_assert_equals(ptr, NULL, bs.buffer);
});
CMC_CREATE_TEST(PFX##_init_custom(), {
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(ptr, bs_alloc_node, bs.alloc);
cmc_assert_equals(ptr, callbacks, bs.callbacks);
bs_release(bs);
bs = bs_init_custom(129, NULL, NULL);
cmc_assert_equals(size_t, bs_bit_to_index(128) + 1, bs.capacity);
bs_release(bs);
bs = bs_init_custom(0, bs_alloc_node, callbacks);
cmc_assert_equals(ptr, NULL, bs.buffer);
});
CMC_CREATE_TEST(PFX##_customize(), {
struct bitset *bs = bs_new(word_bits);
cmc_assert_not_equals(ptr, NULL, bs);
bs->flag = cmc_flags.ERROR;
bs_customize(bs, bs_alloc_node, callbacks);
cmc_assert_equals(ptr, bs_alloc_node, bs->alloc);
cmc_assert_equals(ptr, callbacks, bs->callbacks);
cmc_assert_equals(int32_t, cmc_flags.OK, bs->flag);
bs->flag = cmc_flags.ERROR;
bs_customize(bs, NULL, NULL);
cmc_assert_equals(ptr, &cmc_alloc_node_default, bs->alloc);
cmc_assert_equals(ptr, NULL, bs->callbacks);
cmc_assert_equals(int32_t, cmc_flags.OK, bs->flag);
bs_free(bs);
});
CMC_CREATE_TEST(PFX##_set(), {
struct bitset *bs = bs_new(word_bits);
cmc_assert_not_equals(ptr, NULL, bs);
cmc_assert(0 == bs->buffer[0]);
bs->flag = cmc_flags.ERROR;
cmc_assert(bs_set(bs, 0));
cmc_assert(1 == bs->buffer[0]);
cmc_assert_equals(int32_t, cmc_flags.OK, bs->flag);
bs->buffer[0] = 0;
cmc_assert(bs_set(bs, word_bits - 1));
cmc_assert(((cmc_bitset_word)1 << (word_bits - 1)) == bs->buffer[0]);
cmc_assert(bs_set(bs, word_bits * 8 - 1));
cmc_assert(((cmc_bitset_word)1 << (word_bits - 1)) ==
bs->buffer[bs_bit_to_index(word_bits * 8 - 1)]);
cmc_assert(bs_set(bs, word_bits * 18 - 2));
cmc_assert(((cmc_bitset_word)1 << (word_bits - 2)) ==
bs->buffer[bs_bit_to_index(word_bits * 18 - 2)]);
bs_free(bs);
});
CMC_CREATE_TEST(PFX##_set_range(), {
struct bitset *bs = bs_new(word_bits);
cmc_assert_not_equals(ptr, NULL, bs);
cmc_assert(0 == bs->buffer[0]);
bs->flag = cmc_flags.ERROR;
cmc_assert(bs_set_range(bs, 0, 0));
cmc_assert_equals(uint8_t, 1, bs->buffer[0]);
cmc_assert_equals(int32_t, cmc_flags.OK, bs->flag);
bs->buffer[0] = 0;
cmc_assert(bs_set_range(bs, 4, 7)); /* 1111 0000 */
cmc_assert_equals(uint8_t, 240, bs->buffer[0]);
cmc_assert(bs_set_range(bs, 2, 2)); /* 1111 0100 */
cmc_assert_equals(uint8_t, 244, bs->buffer[0]);
cmc_assert(bs_set_range(bs, word_bits * 6 - 2, word_bits * 6 - 2));
cmc_assert(((cmc_bitset_word)1 << (word_bits - 2)) ==
bs->buffer[bs_bit_to_index(word_bits * 6 - 2)]);
// Make sure we have at leats 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((~(cmc_bitset_word)0) ==
bs->buffer[bs_bit_to_index(word_bits * 20)]);
cmc_assert(0 == bs->buffer[bs_bit_to_index(word_bits * 20 - 1)]);
cmc_assert(0 == bs->buffer[bs_bit_to_index(word_bits * 21 + 1)]);
bs_free(bs);
});
CMC_CREATE_TEST(PFX##_clear(), {
struct bitset *bs = bs_new(64);
// WIP
bs_free(bs);
});
CMC_CREATE_TEST(PFX##_get(), {
struct bitset *bs = bs_new(64);
cmc_assert_not_equals(ptr, NULL, bs);
cmc_assert(bs_set(bs, 1));
cmc_assert(bs_get(bs, 1));
bs_free(bs);
});
CMC_CREATE_TEST(PFX##_resize(), {
struct bitset *bs = bs_new(64);
// WIP
bs_free(bs);
});
});
CMC_CREATE_UNIT(BitSetIter, true, {
CMC_CREATE_TEST(PFX##_iter_start(), {
struct bitset *bs = bs_new(64);
// WIP
bs_free(bs);
});
});