diff --git a/Documentation/Filters/Cache.md b/Documentation/Filters/Cache.md index 2e78676ca..1e6936678 100644 --- a/Documentation/Filters/Cache.md +++ b/Documentation/Filters/Cache.md @@ -481,13 +481,14 @@ SET @maxscale.cache.populate=false; # Rules -The caching rules are expressed as a JSON object. +The caching rules are expressed as a JSON object or as an array +of JSON objects. There are two decisions to be made regarding the caching; in what circumstances should data be stored to the cache and in what circumstances should the data in the cache be used. -In the JSON object this is visible as follows: +Expressed in JSON this looks as follows ``` { @@ -495,12 +496,27 @@ In the JSON object this is visible as follows: use: [ ... ] } ``` +or, in case an array is used, as +``` +[ + { + store: [ ... ], + use: [ ... ] + }, + { ... } +] +``` The `store` field specifies in what circumstances data should be stored to the cache and the `use` field specifies in what circumstances the data in the cache should be used. In both cases, the value is a JSON array containg objects. +If an array of rule objects is specified, then, when looking for a rule that +matches, the `store` field of each object are evaluated in sequential order +until a match is found. Then, the `use` field of that object is used when +deciding whether data in the cache should be used. + ## When to Store By default, if no rules file have been provided or if the `store` field is diff --git a/server/modules/filter/cache/cache.cc b/server/modules/filter/cache/cache.cc index 1542e03f5..457047aac 100644 --- a/server/modules/filter/cache/cache.cc +++ b/server/modules/filter/cache/cache.cc @@ -27,13 +27,13 @@ using namespace std; -Cache::Cache(const std::string& name, - const CACHE_CONFIG* pConfig, - SCacheRules sRules, - SStorageFactory sFactory) +Cache::Cache(const std::string& name, + const CACHE_CONFIG* pConfig, + const std::vector& rules, + SStorageFactory sFactory) : m_name(name) , m_config(*pConfig) - , m_sRules(sRules) + , m_rules(rules) , m_sFactory(sFactory) { } @@ -43,35 +43,42 @@ Cache::~Cache() } //static -bool Cache::Create(const CACHE_CONFIG& config, - CacheRules** ppRules, - StorageFactory** ppFactory) +bool Cache::Create(const CACHE_CONFIG& config, + std::vector* pRules, + StorageFactory** ppFactory) { - CacheRules* pRules = NULL; + std::vector rules; StorageFactory* pFactory = NULL; + bool rv = false; + if (config.rules) { - pRules = CacheRules::load(config.rules, config.debug); + rv = CacheRules::load(config.rules, config.debug, &rules); } else { - pRules = CacheRules::create(config.debug); + auto_ptr sRules(CacheRules::create(config.debug)); + + if (sRules.get()) + { + rules.push_back(SCacheRules(sRules.release())); + rv = true; + } } - if (pRules) + if (rv) { pFactory = StorageFactory::Open(config.storage); if (pFactory) { *ppFactory = pFactory; - *ppRules = pRules; + pRules->swap(rules); } else { MXS_ERROR("Could not open storage factory '%s'.", config.storage); - delete pRules; } } else @@ -155,14 +162,25 @@ cache_result_t Cache::get_default_key(const char* zDefault_db, return CACHE_RESULT_OK; } -bool Cache::should_store(const char* zDefaultDb, const GWBUF* pQuery) +const CacheRules* Cache::should_store(const char* zDefaultDb, const GWBUF* pQuery) { - return m_sRules->should_store(zDefaultDb, pQuery); -} + CacheRules* pRules = NULL; -bool Cache::should_use(const MXS_SESSION* pSession) -{ - return m_sRules->should_use(pSession); + auto i = m_rules.begin(); + + while (!pRules && (i != m_rules.end())) + { + if ((*i)->should_store(zDefaultDb, pQuery)) + { + pRules = (*i).get(); + } + else + { + ++i; + } + } + + return pRules; } json_t* Cache::do_get_info(uint32_t what) const @@ -173,9 +191,18 @@ json_t* Cache::do_get_info(uint32_t what) const { if (what & INFO_RULES) { - json_t* pRules = const_cast(m_sRules->json()); + json_t* pArray = json_array(); - json_object_set(pInfo, "rules", pRules); // Increases ref-count of pRules, we ignore failure. + if (pArray) + { + for (auto i = m_rules.begin(); i < m_rules.end(); ++i) + { + json_t* pRules = const_cast((*i)->json()); + json_array_append(pArray, pRules); // Increases ref-count of pRules, we ignore failure. + } + + json_object_set(pInfo, "rules", pArray); + } } } diff --git a/server/modules/filter/cache/cache.hh b/server/modules/filter/cache/cache.hh index 097fb4d05..af6506694 100644 --- a/server/modules/filter/cache/cache.hh +++ b/server/modules/filter/cache/cache.hh @@ -56,18 +56,9 @@ public: * @param zDefaultDb The current default database. * @param pQuery Buffer containing a SELECT. * - * @return True of the result should be cached. + * @return A rules object, if the query should be stored, NULL otherwise. */ - bool should_store(const char* zDefaultDb, const GWBUF* pQuery); - - /** - * Returns whether cached results should be used. - * - * @param pSession The session in question. - * - * @return True of cached results should be used. - */ - bool should_use(const MXS_SESSION* pSession); + const CacheRules* should_store(const char* zDefaultDb, const GWBUF* pQuery); /** * Specifies whether a particular SessioCache should refresh the data. @@ -134,14 +125,14 @@ public: virtual cache_result_t del_value(const CACHE_KEY& key) = 0; protected: - Cache(const std::string& name, - const CACHE_CONFIG* pConfig, - SCacheRules sRules, - SStorageFactory sFactory); + Cache(const std::string& name, + const CACHE_CONFIG* pConfig, + const std::vector& rules, + SStorageFactory sFactory); - static bool Create(const CACHE_CONFIG& config, - CacheRules** ppRules, - StorageFactory** ppFactory); + static bool Create(const CACHE_CONFIG& config, + std::vector* pRules, + StorageFactory** ppFactory); json_t* do_get_info(uint32_t what) const; @@ -150,8 +141,8 @@ private: Cache& operator = (const Cache&); protected: - const std::string m_name; // The name of the instance; the section name in the config. - const CACHE_CONFIG& m_config; // The configuration of the cache instance. - SCacheRules m_sRules; // The rules of the cache instance. - SStorageFactory m_sFactory; // The storage factory. + const std::string m_name; // The name of the instance; the section name in the config. + const CACHE_CONFIG& m_config; // The configuration of the cache instance. + std::vector m_rules; // The rules of the cache instance. + SStorageFactory m_sFactory; // The storage factory. }; diff --git a/server/modules/filter/cache/cachefiltersession.cc b/server/modules/filter/cache/cachefiltersession.cc index 5f1f01988..306dfd083 100644 --- a/server/modules/filter/cache/cachefiltersession.cc +++ b/server/modules/filter/cache/cachefiltersession.cc @@ -1005,13 +1005,15 @@ CacheFilterSession::routing_action_t CacheFilterSession::route_COM_QUERY(GWBUF* if (cache_action != CACHE_IGNORE) { - if (m_pCache->should_store(m_zDefaultDb, pPacket)) + const CacheRules* pRules = m_pCache->should_store(m_zDefaultDb, pPacket); + + if (pRules) { cache_result_t result = m_pCache->get_key(m_zDefaultDb, pPacket, &m_key); if (CACHE_RESULT_IS_OK(result)) { - routing_action = route_SELECT(cache_action, pPacket); + routing_action = route_SELECT(cache_action, *pRules, pPacket); } else { @@ -1033,6 +1035,7 @@ CacheFilterSession::routing_action_t CacheFilterSession::route_COM_QUERY(GWBUF* * Routes a SELECT packet. * * @param cache_action The desired action. + * @param rules The current rules. * @param pPacket A contiguous COM_QUERY packet containing a SELECT. * * @return ROUTING_ABORT if the processing of the packet should be aborted @@ -1040,11 +1043,12 @@ CacheFilterSession::routing_action_t CacheFilterSession::route_COM_QUERY(GWBUF* * ROUTING_CONTINUE if the normal processing should continue. */ CacheFilterSession::routing_action_t CacheFilterSession::route_SELECT(cache_action_t cache_action, + const CacheRules& rules, GWBUF* pPacket) { routing_action_t routing_action = ROUTING_CONTINUE; - if (should_use(cache_action) && m_pCache->should_use(m_pSession)) + if (should_use(cache_action) && rules.should_use(m_pSession)) { uint32_t flags = CACHE_FLAGS_INCLUDE_STALE; GWBUF* pResponse; diff --git a/server/modules/filter/cache/cachefiltersession.hh b/server/modules/filter/cache/cachefiltersession.hh index 7bef6a010..dca3b00a4 100644 --- a/server/modules/filter/cache/cachefiltersession.hh +++ b/server/modules/filter/cache/cachefiltersession.hh @@ -139,7 +139,7 @@ private: }; routing_action_t route_COM_QUERY(GWBUF* pPacket); - routing_action_t route_SELECT(cache_action_t action, GWBUF* pPacket); + routing_action_t route_SELECT(cache_action_t action, const CacheRules& rules, GWBUF* pPacket); char* set_cache_populate(const char* zName, const char* pValue_begin, diff --git a/server/modules/filter/cache/cachemt.cc b/server/modules/filter/cache/cachemt.cc index 274ced1af..1d0580657 100644 --- a/server/modules/filter/cache/cachemt.cc +++ b/server/modules/filter/cache/cachemt.cc @@ -19,12 +19,12 @@ using maxscale::SpinLockGuard; using std::tr1::shared_ptr; -CacheMT::CacheMT(const std::string& name, - const CACHE_CONFIG* pConfig, - SCacheRules sRules, - SStorageFactory sFactory, - Storage* pStorage) - : CacheSimple(name, pConfig, sRules, sFactory, pStorage) +CacheMT::CacheMT(const std::string& name, + const CACHE_CONFIG* pConfig, + const std::vector& rules, + SStorageFactory sFactory, + Storage* pStorage) + : CacheSimple(name, pConfig, rules, sFactory, pStorage) { spinlock_init(&m_lock_pending); @@ -41,15 +41,14 @@ CacheMT* CacheMT::Create(const std::string& name, const CACHE_CONFIG* pConfig) CacheMT* pCache = NULL; - CacheRules* pRules = NULL; + std::vector rules; StorageFactory* pFactory = NULL; - if (CacheSimple::Create(*pConfig, &pRules, &pFactory)) + if (CacheSimple::Create(*pConfig, &rules, &pFactory)) { - shared_ptr sRules(pRules); shared_ptr sFactory(pFactory); - pCache = Create(name, pConfig, sRules, sFactory); + pCache = Create(name, pConfig, rules, sFactory); } return pCache; @@ -77,10 +76,10 @@ void CacheMT::refreshed(const CACHE_KEY& key, const CacheFilterSession* pSessio } // static -CacheMT* CacheMT::Create(const std::string& name, - const CACHE_CONFIG* pConfig, - SCacheRules sRules, - SStorageFactory sFactory) +CacheMT* CacheMT::Create(const std::string& name, + const CACHE_CONFIG* pConfig, + const std::vector& rules, + SStorageFactory sFactory) { CacheMT* pCache = NULL; @@ -99,7 +98,7 @@ CacheMT* CacheMT::Create(const std::string& name, { MXS_EXCEPTION_GUARD(pCache = new CacheMT(name, pConfig, - sRules, + rules, sFactory, pStorage)); diff --git a/server/modules/filter/cache/cachemt.hh b/server/modules/filter/cache/cachemt.hh index 0965ed628..fb9a25e64 100644 --- a/server/modules/filter/cache/cachemt.hh +++ b/server/modules/filter/cache/cachemt.hh @@ -30,16 +30,16 @@ public: void refreshed(const CACHE_KEY& key, const CacheFilterSession* pSession); private: - CacheMT(const std::string& name, - const CACHE_CONFIG* pConfig, - SCacheRules sRules, - SStorageFactory sFactory, - Storage* pStorage); + CacheMT(const std::string& name, + const CACHE_CONFIG* pConfig, + const std::vector& rules, + SStorageFactory sFactory, + Storage* pStorage); - static CacheMT* Create(const std::string& name, - const CACHE_CONFIG* pConfig, - SCacheRules sRules, - SStorageFactory sFactory); + static CacheMT* Create(const std::string& name, + const CACHE_CONFIG* pConfig, + const std::vector& rules, + SStorageFactory sFactory); private: CacheMT(const CacheMT&); diff --git a/server/modules/filter/cache/cachept.cc b/server/modules/filter/cache/cachept.cc index 4dbbc70ed..69d05d60f 100644 --- a/server/modules/filter/cache/cachept.cc +++ b/server/modules/filter/cache/cachept.cc @@ -48,12 +48,12 @@ inline int thread_index() } -CachePT::CachePT(const std::string& name, - const CACHE_CONFIG* pConfig, - SCacheRules sRules, - SStorageFactory sFactory, - const Caches& caches) - : Cache(name, pConfig, sRules, sFactory) +CachePT::CachePT(const std::string& name, + const CACHE_CONFIG* pConfig, + const std::vector& rules, + SStorageFactory sFactory, + const Caches& caches) + : Cache(name, pConfig, rules, sFactory) , m_caches(caches) { MXS_NOTICE("Created cache per thread."); @@ -70,15 +70,14 @@ CachePT* CachePT::Create(const std::string& name, const CACHE_CONFIG* pConfig) CachePT* pCache = NULL; - CacheRules* pRules = NULL; + std::vector rules; StorageFactory* pFactory = NULL; - if (Cache::Create(*pConfig, &pRules, &pFactory)) + if (Cache::Create(*pConfig, &rules, &pFactory)) { - shared_ptr sRules(pRules); shared_ptr sFactory(pFactory); - pCache = Create(name, pConfig, sRules, sFactory); + pCache = Create(name, pConfig, rules, sFactory); } return pCache; @@ -148,10 +147,10 @@ cache_result_t CachePT::del_value(const CACHE_KEY& key) } // static -CachePT* CachePT::Create(const std::string& name, - const CACHE_CONFIG* pConfig, - SCacheRules sRules, - SStorageFactory sFactory) +CachePT* CachePT::Create(const std::string& name, + const CACHE_CONFIG* pConfig, + const std::vector& rules, + SStorageFactory sFactory) { CachePT* pCache = NULL; @@ -173,7 +172,7 @@ CachePT* CachePT::Create(const std::string& name, CacheST* pCacheST = 0; - MXS_EXCEPTION_GUARD(pCacheST = CacheST::Create(namest, sRules, sFactory, pConfig)); + MXS_EXCEPTION_GUARD(pCacheST = CacheST::Create(namest, rules, sFactory, pConfig)); if (pCacheST) { @@ -191,7 +190,7 @@ CachePT* CachePT::Create(const std::string& name, if (!error) { - pCache = new CachePT(name, pConfig, sRules, sFactory, caches); + pCache = new CachePT(name, pConfig, rules, sFactory, caches); } } catch (const std::exception&) diff --git a/server/modules/filter/cache/cachept.hh b/server/modules/filter/cache/cachept.hh index df2a09e2e..c5579b00f 100644 --- a/server/modules/filter/cache/cachept.hh +++ b/server/modules/filter/cache/cachept.hh @@ -44,16 +44,16 @@ private: typedef std::tr1::shared_ptr SCache; typedef std::vector Caches; - CachePT(const std::string& name, - const CACHE_CONFIG* pConfig, - SCacheRules sRules, - SStorageFactory sFactory, - const Caches& caches); + CachePT(const std::string& name, + const CACHE_CONFIG* pConfig, + const std::vector& rules, + SStorageFactory sFactory, + const Caches& caches); - static CachePT* Create(const std::string& name, - const CACHE_CONFIG* pConfig, - SCacheRules sRules, - SStorageFactory sFactory); + static CachePT* Create(const std::string& name, + const CACHE_CONFIG* pConfig, + const std::vector& rules, + SStorageFactory sFactory); Cache& thread_cache(); diff --git a/server/modules/filter/cache/cachesimple.cc b/server/modules/filter/cache/cachesimple.cc index 031a94adf..e49a9e573 100644 --- a/server/modules/filter/cache/cachesimple.cc +++ b/server/modules/filter/cache/cachesimple.cc @@ -16,12 +16,12 @@ #include "storage.hh" #include "storagefactory.hh" -CacheSimple::CacheSimple(const std::string& name, - const CACHE_CONFIG* pConfig, - SCacheRules sRules, - SStorageFactory sFactory, - Storage* pStorage) - : Cache(name, pConfig, sRules, sFactory) +CacheSimple::CacheSimple(const std::string& name, + const CACHE_CONFIG* pConfig, + const std::vector& rules, + SStorageFactory sFactory, + Storage* pStorage) + : Cache(name, pConfig, rules, sFactory) , m_pStorage(pStorage) { } @@ -32,22 +32,24 @@ CacheSimple::~CacheSimple() } // static -bool CacheSimple::Create(const CACHE_CONFIG& config, - CacheRules** ppRules, - StorageFactory** ppFactory) +bool CacheSimple::Create(const CACHE_CONFIG& config, + std::vector* pRules, + StorageFactory** ppFactory) { int rv = false; - CacheRules* pRules = NULL; + std::vector rules; StorageFactory* pFactory = NULL; - if (Cache::Create(config, &pRules, &pFactory)) + rv = Cache::Create(config, &rules, &pFactory); + + if (rv) { - *ppRules = pRules; + pRules->swap(rules); *ppFactory = pFactory; } - return pRules != NULL; + return rv; } cache_result_t CacheSimple::get_value(const CACHE_KEY& key, diff --git a/server/modules/filter/cache/cachesimple.hh b/server/modules/filter/cache/cachesimple.hh index cee6ceb3c..e0d58206c 100644 --- a/server/modules/filter/cache/cachesimple.hh +++ b/server/modules/filter/cache/cachesimple.hh @@ -34,15 +34,15 @@ public: cache_result_t del_value(const CACHE_KEY& key); protected: - CacheSimple(const std::string& name, - const CACHE_CONFIG* pConfig, - SCacheRules sRules, - SStorageFactory sFactory, - Storage* pStorage); + CacheSimple(const std::string& name, + const CACHE_CONFIG* pConfig, + const std::vector& Rules, + SStorageFactory sFactory, + Storage* pStorage); - static bool Create(const CACHE_CONFIG& config, - CacheRules** ppRules, - StorageFactory** ppFactory); + static bool Create(const CACHE_CONFIG& config, + std::vector* pRules, + StorageFactory** ppFactory); json_t* do_get_info(uint32_t what) const; diff --git a/server/modules/filter/cache/cachest.cc b/server/modules/filter/cache/cachest.cc index c622cfa92..df47b4c6d 100644 --- a/server/modules/filter/cache/cachest.cc +++ b/server/modules/filter/cache/cachest.cc @@ -18,12 +18,12 @@ using std::tr1::shared_ptr; -CacheST::CacheST(const std::string& name, - const CACHE_CONFIG* pConfig, - SCacheRules sRules, - SStorageFactory sFactory, - Storage* pStorage) - : CacheSimple(name, pConfig, sRules, sFactory, pStorage) +CacheST::CacheST(const std::string& name, + const CACHE_CONFIG* pConfig, + const std::vector& rules, + SStorageFactory sFactory, + Storage* pStorage) + : CacheSimple(name, pConfig, rules, sFactory, pStorage) { MXS_NOTICE("Created single threaded cache."); } @@ -38,31 +38,29 @@ CacheST* CacheST::Create(const std::string& name, const CACHE_CONFIG* pConfig) CacheST* pCache = NULL; - CacheRules* pRules = NULL; + std::vector rules; StorageFactory* pFactory = NULL; - if (CacheSimple::Create(*pConfig, &pRules, &pFactory)) + if (CacheSimple::Create(*pConfig, &rules, &pFactory)) { - shared_ptr sRules(pRules); shared_ptr sFactory(pFactory); - pCache = Create(name, pConfig, sRules, sFactory); + pCache = Create(name, pConfig, rules, sFactory); } return pCache; } // static -CacheST* CacheST::Create(const std::string& name, - SCacheRules sRules, - SStorageFactory sFactory, - const CACHE_CONFIG* pConfig) +CacheST* CacheST::Create(const std::string& name, + const std::vector& rules, + SStorageFactory sFactory, + const CACHE_CONFIG* pConfig) { - ss_dassert(sRules.get()); ss_dassert(sFactory.get()); ss_dassert(pConfig); - return Create(name, pConfig, sRules, sFactory); + return Create(name, pConfig, rules, sFactory); } json_t* CacheST::get_info(uint32_t flags) const @@ -81,10 +79,10 @@ void CacheST::refreshed(const CACHE_KEY& key, const CacheFilterSession* pSessio } // static -CacheST* CacheST::Create(const std::string& name, - const CACHE_CONFIG* pConfig, - SCacheRules sRules, - SStorageFactory sFactory) +CacheST* CacheST::Create(const std::string& name, + const CACHE_CONFIG* pConfig, + const std::vector& rules, + SStorageFactory sFactory) { CacheST* pCache = NULL; @@ -103,7 +101,7 @@ CacheST* CacheST::Create(const std::string& name, { MXS_EXCEPTION_GUARD(pCache = new CacheST(name, pConfig, - sRules, + rules, sFactory, pStorage)); diff --git a/server/modules/filter/cache/cachest.hh b/server/modules/filter/cache/cachest.hh index f7ee25fdc..8d148b705 100644 --- a/server/modules/filter/cache/cachest.hh +++ b/server/modules/filter/cache/cachest.hh @@ -22,7 +22,7 @@ public: static CacheST* Create(const std::string& name, const CACHE_CONFIG* pConfig); static CacheST* Create(const std::string& name, - SCacheRules sRules, + const std::vector& rules, SStorageFactory sFactory, const CACHE_CONFIG* pConfig); @@ -33,16 +33,16 @@ public: void refreshed(const CACHE_KEY& key, const CacheFilterSession* pSession); private: - CacheST(const std::string& name, - const CACHE_CONFIG* pConfig, - SCacheRules sRules, - SStorageFactory sFactory, - Storage* pStorage); + CacheST(const std::string& name, + const CACHE_CONFIG* pConfig, + const std::vector& rules, + SStorageFactory sFactory, + Storage* pStorage); - static CacheST* Create(const std::string& name, - const CACHE_CONFIG* pConfig, - SCacheRules sRules, - SStorageFactory sFactory); + static CacheST* Create(const std::string& name, + const CACHE_CONFIG* pConfig, + const std::vector& rules, + SStorageFactory sFactory); private: CacheST(const CacheST&); CacheST& operator = (const CacheST&); diff --git a/server/modules/filter/cache/rules.cc b/server/modules/filter/cache/rules.cc index a25b9f483..27f67e604 100644 --- a/server/modules/filter/cache/rules.cc +++ b/server/modules/filter/cache/rules.cc @@ -315,6 +315,16 @@ void cache_rules_free(CACHE_RULES *rules) } } +void cache_rules_free_array(CACHE_RULES** ppRules, int32_t nRules) +{ + for (auto i = 0; i < nRules; ++i) + { + cache_rules_free(ppRules[i]); + } + + MXS_FREE(ppRules); +} + void cache_rules_print(const CACHE_RULES *self, DCB *dcb, size_t indent) { if (self->root) @@ -405,39 +415,64 @@ CacheRules::~CacheRules() } // static -CacheRules* CacheRules::create(uint32_t debug) +std::auto_ptr CacheRules::create(uint32_t debug) { - CacheRules* pThis = NULL; + std::auto_ptr sThis; CACHE_RULES* pRules = cache_rules_create(debug); if (pRules) { - pThis = new (std::nothrow) CacheRules(pRules); + sThis = std::auto_ptr(new (std::nothrow) CacheRules(pRules)); } - return pThis; + return sThis; } // static -CacheRules* CacheRules::load(const char *zPath, uint32_t debug) +bool CacheRules::load(const char *zPath, uint32_t debug, std::vector* pRules) { - CacheRules* pThis = NULL; + bool rv = false; + + pRules->clear(); CACHE_RULES** ppRules; int32_t nRules; if (cache_rules_load(zPath, debug, &ppRules, &nRules)) { - // TODO: Handle more that one CACHE_RULES object at this level. - ss_dassert(nRules == 1); + int j = 0; - pThis = new (std::nothrow) CacheRules(ppRules[0]); + try + { + std::vector rules; + rules.reserve(nRules); + + for (int i = 0; i < nRules; ++i) + { + j = i; + CacheRules* pRules = new CacheRules(ppRules[i]); + j = i + 1; + + rules.push_back(SCacheRules(pRules)); + } + + pRules->swap(rules); + rv = true; + } + catch (const std::exception&) + { + // Free all CACHE_RULES objects that were not pushed into 'rules' above. + for (; j < nRules; ++j) + { + cache_rules_free(ppRules[j]); + } + } MXS_FREE(ppRules); } - return pThis; + return rv; } const json_t* CacheRules::json() const diff --git a/server/modules/filter/cache/rules.h b/server/modules/filter/cache/rules.h index 23cb8f816..2941946d8 100644 --- a/server/modules/filter/cache/rules.h +++ b/server/modules/filter/cache/rules.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -105,6 +106,14 @@ CACHE_RULES *cache_rules_create(uint32_t debug); */ void cache_rules_free(CACHE_RULES *rules); +/** + * Frees all rules in an array of rules *and* the array itself. + * + * @param ppRules Pointer to array of pointers to rules. + * @param nRules The number of items in the array. + */ +void cache_rules_free_array(CACHE_RULES** ppRules, int32_t nRules); + /** * Loads the caching rules from a file and returns corresponding object. * @@ -175,6 +184,8 @@ MXS_END_DECLS class CacheRules { public: + typedef std::tr1::shared_ptr SCacheRules; + ~CacheRules(); /** @@ -184,17 +195,18 @@ public: * * @return An empty rules object, or NULL in case of error. */ - static CacheRules* create(uint32_t debug); + static std::auto_ptr create(uint32_t debug); /** * Loads the caching rules from a file and returns corresponding object. * - * @param path The path of the file containing the rules. - * @param debug The debug level. + * @param path The path of the file containing the rules. + * @param debug The debug level. + * @param pRules [out] The loaded rules. * - * @return The corresponding rules object, or NULL in case of error. + * @return True, if the rules could be loaded, false otherwise. */ - static CacheRules* load(const char *zPath, uint32_t debug); + static bool load(const char *zPath, uint32_t debug, std::vector* pRules); /** * Returns the json rules object.