summaryrefslogtreecommitdiff
path: root/rushs/tinyprintf/hash_map/hash_map.c
diff options
context:
space:
mode:
Diffstat (limited to 'rushs/tinyprintf/hash_map/hash_map.c')
-rw-r--r--rushs/tinyprintf/hash_map/hash_map.c177
1 files changed, 177 insertions, 0 deletions
diff --git a/rushs/tinyprintf/hash_map/hash_map.c b/rushs/tinyprintf/hash_map/hash_map.c
new file mode 100644
index 0000000..4690e8b
--- /dev/null
+++ b/rushs/tinyprintf/hash_map/hash_map.c
@@ -0,0 +1,177 @@
+#include "hash_map.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct hash_map *hash_map_init(size_t size)
+{
+ struct hash_map *new;
+ if ((new = malloc(sizeof(struct hash_map))) == NULL)
+ {
+ return NULL;
+ }
+ if ((new->data = malloc(size * sizeof(struct pair_list *))) == NULL)
+ {
+ return NULL;
+ }
+ new->size = size;
+
+ for (size_t i = 0; i < size; i++)
+ {
+ new->data[i] = NULL;
+ }
+
+ return new;
+}
+
+bool hash_map_insert(struct hash_map *hash_map, const char *key, char *value,
+ bool *updated)
+{
+ if (hash_map == NULL || updated == NULL || hash_map->size == 0)
+ {
+ return false;
+ }
+ *updated = false;
+
+ size_t h = hash(key);
+ if (h >= hash_map->size)
+ {
+ h %= hash_map->size;
+ }
+
+ struct pair_list *new = malloc(sizeof(struct pair_list));
+ if (new == NULL)
+ {
+ return false;
+ }
+
+ for (struct pair_list *p = hash_map->data[h]; p; p = p->next)
+ {
+ if (strcmp(p->key, key) == 0)
+ {
+ p->value = value;
+ *updated = true;
+ free(new);
+ return true;
+ }
+ }
+
+ new->next = hash_map->data[h];
+ new->key = key;
+ new->value = value;
+ hash_map->data[h] = new;
+ return true;
+}
+
+void hash_map_free(struct hash_map *hash_map)
+{
+ if (hash_map == NULL)
+ {
+ return;
+ }
+
+ if (hash_map->data == NULL)
+ {
+ free(hash_map);
+ return;
+ }
+
+ for (size_t i = 0; i < hash_map->size; i++)
+ {
+ while (hash_map->data[i])
+ {
+ struct pair_list *tmp = hash_map->data[i]->next;
+ free(hash_map->data[i]);
+ hash_map->data[i] = tmp;
+ }
+ }
+
+ free(hash_map->data);
+ free(hash_map);
+}
+
+void hash_map_dump(struct hash_map *hash_map)
+{
+ if (hash_map == NULL || hash_map->data == NULL)
+ {
+ return;
+ }
+
+ for (size_t i = 0; i < hash_map->size; i++)
+ {
+ if (hash_map->data[i] != NULL)
+ {
+ printf("%s: %s", hash_map->data[i]->key, hash_map->data[i]->value);
+ for (struct pair_list *p = hash_map->data[i]->next; p; p = p->next)
+ {
+ printf(", %s: %s", p->key, p->value);
+ }
+ printf("\n");
+ }
+ }
+}
+
+const char *hash_map_get(const struct hash_map *hash_map, const char *key)
+{
+ if (hash_map == NULL || hash_map->data == NULL || hash_map->size == 0)
+ {
+ return NULL;
+ }
+
+ size_t h = hash(key);
+ if (h >= hash_map->size)
+ {
+ h %= hash_map->size;
+ }
+ struct pair_list *p;
+ for (p = hash_map->data[h]; p && strcmp(p->key, key) != 0; p = p->next)
+ {
+ continue;
+ }
+
+ if (p)
+ {
+ return p->value;
+ }
+ return NULL;
+}
+
+bool hash_map_remove(struct hash_map *hash_map, const char *key)
+{
+ if (hash_map == NULL || hash_map->data == NULL || hash_map->size == 0)
+ {
+ return false;
+ }
+
+ size_t h = hash(key);
+ if (h >= hash_map->size)
+ {
+ h %= hash_map->size;
+ }
+ if (hash_map->data[h] == NULL)
+ {
+ return false;
+ }
+
+ if (strcmp(hash_map->data[h]->key, key) == 0)
+ {
+ struct pair_list *tmp = hash_map->data[h]->next;
+ free(hash_map->data[h]);
+ hash_map->data[h] = tmp;
+ return true;
+ }
+
+ struct pair_list *p;
+ for (p = hash_map->data[h]; p->next; p = p->next)
+ {
+ if (strcmp(p->next->key, key) == 0)
+ {
+ struct pair_list *tmp = p->next->next;
+ free(p->next);
+ p->next = tmp;
+ return true;
+ }
+ }
+ return false;
+}