From e01f5d6490dafa4d4951d1d4752275e95b0a6609 Mon Sep 17 00:00:00 2001 From: Albert S Date: Thu, 23 Jun 2022 10:57:52 +0200 Subject: [PATCH] shared: ParallelDirScanner: Perform first pass to collect paths Scan the top directory to collect paths for the threads. This way we don't launch threads for paths without subdirs. Secondly, large trees like usually $HOME will be scanned by multiple threads at first. Nevertheless, ParallelDirScanner can be improved still as threads may run quickly out of work, so we may end up with only one anyway again --- shared/dirscanworker.cpp | 9 ++++++--- shared/paralleldirscanner.cpp | 29 ++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/shared/dirscanworker.cpp b/shared/dirscanworker.cpp index 8659231..6f9c623 100644 --- a/shared/dirscanworker.cpp +++ b/shared/dirscanworker.cpp @@ -19,9 +19,12 @@ void DirScanWorker::run() QString path; /* TODO: if we have e. g. only one path, then only one thread will scan this path. * - * Thus, we must resubmit to the queue directories so other threads can help - the current one (requires a new logic for threads in ParallelDirScanner). Alterantively, - start new DirScanWorkers ourselves here... */ + * Thus, we must submit new directory paths to the queue so other threads can help + the current one. + + It also may not be guaranteed enqueuing new paths is faster than just scanning them, + at least not for dirs with a small number of files + */ while(queue->dequeue(path)) { if(wildcardMatcher.match(path)) diff --git a/shared/paralleldirscanner.cpp b/shared/paralleldirscanner.cpp index 63368b3..ea111ab 100644 --- a/shared/paralleldirscanner.cpp +++ b/shared/paralleldirscanner.cpp @@ -71,7 +71,34 @@ void ParallelDirScanner::scan() this->targetPathsQueue.clear(); this->resultPathsQueue.clear(); - this->targetPathsQueue.enqueue(this->paths); + /* First scan without subdirs. This way we collect paths for the threads */ + WildcardMatcher matcher; + matcher.setPatterns(this->ignorePatterns); + for(QString &path : this->paths) + { + QDirIterator iterator(path, QStringList{}, QDir::Dirs | QDir::QDir::Files | QDir::NoDotDot); + while(iterator.hasNext()) + { + QString path = iterator.next(); + if(matcher.match(path)) + { + continue; + } + QFileInfo info = iterator.fileInfo(); + if(!info.isSymLink()) + { + if(info.isDir()) + { + this->targetPathsQueue.enqueue(info.absoluteFilePath()); + } + else + { + this->resultPathsQueue.enqueue(info.absoluteFilePath()); + this->processedPaths += 1; + } + } + } + } int threadsNum = getThreadsNum(); if(threadsNum == 0) {