From: dan Date: Mon, 24 Aug 2015 10:05:03 +0000 (+0000) Subject: Consolidate two blocks of similar code in btreeFixUnlocked(). X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5cf03728a6d33823bb55cbab69f5e4b415e4d1ae;p=thirdparty%2Fsqlite.git Consolidate two blocks of similar code in btreeFixUnlocked(). FossilOrigin-Name: 701302b4bd62ca7aefe643eac096a0ee672a62fa --- diff --git a/manifest b/manifest index 06617c4d57..fbf1b20715 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\strunk\schanges\swith\sthis\sbranch. -D 2015-08-24T06:44:17.840 +C Consolidate\stwo\sblocks\sof\ssimilar\scode\sin\sbtreeFixUnlocked(). +D 2015-08-24T10:05:03.012 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e2218eb228374422969de7b1680eda6864affcef F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -279,7 +279,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 4d9134dc988a87838c06056c89c0e8c4700a0452 F src/bitvec.c d1f21d7d91690747881f03940584f4cc548c9d3d F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79 -F src/btree.c 245bc696824d5107f3570905325c6ac5b05c18f8 +F src/btree.c e807409602996359211c855078fa5cbcf59da032 F src/btree.h 00d4cdb747c4172a5566faf037116985dbbc377e F src/btreeInt.h 0c19847f87ab82e4f5e67750a069f10829475da6 F src/build.c e47b6fffe14a28d9050e6747beebb01597d37542 @@ -1229,7 +1229,7 @@ F test/unique2.test 41e7f83c6827605991160a31380148a9fc5f1339 F test/unixexcl.test cd6c765f75e50e8e2c2ba763149e5d340ea19825 F test/unlocked.test d143a871bd874311d4e5c98ce458218ca6b579fd F test/unlocked2.test aaa42a08052a146466220b6c3a062ff3c4776ad6 -F test/unlocked3.test 1bc4e3ad8693302639e50b4833a527807ee4863b +F test/unlocked3.test 2cacc31742561f6924706ed9472d0095839da9e4 F test/unordered.test ca7adce0419e4ca0c50f039885e76ed2c531eda8 F test/update.test 6c68446b8a0a33d522a7c72b320934596a2d7d32 F test/uri.test 23662b7b61958b0f0e47082de7d06341ccf85d5b @@ -1381,7 +1381,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 4460764ea8fc948fe02f0a09476857839b3aa1ae f0aba0e120074430cd7ad93291fcc97b8a25a054 -R c9a4c2c74a91d952dffb223e6caf31f7 +P 876810c28b3ad573ae46050ec699ef7eea4e313d +R 11d77b8f4d3f6d9b5ad54020bb4092ee U dan -Z 9a4849fb712895f27dbf139db01b2763 +Z 46d9657b2162cb9e544c380eb188ec18 diff --git a/manifest.uuid b/manifest.uuid index 9e718e4bc3..93c1197630 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -876810c28b3ad573ae46050ec699ef7eea4e313d \ No newline at end of file +701302b4bd62ca7aefe643eac096a0ee672a62fa \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 53b769720d..0b6b1305ae 100644 --- a/src/btree.c +++ b/src/btree.c @@ -3847,6 +3847,73 @@ static int autoVacuumCommit(BtShared *pBt){ #endif #ifdef SQLITE_ENABLE_UNLOCKED +/* +** This function is called as part of merging an UNLOCKED transaction with +** the snapshot at the head of the wal file. It relocates all pages in the +** range iFirst..iLast, inclusive. It is assumed that the BtreePtrmap +** structure at BtShared.pMap contains the location of the pointers to each +** page in the range. +** +** If pnCurrent is NULL, then all pages in the range are moved to currently +** free locations (i.e. free-list entries) within the database file before page +** iFirst. +** +** Or, if pnCurrent is not NULL, then it points to a value containing the +** current size of the database file in pages. In this case, all pages are +** relocated to the end of the database file - page iFirst is relocated to +** page (*pnCurrent+1), page iFirst+1 to page (*pnCurrent+2), and so on. +** Value *pnCurrent is set to the new size of the database before this +** function returns. +** +** If no error occurs, SQLITE_OK is returned. Otherwise, an SQLite error code. +*/ +static int btreeRelocateRange( + BtShared *pBt, /* B-tree handle */ + Pgno iFirst, /* First page to relocate */ + Pgno iLast, /* Last page to relocate */ + Pgno *pnCurrent /* If not NULL, IN/OUT: Database size */ +){ + int rc = SQLITE_OK; + BtreePtrmap *pMap = pBt->pMap; + Pgno iPg; + + for(iPg=iFirst; iPg<=iLast && rc==SQLITE_OK; iPg++){ + MemPage *pFree = 0; /* Page allocated from free-list */ + MemPage *pPg = 0; + Pgno iNew; /* New page number for pPg */ + PtrmapEntry *pEntry; /* Pointer map entry for page iPg */ + + if( iPg==PENDING_BYTE_PAGE(pBt) ) continue; + pEntry = &pMap->aPtr[iPg - pMap->iFirst]; + + if( pEntry->eType==PTRMAP_FREEPAGE ){ + Pgno dummy; + rc = allocateBtreePage(pBt, &pFree, &dummy, iPg, BTALLOC_EXACT); + releasePage(pFree); + assert( rc!=SQLITE_OK || dummy==iPg ); + }else if( pnCurrent ){ + btreeGetPage(pBt, iPg, &pPg, 0); + assert( sqlite3PagerIswriteable(pPg->pDbPage) ); + assert( sqlite3PagerPageRefcount(pPg->pDbPage)==1 ); + iNew = ++(*pnCurrent); + if( iNew==PENDING_BYTE_PAGE(pBt) ) iNew = ++(*pnCurrent); + rc = relocatePage(pBt, pPg, pEntry->eType, pEntry->parent, iNew, 1); + releasePageNotNull(pPg); + }else{ + rc = allocateBtreePage(pBt, &pFree, &iNew, iFirst-1, BTALLOC_LE); + assert( rc!=SQLITE_OK || iNeweType, pEntry->parent,iNew,1); + releasePage(pPg); + } + } + } + return rc; +} + /* ** The b-tree handle passed as the only argument is about to commit an ** UNLOCKED transaction. At this point it is guaranteed that this is @@ -3875,7 +3942,7 @@ static int btreeFixUnlocked(Btree *p){ if( rc==SQLITE_OK ){ Pgno nHPage = get4byte(&p1[28]); - Pgno nFinal = nHPage; /* Size of db after transaction merge */ + Pgno nFin = nHPage; /* Size of db after transaction merge */ if( sqlite3PagerIswriteable(pPage1->pDbPage) ){ Pgno iHTrunk = get4byte(&p1[32]); @@ -3907,71 +3974,32 @@ static int btreeFixUnlocked(Btree *p){ /* The current transaction allocated pages pMap->iFirst through ** nPage (inclusive) at the end of the database file. Meanwhile, ** other transactions have allocated (iFirst..nHPage). So move - ** pages (iFirst..MIN(nPage,nHPage)) to (MAX(nPage,nHPage)+1). - */ + ** pages (iFirst..MIN(nPage,nHPage)) to (MAX(nPage,nHPage)+1). */ Pgno iLast = MIN(nPage, nHPage); /* Last page to move */ - Pgno iPg; Pgno nCurrent; /* Current size of db */ nCurrent = MAX(nPage, nHPage); + rc = btreeRelocateRange(pBt, pMap->iFirst, iLast, &nCurrent); - for(iPg=pMap->iFirst; iPg<=iLast && rc==SQLITE_OK; iPg++){ - MemPage *pPg = 0; - Pgno iNew; /* New page number for pPg */ - PtrmapEntry *pEntry; /* Pointer map entry for page iPg */ - - if( iPg==PENDING_BYTE_PAGE(pBt) ) continue; - pEntry = &pMap->aPtr[iPg - pMap->iFirst]; - if( pEntry->eType==PTRMAP_FREEPAGE ){ - MemPage *pFree = 0; - Pgno dummy; - rc = allocateBtreePage(pBt, &pFree, &dummy, iPg, BTALLOC_EXACT); - releasePage(pFree); - assert( rc!=SQLITE_OK || dummy==iPg ); - }else{ - btreeGetPage(pBt, iPg, &pPg, 0); - assert( sqlite3PagerIswriteable(pPg->pDbPage) ); - assert( sqlite3PagerPageRefcount(pPg->pDbPage)==1 ); - iNew = ++nCurrent; - if( iNew==PENDING_BYTE_PAGE(pBt) ) iNew = ++nCurrent; - rc = relocatePage(pBt, pPg, pEntry->eType, pEntry->parent, iNew, 1); - releasePageNotNull(pPg); + /* There are now no collisions with the snapshot at the head of the + ** database file. So at this point it would be possible to write + ** the transaction out to disk. Before doing so though, attempt to + ** relocate some of the new pages to free locations within the body + ** of the database file (i.e. free-list entries). */ + if( rc==SQLITE_OK ){ + assert( nCurrent!=PENDING_BYTE_PAGE(pBt) ); + sqlite3PagerSetDbsize(pBt->pPager, nCurrent); + nFree = get4byte(&p1[36]); + nFin = MAX(nCurrent-nFree, nHPage); + if( nCurrent>PENDING_BYTE_PAGE(pBt) && nFin<=PENDING_BYTE_PAGE(pBt) ){ + nFin--; } - } - sqlite3PagerSetDbsize(pPager, nCurrent); - assert( nCurrent!=PENDING_BYTE_PAGE(pBt) ); - - nFree = get4byte(&p1[36]); - nFinal = MAX(nCurrent-nFree, nHPage); - if( nCurrent>PENDING_BYTE_PAGE(pBt) && nFinal<=PENDING_BYTE_PAGE(pBt) ){ - nFinal--; + rc = btreeRelocateRange(pBt, nFin+1, nCurrent, 0); } - for(iPg=nFinal+1; rc==SQLITE_OK && iPg<=nCurrent; iPg++){ - Pgno iNew; /* New page number for pPg */ - MemPage *pFree; - PtrmapEntry *pEntry; /* Pointer map entry for page iPg */ - - if( iPg==PENDING_BYTE_PAGE(pBt) ) continue; - pEntry = &pMap->aPtr[iPg - pMap->iFirst]; - if( pEntry->eType==PTRMAP_FREEPAGE ){ - rc = allocateBtreePage(pBt, &pFree, &iNew, iPg, BTALLOC_EXACT); - releasePage(pFree); - }else{ - rc = allocateBtreePage(pBt, &pFree, &iNew, nFinal, BTALLOC_LE); - assert( rc!=SQLITE_OK || iNew<=nFinal ); - releasePage(pFree); - if( rc==SQLITE_OK ){ - MemPage *pPg = 0; - btreeGetPage(pBt, iPg, &pPg, 0); - rc = relocatePage(pBt, pPg, pEntry->eType, pEntry->parent,iNew,1); - releasePage(pPg); - } - } - } - put4byte(&p1[28], nFinal); + put4byte(&p1[28], nFin); } } - sqlite3PagerSetDbsize(pPager, nFinal); + sqlite3PagerSetDbsize(pPager, nFin); } return rc; diff --git a/test/unlocked3.test b/test/unlocked3.test index 9cde078833..61e71c87c3 100644 --- a/test/unlocked3.test +++ b/test/unlocked3.test @@ -84,17 +84,19 @@ set DBLIST {db1 db2 db3 db4} create_schema foreach {tn oplist} { - 1 {1i 2i 3i 4i} - 2 {1iii 2iii 3iii 4iii} - 3 {1d 2d 3d 4d} - . ----------------------- - 4 {1i} - 5 {1d 2i} - . ----------------------- - 6 {1iii 2iii 3iii 4iii} - 7 {1di 2id 3iii 4ddd} - 8 {1iii 2iii 3iii 4iii} - 9 {1D 2II} + 1 {1i 2i 3i 4i} + 2 {1iii 2iii 3iii 4iii} + 3 {1d 2d 3d 4d} + . ----------------------- + 4 {1i} + 5 {1d 2i} + . ----------------------- + 6 {1iii 2iii 3iii 4iii} + 7 {1di 2id 3iii 4ddd} + 8 {1iii 2iii 3iii 4iii} + 9 {1D 2II} + 10 {1I 2D 3I 4D} + 11 {1III 3dddddd 4III} } { if {[string range $oplist 0 0]=="-"} { reset_db