From 2b7a3a815fb5d0b5155deec5f613730e898e4100 Mon Sep 17 00:00:00 2001 From: bpc2003 Date: Thu, 24 Apr 2025 17:08:08 -0400 Subject: Update Documentation --- Makefile | 4 +- README.md | 25 ++++---- src/include/engine/delkeys.c | 111 ++++++++++++++++++++++++++++++++ src/include/engine/engine.h | 43 +++++++++++++ src/include/engine/file.c | 98 ++++++++++++++++++++++++++++ src/include/engine/getkeys.c | 106 +++++++++++++++++++++++++++++++ src/include/engine/setkeys.c | 148 +++++++++++++++++++++++++++++++++++++++++++ src/include/engine/utils.c | 71 +++++++++++++++++++++ src/include/engine/utils.h | 16 +++++ src/include/mdb.h | 6 ++ src/lib/delkeys.c | 112 -------------------------------- src/lib/file.c | 100 ----------------------------- src/lib/getkeys.c | 106 ------------------------------- src/lib/mdb.h | 43 ------------- src/lib/setkeys.c | 148 ------------------------------------------- src/lib/utils.c | 71 --------------------- src/lib/utils.h | 16 ----- src/main.c | 2 +- src/test.c | 2 +- 19 files changed, 614 insertions(+), 614 deletions(-) create mode 100644 src/include/engine/delkeys.c create mode 100644 src/include/engine/engine.h create mode 100644 src/include/engine/file.c create mode 100644 src/include/engine/getkeys.c create mode 100644 src/include/engine/setkeys.c create mode 100644 src/include/engine/utils.c create mode 100644 src/include/engine/utils.h create mode 100644 src/include/mdb.h delete mode 100644 src/lib/delkeys.c delete mode 100644 src/lib/file.c delete mode 100644 src/lib/getkeys.c delete mode 100644 src/lib/mdb.h delete mode 100644 src/lib/setkeys.c delete mode 100644 src/lib/utils.c delete mode 100644 src/lib/utils.h diff --git a/Makefile b/Makefile index 1310bff..6e0e769 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ all: mdb mdb: lib $(CC) src/main.c src/cmd.c $(D_FLAGS) -O2 $(C_FLAGS) -o $(BUILD)/mdb.out lib: $(BUILD) - $(CC) src/lib/*.c $(L_FLAGS) + $(CC) src/include/engine/*.c $(L_FLAGS) $(CC) -shared -o $(BUILD)/libmdb.so *.o rm *.o @@ -20,7 +20,7 @@ test: dev_lib dev: dev_lib $(CC) src/main.c src/cmd.c $(D_FLAGS) -g $(C_FLAGS) -o $(BUILD)/devmdb.out dev_lib: $(BUILD) - $(CC) src/lib/*.c $(L_FLAGS) -g + $(CC) src/include/engine/*.c $(L_FLAGS) -g $(CC) -shared -o $(BUILD)/libmdb.so *.o rm *.o diff --git a/README.md b/README.md index 8224360..9422802 100644 --- a/README.md +++ b/README.md @@ -43,20 +43,17 @@ if the file doesn't exist it will return an empty tablist array\ if readdb fails in any other way it will return NULL. - writedb: takes a filename and tablist array\ writedb writes the given tablist array to a file. -- getkeys: takes a tablist array and index\ -getkeys finds every single key-value pair in a given tablist\ -and returns an integer array with the indexes of each key-value pair. -- getkey: takes a tablist array, index, and key\ -getkey finds a key-value pair from a given tablist\ -if it can't find the key-value pair it will return an empty -tabidx. -- setkey: takes a pointer to a tablist array, an index, and a key-value pair\ -setkey sets a given key-value pair in a given object, if a given key already exists\ -it will overwrite the value set in that key.\ -If setkey is successful it will return 0. -- delkey: takes a tablist array, an index, and a key\ -delkey deletes the given key-value pair from the given object\ -if successful it will return 0. +- getkeys: takes a tablist array, id, list of keys,\ +and the length of the list of keys.\ +If id is -1, it will get every provided key from every document.\ +If keys is NULL, it will get every key-value pair from a document. +- setkeys: takes a tablist array, id, list of key-value pairs,\ +and the length of the list of pairs.\ +If id is -1, it will set the provided pairs in every document. +- delkeys: takes a tablist array, id, list of keys,\ +and the length of the list of keys.\ +If id is -1, it will delete every provided key from every document.\ +If keys is NULL it will delete every key from a document. ## Removal In order to remove mdb run:\ diff --git a/src/include/engine/delkeys.c b/src/include/engine/delkeys.c new file mode 100644 index 0000000..ad9c228 --- /dev/null +++ b/src/include/engine/delkeys.c @@ -0,0 +1,111 @@ +#include +#include +#include + +#include "engine.h" +#include "utils.h" + +static int delkey_helper(void *thr_data); +static int delkey(tablist_t *, int, char *); +static struct params *pass(mtx_t *mtx, tablist_t *list, char **keys, int len, int id); + +struct params { + mtx_t *mtx; + tablist_t *copy; + char **keys; + int len; + int id; +}; + + +int delkeys(tablist_t *list, int id, char **keys, int len) +{ + mtx_t mtx; + if (id >= list[0].len || id < -1 || len < 0) + return -1; + if (mtx_init(&mtx, mtx_plain) != thrd_success) + return -2; + int rc = 0; + tablist_t *copy = calloc(list[0].len, sizeof(tablist_t)); + copytab(copy, list); + + if (id == -1) { + thrd_t *thrds = calloc(list[0].len, sizeof(thrd_t)); + for (int i = 0; i < copy[0].len; ++i) + thrd_create(&thrds[i], delkey_helper, pass(&mtx, copy, keys, len, i)); + for (int i = 0; i < copy[0].len; ++i) { + if (rc) + thrd_join(thrds[i], NULL); + else + thrd_join(thrds[i], &rc); + } + free(thrds); + } else + rc = delkey_helper(pass(&mtx, copy, keys, len, id)); + + if (!rc) { + dellist(list); + memmove(list, copy, copy[0].len * sizeof(tablist_t)); + } else + dellist(copy); + mtx_destroy(&mtx); + free(copy); + return rc; +} + +static int delkey_helper(void *thr_data) +{ + int rc = 0; + struct params *p = (struct params *) thr_data; + + mtx_lock(p->mtx); + if (p->len > 0 && p->keys != NULL) + for (int i = 0; i < p->len; ++i) { + if (p->keys[i] == NULL) { + mtx_unlock(p->mtx); + free(p); + return -3; + } + rc = delkey(p->copy, p->id, p->keys[i]); + } + else { + tablist_t *indexes = getkeys(p->copy, p->id, NULL, 0); + for (int i = 0; indexes[0].tab[i].flag; ++i) + rc = delkey(p->copy, p->id, indexes[0].tab[i].key); + free(indexes); + } + mtx_unlock(p->mtx); + + free(p); + return rc; +} + +static int delkey(tablist_t *list, int id, char *key) +{ + int idx = hash(key); + if (list[id].tab[idx].key == NULL) + return 1; + while (strcmp(list[id].tab[idx].key, key) && idx < TABLEN) + idx++; + if (idx >= TABLEN) + return 2; + free(list[id].tab[idx].key); + list[id].tab[idx].key = NULL; + if (list[id].tab[idx].flag == 3) { + free(list[id].tab[idx].value.str); + list[id].tab[idx].value.str = NULL; + } + list[id].tab[idx].flag = 0; + return 0; +} + +static struct params *pass(mtx_t *mtx, tablist_t *list, char **keys, int len, int id) +{ + struct params *p = calloc(1, sizeof(struct params)); + p->mtx = mtx; + p->copy = list; + p->keys = keys; + p->len = len; + p->id = id; + return p; +} diff --git a/src/include/engine/engine.h b/src/include/engine/engine.h new file mode 100644 index 0000000..d233bdd --- /dev/null +++ b/src/include/engine/engine.h @@ -0,0 +1,43 @@ +#ifndef ENGINE_H +#define ENGINE_H + +#define TABLEN 1024 + +typedef struct { + char *key; + int flag; + union { + char *str; + double num; + unsigned int boolean : 1; + } value; +} tabidx_t; + +typedef struct { + int len; + tabidx_t tab[TABLEN]; +} tablist_t; + +/* getkeys: gets the provided keys from the provided id, + * if the id is set to -1, it will get the provided key from every document, + * if keys is NULL, it will get every key. */ +tablist_t *getkeys(tablist_t *list, int id, char **keys, int len); + +/* setkeys: sets the provided key-value pairs in the provided object, + * if the id is -1, it will set the provided pairs in every object. */ +int setkeys(tablist_t **list, int id, char **pairs, int len); + +/* delkeys: deletes the provided keys from the provided id, + * if the id is -1, it will delete the provided key from every document, + * if keys is NULL it, will delete every key. */ +int delkeys(tablist_t *list, int id, char **keys, int len); + +/* readdb: reads the provided db file, + * if the filename is NULL, it will return an empty table list, + * if the file format is invalid, it will return NULL. */ +tablist_t *readdb(char *filename); + +/* writedb: writes a table list to a database file. */ +void writedb(char *filename, tablist_t *list); + +#endif diff --git a/src/include/engine/file.c b/src/include/engine/file.c new file mode 100644 index 0000000..4da8b2d --- /dev/null +++ b/src/include/engine/file.c @@ -0,0 +1,98 @@ +#include +#include +#include + +#include "engine.h" + +static char *getpair(int *c, FILE *fp); + +// TODO: reimplement this to read file in FI format +tablist_t *readdb(char *filename) +{ + int len = 2; + tablist_t *list = calloc(len, sizeof(tablist_t)); + list[0].len = len; + FILE *fp; + if (filename == NULL || + (fp = fopen(filename, "rb")) == NULL) + return list; + + int c, i = 0, open = 0; + char *p; + while ((c = fgetc(fp)) != EOF) { + switch (c) { + case 250: + p = getpair(&c, fp); + if (p == NULL) goto fail; + setkeys(&list, i, &p, 1); + free(p); + break; + case 251: + if (open == 1) goto fail; + open = 1; + break; + case 254: + open = 0; + i++; + break; + default: + goto fail; + } + } + fclose(fp); + return list; + +fail: + fclose(fp); + delkeys(list, -1, NULL, 0); + free(list); + return NULL; +} + +// TODO: rewrite this function to write data in FI format +void writedb(char *filename, tablist_t *list) +{ + FILE *fp = fopen(filename, "wb"); + if (fp == NULL) + return; + for (int i = 0; i < list[0].len; ++i) { + fputc(0xFB, fp); + tablist_t *indexes = getkeys(list, i, NULL, 0); + for (int j = 0; indexes[0].tab[j].flag; ++j) { + fprintf(fp, "\xfa%s:", indexes[0].tab[j].key); + switch (indexes[0].tab[j].flag) { + case 1: + fprintf(fp, "%.2lf\xfc", indexes[0].tab[j].value.num); + break; + case 2: + fprintf(fp, "%s\xfc", indexes[0].tab[j].value.boolean ? + "true" : "false"); + break; + case 3: + fprintf(fp, "%s\xfc", indexes[0].tab[j].value.str); + break; + } + } + free(indexes); + fputc(0xFE, fp); + } + fclose(fp); +} + +static char *getpair(int *c, FILE *fp) +{ + char *pair = calloc(3, sizeof(char)); + int i = 0, len = 3; + while ((*c = fgetc(fp)) != 252 && *c != EOF) { + if (i >= len) + pair = realloc(pair, ++len * sizeof(char)); + pair[i++] = *c; + } + pair = realloc(pair, ++len * sizeof(char)); + pair[i] = '\0'; + if (*c != 252) { + free(pair); + return NULL; + } + return pair; +} diff --git a/src/include/engine/getkeys.c b/src/include/engine/getkeys.c new file mode 100644 index 0000000..ae2eb73 --- /dev/null +++ b/src/include/engine/getkeys.c @@ -0,0 +1,106 @@ +#include +#include +#include +#include + +#include "engine.h" +#include "utils.h" + +static tabidx_t getkey(tablist_t *list, int id, char *key); + +static int getkeys_helper(void *data); + +struct params { + mtx_t *mtx; + tablist_t *list; + tablist_t *ret; + char **keys; + int len; + int lid; + int pid; +}; + +static struct params *pass(mtx_t *mtx, tablist_t *list, tablist_t *ret, char **keys, int len, int lid, int pid); + +tablist_t *getkeys(tablist_t *list, int id, char **keys, int klen) +{ + mtx_t mtx; + 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(&mtx, 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(&mtx, 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(p->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(p->mtx); + free(p); + return rc; +} + +static struct params *pass(mtx_t *mtx, tablist_t *list, tablist_t *ret, char **keys, int len, int lid, int pid) +{ + struct params *p = calloc(1, sizeof(struct params)); + p->mtx = mtx; + p->list = list; + p->ret = ret; + p->keys = keys; + p->len = len; + p->lid = lid; + p->pid = pid; + return p; +} + +static tabidx_t getkey(tablist_t *list, int id, char *key) +{ + int idx = hash(key); + if (list[id].tab[idx].key == NULL) + return (tabidx_t) { .key = NULL, .flag = 0, .value = { 0 } }; + + while (strcmp(list[id].tab[idx].key, key) && idx < TABLEN) + idx++; + if (idx >= TABLEN) + return (tabidx_t) { .key = NULL, .flag = 0, .value = { 0 } }; + return list[id].tab[idx]; +} diff --git a/src/include/engine/setkeys.c b/src/include/engine/setkeys.c new file mode 100644 index 0000000..34ef3d2 --- /dev/null +++ b/src/include/engine/setkeys.c @@ -0,0 +1,148 @@ +#include +#include +#include +#include + +#include "engine.h" +#include "utils.h" + +static int setkey_helper(void *thr_data); +static int setkey(tablist_t **, int, char *); +static char **getkv(char *pair); + +struct params { + mtx_t *mtx; + tablist_t **copy; + char *pair; + int id; +}; + +static struct params *pass(mtx_t *mtx, tablist_t **copy, char *pair, int id); + +int setkeys(tablist_t **list, int id, char **pairs, int len) +{ + mtx_t mtx; + if (id < -1 || pairs == NULL || len <= 0) + return -1; + if (mtx_init(&mtx, mtx_plain) != thrd_success) + return -2; + int rc = 0; + tablist_t *copy = calloc((*list)[0].len, sizeof(tablist_t)); + copytab(copy, *list); + + for (int i = 0; i < len; ++i) { + char *pair = pairs[i]; + if (id == -1) { + thrd_t *thrds = calloc((*list)[0].len, sizeof(thrd_t)); + for (int i = 0; i < copy[0].len; ++i) + thrd_create(&thrds[i], setkey_helper, pass(&mtx, ©, pair, i)); + for (int i = 0; i < copy[0].len; ++i) { + if (rc) + thrd_join(thrds[i], NULL); + else + thrd_join(thrds[i], &rc); + } + free(thrds); + } + else + rc = setkey_helper(pass(&mtx, ©, pair, id)); + } + + if (!rc) { + if (copy[0].len > (*list)[0].len) + *list = realloc(*list, copy[0].len * sizeof(tablist_t)); + dellist(*list); + copytab(*list, copy); + } + mtx_destroy(&mtx); + dellist(copy); + free(copy); + return rc; +} + +static int setkey_helper(void *thr_data) +{ + int rc; + struct params *p = (struct params *) thr_data; + + mtx_lock(p->mtx); + rc = setkey(p->copy, p->id, p->pair); + mtx_unlock(p->mtx); + + free(p); + return rc; +} + +static int setkey(tablist_t **list, int id, char *pair) +{ + if (pair == NULL) + return 1; + if (id >= (*list)[0].len) { + *list = realloc(*list, (id + 1) * sizeof(tablist_t)); + for (int i = (*list)[0].len; i <= id; ++i) { + for (int j = 0; j < TABLEN; ++j) + (*list)[i].tab[j] = (tabidx_t) { NULL, 0, { 0 } }; + } + (*list)[0].len = id + 1; + } + char **kv = getkv(pair); + if (kv == NULL) + return 2; + + int idx = hash(kv[0]); + while ((*list)[id].tab[idx].key != NULL && + strcmp((*list)[id].tab[idx].key, kv[0]) && + idx < TABLEN) idx++; + if (idx >= TABLEN) + return 2; + if (!(*list)[id].tab[idx].key) + (*list)[id].tab[idx].key = kv[0]; + else { + free(kv[0]); + if ((*list)[id].tab[idx].flag == 3) + free((*list)[id].tab[idx].value.str); + } + char *end; + double num = strtod(kv[1], &end); + if (*end == '\0') { + (*list)[id].tab[idx].flag = 1; + (*list)[id].tab[idx].value.num = num; + } else if (!strcmp(kv[1], "true") || !strcmp(kv[1], "false")) { + (*list)[id].tab[idx].flag = 2; + (*list)[id].tab[idx].value.boolean = !strcmp(kv[1], "true"); + } else { + (*list)[id].tab[idx].flag = 3; + (*list)[id].tab[idx].value.str = calloc(strlen(kv[1]) + 1, sizeof(char)); + strcpy((*list)[id].tab[idx].value.str, kv[1]); + } + free(kv[1]); + free(kv); + return 0; +} + +static char **getkv(char *pair) +{ + char **kv = calloc(2, sizeof(char *)); + int i = 0; + while (pair[i] != ':' && i < strlen(pair)) + i++; + if (i >= strlen(pair)) { + free(kv); + return NULL; + } + kv[0] = calloc(i + 1, sizeof(char)); + strncpy(kv[0], pair, i); + kv[1] = calloc(strlen(pair) - i, sizeof(char)); + strcpy(kv[1], pair + i + 1); + return kv; +} + +static struct params *pass(mtx_t *mtx, tablist_t **copy, char *pair, int id) +{ + struct params *p = calloc(1, sizeof(struct params)); + p->mtx = mtx; + p->copy = copy; + p->pair = pair; + p->id = id; + return p; +} diff --git a/src/include/engine/utils.c b/src/include/engine/utils.c new file mode 100644 index 0000000..909c123 --- /dev/null +++ b/src/include/engine/utils.c @@ -0,0 +1,71 @@ +#include +#include + +#include "utils.h" + +static int delkey(tablist_t *, int, char *); + +void dellist(tablist_t *list) +{ + for (int i = 0; i < list[0].len; ++i) { + tablist_t *indexes = getkeys(list, i, NULL, 0); + for (int j = 0; indexes[0].tab[j].flag; ++j) + delkey(list, i, indexes[0].tab[j].key); + free(indexes); + } +} + +int hash(char *key) +{ + unsigned long h = 5381; + for (int i = 0; i < strlen(key); ++i) + h = ((h << 5) + h) + key[i]; + return h % TABLEN; +} + +tablist_t *copytab(tablist_t *dst, tablist_t *src) +{ + if (dst == NULL) + return NULL; + dst[0].len = src[0].len; + for (int i = 0; i < src[0].len; ++i) { + for (int j = 0; j < TABLEN; ++j) { + dst[i].tab[j] = (tabidx_t) { NULL, 0, { 0 } }; + if (src[i].tab[j].flag) { + switch (src[i].tab[j].flag) { + case 3: + dst[i].tab[j].value.str = + calloc(strlen(src[i].tab[j].value.str) + 1, sizeof(char)); + strcpy(dst[i].tab[j].value.str, src[i].tab[j].value.str); + break; + default: + dst[i].tab[j].value = src[i].tab[j].value; + break; + } + dst[i].tab[j].flag = src[i].tab[j].flag; + dst[i].tab[j].key = calloc(strlen(src[i].tab[j].key) + 1, sizeof(char)); + strcpy(dst[i].tab[j].key, src[i].tab[j].key); + } + } + } + return dst; +} + +static int delkey(tablist_t *list, int id, char *key) +{ + int idx = hash(key); + if (list[id].tab[idx].key == NULL) + return 1; + while (strcmp(list[id].tab[idx].key, key) && idx < TABLEN) + idx++; + if (idx >= TABLEN) + return 2; + free(list[id].tab[idx].key); + list[id].tab[idx].key = NULL; + if (list[id].tab[idx].flag == 3) { + free(list[id].tab[idx].value.str); + list[id].tab[idx].value.str = NULL; + } + list[id].tab[idx].flag = 0; + return 0; +} diff --git a/src/include/engine/utils.h b/src/include/engine/utils.h new file mode 100644 index 0000000..54bfc17 --- /dev/null +++ b/src/include/engine/utils.h @@ -0,0 +1,16 @@ +#ifndef UTILS_H +#define UTILS_H + +#include "engine.h" + +// dellist: deletes the provided table +void dellist(tablist_t *list); + +/* hash: calculates the DJB2 hash of a string, + * and returns that mod TABLEN */ +int hash(char *str); + +// copytab: copys table src into table dst +tablist_t *copytab(tablist_t *dst, tablist_t *src); + +#endif diff --git a/src/include/mdb.h b/src/include/mdb.h new file mode 100644 index 0000000..cba4aa8 --- /dev/null +++ b/src/include/mdb.h @@ -0,0 +1,6 @@ +#ifndef MDB_H +#define MDB_H + +#include "engine/engine.h" + +#endif diff --git a/src/lib/delkeys.c b/src/lib/delkeys.c deleted file mode 100644 index a828e8d..0000000 --- a/src/lib/delkeys.c +++ /dev/null @@ -1,112 +0,0 @@ -#include -#include -#include - -#include "mdb.h" -#include "utils.h" - -static int delkey_helper(void *thr_data); -static int delkey(tablist_t *, int, char *); -static struct params *pass(mtx_t *mtx, tablist_t *list, char **keys, int len, int id); - - -struct params { - mtx_t *mtx; - tablist_t *copy; - char **keys; - int len; - int id; -}; - - -int delkeys(tablist_t *list, int id, char **keys, int len) -{ - mtx_t mtx; - if (id >= list[0].len || id < -1 || len < 0) - return -1; - if (mtx_init(&mtx, mtx_plain) != thrd_success) - return -2; - int rc = 0; - tablist_t *delkey_copy = calloc(list[0].len, sizeof(tablist_t)); - copytab(delkey_copy, list); - - if (id == -1) { - thrd_t *thrds = calloc(list[0].len, sizeof(thrd_t)); - for (int i = 0; i < delkey_copy[0].len; ++i) - thrd_create(&thrds[i], delkey_helper, pass(&mtx, delkey_copy, keys, len, i)); - for (int i = 0; i < delkey_copy[0].len; ++i) { - if (rc) - thrd_join(thrds[i], NULL); - else - thrd_join(thrds[i], &rc); - } - free(thrds); - } else - rc = delkey_helper(pass(&mtx, delkey_copy, keys, len, id)); - - if (!rc) { - dellist(list); - memmove(list, delkey_copy, delkey_copy[0].len * sizeof(tablist_t)); - } else - dellist(delkey_copy); - mtx_destroy(&mtx); - free(delkey_copy); - return rc; -} - -static int delkey_helper(void *thr_data) -{ - int rc = 0; - struct params *p = (struct params *) thr_data; - - mtx_lock(p->mtx); - if (p->len > 0 && p->keys != NULL) - for (int i = 0; i < p->len; ++i) { - if (p->keys[i] == NULL) { - mtx_unlock(p->mtx); - free(p); - return -3; - } - rc = delkey(p->copy, p->id, p->keys[i]); - } - else { - tablist_t *indexes = getkeys(p->copy, p->id, NULL, 0); - for (int i = 0; indexes[0].tab[i].flag; ++i) - rc = delkey(p->copy, p->id, indexes[0].tab[i].key); - free(indexes); - } - mtx_unlock(p->mtx); - - free(p); - return rc; -} - -static int delkey(tablist_t *list, int id, char *key) -{ - int idx = hash(key); - if (list[id].tab[idx].key == NULL) - return 1; - while (strcmp(list[id].tab[idx].key, key) && idx < TABLEN) - idx++; - if (idx >= TABLEN) - return 2; - free(list[id].tab[idx].key); - list[id].tab[idx].key = NULL; - if (list[id].tab[idx].flag == 3) { - free(list[id].tab[idx].value.str); - list[id].tab[idx].value.str = NULL; - } - list[id].tab[idx].flag = 0; - return 0; -} - -static struct params *pass(mtx_t *mtx, tablist_t *list, char **keys, int len, int id) -{ - struct params *p = calloc(1, sizeof(struct params)); - p->mtx = mtx; - p->copy = list; - p->keys = keys; - p->len = len; - p->id = id; - return p; -} diff --git a/src/lib/file.c b/src/lib/file.c deleted file mode 100644 index 8b0c715..0000000 --- a/src/lib/file.c +++ /dev/null @@ -1,100 +0,0 @@ -#include -#include -#include - -#include "mdb.h" - -static char *getpair(int *c, FILE *fp); - -// readdb - reads the given file into a key table list -// if fp returns NULL it will return the empty list -// if readdb fails it will return NULL -tablist_t *readdb(char *filename) -{ - int len = 2; - tablist_t *list = calloc(len, sizeof(tablist_t)); - list[0].len = len; - FILE *fp; - if (filename == NULL || - (fp = fopen(filename, "rb")) == NULL) - return list; - - int c, i = 0, open = 0; - char *p; - while ((c = fgetc(fp)) != EOF) { - switch (c) { - case 250: - p = getpair(&c, fp); - if (p == NULL) goto fail; - setkeys(&list, i, &p, 1); - free(p); - break; - case 251: - if (open == 1) goto fail; - open = 1; - break; - case 254: - open = 0; - i++; - break; - default: - goto fail; - } - } - fclose(fp); - return list; - -fail: - fclose(fp); - delkeys(list, -1, NULL, 0); - free(list); - return NULL; -} - -// writedb - writes a keytablist to a given file -void writedb(char *filename, tablist_t *list) -{ - FILE *fp = fopen(filename, "wb"); - if (fp == NULL) - return; - for (int i = 0; i < list[0].len; ++i) { - fputc(0xFB, fp); - tablist_t *indexes = getkeys(list, i, NULL, 0); - for (int j = 0; indexes[0].tab[j].flag; ++j) { - fprintf(fp, "\xfa%s:", indexes[0].tab[j].key); - switch (indexes[0].tab[j].flag) { - case 1: - fprintf(fp, "%.2lf\xfc", indexes[0].tab[j].value.num); - break; - case 2: - fprintf(fp, "%s\xfc", indexes[0].tab[j].value.boolean ? - "true" : "false"); - break; - case 3: - fprintf(fp, "%s\xfc", indexes[0].tab[j].value.str); - break; - } - } - free(indexes); - fputc(0xFE, fp); - } - fclose(fp); -} - -static char *getpair(int *c, FILE *fp) -{ - char *pair = calloc(3, sizeof(char)); - int i = 0, len = 3; - while ((*c = fgetc(fp)) != 252 && *c != EOF) { - if (i >= len) - pair = realloc(pair, ++len * sizeof(char)); - pair[i++] = *c; - } - pair = realloc(pair, ++len * sizeof(char)); - pair[i] = '\0'; - if (*c != 252) { - free(pair); - return NULL; - } - return pair; -} diff --git a/src/lib/getkeys.c b/src/lib/getkeys.c deleted file mode 100644 index ab1cb2f..0000000 --- a/src/lib/getkeys.c +++ /dev/null @@ -1,106 +0,0 @@ -#include -#include -#include -#include - -#include "mdb.h" -#include "utils.h" - -static tabidx_t getkey(tablist_t *list, int id, char *key); - -static int getkeys_helper(void *data); - -struct params { - mtx_t *mtx; - tablist_t *list; - tablist_t *ret; - char **keys; - int len; - int lid; - int pid; -}; - -static struct params *pass(mtx_t *mtx, tablist_t *list, tablist_t *ret, char **keys, int len, int lid, int pid); - -tablist_t *getkeys(tablist_t *list, int id, char **keys, int klen) -{ - mtx_t mtx; - 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(&mtx, 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(&mtx, 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(p->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(p->mtx); - free(p); - return rc; -} - -static struct params *pass(mtx_t *mtx, tablist_t *list, tablist_t *ret, char **keys, int len, int lid, int pid) -{ - struct params *p = calloc(1, sizeof(struct params)); - p->mtx = mtx; - p->list = list; - p->ret = ret; - p->keys = keys; - p->len = len; - p->lid = lid; - p->pid = pid; - return p; -} - -static tabidx_t getkey(tablist_t *list, int id, char *key) -{ - int idx = hash(key); - if (list[id].tab[idx].key == NULL) - return (tabidx_t) { .key = NULL, .flag = 0, .value = { 0 } }; - - while (strcmp(list[id].tab[idx].key, key) && idx < TABLEN) - idx++; - if (idx >= TABLEN) - return (tabidx_t) { .key = NULL, .flag = 0, .value = { 0 } }; - return list[id].tab[idx]; -} diff --git a/src/lib/mdb.h b/src/lib/mdb.h deleted file mode 100644 index cb0502d..0000000 --- a/src/lib/mdb.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef MDB_H -#define MDB_H - -#define TABLEN 1024 - -typedef struct { - char *key; - int flag; - union { - char *str; - double num; - unsigned int boolean : 1; - } value; -} tabidx_t; - -typedef struct { - int len; - tabidx_t tab[TABLEN]; -} tablist_t; - -/* getkeys: gets the provided keys from the provided id, - * if the id is set to -1, it will get the provided key from every document, - * if keys is NULL, it will get every key. */ -tablist_t *getkeys(tablist_t *list, int id, char **keys, int len); - -/* setkeys: sets the provided key-value pairs in the provided object, - * if the id is -1, it will set the provided pairs in every object. */ -int setkeys(tablist_t **list, int id, char **pairs, int len); - -/* delkeys: deletes the provided keys from the provided id, - * if the id is -1, it will delete the provided key from every document, - * if keys is NULL it, will delete every key. */ -int delkeys(tablist_t *list, int id, char **keys, int len); - -/* readdb: reads the provided db file, - * if the filename is NULL, it will return an empty table list, - * if the file format is invalid, it will return NULL. */ -tablist_t *readdb(char *filename); - -/* writedb: writes a table list to a database file. */ -void writedb(char *filename, tablist_t *list); - -#endif diff --git a/src/lib/setkeys.c b/src/lib/setkeys.c deleted file mode 100644 index f52ab48..0000000 --- a/src/lib/setkeys.c +++ /dev/null @@ -1,148 +0,0 @@ -#include -#include -#include -#include - -#include "mdb.h" -#include "utils.h" - -static int setkey_helper(void *thr_data); -static int setkey(tablist_t **, int, char *); -static char **getkv(char *pair); - -struct params { - mtx_t *mtx; - tablist_t **copy; - char *pair; - int id; -}; - -static struct params *pass(mtx_t *mtx, tablist_t **copy, char *pair, int id); - -int setkeys(tablist_t **list, int id, char **pairs, int len) -{ - mtx_t mtx; - if (id < -1 || pairs == NULL || len <= 0) - return -1; - if (mtx_init(&mtx, mtx_plain) != thrd_success) - return -2; - int rc = 0; - tablist_t *copy = calloc((*list)[0].len, sizeof(tablist_t)); - copytab(copy, *list); - - for (int i = 0; i < len; ++i) { - char *pair = pairs[i]; - if (id == -1) { - thrd_t *thrds = calloc((*list)[0].len, sizeof(thrd_t)); - for (int i = 0; i < copy[0].len; ++i) - thrd_create(&thrds[i], setkey_helper, pass(&mtx, ©, pair, i)); - for (int i = 0; i < copy[0].len; ++i) { - if (rc) - thrd_join(thrds[i], NULL); - else - thrd_join(thrds[i], &rc); - } - free(thrds); - } - else - rc = setkey_helper(pass(&mtx, ©, pair, id)); - } - - if (!rc) { - if (copy[0].len > (*list)[0].len) - *list = realloc(*list, copy[0].len * sizeof(tablist_t)); - dellist(*list); - copytab(*list, copy); - } - mtx_destroy(&mtx); - dellist(copy); - free(copy); - return rc; -} - -static int setkey_helper(void *thr_data) -{ - int rc; - struct params *p = (struct params *) thr_data; - - mtx_lock(p->mtx); - rc = setkey(p->copy, p->id, p->pair); - mtx_unlock(p->mtx); - - free(p); - return rc; -} - -static int setkey(tablist_t **list, int id, char *pair) -{ - if (pair == NULL) - return 1; - if (id >= (*list)[0].len) { - *list = realloc(*list, (id + 1) * sizeof(tablist_t)); - for (int i = (*list)[0].len; i <= id; ++i) { - for (int j = 0; j < TABLEN; ++j) - (*list)[i].tab[j] = (tabidx_t) { NULL, 0, { 0 } }; - } - (*list)[0].len = id + 1; - } - char **kv = getkv(pair); - if (kv == NULL) - return 2; - - int idx = hash(kv[0]); - while ((*list)[id].tab[idx].key != NULL && - strcmp((*list)[id].tab[idx].key, kv[0]) && - idx < TABLEN) idx++; - if (idx >= TABLEN) - return 2; - if (!(*list)[id].tab[idx].key) - (*list)[id].tab[idx].key = kv[0]; - else { - free(kv[0]); - if ((*list)[id].tab[idx].flag == 3) - free((*list)[id].tab[idx].value.str); - } - char *end; - double num = strtod(kv[1], &end); - if (*end == '\0') { - (*list)[id].tab[idx].flag = 1; - (*list)[id].tab[idx].value.num = num; - } else if (!strcmp(kv[1], "true") || !strcmp(kv[1], "false")) { - (*list)[id].tab[idx].flag = 2; - (*list)[id].tab[idx].value.boolean = !strcmp(kv[1], "true"); - } else { - (*list)[id].tab[idx].flag = 3; - (*list)[id].tab[idx].value.str = calloc(strlen(kv[1]) + 1, sizeof(char)); - strcpy((*list)[id].tab[idx].value.str, kv[1]); - } - free(kv[1]); - free(kv); - return 0; -} - -static char **getkv(char *pair) -{ - char **kv = calloc(2, sizeof(char *)); - int i = 0; - while (pair[i] != ':' && i < strlen(pair)) - i++; - if (i >= strlen(pair)) { - free(kv); - return NULL; - } - kv[0] = calloc(i + 1, sizeof(char)); - strncpy(kv[0], pair, i); - kv[1] = calloc(strlen(pair) - i, sizeof(char)); - strcpy(kv[1], pair + i + 1); - return kv; -} - -static struct params *pass(mtx_t *mtx, tablist_t **copy, char *pair, int id) -{ - struct params *p = calloc(1, sizeof(struct params)); - p->mtx = mtx; - p->copy = copy; - p->pair = pair; - p->id = id; - return p; -} diff --git a/src/lib/utils.c b/src/lib/utils.c deleted file mode 100644 index 909c123..0000000 --- a/src/lib/utils.c +++ /dev/null @@ -1,71 +0,0 @@ -#include -#include - -#include "utils.h" - -static int delkey(tablist_t *, int, char *); - -void dellist(tablist_t *list) -{ - for (int i = 0; i < list[0].len; ++i) { - tablist_t *indexes = getkeys(list, i, NULL, 0); - for (int j = 0; indexes[0].tab[j].flag; ++j) - delkey(list, i, indexes[0].tab[j].key); - free(indexes); - } -} - -int hash(char *key) -{ - unsigned long h = 5381; - for (int i = 0; i < strlen(key); ++i) - h = ((h << 5) + h) + key[i]; - return h % TABLEN; -} - -tablist_t *copytab(tablist_t *dst, tablist_t *src) -{ - if (dst == NULL) - return NULL; - dst[0].len = src[0].len; - for (int i = 0; i < src[0].len; ++i) { - for (int j = 0; j < TABLEN; ++j) { - dst[i].tab[j] = (tabidx_t) { NULL, 0, { 0 } }; - if (src[i].tab[j].flag) { - switch (src[i].tab[j].flag) { - case 3: - dst[i].tab[j].value.str = - calloc(strlen(src[i].tab[j].value.str) + 1, sizeof(char)); - strcpy(dst[i].tab[j].value.str, src[i].tab[j].value.str); - break; - default: - dst[i].tab[j].value = src[i].tab[j].value; - break; - } - dst[i].tab[j].flag = src[i].tab[j].flag; - dst[i].tab[j].key = calloc(strlen(src[i].tab[j].key) + 1, sizeof(char)); - strcpy(dst[i].tab[j].key, src[i].tab[j].key); - } - } - } - return dst; -} - -static int delkey(tablist_t *list, int id, char *key) -{ - int idx = hash(key); - if (list[id].tab[idx].key == NULL) - return 1; - while (strcmp(list[id].tab[idx].key, key) && idx < TABLEN) - idx++; - if (idx >= TABLEN) - return 2; - free(list[id].tab[idx].key); - list[id].tab[idx].key = NULL; - if (list[id].tab[idx].flag == 3) { - free(list[id].tab[idx].value.str); - list[id].tab[idx].value.str = NULL; - } - list[id].tab[idx].flag = 0; - return 0; -} diff --git a/src/lib/utils.h b/src/lib/utils.h deleted file mode 100644 index 99a8efa..0000000 --- a/src/lib/utils.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef UTILS_H -#define UTILS_H - -#include "mdb.h" - -// dellist: deletes the provided table -void dellist(tablist_t *list); - -/* hash: calculates the DJB2 hash of a string, - * and returns that mod TABLEN */ -int hash(char *str); - -// copytab: copys table src into table dst -tablist_t *copytab(tablist_t *dst, tablist_t *src); - -#endif diff --git a/src/main.c b/src/main.c index c2043d3..22cb239 100644 --- a/src/main.c +++ b/src/main.c @@ -3,7 +3,7 @@ #include #include -#include "lib/mdb.h" +#include "include/mdb.h" #include "cmd.h" int getid(char *selector); diff --git a/src/test.c b/src/test.c index 58f4a70..ee4b118 100644 --- a/src/test.c +++ b/src/test.c @@ -1,7 +1,7 @@ #include #include -#include "lib/mdb.h" +#include "include/mdb.h" void test_setkeys(void) { -- cgit v1.2.3