#ifndef STATEMENT_CACHE_HPP #define STATEMENT_CACHE_HPP #include "matador/sql/executor.hpp" #include "matador/sql/statement.hpp" #include #include #include namespace matador::sql { class connection_pool; struct statement_cache_event { enum class Type { Accessed, Added, Evicted }; Type type; std::string sql; std::chrono::steady_clock::time_point timestamp; }; class statement_cache_observer_interface { public: virtual void on_event(const statement_cache_event&) = 0; virtual ~statement_cache_observer_interface() = default; }; 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: explicit statement_cache(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; void subscribe(statement_cache_observer_interface &observer); private: void push(statement_cache_event::Type type, const std::string& sql) 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_; std::vector observers_; }; } #endif //STATEMENT_CACHE_HPP