From 5dd0d7700fa98197cdadaa2369d789e092cc0f49 Mon Sep 17 00:00:00 2001 From: Soikk Date: Sun, 7 Aug 2022 15:41:19 +0200 Subject: Added removing things from db. Ref counts update when removing things. Added changelog. --- src/database.c | 148 +++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 96 insertions(+), 52 deletions(-) (limited to 'src/database.c') 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){ -- cgit v1.2.3