Skip to content

feat: add TSDB support for high granularity Flash operations#398

Open
Oliver0927i wants to merge 8 commits intoarmink:masterfrom
Oliver0927i:feat/tsdb_support_high_granularity
Open

feat: add TSDB support for high granularity Flash operations#398
Oliver0927i wants to merge 8 commits intoarmink:masterfrom
Oliver0927i:feat/tsdb_support_high_granularity

Conversation

@Oliver0927i
Copy link

No description provided.

@armink
Copy link
Owner

armink commented Mar 12, 2026

有些冲突需要先解决下哈

@Oliver0927i
Copy link
Author

已解决

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds TSDB (Time Series Database) support for 64-bit and 128-bit Flash write granularity, which was previously explicitly unsupported with a compile-time error. The approach mirrors changes previously made to KVDB: struct fields are converted from native types to byte arrays aligned to write granularity, memcpy is used for reading/writing these fields, and an align_write helper is introduced for blob data.

Changes:

  • Removes the compile-time error blocking 64/128-bit write granularity in TSDB and adjusts sector_hdr_data and log_idx_data structs with byte-array fields and padding for alignment.
  • Adds an align_write function (mirroring the KVDB equivalent) to handle write-granularity-aligned Flash writes for blob data.
  • Updates read_sector_info, format_sector, write_tsl, and update_sec_status to use memcpy for field access and aligned writes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

src/fdb_tsdb.c Outdated
#endif

memset(align_data, FDB_BYTE_ERASED, align_data_size);
result = _fdb_flash_write((fdb_db_t) db, addr, buf, FDB_WG_ALIGN_DOWN(size), false);
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The KVDB version of align_write (in fdb_kvdb.c:1195) guards the first _fdb_flash_write call with if(FDB_WG_ALIGN_DOWN(size) > 0), but this TSDB version unconditionally calls _fdb_flash_write with FDB_WG_ALIGN_DOWN(size) which could be 0 when size is smaller than the write granularity. This should include the same guard to avoid writing 0 bytes.

Copilot uses AI. Check for mistakes.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Oliver0927i 这个可以参考下 AI 的建议

src/fdb_tsdb.c Outdated
Comment on lines +79 to +80
uint8_t magic[TSL_UINT32_ALIGN_SIZE]; /**< magic word(`T`, `S`, `L`, `0`) */
uint8_t start_time[TSL_UINT32_ALIGN_SIZE]; /**< the first start node's timestamp */
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Critical bug: TSL_UINT32_ALIGN_SIZE is FDB_WG_ALIGN(sizeof(uint32_t)) which is 4 bytes for FDB_WRITE_GRAN values of 1, 8, or 32. However, fdb_time_t can be int64_t (8 bytes) when FDB_USING_TIMESTAMP_64BIT is defined. The memcpy calls that copy sizeof(fdb_time_t) bytes from/to these uint8_t[TSL_UINT32_ALIGN_SIZE] arrays (e.g., sec_hdr.start_time, sec_hdr.end_info[i].time) will overflow the buffer and corrupt adjacent struct members. The time fields should use FDB_WG_ALIGN(sizeof(fdb_time_t)) instead of TSL_UINT32_ALIGN_SIZE.

Copilot uses AI. Check for mistakes.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Oliver0927i 这个也可以参考下 AI 的建议

src/fdb_tsdb.c Outdated
Comment on lines 103 to 105
#if (FDB_WRITE_GRAN == 64) || (FDB_WRITE_GRAN == 128)
uint8_t padding[4]; /**< align padding for 64bit write granularity */
#endif
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The padding comment says "align padding for 64bit write granularity" but this same padding is also applied for FDB_WRITE_GRAN == 128. The comment is misleading for the 128-bit case. Additionally, for 128-bit write granularity, 4 bytes of padding may not be sufficient — you should verify that the total struct size after padding is correctly aligned to FDB_WRITE_GRAN/8 (16 bytes for 128-bit).

Suggested change
#if (FDB_WRITE_GRAN == 64) || (FDB_WRITE_GRAN == 128)
uint8_t padding[4]; /**< align padding for 64bit write granularity */
#endif
#if (FDB_WRITE_GRAN == 64)
uint8_t padding[4]; /**< align padding for 64bit write granularity */
#endif
#if (FDB_WRITE_GRAN == 128)
uint8_t padding[12]; /**< align padding for 128bit write granularity */
#endif
#endif /* FDB_TSDB_FIXED_BLOB_SIZE */

Copilot uses AI. Check for mistakes.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Oliver0927i 这个可以参考下 AI 的建议

src/fdb_tsdb.c Outdated
FLASH_WRITE(db, idx_addr + LOG_IDX_TS_OFFSET, &idx.time, sizeof(struct log_idx_data) - LOG_IDX_TS_OFFSET, false);
/* write blob data */
FLASH_WRITE(db, log_addr, blob->buf, blob->size, false);
result = align_write(db, idx.log_addr, blob->buf, blob->size);
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: When FDB_TSDB_FIXED_BLOB_SIZE is defined, the log_idx_data struct does not have a log_addr member (it's inside #ifndef FDB_TSDB_FIXED_BLOB_SIZE), so idx.log_addr on this line will cause a compilation error. The original code correctly used the local variable log_addr (declared on line 357) instead of idx.log_addr. This should be reverted to use log_addr.

Suggested change
result = align_write(db, idx.log_addr, blob->buf, blob->size);
result = align_write(db, log_addr, blob->buf, blob->size);

Copilot uses AI. Check for mistakes.
src/fdb_tsdb.c Outdated
Comment on lines +324 to +349
static fdb_err_t align_write(fdb_tsdb_t db, uint32_t addr, const uint32_t *buf, size_t size)
{
fdb_err_t result = FDB_NO_ERR;
size_t align_remain;

#if (FDB_WRITE_GRAN / 8 > 0)
uint8_t align_data[FDB_WRITE_GRAN / 8];
size_t align_data_size = sizeof(align_data);
#else
/* For compatibility with C89 */
uint8_t align_data_u8, *align_data = &align_data_u8;
size_t align_data_size = 1;
#endif

memset(align_data, FDB_BYTE_ERASED, align_data_size);
result = _fdb_flash_write((fdb_db_t) db, addr, buf, FDB_WG_ALIGN_DOWN(size), false);

align_remain = size - FDB_WG_ALIGN_DOWN(size);
if (result == FDB_NO_ERR && align_remain) {
memcpy(align_data, (uint8_t *) buf + FDB_WG_ALIGN_DOWN(size), align_remain);
result = _fdb_flash_write((fdb_db_t) db, addr + FDB_WG_ALIGN_DOWN(size), (uint32_t *) align_data,
align_data_size, false);
}

return result;
}
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This align_write function is nearly identical to the one in fdb_kvdb.c:1180. Consider extracting it into a shared utility (e.g., in fdb_utils.c) to avoid code duplication and ensure bug fixes are applied consistently to both.

Copilot uses AI. Check for mistakes.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Oliver0927i 这个完全赞同 AI 的建议

src/fdb_tsdb.c Outdated
Comment on lines +87 to +92
#if (FDB_WRITE_GRAN == 64)
uint8_t padding[4]; /**< align padding for 64bit write granularity */
#endif
#if (FDB_WRITE_GRAN == 128)
uint8_t padding[12]; /**< align padding for 128bit write granularity */
#endif
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both #if (FDB_WRITE_GRAN == 64) and #if (FDB_WRITE_GRAN == 128) declare uint8_t padding[...] with the same member name. While they are mutually exclusive preprocessor branches, some compilers may issue a warning about redeclaration. This can be safely combined into a single #if (FDB_WRITE_GRAN == 64) || (FDB_WRITE_GRAN == 128) block using a computed size, similar to how the log_idx_data padding is done.

Suggested change
#if (FDB_WRITE_GRAN == 64)
uint8_t padding[4]; /**< align padding for 64bit write granularity */
#endif
#if (FDB_WRITE_GRAN == 128)
uint8_t padding[12]; /**< align padding for 128bit write granularity */
#endif
#if (FDB_WRITE_GRAN == 64) || (FDB_WRITE_GRAN == 128)
uint8_t padding[(FDB_WRITE_GRAN / 8) - 4]; /**< align padding for 64bit or 128bit write granularity */
#endif

Copilot uses AI. Check for mistakes.
@armink
Copy link
Owner

armink commented Mar 12, 2026

CI 里面的自动化测试用例没有通过,看着是编译都直接报错了,可以找下原因

@Oliver0927i
Copy link
Author

@armink 已经更新了,现在CI 能跑过~

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +110 to +122
sizeof(uint8_t) * TSL_STATUS_TABLE_SIZE
+ sizeof(fdb_time_t)
#ifndef FDB_TSDB_FIXED_BLOB_SIZE
+ sizeof(uint32_t) * 2
#endif
) -
(
sizeof(uint8_t) * TSL_STATUS_TABLE_SIZE
+ sizeof(fdb_time_t)
#ifndef FDB_TSDB_FIXED_BLOB_SIZE
+ sizeof(uint32_t) * 2
#endif
)
src/fdb_tsdb.c Outdated
#endif

memset(align_data, FDB_BYTE_ERASED, align_data_size);
result = _fdb_flash_write((fdb_db_t) db, addr, buf, FDB_WG_ALIGN_DOWN(size), false);
uint32_t reserved;

// Autofill to the FDB WRITE GRAN alignment
uint8_t padding[FDB_WG_ALIGN(sizeof(uint32_t))- sizeof(uint32_t)];
Comment on lines 100 to 106
struct log_idx_data {
uint8_t status_table[TSL_STATUS_TABLE_SIZE]; /**< node status, @see fdb_tsl_status_t */
fdb_time_t time; /**< node timestamp */
#ifndef FDB_TSDB_FIXED_BLOB_SIZE
uint32_t log_len; /**< node total length (header + name + value), must align by FDB_WRITE_GRAN */
uint32_t log_addr; /**< node address */
#endif
@Oliver0927i
Copy link
Author

@armink 已按照AI的建议修改~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants