Changeset 183


Ignore:
Timestamp:
03/25/09 07:46:59 (3 years ago)
Author:
antonbatenev.ya.ru
Message:

Бранч. Найдено еще одно узкое место при работе с хранилищем. Найдено несколько направлений дальнейшей оптимизации.

Location:
branches/message_tree
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • branches/message_tree/form_message.cpp

    r181 r183  
    264264                AMessageInfo info; 
    265265 
     266                // TODO: убрать заполнение лишних полей 
    266267                info.ID             = 0; 
    267268                info.IDTopic        = 0; 
  • branches/message_tree/forum_tree.cpp

    r181 r183  
    816816        AMessageInfoGUI info; 
    817817 
     818        // TODO: убрать заполнение лишних полей 
    818819        info.ID             = 0; 
    819820        info.IDTopic        = 0; 
  • branches/message_tree/message_tree.cpp

    r182 r183  
    494494void AMessageTree::scrollTopics () 
    495495{ 
    496         // Среднее время выполнения для дозагрузки одного элемента 10 ms 
    497         // Среднее время выполнения для дозагрузки страницы из 56 топиков (полный экран 1280х1024) 61 ms 
     496        // Среднее время выполнения для дозагрузки одного элемента 5 ms 
     497        // Среднее время выполнения для дозагрузки страницы из 56 топиков (полный экран 1280х1024) 32 ms 
    498498 
    499499        // пустой форум или спец-группа 
     
    563563        } 
    564564 
    565         if (storage->getTopicInfoList(list, m_me.ID, NULL) == false) 
     565        if (storage->getTopicInfoList(m_current_forum.ID, list, m_me.ID, NULL) == false) 
    566566        { 
    567567                storage->showError(m_parent); 
     
    585585                info->Item->setText(0, info->Subject); 
    586586 
     587                // TODO: сделать общую функцию формирования имени/ника 
    587588                if (info->IDUser == 0) 
    588                         info->Item->setText(1, global->AnonymousName); 
     589                        info->Item->setText(1, global->AnonymousName /*+ info->UserTitle*/); 
    589590                else 
    590591                        info->Item->setText(1, info->UserNick); 
     
    621622        AMessageInfoGUI* info = item->pag(); 
    622623 
     624        // если дочерние сообщения не загружены (а это может быть только для топика в текущей реализации) 
    623625        if (info->HasChild == true && info->IsChildLoaded == false) 
    624626        { 
     
    633635 
    634636                // заполнение списка сообщений 
     637                // ориентировочное время выполнения 111 ms (для топика 279396 - 5149 сообщений) 
     638                // основное время занимает присвоение данных полям (преобразование из QVariant в QSqlQuery) 
    635639                AMessageInfoGUIPtrList list; 
    636640 
    637                 if (storage->getTopicMessageList(info->ID, list, this, m_me.ID, NULL) == false) 
     641                if (storage->getTopicMessageList(m_current_forum.ID, info->ID, list, this, NULL) == false) 
    638642                { 
    639643                        storage->showError(m_parent); 
     
    642646 
    643647                // постройка дерева 
     648                // ориентировочное время выполнения 900 ms (для топика 279396 - 5149 сообщений) 
     649                // основное время уходит на попытку виджета отобразить все изменения 
     650                // если построить дерево без подсоединения к корневому элементу, то это может 
     651                // работать в 4-5 раз быстрее 
     652                // TODO: Выяснить среднюю ширину и высоту дерева, чтобы улучшить алгоритм его обхода 
    644653                buildTree(info, &list); 
    645654 
    646                 // для предотвращения повторной загрузки TODO 
    647                 //info->IsChildLoaded = true; 
    648  
    649                 /* 
     655                // для предотвращения повторной загрузки 
     656                info->IsChildLoaded = true; 
     657 
    650658                // раскрытие дерева до уровня непрочитаных топиков 
    651                 if (item->pag()->UnreadChildCount != 0) 
     659                if (info->UnreadChildCount != 0) 
    652660                        expandUnreadChild(item); 
    653                 */ 
    654661        } 
    655662} 
     
    658665void AMessageTree::buildTree (AMessageInfoGUI* root, AMessageInfoGUIPtrList* list) 
    659666{ 
    660 } 
    661 //---------------------------------------------------------------------------------------------- 
     667        AGlobal* global = AGlobal::getInstance(); 
     668 
     669        AMessageInfoGUIPtrList child_list; 
     670 
     671        int list_index = 0; 
     672        int list_count = list->count(); 
     673 
     674        while (list_index < list_count) 
     675        { 
     676                AMessageInfoGUI* info = list->at(list_index); 
     677 
     678                if (info->IDParent == root->ID) 
     679                { 
     680                        list_count--; 
     681 
     682                        list->removeAt(list_index); 
     683 
     684                        if (info->HasChild) 
     685                                child_list.append(info); 
     686 
     687                        info->IsInfoLoaded       = true; 
     688                        info->IsChildLoaded      = true; 
     689                        info->UnreadChildCount   = 0; 
     690                        info->UnreadChildCountMy = 0; 
     691 
     692                        info->Item->setText(0, info->Subject); 
     693 
     694                        // TODO: сделать общую функцию формирования имени/ника 
     695                        if (info->IDUser != 0) 
     696                                info->Item->setText(1, info->UserNick); 
     697                        else 
     698                                info->Item->setText(1, global->AnonymousName /*+ info->UserTitle*/); 
     699 
     700                        info->Item->setText(2, info->MessageDate.toString(global->DateFormat)); 
     701 
     702                        root->Item->addChild(info->Item); 
     703 
     704                        // установка родителям свойств непрочитанных сообщений 
     705                        if (info->IsRead == false && root->IDUser == m_me.ID) 
     706                        { 
     707                                // сообщение не прочитано и это ответ не мне 
     708                                info->Item->setIcon(0, m_message_unread_my); 
     709 
     710                                MessageTreeWidgetItem* item_parent = static_cast<MessageTreeWidgetItem*>(info->Item->parent()); 
     711 
     712                                while (item_parent != NULL) 
     713                                { 
     714                                        AMessageInfoGUI* info_parent = item_parent->pag(); 
     715 
     716                                        if (info_parent->HasUnreadChildMy != true) 
     717                                        { 
     718                                                info_parent->HasUnreadChild   = true; 
     719                                                info_parent->HasUnreadChildMy = true; 
     720 
     721                                                if (info_parent->IsRead == true) 
     722                                                        item_parent->setIcon(0, m_child_unread_my); 
     723                                                else 
     724                                                        item_parent->setIcon(0, m_message_unread_my); 
     725                                        } 
     726 
     727                                        info_parent->UnreadChildCount++; 
     728                                        info_parent->UnreadChildCountMy++; 
     729 
     730                                        item_parent = static_cast<MessageTreeWidgetItem*>(item_parent->parent()); 
     731 
     732                                }   // while (item_parent != NULL) 
     733                        } 
     734                        else if (info->IsRead == false) 
     735                        { 
     736                                // сообщение не прочитано, но это ответ не мне 
     737                                info->Item->setIcon(0, m_message_unread); 
     738 
     739                                MessageTreeWidgetItem* item_parent = static_cast<MessageTreeWidgetItem*>(info->Item->parent()); 
     740 
     741                                while (item_parent != NULL) 
     742                                { 
     743                                        AMessageInfoGUI* info_parent = item_parent->pag(); 
     744 
     745                                        if (info_parent->HasUnreadChild != true) 
     746                                        { 
     747                                                info_parent->HasUnreadChild = true; 
     748 
     749                                                if (info_parent->IsRead == true) 
     750                                                        item_parent->setIcon(0, m_child_unread); 
     751                                        } 
     752 
     753                                        info_parent->UnreadChildCount++; 
     754 
     755                                        item_parent = static_cast<MessageTreeWidgetItem*>(item_parent->parent()); 
     756 
     757                                }   // while (item_parent != NULL) 
     758                        } 
     759                        else   // else if (info->IsRead == false) 
     760                        { 
     761                                // сообщение прочитано 
     762                                info->Item->setIcon(0, m_message_read); 
     763                        } 
     764                } 
     765                else   // if (info->ID == id_parent) 
     766                { 
     767                        list_index++; 
     768                } 
     769        } 
     770 
     771        // достройка дочерних для каждого найденного 
     772        for (int i = 0; i < child_list.count(); i++) 
     773                buildTree(child_list[i], list); 
     774} 
     775//---------------------------------------------------------------------------------------------- 
     776 
     777void AMessageTree::expandUnreadChild (QTreeWidgetItem* widget_item) 
     778{ 
     779        MessageTreeWidgetItem* item = static_cast<MessageTreeWidgetItem*>(widget_item); 
     780 
     781        if (item->pag()->UnreadChildCount != 0) 
     782        { 
     783                for (int i = 0; i < item->childCount(); i++) 
     784                        if (((MessageTreeWidgetItem*)item->child(i))->pag()->UnreadChildCount != 0) 
     785                                expandUnreadChild(item->child(i)); 
     786 
     787                expandItem(item); 
     788        } 
     789} 
     790//---------------------------------------------------------------------------------------------- 
  • branches/message_tree/message_tree.h

    r182 r183  
    152152                void buildTree (AMessageInfoGUI* root, AMessageInfoGUIPtrList* list); 
    153153 
     154                /*! 
     155                 * \brief Раскрытие дерева элементов до всех непрочитаных сообщений 
     156                 * \param root Родительский элемент дерева для раскрытия 
     157                 */ 
     158                void expandUnreadChild (QTreeWidgetItem* widget_item); 
     159 
    154160        // IMessageTree 
    155161        public: 
  • branches/message_tree/storage/istorage.h

    r182 r183  
    136136 
    137137                /*! 
    138                  * \brief Заполняет информацию о топиках 
     138                 * \brief Заполняет информацию о топиках в форуме 
    139139                 * Поля списка (кроме ID и Item) предполагаются заполненными значениями полей по умолчанию (см. AMessageInfoGUI::AMessageInfoGUI) и не меняются без необходимости. 
    140                  * Функция должна заполнить все поля AMessageInfo плюс установить флаги IsRead, HasUnreadChild, HasUnreadChildMy в актуальные значения. 
     140                 * Функция ДОЛЖНА заполнить все поля AMessageInfo плюс установить флаги IsRead, HasUnreadChild, HasUnreadChildMy в актуальные значения. 
    141141                 * Функция НЕ должна устанавливать флаг IsInfoLoaded (устанавливается вызвающим кодом). 
     142                 * Функция МОЖЕТ оставить некоторые поля AMessageInfo, которые не используются в текущем GUI, незаполненными в целях оптимизации скорости работы - 
     143                 * в этом случае они должны иметь значения по умолчанию (к таким полям, например, может относиться поле LastModerated и т.д.) 
     144                 * \param id_forum ID форума, для которого запрашивается список топиков 
     145                 * (для ненулевого значения, будет произведено исключение одного лишнего преобразования из QVariant на каждый элемент, что положительно влияет на скорость) 
    142146                 * \param list Список топиков (с установленным полем ID, по которому будет производиться дальнейшее заполнение информацией). 
    143147                 * \param id_me ID текущего пользователя avalon. 
    144148                 * \param progress Прогресс выполнения операции. 
    145149                 */ 
    146                 virtual bool getTopicInfoList (AMessageInfoGUIPtrList& list, int id_me, IProgress* progress = NULL) = 0; 
     150                virtual bool getTopicInfoList (int id_forum, AMessageInfoGUIPtrList& list, int id_me, IProgress* progress = NULL) = 0; 
    147151 
    148152                /*! 
    149153                 * \brief Заполняет информацию о всех сообщениях в топике (родительской ветке). 
    150                  * Функция должна заполнить все поля AMessageInfoGUI кроме (TODO) (которые устанавливаются вызвающим кодом), 
    151                  * body - тело сообщения будет запрошено при помощи IAStorage::GetMessageBody, по мере необходимости. 
     154                 * Функция ДОЛЖНА заполнить все поля AMessageInfo плюс установить флаги IsRead, HasChild в актуальные значения. 
     155                 * Функция НЕ должна устанавливать флаг IsInfoLoaded (устанавливается вызвающим кодом). 
     156                 * Функция МОЖЕТ оставить некоторые поля AMessageInfo, которые не используются в текущем GUI, незаполненными в целях оптимизации скорости работы - 
     157                 * в этом случае они должны иметь значения по умолчанию (к таким полям, например, может относиться поле LastModerated и т.д.) 
     158                 * \param id_forum ID форума, для которого запрашивается список топиков 
     159                 * (для ненулевого значения, будет произведено исключение одного лишнего преобразования из QVariant на каждый элемент, что положительно влияет на скорость) 
    152160                 * \param id_topic ID топика (темы, родительской ветки). 
    153                  * \param list Список сообщений (изначально пустой, на выходе заполненый). 
     161                 * \param list Список сообщений (изначально пустой, на выходе заполненый _не_ включая сообщение id_topic). 
    154162                 * \param factory Фабрика для создания элементов (каждый элемент списка создается вызовом IMessageInfoGUIFactory::createItem), 
    155163                 * поля (кроме Item) предполагаются заполненными значениями полей по умолчанию (см. AMessageInfoGUI::AMessageInfoGUI) и не меняются без необходимости. 
    156                  * \param id_me ID текущего пользователя avalon. 
    157                  * \param progress Прогресс выполнения операции. 
    158                  */ 
    159                 virtual bool getTopicMessageList (int id_topic, AMessageInfoGUIPtrList& list, IMessageInfoGUIFactory* factory, int id_me, IProgress* progress = NULL) = 0; 
     164                 * \param progress Прогресс выполнения операции. 
     165                 */ 
     166                virtual bool getTopicMessageList (int id_forum, int id_topic, AMessageInfoGUIPtrList& list, IMessageInfoGUIFactory* factory, IProgress* progress = NULL) = 0; 
    160167 
    161168                /*! 
  • branches/message_tree/storage/mysql_storage.cpp

    r182 r183  
    19411941//---------------------------------------------------------------------------------------------- 
    19421942 
    1943 bool AMySQLStorage::getTopicInfoList (AMessageInfoGUIPtrList& list, int id_me, IProgress* progress) 
     1943bool AMySQLStorage::getTopicInfoList (int id_forum, AMessageInfoGUIPtrList& list, int id_me, IProgress* progress) 
    19441944{ 
    19451945        if (progress != NULL) 
     
    19611961        // 
    19621962        // получение инфы топика 
     1963        // часть полей, не принимающих участия в GUI, пропущена 
    19631964        // 
    19641965 
    19651966        sql += "SELECT\n"; 
    19661967        sql += "        `id`,\n"; 
    1967         sql += "        `id_topic`,\n"; 
    1968         sql += "        `id_parent`,\n"; 
    19691968        sql += "        `id_user`,\n"; 
    19701969        sql += "        `id_forum`,\n"; 
    19711970        sql += "        `subject`,\n"; 
    1972         sql += "        `message_name`,\n"; 
    19731971        sql += "        `user_nick`,\n"; 
    1974         sql += "        `id_article`,\n"; 
    19751972        sql += "        `message_date`,\n"; 
    1976         sql += "        `update_date`,\n"; 
    1977         sql += "        `user_role`,\n"; 
    1978         sql += "        `user_title`,\n"; 
    1979         sql += "        `user_title_color`,\n"; 
    1980         sql += "        `last_moderated`,\n"; 
    19811973        sql += "        `has_child`\n"; 
    19821974        sql += "FROM\n"; 
     
    20051997                        if (id == info->ID) 
    20061998                        { 
    2007                                 // AMessageInfo 
    2008                                 info->IDTopic        = query_select->value(1).toInt(); 
    2009                                 info->IDParent       = query_select->value(2).toInt(); 
    2010                                 info->IDUser         = query_select->value(3).toInt(); 
    2011                                 info->IDForum        = query_select->value(4).toInt(); 
    2012                                 info->Subject        = query_select->value(5).toString(); 
    2013                                 info->MessageName    = query_select->value(6).toString(); 
    2014                                 info->UserNick       = query_select->value(7).toString(); 
    2015                                 info->IDArticle      = query_select->value(8).toInt(); 
    2016                                 info->MessageDate    = query_select->value(9).toDateTime(); 
    2017                                 info->UpdateDate     = query_select->value(10).toDateTime(); 
    2018                                 info->UserRole       = query_select->value(11).toString(); 
    2019                                 info->UserTitle      = query_select->value(12).toString(); 
    2020                                 info->UserTitleColor = query_select->value(13).toInt(); 
    2021                                 info->LastModerated  = query_select->value(14).toDateTime(); 
    2022                                 info->HasChild       = query_select->value(15).toInt(); 
    2023  
    2024                                 // AMessageInfoGUI (в остальные данные не вмешиваемся) 
    2025                                 info->IsInfoLoaded = true; 
     1999                                // часть полей, не принимающих участия в GUI, оставлена без изменений 
     2000                                info->IDTopic  = 0; // всегда 0 для топиков 
     2001                                info->IDParent = 0; // всегда 0 для топиков 
     2002                                info->IDUser   = query_select->value(1).toInt(); 
     2003 
     2004                                if (id_forum != 0) 
     2005                                        info->IDForum = id_forum; 
     2006                                else 
     2007                                        info->IDForum = query_select->value(2).toInt(); 
     2008 
     2009                                info->Subject     = query_select->value(3).toString(); 
     2010                                info->UserNick    = query_select->value(4).toString(); 
     2011                                info->MessageDate = query_select->value(5).toDateTime(); 
     2012                                info->HasChild    = query_select->value(6).toInt(); 
    20262013 
    20272014                                break; 
     
    21182105//---------------------------------------------------------------------------------------------- 
    21192106 
    2120 bool AMySQLStorage::getTopicMessageList (int id_topic, AMessageInfoGUIPtrList& list, IMessageInfoGUIFactory* factory, int id_me, IProgress* progress) 
     2107bool AMySQLStorage::getTopicMessageList (int id_forum, int id_topic, AMessageInfoGUIPtrList& list, IMessageInfoGUIFactory* factory, IProgress* progress) 
    21212108{ 
    21222109 
     
    21282115        // 
    21292116        // получение сообщений топика 
     2117        // часть полей, не принимающих участия в GUI, пропущена 
    21302118        // 
    21312119 
    21322120        sql += "SELECT\n"; 
    21332121        sql += "        `id`,\n"; 
    2134         sql += "        `id_topic`,\n"; 
    21352122        sql += "        `id_parent`,\n"; 
    21362123        sql += "        `id_user`,\n"; 
    21372124        sql += "        `id_forum`,\n"; 
    21382125        sql += "        `subject`,\n"; 
    2139         sql += "        `message_name`,\n"; 
    21402126        sql += "        `user_nick`,\n"; 
    2141         sql += "        `id_article`,\n"; 
    21422127        sql += "        `message_date`,\n"; 
    2143         sql += "        `update_date`,\n"; 
    2144         sql += "        `user_role`,\n"; 
    2145         sql += "        `user_title`,\n"; 
    2146         sql += "        `user_title_color`,\n"; 
    2147         sql += "        `last_moderated`,\n"; 
    21482128        sql += "        `has_child`\n"; 
    21492129        sql += "FROM\n"; 
     
    21722152                AMessageInfoGUI* info = factory->createItem(); 
    21732153 
    2174                 info->ID             = query_select->value(0).toInt(); 
    2175                 info->IDTopic        = query_select->value(1).toInt(); 
    2176                 info->IDParent       = query_select->value(2).toInt(); 
    2177                 info->IDUser         = query_select->value(3).toInt(); 
    2178                 info->IDForum        = query_select->value(4).toInt(); 
    2179                 info->Subject        = query_select->value(5).toString(); 
    2180                 info->MessageName    = query_select->value(6).toString(); 
    2181                 info->UserNick       = query_select->value(7).toString(); 
    2182                 info->IDArticle      = query_select->value(8).toInt(); 
    2183                 info->MessageDate    = query_select->value(9).toDateTime(); 
    2184                 info->UpdateDate     = query_select->value(10).toDateTime(); 
    2185                 info->UserRole       = query_select->value(11).toString(); 
    2186                 info->UserTitle      = query_select->value(12).toString(); 
    2187                 info->UserTitleColor = query_select->value(13).toInt(); 
    2188                 info->LastModerated  = query_select->value(14).toDateTime(); 
    2189                 info->HasChild       = query_select->value(15).toInt(); 
     2154                // часть полей, не принимающих участия в GUI, оставлена без изменений 
     2155                info->ID       = query_select->value(0).toInt(); 
     2156                info->IDTopic  = id_topic; 
     2157                info->IDParent = query_select->value(1).toInt(); 
     2158                info->IDUser   = query_select->value(2).toInt(); 
     2159 
     2160                if (id_forum != 0) 
     2161                        info->IDForum = id_forum; 
     2162                else 
     2163                        info->IDForum = query_select->value(3).toInt(); 
     2164 
     2165                info->Subject     = query_select->value(4).toString(); 
     2166                info->UserNick    = query_select->value(5).toString(); 
     2167                info->MessageDate = query_select->value(6).toDateTime(); 
     2168                info->HasChild    = query_select->value(7).toInt(); 
    21902169 
    21912170                list.append(info); 
     
    21982177        sql  = ""; 
    21992178        sql += "SELECT\n"; 
    2200         sql += "        `id_message`,\n"; 
    2201         sql += "        `id_parent_user`\n"; 
     2179        sql += "        `id_message`\n"; 
    22022180        sql += "FROM\n"; 
    22032181        sql += "        `unread`\n"; 
     
    22202198        { 
    22212199                int id = query_select_unread->value(0).toInt(); 
    2222                 int id_parent_user = query_select_unread->value(1).toInt(); 
    22232200 
    22242201                for (int i = 0; i < list.count(); i++) 
    2225                         if (list[i].ID == id) 
     2202                        if (list[i]->ID == id) 
    22262203                        { 
    2227                                 if (id_parent_user == id_me) 
    2228                                         list[i]->HasUnreadChild = 2; 
    2229  
    22302204                                list[i]->IsRead = false; 
    22312205 
  • branches/message_tree/storage/mysql_storage.h

    r182 r183  
    5757                bool getUnreadCount         (AUnreadForumCountInfoList& list, IProgress* progress = NULL); 
    5858                bool getForumTopicList      (int id_forum, int count, QList<int>& list, IProgress* progress = NULL); 
    59                 bool getTopicInfoList       (AMessageInfoGUIPtrList& list, int id_me, IProgress* progress = NULL); 
    60                 bool getTopicMessageList    (int id_topic, AMessageInfoGUIPtrList& list, IMessageInfoGUIFactory* factory, int id_me, IProgress* progress = NULL); 
     59                bool getTopicInfoList       (int id_forum, AMessageInfoGUIPtrList& list, int id_me, IProgress* progress = NULL); 
     60                bool getTopicMessageList    (int id_forum, int id_topic, AMessageInfoGUIPtrList& list, IMessageInfoGUIFactory* factory, IProgress* progress = NULL); 
    6161                bool getMessageBody         (int id_message, QString& body, IProgress* progress = NULL); 
    6262                bool setIDsAsRead           (const QList<int>& list, AIDSet type, bool read, QDateTime date, IProgress* progress = NULL); 
  • branches/message_tree/version.h

    r182 r183  
    2020 * \brief Дата билда (заменяется автоматически при каждом билде в version.h, что и приводит к смене номера ревизии) 
    2121 */ 
    22 #define AVALON_DATE "Втр Мар 24 20:28:25 MSK 2009" 
     22#define AVALON_DATE "Срд Мар 25 06:37:09 MSK 2009" 
    2323 
    2424#endif 
Note: See TracChangeset for help on using the changeset viewer.