Reprint Notice(转载提示):本文转载自 https://lance.org/format/file/encoding/。 原文标题:Lance Encoding Strategy。 原文语言:English。本文为中文翻译版;英文原文将作为 content_en 同步保留。Lance 编码策略 编码策略定义了“数组数据如何被编码到磁盘页(disk page)”。相比文件格式本身,编码策略演进得更快。旧版编码策略 0.1 与 2.0 编码策略已经不再维护文档。它们与后续版本差异很大,展开细讲会偏离本文重点。术语 Array 是值的序列;array 的 data type 决定这些值的语义解释。Layout 是把 array 编码成一组 buffer 和 child array 的方式。Buffer 是连续字节序列。Encoding 描述“数据语义如何映射到 layout”;Encoder 则负责把数据从一种 layout 转换到另一种 layout。 Data type 与 layout 是正交概念。同一个整数数组,可能被编码成两种完全不同但语义等价的 layout。 Multiple Encodings数据类型(Data Types) Lance 的数据类型采用 Arrow 类型系统的一个子集。需要注意:Arrow data type 同时承担“类型”和“编码”两层含义。 写入阶段,Lance 经常会对 Arrow type 做归一化。例如 string 与 large string 可能最终走同一条变长(variable-width)编码路径。实际上,大多数类型最终会落在两条通用路径上: 一条是定长(fixed-width),一条是变长(variable-width,支持 32-bit 与 64-bit offsets)。 读取阶段,Arrow data type 会决定目标编码。例如 string 与 large string 可能以同一 layout 存储;但读取时会根据 Arrow type 决定返回给用户的 offset 宽度。输出 Arrow type 不要求与输入 Arrow type 完全一致:例如,写入时使用 large string,读取时返回 string,是允许的。搜索缓存(Search Cache) Search cache 是 Lance 文件读取器的关键组件。随机访问需要先定位数据在文件中的物理位置,这依赖若干信息:列使用的 encoding、page 位置,以及其他辅助索引信息。它们统称为 search cache,底层通常是一个基础 LRU cache。 我们把“把这些索引信息装载到 search cache”这一阶段称为 initialization phase。其开销默认假设可在 reader 生命周期内被摊销。 做全表扫描(即非随机访问)时,应尽量绕开 search cache,某些情况下甚至可完全不加载。我们仍然要优化冷扫描(cold scan),因为 initialization phase 在很多实际场景中并不会被充分摊销。结构编码(Structural Encoding) 编码一个数组时,第一步是确定它的 structural encoding。Structural encoding 会把数据切分成可独立解码的更小单元,并负责编码“结构信息”(如 struct validity、list validity、list offsets),通常通过 repetition levels 与 definition levels 表达。 Structural encoding 确实不简单。但它的目标也很明确:把与 I/O 调度相关的复杂性抽离出来,让压缩库专注压缩本身。这样既能保持压缩 trait 简洁,也不牺牲随机访问能力。 Structural encoding 的类型不多。它由 PageLayout message 描述,是编码层的顶层 message。message PageLayout { oneof layout { // A layout used for pages where the data is small MiniBlockLayout mini_block_layout = 1; // A layout used for pages where all (visible) values are the same scalar value or null. ConstantLayout constant_layout = 2; // A layout used for pages where the data is large FullZipLayout…