Skip to content

Commit

Permalink
Add utBitArrayOps() to tests/src/utils.c
Browse files Browse the repository at this point in the history
  • Loading branch information
jdeokkim committed Nov 2, 2024
1 parent eec0232 commit edb697c
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 62 deletions.
94 changes: 49 additions & 45 deletions src/external/ferox_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,38 @@

/* Macros =================================================================> */

#define INT_BIT (sizeof(int) * CHAR_BIT)

/* ========================================================================> */

/* Creates a bit array with `count` bits. */
#define frCreateBitArray(count) \
calloc( \
((count) + (INT_BIT - 1) / INT_BIT), \
sizeof(frBitArray) \
)

/* Releases the memory allocated for `ba`. */
#define frReleaseBitArray(ba) \
free(ba)

/* Returns the `i`-th bit of `ba`. */
#define frBitArrayGet(ba, i) \
(((ba) != NULL) \
? !!((ba)[(i) / INT_BIT] & (1 << ((i) % INT_BIT))) \
: -1 \
)

/* Sets the `i`-th bit of `ba`. */
#define frBitArraySet(ba, i) \
((ba)[(i) / INT_BIT] |= (1 << ((i) % INT_BIT)))

/* Resets the `i`-th bit of `ba`. */
#define frBitArrayReset(ba, i) \
((ba)[(i) / INT_BIT] &= ~(1 << ((i) % INT_BIT)))

/* ========================================================================> */

/* A structure that represents a ring buffer for storing indexed data. */
#define frRingBuffer(type) \
struct { \
Expand All @@ -43,28 +75,28 @@
/*
NOTE: https://graphics.stanford.edu/%7Eseander/bithacks.html
Example #1: `v = 0b00010101`
Example #1: `x = 0b00010101`
=> `v = 0b00010100`
=> `v = 0b00011111`
=> `v = 0b00100000`
=> `x = 0b00010100`
=> `x = 0b00011111`
=> `x = 0b00100000`
Example #2: `v = 0b00010100`
Example #2: `x = 0b00010100`
=> `v = 0b00010011`
=> `v = 0b00011111`
=> `v = 0b00100000`
=> `x = 0b00010011`
=> `x = 0b00011111`
=> `x = 0b00100000`
*/

/* Rounds up `v` to the next highest power of 2. */
#define frRoundUp32(v) \
(--(v), \
(v) |= (v) >> 1, \
(v) |= (v) >> 2, \
(v) |= (v) >> 4, \
(v) |= (v) >> 8, \
(v) |= (v) >> 16, \
++(v))
/* Rounds up `x` to the next highest power of 2. */
#define frRoundUp32(x) \
(--(x), \
(x) |= (x) >> 1, \
(x) |= (x) >> 2, \
(x) |= (x) >> 4, \
(x) |= (x) >> 8, \
(x) |= (x) >> 16, \
++(x))

/* ========================================================================> */

Expand Down Expand Up @@ -110,34 +142,6 @@
: false \
)

/* ========================================================================> */

/* Creates a bit array with `count` bits. */
#define frCreateBitArray(count) \
calloc( \
((count) + (INT_BIT - 1) / INT_BIT), \
sizeof(frBitArray) \
)

/* Releases the memory allocated for `ba`. */
#define frReleaseBitArray(ba) \
free(ba)

/* Returns the `i`-th bit of `ba`. */
#define frBitArrayGet(ba, i) \
(((ba) != NULL) \
? ((ba)[(i) / INT_BIT] & (1 << ((i) % INT_BIT))) \
: -1 \
)

/* Sets the `i`-th bit of `ba`. */
#define frBitArraySet(ba, i) \
((ba)[(i) / INT_BIT] |= (1 << ((i) % INT_BIT)))

/* Resets the `i`-th bit of `ba`. */
#define frBitArrayReset(ba, i) \
((ba)[(i) / INT_BIT] &= ~(1 << ((i) % INT_BIT)))

/* Typedefs ===============================================================> */

/* A data type that represents a bit array.*/
Expand Down
48 changes: 31 additions & 17 deletions tests/src/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,47 +29,61 @@

/* Macros ================================================================== */

#define RING_BUFFER_LENGTH (1 << 3)
#define BIT_ARRAY_LENGTH ((1 << 6) + 1)
#define RING_BUFFER_LENGTH ((1 << 4) + 1)

/* Private Function Prototypes ============================================= */

TEST utBitArrayOps(void);
TEST utRingBufferOps(void);

/* Public Functions ======================================================== */

SUITE(utils) {
RUN_TEST(utBitArrayOps);
RUN_TEST(utRingBufferOps);
}

/* Private Functions ======================================================= */

TEST utRingBufferOps(void) {
frRingBuffer(frContextNode) rbf;

frInitRingBuffer(rbf, RING_BUFFER_LENGTH);
TEST utBitArrayOps(void) {
frBitArray ba = frCreateBitArray(BIT_ARRAY_LENGTH);

{
frContextNode node = { .id = 0 };
const int numbers[] = { 42, 4, 15, 8, 15, 16, 4, 23, 15, 42, 16 };

for (int i = 0; i < RING_BUFFER_LENGTH; i++) {
node.id = i;
for (int i = 0, j = (sizeof numbers / sizeof *numbers); i < j; i++)
frBitArraySet(ba, numbers[i]);

bool result = (i < (RING_BUFFER_LENGTH - 1));
int numberCount = 0;

ASSERT_EQ(result, frAddToRingBuffer(rbf, node));
}
for (int i = 0; i < BIT_ARRAY_LENGTH; i++)
if (frBitArrayGet(ba, i)) numberCount++;

ASSERT_EQ(6, numberCount);
}

frReleaseBitArray(ba);

ASSERT_EQ(false, frAddToRingBuffer(rbf, node));
PASS();
}

TEST utRingBufferOps(void) {
frRingBuffer(frContextNode) rbf;

frInitRingBuffer(rbf, RING_BUFFER_LENGTH);

{
frContextNode node = { .id = -1 };

for (int i = 0; i < RING_BUFFER_LENGTH; i++) {
bool result = (i < (RING_BUFFER_LENGTH - 1));
node.id = (i << 1);

ASSERT_EQ(result, frRemoveFromRingBuffer(rbf, &node));

if (result == true) ASSERT_EQ(i, node.id);
ASSERT_EQ(true, frAddToRingBuffer(rbf, node));
}

ASSERT_EQ(false, frRemoveFromRingBuffer(rbf, &node));
while (frRemoveFromRingBuffer(rbf, &node))
ASSERT_EQ(0, node.id & 1);
}

frReleaseRingBuffer(rbf);
Expand Down

0 comments on commit edb697c

Please sign in to comment.