[tsdb] add rollover control feature.

This commit is contained in:
armink
2020-06-27 23:28:50 +08:00
parent cbad6efc67
commit 2673a71ca8
4 changed files with 92 additions and 52 deletions
+16 -12
View File
@@ -17,22 +17,22 @@ extern "C" {
#endif
/* software version number */
#define FDB_SW_VERSION "1.0.0 beta"
#define FDB_SW_VERSION_NUM 0x10000
#define FDB_SW_VERSION "1.0.0 beta"
#define FDB_SW_VERSION_NUM 0x10000
/* the KV max name length must less then it */
#ifndef FDB_KV_NAME_MAX
#define FDB_KV_NAME_MAX 32
#define FDB_KV_NAME_MAX 32
#endif
/* the KV cache table size, it will improve KV search speed when using cache */
#ifndef FDB_KV_CACHE_TABLE_SIZE
#define FDB_KV_CACHE_TABLE_SIZE 16
#define FDB_KV_CACHE_TABLE_SIZE 16
#endif
/* the sector cache table size, it will improve KV save speed when using cache */
#ifndef FDB_SECTOR_CACHE_TABLE_SIZE
#define FDB_SECTOR_CACHE_TABLE_SIZE 4
#define FDB_SECTOR_CACHE_TABLE_SIZE 4
#endif
#if (FDB_KV_CACHE_TABLE_SIZE > 0) && (FDB_SECTOR_CACHE_TABLE_SIZE > 0)
@@ -41,18 +41,18 @@ extern "C" {
/* log function. default FDB_PRINT macro is printf() */
#ifndef FDB_PRINT
#define FDB_PRINT(...) printf(__VA_ARGS__)
#define FDB_PRINT(...) printf(__VA_ARGS__)
#endif
#define FDB_LOG_PREFIX1() FDB_PRINT("[FlashDB]"FDB_LOG_TAG)
#define FDB_LOG_PREFIX2() FDB_PRINT(" ")
#define FDB_LOG_PREFIX() FDB_LOG_PREFIX1();FDB_LOG_PREFIX2()
#define FDB_LOG_PREFIX1() FDB_PRINT("[FlashDB]"FDB_LOG_TAG)
#define FDB_LOG_PREFIX2() FDB_PRINT(" ")
#define FDB_LOG_PREFIX() FDB_LOG_PREFIX1();FDB_LOG_PREFIX2()
#ifdef FDB_DEBUG_ENABLE
#define FDB_DEBUG(...) FDB_LOG_PREFIX();FDB_PRINT("(%s:%d) ", __FILE__, __LINE__);FDB_PRINT(__VA_ARGS__)
#define FDB_DEBUG(...) FDB_LOG_PREFIX();FDB_PRINT("(%s:%d) ", __FILE__, __LINE__);FDB_PRINT(__VA_ARGS__)
#else
#define FDB_DEBUG(...)
#endif
/* routine print function. Must be implement by user. */
#define FDB_INFO(...) FDB_LOG_PREFIX();FDB_PRINT(__VA_ARGS__)
#define FDB_INFO(...) FDB_LOG_PREFIX();FDB_PRINT(__VA_ARGS__)
/* assert for developer. */
#define FDB_ASSERT(EXPR) \
if (!(EXPR)) \
@@ -61,6 +61,9 @@ if (!(EXPR)) \
while (1); \
}
#define FDB_TSDB_CTRL_SET_ROLLOVER 0x0 /**< set rollover control command */
#define FDB_TSDB_CTRL_GET_ROLLOVER 0x1 /**< get rollover control command */
typedef time_t fdb_time_t;
#ifdef FDB_USING_TIMESTAMP_64BIT
typedef int64_t fdb_time_t;
@@ -87,7 +90,7 @@ typedef enum {
FDB_PART_NOT_FOUND,
FDB_KV_NAME_ERR,
FDB_KV_NAME_EXIST,
FDB_KV_FULL,
FDB_SAVED_FULL,
FDB_INIT_FAILED,
} fdb_err_t;
@@ -255,6 +258,7 @@ struct fdb_tsdb {
fdb_get_time get_time; /**< the current timestamp get function */
size_t max_len; /**< the max log length */
uint32_t oldest_addr; /**< the oldest sector start address */
bool rollover; /**< the oldest data will rollover by newest data, default is true */
void *user_data;
};
+6 -5
View File
@@ -24,13 +24,14 @@
extern "C" {
#endif
/* fdb.c */
void fdb_lock_set(fdb_db_t db, void (*lock)(fdb_db_t db), void (*unlock)(fdb_db_t db));
/* FlashDB database API */
void fdb_lock_set (fdb_db_t db, void (*lock)(fdb_db_t db), void (*unlock)(fdb_db_t db));
void fdb_sec_size_set(fdb_db_t db, uint32_t sec_size);
fdb_err_t fdb_kvdb_init(fdb_kvdb_t db, const char *name, const char *part_name, struct fdb_default_kv *default_kv,
fdb_err_t fdb_kvdb_init (fdb_kvdb_t db, const char *name, const char *part_name, struct fdb_default_kv *default_kv,
void *user_data);
fdb_err_t fdb_tsdb_init(fdb_tsdb_t db, const char *name, const char *part_name, fdb_get_time get_time, size_t max_len,
fdb_err_t fdb_tsdb_init (fdb_tsdb_t db, const char *name, const char *part_name, fdb_get_time get_time, size_t max_len,
void *user_data);
void fdb_tsdb_control(fdb_tsdb_t db, int cmd, void *arg);
/* blob API */
fdb_blob_t fdb_blob_make (fdb_blob_t blob, const void *value_buf, size_t buf_len);
@@ -43,7 +44,7 @@ fdb_err_t fdb_kv_set_blob (fdb_kvdb_t db, const char *key, fdb_blob_t blob);
size_t fdb_kv_get_blob (fdb_kvdb_t db, const char *key, fdb_blob_t blob);
fdb_err_t fdb_kv_del (fdb_kvdb_t db, const char *key);
fdb_kv_t fdb_kv_get_obj (fdb_kvdb_t db, const char *key, fdb_kv_t kv);
fdb_blob_t fdb_kv_to_blob (fdb_kv_t kv, fdb_blob_t blob);
fdb_blob_t fdb_kv_to_blob (fdb_kv_t kv, fdb_blob_t blob);
fdb_err_t fdb_kv_set_default(fdb_kvdb_t db);
void fdb_kv_print (fdb_kvdb_t db);
+4 -4
View File
@@ -923,7 +923,7 @@ static fdb_err_t move_kv(fdb_kvdb_t db, fdb_kv_t kv)
}
}
} else {
return FDB_KV_FULL;
return FDB_SAVED_FULL;
}
/* start move the KV */
{
@@ -1092,7 +1092,7 @@ static fdb_err_t create_kv_blob(fdb_kvdb_t db, kv_sec_info_t sector, const char
if (kv_hdr.len > db_sec_size(db) - SECTOR_HDR_DATA_SIZE) {
FDB_INFO("Error: The KV size is too big\n");
return FDB_KV_FULL;
return FDB_SAVED_FULL;
}
if (kv_addr != FAILED_ADDR || (kv_addr = new_kv(db, sector, kv_hdr.len)) != FAILED_ADDR) {
@@ -1146,7 +1146,7 @@ static fdb_err_t create_kv_blob(fdb_kvdb_t db, kv_sec_info_t sector, const char
db->gc_request = true;
}
} else {
result = FDB_KV_FULL;
result = FDB_SAVED_FULL;
}
return result;
@@ -1192,7 +1192,7 @@ static fdb_err_t set_kv(fdb_kvdb_t db, const char *key, const void *value_buf, s
} else {
/* make sure the flash has enough space */
if (new_kv_ex(db, &sector, strlen(key), buf_len) == FAILED_ADDR) {
return FDB_KV_FULL;
return FDB_SAVED_FULL;
}
kv_is_found = find_kv(db, key, &kv);
/* prepare to delete the old KV */
+66 -31
View File
@@ -287,38 +287,43 @@ static fdb_err_t update_sec_status(fdb_tsdb_t db, tsdb_sec_info_t sector, fdb_bl
uint8_t status[FDB_STORE_STATUS_TABLE_SIZE];
if (sector->status == FDB_SECTOR_STORE_USING && sector->remain < LOG_IDX_DATA_SIZE + FDB_WG_ALIGN(blob->size)) {
uint8_t end_status[TSL_STATUS_TABLE_SIZE];
uint32_t end_index = sector->empty_idx - LOG_IDX_DATA_SIZE, new_sec_addr, cur_sec_addr = sector->addr;
/* save the end node index and timestamp */
if (sector->end_info_stat[0] == FDB_TSL_UNUSED) {
_FDB_WRITE_STATUS(db, cur_sec_addr + SECTOR_END0_STATUS_OFFSET, end_status, FDB_TSL_STATUS_NUM, FDB_TSL_PRE_WRITE);
FLASH_WRITE(db, cur_sec_addr + SECTOR_END0_TIME_OFFSET, (uint32_t * )&db->last_time, sizeof(fdb_time_t));
FLASH_WRITE(db, cur_sec_addr + SECTOR_END0_IDX_OFFSET, &end_index, sizeof(end_index));
_FDB_WRITE_STATUS(db, cur_sec_addr + SECTOR_END0_STATUS_OFFSET, end_status, FDB_TSL_STATUS_NUM, FDB_TSL_WRITE);
} else if (sector->end_info_stat[1] == FDB_TSL_UNUSED) {
_FDB_WRITE_STATUS(db, cur_sec_addr + SECTOR_END1_STATUS_OFFSET, end_status, FDB_TSL_STATUS_NUM, FDB_TSL_PRE_WRITE);
FLASH_WRITE(db, cur_sec_addr + SECTOR_END1_TIME_OFFSET, (uint32_t * )&db->last_time, sizeof(fdb_time_t));
FLASH_WRITE(db, cur_sec_addr + SECTOR_END1_IDX_OFFSET, &end_index, sizeof(end_index));
_FDB_WRITE_STATUS(db, cur_sec_addr + SECTOR_END1_STATUS_OFFSET, end_status, FDB_TSL_STATUS_NUM, FDB_TSL_WRITE);
}
/* change current sector to full */
_FDB_WRITE_STATUS(db, cur_sec_addr, status, FDB_SECTOR_STORE_STATUS_NUM, FDB_SECTOR_STORE_FULL);
/* calculate next sector address */
if (sector->addr + db_sec_size(db) < db_part_size(db)) {
new_sec_addr = sector->addr + db_sec_size(db);
} else {
new_sec_addr = 0;
}
read_sector_info(db, new_sec_addr, &db->cur_sec, false);
if (sector->status != FDB_SECTOR_STORE_EMPTY) {
/* calculate the oldest sector address */
if (new_sec_addr + db_sec_size(db) < db_part_size(db)) {
db->oldest_addr = new_sec_addr + db_sec_size(db);
} else {
db->oldest_addr = 0;
if (db->rollover) {
uint8_t end_status[TSL_STATUS_TABLE_SIZE];
uint32_t end_index = sector->empty_idx - LOG_IDX_DATA_SIZE, new_sec_addr, cur_sec_addr = sector->addr;
/* save the end node index and timestamp */
if (sector->end_info_stat[0] == FDB_TSL_UNUSED) {
_FDB_WRITE_STATUS(db, cur_sec_addr + SECTOR_END0_STATUS_OFFSET, end_status, FDB_TSL_STATUS_NUM, FDB_TSL_PRE_WRITE);
FLASH_WRITE(db, cur_sec_addr + SECTOR_END0_TIME_OFFSET, (uint32_t * )&db->last_time, sizeof(fdb_time_t));
FLASH_WRITE(db, cur_sec_addr + SECTOR_END0_IDX_OFFSET, &end_index, sizeof(end_index));
_FDB_WRITE_STATUS(db, cur_sec_addr + SECTOR_END0_STATUS_OFFSET, end_status, FDB_TSL_STATUS_NUM, FDB_TSL_WRITE);
} else if (sector->end_info_stat[1] == FDB_TSL_UNUSED) {
_FDB_WRITE_STATUS(db, cur_sec_addr + SECTOR_END1_STATUS_OFFSET, end_status, FDB_TSL_STATUS_NUM, FDB_TSL_PRE_WRITE);
FLASH_WRITE(db, cur_sec_addr + SECTOR_END1_TIME_OFFSET, (uint32_t * )&db->last_time, sizeof(fdb_time_t));
FLASH_WRITE(db, cur_sec_addr + SECTOR_END1_IDX_OFFSET, &end_index, sizeof(end_index));
_FDB_WRITE_STATUS(db, cur_sec_addr + SECTOR_END1_STATUS_OFFSET, end_status, FDB_TSL_STATUS_NUM, FDB_TSL_WRITE);
}
/* change current sector to full */
_FDB_WRITE_STATUS(db, cur_sec_addr, status, FDB_SECTOR_STORE_STATUS_NUM, FDB_SECTOR_STORE_FULL);
/* calculate next sector address */
if (sector->addr + db_sec_size(db) < db_part_size(db)) {
new_sec_addr = sector->addr + db_sec_size(db);
} else {
new_sec_addr = 0;
}
format_sector(db, new_sec_addr);
read_sector_info(db, new_sec_addr, &db->cur_sec, false);
if (sector->status != FDB_SECTOR_STORE_EMPTY) {
/* calculate the oldest sector address */
if (new_sec_addr + db_sec_size(db) < db_part_size(db)) {
db->oldest_addr = new_sec_addr + db_sec_size(db);
} else {
db->oldest_addr = 0;
}
format_sector(db, new_sec_addr);
read_sector_info(db, new_sec_addr, &db->cur_sec, false);
}
} else {
/* not rollover */
return FDB_SAVED_FULL;
}
}
@@ -341,10 +346,16 @@ static fdb_err_t tsl_append(fdb_tsdb_t db, fdb_blob_t blob)
FDB_ASSERT(blob->size <= db->max_len);
update_sec_status(db, &db->cur_sec, blob, cur_time);
result = update_sec_status(db, &db->cur_sec, blob, cur_time);
if (result != FDB_NO_ERR) {
return result;
}
/* write the TSL node */
result = write_tsl(db, blob, cur_time);
if (result != FDB_NO_ERR) {
return result;
}
/* recalculate the current using sector info */
db->cur_sec.end_idx = db->cur_sec.empty_idx;
@@ -645,6 +656,28 @@ void fdb_tsl_clean(fdb_tsdb_t db)
db_unlock(db);
}
/**
* This function will get or set some options of the database
*
* @param db database object
* @param cmd the control command
* @param arg the argument
*/
void fdb_tsdb_control(fdb_tsdb_t db, int cmd, void *arg)
{
FDB_ASSERT(db);
switch (cmd) {
case FDB_TSDB_CTRL_GET_ROLLOVER:
*(bool *)arg = db->rollover;
break;
case FDB_TSDB_CTRL_SET_ROLLOVER:
db->rollover = *(bool *)arg;
break;
}
}
/**
* The time series database initialization.
*
@@ -672,6 +705,8 @@ fdb_err_t fdb_tsdb_init(fdb_tsdb_t db, const char *name, const char *part_name,
db->get_time = get_time;
db->max_len = max_len;
/* default rollover flag is true */
db->rollover = true;
db->oldest_addr = FDB_DATA_UNUSED;
db->cur_sec.addr = FDB_DATA_UNUSED;
/* must align with sector size */