74 lines
2 KiB
C
74 lines
2 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
#include <limits.h>
|
|
#include <builtins.h>
|
|
|
|
#define WORD 32
|
|
#define RAND_MAX 4294967296
|
|
#define DELTA 1
|
|
|
|
#define rot32_left(x, y) __builtin_rotateleft32(x, y)
|
|
|
|
// Contains everything the functions for the hashtables need, to work with, including the hash table itself
|
|
typedef struct
|
|
{
|
|
unsigned int *transformation_table;
|
|
int *hash_table;
|
|
unsigned int table_size;
|
|
}shash_hashtable_t;
|
|
|
|
void shash_init_hashtable(shash_hashtable_t *hashtable, unsigned int table_size)
|
|
{
|
|
// Create a random transformation table
|
|
srand(time(NULL));
|
|
unsigned int *table = malloc((CHAR_MAX-CHAR_MIN)*sizeof(int));
|
|
|
|
for(int i = 0; i < CHAR_MAX-CHAR_MIN; i++){
|
|
table[i] = rand();
|
|
}
|
|
hashtable->transformation_table = table;
|
|
|
|
hashtable->hash_table = malloc(table_size * sizeof(int));
|
|
hashtable->table_size = table_size;
|
|
}
|
|
|
|
unsigned int shash_hash(char *key, unsigned int len, shash_hashtable_t *hashtable)
|
|
{
|
|
//Slight variation of cyclic polynomial hasing, as described in the Paper: "Recursive Hashing functions for n-Grams" by J. D. Cohen
|
|
unsigned int hash_word = 0;
|
|
for(int i = 0; i < len; i++)
|
|
{
|
|
hash_word = rot32_left(hash_word, DELTA);
|
|
hash_word = hash_word ^ hashtable->transformation_table[key[i]];
|
|
}
|
|
|
|
return hash_word % hashtable->table_size;
|
|
}
|
|
|
|
void shash_set(char *key, unsigned int len, int value, shash_hashtable_t *hashtable)
|
|
{
|
|
unsigned int hash = shash_hash(key, len, hashtable);
|
|
hashtable->hash_table[hash] = value;
|
|
}
|
|
|
|
int shash_get(char *key, unsigned int len, shash_hashtable_t *hashtable)
|
|
{
|
|
unsigned int hash = shash_hash(key, len, hashtable);
|
|
int value = hashtable->hash_table[hash];
|
|
return value;
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
// Initialize an empty hashtable
|
|
shash_hashtable_t hashtable;
|
|
shash_init_hashtable(&hashtable, 100);
|
|
|
|
shash_set("INC", 3, 41, &hashtable);
|
|
|
|
int retrieved_val = shash_get("INC", 3, &hashtable);
|
|
printf("Stored value %d at INC\n", retrieved_val);
|
|
|
|
return 0;
|
|
}
|