From 9b021c30563bcf310a279ff46db68a185065cc9d Mon Sep 17 00:00:00 2001 From: MikeTuev Date: Sun, 24 Apr 2022 01:25:50 +0500 Subject: [PATCH] reverse iterator --- src/fdb_tsdb.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/src/fdb_tsdb.c b/src/fdb_tsdb.c index 8547761..90cd9dd 100644 --- a/src/fdb_tsdb.c +++ b/src/fdb_tsdb.c @@ -129,6 +129,41 @@ 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)) { @@ -408,6 +443,54 @@ 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_rev(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 = db->cur_sec.empty_idx - LOG_IDX_DATA_SIZE; + } else + 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. *