Move cached_channel_participants_ to DialogParticipantManager.

This commit is contained in:
levlam 2024-03-04 03:16:20 +03:00
parent b788136508
commit d66e3657a3
4 changed files with 126 additions and 89 deletions

View File

@ -2942,8 +2942,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_, cached_channel_participants_, resolved_phone_numbers_, all_imported_contacts_,
linked_channel_ids_, restricted_user_ids_, restricted_channel_ids_);
loaded_from_database_secret_chats_, resolved_phone_numbers_, all_imported_contacts_, linked_channel_ids_,
restricted_user_ids_, restricted_channel_ids_);
}
void ContactsManager::start_up() {
@ -13062,27 +13062,6 @@ void ContactsManager::update_chat_online_member_count(const ChatFull *chat_full,
is_from_server);
}
void ContactsManager::update_channel_online_member_count(ChannelId channel_id, bool is_from_server) {
if (!is_megagroup_channel(channel_id) ||
get_channel_effective_has_hidden_participants(channel_id, "update_channel_online_member_count")) {
return;
}
auto it = cached_channel_participants_.find(channel_id);
if (it == cached_channel_participants_.end()) {
return;
}
td_->dialog_participant_manager_->update_dialog_online_member_count(it->second, DialogId(channel_id), is_from_server);
}
void ContactsManager::set_cached_channel_participants(ChannelId channel_id, vector<DialogParticipant> participants) {
cached_channel_participants_[channel_id] = std::move(participants);
}
void ContactsManager::drop_cached_channel_participants(ChannelId channel_id) {
cached_channel_participants_.erase(channel_id);
}
void ContactsManager::on_get_chat_participants(tl_object_ptr<telegram_api::ChatParticipants> &&participants_ptr,
bool from_update) {
switch (participants_ptr->get_id()) {
@ -13292,9 +13271,8 @@ bool ContactsManager::speculative_add_count(int32 &count, int32 delta_count, int
void ContactsManager::speculative_add_channel_participants(ChannelId channel_id, const vector<UserId> &added_user_ids,
UserId inviter_user_id, int32 date, bool by_me) {
auto it = cached_channel_participants_.find(channel_id);
td_->dialog_participant_manager_->add_cached_channel_participants(channel_id, added_user_ids, inviter_user_id, date);
auto channel_full = get_channel_full_force(channel_id, true, "speculative_add_channel_participants");
bool is_participants_cache_changed = false;
int32 delta_participant_count = 0;
for (auto user_id : added_user_ids) {
@ -13303,22 +13281,6 @@ void ContactsManager::speculative_add_channel_participants(ChannelId channel_id,
}
delta_participant_count++;
if (it != cached_channel_participants_.end()) {
auto &participants = it->second;
bool is_found = false;
for (auto &participant : participants) {
if (participant.dialog_id_ == DialogId(user_id)) {
is_found = true;
break;
}
}
if (!is_found) {
is_participants_cache_changed = true;
participants.emplace_back(DialogId(user_id), inviter_user_id, date, DialogParticipantStatus::Member());
}
}
if (channel_full != nullptr && is_user_bot(user_id) && !td::contains(channel_full->bot_user_ids, user_id)) {
channel_full->bot_user_ids.push_back(user_id);
channel_full->need_save_to_database = true;
@ -13328,9 +13290,6 @@ void ContactsManager::speculative_add_channel_participants(ChannelId channel_id,
channel_full->bot_user_ids, false);
}
}
if (is_participants_cache_changed) {
update_channel_online_member_count(channel_id, false);
}
if (channel_full != nullptr) {
if (channel_full->is_changed) {
channel_full->speculative_version++;
@ -13349,17 +13308,7 @@ void ContactsManager::speculative_delete_channel_participant(ChannelId channel_i
return;
}
auto it = cached_channel_participants_.find(channel_id);
if (it != cached_channel_participants_.end()) {
auto &participants = it->second;
for (size_t i = 0; i < participants.size(); i++) {
if (participants[i].dialog_id_ == DialogId(deleted_user_id)) {
participants.erase(participants.begin() + i);
update_channel_online_member_count(channel_id, false);
break;
}
}
}
td_->dialog_participant_manager_->delete_cached_channel_participant(channel_id, deleted_user_id);
if (is_user_bot(deleted_user_id)) {
auto channel_full = get_channel_full_force(channel_id, true, "speculative_delete_channel_participant");
@ -13429,27 +13378,7 @@ void ContactsManager::speculative_add_channel_user(ChannelId channel_id, UserId
update_channel(c, channel_id);
}
auto it = cached_channel_participants_.find(channel_id);
if (it != cached_channel_participants_.end()) {
auto &participants = it->second;
bool is_found = false;
for (size_t i = 0; i < participants.size(); i++) {
if (participants[i].dialog_id_ == DialogId(user_id)) {
if (!new_status.is_member()) {
participants.erase(participants.begin() + i);
update_channel_online_member_count(channel_id, false);
} else {
participants[i].status_ = new_status;
}
is_found = true;
break;
}
}
if (!is_found && new_status.is_member()) {
participants.emplace_back(DialogId(user_id), get_my_id(), G()->unix_time(), new_status);
update_channel_online_member_count(channel_id, false);
}
}
td_->dialog_participant_manager_->update_cached_channel_participant_status(channel_id, user_id, new_status);
if (channel_full == nullptr) {
return;

View File

@ -354,14 +354,8 @@ class ContactsManager final : public Actor {
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 on_update_channel_bot_user_ids(ChannelId channel_id, vector<UserId> &&bot_user_ids);
void set_cached_channel_participants(ChannelId channel_id, vector<DialogParticipant> participants);
void drop_cached_channel_participants(ChannelId channel_id);
void on_update_username_is_active(UserId user_id, string &&username, bool is_active, Promise<Unit> &&promise);
void on_update_active_usernames_order(UserId user_id, vector<string> &&usernames, Promise<Unit> &&promise);
@ -1930,8 +1924,6 @@ class ContactsManager final : public Actor {
FlatHashMap<int64, std::pair<vector<UserId>, vector<int32>>> imported_contacts_;
FlatHashMap<ChannelId, vector<DialogParticipant>, ChannelIdHash> cached_channel_participants_;
FlatHashMap<string, UserId> resolved_phone_numbers_;
FlatHashMap<UserId, FlatHashSet<MessageFullId, MessageFullIdHash>, UserIdHash> user_messages_;

View File

@ -836,7 +836,8 @@ DialogParticipantManager::DialogParticipantManager(Td *td, ActorShared<> parent)
DialogParticipantManager::~DialogParticipantManager() {
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), user_online_member_dialogs_,
dialog_administrators_, channel_participants_);
dialog_administrators_, channel_participants_,
cached_channel_participants_);
}
void DialogParticipantManager::tear_down() {
@ -1022,7 +1023,7 @@ void DialogParticipantManager::update_user_online_member_count(UserId user_id) {
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);
update_channel_online_member_count(dialog_id.get_channel_id(), false);
break;
case DialogType::User:
case DialogType::SecretChat:
@ -1034,7 +1035,7 @@ void DialogParticipantManager::update_user_online_member_count(UserId user_id) {
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());
drop_cached_channel_participants(dialog_id.get_channel_id());
}
}
if (online_member_dialogs.empty()) {
@ -1042,6 +1043,20 @@ void DialogParticipantManager::update_user_online_member_count(UserId user_id) {
}
}
void DialogParticipantManager::update_channel_online_member_count(ChannelId channel_id, bool is_from_server) {
if (!td_->contacts_manager_->is_megagroup_channel(channel_id) ||
td_->contacts_manager_->get_channel_effective_has_hidden_participants(channel_id,
"update_channel_online_member_count")) {
return;
}
auto it = cached_channel_participants_.find(channel_id);
if (it == cached_channel_participants_.end()) {
return;
}
update_dialog_online_member_count(it->second, DialogId(channel_id), is_from_server);
}
void DialogParticipantManager::update_dialog_online_member_count(const vector<DialogParticipant> &participants,
DialogId dialog_id, bool is_from_server) {
if (td_->auth_manager_->is_bot()) {
@ -1873,8 +1888,8 @@ void DialogParticipantManager::on_get_channel_participants(
administrator_count = narrow_cast<int32>(administrators.size());
if (is_megagroup && !td_->auth_manager_->is_bot() && is_full_recent) {
td_->contacts_manager_->set_cached_channel_participants(channel_id, result);
td_->contacts_manager_->update_channel_online_member_count(channel_id, true);
set_cached_channel_participants(channel_id, result);
update_channel_online_member_count(channel_id, true);
}
} else if (filter.is_administrators()) {
for (const auto &participant : result) {
@ -2780,6 +2795,91 @@ const DialogParticipant *DialogParticipantManager::get_channel_participant_from_
return nullptr;
}
void DialogParticipantManager::set_cached_channel_participants(ChannelId channel_id,
vector<DialogParticipant> participants) {
cached_channel_participants_[channel_id] = std::move(participants);
}
void DialogParticipantManager::drop_cached_channel_participants(ChannelId channel_id) {
cached_channel_participants_.erase(channel_id);
}
void DialogParticipantManager::add_cached_channel_participants(ChannelId channel_id,
const vector<UserId> &added_user_ids,
UserId inviter_user_id, int32 date) {
auto it = cached_channel_participants_.find(channel_id);
if (it == cached_channel_participants_.end()) {
return;
}
auto &participants = it->second;
bool is_participants_cache_changed = false;
for (auto user_id : added_user_ids) {
if (!user_id.is_valid()) {
continue;
}
bool is_found = false;
for (const auto &participant : participants) {
if (participant.dialog_id_ == DialogId(user_id)) {
is_found = true;
break;
}
}
if (!is_found) {
is_participants_cache_changed = true;
participants.emplace_back(DialogId(user_id), inviter_user_id, date, DialogParticipantStatus::Member());
}
}
if (is_participants_cache_changed) {
update_channel_online_member_count(channel_id, false);
}
}
void DialogParticipantManager::delete_cached_channel_participant(ChannelId channel_id, UserId deleted_user_id) {
if (!deleted_user_id.is_valid()) {
return;
}
auto it = cached_channel_participants_.find(channel_id);
if (it == cached_channel_participants_.end()) {
return;
}
auto &participants = it->second;
for (size_t i = 0; i < participants.size(); i++) {
if (participants[i].dialog_id_ == DialogId(deleted_user_id)) {
participants.erase(participants.begin() + i);
update_channel_online_member_count(channel_id, false);
break;
}
}
}
void DialogParticipantManager::update_cached_channel_participant_status(ChannelId channel_id, UserId user_id,
const DialogParticipantStatus &status) {
auto it = cached_channel_participants_.find(channel_id);
if (it == cached_channel_participants_.end()) {
return;
}
auto &participants = it->second;
bool is_found = false;
for (size_t i = 0; i < participants.size(); i++) {
if (participants[i].dialog_id_ == DialogId(user_id)) {
if (!status.is_member()) {
participants.erase(participants.begin() + i);
update_channel_online_member_count(channel_id, false);
} else {
participants[i].status_ = status;
}
is_found = true;
break;
}
}
if (!is_found && status.is_member()) {
participants.emplace_back(DialogId(user_id), td_->contacts_manager_->get_my_id(), G()->unix_time(), status);
update_channel_online_member_count(channel_id, false);
}
}
void DialogParticipantManager::can_transfer_ownership(Promise<CanTransferOwnershipResult> &&promise) {
auto request_promise = PromiseCreator::lambda([promise = std::move(promise)](Result<Unit> r_result) mutable {
CHECK(r_result.is_error());

View File

@ -49,6 +49,14 @@ class DialogParticipantManager final : public Actor {
void on_update_dialog_online_member_count(DialogId dialog_id, int32 online_member_count, bool is_from_server);
void add_cached_channel_participants(ChannelId channel_id, const vector<UserId> &added_user_ids,
UserId inviter_user_id, int32 date);
void delete_cached_channel_participant(ChannelId channel_id, UserId deleted_user_id);
void update_cached_channel_participant_status(ChannelId channel_id, UserId user_id,
const DialogParticipantStatus &status);
void on_dialog_opened(DialogId dialog_id);
void on_dialog_closed(DialogId dialog_id);
@ -254,6 +262,12 @@ class DialogParticipantManager final : public Actor {
void on_channel_participant_cache_timeout(ChannelId channel_id);
void set_cached_channel_participants(ChannelId channel_id, vector<DialogParticipant> participants);
void drop_cached_channel_participants(ChannelId channel_id);
void update_channel_online_member_count(ChannelId channel_id, bool is_from_server);
void transfer_channel_ownership(ChannelId channel_id, UserId user_id,
tl_object_ptr<telegram_api::InputCheckPasswordSRP> input_check_password,
Promise<Unit> &&promise);
@ -283,6 +297,8 @@ class DialogParticipantManager final : public Actor {
};
FlatHashMap<ChannelId, ChannelParticipants, ChannelIdHash> channel_participants_;
FlatHashMap<ChannelId, vector<DialogParticipant>, ChannelIdHash> cached_channel_participants_;
FlatHashMap<ChannelId, vector<Promise<Unit>>, ChannelIdHash> join_channel_queries_;
MultiTimeout update_dialog_online_member_count_timeout_{"UpdateDialogOnlineMemberCountTimeout"};