diff --git a/server/modules/filter/cache/storagefactory.cc b/server/modules/filter/cache/storagefactory.cc index e5a2d560c..86219c831 100644 --- a/server/modules/filter/cache/storagefactory.cc +++ b/server/modules/filter/cache/storagefactory.cc @@ -106,10 +106,15 @@ StorageFactory::StorageFactory(void* handle, uint32_t capabilities) : m_handle(handle) , m_pApi(pApi) - , m_capabilities(capabilities) + , m_storage_caps(capabilities) + , m_caps(capabilities) { ss_dassert(handle); ss_dassert(pApi); + + m_caps |= CACHE_STORAGE_CAP_LRU; + m_caps |= CACHE_STORAGE_CAP_MAX_COUNT; + m_caps |= CACHE_STORAGE_CAP_MAX_SIZE; } StorageFactory::~StorageFactory() @@ -151,60 +156,67 @@ Storage* StorageFactory::createStorage(cache_thread_model_t model, ss_dassert(m_handle); ss_dassert(m_pApi); - Storage* pStorage = 0; + uint32_t mc = cache_storage_has_cap(m_storage_caps, CACHE_STORAGE_CAP_MAX_COUNT) ? maxCount : 0; + uint64_t ms = cache_storage_has_cap(m_storage_caps, CACHE_STORAGE_CAP_MAX_SIZE) ? maxSize : 0; - uint32_t mc = cache_storage_has_cap(m_capabilities, CACHE_STORAGE_CAP_MAX_COUNT) ? maxCount : 0; - uint64_t ms = cache_storage_has_cap(m_capabilities, CACHE_STORAGE_CAP_MAX_SIZE) ? maxSize : 0; + Storage* pStorage = createRawStorage(model, zName, ttl, mc, ms, argc, argv); - CACHE_STORAGE* pRawStorage = m_pApi->createInstance(model, zName, ttl, mc, ms, argc, argv); - - if (pRawStorage) + if (pStorage) { - StorageReal* pStorageReal = NULL; + uint32_t mask = CACHE_STORAGE_CAP_MAX_COUNT | CACHE_STORAGE_CAP_MAX_SIZE; - MXS_EXCEPTION_GUARD(pStorageReal = new StorageReal(m_pApi, pRawStorage)); - - if (pStorageReal) + if (!cache_storage_has_cap(m_storage_caps, mask)) { - uint32_t mask = CACHE_STORAGE_CAP_MAX_COUNT | CACHE_STORAGE_CAP_MAX_SIZE; + // Ok, so the cache cannot handle eviction. Let's decorate the + // real storage with a storage than can. - if (!cache_storage_has_cap(m_capabilities, mask)) + LRUStorage *pLruStorage = NULL; + + if (model == CACHE_THREAD_MODEL_ST) { - // Ok, so the cache cannot handle eviction. Let's decorate the - // real storage with a storage than can. - - LRUStorage *pLruStorage = NULL; - - if (model == CACHE_THREAD_MODEL_ST) - { - pLruStorage = LRUStorageST::create(pStorageReal, maxCount, maxSize); - } - else - { - ss_dassert(model == CACHE_THREAD_MODEL_MT); - - pLruStorage = LRUStorageMT::create(pStorageReal, maxCount, maxSize); - } - - if (pLruStorage) - { - pStorage = pLruStorage; - } - else - { - delete pStorageReal; - } + pLruStorage = LRUStorageST::create(pStorage, maxCount, maxSize); } else { - pStorage = pStorageReal; + ss_dassert(model == CACHE_THREAD_MODEL_MT); + + pLruStorage = LRUStorageMT::create(pStorage, maxCount, maxSize); + } + + if (pLruStorage) + { + pStorage = pLruStorage; + } + else + { + delete pStorage; + pStorage = NULL; } - } - else - { - m_pApi->freeInstance(pRawStorage); } } return pStorage; } + + +Storage* StorageFactory::createRawStorage(cache_thread_model_t model, + const char* zName, + uint32_t ttl, + uint32_t maxCount, + uint64_t maxSize, + int argc, char* argv[]) +{ + ss_dassert(m_handle); + ss_dassert(m_pApi); + + Storage* pStorage = 0; + + CACHE_STORAGE* pRawStorage = m_pApi->createInstance(model, zName, ttl, maxCount, maxSize, argc, argv); + + if (pRawStorage) + { + MXS_EXCEPTION_GUARD(pStorage = new StorageReal(m_pApi, pRawStorage)); + } + + return pStorage; +} diff --git a/server/modules/filter/cache/storagefactory.hh b/server/modules/filter/cache/storagefactory.hh index 9c99db602..dde7babf9 100644 --- a/server/modules/filter/cache/storagefactory.hh +++ b/server/modules/filter/cache/storagefactory.hh @@ -24,6 +24,43 @@ public: static StorageFactory* Open(const char* zName); + /** + * The capabilities of storages created using this factory. + * These capabilities may be a superset of those reported + * by @c storage_capabilities. + * + * @return Bitmask of @c cache_storage_capabilities_t values. + */ + uint32_t capabilities() const { return m_caps; } + + /** + * The capabilities of storages loaded via this factory. These + * capabilities may be a subset of those reported by @ capabilities. + * + * @return Bitmask of @c cache_storage_capabilities_t values. + */ + uint32_t storage_capabilities() const { return m_storage_caps; } + + /** + * Create storage instance. + * + * If some of the required functionality (max_count != 0 and/or + * max_size != 0) is not provided by the underlying storage + * implementation that will be provided on top of what is "natively" + * provided. + * + * @param model The needed thread model. + * @param zName The name of the storage. + * @param ttl Time to live. 0 means no limit. + * @param max_count The maximum number of items in the cache. + * 0 means no limit. + * @param max_size The maximum size of the cache. 0 means + * no limit. + * @argc Number of items in argv. + * @argv Storage specific arguments. + * + * @return A storage instance or NULL in case of errors. + */ Storage* createStorage(cache_thread_model_t model, const char* zName, uint32_t ttl, @@ -31,6 +68,33 @@ public: uint64_t max_size, int argc, char* argv[]); + /** + * Create raw storage instance. + * + * The returned instance provides exactly the functionality the + * underlying storage module is capable of providing. The provided + * arguments (notably max_count and max_size) should be adjusted + * accordingly. + * + * @param model The needed thread model. + * @param zName The name of the storage. + * @param ttl Time to live. 0 means no limit. + * @param max_count The maximum number of items in the cache. + * 0 means no limit. + * @param max_size The maximum size of the cache. 0 means + * no limit. + * @argc Number of items in argv. + * @argv Storage specific arguments. + * + * @return A storage instance or NULL in case of errors. + */ + Storage* createRawStorage(cache_thread_model_t model, + const char* zName, + uint32_t ttl, + uint32_t max_count, + uint64_t max_size, + int argc, char* argv[]); + private: StorageFactory(void* handle, CACHE_STORAGE_API* pApi, uint32_t capabilities); @@ -40,5 +104,6 @@ private: private: void* m_handle; /*< dl handle of storage. */ CACHE_STORAGE_API* m_pApi; /*< API of storage. */ - uint32_t m_capabilities; /*< Capabilities of storage. */ + uint32_t m_storage_caps; /*< Capabilities of underlying storage. */ + uint32_t m_caps; /*< Capabilities of storages of this factory. */ };