Skip to content

Commit db383a1

Browse files
committed
fix(kvdb): Auto test failed when FDB_WRITE_GRAN is 128.
1 parent 2a2e97d commit db383a1

1 file changed

Lines changed: 73 additions & 1 deletion

File tree

tests/fdb_kvdb_tc.c

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include "utest.h"
1616
#include <flashdb.h>
17+
#include <fdb_low_lvl.h>
1718
#include <stdio.h>
1819
#include <stdlib.h>
1920
#include <inttypes.h>
@@ -30,7 +31,78 @@
3031
#define TEST_TS_PART_NAME "fdb_kvdb1"
3132
#define TEST_KV_BLOB_NAME "kv_blob_test"
3233
#define TEST_KV_NAME "kv_test"
33-
#define TEST_KV_VALUE_LEN 1200 /* only save 3 KVs in a 4096 sector */
34+
35+
/* ------------------------------------------------------------------
36+
* Dynamically compute TEST_KV_VALUE_LEN so that exactly 3 KVs fit
37+
* per TEST_KVDB_SECTOR_SIZE-byte sector for ANY FDB_WRITE_GRAN value,
38+
* AND so that the test_fdb_gc2 GC path works correctly.
39+
*
40+
* Let:
41+
* B = _TKV_BASE = KV_HDR_SZ + aligned_name
42+
* V = TEST_KV_VALUE_LEN (aligned to W)
43+
* kv_size = B + V
44+
* kv5_size= B + 2V (kv5 value = 2×V)
45+
* kv4_size= B + 3V (kv4 value = 3×V)
46+
* th = _TKV_THRESHOLD = KV_HDR_SZ + FDB_KV_NAME_MAX
47+
* usable = TEST_KVDB_SECTOR_SIZE - _TKV_SEC_HDR_SZ
48+
*
49+
* Three constraints, from LEAST to MOST strict:
50+
*
51+
* [A] 4th KV does NOT fit (exactly 3 per sector):
52+
* V >= ceil((usable - 5B - 64) / 4)
53+
*
54+
* [B] kv4 (3×V) occupies a full sector (no normal KV fits after it):
55+
* usable - (B+3V) <= (B+V) + th
56+
* V >= ceil((usable - 3B - 64) / 4)
57+
*
58+
* [C] GC does NOT stop early when kv1+kv2 are moved into the initially
59+
* empty sector (sector3). do_gc() stops when remain > free_size,
60+
* where free_size = kv5_size = B+2V. We need:
61+
* usable - 2*(B+V) <= B + 2V
62+
* 3984 - 3B <= 4V
63+
* V >= ceil((usable - 3B) / 4) ← STRICTEST BOUND (no -64 term)
64+
*
65+
* All three constraints reduce to the same form; [C] dominates.
66+
* The minimum V satisfying [C] (ceiling integer division: (N+3)/4):
67+
*
68+
* V_min = FDB_WG_ALIGN( (usable - 3B + 3) / 4 )
69+
* ------------------------------------------------------------------*/
70+
71+
/* write-gran alignment unit in bytes */
72+
#define _TKV_W ((FDB_WRITE_GRAN + 7) / 8)
73+
74+
/* KV status table size */
75+
#define _TKV_KV_STATUS_SZ FDB_STATUS_TABLE_SIZE(FDB_KV_STATUS_NUM)
76+
77+
/* Sector header raw size (store_status + dirty_status + magic + combined + reserved) */
78+
#define _TKV_SEC_HDR_RAW_SZ (FDB_STORE_STATUS_TABLE_SIZE + FDB_DIRTY_STATUS_TABLE_SIZE \
79+
+ sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t))
80+
#define _TKV_SEC_HDR_SZ FDB_WG_ALIGN(_TKV_SEC_HDR_RAW_SZ)
81+
82+
/* KV header raw size (status + magic + len + crc32 + name_len + value_len) */
83+
#define _TKV_KV_HDR_RAW_SZ (_TKV_KV_STATUS_SZ + sizeof(uint32_t) + sizeof(uint32_t) \
84+
+ sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint32_t))
85+
#define _TKV_KV_HDR_SZ FDB_WG_ALIGN(_TKV_KV_HDR_RAW_SZ)
86+
87+
/* FDB_SEC_REMAIN_THRESHOLD equivalent: KV_HDR_DATA_SIZE + FDB_KV_NAME_MAX */
88+
#define _TKV_THRESHOLD (_TKV_KV_HDR_SZ + FDB_KV_NAME_MAX)
89+
90+
/* name length of "kv0".."kv5", aligned */
91+
#define _TKV_NAME_ALIGNED FDB_WG_ALIGN(3)
92+
93+
/* usable data space per sector */
94+
#define _TKV_USABLE (TEST_KVDB_SECTOR_SIZE - _TKV_SEC_HDR_SZ)
95+
96+
/* per-KV base overhead: header + aligned name */
97+
#define _TKV_BASE (_TKV_KV_HDR_SZ + _TKV_NAME_ALIGNED)
98+
99+
/* Minimum V satisfying constraint [C] (the strictest).
100+
* Uses ceiling integer division: (N + 3) / 4. */
101+
#define _TKV_MAX_VAL_ALIGNED FDB_WG_ALIGN((_TKV_USABLE - 3 * _TKV_BASE + 3) / 4)
102+
103+
/* TEST_KV_VALUE_LEN: use aligned size directly (already a multiple of W) */
104+
#define TEST_KV_VALUE_LEN _TKV_MAX_VAL_ALIGNED
105+
34106
#define TEST_KV_MAX_NUM 8
35107
#define TEST_KVDB_SECTOR_SIZE 4096
36108
#define TEST_KVDB_SECTOR_NUM 4

0 commit comments

Comments
 (0)