summaryrefslogtreecommitdiff
path: root/rushs/tinyprintf/hash_map
diff options
context:
space:
mode:
Diffstat (limited to 'rushs/tinyprintf/hash_map')
-rw-r--r--rushs/tinyprintf/hash_map/hash.c13
-rw-r--r--rushs/tinyprintf/hash_map/hash_map.c177
-rw-r--r--rushs/tinyprintf/hash_map/hash_map.h29
3 files changed, 219 insertions, 0 deletions
diff --git a/rushs/tinyprintf/hash_map/hash.c b/rushs/tinyprintf/hash_map/hash.c
new file mode 100644
index 0000000..434616f
--- /dev/null
+++ b/rushs/tinyprintf/hash_map/hash.c
@@ -0,0 +1,13 @@
+#include <stddef.h>
+
+size_t hash(const char *key)
+{
+ size_t i = 0;
+ size_t hash = 0;
+
+ for (i = 0; key[i] != '\0'; ++i)
+ hash += key[i];
+ hash += i;
+
+ return hash;
+}
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;
+}
diff --git a/rushs/tinyprintf/hash_map/hash_map.h b/rushs/tinyprintf/hash_map/hash_map.h
new file mode 100644
index 0000000..c731eab
--- /dev/null
+++ b/rushs/tinyprintf/hash_map/hash_map.h
@@ -0,0 +1,29 @@
+#ifndef HASH_MAP_H
+#define HASH_MAP_H
+
+#include <stdbool.h>
+#include <stddef.h>
+
+struct pair_list
+{
+ const char *key;
+ char *value;
+ struct pair_list *next;
+};
+
+struct hash_map
+{
+ struct pair_list **data;
+ size_t size;
+};
+
+size_t hash(const char *str);
+struct hash_map *hash_map_init(size_t size);
+bool hash_map_insert(struct hash_map *hash_map, const char *key, char *value,
+ bool *updated);
+void hash_map_free(struct hash_map *hash_map);
+void hash_map_dump(struct hash_map *hash_map);
+const char *hash_map_get(const struct hash_map *hash_map, const char *key);
+bool hash_map_remove(struct hash_map *hash_map, const char *key);
+
+#endif /* ! HASH_MAP_H */