From dda3bcd3bd228da1fb18ac1786b690270bf391f0 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Mon, 26 Jul 2021 20:45:16 +0200 Subject: Matrix: greatly improve performance when entering a very large room (initially and later on) --- src/FileAnalyzer.cpp | 41 ++++++++++++----------- src/StringUtils.cpp | 20 +++++++++++ src/plugins/Matrix.cpp | 90 ++++++++++++++++++-------------------------------- 3 files changed, 74 insertions(+), 77 deletions(-) (limited to 'src') diff --git a/src/FileAnalyzer.cpp b/src/FileAnalyzer.cpp index 0178789..a24906f 100644 --- a/src/FileAnalyzer.cpp +++ b/src/FileAnalyzer.cpp @@ -1,6 +1,7 @@ #include "../include/FileAnalyzer.hpp" #include "../include/AsyncImageLoader.hpp" #include "../include/Program.hpp" +#include "../include/StringUtils.hpp" #include #include #include @@ -92,29 +93,29 @@ namespace QuickMedia { } bool is_image_ext(const char *ext) { - return strcasecmp(ext, ".jpg") == 0 - || strcasecmp(ext, ".jpeg") == 0 - || strcasecmp(ext, ".png") == 0 - || strcasecmp(ext, ".gif") == 0 - || strcasecmp(ext, ".webp") == 0; + return strcase_equals(ext, ".jpg") + || strcase_equals(ext, ".jpeg") + || strcase_equals(ext, ".png") + || strcase_equals(ext, ".gif") + || strcase_equals(ext, ".webp"); } bool is_video_ext(const char *ext) { - return strcasecmp(ext, ".webm") == 0 - || strcasecmp(ext, ".mkv") == 0 - || strcasecmp(ext, ".flv") == 0 - || strcasecmp(ext, ".vob") == 0 - || strcasecmp(ext, ".ogv") == 0 - || strcasecmp(ext, ".avi") == 0 - //|| strcasecmp(ext, ".ts") == 0 - || strcasecmp(ext, ".mov") == 0 - || strcasecmp(ext, ".qt") == 0 - || strcasecmp(ext, ".wmv") == 0 - || strcasecmp(ext, ".mp4") == 0 - || strcasecmp(ext, ".m4v") == 0 - || strcasecmp(ext, ".mpg") == 0 - || strcasecmp(ext, ".mpeg") == 0 - || strcasecmp(ext, ".3gp") == 0; + return strcase_equals(ext, ".webm") + || strcase_equals(ext, ".mkv") + || strcase_equals(ext, ".flv") + || strcase_equals(ext, ".vob") + || strcase_equals(ext, ".ogv") + || strcase_equals(ext, ".avi") + //|| strcase_equals(ext, ".ts") + || strcase_equals(ext, ".mov") + || strcase_equals(ext, ".qt") + || strcase_equals(ext, ".wmv") + || strcase_equals(ext, ".mp4") + || strcase_equals(ext, ".m4v") + || strcase_equals(ext, ".mpg") + || strcase_equals(ext, ".mpeg") + || strcase_equals(ext, ".3gp"); } static int accumulate_string(char *data, int size, void *userdata) { diff --git a/src/StringUtils.cpp b/src/StringUtils.cpp index 8ed142f..041a12d 100644 --- a/src/StringUtils.cpp +++ b/src/StringUtils.cpp @@ -109,4 +109,24 @@ namespace QuickMedia { return std::string::npos; return it - str.begin(); } + + static char to_upper(char c) { + if(c >= 'a' && c <= 'z') + return c - 32; + else + return c; + } + + bool strcase_equals(const char *str1, const char *str2) { + for(;;) { + const char c1 = *str1; + const char c2 = *str2; + if(to_upper(c1) != to_upper(c2)) + return false; + else if(c1 == '\0') + return true; + ++str1; + ++str2; + } + } } \ No newline at end of file diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp index a07fc9b..19454df 100644 --- a/src/plugins/Matrix.cpp +++ b/src/plugins/Matrix.cpp @@ -452,47 +452,40 @@ namespace QuickMedia { show_notification("QuickMedia matrix - " + notification.sender_user_id + " (" + notification.room->get_name() + ")", notification.body); } - static UsersByRoom::iterator find_user_data_by_id(UsersByRoom &users_by_room, const MatrixEventUserInfo &user_info) { - RoomData *room = user_info.room; - auto range = users_by_room.equal_range(room); - for(auto &it = range.first; it != range.second; ++it) { - if(it->second.user_id == user_info.user_id) - return it; - } - return users_by_room.end(); - } - void MatrixQuickMedia::add_user(MatrixEventUserInfo user_info) { - auto it = find_user_data_by_id(users_by_room, user_info); - if(it == users_by_room.end()) { - users_by_room.insert(std::make_pair(user_info.room, user_info)); - if(chat_page) - chat_page->add_user(std::move(user_info)); - } + auto &users = users_by_room[user_info.room]; + const bool new_user = users.insert(std::make_pair(user_info.user_id, user_info)).second; + if(!new_user) + return; + + if(chat_page) + chat_page->add_user(std::move(user_info)); } void MatrixQuickMedia::remove_user(MatrixEventUserInfo user_info) { - auto it = find_user_data_by_id(users_by_room, user_info); - if(it != users_by_room.end()) { - users_by_room.erase(it); - if(chat_page) - chat_page->remove_user(std::move(user_info)); - } + auto &users = users_by_room[user_info.room]; + if(users.erase(user_info.user_id) == 0) + return; + + if(chat_page) + chat_page->remove_user(std::move(user_info)); } void MatrixQuickMedia::set_user_info(MatrixEventUserInfo user_info) { - auto it = find_user_data_by_id(users_by_room, user_info); - if(it != users_by_room.end()) { - it->second = user_info; - if(chat_page) - chat_page->set_user_info(std::move(user_info)); - } + auto &users = users_by_room[user_info.room]; + auto it = users.find(user_info.user_id); + if(it == users.end()) + return; + + it->second = user_info; + if(chat_page) + chat_page->set_user_info(std::move(user_info)); } void MatrixQuickMedia::for_each_user_in_room(RoomData *room, std::function callback) { - auto range = users_by_room.equal_range(room); - for(auto &it = range.first; it != range.second; ++it) { - callback(it->second); + auto &users = users_by_room[room]; + for(const auto &user : users) { + callback(user.second); } } @@ -897,19 +890,8 @@ namespace QuickMedia { rooms_page->matrix_delegate->chat_page = nullptr; } - // Returns |default_value| if the input items is empty - static size_t get_body_item_sorted_insert_position_by_author(BodyItems &body_items, const std::string &display_name, size_t default_value) { - for(size_t i = 0; i < body_items.size(); ++i) { - auto &body_item = body_items[i]; - if(strcasecmp(display_name.c_str(), body_item->get_author().c_str()) <= 0) - return i; - } - return default_value; - } - static void add_user_to_body_by_user_info(Body *users_body, const MatrixEventUserInfo &user_info) { std::string display_name = user_info.display_name.value_or(user_info.user_id); - size_t insert_index = get_body_item_sorted_insert_position_by_author(users_body->items, display_name, 0); auto body_item = BodyItem::create(""); body_item->url = user_info.user_id; @@ -923,19 +905,13 @@ namespace QuickMedia { body_item->thumbnail_size = sf::Vector2i(32, 32); users_body->apply_search_filter_for_item(body_item.get()); - users_body->items.insert(users_body->items.begin() + insert_index, std::move(body_item)); + users_body->items.push_back(std::move(body_item)); } void MatrixChatPage::add_user(MatrixEventUserInfo user_info) { if(!current_room || !users_body || user_info.room != current_room) return; - // Ignore if the user already exists in the room - for(auto &body_item : users_body->items) { - if(body_item->url == user_info.user_id) - return; - } - add_user_to_body_by_user_info(users_body, user_info); } @@ -943,6 +919,7 @@ namespace QuickMedia { if(!current_room || !users_body || user_info.room != current_room) return; + // TODO: Optimize for(auto it = users_body->items.begin(), end = users_body->items.end(); it != end; ++it) { if((*it)->url == user_info.user_id) { users_body->items.erase(it); @@ -955,6 +932,7 @@ namespace QuickMedia { if(!current_room || !users_body || user_info.room != current_room) return; + // TODO: Optimize for(auto it = users_body->items.begin(), end = users_body->items.end(); it != end; ++it) { if((*it)->url == user_info.user_id) { if(user_info.avatar_url) @@ -969,14 +947,14 @@ namespace QuickMedia { (*it)->set_author(extract_first_line_remove_newline_elipses(display_name, AUTHOR_MAX_LENGTH)); - auto user_body_item = *it; - users_body->items.erase(it); + //auto user_body_item = *it; + //users_body->items.erase(it); // TODO: extract_first_line_remove_newline_elipses(room->get_user_display_name(message->user), AUTHOR_MAX_LENGTH), // But that should be done in Text because we need author to be 100% the same as in the input to reorder users - users_body->apply_search_filter_for_item(user_body_item.get()); - size_t insert_index = get_body_item_sorted_insert_position_by_author(users_body->items, user_body_item->get_author(), 0); - users_body->items.insert(users_body->items.begin() + insert_index, std::move(user_body_item)); + users_body->apply_search_filter_for_item(it->get()); + //size_t insert_index = get_body_item_sorted_insert_position_by_author(users_body->items, user_body_item->get_author(), 0); + //users_body->items.insert(users_body->items.begin() + insert_index, std::move(user_body_item)); } return; @@ -4414,10 +4392,8 @@ namespace QuickMedia { void Matrix::update() { sf::Clock timer; std::optional> task; - int i = 0; - while((task = ui_thread_tasks.pop_if_available()) != std::nullopt && i < 25) { + while((task = ui_thread_tasks.pop_if_available()) != std::nullopt) { task.value()(); - ++i; } } -- cgit v1.2.3