Cache: Allow storage modules to specify capabilites

Will be used to decide whether a LRUStorage facade is needed in front
of the actual storage or not.
This commit is contained in:
Johan Wikman 2016-11-29 13:06:46 +02:00
parent 1701979696
commit e597523c47
4 changed files with 71 additions and 20 deletions

View File

@ -55,35 +55,57 @@ typedef struct cache_key
char data[CACHE_KEY_MAXLEN];
} CACHE_KEY;
typedef enum cache_storage_capabilities
{
CACHE_STORAGE_CAP_NONE = 0x00,
CACHE_STORAGE_CAP_ST = 0x01, /*< Storage can optimize for single thread. */
CACHE_STORAGE_CAP_MT = 0x02, /*< Storage can handle multiple threads. */
CACHE_STORAGE_CAP_LRU = 0x04, /*< Storage capable of LRU eviction. */
CACHE_STORAGE_CAP_MAX_COUNT = 0x08, /*< Storage capable of capping number of entries.*/
CACHE_STORAGE_CAP_MAX_SIZE = 0x10, /*< Storage capable of capping size of cache.*/
} cache_storage_capabilities_t;
typedef struct cache_storage_api
{
/**
* Called immediately after the storage module has been loaded.
*
* @param capabilities On successful return, contains a bitmask of
* cache_storage_capabilities_t values.
* @return True if the initialization succeeded, false otherwise.
*/
bool (*initialize)();
bool (*initialize)(uint32_t* capabilities);
/**
* Creates an instance of cache storage. This function should, if necessary,
* create the actual storage, initialize it and prepare to put and get
* cache items.
*
* @param model Whether the storage will be used in a single thread or
* multi thread context. In the latter case the storage must
* perform thread synchronization as appropriate, in the former
* case it need not.
* @param name The name of the cache instance.
* @param ttl Time to live; number of seconds the value is valid.
* @param argc The number of elements in the argv array.
* @param argv Array of arguments, as passed in the `storage_options` parameter
* in the cache section in the MaxScale configuration file.
* @param model Whether the storage will be used in a single thread or
* multi thread context. In the latter case the storage must
* perform thread synchronization as appropriate, in the former
* case it need not.
* @param name The name of the cache instance.
* @param ttl Time to live; number of seconds the value is valid.
* @param max_count The maximum number of items the storage may store, before
* it should evict some items. Caller should specify 0, unless
* CACHE_STORAGE_CAP_MAX_COUNT is returned at initialization.
* @param max_count The maximum size of the storage may may occupy, before it
should evict some items. Caller should specify 0, unless
* CACHE_STORAGE_CAP_MAX_SIZE is returned at initialization.
* @param argc The number of elements in the argv array.
* @param argv Array of arguments, as passed in the `storage_options`
* parameter in the cache section in the MaxScale configuration
* file.
*
* @return A new cache instance, or NULL if the instance could not be
* created.
*/
CACHE_STORAGE* (*createInstance)(cache_thread_model_t model,
const char *name,
uint32_t ttl,
uint32_t max_count,
uint32_t max_size,
int argc, char* argv[]);
/**

View File

@ -18,20 +18,36 @@
namespace
{
bool initialize()
bool initialize(uint32_t* pCapabilities)
{
*pCapabilities = CACHE_STORAGE_CAP_MT;
return RocksDBStorage::Initialize();
}
CACHE_STORAGE* createInstance(cache_thread_model_t, // Ignored, RocksDB always MT safe.
const char* zName,
uint32_t ttl,
uint32_t maxCount,
uint32_t maxSize,
int argc, char* argv[])
{
ss_dassert(zName);
CACHE_STORAGE* pStorage = 0;
if (maxCount != 0)
{
MXS_WARNING("A maximum item count of %u specifed, although 'storage_rocksdb' "
"does not enforce such a limit.", maxCount);
}
if (maxSize != 0)
{
MXS_WARNING("A maximum size of %u specified, although 'storage_rocksdb' "
"does not enforce such a limit.", maxSize);
}
try
{
pStorage = reinterpret_cast<CACHE_STORAGE*>(RocksDBStorage::Create(zName, ttl, argc, argv));

View File

@ -26,7 +26,10 @@
namespace
{
bool open_cache_storage(const char* zName, void** pHandle, CACHE_STORAGE_API** ppApi)
bool open_cache_storage(const char* zName,
void** pHandle,
CACHE_STORAGE_API** ppApi,
uint32_t* pCapabilities)
{
bool rv = false;
@ -45,7 +48,7 @@ bool open_cache_storage(const char* zName, void** pHandle, CACHE_STORAGE_API** p
if (pApi)
{
if ((pApi->initialize)())
if ((pApi->initialize)(pCapabilities))
{
*pHandle = handle;
*ppApi = pApi;
@ -96,9 +99,12 @@ void close_cache_storage(void* handle, CACHE_STORAGE_API* pApi)
}
StorageFactory::StorageFactory(void* handle, CACHE_STORAGE_API* pApi)
StorageFactory::StorageFactory(void* handle,
CACHE_STORAGE_API* pApi,
uint32_t capabilities)
: m_handle(handle)
, m_pApi(pApi)
, m_capabilities(capabilities)
{
ss_dassert(handle);
ss_dassert(pApi);
@ -118,10 +124,11 @@ StorageFactory* StorageFactory::Open(const char* zName)
void* handle;
CACHE_STORAGE_API* pApi;
uint32_t capabilities;
if (open_cache_storage(zName, &handle, &pApi))
if (open_cache_storage(zName, &handle, &pApi, &capabilities))
{
CPP_GUARD(pFactory = new StorageFactory(handle, pApi));
CPP_GUARD(pFactory = new StorageFactory(handle, pApi, capabilities));
if (!pFactory)
{
@ -141,7 +148,12 @@ Storage* StorageFactory::createStorage(cache_thread_model_t model,
ss_dassert(m_pApi);
Storage* pStorage = 0;
CACHE_STORAGE* pRawStorage = m_pApi->createInstance(model, zName, ttl, argc, argv);
// TODO: Handle max_count and max_size.
uint32_t max_count = 0;
uint32_t max_size = 0;
CACHE_STORAGE* pRawStorage = m_pApi->createInstance(model, zName, ttl, max_count, max_size,
argc, argv);
if (pRawStorage)
{

View File

@ -32,14 +32,15 @@ public:
int argc, char* argv[]);
private:
StorageFactory(void* handle, CACHE_STORAGE_API* pApi);
StorageFactory(void* handle, CACHE_STORAGE_API* pApi, uint32_t capabilities);
StorageFactory(const StorageFactory&);
StorageFactory& operator = (const StorageFactory&);
private:
void* m_handle;
CACHE_STORAGE_API* m_pApi;
void* m_handle; /*< dl handle of storage. */
CACHE_STORAGE_API* m_pApi; /*< API of storage. */
uint32_t m_capabilities; /*< Capabilities of storage. */
};
#endif