From c793bcd90136c0ddcb9f95a1628d1850087d76d0 Mon Sep 17 00:00:00 2001 From: John Kerl Date: Sun, 29 Sep 2024 21:26:16 -0400 Subject: [PATCH] can_resize_soma_joinid --- libtiledbsoma/src/soma/soma_array.cc | 61 ++++++++++++-- libtiledbsoma/src/soma/soma_array.h | 15 ++-- libtiledbsoma/test/unit_soma_dataframe.cc | 81 +++++++++++++++++++ .../test/unit_soma_sparse_ndarray.cc | 37 +-------- 4 files changed, 147 insertions(+), 47 deletions(-) diff --git a/libtiledbsoma/src/soma/soma_array.cc b/libtiledbsoma/src/soma/soma_array.cc index 8706ff15f3..b351aa65ab 100644 --- a/libtiledbsoma/src/soma/soma_array.cc +++ b/libtiledbsoma/src/soma/soma_array.cc @@ -29,10 +29,10 @@ * This file defines the SOMAArray class. */ +#include "soma_array.h" #include #include "../utils/logger.h" #include "../utils/util.h" -#include "soma_array.h" namespace tiledbsoma { using namespace tiledb; @@ -1012,6 +1012,16 @@ std::vector SOMAArray::dimension_names() const { return result; } +bool SOMAArray::has_dimension_name(const std::string& name) const { + auto dimensions = tiledb_schema()->domain().dimensions(); + for (const auto& dim : dimensions) { + if (dim.name() == name) { + return true; + } + } + return false; +} + void SOMAArray::write(bool sort_coords) { if (mq_->query_type() != TILEDB_WRITE) { throw TileDBSOMAError("[SOMAArray] array must be opened in write mode"); @@ -1549,7 +1559,7 @@ std::pair SOMAArray::_can_set_shape_domainish_helper( return std::pair( false, fmt::format( - "cannot {} for {}: new {} < existing maxshape {}", + "cannot {} for {}: new {} < maxshape {}", method_name_for_messages, dim_name, newshape[i], @@ -1560,11 +1570,48 @@ std::pair SOMAArray::_can_set_shape_domainish_helper( return std::pair(true, ""); } -std::pair SOMAArray::can_set_shape_soma_joinid( - int64_t /*newshape*/, - bool /*is_resize*/, - std::string /*method_name_for_messages*/) { - return std::pair(false, "TBW"); +std::pair SOMAArray::can_resize_soma_joinid( + int64_t newshape) { + // Fail if the array doesn't already have a shape yet (they should upgrade + // first). + if (!has_current_domain()) { + return std::pair( + false, + "can_resize_soma_joinid: dataframe currently has no domain set: " + "please use tiledbsoma_upgrade_domain."); + } + + // OK if soma_joinid isn't a dim. + if (!has_dimension_name("soma_joinid")) { + return std::pair(true, ""); + } + + // Fail if the newshape isn't within the array's core current domain. + std::pair cur_dom_lo_hi = _core_current_domain_slot("soma_joinid"); + if (newshape < cur_dom_lo_hi.second) { + return std::pair( + false, + fmt::format( + "cannot resize_soma_joinid: new soma_joinid shape {} < " + "existing shape {}", + newshape, + cur_dom_lo_hi.second)); + } + + // Fail if the newshape isn't within the array's core (max) domain. + std::pair dom_lo_hi = _core_domain_slot("soma_joinid"); + if (newshape > dom_lo_hi.second) { + return std::pair( + false, + fmt::format( + "cannot resize_soma_joinid: new soma_joinid shape {} > " + "maxshape {}", + newshape, + dom_lo_hi.second)); + } + + // Sucess otherwise. + return std::pair(true, ""); } void SOMAArray::resize(const std::vector& newshape) { diff --git a/libtiledbsoma/src/soma/soma_array.h b/libtiledbsoma/src/soma/soma_array.h index e65b98e2b0..067c459bac 100644 --- a/libtiledbsoma/src/soma/soma_array.h +++ b/libtiledbsoma/src/soma/soma_array.h @@ -290,6 +290,13 @@ class SOMAArray : public SOMAObject { */ std::vector dimension_names() const; + /** + * @brief Sees if the array has a dimension of the given name. + * + * @return bool + */ + bool has_dimension_name(const std::string& name) const; + /** * @brief Set the dimension slice using one point * @@ -1075,12 +1082,10 @@ class SOMAArray : public SOMAObject { } /** - * XXX COMMENT + * This is similar to can_upgrade_shape, but it's a can-we call + * for maybe_resize_soma_joinid. */ - std::pair can_set_shape_soma_joinid( - int64_t newshape, - bool require_has_shape, - std::string method_name_for_messages); + std::pair can_resize_soma_joinid(int64_t newshape); /** * @brief Resize the shape (what core calls "current domain") up to the diff --git a/libtiledbsoma/test/unit_soma_dataframe.cc b/libtiledbsoma/test/unit_soma_dataframe.cc index 33089f6ea9..03ea8e0fd9 100644 --- a/libtiledbsoma/test/unit_soma_dataframe.cc +++ b/libtiledbsoma/test/unit_soma_dataframe.cc @@ -664,6 +664,28 @@ TEST_CASE_METHOD( REQUIRE(maxdom_sjid[1] > 2000000000); } + // Check can_resize_soma_joinid + std::pair check = soma_dataframe + ->can_resize_soma_joinid(1); + if (!use_current_domain) { + REQUIRE(check.first == false); + REQUIRE( + check.second == + "can_resize_soma_joinid: dataframe currently has no domain " + "set: please use tiledbsoma_upgrade_domain."); + } else { + // Must fail since this is too small. + REQUIRE(check.first == false); + REQUIRE( + check.second == + "cannot resize_soma_joinid: new soma_joinid shape 1 < existing " + "shape 199"); + check = soma_dataframe->can_resize_soma_joinid( + SOMA_JOINID_RESIZE_DIM_MAX + 1); + REQUIRE(check.first == true); + REQUIRE(check.second == ""); + } + soma_dataframe->close(); } } @@ -878,6 +900,28 @@ TEST_CASE_METHOD( REQUIRE(maxdom_u32[1] > 2000000000); } + // Check can_resize_soma_joinid + std::pair check = soma_dataframe + ->can_resize_soma_joinid(1); + if (!use_current_domain) { + REQUIRE(check.first == false); + REQUIRE( + check.second == + "can_resize_soma_joinid: dataframe currently has no domain " + "set: please use tiledbsoma_upgrade_domain."); + } else { + // Must fail since this is too small. + REQUIRE(check.first == false); + REQUIRE( + check.second == + "cannot resize_soma_joinid: new soma_joinid shape 1 < existing " + "shape 199"); + check = soma_dataframe->can_resize_soma_joinid( + SOMA_JOINID_RESIZE_DIM_MAX + 1); + REQUIRE(check.first == true); + REQUIRE(check.second == ""); + } + soma_dataframe->close(); } } @@ -1108,6 +1152,28 @@ TEST_CASE_METHOD( REQUIRE(ned_str == std::vector({"", ""})); + // Check can_resize_soma_joinid + std::pair check = soma_dataframe + ->can_resize_soma_joinid(1); + if (!use_current_domain) { + REQUIRE(check.first == false); + REQUIRE( + check.second == + "can_resize_soma_joinid: dataframe currently has no domain " + "set: please use tiledbsoma_upgrade_domain."); + } else { + // Must fail since this is too small. + REQUIRE(check.first == false); + REQUIRE( + check.second == + "cannot resize_soma_joinid: new soma_joinid shape 1 < existing " + "shape 99"); + check = soma_dataframe->can_resize_soma_joinid( + SOMA_JOINID_RESIZE_DIM_MAX + 1); + REQUIRE(check.first == true); + REQUIRE(check.second == ""); + } + soma_dataframe->close(); } } @@ -1299,6 +1365,21 @@ TEST_CASE_METHOD( REQUIRE(maxdom_str == std::vector({"", ""})); } + // Check can_resize_soma_joinid + std::pair check = soma_dataframe + ->can_resize_soma_joinid(0); + if (!use_current_domain) { + REQUIRE(check.first == false); + REQUIRE( + check.second == + "can_resize_soma_joinid: dataframe currently has no domain " + "set: please use tiledbsoma_upgrade_domain."); + } else { + // Must pass since soma_joinid isn't a dim in this case. + REQUIRE(check.first == true); + REQUIRE(check.second == ""); + } + soma_dataframe->close(); } } diff --git a/libtiledbsoma/test/unit_soma_sparse_ndarray.cc b/libtiledbsoma/test/unit_soma_sparse_ndarray.cc index 0fd09b1103..9315a8724b 100644 --- a/libtiledbsoma/test/unit_soma_sparse_ndarray.cc +++ b/libtiledbsoma/test/unit_soma_sparse_ndarray.cc @@ -405,8 +405,8 @@ TEST_CASE( REQUIRE(check.first == false); REQUIRE( check.second == - "cannot tiledbsoma_upgrade_shape for soma_dim_0: new 1009 < existing " - "maxshape 1000"); + "cannot tiledbsoma_upgrade_shape for soma_dim_0: new 1009 < maxshape " + "1000"); check = soma_sparse->can_upgrade_shape(newshape_good); REQUIRE(check.first == true); @@ -478,36 +478,3 @@ TEST_CASE("SOMASparseNDArray: can_resize", "[SOMASparseNDArray]") { REQUIRE(check.first == true); REQUIRE(check.second == ""); } - -// -//// array w shape -//// o set curdom say 1000 and maxdom huge -//// o test newshape.size() is wrong -//// o test doing tiledbsoma_upgrade_shape instead of resize -//// o test resize: -//// - test too small in any one slot -//// - test equal -- do it twice -//// - test larger -// -//// ================================================================ -//// OLD -//// ACC-SNDA URI data-snda-py <----------------- SLOTWISE NONE -//// ACC-SNDA NEW SHAPE False -//// ACC-SNDA SHAPE (2147483646, 2147483646) -//// ACC-SNDA MAXSHAPE (2147483646, 2147483646) -//// -//// ACC-SNDA URI data-snda-shape-py <----------------- SLOTWISE SPECIFIED -//// ACC-SNDA NEW SHAPE False -//// ACC-SNDA SHAPE (100, 200) -//// ACC-SNDA MAXSHAPE (100, 200) -//// -//// ================================================================ -//// ACC-SNDA URI data-snda-py <----------------- SLOTWISE NONE -//// ACC-SNDA NEW SHAPE True -//// ACC-SNDA SHAPE (2147483646, 2147483646) -//// ACC-SNDA MAXSHAPE (2147483646, 2147483646) -//// -//// ACC-SNDA URI data-snda-shape-py <----------------- SLOTWISE SPECIFIED -//// ACC-SNDA NEW SHAPE True -//// ACC-SNDA SHAPE (100, 200) -//// ACC-SNDA MAXSHAPE (2147483646, 2147483646)