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;
 }
 

Reply via email to