From a6146415dfe46c8a786aa0ffc8c5beabdf95218f Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Thu, 21 Mar 2024 20:16:00 +0100 Subject: [PATCH] feat: use WordRefList instead of std::foward_list for results --- QVectorSearch/mainwindow.cpp | 3 +- QVectorSearch/mainwindow.h | 2 +- lib_vector_search/CMakeLists.txt | 1 + lib_vector_search/include/bucket_finder.h | 6 ++-- lib_vector_search/include/finder.h | 6 ++-- lib_vector_search/include/grouped_finder.h | 2 +- lib_vector_search/include/linear_finder.h | 3 +- lib_vector_search/include/parallel_finder.h | 3 +- .../include/sorted_linear_finder.h | 3 +- lib_vector_search/include/tree_finder.h | 7 ++-- lib_vector_search/include/word_list.h | 21 ++++++------ lib_vector_search/src/bucket_finder.cpp | 22 ++++++------- lib_vector_search/src/grouped_finder.cpp | 8 ++--- lib_vector_search/src/linear_finder.cpp | 10 +++--- lib_vector_search/src/parallel_finder.cpp | 8 ++--- .../src/sorted_linear_finder.cpp | 9 +++--- lib_vector_search/src/tree_finder.cpp | 15 +++++---- lib_vector_search/src/word_list.cpp | 32 +++++++++++-------- vector_search_cli/main.cpp | 3 +- 19 files changed, 78 insertions(+), 86 deletions(-) diff --git a/QVectorSearch/mainwindow.cpp b/QVectorSearch/mainwindow.cpp index 70567a9..bb17875 100644 --- a/QVectorSearch/mainwindow.cpp +++ b/QVectorSearch/mainwindow.cpp @@ -122,8 +122,7 @@ void MainWindow::createSelectedFinder() { } } -void MainWindow::showResults( - const std::forward_list &results) { +void MainWindow::showResults(const WordRefList &results) { QStringList ui_results; for (auto word : results) { ui_results.append(QString::fromStdString(*word)); diff --git a/QVectorSearch/mainwindow.h b/QVectorSearch/mainwindow.h index 33f7d24..7d48a6d 100644 --- a/QVectorSearch/mainwindow.h +++ b/QVectorSearch/mainwindow.h @@ -36,7 +36,7 @@ private: void loadWordList(std::filesystem::path path); void search(const QString &search_term); void createSelectedFinder(); - void showResults(const std::forward_list &results); + void showResults(const WordRefList &results); private slots: void on_searchInput_textChanged(const QString &search_term); diff --git a/lib_vector_search/CMakeLists.txt b/lib_vector_search/CMakeLists.txt index 5bc9c1f..9df5030 100644 --- a/lib_vector_search/CMakeLists.txt +++ b/lib_vector_search/CMakeLists.txt @@ -19,6 +19,7 @@ add_library( include/tree_finder.h src/grouped_finder.cpp include/grouped_finder.h + include/finder.h src/bucket_finder.cpp include/bucket_finder.h) diff --git a/lib_vector_search/include/bucket_finder.h b/lib_vector_search/include/bucket_finder.h index 5606ca6..d8eae45 100644 --- a/lib_vector_search/include/bucket_finder.h +++ b/lib_vector_search/include/bucket_finder.h @@ -12,8 +12,7 @@ private: public: void insert(const WordList &word_list, size_t first_index, size_t last_index); - std::forward_list - find_prefix(std::string_view search_term) const; + WordRefList find_prefix(std::string_view search_term) const; }; class BucketFinder : public Finder { @@ -23,6 +22,5 @@ private: public: BucketFinder(const WordList &word_list); - std::forward_list - find_prefix(std::string_view search_term) const override; + WordRefList find_prefix(std::string_view search_term) const override; }; diff --git a/lib_vector_search/include/finder.h b/lib_vector_search/include/finder.h index a8b1d77..4d3bd90 100644 --- a/lib_vector_search/include/finder.h +++ b/lib_vector_search/include/finder.h @@ -1,12 +1,10 @@ #pragma once -#include -#include +#include "word_list.h" class Finder { public: virtual ~Finder() = default; - virtual std::forward_list - find_prefix(std::string_view search_term) const = 0; + virtual WordRefList find_prefix(std::string_view search_term) const = 0; }; diff --git a/lib_vector_search/include/grouped_finder.h b/lib_vector_search/include/grouped_finder.h index 572395a..8e9251d 100644 --- a/lib_vector_search/include/grouped_finder.h +++ b/lib_vector_search/include/grouped_finder.h @@ -12,6 +12,6 @@ private: public: GroupedFinder(const WordList &word_list); - virtual std::forward_list + virtual WordRefList find_prefix(std::string_view search_prefix) const override; }; diff --git a/lib_vector_search/include/linear_finder.h b/lib_vector_search/include/linear_finder.h index 7aabb35..658a6bd 100644 --- a/lib_vector_search/include/linear_finder.h +++ b/lib_vector_search/include/linear_finder.h @@ -10,6 +10,5 @@ private: public: LinearFinder(const WordList &word_list); - std::forward_list - find_prefix(std::string_view search_term) const override; + WordRefList 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 543096b..1e624c9 100644 --- a/lib_vector_search/include/parallel_finder.h +++ b/lib_vector_search/include/parallel_finder.h @@ -10,6 +10,5 @@ private: public: ParallelFinder(const WordList &word_list); - std::forward_list - find_prefix(std::string_view search_prefix) const override; + WordRefList find_prefix(std::string_view search_prefix) const override; }; diff --git a/lib_vector_search/include/sorted_linear_finder.h b/lib_vector_search/include/sorted_linear_finder.h index b2437d0..a338770 100644 --- a/lib_vector_search/include/sorted_linear_finder.h +++ b/lib_vector_search/include/sorted_linear_finder.h @@ -10,6 +10,5 @@ private: public: SortedLinearFinder(const WordList &word_list); - std::forward_list - find_prefix(std::string_view search_term) const override; + WordRefList 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 707a7b2..e1eea3d 100644 --- a/lib_vector_search/include/tree_finder.h +++ b/lib_vector_search/include/tree_finder.h @@ -7,14 +7,14 @@ class SearchTreeNode { private: - std::forward_list words_; + WordRefList words_; std::map children_; public: void insert(std::string_view partial_word, const std::string *original_word); const SearchTreeNode *find(std::string_view search_term) const; - std::forward_list words() const; + WordRefList words() const; }; class SearchTree : public SearchTreeNode { @@ -29,6 +29,5 @@ private: public: TreeFinder(const WordList &word_list); - virtual std::forward_list - find_prefix(std::string_view search_term) const override; + WordRefList 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 index b5a9300..f197170 100644 --- a/lib_vector_search/include/word_list.h +++ b/lib_vector_search/include/word_list.h @@ -1,11 +1,12 @@ #pragma once #include -#include #include #include #include +class WordRefList; + class WordList : public std::vector { public: WordList &multiply(size_t factor); @@ -15,10 +16,11 @@ public: static WordList fourCaps(); static WordList fromFile(const std::filesystem::path &path); - static void find_prefix_in_range( - const WordList &word_list, const std::string_view &search_prefix, - size_t start_index, size_t end_index, - std::forward_list &result, std::mutex &result_mutex); + static void find_prefix_in_range(const WordList &word_list, + const std::string_view &search_prefix, + size_t start_index, size_t end_index, + WordRefList &result, + std::mutex &result_mutex); }; class WordRefList : public std::vector { @@ -26,8 +28,9 @@ public: WordRefList() = default; WordRefList(const WordList &source); - static void find_prefix_in_range( - const WordRefList &word_list, const std::string_view &search_prefix, - size_t start_index, size_t end_index, - std::forward_list &result, std::mutex &result_mutex); + static void find_prefix_in_range(const WordRefList &word_list, + const std::string_view &search_prefix, + size_t start_index, size_t end_index, + WordRefList &result, + std::mutex &result_mutex); }; diff --git a/lib_vector_search/src/bucket_finder.cpp b/lib_vector_search/src/bucket_finder.cpp index 5d600d0..571b0a8 100644 --- a/lib_vector_search/src/bucket_finder.cpp +++ b/lib_vector_search/src/bucket_finder.cpp @@ -12,19 +12,19 @@ void Bucket::insert(const WordList &word_list, size_t first_index, } } -std::forward_list -Bucket::find_prefix(std::string_view search_term) const { - const auto group = groups_.find(search_term.front()); - if (group == groups_.cend()) { +WordRefList Bucket::find_prefix(std::string_view search_term) const { + auto group_it = groups_.find(search_term.front()); + if (group_it == groups_.cend()) { return {}; } - std::forward_list result; - for (const auto *word : group->second) { + WordRefList result; + for (const auto *word : group_it->second) { if (word->starts_with(search_term)) { - result.push_front(word); + result.push_back(word); } } + return result; } @@ -59,9 +59,8 @@ BucketFinder::BucketFinder(const WordList &word_list) { } } -std::forward_list -BucketFinder::find_prefix(std::string_view search_term) const { - std::forward_list result; +WordRefList BucketFinder::find_prefix(std::string_view search_term) const { + WordRefList result; std::mutex result_mutex; std::vector search_threads; @@ -71,7 +70,8 @@ BucketFinder::find_prefix(std::string_view search_term) const { auto thread_result = bucket.find_prefix(search_term); if (!thread_result.empty()) { std::lock_guard result_lock(result_mutex); - result.merge(thread_result); + std::move(thread_result.begin(), thread_result.end(), + std::back_inserter(result)); } }); } diff --git a/lib_vector_search/src/grouped_finder.cpp b/lib_vector_search/src/grouped_finder.cpp index bb8ee88..9bf732f 100644 --- a/lib_vector_search/src/grouped_finder.cpp +++ b/lib_vector_search/src/grouped_finder.cpp @@ -5,8 +5,7 @@ #include #include -using std::mutex, std::vector, std::thread, std::string, std::forward_list, - std::string_view; +using std::mutex, std::vector, std::thread, std::string, std::string_view; GroupedFinder::GroupedFinder(const WordList &word_list) { for (const auto &word : word_list) { @@ -14,8 +13,7 @@ GroupedFinder::GroupedFinder(const WordList &word_list) { } } -forward_list -GroupedFinder::find_prefix(string_view search_prefix) const { +WordRefList GroupedFinder::find_prefix(string_view search_prefix) const { const auto group = groups_.find(search_prefix.front()); if (group == groups_.cend()) { return {}; @@ -27,7 +25,7 @@ GroupedFinder::find_prefix(string_view search_prefix) const { const auto thread_count = std::min(std::thread::hardware_concurrency(), word_list_size); - forward_list result; + WordRefList result; mutex result_mutex; vector search_threads; diff --git a/lib_vector_search/src/linear_finder.cpp b/lib_vector_search/src/linear_finder.cpp index f2d910e..cbefe61 100644 --- a/lib_vector_search/src/linear_finder.cpp +++ b/lib_vector_search/src/linear_finder.cpp @@ -1,18 +1,16 @@ #include "linear_finder.h" -#include #include -using std::string, std::forward_list, std::string_view; +using std::string, std::string_view; LinearFinder::LinearFinder(const WordList &word_list) : word_list_(word_list) {} -forward_list -LinearFinder::find_prefix(string_view search_term) const { - forward_list matching_words; +WordRefList LinearFinder::find_prefix(string_view search_term) const { + WordRefList matching_words; for (const auto ¤t_word : word_list_) { if (current_word.starts_with(search_term)) { - matching_words.push_front(¤t_word); + matching_words.push_back(¤t_word); } } diff --git a/lib_vector_search/src/parallel_finder.cpp b/lib_vector_search/src/parallel_finder.cpp index 15c6a06..b398b2e 100644 --- a/lib_vector_search/src/parallel_finder.cpp +++ b/lib_vector_search/src/parallel_finder.cpp @@ -3,15 +3,13 @@ #include #include -using std::mutex, std::thread, std::vector, std::forward_list, std::string, - std::string_view; +using std::mutex, std::thread, std::vector, std::string, std::string_view; ParallelFinder::ParallelFinder(const WordList &word_list) : word_list_(word_list) {} -forward_list -ParallelFinder::find_prefix(string_view search_prefix) const { - forward_list result; +WordRefList ParallelFinder::find_prefix(string_view search_prefix) const { + WordRefList result; mutex result_mutex; const size_t word_list_size = word_list_.size(); diff --git a/lib_vector_search/src/sorted_linear_finder.cpp b/lib_vector_search/src/sorted_linear_finder.cpp index 3648bb2..fde4e66 100644 --- a/lib_vector_search/src/sorted_linear_finder.cpp +++ b/lib_vector_search/src/sorted_linear_finder.cpp @@ -2,7 +2,7 @@ #include -using std::forward_list, std::string, std::string_view; +using std::string, std::string_view; SortedLinearFinder::SortedLinearFinder(const WordList &word_list) : word_list_(word_list) { @@ -11,14 +11,13 @@ SortedLinearFinder::SortedLinearFinder(const WordList &word_list) [](const string *left, const string *right) { return *left < *right; }); } -forward_list -SortedLinearFinder::find_prefix(string_view search_term) const { - forward_list matching_words; +WordRefList SortedLinearFinder::find_prefix(string_view search_term) const { + WordRefList matching_words; bool in_range = false; for (const auto *word : word_list_) { if (word->starts_with(search_term)) { - matching_words.push_front(word); + matching_words.push_back(word); in_range = true; } else if (in_range) { break; diff --git a/lib_vector_search/src/tree_finder.cpp b/lib_vector_search/src/tree_finder.cpp index 611738e..660f1f7 100644 --- a/lib_vector_search/src/tree_finder.cpp +++ b/lib_vector_search/src/tree_finder.cpp @@ -1,11 +1,11 @@ #include "tree_finder.h" -using std::string, std::string_view, std::forward_list; +using std::string, std::string_view; void SearchTreeNode::insert(string_view partial_word, const string *original_word) { if (partial_word.empty()) { - words_.push_front(original_word); + words_.push_back(original_word); } else { children_[partial_word.front()].insert( string_view(partial_word).substr(1, partial_word.length()), @@ -26,10 +26,12 @@ const SearchTreeNode *SearchTreeNode::find(string_view search_term) const { return nullptr; } -forward_list SearchTreeNode::words() const { - forward_list results(words_); +WordRefList SearchTreeNode::words() const { + WordRefList results(words_); for (const auto &child : children_) { - results.merge(child.second.words()); + auto child_words = child.second.words(); + std::move(child_words.begin(), child_words.end(), + std::back_inserter(results)); } return results; @@ -43,8 +45,7 @@ SearchTree::SearchTree(const WordList &word_list) { TreeFinder::TreeFinder(const WordList &word_list) : search_tree_(word_list) {} -forward_list -TreeFinder::find_prefix(string_view search_term) const { +WordRefList TreeFinder::find_prefix(string_view search_term) const { const auto *result_node = search_tree_.find(search_term); if (result_node == nullptr) { return {}; diff --git a/lib_vector_search/src/word_list.cpp b/lib_vector_search/src/word_list.cpp index 6934beb..039ed83 100644 --- a/lib_vector_search/src/word_list.cpp +++ b/lib_vector_search/src/word_list.cpp @@ -71,22 +71,24 @@ WordList WordList::fromFile(const std::filesystem::path &path) { return word_list; } -void WordList::find_prefix_in_range( - const WordList &word_list, const std::string_view &search_prefix, - size_t start_index, size_t end_index, - std::forward_list &result, std::mutex &result_mutex) { - std::forward_list local_results; +void WordList::find_prefix_in_range(const WordList &word_list, + const std::string_view &search_prefix, + size_t start_index, size_t end_index, + WordRefList &result, + std::mutex &result_mutex) { + WordRefList local_results; for (size_t index = start_index; index < end_index; ++index) { const auto ¤t_word = word_list[index]; if (current_word.starts_with(search_prefix)) { - local_results.push_front(¤t_word); + local_results.push_back(¤t_word); } } if (!local_results.empty()) { const std::lock_guard lock(result_mutex); - result.merge(local_results); + std::move(local_results.begin(), local_results.end(), + std::back_inserter(result)); } }; @@ -96,21 +98,23 @@ WordRefList::WordRefList(const WordList &source) { } } -void WordRefList::find_prefix_in_range( - const WordRefList &word_list, const std::string_view &search_prefix, - size_t start_index, size_t end_index, - std::forward_list &result, std::mutex &result_mutex) { - std::forward_list local_results; +void WordRefList::find_prefix_in_range(const WordRefList &word_list, + const std::string_view &search_prefix, + size_t start_index, size_t end_index, + WordRefList &result, + std::mutex &result_mutex) { + WordRefList local_results; for (size_t index = start_index; index < end_index; ++index) { const auto *current_word = word_list[index]; if (current_word->starts_with(search_prefix)) { - local_results.push_front(current_word); + local_results.push_back(current_word); } } if (!local_results.empty()) { const std::lock_guard lock(result_mutex); - result.merge(local_results); + std::move(local_results.begin(), local_results.end(), + std::back_inserter(result)); } }; diff --git a/vector_search_cli/main.cpp b/vector_search_cli/main.cpp index 52a0b2b..01b84e9 100644 --- a/vector_search_cli/main.cpp +++ b/vector_search_cli/main.cpp @@ -55,13 +55,12 @@ int main(int argc, char *argv[]) { auto word_list = generate_word_list(5); - test_finder(word_list, "bucket finder"); - test_finder(word_list, "linear finder"); test_finder(word_list, "sorted linear finder"); test_finder(word_list, "parallel finder"); test_finder(word_list, "tree finder"); test_finder(word_list, "grouped finder"); + test_finder(word_list, "bucket finder"); return EXIT_SUCCESS; }