token_metadata: Speed up count_normal_token_owners

Currently, a set of nodes is built from _token_to_endpoint_map to get
the number of nodes in _token_to_endpoint_map.

To make it faster so we can call it on a fast path in the following
patch, a _nr_normal_token_owners member is introduced to track the
number.

Refs #10337
Refs #10817
Refs #10836
Refs #10837
This commit is contained in:
Asias He
2022-06-22 09:50:56 +08:00
parent 5a30f9b789
commit 4c714dfe3b

View File

@@ -50,6 +50,9 @@ private:
*/
// FIXME: have to be BiMultiValMap
std::unordered_map<token, inet_address> _token_to_endpoint_map;
// Track the number of nodes in _token_to_endpoint_map. Need to update
// _nr_normal_token_owners when _token_to_endpoint_map is updated.
size_t _nr_normal_token_owners;
/** Maintains endpoint to host ID map of every node in the cluster */
std::unordered_map<inet_address, utils::UUID> _endpoint_to_host_id_map;
@@ -276,6 +279,8 @@ public:
/* Returns the number of different endpoints that own tokens in the ring.
* Bootstrapping tokens are not taken into account. */
size_t count_normal_token_owners() const;
private:
void update_normal_token_owners();
public:
// returns empty vector if keyspace_name not found.
@@ -362,6 +367,7 @@ future<token_metadata_impl> token_metadata_impl::clone_only_token_map(bool clone
return do_for_each(_token_to_endpoint_map, [&ret] (const auto& p) {
ret._token_to_endpoint_map.emplace(p);
}).then([this, &ret] {
ret._nr_normal_token_owners = _nr_normal_token_owners;
ret._endpoint_to_host_id_map = _endpoint_to_host_id_map;
}).then([this, &ret] {
ret._topology = _topology;
@@ -376,6 +382,7 @@ future<token_metadata_impl> 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);
update_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);
@@ -475,6 +482,7 @@ future<> token_metadata_impl::update_normal_tokens(const std::unordered_map<inet
}
}
}
update_normal_token_owners();
// New tokens were added to _token_to_endpoint_map
// so re-sort all tokens.
@@ -647,6 +655,7 @@ bool token_metadata_impl::is_any_node_being_replaced() const {
void token_metadata_impl::remove_endpoint(inet_address endpoint) {
remove_by_value(_bootstrap_tokens, endpoint);
remove_by_value(_token_to_endpoint_map, endpoint);
update_normal_token_owners();
_topology.remove_endpoint(endpoint);
_leaving_endpoints.erase(endpoint);
del_replacing_endpoint(endpoint);
@@ -904,11 +913,15 @@ future<> token_metadata_impl::update_pending_ranges(
}
size_t token_metadata_impl::count_normal_token_owners() const {
std::set<inet_address> eps;
return _nr_normal_token_owners;
}
void token_metadata_impl::update_normal_token_owners() {
std::unordered_set<inet_address> eps;
for (auto [t, ep]: _token_to_endpoint_map) {
eps.insert(ep);
}
return eps.size();
_nr_normal_token_owners = eps.size();
}
void token_metadata_impl::add_leaving_endpoint(inet_address endpoint) {