shared: Begin ParallelDirScanner
Αυτή η υποβολή περιλαμβάνεται σε:
γονέας
f3fbf4a1dc
υποβολή
d7705241ee
103
shared/paralleldirscanner.cpp
Κανονικό αρχείο
103
shared/paralleldirscanner.cpp
Κανονικό αρχείο
@ -0,0 +1,103 @@
|
||||
#include "paralleldirscanner.h"
|
||||
|
||||
#include <QRunnable>
|
||||
#include <QMutex>
|
||||
#include <QDirIterator>
|
||||
#include <QThread>
|
||||
#include <QThreadPool>
|
||||
#include <functional>
|
||||
#include "dirscanworker.h"
|
||||
#include "logger.h"
|
||||
|
||||
ParallelDirScanner::ParallelDirScanner()
|
||||
{
|
||||
this->threadpool.setMaxThreadCount(QThread::idealThreadCount() / 2);
|
||||
}
|
||||
|
||||
ConcurrentQueue<QString> &ParallelDirScanner::getResults()
|
||||
{
|
||||
return this->resultPathsQueue;
|
||||
}
|
||||
|
||||
void ParallelDirScanner::setIgnorePatterns(QStringList patterns)
|
||||
{
|
||||
this->ignorePatterns = patterns;
|
||||
}
|
||||
|
||||
void ParallelDirScanner::setPaths(QVector<QString> paths)
|
||||
{
|
||||
this->paths = paths;
|
||||
}
|
||||
|
||||
void ParallelDirScanner::cancel()
|
||||
{
|
||||
this->stopToken.store(true, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
void ParallelDirScanner::handleWorkersProgress(unsigned int progress)
|
||||
{
|
||||
this->processedPaths += progress;
|
||||
emit this->progress(progress, this->processedPaths);
|
||||
}
|
||||
|
||||
void ParallelDirScanner::handleWorkersFinish()
|
||||
{
|
||||
Logger::info() << "Worker finished";
|
||||
// no mutexes required due to queued connection
|
||||
++finishedWorkers;
|
||||
if(finishedWorkers == getThreadsNum())
|
||||
{
|
||||
running = false;
|
||||
emit scanComplete();
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int ParallelDirScanner::getThreadsNum() const
|
||||
{
|
||||
int threadsNum = this->threadpool.maxThreadCount();
|
||||
if(threadsNum > this->paths.size())
|
||||
{
|
||||
threadsNum = this->paths.size();
|
||||
}
|
||||
return threadsNum;
|
||||
}
|
||||
|
||||
void ParallelDirScanner::scan()
|
||||
{
|
||||
Logger::info() << "I am scanning";
|
||||
this->stopToken.store(false, std::memory_order_relaxed);
|
||||
this->finishedWorkers = 0;
|
||||
this->processedPaths = 0;
|
||||
this->targetPathsQueue.clear();
|
||||
this->resultPathsQueue.clear();
|
||||
|
||||
this->targetPathsQueue.enqueue(this->paths);
|
||||
int threadsNum = getThreadsNum();
|
||||
if(threadsNum == 0)
|
||||
{
|
||||
emit scanComplete();
|
||||
return;
|
||||
}
|
||||
running = true;
|
||||
for(int i = 0; i < threadsNum; i++)
|
||||
{
|
||||
DirScanWorker *runnable = new DirScanWorker(this->targetPathsQueue, this->resultPathsQueue,
|
||||
this->ignorePatterns, 1000, this->stopToken);
|
||||
runnable->setAutoDelete(false);
|
||||
connect(runnable, &DirScanWorker::progress, this, &ParallelDirScanner::handleWorkersProgress,
|
||||
Qt::QueuedConnection);
|
||||
connect(runnable, &DirScanWorker::finished, this, &ParallelDirScanner::handleWorkersFinish,
|
||||
Qt::QueuedConnection);
|
||||
threadpool.start(runnable);
|
||||
}
|
||||
}
|
||||
|
||||
bool ParallelDirScanner::isRunning()
|
||||
{
|
||||
return this->running;
|
||||
}
|
||||
|
||||
unsigned int ParallelDirScanner::pathCount()
|
||||
{
|
||||
return this->processedPaths;
|
||||
}
|
48
shared/paralleldirscanner.h
Κανονικό αρχείο
48
shared/paralleldirscanner.h
Κανονικό αρχείο
@ -0,0 +1,48 @@
|
||||
#ifndef PARALLELDIRSCANNER_H
|
||||
#define PARALLELDIRSCANNER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QMutex>
|
||||
#include <atomic>
|
||||
#include <QThreadPool>
|
||||
#include "concurrentqueue.h"
|
||||
class ParallelDirScanner : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
protected:
|
||||
QStringList ignorePatterns;
|
||||
QThreadPool threadpool;
|
||||
|
||||
unsigned int finishedWorkers = 0;
|
||||
unsigned int processedPaths = 0;
|
||||
|
||||
std::atomic<bool> stopToken;
|
||||
|
||||
bool running = false;
|
||||
|
||||
QVector<QString> paths;
|
||||
ConcurrentQueue<QString> targetPathsQueue;
|
||||
ConcurrentQueue<QString> resultPathsQueue;
|
||||
unsigned int getThreadsNum() const;
|
||||
|
||||
public:
|
||||
ParallelDirScanner();
|
||||
|
||||
ConcurrentQueue<QString> &getResults();
|
||||
void setIgnorePatterns(QStringList patterns);
|
||||
void setPaths(QVector<QString> paths);
|
||||
void scan();
|
||||
bool isRunning();
|
||||
|
||||
unsigned int pathCount();
|
||||
|
||||
signals:
|
||||
void scanComplete();
|
||||
void progress(int, int);
|
||||
public slots:
|
||||
void cancel();
|
||||
void handleWorkersProgress(unsigned int progress);
|
||||
void handleWorkersFinish();
|
||||
};
|
||||
|
||||
#endif // PARALLELDIRSCANNER_H
|
Φόρτωση…
Αναφορά σε νέο ζήτημα
Block a user