aboutsummaryrefslogtreecommitdiff
path: root/src/database.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/database.c')
-rw-r--r--src/database.c138
1 files changed, 88 insertions, 50 deletions
diff --git a/src/database.c b/src/database.c
index 5b6249b..f930539 100644
--- a/src/database.c
+++ b/src/database.c
@@ -14,28 +14,17 @@ database *newDatabase(char *name){
return db;
}
-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);
uint64_t h = crc64(0, file, l);
- uint64_t i = nodeSearch(db->hfiles, h);
-
+ uint64_t i = searchNode(db->hfiles, h);
if(i == -1){
- ltableAdd(db->lfiles, file);
- ctableAdd(db->cfiles, 0);
+ insertLtable(db->lfiles, file);
+ insertCtable(db->cfiles, 0);
i = db->lfiles->size-1;
db->hfiles = insertNode(db->hfiles, h, i);
}
- increaseCount(db->cfiles, i);
-
return i;
}
@@ -43,34 +32,42 @@ uint64_t addTag(database *db, char *tag){
uint32_t l;
tag = normalizeStrLimit(tag, &l, MAXPATH-1);
uint64_t h = crc64(0, tag, l);
- uint64_t i = nodeSearch(db->htags, h);
-
+ uint64_t i = searchNode(db->htags, h);
if(i == -1){
- ltableAdd(db->ltags, tag);
- ctableAdd(db->ctags, 0);
+ insertLtable(db->ltags, tag);
+ insertCtable(db->ctags, 0);
i = db->ltags->size-1;
db->htags = insertNode(db->htags, h, i);
}
- increaseCount(db->ctags, i);
-
return i;
}
+static void increaseCount(ctable *ct, uint64_t i){
+ ct->table[i]++;
+}
+
+static void decreaseCount(ctable *ct, uint64_t i){
+ ct->table[i]--;
+}
+
static int addRelation(database *db, relation r){
- if(mtableSearch(db->map, r) != -1){
- return -1;
+ if(searchMtable(db->map, r) == UINTMAX_MAX){
+ insertMtable(db->map, r);
+ return 0;
}
- mtableAdd(db->map, r);
-
- return 0;
+ return -1;
}
int addFileTag(database *db, char *file, char *tag){
uint64_t fi = addFile(db, file), ti = addTag(db, tag);
- addRelation(db, (relation){.file = fi, .tag = ti});
-
- return 0;
+ int r = addRelation(db, (relation){.file = fi, .tag = ti});
+ if(r == 0){
+ increaseCount(db->cfiles, fi);
+ increaseCount(db->ctags, ti);
+ return 0;
+ }
+ return -1;
}
int addFileTags(database *db, char *file, int ntags, ...){
@@ -81,14 +78,56 @@ int addFileTags(database *db, char *file, int ntags, ...){
addFileTag(db, file, tag);
}
va_end(tags);
+ return 0;
+}
+int addTagFiles(database *db, char *tag, int nfiles, ...){
+ va_list files;
+ va_start(files, nfiles);
+ for(uint64_t i = 0; i < nfiles; ++i){
+ char *file = va_arg(files, char*);
+ addFileTag(db, file, tag);
+ }
+ va_end(files);
return 0;
}
+// When removing the file from the ltable and ctable we change the indexes of the tags in front
+// of it. Thus, we must change their indexes on the avl tree and mapping table. To do this we
+// simply get all tags with an index higher than the tag we removed and substract one from it,
+// since when removing a tag from the tables all we did was shift down all the tags in front of
+// it one position
+static void decreaseHigherIndexNode(node *n, uint64_t i){
+ if(n == NULL){
+ return;
+ }
+ if(n->i > i){
+ n->i--;
+ }
+ decreaseHigherIndexNode(n->left, i);
+ decreaseHigherIndexNode(n->right, i);
+}
+
+static void decreaseHigherFileIndexMap(mtable *mt, uint64_t i){
+ for(uint64_t j = 0; j < mt->size; ++j){
+ if(mt->table[j].file > i){
+ mt->table[j].file--;
+ }
+ }
+}
+
+static void decreaseHigherTagIndexMap(mtable *mt, uint64_t i){
+ for(uint64_t j = 0; j < mt->size; ++j){
+ if(mt->table[j].tag > i){
+ mt->table[j].tag--;
+ }
+ }
+}
+
int removeFile(database *db, char *file){
uint32_t l;
file = normalizeStrLimit(file, &l, MAXPATH-1);
- uint64_t i = ltableSearch(db->lfiles, file);
+ uint64_t i = searchLtable(db->lfiles, file);
if(i == -1){
return -1;
}
@@ -98,17 +137,20 @@ int removeFile(database *db, char *file){
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);
+ removeLtable(db->lfiles, file);
+ removeCtable(db->cfiles, i);
+ removeNode(db->hfiles, h);
+ removeFileMtable(db->map, i);
+
+ decreaseHigherIndexNode(db->hfiles, i);
+ decreaseHigherFileIndexMap(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);
+ uint64_t i = searchLtable(db->ltags, tag);
if(i == -1){
return -1;
}
@@ -118,20 +160,21 @@ int removeTag(database *db, char *tag){
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);
+ removeLtable(db->ltags, tag);
+ removeCtable(db->ctags, i);
+ removeNode(db->htags, h);
+ removeTagMtable(db->map, i);
+
+ decreaseHigherIndexNode(db->htags, i);
+ decreaseHigherTagIndexMap(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){
uint32_t l;
file = normalizeStrLimit(file, &l, MAXPATH-1);
uint64_t h = crc64(0, file, l);
- uint64_t fi = nodeSearch(db->hfiles, h);
+ uint64_t fi = searchNode(db->hfiles, h);
if(fi == -1){
return -1;
}
@@ -151,17 +194,14 @@ int searchFile(database *db, char *file, uint64_t n, uint64_t **r, uint64_t *rl)
(*r)[c++] = db->map->table[i].tag;
}
}
-
return 0;
}
-// Stores in r a list with the indexes of the first n files that have this tag
-// If n is 0 or lower, it returns all of them. Stores in rl the length of r
int searchTag(database *db, char *tag, uint64_t n, uint64_t **r, uint64_t *rl){
uint32_t l;
tag = normalizeStrLimit(tag, &l, MAXPATH-1);
uint64_t h = crc64(0, tag, l);
- uint64_t ti = nodeSearch(db->htags, h);
+ uint64_t ti = searchNode(db->htags, h);
if(ti == -1){
return -1;
}
@@ -181,7 +221,6 @@ int searchTag(database *db, char *tag, uint64_t n, uint64_t **r, uint64_t *rl){
(*r)[c++] = db->map->table[i].file;
}
}
-
return 0;
}
@@ -202,7 +241,6 @@ int storeDatabase(database *db, const char *path){
char end[3] = "END";
fwrite(end, sizeof(char), 3, fp);
-
fclose(fp);
return 0;
}
@@ -255,11 +293,11 @@ void debugDatabase(database *db){
printf("Name: %s\n", db->name);
printf("\t-lfiles: %d\n", db->lfiles->size);
for(uint64_t i = 0; i < db->lfiles->size; ++i){
- printf("\t\t+%s (%" PRIu64 ")\n", db->lfiles->table[i], db->cfiles->table[i]);
+ printf("\t\t+[%" PRIu64 "] %s (%" PRIu64 ")\n", i, db->lfiles->table[i], db->cfiles->table[i]);
}
printf("\t-ltags: %d\n", db->ltags->size);
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\t+[%" PRIu64 "] %s (%" PRIu64 ")\n", i, db->ltags->table[i], db->ctags->table[i]);
}
printf("\t-hfiles: %d\n", db->lfiles->size);
debugAVLtree(db->hfiles);
@@ -267,7 +305,7 @@ void debugDatabase(database *db){
debugAVLtree(db->htags);
printf("\t-map: %d\n", db->map->size);
for(uint64_t i = 0; i < db->map->size; ++i){
- printf("\t\t+%" PRIu64 ":%" PRIu64 "\n", db->map->table[i].file, db->map->table[i].tag);
+ printf("\t\t+[%" PRIu64 "] %" PRIu64 ":%" PRIu64 "\n", i, db->map->table[i].file, db->map->table[i].tag);
}
printf("\n");
}