aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2002-07-08 02:16:37 +0000
committerdrh <drh@noemail.net>2002-07-08 02:16:37 +0000
commit6b30867ff6876b4de791dab705e60dd5348d987f (patch)
treec82238e34e0e88a69696ee2c711cb94582466163 /src
parent6f08d709b1f9bb0196e87043a1c6a28209fa30f3 (diff)
downloadsqlite-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.c35
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]);