Some optimalizations for feeds loading.
This commit is contained in:
		
							parent
							
								
									80e8fcd0f6
								
							
						
					
					
						commit
						94bb790ee5
					
				
					 6 changed files with 66 additions and 61 deletions
				
			
		|  | @ -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 { | ||||
|  |  | |||
|  | @ -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.
 | ||||
|  |  | |||
|  | @ -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; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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.
 | ||||
|  |  | |||
|  | @ -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(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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(); | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue