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
75 changes: 36 additions & 39 deletions src/durable_abi.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ typedef struct {
uint64_t body_cap;
} kvspaceHead_t;

/* 固定 8 字节 head → 元数据(langtype 不在 head,见 kvspaceGetHead attr key)。 */
/* 固定 8 字节 head → 元数据(langtype 在 body 尾 @8+len,见 kvspaceGetHead)。 */
static int from_wire_head(const uint8_t *d, uint32_t total, kvspaceHead_t *out) {
if (!out || !d || total < KVSPACE_XVALUE_HEAD_LEN)
return 1;
Expand Down Expand Up @@ -204,32 +204,20 @@ int kvspaceGetHead(void *h, const char *key, kvspaceHead_t *out) {
return 1;
if (from_wire_head(d, (uint32_t)total, out) != 0)
return 1;
/* langtype 在 x‥langtype attr key:值是字符串 XValue(8 字节 head + body=明文
类型串),从 body 取 out->langtype。attr 缺失/非 wire 串/空 body =
None/无类型(普通值也走 attr,由上层创建时写)。 */
char ltkey[1028];
int ltn = snprintf(ltkey, sizeof ltkey, "%s\xE2\x80\xA5" "langtype", key);
if (ltn < 0 || ltn >= (int)sizeof ltkey)
return 1;
int32_t ltl = 0;
uint8_t *ltd = kvspaceShmGet((kvspace_t *)h, ltkey, 0, &ltl);
if (ltd && ltl >= (int32_t)KVSPACE_XVALUE_HEAD_LEN) {
kvspaceXvalueHead lth;
memcpy(&lth, ltd, sizeof lth);
uint64_t body_len = kvspaceXvalueHeadLen(&lth);
if (lth.storetype <= KVSPACE_XVALUE_ST_EXT &&
lth.ptr <= KVSPACE_XVALUE_PTR_EXT &&
body_len <= (uint64_t)ltl - KVSPACE_XVALUE_HEAD_LEN) {
size_t take = body_len < (uint64_t)sizeof out->langtype - 1
? (size_t)body_len
: (size_t)sizeof out->langtype - 1;
memcpy(out->langtype, ltd + KVSPACE_XVALUE_HEAD_LEN, take);
out->langtype[take] = 0;
out->langtype_len = (int32_t)take;
return 0;
}
/* langtype 在 attr 区 tag=1 记录(@8+len 自描述);无记录 = 无类型。 */
uint64_t blen = (uint64_t)out->body_len;
const uint8_t *lt = NULL;
uint16_t ltl = kvspaceXvalueHeadLangtype(d, blen, &lt);
if (lt && ltl > 0) {
size_t take = (size_t)ltl < (uint64_t)sizeof out->langtype - 1
? (size_t)ltl
: (size_t)sizeof out->langtype - 1;
memcpy(out->langtype, lt, take);
out->langtype[take] = 0;
out->langtype_len = (int32_t)take;
} else {
out->langtype_len = 0;
}
out->langtype_len = 0;
return 0;
}

Expand All @@ -246,14 +234,15 @@ int kvspaceWriteInPlace(void *h, const char *key, int resolve,
return 0;
}

/* 新位置写:按 (ref, storetype, body_len, body_cap) 分配 box、写固定头,
* 返回 body 偏移指针。kvspace 层不写 attr key——`x‥langtype` 归属上层:
* 调用方需要类型时自写 attr key(attr 先落、x 后落 = 提交点),kvspace 只做裸写。 */
/* 新位置写:按 (ref, storetype, body_len, body_cap, langtype) 分配 box、写固定头 +
* langtype 尾部(整体单写),返回 body 偏移指针。 */
int kvspaceWriteNewPlace(void *h, const char *key, uint8_t ref,
uint8_t storetype, uint32_t body_len, uint64_t body_cap,
const char *langtype,
uint8_t **body, char *err, uint32_t err_cap) {
if (kvspaceShmWriteNewPlace((kvspace_t *)h, key, ref, storetype,
(int32_t)body_len, body_cap, body) != 0) {
(int32_t)body_len, body_cap, langtype,
body) != 0) {
if (err && err_cap)
snprintf(err, err_cap, "kvspace: write-new-place failed at %s", key);
return 1;
Expand Down Expand Up @@ -371,50 +360,58 @@ int kvspaceNewPtr(const char *target_kindexpr, const char *target,
uint8_t **out, uint32_t *out_len) {
if (!target_kindexpr || !target || !out || !out_len)
return 1;
/* `any` 不是类型名(空 kindexpr = 不约束)。 */
if (strcmp(target_kindexpr, "any") == 0)
return 1;
uint8_t *value = NULL;
uint64_t total = 0;
if (kvspaceXvalueHeadNewPtr((const uint8_t *)target,
(uint32_t)strlen(target), &value, &total) != 0)
(uint32_t)strlen(target), target_kindexpr,
&value, &total) != 0)
return 1;
return finish(value, total, out, out_len);
}

int kvspaceNewChar(const uint8_t *bytes, uint32_t len, uint8_t **out, uint32_t *out_len) {
int kvspaceNewChar(const uint8_t *bytes, uint32_t len, const char *langtype,
uint8_t **out, uint32_t *out_len) {
uint8_t *value = NULL;
uint64_t total = 0;
int rc = kvspaceXvalueHeadNewSlack(bytes, len, len, &value, &total);
int rc = kvspaceXvalueHeadNewSlack(bytes, len, len, langtype, &value, &total);
return rc == 0 ? finish(value, total, out, out_len) : 1;
}

int kvspaceNewBool(uint8_t v, uint8_t **out, uint32_t *out_len) {
int kvspaceNewBool(uint8_t v, const char *langtype,
uint8_t **out, uint32_t *out_len) {
uint8_t b = v ? 1 : 0;
uint8_t *value = NULL;
uint64_t total = 0;
int rc = kvspaceXvalueHeadNewScalar(KVSPACE_XVALUE_ST_SHORT, &b, 1,
int rc = kvspaceXvalueHeadNewScalar(KVSPACE_XVALUE_ST_SHORT, &b, 1, langtype,
&value, &total);
return rc == 0 ? finish(value, total, out, out_len) : 1;
}

int kvspaceNewInt64(int64_t v, uint8_t **out, uint32_t *out_len) {
int kvspaceNewInt64(int64_t v, const char *langtype,
uint8_t **out, uint32_t *out_len) {
uint8_t raw[8];
for (int i = 0; i < 8; i++)
raw[i] = (uint8_t)((uint64_t)v >> (8 * i));
uint8_t *value = NULL;
uint64_t total = 0;
int rc = kvspaceXvalueHeadNewScalar(KVSPACE_XVALUE_ST_SHORT, raw, 8,
int rc = kvspaceXvalueHeadNewScalar(KVSPACE_XVALUE_ST_SHORT, raw, 8, langtype,
&value, &total);
return rc == 0 ? finish(value, total, out, out_len) : 1;
}

int kvspaceNewFloat64(double v, uint8_t **out, uint32_t *out_len) {
int kvspaceNewFloat64(double v, const char *langtype,
uint8_t **out, uint32_t *out_len) {
uint64_t bits;
memcpy(&bits, &v, sizeof bits);
uint8_t raw[8];
for (int i = 0; i < 8; i++)
raw[i] = (uint8_t)(bits >> (8 * i));
uint8_t *value = NULL;
uint64_t total = 0;
int rc = kvspaceXvalueHeadNewScalar(KVSPACE_XVALUE_ST_SHORT, raw, 8,
int rc = kvspaceXvalueHeadNewScalar(KVSPACE_XVALUE_ST_SHORT, raw, 8, langtype,
&value, &total);
return rc == 0 ? finish(value, total, out, out_len) : 1;
}
Expand Down
44 changes: 36 additions & 8 deletions src/kvspace.c
Original file line number Diff line number Diff line change
Expand Up @@ -2537,8 +2537,13 @@ static int read_value(kvspace_t *kv, uint64_t off, uint8_t **out, int32_t *ol) {
if (l > INT32_MAX)
return -1;
*out = s;
/* None = 空 body(len 0);ptr/ext 由 ptr 字段判定(值恒为叶子)。 */
*ol = (int32_t)(KVSPACE_XVALUE_HEAD_LEN + l);
/* 完整值长 = head + body + attr(attr_len:u16 @8+len 自描述;空 attr=2)。 */
if ((uint64_t)sz < KVSPACE_XVALUE_HEAD_LEN + l + 2)
return -1;
uint64_t alen = kvspaceXvalueHeadAttrLen(s, l);
if (alen < 2 || alen > (uint64_t)sz - KVSPACE_XVALUE_HEAD_LEN - l)
return -1;
*ol = (int32_t)(KVSPACE_XVALUE_HEAD_LEN + l + alen);
return 0;
}
return -1;
Expand Down Expand Up @@ -2600,8 +2605,14 @@ static art_hdr_t *resolve_fetch(kvspace_t *kv, const char *path, char *out, int
if (head_of(s, (int32_t)sz, &wire) == 0) {
uint64_t l3 = kvspaceXvalueHeadLen(&wire);
if (wire.ptr != KVSPACE_XVALUE_PTR_PTR || l3 >= (uint64_t)osz) {
/* 完整值长 = head + body + attr(attr_len @8+len 自描述)。 */
if ((uint64_t)sz < KVSPACE_XVALUE_HEAD_LEN + l3 + 2)
return NULL;
uint64_t alen = kvspaceXvalueHeadAttrLen(s, l3);
if (alen < 2 || alen > (uint64_t)sz - KVSPACE_XVALUE_HEAD_LEN - l3)
return NULL;
*raw = s;
*rl = (int32_t)(KVSPACE_XVALUE_HEAD_LEN + l3);
*rl = (int32_t)(KVSPACE_XVALUE_HEAD_LEN + l3 + alen);
*fetched = 1;
return h;
}
Expand Down Expand Up @@ -3173,7 +3184,7 @@ int kvspaceShmWriteInPlace(kvspace_t *kv, const char *key, int resolve,

int kvspaceShmWriteNewPlace(kvspace_t *kv, const char *key, uint8_t ref,
uint8_t storetype, int32_t body_len,
uint64_t body_cap,
uint64_t body_cap, const char *langtype,
uint8_t **body) {
if (!kv || !key || !body || body_len < 0)
return -1;
Expand All @@ -3197,13 +3208,13 @@ int kvspaceShmWriteNewPlace(kvspace_t *kv, const char *key, uint8_t ref,
uint8_t *value = NULL;
uint64_t total = 0;
if (kvspaceXvalueHeadReserve(storetype, (uint64_t)body_len,
body_cap, &value, &total) != 0)
body_cap, langtype, &value, &total) != 0)
return -1;
if (total > INT32_MAX) {
free(value);
return -1;
}
/* 固定头 8 字节:body 偏移恒 = 8。langtype 由调用方写 x‥langtype attr key。 */
/* 固定头 8 字节:body 偏移恒 = 8;langtype 尾部 @8+body_len 整体单写。 */
uint32_t headlen = KVSPACE_XVALUE_HEAD_LEN;
(void)ptr;
int rc = shm_set_raw(kv, key, value, (int32_t)total);
Expand Down Expand Up @@ -3630,11 +3641,28 @@ int kvspaceShmExtindex(kvspace_t *kv, const char *p, const char *ep,
snprintf(err, err_cap, "ExtIndex target missing: %s", ep);
return -1;
}
/* source 类型在 ep‥langtype attr key(明文事实源);ext 句柄同样侧写。 */
/* source 类型在 ep 值 attr 区(明文事实源);ext 句柄同样携带。 */
char lt[256];
const uint8_t *ltd = NULL;
uint16_t ltl = 0;
if (source_len >= (int32_t)KVSPACE_XVALUE_HEAD_LEN) {
kvspaceXvalueHead sh;
memcpy(&sh, source, sizeof sh);
if (sh.storetype <= KVSPACE_XVALUE_ST_EXT &&
sh.ptr <= KVSPACE_XVALUE_PTR_EXT) {
uint64_t sbody = kvspaceXvalueHeadLen(&sh);
if (sbody <= (uint64_t)source_len - KVSPACE_XVALUE_HEAD_LEN)
ltl = kvspaceXvalueHeadLangtype(source, sbody, &ltd);
}
}
if (ltl > (uint16_t)(sizeof lt - 1))
ltl = (uint16_t)(sizeof lt - 1);
memcpy(lt, ltd, ltl);
lt[ltl] = 0;
uint8_t *v = NULL;
uint64_t vl = 0;
int r = kvspaceXvalueHeadNewExt((const uint8_t *)ep, (uint32_t)strlen(ep),
&v, &vl);
lt, &v, &vl);
if (r == 0)
r = kvspaceShmSetValue(kv, p, v, (int32_t)vl);
free(v);
Expand Down
6 changes: 3 additions & 3 deletions src/kvspace_shm.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,11 @@ int kvspaceShmSetValueByRef(kvspace_t *kv, kvspaceRef_t *ref,
// 覆写);否则返回非 0。
int kvspaceShmWriteInPlace(kvspace_t *kv, const char *key, int resolve,
int32_t body_len, uint8_t **body);
// WriteNewPlace: 按 (ref, storetype, body_len) 分配新 box、写固定头、
// 维护父索引,返回 body 指针。langtype 由调用方顺写 x‥langtype attr key。
// WriteNewPlace: 按 (ref, storetype, body_len, langtype) 分配新 box、写固定头 +
// langtype 尾部(整体单写)、维护父索引,返回 body 指针。
int kvspaceShmWriteNewPlace(kvspace_t *kv, const char *key, uint8_t ref,
uint8_t storetype, int32_t body_len,
uint64_t body_cap,
uint64_t body_cap, const char *langtype,
uint8_t **body);
// ListLen: 只返回前缀下子项计数,无缓冲。
int kvspaceShmListLen(kvspace_t *kv, const char *prefix, bool expand_ext,
Expand Down
Loading
Loading