feat: add SCANPREFIX/KEYSPREFIX/SCANRANGE/KEYSRANGE

This commit is contained in:
1iaan
2026-04-07 12:39:55 +08:00
parent aee84df665
commit 8fdefc2100
4 changed files with 296 additions and 46 deletions

123
kvstore.c
View File

@@ -163,10 +163,10 @@ static int resp_value_encoded_len(const resp_value_t *v, size_t *out_len) {
len = 5; /* "$-1\r\n" */
break;
case RESP_T_BULK_STR: {
char tmp[32];
int n;
size_t t;
case RESP_T_BULK_STR: {
char tmp[32];
int n;
size_t t;
if (v->bulk.len > 0 && !v->bulk.ptr) {
return -1;
@@ -182,12 +182,57 @@ static int resp_value_encoded_len(const resp_value_t *v, size_t *out_len) {
checked_size_add(t, (size_t)v->bulk.len, &t) < 0 ||
checked_size_add(t, 2, &len) < 0) { /* trailing \r\n */
return -1;
}
break;
}
default:
return -1;
}
break;
}
case RESP_T_ARRAY: {
char tmp[32];
int n;
size_t t = 0;
if (v->array.count > 0 && !v->array.items) {
return -1;
}
n = snprintf(tmp, sizeof(tmp), "%u", (unsigned)v->array.count);
if (n <= 0) {
return -1;
}
if (checked_size_add(1, (size_t)n, &t) < 0 ||
checked_size_add(t, 2, &t) < 0) {
return -1;
}
for (uint32_t i = 0; i < v->array.count; ++i) {
size_t item_len = 0;
int item_digits;
if (v->array.items[i].len > 0 && !v->array.items[i].ptr) {
return -1;
}
item_digits = snprintf(tmp, sizeof(tmp), "%u", (unsigned)v->array.items[i].len);
if (item_digits <= 0) {
return -1;
}
if (checked_size_add(1, (size_t)item_digits, &item_len) < 0 ||
checked_size_add(item_len, 2, &item_len) < 0 ||
checked_size_add(item_len, (size_t)v->array.items[i].len, &item_len) < 0 ||
checked_size_add(item_len, 2, &item_len) < 0 ||
checked_size_add(t, item_len, &t) < 0) {
return -1;
}
}
len = t;
break;
}
default:
return -1;
}
*out_len = len;
@@ -324,33 +369,37 @@ int kvs_protocol(struct conn* conn){
resp_len = resp_build_value(&val, response, sizeof(response));
if (resp_len < 0) {
size_t resp_need = 0;
uint8_t *resp_heap = NULL;
if (resp_value_encoded_len(&val, &resp_need) < 0) {
return -1;
}
resp_heap = (uint8_t *)kvs_malloc(resp_need);
if (!resp_heap) {
return -1;
}
resp_len = resp_build_value(&val, resp_heap, resp_need);
if (resp_len < 0 ||
chain_buffer_append(&conn->wbuf, resp_heap, (size_t)resp_len) < 0) {
free(resp_heap);
return -1;
}
free(resp_heap);
resp_len = 0;
}
}
out_len += (size_t)resp_len;
// __completed_cmd(request, consumed, 0);
size_t resp_need = 0;
uint8_t *resp_heap = NULL;
if (resp_value_encoded_len(&val, &resp_need) < 0) {
resp_value_release(&val);
return -1;
}
resp_heap = (uint8_t *)kvs_malloc(resp_need);
if (!resp_heap) {
resp_value_release(&val);
return -1;
}
resp_len = resp_build_value(&val, resp_heap, resp_need);
if (resp_len < 0 ||
chain_buffer_append(&conn->wbuf, resp_heap, (size_t)resp_len) < 0) {
free(resp_heap);
resp_value_release(&val);
return -1;
}
free(resp_heap);
resp_len = 0;
}
}
out_len += (size_t)resp_len;
resp_value_release(&val);
// __completed_cmd(request, consumed, 0);
consumed += len;
}