Files
Z3D/source/assets/prefetch_lookups/pose_prefetch_lookup.cpp
2024-12-22 16:58:40 +01:00

139 lines
3.2 KiB
C++

#include "assets/prefetch_lookups/pose_prefetch_lookup.hpp"
#include <algorithm>
pose_prefetch_lookup::find_directory(
const std::filesystem::path& directory
) {
const auto dir_it = m_directory_lookup.find(directory);
const auto dir_match = dir_it != m_directory_lookup.end();
auto offset = index_type{};
if (dir_match)
{
for (index_type i{}; i != dir_match; ++i)
{
offset += m_directory_indices[offset];
}
}
return { std::make_pair(dir_it, offset), dir_match };
}
std::pair<pose_prefetch_lookup::index_iterator, dynamic_pose_store::id_type> pose_prefetch_lookup::find_index(
directory_iterator directory_it,
index_type index
) {
const auto [ dir_it, dir_offset ] = directory_it;
const auto index_count = m_directory_indices[dir_offset];
const auto indices_begin = m_directory_indices.begin() + dir_offset + 1;
const auto indices_end = indices_begin + index_count;
const auto it = std::upper_bound(indices_begin, indices_end, index);
const auto is_match = it != indices_begin and *std::prev(it) == index;
auto match = dynamic_pose_store::id_type{};
if (is_match)
{
const auto dir_index = dir_it->second;
const auto id_index = it - m_directory_indices.begin() - match - dir_index;
match = m_pose_ids[id_index];
}
return { it, match };
}
pose_prefetch_lookup::directory_iterator pose_prefetch_lookup::emplace_dir(
directory_iterator directory_it,
const std::filesystem::path& directory
) {
auto [ dir_it, dir_offset ] = directory_it;
dir_it = m_directory_lookup.emplace_hint(dir_it, directory, m_directory_lookup.size());
dir_offset = m_directory_indices.size();
m_directory_indices.push_back(1);
return { dir_it, dir_offset };
}
void pose_prefetch_lookup::emplace(
const std::filesystem::path& directory,
index_type index,
dynamic_pose_store::id_type id
) {
auto [ directory_it, dir_match ] = find_directory(directory);
if (not dir_match) [[unlikely]]
{
directory_it = emplace_dir(directory_it, directory);
}
const auto [ index_it, match ] = find_index(
directory_it,
index
);
if (not match)
{
}
emplace_hint_dir_index(
directory_it,
index_it,
index,
id
);
}
void pose_prefetch_lookup::emplace_hint_dir(
directory_iterator directory_it,
const std::filesystem::path& directory,
const index_type index,
const dynamic_pose_store::id_type id
) {
directory_it = emplace_dir(directory_it, directory);
const auto [ index_it, match ] = find_index(
directory_it,
index
);
if (match) [[unlikely]]
{
const auto dir_index = dir_it->second;
const auto id_index = index_it - m_directory_indices.begin() - dir_index;
m_pose_ids[id_index] = match; // TODO I guess I should warn?!?
}
else [[likely]]
{
emplace_hint_dir_index(
directory_it,
index_it,
index,
id
);
}
}
void pose_prefetch_lookup::emplace_hint_dir_index(
directory_iterator directory_it,
index_iterator index_it,
index_type index,
const dynamic_pose_store::id_type id
) {
const auto [ dir_it, dir_offset ] = directory_it;
const auto dir_index = dir_it->second;
index_it = m_directory_indices.emplace(index_it, index);
++m_directory_indices[dir_offset];
const auto id_index = index_it - m_directory_indices.begin() - dir_index;
const auto id_it = m_pose_ids.begin() + id_index;
m_pose_ids.insert(id_it, id);
}