summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbpc2003 <wpesfriendnva@gmail.com>2025-04-30 12:20:13 -0400
committerbpc2003 <wpesfriendnva@gmail.com>2025-04-30 12:20:13 -0400
commit4ea8fe896cc333f5e7addd56e23db5668f4599b3 (patch)
tree56dd3eac6e94f26976188cd08db4ad0466fec826
parent1eddf23c5da0faa055a5feb1bf22cf52b17011a4 (diff)
Made readdb and writedb smaller
-rw-r--r--src/include/engine/file.c211
-rw-r--r--src/main.c49
2 files changed, 132 insertions, 128 deletions
diff --git a/src/include/engine/file.c b/src/include/engine/file.c
index e89dacf..13d6d3e 100644
--- a/src/include/engine/file.c
+++ b/src/include/engine/file.c
@@ -5,137 +5,172 @@
#include "engine.h"
static int check(char **known, int len, char *str);
+static void freeknown(char ***known, int len);
+
static long getsz(FILE *fp);
-static char *makepair(char *key, char *value);
+static int checkmark(char *buf, int pos);
+static char *readidx(char *buf, int *i, char ***known, int *len, int *pos);
-// TODO: reimplement this to read file in FI (Fast Infoset) format
-// TODO: make this smaller
tablist_t *readdb(char *filename)
{
FILE *fp;
- int llen = 2, tlen = 2;
- char **ktags = calloc(tlen, sizeof(char *));
- tablist_t *list = calloc(llen, sizeof(tablist_t));
- list[0].len = llen;
-
+ int len = 2;
+ tablist_t *list = calloc(len, sizeof(tablist_t));
+ list[0].len = len;
if (filename == NULL || (fp = fopen(filename, "rb")) == NULL)
return list;
-
long sz = getsz(fp);
char *buf = calloc(sz, sizeof(char));
fread(buf, sizeof(char), sz, fp);
- char *v, *k;
- for (int i = 0, j = 0, id = 0; i < sz; ++i) {
- if (buf[i] == '\n')
- continue;
- if (j >= tlen)
- ktags = realloc(ktags, ++tlen * sizeof(char *));
- if (buf[i] == '<' || buf[i] == ':') {
- if (buf[i] == '<') {
- int t;
- for (t = i + 1; buf[t] != '>'; ++t) ;
- ktags[j] = calloc(t - i, sizeof(char));
- strncpy(ktags[j++], buf + i + 1, t - i - 1);
- k = ktags[j - 1];
- i += t - i;
- } else {
- int t;
- for (t = i + 1; buf[t] != '\n'; ++t) ;
- v = calloc(t - i, sizeof(char));
- strncpy(v, buf + i + 1, t - i - 1);
- i += t - i;
- char *pair = makepair(k, v);
- setkeys(&list, id, &pair, 1);
- free(pair);
- free(v);
- }
- } else {
- int idx = 0;
- memcpy(&idx, buf + i, sizeof(int));
- i += sizeof(int) - 1;
- if (idx == 1)
- id++;
- k = ktags[idx];
+ fclose(fp);
+
+ int tlen, vlen, t = 0, v = 0, l = -1;
+ char **ktags = calloc((tlen = 2), sizeof(char *));
+ char **kvalues = calloc((vlen = 2), sizeof (char *));
+ char *key, *value;
+ for (int i = 0; i < sz; ++i) {
+ if (buf[i] == ':') {
+ ++i;
+ value = readidx(buf, &i, &kvalues, &vlen, &v);
+ char *pair = calloc(strlen(key) + strlen(value) + 2, sizeof(char));
+ sprintf(pair, "%s:%s", key, value);
+ setkeys(&list, l, &pair, 1);
+ free(pair);
+ key = value = NULL;
+ }
+ else {
+ key = readidx(buf, &i, &ktags, &tlen, &t);
+ if (!strcmp(key, "document"))
+ ++l;
}
}
-
- for (int i = 0; i < tlen - 1; ++i)
- free(ktags[i]);
- free(ktags);
+ freeknown(&ktags, t);
+ freeknown(&kvalues, v);
free(buf);
- fclose(fp);
return list;
}
-// TODO: Make this write to a file in the FI (Fast Infoset) format
-// TODO: Make this smaller
+static char *readidx(char *buf, int *i, char ***known, int *len, int *pos)
+{
+ char *r = NULL;
+ if (checkmark(buf, *i)) {
+ if (*len >= *pos) {
+ *len *= 2;
+ *known = realloc(*known, *len * sizeof(char *));
+ }
+ *i += 4;
+ int nlen;
+ memcpy(&nlen, buf + *i, sizeof(int));
+ *i += sizeof(int);
+ (*known)[*pos] = calloc(nlen + 1, sizeof(char));
+ strncpy((*known)[(*pos)++], buf + *i, nlen);
+ r = (*known)[(*pos) - 1];
+ *i += nlen - 1;
+ } else {
+ int idx;
+ memcpy(&idx, buf + *i, sizeof(int));
+ *i += sizeof(int) - 1;
+ if (idx > *pos)
+ return NULL;
+ r = (*known)[idx];
+ }
+ return r;
+}
+
+static int checkmark(char *buf, int pos)
+{
+ int marker = 0xffffffff;
+ return !memcmp(buf + pos, &marker, sizeof(int));
+}
+
+static long getsz(FILE *fp)
+{
+ fseek(fp, 0, SEEK_END);
+ long sz = ftell(fp);
+ fseek(fp, 0, SEEK_SET);
+ return sz;
+}
+
+static void newtag(char *tag, FILE *fp);
+static void writeidx(char ***known, int *len, int *pos, char *str, FILE *fp);
+
void writedb(char *filename, tablist_t *list)
{
FILE *fp = fopen(filename, "wb");
if (fp == NULL)
return;
- int len = 2;
- char **ktags = calloc(len, sizeof(char *));
+ int tlen, vlen, t = 0, v = 0;
+ char **ktags = calloc((tlen = 2), sizeof(char *));
+ writeidx(&ktags, &tlen, &t, "documents", fp);
+ writeidx(&ktags, &tlen, &t, "document", fp);
- fprintf(fp, "<documents>\n");
- fprintf(fp, "<document>\n");
- ktags[0] = "documents";
- ktags[1] = "document";
+ char buf[64];
+ char **kvalues = calloc((vlen = 2), sizeof(char *));
tablist_t *indexes = getkeys(list, -1, NULL, 0);
- for (int i = 0, j = 2; i < indexes[0].len; ++i) {
- int n = 1;
+ for (int i = 0; i < indexes[0].len; ++i) {
if (i > 0)
- fwrite(&n, sizeof(int), 1, fp);
- for (int k = 0; indexes[i].tab[k].flag; ++k) {
- if ((n = check(ktags, len, indexes[i].tab[k].key)) >= 0)
- fwrite(&n, sizeof(int), 1, fp);
- else {
- fprintf(fp, "<%s>", indexes[i].tab[k].key);
- if (j >= len)
- ktags = realloc(ktags, ++len * sizeof(char *));
- ktags[j] = calloc(strlen(indexes[i].tab[k].key) + 1, sizeof(char));
- strcpy(ktags[j++], indexes[i].tab[k].key);
- }
- switch (indexes[i].tab[k].flag) {
+ writeidx(&ktags, &tlen, &t, "document", fp);
+ for (int j = 0; indexes[i].tab[j].flag; ++j) {
+ writeidx(&ktags, &tlen, &t, indexes[i].tab[j].key, fp);
+ fputc(':', fp);
+ switch (indexes[i].tab[j].flag) {
case 1:
- fprintf(fp, ":%g\n", indexes[i].tab[k].value.num);
+ snprintf(buf, 64, "%g", indexes[i].tab[j].value.num);
+ writeidx(&kvalues, &vlen, &v, buf, fp);
break;
case 2:
- fprintf(fp, ":%s\n", indexes[i].tab[k].value.boolean ? "true" : "false");
+ writeidx(&kvalues, &vlen, &v,
+ indexes[i].tab[j].value.boolean ? "true" : "false", fp);
break;
case 3:
- fprintf(fp, ":%s\n", indexes[i].tab[k].value.str);
+ writeidx(&kvalues, &vlen, &v, indexes[i].tab[j].value.str, fp);
break;
}
}
}
- for (int i = 2; i < len; ++i)
- free(ktags[i]);
- free(ktags);
+ freeknown(&ktags, t);
+ freeknown(&kvalues, v);
free(indexes);
fclose(fp);
}
-static int check(char **known, int len, char *str)
+static void newtag(char *tag, FILE *fp)
{
- for (int i = 0; i < len; ++i) {
- if (!strcmp(str, known[i]))
- return i;
+ int len = strlen(tag);
+ int marker = 0xffffffff;
+ fwrite(&marker, sizeof(int), 1, fp);
+ fwrite(&len, sizeof(int), 1, fp);
+ fwrite(tag, sizeof(char), len, fp);
+}
+
+static void writeidx(char ***known, int *len, int *pos, char *str, FILE *fp)
+{
+ int n;
+ if ((n = check(*known, *pos, str)) >= 0)
+ fwrite(&n, sizeof(int), 1, fp);
+ else {
+ if (*pos >= *len) {
+ *len *= 2;
+ *known = realloc(*known, *len * sizeof(char *));
+ }
+ (*known)[*pos] = calloc(strlen(str) + 1, sizeof(char));
+ strcpy((*known)[*pos], str);
+ newtag((*known)[(*pos)++], fp);
}
- return -1;
}
-static long getsz(FILE *fp)
+static void freeknown(char ***known, int pos)
{
- fseek(fp, 0, SEEK_END);
- long sz = ftell(fp);
- fseek(fp, 0, SEEK_SET);
- return sz;
+ for (int i = 0; i < pos; ++i)
+ free((*known)[i]);
+ free(*known);
}
-static char *makepair(char *key, char *value)
+static int check(char **known, int len, char *str)
{
- char *pair = calloc(strlen(key) + strlen(value) + 2, sizeof(char));
- sprintf(pair, "%s:%s", key, value);
- return pair;
+ for (int i = 0; i < len; ++i) {
+ if (!strcmp(str, known[i]))
+ return i;
+ }
+ return -1;
}
diff --git a/src/main.c b/src/main.c
index 22cb239..42370ab 100644
--- a/src/main.c
+++ b/src/main.c
@@ -7,13 +7,8 @@
#include "cmd.h"
int getid(char *selector);
-int printkeys(tablist_t **list, int id, char **keys, int klen);
+int printkeys(tablist_t *list, int id, char **keys, int klen);
void printkey(tabidx_t idx);
-// TODO: rename these functions
-int setkeys_main(tablist_t **list, int id, char **pairs, int plen);
-int delkeys_main(tablist_t **list, int id, char **keys, int klen);
-int exec(int (*tabop)(tablist_t **, int, char **, int),
- tablist_t **list, int id, char **keys, int klen);
int main(int argc, char **argv)
{
@@ -37,12 +32,15 @@ int main(int argc, char **argv)
int id = getid(evaled.selector);
switch (evaled.type) {
case GET:
- exec(printkeys, &list, id, evaled.params, evaled.plen);
+ printkeys(list, id, evaled.params, evaled.plen);
break;
case SET:
+ id = setkeys(&list, id, evaled.params, evaled.plen);
+ if (!id && filename)
+ writedb(filename, list);
+ break;
case DEL:
- id = exec(evaled.type == SET ? setkeys_main : delkeys_main,
- &list, id, evaled.params, evaled.plen);
+ id = delkeys(list, id, evaled.params, evaled.plen);
if (!id && filename)
writedb(filename, list);
break;
@@ -77,9 +75,9 @@ int getid(char *selector) {
return -2;
}
-int printkeys(tablist_t **list, int id, char **keys, int klen)
+int printkeys(tablist_t *list, int id, char **keys, int klen)
{
- tablist_t *indexes = getkeys(*list, id, keys, klen);
+ tablist_t *indexes = getkeys(list, id, keys, klen);
if (indexes == NULL)
return 1;
for (int i = 0; i < indexes[0].len; ++i) {
@@ -107,32 +105,3 @@ void printkey(tabidx_t idx)
break;
}
}
-
-int setkeys_main(tablist_t **list, int id, char **pairs, int plen)
-{
- if (pairs == NULL || id < -1)
- return 1;
- if (setkeys(list, id, pairs, plen))
- return 2;
- return 0;
-}
-
-int delkeys_main(tablist_t **list, int id, char **keys, int klen)
-{
- if (keys == NULL || id < -1)
- return 1;
- if (delkeys(*list, id, keys, klen))
- return 2;
- return 0;
-}
-
-int exec(int (*tabop)(tablist_t **, int, char **, int),
- tablist_t **list, int id, char **keys, int klen)
-{
- if (id >= -1)
- return tabop(list, id, keys, klen);
- else {
- fprintf(stderr, "Invalid id\n");
- return 1;
- }
-}