mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Micro-optimizations in sqlite3BtreeNext() and sqlite3BtreePrevious().
FossilOrigin-Name: 839c7996eecd5480152c514555b9aa1121a69ce0
This commit is contained in:
14
manifest
14
manifest
@@ -1,5 +1,5 @@
|
||||
C Fix\sharmless\scompiler\swarnings\sfor\sMSVC.
|
||||
D 2014-09-01T01:16:49.641
|
||||
C Micro-optimizations\sin\ssqlite3BtreeNext()\sand\ssqlite3BtreePrevious().
|
||||
D 2014-09-01T13:29:32.250
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 5eb79e334a5de69c87740edd56af6527dd219308
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@@ -168,7 +168,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
|
||||
F src/backup.c a31809c65623cc41849b94d368917f8bb66e6a7e
|
||||
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
|
||||
F src/btmutex.c ec9d3f1295dafeb278c3830211cc5584132468f4
|
||||
F src/btree.c 4737cb5bdb2eb8989cb292f6ff921f7ff45f0c46
|
||||
F src/btree.c 4d0427bab54229030fc5b8577d2e5ffdc8129030
|
||||
F src/btree.h a79aa6a71e7f1055f01052b7f821bd1c2dce95c8
|
||||
F src/btreeInt.h cf180d86b2e9e418f638d65baa425c4c69c0e0e3
|
||||
F src/build.c 058e3aadb1376521ff291735237edf4c10f438fb
|
||||
@@ -1188,7 +1188,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P f61db04be4d7fb21b7f721647c37c45e283ffbea
|
||||
R fb90b1156ce26645b130e94c9528a286
|
||||
U mistachkin
|
||||
Z ab89ed2842a9e03f7299dfc1fb42f5cb
|
||||
P 3ef3246120d72dffe469733bb21667a548af0a44
|
||||
R 8a87472d819e62a6d7e88f3d5e77ba23
|
||||
U drh
|
||||
Z 5b0c8a527e1dec5d8cc1bbd203422489
|
||||
|
@@ -1 +1 @@
|
||||
3ef3246120d72dffe469733bb21667a548af0a44
|
||||
839c7996eecd5480152c514555b9aa1121a69ce0
|
123
src/btree.c
123
src/btree.c
@@ -4513,17 +4513,16 @@ static int moveToRightmost(BtCursor *pCur){
|
||||
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( pCur->eState==CURSOR_VALID );
|
||||
while( rc==SQLITE_OK && !(pPage = pCur->apPage[pCur->iPage])->leaf ){
|
||||
while( !(pPage = pCur->apPage[pCur->iPage])->leaf ){
|
||||
pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
|
||||
pCur->aiIdx[pCur->iPage] = pPage->nCell;
|
||||
rc = moveToChild(pCur, pgno);
|
||||
if( rc ) return rc;
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
pCur->aiIdx[pCur->iPage] = pPage->nCell-1;
|
||||
pCur->info.nSize = 0;
|
||||
pCur->curFlags &= ~BTCF_ValidNKey;
|
||||
}
|
||||
return rc;
|
||||
pCur->aiIdx[pCur->iPage] = pPage->nCell-1;
|
||||
assert( pCur->info.nSize==0 );
|
||||
assert( (pCur->curFlags & BTCF_ValidNKey)==0 );
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/* Move the cursor to the first entry in the table. Return SQLITE_OK
|
||||
@@ -4843,6 +4842,12 @@ int sqlite3BtreeEof(BtCursor *pCur){
|
||||
** was already pointing to the last entry in the database before
|
||||
** this routine was called, then set *pRes=1.
|
||||
**
|
||||
** The main entry point is sqlite3BtreeNext(). That routine is optimized
|
||||
** for the common case of merely incrementing the cell counter BtCursor.aiIdx
|
||||
** to the next cell on the current page. The (slower) btreeNext() helper
|
||||
** routine is called when it is necessary to move to a different page or
|
||||
** to restore the cursor.
|
||||
**
|
||||
** The calling function will set *pRes to 0 or 1. The initial *pRes value
|
||||
** will be 1 if the cursor being stepped corresponds to an SQL index and
|
||||
** if this routine could have been skipped if that SQL index had been
|
||||
@@ -4852,20 +4857,18 @@ int sqlite3BtreeEof(BtCursor *pCur){
|
||||
** SQLite btree implementation does not. (Note that the comdb2 btree
|
||||
** implementation does use this hint, however.)
|
||||
*/
|
||||
int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
|
||||
static SQLITE_NOINLINE int btreeNext(BtCursor *pCur, int *pRes){
|
||||
int rc;
|
||||
int idx;
|
||||
MemPage *pPage;
|
||||
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( pRes!=0 );
|
||||
assert( *pRes==0 || *pRes==1 );
|
||||
assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
|
||||
assert( *pRes==0 );
|
||||
if( pCur->eState!=CURSOR_VALID ){
|
||||
invalidateOverflowCache(pCur);
|
||||
assert( (pCur->curFlags & BTCF_ValidOvfl)==0 );
|
||||
rc = restoreCursorPosition(pCur);
|
||||
if( rc!=SQLITE_OK ){
|
||||
*pRes = 0;
|
||||
return rc;
|
||||
}
|
||||
if( CURSOR_INVALID==pCur->eState ){
|
||||
@@ -4877,7 +4880,6 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
|
||||
pCur->eState = CURSOR_VALID;
|
||||
if( pCur->skipNext>0 ){
|
||||
pCur->skipNext = 0;
|
||||
*pRes = 0;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
pCur->skipNext = 0;
|
||||
@@ -4895,18 +4897,11 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
|
||||
** page into more than one b-tree structure. */
|
||||
testcase( idx>pPage->nCell );
|
||||
|
||||
pCur->info.nSize = 0;
|
||||
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
|
||||
if( idx>=pPage->nCell ){
|
||||
if( !pPage->leaf ){
|
||||
rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
|
||||
if( rc ){
|
||||
*pRes = 0;
|
||||
return rc;
|
||||
}
|
||||
rc = moveToLeftmost(pCur);
|
||||
*pRes = 0;
|
||||
return rc;
|
||||
if( rc ) return rc;
|
||||
return moveToLeftmost(pCur);
|
||||
}
|
||||
do{
|
||||
if( pCur->iPage==0 ){
|
||||
@@ -4917,22 +4912,39 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
|
||||
moveToParent(pCur);
|
||||
pPage = pCur->apPage[pCur->iPage];
|
||||
}while( pCur->aiIdx[pCur->iPage]>=pPage->nCell );
|
||||
*pRes = 0;
|
||||
if( pPage->intKey ){
|
||||
rc = sqlite3BtreeNext(pCur, pRes);
|
||||
return sqlite3BtreeNext(pCur, pRes);
|
||||
}else{
|
||||
rc = SQLITE_OK;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
*pRes = 0;
|
||||
if( pPage->leaf ){
|
||||
return SQLITE_OK;
|
||||
}else{
|
||||
return moveToLeftmost(pCur);
|
||||
}
|
||||
}
|
||||
int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
|
||||
MemPage *pPage;
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( pRes!=0 );
|
||||
assert( *pRes==0 || *pRes==1 );
|
||||
assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
|
||||
pCur->info.nSize = 0;
|
||||
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
|
||||
*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]--;
|
||||
return btreeNext(pCur, pRes);
|
||||
}
|
||||
if( pPage->leaf ){
|
||||
return SQLITE_OK;
|
||||
}else{
|
||||
return moveToLeftmost(pCur);
|
||||
}
|
||||
rc = moveToLeftmost(pCur);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Step the cursor to the back to the previous entry in the database. If
|
||||
@@ -4940,6 +4952,12 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
|
||||
** was already pointing to the first entry in the database before
|
||||
** this routine was called, then set *pRes=1.
|
||||
**
|
||||
** The main entry point is sqlite3BtreePrevious(). That routine is optimized
|
||||
** for the common case of merely decrementing the cell counter BtCursor.aiIdx
|
||||
** to the previous cell on the current page. The (slower) btreePrevious() helper
|
||||
** routine is called when it is necessary to move to a different page or
|
||||
** to restore the cursor.
|
||||
**
|
||||
** The calling function will set *pRes to 0 or 1. The initial *pRes value
|
||||
** will be 1 if the cursor being stepped corresponds to an SQL index and
|
||||
** if this routine could have been skipped if that SQL index had been
|
||||
@@ -4949,22 +4967,21 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
|
||||
** SQLite btree implementation does not. (Note that the comdb2 btree
|
||||
** implementation does use this hint, however.)
|
||||
*/
|
||||
int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
|
||||
static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur, int *pRes){
|
||||
int rc;
|
||||
MemPage *pPage;
|
||||
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( pRes!=0 );
|
||||
assert( *pRes==0 || *pRes==1 );
|
||||
assert( *pRes==0 );
|
||||
assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
|
||||
pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidOvfl);
|
||||
assert( (pCur->curFlags & (BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey))==0 );
|
||||
assert( pCur->info.nSize==0 );
|
||||
if( pCur->eState!=CURSOR_VALID ){
|
||||
if( ALWAYS(pCur->eState>=CURSOR_REQUIRESEEK) ){
|
||||
rc = btreeRestoreCursorPosition(pCur);
|
||||
if( rc!=SQLITE_OK ){
|
||||
*pRes = 0;
|
||||
return rc;
|
||||
}
|
||||
assert( pCur->eState>=CURSOR_REQUIRESEEK );
|
||||
rc = btreeRestoreCursorPosition(pCur);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
if( CURSOR_INVALID==pCur->eState ){
|
||||
*pRes = 1;
|
||||
@@ -4975,7 +4992,6 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
|
||||
pCur->eState = CURSOR_VALID;
|
||||
if( pCur->skipNext<0 ){
|
||||
pCur->skipNext = 0;
|
||||
*pRes = 0;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
pCur->skipNext = 0;
|
||||
@@ -4987,10 +5003,7 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
|
||||
if( !pPage->leaf ){
|
||||
int idx = pCur->aiIdx[pCur->iPage];
|
||||
rc = moveToChild(pCur, get4byte(findCell(pPage, idx)));
|
||||
if( rc ){
|
||||
*pRes = 0;
|
||||
return rc;
|
||||
}
|
||||
if( rc ) return rc;
|
||||
rc = moveToRightmost(pCur);
|
||||
}else{
|
||||
while( pCur->aiIdx[pCur->iPage]==0 ){
|
||||
@@ -5001,8 +5014,8 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
|
||||
}
|
||||
moveToParent(pCur);
|
||||
}
|
||||
pCur->info.nSize = 0;
|
||||
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
|
||||
assert( pCur->info.nSize==0 );
|
||||
assert( (pCur->curFlags & (BTCF_ValidNKey|BTCF_ValidOvfl))==0 );
|
||||
|
||||
pCur->aiIdx[pCur->iPage]--;
|
||||
pPage = pCur->apPage[pCur->iPage];
|
||||
@@ -5012,9 +5025,25 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
}
|
||||
*pRes = 0;
|
||||
return rc;
|
||||
}
|
||||
int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( pRes!=0 );
|
||||
assert( *pRes==0 || *pRes==1 );
|
||||
assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
|
||||
*pRes = 0;
|
||||
pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey);
|
||||
pCur->info.nSize = 0;
|
||||
if( pCur->eState!=CURSOR_VALID
|
||||
|| pCur->aiIdx[pCur->iPage]==0
|
||||
|| pCur->apPage[pCur->iPage]->leaf==0
|
||||
){
|
||||
return btreePrevious(pCur, pRes);
|
||||
}
|
||||
pCur->aiIdx[pCur->iPage]--;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Allocate a new page from the database file.
|
||||
|
Reference in New Issue
Block a user