Skip to content

Instantly share code, notes, and snippets.

@lighth7015
Last active May 16, 2020 17:31
Show Gist options
  • Save lighth7015/eef36780d42914aff54734ad1e38145d to your computer and use it in GitHub Desktop.
Save lighth7015/eef36780d42914aff54734ad1e38145d to your computer and use it in GitHub Desktop.
hash.c
#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