summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Makefile7
-rw-r--r--src/lib/batch.c2
-rw-r--r--src/lib/getkeys.c89
-rw-r--r--src/lib/keytab.c32
-rw-r--r--src/main.c49
-rw-r--r--src/test.c12
7 files changed, 116 insertions, 77 deletions
diff --git a/.gitignore b/.gitignore
index 1390775..17f634a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,5 +9,5 @@ target/
.ccls-cache
# debug files
-dbg
+*dbg
core
diff --git a/Makefile b/Makefile
index e039ed5..1310bff 100644
--- a/Makefile
+++ b/Makefile
@@ -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)
diff --git a/src/main.c b/src/main.c
index df49b49..c2043d3 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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;
}
diff --git a/src/test.c b/src/test.c
index bb5f063..18201e6 100644
--- a/src/test.c
+++ b/src/test.c
@@ -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();