From 48f05ddb4fde33b24ca02dcc5eb5a9f5821d5464 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Thu, 21 Mar 2024 08:55:44 +0100 Subject: [PATCH] refactor: add WordList type --- QVectorSearch/mainwindow.cpp | 19 ++---- QVectorSearch/mainwindow.h | 3 +- lib_vector_search/CMakeLists.txt | 4 +- lib_vector_search/include/grouped_finder.h | 3 +- lib_vector_search/include/linear_finder.h | 10 ++-- lib_vector_search/include/parallel_finder.h | 7 +-- .../include/sorted_linear_finder.h | 3 +- lib_vector_search/include/tree_finder.h | 6 +- lib_vector_search/include/word_list.h | 14 +++++ .../include/word_list_generator.h | 13 ---- lib_vector_search/src/grouped_finder.cpp | 2 +- lib_vector_search/src/linear_finder.cpp | 3 +- lib_vector_search/src/parallel_finder.cpp | 4 +- .../src/sorted_linear_finder.cpp | 4 +- lib_vector_search/src/tree_finder.cpp | 7 +-- lib_vector_search/src/word_list.cpp | 59 +++++++++++++++++++ lib_vector_search/src/word_list_generator.cpp | 32 ---------- vector_search_cli/main.cpp | 10 ++-- 18 files changed, 111 insertions(+), 92 deletions(-) create mode 100644 lib_vector_search/include/word_list.h delete mode 100644 lib_vector_search/include/word_list_generator.h create mode 100644 lib_vector_search/src/word_list.cpp delete mode 100644 lib_vector_search/src/word_list_generator.cpp diff --git a/QVectorSearch/mainwindow.cpp b/QVectorSearch/mainwindow.cpp index 69fb33c..4967bba 100644 --- a/QVectorSearch/mainwindow.cpp +++ b/QVectorSearch/mainwindow.cpp @@ -8,9 +8,7 @@ #include "sorted_linear_finder.h" #include "timer.h" #include "tree_finder.h" -#include "word_list_generator.h" -#include #include MainWindow::MainWindow(QWidget *parent) @@ -55,7 +53,9 @@ void MainWindow::setupWordList() { void MainWindow::generateWordList() { Timer timer; - word_list_ = WordListGenerator::generate(ui->wordListSizeSelector->value()); + word_list_ = WordList::fourCaps() + .multiply(ui->wordListSizeSelector->value()) + .shuffle(); timer.stop(); std::stringstream status_message; @@ -64,17 +64,10 @@ void MainWindow::generateWordList() { } void MainWindow::loadWordList(std::filesystem::path path) { - word_list_.clear(); - Timer timer; - std::ifstream ifs(path); - - std::string line; - while (std::getline(ifs, line)) { - for (auto i = 0; i < ui->wordListSizeSelector->value(); ++i) { - word_list_.emplace_back(line); - } - } + word_list_ = WordList::fromFile("words.txt") + .multiply(ui->wordListSizeSelector->value()) + .shuffle(); timer.stop(); std::stringstream status_message; diff --git a/QVectorSearch/mainwindow.h b/QVectorSearch/mainwindow.h index 84976b6..33f7d24 100644 --- a/QVectorSearch/mainwindow.h +++ b/QVectorSearch/mainwindow.h @@ -2,6 +2,7 @@ #define MAINWINDOW_H #include "finder.h" +#include "word_list.h" #include #include #include @@ -17,7 +18,7 @@ class MainWindow : public QMainWindow { Q_OBJECT private: - std::vector word_list_; + WordList word_list_; QStringListModel result_model_; QStandardItemModel search_algorithms_; QStandardItemModel word_list_sources_; diff --git a/lib_vector_search/CMakeLists.txt b/lib_vector_search/CMakeLists.txt index 38f41b6..daa98b2 100644 --- a/lib_vector_search/CMakeLists.txt +++ b/lib_vector_search/CMakeLists.txt @@ -7,8 +7,8 @@ project( add_library( vector_search STATIC - src/word_list_generator.cpp - include/word_list_generator.h + src/word_list.cpp + include/word_list.h src/linear_finder.cpp include/linear_finder.h src/sorted_linear_finder.cpp diff --git a/lib_vector_search/include/grouped_finder.h b/lib_vector_search/include/grouped_finder.h index 060b437..b562330 100644 --- a/lib_vector_search/include/grouped_finder.h +++ b/lib_vector_search/include/grouped_finder.h @@ -1,6 +1,7 @@ #pragma once #include "finder.h" +#include "word_list.h" #include #include @@ -10,7 +11,7 @@ private: std::map> groups_; public: - GroupedFinder(const std::vector &word_list); + GroupedFinder(const WordList &word_list); virtual std::forward_list find_prefix(std::string_view search_term) const override; diff --git a/lib_vector_search/include/linear_finder.h b/lib_vector_search/include/linear_finder.h index 35201d9..7aabb35 100644 --- a/lib_vector_search/include/linear_finder.h +++ b/lib_vector_search/include/linear_finder.h @@ -1,17 +1,15 @@ #pragma once #include "finder.h" - -#include - -using std::vector; +#include "word_list.h" class LinearFinder : public Finder { private: - const vector &word_list_; + const WordList &word_list_; public: - LinearFinder(const vector &word_list); + LinearFinder(const WordList &word_list); + std::forward_list find_prefix(std::string_view search_term) const override; }; diff --git a/lib_vector_search/include/parallel_finder.h b/lib_vector_search/include/parallel_finder.h index 1e8b527..55c776b 100644 --- a/lib_vector_search/include/parallel_finder.h +++ b/lib_vector_search/include/parallel_finder.h @@ -1,15 +1,14 @@ #pragma once #include "finder.h" - -#include +#include "word_list.h" class ParallelFinder : public Finder { private: - const std::vector &word_list_; + const WordList &word_list_; public: - ParallelFinder(const std::vector &word_list); + ParallelFinder(const WordList &word_list); std::forward_list find_prefix(std::string_view search_term) const override; diff --git a/lib_vector_search/include/sorted_linear_finder.h b/lib_vector_search/include/sorted_linear_finder.h index f49c27e..866c2b2 100644 --- a/lib_vector_search/include/sorted_linear_finder.h +++ b/lib_vector_search/include/sorted_linear_finder.h @@ -1,6 +1,7 @@ #pragma once #include "finder.h" +#include "word_list.h" #include @@ -9,7 +10,7 @@ private: std::vector word_list_; public: - SortedLinearFinder(const std::vector &word_list); + SortedLinearFinder(const WordList &word_list); std::forward_list find_prefix(std::string_view search_term) const override; diff --git a/lib_vector_search/include/tree_finder.h b/lib_vector_search/include/tree_finder.h index ffac545..707a7b2 100644 --- a/lib_vector_search/include/tree_finder.h +++ b/lib_vector_search/include/tree_finder.h @@ -1,9 +1,9 @@ #pragma once #include "finder.h" +#include "word_list.h" #include -#include class SearchTreeNode { private: @@ -19,7 +19,7 @@ public: class SearchTree : public SearchTreeNode { public: - SearchTree(const std::vector &word_list); + SearchTree(const WordList &word_list); }; class TreeFinder : public Finder { @@ -27,7 +27,7 @@ private: SearchTree search_tree_; public: - TreeFinder(const std::vector &word_list); + TreeFinder(const WordList &word_list); virtual std::forward_list find_prefix(std::string_view search_term) const override; diff --git a/lib_vector_search/include/word_list.h b/lib_vector_search/include/word_list.h new file mode 100644 index 0000000..ca52d9a --- /dev/null +++ b/lib_vector_search/include/word_list.h @@ -0,0 +1,14 @@ +#pragma once + +#include +#include +#include + +class WordList : public std::vector { +public: + WordList &multiply(size_t factor); + WordList &shuffle(); + + static WordList fourCaps(); + static WordList fromFile(const std::filesystem::path &path); +}; diff --git a/lib_vector_search/include/word_list_generator.h b/lib_vector_search/include/word_list_generator.h deleted file mode 100644 index 605b749..0000000 --- a/lib_vector_search/include/word_list_generator.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include -#include - -class WordListGenerator { -private: - static const std::string charset_; - -public: - WordListGenerator() = delete; - static std::vector generate(const size_t multiplier = 1); -}; diff --git a/lib_vector_search/src/grouped_finder.cpp b/lib_vector_search/src/grouped_finder.cpp index 20e4d67..39b8b43 100644 --- a/lib_vector_search/src/grouped_finder.cpp +++ b/lib_vector_search/src/grouped_finder.cpp @@ -8,7 +8,7 @@ using std::mutex, std::vector, std::thread, std::lock_guard, std::string, std::forward_list, std::string_view; -GroupedFinder::GroupedFinder(const std::vector &word_list) { +GroupedFinder::GroupedFinder(const WordList &word_list) { for (const auto &word : word_list) { groups_[word.front()].push_back(&word); } diff --git a/lib_vector_search/src/linear_finder.cpp b/lib_vector_search/src/linear_finder.cpp index 45525ac..f2d910e 100644 --- a/lib_vector_search/src/linear_finder.cpp +++ b/lib_vector_search/src/linear_finder.cpp @@ -4,8 +4,7 @@ using std::string, std::forward_list, std::string_view; -LinearFinder::LinearFinder(const vector &word_list) - : word_list_(word_list) {} +LinearFinder::LinearFinder(const WordList &word_list) : word_list_(word_list) {} forward_list LinearFinder::find_prefix(string_view search_term) const { diff --git a/lib_vector_search/src/parallel_finder.cpp b/lib_vector_search/src/parallel_finder.cpp index 441cadb..1b7effe 100644 --- a/lib_vector_search/src/parallel_finder.cpp +++ b/lib_vector_search/src/parallel_finder.cpp @@ -6,7 +6,7 @@ using std::mutex, std::thread, std::lock_guard, std::vector, std::forward_list, std::string, std::string_view; -ParallelFinder::ParallelFinder(const vector &word_list) +ParallelFinder::ParallelFinder(const WordList &word_list) : word_list_(word_list) {} forward_list @@ -28,7 +28,7 @@ ParallelFinder::find_prefix(string_view search_term) const { : (thread_index + 1) * (word_list_size / thread_count); threads.emplace_back( - [](const vector &word_list, const string_view &search_term, + [](const WordList &word_list, const string_view &search_term, forward_list &result, size_t start_index, size_t end_index, mutex &result_mutex) { forward_list thread_results; diff --git a/lib_vector_search/src/sorted_linear_finder.cpp b/lib_vector_search/src/sorted_linear_finder.cpp index e904d6f..db11154 100644 --- a/lib_vector_search/src/sorted_linear_finder.cpp +++ b/lib_vector_search/src/sorted_linear_finder.cpp @@ -3,9 +3,9 @@ #include #include -using std::vector, std::forward_list, std::string, std::string_view; +using std::forward_list, std::string, std::string_view; -SortedLinearFinder::SortedLinearFinder(const vector &word_list) { +SortedLinearFinder::SortedLinearFinder(const WordList &word_list) { std::transform(word_list.cbegin(), word_list.cend(), std::back_inserter(word_list_), [](const string &word) { return &word; }); diff --git a/lib_vector_search/src/tree_finder.cpp b/lib_vector_search/src/tree_finder.cpp index 2367d98..611738e 100644 --- a/lib_vector_search/src/tree_finder.cpp +++ b/lib_vector_search/src/tree_finder.cpp @@ -1,6 +1,6 @@ #include "tree_finder.h" -using std::string, std::string_view, std::forward_list, std::vector; +using std::string, std::string_view, std::forward_list; void SearchTreeNode::insert(string_view partial_word, const string *original_word) { @@ -35,14 +35,13 @@ forward_list SearchTreeNode::words() const { return results; }; -SearchTree::SearchTree(const vector &word_list) { +SearchTree::SearchTree(const WordList &word_list) { for (const auto &word : word_list) { insert(string_view(word), &word); } } -TreeFinder::TreeFinder(const vector &word_list) - : search_tree_(word_list) {} +TreeFinder::TreeFinder(const WordList &word_list) : search_tree_(word_list) {} forward_list TreeFinder::find_prefix(string_view search_term) const { diff --git a/lib_vector_search/src/word_list.cpp b/lib_vector_search/src/word_list.cpp new file mode 100644 index 0000000..db01a19 --- /dev/null +++ b/lib_vector_search/src/word_list.cpp @@ -0,0 +1,59 @@ +#include "word_list.h" + +#include +#include +#include + +WordList &WordList::multiply(size_t factor) { + WordList result; + result.reserve(size() * factor); + + for (auto time = 0; time < factor; ++time) { + std::copy(cbegin(), cend(), std::back_inserter(result)); + } + + std::swap(*this, result); + + return *this; +}; + +WordList &WordList::shuffle() { + std::random_device random_device; + std::mt19937 random_number_generator(random_device()); + std::shuffle(begin(), end(), random_number_generator); + + return *this; +} + +WordList WordList::fourCaps() { + const static std::string charset_ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + WordList word_list; + word_list.reserve(std::pow(charset_.length(), 4)); + + for (auto char_1 : charset_) { + for (auto char_2 : charset_) { + for (auto char_3 : charset_) { + for (auto char_4 : charset_) { + word_list.emplace_back( + std::initializer_list({char_1, char_2, char_3, char_4})); + } + } + } + } + + return word_list; +}; + +WordList WordList::fromFile(const std::filesystem::path &path) { + WordList word_list; + + std::ifstream ifs(path); + + std::string line; + while (std::getline(ifs, line)) { + word_list.emplace_back(line); + } + + return word_list; +} diff --git a/lib_vector_search/src/word_list_generator.cpp b/lib_vector_search/src/word_list_generator.cpp deleted file mode 100644 index ba4cf06..0000000 --- a/lib_vector_search/src/word_list_generator.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include "word_list_generator.h" - -#include -#include -#include - -const std::string WordListGenerator::charset_ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - -std::vector WordListGenerator::generate(const size_t multiplier) { - std::vector word_list; - word_list.reserve(multiplier * std::pow(charset_.length(), 4)); - - for (auto char_1 : charset_) { - for (auto char_2 : charset_) { - for (auto char_3 : charset_) { - for (auto char_4 : charset_) { - for (auto i = 0; i < multiplier; ++i) { - word_list.emplace_back( - std::initializer_list({char_1, char_2, char_3, char_4})); - } - } - } - } - } - - std::random_device random_device; - std::mt19937 random_number_generator(random_device()); - - std::shuffle(word_list.begin(), word_list.end(), random_number_generator); - - return word_list; -} diff --git a/vector_search_cli/main.cpp b/vector_search_cli/main.cpp index e915f2e..9922090 100644 --- a/vector_search_cli/main.cpp +++ b/vector_search_cli/main.cpp @@ -4,18 +4,18 @@ #include "sorted_linear_finder.h" #include "timer.h" #include "tree_finder.h" -#include "word_list_generator.h" +#include "word_list.h" #include #include -using std::string, std::string_view, std::vector, std::cout, std::endl; +using std::string, std::string_view, std::cout, std::endl; -vector generate_word_list(size_t size_factor = 1) { +WordList generate_word_list(size_t size_factor = 1) { cout << endl << "generating word list (" << size_factor << "x)" << endl; Timer generator_timer; - auto word_list = WordListGenerator::generate(size_factor); + auto word_list = WordList::fourCaps().multiply(size_factor).shuffle(); generator_timer.stop(); cout << "word list generator took " << generator_timer << endl; @@ -36,7 +36,7 @@ void test_finder_search(Finder &finder, string_view name, } template -void test_finder(const vector &word_list, string_view finder_name) { +void test_finder(const WordList &word_list, string_view finder_name) { cout << endl << "running " << finder_name << endl; Timer constructor_timer;