开发 Arrow C++ 计算模块#
本节为 Arrow C++ 计算模块的开发者提供相关信息。
行表 (Row Table)#
Arrow 中的行表以行优先 (row-major) 格式存储数据。这种格式对于涉及随机访问单行数据,以及需要频繁同时访问所有列的场景特别有用。它对于哈希表键值尤为有利,并通过优化内存访问模式和数据局部性,促进了分组和哈希连接等高效操作。
元数据#
行表由其元数据 RowTableMetadata 定义,其中包括关于其模式 (schema)、对齐方式和派生属性的信息。
模式指定了列的类型和顺序。行表中的每一行都包含按该逻辑顺序排列的各列数据(物理顺序可能有所不同;详见 行编码)。
注意
行表中不支持嵌套类型或大二进制类型的列。
从模式中导出的一个重要属性是行表是定长还是变长的。定长行表仅包含定长列,而变长行表至少包含一个变长列。这种区别决定了数据在行表中的存储和访问方式。
行表中的每一行都与 RowTableMetadata::row_alignment 字节对齐。长度非 2 的幂的定长列也与 RowTableMetadata::row_alignment 字节对齐。变长列则与 RowTableMetadata::string_alignment 字节对齐。
缓冲区布局#
与大多数 Arrow Array 类似,行表由三个缓冲区组成:
空值掩码缓冲区 (Null Masks Buffer):指示每一行中每一列的空值情况。
定长缓冲区 (Fixed-length Buffer):存储定长表中的行数据,或存储变长表中指向变长数据的偏移量。
变长缓冲区 (Varying-length Buffer)(可选):包含变长表中的行数据;对于定长表,此缓冲区不使用。
行格式#
空值掩码#
对于每一行,用连续的位序列表示该行中的每一列是否为空。每一位对应一列,1 表示值为空,0 表示值为有效。注意,这与 Array 的有效性位图(validity bitmap)逻辑相反。一行的空值掩码占用 RowTableMetadata::null_masks_bytes_per_row 字节。
定长行数据#
在定长行表中,行数据直接存储在定长缓冲区中。每一行中的所有列依次存储。值得注意的是,boolean 列比较特殊:在普通 Arrow Array 中它占用 1 位,而在行表中它占用 1 字节。变长缓冲区在这种情况下不使用。
例如,模式为 (int32, boolean) 且行为 [[7, false], [8, true], [9, false], ...] 的行表,在定长缓冲区中存储如下:
第 0 行 |
第 1 行 |
第 2 行 |
… |
|---|---|---|---|
|
|
|
… |
变长行数据的偏移量#
在变长行表中,定长缓冲区包含指向变长行数据的偏移量,变长数据单独存储在可选的变长缓冲区中。偏移量类型为 RowTableMetadata::offset_type(固定为 int64_t),指示每一行数据的起始位置。
变长行数据#
在变长行表中,变长缓冲区包含实际的行数据,数据连续存储。定长缓冲区中的偏移量指向每一行数据的起始位置。
行编码#
变长行的编码方式如下:
首先存储定长列。
接着是每个变长列的偏移量序列。每个偏移量为 32 位,指示对应变长列在行数据内的结束位置。
最后存储变长列。
例如,模式为 (int32, string, string, int32) 且行为 [[7, 'Alice', 'x', 0], [8, 'Bob', 'y', 1], [9, 'Charlotte', 'z', 2], ...] 的行表,存储如下(假设变长列为 8 字节对齐):
定长缓冲区(行偏移量)
第 0 行 |
第 1 行 |
第 2 行 |
第 3 行 |
… |
|---|---|---|---|---|
|
|
|
|
… |
变长缓冲区(行数据)
行 |
定长列 |
变长偏移量 |
变长列 |
|---|---|---|---|
0 |
|
|
|
1 |
|
|
|
2 |
|
|
|
3 |
… |
… |
… |