From 670ce5b0b3e026b1752ea3429b43ac279535b72a Mon Sep 17 00:00:00 2001 From: karsten Date: Fri, 17 Dec 2021 19:36:45 +0100 Subject: [PATCH] remove templating ... it is not required --- CMakeLists.txt | 2 +- ParallelSearch.cpp | 66 ++++++++++++++++++++++++++++++++++++++++ ParallelSearch.hpp | 75 ++-------------------------------------------- WordList.hpp | 11 +++++++ main.cpp | 54 +++++++++++++-------------------- 5 files changed, 102 insertions(+), 106 deletions(-) create mode 100644 ParallelSearch.cpp create mode 100644 WordList.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a2437d2..7ffd8e0 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" "TestRunner.hpp" "ParallelSearch.hpp" "Parameters.hpp") +add_executable (ParallelSearch "main.cpp" "TestRunner.hpp" "ParallelSearch.hpp" "Parameters.hpp" "WordList.hpp" "ParallelSearch.cpp") # TODO: Fügen Sie bei Bedarf Tests hinzu, und installieren Sie Ziele. diff --git a/ParallelSearch.cpp b/ParallelSearch.cpp new file mode 100644 index 0000000..e51c42d --- /dev/null +++ b/ParallelSearch.cpp @@ -0,0 +1,66 @@ +#include "ParallelSearch.hpp" + +#include + +ParallelSearch::SearchJob::SearchJob(Iterator begin, Iterator end, const std::string& pattern) : begin_(begin), end_(end), pattern_(pattern) +{ + result_.reserve(INITIAL_RESERVE); +} + +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); + } + } +} + +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; + } +}; + +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()); + } +} \ No newline at end of file diff --git a/ParallelSearch.hpp b/ParallelSearch.hpp index 13b7e94..4c28110 100644 --- a/ParallelSearch.hpp +++ b/ParallelSearch.hpp @@ -1,16 +1,14 @@ #ifndef PARALLELSEARCH_HPP #define PARALLELSEARCH_HPP -#include #include -#include -#include +#include "WordList.hpp" -template class ParallelSearch { public: - + // Iterator type used inside the class + typedef WordList::const_iterator Iterator; // Type of the search result typedef std::vector ResultList; @@ -61,71 +59,4 @@ private: }; -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/WordList.hpp b/WordList.hpp new file mode 100644 index 0000000..421cc1c --- /dev/null +++ b/WordList.hpp @@ -0,0 +1,11 @@ +#ifndef WORDLIST_HPP +#define WORDLIST_HPP + +#include +#include + +// Type of our hay stack: a list of strings +typedef std::vector WordList; + + +#endif \ No newline at end of file diff --git a/main.cpp b/main.cpp index a349741..c85ce08 100644 --- a/main.cpp +++ b/main.cpp @@ -8,11 +8,6 @@ #include "TestRunner.hpp" #include "Parameters.hpp" -// Type of our hay stack: a list of strings -typedef std::vector WordList; - -typedef ParallelSearch ParallelWordSearch; - void create_testdata(WordList& words) { const char start = 'A'; @@ -35,27 +30,23 @@ void shuffle_testdata(WordList& words) std::shuffle(words.begin(), words.end(), rng); } -void run_wordsearch(ParallelWordSearch& search) +void run_wordsearch(ParallelSearch& search) { search.run(); } -bool check_result(const WordList& haystack, const std::string& pattern, const ParallelWordSearch::ResultList& result) +bool check_result(const WordList& haystack, const std::string& pattern, const ParallelSearch::ResultList& result) { - bool result_is_valid = true; + bool result_valid = true; // check number of matches const unsigned TESTPATTERN_LENGTH = 4; unsigned expected_count = static_cast(pow(26.0, double(TESTPATTERN_LENGTH - pattern.size()))); - std::cout << "number of matches expected: " << expected_count << " got: " << result.size() << " --> "; - if (result.size() == expected_count) + + if (result.size() != expected_count) { - std::cout << "OK" << std::endl; - } - else - { - std::cout << "ERROR" << std::endl; - result_is_valid = false; + std::cout << "wrong number of matches: expected " << expected_count << " but got " << result.size() << std::endl; + result_valid = false; } // verify matches contain the search-pattern @@ -68,12 +59,12 @@ bool check_result(const WordList& haystack, const std::string& pattern, const Pa } else { - std::cout << "found mismatch: " << *itr << std::endl; - result_is_valid = false; + std::cout << "found unexpected entry in result: " << *itr << std::endl; + result_valid = false; } } - std::cout << "verified " << valid_count << " matches --> " << ((result.size() == valid_count) ? "OK" : "ERROR") << std::endl; + std::cout << "result is " << (result_valid ? "VALID" : "INVALID") << std::endl; } int main(int argc, char** argv) @@ -90,9 +81,10 @@ int main(int argc, char** argv) exit(1); } - std::cout << "Workercount: " << parameters.WorkerCount() << std::endl; - std::cout << "Search pattern: " << parameters.SearchPattern() << std::endl; - std::cout << std::endl; + std::cout + << "Workercount: " << parameters.WorkerCount() << std::endl + << "Search pattern: " << parameters.SearchPattern() << std::endl + << std::endl; time_span = TestRunner(create_testdata, test_data); std::cout << "created test_data (" << test_data.size() << " words) in " << time_span << " seconds" << std::endl; @@ -100,21 +92,17 @@ int main(int argc, char** argv) time_span = TestRunner(shuffle_testdata, test_data); std::cout << "shuffled test_data in " << time_span << " seconds" << std::endl; - ParallelWordSearch wordSearch(1, test_data.begin(), test_data.end(), parameters.SearchPattern()); - - time_span = TestRunner(run_wordsearch, wordSearch); - std::cout << "linear search found " << wordSearch.get_result().size() << " matches in " << time_span << " seconds" << std::endl; + ParallelSearch linearSearch(1, test_data.begin(), test_data.end(), parameters.SearchPattern()); + time_span = TestRunner(run_wordsearch, linearSearch); + std::cout << "linear search found " << linearSearch.get_result().size() << " matches in " << time_span << " seconds" << std::endl; - ParallelWordSearch parallelWordSearch(parameters.WorkerCount(), test_data.begin(), test_data.end(), parameters.SearchPattern()); - time_span = TestRunner(run_wordsearch, parallelWordSearch); - std::cout << "parallel search found " << parallelWordSearch.get_result().size() << " matches in " << time_span << " seconds" << std::endl; + ParallelSearch parallelSearch(parameters.WorkerCount(), test_data.begin(), test_data.end(), parameters.SearchPattern()); + time_span = TestRunner(run_wordsearch, parallelSearch); + std::cout << "parallel search found " << parallelSearch.get_result().size() << " matches in " << time_span << " seconds" << std::endl; std::cout << std::endl; std::cout << "checking result of parallel search ..." << std::endl; - bool result_valid = check_result(test_data, parameters.SearchPattern(), parallelWordSearch.get_result()); - - std::cout << std::endl << "Result is " << (result_valid ? "VALID" : "INVALID") << std::endl; - std::cout << std::endl; + check_result(test_data, parameters.SearchPattern(), parallelSearch.get_result()); return 0; }