From 07c567ba239c5149eceb3e47450056b15d53aed1 Mon Sep 17 00:00:00 2001 From: Nimit Bhardwaj Date: Sat, 1 Jul 2017 09:54:23 +0530 Subject: [PATCH 01/10] Definations of basic functions of Bitset --- src/bitset.c | 21 ++++++++++++ src/include/bitset.h | 81 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 src/bitset.c create mode 100644 src/include/bitset.h diff --git a/src/bitset.c b/src/bitset.c new file mode 100644 index 0000000..e5c68c7 --- /dev/null +++ b/src/bitset.c @@ -0,0 +1,21 @@ +/* + * Collections-C + * Copyright (C) 2013-2014 Srđan Panić + * + * This file is part of Collections-C. + * + * Collections-C is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Collections-C is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Collections-C. If not, see . + */ + +#include "array.h" diff --git a/src/include/bitset.h b/src/include/bitset.h new file mode 100644 index 0000000..5d29168 --- /dev/null +++ b/src/include/bitset.h @@ -0,0 +1,81 @@ +/* + * Collections-C + * Copyright (C) 2013-2017 Srđan Panić + * + * This file is part of Collections-C. + * + * Collections-C is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Collections-C is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Collections-C. If not, see . + */ + +#ifndef COLLECTIONS_C_BITSET_H +#define COLLECTIONS_C_BITSET_H + +#include "array.h" +#include "common.h" +#define INVALID_BIT -1 + +/* + * A static, space optimized Bitset, all initiallized to 0 and have a constant size. + * Various bitwise operations can be performed on it + * + * It is made on array_s, the size taken for its parameter will be the number of + * bits the actual value for the size of will be calculated internally + */ +typedef struct array_s Bitset; + + +typedef struct bitset_conf_s +{ + /* + * The Bitset struct is based on the Array so ArrayConf is added */ + + ArrayConf cfg; + + /* + * The size is the number of the bits, this is added explicitly even + * ArrayConf has size as it makes the use of BitsetConf easier */ + + size_t size; +} BitsetConf; + +enum cc_stat bitset_new (Bitset **out); +enum cc_stat bitset_new_conf (BitsetConf const * const conf, Bitset **out); +void bitset_conf_init (BitsetConf *cfg); +enum cc_stat bitset_copy (Bitset *bs1, Bitset **out); + +void bitset_destroy (Bitset *bs); +void bitset_destroy_free (Bitset *bs); + +enum cc_stat bitset_setbits_range (Bitset *bs, size_t l, size_t r); +enum cc_stat bitset_unsetbits_range (Bitset *bs, size_t l, size_t r); +enum cc_stat bitset_flipbits_range (Bitset *bs, size_t l, size_t r); +enum cc_stat bitset_setbit_at (Bitset *bs, size_t position); +enum cc_stat bitset_unsetbit_at (Bitset *bs, size_t position); +enum cc_stat bitset_flipbit_at (Bitset *bs, size_t position); +int bitset_getbit_at (Bitset *bs, size_t position); +enum cc_stat bitset_and_operator (Bitset *bs1, Bitset *bs2); +enum cc_stat bitset_or_operator (Bitset *bs1, Bitset *bs2); +enum cc_stat bitset_xor_operator (Bitset *bs1, Bitset *bs2); +enum cc_stat bitset_not_operator (Bitset *bs); +enum cc_stat bitset_left_shift (Bitset *bs); +enum cc_stat bitset_left_shift_cyclic (Bitset *bs); +enum cc_stat bitset_right_shift (Bitset *bs); +enum cc_stat bitset_right_shift_cyclic (Bitset *bs); +int bitset_count_ones (Bitset *bs); +int bitset_count_zeros (Bitset *bs); +enum cc_stat bitset_add (Bitset *bs1, Bitset *bs2, Bitset **out); +enum cc_stat bitset_sub (Bitset *bs1, Bitset *bs2, Bitset **out); +enum cc_stat bitset_multiply (Bitset *bs1, Bitset *bs2, Bitset **out); + +#endif From 52151c670b3ae8559acac49f075f48e26bab1bce Mon Sep 17 00:00:00 2001 From: Nimit Bhardwaj Date: Sat, 1 Jul 2017 14:34:22 +0530 Subject: [PATCH 02/10] Bitset construction, deconstruction, manipulation functions added --- src/bitset.c | 283 +++++++++++++++++++++++++++++++++++++++++++ src/include/bitset.h | 12 +- 2 files changed, 289 insertions(+), 6 deletions(-) diff --git a/src/bitset.c b/src/bitset.c index e5c68c7..5b02529 100644 --- a/src/bitset.c +++ b/src/bitset.c @@ -19,3 +19,286 @@ */ #include "array.h" +#include "bitset.h" + +#define DEFAULT_SIZE 64 +#define CEIL(x,y) x/y+(x%y!=0) + +struct bitset_s +{ + Array *v; + /* Memory Management Function Pointers */ + + void *(*mem_alloc) (size_t size); + void *(*mem_calloc) (size_t blocks, size_t size); + void (*mem_free) (void *block); + + /*The number of ones and zeros in the bitset*/ + size_t nOnes, nZeros; + /*Number of the bits*/ + size_t size; +}; + +/* + * Initializes the fields of BitsetConf to default values + * @param[in, out] conf BitsetConf structure that is being initialized + */ + +void bitset_conf_init(BitsetConf *conf) +{ + array_conf_init(&conf->cfg); + conf->size = DEFAULT_SIZE; +} + +/** + * Creates the new Bitset with the size of Bitset equal to DEFAULT_SIZE + * + * @param[out] out pointer to where the newly created Bitset is to be stored + * + * + * @return CC_OK if the creation was successful, or CC_ERR_ALLOC if the + * memory allocation for the new Bitset structure failed. + */ + +enum cc_stat bitset_new(Bitset **out) +{ + BitsetConf conf; + bitset_conf_init(&conf); + return bitset_new_conf(&conf, out); +} + +/** + * Creates the new Bitset according to given configurations conf + * + * @param[in] conf the pointer to BitsetConf according to which new + * Bitset will be made + * + * @param[out] out the double pointer to the Bitset object created + * @return CC_OK if Bitset created successfully, CC_ERR_ALLOC if + * there was an error in allocating the memory + */ + +enum cc_stat bitset_new_conf (BitsetConf const * const conf, Bitset **out) +{ + size_t i, sz; + char *p; + Bitset *bset = (Bitset *) conf->cfg.mem_calloc(1, sizeof(Bitset)); + if(!bset) + return CC_ERR_ALLOC; + + bset->mem_alloc = conf->cfg.mem_alloc; + bset->mem_calloc = conf->cfg.mem_calloc; + bset->mem_free = conf->cfg.mem_free; + + bset->size = conf->size; + bset->nZeros = conf->size; + bset->nOnes = 0; + + Array *bitvec; + + enum cc_stat status; + + if((status = array_new_conf(&conf->cfg, &bitvec)) == CC_OK) { + bset->v = bitvec; + } else { + conf->cfg.mem_free(bset); + return status; + } + + sz = CEIL(conf->size, 8); + + for(i = 0; i < sz; i++) { + p = (char *) bset->mem_calloc(1, sizeof(char)); + if(!p) { + array_destroy_free(bset->v); + bset->mem_free(bset); + return CC_ERR_ALLOC; + } + *p = 0; + status = array_add(bset->v, p); + if(status != CC_OK) { + array_destroy_free(bset->v); + bset->mem_free(bset); + return status; + } + } + + *out = bset; + return CC_OK; +} + +/** + * Destroys the specified Bitset structure, while leaving the data it holds + * intact. + * + * @param[in] bs the Bitset to be destroyed + */ + +void bitset_destroy(Bitset *bs) +{ + array_destroy(bs->v); + bs->mem_free(bs); +} + +/** + * Destroys the specified Bitset structure along with all the data it holds. + * + * @note This function should not be called on a Bitset that has some of its + * elements allocated on the Stack (stack memory of function calls). + * + * @param[in] bs the Bitset to be destroyed + */ + +void bitset_destroy_free(Bitset *bs) +{ + array_destroy_free(bs->v); + bs->mem_free(bs); +} + +/* + * Return the bit at the position specified in the Bitset + * The index starts from left and is 0-indexed + * + * @param[in] bs the Bitset whose bit we need + * @param[pos] the position parameter + * + * @return 1, if the bit at given position was set + * 0, if the bit at given position was unset + * -1, if the bit at given position was invalid + */ + +int bitset_getbit_at(Bitset *bs, size_t pos) +{ + size_t q = pos / 8, r = 7 - pos % 8; + char *ch; + if(pos >= bs->size) + return INVALID_BIT; + array_get_at(bs->v, q, (void **)&ch); + if((*ch & (1 << r)) == 0) + return 0; + else + return 1; +} + +/* + * Sets the bit at the position specified in the bitset + * + * @param[in] bs the bitmask whose bit need to be set + * @param[in] pos the position of the bit to be set + * @return CC_OK if the operation was successful otherwise + * if the position was invalid, CC_ERR_OUT_OF_RANGE is returned + */ + +enum cc_stat bitset_setbit_at(Bitset *bs, size_t pos) +{ + size_t q = pos / 8, r = 7 - pos % 8; + char *ch; + if(pos >= bs->size) + return CC_ERR_OUT_OF_RANGE; + array_get_at(bs->v, q, (void **)&ch); + *ch = *ch | (1 << r); + return CC_OK; +} + +/* + * Unsets the bit at the position specified in the bitset + * + * @param[in] bs the bitmask whose bit need to be unset + * @param[in] pos the position of the bit to be unset + * @return CC_OK if the operation was successful otherwise + * if the position was invalid, CC_ERR_OUT_OF_RANGE is returned + */ + +enum cc_stat bitset_unsetbit_at(Bitset *bs, size_t pos) +{ + size_t q = pos / 8, r = 7 - pos % 8; + char *ch; + if(pos >= bs->size) + return CC_ERR_OUT_OF_RANGE; + array_get_at(bs->v, q, (void **)&ch); + *ch = *ch & ~(1 << r); + return CC_OK; +} + +/* + * Flips the bit at the position specified in the bitset + * + * @param[in] bs the bitmask whose bit need to be flip + * @param[in] pos the position of the bit to be flip + * @return CC_OK if the operation was successful otherwise + * if the position was invalid, CC_ERR_OUT_OF_RANGE is returned + */ + +enum cc_stat bitset_flipbit_at(Bitset *bs, size_t pos) +{ + int bit = bitset_getbit_at(bs, pos); + if(pos >= bs->size) + return CC_ERR_OUT_OF_RANGE; + if(bit == 0) + return bitset_setbit_at(bs, pos); + else if(bit == 1) + return bitset_unsetbit_at(bs, pos); + else + return CC_ERR_OUT_OF_RANGE; + +} + +/* + * Sets the bits in the given range + * @param[in] bs the input bitset + * @param[in] l the lower bound parameter + * @param[in] r upper bound parameter + * + * @return CC_OK if the operation was successful, + * otherwise CC_ERR_OUT_OF_RANGE if the range is not valid + */ + +enum cc_stat bitset_setbits_range(Bitset *bs, size_t l, size_t r) +{ + size_t i; + if(l >= bs->size || r >= bs->size) + return CC_ERR_OUT_OF_RANGE; + for(i = l; i < r; i++) + bitset_setbit_at(bs, i); + return CC_OK; +} + +/* + * Unsets the bits in the given range + * @param[in] bs the input bitset + * @param[in] l the lower bound parameter + * @param[in] r upper bound parameter + * + * @return CC_OK if the operation was successful, + * otherwise CC_ERR_OUT_OF_RANGE if the range is not valid + */ + +enum cc_stat bitset_unsetbits_range(Bitset *bs, size_t l, size_t r) +{ + size_t i; + if(l >= bs->size || r >= bs->size) + return CC_ERR_OUT_OF_RANGE; + for(i = l; i < r; i++) + bitset_unsetbit_at(bs, i); + return CC_OK; +} + +/* + * Flips the bits in the given range + * @param[in] bs the input bitset + * @param[in] l the lower bound parameter + * @param[in] r upper bound parameter + * + * @return CC_OK if the operation was successful, + * otherwise CC_ERR_OUT_OF_RANGE if the range is not valid + */ + +enum cc_stat bitset_flipbits_range(Bitset *bs, size_t l, size_t r) +{ + size_t i; + if(l >= bs->size || r >= bs->size) + return CC_ERR_OUT_OF_RANGE; + for(i = l; i < r; i++) + bitset_flipbit_at(bs, i); + return CC_OK; +} diff --git a/src/include/bitset.h b/src/include/bitset.h index 5d29168..17357df 100644 --- a/src/include/bitset.h +++ b/src/include/bitset.h @@ -32,7 +32,7 @@ * It is made on array_s, the size taken for its parameter will be the number of * bits the actual value for the size of will be calculated internally */ -typedef struct array_s Bitset; +typedef struct bitset_s Bitset; typedef struct bitset_conf_s @@ -51,19 +51,19 @@ typedef struct bitset_conf_s enum cc_stat bitset_new (Bitset **out); enum cc_stat bitset_new_conf (BitsetConf const * const conf, Bitset **out); -void bitset_conf_init (BitsetConf *cfg); +void bitset_conf_init (BitsetConf *conf); enum cc_stat bitset_copy (Bitset *bs1, Bitset **out); void bitset_destroy (Bitset *bs); void bitset_destroy_free (Bitset *bs); -enum cc_stat bitset_setbits_range (Bitset *bs, size_t l, size_t r); -enum cc_stat bitset_unsetbits_range (Bitset *bs, size_t l, size_t r); -enum cc_stat bitset_flipbits_range (Bitset *bs, size_t l, size_t r); +int bitset_getbit_at (Bitset *bs, size_t position); enum cc_stat bitset_setbit_at (Bitset *bs, size_t position); enum cc_stat bitset_unsetbit_at (Bitset *bs, size_t position); enum cc_stat bitset_flipbit_at (Bitset *bs, size_t position); -int bitset_getbit_at (Bitset *bs, size_t position); +enum cc_stat bitset_setbits_range (Bitset *bs, size_t l, size_t r); +enum cc_stat bitset_unsetbits_range (Bitset *bs, size_t l, size_t r); +enum cc_stat bitset_flipbits_range (Bitset *bs, size_t l, size_t r); enum cc_stat bitset_and_operator (Bitset *bs1, Bitset *bs2); enum cc_stat bitset_or_operator (Bitset *bs1, Bitset *bs2); enum cc_stat bitset_xor_operator (Bitset *bs1, Bitset *bs2); From ba6877a5ebe562fba20881d07e7965740fbfe1f8 Mon Sep 17 00:00:00 2001 From: Nimit Bhardwaj Date: Sat, 1 Jul 2017 14:50:26 +0530 Subject: [PATCH 03/10] Add suggestions and made changes to handle bitcounts --- src/bitset.c | 43 +++++++++++++++++++++++++------------------ src/include/bitset.h | 28 ++++++++++++++-------------- 2 files changed, 39 insertions(+), 32 deletions(-) diff --git a/src/bitset.c b/src/bitset.c index 5b02529..e5a379a 100644 --- a/src/bitset.c +++ b/src/bitset.c @@ -160,18 +160,18 @@ void bitset_destroy_free(Bitset *bs) * The index starts from left and is 0-indexed * * @param[in] bs the Bitset whose bit we need - * @param[pos] the position parameter + * @param[index] the position parameter * * @return 1, if the bit at given position was set * 0, if the bit at given position was unset * -1, if the bit at given position was invalid */ -int bitset_getbit_at(Bitset *bs, size_t pos) +int bitset_getbit_at(Bitset *bs, size_t index) { - size_t q = pos / 8, r = 7 - pos % 8; + size_t q = index / 8, r = 7 - index % 8; char *ch; - if(pos >= bs->size) + if(index >= bs->size) return INVALID_BIT; array_get_at(bs->v, q, (void **)&ch); if((*ch & (1 << r)) == 0) @@ -184,17 +184,21 @@ int bitset_getbit_at(Bitset *bs, size_t pos) * Sets the bit at the position specified in the bitset * * @param[in] bs the bitmask whose bit need to be set - * @param[in] pos the position of the bit to be set + * @param[in] index the position of the bit to be set * @return CC_OK if the operation was successful otherwise * if the position was invalid, CC_ERR_OUT_OF_RANGE is returned */ -enum cc_stat bitset_setbit_at(Bitset *bs, size_t pos) +enum cc_stat bitset_setbit_at(Bitset *bs, size_t index) { - size_t q = pos / 8, r = 7 - pos % 8; + size_t q = index / 8, r = 7 - index % 8; char *ch; - if(pos >= bs->size) + int bit; + if(index >= bs->size) return CC_ERR_OUT_OF_RANGE; + bit = bitset_getbit_at(bs, index); + if(bit == 0) + nOne++, nZeros--; array_get_at(bs->v, q, (void **)&ch); *ch = *ch | (1 << r); return CC_OK; @@ -204,17 +208,20 @@ enum cc_stat bitset_setbit_at(Bitset *bs, size_t pos) * Unsets the bit at the position specified in the bitset * * @param[in] bs the bitmask whose bit need to be unset - * @param[in] pos the position of the bit to be unset + * @param[in] index the position of the bit to be unset * @return CC_OK if the operation was successful otherwise * if the position was invalid, CC_ERR_OUT_OF_RANGE is returned */ -enum cc_stat bitset_unsetbit_at(Bitset *bs, size_t pos) +enum cc_stat bitset_unsetbit_at(Bitset *bs, size_t index) { - size_t q = pos / 8, r = 7 - pos % 8; + size_t q = index / 8, r = 7 - index % 8; char *ch; - if(pos >= bs->size) + if(index >= bs->size) return CC_ERR_OUT_OF_RANGE; + bit = bitset_getbit_at(bs, index); + if(bit == 1) + nOne--, nZeros++; array_get_at(bs->v, q, (void **)&ch); *ch = *ch & ~(1 << r); return CC_OK; @@ -224,20 +231,20 @@ enum cc_stat bitset_unsetbit_at(Bitset *bs, size_t pos) * Flips the bit at the position specified in the bitset * * @param[in] bs the bitmask whose bit need to be flip - * @param[in] pos the position of the bit to be flip + * @param[in] index the position of the bit to be flip * @return CC_OK if the operation was successful otherwise * if the position was invalid, CC_ERR_OUT_OF_RANGE is returned */ -enum cc_stat bitset_flipbit_at(Bitset *bs, size_t pos) +enum cc_stat bitset_flipbit_at(Bitset *bs, size_t index) { - int bit = bitset_getbit_at(bs, pos); - if(pos >= bs->size) + int bit = bitset_getbit_at(bs, index); + if(index >= bs->size) return CC_ERR_OUT_OF_RANGE; if(bit == 0) - return bitset_setbit_at(bs, pos); + return bitset_setbit_at(bs, index); else if(bit == 1) - return bitset_unsetbit_at(bs, pos); + return bitset_unsetbit_at(bs, index); else return CC_ERR_OUT_OF_RANGE; diff --git a/src/include/bitset.h b/src/include/bitset.h index 17357df..2de906d 100644 --- a/src/include/bitset.h +++ b/src/include/bitset.h @@ -57,25 +57,25 @@ enum cc_stat bitset_copy (Bitset *bs1, Bitset **out); void bitset_destroy (Bitset *bs); void bitset_destroy_free (Bitset *bs); -int bitset_getbit_at (Bitset *bs, size_t position); -enum cc_stat bitset_setbit_at (Bitset *bs, size_t position); -enum cc_stat bitset_unsetbit_at (Bitset *bs, size_t position); -enum cc_stat bitset_flipbit_at (Bitset *bs, size_t position); -enum cc_stat bitset_setbits_range (Bitset *bs, size_t l, size_t r); -enum cc_stat bitset_unsetbits_range (Bitset *bs, size_t l, size_t r); -enum cc_stat bitset_flipbits_range (Bitset *bs, size_t l, size_t r); -enum cc_stat bitset_and_operator (Bitset *bs1, Bitset *bs2); -enum cc_stat bitset_or_operator (Bitset *bs1, Bitset *bs2); -enum cc_stat bitset_xor_operator (Bitset *bs1, Bitset *bs2); -enum cc_stat bitset_not_operator (Bitset *bs); +int bitset_getbit_at (Bitset *bs, size_t index); +enum cc_stat bitset_setbit_at (Bitset *bs, size_t index); +enum cc_stat bitset_unsetbit_at (Bitset *bs, size_t index); +enum cc_stat bitset_flipbit_at (Bitset *bs, size_t index); +enum cc_stat bitset_setbits_range (Bitset *bs, size_t from, size_t to); +enum cc_stat bitset_unsetbits_range (Bitset *bs, size_t from, size_t to); +enum cc_stat bitset_flipbits_range (Bitset *bs, size_t from, size_t to); +enum cc_stat bitset_and (Bitset *bs1, Bitset *bs2); +enum cc_stat bitset_or (Bitset *bs1, Bitset *bs2); +enum cc_stat bitset_xor (Bitset *bs1, Bitset *bs2); +enum cc_stat bitset_not (Bitset *bs); enum cc_stat bitset_left_shift (Bitset *bs); enum cc_stat bitset_left_shift_cyclic (Bitset *bs); enum cc_stat bitset_right_shift (Bitset *bs); enum cc_stat bitset_right_shift_cyclic (Bitset *bs); -int bitset_count_ones (Bitset *bs); -int bitset_count_zeros (Bitset *bs); +size_t bitset_count_ones (Bitset *bs); +size_t bitset_count_zeros (Bitset *bs); enum cc_stat bitset_add (Bitset *bs1, Bitset *bs2, Bitset **out); enum cc_stat bitset_sub (Bitset *bs1, Bitset *bs2, Bitset **out); -enum cc_stat bitset_multiply (Bitset *bs1, Bitset *bs2, Bitset **out); +enum cc_stat bitset_multi (Bitset *bs1, Bitset *bs2, Bitset **out); #endif From 11c866d4ff1bff593a456f04f7655795def9ab1e Mon Sep 17 00:00:00 2001 From: Nimit Bhardwaj Date: Sat, 1 Jul 2017 15:01:05 +0530 Subject: [PATCH 04/10] Fix of the errors --- src/bitset.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/bitset.c b/src/bitset.c index e5a379a..f363bd2 100644 --- a/src/bitset.c +++ b/src/bitset.c @@ -198,7 +198,7 @@ enum cc_stat bitset_setbit_at(Bitset *bs, size_t index) return CC_ERR_OUT_OF_RANGE; bit = bitset_getbit_at(bs, index); if(bit == 0) - nOne++, nZeros--; + bs->nOnes++, bs->nZeros--; array_get_at(bs->v, q, (void **)&ch); *ch = *ch | (1 << r); return CC_OK; @@ -219,9 +219,9 @@ enum cc_stat bitset_unsetbit_at(Bitset *bs, size_t index) char *ch; if(index >= bs->size) return CC_ERR_OUT_OF_RANGE; - bit = bitset_getbit_at(bs, index); + int bit = bitset_getbit_at(bs, index); if(bit == 1) - nOne--, nZeros++; + bs->nOnes--, bs->nZeros++; array_get_at(bs->v, q, (void **)&ch); *ch = *ch & ~(1 << r); return CC_OK; From 74eb1ef1b6ee3444141957fdb76835d6a7adf0db Mon Sep 17 00:00:00 2001 From: Nimit Bhardwaj Date: Sun, 2 Jul 2017 12:55:42 +0530 Subject: [PATCH 05/10] Implement functions:count set, unset and get size bits --- src/bitset.c | 59 ++++++++++++++++++++++++++++++++++++++++++++ src/include/bitset.h | 17 +++++++------ 2 files changed, 68 insertions(+), 8 deletions(-) diff --git a/src/bitset.c b/src/bitset.c index f363bd2..3be0327 100644 --- a/src/bitset.c +++ b/src/bitset.c @@ -309,3 +309,62 @@ enum cc_stat bitset_flipbits_range(Bitset *bs, size_t l, size_t r) bitset_flipbit_at(bs, i); return CC_OK; } + +/* + * Return the number of the set bits in the bitset + * @param[in] bs the bitset on which this query is done + * + * @return the number of ones in the bitset + */ + +size_t bitset_count_ones(Bitset *bs) +{ + return bs->nOnes; +} + +/* + * Return the number of the unset bits in the bitset + * @param[in] bs the bitset on which this query is done + * + * @return the number of zeros in the bitset + */ + +size_t bitset_count_zeros(Bitset *bs) +{ + return bs->nZeros; +} + +/* + * Return the number of the bits in the bitset + * @param[in] bs the bitset on which this query is done + * @return the size of the bitset bs + */ + +size_t bitset_size(Bitset *bs) +{ + return bs->size; +} + +/* + * Apply the bitwise AND operator on the bitsets bs1 and bs2 + * if the out is NULL then the resulting bitset is set to bs1 + * if the size of the two bitsets are not equal then the + * result will be of big bitset and the remaining bits of the bitset + * are 0 on which the operation can't be performed. + * The and operation will be performed in the direction of right to left + * which is according to standard AND operation. + * + * @param[in, out] bs1 is input bitset, if out is NULL then output will + * be stored in it + * @param[in] bs2 the second bitset + * @param[out] out set the output to the out, if its NULL then output is bs1 + * + * @return CC_OK if there is success or CC_ERR_ALLOC if there was error in + * allocation of memory for the new bitset + */ + +enum cc_stat bitset_and(Bitset *bs1, Bitset *bs2, Bitset **out) +{ + /*TODO Implement this function*/ + return CC_OK; +} diff --git a/src/include/bitset.h b/src/include/bitset.h index 2de906d..ed27686 100644 --- a/src/include/bitset.h +++ b/src/include/bitset.h @@ -64,16 +64,17 @@ enum cc_stat bitset_flipbit_at (Bitset *bs, size_t index); enum cc_stat bitset_setbits_range (Bitset *bs, size_t from, size_t to); enum cc_stat bitset_unsetbits_range (Bitset *bs, size_t from, size_t to); enum cc_stat bitset_flipbits_range (Bitset *bs, size_t from, size_t to); -enum cc_stat bitset_and (Bitset *bs1, Bitset *bs2); -enum cc_stat bitset_or (Bitset *bs1, Bitset *bs2); -enum cc_stat bitset_xor (Bitset *bs1, Bitset *bs2); -enum cc_stat bitset_not (Bitset *bs); -enum cc_stat bitset_left_shift (Bitset *bs); -enum cc_stat bitset_left_shift_cyclic (Bitset *bs); -enum cc_stat bitset_right_shift (Bitset *bs); -enum cc_stat bitset_right_shift_cyclic (Bitset *bs); +enum cc_stat bitset_and (Bitset *bs1, Bitset *bs2, Bitset **out); +enum cc_stat bitset_or (Bitset *bs1, Bitset *bs2, Bitset **out); +enum cc_stat bitset_xor (Bitset *bs1, Bitset *bs2, Bitset **out); +enum cc_stat bitset_not (Bitset *bs, Bitset **out); +enum cc_stat bitset_left_shift (Bitset *bs, Bitset **out); +enum cc_stat bitset_left_shift_cyclic (Bitset *bs, Bitset **out); +enum cc_stat bitset_right_shift (Bitset *bs, Bitset **out); +enum cc_stat bitset_right_shift_cyclic (Bitset *bs, Bitset **out); size_t bitset_count_ones (Bitset *bs); size_t bitset_count_zeros (Bitset *bs); +size_t bitset_size (Bitset *bs); enum cc_stat bitset_add (Bitset *bs1, Bitset *bs2, Bitset **out); enum cc_stat bitset_sub (Bitset *bs1, Bitset *bs2, Bitset **out); enum cc_stat bitset_multi (Bitset *bs1, Bitset *bs2, Bitset **out); From b7c1476cb484ee70dd01f1cb34ac3a566a94007d Mon Sep 17 00:00:00 2001 From: Nimit Bhardwaj Date: Sun, 2 Jul 2017 13:17:05 +0530 Subject: [PATCH 06/10] Implement bitset_copy function --- src/bitset.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/bitset.c b/src/bitset.c index 3be0327..aaeb6c4 100644 --- a/src/bitset.c +++ b/src/bitset.c @@ -39,6 +39,8 @@ struct bitset_s size_t size; }; +static void *cp(void *P); + /* * Initializes the fields of BitsetConf to default values * @param[in, out] conf BitsetConf structure that is being initialized @@ -127,6 +129,24 @@ enum cc_stat bitset_new_conf (BitsetConf const * const conf, Bitset **out) return CC_OK; } +enum cc_stat bitset_copy(Bitset *bs, Bitset **out) +{ + Bitset *copy = (Bitset *) bs->mem_alloc(sizeof(Bitset)); + if(!copy) { + return CC_ERR_ALLOC; + } + if(array_copy_deep(bs->v, cp, ©->v) != CC_OK) + return CC_ERR_ALLOC; + copy->mem_alloc = bs->mem_alloc; + copy->mem_calloc = bs->mem_calloc; + copy->mem_free = bs->mem_free; + copy->nOnes = bs->nOnes; + copy->nZeros = bs->nZeros; + copy->size = bs->size; + *out = copy; + return CC_OK; +} + /** * Destroys the specified Bitset structure, while leaving the data it holds * intact. @@ -368,3 +388,10 @@ enum cc_stat bitset_and(Bitset *bs1, Bitset *bs2, Bitset **out) /*TODO Implement this function*/ return CC_OK; } + +static void *cp(void *P) +{ + char *ret = (char *) malloc(sizeof(char)); + *ret = *((char *)P); + return (void *) ret; +} From f7c41db9c8a609c6bc14e6d903a001c949f92139 Mon Sep 17 00:00:00 2001 From: Nimit Bhardwaj Date: Sun, 2 Jul 2017 13:27:24 +0530 Subject: [PATCH 07/10] Document bitset_copy --- src/bitset.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/bitset.c b/src/bitset.c index aaeb6c4..030ab26 100644 --- a/src/bitset.c +++ b/src/bitset.c @@ -129,6 +129,15 @@ enum cc_stat bitset_new_conf (BitsetConf const * const conf, Bitset **out) return CC_OK; } +/* + * Do a deep copy of the bitset bt to the out + * @param[in] bs bitset whose copy is to be made + * @param[out] the bitset where the copy is to be stored + * + * @return CC_OK if the operation was a success otherwise CC_ERR_ALLOC + * if there was error in allocation of memory + */ + enum cc_stat bitset_copy(Bitset *bs, Bitset **out) { Bitset *copy = (Bitset *) bs->mem_alloc(sizeof(Bitset)); @@ -389,6 +398,12 @@ enum cc_stat bitset_and(Bitset *bs1, Bitset *bs2, Bitset **out) return CC_OK; } +/* + * A helper function for the bitset_copy, creates a memory of 1 byte and returns + * @param[in] P the pointer to the memory whose copy is needed + * @return ret the pointer of new memory location and value of P copied to it + */ + static void *cp(void *P) { char *ret = (char *) malloc(sizeof(char)); From eb81cab5ff15ec6c6cec3d4276795dcb076579ee Mon Sep 17 00:00:00 2001 From: Nimit Bhardwaj Date: Wed, 5 Jul 2017 16:21:13 +0530 Subject: [PATCH 08/10] Implement bitset_and function --- src/bitset.c | 31 +++++++++++++++++++++++++------ src/include/bitset.h | 2 +- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/bitset.c b/src/bitset.c index 030ab26..93b0f75 100644 --- a/src/bitset.c +++ b/src/bitset.c @@ -20,6 +20,7 @@ #include "array.h" #include "bitset.h" +#include #define DEFAULT_SIZE 64 #define CEIL(x,y) x/y+(x%y!=0) @@ -196,7 +197,7 @@ void bitset_destroy_free(Bitset *bs) * -1, if the bit at given position was invalid */ -int bitset_getbit_at(Bitset *bs, size_t index) +ssize_t bitset_getbit_at(Bitset *bs, size_t index) { size_t q = index / 8, r = 7 - index % 8; char *ch; @@ -376,17 +377,17 @@ size_t bitset_size(Bitset *bs) /* * Apply the bitwise AND operator on the bitsets bs1 and bs2 - * if the out is NULL then the resulting bitset is set to bs1 * if the size of the two bitsets are not equal then the * result will be of big bitset and the remaining bits of the bitset * are 0 on which the operation can't be performed. * The and operation will be performed in the direction of right to left * which is according to standard AND operation. * - * @param[in, out] bs1 is input bitset, if out is NULL then output will - * be stored in it + * The result will be stored int the out + * + * @param[in] bs1 is input bitset * @param[in] bs2 the second bitset - * @param[out] out set the output to the out, if its NULL then output is bs1 + * @param[out] out set the output to the out * * @return CC_OK if there is success or CC_ERR_ALLOC if there was error in * allocation of memory for the new bitset @@ -394,7 +395,25 @@ size_t bitset_size(Bitset *bs) enum cc_stat bitset_and(Bitset *bs1, Bitset *bs2, Bitset **out) { - /*TODO Implement this function*/ + Bitset *tmp1, *tmp2; + enum cc_stat status; + bs1->size > bs2->size ? (status = bitset_copy(bs1, &tmp1), tmp2 = bs2) : (status = bitset_copy(bs2, &tmp1), tmp2 = bs1); + if(status != CC_OK) + return status; + ssize_t i, j; + for(i = tmp1->size - 1, j = tmp2->size - 1; i >= 0 && j >= 0; i--, j--) + { + ssize_t bit1 = bitset_getbit_at(tmp1, i); + ssize_t bit2 = bitset_getbit_at(tmp2, j); + bit1 = bit1 & bit2; + if(bit1 == 0) + bitset_unsetbit_at(tmp1, i); + else + bitset_setbit_at(tmp1, i); + } + for(i = tmp1->size - tmp2->size - 1; i >= 0; i--) + bitset_unsetbit_at(tmp1, i); + *out = tmp1; return CC_OK; } diff --git a/src/include/bitset.h b/src/include/bitset.h index ed27686..7deaf08 100644 --- a/src/include/bitset.h +++ b/src/include/bitset.h @@ -57,7 +57,7 @@ enum cc_stat bitset_copy (Bitset *bs1, Bitset **out); void bitset_destroy (Bitset *bs); void bitset_destroy_free (Bitset *bs); -int bitset_getbit_at (Bitset *bs, size_t index); +ssize_t bitset_getbit_at (Bitset *bs, size_t index); enum cc_stat bitset_setbit_at (Bitset *bs, size_t index); enum cc_stat bitset_unsetbit_at (Bitset *bs, size_t index); enum cc_stat bitset_flipbit_at (Bitset *bs, size_t index); From 9fddcb28bd74861251a3838138d66e7d32b77bb6 Mon Sep 17 00:00:00 2001 From: Nimit Bhardwaj Date: Wed, 5 Jul 2017 16:43:08 +0530 Subject: [PATCH 09/10] Implement bitset_or, bitset_xor, bitset_not functions --- src/bitset.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 96 insertions(+), 2 deletions(-) diff --git a/src/bitset.c b/src/bitset.c index 93b0f75..c866214 100644 --- a/src/bitset.c +++ b/src/bitset.c @@ -20,7 +20,6 @@ #include "array.h" #include "bitset.h" -#include #define DEFAULT_SIZE 64 #define CEIL(x,y) x/y+(x%y!=0) @@ -380,7 +379,7 @@ size_t bitset_size(Bitset *bs) * if the size of the two bitsets are not equal then the * result will be of big bitset and the remaining bits of the bitset * are 0 on which the operation can't be performed. - * The and operation will be performed in the direction of right to left + * The AND operation will be performed in the direction of right to left * which is according to standard AND operation. * * The result will be stored int the out @@ -417,6 +416,101 @@ enum cc_stat bitset_and(Bitset *bs1, Bitset *bs2, Bitset **out) return CC_OK; } +/* + * Apply the bitwise OR operator on the bitsets bs1 and bs2 + * if the size of the two bitsets are not equal then the + * result will be of big bitset and the remaining bits of the bitset + * are left as were in the big bitset on which the operation can't be performed. + * As the standard OR operation the 0 | X = X, so they were left as it is + * The OR operation will be performed in the direction of right to left + * which is according to standard OR operation. + * + * The result will be stored int the out + * + * @param[in] bs1 is input bitset + * @param[in] bs2 the second bitset + * @param[out] out set the output to the out + * + * @return CC_OK if there is success or CC_ERR_ALLOC if there was error in + * allocation of memory for the new bitset + */ + +enum cc_stat bitset_or(Bitset *bs1, Bitset *bs2, Bitset **out) +{ + Bitset *tmp1, *tmp2; + enum cc_stat status; + bs1->size > bs2->size ? (status = bitset_copy(bs1, &tmp1), tmp2 = bs2) : (status = bitset_copy(bs2, &tmp1), tmp2 = bs1); + if(status != CC_OK) + return status; + ssize_t i, j; + for(i = tmp1->size - 1, j = tmp2->size - 1; i >= 0 && j >= 0; i--, j--) + { + ssize_t bit1 = bitset_getbit_at(tmp1, i); + ssize_t bit2 = bitset_getbit_at(tmp2, j); + bit1 = bit1 | bit2; + if(bit1 == 0) + bitset_unsetbit_at(tmp1, i); + else + bitset_setbit_at(tmp1, i); + } + *out = tmp1; + return CC_OK; + +} + +/* + * Apply the bitwise XOR operator on the bitsets bs1 and bs2 + * if the size of the two bitsets are not equal then the + * result will be of big bitset and the remaining bits of the bitset + * are left as were in the big bitset on which the operation can't be performed. + * As the standard OR operation the 0 ^ X = X, so they were left as it is + * The XOR operation will be performed in the direction of right to left + * which is according to standard XOR operation. + * + * The result will be stored int the out + * + * @param[in] bs1 is input bitset + * @param[in] bs2 the second bitset + * @param[out] out set the output to the out + * + * @return CC_OK if there is success or CC_ERR_ALLOC if there was error in + * allocation of memory for the new bitset + */ + +enum cc_stat bitset_xor(Bitset *bs1, Bitset *bs2, Bitset **out) +{ + Bitset *tmp1, *tmp2; + enum cc_stat status; + bs1->size > bs2->size ? (status = bitset_copy(bs1, &tmp1), tmp2 = bs2) : (status = bitset_copy(bs2, &tmp1), tmp2 = bs1); + if(status != CC_OK) + return status; + ssize_t i, j; + for(i = tmp1->size - 1, j = tmp2->size - 1; i >= 0 && j >= 0; i--, j--) + { + ssize_t bit1 = bitset_getbit_at(tmp1, i); + ssize_t bit2 = bitset_getbit_at(tmp2, j); + bit1 = bit1 ^ bit2; + if(bit1 == 0) + bitset_unsetbit_at(tmp1, i); + else + bitset_setbit_at(tmp1, i); + } + *out = tmp1; + return CC_OK; + +} + +enum cc_stat bitset_not(Bitset *bs, Bitset **out) +{ + Bitset *tmp; + enum cc_stat status = bitset_copy(bs, &tmp); + if(status != CC_OK) + return status; + bitset_flipbits_range(tmp, 0, tmp->size - 1); + *out = tmp; + return CC_OK; +} + /* * A helper function for the bitset_copy, creates a memory of 1 byte and returns * @param[in] P the pointer to the memory whose copy is needed From abe92fbb83d8a71aaf1c1cfc93e64e91c6e8f414 Mon Sep 17 00:00:00 2001 From: Nimit Bhardwaj Date: Wed, 5 Jul 2017 16:45:46 +0530 Subject: [PATCH 10/10] Doc for bitset_not --- src/bitset.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/bitset.c b/src/bitset.c index c866214..3ee4fc0 100644 --- a/src/bitset.c +++ b/src/bitset.c @@ -500,6 +500,16 @@ enum cc_stat bitset_xor(Bitset *bs1, Bitset *bs2, Bitset **out) } +/* + * Do the bitwise NOT operatinon on bs and store the result in out + * + * @param[in] bs the input bitset + * @param[out] out the output of function + * + * @return CC_ERR_ALLOC if error in allocation of memory + * otherwise CC_OK + */ + enum cc_stat bitset_not(Bitset *bs, Bitset **out) { Bitset *tmp;