From 02abe1ac77d10434ed4aca9029bd33dc80a3d4f7 Mon Sep 17 00:00:00 2001
From: Orestis <orestis.malaspinas@pm.me>
Date: Tue, 27 Feb 2024 11:48:58 +0100
Subject: [PATCH] added hm

---
 slides/exemples/hashmap/Makefile | 15 ++++++++
 slides/exemples/hashmap/hm.c     | 59 ++++++++++++++++++++++++++++++++
 slides/exemples/hashmap/hm.h     | 28 +++++++++++++++
 slides/exemples/hashmap/main.c   | 31 +++++++++++++++++
 4 files changed, 133 insertions(+)
 create mode 100644 slides/exemples/hashmap/Makefile
 create mode 100644 slides/exemples/hashmap/hm.c
 create mode 100644 slides/exemples/hashmap/hm.h
 create mode 100644 slides/exemples/hashmap/main.c

diff --git a/slides/exemples/hashmap/Makefile b/slides/exemples/hashmap/Makefile
new file mode 100644
index 0000000..096c299
--- /dev/null
+++ b/slides/exemples/hashmap/Makefile
@@ -0,0 +1,15 @@
+CC:=clang
+CFLAGS:=-Wall -Wextra -pedantic -g -fsanitize=address,undefined
+LDFLAGS:=-fsanitize=address,undefined
+
+main: main.o hm.o
+	$(CC) main.o hm.o -o main $(LDFLAGS)
+
+main.o: main.c hm.h
+	$(CC) -c main.c -o main.o $(CFLAGS)
+
+hm.o: hm.c hm.h
+	$(CC) -c hm.c -o hm.o $(CFLAGS)
+
+clean:
+	rm -f *.o main
\ No newline at end of file
diff --git a/slides/exemples/hashmap/hm.c b/slides/exemples/hashmap/hm.c
new file mode 100644
index 0000000..631eafe
--- /dev/null
+++ b/slides/exemples/hashmap/hm.c
@@ -0,0 +1,59 @@
+#include <string.h>
+#include "hm.h"
+
+static size_t hash(char *key, size_t table_capacity) {
+    size_t h = 0;
+    for (size_t i = 0; i < strlen(key); ++i) {
+        h = (h + key[i] * 43) % table_capacity;
+    }
+    return h;
+}
+
+void hm_init(hm_t *hm, size_t table_capacity) {
+    hm->table = malloc(sizeof(*(hm->table)) * table_capacity);
+    hm->table_capacity = table_capacity;
+    hm->table_length = 0;
+    for (size_t i = 0; i < hm->table_capacity; ++i) {
+        hm->table[i].state = EMPTY;
+    }
+}
+
+void hm_destroy(hm_t *hm) {
+    free(hm->table);
+    hm->table = NULL;
+    hm->table_capacity = 0;
+    hm->table_length = 0;
+}
+
+void hm_insert(hm_t *hm, char *key, char *value) {
+    if (hm->table_capacity == hm->table_length) {
+        return;
+    }
+    size_t index = hash(key, hm->table_capacity);
+    while(hm->table[index].state == OCCUPIED && (0 != strcmp(key, hm->table[index].key))) {
+        index = (index + 1) % hm->table_capacity;
+    }
+    if (hm->table[index].state != OCCUPIED) {
+        hm->table_length += 1;
+        strcpy(hm->table[index].key, key);
+        hm->table[index].state = OCCUPIED;
+    }
+    strcpy(hm->table[index].value, value);
+}
+
+void hm_remove(hm_t *hm, char *key) {
+    if (0 == hm->table_length) {
+        return;
+    }
+    size_t index = hash(key, hm->table_capacity);
+    while (hm->table[index].state == EMPTY && 
+        (0 != strcmp(key, hm->table[index].key))) {
+        index = (index + 1) % hm->table_capacity;
+    }
+    if (0 == strcmp(key, hm->table[index].key)) {
+        hm->table[index].state = DELETED;
+        hm->table[index].key[0] = '\0';
+        hm->table_length -= 1;
+    }
+}
+
diff --git a/slides/exemples/hashmap/hm.h b/slides/exemples/hashmap/hm.h
new file mode 100644
index 0000000..5bec3ff
--- /dev/null
+++ b/slides/exemples/hashmap/hm.h
@@ -0,0 +1,28 @@
+#ifndef HM_H
+#define HM_H
+
+#include <stdlib.h>
+
+#define MAX_SIZE 80
+
+typedef enum _state_t { EMPTY, OCCUPIED, DELETED } state_t;
+
+typedef struct _entry_t {
+    char key[MAX_SIZE];
+    char value[MAX_SIZE];
+    state_t state;
+} entry_t;
+
+typedef struct _hm_t {
+    entry_t *table;
+    size_t table_capacity;
+    size_t table_length;
+} hm_t;
+
+void hm_init(hm_t *hm, size_t table_capacity);
+void hm_destroy(hm_t *hm);
+
+void hm_insert(hm_t *hm, char *key, char *value);
+void hm_remove(hm_t *hm, char *key);
+
+#endif
diff --git a/slides/exemples/hashmap/main.c b/slides/exemples/hashmap/main.c
new file mode 100644
index 0000000..95a782e
--- /dev/null
+++ b/slides/exemples/hashmap/main.c
@@ -0,0 +1,31 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include "hm.h"
+
+int main(int argc, char *argv[]) {
+    hm_t hm;
+    hm_init(&hm, 50);
+    printf("capacity = %zu, length = %zu\n", hm.table_capacity, hm.table_length);
+    char key1[] = "Orestis";
+    char value1[] = "1234567";
+    hm_insert(&hm, key1, value1);
+    hm_remove(&hm, key1);
+    char value2[] = "2345678";
+    hm_insert(&hm, key1, value2);
+    for (int i = 0; i < 50; ++i) {
+        if (hm.table[i].state == OCCUPIED) {
+            printf("key: %s, value %s\n", hm.table[i].key, hm.table[i].value);
+        }
+    }
+    for (int i = 0; i < 50; ++i) {
+        if (hm.table[i].state == OCCUPIED) {
+            printf("key: %s, value %s\n", hm.table[i].key, hm.table[i].value);
+        }
+    }
+    printf("capacity = %zu, length = %zu\n", hm.table_capacity, hm.table_length);
+
+
+    hm_destroy(&hm);
+    printf("capacity = %zu, length = %zu\n", hm.table_capacity, hm.table_length);
+    return EXIT_SUCCESS;
+}
-- 
GitLab