diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | Makefile | 7 | ||||
-rw-r--r-- | src/lib/batch.c | 2 | ||||
-rw-r--r-- | src/lib/getkeys.c | 89 | ||||
-rw-r--r-- | src/lib/keytab.c | 32 | ||||
-rw-r--r-- | src/main.c | 49 | ||||
-rw-r--r-- | src/test.c | 12 |
7 files changed, 116 insertions, 77 deletions
@@ -9,5 +9,5 @@ target/ .ccls-cache # debug files -dbg +*dbg core @@ -1,7 +1,7 @@ CC = gcc BUILD = target C_FLAGS = -Wall -lmdb -std=c11 -D_FLAGS = -L$(BUILD) -Wl,-rpath=$(BUILD) +D_FLAGS = -L$(BUILD) -Wl,-rpath=$(BUILD) -O0 L_FLAGS = -c -fPIC -Wall -Werror all: mdb @@ -14,10 +14,9 @@ lib: $(BUILD) test: dev_lib $(CC) src/test.c $(D_FLAGS) -g $(C_FLAGS) -o $(BUILD)/test.out - valgrind --leak-check=full ./$(BUILD)/test.out 2> dbg - valgrind --tool=helgrind ./$(BUILD)/test.out 2>> dbg + valgrind --tool=memcheck -s --log-file="mem_dbg" ./$(BUILD)/test.out + valgrind --tool=drd -s --log-file="thrd_dbg" ./$(BUILD)/test.out rm -rf $(BUILD) - dev: dev_lib $(CC) src/main.c src/cmd.c $(D_FLAGS) -g $(C_FLAGS) -o $(BUILD)/devmdb.out dev_lib: $(BUILD) diff --git a/src/lib/batch.c b/src/lib/batch.c index 998abb9..2d75083 100644 --- a/src/lib/batch.c +++ b/src/lib/batch.c @@ -52,6 +52,7 @@ int setkeys(tablist_t **list, int id, char **pairs, int len) dellist(*list); copytab(*list, setkey_copy); } + mtx_destroy(&setkey_mtx); dellist(setkey_copy); free(setkey_copy); return rc; @@ -93,6 +94,7 @@ int delkeys(tablist_t *list, int id, char **keys, int len) memmove(list, delkey_copy, delkey_copy[0].len * sizeof(tablist_t)); } else dellist(delkey_copy); + mtx_destroy(&delkey_mtx); free(delkey_copy); return rc; } diff --git a/src/lib/getkeys.c b/src/lib/getkeys.c index e69de29..85b3ba1 100644 --- a/src/lib/getkeys.c +++ b/src/lib/getkeys.c @@ -0,0 +1,89 @@ +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <threads.h> + +#include "mdb.h" + +static int getkeys_helper(void *data); + +struct params { + tablist_t *list; + tablist_t *ret; + char **keys; + int len; + int lid; + int pid; +}; + +static struct params *pass(tablist_t *list, tablist_t *ret, char **keys, int len, int lid, int pid); + +mtx_t mtx; + +tablist_t *getkeys(tablist_t *list, int id, char **keys, int klen) +{ + if (id >= list[0].len || id < -1 || mtx_init(&mtx, mtx_plain) != thrd_success) + return NULL; + int rc = 0; + int len = id == -1 ? list[0].len : 1; + tablist_t *indexes = calloc(len, sizeof(tablist_t)); + indexes[0].len = len; + if (id >= 0) + rc = getkeys_helper(pass(list, indexes, keys, klen, id, 0)); + else { + thrd_t *thrds = calloc(list[0].len, sizeof(thrd_t)); + for (int i = 0; i < list[0].len; ++i) + thrd_create(&thrds[i], getkeys_helper, pass(list, indexes, keys, klen, i, i)); + for (int i = 0; i < list[0].len; ++i) { + if (rc) + thrd_join(thrds[i], NULL); + else + thrd_join(thrds[i], &rc); + } + free(thrds); + } + + mtx_destroy(&mtx); + if (!rc) { + return indexes; + } else { + free(indexes); + return NULL; + } +} + +static int getkeys_helper(void *data) +{ + struct params *p = (struct params *) data; + int rc = 0; + + mtx_lock(&mtx); + if (p->keys == NULL) { + for (int i = 0, j = 0; i < TABLEN; ++i) + if (p->list[p->lid].tab[i].flag) + p->ret[p->pid].tab[j++] = p->list[p->lid].tab[i]; + } else { + for (int i = 0, j = 0; i < p->len; ++i) { + tabidx_t idx = getkey(p->list, p->lid, p->keys[i]); + if (idx.flag == 0) + rc = 1; + else + p->ret[p->pid].tab[j++] = idx; + } + } + mtx_unlock(&mtx); + free(p); + return rc; +} + +static struct params *pass(tablist_t *list, tablist_t *ret, char **keys, int len, int lid, int pid) +{ + struct params *p = calloc(1, sizeof(struct params)); + p->list = list; + p->ret = ret; + p->keys = keys; + p->len = len; + p->lid = lid; + p->pid = pid; + return p; +} diff --git a/src/lib/keytab.c b/src/lib/keytab.c index 146937c..9ef4089 100644 --- a/src/lib/keytab.c +++ b/src/lib/keytab.c @@ -7,38 +7,6 @@ static int hash(char *key); static char **getkv(char *pair); -// getkeys - gets every single key in a key table -tablist_t *getkeys(tablist_t *list, int id, char **keys, int klen) -{ - if (id >= list[0].len || id < -1) - return NULL; - int rc = 0; - int len = id == -1 ? list[0].len : 1; - tablist_t *indexes = calloc(len, sizeof(tablist_t)); - indexes[0].len = len; - if (id >= 0) { - if (klen == 0) { - for (int i = 0, j = 0; i < TABLEN; ++i) { - if (list[id].tab[i].flag) - indexes[0].tab[j++] = list[id].tab[i]; - } - } else { - for (int i = 0, j = 0; i < klen; ++i) { - tabidx_t idx = getkey(list, id, keys[i]); - if (idx.flag == 0) - rc = 1; - indexes[0].tab[j++] = idx; - } - } - } - if (!rc) { - return indexes; - } else { - free(indexes); - return NULL; - } -} - // getkey - gets a single key from a keytable // if it can't find the key it will return an empty table index tabidx_t getkey(tablist_t *list, int id, char *key) @@ -79,47 +79,16 @@ int getid(char *selector) { int printkeys(tablist_t **list, int id, char **keys, int klen) { - if (id > -1) { - if (keys == NULL) { - tabidx_t *indexes = getkeys(*list, id, NULL, 0); - printf("{ id: %d ", id); - for (int i = 0; indexes[i].flag; ++i) - printkey(indexes[i]); - free(indexes); - printf("}\n"); - } else { - printf("{ id: %d ", id); - for (int i = 0; i < klen; ++i) { - tabidx_t idx = getkey(*list, id, keys[i]); - if (idx.flag == 0) - continue; - printkey(idx); - } - printf("}\n"); - } - } else { - if (keys == NULL) { - for (int i = 0; i < (*list)[0].len; ++i) { - tabidx_t *indexes = getkeys(*list, i, NULL, 0); - printf("{ id: %d ", i); - for (int j = 0; indexes[j].flag; ++j) - printkey(indexes[j]); - free(indexes); - printf("}\n"); - } - } else { - for (int i = 0; i < (*list)[0].len; ++i) { - printf("{ id: %d\n", i); - for (int j = 0; j < klen; ++j) { - tabidx_t idx = getkey(*list, i, keys[i]); - if (idx.flag == 0) - continue; - printkey(idx); - } - printf("}\n"); - } - } + tablist_t *indexes = getkeys(*list, id, keys, klen); + if (indexes == NULL) + return 1; + for (int i = 0; i < indexes[0].len; ++i) { + printf("{ id: %d ", i); + for (int j = 0; indexes[i].tab[j].flag; ++j) + printkey(indexes[i].tab[j]); + printf("}\n"); } + free(indexes); return 0; } @@ -139,8 +139,20 @@ void test_getkeys_multi_fail(void) free(list); } +void test_getkeys(void) +{ + tablist_t *list = readdb("dbs/test.db"); + tablist_t *ret = getkeys(list, -1, NULL, 0); + if (!ret) + fprintf(stderr, "test_getkeys: failed\n"); + free(ret); + delkeys(list, -1, NULL, 0); + free(list); +} + int main(void) { + test_getkeys(); test_getkeys_multi(); test_getkeys_multi_fail(); |