简单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

116
kvstore.c
View File

@@ -17,9 +17,10 @@
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <libxml/parser.h>
#include <limits.h>
#include <arpa/inet.h>
#include <libxml/parser.h>
#include <limits.h>
#include <time.h>
#define TIME_COLLECT 0
@@ -33,7 +34,16 @@ unsigned long long global_seq;
extern int global_oplog_fd;
replica_shm_t g_rep_shm;
replica_shm_t g_rep_shm;
typedef struct ttl_delete_task_s {
struct ttl_delete_task_s *next;
uint8_t *key;
uint32_t key_len;
} ttl_delete_task_t;
static ttl_delete_task_t *g_ttl_delete_head = NULL;
static ttl_delete_task_t *g_ttl_delete_tail = NULL;
__attribute__((noinline))
void __completed_cmd(const uint8_t *cmd, size_t len, unsigned long long seq){
@@ -45,13 +55,80 @@ void __completed_cmd(const uint8_t *cmd, size_t len, unsigned long long seq){
#define TIME_SUB_MS(tv1, tv2) ((tv1.tv_sec - tv2.tv_sec) * 1000 + (tv1.tv_usec - tv2.tv_usec) / 1000)
#define TIME_SUB_US(tv1, tv2) ((tv1.tv_sec - tv2.tv_sec) * 1000000 + (tv1.tv_usec - tv2.tv_usec))
static int checked_size_add(size_t a, size_t b, size_t *out) {
static int checked_size_add(size_t a, size_t b, size_t *out) {
if (!out || a > SIZE_MAX - b) {
return -1;
}
*out = a + b;
return 0;
}
*out = a + b;
return 0;
}
uint64_t kvs_now_ms(void) {
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
return (uint64_t)ts.tv_sec * 1000ULL + (uint64_t)ts.tv_nsec / 1000000ULL;
}
int ttl_delete_schedule(const void *key, uint32_t key_len) {
ttl_delete_task_t *task;
if (!key || key_len == 0) return -1;
task = (ttl_delete_task_t *)kvs_malloc(sizeof(*task));
if (!task) return -1;
memset(task, 0, sizeof(*task));
task->key = (uint8_t *)kvs_malloc(key_len);
if (!task->key) {
kvs_free(task);
return -1;
}
memcpy(task->key, key, key_len);
task->key_len = key_len;
if (g_ttl_delete_tail) {
g_ttl_delete_tail->next = task;
} else {
g_ttl_delete_head = task;
}
g_ttl_delete_tail = task;
return 0;
}
int ttl_delete_drain(int budget) {
int drained = 0;
#if !ENABLE_RBTREE
(void)budget;
return 0;
#else
while (budget > 0 && g_ttl_delete_head) {
ttl_delete_task_t *task = g_ttl_delete_head;
rbtree_node *node;
g_ttl_delete_head = task->next;
if (!g_ttl_delete_head) {
g_ttl_delete_tail = NULL;
}
node = rbtree_search(&global_rbtree, task->key, task->key_len);
if (node != global_rbtree.nil &&
node->expire_at_ms != 0 &&
node->expire_at_ms <= kvs_now_ms()) {
(void)kvs_rbtree_del(&global_rbtree, task->key, task->key_len);
}
kvs_free(task->key);
kvs_free(task);
drained++;
budget--;
}
return drained;
#endif
}
static int resp_value_encoded_len(const resp_value_t *v, size_t *out_len) {
size_t len = 0;
@@ -138,11 +215,12 @@ static int is_update_cmd(const resp_cmd_t *cmd) {
return 0;
}
c0 = &cmd->argv[0];
return ascii_casecmp(c0->ptr, c0->len, "SET") == 0 ||
ascii_casecmp(c0->ptr, c0->len, "DEL") == 0 ||
ascii_casecmp(c0->ptr, c0->len, "MOD") == 0 ||
ascii_casecmp(c0->ptr, c0->len, "RSET") == 0 ||
c0 = &cmd->argv[0];
return ascii_casecmp(c0->ptr, c0->len, "SET") == 0 ||
ascii_casecmp(c0->ptr, c0->len, "DEL") == 0 ||
ascii_casecmp(c0->ptr, c0->len, "SETEX") == 0 ||
ascii_casecmp(c0->ptr, c0->len, "MOD") == 0 ||
ascii_casecmp(c0->ptr, c0->len, "RSET") == 0 ||
ascii_casecmp(c0->ptr, c0->len, "RDEL") == 0 ||
ascii_casecmp(c0->ptr, c0->len, "RMOD") == 0 ||
ascii_casecmp(c0->ptr, c0->len, "HSET") == 0 ||
@@ -420,11 +498,13 @@ int init_config(AppConfig *cfg){
printf("|—— Persist-rbtree : %s\n", cfg->rbtree_file);
printf("|—— Persist-hash : %s\n", cfg->hash_file);
printf("Log level : %s\n", log_level_to_string(cfg->log_level));
printf("Memory : \n");
printf("|——Allocator : %s\n", allocator_to_string(cfg->allocator));
printf("|——MemLeakDetectMode : %s\n", leakage_to_string(cfg->leak_mode));
printf("=============== Config ===============\n");
printf("Log level : %s\n", log_level_to_string(cfg->log_level));
printf("Memory : \n");
printf("|——Allocator : %s\n", allocator_to_string(cfg->allocator));
printf("|——MemLeakDetectMode : %s\n", leakage_to_string(cfg->leak_mode));
printf("Redis-Compat\t\t: \n");
printf("|——Auth Password\t: %s\n", cfg->redis_auth_password[0] ? "[configured]" : "[empty]");
printf("=============== Config ===============\n");
xmlCleanupParser();
return 0;