aboutsummaryrefslogtreecommitdiff
path: root/src/zenstore/workspaces.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/zenstore/workspaces.cpp')
-rw-r--r--src/zenstore/workspaces.cpp98
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>