diff --git a/src/fdb_tsdb.c b/src/fdb_tsdb.c index 1fb5ee5..5f4f9fb 100644 --- a/src/fdb_tsdb.c +++ b/src/fdb_tsdb.c @@ -125,41 +125,6 @@ static fdb_err_t read_tsl(fdb_tsdb_t db, fdb_tsl_t tsl) return FDB_NO_ERR; } -static uint32_t get_prev_sector_addr(fdb_tsdb_t db, tsdb_sec_info_t pre_sec, uint32_t traversed_len) -{ - /* check if we are not yet traversed along whole db */ - if (db_sec_size(db) + traversed_len <= db_max_size(db)) - { - if (pre_sec->addr >= db_sec_size(db)) - { - /* the next sector is previous sector */ - return pre_sec->addr - db_sec_size(db); - } else { - /* the next sector is the last sector */ - return db_max_size(db) - db_sec_size(db); - } - } else { - /* finished */ - return FAILED_ADDR; - } -} - -static uint32_t get_prev_tsl_addr(tsdb_sec_info_t sector, fdb_tsl_t pre_tsl) -{ - uint32_t addr = FAILED_ADDR; - - if (sector->status == FDB_SECTOR_STORE_EMPTY) { - return FAILED_ADDR; - } - if (pre_tsl->addr.index - LOG_IDX_DATA_SIZE >= sector->addr + SECTOR_HDR_DATA_SIZE) { - addr = pre_tsl->addr.index - LOG_IDX_DATA_SIZE; - } else { - /* no TSL */ - return FAILED_ADDR; - } - return addr; -} - static uint32_t get_next_sector_addr(fdb_tsdb_t db, tsdb_sec_info_t pre_sec, uint32_t traversed_len) { if (traversed_len + db_sec_size(db) <= db_max_size(db)) { @@ -193,6 +158,38 @@ static uint32_t get_next_tsl_addr(tsdb_sec_info_t sector, fdb_tsl_t pre_tsl) return addr; } +static uint32_t get_last_tsl_addr(tsdb_sec_info_t sector, fdb_tsl_t pre_tsl) +{ + uint32_t addr = FAILED_ADDR; + + if (sector->status == FDB_SECTOR_STORE_EMPTY) { + return FAILED_ADDR; + } + + if (pre_tsl->addr.index >= (sector->addr + SECTOR_HDR_DATA_SIZE + LOG_IDX_DATA_SIZE)) { + addr = pre_tsl->addr.index - LOG_IDX_DATA_SIZE; + } else { + return FAILED_ADDR; + } + + return addr; +} + +static uint32_t get_last_sector_addr(fdb_tsdb_t db, tsdb_sec_info_t pre_sec, uint32_t traversed_len) +{ + if (traversed_len + db_sec_size(db) <= db_max_size(db)) { + if (pre_sec->addr >= db_sec_size(db)) { + /* the next sector is previous sector */ + return pre_sec->addr - db_sec_size(db); + } else { + /* the next sector is the last sector */ + return db_max_size(db) - db_sec_size(db); + } + } else { + return FAILED_ADDR; + } +} + static fdb_err_t read_sector_info(fdb_tsdb_t db, uint32_t addr, tsdb_sec_info_t sector, bool traversal) { fdb_err_t result = FDB_NO_ERR; @@ -439,53 +436,6 @@ fdb_err_t fdb_tsl_append(fdb_tsdb_t db, fdb_blob_t blob) return result; } -/** - * The TSDB reverse iterator for each TSL. - * - * @param db database object - * @param cb callback - * @param arg callback argument - */ -void fdb_tsl_iter_reverse(fdb_tsdb_t db, fdb_tsl_cb cb, void *arg) -{ - struct tsdb_sec_info sector; - uint32_t sec_addr, traversed_len = 0; - struct fdb_tsl tsl; - - if (!db_init_ok(db)) { - FDB_INFO("Error: TSL (%s) isn't initialize OK.\n", db_name(db)); - } - - if (cb == NULL) { - return; - } - sec_addr = db->cur_sec.addr; - /* search all sectors */ - do { - traversed_len += db_sec_size(db); - if (read_sector_info(db, sec_addr, §or, false) != FDB_NO_ERR) { - continue; - } - /* sector has TSL */ - if (sector.status == FDB_SECTOR_STORE_USING || sector.status == FDB_SECTOR_STORE_FULL) { - if (sector.status == FDB_SECTOR_STORE_USING) { - /* copy the current using sector status */ - sector = db->cur_sec; - } - tsl.addr.index = sector.end_idx; - /* search all TSL */ - do { - read_tsl(db, &tsl); - /* iterator is interrupted when callback return true */ - if (cb(&tsl, arg)) { - return; - } - } while ((tsl.addr.index = get_prev_tsl_addr(§or, &tsl)) != FAILED_ADDR); - } else if (sector.status == FDB_SECTOR_STORE_EMPTY || sector.status == FDB_SECTOR_STORE_UNUSED) - return; - } while ((sec_addr = get_prev_sector_addr(db, §or, traversed_len)) != FAILED_ADDR); -} - /** * The TSDB iterator for each TSL. * @@ -534,22 +484,79 @@ void fdb_tsl_iter(fdb_tsdb_t db, fdb_tsl_cb cb, void *arg) } /** - * The TSDB iterator for each TSL addr. + * The TSDB iterator for each TSL. + * * @param db database object - * @param starting tsl addr of the current sector - * @param ending tsl addr of the current sector - * @param from starting timestap + * @param cb callback + * @param arg callback argument */ -static int search_tsl_addr(fdb_tsdb_t db,int start,int end,int from) - { +void fdb_tsl_iter_reverse(fdb_tsdb_t db, fdb_tsl_cb cb, void *cb_arg) +{ + struct tsdb_sec_info sector; + uint32_t sec_addr, traversed_len = 0; struct fdb_tsl tsl; - while (start <= end) { - tsl.addr.index = start + ((end - start) / 2 + 1) / LOG_IDX_DATA_SIZE * LOG_IDX_DATA_SIZE; + + if (!db_init_ok(db)) { + FDB_INFO("Error: TSL (%s) isn't initialize OK.\n", db_name(db)); + } + + if (cb == NULL) { + return; + } + + sec_addr = db->cur_sec.addr; + /* search all sectors */ + do { + traversed_len += db_sec_size(db); + if (read_sector_info(db, sec_addr, §or, false) != FDB_NO_ERR) { + continue; + } + /* sector has TSL */ + if (sector.status == FDB_SECTOR_STORE_USING || sector.status == FDB_SECTOR_STORE_FULL) { + if (sector.status == FDB_SECTOR_STORE_USING) { + /* copy the current using sector status */ + sector = db->cur_sec; + } + tsl.addr.index = sector.end_idx; + /* search all TSL */ + do { + read_tsl(db, &tsl); + /* iterator is interrupted when callback return true */ + if (cb(&tsl, cb_arg)) { + return; + } + } while ((tsl.addr.index = get_last_tsl_addr(§or, &tsl)) != FAILED_ADDR); + } else if (sector.status == FDB_SECTOR_STORE_EMPTY || sector.status == FDB_SECTOR_STORE_UNUSED) + return; + } while ((sec_addr = get_last_sector_addr(db, §or, traversed_len)) != FAILED_ADDR); +} + +/* + * Found the matched TSL address. + */ +static int search_start_tsl_addr(fdb_tsdb_t db, int start, int end, fdb_time_t from, fdb_time_t to) +{ + struct fdb_tsl tsl; + while (true) { + tsl.addr.index = start + FDB_ALIGN((end - start) / 2, LOG_IDX_DATA_SIZE); read_tsl(db, &tsl); if (tsl.time < from) { start = tsl.addr.index + LOG_IDX_DATA_SIZE; - } else { + } else if (tsl.time > from) { end = tsl.addr.index - LOG_IDX_DATA_SIZE; + } else { + return tsl.addr.index; + } + + if (start > end) { + if (from > to) { + tsl.addr.index = start; + read_tsl(db, &tsl); + if (tsl.time > from) { + start -= LOG_IDX_DATA_SIZE; + } + } + break; } } return start; @@ -567,25 +574,25 @@ static int search_tsl_addr(fdb_tsdb_t db,int start,int end,int from) void fdb_tsl_iter_by_time(fdb_tsdb_t db, fdb_time_t from, fdb_time_t to, fdb_tsl_cb cb, void *cb_arg) { struct tsdb_sec_info sector; - uint32_t sec_addr, oldest_addr, traversed_len = 0; + uint32_t sec_addr, start_addr, traversed_len = 0; struct fdb_tsl tsl; bool found_start_tsl = false; - uint32_t (*get_sector_addr)( fdb_tsdb_t, tsdb_sec_info_t, uint32_t); - uint32_t (*get_tsl_addr)( tsdb_sec_info_t, fdb_tsl_t); + uint32_t (*get_sector_addr)(fdb_tsdb_t , tsdb_sec_info_t , uint32_t); + uint32_t (*get_tsl_addr)(tsdb_sec_info_t , fdb_tsl_t); if (!db_init_ok(db)) { FDB_INFO("Error: TSL (%s) isn't initialize OK.\n", db_name(db)); } - if (from <= to) { - oldest_addr = db->oldest_addr; + if(from <= to) { + start_addr = db->oldest_addr; get_sector_addr = get_next_sector_addr; get_tsl_addr = get_next_tsl_addr; } else { - oldest_addr = db->cur_sec.addr; - get_sector_addr = get_prev_sector_addr; - get_tsl_addr = get_prev_tsl_addr; + start_addr = db->cur_sec.addr; + get_sector_addr = get_last_sector_addr; + get_tsl_addr = get_last_tsl_addr; } // FDB_INFO("from %s", ctime((const time_t * )&from)); @@ -595,7 +602,7 @@ void fdb_tsl_iter_by_time(fdb_tsdb_t db, fdb_time_t from, fdb_time_t to, fdb_tsl return; } - sec_addr = oldest_addr; + sec_addr = start_addr; /* search all sectors */ do { traversed_len += db_sec_size(db); @@ -609,16 +616,15 @@ void fdb_tsl_iter_by_time(fdb_tsdb_t db, fdb_time_t from, fdb_time_t to, fdb_tsl sector = db->cur_sec; } if ((found_start_tsl) - || (!found_start_tsl - && ((from >= sector.start_time && from <= sector.end_time) - || (from <= to && sec_addr == oldest_addr && from <= sector.start_time) - || (from > to && sec_addr == oldest_addr && from >= sector.end_time)))) { + || (!found_start_tsl && + ((from <= to && ((sec_addr == start_addr && from <= sector.start_time) || from <= sector.end_time)) || + (from > to && ((sec_addr == start_addr && from >= sector.end_time) || from >= sector.start_time))) + )) { uint32_t start = sector.addr + SECTOR_HDR_DATA_SIZE, end = sector.end_idx; found_start_tsl = true; - - tsl.addr.index = search_tsl_addr(db, start, end, from); - + /* search the first start TSL address */ + tsl.addr.index = search_start_tsl_addr(db, start, end, from, to); /* search all TSL */ do { read_tsl(db, &tsl);