diff --git a/slides/exemples/hm/Makefile b/slides/exemples/hm/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..42fbedf76af6c39e84f3bd4e46f0b4201bf36b20 --- /dev/null +++ b/slides/exemples/hm/Makefile @@ -0,0 +1,14 @@ +CC:=gcc +CFLAGS:=-Wall -Wextra -pedantic -fsanitize=address -g +LDFLAGS:=-fsanitize=address + +main: main.o hm.o + +main.o: hm.h +hm.o: hm.h + +.PHONY: clean + +clean: + rm -f *.o main + diff --git a/slides/exemples/hm/hm.c b/slides/exemples/hm/hm.c new file mode 100644 index 0000000000000000000000000000000000000000..b79f10e5ea39c79366722beaeed77035827d944d --- /dev/null +++ b/slides/exemples/hm/hm.c @@ -0,0 +1,98 @@ +#include "hm.h" + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +static int hash(char *key, int capacity) { + int h = 0; + for (int i = 0; i < (int)strlen(key); ++i) { + h = (h + key[i] * 43) % capacity; + } + return h; +} + +// allocate memory of the table to capacity +void hm_init(struct hm_t *hm, int capacity) { + hm->table = malloc(sizeof(*(hm->table)) * capacity); + hm->capacity = capacity; + hm->size = 0; + for (int i = 0; i < hm->capacity; ++i) { + hm->table[i].state = empty; + } +} + +// insert the key - value pair: if key is already present +// we erase the old value. if the table is full we return false +bool hm_insert(struct hm_t *hm, char *key, char *value) { + int index = hash(key, hm->capacity); + int initial_index = index; + while (hm->table[index].state == occupied && strncmp(hm->table[index].key, key, MAX_LEN) != 0) { + index = (index + 1) % hm->capacity; + if (index == initial_index) { + return false; + } + } + hm->table[index].state = occupied; + strncpy(hm->table[index].key, key, MAX_LEN); + strncpy(hm->table[index].value, value, MAX_LEN); + hm->size += 1; + + return true; +} + +// changes the state of the table at the "key" position to deleted +void hm_delete(struct hm_t *hm, char *key) { + int index = hash(key, hm->capacity); + int initial_index = index; + while (hm->table[index].state != empty) { + if (hm->table[index].state == occupied && strncmp(hm->table[index].key, key, MAX_LEN) == 0) + { + hm->table[index].state = deleted; + hm->size -= 1; + } + index = (index + 1) % hm->capacity; + if (index == initial_index) { + return; + } + } +} + +// returns the value linked to the key if present +// return NULL otherwise +char *hm_get(struct hm_t hm, char *key) { + int index = hash(key, hm.capacity); + int initial_index = index; + while (hm.table[index].state != empty) { + if (hm.table[index].state == occupied && strncmp(hm.table[index].key, key, MAX_LEN) == 0) { + return hm.table[index].value; + } + index = (index + 1) % hm.capacity; + if (index == initial_index) { + return NULL; + } + } + + return NULL; +} + +// prints the state of the table +void hm_print(struct hm_t hm) { + for (int i = 0; i < hm.capacity; ++i) { + if (hm.table[i].state == empty) { + printf("[%d]: empty\n", i); + } else if (hm.table[i].state == occupied) { + printf("[%d]: occupied, %s, %s\n", i, hm.table[i].key, hm.table[i].value); + } else { + printf("[%d]: deleted, %s, %s\n", i, hm.table[i].key, hm.table[i].value); + } + } +} + +// frees ressources +void hm_destroy(struct hm_t *hm) { + free(hm->table); + hm->table = NULL; + hm->size = -1; + hm->capacity = -1; +} diff --git a/slides/exemples/hm/hm.h b/slides/exemples/hm/hm.h new file mode 100644 index 0000000000000000000000000000000000000000..616079a06e9f4f53d8740de964b24f4030a06647 --- /dev/null +++ b/slides/exemples/hm/hm.h @@ -0,0 +1,42 @@ +#ifndef HM_H +#define HM_H + +#include <stdbool.h> + +#define MAX_LEN 80 + +typedef enum {occupied, empty, deleted} state_t; + +struct cell_t { + char key[MAX_LEN]; + char value[MAX_LEN]; + state_t state; +}; + +struct hm_t { + struct cell_t *table; + int size; + int capacity; +}; + +// allocate memory of the table to capacity +void hm_init(struct hm_t *hm, int capacity); + +// insert the key - value pair: if key is already present +// we erase the old value. if the table is full we return false +bool hm_insert(struct hm_t *hm, char *key, char *value); + +// changes the state of the table at the "key" position to deleted +void hm_delete(struct hm_t *hm, char *key); + +// returns the value linked to the key if present +// return NULL otherwise +char *hm_get(struct hm_t hm, char *key); + +// prints the state of the table +void hm_print(struct hm_t hm); + +// frees ressources +void hm_destroy(struct hm_t *hm); + +#endif // !HM_H diff --git a/slides/exemples/hm/main.c b/slides/exemples/hm/main.c new file mode 100644 index 0000000000000000000000000000000000000000..27665169b335589069390030d17523953fc5b1e8 --- /dev/null +++ b/slides/exemples/hm/main.c @@ -0,0 +1,37 @@ +#include <stdlib.h> +#include <stdio.h> +#include "hm.h" + +int main() { + struct hm_t hm; + hm_init(&hm, 10); + hm_print(hm); + hm_insert(&hm, "orestis", "123"); + hm_insert(&hm, "paul", "234"); + hm_insert(&hm, "delphine", "12lsk3"); + hm_insert(&hm, "noria", "12as 3"); + hm_insert(&hm, "andres", "123am"); + /*hm_insert(&hm, "fabien", "236123");*/ + hm_insert(&hm, "tewfik", "123skjs"); + hm_insert(&hm, "florent", "12adsadcasd3"); + hm_insert(&hm, "mickael", "123aaaaaaa"); + hm_insert(&hm, "guido", "1asdljncaskjdnckajsd23"); + hm_insert(&hm, "orestis", "1298392"); + hm_print(hm); + printf("value is: %s\n", hm_get(hm, "orestis")); + printf("value is: %s\n", hm_get(hm, "guido")); + printf("value is: %s\n", hm_get(hm, "noria")); + printf("value is: %s\n", hm_get(hm, "bob")); + + hm_delete(&hm, "fabien"); + hm_delete(&hm, "paul"); + hm_delete(&hm, "florent"); + hm_delete(&hm, "orestis"); + hm_delete(&hm, "paul"); + hm_print(hm); + hm_insert(&hm, "paul", "aksjdnckajndcaksjdc"); + hm_print(hm); + + hm_destroy(&hm); + return EXIT_SUCCESS; +}