Some optimalizations for feeds loading.

This commit is contained in:
Martin Rotter 2013-12-22 21:31:36 +01:00
parent 80e8fcd0f6
commit 94bb790ee5
6 changed files with 66 additions and 61 deletions

View File

@ -11,6 +11,7 @@
#include <QSqlQuery>
#include <QSqlRecord>
#include <QPair>
#include <QQueue>
FeedsModel::FeedsModel(QObject *parent) : QAbstractItemModel(parent) {
@ -277,25 +278,8 @@ void FeedsModel::loadFromDatabase() {
}
QList<FeedsModelFeed*> FeedsModel::feedsForIndex(const QModelIndex &index) {
QList<FeedsModelFeed*> feeds;
FeedsModelRootItem *item = itemForIndex(index);
switch (item->kind()) {
case FeedsModelRootItem::Category:
// This item is a category, add all its child feeds.
feeds.append(static_cast<FeedsModelCategory*>(item)->feeds());
break;
case FeedsModelRootItem::Feed:
// This item is feed (it SURELY subclasses FeedsModelFeed), add it.
feeds.append(static_cast<FeedsModelFeed*>(item));
break;
default:
break;
}
return feeds;
return getFeeds(item);
}
QList<FeedsModelFeed*> FeedsModel::feedsForIndexes(const QModelIndexList &indexes) {
@ -308,13 +292,19 @@ QList<FeedsModelFeed*> FeedsModel::feedsForIndexes(const QModelIndexList &indexe
return feeds;
}
QHash<int, FeedsModelCategory *> FeedsModel::getCategories(FeedsModelRootItem *root) {
QHash<int, FeedsModelCategory*> FeedsModel::getAllCategories() {
return getCategories(m_rootItem);
}
// TODO: Rewrite this iterativelly (instead of
// current recursive implementation).
QHash<int, FeedsModelCategory*> FeedsModel::getCategories(FeedsModelRootItem *root) {
QHash<int, FeedsModelCategory*> categories;
foreach (FeedsModelRootItem *child, root->childItems()) {
FeedsModelCategory *converted = dynamic_cast<FeedsModelCategory*>(child);
if (child->kind() == FeedsModelRootItem::Category) {
FeedsModelCategory *converted = static_cast<FeedsModelCategory*>(child);
if (converted != NULL) {
// This child is some kind of category.
categories.insert(converted->id(), converted);
@ -326,12 +316,45 @@ QHash<int, FeedsModelCategory *> FeedsModel::getCategories(FeedsModelRootItem *r
return categories;
}
QHash<int, FeedsModelCategory *> FeedsModel::getCategories() {
return getCategories(m_rootItem);
QList<FeedsModelFeed*> FeedsModel::getAllFeeds() {
return getFeeds(m_rootItem);
}
QList<FeedsModelFeed*> FeedsModel::getFeeds(FeedsModelRootItem *root) {
QList<FeedsModelFeed*> feeds;
if (root->kind() == FeedsModelRootItem::Feed) {
// Root itself is a FEED.
feeds.append(static_cast<FeedsModelFeed*>(root));
}
else {
// Root itself is a CATEGORY or ROOT item.
QQueue<FeedsModelRootItem*> traversable_items;
traversable_items.enqueue(root);
// Iterate all nested categories.
while (!traversable_items.isEmpty()) {
FeedsModelRootItem *active_category = traversable_items.dequeue();
foreach (FeedsModelRootItem *child, active_category->childItems()) {
if (child->kind() == FeedsModelRootItem::Feed) {
// This child is feed.
feeds.append(static_cast<FeedsModelFeed*>(child));
}
else if (child->kind() == FeedsModelRootItem::Category) {
// This child is category, add its child feeds too.
traversable_items.enqueue(static_cast<FeedsModelCategory*>(child));
}
}
}
}
return feeds;
}
void FeedsModel::assembleFeeds(FeedAssignment feeds) {
QHash<int, FeedsModelCategory*> categories = getCategories();
QHash<int, FeedsModelCategory*> categories = getAllCategories();
foreach (const FeedAssignmentItem &feed, feeds) {
if (feed.first == NO_PARENT_CATEGORY) {
@ -339,7 +362,7 @@ void FeedsModel::assembleFeeds(FeedAssignment feeds) {
m_rootItem->appendChild(feed.second);
}
else if (categories.contains(feed.first)) {
// This feed belongs to some category.
// This feed belongs to this category.
categories.value(feed.first)->appendChild(feed.second);
}
else {

View File

@ -30,12 +30,21 @@ class FeedsModel : public QAbstractItemModel {
int columnCount(const QModelIndex &parent) const;
int rowCount(const QModelIndex &parent) const;
// Returns all categories.
QHash<int, FeedsModelCategory*> getCategories();
// Returns all categories, each pair
// consists of ID of parent item and pointer to category.
QHash<int, FeedsModelCategory*> getAllCategories();
// Returns categories from the subtree with given root node.
// Returns categories from the subtree with given root node, each pair
// consists of ID of parent item and pointer to category.
QHash<int, FeedsModelCategory*> getCategories(FeedsModelRootItem *root);
// Returns list of all feeds contained in the model.
QList<FeedsModelFeed*> getAllFeeds();
// Get list of feeds from tree with particular item
// as root. If root itself is a feed, then it is returned.
QList<FeedsModelFeed*> getFeeds(FeedsModelRootItem *root);
// Returns list of feeds which belong to given indexes.
// NOTE: If index is "category", then all child feeds are contained in the
// result.

View File

@ -14,35 +14,6 @@ FeedsModelCategory::FeedsModelCategory(FeedsModelRootItem *parent_item)
FeedsModelCategory::~FeedsModelCategory() {
}
QList<FeedsModelFeed*> FeedsModelCategory::feeds() {
QList<FeedsModelFeed*> feeds;
QQueue<FeedsModelCategory*> categories;
categories.enqueue(this);
while (!categories.isEmpty()) {
FeedsModelCategory *active_category = categories.dequeue();
foreach (FeedsModelRootItem *child, active_category->childItems()) {
switch (child->kind()) {
case FeedsModelRootItem::Feed:
feeds.append(static_cast<FeedsModelFeed*>(child));
break;
case FeedsModelRootItem::Category:
// This is category, so add it to traversed categories.
categories.enqueue(static_cast<FeedsModelCategory*>(child));
break;
default:
break;
}
}
}
return feeds;
}
int FeedsModelCategory::countOfAllMessages() const {
int total_count = 0;

View File

@ -25,10 +25,6 @@ class FeedsModelCategory : public FeedsModelRootItem {
explicit FeedsModelCategory(FeedsModelRootItem *parent_item = NULL);
virtual ~FeedsModelCategory();
// Returns list of ALL feeds situated under this category.
// NOTE: This is recursive.
virtual QList<FeedsModelFeed*> feeds();
// Counts of messages.
// NOTE: Counts of messages in categories include
// counts of messages from all children.

View File

@ -34,6 +34,10 @@ QList<FeedsModelFeed *> FeedsView::selectedFeeds() const {
return m_sourceModel->feedsForIndexes(mapped_selection);
}
QList<FeedsModelFeed *> FeedsView::allFeeds() const {
return m_sourceModel->getAllFeeds();
}
void FeedsView::updateCountsOfSelectedFeeds() {
QList<FeedsModelFeed*> feeds = selectedFeeds();

View File

@ -21,6 +21,8 @@ class FeedsView : public QTreeView {
// Returns list of selected feeds.
QList<FeedsModelFeed*> selectedFeeds() const;
QList<FeedsModelFeed*> allFeeds() const;
public slots:
// Reloads count for selected feeds.
void updateCountsOfSelectedFeeds();