From: drh <> Date: Fri, 21 Jul 2023 11:09:53 +0000 (+0000) Subject: More infrastructure changes towards improving JSON cache performance. X-Git-Tag: version-3.43.0~114^2~11 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c8f4fec2dea3c2d89eaa38bf5eb7dd0de8b02e37;p=thirdparty%2Fsqlite.git More infrastructure changes towards improving JSON cache performance. Incremental check-in. FossilOrigin-Name: 1955e66cfc4614df97b8d68b0e662f309513d62dc8aeec71af5a54e66b79c707 --- diff --git a/manifest b/manifest index 9bdb33ae9d..715018c361 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Experimental\sframework\supon\swhich\sto\sbuild\sa\sbetter\sJSON\sparse\sstructure\sthat\nsupports\scached\sof\smodified\sJSON.\s\sAll\sof\sthese\schanges\sare\stentative\sand\nsubject\sto\schange\sor\sremoval.\s\sIncremental\scheck-in. -D 2023-07-20T17:45:09.052 +C More\sinfrastructure\schanges\stowards\simproving\sJSON\scache\sperformance.\nIncremental\scheck-in. +D 2023-07-21T11:09:53.138 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -597,7 +597,7 @@ F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51 F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 3f0a94082d978bbdd33c38fefea15346c6c6bffb70bc645a71dc0f1f87dd3276 -F src/json.c 888fcc121f7466bdf1518a8ae6adbfa7c4562438d046f1f21c942d625a208143 +F src/json.c 3bdc8916ee1acf47f63373278b7913befea89fc8f4bfc0299ae9a2b34b35ee07 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 176d6b2cb18a6ad73b133db17f6fc351c4d9a2d510deebdb76c22bde9cfd1465 F src/main.c 512b1d45bc556edf4471a845afb7ba79e64bd5b832ab222dc195c469534cd002 @@ -2043,8 +2043,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 144c8ccf6e5bb2527dd98742f0d67e0a16c627e7c67f754ce8ed4c4fb5b8d8b6 -R 086ba0782e2494053078635aa92191a8 +P e384163a4763c10b5838cbf28f9c4d8ea799bbbed6e890e8aa91b2bd1458646d +R 35c799f493c52a97264947f70c69a12e U drh -Z a6562dc595d378e643249c9e30c8bba6 +Z 7b5e59d8c6f3a8847c09c081e8b2a5bc # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 654058e2a7..b1ca498e22 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e384163a4763c10b5838cbf28f9c4d8ea799bbbed6e890e8aa91b2bd1458646d \ No newline at end of file +1955e66cfc4614df97b8d68b0e662f309513d62dc8aeec71af5a54e66b79c707 \ No newline at end of file diff --git a/src/json.c b/src/json.c index 2b309ee32e..b7c94a8a06 100644 --- a/src/json.c +++ b/src/json.c @@ -72,6 +72,7 @@ struct JsonString { u64 nUsed; /* Bytes of zBuf[] currently used */ u8 bStatic; /* True if zBuf is static space */ u8 bErr; /* True if an error has been encountered */ + u8 bOrig; /* Ignore edits when rendering JSON */ char zSpace[100]; /* Initial static space */ }; @@ -148,7 +149,7 @@ struct JsonParse { u8 oom; /* Set to true if out of memory */ u8 hasNonstd; /* True if input uses non-standard features like JSON5 */ u8 nJPRef; /* Number of references to this object */ - u8 bIgnoreEdits; /* Ignore edit marks during search */ + u8 bOrig; /* Ignore edit marks during search */ int nJson; /* Length of the zJson string in bytes */ u32 iErr; /* Error location in zJson[] */ u32 iHold; /* Replace cache line with the lowest iHold value */ @@ -174,6 +175,7 @@ static void jsonZero(JsonString *p){ p->nAlloc = sizeof(p->zSpace); p->nUsed = 0; p->bStatic = 1; + p->bOrig = 0; } /* Initialize the JsonString object @@ -584,7 +586,7 @@ static void jsonRenderNode( sqlite3_value **aReplace /* Replacement values */ ){ assert( pNode!=0 ); - if( pNode->jnFlags & (JNODE_REPLACE|JNODE_PATCH) ){ + if( (pNode->jnFlags & (JNODE_REPLACE|JNODE_PATCH)) && !pOut->bOrig ){ if( (pNode->jnFlags & JNODE_REPLACE)!=0 && ALWAYS(aReplace!=0) ){ assert( pNode->eU==4 ); jsonAppendValue(pOut, aReplace[pNode->u.iReplace]); @@ -650,13 +652,13 @@ static void jsonRenderNode( jsonAppendChar(pOut, '['); for(;;){ while( j<=pNode->n ){ - if( (pNode[j].jnFlags & JNODE_REMOVE)==0 ){ + if( (pNode[j].jnFlags & JNODE_REMOVE)==0 || pOut->bOrig ){ jsonAppendSeparator(pOut); jsonRenderNode(&pNode[j], pOut, aReplace); } j += jsonNodeSize(&pNode[j]); } - if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; + if( (pNode->jnFlags & JNODE_APPEND)==0 || pOut->bOrig ) break; assert( pNode->eU==2 ); pNode = &pNode[pNode->u.iAppend]; j = 1; @@ -669,7 +671,7 @@ static void jsonRenderNode( jsonAppendChar(pOut, '{'); for(;;){ while( j<=pNode->n ){ - if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 ){ + if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 || pOut->bOrig ){ jsonAppendSeparator(pOut); jsonRenderNode(&pNode[j], pOut, aReplace); jsonAppendChar(pOut, ':'); @@ -677,7 +679,7 @@ static void jsonRenderNode( } j += 1 + jsonNodeSize(&pNode[j+1]); } - if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; + if( (pNode->jnFlags & JNODE_APPEND)==0 || pOut->bOrig ) break; assert( pNode->eU==2 ); pNode = &pNode[pNode->u.iAppend]; j = 1; @@ -694,10 +696,12 @@ static void jsonRenderNode( static void jsonReturnJson( JsonNode *pNode, /* Node to return */ sqlite3_context *pCtx, /* Return value for this function */ - sqlite3_value **aReplace /* Array of replacement values */ + sqlite3_value **aReplace, /* Array of replacement values */ + int bOrig /* Ignore edits if true */ ){ JsonString s; jsonInit(&s, pCtx); + s.bOrig = bOrig!=0; jsonRenderNode(pNode, &s, aReplace); jsonResult(&s); sqlite3_result_subtype(pCtx, JSON_SUBTYPE); @@ -740,7 +744,8 @@ static u32 jsonHexToInt4(const char *z){ static void jsonReturn( JsonNode *pNode, /* Node to return */ sqlite3_context *pCtx, /* Return value for this function */ - sqlite3_value **aReplace /* Array of replacement values */ + sqlite3_value **aReplace, /* Array of replacement values */ + int bOrig /* Ignore edits if true */ ){ switch( pNode->eType ){ default: { @@ -887,7 +892,7 @@ static void jsonReturn( } case JSON_ARRAY: case JSON_OBJECT: { - jsonReturnJson(pNode, pCtx, aReplace); + jsonReturnJson(pNode, pCtx, aReplace, bOrig); break; } } @@ -1797,7 +1802,7 @@ static JsonNode *jsonLookupStep( const char *zKey; JsonNode *pRoot = &pParse->aNode[iRoot]; if( zPath[0]==0 ) return pRoot; - if( pRoot->jnFlags & JNODE_REPLACE ) return 0; + if( (pRoot->jnFlags & JNODE_REPLACE)!=0 && !pParse->bOrig ) return 0; if( zPath[0]=='.' ){ if( pRoot->eType!=JSON_OBJECT ) return 0; zPath++; @@ -1830,7 +1835,7 @@ static JsonNode *jsonLookupStep( j++; j += jsonNodeSize(&pRoot[j]); } - if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; + if( (pRoot->jnFlags & JNODE_APPEND)==0 || pParse->bOrig ) break; assert( pRoot->eU==2 ); iRoot += pRoot->u.iAppend; pRoot = &pParse->aNode[iRoot]; @@ -1839,6 +1844,7 @@ static JsonNode *jsonLookupStep( if( pApnd ){ u32 iStart, iLabel; JsonNode *pNode; + assert( !pParse->bOrig ); iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0); iLabel = jsonParseAddNode(pParse, JSON_STRING, nKey, zKey); zPath += i; @@ -1868,10 +1874,10 @@ static JsonNode *jsonLookupStep( if( pRoot->eType!=JSON_ARRAY ) return 0; for(;;){ while( j<=pBase->n ){ - if( (pBase[j].jnFlags & JNODE_REMOVE)==0 ) i++; + if( (pBase[j].jnFlags & JNODE_REMOVE)==0 || pParse->bOrig ) i++; j += jsonNodeSize(&pBase[j]); } - if( (pBase->jnFlags & JNODE_APPEND)==0 ) break; + if( (pBase->jnFlags & JNODE_APPEND)==0 || pParse->bOrig ) break; assert( pBase->eU==2 ); iBase += pBase->u.iAppend; pBase = &pParse->aNode[iBase]; @@ -1901,11 +1907,13 @@ static JsonNode *jsonLookupStep( zPath += j + 1; j = 1; for(;;){ - while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){ - if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--; + while( j<=pRoot->n + && (i>0 || ((pRoot[j].jnFlags & JNODE_REMOVE) && !pParse->bOrig)) + ){ + if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 || pParse->bOrig ) i--; j += jsonNodeSize(&pRoot[j]); } - if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; + if( (pRoot->jnFlags & JNODE_APPEND)==0 || pParse->bOrig ) break; assert( pRoot->eU==2 ); iRoot += pRoot->u.iAppend; pRoot = &pParse->aNode[iRoot]; @@ -1917,6 +1925,7 @@ static JsonNode *jsonLookupStep( if( i==0 && pApnd ){ u32 iStart; JsonNode *pNode; + assert( !pParse->bOrig ); iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0); pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr); if( pParse->oom ) return 0; @@ -2269,15 +2278,15 @@ static void jsonExtractFunc( } if( pNode ){ if( flags & JSON_JSON ){ - jsonReturnJson(pNode, ctx, 0); + jsonReturnJson(pNode, ctx, 0, 1); }else{ - jsonReturn(pNode, ctx, 0); + jsonReturn(pNode, ctx, 0, 1); sqlite3_result_subtype(ctx, 0); } } }else{ pNode = jsonLookup(p, zPath, 0, ctx); - if( p->nErr==0 && pNode ) jsonReturn(pNode, ctx, 0); + if( p->nErr==0 && pNode ) jsonReturn(pNode, ctx, 0, 1); } }else{ /* Two or more PATH arguments results in a JSON array with each @@ -2405,7 +2414,7 @@ static void jsonPatchFunc( pResult = jsonMergePatch(&x, 0, y.aNode); assert( pResult!=0 || x.oom ); if( pResult ){ - jsonReturnJson(pResult, ctx, 0); + jsonReturnJson(pResult, ctx, 0, 0); }else{ sqlite3_result_error_nomem(ctx); } @@ -2482,7 +2491,7 @@ static void jsonRemoveFunc( if( pNode ) pNode->jnFlags |= JNODE_REMOVE; } if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){ - jsonReturnJson(x.aNode, ctx, 0); + jsonReturnJson(x.aNode, ctx, 0, 0); } remove_done: jsonParseReset(&x); @@ -2527,7 +2536,7 @@ static void jsonReplaceFunc( assert( x.aNode[0].eU==4 ); sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]); }else{ - jsonReturnJson(x.aNode, ctx, argv); + jsonReturnJson(x.aNode, ctx, argv, 0); } replace_err: jsonParseReset(&x); @@ -2586,7 +2595,7 @@ static void jsonSetFunc( assert( x.aNode[0].eU==4 ); sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]); }else{ - jsonReturnJson(x.aNode, ctx, argv); + jsonReturnJson(x.aNode, ctx, argv, 0); } jsonSetDone: jsonParseReset(&x); @@ -3095,7 +3104,7 @@ static int jsonEachColumn( case JEACH_KEY: { if( p->i==0 ) break; if( p->eType==JSON_OBJECT ){ - jsonReturn(pThis, ctx, 0); + jsonReturn(pThis, ctx, 0, 0); }else if( p->eType==JSON_ARRAY ){ u32 iKey; if( p->bRecursive ){ @@ -3111,7 +3120,7 @@ static int jsonEachColumn( } case JEACH_VALUE: { if( pThis->jnFlags & JNODE_LABEL ) pThis++; - jsonReturn(pThis, ctx, 0); + jsonReturn(pThis, ctx, 0, 0); break; } case JEACH_TYPE: { @@ -3122,7 +3131,7 @@ static int jsonEachColumn( case JEACH_ATOM: { if( pThis->jnFlags & JNODE_LABEL ) pThis++; if( pThis->eType>=JSON_ARRAY ) break; - jsonReturn(pThis, ctx, 0); + jsonReturn(pThis, ctx, 0, 0); break; } case JEACH_ID: {