diff --git a/src/database.c b/src/database.c index a7576f9..80e0a05 100644 --- a/src/database.c +++ b/src/database.c @@ -16,6 +16,7 @@ #include "common.h" #include "database.h" +#include "bitmap.h" #define DB_SEEK(db, offset) \ errno = 0; \ @@ -180,3 +181,65 @@ int db_wr_list(db_t *db, rec_t *list, size_t list_len) return processed; } + +int db_search(db_t *db, rec_t *sample, float tresh, match_t **matches) +{ + const int blk_size = 4096; + uint64_t found = 0; + block_t blk; + unsigned int i = 0; + unsigned char *p = NULL, *t = NULL; + float diff = 0.0; + + assert(db != NULL); + assert(sample != NULL); + assert(matches != NULL); + + memset(&blk, 0x0, sizeof(block_t)); + blk.start = 1; + blk.records = blk_size; + + if (db_rd_rec(db, sample) < 1) { + db->errstr = "Can't read source sample"; + return -1; + } + + if (!sample->data[0]) { + db->errstr = "Source sample not exists"; + return -1; + } + + *matches = NULL; + while (db_rd_blk(db, &blk) > 0) { + p = blk.data; + for (i = 0; i < blk.records; i++, p += REC_LEN) { + t = p + OFF_USED; + if (*t == 0x0) continue; + + t = p + OFF_BITMAP; + diff = (float) bitmap_compare(t, sample->data + OFF_BITMAP); + diff /= BITMAP_BITS; + if (diff > tresh) continue; + + /* allocate more memory, if needed */ + if (found % 10 == 0) { + *matches = realloc(*matches, (found + 10) * sizeof(match_t)); + if (*matches == NULL) { + db->errstr = "Memory allocation error"; + FREE(blk.data); + return -1; + } + memset(&(*matches)[found], 0x0, sizeof(match_t) * 10); + } + + /* create match record */ + (*matches)[found].num = blk.start + i; + (*matches)[found].diff = diff; + found++; + } + FREE(blk.data); + blk.start += blk_size; + } + + return found; +} diff --git a/src/database.h b/src/database.h index 58368c2..8352b61 100644 --- a/src/database.h +++ b/src/database.h @@ -55,5 +55,13 @@ extern int db_wr_blk(db_t *db, block_t *blk); extern int db_rd_list(db_t *db, rec_t *list, size_t list_len); extern int db_wr_list(db_t *db, rec_t *list, size_t list_len); +/** + @returns: + -1 on error + 0 if nothing found + >0 if found some matches + */ +extern int db_search(db_t *db, rec_t *sample, float tresh, match_t **matches); + #endif #define HAS_DATABASE_H 1