xvalue 改为 64 字节定长 head (#329) - #351
carsontung666 wants to merge 1 commit into
Conversation
3c3dd2e to
d6cd101
Compare
回归确证:本 PR 让 test-fs 从
|
| 分支 | test-fs | test-shm |
|---|---|---|
| master | PASS:214 FAIL:3 | PASS:213 FAIL:4 |
| 本 PR | PASS:0 FAIL:217 | fail |
本地已复现:bin/kvlang tutorial/01-basics/hello.kv → 反复输出 kvlang: vthread 1 错误 rc=-1 :(错误信息为空)。同一份代码在 master 上正常输出 hello kvlang。
二分定位:问题只在 runtime/src/xvalue.c
| 实验 | C 侧 xvalue.c |
Rust 侧 engine.rs |
结果 |
|---|---|---|---|
| A | 本 PR(box64) | master | ❌ 失败 |
| B | master | 本 PR | ✅ 通过 |
所以 engine.rs 的改动单独存在时无害,触发点是 C 侧的 box64 编码器。
根因:box64 的字节 0–1 被 kvspace 当成 headlen
kvlangXvalueEncodeBox() 里 buf[0] = 0(硬编码)、buf[1] = storetype。而写值的路径 runtime/src/kvspace.c:529 用的是 kvspace 的 kvspaceDecodeHead,它按旧布局读 headlen = data[0] | data[1] << 8:
C rwir 产出的值: len=69, byte0=0, byte1(storetype)=2
kvspace 旧布局算 headlen = data[0] | data[1]<<8 = 512 (实际 len=69)
kvspaceDecodeHead(box64 buffer) = 1 ← kvspace.c:529 据此 continue
kvspace.c:520-541 是所有 C 侧值的唯一写出口:529 行解码取 ref/storetype/ro/vid/langtype/body,再交给 kvspaceWriteInPlace/NewPlace 由 kvspace 重建 head。现在第 529 行拿到 1(解码失败)→ 走 continue:
kvspaceHead_t h;
/* Skip only if head decode fails. Empty langtype is still a valid Ptr. */
if (kvspaceDecodeHead(v->data, v->len, &h) != 0)
continue; // ← 静默丢弃,值根本没写进 kvspace于是 C rwir 产出的每一个值都被静默丢弃,下游全部读到空 → rc=-1 且 msg 为空 → 217 个用例全挂。
这不是「漏改一处」
唯一认识 box64 的解码器 kvlangXvalueDecodeHeadRaw 是 static(xvalue.c:224),跨翻译单元根本调不到。也就是说 kvspace.c:529 和 rwir_func.c:146 这两处直接调 kvspaceDecodeHead 的地方,在当前设计下没有修好的可能。
同一个 PR 里现在并存两份 head codec:
- kvspace 的
kvspaceDecodeHead(head 的权威定义,见kvspace.h顶部注释) - 本 PR 的
looks_head64()/decode_head64()
写方换了格式、读方只改了一部分,剩下的静默失败。head 的 codec 属于 kvspace 的职责(#329 目前仍是 OPEN RFC),建议先确认格式归属再动。
另有两处确认存在,但不是本次全挂的触发点
1. kind id 表错位(差 4 位)
写方 xvalue.c 的 h64_kind_names[] 里 FLOAT32, FLOAT64 之后是 FLOAT16, BFLOAT16, FLOAT8_E4M3, FLOAT8_E5M2,所以 char/utf32 落在 16(实测 kid=16)。读方 engine.rs:124-128 写的是:
12 => "char/utf32", // 写方此处是 FLOAT16
13 => "char/utf8", // BFLOAT16
14 => "char/ascii", // FLOAT8_E4M3我单独把 12/13/14 改成 16/17/18 重跑,hello.kv 仍然挂 —— 它不是本次全挂的原因,但仍然是错的:所有 char/* 值会落进 _ => ""。
顺带一提,runtime_internal.h:239 已经有权威的 runtime id 表:
enum { KVLANG_LT_UNKNOWN = 0, KVLANG_LT_NONE, KVLANG_LT_BOOL, ...
KVLANG_LT_FLOAT64, KVLANG_LT_CHAR_UTF32, ... };
int kvlangLangTypeId(const char *s, size_t len);
const char *kvlangLangTypeKind(int id);本 PR 没有复用它,而是另造了 h64_kind_names[],又在 engine.rs 里硬编码了第三份。三张表三种编号,建议从 KVLANG_LT_* 单向导出。
2. 同文件两种格式并存 + 格式嗅探
| 构造器 | 走的编码路径 | 实测长度 |
|---|---|---|
kvlangXvalueNewTlv() |
box64 | 69 |
kvlangXvalueNewTlvDims() |
kvspaceTlvEncode(旧格式) |
36 |
同一个文件里两个构造器写两种格式,读方只能靠 looks_head64() 猜。格式应当自描述,不宜靠启发式判定。
以上定位基于本地完整构建(C runtime + layout + runtime-rs,kvspace 三后端从源码编译),A/B 两组实验可复现。
|
同意定位:box64 编码器与 head codec 属于 kvspace,#329 仍是 OPEN RFC(待裁决未填)。本 PR 另造了一份 先转为 draft,等 kvspace 侧格式定案后再从 kvspace 的 codec 单向导出,不再在 runtime 里并行编解码。 |
|
#329 仍是 OPEN RFC,head codec 属于 kvspace,待裁决未填。本 PR 的 box64 编码器与 |
No description provided.