diff --git a/NetDb.cpp b/NetDb.cpp index c5d0fde8..b5868600 100644 --- a/NetDb.cpp +++ b/NetDb.cpp @@ -922,6 +922,50 @@ namespace data return r; } + std::vector NetDb::GetClosestFloodfills (const IdentHash& destination, size_t num) const + { + struct Sorted + { + std::shared_ptr r; + XORMetric metric; + bool operator< (const Sorted& other) const { return metric < other.metric; }; + }; + + std::set sorted; + IdentHash destKey = CreateRoutingKey (destination); + { + std::unique_lock l(m_FloodfillsMutex); + for (auto it: m_Floodfills) + { + if (!it->IsUnreachable ()) + { + XORMetric m = destKey ^ it->GetIdentHash (); + if (sorted.size () < num) + sorted.insert ({it, m}); + else if (m < sorted.rbegin ()->metric) + { + sorted.insert ({it, m}); + sorted.erase (std::prev (sorted.end ())); + } + } + } + } + + std::vector res; + size_t i = 0; + for (auto it: sorted) + { + if (i < num) + { + res.push_back (it.r->GetIdentHash ()); + i++; + } + else + break; + } + return res; + } + std::shared_ptr NetDb::GetClosestNonFloodfill (const IdentHash& destination, const std::set& excluded) const { diff --git a/NetDb.h b/NetDb.h index 106a529e..44efa454 100644 --- a/NetDb.h +++ b/NetDb.h @@ -51,6 +51,7 @@ namespace data std::shared_ptr GetRandomPeerTestRouter () const; std::shared_ptr GetRandomIntroducer () const; std::shared_ptr GetClosestFloodfill (const IdentHash& destination, const std::set& excluded) const; + std::vector GetClosestFloodfills (const IdentHash& destination, size_t num) const; std::shared_ptr GetClosestNonFloodfill (const IdentHash& destination, const std::set& excluded) const; void SetUnreachable (const IdentHash& ident, bool unreachable);