From: drh Date: Fri, 13 Jan 2006 04:31:58 +0000 (+0000) Subject: Additional speed enhancements in btree.c. (CVS 2935) X-Git-Tag: version-3.6.10~3232 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=777e4c43f28d54370bfefefdea5a18f6905e9c4b;p=thirdparty%2Fsqlite.git Additional speed enhancements in btree.c. (CVS 2935) FossilOrigin-Name: 48b550ce2ea43c7c1c59cd43d0008ba18fc0215b --- diff --git a/manifest b/manifest index 2ac0be5abe..d07fa6571c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\sperformance\simprovement\son\ssqlite3BtreeMoveto.\s(CVS\s2934) -D 2006-01-13T02:35:10 +C Additional\sspeed\senhancements\sin\sbtree.c.\s(CVS\s2935) +D 2006-01-13T04:31:58 F Makefile.in ab3ffd8d469cef4477257169b82810030a6bb967 F Makefile.linux-gcc aee18d8a05546dcf1888bd4547e442008a49a092 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -34,7 +34,7 @@ F src/alter.c 4139c8f1d0f12b1759e767b1d09dd594e2b5ac1d F src/analyze.c 7d2b7ab9a9c2fd6e55700f69064dfdd3e36d7a8a F src/attach.c d4b9d8bd71d72409720946355be41cafb6c09079 F src/auth.c cdec356a5cd8b217c346f816c5912221537fe87f -F src/btree.c 51b54ae0182d6b2cf129bc98064f5a2c4ed30ab9 +F src/btree.c 91943e07457ced1842ff93f331ab6bc1e277747e F src/btree.h 5663c4f43e8521546ccebc8fc95acb013b8f3184 F src/build.c a055974683ddc465bdc8669d43d6ab35d3dbb55f F src/callback.c ba3e6cc7a6beb562e7a66f92e26fabcb21aab1e2 @@ -340,7 +340,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513 -P a64e8251a606fb2c298d7d804f3964a9155c73c5 -R 88c254e780b2ea9454333fd58253e3cf +P c780152f3cff9c0a13d231935ae3c2e2d28b4460 +R faee7b6f93f8c539141e3d35033db1a4 U drh -Z cf8b778aba2aa976f9c38e986b5a01cc +Z 5297e80bacccd6731d8a506f98111dd3 diff --git a/manifest.uuid b/manifest.uuid index ac82ed014a..69df06db98 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c780152f3cff9c0a13d231935ae3c2e2d28b4460 \ No newline at end of file +48b550ce2ea43c7c1c59cd43d0008ba18fc0215b \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index dada61a0f8..ec079f7b99 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btree.c,v 1.294 2006/01/13 02:35:10 drh Exp $ +** $Id: btree.c,v 1.295 2006/01/13 04:31:58 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to @@ -411,7 +411,7 @@ struct BtCursor { ** The table that this cursor was opened on still exists, but has been ** modified since the cursor was last used. The cursor position is saved ** in variables BtCursor.pKey and BtCursor.nKey. When a cursor is in -** this state, restoreCursorPosition() can be called to attempt to seek +** this state, restoreOrClearCursorPosition() can be called to attempt to seek ** the cursor to the saved position. */ #define CURSOR_INVALID 0 @@ -501,7 +501,7 @@ struct BtLock { #define queryTableLock(a,b,c) SQLITE_OK #define lockTable(a,b,c) SQLITE_OK #define unlockAllTables(a) - #define restoreCursorPosition(a,b) SQLITE_OK + #define restoreOrClearCursorPosition(a,b) SQLITE_OK #define saveAllCursors(a,b,c) SQLITE_OK #else @@ -574,14 +574,14 @@ static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){ ** Restore the cursor to the position it was in (or as close to as possible) ** when saveCursorPosition() was called. Note that this call deletes the ** saved position info stored by saveCursorPosition(), so there can be -** at most one effective restoreCursorPosition() call after each +** at most one effective restoreOrClearCursorPosition() call after each ** saveCursorPosition(). ** ** If the second argument argument - doSeek - is false, then instead of ** returning the cursor to it's saved position, any saved position is deleted ** and the cursor state set to CURSOR_INVALID. */ -static int restoreCursorPosition(BtCursor *pCur, int doSeek){ +static int restoreOrClearCursorPosition(BtCursor *pCur, int doSeek){ int rc = SQLITE_OK; if( pCur->eState==CURSOR_REQUIRESEEK ){ assert( sqlite3ThreadDataReadOnly()->useSharedData ); @@ -2768,7 +2768,7 @@ void sqlite3BtreeSetCompare( */ int sqlite3BtreeCloseCursor(BtCursor *pCur){ BtShared *pBt = pCur->pBtree->pBt; - restoreCursorPosition(pCur, 0); + restoreOrClearCursorPosition(pCur, 0); if( pCur->pPrev ){ pCur->pPrev->pNext = pCur->pNext; }else{ @@ -2835,7 +2835,7 @@ static void getCellInfo(BtCursor *pCur){ ** itself, not the number of bytes in the key. */ int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){ - int rc = restoreCursorPosition(pCur, 1); + int rc = restoreOrClearCursorPosition(pCur, 1); if( rc==SQLITE_OK ){ assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID ); if( pCur->eState==CURSOR_INVALID ){ @@ -2856,7 +2856,7 @@ int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){ ** the database is empty) then *pSize is set to 0. */ int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){ - int rc = restoreCursorPosition(pCur, 1); + int rc = restoreOrClearCursorPosition(pCur, 1); if( rc==SQLITE_OK ){ assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID ); if( pCur->eState==CURSOR_INVALID ){ @@ -2970,7 +2970,7 @@ static int getPayload( ** the available payload. */ int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ - int rc = restoreCursorPosition(pCur, 1); + int rc = restoreOrClearCursorPosition(pCur, 1); if( rc==SQLITE_OK ){ assert( pCur->eState==CURSOR_VALID ); assert( pCur->pPage!=0 ); @@ -2994,7 +2994,7 @@ int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ ** the available payload. */ int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ - int rc = restoreCursorPosition(pCur, 1); + int rc = restoreOrClearCursorPosition(pCur, 1); if( rc==SQLITE_OK ){ assert( pCur->eState==CURSOR_VALID ); assert( pCur->pPage!=0 ); @@ -3164,19 +3164,25 @@ static void moveToParent(BtCursor *pCur){ */ static int moveToRoot(BtCursor *pCur){ MemPage *pRoot; - int rc; + int rc = SQLITE_OK; BtShared *pBt = pCur->pBtree->pBt; - if( - SQLITE_OK!=(rc = restoreCursorPosition(pCur, 0)) || - SQLITE_OK!=(rc = getAndInitPage(pBt, pCur->pgnoRoot, &pRoot, 0)) - ){ - pCur->eState = CURSOR_INVALID; - return rc; + restoreOrClearCursorPosition(pCur, 0); + assert( pCur->pPage ); + pRoot = pCur->pPage; + if( pRoot->pgno==pCur->pgnoRoot ){ + assert( pRoot->isInit ); + }else{ + if( + SQLITE_OK!=(rc = getAndInitPage(pBt, pCur->pgnoRoot, &pRoot, 0)) + ){ + pCur->eState = CURSOR_INVALID; + return rc; + } + releasePage(pCur->pPage); + pageIntegrity(pRoot); + pCur->pPage = pRoot; } - releasePage(pCur->pPage); - pageIntegrity(pRoot); - pCur->pPage = pRoot; pCur->idx = 0; pCur->info.nSize = 0; if( pRoot->nCell==0 && !pRoot->leaf ){ @@ -3194,6 +3200,9 @@ static int moveToRoot(BtCursor *pCur){ /* ** Move the cursor down to the left-most leaf entry beneath the ** entry to which it is currently pointing. +** +** The left-most leaf is the one with the smallest key - the first +** in ascending order. */ static int moveToLeftmost(BtCursor *pCur){ Pgno pgno; @@ -3216,6 +3225,9 @@ static int moveToLeftmost(BtCursor *pCur){ ** between moveToLeftmost() and moveToRightmost(). moveToLeftmost() ** finds the left-most entry beneath the *entry* whereas moveToRightmost() ** finds the right-most entry beneath the *page*. +** +** The right-most entry is the one with the largest key - the last +** key in ascending order. */ static int moveToRightmost(BtCursor *pCur){ Pgno pgno; @@ -3301,10 +3313,12 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ */ int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, i64 nKey, int *pRes){ int rc; + int tryRightmost; rc = moveToRoot(pCur); if( rc ) return rc; assert( pCur->pPage ); assert( pCur->pPage->isInit ); + tryRightmost = pCur->pPage->intKey; if( pCur->eState==CURSOR_INVALID ){ *pRes = -1; assert( pCur->pPage->nCell==0 ); @@ -3327,8 +3341,11 @@ int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, i64 nKey, int *pRes){ pCur->idx = (lwr+upr)/2; pCur->info.nSize = 0; if( pPage->intKey ){ - u8 *pCell = findCell(pPage, pCur->idx); - pCell += pPage->childPtrSize; + u8 *pCell; + if( tryRightmost ){ + pCur->idx = upr; + } + pCell = findCell(pPage, pCur->idx) + pPage->childPtrSize; if( pPage->hasData ){ int dummy; pCell += getVarint32(pCell, &dummy); @@ -3338,6 +3355,7 @@ int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, i64 nKey, int *pRes){ c = -1; }else if( nCellKey>nKey ){ c = +1; + tryRightmost = 0; }else{ c = 0; } @@ -3422,7 +3440,7 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){ MemPage *pPage = pCur->pPage; #ifndef SQLITE_OMIT_SHARED_CACHE - rc = restoreCursorPosition(pCur, 1); + rc = restoreOrClearCursorPosition(pCur, 1); if( rc!=SQLITE_OK ){ return rc; } @@ -3489,7 +3507,7 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){ MemPage *pPage; #ifndef SQLITE_OMIT_SHARED_CACHE - rc = restoreCursorPosition(pCur, 1); + rc = restoreOrClearCursorPosition(pCur, 1); if( rc!=SQLITE_OK ){ return rc; } @@ -5159,8 +5177,8 @@ int sqlite3BtreeInsert( } /* Save the positions of any other cursors open on this table */ + restoreOrClearCursorPosition(pCur, 0); if( - SQLITE_OK!=(rc = restoreCursorPosition(pCur, 0)) || SQLITE_OK!=(rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur)) || SQLITE_OK!=(rc = sqlite3BtreeMoveto(pCur, pKey, nKey, &loc)) ){ @@ -5246,7 +5264,7 @@ int sqlite3BtreeDelete(BtCursor *pCur){ ** that the entry will be deleted from. */ if( - (rc = restoreCursorPosition(pCur, 1)) || + (rc = restoreOrClearCursorPosition(pCur, 1)) || (rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur)) || (rc = sqlite3pager_write(pPage->aData)) ){ @@ -5728,7 +5746,7 @@ int sqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){ */ int sqlite3BtreeFlags(BtCursor *pCur){ /* TODO: What about CURSOR_REQUIRESEEK state? Probably need to call - ** restoreCursorPosition() here. + ** restoreOrClearCursorPosition() here. */ MemPage *pPage = pCur->pPage; return pPage ? pPage->aData[pPage->hdrOffset] : 0; @@ -5863,7 +5881,7 @@ int sqlite3BtreeCursorInfo(BtCursor *pCur, int *aResult, int upCnt){ MemPage *pPage = pCur->pPage; BtCursor tmpCur; - int rc = restoreCursorPosition(pCur, 1); + int rc = restoreOrClearCursorPosition(pCur, 1); if( rc!=SQLITE_OK ){ return rc; }