db/hints: Introduce hint_directory_manager
This commit introduces a new class responsible for keeping track of mappings IP-host ID. Before hinted handoff is migrated to using host IDs, hint directories still have to represent IP addresses. However, since we identify endpoint managers by host IDs already, we need to be able to associate them with the directories they manage. This class serves this purpose.
This commit is contained in:
@@ -275,5 +275,76 @@ future<> rebalance_hints(fs::path hint_directory) {
|
||||
co_await remove_irrelevant_shards_directories(hint_directory);
|
||||
}
|
||||
|
||||
std::pair<locator::host_id, gms::inet_address> hint_directory_manager::insert_mapping(const locator::host_id& host_id,
|
||||
const gms::inet_address& ip)
|
||||
{
|
||||
const auto maybe_mapping = get_mapping(host_id, ip);
|
||||
if (maybe_mapping) {
|
||||
return *maybe_mapping;
|
||||
}
|
||||
|
||||
|
||||
_mappings.emplace(host_id, ip);
|
||||
return std::make_pair(host_id, ip);
|
||||
}
|
||||
|
||||
std::optional<gms::inet_address> hint_directory_manager::get_mapping(const locator::host_id& host_id) const noexcept {
|
||||
auto it = _mappings.find(host_id);
|
||||
if (it != _mappings.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::optional<locator::host_id> hint_directory_manager::get_mapping(const gms::inet_address& ip) const noexcept {
|
||||
for (const auto& [host_id, ep] : _mappings) {
|
||||
if (ep == ip) {
|
||||
return host_id;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::optional<std::pair<locator::host_id, gms::inet_address>> hint_directory_manager::get_mapping(
|
||||
const locator::host_id& host_id, const gms::inet_address& ip) const noexcept
|
||||
{
|
||||
for (const auto& [hid, ep] : _mappings) {
|
||||
if (hid == host_id || ep == ip) {
|
||||
return std::make_pair(hid, ep);
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void hint_directory_manager::remove_mapping(const locator::host_id& host_id) noexcept {
|
||||
_mappings.erase(host_id);
|
||||
}
|
||||
|
||||
void hint_directory_manager::remove_mapping(const gms::inet_address& ip) noexcept {
|
||||
for (const auto& [host_id, ep] : _mappings) {
|
||||
if (ep == ip) {
|
||||
_mappings.erase(host_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool hint_directory_manager::has_mapping(const locator::host_id& host_id) const noexcept {
|
||||
return _mappings.contains(host_id);
|
||||
}
|
||||
|
||||
bool hint_directory_manager::has_mapping(const gms::inet_address& ip) const noexcept {
|
||||
for (const auto& [_, ep] : _mappings) {
|
||||
if (ip == ep) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void hint_directory_manager::clear() noexcept {
|
||||
_mappings.clear();
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace db::hints
|
||||
|
||||
@@ -46,5 +46,41 @@ using hint_entry_reader = commitlog_entry_reader;
|
||||
/// \return A future that resolves when the operation is complete.
|
||||
future<> rebalance_hints(std::filesystem::path hint_directory);
|
||||
|
||||
class hint_directory_manager {
|
||||
private:
|
||||
std::map<locator::host_id, gms::inet_address> _mappings;
|
||||
|
||||
public:
|
||||
// Inserts a new mapping and returns it.
|
||||
// If either the host ID or the IP is already in the map, the function inserts nothings
|
||||
// and returns the existing mapping instead.
|
||||
std::pair<locator::host_id, gms::inet_address> insert_mapping(const locator::host_id& host_id,
|
||||
const gms::inet_address& ip);
|
||||
|
||||
// Returns the corresponding IP for a given host ID if a mapping is present in the directory manager.
|
||||
// Otherwise, an empty optional is returned.
|
||||
[[nodiscard]] std::optional<gms::inet_address> get_mapping(const locator::host_id& host_id) const noexcept;
|
||||
|
||||
// Returns the corresponding host ID for a given IP if a mapping is present in the directory manager.
|
||||
// Otherwise, an empty optional is returned.
|
||||
[[nodiscard]] std::optional<locator::host_id> get_mapping(const gms::inet_address& ip) const noexcept;
|
||||
|
||||
// Returns a mapping corresponding to either the passed host ID, or the passed IP if the mapping exists.
|
||||
// Otherwise, an empty optional is returned.
|
||||
[[nodiscard]] std::optional<std::pair<locator::host_id, gms::inet_address>> get_mapping(
|
||||
const locator::host_id& host_id, const gms::inet_address& ip) const noexcept;
|
||||
|
||||
// Removes a mapping corresponding to the passed host ID if the mapping exists.
|
||||
void remove_mapping(const locator::host_id& host_id) noexcept;
|
||||
// Removes a mapping corresponding to the passed IP if the mapping exists.
|
||||
void remove_mapping(const gms::inet_address& ip) noexcept;
|
||||
|
||||
bool has_mapping(const locator::host_id& host_id) const noexcept;
|
||||
bool has_mapping(const gms::inet_address& ip) const noexcept;
|
||||
|
||||
// Removes all of the mappings.
|
||||
void clear() noexcept;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace db::hints
|
||||
|
||||
Reference in New Issue
Block a user