#include #include #include #include #include #include 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 *key) { if (!key) return 0; uint32_t hash = 2166136261; uint32_t prime = 16777619; while (*key) { hash ^= *key; hash *= prime; key++; } return hash; } struct hash_map *hash_map_init(size_t size) { struct hash_map *res = malloc(sizeof(struct hash_map)); if (!res) return NULL; res->data = calloc(size, sizeof(struct pair_list *)); if (!res->data) { free(res); return NULL; } res->size = size; return res; } bool hash_map_insert(struct hash_map *hash_map, const char *key, char *value, bool *updated) { if (!hash_map || hash_map->size == 0 || !key) return false; size_t hashed_val = hash(key) % hash_map->size; struct pair_list *elt = hash_map->data[hashed_val]; while (elt) { if (strcmp(key, elt->key) == 0) break; elt = elt->next; } if (!elt) { struct pair_list *new = calloc(1, sizeof(struct pair_list)); if (!new) return false; new->key = key; new->value = value; struct pair_list *res = hash_map->data[hashed_val]; new->next = res; hash_map->data[hashed_val] = new; if (updated) *updated = false; return true; } elt->value = value; if (updated) *updated = true; return true; } void hash_map_free(struct hash_map *hash_map) { if (!hash_map) return; for (size_t i = 0; i < hash_map->size; i++) { struct pair_list *elt = hash_map->data[i]; while (elt) { struct pair_list *n = elt->next; free(elt); elt = n; } } free(hash_map->data); free(hash_map); //hash_map->data = NULL; } void hash_map_dump(struct hash_map *hash_map) { if (!hash_map) return; for (size_t i = 0; i < hash_map->size; i++) { struct pair_list *elt = hash_map->data[i]; while (elt) { printf("%s: %s", elt->key, elt->value); elt = elt->next; if (elt) printf(", "); else putchar('\n'); } } } const char *hash_map_get(const struct hash_map *hash_map, const char *key) { if (!hash_map || hash_map->size == 0) return NULL; size_t hashed_val = hash(key) % hash_map->size; struct pair_list *elt = hash_map->data[hashed_val]; while (elt) { if (strcmp(key, elt->key) == 0) break; elt = elt->next; } if (elt) return elt->value; return NULL; } bool hash_map_remove(struct hash_map *hash_map, const char *key) { if (!hash_map || hash_map->size == 0) return false; size_t hashed_val = hash(key) % hash_map->size; struct pair_list *elt = hash_map->data[hashed_val]; struct pair_list *prev = NULL; while (elt) { if (strcmp(key, elt->key) == 0) break; prev = elt; elt = elt->next; } if (!elt) return false; if (prev) prev->next = elt->next; else hash_map->data[hashed_val] = elt->next; //free(elt); printf("removed %s", elt->value); free(elt); return true; } int main(void) { struct hash_map *map = hash_map_init(10); if (!map) return 1; bool updated; hash_map_insert(map, "key1", "value1", &updated); hash_map_insert(map, "key2", "value2", &updated); hash_map_insert(map, "key1", "new_value1", &updated); hash_map_dump(map); const char *val = hash_map_get(map, "key1"); if (val) printf("Retrieved key1: %s\n", val); hash_map_remove(map, "key2"); hash_map_dump(map); hash_map_free(map); printf("Everything is ok!\n"); return 0; }