diff --git a/server/modules/filter/cache/CMakeLists.txt b/server/modules/filter/cache/CMakeLists.txt index 7813af648..41478256f 100644 --- a/server/modules/filter/cache/CMakeLists.txt +++ b/server/modules/filter/cache/CMakeLists.txt @@ -3,7 +3,6 @@ if (JANSSON_FOUND) cache.cc cachefilter.cc cachefiltersession.cc - cache_storage_api.c cache_storage_api.cc cachemt.cc cachept.cc diff --git a/server/modules/filter/cache/cache.hh b/server/modules/filter/cache/cache.hh index 0ffc9ca29..b35973f35 100644 --- a/server/modules/filter/cache/cache.hh +++ b/server/modules/filter/cache/cache.hh @@ -19,12 +19,95 @@ #include #include #include -#include "cachefilter.h" -#include "cache_storage_api.h" + +#include "rules.hh" +#include "cache_storage_api.hh" class CacheFilterSession; class StorageFactory; +#define CACHE_DEBUG_NONE 0 /* 0b00000 */ +#define CACHE_DEBUG_MATCHING 1 /* 0b00001 */ +#define CACHE_DEBUG_NON_MATCHING 2 /* 0b00010 */ +#define CACHE_DEBUG_USE 4 /* 0b00100 */ +#define CACHE_DEBUG_NON_USE 8 /* 0b01000 */ +#define CACHE_DEBUG_DECISIONS 16 /* 0b10000 */ + +#define CACHE_DEBUG_RULES (CACHE_DEBUG_MATCHING | CACHE_DEBUG_NON_MATCHING) +#define CACHE_DEBUG_USAGE (CACHE_DEBUG_USE | CACHE_DEBUG_NON_USE) +#define CACHE_DEBUG_MIN CACHE_DEBUG_NONE +#define CACHE_DEBUG_MAX (CACHE_DEBUG_RULES | CACHE_DEBUG_USAGE | CACHE_DEBUG_DECISIONS) + +#if !defined (UINT32_MAX) +#define UINT32_MAX (4294967295U) +#endif + +#if !defined (UINT64_MAX) +#define UINT64_MAX (18446744073709551615UL) +#endif + +typedef enum cache_selects +{ + CACHE_SELECTS_ASSUME_CACHEABLE, + CACHE_SELECTS_VERIFY_CACHEABLE, +} cache_selects_t; + +// Count +#define CACHE_ZDEFAULT_MAX_RESULTSET_ROWS "0" +// Bytes +#define CACHE_ZDEFAULT_MAX_RESULTSET_SIZE "0" +// Seconds +#define CACHE_ZDEFAULT_HARD_TTL "0" +// Seconds +#define CACHE_ZDEFAULT_SOFT_TTL "0" +// Integer value +#define CACHE_ZDEFAULT_DEBUG "0" +// Positive integer +#define CACHE_ZDEFAULT_MAX_COUNT "0" +// Positive integer +#define CACHE_ZDEFAULT_MAX_SIZE "0" +// Thread model +#define CACHE_ZDEFAULT_THREAD_MODEL "thread_specific" +const cache_thread_model CACHE_DEFAULT_THREAD_MODEL = CACHE_THREAD_MODEL_ST; +// Cacheable selects +#define CACHE_ZDEFAULT_SELECTS "assume_cacheable" +const cache_selects_t CACHE_DEFAULT_SELECTS = CACHE_SELECTS_ASSUME_CACHEABLE; +// Storage +#define CACHE_ZDEFAULT_STORAGE "storage_inmemory" +// Transaction behaviour +#define CACHE_ZDEFAULT_CACHE_IN_TRXS "all_transactions" +// Enabled +#define CACHE_ZDEFAULT_ENABLED "true" + +typedef enum cache_in_trxs +{ + // Do NOT change the order. Code relies upon NEVER < READ_ONLY < ALL. + CACHE_IN_TRXS_NEVER, + CACHE_IN_TRXS_READ_ONLY, + CACHE_IN_TRXS_ALL, +} cache_in_trxs_t; + +typedef struct cache_config +{ + uint64_t max_resultset_rows; /**< The maximum number of rows of a resultset for it to be + * cached. */ + uint64_t max_resultset_size;/**< The maximum size of a resultset for it to be cached. */ + char* rules; /**< Name of rules file. */ + char* storage; /**< Name of storage module. */ + char* storage_options; /**< Raw options for storage module. */ + char** storage_argv; /**< Cooked options for storage module. */ + int storage_argc; /**< Number of cooked options. */ + uint32_t hard_ttl; /**< Hard time to live. */ + uint32_t soft_ttl; /**< Soft time to live. */ + uint64_t max_count; /**< Maximum number of entries in the cache.*/ + uint64_t max_size; /**< Maximum size of the cache.*/ + uint32_t debug; /**< Debug settings. */ + cache_thread_model_t thread_model; /**< Thread model. */ + cache_selects_t selects; /**< Assume/verify that selects are cacheable. */ + cache_in_trxs_t cache_in_trxs; /**< To cache or not to cache inside transactions. */ + bool enabled; /**< Whether the cache is enabled or not. */ +} CACHE_CONFIG; + class Cache { public: diff --git a/server/modules/filter/cache/cache_storage_api.c b/server/modules/filter/cache/cache_storage_api.c deleted file mode 100644 index 3d7eb64ec..000000000 --- a/server/modules/filter/cache/cache_storage_api.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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/bsl11. - * - * Change Date: 2022-01-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 "cache_storage_api.h" - - -size_t cache_key_hash(const CACHE_KEY* key) -{ - mxb_assert(key); - mxb_assert(sizeof(key->data) == sizeof(size_t)); - - return key->data; -} - -bool cache_key_equal_to(const CACHE_KEY* lhs, const CACHE_KEY* rhs) -{ - mxb_assert(lhs); - mxb_assert(rhs); - - return lhs->data == rhs->data; -} diff --git a/server/modules/filter/cache/cache_storage_api.cc b/server/modules/filter/cache/cache_storage_api.cc index fee2682d9..f3ef38ba0 100644 --- a/server/modules/filter/cache/cache_storage_api.cc +++ b/server/modules/filter/cache/cache_storage_api.cc @@ -26,3 +26,19 @@ std::string cache_key_to_string(const CACHE_KEY& key) return ss.str(); } + +size_t cache_key_hash(const CACHE_KEY* key) +{ + mxb_assert(key); + mxb_assert(sizeof(key->data) == sizeof(size_t)); + + return key->data; +} + +bool cache_key_equal_to(const CACHE_KEY* lhs, const CACHE_KEY* rhs) +{ + mxb_assert(lhs); + mxb_assert(rhs); + + return lhs->data == rhs->data; +} diff --git a/server/modules/filter/cache/cache_storage_api.h b/server/modules/filter/cache/cache_storage_api.h deleted file mode 100644 index 0a4e73133..000000000 --- a/server/modules/filter/cache/cache_storage_api.h +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Copyright (c) 2018 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/bsl11. - * - * Change Date: 2022-01-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. - */ -#pragma once - -#include -#include -#include -#include -#include -#include - -MXS_BEGIN_DECLS - -typedef enum cache_result_bits -{ - CACHE_RESULT_OK = 0x01, - CACHE_RESULT_NOT_FOUND = 0x02, - CACHE_RESULT_ERROR = 0x03, - CACHE_RESULT_OUT_OF_RESOURCES = 0x04, - - CACHE_RESULT_STALE = 0x10000, /*< Possibly combined with OK and NOT_FOUND. */ - CACHE_RESULT_DISCARDED = 0x20000, /*< Possibly combined with NOT_FOUND. */ -} cache_result_bits_t; - -typedef uint32_t cache_result_t; - -#define CACHE_RESULT_IS_OK(result) (result & CACHE_RESULT_OK) -#define CACHE_RESULT_IS_NOT_FOUND(result) (result & CACHE_RESULT_NOT_FOUND) -#define CACHE_RESULT_IS_ERROR(result) (result & CACHE_RESULT_ERROR) -#define CACHE_RESULT_IS_OUT_OF_RESOURCES(result) (result & CACHE_RESULT_OUT_OF_RESOURCES) -#define CACHE_RESULT_IS_STALE(result) (result & CACHE_RESULT_STALE) -#define CACHE_RESULT_IS_DISCARDED(result) (result & CACHE_RESULT_DISCARDED) - -typedef enum cache_flags -{ - CACHE_FLAGS_NONE = 0x00, - CACHE_FLAGS_INCLUDE_STALE = 0x01, -} cache_flags_t; - -typedef enum cache_storage_info -{ - // TODO: Provide more granularity. - CACHE_STORAGE_INFO_ALL = 0 -} cache_storage_info_t; - -typedef enum cache_thread_model -{ - CACHE_THREAD_MODEL_ST, - CACHE_THREAD_MODEL_MT -} cache_thread_model_t; - -typedef void* CACHE_STORAGE; - -typedef struct cache_key -{ - uint64_t data; -} CACHE_KEY; - -/** - * Hashes a CACHE_KEY to a size_t - * - * @param key The key to be hashed. - * - * @return The corresponding hash. - */ -size_t cache_key_hash(const CACHE_KEY* key); - -/** - * Are two CACHE_KEYs equal. - * - * @param lhs One cache key. - * @param rhs Another cache key. - * - * @return True, if the keys are equal. - */ -bool cache_key_equal_to(const CACHE_KEY* lhs, const CACHE_KEY* rhs); - -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; - -static inline bool cache_storage_has_cap(uint32_t capabilities, uint32_t mask) -{ - return (capabilities & mask) == mask; -} - -typedef struct cache_storage_config_t -{ - /** - * Specifies 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. - */ - cache_thread_model_t thread_model; - - /** - * Hard Time-to-live; number of seconds the value is valid. A value of 0 means - * that there is no time-to-live, but that the value is considered fresh - * as long as it is available. - */ - uint32_t hard_ttl; - - /** - * Soft Time-to-live; number of seconds the value is valid. A value of 0 means - * that there is no time-to-live, but that the value is considered fresh - * as long as it is available. When the soft TTL has passed, but the hard TTL - * has not yet been reached, the stale cached value will be returned, provided - * the flag @c CACHE_FLAGS_INCLUDE_STALE is specified when getting the value. - */ - uint32_t soft_ttl; - - /** - * The maximum number of items the storage may store, before it should - * evict some items. A value of 0 means that there is no limit. The caller - * should specify 0, unless CACHE_STORAGE_CAP_MAX_COUNT is returned at - * initialization. - */ - uint32_t max_count; - - /** - * The maximum size of the storage may may occupy, before it should evict - * some items. A value of 0 means that there is no limit. The caller should - * specify 0, unless CACHE_STORAGE_CAP_MAX_SIZE is returned at initialization. - */ - uint64_t max_size; -} CACHE_STORAGE_CONFIG; - -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)(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 name The name of the cache instance. - * @param config The storage configuration. - * @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)(const char* name, - const CACHE_STORAGE_CONFIG* config, - int argc, char* argv[]); - - /** - * Frees an CACHE_STORAGE instance earlier created with createInstance. - * - * @param instance The CACHE_STORAGE instance to be freed. - */ - void (* freeInstance)(CACHE_STORAGE* instance); - - /** - * Returns the configuration the storage was created with. - * - * @param storage Pointer to a CACHE_STORAGE - * @param config Pointer to variable that will be updated with the config. - */ - void (* getConfig)(CACHE_STORAGE* storage, - CACHE_STORAGE_CONFIG* config); - - /** - * Returns information about the storage. - * - * @param storage Pointer to a CACHE_STORAGE. - * @param what Bitmask of cache_storage_info_t values. - * @param info Upon successful return points to json_t object containing - * information. The caller should call @c json_decref on the - * object when it is no longer needed. - * - * @return CACHE_RESULT_OK if a json object could be created. - */ - cache_result_t (* getInfo)(CACHE_STORAGE* storage, - uint32_t what, - json_t** info); - /** - * Get a value from the cache. - * - * @param storage Pointer to a CACHE_STORAGE. - * @param key A key generated with get_key. - * @param flags Mask of cache_flags_t values. - * @param soft_ttl The soft TTL. A value of CACHE_USE_CONFIG_TTL (-1) indicates - * that the value specfied in the config, used in the creation, - * should be used. - * @param hard_ttl The hard TTL. A value of CACHE_USE_CONFIG_TTL (-1) indicates - * that the value specfied in the config, used in the creation, - * should be used. - * @param result Pointer to variable that after a successful return will - * point to a GWBUF. - * - * @return CACHE_RESULT_OK if item was found, CACHE_RESULT_NOT_FOUND if - * item was not found or some other error code. In the OK an NOT_FOUND - * cases, the bit CACHE_RESULT_STALE is set if the item exists but the - * soft TTL has passed. In the NOT_FOUND case, the but CACHE_RESULT_DISCARDED - * if the item existed but the hard TTL had passed. - */ - cache_result_t (* getValue)(CACHE_STORAGE* storage, - const CACHE_KEY* key, - uint32_t flags, - uint32_t soft_ttl, - uint32_t hard_ttl, - GWBUF** result); - - /** - * Put a value to the cache. - * - * @param storage Pointer to a CACHE_STORAGE. - * @param key A key generated with get_key. - * @param value Pointer to GWBUF containing the value to be stored. - * Must be one contiguous buffer. - * - * @return CACHE_RESULT_OK if item was successfully put, - * CACHE_RESULT_OUT_OF_RESOURCES if item could not be put, due to - * some resource having become exhausted, or some other error code. - */ - cache_result_t (* putValue)(CACHE_STORAGE* storage, - const CACHE_KEY* key, - const GWBUF* value); - - /** - * Delete a value from the cache. - * - * @param storage Pointer to a CACHE_STORAGE. - * @param key A key generated with get_key. - * - * @return CACHE_RESULT_OK if item was successfully deleted. Note that - * CACHE_RESULT_OK may be returned also if the entry was not present. - */ - cache_result_t (* delValue)(CACHE_STORAGE* storage, - const CACHE_KEY* key); - - /** - * Get the head item from the storage. This is only intended for testing and - * debugging purposes and if the storage is being used by different threads - * at the same time, the returned result may be incorrect the moment it has - * been returned. - * - * @param storage Pointer to a CACHE_STORAGE. - * @param key Pointer to variable that after a successful return will - * contain the key. - * @param head Pointer to variable that after a successful return will - * point to a GWBUF. - * - * @return CACHE_RESULT_OK if the head item was returned, - * CACHE_RESULT_NOT_FOUND if the cache is empty, - * CACHE_RESULT_OUT_OF_RESOURCES if the storage is incapable of - * returning the head, and - * CACHE_RESULT_ERROR otherwise. - */ - cache_result_t (* getHead)(CACHE_STORAGE* storage, - CACHE_KEY* key, - GWBUF** head); - - /** - * Get the tail item from the cache. This is only intended for testing and - * debugging purposes and if the storage is being used by different threads - * at the same time, the returned result may become incorrect the moment it - * has been returned. - * - * @param storage Pointer to a CACHE_STORAGE. - * @param key Pointer to variable that after a successful return will - * contain the key. - * @param tail Pointer to variable that after a successful return will - * point to a GWBUF. - * - * @return CACHE_RESULT_OK if the head item was returned, - * CACHE_RESULT_NOT_FOUND if the cache is empty, - * CACHE_RESULT_OUT_OF_RESOURCES if the storage is incapable of - * returning the tail, and - * CACHE_RESULT_ERROR otherwise. - */ - cache_result_t (* getTail)(CACHE_STORAGE* storage, - CACHE_KEY* key, - GWBUF** tail); - - /** - * Get the current size of the storage. This is only intended for testing and - * debugging purposes and if the storage is being used by different threads - * at the same time, the returned result may become incorrect the moment it - * has been returned. - * - * @param storage Pointer to a CACHE_STORAGE. - * @param size Pointer to variable that after a successful return will - * contain the current size of the storage. - * - * @return CACHE_RESULT_OK if the size was returned, - * CACHE_RESULT_OUT_OF_RESOURCES if the storage - * is incapable of returning the size, and - * CACHE_RESULT_ERROR otherwise. - */ - cache_result_t (* getSize)(CACHE_STORAGE* storage, - uint64_t* size); - - /** - * Get the current number of items in the storage. This is only intended for - * testing and debugging purposes and if the storage is being used by different - * threads at the same time, the returned result may become incorrect the moment - * it has been returned. - * - * @param storage Pointer to a CACHE_STORAGE. - * @param items Pointer to variable that after a successful return will - * contain the current number of items in the storage. - * - * @return CACHE_RESULT_OK if the size was returned, - * CACHE_RESULT_OUT_OF_RESOURCES if the storage - * is incapable of returning the size, and - * CACHE_RESULT_ERROR otherwise. - */ - cache_result_t (* getItems)(CACHE_STORAGE* storage, - uint64_t* items); -} CACHE_STORAGE_API; - -#if defined __cplusplus -const uint32_t CACHE_USE_CONFIG_TTL = static_cast(-1); -#else -#define CACHE_USE_CONFIG_TTL ((uint32_t)-1) -#endif - -#define CACHE_STORAGE_ENTRY_POINT "CacheGetStorageAPI" -typedef CACHE_STORAGE_API* (* CacheGetStorageAPIFN)(); - -MXS_END_DECLS diff --git a/server/modules/filter/cache/cache_storage_api.hh b/server/modules/filter/cache/cache_storage_api.hh index cd6ca234b..aff1b41e4 100644 --- a/server/modules/filter/cache/cache_storage_api.hh +++ b/server/modules/filter/cache/cache_storage_api.hh @@ -13,10 +13,343 @@ #pragma once #include + +#include +#include +#include + #include #include -#include -#include "cache_storage_api.h" + +#include +#include + +typedef enum cache_result_bits +{ + CACHE_RESULT_OK = 0x01, + CACHE_RESULT_NOT_FOUND = 0x02, + CACHE_RESULT_ERROR = 0x03, + CACHE_RESULT_OUT_OF_RESOURCES = 0x04, + + CACHE_RESULT_STALE = 0x10000, /*< Possibly combined with OK and NOT_FOUND. */ + CACHE_RESULT_DISCARDED = 0x20000, /*< Possibly combined with NOT_FOUND. */ +} cache_result_bits_t; + +typedef uint32_t cache_result_t; + +#define CACHE_RESULT_IS_OK(result) (result & CACHE_RESULT_OK) +#define CACHE_RESULT_IS_NOT_FOUND(result) (result & CACHE_RESULT_NOT_FOUND) +#define CACHE_RESULT_IS_ERROR(result) (result & CACHE_RESULT_ERROR) +#define CACHE_RESULT_IS_OUT_OF_RESOURCES(result) (result & CACHE_RESULT_OUT_OF_RESOURCES) +#define CACHE_RESULT_IS_STALE(result) (result & CACHE_RESULT_STALE) +#define CACHE_RESULT_IS_DISCARDED(result) (result & CACHE_RESULT_DISCARDED) + +typedef enum cache_flags +{ + CACHE_FLAGS_NONE = 0x00, + CACHE_FLAGS_INCLUDE_STALE = 0x01, +} cache_flags_t; + +typedef enum cache_storage_info +{ + // TODO: Provide more granularity. + CACHE_STORAGE_INFO_ALL = 0 +} cache_storage_info_t; + +typedef enum cache_thread_model +{ + CACHE_THREAD_MODEL_ST, + CACHE_THREAD_MODEL_MT +} cache_thread_model_t; + +typedef void* CACHE_STORAGE; + +typedef struct cache_key +{ + uint64_t data; +} CACHE_KEY; + +/** + * Hashes a CACHE_KEY to a size_t + * + * @param key The key to be hashed. + * + * @return The corresponding hash. + */ +size_t cache_key_hash(const CACHE_KEY* key); + +/** + * Are two CACHE_KEYs equal. + * + * @param lhs One cache key. + * @param rhs Another cache key. + * + * @return True, if the keys are equal. + */ +bool cache_key_equal_to(const CACHE_KEY* lhs, const CACHE_KEY* rhs); + +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; + +static inline bool cache_storage_has_cap(uint32_t capabilities, uint32_t mask) +{ + return (capabilities & mask) == mask; +} + +typedef struct cache_storage_config_t +{ + /** + * Specifies 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. + */ + cache_thread_model_t thread_model; + + /** + * Hard Time-to-live; number of seconds the value is valid. A value of 0 means + * that there is no time-to-live, but that the value is considered fresh + * as long as it is available. + */ + uint32_t hard_ttl; + + /** + * Soft Time-to-live; number of seconds the value is valid. A value of 0 means + * that there is no time-to-live, but that the value is considered fresh + * as long as it is available. When the soft TTL has passed, but the hard TTL + * has not yet been reached, the stale cached value will be returned, provided + * the flag @c CACHE_FLAGS_INCLUDE_STALE is specified when getting the value. + */ + uint32_t soft_ttl; + + /** + * The maximum number of items the storage may store, before it should + * evict some items. A value of 0 means that there is no limit. The caller + * should specify 0, unless CACHE_STORAGE_CAP_MAX_COUNT is returned at + * initialization. + */ + uint32_t max_count; + + /** + * The maximum size of the storage may may occupy, before it should evict + * some items. A value of 0 means that there is no limit. The caller should + * specify 0, unless CACHE_STORAGE_CAP_MAX_SIZE is returned at initialization. + */ + uint64_t max_size; +} CACHE_STORAGE_CONFIG; + +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)(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 name The name of the cache instance. + * @param config The storage configuration. + * @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)(const char* name, + const CACHE_STORAGE_CONFIG* config, + int argc, char* argv[]); + + /** + * Frees an CACHE_STORAGE instance earlier created with createInstance. + * + * @param instance The CACHE_STORAGE instance to be freed. + */ + void (* freeInstance)(CACHE_STORAGE* instance); + + /** + * Returns the configuration the storage was created with. + * + * @param storage Pointer to a CACHE_STORAGE + * @param config Pointer to variable that will be updated with the config. + */ + void (* getConfig)(CACHE_STORAGE* storage, + CACHE_STORAGE_CONFIG* config); + + /** + * Returns information about the storage. + * + * @param storage Pointer to a CACHE_STORAGE. + * @param what Bitmask of cache_storage_info_t values. + * @param info Upon successful return points to json_t object containing + * information. The caller should call @c json_decref on the + * object when it is no longer needed. + * + * @return CACHE_RESULT_OK if a json object could be created. + */ + cache_result_t (* getInfo)(CACHE_STORAGE* storage, + uint32_t what, + json_t** info); + /** + * Get a value from the cache. + * + * @param storage Pointer to a CACHE_STORAGE. + * @param key A key generated with get_key. + * @param flags Mask of cache_flags_t values. + * @param soft_ttl The soft TTL. A value of CACHE_USE_CONFIG_TTL (-1) indicates + * that the value specfied in the config, used in the creation, + * should be used. + * @param hard_ttl The hard TTL. A value of CACHE_USE_CONFIG_TTL (-1) indicates + * that the value specfied in the config, used in the creation, + * should be used. + * @param result Pointer to variable that after a successful return will + * point to a GWBUF. + * + * @return CACHE_RESULT_OK if item was found, CACHE_RESULT_NOT_FOUND if + * item was not found or some other error code. In the OK an NOT_FOUND + * cases, the bit CACHE_RESULT_STALE is set if the item exists but the + * soft TTL has passed. In the NOT_FOUND case, the but CACHE_RESULT_DISCARDED + * if the item existed but the hard TTL had passed. + */ + cache_result_t (* getValue)(CACHE_STORAGE* storage, + const CACHE_KEY* key, + uint32_t flags, + uint32_t soft_ttl, + uint32_t hard_ttl, + GWBUF** result); + + /** + * Put a value to the cache. + * + * @param storage Pointer to a CACHE_STORAGE. + * @param key A key generated with get_key. + * @param value Pointer to GWBUF containing the value to be stored. + * Must be one contiguous buffer. + * + * @return CACHE_RESULT_OK if item was successfully put, + * CACHE_RESULT_OUT_OF_RESOURCES if item could not be put, due to + * some resource having become exhausted, or some other error code. + */ + cache_result_t (* putValue)(CACHE_STORAGE* storage, + const CACHE_KEY* key, + const GWBUF* value); + + /** + * Delete a value from the cache. + * + * @param storage Pointer to a CACHE_STORAGE. + * @param key A key generated with get_key. + * + * @return CACHE_RESULT_OK if item was successfully deleted. Note that + * CACHE_RESULT_OK may be returned also if the entry was not present. + */ + cache_result_t (* delValue)(CACHE_STORAGE* storage, + const CACHE_KEY* key); + + /** + * Get the head item from the storage. This is only intended for testing and + * debugging purposes and if the storage is being used by different threads + * at the same time, the returned result may be incorrect the moment it has + * been returned. + * + * @param storage Pointer to a CACHE_STORAGE. + * @param key Pointer to variable that after a successful return will + * contain the key. + * @param head Pointer to variable that after a successful return will + * point to a GWBUF. + * + * @return CACHE_RESULT_OK if the head item was returned, + * CACHE_RESULT_NOT_FOUND if the cache is empty, + * CACHE_RESULT_OUT_OF_RESOURCES if the storage is incapable of + * returning the head, and + * CACHE_RESULT_ERROR otherwise. + */ + cache_result_t (* getHead)(CACHE_STORAGE* storage, + CACHE_KEY* key, + GWBUF** head); + + /** + * Get the tail item from the cache. This is only intended for testing and + * debugging purposes and if the storage is being used by different threads + * at the same time, the returned result may become incorrect the moment it + * has been returned. + * + * @param storage Pointer to a CACHE_STORAGE. + * @param key Pointer to variable that after a successful return will + * contain the key. + * @param tail Pointer to variable that after a successful return will + * point to a GWBUF. + * + * @return CACHE_RESULT_OK if the head item was returned, + * CACHE_RESULT_NOT_FOUND if the cache is empty, + * CACHE_RESULT_OUT_OF_RESOURCES if the storage is incapable of + * returning the tail, and + * CACHE_RESULT_ERROR otherwise. + */ + cache_result_t (* getTail)(CACHE_STORAGE* storage, + CACHE_KEY* key, + GWBUF** tail); + + /** + * Get the current size of the storage. This is only intended for testing and + * debugging purposes and if the storage is being used by different threads + * at the same time, the returned result may become incorrect the moment it + * has been returned. + * + * @param storage Pointer to a CACHE_STORAGE. + * @param size Pointer to variable that after a successful return will + * contain the current size of the storage. + * + * @return CACHE_RESULT_OK if the size was returned, + * CACHE_RESULT_OUT_OF_RESOURCES if the storage + * is incapable of returning the size, and + * CACHE_RESULT_ERROR otherwise. + */ + cache_result_t (* getSize)(CACHE_STORAGE* storage, + uint64_t* size); + + /** + * Get the current number of items in the storage. This is only intended for + * testing and debugging purposes and if the storage is being used by different + * threads at the same time, the returned result may become incorrect the moment + * it has been returned. + * + * @param storage Pointer to a CACHE_STORAGE. + * @param items Pointer to variable that after a successful return will + * contain the current number of items in the storage. + * + * @return CACHE_RESULT_OK if the size was returned, + * CACHE_RESULT_OUT_OF_RESOURCES if the storage + * is incapable of returning the size, and + * CACHE_RESULT_ERROR otherwise. + */ + cache_result_t (* getItems)(CACHE_STORAGE* storage, + uint64_t* items); +} CACHE_STORAGE_API; + +#if defined __cplusplus +const uint32_t CACHE_USE_CONFIG_TTL = static_cast(-1); +#else +#define CACHE_USE_CONFIG_TTL ((uint32_t)-1) +#endif + +#define CACHE_STORAGE_ENTRY_POINT "CacheGetStorageAPI" +typedef CACHE_STORAGE_API* (* CacheGetStorageAPIFN)(); namespace std diff --git a/server/modules/filter/cache/cachefilter.h b/server/modules/filter/cache/cachefilter.h deleted file mode 100644 index 5468fc213..000000000 --- a/server/modules/filter/cache/cachefilter.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2018 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/bsl11. - * - * Change Date: 2022-01-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. - */ -#pragma once - -#include -#include -#include "cache_storage_api.h" -#include "rules.h" - - -#define CACHE_DEBUG_NONE 0 /* 0b00000 */ -#define CACHE_DEBUG_MATCHING 1 /* 0b00001 */ -#define CACHE_DEBUG_NON_MATCHING 2 /* 0b00010 */ -#define CACHE_DEBUG_USE 4 /* 0b00100 */ -#define CACHE_DEBUG_NON_USE 8 /* 0b01000 */ -#define CACHE_DEBUG_DECISIONS 16 /* 0b10000 */ - -#define CACHE_DEBUG_RULES (CACHE_DEBUG_MATCHING | CACHE_DEBUG_NON_MATCHING) -#define CACHE_DEBUG_USAGE (CACHE_DEBUG_USE | CACHE_DEBUG_NON_USE) -#define CACHE_DEBUG_MIN CACHE_DEBUG_NONE -#define CACHE_DEBUG_MAX (CACHE_DEBUG_RULES | CACHE_DEBUG_USAGE | CACHE_DEBUG_DECISIONS) - -#if !defined (UINT32_MAX) -#define UINT32_MAX (4294967295U) -#endif - -#if !defined (UINT64_MAX) -#define UINT64_MAX (18446744073709551615UL) -#endif - -typedef enum cache_selects -{ - CACHE_SELECTS_ASSUME_CACHEABLE, - CACHE_SELECTS_VERIFY_CACHEABLE, -} cache_selects_t; - -// Count -#define CACHE_ZDEFAULT_MAX_RESULTSET_ROWS "0" -// Bytes -#define CACHE_ZDEFAULT_MAX_RESULTSET_SIZE "0" -// Seconds -#define CACHE_ZDEFAULT_HARD_TTL "0" -// Seconds -#define CACHE_ZDEFAULT_SOFT_TTL "0" -// Integer value -#define CACHE_ZDEFAULT_DEBUG "0" -// Positive integer -#define CACHE_ZDEFAULT_MAX_COUNT "0" -// Positive integer -#define CACHE_ZDEFAULT_MAX_SIZE "0" -// Thread model -#define CACHE_ZDEFAULT_THREAD_MODEL "thread_specific" -const cache_thread_model CACHE_DEFAULT_THREAD_MODEL = CACHE_THREAD_MODEL_ST; -// Cacheable selects -#define CACHE_ZDEFAULT_SELECTS "assume_cacheable" -const cache_selects_t CACHE_DEFAULT_SELECTS = CACHE_SELECTS_ASSUME_CACHEABLE; -// Storage -#define CACHE_ZDEFAULT_STORAGE "storage_inmemory" -// Transaction behaviour -#define CACHE_ZDEFAULT_CACHE_IN_TRXS "all_transactions" -// Enabled -#define CACHE_ZDEFAULT_ENABLED "true" - -typedef enum cache_in_trxs -{ - // Do NOT change the order. Code relies upon NEVER < READ_ONLY < ALL. - CACHE_IN_TRXS_NEVER, - CACHE_IN_TRXS_READ_ONLY, - CACHE_IN_TRXS_ALL, -} cache_in_trxs_t; - -typedef struct cache_config -{ - uint64_t max_resultset_rows; /**< The maximum number of rows of a resultset for it to be - * cached. */ - uint64_t max_resultset_size;/**< The maximum size of a resultset for it to be cached. */ - char* rules; /**< Name of rules file. */ - char* storage; /**< Name of storage module. */ - char* storage_options; /**< Raw options for storage module. */ - char** storage_argv; /**< Cooked options for storage module. */ - int storage_argc; /**< Number of cooked options. */ - uint32_t hard_ttl; /**< Hard time to live. */ - uint32_t soft_ttl; /**< Soft time to live. */ - uint64_t max_count; /**< Maximum number of entries in the cache.*/ - uint64_t max_size; /**< Maximum size of the cache.*/ - uint32_t debug; /**< Debug settings. */ - cache_thread_model_t thread_model; /**< Thread model. */ - cache_selects_t selects; /**< Assume/verify that selects are cacheable. */ - cache_in_trxs_t cache_in_trxs; /**< To cache or not to cache inside transactions. */ - bool enabled; /**< Whether the cache is enabled or not. */ -} CACHE_CONFIG; diff --git a/server/modules/filter/cache/cachefilter.hh b/server/modules/filter/cache/cachefilter.hh index 131f6143c..962d57a02 100644 --- a/server/modules/filter/cache/cachefilter.hh +++ b/server/modules/filter/cache/cachefilter.hh @@ -13,10 +13,13 @@ #pragma once #include +#include #include -#include "cachefilter.h" +#include "rules.hh" +#include "cache.hh" #include "cachefiltersession.hh" + class CacheFilter : public maxscale::Filter { public: diff --git a/server/modules/filter/cache/cachefiltersession.hh b/server/modules/filter/cache/cachefiltersession.hh index 5cc5b86f0..bfff45495 100644 --- a/server/modules/filter/cache/cachefiltersession.hh +++ b/server/modules/filter/cache/cachefiltersession.hh @@ -16,8 +16,8 @@ #include #include #include "cache.hh" -#include "cachefilter.h" -#include "cache_storage_api.h" +#include "cachefilter.hh" +#include "cache_storage_api.hh" class CacheFilterSession : public maxscale::FilterSession { diff --git a/server/modules/filter/cache/lrustorage.hh b/server/modules/filter/cache/lrustorage.hh index a9746c951..d7235868e 100644 --- a/server/modules/filter/cache/lrustorage.hh +++ b/server/modules/filter/cache/lrustorage.hh @@ -14,7 +14,7 @@ #include #include -#include "cachefilter.h" +#include "cachefilter.hh" #include "cache_storage_api.hh" #include "storage.hh" diff --git a/server/modules/filter/cache/rules.cc b/server/modules/filter/cache/rules.cc index 4a72c60c5..dbdfddbbf 100644 --- a/server/modules/filter/cache/rules.cc +++ b/server/modules/filter/cache/rules.cc @@ -12,7 +12,7 @@ */ #define MXS_MODULE_NAME "cache" -#include "rules.h" +#include "rules.hh" #include #include @@ -27,7 +27,7 @@ #include #include -#include "cachefilter.h" +#include "cachefilter.hh" static int next_thread_id = 0; static thread_local int current_thread_id = -1; diff --git a/server/modules/filter/cache/rules.h b/server/modules/filter/cache/rules.hh similarity index 99% rename from server/modules/filter/cache/rules.h rename to server/modules/filter/cache/rules.hh index 379ad1c1d..fb80c98e8 100644 --- a/server/modules/filter/cache/rules.h +++ b/server/modules/filter/cache/rules.hh @@ -14,7 +14,7 @@ * Public License. */ -#include +#include #include #include #include diff --git a/server/modules/filter/cache/storage.hh b/server/modules/filter/cache/storage.hh index eb4730269..e7a157a55 100644 --- a/server/modules/filter/cache/storage.hh +++ b/server/modules/filter/cache/storage.hh @@ -13,7 +13,7 @@ #pragma once #include -#include "cache_storage_api.h" +#include "cache_storage_api.hh" class Storage { diff --git a/server/modules/filter/cache/storage/storage_inmemory/storage_inmemory.cc b/server/modules/filter/cache/storage/storage_inmemory/storage_inmemory.cc index 15399518a..25706559c 100644 --- a/server/modules/filter/cache/storage/storage_inmemory/storage_inmemory.cc +++ b/server/modules/filter/cache/storage/storage_inmemory/storage_inmemory.cc @@ -13,7 +13,7 @@ #define MXS_MODULE_NAME "storage_inmemory" #include -#include "../../cache_storage_api.h" +#include "../../cache_storage_api.hh" #include "../storagemodule.hh" #include "inmemorystoragest.hh" diff --git a/server/modules/filter/cache/storagefactory.cc b/server/modules/filter/cache/storagefactory.cc index ccec2e788..d2c575bc1 100644 --- a/server/modules/filter/cache/storagefactory.cc +++ b/server/modules/filter/cache/storagefactory.cc @@ -19,7 +19,7 @@ #include #include #include -#include "cachefilter.h" +#include "cachefilter.hh" #include "lrustoragest.hh" #include "lrustoragemt.hh" #include "storagereal.hh" diff --git a/server/modules/filter/cache/storagefactory.hh b/server/modules/filter/cache/storagefactory.hh index 25db32cbc..956fa503e 100644 --- a/server/modules/filter/cache/storagefactory.hh +++ b/server/modules/filter/cache/storagefactory.hh @@ -13,7 +13,7 @@ #pragma once #include -#include "cache_storage_api.h" +#include "cache_storage_api.hh" class Storage; diff --git a/server/modules/filter/cache/test/test_cacheoptions.cc b/server/modules/filter/cache/test/test_cacheoptions.cc index 7668c0e45..db4a0878c 100644 --- a/server/modules/filter/cache/test/test_cacheoptions.cc +++ b/server/modules/filter/cache/test/test_cacheoptions.cc @@ -18,7 +18,7 @@ #include #include #include -#include "../cachefilter.h" +#include "../cachefilter.hh" using namespace std; using maxscale::FilterModule; diff --git a/server/modules/filter/cache/test/testrules.cc b/server/modules/filter/cache/test/testrules.cc index 3b83aca11..9418b3fae 100644 --- a/server/modules/filter/cache/test/testrules.cc +++ b/server/modules/filter/cache/test/testrules.cc @@ -11,7 +11,7 @@ * Public License. */ -#include "rules.h" +#include "rules.hh" #include #include #include