Invalidate cache of getGroupsInCommon when count is changed or in 1 hour.
GitOrigin-RevId: e57edb01d3fe3a21e208e8247ca666284a755bcb
This commit is contained in:
parent
8b174198d9
commit
606b427673
@ -2756,7 +2756,7 @@ checkChatUsername chat_id:int53 username:string = CheckChatUsernameResult;
|
||||
getCreatedPublicChats = Chats;
|
||||
|
||||
|
||||
//@description Returns a list of common chats with a given user. Chats are sorted by their type and creation date @user_id User identifier @offset_chat_id Chat identifier starting from which to return chats; use 0 for the first request @limit Maximum number of chats to be returned; up to 100
|
||||
//@description Returns a list of common group chats with a given user. Chats are sorted by their type and creation date @user_id User identifier @offset_chat_id Chat identifier starting from which to return chats; use 0 for the first request @limit Maximum number of chats to be returned; up to 100
|
||||
getGroupsInCommon user_id:int32 offset_chat_id:int53 limit:int32 = Chats;
|
||||
|
||||
|
||||
|
@ -6404,6 +6404,10 @@ void ContactsManager::update_secret_chat(SecretChat *c, SecretChatId secret_chat
|
||||
|
||||
void ContactsManager::update_user_full(UserFull *user_full, UserId user_id) {
|
||||
CHECK(user_full != nullptr);
|
||||
if (user_full->is_common_chat_count_changed) {
|
||||
td_->messages_manager_->drop_common_dialogs_cache(user_id);
|
||||
user_full->is_common_chat_count_changed = false;
|
||||
}
|
||||
if (user_full->is_changed) {
|
||||
user_full->is_changed = false;
|
||||
if (user_full->is_inited) {
|
||||
@ -6487,15 +6491,15 @@ void ContactsManager::on_get_user_full(tl_object_ptr<telegram_api::userFull> &&u
|
||||
user->is_inited = true;
|
||||
|
||||
on_update_user_full_is_blocked(user, user_id, (user_full->flags_ & USER_FULL_FLAG_IS_BLOCKED) != 0);
|
||||
on_update_user_full_common_chat_count(user, user_id, user_full->common_chats_count_);
|
||||
|
||||
bool can_be_called = user_full->phone_calls_available_ && !user_full->phone_calls_private_;
|
||||
bool has_private_calls = user_full->phone_calls_private_;
|
||||
if (user->can_be_called != can_be_called || user->has_private_calls != has_private_calls ||
|
||||
user->about != user_full->about_ || user->common_chat_count != user_full->common_chats_count_) {
|
||||
user->about != user_full->about_) {
|
||||
user->can_be_called = can_be_called;
|
||||
user->has_private_calls = has_private_calls;
|
||||
user->about = std::move(user_full->about_);
|
||||
user->common_chat_count = user_full->common_chats_count_;
|
||||
|
||||
user->is_changed = true;
|
||||
}
|
||||
@ -7091,6 +7095,31 @@ void ContactsManager::on_update_user_full_is_blocked(UserFull *user_full, UserId
|
||||
}
|
||||
}
|
||||
|
||||
void ContactsManager::on_update_user_common_chat_count(UserId user_id, int32 common_chat_count) {
|
||||
LOG(INFO) << "Receive " << common_chat_count << " common chat count with " << user_id;
|
||||
if (!user_id.is_valid()) {
|
||||
LOG(ERROR) << "Receive invalid " << user_id;
|
||||
return;
|
||||
}
|
||||
|
||||
UserFull *user_full = get_user_full(user_id);
|
||||
if (user_full == nullptr) {
|
||||
return;
|
||||
}
|
||||
on_update_user_full_common_chat_count(user_full, user_id, common_chat_count);
|
||||
update_user_full(user_full, user_id);
|
||||
}
|
||||
|
||||
void ContactsManager::on_update_user_full_common_chat_count(UserFull *user_full, UserId user_id,
|
||||
int32 common_chat_count) {
|
||||
CHECK(user_full != nullptr);
|
||||
if (user_full->is_inited && user_full->common_chat_count != common_chat_count) {
|
||||
user_full->common_chat_count = common_chat_count;
|
||||
user_full->is_common_chat_count_changed = true;
|
||||
user_full->is_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ContactsManager::on_delete_profile_photo(int64 profile_photo_id, Promise<Unit> promise) {
|
||||
UserId my_id = get_my_id();
|
||||
|
||||
|
@ -157,6 +157,7 @@ class ContactsManager : public Actor {
|
||||
void on_update_user_links(UserId user_id, tl_object_ptr<telegram_api::ContactLink> &&outbound,
|
||||
tl_object_ptr<telegram_api::ContactLink> &&inbound);
|
||||
void on_update_user_blocked(UserId user_id, bool is_blocked);
|
||||
void on_update_user_common_chat_count(UserId user_id, int32 common_chat_count);
|
||||
|
||||
void on_delete_profile_photo(int64 profile_photo_id, Promise<Unit> promise);
|
||||
|
||||
@ -547,6 +548,7 @@ class ContactsManager : public Actor {
|
||||
bool can_be_called = false;
|
||||
bool has_private_calls = false;
|
||||
|
||||
bool is_common_chat_count_changed = true;
|
||||
bool is_changed = true;
|
||||
|
||||
double expires_at = 0.0;
|
||||
@ -873,6 +875,7 @@ class ContactsManager : public Actor {
|
||||
void add_user_photo_id(User *u, UserId user_id, int64 photo_id, const vector<FileId> &photo_file_ids);
|
||||
|
||||
void on_update_user_full_is_blocked(UserFull *user_full, UserId user_id, bool is_blocked);
|
||||
void on_update_user_full_common_chat_count(UserFull *user_full, UserId user_id, int32 common_chat_count);
|
||||
bool on_update_user_full_bot_info(UserFull *user_full, UserId user_id, int32 bot_info_version,
|
||||
tl_object_ptr<telegram_api::botInfo> &&bot_info);
|
||||
void invalidate_user_full(UserId user_id);
|
||||
|
@ -484,6 +484,7 @@ class SearchPublicDialogsQuery : public Td::ResultHandler {
|
||||
class GetCommonDialogsQuery : public Td::ResultHandler {
|
||||
Promise<Unit> promise_;
|
||||
UserId user_id_;
|
||||
int32 offset_chat_id_ = 0;
|
||||
|
||||
public:
|
||||
explicit GetCommonDialogsQuery(Promise<Unit> &&promise) : promise_(std::move(promise)) {
|
||||
@ -491,6 +492,7 @@ class GetCommonDialogsQuery : public Td::ResultHandler {
|
||||
|
||||
void send(UserId user_id, int32 offset_chat_id, int32 limit) {
|
||||
user_id_ = user_id;
|
||||
offset_chat_id_ = offset_chat_id;
|
||||
LOG(INFO) << "Get common dialogs with " << user_id << " from " << offset_chat_id << " with limit " << limit;
|
||||
|
||||
auto input_user = td->contacts_manager_->get_input_user(user_id);
|
||||
@ -512,13 +514,14 @@ class GetCommonDialogsQuery : public Td::ResultHandler {
|
||||
switch (constructor_id) {
|
||||
case telegram_api::messages_chats::ID: {
|
||||
auto chats = move_tl_object_as<telegram_api::messages_chats>(chats_ptr);
|
||||
td->messages_manager_->on_get_common_dialogs(user_id_, std::move(chats->chats_),
|
||||
td->messages_manager_->on_get_common_dialogs(user_id_, offset_chat_id_, std::move(chats->chats_),
|
||||
narrow_cast<int32>(chats->chats_.size()));
|
||||
break;
|
||||
}
|
||||
case telegram_api::messages_chatsSlice::ID: {
|
||||
auto chats = move_tl_object_as<telegram_api::messages_chatsSlice>(chats_ptr);
|
||||
td->messages_manager_->on_get_common_dialogs(user_id_, std::move(chats->chats_), chats->count_);
|
||||
td->messages_manager_->on_get_common_dialogs(user_id_, offset_chat_id_, std::move(chats->chats_),
|
||||
chats->count_);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -11681,6 +11684,13 @@ vector<DialogId> MessagesManager::search_dialogs_on_server(const string &query,
|
||||
return vector<DialogId>();
|
||||
}
|
||||
|
||||
void MessagesManager::drop_common_dialogs_cache(UserId user_id) {
|
||||
auto it = found_common_dialogs_.find(user_id);
|
||||
if (it != found_common_dialogs_.end()) {
|
||||
it->second.is_outdated = true;
|
||||
}
|
||||
}
|
||||
|
||||
vector<DialogId> MessagesManager::get_common_dialogs(UserId user_id, DialogId offset_dialog_id, int32 limit, bool force,
|
||||
Promise<Unit> &&promise) {
|
||||
if (!td_->contacts_manager_->have_input_user(user_id)) {
|
||||
@ -11723,42 +11733,58 @@ vector<DialogId> MessagesManager::get_common_dialogs(UserId user_id, DialogId of
|
||||
}
|
||||
|
||||
auto it = found_common_dialogs_.find(user_id);
|
||||
if (it != found_common_dialogs_.end() && !it->second.empty()) {
|
||||
vector<DialogId> &common_dialog_ids = it->second;
|
||||
auto offset_it = common_dialog_ids.begin();
|
||||
if (offset_dialog_id != DialogId()) {
|
||||
offset_it = std::find(common_dialog_ids.begin(), common_dialog_ids.end(), offset_dialog_id);
|
||||
if (offset_it == common_dialog_ids.end()) {
|
||||
promise.set_error(Status::Error(6, "Wrong offset_chat_id"));
|
||||
return vector<DialogId>();
|
||||
if (it != found_common_dialogs_.end() && !it->second.dialog_ids.empty()) {
|
||||
vector<DialogId> &common_dialog_ids = it->second.dialog_ids;
|
||||
bool use_cache = (!it->second.is_outdated && it->second.received_date >= Time::now() - 3600) || force ||
|
||||
offset_chat_id != 0 || common_dialog_ids.size() >= static_cast<size_t>(MAX_GET_DIALOGS);
|
||||
// use cache if it's up to date, or we required to use it or we can't update it
|
||||
if (use_cache) {
|
||||
auto offset_it = common_dialog_ids.begin();
|
||||
if (offset_dialog_id != DialogId()) {
|
||||
offset_it = std::find(common_dialog_ids.begin(), common_dialog_ids.end(), offset_dialog_id);
|
||||
if (offset_it == common_dialog_ids.end()) {
|
||||
promise.set_error(Status::Error(6, "Wrong offset_chat_id"));
|
||||
return vector<DialogId>();
|
||||
}
|
||||
++offset_it;
|
||||
}
|
||||
++offset_it;
|
||||
}
|
||||
vector<DialogId> result;
|
||||
while (result.size() < static_cast<size_t>(limit)) {
|
||||
if (offset_it == common_dialog_ids.end()) {
|
||||
break;
|
||||
vector<DialogId> result;
|
||||
while (result.size() < static_cast<size_t>(limit)) {
|
||||
if (offset_it == common_dialog_ids.end()) {
|
||||
break;
|
||||
}
|
||||
auto dialog_id = *offset_it++;
|
||||
if (dialog_id == DialogId()) { // end of the list
|
||||
promise.set_value(Unit());
|
||||
return result;
|
||||
}
|
||||
result.push_back(dialog_id);
|
||||
}
|
||||
auto dialog_id = *offset_it++;
|
||||
if (dialog_id == DialogId()) { // end of the list
|
||||
if (result.size() == static_cast<size_t>(limit) || force) {
|
||||
promise.set_value(Unit());
|
||||
return result;
|
||||
}
|
||||
result.push_back(dialog_id);
|
||||
}
|
||||
if (result.size() == static_cast<size_t>(limit) || force) {
|
||||
promise.set_value(Unit());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
td_->create_handler<GetCommonDialogsQuery>(std::move(promise))->send(user_id, offset_chat_id, limit);
|
||||
td_->create_handler<GetCommonDialogsQuery>(std::move(promise))->send(user_id, offset_chat_id, MAX_GET_DIALOGS);
|
||||
return vector<DialogId>();
|
||||
}
|
||||
|
||||
void MessagesManager::on_get_common_dialogs(UserId user_id, vector<tl_object_ptr<telegram_api::Chat>> &&chats,
|
||||
int32 total_count) {
|
||||
auto &result = found_common_dialogs_[user_id];
|
||||
void MessagesManager::on_get_common_dialogs(UserId user_id, int32 offset_chat_id,
|
||||
vector<tl_object_ptr<telegram_api::Chat>> &&chats, int32 total_count) {
|
||||
td_->contacts_manager_->on_update_user_common_chat_count(user_id, total_count);
|
||||
|
||||
auto &common_dialogs = found_common_dialogs_[user_id];
|
||||
if (common_dialogs.is_outdated && offset_chat_id == 0 && common_dialogs.dialog_ids.size() < static_cast<size_t>(MAX_GET_DIALOGS)) {
|
||||
// drop outdated cache if possible
|
||||
common_dialogs = CommonDialogs();
|
||||
}
|
||||
if (common_dialogs.received_date == 0) {
|
||||
common_dialogs.received_date = Time::now();
|
||||
}
|
||||
common_dialogs.is_outdated = false;
|
||||
auto &result = common_dialogs.dialog_ids;
|
||||
if (!result.empty() && result.back() == DialogId()) {
|
||||
return;
|
||||
}
|
||||
|
@ -266,7 +266,8 @@ class MessagesManager : public Actor {
|
||||
void on_get_dialogs(vector<tl_object_ptr<telegram_api::dialog>> &&dialogs, int32 total_count,
|
||||
vector<tl_object_ptr<telegram_api::Message>> &&messages, Promise<Unit> &&promise);
|
||||
|
||||
void on_get_common_dialogs(UserId user_id, vector<tl_object_ptr<telegram_api::Chat>> &&chats, int32 total_count);
|
||||
void on_get_common_dialogs(UserId user_id, int32 offset_chat_id, vector<tl_object_ptr<telegram_api::Chat>> &&chats,
|
||||
int32 total_count);
|
||||
|
||||
bool on_update_message_id(int64 random_id, MessageId new_message_id, const string &source);
|
||||
|
||||
@ -465,6 +466,8 @@ class MessagesManager : public Actor {
|
||||
|
||||
vector<DialogId> search_dialogs_on_server(const string &query, int32 limit, Promise<Unit> &&promise);
|
||||
|
||||
void drop_common_dialogs_cache(UserId user_id);
|
||||
|
||||
vector<DialogId> get_common_dialogs(UserId user_id, DialogId offset_dialog_id, int32 limit, bool force,
|
||||
Promise<Unit> &&promise);
|
||||
|
||||
@ -2239,7 +2242,12 @@ class MessagesManager : public Actor {
|
||||
std::unordered_map<string, vector<DialogId>> found_public_dialogs_; // TODO time bound cache
|
||||
std::unordered_map<string, vector<DialogId>> found_on_server_dialogs_; // TODO time bound cache
|
||||
|
||||
std::unordered_map<UserId, vector<DialogId>, UserIdHash> found_common_dialogs_; // TODO time bound cache
|
||||
struct CommonDialogs {
|
||||
vector<DialogId> dialog_ids;
|
||||
double received_date = 0;
|
||||
bool is_outdated = false;
|
||||
};
|
||||
std::unordered_map<UserId, CommonDialogs, UserIdHash> found_common_dialogs_;
|
||||
|
||||
std::unordered_map<int64, FullMessageId> get_dialog_message_by_date_results_;
|
||||
|
||||
|
Reference in New Issue
Block a user