Compare commits
6 Commits
master
...
revert-316
Author | SHA1 | Date | |
---|---|---|---|
![]() |
9a13cf1860 | ||
![]() |
da4cfd716e | ||
![]() |
c55e48b61b | ||
![]() |
6fb59b9313 | ||
![]() |
427b13d14a | ||
![]() |
c13e3d95e4 |
@@ -81,7 +81,7 @@ typedef uint64_t kv_dword_t; // double word
|
||||
|
||||
#define KV_NO_WRITEABLE_BLK() (KV_MGR_BLK_NUM_INUSE == 0 && KV_MGR_BLK_NUM_FRESH == 0)
|
||||
|
||||
#define KV_ITEM_HDR_MAGIC 0xABCD1234DCBA4321
|
||||
#define KV_ITEM_HDR_MAGIC 0x69745F6D61676963 /* "it_magic" */
|
||||
#define KV_ITEM_DISCARDED 0x0F0F0F0F0F0F0F0F
|
||||
#define KV_ITEM_IS_DISCARDED(item_hdr) ((item_hdr)->discarded_flag == KV_ITEM_DISCARDED)
|
||||
#define KV_ITEM_IS_LEGAL(item_hdr) ((item_hdr)->magic == KV_ITEM_HDR_MAGIC)
|
||||
@@ -100,10 +100,10 @@ typedef uint64_t kv_dword_t; // double word
|
||||
#define KV_ITEM_SIZE_OF_BODY(item) KV_ITEM_BODY_SIZE(item->hdr.k_len, item->hdr.v_len)
|
||||
#define KV_ITEM_ADDR_OF_BODY(item) (item->pos + KV_ITEM_HDR_SIZE)
|
||||
|
||||
#define KV_BLK_HDR_MAGIC 0x1234ABCD4321DCBA
|
||||
#define KV_BLK_HDR_GC_SRC 0x5678DCBA8765ABCD
|
||||
#define KV_BLK_HDR_GC_DST 0x8765ABCD8765DCBA
|
||||
#define KV_BLK_HDR_GC_DONE 0x4321DCBA1234ABCD
|
||||
#define KV_BLK_HDR_MAGIC 0x48445F4D41474943 /* "HD_MAGIC" */
|
||||
#define KV_BLK_HDR_GC_SRC 0x6D61726B5F737263 /* "mark_src" */
|
||||
#define KV_BLK_HDR_GC_DST 0x6D61726B5F647374 /* "mark_dst" */
|
||||
#define KV_BLK_HDR_GC_DONE 0x6B67635F646F6E65 /* "kgc_done" */
|
||||
|
||||
#define KV_BLK_IS_LEGAL(blk_hdr) ((blk_hdr)->magic == KV_BLK_HDR_MAGIC)
|
||||
|
||||
@@ -196,7 +196,7 @@ typedef struct kv_item_st {
|
||||
uint8_t *body; /*< item body: key/value buffer */
|
||||
} kv_item_t;
|
||||
|
||||
__STATIC__ kv_ctl_t kv_ctl;
|
||||
extern kv_ctl_t kv_ctl;
|
||||
|
||||
__STATIC_INLINE__ void kv_blk_freesz_set(uint32_t blk_start, uint32_t free_size)
|
||||
{
|
||||
|
@@ -145,6 +145,20 @@ __STATIC__ uint32_t kv_blk_next_fresh(void)
|
||||
return KV_BLK_INVALID;
|
||||
}
|
||||
|
||||
__STATIC__ uint32_t kv_blk_get_a_fresh(void)
|
||||
{
|
||||
uint32_t cur_blk;
|
||||
|
||||
KV_BLK_FOR_EACH(cur_blk) {
|
||||
if (kv_blk_is_fresh(cur_blk)) {
|
||||
return cur_blk;
|
||||
}
|
||||
}
|
||||
|
||||
return KV_BLK_INVALID;
|
||||
}
|
||||
|
||||
|
||||
__STATIC__ uint32_t kv_blk_search_inuse(uint32_t item_size)
|
||||
{
|
||||
uint32_t cur_blk;
|
||||
@@ -940,6 +954,26 @@ __STATIC__ int kv_mgr_blk_index_rebuild(void)
|
||||
return is_rebuild_done;
|
||||
}
|
||||
|
||||
__STATIC__ kv_err_t kv_try_gc(void)
|
||||
{
|
||||
uint32_t cur_blk, blk_dst;
|
||||
|
||||
blk_dst = kv_blk_get_a_fresh();
|
||||
if (blk_dst == KV_BLK_INVALID) {
|
||||
return KV_ERR_GC_NOTHING;
|
||||
}
|
||||
|
||||
KV_BLK_FOR_EACH(cur_blk) {
|
||||
if (kv_blk_is_dirty(cur_blk)) {
|
||||
if (kv_do_gc(cur_blk, blk_dst, K_FALSE) == KV_ERR_NONE) {
|
||||
return KV_ERR_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return KV_ERR_GC_NOTHING;
|
||||
}
|
||||
|
||||
__STATIC__ kv_err_t kv_mgr_workspace_locate(void)
|
||||
{
|
||||
uint32_t cur_blk;
|
||||
@@ -949,6 +983,12 @@ __STATIC__ kv_err_t kv_mgr_workspace_locate(void)
|
||||
kv_mgr_blk_index_rebuild();
|
||||
}
|
||||
|
||||
if (KV_MGR_BLK_NUM_INUSE == 0 && KV_MGR_BLK_NUM_FRESH == 1) {
|
||||
/* if here, we cannot just give out the last fresh block, otherwise the kv will get into
|
||||
KV_ERR_NO_WRITEABLE_BLK next time, try a gc here to get a "rescue" */
|
||||
kv_try_gc();
|
||||
}
|
||||
|
||||
if (KV_NO_WRITEABLE_BLK()) {
|
||||
return KV_ERR_NO_WRITEABLE_BLK;
|
||||
}
|
||||
@@ -1078,7 +1118,6 @@ __STATIC__ int kv_handle_incomplete_gc(struct blk_info gc_src_blk, struct blk_in
|
||||
|
||||
__STATIC__ int kv_mgr_ctl_build(void)
|
||||
{
|
||||
kv_err_t err;
|
||||
uint32_t cur_blk;
|
||||
kv_blk_hdr_t blk_hdr;
|
||||
|
||||
@@ -1176,22 +1215,21 @@ __STATIC__ kv_err_t kv_gc(void)
|
||||
|
||||
// there must be at least one fresh block left, make workspace pointer to the fresh one
|
||||
blk_dst = kv_blk_next_fresh();
|
||||
if (blk_dst == KV_BLK_INVALID) {
|
||||
/* kinda a bug here, KV_MGR_BLK_NUM_FRESH == 1 */
|
||||
return KV_ERR_GC_NOTHING;
|
||||
}
|
||||
|
||||
KV_BLK_FOR_EACH(cur_blk) {
|
||||
if (kv_blk_is_dirty(cur_blk)) {
|
||||
if (kv_do_gc(cur_blk, blk_dst, K_FALSE) != KV_ERR_NONE) {
|
||||
// cannot do gc for this block, give others a try
|
||||
continue;
|
||||
if (kv_do_gc(cur_blk, blk_dst, K_FALSE) == KV_ERR_NONE) {
|
||||
is_gc_done = K_TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
is_gc_done = K_TRUE;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_gc_done) {
|
||||
// if do nothing, should restore the workspace;
|
||||
KV_MGR_WORKSPACE = blk_dst;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user