From: drh <> Date: Fri, 25 Feb 2022 20:11:59 +0000 (+0000) Subject: Revise the initialization processing for OP_Column to make it about X-Git-Tag: version-3.39.0~366 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=fc56950337825789486227a2f4ce8655d670b420;p=thirdparty%2Fsqlite.git Revise the initialization processing for OP_Column to make it about 1.8 million cycles faster. FossilOrigin-Name: 3b7259ebd5b9b1f75577521c4d0d96f5503d302a513b20a0b17dbe8c3823dd33 --- diff --git a/manifest b/manifest index 42a39fbdc4..892f8fb779 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sOP_NullRow\sdocumentation\sso\sthat\sit\saccurately\sdescribes\swhat\sit\nactually\sdoes\sfor\sa\spseudo-cursor. -D 2022-02-25T18:51:09.169 +C Revise\sthe\sinitialization\sprocessing\sfor\sOP_Column\sto\smake\sit\sabout\n1.8\smillion\scycles\sfaster. +D 2022-02-25T20:11:59.160 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -624,11 +624,11 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c 5299556464a6a947611334db56adbf20d2b345c1cff7d74f666008c349f0410c +F src/vdbe.c e3947ae70531c7e26fdca3da379bcb1aaad349dc1daad9841a11dd78f40e4705 F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e -F src/vdbeInt.h b45599a2b59f1ce042512ab6786b0b82a8cf3002f6b0fa60b4834e2cd3ac61d8 +F src/vdbeInt.h de2348c1643c1ac5bf0932452cbb708f52f52d8b4e29b667abdcfd4bacbf6aa6 F src/vdbeapi.c 8863ffb5a7bac42fe9a68aaa3526ee29fc18fb02a9b27188b756de41e33856e9 -F src/vdbeaux.c 3aa7ec0f53156760e9b42557122c61f90efddba5d9d173d076b3b8826b1b23bb +F src/vdbeaux.c 1dc2bdd377baf4e3602e02ca33d241944f04bda2e724526437018f143f9e75f3 F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 7737f0b1c480a32b057849c804d2f21d5389649bb8be80f77ad75df700adc9a1 F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 @@ -1944,8 +1944,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 54f49f65ac943263a1622b1efe519c8a61f30f23694fd4fec89ad2bf0e17b473 -R 84b7b86c0cda7b37ea1827afa5aef02e +P 4e269902094e8f9d852e5fc852e473167048fdeb9034f1fb1436f6df205de926 +R 8636bb1bb599a232ab53a80eb27f1dd2 U drh -Z ad486a9d2be85a263d9516418548523a +Z 2c3c6e68626da40fc12f58f70cf79dcd # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 05dec89be9..45a49d23f0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4e269902094e8f9d852e5fc852e473167048fdeb9034f1fb1436f6df205de926 \ No newline at end of file +3b7259ebd5b9b1f75577521c4d0d96f5503d302a513b20a0b17dbe8c3823dd33 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index f6c350a9b5..d1e54b8f9e 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2659,7 +2659,7 @@ case OP_Offset: { /* out3 */ case OP_Column: { u32 p2; /* column number to retrieve */ VdbeCursor *pC; /* The VDBE cursor */ - BtCursor *pCrsr; /* The BTree cursor */ + BtCursor *pCrsr; /* The B-Tree cursor corresponding to pC */ u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */ int len; /* The length of the serialized data for the column */ int i; /* Loop counter */ @@ -2673,19 +2673,11 @@ case OP_Column: { Mem *pReg; /* PseudoTable input register */ assert( pOp->p1>=0 && pOp->p1nCursor ); + assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); pC = p->apCsr[pOp->p1]; - assert( pC!=0 ); p2 = (u32)pOp->p2; - /* If the cursor cache is stale (meaning it is not currently point at - ** the correct row) then bring it up-to-date by doing the necessary - ** B-Tree seek. */ - rc = sqlite3VdbeCursorMoveto(&pC, &p2); - if( rc ) goto abort_due_to_error; - - assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); - pDest = &aMem[pOp->p3]; - memAboutToChange(p, pDest); +op_column_restart: assert( pC!=0 ); assert( p2<(u32)pC->nField ); aOffset = pC->aOffset; @@ -2706,11 +2698,28 @@ case OP_Column: { pC->payloadSize = pC->szRow = pReg->n; pC->aRow = (u8*)pReg->z; }else{ + pDest = &aMem[pOp->p3]; + memAboutToChange(p, pDest); sqlite3VdbeMemSetNull(pDest); goto op_column_out; } }else{ pCrsr = pC->uc.pCursor; + if( pC->deferredMoveto ){ + u32 iMap; + assert( !pC->isEphemeral ); + if( pC->ub.aAltMap && (iMap = pC->ub.aAltMap[1+p2])>0 ){ + pC = pC->pAltCursor; + p2 = iMap - 1; + goto op_column_restart; + } + rc = sqlite3VdbeFinishMoveto(pC); + if( rc ) goto abort_due_to_error; + }else if( sqlite3BtreeCursorHasMoved(pCrsr) ){ + rc = sqlite3VdbeHandleMovedCursor(pC); + if( rc ) goto abort_due_to_error; + goto op_column_restart; + } assert( pC->eCurType==CURTYPE_BTREE ); assert( pCrsr ); assert( sqlite3BtreeCursorIsValid(pCrsr) ); @@ -2766,6 +2775,10 @@ case OP_Column: { testcase( aOffset[0]==0 ); goto op_column_read_header; } + }else if( sqlite3BtreeCursorHasMoved(pC->uc.pCursor) ){ + rc = sqlite3VdbeHandleMovedCursor(pC); + if( rc ) goto abort_due_to_error; + goto op_column_restart; } /* Make sure at least the first p2+1 entries of the header have been @@ -2834,6 +2847,8 @@ case OP_Column: { ** columns. So the result will be either the default value or a NULL. */ if( pC->nHdrParsed<=p2 ){ + pDest = &aMem[pOp->p3]; + memAboutToChange(p, pDest); if( pOp->p4type==P4_MEM ){ sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static); }else{ @@ -2851,6 +2866,8 @@ case OP_Column: { */ assert( p2nHdrParsed ); assert( rc==SQLITE_OK ); + pDest = &aMem[pOp->p3]; + memAboutToChange(p, pDest); assert( sqlite3VdbeCheckMemInvariants(pDest) ); if( VdbeMemDynamic(pDest) ){ sqlite3VdbeMemSetNull(pDest); @@ -6197,6 +6214,7 @@ case OP_IdxRowid: { /* out2 */ pTabCur->nullRow = 0; pTabCur->movetoTarget = rowid; pTabCur->deferredMoveto = 1; + pTabCur->cacheStatus = CACHE_STALE; assert( pOp->p4type==P4_INTARRAY || pOp->p4.ai==0 ); assert( !pTabCur->isEphemeral ); pTabCur->ub.aAltMap = pOp->p4.ai; diff --git a/src/vdbeInt.h b/src/vdbeInt.h index f02b37c6a2..cc5fd604d5 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -506,8 +506,8 @@ struct ValueList { void sqlite3VdbeError(Vdbe*, const char *, ...); void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*); void sqliteVdbePopStack(Vdbe*,int); +int SQLITE_NOINLINE sqlite3VdbeHandleMovedCursor(VdbeCursor *p); int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor*); -int sqlite3VdbeCursorMoveto(VdbeCursor**, u32*); int sqlite3VdbeCursorRestore(VdbeCursor*); u32 sqlite3VdbeSerialTypeLen(u32); u8 sqlite3VdbeOneByteSerialTypeLen(u8); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index bcfe63130f..35044127ac 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3505,7 +3505,7 @@ int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor *p){ ** is supposed to be pointing. If the row was deleted out from under the ** cursor, set the cursor to point to a NULL row. */ -static int SQLITE_NOINLINE handleMovedCursor(VdbeCursor *p){ +int SQLITE_NOINLINE sqlite3VdbeHandleMovedCursor(VdbeCursor *p){ int isDifferentRow, rc; assert( p->eCurType==CURTYPE_BTREE ); assert( p->uc.pCursor!=0 ); @@ -3523,39 +3523,7 @@ static int SQLITE_NOINLINE handleMovedCursor(VdbeCursor *p){ int sqlite3VdbeCursorRestore(VdbeCursor *p){ assert( p->eCurType==CURTYPE_BTREE ); if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){ - return handleMovedCursor(p); - } - return SQLITE_OK; -} - -/* -** Make sure the cursor p is ready to read or write the row to which it -** was last positioned. Return an error code if an OOM fault or I/O error -** prevents us from positioning the cursor to its correct position. -** -** If a MoveTo operation is pending on the given cursor, then do that -** MoveTo now. If no move is pending, check to see if the row has been -** deleted out from under the cursor and if it has, mark the row as -** a NULL row. -** -** If the cursor is already pointing to the correct row and that row has -** not been deleted out from under the cursor, then this routine is a no-op. -*/ -int sqlite3VdbeCursorMoveto(VdbeCursor **pp, u32 *piCol){ - VdbeCursor *p = *pp; - assert( p->eCurType==CURTYPE_BTREE || p->eCurType==CURTYPE_PSEUDO ); - if( p->deferredMoveto ){ - u32 iMap; - assert( !p->isEphemeral ); - if( p->ub.aAltMap && (iMap = p->ub.aAltMap[1+*piCol])>0 && !p->nullRow ){ - *pp = p->pAltCursor; - *piCol = iMap - 1; - return SQLITE_OK; - } - return sqlite3VdbeFinishMoveto(p); - } - if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){ - return handleMovedCursor(p); + return sqlite3VdbeHandleMovedCursor(p); } return SQLITE_OK; }