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
джерело 759d2a7924
коміт e01f5d6490
2 змінених файлів з 34 додано та 4 видалено

@ -19,9 +19,12 @@ void DirScanWorker::run()
QString path; QString path;
/* TODO: if we have e. g. only one path, then only one thread will scan this 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 * Thus, we must submit new directory paths to the queue so other threads can help
the current one (requires a new logic for threads in ParallelDirScanner). Alterantively, the current one.
start new DirScanWorkers ourselves here... */
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)) while(queue->dequeue(path))
{ {
if(wildcardMatcher.match(path)) if(wildcardMatcher.match(path))

@ -71,7 +71,34 @@ void ParallelDirScanner::scan()
this->targetPathsQueue.clear(); this->targetPathsQueue.clear();
this->resultPathsQueue.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(); int threadsNum = getThreadsNum();
if(threadsNum == 0) if(threadsNum == 0)
{ {