Merge remote-tracking branch 'td/master'
This commit is contained in:
commit
eadb920736
@ -88,6 +88,9 @@ function(td_set_up_compiler)
|
||||
# _FILE_OFFSET_BITS is broken in Android NDK r15, r15b and r17 and doesn't work prior to Android 7.0
|
||||
add_definitions(-D_FILE_OFFSET_BITS=64)
|
||||
|
||||
# _GNU_SOURCE might not be defined by g++
|
||||
add_definitions(-D_GNU_SOURCE)
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "SunOS")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lsocket -lnsl")
|
||||
if (ILLUMOS)
|
||||
|
@ -3399,43 +3399,16 @@ ContactsManager::ContactsManager(Td *td, ActorShared<> parent) : td_(td), parent
|
||||
}
|
||||
|
||||
ContactsManager::~ContactsManager() {
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), users_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), users_full_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), user_photos_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), unknown_users_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), pending_user_photos_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), user_profile_photo_file_source_ids_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), my_photo_file_id_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), chats_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), chats_full_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), unknown_chats_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), chat_full_file_source_ids_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), min_channels_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), channels_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), channels_full_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), unknown_channels_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), invalidated_channels_full_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), channel_full_file_source_ids_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), secret_chats_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), unknown_secret_chats_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), secret_chats_with_user_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), invite_link_infos_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), dialog_access_by_invite_link_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), loaded_from_database_users_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), unavailable_user_fulls_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), loaded_from_database_chats_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), unavailable_chat_fulls_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), loaded_from_database_channels_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), unavailable_channel_fulls_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), loaded_from_database_secret_chats_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), dialog_administrators_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), cached_channel_participants_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), resolved_phone_numbers_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), channel_participants_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), all_imported_contacts_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), linked_channel_ids_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), restricted_user_ids_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), restricted_channel_ids_);
|
||||
Scheduler::instance()->destroy_on_scheduler(
|
||||
G()->get_gc_scheduler_id(), users_, users_full_, user_photos_, unknown_users_, pending_user_photos_,
|
||||
user_profile_photo_file_source_ids_, my_photo_file_id_, chats_, chats_full_, unknown_chats_,
|
||||
chat_full_file_source_ids_, min_channels_, channels_, channels_full_, unknown_channels_,
|
||||
invalidated_channels_full_, channel_full_file_source_ids_, secret_chats_, unknown_secret_chats_,
|
||||
secret_chats_with_user_, invite_link_infos_, dialog_access_by_invite_link_, loaded_from_database_users_,
|
||||
unavailable_user_fulls_, loaded_from_database_chats_, unavailable_chat_fulls_, loaded_from_database_channels_,
|
||||
unavailable_channel_fulls_, loaded_from_database_secret_chats_, dialog_administrators_,
|
||||
cached_channel_participants_, resolved_phone_numbers_, channel_participants_, all_imported_contacts_,
|
||||
linked_channel_ids_, restricted_user_ids_, restricted_channel_ids_);
|
||||
}
|
||||
|
||||
void ContactsManager::tear_down() {
|
||||
@ -8795,23 +8768,24 @@ void ContactsManager::on_get_user(tl_object_ptr<telegram_api::User> &&user_ptr,
|
||||
class ContactsManager::UserLogEvent {
|
||||
public:
|
||||
UserId user_id;
|
||||
User u;
|
||||
const User *u_in = nullptr;
|
||||
unique_ptr<User> u_out;
|
||||
|
||||
UserLogEvent() = default;
|
||||
|
||||
UserLogEvent(UserId user_id, const User &u) : user_id(user_id), u(u) {
|
||||
UserLogEvent(UserId user_id, const User *u) : user_id(user_id), u_in(u) {
|
||||
}
|
||||
|
||||
template <class StorerT>
|
||||
void store(StorerT &storer) const {
|
||||
td::store(user_id, storer);
|
||||
td::store(u, storer);
|
||||
td::store(*u_in, storer);
|
||||
}
|
||||
|
||||
template <class ParserT>
|
||||
void parse(ParserT &parser) {
|
||||
td::parse(user_id, parser);
|
||||
td::parse(u, parser);
|
||||
td::parse(u_out, parser);
|
||||
}
|
||||
};
|
||||
|
||||
@ -8830,7 +8804,7 @@ void ContactsManager::save_user(User *u, UserId user_id, bool from_binlog) {
|
||||
make_tl_object<td_api::updateAccessHash>(get_user_access_hash_object(user_id, u)));
|
||||
}
|
||||
if (!from_binlog) {
|
||||
auto log_event = UserLogEvent(user_id, *u);
|
||||
auto log_event = UserLogEvent(user_id, u);
|
||||
auto storer = get_log_event_storer(log_event);
|
||||
if (u->log_event_id == 0) {
|
||||
u->log_event_id = binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::Users, storer);
|
||||
@ -8860,8 +8834,8 @@ void ContactsManager::on_binlog_user_event(BinlogEvent &&event) {
|
||||
}
|
||||
|
||||
LOG(INFO) << "Add " << user_id << " from binlog";
|
||||
User *u = add_user(user_id, "on_binlog_user_event");
|
||||
*u = std::move(log_event.u); // users come from binlog before all other events, so just add them
|
||||
User *u = users_.emplace(user_id, std::move(log_event.u_out)).first->second.get();
|
||||
CHECK(u != nullptr);
|
||||
|
||||
u->log_event_id = event.id_;
|
||||
|
||||
@ -9109,23 +9083,24 @@ ContactsManager::User *ContactsManager::get_user_force_impl(UserId user_id) {
|
||||
class ContactsManager::ChatLogEvent {
|
||||
public:
|
||||
ChatId chat_id;
|
||||
Chat c;
|
||||
const Chat *c_in = nullptr;
|
||||
unique_ptr<Chat> c_out;
|
||||
|
||||
ChatLogEvent() = default;
|
||||
|
||||
ChatLogEvent(ChatId chat_id, const Chat &c) : chat_id(chat_id), c(c) {
|
||||
ChatLogEvent(ChatId chat_id, const Chat *c) : chat_id(chat_id), c_in(c) {
|
||||
}
|
||||
|
||||
template <class StorerT>
|
||||
void store(StorerT &storer) const {
|
||||
td::store(chat_id, storer);
|
||||
td::store(c, storer);
|
||||
td::store(*c_in, storer);
|
||||
}
|
||||
|
||||
template <class ParserT>
|
||||
void parse(ParserT &parser) {
|
||||
td::parse(chat_id, parser);
|
||||
td::parse(c, parser);
|
||||
td::parse(c_out, parser);
|
||||
}
|
||||
};
|
||||
|
||||
@ -9136,7 +9111,7 @@ void ContactsManager::save_chat(Chat *c, ChatId chat_id, bool from_binlog) {
|
||||
CHECK(c != nullptr);
|
||||
if (!c->is_saved) {
|
||||
if (!from_binlog) {
|
||||
auto log_event = ChatLogEvent(chat_id, *c);
|
||||
auto log_event = ChatLogEvent(chat_id, c);
|
||||
auto storer = get_log_event_storer(log_event);
|
||||
if (c->log_event_id == 0) {
|
||||
c->log_event_id = binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::Chats, storer);
|
||||
@ -9167,8 +9142,8 @@ void ContactsManager::on_binlog_chat_event(BinlogEvent &&event) {
|
||||
}
|
||||
|
||||
LOG(INFO) << "Add " << chat_id << " from binlog";
|
||||
Chat *c = add_chat(chat_id);
|
||||
*c = std::move(log_event.c); // chats come from binlog before all other events, so just add them
|
||||
Chat *c = chats_.emplace(chat_id, std::move(log_event.c_out)).first->second.get();
|
||||
CHECK(c != nullptr);
|
||||
|
||||
c->log_event_id = event.id_;
|
||||
|
||||
@ -9346,23 +9321,24 @@ ContactsManager::Chat *ContactsManager::get_chat_force(ChatId chat_id) {
|
||||
class ContactsManager::ChannelLogEvent {
|
||||
public:
|
||||
ChannelId channel_id;
|
||||
Channel c;
|
||||
const Channel *c_in = nullptr;
|
||||
unique_ptr<Channel> c_out;
|
||||
|
||||
ChannelLogEvent() = default;
|
||||
|
||||
ChannelLogEvent(ChannelId channel_id, const Channel &c) : channel_id(channel_id), c(c) {
|
||||
ChannelLogEvent(ChannelId channel_id, const Channel *c) : channel_id(channel_id), c_in(c) {
|
||||
}
|
||||
|
||||
template <class StorerT>
|
||||
void store(StorerT &storer) const {
|
||||
td::store(channel_id, storer);
|
||||
td::store(c, storer);
|
||||
td::store(*c_in, storer);
|
||||
}
|
||||
|
||||
template <class ParserT>
|
||||
void parse(ParserT &parser) {
|
||||
td::parse(channel_id, parser);
|
||||
td::parse(c, parser);
|
||||
td::parse(c_out, parser);
|
||||
}
|
||||
};
|
||||
|
||||
@ -9381,7 +9357,7 @@ void ContactsManager::save_channel(Channel *c, ChannelId channel_id, bool from_b
|
||||
make_tl_object<td_api::updateAccessHash>(get_channel_access_hash_object(channel_id, c)));
|
||||
}
|
||||
if (!from_binlog) {
|
||||
auto log_event = ChannelLogEvent(channel_id, *c);
|
||||
auto log_event = ChannelLogEvent(channel_id, c);
|
||||
auto storer = get_log_event_storer(log_event);
|
||||
if (c->log_event_id == 0) {
|
||||
c->log_event_id = binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::Channels, storer);
|
||||
@ -9412,8 +9388,8 @@ void ContactsManager::on_binlog_channel_event(BinlogEvent &&event) {
|
||||
}
|
||||
|
||||
LOG(INFO) << "Add " << channel_id << " from binlog";
|
||||
Channel *c = add_channel(channel_id, "on_binlog_channel_event");
|
||||
*c = std::move(log_event.c); // channels come from binlog before all other events, so just add them
|
||||
Channel *c = channels_.emplace(channel_id, std::move(log_event.c_out)).first->second.get();
|
||||
CHECK(c != nullptr);
|
||||
|
||||
c->log_event_id = event.id_;
|
||||
|
||||
@ -9607,23 +9583,24 @@ ContactsManager::Channel *ContactsManager::get_channel_force(ChannelId channel_i
|
||||
class ContactsManager::SecretChatLogEvent {
|
||||
public:
|
||||
SecretChatId secret_chat_id;
|
||||
SecretChat c;
|
||||
const SecretChat *c_in = nullptr;
|
||||
unique_ptr<SecretChat> c_out;
|
||||
|
||||
SecretChatLogEvent() = default;
|
||||
|
||||
SecretChatLogEvent(SecretChatId secret_chat_id, const SecretChat &c) : secret_chat_id(secret_chat_id), c(c) {
|
||||
SecretChatLogEvent(SecretChatId secret_chat_id, const SecretChat *c) : secret_chat_id(secret_chat_id), c_in(c) {
|
||||
}
|
||||
|
||||
template <class StorerT>
|
||||
void store(StorerT &storer) const {
|
||||
td::store(secret_chat_id, storer);
|
||||
td::store(c, storer);
|
||||
td::store(*c_in, storer);
|
||||
}
|
||||
|
||||
template <class ParserT>
|
||||
void parse(ParserT &parser) {
|
||||
td::parse(secret_chat_id, parser);
|
||||
td::parse(c, parser);
|
||||
td::parse(c_out, parser);
|
||||
}
|
||||
};
|
||||
|
||||
@ -9634,7 +9611,7 @@ void ContactsManager::save_secret_chat(SecretChat *c, SecretChatId secret_chat_i
|
||||
CHECK(c != nullptr);
|
||||
if (!c->is_saved) {
|
||||
if (!from_binlog) {
|
||||
auto log_event = SecretChatLogEvent(secret_chat_id, *c);
|
||||
auto log_event = SecretChatLogEvent(secret_chat_id, c);
|
||||
auto storer = get_log_event_storer(log_event);
|
||||
if (c->log_event_id == 0) {
|
||||
c->log_event_id = binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::SecretChatInfos, storer);
|
||||
@ -9665,8 +9642,8 @@ void ContactsManager::on_binlog_secret_chat_event(BinlogEvent &&event) {
|
||||
}
|
||||
|
||||
LOG(INFO) << "Add " << secret_chat_id << " from binlog";
|
||||
SecretChat *c = add_secret_chat(secret_chat_id);
|
||||
*c = std::move(log_event.c); // secret chats come from binlog before all other events, so just add them
|
||||
SecretChat *c = secret_chats_.emplace(secret_chat_id, std::move(log_event.c_out)).first->second.get();
|
||||
CHECK(c != nullptr);
|
||||
|
||||
c->log_event_id = event.id_;
|
||||
|
||||
|
@ -6,7 +6,6 @@
|
||||
//
|
||||
#include "td/telegram/DownloadManager.h"
|
||||
|
||||
#include "td/telegram/FileReferenceManager.h"
|
||||
#include "td/telegram/files/FileId.hpp"
|
||||
#include "td/telegram/files/FileSourceId.hpp"
|
||||
#include "td/telegram/Global.h"
|
||||
@ -83,64 +82,43 @@ class DownloadManagerImpl final : public DownloadManager {
|
||||
load_database_files();
|
||||
}
|
||||
|
||||
Status toggle_is_paused(FileId file_id, bool is_paused) final {
|
||||
TRY_STATUS(check_is_active());
|
||||
TRY_RESULT(file_info_ptr, get_file_info(file_id));
|
||||
void toggle_is_paused(FileId file_id, bool is_paused, Promise<Unit> promise) final {
|
||||
TRY_STATUS_PROMISE(promise, check_is_active());
|
||||
TRY_RESULT_PROMISE(promise, file_info_ptr, get_file_info(file_id));
|
||||
toggle_is_paused(*file_info_ptr, is_paused);
|
||||
return Status::OK();
|
||||
promise.set_value(Unit());
|
||||
}
|
||||
|
||||
Status toggle_all_is_paused(bool is_paused) final {
|
||||
TRY_STATUS(check_is_active());
|
||||
void toggle_all_is_paused(bool is_paused, Promise<Unit> promise) final {
|
||||
TRY_STATUS_PROMISE(promise, check_is_active());
|
||||
|
||||
vector<FileId> to_toggle;
|
||||
for (auto &it : files_) {
|
||||
toggle_is_paused(*it.second, is_paused);
|
||||
FileInfo &file_info = *it.second;
|
||||
if (!is_completed(file_info) && is_paused != file_info.is_paused) {
|
||||
to_toggle.push_back(file_info.file_id);
|
||||
}
|
||||
}
|
||||
for (auto file_id : to_toggle) {
|
||||
auto r_file_info_ptr = get_file_info(file_id);
|
||||
if (r_file_info_ptr.is_ok()) {
|
||||
toggle_is_paused(*r_file_info_ptr.ok(), is_paused);
|
||||
}
|
||||
}
|
||||
|
||||
return Status::OK();
|
||||
promise.set_value(Unit());
|
||||
}
|
||||
|
||||
Status remove_file(FileId file_id, FileSourceId file_source_id, bool delete_from_cache) final {
|
||||
LOG(INFO) << "Remove from downloads file " << file_id << " from " << file_source_id;
|
||||
TRY_STATUS(check_is_active());
|
||||
TRY_RESULT(file_info_ptr, get_file_info(file_id, file_source_id));
|
||||
auto &file_info = *file_info_ptr;
|
||||
auto download_id = file_info.download_id;
|
||||
if (!is_completed(file_info) && !file_info.is_paused) {
|
||||
callback_->pause_file(file_info.internal_file_id);
|
||||
}
|
||||
unregister_file_info(file_info);
|
||||
if (delete_from_cache) {
|
||||
callback_->delete_file(file_info.internal_file_id);
|
||||
}
|
||||
by_internal_file_id_.erase(file_info.internal_file_id);
|
||||
by_file_id_.erase(file_info.file_id);
|
||||
hints_.remove(download_id);
|
||||
completed_download_ids_.erase(download_id);
|
||||
|
||||
remove_from_database(file_info);
|
||||
files_.erase(download_id);
|
||||
if (is_search_inited_) {
|
||||
callback_->update_file_removed(file_id, file_counters_);
|
||||
}
|
||||
|
||||
update_counters();
|
||||
on_file_viewed(download_id);
|
||||
|
||||
return Status::OK();
|
||||
void remove_file(FileId file_id, FileSourceId file_source_id, bool delete_from_cache, Promise<Unit> promise) final {
|
||||
promise.set_result(remove_file_impl(file_id, file_source_id, delete_from_cache));
|
||||
}
|
||||
|
||||
Status remove_file_if_finished(FileId file_id) {
|
||||
TRY_STATUS(check_is_active());
|
||||
TRY_RESULT(file_info_ptr, get_file_info(file_id, {}));
|
||||
if (!is_completed(*file_info_ptr)) {
|
||||
return Status::Error("File is active");
|
||||
}
|
||||
return remove_file(file_id, {}, false);
|
||||
void remove_file_if_finished(FileId file_id) final {
|
||||
remove_file_if_finished_impl(file_id).ignore();
|
||||
}
|
||||
|
||||
Status remove_all_files(bool only_active, bool only_completed, bool delete_from_cache) final {
|
||||
TRY_STATUS(check_is_active());
|
||||
void remove_all_files(bool only_active, bool only_completed, bool delete_from_cache, Promise<Unit> promise) final {
|
||||
TRY_STATUS_PROMISE(promise, check_is_active());
|
||||
vector<FileId> to_remove;
|
||||
for (auto &it : files_) {
|
||||
FileInfo &file_info = *it.second;
|
||||
@ -153,15 +131,16 @@ class DownloadManagerImpl final : public DownloadManager {
|
||||
to_remove.push_back(file_info.file_id);
|
||||
}
|
||||
for (auto file_id : to_remove) {
|
||||
remove_file(file_id, {}, delete_from_cache);
|
||||
remove_file_impl(file_id, {}, delete_from_cache);
|
||||
}
|
||||
return Status::OK();
|
||||
promise.set_value(Unit());
|
||||
}
|
||||
|
||||
Status add_file(FileId file_id, FileSourceId file_source_id, string search_text, int8 priority) final {
|
||||
TRY_STATUS(check_is_active());
|
||||
void add_file(FileId file_id, FileSourceId file_source_id, string search_text, int8 priority,
|
||||
Promise<td_api::object_ptr<td_api::file>> promise) final {
|
||||
TRY_STATUS_PROMISE(promise, check_is_active());
|
||||
|
||||
remove_file(file_id, {}, false);
|
||||
remove_file_impl(file_id, {}, false);
|
||||
|
||||
auto download_id = next_download_id();
|
||||
|
||||
@ -176,19 +155,23 @@ class DownloadManagerImpl final : public DownloadManager {
|
||||
|
||||
add_file_info(std::move(file_info), search_text);
|
||||
|
||||
return Status::OK();
|
||||
promise.set_value(callback_->get_file_object(file_id));
|
||||
}
|
||||
|
||||
Status change_search_text(FileId file_id, FileSourceId file_source_id, string search_text) final {
|
||||
void change_search_text(FileId file_id, FileSourceId file_source_id, string search_text) final {
|
||||
if (!is_search_inited_) {
|
||||
return Status::OK();
|
||||
return;
|
||||
}
|
||||
|
||||
TRY_STATUS(check_is_active());
|
||||
TRY_RESULT(file_info_ptr, get_file_info(file_id, file_source_id));
|
||||
auto &file_info = *file_info_ptr;
|
||||
if (check_is_active().is_error()) {
|
||||
return;
|
||||
}
|
||||
auto r_file_info_ptr = get_file_info(file_id, file_source_id);
|
||||
if (r_file_info_ptr.is_error()) {
|
||||
return;
|
||||
}
|
||||
auto &file_info = *r_file_info_ptr.ok();
|
||||
hints_.add(file_info.download_id, search_text.empty() ? string(" ") : search_text);
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
void hints_synchronized(Result<Unit>) {
|
||||
@ -328,7 +311,7 @@ class DownloadManagerImpl final : public DownloadManager {
|
||||
return;
|
||||
}
|
||||
auto &file_info = *r_file_info_ptr.ok();
|
||||
remove_file(file_info.file_id, {}, false);
|
||||
remove_file_impl(file_info.file_id, {}, false);
|
||||
}
|
||||
|
||||
void update_file_viewed(FileId file_id, FileSourceId file_source_id) final {
|
||||
@ -376,6 +359,7 @@ class DownloadManagerImpl final : public DownloadManager {
|
||||
Counters sent_counters_;
|
||||
FileCounters file_counters_;
|
||||
bool is_inited_{false};
|
||||
bool is_database_being_loaded_{false};
|
||||
bool is_database_loaded_{false};
|
||||
bool is_search_inited_{false};
|
||||
int64 max_download_id_{0};
|
||||
@ -488,6 +472,8 @@ class DownloadManagerImpl final : public DownloadManager {
|
||||
return;
|
||||
}
|
||||
CHECK(is_inited_);
|
||||
CHECK(!is_database_being_loaded_);
|
||||
is_database_being_loaded_ = true;
|
||||
|
||||
LOG(INFO) << "Start Download Manager database loading";
|
||||
|
||||
@ -503,6 +489,7 @@ class DownloadManagerImpl final : public DownloadManager {
|
||||
}
|
||||
|
||||
is_database_loaded_ = true;
|
||||
is_database_being_loaded_ = false;
|
||||
update_counters();
|
||||
check_completed_downloads_size();
|
||||
|
||||
@ -512,13 +499,13 @@ class DownloadManagerImpl final : public DownloadManager {
|
||||
void prepare_hints() {
|
||||
for (auto &it : files_) {
|
||||
const auto &file_info = *it.second;
|
||||
send_closure(G()->file_reference_manager(), &FileReferenceManager::get_file_search_text, file_info.file_source_id,
|
||||
callback_->get_file_view(file_info.file_id).get_unique_file_id(),
|
||||
[actor_id = actor_id(this), promise = load_search_text_multipromise_.get_promise(),
|
||||
download_id = it.first](Result<string> r_search_text) mutable {
|
||||
send_closure(actor_id, &DownloadManagerImpl::add_download_to_hints, download_id,
|
||||
std::move(r_search_text), std::move(promise));
|
||||
});
|
||||
auto promise =
|
||||
PromiseCreator::lambda([actor_id = actor_id(this), promise = load_search_text_multipromise_.get_promise(),
|
||||
download_id = it.first](Result<string> r_search_text) mutable {
|
||||
send_closure(actor_id, &DownloadManagerImpl::add_download_to_hints, download_id, std::move(r_search_text),
|
||||
std::move(promise));
|
||||
});
|
||||
callback_->get_file_search_text(file_info.file_id, file_info.file_source_id, std::move(promise));
|
||||
}
|
||||
}
|
||||
|
||||
@ -530,7 +517,7 @@ class DownloadManagerImpl final : public DownloadManager {
|
||||
|
||||
if (r_search_text.is_error()) {
|
||||
if (!G()->close_flag()) {
|
||||
remove_file(it->second->file_id, {}, false);
|
||||
remove_file_impl(it->second->file_id, {}, false);
|
||||
}
|
||||
} else {
|
||||
auto search_text = r_search_text.move_as_ok();
|
||||
@ -567,11 +554,8 @@ class DownloadManagerImpl final : public DownloadManager {
|
||||
<< file_info->size << '/' << file_info->expected_size
|
||||
<< " with downloaded_size = " << file_info->downloaded_size
|
||||
<< " and is_paused = " << file_info->is_paused;
|
||||
auto res = files_.emplace(download_id, std::move(file_info));
|
||||
auto it = res.first;
|
||||
auto it = files_.emplace(download_id, std::move(file_info)).first;
|
||||
bool was_completed = is_completed(*it->second);
|
||||
LOG_CHECK(!it->second->is_registered)
|
||||
<< res.second << ' ' << download_id << ' ' << max_download_id_ << ' ' << it->second->need_save_to_database;
|
||||
register_file_info(*it->second); // must be called before start_file, which can call update_file_download_state
|
||||
if (is_completed(*it->second)) {
|
||||
bool is_inserted = completed_download_ids_.insert(it->second->download_id).second;
|
||||
@ -588,6 +572,45 @@ class DownloadManagerImpl final : public DownloadManager {
|
||||
}
|
||||
}
|
||||
|
||||
Status remove_file_impl(FileId file_id, FileSourceId file_source_id, bool delete_from_cache) {
|
||||
LOG(INFO) << "Remove from downloads file " << file_id << " from " << file_source_id;
|
||||
TRY_STATUS(check_is_active());
|
||||
TRY_RESULT(file_info_ptr, get_file_info(file_id, file_source_id));
|
||||
auto &file_info = *file_info_ptr;
|
||||
auto download_id = file_info.download_id;
|
||||
if (!is_completed(file_info) && !file_info.is_paused) {
|
||||
callback_->pause_file(file_info.internal_file_id);
|
||||
}
|
||||
unregister_file_info(file_info);
|
||||
if (delete_from_cache) {
|
||||
callback_->delete_file(file_info.internal_file_id);
|
||||
}
|
||||
by_internal_file_id_.erase(file_info.internal_file_id);
|
||||
by_file_id_.erase(file_info.file_id);
|
||||
hints_.remove(download_id);
|
||||
completed_download_ids_.erase(download_id);
|
||||
|
||||
remove_from_database(file_info);
|
||||
files_.erase(download_id);
|
||||
if (is_search_inited_) {
|
||||
callback_->update_file_removed(file_id, file_counters_);
|
||||
}
|
||||
|
||||
update_counters();
|
||||
on_file_viewed(download_id);
|
||||
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status remove_file_if_finished_impl(FileId file_id) {
|
||||
TRY_STATUS(check_is_active());
|
||||
TRY_RESULT(file_info_ptr, get_file_info(file_id, {}));
|
||||
if (!is_completed(*file_info_ptr)) {
|
||||
return Status::Error("File is active");
|
||||
}
|
||||
return remove_file_impl(file_id, {}, false);
|
||||
}
|
||||
|
||||
void timeout_expired() final {
|
||||
clear_counters();
|
||||
}
|
||||
@ -756,7 +779,7 @@ class DownloadManagerImpl final : public DownloadManager {
|
||||
while (completed_download_ids_.size() > MAX_COMPLETED_DOWNLOADS) {
|
||||
auto download_id = *completed_download_ids_.begin();
|
||||
auto file_info = get_file_info(download_id).move_as_ok();
|
||||
remove_file(file_info->file_id, FileSourceId(), false);
|
||||
remove_file_impl(file_info->file_id, FileSourceId(), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,8 +73,10 @@ class DownloadManager : public Actor {
|
||||
virtual void delete_file(FileId file_id) = 0;
|
||||
virtual FileId dup_file_id(FileId file_id) = 0;
|
||||
|
||||
virtual FileView get_file_view(FileId file_id) = 0;
|
||||
virtual void get_file_search_text(FileId file_id, FileSourceId file_source_id, Promise<string> &&promise) = 0;
|
||||
|
||||
virtual FileView get_sync_file_view(FileId file_id) = 0;
|
||||
virtual td_api::object_ptr<td_api::file> get_file_object(FileId file_id) = 0;
|
||||
virtual td_api::object_ptr<td_api::fileDownload> get_file_download_object(FileId file_id,
|
||||
FileSourceId file_source_id,
|
||||
int32 add_date, int32 complete_date,
|
||||
@ -86,20 +88,23 @@ class DownloadManager : public Actor {
|
||||
//
|
||||
// public interface for user
|
||||
//
|
||||
virtual void after_get_difference() = 0;
|
||||
virtual Status add_file(FileId file_id, FileSourceId file_source_id, string search_text, int8 priority) = 0;
|
||||
virtual Status change_search_text(FileId file_id, FileSourceId file_source_id, string search_text) = 0;
|
||||
virtual Status toggle_is_paused(FileId file_id, bool is_paused) = 0;
|
||||
virtual Status toggle_all_is_paused(bool is_paused) = 0;
|
||||
virtual void add_file(FileId file_id, FileSourceId file_source_id, string search_text, int8 priority,
|
||||
Promise<td_api::object_ptr<td_api::file>> promise) = 0;
|
||||
virtual void toggle_is_paused(FileId file_id, bool is_paused, Promise<Unit> promise) = 0;
|
||||
virtual void toggle_all_is_paused(bool is_paused, Promise<Unit> promise) = 0;
|
||||
virtual void search(string query, bool only_active, bool only_completed, string offset, int32 limit,
|
||||
Promise<td_api::object_ptr<td_api::foundFileDownloads>> promise) = 0;
|
||||
virtual Status remove_file(FileId file_id, FileSourceId file_source_id, bool delete_from_cache) = 0;
|
||||
virtual Status remove_file_if_finished(FileId file_id) = 0;
|
||||
virtual Status remove_all_files(bool only_active, bool only_completed, bool delete_from_cache) = 0;
|
||||
virtual void remove_file(FileId file_id, FileSourceId file_source_id, bool delete_from_cache,
|
||||
Promise<Unit> promise) = 0;
|
||||
virtual void remove_all_files(bool only_active, bool only_completed, bool delete_from_cache,
|
||||
Promise<Unit> promise) = 0;
|
||||
|
||||
//
|
||||
// private interface to handle all kinds of updates
|
||||
//
|
||||
virtual void after_get_difference() = 0;
|
||||
virtual void change_search_text(FileId file_id, FileSourceId file_source_id, string search_text) = 0;
|
||||
virtual void remove_file_if_finished(FileId file_id) = 0;
|
||||
virtual void update_file_download_state(FileId internal_file_id, int64 downloaded_size, int64 size,
|
||||
int64 expected_size, bool is_paused) = 0;
|
||||
virtual void update_file_deleted(FileId internal_file_id) = 0;
|
||||
|
@ -64,6 +64,12 @@ FileId DownloadManagerCallback::dup_file_id(FileId file_id) {
|
||||
return td_->file_manager_->dup_file_id(file_id);
|
||||
}
|
||||
|
||||
void DownloadManagerCallback::get_file_search_text(FileId file_id, FileSourceId file_source_id,
|
||||
Promise<string> &&promise) {
|
||||
send_closure(td_->file_reference_manager_actor_, &FileReferenceManager::get_file_search_text, file_source_id,
|
||||
get_file_view(file_id).get_unique_file_id(), std::move(promise));
|
||||
}
|
||||
|
||||
FileView DownloadManagerCallback::get_file_view(FileId file_id) {
|
||||
return td_->file_manager_->get_file_view(file_id);
|
||||
}
|
||||
@ -73,6 +79,10 @@ FileView DownloadManagerCallback::get_sync_file_view(FileId file_id) {
|
||||
return get_file_view(file_id);
|
||||
}
|
||||
|
||||
td_api::object_ptr<td_api::file> DownloadManagerCallback::get_file_object(FileId file_id) {
|
||||
return td_->file_manager_->get_file_object(file_id);
|
||||
}
|
||||
|
||||
td_api::object_ptr<td_api::fileDownload> DownloadManagerCallback::get_file_download_object(
|
||||
FileId file_id, FileSourceId file_source_id, int32 add_date, int32 complete_date, bool is_paused) {
|
||||
return td_api::make_object<td_api::fileDownload>(td_->file_manager_->get_file_view(file_id).get_main_file_id().get(),
|
||||
|
@ -45,18 +45,22 @@ class DownloadManagerCallback final : public DownloadManager::Callback {
|
||||
|
||||
FileId dup_file_id(FileId file_id) final;
|
||||
|
||||
FileView get_file_view(FileId file_id) final;
|
||||
void get_file_search_text(FileId file_id, FileSourceId file_source_id, Promise<string> &&promise) final;
|
||||
|
||||
FileView get_sync_file_view(FileId file_id) final;
|
||||
|
||||
td_api::object_ptr<td_api::file> get_file_object(FileId file_id) final;
|
||||
|
||||
td_api::object_ptr<td_api::fileDownload> get_file_download_object(FileId file_id, FileSourceId file_source_id,
|
||||
int32 add_date, int32 complete_date,
|
||||
bool is_paused);
|
||||
bool is_paused) final;
|
||||
|
||||
private:
|
||||
Td *td_;
|
||||
ActorShared<> parent_;
|
||||
|
||||
FileView get_file_view(FileId file_id);
|
||||
|
||||
static std::shared_ptr<FileManager::DownloadCallback> make_download_file_callback(
|
||||
Td *td, ActorShared<DownloadManager> download_manager);
|
||||
};
|
||||
|
@ -1057,7 +1057,7 @@ unique_ptr<LinkManager::InternalLink> LinkManager::parse_tg_link_query(Slice que
|
||||
nullptr, std::move(user_link), url_query.get_arg("attach").str(), url_query.get_arg("startattach"));
|
||||
}
|
||||
// resolve?phone=12345
|
||||
return user_link;
|
||||
return std::move(user_link);
|
||||
}
|
||||
} else if (path.size() == 1 && path[0] == "login") {
|
||||
// login?code=123456
|
||||
@ -1239,7 +1239,7 @@ unique_ptr<LinkManager::InternalLink> LinkManager::parse_t_me_link_query(Slice q
|
||||
nullptr, std::move(user_link), url_query.get_arg("attach").str(), url_query.get_arg("startattach"));
|
||||
}
|
||||
// /+<phone_number>
|
||||
return user_link;
|
||||
return std::move(user_link);
|
||||
} else {
|
||||
// /+<link>
|
||||
return td::make_unique<InternalLinkDialogInvite>(PSTRING() << "tg:join?invite="
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include "td/telegram/NotificationSettingsManager.h"
|
||||
#include "td/telegram/NotificationSound.h"
|
||||
#include "td/telegram/NotificationType.h"
|
||||
#include "td/telegram/PollId.h"
|
||||
#include "td/telegram/PublicDialogType.h"
|
||||
#include "td/telegram/ReplyMarkup.h"
|
||||
#include "td/telegram/ReplyMarkup.hpp"
|
||||
@ -5810,34 +5811,16 @@ MessagesManager::MessagesManager(Td *td, ActorShared<> parent)
|
||||
}
|
||||
|
||||
MessagesManager::~MessagesManager() {
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), ttl_nodes_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), ttl_heap_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), being_sent_messages_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), update_message_ids_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), update_scheduled_message_ids_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), message_id_to_dialog_id_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), last_clear_history_message_id_to_dialog_id_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), dialogs_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), postponed_chat_read_inbox_updates_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), found_public_dialogs_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), found_on_server_dialogs_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), found_common_dialogs_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), message_embedding_codes_[0]);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), message_embedding_codes_[1]);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), replied_by_media_timestamp_messages_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), notification_group_id_to_dialog_id_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), active_get_channel_differencies_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), get_channel_difference_to_log_event_id_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), channel_get_difference_retry_timeouts_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), is_channel_difference_finished_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), resolved_usernames_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), inaccessible_resolved_usernames_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), dialog_bot_command_message_ids_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), full_message_id_to_file_source_id_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), last_outgoing_forwarded_message_date_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), dialog_viewed_messages_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), dialog_online_member_counts_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), previous_repaired_read_inbox_max_message_id_);
|
||||
Scheduler::instance()->destroy_on_scheduler(
|
||||
G()->get_gc_scheduler_id(), ttl_nodes_, ttl_heap_, being_sent_messages_, update_message_ids_,
|
||||
update_scheduled_message_ids_, message_id_to_dialog_id_, last_clear_history_message_id_to_dialog_id_, dialogs_,
|
||||
postponed_chat_read_inbox_updates_, found_public_dialogs_, found_on_server_dialogs_, found_common_dialogs_,
|
||||
message_embedding_codes_[0], message_embedding_codes_[1], replied_by_media_timestamp_messages_,
|
||||
notification_group_id_to_dialog_id_, active_get_channel_differencies_, get_channel_difference_to_log_event_id_,
|
||||
channel_get_difference_retry_timeouts_, is_channel_difference_finished_, resolved_usernames_,
|
||||
inaccessible_resolved_usernames_, dialog_bot_command_message_ids_, full_message_id_to_file_source_id_,
|
||||
last_outgoing_forwarded_message_date_, dialog_viewed_messages_, dialog_online_member_counts_,
|
||||
previous_repaired_read_inbox_max_message_id_);
|
||||
}
|
||||
|
||||
void MessagesManager::on_channel_get_difference_timeout_callback(void *messages_manager_ptr, int64 dialog_id_int) {
|
||||
@ -20806,7 +20789,8 @@ Status MessagesManager::view_messages(DialogId dialog_id, MessageId top_thread_m
|
||||
for (auto file_id : get_message_file_ids(m)) {
|
||||
auto file_view = td_->file_manager_->get_file_view(file_id);
|
||||
CHECK(!file_view.empty());
|
||||
td_->download_manager_->update_file_viewed(file_view.get_main_file_id(), file_source_id);
|
||||
send_closure(td_->download_manager_actor_, &DownloadManager::update_file_viewed, file_view.get_main_file_id(),
|
||||
file_source_id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -22975,7 +22959,7 @@ void MessagesManager::remove_message_file_sources(DialogId dialog_id, const Mess
|
||||
for (auto file_id : file_ids) {
|
||||
auto file_view = td_->file_manager_->get_file_view(file_id);
|
||||
send_closure(td_->download_manager_actor_, &DownloadManager::remove_file, file_view.get_main_file_id(),
|
||||
file_source_id, false);
|
||||
file_source_id, false, Promise<Unit>());
|
||||
td_->file_manager_->remove_file_source(file_id, file_source_id);
|
||||
}
|
||||
}
|
||||
@ -23002,7 +22986,7 @@ void MessagesManager::change_message_files(DialogId dialog_id, const Message *m,
|
||||
if (file_source_id.is_valid()) {
|
||||
auto file_view = td_->file_manager_->get_file_view(file_id);
|
||||
send_closure(td_->download_manager_actor_, &DownloadManager::remove_file, file_view.get_main_file_id(),
|
||||
file_source_id, false);
|
||||
file_source_id, false, Promise<Unit>());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -28032,8 +28016,8 @@ class MessagesManager::ForwardMessagesLogEvent {
|
||||
DialogId from_dialog_id;
|
||||
vector<MessageId> message_ids;
|
||||
vector<Message *> messages_in;
|
||||
bool drop_author = false;
|
||||
bool drop_media_captions = false;
|
||||
bool drop_author;
|
||||
bool drop_media_captions;
|
||||
vector<unique_ptr<Message>> messages_out;
|
||||
|
||||
template <class StorerT>
|
||||
@ -28055,6 +28039,9 @@ class MessagesManager::ForwardMessagesLogEvent {
|
||||
PARSE_FLAG(drop_author);
|
||||
PARSE_FLAG(drop_media_captions);
|
||||
END_PARSE_FLAGS();
|
||||
} else {
|
||||
drop_author = false;
|
||||
drop_media_captions = false;
|
||||
}
|
||||
td::parse(to_dialog_id, parser);
|
||||
td::parse(from_dialog_id, parser);
|
||||
@ -28190,6 +28177,9 @@ unique_ptr<MessagesManager::MessageForwardInfo> MessagesManager::create_message_
|
||||
|
||||
void MessagesManager::fix_forwarded_message(Message *m, DialogId to_dialog_id, const Message *forwarded_message,
|
||||
int64 media_album_id, bool drop_author) const {
|
||||
if (m->content->get_type() == MessageContentType::Audio) {
|
||||
drop_author = true;
|
||||
}
|
||||
bool is_game = m->content->get_type() == MessageContentType::Game;
|
||||
if (!drop_author || is_game) {
|
||||
m->via_bot_user_id = forwarded_message->via_bot_user_id;
|
||||
@ -28346,9 +28336,20 @@ Result<MessagesManager::ForwardedMessages> MessagesManager::get_forwarded_messag
|
||||
continue;
|
||||
}
|
||||
|
||||
bool is_broken_server_copy = [&] {
|
||||
switch (forwarded_message->content->get_type()) {
|
||||
case MessageContentType::Poll:
|
||||
return get_message_content_poll_is_closed(td_, forwarded_message->content.get()) ||
|
||||
td_->auth_manager_->is_bot();
|
||||
case MessageContentType::Dice:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}();
|
||||
|
||||
bool need_copy = !message_id.is_server() || to_secret || copy_options[i].send_copy;
|
||||
bool is_local_copy = need_copy && !(message_id.is_server() && can_use_server_forward &&
|
||||
forwarded_message->content->get_type() != MessageContentType::Dice);
|
||||
bool is_local_copy = need_copy && !(message_id.is_server() && can_use_server_forward && !is_broken_server_copy);
|
||||
if (!(need_copy && td_->auth_manager_->is_bot()) && !can_save_message(from_dialog_id, forwarded_message)) {
|
||||
LOG(INFO) << "Forward of " << message_id << " is restricted";
|
||||
continue;
|
||||
@ -31044,8 +31045,29 @@ void MessagesManager::check_send_message_result(int64 random_id, DialogId dialog
|
||||
CHECK(source != nullptr);
|
||||
auto sent_messages = UpdatesManager::get_new_messages(updates_ptr);
|
||||
auto sent_messages_random_ids = UpdatesManager::get_sent_messages_random_ids(updates_ptr);
|
||||
|
||||
auto is_invalid_poll_message = [](const telegram_api::Message *message) {
|
||||
CHECK(message != nullptr);
|
||||
auto constructor_id = message->get_id();
|
||||
if (constructor_id == telegram_api::messageEmpty::ID) {
|
||||
return true;
|
||||
}
|
||||
if (constructor_id != telegram_api::message::ID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto media = static_cast<const telegram_api::message *>(message)->media_.get();
|
||||
if (media == nullptr || media->get_id() != telegram_api::messageMediaPoll::ID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto poll = static_cast<const telegram_api::messageMediaPoll *>(media)->poll_.get();
|
||||
return !PollId(poll->id_).is_valid();
|
||||
};
|
||||
|
||||
if (sent_messages.size() != 1u || sent_messages_random_ids.size() != 1u ||
|
||||
*sent_messages_random_ids.begin() != random_id || get_message_dialog_id(*sent_messages[0]) != dialog_id) {
|
||||
*sent_messages_random_ids.begin() != random_id || get_message_dialog_id(*sent_messages[0]) != dialog_id ||
|
||||
is_invalid_poll_message(sent_messages[0]->get())) {
|
||||
LOG(ERROR) << "Receive wrong result for sending message with random_id " << random_id << " from " << source
|
||||
<< " to " << dialog_id << ": " << oneline(to_string(*updates_ptr));
|
||||
Dialog *d = get_dialog(dialog_id);
|
||||
@ -40250,9 +40272,8 @@ void MessagesManager::add_message_file_to_downloads(FullMessageId full_message_i
|
||||
auto search_text = get_message_search_text(m);
|
||||
auto file_source_id = get_message_file_source_id(full_message_id, true);
|
||||
CHECK(file_source_id.is_valid());
|
||||
TRY_STATUS_PROMISE(promise, td_->download_manager_->add_file(file_id, file_source_id, std::move(search_text),
|
||||
static_cast<int8>(priority)));
|
||||
promise.set_value(td_->file_manager_->get_file_object(file_id));
|
||||
send_closure(td_->download_manager_actor_, &DownloadManager::add_file, file_id, file_source_id,
|
||||
std::move(search_text), static_cast<int8>(priority), std::move(promise));
|
||||
}
|
||||
|
||||
void MessagesManager::get_message_file_search_text(FullMessageId full_message_id, string unique_file_id,
|
||||
|
@ -267,11 +267,8 @@ void PollManager::tear_down() {
|
||||
}
|
||||
|
||||
PollManager::~PollManager() {
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), polls_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), server_poll_messages_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), other_poll_messages_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), poll_voters_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), loaded_from_database_polls_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), polls_, server_poll_messages_,
|
||||
other_poll_messages_, poll_voters_, loaded_from_database_polls_);
|
||||
}
|
||||
|
||||
void PollManager::on_update_poll_timeout_callback(void *poll_manager_ptr, int64 poll_id_int) {
|
||||
@ -1218,11 +1215,26 @@ void PollManager::do_stop_poll(PollId poll_id, FullMessageId full_message_id, un
|
||||
|
||||
bool is_inserted = being_closed_polls_.insert(poll_id).second;
|
||||
CHECK(is_inserted);
|
||||
auto new_promise = get_erase_log_event_promise(log_event_id, std::move(promise));
|
||||
auto new_promise = PromiseCreator::lambda(
|
||||
[actor_id = actor_id(this), poll_id, log_event_id, promise = std::move(promise)](Result<Unit> result) mutable {
|
||||
send_closure(actor_id, &PollManager::on_stop_poll_finished, poll_id, log_event_id, std::move(result),
|
||||
std::move(promise));
|
||||
});
|
||||
|
||||
td_->create_handler<StopPollQuery>(std::move(new_promise))->send(full_message_id, std::move(reply_markup), poll_id);
|
||||
}
|
||||
|
||||
void PollManager::on_stop_poll_finished(PollId poll_id, uint64 log_event_id, Result<Unit> &&result,
|
||||
Promise<Unit> &&promise) {
|
||||
being_closed_polls_.erase(poll_id);
|
||||
|
||||
if (log_event_id != 0 && !G()->close_flag()) {
|
||||
binlog_erase(G()->td_db()->get_binlog(), log_event_id);
|
||||
}
|
||||
|
||||
promise.set_result(std::move(result));
|
||||
}
|
||||
|
||||
void PollManager::stop_local_poll(PollId poll_id) {
|
||||
CHECK(is_local_poll_id(poll_id));
|
||||
auto poll = get_poll_editable(poll_id);
|
||||
|
@ -215,6 +215,8 @@ class PollManager final : public Actor {
|
||||
void do_stop_poll(PollId poll_id, FullMessageId full_message_id, unique_ptr<ReplyMarkup> &&reply_markup,
|
||||
uint64 log_event_id, Promise<Unit> &&promise);
|
||||
|
||||
void on_stop_poll_finished(PollId poll_id, uint64 log_event_id, Result<Unit> &&result, Promise<Unit> &&promise);
|
||||
|
||||
void forget_local_poll(PollId poll_id);
|
||||
|
||||
MultiTimeout update_poll_timeout_{"UpdatePollTimeout"};
|
||||
|
@ -221,13 +221,14 @@ static KeyboardButton get_keyboard_button(tl_object_ptr<telegram_api::KeyboardBu
|
||||
}
|
||||
case telegram_api::keyboardButtonSimpleWebView::ID: {
|
||||
auto keyboard_button = move_tl_object_as<telegram_api::keyboardButtonSimpleWebView>(keyboard_button_ptr);
|
||||
button.type = KeyboardButton::Type::WebView;
|
||||
button.text = std::move(keyboard_button->text_);
|
||||
auto r_url = LinkManager::check_link(keyboard_button->url_);
|
||||
if (r_url.is_error()) {
|
||||
LOG(ERROR) << "Keyboard Web App " << r_url.error().message();
|
||||
return {};
|
||||
break;
|
||||
}
|
||||
|
||||
button.type = KeyboardButton::Type::WebView;
|
||||
button.text = std::move(keyboard_button->text_);
|
||||
button.url = r_url.move_as_ok();
|
||||
break;
|
||||
}
|
||||
@ -245,13 +246,13 @@ static InlineKeyboardButton get_inline_keyboard_button(
|
||||
switch (keyboard_button_ptr->get_id()) {
|
||||
case telegram_api::keyboardButtonUrl::ID: {
|
||||
auto keyboard_button = move_tl_object_as<telegram_api::keyboardButtonUrl>(keyboard_button_ptr);
|
||||
button.type = InlineKeyboardButton::Type::Url;
|
||||
button.text = std::move(keyboard_button->text_);
|
||||
auto r_url = LinkManager::check_link(keyboard_button->url_);
|
||||
if (r_url.is_error()) {
|
||||
LOG(ERROR) << "Inline keyboard " << r_url.error().message();
|
||||
return {};
|
||||
break;
|
||||
}
|
||||
button.type = InlineKeyboardButton::Type::Url;
|
||||
button.text = std::move(keyboard_button->text_);
|
||||
button.data = r_url.move_as_ok();
|
||||
break;
|
||||
}
|
||||
@ -286,38 +287,39 @@ static InlineKeyboardButton get_inline_keyboard_button(
|
||||
}
|
||||
case telegram_api::keyboardButtonUrlAuth::ID: {
|
||||
auto keyboard_button = move_tl_object_as<telegram_api::keyboardButtonUrlAuth>(keyboard_button_ptr);
|
||||
auto r_url = LinkManager::check_link(keyboard_button->url_);
|
||||
if (r_url.is_error()) {
|
||||
LOG(ERROR) << "Inline keyboard Login " << r_url.error().message();
|
||||
break;
|
||||
}
|
||||
button.type = InlineKeyboardButton::Type::UrlAuth;
|
||||
button.id = keyboard_button->button_id_;
|
||||
button.text = std::move(keyboard_button->text_);
|
||||
button.forward_text = std::move(keyboard_button->fwd_text_);
|
||||
auto r_url = LinkManager::check_link(keyboard_button->url_);
|
||||
if (r_url.is_error()) {
|
||||
LOG(ERROR) << "Inline keyboard Login " << r_url.error().message();
|
||||
return {};
|
||||
}
|
||||
button.data = r_url.move_as_ok();
|
||||
break;
|
||||
}
|
||||
case telegram_api::keyboardButtonUserProfile::ID: {
|
||||
auto keyboard_button = move_tl_object_as<telegram_api::keyboardButtonUserProfile>(keyboard_button_ptr);
|
||||
auto user_id = UserId(keyboard_button->user_id_);
|
||||
if (!user_id.is_valid()) {
|
||||
LOG(ERROR) << "Receive " << user_id << " in inline keyboard";
|
||||
break;
|
||||
}
|
||||
button.type = InlineKeyboardButton::Type::User;
|
||||
button.text = std::move(keyboard_button->text_);
|
||||
button.user_id = UserId(keyboard_button->user_id_);
|
||||
if (!button.user_id.is_valid()) {
|
||||
LOG(ERROR) << "Receive " << button.user_id << " in inline keyboard";
|
||||
return {};
|
||||
}
|
||||
button.user_id = user_id;
|
||||
break;
|
||||
}
|
||||
case telegram_api::keyboardButtonWebView::ID: {
|
||||
auto keyboard_button = move_tl_object_as<telegram_api::keyboardButtonWebView>(keyboard_button_ptr);
|
||||
button.type = InlineKeyboardButton::Type::WebView;
|
||||
button.text = std::move(keyboard_button->text_);
|
||||
auto r_url = LinkManager::check_link(keyboard_button->url_);
|
||||
if (r_url.is_error()) {
|
||||
LOG(ERROR) << "Inline keyboard Web App " << r_url.error().message();
|
||||
return {};
|
||||
break;
|
||||
}
|
||||
button.type = InlineKeyboardButton::Type::WebView;
|
||||
button.text = std::move(keyboard_button->text_);
|
||||
button.data = r_url.move_as_ok();
|
||||
break;
|
||||
}
|
||||
|
@ -1305,18 +1305,10 @@ StickersManager::StickersManager(Td *td, ActorShared<> parent) : td_(td), parent
|
||||
}
|
||||
|
||||
StickersManager::~StickersManager() {
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), stickers_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), sticker_sets_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), short_name_to_sticker_set_id_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), attached_sticker_sets_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), found_stickers_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), found_sticker_sets_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), emoji_language_codes_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), emoji_language_code_versions_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), emoji_language_code_last_difference_times_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), reloaded_emoji_keywords_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), dice_messages_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), emoji_messages_);
|
||||
Scheduler::instance()->destroy_on_scheduler(
|
||||
G()->get_gc_scheduler_id(), stickers_, sticker_sets_, short_name_to_sticker_set_id_, attached_sticker_sets_,
|
||||
found_stickers_, found_sticker_sets_, emoji_language_codes_, emoji_language_code_versions_,
|
||||
emoji_language_code_last_difference_times_, reloaded_emoji_keywords_, dice_messages_, emoji_messages_);
|
||||
}
|
||||
|
||||
void StickersManager::start_up() {
|
||||
|
@ -4003,6 +4003,10 @@ void Td::init_file_manager() {
|
||||
explicit FileManagerContext(Td *td) : td_(td) {
|
||||
}
|
||||
|
||||
bool need_notify_on_new_files() final {
|
||||
return !td_->auth_manager_->is_bot();
|
||||
}
|
||||
|
||||
void on_new_file(int64 size, int64 real_size, int32 cnt) final {
|
||||
send_closure(G()->storage_manager(), &StorageManager::on_new_file, size, real_size, cnt);
|
||||
}
|
||||
@ -4894,6 +4898,7 @@ void Td::on_request(uint64 id, td_api::getStorageStatistics &request) {
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, td_api::getStorageStatisticsFast &request) {
|
||||
CHECK_IS_USER();
|
||||
CREATE_REQUEST_PROMISE();
|
||||
auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result<FileStatsFast> result) mutable {
|
||||
if (result.is_error()) {
|
||||
@ -6691,23 +6696,26 @@ void Td::on_request(uint64 id, const td_api::addFileToDownloads &request) {
|
||||
|
||||
void Td::on_request(uint64 id, const td_api::toggleDownloadIsPaused &request) {
|
||||
CREATE_OK_REQUEST_PROMISE();
|
||||
promise.set_result(download_manager_->toggle_is_paused(FileId(request.file_id_, 0), request.is_paused_));
|
||||
send_closure(download_manager_actor_, &DownloadManager::toggle_is_paused, FileId(request.file_id_, 0),
|
||||
request.is_paused_, std::move(promise));
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, const td_api::toggleAllDownloadsArePaused &request) {
|
||||
CREATE_OK_REQUEST_PROMISE();
|
||||
promise.set_result(download_manager_->toggle_all_is_paused(request.are_paused_));
|
||||
send_closure(download_manager_actor_, &DownloadManager::toggle_all_is_paused, request.are_paused_,
|
||||
std::move(promise));
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, const td_api::removeFileFromDownloads &request) {
|
||||
CREATE_OK_REQUEST_PROMISE();
|
||||
promise.set_result(download_manager_->remove_file(FileId(request.file_id_, 0), {}, request.delete_from_cache_));
|
||||
send_closure(download_manager_actor_, &DownloadManager::remove_file, FileId(request.file_id_, 0), FileSourceId(),
|
||||
request.delete_from_cache_, std::move(promise));
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, const td_api::removeAllFilesFromDownloads &request) {
|
||||
CREATE_OK_REQUEST_PROMISE();
|
||||
promise.set_result(
|
||||
download_manager_->remove_all_files(request.only_active_, request.only_completed_, request.delete_from_cache_));
|
||||
send_closure(download_manager_actor_, &DownloadManager::remove_all_files, request.only_active_,
|
||||
request.only_completed_, request.delete_from_cache_, std::move(promise));
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, td_api::searchFileDownloads &request) {
|
||||
|
@ -1617,7 +1617,7 @@ void UpdatesManager::after_get_difference() {
|
||||
}
|
||||
}
|
||||
|
||||
td_->download_manager_->after_get_difference();
|
||||
send_closure(td_->download_manager_actor_, &DownloadManager::after_get_difference);
|
||||
td_->inline_queries_manager_->after_get_difference();
|
||||
td_->messages_manager_->after_get_difference();
|
||||
send_closure_later(td_->notification_manager_actor_, &NotificationManager::after_get_difference);
|
||||
|
@ -101,9 +101,8 @@ VoiceNotesManager::VoiceNotesManager(Td *td, ActorShared<> parent) : td_(td), pa
|
||||
}
|
||||
|
||||
VoiceNotesManager::~VoiceNotesManager() {
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), voice_notes_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), voice_note_messages_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), message_voice_notes_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), voice_notes_, voice_note_messages_,
|
||||
message_voice_notes_);
|
||||
}
|
||||
|
||||
void VoiceNotesManager::tear_down() {
|
||||
|
@ -418,11 +418,8 @@ void WebPagesManager::tear_down() {
|
||||
}
|
||||
|
||||
WebPagesManager::~WebPagesManager() {
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), web_pages_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), web_page_messages_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), got_web_page_previews_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), url_to_web_page_id_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), url_to_file_source_id_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), web_pages_, web_page_messages_,
|
||||
got_web_page_previews_, url_to_web_page_id_, url_to_file_source_id_);
|
||||
}
|
||||
|
||||
WebPageId WebPagesManager::on_get_web_page(tl_object_ptr<telegram_api::WebPage> &&web_page_ptr,
|
||||
|
@ -841,14 +841,9 @@ void FileManager::init_actor() {
|
||||
}
|
||||
|
||||
FileManager::~FileManager() {
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), remote_location_info_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), file_hash_to_file_id_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), local_location_to_file_id_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), generate_location_to_file_id_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), pmc_id_to_file_node_id_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), file_id_info_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), empty_file_ids_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), file_nodes_);
|
||||
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), remote_location_info_, file_hash_to_file_id_,
|
||||
local_location_to_file_id_, generate_location_to_file_id_,
|
||||
pmc_id_to_file_node_id_, file_id_info_, empty_file_ids_, file_nodes_);
|
||||
}
|
||||
|
||||
string FileManager::fix_file_extension(Slice file_name, Slice file_type, Slice file_extension) {
|
||||
@ -2163,7 +2158,9 @@ void FileManager::delete_file(FileId file_id, Promise<Unit> promise, const char
|
||||
if (file_view.has_local_location()) {
|
||||
if (begins_with(file_view.local_location().path_, get_files_dir(file_view.get_type()))) {
|
||||
clear_from_pmc(node);
|
||||
context_->on_new_file(-file_view.size(), -file_view.get_allocated_local_size(), -1);
|
||||
if (context_->need_notify_on_new_files()) {
|
||||
context_->on_new_file(-file_view.size(), -file_view.get_allocated_local_size(), -1);
|
||||
}
|
||||
path = std::move(node->local_.full().path_);
|
||||
}
|
||||
} else {
|
||||
@ -3517,7 +3514,7 @@ void FileManager::on_download_ok(QueryId query_id, FullLocalFileLocation local,
|
||||
if (r_new_file_id.is_error()) {
|
||||
status = Status::Error(PSLICE() << "Can't register local file after download: " << r_new_file_id.error().message());
|
||||
} else {
|
||||
if (is_new) {
|
||||
if (is_new && context_->need_notify_on_new_files()) {
|
||||
context_->on_new_file(size, get_file_view(r_new_file_id.ok()).get_allocated_local_size(), 1);
|
||||
}
|
||||
auto r_file_id = merge(r_new_file_id.ok(), file_id);
|
||||
@ -3690,8 +3687,10 @@ void FileManager::on_generate_ok(QueryId query_id, FullLocalFileLocation local)
|
||||
CHECK(file_node);
|
||||
|
||||
FileView file_view(file_node);
|
||||
if (!file_view.has_generate_location() || !begins_with(file_view.generate_location().conversion_, "#file_id#")) {
|
||||
context_->on_new_file(file_view.size(), file_view.get_allocated_local_size(), 1);
|
||||
if (context_->need_notify_on_new_files()) {
|
||||
if (!file_view.has_generate_location() || !begins_with(file_view.generate_location().conversion_, "#file_id#")) {
|
||||
context_->on_new_file(file_view.size(), file_view.get_allocated_local_size(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
run_upload(file_node, {});
|
||||
|
@ -384,6 +384,8 @@ class FileManager final : public FileLoadManager::Callback {
|
||||
|
||||
class Context {
|
||||
public:
|
||||
virtual bool need_notify_on_new_files() = 0;
|
||||
|
||||
virtual void on_new_file(int64 size, int64 real_size, int32 cnt) = 0;
|
||||
|
||||
virtual void on_file_updated(FileId size) = 0;
|
||||
|
@ -105,6 +105,9 @@ class Scheduler {
|
||||
template <class T>
|
||||
void destroy_on_scheduler(int32 sched_id, T &value);
|
||||
|
||||
template <class... ArgsT>
|
||||
void destroy_on_scheduler(int32 sched_id, ArgsT &...values);
|
||||
|
||||
template <ActorSendType send_type, class EventT>
|
||||
void send_lambda(ActorRef actor_ref, EventT &&lambda);
|
||||
|
||||
|
@ -171,7 +171,7 @@ inline void Scheduler::send_to_scheduler(int32 sched_id, const ActorId<Actor> &a
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void Scheduler::destroy_on_scheduler(int32 sched_id, T &value) {
|
||||
void Scheduler::destroy_on_scheduler(int32 sched_id, T &value) {
|
||||
if (!value.empty()) {
|
||||
destroy_on_scheduler_impl(sched_id, PromiseCreator::lambda([value = std::move(value)](Unit) {
|
||||
// destroy value
|
||||
@ -179,6 +179,13 @@ inline void Scheduler::destroy_on_scheduler(int32 sched_id, T &value) {
|
||||
}
|
||||
}
|
||||
|
||||
template <class... ArgsT>
|
||||
void Scheduler::destroy_on_scheduler(int32 sched_id, ArgsT &...values) {
|
||||
destroy_on_scheduler_impl(sched_id, PromiseCreator::lambda([values = std::make_tuple(std::move(values)...)](Unit) {
|
||||
// destroy values
|
||||
}));
|
||||
}
|
||||
|
||||
inline void Scheduler::before_tail_send(const ActorId<> &actor_id) {
|
||||
// TODO
|
||||
}
|
||||
|
@ -253,7 +253,7 @@ class MainQueryActor final : public td::Actor {
|
||||
}
|
||||
|
||||
void wakeup() final {
|
||||
int cnt = 100000;
|
||||
int cnt = 10000;
|
||||
while (out_cnt_ < in_cnt_ + 100 && out_cnt_ < cnt) {
|
||||
if (td::Random::fast_bool()) {
|
||||
send_closure(rand_elem(actors_), &QueryActor::query, create_query());
|
||||
@ -294,7 +294,7 @@ class SimpleActor final : public td::Actor {
|
||||
}
|
||||
|
||||
void wakeup() final {
|
||||
if (q_ == 100000) {
|
||||
if (q_ == 10000) {
|
||||
td::Scheduler::instance()->finish();
|
||||
stop();
|
||||
return;
|
||||
|
@ -138,13 +138,13 @@ TEST(Actors, workers_big_query_nine_threads) {
|
||||
}
|
||||
|
||||
TEST(Actors, workers_small_query_one_thread) {
|
||||
test_workers(0, 10, 1000000, 1);
|
||||
test_workers(0, 10, 100000, 1);
|
||||
}
|
||||
|
||||
TEST(Actors, workers_small_query_two_threads) {
|
||||
test_workers(2, 10, 1000000, 1);
|
||||
test_workers(2, 10, 100000, 1);
|
||||
}
|
||||
|
||||
TEST(Actors, workers_small_query_nine_threads) {
|
||||
test_workers(9, 10, 1000000, 1);
|
||||
test_workers(9, 10, 10000, 1);
|
||||
}
|
||||
|
@ -469,7 +469,8 @@ class FlatHashTableChunks {
|
||||
struct ChunkIt {
|
||||
size_t chunk_i;
|
||||
size_t chunk_mask;
|
||||
size_t shift{};
|
||||
size_t shift;
|
||||
|
||||
size_t pos() const {
|
||||
return chunk_i;
|
||||
}
|
||||
@ -482,7 +483,7 @@ class FlatHashTableChunks {
|
||||
};
|
||||
|
||||
ChunkIt get_chunk_it(size_t chunk_i) {
|
||||
return {chunk_i, chunks_.size() - 1};
|
||||
return ChunkIt{chunk_i, chunks_.size() - 1, 0};
|
||||
}
|
||||
|
||||
HashInfo calc_hash(const KeyT &key) {
|
||||
|
@ -198,13 +198,8 @@ class FlatHashTable {
|
||||
};
|
||||
|
||||
FlatHashTable() = default;
|
||||
FlatHashTable(const FlatHashTable &other) {
|
||||
assign(other);
|
||||
}
|
||||
void operator=(const FlatHashTable &other) {
|
||||
clear();
|
||||
assign(other);
|
||||
}
|
||||
FlatHashTable(const FlatHashTable &other) = delete;
|
||||
FlatHashTable &operator=(const FlatHashTable &other) = delete;
|
||||
|
||||
FlatHashTable(std::initializer_list<NodeT> nodes) {
|
||||
if (nodes.size() == 0) {
|
||||
@ -249,9 +244,7 @@ class FlatHashTable {
|
||||
other.drop();
|
||||
}
|
||||
~FlatHashTable() {
|
||||
if (nodes_ != nullptr) {
|
||||
clear_nodes(nodes_);
|
||||
}
|
||||
clear_nodes(nodes_);
|
||||
}
|
||||
|
||||
void swap(FlatHashTable &other) noexcept {
|
||||
@ -433,30 +426,6 @@ class FlatHashTable {
|
||||
begin_bucket_ = 0;
|
||||
}
|
||||
|
||||
void assign(const FlatHashTable &other) {
|
||||
if (other.size() == 0) {
|
||||
return;
|
||||
}
|
||||
resize(other.bucket_count());
|
||||
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(*other_node);
|
||||
break;
|
||||
}
|
||||
next_bucket(bucket);
|
||||
}
|
||||
}
|
||||
used_node_count_ = other.used_node_count_;
|
||||
}
|
||||
|
||||
NodeT *begin_impl() {
|
||||
if (empty()) {
|
||||
return nullptr;
|
||||
|
@ -54,7 +54,7 @@ struct MapNode {
|
||||
DCHECK(empty());
|
||||
DCHECK(!other.empty());
|
||||
first = std::move(other.first);
|
||||
other.first = KeyT{};
|
||||
other.first = KeyT();
|
||||
new (&second) ValueT(std::move(other.second));
|
||||
other.second.~ValueT();
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ struct SetNode {
|
||||
using public_type = const KeyT;
|
||||
using second_type = KeyT; // TODO: remove second_type?
|
||||
|
||||
KeyT first{};
|
||||
KeyT first;
|
||||
|
||||
const KeyT &key() const {
|
||||
return first;
|
||||
@ -30,7 +30,8 @@ struct SetNode {
|
||||
return first;
|
||||
}
|
||||
|
||||
SetNode() = default;
|
||||
SetNode(): first() {
|
||||
}
|
||||
explicit SetNode(KeyT key) : first(std::move(key)) {
|
||||
}
|
||||
SetNode(const SetNode &other) = delete;
|
||||
@ -42,7 +43,7 @@ struct SetNode {
|
||||
DCHECK(empty());
|
||||
DCHECK(!other.empty());
|
||||
first = std::move(other.first);
|
||||
other.first = KeyT{};
|
||||
other.first = KeyT();
|
||||
}
|
||||
~SetNode() = default;
|
||||
|
||||
@ -71,7 +72,7 @@ struct SetNode<KeyT, typename std::enable_if_t<(sizeof(KeyT) > 28 * sizeof(void
|
||||
struct Impl {
|
||||
using second_type = KeyT;
|
||||
|
||||
KeyT first{};
|
||||
KeyT first;
|
||||
|
||||
template <class InputKeyT>
|
||||
explicit Impl(InputKeyT &&key) : first(std::forward<InputKeyT>(key)) {
|
||||
@ -99,7 +100,7 @@ struct SetNode<KeyT, typename std::enable_if_t<(sizeof(KeyT) > 28 * sizeof(void
|
||||
return impl_->first;
|
||||
}
|
||||
|
||||
SetNode() {
|
||||
SetNode(): impl_() {
|
||||
}
|
||||
explicit SetNode(KeyT key) : impl_(td::make_unique<Impl>(std::move(key))) {
|
||||
}
|
||||
|
@ -124,7 +124,6 @@ TEST(FlatHashMap, basic) {
|
||||
ASSERT_EQ(2, kv.second);
|
||||
}
|
||||
map.erase(map.find(1));
|
||||
auto map_copy = map;
|
||||
}
|
||||
|
||||
td::FlatHashMap<int, std::array<td::unique_ptr<td::string>, 10>> x;
|
||||
@ -159,9 +158,6 @@ TEST(FlatHashMap, basic) {
|
||||
}
|
||||
ASSERT_EQ(data, extract_kv(kv));
|
||||
|
||||
KV copied_kv(kv);
|
||||
ASSERT_EQ(data, extract_kv(copied_kv));
|
||||
|
||||
KV moved_kv(std::move(kv));
|
||||
ASSERT_EQ(data, extract_kv(moved_kv));
|
||||
ASSERT_EQ(Data{}, extract_kv(kv));
|
||||
@ -169,10 +165,6 @@ TEST(FlatHashMap, basic) {
|
||||
kv = std::move(moved_kv);
|
||||
ASSERT_EQ(data, extract_kv(kv));
|
||||
|
||||
KV assign_copied_kv;
|
||||
assign_copied_kv = kv;
|
||||
ASSERT_EQ(data, extract_kv(assign_copied_kv));
|
||||
|
||||
KV assign_moved_kv;
|
||||
assign_moved_kv = std::move(kv);
|
||||
ASSERT_EQ(data, extract_kv(assign_moved_kv));
|
||||
|
@ -377,7 +377,7 @@ TEST(DB, key_value) {
|
||||
values.push_back(td::rand_string('a', 'b', td::Random::fast(1, 10)));
|
||||
}
|
||||
|
||||
int queries_n = 3000;
|
||||
int queries_n = 1000;
|
||||
td::vector<DbQuery> queries(queries_n);
|
||||
for (auto &q : queries) {
|
||||
int op = td::Random::fast(0, 2);
|
||||
@ -427,7 +427,7 @@ TEST(DB, key_value) {
|
||||
ASSERT_EQ(a.value, c.value);
|
||||
ASSERT_EQ(a.value, d.value);
|
||||
ASSERT_EQ(a.value, e.value);
|
||||
if (cnt++ % 500 == 0) {
|
||||
if (cnt++ % 200 == 0) {
|
||||
new_kv.impl().init(new_kv_name.str()).ensure();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user