From: danielk1977 Date: Sat, 19 Jul 2008 11:49:07 +0000 (+0000) Subject: Improve the performance of balance_nonroot() on auto-vacuum databases by reducing... X-Git-Tag: version-3.6.10~735 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=87c52b58f03027f6747c47e3667c84785e35f54e;p=thirdparty%2Fsqlite.git Improve the performance of balance_nonroot() on auto-vacuum databases by reducing the number of calls to ptrmapPut(). (CVS 5442) FossilOrigin-Name: 9992b1aecdbbc7a260f00cb6ef78b500aeab22df --- diff --git a/manifest b/manifest index 081287fa6c..e5b7f7a724 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sdead\scode\sfrom\sos_win.c.\s\sTicket\s\s#3232.\s(CVS\s5441) -D 2008-07-18T23:47:43 +C Improve\sthe\sperformance\sof\sbalance_nonroot()\son\sauto-vacuum\sdatabases\sby\sreducing\sthe\snumber\sof\scalls\sto\sptrmapPut().\s(CVS\s5442) +D 2008-07-19T11:49:07 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in a03f7cb4f7ad50bc53a788c6c544430e81f95de4 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -96,7 +96,7 @@ F src/attach.c b18ba42c77f7d3941f5d23d2ca20fa1d841a4e91 F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627 F src/bitvec.c 95c86bd18d8fedf0533f5af196192546e10a7e7d F src/btmutex.c 709cad2cdca0afd013f0f612363810e53f59ec53 -F src/btree.c 770e1b121d1e6c194c836fec2eab6739ebf4d059 +F src/btree.c 7303414d1afc4c56c8e16eb530fbd902c1243fbc F src/btree.h 03256ed7ee42b5ecacbe887070b0f8249e7d069d F src/btreeInt.h 6e4cb69a9192a8d609c27034ae5f921cf0ecdde1 F src/build.c bac7233d984be3805aaa41cf500f7ee12dc97249 @@ -608,7 +608,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e -P 5c22132eb171058f30ec5b7562b8164611236748 -R e6e5c52038725d75fcfc314f6d0945ad -U drh -Z f2c9fcc16d2a69d031b97db5b7833d47 +P 5c5c1f72797e4ceb229b8e3a7c65e5f173bb9e1a +R b8085ba1aaa9b1c45ae3197480a7b3e3 +U danielk1977 +Z bd3b5f822992a4ea7d03ac4968dd7385 diff --git a/manifest.uuid b/manifest.uuid index dc4a2a4a8a..5b742d62df 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5c5c1f72797e4ceb229b8e3a7c65e5f173bb9e1a \ No newline at end of file +9992b1aecdbbc7a260f00cb6ef78b500aeab22df \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 428183c9de..1594156fcd 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.489 2008/07/18 17:16:26 drh Exp $ +** $Id: btree.c,v 1.490 2008/07/19 11:49:07 danielk1977 Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. @@ -4526,8 +4526,18 @@ static int fillInCell( ** Change the MemPage.pParent pointer on the page whose number is ** given in the second argument so that MemPage.pParent holds the ** pointer in the third argument. +** +** If the final argument, updatePtrmap, is non-zero and the database +** is an auto-vacuum database, then the pointer-map entry for pgno +** is updated. */ -static int reparentPage(BtShared *pBt, Pgno pgno, MemPage *pNewParent, int idx){ +static int reparentPage( + BtShared *pBt, /* B-Tree structure */ + Pgno pgno, /* Page number of child being adopted */ + MemPage *pNewParent, /* New parent of pgno */ + int idx, /* Index of child page pgno in pNewParent */ + int updatePtrmap /* If true, update pointer-map for pgno */ +){ MemPage *pThis; DbPage *pDbPage; @@ -4551,9 +4561,22 @@ static int reparentPage(BtShared *pBt, Pgno pgno, MemPage *pNewParent, int idx){ } #ifndef SQLITE_OMIT_AUTOVACUUM - if( pBt->autoVacuum ){ + if( pBt->autoVacuum && updatePtrmap ){ return ptrmapPut(pBt, pgno, PTRMAP_BTREE, pNewParent->pgno); } + +#ifndef NDEBUG + /* If the updatePtrmap flag was clear, assert that the entry in the + ** pointer-map is already correct. + */ + if( pBt->autoVacuum ){ + u8 eType; + Pgno ii; + ptrmapGet(pBt, pgno, &eType, &ii); + assert( ii==pNewParent->pgno && eType==PTRMAP_BTREE ); + } +#endif + #endif return SQLITE_OK; } @@ -4569,23 +4592,26 @@ static int reparentPage(BtShared *pBt, Pgno pgno, MemPage *pNewParent, int idx){ ** ** This routine gets called after you memcpy() one page into ** another. +** +** If updatePtrmap is true, then the pointer-map entries for all child +** pages of pPage are updated. */ -static int reparentChildPages(MemPage *pPage){ - int i; - BtShared *pBt = pPage->pBt; +static int reparentChildPages(MemPage *pPage, int updatePtrmap){ int rc = SQLITE_OK; - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - if( pPage->leaf ) return SQLITE_OK; + if( !pPage->leaf ){ + int i; + BtShared *pBt = pPage->pBt; + Pgno iRight = get4byte(&pPage->aData[pPage->hdrOffset+8]); - for(i=0; inCell; i++){ - u8 *pCell = findCell(pPage, i); - rc = reparentPage(pBt, get4byte(pCell), pPage, i); - if( rc!=SQLITE_OK ) return rc; + for(i=0; inCell; i++){ + u8 *pCell = findCell(pPage, i); + rc = reparentPage(pBt, get4byte(pCell), pPage, i, updatePtrmap); + if( rc!=SQLITE_OK ) return rc; + } + rc = reparentPage(pBt, iRight, pPage, i, updatePtrmap); + pPage->idxShift = 0; } - rc = reparentPage(pBt, get4byte(&pPage->aData[pPage->hdrOffset+8]), - pPage, i); - pPage->idxShift = 0; return rc; } @@ -5350,17 +5376,20 @@ static int balance_nonroot(MemPage *pPage){ assert( pNew->nCell>0 || (nNew==1 && cntNew[0]==0) ); assert( pNew->nOverflow==0 ); -#ifndef SQLITE_OMIT_AUTOVACUUM /* If this is an auto-vacuum database, update the pointer map entries ** that point to the siblings that were rearranged. These can be: left ** children of cells, the right-child of the page, or overflow pages ** pointed to by cells. */ +#ifndef SQLITE_OMIT_AUTOVACUUM if( pBt->autoVacuum ){ for(k=j; kpgno!=pNew->pgno ){ rc = ptrmapPutOvfl(pNew, k-j); + if( rc==SQLITE_OK && leafCorrection==0 ){ + rc = ptrmapPut(pBt, get4byte(apCell[k]), PTRMAP_BTREE, pNew->pgno); + } if( rc!=SQLITE_OK ){ goto balance_cleanup; } @@ -5385,6 +5414,16 @@ static int balance_nonroot(MemPage *pPage){ pTemp = &aSpace2[iSpace2]; if( !pNew->leaf ){ memcpy(&pNew->aData[8], pCell, 4); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum + && (aFrom[j]==0xFF || apCopy[aFrom[j]]->pgno!=pNew->pgno) + ){ + rc = ptrmapPut(pBt, get4byte(pCell), PTRMAP_BTREE, pNew->pgno); + if( rc!=SQLITE_OK ){ + goto balance_cleanup; + } + } +#endif }else if( leafData ){ /* If the tree is a leaf-data tree, and the siblings are leaves, ** then there is no divider cell in apCell[]. Instead, the divider @@ -5436,12 +5475,31 @@ static int balance_nonroot(MemPage *pPage){ j++; nxDiv++; } + +#ifndef SQLITE_OMIT_AUTOVACUUM + /* Set the pointer-map entry for the new sibling page. */ + if( pBt->autoVacuum ){ + rc = ptrmapPut(pBt, pNew->pgno, PTRMAP_BTREE, pParent->pgno); + if( rc!=SQLITE_OK ){ + goto balance_cleanup; + } + } +#endif } assert( j==nCell ); assert( nOld>0 ); assert( nNew>0 ); if( (pageFlags & PTF_LEAF)==0 ){ - memcpy(&apNew[nNew-1]->aData[8], &apCopy[nOld-1]->aData[8], 4); + u8 *zChild = &apCopy[nOld-1]->aData[8]; + memcpy(&apNew[nNew-1]->aData[8], zChild, 4); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + rc = ptrmapPut(pBt, get4byte(zChild), PTRMAP_BTREE, apNew[nNew-1]->pgno); + if( rc!=SQLITE_OK ){ + goto balance_cleanup; + } + } +#endif } if( nxDiv==pParent->nCell+pParent->nOverflow ){ /* Right-most sibling is the right-most child of pParent */ @@ -5456,10 +5514,10 @@ static int balance_nonroot(MemPage *pPage){ ** Reparent children of all cells. */ for(i=0; ipgno, pPage->pgno)); } - rc = reparentChildPages(pPage); + rc = reparentChildPages(pPage, 1); assert( pPage->nOverflow==0 ); #ifndef SQLITE_OMIT_AUTOVACUUM if( pBt->autoVacuum ){ @@ -5645,9 +5703,12 @@ static int balance_deeper(MemPage *pPage){ goto balancedeeper_out; } } + rc = reparentChildPages(pChild, 1); } #endif - rc = balance_nonroot(pChild); + if( rc==SQLITE_OK ){ + rc = balance_nonroot(pChild); + } balancedeeper_out: releasePage(pChild);