Untitled
unknown
plain_text
a year ago
2.3 kB
4
Indexable
Never
std::optional<FSNodes> Folder::get_contents_recursively(const std::atomic<bool>& stop_token /= false/) const { FSNodes nodes; FSNodes local_folders; FSNodes local_files; auto formatPath = [](std::wstring_view file_name, std::wstring directory) -> std::wstring { if (directory.back() != '\\') // \ directory.append(1, '\\'); directory.append(file_name); return directory; }; WIN32_FIND_DATA findFileData; std::queue<std::wstring> tasks_pool; tasks_pool.push(m_path_); while (!tasks_pool.empty() and !stop_token) { HANDLE hFind = FindFirstFile(std::wstring(tasks_pool.front().data() + std::wstring(L"\\*")).c_str(), &findFileData); if (hFind != INVALID_HANDLE_VALUE) { do { if (std::wstring fileName = findFileData.cFileName; fileName != L"." && fileName != L".." && fileName != L"") { std::wstring formattedPath = formatPath(fileName, tasks_pool.front()); if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { tasks_pool.emplace(formattedPath); local_folders.emplace_back(std::make_unique<Folder>(std::move(formattedPath))); continue; } local_files.emplace_back(std::make_unique<File>(std::move(formattedPath))); } } while (FindNextFile(hFind, &findFileData)); } FindClose(hFind); tasks_pool.pop(); } auto fix_path = [&](auto& elem) { // just to erase the leftover * auto& acquired_path = elem->get_modifiable_path(); std::erase(acquired_path, L'*'); }; auto visit_vector = [&](auto& variant, auto& vector) { std::visit([&](auto policy){ std::for_each(policy, vector.begin(), vector.end(), fix_path); }, variant); }; bool high_elem_count = (local_folders.size() + local_files.size()) > 100'000; std::variant<std::execution::sequenced_policy, std::execution::parallel_policy> exec_policy; if (high_elem_count) exec_policy = std::execution::par; else exec_policy = std::execution::seq; visit_vector(exec_policy, local_folders); visit_vector(exec_policy, local_files); nodes.reserve(local_files.size() + local_folders.size()); nodes.insert(nodes.end(), std::make_move_iterator(local_folders.begin()), std::make_move_iterator(local_folders.end())); nodes.insert(nodes.end(), std::make_move_iterator(local_files.begin()), std::make_move_iterator(local_files.end())); return nodes; }