refactor(global_entry_data): use flat_hash_map instead of F14FastMap

The F14 map in combination with range-v3 was causing strange warning
with some versions of GCC:

```
    inlined from 'static void dwarfs::writer::internal::global_entry_data::index(map_type<std::__cxx11::basic_string<char>, unsigned int>&)' at /home/mhx/git/github/dwarfs/src/writer/internal/global_entry_data.cpp:63:51:
/usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/bits/stl_iterator_base_funcs.h:162:7: error: iteration 288230376151711743 invokes undefined behavior [-Werror=aggressive-loop-optimizations]
  162 |       while (__n--)
      |       ^~~~~
```
This commit is contained in:
Marcus Holland-Moritz 2024-12-03 21:14:08 +01:00
parent 7020b4a10d
commit 1d12e081c7
2 changed files with 22 additions and 15 deletions

View File

@ -26,7 +26,7 @@
#include <string>
#include <vector>
#include <folly/container/F14Map.h>
#include <parallel_hashmap/phmap.h>
#include <dwarfs/file_stat.h>
@ -59,10 +59,7 @@ class global_entry_data {
void add_name(std::string const& name) { names_.emplace(name, 0); }
void add_link(std::string const& link) { symlinks_.emplace(link, 0); }
void index() {
index(names_);
index(symlinks_);
}
void index();
size_t get_uid_index(uid_type uid) const;
size_t get_gid_index(gid_type gid) const;
@ -86,13 +83,11 @@ class global_entry_data {
private:
template <typename K, typename V>
using map_type = folly::F14FastMap<K, V>;
using map_type = phmap::flat_hash_map<K, V>;
template <typename T, typename U>
std::vector<T> get_vector(map_type<T, U> const& map) const;
static void index(map_type<std::string, uint32_t>& map);
template <typename T>
void add(T val, map_type<T, T>& map, T& next_index) {
if (map.emplace(val, next_index).second) {

View File

@ -30,6 +30,22 @@
namespace dwarfs::writer::internal {
namespace {
template <typename MapT>
void index_map(MapT& map) {
using mapped_type = typename MapT::mapped_type;
static_assert(std::is_integral_v<mapped_type>);
auto keys = map | ranges::views::keys | ranges::to<std::vector>;
ranges::sort(keys);
mapped_type ix{0};
for (auto& k : keys) {
map[k] = ix++;
}
}
} // namespace
template <typename T, typename U>
std::vector<T> global_entry_data::get_vector(map_type<T, U> const& map) const {
std::vector<std::pair<T, U>> pairs{map.begin(), map.end()};
@ -59,13 +75,9 @@ auto global_entry_data::get_symlinks() const -> std::vector<std::string> {
return get_vector(symlinks_);
}
void global_entry_data::index(map_type<std::string, uint32_t>& map) {
auto keys = map | ranges::views::keys | ranges::to<std::vector>;
ranges::sort(keys);
std::decay_t<decltype(map)>::mapped_type ix{0};
for (auto& k : keys) {
map[k] = ix++;
}
void global_entry_data::index() {
index_map(names_);
index_map(symlinks_);
}
uint64_t global_entry_data::get_time_offset(uint64_t time) const {