139 lines
3.2 KiB
C++
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);
|
|
} |