snitch: Move sort_by_proximity() to topology

Signed-off-by: Pavel Emelyanov <xemul@scylladb.com>
This commit is contained in:
Pavel Emelyanov
2022-08-30 13:26:25 +03:00
parent 41973c5bf7
commit debfcc0eff
5 changed files with 64 additions and 91 deletions

View File

@@ -37,16 +37,6 @@ struct simple_snitch : public snitch_base {
return "datacenter1";
}
virtual void sort_by_proximity(
inet_address address, inet_address_vector_replica_set& addresses) override {
// Optimization to avoid walking the list
}
virtual int compare_endpoints(inet_address& target, inet_address& a1,
inet_address& a2) override {
return 0;
}
virtual sstring get_name() const override {
return "org.apache.cassandra.locator.SimpleSnitch";
}

View File

@@ -13,66 +13,6 @@
#include "gms/application_state.hh"
namespace locator {
void snitch_base::sort_by_proximity(
inet_address address, inet_address_vector_replica_set& addresses) {
std::sort(addresses.begin(), addresses.end(),
[this, &address](inet_address& a1, inet_address& a2)
{
return compare_endpoints(address, a1, a2) < 0;
});
}
int snitch_base::compare_endpoints(
inet_address& address, inet_address& a1, inet_address& a2) {
//
// if one of the Nodes IS the Node we are comparing to and the other one
// IS NOT - then return the appropriate result.
//
if (address == a1 && address != a2) {
return -1;
}
if (address == a2 && address != a1) {
return 1;
}
// ...otherwise perform the similar check in regard to Data Center
sstring address_datacenter = get_datacenter(address);
sstring a1_datacenter = get_datacenter(a1);
sstring a2_datacenter = get_datacenter(a2);
if (address_datacenter == a1_datacenter &&
address_datacenter != a2_datacenter) {
return -1;
} else if (address_datacenter == a2_datacenter &&
address_datacenter != a1_datacenter) {
return 1;
} else if (address_datacenter == a2_datacenter &&
address_datacenter == a1_datacenter) {
//
// ...otherwise (in case Nodes belong to the same Data Center) check
// the racks they belong to.
//
sstring address_rack = get_rack(address);
sstring a1_rack = get_rack(a1);
sstring a2_rack = get_rack(a2);
if (address_rack == a1_rack && address_rack != a2_rack) {
return -1;
}
if (address_rack == a2_rack && address_rack != a1_rack) {
return 1;
}
}
//
// We don't differentiate between Nodes if all Nodes belong to different
// Data Centers, thus make them equal.
//
return 0;
}
std::list<std::pair<gms::application_state, gms::versioned_value>> snitch_base::get_app_states() const {
return {

View File

@@ -67,20 +67,6 @@ public:
*/
virtual sstring get_datacenter(inet_address endpoint) = 0;
/**
* This method will sort the <tt>List</tt> by proximity to the given
* address.
*/
virtual void sort_by_proximity(
inet_address address, inet_address_vector_replica_set& addresses) = 0;
/**
* compares two endpoints in relation to the target endpoint, returning as
* Comparator.compare would
*/
virtual int compare_endpoints(
inet_address& target, inet_address& a1, inet_address& a2) = 0;
/**
* returns whatever info snitch wants to gossip
*/
@@ -313,12 +299,6 @@ public:
// virtual sstring get_datacenter(inet_address endpoint) = 0;
//
virtual void sort_by_proximity(
inet_address address, inet_address_vector_replica_set& addresses) override;
virtual int compare_endpoints(
inet_address& address, inet_address& a1, inet_address& a2) override;
virtual std::list<std::pair<gms::application_state, gms::versioned_value>> get_app_states() const override;
protected:

View File

@@ -1320,7 +1320,60 @@ std::function<bool(inet_address)> topology::get_local_dc_filter() const noexcept
}
void topology::sort_by_proximity(inet_address address, inet_address_vector_replica_set& addresses) const {
i_endpoint_snitch::get_local_snitch_ptr()->sort_by_proximity(address, addresses);
if (_sort_by_proximity) {
std::sort(addresses.begin(), addresses.end(), [this, &address](inet_address& a1, inet_address& a2) {
return compare_endpoints(address, a1, a2) < 0;
});
}
}
int topology::compare_endpoints(inet_address& address, inet_address& a1, inet_address& a2) const {
//
// if one of the Nodes IS the Node we are comparing to and the other one
// IS NOT - then return the appropriate result.
//
if (address == a1 && address != a2) {
return -1;
}
if (address == a2 && address != a1) {
return 1;
}
// ...otherwise perform the similar check in regard to Data Center
sstring address_datacenter = get_datacenter(address);
sstring a1_datacenter = get_datacenter(a1);
sstring a2_datacenter = get_datacenter(a2);
if (address_datacenter == a1_datacenter &&
address_datacenter != a2_datacenter) {
return -1;
} else if (address_datacenter == a2_datacenter &&
address_datacenter != a1_datacenter) {
return 1;
} else if (address_datacenter == a2_datacenter &&
address_datacenter == a1_datacenter) {
//
// ...otherwise (in case Nodes belong to the same Data Center) check
// the racks they belong to.
//
sstring address_rack = get_rack(address);
sstring a1_rack = get_rack(a1);
sstring a2_rack = get_rack(a2);
if (address_rack == a1_rack && address_rack != a2_rack) {
return -1;
}
if (address_rack == a2_rack && address_rack != a1_rack) {
return 1;
}
}
//
// We don't differentiate between Nodes if all Nodes belong to different
// Data Centers, thus make them equal.
//
return 0;
}
/////////////////// class topology end /////////////////////////////////////////

View File

@@ -105,6 +105,10 @@ public:
return std::count_if(endpoints.begin(), endpoints.end(), filter);
}
/**
* This method will sort the <tt>List</tt> by proximity to the given
* address.
*/
void sort_by_proximity(inet_address address, inet_address_vector_replica_set& addresses) const;
void disable_proximity_sorting() noexcept {
@@ -112,6 +116,12 @@ public:
}
private:
/**
* compares two endpoints in relation to the target endpoint, returning as
* Comparator.compare would
*/
int compare_endpoints(inet_address& address, inet_address& a1, inet_address& a2) const;
/** multi-map: DC -> endpoints in that DC */
std::unordered_map<sstring,
std::unordered_set<inet_address>>