perf: faster tr_sessionCountQueueFreeSlots() (#1785)
The previous code had some redundant calculations, e.g. calling tr_torrentGetActivity() a couple of times per torrent, once in tr_sessionCountQueueFreeSlots() and once in tr_torrentIsStalled(). Only one call is necessary. tr_sessionCountQueueFreeSlots() used to keep iterating through all torrents even if the number of free slots had already been decremented to zero, even though further iteration does not change the zero return value :) This PR checks the return value while looping to prevent this.
This commit is contained in:
parent
a673c49bd6
commit
40868d1621
|
@ -176,14 +176,11 @@ static void allocateBandwidth(
|
|||
}
|
||||
|
||||
/* traverse & repeat for the subtree */
|
||||
if (true)
|
||||
struct tr_bandwidth** children = (struct tr_bandwidth**)tr_ptrArrayBase(&b->children);
|
||||
struct tr_bandwidth** const end = children + tr_ptrArraySize(&b->children);
|
||||
for (; children != end; ++children)
|
||||
{
|
||||
struct tr_bandwidth** children = (struct tr_bandwidth**)tr_ptrArrayBase(&b->children);
|
||||
|
||||
for (int i = 0, n = tr_ptrArraySize(&b->children); i < n; ++i)
|
||||
{
|
||||
allocateBandwidth(children[i], priority, dir, period_msec, peer_pool);
|
||||
}
|
||||
allocateBandwidth(*children, priority, dir, period_msec, peer_pool);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3096,8 +3096,6 @@ void tr_sessionGetNextQueuedTorrents(tr_session* session, tr_direction direction
|
|||
|
||||
int tr_sessionCountQueueFreeSlots(tr_session* session, tr_direction dir)
|
||||
{
|
||||
tr_torrent* tor;
|
||||
int active_count;
|
||||
int const max = tr_sessionGetQueueSize(session, dir);
|
||||
tr_torrent_activity const activity = dir == TR_UP ? TR_STATUS_SEED : TR_STATUS_DOWNLOAD;
|
||||
|
||||
|
@ -3106,20 +3104,31 @@ int tr_sessionCountQueueFreeSlots(tr_session* session, tr_direction dir)
|
|||
return INT_MAX;
|
||||
}
|
||||
|
||||
tor = NULL;
|
||||
active_count = 0;
|
||||
|
||||
/* count how many torrents are active */
|
||||
int active_count = 0;
|
||||
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 = NULL;
|
||||
while ((tor = tr_torrentNext(session, tor)) != NULL)
|
||||
{
|
||||
if (!tr_torrentIsStalled(tor) && (tr_torrentGetActivity(tor) == activity))
|
||||
{
|
||||
++active_count;
|
||||
}
|
||||
}
|
||||
/* is it the right activity? */
|
||||
if (activity != tr_torrentGetActivity(tor))
|
||||
continue;
|
||||
|
||||
if (active_count >= max)
|
||||
{
|
||||
return 0;
|
||||
/* is it stalled? */
|
||||
if (stalled_enabled)
|
||||
{
|
||||
int const idle_secs = (int)difftime(now, MAX(tor->startDate, tor->activityDate));
|
||||
if (idle_secs >= stalled_if_idle_for_n_seconds)
|
||||
continue;
|
||||
}
|
||||
|
||||
++active_count;
|
||||
|
||||
/* if we've reached the limit, no need to keep counting */
|
||||
if (active_count >= max)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return max - active_count;
|
||||
|
|
|
@ -1240,27 +1240,16 @@ tr_torrent_activity tr_torrentGetActivity(tr_torrent const* tor)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int torrentGetIdleSecs(tr_torrent const* tor)
|
||||
static int torrentGetIdleSecs(tr_torrent const* tor, tr_torrent_activity activity)
|
||||
{
|
||||
int idle_secs;
|
||||
tr_torrent_activity const activity = tr_torrentGetActivity(tor);
|
||||
|
||||
if ((activity == TR_STATUS_DOWNLOAD || activity == TR_STATUS_SEED) && tor->startDate != 0)
|
||||
{
|
||||
idle_secs = (int)difftime(tr_time(), MAX(tor->startDate, tor->activityDate));
|
||||
}
|
||||
else
|
||||
{
|
||||
idle_secs = -1;
|
||||
}
|
||||
|
||||
return idle_secs;
|
||||
return ((activity == TR_STATUS_DOWNLOAD || activity == TR_STATUS_SEED) && tor->startDate != 0) ?
|
||||
(int)difftime(tr_time(), MAX(tor->startDate, tor->activityDate)) :
|
||||
-1;
|
||||
}
|
||||
|
||||
bool tr_torrentIsStalled(tr_torrent const* tor)
|
||||
static inline bool tr_torrentIsStalled(tr_torrent const* tor, int idle_secs)
|
||||
{
|
||||
return tr_sessionGetQueueStalledEnabled(tor->session) &&
|
||||
torrentGetIdleSecs(tor) > tr_sessionGetQueueStalledMinutes(tor->session) * 60;
|
||||
return tr_sessionGetQueueStalledEnabled(tor->session) && idle_secs > tr_sessionGetQueueStalledMinutes(tor->session) * 60;
|
||||
}
|
||||
|
||||
static double getVerifyProgress(tr_torrent const* tor)
|
||||
|
@ -1316,7 +1305,8 @@ tr_stat const* tr_torrentStat(tr_torrent* tor)
|
|||
s->activity = tr_torrentGetActivity(tor);
|
||||
s->error = tor->error;
|
||||
s->queuePosition = tor->queuePosition;
|
||||
s->isStalled = tr_torrentIsStalled(tor);
|
||||
s->idleSecs = torrentGetIdleSecs(tor, s->activity);
|
||||
s->isStalled = tr_torrentIsStalled(tor, s->idleSecs);
|
||||
tr_strlcpy(s->errorString, tor->errorString, sizeof(s->errorString));
|
||||
|
||||
s->manualAnnounceTime = tr_announcerNextManualAnnounce(tor);
|
||||
|
@ -1351,7 +1341,6 @@ tr_stat const* tr_torrentStat(tr_torrent* tor)
|
|||
s->startDate = tor->startDate;
|
||||
s->secondsSeeding = tor->secondsSeeding;
|
||||
s->secondsDownloading = tor->secondsDownloading;
|
||||
s->idleSecs = torrentGetIdleSecs(tor);
|
||||
|
||||
s->corruptEver = tor->corruptCur + tor->corruptPrev;
|
||||
s->downloadedEver = tor->downloadedCur + tor->downloadedPrev;
|
||||
|
|
|
@ -425,8 +425,6 @@ time_t tr_torrentGetFileMTime(tr_torrent const* tor, tr_file_index_t i);
|
|||
|
||||
uint64_t tr_torrentGetCurrentSizeOnDisk(tr_torrent const* tor);
|
||||
|
||||
bool tr_torrentIsStalled(tr_torrent const* tor);
|
||||
|
||||
unsigned char const* tr_torrentGetPeerId(tr_torrent* tor);
|
||||
|
||||
static inline uint64_t tr_torrentGetLeftUntilDone(tr_torrent const* tor)
|
||||
|
|
Loading…
Reference in New Issue