Fixed FileManager iterators

This commit is contained in:
Andrea Cavalli 2020-08-03 13:29:20 +02:00
parent d890456b81
commit 159ec55ecf
2 changed files with 133 additions and 77 deletions

View File

@ -803,8 +803,6 @@ FileManager::FileManager(unique_ptr<Context> context) : context_(std::move(conte
} }
parent_ = context_->create_reference(); parent_ = context_->create_reference();
next_file_id();
next_file_node_id();
std::unordered_set<string> dir_paths; std::unordered_set<string> dir_paths;
for (int32 i = 0; i < MAX_FILE_TYPE; i++) { for (int32 i = 0; i < MAX_FILE_TYPE; i++) {
@ -3836,7 +3834,7 @@ void FileManager::memory_cleanup() {
LOG(ERROR) << "Initial registered ids: " << file_id_info_.size() << " registered nodes: " << file_nodes_.size(); LOG(ERROR) << "Initial registered ids: " << file_id_info_.size() << " registered nodes: " << file_nodes_.size();
/* DESTROY OLD file_id_info_ */ /* DESTROY OLD file_id_info_ */
{ if (true) {
std::lock_guard<std::shared_timed_mutex> writerLock(memory_cleanup_mutex); std::lock_guard<std::shared_timed_mutex> writerLock(memory_cleanup_mutex);
auto it = file_id_info_.begin(); auto it = file_id_info_.begin();
auto time = std::time(nullptr); auto time = std::time(nullptr);
@ -3844,52 +3842,62 @@ void FileManager::memory_cleanup() {
while (it != file_id_info_.end()) { while (it != file_id_info_.end()) {
if (it->second.node_id_ != 0) { if (it->second.node_id_ != 0) {
auto &node = file_nodes_[it->second.node_id_]; auto find_node = file_nodes_.find(it->second.node_id_);
if (find_node != file_nodes_.end()) {
auto &node = find_node->second;
if (time - node->main_file_id_.get_time() > FILE_TTL) { if (time - node->main_file_id_.get_time() > FILE_TTL) {
auto can_reset = node->download_priority_ == 0; auto can_reset = node->download_priority_ == 0;
can_reset &= node->generate_download_priority_ == 0; can_reset &= node->generate_download_priority_ == 0;
can_reset &= node->download_id_ == 0; can_reset &= node->download_id_ == 0;
if (can_reset) { if (can_reset) {
auto file_ids_it = node->file_ids_.begin(); auto file_ids_it = node->file_ids_.begin();
while (file_ids_it != node->file_ids_.end() && can_reset) { while (file_ids_it != node->file_ids_.end() && can_reset) {
auto &file = file_id_info_[file_ids_it->fast_get()]; auto find_file = file_id_info_.find(file_ids_it->fast_get());
can_reset &= file.download_priority_ == 0; if (find_file != file_id_info_.end()) {
can_reset &= time - file_ids_it->get_time() > FILE_TTL; auto &file = find_file->second;
++file_ids_it; can_reset &= file.download_priority_ == 0;
} can_reset &= time - file_ids_it->get_time() > FILE_TTL;
} }
file_ids_it++;
if (can_reset) { }
node->main_file_id_.reset_time();
for (auto &file_id : node->file_ids_) {
file_id.reset_time();
/* DESTROY ASSOCIATED QUERIES */
destroy_query(file_id.fast_get());
/* DESTROY ASSOCIATED LATE */
file_to_be_deleted.push_back(file_id.fast_get());
} }
/* DESTROY MAIN QUERY */ if (can_reset) {
destroy_query(it->first); node->main_file_id_.reset_time();
/* DESTROY MAIN NODE */ for (auto &file_id : node->file_ids_) {
file_nodes_.erase(it->first); file_id.reset_time();
/* DESTROY MAIN FILE LATE */ /* DESTROY ASSOCIATED QUERIES */
file_to_be_deleted.push_back(it->first); destroy_query(file_id.fast_get());
/* DESTROY ASSOCIATED LATE */
file_to_be_deleted.push_back(file_id.fast_get());
}
/* DESTROY MAIN QUERY */
destroy_query(it->first);
/* DESTROY MAIN NODE */
file_nodes_.erase(it->first);
/* DESTROY MAIN FILE LATE */
file_to_be_deleted.push_back(it->first);
}
} }
} else {
/* The file has a nonexistent node associated */
file_to_be_deleted.push_back(it->first);
} }
} else { } else {
file_to_be_deleted.push_back(it->first); // todo: When the program starts there is a file that points to the node 0. It shouldn't happen but it happens, so don't delete it, maybe that file is used by tdlib for some reason.
// file_to_be_deleted.push_back(it->first);
} }
++it; it++;
} }
for (auto file_id : file_to_be_deleted) { for (auto file_id : file_to_be_deleted) {
@ -3899,34 +3907,42 @@ void FileManager::memory_cleanup() {
} }
/* DESTROY INVALID FILES */ /* DESTROY INVALID FILES */
{ if (true) {
auto it = file_id_info_.begin(); auto it = file_id_info_.begin();
while (it != file_id_info_.end()) { while (it != file_id_info_.end()) {
auto is_invalid = false;
if (it->second.node_id_ != 0) { if (it->second.node_id_ != 0) {
auto find_file_node = file_nodes_.find(it->second.node_id_); auto find_file_node = file_nodes_.find(it->second.node_id_);
if (find_file_node == file_nodes_.end() || find_file_node->second->empty) { if (find_file_node == file_nodes_.end() || find_file_node->second->empty) {
is_invalid = true;
destroy_query(it->first); destroy_query(it->first);
context_->destroy_file_source({it->first, 0}); context_->destroy_file_source({it->first, 0});
file_nodes_.erase(it->second.node_id_); file_nodes_.erase(it->second.node_id_);
file_id_info_.erase(it++);
} else {
++it;
} }
} else { } else {
++it; is_invalid = true;
}
if (is_invalid) {
it = file_id_info_.erase(it);
} else {
it++;
} }
} }
} }
/* DESTROY INVALID file_nodes_ */ /* DESTROY INVALID file_nodes_ */
{ if (true) {
auto it = file_nodes_.begin(); auto it = file_nodes_.begin();
while (it != file_nodes_.end()) { while (it != file_nodes_.end()) {
auto is_invalid = false;
if (it->second == nullptr || it->second->empty) { if (it->second == nullptr || it->second->empty) {
file_nodes_.erase(it++); is_invalid = true;
} else { } else {
if (it->second->main_file_id_.empty()) { if (it->second->main_file_id_.empty()) {
file_nodes_.erase(it++); is_invalid = true;
} else { } else {
if (file_id_info_[it->second->main_file_id_.get()].node_id_ == 0) { if (file_id_info_[it->second->main_file_id_.get()].node_id_ == 0) {
for (auto &file_id : it->second->file_ids_) { for (auto &file_id : it->second->file_ids_) {
@ -3934,107 +3950,147 @@ void FileManager::memory_cleanup() {
file_id_info_.erase(file_id.get()); file_id_info_.erase(file_id.get());
} }
file_id_info_.erase(it->second->main_file_id_.get()); file_id_info_.erase(it->second->main_file_id_.get());
file_nodes_.erase(it++); is_invalid = true;
} else {
++it;
} }
} }
} }
if (is_invalid) {
it = file_nodes_.erase(it);
} else {
it++;
}
} }
} }
/* DESTROY INVALID file_hash_to_file_id_ */ /* DESTROY INVALID file_hash_to_file_id_ */
{ if (true) {
auto it = file_hash_to_file_id_.begin(); auto it = file_hash_to_file_id_.begin();
while (it != file_hash_to_file_id_.end()) { while (it != file_hash_to_file_id_.end()) {
auto is_invalid = false;
auto find_file = file_id_info_.find(it->second.fast_get()); auto find_file = file_id_info_.find(it->second.fast_get());
if (find_file != file_id_info_.end()) { if (find_file != file_id_info_.end()) {
auto &file = find_file->second; auto &file = find_file->second;
auto find_file_node = file_nodes_.find(file.node_id_); auto find_file_node = file_nodes_.find(file.node_id_);
if (find_file_node == file_nodes_.end() || find_file_node->second->empty) { if (find_file_node == file_nodes_.end() || find_file_node->second->empty) {
file_hash_to_file_id_.erase(it++); is_invalid = true;
file_nodes_.erase(file.node_id_); file_nodes_.erase(file.node_id_);
} else {
++it;
} }
} else { } else {
++it; is_invalid = true;
}
if (is_invalid) {
it = file_hash_to_file_id_.erase(it);
} else {
it++;
} }
} }
} }
/* DESTROY INVALID local_location_to_file_id_ */ /* DESTROY INVALID local_location_to_file_id_ */
{ if (true) {
auto it = local_location_to_file_id_.begin(); auto it = local_location_to_file_id_.begin();
while (it != local_location_to_file_id_.end()) { while (it != local_location_to_file_id_.end()) {
auto is_invalid = false;
auto find_file = file_id_info_.find(it->second.fast_get()); auto find_file = file_id_info_.find(it->second.fast_get());
if (find_file != file_id_info_.end()) { if (find_file != file_id_info_.end()) {
auto &file = find_file->second; auto &file = find_file->second;
auto find_file_node = file_nodes_.find(file.node_id_); auto find_file_node = file_nodes_.find(file.node_id_);
if (find_file_node == file_nodes_.end() || find_file_node->second->empty) { if (find_file_node == file_nodes_.end() || find_file_node->second->empty) {
it = local_location_to_file_id_.erase(it++); is_invalid = true;
file_nodes_.erase(file.node_id_); file_nodes_.erase(file.node_id_);
} else {
++it;
} }
} else { } else {
++it; is_invalid = true;
}
if (is_invalid) {
it = local_location_to_file_id_.erase(it);
} else {
it++;
} }
} }
} }
/* DESTROY INVALID generate_location_to_file_id_ */ /* DESTROY INVALID generate_location_to_file_id_ */
{ if (true) {
auto it = generate_location_to_file_id_.begin(); auto it = generate_location_to_file_id_.begin();
while (it != generate_location_to_file_id_.end()) { while (it != generate_location_to_file_id_.end()) {
auto is_invalid = false;
auto find_file = file_id_info_.find(it->second.fast_get()); auto find_file = file_id_info_.find(it->second.fast_get());
if (find_file != file_id_info_.end()) { if (find_file != file_id_info_.end()) {
auto &file = find_file->second; auto &file = find_file->second;
auto find_file_node = file_nodes_.find(file.node_id_); auto find_file_node = file_nodes_.find(file.node_id_);
if (find_file_node == file_nodes_.end() || find_file_node->second->empty) { if (find_file_node == file_nodes_.end() || find_file_node->second->empty) {
it = generate_location_to_file_id_.erase(it++); is_invalid = true;
file_nodes_.erase(file.node_id_); file_nodes_.erase(file.node_id_);
} else {
++it;
} }
} else { } else {
++it; is_invalid = true;
}
if (is_invalid) {
it = generate_location_to_file_id_.erase(it);
} else {
it++;
} }
} }
} }
/* DESTROY INVALID remote_location_info_ */ /* DESTROY INVALID remote_location_info_ */
{ if (true) {
auto map = remote_location_info_.get_map(); auto map = remote_location_info_.get_map();
auto it = map.begin(); auto it = map.begin();
while (it != map.end()) { while (it != map.end()) {
auto is_invalid = false;
auto find_file = file_id_info_.find(it->first.file_id_.fast_get()); auto find_file = file_id_info_.find(it->first.file_id_.fast_get());
if (find_file != file_id_info_.end()) { if (find_file != file_id_info_.end()) {
auto &file = find_file->second; auto &file = find_file->second;
auto find_file_node = file_nodes_.find(file.node_id_); auto find_file_node = file_nodes_.find(file.node_id_);
if (find_file_node == file_nodes_.end() || find_file_node->second->empty) { if (find_file_node == file_nodes_.end() || find_file_node->second->empty) {
remote_location_info_.erase(it->second); is_invalid = true;
map.erase(it++);
file_nodes_.erase(file.node_id_); file_nodes_.erase(file.node_id_);
} else {
++it;
} }
} else { } else {
++it; is_invalid = true;
}
if (is_invalid) {
remote_location_info_.erase(it->second);
// Todo: check if if the map must be emptied, or if it's ok to just add the emptied id with Enumerator erase
// it = map.erase(it);
it++;
} else {
it++;
} }
} }
} }
/* DESTROY NULL file_id_info_ */ /* DESTROY NULL file_id_info_ */
{ if (true) {
auto it = file_id_info_.begin(); auto it = file_id_info_.begin();
while (it != file_id_info_.end()) { while (it != file_id_info_.end()) {
auto find_file_node = file_nodes_.find(it->second.node_id_); auto is_invalid = false;
if (find_file_node == file_nodes_.end() || find_file_node->second->empty) {
context_->destroy_file_source({it->first, 0}); if (it->second.node_id_ != 0) {
file_id_info_.erase(it++); auto find_file_node = file_nodes_.find(it->second.node_id_);
if (find_file_node == file_nodes_.end() || find_file_node->second->empty) {
is_invalid = true;
context_->destroy_file_source({it->first, 0});
}
} else { } else {
++it; is_invalid = true;
}
if (is_invalid) {
it = file_id_info_.erase(it);
} else {
it++;
} }
} }
} }

View File

@ -589,8 +589,8 @@ class FileManager : public FileLoadManager::Callback {
}; };
Enumerator<RemoteInfo> remote_location_info_; Enumerator<RemoteInfo> remote_location_info_;
FileNodeId file_node_seqno = 0; FileNodeId file_node_seqno = 1;
int32 file_id_seqno = 0; int32 file_id_seqno = 1;
std::unordered_map<string, FileId> file_hash_to_file_id_; std::unordered_map<string, FileId> file_hash_to_file_id_;