#pragma once #include "time.hpp" #include namespace llarp::util { template > struct DecayingHashTable { DecayingHashTable(std::chrono::milliseconds cacheInterval = 1h) : m_CacheInterval(cacheInterval) {} void Decay(llarp_time_t now) { EraseIf([&](const auto& item) { return item.second.second + m_CacheInterval <= now; }); } /// return if we have this value by key bool Has(const Key_t& k) const { return m_Values.find(k) != m_Values.end(); } /// return true if inserted /// return false if not inserted bool Put(Key_t key, Value_t value, llarp_time_t now = 0s) { if (now == 0s) now = llarp::time_now_ms(); return m_Values.try_emplace(std::move(key), std::make_pair(std::move(value), now)).second; } /// get value by key std::optional Get(Key_t k) const { const auto itr = m_Values.find(k); if (itr == m_Values.end()) return std::nullopt; return itr->second.first; } /// explicit remove an item from the cache by key void Remove(const Key_t& key) { m_Values.erase(key); } private: template void EraseIf(Predicate_t pred) { for (auto i = m_Values.begin(), last = m_Values.end(); i != last;) { if (pred(*i)) { i = m_Values.erase(i); } else { ++i; } } } llarp_time_t m_CacheInterval; std::unordered_map, Hash_t> m_Values; }; } // namespace llarp::util