简单ttl懒删除支持

This commit is contained in:
1iaan
2026-04-04 22:31:00 +08:00
parent 6ede44bd80
commit 78519fbfe5
11 changed files with 375 additions and 98 deletions

View File

@@ -2,6 +2,7 @@
#include "kvs_rw_tools.h"
#include "memory/alloc_dispatch.h"
#include "diskuring/diskuring.h"
#include <endian.h>
/* ============================================================================
* 内存布局说明:
@@ -31,6 +32,10 @@ static inline uint8_t* rbtree_node_get_key(rbtree_node *node) {
return (uint8_t *)node + sizeof(rbtree_node_fixed);
}
const uint8_t *kvs_rbtree_node_key_ptr(const rbtree_node *node) {
return node ? (const uint8_t *)rbtree_node_get_key((rbtree_node *)node) : NULL;
}
// ============================================================================
// 辅助函数获取节点内的value指针
// ============================================================================
@@ -39,6 +44,10 @@ static inline uint8_t* rbtree_node_get_value(rbtree_node *node) {
return (uint8_t *)node + sizeof(rbtree_node_fixed) + node->key_len;
}
const uint8_t *kvs_rbtree_node_value_ptr(const rbtree_node *node) {
return node ? (const uint8_t *)rbtree_node_get_value((rbtree_node *)node) : NULL;
}
// ============================================================================
// 原始比较函数(保持不变)
// ============================================================================
@@ -383,6 +392,27 @@ rbtree_node *rbtree_search(rbtree *T, const uint8_t *key, uint32_t keylen) {
return T->nil;
}
rbtree_node *rbtree_search_with_visit(rbtree *T, const uint8_t *key, uint32_t keylen,
kvs_rbtree_visit_cb cb, void *arg) {
rbtree_node *node;
if (!T) return NULL;
node = T->root;
while (node != T->nil) {
if (cb && cb(node, arg) != 0) {
break;
}
uint8_t *node_key = rbtree_node_get_key(node);
int c = kvs_keycmp(key, keylen, node_key, node->key_len);
if (c < 0) node = node->left;
else if (c > 0) node = node->right;
else return node;
}
return T->nil;
}
void rbtree_traversal(rbtree *T, rbtree_node *node) {
if (node != T->nil) {
@@ -412,6 +442,7 @@ int kvs_rbtree_create(kvs_rbtree_t *inst) {
inst->nil->color = BLACK;
inst->nil->left = inst->nil->right = inst->nil->parent = inst->nil;
inst->nil->expire_at_ms = 0;
inst->nil->key_len = 0;
inst->nil->value_len = 0;
inst->root = inst->nil;
@@ -448,6 +479,11 @@ void kvs_rbtree_destroy(kvs_rbtree_t *inst) {
* @return: <0 error; 0 success; 1 exist
*/
int kvs_rbtree_set(kvs_rbtree_t *inst, const void *key, uint32_t key_len, const void *value, uint32_t value_len) {
return kvs_rbtree_set_ex(inst, key, key_len, value, value_len, 0);
}
int kvs_rbtree_set_ex(kvs_rbtree_t *inst, const void *key, uint32_t key_len,
const void *value, uint32_t value_len, uint64_t expire_at_ms) {
if (!inst || !key || !value) return -1;
// 1. 查找键是否已存在
@@ -467,6 +503,7 @@ int kvs_rbtree_set(kvs_rbtree_t *inst, const void *key, uint32_t key_len, const
new_node->right = existing->right;
new_node->left = existing->left;
new_node->parent = existing->parent;
new_node->expire_at_ms = expire_at_ms;
new_node->key_len = key_len;
new_node->value_len = value_len;
@@ -500,6 +537,7 @@ int kvs_rbtree_set(kvs_rbtree_t *inst, const void *key, uint32_t key_len, const
// 大小相同,直接更新值
uint8_t *val = rbtree_node_get_value(existing);
if (value_len > 0) memcpy(val, value, value_len);
existing->expire_at_ms = expire_at_ms;
}
return 0;
}
@@ -513,6 +551,7 @@ int kvs_rbtree_set(kvs_rbtree_t *inst, const void *key, uint32_t key_len, const
node->key_len = key_len;
node->value_len = value_len;
node->expire_at_ms = expire_at_ms;
uint8_t *node_key = rbtree_node_get_key(node);
uint8_t *node_val = rbtree_node_get_value(node);
@@ -592,6 +631,7 @@ int kvs_rbtree_mod(kvs_rbtree_t *inst, const void *key, uint32_t key_len, const
new_node->left = node->left;
new_node->right = node->right;
new_node->parent = node->parent;
new_node->expire_at_ms = node->expire_at_ms;
new_node->key_len = node->key_len;
new_node->value_len = value_len;
@@ -645,9 +685,10 @@ static int kvs_rbtree_save_node(iouring_ctx_t *uring, int fd, off_t *current_off
uint32_t klen = htonl(node->key_len);
uint32_t vlen = htonl(node->value_len);
uint64_t expire_at_ms = htobe64(node->expire_at_ms);
void *bufs[4];
size_t lens[4];
void *bufs[5];
size_t lens[5];
int count = 0;
bufs[count] = &klen;
@@ -658,6 +699,10 @@ static int kvs_rbtree_save_node(iouring_ctx_t *uring, int fd, off_t *current_off
lens[count] = sizeof(vlen);
count++;
bufs[count] = &expire_at_ms;
lens[count] = sizeof(expire_at_ms);
count++;
uint8_t *node_key = rbtree_node_get_key(node);
if (node->key_len > 0) {
bufs[count] = node_key;
@@ -718,12 +763,25 @@ int kvs_rbtree_load(kvs_rbtree_t *inst, const char* filename){
for (;;) {
uint32_t klen_n = 0, vlen_n = 0;
uint64_t expire_at_ms_n = 0;
size_t r = fread(&klen_n, 1, sizeof(klen_n), fp);
if (r == 0) {
if (feof(fp)) {
fclose(fp);
return 0;
}
fclose(fp);
return -3;
}
if (r != sizeof(klen_n)) { fclose(fp); return -3; }
if (kvs_read_file(fp, &klen_n, 4) < 0) { fclose(fp); return -3; }
if (kvs_read_file(fp, &vlen_n, 4) < 0) { fclose(fp); return -3; }
if (kvs_read_file(fp, &expire_at_ms_n, sizeof(expire_at_ms_n)) < 0) { fclose(fp); return -3; }
uint32_t klen = ntohl(klen_n);
uint32_t vlen = ntohl(vlen_n);
uint64_t expire_at_ms = be64toh(expire_at_ms_n);
if (klen == 0) { fclose(fp); return -3; }
@@ -735,6 +793,7 @@ int kvs_rbtree_load(kvs_rbtree_t *inst, const char* filename){
memset(node, 0, node_size);
node->key_len = klen;
node->value_len = vlen;
node->expire_at_ms = expire_at_ms;
uint8_t *keybuf = rbtree_node_get_key(node);
if (kvs_read_file(fp, keybuf, (size_t)klen) < 0) {
@@ -753,6 +812,11 @@ int kvs_rbtree_load(kvs_rbtree_t *inst, const char* filename){
}
}
if (node->expire_at_ms != 0 && node->expire_at_ms <= kvs_now_ms()) {
kvs_free(node);
continue;
}
// 使用原生 rbtree_insert 而非 kvs_rbtree_set
// 因为 kvs_rbtree_set 会重新分配节点
if (rbtree_insert(inst, node) < 0) {
@@ -764,4 +828,4 @@ int kvs_rbtree_load(kvs_rbtree_t *inst, const char* filename){
fclose(fp);
return 0;
}
}