Cache: Add LRU storage
The LRUStorage hierarchy implements the decorator pattern and is capable of providing LRU behaviour to any underlying storage. There are two concrete classes - LRUStorageST and LRUStorageMT - that can be used in single thread and multiple thread contentx, respectively. Also tests the convention of placing _ as suffix on member variables.
This commit is contained in:
17
server/modules/filter/cache/CMakeLists.txt
vendored
17
server/modules/filter/cache/CMakeLists.txt
vendored
@ -1,5 +1,20 @@
|
|||||||
if (JANSSON_FOUND)
|
if (JANSSON_FOUND)
|
||||||
add_library(cache SHARED cache.cc cachefilter.cc cachemt.cc cachept.cc cachesimple.cc cachest.cc rules.cc sessioncache.cc storage.cc storagefactory.cc storagereal.cc)
|
add_library(cache SHARED
|
||||||
|
cache.cc
|
||||||
|
cachefilter.cc
|
||||||
|
cachemt.cc
|
||||||
|
cachept.cc
|
||||||
|
cachesimple.cc
|
||||||
|
cachest.cc
|
||||||
|
lrustorage.cc
|
||||||
|
lrustoragemt.cc
|
||||||
|
lrustoragest.cc
|
||||||
|
rules.cc
|
||||||
|
sessioncache.cc
|
||||||
|
storage.cc
|
||||||
|
storagefactory.cc
|
||||||
|
storagereal.cc
|
||||||
|
)
|
||||||
target_link_libraries(cache maxscale-common jansson)
|
target_link_libraries(cache maxscale-common jansson)
|
||||||
set_target_properties(cache PROPERTIES VERSION "1.0.0")
|
set_target_properties(cache PROPERTIES VERSION "1.0.0")
|
||||||
set_target_properties(cache PROPERTIES LINK_FLAGS -Wl,-z,defs)
|
set_target_properties(cache PROPERTIES LINK_FLAGS -Wl,-z,defs)
|
||||||
|
|||||||
314
server/modules/filter/cache/lrustorage.cc
vendored
Normal file
314
server/modules/filter/cache/lrustorage.cc
vendored
Normal file
@ -0,0 +1,314 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||||
|
*
|
||||||
|
* Use of this software is governed by the Business Source License included
|
||||||
|
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||||
|
*
|
||||||
|
* Change Date: 2019-07-01
|
||||||
|
*
|
||||||
|
* On the date above, in accordance with the Business Source License, use
|
||||||
|
* of this software will be governed by version 2 or later of the General
|
||||||
|
* Public License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lrustorage.h"
|
||||||
|
|
||||||
|
|
||||||
|
LRUStorage::LRUStorage(Storage* pstorage, size_t max_count, size_t max_size)
|
||||||
|
: pstorage_(pstorage)
|
||||||
|
, max_count_(max_count)
|
||||||
|
, max_size_(max_size)
|
||||||
|
, count_(0)
|
||||||
|
, size_(0)
|
||||||
|
, phead_(NULL)
|
||||||
|
, ptail_(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
LRUStorage::~LRUStorage()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
cache_result_t LRUStorage::get_key(const char* zdefault_db,
|
||||||
|
const GWBUF* pquery,
|
||||||
|
CACHE_KEY* pkey)
|
||||||
|
{
|
||||||
|
return pstorage_->get_key(zdefault_db, pquery, pkey);
|
||||||
|
}
|
||||||
|
|
||||||
|
cache_result_t LRUStorage::do_get_value(const CACHE_KEY& key,
|
||||||
|
uint32_t flags,
|
||||||
|
GWBUF** ppvalue)
|
||||||
|
{
|
||||||
|
NodesPerKey::iterator i = nodes_per_key_.find(key);
|
||||||
|
bool existed = (i != nodes_per_key_.end());
|
||||||
|
|
||||||
|
cache_result_t result = pstorage_->get_value(key, flags, ppvalue);
|
||||||
|
|
||||||
|
if (result == CACHE_RESULT_OK)
|
||||||
|
{
|
||||||
|
if (existed)
|
||||||
|
{
|
||||||
|
if (ptail_ == i->second)
|
||||||
|
{
|
||||||
|
ptail_ = i->second->next();
|
||||||
|
}
|
||||||
|
|
||||||
|
phead_ = i->second->prepend(phead_);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MXS_ERROR("Item found in storage, but not in key mapping.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
cache_result_t LRUStorage::do_put_value(const CACHE_KEY& key,
|
||||||
|
const GWBUF* pvalue)
|
||||||
|
{
|
||||||
|
cache_result_t result = CACHE_RESULT_ERROR;
|
||||||
|
|
||||||
|
size_t value_size = GWBUF_LENGTH(pvalue);
|
||||||
|
size_t new_size = size_ + value_size;
|
||||||
|
|
||||||
|
Node* pnode = NULL;
|
||||||
|
|
||||||
|
NodesPerKey::iterator i = nodes_per_key_.find(key);
|
||||||
|
bool existed = (i != nodes_per_key_.end());
|
||||||
|
|
||||||
|
if (existed)
|
||||||
|
{
|
||||||
|
// TODO: Also in this case max_size_ needs to be honoured.
|
||||||
|
pnode = i->second;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((new_size > max_size_) || (count_ == max_count_))
|
||||||
|
{
|
||||||
|
if (new_size > max_size_)
|
||||||
|
{
|
||||||
|
MXS_NOTICE("New size %lu > max size %lu. Removing least recently used.",
|
||||||
|
new_size, max_size_);
|
||||||
|
|
||||||
|
pnode = free_lru(value_size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ss_dassert(count_ == max_count_);
|
||||||
|
MXS_NOTICE("Max count %lu reached, removing least recently used.", max_count_);
|
||||||
|
pnode = free_lru();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pnode = new (std::nothrow) Node;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pnode)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
std::pair<NodesPerKey::iterator, bool>
|
||||||
|
rv = nodes_per_key_.insert(std::make_pair(key, pnode));
|
||||||
|
ss_dassert(rv.second);
|
||||||
|
|
||||||
|
i = rv.first;
|
||||||
|
}
|
||||||
|
catch (const std::exception& x)
|
||||||
|
{
|
||||||
|
delete pnode;
|
||||||
|
pnode = NULL;
|
||||||
|
result = CACHE_RESULT_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pnode)
|
||||||
|
{
|
||||||
|
result = pstorage_->put_value(key, pvalue);
|
||||||
|
|
||||||
|
if (result == CACHE_RESULT_OK)
|
||||||
|
{
|
||||||
|
if (existed)
|
||||||
|
{
|
||||||
|
size_ -= pnode->size();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++count_;
|
||||||
|
}
|
||||||
|
|
||||||
|
pnode->reset(&i->first, value_size);
|
||||||
|
size_ += pnode->size();
|
||||||
|
|
||||||
|
if (ptail_ == pnode)
|
||||||
|
{
|
||||||
|
ptail_ = pnode->prev();
|
||||||
|
}
|
||||||
|
|
||||||
|
phead_ = pnode->prepend(phead_);
|
||||||
|
|
||||||
|
if (!ptail_)
|
||||||
|
{
|
||||||
|
ptail_ = phead_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!existed)
|
||||||
|
{
|
||||||
|
MXS_ERROR("Could not put a value to the storage.");
|
||||||
|
nodes_per_key_.erase(i);
|
||||||
|
delete pnode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
cache_result_t LRUStorage::do_del_value(const CACHE_KEY& key)
|
||||||
|
{
|
||||||
|
NodesPerKey::iterator i = nodes_per_key_.find(key);
|
||||||
|
|
||||||
|
cache_result_t result = pstorage_->del_value(key);
|
||||||
|
|
||||||
|
if (result == CACHE_RESULT_OK)
|
||||||
|
{
|
||||||
|
if (i == nodes_per_key_.end())
|
||||||
|
{
|
||||||
|
Node* pnode = i->second;
|
||||||
|
|
||||||
|
ss_dassert(size_ > pnode->size());
|
||||||
|
ss_dassert(count_ > 0);
|
||||||
|
|
||||||
|
size_ -= pnode->size();
|
||||||
|
--count_;
|
||||||
|
|
||||||
|
phead_ = pnode->remove();
|
||||||
|
delete pnode;
|
||||||
|
|
||||||
|
if (!phead_)
|
||||||
|
{
|
||||||
|
ptail_ = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
nodes_per_key_.erase(i);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MXS_ERROR("Key was found from storage, but not from LRU register.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free the data associated with the least recently used node.
|
||||||
|
*
|
||||||
|
* @return The node itself, for reuse.
|
||||||
|
*/
|
||||||
|
LRUStorage::Node* LRUStorage::free_lru()
|
||||||
|
{
|
||||||
|
ss_dassert(ptail_);
|
||||||
|
|
||||||
|
Node* pnode = NULL;
|
||||||
|
|
||||||
|
if (free_node_data(ptail_))
|
||||||
|
{
|
||||||
|
pnode = ptail_;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pnode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free the data associated with sufficient number of least recently used nodes,
|
||||||
|
* to make the required space available.
|
||||||
|
*
|
||||||
|
* @return The last node whose data was freed, for reuse.
|
||||||
|
*/
|
||||||
|
LRUStorage::Node* LRUStorage::free_lru(size_t needed_space)
|
||||||
|
{
|
||||||
|
Node* pnode = NULL;
|
||||||
|
|
||||||
|
size_t freed_space = 0;
|
||||||
|
bool error = false;
|
||||||
|
|
||||||
|
while (!error && ptail_ && (freed_space < needed_space))
|
||||||
|
{
|
||||||
|
size_t size = ptail_->size();
|
||||||
|
|
||||||
|
if (free_node_data(ptail_))
|
||||||
|
{
|
||||||
|
freed_space += size;
|
||||||
|
|
||||||
|
pnode = ptail_;
|
||||||
|
ptail_ = ptail_->remove();
|
||||||
|
|
||||||
|
if (freed_space < needed_space)
|
||||||
|
{
|
||||||
|
delete pnode;
|
||||||
|
pnode = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pnode)
|
||||||
|
{
|
||||||
|
pnode->reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
return pnode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free the data associated with a node.
|
||||||
|
*
|
||||||
|
* @return True, if the data could be freed, false otherwise.
|
||||||
|
*/
|
||||||
|
bool LRUStorage::free_node_data(Node* pnode)
|
||||||
|
{
|
||||||
|
bool success = true;
|
||||||
|
|
||||||
|
const CACHE_KEY* pkey = pnode->key();
|
||||||
|
ss_dassert(pkey);
|
||||||
|
|
||||||
|
NodesPerKey::iterator i = nodes_per_key_.find(*pkey);
|
||||||
|
|
||||||
|
if (i != nodes_per_key_.end())
|
||||||
|
{
|
||||||
|
MXS_ERROR("Item in LRU list was not found in key mapping.");
|
||||||
|
}
|
||||||
|
|
||||||
|
cache_result_t result = pstorage_->del_value(*pkey);
|
||||||
|
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
case CACHE_RESULT_NOT_FOUND:
|
||||||
|
MXS_ERROR("Item in LRU list was not found in storage.");
|
||||||
|
case CACHE_RESULT_OK:
|
||||||
|
if (i != nodes_per_key_.end())
|
||||||
|
{
|
||||||
|
nodes_per_key_.erase(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
ss_dassert(size_ >= pnode->size());
|
||||||
|
ss_dassert(count_ > 0);
|
||||||
|
|
||||||
|
size_ -= pnode->size();
|
||||||
|
count_ -= 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
MXS_ERROR("Could not remove value from storage, cannot "
|
||||||
|
"remove from LRU list or key mapping either.");
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
177
server/modules/filter/cache/lrustorage.h
vendored
Normal file
177
server/modules/filter/cache/lrustorage.h
vendored
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
#pragma once
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||||
|
*
|
||||||
|
* Use of this software is governed by the Business Source License included
|
||||||
|
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||||
|
*
|
||||||
|
* Change Date: 2019-07-01
|
||||||
|
*
|
||||||
|
* On the date above, in accordance with the Business Source License, use
|
||||||
|
* of this software will be governed by version 2 or later of the General
|
||||||
|
* Public License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <maxscale/cdefs.h>
|
||||||
|
#include <tr1/unordered_map>
|
||||||
|
#include "storage.h"
|
||||||
|
#include "cachefilter.h"
|
||||||
|
|
||||||
|
class LRUStorage : public Storage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~LRUStorage();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Storage::get_key
|
||||||
|
*/
|
||||||
|
cache_result_t get_key(const char* zDefaultDb,
|
||||||
|
const GWBUF* pQuery,
|
||||||
|
CACHE_KEY* pKey);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
LRUStorage(Storage* pstorage, size_t max_count, size_t max_size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches the value from the underlying storage and, if found, moves the
|
||||||
|
* entry to the top of the LRU list.
|
||||||
|
*
|
||||||
|
* @see Storage::get_value
|
||||||
|
*/
|
||||||
|
cache_result_t do_get_value(const CACHE_KEY& key,
|
||||||
|
uint32_t flags,
|
||||||
|
GWBUF** ppValue);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the value to the underlying storage and, if successful, either
|
||||||
|
* places the entry at or moves the existing entry to the top of the LRU
|
||||||
|
* list.
|
||||||
|
*
|
||||||
|
* @see Storage::put_value
|
||||||
|
*/
|
||||||
|
cache_result_t do_put_value(const CACHE_KEY& key,
|
||||||
|
const GWBUF* pValue);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes the value from the underlying storage and, if successful, removes
|
||||||
|
* the entry from the LRU list.
|
||||||
|
*
|
||||||
|
* @see Storage::del_value
|
||||||
|
*/
|
||||||
|
cache_result_t do_del_value(const CACHE_KEY& key);
|
||||||
|
|
||||||
|
private:
|
||||||
|
LRUStorage(const LRUStorage&);
|
||||||
|
LRUStorage& operator = (const LRUStorage&);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Node class is used for maintaining LRU information.
|
||||||
|
*/
|
||||||
|
class Node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Node()
|
||||||
|
: pkey_(NULL)
|
||||||
|
, size_(0)
|
||||||
|
, pnext_(NULL)
|
||||||
|
, pprev_(NULL)
|
||||||
|
{}
|
||||||
|
~Node()
|
||||||
|
{
|
||||||
|
if (pnext_)
|
||||||
|
{
|
||||||
|
pnext_->pprev_ = pprev_;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pprev_)
|
||||||
|
{
|
||||||
|
pprev_->pnext_ = pnext_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const CACHE_KEY* key() const { return pkey_; }
|
||||||
|
size_t size() const { return size_; }
|
||||||
|
Node* next() const { return pnext_; }
|
||||||
|
Node* prev() const { return pprev_; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move the node before the node provided as argument.
|
||||||
|
*
|
||||||
|
* @param pnode The node in front of which this should be moved.
|
||||||
|
* @return This node.
|
||||||
|
*/
|
||||||
|
Node* prepend(Node* pnode)
|
||||||
|
{
|
||||||
|
if (pnode)
|
||||||
|
{
|
||||||
|
if (pprev_)
|
||||||
|
{
|
||||||
|
pprev_->pnext_ = pnext_;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pnext_)
|
||||||
|
{
|
||||||
|
pnext_->pprev_ = pprev_;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pnode->pprev_)
|
||||||
|
{
|
||||||
|
pnode->pprev_->pnext_ = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
pnode->pprev_ = this;
|
||||||
|
pnext_ = pnode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove this node from the list.
|
||||||
|
*
|
||||||
|
* @return The previous node if there is one, or the next node.
|
||||||
|
*/
|
||||||
|
Node* remove()
|
||||||
|
{
|
||||||
|
if (pprev_)
|
||||||
|
{
|
||||||
|
pprev_->pnext_ = pnext_;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pnext_)
|
||||||
|
{
|
||||||
|
pnext_->pprev_ = pprev_;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pprev_ ? pprev_ : pnext_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset(const CACHE_KEY* pkey = NULL, size_t size = 0)
|
||||||
|
{
|
||||||
|
pkey_ = pkey;
|
||||||
|
size_ = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const CACHE_KEY* pkey_; /*< Points at the key stored in nodes_per_key_ below. */
|
||||||
|
size_t size_; /*< The size of the data referred to by pkey_. */
|
||||||
|
Node* pnext_; /*< The next node in the LRU list. */
|
||||||
|
Node* pprev_; /*< The previous node in the LRU list. */
|
||||||
|
};
|
||||||
|
|
||||||
|
Node* free_lru();
|
||||||
|
Node* free_lru(size_t space);
|
||||||
|
bool free_node_data(Node* pnode);
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef std::tr1::unordered_map<CACHE_KEY, Node*> NodesPerKey;
|
||||||
|
|
||||||
|
Storage* pstorage_; /*< The actual storage. */
|
||||||
|
size_t max_count_; /*< The maximum number of items in the LRU list, */
|
||||||
|
size_t max_size_; /*< The maximum size of all cached items. */
|
||||||
|
size_t count_; /*< The current count of cached items. */
|
||||||
|
size_t size_; /*< The current size of all cached items. */
|
||||||
|
NodesPerKey nodes_per_key_; /*< Mapping from cache keys to corresponding Node. */
|
||||||
|
Node* phead_; /*< The node at the LRU list. */
|
||||||
|
Node* ptail_; /*< The node at bottom of the LRU list.*/
|
||||||
|
};
|
||||||
63
server/modules/filter/cache/lrustoragemt.cc
vendored
Normal file
63
server/modules/filter/cache/lrustoragemt.cc
vendored
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||||
|
*
|
||||||
|
* Use of this software is governed by the Business Source License included
|
||||||
|
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||||
|
*
|
||||||
|
* Change Date: 2019-07-01
|
||||||
|
*
|
||||||
|
* On the date above, in accordance with the Business Source License, use
|
||||||
|
* of this software will be governed by version 2 or later of the General
|
||||||
|
* Public License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lrustoragemt.h"
|
||||||
|
|
||||||
|
LRUStorageMT::LRUStorageMT(Storage* pstorage, size_t max_count, size_t max_size)
|
||||||
|
: LRUStorage(pstorage, max_count, max_size)
|
||||||
|
{
|
||||||
|
spinlock_init(&lock_);
|
||||||
|
}
|
||||||
|
|
||||||
|
LRUStorageMT::~LRUStorageMT()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
LRUStorageMT* LRUStorageMT::create(Storage* pstorage, size_t max_count, size_t max_size)
|
||||||
|
{
|
||||||
|
LRUStorageMT* plru_storage = NULL;
|
||||||
|
|
||||||
|
CPP_GUARD(plru_storage = new LRUStorageMT(pstorage, max_count, max_size));
|
||||||
|
|
||||||
|
return plru_storage;
|
||||||
|
}
|
||||||
|
|
||||||
|
cache_result_t LRUStorageMT::get_value(const CACHE_KEY& key,
|
||||||
|
uint32_t flags,
|
||||||
|
GWBUF** ppvalue)
|
||||||
|
{
|
||||||
|
spinlock_acquire(&lock_);
|
||||||
|
cache_result_t rv = LRUStorage::do_get_value(key, flags, ppvalue);
|
||||||
|
spinlock_release(&lock_);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
cache_result_t LRUStorageMT::put_value(const CACHE_KEY& key,
|
||||||
|
const GWBUF* pvalue)
|
||||||
|
{
|
||||||
|
spinlock_acquire(&lock_);
|
||||||
|
cache_result_t rv = LRUStorage::do_put_value(key, pvalue);
|
||||||
|
spinlock_release(&lock_);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
cache_result_t LRUStorageMT::del_value(const CACHE_KEY& key)
|
||||||
|
{
|
||||||
|
spinlock_acquire(&lock_);
|
||||||
|
cache_result_t rv = LRUStorage::do_del_value(key);
|
||||||
|
spinlock_release(&lock_);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
43
server/modules/filter/cache/lrustoragemt.h
vendored
Normal file
43
server/modules/filter/cache/lrustoragemt.h
vendored
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#pragma once
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||||
|
*
|
||||||
|
* Use of this software is governed by the Business Source License included
|
||||||
|
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||||
|
*
|
||||||
|
* Change Date: 2019-07-01
|
||||||
|
*
|
||||||
|
* On the date above, in accordance with the Business Source License, use
|
||||||
|
* of this software will be governed by version 2 or later of the General
|
||||||
|
* Public License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <maxscale/cdefs.h>
|
||||||
|
#include <maxscale/spinlock.h>
|
||||||
|
#include "lrustorage.h"
|
||||||
|
|
||||||
|
class LRUStorageMT : public LRUStorage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~LRUStorageMT();
|
||||||
|
|
||||||
|
LRUStorageMT* create(Storage* pstorage, size_t max_count, size_t max_size);
|
||||||
|
|
||||||
|
cache_result_t get_value(const CACHE_KEY& key,
|
||||||
|
uint32_t flags,
|
||||||
|
GWBUF** ppvalue);
|
||||||
|
|
||||||
|
cache_result_t put_value(const CACHE_KEY& key,
|
||||||
|
const GWBUF* pvalue);
|
||||||
|
|
||||||
|
cache_result_t del_value(const CACHE_KEY& key);
|
||||||
|
|
||||||
|
private:
|
||||||
|
LRUStorageMT(Storage* pstorage, size_t max_count, size_t max_size);
|
||||||
|
|
||||||
|
LRUStorageMT(const LRUStorageMT&);
|
||||||
|
LRUStorageMT& operator = (const LRUStorageMT&);
|
||||||
|
|
||||||
|
private:
|
||||||
|
SPINLOCK lock_;
|
||||||
|
};
|
||||||
50
server/modules/filter/cache/lrustoragest.cc
vendored
Normal file
50
server/modules/filter/cache/lrustoragest.cc
vendored
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||||
|
*
|
||||||
|
* Use of this software is governed by the Business Source License included
|
||||||
|
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||||
|
*
|
||||||
|
* Change Date: 2019-07-01
|
||||||
|
*
|
||||||
|
* On the date above, in accordance with the Business Source License, use
|
||||||
|
* of this software will be governed by version 2 or later of the General
|
||||||
|
* Public License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lrustoragest.h"
|
||||||
|
|
||||||
|
LRUStorageST::LRUStorageST(Storage* pstorage, size_t max_count, size_t max_size)
|
||||||
|
: LRUStorage(pstorage, max_count, max_size)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
LRUStorageST::~LRUStorageST()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
LRUStorageST* LRUStorageST::create(Storage* pstorage, size_t max_count, size_t max_size)
|
||||||
|
{
|
||||||
|
LRUStorageST* plru_storage = NULL;
|
||||||
|
|
||||||
|
CPP_GUARD(plru_storage = new LRUStorageST(pstorage, max_count, max_size));
|
||||||
|
|
||||||
|
return plru_storage;
|
||||||
|
}
|
||||||
|
|
||||||
|
cache_result_t LRUStorageST::get_value(const CACHE_KEY& key,
|
||||||
|
uint32_t flags,
|
||||||
|
GWBUF** ppvalue)
|
||||||
|
{
|
||||||
|
return LRUStorage::do_get_value(key, flags, ppvalue);
|
||||||
|
}
|
||||||
|
|
||||||
|
cache_result_t LRUStorageST::put_value(const CACHE_KEY& key,
|
||||||
|
const GWBUF* pvalue)
|
||||||
|
{
|
||||||
|
return LRUStorage::do_put_value(key, pvalue);
|
||||||
|
}
|
||||||
|
|
||||||
|
cache_result_t LRUStorageST::del_value(const CACHE_KEY& key)
|
||||||
|
{
|
||||||
|
return LRUStorage::do_del_value(key);
|
||||||
|
}
|
||||||
39
server/modules/filter/cache/lrustoragest.h
vendored
Normal file
39
server/modules/filter/cache/lrustoragest.h
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#pragma once
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016 MariaDB Corporation Ab
|
||||||
|
*
|
||||||
|
* Use of this software is governed by the Business Source License included
|
||||||
|
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
||||||
|
*
|
||||||
|
* Change Date: 2019-07-01
|
||||||
|
*
|
||||||
|
* On the date above, in accordance with the Business Source License, use
|
||||||
|
* of this software will be governed by version 2 or later of the General
|
||||||
|
* Public License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <maxscale/cdefs.h>
|
||||||
|
#include "lrustorage.h"
|
||||||
|
|
||||||
|
class LRUStorageST : public LRUStorage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~LRUStorageST();
|
||||||
|
|
||||||
|
LRUStorageST* create(Storage* pstorage, size_t max_count, size_t max_size);
|
||||||
|
|
||||||
|
cache_result_t get_value(const CACHE_KEY& key,
|
||||||
|
uint32_t flags,
|
||||||
|
GWBUF** ppValue);
|
||||||
|
|
||||||
|
cache_result_t put_value(const CACHE_KEY& key,
|
||||||
|
const GWBUF* pValue);
|
||||||
|
|
||||||
|
cache_result_t del_value(const CACHE_KEY& key);
|
||||||
|
|
||||||
|
private:
|
||||||
|
LRUStorageST(Storage* pstorage, size_t max_count, size_t max_size);
|
||||||
|
|
||||||
|
LRUStorageST(const LRUStorageST&);
|
||||||
|
LRUStorageST& operator = (const LRUStorageST&);
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user