mirror of
https://github.com/transmission/transmission.git
synced 2025-12-20 02:18:42 +00:00
refactor: getPeerCandidates returns a std::vector (#2042)
Previously was a manually-malloced and freed array.
This commit is contained in:
@@ -68,7 +68,7 @@ static auto constexpr MaxUploadIdleSecs = int{ 60 * 5 };
|
|||||||
|
|
||||||
// max number of peers to ask for per second overall.
|
// max number of peers to ask for per second overall.
|
||||||
// this throttle is to avoid overloading the router
|
// 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
|
// number of bad pieces a peer is allowed to send before we ban them
|
||||||
static auto constexpr MaxBadPiecesPerPeer = int{ 5 };
|
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)
|
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;
|
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)
|
static bool calculateAllSeeds(tr_swarm* swarm)
|
||||||
{
|
{
|
||||||
int nAtoms = 0;
|
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 */
|
/** @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();
|
time_t const now = tr_time();
|
||||||
uint64_t const now_msec = tr_time_msec();
|
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 */
|
/* don't start any new handshakes if we're full up */
|
||||||
if (maxCandidates <= peerCount)
|
if (maxCandidates <= peerCount)
|
||||||
{
|
{
|
||||||
*candidateCount = 0;
|
return {};
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allocate an array of candidates */
|
auto candidates = std::vector<peer_candidate>{};
|
||||||
peer_candidate* const candidates = tr_new(peer_candidate, atomCount);
|
candidates.reserve(atomCount);
|
||||||
peer_candidate* walk = candidates;
|
|
||||||
|
|
||||||
/* populate the candidate array */
|
/* populate the candidate array */
|
||||||
for (auto* tor : session->torrents)
|
for (auto* tor : session->torrents)
|
||||||
@@ -4139,26 +4107,22 @@ static struct peer_candidate* getPeerCandidates(tr_session* session, int* candid
|
|||||||
if (isPeerCandidate(tor, atom, now))
|
if (isPeerCandidate(tor, atom, now))
|
||||||
{
|
{
|
||||||
uint8_t const salt = tr_rand_int_weak(1024);
|
uint8_t const salt = tr_rand_int_weak(1024);
|
||||||
walk->tor = tor;
|
candidates.push_back({ getPeerCandidateScore(tor, atom, salt), tor, atom });
|
||||||
walk->atom = atom;
|
|
||||||
walk->score = getPeerCandidateScore(tor, atom, salt);
|
|
||||||
++walk;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto const n_candidates = walk - candidates;
|
// only keep the best `max` candidates
|
||||||
*candidateCount = n_candidates;
|
if (std::size(candidates) > max)
|
||||||
if (n_candidates > max)
|
|
||||||
{
|
{
|
||||||
std::partial_sort(
|
std::partial_sort(
|
||||||
candidates,
|
std::begin(candidates),
|
||||||
candidates + max,
|
std::begin(candidates) + max,
|
||||||
candidates + n_candidates,
|
std::end(candidates),
|
||||||
[](auto const& a, auto const& b) { return a.score < b.score; });
|
[](auto const& a, auto const& b) { return a.score < b.score; });
|
||||||
|
candidates.resize(max);
|
||||||
}
|
}
|
||||||
|
|
||||||
TR_ASSERT(checkBestScoresComeFirst(candidates, *candidateCount, max));
|
|
||||||
return candidates;
|
return candidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4207,7 +4171,7 @@ static void initiateConnection(tr_peerMgr* mgr, tr_swarm* s, struct peer_atom* a
|
|||||||
atom->time = now;
|
atom->time = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initiateCandidateConnection(tr_peerMgr* mgr, struct peer_candidate* c)
|
static void initiateCandidateConnection(tr_peerMgr* mgr, peer_candidate& c)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
|
|
||||||
@@ -4217,18 +4181,13 @@ static void initiateCandidateConnection(tr_peerMgr* mgr, struct peer_candidate*
|
|||||||
|
|
||||||
#endif
|
#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{};
|
for (auto& candidate : getPeerCandidates(mgr->session, max))
|
||||||
struct peer_candidate* candidates = getPeerCandidates(mgr->session, &n, max);
|
|
||||||
|
|
||||||
for (int i = 0; i < n && i < max; ++i)
|
|
||||||
{
|
{
|
||||||
initiateCandidateConnection(mgr, &candidates[i]);
|
initiateCandidateConnection(mgr, candidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
tr_free(candidates);
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user