#include "assets/prefetch_lookups/pose_prefetch_lookup.hpp" #include 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::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); } emplace_hint_dir( directory_it, index, id ); } void pose_prefetch_lookup::emplace_hint_dir( directory_iterator directory_it, const index_type index, const dynamic_pose_store::id_type id ) { const auto [ index_it, match ] = find_index( directory_it, index ); if (match) [[unlikely]] { const auto dir_index = directory_it.first->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); }