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/FlatHashMap.h"
#include "td/utils/FlatHashSet.h"
#include "td/utils/Status.h"
#include <memory>
#include <unordered_set>
#include <utility>
namespace td {
@ -169,7 +169,7 @@ class BackgroundManager final : public Actor {
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_;
BackgroundId set_background_id_[2];

View File

@ -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 <tuple>
#include <unordered_set>
namespace td {
@ -254,7 +254,7 @@ void CallActor::rate_call(int32 rating, string comment, vector<td_api::object_pt
comment.clear();
}
std::unordered_set<string> tags;
FlatHashSet<string> tags;
for (auto &problem : problems) {
if (problem == nullptr) {
continue;

View File

@ -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 <memory>
#include <mutex>
#include <queue>
#include <unordered_set>
namespace td {
@ -204,7 +204,7 @@ class ClientManager::Impl final {
unique_ptr<ConcurrentScheduler> concurrent_scheduler_;
ClientId client_id_{0};
Td::Options options_;
std::unordered_set<int32> pending_clients_;
FlatHashSet<int32> pending_clients_;
FlatHashMap<int32, ActorOwn<Td>> tds_;
};

View File

@ -69,6 +69,7 @@
#include <limits>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
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);
std::unordered_set<UserId, UserIdHash> contact_user_ids;
FlatHashSet<UserId, UserIdHash> 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<DialogId, DialogIdHash> result_dialog_ids_set(result_dialog_ids.second.begin(),
result_dialog_ids.second.end());
FlatHashSet<DialogId, DialogIdHash> 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);
}
}

View File

@ -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 <functional>
#include <memory>
#include <unordered_set>
#include <utility>
namespace td {
@ -629,7 +629,7 @@ class ContactsManager final : public Actor {
string language_code;
std::unordered_set<int64> photo_ids;
FlatHashSet<int64> photo_ids;
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<UserFull>, UserIdHash> users_full_;
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_;
struct UserIdPhotoIdHash {
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<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<ChannelId, unique_ptr<MinChannel>, ChannelIdHash> min_channels_;
FlatHashMap<ChannelId, unique_ptr<Channel>, ChannelIdHash> channels_;
FlatHashMap<ChannelId, unique_ptr<ChannelFull>, ChannelIdHash> channels_full_;
mutable std::unordered_set<ChannelId, ChannelIdHash> unknown_channels_;
std::unordered_set<ChannelId, ChannelIdHash> invalidated_channels_full_;
mutable FlatHashSet<ChannelId, ChannelIdHash> unknown_channels_;
FlatHashSet<ChannelId, ChannelIdHash> invalidated_channels_full_;
FlatHashMap<ChannelId, FileSourceId, ChannelIdHash> channel_full_file_source_ids_;
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_;
struct DialogAccessByInviteLink {
std::unordered_set<string> invite_links;
FlatHashSet<string> invite_links;
int32 accessible_before = 0;
};
FlatHashMap<string, unique_ptr<InviteLinkInfo>> invite_link_infos_;
@ -1687,19 +1687,19 @@ class ContactsManager final : public Actor {
vector<ChannelId> inactive_channels_;
FlatHashMap<UserId, vector<Promise<Unit>>, UserIdHash> load_user_from_database_queries_;
std::unordered_set<UserId, UserIdHash> loaded_from_database_users_;
std::unordered_set<UserId, UserIdHash> unavailable_user_fulls_;
FlatHashSet<UserId, UserIdHash> loaded_from_database_users_;
FlatHashSet<UserId, UserIdHash> unavailable_user_fulls_;
FlatHashMap<ChatId, vector<Promise<Unit>>, ChatIdHash> load_chat_from_database_queries_;
std::unordered_set<ChatId, ChatIdHash> loaded_from_database_chats_;
std::unordered_set<ChatId, ChatIdHash> unavailable_chat_fulls_;
FlatHashSet<ChatId, ChatIdHash> loaded_from_database_chats_;
FlatHashSet<ChatId, ChatIdHash> unavailable_chat_fulls_;
FlatHashMap<ChannelId, vector<Promise<Unit>>, ChannelIdHash> load_channel_from_database_queries_;
std::unordered_set<ChannelId, ChannelIdHash> loaded_from_database_channels_;
std::unordered_set<ChannelId, ChannelIdHash> unavailable_channel_fulls_;
FlatHashSet<ChannelId, ChannelIdHash> loaded_from_database_channels_;
FlatHashSet<ChannelId, ChannelIdHash> unavailable_channel_fulls_;
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_chat_full_queries_{"GetChatFullCombiner", 2.0};
@ -1771,7 +1771,7 @@ class ContactsManager final : public Actor {
vector<DialogNearby> users_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 pending_location_visibility_expire_date_ = -1;
@ -1780,8 +1780,8 @@ class ContactsManager final : public Actor {
FlatHashMap<ChannelId, ChannelId, ChannelIdHash> linked_channel_ids_;
std::unordered_set<UserId, UserIdHash> restricted_user_ids_;
std::unordered_set<ChannelId, ChannelIdHash> restricted_channel_ids_;
FlatHashSet<UserId, UserIdHash> restricted_user_ids_;
FlatHashSet<ChannelId, ChannelIdHash> restricted_channel_ids_;
vector<Contact> next_all_imported_contacts_;
vector<size_t> imported_contacts_unique_id_;

View File

@ -13,19 +13,19 @@
#include "td/telegram/UserId.h"
#include "td/telegram/WebPageId.h"
#include <unordered_set>
#include "td/utils/FlatHashSet.h"
namespace td {
class Td;
class Dependencies {
std::unordered_set<UserId, UserIdHash> user_ids;
std::unordered_set<ChatId, ChatIdHash> chat_ids;
std::unordered_set<ChannelId, ChannelIdHash> channel_ids;
std::unordered_set<SecretChatId, SecretChatIdHash> secret_chat_ids;
std::unordered_set<DialogId, DialogIdHash> dialog_ids;
std::unordered_set<WebPageId, WebPageIdHash> web_page_ids;
FlatHashSet<UserId, UserIdHash> user_ids;
FlatHashSet<ChatId, ChatIdHash> chat_ids;
FlatHashSet<ChannelId, ChannelIdHash> channel_ids;
FlatHashSet<SecretChatId, SecretChatIdHash> secret_chat_ids;
FlatHashSet<DialogId, DialogIdHash> dialog_ids;
FlatHashSet<WebPageId, WebPageIdHash> 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<DialogId, DialogIdHash> &get_dialog_ids() const {
const FlatHashSet<DialogId, DialogIdHash> &get_dialog_ids() const {
return dialog_ids;
}
};

View File

@ -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 <unordered_set>
namespace td {
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->title = std::move(filter->title_);
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->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> 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<DialogId, DialogIdHash> removed_dialog_ids;
FlatHashSet<DialogId, DialogIdHash> 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> 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> DialogFilter::merge_dialog_filter_changes(const DialogF
}
// 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) {
CHECK(old_dialog_id.get_dialog_id().is_valid());
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) {
auto dialog_id = new_dialog_id.get_dialog_id();
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);
{
std::unordered_set<DialogId, DialogIdHash> added_dialog_ids;
FlatHashSet<DialogId, DialogIdHash> 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);

View File

@ -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 <map>
#include <unordered_set>
#include <utility>
namespace td {
@ -2064,10 +2064,11 @@ void GroupCallManager::process_group_call_participants(
return;
}
std::unordered_set<DialogId, DialogIdHash> old_participant_dialog_ids;
FlatHashSet<DialogId, DialogIdHash> 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);
}
}

View File

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

View File

@ -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 <unordered_set>
namespace td {
class InputDialogId {
@ -28,9 +27,8 @@ class InputDialogId {
explicit InputDialogId(const tl_object_ptr<telegram_api::InputPeer> &input_peer);
static vector<InputDialogId> get_input_dialog_ids(
const vector<tl_object_ptr<telegram_api::InputPeer>> &input_peers,
std::unordered_set<DialogId, DialogIdHash> *added_dialog_ids = nullptr);
static vector<InputDialogId> get_input_dialog_ids(const vector<tl_object_ptr<telegram_api::InputPeer>> &input_peers,
FlatHashSet<DialogId, DialogIdHash> *added_dialog_ids = nullptr);
static vector<telegram_api::object_ptr<telegram_api::InputDialogPeer>> get_input_dialog_peers(
const vector<InputDialogId> &input_dialog_ids);

View File

@ -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 <atomic>
#include <limits>
#include <map>
#include <unordered_set>
#include <utility>
namespace td {
@ -63,7 +63,7 @@ struct LanguagePackManager::Language {
vector<Promise<Unit>> get_difference_queries_;
FlatHashMap<string, string> ordinary_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_
};
@ -979,11 +979,11 @@ void LanguagePackManager::on_get_languages(vector<tl_object_ptr<telegram_api::la
string language_pack, bool only_local,
Promise<td_api::object_ptr<td_api::localizationTargetInfo>> promise) {
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,
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;
}

View File

@ -1270,9 +1270,14 @@ static Slice fix_url(Slice str) {
return full_url;
}
const std::unordered_set<Slice, SliceHash> &get_valid_short_usernames() {
static const std::unordered_set<Slice, SliceHash> valid_usernames{"gif", "wiki", "vid", "bing", "pic",
"bold", "imdb", "coub", "like", "vote"};
const FlatHashSet<Slice, SliceHash> &get_valid_short_usernames() {
static const FlatHashSet<Slice, SliceHash> valid_usernames = [] {
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;
}

View File

@ -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 <unordered_set>
#include <utility>
namespace td {
@ -131,7 +131,7 @@ inline bool operator!=(const FormattedText &lhs, const FormattedText &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,
vector<tl_object_ptr<td_api::textEntity>> &&input_entities,

View File

@ -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 <algorithm>
#include <unordered_set>
#include <utility>
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<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) {
if (update->get_id() == telegram_api::updateMessageReactions::ID) {
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->is_min_ = reactions->min_;
std::unordered_set<string> reaction_strings;
std::unordered_set<DialogId, DialogIdHash> recent_choosers;
FlatHashSet<string> reaction_strings;
FlatHashSet<DialogId, DialogIdHash> 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;

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) {
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<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; });
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<tl_object_ptr<te
if (pinned_dialog_ids != added_dialog_ids) {
LOG(INFO) << "Update pinned chats order from " << format::as_array(pinned_dialog_ids) << " to "
<< format::as_array(added_dialog_ids);
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 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<DialogId, DialogIdHash> all_dialog_ids;
FlatHashSet<DialogId, DialogIdHash> 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<unique_ptr<DialogFilter>> MessagesManager::create_dialog_filter(DialogFil
auto dialog_filter = make_unique<DialogFilter>();
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) {
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<D
int32 dialog_count = 0;
int32 secret_dialog_count = 0;
auto dialog_count_limit = get_pinned_dialogs_limit(dialog_list_id);
FlatHashSet<DialogId, DialogIdHash> 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<D
if (dialog_count > 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<DialogId, DialogIdHash> 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<D
std::reverse(pinned_dialog_ids.begin(), pinned_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();
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<Unit> &&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::Dialog> 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<Dialog>();
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<MessageId, MessageIdHash> changed_message_ids;
FlatHashSet<MessageId, MessageIdHash> 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<BinlogEvent> &&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<BinlogEvent> &&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;

View File

@ -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<int32, MessageId> last_assigned_scheduled_message_id; // date -> message_id
std::unordered_set<MessageId, MessageIdHash> deleted_message_ids;
std::unordered_set<ScheduledServerMessageId, ScheduledServerMessageIdHash> deleted_scheduled_server_message_ids;
FlatHashSet<MessageId, MessageIdHash> deleted_message_ids;
FlatHashSet<ScheduledServerMessageId, ScheduledServerMessageIdHash> deleted_scheduled_server_message_ids;
std::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_message_notifications;
vector<std::pair<DialogId, MessageId>> pending_new_mention_notifications;
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_;
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> scheduled_messages;
@ -3450,10 +3451,9 @@ class MessagesManager final : public Actor {
FlatHashMap<DialogId, unique_ptr<Dialog>, DialogIdHash> dialogs_;
std::unordered_set<DialogId, DialogIdHash>
loaded_dialogs_; // dialogs loaded from database, but not added to dialogs_
FlatHashSet<DialogId, DialogIdHash> 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 {
MessageId message_id;
@ -3504,7 +3504,7 @@ class MessagesManager final : public Actor {
FlatHashMap<FullMessageId, int32, FullMessageIdHash> replied_by_yet_unsent_messages_;
// 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_;
struct ActiveDialogAction {
@ -3555,7 +3555,7 @@ class MessagesManager final : public Actor {
FlatHashMap<DialogId, uint64, DialogIdHash> get_channel_difference_to_log_event_id_;
FlatHashMap<DialogId, int32, DialogIdHash> channel_get_difference_retry_timeouts_;
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_retry_timeout_{"ChannelGetDifferenceRetryTimeout"};
@ -3576,7 +3576,7 @@ class MessagesManager final : public Actor {
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;
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, DialogId> inaccessible_resolved_usernames_;
std::unordered_set<string> reload_voice_chat_on_search_usernames_;
FlatHashSet<string> 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<MessageId, MessageIdHash> message_ids;
FlatHashSet<MessageId, MessageIdHash> 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_;
struct ReactionsToReload {
std::unordered_set<MessageId, MessageIdHash> message_ids;
FlatHashSet<MessageId, MessageIdHash> message_ids;
bool is_request_sent = false;
};
FlatHashMap<DialogId, ReactionsToReload, DialogIdHash> being_reloaded_reactions_;

View File

@ -61,7 +61,6 @@
#include <algorithm>
#include <iterator>
#include <limits>
#include <unordered_set>
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<int32> added_notification_ids;
std::unordered_set<int32> edited_notification_ids;
std::unordered_set<int32> removed_notification_ids;
FlatHashSet<int32> added_notification_ids;
FlatHashSet<int32> edited_notification_ids;
FlatHashSet<int32> removed_notification_ids;
for (auto &update : updates) {
CHECK(update != nullptr);
if (update->get_id() == td_api::updateNotificationGroup::ID) {
auto update_ptr = static_cast<td_api::updateNotificationGroup *>(update.get());
for (auto &notification : 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 &notification_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<td_api::updateNotification *>(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<int32, size_t> first_add_notification_pos;
FlatHashMap<int32, size_t> first_edit_notification_pos;
std::unordered_set<int32> can_be_deleted_notification_ids;
std::vector<int32> moved_deleted_notification_ids;
FlatHashSet<int32> can_be_deleted_notification_ids;
vector<int32> 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 &notification : 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<int32> removed_notification_ids;
FlatHashSet<int32> 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 &notification : 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<td_api::updateNotification *>(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;

View File

@ -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 <functional>
#include <map>
#include <unordered_set>
namespace td {
@ -372,7 +372,7 @@ class NotificationManager final : public Actor {
bool is_binlog_processed_ = false;
bool running_get_difference_ = false;
std::unordered_set<int32> running_get_chat_difference_;
FlatHashSet<int32> running_get_chat_difference_;
NotificationGroups groups_;
FlatHashMap<NotificationGroupId, NotificationGroupKey, NotificationGroupIdHash> group_keys_;
@ -383,7 +383,7 @@ class NotificationManager final : public Actor {
MultiTimeout flush_pending_updates_timeout_{"FlushPendingUpdatesTimeout"};
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<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) {
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<ReplyMarkup> &&reply_markup,
uint64 log_event_id, Promise<Unit> &&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<telegram_api::poll
return PollId();
}
if (poll_server != nullptr) {
std::unordered_set<Slice, SliceHash> option_data;
FlatHashSet<Slice, SliceHash> 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);

View File

@ -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 <unordered_set>
#include <utility>
namespace td {
@ -209,7 +209,7 @@ class PollManager final : public Actor {
ActorShared<> parent_;
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 {
vector<string> options_;
@ -226,9 +226,9 @@ class PollManager final : public Actor {
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

View File

@ -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<Unit>());
}

View File

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

View File

@ -65,7 +65,6 @@
#include <cmath>
#include <limits>
#include <type_traits>
#include <unordered_set>
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<telegram_api::messages_allStickers>(stickers_ptr);
std::unordered_set<StickerSetId, StickerSetIdHash> uninstalled_sticker_sets(
installed_sticker_set_ids_[is_masks].begin(), installed_sticker_set_ids_[is_masks].end());
FlatHashSet<StickerSetId, StickerSetIdHash> uninstalled_sticker_sets;
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> 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<StickerSetId, StickerSetIdHash> unread_sticker_set_ids;
FlatHashSet<StickerSetId, StickerSetIdHash> 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<StickerSetId> 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<StickerSetId, StickerSetIdHash> valid_set_ids(current_sticker_set_ids.begin(),
current_sticker_set_ids.end());
FlatHashSet<StickerSetId, StickerSetIdHash> valid_set_ids;
for (auto sticker_set_id : current_sticker_set_ids) {
valid_set_ids.insert(sticker_set_id);
}
vector<StickerSetId> 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<FileId> local_file_ids;
vector<FileId> url_file_ids;
std::unordered_set<int32> sticker_formats;
FlatHashSet<int32> sticker_formats;
StickerFormat sticker_format = StickerFormat::Unknown;
for (auto &sticker : stickers) {
auto r_file_id = prepare_input_sticker(sticker.get());

View File

@ -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 <memory>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
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<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_;
int32 recent_stickers_limit_ = 200;
@ -881,15 +881,15 @@ class StickersManager final : public Actor {
FlatHashMap<string, vector<string>> emoji_language_codes_;
FlatHashMap<string, int32> emoji_language_code_versions_;
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_language_codes_queries_;
FlatHashMap<int64, string> emoji_suggestions_urls_;
FlatHashMap<string, std::unordered_set<FullMessageId, FullMessageIdHash>> dice_messages_;
FlatHashMap<string, FlatHashSet<FullMessageId, FullMessageIdHash>> dice_messages_;
struct EmojiMessages {
std::unordered_set<FullMessageId, FullMessageIdHash> full_message_ids;
FlatHashSet<FullMessageId, FullMessageIdHash> full_message_ids;
std::pair<FileId, int> animated_emoji_sticker;
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)));
}
std::unordered_set<int64> UpdatesManager::get_sent_messages_random_ids(const telegram_api::Updates *updates_ptr) {
std::unordered_set<int64> random_ids;
FlatHashSet<int64> UpdatesManager::get_sent_messages_random_ids(const telegram_api::Updates *updates_ptr) {
FlatHashSet<int64> 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<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;
}
}

View File

@ -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 <map>
#include <unordered_set>
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,
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(
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()) {
return;
}
CHECK(web_page_id.is_valid());
if (!loaded_from_database_web_pages_.insert(web_page_id).second) {
return;
}

View File

@ -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 <unordered_set>
#include <utility>
namespace td {
@ -182,7 +182,7 @@ class WebPagesManager final : public Actor {
FlatHashMap<WebPageId, unique_ptr<WebPage>, WebPageIdHash> web_pages_;
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 {
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, 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_;

View File

@ -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 <memory>
#include <queue>
#include <tuple>
#include <unordered_set>
#include <utility>
#ifdef USE_READLINE
@ -432,9 +432,9 @@ class CliClient final : public Actor {
}
static char get_delimiter(Slice str) {
std::unordered_set<char> chars;
FlatHashSet<char> chars;
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);
}
}

View File

@ -48,7 +48,6 @@
#include <limits>
#include <numeric>
#include <tuple>
#include <unordered_set>
#include <utility>
namespace td {
@ -827,7 +826,7 @@ FileManager::FileManager(unique_ptr<Context> context) : context_(std::move(conte
next_file_id();
next_file_node_id();
std::unordered_set<string> dir_paths;
FlatHashSet<string> dir_paths;
for (int32 i = 0; i < MAX_FILE_TYPE; 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));
}
std::unordered_set<FileId, FileIdHash> FileManager::get_main_file_ids(const vector<FileId> &file_ids) {
std::unordered_set<FileId, FileIdHash> result;
FlatHashSet<FileId, FileIdHash> FileManager::get_main_file_ids(const vector<FileId> &file_ids) {
FlatHashSet<FileId, FileIdHash> result;
for (auto file_id : file_ids) {
auto node = get_file_node(file_id);
if (node) {

View File

@ -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 <map>
#include <memory>
#include <set>
#include <unordered_set>
#include <utility>
namespace td {
@ -666,7 +666,7 @@ class FileManager final : public FileLoadManager::Callback {
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 tear_down() final;

View File

@ -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 <algorithm>
#include <unordered_set>
#include <utility>
namespace td {
@ -109,11 +109,15 @@ void FileStats::apply_dialog_limit(int32 limit) {
}
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;
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;

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;
query->unknown = true;
CHECK(id != 0);
unknown_queries_.insert(id);
}

View File

@ -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 <functional>
#include <map>
#include <memory>
#include <unordered_set>
#include <utility>
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<uint64> unknown_queries_;
std::vector<int64> to_cancel_;
FlatHashSet<uint64> unknown_queries_;
vector<int64> to_cancel_;
// Do not invalidate iterators of these two containers!
// TODO: better data structures

View File

@ -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 <functional>
#include <unordered_map>
#include <unordered_set>
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<TaskId> visited;
FlatHashSet<TaskId> visited;
bool check_for_collisions = task->chains.size() > 1;
for (TaskChainInfo &task_chain_info : task->chains) {
ChainInfo &chain_info = *task_chain_info.chain_info;

View File

@ -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);

View File

@ -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 {

View File

@ -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 <unordered_set>
namespace td {
bool is_emoji(Slice str) {
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
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<Slice, SliceHash> all_emojis;
FlatHashSet<Slice, SliceHash> all_emojis;
all_emojis.reserve(EMOJI_COUNT);
for (size_t i = 0; i < all_emojis_str.size(); i++) {
CHECK(all_emojis_str[i] != ' ');

View File

@ -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 <cstring>
#include <mutex>
#include <unordered_set>
#include <utility>
#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::unordered_set<string> locked_files;
static FlatHashSet<string> 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<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 << '"';
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<std::mutex> 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() {

View File

@ -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 <type_traits>
#include <unordered_set>
#include <utility>
#define BEGIN_STORE_FLAGS() \
@ -172,15 +172,15 @@ void parse(unique_ptr<T> &ptr, ParserT &parser) {
parse(*ptr, parser);
}
template <class Key, class Hash, class KeyEqual, class Allocator, class StorerT>
void store(const std::unordered_set<Key, Hash, KeyEqual, Allocator> &s, StorerT &storer) {
template <class Key, class Hash, class KeyEqual, class StorerT>
void store(const FlatHashSet<Key, Hash, KeyEqual> &s, StorerT &storer) {
storer.store_binary(narrow_cast<int32>(s.size()));
for (auto &val : s) {
store(val, storer);
}
}
template <class Key, class Hash, class KeyEqual, class Allocator, class ParserT>
void parse(std::unordered_set<Key, Hash, KeyEqual, Allocator> &s, ParserT &parser) {
template <class Key, class Hash, class KeyEqual, class ParserT>
void parse(FlatHashSet<Key, Hash, KeyEqual> &s, ParserT &parser) {
uint32 size = parser.fetch_int();
if (parser.get_left_len() < size) {
parser.set_error("Wrong set length");