From da979c4631095ff31ebcc85dc99f3a619a046976 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 19 Feb 2024 02:15:05 +0300 Subject: [PATCH] Move user_online_member_dialogs_ to DialogParticipantManager. --- td/telegram/ContactsManager.cpp | 91 +++-------------------- td/telegram/ContactsManager.h | 16 ++-- td/telegram/DialogParticipantManager.cpp | 94 +++++++++++++++++++++--- td/telegram/DialogParticipantManager.h | 14 +++- 4 files changed, 112 insertions(+), 103 deletions(-) diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index ff75f287a..7a042d873 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -3183,9 +3183,8 @@ ContactsManager::~ContactsManager() { Scheduler::instance()->destroy_on_scheduler( G()->get_gc_scheduler_id(), loaded_from_database_users_, unavailable_user_fulls_, loaded_from_database_chats_, unavailable_chat_fulls_, loaded_from_database_channels_, unavailable_channel_fulls_, - loaded_from_database_secret_chats_, user_online_member_dialogs_, cached_channel_participants_, - resolved_phone_numbers_, all_imported_contacts_, linked_channel_ids_, restricted_user_ids_, - restricted_channel_ids_); + loaded_from_database_secret_chats_, cached_channel_participants_, resolved_phone_numbers_, all_imported_contacts_, + linked_channel_ids_, restricted_user_ids_, restricted_channel_ids_); } void ContactsManager::start_up() { @@ -3246,7 +3245,7 @@ void ContactsManager::on_user_online_timeout(UserId user_id) { td_api::make_object(user_id.get(), get_user_status_object(user_id, u, G()->unix_time()))); - update_user_online_member_count(user_id); + td_->dialog_participant_manager_->update_user_online_member_count(user_id); } void ContactsManager::on_user_emoji_status_timeout_callback(void *contacts_manager_ptr, int64 user_id_long) { @@ -11184,7 +11183,7 @@ void ContactsManager::update_user(User *u, UserId user_id, bool from_binlog, boo u->is_status_changed = false; } if (u->is_online_status_changed) { - update_user_online_member_count(user_id); + td_->dialog_participant_manager_->update_user_online_member_count(user_id); u->is_online_status_changed = false; } @@ -13585,52 +13584,6 @@ void ContactsManager::drop_user_full(UserId user_id) { td_->group_call_manager_->on_update_dialog_about(DialogId(user_id), user_full->about, true); } -void ContactsManager::update_user_online_member_count(UserId user_id) { - if (td_->auth_manager_->is_bot()) { - return; - } - auto user_it = user_online_member_dialogs_.find(user_id); - if (user_it == user_online_member_dialogs_.end()) { - return; - } - CHECK(user_it->second != nullptr); - auto &online_member_dialogs = user_it->second->online_member_dialogs_; - - auto now = G()->unix_time(); - vector expired_dialog_ids; - for (const auto &it : online_member_dialogs) { - auto dialog_id = it.first; - auto time = it.second; - if (time < now - DialogParticipantManager::ONLINE_MEMBER_COUNT_CACHE_EXPIRE_TIME) { - expired_dialog_ids.push_back(dialog_id); - continue; - } - - switch (dialog_id.get_type()) { - case DialogType::Chat: - update_chat_online_member_count(dialog_id.get_chat_id(), false); - break; - case DialogType::Channel: - update_channel_online_member_count(dialog_id.get_channel_id(), false); - break; - case DialogType::User: - case DialogType::SecretChat: - case DialogType::None: - UNREACHABLE(); - break; - } - } - for (auto &dialog_id : expired_dialog_ids) { - online_member_dialogs.erase(dialog_id); - if (dialog_id.get_type() == DialogType::Channel) { - cached_channel_participants_.erase(dialog_id.get_channel_id()); - } - } - if (online_member_dialogs.empty()) { - user_online_member_dialogs_.erase(user_it); - } -} - void ContactsManager::update_chat_online_member_count(ChatId chat_id, bool is_from_server) { auto chat_full = get_chat_full(chat_id); if (chat_full != nullptr) { @@ -13639,7 +13592,8 @@ void ContactsManager::update_chat_online_member_count(ChatId chat_id, bool is_fr } void ContactsManager::update_chat_online_member_count(const ChatFull *chat_full, ChatId chat_id, bool is_from_server) { - update_dialog_online_member_count(chat_full->participants, DialogId(chat_id), is_from_server); + td_->dialog_participant_manager_->update_dialog_online_member_count(chat_full->participants, DialogId(chat_id), + is_from_server); } void ContactsManager::update_channel_online_member_count(ChannelId channel_id, bool is_from_server) { @@ -13652,38 +13606,11 @@ void ContactsManager::update_channel_online_member_count(ChannelId channel_id, b if (it == cached_channel_participants_.end()) { return; } - update_dialog_online_member_count(it->second, DialogId(channel_id), is_from_server); + td_->dialog_participant_manager_->update_dialog_online_member_count(it->second, DialogId(channel_id), is_from_server); } -void ContactsManager::update_dialog_online_member_count(const vector &participants, - DialogId dialog_id, bool is_from_server) { - if (td_->auth_manager_->is_bot()) { - return; - } - CHECK(dialog_id.is_valid()); - - int32 online_member_count = 0; - int32 unix_time = G()->unix_time(); - for (const auto &participant : participants) { - if (participant.dialog_id_.get_type() != DialogType::User) { - continue; - } - auto user_id = participant.dialog_id_.get_user_id(); - if (!is_user_deleted(user_id) && !is_user_bot(user_id)) { - if (is_user_online(user_id, 0, unix_time)) { - online_member_count++; - } - if (is_from_server) { - auto &online_member_dialogs = user_online_member_dialogs_[user_id]; - if (online_member_dialogs == nullptr) { - online_member_dialogs = make_unique(); - } - online_member_dialogs->online_member_dialogs_[dialog_id] = unix_time; - } - } - } - td_->dialog_participant_manager_->on_update_dialog_online_member_count(dialog_id, online_member_count, - is_from_server); +void ContactsManager::drop_cached_channel_participants(ChannelId channel_id) { + cached_channel_participants_.erase(channel_id); } void ContactsManager::on_get_chat_participants(tl_object_ptr &&participants_ptr, diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index 6d88fd05f..9d85ca0e6 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -353,6 +353,12 @@ class ContactsManager final : public Actor { static ChannelId get_unsupported_channel_id(); + void update_chat_online_member_count(ChatId chat_id, bool is_from_server); + + void update_channel_online_member_count(ChannelId channel_id, bool is_from_server); + + void drop_cached_channel_participants(ChannelId channel_id); + void on_update_username_is_active(UserId user_id, string &&username, bool is_active, Promise &&promise); void on_update_active_usernames_order(UserId user_id, vector &&usernames, Promise &&promise); @@ -1551,12 +1557,7 @@ class ContactsManager final : public Actor { void do_invalidate_channel_full(ChannelFull *channel_full, ChannelId channel_id, bool need_drop_slow_mode_delay); - void update_user_online_member_count(UserId user_id); - void update_chat_online_member_count(ChatId chat_id, bool is_from_server); void update_chat_online_member_count(const ChatFull *chat_full, ChatId chat_id, bool is_from_server); - void update_channel_online_member_count(ChannelId channel_id, bool is_from_server); - void update_dialog_online_member_count(const vector &participants, DialogId dialog_id, - bool is_from_server); void on_get_chat_empty(telegram_api::chatEmpty &chat, const char *source); void on_get_chat(telegram_api::chat &chat, const char *source); @@ -1980,11 +1981,6 @@ class ContactsManager final : public Actor { FlatHashMap, vector>> imported_contacts_; - struct UserOnlineMemberDialogs { - FlatHashMap online_member_dialogs_; // dialog_id -> time - }; - FlatHashMap, UserIdHash> user_online_member_dialogs_; - FlatHashMap, ChannelIdHash> cached_channel_participants_; FlatHashMap resolved_phone_numbers_; diff --git a/td/telegram/DialogParticipantManager.cpp b/td/telegram/DialogParticipantManager.cpp index 11d50dbf2..d357ca115 100644 --- a/td/telegram/DialogParticipantManager.cpp +++ b/td/telegram/DialogParticipantManager.cpp @@ -591,8 +591,8 @@ DialogParticipantManager::DialogParticipantManager(Td *td, ActorShared<> parent) } DialogParticipantManager::~DialogParticipantManager() { - Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), dialog_administrators_, - channel_participants_); + Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), user_online_member_dialogs_, + dialog_administrators_, channel_participants_); } void DialogParticipantManager::tear_down() { @@ -665,7 +665,7 @@ void DialogParticipantManager::on_update_dialog_online_member_count(DialogId dia } set_dialog_online_member_count(dialog_id, online_member_count, is_from_server, - "on_update_channel_online_member_count"); + "on_update_dialog_online_member_count"); } void DialogParticipantManager::on_dialog_opened(DialogId dialog_id) { @@ -753,15 +753,80 @@ void DialogParticipantManager::send_update_chat_online_member_count(DialogId dia td_->dialog_manager_->get_chat_id_object(dialog_id, "updateChatOnlineMemberCount"), online_member_count)); } -void DialogParticipantManager::get_current_state(vector> &updates) const { - for (const auto &it : dialog_online_member_counts_) { +void DialogParticipantManager::update_user_online_member_count(UserId user_id) { + if (td_->auth_manager_->is_bot()) { + return; + } + auto user_it = user_online_member_dialogs_.find(user_id); + if (user_it == user_online_member_dialogs_.end()) { + return; + } + CHECK(user_it->second != nullptr); + auto &online_member_dialogs = user_it->second->online_member_dialogs_; + + auto now = G()->unix_time(); + vector expired_dialog_ids; + for (const auto &it : online_member_dialogs) { auto dialog_id = it.first; - if (it.second.is_update_sent && td_->messages_manager_->is_dialog_opened(dialog_id)) { - updates.push_back(td_api::make_object( - td_->dialog_manager_->get_chat_id_object(dialog_id, "updateChatOnlineMemberCount"), - it.second.online_member_count)); + auto time = it.second; + if (time < now - ONLINE_MEMBER_COUNT_CACHE_EXPIRE_TIME) { + expired_dialog_ids.push_back(dialog_id); + continue; + } + + switch (dialog_id.get_type()) { + case DialogType::Chat: + td_->contacts_manager_->update_chat_online_member_count(dialog_id.get_chat_id(), false); + break; + case DialogType::Channel: + td_->contacts_manager_->update_channel_online_member_count(dialog_id.get_channel_id(), false); + break; + case DialogType::User: + case DialogType::SecretChat: + case DialogType::None: + UNREACHABLE(); + break; } } + for (auto &dialog_id : expired_dialog_ids) { + online_member_dialogs.erase(dialog_id); + if (dialog_id.get_type() == DialogType::Channel) { + td_->contacts_manager_->drop_cached_channel_participants(dialog_id.get_channel_id()); + } + } + if (online_member_dialogs.empty()) { + user_online_member_dialogs_.erase(user_it); + } +} + +void DialogParticipantManager::update_dialog_online_member_count(const vector &participants, + DialogId dialog_id, bool is_from_server) { + if (td_->auth_manager_->is_bot()) { + return; + } + CHECK(dialog_id.is_valid()); + + int32 online_member_count = 0; + int32 unix_time = G()->unix_time(); + for (const auto &participant : participants) { + if (participant.dialog_id_.get_type() != DialogType::User) { + continue; + } + auto user_id = participant.dialog_id_.get_user_id(); + if (!td_->contacts_manager_->is_user_deleted(user_id) && !td_->contacts_manager_->is_user_bot(user_id)) { + if (td_->contacts_manager_->is_user_online(user_id, 0, unix_time)) { + online_member_count++; + } + if (is_from_server) { + auto &online_member_dialogs = user_online_member_dialogs_[user_id]; + if (online_member_dialogs == nullptr) { + online_member_dialogs = make_unique(); + } + online_member_dialogs->online_member_dialogs_[dialog_id] = unix_time; + } + } + } + on_update_dialog_online_member_count(dialog_id, online_member_count, is_from_server); } Status DialogParticipantManager::can_manage_dialog_join_requests(DialogId dialog_id) { @@ -1994,4 +2059,15 @@ const DialogParticipant *DialogParticipantManager::get_channel_participant_from_ return nullptr; } +void DialogParticipantManager::get_current_state(vector> &updates) const { + for (const auto &it : dialog_online_member_counts_) { + auto dialog_id = it.first; + if (it.second.is_update_sent && td_->messages_manager_->is_dialog_opened(dialog_id)) { + updates.push_back(td_api::make_object( + td_->dialog_manager_->get_chat_id_object(dialog_id, "updateChatOnlineMemberCount"), + it.second.online_member_count)); + } + } +} + } // namespace td diff --git a/td/telegram/DialogParticipantManager.h b/td/telegram/DialogParticipantManager.h index 3201320ab..d46a7c75b 100644 --- a/td/telegram/DialogParticipantManager.h +++ b/td/telegram/DialogParticipantManager.h @@ -37,7 +37,10 @@ class DialogParticipantManager final : public Actor { DialogParticipantManager &operator=(DialogParticipantManager &&) = delete; ~DialogParticipantManager() final; - static constexpr int32 ONLINE_MEMBER_COUNT_CACHE_EXPIRE_TIME = 30 * 60; + void update_user_online_member_count(UserId user_id); + + void update_dialog_online_member_count(const vector &participants, DialogId dialog_id, + bool is_from_server); void on_update_dialog_online_member_count(DialogId dialog_id, int32 online_member_count, bool is_from_server); @@ -114,12 +117,14 @@ class DialogParticipantManager final : public Actor { void get_current_state(vector> &updates) const; private: - void tear_down() final; + static constexpr int32 ONLINE_MEMBER_COUNT_CACHE_EXPIRE_TIME = 30 * 60; static constexpr int32 ONLINE_MEMBER_COUNT_UPDATE_TIME = 5 * 60; static constexpr int32 CHANNEL_PARTICIPANT_CACHE_TIME = 1800; // some reasonable limit + void tear_down() final; + static void on_update_dialog_online_member_count_timeout_callback(void *dialog_participant_manager_ptr, int64 dialog_id_int); @@ -203,6 +208,11 @@ class DialogParticipantManager final : public Actor { }; FlatHashMap dialog_online_member_counts_; + struct UserOnlineMemberDialogs { + FlatHashMap online_member_dialogs_; // dialog_id -> time + }; + FlatHashMap, UserIdHash> user_online_member_dialogs_; + FlatHashMap, DialogIdHash> dialog_administrators_; // bot-administrators only