-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Fredrik Widlund
committed
Apr 15, 2019
1 parent
853098b
commit ba34ba8
Showing
10 changed files
with
513 additions
and
84 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains 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
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); | ||
} |
This file contains 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
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); | ||
} |
This file contains 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
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); | ||
} | ||
|
This file contains 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
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 */ |
Oops, something went wrong.