.. _program_listing_file_SeQuant_domain_eval_cache_manager.hpp: Program Listing for File cache_manager.hpp ========================================== |exhale_lsh| :ref:`Return to documentation for file ` (``SeQuant/domain/eval/cache_manager.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #ifndef SEQUANT_EVAL_CACHE_MANAGER_HPP #define SEQUANT_EVAL_CACHE_MANAGER_HPP #include #include #include #include #include #include #include namespace sequant { class CacheManager { public: using key_type = size_t; private: class entry { private: size_t max_life; size_t life_c; ERPtr data_p; public: explicit entry(size_t count) noexcept; [[nodiscard]] ERPtr access() noexcept; void store(ERPtr data) noexcept; void reset() noexcept; [[nodiscard]] size_t life_count() const noexcept; [[nodiscard]] size_t max_life_count() const noexcept; private: [[nodiscard]] int decay() noexcept; }; // entry static ERPtr store(entry& entry, ERPtr data) noexcept; container::map cache_map_; public: template > explicit CacheManager(Iterable1&& decaying) noexcept { for (auto&& [k, c] : decaying) cache_map_.try_emplace(k, entry{c}); } void reset() noexcept; ERPtr access(key_type key) noexcept; [[nodiscard]] ERPtr store(key_type key, ERPtr data) noexcept; [[nodiscard]] bool exists(key_type key) const noexcept; [[nodiscard]] int life(key_type key) const noexcept; [[nodiscard]] int max_life(key_type key) const noexcept; [[nodiscard]] container::set keys() const noexcept; static CacheManager empty() noexcept; // for unit testing template struct access_by; template friend struct access_by; }; // CacheManager template >> CacheManager cache_manager(NodesI const& nodes, size_t min_repeats = 2) noexcept { auto imed_counts = container::map{}; // visits a node and check if its hash value exists in imed_counts map // if it does increase the count and return false (to signal stop visiting // children nodes) otherwise returns true. auto imed_visitor = [&imed_counts](auto&& n) -> bool { auto&& end = imed_counts.end(); auto&& h = hash::value(*n); if (auto&& found = imed_counts.find(h); found != end) { ++found->second; return false; } else imed_counts.emplace(h, 1); return true; }; // imed_visitor // visit imeds ranges::for_each(nodes, [&imed_visitor](auto&& tree) { tree.visit_internal(imed_visitor); }); // remove less repeating imeds auto less_repeating = [min_repeats](auto&& pair) { return pair.second < min_repeats; }; ranges::actions::remove_if(imed_counts, less_repeating); return CacheManager{imed_counts}; } AsyCost peak_cache(Sum const& expr); } // namespace sequant #endif // SEQUANT_EVAL_CACHE_MANAGER_HPP