#ifndef STATEMENT_CACHE_HPP #define STATEMENT_CACHE_HPP #include "matador/sql/executor.hpp" #include "matador/sql/statement.hpp" #include "matador/utils/message_bus.hpp" #include #include #include namespace matador::sql { class connection_pool; struct statement_event { std::string sql{}; std::chrono::steady_clock::time_point timestamp{}; }; struct statement_accessed_event : statement_event {}; struct statement_added_event : statement_event {}; struct statement_evicted_event : statement_event {}; struct statement_lock_failed_event : statement_event { std::chrono::nanoseconds duration{}; }; struct statement_lock_acquired_event : statement_event { std::chrono::nanoseconds duration{}; }; struct statement_execution_event : statement_event { std::chrono::nanoseconds duration{}; }; struct statement_cache_config { size_t max_size; }; class statement_cache final { private: using list_iterator = std::list::iterator; struct cache_entry { statement stmt; std::chrono::steady_clock::time_point last_access; list_iterator position; }; public: statement_cache(utils::message_bus &bus, connection_pool &pool, size_t max_size = 50); statement_cache(const statement_cache &) = delete; statement_cache &operator=(const statement_cache &) = delete; statement_cache(statement_cache &&) = delete; statement_cache &operator=(statement_cache &&) = delete; ~statement_cache() = default; [[nodiscard]] utils::result acquire(const query_context &ctx); [[nodiscard]] size_t size() const; [[nodiscard]] size_t capacity() const; [[nodiscard]] bool empty() const; template utils::subscription subscribe(std::function handler) { return bus_.subscribe(handler); } connection_pool& pool() const; private: size_t max_size_{}; std::list usage_list_; // LRU: front = most recent, back = least recent std::unordered_map cache_map_; std::mutex mutex_; connection_pool &pool_; const sql::dialect &dialect_; utils::message_bus &bus_; }; } #endif //STATEMENT_CACHE_HPP