]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Consolidate two blocks of similar code in btreeFixUnlocked().
authordan <dan@noemail.net>
Mon, 24 Aug 2015 10:05:03 +0000 (10:05 +0000)
committerdan <dan@noemail.net>
Mon, 24 Aug 2015 10:05:03 +0000 (10:05 +0000)
FossilOrigin-Name: 701302b4bd62ca7aefe643eac096a0ee672a62fa

manifest
manifest.uuid
src/btree.c
test/unlocked3.test

index 06617c4d57577d55d8b80f9c12d7c8ca97f4b6e5..fbf1b207152397c2e254e407393db317f094ffc8 100644 (file)
--- 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
index 9e718e4bc395630acaea5b098f2df326bb0dd254..93c119763033a5d739324b44acf3b8702121decd 100644 (file)
@@ -1 +1 @@
-876810c28b3ad573ae46050ec699ef7eea4e313d
\ No newline at end of file
+701302b4bd62ca7aefe643eac096a0ee672a62fa
\ No newline at end of file
index 53b769720d9f17ac963f34f9f0dc9f164e8dbc01..0b6b1305ae9fc001c60c73968dc5ae2065e90567 100644 (file)
@@ -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 || iNew<iFirst );
+      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);
+      }
+    }
+  }
+  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;
index 9cde0788332b1e0370e05c20861616cb4982363b..61e71c87c34e59c69e0efaee02a10c5a7cf9105a 100644 (file)
@@ -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