From: drh Date: Thu, 30 Aug 2018 01:52:10 +0000 (+0000) Subject: Improved JSON parser caching. X-Git-Tag: version-3.25.0~50 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e35fc302c3da49ac52edcda89a604a99ef898039;p=thirdparty%2Fsqlite.git Improved JSON parser caching. FossilOrigin-Name: 58078c0d2647a194279fa80e032670441b296ffc3acee692901faa5beca460b7 --- diff --git a/ext/misc/json1.c b/ext/misc/json1.c index f1b633d2c6..51a519cf01 100644 --- a/ext/misc/json1.c +++ b/ext/misc/json1.c @@ -172,6 +172,7 @@ struct JsonParse { u8 nErr; /* Number of errors seen */ u16 iDepth; /* Nesting depth */ int nJson; /* Length of the zJson string in bytes */ + u32 iHold; /* Replace cache line with the lowest iHold value */ }; /* @@ -976,7 +977,8 @@ static int jsonParseFindParents(JsonParse *pParse){ /* ** Magic number used for the JSON parse cache in sqlite3_get_auxdata() */ -#define JSON_CACHE_ID (-429938) +#define JSON_CACHE_ID (-429938) /* First cache entry */ +#define JSON_CACHE_SZ 4 /* Max number of cache entries */ /* ** Obtain a complete parse of the JSON found in the first argument @@ -988,16 +990,42 @@ static int jsonParseFindParents(JsonParse *pParse){ */ static JsonParse *jsonParseCached( sqlite3_context *pCtx, - sqlite3_value **argv + sqlite3_value **argv, + sqlite3_context *pErrCtx ){ const char *zJson = (const char*)sqlite3_value_text(argv[0]); int nJson = sqlite3_value_bytes(argv[0]); JsonParse *p; + JsonParse *pMatch = 0; + int iKey; + int iMinKey = 0; + u32 iMinHold = 0xffffffff; + u32 iMaxHold = 0; if( zJson==0 ) return 0; - p = (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID); - if( p && p->nJson==nJson && memcmp(p->zJson,zJson,nJson)==0 ){ - p->nErr = 0; - return p; /* The cached entry matches, so return it */ + for(iKey=0; iKeynJson==nJson + && memcmp(p->zJson,zJson,nJson)==0 + ){ + p->nErr = 0; + pMatch = p; + }else if( p->iHoldiHold; + iMinKey = iKey; + } + if( p->iHold>iMaxHold ){ + iMaxHold = p->iHold; + } + } + if( pMatch ){ + pMatch->nErr = 0; + pMatch->iHold = iMaxHold+1; + return pMatch; } p = sqlite3_malloc( sizeof(*p) + nJson + 1 ); if( p==0 ){ @@ -1007,13 +1035,15 @@ static JsonParse *jsonParseCached( memset(p, 0, sizeof(*p)); p->zJson = (char*)&p[1]; memcpy((char*)p->zJson, zJson, nJson+1); - if( jsonParse(p, pCtx, p->zJson) ){ + if( jsonParse(p, pErrCtx, p->zJson) ){ sqlite3_free(p); return 0; } p->nJson = nJson; - sqlite3_set_auxdata(pCtx, JSON_CACHE_ID, p, (void(*)(void*))jsonParseFree); - return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID); + p->iHold = iMaxHold+1; + sqlite3_set_auxdata(pCtx, JSON_CACHE_ID+iMinKey, p, + (void(*)(void*))jsonParseFree); + return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iMinKey); } /* @@ -1386,7 +1416,7 @@ static void jsonArrayLengthFunc( u32 i; JsonNode *pNode; - p = jsonParseCached(ctx, argv); + p = jsonParseCached(ctx, argv, ctx); if( p==0 ) return; assert( p->nNode ); if( argc==2 ){ @@ -1427,7 +1457,7 @@ static void jsonExtractFunc( int i; if( argc<2 ) return; - p = jsonParseCached(ctx, argv); + p = jsonParseCached(ctx, argv, ctx); if( p==0 ) return; jsonInit(&jx, ctx); jsonAppendChar(&jx, '['); @@ -1734,22 +1764,21 @@ static void jsonTypeFunc( int argc, sqlite3_value **argv ){ - JsonParse x; /* The parse */ + JsonParse *p; /* The parse */ const char *zPath; JsonNode *pNode; - if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; - assert( x.nNode ); + p = jsonParseCached(ctx, argv, ctx); + if( p==0 ) return; if( argc==2 ){ zPath = (const char*)sqlite3_value_text(argv[1]); - pNode = jsonLookup(&x, zPath, 0, ctx); + pNode = jsonLookup(p, zPath, 0, ctx); }else{ - pNode = x.aNode; + pNode = p->aNode; } if( pNode ){ sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC); } - jsonParseReset(&x); } /* @@ -1763,15 +1792,10 @@ static void jsonValidFunc( int argc, sqlite3_value **argv ){ - JsonParse x; /* The parse */ - int rc = 0; - + JsonParse *p; /* The parse */ UNUSED_PARAM(argc); - if( jsonParse(&x, 0, (const char*)sqlite3_value_text(argv[0]))==0 ){ - rc = 1; - } - jsonParseReset(&x); - sqlite3_result_int(ctx, rc); + p = jsonParseCached(ctx, argv, 0); + sqlite3_result_int(ctx, p!=0); } diff --git a/manifest b/manifest index 19aea93dfd..ca27635ca6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Additional\stest\scases\sfor\sgeopoly. -D 2018-08-29T21:01:22.572 +C Improved\sJSON\sparser\scaching. +D 2018-08-30T01:52:10.764 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in d06f463c5b623a61ac27f5cb8214fca9e53a6704d34d6b8f2124e2b1b293c88f @@ -284,7 +284,7 @@ F ext/misc/eval.c 6ea9b22a5fa0dd973b67ca4e53555be177bc0b7b263aadf1024429457c82c0 F ext/misc/fileio.c 48c7751c78fc4cdd29d8c862fd2f3f98bbfefa2a3cf1ca1496df4bf02eb8cded F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c -F ext/misc/json1.c 696c596de45d991e6c4617b5a3cb4cc60d231aa4be10edea7d27a4008df2f545 +F ext/misc/json1.c 34a31eac76aeec269657f6f84a72533600d511005efa5dd97034909a2a0fbc9a F ext/misc/memvfs.c ab36f49e02ebcdf85a1e08dc4d8599ea8f343e073ac9e0bca18a98b7e1ec9567 F ext/misc/mmapwarm.c 70b618f2d0bde43fae288ad0b7498a629f2b6f61b50a27e06fae3cd23c83af29 F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 @@ -1758,7 +1758,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7c3cee0a2a5ccacff27400c38bd708f7b9b968eb013a8fa685d876dfe85e12a6 -R 771e2fad0c71e34b021e9df816201c53 +P 19b5eb45e090c4b7169a52d881495ee2eafc59f80e3db2288fc1814ba76134ac +R 6879c3448f3a21f21360b0e010f06ec5 U drh -Z fceaa831790380442f9478793a598598 +Z c5fe49b6610cf864d1fad4e0e99d3945 diff --git a/manifest.uuid b/manifest.uuid index e33dd2740f..554957456a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -19b5eb45e090c4b7169a52d881495ee2eafc59f80e3db2288fc1814ba76134ac \ No newline at end of file +58078c0d2647a194279fa80e032670441b296ffc3acee692901faa5beca460b7 \ No newline at end of file