Skip to content

Commit

Permalink
Merge pull request armink#145 from MikeTuev/MikeTuev-patch-reverse_it…
Browse files Browse the repository at this point in the history
…erator

Mike tuev patch reverse iterator
  • Loading branch information
armink authored May 18, 2022
2 parents c175635 + 85d136e commit e3b1bee
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 0 deletions.
1 change: 1 addition & 0 deletions inc/flashdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ bool fdb_kv_iterate (fdb_kvdb_t db, fdb_kv_iterator_t itr);
/* Time series log API like a TSDB */
fdb_err_t fdb_tsl_append (fdb_tsdb_t db, fdb_blob_t blob);
void fdb_tsl_iter (fdb_tsdb_t db, fdb_tsl_cb cb, void *cb_arg);
void fdb_tsl_iter_rev (fdb_tsdb_t db, fdb_tsl_cb cb, void *arg)
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);
size_t fdb_tsl_query_count (fdb_tsdb_t db, fdb_time_t from, fdb_time_t to, fdb_tsl_status_t status);
fdb_err_t fdb_tsl_set_status (fdb_tsdb_t db, fdb_tsl_t tsl, fdb_tsl_status_t status);
Expand Down
87 changes: 87 additions & 0 deletions src/fdb_tsdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
if (result != FDB_NO_ERR) return result; \
} while(0);

#pragma pack(push,1)

struct sector_hdr_data {
uint8_t status[FDB_STORE_STATUS_TABLE_SIZE]; /**< sector store status @see fdb_sector_store_status_t */
uint32_t magic; /**< magic word(`T`, `S`, `L`, `0`) */
Expand All @@ -94,6 +96,8 @@ struct log_idx_data {
};
typedef struct log_idx_data *log_idx_data_t;

#pragma pack(pop)

struct query_count_args {
fdb_tsl_status_t status;
size_t count;
Expand Down Expand Up @@ -125,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)) {
Expand Down Expand Up @@ -404,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, &sector, 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(&sector, &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, &sector, traversed_len)) != FAILED_ADDR);
}

/**
* The TSDB iterator for each TSL.
*
Expand Down

0 comments on commit e3b1bee

Please sign in to comment.