Use FlatHashSet.

This commit is contained in:
levlam 2022-03-11 21:38:48 +03:00
parent 8b16cf7271
commit 1f38124861
40 changed files with 247 additions and 170 deletions

View File

@ -20,10 +20,10 @@
#include "td/utils/common.h" #include "td/utils/common.h"
#include "td/utils/FlatHashMap.h" #include "td/utils/FlatHashMap.h"
#include "td/utils/FlatHashSet.h"
#include "td/utils/Status.h" #include "td/utils/Status.h"
#include <memory> #include <memory>
#include <unordered_set>
#include <utility> #include <utility>
namespace td { namespace td {
@ -169,7 +169,7 @@ class BackgroundManager final : public Actor {
FlatHashMap<FileId, BackgroundId, FileIdHash> file_id_to_background_id_; FlatHashMap<FileId, BackgroundId, FileIdHash> file_id_to_background_id_;
std::unordered_set<string> loaded_from_database_backgrounds_; FlatHashSet<string> loaded_from_database_backgrounds_;
FlatHashMap<string, vector<Promise<Unit>>> being_loaded_from_database_backgrounds_; FlatHashMap<string, vector<Promise<Unit>>> being_loaded_from_database_backgrounds_;
BackgroundId set_background_id_[2]; BackgroundId set_background_id_[2];

View File

@ -25,13 +25,13 @@
#include "td/utils/buffer.h" #include "td/utils/buffer.h"
#include "td/utils/common.h" #include "td/utils/common.h"
#include "td/utils/crypto.h" #include "td/utils/crypto.h"
#include "td/utils/FlatHashSet.h"
#include "td/utils/logging.h" #include "td/utils/logging.h"
#include "td/utils/misc.h" #include "td/utils/misc.h"
#include "td/utils/Random.h" #include "td/utils/Random.h"
#include "td/utils/SliceBuilder.h" #include "td/utils/SliceBuilder.h"
#include <tuple> #include <tuple>
#include <unordered_set>
namespace td { namespace td {
@ -254,7 +254,7 @@ void CallActor::rate_call(int32 rating, string comment, vector<td_api::object_pt
comment.clear(); comment.clear();
} }
std::unordered_set<string> tags; FlatHashSet<string> tags;
for (auto &problem : problems) { for (auto &problem : problems) {
if (problem == nullptr) { if (problem == nullptr) {
continue; continue;

View File

@ -17,6 +17,7 @@
#include "td/utils/crypto.h" #include "td/utils/crypto.h"
#include "td/utils/ExitGuard.h" #include "td/utils/ExitGuard.h"
#include "td/utils/FlatHashMap.h" #include "td/utils/FlatHashMap.h"
#include "td/utils/FlatHashSet.h"
#include "td/utils/logging.h" #include "td/utils/logging.h"
#include "td/utils/misc.h" #include "td/utils/misc.h"
#include "td/utils/MpscPollableQueue.h" #include "td/utils/MpscPollableQueue.h"
@ -30,7 +31,6 @@
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <queue> #include <queue>
#include <unordered_set>
namespace td { namespace td {
@ -204,7 +204,7 @@ class ClientManager::Impl final {
unique_ptr<ConcurrentScheduler> concurrent_scheduler_; unique_ptr<ConcurrentScheduler> concurrent_scheduler_;
ClientId client_id_{0}; ClientId client_id_{0};
Td::Options options_; Td::Options options_;
std::unordered_set<int32> pending_clients_; FlatHashSet<int32> pending_clients_;
FlatHashMap<int32, ActorOwn<Td>> tds_; FlatHashMap<int32, ActorOwn<Td>> tds_;
}; };

View File

@ -69,6 +69,7 @@
#include <limits> #include <limits>
#include <tuple> #include <tuple>
#include <unordered_map> #include <unordered_map>
#include <unordered_set>
#include <utility> #include <utility>
namespace td { namespace td {
@ -8152,7 +8153,7 @@ void ContactsManager::on_get_contacts(tl_object_ptr<telegram_api::contacts_Conta
} }
auto contacts = move_tl_object_as<telegram_api::contacts_contacts>(new_contacts); auto contacts = move_tl_object_as<telegram_api::contacts_contacts>(new_contacts);
std::unordered_set<UserId, UserIdHash> contact_user_ids; FlatHashSet<UserId, UserIdHash> contact_user_ids;
for (auto &user : contacts->users_) { for (auto &user : contacts->users_) {
auto user_id = get_user_id(user); auto user_id = get_user_id(user);
if (!user_id.is_valid()) { if (!user_id.is_valid()) {
@ -8719,6 +8720,7 @@ void ContactsManager::on_load_user_from_database(UserId user_id, string value, b
return; return;
} }
CHECK(user_id.is_valid());
if (!loaded_from_database_users_.insert(user_id).second) { if (!loaded_from_database_users_.insert(user_id).second) {
return; return;
} }
@ -9020,6 +9022,7 @@ void ContactsManager::on_load_chat_from_database(ChatId chat_id, string value, b
return; return;
} }
CHECK(chat_id.is_valid());
if (!loaded_from_database_chats_.insert(chat_id).second) { if (!loaded_from_database_chats_.insert(chat_id).second) {
return; return;
} }
@ -9259,6 +9262,7 @@ void ContactsManager::on_load_channel_from_database(ChannelId channel_id, string
return; return;
} }
CHECK(channel_id.is_valid());
if (!loaded_from_database_channels_.insert(channel_id).second) { if (!loaded_from_database_channels_.insert(channel_id).second) {
return; return;
} }
@ -9515,6 +9519,7 @@ void ContactsManager::on_load_secret_chat_from_database(SecretChatId secret_chat
return; return;
} }
CHECK(secret_chat_id.is_valid());
if (!loaded_from_database_secret_chats_.insert(secret_chat_id).second) { if (!loaded_from_database_secret_chats_.insert(secret_chat_id).second) {
return; return;
} }
@ -12175,8 +12180,11 @@ void ContactsManager::on_get_channel_participants(
search_among_dialogs(dialog_ids, additional_query, additional_limit); search_among_dialogs(dialog_ids, additional_query, additional_limit);
total_count = result_dialog_ids.first; total_count = result_dialog_ids.first;
std::unordered_set<DialogId, DialogIdHash> result_dialog_ids_set(result_dialog_ids.second.begin(), FlatHashSet<DialogId, DialogIdHash> result_dialog_ids_set;
result_dialog_ids.second.end()); for (auto result_dialog_id : result_dialog_ids.second) {
CHECK(result_dialog_id.is_valid());
result_dialog_ids_set.insert(result_dialog_id);
}
auto all_participants = std::move(result); auto all_participants = std::move(result);
result.clear(); result.clear();
for (auto &participant : all_participants) { for (auto &participant : all_participants) {
@ -12502,7 +12510,7 @@ void ContactsManager::invalidate_channel_full(ChannelId channel_id, bool need_dr
if (channel_full != nullptr) { if (channel_full != nullptr) {
do_invalidate_channel_full(channel_full, channel_id, need_drop_slow_mode_delay); do_invalidate_channel_full(channel_full, channel_id, need_drop_slow_mode_delay);
update_channel_full(channel_full, channel_id, "invalidate_channel_full"); update_channel_full(channel_full, channel_id, "invalidate_channel_full");
} else { } else if (channel_id.is_valid()) {
invalidated_channels_full_.insert(channel_id); invalidated_channels_full_.insert(channel_id);
} }
} }

View File

@ -41,6 +41,7 @@
#include "td/utils/common.h" #include "td/utils/common.h"
#include "td/utils/FlatHashMap.h" #include "td/utils/FlatHashMap.h"
#include "td/utils/FlatHashSet.h"
#include "td/utils/Hints.h" #include "td/utils/Hints.h"
#include "td/utils/Status.h" #include "td/utils/Status.h"
#include "td/utils/StringBuilder.h" #include "td/utils/StringBuilder.h"
@ -48,7 +49,6 @@
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <unordered_set>
#include <utility> #include <utility>
namespace td { namespace td {
@ -629,7 +629,7 @@ class ContactsManager final : public Actor {
string language_code; string language_code;
std::unordered_set<int64> photo_ids; FlatHashSet<int64> photo_ids;
FlatHashMap<DialogId, int32, DialogIdHash> online_member_dialogs; // id -> time FlatHashMap<DialogId, int32, DialogIdHash> online_member_dialogs; // id -> time
@ -1642,7 +1642,7 @@ class ContactsManager final : public Actor {
FlatHashMap<UserId, unique_ptr<User>, UserIdHash> users_; FlatHashMap<UserId, unique_ptr<User>, UserIdHash> users_;
FlatHashMap<UserId, unique_ptr<UserFull>, UserIdHash> users_full_; FlatHashMap<UserId, unique_ptr<UserFull>, UserIdHash> users_full_;
FlatHashMap<UserId, UserPhotos, UserIdHash> user_photos_; FlatHashMap<UserId, UserPhotos, UserIdHash> user_photos_;
mutable std::unordered_set<UserId, UserIdHash> unknown_users_; mutable FlatHashSet<UserId, UserIdHash> unknown_users_;
FlatHashMap<UserId, tl_object_ptr<telegram_api::UserProfilePhoto>, UserIdHash> pending_user_photos_; FlatHashMap<UserId, tl_object_ptr<telegram_api::UserProfilePhoto>, UserIdHash> pending_user_photos_;
struct UserIdPhotoIdHash { struct UserIdPhotoIdHash {
std::size_t operator()(const std::pair<UserId, int64> &pair) const { std::size_t operator()(const std::pair<UserId, int64> &pair) const {
@ -1654,23 +1654,23 @@ class ContactsManager final : public Actor {
FlatHashMap<ChatId, unique_ptr<Chat>, ChatIdHash> chats_; FlatHashMap<ChatId, unique_ptr<Chat>, ChatIdHash> chats_;
FlatHashMap<ChatId, unique_ptr<ChatFull>, ChatIdHash> chats_full_; FlatHashMap<ChatId, unique_ptr<ChatFull>, ChatIdHash> chats_full_;
mutable std::unordered_set<ChatId, ChatIdHash> unknown_chats_; mutable FlatHashSet<ChatId, ChatIdHash> unknown_chats_;
FlatHashMap<ChatId, FileSourceId, ChatIdHash> chat_full_file_source_ids_; FlatHashMap<ChatId, FileSourceId, ChatIdHash> chat_full_file_source_ids_;
FlatHashMap<ChannelId, unique_ptr<MinChannel>, ChannelIdHash> min_channels_; FlatHashMap<ChannelId, unique_ptr<MinChannel>, ChannelIdHash> min_channels_;
FlatHashMap<ChannelId, unique_ptr<Channel>, ChannelIdHash> channels_; FlatHashMap<ChannelId, unique_ptr<Channel>, ChannelIdHash> channels_;
FlatHashMap<ChannelId, unique_ptr<ChannelFull>, ChannelIdHash> channels_full_; FlatHashMap<ChannelId, unique_ptr<ChannelFull>, ChannelIdHash> channels_full_;
mutable std::unordered_set<ChannelId, ChannelIdHash> unknown_channels_; mutable FlatHashSet<ChannelId, ChannelIdHash> unknown_channels_;
std::unordered_set<ChannelId, ChannelIdHash> invalidated_channels_full_; FlatHashSet<ChannelId, ChannelIdHash> invalidated_channels_full_;
FlatHashMap<ChannelId, FileSourceId, ChannelIdHash> channel_full_file_source_ids_; FlatHashMap<ChannelId, FileSourceId, ChannelIdHash> channel_full_file_source_ids_;
FlatHashMap<SecretChatId, unique_ptr<SecretChat>, SecretChatIdHash> secret_chats_; FlatHashMap<SecretChatId, unique_ptr<SecretChat>, SecretChatIdHash> secret_chats_;
mutable std::unordered_set<SecretChatId, SecretChatIdHash> unknown_secret_chats_; mutable FlatHashSet<SecretChatId, SecretChatIdHash> unknown_secret_chats_;
FlatHashMap<UserId, vector<SecretChatId>, UserIdHash> secret_chats_with_user_; FlatHashMap<UserId, vector<SecretChatId>, UserIdHash> secret_chats_with_user_;
struct DialogAccessByInviteLink { struct DialogAccessByInviteLink {
std::unordered_set<string> invite_links; FlatHashSet<string> invite_links;
int32 accessible_before = 0; int32 accessible_before = 0;
}; };
FlatHashMap<string, unique_ptr<InviteLinkInfo>> invite_link_infos_; FlatHashMap<string, unique_ptr<InviteLinkInfo>> invite_link_infos_;
@ -1687,19 +1687,19 @@ class ContactsManager final : public Actor {
vector<ChannelId> inactive_channels_; vector<ChannelId> inactive_channels_;
FlatHashMap<UserId, vector<Promise<Unit>>, UserIdHash> load_user_from_database_queries_; FlatHashMap<UserId, vector<Promise<Unit>>, UserIdHash> load_user_from_database_queries_;
std::unordered_set<UserId, UserIdHash> loaded_from_database_users_; FlatHashSet<UserId, UserIdHash> loaded_from_database_users_;
std::unordered_set<UserId, UserIdHash> unavailable_user_fulls_; FlatHashSet<UserId, UserIdHash> unavailable_user_fulls_;
FlatHashMap<ChatId, vector<Promise<Unit>>, ChatIdHash> load_chat_from_database_queries_; FlatHashMap<ChatId, vector<Promise<Unit>>, ChatIdHash> load_chat_from_database_queries_;
std::unordered_set<ChatId, ChatIdHash> loaded_from_database_chats_; FlatHashSet<ChatId, ChatIdHash> loaded_from_database_chats_;
std::unordered_set<ChatId, ChatIdHash> unavailable_chat_fulls_; FlatHashSet<ChatId, ChatIdHash> unavailable_chat_fulls_;
FlatHashMap<ChannelId, vector<Promise<Unit>>, ChannelIdHash> load_channel_from_database_queries_; FlatHashMap<ChannelId, vector<Promise<Unit>>, ChannelIdHash> load_channel_from_database_queries_;
std::unordered_set<ChannelId, ChannelIdHash> loaded_from_database_channels_; FlatHashSet<ChannelId, ChannelIdHash> loaded_from_database_channels_;
std::unordered_set<ChannelId, ChannelIdHash> unavailable_channel_fulls_; FlatHashSet<ChannelId, ChannelIdHash> unavailable_channel_fulls_;
FlatHashMap<SecretChatId, vector<Promise<Unit>>, SecretChatIdHash> load_secret_chat_from_database_queries_; FlatHashMap<SecretChatId, vector<Promise<Unit>>, SecretChatIdHash> load_secret_chat_from_database_queries_;
std::unordered_set<SecretChatId, SecretChatIdHash> loaded_from_database_secret_chats_; FlatHashSet<SecretChatId, SecretChatIdHash> loaded_from_database_secret_chats_;
QueryCombiner get_user_full_queries_{"GetUserFullCombiner", 2.0}; QueryCombiner get_user_full_queries_{"GetUserFullCombiner", 2.0};
QueryCombiner get_chat_full_queries_{"GetChatFullCombiner", 2.0}; QueryCombiner get_chat_full_queries_{"GetChatFullCombiner", 2.0};
@ -1771,7 +1771,7 @@ class ContactsManager final : public Actor {
vector<DialogNearby> users_nearby_; vector<DialogNearby> users_nearby_;
vector<DialogNearby> channels_nearby_; vector<DialogNearby> channels_nearby_;
std::unordered_set<UserId, UserIdHash> all_users_nearby_; FlatHashSet<UserId, UserIdHash> all_users_nearby_;
int32 location_visibility_expire_date_ = 0; int32 location_visibility_expire_date_ = 0;
int32 pending_location_visibility_expire_date_ = -1; int32 pending_location_visibility_expire_date_ = -1;
@ -1780,8 +1780,8 @@ class ContactsManager final : public Actor {
FlatHashMap<ChannelId, ChannelId, ChannelIdHash> linked_channel_ids_; FlatHashMap<ChannelId, ChannelId, ChannelIdHash> linked_channel_ids_;
std::unordered_set<UserId, UserIdHash> restricted_user_ids_; FlatHashSet<UserId, UserIdHash> restricted_user_ids_;
std::unordered_set<ChannelId, ChannelIdHash> restricted_channel_ids_; FlatHashSet<ChannelId, ChannelIdHash> restricted_channel_ids_;
vector<Contact> next_all_imported_contacts_; vector<Contact> next_all_imported_contacts_;
vector<size_t> imported_contacts_unique_id_; vector<size_t> imported_contacts_unique_id_;

View File

@ -13,19 +13,19 @@
#include "td/telegram/UserId.h" #include "td/telegram/UserId.h"
#include "td/telegram/WebPageId.h" #include "td/telegram/WebPageId.h"
#include <unordered_set> #include "td/utils/FlatHashSet.h"
namespace td { namespace td {
class Td; class Td;
class Dependencies { class Dependencies {
std::unordered_set<UserId, UserIdHash> user_ids; FlatHashSet<UserId, UserIdHash> user_ids;
std::unordered_set<ChatId, ChatIdHash> chat_ids; FlatHashSet<ChatId, ChatIdHash> chat_ids;
std::unordered_set<ChannelId, ChannelIdHash> channel_ids; FlatHashSet<ChannelId, ChannelIdHash> channel_ids;
std::unordered_set<SecretChatId, SecretChatIdHash> secret_chat_ids; FlatHashSet<SecretChatId, SecretChatIdHash> secret_chat_ids;
std::unordered_set<DialogId, DialogIdHash> dialog_ids; FlatHashSet<DialogId, DialogIdHash> dialog_ids;
std::unordered_set<WebPageId, WebPageIdHash> web_page_ids; FlatHashSet<WebPageId, WebPageIdHash> web_page_ids;
public: public:
void add(UserId user_id); void add(UserId user_id);
@ -46,7 +46,7 @@ class Dependencies {
bool resolve_force(Td *td, const char *source) const; bool resolve_force(Td *td, const char *source) const;
const std::unordered_set<DialogId, DialogIdHash> &get_dialog_ids() const { const FlatHashSet<DialogId, DialogIdHash> &get_dialog_ids() const {
return dialog_ids; return dialog_ids;
} }
}; };

View File

@ -10,11 +10,10 @@
#include "td/utils/algorithm.h" #include "td/utils/algorithm.h"
#include "td/utils/emoji.h" #include "td/utils/emoji.h"
#include "td/utils/FlatHashSet.h"
#include "td/utils/format.h" #include "td/utils/format.h"
#include "td/utils/logging.h" #include "td/utils/logging.h"
#include <unordered_set>
namespace td { namespace td {
unique_ptr<DialogFilter> DialogFilter::get_dialog_filter(telegram_api::object_ptr<telegram_api::dialogFilter> filter, unique_ptr<DialogFilter> DialogFilter::get_dialog_filter(telegram_api::object_ptr<telegram_api::dialogFilter> filter,
@ -28,7 +27,7 @@ unique_ptr<DialogFilter> DialogFilter::get_dialog_filter(telegram_api::object_pt
dialog_filter->dialog_filter_id = dialog_filter_id; dialog_filter->dialog_filter_id = dialog_filter_id;
dialog_filter->title = std::move(filter->title_); dialog_filter->title = std::move(filter->title_);
dialog_filter->emoji = std::move(filter->emoticon_); dialog_filter->emoji = std::move(filter->emoticon_);
std::unordered_set<DialogId, DialogIdHash> added_dialog_ids; FlatHashSet<DialogId, DialogIdHash> added_dialog_ids;
dialog_filter->pinned_dialog_ids = InputDialogId::get_input_dialog_ids(filter->pinned_peers_, &added_dialog_ids); dialog_filter->pinned_dialog_ids = InputDialogId::get_input_dialog_ids(filter->pinned_peers_, &added_dialog_ids);
dialog_filter->included_dialog_ids = InputDialogId::get_input_dialog_ids(filter->include_peers_, &added_dialog_ids); dialog_filter->included_dialog_ids = InputDialogId::get_input_dialog_ids(filter->include_peers_, &added_dialog_ids);
dialog_filter->excluded_dialog_ids = InputDialogId::get_input_dialog_ids(filter->exclude_peers_, &added_dialog_ids); dialog_filter->excluded_dialog_ids = InputDialogId::get_input_dialog_ids(filter->exclude_peers_, &added_dialog_ids);
@ -271,7 +270,7 @@ unique_ptr<DialogFilter> DialogFilter::merge_dialog_filter_changes(const DialogF
LOG(INFO) << "Pinned chats was not changed locally in " << dialog_filter_id << ", keep remote changes"; LOG(INFO) << "Pinned chats was not changed locally in " << dialog_filter_id << ", keep remote changes";
size_t kept_server_dialogs = 0; size_t kept_server_dialogs = 0;
std::unordered_set<DialogId, DialogIdHash> removed_dialog_ids; FlatHashSet<DialogId, DialogIdHash> removed_dialog_ids;
auto old_it = old_server_dialog_ids.rbegin(); auto old_it = old_server_dialog_ids.rbegin();
for (auto &input_dialog_id : reversed(new_server_dialog_ids)) { for (auto &input_dialog_id : reversed(new_server_dialog_ids)) {
auto dialog_id = input_dialog_id.get_dialog_id(); auto dialog_id = input_dialog_id.get_dialog_id();
@ -283,12 +282,14 @@ unique_ptr<DialogFilter> DialogFilter::merge_dialog_filter_changes(const DialogF
} }
// remove the dialog, it could be added back later // remove the dialog, it could be added back later
CHECK(old_it->get_dialog_id().is_valid());
removed_dialog_ids.insert(old_it->get_dialog_id()); removed_dialog_ids.insert(old_it->get_dialog_id());
++old_it; ++old_it;
} }
} }
while (old_it < old_server_dialog_ids.rend()) { while (old_it < old_server_dialog_ids.rend()) {
// remove the dialog, it could be added back later // remove the dialog, it could be added back later
CHECK(old_it->get_dialog_id().is_valid());
removed_dialog_ids.insert(old_it->get_dialog_id()); removed_dialog_ids.insert(old_it->get_dialog_id());
++old_it; ++old_it;
} }
@ -310,11 +311,12 @@ unique_ptr<DialogFilter> DialogFilter::merge_dialog_filter_changes(const DialogF
} }
// merge additions and deletions from other clients to the local changes // merge additions and deletions from other clients to the local changes
std::unordered_set<DialogId, DialogIdHash> deleted_dialog_ids; FlatHashSet<DialogId, DialogIdHash> deleted_dialog_ids;
for (const auto &old_dialog_id : old_server_dialog_ids) { for (const auto &old_dialog_id : old_server_dialog_ids) {
CHECK(old_dialog_id.get_dialog_id().is_valid());
deleted_dialog_ids.insert(old_dialog_id.get_dialog_id()); deleted_dialog_ids.insert(old_dialog_id.get_dialog_id());
} }
std::unordered_set<DialogId, DialogIdHash> added_dialog_ids; FlatHashSet<DialogId, DialogIdHash> added_dialog_ids;
for (const auto &new_dialog_id : new_server_dialog_ids) { for (const auto &new_dialog_id : new_server_dialog_ids) {
auto dialog_id = new_dialog_id.get_dialog_id(); auto dialog_id = new_dialog_id.get_dialog_id();
if (deleted_dialog_ids.erase(dialog_id) == 0) { if (deleted_dialog_ids.erase(dialog_id) == 0) {
@ -347,10 +349,12 @@ unique_ptr<DialogFilter> DialogFilter::merge_dialog_filter_changes(const DialogF
new_server_filter->excluded_dialog_ids); new_server_filter->excluded_dialog_ids);
{ {
std::unordered_set<DialogId, DialogIdHash> added_dialog_ids; FlatHashSet<DialogId, DialogIdHash> added_dialog_ids;
auto remove_duplicates = [&added_dialog_ids](auto &input_dialog_ids) { auto remove_duplicates = [&added_dialog_ids](auto &input_dialog_ids) {
td::remove_if(input_dialog_ids, [&added_dialog_ids](auto input_dialog_id) { td::remove_if(input_dialog_ids, [&added_dialog_ids](auto input_dialog_id) {
return !added_dialog_ids.insert(input_dialog_id.get_dialog_id()).second; auto dialog_id = input_dialog_id.get_dialog_id();
CHECK(dialog_id.is_valid());
return !added_dialog_ids.insert(dialog_id).second;
}); });
}; };
remove_duplicates(new_filter->pinned_dialog_ids); remove_duplicates(new_filter->pinned_dialog_ids);

View File

@ -22,13 +22,13 @@
#include "td/utils/algorithm.h" #include "td/utils/algorithm.h"
#include "td/utils/buffer.h" #include "td/utils/buffer.h"
#include "td/utils/FlatHashSet.h"
#include "td/utils/logging.h" #include "td/utils/logging.h"
#include "td/utils/misc.h" #include "td/utils/misc.h"
#include "td/utils/Random.h" #include "td/utils/Random.h"
#include "td/utils/SliceBuilder.h" #include "td/utils/SliceBuilder.h"
#include <map> #include <map>
#include <unordered_set>
#include <utility> #include <utility>
namespace td { namespace td {
@ -2064,10 +2064,11 @@ void GroupCallManager::process_group_call_participants(
return; return;
} }
std::unordered_set<DialogId, DialogIdHash> old_participant_dialog_ids; FlatHashSet<DialogId, DialogIdHash> old_participant_dialog_ids;
if (is_sync) { if (is_sync) {
auto *group_call_participants = add_group_call_participants(input_group_call_id); auto *group_call_participants = add_group_call_participants(input_group_call_id);
for (auto &participant : group_call_participants->participants) { for (auto &participant : group_call_participants->participants) {
CHECK(participant.dialog_id.is_valid());
old_participant_dialog_ids.insert(participant.dialog_id); old_participant_dialog_ids.insert(participant.dialog_id);
} }
} }

View File

@ -54,8 +54,8 @@ InputDialogId::InputDialogId(const tl_object_ptr<telegram_api::InputPeer> &input
vector<InputDialogId> InputDialogId::get_input_dialog_ids( vector<InputDialogId> InputDialogId::get_input_dialog_ids(
const vector<tl_object_ptr<telegram_api::InputPeer>> &input_peers, const vector<tl_object_ptr<telegram_api::InputPeer>> &input_peers,
std::unordered_set<DialogId, DialogIdHash> *added_dialog_ids) { FlatHashSet<DialogId, DialogIdHash> *added_dialog_ids) {
std::unordered_set<DialogId, DialogIdHash> temp_added_dialog_ids; FlatHashSet<DialogId, DialogIdHash> temp_added_dialog_ids;
if (added_dialog_ids == nullptr) { if (added_dialog_ids == nullptr) {
added_dialog_ids = &temp_added_dialog_ids; added_dialog_ids = &temp_added_dialog_ids;
} }

View File

@ -10,10 +10,9 @@
#include "td/telegram/telegram_api.h" #include "td/telegram/telegram_api.h"
#include "td/utils/common.h" #include "td/utils/common.h"
#include "td/utils/FlatHashSet.h"
#include "td/utils/StringBuilder.h" #include "td/utils/StringBuilder.h"
#include <unordered_set>
namespace td { namespace td {
class InputDialogId { class InputDialogId {
@ -28,9 +27,8 @@ class InputDialogId {
explicit InputDialogId(const tl_object_ptr<telegram_api::InputPeer> &input_peer); explicit InputDialogId(const tl_object_ptr<telegram_api::InputPeer> &input_peer);
static vector<InputDialogId> get_input_dialog_ids( static vector<InputDialogId> get_input_dialog_ids(const vector<tl_object_ptr<telegram_api::InputPeer>> &input_peers,
const vector<tl_object_ptr<telegram_api::InputPeer>> &input_peers, FlatHashSet<DialogId, DialogIdHash> *added_dialog_ids = nullptr);
std::unordered_set<DialogId, DialogIdHash> *added_dialog_ids = nullptr);
static vector<telegram_api::object_ptr<telegram_api::InputDialogPeer>> get_input_dialog_peers( static vector<telegram_api::object_ptr<telegram_api::InputDialogPeer>> get_input_dialog_peers(
const vector<InputDialogId> &input_dialog_ids); const vector<InputDialogId> &input_dialog_ids);

View File

@ -20,6 +20,7 @@
#include "td/utils/algorithm.h" #include "td/utils/algorithm.h"
#include "td/utils/ExitGuard.h" #include "td/utils/ExitGuard.h"
#include "td/utils/FlatHashSet.h"
#include "td/utils/logging.h" #include "td/utils/logging.h"
#include "td/utils/misc.h" #include "td/utils/misc.h"
#include "td/utils/SliceBuilder.h" #include "td/utils/SliceBuilder.h"
@ -28,7 +29,6 @@
#include <atomic> #include <atomic>
#include <limits> #include <limits>
#include <map> #include <map>
#include <unordered_set>
#include <utility> #include <utility>
namespace td { namespace td {
@ -63,7 +63,7 @@ struct LanguagePackManager::Language {
vector<Promise<Unit>> get_difference_queries_; vector<Promise<Unit>> get_difference_queries_;
FlatHashMap<string, string> ordinary_strings_; FlatHashMap<string, string> ordinary_strings_;
FlatHashMap<string, unique_ptr<PluralizedString>> pluralized_strings_; FlatHashMap<string, unique_ptr<PluralizedString>> pluralized_strings_;
std::unordered_set<string> deleted_strings_; FlatHashSet<string> deleted_strings_;
SqliteKeyValue kv_; // usages should be guarded by database_->mutex_ SqliteKeyValue kv_; // usages should be guarded by database_->mutex_
}; };
@ -979,11 +979,11 @@ void LanguagePackManager::on_get_languages(vector<tl_object_ptr<telegram_api::la
string language_pack, bool only_local, string language_pack, bool only_local,
Promise<td_api::object_ptr<td_api::localizationTargetInfo>> promise) { Promise<td_api::object_ptr<td_api::localizationTargetInfo>> promise) {
auto results = td_api::make_object<td_api::localizationTargetInfo>(); auto results = td_api::make_object<td_api::localizationTargetInfo>();
std::unordered_set<string> added_languages; FlatHashSet<string> added_languages;
auto add_language_info = [&results, &added_languages](const string &language_code, const LanguageInfo &info, auto add_language_info = [&results, &added_languages](const string &language_code, const LanguageInfo &info,
bool is_installed) { bool is_installed) {
if (added_languages.insert(language_code).second) { if (!language_code.empty() && added_languages.insert(language_code).second) {
results->language_packs_.push_back(get_language_pack_info_object(language_code, info)); results->language_packs_.push_back(get_language_pack_info_object(language_code, info));
results->language_packs_.back()->is_installed_ = is_installed; results->language_packs_.back()->is_installed_ = is_installed;
} }

View File

@ -1270,9 +1270,14 @@ static Slice fix_url(Slice str) {
return full_url; return full_url;
} }
const std::unordered_set<Slice, SliceHash> &get_valid_short_usernames() { const FlatHashSet<Slice, SliceHash> &get_valid_short_usernames() {
static const std::unordered_set<Slice, SliceHash> valid_usernames{"gif", "wiki", "vid", "bing", "pic", static const FlatHashSet<Slice, SliceHash> valid_usernames = [] {
"bold", "imdb", "coub", "like", "vote"}; FlatHashSet<Slice, SliceHash> result;
for (auto username : {"gif", "wiki", "vid", "bing", "pic", "bold", "imdb", "coub", "like", "vote"}) {
result.insert(Slice(username));
}
return result;
}();
return valid_usernames; return valid_usernames;
} }

View File

@ -13,11 +13,11 @@
#include "td/telegram/UserId.h" #include "td/telegram/UserId.h"
#include "td/utils/common.h" #include "td/utils/common.h"
#include "td/utils/FlatHashSet.h"
#include "td/utils/Slice.h" #include "td/utils/Slice.h"
#include "td/utils/Status.h" #include "td/utils/Status.h"
#include "td/utils/StringBuilder.h" #include "td/utils/StringBuilder.h"
#include <unordered_set>
#include <utility> #include <utility>
namespace td { namespace td {
@ -131,7 +131,7 @@ inline bool operator!=(const FormattedText &lhs, const FormattedText &rhs) {
return !(lhs == rhs); return !(lhs == rhs);
} }
const std::unordered_set<Slice, SliceHash> &get_valid_short_usernames(); const FlatHashSet<Slice, SliceHash> &get_valid_short_usernames();
Result<vector<MessageEntity>> get_message_entities(const ContactsManager *contacts_manager, Result<vector<MessageEntity>> get_message_entities(const ContactsManager *contacts_manager,
vector<tl_object_ptr<td_api::textEntity>> &&input_entities, vector<tl_object_ptr<td_api::textEntity>> &&input_entities,

View File

@ -17,11 +17,11 @@
#include "td/utils/algorithm.h" #include "td/utils/algorithm.h"
#include "td/utils/buffer.h" #include "td/utils/buffer.h"
#include "td/utils/FlatHashSet.h"
#include "td/utils/logging.h" #include "td/utils/logging.h"
#include "td/utils/Status.h" #include "td/utils/Status.h"
#include <algorithm> #include <algorithm>
#include <unordered_set>
#include <utility> #include <utility>
namespace td { namespace td {
@ -52,7 +52,10 @@ class GetMessagesReactionsQuery final : public Td::ResultHandler {
LOG(INFO) << "Receive result for GetMessagesReactionsQuery: " << to_string(ptr); LOG(INFO) << "Receive result for GetMessagesReactionsQuery: " << to_string(ptr);
if (ptr->get_id() == telegram_api::updates::ID) { if (ptr->get_id() == telegram_api::updates::ID) {
auto &updates = static_cast<telegram_api::updates *>(ptr.get())->updates_; auto &updates = static_cast<telegram_api::updates *>(ptr.get())->updates_;
std::unordered_set<MessageId, MessageIdHash> skipped_message_ids(message_ids_.begin(), message_ids_.end()); FlatHashSet<MessageId, MessageIdHash> skipped_message_ids;
for (auto message_id : message_ids_) {
skipped_message_ids.insert(message_id);
}
for (const auto &update : updates) { for (const auto &update : updates) {
if (update->get_id() == telegram_api::updateMessageReactions::ID) { if (update->get_id() == telegram_api::updateMessageReactions::ID) {
auto update_message_reactions = static_cast<const telegram_api::updateMessageReactions *>(update.get()); auto update_message_reactions = static_cast<const telegram_api::updateMessageReactions *>(update.get());
@ -288,10 +291,11 @@ unique_ptr<MessageReactions> MessageReactions::get_message_reactions(
result->can_get_added_reactions_ = reactions->can_see_list_; result->can_get_added_reactions_ = reactions->can_see_list_;
result->is_min_ = reactions->min_; result->is_min_ = reactions->min_;
std::unordered_set<string> reaction_strings; FlatHashSet<string> reaction_strings;
std::unordered_set<DialogId, DialogIdHash> recent_choosers; FlatHashSet<DialogId, DialogIdHash> recent_choosers;
for (auto &reaction_count : reactions->results_) { for (auto &reaction_count : reactions->results_) {
if (reaction_count->count_ <= 0 || reaction_count->count_ >= MessageReaction::MAX_CHOOSE_COUNT) { if (reaction_count->count_ <= 0 || reaction_count->count_ >= MessageReaction::MAX_CHOOSE_COUNT ||
reaction_count->reaction_.empty()) {
LOG(ERROR) << "Receive reaction " << reaction_count->reaction_ << " with invalid count " LOG(ERROR) << "Receive reaction " << reaction_count->reaction_ << " with invalid count "
<< reaction_count->count_; << reaction_count->count_;
continue; continue;

View File

@ -8723,6 +8723,7 @@ void MessagesManager::queue_message_reactions_reload(FullMessageId full_message_
void MessagesManager::queue_message_reactions_reload(DialogId dialog_id, const vector<MessageId> &message_ids) { void MessagesManager::queue_message_reactions_reload(DialogId dialog_id, const vector<MessageId> &message_ids) {
auto &message_ids_to_reload = being_reloaded_reactions_[dialog_id].message_ids; auto &message_ids_to_reload = being_reloaded_reactions_[dialog_id].message_ids;
for (auto &message_id : message_ids) { for (auto &message_id : message_ids) {
CHECK(message_id.is_valid());
message_ids_to_reload.insert(message_id); message_ids_to_reload.insert(message_id);
} }
try_reload_message_reactions(dialog_id, false); try_reload_message_reactions(dialog_id, false);
@ -11968,6 +11969,7 @@ void MessagesManager::delete_all_dialog_messages(Dialog *d, bool remove_from_dia
delete_all_dialog_messages_from_database(d, MessageId::max(), "delete_all_dialog_messages 3"); delete_all_dialog_messages_from_database(d, MessageId::max(), "delete_all_dialog_messages 3");
if (is_permanently_deleted) { if (is_permanently_deleted) {
for (auto id : deleted_message_ids) { for (auto id : deleted_message_ids) {
CHECK(id != 0);
d->deleted_message_ids.insert(MessageId{id}); d->deleted_message_ids.insert(MessageId{id});
} }
} }
@ -15340,7 +15342,7 @@ void MessagesManager::remove_dialog_mention_notifications(Dialog *d) {
VLOG(notifications) << "Remove mention notifications in " << d->dialog_id; VLOG(notifications) << "Remove mention notifications in " << d->dialog_id;
vector<MessageId> message_ids; vector<MessageId> message_ids;
std::unordered_set<NotificationId, NotificationIdHash> removed_notification_ids_set; FlatHashSet<NotificationId, NotificationIdHash> removed_notification_ids_set;
find_messages(d->messages.get(), message_ids, [](const Message *m) { return m->contains_unread_mention; }); find_messages(d->messages.get(), message_ids, [](const Message *m) { return m->contains_unread_mention; });
VLOG(notifications) << "Found unread mentions in " << message_ids; VLOG(notifications) << "Found unread mentions in " << message_ids;
for (auto &message_id : message_ids) { for (auto &message_id : message_ids) {
@ -15854,8 +15856,10 @@ void MessagesManager::on_get_dialogs(FolderId folder_id, vector<tl_object_ptr<te
if (pinned_dialog_ids != added_dialog_ids) { if (pinned_dialog_ids != added_dialog_ids) {
LOG(INFO) << "Update pinned chats order from " << format::as_array(pinned_dialog_ids) << " to " LOG(INFO) << "Update pinned chats order from " << format::as_array(pinned_dialog_ids) << " to "
<< format::as_array(added_dialog_ids); << format::as_array(added_dialog_ids);
std::unordered_set<DialogId, DialogIdHash> old_pinned_dialog_ids(pinned_dialog_ids.begin(), FlatHashSet<DialogId, DialogIdHash> old_pinned_dialog_ids;
pinned_dialog_ids.end()); for (auto pinned_dialog_id : pinned_dialog_ids) {
old_pinned_dialog_ids.insert(pinned_dialog_id);
}
std::reverse(pinned_dialog_ids.begin(), pinned_dialog_ids.end()); std::reverse(pinned_dialog_ids.begin(), pinned_dialog_ids.end());
std::reverse(added_dialog_ids.begin(), added_dialog_ids.end()); std::reverse(added_dialog_ids.begin(), added_dialog_ids.end());
@ -19158,12 +19162,13 @@ void MessagesManager::sort_dialog_filter_input_dialog_ids(DialogFilter *dialog_f
sort_input_dialog_ids(dialog_filter->excluded_dialog_ids); sort_input_dialog_ids(dialog_filter->excluded_dialog_ids);
sort_input_dialog_ids(dialog_filter->included_dialog_ids); sort_input_dialog_ids(dialog_filter->included_dialog_ids);
std::unordered_set<DialogId, DialogIdHash> all_dialog_ids; FlatHashSet<DialogId, DialogIdHash> all_dialog_ids;
for (auto input_dialog_ids : for (auto input_dialog_ids :
{&dialog_filter->pinned_dialog_ids, &dialog_filter->excluded_dialog_ids, &dialog_filter->included_dialog_ids}) { {&dialog_filter->pinned_dialog_ids, &dialog_filter->excluded_dialog_ids, &dialog_filter->included_dialog_ids}) {
for (const auto &input_dialog_id : *input_dialog_ids) { for (const auto &input_dialog_id : *input_dialog_ids) {
LOG_CHECK(all_dialog_ids.insert(input_dialog_id.get_dialog_id()).second) auto dialog_id = input_dialog_id.get_dialog_id();
<< source << ' ' << input_dialog_id.get_dialog_id() << ' ' << dialog_filter; CHECK(dialog_id.is_valid());
LOG_CHECK(all_dialog_ids.insert(dialog_id).second) << source << ' ' << dialog_id << ' ' << dialog_filter;
} }
} }
} }
@ -19193,7 +19198,7 @@ Result<unique_ptr<DialogFilter>> MessagesManager::create_dialog_filter(DialogFil
auto dialog_filter = make_unique<DialogFilter>(); auto dialog_filter = make_unique<DialogFilter>();
dialog_filter->dialog_filter_id = dialog_filter_id; dialog_filter->dialog_filter_id = dialog_filter_id;
std::unordered_set<int64> added_dialog_ids; FlatHashSet<int64> added_dialog_ids;
auto add_chats = [this, &added_dialog_ids](vector<InputDialogId> &input_dialog_ids, const vector<int64> &chat_ids) { auto add_chats = [this, &added_dialog_ids](vector<InputDialogId> &input_dialog_ids, const vector<int64> &chat_ids) {
for (const auto &chat_id : chat_ids) { for (const auto &chat_id : chat_ids) {
if (!added_dialog_ids.insert(chat_id).second) { if (!added_dialog_ids.insert(chat_id).second) {
@ -20129,6 +20134,7 @@ Status MessagesManager::set_pinned_dialogs(DialogListId dialog_list_id, vector<D
int32 dialog_count = 0; int32 dialog_count = 0;
int32 secret_dialog_count = 0; int32 secret_dialog_count = 0;
auto dialog_count_limit = get_pinned_dialogs_limit(dialog_list_id); auto dialog_count_limit = get_pinned_dialogs_limit(dialog_list_id);
FlatHashSet<DialogId, DialogIdHash> new_pinned_dialog_ids;
for (auto dialog_id : dialog_ids) { for (auto dialog_id : dialog_ids) {
Dialog *d = get_dialog_force(dialog_id, "set_pinned_dialogs"); Dialog *d = get_dialog_force(dialog_id, "set_pinned_dialogs");
if (d == nullptr) { if (d == nullptr) {
@ -20152,8 +20158,9 @@ Status MessagesManager::set_pinned_dialogs(DialogListId dialog_list_id, vector<D
if (dialog_count > dialog_count_limit || secret_dialog_count > dialog_count_limit) { if (dialog_count > dialog_count_limit || secret_dialog_count > dialog_count_limit) {
return Status::Error(400, "The maximum number of pinned chats exceeded"); return Status::Error(400, "The maximum number of pinned chats exceeded");
} }
new_pinned_dialog_ids.insert(dialog_id);
} }
std::unordered_set<DialogId, DialogIdHash> new_pinned_dialog_ids(dialog_ids.begin(), dialog_ids.end());
if (new_pinned_dialog_ids.size() != dialog_ids.size()) { if (new_pinned_dialog_ids.size() != dialog_ids.size()) {
return Status::Error(400, "Duplicate chats in the list of pinned chats"); return Status::Error(400, "Duplicate chats in the list of pinned chats");
} }
@ -20211,7 +20218,10 @@ Status MessagesManager::set_pinned_dialogs(DialogListId dialog_list_id, vector<D
std::reverse(pinned_dialog_ids.begin(), pinned_dialog_ids.end()); std::reverse(pinned_dialog_ids.begin(), pinned_dialog_ids.end());
std::reverse(dialog_ids.begin(), dialog_ids.end()); std::reverse(dialog_ids.begin(), dialog_ids.end());
std::unordered_set<DialogId, DialogIdHash> old_pinned_dialog_ids(pinned_dialog_ids.begin(), pinned_dialog_ids.end()); FlatHashSet<DialogId, DialogIdHash> old_pinned_dialog_ids;
for (auto dialog_id : pinned_dialog_ids) {
old_pinned_dialog_ids.insert(dialog_id);
}
auto old_it = pinned_dialog_ids.begin(); auto old_it = pinned_dialog_ids.begin();
for (auto dialog_id : dialog_ids) { for (auto dialog_id : dialog_ids) {
old_pinned_dialog_ids.erase(dialog_id); old_pinned_dialog_ids.erase(dialog_id);
@ -32736,7 +32746,10 @@ DialogId MessagesManager::search_public_dialog(const string &username_to_search,
} }
void MessagesManager::reload_voice_chat_on_search(const string &username) { void MessagesManager::reload_voice_chat_on_search(const string &username) {
reload_voice_chat_on_search_usernames_.insert(clean_username(username)); auto cleaned_username = clean_username(username);
if (!cleaned_username.empty()) {
reload_voice_chat_on_search_usernames_.insert(cleaned_username);
}
} }
void MessagesManager::send_get_dialog_notification_settings_query(DialogId dialog_id, Promise<Unit> &&promise) { void MessagesManager::send_get_dialog_notification_settings_query(DialogId dialog_id, Promise<Unit> &&promise) {
@ -35423,7 +35436,7 @@ void MessagesManager::delete_message_from_database(Dialog *d, MessageId message_
} }
if (is_permanently_deleted) { if (is_permanently_deleted) {
if (message_id.is_scheduled() && message_id.is_scheduled_server()) { if (message_id.is_scheduled() && message_id.is_valid_scheduled() && message_id.is_scheduled_server()) {
d->deleted_scheduled_server_message_ids.insert(message_id.get_scheduled_server_message_id()); d->deleted_scheduled_server_message_ids.insert(message_id.get_scheduled_server_message_id());
} else { } else {
// don't store failed to send message identifiers for bots to reduce memory usage // don't store failed to send message identifiers for bots to reduce memory usage
@ -37473,6 +37486,7 @@ MessagesManager::Dialog *MessagesManager::get_dialog_force(DialogId dialog_id, c
unique_ptr<MessagesManager::Dialog> MessagesManager::parse_dialog(DialogId dialog_id, const BufferSlice &value, unique_ptr<MessagesManager::Dialog> MessagesManager::parse_dialog(DialogId dialog_id, const BufferSlice &value,
const char *source) { const char *source) {
LOG(INFO) << "Loaded " << dialog_id << " of size " << value.size() << " from database from " << source; LOG(INFO) << "Loaded " << dialog_id << " of size " << value.size() << " from database from " << source;
CHECK(dialog_id.is_valid());
auto d = make_unique<Dialog>(); auto d = make_unique<Dialog>();
d->dialog_id = dialog_id; d->dialog_id = dialog_id;
invalidate_message_indexes(d.get()); // must initialize indexes, because some of them could be not parsed invalidate_message_indexes(d.get()); // must initialize indexes, because some of them could be not parsed
@ -38087,7 +38101,7 @@ void MessagesManager::process_get_channel_difference_updates(
debug_channel_difference_dialog_ = dialog_id; debug_channel_difference_dialog_ = dialog_id;
// identifiers of edited and deleted messages // identifiers of edited and deleted messages
std::unordered_set<MessageId, MessageIdHash> changed_message_ids; FlatHashSet<MessageId, MessageIdHash> changed_message_ids;
for (auto &update_ptr : other_updates) { for (auto &update_ptr : other_updates) {
bool is_good_update = true; bool is_good_update = true;
switch (update_ptr->get_id()) { switch (update_ptr->get_id()) {
@ -38146,7 +38160,10 @@ void MessagesManager::process_get_channel_difference_updates(
for (auto &message : new_messages) { for (auto &message : new_messages) {
if (is_edited_message(message)) { if (is_edited_message(message)) {
changed_message_ids.insert(get_message_id(message, false)); auto message_id = get_message_id(message, false);
if (message_id.is_valid()) {
changed_message_ids.insert(message_id);
}
} }
} }
@ -39189,7 +39206,7 @@ void MessagesManager::on_binlog_events(vector<BinlogEvent> &&events) {
auto message_id = log_event.full_message_id_.get_message_id(); auto message_id = log_event.full_message_id_.get_message_id();
if (message_id.is_valid_scheduled() && message_id.is_scheduled_server()) { if (message_id.is_valid_scheduled() && message_id.is_scheduled_server()) {
d->deleted_scheduled_server_message_ids.insert(message_id.get_scheduled_server_message_id()); d->deleted_scheduled_server_message_ids.insert(message_id.get_scheduled_server_message_id());
} else { } else if (message_id != MessageId()) {
d->deleted_message_ids.insert(message_id); d->deleted_message_ids.insert(message_id);
} }
} }
@ -39213,7 +39230,10 @@ void MessagesManager::on_binlog_events(vector<BinlogEvent> &&events) {
break; break;
} }
d->deleted_message_ids.insert(log_event.message_ids_.begin(), log_event.message_ids_.end()); for (auto message_id : log_event.message_ids_) {
CHECK(message_id.is_valid());
d->deleted_message_ids.insert(message_id);
}
delete_messages_on_server(dialog_id, std::move(log_event.message_ids_), log_event.revoke_, event.id_, Auto()); delete_messages_on_server(dialog_id, std::move(log_event.message_ids_), log_event.revoke_, event.id_, Auto());
break; break;

View File

@ -67,6 +67,7 @@
#include "td/utils/ChangesProcessor.h" #include "td/utils/ChangesProcessor.h"
#include "td/utils/common.h" #include "td/utils/common.h"
#include "td/utils/FlatHashMap.h" #include "td/utils/FlatHashMap.h"
#include "td/utils/FlatHashSet.h"
#include "td/utils/Heap.h" #include "td/utils/Heap.h"
#include "td/utils/Hints.h" #include "td/utils/Hints.h"
#include "td/utils/logging.h" #include "td/utils/logging.h"
@ -1371,11 +1372,11 @@ class MessagesManager final : public Actor {
FlatHashMap<int32, MessageId> last_assigned_scheduled_message_id; // date -> message_id FlatHashMap<int32, MessageId> last_assigned_scheduled_message_id; // date -> message_id
std::unordered_set<MessageId, MessageIdHash> deleted_message_ids; FlatHashSet<MessageId, MessageIdHash> deleted_message_ids;
std::unordered_set<ScheduledServerMessageId, ScheduledServerMessageIdHash> deleted_scheduled_server_message_ids; FlatHashSet<ScheduledServerMessageId, ScheduledServerMessageIdHash> deleted_scheduled_server_message_ids;
std::vector<std::pair<DialogId, MessageId>> pending_new_message_notifications; vector<std::pair<DialogId, MessageId>> pending_new_message_notifications;
std::vector<std::pair<DialogId, MessageId>> pending_new_mention_notifications; vector<std::pair<DialogId, MessageId>> pending_new_mention_notifications;
FlatHashMap<NotificationId, MessageId, NotificationIdHash> notification_id_to_message_id; FlatHashMap<NotificationId, MessageId, NotificationIdHash> notification_id_to_message_id;
@ -1388,7 +1389,7 @@ class MessagesManager final : public Actor {
std::vector<std::pair<Promise<>, std::function<bool(const Message *)>>> suffix_load_queries_; std::vector<std::pair<Promise<>, std::function<bool(const Message *)>>> suffix_load_queries_;
FlatHashMap<MessageId, int64, MessageIdHash> pending_viewed_live_locations; // message_id -> task_id FlatHashMap<MessageId, int64, MessageIdHash> pending_viewed_live_locations; // message_id -> task_id
std::unordered_set<MessageId, MessageIdHash> pending_viewed_message_ids; FlatHashSet<MessageId, MessageIdHash> pending_viewed_message_ids;
unique_ptr<Message> messages; unique_ptr<Message> messages;
unique_ptr<Message> scheduled_messages; unique_ptr<Message> scheduled_messages;
@ -3450,10 +3451,9 @@ class MessagesManager final : public Actor {
FlatHashMap<DialogId, unique_ptr<Dialog>, DialogIdHash> dialogs_; FlatHashMap<DialogId, unique_ptr<Dialog>, DialogIdHash> dialogs_;
std::unordered_set<DialogId, DialogIdHash> FlatHashSet<DialogId, DialogIdHash> loaded_dialogs_; // dialogs loaded from database, but not added to dialogs_
loaded_dialogs_; // dialogs loaded from database, but not added to dialogs_
std::unordered_set<DialogId, DialogIdHash> postponed_chat_read_inbox_updates_; FlatHashSet<DialogId, DialogIdHash> postponed_chat_read_inbox_updates_;
struct PendingGetMessageRequest { struct PendingGetMessageRequest {
MessageId message_id; MessageId message_id;
@ -3504,7 +3504,7 @@ class MessagesManager final : public Actor {
FlatHashMap<FullMessageId, int32, FullMessageIdHash> replied_by_yet_unsent_messages_; FlatHashMap<FullMessageId, int32, FullMessageIdHash> replied_by_yet_unsent_messages_;
// full_message_id -> replies with media timestamps // full_message_id -> replies with media timestamps
FlatHashMap<FullMessageId, std::unordered_set<MessageId, MessageIdHash>, FullMessageIdHash> FlatHashMap<FullMessageId, FlatHashSet<MessageId, MessageIdHash>, FullMessageIdHash>
replied_by_media_timestamp_messages_; replied_by_media_timestamp_messages_;
struct ActiveDialogAction { struct ActiveDialogAction {
@ -3555,7 +3555,7 @@ class MessagesManager final : public Actor {
FlatHashMap<DialogId, uint64, DialogIdHash> get_channel_difference_to_log_event_id_; FlatHashMap<DialogId, uint64, DialogIdHash> get_channel_difference_to_log_event_id_;
FlatHashMap<DialogId, int32, DialogIdHash> channel_get_difference_retry_timeouts_; FlatHashMap<DialogId, int32, DialogIdHash> channel_get_difference_retry_timeouts_;
FlatHashMap<DialogId, std::multimap<int32, PendingPtsUpdate>, DialogIdHash> postponed_channel_updates_; FlatHashMap<DialogId, std::multimap<int32, PendingPtsUpdate>, DialogIdHash> postponed_channel_updates_;
std::unordered_set<DialogId, DialogIdHash> is_channel_difference_finished_; FlatHashSet<DialogId, DialogIdHash> is_channel_difference_finished_;
MultiTimeout channel_get_difference_timeout_{"ChannelGetDifferenceTimeout"}; MultiTimeout channel_get_difference_timeout_{"ChannelGetDifferenceTimeout"};
MultiTimeout channel_get_difference_retry_timeout_{"ChannelGetDifferenceRetryTimeout"}; MultiTimeout channel_get_difference_retry_timeout_{"ChannelGetDifferenceRetryTimeout"};
@ -3576,7 +3576,7 @@ class MessagesManager final : public Actor {
Hints dialogs_hints_; // search dialogs by title and username Hints dialogs_hints_; // search dialogs by title and username
std::unordered_set<FullMessageId, FullMessageIdHash> active_live_location_full_message_ids_; FlatHashSet<FullMessageId, FullMessageIdHash> active_live_location_full_message_ids_;
bool are_active_live_location_messages_loaded_ = false; bool are_active_live_location_messages_loaded_ = false;
vector<Promise<Unit>> load_active_live_location_messages_queries_; vector<Promise<Unit>> load_active_live_location_messages_queries_;
@ -3589,7 +3589,7 @@ class MessagesManager final : public Actor {
FlatHashMap<string, ResolvedUsername> resolved_usernames_; FlatHashMap<string, ResolvedUsername> resolved_usernames_;
FlatHashMap<string, DialogId> inaccessible_resolved_usernames_; FlatHashMap<string, DialogId> inaccessible_resolved_usernames_;
std::unordered_set<string> reload_voice_chat_on_search_usernames_; FlatHashSet<string> reload_voice_chat_on_search_usernames_;
struct GetDialogsTask { struct GetDialogsTask {
DialogListId dialog_list_id; DialogListId dialog_list_id;
@ -3628,7 +3628,7 @@ class MessagesManager final : public Actor {
pending_add_default_send_message_as_dialog_id_; // dialog_id -> [dependent dialog, need_drop] pending_add_default_send_message_as_dialog_id_; // dialog_id -> [dependent dialog, need_drop]
struct MessageIds { struct MessageIds {
std::unordered_set<MessageId, MessageIdHash> message_ids; FlatHashSet<MessageId, MessageIdHash> message_ids;
}; };
FlatHashMap<DialogId, MessageIds, DialogIdHash> dialog_bot_command_message_ids_; FlatHashMap<DialogId, MessageIds, DialogIdHash> dialog_bot_command_message_ids_;
@ -3671,7 +3671,7 @@ class MessagesManager final : public Actor {
FlatHashMap<DialogId, OnlineMemberCountInfo, DialogIdHash> dialog_online_member_counts_; FlatHashMap<DialogId, OnlineMemberCountInfo, DialogIdHash> dialog_online_member_counts_;
struct ReactionsToReload { struct ReactionsToReload {
std::unordered_set<MessageId, MessageIdHash> message_ids; FlatHashSet<MessageId, MessageIdHash> message_ids;
bool is_request_sent = false; bool is_request_sent = false;
}; };
FlatHashMap<DialogId, ReactionsToReload, DialogIdHash> being_reloaded_reactions_; FlatHashMap<DialogId, ReactionsToReload, DialogIdHash> being_reloaded_reactions_;

View File

@ -61,7 +61,6 @@
#include <algorithm> #include <algorithm>
#include <iterator> #include <iterator>
#include <limits> #include <limits>
#include <unordered_set>
namespace td { namespace td {
@ -249,6 +248,9 @@ void NotificationManager::init() {
}); });
VLOG(notifications) << "Load call_notification_group_ids = " << call_notification_group_ids; VLOG(notifications) << "Load call_notification_group_ids = " << call_notification_group_ids;
for (auto &group_id : call_notification_group_ids) { for (auto &group_id : call_notification_group_ids) {
if (!group_id.is_valid()) {
continue;
}
if (group_id.get() > current_notification_group_id_.get()) { if (group_id.get() > current_notification_group_id_.get()) {
LOG(ERROR) << "Fix current notification group identifier from " << current_notification_group_id_ << " to " LOG(ERROR) << "Fix current notification group identifier from " << current_notification_group_id_ << " to "
<< group_id; << group_id;
@ -1021,21 +1023,23 @@ void NotificationManager::flush_pending_updates(int32 group_id, const char *sour
// and second addition, because we has kept the deletion // and second addition, because we has kept the deletion
// calculate last state of all notifications // calculate last state of all notifications
std::unordered_set<int32> added_notification_ids; FlatHashSet<int32> added_notification_ids;
std::unordered_set<int32> edited_notification_ids; FlatHashSet<int32> edited_notification_ids;
std::unordered_set<int32> removed_notification_ids; FlatHashSet<int32> removed_notification_ids;
for (auto &update : updates) { for (auto &update : updates) {
CHECK(update != nullptr); CHECK(update != nullptr);
if (update->get_id() == td_api::updateNotificationGroup::ID) { if (update->get_id() == td_api::updateNotificationGroup::ID) {
auto update_ptr = static_cast<td_api::updateNotificationGroup *>(update.get()); auto update_ptr = static_cast<td_api::updateNotificationGroup *>(update.get());
for (auto &notification : update_ptr->added_notifications_) { for (auto &notification : update_ptr->added_notifications_) {
auto notification_id = notification->id_; auto notification_id = notification->id_;
CHECK(notification_id != 0);
bool is_inserted = added_notification_ids.insert(notification_id).second; bool is_inserted = added_notification_ids.insert(notification_id).second;
CHECK(is_inserted); // there must be no additions after addition CHECK(is_inserted); // there must be no additions after addition
CHECK(edited_notification_ids.count(notification_id) == 0); // there must be no additions after edit CHECK(edited_notification_ids.count(notification_id) == 0); // there must be no additions after edit
removed_notification_ids.erase(notification_id); removed_notification_ids.erase(notification_id);
} }
for (auto &notification_id : update_ptr->removed_notification_ids_) { for (auto &notification_id : update_ptr->removed_notification_ids_) {
CHECK(notification_id != 0);
added_notification_ids.erase(notification_id); added_notification_ids.erase(notification_id);
edited_notification_ids.erase(notification_id); edited_notification_ids.erase(notification_id);
if (!removed_notification_ids.insert(notification_id).second) { if (!removed_notification_ids.insert(notification_id).second) {
@ -1050,6 +1054,7 @@ void NotificationManager::flush_pending_updates(int32 group_id, const char *sour
CHECK(update->get_id() == td_api::updateNotification::ID); CHECK(update->get_id() == td_api::updateNotification::ID);
auto update_ptr = static_cast<td_api::updateNotification *>(update.get()); auto update_ptr = static_cast<td_api::updateNotification *>(update.get());
auto notification_id = update_ptr->notification_->id_; auto notification_id = update_ptr->notification_->id_;
CHECK(notification_id != 0);
CHECK(removed_notification_ids.count(notification_id) == 0); // there must be no edits of deleted notifications CHECK(removed_notification_ids.count(notification_id) == 0); // there must be no edits of deleted notifications
added_notification_ids.erase(notification_id); added_notification_ids.erase(notification_id);
edited_notification_ids.insert(notification_id); edited_notification_ids.insert(notification_id);
@ -1076,8 +1081,8 @@ void NotificationManager::flush_pending_updates(int32 group_id, const char *sour
size_t cur_pos = 0; size_t cur_pos = 0;
FlatHashMap<int32, size_t> first_add_notification_pos; FlatHashMap<int32, size_t> first_add_notification_pos;
FlatHashMap<int32, size_t> first_edit_notification_pos; FlatHashMap<int32, size_t> first_edit_notification_pos;
std::unordered_set<int32> can_be_deleted_notification_ids; FlatHashSet<int32> can_be_deleted_notification_ids;
std::vector<int32> moved_deleted_notification_ids; vector<int32> moved_deleted_notification_ids;
size_t first_notification_group_pos = 0; size_t first_notification_group_pos = 0;
for (auto &update : updates) { for (auto &update : updates) {
@ -1089,6 +1094,7 @@ void NotificationManager::flush_pending_updates(int32 group_id, const char *sour
for (auto &notification : update_ptr->added_notifications_) { for (auto &notification : update_ptr->added_notifications_) {
auto notification_id = notification->id_; auto notification_id = notification->id_;
CHECK(notification_id != 0);
bool is_needed = bool is_needed =
added_notification_ids.count(notification_id) != 0 || edited_notification_ids.count(notification_id) != 0; added_notification_ids.count(notification_id) != 0 || edited_notification_ids.count(notification_id) != 0;
if (!is_needed) { if (!is_needed) {
@ -1772,7 +1778,7 @@ void NotificationManager::remove_added_notifications_from_pending_updates(
return; return;
} }
std::unordered_set<int32> removed_notification_ids; FlatHashSet<int32> removed_notification_ids;
for (auto &update : it->second) { for (auto &update : it->second) {
if (update == nullptr) { if (update == nullptr) {
continue; continue;
@ -1786,6 +1792,7 @@ void NotificationManager::remove_added_notifications_from_pending_updates(
} }
for (auto &notification : update_ptr->added_notifications_) { for (auto &notification : update_ptr->added_notifications_) {
if (is_removed(notification)) { if (is_removed(notification)) {
CHECK(notification->id_ != 0);
removed_notification_ids.insert(notification->id_); removed_notification_ids.insert(notification->id_);
VLOG(notifications) << "Remove " << NotificationId(notification->id_) << " in " << group_id; VLOG(notifications) << "Remove " << NotificationId(notification->id_) << " in " << group_id;
notification = nullptr; notification = nullptr;
@ -1796,6 +1803,7 @@ void NotificationManager::remove_added_notifications_from_pending_updates(
CHECK(update->get_id() == td_api::updateNotification::ID); CHECK(update->get_id() == td_api::updateNotification::ID);
auto update_ptr = static_cast<td_api::updateNotification *>(update.get()); auto update_ptr = static_cast<td_api::updateNotification *>(update.get());
if (is_removed(update_ptr->notification_)) { if (is_removed(update_ptr->notification_)) {
CHECK(update_ptr->notification_->id_ != 0);
removed_notification_ids.insert(update_ptr->notification_->id_); removed_notification_ids.insert(update_ptr->notification_->id_);
VLOG(notifications) << "Remove " << NotificationId(update_ptr->notification_->id_) << " in " << group_id; VLOG(notifications) << "Remove " << NotificationId(update_ptr->notification_->id_) << " in " << group_id;
update = nullptr; update = nullptr;

View File

@ -25,6 +25,7 @@
#include "td/utils/common.h" #include "td/utils/common.h"
#include "td/utils/FlatHashMap.h" #include "td/utils/FlatHashMap.h"
#include "td/utils/FlatHashSet.h"
#include "td/utils/logging.h" #include "td/utils/logging.h"
#include "td/utils/Status.h" #include "td/utils/Status.h"
#include "td/utils/StringBuilder.h" #include "td/utils/StringBuilder.h"
@ -32,7 +33,6 @@
#include <functional> #include <functional>
#include <map> #include <map>
#include <unordered_set>
namespace td { namespace td {
@ -372,7 +372,7 @@ class NotificationManager final : public Actor {
bool is_binlog_processed_ = false; bool is_binlog_processed_ = false;
bool running_get_difference_ = false; bool running_get_difference_ = false;
std::unordered_set<int32> running_get_chat_difference_; FlatHashSet<int32> running_get_chat_difference_;
NotificationGroups groups_; NotificationGroups groups_;
FlatHashMap<NotificationGroupId, NotificationGroupKey, NotificationGroupIdHash> group_keys_; FlatHashMap<NotificationGroupId, NotificationGroupKey, NotificationGroupIdHash> group_keys_;
@ -383,7 +383,7 @@ class NotificationManager final : public Actor {
MultiTimeout flush_pending_updates_timeout_{"FlushPendingUpdatesTimeout"}; MultiTimeout flush_pending_updates_timeout_{"FlushPendingUpdatesTimeout"};
vector<NotificationGroupId> call_notification_group_ids_; vector<NotificationGroupId> call_notification_group_ids_;
std::unordered_set<NotificationGroupId, NotificationGroupIdHash> available_call_notification_group_ids_; FlatHashSet<NotificationGroupId, NotificationGroupIdHash> available_call_notification_group_ids_;
FlatHashMap<DialogId, NotificationGroupId, DialogIdHash> dialog_id_to_call_notification_group_id_; FlatHashMap<DialogId, NotificationGroupId, DialogIdHash> dialog_id_to_call_notification_group_id_;
FlatHashMap<NotificationId, uint64, NotificationIdHash> temporary_notification_log_event_ids_; FlatHashMap<NotificationId, uint64, NotificationIdHash> temporary_notification_log_event_ids_;

View File

@ -337,6 +337,7 @@ void PollManager::save_poll(const Poll *poll, PollId poll_id) {
} }
void PollManager::on_load_poll_from_database(PollId poll_id, string value) { void PollManager::on_load_poll_from_database(PollId poll_id, string value) {
CHECK(poll_id.is_valid());
loaded_from_database_polls_.insert(poll_id); loaded_from_database_polls_.insert(poll_id);
LOG(INFO) << "Successfully loaded " << poll_id << " of size " << value.size() << " from database"; LOG(INFO) << "Successfully loaded " << poll_id << " of size " << value.size() << " from database";
@ -1126,6 +1127,8 @@ class PollManager::StopPollLogEvent {
void PollManager::do_stop_poll(PollId poll_id, FullMessageId full_message_id, unique_ptr<ReplyMarkup> &&reply_markup, void PollManager::do_stop_poll(PollId poll_id, FullMessageId full_message_id, unique_ptr<ReplyMarkup> &&reply_markup,
uint64 log_event_id, Promise<Unit> &&promise) { uint64 log_event_id, Promise<Unit> &&promise) {
LOG(INFO) << "Stop " << poll_id << " from " << full_message_id; LOG(INFO) << "Stop " << poll_id << " from " << full_message_id;
CHECK(poll_id.is_valid());
if (log_event_id == 0 && G()->parameters().use_message_db && reply_markup == nullptr) { if (log_event_id == 0 && G()->parameters().use_message_db && reply_markup == nullptr) {
StopPollLogEvent log_event{poll_id, full_message_id}; StopPollLogEvent log_event{poll_id, full_message_id};
log_event_id = log_event_id =
@ -1352,7 +1355,7 @@ PollId PollManager::on_get_poll(PollId poll_id, tl_object_ptr<telegram_api::poll
return PollId(); return PollId();
} }
if (poll_server != nullptr) { if (poll_server != nullptr) {
std::unordered_set<Slice, SliceHash> option_data; FlatHashSet<Slice, SliceHash> option_data;
for (auto &answer : poll_server->answers_) { for (auto &answer : poll_server->answers_) {
if (answer->option_.empty()) { if (answer->option_.empty()) {
LOG(ERROR) << "Receive " << poll_id << " with an empty option data: " << to_string(poll_server); LOG(ERROR) << "Receive " << poll_id << " with an empty option data: " << to_string(poll_server);

View File

@ -22,9 +22,9 @@
#include "td/utils/buffer.h" #include "td/utils/buffer.h"
#include "td/utils/common.h" #include "td/utils/common.h"
#include "td/utils/FlatHashMap.h" #include "td/utils/FlatHashMap.h"
#include "td/utils/FlatHashSet.h"
#include "td/utils/Status.h" #include "td/utils/Status.h"
#include <unordered_set>
#include <utility> #include <utility>
namespace td { namespace td {
@ -209,7 +209,7 @@ class PollManager final : public Actor {
ActorShared<> parent_; ActorShared<> parent_;
FlatHashMap<PollId, unique_ptr<Poll>, PollIdHash> polls_; FlatHashMap<PollId, unique_ptr<Poll>, PollIdHash> polls_;
FlatHashMap<PollId, std::unordered_set<FullMessageId, FullMessageIdHash>, PollIdHash> poll_messages_; FlatHashMap<PollId, FlatHashSet<FullMessageId, FullMessageIdHash>, PollIdHash> poll_messages_;
struct PendingPollAnswer { struct PendingPollAnswer {
vector<string> options_; vector<string> options_;
@ -226,9 +226,9 @@ class PollManager final : public Actor {
uint64 current_generation_ = 0; uint64 current_generation_ = 0;
std::unordered_set<PollId, PollIdHash> loaded_from_database_polls_; FlatHashSet<PollId, PollIdHash> loaded_from_database_polls_;
std::unordered_set<PollId, PollIdHash> being_closed_polls_; FlatHashSet<PollId, PollIdHash> being_closed_polls_;
}; };
} // namespace td } // namespace td

View File

@ -198,6 +198,9 @@ bool RecentDialogList::do_add_dialog(DialogId dialog_id) {
} }
void RecentDialogList::remove_dialog(DialogId dialog_id) { void RecentDialogList::remove_dialog(DialogId dialog_id) {
if (!dialog_id.is_valid()) {
return;
}
if (!is_loaded_) { if (!is_loaded_) {
load_dialogs(Promise<Unit>()); load_dialogs(Promise<Unit>());
} }

View File

@ -12,8 +12,8 @@
#include "td/actor/PromiseFuture.h" #include "td/actor/PromiseFuture.h"
#include "td/utils/common.h" #include "td/utils/common.h"
#include "td/utils/FlatHashSet.h"
#include <unordered_set>
#include <utility> #include <utility>
namespace td { namespace td {
@ -38,7 +38,7 @@ class RecentDialogList final : public Actor {
const char *name_; const char *name_;
size_t max_size_; size_t max_size_;
vector<DialogId> dialog_ids_; vector<DialogId> dialog_ids_;
std::unordered_set<DialogId, DialogIdHash> removed_dialog_ids_; FlatHashSet<DialogId, DialogIdHash> removed_dialog_ids_;
bool is_loaded_ = false; bool is_loaded_ = false;
vector<Promise<Unit>> load_list_queries_; vector<Promise<Unit>> load_list_queries_;

View File

@ -65,7 +65,6 @@
#include <cmath> #include <cmath>
#include <limits> #include <limits>
#include <type_traits> #include <type_traits>
#include <unordered_set>
namespace td { namespace td {
@ -3320,8 +3319,10 @@ void StickersManager::on_get_installed_sticker_sets(bool is_masks,
CHECK(constructor_id == telegram_api::messages_allStickers::ID); CHECK(constructor_id == telegram_api::messages_allStickers::ID);
auto stickers = move_tl_object_as<telegram_api::messages_allStickers>(stickers_ptr); auto stickers = move_tl_object_as<telegram_api::messages_allStickers>(stickers_ptr);
std::unordered_set<StickerSetId, StickerSetIdHash> uninstalled_sticker_sets( FlatHashSet<StickerSetId, StickerSetIdHash> uninstalled_sticker_sets;
installed_sticker_set_ids_[is_masks].begin(), installed_sticker_set_ids_[is_masks].end()); for (auto &sticker_set_id : installed_sticker_set_ids_[is_masks]) {
uninstalled_sticker_sets.insert(sticker_set_id);
}
vector<StickerSetId> sets_to_load; vector<StickerSetId> sets_to_load;
vector<StickerSetId> installed_sticker_set_ids; vector<StickerSetId> installed_sticker_set_ids;
@ -5241,9 +5242,12 @@ void StickersManager::on_get_featured_sticker_sets(
// the count will be fixed in on_load_old_featured_sticker_sets_finished // the count will be fixed in on_load_old_featured_sticker_sets_finished
} }
std::unordered_set<StickerSetId, StickerSetIdHash> unread_sticker_set_ids; FlatHashSet<StickerSetId, StickerSetIdHash> unread_sticker_set_ids;
for (auto &unread_sticker_set_id : featured_stickers->unread_) { for (auto &unread_sticker_set_id : featured_stickers->unread_) {
unread_sticker_set_ids.insert(StickerSetId(unread_sticker_set_id)); StickerSetId sticker_set_id(unread_sticker_set_id);
if (sticker_set_id.is_valid()) {
unread_sticker_set_ids.insert(sticker_set_id);
}
} }
vector<StickerSetId> featured_sticker_set_ids; vector<StickerSetId> featured_sticker_set_ids;
@ -5555,8 +5559,11 @@ int StickersManager::apply_installed_sticker_sets_order(bool is_masks, const vec
return 0; return 0;
} }
std::unordered_set<StickerSetId, StickerSetIdHash> valid_set_ids(current_sticker_set_ids.begin(), FlatHashSet<StickerSetId, StickerSetIdHash> valid_set_ids;
current_sticker_set_ids.end()); for (auto sticker_set_id : current_sticker_set_ids) {
valid_set_ids.insert(sticker_set_id);
}
vector<StickerSetId> new_sticker_set_ids; vector<StickerSetId> new_sticker_set_ids;
for (auto sticker_set_id : sticker_set_ids) { for (auto sticker_set_id : sticker_set_ids) {
auto it = valid_set_ids.find(sticker_set_id); auto it = valid_set_ids.find(sticker_set_id);
@ -5845,7 +5852,7 @@ void StickersManager::create_new_sticker_set(UserId user_id, string &title, stri
file_ids.reserve(stickers.size()); file_ids.reserve(stickers.size());
vector<FileId> local_file_ids; vector<FileId> local_file_ids;
vector<FileId> url_file_ids; vector<FileId> url_file_ids;
std::unordered_set<int32> sticker_formats; FlatHashSet<int32> sticker_formats;
StickerFormat sticker_format = StickerFormat::Unknown; StickerFormat sticker_format = StickerFormat::Unknown;
for (auto &sticker : stickers) { for (auto &sticker : stickers) {
auto r_file_id = prepare_input_sticker(sticker.get()); auto r_file_id = prepare_input_sticker(sticker.get());

View File

@ -26,6 +26,7 @@
#include "td/utils/buffer.h" #include "td/utils/buffer.h"
#include "td/utils/common.h" #include "td/utils/common.h"
#include "td/utils/FlatHashMap.h" #include "td/utils/FlatHashMap.h"
#include "td/utils/FlatHashSet.h"
#include "td/utils/Hints.h" #include "td/utils/Hints.h"
#include "td/utils/Slice.h" #include "td/utils/Slice.h"
#include "td/utils/Status.h" #include "td/utils/Status.h"
@ -33,7 +34,6 @@
#include <memory> #include <memory>
#include <tuple> #include <tuple>
#include <unordered_map> #include <unordered_map>
#include <unordered_set>
#include <utility> #include <utility>
namespace td { namespace td {
@ -831,7 +831,7 @@ class StickersManager final : public Actor {
std::unordered_map<string, vector<StickerSetId>> found_sticker_sets_; std::unordered_map<string, vector<StickerSetId>> found_sticker_sets_;
std::unordered_map<string, vector<Promise<Unit>>> search_sticker_sets_queries_; std::unordered_map<string, vector<Promise<Unit>>> search_sticker_sets_queries_;
std::unordered_set<StickerSetId, StickerSetIdHash> pending_viewed_featured_sticker_set_ids_; FlatHashSet<StickerSetId, StickerSetIdHash> pending_viewed_featured_sticker_set_ids_;
Timeout pending_featured_sticker_set_views_timeout_; Timeout pending_featured_sticker_set_views_timeout_;
int32 recent_stickers_limit_ = 200; int32 recent_stickers_limit_ = 200;
@ -881,15 +881,15 @@ class StickersManager final : public Actor {
FlatHashMap<string, vector<string>> emoji_language_codes_; FlatHashMap<string, vector<string>> emoji_language_codes_;
FlatHashMap<string, int32> emoji_language_code_versions_; FlatHashMap<string, int32> emoji_language_code_versions_;
FlatHashMap<string, double> emoji_language_code_last_difference_times_; FlatHashMap<string, double> emoji_language_code_last_difference_times_;
std::unordered_set<string> reloaded_emoji_keywords_; FlatHashSet<string> reloaded_emoji_keywords_;
FlatHashMap<string, vector<Promise<Unit>>> load_emoji_keywords_queries_; FlatHashMap<string, vector<Promise<Unit>>> load_emoji_keywords_queries_;
FlatHashMap<string, vector<Promise<Unit>>> load_language_codes_queries_; FlatHashMap<string, vector<Promise<Unit>>> load_language_codes_queries_;
FlatHashMap<int64, string> emoji_suggestions_urls_; FlatHashMap<int64, string> emoji_suggestions_urls_;
FlatHashMap<string, std::unordered_set<FullMessageId, FullMessageIdHash>> dice_messages_; FlatHashMap<string, FlatHashSet<FullMessageId, FullMessageIdHash>> dice_messages_;
struct EmojiMessages { struct EmojiMessages {
std::unordered_set<FullMessageId, FullMessageIdHash> full_message_ids; FlatHashSet<FullMessageId, FullMessageIdHash> full_message_ids;
std::pair<FileId, int> animated_emoji_sticker; std::pair<FileId, int> animated_emoji_sticker;
FileId sound_file_id; FileId sound_file_id;
}; };

View File

@ -1064,14 +1064,14 @@ vector<tl_object_ptr<telegram_api::Update>> *UpdatesManager::get_updates(telegra
get_updates(static_cast<const telegram_api::Updates *>(updates_ptr))); get_updates(static_cast<const telegram_api::Updates *>(updates_ptr)));
} }
std::unordered_set<int64> UpdatesManager::get_sent_messages_random_ids(const telegram_api::Updates *updates_ptr) { FlatHashSet<int64> UpdatesManager::get_sent_messages_random_ids(const telegram_api::Updates *updates_ptr) {
std::unordered_set<int64> random_ids; FlatHashSet<int64> random_ids;
auto updates = get_updates(updates_ptr); auto updates = get_updates(updates_ptr);
if (updates != nullptr) { if (updates != nullptr) {
for (auto &update : *updates) { for (auto &update : *updates) {
if (update->get_id() == telegram_api::updateMessageID::ID) { if (update->get_id() == telegram_api::updateMessageID::ID) {
int64 random_id = static_cast<const telegram_api::updateMessageID *>(update.get())->random_id_; int64 random_id = static_cast<const telegram_api::updateMessageID *>(update.get())->random_id_;
if (!random_ids.insert(random_id).second) { if (random_id != 0 && !random_ids.insert(random_id).second) {
LOG(ERROR) << "Receive twice updateMessageID for " << random_id; LOG(ERROR) << "Receive twice updateMessageID for " << random_id;
} }
} }

View File

@ -21,13 +21,13 @@
#include "td/actor/Timeout.h" #include "td/actor/Timeout.h"
#include "td/utils/common.h" #include "td/utils/common.h"
#include "td/utils/FlatHashSet.h"
#include "td/utils/logging.h" #include "td/utils/logging.h"
#include "td/utils/Status.h" #include "td/utils/Status.h"
#include "td/utils/tl_storers.h" #include "td/utils/tl_storers.h"
#include "td/utils/TlStorerToString.h" #include "td/utils/TlStorerToString.h"
#include <map> #include <map>
#include <unordered_set>
namespace td { namespace td {
@ -99,7 +99,7 @@ class UpdatesManager final : public Actor {
void add_pending_pts_update(tl_object_ptr<telegram_api::Update> &&update, int32 new_pts, int32 pts_count, void add_pending_pts_update(tl_object_ptr<telegram_api::Update> &&update, int32 new_pts, int32 pts_count,
double receive_time, Promise<Unit> &&promise, const char *source); double receive_time, Promise<Unit> &&promise, const char *source);
static std::unordered_set<int64> get_sent_messages_random_ids(const telegram_api::Updates *updates_ptr); static FlatHashSet<int64> get_sent_messages_random_ids(const telegram_api::Updates *updates_ptr);
static vector<const tl_object_ptr<telegram_api::Message> *> get_new_messages( static vector<const tl_object_ptr<telegram_api::Message> *> get_new_messages(
const telegram_api::Updates *updates_ptr); const telegram_api::Updates *updates_ptr);

View File

@ -1634,6 +1634,7 @@ void WebPagesManager::on_load_web_page_from_database(WebPageId web_page_id, stri
if (G()->close_flag()) { if (G()->close_flag()) {
return; return;
} }
CHECK(web_page_id.is_valid());
if (!loaded_from_database_web_pages_.insert(web_page_id).second) { if (!loaded_from_database_web_pages_.insert(web_page_id).second) {
return; return;
} }

View File

@ -21,9 +21,9 @@
#include "td/utils/common.h" #include "td/utils/common.h"
#include "td/utils/FlatHashMap.h" #include "td/utils/FlatHashMap.h"
#include "td/utils/FlatHashSet.h"
#include "td/utils/Status.h" #include "td/utils/Status.h"
#include <unordered_set>
#include <utility> #include <utility>
namespace td { namespace td {
@ -182,7 +182,7 @@ class WebPagesManager final : public Actor {
FlatHashMap<WebPageId, unique_ptr<WebPage>, WebPageIdHash> web_pages_; FlatHashMap<WebPageId, unique_ptr<WebPage>, WebPageIdHash> web_pages_;
FlatHashMap<WebPageId, vector<Promise<Unit>>, WebPageIdHash> load_web_page_from_database_queries_; FlatHashMap<WebPageId, vector<Promise<Unit>>, WebPageIdHash> load_web_page_from_database_queries_;
std::unordered_set<WebPageId, WebPageIdHash> loaded_from_database_web_pages_; FlatHashSet<WebPageId, WebPageIdHash> loaded_from_database_web_pages_;
struct PendingWebPageInstantViewQueries { struct PendingWebPageInstantViewQueries {
vector<Promise<WebPageId>> partial; vector<Promise<WebPageId>> partial;
@ -190,7 +190,7 @@ class WebPagesManager final : public Actor {
}; };
FlatHashMap<WebPageId, PendingWebPageInstantViewQueries, WebPageIdHash> load_web_page_instant_view_queries_; FlatHashMap<WebPageId, PendingWebPageInstantViewQueries, WebPageIdHash> load_web_page_instant_view_queries_;
FlatHashMap<WebPageId, std::unordered_set<FullMessageId, FullMessageIdHash>, WebPageIdHash> web_page_messages_; FlatHashMap<WebPageId, FlatHashSet<FullMessageId, FullMessageIdHash>, WebPageIdHash> web_page_messages_;
FlatHashMap<WebPageId, FlatHashMap<int64, std::pair<string, Promise<Unit>>>, WebPageIdHash> pending_get_web_pages_; FlatHashMap<WebPageId, FlatHashMap<int64, std::pair<string, Promise<Unit>>>, WebPageIdHash> pending_get_web_pages_;

View File

@ -26,6 +26,7 @@
#include "td/utils/FileLog.h" #include "td/utils/FileLog.h"
#include "td/utils/filesystem.h" #include "td/utils/filesystem.h"
#include "td/utils/FlatHashMap.h" #include "td/utils/FlatHashMap.h"
#include "td/utils/FlatHashSet.h"
#include "td/utils/format.h" #include "td/utils/format.h"
#include "td/utils/JsonBuilder.h" #include "td/utils/JsonBuilder.h"
#include "td/utils/logging.h" #include "td/utils/logging.h"
@ -64,7 +65,6 @@
#include <memory> #include <memory>
#include <queue> #include <queue>
#include <tuple> #include <tuple>
#include <unordered_set>
#include <utility> #include <utility>
#ifdef USE_READLINE #ifdef USE_READLINE
@ -432,9 +432,9 @@ class CliClient final : public Actor {
} }
static char get_delimiter(Slice str) { static char get_delimiter(Slice str) {
std::unordered_set<char> chars; FlatHashSet<char> chars;
for (auto c : trim(str)) { for (auto c : trim(str)) {
if (!is_alnum(c) && c != '-' && c != '.' && c != '/' && static_cast<uint8>(c) <= 127) { if (!is_alnum(c) && c != '-' && c != '.' && c != '/' && c != '\0' && static_cast<uint8>(c) <= 127) {
chars.insert(c); chars.insert(c);
} }
} }

View File

@ -48,7 +48,6 @@
#include <limits> #include <limits>
#include <numeric> #include <numeric>
#include <tuple> #include <tuple>
#include <unordered_set>
#include <utility> #include <utility>
namespace td { namespace td {
@ -827,7 +826,7 @@ FileManager::FileManager(unique_ptr<Context> context) : context_(std::move(conte
next_file_id(); next_file_id();
next_file_node_id(); next_file_node_id();
std::unordered_set<string> dir_paths; FlatHashSet<string> dir_paths;
for (int32 i = 0; i < MAX_FILE_TYPE; i++) { for (int32 i = 0; i < MAX_FILE_TYPE; i++) {
dir_paths.insert(get_files_dir(static_cast<FileType>(i))); dir_paths.insert(get_files_dir(static_cast<FileType>(i)));
} }
@ -1787,8 +1786,8 @@ void FileManager::on_file_reference_repaired(FileId file_id, FileSourceId file_s
promise.set_result(std::move(result)); promise.set_result(std::move(result));
} }
std::unordered_set<FileId, FileIdHash> FileManager::get_main_file_ids(const vector<FileId> &file_ids) { FlatHashSet<FileId, FileIdHash> FileManager::get_main_file_ids(const vector<FileId> &file_ids) {
std::unordered_set<FileId, FileIdHash> result; FlatHashSet<FileId, FileIdHash> result;
for (auto file_id : file_ids) { for (auto file_id : file_ids) {
auto node = get_file_node(file_id); auto node = get_file_node(file_id);
if (node) { if (node) {

View File

@ -28,6 +28,7 @@
#include "td/utils/Container.h" #include "td/utils/Container.h"
#include "td/utils/Enumerator.h" #include "td/utils/Enumerator.h"
#include "td/utils/FlatHashMap.h" #include "td/utils/FlatHashMap.h"
#include "td/utils/FlatHashSet.h"
#include "td/utils/logging.h" #include "td/utils/logging.h"
#include "td/utils/optional.h" #include "td/utils/optional.h"
#include "td/utils/Slice.h" #include "td/utils/Slice.h"
@ -37,7 +38,6 @@
#include <map> #include <map>
#include <memory> #include <memory>
#include <set> #include <set>
#include <unordered_set>
#include <utility> #include <utility>
namespace td { namespace td {
@ -666,7 +666,7 @@ class FileManager final : public FileLoadManager::Callback {
FullRemoteFileLocation *get_remote(int32 key); FullRemoteFileLocation *get_remote(int32 key);
std::unordered_set<FileId, FileIdHash> get_main_file_ids(const vector<FileId> &file_ids); FlatHashSet<FileId, FileIdHash> get_main_file_ids(const vector<FileId> &file_ids);
void hangup() final; void hangup() final;
void tear_down() final; void tear_down() final;

View File

@ -11,11 +11,11 @@
#include "td/utils/algorithm.h" #include "td/utils/algorithm.h"
#include "td/utils/common.h" #include "td/utils/common.h"
#include "td/utils/FlatHashSet.h"
#include "td/utils/format.h" #include "td/utils/format.h"
#include "td/utils/misc.h" #include "td/utils/misc.h"
#include <algorithm> #include <algorithm>
#include <unordered_set>
#include <utility> #include <utility>
namespace td { namespace td {
@ -109,11 +109,15 @@ void FileStats::apply_dialog_limit(int32 limit) {
} }
void FileStats::apply_dialog_ids(const vector<DialogId> &dialog_ids) { void FileStats::apply_dialog_ids(const vector<DialogId> &dialog_ids) {
std::unordered_set<DialogId, DialogIdHash> all_dialogs(dialog_ids.begin(), dialog_ids.end()); FlatHashSet<DialogId, DialogIdHash> all_dialog_ids;
for (auto &dialog_id : dialog_ids) {
CHECK(dialog_id.is_valid());
all_dialog_ids.insert(dialog_id);
}
StatByType other_stats; StatByType other_stats;
bool other_flag = false; bool other_flag = false;
table_remove_if(stat_by_owner_dialog_id_, [&](const auto &it) { table_remove_if(stat_by_owner_dialog_id_, [&](const auto &it) {
if (!all_dialogs.count(it.first)) { if (!all_dialog_ids.count(it.first)) {
for (int32 i = 0; i < MAX_FILE_TYPE; i++) { for (int32 i = 0; i < MAX_FILE_TYPE; i++) {
other_stats[i].size += it.second[i].size; other_stats[i].size += it.second[i].size;
other_stats[i].cnt += it.second[i].cnt; other_stats[i].cnt += it.second[i].cnt;

View File

@ -726,6 +726,7 @@ void Session::mark_as_unknown(uint64 id, Query *query) {
} }
VLOG(net_query) << "Mark as unknown " << tag("msg_id", id) << query->query; VLOG(net_query) << "Mark as unknown " << tag("msg_id", id) << query->query;
query->unknown = true; query->unknown = true;
CHECK(id != 0);
unknown_queries_.insert(id); unknown_queries_.insert(id);
} }

View File

@ -23,6 +23,7 @@
#include "td/utils/CancellationToken.h" #include "td/utils/CancellationToken.h"
#include "td/utils/common.h" #include "td/utils/common.h"
#include "td/utils/FlatHashMap.h" #include "td/utils/FlatHashMap.h"
#include "td/utils/FlatHashSet.h"
#include "td/utils/List.h" #include "td/utils/List.h"
#include "td/utils/Status.h" #include "td/utils/Status.h"
#include "td/utils/StringBuilder.h" #include "td/utils/StringBuilder.h"
@ -33,7 +34,6 @@
#include <functional> #include <functional>
#include <map> #include <map>
#include <memory> #include <memory>
#include <unordered_set>
#include <utility> #include <utility>
namespace td { namespace td {
@ -122,8 +122,8 @@ class Session final
double last_success_timestamp_ = 0; // time when auth_key and Session definitely was valid double last_success_timestamp_ = 0; // time when auth_key and Session definitely was valid
size_t dropped_size_ = 0; size_t dropped_size_ = 0;
std::unordered_set<uint64> unknown_queries_; FlatHashSet<uint64> unknown_queries_;
std::vector<int64> to_cancel_; vector<int64> to_cancel_;
// Do not invalidate iterators of these two containers! // Do not invalidate iterators of these two containers!
// TODO: better data structures // TODO: better data structures

View File

@ -9,6 +9,7 @@
#include "td/utils/algorithm.h" #include "td/utils/algorithm.h"
#include "td/utils/common.h" #include "td/utils/common.h"
#include "td/utils/Container.h" #include "td/utils/Container.h"
#include "td/utils/FlatHashSet.h"
#include "td/utils/List.h" #include "td/utils/List.h"
#include "td/utils/logging.h" #include "td/utils/logging.h"
#include "td/utils/optional.h" #include "td/utils/optional.h"
@ -18,7 +19,6 @@
#include <functional> #include <functional>
#include <unordered_map> #include <unordered_map>
#include <unordered_set>
namespace td { namespace td {
@ -56,7 +56,7 @@ class ChainScheduler final : public ChainSchedulerBase {
void for_each_dependent(TaskId task_id, F &&f) { void for_each_dependent(TaskId task_id, F &&f) {
auto *task = tasks_.get(task_id); auto *task = tasks_.get(task_id);
CHECK(task != nullptr); CHECK(task != nullptr);
std::unordered_set<TaskId> visited; FlatHashSet<TaskId> visited;
bool check_for_collisions = task->chains.size() > 1; bool check_for_collisions = task->chains.size() > 1;
for (TaskChainInfo &task_chain_info : task->chains) { for (TaskChainInfo &task_chain_info : task->chains) {
ChainInfo &chain_info = *task_chain_info.chain_info; ChainInfo &chain_info = *task_chain_info.chain_info;

View File

@ -68,9 +68,16 @@ class FlatHashTable {
reference operator*() { reference operator*() {
return it_->get_public(); return it_->get_public();
} }
const value_type &operator*() const {
return it_->get_public();
}
pointer operator->() { pointer operator->() {
return &it_->get_public(); return &it_->get_public();
} }
const value_type *operator->() const {
return &it_->get_public();
}
NodeT *get() { NodeT *get() {
return it_; return it_;
} }
@ -108,10 +115,10 @@ class FlatHashTable {
++it_; ++it_;
return *this; return *this;
} }
reference operator*() { reference operator*() const {
return *it_; return *it_;
} }
pointer operator->() { pointer operator->() const {
return &*it_; return &*it_;
} }
bool operator==(const ConstIterator &other) const { bool operator==(const ConstIterator &other) const {
@ -358,12 +365,17 @@ class FlatHashTable {
return; return;
} }
resize(other.bucket_count()); resize(other.bucket_count());
for (const auto &new_node : other) { auto other_nodes_end = other.nodes_ + other.bucket_count_;
auto bucket = calc_bucket(new_node.key()); for (const NodeT *other_node = other.nodes_; other_node != other_nodes_end; ++other_node) {
if (other_node->empty()) {
continue;
}
auto bucket = calc_bucket(other_node->key());
while (true) { while (true) {
auto &node = nodes_[bucket]; auto &node = nodes_[bucket];
if (node.empty()) { if (node.empty()) {
node.copy_from(new_node); node.copy_from(*other_node);
break; break;
} }
next_bucket(bucket); next_bucket(bucket);

View File

@ -45,8 +45,8 @@ struct SetNode {
void copy_from(const SetNode &other) { void copy_from(const SetNode &other) {
DCHECK(empty()); DCHECK(empty());
DCHECK(!other.empty());
first = other.first; first = other.first;
DCHECK(!empty());
} }
bool empty() const { bool empty() const {

View File

@ -7,16 +7,15 @@
#include "td/utils/emoji.h" #include "td/utils/emoji.h"
#include "td/utils/base64.h" #include "td/utils/base64.h"
#include "td/utils/FlatHashSet.h"
#include "td/utils/Gzip.h" #include "td/utils/Gzip.h"
#include "td/utils/misc.h" #include "td/utils/misc.h"
#include <unordered_set>
namespace td { namespace td {
bool is_emoji(Slice str) { bool is_emoji(Slice str) {
constexpr size_t MAX_EMOJI_LENGTH = 35; constexpr size_t MAX_EMOJI_LENGTH = 35;
static const std::unordered_set<Slice, SliceHash> emojis = [max_emoji_length = MAX_EMOJI_LENGTH] { static const FlatHashSet<Slice, SliceHash> emojis = [max_emoji_length = MAX_EMOJI_LENGTH] {
#if TD_HAVE_ZLIB #if TD_HAVE_ZLIB
Slice packed_emojis( Slice packed_emojis(
"eJyNnety27i2rV8lVfvf-XXul7frVmfZ6cS6kKJskrLj7tUUaUmOI1uObcUEWLUfJecBdledFzgaJIfJiUkyqyqAJ4wxJzE_QABF2fGPs_" "eJyNnety27i2rV8lVfvf-XXul7frVmfZ6cS6kKJskrLj7tUUaUmOI1uObcUEWLUfJecBdledFzgaJIfJiUkyqyqAJ4wxJzE_QABF2fGPs_"
@ -202,7 +201,7 @@ bool is_emoji(Slice str) {
string all_emojis_str; string all_emojis_str;
constexpr size_t EMOJI_COUNT = 0; constexpr size_t EMOJI_COUNT = 0;
#endif #endif
std::unordered_set<Slice, SliceHash> all_emojis; FlatHashSet<Slice, SliceHash> all_emojis;
all_emojis.reserve(EMOJI_COUNT); all_emojis.reserve(EMOJI_COUNT);
for (size_t i = 0; i < all_emojis_str.size(); i++) { for (size_t i = 0; i < all_emojis_str.size(); i++) {
CHECK(all_emojis_str[i] != ' '); CHECK(all_emojis_str[i] != ' ');

View File

@ -14,6 +14,7 @@
#include "td/utils/common.h" #include "td/utils/common.h"
#include "td/utils/ExitGuard.h" #include "td/utils/ExitGuard.h"
#include "td/utils/FlatHashSet.h"
#include "td/utils/logging.h" #include "td/utils/logging.h"
#include "td/utils/misc.h" #include "td/utils/misc.h"
#include "td/utils/port/detail/PollableFd.h" #include "td/utils/port/detail/PollableFd.h"
@ -26,7 +27,6 @@
#include <cstring> #include <cstring>
#include <mutex> #include <mutex>
#include <unordered_set>
#include <utility> #include <utility>
#if TD_PORT_POSIX #if TD_PORT_POSIX
@ -384,14 +384,14 @@ Result<size_t> FileFd::pread(MutableSlice slice, int64 offset) const {
} }
static std::mutex in_process_lock_mutex; static std::mutex in_process_lock_mutex;
static std::unordered_set<string> locked_files; static FlatHashSet<string> locked_files;
static ExitGuard exit_guard; static ExitGuard exit_guard;
static Status create_local_lock(const string &path, int32 &max_tries) { static Status create_local_lock(const string &path, int32 &max_tries) {
while (true) { while (true) {
{ // mutex lock scope { // mutex lock scope
std::lock_guard<std::mutex> lock(in_process_lock_mutex); std::lock_guard<std::mutex> lock(in_process_lock_mutex);
if (locked_files.find(path) == locked_files.end()) { if (!path.empty() && locked_files.find(path) == locked_files.end()) {
VLOG(fd) << "Lock file \"" << path << '"'; VLOG(fd) << "Lock file \"" << path << '"';
locked_files.insert(path); locked_files.insert(path);
return Status::OK(); return Status::OK();
@ -505,7 +505,7 @@ void FileFd::remove_local_lock(const string &path) {
VLOG(fd) << "Unlock file \"" << path << '"'; VLOG(fd) << "Unlock file \"" << path << '"';
std::unique_lock<std::mutex> lock(in_process_lock_mutex); std::unique_lock<std::mutex> lock(in_process_lock_mutex);
auto erased_count = locked_files.erase(path); auto erased_count = locked_files.erase(path);
CHECK(erased_count > 0 || ExitGuard::is_exited()); CHECK(erased_count > 0 || path.empty() || ExitGuard::is_exited());
} }
void FileFd::close() { void FileFd::close() {

View File

@ -7,6 +7,7 @@
#pragma once #pragma once
#include "td/utils/common.h" #include "td/utils/common.h"
#include "td/utils/FlatHashSet.h"
#include "td/utils/misc.h" #include "td/utils/misc.h"
#include "td/utils/SharedSlice.h" #include "td/utils/SharedSlice.h"
#include "td/utils/Slice.h" #include "td/utils/Slice.h"
@ -18,7 +19,6 @@
#include "td/utils/Variant.h" #include "td/utils/Variant.h"
#include <type_traits> #include <type_traits>
#include <unordered_set>
#include <utility> #include <utility>
#define BEGIN_STORE_FLAGS() \ #define BEGIN_STORE_FLAGS() \
@ -172,15 +172,15 @@ void parse(unique_ptr<T> &ptr, ParserT &parser) {
parse(*ptr, parser); parse(*ptr, parser);
} }
template <class Key, class Hash, class KeyEqual, class Allocator, class StorerT> template <class Key, class Hash, class KeyEqual, class StorerT>
void store(const std::unordered_set<Key, Hash, KeyEqual, Allocator> &s, StorerT &storer) { void store(const FlatHashSet<Key, Hash, KeyEqual> &s, StorerT &storer) {
storer.store_binary(narrow_cast<int32>(s.size())); storer.store_binary(narrow_cast<int32>(s.size()));
for (auto &val : s) { for (auto &val : s) {
store(val, storer); store(val, storer);
} }
} }
template <class Key, class Hash, class KeyEqual, class Allocator, class ParserT> template <class Key, class Hash, class KeyEqual, class ParserT>
void parse(std::unordered_set<Key, Hash, KeyEqual, Allocator> &s, ParserT &parser) { void parse(FlatHashSet<Key, Hash, KeyEqual> &s, ParserT &parser) {
uint32 size = parser.fetch_int(); uint32 size = parser.fetch_int();
if (parser.get_left_len() < size) { if (parser.get_left_len() < size) {
parser.set_error("Wrong set length"); parser.set_error("Wrong set length");