3#include <boost/asio/use_awaitable.hpp>
7#include <unordered_map>
9namespace asio = boost::asio;
13using Clock = std::chrono::steady_clock;
20class MemoryStore final :
public Haio::Cdn::CacheStore {
22 MemoryStore(
size_t maxUsage, std::chrono::seconds ttl) : maxUsage_(maxUsage), ttl_(ttl) {}
24 asio::awaitable<std::optional<Haio::Cdn::CacheEntry>> get(
const std::string& key)
override {
25 const auto found = index_.find(key);
26 if (found == index_.end())
co_return std::nullopt;
28 if (Clock::now() >= found->second->storedUntil) {
30 co_return std::nullopt;
34 order_.splice(order_.begin(), order_, found->second);
35 found->second->storedUntil = Clock::now() + ttl_;
36 co_return found->second->entry;
39 asio::awaitable<void> put(
const std::string& key,
const Haio::Cdn::CacheEntry& entry)
override {
40 const auto size =
sizeOf(entry);
41 if (size > maxUsage_)
co_return;
43 if (
const auto found = index_.find(key); found != index_.end()) drop(found);
45 order_.push_front(Node{key, entry, Clock::now() + ttl_, size});
46 index_.emplace(key, order_.begin());
49 while (held_ > maxUsage_ && !order_.empty()) {
50 const auto last = std::prev(order_.end());
52 index_.erase(last->key);
61 Haio::Cdn::CacheEntry entry;
62 Clock::time_point storedUntil;
66 static size_t sizeOf(
const Haio::Cdn::CacheEntry& entry) {
70 void drop(std::unordered_map<std::string, std::list<Node>::iterator>::iterator found) {
71 held_ -= found->second->size;
72 order_.erase(found->second);
77 std::chrono::seconds ttl_;
79 std::list<Node> order_;
80 std::unordered_map<std::string, std::list<Node>::iterator> index_;
87std::unique_ptr<CacheStore>
makeMemoryStore(
size_t maxUsage, std::chrono::seconds ttl) {
88 return std::make_unique<MemoryStore>(maxUsage, ttl);
std::vector< uint8_t > data
std::unique_ptr< CacheStore > makeMemoryStore(size_t maxUsage, std::chrono::seconds ttl)
Result< size_t > sizeOf(Color color, Size size)