diff options
author | Preston Pan <preston@nullring.xyz> | 2023-01-05 21:02:26 -0800 |
---|---|---|
committer | Preston Pan <preston@nullring.xyz> | 2023-01-05 21:02:26 -0800 |
commit | 5ecf1f46aae4994662bd8e3df189f8d60b49a304 (patch) | |
tree | 91b6a15d65c9e8d7a5e7ae87712830b1bf4f4eca /hash_table_new.c | |
parent | 7ff373076c59af3ba166e5080b8ecead569d5a44 (diff) |
bind works for real, I think this works now
Diffstat (limited to 'hash_table_new.c')
-rw-r--r-- | hash_table_new.c | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/hash_table_new.c b/hash_table_new.c new file mode 100644 index 0000000..8722a60 --- /dev/null +++ b/hash_table_new.c @@ -0,0 +1,130 @@ +#include "./include/hash_table.h" +#include "./include/ast.h" +#include "./include/macros.h" +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +pair_t *init_pair(char *key, ast_t *value) { + pair_t *p = (pair_t *)malloc(sizeof(pair_t)); + if (p == NULL) + die("malloc on pair"); + p->key = key; + p->value = value; + return p; +} + +sl_node_t *init_sl_node(char *key, ast_t *value) { + sl_node_t *n = (sl_node_t *)malloc(sizeof(sl_node_t)); + if (n == NULL) + die("malloc on node"); + n->value = init_pair(key, value); + n->next = NULL; + return n; +} + +/*** SINGLY LINKED LIST FUNCTIONS ***/ +sl_list_t *init_sl_list() { + sl_list_t *l = (sl_list_t *)malloc(sizeof(sl_list_t)); + if (l == NULL) + die("malloc on list"); + l->size = 0; + l->head = NULL; + return l; +} + +/* TODO: fix segfault bug */ +void sl_list_add(sl_list_t *l, char *key, ast_t *value) { + if (l->head == NULL) { + l->head = init_sl_node(key, value); + l->size++; + return; + } else { + sl_node_t *cur = l->head; + while (cur->next != NULL) + cur = cur->next; + cur->next = init_sl_node(key, value); + l->size++; + } +} + +ast_t *sl_list_get(sl_list_t *l, char *key) { + sl_node_t *cur = l->head; + printf("in hash table get\n"); + while (cur != NULL) { + if (cur->value == NULL) { + printf("unlucky\n"); + } + if (strcmp(cur->value->key, key) == 0) + return cur->value->value; + cur = cur->next; + } + return NULL; +} + +bool sl_list_exists(sl_list_t *l, char *key) { + if (sl_list_get(l, key) != NULL) + return true; + return false; +} + +void sl_list_free(sl_list_t *l) { + sl_node_t *cur = l->head; + sl_node_t *tmp; + while (cur != NULL) { + tmp = cur; + cur = cur->next; + free(cur); + } + free(l); +} + +/*** HASH TABLE FUNCTIONS ***/ +hash_table_t *init_hash_table(int size) { + hash_table_t *h = (hash_table_t *)malloc(sizeof(hash_table_t)); + if (h == NULL) + die("malloc on hash table"); + h->size = size; + h->buckets = malloc(sizeof(sl_list_t *)); + if (h->buckets == NULL) + die("malloc on buckets"); + for (int i = 0; i < h->size; i++) + h->buckets[i] = init_sl_list(); + return h; +} + +void hash_table_add(hash_table_t *h, char *key, ast_t *value) { + if (hash_table_exists(h, key)) { + printf("BUG!\n"); + return; + } + sl_list_t *l = h->buckets[hash(key, h->size)]; + sl_list_add(l, key, value); +} + +ast_t *hash_table_get(hash_table_t *h, char *key) { + sl_list_t *l = h->buckets[hash(key, h->size)]; + return sl_list_get(l, key); +} + +bool hash_table_exists(hash_table_t *h, char *key) { + printf("in hash table\n"); + sl_list_t *l = h->buckets[hash(key, h->size)]; + return sl_list_exists(l, key); +} + +void hash_table_free(hash_table_t *h) { + for (int i = 0; i < h->size; i++) + sl_list_free(h->buckets[i]); + free(h); +} + +/* DJB2 HASH FUNCTION */ +unsigned long hash(char *key, int size) { + unsigned long hash = 5381; + int c; + while ((c = *key++)) + hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ + return hash % size; +} |