M src/bitarr.c => src/bitarr.c +8 -9
@@ 2,20 2,20 @@
#include "bitops.h"
#include <stdint.h>
-BitArray* BitArray_calloc(uint32_t n, uint8_t l)
+BitArray* BitArray_calloc(uint32_t n, uint8_t element_size, size_t word_size)
{
- unsigned int n_entries = 1 + (((l * n) - 1) / WORD_SIZE);
+ unsigned int n_entries = 1 + (((element_size * n) - 1) / 32);
// space for bitarray + space needed for n_entries of word_size
- BitArray *bitarr = calloc(1, sizeof(BitArray) + WORD_SIZE * n_entries);
+ BitArray *bitarr = calloc(1, sizeof(BitArray) + (word_size * CHAR_BIT) * n_entries);
if (bitarr == NULL) {
printf("Couldn't allocate memory for vector.\n");
exit(EXIT_FAILURE);
}
// Set values
- bitarr->l = l;
- bitarr->width = WORD_SIZE;
+ bitarr->element_size = element_size;
+ bitarr->width = word_size * CHAR_BIT;
bitarr->n = n;
-
+
return bitarr;
}
@@ 23,10 23,9 @@ void BitArray_free(BitArray *bitarr) {
free(bitarr);
}
-
-BitArray* BitArray_init(unsigned int A[], uint32_t n, uint8_t l)
+BitArray* BitArray_init(unsigned int A[], uint32_t n, uint8_t element_size, size_t word_size)
{
- BitArray* bit_arr = BitArray_calloc(n, l);
+ BitArray* bit_arr = BitArray_calloc(n, element_size, word_size);
// Compress values from A into BitArray
unsigned int i;
for (i = 0; i < n; ++i) BitArray_write(bit_arr, i, A[i]);
M src/bitarr.h => src/bitarr.h +10 -20
@@ 17,7 17,7 @@
* │ │ │ │ │ │ │ │ │ │
* ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼
* ┌──────┬──────┬──────┬──────┬──────┬──────┬──────┬──────┬──────┬──────┐
- * B │10100 │10010 │10110 │10110 │10000 │10101 │01011 │10110 │10101 │10101 │
+ * B │10100 │10010 │10110 │10110 │10000 │10101 │01011 │10110 │10101 │10101 │
* └──────┴──────┴──────┴──────┴──────┴──────┴──────┴──────┴──────┴──────┘
* │ │ │ │ │ │ │ │ │ │
* │ │ │ B is a virtual bit array │ │ │ │
@@ 63,6 63,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
+#include <limits.h>
typedef enum {
@@ 72,25 73,13 @@ typedef enum {
} BITARR_ERROR;
-// The size of each 'word' in W is 4 bytes (32 bits)
-// sizeof(uint32_t) == sizeof(int) == (sizeof(unsigned int) * 2)
-//
-// NOTE:
-// What is the valid type (or size) to consider as the systems word size?
-// Is it appropriate to just define the size in our implementation?
-// - https://stackoverflow.com/q/35843365
-// - https://stackoverflow.com/q/14792068
-//
-//
-#define WORD_SIZE (sizeof(uint32_t) * 8)
-
/**
* @struct BitArray
*
* Compact BitArray implementation where each element in the original array (A)
* is the same size.
*
- * @var BitArray.l
+ * @var BitArray.l
* number of bits to store each value in A
* @var BitArray.width
* number of bits of each member in v (e.g. 32)
@@ 100,10 89,10 @@ typedef enum {
* compressed version of A (v)
*/
typedef struct {
- uint8_t l;
- uint8_t width;
+ size_t element_size;
+ uint8_t width;
uint32_t n;
- unsigned int v[];
+ unsigned int v[];
} BitArray;
@@ 114,12 103,12 @@ typedef struct {
* @param l Size in bits of each item
* @return Pointer to BitArray
*/
-BitArray* BitArray_calloc(uint32_t n, uint8_t l);
+BitArray* BitArray_calloc(uint32_t n, uint8_t element_size, size_t word_size);
/**
* @brief Free BitArray allocated on the heap
*
- * @param bitarr
+ * @param bitarr
*/
void BitArray_free(BitArray *bitarr);
@@ 131,7 120,8 @@ void BitArray_free(BitArray *bitarr);
* @param l Maximum number of bits for each element in A
* @return pointer to BitArray
*/
-BitArray* BitArray_init(unsigned int A[], uint32_t length, uint8_t l);
+BitArray* BitArray_init(unsigned int A[], uint32_t length, uint8_t element_size,
+ size_t word_size);
#endif // BITARR_H_
M src/bitarr_io.c => src/bitarr_io.c +4 -8
@@ 1,8 1,4 @@
#include "bitarr_io.h"
-#include "bitarr.h"
-#include <stdio.h>
-#include <string.h>
-
void BitArray_save(BitArray* bitarr, FILE *fp)
{
@@ 11,12 7,12 @@ void BitArray_save(BitArray* bitarr, FILE *fp)
fwrite(&BIT_MAGIC_NUMBER, sizeof(char), strlen(BIT_MAGIC_NUMBER), fp);
// BitArray metadata needed to construct data structure
- fwrite(&bitarr->l, sizeof(uint8_t), 1, fp);
+ fwrite(&bitarr->element_size, sizeof(uint8_t), 1, fp);
fwrite(&bitarr->width, sizeof(uint8_t), 1, fp);
fwrite(&bitarr->n, sizeof(uint32_t), 1, fp);
// Write out compressed array
- unsigned int n_entries = 1 + (((bitarr->l * bitarr->n) - 1) / WORD_SIZE);
+ unsigned int n_entries = 1 + (((bitarr->element_size * bitarr->n) - 1) / bitarr->width);
fwrite(&(bitarr->v), sizeof(unsigned int), n_entries, fp);
}
@@ 37,9 33,9 @@ BitArray* BitArray_open(FILE *fp)
fread(&l, sizeof(uint8_t), 1, fp);
fread(&width, sizeof(uint8_t), 1, fp);
fread(&n, sizeof(uint32_t), 1, fp);
- BitArray* bitarr = BitArray_calloc(n, l);
+ BitArray* bitarr = BitArray_calloc(n, l, width / CHAR_BIT);
// Read in compressed array
- fread(&(bitarr->v), WORD_SIZE, 1, fp);
+ fread(&(bitarr->v), width, 1, fp);
return bitarr;
}
M src/bitops.c => src/bitops.c +4 -3
@@ 14,7 14,6 @@ extern inline unsigned int sig_bit_idx(unsigned int j, unsigned int word_size)
// -- Single bit ops ----------------------------------------------------------
unsigned int BitArray_bitread(BitArray* bit_arr, unsigned int j) {
- // TODO: Add range checking
return (bit_arr->v[j/bit_arr->width] >> (j % bit_arr->width)) & 1;
}
@@ 70,7 69,8 @@ unsigned int BitArray_read(BitArray* bit_arr, unsigned int i)
fprintf(stderr, "%s:%d Out of bounds index\n", __FILE__, __LINE__);
exit(OUT_OF_BOUNDS);
}
- return BitArray_bitsread(bit_arr, i*bit_arr->l, (i+1)*bit_arr->l-1);
+ return BitArray_bitsread(bit_arr, i*bit_arr->element_size,
+ (i+1)*bit_arr->element_size-1);
}
// -- Writing -----------------------------------------------------------------
@@ 115,5 115,6 @@ void BitArray_write(BitArray* bit_arr, unsigned int i, unsigned int x)
fprintf(stderr, "%s:%d Out of bounds index\n", __FILE__, __LINE__);
exit(OUT_OF_BOUNDS);
}
- BitArray_bitswrite(bit_arr, i*bit_arr->l, (i+1)*bit_arr->l-1, x);
+ BitArray_bitswrite(bit_arr, i*bit_arr->element_size,
+ (i+1)*bit_arr->element_size-1, x);
}
M tests/tests.c => tests/tests.c +1 -1
@@ 29,7 29,7 @@ unsigned int B_sig_ordered[64] = {
0,1,0,0,1,1,0,1,1,0,1,0,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};
unsigned int correct_W[2] = { 3943389780, 177586} ;
-BitArray* bit_arr = BitArray_init(A, (sizeof(A)/sizeof(A[0])), 5);
+BitArray* bit_arr = BitArray_init(A, (sizeof(A)/sizeof(A[0])), 5, sizeof(uint32_t));
static char bit_arr_fp[] = "./data/bitarr_test.bit";