diff options
Diffstat (limited to 'src/zenstore/workspaces.cpp')
| -rw-r--r-- | src/zenstore/workspaces.cpp | 98 |
1 files changed, 41 insertions, 57 deletions
diff --git a/src/zenstore/workspaces.cpp b/src/zenstore/workspaces.cpp index 80e03296c..02a83d2a6 100644 --- a/src/zenstore/workspaces.cpp +++ b/src/zenstore/workspaces.cpp @@ -2,13 +2,13 @@ #include "zenstore/workspaces.h" +#include <zencore/basicfile.h> #include <zencore/compactbinarybuilder.h> #include <zencore/fmtutils.h> #include <zencore/scopeguard.h> #include <zencore/timer.h> #include <zencore/trace.h> #include <zencore/workthreadpool.h> -#include <zenutil/basicfile.h> ZEN_THIRD_PARTY_INCLUDES_START #include <tsl/robin_set.h> @@ -252,18 +252,43 @@ FolderStructure::FolderStructure(std::vector<FileEntry>&& InEntries, std::vector } namespace { - struct FolderScanner + struct FolderScanner : public GetDirectoryContentVisitor { FolderScanner(LoggerRef& Log, WorkerThreadPool& WorkerPool, const std::filesystem::path& Path) : m_Log(Log) , Path(Path) - , WorkLatch(1) , WorkerPool(WorkerPool) { } void Traverse(); - void Traverse(const std::filesystem::path& RelativeRoot, const std::filesystem::path& Path); + + virtual void AsyncVisitDirectory(const std::filesystem::path& RelativeRoot, DirectoryContent&& Content) override + { + std::vector<FolderStructure::FileEntry> FileEntries; + std::vector<Oid> PathIds; + const size_t FileCount = Content.FileNames.size(); + FileEntries.reserve(FileCount); + PathIds.reserve(FileCount); + + auto FileNameIt = Content.FileNames.begin(); + auto FileSizeIt = Content.FileSizes.begin(); + while (FileNameIt != Content.FileNames.end()) + { + ZEN_ASSERT_SLOW(FileSizeIt != Content.FileSizes.end()); + + std::filesystem::path RelativePath = RelativeRoot.empty() ? *FileNameIt : RelativeRoot / *FileNameIt; + PathIds.emplace_back(Workspaces::PathToId(RelativePath)); + FileEntries.emplace_back(FolderStructure::FileEntry{.RelativePath = std::move(RelativePath), .Size = *FileSizeIt}); + + FileNameIt++; + FileSizeIt++; + } + WorkLock.WithExclusiveLock([&]() { + FoundFiles.insert(FoundFiles.end(), FileEntries.begin(), FileEntries.end()); + FoundFileIds.insert(FoundFileIds.end(), PathIds.begin(), PathIds.end()); + }); + } LoggerRef& Log() { return m_Log; } LoggerRef& m_Log; @@ -271,75 +296,34 @@ namespace { RwLock WorkLock; std::vector<FolderStructure::FileEntry> FoundFiles; std::vector<Oid> FoundFileIds; - Latch WorkLatch; WorkerThreadPool& WorkerPool; }; - struct Visitor : public FileSystemTraversal::TreeVisitor + void FolderScanner::Traverse() { - Visitor(FolderScanner& Data, const std::filesystem::path& RelativeRoot) : Data(Data), RelativeRoot(RelativeRoot) {} + Stopwatch Timer; - FileSystemTraversal Traverser; - FolderScanner& Data; - std::vector<FolderStructure::FileEntry> Entries; - std::vector<Oid> FileIds; - std::filesystem::path RelativeRoot; + const std::filesystem::path Root = std::filesystem::absolute(Path); - virtual void VisitFile(const std::filesystem::path&, const path_view& File, uint64_t FileSize) - { - std::filesystem::path RelativePath = RelativeRoot.empty() ? File : RelativeRoot / File; - Entries.push_back(FolderStructure::FileEntry{.RelativePath = RelativePath, .Size = FileSize}); - FileIds.push_back(Workspaces::PathToId(RelativePath)); - } + Latch WorkLatch(1); - virtual bool VisitDirectory(const std::filesystem::path& Parent, const path_view& DirectoryName) - { - ZEN_ASSERT(!Parent.empty()); - ZEN_ASSERT(!DirectoryName.empty()); - FolderScanner* DataPtr = &Data; - Data.WorkLatch.AddCount(1); - Data.WorkerPool.ScheduleWork([DataPtr, - RootDir = Parent / DirectoryName, - RelativeRoot = RelativeRoot.empty() ? DirectoryName : RelativeRoot / DirectoryName]() { - auto _ = MakeGuard([DataPtr]() { DataPtr->WorkLatch.CountDown(); }); - try - { - DataPtr->Traverse(RelativeRoot, RootDir); - } - catch (const std::exception& Ex) - { - ZEN_WARN("Exception while traversing path {} {}: {}", RelativeRoot, RootDir, Ex.what()); - } - }); - return false; - } - }; + GetDirectoryContent( + Root, + DirectoryContentFlags::IncludeFiles | DirectoryContentFlags::IncludeFileSizes | DirectoryContentFlags::Recursive, + *this, + WorkerPool, + WorkLatch); - void FolderScanner::Traverse() - { - Stopwatch Timer; - Traverse({}, std::filesystem::absolute(Path)); WorkLatch.CountDown(); while (!WorkLatch.Wait(1000)) { - WorkLock.WithSharedLock([&]() { ZEN_INFO("Found {} files in '{}'...", FoundFiles.size(), Path.string()); }); + WorkLock.WithSharedLock([&]() { ZEN_INFO("Found {} files in '{}'...", FoundFiles.size(), Root.string()); }); } + ZEN_ASSERT(FoundFiles.size() == FoundFileIds.size()); ZEN_INFO("Found {} files in '{}' in {}", FoundFiles.size(), Path.string(), NiceLatencyNs(Timer.GetElapsedTimeUs() * 1000)); } - void FolderScanner::Traverse(const std::filesystem::path& RelativeRoot, const std::filesystem::path& AbsoluteRoot) - { - Visitor LeafVisitor(*this, RelativeRoot); - LeafVisitor.Traverser.TraverseFileSystem(AbsoluteRoot, LeafVisitor); - if (!LeafVisitor.Entries.empty()) - { - WorkLock.WithExclusiveLock([&]() { - FoundFiles.insert(FoundFiles.end(), LeafVisitor.Entries.begin(), LeafVisitor.Entries.end()); - FoundFileIds.insert(FoundFileIds.end(), LeafVisitor.FileIds.begin(), LeafVisitor.FileIds.end()); - }); - } - } } // namespace std::unique_ptr<FolderStructure> |