jweinst1
6/25/2018 - 8:54 PM

hash map implementation with exists method

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;
}