@@ -48,7 +48,16 @@ void LooseFileLoader::on_draw_ui() {
4848 return ;
4949 }
5050
51+ auto clear_existence_cache = [&]() {
52+ std::unique_lock _{m_files_on_disk_mutex};
53+ m_files_on_disk.clear ();
54+ m_seen_files.clear ();
55+ m_cache_hits = 0 ;
56+ m_uncached_hits = 0 ;
57+ };
58+
5159 if (m_enabled->draw (" Enable Loose File Loader" )) {
60+ clear_existence_cache ();
5261 }
5362
5463 if (m_hook_success) {
@@ -66,6 +75,18 @@ void LooseFileLoader::on_draw_ui() {
6675 m_all_loose_files.clear ();
6776 }
6877
78+ if (ImGui::TreeNode (" Debug" )) {
79+ ImGui::Checkbox (" Enable file cache" , &m_enable_file_cache);
80+ ImGui::TextWrapped (" Cache hits: %d" , m_cache_hits);
81+ ImGui::TextWrapped (" Uncached hits: %d" , m_uncached_hits);
82+
83+ if (ImGui::Button (" Clear existence cache" )) {
84+ clear_existence_cache ();
85+ }
86+
87+ ImGui::TreePop ();
88+ }
89+
6990 ImGui::Checkbox (" Show recent files" , &m_show_recent_files);
7091
7192 if (m_show_recent_files) {
@@ -175,7 +196,7 @@ void LooseFileLoader::hook() {
175196 m_hook_success = true ;
176197}
177198
178- bool LooseFileLoader::handle_path (const wchar_t * path) {
199+ bool LooseFileLoader::handle_path (const wchar_t * path, size_t hash ) {
179200 if (path == nullptr || path[0 ] == L' \0 ' ) {
180201 return false ;
181202 }
@@ -198,8 +219,36 @@ bool LooseFileLoader::handle_path(const wchar_t* path) {
198219
199220 // spdlog::info("[LooseFileLoader] path_to_hash_hook called with path: {}", utility::narrow(path));
200221
201- if (enabled && std::filesystem::exists (path)) {
202- if (m_show_recent_files) {
222+ if (enabled) {
223+ bool exists_in_cache{false };
224+ bool exists_on_disk{false };
225+
226+ if (m_enable_file_cache) {
227+ {
228+ std::shared_lock _{m_files_on_disk_mutex};
229+ exists_on_disk = m_files_on_disk.contains (hash);
230+ exists_in_cache = exists_on_disk || m_seen_files.contains (hash);
231+ }
232+
233+ if (!exists_in_cache) {
234+ std::unique_lock _{m_files_on_disk_mutex};
235+
236+ if (std::filesystem::exists (path)) {
237+ m_files_on_disk.insert (hash);
238+ exists_on_disk = true ;
239+ }
240+
241+ m_seen_files.insert (hash);
242+ ++m_uncached_hits;
243+ } else {
244+ ++m_cache_hits;
245+ }
246+ } else {
247+ exists_on_disk = std::filesystem::exists (path);
248+ ++m_uncached_hits;
249+ }
250+
251+ if (m_show_recent_files && exists_on_disk) {
203252 std::unique_lock _{m_mutex};
204253
205254 m_all_loose_files.insert (path);
@@ -210,21 +259,23 @@ bool LooseFileLoader::handle_path(const wchar_t* path) {
210259 }
211260 }
212261
213- ++g_loose_file_loader->m_loose_files_loaded ;
214- return true ;
262+ if (exists_on_disk) {
263+ ++g_loose_file_loader->m_loose_files_loaded ;
264+ return true ;
265+ }
215266 }
216267
217268 return false ;
218269}
219270
220271uint64_t LooseFileLoader::path_to_hash_hook (const wchar_t * path) {
272+ const auto og = g_loose_file_loader->m_path_to_hash_hook ->get_original <decltype (path_to_hash_hook)>();
273+ const auto result = og (path);
274+
221275 // true to skip.
222- if (g_loose_file_loader->handle_path (path)) {
276+ if (g_loose_file_loader->handle_path (path, result )) {
223277 return 4294967296 ;
224278 }
225279
226- const auto og = g_loose_file_loader->m_path_to_hash_hook ->get_original <decltype (path_to_hash_hook)>();
227- const auto result = og (path);
228-
229280 return result;
230281}
0 commit comments