mirror of
https://github.com/armink/FlashDB.git
synced 2025-02-04 08:43:07 +08:00
reverse iterator
This commit is contained in:
parent
a65a323508
commit
9b021c3056
@ -129,6 +129,41 @@ static fdb_err_t read_tsl(fdb_tsdb_t db, fdb_tsl_t tsl)
|
|||||||
return FDB_NO_ERR;
|
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)
|
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)) {
|
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;
|
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.
|
* The TSDB iterator for each TSL.
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user