mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +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:
14
manifest
14
manifest
@@ -1,5 +1,5 @@
|
||||
C Declare\sthe\sLemon-generated\sparser\sobject\sas\sitself.\s\s(Duh)
|
||||
D 2017-03-30T17:13:37.978
|
||||
C Save\sa\s78\sbytes\sof\scode\sspace\sand\sa\smillion\sCPU\scycles\sin\sspeedtest1\sby\nstoring\sthe\scell\sindex\sfor\sthe\sleaf\spage\sin\sthe\sBtCursor\sobject\sin\sits\sown\nfield\s(BtCursor.ix),\srather\sthan\sas\san\sentry\sin\sthe\sBtCursor.aiIdx\sarray.
|
||||
D 2017-04-01T00:20:06.305
|
||||
F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a
|
||||
@@ -344,9 +344,9 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792
|
||||
F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b
|
||||
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
|
||||
F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca
|
||||
F src/btree.c 64ff65a01851a34c8145e5bc767df9e57d2f3c1acdc6aba334794b7c40c684e6
|
||||
F src/btree.c 24ae5472bd0b53b4130ecdda389deb621af721d1fcb50890b878102b00bd10fa
|
||||
F src/btree.h bf64dfeeddeebdb775a5eba0098bbc00d073290d
|
||||
F src/btreeInt.h cd55d39d9916270837a88c12e701047cba0729b0
|
||||
F src/btreeInt.h 874e49bdfab514285dda1cb01880e4c82b7a428a0de7d9b2978d8d8849fbb210
|
||||
F src/build.c 43f903c9082040ced2b421543cb0300c2973647d
|
||||
F src/callback.c 2e76147783386374bf01b227f752c81ec872d730
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
@@ -1569,7 +1569,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 9e550ccc29f317422dae3a4bb89a78b839330825fecd40a01d1a2acc719cef79
|
||||
R 288166ae6bc74f6b9a15fa169ea78182
|
||||
P c8000e94cca59dabf83d6cb75b40441aaf793d29880582dc4baa17246449b5fe
|
||||
R a50a3e5b98174af9f9e2e47aca996e63
|
||||
U drh
|
||||
Z 81f3770fca5082b63e34ff795f3d141f
|
||||
Z 14f3c01fb36e600191848f3a558eb584
|
||||
|
@@ -1 +1 @@
|
||||
c8000e94cca59dabf83d6cb75b40441aaf793d29880582dc4baa17246449b5fe
|
||||
2452f0617d1085689264b5f66681788cfe9e3b1a7b318307c93942b702a443df
|
77
src/btree.c
77
src/btree.c
@@ -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{
|
||||
|
@@ -517,6 +517,7 @@ struct BtCursor {
|
||||
** initialized. */
|
||||
i8 iPage; /* Index of current page in apPage */
|
||||
u8 curIntKey; /* Value of apPage[0]->intKey */
|
||||
u16 ix; /* Current index for apPage[iPage] */
|
||||
struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */
|
||||
void *padding1; /* Make object size a multiple of 16 */
|
||||
u16 aiIdx[BTCURSOR_MAX_DEPTH]; /* Current index in apPage[i] */
|
||||
|
Reference in New Issue
Block a user