aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSoikk2022-07-24 22:18:31 +0200
committerSoikk2022-07-24 22:18:31 +0200
commitff5da06da823ac3a0bc7e89b35ed573255139b2d (patch)
tree41551fe546a34ad8f771b5a75eb4d883db5fb4ac /src
parentcaacd02d3c6a6ab3ddea620214ee5d1836de2c31 (diff)
downloadsoikk-DB-ff5da06da823ac3a0bc7e89b35ed573255139b2d.tar.xz
soikk-DB-ff5da06da823ac3a0bc7e89b35ed573255139b2d.tar.zst
Added ref count for files & tags. Refactored database.c. Removed tags.h but kept documentation.
Diffstat (limited to 'src')
-rw-r--r--src/bm.c2
-rw-r--r--src/database.c152
-rw-r--r--src/main.c22
3 files changed, 112 insertions, 64 deletions
diff --git a/src/bm.c b/src/bm.c
index d94765e..d2afb0a 100644
--- a/src/bm.c
+++ b/src/bm.c
@@ -41,4 +41,4 @@ ssize_t BM(char *x, int m, char *y, int n){
j += shift; /* shift */
}
return -1;
-} \ No newline at end of file
+}
diff --git a/src/database.c b/src/database.c
index db7759e..f034464 100644
--- a/src/database.c
+++ b/src/database.c
@@ -8,6 +8,8 @@ database *newDatabase(char *name){
db->ltags = newLtable(0);
db->hfiles = newHtable(0);
db->htags = newHtable(0);
+ db->fcount = newHtable(0);
+ db->tcount = newHtable(0);
db->map = newMtable(0);
return db;
}
@@ -19,6 +21,7 @@ database *loadDatabase(const char* path){
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);
@@ -26,9 +29,12 @@ database *loadDatabase(const char* path){
db->ltags = loadLtable(fp);
db->hfiles = loadHtable(fp);
db->htags = loadHtable(fp);
+ db->fcount = loadHtable(fp);
+ db->tcount = loadHtable(fp);
db->map = loadMtable(fp);
- char end[4];
- fread(&end, sizeof(char), 3, 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);
}
@@ -47,6 +53,8 @@ int storeDatabase(database *db, const char *path){
storeLtable(db->ltags, fp);
storeHtable(db->hfiles, fp);
storeHtable(db->htags, fp);
+ storeHtable(db->fcount, fp);
+ storeHtable(db->tcount, fp);
storeMtable(db->map, fp);
char end[3] = "END";
@@ -56,6 +64,44 @@ int storeDatabase(database *db, const char *path){
return 0;
}
+static void increaseCount(htable *ht, uint64_t i){
+ ht->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 = htableSearch(db->hfiles, h);
+
+ if(i == -1){
+ ltableAdd(db->lfiles, file);
+ htableAdd(db->hfiles, h);
+ htableAdd(db->fcount, 0);
+ i = db->hfiles->size-1;
+ }
+ increaseCount(db->fcount, i);
+
+ return i;
+}
+
+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 = htableSearch(db->htags, h);
+
+ if(i == -1){
+ ltableAdd(db->ltags, tag);
+ htableAdd(db->htags, h);
+ htableAdd(db->tcount, 0);
+ i = db->htags->size-1;
+ }
+ increaseCount(db->tcount, i);
+
+ return i;
+}
+
static int addRelation(database *db, relation r){
if(mtableSearch(db->map, r) != -1){
return -1;
@@ -66,83 +112,81 @@ static int addRelation(database *db, relation r){
}
int addFileTag(database *db, char *file, char *tag){
- uint32_t lf, lt;
- file = normalizeStrLimit(file, &lf, MAXPATH-1);
- tag = normalizeStrLimit(tag, &lt, MAXPATH-1);
- uint64_t hf = crc64(0, file, lf), ht = crc64(0, tag, lt);
- uint64_t fi = htableSearch(db->hfiles, hf), ti = htableSearch(db->htags, ht);
-
- if(fi == -1){
- ltableAdd(db->lfiles, file);
- htableAdd(db->hfiles, hf);
- fi = db->hfiles->size-1;
- }
- if(ti == -1){
- ltableAdd(db->ltags, tag);
- htableAdd(db->htags, ht);
- ti = db->htags->size-1;
- }
-
+ uint64_t fi = addFile(db, file), ti = addTag(db, tag);
addRelation(db, (relation){.file = fi, .tag = ti});
+
return 0;
}
int addFileTags(database *db, char *file, int ntags, ...){
- uint32_t lf;
- file = normalizeStrLimit(file, &lf, MAXPATH-1);
- uint64_t hf = crc64(0, file, lf);
- uint64_t fi = htableSearch(db->hfiles, hf);
-
- if(fi == -1){
- ltableAdd(db->lfiles, file);
- htableAdd(db->hfiles, hf);
- fi = db->hfiles->size-1;
- }
-
va_list tags;
va_start(tags, ntags);
for(uint64_t i = 0; i < ntags; ++i){
char *tag = va_arg(tags, char*);
- uint32_t lt;
- tag = normalizeStrLimit(tag, &lt, MAXPATH-1);
- uint64_t ht = crc64(0, tag, lt);
- uint64_t ti = htableSearch(db->htags, ht);
-
- if(ti == -1){
- ltableAdd(db->ltags, tag);
- htableAdd(db->htags, ht);
- ti = db->htags->size-1;
- }
-
- addRelation(db, (relation){.file = fi, .tag = ti});
+ addFileTag(db, file, tag);
}
va_end(tags);
return 0;
}
-// Should return a list with the indexes of the files that have this tag
-int searchTag(database *db, char *tag, uint64_t *rl){
+// 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 = htableSearch(db->htags, h);
- // TODO: error checking
+ if(ti == -1){
+ return -1;
+ }
- uint64_t c = 0;
+ *rl = 0;
for(uint64_t i = 0; i < db->map->size; ++i){
+ if(n < 1 || *rl < n){
+ if(db->map->table[i].tag == ti){
+ ++(*rl);
+ }
+ }
+ }
+ *r = malloc((*rl)*sizeof(uint64_t));
+ uint64_t c = 0;
+ for(uint64_t i = 0; i < db->map->size && c < *rl; ++i){
if(db->map->table[i].tag == ti){
- ++c;
+ (*r)[c++] = db->map->table[i].file;
}
}
- uint64_t *r = malloc(c*sizeof(uint64_t));
- c = 0;
+
+ 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 = htableSearch(db->hfiles, h);
+ if(fi == -1){
+ return -1;
+ }
+
+ *rl = 0;
for(uint64_t i = 0; i < db->map->size; ++i){
- if(db->map->table[i].tag == ti){
- r[c++] = db->map->table[i].file;
+ if(n < 1 || *rl < n){
+ if(db->map->table[i].file == fi){
+ ++(*rl);
+ }
}
}
- rl = r;
+ *r = malloc((*rl)*sizeof(uint64_t));
+ uint64_t c = 0;
+ for(uint64_t i = 0; i < db->map->size && c < *rl; ++i){
+ if(db->map->table[i].file == fi){
+ (*r)[c++] = db->map->table[i].tag;
+ }
+ }
+
return 0;
}
@@ -158,11 +202,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\n", db->lfiles->table[i]);
+ printf("\t\t+%s (%" PRIu64 ")\n", db->lfiles->table[i], db->fcount->table[i]);
}
printf("\t-ltags: %d\n", db->ltags->size);
for(uint64_t i = 0; i < db->ltags->size; ++i){
- printf("\t\t+%s\n", db->ltags->table[i]);
+ printf("\t\t+%s (%" PRIu64 ")\n", db->ltags->table[i], db->tcount->table[i]);
}
printf("\t-hfiles: %d\n", db->hfiles->size);
for(uint64_t i = 0; i < db->hfiles->size; ++i){
diff --git a/src/main.c b/src/main.c
index 01fdad2..bd5c6b9 100644
--- a/src/main.c
+++ b/src/main.c
@@ -4,26 +4,30 @@
int main(){
- printf("%016llu\n", (uint64_t) crc64(0, (unsigned char*)"cacadevaca", 10));
-
+ database *db = newDatabase("miDB");
inputBuffer *in = newInputBuffer();
- char *str = "grandmother;football;capital;concerned;entire;realize;garden;refused;proud;tune;rhyme;other;writer;command;fresh;fence;rapidly;active;cover;repeat;determine;yard;cannot;animal;pure;rich;mirror;frozen;vast;coach;brass;activity;bottom;airplane;local;tone;attack;though;between;value;collect;mission;tower;brought;original;history;reason;minute;would;hung;strange;children;offer;blue;wrapped;magnet;color;cage;easily;percent;lower;verb;hundred;larger;away;was;certain;western;yes;lack;wish;same;spend;arrive;fog;heard;bill;effort;steam;wolf;indicate;suppose;because;life;down;seat;age;earn;under;cell;floating;although;spent;folks;swing;hello;cent;swung;pen;happened;slip;pupil;smell;fix;piano;closer;idea;trunk;model;school;particularly;he;coast;describe;such;join;been;hard;three;around;tube;soldier;baby;mouse;note;sort;house;gasoline;organized;eat;sat;crowd;alive;spoken;wide;square;luck;tales;angry;having;wear;frog;outer;nice;regular;year;clothing;check;throughout;farmer;dug;dark;exercise;table;your;form;should;personal;use;road;bright;walk;fairly;affect;but;night;close;job;front;fight;beside;ocean;herd;pass;hardly;widely;prepare;nails;paid;lucky;design;grandfather;aid;heavy;truck;sleep;difficult;log;keep;government;headed;mother;sad;bread;voyage;when;happy;making;whistle;plural;guard;therefore;continent;roof;money;pan;unusual;region;special;generally;plate;visit;look;lost;sick;wonderful;farther;put;characteristic;gravity;trap;system;twice;taste;knew;mad;smallest;automobile;return;huge;underline;danger;news;electric;information;breeze;thread;equally;five;new;average;former;wild;spend;cabin;recognize;nearest;circle;such;found;pass;whistle;slave;event;knowledge;fear;friend;am;browserling;cry;length;thy;create;busy;office;earth;blind;smallest;birthday;putting;classroom;pen;southern;summer;put;open;solution;spread;equator;else;kitchen;determine;strong;change;world;pocket;claws;earn;excellent;drove;donkey;rush;band;energy;fighting;hurt;ordinary;native;visitor;give;storm;pressure;imagine;street;engine;worth;hospital;attached;subject;perhaps;hospital;living;waste;dark;natural;change;enter;girl;motor;element;experiment;physical;value;excited;fort;layers;buy;minerals;satisfied;next;spirit;unhappy;storm;angry;science;desk;develop;behind;afraid;act;else;prepare;given;raw;affect;husband;ring;older;brought;book;cow;lake;sides;ago;fill;successful;real;aside;taught;mind;straight;date;very;chart;slabs;thin;saddle;full;sort;heard;surprise;fox;cool;dish;alphabet;early;spring;nest;sometime;date;light;break;lion;difference;rhyme;might;step;teach;potatoes;young;nine;liquid;how;lunch;heavy;mass;being;save;cutting;negative;swimming;cutting;journey;army;none;worry;leave;explore;baseball;fight;road;exact;hay;voyage;sheet;test;right;examine;agree;heart;pig;cannot;tool;hill;changing;bee;find;together;lay;tie;lost;continued;then;came;rhyme;mirror;town;substance;both;up;quite;push;shake;solid;result;you;ought;chicken;waste;freedom;why;somehow;not;complete;sick;struggle;military;pure;top;south;step;education;could;between;familiar;recognize;rich;tool;material;were;chicken;stopped;stay;policeman;round;firm";
-
-
- database *db = newDatabase("miDB");
addFileTag(db, "vaca.png", "naturaleza");
addFileTags(db, "donald-tromp.jpg", 3, "based", "hitler", "very cool");
+ addFileTag(db, "vaca.png", "lovely");
+ addFileTags(db, "vaca.png", 3, "nature", "kami", "very cool");
storeDatabase(db, "db.db");
-
- db = loadDatabase("db.db");
printDatabase(db);
debugDatabase(db);
-
+
+ uint64_t *l, i;
+ searchFile(db, "donald-tromp.jpg", 0, &l, &i);
+
+ printf("Tags with tag 'donald-tromp.jpg':\n");
+ for(uint64_t j = 0; j < i; ++j){
+ printf("\t%s\n", db->ltags->table[l[j]]);
+
+ }
+
while(0){