diff --git a/server/modules/filter/cache/cache.cc b/server/modules/filter/cache/cache.cc index 1d506c616..6262ddab8 100644 --- a/server/modules/filter/cache/cache.cc +++ b/server/modules/filter/cache/cache.cc @@ -20,15 +20,14 @@ #include "storage.h" Cache::Cache(const char* zName, - CACHE_CONFIG& config, + const CACHE_CONFIG* pConfig, CACHE_RULES* pRules, StorageFactory* pFactory) : m_zName(zName) - , m_config(config) + , m_config(*pConfig) , m_pRules(pRules) , m_pFactory(pFactory) { - cache_config_reset(config); } Cache::~Cache() @@ -39,11 +38,9 @@ Cache::~Cache() //static bool Cache::Create(const CACHE_CONFIG& config, - CACHE_RULES** ppRules, - StorageFactory** ppFactory) + CACHE_RULES** ppRules) { CACHE_RULES* pRules = NULL; - StorageFactory* pFactory = NULL; if (config.rules) { @@ -55,29 +52,42 @@ bool Cache::Create(const CACHE_CONFIG& config, } if (pRules) - { - pFactory = StorageFactory::Open(config.storage); - - if (!pFactory) - { - MXS_ERROR("Could not open storage factory '%s'.", config.storage); - } - } - - bool rv = (pRules && pFactory); - - if (rv) { *ppRules = pRules; - *ppFactory = pFactory; } else { - cache_rules_free(pRules); - delete pFactory; + MXS_ERROR("Could not create rules."); } - return rv; + return pRules != NULL; +} + +//static +bool Cache::Create(const CACHE_CONFIG& config, + CACHE_RULES** ppRules, + StorageFactory** ppFactory) +{ + CACHE_RULES* pRules = NULL; + StorageFactory* pFactory = NULL; + + if (Create(config, &pRules)) + { + pFactory = StorageFactory::Open(config.storage); + + if (pFactory) + { + *ppFactory = pFactory; + *ppRules = pRules; + } + else + { + MXS_ERROR("Could not open storage factory '%s'.", config.storage); + cache_rules_free(pRules); + } + } + + return pFactory != NULL; } bool Cache::shouldStore(const char* zDefaultDb, const GWBUF* pQuery) diff --git a/server/modules/filter/cache/cache.h b/server/modules/filter/cache/cache.h index b2f3da803..bcbc8670e 100644 --- a/server/modules/filter/cache/cache.h +++ b/server/modules/filter/cache/cache.h @@ -74,10 +74,13 @@ public: protected: Cache(const char* zName, - CACHE_CONFIG& config, + const CACHE_CONFIG* pConfig, CACHE_RULES* pRules, StorageFactory* pFactory); + static bool Create(const CACHE_CONFIG& config, + CACHE_RULES** ppRules); + static bool Create(const CACHE_CONFIG& config, CACHE_RULES** ppRules, StorageFactory** ppFactory); @@ -87,8 +90,8 @@ private: Cache& operator = (const Cache&); protected: - const char* m_zName; // The name of the instance; the section name in the config. - CACHE_CONFIG m_config; // The configuration of the cache instance. - CACHE_RULES* m_pRules; // The rules of the cache instance. - StorageFactory* m_pFactory; // The storage factory. + const char* m_zName; // The name of the instance; the section name in the config. + const CACHE_CONFIG& m_config; // The configuration of the cache instance. + CACHE_RULES* m_pRules; // The rules of the cache instance. + StorageFactory* m_pFactory; // The storage factory. }; diff --git a/server/modules/filter/cache/cachefilter.cc b/server/modules/filter/cache/cachefilter.cc index ac03179a7..b37b5de9d 100644 --- a/server/modules/filter/cache/cachefilter.cc +++ b/server/modules/filter/cache/cachefilter.cc @@ -14,6 +14,7 @@ #define MXS_MODULE_NAME "cache" #include "cachefilter.h" #include +#include #include #include #include @@ -35,6 +36,28 @@ static const CACHE_CONFIG DEFAULT_CONFIG = CACHE_DEFAULT_DEBUG }; +typedef struct cache_filter +{ + cache_filter() + : config(DEFAULT_CONFIG) + , pCache(NULL) + { + } + + ~cache_filter() + { + delete pCache; + cache_config_finish(config); + } + + CACHE_CONFIG config; + Cache* pCache; + +private: + cache_filter(const cache_filter&); + cache_filter& operator = (const cache_filter&); +} CACHE_FILTER; + static FILTER* createInstance(const char* zName, char** pzOptions, FILTER_PARAMETER** ppParams); static void* newSession(FILTER* pInstance, SESSION* pSession); static void closeSession(FILTER* pInstance, void* pSessionData); @@ -114,20 +137,24 @@ extern "C" FILTER_OBJECT *GetModuleObject() */ static FILTER *createInstance(const char* zName, char** pzOptions, FILTER_PARAMETER** ppParams) { - Cache* pCache = NULL; - CACHE_CONFIG config = DEFAULT_CONFIG; + CACHE_FILTER* pFilter = new (std::nothrow) CACHE_FILTER; - if (process_params(pzOptions, ppParams, config)) + if (pFilter) { - CPP_GUARD(pCache = CacheMT::Create(zName, config)); - - if (!pCache) + if (process_params(pzOptions, ppParams, pFilter->config)) { - cache_config_finish(config); + CPP_GUARD(pFilter->pCache = CacheMT::Create(zName, &pFilter->config)); + + if (!pFilter->pCache) + { + cache_config_finish(pFilter->config); + delete pFilter; + pFilter = NULL; + } } } - return reinterpret_cast(pCache); + return reinterpret_cast(pFilter); } /** @@ -140,7 +167,8 @@ static FILTER *createInstance(const char* zName, char** pzOptions, FILTER_PARAME */ static void *newSession(FILTER* pInstance, SESSION* pSession) { - Cache* pCache = reinterpret_cast(pInstance); + CACHE_FILTER *pFilter = reinterpret_cast(pInstance); + Cache* pCache = pFilter->pCache; SessionCache* pSessionCache = NULL; CPP_GUARD(pSessionCache = SessionCache::Create(pCache, pSession)); @@ -447,11 +475,7 @@ void cache_config_finish(CACHE_CONFIG& config) MXS_FREE(config.rules); MXS_FREE(config.storage); MXS_FREE(config.storage_options); - - for (int i = 0; i < config.storage_argc; ++i) - { - MXS_FREE(config.storage_argv[i]); - } + MXS_FREE(config.storage_argv); // The items need not be freed, they point into storage_options. config.max_resultset_rows = 0; config.max_resultset_size = 0; diff --git a/server/modules/filter/cache/cachemt.cc b/server/modules/filter/cache/cachemt.cc index 95e5ef454..35c5eef38 100644 --- a/server/modules/filter/cache/cachemt.cc +++ b/server/modules/filter/cache/cachemt.cc @@ -16,12 +16,12 @@ #include "storagefactory.h" CacheMT::CacheMT(const char* zName, - CACHE_CONFIG& config, + const CACHE_CONFIG* pConfig, CACHE_RULES* pRules, StorageFactory* pFactory, - Storage* pStorage, - HASHTABLE* pPending) - : CacheSimple(zName, config, pRules, pFactory, pStorage, pPending) + HASHTABLE* pPending, + Storage* pStorage) + : CacheSimple(zName, pConfig, pRules, pFactory, pPending, pStorage) { spinlock_init(&m_lockPending); } @@ -30,39 +30,38 @@ CacheMT::~CacheMT() { } -CacheMT* CacheMT::Create(const char* zName, CACHE_CONFIG& config) +CacheMT* CacheMT::Create(const char* zName, const CACHE_CONFIG* pConfig) { + ss_dassert(pConfig); + CacheMT* pCache = NULL; CACHE_RULES* pRules = NULL; HASHTABLE* pPending = NULL; StorageFactory* pFactory = NULL; - if (CacheSimple::Create(config, &pRules, &pFactory, &pPending)) + if (CacheSimple::Create(*pConfig, &pRules, &pPending, &pFactory)) { - uint32_t ttl = config.ttl; - int argc = config.storage_argc; - char** argv = config.storage_argv; + pCache = Create(zName, pConfig, pRules, pFactory, pPending); + } - Storage* pStorage = pFactory->createStorage(CACHE_THREAD_MODEL_MT, zName, ttl, argc, argv); + return pCache; +} - if (pStorage) - { - CPP_GUARD(pCache = new CacheMT(zName, - config, - pRules, - pFactory, - pStorage, - pPending)); +// static +CacheMT* CacheMT::Create(const char* zName, StorageFactory* pFactory, const CACHE_CONFIG* pConfig) +{ + ss_dassert(pConfig); + ss_dassert(pFactory); - if (!pCache) - { - cache_rules_free(pRules); - hashtable_free(pPending); - delete pStorage; - delete pFactory; - } - } + CacheMT* pCache = NULL; + + CACHE_RULES* pRules = NULL; + HASHTABLE* pPending = NULL; + + if (CacheSimple::Create(*pConfig, &pRules, &pPending)) + { + pCache = Create(zName, pConfig, pRules, pFactory, pPending); } return pCache; @@ -87,3 +86,39 @@ void CacheMT::refreshed(const CACHE_KEY& key, const SessionCache* pSessionCache CacheSimple::refreshed(k, pSessionCache); spinlock_release(&m_lockPending); } + +// static +CacheMT* CacheMT::Create(const char* zName, + const CACHE_CONFIG* pConfig, + CACHE_RULES* pRules, + StorageFactory* pFactory, + HASHTABLE* pPending) +{ + CacheMT* pCache = NULL; + + uint32_t ttl = pConfig->ttl; + int argc = pConfig->storage_argc; + char** argv = pConfig->storage_argv; + + Storage* pStorage = pFactory->createStorage(CACHE_THREAD_MODEL_MT, zName, ttl, argc, argv); + + if (pStorage) + { + CPP_GUARD(pCache = new CacheMT(zName, + pConfig, + pRules, + pFactory, + pPending, + pStorage)); + + if (!pCache) + { + delete pStorage; + cache_rules_free(pRules); + hashtable_free(pPending); + delete pFactory; + } + } + + return pCache; +} diff --git a/server/modules/filter/cache/cachemt.h b/server/modules/filter/cache/cachemt.h index 7ce1d8ba4..ca7b90b3b 100644 --- a/server/modules/filter/cache/cachemt.h +++ b/server/modules/filter/cache/cachemt.h @@ -21,19 +21,26 @@ class CacheMT : public CacheSimple public: ~CacheMT(); - static CacheMT* Create(const char* zName, CACHE_CONFIG& config); + static CacheMT* Create(const char* zName, const CACHE_CONFIG* pConfig); + static CacheMT* Create(const char* zName, StorageFactory* pFactory, const CACHE_CONFIG* pConfig); bool mustRefresh(const CACHE_KEY& key, const SessionCache* pSessionCache); void refreshed(const CACHE_KEY& key, const SessionCache* pSessionCache); private: - CacheMT(const char* zName, - CACHE_CONFIG& config, - CACHE_RULES* pRules, - StorageFactory* pFactory, - Storage* pStorage, - HASHTABLE* pPending); + CacheMT(const char* zName, + const CACHE_CONFIG* pConfig, + CACHE_RULES* pRules, + StorageFactory* pFactory, + HASHTABLE* pPending, + Storage* pStorage); + + static CacheMT* Create(const char* zName, + const CACHE_CONFIG* pConfig, + CACHE_RULES* pRules, + StorageFactory* pFactory, + HASHTABLE* pPending); private: CacheMT(const CacheMT&); diff --git a/server/modules/filter/cache/cachesimple.cc b/server/modules/filter/cache/cachesimple.cc index 7dd66b086..75caa16d8 100644 --- a/server/modules/filter/cache/cachesimple.cc +++ b/server/modules/filter/cache/cachesimple.cc @@ -60,15 +60,15 @@ int hashcmp(const void* address1, const void* address2) } -CacheSimple::CacheSimple(const char* zName, - CACHE_CONFIG& config, - CACHE_RULES* pRules, - StorageFactory* pFactory, - Storage* pStorage, - HASHTABLE* pPending) - : Cache(zName, config, pRules, pFactory) - , m_pStorage(pStorage) +CacheSimple::CacheSimple(const char* zName, + const CACHE_CONFIG* pConfig, + CACHE_RULES* pRules, + StorageFactory* pFactory, + HASHTABLE* pPending, + Storage* pStorage) + : Cache(zName, pConfig, pRules, pFactory) , m_pPending(pPending) + , m_pStorage(pStorage) { } @@ -79,33 +79,51 @@ CacheSimple::~CacheSimple() } -// static protected +// static bool CacheSimple::Create(const CACHE_CONFIG& config, CACHE_RULES** ppRules, - StorageFactory** ppFactory, HASHTABLE** ppPending) { int rv = false; + CACHE_RULES* pRules = NULL; + HASHTABLE* pPending = NULL; + + if (Cache::Create(config, &pRules) && Create(&pPending)) + { + *ppRules = pRules; + *ppPending = pPending; + } + else + { + cache_rules_free(pRules); + } + + return pPending != NULL;; +} + +// static +bool CacheSimple::Create(const CACHE_CONFIG& config, + CACHE_RULES** ppRules, + HASHTABLE** ppPending, + StorageFactory** ppFactory) +{ + int rv = false; + CACHE_RULES* pRules = NULL; StorageFactory* pFactory = NULL; HASHTABLE* pPending = NULL; - if (Cache::Create(config, &pRules, &pFactory)) + if (Cache::Create(config, &pRules, &pFactory) && Create(&pPending)) { - pPending = hashtable_alloc(CACHE_PENDING_ITEMS, hashfn, hashcmp); - - if (pPending) - { - *ppRules = pRules; - *ppPending = pPending; - *ppFactory = pFactory; - } - else - { - cache_rules_free(pRules); - delete pFactory; - } + *ppRules = pRules; + *ppPending = pPending; + *ppFactory = pFactory; + } + else + { + cache_rules_free(pRules); + delete pFactory; } return pPending != NULL; @@ -162,3 +180,16 @@ void CacheSimple::refreshed(long key, const SessionCache* pSessionCache) ss_debug(int n =) hashtable_delete(m_pPending, (void*)key); ss_dassert(n == 1); } + +// static +bool CacheSimple::Create(HASHTABLE** ppPending) +{ + HASHTABLE* pPending = hashtable_alloc(CACHE_PENDING_ITEMS, hashfn, hashcmp); + + if (pPending) + { + *ppPending = pPending; + } + + return pPending != NULL; +} diff --git a/server/modules/filter/cache/cachesimple.h b/server/modules/filter/cache/cachesimple.h index cf5949bf8..dc51fc40a 100644 --- a/server/modules/filter/cache/cachesimple.h +++ b/server/modules/filter/cache/cachesimple.h @@ -32,18 +32,23 @@ public: cache_result_t delValue(const CACHE_KEY& key); protected: - CacheSimple(const char* zName, - CACHE_CONFIG& config, - CACHE_RULES* pRules, - StorageFactory* pFactory, - Storage* pStorage, - HASHTABLE* pPending); + CacheSimple(const char* zName, + const CACHE_CONFIG* pConfig, + CACHE_RULES* pRules, + StorageFactory* pFactory, + HASHTABLE* pPending, + Storage* pStorage); static bool Create(const CACHE_CONFIG& config, CACHE_RULES** ppRules, - StorageFactory** ppFactory, HASHTABLE** ppPending); + static bool Create(const CACHE_CONFIG& config, + CACHE_RULES** ppRules, + HASHTABLE** ppPending, + StorageFactory** ppFactory); + + long hashOfKey(const CACHE_KEY& key); bool mustRefresh(long key, const SessionCache* pSessionCache); @@ -54,7 +59,9 @@ private: CacheSimple(const Cache&); CacheSimple& operator = (const CacheSimple&); + static bool Create(HASHTABLE** ppPending); + protected: - Storage* m_pStorage; // The storage instance to use. HASHTABLE* m_pPending; // Pending items; being fetched from the backend. + Storage* m_pStorage; // The storage instance to use. }; diff --git a/server/modules/filter/cache/cachest.cc b/server/modules/filter/cache/cachest.cc index e2f428d4f..06819fbd7 100644 --- a/server/modules/filter/cache/cachest.cc +++ b/server/modules/filter/cache/cachest.cc @@ -16,12 +16,12 @@ #include "storagefactory.h" CacheST::CacheST(const char* zName, - CACHE_CONFIG& config, + const CACHE_CONFIG* pConfig, CACHE_RULES* pRules, StorageFactory* pFactory, - Storage* pStorage, - HASHTABLE* pPending) - : CacheSimple(zName, config, pRules, pFactory, pStorage, pPending) + HASHTABLE* pPending, + Storage* pStorage) + : CacheSimple(zName, pConfig, pRules, pFactory, pPending, pStorage) { } @@ -29,39 +29,38 @@ CacheST::~CacheST() { } -CacheST* CacheST::Create(const char* zName, CACHE_CONFIG& config) +CacheST* CacheST::Create(const char* zName, const CACHE_CONFIG* pConfig) { + ss_dassert(pConfig); + CacheST* pCache = NULL; CACHE_RULES* pRules = NULL; HASHTABLE* pPending = NULL; StorageFactory* pFactory = NULL; - if (CacheSimple::Create(config, &pRules, &pFactory, &pPending)) + if (CacheSimple::Create(*pConfig, &pRules, &pPending, &pFactory)) { - uint32_t ttl = config.ttl; - int argc = config.storage_argc; - char** argv = config.storage_argv; + pCache = Create(zName, pConfig, pRules, pFactory, pPending); + } - Storage* pStorage = pFactory->createStorage(CACHE_THREAD_MODEL_ST, zName, ttl, argc, argv); + return pCache; +} - if (pStorage) - { - CPP_GUARD(pCache = new CacheST(zName, - config, - pRules, - pFactory, - pStorage, - pPending)); +// static +CacheST* CacheST::Create(const char* zName, StorageFactory* pFactory, const CACHE_CONFIG* pConfig) +{ + ss_dassert(pConfig); + ss_dassert(pFactory); - if (!pCache) - { - cache_rules_free(pRules); - hashtable_free(pPending); - delete pStorage; - delete pFactory; - } - } + CacheST* pCache = NULL; + + CACHE_RULES* pRules = NULL; + HASHTABLE* pPending = NULL; + + if (CacheSimple::Create(*pConfig, &pRules, &pPending)) + { + pCache = Create(zName, pConfig, pRules, pFactory, pPending); } return pCache; @@ -80,3 +79,39 @@ void CacheST::refreshed(const CACHE_KEY& key, const SessionCache* pSessionCache CacheSimple::refreshed(k, pSessionCache); } + +// statis +CacheST* CacheST::Create(const char* zName, + const CACHE_CONFIG* pConfig, + CACHE_RULES* pRules, + StorageFactory* pFactory, + HASHTABLE* pPending) +{ + CacheST* pCache = NULL; + + uint32_t ttl = pConfig->ttl; + int argc = pConfig->storage_argc; + char** argv = pConfig->storage_argv; + + Storage* pStorage = pFactory->createStorage(CACHE_THREAD_MODEL_ST, zName, ttl, argc, argv); + + if (pStorage) + { + CPP_GUARD(pCache = new CacheST(zName, + pConfig, + pRules, + pFactory, + pPending, + pStorage)); + + if (!pCache) + { + delete pStorage; + cache_rules_free(pRules); + hashtable_free(pPending); + delete pFactory; + } + } + + return pCache; +} diff --git a/server/modules/filter/cache/cachest.h b/server/modules/filter/cache/cachest.h index 73323c846..56e45d878 100644 --- a/server/modules/filter/cache/cachest.h +++ b/server/modules/filter/cache/cachest.h @@ -20,20 +20,26 @@ class CacheST : public CacheSimple public: ~CacheST(); - static CacheST* Create(const char* zName, CACHE_CONFIG& config); + static CacheST* Create(const char* zName, const CACHE_CONFIG* pConfig); + static CacheST* Create(const char* zName, StorageFactory* pFactory, const CACHE_CONFIG* pConfig); bool mustRefresh(const CACHE_KEY& key, const SessionCache* pSessionCache); void refreshed(const CACHE_KEY& key, const SessionCache* pSessionCache); private: - CacheST(const char* zName, - CACHE_CONFIG& config, - CACHE_RULES* pRules, - StorageFactory* pFactory, - Storage* pStorage, - HASHTABLE* pPending); + CacheST(const char* zName, + const CACHE_CONFIG* pConfig, + CACHE_RULES* pRules, + StorageFactory* pFactory, + HASHTABLE* pPending, + Storage* pStorage); + static CacheST* Create(const char* zName, + const CACHE_CONFIG* pConfig, + CACHE_RULES* pRules, + StorageFactory* pFactory, + HASHTABLE* pPending); private: CacheST(const CacheST&); CacheST& operator = (const CacheST&);