mirror of
https://github.com/armink/FlashDB.git
synced 2026-10-06 12:59:32 +08:00
[tsdb] add rollover control feature.
This commit is contained in:
+16
-12
@@ -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
@@ -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
@@ -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, §or, 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
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user