diff --git a/es-app/src/FileData.cpp b/es-app/src/FileData.cpp index 88934e7ed..0bb29157c 100644 --- a/es-app/src/FileData.cpp +++ b/es-app/src/FileData.cpp @@ -1313,14 +1313,12 @@ void FolderData::removeChild(FileData* file) assert(file->getParent() == this); #endif - for (auto it = mChildren.cbegin(); it != mChildren.cend(); it++) + auto it = std::find(mChildren.begin(), mChildren.end(), file); + if (it != mChildren.end()) { - if (*it == file) - { - file->setParent(NULL); - mChildren.erase(it); - return; - } + file->setParent(nullptr); + std::iter_swap(it, mChildren.end() - 1); + mChildren.pop_back(); } // File somehow wasn't in our children. @@ -1329,6 +1327,26 @@ void FolderData::removeChild(FileData* file) #endif } +void FolderData::bulkRemoveChildren(std::vector& mChildren, const std::unordered_set& filesToRemove) +{ + mChildren.erase( + std::remove_if( + mChildren.begin(), + mChildren.end(), + [&filesToRemove](FileData* file) + { + if (filesToRemove.count(file)) + { + file->setParent(nullptr); + return true; + } + return false; + } + ), + mChildren.end() + ); +} + FileData* FolderData::FindByPath(const std::string& path) { std::vector children = getChildren(); @@ -1506,23 +1524,26 @@ void FileData::detectLanguageAndRegion(bool overWrite) mMetadata.set(MetaDataId::Region, info.region); } -void FolderData::removeVirtualFolders() -{ +void FolderData::removeVirtualFolders() { if (!mOwnsChildrens) return; - for (int i = mChildren.size() - 1; i >= 0; i--) + std::unordered_set filesToRemove; + + for (auto file : mChildren) { - auto file = mChildren.at(i); if (file->getType() != FOLDER) continue; - if (((FolderData*)file)->mOwnsChildrens) - continue; + auto folder = static_cast(file); + if (!folder->mOwnsChildrens) + filesToRemove.insert(file); + } + + bulkRemoveChildren(mChildren, filesToRemove); - removeChild(file); + for (auto file : filesToRemove) delete file; - } } void FileData::checkCrc32(bool force) @@ -1726,14 +1747,13 @@ FolderData::~FolderData() clear(); } -void FolderData::clear() -{ +void FolderData::clear() { if (mOwnsChildrens) - { - for (int i = mChildren.size() - 1; i >= 0; i--) - delete mChildren.at(i); - } - + for (auto* child : mChildren) + { + child->setParent(nullptr); // prevent each child from inefficiently removing itself from our mChildren vector, since we're about to clear it anyway + delete child; + } mChildren.clear(); } diff --git a/es-app/src/FileData.h b/es-app/src/FileData.h index b916c6bde..59aee4743 100644 --- a/es-app/src/FileData.h +++ b/es-app/src/FileData.h @@ -5,6 +5,7 @@ #include "utils/FileSystemUtil.h" #include "MetaData.h" #include +#include #include #include #include @@ -251,6 +252,7 @@ class FolderData : public FileData void addChild(FileData* file, bool assignParent = true); // Error if mType != FOLDER void removeChild(FileData* file); //Error if mType != FOLDER + void bulkRemoveChildren(std::vector& mChildren, const std::unordered_set& filesToRemove); //Error if mType != FOLDER void createChildrenByFilenameMap(std::unordered_map& map);