From 8a20d3219bc772536d64dc103d2b15c3b8b29f55 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 3 May 2024 08:54:55 -0400 Subject: [PATCH] don't build exploratory selection on each request --- libi2pd/NetDb.cpp | 48 +++++++++++++++++++++++++++-------------------- libi2pd/NetDb.hpp | 6 +++++- 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index f1d221ce..b244b52f 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -38,7 +38,9 @@ namespace data { NetDb netdb; - NetDb::NetDb (): m_IsRunning (false), m_Thread (nullptr), m_Reseeder (nullptr), m_Storage("netDb", "r", "routerInfo-", "dat"), m_PersistProfiles (true) + NetDb::NetDb (): m_IsRunning (false), m_Thread (nullptr), m_Reseeder (nullptr), + m_Storage("netDb", "r", "routerInfo-", "dat"), m_PersistProfiles (true), + m_LastExploratorySelectionUpdateTime (0) { } @@ -1094,7 +1096,7 @@ namespace data excludedRouters.insert (excluded_ident); excluded_ident += 32; } - replyMsg = CreateDatabaseSearchReply (ident, GetClosestNonFloodfill (ident, + replyMsg = CreateDatabaseSearchReply (ident, GetExploratoryNonFloodfill (ident, NETDB_MAX_NUM_SEARCH_REPLY_PEER_HASHES, excludedRouters)); } else @@ -1451,32 +1453,38 @@ namespace data }); } - std::vector NetDb::GetClosestNonFloodfill (const IdentHash& destination, - size_t num, const std::set& excluded) const + std::vector NetDb::GetExploratoryNonFloodfill (const IdentHash& destination, + size_t num, const std::set& excluded) { std::vector ret; if (!num) return ret; // empty list - // collect eligible - std::vector > eligible; - eligible.reserve (NETDB_MAX_EXPLORATORY_SELECTION_SIZE); + auto ts = i2p::util::GetMonotonicSeconds (); + if (ts > m_LastExploratorySelectionUpdateTime + NETDB_EXPLORATORY_SELECTION_UPDATE_INTERVAL) { - bool checkIsReal = i2p::tunnel::tunnels.GetPreciseTunnelCreationSuccessRate () < NETDB_TUNNEL_CREATION_RATE_THRESHOLD; // too low rate - std::lock_guard l(m_RouterInfosMutex); - for (const auto& it: m_RouterInfos) - if (!it.second->IsDeclaredFloodfill () && - (!checkIsReal || (it.second->HasProfile () && it.second->GetProfile ()->IsReal ()))) - eligible.push_back (it.second); - } - // reduce number of eligible routers if too many - if (eligible.size () > NETDB_MAX_EXPLORATORY_SELECTION_SIZE) - { - std::shuffle (eligible.begin(), eligible.end(), std::mt19937(std::random_device()())); - eligible.resize (NETDB_MAX_EXPLORATORY_SELECTION_SIZE); + // update selection + m_ExploratorySelection.clear (); + { + // collect eligible from current netdb + bool checkIsReal = i2p::tunnel::tunnels.GetPreciseTunnelCreationSuccessRate () < NETDB_TUNNEL_CREATION_RATE_THRESHOLD; // too low rate + std::lock_guard l(m_RouterInfosMutex); + for (const auto& it: m_RouterInfos) + if (!it.second->IsDeclaredFloodfill () && + (!checkIsReal || (it.second->HasProfile () && it.second->GetProfile ()->IsReal ()))) + m_ExploratorySelection.push_back (it.second); + } + if (m_ExploratorySelection.size () > NETDB_MAX_EXPLORATORY_SELECTION_SIZE) + { + // reduce number of eligible to max selection size + std::shuffle (m_ExploratorySelection.begin(), m_ExploratorySelection.end(), std::mt19937(std::random_device()())); + m_ExploratorySelection.resize (NETDB_MAX_EXPLORATORY_SELECTION_SIZE); + } + m_LastExploratorySelectionUpdateTime = ts; } + // sort by distance IdentHash destKey = CreateRoutingKey (destination); std::map > sorted; - for (const auto& it: eligible) + for (const auto& it: m_ExploratorySelection) if (!excluded.count (it->GetIdentHash ())) sorted.emplace (destKey ^ it->GetIdentHash (), it); // return first num closest routers diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index dedced61..4153817a 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -55,6 +55,7 @@ namespace data const int NETDB_MIN_SHORT_TUNNEL_BUILD_VERSION = MAKE_VERSION_NUMBER(0, 9, 51); // 0.9.51 const size_t NETDB_MAX_NUM_SEARCH_REPLY_PEER_HASHES = 16; const size_t NETDB_MAX_EXPLORATORY_SELECTION_SIZE = 500; + const int NETDB_EXPLORATORY_SELECTION_UPDATE_INTERVAL = 82; // in seconds /** function for visiting a leaseset stored in a floodfill */ typedef std::function)> LeaseSetVisitor; @@ -99,7 +100,7 @@ namespace data std::shared_ptr GetClosestFloodfill (const IdentHash& destination, const std::set& excluded) const; std::vector GetClosestFloodfills (const IdentHash& destination, size_t num, std::set& excluded, bool closeThanUsOnly = false) const; - std::vector GetClosestNonFloodfill (const IdentHash& destination, size_t num, const std::set& excluded) const; + std::vector GetExploratoryNonFloodfill (const IdentHash& destination, size_t num, const std::set& excluded); std::shared_ptr GetRandomRouterInFamily (FamilyID fam) const; void SetUnreachable (const IdentHash& ident, bool unreachable); void ExcludeReachableTransports (const IdentHash& ident, RouterInfo::CompatibleTransports transports); @@ -190,6 +191,9 @@ namespace data std::set m_PublishExcluded; uint32_t m_PublishReplyToken = 0; + std::vector > m_ExploratorySelection; + uint64_t m_LastExploratorySelectionUpdateTime; // in monotonic seconds + i2p::util::MemoryPoolMt m_RouterInfoBuffersPool; i2p::util::MemoryPoolMt m_RouterInfoAddressesPool; i2p::util::MemoryPoolMt m_RouterInfoAddressVectorsPool;