lang/c/ ToyHashTable1
Motivation
I started watching https://www.youtube.com/watch?v=2Ti5yvumFTU and decided to have a go at writing the simplest toy hash table I could before watching the rest of the video. As such, this uses a poor choice of hash function (basically just Xor all the characters), and cannot delete items.
Code
hasht.h
typedef struct _hasht hasht;
hasht* hasht_new(void);
const char* hasht_get(hasht* h, const char* key);
void hasht_store(hasht* h, const char* key, const char* value);
hasht.c
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "hasht.h"
typedef struct _llnode {
const char* key;
const char* data;
struct _llnode *next;
} llnode;
typedef struct _ll {
struct _llnode *head;
} ll;
struct _hasht {
ll bins[256];
};
hasht* hasht_new(void) {
hasht* h = (hasht*)malloc(sizeof(hasht));
memset(h,0,sizeof(hasht));
return h;
}
char hasht_hash(const char* key) {
char x = 0;
const char *p = key;
while(*p != 0) {
x ^= *p;
p++;
}
return x;
}
llnode* create_llnode(const char* key, const char* data) {
llnode *n = (llnode*)malloc(sizeof(llnode));
char *key_cpy = (char*)malloc(strlen(key)+1);
strcpy(key_cpy,key);
n->key = key_cpy;
n->data = data;
n->next = NULL;
return n;
}
void hasht_store(hasht *h, const char* key, const char* data) {
char hk = hasht_hash(key);
llnode *p = h->bins[hk].head;
if( p == NULL ) {
p = create_llnode(key,data);
h->bins[hk].head = p;
return;
}
// if we are here, then the list is nonempty
while( p->next != NULL ) {
if( strcmp(p->key,key) == 0 ) {
p->data = data;
return;
}
p = p->next;
}
// if we are here, then p points to the last element in the list
if( strcmp(p->key,key) == 0 ) {
p->data = data;
return;
}
// if we are here, then then key is not in the table
p->next = create_llnode(key,data);
// so now our new element is last in the bin
}
const char* hasht_get(hasht *h, const char *key) {
char hk = hasht_hash(key);
llnode *p = h->bins[hk].head;
while(p != NULL) {
if( strcmp(p->key,key) == 0) {
return p->data;
}
p = p->next;
}
return "";
}
Test program
test.c
#include <stdio.h>
#include "hasht.h"
int main() {
hasht* h = hasht_new();
char* item1 = "hello world";
char* item2 = "mr flibble";
hasht_store(h, "hello",item1);
hasht_store(h, "hex",item2);
printf("1:\n");
printf("%s %s\n",hasht_get(h, "hello"),hasht_get(h, "hex"));
hasht_store(h, "hello", "boing");
printf("2:\n");
printf("%s %s\n",hasht_get(h, "hello"),hasht_get(h, "hex"));
}