From e635aa30d60d3b387f2347f1f6127ff80ffb0321 Mon Sep 17 00:00:00 2001 From: Benny Halevy Date: Tue, 11 Apr 2023 15:29:46 +0300 Subject: [PATCH] token_metadata: get endpoint to node map from topology Don't maintain a "shadow" endpoint_to_host_id_map in token_metadata_impl. Instead, get the nodes_by_endpoint map from topology and use it to build the endpoint_to_host_id_map. Signed-off-by: Benny Halevy --- db/view/view.cc | 2 +- locator/token_metadata.cc | 49 ++++++++++++++++----------------------- locator/token_metadata.hh | 2 +- locator/topology.hh | 5 ++++ 4 files changed, 27 insertions(+), 31 deletions(-) diff --git a/db/view/view.cc b/db/view/view.cc index 6f49c4a5aa..cd6b5456b5 100644 --- a/db/view/view.cc +++ b/db/view/view.cc @@ -2093,7 +2093,7 @@ future<> view_builder::calculate_shard_build_step(view_builder_init_state& vbi) future> view_builder::view_build_statuses(sstring keyspace, sstring view_name) const { return _sys_dist_ks.view_status(std::move(keyspace), std::move(view_name)).then([] (std::unordered_map status) { - auto& endpoint_to_host_id = service::get_local_storage_proxy().get_token_metadata_ptr()->get_endpoint_to_host_id_map_for_reading(); + auto endpoint_to_host_id = service::get_local_storage_proxy().get_token_metadata_ptr()->get_endpoint_to_host_id_map_for_reading(); return boost::copy_range>(endpoint_to_host_id | boost::adaptors::transformed([&status] (const std::pair& p) { auto it = status.find(p.second); diff --git a/locator/token_metadata.cc b/locator/token_metadata.cc index 7ce338083d..32254ca33c 100644 --- a/locator/token_metadata.cc +++ b/locator/token_metadata.cc @@ -53,9 +53,6 @@ private: // Track the unique set of nodes in _token_to_endpoint_map std::unordered_set _normal_token_owners; - /** Maintains endpoint to host ID map of every node in the cluster */ - std::unordered_map _endpoint_to_host_id_map; - std::unordered_map _bootstrap_tokens; std::unordered_set _leaving_endpoints; // The map between the existing node to be replaced and the replacing node @@ -148,7 +145,7 @@ public: std::optional get_endpoint_for_host_id(host_id) const; /** @return a copy of the endpoint-to-id map for read-only operations */ - const std::unordered_map& get_endpoint_to_host_id_map_for_reading() const; + std::unordered_map get_endpoint_to_host_id_map_for_reading() const; void add_bootstrap_token(token t, inet_address endpoint); @@ -367,7 +364,6 @@ future token_metadata_impl::clone_only_token_map(bool clone co_await coroutine::maybe_yield(); } ret._normal_token_owners = _normal_token_owners; - ret._endpoint_to_host_id_map = _endpoint_to_host_id_map; ret._topology = co_await _topology.clone_gently(); if (clone_sorted_tokens) { ret._sorted_tokens = _sorted_tokens; @@ -379,7 +375,6 @@ future token_metadata_impl::clone_only_token_map(bool clone future<> token_metadata_impl::clear_gently() noexcept { co_await utils::clear_gently(_token_to_endpoint_map); co_await utils::clear_gently(_normal_token_owners); - co_await utils::clear_gently(_endpoint_to_host_id_map); co_await utils::clear_gently(_bootstrap_tokens); co_await utils::clear_gently(_leaving_endpoints); co_await utils::clear_gently(_replacing_endpoints); @@ -508,10 +503,6 @@ void token_metadata_impl::debug_show() const { for (auto x : _token_to_endpoint_map) { fmt::print("inet_address={}, token={}\n", x.second, x.first); } - fmt::print("Endpoint -> host_id\n"); - for (auto x : _endpoint_to_host_id_map) { - fmt::print("inet_address={}, uuid={}\n", x.first, x.second); - } fmt::print("Sorted Token\n"); for (auto x : _sorted_tokens) { fmt::print("token={}\n", x); @@ -522,39 +513,40 @@ void token_metadata_impl::debug_show() const { void token_metadata_impl::update_host_id(const host_id& host_id, inet_address endpoint) { _topology.add_or_update_endpoint(endpoint, host_id); - _endpoint_to_host_id_map[endpoint] = host_id; } host_id token_metadata_impl::get_host_id(inet_address endpoint) const { - if (!_endpoint_to_host_id_map.contains(endpoint)) { + if (const auto* node = _topology.find_node(endpoint)) [[likely]] { + return node->host_id(); + } else { throw std::runtime_error(format("host_id for endpoint {} is not found", endpoint)); } - return _endpoint_to_host_id_map.at(endpoint); } std::optional token_metadata_impl::get_host_id_if_known(inet_address endpoint) const { - auto it = _endpoint_to_host_id_map.find(endpoint); - if (it == _endpoint_to_host_id_map.end()) { - return { }; + if (const auto* node = _topology.find_node(endpoint)) [[likely]] { + return node->host_id(); + } else { + return std::nullopt; } - return it->second; } std::optional token_metadata_impl::get_endpoint_for_host_id(host_id host_id) const { - auto beg = _endpoint_to_host_id_map.cbegin(); - auto end = _endpoint_to_host_id_map.cend(); - auto it = std::find_if(beg, end, [host_id] (auto x) { - return x.second == host_id; - }); - if (it == end) { - return {}; + if (const auto* node = _topology.find_node(host_id)) [[likely]] { + return node->endpoint(); } else { - return (*it).first; + return std::nullopt; } } -const std::unordered_map& token_metadata_impl::get_endpoint_to_host_id_map_for_reading() const{ - return _endpoint_to_host_id_map; +std::unordered_map token_metadata_impl::get_endpoint_to_host_id_map_for_reading() const { + const auto& nodes = _topology.get_nodes_by_endpoint(); + std::unordered_map map; + map.reserve(nodes.size()); + for (const auto& [endpoint, node] : nodes) { + map[endpoint] = node->host_id(); + } + return map; } bool token_metadata_impl::is_normal_token_owner(inet_address endpoint) const { @@ -635,7 +627,6 @@ void token_metadata_impl::remove_endpoint(inet_address endpoint) { _topology.remove_endpoint(endpoint); _leaving_endpoints.erase(endpoint); del_replacing_endpoint(endpoint); - _endpoint_to_host_id_map.erase(endpoint); invalidate_cached_rings(); } @@ -1080,7 +1071,7 @@ host_id_or_endpoint token_metadata::parse_host_id_and_endpoint(const sstring& ho return res; } -const std::unordered_map& +std::unordered_map token_metadata::get_endpoint_to_host_id_map_for_reading() const { return _impl->get_endpoint_to_host_id_map_for_reading(); } diff --git a/locator/token_metadata.hh b/locator/token_metadata.hh index 25e5863e48..d9eccac12f 100644 --- a/locator/token_metadata.hh +++ b/locator/token_metadata.hh @@ -161,7 +161,7 @@ public: host_id_or_endpoint parse_host_id_and_endpoint(const sstring& host_id_string) const; /** @return a copy of the endpoint-to-id map for read-only operations */ - const std::unordered_map& get_endpoint_to_host_id_map_for_reading() const; + std::unordered_map get_endpoint_to_host_id_map_for_reading() const; void add_bootstrap_token(token t, inet_address endpoint); diff --git a/locator/topology.hh b/locator/topology.hh index d67701e325..9ce0f5f73b 100644 --- a/locator/topology.hh +++ b/locator/topology.hh @@ -304,6 +304,11 @@ private: void calculate_datacenters(); + const std::unordered_map& get_nodes_by_endpoint() const noexcept { + return _nodes_by_endpoint; + }; + + friend class token_metadata_impl; public: void test_compare_endpoints(const inet_address& address, const inet_address& a1, const inet_address& a2) const; };