From 51f80488f31f11a89fe457e705550fb70027906e Mon Sep 17 00:00:00 2001 From: Agisilaos Kounelis Date: Wed, 28 Aug 2024 19:52:49 +0300 Subject: [PATCH 1/3] Add tiledb_fragment_info_dump_str --- tiledb/doxygen/source/c-api.rst | 2 + tiledb/sm/c_api/tiledb.cc | 32 ++++++++++++- tiledb/sm/c_api/tiledb.h | 24 ++++++++++ tiledb/sm/cpp_api/fragment_info.h | 24 ++++++++++ tiledb/sm/fragment/fragment_info.cc | 57 +++++++++++------------ tiledb/sm/fragment/fragment_info.h | 4 ++ tiledb/sm/fragment/single_fragment_info.h | 8 ++-- 7 files changed, 116 insertions(+), 35 deletions(-) diff --git a/tiledb/doxygen/source/c-api.rst b/tiledb/doxygen/source/c-api.rst index a74047c4445..334673bb041 100644 --- a/tiledb/doxygen/source/c-api.rst +++ b/tiledb/doxygen/source/c-api.rst @@ -772,6 +772,8 @@ Fragment Info :project: TileDB-C .. doxygenfunction:: tiledb_fragment_info_dump :project: TileDB-C +.. doxygenfunction:: tiledb_fragment_info_dump_str + :project: TileDB-C Experimental ------------- diff --git a/tiledb/sm/c_api/tiledb.cc b/tiledb/sm/c_api/tiledb.cc index 4cd80bf5cc0..3d5502b96ea 100644 --- a/tiledb/sm/c_api/tiledb.cc +++ b/tiledb/sm/c_api/tiledb.cc @@ -3961,7 +3961,28 @@ int32_t tiledb_fragment_info_dump( tiledb_ctx_t* ctx, const tiledb_fragment_info_t* fragment_info, FILE* out) { if (sanity_check(ctx, fragment_info) == TILEDB_ERR) return TILEDB_ERR; - fragment_info->fragment_info_->dump(out); + + std::stringstream ss; + ss << *fragment_info->fragment_info_; + size_t r = fwrite(ss.str().c_str(), sizeof(char), ss.str().size(), out); + if (r != ss.str().size()) { + throw CAPIException("Error writing fragment info to output stream"); + } + + return TILEDB_OK; +} + +int32_t tiledb_fragment_info_dump_str( + tiledb_ctx_t* ctx, + const tiledb_fragment_info_t* fragment_info, + tiledb_string_t** out) { + if (sanity_check(ctx, fragment_info) == TILEDB_ERR) + return TILEDB_ERR; + + std::stringstream ss; + ss << *fragment_info->fragment_info_; + *out = tiledb_string_handle_t::make_handle(ss.str()); + return TILEDB_OK; } @@ -6131,6 +6152,15 @@ CAPI_INTERFACE( ctx, fragment_info, out); } +CAPI_INTERFACE( + fragment_info_dump_str, + tiledb_ctx_t* ctx, + const tiledb_fragment_info_t* fragment_info, + tiledb_string_handle_t** out) { + return api_entry( + ctx, fragment_info, out); +} + /* ********************************* */ /* EXPERIMENTAL APIs */ /* ********************************* */ diff --git a/tiledb/sm/c_api/tiledb.h b/tiledb/sm/c_api/tiledb.h index c0bd23eb93e..b4f13568c33 100644 --- a/tiledb/sm/c_api/tiledb.h +++ b/tiledb/sm/c_api/tiledb.h @@ -3742,6 +3742,30 @@ TILEDB_EXPORT int32_t tiledb_fragment_info_dump( const tiledb_fragment_info_t* fragment_info, FILE* out) TILEDB_NOEXCEPT; +/** + * Dumps the fragment info in ASCII format in the selected string output. + * + * The output string handle must be freed by the user after use. + * + * **Example:** + * + * @code{.c} + * tiledb_string_t* tdb_string; + * tiledb_fragment_info_dump_str(ctx, fragment_info, &tdb_string); + * // Use the string + * tiledb_string_free(&tdb_string); + * @endcode + * + * @param[in] ctx The TileDB context. + * @param[in] fragment_info The fragment info object. + * @param[out] out The output string. + * @return `TILEDB_OK` for success and `TILEDB_ERR` for error. + */ +TILEDB_EXPORT capi_return_t tiledb_fragment_info_dump_str( + tiledb_ctx_t* ctx, + const tiledb_fragment_info_t* fragment_info, + tiledb_string_t** out) TILEDB_NOEXCEPT; + #ifdef __cplusplus } #endif diff --git a/tiledb/sm/cpp_api/fragment_info.h b/tiledb/sm/cpp_api/fragment_info.h index 1e254657fdb..a398c68ffaa 100644 --- a/tiledb/sm/cpp_api/fragment_info.h +++ b/tiledb/sm/cpp_api/fragment_info.h @@ -101,6 +101,11 @@ class FragmentInfo { return impl::convert_to_string(&name).value(); } + /** Returns the context that the fragment info belongs to. */ + const Context& context() const { + return ctx_; + } + /** * Retrieves the non-empty domain of the fragment with the given index * on the given dimension index. @@ -403,17 +408,20 @@ class FragmentInfo { return std::string(uri_c); } +#ifndef TILEDB_REMOVE_DEPRECATIONS /** * Dumps the fragment info in an ASCII representation to an output. * * @param out (Optional) File to dump output to. Defaults to `nullptr` * which will lead to selection of `stdout`. */ + TILEDB_DEPRECATED void dump(FILE* out = nullptr) const { auto& ctx = ctx_.get(); ctx.handle_error( tiledb_fragment_info_dump(ctx.ptr().get(), fragment_info_.get(), out)); } +#endif /** Returns the C TileDB context object. */ std::shared_ptr ptr() const { @@ -435,6 +443,22 @@ class FragmentInfo { std::shared_ptr fragment_info_; }; +/* ********************************* */ +/* MISC */ +/* ********************************* */ + +/** Get a string representation of fragment info. */ +inline std::ostream& operator<<(std::ostream& os, const FragmentInfo& fi) { + tiledb_string_t* tdb_string; + auto& ctx = fi.context(); + ctx.handle_error(tiledb_fragment_info_dump_str( + ctx.ptr().get(), fi.ptr().get(), &tdb_string)); + + os << impl::convert_to_string(&tdb_string).value(); + + return os; +} + } // namespace tiledb #endif // TILEDB_CPP_API_FRAGMENT_INFO_H diff --git a/tiledb/sm/fragment/fragment_info.cc b/tiledb/sm/fragment/fragment_info.cc index 728c95d293e..12c2808979c 100644 --- a/tiledb/sm/fragment/fragment_info.cc +++ b/tiledb/sm/fragment/fragment_info.cc @@ -84,35 +84,6 @@ void FragmentInfo::expand_anterior_ndrange( domain.expand_ndrange(range, &anterior_ndrange_); } -void FragmentInfo::dump(FILE* out) const { - ensure_loaded(); - if (out == nullptr) - out = stdout; - - auto fragment_num = this->fragment_num(); - - std::stringstream ss; - ss << "- Fragment num: " << fragment_num << "\n"; - ss << "- Unconsolidated metadata num: " << unconsolidated_metadata_num_ - << "\n"; - ss << "- To vacuum num: " << to_vacuum_.size() << "\n"; - - if (!to_vacuum_.empty()) { - ss << "- To vacuum URIs:\n"; - for (const auto& v : to_vacuum_) - ss << " > " << v.c_str() << "\n"; - } - - fprintf(out, "%s", ss.str().c_str()); - - for (uint32_t fid = 0; fid < fragment_num; ++fid) { - auto meta = single_fragment_info_vec_[fid].meta(); - auto dim_types = meta->dim_types(); - fprintf(out, "- Fragment #%u:\n", fid + 1); - single_fragment_info_vec_[fid].dump(dim_types, out); - } -} - Status FragmentInfo::get_dense(uint32_t fid, int32_t* dense) const { ensure_loaded(); if (dense == nullptr) @@ -1203,3 +1174,31 @@ Status FragmentInfo::replace( } } // namespace tiledb::sm + +std::ostream& operator<<( + std::ostream& os, const tiledb::sm::FragmentInfo& fragment_info) { + auto fragment_num = fragment_info.fragment_num(); + + os << "- Fragment num: " << fragment_num << "\n"; + os << "- Unconsolidated metadata num: " + << fragment_info.unconsolidated_metadata_num() << "\n"; + + auto to_vacuum = fragment_info.to_vacuum(); + os << "- To vacuum num: " << to_vacuum.size() << "\n"; + + if (!to_vacuum.empty()) { + os << "- To vacuum URIs:\n"; + for (const auto& v : to_vacuum) + os << " > " << v.c_str() << "\n"; + } + + auto single_fragment_info_vec = fragment_info.single_fragment_info_vec(); + for (uint32_t fid = 0; fid < fragment_num; ++fid) { + auto meta = single_fragment_info_vec[fid].meta(); + auto dim_types = meta->dim_types(); + os << "- Fragment #" << fid + 1 << ":\n"; + os << single_fragment_info_vec[fid].dump_single_fragment_info(dim_types); + } + + return os; +} diff --git a/tiledb/sm/fragment/fragment_info.h b/tiledb/sm/fragment/fragment_info.h index 5f5b3bc5dbd..2dee1a06e48 100644 --- a/tiledb/sm/fragment/fragment_info.h +++ b/tiledb/sm/fragment/fragment_info.h @@ -485,3 +485,7 @@ class FragmentInfo { } // namespace tiledb #endif // TILEDB_FRAGMENT_INFO_H + +/** Converts the fragment info into a string representation. */ +std::ostream& operator<<( + std::ostream& os, const tiledb::sm::FragmentInfo& fragment_info); diff --git a/tiledb/sm/fragment/single_fragment_info.h b/tiledb/sm/fragment/single_fragment_info.h index 19a7dd21c9c..8ee43b9eae8 100644 --- a/tiledb/sm/fragment/single_fragment_info.h +++ b/tiledb/sm/fragment/single_fragment_info.h @@ -119,10 +119,8 @@ class SingleFragmentInfo { } /** Dumps the single fragment info in ASCII format in the selected output. */ - void dump(const std::vector& dim_types, FILE* out) const { - if (out == nullptr) - out = stdout; - + std::string dump_single_fragment_info( + const std::vector& dim_types) const { std::stringstream ss; ss << " > URI: " << uri_.c_str() << "\n"; ss << " > Schema name: " << array_schema_name_ << "\n"; @@ -137,7 +135,7 @@ class SingleFragmentInfo { ss << " > Has consolidated metadata: " << (has_consolidated_footer_ ? "yes" : "no") << "\n"; - fprintf(out, "%s", ss.str().c_str()); + return ss.str(); } /** Returns `true` if the fragment is sparse. */ From 4d6b11f2ad765985f3d788a07b945edb86179ba3 Mon Sep 17 00:00:00 2001 From: Agisilaos Kounelis Date: Thu, 29 Aug 2024 14:41:35 +0300 Subject: [PATCH 2/3] Fix --- tiledb/sm/fragment/fragment_info.cc | 2 +- tiledb/sm/fragment/single_fragment_info.h | 25 ++++++++++------------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/tiledb/sm/fragment/fragment_info.cc b/tiledb/sm/fragment/fragment_info.cc index 12c2808979c..08aa78dbf31 100644 --- a/tiledb/sm/fragment/fragment_info.cc +++ b/tiledb/sm/fragment/fragment_info.cc @@ -1197,7 +1197,7 @@ std::ostream& operator<<( auto meta = single_fragment_info_vec[fid].meta(); auto dim_types = meta->dim_types(); os << "- Fragment #" << fid + 1 << ":\n"; - os << single_fragment_info_vec[fid].dump_single_fragment_info(dim_types); + single_fragment_info_vec[fid].dump_single_fragment_info(os, dim_types); } return os; diff --git a/tiledb/sm/fragment/single_fragment_info.h b/tiledb/sm/fragment/single_fragment_info.h index 8ee43b9eae8..4f98b39e1b9 100644 --- a/tiledb/sm/fragment/single_fragment_info.h +++ b/tiledb/sm/fragment/single_fragment_info.h @@ -119,23 +119,20 @@ class SingleFragmentInfo { } /** Dumps the single fragment info in ASCII format in the selected output. */ - std::string dump_single_fragment_info( - const std::vector& dim_types) const { - std::stringstream ss; - ss << " > URI: " << uri_.c_str() << "\n"; - ss << " > Schema name: " << array_schema_name_ << "\n"; - ss << " > Type: " << (sparse_ ? "sparse" : "dense") << "\n"; - ss << " > Non-empty domain: " << non_empty_domain_str(dim_types).c_str() + void dump_single_fragment_info( + std::ostream& os, const std::vector& dim_types) const { + os << " > URI: " << uri_.c_str() << "\n"; + os << " > Schema name: " << array_schema_name_ << "\n"; + os << " > Type: " << (sparse_ ? "sparse" : "dense") << "\n"; + os << " > Non-empty domain: " << non_empty_domain_str(dim_types).c_str() << "\n"; - ss << " > Size: " << fragment_size_ << "\n"; - ss << " > Cell num: " << cell_num_ << "\n"; - ss << " > Timestamp range: [" << timestamp_range_.first << ", " + os << " > Size: " << fragment_size_ << "\n"; + os << " > Cell num: " << cell_num_ << "\n"; + os << " > Timestamp range: [" << timestamp_range_.first << ", " << timestamp_range_.second << "]\n"; - ss << " > Format version: " << version_ << "\n"; - ss << " > Has consolidated metadata: " + os << " > Format version: " << version_ << "\n"; + os << " > Has consolidated metadata: " << (has_consolidated_footer_ ? "yes" : "no") << "\n"; - - return ss.str(); } /** Returns `true` if the fragment is sparse. */ From bc12c764672c259e92c9d6898bf41c4ef0af7584 Mon Sep 17 00:00:00 2001 From: Agisilaos Kounelis <36283973+kounelisagis@users.noreply.github.com> Date: Thu, 29 Aug 2024 15:00:13 +0300 Subject: [PATCH 3/3] Add ensure_output_pointer_is_valid Co-authored-by: Theodore Tsirpanis --- tiledb/sm/c_api/tiledb.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/tiledb/sm/c_api/tiledb.cc b/tiledb/sm/c_api/tiledb.cc index 3d5502b96ea..5989a8c5803 100644 --- a/tiledb/sm/c_api/tiledb.cc +++ b/tiledb/sm/c_api/tiledb.cc @@ -3978,6 +3978,7 @@ int32_t tiledb_fragment_info_dump_str( tiledb_string_t** out) { if (sanity_check(ctx, fragment_info) == TILEDB_ERR) return TILEDB_ERR; + ensure_output_pointer_is_valid(out); std::stringstream ss; ss << *fragment_info->fragment_info_;