diff --git a/locator/token_metadata.cc b/locator/token_metadata.cc index a9d1639bfe..af8739e468 100644 --- a/locator/token_metadata.cc +++ b/locator/token_metadata.cc @@ -917,12 +917,36 @@ future<> topology_change_info::clear_gently() { template generic_token_metadata::generic_token_metadata(std::unique_ptr> impl) - : _impl(std::move(impl)) { + : _impl(std::move(impl)) +{ +} + +template +template +requires std::is_same_v +generic_token_metadata::generic_token_metadata(std::unique_ptr> impl, + token_metadata2 new_value) + : _impl(std::move(impl)) + , _new_value(make_token_metadata2_ptr(std::move(new_value))) +{ +} + +template +template +requires std::is_same_v +generic_token_metadata::generic_token_metadata(token_metadata2_ptr new_value) + : _impl(nullptr) + , _new_value(std::move(new_value)) +{ } template generic_token_metadata::generic_token_metadata(config cfg) - : _impl(std::make_unique>(std::move(cfg))) { + : _impl(std::make_unique>(cfg)) +{ + if constexpr (std::is_same_v) { + _new_value = make_token_metadata2_ptr(std::move(cfg)); + } } template @@ -1163,30 +1187,47 @@ void generic_token_metadata::del_replacing_endpoint(NodeId existing_node template future> generic_token_metadata::clone_async() const noexcept { - return _impl->clone_async().then([] (std::unique_ptr> impl) { - return make_ready_future(std::move(impl)); - }); + if constexpr (std::is_same_v) { + co_return !holds_alternative(_new_value) + ? generic_token_metadata(co_await _impl->clone_async(), co_await get_new()->clone_async()) + : generic_token_metadata(co_await _impl->clone_async()); + } else { + co_return generic_token_metadata(co_await _impl->clone_async()); + } } template future> generic_token_metadata::clone_only_token_map() const noexcept { - return _impl->clone_only_token_map().then([] (std::unique_ptr> impl) { - return generic_token_metadata(std::move(impl)); - }); + if constexpr (std::is_same_v) { + co_return !holds_alternative(_new_value) + ? generic_token_metadata(co_await _impl->clone_only_token_map(), co_await get_new()->clone_only_token_map()) + : generic_token_metadata(co_await _impl->clone_only_token_map()); + } else { + co_return generic_token_metadata(co_await _impl->clone_only_token_map()); + } } template future> generic_token_metadata::clone_after_all_left() const noexcept { - return _impl->clone_after_all_left().then([] (std::unique_ptr> impl) { - return generic_token_metadata(std::move(impl)); - }); + if constexpr (std::is_same_v) { + co_return !holds_alternative(_new_value) + ? generic_token_metadata(co_await _impl->clone_after_all_left(), co_await get_new()->clone_after_all_left()) + : generic_token_metadata(co_await _impl->clone_after_all_left()); + } else { + co_return generic_token_metadata(co_await _impl->clone_after_all_left()); + } } template future<> generic_token_metadata::clear_gently() noexcept { - return _impl->clear_gently(); + co_await _impl->clear_gently(); + if constexpr (std::is_same_v) { + if (holds_alternative>(_new_value)) { + co_await get_new()->clear_gently(); + } + } } template @@ -1409,5 +1450,10 @@ template class generic_token_metadata; template class generic_token_metadata; template void host_id_or_endpoint::resolve(const token_metadata& tm); template void host_id_or_endpoint::resolve(const token_metadata2& tm); +template token_metadata2* generic_token_metadata::get_new<>(); +template const token_metadata2* generic_token_metadata::get_new<>() const; +template lw_shared_ptr generic_token_metadata::get_new_strong<>() const; +template generic_token_metadata::generic_token_metadata(std::unique_ptr>, token_metadata2); +template generic_token_metadata::generic_token_metadata(token_metadata2_ptr); } // namespace locator diff --git a/locator/token_metadata.hh b/locator/token_metadata.hh index 8b5b4310f6..64e13e6866 100644 --- a/locator/token_metadata.hh +++ b/locator/token_metadata.hh @@ -93,6 +93,7 @@ public: template class generic_token_metadata final: public generic_token_metadata_base { std::unique_ptr> _impl; + std::variant, lw_shared_ptr> _new_value; private: friend class token_metadata_ring_splitter; class tokens_iterator { @@ -119,6 +120,12 @@ private: public: generic_token_metadata(config cfg); explicit generic_token_metadata(std::unique_ptr> impl); + template + requires std::is_same_v + generic_token_metadata(std::unique_ptr> impl, token_metadata2 new_value); + template + requires std::is_same_v + generic_token_metadata(lw_shared_ptr new_value); generic_token_metadata(generic_token_metadata&&) noexcept; // Can't use "= default;" - hits some static_assert in unique_ptr generic_token_metadata& operator=(generic_token_metadata&&) noexcept; ~generic_token_metadata(); @@ -140,6 +147,39 @@ public: const std::unordered_set& get_leaving_endpoints() const; const std::unordered_map& get_bootstrap_tokens() const; + template + requires std::is_same_v + token_metadata2* get_new() { + if (holds_alternative>(_new_value)) { + return get>(_new_value).get(); + } + throw_with_backtrace("no mutable new value"); + } + + template + requires std::is_same_v + const token_metadata2* get_new() const { + if (holds_alternative>(_new_value)) { + return get>(_new_value).get(); + } + if (holds_alternative>(_new_value)) { + return get>(_new_value).get(); + } + throw_with_backtrace("no new value"); + } + + template + requires std::is_same_v + lw_shared_ptr get_new_strong() const { + if (holds_alternative>(_new_value)) { + return get>(_new_value); + } + if (holds_alternative>(_new_value)) { + return get>(_new_value); + } + throw_with_backtrace("no new value"); + } + /** * Update or add endpoint given its inet_address and endpoint_dc_rack. */