1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2024-12-28 02:27:41 +00:00

refactor: use std::set in verify.cc's verifyList (#1848)

* refactor: use std::set in verify.cc
This commit is contained in:
Charles Kerr 2021-09-27 17:07:58 -05:00 committed by GitHub
parent 2554adba9c
commit 16a70e57d2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -9,12 +9,12 @@
#include <algorithm> #include <algorithm>
#include <cstdlib> /* free() */ #include <cstdlib> /* free() */
#include <cstring> /* memcmp() */ #include <cstring> /* memcmp() */
#include <set>
#include "transmission.h" #include "transmission.h"
#include "completion.h" #include "completion.h"
#include "crypto-utils.h" #include "crypto-utils.h"
#include "file.h" #include "file.h"
#include "list.h"
#include "log.h" #include "log.h"
#include "platform.h" /* tr_lock() */ #include "platform.h" /* tr_lock() */
#include "torrent.h" #include "torrent.h"
@ -177,10 +177,35 @@ struct verify_node
tr_verify_done_func callback_func; tr_verify_done_func callback_func;
void* callback_data; void* callback_data;
uint64_t current_size; uint64_t current_size;
int compare(verify_node const& that) const
{
// higher priority comes before lower priority
auto const pa = tr_torrentGetPriority(torrent);
auto const pb = tr_torrentGetPriority(that.torrent);
if (pa != pb)
{
return pa > pb ? -1 : 1;
}
// smaller torrents come before larger ones because they verify faster
if (current_size != that.current_size)
{
return current_size < that.current_size ? -1 : 1;
}
return 0;
}
bool operator<(verify_node const& that) const
{
return compare(that) < 0;
}
}; };
static struct verify_node currentNode; static struct verify_node currentNode;
static tr_list* verifyList = nullptr; // TODO: refactor s.t. this doesn't leak
static auto& verifyList{ *new std::set<verify_node>{} };
static tr_thread* verifyThread = nullptr; static tr_thread* verifyThread = nullptr;
static bool stopCurrent = false; static bool stopCurrent = false;
@ -203,24 +228,21 @@ static void verifyThreadFunc(void* user_data)
for (;;) for (;;)
{ {
bool changed = false; bool changed = false;
tr_torrent* tor;
tr_lockLock(getVerifyLock()); tr_lockLock(getVerifyLock());
stopCurrent = false; stopCurrent = false;
auto* node = static_cast<struct verify_node*>(verifyList != nullptr ? verifyList->data : nullptr); if (std::empty(verifyList))
if (node == nullptr)
{ {
currentNode.torrent = nullptr; currentNode.torrent = nullptr;
break; break; // FIXME: unbalanced lock?
} }
currentNode = *node; auto const it = std::begin(verifyList);
tor = currentNode.torrent; currentNode = *it;
tr_list_remove_data(&verifyList, node); verifyList.erase(it);
tr_free(node);
tr_lockUnlock(getVerifyLock()); tr_lockUnlock(getVerifyLock());
tr_torrent* tor = currentNode.torrent;
tr_logAddTorInfo(tor, "%s", _("Verifying torrent")); tr_logAddTorInfo(tor, "%s", _("Verifying torrent"));
tr_torrentSetVerifyState(tor, TR_VERIFY_NOW); tr_torrentSetVerifyState(tor, TR_VERIFY_NOW);
changed = verifyTorrent(tor, &stopCurrent); changed = verifyTorrent(tor, &stopCurrent);
@ -242,48 +264,20 @@ static void verifyThreadFunc(void* user_data)
tr_lockUnlock(getVerifyLock()); tr_lockUnlock(getVerifyLock());
} }
static int compareVerifyByPriorityAndSize(void const* va, void const* vb)
{
auto const* a = static_cast<struct verify_node const*>(va);
auto const* b = static_cast<struct verify_node const*>(vb);
/* higher priority comes before lower priority */
tr_priority_t const pa = tr_torrentGetPriority(a->torrent);
tr_priority_t const pb = tr_torrentGetPriority(b->torrent);
if (pa != pb)
{
return pa > pb ? -1 : 1;
}
/* smaller torrents come before larger ones because they verify faster */
if (a->current_size < b->current_size)
{
return -1;
}
if (a->current_size > b->current_size)
{
return 1;
}
return 0;
}
void tr_verifyAdd(tr_torrent* tor, tr_verify_done_func callback_func, void* callback_data) void tr_verifyAdd(tr_torrent* tor, tr_verify_done_func callback_func, void* callback_data)
{ {
TR_ASSERT(tr_isTorrent(tor)); TR_ASSERT(tr_isTorrent(tor));
tr_logAddTorInfo(tor, "%s", _("Queued for verification")); tr_logAddTorInfo(tor, "%s", _("Queued for verification"));
struct verify_node* node = tr_new(struct verify_node, 1); auto node = verify_node{};
node->torrent = tor; node.torrent = tor;
node->callback_func = callback_func; node.callback_func = callback_func;
node->callback_data = callback_data; node.callback_data = callback_data;
node->current_size = tr_torrentGetCurrentSizeOnDisk(tor); node.current_size = tr_torrentGetCurrentSizeOnDisk(tor);
tr_lockLock(getVerifyLock()); tr_lockLock(getVerifyLock());
tr_torrentSetVerifyState(tor, TR_VERIFY_WAIT); tr_torrentSetVerifyState(tor, TR_VERIFY_WAIT);
tr_list_insert_sorted(&verifyList, node, compareVerifyByPriorityAndSize); verifyList.insert(node);
if (verifyThread == nullptr) if (verifyThread == nullptr)
{ {
@ -293,13 +287,6 @@ void tr_verifyAdd(tr_torrent* tor, tr_verify_done_func callback_func, void* call
tr_lockUnlock(getVerifyLock()); tr_lockUnlock(getVerifyLock());
} }
static int compareVerifyByTorrent(void const* va, void const* vb)
{
auto const* const a = static_cast<struct verify_node const*>(va);
auto const* const b = static_cast<tr_torrent const*>(vb);
return a->torrent - b;
}
void tr_verifyRemove(tr_torrent* tor) void tr_verifyRemove(tr_torrent* tor)
{ {
TR_ASSERT(tr_isTorrent(tor)); TR_ASSERT(tr_isTorrent(tor));
@ -320,18 +307,21 @@ void tr_verifyRemove(tr_torrent* tor)
} }
else else
{ {
auto* node = static_cast<struct verify_node*>(tr_list_remove(&verifyList, tor, compareVerifyByTorrent)); auto const it = std::find_if(
std::begin(verifyList),
std::end(verifyList),
[tor](auto const& task) { return tor == task.torrent; });
tr_torrentSetVerifyState(tor, TR_VERIFY_NONE); tr_torrentSetVerifyState(tor, TR_VERIFY_NONE);
if (node != nullptr) if (it != std::end(verifyList))
{ {
if (node->callback_func != nullptr) if (it->callback_func != nullptr)
{ {
(*node->callback_func)(tor, true, node->callback_data); (*it->callback_func)(tor, true, it->callback_data);
} }
tr_free(node); verifyList.erase(it);
} }
} }
@ -345,7 +335,7 @@ void tr_verifyClose(tr_session* session)
tr_lockLock(getVerifyLock()); tr_lockLock(getVerifyLock());
stopCurrent = true; stopCurrent = true;
tr_list_free(&verifyList, tr_free); verifyList.clear();
tr_lockUnlock(getVerifyLock()); tr_lockUnlock(getVerifyLock());
} }