From c25371eca746929898d0fef0dc4e05f54824167c Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Thu, 17 Mar 2016 09:10:04 +0100 Subject: [PATCH] Performance with recalculating message counts updated. --- resources/text/CHANGELOG | 4 ++ src/gui/messagesview.cpp | 6 -- src/gui/messagesview.h | 2 - src/services/abstract/category.cpp | 71 +++++++++++++++++++ src/services/abstract/category.h | 2 + src/services/abstract/feed.cpp | 12 ++-- src/services/abstract/rootitem.cpp | 2 +- src/services/abstract/rootitem.h | 2 +- src/services/abstract/serviceroot.cpp | 4 +- src/services/owncloud/owncloudserviceroot.cpp | 6 +- src/services/standard/standardserviceroot.cpp | 2 +- src/services/tt-rss/ttrssserviceroot.cpp | 4 +- 12 files changed, 92 insertions(+), 25 deletions(-) diff --git a/resources/text/CHANGELOG b/resources/text/CHANGELOG index 22465fb5f..bf5a1e22a 100755 --- a/resources/text/CHANGELOG +++ b/resources/text/CHANGELOG @@ -20,6 +20,10 @@ Fixed: ▪ Fixed little problem with feed list hiding. (bug #163) ▪ Web browser search context menu item now trims the searched string. (bug #168) +Changed: + +▪ Better performance when recalculating counts of all/unread messages in categories with many feeds. + 3.1.0 ————— diff --git a/src/gui/messagesview.cpp b/src/gui/messagesview.cpp index 3e8da0488..79ce2b30f 100755 --- a/src/gui/messagesview.cpp +++ b/src/gui/messagesview.cpp @@ -50,12 +50,6 @@ MessagesView::~MessagesView() { qDebug("Destroying MessagesView instance."); } -void MessagesView::setSortingEnabled(bool enable) { - disconnect(header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), this, SLOT(onSortIndicatorChanged(int,Qt::SortOrder))); - QTreeView::setSortingEnabled(enable); - connect(header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), this, SLOT(onSortIndicatorChanged(int,Qt::SortOrder))); -} - void MessagesView::createConnections() { connect(this, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(openSelectedSourceMessagesInternallyNoNewTab())); diff --git a/src/gui/messagesview.h b/src/gui/messagesview.h index 5e4e06994..4e3eb9f4d 100755 --- a/src/gui/messagesview.h +++ b/src/gui/messagesview.h @@ -36,8 +36,6 @@ class MessagesView : public QTreeView { explicit MessagesView(QWidget *parent = 0); virtual ~MessagesView(); - void setSortingEnabled(bool enable); - // Model accessors. inline MessagesProxyModel *model() const { return m_proxyModel; diff --git a/src/services/abstract/category.cpp b/src/services/abstract/category.cpp index e3ad1296a..173d823ad 100755 --- a/src/services/abstract/category.cpp +++ b/src/services/abstract/category.cpp @@ -17,6 +17,12 @@ #include "services/abstract/category.h" +#include "miscellaneous/application.h" +#include "services/abstract/serviceroot.h" +#include "services/abstract/feed.h" + +#include + Category::Category(RootItem *parent) : RootItem(parent) { setKind(RootItemKind::Category); @@ -24,3 +30,68 @@ Category::Category(RootItem *parent) : RootItem(parent) { Category::~Category() { } + +void Category::updateCounts(bool including_total_count) { + QList feeds; + + foreach (RootItem *child, childItems()) { + if (child->kind() == RootItemKind::Feed) { + feeds.append(child->toFeed()); + } + else { + child->updateCounts(including_total_count); + } + } + + if (feeds.isEmpty()) { + return; + } + + QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings); + QSqlQuery query_all(database); + QMap counts; + + query_all.setForwardOnly(true); + + if (including_total_count) { + query_all.prepare("SELECT feed, count(*) FROM Messages " + "WHERE feed IN (SELECT custom_id FROM Feeds WHERE category = :category AND account_id = :account_id) AND is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id " + "GROUP BY feed;"); + query_all.bindValue(QSL(":category"), customId()); + query_all.bindValue(QSL(":account_id"), getParentServiceRoot()->accountId()); + + if (query_all.exec()) { + while (query_all.next()) { + int feed_id = query_all.value(0).toInt(); + int new_count = query_all.value(1).toInt(); + + counts.insert(feed_id, new_count); + } + + foreach (Feed *feed, feeds) { + feed->setCountOfAllMessages(counts.value(feed->customId())); + } + } + } + + counts.clear(); + query_all.prepare("SELECT feed, count(*) FROM Messages " + "WHERE feed IN (SELECT custom_id FROM Feeds WHERE category = :category AND account_id = :account_id) AND is_deleted = 0 AND is_pdeleted = 0 AND is_read = 0 AND account_id = :account_id " + "GROUP BY feed;"); + query_all.bindValue(QSL(":category"), customId()); + query_all.bindValue(QSL(":account_id"), getParentServiceRoot()->accountId()); + + // Obtain count of unread messages. + if (query_all.exec()) { + while (query_all.next()) { + int feed_id = query_all.value(0).toInt(); + int new_count = query_all.value(1).toInt(); + + counts.insert(feed_id, new_count); + } + + foreach (Feed *feed, feeds) { + feed->setCountOfUnreadMessages(counts.value(feed->customId())); + } + } +} diff --git a/src/services/abstract/category.h b/src/services/abstract/category.h index 0e43c2edf..af594bf88 100755 --- a/src/services/abstract/category.h +++ b/src/services/abstract/category.h @@ -27,6 +27,8 @@ class Category : public RootItem { public: explicit Category(RootItem *parent = NULL); virtual ~Category(); + + void updateCounts(bool including_total_count); }; #endif // CATEGORY_H diff --git a/src/services/abstract/feed.cpp b/src/services/abstract/feed.cpp index d24285704..3df7fb925 100755 --- a/src/services/abstract/feed.cpp +++ b/src/services/abstract/feed.cpp @@ -101,6 +101,10 @@ void Feed::setCountOfAllMessages(int count_all_messages) { } void Feed::setCountOfUnreadMessages(int count_unread_messages) { + if (status() == NewMessages && count_unread_messages < countOfUnreadMessages()) { + setStatus(Normal); + } + m_unreadCount = count_unread_messages; } @@ -156,13 +160,7 @@ void Feed::updateCounts(bool including_total_count) { // Obtain count of unread messages. if (query_all.exec() && query_all.next()) { - int new_unread_count = query_all.value(0).toInt(); - - if (status() == NewMessages && new_unread_count < countOfUnreadMessages()) { - setStatus(Normal); - } - - setCountOfUnreadMessages(new_unread_count); + setCountOfUnreadMessages(query_all.value(0).toInt()); } } diff --git a/src/services/abstract/rootitem.cpp b/src/services/abstract/rootitem.cpp index a1dbe9448..36dfb825c 100755 --- a/src/services/abstract/rootitem.cpp +++ b/src/services/abstract/rootitem.cpp @@ -310,7 +310,7 @@ QHash RootItem::getHashedSubTreeCategories() const { RootItem *active_item = traversable_items.takeFirst(); if (active_item->kind() == RootItemKind::Category && !children.contains(active_item->id())) { - children.insert(active_item->id(), active_item->toCategory()); + children.insert(active_item->customId(), active_item->toCategory()); } traversable_items.append(active_item->childItems()); diff --git a/src/services/abstract/rootitem.h b/src/services/abstract/rootitem.h index 43f1f316a..713d0f488 100755 --- a/src/services/abstract/rootitem.h +++ b/src/services/abstract/rootitem.h @@ -247,7 +247,7 @@ class RootItem : public QObject { m_boldFont = bold_font; } - // NOTE: For standard feed, this WILL equal to id(). + // NOTE: For standard feed/category, this WILL equal to id(). int customId() const; void setCustomId(int custom_id); diff --git a/src/services/abstract/serviceroot.cpp b/src/services/abstract/serviceroot.cpp index 7660f7aed..887bea27d 100755 --- a/src/services/abstract/serviceroot.cpp +++ b/src/services/abstract/serviceroot.cpp @@ -209,7 +209,7 @@ void ServiceRoot::storeNewFeedTree(RootItem *root) { query_feed.bindValue(QSL(":title"), feed->title()); query_feed.bindValue(QSL(":icon"), qApp->icons()->toByteArray(feed->icon())); - query_feed.bindValue(QSL(":category"), feed->parent()->id()); + query_feed.bindValue(QSL(":category"), feed->parent()->customId()); query_feed.bindValue(QSL(":protected"), 0); query_feed.bindValue(QSL(":update_type"), (int) feed->autoUpdateType()); query_feed.bindValue(QSL(":update_interval"), feed->autoUpdateInitialInterval()); @@ -535,12 +535,10 @@ void ServiceRoot::assembleFeeds(Assignment feeds) { if (feed.first == NO_PARENT_CATEGORY) { // This is top-level feed, add it to the root item. appendChild(feed.second); - feed.second->updateCounts(true); } else if (categories.contains(feed.first)) { // This feed belongs to this category. categories.value(feed.first)->appendChild(feed.second); - feed.second->updateCounts(true); } else { qWarning("Feed '%s' is loose, skipping it.", qPrintable(feed.second->title())); diff --git a/src/services/owncloud/owncloudserviceroot.cpp b/src/services/owncloud/owncloudserviceroot.cpp index 0c296c822..dcff7749b 100755 --- a/src/services/owncloud/owncloudserviceroot.cpp +++ b/src/services/owncloud/owncloudserviceroot.cpp @@ -99,9 +99,11 @@ RecycleBin *OwnCloudServiceRoot::recycleBin() const { } void OwnCloudServiceRoot::start(bool freshly_activated) { + Q_UNUSED(freshly_activated) + loadFromDatabase(); - if (childCount() == 1 && child(0)->kind() == RootItemKind::Bin) { + if (qApp->isFirstRun(QSL("3.1.1")) || (childCount() == 1 && child(0)->kind() == RootItemKind::Bin)) { syncIn(); } } @@ -345,5 +347,5 @@ void OwnCloudServiceRoot::loadFromDatabase() { // As the last item, add recycle bin, which is needed. appendChild(m_recycleBin); - m_recycleBin->updateCounts(true); + updateCounts(true); } diff --git a/src/services/standard/standardserviceroot.cpp b/src/services/standard/standardserviceroot.cpp index 1c8f68e3b..551076a12 100755 --- a/src/services/standard/standardserviceroot.cpp +++ b/src/services/standard/standardserviceroot.cpp @@ -235,7 +235,7 @@ void StandardServiceRoot::loadFromDatabase(){ // As the last item, add recycle bin, which is needed. appendChild(m_recycleBin); - m_recycleBin->updateCounts(true); + updateCounts(true); } void StandardServiceRoot::checkArgumentsForFeedAdding() { diff --git a/src/services/tt-rss/ttrssserviceroot.cpp b/src/services/tt-rss/ttrssserviceroot.cpp index 182168a9a..7aa1f88b5 100755 --- a/src/services/tt-rss/ttrssserviceroot.cpp +++ b/src/services/tt-rss/ttrssserviceroot.cpp @@ -54,7 +54,7 @@ void TtRssServiceRoot::start(bool freshly_activated) { loadFromDatabase(); - if (childCount() == 1 && child(0)->kind() == RootItemKind::Bin) { + if (qApp->isFirstRun(QSL("3.1.1")) || (childCount() == 1 && child(0)->kind() == RootItemKind::Bin)) { syncIn(); } } @@ -340,7 +340,7 @@ void TtRssServiceRoot::loadFromDatabase() { // As the last item, add recycle bin, which is needed. appendChild(m_recycleBin); - m_recycleBin->updateCounts(true); + updateCounts(true); } void TtRssServiceRoot::updateTitle() {