aboutsummaryrefslogtreecommitdiff
path: root/src/storage.c
diff options
context:
space:
mode:
authorSoikk2022-07-23 01:46:24 +0200
committerSoikk2022-07-23 01:46:24 +0200
commit28578b192d0828a9820983b5624b9bcc3577cd18 (patch)
tree2f30b1730f30a7eeee80995ee3984c10f5bdc2ff /src/storage.c
parent377dc104be127291ede5b32640c23eea0ba6791a (diff)
downloadsoikk-DB-28578b192d0828a9820983b5624b9bcc3577cd18.tar.xz
soikk-DB-28578b192d0828a9820983b5624b9bcc3577cd18.tar.zst
Improved the database storage system. Added persistency.
Diffstat (limited to 'src/storage.c')
-rw-r--r--src/storage.c255
1 files changed, 229 insertions, 26 deletions
diff --git a/src/storage.c b/src/storage.c
index 868e0b2..930f636 100644
--- a/src/storage.c
+++ b/src/storage.c
@@ -1,18 +1,234 @@
#include "db.h"
-row *newRow(const char path[MAXPATH]){
- row *nr = malloc(sizeof(row));
- memcpy(nr->path, path, len(path));
- nr->numTags = 0;
- nr->lenTags = 0;
+ltable *newLtable(uint64_t size){
+ ltable *lt = malloc(sizeof(ltable));
+ size = (((uint64_t)size) < 0) ? 0 : size;
+ lt->size = size;
+ lt->table = malloc(size*sizeof(char*));
+ return lt;
+}
+
+ltable *loadLtable(FILE *fp){
+ char header;
+ fread(&header, sizeof(char), 1, fp);
+ if(header != 'L'){
+ printf("header is %c not L\n", header);
+ }
+ uint64_t size;
+ fread(&size, sizeof(uint64_t), 1, fp);
+ ltable *lt = newLtable(size);
+ for(uint64_t i = 0; i < lt->size; ++i){
+ uint32_t sl;
+ fread(&sl, sizeof(uint32_t), 1, fp);
+ lt->table[i] = malloc(sl*sizeof(char));
+ fread(lt->table[i], sizeof(char), sl, fp);
+ }
+ char end;
+ fread(&end, sizeof(char), 1, fp);
+ if(end != 'E'){
+ printf("end is %c not E\n", end);
+ }
+ return lt;
+}
+
+int storeLtable(const ltable *lt, FILE *fp){
+ char header = 'L';
+ fwrite(&header, sizeof(char), 1, fp);
+ fwrite(&lt->size, sizeof(uint64_t), 1, fp);
+ for(uint64_t i = 0; i < lt->size; ++i){
+ uint32_t l = len(lt->table[i]) + 1;
+ fwrite(&l, sizeof(uint32_t), 1, fp);
+ fwrite(lt->table[i], sizeof(char), l, fp);
+ }
+ char end = 'E';
+ fwrite(&end, sizeof(char), 1, fp);
+ return 0;
+}
+
+int ltableAdd(ltable *lt, char *str){
+ uint32_t ls;
+ str = normalizeStrLimit(str, &ls, MAXPATH-1);
+
+ char **nlt = malloc((lt->size+1)*sizeof(char*));
+ for(uint64_t i = 0; i < lt->size; ++i){
+ if(sameStr(str, lt->table[i])){
+ return -1;
+ }
+ uint32_t l = len(lt->table[i]);
+ nlt[i] = malloc((l+1)*sizeof(char));
+ memcpy(nlt[i], lt->table[i], l+1);
+ }
+ nlt[lt->size] = malloc((ls+1)*sizeof(char));
+ memcpy(nlt[lt->size], str, ls+1);
+
+ lt->size++;
+ lt->table = malloc(lt->size*sizeof(char*));
+ for(uint64_t i = 0; i < lt->size; ++i){
+ uint32_t l = len(nlt[i]);
+ lt->table[i] = malloc((l+1)*sizeof(char));
+ memcpy(lt->table[i], nlt[i], l+1);
+ }
+ return 0;
+}
+
+uint64_t ltableSearch(ltable *lt, char *str){
+ uint32_t l;
+ str = normalizeStrLimit(str, &l, MAXPATH-1);
+
+ for(uint64_t i = 0; i < lt->size; ++i){
+ if(sameStr(str, lt->table[i])){
+ return i;
+ }
+ }
+ return -1;
+}
+
+htable *newHtable(uint64_t size){
+ htable *ht = malloc(sizeof(htable));
+ size = (((uint64_t)size) < 0) ? 0 : size;
+ ht->size = size;
+ ht->table = malloc(size*sizeof(uint64_t));
+ return ht;
+}
+
+htable *loadHtable(FILE *fp){
+ char header;
+ fread(&header, sizeof(char), 1, fp);
+ if(header != 'H'){
+ printf("header is %c not H\n", header);
+ }
+ uint64_t size;
+ fread(&size, sizeof(uint64_t), 1, fp);
+ htable *ht = newHtable(size);
+ for(uint64_t i = 0; i < ht->size; ++i){
+ fread(&ht->table[i], sizeof(uint64_t), 1, fp);
+ }
+ char end;
+ fread(&end, sizeof(char), 1, fp);
+ if(end != 'E'){
+ printf("end is %c not E\n", end);
+ }
+ return ht;
+}
+
+int storeHtable(const htable *ht, FILE *fp){
+ char header = 'H';
+ fwrite(&header, sizeof(char), 1, fp);
+ fwrite(&ht->size, sizeof(uint64_t), 1, fp);
+ for(uint64_t i = 0; i < ht->size; ++i){
+ fwrite(&ht->table[i], sizeof(uint64_t), 1, fp);
+ }
+ char end = 'E';
+ fwrite(&end, sizeof(char), 1, fp);
+ return 0;
+}
+
+int htableAdd(htable *ht, uint64_t h){
+ uint64_t *nht = malloc((ht->size+1)*sizeof(uint64_t));
+ for(uint64_t i = 0; i < ht->size; ++i){
+ if(h == ht->table[i]){
+ return -1;
+ }
+ nht[i] = ht->table[i];
+ }
+ nht[ht->size] = h;
+
+ ht->size++;
+ ht->table = malloc(ht->size*sizeof(uint64_t));
+ for(uint64_t i = 0; i < ht->size; ++i){
+ ht->table[i] = nht[i];
+ }
+ return 0;
+}
+
+uint64_t htableSearch(htable *ht, uint64_t h){
+ for(uint64_t i = 0; i < ht->size; ++i){
+ if(h == ht->table[i]){
+ return i;
+ }
+ }
+ return -1;
+}
+
+mtable *newMtable(uint64_t size){
+ mtable *mt = malloc(sizeof(mtable));
+ size = (((uint64_t)size) < 0) ? 0 : size;
+ mt->size = size;
+ mt->table = malloc(size*sizeof(relation));
+ return mt;
+}
+
+mtable *loadMtable(FILE *fp){
+ char header;
+ fread(&header, sizeof(char), 1, fp);
+ if(header != 'M'){
+ printf("header is %c not M\n", header);
+ }
+ uint64_t size;
+ fread(&size, sizeof(uint64_t), 1, fp);
+ mtable *mt = newMtable(size);
+ for(uint64_t i = 0; i < mt->size; ++i){
+ fread(&mt->table[i].file, sizeof(uint64_t), 1, fp);
+ fread(&mt->table[i].tag, sizeof(uint64_t), 1, fp);
+ }
+ char end;
+ fread(&end, sizeof(char), 1, fp);
+ if(end != 'E'){
+ printf("end is %c not E\n", end);
+ }
+ return mt;
+}
- return nr;
+int storeMtable(const mtable *mt, FILE *fp){
+ char header = 'M';
+ fwrite(&header, sizeof(char), 1, fp);
+ fwrite(&mt->size, sizeof(uint64_t), 1, fp);
+ for(uint64_t i = 0; i < mt->size; ++i){
+ fwrite(&mt->table[i].file, sizeof(uint64_t), 1, fp);
+ fwrite(&mt->table[i].tag, sizeof(uint64_t), 1, fp);
+ }
+ char end = 'E';
+ fwrite(&end, sizeof(char), 1, fp);
+ return 0;
}
+int mtableAdd(mtable *mt, relation r){
+ relation *nmt = malloc((mt->size+1)*sizeof(relation));
+ for(uint64_t i = 0; i < mt->size; ++i){
+ if(r.file == mt->table[i].file && r.tag == mt->table[i].tag){
+ return -1;
+ }
+ nmt[i] = mt->table[i];
+ }
+ nmt[mt->size] = r;
+
+ mt->size++;
+ mt->table = malloc(mt->size*sizeof(relation));
+ for(uint64_t i = 0; i < mt->size; ++i){
+ mt->table[i] = nmt[i];
+ }
+ return 0;
+}
+
+uint64_t mtableSearch(mtable *mt, relation r){
+ for(uint64_t i = 0; i < mt->size; ++i){
+ if(r.file == mt->table[i].file && r.tag == mt->table[i].tag){
+ return i;
+ }
+ }
+ return -1;
+}
+
+
+
+
+/*
+// TODO: remove old impl
+
// Splits src into words based on a separator character (sep) and stores them in arr,
// and the length in len. Inspired by https://github.com/joshdk/tag/blob/master/src/dsv.c's split
-static void split(const char *src, char sep, char ***arr, uint16_t *len){
+static void split(const char *src, char sep, char ***arr, uint32_t *len){
int slen = 0, ai = 0, wnum = 0, wlen = 0;
while(src[slen] != '\0'){
@@ -48,26 +264,12 @@ static void swapWords(char ***arr, int a, int b){
(*arr)[b] = tmp;
}
-static char *normalizeTag(char *tag, uint16_t *ln){
- uint16_t l = len(tag);
- char *ntag = calloc(l+1, sizeof(char));
- for(int i = 0; i < l; ++i){
- ntag[i] = tolower(tag[i]);
- if(i == l-1 && tag[i] == ' '){
- ntag[i] = '\0';
- --l;
- }
- }
- *ln = l;
- return ntag;
-}
-
// Adds a tag in the tags array in the row r, sorted by natural string
// comparison with strnatcmp. We assume that when adding a tag all other
// tags are already sorted. Nothing is done if the tag is already in the tags
void insertTag(row *r, char *tag){
- uint16_t l, ltag;
- tag = normalizeTag(tag, &ltag);
+ uint32_t l, ltag;
+ tag = normalizeStr(tag, &ltag);
if(ltag == 0){
return;
@@ -130,8 +332,8 @@ void insertTag(row *r, char *tag){
// Remove a tag from the tags array in the row r
// Nothing is done if the tag isnt in the tags
void removeTag(row *r, char *tag){
- uint16_t l, ltag;
- tag = normalizeTag(tag, &ltag);
+ uint32_t l, ltag;
+ tag = normalizeStr(tag, &ltag);
if(ltag == 0){
return;
@@ -166,4 +368,5 @@ void removeTag(row *r, char *tag){
r->tags[tagnum] = '\0';
r->numTags = l;
r->lenTags = tagnum;
-} \ No newline at end of file
+}
+*/