diff --git a/src/cli/main.cpp b/src/cli/main.cpp index d26e3fd..7e31ec0 100644 --- a/src/cli/main.cpp +++ b/src/cli/main.cpp @@ -19,6 +19,9 @@ #include #include #include +#include +#include +#include #include #include "sqlite.hpp" #include "remwharead_cli.hpp" @@ -36,6 +39,8 @@ using std::endl; using std::string; using std::chrono::system_clock; using std::ofstream; +using std::thread; +using std::move; using std::list; int App::main(const std::vector &args) @@ -114,11 +119,54 @@ int App::main(const std::vector &args) if (!_search_tags.empty()) { + Search search(entries); entries = search.search_tags(_search_tags, _regex); } else if (!_search_all.empty()) { - entries = search.search_all(_search_all, _regex); + const size_t len = entries.size(); + constexpr size_t min_len = 100; + constexpr size_t n_threads = 2; + // If there are over `min_len` entries, use `n_threads` threads. + const size_t cut_at = ((len > min_len) ? (len / n_threads) : len); + + list> segments; + + // Use threads if list is big. + while (entries.size() > cut_at) + { + list segment; + + auto it = entries.begin(); + std::advance(it, cut_at); + + // Move the first `cut_at` entries into `segments`. + segment.splice(segment.begin(), entries, entries.begin(), it); + segments.push_back(move(segment)); + } + // Move rest of `entries` into `segments`. + segments.push_back(move(entries)); + + list threads; + for (auto &segment : segments) + { + thread t( + [&] + { + Search search(segment); + // Replace `segment` with `result`. + segment = search.search_all(_search_all, _regex); + }); + threads.push_back(move(t)); + } + + for (thread &t : threads) + { + t.join(); + // Move each of `segments` into `entries`. + entries.splice(entries.end(), segments.front()); + segments.pop_front(); + } } switch (_format)