diff options
author | drh <drh@noemail.net> | 2002-07-08 02:16:37 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2002-07-08 02:16:37 +0000 |
commit | 6b30867ff6876b4de791dab705e60dd5348d987f (patch) | |
tree | c82238e34e0e88a69696ee2c711cb94582466163 /src | |
parent | 6f08d709b1f9bb0196e87043a1c6a28209fa30f3 (diff) | |
download | sqlite-6b30867ff6876b4de791dab705e60dd5348d987f.tar.gz sqlite-6b30867ff6876b4de791dab705e60dd5348d987f.zip |
Make the BTree balance() routine a little faster by reusing database
pages locally rather than freeing and reallocating them. (CVS 666)
FossilOrigin-Name: 3c2dea4310af491d6cb09856d4bc5236d6dc44ac
Diffstat (limited to 'src')
-rw-r--r-- | src/btree.c | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/src/btree.c b/src/btree.c index 01200492e..9dfb46dd9 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.65 2002/07/07 16:52:47 drh Exp $ +** $Id: btree.c,v 1.66 2002/07/08 02:16:38 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to @@ -2099,10 +2099,6 @@ static int balance(Btree *pBt, MemPage *pPage, BtCursor *pCur){ */ for(i=0; i<nOld; i++){ copyPage(&aOld[i], apOld[i]); - rc = freePage(pBt, apOld[i], pgnoOld[i]); - if( rc ) goto balance_cleanup; - sqlitepager_unref(apOld[i]); - apOld[i] = &aOld[i]; } /* @@ -2112,7 +2108,7 @@ static int balance(Btree *pBt, MemPage *pPage, BtCursor *pCur){ */ nCell = 0; for(i=0; i<nOld; i++){ - MemPage *pOld = apOld[i]; + MemPage *pOld = &aOld[i]; for(j=0; j<pOld->nCell; j++){ apCell[nCell] = pOld->apCell[j]; szCell[nCell] = cellSize(apCell[nCell]); @@ -2166,16 +2162,33 @@ static int balance(Btree *pBt, MemPage *pPage, BtCursor *pCur){ assert( cntNew[0]>0 ); /* - ** Allocate k new pages + ** Allocate k new pages. Reuse old pages where possible. */ for(i=0; i<k; i++){ - rc = allocatePage(pBt, &apNew[i], &pgnoNew[i]); - if( rc ) goto balance_cleanup; + if( i<nOld ){ + apNew[i] = apOld[i]; + pgnoNew[i] = pgnoOld[i]; + apOld[i] = 0; + sqlitepager_write(apNew[i]); + }else{ + rc = allocatePage(pBt, &apNew[i], &pgnoNew[i]); + if( rc ) goto balance_cleanup; + } nNew++; zeroPage(apNew[i]); apNew[i]->isInit = 1; } + /* Free any old pages that were not reused as new pages. + */ + while( i<nOld ){ + rc = freePage(pBt, apOld[i], pgnoOld[i]); + if( rc ) goto balance_cleanup; + sqlitepager_unref(apOld[i]); + apOld[i] = 0; + i++; + } + /* ** Put the new pages in accending order. This helps to ** keep entries in the disk file in order so that a scan @@ -2236,7 +2249,7 @@ static int balance(Btree *pBt, MemPage *pPage, BtCursor *pCur){ } } assert( j==nCell ); - apNew[nNew-1]->u.hdr.rightChild = apOld[nOld-1]->u.hdr.rightChild; + apNew[nNew-1]->u.hdr.rightChild = aOld[nOld-1].u.hdr.rightChild; if( nxDiv==pParent->nCell ){ pParent->u.hdr.rightChild = pgnoNew[nNew-1]; }else{ @@ -2274,7 +2287,7 @@ balance_cleanup: sqlitepager_unref(extraUnref); } for(i=0; i<nOld; i++){ - if( apOld[i]!=&aOld[i] ) sqlitepager_unref(apOld[i]); + if( apOld[i]!=0 && apOld[i]!=&aOld[i] ) sqlitepager_unref(apOld[i]); } for(i=0; i<nNew; i++){ sqlitepager_unref(apNew[i]); |