From 5bf1baf8369138dbe6a9eab1f987e0749d6172ba Mon Sep 17 00:00:00 2001 From: Beka Davis <31743465+bekadavis9@users.noreply.github.com> Date: Wed, 9 Oct 2024 13:03:35 -0400 Subject: [PATCH] Subarray CAPI Handle. (#5334) `Subarray` CAPI Handle. [sc-53777] --- TYPE: NO_HISTORY DESC: `Subarray` CAPI Handle. --- CMakeLists.txt | 2 + ...test-cppapi-dense-array-dimension-label.cc | 4 +- test/src/unit-Subarray.cc | 5 +- test/src/unit-cppapi-subarray.cc | 22 +- test/src/unit-ordered-dim-label-reader.cc | 20 +- test/support/src/helpers.h | 2 +- test/support/src/serialization_wrappers.cc | 6 +- tiledb/api/c_api/CMakeLists.txt | 3 + tiledb/api/c_api/subarray/CMakeLists.txt | 42 ++ tiledb/api/c_api/subarray/subarray_api.cc | 455 +++++++++++ .../subarray/subarray_api_experimental.h | 73 ++ .../c_api/subarray/subarray_api_external.h | 523 +++++++++++++ .../c_api/subarray/subarray_api_internal.h | 267 +++++++ tiledb/api/c_api/subarray/test/CMakeLists.txt | 33 + .../test/compile_capi_subarray_stub_main.cc | 35 + .../c_api/subarray/test/unit_capi_subarray.cc | 709 ++++++++++++++++++ .../testsupport_capi_subarray.h | 95 +++ tiledb/sm/c_api/api_argument_validator.h | 12 - tiledb/sm/c_api/tiledb.cc | 469 +----------- tiledb/sm/c_api/tiledb.h | 477 +----------- tiledb/sm/c_api/tiledb_dimension_label.cc | 29 +- tiledb/sm/c_api/tiledb_experimental.h | 13 +- tiledb/sm/c_api/tiledb_struct_def.h | 7 - 23 files changed, 2291 insertions(+), 1012 deletions(-) create mode 100644 tiledb/api/c_api/subarray/CMakeLists.txt create mode 100644 tiledb/api/c_api/subarray/subarray_api.cc create mode 100644 tiledb/api/c_api/subarray/subarray_api_experimental.h create mode 100644 tiledb/api/c_api/subarray/subarray_api_external.h create mode 100644 tiledb/api/c_api/subarray/subarray_api_internal.h create mode 100644 tiledb/api/c_api/subarray/test/CMakeLists.txt create mode 100644 tiledb/api/c_api/subarray/test/compile_capi_subarray_stub_main.cc create mode 100644 tiledb/api/c_api/subarray/test/unit_capi_subarray.cc create mode 100644 tiledb/api/c_api_test_support/testsupport_capi_subarray.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 952800b5c95..fef5de5ce70 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -329,6 +329,8 @@ list(APPEND TILEDB_C_API_RELATIVE_HEADERS "${CMAKE_SOURCE_DIR}/tiledb/api/c_api/query_field/query_field_api_external_experimental.h" "${CMAKE_SOURCE_DIR}/tiledb/api/c_api/query_plan/query_plan_api_external_experimental.h" "${CMAKE_SOURCE_DIR}/tiledb/api/c_api/string/string_api_external.h" + "${CMAKE_SOURCE_DIR}/tiledb/api/c_api/subarray/subarray_api_experimental.h" + "${CMAKE_SOURCE_DIR}/tiledb/api/c_api/subarray/subarray_api_external.h" "${CMAKE_SOURCE_DIR}/tiledb/api/c_api/vfs/vfs_api_enum.h" "${CMAKE_SOURCE_DIR}/tiledb/api/c_api/vfs/vfs_api_external.h" "${CMAKE_SOURCE_DIR}/tiledb/api/c_api/vfs/vfs_api_experimental.h" diff --git a/test/src/test-cppapi-dense-array-dimension-label.cc b/test/src/test-cppapi-dense-array-dimension-label.cc index 3f723daebd2..c45c4db3c5e 100644 --- a/test/src/test-cppapi-dense-array-dimension-label.cc +++ b/test/src/test-cppapi-dense-array-dimension-label.cc @@ -5,7 +5,7 @@ * * The MIT License * - * @copyright Copyright (c) 2023 TileDB, Inc. + * @copyright Copyright (c) 2023-2024 TileDB, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -592,5 +592,5 @@ TEST_CASE( CHECK(query.ptr()->query_->subarray()->range_num() == 1); CHECK( query.ptr()->query_->subarray()->ranges_for_dim(0) == - expected_subarray.ptr()->subarray_->ranges_for_dim(0)); + expected_subarray.ptr()->ranges_for_dim(0)); } diff --git a/test/src/unit-Subarray.cc b/test/src/unit-Subarray.cc index 7258c9d2aec..2cc16a97d86 100644 --- a/test/src/unit-Subarray.cc +++ b/test/src/unit-Subarray.cc @@ -33,7 +33,6 @@ #include "test/support/src/helpers.h" #include "test/support/src/vfs_helpers.h" #include "tiledb/api/c_api/array/array_api_internal.h" -#include "tiledb/sm/c_api/tiledb_struct_def.h" #include "tiledb/sm/subarray/subarray_partitioner.h" #ifdef _WIN32 @@ -963,10 +962,10 @@ TEST_CASE_METHOD( Range(&range_data[0], &range_data[1], sizeof(int64_t)), Range(&range_data[2], &range_data[3], sizeof(int64_t)), Range(&range_data[4], &range_data[5], sizeof(int64_t))}; - subarray->subarray_->set_attribute_ranges("b", input_ranges); + subarray->set_attribute_ranges("b", input_ranges); // Get attribute ranges and verify results - const auto& output_ranges = subarray->subarray_->get_attribute_ranges("b"); + const auto& output_ranges = subarray->get_attribute_ranges("b"); for (uint32_t ii = 0; ii < 3; ++ii) { CHECK(input_ranges[ii] == output_ranges[ii]); } diff --git a/test/src/unit-cppapi-subarray.cc b/test/src/unit-cppapi-subarray.cc index 6a4af6da9d2..e630a4b9dc0 100644 --- a/test/src/unit-cppapi-subarray.cc +++ b/test/src/unit-cppapi-subarray.cc @@ -468,29 +468,29 @@ TEST_CASE( SECTION("- Upper bound OOB") { int range[] = {0, 100}; auto r = Range(&range[0], &range[1], sizeof(int)); - CHECK_NOTHROW(subarray.ptr().get()->subarray_->add_range_unsafe(0, r)); + CHECK_NOTHROW(subarray.ptr().get()->add_range_unsafe(0, r)); } SECTION("- Lower bound OOB") { int range[] = {-1, 2}; auto r = Range(&range[0], &range[1], sizeof(int)); - CHECK_NOTHROW(subarray.ptr().get()->subarray_->add_range_unsafe(0, r)); + CHECK_NOTHROW(subarray.ptr().get()->add_range_unsafe(0, r)); } SECTION("- Second range OOB") { int range[] = {1, 4}; auto r = Range(&range[0], &range[1], sizeof(int)); - CHECK_NOTHROW(subarray.ptr().get()->subarray_->add_range_unsafe(0, r)); + CHECK_NOTHROW(subarray.ptr().get()->add_range_unsafe(0, r)); int range2[] = {10, 20}; auto r2 = Range(&range2[0], &range2[1], sizeof(int)); - CHECK_NOTHROW(subarray.ptr().get()->subarray_->add_range_unsafe(1, r2)); + CHECK_NOTHROW(subarray.ptr().get()->add_range_unsafe(1, r2)); } SECTION("- Valid ranges") { int range[] = {0, 1}; auto r = Range(&range[0], &range[1], sizeof(int)); - CHECK_NOTHROW(subarray.ptr().get()->subarray_->add_range_unsafe(0, r)); - CHECK_NOTHROW(subarray.ptr().get()->subarray_->add_range_unsafe(1, r)); + CHECK_NOTHROW(subarray.ptr().get()->add_range_unsafe(0, r)); + CHECK_NOTHROW(subarray.ptr().get()->add_range_unsafe(1, r)); expected = TILEDB_OK; } @@ -822,14 +822,14 @@ TEST_CASE( // since the other CHECKS(range_num == 1) succeed whether or not the //.set_subarray() was done (accidental discovery.) CHECK(!subarray_equiv( - *default_subarray_from_query.ptr().get()->subarray_, - *subarray.ptr().get()->subarray_)); + *default_subarray_from_query.ptr()->subarray().get(), + *subarray.ptr()->subarray().get())); query.set_subarray(subarray); tiledb::Subarray retrieved_query_subarray(query.ctx(), query.array()); query.update_subarray_from_query(&retrieved_query_subarray); CHECK(subarray_equiv( - *retrieved_query_subarray.ptr().get()->subarray_, - *subarray.ptr().get()->subarray_)); + *retrieved_query_subarray.ptr()->subarray().get(), + *subarray.ptr()->subarray().get())); // Test range num auto range_num = retrieved_query_subarray.range_num(0); CHECK(range_num == 1); @@ -1293,7 +1293,7 @@ TEST_CASE( tiledb_subarray_serialize(ctx.ptr().get(), array.ptr().get(), &ptr); subarray.replace_subarray_data(ptr); } - CHECK(coalesce == subarray.ptr()->subarray_->coalesce_ranges()); + CHECK(coalesce == subarray.ptr()->coalesce_ranges()); subarray.add_range(0, 1, 10); subarray.add_range(0, 11, 20); diff --git a/test/src/unit-ordered-dim-label-reader.cc b/test/src/unit-ordered-dim-label-reader.cc index a14b37cec4c..8313cd80416 100644 --- a/test/src/unit-ordered-dim-label-reader.cc +++ b/test/src/unit-ordered-dim-label-reader.cc @@ -126,7 +126,7 @@ struct CPPOrderedDimLabelReaderFixedFx { } Subarray subarray(ctx_, array); - subarray.ptr()->subarray_->set_attribute_ranges("labels", input_ranges); + subarray.ptr()->set_attribute_ranges("labels", input_ranges); if (serialize_) { auto subarray_ptr = subarray.ptr().get(); tiledb_subarray_serialize( @@ -173,7 +173,7 @@ struct CPPOrderedDimLabelReaderFixedFx { &second_label, &first_label, sizeof(LabelT)); Subarray subarray(ctx_, array); - subarray.ptr()->subarray_->set_attribute_ranges("labels", input_ranges); + subarray.ptr()->set_attribute_ranges("labels", input_ranges); if (serialize_) { auto subarray_ptr = subarray.ptr().get(); tiledb_subarray_serialize( @@ -256,7 +256,7 @@ TEST_CASE_METHOD( input_ranges.emplace_back(&val, &val, sizeof(double)); Subarray subarray(ctx_, array); - subarray.ptr()->subarray_->set_attribute_ranges("labels", input_ranges); + subarray.ptr()->set_attribute_ranges("labels", input_ranges); if (serialize_) { auto subarray_ptr = subarray.ptr().get(); tiledb_subarray_serialize( @@ -295,7 +295,7 @@ TEST_CASE_METHOD( input_ranges.emplace_back(&val, &val, sizeof(double)); Subarray subarray(ctx_, array); - subarray.ptr()->subarray_->set_attribute_ranges("labels", input_ranges); + subarray.ptr()->set_attribute_ranges("labels", input_ranges); if (serialize_) { auto subarray_ptr = subarray.ptr().get(); tiledb_subarray_serialize( @@ -335,7 +335,7 @@ TEST_CASE_METHOD( input_ranges.emplace_back(&val, &val, sizeof(double)); Subarray subarray(ctx_, array); - subarray.ptr()->subarray_->set_attribute_ranges("labels", input_ranges); + subarray.ptr()->set_attribute_ranges("labels", input_ranges); if (serialize_) { auto subarray_ptr = subarray.ptr().get(); tiledb_subarray_serialize( @@ -376,7 +376,7 @@ TEST_CASE_METHOD( Subarray subarray(ctx_, array); subarray.add_range(0, 1, 1); - subarray.ptr()->subarray_->set_attribute_ranges("labels", input_ranges); + subarray.ptr()->set_attribute_ranges("labels", input_ranges); if (serialize_) { auto subarray_ptr = subarray.ptr().get(); tiledb_subarray_serialize( @@ -412,7 +412,7 @@ TEST_CASE_METHOD( input_ranges.emplace_back(&ranges[0], &ranges[1], sizeof(double)); Subarray subarray(ctx_, array); - subarray.ptr()->subarray_->set_attribute_ranges("labels", input_ranges); + subarray.ptr()->set_attribute_ranges("labels", input_ranges); if (serialize_) { auto subarray_ptr = subarray.ptr().get(); tiledb_subarray_serialize( @@ -777,7 +777,7 @@ struct CPPOrderedDimLabelReaderVarFx { } Subarray subarray(ctx_, array); - subarray.ptr()->subarray_->set_attribute_ranges("labels", input_ranges); + subarray.ptr()->set_attribute_ranges("labels", input_ranges); if (serialize_) { auto subarray_ptr = subarray.ptr().get(); tiledb_subarray_serialize( @@ -831,7 +831,7 @@ struct CPPOrderedDimLabelReaderVarFx { labels_data.data() + 4, 4, labels_data.data(), 4); Subarray subarray(ctx_, array); - subarray.ptr()->subarray_->set_attribute_ranges("labels", input_ranges); + subarray.ptr()->set_attribute_ranges("labels", input_ranges); if (serialize_) { auto subarray_ptr = subarray.ptr().get(); tiledb_subarray_serialize( @@ -1057,7 +1057,7 @@ TEST_CASE_METHOD( } Subarray subarray(ctx_, array); - subarray.ptr()->subarray_->set_attribute_ranges("labels", input_ranges); + subarray.ptr()->set_attribute_ranges("labels", input_ranges); if (serialize_) { auto subarray_ptr = subarray.ptr().get(); tiledb_subarray_serialize( diff --git a/test/support/src/helpers.h b/test/support/src/helpers.h index 201821c09c6..c00e05c281f 100644 --- a/test/support/src/helpers.h +++ b/test/support/src/helpers.h @@ -36,6 +36,7 @@ #include "test/support/src/coords_workaround.h" #include "test/support/src/mem_helpers.h" #include "tiledb.h" +#include "tiledb/api/c_api/subarray/subarray_api_internal.h" #include "tiledb/common/common.h" #include "tiledb/common/random/random_label.h" #include "tiledb/sm/array/array.h" @@ -43,7 +44,6 @@ #include "tiledb/sm/enums/layout.h" #include "tiledb/sm/enums/serialization_type.h" #include "tiledb/sm/stats/stats.h" -#include "tiledb/sm/subarray/subarray.h" #include "tiledb_serialization.h" #include diff --git a/test/support/src/serialization_wrappers.cc b/test/support/src/serialization_wrappers.cc index c3e6dad4d14..c0fc47ef842 100644 --- a/test/support/src/serialization_wrappers.cc +++ b/test/support/src/serialization_wrappers.cc @@ -203,14 +203,16 @@ void tiledb_subarray_serialize( tiledb_array_schema_t* array_schema = nullptr; tiledb_array_get_schema(ctx, array, &array_schema); REQUIRE(tiledb::sm::serialization::subarray_to_capnp( - *(array_schema->array_schema()), (*subarray)->subarray_, &builder) + *(array_schema->array_schema()), + (*subarray)->subarray().get(), + &builder) .ok()); // Deserialize tiledb_subarray_t* deserialized_subarray; tiledb::test::require_tiledb_ok( ctx, tiledb_subarray_alloc(ctx, array, &deserialized_subarray)); REQUIRE(tiledb::sm::serialization::subarray_from_capnp( - builder, deserialized_subarray->subarray_) + builder, deserialized_subarray->subarray().get()) .ok()); *subarray = deserialized_subarray; #endif diff --git a/tiledb/api/c_api/CMakeLists.txt b/tiledb/api/c_api/CMakeLists.txt index eda72d37811..3a41b43b1ca 100644 --- a/tiledb/api/c_api/CMakeLists.txt +++ b/tiledb/api/c_api/CMakeLists.txt @@ -121,6 +121,9 @@ add_subdirectory(object) # `query`: no dependencies yet but will have some add_subdirectory(query) +# `subarray`: depends on `context` +add_subdirectory(subarray) + # `string`: no dependencies add_subdirectory(string) diff --git a/tiledb/api/c_api/subarray/CMakeLists.txt b/tiledb/api/c_api/subarray/CMakeLists.txt new file mode 100644 index 00000000000..b3eb1f8c465 --- /dev/null +++ b/tiledb/api/c_api/subarray/CMakeLists.txt @@ -0,0 +1,42 @@ +# +# tiledb/api/c_api/subarray/CMakeLists.txt +# +# The MIT License +# +# Copyright (c) 2024 TileDB, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# + +include(common NO_POLICY_SCOPE) +include(object_library) + +list(APPEND SOURCES + subarray_api.cc +) +gather_sources(${SOURCES}) + +commence(object_library capi_subarray_stub) + this_target_sources(${SOURCES}) + this_target_link_libraries(export) + this_target_object_libraries(subarray) + this_target_object_libraries(capi_context_stub) +conclude(object_library) + +add_test_subdirectory() diff --git a/tiledb/api/c_api/subarray/subarray_api.cc b/tiledb/api/c_api/subarray/subarray_api.cc new file mode 100644 index 00000000000..e9161142f75 --- /dev/null +++ b/tiledb/api/c_api/subarray/subarray_api.cc @@ -0,0 +1,455 @@ +/** + * @file tiledb/api/c_api/subarray/subarray_api.cc + * + * @section LICENSE + * + * The MIT License + * + * @copyright Copyright (c) 2024 TileDB, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @section DESCRIPTION + * + * This file defines C API functions for the fragment info section. + */ + +#include "subarray_api_experimental.h" +#include "subarray_api_internal.h" +#include "tiledb/api/c_api/array/array_api_internal.h" +#include "tiledb/api/c_api/context/context_api_internal.h" +#include "tiledb/api/c_api_support/c_api_support.h" + +namespace tiledb::api { + +capi_return_t tiledb_subarray_alloc( + tiledb_ctx_t* ctx, + const tiledb_array_t* array, + tiledb_subarray_t** subarray) { + ensure_array_is_valid(array); + ensure_output_pointer_is_valid(subarray); + + // Error if array is not open + if (!array->is_open()) { + throw CAPIException("Cannot create subarray; array is not open"); + } + + // Create Subarray object + *subarray = tiledb_subarray_t::make_handle( + array->array().get(), + (tiledb::sm::stats::Stats*)nullptr, + ctx->resources().logger(), + true); + return TILEDB_OK; +} + +void tiledb_subarray_free(tiledb_subarray_t** subarray) { + ensure_output_pointer_is_valid(subarray); + ensure_subarray_is_valid(*subarray); + tiledb_subarray_t::break_handle(*subarray); +} + +capi_return_t tiledb_subarray_set_config( + tiledb_subarray_t* subarray, tiledb_config_t* config) { + ensure_subarray_is_valid(subarray); + ensure_config_is_valid(config); + subarray->set_config(tiledb::sm::QueryType::READ, config->config()); + return TILEDB_OK; +} + +capi_return_t tiledb_subarray_set_coalesce_ranges( + tiledb_subarray_t* subarray, int coalesce_ranges) { + ensure_subarray_is_valid(subarray); + subarray->set_coalesce_ranges(coalesce_ranges != 0); + return TILEDB_OK; +} + +capi_return_t tiledb_subarray_set_subarray( + tiledb_subarray_t* subarray, const void* subarray_vals) { + ensure_subarray_is_valid(subarray); + subarray->set_subarray(subarray_vals); + return TILEDB_OK; +} + +capi_return_t tiledb_subarray_add_point_ranges( + tiledb_subarray_t* subarray, + uint32_t dim_idx, + const void* start, + uint64_t count) { + ensure_subarray_is_valid(subarray); + subarray->add_point_ranges(dim_idx, start, count); + return TILEDB_OK; +} + +capi_return_t tiledb_subarray_add_range( + tiledb_subarray_t* subarray, + uint32_t dim_idx, + const void* start, + const void* end, + const void* stride) { + ensure_subarray_is_valid(subarray); + ensure_unsupported_stride_is_null(stride); + subarray->add_range(dim_idx, start, end); + return TILEDB_OK; +} + +capi_return_t tiledb_subarray_add_range_by_name( + tiledb_subarray_t* subarray, + const char* dim_name, + const void* start, + const void* end, + const void* stride) { + ensure_subarray_is_valid(subarray); + ensure_unsupported_stride_is_null(stride); + subarray->add_range_by_name(dim_name, start, end); + return TILEDB_OK; +} + +capi_return_t tiledb_subarray_add_range_var( + tiledb_subarray_t* subarray, + uint32_t dim_idx, + const void* start, + uint64_t start_size, + const void* end, + uint64_t end_size) { + ensure_subarray_is_valid(subarray); + subarray->add_range_var(dim_idx, start, start_size, end, end_size); + return TILEDB_OK; +} + +capi_return_t tiledb_subarray_add_range_var_by_name( + tiledb_subarray_t* subarray, + const char* dim_name, + const void* start, + uint64_t start_size, + const void* end, + uint64_t end_size) { + ensure_subarray_is_valid(subarray); + subarray->add_range_var_by_name(dim_name, start, start_size, end, end_size); + return TILEDB_OK; +} + +capi_return_t tiledb_subarray_get_range_num( + const tiledb_subarray_t* subarray, uint32_t dim_idx, uint64_t* range_num) { + ensure_subarray_is_valid(subarray); + ensure_output_pointer_is_valid(range_num); + subarray->get_range_num(dim_idx, range_num); + return TILEDB_OK; +} + +capi_return_t tiledb_subarray_get_range_num_from_name( + const tiledb_subarray_t* subarray, + const char* dim_name, + uint64_t* range_num) { + ensure_subarray_is_valid(subarray); + ensure_output_pointer_is_valid(range_num); + subarray->get_range_num_from_name(dim_name, range_num); + return TILEDB_OK; +} + +capi_return_t tiledb_subarray_get_range( + const tiledb_subarray_t* subarray, + uint32_t dim_idx, + uint64_t range_idx, + const void** start, + const void** end, + const void** stride) { + ensure_subarray_is_valid(subarray); + ensure_output_pointer_is_valid(start); + ensure_output_pointer_is_valid(end); + if (stride != nullptr) { + *stride = nullptr; + } + subarray->get_range(dim_idx, range_idx, start, end); + return TILEDB_OK; +} + +capi_return_t tiledb_subarray_get_range_from_name( + const tiledb_subarray_t* subarray, + const char* dim_name, + uint64_t range_idx, + const void** start, + const void** end, + const void** stride) { + ensure_subarray_is_valid(subarray); + ensure_output_pointer_is_valid(start); + ensure_output_pointer_is_valid(end); + if (stride != nullptr) { + *stride = nullptr; + } + subarray->get_range_from_name(dim_name, range_idx, start, end); + return TILEDB_OK; +} + +capi_return_t tiledb_subarray_get_range_var_size( + const tiledb_subarray_t* subarray, + uint32_t dim_idx, + uint64_t range_idx, + uint64_t* start_size, + uint64_t* end_size) { + ensure_subarray_is_valid(subarray); + ensure_output_pointer_is_valid(start_size); + ensure_output_pointer_is_valid(end_size); + subarray->get_range_var_size(dim_idx, range_idx, start_size, end_size); + return TILEDB_OK; +} + +capi_return_t tiledb_subarray_get_range_var_size_from_name( + const tiledb_subarray_t* subarray, + const char* dim_name, + uint64_t range_idx, + uint64_t* start_size, + uint64_t* end_size) { + ensure_subarray_is_valid(subarray); + ensure_output_pointer_is_valid(start_size); + ensure_output_pointer_is_valid(end_size); + subarray->get_range_var_size_from_name( + dim_name, range_idx, start_size, end_size); + return TILEDB_OK; +} + +capi_return_t tiledb_subarray_get_range_var( + const tiledb_subarray_t* subarray, + uint32_t dim_idx, + uint64_t range_idx, + void* start, + void* end) { + ensure_subarray_is_valid(subarray); + ensure_output_pointer_is_valid(start); + ensure_output_pointer_is_valid(end); + subarray->get_range_var(dim_idx, range_idx, start, end); + return TILEDB_OK; +} + +capi_return_t tiledb_subarray_get_range_var_from_name( + const tiledb_subarray_t* subarray, + const char* dim_name, + uint64_t range_idx, + void* start, + void* end) { + ensure_subarray_is_valid(subarray); + ensure_output_pointer_is_valid(start); + ensure_output_pointer_is_valid(end); + subarray->get_range_var_from_name(dim_name, range_idx, start, end); + return TILEDB_OK; +} + +} // namespace tiledb::api + +using tiledb::api::api_entry_context; +using tiledb::api::api_entry_void; +using tiledb::api::api_entry_with_context; + +CAPI_INTERFACE( + subarray_alloc, + tiledb_ctx_t* ctx, + const tiledb_array_t* array, + tiledb_subarray_t** subarray) { + return api_entry_with_context( + ctx, array, subarray); +} + +CAPI_INTERFACE_VOID(subarray_free, tiledb_subarray_t** subarray) { + return api_entry_void(subarray); +} + +CAPI_INTERFACE( + subarray_set_config, + tiledb_ctx_t* ctx, + tiledb_subarray_t* subarray, + tiledb_config_t* config) { + return api_entry_context( + ctx, subarray, config); +} + +CAPI_INTERFACE( + subarray_set_coalesce_ranges, + tiledb_ctx_t* ctx, + tiledb_subarray_t* subarray, + int coalesce_ranges) { + return api_entry_context( + ctx, subarray, coalesce_ranges); +} + +CAPI_INTERFACE( + subarray_set_subarray, + tiledb_ctx_t* ctx, + tiledb_subarray_t* subarray_obj, + const void* subarray_vals) { + return api_entry_context( + ctx, subarray_obj, subarray_vals); +} + +CAPI_INTERFACE( + subarray_add_point_ranges, + tiledb_ctx_t* ctx, + tiledb_subarray_t* subarray, + uint32_t dim_idx, + const void* start, + uint64_t count) { + return api_entry_context( + ctx, subarray, dim_idx, start, count); +} + +CAPI_INTERFACE( + subarray_add_range, + tiledb_ctx_t* ctx, + tiledb_subarray_t* subarray, + uint32_t dim_idx, + const void* start, + const void* end, + const void* stride) { + return api_entry_context( + ctx, subarray, dim_idx, start, end, stride); +} + +CAPI_INTERFACE( + subarray_add_range_by_name, + tiledb_ctx_t* ctx, + tiledb_subarray_t* subarray, + const char* dim_name, + const void* start, + const void* end, + const void* stride) { + return api_entry_context( + ctx, subarray, dim_name, start, end, stride); +} + +CAPI_INTERFACE( + subarray_add_range_var, + tiledb_ctx_t* ctx, + tiledb_subarray_t* subarray, + uint32_t dim_idx, + const void* start, + uint64_t start_size, + const void* end, + uint64_t end_size) { + return api_entry_context( + ctx, subarray, dim_idx, start, start_size, end, end_size); +} + +CAPI_INTERFACE( + subarray_add_range_var_by_name, + tiledb_ctx_t* ctx, + tiledb_subarray_t* subarray, + const char* dim_name, + const void* start, + uint64_t start_size, + const void* end, + uint64_t end_size) { + return api_entry_context( + ctx, subarray, dim_name, start, start_size, end, end_size); +} + +CAPI_INTERFACE( + subarray_get_range_num, + tiledb_ctx_t* ctx, + const tiledb_subarray_t* subarray, + uint32_t dim_idx, + uint64_t* range_num) { + return api_entry_context( + ctx, subarray, dim_idx, range_num); +} + +CAPI_INTERFACE( + subarray_get_range_num_from_name, + tiledb_ctx_t* ctx, + const tiledb_subarray_t* subarray, + const char* dim_name, + uint64_t* range_num) { + return api_entry_context< + tiledb::api::tiledb_subarray_get_range_num_from_name>( + ctx, subarray, dim_name, range_num); +} + +CAPI_INTERFACE( + subarray_get_range, + tiledb_ctx_t* ctx, + const tiledb_subarray_t* subarray, + uint32_t dim_idx, + uint64_t range_idx, + const void** start, + const void** end, + const void** stride) { + return api_entry_context( + ctx, subarray, dim_idx, range_idx, start, end, stride); +} + +CAPI_INTERFACE( + subarray_get_range_from_name, + tiledb_ctx_t* ctx, + const tiledb_subarray_t* subarray, + const char* dim_name, + uint64_t range_idx, + const void** start, + const void** end, + const void** stride) { + return api_entry_context( + ctx, subarray, dim_name, range_idx, start, end, stride); +} + +CAPI_INTERFACE( + subarray_get_range_var_size, + tiledb_ctx_t* ctx, + const tiledb_subarray_t* subarray, + uint32_t dim_idx, + uint64_t range_idx, + uint64_t* start_size, + uint64_t* end_size) { + return api_entry_context( + ctx, subarray, dim_idx, range_idx, start_size, end_size); +} + +CAPI_INTERFACE( + subarray_get_range_var_size_from_name, + tiledb_ctx_t* ctx, + const tiledb_subarray_t* subarray, + const char* dim_name, + uint64_t range_idx, + uint64_t* start_size, + uint64_t* end_size) { + return api_entry_context< + tiledb::api::tiledb_subarray_get_range_var_size_from_name>( + ctx, subarray, dim_name, range_idx, start_size, end_size); +} + +CAPI_INTERFACE( + subarray_get_range_var, + tiledb_ctx_t* ctx, + const tiledb_subarray_t* subarray, + uint32_t dim_idx, + uint64_t range_idx, + void* start, + void* end) { + return api_entry_context( + ctx, subarray, dim_idx, range_idx, start, end); +} + +CAPI_INTERFACE( + subarray_get_range_var_from_name, + tiledb_ctx_t* ctx, + const tiledb_subarray_t* subarray, + const char* dim_name, + uint64_t range_idx, + void* start, + void* end) { + return api_entry_context< + tiledb::api::tiledb_subarray_get_range_var_from_name>( + ctx, subarray, dim_name, range_idx, start, end); +} diff --git a/tiledb/api/c_api/subarray/subarray_api_experimental.h b/tiledb/api/c_api/subarray/subarray_api_experimental.h new file mode 100644 index 00000000000..5ae095c3fd5 --- /dev/null +++ b/tiledb/api/c_api/subarray/subarray_api_experimental.h @@ -0,0 +1,73 @@ +/** + * @file tiledb/api/c_api/subarray/subarray_api_experimental.h + * + * @section LICENSE + * + * The MIT License + * + * @copyright Copyright (c) 2024 TileDB, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @section DESCRIPTION + * + * This file declares the subarray section of the experimental TileDB C API + */ + +#ifndef TILEDB_CAPI_SUBARRAY_EXPERIMENTAL_H +#define TILEDB_CAPI_SUBARRAY_EXPERIMENTAL_H + +#include "../api_external_common.h" +#include "subarray_api_external.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Adds point ranges to the given dimension index of the subarray + * Effectively `add_range(x_i, x_i)` for `count` points in the + * target array, but set in bulk to amortize expensive steps. + * + * **Example:** + * + * @code{.c} + * uint64_t ranges[] = {1, 3, 7, 10}; + * tiledb_subarray_add_point_ranges(ctx, subarray, 0, ranges, 4); + * @endcode + * + * @param[in] ctx The TileDB context. + * @param[in] subarray The subarray. + * @param[in] dim_idx The index of the dimension to add the range to. + * @param[in] start The range start. + * @param[in] count The number of points in the target array to add ranges on. + * + */ +TILEDB_EXPORT capi_return_t tiledb_subarray_add_point_ranges( + tiledb_ctx_t* ctx, + tiledb_subarray_t* subarray, + uint32_t dim_idx, + const void* start, + uint64_t count) TILEDB_NOEXCEPT; + +#ifdef __cplusplus +} +#endif + +#endif // TILEDB_CAPI_SUBARRAY_EXPERIMENTAL_H diff --git a/tiledb/api/c_api/subarray/subarray_api_external.h b/tiledb/api/c_api/subarray/subarray_api_external.h new file mode 100644 index 00000000000..c912af472d8 --- /dev/null +++ b/tiledb/api/c_api/subarray/subarray_api_external.h @@ -0,0 +1,523 @@ +/** + * @file tiledb/api/c_api/subarray/subarray_api_external.h + * + * @section LICENSE + * + * The MIT License + * + * @copyright Copyright (c) 2024 TileDB, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @section DESCRIPTION + * + * This file declares the Subarray C API for TileDB. + */ + +#ifndef TILEDB_CAPI_SUBARRAY_EXTERNAL_H +#define TILEDB_CAPI_SUBARRAY_EXTERNAL_H + +#include "../api_external_common.h" +#include "../array/array_api_external.h" +#include "../context/context_api_external.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** C API carrier for a TileDB subarray object. */ +typedef struct tiledb_subarray_handle_t tiledb_subarray_t; + +/** + * Allocates a TileDB subarray object. + * + * @note The allocated subarray initially has internal coalesce_ranges == true. + * + * **Example:** + * + * @code{.c} + * tiledb_subarray_t* subarray; + * tiledb_subarray_alloc(ctx, array, &subarray); + * @endcode + * + * @param[in] ctx The TileDB context. + * @param[in] array An open array object. + * @param[out] subarray The subarray object to be created. + * @return `TILEDB_OK` for success or `TILEDB_OOM` or `TILEDB_ERR` for error. + */ +TILEDB_EXPORT capi_return_t tiledb_subarray_alloc( + tiledb_ctx_t* ctx, + const tiledb_array_t* array, + tiledb_subarray_t** subarray) TILEDB_NOEXCEPT; + +/** + * Frees a TileDB subarray object. + * + * **Example:** + * + * @code{.c} + * tiledb_subarray_t* subarray; + * tiledb_array_open(ctx, array, TILEDB_READ); + * tiledb_subarray_alloc(ctx, array, &subarray); + * tiledb_array_close(ctx, array); + * tiledb_subarray_free(&subarray); + * @endcode + * + * @param[in] subarray The subarray object to be freed. + */ +TILEDB_EXPORT void tiledb_subarray_free(tiledb_subarray_t** subarray) + TILEDB_NOEXCEPT; + +/** + * Set the subarray config. + * + * @note This function _only_ overrides config parameter `sm.read_range_oob`. + * + * **Example:** + * + * @code{.c} + * tiledb_subarray_t* subarray; + * tiledb_subarray_alloc(ctx, array, &subarray); + * tiledb_config_t config; + * tiledb_subarray_set_config(ctx, subarray, &config); + * @endcode + * + * @param[in] ctx The TileDB context. + * @param[in] subarray The subarray object to set the config on. + * @param[in] config The config to set on the subarray. + */ +TILEDB_EXPORT capi_return_t tiledb_subarray_set_config( + tiledb_ctx_t* ctx, + tiledb_subarray_t* subarray, + tiledb_config_t* config) TILEDB_NOEXCEPT; + +/** + * Sets coalesce_ranges property on a TileDB subarray object. + * Intended to be used just after tiledb_subarray_alloc() to replace + * the initial coalesce_ranges == true with coalesce_ranges = false if needed. + * + * **Example:** + * + * @code{.c} + * tiledb_subarray_t* subarray; + * //tiledb_subarray_alloc internally defaults to 'coalesce_ranges == true' + * tiledb_subarray_alloc(ctx, array, &subarray); + * // so manually set to 'false' to match earlier behaviour with older + * // tiledb_query_ subarray actions. + * bool coalesce_ranges = false; + * tiledb_subarray_set_coalesce_ranges(ctx, subarray, coalesce_ranges); + * @endcode + * + * @param[in] ctx The TileDB context. + * @param[in] subarray The subarray object to change. + * @param[in] coalesce_ranges The true/false value to be set + * @return `TILEDB_OK` for success or `TILEDB_ERR` for error. + */ +TILEDB_EXPORT capi_return_t tiledb_subarray_set_coalesce_ranges( + tiledb_ctx_t* ctx, + tiledb_subarray_t* subarray, + int coalesce_ranges) TILEDB_NOEXCEPT; + +/** + * Populates a subarray with specific indicies. + * + * **Example:** + * + * The following sets a 2D subarray [0,10], [20, 30] on the subarray. + * + * @code{.c} + * tiledb_subarray_t *subarray; + * uint64_t subarray_v[] = { 0, 10, 20, 30}; + * tiledb_subarray_set_subarray(ctx, subarray, subarray_v); + * @endcode + * + * @param[in] ctx The TileDB context. + * @param[in] subarray The TileDB subarray object. + * @param[in] subarray_v The subarray values which can be used to limit the + * subarray read/write. + * It should be a sequence of [low, high] pairs (one pair per dimension). + * When the subarray is used for writes, this is meaningful only for dense + * arrays, and specifically dense writes. Note that `subarray_a` must have + * the same type as the domain of the subarray's associated array. + * @return `TILEDB_OK` for success or `TILEDB_ERR` for error. + */ +TILEDB_EXPORT capi_return_t tiledb_subarray_set_subarray( + tiledb_ctx_t* ctx, + tiledb_subarray_t* subarray, + const void* subarray_v) TILEDB_NOEXCEPT; + +/** + * Adds a 1D range along a subarray dimension index, which is in the form + * (start, end, stride). The datatype of the range components must be the same + * as the type of the domain of the array in the query. + * + * @note The stride is currently unsupported. Use 0/NULL/nullptr as the + * stride argument. + * + * **Example:** + * + * @code{.c} + * uint32_t dim_idx = 2; + * int64_t start = 10; + * int64_t end = 20; + * tiledb_subarray_add_range(ctx, subarray, dim_idx, &start, &end, nullptr); + * @endcode + * + * @param[in] ctx The TileDB context. + * @param[in] subarray The subarray to add the range to. + * @param[in] dim_idx The index of the dimension to add the range to. + * @param[in] start The range start. + * @param[in] end The range end. + * @param[in] stride The range stride. + * @return `TILEDB_OK` for success or `TILEDB_ERR` for error. + */ +TILEDB_EXPORT capi_return_t tiledb_subarray_add_range( + tiledb_ctx_t* ctx, + tiledb_subarray_t* subarray, + uint32_t dim_idx, + const void* start, + const void* end, + const void* stride) TILEDB_NOEXCEPT; + +/** + * Adds a 1D range along a subarray dimension name, which is in the form + * (start, end, stride). The datatype of the range components must be the same + * as the type of the domain of the array in the query. + * + * @note The stride is currently unsupported. Use 0/NULL/nullptr as the + * stride argument. + * + * **Example:** + * + * @code{.c} + * char* dim_name = "rows"; + * int64_t start = 10; + * int64_t end = 20; + * tiledb_subarray_add_range_by_name( + * ctx, subarray, dim_name, &start, &end, nullptr); + * @endcode + * + * @param[in] ctx The TileDB context. + * @param[in] subarray The subarray to add the range to. + * @param[in] dim_name The name of the dimension to add the range to. + * @param[in] start The range start. + * @param[in] end The range end. + * @param[in] stride The range stride. + * @return `TILEDB_OK` for success or `TILEDB_ERR` for error. + */ +TILEDB_EXPORT capi_return_t tiledb_subarray_add_range_by_name( + tiledb_ctx_t* ctx, + tiledb_subarray_t* subarray, + const char* dim_name, + const void* start, + const void* end, + const void* stride) TILEDB_NOEXCEPT; + +/** + * Adds a 1D variable-sized range along a subarray dimension index, which is in + * the form (start, end). Applicable only to variable-sized dimensions. + * + * **Example:** + * + * @code{.c} + * uint32_t dim_idx = 2; + * char start[] = "a"; + * char end[] = "bb"; + * tiledb_subarray_add_range_var(ctx, subarray, dim_idx, start, 1, end, 2); + * @endcode + * + * @param[in] ctx The TileDB context. + * @param[in] subarray The subarray to add the range to. + * @param[in] dim_idx The index of the dimension to add the range to. + * @param[in] start The range start. + * @param[in] start_size The size of the range start in bytes. + * @param[in] end The range end. + * @param[in] end_size The size of the range end in bytes. + * @return `TILEDB_OK` for success or `TILEDB_ERR` for error. + */ +TILEDB_EXPORT capi_return_t tiledb_subarray_add_range_var( + tiledb_ctx_t* ctx, + tiledb_subarray_t* subarray, + uint32_t dim_idx, + const void* start, + uint64_t start_size, + const void* end, + uint64_t end_size) TILEDB_NOEXCEPT; + +/** + * Adds a 1D variable-sized range along a subarray dimension name, which is in + * the form (start, end). Applicable only to variable-sized dimensions. + * + * **Example:** + * + * @code{.c} + * char* dim_name = "rows"; + * char start[] = "a"; + * char end[] = "bb"; + * tiledb_subarray_add_range_var_by_name( + * ctx, subarray, dim_name, start, 1, end, 2); + * @endcode + * + * @param[in] ctx The TileDB context. + * @param[in] subarray The subarray to add the range to. + * @param[in] dim_name The name of the dimension to add the range to. + * @param[in] start The range start. + * @param[in] start_size The size of the range start in bytes. + * @param[in] end The range end. + * @param[in] end_size The size of the range end in bytes. + * @return `TILEDB_OK` for success or `TILEDB_ERR` for error. + */ +TILEDB_EXPORT capi_return_t tiledb_subarray_add_range_var_by_name( + tiledb_ctx_t* ctx, + tiledb_subarray_t* subarray, + const char* dim_name, + const void* start, + uint64_t start_size, + const void* end, + uint64_t end_size) TILEDB_NOEXCEPT; + +/** + * Retrieves the number of ranges of the query subarray along a given dimension + * index. + * + * **Example:** + * + * @code{.c} + * uint64_t range_num; + * tiledb_subarray_get_range_num(ctx, subarray, dim_idx, &range_num); + * @endcode + * + * @param[in] ctx The TileDB context + * @param[in] subarray The subarray. + * @param[in] dim_idx The index of the dimension for which to retrieve number of + * ranges. + * @param[out] range_num The retrieved number of ranges. + * @return `TILEDB_OK` for success or `TILEDB_ERR` for error. + */ +TILEDB_EXPORT capi_return_t tiledb_subarray_get_range_num( + tiledb_ctx_t* ctx, + const tiledb_subarray_t* subarray, + uint32_t dim_idx, + uint64_t* range_num) TILEDB_NOEXCEPT; + +/** + * Retrieve the number of ranges of the subarray along a given dimension name. + * + * **Example:** + * + * @code{.c} + * uint64_t range_num; + * tiledb_subarray_get_range_num_from_name(ctx, subarray, dim_name, &range_num); + * @endcode + * + * @param[in] ctx The TileDB context + * @param[in] subarray The subarray. + * @param[in] dim_name The name of the dimension whose range number to retrieve. + * @param[out] range_num The retrieved number of ranges. + * @return `TILEDB_OK` for success or `TILEDB_ERR` for error. + */ +TILEDB_EXPORT capi_return_t tiledb_subarray_get_range_num_from_name( + tiledb_ctx_t* ctx, + const tiledb_subarray_t* subarray, + const char* dim_name, + uint64_t* range_num) TILEDB_NOEXCEPT; + +/** + * Retrieves a specific range of the subarray along a given dimension index. + * + * **Example:** + * + * @code{.c} + * const void* start; + * const void* end; + * const void* stride; + * tiledb_subarray_get_range( + * ctx, subarray, dim_idx, range_idx, &start, &end, &stride); + * @endcode + * + * @param[in] ctx The TileDB context + * @param[in] subarray The subarray. + * @param[in] dim_idx The index of the dimension to retrieve the range from. + * @param[in] range_idx The index of the range to retrieve. + * @param[out] start The retrieved range start. + * @param[out] end The received range end. + * @param[out] stride The retrieved range stride. + * @return `TILEDB_OK` for success or `TILEDB_ERR` for error. + */ +TILEDB_EXPORT capi_return_t tiledb_subarray_get_range( + tiledb_ctx_t* ctx, + const tiledb_subarray_t* subarray, + uint32_t dim_idx, + uint64_t range_idx, + const void** start, + const void** end, + const void** stride) TILEDB_NOEXCEPT; + +/** + * Retrieves a specific range of the subarray along a given dimension name. + * + * **Example:** + * + * @code{.c} + * const void* start; + * const void* end; + * const void* stride; + * tiledb_subarray_get_range_from_name( + * ctx, query, dim_name, range_idx, &start, &end, &stride); + * @endcode + * + * @param[in] ctx The TileDB context + * @param[in] subarray The subarray. + * @param[in] dim_name The name of the dimension to retrieve the range from. + * @param[in] range_idx The index of the range to retrieve. + * @param[out] start The retrieved range start. + * @param[out] end The retrieved range end. + * @param[out] stride The retrieved range stride. + * @return `TILEDB_OK` for success or `TILEDB_ERR` for error. + */ +TILEDB_EXPORT capi_return_t tiledb_subarray_get_range_from_name( + tiledb_ctx_t* ctx, + const tiledb_subarray_t* subarray, + const char* dim_name, + uint64_t range_idx, + const void** start, + const void** end, + const void** stride) TILEDB_NOEXCEPT; + +/** + * Retrieves a range's start and end size for a given variable-length + * dimension index at a given range index. + * + * **Example:** + * + * @code{.c} + * uint64_t start_size; + * uint64_t end_size; + * tiledb_subarray_get_range_var_size( + * ctx, subarray, dim_idx, range_idx, &start_size, &end_size); + * @endcode + * + * @param[in] ctx The TileDB context + * @param[in] subarray The subarray. + * @param[in] dim_idx The index of the dimension to retrieve the range from. + * @param[in] range_idx The index of the range to retrieve. + * @param[out] start_size The retrieved range start size in bytes + * @param[out] end_size The retrieved range end size in bytes + * @return `TILEDB_OK` for success or `TILEDB_ERR` for error. + */ +TILEDB_EXPORT capi_return_t tiledb_subarray_get_range_var_size( + tiledb_ctx_t* ctx, + const tiledb_subarray_t* subarray, + uint32_t dim_idx, + uint64_t range_idx, + uint64_t* start_size, + uint64_t* end_size) TILEDB_NOEXCEPT; + +/** + * Retrieves a range's start and end size for a given variable-length + * dimension name at a given range index. + * + * **Example:** + * + * @code{.c} + * uint64_t start_size; + * uint64_t end_size; + * tiledb_subarray_get_range_var_size_from_name( + * ctx, subarray, dim_name, range_idx, &start_size, &end_size); + * @endcode + * + * @param[in] ctx The TileDB context + * @param[in] subarray The subarray. + * @param[in] dim_name The name of the dimension to retrieve the range from. + * @param[in] range_idx The index of the range to retrieve. + * @param[out] start_size The retrieved range start size in bytes + * @param[out] end_size The retrieved range end size in bytes + * @return `TILEDB_OK` for success or `TILEDB_ERR` for error. + */ +TILEDB_EXPORT capi_return_t tiledb_subarray_get_range_var_size_from_name( + tiledb_ctx_t* ctx, + const tiledb_subarray_t* subarray, + const char* dim_name, + uint64_t range_idx, + uint64_t* start_size, + uint64_t* end_size) TILEDB_NOEXCEPT; + +/** + * Retrieves a specific range of the subarray along a given + * variable-length dimension index. + * + * **Example:** + * + * @code{.c} + * const void* start; + * const void* end; + * tiledb_subarray_get_range_var( + * ctx, subarray, dim_idx, range_idx, &start, &end); + * @endcode + * + * @param[in] ctx The TileDB context + * @param[in] subarray The subarray. + * @param[in] dim_idx The index of the dimension to retrieve the range from. + * @param[in] range_idx The index of the range to retrieve. + * @param[out] start The retrieved range start. + * @param[out] end The retrieved range end. + * @return `TILEDB_OK` for success or `TILEDB_ERR` for error. + */ +TILEDB_EXPORT capi_return_t tiledb_subarray_get_range_var( + tiledb_ctx_t* ctx, + const tiledb_subarray_t* subarray, + uint32_t dim_idx, + uint64_t range_idx, + void* start, + void* end) TILEDB_NOEXCEPT; + +/** + * Retrieves a specific range of the subarray along a given + * variable-length dimension name. + * + * **Example:** + * + * @code{.c} + * const void* start; + * const void* end; + * tiledb_subarray_get_range_var_from_name( + * ctx, subarray, dim_name, range_idx, &start, &end); + * @endcode + * + * @param[in] ctx The TileDB context + * @param[in] subarray The subarray. + * @param[in] dim_name The name of the dimension to retrieve the range from. + * @param[in] range_idx The index of the range to retrieve. + * @param[out] start The retrieved range start. + * @param[out] end The retrieved range end. + * @return `TILEDB_OK` for success or `TILEDB_ERR` for error. + */ +TILEDB_EXPORT capi_return_t tiledb_subarray_get_range_var_from_name( + tiledb_ctx_t* ctx, + const tiledb_subarray_t* subarray, + const char* dim_name, + uint64_t range_idx, + void* start, + void* end) TILEDB_NOEXCEPT; + +#ifdef __cplusplus +} +#endif + +#endif // TILEDB_CAPI_SUBARRAY_EXTERNAL_H diff --git a/tiledb/api/c_api/subarray/subarray_api_internal.h b/tiledb/api/c_api/subarray/subarray_api_internal.h new file mode 100644 index 00000000000..18db4646f71 --- /dev/null +++ b/tiledb/api/c_api/subarray/subarray_api_internal.h @@ -0,0 +1,267 @@ +/** + * @file tiledb/api/c_api/subarray/subarray_api_internal.h + * + * @section LICENSE + * + * The MIT License + * + * @copyright Copyright (c) 2024 TileDB, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @section DESCRIPTION + * + * This file declares the internals of the subarray section of the C API. + */ + +#ifndef TILEDB_CAPI_SUBARRAY_INTERNAL_H +#define TILEDB_CAPI_SUBARRAY_INTERNAL_H + +#include "subarray_api_external.h" + +#include "tiledb/api/c_api/context/context_api_internal.h" +#include "tiledb/api/c_api_support/handle/handle.h" +#include "tiledb/common/common.h" +#include "tiledb/sm/subarray/subarray.h" +#include "tiledb/sm/subarray/subarray_partitioner.h" + +/** Handle `struct` for API Subarray objects. */ +struct tiledb_subarray_handle_t + : public tiledb::api::CAPIHandle { + /** Type name */ + static constexpr std::string_view object_type_name{"subarray"}; + + private: + using subarray_type = shared_ptr; + subarray_type subarray_; + + public: + template + explicit tiledb_subarray_handle_t(Args... args) + : subarray_{make_shared( + HERE(), std::forward(args)...)} { + } + + explicit tiledb_subarray_handle_t(const tiledb::sm::Subarray& subarray) + : subarray_{make_shared(HERE(), subarray)} { + } + + /** + * Constructor from `shared_ptr` copies the shared pointer. + */ + explicit tiledb_subarray_handle_t(const subarray_type& x) + : subarray_(x) { + } + + subarray_type subarray() const { + return subarray_; + } + + void add_label_range( + const std::string& label_name, const void* start, const void* end) { + subarray_->add_label_range(label_name, start, end); + } + + void add_label_range_var( + const std::string& label_name, + const void* start, + uint64_t start_size, + const void* end, + uint64_t end_size) { + subarray_->add_label_range_var( + label_name, start, start_size, end, end_size); + } + + void add_point_ranges( + unsigned dim_idx, const void* start, uint64_t count, bool check = true) { + subarray_->add_point_ranges(dim_idx, start, count, check); + } + + void add_range(unsigned dim_idx, const void* start, const void* end) { + subarray_->add_range(dim_idx, start, end); + } + + void add_range_by_name( + const std::string& dim_name, const void* start, const void* end) { + subarray_->add_range_by_name(dim_name, start, end); + } + + void add_range_unsafe(uint32_t dim_idx, const Range& range) { + subarray_->add_range_unsafe(dim_idx, range); + } + + void add_range_var( + unsigned dim_idx, + const void* start, + uint64_t start_size, + const void* end, + uint64_t end_size) { + subarray_->add_range_var(dim_idx, start, start_size, end, end_size); + } + + void add_range_var_by_name( + const std::string& dim_name, + const void* start, + uint64_t start_size, + const void* end, + uint64_t end_size) { + subarray_->add_range_var_by_name( + dim_name, start, start_size, end, end_size); + } + + bool coalesce_ranges() const { + return subarray_->coalesce_ranges(); + } + + const std::vector& get_attribute_ranges( + const std::string& attr_name) const { + return subarray_->get_attribute_ranges(attr_name); + } + + const std::string& get_label_name(const uint32_t dim_index) const { + return subarray_->get_label_name(dim_index); + } + + void get_label_range( + const std::string& label_name, + uint64_t range_idx, + const void** start, + const void** end) const { + subarray_->get_label_range(label_name, range_idx, start, end); + } + + void get_label_range_num( + const std::string& label_name, uint64_t* range_num) const { + subarray_->get_label_range_num(label_name, range_num); + } + + void get_label_range_var( + const std::string& label_name, + uint64_t range_idx, + void* start, + void* end) const { + subarray_->get_label_range_var(label_name, range_idx, start, end); + } + + void get_label_range_var_size( + const std::string& label_name, + uint64_t range_idx, + uint64_t* start_size, + uint64_t* end_size) const { + subarray_->get_label_range_var_size( + label_name, range_idx, start_size, end_size); + } + + void get_range( + uint32_t dim_idx, + uint64_t range_idx, + const void** start, + const void** end) const { + subarray_->get_range(dim_idx, range_idx, start, end); + } + + void get_range_from_name( + const std::string& dim_name, + uint64_t range_idx, + const void** start, + const void** end) const { + subarray_->get_range_from_name(dim_name, range_idx, start, end); + } + + void get_range_num(uint32_t dim_idx, uint64_t* range_num) const { + subarray_->get_range_num(dim_idx, range_num); + } + + void get_range_num_from_name( + const std::string& dim_name, uint64_t* range_num) const { + subarray_->get_range_num_from_name(dim_name, range_num); + } + + void get_range_var( + unsigned dim_idx, uint64_t range_idx, void* start, void* end) const { + subarray_->get_range_var(dim_idx, range_idx, start, end); + } + + void get_range_var_from_name( + const std::string& dim_name, + uint64_t range_idx, + void* start, + void* end) const { + subarray_->get_range_var_from_name(dim_name, range_idx, start, end); + } + + void get_range_var_size( + uint32_t dim_idx, + uint64_t range_idx, + uint64_t* start_size, + uint64_t* end_size) const { + subarray_->get_range_var_size(dim_idx, range_idx, start_size, end_size); + } + + void get_range_var_size_from_name( + const std::string& dim_name, + uint64_t range_idx, + uint64_t* start_size, + uint64_t* end_size) const { + subarray_->get_range_var_size_from_name( + dim_name, range_idx, start_size, end_size); + } + + bool has_label_ranges(const uint32_t dim_index) const { + return subarray_->has_label_ranges(dim_index); + } + + const std::vector& ranges_for_dim(uint32_t dim_idx) const { + return subarray_->ranges_for_dim(dim_idx); + } + + void set_attribute_ranges( + const std::string& attr_name, const std::vector& ranges) { + subarray_->set_attribute_ranges(attr_name, ranges); + } + + void set_coalesce_ranges(bool coalesce_ranges = true) { + subarray_->set_coalesce_ranges(coalesce_ranges); + } + + void set_config( + const tiledb::sm::QueryType query_type, + const tiledb::sm::Config& config) { + subarray_->set_config(query_type, config); + } + + void set_subarray(const void* subarray) { + subarray_->set_subarray(subarray); + } +}; + +namespace tiledb::api { + +/** + * Returns after successfully validating a subarray object. + * + * @param subarray Possibly-valid pointer to a subarray object. + */ +inline void ensure_subarray_is_valid(const tiledb_subarray_t* subarray) { + ensure_handle_is_valid(subarray); +} + +} // namespace tiledb::api + +#endif // TILEDB_CAPI_SUBARRAY_INTERNAL_H diff --git a/tiledb/api/c_api/subarray/test/CMakeLists.txt b/tiledb/api/c_api/subarray/test/CMakeLists.txt new file mode 100644 index 00000000000..8c123b3dc01 --- /dev/null +++ b/tiledb/api/c_api/subarray/test/CMakeLists.txt @@ -0,0 +1,33 @@ +# +# tiledb/api/c_api/subarray/test/CMakeLists.txt +# +# The MIT License +# +# Copyright (c) 2024 TileDB, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# + +include(unit_test) + +commence(unit_test capi_subarray) + this_target_sources(unit_capi_subarray.cc) + this_target_object_libraries(capi_subarray_stub) + this_target_link_libraries(tiledb_test_support_lib) +conclude(unit_test) diff --git a/tiledb/api/c_api/subarray/test/compile_capi_subarray_stub_main.cc b/tiledb/api/c_api/subarray/test/compile_capi_subarray_stub_main.cc new file mode 100644 index 00000000000..b5cf6f809f7 --- /dev/null +++ b/tiledb/api/c_api/subarray/test/compile_capi_subarray_stub_main.cc @@ -0,0 +1,35 @@ +/** + * @file + * tiledb/api/c_api/subarray/test/compile_capi_subarray_stub_main.cc + * + * @section LICENSE + * + * The MIT License + * + * @copyright Copyright (c) 2024 TileDB, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "../subarray_api_external.h" + +int main() { + tiledb_subarray_set_config(nullptr, nullptr, nullptr); + return 0; +} diff --git a/tiledb/api/c_api/subarray/test/unit_capi_subarray.cc b/tiledb/api/c_api/subarray/test/unit_capi_subarray.cc new file mode 100644 index 00000000000..1e542bbb604 --- /dev/null +++ b/tiledb/api/c_api/subarray/test/unit_capi_subarray.cc @@ -0,0 +1,709 @@ +/** + * @file tiledb/api/c_api/subarray/test/unit_capi_subarray.cc + * + * @section LICENSE + * + * The MIT License + * + * @copyright Copyright (c) 2024 TileDB, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Validates the arguments for the Subarray C API. + */ + +#define CATCH_CONFIG_MAIN +#include +#include "../../../c_api_test_support/testsupport_capi_subarray.h" +#include "../subarray_api_experimental.h" +#include "../subarray_api_external.h" +#include "../subarray_api_internal.h" + +using namespace tiledb::api::test_support; + +TEST_CASE( + "C API: tiledb_subarray_alloc argument validation", "[capi][subarray]") { + capi_return_t rc; + ordinary_array x{}; + x.open(); // The array must be open. + tiledb_subarray_handle_t* subarray{}; + + SECTION("success") { + rc = tiledb_subarray_alloc(x.ctx(), x.array, &subarray); + REQUIRE(tiledb_status(rc) == TILEDB_OK); + tiledb_subarray_free(&subarray); + CHECK(subarray == nullptr); + } + SECTION("null context") { + rc = tiledb_subarray_alloc(nullptr, x.array, &subarray); + REQUIRE(tiledb_status(rc) == TILEDB_INVALID_CONTEXT); + } + SECTION("null array") { + rc = tiledb_subarray_alloc(x.ctx(), nullptr, &subarray); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("invalid array") { + x.close(); + rc = tiledb_subarray_alloc(x.ctx(), x.array, &subarray); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("null subarray") { + rc = tiledb_subarray_alloc(x.ctx(), x.array, nullptr); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } +} + +TEST_CASE( + "C API: tiledb_subarray_free argument validation", "[capi][subarray]") { + ordinary_array x{}; + x.open(); // The array must be open. + tiledb_subarray_handle_t* subarray{}; + auto rc = tiledb_subarray_alloc(x.ctx(), x.array, &subarray); + REQUIRE(tiledb_status(rc) == TILEDB_OK); + SECTION("success") { + REQUIRE_NOTHROW(tiledb_subarray_free(&subarray)); + CHECK(subarray == nullptr); + } + SECTION("null subarray") { + /* + * `tiledb_subarray_free` is a void function, otherwise we would check + * for an error. + */ + REQUIRE_NOTHROW(tiledb_subarray_free(nullptr)); + } +} + +TEST_CASE( + "C API: tiledb_subarray_set_config argument validation", + "[capi][subarray]") { + capi_return_t rc; + ordinary_subarray x{}; + tiledb_config_handle_t* config; + tiledb_error_handle_t* err; + rc = tiledb_config_alloc(&config, &err); + REQUIRE(tiledb_status(rc) == TILEDB_OK); + + SECTION("success") { + rc = tiledb_subarray_set_config(x.ctx(), x.subarray, config); + REQUIRE(tiledb_status(rc) == TILEDB_OK); + REQUIRE_NOTHROW(tiledb_config_free(&config)); + CHECK(config == nullptr); + } + SECTION("null context") { + rc = tiledb_subarray_set_config(nullptr, x.subarray, config); + REQUIRE(tiledb_status(rc) == TILEDB_INVALID_CONTEXT); + } + SECTION("null subarray") { + rc = tiledb_subarray_set_config(x.ctx(), nullptr, config); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("null config") { + rc = tiledb_subarray_set_config(x.ctx(), x.subarray, nullptr); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } +} + +TEST_CASE( + "C API: tiledb_subarray_set_coalesce_ranges argument validation", + "[capi][subarray]") { + capi_return_t rc; + ordinary_subarray x{}; + SECTION("success") { + rc = tiledb_subarray_set_coalesce_ranges(x.ctx(), x.subarray, 0); + REQUIRE(tiledb_status(rc) == TILEDB_OK); + } + SECTION("null context") { + rc = tiledb_subarray_set_coalesce_ranges(nullptr, x.subarray, 0); + REQUIRE(tiledb_status(rc) == TILEDB_INVALID_CONTEXT); + } + SECTION("null subarray") { + rc = tiledb_subarray_set_coalesce_ranges(x.ctx(), nullptr, 0); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } +} + +TEST_CASE( + "C API: tiledb_subarray_set_subarray argument validation", + "[capi][subarray]") { + capi_return_t rc; + ordinary_subarray x{}; + int subarray_v[] = {1, 4}; // The domain range + SECTION("success") { + rc = tiledb_subarray_set_subarray(x.ctx(), x.subarray, subarray_v); + REQUIRE(tiledb_status(rc) == TILEDB_OK); + } + SECTION("null context") { + rc = tiledb_subarray_set_subarray(nullptr, x.subarray, subarray_v); + REQUIRE(tiledb_status(rc) == TILEDB_INVALID_CONTEXT); + } + SECTION("null subarray") { + rc = tiledb_subarray_set_subarray(x.ctx(), nullptr, subarray_v); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("invalid subarray_v") { + int subarray_inv[] = {10, 20}; + rc = tiledb_subarray_set_subarray(x.ctx(), x.subarray, subarray_inv); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } +} + +TEST_CASE( + "C API: tiledb_subarray_add_point_ranges argument validation", + "[capi][subarray]") { + capi_return_t rc; + ordinary_subarray x{}; + int ranges[] = {1, 4}; // The domain range + SECTION("success") { + rc = tiledb_subarray_add_point_ranges(x.ctx(), x.subarray, 0, ranges, 2); + REQUIRE(tiledb_status(rc) == TILEDB_OK); + } + SECTION("null context") { + rc = tiledb_subarray_add_point_ranges(nullptr, x.subarray, 0, ranges, 2); + REQUIRE(tiledb_status(rc) == TILEDB_INVALID_CONTEXT); + } + SECTION("null subarray") { + rc = tiledb_subarray_add_point_ranges(x.ctx(), nullptr, 0, ranges, 2); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("invalid dim_idx") { + rc = tiledb_subarray_add_point_ranges(x.ctx(), x.subarray, 3, ranges, 2); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("invalid ranges") { + int ranges_inv[] = {10, 20}; + rc = + tiledb_subarray_add_point_ranges(x.ctx(), x.subarray, 0, ranges_inv, 2); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("invalid count") { + rc = tiledb_subarray_add_point_ranges(x.ctx(), x.subarray, 0, ranges, 20); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } +} + +TEST_CASE( + "C API: tiledb_subarray_add_range argument validation", + "[capi][subarray]") { + capi_return_t rc; + ordinary_subarray x{}; + int start = 1, end = 4; // The domain range + const void* stride = nullptr; // Stride is not yet supported. + SECTION("success") { + rc = + tiledb_subarray_add_range(x.ctx(), x.subarray, 0, &start, &end, stride); + REQUIRE(tiledb_status(rc) == TILEDB_OK); + } + SECTION("null context") { + rc = + tiledb_subarray_add_range(nullptr, x.subarray, 0, &start, &end, stride); + REQUIRE(tiledb_status(rc) == TILEDB_INVALID_CONTEXT); + } + SECTION("null subarray") { + rc = tiledb_subarray_add_range(x.ctx(), nullptr, 0, &start, &end, stride); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("invalid dim_idx") { + rc = + tiledb_subarray_add_range(x.ctx(), x.subarray, 2, &start, &end, stride); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("invalid start") { + int start_inv = 10; + rc = tiledb_subarray_add_range( + x.ctx(), x.subarray, 2, &start_inv, &end, stride); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("invalid end") { + int end_inv = 20; + rc = tiledb_subarray_add_range( + x.ctx(), x.subarray, 2, &start, &end_inv, stride); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + /** + * No "invalid stride" section here; + * The stride is currently unsupported. All usage resolves to `nullptr`. + */ +} + +TEST_CASE( + "C API: tiledb_subarray_add_range_by_name argument validation", + "[capi][subarray]") { + capi_return_t rc; + ordinary_subarray x{}; + const char* dim_name = "dim"; // The dimension name + int start = 1, end = 4; // The domain range + const void* stride = nullptr; // Stride is not yet supported. + SECTION("success") { + rc = tiledb_subarray_add_range_by_name( + x.ctx(), x.subarray, dim_name, &start, &end, stride); + REQUIRE(tiledb_status(rc) == TILEDB_OK); + } + SECTION("null context") { + rc = tiledb_subarray_add_range_by_name( + nullptr, x.subarray, dim_name, &start, &end, stride); + REQUIRE(tiledb_status(rc) == TILEDB_INVALID_CONTEXT); + } + SECTION("null subarray") { + rc = tiledb_subarray_add_range_by_name( + x.ctx(), nullptr, dim_name, &start, &end, stride); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("invalid dim_name") { + rc = tiledb_subarray_add_range_by_name( + x.ctx(), x.subarray, "invalid", &start, &end, stride); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("invalid start") { + int start_inv = 10; + rc = tiledb_subarray_add_range_by_name( + x.ctx(), x.subarray, dim_name, &start_inv, &end, stride); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("invalid end") { + int end_inv = 10; + rc = tiledb_subarray_add_range_by_name( + x.ctx(), x.subarray, dim_name, &start, &end_inv, stride); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + /** + * No "invalid stride" section here; + * The stride is currently unsupported. All usage resolves to `nullptr`. + */ +} + +TEST_CASE( + "C API: tiledb_subarray_add_range_var argument validation", + "[capi][subarray]") { + capi_return_t rc; + ordinary_subarray_var x{}; + char start[] = "start", end[] = "end"; + SECTION("success") { + rc = + tiledb_subarray_add_range_var(x.ctx(), x.subarray, 0, start, 5, end, 3); + REQUIRE(tiledb_status(rc) == TILEDB_OK); + } + SECTION("null context") { + rc = + tiledb_subarray_add_range_var(nullptr, x.subarray, 0, start, 5, end, 3); + REQUIRE(tiledb_status(rc) == TILEDB_INVALID_CONTEXT); + } + SECTION("null subarray") { + rc = tiledb_subarray_add_range_var(x.ctx(), nullptr, 0, start, 5, end, 3); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("invalid dim_idx") { + rc = + tiledb_subarray_add_range_var(x.ctx(), x.subarray, 2, start, 5, end, 3); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("null start") { + rc = tiledb_subarray_add_range_var( + x.ctx(), x.subarray, 0, nullptr, 5, end, 3); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("null end") { + rc = tiledb_subarray_add_range_var( + x.ctx(), x.subarray, 0, start, 5, nullptr, 3); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + /** + * No "invalid [start, end]_size" sections here; + * All values, including 0 (empty range), are valid. + */ +} + +TEST_CASE( + "C API: tiledb_subarray_add_range_var_by_name argument validation", + "[capi][subarray]") { + capi_return_t rc; + ordinary_subarray_var x{}; + const char* dim_name = "dim"; // The dimension name + char start[] = "start", end[] = "end"; + SECTION("success") { + rc = tiledb_subarray_add_range_var_by_name( + x.ctx(), x.subarray, dim_name, start, 5, end, 3); + REQUIRE(tiledb_status(rc) == TILEDB_OK); + } + SECTION("null context") { + rc = tiledb_subarray_add_range_var_by_name( + nullptr, x.subarray, dim_name, start, 5, end, 3); + REQUIRE(tiledb_status(rc) == TILEDB_INVALID_CONTEXT); + } + SECTION("null subarray") { + rc = tiledb_subarray_add_range_var_by_name( + x.ctx(), nullptr, dim_name, start, 5, end, 3); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("invalid dim_name") { + rc = tiledb_subarray_add_range_var_by_name( + x.ctx(), x.subarray, "invalid", start, 5, end, 3); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("null start") { + rc = tiledb_subarray_add_range_var_by_name( + x.ctx(), x.subarray, dim_name, nullptr, 5, end, 3); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("null end") { + rc = tiledb_subarray_add_range_var_by_name( + x.ctx(), x.subarray, dim_name, start, 5, nullptr, 3); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + /** + * No "invalid [start, end]_size" sections here; + * All values, including 0 (empty range), are valid. + */ +} + +TEST_CASE( + "C API: tiledb_subarray_get_range_num argument validation", + "[capi][subarray]") { + capi_return_t rc; + ordinary_subarray x{}; + uint64_t range_num; + SECTION("success") { + rc = tiledb_subarray_get_range_num(x.ctx(), x.subarray, 0, &range_num); + REQUIRE(tiledb_status(rc) == TILEDB_OK); + } + SECTION("null context") { + rc = tiledb_subarray_get_range_num(nullptr, x.subarray, 0, &range_num); + REQUIRE(tiledb_status(rc) == TILEDB_INVALID_CONTEXT); + } + SECTION("null subarray") { + rc = tiledb_subarray_get_range_num(x.ctx(), nullptr, 0, &range_num); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("invalid dim_idx") { + rc = tiledb_subarray_get_range_num(x.ctx(), x.subarray, 2, &range_num); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("null range_num") { + rc = tiledb_subarray_get_range_num(x.ctx(), x.subarray, 0, nullptr); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } +} + +TEST_CASE( + "C API: tiledb_subarray_get_range_num_from_name argument validation", + "[capi][subarray]") { + capi_return_t rc; + ordinary_subarray x{}; + const char* dim_name = "dim"; // The dimension name + uint64_t range_num; + SECTION("success") { + rc = tiledb_subarray_get_range_num_from_name( + x.ctx(), x.subarray, dim_name, &range_num); + REQUIRE(tiledb_status(rc) == TILEDB_OK); + } + SECTION("null context") { + rc = tiledb_subarray_get_range_num_from_name( + nullptr, x.subarray, dim_name, &range_num); + REQUIRE(tiledb_status(rc) == TILEDB_INVALID_CONTEXT); + } + SECTION("null subarray") { + rc = tiledb_subarray_get_range_num_from_name( + x.ctx(), nullptr, dim_name, &range_num); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("invalid dim_name") { + rc = tiledb_subarray_get_range_num_from_name( + x.ctx(), x.subarray, "invalid", &range_num); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("null range_num") { + rc = tiledb_subarray_get_range_num_from_name( + x.ctx(), x.subarray, dim_name, nullptr); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } +} + +TEST_CASE( + "C API: tiledb_subarray_get_range argument validation", + "[capi][subarray]") { + capi_return_t rc; + ordinary_subarray x{}; + const void *start, *end, *stride; + SECTION("success") { + rc = tiledb_subarray_get_range( + x.ctx(), x.subarray, 0, 0, &start, &end, &stride); + REQUIRE(tiledb_status(rc) == TILEDB_OK); + } + SECTION("null context") { + rc = tiledb_subarray_get_range( + nullptr, x.subarray, 0, 0, &start, &end, &stride); + REQUIRE(tiledb_status(rc) == TILEDB_INVALID_CONTEXT); + } + SECTION("null subarray") { + rc = tiledb_subarray_get_range( + x.ctx(), nullptr, 0, 0, &start, &end, &stride); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("invalid dim_idx") { + rc = tiledb_subarray_get_range( + x.ctx(), x.subarray, 2, 0, &start, &end, &stride); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("invalid range_idx") { + rc = tiledb_subarray_get_range( + x.ctx(), x.subarray, 0, 2, &start, &end, &stride); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("null start") { + rc = tiledb_subarray_get_range( + x.ctx(), x.subarray, 0, 0, nullptr, &end, &stride); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("null end") { + rc = tiledb_subarray_get_range( + x.ctx(), x.subarray, 0, 0, &start, nullptr, &stride); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + /** + * No "invalid stride" section here; + * The stride is currently unsupported. All usage resolves to `nullptr`. + */ +} + +TEST_CASE( + "C API: tiledb_subarray_get_range_from_name argument validation", + "[capi][subarray]") { + capi_return_t rc; + ordinary_subarray x{}; + const char* dim_name = "dim"; // The dimension name + const void *start, *end, *stride; + SECTION("success") { + rc = tiledb_subarray_get_range_from_name( + x.ctx(), x.subarray, dim_name, 0, &start, &end, &stride); + REQUIRE(tiledb_status(rc) == TILEDB_OK); + } + SECTION("null context") { + rc = tiledb_subarray_get_range_from_name( + nullptr, x.subarray, dim_name, 0, &start, &end, &stride); + REQUIRE(tiledb_status(rc) == TILEDB_INVALID_CONTEXT); + } + SECTION("null subarray") { + rc = tiledb_subarray_get_range_from_name( + x.ctx(), nullptr, dim_name, 0, &start, &end, &stride); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("invalid dim_name") { + rc = tiledb_subarray_get_range_from_name( + x.ctx(), x.subarray, "invalid", 0, &start, &end, &stride); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("invalid range_idx") { + rc = tiledb_subarray_get_range_from_name( + x.ctx(), x.subarray, dim_name, 2, &start, &end, &stride); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("null start") { + rc = tiledb_subarray_get_range_from_name( + x.ctx(), x.subarray, dim_name, 0, nullptr, &end, &stride); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("null end") { + rc = tiledb_subarray_get_range_from_name( + x.ctx(), x.subarray, dim_name, 0, &start, nullptr, &stride); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + /** + * No "invalid stride" section here; + * The stride is currently unsupported. All usage resolves to `nullptr`. + */ +} + +TEST_CASE( + "C API: tiledb_subarray_get_range_var_size argument validation", + "[capi][subarray]") { + capi_return_t rc; + ordinary_subarray_var x{}; + uint64_t start_size, end_size; + SECTION("success") { + rc = tiledb_subarray_get_range_var_size( + x.ctx(), x.subarray, 0, 0, &start_size, &end_size); + REQUIRE(tiledb_status(rc) == TILEDB_OK); + } + SECTION("null context") { + rc = tiledb_subarray_get_range_var_size( + nullptr, x.subarray, 0, 0, &start_size, &end_size); + REQUIRE(tiledb_status(rc) == TILEDB_INVALID_CONTEXT); + } + SECTION("null subarray") { + rc = tiledb_subarray_get_range_var_size( + x.ctx(), nullptr, 0, 0, &start_size, &end_size); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("invalid dim_idx") { + rc = tiledb_subarray_get_range_var_size( + x.ctx(), x.subarray, 2, 0, &start_size, &end_size); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("invalid range_idx") { + rc = tiledb_subarray_get_range_var_size( + x.ctx(), x.subarray, 0, 2, &start_size, &end_size); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("null start_size") { + rc = tiledb_subarray_get_range_var_size( + x.ctx(), x.subarray, 0, 0, nullptr, &end_size); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("null end_size") { + rc = tiledb_subarray_get_range_var_size( + x.ctx(), x.subarray, 0, 0, &start_size, nullptr); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } +} + +TEST_CASE( + "C API: tiledb_subarray_get_range_var_size_from_name argument validation", + "[capi][subarray]") { + capi_return_t rc; + ordinary_subarray_var x{}; + const char* dim_name = "dim"; // The dimension name + uint64_t start_size, end_size; + SECTION("success") { + rc = tiledb_subarray_get_range_var_size_from_name( + x.ctx(), x.subarray, dim_name, 0, &start_size, &end_size); + REQUIRE(tiledb_status(rc) == TILEDB_OK); + } + SECTION("null context") { + rc = tiledb_subarray_get_range_var_size_from_name( + nullptr, x.subarray, dim_name, 0, &start_size, &end_size); + REQUIRE(tiledb_status(rc) == TILEDB_INVALID_CONTEXT); + } + SECTION("null subarray") { + rc = tiledb_subarray_get_range_var_size_from_name( + x.ctx(), nullptr, dim_name, 0, &start_size, &end_size); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("invalid dim_name") { + rc = tiledb_subarray_get_range_var_size_from_name( + x.ctx(), x.subarray, "invalid", 0, &start_size, &end_size); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("invalid range_idx") { + rc = tiledb_subarray_get_range_var_size_from_name( + x.ctx(), x.subarray, "invalid", 2, &start_size, &end_size); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("null start_size") { + rc = tiledb_subarray_get_range_var_size_from_name( + x.ctx(), x.subarray, dim_name, 0, nullptr, &end_size); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("null end_size") { + rc = tiledb_subarray_get_range_var_size_from_name( + x.ctx(), x.subarray, dim_name, 0, &start_size, nullptr); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } +} + +TEST_CASE( + "C API: tiledb_subarray_get_range_var argument validation", + "[capi][subarray]") { + capi_return_t rc; + ordinary_subarray_var x{}; + + // Add a range to be fetched + char start[] = "start", end[] = "end"; + rc = tiledb_subarray_add_range_var(x.ctx(), x.subarray, 0, start, 5, end, 3); + REQUIRE(tiledb_status(rc) == TILEDB_OK); + + SECTION("success") { + rc = tiledb_subarray_get_range_var(x.ctx(), x.subarray, 0, 0, &start, &end); + REQUIRE(tiledb_status(rc) == TILEDB_OK); + } + SECTION("null context") { + rc = tiledb_subarray_get_range_var(nullptr, x.subarray, 0, 0, &start, &end); + REQUIRE(tiledb_status(rc) == TILEDB_INVALID_CONTEXT); + } + SECTION("null subarray") { + rc = tiledb_subarray_get_range_var(x.ctx(), nullptr, 0, 0, &start, &end); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("invalid dim_idx") { + rc = tiledb_subarray_get_range_var(x.ctx(), x.subarray, 2, 0, &start, &end); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("invalid range_idx") { + rc = tiledb_subarray_get_range_var(x.ctx(), x.subarray, 0, 2, &start, &end); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("null start") { + rc = + tiledb_subarray_get_range_var(x.ctx(), x.subarray, 0, 0, nullptr, &end); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("null end") { + rc = tiledb_subarray_get_range_var( + x.ctx(), x.subarray, 0, 0, &start, nullptr); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } +} + +TEST_CASE( + "C API: tiledb_subarray_get_range_var_from_name argument validation", + "[capi][subarray]") { + capi_return_t rc; + ordinary_subarray_var x{}; + const char* dim_name = "dim"; // The dimension name + + // Add a range to be fetched + char start[] = "start", end[] = "end"; + rc = tiledb_subarray_add_range_var_by_name( + x.ctx(), x.subarray, dim_name, start, 5, end, 3); + REQUIRE(tiledb_status(rc) == TILEDB_OK); + + SECTION("success") { + rc = tiledb_subarray_get_range_var_from_name( + x.ctx(), x.subarray, dim_name, 0, &start, &end); + REQUIRE(tiledb_status(rc) == TILEDB_OK); + } + SECTION("null context") { + rc = tiledb_subarray_get_range_var_from_name( + nullptr, x.subarray, dim_name, 0, &start, &end); + REQUIRE(tiledb_status(rc) == TILEDB_INVALID_CONTEXT); + } + SECTION("null subarray") { + rc = tiledb_subarray_get_range_var_from_name( + x.ctx(), nullptr, dim_name, 0, &start, &end); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("invalid dim_name") { + rc = tiledb_subarray_get_range_var_from_name( + x.ctx(), x.subarray, "invalid", 0, &start, &end); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("invalid range_idx") { + rc = tiledb_subarray_get_range_var_from_name( + x.ctx(), x.subarray, dim_name, 2, &start, &end); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("null start") { + rc = tiledb_subarray_get_range_var_from_name( + x.ctx(), x.subarray, dim_name, 0, nullptr, &end); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } + SECTION("null end") { + rc = tiledb_subarray_get_range_var_from_name( + x.ctx(), x.subarray, dim_name, 0, &start, nullptr); + REQUIRE(tiledb_status(rc) == TILEDB_ERR); + } +} diff --git a/tiledb/api/c_api_test_support/testsupport_capi_subarray.h b/tiledb/api/c_api_test_support/testsupport_capi_subarray.h new file mode 100644 index 00000000000..d29fc6da7a1 --- /dev/null +++ b/tiledb/api/c_api_test_support/testsupport_capi_subarray.h @@ -0,0 +1,95 @@ +/** + * @file tiledb/api/c_api_test_support/testsupport_capi_subarray.h + * + * @section LICENSE + * + * The MIT License + * + * @copyright Copyright (c) 2024 TileDB, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @section DESCRIPTION + * + * This file defines test support for the subarray section of the C API. + */ + +#ifndef TILEDB_TESTSUPPORT_CAPI_SUBARRAY_H +#define TILEDB_TESTSUPPORT_CAPI_SUBARRAY_H + +#include "testsupport_capi_array.h" +#include "tiledb/api/c_api/subarray/subarray_api_external.h" +#include "tiledb/api/c_api/subarray/subarray_api_internal.h" + +namespace tiledb::api::test_support { + +struct ordinary_subarray { + ordinary_array array{}; + tiledb_subarray_handle_t* subarray{nullptr}; + + ordinary_subarray() { + array.open(); + auto rc = tiledb_subarray_alloc(array.ctx(), array.array, &subarray); + if (rc != TILEDB_OK) { + throw std::runtime_error("error creating test subarray"); + } + if (subarray == nullptr) { + throw std::logic_error( + "tiledb_subarray_alloc returned OK but without subarray"); + } + } + ~ordinary_subarray() { + tiledb_subarray_free(&subarray); + } + + [[nodiscard]] tiledb_ctx_handle_t* ctx() const { + return array.ctx(); + } +}; + +/** + * Ordinary subarray with var-sized dimensions. + */ +struct ordinary_subarray_var { + ordinary_array array{true}; // Make the dimensions var-sized. + tiledb_subarray_handle_t* subarray{nullptr}; + + ordinary_subarray_var() { + array.open(); + auto rc = tiledb_subarray_alloc(array.ctx(), array.array, &subarray); + if (rc != TILEDB_OK) { + throw std::runtime_error("error creating test subarray"); + } + if (subarray == nullptr) { + throw std::logic_error( + "tiledb_subarray_alloc returned OK but without subarray"); + } + } + ~ordinary_subarray_var() { + tiledb_subarray_free(&subarray); + } + + [[nodiscard]] tiledb_ctx_handle_t* ctx() const { + return array.ctx(); + } +}; + +} // namespace tiledb::api::test_support + +#endif // TILEDB_TESTSUPPORT_CAPI_SUBARRAY_H diff --git a/tiledb/sm/c_api/api_argument_validator.h b/tiledb/sm/c_api/api_argument_validator.h index b1c301f5158..7eab1523119 100644 --- a/tiledb/sm/c_api/api_argument_validator.h +++ b/tiledb/sm/c_api/api_argument_validator.h @@ -44,18 +44,6 @@ /* AUXILIARY FUNCTIONS */ /* ********************************* */ -namespace tiledb::api { -/** - * Returns if a subarray handle (old style) is valid. Throws otherwise. - */ -inline void ensure_subarray_is_valid(const tiledb_subarray_t* p) { - if (p == nullptr || p->subarray_ == nullptr || - p->subarray_->array() == nullptr) { - throw CAPIException("Invalid TileDB subarray object"); - } -} -} // namespace tiledb::api - inline int32_t sanity_check(tiledb_ctx_t* ctx, const tiledb_query_t* query) { if (query == nullptr || query->query_ == nullptr) { auto st = Status_Error("Invalid TileDB query object"); diff --git a/tiledb/sm/c_api/tiledb.cc b/tiledb/sm/c_api/tiledb.cc index 48ff533b744..3f2980c169a 100644 --- a/tiledb/sm/c_api/tiledb.cc +++ b/tiledb/sm/c_api/tiledb.cc @@ -51,6 +51,7 @@ #include "tiledb/api/c_api/filter_list/filter_list_api_internal.h" #include "tiledb/api/c_api/fragment_info/fragment_info_api_internal.h" #include "tiledb/api/c_api/string/string_api_internal.h" +#include "tiledb/api/c_api/subarray/subarray_api_internal.h" #include "tiledb/api/c_api_support/c_api_support.h" #include "tiledb/as_built/as_built.h" #include "tiledb/common/common.h" @@ -97,18 +98,6 @@ #include #include -/** - * Helper class to aid shimming access from _query... routines in this module to - * _subarray... routines deprecating them. - */ - -struct tiledb_subarray_transient_local_t : public tiledb_subarray_t { - explicit tiledb_subarray_transient_local_t(const tiledb_query_t* query) { - this->subarray_ = - const_cast(query->query_->subarray()); - } -}; - /* * The Definition for a "C" function can't be in a header. */ @@ -467,7 +456,7 @@ int32_t tiledb_query_set_subarray_t( return TILEDB_ERR; } ensure_subarray_is_valid(subarray); - query->query_->set_subarray(*subarray->subarray_); + query->query_->set_subarray(*subarray->subarray()); return TILEDB_OK; } @@ -834,22 +823,11 @@ int32_t tiledb_query_get_subarray_t( tiledb_ctx_t* ctx, const tiledb_query_t* query, tiledb_subarray_t** subarray) { - *subarray = nullptr; - // Sanity check - if (sanity_check(ctx, query) == TILEDB_ERR) + if (sanity_check(ctx, query) == TILEDB_ERR) { return TILEDB_ERR; - - *subarray = new (std::nothrow) tiledb_subarray_t; - if (*subarray == nullptr) { - auto st = Status_Error("Failed to allocate TileDB subarray object"); - LOG_STATUS_NO_RETURN_VALUE(st); - save_error(ctx, st); - return TILEDB_OOM; } - - (*subarray)->subarray_ = - const_cast(query->query_->subarray()); - + ensure_output_pointer_is_valid(subarray); + *subarray = tiledb_subarray_t::make_handle(*(query->query_->subarray())); return TILEDB_OK; } @@ -889,245 +867,6 @@ int32_t tiledb_query_add_update_value( return TILEDB_OK; } -/* ****************************** */ -/* SUBARRAY */ -/* ****************************** */ - -capi_return_t tiledb_subarray_alloc( - tiledb_ctx_t* ctx, - const tiledb_array_t* array, - tiledb_subarray_t** subarray) { - ensure_array_is_valid(array); - ensure_output_pointer_is_valid(subarray); - - // Error if array is not open - if (!array->is_open()) { - throw CAPIException("Cannot create subarray; array is not open"); - } - - // Create a new subarray object - *subarray = new tiledb_subarray_t; - try { - (*subarray)->subarray_ = new tiledb::sm::Subarray( - array->array().get(), - (tiledb::sm::stats::Stats*)nullptr, - ctx->resources().logger(), - true); - (*subarray)->is_allocated_ = true; - } catch (...) { - delete *subarray; - *subarray = nullptr; - throw CAPIException("Failed to create subarray"); - } - - return TILEDB_OK; -} - -int32_t tiledb_subarray_set_config( - tiledb_ctx_t*, tiledb_subarray_t* subarray, tiledb_config_t* config) { - ensure_subarray_is_valid(subarray); - api::ensure_config_is_valid(config); - subarray->subarray_->set_config( - tiledb::sm::QueryType::READ, config->config()); - return TILEDB_OK; -} - -void tiledb_subarray_free(tiledb_subarray_t** subarray) { - if (subarray != nullptr && *subarray != nullptr) { - if ((*subarray)->is_allocated_) { - delete (*subarray)->subarray_; - } else { - (*subarray)->subarray_ = nullptr; - } - delete (*subarray); - *subarray = nullptr; - } -} - -int32_t tiledb_subarray_set_coalesce_ranges( - tiledb_ctx_t*, tiledb_subarray_t* subarray, int coalesce_ranges) { - ensure_subarray_is_valid(subarray); - subarray->subarray_->set_coalesce_ranges(coalesce_ranges != 0); - return TILEDB_OK; -} - -int32_t tiledb_subarray_set_subarray( - tiledb_ctx_t*, tiledb_subarray_t* subarray_obj, const void* subarray_vals) { - ensure_subarray_is_valid(subarray_obj); - subarray_obj->subarray_->set_subarray(subarray_vals); - return TILEDB_OK; -} - -int32_t tiledb_subarray_add_range( - tiledb_ctx_t*, - tiledb_subarray_t* subarray, - uint32_t dim_idx, - const void* start, - const void* end, - const void* stride) { - ensure_subarray_is_valid(subarray); - ensure_unsupported_stride_is_null(stride); - subarray->subarray_->add_range(dim_idx, start, end); - return TILEDB_OK; -} - -int32_t tiledb_subarray_add_point_ranges( - tiledb_ctx_t*, - tiledb_subarray_t* subarray, - uint32_t dim_idx, - const void* start, - uint64_t count) { - ensure_subarray_is_valid(subarray); - subarray->subarray_->add_point_ranges(dim_idx, start, count); - return TILEDB_OK; -} - -int32_t tiledb_subarray_add_range_by_name( - tiledb_ctx_t*, - tiledb_subarray_t* subarray, - const char* dim_name, - const void* start, - const void* end, - const void* stride) { - ensure_subarray_is_valid(subarray); - ensure_unsupported_stride_is_null(stride); - subarray->subarray_->add_range_by_name(dim_name, start, end); - return TILEDB_OK; -} - -int32_t tiledb_subarray_add_range_var( - tiledb_ctx_t*, - tiledb_subarray_t* subarray, - uint32_t dim_idx, - const void* start, - uint64_t start_size, - const void* end, - uint64_t end_size) { - ensure_subarray_is_valid(subarray); - subarray->subarray_->add_range_var(dim_idx, start, start_size, end, end_size); - return TILEDB_OK; -} - -int32_t tiledb_subarray_add_range_var_by_name( - tiledb_ctx_t*, - tiledb_subarray_t* subarray, - const char* dim_name, - const void* start, - uint64_t start_size, - const void* end, - uint64_t end_size) { - ensure_subarray_is_valid(subarray); - subarray->subarray_->add_range_var_by_name( - dim_name, start, start_size, end, end_size); - return TILEDB_OK; -} - -int32_t tiledb_subarray_get_range_num( - tiledb_ctx_t*, - const tiledb_subarray_t* subarray, - uint32_t dim_idx, - uint64_t* range_num) { - ensure_subarray_is_valid(subarray); - subarray->subarray_->get_range_num(dim_idx, range_num); - return TILEDB_OK; -} - -int32_t tiledb_subarray_get_range_num_from_name( - tiledb_ctx_t*, - const tiledb_subarray_t* subarray, - const char* dim_name, - uint64_t* range_num) { - ensure_subarray_is_valid(subarray); - subarray->subarray_->get_range_num_from_name(dim_name, range_num); - return TILEDB_OK; -} - -int32_t tiledb_subarray_get_range( - tiledb_ctx_t*, - const tiledb_subarray_t* subarray, - uint32_t dim_idx, - uint64_t range_idx, - const void** start, - const void** end, - const void** stride) { - ensure_subarray_is_valid(subarray); - ensure_output_pointer_is_valid(start); - ensure_output_pointer_is_valid(end); - if (stride != nullptr) { - *stride = nullptr; - } - subarray->subarray_->get_range(dim_idx, range_idx, start, end); - return TILEDB_OK; -} - -int32_t tiledb_subarray_get_range_var_size( - tiledb_ctx_t*, - const tiledb_subarray_t* subarray, - uint32_t dim_idx, - uint64_t range_idx, - uint64_t* start_size, - uint64_t* end_size) { - ensure_subarray_is_valid(subarray); - subarray->subarray_->get_range_var_size( - dim_idx, range_idx, start_size, end_size); - return TILEDB_OK; -} - -int32_t tiledb_subarray_get_range_from_name( - tiledb_ctx_t*, - const tiledb_subarray_t* subarray, - const char* dim_name, - uint64_t range_idx, - const void** start, - const void** end, - const void** stride) { - ensure_subarray_is_valid(subarray); - ensure_output_pointer_is_valid(start); - ensure_output_pointer_is_valid(end); - if (stride != nullptr) { - *stride = nullptr; - } - subarray->subarray_->get_range_from_name(dim_name, range_idx, start, end); - return TILEDB_OK; -} - -int32_t tiledb_subarray_get_range_var_size_from_name( - tiledb_ctx_t*, - const tiledb_subarray_t* subarray, - const char* dim_name, - uint64_t range_idx, - uint64_t* start_size, - uint64_t* end_size) { - ensure_subarray_is_valid(subarray); - subarray->subarray_->get_range_var_size_from_name( - dim_name, range_idx, start_size, end_size); - return TILEDB_OK; -} - -int32_t tiledb_subarray_get_range_var( - tiledb_ctx_t*, - const tiledb_subarray_t* subarray, - uint32_t dim_idx, - uint64_t range_idx, - void* start, - void* end) { - ensure_subarray_is_valid(subarray); - subarray->subarray_->get_range_var(dim_idx, range_idx, start, end); - return TILEDB_OK; -} - -int32_t tiledb_subarray_get_range_var_from_name( - tiledb_ctx_t*, - const tiledb_subarray_t* subarray, - const char* dim_name, - uint64_t range_idx, - void* start, - void* end) { - ensure_subarray_is_valid(subarray); - subarray->subarray_->get_range_var_from_name(dim_name, range_idx, start, end); - return TILEDB_OK; -} - /* ****************************** */ /* QUERY CONDITION */ /* ****************************** */ @@ -3162,204 +2901,6 @@ CAPI_INTERFACE( ctx, query, relevant_fragment_num); } -/* ****************************** */ -/* SUBARRAY */ -/* ****************************** */ - -CAPI_INTERFACE( - subarray_alloc, - tiledb_ctx_t* ctx, - const tiledb_array_t* array, - tiledb_subarray_t** subarray) { - return api_entry(ctx, array, subarray); -} - -CAPI_INTERFACE( - subarray_set_config, - tiledb_ctx_t* ctx, - tiledb_subarray_t* subarray, - tiledb_config_t* config) { - return api_entry( - ctx, subarray, config); -} - -CAPI_INTERFACE_VOID(subarray_free, tiledb_subarray_t** subarray) { - return api_entry_void(subarray); -} - -CAPI_INTERFACE( - subarray_set_coalesce_ranges, - tiledb_ctx_t* ctx, - tiledb_subarray_t* subarray, - int coalesce_ranges) { - return api_entry( - ctx, subarray, coalesce_ranges); -} - -CAPI_INTERFACE( - subarray_set_subarray, - tiledb_ctx_t* ctx, - tiledb_subarray_t* subarray_obj, - const void* subarray_vals) { - return api_entry( - ctx, subarray_obj, subarray_vals); -} - -CAPI_INTERFACE( - subarray_add_range, - tiledb_ctx_t* ctx, - tiledb_subarray_t* subarray, - uint32_t dim_idx, - const void* start, - const void* end, - const void* stride) { - return api_entry( - ctx, subarray, dim_idx, start, end, stride); -} - -CAPI_INTERFACE( - subarray_add_point_ranges, - tiledb_ctx_t* ctx, - tiledb_subarray_t* subarray, - uint32_t dim_idx, - const void* start, - uint64_t count) { - return api_entry( - ctx, subarray, dim_idx, start, count); -} - -CAPI_INTERFACE( - subarray_add_range_by_name, - tiledb_ctx_t* ctx, - tiledb_subarray_t* subarray, - const char* dim_name, - const void* start, - const void* end, - const void* stride) { - return api_entry( - ctx, subarray, dim_name, start, end, stride); -} - -CAPI_INTERFACE( - subarray_add_range_var, - tiledb_ctx_t* ctx, - tiledb_subarray_t* subarray, - uint32_t dim_idx, - const void* start, - uint64_t start_size, - const void* end, - uint64_t end_size) { - return api_entry( - ctx, subarray, dim_idx, start, start_size, end, end_size); -} - -CAPI_INTERFACE( - subarray_add_range_var_by_name, - tiledb_ctx_t* ctx, - tiledb_subarray_t* subarray, - const char* dim_name, - const void* start, - uint64_t start_size, - const void* end, - uint64_t end_size) { - return api_entry( - ctx, subarray, dim_name, start, start_size, end, end_size); -} - -CAPI_INTERFACE( - subarray_get_range_num, - tiledb_ctx_t* ctx, - const tiledb_subarray_t* subarray, - uint32_t dim_idx, - uint64_t* range_num) { - return api_entry( - ctx, subarray, dim_idx, range_num); -} - -CAPI_INTERFACE( - subarray_get_range_num_from_name, - tiledb_ctx_t* ctx, - const tiledb_subarray_t* subarray, - const char* dim_name, - uint64_t* range_num) { - return api_entry( - ctx, subarray, dim_name, range_num); -} - -CAPI_INTERFACE( - subarray_get_range, - tiledb_ctx_t* ctx, - const tiledb_subarray_t* subarray, - uint32_t dim_idx, - uint64_t range_idx, - const void** start, - const void** end, - const void** stride) { - return api_entry( - ctx, subarray, dim_idx, range_idx, start, end, stride); -} - -CAPI_INTERFACE( - subarray_get_range_var_size, - tiledb_ctx_t* ctx, - const tiledb_subarray_t* subarray, - uint32_t dim_idx, - uint64_t range_idx, - uint64_t* start_size, - uint64_t* end_size) { - return api_entry( - ctx, subarray, dim_idx, range_idx, start_size, end_size); -} - -CAPI_INTERFACE( - subarray_get_range_from_name, - tiledb_ctx_t* ctx, - const tiledb_subarray_t* subarray, - const char* dim_name, - uint64_t range_idx, - const void** start, - const void** end, - const void** stride) { - return api_entry( - ctx, subarray, dim_name, range_idx, start, end, stride); -} - -CAPI_INTERFACE( - subarray_get_range_var_size_from_name, - tiledb_ctx_t* ctx, - const tiledb_subarray_t* subarray, - const char* dim_name, - uint64_t range_idx, - uint64_t* start_size, - uint64_t* end_size) { - return api_entry( - ctx, subarray, dim_name, range_idx, start_size, end_size); -} - -CAPI_INTERFACE( - subarray_get_range_var, - tiledb_ctx_t* ctx, - const tiledb_subarray_t* subarray, - uint32_t dim_idx, - uint64_t range_idx, - void* start, - void* end) { - return api_entry( - ctx, subarray, dim_idx, range_idx, start, end); -} - -CAPI_INTERFACE( - subarray_get_range_var_from_name, - tiledb_ctx_t* ctx, - const tiledb_subarray_t* subarray, - const char* dim_name, - uint64_t range_idx, - void* start, - void* end) { - return api_entry( - ctx, subarray, dim_name, range_idx, start, end); -} - /* ****************************** */ /* QUERY CONDITION */ /* ****************************** */ diff --git a/tiledb/sm/c_api/tiledb.h b/tiledb/sm/c_api/tiledb.h index e45802c74ba..dc0102ab135 100644 --- a/tiledb/sm/c_api/tiledb.h +++ b/tiledb/sm/c_api/tiledb.h @@ -76,6 +76,7 @@ #include "tiledb/api/c_api/object/object_api_external.h" #include "tiledb/api/c_api/query/query_api_external.h" #include "tiledb/api/c_api/string/string_api_external.h" +#include "tiledb/api/c_api/subarray/subarray_api_external.h" #include "tiledb/api/c_api/vfs/vfs_api_external.h" #include @@ -214,9 +215,6 @@ TILEDB_EXPORT void tiledb_version(int32_t* major, int32_t* minor, int32_t* rev) /* TILEDB TYPES */ /* ********************************* */ -/** A subarray object. */ -typedef struct tiledb_subarray_t tiledb_subarray_t; - /** A TileDB query condition object. */ typedef struct tiledb_query_condition_t tiledb_query_condition_t; @@ -1194,479 +1192,6 @@ TILEDB_EXPORT int32_t tiledb_query_condition_negate( const tiledb_query_condition_t* cond, tiledb_query_condition_t** negated_cond) TILEDB_NOEXCEPT; -/* ********************************* */ -/* SUBARRAY */ -/* ********************************* */ - -/** - * Allocates a TileDB subarray object. - * - * **Example:** - * - * @code{.c} - * tiledb_subarray_t* subarray; - * tiledb_subarray_alloc(ctx, array, &subarray); - * @endcode - * - * @param ctx The TileDB context. - * @param array An open array object. - * @param subarray The subarray object to be created. - * @return `TILEDB_OK` for success or `TILEDB_OOM` or `TILEDB_ERR` for error. - * - * @note The allocated subarray initially has internal coalesce_ranges == true. - */ -TILEDB_EXPORT int32_t tiledb_subarray_alloc( - tiledb_ctx_t* ctx, - const tiledb_array_t* array, - tiledb_subarray_t** subarray) TILEDB_NOEXCEPT; - -/** - * Set the subarray config. - * - * Setting the configuration with this function overrides the following - * Subarray-level parameters only: - * - * - `sm.read_range_oob` - */ -TILEDB_EXPORT int32_t tiledb_subarray_set_config( - tiledb_ctx_t* ctx, - tiledb_subarray_t* subarray, - tiledb_config_t* config) TILEDB_NOEXCEPT; - -/** - * Frees a TileDB subarray object. - * - * **Example:** - * - * @code{.c} - * tiledb_subarray_t* subarray; - * tiledb_array_open(ctx, array, TILEDB_READ); - * tiledb_subarray_alloc(ctx, array, &subarray); - * tiledb_array_close(ctx, array); - * tiledb_subarray_free(&subarray); - * @endcode - * - * @param subarray The subarray object to be freed. - */ -TILEDB_EXPORT void tiledb_subarray_free(tiledb_subarray_t** subarray) - TILEDB_NOEXCEPT; - -/** - * Set coalesce_ranges property on a TileDB subarray object. - * Intended to be used just after tiledb_subarray_alloc() to replace - * the initial coalesce_ranges == true - * with coalesce_ranges = false if - * needed. - * - * **Example:** - * - * @code{.c} - * tiledb_subarray_t* subarray; - * //tiledb_subarray_alloc internally defaults to 'coalesce_ranges == true' - * tiledb_subarray_alloc(ctx, array, &subarray); - * // so manually set to 'false' to match earlier behaviour with older - * // tiledb_query_ subarray actions. - * bool coalesce_ranges = false; - * tiledb_subarray_set_coalesce_ranges(ctx, subarray, coalesce_ranges); - * @endcode - * - * @param ctx The TileDB context. - * @param subarray The subarray object to change. - * @param coalesce_ranges The true/false value to be set - * @return `TILEDB_OK` for success or `TILEDB_ERR` for error. - */ -TILEDB_EXPORT int32_t tiledb_subarray_set_coalesce_ranges( - tiledb_ctx_t* ctx, - tiledb_subarray_t* subarray, - int coalesce_ranges) TILEDB_NOEXCEPT; - -/** - * Populates a subarray with specific indicies. - * - * **Example:** - * - * The following sets a 2D subarray [0,10], [20, 30] to the subarray. - * - * @code{.c} - * tiledb_subarray_t *subarray; - * uint64_t subarray_v[] = { 0, 10, 20, 30}; - * tiledb_subarray_set_subarray(ctx, subarray, subarray_v); - * @endcode - * - * @param ctx The TileDB context. - * @param subarray The TileDB subarray object. - * @param subarray_v The subarray values which can be used to limit the subarray - * read/write. - * It should be a sequence of [low, high] pairs (one pair per dimension). - * When the subarray is used for writes, this is meaningful only - * for dense arrays, and specifically dense writes. Note that `subarray_a` - * must have the same type as the domain of the subarray's associated - * array. - * @return `TILEDB_OK` for success or `TILEDB_ERR` for error. - */ -TILEDB_EXPORT -int32_t tiledb_subarray_set_subarray( - tiledb_ctx_t* ctx, - tiledb_subarray_t* subarray, - const void* subarray_v) TILEDB_NOEXCEPT; - -/** - * Adds a 1D range along a subarray dimension index, which is in the form - * (start, end, stride). The datatype of the range components - * must be the same as the type of the domain of the array in the query. - * - * **Example:** - * - * @code{.c} - * uint32_t dim_idx = 2; - * int64_t start = 10; - * int64_t end = 20; - * tiledb_subarray_add_range(ctx, subarray, dim_idx, &start, &end, nullptr); - * @endcode - * - * @param ctx The TileDB context. - * @param subarray The subarray to add the range to. - * @param dim_idx The index of the dimension to add the range to. - * @param start The range start. - * @param end The range end. - * @param stride The range stride. - * @return `TILEDB_OK` for success or `TILEDB_ERR` for error. - * - * @note The stride is currently unsupported. Use 0/NULL/nullptr as the - * stride argument. - */ -TILEDB_EXPORT int32_t tiledb_subarray_add_range( - tiledb_ctx_t* ctx, - tiledb_subarray_t* subarray, - uint32_t dim_idx, - const void* start, - const void* end, - const void* stride) TILEDB_NOEXCEPT; - -/** - * Adds a 1D range along a subarray dimension name, which is in the form - * (start, end, stride). The datatype of the range components - * must be the same as the type of the domain of the array in the query. - * - * **Example:** - * - * @code{.c} - * char* dim_name = "rows"; - * int64_t start = 10; - * int64_t end = 20; - * tiledb_subarray_add_range_by_name( - * ctx, subarray, dim_name, &start, &end, nullptr); - * @endcode - * - * @param ctx The TileDB context. - * @param subarray The subarray to add the range to. - * @param dim_name The name of the dimension to add the range to. - * @param start The range start. - * @param end The range end. - * @param stride The range stride. - * @return `TILEDB_OK` for success or `TILEDB_ERR` for error. - * - * @note The stride is currently unsupported. Use 0/NULL/nullptr as the - * stride argument. - */ -TILEDB_EXPORT int32_t tiledb_subarray_add_range_by_name( - tiledb_ctx_t* ctx, - tiledb_subarray_t* subarray, - const char* dim_name, - const void* start, - const void* end, - const void* stride) TILEDB_NOEXCEPT; - -/** - * Adds a 1D variable-sized range along a subarray dimension index, which is in - * the form (start, end). Applicable only to variable-sized dimensions. - * - * **Example:** - * - * @code{.c} - * uint32_t dim_idx = 2; - * char start[] = "a"; - * char end[] = "bb"; - * tiledb_subarray_add_range_var(ctx, subarray, dim_idx, start, 1, end, 2); - * @endcode - * - * @param ctx The TileDB context. - * @param subarray The subarray to add the range to. - * @param dim_idx The index of the dimension to add the range to. - * @param start The range start. - * @param start_size The size of the range start in bytes. - * @param end The range end. - * @param end_size The size of the range end in bytes. - * @return `TILEDB_OK` for success or `TILEDB_ERR` for error. - */ -TILEDB_EXPORT int32_t tiledb_subarray_add_range_var( - tiledb_ctx_t* ctx, - tiledb_subarray_t* subarray, - uint32_t dim_idx, - const void* start, - uint64_t start_size, - const void* end, - uint64_t end_size) TILEDB_NOEXCEPT; - -/** - * Adds a 1D variable-sized range along a subarray dimension name, which is in - * the form (start, end). Applicable only to variable-sized dimensions. - * - * **Example:** - * - * @code{.c} - * char* dim_name = "rows"; - * char start[] = "a"; - * char end[] = "bb"; - * tiledb_subarray_add_range_var_by_name( - * ctx, subarray, dim_name, start, 1, end, 2); - * @endcode - * - * @param ctx The TileDB context. - * @param subarray The subarray to add the range to. - * @param dim_name The name of the dimension to add the range to. - * @param start The range start. - * @param start_size The size of the range start in bytes. - * @param end The range end. - * @param end_size The size of the range end in bytes. - * @return `TILEDB_OK` for success or `TILEDB_ERR` for error. - */ -TILEDB_EXPORT int32_t tiledb_subarray_add_range_var_by_name( - tiledb_ctx_t* ctx, - tiledb_subarray_t* subarray, - const char* dim_name, - const void* start, - uint64_t start_size, - const void* end, - uint64_t end_size) TILEDB_NOEXCEPT; - -/** - * Retrieves the number of ranges of the query subarray along a given dimension - * index. - * - * **Example:** - * - * @code{.c} - * uint64_t range_num; - * tiledb_subarray_get_range_num(ctx, subarray, dim_idx, &range_num); - * @endcode - * - * @param ctx The TileDB context - * @param subarray The subarray. - * @param dim_idx The index of the dimension for which to retrieve number of - * ranges. - * @param range_num Receives the retrieved number of ranges. - * @return `TILEDB_OK` for success or `TILEDB_ERR` for error. - */ -TILEDB_EXPORT int32_t tiledb_subarray_get_range_num( - tiledb_ctx_t* ctx, - const tiledb_subarray_t* subarray, - uint32_t dim_idx, - uint64_t* range_num) TILEDB_NOEXCEPT; - -/** - * Retrieves the number of ranges of the subarray along a given dimension - * name. - * - * **Example:** - * - * @code{.c} - * uint64_t range_num; - * tiledb_subarray_get_range_num_from_name(ctx, subarray, dim_name, &range_num); - * @endcode - * - * @param ctx The TileDB context - * @param subarray The subarray. - * @param dim_name The name of the dimension whose range number to retrieve. - * @param range_num Receives the retrieved number of ranges. - * @return `TILEDB_OK` for success or `TILEDB_ERR` for error. - */ -TILEDB_EXPORT int32_t tiledb_subarray_get_range_num_from_name( - tiledb_ctx_t* ctx, - const tiledb_subarray_t* subarray, - const char* dim_name, - uint64_t* range_num) TILEDB_NOEXCEPT; - -/** - * Retrieves a specific range of the subarray along a given dimension - * index. - * - * **Example:** - * - * @code{.c} - * const void* start; - * const void* end; - * const void* stride; - * tiledb_subarray_get_range( - * ctx, subarray, dim_idx, range_idx, &start, &end, &stride); - * @endcode - * - * @param ctx The TileDB context - * @param subarray The subarray. - * @param dim_idx The index of the dimension to retrieve the range from. - * @param range_idx The index of the range to retrieve. - * @param start Receives the retrieved range start. - * @param end Receives the received range end. - * @param stride Receives the retrieved range stride. - * @return `TILEDB_OK` for success or `TILEDB_ERR` for error. - */ -TILEDB_EXPORT int32_t tiledb_subarray_get_range( - tiledb_ctx_t* ctx, - const tiledb_subarray_t* subarray, - uint32_t dim_idx, - uint64_t range_idx, - const void** start, - const void** end, - const void** stride) TILEDB_NOEXCEPT; - -/** - * Retrieves a specific range of the subarray along a given dimension - * name. - * - * **Example:** - * - * @code{.c} - * const void* start; - * const void* end; - * const void* stride; - * tiledb_subarray_get_range_from_name( - * ctx, query, dim_name, range_idx, &start, &end, &stride); - * @endcode - * - * @param ctx The TileDB context - * @param subarray The subarray. - * @param dim_name The name of the dimension to retrieve the range from. - * @param range_idx The index of the range to retrieve. - * @param start Receives the retrieved range start. - * @param end Receives the retrieved range end. - * @param stride Receives the retrieved range stride. - * @return `TILEDB_OK` for success or `TILEDB_ERR` for error. - */ -TILEDB_EXPORT int32_t tiledb_subarray_get_range_from_name( - tiledb_ctx_t* ctx, - const tiledb_subarray_t* subarray, - const char* dim_name, - uint64_t range_idx, - const void** start, - const void** end, - const void** stride) TILEDB_NOEXCEPT; - -/** - * Retrieves a range's start and end size for a given variable-length - * dimension index at a given range index. - * - * **Example:** - * - * @code{.c} - * uint64_t start_size; - * uint64_t end_size; - * tiledb_subarray_get_range_var_size( - * ctx, subarray, dim_idx, range_idx, &start_size, &end_size); - * @endcode - * - * @param ctx The TileDB context - * @param subarray The subarray. - * @param dim_idx The index of the dimension to retrieve the range from. - * @param range_idx The index of the range to retrieve. - * @param start_size Receives the retrieved range start size in bytes - * @param end_size Receives the retrieved range end size in bytes - * @return `TILEDB_OK` for success or `TILEDB_ERR` for error. - */ -TILEDB_EXPORT int32_t tiledb_subarray_get_range_var_size( - tiledb_ctx_t* ctx, - const tiledb_subarray_t* subarray, - uint32_t dim_idx, - uint64_t range_idx, - uint64_t* start_size, - uint64_t* end_size) TILEDB_NOEXCEPT; - -/** - * Retrieves a range's start and end size for a given variable-length - * dimension name at a given range index. - * - * **Example:** - * - * @code{.c} - * uint64_t start_size; - * uint64_t end_size; - * tiledb_subarray_get_range_var_size_from_name( - * ctx, subarray, dim_name, range_idx, &start_size, &end_size); - * @endcode - * - * @param ctx The TileDB context - * @param subarray The subarray. - * @param dim_name The name of the dimension to retrieve the range from. - * @param range_idx The index of the range to retrieve. - * @param start_size Receives the retrieved range start size in bytes - * @param end_size Receives the retrieved range end size in bytes - * @return `TILEDB_OK` for success or `TILEDB_ERR` for error. - */ -TILEDB_EXPORT int32_t tiledb_subarray_get_range_var_size_from_name( - tiledb_ctx_t* ctx, - const tiledb_subarray_t* subarray, - const char* dim_name, - uint64_t range_idx, - uint64_t* start_size, - uint64_t* end_size) TILEDB_NOEXCEPT; - -/** - * Retrieves a specific range of the subarray along a given - * variable-length dimension index. - * - * **Example:** - * - * @code{.c} - * const void* start; - * const void* end; - * tiledb_subarray_get_range_var( - * ctx, subarray, dim_idx, range_idx, &start, &end); - * @endcode - * - * @param ctx The TileDB context - * @param subarray The subarray. - * @param dim_idx The index of the dimension to retrieve the range from. - * @param range_idx The index of the range to retrieve. - * @param start Receives the retrieved range start. - * @param end Receives the retrieved range end. - * @return `TILEDB_OK` for success or `TILEDB_ERR` for error. - */ -TILEDB_EXPORT int32_t tiledb_subarray_get_range_var( - tiledb_ctx_t* ctx, - const tiledb_subarray_t* subarray, - uint32_t dim_idx, - uint64_t range_idx, - void* start, - void* end) TILEDB_NOEXCEPT; - -/** - * Retrieves a specific range of the subarray along a given - * variable-length dimension name. - * - * **Example:** - * - * @code{.c} - * const void* start; - * const void* end; - * tiledb_subarray_get_range_var_from_name( - * ctx, subarray, dim_name, range_idx, &start, &end); - * @endcode - * - * @param ctx The TileDB context - * @param subarray The subarray. - * @param dim_name The name of the dimension to retrieve the range from. - * @param range_idx The index of the range to retrieve. - * @param start Receives the retrieved range start. - * @param end Receives the retrieved range end. - * @return `TILEDB_OK` for success or `TILEDB_ERR` for error. - */ -TILEDB_EXPORT int32_t tiledb_subarray_get_range_var_from_name( - tiledb_ctx_t* ctx, - const tiledb_subarray_t* subarray, - const char* dim_name, - uint64_t range_idx, - void* start, - void* end) TILEDB_NOEXCEPT; - /* ********************************* */ /* ARRAY CONSOLIDATION */ /* ********************************* */ diff --git a/tiledb/sm/c_api/tiledb_dimension_label.cc b/tiledb/sm/c_api/tiledb_dimension_label.cc index 53712a508c1..b24ea106f78 100644 --- a/tiledb/sm/c_api/tiledb_dimension_label.cc +++ b/tiledb/sm/c_api/tiledb_dimension_label.cc @@ -31,8 +31,8 @@ #include "tiledb/api/c_api/dimension/dimension_api_internal.h" #include "tiledb/api/c_api/dimension_label/dimension_label_api_internal.h" #include "tiledb/api/c_api/filter_list/filter_list_api_internal.h" +#include "tiledb/api/c_api/subarray/subarray_api_internal.h" #include "tiledb/api/c_api_support/c_api_support.h" -#include "tiledb/sm/c_api/api_argument_validator.h" #include "tiledb/sm/c_api/tiledb.h" #include "tiledb/sm/c_api/tiledb_dimension_label_experimental.h" @@ -58,7 +58,7 @@ capi_return_t tiledb_array_schema_get_dimension_label_from_name( const char* label_name, tiledb_dimension_label_t** dim_label) { ensure_array_schema_is_valid(array_schema); - tiledb::api::ensure_output_pointer_is_valid(dim_label); + ensure_output_pointer_is_valid(dim_label); *dim_label = tiledb_dimension_label_t::make_handle( array_schema->array_uri(), array_schema->dimension_label(label_name)); return TILEDB_OK; @@ -124,7 +124,7 @@ capi_return_t tiledb_subarray_add_label_range( const void* stride) { ensure_subarray_is_valid(subarray); ensure_unsupported_stride_is_null(stride); - subarray->subarray_->add_label_range(label_name, start, end); + subarray->add_label_range(label_name, start, end); return TILEDB_OK; } @@ -136,15 +136,15 @@ capi_return_t tiledb_subarray_add_label_range_var( const void* end, uint64_t end_size) { ensure_subarray_is_valid(subarray); - subarray->subarray_->add_label_range_var( - label_name, start, start_size, end, end_size); + subarray->add_label_range_var(label_name, start, start_size, end, end_size); return TILEDB_OK; } capi_return_t tiledb_subarray_get_label_name( tiledb_subarray_t* subarray, uint32_t dim_idx, const char** label_name) { ensure_subarray_is_valid(subarray); - const auto& name = subarray->subarray_->get_label_name(dim_idx); + ensure_output_pointer_is_valid(label_name); + const auto& name = subarray->get_label_name(dim_idx); *label_name = name.c_str(); return TILEDB_OK; } @@ -162,7 +162,7 @@ capi_return_t tiledb_subarray_get_label_range( if (stride != nullptr) { *stride = nullptr; } - subarray->subarray_->get_label_range(dim_name, range_idx, start, end); + subarray->get_label_range(dim_name, range_idx, start, end); return TILEDB_OK; } @@ -171,7 +171,8 @@ capi_return_t tiledb_subarray_get_label_range_num( const char* dim_name, uint64_t* range_num) { ensure_subarray_is_valid(subarray); - subarray->subarray_->get_label_range_num(dim_name, range_num); + ensure_output_pointer_is_valid(range_num); + subarray->get_label_range_num(dim_name, range_num); return TILEDB_OK; } @@ -182,7 +183,9 @@ capi_return_t tiledb_subarray_get_label_range_var( void* start, void* end) { ensure_subarray_is_valid(subarray); - subarray->subarray_->get_label_range_var(dim_name, range_idx, start, end); + ensure_output_pointer_is_valid(start); + ensure_output_pointer_is_valid(end); + subarray->get_label_range_var(dim_name, range_idx, start, end); return TILEDB_OK; } @@ -193,8 +196,9 @@ capi_return_t tiledb_subarray_get_label_range_var_size( uint64_t* start_size, uint64_t* end_size) { ensure_subarray_is_valid(subarray); - subarray->subarray_->get_label_range_var_size( - dim_name, range_idx, start_size, end_size); + ensure_output_pointer_is_valid(start_size); + ensure_output_pointer_is_valid(end_size); + subarray->get_label_range_var_size(dim_name, range_idx, start_size, end_size); return TILEDB_OK; } @@ -203,7 +207,8 @@ capi_return_t tiledb_subarray_has_label_ranges( const uint32_t dim_idx, int32_t* has_label_ranges) { ensure_subarray_is_valid(subarray); - bool has_ranges = subarray->subarray_->has_label_ranges(dim_idx); + ensure_output_pointer_is_valid(has_label_ranges); + bool has_ranges = subarray->has_label_ranges(dim_idx); *has_label_ranges = has_ranges ? 1 : 0; return TILEDB_OK; } diff --git a/tiledb/sm/c_api/tiledb_experimental.h b/tiledb/sm/c_api/tiledb_experimental.h index 7a7aed03cab..5188d5c3a0b 100644 --- a/tiledb/sm/c_api/tiledb_experimental.h +++ b/tiledb/sm/c_api/tiledb_experimental.h @@ -50,6 +50,7 @@ #include "tiledb/api/c_api/query_aggregate/query_aggregate_api_external_experimental.h" #include "tiledb/api/c_api/query_field/query_field_api_external_experimental.h" #include "tiledb/api/c_api/query_plan/query_plan_api_external_experimental.h" +#include "tiledb/api/c_api/subarray/subarray_api_experimental.h" #include "tiledb/api/c_api/vfs/vfs_api_experimental.h" #include "tiledb_dimension_label_experimental.h" @@ -363,18 +364,6 @@ TILEDB_EXPORT int32_t tiledb_query_add_update_value( const void* update_value, uint64_t update_value_size) TILEDB_NOEXCEPT; -/** - * Adds point ranges to the given dimension index of the subarray - * Effectively `add_range(x_i, x_i)` for `count` points in the - * target array, but set in bulk to amortize expensive steps. - */ -TILEDB_EXPORT int32_t tiledb_subarray_add_point_ranges( - tiledb_ctx_t* ctx, - tiledb_subarray_t* subarray, - uint32_t dim_idx, - const void* start, - uint64_t count) TILEDB_NOEXCEPT; - /** * Get the number of relevant fragments from the subarray. Should only be * called after size estimation was asked for. diff --git a/tiledb/sm/c_api/tiledb_struct_def.h b/tiledb/sm/c_api/tiledb_struct_def.h index 66d5344cda0..d6a106bb276 100644 --- a/tiledb/sm/c_api/tiledb_struct_def.h +++ b/tiledb/sm/c_api/tiledb_struct_def.h @@ -44,13 +44,6 @@ #include "tiledb/sm/query/query_condition.h" #include "tiledb/sm/query/update_value.h" #include "tiledb/sm/storage_manager/context.h" -#include "tiledb/sm/subarray/subarray.h" -#include "tiledb/sm/subarray/subarray_partitioner.h" - -struct tiledb_subarray_t { - tiledb::sm::Subarray* subarray_ = nullptr; - bool is_allocated_ = false; -}; struct tiledb_query_t { tiledb::sm::Query* query_ = nullptr;