|
17 | 17 | * under the License. |
18 | 18 | */ |
19 | 19 |
|
| 20 | +#include <functional> |
20 | 21 | #include <memory> |
| 22 | +#include <mutex> |
| 23 | +#include <thread> |
21 | 24 | #include <unordered_map> |
| 25 | +#include <utility> |
| 26 | +#include <vector> |
22 | 27 |
|
23 | 28 | #include <arrow/api.h> |
24 | 29 | #include <arrow/c/bridge.h> |
25 | 30 | #include <arrow/extension/uuid.h> |
26 | 31 | #include <arrow/result.h> |
27 | 32 | #include <arrow/type_fwd.h> |
| 33 | +#include <arrow/util/config.h> |
28 | 34 | #include <arrow/util/key_value_metadata.h> |
| 35 | +#include <arrow/util/thread_pool.h> |
29 | 36 | #include <gtest/gtest.h> |
30 | 37 |
|
| 38 | +#include "iceberg/arrow/arrow_status_internal.h" |
31 | 39 | #include "iceberg/constants.h" |
| 40 | +#include "iceberg/result.h" |
32 | 41 | #include "iceberg/schema.h" |
33 | 42 | #include "iceberg/schema_internal.h" |
34 | 43 | #include "iceberg/test/matchers.h" |
| 44 | +#include "iceberg/util/executor.h" |
| 45 | +#include "iceberg/util/task_group.h" |
35 | 46 |
|
36 | 47 | namespace iceberg { |
37 | 48 |
|
38 | 49 | struct ToArrowSchemaParam { |
39 | 50 | std::shared_ptr<Type> iceberg_type; |
40 | 51 | bool optional = true; |
41 | | - std::shared_ptr<arrow::DataType> arrow_type; |
| 52 | + std::shared_ptr<::arrow::DataType> arrow_type; |
42 | 53 | }; |
43 | 54 |
|
44 | 55 | class ToArrowSchemaTest : public ::testing::TestWithParam<ToArrowSchemaParam> {}; |
@@ -89,17 +100,17 @@ INSTANTIATE_TEST_SUITE_P( |
89 | 100 | ToArrowSchemaParam{.iceberg_type = iceberg::date(), |
90 | 101 | .arrow_type = ::arrow::date32()}, |
91 | 102 | ToArrowSchemaParam{.iceberg_type = iceberg::time(), |
92 | | - .arrow_type = ::arrow::time64(arrow::TimeUnit::MICRO)}, |
| 103 | + .arrow_type = ::arrow::time64(::arrow::TimeUnit::MICRO)}, |
93 | 104 | ToArrowSchemaParam{.iceberg_type = iceberg::timestamp(), |
94 | | - .arrow_type = ::arrow::timestamp(arrow::TimeUnit::MICRO)}, |
| 105 | + .arrow_type = ::arrow::timestamp(::arrow::TimeUnit::MICRO)}, |
95 | 106 | ToArrowSchemaParam{ |
96 | 107 | .iceberg_type = iceberg::timestamp_tz(), |
97 | | - .arrow_type = ::arrow::timestamp(arrow::TimeUnit::MICRO, "UTC")}, |
| 108 | + .arrow_type = ::arrow::timestamp(::arrow::TimeUnit::MICRO, "UTC")}, |
98 | 109 | ToArrowSchemaParam{.iceberg_type = iceberg::timestamp_ns(), |
99 | | - .arrow_type = ::arrow::timestamp(arrow::TimeUnit::NANO)}, |
| 110 | + .arrow_type = ::arrow::timestamp(::arrow::TimeUnit::NANO)}, |
100 | 111 | ToArrowSchemaParam{ |
101 | 112 | .iceberg_type = iceberg::timestamptz_ns(), |
102 | | - .arrow_type = ::arrow::timestamp(arrow::TimeUnit::NANO, "UTC")}, |
| 113 | + .arrow_type = ::arrow::timestamp(::arrow::TimeUnit::NANO, "UTC")}, |
103 | 114 | ToArrowSchemaParam{.iceberg_type = iceberg::string(), |
104 | 115 | .arrow_type = ::arrow::utf8()}, |
105 | 116 | ToArrowSchemaParam{.iceberg_type = iceberg::binary(), |
@@ -311,7 +322,7 @@ TEST(ToArrowSchemaTest, NestedUnknownFieldsRoundTrip) { |
311 | 322 | } |
312 | 323 |
|
313 | 324 | struct FromArrowSchemaParam { |
314 | | - std::shared_ptr<arrow::DataType> arrow_type; |
| 325 | + std::shared_ptr<::arrow::DataType> arrow_type; |
315 | 326 | bool optional = true; |
316 | 327 | std::shared_ptr<Type> iceberg_type; |
317 | 328 | }; |
@@ -365,17 +376,17 @@ INSTANTIATE_TEST_SUITE_P( |
365 | 376 | .iceberg_type = iceberg::decimal(10, 2)}, |
366 | 377 | FromArrowSchemaParam{.arrow_type = ::arrow::date32(), |
367 | 378 | .iceberg_type = iceberg::date()}, |
368 | | - FromArrowSchemaParam{.arrow_type = ::arrow::time64(arrow::TimeUnit::MICRO), |
| 379 | + FromArrowSchemaParam{.arrow_type = ::arrow::time64(::arrow::TimeUnit::MICRO), |
369 | 380 | .iceberg_type = iceberg::time()}, |
370 | | - FromArrowSchemaParam{.arrow_type = ::arrow::timestamp(arrow::TimeUnit::MICRO), |
| 381 | + FromArrowSchemaParam{.arrow_type = ::arrow::timestamp(::arrow::TimeUnit::MICRO), |
371 | 382 | .iceberg_type = iceberg::timestamp()}, |
372 | 383 | FromArrowSchemaParam{ |
373 | | - .arrow_type = ::arrow::timestamp(arrow::TimeUnit::MICRO, "UTC"), |
| 384 | + .arrow_type = ::arrow::timestamp(::arrow::TimeUnit::MICRO, "UTC"), |
374 | 385 | .iceberg_type = std::make_shared<TimestampTzType>()}, |
375 | | - FromArrowSchemaParam{.arrow_type = ::arrow::timestamp(arrow::TimeUnit::NANO), |
| 386 | + FromArrowSchemaParam{.arrow_type = ::arrow::timestamp(::arrow::TimeUnit::NANO), |
376 | 387 | .iceberg_type = iceberg::timestamp_ns()}, |
377 | 388 | FromArrowSchemaParam{ |
378 | | - .arrow_type = ::arrow::timestamp(arrow::TimeUnit::NANO, "UTC"), |
| 389 | + .arrow_type = ::arrow::timestamp(::arrow::TimeUnit::NANO, "UTC"), |
379 | 390 | .iceberg_type = iceberg::timestamptz_ns()}, |
380 | 391 | FromArrowSchemaParam{.arrow_type = ::arrow::utf8(), |
381 | 392 | .iceberg_type = iceberg::string()}, |
@@ -588,4 +599,50 @@ TEST(FromArrowSchemaTest, MapType) { |
588 | 599 | ASSERT_EQ(value.type()->type_id(), TypeId::kInt); |
589 | 600 | } |
590 | 601 |
|
| 602 | +TEST(ArrowExecutorAdapterTest, RunsTaskGroupOnThreadPool) { |
| 603 | +#ifndef ARROW_ENABLE_THREADING |
| 604 | + GTEST_SKIP() << "Test requires ARROW_ENABLE_THREADING=ON"; |
| 605 | +#endif |
| 606 | + |
| 607 | + class ArrowExecutorAdapter final : public Executor { |
| 608 | + public: |
| 609 | + explicit ArrowExecutorAdapter(::arrow::internal::Executor& executor) |
| 610 | + : executor_(executor) {} |
| 611 | + |
| 612 | + Status Submit(ExecutorTask task) override { |
| 613 | + ICEBERG_ARROW_RETURN_NOT_OK(executor_.Spawn(std::move(task))); |
| 614 | + return {}; |
| 615 | + } |
| 616 | + |
| 617 | + private: |
| 618 | + ::arrow::internal::Executor& executor_; |
| 619 | + }; |
| 620 | + |
| 621 | + auto thread_pool = ::arrow::internal::ThreadPool::Make(2).ValueOrDie(); |
| 622 | + ArrowExecutorAdapter executor(*thread_pool); |
| 623 | + |
| 624 | + std::mutex mutex; |
| 625 | + std::vector<std::thread::id> thread_ids; |
| 626 | + |
| 627 | + auto status = TaskGroup<>() |
| 628 | + .SetExecutor(std::ref(executor)) |
| 629 | + .Submit([&]() -> Status { |
| 630 | + std::lock_guard lock(mutex); |
| 631 | + thread_ids.push_back(std::this_thread::get_id()); |
| 632 | + return {}; |
| 633 | + }) |
| 634 | + .Submit([&]() -> Status { |
| 635 | + std::lock_guard lock(mutex); |
| 636 | + thread_ids.push_back(std::this_thread::get_id()); |
| 637 | + return {}; |
| 638 | + }) |
| 639 | + .Run(); |
| 640 | + |
| 641 | + EXPECT_THAT(status, IsOk()); |
| 642 | + EXPECT_EQ(thread_ids.size(), 2); |
| 643 | + EXPECT_NE(thread_ids[0], std::this_thread::get_id()); |
| 644 | + EXPECT_NE(thread_ids[1], std::this_thread::get_id()); |
| 645 | + EXPECT_TRUE(thread_pool->Shutdown().ok()); |
| 646 | +} |
| 647 | + |
591 | 648 | } // namespace iceberg |
0 commit comments