Skip to content

Commit

Permalink
refactor: Use unordered_map in macro cache
Browse files Browse the repository at this point in the history
  • Loading branch information
slavek-kucera authored May 21, 2024
1 parent a888343 commit ad0c447
Showing 1 changed file with 49 additions and 16 deletions.
65 changes: 49 additions & 16 deletions parser_library/src/workspaces/macro_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@
#ifndef HLASMPLUGIN_PARSERLIBRARY_MACRO_CACHE_H
#define HLASMPLUGIN_PARSERLIBRARY_MACRO_CACHE_H

#include <compare>
#include <map>
#include <memory>
#include <optional>
#include <unordered_map>
#include <variant>
#include <vector>

#include "context/copy_member.h"
#include "context/id_index.h"
#include "lsp/macro_info.h"
#include "protocol.h"
#include "utils/general_hashers.h"

namespace hlasm_plugin::parser_library {
class analyzer;
Expand All @@ -34,6 +34,23 @@ struct analyzing_context;
namespace hlasm_plugin::parser_library::context {
class hlasm_context;
} // namespace hlasm_plugin::parser_library::context
namespace hlasm_plugin::parser_library::workspaces {
struct cached_opsyn_mnemo;
struct macro_cache_key;
} // namespace hlasm_plugin::parser_library::workspaces

template<>
struct std::hash<hlasm_plugin::parser_library::workspaces::cached_opsyn_mnemo>
{
std::size_t operator()(const hlasm_plugin::parser_library::workspaces::cached_opsyn_mnemo& e) const noexcept;
};

template<>
struct std::hash<hlasm_plugin::parser_library::workspaces::macro_cache_key>
{
std::size_t operator()(const hlasm_plugin::parser_library::workspaces::macro_cache_key& key) const noexcept;
};


namespace hlasm_plugin::parser_library::workspaces {

Expand All @@ -46,7 +63,15 @@ struct cached_opsyn_mnemo
context::id_index to_instr;
bool is_macro;

constexpr auto operator<=>(const cached_opsyn_mnemo&) const = default;
constexpr bool operator==(const cached_opsyn_mnemo&) const noexcept = default;

std::size_t hash() const noexcept
{
using utils::hashers::hash_combine;
const auto f = std::hash<context::id_index>()(from_instr);
const auto t = std::hash<context::id_index>()(to_instr);
return hash_combine(hash_combine(t, f), is_macro);
}
};

// Contains all the context that affects parsing an external file (macro or copy member)
Expand All @@ -62,19 +87,16 @@ struct macro_cache_key
std::vector<cached_opsyn_mnemo> opsyn_state;

bool operator==(const macro_cache_key&) const = default;
auto operator<=>(const macro_cache_key& o) const

size_t hash() const noexcept
{
if (auto c = kind <=> o.kind; c != 0)
return c;
if (auto c = name <=> o.name; c != 0)
return c;
if (auto c = opsyn_state.size() <=> o.opsyn_state.size(); c != 0)
return c;
// libc++ still does not support <=> for vector or lexicographical_compare_three_way
for (auto l = opsyn_state.begin(), r = o.opsyn_state.begin(); l != opsyn_state.end(); ++l, ++r)
if (auto c = *l <=> *r; c != 0)
return c;
return std::strong_ordering::equal;
using utils::hashers::hash_combine;
auto h = hash_combine(std::hash<context::id_index>()(name), (size_t)kind);

for (const auto& e : opsyn_state)
h = hash_combine(h, std::hash<cached_opsyn_mnemo>()(e));

return h;
}
};

Expand All @@ -93,7 +115,7 @@ struct macro_cache_data
// Macro cache is tied to a specific id_storage
class macro_cache final
{
std::map<macro_cache_key, macro_cache_data> cache_;
std::unordered_map<macro_cache_key, macro_cache_data> cache_;
const file_manager* file_mngr_;
std::shared_ptr<file> macro_file_;

Expand All @@ -112,5 +134,16 @@ class macro_cache final

} // namespace hlasm_plugin::parser_library::workspaces

inline std::size_t std::hash<hlasm_plugin::parser_library::workspaces::cached_opsyn_mnemo>::operator()(
const hlasm_plugin::parser_library::workspaces::cached_opsyn_mnemo& e) const noexcept
{
return e.hash();
}

inline std::size_t std::hash<hlasm_plugin::parser_library::workspaces::macro_cache_key>::operator()(
const hlasm_plugin::parser_library::workspaces::macro_cache_key& key) const noexcept
{
return key.hash();
}

#endif

0 comments on commit ad0c447

Please sign in to comment.