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
This commit is contained in:
Albert S. 2022-06-23 10:57:52 +02:00
parent 759d2a7924
commit e01f5d6490
2 changed files with 34 additions and 4 deletions

View File

@ -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))

View File

@ -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)
{