Skip to content

Commit

Permalink
fix and add examples
Browse files Browse the repository at this point in the history
  • Loading branch information
abxh committed Oct 9, 2024
1 parent 2e8fba7 commit 0f26458
Show file tree
Hide file tree
Showing 5 changed files with 283 additions and 2 deletions.
33 changes: 33 additions & 0 deletions examples/fqueue/makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
EXEC_NAME := a.out

CC := gcc
CFLAGS += -I./../../lib
CFLAGS += -Wall -Wextra -Wshadow -Wconversion -pedantic
CFLAGS += -ggdb3
CFLAGS += -fsanitize=undefined
CFLAGS += -fsanitize=address

C_FILES := $(wildcard *.c)
OBJ_FILES := $(C_FILES:.c=.o)

LD_FLAGS += -fsanitize=undefined
LD_FLAGS += -fsanitize=address

.PHONY: all clean test

all: $(EXEC_NAME)

clean:
rm -rf $(OBJ_FILES)
rm -rf $(EXEC_NAME)

test: $(EXEC_NAME)
./a.out

$(EXEC_NAME): $(OBJ_FILES)
$(CC) $(LD_FLAGS) $^ -o $(EXEC_NAME)

$(OBJ_FILES): $(SRC_FILES)

$(SRC_FILES):
$(CC) -c $(CFLAGS) $@
117 changes: 117 additions & 0 deletions examples/fqueue/moving_average_from_data_stream.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@

#include <float.h>
#include <math.h>

#define NAME flt_queue
#define VALUE_TYPE float
#include "fqueue.h"

struct data_stream {
float avg;
struct flt_queue *queue;
};

static inline void data_stream_init(struct data_stream *s, uint32_t max_elm)
{
s->avg = FP_NAN;
s->queue = flt_queue_create(max_elm);
}

static inline void data_stream_deinit(struct data_stream *s)
{
flt_queue_destroy(s->queue);
}

static inline void data_stream_enqueue(struct data_stream *s, float val)
{
if (flt_queue_is_full(s->queue)) {
return;
}
if (s->queue->count == 0) {
s->avg = val;
}
else {
s->avg = (s->avg * (float)s->queue->count + val) / (float)(s->queue->count + 1);
}
flt_queue_enqueue(s->queue, val);
}

static inline float data_stream_dequeue(struct data_stream *s)
{
if (flt_queue_is_empty(s->queue)) {
return FP_NAN;
}
s->avg = (s->avg * (float)(s->queue->count) - flt_queue_peek(s->queue)) / (float)(s->queue->count - 1);
return flt_queue_dequeue(s->queue);
}

static inline void data_stream_print(struct data_stream *s)
{
printf("stream: [");
if (!flt_queue_is_empty(s->queue)) {
printf(" %.2f", flt_queue_at(s->queue, 0));
}
for (size_t i = 1; i < s->queue->count; i++) {
printf(", %.2f", flt_queue_at(s->queue, (uint32_t)i));
}
printf(" ]\n");
}

static inline bool float_is_nearly_equal(const float a, const float b, const uint16_t n)
{
return fabsf(a - b) <= FLT_EPSILON * (float)n;
}

#define print_line(expr) \
__extension__({ \
(expr); \
printf("%-34s", #expr); \
})

int main(void)
{
struct data_stream s;
data_stream_init(&s, 8);

print_line(data_stream_enqueue(&s, 3.f));
printf("average: %-10.2f ", s.avg);
data_stream_print(&s);
assert(float_is_nearly_equal(s.avg, (3.f) / (float)(1), 128));

print_line(data_stream_enqueue(&s, 5.f));
printf("average: %-10.2f ", s.avg);
data_stream_print(&s);
assert(float_is_nearly_equal(s.avg, (3.f + 5.f) / (float)(2), 128));

print_line(data_stream_enqueue(&s, 15.f));
printf("average: %-10.2f ", s.avg);
data_stream_print(&s);
assert(float_is_nearly_equal(s.avg, (3.f + 5.f + 15.f) / (float)(3), 128));

print_line(data_stream_dequeue(&s));
printf("average: %-10.2f ", s.avg);
data_stream_print(&s);
assert(float_is_nearly_equal(s.avg, (5.f + 15.f) / (float)(2), 128));

print_line(data_stream_dequeue(&s));
printf("average: %-10.2f ", s.avg);
data_stream_print(&s);
assert(float_is_nearly_equal(s.avg, (15.f) / (float)(1), 128));

print_line(data_stream_enqueue(&s, 45.f));
printf("average: %-10.2f ", s.avg);
data_stream_print(&s);
assert(float_is_nearly_equal(s.avg, (15.f + 45.f) / (float)(2), 128));

print_line(data_stream_dequeue(&s));
printf("average: %-10.2f ", s.avg);
data_stream_print(&s);
assert(float_is_nearly_equal(s.avg, (45.f) / (float)(1), 128));

print_line(data_stream_dequeue(&s));
printf("average: %-10.2f ", s.avg);
data_stream_print(&s);
assert(isnanf(s.avg));

data_stream_deinit(&s);
}
33 changes: 33 additions & 0 deletions examples/fstack/makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
EXEC_NAME := a.out

CC := gcc
CFLAGS += -I./../../lib
CFLAGS += -Wall -Wextra -Wshadow -Wconversion -pedantic
CFLAGS += -ggdb3
CFLAGS += -fsanitize=undefined
CFLAGS += -fsanitize=address

C_FILES := $(wildcard *.c)
OBJ_FILES := $(C_FILES:.c=.o)

LD_FLAGS += -fsanitize=undefined
LD_FLAGS += -fsanitize=address

.PHONY: all clean test

all: $(EXEC_NAME)

clean:
rm -rf $(OBJ_FILES)
rm -rf $(EXEC_NAME)

test: $(EXEC_NAME)
./a.out

$(EXEC_NAME): $(OBJ_FILES)
$(CC) $(LD_FLAGS) $^ -o $(EXEC_NAME)

$(OBJ_FILES): $(SRC_FILES)

$(SRC_FILES):
$(CC) -c $(CFLAGS) $@
98 changes: 98 additions & 0 deletions examples/fstack/valid_parentheses.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#include <stdint.h>
#include <stdio.h>
#include <string.h>

#define NAME paren_stk
#define VALUE_TYPE char
#include "fstack.h"

void print_paren_stk(struct paren_stk *stk)
{
if (stk->count > 0) {
printf("%c", paren_stk_at(stk, 0));
}
else {
printf("(empty)");
}
for (size_t i = 1; i < stk->count; i++) {
printf(" <- %c", paren_stk_at(stk, (uint32_t)i));
}
printf("\n");
}

char matching_paren(char c)
{
switch (c) {
case '(':
return ')';
case '{':
return '}';
case '[':
return ']';
case ')':
return '(';
case '}':
return '{';
case ']':
return '[';
}
return '\0';
}

bool isValid(char *s)
{
const size_t n = strlen(s);
struct paren_stk *stk = paren_stk_create((uint32_t)n);

bool retVal = true;

for (size_t i = 0; i < n; i++) {
switch (s[i]) {
case '(':
case '{':
case '[':
if (!paren_stk_is_full(stk)) {
paren_stk_push(stk, matching_paren(s[i]));
}
else {
assert(false);
}
break;
case ')':
case '}':
case ']':
retVal &= !paren_stk_is_empty(stk) && paren_stk_pop(stk) == s[i];
break;
default:
assert(false);
break;
}
}
retVal &= stk->count == 0;

paren_stk_destroy(stk);

return retVal;
}

#define print_and_assert(expr, expected) \
__extension__({ \
bool res = (expr); \
assert(res == (expected)); \
printf("%-17s = %s\n", #expr, res ? "true" : "false"); \
})

int main(void)
{
(void)(print_paren_stk);

print_and_assert(isValid("()"), true);
print_and_assert(isValid("("), false);
print_and_assert(isValid(")"), false);
print_and_assert(isValid("(]"), false);
print_and_assert(isValid("([]){}"), true);
print_and_assert(isValid("([){}"), false);
print_and_assert(isValid("{[][]}"), true);
print_and_assert(isValid("{[[]}"), false);
print_and_assert(isValid("{[(])}"), false);
}
4 changes: 2 additions & 2 deletions lib/fhashtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ static inline void JOIN(FHASHTABLE_NAME, insert)(FHASHTABLE_TYPE *self, KEY_TYPE
break;
}

if (current_slot.offset < self->slots[index].offset) {
if (current_slot.offset > self->slots[index].offset) {
FHASHTABLE_SWAP_SLOTS(&self->slots[index], &current_slot);
}

Expand Down Expand Up @@ -539,7 +539,7 @@ static inline void JOIN(FHASHTABLE_NAME, update)(FHASHTABLE_TYPE *self, KEY_TYPE
return;
}

if (current_slot.offset < self->slots[index].offset) {
if (current_slot.offset > self->slots[index].offset) {
FHASHTABLE_SWAP_SLOTS(&current_slot, &self->slots[index]);
}

Expand Down

0 comments on commit 0f26458

Please sign in to comment.