ParallelSearch/ParallelSearch.hpp
2021-12-15 18:20:10 +01:00

79 lines
2.1 KiB
C++

#ifndef PARALLELSEARCH_HPP
#define PARALLELSEARCH_HPP
#include <string>
#include <vector>
#include <iostream>
#include <thread>
#include "SearchJob.hpp"
template <typename Iterator>
class ParallelSearch
{
public:
// Type of the search result
typedef std::vector<Iterator> ResultList;
// construct parallel search by splitting the search range across <workerCount> SearchJob objects
ParallelSearch(unsigned workerCount, Iterator begin, Iterator end, const std::string& pattern)
{
std::size_t totalCount = end - begin;
std::size_t bucketSize = totalCount / workerCount;
std::size_t remains = totalCount % workerCount;
std::size_t offset = 0;
while (offset < totalCount)
{
// compute [first; last( iterators for sub-range
std::size_t size = bucketSize + remains;
Iterator first = begin + offset;
Iterator last = first + size;
// add appropriate search job
jobList_.push_back(SearchJob<Iterator>(first, last, pattern));
// increment offset
offset += size;
// clear remains (it has been added to first bucket)
remains = 0;
}
}
// Destructor
~ParallelSearch()
{
}
// run the search workers and collect results
void run()
{
// start thread for each job
std::vector<std::thread> threads;
for (SearchJob<Iterator>& job : jobList_)
{
threads.push_back(std::thread(&SearchJob<Iterator>::run, &job));
}
// wait for all threads to join
for (std::thread& th : threads)
{
th.join();
}
// collect the results
for (SearchJob<Iterator>& job : jobList_)
{
result_.insert(result_.end(), job.get_result().begin(), job.get_result().end());
}
}
// return the result
const ResultList& get_result() const { return result_; };
private:
// jobs to execute
std::vector<SearchJob<Iterator>> jobList_;
// result of the search
ResultList result_;
};
#endif