Use FlatHashMap in mtproto and td_json_client.

This commit is contained in:
levlam 2022-02-09 16:05:53 +03:00
parent b403a3793d
commit b4fda2d45a
6 changed files with 41 additions and 31 deletions

View File

@ -136,7 +136,7 @@ void gen_tl_constructor_from_string(StringBuilder &sb, Slice name, const Vec &ve
return;
}
sb << " {\n";
sb << " static const std::unordered_map<Slice, int32, SliceHash> m = {\n";
sb << " static const FlatHashMap<Slice, int32, SliceHash> m = {\n";
bool is_first = true;
for (auto &p : vec) {
@ -216,10 +216,10 @@ void gen_json_converter_file(const tl::simple::Schema &schema, const std::string
sb << "#include \"td/utils/base64.h\"\n";
sb << "#include \"td/utils/common.h\"\n";
sb << "#include \"td/utils/FlatHashMap.h\"\n";
sb << "#include \"td/utils/Slice.h\"\n\n";
sb << "#include <functional>\n";
sb << "#include <unordered_map>\n\n";
sb << "#include <functional>\n\n";
}
sb << "namespace td {\n";
sb << "namespace td_api {\n";

View File

@ -15,6 +15,7 @@
#include "td/net/DarwinHttp.h"
#endif
#include "td/utils/FlatHashMap.h"
#include "td/utils/format.h"
#include "td/utils/logging.h"
#include "td/utils/misc.h"
@ -26,7 +27,6 @@
#include "td/utils/StorerBase.h"
#include <memory>
#include <unordered_map>
#include <utility>
namespace td {
@ -67,6 +67,7 @@ class RawConnectionDefault final : public RawConnection {
bool use_quick_ack = false;
if (quick_ack_token != 0 && transport_->support_quick_ack()) {
CHECK(info.message_ack & (1u << 31));
auto tmp = quick_ack_to_token_.emplace(info.message_ack, quick_ack_token);
if (tmp.second) {
use_quick_ack = true;
@ -130,7 +131,7 @@ class RawConnectionDefault final : public RawConnection {
PublicFields extra_;
BufferedFd<SocketFd> socket_fd_;
unique_ptr<IStreamTransport> transport_;
std::unordered_map<uint32, uint64> quick_ack_to_token_;
FlatHashMap<uint32, uint64> quick_ack_to_token_;
bool has_error_{false};
unique_ptr<StatsCallback> stats_callback_;
@ -218,11 +219,15 @@ class RawConnectionDefault final : public RawConnection {
}
Status on_quick_ack(uint32 quick_ack, Callback &callback) {
if ((quick_ack & (1u << 31)) == 0) {
LOG(ERROR) << "Receive invalid quick_ack " << quick_ack;
return Status::OK();
}
auto it = quick_ack_to_token_.find(quick_ack);
if (it == quick_ack_to_token_.end()) {
LOG(WARNING) << Status::Error(PSLICE() << "Unknown quick_ack " << quick_ack);
LOG(WARNING) << "Receive unknown quick_ack " << quick_ack;
return Status::OK();
// TODO: return Status::Error(PSLICE() << "Unknown quick_ack " << quick_ack);
}
auto token = it->second;
quick_ack_to_token_.erase(it);

View File

@ -437,13 +437,13 @@ Status SessionConnection::on_packet(const MsgInfo &info, const mtproto_api::msgs
if (it == service_queries_.end()) {
return Status::Error("Unknown msgs_state_info");
}
SCOPE_EXIT {
service_queries_.erase(it);
};
if (it->second.type != ServiceQuery::GetStateInfo) {
return Status::Error("Got msg_state_info in response not to GetStateInfo");
auto query = std::move(it->second);
service_queries_.erase(it);
if (query.type != ServiceQuery::GetStateInfo) {
return Status::Error("Receive msg_state_info in response not to GetStateInfo");
}
return on_msgs_state_info(it->second.message_ids, msgs_state_info.info_);
return on_msgs_state_info(query.message_ids, msgs_state_info.info_);
}
Status SessionConnection::on_packet(const MsgInfo &info, const mtproto_api::msgs_all_info &msgs_all_info) {
@ -573,8 +573,9 @@ void SessionConnection::on_message_failed(uint64 id, Status status) {
auto cit = container_to_service_msg_.find(id);
if (cit != container_to_service_msg_.end()) {
for (auto nid : cit->second) {
on_message_failed_inner(nid);
auto message_ids = cit->second;
for (auto message_id : message_ids) {
on_message_failed_inner(message_id);
}
} else {
on_message_failed_inner(id);
@ -586,21 +587,25 @@ void SessionConnection::on_message_failed_inner(uint64 id) {
if (it == service_queries_.end()) {
return;
}
switch (it->second.type) {
auto query = std::move(it->second);
service_queries_.erase(it);
switch (query.type) {
case ServiceQuery::ResendAnswer: {
for (auto message_id : it->second.message_ids) {
for (auto message_id : query.message_ids) {
resend_answer(message_id);
}
break;
}
case ServiceQuery::GetStateInfo: {
for (auto message_id : it->second.message_ids) {
for (auto message_id : query.message_ids) {
get_state_info(message_id);
}
break;
}
default:
UNREACHABLE();
}
service_queries_.erase(id);
}
bool SessionConnection::must_flush_packet() {
@ -968,11 +973,10 @@ void SessionConnection::flush_packet() {
}
if (resend_answer_id) {
service_queries_.insert({resend_answer_id, ServiceQuery{ServiceQuery::ResendAnswer, std::move(to_resend_answer)}});
service_queries_.emplace(resend_answer_id, ServiceQuery{ServiceQuery::ResendAnswer, std::move(to_resend_answer)});
}
if (get_state_info_id) {
service_queries_.insert(
{get_state_info_id, ServiceQuery{ServiceQuery::GetStateInfo, std::move(to_get_state_info)}});
service_queries_.emplace(get_state_info_id, ServiceQuery{ServiceQuery::GetStateInfo, std::move(to_get_state_info)});
}
if (ping_id != 0) {
last_ping_container_id_ = container_id;

View File

@ -11,6 +11,7 @@
#include "td/mtproto/RawConnection.h"
#include "td/utils/buffer.h"
#include "td/utils/FlatHashMap.h"
#include "td/utils/format.h"
#include "td/utils/logging.h"
#include "td/utils/Named.h"
@ -22,7 +23,6 @@
#include "td/utils/StringBuilder.h"
#include "td/utils/tl_parsers.h"
#include <unordered_map>
#include <utility>
namespace td {
@ -176,10 +176,10 @@ class SessionConnection final
vector<int64> to_resend_answer_;
vector<int64> to_cancel_answer_;
vector<int64> to_get_state_info_;
std::unordered_map<uint64, ServiceQuery> service_queries_;
FlatHashMap<uint64, ServiceQuery> service_queries_;
// nobody cleans up this map. But it should be really small.
std::unordered_map<uint64, vector<uint64>> container_to_service_msg_;
FlatHashMap<uint64, vector<uint64>> container_to_service_msg_;
double last_read_at_ = 0;
double last_ping_at_ = 0;

View File

@ -3441,13 +3441,15 @@ void ContactsManager::on_channel_participant_cache_timeout(ChannelId channel_id)
auto &participants = channel_participants_it->second.participants_;
auto min_access_date = G()->unix_time() - CHANNEL_PARTICIPANT_CACHE_TIME;
for (auto it = participants.begin(); it != participants.end();) {
vector<DialogId> to_delete_dialog_ids;
for (auto it = participants.begin(); it != participants.end(); ++it) {
if (it->second.last_access_date_ < min_access_date) {
it = participants.erase(it);
} else {
++it;
to_delete_dialog_ids.push_back(it->first);
}
}
for (auto dialog_id : to_delete_dialog_ids) {
participants.erase(dialog_id);
}
if (participants.empty()) {
channel_participants_.erase(channel_participants_it);

View File

@ -48,7 +48,6 @@
#include <functional>
#include <memory>
#include <unordered_map>
#include <unordered_set>
#include <utility>
@ -1742,7 +1741,7 @@ class ContactsManager final : public Actor {
int32 last_access_date_ = 0;
};
struct ChannelParticipants {
std::unordered_map<DialogId, ChannelParticipantInfo, DialogIdHash> participants_;
FlatHashMap<DialogId, ChannelParticipantInfo, DialogIdHash> participants_;
};
FlatHashMap<ChannelId, ChannelParticipants, ChannelIdHash> channel_participants_;