Skip to content

Commit

Permalink
hash map refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
Fredrik Widlund committed Apr 15, 2019
1 parent 853098b commit ba34ba8
Show file tree
Hide file tree
Showing 10 changed files with 513 additions and 84 deletions.
70 changes: 0 additions & 70 deletions examples/map_str_ptr.c

This file was deleted.

14 changes: 0 additions & 14 deletions examples/map_str_ptr.h

This file was deleted.

75 changes: 75 additions & 0 deletions examples/mapi.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>
#include <string.h>
#include <assert.h>

#include <dynamic.h>

static uint64_t nano_time(void)
{
struct timespec ts;

(void) clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
return ((uint64_t) ts.tv_sec * 1000000000) + ((uint64_t) ts.tv_nsec);
}

static void release(mapi_entry *e)
{
(void) e;
}

int main(int argc, char **argv)
{
uintptr_t *keys, *values, p;
mapi m;
uint64_t n, i;
uint64_t t1, t2;

if (argc != 2)
exit(1);
n = strtoul(argv[1], NULL, 0);
// create keys/values
keys = calloc(n, sizeof keys[0]);
values = calloc(n, sizeof values[0]);
for (i = 0; i < n; i ++)
{
keys[i] = i + 1;
values[i] = i + 1;
}

// construct map
mapi_construct(&m);

// insert key->value mappings

t1 = nano_time();
for (i = 0; i < n; i ++)
mapi_insert(&m, keys[i], values[i], release);
t2 = nano_time();
printf("insert %lu\n", t2 - t1);

// lookup key and validate value
t1 = nano_time();
for (i = 0; i < n; i ++)
{
p = mapi_at(&m, keys[i]);
assert(p == values[i]);
}
t2 = nano_time();
printf("lookup %lu\n", t2 - t1);

t1 = nano_time();
for (i = 0; i < n; i ++)
mapi_erase(&m, keys[i], release);
t2 = nano_time();
printf("erase %lu\n", t2 - t1);

// release keys/values
free(keys);
free(values);

// destruct map
mapi_destruct(&m, release);
}
93 changes: 93 additions & 0 deletions examples/maps.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>
#include <string.h>
#include <assert.h>

#include <dynamic.h>

typedef struct value value;
struct value
{
int number;
};

static uint64_t nano_time(void)
{
struct timespec ts;

(void) clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
return ((uint64_t) ts.tv_sec * 1000000000) + ((uint64_t) ts.tv_nsec);
}

static void release(maps_entry *e)
{
(void) e;
}


int main(int argc, char **argv)
{
char **keys, buffer[256];
value **values;
maps m;
int n, i, *p;
uint64_t t1, t2;

if (argc != 2)
exit(1);
n = strtoul(argv[1], NULL, 0);

// create keys/values
keys = calloc(n, sizeof keys[0]);
values = calloc(n, sizeof values[0]);
for (i = 0; i < n; i ++)
{
snprintf(buffer, sizeof buffer, "key-%u", i);
keys[i] = strdup(buffer);
values[i] = malloc(sizeof(value));
values[i]->number = i;
}

// construct map
maps_construct(&m);

// insert key->value mappings

t1 = nano_time();
for (i = 0; i < n; i ++)
maps_insert(&m, keys[i], (uintptr_t) values[i], release);
t2 = nano_time();
printf("insert %lu\n", t2 - t1);

// lookup key and validate value
t1 = nano_time();
for (i = 0; i < n; i ++)
{
snprintf(buffer, sizeof buffer, "key-%u", i);
p = (void *) maps_at(&m, buffer);
assert(p);
assert(*p == i);
}
t2 = nano_time();
printf("lookup %lu\n", t2 - t1);

t1 = nano_time();
for (i = 0; i < n; i ++)
maps_erase(&m, keys[i], release);
t2 = nano_time();
printf("erase %lu\n", t2 - t1);

// release keys/values
for (i = 0; i < n; i ++)
{
free(keys[i]);
free(values[i]);
}
free(keys);
free(values);

// destruct map
maps_destruct(&m, release);
}
78 changes: 78 additions & 0 deletions src/dynamic/mapi.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

#include "hash.h"
#include "map.h"
#include "mapi.h"

static void set(void *p1, void *p2)
{
mapi_entry *a = p1, *b = p2;

*a = b ? *b : (mapi_entry) {0};
}

static int equal(void *p1, void *p2)
{
mapi_entry *a = p1, *b = p2;

return b ? a->key == b->key : a->key == 0;
}

static size_t hash(void *p)
{
mapi_entry *a = p;

return hash_uint64(a->key);
}

/* constructor/destructor */

void mapi_construct(mapi *mapi)
{
map_construct(&mapi->map, sizeof(mapi_entry), set);
}

void mapi_destruct(mapi *mapi, mapi_release *release)
{
map_destruct(&mapi->map, equal, (map_release *) release);
}

/* capacity */

size_t mapi_size(mapi *mapi)
{
return map_size(&mapi->map);
}

void mapi_reserve(mapi *mapi, size_t size)
{
map_reserve(&mapi->map, size, hash, set, equal);
}

/* element access */

uintptr_t mapi_at(mapi *mapi, uintptr_t key)
{
return ((mapi_entry *) map_at(&mapi->map, (mapi_entry[]){{.key = key}}, hash, equal))->value;
}

/* modifiers */

void mapi_insert(mapi *mapi, uintptr_t key, uintptr_t value, mapi_release *release)
{
map_insert(&mapi->map,(mapi_entry[]){{.key = key, .value = value}}, hash, set, equal, (map_release *) release);
}

void mapi_erase(mapi *mapi, uintptr_t key, mapi_release *release)
{
map_erase(&mapi->map, (mapi_entry[]){{.key = key}}, hash, set, equal, (map_release *) release);
}

void mapi_clear(mapi *mapi, mapi_release *release)
{
map_clear(&mapi->map, set, equal, (map_release *) release);
}

39 changes: 39 additions & 0 deletions src/dynamic/mapi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#ifndef MAPI_H_INCLUDED
#define MAPI_H_INCLUDED

#define mapi_foreach(m, e) \
for ((e) = (m)->map.elements; (e) != ((mapi_entry *) (m)->map.elements) + (m)->map.elements_capacity; (e) ++) \
if ((e)->key)

typedef struct mapi_entry mapi_entry;
typedef struct mapi mapi;
typedef void mapi_release(mapi_entry *);

struct mapi_entry
{
uintptr_t key;
uintptr_t value;
};

struct mapi
{
map map;
};

/* constructor/destructor */
void mapi_construct(mapi *);
void mapi_destruct(mapi *, mapi_release *);

/* capacity */
size_t mapi_size(mapi *);
void mapi_reserve(mapi *, size_t);

/* element access */
uintptr_t mapi_at(mapi *, uintptr_t);

/* modifiers */
void mapi_insert(mapi *, uintptr_t, uintptr_t, mapi_release *);
void mapi_erase(mapi *, uintptr_t, mapi_release *);
void mapi_clear(mapi *, mapi_release *);

#endif /* MAPI_H_INCLUDED */

0 comments on commit ba34ba8

Please sign in to comment.