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/plugins/Matrix.cpp | 90 ++++++++++++++++++-------------------------------- 1 file changed, 33 insertions(+), 57 deletions(-) (limited to 'src/plugins') 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