mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Improve the performance of balance_nonroot() on auto-vacuum databases by reducing the number of calls to ptrmapPut(). (CVS 5442)
FossilOrigin-Name: 9992b1aecdbbc7a260f00cb6ef78b500aeab22df
This commit is contained in:
14
manifest
14
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Remove\sdead\scode\sfrom\sos_win.c.\s\sTicket\s\s#3232.\s(CVS\s5441)
|
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-18T23:47:43
|
D 2008-07-19T11:49:07
|
||||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||||
F Makefile.in a03f7cb4f7ad50bc53a788c6c544430e81f95de4
|
F Makefile.in a03f7cb4f7ad50bc53a788c6c544430e81f95de4
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@@ -96,7 +96,7 @@ F src/attach.c b18ba42c77f7d3941f5d23d2ca20fa1d841a4e91
|
|||||||
F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
|
F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
|
||||||
F src/bitvec.c 95c86bd18d8fedf0533f5af196192546e10a7e7d
|
F src/bitvec.c 95c86bd18d8fedf0533f5af196192546e10a7e7d
|
||||||
F src/btmutex.c 709cad2cdca0afd013f0f612363810e53f59ec53
|
F src/btmutex.c 709cad2cdca0afd013f0f612363810e53f59ec53
|
||||||
F src/btree.c 770e1b121d1e6c194c836fec2eab6739ebf4d059
|
F src/btree.c 7303414d1afc4c56c8e16eb530fbd902c1243fbc
|
||||||
F src/btree.h 03256ed7ee42b5ecacbe887070b0f8249e7d069d
|
F src/btree.h 03256ed7ee42b5ecacbe887070b0f8249e7d069d
|
||||||
F src/btreeInt.h 6e4cb69a9192a8d609c27034ae5f921cf0ecdde1
|
F src/btreeInt.h 6e4cb69a9192a8d609c27034ae5f921cf0ecdde1
|
||||||
F src/build.c bac7233d984be3805aaa41cf500f7ee12dc97249
|
F src/build.c bac7233d984be3805aaa41cf500f7ee12dc97249
|
||||||
@@ -608,7 +608,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
|
|||||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||||
F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
|
F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
P 5c22132eb171058f30ec5b7562b8164611236748
|
P 5c5c1f72797e4ceb229b8e3a7c65e5f173bb9e1a
|
||||||
R e6e5c52038725d75fcfc314f6d0945ad
|
R b8085ba1aaa9b1c45ae3197480a7b3e3
|
||||||
U drh
|
U danielk1977
|
||||||
Z f2c9fcc16d2a69d031b97db5b7833d47
|
Z bd3b5f822992a4ea7d03ac4968dd7385
|
||||||
|
@@ -1 +1 @@
|
|||||||
5c5c1f72797e4ceb229b8e3a7c65e5f173bb9e1a
|
9992b1aecdbbc7a260f00cb6ef78b500aeab22df
|
103
src/btree.c
103
src/btree.c
@@ -9,7 +9,7 @@
|
|||||||
** May you share freely, never taking more than you give.
|
** 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.
|
** This file implements a external (disk-based) database using BTrees.
|
||||||
** See the header comment on "btreeInt.h" for additional information.
|
** 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
|
** Change the MemPage.pParent pointer on the page whose number is
|
||||||
** given in the second argument so that MemPage.pParent holds the
|
** given in the second argument so that MemPage.pParent holds the
|
||||||
** pointer in the third argument.
|
** 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;
|
MemPage *pThis;
|
||||||
DbPage *pDbPage;
|
DbPage *pDbPage;
|
||||||
|
|
||||||
@@ -4551,9 +4561,22 @@ static int reparentPage(BtShared *pBt, Pgno pgno, MemPage *pNewParent, int idx){
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_AUTOVACUUM
|
#ifndef SQLITE_OMIT_AUTOVACUUM
|
||||||
if( pBt->autoVacuum ){
|
if( pBt->autoVacuum && updatePtrmap ){
|
||||||
return ptrmapPut(pBt, pgno, PTRMAP_BTREE, pNewParent->pgno);
|
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
|
#endif
|
||||||
return SQLITE_OK;
|
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
|
** This routine gets called after you memcpy() one page into
|
||||||
** another.
|
** another.
|
||||||
|
**
|
||||||
|
** If updatePtrmap is true, then the pointer-map entries for all child
|
||||||
|
** pages of pPage are updated.
|
||||||
*/
|
*/
|
||||||
static int reparentChildPages(MemPage *pPage){
|
static int reparentChildPages(MemPage *pPage, int updatePtrmap){
|
||||||
int i;
|
|
||||||
BtShared *pBt = pPage->pBt;
|
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
|
|
||||||
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
|
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; i<pPage->nCell; i++){
|
for(i=0; i<pPage->nCell; i++){
|
||||||
u8 *pCell = findCell(pPage, i);
|
u8 *pCell = findCell(pPage, i);
|
||||||
rc = reparentPage(pBt, get4byte(pCell), pPage, i);
|
rc = reparentPage(pBt, get4byte(pCell), pPage, i, updatePtrmap);
|
||||||
if( rc!=SQLITE_OK ) return rc;
|
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;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5350,17 +5376,20 @@ static int balance_nonroot(MemPage *pPage){
|
|||||||
assert( pNew->nCell>0 || (nNew==1 && cntNew[0]==0) );
|
assert( pNew->nCell>0 || (nNew==1 && cntNew[0]==0) );
|
||||||
assert( pNew->nOverflow==0 );
|
assert( pNew->nOverflow==0 );
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_AUTOVACUUM
|
|
||||||
/* If this is an auto-vacuum database, update the pointer map entries
|
/* If this is an auto-vacuum database, update the pointer map entries
|
||||||
** that point to the siblings that were rearranged. These can be: left
|
** that point to the siblings that were rearranged. These can be: left
|
||||||
** children of cells, the right-child of the page, or overflow pages
|
** children of cells, the right-child of the page, or overflow pages
|
||||||
** pointed to by cells.
|
** pointed to by cells.
|
||||||
*/
|
*/
|
||||||
|
#ifndef SQLITE_OMIT_AUTOVACUUM
|
||||||
if( pBt->autoVacuum ){
|
if( pBt->autoVacuum ){
|
||||||
for(k=j; k<cntNew[i]; k++){
|
for(k=j; k<cntNew[i]; k++){
|
||||||
assert( k<nMaxCells );
|
assert( k<nMaxCells );
|
||||||
if( aFrom[k]==0xFF || apCopy[aFrom[k]]->pgno!=pNew->pgno ){
|
if( aFrom[k]==0xFF || apCopy[aFrom[k]]->pgno!=pNew->pgno ){
|
||||||
rc = ptrmapPutOvfl(pNew, k-j);
|
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 ){
|
if( rc!=SQLITE_OK ){
|
||||||
goto balance_cleanup;
|
goto balance_cleanup;
|
||||||
}
|
}
|
||||||
@@ -5385,6 +5414,16 @@ static int balance_nonroot(MemPage *pPage){
|
|||||||
pTemp = &aSpace2[iSpace2];
|
pTemp = &aSpace2[iSpace2];
|
||||||
if( !pNew->leaf ){
|
if( !pNew->leaf ){
|
||||||
memcpy(&pNew->aData[8], pCell, 4);
|
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 ){
|
}else if( leafData ){
|
||||||
/* If the tree is a leaf-data tree, and the siblings are leaves,
|
/* If the tree is a leaf-data tree, and the siblings are leaves,
|
||||||
** then there is no divider cell in apCell[]. Instead, the divider
|
** then there is no divider cell in apCell[]. Instead, the divider
|
||||||
@@ -5436,12 +5475,31 @@ static int balance_nonroot(MemPage *pPage){
|
|||||||
j++;
|
j++;
|
||||||
nxDiv++;
|
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( j==nCell );
|
||||||
assert( nOld>0 );
|
assert( nOld>0 );
|
||||||
assert( nNew>0 );
|
assert( nNew>0 );
|
||||||
if( (pageFlags & PTF_LEAF)==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 ){
|
if( nxDiv==pParent->nCell+pParent->nOverflow ){
|
||||||
/* Right-most sibling is the right-most child of pParent */
|
/* 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.
|
** Reparent children of all cells.
|
||||||
*/
|
*/
|
||||||
for(i=0; i<nNew; i++){
|
for(i=0; i<nNew; i++){
|
||||||
rc = reparentChildPages(apNew[i]);
|
rc = reparentChildPages(apNew[i], 0);
|
||||||
if( rc!=SQLITE_OK ) goto balance_cleanup;
|
if( rc!=SQLITE_OK ) goto balance_cleanup;
|
||||||
}
|
}
|
||||||
rc = reparentChildPages(pParent);
|
rc = reparentChildPages(pParent, 0);
|
||||||
if( rc!=SQLITE_OK ) goto balance_cleanup;
|
if( rc!=SQLITE_OK ) goto balance_cleanup;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -5567,7 +5625,7 @@ static int balance_shallower(MemPage *pPage){
|
|||||||
TRACE(("BALANCE: transfer child %d into root %d\n",
|
TRACE(("BALANCE: transfer child %d into root %d\n",
|
||||||
pChild->pgno, pPage->pgno));
|
pChild->pgno, pPage->pgno));
|
||||||
}
|
}
|
||||||
rc = reparentChildPages(pPage);
|
rc = reparentChildPages(pPage, 1);
|
||||||
assert( pPage->nOverflow==0 );
|
assert( pPage->nOverflow==0 );
|
||||||
#ifndef SQLITE_OMIT_AUTOVACUUM
|
#ifndef SQLITE_OMIT_AUTOVACUUM
|
||||||
if( pBt->autoVacuum ){
|
if( pBt->autoVacuum ){
|
||||||
@@ -5645,9 +5703,12 @@ static int balance_deeper(MemPage *pPage){
|
|||||||
goto balancedeeper_out;
|
goto balancedeeper_out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
rc = reparentChildPages(pChild, 1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
rc = balance_nonroot(pChild);
|
if( rc==SQLITE_OK ){
|
||||||
|
rc = balance_nonroot(pChild);
|
||||||
|
}
|
||||||
|
|
||||||
balancedeeper_out:
|
balancedeeper_out:
|
||||||
releasePage(pChild);
|
releasePage(pChild);
|
||||||
|
Reference in New Issue
Block a user