refactor: use std container for session torrents (#1832)

* refactor: use std container for session's torrents
This commit is contained in:
Charles Kerr 2021-09-24 18:31:02 -05:00 committed by GitHub
parent 6c77fa92ce
commit b92c609ed9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 125 additions and 251 deletions

View File

@ -1713,8 +1713,7 @@ static void scrapeAndAnnounceMore(tr_announcer* announcer)
/* build a list of tiers that need to be announced */
auto announce_me = std::vector<tr_tier*>{};
auto scrape_me = std::vector<tr_tier*>{};
tr_torrent* tor = nullptr;
while ((tor = tr_torrentNext(announcer->session, tor)) != nullptr)
for (auto* tor : announcer->session->torrents)
{
struct tr_torrent_tiers* tt = tor->tiers;

View File

@ -553,12 +553,9 @@ void tr_peerMgrFree(tr_peerMgr* manager)
void tr_peerMgrOnBlocklistChanged(tr_peerMgr* mgr)
{
tr_torrent* tor = nullptr;
tr_session* session = mgr->session;
/* we cache whether or not a peer is blocklisted...
since the blocklist has changed, erase that cached value */
while ((tor = tr_torrentNext(session, tor)) != nullptr)
for (auto* tor : mgr->session->torrents)
{
tr_swarm* s = tor->swarm;
@ -1490,7 +1487,6 @@ static void refillUpkeep(evutil_socket_t fd, short what, void* vmgr)
time_t now;
time_t too_old;
tr_torrent* tor;
int cancel_buflen = 0;
struct block_request* cancel = nullptr;
auto* mgr = static_cast<tr_peerMgr*>(vmgr);
@ -1500,9 +1496,7 @@ static void refillUpkeep(evutil_socket_t fd, short what, void* vmgr)
too_old = now - REQUEST_TTL_SECS;
/* alloc the temporary "cancel" buffer */
tor = nullptr;
while ((tor = tr_torrentNext(mgr->session, tor)) != nullptr)
for (auto const* tor : mgr->session->torrents)
{
cancel_buflen = std::max(cancel_buflen, tor->swarm->requestCount);
}
@ -1513,9 +1507,7 @@ static void refillUpkeep(evutil_socket_t fd, short what, void* vmgr)
}
/* prune requests that are too old */
tor = nullptr;
while ((tor = tr_torrentNext(mgr->session, tor)) != nullptr)
for (auto* tor : mgr->session->torrents)
{
tr_swarm* s = tor->swarm;
int const n = s->requestCount;
@ -3378,13 +3370,12 @@ static void rechokePulse(evutil_socket_t fd, short what, void* vmgr)
TR_UNUSED(fd);
TR_UNUSED(what);
tr_torrent* tor = nullptr;
auto* mgr = static_cast<tr_peerMgr*>(vmgr);
uint64_t const now = tr_time_msec();
managerLock(mgr);
while ((tor = tr_torrentNext(mgr->session, tor)) != nullptr)
for (auto* tor : mgr->session->torrents)
{
if (tor->isRunning)
{
@ -3720,17 +3711,15 @@ static void enforceTorrentPeerLimit(tr_swarm* s, uint64_t now)
static void enforceSessionPeerLimit(tr_session* session, uint64_t now)
{
int n = 0;
tr_torrent* tor = nullptr;
int const max = tr_sessionGetPeerLimit(session);
/* count the total number of peers */
while ((tor = tr_torrentNext(session, tor)) != nullptr)
int n = 0;
for (auto const* tor : session->torrents)
{
n += tr_ptrArraySize(&tor->swarm->peers);
}
/* if there are too many, prune out the worst */
int const max = tr_sessionGetPeerLimit(session);
if (n > max)
{
tr_peer** peers = tr_new(tr_peer*, n);
@ -3738,9 +3727,7 @@ static void enforceSessionPeerLimit(tr_session* session, uint64_t now)
/* populate the peer array */
n = 0;
tor = nullptr;
while ((tor = tr_torrentNext(session, tor)) != nullptr)
for (auto* tor : session->torrents)
{
tr_swarm* s = tor->swarm;
@ -3774,7 +3761,6 @@ static void reconnectPulse(evutil_socket_t fd, short what, void* vmgr)
TR_UNUSED(fd);
TR_UNUSED(what);
tr_torrent* tor;
auto* mgr = static_cast<tr_peerMgr*>(vmgr);
time_t const now_sec = tr_time();
uint64_t const now_msec = tr_time_msec();
@ -3784,9 +3770,7 @@ static void reconnectPulse(evutil_socket_t fd, short what, void* vmgr)
**/
/* if we're over the per-torrent peer limits, cull some peers */
tor = nullptr;
while ((tor = tr_torrentNext(mgr->session, tor)) != nullptr)
for (auto* tor : mgr->session->torrents)
{
if (tor->isRunning)
{
@ -3798,9 +3782,7 @@ static void reconnectPulse(evutil_socket_t fd, short what, void* vmgr)
enforceSessionPeerLimit(mgr->session, now_msec);
/* remove crappy peers */
tor = nullptr;
while ((tor = tr_torrentNext(mgr->session, tor)) != nullptr)
for (auto* tor : mgr->session->torrents)
{
if (!tor->swarm->isRunning)
{
@ -3825,9 +3807,7 @@ static void reconnectPulse(evutil_socket_t fd, short what, void* vmgr)
static void pumpAllPeers(tr_peerMgr* mgr)
{
tr_torrent* tor = nullptr;
while ((tor = tr_torrentNext(mgr->session, tor)) != nullptr)
for (auto* tor : mgr->session->torrents)
{
tr_swarm* s = tor->swarm;
@ -3883,8 +3863,7 @@ static void bandwidthPulse(evutil_socket_t fd, short what, void* vmgr)
tr_bandwidthAllocate(&session->bandwidth, TR_DOWN, BANDWIDTH_PERIOD_MSEC);
/* torrent upkeep */
tr_torrent* tor = nullptr;
while ((tor = tr_torrentNext(session, tor)) != nullptr)
for (auto* tor : session->torrents)
{
/* possibly stop torrents that have seeded enough */
tr_torrentCheckSeedLimit(tor);
@ -3986,8 +3965,7 @@ static void atomPulse(evutil_socket_t fd, short what, void* vmgr)
auto* mgr = static_cast<tr_peerMgr*>(vmgr);
managerLock(mgr);
tr_torrent* tor = nullptr;
while ((tor = tr_torrentNext(mgr->session, tor)) != nullptr)
for (auto* tor : mgr->session->torrents)
{
int atomCount;
tr_swarm* s = tor->swarm;
@ -4237,9 +4215,6 @@ static bool swarmIsAllSeeds(struct 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)
{
int atomCount;
int peerCount;
tr_torrent* tor;
struct peer_candidate* candidates;
struct peer_candidate* walk;
time_t const now = tr_time();
@ -4248,11 +4223,9 @@ static struct peer_candidate* getPeerCandidates(tr_session* session, int* candid
int const maxCandidates = tr_sessionGetPeerLimit(session) * 0.95;
/* count how many peers and atoms we've got */
tor = nullptr;
atomCount = 0;
peerCount = 0;
while ((tor = tr_torrentNext(session, tor)) != nullptr)
int atomCount = 0;
int peerCount = 0;
for (auto const* tor : session->torrents)
{
atomCount += tr_ptrArraySize(&tor->swarm->pool);
peerCount += tr_ptrArraySize(&tor->swarm->peers);
@ -4269,9 +4242,7 @@ static struct peer_candidate* getPeerCandidates(tr_session* session, int* candid
walk = candidates = tr_new(struct peer_candidate, atomCount);
/* populate the candidate array */
tor = nullptr;
while ((tor = tr_torrentNext(session, tor)) != nullptr)
for (auto* tor : session->torrents)
{
int nAtoms;
struct peer_atom** atoms;

View File

@ -6,14 +6,17 @@
*
*/
#include <cstdlib>
#include <cstring>
#include <map>
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 600 /* needed for recursive locks. */
#endif
#ifndef __USE_UNIX98
#define __USE_UNIX98 /* some older Linuxes need it spelt out for them */
#endif
#include <stdlib.h>
#include <string.h>
#ifdef __HAIKU__
#include <limits.h> /* PATH_MAX */
#endif

View File

@ -160,13 +160,12 @@ static tr_torrent** getTorrents(tr_session* session, tr_variant* args, int* setm
{
if (strcmp(str, "recently-active") == 0)
{
tr_torrent* tor = nullptr;
time_t const now = tr_time();
time_t const window = RECENTLY_ACTIVE_SECONDS;
int const n = tr_sessionCountTorrents(session);
torrents = tr_new0(tr_torrent*, n);
while ((tor = tr_torrentNext(session, tor)) != nullptr)
for (auto* tor : session->torrents)
{
if (tor->anyDate >= now - window)
{
@ -187,7 +186,11 @@ static tr_torrent** getTorrents(tr_session* session, tr_variant* args, int* setm
}
else /* all of them */
{
torrents = tr_sessionGetTorrents(session, &torrentCount);
// TODO: getTorrents() should return a std::vector<tr_torrent*>
auto tmp = tr_sessionGetTorrents(session);
torrentCount = std::size(tmp);
torrents = tr_new(tr_torrent*, torrentCount);
std::copy_n(std::begin(tmp), torrentCount, torrents);
}
*setmeCount = torrentCount;
@ -2382,21 +2385,14 @@ static char const* sessionStats(
TR_ASSERT(idle_data == nullptr);
int running = 0;
int total = 0;
auto currentStats = tr_session_stats{};
auto cumulativeStats = tr_session_stats{};
tr_torrent* tor = nullptr;
while ((tor = tr_torrentNext(session, tor)) != nullptr)
{
++total;
if (tor->isRunning)
{
++running;
}
}
int const total = std::size(session->torrents);
int const running = std::count_if(
std::begin(session->torrents),
std::end(session->torrents),
[](auto const* tor) { return tor->isRunning; });
tr_sessionGetStats(session, &currentStats);
tr_sessionGetCumulativeStats(session, &cumulativeStats);

View File

@ -586,7 +586,6 @@ static void onSaveTimer(evutil_socket_t fd, short what, void* vsession)
TR_UNUSED(fd);
TR_UNUSED(what);
tr_torrent* tor = nullptr;
auto* session = static_cast<tr_session*>(vsession);
if (tr_cacheFlushDone(session->cache) != 0)
@ -594,7 +593,7 @@ static void onSaveTimer(evutil_socket_t fd, short what, void* vsession)
tr_logAddError("Error while flushing completed pieces from cache");
}
while ((tor = tr_torrentNext(session, tor)) != nullptr)
for (auto* tor : session->torrents)
{
tr_torrentSave(tor);
}
@ -624,22 +623,18 @@ tr_session* tr_sessionInit(char const* configDir, bool messageQueuingEnabled, tr
TR_ASSERT(tr_variantIsDict(clientSettings));
int64_t i;
tr_session* session;
struct init_data data;
tr_timeUpdate(time(nullptr));
/* initialize the bare skeleton of the session object */
session = tr_new0(tr_session, 1);
auto* session = new tr_session{};
session->udp_socket = TR_BAD_SOCKET;
session->udp6_socket = TR_BAD_SOCKET;
session->lock = tr_lockNew();
session->cache = tr_cacheNew(1024 * 1024 * 2);
session->magicNumber = SESSION_MAGIC_NUMBER;
session->session_id = tr_session_id_new();
session->torrentsSortedByHash = {};
session->torrentsSortedByHashString = {};
session->torrentsSortedById = {};
tr_bandwidthConstruct(&session->bandwidth, session, nullptr);
tr_variantInitList(&session->removedTorrents, 0);
@ -686,7 +681,6 @@ static void onNowTimer(evutil_socket_t fd, short what, void* vsession)
int const min = 100;
int const max = 999999;
struct timeval tv;
tr_torrent* tor = nullptr;
time_t const now = time(nullptr);
/**
@ -702,7 +696,10 @@ static void onNowTimer(evutil_socket_t fd, short what, void* vsession)
turtleCheckClock(session, &session->turtle);
}
while ((tor = tr_torrentNext(session, tor)) != nullptr)
// TODO: this seems a little silly. Why do we increment this
// every second instead of computing the value as needed by
// subtracting the current time from a start time?
for (auto* tor : session->torrents)
{
if (tor->isRunning)
{
@ -1325,13 +1322,11 @@ static void peerPortChanged(void* vsession)
auto* session = static_cast<tr_session*>(vsession);
TR_ASSERT(tr_isSession(session));
tr_torrent* tor = nullptr;
close_incoming_peer_port(session);
open_incoming_peer_port(session);
tr_sharedPortChanged(session);
while ((tor = tr_torrentNext(session, tor)) != nullptr)
for (auto* tor : session->torrents)
{
tr_torrentChangeMyPort(tor);
}
@ -1908,52 +1903,26 @@ double tr_sessionGetRawSpeed_KBps(tr_session const* session, tr_direction dir)
int tr_sessionCountTorrents(tr_session const* session)
{
return tr_isSession(session) ? session->torrentCount : 0;
return tr_isSession(session) ? std::size(session->torrents) : 0;
}
tr_torrent** tr_sessionGetTorrents(tr_session* session, int* setme_n)
std::vector<tr_torrent*> tr_sessionGetTorrents(tr_session* session)
{
TR_ASSERT(tr_isSession(session));
TR_ASSERT(setme_n != nullptr);
int n = tr_sessionCountTorrents(session);
*setme_n = n;
tr_torrent** torrents = tr_new(tr_torrent*, n);
tr_torrent* tor = nullptr;
for (int i = 0; i < n; ++i)
{
torrents[i] = tor = tr_torrentNext(session, tor);
}
auto const& src = session->torrents;
auto const n = std::size(src);
auto torrents = std::vector<tr_torrent*>{ n };
std::copy(std::begin(src), std::end(src), std::begin(torrents));
return torrents;
}
static int compareTorrentByCur(void const* va, void const* vb)
{
tr_torrent const* a = *(tr_torrent const* const*)va;
tr_torrent const* b = *(tr_torrent const* const*)vb;
uint64_t const aCur = a->downloadedCur + a->uploadedCur;
uint64_t const bCur = b->downloadedCur + b->uploadedCur;
if (aCur != bCur)
{
return aCur > bCur ? -1 : 1; /* close the biggest torrents first */
}
return 0;
}
static void closeBlocklists(tr_session*);
static void sessionCloseImplWaitForIdleUdp(evutil_socket_t fd, short what, void* vsession);
static void sessionCloseImplStart(tr_session* session)
{
int n;
tr_torrent** torrents;
session->isClosing = true;
free_incoming_peer_port(session);
@ -1979,15 +1948,23 @@ static void sessionCloseImplStart(tr_session* session)
/* Close the torrents. Get the most active ones first so that
* if we can't get them all closed in a reasonable amount of time,
* at least we get the most important ones first. */
torrents = tr_sessionGetTorrents(session, &n);
qsort(torrents, n, sizeof(tr_torrent*), compareTorrentByCur);
auto torrents = tr_sessionGetTorrents(session);
std::sort(
std::begin(torrents),
std::end(torrents),
[](auto const* a, auto const* b)
{
auto const aCur = a->downloadedCur + a->uploadedCur;
auto const bCur = b->downloadedCur + b->uploadedCur;
return aCur > bCur; // larger xfers go first
});
for (int i = 0; i < n; ++i)
for (auto* tor : torrents)
{
tr_torrentFree(torrents[i]);
tr_torrentFree(tor);
}
tr_free(torrents);
torrents.clear();
/* Close the announcer *after* closing the torrents
so that all the &event=stopped messages will be
@ -2144,9 +2121,6 @@ void tr_sessionClose(tr_session* session)
}
tr_device_info_free(session->downloadDir);
tr_ptrArrayDestruct(&session->torrentsSortedByHash, nullptr);
tr_ptrArrayDestruct(&session->torrentsSortedByHashString, nullptr);
tr_ptrArrayDestruct(&session->torrentsSortedById, nullptr);
tr_free(session->torrentDoneScript);
tr_free(session->configDir);
tr_free(session->resumeDir);
@ -2154,7 +2128,7 @@ void tr_sessionClose(tr_session* session)
tr_free(session->incompleteDir);
tr_free(session->blocklist_url);
tr_free(session->peer_congestion_algorithm);
tr_free(session);
delete session;
}
struct sessionLoadTorrentsData
@ -3026,8 +3000,7 @@ void tr_sessionGetNextQueuedTorrents(tr_session* session, tr_direction direction
// build an array of the candidates
auto candidates = std::vector<tr_torrent*>{};
candidates.reserve(tr_sessionCountTorrents(session));
tr_torrent* tor = nullptr;
while ((tor = tr_torrentNext(session, tor)) != nullptr)
for (auto* tor : session->torrents)
{
if (tr_torrentIsQueued(tor) && (direction == tr_torrentGetQueueDirection(tor)))
{
@ -3069,8 +3042,7 @@ int tr_sessionCountQueueFreeSlots(tr_session* session, tr_direction dir)
bool const stalled_enabled = tr_sessionGetQueueStalledEnabled(session);
int const stalled_if_idle_for_n_seconds = tr_sessionGetQueueStalledMinutes(session) * 60;
time_t const now = tr_time();
tr_torrent* tor = nullptr;
while ((tor = tr_torrentNext(session, tor)) != nullptr)
for (auto const* tor : session->torrents)
{
/* is it the right activity? */
if (activity != tr_torrentGetActivity(tor))
@ -3098,67 +3070,18 @@ int tr_sessionCountQueueFreeSlots(tr_session* session, tr_direction dir)
return max - active_count;
}
static int compareTorrentsById(void const* va, void const* vb)
{
auto const* const a = static_cast<tr_torrent const*>(va);
auto const* const b = static_cast<tr_torrent const*>(vb);
return a->uniqueId - b->uniqueId;
}
static int compareTorrentsByHashString(void const* va, void const* vb)
{
auto const* const a = static_cast<tr_torrent const*>(va);
auto const* const b = static_cast<tr_torrent const*>(vb);
return evutil_ascii_strcasecmp(a->info.hashString, b->info.hashString);
}
static int compareTorrentsByHash(void const* va, void const* vb)
{
auto const* const a = static_cast<tr_torrent const*>(va);
auto const* const b = static_cast<tr_torrent const*>(vb);
return memcmp(a->info.hash, b->info.hash, SHA_DIGEST_LENGTH);
}
void tr_sessionAddTorrent(tr_session* session, tr_torrent* tor)
{
/* add tor to tr_session.torrentList */
tor->next = session->torrentList;
session->torrentList = tor;
/* add tor to tr_session.torrentsSortedByFoo */
tr_ptrArrayInsertSorted(&session->torrentsSortedById, tor, compareTorrentsById);
tr_ptrArrayInsertSorted(&session->torrentsSortedByHashString, tor, compareTorrentsByHashString);
tr_ptrArrayInsertSorted(&session->torrentsSortedByHash, tor, compareTorrentsByHash);
/* increment the torrent count */
++session->torrentCount;
session->torrents.insert(tor);
session->torrentsById.insert_or_assign(tor->uniqueId, tor);
session->torrentsByHash.insert_or_assign(tor->info.hash, tor);
session->torrentsByHashString.insert_or_assign(tor->info.hashString, tor);
}
void tr_sessionRemoveTorrent(tr_session* session, tr_torrent* tor)
{
/* remove tor from tr_session.torrentList */
if (tor == session->torrentList)
{
session->torrentList = tor->next;
}
else
{
for (tr_torrent* t = session->torrentList; t != nullptr; t = t->next)
{
if (t->next == tor)
{
t->next = tor->next;
break;
}
}
}
/* remove tor from tr_session.torrentsSortedByFoo */
tr_ptrArrayRemoveSortedPointer(&session->torrentsSortedById, tor, compareTorrentsById);
tr_ptrArrayRemoveSortedPointer(&session->torrentsSortedByHashString, tor, compareTorrentsByHashString);
tr_ptrArrayRemoveSortedPointer(&session->torrentsSortedByHash, tor, compareTorrentsByHash);
/* decrement the torrent count */
TR_ASSERT(session->torrentCount >= 1);
session->torrentCount--;
session->torrents.erase(tor);
session->torrentsById.erase(tor->uniqueId);
session->torrentsByHash.erase(tor->info.hash);
session->torrentsByHashString.erase(tor->info.hashString);
}

View File

@ -14,6 +14,13 @@
#define TR_NAME "Transmission"
#include <cstring> // memcmp()
#include <map>
#include <unordered_set>
#include <vector>
#include <event2/util.h> // evutil_ascii_strcasecmp()
#include "bandwidth.h"
#include "bitfield.h"
#include "net.h"
@ -22,8 +29,6 @@
#include "utils.h"
#include "variant.h"
TR_BEGIN_DECLS
typedef enum
{
TR_NET_OK,
@ -95,6 +100,22 @@ struct tr_turtle_info
tr_auto_switch_state_t autoTurtleState;
};
struct CompareHash
{
bool operator()(uint8_t const* const a, uint8_t const* const b) const
{
return std::memcmp(a, b, SHA_DIGEST_LENGTH) < 0;
}
};
struct CompareHashString
{
bool operator()(char const* const a, char const* const b) const
{
return evutil_ascii_strcasecmp(a, b) < 0;
}
};
/** @brief handle to an active libtransmission session */
struct tr_session
{
@ -176,11 +197,10 @@ struct tr_session
int peerSocketTOS;
char* peer_congestion_algorithm;
int torrentCount;
tr_torrent* torrentList;
tr_ptrArray torrentsSortedByHash;
tr_ptrArray torrentsSortedByHashString;
tr_ptrArray torrentsSortedById;
std::unordered_set<tr_torrent*> torrents;
std::map<int, tr_torrent*> torrentsById;
std::map<uint8_t const*, tr_torrent*, CompareHash> torrentsByHash;
std::map<char const*, tr_torrent*, CompareHashString> torrentsByHashString;
char* torrentDoneScript;
@ -256,7 +276,7 @@ struct tr_bindsockets* tr_sessionGetBindSockets(tr_session*);
int tr_sessionCountTorrents(tr_session const* session);
tr_torrent** tr_sessionGetTorrents(tr_session* session, int* setme_n);
std::vector<tr_torrent*> tr_sessionGetTorrents(tr_session* session);
enum
{
@ -328,5 +348,3 @@ int tr_sessionCountQueueFreeSlots(tr_session* session, tr_direction);
void tr_sessionAddTorrent(tr_session* session, tr_torrent* tor);
void tr_sessionRemoveTorrent(tr_session* session, tr_torrent* tor);
TR_END_DECLS

View File

@ -73,42 +73,25 @@ int tr_torrentId(tr_torrent const* tor)
return tor != nullptr ? tor->uniqueId : -1;
}
static int compareKeyToTorrentId(void const* va, void const* vb)
{
auto const* const a = static_cast<tr_torrent const*>(va);
auto const b = *static_cast<int const*>(vb);
return a->uniqueId - b;
}
tr_torrent* tr_torrentFindFromId(tr_session* session, int id)
{
return static_cast<tr_torrent*>(tr_ptrArrayFindSorted(&session->torrentsSortedById, &id, compareKeyToTorrentId));
auto& src = session->torrentsById;
auto it = src.find(id);
return it == std::end(src) ? nullptr : it->second;
}
static int compareKeyToTorrentHashString(void const* va, void const* vb)
tr_torrent* tr_torrentFindFromHashString(tr_session* session, char const* hashstr)
{
auto const* const a = static_cast<tr_torrent const*>(va);
auto const* const b = static_cast<char const*>(vb);
return evutil_ascii_strcasecmp(a->info.hashString, b);
auto& src = session->torrentsByHashString;
auto it = src.find(hashstr);
return it == std::end(src) ? nullptr : it->second;
}
tr_torrent* tr_torrentFindFromHashString(tr_session* session, char const* str)
tr_torrent* tr_torrentFindFromHash(tr_session* session, uint8_t const* hash)
{
return static_cast<tr_torrent*>(
tr_ptrArrayFindSorted(&session->torrentsSortedByHashString, str, compareKeyToTorrentHashString));
}
static int compareKeyToTorrentHash(void const* va, void const* vb)
{
auto const* const a = static_cast<tr_torrent const*>(va);
auto const* const b = static_cast<uint8_t const*>(vb);
return memcmp(a->info.hash, b, SHA_DIGEST_LENGTH);
}
tr_torrent* tr_torrentFindFromHash(tr_session* session, uint8_t const* torrentHash)
{
return static_cast<tr_torrent*>(
tr_ptrArrayFindSorted(&session->torrentsSortedByHash, torrentHash, compareKeyToTorrentHash));
auto& src = session->torrentsByHash;
auto it = src.find(hash);
return it == std::end(src) ? nullptr : it->second;
}
tr_torrent* tr_torrentFindFromMagnetLink(tr_session* session, char const* magnet)
@ -127,9 +110,7 @@ tr_torrent* tr_torrentFindFromMagnetLink(tr_session* session, char const* magnet
tr_torrent* tr_torrentFindFromObfuscatedHash(tr_session* session, uint8_t const* obfuscatedTorrentHash)
{
tr_torrent* tor = nullptr;
while ((tor = tr_torrentNext(session, tor)) != nullptr)
for (auto* tor : session->torrents)
{
if (memcmp(tor->obfuscatedHash, obfuscatedTorrentHash, SHA_DIGEST_LENGTH) == 0)
{
@ -883,7 +864,7 @@ static void torrentInit(tr_torrent* tor, tr_ctor const* ctor)
tor->session = session;
tor->uniqueId = nextUniqueId++;
tor->magicNumber = TORRENT_MAGIC_NUMBER;
tor->queuePosition = session->torrentCount;
tor->queuePosition = tr_sessionCountTorrents(session);
tor->labels = {};
tr_sha1(tor->obfuscatedHash, "req2", 4, tor->info.hash, SHA_DIGEST_LENGTH, nullptr);
@ -1644,9 +1625,7 @@ static void freeTorrent(tr_torrent* tor)
tr_sessionRemoveTorrent(session, tor);
/* resequence the queue positions */
tr_torrent* t = nullptr;
while ((t = tr_torrentNext(session, t)) != nullptr)
for (auto* t : session->torrents)
{
if (t->queuePosition > tor->queuePosition)
{
@ -3599,13 +3578,11 @@ static int compareTorrentByQueuePosition(void const* va, void const* vb)
static bool queueIsSequenced(tr_session* session)
{
int n;
bool is_sequenced;
tr_torrent** torrents;
n = 0;
torrents = tr_sessionGetTorrents(session, &n);
qsort(torrents, n, sizeof(tr_torrent*), compareTorrentByQueuePosition);
auto torrents = tr_sessionGetTorrents(session);
std::sort(
std::begin(torrents),
std::end(torrents),
[](auto const* a, auto const* b) { return a->queuePosition < b->queuePosition; });
#if 0
@ -3621,14 +3598,13 @@ static bool queueIsSequenced(tr_session* session)
#endif
/* test them */
is_sequenced = true;
bool is_sequenced = true;
for (int i = 0; is_sequenced && i < n; ++i)
for (int i = 0, n = std::size(torrents); is_sequenced && i < n; ++i)
{
is_sequenced = torrents[i]->queuePosition == i;
}
tr_free(torrents);
return is_sequenced;
}
@ -3642,7 +3618,6 @@ int tr_torrentGetQueuePosition(tr_torrent const* tor)
void tr_torrentSetQueuePosition(tr_torrent* tor, int pos)
{
int back = -1;
tr_torrent* walk;
int const old_pos = tor->queuePosition;
time_t const now = tr_time();
@ -3653,9 +3628,7 @@ void tr_torrentSetQueuePosition(tr_torrent* tor, int pos)
tor->queuePosition = -1;
walk = nullptr;
while ((walk = tr_torrentNext(tor->session, walk)) != nullptr)
for (auto* walk : tor->session->torrents)
{
if ((old_pos < pos) && (old_pos <= walk->queuePosition) && (walk->queuePosition <= pos))
{

View File

@ -253,8 +253,6 @@ struct tr_torrent
time_t lastStatTime;
tr_stat stats;
tr_torrent* next;
int uniqueId;
struct tr_bandwidth bandwidth;
@ -271,11 +269,6 @@ struct tr_torrent
tr_ptrArray labels;
};
static inline tr_torrent* tr_torrentNext(tr_session* session, tr_torrent* current)
{
return current != nullptr ? current->next : session->torrentList;
}
/* what piece index is this block in? */
static inline tr_piece_index_t tr_torBlockPiece(tr_torrent const* tor, tr_block_index_t const block)
{

View File

@ -768,10 +768,9 @@ static int tr_dhtAnnounce(tr_torrent* tor, int af, bool announce)
void tr_dhtUpkeep(tr_session* session)
{
tr_torrent* tor = nullptr;
time_t const now = tr_time();
while ((tor = tr_torrentNext(session, tor)) != nullptr)
for (auto* tor : session->torrents)
{
if (!tor->isRunning || !tr_torrentAllowsDHT(tor))
{

View File

@ -618,7 +618,6 @@ static int tr_lpdConsiderAnnounce(tr_pex* peer, char const* const msg)
*/
static int tr_lpdAnnounceMore(time_t const now, int const interval)
{
tr_torrent* tor = nullptr;
int announcesSent = 0;
if (!tr_isSession(session))
@ -626,9 +625,9 @@ static int tr_lpdAnnounceMore(time_t const now, int const interval)
return -1;
}
while ((tor = tr_torrentNext(session, tor)) != nullptr && tr_sessionAllowsLPD(session))
if (tr_sessionAllowsLPD(session))
{
if (tr_isTorrent(tor))
for (auto* tor : session->torrents)
{
int announcePrio = 0;