mirror of
https://github.com/tdlight-team/tdlight-telegram-bot-api.git
synced 2024-08-24 16:20:30 +02:00
Use td::FlatHashTable instead of std::unordered_map/set.
This commit is contained in:
parent
d8166a558d
commit
3e9da68537
@ -3760,7 +3760,7 @@ void Client::check_chat_access(int64 chat_id, AccessRights access_rights, const
|
||||
CHECK(group_info != nullptr);
|
||||
if (!group_info->is_active && need_write_access) {
|
||||
if (group_info->upgraded_to_supergroup_id != 0) {
|
||||
std::unordered_map<td::string, std::unique_ptr<td::VirtuallyJsonable>> parameters;
|
||||
td::FlatHashMap<td::string, std::unique_ptr<td::VirtuallyJsonable>> parameters;
|
||||
auto updagraded_to_chat_id = get_supergroup_chat_id(group_info->upgraded_to_supergroup_id);
|
||||
parameters.emplace("migrate_to_chat_id", std::make_unique<td::VirtuallyJsonableLong>(updagraded_to_chat_id));
|
||||
return fail_query(400, "Bad Request: group chat was upgraded to a supergroup chat", std::move(query),
|
||||
@ -4398,7 +4398,8 @@ void Client::on_update(object_ptr<td_api::Object> result) {
|
||||
}
|
||||
case td_api::updateUser::ID: {
|
||||
auto update = move_object_as<td_api::updateUser>(result);
|
||||
add_user(users_, std::move(update->user_));
|
||||
auto *user_info = add_user_info(update->user_->id_);
|
||||
add_user(user_info, std::move(update->user_));
|
||||
break;
|
||||
}
|
||||
case td_api::updateUserFullInfo::ID: {
|
||||
@ -4410,7 +4411,8 @@ void Client::on_update(object_ptr<td_api::Object> result) {
|
||||
}
|
||||
case td_api::updateBasicGroup::ID: {
|
||||
auto update = move_object_as<td_api::updateBasicGroup>(result);
|
||||
add_group(groups_, std::move(update->basic_group_));
|
||||
auto *group_info = add_group_info(update->basic_group_->id_);
|
||||
add_group(group_info, std::move(update->basic_group_));
|
||||
break;
|
||||
}
|
||||
case td_api::updateBasicGroupFullInfo::ID: {
|
||||
@ -4425,7 +4427,8 @@ void Client::on_update(object_ptr<td_api::Object> result) {
|
||||
}
|
||||
case td_api::updateSupergroup::ID: {
|
||||
auto update = move_object_as<td_api::updateSupergroup>(result);
|
||||
add_supergroup(supergroups_, std::move(update->supergroup_));
|
||||
auto *supergroup_info = add_supergroup_info(update->supergroup_->id_);
|
||||
add_supergroup(supergroup_info, std::move(update->supergroup_));
|
||||
break;
|
||||
}
|
||||
case td_api::updateSupergroupFullInfo::ID: {
|
||||
@ -6392,7 +6395,7 @@ void Client::on_message_send_succeeded(object_ptr<td_api::message> &&message, in
|
||||
|
||||
auto query_id =
|
||||
extract_yet_unsent_message_query_id(chat_id, old_message_id, &message_info->is_reply_to_message_deleted);
|
||||
auto &query = pending_send_message_queries_[query_id];
|
||||
auto &query = *pending_send_message_queries_[query_id];
|
||||
if (query.is_multisend) {
|
||||
query.messages.push_back(td::json_encode<td::string>(JsonMessage(message_info, true, "sent message", this)));
|
||||
query.awaited_message_count--;
|
||||
@ -6420,7 +6423,7 @@ void Client::on_message_send_failed(int64 chat_id, int64 old_message_id, int64 n
|
||||
auto error = make_object<td_api::error>(result.code(), result.message().str());
|
||||
|
||||
auto query_id = extract_yet_unsent_message_query_id(chat_id, old_message_id, nullptr);
|
||||
auto &query = pending_send_message_queries_[query_id];
|
||||
auto &query = *pending_send_message_queries_[query_id];
|
||||
if (query.is_multisend) {
|
||||
if (query.error == nullptr) {
|
||||
query.error = std::move(error);
|
||||
@ -8253,8 +8256,10 @@ void Client::do_send_message(object_ptr<td_api::InputMessageContent> input_messa
|
||||
td::int64 Client::get_send_message_query_id(PromisedQueryPtr query, bool is_multisend) {
|
||||
auto query_id = current_send_message_query_id_++;
|
||||
auto &pending_query = pending_send_message_queries_[query_id];
|
||||
pending_query.query = std::move(query);
|
||||
pending_query.is_multisend = is_multisend;
|
||||
CHECK(pending_query == nullptr);
|
||||
pending_query = td::make_unique<PendingSendMessageQuery>();
|
||||
pending_query->query = std::move(query);
|
||||
pending_query->is_multisend = is_multisend;
|
||||
return query_id;
|
||||
}
|
||||
|
||||
@ -8276,7 +8281,7 @@ void Client::on_sent_message(object_ptr<td_api::message> &&message, int64 query_
|
||||
auto emplace_result = yet_unsent_messages_.emplace(yet_unsent_message_id, yet_unsent_message);
|
||||
CHECK(emplace_result.second);
|
||||
yet_unsent_message_count_[chat_id]++;
|
||||
pending_send_message_queries_[query_id].awaited_message_count++;
|
||||
pending_send_message_queries_[query_id]->awaited_message_count++;
|
||||
}
|
||||
|
||||
void Client::abort_long_poll(bool from_set_webhook) {
|
||||
@ -8442,8 +8447,7 @@ void Client::long_poll_wakeup(bool force_flag) {
|
||||
}
|
||||
}
|
||||
|
||||
void Client::add_user(std::unordered_map<int64, UserInfo> &users, object_ptr<td_api::user> &&user) {
|
||||
auto user_info = &users[user->id_];
|
||||
void Client::add_user(UserInfo *user_info, object_ptr<td_api::user> &&user) {
|
||||
user_info->first_name = std::move(user->first_name_);
|
||||
user_info->last_name = std::move(user->last_name_);
|
||||
user_info->username = std::move(user->username_);
|
||||
@ -8475,23 +8479,31 @@ void Client::add_user(std::unordered_map<int64, UserInfo> &users, object_ptr<td_
|
||||
}
|
||||
}
|
||||
|
||||
Client::UserInfo *Client::add_user_info(int64 user_id) {
|
||||
auto emplace_result = users_.emplace(user_id, nullptr);
|
||||
auto &user_info = emplace_result.first->second;
|
||||
if (emplace_result.second) {
|
||||
user_info = td::make_unique<UserInfo>();
|
||||
} else {
|
||||
CHECK(user_info != nullptr);
|
||||
}
|
||||
return user_info.get();
|
||||
}
|
||||
|
||||
const Client::UserInfo *Client::get_user_info(int64 user_id) const {
|
||||
auto it = users_.find(user_id);
|
||||
return it == users_.end() ? nullptr : &it->second;
|
||||
return it == users_.end() ? nullptr : it->second.get();
|
||||
}
|
||||
|
||||
void Client::set_user_bio(int64 user_id, td::string &&bio) {
|
||||
auto user_info = &users_[user_id];
|
||||
user_info->bio = std::move(bio);
|
||||
add_user_info(user_id)->bio = std::move(bio);
|
||||
}
|
||||
|
||||
void Client::set_user_has_private_forwards(int64 user_id, bool has_private_forwards) {
|
||||
auto user_info = &users_[user_id];
|
||||
user_info->has_private_forwards = has_private_forwards;
|
||||
add_user_info(user_id)->has_private_forwards = has_private_forwards;
|
||||
}
|
||||
|
||||
void Client::add_group(std::unordered_map<int64, GroupInfo> &groups, object_ptr<td_api::basicGroup> &&group) {
|
||||
auto group_info = &groups[group->id_];
|
||||
void Client::add_group(GroupInfo *group_info, object_ptr<td_api::basicGroup> &&group) {
|
||||
group_info->member_count = group->member_count_;
|
||||
group_info->left = group->status_->get_id() == td_api::chatMemberStatusLeft::ID;
|
||||
group_info->kicked = group->status_->get_id() == td_api::chatMemberStatusBanned::ID;
|
||||
@ -8502,24 +8514,31 @@ void Client::add_group(std::unordered_map<int64, GroupInfo> &groups, object_ptr<
|
||||
}
|
||||
}
|
||||
|
||||
Client::GroupInfo *Client::add_group_info(int64 group_id) {
|
||||
auto emplace_result = groups_.emplace(group_id, nullptr);
|
||||
auto &group_info = emplace_result.first->second;
|
||||
if (emplace_result.second) {
|
||||
group_info = td::make_unique<GroupInfo>();
|
||||
} else {
|
||||
CHECK(group_info != nullptr);
|
||||
}
|
||||
return group_info.get();
|
||||
}
|
||||
|
||||
const Client::GroupInfo *Client::get_group_info(int64 group_id) const {
|
||||
auto it = groups_.find(group_id);
|
||||
return it == groups_.end() ? nullptr : &it->second;
|
||||
return it == groups_.end() ? nullptr : it->second.get();
|
||||
}
|
||||
|
||||
void Client::set_group_description(int64 group_id, td::string &&descripton) {
|
||||
auto group_info = &groups_[group_id];
|
||||
group_info->description = std::move(descripton);
|
||||
add_group_info(group_id)->description = std::move(descripton);
|
||||
}
|
||||
|
||||
void Client::set_group_invite_link(int64 group_id, td::string &&invite_link) {
|
||||
auto group_info = &groups_[group_id];
|
||||
group_info->invite_link = std::move(invite_link);
|
||||
add_group_info(group_id)->invite_link = std::move(invite_link);
|
||||
}
|
||||
|
||||
void Client::add_supergroup(std::unordered_map<int64, SupergroupInfo> &supergroups,
|
||||
object_ptr<td_api::supergroup> &&supergroup) {
|
||||
auto supergroup_info = &supergroups[supergroup->id_];
|
||||
void Client::add_supergroup(SupergroupInfo *supergroup_info, object_ptr<td_api::supergroup> &&supergroup) {
|
||||
supergroup_info->username = std::move(supergroup->username_);
|
||||
supergroup_info->date = supergroup->date_;
|
||||
supergroup_info->status = std::move(supergroup->status_);
|
||||
@ -8528,48 +8547,59 @@ void Client::add_supergroup(std::unordered_map<int64, SupergroupInfo> &supergrou
|
||||
}
|
||||
|
||||
void Client::set_supergroup_description(int64 supergroup_id, td::string &&descripton) {
|
||||
auto supergroup_info = &supergroups_[supergroup_id];
|
||||
supergroup_info->description = std::move(descripton);
|
||||
add_supergroup_info(supergroup_id)->description = std::move(descripton);
|
||||
}
|
||||
|
||||
void Client::set_supergroup_invite_link(int64 supergroup_id, td::string &&invite_link) {
|
||||
auto supergroup_info = &supergroups_[supergroup_id];
|
||||
supergroup_info->invite_link = std::move(invite_link);
|
||||
add_supergroup_info(supergroup_id)->invite_link = std::move(invite_link);
|
||||
}
|
||||
|
||||
void Client::set_supergroup_sticker_set_id(int64 supergroup_id, int64 sticker_set_id) {
|
||||
auto supergroup_info = &supergroups_[supergroup_id];
|
||||
supergroup_info->sticker_set_id = sticker_set_id;
|
||||
add_supergroup_info(supergroup_id)->sticker_set_id = sticker_set_id;
|
||||
}
|
||||
|
||||
void Client::set_supergroup_can_set_sticker_set(int64 supergroup_id, bool can_set_sticker_set) {
|
||||
auto supergroup_info = &supergroups_[supergroup_id];
|
||||
supergroup_info->can_set_sticker_set = can_set_sticker_set;
|
||||
add_supergroup_info(supergroup_id)->can_set_sticker_set = can_set_sticker_set;
|
||||
}
|
||||
|
||||
void Client::set_supergroup_slow_mode_delay(int64 supergroup_id, int32 slow_mode_delay) {
|
||||
auto supergroup_info = &supergroups_[supergroup_id];
|
||||
supergroup_info->slow_mode_delay = slow_mode_delay;
|
||||
add_supergroup_info(supergroup_id)->slow_mode_delay = slow_mode_delay;
|
||||
}
|
||||
|
||||
void Client::set_supergroup_linked_chat_id(int64 supergroup_id, int64 linked_chat_id) {
|
||||
auto supergroup_info = &supergroups_[supergroup_id];
|
||||
supergroup_info->linked_chat_id = linked_chat_id;
|
||||
add_supergroup_info(supergroup_id)->linked_chat_id = linked_chat_id;
|
||||
}
|
||||
|
||||
void Client::set_supergroup_location(int64 supergroup_id, object_ptr<td_api::chatLocation> location) {
|
||||
auto supergroup_info = &supergroups_[supergroup_id];
|
||||
supergroup_info->location = std::move(location);
|
||||
add_supergroup_info(supergroup_id)->location = std::move(location);
|
||||
}
|
||||
|
||||
Client::SupergroupInfo *Client::add_supergroup_info(int64 supergroup_id) {
|
||||
auto emplace_result = supergroups_.emplace(supergroup_id, nullptr);
|
||||
auto &supergroup_info = emplace_result.first->second;
|
||||
if (emplace_result.second) {
|
||||
supergroup_info = td::make_unique<SupergroupInfo>();
|
||||
} else {
|
||||
CHECK(supergroup_info != nullptr);
|
||||
}
|
||||
return supergroup_info.get();
|
||||
}
|
||||
|
||||
const Client::SupergroupInfo *Client::get_supergroup_info(int64 supergroup_id) const {
|
||||
auto it = supergroups_.find(supergroup_id);
|
||||
return it == supergroups_.end() ? nullptr : &it->second;
|
||||
return it == supergroups_.end() ? nullptr : it->second.get();
|
||||
}
|
||||
|
||||
Client::ChatInfo *Client::add_chat(int64 chat_id) {
|
||||
LOG(DEBUG) << "Update chat " << chat_id;
|
||||
return &chats_[chat_id];
|
||||
auto emplace_result = chats_.emplace(chat_id, nullptr);
|
||||
auto &chat_info = emplace_result.first->second;
|
||||
if (emplace_result.second) {
|
||||
chat_info = td::make_unique<ChatInfo>();
|
||||
} else {
|
||||
CHECK(chat_info != nullptr);
|
||||
}
|
||||
return chat_info.get();
|
||||
}
|
||||
|
||||
const Client::ChatInfo *Client::get_chat(int64 chat_id) const {
|
||||
@ -8577,7 +8607,7 @@ const Client::ChatInfo *Client::get_chat(int64 chat_id) const {
|
||||
if (it == chats_.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
return &it->second;
|
||||
return it->second.get();
|
||||
}
|
||||
|
||||
Client::ChatType Client::get_chat_type(int64 chat_id) const {
|
||||
@ -8879,10 +8909,7 @@ void Client::add_new_message(object_ptr<td_api::message> &&message, bool is_edit
|
||||
}
|
||||
|
||||
auto chat_id = message->chat_id_;
|
||||
if (chat_id == 0) {
|
||||
LOG(ERROR) << "Receive invalid chat in " << to_string(message);
|
||||
return;
|
||||
}
|
||||
CHECK(chat_id != 0);
|
||||
new_message_queues_[chat_id].queue_.emplace(std::move(message), is_edited);
|
||||
process_new_message_queue(chat_id);
|
||||
}
|
||||
@ -8916,10 +8943,7 @@ void Client::add_new_chosen_inline_result(int64 sender_user_id, object_ptr<td_ap
|
||||
void Client::add_new_callback_query(object_ptr<td_api::updateNewCallbackQuery> &&query) {
|
||||
CHECK(query != nullptr);
|
||||
auto user_id = query->sender_user_id_;
|
||||
if (user_id == 0) {
|
||||
LOG(ERROR) << "Receive invalid sender in " << to_string(query);
|
||||
return;
|
||||
}
|
||||
CHECK(user_id != 0);
|
||||
new_callback_query_queues_[user_id].queue_.push(std::move(query));
|
||||
process_new_callback_query_queue(user_id, 0);
|
||||
}
|
||||
@ -9806,6 +9830,6 @@ constexpr Client::Slice Client::API_ID_INVALID_ERROR_DESCRIPTION;
|
||||
constexpr int Client::CLOSING_ERROR_CODE;
|
||||
constexpr Client::Slice Client::CLOSING_ERROR_DESCRIPTION;
|
||||
|
||||
std::unordered_map<td::string, td::Status (Client::*)(PromisedQueryPtr &query)> Client::methods_;
|
||||
td::FlatHashMap<td::string, td::Status (Client::*)(PromisedQueryPtr &query)> Client::methods_;
|
||||
|
||||
} // namespace telegram_bot_api
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/Container.h"
|
||||
#include "td/utils/FlatHashMap.h"
|
||||
#include "td/utils/FlatHashSet.h"
|
||||
#include "td/utils/JsonBuilder.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/Status.h"
|
||||
@ -27,8 +29,6 @@
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <queue>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace telegram_bot_api {
|
||||
|
||||
@ -588,9 +588,10 @@ class Client final : public WebhookActor::Callback {
|
||||
bool is_inline_bot = false;
|
||||
bool has_private_forwards = false;
|
||||
};
|
||||
static void add_user(std::unordered_map<int64, UserInfo> &users, object_ptr<td_api::user> &&user);
|
||||
static void add_user(UserInfo *user_info, object_ptr<td_api::user> &&user);
|
||||
void set_user_bio(int64 user_id, td::string &&bio);
|
||||
void set_user_has_private_forwards(int64 user_id, bool has_private_forwards);
|
||||
UserInfo *add_user_info(int64 user_id);
|
||||
const UserInfo *get_user_info(int64 user_id) const;
|
||||
|
||||
struct GroupInfo {
|
||||
@ -602,9 +603,10 @@ class Client final : public WebhookActor::Callback {
|
||||
bool is_active = false;
|
||||
int64 upgraded_to_supergroup_id = 0;
|
||||
};
|
||||
static void add_group(std::unordered_map<int64, GroupInfo> &groups, object_ptr<td_api::basicGroup> &&group);
|
||||
static void add_group(GroupInfo *group_info, object_ptr<td_api::basicGroup> &&group);
|
||||
void set_group_description(int64 group_id, td::string &&descripton);
|
||||
void set_group_invite_link(int64 group_id, td::string &&invite_link);
|
||||
GroupInfo *add_group_info(int64 group_id);
|
||||
const GroupInfo *get_group_info(int64 group_id) const;
|
||||
|
||||
struct SupergroupInfo {
|
||||
@ -621,8 +623,7 @@ class Client final : public WebhookActor::Callback {
|
||||
bool can_set_sticker_set = false;
|
||||
bool has_location = false;
|
||||
};
|
||||
static void add_supergroup(std::unordered_map<int64, SupergroupInfo> &supergroups,
|
||||
object_ptr<td_api::supergroup> &&supergroup);
|
||||
static void add_supergroup(SupergroupInfo *supergroup_info, object_ptr<td_api::supergroup> &&supergroup);
|
||||
void set_supergroup_description(int64 supergroup_id, td::string &&descripton);
|
||||
void set_supergroup_invite_link(int64 supergroup_id, td::string &&invite_link);
|
||||
void set_supergroup_sticker_set_id(int64 supergroup_id, int64 sticker_set_id);
|
||||
@ -630,6 +631,7 @@ class Client final : public WebhookActor::Callback {
|
||||
void set_supergroup_slow_mode_delay(int64 supergroup_id, int32 slow_mode_delay);
|
||||
void set_supergroup_linked_chat_id(int64 supergroup_id, int64 linked_chat_id);
|
||||
void set_supergroup_location(int64 supergroup_id, object_ptr<td_api::chatLocation> location);
|
||||
SupergroupInfo *add_supergroup_info(int64 supergroup_id);
|
||||
const SupergroupInfo *get_supergroup_info(int64 supergroup_id) const;
|
||||
|
||||
struct ChatInfo {
|
||||
@ -861,30 +863,30 @@ class Client final : public WebhookActor::Callback {
|
||||
int64 channel_bot_user_id_ = 0;
|
||||
int64 service_notifications_user_id_ = 0;
|
||||
|
||||
static std::unordered_map<td::string, Status (Client::*)(PromisedQueryPtr &query)> methods_;
|
||||
static td::FlatHashMap<td::string, Status (Client::*)(PromisedQueryPtr &query)> methods_;
|
||||
|
||||
std::unordered_map<FullMessageId, std::unique_ptr<MessageInfo>, FullMessageIdHash> messages_; // message cache
|
||||
std::unordered_map<int64, UserInfo> users_; // user info cache
|
||||
std::unordered_map<int64, GroupInfo> groups_; // group info cache
|
||||
std::unordered_map<int64, SupergroupInfo> supergroups_; // supergroup info cache
|
||||
std::unordered_map<int64, ChatInfo> chats_; // chat info cache
|
||||
td::FlatHashMap<FullMessageId, std::unique_ptr<MessageInfo>, FullMessageIdHash> messages_; // message cache
|
||||
td::FlatHashMap<int64, td::unique_ptr<UserInfo>> users_; // user info cache
|
||||
td::FlatHashMap<int64, td::unique_ptr<GroupInfo>> groups_; // group info cache
|
||||
td::FlatHashMap<int64, td::unique_ptr<SupergroupInfo>> supergroups_; // supergroup info cache
|
||||
td::FlatHashMap<int64, td::unique_ptr<ChatInfo>> chats_; // chat info cache
|
||||
|
||||
std::unordered_map<FullMessageId, std::unordered_set<int64>, FullMessageIdHash>
|
||||
td::FlatHashMap<FullMessageId, td::FlatHashSet<int64>, FullMessageIdHash>
|
||||
reply_message_ids_; // message -> replies to it
|
||||
std::unordered_map<FullMessageId, std::unordered_set<int64>, FullMessageIdHash>
|
||||
td::FlatHashMap<FullMessageId, td::FlatHashSet<int64>, FullMessageIdHash>
|
||||
yet_unsent_reply_message_ids_; // message -> replies to it
|
||||
|
||||
std::unordered_map<int32, td::vector<PromisedQueryPtr>> file_download_listeners_;
|
||||
std::unordered_set<int32> download_started_file_ids_;
|
||||
td::FlatHashMap<int32, td::vector<PromisedQueryPtr>> file_download_listeners_;
|
||||
td::FlatHashSet<int32> download_started_file_ids_;
|
||||
|
||||
struct YetUnsentMessage {
|
||||
int64 reply_to_message_id = 0;
|
||||
bool is_reply_to_message_deleted = false;
|
||||
int64 send_message_query_id = 0;
|
||||
};
|
||||
std::unordered_map<FullMessageId, YetUnsentMessage, FullMessageIdHash> yet_unsent_messages_;
|
||||
td::FlatHashMap<FullMessageId, YetUnsentMessage, FullMessageIdHash> yet_unsent_messages_;
|
||||
|
||||
std::unordered_map<int64, int32> yet_unsent_message_count_;
|
||||
td::FlatHashMap<int64, int32> yet_unsent_message_count_; // chat_id -> count
|
||||
|
||||
struct PendingSendMessageQuery {
|
||||
PromisedQueryPtr query;
|
||||
@ -893,7 +895,7 @@ class Client final : public WebhookActor::Callback {
|
||||
td::vector<td::string> messages;
|
||||
object_ptr<td_api::error> error;
|
||||
};
|
||||
std::unordered_map<int64, PendingSendMessageQuery>
|
||||
td::FlatHashMap<int64, td::unique_ptr<PendingSendMessageQuery>>
|
||||
pending_send_message_queries_; // query_id -> PendingSendMessageQuery
|
||||
int64 current_send_message_query_id_ = 1;
|
||||
|
||||
@ -909,28 +911,28 @@ class Client final : public WebhookActor::Callback {
|
||||
std::queue<NewMessage> queue_;
|
||||
bool has_active_request_ = false;
|
||||
};
|
||||
std::unordered_map<int64, NewMessageQueue> new_message_queues_; // chat_id -> queue
|
||||
td::FlatHashMap<int64, NewMessageQueue> new_message_queues_; // chat_id -> queue
|
||||
|
||||
struct NewCallbackQueryQueue {
|
||||
std::queue<object_ptr<td_api::updateNewCallbackQuery>> queue_;
|
||||
bool has_active_request_ = false;
|
||||
};
|
||||
std::unordered_map<int64, NewCallbackQueryQueue> new_callback_query_queues_; // sender_user_id -> queue
|
||||
td::FlatHashMap<int64, NewCallbackQueryQueue> new_callback_query_queues_; // sender_user_id -> queue
|
||||
|
||||
std::unordered_map<int64, td::string> sticker_set_names_;
|
||||
td::FlatHashMap<int64, td::string> sticker_set_names_;
|
||||
|
||||
int64 cur_temp_bot_user_id_ = 1;
|
||||
std::unordered_map<td::string, int64> bot_user_ids_;
|
||||
std::unordered_set<td::string> unresolved_bot_usernames_;
|
||||
std::unordered_map<int64, int64> temp_to_real_bot_user_id_;
|
||||
std::unordered_map<td::string, td::vector<int64>> awaiting_bot_resolve_queries_;
|
||||
td::FlatHashMap<td::string, int64> bot_user_ids_;
|
||||
td::FlatHashSet<td::string> unresolved_bot_usernames_;
|
||||
td::FlatHashMap<int64, int64> temp_to_real_bot_user_id_;
|
||||
td::FlatHashMap<td::string, td::vector<int64>> awaiting_bot_resolve_queries_;
|
||||
|
||||
struct PendingBotResolveQuery {
|
||||
std::size_t pending_resolve_count = 0;
|
||||
PromisedQueryPtr query;
|
||||
td::Promise<PromisedQueryPtr> on_success;
|
||||
};
|
||||
std::unordered_map<int64, PendingBotResolveQuery> pending_bot_resolve_queries_;
|
||||
td::FlatHashMap<int64, PendingBotResolveQuery> pending_bot_resolve_queries_;
|
||||
int64 current_bot_resolve_query_id_ = 1;
|
||||
|
||||
td::string dir_;
|
||||
|
@ -71,9 +71,13 @@ void ClientManager::send(PromisedQueryPtr query) {
|
||||
return fail_query(401, "Unauthorized: invalid token specified", std::move(query));
|
||||
}
|
||||
auto r_user_id = td::to_integer_safe<td::int64>(query->token().substr(0, token.find(':')));
|
||||
if (r_user_id.is_error() || r_user_id.ok() < 0 || !token_range_(r_user_id.ok())) {
|
||||
if (r_user_id.is_error() || !token_range_(r_user_id.ok())) {
|
||||
return fail_query(421, "Misdirected Request: unallowed token specified", std::move(query));
|
||||
}
|
||||
auto user_id = r_user_id.ok();
|
||||
if (user_id <= 0 || user_id >= (static_cast<td::int64>(1) << 54)) {
|
||||
return fail_query(401, "Unauthorized: invalid token specified", std::move(query));
|
||||
}
|
||||
|
||||
if (query->is_test_dc()) {
|
||||
token += "/test";
|
||||
@ -113,7 +117,7 @@ void ClientManager::send(PromisedQueryPtr query) {
|
||||
}
|
||||
flood_control.add_event(static_cast<td::int32>(now));
|
||||
}
|
||||
auto tqueue_id = get_tqueue_id(r_user_id.ok(), query->is_test_dc());
|
||||
auto tqueue_id = get_tqueue_id(user_id, query->is_test_dc());
|
||||
if (active_client_count_.find(tqueue_id) != active_client_count_.end()) {
|
||||
// return query->set_retry_after_error(1);
|
||||
}
|
||||
@ -392,6 +396,7 @@ void ClientManager::raw_event(const td::Event::Raw &event) {
|
||||
auto id = get_link_token();
|
||||
auto *info = clients_.get(id);
|
||||
CHECK(info != nullptr);
|
||||
CHECK(info->tqueue_id_ != 0);
|
||||
auto &value = active_client_count_[info->tqueue_id_];
|
||||
if (event.ptr != nullptr) {
|
||||
value++;
|
||||
|
@ -16,11 +16,11 @@
|
||||
#include "td/utils/buffer.h"
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/Container.h"
|
||||
#include "td/utils/FlatHashMap.h"
|
||||
#include "td/utils/FloodControlFast.h"
|
||||
#include "td/utils/Slice.h"
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
|
||||
namespace telegram_bot_api {
|
||||
@ -61,9 +61,9 @@ class ClientManager final : public td::Actor {
|
||||
std::shared_ptr<const ClientParameters> parameters_;
|
||||
TokenRange token_range_;
|
||||
|
||||
std::unordered_map<td::string, td::uint64> token_to_id_;
|
||||
std::unordered_map<td::string, td::FloodControlFast> flood_controls_;
|
||||
std::unordered_map<td::int64, td::uint64> active_client_count_;
|
||||
td::FlatHashMap<td::string, td::uint64> token_to_id_;
|
||||
td::FlatHashMap<td::string, td::FloodControlFast> flood_controls_;
|
||||
td::FlatHashMap<td::int64, td::uint64> active_client_count_;
|
||||
|
||||
bool close_flag_ = false;
|
||||
td::vector<td::Promise<td::Unit>> close_promises_;
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
namespace telegram_bot_api {
|
||||
|
||||
std::unordered_map<td::string, std::unique_ptr<td::VirtuallyJsonable>> empty_parameters;
|
||||
td::FlatHashMap<td::string, std::unique_ptr<td::VirtuallyJsonable>> empty_parameters;
|
||||
|
||||
Query::Query(td::vector<td::BufferSlice> &&container, td::Slice token, bool is_test_dc, td::MutableSlice method,
|
||||
td::vector<std::pair<td::MutableSlice, td::MutableSlice>> &&args,
|
||||
@ -96,7 +96,7 @@ void Query::set_error(int http_status_code, td::BufferSlice result) {
|
||||
void Query::set_retry_after_error(int retry_after) {
|
||||
retry_after_ = retry_after;
|
||||
|
||||
std::unordered_map<td::string, std::unique_ptr<td::VirtuallyJsonable>> parameters;
|
||||
td::FlatHashMap<td::string, std::unique_ptr<td::VirtuallyJsonable>> parameters;
|
||||
parameters.emplace("retry_after", std::make_unique<td::VirtuallyJsonableLong>(retry_after));
|
||||
set_error(429, td::json_encode<td::BufferSlice>(
|
||||
JsonQueryError(429, PSLICE() << "Too Many Requests: retry after " << retry_after, parameters)));
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include "td/utils/buffer.h"
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/FlatHashMap.h"
|
||||
#include "td/utils/JsonBuilder.h"
|
||||
#include "td/utils/List.h"
|
||||
#include "td/utils/port/IPAddress.h"
|
||||
@ -23,7 +24,6 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
|
||||
namespace telegram_bot_api {
|
||||
@ -164,11 +164,11 @@ td::StringBuilder &operator<<(td::StringBuilder &sb, const Query &query);
|
||||
|
||||
// fix for outdated C++14 libraries
|
||||
// https://stackoverflow.com/questions/26947704/implicit-conversion-failure-from-initializer-list
|
||||
extern std::unordered_map<td::string, std::unique_ptr<td::VirtuallyJsonable>> empty_parameters;
|
||||
extern td::FlatHashMap<td::string, std::unique_ptr<td::VirtuallyJsonable>> empty_parameters;
|
||||
|
||||
class JsonParameters final : public td::Jsonable {
|
||||
public:
|
||||
explicit JsonParameters(const std::unordered_map<td::string, std::unique_ptr<td::VirtuallyJsonable>> ¶meters)
|
||||
explicit JsonParameters(const td::FlatHashMap<td::string, std::unique_ptr<td::VirtuallyJsonable>> ¶meters)
|
||||
: parameters_(parameters) {
|
||||
}
|
||||
void store(td::JsonValueScope *scope) const {
|
||||
@ -180,7 +180,7 @@ class JsonParameters final : public td::Jsonable {
|
||||
}
|
||||
|
||||
private:
|
||||
const std::unordered_map<td::string, std::unique_ptr<td::VirtuallyJsonable>> ¶meters_;
|
||||
const td::FlatHashMap<td::string, std::unique_ptr<td::VirtuallyJsonable>> ¶meters_;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
@ -206,7 +206,7 @@ class JsonQueryError final : public td::Jsonable {
|
||||
public:
|
||||
JsonQueryError(
|
||||
int error_code, td::Slice description,
|
||||
const std::unordered_map<td::string, std::unique_ptr<td::VirtuallyJsonable>> ¶meters = empty_parameters)
|
||||
const td::FlatHashMap<td::string, std::unique_ptr<td::VirtuallyJsonable>> ¶meters = empty_parameters)
|
||||
: error_code_(error_code), description_(description), parameters_(parameters) {
|
||||
}
|
||||
void store(td::JsonValueScope *scope) const {
|
||||
@ -222,7 +222,7 @@ class JsonQueryError final : public td::Jsonable {
|
||||
private:
|
||||
int error_code_;
|
||||
td::Slice description_;
|
||||
const std::unordered_map<td::string, std::unique_ptr<td::VirtuallyJsonable>> ¶meters_;
|
||||
const td::FlatHashMap<td::string, std::unique_ptr<td::VirtuallyJsonable>> ¶meters_;
|
||||
};
|
||||
|
||||
class PromiseDeleter {
|
||||
@ -261,7 +261,7 @@ void answer_query(const Jsonable &result, PromisedQueryPtr query, td::Slice desc
|
||||
|
||||
inline void fail_query(
|
||||
int http_status_code, td::Slice description, PromisedQueryPtr query,
|
||||
const std::unordered_map<td::string, std::unique_ptr<td::VirtuallyJsonable>> ¶meters = empty_parameters) {
|
||||
const td::FlatHashMap<td::string, std::unique_ptr<td::VirtuallyJsonable>> ¶meters = empty_parameters) {
|
||||
query->set_error(http_status_code,
|
||||
td::json_encode<td::BufferSlice>(JsonQueryError(http_status_code, description, parameters)));
|
||||
query.reset(); // send query into promise explicitly
|
||||
|
@ -379,11 +379,14 @@ void WebhookActor::load_updates() {
|
||||
|
||||
for (auto &update : updates) {
|
||||
VLOG(webhook) << "Load update " << update.id;
|
||||
if (update_map_.find(update.id) != update_map_.end()) {
|
||||
LOG(ERROR) << "Receive duplicated event " << update.id << " from tqueue";
|
||||
CHECK(update.id.is_valid());
|
||||
auto &dest_ptr = update_map_[update.id];
|
||||
if (dest_ptr != nullptr) {
|
||||
LOG(ERROR) << "Receive duplicated event " << update.id << " from TQueue";
|
||||
continue;
|
||||
}
|
||||
auto &dest = update_map_[update.id];
|
||||
dest_ptr = td::make_unique<Update>();
|
||||
auto &dest = *dest_ptr;
|
||||
dest.id_ = update.id;
|
||||
dest.json_ = update.data.str();
|
||||
dest.delay_ = 1;
|
||||
@ -437,7 +440,7 @@ void WebhookActor::load_updates() {
|
||||
void WebhookActor::drop_event(td::TQueue::EventId event_id) {
|
||||
auto it = update_map_.find(event_id);
|
||||
CHECK(it != update_map_.end());
|
||||
auto queue_id = it->second.queue_id_;
|
||||
auto queue_id = it->second->queue_id_;
|
||||
update_map_.erase(it);
|
||||
|
||||
auto queue_updates_it = queue_updates_.find(queue_id);
|
||||
@ -448,8 +451,10 @@ void WebhookActor::drop_event(td::TQueue::EventId event_id) {
|
||||
if (queue_updates_it->second.event_ids.empty()) {
|
||||
queue_updates_.erase(queue_updates_it);
|
||||
} else {
|
||||
auto &update = update_map_[queue_updates_it->second.event_ids.front()];
|
||||
queues_.emplace(update.wakeup_at_, update.queue_id_);
|
||||
auto update_id = queue_updates_it->second.event_ids.front();
|
||||
CHECK(update_id.is_valid());
|
||||
auto &update = update_map_[update_id];
|
||||
queues_.emplace(update->wakeup_at_, update->queue_id_);
|
||||
}
|
||||
|
||||
parameters_->shared_data_->tqueue_->forget(tqueue_id_, event_id);
|
||||
@ -462,7 +467,7 @@ void WebhookActor::on_update_ok(td::TQueue::EventId event_id) {
|
||||
auto it = update_map_.find(event_id);
|
||||
CHECK(it != update_map_.end());
|
||||
|
||||
VLOG(webhook) << "Receive ok for update " << event_id << " in " << (last_success_time_ - it->second.last_send_time_)
|
||||
VLOG(webhook) << "Receive ok for update " << event_id << " in " << (last_success_time_ - it->second->last_send_time_)
|
||||
<< " seconds";
|
||||
|
||||
drop_event(event_id);
|
||||
@ -474,21 +479,22 @@ void WebhookActor::on_update_error(td::TQueue::EventId event_id, td::Slice error
|
||||
|
||||
auto it = update_map_.find(event_id);
|
||||
CHECK(it != update_map_.end());
|
||||
CHECK(it->second != nullptr);
|
||||
auto &update = *it->second;
|
||||
|
||||
const int MAX_RETRY_AFTER = 3600;
|
||||
retry_after = td::clamp(retry_after, 0, MAX_RETRY_AFTER);
|
||||
int next_delay = it->second.delay_;
|
||||
int next_delay = update.delay_;
|
||||
int next_effective_delay = retry_after;
|
||||
if (retry_after == 0 && it->second.fail_count_ > 0) {
|
||||
if (retry_after == 0 && update.fail_count_ > 0) {
|
||||
next_delay = td::min(WEBHOOK_MAX_RESEND_TIMEOUT, next_delay * 2);
|
||||
next_effective_delay = next_delay;
|
||||
}
|
||||
if (parameters_->shared_data_->get_unix_time(now) + next_effective_delay > it->second.expires_at_) {
|
||||
if (parameters_->shared_data_->get_unix_time(now) + next_effective_delay > update.expires_at_) {
|
||||
LOG(WARNING) << "Drop update " << event_id << ": " << error;
|
||||
drop_event(event_id);
|
||||
return;
|
||||
}
|
||||
auto &update = it->second;
|
||||
update.delay_ = next_delay;
|
||||
update.wakeup_at_ = now + next_effective_delay;
|
||||
update.fail_count_++;
|
||||
@ -514,10 +520,15 @@ td::Status WebhookActor::send_update() {
|
||||
}
|
||||
|
||||
auto queue_id = it->id;
|
||||
CHECK(queue_id != 0);
|
||||
queues_.erase(it);
|
||||
auto event_id = queue_updates_[queue_id].event_ids.front();
|
||||
CHECK(event_id.is_valid());
|
||||
|
||||
auto &update = update_map_[event_id];
|
||||
auto update_map_it = update_map_.find(event_id);
|
||||
CHECK(update_map_it != update_map_.end());
|
||||
CHECK(update_map_it->second != nullptr);
|
||||
auto &update = *update_map_it->second;
|
||||
update.last_send_time_ = now;
|
||||
|
||||
auto body = td::json_encode<td::BufferSlice>(JsonUpdate(update.id_.value(), update.json_));
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "td/utils/BufferedFd.h"
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/Container.h"
|
||||
#include "td/utils/FlatHashMap.h"
|
||||
#include "td/utils/FloodControlFast.h"
|
||||
#include "td/utils/HttpUrl.h"
|
||||
#include "td/utils/JsonBuilder.h"
|
||||
@ -35,7 +36,6 @@
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <tuple>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace telegram_bot_api {
|
||||
|
||||
@ -127,8 +127,8 @@ class WebhookActor final : public td::HttpOutboundConnection::Callback {
|
||||
return std::hash<td::int32>()(event_id.value());
|
||||
}
|
||||
};
|
||||
std::unordered_map<td::TQueue::EventId, Update, EventIdHash> update_map_;
|
||||
std::unordered_map<td::int64, QueueUpdates> queue_updates_;
|
||||
td::FlatHashMap<td::TQueue::EventId, td::unique_ptr<Update>, EventIdHash> update_map_;
|
||||
td::FlatHashMap<td::int64, QueueUpdates> queue_updates_;
|
||||
std::set<Queue> queues_;
|
||||
td::int64 unique_queue_id_ = static_cast<td::int64>(1) << 60;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user