1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-05 15:55:57 +03:00

Save a 78 bytes of code space and a million CPU cycles in speedtest1 by

storing the cell index for the leaf page in the BtCursor object in its own
field (BtCursor.ix), rather than as an entry in the BtCursor.aiIdx array.

FossilOrigin-Name: 2452f0617d1085689264b5f66681788cfe9e3b1a7b318307c93942b702a443df
This commit is contained in:
drh
2017-04-01 00:20:06 +00:00
parent 53b2459a36
commit 75e96b3100
4 changed files with 48 additions and 46 deletions

View File

@@ -4317,7 +4317,7 @@ int sqlite3BtreeCloseCursor(BtCursor *pCur){
CellInfo info;
int iPage = pCur->iPage;
memset(&info, 0, sizeof(info));
btreeParseCell(pCur->apPage[iPage], pCur->aiIdx[iPage], &info);
btreeParseCell(pCur->apPage[iPage], pCur->ix, &info);
assert( CORRUPT_DB || memcmp(&info, &pCur->info, sizeof(info))==0 );
}
#else
@@ -4327,7 +4327,7 @@ static SQLITE_NOINLINE void getCellInfo(BtCursor *pCur){
if( pCur->info.nSize==0 ){
int iPage = pCur->iPage;
pCur->curFlags |= BTCF_ValidNKey;
btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info);
btreeParseCell(pCur->apPage[iPage],pCur->ix,&pCur->info);
}else{
assertCellInfo(pCur);
}
@@ -4534,7 +4534,7 @@ static int accessPayload(
assert( pPage );
assert( eOp==0 || eOp==1 );
assert( pCur->eState==CURSOR_VALID );
assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
assert( pCur->ix<pPage->nCell );
assert( cursorHoldsMutex(pCur) );
getCellInfo(pCur);
@@ -4721,7 +4721,7 @@ int sqlite3BtreePayload(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
assert( cursorHoldsMutex(pCur) );
assert( pCur->eState==CURSOR_VALID );
assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] );
assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
assert( pCur->ix<pCur->apPage[pCur->iPage]->nCell );
return accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0);
}
@@ -4783,7 +4783,7 @@ static const void *fetchPayload(
assert( pCur->eState==CURSOR_VALID );
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
assert( cursorOwnsBtShared(pCur) );
assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
assert( pCur->ix<pCur->apPage[pCur->iPage]->nCell );
assert( pCur->info.nSize>0 );
assert( pCur->info.pPayload>pCur->apPage[pCur->iPage]->aData || CORRUPT_DB );
assert( pCur->info.pPayload<pCur->apPage[pCur->iPage]->aDataEnd ||CORRUPT_DB);
@@ -4834,8 +4834,8 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){
}
pCur->info.nSize = 0;
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
pCur->iPage++;
pCur->aiIdx[pCur->iPage] = 0;
pCur->aiIdx[pCur->iPage++] = pCur->ix;
pCur->ix = 0;
return getAndInitPage(pBt, newPgno, &pCur->apPage[pCur->iPage],
pCur, pCur->curPagerFlags);
}
@@ -4883,6 +4883,7 @@ static void moveToParent(BtCursor *pCur){
testcase( pCur->aiIdx[pCur->iPage-1] > pCur->apPage[pCur->iPage-1]->nCell );
pCur->info.nSize = 0;
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
pCur->ix = pCur->aiIdx[pCur->iPage-1];
releasePageNotNull(pCur->apPage[pCur->iPage--]);
}
@@ -4964,7 +4965,7 @@ static int moveToRoot(BtCursor *pCur){
}
skip_init:
pCur->aiIdx[0] = 0;
pCur->ix = 0;
pCur->info.nSize = 0;
pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidNKey|BTCF_ValidOvfl);
@@ -4998,8 +4999,8 @@ static int moveToLeftmost(BtCursor *pCur){
assert( cursorOwnsBtShared(pCur) );
assert( pCur->eState==CURSOR_VALID );
while( rc==SQLITE_OK && !(pPage = pCur->apPage[pCur->iPage])->leaf ){
assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
pgno = get4byte(findCell(pPage, pCur->aiIdx[pCur->iPage]));
assert( pCur->ix<pPage->nCell );
pgno = get4byte(findCell(pPage, pCur->ix));
rc = moveToChild(pCur, pgno);
}
return rc;
@@ -5024,11 +5025,11 @@ static int moveToRightmost(BtCursor *pCur){
assert( pCur->eState==CURSOR_VALID );
while( !(pPage = pCur->apPage[pCur->iPage])->leaf ){
pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
pCur->aiIdx[pCur->iPage] = pPage->nCell;
pCur->ix = pPage->nCell;
rc = moveToChild(pCur, pgno);
if( rc ) return rc;
}
pCur->aiIdx[pCur->iPage] = pPage->nCell-1;
pCur->ix = pPage->nCell-1;
assert( pCur->info.nSize==0 );
assert( (pCur->curFlags & BTCF_ValidNKey)==0 );
return SQLITE_OK;
@@ -5076,7 +5077,7 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
for(ii=0; ii<pCur->iPage; ii++){
assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell );
}
assert( pCur->aiIdx[pCur->iPage]==pCur->apPage[pCur->iPage]->nCell-1 );
assert( pCur->ix==pCur->apPage[pCur->iPage]->nCell-1 );
assert( pCur->apPage[pCur->iPage]->leaf );
#endif
return SQLITE_OK;
@@ -5223,7 +5224,7 @@ int sqlite3BtreeMovetoUnpacked(
upr = pPage->nCell-1;
assert( biasRight==0 || biasRight==1 );
idx = upr>>(1-biasRight); /* idx = biasRight ? upr : (lwr+upr)/2; */
pCur->aiIdx[pCur->iPage] = (u16)idx;
pCur->ix = (u16)idx;
if( xRecordCompare==0 ){
for(;;){
i64 nCellKey;
@@ -5242,7 +5243,7 @@ int sqlite3BtreeMovetoUnpacked(
if( lwr>upr ){ c = +1; break; }
}else{
assert( nCellKey==intKey );
pCur->aiIdx[pCur->iPage] = (u16)idx;
pCur->ix = (u16)idx;
if( !pPage->leaf ){
lwr = idx;
goto moveto_next_layer;
@@ -5311,7 +5312,7 @@ int sqlite3BtreeMovetoUnpacked(
rc = SQLITE_NOMEM_BKPT;
goto moveto_finish;
}
pCur->aiIdx[pCur->iPage] = (u16)idx;
pCur->ix = (u16)idx;
rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0);
pCur->curFlags &= ~BTCF_ValidOvfl;
if( rc ){
@@ -5333,7 +5334,7 @@ int sqlite3BtreeMovetoUnpacked(
assert( c==0 );
*pRes = 0;
rc = SQLITE_OK;
pCur->aiIdx[pCur->iPage] = (u16)idx;
pCur->ix = (u16)idx;
if( pIdxKey->errCode ) rc = SQLITE_CORRUPT;
goto moveto_finish;
}
@@ -5345,8 +5346,8 @@ int sqlite3BtreeMovetoUnpacked(
assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) );
assert( pPage->isInit );
if( pPage->leaf ){
assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
pCur->aiIdx[pCur->iPage] = (u16)idx;
assert( pCur->ix<pCur->apPage[pCur->iPage]->nCell );
pCur->ix = (u16)idx;
*pRes = c;
rc = SQLITE_OK;
goto moveto_finish;
@@ -5357,7 +5358,7 @@ moveto_next_layer:
}else{
chldPg = get4byte(findCell(pPage, lwr));
}
pCur->aiIdx[pCur->iPage] = (u16)lwr;
pCur->ix = (u16)lwr;
rc = moveToChild(pCur, chldPg);
if( rc ) break;
}
@@ -5458,7 +5459,7 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur, int *pRes){
}
pPage = pCur->apPage[pCur->iPage];
idx = ++pCur->aiIdx[pCur->iPage];
idx = ++pCur->ix;
assert( pPage->isInit );
/* If the database file is corrupt, it is possible for the value of idx
@@ -5482,7 +5483,7 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur, int *pRes){
}
moveToParent(pCur);
pPage = pCur->apPage[pCur->iPage];
}while( pCur->aiIdx[pCur->iPage]>=pPage->nCell );
}while( pCur->ix>=pPage->nCell );
if( pPage->intKey ){
return sqlite3BtreeNext(pCur, pRes);
}else{
@@ -5506,8 +5507,8 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
*pRes = 0;
if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur, pRes);
pPage = pCur->apPage[pCur->iPage];
if( (++pCur->aiIdx[pCur->iPage])>=pPage->nCell ){
pCur->aiIdx[pCur->iPage]--;
if( (++pCur->ix)>=pPage->nCell ){
pCur->ix--;
return btreeNext(pCur, pRes);
}
if( pPage->leaf ){
@@ -5571,12 +5572,12 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur, int *pRes){
pPage = pCur->apPage[pCur->iPage];
assert( pPage->isInit );
if( !pPage->leaf ){
int idx = pCur->aiIdx[pCur->iPage];
int idx = pCur->ix;
rc = moveToChild(pCur, get4byte(findCell(pPage, idx)));
if( rc ) return rc;
rc = moveToRightmost(pCur);
}else{
while( pCur->aiIdx[pCur->iPage]==0 ){
while( pCur->ix==0 ){
if( pCur->iPage==0 ){
pCur->eState = CURSOR_INVALID;
*pRes = 1;
@@ -5587,7 +5588,7 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur, int *pRes){
assert( pCur->info.nSize==0 );
assert( (pCur->curFlags & (BTCF_ValidOvfl))==0 );
pCur->aiIdx[pCur->iPage]--;
pCur->ix--;
pPage = pCur->apPage[pCur->iPage];
if( pPage->intKey && !pPage->leaf ){
rc = sqlite3BtreePrevious(pCur, pRes);
@@ -5606,12 +5607,12 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey);
pCur->info.nSize = 0;
if( pCur->eState!=CURSOR_VALID
|| pCur->aiIdx[pCur->iPage]==0
|| pCur->ix==0
|| pCur->apPage[pCur->iPage]->leaf==0
){
return btreePrevious(pCur, pRes);
}
pCur->aiIdx[pCur->iPage]--;
pCur->ix--;
return SQLITE_OK;
}
@@ -7933,8 +7934,8 @@ static int balance(BtCursor *pCur){
rc = balance_deeper(pPage, &pCur->apPage[1]);
if( rc==SQLITE_OK ){
pCur->iPage = 1;
pCur->ix = 0;
pCur->aiIdx[0] = 0;
pCur->aiIdx[1] = 0;
assert( pCur->apPage[1]->nOverflow );
}
}else{
@@ -8163,7 +8164,7 @@ int sqlite3BtreeInsert(
if( rc ) goto end_insert;
assert( szNew==pPage->xCellSize(pPage, newCell) );
assert( szNew <= MX_CELL_SIZE(pBt) );
idx = pCur->aiIdx[pCur->iPage];
idx = pCur->ix;
if( loc==0 ){
CellInfo info;
assert( idx<pPage->nCell );
@@ -8191,7 +8192,7 @@ int sqlite3BtreeInsert(
if( rc ) goto end_insert;
}else if( loc<0 && pPage->nCell>0 ){
assert( pPage->leaf );
idx = ++pCur->aiIdx[pCur->iPage];
idx = ++pCur->ix;
}else{
assert( pPage->leaf );
}
@@ -8287,12 +8288,12 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
assert( pCur->curFlags & BTCF_WriteFlag );
assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
assert( !hasReadConflicts(p, pCur->pgnoRoot) );
assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
assert( pCur->ix<pCur->apPage[pCur->iPage]->nCell );
assert( pCur->eState==CURSOR_VALID );
assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 );
iCellDepth = pCur->iPage;
iCellIdx = pCur->aiIdx[iCellDepth];
iCellIdx = pCur->ix;
pPage = pCur->apPage[iCellDepth];
pCell = findCell(pPage, iCellIdx);
@@ -8409,7 +8410,7 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
pCur->eState = CURSOR_SKIPNEXT;
if( iCellIdx>=pPage->nCell ){
pCur->skipNext = -1;
pCur->aiIdx[iCellDepth] = pPage->nCell-1;
pCur->ix = pPage->nCell-1;
}else{
pCur->skipNext = 1;
}
@@ -8922,16 +8923,16 @@ int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){
return moveToRoot(pCur);
}
moveToParent(pCur);
}while ( pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell );
}while ( pCur->ix>=pCur->apPage[pCur->iPage]->nCell );
pCur->aiIdx[pCur->iPage]++;
pCur->ix++;
pPage = pCur->apPage[pCur->iPage];
}
/* Descend to the child node of the cell that the cursor currently
** points at. This is the right-child if (iIdx==pPage->nCell).
*/
iIdx = pCur->aiIdx[pCur->iPage];
iIdx = pCur->ix;
if( iIdx==pPage->nCell ){
rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
}else{