-
Notifications
You must be signed in to change notification settings - Fork 185
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove serialization non C.41 constructors from fragment_metadata_from_capnp #4682
base: dev
Are you sure you want to change the base?
Conversation
This pull request has been linked to Shortcut Story #40131: Remove serialization non C.41 constructors from fragment_metadata_from_capnp.. |
7bf109f
to
9a4c573
Compare
… qualifiers and return small values by value.
9a4c573
to
f2728ba
Compare
dc18af8
to
f3b3138
Compare
f3b3138
to
9a3ab85
Compare
@teo-tsirpanis let's not work more on this PR. I started to review and it became obvious to me we need to design something different here. The 30 parameters constructor doesn't look good. |
Undrafting, regardless of whether we will take it, it is finished and ready for review. |
@@ -727,7 +775,9 @@ class FragmentMetadata { | |||
URI validity_uri(const std::string& name) const; | |||
|
|||
/** Return the array schema name. */ | |||
const std::string& array_schema_name(); | |||
const std::string& array_schema_name() const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be declared inline
. Not always necessary with modern code generation, but it remains valuable for its documentary value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
/** gt_offsets_ accessor */ | ||
inline GenericTileOffsets& generic_tile_offsets() { | ||
return gt_offsets_; | ||
const shared_ptr<const ArraySchema>& array_schema() const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
inline
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
tiledb/sm/query/strategy_base.cc
Outdated
@@ -61,6 +63,10 @@ StrategyBase::StrategyBase( | |||
, offsets_bitsize_(constants::cell_var_offset_size * 8) { | |||
} | |||
|
|||
ContextResources& StrategyBase::resources() const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be inline
in the header.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I initially did it this way because moving the function to the header would include storage_manager.h
, but now done.
*/ | ||
Status fragment_metadata_from_capnp( | ||
shared_ptr<FragmentMetadata> fragment_metadata_from_capnp( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be much better to have this function return just FragmentMetadata
and have the caller allocate it in shared_ptr
if it needs to. I looked at its uses, and it looks like at least some of them don't need to allocate (usually because they already allocate, say, within vector
).
We don't want to expand the scope of the present PR to change all the classes where there's spurious allocation. On the other hand we don't want to change this function signature and not get it write. The change requires only a handful of make_shared
calls at the call sites of this function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This cannot happen as long as tiledb::common::pmr::vector
(and consequently FragmentMetadata
) is not move-constructible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@teo-tsirpanis can we change the return value here now that we changed the constructor?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed the return type and restored the move constructors on FragmentMetadata
and got errors that a copy constructor is deleted. All members of the class are move-constructible; I have no idea why it fails.
Patch applied
diff --git a/tiledb/sm/fragment/fragment_metadata.h b/tiledb/sm/fragment/fragment_metadata.h
index 92dcea4..0637d4d 100644
--- a/tiledb/sm/fragment/fragment_metadata.h
+++ b/tiledb/sm/fragment/fragment_metadata.h
@@ -152,7 +152,9 @@ class FragmentMetadata {
~FragmentMetadata();
DISABLE_COPY_AND_COPY_ASSIGN(FragmentMetadata);
- DISABLE_MOVE_AND_MOVE_ASSIGN(FragmentMetadata);
+
+ FragmentMetadata(FragmentMetadata&&) = default;
+ FragmentMetadata& operator=(FragmentMetadata&&) = default;
/* ********************************* */
/* TYPE DEFINITIONS */
diff --git a/tiledb/sm/serialization/array.cc b/tiledb/sm/serialization/array.cc
index 8957209..813851b 100644
--- a/tiledb/sm/serialization/array.cc
+++ b/tiledb/sm/serialization/array.cc
@@ -299,11 +299,13 @@ Status array_from_capnp(
auto fragment_metadata_all_reader = array_reader.getFragmentMetadataAll();
fragment_metadata.reserve(fragment_metadata_all_reader.size());
for (auto frag_meta_reader : fragment_metadata_all_reader) {
- auto meta = fragment_metadata_from_capnp(
- array->array_schema_latest_ptr(),
- frag_meta_reader,
- &storage_manager->resources(),
- array->memory_tracker());
+ auto meta = make_shared<FragmentMetadata>(
+ HERE(),
+ fragment_metadata_from_capnp(
+ array->array_schema_latest_ptr(),
+ frag_meta_reader,
+ &storage_manager->resources(),
+ array->memory_tracker()));
if (client_side) {
meta->set_rtree_loaded();
}
diff --git a/tiledb/sm/serialization/fragment_info.cc b/tiledb/sm/serialization/fragment_info.cc
index 66f39fd..4f6942b 100644
--- a/tiledb/sm/serialization/fragment_info.cc
+++ b/tiledb/sm/serialization/fragment_info.cc
@@ -228,11 +228,13 @@ single_fragment_info_from_capnp(
"Missing fragment metadata from single fragment info capnp reader"),
nullopt};
}
- shared_ptr<FragmentMetadata> meta = fragment_metadata_from_capnp(
- schema->second,
- single_frag_info_reader.getMeta(),
- fragment_info->resources(),
- fragment_info->resources()->create_memory_tracker());
+ auto meta = make_shared<FragmentMetadata>(
+ HERE(),
+ fragment_metadata_from_capnp(
+ schema->second,
+ single_frag_info_reader.getMeta(),
+ fragment_info->resources(),
+ fragment_info->resources()->create_memory_tracker()));
auto expanded_non_empty_domain = meta->non_empty_domain();
if (meta->dense()) {
diff --git a/tiledb/sm/serialization/fragment_metadata.cc b/tiledb/sm/serialization/fragment_metadata.cc
index 3d828d4..fa10d7c 100644
--- a/tiledb/sm/serialization/fragment_metadata.cc
+++ b/tiledb/sm/serialization/fragment_metadata.cc
@@ -166,7 +166,7 @@ static FragmentMetadata::GenericTileOffsets generic_tile_offsets_from_capnp(
return gt_offsets;
}
-shared_ptr<FragmentMetadata> fragment_metadata_from_capnp(
+FragmentMetadata fragment_metadata_from_capnp(
const shared_ptr<const ArraySchema>& array_schema,
const capnp::FragmentMetadata::Reader& frag_meta_reader,
ContextResources* resources,
@@ -198,8 +198,7 @@ shared_ptr<FragmentMetadata> fragment_metadata_from_capnp(
deserializer, &array_schema->domain(), constants::format_version);
}
- return make_shared<FragmentMetadata>(
- HERE(),
+ return FragmentMetadata(
resources,
memory_tracker,
array_schema,
diff --git a/tiledb/sm/serialization/fragment_metadata.h b/tiledb/sm/serialization/fragment_metadata.h
index d8f7da8..cc76f05 100644
--- a/tiledb/sm/serialization/fragment_metadata.h
+++ b/tiledb/sm/serialization/fragment_metadata.h
@@ -58,9 +58,9 @@ namespace serialization {
* @param frag_meta_reader cap'n proto class
* @param resources ContextResources associated
* @param memory_tracker memory tracker associated
- * @return shared pointer to deserialized FragmentMetadata
+ * @return deserialized FragmentMetadata
*/
-shared_ptr<FragmentMetadata> fragment_metadata_from_capnp(
+FragmentMetadata fragment_metadata_from_capnp(
const shared_ptr<const ArraySchema>& array_schema,
const capnp::FragmentMetadata::Reader& frag_meta_reader,
ContextResources* resources,
diff --git a/tiledb/sm/serialization/query.cc b/tiledb/sm/serialization/query.cc
index fda96c0..a76fcbb 100644
--- a/tiledb/sm/serialization/query.cc
+++ b/tiledb/sm/serialization/query.cc
@@ -2995,11 +2995,13 @@ Status global_write_state_from_capnp(
write_state->last_hilbert_value_ = state_reader.getLastHilbertValue();
if (state_reader.hasFragMeta()) {
- write_state->frag_meta_ = fragment_metadata_from_capnp(
- query.array_schema_shared(),
- state_reader.getFragMeta(),
- &global_writer->resources(),
- global_writer->resources().create_memory_tracker());
+ write_state->frag_meta_ = make_shared<FragmentMetadata>(
+ HERE(),
+ fragment_metadata_from_capnp(
+ query.array_schema_shared(),
+ state_reader.getFragMeta(),
+ &global_writer->resources(),
+ global_writer->resources().create_memory_tracker()));
}
// Deserialize the multipart upload state
@@ -3118,11 +3120,13 @@ Status unordered_write_state_from_capnp(
// Fragment metadata is not allocated when deserializing into a new Query
// object.
if (unordered_writer->frag_meta() == nullptr) {
- unordered_writer->set_frag_meta(fragment_metadata_from_capnp(
- query.array_schema_shared(),
- state_reader.getFragMeta(),
- &unordered_writer->resources(),
- unordered_writer->resources().create_memory_tracker()));
+ unordered_writer->set_frag_meta(make_shared<FragmentMetadata>(
+ HERE(),
+ fragment_metadata_from_capnp(
+ query.array_schema_shared(),
+ state_reader.getFragMeta(),
+ &unordered_writer->resources(),
+ unordered_writer->resources().create_memory_tracker())));
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
auto meta = make_shared<FragmentMetadata>(...
is written with =
like an assignment, so it might be doing copy-initialization. Another possibility is that there's a copy happening with make_shared
, since I don't see move
being used to ask for the move constructor.
There are bigger hammers available with things like allocate_shared_for_overwrite
and placement new
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the compiler's stack trace, it uses FragmentMetadata&&
all the way down to std::construct_at
:
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\xutility(241): error C2280: 'tiledb::sm::FragmentMetadata::FragmentMetadata(const tiledb::sm::FragmentMetadata &)': attempting to reference a deleted function
C:\Users\teo\code\TileDB\tiledb/sm/fragment/fragment_metadata.h(154): note: see declaration of 'tiledb::sm::FragmentMetadata::FragmentMetadata'
C:\Users\teo\code\TileDB\tiledb/sm/fragment/fragment_metadata.h(154): note: 'tiledb::sm::FragmentMetadata::FragmentMetadata(const tiledb::sm::FragmentMetadata &)': function was explicitly deleted
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\xutility(241): note: the template instantiation context (the oldest one first) is
C:\Users\teo\code\TileDB\tiledb\sm\serialization\array.cc(302): note: see reference to function template instantiation 'std::shared_ptr<tiledb::sm::FragmentMetadata> tiledb::common::make_shared<tiledb::sm::FragmentMetadata,62,tiledb::sm::FragmentMetadata>(const char (&)[62],tiledb::sm::FragmentMetadata &&)' being compiled
C:\Users\teo\code\TileDB\tiledb/common/dynamic_memory/dynamic_memory.h(266): note: see reference to function template instantiation 'std::shared_ptr<tiledb::sm::FragmentMetadata> tiledb::common::`anonymous-namespace'::AllocationFunctions<tiledb::sm::FragmentMetadata>::make_shared<62,_Ty>(const char (&)[62],_Ty &&)' being compiled
with
[
_Ty=tiledb::sm::FragmentMetadata
]
C:\Users\teo\code\TileDB\tiledb/common/dynamic_memory/dynamic_memory.h(238): note: see reference to function template instantiation 'std::shared_ptr<tiledb::sm::FragmentMetadata> tiledb::common::`anonymous-namespace'::AllocationFunctions<tiledb::sm::FragmentMetadata>::make_shared_notrace<_Ty>(_Ty &&)' being compiled
with
[
_Ty=tiledb::sm::FragmentMetadata
]
C:\Users\teo\code\TileDB\tiledb/common/dynamic_memory/dynamic_memory.h(198): note: see reference to function template instantiation 'std::shared_ptr<tiledb::sm::FragmentMetadata> std::allocate_shared<T,tiledb::common::GovernedAllocator<T,tiledb::common::`anonymous-namespace'::TiledbTracedAllocator,tiledb::common::Governor>,_Ty>(const _Alloc &,_Ty &&)' being compiled
with
[
T=tiledb::sm::FragmentMetadata,
_Ty=tiledb::sm::FragmentMetadata,
_Alloc=tiledb::common::GovernedAllocator<tiledb::sm::FragmentMetadata,tiledb::common::`anonymous-namespace'::TiledbTracedAllocator,tiledb::common::Governor>
]
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\memory(2840): note: see reference to function template instantiation 'void std::_Construct_in_place<std::_Ref_count_obj_alloc3<tiledb::sm::FragmentMetadata,tiledb::common::GovernedAllocator<T,tiledb::common::`anonymous-namespace'::TiledbTracedAllocator,tiledb::common::Governor>>,const _Alloc&,_Ty>(std::_Ref_count_obj_alloc3<_Ty,_Alloc> &,const _Alloc &,_Ty &&) noexcept(false)' being compiled
with
[
T=tiledb::sm::FragmentMetadata,
_Alloc=tiledb::common::GovernedAllocator<tiledb::sm::FragmentMetadata,tiledb::common::`anonymous-namespace'::TiledbTracedAllocator,tiledb::common::Governor>,
_Ty=tiledb::sm::FragmentMetadata
]
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\xutility(255): note: see reference to function template instantiation 'std::_Ref_count_obj_alloc3<tiledb::sm::FragmentMetadata,tiledb::common::GovernedAllocator<T,tiledb::common::`anonymous-namespace'::TiledbTracedAllocator,tiledb::common::Governor>>::_Ref_count_obj_alloc3<_Ty>(const _Alloc &,_Ty &&)' being compiled
with
[
T=tiledb::sm::FragmentMetadata,
_Ty=tiledb::sm::FragmentMetadata,
_Alloc=tiledb::common::GovernedAllocator<tiledb::sm::FragmentMetadata,tiledb::common::`anonymous-namespace'::TiledbTracedAllocator,tiledb::common::Governor>
]
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\memory(2452): note: see reference to function template instantiation 'void std::_Normal_allocator_traits<_Alloc>::construct<_Ty,_Ty>(_Alloc &,_Ty *,_Ty &&)' being compiled
with
[
_Alloc=tiledb::common::GovernedAllocator<tiledb::sm::FragmentMetadata,tiledb::common::`anonymous-namespace'::TiledbTracedAllocator,tiledb::common::Governor>,
_Ty=tiledb::sm::FragmentMetadata
]
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\xmemory(610): note: see reference to function template instantiation '_Ty *std::construct_at<_Ty,_Ty,0x0>(_Ty *const ,_Ty &&) noexcept(<expr>)' being compiled
with
[
_Ty=tiledb::sm::FragmentMetadata
]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Turns out FragmentMetadata
has a mutex
, which is neither copy nor move-constructible. We cannot remove the shared_ptr
.
eae03a6
to
f894873
Compare
I restored some move constructors and am getting errors like |
@davisp any ideas here? |
That’s a rule for constructors on PMR containers stored inside other pmr containers. Either the constructor has to have the last argument for the Allocator, or the first argument must be the special trait marker and the second argument is the allocator argument. So likely this was adding the move constructor without providing an argument to accept the allocator. |
Pablo Halpern covers the container constructor stuff during this part of his cppcon talk: https://youtu.be/v3dz-AKOVL8?t=2360&si=qKn94l2h8x9uwtHT |
Thanks for the help! The problem was in d4d9007, and after a couple more modifications it builds locally. |
All feedback was addressed, except for one item which is not immediately actionable.
CI is green. @KiterLuc can we merge it? |
SC-40131
TYPE: NO_HISTORY
DESC: Refactor the
FragmentMetadata
class to reduce mutable state.