implemented the first version of statement_cache
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
#include "matador/sql/statement_cache.hpp"
|
||||
#include "matador/sql/backend_provider.hpp"
|
||||
#include "matador/sql/error_code.hpp"
|
||||
#include "matador/sql/connection_pool.hpp"
|
||||
|
||||
namespace matador::sql {
|
||||
namespace internal {
|
||||
class statement_cache_proxy final : public statement_proxy {
|
||||
public:
|
||||
explicit statement_cache_proxy(std::unique_ptr<statement_impl>&& stmt)
|
||||
: statement_proxy(std::move(stmt)) {}
|
||||
|
||||
utils::result<size_t, utils::error> execute() override {
|
||||
return statement_->execute();
|
||||
}
|
||||
utils::result<std::unique_ptr<query_result_impl>, utils::error> fetch() override {
|
||||
return statement_->fetch();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
statement_cache::statement_cache(connection_pool &pool, const size_t max_size)
|
||||
: max_size_(max_size)
|
||||
, pool_(pool)
|
||||
, dialect_(backend_provider::instance().connection_dialect(pool_.info().type)) {}
|
||||
|
||||
utils::result<statement, utils::error> statement_cache::acquire(const query_context& ctx) {
|
||||
std::unique_lock lock(mutex_);
|
||||
// hash statement
|
||||
const auto key = std::hash<std::string>{}(ctx.sql);
|
||||
// Found in cache. Move it to of the LRU list
|
||||
if (const auto it = cache_map_.find(key); it != cache_map_.end()) {
|
||||
usage_list_.splice(usage_list_.begin(), usage_list_, it->second.second);
|
||||
return utils::ok(it->second.first);
|
||||
}
|
||||
// Prepare a new statement
|
||||
// acquire pool connection
|
||||
const auto conn = pool_.acquire();
|
||||
auto result = conn->perform_prepare(ctx);
|
||||
if (!result) {
|
||||
return utils::failure(utils::error{error_code::PREPARE_FAILED, std::string("Failed to prepare")});
|
||||
}
|
||||
|
||||
// If cache max size reached ensure space
|
||||
if (cache_map_.size() >= max_size_) {
|
||||
const size_t& lru_key = usage_list_.back();
|
||||
cache_map_.erase(lru_key);
|
||||
usage_list_.pop_back();
|
||||
}
|
||||
|
||||
usage_list_.push_front(key);
|
||||
const auto it = cache_map_.insert({
|
||||
key,
|
||||
std::make_pair(statement{
|
||||
std::make_shared<internal::statement_cache_proxy>(result.release())},
|
||||
usage_list_.begin())
|
||||
}).first;
|
||||
|
||||
return utils::ok(it->second.first);
|
||||
}
|
||||
|
||||
size_t statement_cache::size() const {
|
||||
return cache_map_.size();
|
||||
}
|
||||
size_t statement_cache::capacity() const {
|
||||
return max_size_;
|
||||
}
|
||||
|
||||
bool statement_cache::empty() const {
|
||||
return cache_map_.empty();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user