hash map implementation with exists method
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Implementation for hash table
#define Map_SIZED(n) (sizeof(struct Map) + (sizeof(struct MapSlot) * n))
unsigned long
hash(void *object)
{
unsigned char* strRep = object;
unsigned long hash = 5381;
int c;
while ((c = *strRep++))
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
return hash;
}
struct MapSlot
{
unsigned long key;
void* item;
struct MapSlot* next;
int info; // for type
};
struct Map
{
unsigned size;
struct MapSlot slots[0];
};
struct Map* Map_new(unsigned size)
{
struct Map* newmap = malloc(Map_SIZED(size));
memset(newmap, 0, Map_SIZED(size));
newmap->size = size;
return newmap;
}
struct MapSlot* MapSlot_new(unsigned long hashKey, void* value, int info)
{
struct MapSlot* newslot = malloc(sizeof(struct MapSlot));
newslot->key = hashKey;
newslot->item = value;
newslot->info = info;
return newslot;
}
// Inserts into hash map
// returns 0 if the key is already present (doesn't allow overwrite)
int Map_insert(struct Map* table, const char* key, void* value, int info)
{
unsigned long hashed = hash((void*)key);
struct MapSlot* index = table->slots + (hashed % table->size);
if(!(index->key))
{
index->key = hashed;
index->item = value;
index->info = info;
return 1;
}
else if (index->key == hashed)
{
return 0;
}
else
{
while(index->next != NULL) index = index->next;
index->next = MapSlot_new(hashed, value, info);
return 1;
}
}
struct MapSlot* Map_get(struct Map* table, const char* key)
{
unsigned long hashed = hash((void*)key);
struct MapSlot* index = table->slots + (hashed % table->size);
if(!(index->key)) return NULL;
else if(index->key == hashed) return index;
else
{
while(index != NULL && index->key != hashed)
{
index = index->next;
}
return index;
}
}
int Map_exists(struct Map* table, const char* key)
{
unsigned long hashed = hash((void*)key);
struct MapSlot* index = table->slots + (hashed % table->size);
if(!(index->key)) return 0;
else if(index->key == hashed) return 1;
else
{
while(index->next != NULL)
{
if(index->key == hashed) return 1;
else index = index->next;
}
return 0;
}
}
int main(int argc, char const *argv[])
{
const char* sample = "Hello World!";
const char* sample2 = "Hello Wolf!";
struct Map* dict = Map_new(1000);
Map_insert(dict, "Foo", (void*)sample, 1);
Map_insert(dict, "Doo", (void*)sample2, 1);
const char* got = (const char*)(Map_get(dict, "Doo")->item);
printf("%s\n", got);
printf("Foo exists %d\n", Map_exists(dict, "Foo"));
return 0;
}