MCPcopy Create free account
hub / github.com/PurpleI2P/i2pd / GetRandomPeer

Method GetRandomPeer

libi2pd/Transports.cpp:1151–1242  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1149
1150 template<typename Filter>
1151 std::shared_ptr<const i2p::data::RouterInfo> Transports::GetRandomPeer (Filter filter) const
1152 {
1153 if (m_Peers.empty()) return nullptr;
1154 auto ts = i2p::util::GetSecondsSinceEpoch ();
1155 bool found = false;
1156 i2p::data::IdentHash ident;
1157 {
1158 uint16_t inds[3];
1159 RAND_bytes ((uint8_t *)inds, sizeof (inds));
1160 std::lock_guard<std::mutex> l(m_PeersMutex);
1161 auto count = m_Peers.size ();
1162 if(count == 0) return nullptr;
1163 inds[0] %= count;
1164 auto it = m_Peers.begin ();
1165 std::advance (it, inds[0]);
1166 // try random peer
1167 if (it != m_Peers.end () && filter (it->second))
1168 {
1169 ident = it->first;
1170 found = true;
1171 }
1172 else
1173 {
1174 // try some peers around
1175 auto it1 = m_Peers.begin ();
1176 if (inds[0])
1177 {
1178 // before
1179 inds[1] %= inds[0];
1180 std::advance (it1, (inds[1] + inds[0])/2);
1181 }
1182 else
1183 it1 = it;
1184 auto it2 = it;
1185 if (inds[0] < m_Peers.size () - 1)
1186 {
1187 // after
1188 inds[2] %= (m_Peers.size () - 1 - inds[0]); inds[2] /= 2;
1189 std::advance (it2, inds[2]);
1190 }
1191 // it1 - from, it2 - to
1192 it = it1;
1193 while (it != it2 && it != m_Peers.end ())
1194 {
1195 if (ts > it->second->lastSelectionTime + PEER_SELECTION_MIN_INTERVAL &&
1196 filter (it->second))
1197 {
1198 ident = it->first;
1199 it->second->lastSelectionTime = ts;
1200 found = true;
1201 break;
1202 }
1203 it++;
1204 }
1205 if (!found)
1206 {
1207 // still not found, try from the beginning
1208 it = m_Peers.begin ();

Callers 1

StandardSelectPeersMethod · 0.80

Calls 6

GetSecondsSinceEpochFunction · 0.85
FindRouterMethod · 0.80
IsBandwidthExceededMethod · 0.80
IsConnectedMethod · 0.45
GetSendQueueSizeMethod · 0.45
IsSlowMethod · 0.45

Tested by

no test coverage detected