aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordanielk1977 <danielk1977@noemail.net>2008-09-19 16:39:38 +0000
committerdanielk1977 <danielk1977@noemail.net>2008-09-19 16:39:38 +0000
commitd9f6c53232b64a1f163915699bd6f27dd2c85672 (patch)
tree348cafb82e072f6fb92494d2835b96d8887158fd /src
parentea89730823331765de66391998f58b8a11a02c29 (diff)
downloadsqlite-d9f6c53232b64a1f163915699bd6f27dd2c85672.tar.gz
sqlite-d9f6c53232b64a1f163915699bd6f27dd2c85672.zip
In function moveToRoot(), use the MemPage.pParent pointers to find the root page if they are valid. This is slightly faster than requesting a new reference to the root page from the pager layer. (CVS 5725)
FossilOrigin-Name: 0c8b74e668b7462c5439c04993d1d7cd74210075
Diffstat (limited to 'src')
-rw-r--r--src/btree.c37
1 files changed, 31 insertions, 6 deletions
diff --git a/src/btree.c b/src/btree.c
index 3c1512f2b..2a0b048be 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.515 2008/09/19 15:10:58 danielk1977 Exp $
+** $Id: btree.c,v 1.516 2008/09/19 16:39:38 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** See the header comment on "btreeInt.h" for additional information.
@@ -3564,8 +3564,22 @@ static int moveToRoot(BtCursor *pCur){
clearCursorPosition(pCur);
}
pRoot = pCur->pPage;
- if( pRoot && pRoot->pgno==pCur->pgnoRoot ){
+ if( pRoot && pRoot->isInit ){
+ /* If the page the cursor is currently pointing to is fully initialized,
+ ** then the root page can be found by following the MemPage.pParent
+ ** pointers. This is faster than requesting a reference to the root
+ ** page from the pager layer.
+ */
+ while( pRoot->pParent ){
+ assert( pRoot->isInit==PAGE_ISINIT_FULL );
+ pRoot = pRoot->pParent;
+ }
assert( pRoot->isInit==PAGE_ISINIT_FULL );
+ if( pRoot!=pCur->pPage ){
+ sqlite3PagerRef(pRoot->pDbPage);
+ releasePage(pCur->pPage);
+ pCur->pPage = pRoot;
+ }
}else{
if(
SQLITE_OK!=(rc = getAndInitPage(pBt, pCur->pgnoRoot, &pRoot, 0))
@@ -3576,6 +3590,7 @@ static int moveToRoot(BtCursor *pCur){
releasePage(pCur->pPage);
pCur->pPage = pRoot;
}
+ assert( pCur->pPage->pgno==pCur->pgnoRoot );
pCur->idx = 0;
pCur->info.nSize = 0;
pCur->atLast = 0;
@@ -3745,7 +3760,6 @@ int sqlite3BtreeMovetoUnpacked(
}
}
-
rc = moveToRoot(pCur);
if( rc ){
return rc;
@@ -6472,18 +6486,29 @@ int sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){
}
assert( idx>=0 && idx<=15 );
- if( !pBt->pPage1 ){
+ if( pBt->pPage1 ){
+ /* The b-tree is already holding a reference to page 1 of the database
+ ** file. In this case the required meta-data value can be read directly
+ ** from the page data of this reference. This is slightly faster than
+ ** requesting a new reference from the pager layer.
+ */
+ pP1 = (unsigned char *)pBt->pPage1->aData;
+ }else{
+ /* The b-tree does not have a reference to page 1 of the database file.
+ ** Obtain one from the pager layer.
+ */
rc = sqlite3PagerGet(pBt->pPager, 1, &pDbPage);
if( rc ){
sqlite3BtreeLeave(p);
return rc;
}
pP1 = (unsigned char *)sqlite3PagerGetData(pDbPage);
- }else{
- pP1 = (unsigned char *)pBt->pPage1->aData;
}
*pMeta = get4byte(&pP1[36 + idx*4]);
+ /* If the b-tree is not holding a reference to page 1, then one was
+ ** requested from the pager layer in the above block. Release it now.
+ */
if( !pBt->pPage1 ){
sqlite3PagerUnref(pDbPage);
}