From d4882f7c070b9ca522eaa2a26c0abcd502947b3c Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 18 Jan 2019 23:12:09 +0300 Subject: [PATCH] Add change_files_source method. GitOrigin-RevId: 25078e0ca82d34489727823bfcfa781424f48913 --- td/telegram/FileReferenceManager.cpp | 22 ++++++++++-------- td/telegram/FileReferenceManager.h | 4 ++-- td/telegram/files/FileManager.cpp | 34 ++++++++++++++++++++++++---- td/telegram/files/FileManager.h | 6 +++++ 4 files changed, 50 insertions(+), 16 deletions(-) diff --git a/td/telegram/FileReferenceManager.cpp b/td/telegram/FileReferenceManager.cpp index b572a278..7158868a 100644 --- a/td/telegram/FileReferenceManager.cpp +++ b/td/telegram/FileReferenceManager.cpp @@ -87,16 +87,16 @@ FileSourceId FileReferenceManager::create_saved_animations_file_source() { } void FileReferenceManager::add_file_source(NodeId node_id, FileSourceId file_source_id) { - VLOG(file_references) << "add_file_source: " << node_id << " " << file_source_id; + VLOG(file_references) << "Add file source " << file_source_id << " for file " << node_id; nodes_[node_id].file_source_ids.add(file_source_id); } void FileReferenceManager::remove_file_source(NodeId node_id, FileSourceId file_source_id) { - VLOG(file_references) << "remove_file_source: " << node_id << " " << file_source_id; + VLOG(file_references) << "Remove file source " << file_source_id << " from file " << node_id; nodes_[node_id].file_source_ids.remove(file_source_id); } -void merge(std::vector> &a, std::vector> &b) { +static void merge(std::vector> &a, std::vector> &b) { if (a.size() < b.size()) { std::swap(a, b); } @@ -106,7 +106,7 @@ void merge(std::vector> &a, std::vector> &b) { } void FileReferenceManager::merge(NodeId to_node_id, NodeId from_node_id) { - VLOG(file_references) << "merge: " << to_node_id << " " << from_node_id; + VLOG(file_references) << "Merge sources of files " << to_node_id << " and " << from_node_id; auto &to = nodes_[to_node_id]; auto &from = nodes_[from_node_id]; CHECK(!to.query || to.query->proxy.empty()); @@ -128,7 +128,7 @@ void FileReferenceManager::merge(NodeId to_node_id, NodeId from_node_id) { } void FileReferenceManager::run_node(NodeId node_id) { - VLOG(file_references) << "run_node: " << node_id; + VLOG(file_references) << "Run file references repair for file " << node_id; Node &node = nodes_[node_id]; if (!node.query) { return; @@ -152,7 +152,8 @@ void FileReferenceManager::run_node(NodeId node_id) { } void FileReferenceManager::send_query(Destination dest, FileSourceId file_source_id) { - VLOG(file_references) << "send_query " << dest.node_id << " " << dest.generation << " " << file_source_id; + VLOG(file_references) << "Send file references repair query for file " << dest.node_id << " with generation " + << dest.generation << " from source " << file_source_id; auto &node = nodes_[dest.node_id]; node.query->active_queries++; @@ -219,8 +220,9 @@ void FileReferenceManager::send_query(Destination dest, FileSourceId file_source FileReferenceManager::Destination FileReferenceManager::on_query_result(Destination dest, FileSourceId file_source_id, Status status, int32 sub) { - VLOG(file_references) << "on_query_result " << dest.node_id << " " << dest.generation << " " << file_source_id << " " - << status << " " << sub; + VLOG(file_references) << "Receive result of file references repair query for file " << dest.node_id + << " with generation " << dest.generation << " from source " << file_source_id << ": " << status + << " " << sub; auto &node = nodes_[dest.node_id]; auto query = node.query.get(); @@ -257,8 +259,8 @@ FileReferenceManager::Destination FileReferenceManager::on_query_result(Destinat return dest; } -void FileReferenceManager::update_file_reference(NodeId node_id, Promise<> promise) { - VLOG(file_references) << "update_file_reference " << node_id; +void FileReferenceManager::repair_file_reference(NodeId node_id, Promise<> promise) { + VLOG(file_references) << "Repair file reference for file " << node_id; auto &node = nodes_[node_id]; if (!node.query) { node.query = make_unique(); diff --git a/td/telegram/FileReferenceManager.h b/td/telegram/FileReferenceManager.h index 72a08645..fdb01470 100644 --- a/td/telegram/FileReferenceManager.h +++ b/td/telegram/FileReferenceManager.h @@ -35,9 +35,9 @@ class FileReferenceManager : public Actor { FileSourceId create_saved_animations_file_source(); using NodeId = FileId; - void update_file_reference(NodeId node_id, Promise<> promise); + void repair_file_reference(NodeId node_id, Promise<> promise); void add_file_source(NodeId node_id, FileSourceId file_source_id); - void remove_file_source(NodeId file_id, FileSourceId file_source_id); + void remove_file_source(NodeId node_id, FileSourceId file_source_id); void merge(NodeId to_node_id, NodeId from_node_id); private: diff --git a/td/telegram/files/FileManager.cpp b/td/telegram/files/FileManager.cpp index cf0d92a5..5bbe243a 100644 --- a/td/telegram/files/FileManager.cpp +++ b/td/telegram/files/FileManager.cpp @@ -1345,7 +1345,6 @@ Result FileManager::merge(FileId x_file_id, FileId y_file_id, bool no_sy } void FileManager::add_file_source(FileId file_id, FileSourceId file_source_id) { - LOG(ERROR) << "Add file source " << file_id << " " << file_source_id; auto node = get_file_node(file_id); if (!node) { return; @@ -1356,7 +1355,6 @@ void FileManager::add_file_source(FileId file_id, FileSourceId file_source_id) { } void FileManager::remove_file_source(FileId file_id, FileSourceId file_source_id) { - LOG(ERROR) << "Remove file source " << file_id << " " << file_source_id; auto node = get_file_node(file_id); if (!node) { return; @@ -1365,6 +1363,34 @@ void FileManager::remove_file_source(FileId file_id, FileSourceId file_source_id file_source_id); } +void FileManager::change_files_source(FileSourceId file_source_id, const vector &old_file_ids, + const vector &new_file_ids) { + auto old_main_file_ids = get_main_file_ids(old_file_ids); + auto new_main_file_ids = get_main_file_ids(new_file_ids); + for (auto file_id : old_main_file_ids) { + auto it = new_main_file_ids.find(file_id); + if (it == new_main_file_ids.end()) { + send_closure(G()->file_reference_manager(), &FileReferenceManager::remove_file_source, file_id, file_source_id); + } else { + new_main_file_ids.erase(it); + } + } + for (auto file_id : new_main_file_ids) { + send_closure(G()->file_reference_manager(), &FileReferenceManager::add_file_source, file_id, file_source_id); + } +} + +std::unordered_set FileManager::get_main_file_ids(const vector &file_ids) { + std::unordered_set result; + for (auto file_id : file_ids) { + auto node = get_file_node(file_id); + if (node) { + result.insert(node->main_file_id_); + } + } + return result; +} + void FileManager::try_flush_node_full(FileNodePtr node, bool new_remote, bool new_local, bool new_generate, FileDbId other_pmc_id) { if (node->need_pmc_flush()) { @@ -1762,7 +1788,7 @@ void FileManager::run_download(FileNodePtr node) { } node->download_was_update_file_reference_ = true; - send_closure(G()->file_reference_manager(), &FileReferenceManager::update_file_reference, file_id, + send_closure(G()->file_reference_manager(), &FileReferenceManager::repair_file_reference, file_id, PromiseCreator::lambda([id, actor_id = actor_id(this), file_id](Result res) { Status error; if (res.is_ok()) { @@ -2044,7 +2070,7 @@ void FileManager::run_upload(FileNodePtr node, std::vector bad_parts) { node->upload_id_ = id; node->upload_was_update_file_reference_ = true; - send_closure(G()->file_reference_manager(), &FileReferenceManager::update_file_reference, file_id, + send_closure(G()->file_reference_manager(), &FileReferenceManager::repair_file_reference, file_id, PromiseCreator::lambda([id, actor_id = actor_id(this)](Result res) { send_closure(actor_id, &FileManager::on_error, id, Status::Error("FILE_UPLOAD_RESTART_WITH_FILE_REFERENCE")); diff --git a/td/telegram/files/FileManager.h b/td/telegram/files/FileManager.h index 477c4b2a..6963167b 100644 --- a/td/telegram/files/FileManager.h +++ b/td/telegram/files/FileManager.h @@ -33,6 +33,7 @@ #include #include #include +#include #include namespace td { @@ -352,6 +353,9 @@ class FileManager : public FileLoadManager::Callback { void remove_file_source(FileId file_id, FileSourceId file_source_id); + void change_files_source(FileSourceId file_source_id, const vector &old_file_ids, + const vector &new_file_ids); + bool set_encryption_key(FileId file_id, FileEncryptionKey key); bool set_content(FileId file_id, BufferSlice bytes); @@ -535,6 +539,8 @@ class FileManager : public FileLoadManager::Callback { FullRemoteFileLocation *get_remote(int32 key); + std::unordered_set get_main_file_ids(const vector &file_ids); + void hangup() override; void tear_down() override;