From 000fa3cf55c6aa1cc17da7e3c00ba29a7a3513e6 Mon Sep 17 00:00:00 2001 From: Emmanuel Gil Peyrot Date: Sun, 6 Sep 2015 07:59:04 +0100 Subject: [PATCH] Common: Replace ScanDirectoryTree with a non-recursive implementation. This makes it do only what we need for our readdir implementation, thus improving performances a lot in heavy trees and fixing bugs like #1115. --- src/common/file_util.cpp | 14 +++++++------- src/common/file_util.h | 12 +++++++++--- src/core/file_sys/disk_archive.cpp | 2 +- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index dcb9baa08..12b18e563 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp @@ -420,9 +420,7 @@ bool CreateEmptyFile(const std::string &filename) } -// Scans the directory tree gets, starting from _Directory and adds the -// results into parentEntry. Returns the number of files+directories found -u32 ScanDirectoryTree(const std::string &directory, FSTEntry& parentEntry) +u32 ReadDirectory(const std::string& directory, FSTEntry& parentEntry, int recursion) { LOG_TRACE(Common_Filesystem, "directory %s", directory.c_str()); // How many files + directories we found @@ -467,12 +465,14 @@ u32 ScanDirectoryTree(const std::string &directory, FSTEntry& parentEntry) if (IsDirectory(entry.physicalName.c_str())) { entry.isDirectory = true; - // is a directory, lets go inside - entry.size = ScanDirectoryTree(entry.physicalName, entry); - foundEntries += (u32)entry.size; + if (recursion > 0) + { + entry.size = ReadDirectory(entry.physicalName, entry, recursion - 1); + foundEntries += (u32)entry.size; + } } else - { // is a file + { entry.isDirectory = false; entry.size = GetSize(entry.physicalName.c_str()); } diff --git a/src/common/file_util.h b/src/common/file_util.h index e71a9b2fa..8315973b8 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -96,9 +96,15 @@ bool Copy(const std::string &srcFilename, const std::string &destFilename); // creates an empty file filename, returns true on success bool CreateEmptyFile(const std::string &filename); -// Scans the directory tree gets, starting from _Directory and adds the -// results into parentEntry. Returns the number of files+directories found -u32 ScanDirectoryTree(const std::string &directory, FSTEntry& parentEntry); +/** + * Reads the contents of a directory, and adds the results into + * parentEntry, optionally going down up to recursion levels. + * @param directory Path of the directory to scan. + * @param parentEntry Structure into which found files will be put. + * @param recursion Number of children directory to read before giving up. + * @returns u32 The number of files+directories found. + */ +u32 ReadDirectory(const std::string& directory, FSTEntry& parentEntry, int recursion = 0); // deletes the given directory and anything under it. Returns true on success. bool DeleteDirRecursively(const std::string &directory); diff --git a/src/core/file_sys/disk_archive.cpp b/src/core/file_sys/disk_archive.cpp index e9ecd2b1c..f0facf726 100644 --- a/src/core/file_sys/disk_archive.cpp +++ b/src/core/file_sys/disk_archive.cpp @@ -144,7 +144,7 @@ DiskDirectory::DiskDirectory(const DiskArchive& archive, const Path& path) { bool DiskDirectory::Open() { if (!FileUtil::IsDirectory(path)) return false; - FileUtil::ScanDirectoryTree(path, directory); + FileUtil::ReadDirectory(path, directory); children_iterator = directory.children.begin(); return true; }