minor, add cache in ODBC
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/27dfdbc6 Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/27dfdbc6 Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/27dfdbc6 Branch: refs/heads/master Commit: 27dfdbc65fa68609a8c9fd26c75067d1df4b6753 Parents: 3dbdbf5 Author: Roger Shi <[email protected]> Authored: Thu Jun 15 15:12:15 2017 +0800 Committer: Dong Li <[email protected]> Committed: Thu Jun 15 16:49:07 2017 +0800 ---------------------------------------------------------------------- odbc/Common/QueryCache.cpp | 84 +++++++++++++++-------------------------- odbc/Common/QueryCache.h | 1 + odbc/Common/REST.cpp | 14 +------ 3 files changed, 32 insertions(+), 67 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/kylin/blob/27dfdbc6/odbc/Common/QueryCache.cpp ---------------------------------------------------------------------- diff --git a/odbc/Common/QueryCache.cpp b/odbc/Common/QueryCache.cpp index 48c187e..6b49273 100644 --- a/odbc/Common/QueryCache.cpp +++ b/odbc/Common/QueryCache.cpp @@ -23,72 +23,48 @@ #include <cpprest/json.h> #include <cpprest/uri.h> #include <regex> +#include <map> +#include <queue> +#include <mutex> #include "Dump.h" #include "JsonConverter.h" +using namespace std; -const wchar_t* alwaysFailQueries[7] = { - L"(\\s)*CREATE(\\s)*LOCAL(\\s)*TEMPORARY(\\s)*TABLE(\\s)*\"XTableau_B_Connect\"(\\s)*\\((\\s)*\"COL\"(\\s)*INTEGER(\\s)*\\)(\\s)*ON(\\s)*COMMIT(\\s)*PRESERVE(\\s)*ROWS(\\s)*", - L"(\\s)*DROP(\\s)*TABLE(\\s)*\"XTableau_B_Connect\"(\\s)*", - L"(\\s)*SELECT(\\s)*TOP(\\s)*1(\\s)*\"COL\"(\\s)*FROM(\\s)*\\(SELECT(\\s)*1(\\s)*AS(\\s)*\"COL\"(\\s)*\\)(\\s)*AS(\\s)*\"CHECKTOP\"(\\s)*", - L"(\\s)*SELECT(\\s)*\"SUBCOL\"(\\s)*AS(\\s)*\"COL\"(\\s)*FROM(\\s)*\\((\\s)*SELECT(\\s)*1(\\s)*AS(\\s)*\"SUBCOL\"(\\s)*\\)(\\s)*\"SUBQUERY\"(\\s)*GROUP(\\s)*BY(\\s)*1(\\s)*", - L"(\\s)*SELECT(\\s)*\"SUBCOL\"(\\s)*AS(\\s)*\"COL\"(\\s)*FROM(\\s)*\\((\\s)*SELECT(\\s)*1(\\s)*AS(\\s)*\"SUBCOL\"(\\s)*\\)(\\s)*\"SUBQUERY\"(\\s)*GROUP(\\s)*BY(\\s)*\"COL\"(\\s)*", - L"(\\s)*INSERT(\\s)*INTO(\\s)*\"XTableau_C_Connect\"(\\s)*SELECT(\\s)*\\*(\\s)*FROM(\\s)*\\(SELECT(\\s)*1(\\s)*AS(\\s)*COL(\\s)*\\)(\\s)*AS(\\s)*CHECKTEMP(\\s)*LIMIT(\\s)*1(\\s)*", - L"(\\s)*DROP(\\s)*TABLE(\\s)*\"XTableau_C_Connect\"(\\s)*" -}; +map<wstring, wstring> queryMap; +queue<wstring> queryQueue; +const int cacheSize = 20; +mutex cacheMutex; -const wchar_t* alwaysSuccessQueries[3] = { - L"(\\s)*SELECT(\\s)*1(\\s)*", - L"(\\s)*SELECT(\\s)*\"COL\"(\\s)*FROM(\\s)*\\(SELECT(\\s)*1(\\s)*AS(\\s)*\"COL\"\\)(\\s)*AS(\\s)*\"SUBQUERY\"(\\s)*", - L"(\\s)*SELECT(\\s)*\"COL\"(\\s)*FROM(\\s)*\\(SELECT(\\s)*1(\\s)*AS(\\s)*\"COL\"\\)(\\s)*AS(\\s)*\"CHECKTOP\"(\\s)*LIMIT(\\s)*1(\\s)*" -}; - -const wchar_t* alwaysSuccessResults[3] = { - L"{\"columnMetas\":[{\"isNullable\":2,\"displaySize\":11,\"label\":\"COL\",\"name\":\"COL\",\"schemaName\":\"\",\"catelogName\":\"\",\"tableName\":\"\",\"precision\":10,\"scale\":0,\"columnType\":4,\"columnTypeName\":\"int4\",\"writable\":true,\"caseSensitive\":false,\"autoIncrement\":false,\"searchable\":true,\"currency\":false,\"signed\":true,\"definitelyWritable\":false,\"readOnly\":false}],\"results\":[[\"1\"]],\"isResultsFlatten\":false,\"flattenResult\":null,\"flattenResultOriginalSize\":0,\"cubes\":null,\"affectedRowCount\":0,\"isException\":false,\"exceptionMessage\":null,\"duration\":0.002,\"partial\":false}", - L"{\"columnMetas\":[{\"isNullable\":2,\"displaySize\":11,\"label\":\"COL\",\"name\":\"COL\",\"schemaName\":\"\",\"catelogName\":\"\",\"tableName\":\"\",\"precision\":10,\"scale\":0,\"columnType\":4,\"columnTypeName\":\"int4\",\"writable\":true,\"caseSensitive\":false,\"autoIncrement\":false,\"searchable\":true,\"currency\":false,\"signed\":true,\"definitelyWritable\":false,\"readOnly\":false}],\"results\":[[\"1\"]],\"isResultsFlatten\":false,\"flattenResult\":null,\"flattenResultOriginalSize\":0,\"cubes\":null,\"affectedRowCount\":0,\"isException\":false,\"exceptionMessage\":null,\"duration\":0.002,\"partial\":false}", - L"{\"columnMetas\":[{\"isNullable\":2,\"displaySize\":11,\"label\":\"COL\",\"name\":\"COL\",\"schemaName\":\"\",\"catelogName\":\"\",\"tableName\":\"\",\"precision\":10,\"scale\":0,\"columnType\":4,\"columnTypeName\":\"int4\",\"writable\":true,\"caseSensitive\":false,\"autoIncrement\":false,\"searchable\":true,\"currency\":false,\"signed\":true,\"definitelyWritable\":false,\"readOnly\":false}],\"results\":[[\"1\"]],\"isResultsFlatten\":false,\"flattenResult\":null,\"flattenResultOriginalSize\":0,\"cubes\":null,\"affectedRowCount\":0,\"isException\":false,\"exceptionMessage\":null,\"duration\":0.002,\"partial\":false}" -}; - -int findQuery ( const wchar_t* sql, const wchar_t** regexs, int size ) +const wchar_t* loadCache ( const wchar_t* query ) { - for ( int i = 0; i < size; ++i ) - { - std::tr1::wregex rgx ( regexs[i], regex_constants::icase ); - bool match = std::tr1::regex_search ( sql, rgx ); - - if ( match ) - { - return i; - } + lock_guard<mutex> lock(cacheMutex); + wstring queryString = wstring(query); + queryString.erase(remove_if(queryString.begin(), queryString.end(), ::isspace), queryString.end()); + map<wstring, wstring>::iterator it = queryMap.find(queryString); + if (it != queryMap.end()) { + return it->second.c_str(); } - - return -1; -} - -int findInAlwaysSuccessQuery ( const wchar_t* sql ) -{ - return findQuery ( sql, alwaysSuccessQueries, sizeof ( alwaysSuccessQueries ) / sizeof ( wchar_t*) ); -} - -int findInAlwaysFailQuery ( const wchar_t* sql ) -{ - return findQuery ( sql, alwaysFailQueries, sizeof ( alwaysFailQueries ) / sizeof ( wchar_t*) ); + return NULL; } -const wchar_t* loadCache ( const wchar_t* query ) +void storeCache (const wchar_t* query, const wchar_t* result) { - int index = 0; - - if ( findInAlwaysFailQuery ( query ) >= 0 ) - { - throw exception ( "Unsupported SQL" ); + lock_guard<mutex> lock(cacheMutex); + wstring queryString = wstring(query); + queryString.erase(remove_if(queryString.begin(), queryString.end(), ::isspace), queryString.end()); + + map<wstring, wstring>::iterator it = queryMap.find(queryString); + if (it != queryMap.end()) { + return; } - else if ( ( index = findInAlwaysSuccessQuery ( query ) ) >= 0 ) - { - return alwaysSuccessResults[index]; + if (queryQueue.size() >= cacheSize) { + wstring head = queryQueue.front(); + queryQueue.pop(); + queryMap.erase(head); } - return NULL; + queryQueue.push(queryString); + queryMap[queryString] = result; } - http://git-wip-us.apache.org/repos/asf/kylin/blob/27dfdbc6/odbc/Common/QueryCache.h ---------------------------------------------------------------------- diff --git a/odbc/Common/QueryCache.h b/odbc/Common/QueryCache.h index 1ce6dbd..f06a7ae 100644 --- a/odbc/Common/QueryCache.h +++ b/odbc/Common/QueryCache.h @@ -22,4 +22,5 @@ #include "MsgTypes.h" const wchar_t* loadCache ( const wchar_t* query ); +void storeCache (const wchar_t* query, const wchar_t* result); http://git-wip-us.apache.org/repos/asf/kylin/blob/27dfdbc6/odbc/Common/REST.cpp ---------------------------------------------------------------------- diff --git a/odbc/Common/REST.cpp b/odbc/Common/REST.cpp index 8fe62d5..2111aca 100644 --- a/odbc/Common/REST.cpp +++ b/odbc/Common/REST.cpp @@ -45,19 +45,6 @@ using namespace concurrency::streams; using namespace web; using namespace web::json; -void printLog ( const char* msg ) -{ - time_t now = time ( 0 ); - struct tm tstruct; - char buffer[100]; - tstruct = *localtime ( &now ); - strftime ( buffer, 100, "%Y-%m-%d.%X", &tstruct ); - printf ( buffer ); - printf ( "\n" ); - printf ( msg ); - printf ( "\n" ); -} - /// <summary> /// Find the longest length /// </summary> @@ -457,6 +444,7 @@ wstring requestQuery ( wchar_t* rawSql, char* serverAddr, long port, char* usern wstring ret = getBodyString ( response ); + storeCache(rawSql, ret.c_str()); return ret; }
