Browse Source

Add NetDb::VisitRandomRouterInfos

pull/628/head
Jeff Becker 8 years ago
parent
commit
970557660e
No known key found for this signature in database
GPG Key ID: AB950234D6EA286B
  1. 54
      NetDb.cpp
  2. 8
      NetDb.h

54
NetDb.cpp

@ -69,18 +69,8 @@ namespace data
} }
} }
void NetDb::WaitForReady()
{
m_Ready.get_future().wait();
}
void NetDb::Run () void NetDb::Run ()
{ {
try {
m_Ready.set_value();
} catch( std::future_error & ex) {
(void) ex;
}
uint32_t lastSave = 0, lastPublish = 0, lastExploratory = 0, lastManageRequest = 0, lastDestinationCleanup = 0; uint32_t lastSave = 0, lastPublish = 0, lastExploratory = 0, lastManageRequest = 0, lastDestinationCleanup = 0;
while (m_IsRunning) while (m_IsRunning)
{ {
@ -355,6 +345,50 @@ namespace data
v(*item.second); v(*item.second);
} }
size_t NetDb::VisitRandomRouterInfos(RouterInfoFilter filter, RouterInfoVisitor v, size_t n)
{
std::vector<std::shared_ptr<const RouterInfo> > found;
const size_t max_iters_per_cyle = 3;
size_t iters = max_iters_per_cyle;
while(n)
{
std::unique_lock<std::mutex> lock(m_RouterInfosMutex);
uint32_t idx = rand () % m_RouterInfos.size ();
uint32_t i = 0;
for (const auto & it : m_RouterInfos) {
if(i >= idx) // are we at the random start point?
{
// yes, check if we want this one
if(filter(*it.second))
{
// we have a match
--n;
found.push_back(it.second);
// reset max iterations per cycle
iters = max_iters_per_cyle;
break;
}
}
else // not there yet
++i;
}
--iters;
// have we tried enough this cycle ?
if(!iters) {
// yes let's try the next cycle
--n;
iters = max_iters_per_cyle;
}
}
// visit the ones we found
size_t visited = 0;
for(const auto & ri : found ) {
v(*ri);
++visited;
}
return visited;
}
void NetDb::Load () void NetDb::Load ()
{ {
// make sure we cleanup netDb from previous attempts // make sure we cleanup netDb from previous attempts

8
NetDb.h

@ -40,6 +40,9 @@ namespace data
/** function for visiting a router info we have locally */ /** function for visiting a router info we have locally */
typedef std::function<void(const i2p::data::RouterInfo &)> RouterInfoVisitor; typedef std::function<void(const i2p::data::RouterInfo &)> RouterInfoVisitor;
/** function for visiting a router info and determining if we want to use it */
typedef std::function<bool(const i2p::data::RouterInfo &)> RouterInfoFilter;
class NetDb class NetDb
{ {
public: public:
@ -49,8 +52,6 @@ namespace data
void Start (); void Start ();
void Stop (); void Stop ();
/** block until netdb is ready, call only once*/
void WaitForReady();
bool AddRouterInfo (const uint8_t * buf, int len); bool AddRouterInfo (const uint8_t * buf, int len);
bool AddRouterInfo (const IdentHash& ident, const uint8_t * buf, int len); bool AddRouterInfo (const IdentHash& ident, const uint8_t * buf, int len);
@ -96,6 +97,8 @@ namespace data
void VisitStoredRouterInfos(RouterInfoVisitor v); void VisitStoredRouterInfos(RouterInfoVisitor v);
/** visit all router infos we have loaded in memory, cheaper than VisitLocalRouterInfos but locks access while visiting */ /** visit all router infos we have loaded in memory, cheaper than VisitLocalRouterInfos but locks access while visiting */
void VisitRouterInfos(RouterInfoVisitor v); void VisitRouterInfos(RouterInfoVisitor v);
/** visit N random router that match using filter, then visit them with a visitor, return number of RouterInfos that were visited */
size_t VisitRandomRouterInfos(RouterInfoFilter f, RouterInfoVisitor v, size_t n);
private: private:
void Load (); void Load ();
@ -112,7 +115,6 @@ namespace data
std::shared_ptr<const RouterInfo> GetRandomRouter (Filter filter) const; std::shared_ptr<const RouterInfo> GetRandomRouter (Filter filter) const;
private: private:
std::promise<void> m_Ready;
mutable std::mutex m_LeaseSetsMutex; mutable std::mutex m_LeaseSetsMutex;
std::map<IdentHash, std::shared_ptr<LeaseSet> > m_LeaseSets; std::map<IdentHash, std::shared_ptr<LeaseSet> > m_LeaseSets;

Loading…
Cancel
Save