Skip to content

Instantly share code, notes, and snippets.

@itsbth
Created March 26, 2011 02:32
Show Gist options
  • Save itsbth/887978 to your computer and use it in GitHub Desktop.
Save itsbth/887978 to your computer and use it in GitHub Desktop.
#include "hash.h"
unsigned int hash(char *str)
{
unsigned int ret = 5381;
char c;
while ((c = *str++)) // Stupid bitching GCC wall
{
ret = ((ret << 5) + ret) ^ c;
}
return ret;
}
struct hash_map *hash_map_create()
{
struct hash_map *ret = malloc(sizeof(struct hash_map));
memset(ret, 0, sizeof(struct hash_map));
return ret;
}
void hash_map_destroy(struct hash_map *map)
{
for (unsigned int i = 0; i < 65536; i++)
{
if (map->entries[i].count > 0)
{
for (unsigned int j = 0; j < map->entries[i].count; j++)
{
free(map->entries[i].items[j]);
}
free(map->entries[i].items);
}
}
free(map);
}
void hash_map_insert(struct hash_map *map, char *key, char *value)
{
unsigned int hkey = hash(key) & (65536 - 1);
struct hash_map_entry *entry = &map->entries[hkey];
entry->count += 1;
entry->items = realloc(entry->items, sizeof(struct hash_map_item*) * entry->count); // Performance? Wut is dat?
struct hash_map_item *item = malloc(sizeof(struct hash_map_item));
item->key = key;
item->value = value;
entry->items[entry->count - 1] = item;
}
void hash_map_update(struct hash_map *map, char *key, char *value)
{
unsigned int hkey = hash(key) & (65536 - 1);
struct hash_map_entry *entry = &map->entries[hkey];
if (entry->count == 0) return;
for (unsigned int i = 0; i < entry->count; i++)
{
if (strcmp(entry->items[i]->key, key) == 0)
{
entry->items[i]->value = value;
return;
}
}
}
char *hash_map_get(struct hash_map *map, char *key)
{
unsigned int hkey = hash(key) & (65536 - 1);
struct hash_map_entry *entry = &map->entries[hkey];
if (entry->count == 0) return NULL;
for (unsigned int i = 0; i < entry->count; i++)
{
if (strcmp(entry->items[i]->key, key) == 0) return entry->items[i]->value;
}
return NULL;
}
#ifndef _HASH_H_
#define _HASH_H_
#include <stdlib.h>
#include <string.h>
unsigned int hash(char*);
struct hash_map_item {
char *key;
char *value;
};
struct hash_map_entry {
int count;
struct hash_map_item **items;
};
struct hash_map {
struct hash_map_entry entries[65536];
};
struct hash_map *hash_map_create();
void hash_map_destroy(struct hash_map *map);
void hash_map_insert(struct hash_map *map, char *key, char *value);
void hash_map_update(struct hash_map *map, char *key, char *value);
char *hash_map_get(struct hash_map *map, char *key);
#endif // _HASH_H_
#include <stdio.h>
#include "hash.h"
void print_value(struct hash_map *map, char *key);
int main(int argc, char **argv)
{
struct hash_map *map = hash_map_create();
print_value(map, "key");
hash_map_insert(map, "key", "value");
print_value(map, "key");
hash_map_update(map, "key", "new value");
print_value(map, "key");
hash_map_destroy(map);
return 0;
}
void print_value(struct hash_map *map, char *key)
{
char *value = hash_map_get(map, key);
if (value == NULL) printf("Key not found.\n");
else printf("Value of '%s': '%s'.\n", key, value);
}
CC=gcc
CFLAGS=-Wall -std=c99 -ggdb
main: main.o hash.o
clean:
rm -f main main.o hash.o
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment