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:
Dawid Medrek
2024-03-22 14:12:09 +01:00
parent f9af01852d
commit d0f58736c8
2 changed files with 107 additions and 0 deletions

View File

@@ -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

View File

@@ -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