diff --git a/libtransmission/resume.cc b/libtransmission/resume.cc index 4bfa80e9f..67fe1671c 100644 --- a/libtransmission/resume.cc +++ b/libtransmission/resume.cc @@ -104,7 +104,7 @@ static void saveLabels(tr_variant* dict, tr_torrent const* tor) tr_variant* list = tr_variantDictAddList(dict, TR_KEY_labels, std::size(labels)); for (auto const& label : labels) { - tr_variantListAddStr(list, label); + tr_variantListAddQuark(list, label); } } @@ -116,16 +116,19 @@ static auto loadLabels(tr_variant* dict, tr_torrent* tor) return tr_resume::fields_t{}; } - int const n = tr_variantListSize(list); - for (int i = 0; i < n; ++i) + auto const n = tr_variantListSize(list); + auto labels = std::vector{}; + labels.reserve(n); + for (size_t i = 0; i < n; ++i) { auto sv = std::string_view{}; if (tr_variantGetStrView(tr_variantListChild(list, i), &sv) && !std::empty(sv)) { - tor->labels.emplace(sv); + labels.emplace_back(tr_quark_new(sv)); } } + tor->setLabels(std::data(labels), std::size(labels)); return tr_resume::Labels; } diff --git a/libtransmission/rpcimpl.cc b/libtransmission/rpcimpl.cc index 8f7381d7d..ebcd419fb 100644 --- a/libtransmission/rpcimpl.cc +++ b/libtransmission/rpcimpl.cc @@ -363,7 +363,7 @@ static void addLabels(tr_torrent const* tor, tr_variant* list) tr_variantInitList(list, std::size(tor->labels)); for (auto const& label : tor->labels) { - tr_variantListAddStr(list, label); + tr_variantListAddQuark(list, label); } } @@ -941,10 +941,12 @@ static char const* torrentGet(tr_session* session, tr_variant* args_in, tr_varia **** ***/ -static std::pair makeLabels(tr_variant* list) +static std::pair, char const* /*errmsg*/> makeLabels(tr_variant* list) { - auto labels = tr_labels_t{}; + auto labels = std::vector{}; size_t const n = tr_variantListSize(list); + labels.reserve(n); + for (size_t i = 0; i < n; ++i) { auto label = std::string_view{}; @@ -964,7 +966,7 @@ static std::pair makeLabels(tr_variant* lis return { {}, "labels cannot contain comma (,) character" }; } - labels.emplace(label); + labels.emplace_back(tr_quark_new(label)); } return { labels, nullptr }; @@ -979,7 +981,7 @@ static char const* setLabels(tr_torrent* tor, tr_variant* list) return errmsg; } - tr_torrentSetLabels(tor, std::move(labels)); + tor->setLabels(std::data(labels), std::size(labels)); return nullptr; } @@ -1666,7 +1668,7 @@ static char const* torrentAdd(tr_session* session, tr_variant* args_in, tr_varia return errmsg; } - tr_ctorSetLabels(ctor, std::move(labels)); + tr_ctorSetLabels(ctor, std::data(labels), std::size(labels)); } tr_logAddTrace(fmt::format("torrentAdd: filename is '{}'", filename)); diff --git a/libtransmission/torrent-ctor.cc b/libtransmission/torrent-ctor.cc index 0309d3cd1..9ef029888 100644 --- a/libtransmission/torrent-ctor.cc +++ b/libtransmission/torrent-ctor.cc @@ -41,7 +41,7 @@ struct tr_ctor tr_priority_t priority = TR_PRI_NORMAL; - tr_labels_t labels = {}; + tr_torrent::labels_t labels = {}; struct optional_args optional_args[2]; @@ -329,12 +329,12 @@ tr_priority_t tr_ctorGetBandwidthPriority(tr_ctor const* ctor) **** ***/ -void tr_ctorSetLabels(tr_ctor* ctor, tr_labels_t&& labels) +void tr_ctorSetLabels(tr_ctor* ctor, tr_quark const* labels, size_t n_labels) { - ctor->labels = std::move(labels); + ctor->labels = { labels, labels + n_labels }; } -tr_labels_t tr_ctorGetLabels(tr_ctor const* ctor) +tr_torrent::labels_t const& tr_ctorGetLabels(tr_ctor const* ctor) { return ctor->labels; } diff --git a/libtransmission/torrent.cc b/libtransmission/torrent.cc index 42cd89ca2..48a53f5d2 100644 --- a/libtransmission/torrent.cc +++ b/libtransmission/torrent.cc @@ -717,7 +717,8 @@ static void torrentInit(tr_torrent* tor, tr_ctor const* ctor) tor->error = TR_STAT_OK; tor->finishedSeedingByIdle = false; - tor->labels = tr_ctorGetLabels(ctor); + auto const& labels = tr_ctorGetLabels(ctor); + tor->setLabels(std::data(labels), std::size(labels)); tor->uniqueId = session->torrents().add(tor); @@ -1926,13 +1927,13 @@ void tr_torrentSetFileDLs(tr_torrent* tor, tr_file_index_t const* files, tr_file **** ***/ -void tr_torrentSetLabels(tr_torrent* tor, tr_labels_t&& labels) +void tr_torrent::setLabels(tr_quark const* new_labels, size_t n_labels) { - TR_ASSERT(tr_isTorrent(tor)); - auto const lock = tor->unique_lock(); - - tor->labels = std::move(labels); - tor->setDirty(); + auto const lock = unique_lock(); + auto const sorted_unique = std::set{ new_labels, new_labels + n_labels }; + this->labels = { std::begin(sorted_unique), std::end(sorted_unique) }; + this->labels.shrink_to_fit(); + this->setDirty(); } /*** diff --git a/libtransmission/torrent.h b/libtransmission/torrent.h index 548409919..6f27ea5f5 100644 --- a/libtransmission/torrent.h +++ b/libtransmission/torrent.h @@ -14,7 +14,6 @@ #include #include #include -#include #include #include "transmission.h" @@ -41,8 +40,6 @@ struct tr_session; struct tr_torrent; struct tr_torrent_announcer; -using tr_labels_t = std::unordered_set; - /** *** Package-visible ctor API **/ @@ -59,14 +56,10 @@ tr_session* tr_ctorGetSession(tr_ctor const* ctor); bool tr_ctorGetIncompleteDir(tr_ctor const* ctor, char const** setmeIncompleteDir); -tr_labels_t tr_ctorGetLabels(tr_ctor const* ctor); - /** *** **/ -void tr_torrentSetLabels(tr_torrent* tor, tr_labels_t&& labels); - void tr_torrentChangeMyPort(tr_torrent* session); tr_torrent* tr_torrentFindFromObfuscatedHash(tr_session* session, tr_sha1_digest_t const& hash); @@ -573,6 +566,8 @@ public: void setDateActive(time_t t); + void setLabels(tr_quark const* labels, size_t n_labels); + /** Return the mime-type (e.g. "audio/x-flac") that matches more of the torrent's content than any other mime-type. */ [[nodiscard]] std::string_view primaryMimeType() const; @@ -707,7 +702,8 @@ public: tr_idlelimit idleLimitMode = TR_IDLELIMIT_GLOBAL; bool finishedSeedingByIdle = false; - tr_labels_t labels; + using labels_t = std::vector; + labels_t labels; std::string group; /* Set the bandwidth group the torrent belongs to */ @@ -761,7 +757,8 @@ tr_torrent_metainfo tr_ctorStealMetainfo(tr_ctor* ctor); bool tr_ctorSetMetainfoFromFile(tr_ctor* ctor, std::string const& filename, tr_error** error); bool tr_ctorSetMetainfoFromMagnetLink(tr_ctor* ctor, std::string const& filename, tr_error** error); -void tr_ctorSetLabels(tr_ctor* ctor, tr_labels_t&& labels); +void tr_ctorSetLabels(tr_ctor* ctor, tr_quark const* labels, size_t n_labels); +tr_torrent::labels_t const& tr_ctorGetLabels(tr_ctor const* ctor); #define tr_logAddCriticalTor(tor, msg) tr_logAddCritical(msg, (tor)->name()) #define tr_logAddErrorTor(tor, msg) tr_logAddError(msg, (tor)->name())