这件事在解决什么
今天 kvspace 里每个 XValue 的 head,开头都塞着一个叫 xkind 的字节,它把值硬分成五类(None / Ptr / ExtValue / DefKindexpr / RealValue)。问题是这一个字节同时在管三件本来不相干的事:值存在哪(内联?指针?扩展世界?)、物理上长什么样(一个标量?一片定长数组?一张成员名表?)、以及它的语义类型是什么。三件事挤在一个枚举里,任何一件想扩展都得回来动这张五分类表——这就是为什么加 struct、加 def 族、加多维数组时 head 一直别扭。
spec(02-kvspace模型/06-XValueHead线格式、03-类型系统/19-25)已经把答案敲定:把这一个字节拆成三根互相独立的轴——
- ref:值存在哪。
0=内联、1=指针(body 是目标 key)、2=@ext(body 是扩展世界定位符)。
- storetype:body 物理上怎么摆,codec 只认它来分派。NONE / ATOM / ARRAYND / index / extindex / def 族。
- langtype:完整的 kindexpr 串,语义类型的唯一真相,能承载
[dims]、map 的 key·value、struct 原型路径、def 族签名这些高级定义。
三根轴各管各的,谁要扩展都不用惊动另外两根。这就是这个 issue 要落的地。
目标 wire(已冻结,来自 spec)
head = [headlen u16 LE][ref u8][storetype u8][ro u8][vid u32 LE][body_len u32 LE]
[storetype 物理字段(变长,按 storetype)][langtype kindexpr 串(占到 headlen 为止)]
body = [body_len B raw]
和今天最大的三个不同:
- head 开头多了
headlen u16,body 从偏移 headlen 开始——不用再靠数字段推。
[dims] 从 kindexpr 串里搬出来,进 ARRAYND 的物理字段(ndim u8 + dims[ndim] u32);langtype 串里仍写 [dims],两边由 codec 保证同步。
- codec 从「按 base kind 串匹配」改成「按 storetype 字节分派」。
旧 xkind → 新 (ref, storetype) 映射(迁移基准,锁定)
| 旧 xkind |
新 ref |
新 storetype |
| NONE(0) |
0 |
NONE |
| PTR(1) |
1 |
目标的 storetype |
| EXTVALUE(2) |
2(@ext) |
按目标 |
| DEFKINDEXPR(3) |
0 |
def 族(见 22-storetype-def族与签名行) |
| REALVALUE(4) |
0 |
ATOM / ARRAYND / index / extindex(按 kind) |
怎么分阶段做
严格自底向上,一层测通再上移。wire 和 C ABI 双破坏,所以 P1 不打 tag,P2/P3 一律不许动——否则新旧格式撞进同一个 redis/shm 就是一地碎。
P1 · kvspace 家族(3 repo,原子同 tag)
契约面先定死,两个后端逐字节跟上。
P2 · kvlang layout(o0 编译器)
P3 · kvlang runtime(C + Rust 同步,一个 gate)
两个 runtime 读同一个 kvspace,必须同格式落地,不能一新一旧。
P3 联合验收:kvlang tutorial 全量三后端回归 + runtime-c 与 runtime-rs 交叉读同一 kvspace 的 key byte-identical,子8/子9 同时全绿才算完。
随手清掉的过时注释(A1)
kvspace-c/.claude/CLAUDE.md 里还写着旧的 [kind_len][kind]… TLV —— P1 改。
kvspace-durable/src/xvalue.rs 顶部 kindexp TLV 注释 —— P1 改。
kvlang/layout/src/code.rs 头注释 —— P2 改。
破坏性与回归口径
这件事在解决什么
今天 kvspace 里每个 XValue 的 head,开头都塞着一个叫
xkind的字节,它把值硬分成五类(None / Ptr / ExtValue / DefKindexpr / RealValue)。问题是这一个字节同时在管三件本来不相干的事:值存在哪(内联?指针?扩展世界?)、物理上长什么样(一个标量?一片定长数组?一张成员名表?)、以及它的语义类型是什么。三件事挤在一个枚举里,任何一件想扩展都得回来动这张五分类表——这就是为什么加 struct、加 def 族、加多维数组时 head 一直别扭。spec(
02-kvspace模型/06-XValueHead线格式、03-类型系统/19-25)已经把答案敲定:把这一个字节拆成三根互相独立的轴——0=内联、1=指针(body 是目标 key)、2=@ext(body 是扩展世界定位符)。[dims]、map 的key·value、struct 原型路径、def 族签名这些高级定义。三根轴各管各的,谁要扩展都不用惊动另外两根。这就是这个 issue 要落的地。
目标 wire(已冻结,来自 spec)
和今天最大的三个不同:
headlen u16,body 从偏移headlen开始——不用再靠数字段推。[dims]从 kindexpr 串里搬出来,进 ARRAYND 的物理字段(ndim u8 + dims[ndim] u32);langtype 串里仍写[dims],两边由 codec 保证同步。旧 xkind → 新 (ref, storetype) 映射(迁移基准,锁定)
22-storetype-def族与签名行)怎么分阶段做
严格自底向上,一层测通再上移。wire 和 C ABI 双破坏,所以 P1 不打 tag,P2/P3 一律不许动——否则新旧格式撞进同一个 redis/shm 就是一地碎。
P1 · kvspace 家族(3 repo,原子同 tag)
契约面先定死,两个后端逐字节跟上。
P2 · kvlang layout(o0 编译器)
P3 · kvlang runtime(C + Rust 同步,一个 gate)
两个 runtime 读同一个 kvspace,必须同格式落地,不能一新一旧。
随手清掉的过时注释(A1)
kvspace-c/.claude/CLAUDE.md里还写着旧的[kind_len][kind]…TLV —— P1 改。kvspace-durable/src/xvalue.rs顶部 kindexp TLV 注释 —— P1 改。kvlang/layout/src/code.rs头注释 —— P2 改。破坏性与回归口径