Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ name: AutoTestCI
on: [push, pull_request]
jobs:
test:
name: AutoTest
name: "AutoTest (GRAN=${{ matrix.write_gran }})"
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
write_gran: [1, 8, 32, 64, 128]
env:
TEST_BSP_ROOT: ../AutoTestBsp
UTEST_RUNNER_PATH: ../UtestRunner
Expand All @@ -26,7 +30,7 @@ jobs:
cp -rf inc/fdb_low_lvl.h $TEST_BSP_ROOT/packages/FlashDB/inc/fdb_low_lvl.h
cp -rf inc/flashdb.h $TEST_BSP_ROOT/packages/FlashDB/inc/flashdb.h
/opt/gcc-arm-none-eabi-10-2020-q4-major/bin/arm-none-eabi-gcc --version
scons -j$(nproc) -C $TEST_BSP_ROOT
scons --global-macros="FDB_WRITE_GRAN=${{ matrix.write_gran }}" -j$(nproc) -C $TEST_BSP_ROOT
- name: Start test
run: |
python3 $UTEST_RUNNER_PATH/qemu_runner.py --elf $TEST_BSP_ROOT/rtthread.elf --sd $TEST_BSP_ROOT/sd.bin
Expand Down
27 changes: 15 additions & 12 deletions src/fdb_tsdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,25 +32,28 @@
#define TSL_UINT32_ALIGN_SIZE (FDB_WG_ALIGN(sizeof(uint32_t)))

#ifdef FDB_USING_TIMESTAMP_64BIT
#define TSL_TIME_ALIGN_SIZE FDB_WG_ALIGN(sizeof(int64_t))
#define TSL_TIME_ALIGN_SIZE FDB_WG_ALIGN(sizeof(int64_t))
#else
#define TSL_TIME_ALIGN_SIZE FDB_WG_ALIGN(sizeof(int32_t))
#define TSL_TIME_ALIGN_SIZE FDB_WG_ALIGN(sizeof(int32_t))
#endif

// Autofill to struct sector_hdr_data
enum {
TSL_HDR_PADDING_SIZE = FDB_WG_ALIGN(sizeof(uint32_t)) - sizeof(uint32_t)
};
#define SECTOR_HDR_PADDING_SIZE (FDB_WG_ALIGN(4) - 4)

// Autofill to struct log_idx_data
enum {
#ifdef FDB_USING_TIMESTAMP_64BIT
#define _TSL_FDBTIME_SIZE (8)
#else
#define _TSL_FDBTIME_SIZE (4)
#endif

#ifdef FDB_TSDB_FIXED_BLOB_SIZE
LOG_IDX_BASE_SIZE = TSL_STATUS_TABLE_SIZE + sizeof(fdb_time_t),
#define LOG_IDX_BASE_SIZE (TSL_STATUS_TABLE_SIZE + _TSL_FDBTIME_SIZE)
#else
LOG_IDX_BASE_SIZE = TSL_STATUS_TABLE_SIZE + sizeof(fdb_time_t) + sizeof(uint32_t) * 2,
#define LOG_IDX_BASE_SIZE (TSL_STATUS_TABLE_SIZE + _TSL_FDBTIME_SIZE + 4 * 2)
#endif
LOG_IDX_PADDING_SIZE = FDB_WG_ALIGN(LOG_IDX_BASE_SIZE) - LOG_IDX_BASE_SIZE
};

#define LOG_IDX_PADDING_SIZE (FDB_WG_ALIGN(LOG_IDX_BASE_SIZE) - LOG_IDX_BASE_SIZE)

#define SECTOR_HDR_DATA_SIZE (FDB_WG_ALIGN(sizeof(struct sector_hdr_data)))
#define LOG_IDX_DATA_SIZE (FDB_WG_ALIGN(sizeof(struct log_idx_data)))
Expand Down Expand Up @@ -107,8 +110,8 @@ struct sector_hdr_data {
uint32_t reserved;

// Autofill to the FDB WRITE GRAN alignment
#if TSL_HDR_PADDING_SIZE > 0
uint8_t padding[TSL_HDR_PADDING_SIZE];
#if SECTOR_HDR_PADDING_SIZE > 0
uint8_t padding[SECTOR_HDR_PADDING_SIZE];
#endif
};
typedef struct sector_hdr_data *sector_hdr_data_t;
Expand Down
74 changes: 73 additions & 1 deletion tests/fdb_kvdb_tc.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include "utest.h"
#include <flashdb.h>
#include <fdb_low_lvl.h>
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
Expand All @@ -30,7 +31,78 @@
#define TEST_TS_PART_NAME "fdb_kvdb1"
#define TEST_KV_BLOB_NAME "kv_blob_test"
#define TEST_KV_NAME "kv_test"
#define TEST_KV_VALUE_LEN 1200 /* only save 3 KVs in a 4096 sector */

/* ------------------------------------------------------------------
* Dynamically compute TEST_KV_VALUE_LEN so that exactly 3 KVs fit
* per TEST_KVDB_SECTOR_SIZE-byte sector for ANY FDB_WRITE_GRAN value,
* AND so that the test_fdb_gc2 GC path works correctly.
*
* Let:
* B = _TKV_BASE = KV_HDR_SZ + aligned_name
* V = TEST_KV_VALUE_LEN (aligned to W)
* kv_size = B + V
* kv5_size= B + 2V (kv5 value = 2×V)
* kv4_size= B + 3V (kv4 value = 3×V)
* th = _TKV_THRESHOLD = KV_HDR_SZ + FDB_KV_NAME_MAX
* usable = TEST_KVDB_SECTOR_SIZE - _TKV_SEC_HDR_SZ
*
* Three constraints, from LEAST to MOST strict:
*
* [A] 4th KV does NOT fit (exactly 3 per sector):
* V >= ceil((usable - 5B - 64) / 4)
*
* [B] kv4 (3×V) occupies a full sector (no normal KV fits after it):
* usable - (B+3V) <= (B+V) + th
* V >= ceil((usable - 3B - 64) / 4)
*
* [C] GC does NOT stop early when kv1+kv2 are moved into the initially
* empty sector (sector3). do_gc() stops when remain > free_size,
* where free_size = kv5_size = B+2V. We need:
* usable - 2*(B+V) <= B + 2V
* 3984 - 3B <= 4V
* V >= ceil((usable - 3B) / 4) ← STRICTEST BOUND (no -64 term)
*
* All three constraints reduce to the same form; [C] dominates.
* The minimum V satisfying [C] (ceiling integer division: (N+3)/4):
*
* V_min = FDB_WG_ALIGN( (usable - 3B + 3) / 4 )
* ------------------------------------------------------------------*/

/* write-gran alignment unit in bytes */
#define _TKV_W ((FDB_WRITE_GRAN + 7) / 8)

/* KV status table size */
#define _TKV_KV_STATUS_SZ FDB_STATUS_TABLE_SIZE(FDB_KV_STATUS_NUM)

/* Sector header raw size (store_status + dirty_status + magic + combined + reserved) */
#define _TKV_SEC_HDR_RAW_SZ (FDB_STORE_STATUS_TABLE_SIZE + FDB_DIRTY_STATUS_TABLE_SIZE \
+ sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t))
#define _TKV_SEC_HDR_SZ FDB_WG_ALIGN(_TKV_SEC_HDR_RAW_SZ)

/* KV header raw size (status + magic + len + crc32 + name_len + value_len) */
#define _TKV_KV_HDR_RAW_SZ (_TKV_KV_STATUS_SZ + sizeof(uint32_t) + sizeof(uint32_t) \
+ sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint32_t))
#define _TKV_KV_HDR_SZ FDB_WG_ALIGN(_TKV_KV_HDR_RAW_SZ)

/* FDB_SEC_REMAIN_THRESHOLD equivalent: KV_HDR_DATA_SIZE + FDB_KV_NAME_MAX */
#define _TKV_THRESHOLD (_TKV_KV_HDR_SZ + FDB_KV_NAME_MAX)

/* name length of "kv0".."kv5", aligned */
#define _TKV_NAME_ALIGNED FDB_WG_ALIGN(3)

/* usable data space per sector */
#define _TKV_USABLE (TEST_KVDB_SECTOR_SIZE - _TKV_SEC_HDR_SZ)

/* per-KV base overhead: header + aligned name */
#define _TKV_BASE (_TKV_KV_HDR_SZ + _TKV_NAME_ALIGNED)

/* Minimum V satisfying constraint [C] (the strictest).
* Uses ceiling integer division: (N + 3) / 4. */
#define _TKV_MAX_VAL_ALIGNED FDB_WG_ALIGN((_TKV_USABLE - 3 * _TKV_BASE + 3) / 4)

/* TEST_KV_VALUE_LEN: use aligned size directly (already a multiple of W) */
#define TEST_KV_VALUE_LEN _TKV_MAX_VAL_ALIGNED

#define TEST_KV_MAX_NUM 8
#define TEST_KVDB_SECTOR_SIZE 4096
#define TEST_KVDB_SECTOR_NUM 4
Expand Down