Untitled
unknown
plain_text
2 years ago
2.3 kB
8
Indexable
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;
}Editor is loading...