From f8729011e89341840e600c3cc5dec016f42f2549 Mon Sep 17 00:00:00 2001 From: karsten Date: Thu, 16 Dec 2021 11:35:38 +0100 Subject: [PATCH] made SearchJob a sub-class --- CMakeLists.txt | 2 +- ParallelSearch.hpp | 153 ++++++++++++++++++++++++++++++--------------- SearchJob.hpp | 54 ---------------- main.cpp | 14 +---- 4 files changed, 107 insertions(+), 116 deletions(-) delete mode 100644 SearchJob.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ace84d..253f540 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,6 @@ cmake_minimum_required (VERSION 3.8) project ("ParallelSearch") # Fügen Sie der ausführbaren Datei dieses Projekts eine Quelle hinzu. -add_executable (ParallelSearch "main.cpp" "SearchJob.hpp" "TestRunner.hpp" "ParallelSearch.hpp") +add_executable (ParallelSearch "main.cpp" "TestRunner.hpp" "ParallelSearch.hpp") # TODO: Fügen Sie bei Bedarf Tests hinzu, und installieren Sie Ziele. diff --git a/ParallelSearch.hpp b/ParallelSearch.hpp index 9e73edb..58fee13 100644 --- a/ParallelSearch.hpp +++ b/ParallelSearch.hpp @@ -5,75 +5,128 @@ #include #include #include -#include "SearchJob.hpp" +// #include "SearchJob.hpp" template class ParallelSearch { public: + // Type of the search result typedef std::vector ResultList; + class SearchJob + { + public: + // initially reserve n entries in result-list (to cut down number of reallocations) + enum { INITIAL_RESERVE = 128 }; + + // Create partial search job for provided range + SearchJob(Iterator begin, Iterator end, const std::string& pattern); + // Destructor + ~SearchJob() {} + + // run the search job and collect results internally + void execute(); + + // return the result + const ResultList& get_result() const { return result_; }; + + private: + // pattern to search for + std::string pattern_; + // start of search range + Iterator begin_; + // end of search range + Iterator end_; + // result of the search + ResultList result_; + }; + // construct parallel search by splitting the search range across 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 = begin + offset + size; - - // add appropriate search job - jobList_.push_back(SearchJob(first, last, pattern)); - - // increment offset - offset += size; - // clear remains (it has been added to first bucket) - remains = 0; - } - } - + ParallelSearch(unsigned workerCount, Iterator begin, Iterator end, const std::string& pattern); // Destructor - ~ParallelSearch() - { - } + ~ParallelSearch() {} // run the search workers and collect results - void run() - { - // start thread for each job - std::vector threads; - for (SearchJob& job : jobList_) - { - threads.push_back(std::thread(&SearchJob::run, &job)); - } - - // wait for all threads to join - for (std::thread& th : threads) - { - th.join(); - } - - // collect the results - for (SearchJob& job : jobList_) - { - result_.insert(result_.end(), job.get_result().begin(), job.get_result().end()); - } - } + void run(); // return the result const ResultList& get_result() const { return result_; }; private: // jobs to execute - std::vector> jobList_; + std::vector jobList_; // result of the search ResultList result_; }; + + +template +ParallelSearch::SearchJob::SearchJob(Iterator begin, Iterator end, const std::string& pattern) : begin_(begin), end_(end), pattern_(pattern) +{ + result_.reserve(INITIAL_RESERVE); +} + +template +void ParallelSearch::SearchJob::execute() +{ + for (Iterator itr = begin_; itr != end_; itr++) + { + if (0 == itr->compare(0, pattern_.size(), pattern_)) + { + // found a match, save the index + result_.push_back(itr); + } + } +} + +template +ParallelSearch::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 = begin + offset + size; + + // add appropriate search job + jobList_.push_back(SearchJob(first, last, pattern)); + + // increment offset + offset += size; + // clear remains (it has been added to first bucket) + remains = 0; + } +}; + + template + void ParallelSearch::run() +{ + // start thread for each job + std::vector threads; + for (SearchJob& job : jobList_) + { + threads.push_back(std::thread(&SearchJob::execute, &job)); + } + + // wait for all threads to join + for (std::thread& th : threads) + { + th.join(); + } + + // collect the results + for (SearchJob& job : jobList_) + { + result_.insert(result_.end(), job.get_result().begin(), job.get_result().end()); + } +} + #endif \ No newline at end of file diff --git a/SearchJob.hpp b/SearchJob.hpp deleted file mode 100644 index 48340f4..0000000 --- a/SearchJob.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef SEARCHJOB_HPP -#define SEARCHJOB_HPP - -#include -#include - -template -class SearchJob -{ -public: - // initially reserve n entries in result-list (to cut down number of reallocations) - enum { INITIAL_RESERVE = 128 }; - - // Type of the search result - typedef std::vector ResultList; - - // Create partial search job for provided range - SearchJob(Iterator begin, Iterator end, const std::string& pattern) : begin_(begin), end_(end), pattern_(pattern) - { - result_.reserve(INITIAL_RESERVE); - } - - // Destructor - ~SearchJob() - { - } - - // run the search job and collect results internally - void run() - { - for (Iterator itr = begin_; itr != end_; itr++) - { - if (0 == itr->compare(0, pattern_.size(), pattern_)) - { - // found a match, save the index - result_.push_back(itr); - } - } - } - - // return the result - const ResultList& get_result() const { return result_; }; - -private: - // pattern to search for - std::string pattern_; - // start of search range - Iterator begin_; - // end of search range - Iterator end_; - // result of the search - ResultList result_; -}; -#endif \ No newline at end of file diff --git a/main.cpp b/main.cpp index aa0a85a..67ea0be 100644 --- a/main.cpp +++ b/main.cpp @@ -5,16 +5,12 @@ #include #include -#include "SearchJob.hpp" #include "ParallelSearch.hpp" #include "TestRunner.hpp" - // Type of our hay stack: a list of strings typedef std::vector WordList; -typedef SearchJob WordSearch; - typedef ParallelSearch ParallelWordSearch; void create_testdata(WordList& words) @@ -37,15 +33,11 @@ void shuffle_testdata(WordList& words) std::shuffle(words.begin(), words.end(), rng); } -void run_wordsearch(WordSearch& search) +void run_wordsearch(ParallelWordSearch& search) { search.run(); } -void run_parallel_wordsearch(ParallelWordSearch& search) -{ - search.run(); -} int main() { @@ -60,13 +52,13 @@ int main() time_span = TestRunner(shuffle_testdata, test_data); std::cout << "shuffled test_data " << time_span << " seconds" << std::endl; - WordSearch wordSearch(test_data.begin(), test_data.end(), pattern); + ParallelWordSearch wordSearch(1, test_data.begin(), test_data.end(), pattern); time_span = TestRunner(run_wordsearch, wordSearch); std::cout << "linear search found " << wordSearch.get_result().size() << " matches: " << time_span << " seconds" << std::endl; ParallelWordSearch parallelWordSearch(workerCount, test_data.begin(), test_data.end(), pattern); - time_span = TestRunner(run_parallel_wordsearch, parallelWordSearch); + time_span = TestRunner(run_wordsearch, parallelWordSearch); std::cout << "parallel search found " << parallelWordSearch.get_result().size() << " matches: " << time_span << " seconds" << std::endl; // TODO add validation of results