diff options
| author | 2023-05-09 09:47:36 -0400 | |
|---|---|---|
| committer | 2023-05-09 09:47:36 -0400 | |
| commit | 7944f271dcbd8217ea0a9e556b75edbe7a23eaff (patch) | |
| tree | 7e2159b9fc6043e8318d14d0eb8da803d4019d6a | |
| parent | Merge pull request #10203 from german77/calibration (diff) | |
| parent | vfs_layered: avoid n^2 lookup in layeredfs building (diff) | |
| download | yuzu-7944f271dcbd8217ea0a9e556b75edbe7a23eaff.tar.gz yuzu-7944f271dcbd8217ea0a9e556b75edbe7a23eaff.tar.xz yuzu-7944f271dcbd8217ea0a9e556b75edbe7a23eaff.zip | |
Merge pull request #10183 from liamwhite/mods
vfs_vector: avoid n^2 lookup in layeredfs building
| -rw-r--r-- | src/core/file_sys/vfs_layered.cpp | 9 | ||||
| -rw-r--r-- | src/core/file_sys/vfs_vector.cpp | 19 | ||||
| -rw-r--r-- | src/core/file_sys/vfs_vector.h | 4 |
3 files changed, 29 insertions, 3 deletions
diff --git a/src/core/file_sys/vfs_layered.cpp b/src/core/file_sys/vfs_layered.cpp index da05dd395..3e6426afc 100644 --- a/src/core/file_sys/vfs_layered.cpp +++ b/src/core/file_sys/vfs_layered.cpp | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include <algorithm> | 4 | #include <algorithm> |
| 5 | #include <set> | ||
| 5 | #include <utility> | 6 | #include <utility> |
| 6 | #include "core/file_sys/vfs_layered.h" | 7 | #include "core/file_sys/vfs_layered.h" |
| 7 | 8 | ||
| @@ -58,11 +59,13 @@ std::string LayeredVfsDirectory::GetFullPath() const { | |||
| 58 | 59 | ||
| 59 | std::vector<VirtualFile> LayeredVfsDirectory::GetFiles() const { | 60 | std::vector<VirtualFile> LayeredVfsDirectory::GetFiles() const { |
| 60 | std::vector<VirtualFile> out; | 61 | std::vector<VirtualFile> out; |
| 62 | std::set<std::string, std::less<>> out_names; | ||
| 63 | |||
| 61 | for (const auto& layer : dirs) { | 64 | for (const auto& layer : dirs) { |
| 62 | for (const auto& file : layer->GetFiles()) { | 65 | for (const auto& file : layer->GetFiles()) { |
| 63 | if (std::find_if(out.begin(), out.end(), [&file](const VirtualFile& comp) { | 66 | auto file_name = file->GetName(); |
| 64 | return comp->GetName() == file->GetName(); | 67 | if (!out_names.contains(file_name)) { |
| 65 | }) == out.end()) { | 68 | out_names.emplace(std::move(file_name)); |
| 66 | out.push_back(file); | 69 | out.push_back(file); |
| 67 | } | 70 | } |
| 68 | } | 71 | } |
diff --git a/src/core/file_sys/vfs_vector.cpp b/src/core/file_sys/vfs_vector.cpp index 251d9d7c9..af1df4c51 100644 --- a/src/core/file_sys/vfs_vector.cpp +++ b/src/core/file_sys/vfs_vector.cpp | |||
| @@ -67,6 +67,23 @@ VectorVfsDirectory::VectorVfsDirectory(std::vector<VirtualFile> files_, | |||
| 67 | 67 | ||
| 68 | VectorVfsDirectory::~VectorVfsDirectory() = default; | 68 | VectorVfsDirectory::~VectorVfsDirectory() = default; |
| 69 | 69 | ||
| 70 | VirtualFile VectorVfsDirectory::GetFile(std::string_view file_name) const { | ||
| 71 | if (!optimized_file_index_built) { | ||
| 72 | optimized_file_index.clear(); | ||
| 73 | for (size_t i = 0; i < files.size(); i++) { | ||
| 74 | optimized_file_index.emplace(files[i]->GetName(), i); | ||
| 75 | } | ||
| 76 | optimized_file_index_built = true; | ||
| 77 | } | ||
| 78 | |||
| 79 | const auto it = optimized_file_index.find(file_name); | ||
| 80 | if (it != optimized_file_index.end()) { | ||
| 81 | return files[it->second]; | ||
| 82 | } | ||
| 83 | |||
| 84 | return nullptr; | ||
| 85 | } | ||
| 86 | |||
| 70 | std::vector<VirtualFile> VectorVfsDirectory::GetFiles() const { | 87 | std::vector<VirtualFile> VectorVfsDirectory::GetFiles() const { |
| 71 | return files; | 88 | return files; |
| 72 | } | 89 | } |
| @@ -107,6 +124,7 @@ bool VectorVfsDirectory::DeleteSubdirectory(std::string_view subdir_name) { | |||
| 107 | } | 124 | } |
| 108 | 125 | ||
| 109 | bool VectorVfsDirectory::DeleteFile(std::string_view file_name) { | 126 | bool VectorVfsDirectory::DeleteFile(std::string_view file_name) { |
| 127 | optimized_file_index_built = false; | ||
| 110 | return FindAndRemoveVectorElement(files, file_name); | 128 | return FindAndRemoveVectorElement(files, file_name); |
| 111 | } | 129 | } |
| 112 | 130 | ||
| @@ -124,6 +142,7 @@ VirtualFile VectorVfsDirectory::CreateFile(std::string_view file_name) { | |||
| 124 | } | 142 | } |
| 125 | 143 | ||
| 126 | void VectorVfsDirectory::AddFile(VirtualFile file) { | 144 | void VectorVfsDirectory::AddFile(VirtualFile file) { |
| 145 | optimized_file_index_built = false; | ||
| 127 | files.push_back(std::move(file)); | 146 | files.push_back(std::move(file)); |
| 128 | } | 147 | } |
| 129 | 148 | ||
diff --git a/src/core/file_sys/vfs_vector.h b/src/core/file_sys/vfs_vector.h index bfedb6e42..c9955755b 100644 --- a/src/core/file_sys/vfs_vector.h +++ b/src/core/file_sys/vfs_vector.h | |||
| @@ -105,6 +105,7 @@ public: | |||
| 105 | VirtualDir parent = nullptr); | 105 | VirtualDir parent = nullptr); |
| 106 | ~VectorVfsDirectory() override; | 106 | ~VectorVfsDirectory() override; |
| 107 | 107 | ||
| 108 | VirtualFile GetFile(std::string_view file_name) const override; | ||
| 108 | std::vector<VirtualFile> GetFiles() const override; | 109 | std::vector<VirtualFile> GetFiles() const override; |
| 109 | std::vector<VirtualDir> GetSubdirectories() const override; | 110 | std::vector<VirtualDir> GetSubdirectories() const override; |
| 110 | bool IsWritable() const override; | 111 | bool IsWritable() const override; |
| @@ -126,6 +127,9 @@ private: | |||
| 126 | 127 | ||
| 127 | VirtualDir parent; | 128 | VirtualDir parent; |
| 128 | std::string name; | 129 | std::string name; |
| 130 | |||
| 131 | mutable std::map<std::string, size_t, std::less<>> optimized_file_index; | ||
| 132 | mutable bool optimized_file_index_built{}; | ||
| 129 | }; | 133 | }; |
| 130 | 134 | ||
| 131 | } // namespace FileSys | 135 | } // namespace FileSys |