Last active
May 16, 2020 17:31
-
-
Save lighth7015/eef36780d42914aff54734ad1e38145d to your computer and use it in GitHub Desktop.
hash.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdbool.h> /* bool, true, false */ | |
#include <stdio.h> /* printf */ | |
#include <string.h> /* strdup */ | |
#include <stdlib.h> /* calloc */ | |
typedef struct hash_t { | |
size_t size, count; | |
size_t bytes; | |
const char **keys; | |
struct hash_t** items; | |
} *hash_t; | |
typedef struct node_t { | |
size_t size, count; | |
size_t bytes; | |
const char **keys; | |
struct hash_t **items; | |
const char *name, *value; | |
} *node_t; | |
void hexdump(const void* data, size_t size) { | |
char ascii[17]; | |
ascii[16] = '\0'; | |
printf("%08x ", 0); | |
for (size_t i = 0, j = 0; i < size; ++i) { | |
printf("%02X ", ((unsigned char*)data)[i]); | |
if (((unsigned char*)data)[i] >= ' ' && ((unsigned char*)data)[i] <= '~') { | |
ascii[i % 16] = ((unsigned char*)data)[i]; | |
} else { | |
ascii[i % 16] = '.'; | |
} | |
if ((i+1) % 8 == 0 || i+1 == size) { | |
printf(" "); | |
if ((i+1) % 16 == 0) { | |
printf(" | %-16s |\n%08zx ", ascii, i); | |
} else if (i+1 == size) { | |
ascii[(i+1) % 16] = '\0'; | |
if ((i+1) % 16 <= 8) { | |
printf(" "); | |
} | |
for (j = (i+1) % 16; j < 16; ++j) { | |
printf(" "); | |
} | |
printf(" | %-16s |\n", ascii); | |
} | |
} | |
} | |
puts(""); | |
} | |
hash_t halloc (size_t nbytes) { | |
hash_t h = calloc(1, nbytes); | |
h->keys = NULL; | |
h->items = NULL; | |
h->bytes = nbytes; | |
h->size = 0; | |
h->count = 0; | |
return h; | |
} | |
size_t hindex (hash_t h, const char* key) { | |
size_t index = -1; | |
if (h->keys && h->size > 0) { | |
for ( index = (int) key % h->size | |
; h->keys[index] && h->keys[index] != key | |
; index = (index + 1) % h->size) | |
{ | |
// Nothing to do here, lol. | |
} | |
} | |
return index; | |
} | |
void hinsert (hash_t h, const char* key, node_t value) { | |
node_t item = (node_t) halloc(sizeof(struct node_t)); | |
size_t index = hindex(h, key); | |
if (++h->count > h->size) { | |
const char* fmt = h->items? "%s: Expanding storage, %zu -> %zu.\n": | |
"%s: Allocating storage for newly-initialized hash table.\n"; | |
printf (fmt, __FUNCTION__, h->size - 1, h->size); | |
h->keys = h && h->keys && *h->keys | |
? reallocarray(h->keys, h->count, sizeof(const char *)) | |
: calloc(h->count, sizeof(const char *)); | |
h->items = h && h->items && *h->items | |
? reallocarray(h->items, h->count, h->bytes ) | |
: calloc(h->count, h->bytes ); | |
h->size ++; | |
} | |
item->name = strdup(value->name); | |
item->value = strdup(value->value); | |
hexdump( item, item->bytes ); | |
h->keys[index] = key; | |
h->items[index] = (hash_t) item; | |
} | |
hash_t hlookup (hash_t h, const char* key) { | |
size_t length = 0, index = hindex(h, key); | |
hash_t entry = NULL; | |
if (h->items && ( index >= 0 && index <= h->count ) && ( entry = h->items[index])) { | |
printf( "Match: entry->keys[%zu] = %p\n", index, entry->keys ); | |
hexdump( entry, entry->bytes ); | |
} | |
return entry; | |
} | |
bool hcontains( hash_t h, const char* key, const char* element ) { | |
bool result = false; | |
hash_t match, found; | |
if (( match = hlookup( h, key )) && match && match->count > 0) { | |
printf( "match:keys = (%zu, %p)\n", match->count, match->keys ); | |
/* | |
if (( found = hlookup( match, element ))) { | |
result = true; | |
} | |
*/ | |
} | |
return result; | |
} | |
struct node_t | |
item1 = { .name = "Hello", .value = "world", .size = 0, .items = NULL }, | |
item2 = { .name = "Arbitrary", .value = "length", .size = 0, .items = NULL }, | |
item3 = { .name = "Hash", .value = "table", .size = 0, .items = NULL }; | |
int main () { | |
hash_t h = halloc(sizeof(struct hash_t)), | |
entry = NULL; | |
hinsert(h, "", &item1 ); | |
hinsert(h, "Foo", &item2 ); | |
if (( entry = hlookup(h, ""))) { | |
//printf("Hello, %s\n", entry->value); | |
} | |
else { | |
//puts ("Unable to find entry \"\"."); | |
} | |
//hcontains( h, "", "Hello" ); | |
//printf("herp => %s\n", hash_lookup(h, "herp")); | |
//printf("a => %s\n", hash_lookup(h, "a")); | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment