From 15ea836bb95940a80915d3012c6fcce93ca98574 Mon Sep 17 00:00:00 2001 From: Vladimir Golovnev Date: Tue, 26 Nov 2024 09:04:59 +0300 Subject: [PATCH] Avoid repeatedly creating the same QDateTime values PR #21904. --- src/base/bittorrent/sessionimpl.cpp | 4 +- src/base/bittorrent/torrent.h | 15 +- src/base/bittorrent/torrentdescriptor.cpp | 17 ++- src/base/bittorrent/torrentdescriptor.h | 7 +- src/base/bittorrent/torrentimpl.cpp | 129 +++++++++--------- src/base/bittorrent/torrentimpl.h | 23 +++- src/base/rss/rss_parser.cpp | 3 +- src/gui/rss/htmlbrowser.cpp | 8 +- src/webui/api/serialize/serialize_torrent.cpp | 2 +- 9 files changed, 115 insertions(+), 93 deletions(-) diff --git a/src/base/bittorrent/sessionimpl.cpp b/src/base/bittorrent/sessionimpl.cpp index efcabbf0d..c498b46f0 100644 --- a/src/base/bittorrent/sessionimpl.cpp +++ b/src/base/bittorrent/sessionimpl.cpp @@ -1610,7 +1610,7 @@ void SessionImpl::endStartup(ResumeSessionContext *context) reannounceToAllTrackers(); } - m_wakeupCheckTimestamp = QDateTime::currentDateTime(); + m_wakeupCheckTimestamp = now; }); m_wakeupCheckTimestamp = QDateTime::currentDateTime(); m_wakeupCheckTimer->start(30s); @@ -6396,7 +6396,7 @@ void SessionImpl::handleRemovedTorrent(const TorrentID &torrentID, const QString m_removingTorrents.erase(removingTorrentDataIter); } -QDateTime SessionImpl::fromLTTimePoint32(const libtorrent::time_point32 &timePoint) const +QDateTime SessionImpl::fromLTTimePoint32(const lt::time_point32 &timePoint) const { const auto secsSinceNow = lt::duration_cast(timePoint - m_ltNow + lt::milliseconds(500)).count(); return m_qNow.addSecs(secsSinceNow); diff --git a/src/base/bittorrent/torrent.h b/src/base/bittorrent/torrent.h index bd034f133..d2eefbabf 100644 --- a/src/base/bittorrent/torrent.h +++ b/src/base/bittorrent/torrent.h @@ -215,7 +215,15 @@ namespace BitTorrent virtual int piecesCount() const = 0; virtual int piecesHave() const = 0; virtual qreal progress() const = 0; + virtual QDateTime addedTime() const = 0; + virtual QDateTime completedTime() const = 0; + virtual QDateTime lastSeenComplete() const = 0; + virtual qlonglong activeTime() const = 0; + virtual qlonglong finishedTime() const = 0; + virtual qlonglong timeSinceUpload() const = 0; + virtual qlonglong timeSinceDownload() const = 0; + virtual qlonglong timeSinceActivity() const = 0; // Share limits virtual qreal ratioLimit() const = 0; @@ -254,8 +262,6 @@ namespace BitTorrent virtual QString error() const = 0; virtual qlonglong totalDownload() const = 0; virtual qlonglong totalUpload() const = 0; - virtual qlonglong activeTime() const = 0; - virtual qlonglong finishedTime() const = 0; virtual qlonglong eta() const = 0; virtual int seedsCount() const = 0; virtual int peersCount() const = 0; @@ -263,11 +269,6 @@ namespace BitTorrent virtual int totalSeedsCount() const = 0; virtual int totalPeersCount() const = 0; virtual int totalLeechersCount() const = 0; - virtual QDateTime lastSeenComplete() const = 0; - virtual QDateTime completedTime() const = 0; - virtual qlonglong timeSinceUpload() const = 0; - virtual qlonglong timeSinceDownload() const = 0; - virtual qlonglong timeSinceActivity() const = 0; virtual int downloadLimit() const = 0; virtual int uploadLimit() const = 0; virtual bool superSeeding() const = 0; diff --git a/src/base/bittorrent/torrentdescriptor.cpp b/src/base/bittorrent/torrentdescriptor.cpp index 42e969b0d..437c6557c 100644 --- a/src/base/bittorrent/torrentdescriptor.cpp +++ b/src/base/bittorrent/torrentdescriptor.cpp @@ -1,6 +1,6 @@ /* * Bittorrent Client using Qt and libtorrent. - * Copyright (C) 2015-2023 Vladimir Golovnev + * Copyright (C) 2015-2024 Vladimir Golovnev * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -35,9 +35,7 @@ #include #include -#include #include -#include #include #include "base/global.h" @@ -147,7 +145,13 @@ BitTorrent::TorrentDescriptor::TorrentDescriptor(lt::add_torrent_params ltAddTor : m_ltAddTorrentParams {std::move(ltAddTorrentParams)} { if (m_ltAddTorrentParams.ti && m_ltAddTorrentParams.ti->is_valid()) + { m_info.emplace(*m_ltAddTorrentParams.ti); + if (m_ltAddTorrentParams.ti->creation_date() > 0) + m_creationDate = QDateTime::fromSecsSinceEpoch(m_ltAddTorrentParams.ti->creation_date()); + m_creator = QString::fromStdString(m_ltAddTorrentParams.ti->creator()); + m_comment = QString::fromStdString(m_ltAddTorrentParams.ti->comment()); + } } BitTorrent::InfoHash BitTorrent::TorrentDescriptor::infoHash() const @@ -166,18 +170,17 @@ QString BitTorrent::TorrentDescriptor::name() const QDateTime BitTorrent::TorrentDescriptor::creationDate() const { - return ((m_ltAddTorrentParams.ti->creation_date() != 0) - ? QDateTime::fromSecsSinceEpoch(m_ltAddTorrentParams.ti->creation_date()) : QDateTime()); + return m_creationDate; } QString BitTorrent::TorrentDescriptor::creator() const { - return QString::fromStdString(m_ltAddTorrentParams.ti->creator()); + return m_creator; } QString BitTorrent::TorrentDescriptor::comment() const { - return QString::fromStdString(m_ltAddTorrentParams.ti->comment()); + return m_comment; } const std::optional &BitTorrent::TorrentDescriptor::info() const diff --git a/src/base/bittorrent/torrentdescriptor.h b/src/base/bittorrent/torrentdescriptor.h index 54248ae57..f41140fed 100644 --- a/src/base/bittorrent/torrentdescriptor.h +++ b/src/base/bittorrent/torrentdescriptor.h @@ -33,15 +33,15 @@ #include #include +#include #include +#include #include "base/3rdparty/expected.hpp" #include "base/path.h" #include "torrentinfo.h" class QByteArray; -class QDateTime; -class QString; class QUrl; namespace BitTorrent @@ -77,6 +77,9 @@ namespace BitTorrent lt::add_torrent_params m_ltAddTorrentParams; std::optional m_info; + QDateTime m_creationDate; + QString m_creator; + QString m_comment; }; } diff --git a/src/base/bittorrent/torrentimpl.cpp b/src/base/bittorrent/torrentimpl.cpp index ecfcb66e5..5c8ae4dc8 100644 --- a/src/base/bittorrent/torrentimpl.cpp +++ b/src/base/bittorrent/torrentimpl.cpp @@ -322,6 +322,11 @@ TorrentImpl::TorrentImpl(SessionImpl *session, lt::session *nativeSession { if (m_ltAddTorrentParams.ti) { + if (const std::time_t creationDate = m_ltAddTorrentParams.ti->creation_date(); creationDate > 0) + m_creationDate = QDateTime::fromSecsSinceEpoch(creationDate); + m_creator = QString::fromStdString(m_ltAddTorrentParams.ti->creator()); + m_comment = QString::fromStdString(m_ltAddTorrentParams.ti->comment()); + // Initialize it only if torrent is added with metadata. // Otherwise it should be initialized in "Metadata received" handler. m_torrentInfo = TorrentInfo(*m_ltAddTorrentParams.ti); @@ -365,6 +370,12 @@ TorrentImpl::TorrentImpl(SessionImpl *session, lt::session *nativeSession m_urlSeeds.append(QString::fromStdString(urlSeed)); m_nativeStatus = extensionData->status; + m_addedTime = QDateTime::fromSecsSinceEpoch(m_nativeStatus.added_time); + if (m_nativeStatus.completed_time > 0) + m_completedTime = QDateTime::fromSecsSinceEpoch(m_nativeStatus.completed_time); + if (m_nativeStatus.last_seen_complete > 0) + m_lastSeenComplete = QDateTime::fromSecsSinceEpoch(m_nativeStatus.last_seen_complete); + if (hasMetadata()) updateProgress(); @@ -408,27 +419,17 @@ QString TorrentImpl::name() const QDateTime TorrentImpl::creationDate() const { - if (!hasMetadata()) - return {}; - - const std::time_t date = nativeTorrentInfo()->creation_date(); - return ((date != 0) ? QDateTime::fromSecsSinceEpoch(date) : QDateTime()); + return m_creationDate; } QString TorrentImpl::creator() const { - if (!hasMetadata()) - return {}; - - return QString::fromStdString(nativeTorrentInfo()->creator()); + return m_creator; } QString TorrentImpl::comment() const { - if (!hasMetadata()) - return {}; - - return QString::fromStdString(nativeTorrentInfo()->comment()); + return m_comment; } bool TorrentImpl::isPrivate() const @@ -957,7 +958,52 @@ void TorrentImpl::removeAllTags() QDateTime TorrentImpl::addedTime() const { - return QDateTime::fromSecsSinceEpoch(m_nativeStatus.added_time); + return m_addedTime; +} + +QDateTime TorrentImpl::completedTime() const +{ + return m_completedTime; +} + +QDateTime TorrentImpl::lastSeenComplete() const +{ + return m_lastSeenComplete; +} + +qlonglong TorrentImpl::activeTime() const +{ + return lt::total_seconds(m_nativeStatus.active_duration); +} + +qlonglong TorrentImpl::finishedTime() const +{ + return lt::total_seconds(m_nativeStatus.finished_duration); +} + +qlonglong TorrentImpl::timeSinceUpload() const +{ + if (m_nativeStatus.last_upload.time_since_epoch().count() == 0) + return -1; + + return lt::total_seconds(lt::clock_type::now() - m_nativeStatus.last_upload); +} + +qlonglong TorrentImpl::timeSinceDownload() const +{ + if (m_nativeStatus.last_download.time_since_epoch().count() == 0) + return -1; + + return lt::total_seconds(lt::clock_type::now() - m_nativeStatus.last_download); +} + +qlonglong TorrentImpl::timeSinceActivity() const +{ + const qlonglong upTime = timeSinceUpload(); + const qlonglong downTime = timeSinceDownload(); + return ((upTime < 0) != (downTime < 0)) + ? std::max(upTime, downTime) + : std::min(upTime, downTime); } qreal TorrentImpl::ratioLimit() const @@ -1276,16 +1322,6 @@ qlonglong TorrentImpl::totalUpload() const return m_nativeStatus.all_time_upload; } -qlonglong TorrentImpl::activeTime() const -{ - return lt::total_seconds(m_nativeStatus.active_duration); -} - -qlonglong TorrentImpl::finishedTime() const -{ - return lt::total_seconds(m_nativeStatus.finished_duration); -} - qlonglong TorrentImpl::eta() const { if (isStopped()) return MAX_ETA; @@ -1395,45 +1431,6 @@ int TorrentImpl::totalLeechersCount() const return (m_nativeStatus.num_incomplete > -1) ? m_nativeStatus.num_incomplete : (m_nativeStatus.list_peers - m_nativeStatus.list_seeds); } -QDateTime TorrentImpl::lastSeenComplete() const -{ - if (m_nativeStatus.last_seen_complete > 0) - return QDateTime::fromSecsSinceEpoch(m_nativeStatus.last_seen_complete); - else - return {}; -} - -QDateTime TorrentImpl::completedTime() const -{ - if (m_nativeStatus.completed_time > 0) - return QDateTime::fromSecsSinceEpoch(m_nativeStatus.completed_time); - else - return {}; -} - -qlonglong TorrentImpl::timeSinceUpload() const -{ - if (m_nativeStatus.last_upload.time_since_epoch().count() == 0) - return -1; - return lt::total_seconds(lt::clock_type::now() - m_nativeStatus.last_upload); -} - -qlonglong TorrentImpl::timeSinceDownload() const -{ - if (m_nativeStatus.last_download.time_since_epoch().count() == 0) - return -1; - return lt::total_seconds(lt::clock_type::now() - m_nativeStatus.last_download); -} - -qlonglong TorrentImpl::timeSinceActivity() const -{ - const qlonglong upTime = timeSinceUpload(); - const qlonglong downTime = timeSinceDownload(); - return ((upTime < 0) != (downTime < 0)) - ? std::max(upTime, downTime) - : std::min(upTime, downTime); -} - int TorrentImpl::downloadLimit() const { return m_downloadLimit;; @@ -2646,6 +2643,12 @@ void TorrentImpl::updateStatus(const lt::torrent_status &nativeStatus) if (m_nativeStatus.num_pieces != oldStatus.num_pieces) updateProgress(); + if (m_nativeStatus.completed_time != oldStatus.completed_time) + m_completedTime = (m_nativeStatus.completed_time > 0) ? QDateTime::fromSecsSinceEpoch(m_nativeStatus.completed_time) : QDateTime(); + + if (m_nativeStatus.last_seen_complete != oldStatus.last_seen_complete) + m_lastSeenComplete = QDateTime::fromSecsSinceEpoch(m_nativeStatus.last_seen_complete); + updateState(); m_payloadRateMonitor.addSample({nativeStatus.download_payload_rate diff --git a/src/base/bittorrent/torrentimpl.h b/src/base/bittorrent/torrentimpl.h index 9b0d4df2a..5c54b2d00 100644 --- a/src/base/bittorrent/torrentimpl.h +++ b/src/base/bittorrent/torrentimpl.h @@ -138,7 +138,15 @@ namespace BitTorrent int piecesCount() const override; int piecesHave() const override; qreal progress() const override; + QDateTime addedTime() const override; + QDateTime completedTime() const override; + QDateTime lastSeenComplete() const override; + qlonglong activeTime() const override; + qlonglong finishedTime() const override; + qlonglong timeSinceUpload() const override; + qlonglong timeSinceDownload() const override; + qlonglong timeSinceActivity() const override; qreal ratioLimit() const override; void setRatioLimit(qreal limit) override; @@ -181,8 +189,6 @@ namespace BitTorrent QString error() const override; qlonglong totalDownload() const override; qlonglong totalUpload() const override; - qlonglong activeTime() const override; - qlonglong finishedTime() const override; qlonglong eta() const override; QList filesProgress() const override; int seedsCount() const override; @@ -191,11 +197,6 @@ namespace BitTorrent int totalSeedsCount() const override; int totalPeersCount() const override; int totalLeechersCount() const override; - QDateTime lastSeenComplete() const override; - QDateTime completedTime() const override; - qlonglong timeSinceUpload() const override; - qlonglong timeSinceDownload() const override; - qlonglong timeSinceActivity() const override; int downloadLimit() const override; int uploadLimit() const override; bool superSeeding() const override; @@ -342,6 +343,14 @@ namespace BitTorrent InfoHash m_infoHash; + QDateTime m_creationDate; + QString m_creator; + QString m_comment; + + QDateTime m_addedTime; + QDateTime m_completedTime; + QDateTime m_lastSeenComplete; + // m_moveFinishedTriggers is activated only when the following conditions are met: // all file rename jobs complete, all file move jobs complete QQueue m_moveFinishedTriggers; diff --git a/src/base/rss/rss_parser.cpp b/src/base/rss/rss_parser.cpp index 07fa7dffd..19d199ce4 100644 --- a/src/base/rss/rss_parser.cpp +++ b/src/base/rss/rss_parser.cpp @@ -700,6 +700,7 @@ void RSS::Private::Parser::parseRSSChannel(QXmlStreamReader &xml) void RSS::Private::Parser::parseAtomArticle(QXmlStreamReader &xml) { + const auto currentDateTime = QDateTime::currentDateTime(); QVariantHash article; bool doubleContent = false; @@ -756,7 +757,7 @@ void RSS::Private::Parser::parseAtomArticle(QXmlStreamReader &xml) { // ATOM uses standard compliant date, don't do fancy stuff const QDateTime articleDate = QDateTime::fromString(xml.readElementText().trimmed(), Qt::ISODate); - article[Article::KeyDate] = (articleDate.isValid() ? articleDate : QDateTime::currentDateTime()); + article[Article::KeyDate] = (articleDate.isValid() ? articleDate : currentDateTime); } else if (name == u"author") { diff --git a/src/gui/rss/htmlbrowser.cpp b/src/gui/rss/htmlbrowser.cpp index ecf3ff7ad..4c34923bc 100644 --- a/src/gui/rss/htmlbrowser.cpp +++ b/src/gui/rss/htmlbrowser.cpp @@ -106,10 +106,12 @@ void HtmlBrowser::resourceLoaded(QNetworkReply *reply) atts[QNetworkRequest::HttpStatusCodeAttribute] = 200; atts[QNetworkRequest::HttpReasonPhraseAttribute] = u"Ok"_s; metaData.setAttributes(atts); - metaData.setLastModified(QDateTime::currentDateTime()); - metaData.setExpirationDate(QDateTime::currentDateTime().addDays(1)); + const auto currentDateTime = QDateTime::currentDateTime(); + metaData.setLastModified(currentDateTime); + metaData.setExpirationDate(currentDateTime.addDays(1)); QIODevice *dev = m_diskCache->prepare(metaData); - if (!dev) return; + if (!dev) + return; QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning).pixmap(32, 32).save(dev, "PNG"); m_diskCache->insert(dev); diff --git a/src/webui/api/serialize/serialize_torrent.cpp b/src/webui/api/serialize/serialize_torrent.cpp index 177c44f5b..bc75a7698 100644 --- a/src/webui/api/serialize/serialize_torrent.cpp +++ b/src/webui/api/serialize/serialize_torrent.cpp @@ -104,7 +104,7 @@ QVariantMap serialize(const BitTorrent::Torrent &torrent) const qlonglong timeSinceActivity = torrent.timeSinceActivity(); return (timeSinceActivity < 0) ? Utils::DateTime::toSecsSinceEpoch(torrent.addedTime()) - : (QDateTime::currentDateTime().toSecsSinceEpoch() - timeSinceActivity); + : (QDateTime::currentSecsSinceEpoch() - timeSinceActivity); }; return {