diff --git a/server/core/maxscale/trxboundaryparser.hh b/server/core/maxscale/trxboundaryparser.hh index d21eda98d..0b80a3933 100644 --- a/server/core/maxscale/trxboundaryparser.hh +++ b/server/core/maxscale/trxboundaryparser.hh @@ -13,6 +13,8 @@ */ #include +#include +#include #include namespace maxscale @@ -89,6 +91,29 @@ public: { } + /** + * Return the type mask of a statement, provided the statement affects + * transaction state or autocommit mode. + * + * @param pSql SQL statament. + * @param len Length of pSql. + * + * @return The corresponding type mask or 0, if the statement does not + * affect transaction state or autocommit mode. + */ + uint32_t type_mask_of(const char* pSql, size_t len) + { + uint32_t type_mask = 0; + + m_pSql = pSql; + m_len = len; + + m_pI = m_pSql; + m_pEnd = m_pI + m_len; + + return parse(); + } + /** * Return the type mask of a statement, provided the statement affects * transaction state or autocommit mode. diff --git a/server/core/test/CMakeLists.txt b/server/core/test/CMakeLists.txt index 1c0dfb992..077731156 100644 --- a/server/core/test/CMakeLists.txt +++ b/server/core/test/CMakeLists.txt @@ -20,6 +20,7 @@ add_executable(testfeedback testfeedback.c) add_executable(testmaxscalepcre2 testmaxscalepcre2.c) add_executable(testmodulecmd testmodulecmd.c) add_executable(testconfig testconfig.c) +add_executable(trxboundaryparser_profile trxboundaryparser_profile.cc) target_link_libraries(test_adminusers maxscale-common) target_link_libraries(test_buffer maxscale-common) target_link_libraries(test_dcb maxscale-common) @@ -42,6 +43,7 @@ target_link_libraries(testfeedback maxscale-common) target_link_libraries(testmaxscalepcre2 maxscale-common) target_link_libraries(testmodulecmd maxscale-common) target_link_libraries(testconfig maxscale-common) +target_link_libraries(trxboundaryparser_profile maxscale-common) add_test(TestAdminUsers test_adminusers) add_test(TestBuffer test_buffer) add_test(TestDCB test_dcb) diff --git a/server/core/test/trxboundaryparser_profile.cc b/server/core/test/trxboundaryparser_profile.cc new file mode 100644 index 000000000..be9a6043f --- /dev/null +++ b/server/core/test/trxboundaryparser_profile.cc @@ -0,0 +1,116 @@ +/* + * 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: 2019-07-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 +#include +#include +#include +#include "../maxscale/trxboundaryparser.hh" + +using namespace std; + +namespace +{ + +char USAGE[] = "usage: trxboundaryparser -n count -s statement\n"; + +timespec timespec_subtract(const timespec& later, const timespec& earlier) +{ + timespec result = { 0, 0 }; + + ss_dassert((later.tv_sec > earlier.tv_sec) || + ((later.tv_sec == earlier.tv_sec) && (later.tv_nsec > earlier.tv_nsec))); + + if (later.tv_nsec >= earlier.tv_nsec) + { + result.tv_sec = later.tv_sec - earlier.tv_sec; + result.tv_nsec = later.tv_nsec - earlier.tv_nsec; + } + else + { + result.tv_sec = later.tv_sec - earlier.tv_sec - 1; + result.tv_nsec = 1000000000 + later.tv_nsec - earlier.tv_nsec; + } + + return result; +} + +} + +int main(int argc, char* argv[]) +{ + int rc = EXIT_SUCCESS; + + int nCount = 0; + const char* zStatement = NULL; + + int c; + while ((c = getopt(argc, argv, "n:s:")) != -1) + { + switch (c) + { + case 'n': + nCount = atoi(optarg); + break; + + case 's': + zStatement = optarg; + break; + + default: + rc = EXIT_FAILURE; + } + } + + if ((rc == EXIT_SUCCESS) && zStatement && (nCount > 0)) + { + rc = EXIT_FAILURE; + + set_datadir(strdup("/tmp")); + set_langdir(strdup(".")); + set_process_datadir(strdup("/tmp")); + + if (mxs_log_init(NULL, ".", MXS_LOG_TARGET_DEFAULT)) + { + size_t len = strlen(zStatement); + maxscale::TrxBoundaryParser parser; + + struct timespec start; + clock_gettime(CLOCK_MONOTONIC_RAW, &start); + + for (int i = 0; i < nCount; ++i) + { + parser.type_mask_of(zStatement, len); + } + + struct timespec finish; + clock_gettime(CLOCK_MONOTONIC_RAW, &finish); + + struct timespec diff = timespec_subtract(finish, start); + + cout << "Time:" << diff.tv_sec << "." << setfill('0') << setw(9) << diff.tv_nsec << endl; + + mxs_log_finish(); + } + else + { + cerr << "error: Could not initialize log." << endl; + } + } + else + { + cout << USAGE << endl; + } + + return rc; +}