From ef9ab1fd141f4057d41f2d6ed8ab8d67c44894d5 Mon Sep 17 00:00:00 2001 From: Preston Pan Date: Thu, 9 Jan 2025 16:32:55 -0800 Subject: save state --- src/common/array.c | 5 +- src/common/better_string.c | 10 +++- src/common/hash_table.c | 140 ++++++++++++++++++++++++++++++++++++++++++++- src/common/helpers.c | 13 +++-- src/common/list.c | 78 +++++++++++++++++++++++++ src/common/protocol.c | 20 +++++++ 6 files changed, 253 insertions(+), 13 deletions(-) create mode 100644 src/common/list.c create mode 100644 src/common/protocol.c (limited to 'src/common') diff --git a/src/common/array.c b/src/common/array.c index 4ebb67e..9648f5a 100644 --- a/src/common/array.c +++ b/src/common/array.c @@ -39,9 +39,10 @@ array_t *array_reverse(array_t *a) { void array_free(void *x, void (*freefunc)(void *)) { array_t *a = (array_t *)x; - for (int i = 0; i < a->size; i++) { + if (!x) + return; + for (int i = 0; i < a->size; i++) freefunc(a->items[i]); - } free(a->items); free(a); } diff --git a/src/common/better_string.c b/src/common/better_string.c index 366dda6..7863da0 100644 --- a/src/common/better_string.c +++ b/src/common/better_string.c @@ -18,11 +18,12 @@ string_t *init_string(const char *src) { } void string_push(string_t *s, char c) { - if (s->len >= s->size - 2) { + if (s->len >= s->size - 3) { s->size *= 2; s->buf = safe_realloc(s->buf, s->size); } s->buf[s->len] = c; + s->buf[s->len + 1] = '\0'; s->len++; } @@ -33,9 +34,8 @@ char string_pop(string_t *s) { } void string_concat_const(string_t *s1, const char *s2) { - for (int i = 0; i < strlen(s2); i++) { + for (int i = 0; i < strlen(s2); i++) string_push(s1, s2[i]); - } } void string_concat(string_t *s1, string_t *s2) { @@ -46,6 +46,10 @@ void string_concat(string_t *s1, string_t *s2) { void string_free(void *x) { string_t *s = x; + + if (!x) + return; + free(s->buf); free(s); } diff --git a/src/common/hash_table.c b/src/common/hash_table.c index 2f66d45..6b4c014 100644 --- a/src/common/hash_table.c +++ b/src/common/hash_table.c @@ -1,12 +1,148 @@ #include "../include/hash_table.h" #include "../include/helpers.h" - +#include "../include/list.h" #include +#include + +pair_t *init_pair(char *key, void *v) { + pair_t *pair = safe_calloc(1, sizeof(pair_t)); + pair->key = key; + pair->v = v; + return pair; +} + +void *bucket_pop(list_t *b, char *key) { + node_t *cur = b->head; + node_t *prev; + pair_t *cur_pair; + node_t *tmp; + + if (b->size == 0) + return NULL; + + while (cur) { + cur_pair = cur->item; + if (strcmp(cur_pair->key, key) == 0) { + prev = cur->prev; + if (prev) { + tmp = cur->next; + prev->next = tmp; + + if (tmp) + tmp->prev = prev; + else { + b->tail = prev; + } + + b->size--; + + if (b->size <= 1) + b->head = b->tail; + + return cur; + } else { + tmp = cur->next; + if (tmp) + tmp->prev = NULL; + + b->head = tmp; + b->size--; + + if (b->size <= 1) + b->tail = b->head; + + return cur; + } + } + } + return NULL; +} + +void *bucket_get(list_t *b, char *key) { + node_t *cur = b->head; + pair_t *cur_pair; + + while (cur) { + cur_pair = cur->item; + if (strcmp(key, cur_pair->key) == 0) { + return cur_pair->v; + } + } + return NULL; +} + +void bucket_free(void *x, void (*freefunc)(void *)) { + list_t *b = x; + node_t *cur = b->head; + node_t *tmp; + pair_t *cur_pair; + + if (!x) + return; + + while (cur) { + cur_pair = cur->item; + + freefunc(cur_pair->v); + free(cur_pair->key); + free(cur_pair); + + tmp = cur->next; + free(cur); + cur = tmp; + } + free(b); +} ht_t *init_ht(size_t size) { ht_t *ht = safe_calloc(1, sizeof(size)); size_t realsize = size == 0 ? DEFAULT_HT_SIZE : size; - ht->buckets = safe_calloc(realsize, sizeof(sll_t *)); + ht->buckets = safe_calloc(realsize, sizeof(list_t *)); ht->size = realsize; return ht; } + +void ht_insert(ht_t *ht, char *key, void *value) { + unsigned long bn = hash(key) % ht->size; + list_t *bucket = ht->buckets[bn]; + if (!bucket) + ht->buckets[bn] = init_list(); + + list_push_back(bucket, init_pair(key, value)); +} + +void *ht_pop(ht_t *ht, char *key) { + unsigned long bn = hash(key) % ht->size; + list_t *bucket = ht->buckets[bn]; + if (!bucket) + return NULL; + return bucket_pop(bucket, key); +} + +void *ht_get(ht_t *ht, char *key) { + unsigned long bn = hash(key) % ht->size; + list_t *bucket = ht->buckets[bn]; + if (!bucket) + return NULL; + return bucket_get(bucket, key); +} + +void ht_free(void *x, void (*freefunc)(void *)) { + ht_t *ht = x; + for (int i = 0; i < ht->size; i++) + bucket_free(ht->buckets[i], freefunc); + + free(ht->buckets); + free(ht); +} + +/* DJB2 hash function */ +unsigned long hash(char *str) { + unsigned long hash = 5381; + int c; + + while ((c = *str++)) + hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ + + return hash; +} diff --git a/src/common/helpers.c b/src/common/helpers.c index 4bf7301..4a3606a 100644 --- a/src/common/helpers.c +++ b/src/common/helpers.c @@ -4,9 +4,8 @@ #include void die_lz(int code, const char *msg) { - if (code < 0) { + if (code < 0) die(msg); - } } void die(const char *msg) { @@ -17,17 +16,19 @@ void die(const char *msg) { void *safe_calloc(unsigned int i, size_t size) { void *x = calloc(i, size); - if (x == NULL) { + + if (x == NULL) die("abort: calloc()"); - } + return x; } void *safe_realloc(void *x, size_t size) { void *p = realloc(x, size); - if (x == NULL) { + + if (x == NULL) die("abort: realloc()"); - } + return p; } diff --git a/src/common/list.c b/src/common/list.c new file mode 100644 index 0000000..00c18ee --- /dev/null +++ b/src/common/list.c @@ -0,0 +1,78 @@ +#include "../include/list.h" +#include "../include/helpers.h" + +node_t *init_node(void *x) { + node_t *n = safe_calloc(1, sizeof(node_t)); + n->item = x; + n->next = NULL; + n->prev = NULL; + return n; +} + +list_t *init_list() { + list_t *l = safe_calloc(1, sizeof(list_t)); + l->head = NULL; + l->tail = NULL; + l->size = 0; + return l; +} + +void *list_pop_front(list_t *l) { + node_t *front = l->head; + if (!front) + return NULL; + + node_t *new = front->next; + l->head = new; + + if (!new) + l->tail = NULL; + + l->size--; + return front; +} + +void list_push_back(list_t *l, void *x) { + node_t *back = l->tail; + node_t *new = init_node(x); + if (!back) { + l->head = new; + l->tail = l->head; + } else { + back->next = new; + new->prev = back; + l->tail = new; + } + l->size++; +} + +void list_push_front(list_t *l, void *x) { + node_t *front = l->head; + node_t *new = init_node(x); + if (!front) { + l->tail = new; + l->head = l->tail; + } else { + front->prev = new; + new->next = front; + l->head = new; + } + l->size++; +} + +void list_free(void *x, void (*freefunc)(void *)) { + list_t *l = x; + node_t *cur = l->head; + node_t *tmp; + + if (!x) + return; + + while (cur) { + freefunc(cur->item); + tmp = cur->next; + free(cur); + cur = tmp; + } + free(l); +} diff --git a/src/common/protocol.c b/src/common/protocol.c new file mode 100644 index 0000000..9be3bcf --- /dev/null +++ b/src/common/protocol.c @@ -0,0 +1,20 @@ +#include "../include/protocol.h" +#include "../include/better_string.h" + +#include +#include +#include + +string_t *date_str() { + char dateStr[11]; + time_t t = time(NULL); + struct tm *tm_info = localtime(&t); + + strftime(dateStr, sizeof(dateStr), "%d-%m-%Y", tm_info); + return init_string(dateStr); +} + +bool same_day(struct tm *date1, struct tm *date2) { + return (date1->tm_year == date2->tm_year && date1->tm_mon == date2->tm_mon && + date1->tm_mday == date2->tm_mday); +} -- cgit