I'm implementing a hash table in c and I chose as key the sha256 hash of the file that I need to store. The problem is that I need to convert the key to a reusable index to insert in the hash table. I tought to rehash the key, but this way I would increase the possibility of overlapping values. Is there a way to use this hash as the key to the table?
The sha256 is store as a BYTE[32] or can be converted as a sting
void* ht_get(ht* table, const char *key) {
size_t index = magicfunction(key);
while (table->entries[index].key != NULL) {
if (strcmp(key, table->entries[index].key) == 0) {
// Found key, return value.
return table->entries[index].value;
}
// Key wasn't in this slot, move to next (linear probing).
index++;
if (index >= table->capacity) {
index = 0;
}
}
return NULL;
}
When I need an absolute minimalist hashmap in C, I usually end up doing something like that:
#include <stddef.h>
#include <string.h>
#include <stdio.h>
struct hmap_entry {
const char *key;
/* Or in your case: */
/* char key[SIZE_OF_SHA256]; */
void *payload;
};
#define HMAP_ENTRY_CNT 256
struct hmap {
struct hmap_entry entries[HMAP_ENTRY_CNT];
};
static size_t str_hash(const char *s) {
size_t hash = 0;
while(*s) {
hash = (hash << 7) ^ (size_t)*s++ ^ hash;
}
return hash;
}
static struct hmap_entry *hmap_search_entry(struct hmap *map
, const char *key)
{
size_t hash = str_hash(key);
/* Or in your case: */
/* size_t hash = 0; memcpy(&hash, key, sizeof(key)) */
hash = hash % HMAP_ENTRY_CNT;
struct hmap_entry *e = NULL;
while(1) {
e = map->entries + hash;
if(e->key == NULL
|| strcmp(key, e->key) == 0) {
break;
}
/* Or in your case: */
/* if(e->key == NULL
|| memcmp(key, e->key, SIZE_OF_SHA256) == 0) {
break;
}
*/
hash = (hash + 1) % HMAP_ENTRY_CNT;
}
return e;
}
And this is how I use it:
int main()
{
struct hmap_entry *e;
struct hmap map = {};
/* insert foo */
e = hmap_search_entry(&map, "foo");
e->key = "foo";
e->payload = "hello world";
/* insert bar */
e = hmap_search_entry(&map, "bar");
e->key = "bar";
e->payload = "Something else";
/* get foo */
e = hmap_search_entry(&map, "foo");
if(e->key) {
printf("Value of \"%s\" is \"%s\"\n", e->key, (const char *)e->payload);
}
else {
printf("Not found!\n");
}
/* get bar */
e = hmap_search_entry(&map, "bar");
if(e->key) {
printf("Value of \"%s\" is \"%s\"\n", e->key, (const char *)e->payload);
}
else {
printf("Not found!\n");
}
/* get test */
e = hmap_search_entry(&map, "test");
if(e->key) {
printf("Value of \"%s\" is \"%s\"\n", e->key, (const char *)e->payload);
}
else {
printf("Not found!\n");
}
return 0;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.