refactor: getPeerCandidates returns a std::vector (#2042)
Previously was a manually-malloced and freed array.
This commit is contained in:
parent
93d8a03d55
commit
775e30eefd
|
@ -68,7 +68,7 @@ static auto constexpr MaxUploadIdleSecs = int{ 60 * 5 };
|
|||
|
||||
// max number of peers to ask for per second overall.
|
||||
// this throttle is to avoid overloading the router
|
||||
static auto constexpr MaxConnectionsPerSecond = int{ 12 };
|
||||
static auto constexpr MaxConnectionsPerSecond = size_t{ 12 };
|
||||
|
||||
// number of bad pieces a peer is allowed to send before we ban them
|
||||
static auto constexpr MaxBadPiecesPerPeer = int{ 5 };
|
||||
|
@ -3632,7 +3632,7 @@ static void enforceSessionPeerLimit(tr_session* session, uint64_t now)
|
|||
}
|
||||
}
|
||||
|
||||
static void makeNewPeerConnections(tr_peerMgr* mgr, int max);
|
||||
static void makeNewPeerConnections(tr_peerMgr* mgr, size_t max);
|
||||
|
||||
static void reconnectPulse(evutil_socket_t /*fd*/, short /*what*/, void* vmgr)
|
||||
{
|
||||
|
@ -4016,36 +4016,6 @@ static uint64_t getPeerCandidateScore(tr_torrent const* tor, struct peer_atom co
|
|||
return score;
|
||||
}
|
||||
|
||||
#ifdef TR_ENABLE_ASSERTS
|
||||
|
||||
static bool checkBestScoresComeFirst(struct peer_candidate const* candidates, int n, int k)
|
||||
{
|
||||
uint64_t worstFirstScore = 0;
|
||||
int const x = std::min(n, k) - 1;
|
||||
|
||||
for (int i = 0; i < x; i++)
|
||||
{
|
||||
if (worstFirstScore < candidates[i].score)
|
||||
{
|
||||
worstFirstScore = candidates[i].score;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < x; i++)
|
||||
{
|
||||
TR_ASSERT(candidates[i].score <= worstFirstScore);
|
||||
}
|
||||
|
||||
for (int i = x + 1; i < n; i++)
|
||||
{
|
||||
TR_ASSERT(candidates[i].score >= worstFirstScore);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* TR_ENABLE_ASSERTS */
|
||||
|
||||
static bool calculateAllSeeds(tr_swarm* swarm)
|
||||
{
|
||||
int nAtoms = 0;
|
||||
|
@ -4074,7 +4044,7 @@ static bool swarmIsAllSeeds(tr_swarm* swarm)
|
|||
}
|
||||
|
||||
/** @return an array of all the atoms we might want to connect to */
|
||||
static struct peer_candidate* getPeerCandidates(tr_session* session, int* candidateCount, int max)
|
||||
static std::vector<peer_candidate> getPeerCandidates(tr_session* session, size_t max)
|
||||
{
|
||||
time_t const now = tr_time();
|
||||
uint64_t const now_msec = tr_time_msec();
|
||||
|
@ -4093,13 +4063,11 @@ static struct peer_candidate* getPeerCandidates(tr_session* session, int* candid
|
|||
/* don't start any new handshakes if we're full up */
|
||||
if (maxCandidates <= peerCount)
|
||||
{
|
||||
*candidateCount = 0;
|
||||
return nullptr;
|
||||
return {};
|
||||
}
|
||||
|
||||
/* allocate an array of candidates */
|
||||
peer_candidate* const candidates = tr_new(peer_candidate, atomCount);
|
||||
peer_candidate* walk = candidates;
|
||||
auto candidates = std::vector<peer_candidate>{};
|
||||
candidates.reserve(atomCount);
|
||||
|
||||
/* populate the candidate array */
|
||||
for (auto* tor : session->torrents)
|
||||
|
@ -4139,26 +4107,22 @@ static struct peer_candidate* getPeerCandidates(tr_session* session, int* candid
|
|||
if (isPeerCandidate(tor, atom, now))
|
||||
{
|
||||
uint8_t const salt = tr_rand_int_weak(1024);
|
||||
walk->tor = tor;
|
||||
walk->atom = atom;
|
||||
walk->score = getPeerCandidateScore(tor, atom, salt);
|
||||
++walk;
|
||||
candidates.push_back({ getPeerCandidateScore(tor, atom, salt), tor, atom });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto const n_candidates = walk - candidates;
|
||||
*candidateCount = n_candidates;
|
||||
if (n_candidates > max)
|
||||
// only keep the best `max` candidates
|
||||
if (std::size(candidates) > max)
|
||||
{
|
||||
std::partial_sort(
|
||||
candidates,
|
||||
candidates + max,
|
||||
candidates + n_candidates,
|
||||
std::begin(candidates),
|
||||
std::begin(candidates) + max,
|
||||
std::end(candidates),
|
||||
[](auto const& a, auto const& b) { return a.score < b.score; });
|
||||
candidates.resize(max);
|
||||
}
|
||||
|
||||
TR_ASSERT(checkBestScoresComeFirst(candidates, *candidateCount, max));
|
||||
return candidates;
|
||||
}
|
||||
|
||||
|
@ -4207,7 +4171,7 @@ static void initiateConnection(tr_peerMgr* mgr, tr_swarm* s, struct peer_atom* a
|
|||
atom->time = now;
|
||||
}
|
||||
|
||||
static void initiateCandidateConnection(tr_peerMgr* mgr, struct peer_candidate* c)
|
||||
static void initiateCandidateConnection(tr_peerMgr* mgr, peer_candidate& c)
|
||||
{
|
||||
#if 0
|
||||
|
||||
|
@ -4217,18 +4181,13 @@ static void initiateCandidateConnection(tr_peerMgr* mgr, struct peer_candidate*
|
|||
|
||||
#endif
|
||||
|
||||
initiateConnection(mgr, c->tor->swarm, c->atom);
|
||||
initiateConnection(mgr, c.tor->swarm, c.atom);
|
||||
}
|
||||
|
||||
static void makeNewPeerConnections(struct tr_peerMgr* mgr, int max)
|
||||
static void makeNewPeerConnections(struct tr_peerMgr* mgr, size_t max)
|
||||
{
|
||||
auto n = int{};
|
||||
struct peer_candidate* candidates = getPeerCandidates(mgr->session, &n, max);
|
||||
|
||||
for (int i = 0; i < n && i < max; ++i)
|
||||
for (auto& candidate : getPeerCandidates(mgr->session, max))
|
||||
{
|
||||
initiateCandidateConnection(mgr, &candidates[i]);
|
||||
initiateCandidateConnection(mgr, candidate);
|
||||
}
|
||||
|
||||
tr_free(candidates);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue