Skip to content

Commit

Permalink
Update how word size of bitarray is decided
Browse files Browse the repository at this point in the history
  • Loading branch information
ocsmit committed Jul 26, 2023
1 parent a1dd574 commit 7806827
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 41 deletions.
17 changes: 8 additions & 9 deletions src/bitarr.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,30 @@
#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;
}

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]);
Expand Down
30 changes: 10 additions & 20 deletions src/bitarr.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 │ │ │ │
Expand Down Expand Up @@ -63,6 +63,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>


typedef enum {
Expand All @@ -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)
Expand All @@ -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;


Expand All @@ -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);

Expand All @@ -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_
12 changes: 4 additions & 8 deletions src/bitarr_io.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
#include "bitarr_io.h"
#include "bitarr.h"
#include <stdio.h>
#include <string.h>


void BitArray_save(BitArray* bitarr, FILE *fp)
{
Expand All @@ -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);
}

Expand All @@ -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;
}
7 changes: 4 additions & 3 deletions src/bitops.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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 -----------------------------------------------------------------
Expand Down Expand Up @@ -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);
}
2 changes: 1 addition & 1 deletion tests/tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down

0 comments on commit 7806827

Please sign in to comment.