Apache Arrow nanoarrow 0.1 版本发布
已发布 2023年3月7日
作者 Apache Arrow PMC (pmc)
Apache Arrow 团队很高兴地宣布 Apache Arrow nanoarrow 0.1.0 版本发布。此初始版本涵盖了来自 6 位贡献者的 31 个已解决问题。
版本亮点
此初始版本包括以下内容
请参阅 更新日志,了解导致初始版本的详细贡献列表。
为什么选择 nanoarrow?
自 Arrow C 数据接口 和 Arrow C 流接口 推出 以来,它们获得了令人印象深刻和热烈的采用:Arrow 语言绑定不仅采用了该标准在其之间传递数据,而且越来越多的知名库,如 GDAL 和 DuckDB,也使用该标准来提高性能并提供 ABI 稳定的表格输入和输出接口。
GDAL 和 DuckDB 幸运地拥有勤奋且具有前瞻性思维的维护者,他们有动力提供对 Arrow C 数据和流接口的支持,即使这样做需要深入了解接口及其所基于的列式规范。
nanoarrow 的愿景是,库或应用程序实现基于 Arrow 的接口应该很简单:如果库使用或生成表格数据,Arrow 应该是开发人员首先考虑的地方。开发人员不必熟悉列式规范的细节,也不必承担任何构建时依赖项即可入门。
Arrow 数据库连接 (ADBC) 规范就是这样一个项目的很好的例子,它为 nanoarrow 的开发提供了强大的动力:ADBC 的核心思想是核心“驱动程序管理器”和特定于数据库的驱动程序,这些驱动程序作为独立的 C/C++/Python/R/Java/Go 项目分发。至少在 R 和 Python 中,在旨在加载到同一进程的多个包的上下文中嵌入现有的 Arrow 实现(例如,Arrow C++)具有挑战性。在撰写本文时,ADBC 包括基于 nanoarrow 的 SQLite 和 PostgreSQL 驱动程序以及基于 nanoarrow 的驱动程序验证套件。
在 C 中使用 nanoarrow
nanoarrow C 库以 两个文件(nanoarrow.h 和 nanoarrow.c) 的形式分发,可以将其复制并嵌入到现有的代码库中。这将生成一个大约 50 KB 的静态库,并在不到一秒钟的时间内构建完成。nanoarrow 提供的一些功能包括
- 创建类型、模式和元数据的助手
- 可增长缓冲区,包括自定义分配器/释放器的选项。
- 位图(即位打包布尔值)实用程序
- 一个 从缓冲区构建数组的 API
- 一个 逐元素构建数组的 API
- 一个 从现有数组中逐元素提取元素的 API。
例如,可以逐元素构建一个整数数组
#include "nanoarrow.h"
int make_simple_array(struct ArrowArray* array_out, struct ArrowSchema* schema_out) {
struct ArrowError error;
array_out->release = NULL;
schema_out->release = NULL;
NANOARROW_RETURN_NOT_OK(ArrowArrayInitFromType(array_out, NANOARROW_TYPE_INT32));
NANOARROW_RETURN_NOT_OK(ArrowArrayStartAppending(array_out));
NANOARROW_RETURN_NOT_OK(ArrowArrayAppendInt(array_out, 1));
NANOARROW_RETURN_NOT_OK(ArrowArrayAppendInt(array_out, 2));
NANOARROW_RETURN_NOT_OK(ArrowArrayAppendInt(array_out, 3));
NANOARROW_RETURN_NOT_OK(ArrowArrayFinishBuilding(array_out, &error));
NANOARROW_RETURN_NOT_OK(ArrowSchemaInitFromType(schema_out, NANOARROW_TYPE_INT32));
return NANOARROW_OK;
}
类似地,可以从数组中提取元素
#include <stdio.h>
#include "nanoarrow.h"
int print_simple_array(struct ArrowArray* array, struct ArrowSchema* schema) {
struct ArrowError error;
struct ArrowArrayView array_view;
NANOARROW_RETURN_NOT_OK(ArrowArrayViewInitFromSchema(&array_view, schema, &error));
if (array_view.storage_type != NANOARROW_TYPE_INT32) {
printf("Array has storage that is not int32\n");
}
int result = ArrowArrayViewSetArray(&array_view, array, &error);
if (result != NANOARROW_OK) {
ArrowArrayViewReset(&array_view);
return result;
}
for (int64_t i = 0; i < array->length; i++) {
printf("%d\n", (int)ArrowArrayViewGetIntUnsafe(&array_view, i));
}
ArrowArrayViewReset(&array_view);
return NANOARROW_OK;
}
在 C++、R 和 Python 中使用 nanoarrow
认识到许多 nanoarrow 可能有用的项目将可以使用比 C 更高级别的运行时,因此有一些实验可以为这些用户提供一组最小的有用工具。
对于 C++ 项目,实验性的 “nanoarrow.hpp” 接口为 nanoarrow C 对象提供了类似于 unique_ptr
的包装器,以减少使用 nanoarrow API 的冗长性。例如,之前的 print_simple_array()
实现将折叠为
#include <stdio.h>
#include "nanoarrow.hpp"
int print_simple_array2(struct ArrowArray* array, struct ArrowSchema* schema) {
struct ArrowError error;
nanoarrow::UniqueArrayView array_view;
NANOARROW_RETURN_NOT_OK(ArrowArrayViewInitFromSchema(array_view.get(), schema, &error));
NANOARROW_RETURN_NOT_OK(ArrowArrayViewSetArray(array_view.get(), array, &error));
for (int64_t i = 0; i < array->length; i++) {
printf("%d\n", (int)ArrowArrayViewGetIntUnsafe(array_view.get(), i));
}
return NANOARROW_OK;
}
对于 R 包,实验性的 R 绑定 提供了 R 向量和 Arrow 数组之间有限的转换集,这样具有基于 Arrow 接口的库的 R 绑定就不需要自己提供此行为。其他功能包括打印和验证 C 数据和 C 流接口核心的 C 结构的内容,以方便开发与基于 Arrow 的库的绑定。
# install.packages("remotes")
remotes::install_github("apache/arrow-nanoarrow/r", build = FALSE)
library(nanoarrow)
as_nanoarrow_array(1:5)
#> <nanoarrow_array int32[5]>
#> $ length : int 5
#> $ null_count: int 0
#> $ offset : int 0
#> $ buffers :List of 2
#> ..$ :<nanoarrow_buffer_validity[0 b] at 0x0>
#> ..$ :<nanoarrow_buffer_data_int32[20 b] at 0x135d13c28>
#> $ dictionary: NULL
#> $ children : list()
nanoarrow 存储库中存在一个 Python 包框架,一旦 C 库接口稳定下来,可能会添加更多功能。
试用 nanoarrow
对于任何有兴趣试用 nanoarrow 的人来说,最简单的入门方法是从 GitHub 克隆 nanoarrow 存储库 并构建/修改 最小的 CMake 构建示例。对于应用用法,可以参考 ADBC SQLite 驱动程序 和 ADBC PostgreSQL 驱动程序。
贡献者
除了 Apache Arrow 开发人员邮件列表的宝贵建议和支持外,此初始版本还包含来自 6 位贡献者的贡献。
$ git shortlog -sn 8339114637919b661c1c8fae6764ceed532c935e..apache-arrow-nanoarrow-0.1.0 | grep -v "GitHub Actions"
100 Dewey Dunnington
7 David Li
2 Dirk Eddelbuettel
1 Dane Pitkin
1 Jonathan Keane
1 Joris Van den Bossche