aboutsummaryrefslogtreecommitdiff
path: root/src/database.c
diff options
context:
space:
mode:
authorSoikk2022-08-07 15:41:19 +0200
committerSoikk2022-08-07 15:41:19 +0200
commit5dd0d7700fa98197cdadaa2369d789e092cc0f49 (patch)
tree99d2dd331eb4c887b7895c893b803e34a9c10a77 /src/database.c
parentf9a7d9cd8a7e603c89d4cc5d98d7f694cc217d85 (diff)
downloadsoikk-DB-5dd0d7700fa98197cdadaa2369d789e092cc0f49.tar.xz
soikk-DB-5dd0d7700fa98197cdadaa2369d789e092cc0f49.tar.zst
Added removing things from db. Ref counts update when removing things. Added changelog.
Diffstat (limited to 'src/database.c')
-rw-r--r--src/database.c148
1 files changed, 96 insertions, 52 deletions
diff --git a/src/database.c b/src/database.c
index a6a9dfa..5b6249b 100644
--- a/src/database.c
+++ b/src/database.c
@@ -14,60 +14,14 @@ database *newDatabase(char *name){
return db;
}
-database *loadDatabase(const char* path){
- FILE *fp = fopen(path, "rb");
- char *header = calloc(2, sizeof(char));
- fread(header, sizeof(char), 2, fp);
- if(!sameStr(header, "DB")){
- fprintf(stderr, "Header is '%s' not 'DB'\n", header);
- }
-
- char name[32];
- fread(&name, sizeof(char), 32, fp);
- database *db = newDatabase(name);
- db->lfiles = loadLtable(fp);
- db->ltags = loadLtable(fp);
- db->cfiles = loadCtable(fp);
- db->ctags = loadCtable(fp);
- db->hfiles = loadAVLTree(fp);
- db->htags = loadAVLTree(fp);
- db->map = loadMtable(fp);
-
- char *end = calloc(3, sizeof(char));
- fread(end, sizeof(char), 3, fp);
- if(!sameStr(end, "END")){
- fprintf(stderr, "End is '%s' not 'END'\n", end);
- }
- fclose(fp);
- return db;
-}
-
-int storeDatabase(database *db, const char *path){
- FILE *fp = fopen(path, "wb");
-
- char header[2] = "DB";
- fwrite(header, sizeof(char), 2, fp);
- fwrite(db->name, sizeof(char), 32, fp);
-
- storeLtable(db->lfiles, fp);
- storeLtable(db->ltags, fp);
- storeCtable(db->cfiles, fp);
- storeCtable(db->ctags, fp);
- storeAVLTree(db->hfiles, fp);
- storeAVLTree(db->htags, fp);
- storeMtable(db->map, fp);
-
- char end[3] = "END";
- fwrite(end, sizeof(char), 3, fp);
-
- fclose(fp);
- return 0;
-}
-
static void increaseCount(ctable *ct, uint64_t i){
ct->table[i]++;
}
+static void decreaseCount(ctable *ct, uint64_t i){
+ ct->table[i]--;
+}
+
uint64_t addFile(database *db, char *file){
uint32_t l;
file = normalizeStrLimit(file, &l, MAXPATH-1);
@@ -131,6 +85,46 @@ int addFileTags(database *db, char *file, int ntags, ...){
return 0;
}
+int removeFile(database *db, char *file){
+ uint32_t l;
+ file = normalizeStrLimit(file, &l, MAXPATH-1);
+ uint64_t i = ltableSearch(db->lfiles, file);
+ if(i == -1){
+ return -1;
+ }
+ uint64_t *r, rl;
+ searchFile(db, file, 0, &r, &rl);
+ for(uint64_t j = 0; j < rl; ++j){
+ decreaseCount(db->ctags, r[j]);
+ }
+ uint64_t h = crc64(0, file, l);
+ ltableRemove(db->lfiles, file);
+ ctableRemove(db->cfiles, i);
+ deleteNode(db->hfiles, h);
+ mtableRemoveFile(db->map, i);
+ return 0;
+}
+
+int removeTag(database *db, char *tag){
+ uint32_t l;
+ tag = normalizeStrLimit(tag, &l, MAXPATH-1);
+ uint64_t i = ltableSearch(db->ltags, tag);
+ if(i == -1){
+ return -1;
+ }
+ uint64_t *r, rl;
+ searchTag(db, tag, 0, &r, &rl);
+ for(uint64_t j = 0; j < rl; ++j){
+ decreaseCount(db->cfiles, r[j]);
+ }
+ uint64_t h = crc64(0, tag, l);
+ ltableRemove(db->ltags, tag);
+ ctableRemove(db->ctags, i);
+ deleteNode(db->htags, h);
+ mtableRemoveTag(db->map, i);
+ return 0;
+}
+
// Stores in r a list with the indexes of the first n tags that this file has
// If n is 0 or lower, it returns all of them. Stores in rl the length of r
int searchFile(database *db, char *file, uint64_t n, uint64_t **r, uint64_t *rl){
@@ -191,6 +185,56 @@ int searchTag(database *db, char *tag, uint64_t n, uint64_t **r, uint64_t *rl){
return 0;
}
+int storeDatabase(database *db, const char *path){
+ FILE *fp = fopen(path, "wb");
+
+ char header[2] = "DB";
+ fwrite(header, sizeof(char), 2, fp);
+ fwrite(db->name, sizeof(char), 32, fp);
+
+ storeLtable(db->lfiles, fp);
+ storeLtable(db->ltags, fp);
+ storeCtable(db->cfiles, fp);
+ storeCtable(db->ctags, fp);
+ storeAVLTree(db->hfiles, fp);
+ storeAVLTree(db->htags, fp);
+ storeMtable(db->map, fp);
+
+ char end[3] = "END";
+ fwrite(end, sizeof(char), 3, fp);
+
+ fclose(fp);
+ return 0;
+}
+
+database *loadDatabase(const char* path){
+ FILE *fp = fopen(path, "rb");
+ char *header = calloc(2, sizeof(char));
+ fread(header, sizeof(char), 2, fp);
+ if(!sameStr(header, "DB")){
+ fprintf(stderr, "Header is '%s' not 'DB'\n", header);
+ }
+
+ char name[32];
+ fread(&name, sizeof(char), 32, fp);
+ database *db = newDatabase(name);
+ db->lfiles = loadLtable(fp);
+ db->ltags = loadLtable(fp);
+ db->cfiles = loadCtable(fp);
+ db->ctags = loadCtable(fp);
+ db->hfiles = loadAVLTree(fp);
+ db->htags = loadAVLTree(fp);
+ db->map = loadMtable(fp);
+
+ char *end = calloc(3, sizeof(char));
+ fread(end, sizeof(char), 3, fp);
+ if(!sameStr(end, "END")){
+ fprintf(stderr, "End is '%s' not 'END'\n", end);
+ }
+ fclose(fp);
+ return db;
+}
+
void printDatabase(database *db){
for(uint64_t i = 0; i < db->map->size; ++i){
printf("%s -> %s\n", db->lfiles->table[db->map->table[i].file], db->ltags->table[db->map->table[i].tag]);
@@ -217,9 +261,9 @@ void debugDatabase(database *db){
for(uint64_t i = 0; i < db->ltags->size; ++i){
printf("\t\t+%s (%" PRIu64 ")\n", db->ltags->table[i], db->ctags->table[i]);
}
- printf("\t-hfiles: %d\n", height(db->hfiles));
+ printf("\t-hfiles: %d\n", db->lfiles->size);
debugAVLtree(db->hfiles);
- printf("\t-htags: %d\n", height(db->htags));
+ printf("\t-htags: %d\n", db->ltags->size);
debugAVLtree(db->htags);
printf("\t-map: %d\n", db->map->size);
for(uint64_t i = 0; i < db->map->size; ++i){