summaryrefslogtreecommitdiff
path: root/hash_table_new.c
diff options
context:
space:
mode:
authorPreston Pan <preston@nullring.xyz>2023-01-05 21:02:26 -0800
committerPreston Pan <preston@nullring.xyz>2023-01-05 21:02:26 -0800
commit5ecf1f46aae4994662bd8e3df189f8d60b49a304 (patch)
tree91b6a15d65c9e8d7a5e7ae87712830b1bf4f4eca /hash_table_new.c
parent7ff373076c59af3ba166e5080b8ecead569d5a44 (diff)
bind works for real, I think this works now
Diffstat (limited to 'hash_table_new.c')
-rw-r--r--hash_table_new.c130
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;
+}