在循环中创建 ArrayBuilder
Creating ArrayBuilders in a Loop
有没有办法创建 arrow::ArrayBuilder
对象的动态容器?这是一个例子
int main(int argc, char** argv) {
std::size_t rowCount = 5;
arrow::MemoryPool* pool = arrow::default_memory_pool();
std::vector<arrow::Int64Builder> builders;
for (std::size_t i = 0; i < 2; i++) {
arrow::Int64Builder tmp(pool);
tmp.Reserve(rowCount);
builders.push_back(tmp);
}
return 0;
}
这会产生 error: variable ‘arrow::Int64Builder tmp’ has initializer but incomplete type
理想情况下,我正在尝试构建一个集合来容纳各种构建器,并根据我收到的按行数据构建 table。我的猜测是这不是构建器的预期用途,但我在 Arrow 文档中找不到任何确定的内容
你的包含是什么样子的?该错误消息似乎表明您没有包含正确的文件。 arrow:Int64Builder
的完整定义在 arrow/array/builder_primitive.h
中,但您通常只需包含 arrow/api.h
即可获得所有内容。
以下为我编译:
#include <iostream>
#include <arrow/api.h>
arrow::Status Main() {
std::size_t rowCount = 5;
arrow::MemoryPool* pool = arrow::default_memory_pool();
std::vector<arrow::Int64Builder> builders;
for (std::size_t i = 0; i < 2; i++) {
arrow::Int64Builder tmp(pool);
ARROW_RETURN_NOT_OK(tmp.Reserve(rowCount));
builders.push_back(std::move(tmp));
}
return arrow::Status::OK();
}
int main() {
auto status = Main();
if (!status.ok()) {
std::cerr << "Err: " << status << std::endl;
return 1;
}
return 0;
}
您的示例的一个小改动是构建器没有复制构造函数/无法复制。所以我不得不 std::move
把它放到向量中。
此外,如果您想要一个包含许多不同类型构建器的集合,那么您可能需要 std::vector<std::unique_ptr<arrow::ArrayBuilder>>
并且您需要在堆上构建构建器。
您可能 运行 遇到的一个挑战是构建器对 Append
方法都有不同的签名(例如 Int64Builder
有 Append(long)
但 StringBuilder
有 Append(arrow::util::string_view)
)。结果 arrow::ArrayBuilder
实际上没有任何 Append
方法(如果您碰巧已经将数据作为 Arrow C++ 标量,则有一些方法采用标量)。但是,您可以通过在需要追加时转换为适当的类型来克服这个问题。
更新:
如果您真的想避免强制转换并且您提前知道架构,您可以按照...
std::vector<std::function<arrow::Status(const Row&)>> append_funcs;
std::vector<std::shared_ptr<arrow::ArrayBuilder>> builders;
for (std::size_t i = 0; i < schema.fields().size(); i++) {
const auto& field = schema.fields()[i];
if (isInt32(field)) {
auto int_builder = std::make_shared<Int32Builder>();
append_funcs.push_back([int_builder] (const Row& row) ({
int val = row.GetCell<int>(i);
return int_builder->Append(val);
});
builders.push_back(std::move(int_builder));
} else if {
// Other types go here
}
}
// Later
for (const auto& row : rows) {
for (const auto& append_func : append_funcs) {
ARROW_RETURN_NOT_OK(append_func(row));
}
}
注意:Row
是我编的,因为我不知道你的数据原来是什么格式。我还编了 isInt32
因为我不记得如何检查它了。
这里使用 shared_ptr
而不是 unique_ptr
因为你需要两个副本,一个在 lambda 的捕获中,另一个在 builders
数组中。
有没有办法创建 arrow::ArrayBuilder
对象的动态容器?这是一个例子
int main(int argc, char** argv) {
std::size_t rowCount = 5;
arrow::MemoryPool* pool = arrow::default_memory_pool();
std::vector<arrow::Int64Builder> builders;
for (std::size_t i = 0; i < 2; i++) {
arrow::Int64Builder tmp(pool);
tmp.Reserve(rowCount);
builders.push_back(tmp);
}
return 0;
}
这会产生 error: variable ‘arrow::Int64Builder tmp’ has initializer but incomplete type
理想情况下,我正在尝试构建一个集合来容纳各种构建器,并根据我收到的按行数据构建 table。我的猜测是这不是构建器的预期用途,但我在 Arrow 文档中找不到任何确定的内容
你的包含是什么样子的?该错误消息似乎表明您没有包含正确的文件。 arrow:Int64Builder
的完整定义在 arrow/array/builder_primitive.h
中,但您通常只需包含 arrow/api.h
即可获得所有内容。
以下为我编译:
#include <iostream>
#include <arrow/api.h>
arrow::Status Main() {
std::size_t rowCount = 5;
arrow::MemoryPool* pool = arrow::default_memory_pool();
std::vector<arrow::Int64Builder> builders;
for (std::size_t i = 0; i < 2; i++) {
arrow::Int64Builder tmp(pool);
ARROW_RETURN_NOT_OK(tmp.Reserve(rowCount));
builders.push_back(std::move(tmp));
}
return arrow::Status::OK();
}
int main() {
auto status = Main();
if (!status.ok()) {
std::cerr << "Err: " << status << std::endl;
return 1;
}
return 0;
}
您的示例的一个小改动是构建器没有复制构造函数/无法复制。所以我不得不 std::move
把它放到向量中。
此外,如果您想要一个包含许多不同类型构建器的集合,那么您可能需要 std::vector<std::unique_ptr<arrow::ArrayBuilder>>
并且您需要在堆上构建构建器。
您可能 运行 遇到的一个挑战是构建器对 Append
方法都有不同的签名(例如 Int64Builder
有 Append(long)
但 StringBuilder
有 Append(arrow::util::string_view)
)。结果 arrow::ArrayBuilder
实际上没有任何 Append
方法(如果您碰巧已经将数据作为 Arrow C++ 标量,则有一些方法采用标量)。但是,您可以通过在需要追加时转换为适当的类型来克服这个问题。
更新:
如果您真的想避免强制转换并且您提前知道架构,您可以按照...
std::vector<std::function<arrow::Status(const Row&)>> append_funcs;
std::vector<std::shared_ptr<arrow::ArrayBuilder>> builders;
for (std::size_t i = 0; i < schema.fields().size(); i++) {
const auto& field = schema.fields()[i];
if (isInt32(field)) {
auto int_builder = std::make_shared<Int32Builder>();
append_funcs.push_back([int_builder] (const Row& row) ({
int val = row.GetCell<int>(i);
return int_builder->Append(val);
});
builders.push_back(std::move(int_builder));
} else if {
// Other types go here
}
}
// Later
for (const auto& row : rows) {
for (const auto& append_func : append_funcs) {
ARROW_RETURN_NOT_OK(append_func(row));
}
}
注意:Row
是我编的,因为我不知道你的数据原来是什么格式。我还编了 isInt32
因为我不记得如何检查它了。
这里使用 shared_ptr
而不是 unique_ptr
因为你需要两个副本,一个在 lambda 的捕获中,另一个在 builders
数组中。