Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions include/kvspace/kvspace.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,23 @@ void kvspaceClose(void *h);
* 调用方不得 free。resolve=1 穿透 link。key 不存在/空值 → *out=NULL、*out_len=0、返回 0。 */
int kvspaceGet(void *h, const char *key, int resolve, uint8_t **out, uint32_t *out_len);

/* ResolveRef:block_id=叶子、gen=0;parent_id=目录祖先 ART 节点,
* depth=进入该节点时 key 已消费字节数。GetByRef:gen==0 直取叶子;
* gen>0 则 block_id 为父节点、gen 为 depth,从该处续走剩余字节。
* 后端未实现父节点时 parent_id 保持 0。 */
typedef struct {
uint32_t block_id;
uint32_t gen;
uint32_t parent_id;
uint32_t depth;
} kvspaceRef_t;
int kvspaceResolveRef(void *h, const char *key, kvspaceRef_t *ref);
int kvspaceGetByRef(void *h, kvspaceRef_t *ref, const char *key_fallback,
uint8_t **out, uint32_t *out_len);
int kvspaceSetPartByRef(void *h, kvspaceRef_t *ref, const char *key_fallback,
uint32_t offset, const uint8_t *buf, uint32_t buf_len,
char *err, uint32_t err_cap);

/* 指令边界回收读借用池:VM 每条指令执行完调用一次。此后本指令内 Get/GetPart 借出的
* 指针一律失效。shm 常驻映射侧为 no-op;durable 惰性写不清池,全靠本调用回收。 */
void kvspaceReadReset(void *h);
Expand Down
36 changes: 36 additions & 0 deletions src/frontend.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ typedef struct {
int (*clear)(void *h, char *err, uint32_t err_cap);
int (*watch)(void *h, const char *key, const uint8_t *target, uint32_t target_len,
uint64_t tick_ns, uint8_t **out, uint32_t *out_len);
int (*resolveref)(void *h, const char *key, kvspaceRef_t *ref);
int (*getbyref)(void *h, kvspaceRef_t *ref, const char *key_fallback,
uint8_t **out, uint32_t *out_len);
int (*setpartbyref)(void *h, kvspaceRef_t *ref, const char *key_fallback,
uint32_t offset, const uint8_t *buf, uint32_t buf_len,
char *err, uint32_t err_cap);
} kvspace_vt;

typedef struct {
Expand Down Expand Up @@ -140,6 +146,9 @@ void *kvspaceConnect(const char *dsn) {
LOAD(clear, "kvspaceClear");
LOAD(watch, "kvspaceWatch");
#undef LOAD
*(void **)&vt->resolveref = dlsym(dl, "kvspaceResolveRef");
*(void **)&vt->getbyref = dlsym(dl, "kvspaceGetByRef");
*(void **)&vt->setpartbyref = dlsym(dl, "kvspaceSetPartByRef");

void *(*connect)(const char *) = dlsym(dl, "kvspaceConnect");
if (!connect) { free(vt); dlclose(dl); return NULL; }
Expand Down Expand Up @@ -168,6 +177,33 @@ int kvspaceGet(void *h, const char *key, int resolve, uint8_t **out, uint32_t *o
return x->vt->get(x->backend, key, resolve, out, out_len);
}

int kvspaceResolveRef(void *h, const char *key, kvspaceRef_t *ref) {
kvspace_handle *x = H(h);
if (!x->vt->resolveref) return 1;
return x->vt->resolveref(x->backend, key, ref);
}

int kvspaceGetByRef(void *h, kvspaceRef_t *ref, const char *key_fallback,
uint8_t **out, uint32_t *out_len) {
kvspace_handle *x = H(h);
if (x->vt->getbyref)
return x->vt->getbyref(x->backend, ref, key_fallback, out, out_len);
if (!key_fallback) { *out = NULL; *out_len = 0; return 0; }
return x->vt->get(x->backend, key_fallback, 0, out, out_len);
}

int kvspaceSetPartByRef(void *h, kvspaceRef_t *ref, const char *key_fallback,
uint32_t offset, const uint8_t *buf, uint32_t buf_len,
char *err, uint32_t err_cap) {
kvspace_handle *x = H(h);
if (x->vt->setpartbyref)
return x->vt->setpartbyref(x->backend, ref, key_fallback, offset, buf,
buf_len, err, err_cap);
if (err && err_cap)
snprintf(err, err_cap, "kvspace: set-part-by-ref unsupported");
return 1;
}

void kvspaceReadReset(void *h) {
kvspace_handle *x = H(h);
if (x->vt->readreset) x->vt->readreset(x->backend);
Expand Down