123789456ye

已AFO

一个由Rust原生类型数组向Apache Arrow Array类型转换的库

前言

刚从C++转到Rust时,总觉得Rust语法实在是太丑了
写了一段时间Rust后,发现Rust语法确实丑
不过只要能过编译,能过测试(逻辑正确),就很难出问题,这是一个很大的优点
当然,时不时要重构也是必要的代价了

作为练手任务,mt预计时间为两周,实际的实现时间大概一周多一点,感谢无敌的Claude Code
结果缝缝补补,明确需求,重构,又花了一周,难绷

设计思路

mt给的简单框架,我们需要在运行时转换,从而需要一些类型擦除和分发的代码
具体来说,我们需要实现类似以下的东西

pub trait NativeArray {
    type Item;
    type ItemRef<'r>;

    fn push(&mut self, item: Self::Item);

    fn get(&self, index: usize) -> Self::ItemRef<'_>;

    fn to_arrow_array(&self) -> arrow::Array;
}

/// Vec<i32> -> Int32Array
impl NativeArray for Vec<i32> {
    ...

    fn to_arrow_array(&self) -> arrow::Array {
        Int32Builder::new().append_slice(self.as_slice()).finish()
    }
}

pub enum DynScalar {
    Bool(bool),
    Int32(i32),
    String(String),
    Binary(Vec<u8>),
    List(Vec<DynScalar>),
}

pub struct DynNativeArray {

}

实现过程

静态部分

不过claude给的思路不太一样,它是对每一个type实现一个TypedVec,然后对这些Vec impl NativeArray 和 DynNativeArray,从而达到转换
由于arrow-rs已经对不少类型实现了Into这个trait,我们可以直接into()过去,因此静态部分实际上挺简单的,一天之内我就搓完了
基本类型直接用宏一把梭,就是需要对bool,string,binary,decimal和time类型再实现一下

动态部分

mt给的思路是用一个inner,加上自己写vtable分发来实现DynNativeArray
不过这里不是这样,而是用<Self as NativeArray>::to_arrow_array()这种神秘方法实现
要求构造时可以通过vector直接构造,所以需要DynScalar作为擦除,和dispatch代码
复杂度是不会消失的,对每种类型还是得老实写分发代码和实现trait,这里用了两天,但其实也不难

嵌套类型

按道理这个不是和前两个并列的,但是实现时是并列的,所以还是这样写
首先我们需要自己定义struct和DynScalar了,然后我们需要把前两部分的东西再写一遍
还要手写构造和转换代码,然后终于到了紧张刺激的debug环节
好在有原生的builder可以直接assert,哪里不对点哪里就完事了,这里又用了两天,完成了元素为基本类型情况下的转换
但是还有一(两)个大坑:

  1. 如何将含原生类型元素的嵌套类型转换为DynScalar?
  2. 如何使用schema(在不使用反射的情况下)转换struct?

上面的坑解决方法是这样的:
用过程宏来为编译期定义的Struct impl一个到DynScalar::Struct(HashMap<String,DynScalar>)的trait,再用函数将Vec转ArrayRef
第二步转换时是要递归的,来解决嵌套问题
好在复杂度基本上在第二步,所以这个过程宏还好
加上mt觉得要加上测试深层嵌套的代码,于是又花了两天修

然后我觉得既然都在编译期确定了Struct,可以直接一步到位,于是又花了快两天写了个直接转换的过程宏
这个就复杂多了,只能靠展开来debug,还不确定是不是都测试到了
结果发现需要在运行时确定schema和数据类型,不一定有struct,直接从HashMap转,所以上面的两个过程宏疑似白写(

Option类型

这个其实没必要并列,不过还是写一下
我花了一天把原版的全部复刻了一遍,但是我觉得太丑了
然后review的时候觉得可以套用Arrow的布局,直接把nulls和offsets(如有)从转换时计算移到自己的field里,于是又花了一天合并回去

posted @ 2025-07-16 18:01  123789456ye  阅读(21)  评论(0)    收藏  举报