From 1b9a8cc6fe05047d5a117531ddf146e2930d148d Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 27 Oct 2022 14:58:21 +0300 Subject: [PATCH] Add ForumTopicInfo cache. --- td/telegram/ForumTopicManager.cpp | 45 +++++++++++++++++++++++++------ td/telegram/ForumTopicManager.h | 13 ++++++++- 2 files changed, 49 insertions(+), 9 deletions(-) diff --git a/td/telegram/ForumTopicManager.cpp b/td/telegram/ForumTopicManager.cpp index 8ec773236..a2e2107f1 100644 --- a/td/telegram/ForumTopicManager.cpp +++ b/td/telegram/ForumTopicManager.cpp @@ -85,13 +85,15 @@ class CreateForumTopicQuery final : public Td::ResultHandler { } auto action = static_cast(service_message->action_.get()); - ForumTopicInfo forum_topic_info(MessageId(ServerMessageId(service_message->id_)), action->title_, - ForumTopicIcon(action->icon_color_, action->icon_emoji_id_), service_message->date_, - creator_dialog_id_, true, false); + auto forum_topic_info = + td::make_unique(MessageId(ServerMessageId(service_message->id_)), action->title_, + ForumTopicIcon(action->icon_color_, action->icon_emoji_id_), + service_message->date_, creator_dialog_id_, true, false); td_->updates_manager_->on_get_updates( - std::move(ptr), PromiseCreator::lambda([forum_topic_info = std::move(forum_topic_info), - promise = std::move(promise_)](Unit result) mutable { - send_closure(G()->forum_topic_manager(), &ForumTopicManager::on_forum_topic_created, + std::move(ptr), + PromiseCreator::lambda([dialog_id = DialogId(channel_id_), forum_topic_info = std::move(forum_topic_info), + promise = std::move(promise_)](Unit result) mutable { + send_closure(G()->forum_topic_manager(), &ForumTopicManager::on_forum_topic_created, dialog_id, std::move(forum_topic_info), std::move(promise)); })); } @@ -142,11 +144,22 @@ void ForumTopicManager::create_forum_topic(DialogId dialog_id, string &&title, ->send(channel_id, new_title, icon_color, icon_custom_emoji_id, as_dialog_id); } -void ForumTopicManager::on_forum_topic_created(ForumTopicInfo &&forum_topic_info, +void ForumTopicManager::on_forum_topic_created(DialogId dialog_id, unique_ptr &&forum_topic_info, Promise> &&promise) { TRY_STATUS_PROMISE(promise, G()->close_status()); - promise.set_value(forum_topic_info.get_forum_topic_info_object(td_)); + MessageId top_thread_message_id = forum_topic_info->get_thread_id(); + auto topic_info = get_topic_info(dialog_id, top_thread_message_id); + if (topic_info == nullptr) { + if (dialog_topics_.get_pointer(dialog_id) == nullptr) { + dialog_topics_.set(dialog_id, make_unique()); + } + dialog_topics_.get_pointer(dialog_id)->topic_infos_.set(top_thread_message_id, std::move(forum_topic_info)); + topic_info = get_topic_info(dialog_id, top_thread_message_id); + CHECK(topic_info != nullptr); + } + + promise.set_value(topic_info->get_forum_topic_info_object(td_)); } Status ForumTopicManager::is_forum(DialogId dialog_id) { @@ -160,4 +173,20 @@ Status ForumTopicManager::is_forum(DialogId dialog_id) { return Status::OK(); } +ForumTopicInfo *ForumTopicManager::get_topic_info(DialogId dialog_id, MessageId top_thread_message_id) { + auto *dialog_info = dialog_topics_.get_pointer(dialog_id); + if (dialog_info == nullptr) { + return nullptr; + } + return dialog_info->topic_infos_.get_pointer(top_thread_message_id); +} + +const ForumTopicInfo *ForumTopicManager::get_topic_info(DialogId dialog_id, MessageId top_thread_message_id) const { + auto *dialog_info = dialog_topics_.get_pointer(dialog_id); + if (dialog_info == nullptr) { + return nullptr; + } + return dialog_info->topic_infos_.get_pointer(top_thread_message_id); +} + } // namespace td diff --git a/td/telegram/ForumTopicManager.h b/td/telegram/ForumTopicManager.h index e2e0393a1..ae4ee50dd 100644 --- a/td/telegram/ForumTopicManager.h +++ b/td/telegram/ForumTopicManager.h @@ -14,6 +14,7 @@ #include "td/utils/common.h" #include "td/utils/Promise.h" +#include "td/utils/WaitFreeHashMap.h" namespace td { @@ -31,18 +32,28 @@ class ForumTopicManager final : public Actor { void create_forum_topic(DialogId dialog_id, string &&title, td_api::object_ptr &&icon, Promise> &&promise); - void on_forum_topic_created(ForumTopicInfo &&forum_topic_info, + void on_forum_topic_created(DialogId dialog_id, unique_ptr &&forum_topic_info, Promise> &&promise); private: static constexpr size_t MAX_FORUM_TOPIC_TITLE_LENGTH = 128; // server side limit for forum topic title + struct DialogTopics { + WaitFreeHashMap, MessageIdHash> topic_infos_; + }; + void tear_down() final; Status is_forum(DialogId dialog_id); + ForumTopicInfo *get_topic_info(DialogId dialog_id, MessageId top_thread_message_id); + + const ForumTopicInfo *get_topic_info(DialogId dialog_id, MessageId top_thread_message_id) const; + Td *td_; ActorShared<> parent_; + + WaitFreeHashMap, DialogIdHash> dialog_topics_; }; } // namespace td