From 5445d920b13871fad12ddf72d356b3c7ec6009b5 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 16 Jan 2018 19:04:36 +0300 Subject: [PATCH] Combine simultaneous SearchPublicChats queries. GitOrigin-RevId: f51ed555b0758ef0cdf8afb73f276dbeb687e70e --- td/telegram/MessagesManager.cpp | 61 +++++++++++++++++++++++---------- td/telegram/MessagesManager.h | 10 ++++-- 2 files changed, 49 insertions(+), 22 deletions(-) diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 3d6681e6a..53060eb0c 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -465,17 +465,13 @@ class GetDialogListQuery : public NetActorOnce { }; class SearchPublicDialogsQuery : public Td::ResultHandler { - Promise promise_; string query_; public: - explicit SearchPublicDialogsQuery(Promise &&promise) : promise_(std::move(promise)) { - } - void send(const string &query) { query_ = query; send_query(G()->net_query_creator().create( - create_storer(telegram_api::contacts_search(query, 100 /* ignored server-side */)))); + create_storer(telegram_api::contacts_search(query, 3 /* ignored server-side */)))); } void on_result(uint64 id, BufferSlice packet) override { @@ -489,14 +485,11 @@ class SearchPublicDialogsQuery : public Td::ResultHandler { td->contacts_manager_->on_get_chats(std::move(dialogs->chats_)); td->contacts_manager_->on_get_users(std::move(dialogs->users_)); td->messages_manager_->on_get_public_dialogs_search_result(query_, std::move(dialogs->results_)); - - promise_.set_value(Unit()); } void on_error(uint64 id, Status status) override { - td->messages_manager_->on_failed_public_dialogs_search(query_); LOG(ERROR) << "Receive error for SearchPublicDialogsQuery: " << status; - promise_.set_error(std::move(status)); + td->messages_manager_->on_failed_public_dialogs_search(query_, std::move(status)); } }; @@ -6484,6 +6477,12 @@ void MessagesManager::on_get_history(DialogId dialog_id, MessageId from_message_ void MessagesManager::on_get_public_dialogs_search_result(const string &query, vector> &&peers) { + auto it = search_public_dialogs_queries_.find(query); + CHECK(it != search_public_dialogs_queries_.end()); + CHECK(it->second.size() > 0); + auto promises = std::move(it->second); + search_public_dialogs_queries_.erase(it); + vector result; result.reserve(peers.size()); for (auto &peer : peers) { @@ -6495,10 +6494,24 @@ void MessagesManager::on_get_public_dialogs_search_result(const string &query, } found_public_dialogs_[query] = std::move(result); + + for (auto &promise : promises) { + promise.set_value(Unit()); + } } -void MessagesManager::on_failed_public_dialogs_search(const string &query) { +void MessagesManager::on_failed_public_dialogs_search(const string &query, Status &&error) { + auto it = search_public_dialogs_queries_.find(query); + CHECK(it != search_public_dialogs_queries_.end()); + CHECK(it->second.size() > 0); + auto promises = std::move(it->second); + search_public_dialogs_queries_.erase(it); + found_public_dialogs_[query]; // negative cache + + for (auto &promise : promises) { + promise.set_error(error.clone()); + } } void MessagesManager::on_get_dialog_messages_search_result(DialogId dialog_id, const string &query, @@ -10501,11 +10514,21 @@ vector MessagesManager::search_public_dialogs(const string &query, Pro return it->second; } - // TODO MultiPromise - td_->create_handler(std::move(promise))->send(query); + send_search_public_dialogs_query(query, std::move(promise)); return vector(); } +void MessagesManager::send_search_public_dialogs_query(const string &query, Promise &&promise) { + auto &promises = search_public_dialogs_queries_[query]; + promises.push_back(std::move(promise)); + if (promises.size() != 1) { + // query has already been sent, just wait for the result + return; + } + + td_->create_handler()->send(query); +} + std::pair> MessagesManager::search_dialogs(const string &query, int32 limit, Promise &&promise) { LOG(INFO) << "Search chats with query \"" << query << "\" and limit " << limit; @@ -11282,7 +11305,7 @@ void MessagesManager::create_dialog(DialogId dialog_id, Promise &&promise) } else { const Dialog *d = get_dialog_force(dialog_id); if (d == nullptr || !d->notification_settings.is_synchronized) { - return get_dialog_query(dialog_id, std::move(promise)); + return send_get_dialog_query(dialog_id, std::move(promise)); } } @@ -11790,7 +11813,7 @@ tl_object_ptr MessagesManager::get_chat_object(const Dialog *d) { if (!d->notification_settings.is_synchronized && d->dialog_id.get_type() != DialogType::SecretChat && have_input_peer(d->dialog_id, AccessRights::Read)) { // asynchronously get dialog from the server - get_dialog_query(d->dialog_id, Auto()); + send_get_dialog_query(d->dialog_id, Auto()); } } @@ -17549,7 +17572,7 @@ void MessagesManager::send_update_new_message(Dialog *d, const Message *m, bool auto promise = PromiseCreator::lambda([actor_id = actor_id(this), dialog_id = d->dialog_id](Result result) { send_closure(actor_id, &MessagesManager::flush_pending_update_new_messages, dialog_id); }); - get_dialog_query(settings_dialog_id, std::move(promise)); // TODO use GetNotifySettingsQuery when possible + send_get_dialog_query(settings_dialog_id, std::move(promise)); // TODO use GetNotifySettingsQuery when possible return; } @@ -18419,7 +18442,7 @@ DialogId MessagesManager::search_public_dialog(const string &username_to_search, } else { const Dialog *d = get_dialog_force(dialog_id); if (d == nullptr || !d->notification_settings.is_synchronized) { - get_dialog_query(dialog_id, std::move(promise)); + send_get_dialog_query(dialog_id, std::move(promise)); return DialogId(); } } @@ -18440,7 +18463,7 @@ DialogId MessagesManager::search_public_dialog(const string &username_to_search, return DialogId(); } -void MessagesManager::get_dialog_query(DialogId dialog_id, Promise &&promise) { +void MessagesManager::send_get_dialog_query(DialogId dialog_id, Promise &&promise) { if (td_->auth_manager_->is_bot()) { return; } @@ -18541,7 +18564,7 @@ void MessagesManager::drop_username(const string &username) { auto dialog_id = it->second.dialog_id; if (have_input_peer(dialog_id, AccessRights::Read)) { CHECK(dialog_id.get_type() != DialogType::SecretChat); - get_dialog_query(dialog_id, Auto()); + send_get_dialog_query(dialog_id, Auto()); } resolved_usernames_.erase(it); @@ -22084,7 +22107,7 @@ void MessagesManager::force_create_dialog(DialogId dialog_id, const char *source if (have_input_peer(dialog_id, AccessRights::Read)) { if (dialog_id.get_type() != DialogType::SecretChat && !d->notification_settings.is_synchronized) { // asynchronously preload information about the dialog - get_dialog_query(dialog_id, Auto()); + send_get_dialog_query(dialog_id, Auto()); } } else { if (!have_dialog_info(dialog_id)) { diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 195bfa416..d60a79870 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -851,7 +851,7 @@ class MessagesManager : public Actor { vector> &&messages); void on_get_public_dialogs_search_result(const string &query, vector> &&peers); - void on_failed_public_dialogs_search(const string &query); + void on_failed_public_dialogs_search(const string &query, Status &&error); void on_get_dialog_messages_search_result(DialogId dialog_id, const string &query, UserId sender_user_id, MessageId from_message_id, int32 offset, int32 limit, @@ -2121,7 +2121,9 @@ class MessagesManager : public Actor { void on_get_dialogs_from_database(vector &&dialogs, Promise &&promise); - void get_dialog_query(DialogId dialog_id, Promise &&promise); + void send_get_dialog_query(DialogId dialog_id, Promise &&promise); + + void send_search_public_dialogs_query(const string &query, Promise &&promise); vector get_pinned_dialogs() const; @@ -2510,7 +2512,9 @@ class MessagesManager : public Actor { std::unordered_map>>, DialogIdHash> postponed_get_message_requests_; - std::unordered_map> found_public_dialogs_; // TODO time bound cache + std::unordered_map>> search_public_dialogs_queries_; + std::unordered_map> found_public_dialogs_; // TODO time bound cache + std::unordered_map, UserIdHash> found_common_dialogs_; // TODO time bound cache std::unordered_map get_dialog_message_by_date_results_;