From 4fce72a967fd3c65b571a675064c6fa31bf3bf89 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 3 Jul 2021 18:10:06 +0200 Subject: [PATCH] Assistant: Use fstatat() while building FileProvider path cache Using fstatat() allows the kernel to do relative path resolution as opposed to absolute path resolution, which is significantly faster and allows us to build the path cache sooner. :^) --- Userland/Applications/Assistant/Providers.cpp | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/Userland/Applications/Assistant/Providers.cpp b/Userland/Applications/Assistant/Providers.cpp index ace92b6a35..695669bf65 100644 --- a/Userland/Applications/Assistant/Providers.cpp +++ b/Userland/Applications/Assistant/Providers.cpp @@ -6,8 +6,10 @@ #include "Providers.h" #include "FuzzyMatch.h" +#include #include #include +#include #include #include #include @@ -18,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -151,28 +154,34 @@ void FileProvider::build_filesystem_cache() m_work_queue.enqueue("/"); Threading::BackgroundAction::create([this](auto&) { + String slash = "/"; + Core::ElapsedTimer timer; + timer.start(); while (!m_work_queue.is_empty()) { - auto start = m_work_queue.dequeue(); - Core::DirIterator di(start, Core::DirIterator::SkipDots); + auto base_directory = m_work_queue.dequeue(); + Core::DirIterator di(base_directory, Core::DirIterator::SkipDots); while (di.has_next()) { - auto path = di.next_full_path(); + auto path = di.next_path(); struct stat st = {}; - if (lstat(path.characters(), &st) < 0) { - perror("stat"); + if (fstatat(di.fd(), path.characters(), &st, AT_SYMLINK_NOFOLLOW) < 0) { + perror("fstatat"); continue; } if (S_ISLNK(st.st_mode)) continue; - m_full_path_cache.append(path); + auto full_path = LexicalPath::join(slash, base_directory, path).string(); + + m_full_path_cache.append(full_path); if (S_ISDIR(st.st_mode)) { - m_work_queue.enqueue(path); + m_work_queue.enqueue(full_path); } } } + dbgln("Built cache in {} ms", timer.elapsed()); return 0; }, [this](auto) { m_building_cache = false; }); }