diff --git a/td/telegram/BackgroundManager.h b/td/telegram/BackgroundManager.h index 864a29ee0..b484a4dac 100644 --- a/td/telegram/BackgroundManager.h +++ b/td/telegram/BackgroundManager.h @@ -20,10 +20,10 @@ #include "td/utils/common.h" #include "td/utils/FlatHashMap.h" +#include "td/utils/FlatHashSet.h" #include "td/utils/Status.h" #include -#include #include namespace td { @@ -169,7 +169,7 @@ class BackgroundManager final : public Actor { FlatHashMap file_id_to_background_id_; - std::unordered_set loaded_from_database_backgrounds_; + FlatHashSet loaded_from_database_backgrounds_; FlatHashMap>> being_loaded_from_database_backgrounds_; BackgroundId set_background_id_[2]; diff --git a/td/telegram/CallActor.cpp b/td/telegram/CallActor.cpp index e70d55f86..e43aeb96e 100644 --- a/td/telegram/CallActor.cpp +++ b/td/telegram/CallActor.cpp @@ -25,13 +25,13 @@ #include "td/utils/buffer.h" #include "td/utils/common.h" #include "td/utils/crypto.h" +#include "td/utils/FlatHashSet.h" #include "td/utils/logging.h" #include "td/utils/misc.h" #include "td/utils/Random.h" #include "td/utils/SliceBuilder.h" #include -#include namespace td { @@ -254,7 +254,7 @@ void CallActor::rate_call(int32 rating, string comment, vector tags; + FlatHashSet tags; for (auto &problem : problems) { if (problem == nullptr) { continue; diff --git a/td/telegram/Client.cpp b/td/telegram/Client.cpp index 6a792f605..e9f9bf548 100644 --- a/td/telegram/Client.cpp +++ b/td/telegram/Client.cpp @@ -17,6 +17,7 @@ #include "td/utils/crypto.h" #include "td/utils/ExitGuard.h" #include "td/utils/FlatHashMap.h" +#include "td/utils/FlatHashSet.h" #include "td/utils/logging.h" #include "td/utils/misc.h" #include "td/utils/MpscPollableQueue.h" @@ -30,7 +31,6 @@ #include #include #include -#include namespace td { @@ -204,7 +204,7 @@ class ClientManager::Impl final { unique_ptr concurrent_scheduler_; ClientId client_id_{0}; Td::Options options_; - std::unordered_set pending_clients_; + FlatHashSet pending_clients_; FlatHashMap> tds_; }; diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index d1f1087c8..47080e9d2 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -69,6 +69,7 @@ #include #include #include +#include #include namespace td { @@ -8152,7 +8153,7 @@ void ContactsManager::on_get_contacts(tl_object_ptr(new_contacts); - std::unordered_set contact_user_ids; + FlatHashSet contact_user_ids; for (auto &user : contacts->users_) { auto user_id = get_user_id(user); if (!user_id.is_valid()) { @@ -8719,6 +8720,7 @@ void ContactsManager::on_load_user_from_database(UserId user_id, string value, b return; } + CHECK(user_id.is_valid()); if (!loaded_from_database_users_.insert(user_id).second) { return; } @@ -9020,6 +9022,7 @@ void ContactsManager::on_load_chat_from_database(ChatId chat_id, string value, b return; } + CHECK(chat_id.is_valid()); if (!loaded_from_database_chats_.insert(chat_id).second) { return; } @@ -9259,6 +9262,7 @@ void ContactsManager::on_load_channel_from_database(ChannelId channel_id, string return; } + CHECK(channel_id.is_valid()); if (!loaded_from_database_channels_.insert(channel_id).second) { return; } @@ -9515,6 +9519,7 @@ void ContactsManager::on_load_secret_chat_from_database(SecretChatId secret_chat return; } + CHECK(secret_chat_id.is_valid()); if (!loaded_from_database_secret_chats_.insert(secret_chat_id).second) { return; } @@ -12175,8 +12180,11 @@ void ContactsManager::on_get_channel_participants( search_among_dialogs(dialog_ids, additional_query, additional_limit); total_count = result_dialog_ids.first; - std::unordered_set result_dialog_ids_set(result_dialog_ids.second.begin(), - result_dialog_ids.second.end()); + FlatHashSet result_dialog_ids_set; + 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); result.clear(); for (auto &participant : all_participants) { @@ -12502,7 +12510,7 @@ void ContactsManager::invalidate_channel_full(ChannelId channel_id, bool need_dr if (channel_full != nullptr) { do_invalidate_channel_full(channel_full, channel_id, need_drop_slow_mode_delay); update_channel_full(channel_full, channel_id, "invalidate_channel_full"); - } else { + } else if (channel_id.is_valid()) { invalidated_channels_full_.insert(channel_id); } } diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index c031d3d48..26afb6591 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -41,6 +41,7 @@ #include "td/utils/common.h" #include "td/utils/FlatHashMap.h" +#include "td/utils/FlatHashSet.h" #include "td/utils/Hints.h" #include "td/utils/Status.h" #include "td/utils/StringBuilder.h" @@ -48,7 +49,6 @@ #include #include -#include #include namespace td { @@ -629,7 +629,7 @@ class ContactsManager final : public Actor { string language_code; - std::unordered_set photo_ids; + FlatHashSet photo_ids; FlatHashMap online_member_dialogs; // id -> time @@ -1642,7 +1642,7 @@ class ContactsManager final : public Actor { FlatHashMap, UserIdHash> users_; FlatHashMap, UserIdHash> users_full_; FlatHashMap user_photos_; - mutable std::unordered_set unknown_users_; + mutable FlatHashSet unknown_users_; FlatHashMap, UserIdHash> pending_user_photos_; struct UserIdPhotoIdHash { std::size_t operator()(const std::pair &pair) const { @@ -1654,23 +1654,23 @@ class ContactsManager final : public Actor { FlatHashMap, ChatIdHash> chats_; FlatHashMap, ChatIdHash> chats_full_; - mutable std::unordered_set unknown_chats_; + mutable FlatHashSet unknown_chats_; FlatHashMap chat_full_file_source_ids_; FlatHashMap, ChannelIdHash> min_channels_; FlatHashMap, ChannelIdHash> channels_; FlatHashMap, ChannelIdHash> channels_full_; - mutable std::unordered_set unknown_channels_; - std::unordered_set invalidated_channels_full_; + mutable FlatHashSet unknown_channels_; + FlatHashSet invalidated_channels_full_; FlatHashMap channel_full_file_source_ids_; FlatHashMap, SecretChatIdHash> secret_chats_; - mutable std::unordered_set unknown_secret_chats_; + mutable FlatHashSet unknown_secret_chats_; FlatHashMap, UserIdHash> secret_chats_with_user_; struct DialogAccessByInviteLink { - std::unordered_set invite_links; + FlatHashSet invite_links; int32 accessible_before = 0; }; FlatHashMap> invite_link_infos_; @@ -1687,19 +1687,19 @@ class ContactsManager final : public Actor { vector inactive_channels_; FlatHashMap>, UserIdHash> load_user_from_database_queries_; - std::unordered_set loaded_from_database_users_; - std::unordered_set unavailable_user_fulls_; + FlatHashSet loaded_from_database_users_; + FlatHashSet unavailable_user_fulls_; FlatHashMap>, ChatIdHash> load_chat_from_database_queries_; - std::unordered_set loaded_from_database_chats_; - std::unordered_set unavailable_chat_fulls_; + FlatHashSet loaded_from_database_chats_; + FlatHashSet unavailable_chat_fulls_; FlatHashMap>, ChannelIdHash> load_channel_from_database_queries_; - std::unordered_set loaded_from_database_channels_; - std::unordered_set unavailable_channel_fulls_; + FlatHashSet loaded_from_database_channels_; + FlatHashSet unavailable_channel_fulls_; FlatHashMap>, SecretChatIdHash> load_secret_chat_from_database_queries_; - std::unordered_set loaded_from_database_secret_chats_; + FlatHashSet loaded_from_database_secret_chats_; QueryCombiner get_user_full_queries_{"GetUserFullCombiner", 2.0}; QueryCombiner get_chat_full_queries_{"GetChatFullCombiner", 2.0}; @@ -1771,7 +1771,7 @@ class ContactsManager final : public Actor { vector users_nearby_; vector channels_nearby_; - std::unordered_set all_users_nearby_; + FlatHashSet all_users_nearby_; int32 location_visibility_expire_date_ = 0; int32 pending_location_visibility_expire_date_ = -1; @@ -1780,8 +1780,8 @@ class ContactsManager final : public Actor { FlatHashMap linked_channel_ids_; - std::unordered_set restricted_user_ids_; - std::unordered_set restricted_channel_ids_; + FlatHashSet restricted_user_ids_; + FlatHashSet restricted_channel_ids_; vector next_all_imported_contacts_; vector imported_contacts_unique_id_; diff --git a/td/telegram/Dependencies.h b/td/telegram/Dependencies.h index 54ddffae5..e4d3541fa 100644 --- a/td/telegram/Dependencies.h +++ b/td/telegram/Dependencies.h @@ -13,19 +13,19 @@ #include "td/telegram/UserId.h" #include "td/telegram/WebPageId.h" -#include +#include "td/utils/FlatHashSet.h" namespace td { class Td; class Dependencies { - std::unordered_set user_ids; - std::unordered_set chat_ids; - std::unordered_set channel_ids; - std::unordered_set secret_chat_ids; - std::unordered_set dialog_ids; - std::unordered_set web_page_ids; + FlatHashSet user_ids; + FlatHashSet chat_ids; + FlatHashSet channel_ids; + FlatHashSet secret_chat_ids; + FlatHashSet dialog_ids; + FlatHashSet web_page_ids; public: void add(UserId user_id); @@ -46,7 +46,7 @@ class Dependencies { bool resolve_force(Td *td, const char *source) const; - const std::unordered_set &get_dialog_ids() const { + const FlatHashSet &get_dialog_ids() const { return dialog_ids; } }; diff --git a/td/telegram/DialogFilter.cpp b/td/telegram/DialogFilter.cpp index 6e97bf379..53f9066dd 100644 --- a/td/telegram/DialogFilter.cpp +++ b/td/telegram/DialogFilter.cpp @@ -10,11 +10,10 @@ #include "td/utils/algorithm.h" #include "td/utils/emoji.h" +#include "td/utils/FlatHashSet.h" #include "td/utils/format.h" #include "td/utils/logging.h" -#include - namespace td { unique_ptr DialogFilter::get_dialog_filter(telegram_api::object_ptr filter, @@ -28,7 +27,7 @@ unique_ptr DialogFilter::get_dialog_filter(telegram_api::object_pt dialog_filter->dialog_filter_id = dialog_filter_id; dialog_filter->title = std::move(filter->title_); dialog_filter->emoji = std::move(filter->emoticon_); - std::unordered_set added_dialog_ids; + FlatHashSet 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->excluded_dialog_ids = InputDialogId::get_input_dialog_ids(filter->exclude_peers_, &added_dialog_ids); @@ -271,7 +270,7 @@ unique_ptr DialogFilter::merge_dialog_filter_changes(const DialogF LOG(INFO) << "Pinned chats was not changed locally in " << dialog_filter_id << ", keep remote changes"; size_t kept_server_dialogs = 0; - std::unordered_set removed_dialog_ids; + FlatHashSet removed_dialog_ids; auto old_it = old_server_dialog_ids.rbegin(); for (auto &input_dialog_id : reversed(new_server_dialog_ids)) { auto dialog_id = input_dialog_id.get_dialog_id(); @@ -283,12 +282,14 @@ unique_ptr DialogFilter::merge_dialog_filter_changes(const DialogF } // 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()); ++old_it; } } while (old_it < old_server_dialog_ids.rend()) { // 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()); ++old_it; } @@ -310,11 +311,12 @@ unique_ptr DialogFilter::merge_dialog_filter_changes(const DialogF } // merge additions and deletions from other clients to the local changes - std::unordered_set deleted_dialog_ids; + FlatHashSet deleted_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()); } - std::unordered_set added_dialog_ids; + FlatHashSet added_dialog_ids; for (const auto &new_dialog_id : new_server_dialog_ids) { auto dialog_id = new_dialog_id.get_dialog_id(); if (deleted_dialog_ids.erase(dialog_id) == 0) { @@ -347,10 +349,12 @@ unique_ptr DialogFilter::merge_dialog_filter_changes(const DialogF new_server_filter->excluded_dialog_ids); { - std::unordered_set added_dialog_ids; + FlatHashSet added_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) { - 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); diff --git a/td/telegram/GroupCallManager.cpp b/td/telegram/GroupCallManager.cpp index 35fb38266..cf68604fb 100644 --- a/td/telegram/GroupCallManager.cpp +++ b/td/telegram/GroupCallManager.cpp @@ -22,13 +22,13 @@ #include "td/utils/algorithm.h" #include "td/utils/buffer.h" +#include "td/utils/FlatHashSet.h" #include "td/utils/logging.h" #include "td/utils/misc.h" #include "td/utils/Random.h" #include "td/utils/SliceBuilder.h" #include -#include #include namespace td { @@ -2064,10 +2064,11 @@ void GroupCallManager::process_group_call_participants( return; } - std::unordered_set old_participant_dialog_ids; + FlatHashSet old_participant_dialog_ids; if (is_sync) { auto *group_call_participants = add_group_call_participants(input_group_call_id); for (auto &participant : group_call_participants->participants) { + CHECK(participant.dialog_id.is_valid()); old_participant_dialog_ids.insert(participant.dialog_id); } } diff --git a/td/telegram/InputDialogId.cpp b/td/telegram/InputDialogId.cpp index 8edec743a..3ffb79873 100644 --- a/td/telegram/InputDialogId.cpp +++ b/td/telegram/InputDialogId.cpp @@ -54,8 +54,8 @@ InputDialogId::InputDialogId(const tl_object_ptr &input vector InputDialogId::get_input_dialog_ids( const vector> &input_peers, - std::unordered_set *added_dialog_ids) { - std::unordered_set temp_added_dialog_ids; + FlatHashSet *added_dialog_ids) { + FlatHashSet temp_added_dialog_ids; if (added_dialog_ids == nullptr) { added_dialog_ids = &temp_added_dialog_ids; } diff --git a/td/telegram/InputDialogId.h b/td/telegram/InputDialogId.h index c4139d62d..ac03ad0c3 100644 --- a/td/telegram/InputDialogId.h +++ b/td/telegram/InputDialogId.h @@ -10,10 +10,9 @@ #include "td/telegram/telegram_api.h" #include "td/utils/common.h" +#include "td/utils/FlatHashSet.h" #include "td/utils/StringBuilder.h" -#include - namespace td { class InputDialogId { @@ -28,9 +27,8 @@ class InputDialogId { explicit InputDialogId(const tl_object_ptr &input_peer); - static vector get_input_dialog_ids( - const vector> &input_peers, - std::unordered_set *added_dialog_ids = nullptr); + static vector get_input_dialog_ids(const vector> &input_peers, + FlatHashSet *added_dialog_ids = nullptr); static vector> get_input_dialog_peers( const vector &input_dialog_ids); diff --git a/td/telegram/LanguagePackManager.cpp b/td/telegram/LanguagePackManager.cpp index 7aa9244fa..589702355 100644 --- a/td/telegram/LanguagePackManager.cpp +++ b/td/telegram/LanguagePackManager.cpp @@ -20,6 +20,7 @@ #include "td/utils/algorithm.h" #include "td/utils/ExitGuard.h" +#include "td/utils/FlatHashSet.h" #include "td/utils/logging.h" #include "td/utils/misc.h" #include "td/utils/SliceBuilder.h" @@ -28,7 +29,6 @@ #include #include #include -#include #include namespace td { @@ -63,7 +63,7 @@ struct LanguagePackManager::Language { vector> get_difference_queries_; FlatHashMap ordinary_strings_; FlatHashMap> pluralized_strings_; - std::unordered_set deleted_strings_; + FlatHashSet deleted_strings_; SqliteKeyValue kv_; // usages should be guarded by database_->mutex_ }; @@ -979,11 +979,11 @@ void LanguagePackManager::on_get_languages(vector> promise) { auto results = td_api::make_object(); - std::unordered_set added_languages; + FlatHashSet added_languages; auto add_language_info = [&results, &added_languages](const string &language_code, const LanguageInfo &info, 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_.back()->is_installed_ = is_installed; } diff --git a/td/telegram/MessageEntity.cpp b/td/telegram/MessageEntity.cpp index e4c5fe96a..74b835548 100644 --- a/td/telegram/MessageEntity.cpp +++ b/td/telegram/MessageEntity.cpp @@ -1270,9 +1270,14 @@ static Slice fix_url(Slice str) { return full_url; } -const std::unordered_set &get_valid_short_usernames() { - static const std::unordered_set valid_usernames{"gif", "wiki", "vid", "bing", "pic", - "bold", "imdb", "coub", "like", "vote"}; +const FlatHashSet &get_valid_short_usernames() { + static const FlatHashSet valid_usernames = [] { + FlatHashSet result; + for (auto username : {"gif", "wiki", "vid", "bing", "pic", "bold", "imdb", "coub", "like", "vote"}) { + result.insert(Slice(username)); + } + return result; + }(); return valid_usernames; } diff --git a/td/telegram/MessageEntity.h b/td/telegram/MessageEntity.h index a4934e4e9..4a0ec6e29 100644 --- a/td/telegram/MessageEntity.h +++ b/td/telegram/MessageEntity.h @@ -13,11 +13,11 @@ #include "td/telegram/UserId.h" #include "td/utils/common.h" +#include "td/utils/FlatHashSet.h" #include "td/utils/Slice.h" #include "td/utils/Status.h" #include "td/utils/StringBuilder.h" -#include #include namespace td { @@ -131,7 +131,7 @@ inline bool operator!=(const FormattedText &lhs, const FormattedText &rhs) { return !(lhs == rhs); } -const std::unordered_set &get_valid_short_usernames(); +const FlatHashSet &get_valid_short_usernames(); Result> get_message_entities(const ContactsManager *contacts_manager, vector> &&input_entities, diff --git a/td/telegram/MessageReaction.cpp b/td/telegram/MessageReaction.cpp index bc0477baf..feade1105 100644 --- a/td/telegram/MessageReaction.cpp +++ b/td/telegram/MessageReaction.cpp @@ -17,11 +17,11 @@ #include "td/utils/algorithm.h" #include "td/utils/buffer.h" +#include "td/utils/FlatHashSet.h" #include "td/utils/logging.h" #include "td/utils/Status.h" #include -#include #include namespace td { @@ -52,7 +52,10 @@ class GetMessagesReactionsQuery final : public Td::ResultHandler { LOG(INFO) << "Receive result for GetMessagesReactionsQuery: " << to_string(ptr); if (ptr->get_id() == telegram_api::updates::ID) { auto &updates = static_cast(ptr.get())->updates_; - std::unordered_set skipped_message_ids(message_ids_.begin(), message_ids_.end()); + FlatHashSet skipped_message_ids; + for (auto message_id : message_ids_) { + skipped_message_ids.insert(message_id); + } for (const auto &update : updates) { if (update->get_id() == telegram_api::updateMessageReactions::ID) { auto update_message_reactions = static_cast(update.get()); @@ -288,10 +291,11 @@ unique_ptr MessageReactions::get_message_reactions( result->can_get_added_reactions_ = reactions->can_see_list_; result->is_min_ = reactions->min_; - std::unordered_set reaction_strings; - std::unordered_set recent_choosers; + FlatHashSet reaction_strings; + FlatHashSet recent_choosers; 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 " << reaction_count->count_; continue; diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index ea2aef805..097c488d0 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -8723,6 +8723,7 @@ void MessagesManager::queue_message_reactions_reload(FullMessageId full_message_ void MessagesManager::queue_message_reactions_reload(DialogId dialog_id, const vector &message_ids) { auto &message_ids_to_reload = being_reloaded_reactions_[dialog_id].message_ids; for (auto &message_id : message_ids) { + CHECK(message_id.is_valid()); message_ids_to_reload.insert(message_id); } 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"); if (is_permanently_deleted) { for (auto id : deleted_message_ids) { + CHECK(id != 0); 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; vector message_ids; - std::unordered_set removed_notification_ids_set; + FlatHashSet removed_notification_ids_set; find_messages(d->messages.get(), message_ids, [](const Message *m) { return m->contains_unread_mention; }); VLOG(notifications) << "Found unread mentions in " << message_ids; for (auto &message_id : message_ids) { @@ -15854,8 +15856,10 @@ void MessagesManager::on_get_dialogs(FolderId folder_id, vector old_pinned_dialog_ids(pinned_dialog_ids.begin(), - pinned_dialog_ids.end()); + FlatHashSet old_pinned_dialog_ids; + 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(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->included_dialog_ids); - std::unordered_set all_dialog_ids; + FlatHashSet all_dialog_ids; for (auto input_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) { - LOG_CHECK(all_dialog_ids.insert(input_dialog_id.get_dialog_id()).second) - << source << ' ' << input_dialog_id.get_dialog_id() << ' ' << dialog_filter; + auto dialog_id = input_dialog_id.get_dialog_id(); + CHECK(dialog_id.is_valid()); + LOG_CHECK(all_dialog_ids.insert(dialog_id).second) << source << ' ' << dialog_id << ' ' << dialog_filter; } } } @@ -19193,7 +19198,7 @@ Result> MessagesManager::create_dialog_filter(DialogFil auto dialog_filter = make_unique(); dialog_filter->dialog_filter_id = dialog_filter_id; - std::unordered_set added_dialog_ids; + FlatHashSet added_dialog_ids; auto add_chats = [this, &added_dialog_ids](vector &input_dialog_ids, const vector &chat_ids) { for (const auto &chat_id : chat_ids) { if (!added_dialog_ids.insert(chat_id).second) { @@ -20129,6 +20134,7 @@ Status MessagesManager::set_pinned_dialogs(DialogListId dialog_list_id, vector new_pinned_dialog_ids; for (auto dialog_id : dialog_ids) { Dialog *d = get_dialog_force(dialog_id, "set_pinned_dialogs"); if (d == nullptr) { @@ -20152,8 +20158,9 @@ Status MessagesManager::set_pinned_dialogs(DialogListId dialog_list_id, vector dialog_count_limit || secret_dialog_count > dialog_count_limit) { return Status::Error(400, "The maximum number of pinned chats exceeded"); } + + new_pinned_dialog_ids.insert(dialog_id); } - std::unordered_set new_pinned_dialog_ids(dialog_ids.begin(), dialog_ids.end()); if (new_pinned_dialog_ids.size() != dialog_ids.size()) { 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 old_pinned_dialog_ids(pinned_dialog_ids.begin(), pinned_dialog_ids.end()); + FlatHashSet 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(); for (auto dialog_id : dialog_ids) { 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) { - 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 &&promise) { @@ -35423,7 +35436,7 @@ void MessagesManager::delete_message_from_database(Dialog *d, MessageId message_ } 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()); } else { // 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::parse_dialog(DialogId dialog_id, const BufferSlice &value, const char *source) { LOG(INFO) << "Loaded " << dialog_id << " of size " << value.size() << " from database from " << source; + CHECK(dialog_id.is_valid()); auto d = make_unique(); d->dialog_id = dialog_id; 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; // identifiers of edited and deleted messages - std::unordered_set changed_message_ids; + FlatHashSet changed_message_ids; for (auto &update_ptr : other_updates) { bool is_good_update = true; switch (update_ptr->get_id()) { @@ -38146,7 +38160,10 @@ void MessagesManager::process_get_channel_difference_updates( for (auto &message : new_messages) { 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 &&events) { auto message_id = log_event.full_message_id_.get_message_id(); 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()); - } else { + } else if (message_id != MessageId()) { d->deleted_message_ids.insert(message_id); } } @@ -39213,7 +39230,10 @@ void MessagesManager::on_binlog_events(vector &&events) { 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()); break; diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 82da324bf..e81a172c9 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -67,6 +67,7 @@ #include "td/utils/ChangesProcessor.h" #include "td/utils/common.h" #include "td/utils/FlatHashMap.h" +#include "td/utils/FlatHashSet.h" #include "td/utils/Heap.h" #include "td/utils/Hints.h" #include "td/utils/logging.h" @@ -1371,11 +1372,11 @@ class MessagesManager final : public Actor { FlatHashMap last_assigned_scheduled_message_id; // date -> message_id - std::unordered_set deleted_message_ids; - std::unordered_set deleted_scheduled_server_message_ids; + FlatHashSet deleted_message_ids; + FlatHashSet deleted_scheduled_server_message_ids; - std::vector> pending_new_message_notifications; - std::vector> pending_new_mention_notifications; + vector> pending_new_message_notifications; + vector> pending_new_mention_notifications; FlatHashMap notification_id_to_message_id; @@ -1388,7 +1389,7 @@ class MessagesManager final : public Actor { std::vector, std::function>> suffix_load_queries_; FlatHashMap pending_viewed_live_locations; // message_id -> task_id - std::unordered_set pending_viewed_message_ids; + FlatHashSet pending_viewed_message_ids; unique_ptr messages; unique_ptr scheduled_messages; @@ -3450,10 +3451,9 @@ class MessagesManager final : public Actor { FlatHashMap, DialogIdHash> dialogs_; - std::unordered_set - loaded_dialogs_; // dialogs loaded from database, but not added to dialogs_ + FlatHashSet loaded_dialogs_; // dialogs loaded from database, but not added to dialogs_ - std::unordered_set postponed_chat_read_inbox_updates_; + FlatHashSet postponed_chat_read_inbox_updates_; struct PendingGetMessageRequest { MessageId message_id; @@ -3504,7 +3504,7 @@ class MessagesManager final : public Actor { FlatHashMap replied_by_yet_unsent_messages_; // full_message_id -> replies with media timestamps - FlatHashMap, FullMessageIdHash> + FlatHashMap, FullMessageIdHash> replied_by_media_timestamp_messages_; struct ActiveDialogAction { @@ -3555,7 +3555,7 @@ class MessagesManager final : public Actor { FlatHashMap get_channel_difference_to_log_event_id_; FlatHashMap channel_get_difference_retry_timeouts_; FlatHashMap, DialogIdHash> postponed_channel_updates_; - std::unordered_set is_channel_difference_finished_; + FlatHashSet is_channel_difference_finished_; MultiTimeout channel_get_difference_timeout_{"ChannelGetDifferenceTimeout"}; 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 - std::unordered_set active_live_location_full_message_ids_; + FlatHashSet active_live_location_full_message_ids_; bool are_active_live_location_messages_loaded_ = false; vector> load_active_live_location_messages_queries_; @@ -3589,7 +3589,7 @@ class MessagesManager final : public Actor { FlatHashMap resolved_usernames_; FlatHashMap inaccessible_resolved_usernames_; - std::unordered_set reload_voice_chat_on_search_usernames_; + FlatHashSet reload_voice_chat_on_search_usernames_; struct GetDialogsTask { 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] struct MessageIds { - std::unordered_set message_ids; + FlatHashSet message_ids; }; FlatHashMap dialog_bot_command_message_ids_; @@ -3671,7 +3671,7 @@ class MessagesManager final : public Actor { FlatHashMap dialog_online_member_counts_; struct ReactionsToReload { - std::unordered_set message_ids; + FlatHashSet message_ids; bool is_request_sent = false; }; FlatHashMap being_reloaded_reactions_; diff --git a/td/telegram/NotificationManager.cpp b/td/telegram/NotificationManager.cpp index 36ae544a7..605588d67 100644 --- a/td/telegram/NotificationManager.cpp +++ b/td/telegram/NotificationManager.cpp @@ -61,7 +61,6 @@ #include #include #include -#include namespace td { @@ -249,6 +248,9 @@ void NotificationManager::init() { }); VLOG(notifications) << "Load call_notification_group_ids = " << 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()) { LOG(ERROR) << "Fix current notification group identifier from " << current_notification_group_id_ << " to " << 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 // calculate last state of all notifications - std::unordered_set added_notification_ids; - std::unordered_set edited_notification_ids; - std::unordered_set removed_notification_ids; + FlatHashSet added_notification_ids; + FlatHashSet edited_notification_ids; + FlatHashSet removed_notification_ids; for (auto &update : updates) { CHECK(update != nullptr); if (update->get_id() == td_api::updateNotificationGroup::ID) { auto update_ptr = static_cast(update.get()); for (auto ¬ification : update_ptr->added_notifications_) { auto notification_id = notification->id_; + CHECK(notification_id != 0); bool is_inserted = added_notification_ids.insert(notification_id).second; 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 removed_notification_ids.erase(notification_id); } for (auto ¬ification_id : update_ptr->removed_notification_ids_) { + CHECK(notification_id != 0); added_notification_ids.erase(notification_id); edited_notification_ids.erase(notification_id); 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); auto update_ptr = static_cast(update.get()); 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 added_notification_ids.erase(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; FlatHashMap first_add_notification_pos; FlatHashMap first_edit_notification_pos; - std::unordered_set can_be_deleted_notification_ids; - std::vector moved_deleted_notification_ids; + FlatHashSet can_be_deleted_notification_ids; + vector moved_deleted_notification_ids; size_t first_notification_group_pos = 0; for (auto &update : updates) { @@ -1089,6 +1094,7 @@ void NotificationManager::flush_pending_updates(int32 group_id, const char *sour for (auto ¬ification : update_ptr->added_notifications_) { auto notification_id = notification->id_; + CHECK(notification_id != 0); bool is_needed = added_notification_ids.count(notification_id) != 0 || edited_notification_ids.count(notification_id) != 0; if (!is_needed) { @@ -1772,7 +1778,7 @@ void NotificationManager::remove_added_notifications_from_pending_updates( return; } - std::unordered_set removed_notification_ids; + FlatHashSet removed_notification_ids; for (auto &update : it->second) { if (update == nullptr) { continue; @@ -1786,6 +1792,7 @@ void NotificationManager::remove_added_notifications_from_pending_updates( } for (auto ¬ification : update_ptr->added_notifications_) { if (is_removed(notification)) { + CHECK(notification->id_ != 0); removed_notification_ids.insert(notification->id_); VLOG(notifications) << "Remove " << NotificationId(notification->id_) << " in " << group_id; notification = nullptr; @@ -1796,6 +1803,7 @@ void NotificationManager::remove_added_notifications_from_pending_updates( CHECK(update->get_id() == td_api::updateNotification::ID); auto update_ptr = static_cast(update.get()); if (is_removed(update_ptr->notification_)) { + CHECK(update_ptr->notification_->id_ != 0); removed_notification_ids.insert(update_ptr->notification_->id_); VLOG(notifications) << "Remove " << NotificationId(update_ptr->notification_->id_) << " in " << group_id; update = nullptr; diff --git a/td/telegram/NotificationManager.h b/td/telegram/NotificationManager.h index 188c595c1..8e54d1bcf 100644 --- a/td/telegram/NotificationManager.h +++ b/td/telegram/NotificationManager.h @@ -25,6 +25,7 @@ #include "td/utils/common.h" #include "td/utils/FlatHashMap.h" +#include "td/utils/FlatHashSet.h" #include "td/utils/logging.h" #include "td/utils/Status.h" #include "td/utils/StringBuilder.h" @@ -32,7 +33,6 @@ #include #include -#include namespace td { @@ -372,7 +372,7 @@ class NotificationManager final : public Actor { bool is_binlog_processed_ = false; bool running_get_difference_ = false; - std::unordered_set running_get_chat_difference_; + FlatHashSet running_get_chat_difference_; NotificationGroups groups_; FlatHashMap group_keys_; @@ -383,7 +383,7 @@ class NotificationManager final : public Actor { MultiTimeout flush_pending_updates_timeout_{"FlushPendingUpdatesTimeout"}; vector call_notification_group_ids_; - std::unordered_set available_call_notification_group_ids_; + FlatHashSet available_call_notification_group_ids_; FlatHashMap dialog_id_to_call_notification_group_id_; FlatHashMap temporary_notification_log_event_ids_; diff --git a/td/telegram/PollManager.cpp b/td/telegram/PollManager.cpp index c0e4a963a..50baf6aad 100644 --- a/td/telegram/PollManager.cpp +++ b/td/telegram/PollManager.cpp @@ -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) { + CHECK(poll_id.is_valid()); loaded_from_database_polls_.insert(poll_id); 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 &&reply_markup, uint64 log_event_id, Promise &&promise) { 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) { StopPollLogEvent log_event{poll_id, full_message_id}; log_event_id = @@ -1352,7 +1355,7 @@ PollId PollManager::on_get_poll(PollId poll_id, tl_object_ptr option_data; + FlatHashSet option_data; for (auto &answer : poll_server->answers_) { if (answer->option_.empty()) { LOG(ERROR) << "Receive " << poll_id << " with an empty option data: " << to_string(poll_server); diff --git a/td/telegram/PollManager.h b/td/telegram/PollManager.h index 2a8e3dd30..01f2bd130 100644 --- a/td/telegram/PollManager.h +++ b/td/telegram/PollManager.h @@ -22,9 +22,9 @@ #include "td/utils/buffer.h" #include "td/utils/common.h" #include "td/utils/FlatHashMap.h" +#include "td/utils/FlatHashSet.h" #include "td/utils/Status.h" -#include #include namespace td { @@ -209,7 +209,7 @@ class PollManager final : public Actor { ActorShared<> parent_; FlatHashMap, PollIdHash> polls_; - FlatHashMap, PollIdHash> poll_messages_; + FlatHashMap, PollIdHash> poll_messages_; struct PendingPollAnswer { vector options_; @@ -226,9 +226,9 @@ class PollManager final : public Actor { uint64 current_generation_ = 0; - std::unordered_set loaded_from_database_polls_; + FlatHashSet loaded_from_database_polls_; - std::unordered_set being_closed_polls_; + FlatHashSet being_closed_polls_; }; } // namespace td diff --git a/td/telegram/RecentDialogList.cpp b/td/telegram/RecentDialogList.cpp index e6b6e945c..9ff84a074 100644 --- a/td/telegram/RecentDialogList.cpp +++ b/td/telegram/RecentDialogList.cpp @@ -198,6 +198,9 @@ bool RecentDialogList::do_add_dialog(DialogId dialog_id) { } void RecentDialogList::remove_dialog(DialogId dialog_id) { + if (!dialog_id.is_valid()) { + return; + } if (!is_loaded_) { load_dialogs(Promise()); } diff --git a/td/telegram/RecentDialogList.h b/td/telegram/RecentDialogList.h index 8618cb0b0..b12edb8a6 100644 --- a/td/telegram/RecentDialogList.h +++ b/td/telegram/RecentDialogList.h @@ -12,8 +12,8 @@ #include "td/actor/PromiseFuture.h" #include "td/utils/common.h" +#include "td/utils/FlatHashSet.h" -#include #include namespace td { @@ -38,7 +38,7 @@ class RecentDialogList final : public Actor { const char *name_; size_t max_size_; vector dialog_ids_; - std::unordered_set removed_dialog_ids_; + FlatHashSet removed_dialog_ids_; bool is_loaded_ = false; vector> load_list_queries_; diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index d29c38d8d..bd57f2d17 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -65,7 +65,6 @@ #include #include #include -#include namespace td { @@ -3320,8 +3319,10 @@ void StickersManager::on_get_installed_sticker_sets(bool is_masks, CHECK(constructor_id == telegram_api::messages_allStickers::ID); auto stickers = move_tl_object_as(stickers_ptr); - std::unordered_set uninstalled_sticker_sets( - installed_sticker_set_ids_[is_masks].begin(), installed_sticker_set_ids_[is_masks].end()); + FlatHashSet uninstalled_sticker_sets; + for (auto &sticker_set_id : installed_sticker_set_ids_[is_masks]) { + uninstalled_sticker_sets.insert(sticker_set_id); + } vector sets_to_load; vector 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 } - std::unordered_set unread_sticker_set_ids; + FlatHashSet unread_sticker_set_ids; 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 featured_sticker_set_ids; @@ -5555,8 +5559,11 @@ int StickersManager::apply_installed_sticker_sets_order(bool is_masks, const vec return 0; } - std::unordered_set valid_set_ids(current_sticker_set_ids.begin(), - current_sticker_set_ids.end()); + FlatHashSet valid_set_ids; + for (auto sticker_set_id : current_sticker_set_ids) { + valid_set_ids.insert(sticker_set_id); + } + vector new_sticker_set_ids; for (auto sticker_set_id : sticker_set_ids) { 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()); vector local_file_ids; vector url_file_ids; - std::unordered_set sticker_formats; + FlatHashSet sticker_formats; StickerFormat sticker_format = StickerFormat::Unknown; for (auto &sticker : stickers) { auto r_file_id = prepare_input_sticker(sticker.get()); diff --git a/td/telegram/StickersManager.h b/td/telegram/StickersManager.h index 51fc727c9..2b0e1fb80 100644 --- a/td/telegram/StickersManager.h +++ b/td/telegram/StickersManager.h @@ -26,6 +26,7 @@ #include "td/utils/buffer.h" #include "td/utils/common.h" #include "td/utils/FlatHashMap.h" +#include "td/utils/FlatHashSet.h" #include "td/utils/Hints.h" #include "td/utils/Slice.h" #include "td/utils/Status.h" @@ -33,7 +34,6 @@ #include #include #include -#include #include namespace td { @@ -831,7 +831,7 @@ class StickersManager final : public Actor { std::unordered_map> found_sticker_sets_; std::unordered_map>> search_sticker_sets_queries_; - std::unordered_set pending_viewed_featured_sticker_set_ids_; + FlatHashSet pending_viewed_featured_sticker_set_ids_; Timeout pending_featured_sticker_set_views_timeout_; int32 recent_stickers_limit_ = 200; @@ -881,15 +881,15 @@ class StickersManager final : public Actor { FlatHashMap> emoji_language_codes_; FlatHashMap emoji_language_code_versions_; FlatHashMap emoji_language_code_last_difference_times_; - std::unordered_set reloaded_emoji_keywords_; + FlatHashSet reloaded_emoji_keywords_; FlatHashMap>> load_emoji_keywords_queries_; FlatHashMap>> load_language_codes_queries_; FlatHashMap emoji_suggestions_urls_; - FlatHashMap> dice_messages_; + FlatHashMap> dice_messages_; struct EmojiMessages { - std::unordered_set full_message_ids; + FlatHashSet full_message_ids; std::pair animated_emoji_sticker; FileId sound_file_id; }; diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index 3c2bb2e71..efc1f2561 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -1064,14 +1064,14 @@ vector> *UpdatesManager::get_updates(telegra get_updates(static_cast(updates_ptr))); } -std::unordered_set UpdatesManager::get_sent_messages_random_ids(const telegram_api::Updates *updates_ptr) { - std::unordered_set random_ids; +FlatHashSet UpdatesManager::get_sent_messages_random_ids(const telegram_api::Updates *updates_ptr) { + FlatHashSet random_ids; auto updates = get_updates(updates_ptr); if (updates != nullptr) { for (auto &update : *updates) { if (update->get_id() == telegram_api::updateMessageID::ID) { int64 random_id = static_cast(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; } } diff --git a/td/telegram/UpdatesManager.h b/td/telegram/UpdatesManager.h index 45ccc090b..37398c80d 100644 --- a/td/telegram/UpdatesManager.h +++ b/td/telegram/UpdatesManager.h @@ -21,13 +21,13 @@ #include "td/actor/Timeout.h" #include "td/utils/common.h" +#include "td/utils/FlatHashSet.h" #include "td/utils/logging.h" #include "td/utils/Status.h" #include "td/utils/tl_storers.h" #include "td/utils/TlStorerToString.h" #include -#include namespace td { @@ -99,7 +99,7 @@ class UpdatesManager final : public Actor { void add_pending_pts_update(tl_object_ptr &&update, int32 new_pts, int32 pts_count, double receive_time, Promise &&promise, const char *source); - static std::unordered_set get_sent_messages_random_ids(const telegram_api::Updates *updates_ptr); + static FlatHashSet get_sent_messages_random_ids(const telegram_api::Updates *updates_ptr); static vector *> get_new_messages( const telegram_api::Updates *updates_ptr); diff --git a/td/telegram/WebPagesManager.cpp b/td/telegram/WebPagesManager.cpp index cd7c0ffcb..d9df2f279 100644 --- a/td/telegram/WebPagesManager.cpp +++ b/td/telegram/WebPagesManager.cpp @@ -1634,6 +1634,7 @@ void WebPagesManager::on_load_web_page_from_database(WebPageId web_page_id, stri if (G()->close_flag()) { return; } + CHECK(web_page_id.is_valid()); if (!loaded_from_database_web_pages_.insert(web_page_id).second) { return; } diff --git a/td/telegram/WebPagesManager.h b/td/telegram/WebPagesManager.h index 1e9751e20..cfe447818 100644 --- a/td/telegram/WebPagesManager.h +++ b/td/telegram/WebPagesManager.h @@ -21,9 +21,9 @@ #include "td/utils/common.h" #include "td/utils/FlatHashMap.h" +#include "td/utils/FlatHashSet.h" #include "td/utils/Status.h" -#include #include namespace td { @@ -182,7 +182,7 @@ class WebPagesManager final : public Actor { FlatHashMap, WebPageIdHash> web_pages_; FlatHashMap>, WebPageIdHash> load_web_page_from_database_queries_; - std::unordered_set loaded_from_database_web_pages_; + FlatHashSet loaded_from_database_web_pages_; struct PendingWebPageInstantViewQueries { vector> partial; @@ -190,7 +190,7 @@ class WebPagesManager final : public Actor { }; FlatHashMap load_web_page_instant_view_queries_; - FlatHashMap, WebPageIdHash> web_page_messages_; + FlatHashMap, WebPageIdHash> web_page_messages_; FlatHashMap>>, WebPageIdHash> pending_get_web_pages_; diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 3b7325e88..a8746119b 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -26,6 +26,7 @@ #include "td/utils/FileLog.h" #include "td/utils/filesystem.h" #include "td/utils/FlatHashMap.h" +#include "td/utils/FlatHashSet.h" #include "td/utils/format.h" #include "td/utils/JsonBuilder.h" #include "td/utils/logging.h" @@ -64,7 +65,6 @@ #include #include #include -#include #include #ifdef USE_READLINE @@ -432,9 +432,9 @@ class CliClient final : public Actor { } static char get_delimiter(Slice str) { - std::unordered_set chars; + FlatHashSet chars; for (auto c : trim(str)) { - if (!is_alnum(c) && c != '-' && c != '.' && c != '/' && static_cast(c) <= 127) { + if (!is_alnum(c) && c != '-' && c != '.' && c != '/' && c != '\0' && static_cast(c) <= 127) { chars.insert(c); } } diff --git a/td/telegram/files/FileManager.cpp b/td/telegram/files/FileManager.cpp index 882eb3e17..f34f0da0f 100644 --- a/td/telegram/files/FileManager.cpp +++ b/td/telegram/files/FileManager.cpp @@ -48,7 +48,6 @@ #include #include #include -#include #include namespace td { @@ -827,7 +826,7 @@ FileManager::FileManager(unique_ptr context) : context_(std::move(conte next_file_id(); next_file_node_id(); - std::unordered_set dir_paths; + FlatHashSet dir_paths; for (int32 i = 0; i < MAX_FILE_TYPE; i++) { dir_paths.insert(get_files_dir(static_cast(i))); } @@ -1787,8 +1786,8 @@ void FileManager::on_file_reference_repaired(FileId file_id, FileSourceId file_s promise.set_result(std::move(result)); } -std::unordered_set FileManager::get_main_file_ids(const vector &file_ids) { - std::unordered_set result; +FlatHashSet FileManager::get_main_file_ids(const vector &file_ids) { + FlatHashSet result; for (auto file_id : file_ids) { auto node = get_file_node(file_id); if (node) { diff --git a/td/telegram/files/FileManager.h b/td/telegram/files/FileManager.h index 956fc9e81..917782ef5 100644 --- a/td/telegram/files/FileManager.h +++ b/td/telegram/files/FileManager.h @@ -28,6 +28,7 @@ #include "td/utils/Container.h" #include "td/utils/Enumerator.h" #include "td/utils/FlatHashMap.h" +#include "td/utils/FlatHashSet.h" #include "td/utils/logging.h" #include "td/utils/optional.h" #include "td/utils/Slice.h" @@ -37,7 +38,6 @@ #include #include #include -#include #include namespace td { @@ -666,7 +666,7 @@ class FileManager final : public FileLoadManager::Callback { FullRemoteFileLocation *get_remote(int32 key); - std::unordered_set get_main_file_ids(const vector &file_ids); + FlatHashSet get_main_file_ids(const vector &file_ids); void hangup() final; void tear_down() final; diff --git a/td/telegram/files/FileStats.cpp b/td/telegram/files/FileStats.cpp index 5b4138d16..b391ec7bc 100644 --- a/td/telegram/files/FileStats.cpp +++ b/td/telegram/files/FileStats.cpp @@ -11,11 +11,11 @@ #include "td/utils/algorithm.h" #include "td/utils/common.h" +#include "td/utils/FlatHashSet.h" #include "td/utils/format.h" #include "td/utils/misc.h" #include -#include #include namespace td { @@ -109,11 +109,15 @@ void FileStats::apply_dialog_limit(int32 limit) { } void FileStats::apply_dialog_ids(const vector &dialog_ids) { - std::unordered_set all_dialogs(dialog_ids.begin(), dialog_ids.end()); + FlatHashSet all_dialog_ids; + for (auto &dialog_id : dialog_ids) { + CHECK(dialog_id.is_valid()); + all_dialog_ids.insert(dialog_id); + } StatByType other_stats; bool other_flag = false; 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++) { other_stats[i].size += it.second[i].size; other_stats[i].cnt += it.second[i].cnt; diff --git a/td/telegram/net/Session.cpp b/td/telegram/net/Session.cpp index 728da8ea1..217e63844 100644 --- a/td/telegram/net/Session.cpp +++ b/td/telegram/net/Session.cpp @@ -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; query->unknown = true; + CHECK(id != 0); unknown_queries_.insert(id); } diff --git a/td/telegram/net/Session.h b/td/telegram/net/Session.h index b3dea1866..259307d02 100644 --- a/td/telegram/net/Session.h +++ b/td/telegram/net/Session.h @@ -23,6 +23,7 @@ #include "td/utils/CancellationToken.h" #include "td/utils/common.h" #include "td/utils/FlatHashMap.h" +#include "td/utils/FlatHashSet.h" #include "td/utils/List.h" #include "td/utils/Status.h" #include "td/utils/StringBuilder.h" @@ -33,7 +34,6 @@ #include #include #include -#include #include namespace td { @@ -122,8 +122,8 @@ class Session final double last_success_timestamp_ = 0; // time when auth_key and Session definitely was valid size_t dropped_size_ = 0; - std::unordered_set unknown_queries_; - std::vector to_cancel_; + FlatHashSet unknown_queries_; + vector to_cancel_; // Do not invalidate iterators of these two containers! // TODO: better data structures diff --git a/tdutils/td/utils/ChainScheduler.h b/tdutils/td/utils/ChainScheduler.h index 2ce705965..f90b37c98 100644 --- a/tdutils/td/utils/ChainScheduler.h +++ b/tdutils/td/utils/ChainScheduler.h @@ -9,6 +9,7 @@ #include "td/utils/algorithm.h" #include "td/utils/common.h" #include "td/utils/Container.h" +#include "td/utils/FlatHashSet.h" #include "td/utils/List.h" #include "td/utils/logging.h" #include "td/utils/optional.h" @@ -18,7 +19,6 @@ #include #include -#include namespace td { @@ -56,7 +56,7 @@ class ChainScheduler final : public ChainSchedulerBase { void for_each_dependent(TaskId task_id, F &&f) { auto *task = tasks_.get(task_id); CHECK(task != nullptr); - std::unordered_set visited; + FlatHashSet visited; bool check_for_collisions = task->chains.size() > 1; for (TaskChainInfo &task_chain_info : task->chains) { ChainInfo &chain_info = *task_chain_info.chain_info; diff --git a/tdutils/td/utils/FlatHashTable.h b/tdutils/td/utils/FlatHashTable.h index 30ed44415..f27076c88 100644 --- a/tdutils/td/utils/FlatHashTable.h +++ b/tdutils/td/utils/FlatHashTable.h @@ -68,9 +68,16 @@ class FlatHashTable { reference operator*() { return it_->get_public(); } + const value_type &operator*() const { + return it_->get_public(); + } pointer operator->() { return &it_->get_public(); } + const value_type *operator->() const { + return &it_->get_public(); + } + NodeT *get() { return it_; } @@ -108,10 +115,10 @@ class FlatHashTable { ++it_; return *this; } - reference operator*() { + reference operator*() const { return *it_; } - pointer operator->() { + pointer operator->() const { return &*it_; } bool operator==(const ConstIterator &other) const { @@ -358,12 +365,17 @@ class FlatHashTable { return; } resize(other.bucket_count()); - for (const auto &new_node : other) { - auto bucket = calc_bucket(new_node.key()); + auto other_nodes_end = other.nodes_ + other.bucket_count_; + 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) { auto &node = nodes_[bucket]; if (node.empty()) { - node.copy_from(new_node); + node.copy_from(*other_node); break; } next_bucket(bucket); diff --git a/tdutils/td/utils/SetNode.h b/tdutils/td/utils/SetNode.h index dbef6a872..05d22722c 100644 --- a/tdutils/td/utils/SetNode.h +++ b/tdutils/td/utils/SetNode.h @@ -45,8 +45,8 @@ struct SetNode { void copy_from(const SetNode &other) { DCHECK(empty()); - DCHECK(!other.empty()); first = other.first; + DCHECK(!empty()); } bool empty() const { diff --git a/tdutils/td/utils/emoji.cpp b/tdutils/td/utils/emoji.cpp index e009f01f5..c4679eb74 100644 --- a/tdutils/td/utils/emoji.cpp +++ b/tdutils/td/utils/emoji.cpp @@ -7,16 +7,15 @@ #include "td/utils/emoji.h" #include "td/utils/base64.h" +#include "td/utils/FlatHashSet.h" #include "td/utils/Gzip.h" #include "td/utils/misc.h" -#include - namespace td { bool is_emoji(Slice str) { constexpr size_t MAX_EMOJI_LENGTH = 35; - static const std::unordered_set emojis = [max_emoji_length = MAX_EMOJI_LENGTH] { + static const FlatHashSet emojis = [max_emoji_length = MAX_EMOJI_LENGTH] { #if TD_HAVE_ZLIB Slice packed_emojis( "eJyNnety27i2rV8lVfvf-XXul7frVmfZ6cS6kKJskrLj7tUUaUmOI1uObcUEWLUfJecBdledFzgaJIfJiUkyqyqAJ4wxJzE_QABF2fGPs_" @@ -202,7 +201,7 @@ bool is_emoji(Slice str) { string all_emojis_str; constexpr size_t EMOJI_COUNT = 0; #endif - std::unordered_set all_emojis; + FlatHashSet all_emojis; all_emojis.reserve(EMOJI_COUNT); for (size_t i = 0; i < all_emojis_str.size(); i++) { CHECK(all_emojis_str[i] != ' '); diff --git a/tdutils/td/utils/port/FileFd.cpp b/tdutils/td/utils/port/FileFd.cpp index 73dc7b495..2a50dbc13 100644 --- a/tdutils/td/utils/port/FileFd.cpp +++ b/tdutils/td/utils/port/FileFd.cpp @@ -14,6 +14,7 @@ #include "td/utils/common.h" #include "td/utils/ExitGuard.h" +#include "td/utils/FlatHashSet.h" #include "td/utils/logging.h" #include "td/utils/misc.h" #include "td/utils/port/detail/PollableFd.h" @@ -26,7 +27,6 @@ #include #include -#include #include #if TD_PORT_POSIX @@ -384,14 +384,14 @@ Result FileFd::pread(MutableSlice slice, int64 offset) const { } static std::mutex in_process_lock_mutex; -static std::unordered_set locked_files; +static FlatHashSet locked_files; static ExitGuard exit_guard; static Status create_local_lock(const string &path, int32 &max_tries) { while (true) { { // mutex lock scope std::lock_guard 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 << '"'; locked_files.insert(path); return Status::OK(); @@ -505,7 +505,7 @@ void FileFd::remove_local_lock(const string &path) { VLOG(fd) << "Unlock file \"" << path << '"'; std::unique_lock lock(in_process_lock_mutex); 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() { diff --git a/tdutils/td/utils/tl_helpers.h b/tdutils/td/utils/tl_helpers.h index 743e6a723..ee5c9e6c3 100644 --- a/tdutils/td/utils/tl_helpers.h +++ b/tdutils/td/utils/tl_helpers.h @@ -7,6 +7,7 @@ #pragma once #include "td/utils/common.h" +#include "td/utils/FlatHashSet.h" #include "td/utils/misc.h" #include "td/utils/SharedSlice.h" #include "td/utils/Slice.h" @@ -18,7 +19,6 @@ #include "td/utils/Variant.h" #include -#include #include #define BEGIN_STORE_FLAGS() \ @@ -172,15 +172,15 @@ void parse(unique_ptr &ptr, ParserT &parser) { parse(*ptr, parser); } -template -void store(const std::unordered_set &s, StorerT &storer) { +template +void store(const FlatHashSet &s, StorerT &storer) { storer.store_binary(narrow_cast(s.size())); for (auto &val : s) { store(val, storer); } } -template -void parse(std::unordered_set &s, ParserT &parser) { +template +void parse(FlatHashSet &s, ParserT &parser) { uint32 size = parser.fetch_int(); if (parser.get_left_len() < size) { parser.set_error("Wrong set length");