Apache Arrow C 扩展类型Extension Types完全指南内置扩展与自定义实现【免费下载链接】arrowApache Arrow is the universal columnar format and multi-language toolbox for fast data interchange and in-memory analytics项目地址: https://gitcode.com/GitHub_Trending/arrow3/arrow本文以 Apache Arrow C 官方 API 文档 docs/source/cpp/api/extension.rst 为骨架系统讲解 Arrow 扩展类型机制的基类设计、全局注册表以及Bool8、FixedShapeTensor、Opaque、Json、Uuid五类官方内置扩展的存储布局与序列化行为并给出基于源码接口的自定义扩展类型实现路径。读完本文你将掌握如何在 Arrow 列式数据中承载自定义语义类型如 UUID、JSON、张量并能独立实现、注册与跨语言序列化自己的扩展类型。扩展类型在 Arrow 类型系统之上叠加自定义语义Arrow 的列式格式以一组固定的物理类型int32、utf8、fixed_size_list 等承载数据。但在真实业务中往往需要表达更丰富的语义——例如这一列是 UUID、这一列是 JSON 文档、这一列是形状固定的张量。扩展类型Extension Type正是为此设计的机制它不改变底层存储布局而是在既有物理类型之上附加一层类型语义使数据既能被不了解该语义的系统当作普通 Arrow 列处理又能被了解该语义的系统以高级 API 解读。该机制自 Arrow 0.13.0 起引入见 extension_type.h 顶部注释核心思想记录在两个关键常量中extension_type.hkExtensionTypeKeyNameIPC/文件元数据中标识扩展类型的键名kExtensionMetadataKeyName携带序列化元数据的键名。基类设计ExtensionType 与 ExtensionArrayExtensionType自定义类型的抽象基类所有扩展类型都继承自arrow::ExtensionType定义于 extension_type.h它是DataType的子类type_id固定为Type::EXTENSION。子类必须实现五个纯虚方法纯虚方法职责说明extension_name()返回扩展类型的全局唯一名称用于注册表索引与 IPC 序列化标识例如arrow.uuidExtensionEquals()判断两个同类扩展实例是否相等由DataType::Equals间接调用MakeArray()把存储数组包装为扩展数组输入ArrayData输出用户自定义的ExtensionArray子类Serialize()将类型元数据序列化为字符串存储类型本身由 IPC 代码自动处理这里只序列化附加元数据Deserialize()从存储类型 序列化元数据重建类型实例读取 IPC 时被调用基类还提供一组实用方法storage_type()返回物理存储类型这是扩展类型的地基storage_id()/byte_width()/bit_width()直接透传给存储类型因此物理布局计算完全复用底层类型WrapArray()静态方法extension_type.h把普通存储数组或ChunkedArray直接包装为扩展数组无需拷贝数据。ExtensionArray扩展数据的数组视图arrow::ExtensionArrayextension_type.h继承自Array持有storage_底层存储数组引用。构造方式有两种直接由携带正确扩展类型的ArrayData构造或由类型 存储数组构造。关键成员extension_type()返回扩展类型指针内部做了checked_caststorage()返回物理存储数组。从源码结构可以推断扩展数组本质上不复制数据只提供语义视图因此创建扩展列的开销极小。全局注册表让扩展类型可被跨系统识别为了让反序列化方如读取 IPC 文件的其他进程能根据扩展名找到对应的类型类Arrow 提供了全局注册表机制extension_type.hExtensionTypeRegistry::GetGlobalRegistry()获取全局单例注册表RegisterExtensionType()注册扩展类型名称必须全局唯一线程安全UnregisterExtensionType()按名称注销未知名称返回错误GetExtensionType()按名称查询未找到返回nullptr线程安全。实际开发中模块加载时应注册自定义类型读取包含扩展类型列的 IPC 数据前也必须先完成注册否则无法解析。官方内置扩展类型逐一解析Arrow 在 cpp/src/arrow/extension/ 目录下提供了五个开箱即用的扩展类型全部列于官方 API 文档 extension.rst 中。Bool8Type / Bool8Array8 位布尔扩展名arrow.bool8见 bool8.h存储类型int8见 bool8.h语义标准 Arrow 布尔列每值占用 1 bit位图而 Bool8 为每值分配 8 bit是一种按字节对齐的布尔替代表示适合对位操作不友好的计算路径。序列化Serialize()返回空字符串无附加元数据Deserialize()会校验存储类型必须是INT8、序列化数据必须为空bool8.cc。使用入口arrow::extension::bool8()工厂函数返回类型实例Bool8Type::Make()返回ResultDataType。FixedShapeTensorType / FixedShapeTensorArray定形张量这是最具计算价值的内置扩展也是 Arrow 官方规范中的 canonical 扩展类型见 fixed_shape_tensor.h 注释。扩展名arrow.fixed_shape_tensor存储类型fixed_size_list(value_type, size)即每个元素是一个定长列表size为所有维度元素个数之积fixed_shape_tensor.h。构造参数fixed_shape_tensor.hvalue_type张量元素类型如 float、int64size单个张量的元素总数shape各维度大小向量permutation可选逻辑维度到物理内存布局的置换映射dim_names可选维度名称按物理顺序排列。派生属性ndim()张量维度数shape长度shape()/value_type()/permutation()/dim_names()对应构造参数strides()各维度相邻元素间的字节偏移在提供置换时由置换后的形状计算得出fixed_shape_tensor.h。张量互转能力FixedShapeTensorArray::FromTensor()从arrow::Tensor创建数组取 Tensor 的第一维作为数组元素个数、剩余维度作为单个张量形状若 Tensor 携带 strides 则据此推断维度置换否则假定行主序fixed_shape_tensor.hFixedShapeTensorType::MakeTensor()从ExtensionScalar重建Tensor按置换还原形状与维度名fixed_shape_tensor.h。序列化Serialize()输出 JSON 对象包含shape数组以及可选的permutation、dim_namesfixed_shape_tensor.ccDeserialize()要求存储类型必须是FIXED_SIZE_LIST并从中反解value_typefixed_shape_tensor.cc。相等性判定ExtensionEquals()比较存储类型、shape、dim_names并把空置换与恒等置换视为等价fixed_shape_tensor.cc。仓库另提供 variable_shape_tensor.h 作为变长张量类型的参考实现相关测试见 tensor_extension_array_test.cc。JsonExtensionType可变长 JSON扩展名arrow.json见 json.h存储类型默认utf8()通过构造函数可显式指定IsSupportedStorageType()限定了合法存储类型仅为STRING、STRING_VIEW、LARGE_STRINGjson.cc。语义以 UTF-8 编码承载可变长 JSON 文档不校验 JSON 合法性仅提供类型语义标注。序列化Serialize()返回空字符串Deserialize()直接以传入的存储类型重建实例json.cc。相等性要求扩展名相同且存储类型Equalsjson.cc。使用入口arrow::extension::json()工厂函数可传存储类型参数默认 utf8json.h。测试覆盖见 json_test.cc。OpaqueType / OpaqueArray外部系统的类型占位扩展名arrow.opaque见 opaque.h语义用于承载来自外部通常非 Arrow系统、无法被 Arrow 解释的类型数据例如数据库厂商自定义类型的原始字节opaque.h。构造参数opaque.hstorage_type底层存储类型若没有数据应为arrow::nulltype_name外部系统中该类型的名称vendor_name外部系统的名称。访问器type_name()与vendor_name()分别返回两个元数据字符串。序列化Serialize()使用 simdjson 写出{type_name: ..., vendor_name: ...}JSON 对象opaque.ccDeserialize()反向解析并重建opaque.cc。ToString()输出形如extensionarrow.opaque[storage_type..., type_name..., vendor_name...]的可读文本opaque.cc。测试覆盖见 opaque_test.cc。UuidType / UuidArrayUUID 列扩展名arrow.uuid见 uuid.h存储类型fixed_size_binary(16)uuid.h即每个 UUID 恰好 16 字节。语义采用大端表示法存储 UUIDArrow 本身不解释字节内容也不要求或保证特定 UUID 版本uuid.h。IsSupportedStorageType()用于校验存储类型合法性。序列化Serialize()返回空字符串无附加元数据Deserialize()校验存储类型后返回UuidType实例uuid.h。使用入口arrow::extension::uuid()工厂函数。内置扩展一览表扩展类Type扩展数组类扩展名存储类型附加元数据Bool8TypeBool8Arrayarrow.bool8int8无FixedShapeTensorTypeFixedShapeTensorArrayarrow.fixed_shape_tensorfixed_size_list(value_type, size)shape、permutation、dim_namesJsonExtensionTypeExtensionArrayarrow.jsonutf8/string_view/large_string无OpaqueTypeOpaqueArrayarrow.opaque任意通常 binarytype_name、vendor_nameUuidTypeUuidArrayarrow.uuidfixed_size_binary(16)无注文档 extension.rst 中 Type 与 Array 分别成节列出JsonExtensionType的MakeArray()直接返回通用ExtensionArrayjson.cc因此 Array 节中未单列 Json 数组类。自定义扩展类型的实现路径参考内置实现的接口约束extension_type.h实现一个自定义扩展类型通常需要以下步骤继承ExtensionType在构造函数中传入物理存储类型作为storage_type实现extension_name()返回全局唯一的字符串标识实现Serialize()/Deserialize()无附加元数据时返回空串并在Deserialize中校验有元数据时参考 Opaque 与 FixedShapeTensor 的 simdjson 写法序列化为 JSON实现ExtensionEquals()先比较extension_name()再比较存储类型与元数据实现MakeArray()对ArrayData做类型断言后返回自定义的ExtensionArray子类参考 bool8.cc提供工厂函数返回shared_ptrDataType如bool8()、uuid()的写法注册程序启动时调用RegisterExtensionType()注册读取含扩展列的 IPC 数据前确保已注册。单元测试方面可参照仓库中 bool8_test.cc、uuid_test.cc 等测试文件覆盖相等性比较、序列化往返、数组包装等场景。扩展类型的适用场景与边界从源码可以确认以下几点使用边界存储零拷贝扩展类型不改变存储布局WrapArray与MakeArray均只是视图包装物理数据与普通 Arrow 列完全一致跨系统兼容不了解扩展语义的系统仍可按底层存储类型正常读写该列了解扩展语义的系统通过GetExtensionType()查找注册表后即可按高级 API 消费序列化范围IPC 代码自动处理存储类型Serialize()只负责附加元数据因此附加元数据应保持精简合法性校验Deserialize()中对存储类型的强校验如 Bool8 要求 INT8、FixedShapeTensor 要求 FIXED_SIZE_LIST保证了反序列化的安全性。总结Apache Arrow C 的扩展类型机制以ExtensionType/ExtensionArray为基座、全局注册表为桥梁在不改动列式存储布局的前提下为 UUID、JSON、定形张量、外部系统类型等自定义语义提供了标准化承载方案。官方文档 extension.rst 列出的五个内置扩展Bool8、FixedShapeTensor、Opaque、Json、Uuid覆盖了从布尔压缩表示、多维张量到外部类型占位的典型场景开发者亦可遵循同一套虚接口轻松扩展出自己的类型并借助 IPC 序列化让扩展类型在 Arrow 生态各语言绑定间自由流转。【免费下载链接】arrowApache Arrow is the universal columnar format and multi-language toolbox for fast data interchange and in-memory analytics项目地址: https://gitcode.com/GitHub_Trending/arrow3/arrow创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考