52 lines
1.4 KiB
C++
52 lines
1.4 KiB
C++
#include "grouped_finder.h"
|
|
|
|
#include <forward_list>
|
|
#include <mutex>
|
|
#include <thread>
|
|
#include <vector>
|
|
|
|
using std::mutex, std::vector, std::thread, std::string, std::forward_list,
|
|
std::string_view;
|
|
|
|
GroupedFinder::GroupedFinder(const WordList &word_list) {
|
|
for (const auto &word : word_list) {
|
|
groups_[word.front()].push_back(&word);
|
|
}
|
|
}
|
|
|
|
std::forward_list<const std::string *>
|
|
GroupedFinder::find_prefix(std::string_view search_prefix) const {
|
|
const auto group = groups_.find(search_prefix.front());
|
|
if (group == groups_.cend()) {
|
|
return {};
|
|
}
|
|
|
|
const auto word_list = group->second;
|
|
const auto word_list_size = word_list.size();
|
|
|
|
const auto thread_count =
|
|
std::min<size_t>(std::thread::hardware_concurrency(), word_list_size);
|
|
|
|
forward_list<const string *> result;
|
|
mutex result_mutex;
|
|
|
|
vector<thread> search_threads;
|
|
for (size_t thread_index = 0; thread_index < thread_count; ++thread_index) {
|
|
const size_t first_index = thread_index * (word_list_size / thread_count);
|
|
|
|
const size_t last_index =
|
|
(thread_index == thread_count - 1)
|
|
? word_list_size
|
|
: (thread_index + 1) * (word_list_size / thread_count);
|
|
|
|
search_threads.emplace_back(
|
|
WordRefList::find_prefix_in_range, cref(word_list), cref(search_prefix),
|
|
first_index, last_index, ref(result), ref(result_mutex));
|
|
}
|
|
|
|
for (auto &thread : search_threads) {
|
|
thread.join();
|
|
}
|
|
|
|
return result;
|
|
}
|