mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Optimizations to the OP_Found opcode save about 600K cycles in speedtest1.
FossilOrigin-Name: 5c3357ad62843fe982b9c2d31dbf02018f2948ceab2c85dac917cd9ce1e97dd6
This commit is contained in:
53
src/vdbe.c
53
src/vdbe.c
@@ -4966,11 +4966,9 @@ case OP_NoConflict: /* jump, in3 */
|
||||
case OP_NotFound: /* jump, in3 */
|
||||
case OP_Found: { /* jump, in3 */
|
||||
int alreadyExists;
|
||||
int takeJump;
|
||||
int ii;
|
||||
VdbeCursor *pC;
|
||||
int res;
|
||||
UnpackedRecord *pFree;
|
||||
UnpackedRecord *pIdxKey;
|
||||
UnpackedRecord r;
|
||||
|
||||
@@ -4990,9 +4988,11 @@ case OP_Found: { /* jump, in3 */
|
||||
assert( pC->uc.pCursor!=0 );
|
||||
assert( pC->isTable==0 );
|
||||
if( pOp->p4.i>0 ){
|
||||
r.pKeyInfo = pC->pKeyInfo;
|
||||
/* Key values in an array of registers */
|
||||
r.nField = (u16)pOp->p4.i;
|
||||
r.pKeyInfo = pC->pKeyInfo;
|
||||
r.aMem = pIn3;
|
||||
r.default_rc = 0;
|
||||
#ifdef SQLITE_DEBUG
|
||||
for(ii=0; ii<r.nField; ii++){
|
||||
assert( memIsValid(&r.aMem[ii]) );
|
||||
@@ -5000,32 +5000,21 @@ case OP_Found: { /* jump, in3 */
|
||||
if( ii ) REGISTER_TRACE(pOp->p3+ii, &r.aMem[ii]);
|
||||
}
|
||||
#endif
|
||||
pIdxKey = &r;
|
||||
pFree = 0;
|
||||
rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, &r, &res);
|
||||
}else{
|
||||
/* Composite key generated by OP_MakeRecord */
|
||||
assert( pIn3->flags & MEM_Blob );
|
||||
assert( pOp->opcode!=OP_NoConflict );
|
||||
rc = ExpandBlob(pIn3);
|
||||
assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
|
||||
if( rc ) goto no_mem;
|
||||
pFree = pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo);
|
||||
pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo);
|
||||
if( pIdxKey==0 ) goto no_mem;
|
||||
sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey);
|
||||
pIdxKey->default_rc = 0;
|
||||
rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, pIdxKey, &res);
|
||||
sqlite3DbFreeNN(db, pIdxKey);
|
||||
}
|
||||
pIdxKey->default_rc = 0;
|
||||
takeJump = 0;
|
||||
if( pOp->opcode==OP_NoConflict ){
|
||||
/* For the OP_NoConflict opcode, take the jump if any of the
|
||||
** input fields are NULL, since any key with a NULL will not
|
||||
** conflict */
|
||||
for(ii=0; ii<pIdxKey->nField; ii++){
|
||||
if( pIdxKey->aMem[ii].flags & MEM_Null ){
|
||||
takeJump = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, pIdxKey, &res);
|
||||
if( pFree ) sqlite3DbFreeNN(db, pFree);
|
||||
if( rc!=SQLITE_OK ){
|
||||
goto abort_due_to_error;
|
||||
}
|
||||
@@ -5038,9 +5027,25 @@ case OP_Found: { /* jump, in3 */
|
||||
VdbeBranchTaken(alreadyExists!=0,2);
|
||||
if( alreadyExists ) goto jump_to_p2;
|
||||
}else{
|
||||
VdbeBranchTaken(takeJump||alreadyExists==0,2);
|
||||
if( takeJump || !alreadyExists ) goto jump_to_p2;
|
||||
if( pOp->opcode==OP_IfNoHope ) pC->seekHit = pOp->p4.i;
|
||||
if( !alreadyExists ){
|
||||
VdbeBranchTaken(1,2);
|
||||
goto jump_to_p2;
|
||||
}
|
||||
if( pOp->opcode==OP_NoConflict ){
|
||||
/* For the OP_NoConflict opcode, take the jump if any of the
|
||||
** input fields are NULL, since any key with a NULL will not
|
||||
** conflict */
|
||||
for(ii=0; ii<r.nField; ii++){
|
||||
if( r.aMem[ii].flags & MEM_Null ){
|
||||
VdbeBranchTaken(1,2);
|
||||
goto jump_to_p2;
|
||||
}
|
||||
}
|
||||
}
|
||||
VdbeBranchTaken(0,2);
|
||||
if( pOp->opcode==OP_IfNoHope ){
|
||||
pC->seekHit = pOp->p4.i;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
Reference in New Issue
Block a user