]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Experimental changes that cause SQLite to use bytes 28..31 of the database
authordrh <drh@noemail.net>
Sat, 27 Mar 2010 17:12:36 +0000 (17:12 +0000)
committerdrh <drh@noemail.net>
Sat, 27 Mar 2010 17:12:36 +0000 (17:12 +0000)
header to determine the database size, rather than using the actual database
size.  This allows database space to be preallocated.

FossilOrigin-Name: b844ac6fcb72595a71e5c5283ec461309a87ba79

manifest
manifest.uuid
src/btree.c
src/btreeInt.h
src/pager.c
test/corrupt2.test
test/pragma.test

index 233eb87ec31b43f029f524d7396f1f5686335517..6bc092dab161d68c85f727b0f3ae042b2114406f 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,8 @@
-C Increase\sthe\sestimated\scost\sof\susing\sa\svirtual\stable\sas\sthe\souter\sloop\sof\sa\sjoin\swhen\sthere\sexists\san\sORDER\sBY\sclause\sthat\sis\snot\ssatisfied\sby\sthe\svirtual\stable.\sFix\sfor\s[775b39dd3c].
-D 2010-03-27T09:44:42
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+
+C Experimental\schanges\sthat\scause\sSQLite\sto\suse\sbytes\s28..31\sof\sthe\sdatabase\nheader\sto\sdetermine\sthe\sdatabase\ssize,\srather\sthan\susing\sthe\sactual\sdatabase\nsize.\s\sThis\sallows\sdatabase\sspace\sto\sbe\spreallocated.
+D 2010-03-27T17:12:36
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in 4f2f967b7e58a35bb74fb7ec8ae90e0f4ca7868b
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -109,9 +112,9 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
 F src/backup.c b293534bc2df23c57668a585b17ee7faaaef0939
 F src/bitvec.c 06ad2c36a9c3819c0b9cbffec7b15f58d5d834e0
 F src/btmutex.c 96a12f50f7a17475155971a241d85ec5171573ff
-F src/btree.c 0d6e44d664b1775b269ea7e6f66fdffcfc32ceb3
+F src/btree.c 28c3975060209dc5c5ca91abaa5e034dab03539f
 F src/btree.h 0e193b7e90f1d78b79c79474040e3d66a553a4fa
-F src/btreeInt.h 71ed5e7f009caf17b7dc304350b3cb64b5970135
+F src/btreeInt.h 132d750db5d86b75344cec870501fa09a67b1f96
 F src/build.c 11100b66fb97638d2d874c1d34d8db90650bb1d7
 F src/callback.c 908f3e0172c3d4058f4ca0acd42c637c52e9669f
 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
@@ -152,7 +155,7 @@ F src/os_common.h 240c88b163b02c21a9f21f87d49678a0aa21ff30
 F src/os_os2.c 75a8c7b9a00a2cf1a65f9fa4afbc27d46634bb2f
 F src/os_unix.c 148d2f625db3727250c0b880481ae7630b6d0eb0
 F src/os_win.c 1c7453c2df4dab26d90ff6f91272aea18bcf7053
-F src/pager.c 2a374f72e6c87150d043173b8041dc537f926b02
+F src/pager.c af1c58b7b884839853cc553681f771297de56049
 F src/pager.h ef8a2cf10084f60ab45ee2dfded8bf8b0c655ddf
 F src/parse.y ace5c7a125d9f2a410e431ee3209034105045f7e
 F src/pcache.c ace8f6a5ecd4711cc66a1b23053be7109bd437cf
@@ -293,7 +296,7 @@ F test/colmeta.test 087c42997754b8c648819832241daf724f813322
 F test/colname.test 08948a4809d22817e0e5de89c7c0a8bd90cb551b
 F test/conflict.test 0ed68b11f22721052d880ee80bd528a0e0828236
 F test/corrupt.test 0d346c9fe064ca71281685a8a732fcc83461bb99
-F test/corrupt2.test a571e30ea4e82318f319a24b6cc55935ce862079
+F test/corrupt2.test 576122d756feda40e63ef1c1ff6c4720a927d126
 F test/corrupt3.test 263e8bb04e2728df832fddf6973cf54c91db0c32
 F test/corrupt4.test acdb01afaedf529004b70e55de1a6f5a05ae7fff
 F test/corrupt5.test c23da7bfb20917cc7fdbb13ee25c7cc4e9fffeff
@@ -528,7 +531,7 @@ F test/pagesize.test 76aa9f23ecb0741a4ed9d2e16c5fa82671f28efb
 F test/pcache.test eebc4420b37cb07733ae9b6e99c9da7c40dd6d58
 F test/pcache2.test 0d85f2ab6963aee28c671d4c71bec038c00a1d16
 F test/permutations.test 91928573ca2db2c88dbc50ab34e4a585d912b580
-F test/pragma.test 5aeb48a442dba3c3e8e38773b121371814ab3b17
+F test/pragma.test 6960f9efbce476f70ba9ee2171daf5042f9e3d8a
 F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47
 F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea
 F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301
@@ -794,7 +797,18 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P c33b38b59f733494ca0bce3f59a669fe7ed76b9f
-R 1048b4f005b8cf985bff319e6cd284fa
-U dan
-Z 25a9f1889e9ba9dd674533c69390c60b
+P 9e075e70f0e2a1ad302d17150cd58f91669a97a6
+R 8d4f88bef4d5dad0eb6446592a8450b9
+T *bgcolor * #c0ffc0
+T *branch * experimental
+T *sym-experimental *
+T -sym-trunk *
+U drh
+Z 4146840317f4bfa6058f588cd6ed7701
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.4.6 (GNU/Linux)
+
+iD8DBQFLrjyHoxKgR168RlERArtLAKCJtnFICZRpFQj18diXIg+u0uOi3ACgh4j0
+mhbXREy6ig+7NdEp5dlms38=
+=ITwY
+-----END PGP SIGNATURE-----
index cefdd79cc524fb8f1fc4d871878125a95dace220..35e921ca955251b7d52cffde1f8f53e1318c0e9e 100644 (file)
@@ -1 +1 @@
-9e075e70f0e2a1ad302d17150cd58f91669a97a6
\ No newline at end of file
+b844ac6fcb72595a71e5c5283ec461309a87ba79
\ No newline at end of file
index dbcdf65ec86b24f8e866637a6cb97a55ca41f041..b8c41674a285d655fe4b937deed710f758493ba8 100644 (file)
@@ -516,11 +516,8 @@ static void invalidateIncrblobCursors(
 static int btreeSetHasContent(BtShared *pBt, Pgno pgno){
   int rc = SQLITE_OK;
   if( !pBt->pHasContent ){
-    int nPage = 100;
-    sqlite3PagerPagecount(pBt->pPager, &nPage);
-    /* If sqlite3PagerPagecount() fails there is no harm because the
-    ** nPage variable is unchanged from its default value of 100 */
-    pBt->pHasContent = sqlite3BitvecCreate((u32)nPage);
+    assert( pgno<=pBt->nPage );
+    pBt->pHasContent = sqlite3BitvecCreate(pBt->nPage);
     if( !pBt->pHasContent ){
       rc = SQLITE_NOMEM;
     }
@@ -1564,12 +1561,8 @@ static MemPage *btreePageLookup(BtShared *pBt, Pgno pgno){
 ** error, return ((unsigned int)-1).
 */
 static Pgno pagerPagecount(BtShared *pBt){
-  int nPage = -1;
-  int rc;
-  assert( pBt->pPage1 );
-  rc = sqlite3PagerPagecount(pBt->pPager, &nPage);
-  assert( rc==SQLITE_OK || nPage==-1 );
-  return (Pgno)nPage;
+  int nPage = (int)pBt->nPage;
+  return nPage;
 }
 
 /*
@@ -2254,8 +2247,8 @@ static int lockBtree(BtShared *pBt){
   /* Do some checking to help insure the file we opened really is
   ** a valid database file. 
   */
-  rc = sqlite3PagerPagecount(pBt->pPager, &nPage);
-  if( rc!=SQLITE_OK ){
+  nPage = get4byte(28+(u8*)pPage1->aData);
+  if( nPage==0 && (rc = sqlite3PagerPagecount(pBt->pPager, &nPage))!=0 ){
     goto page1_init_failed;
   }else if( nPage>0 ){
     int pageSize;
@@ -2333,6 +2326,7 @@ static int lockBtree(BtShared *pBt){
   pBt->minLeaf = (pBt->usableSize-12)*32/255 - 23;
   assert( pBt->maxLeaf + 23 <= MX_CELL_SIZE(pBt) );
   pBt->pPage1 = pPage1;
+  pBt->nPage = nPage;
   return SQLITE_OK;
 
 page1_init_failed:
@@ -2370,12 +2364,10 @@ static int newDatabase(BtShared *pBt){
   MemPage *pP1;
   unsigned char *data;
   int rc;
-  int nPage;
 
   assert( sqlite3_mutex_held(pBt->mutex) );
-  rc = sqlite3PagerPagecount(pBt->pPager, &nPage);
-  if( rc!=SQLITE_OK || nPage>0 ){
-    return rc;
+  if( pBt->nPage>0 ){
+    return SQLITE_OK;
   }
   pP1 = pBt->pPage1;
   assert( pP1!=0 );
@@ -2401,6 +2393,8 @@ static int newDatabase(BtShared *pBt){
   put4byte(&data[36 + 4*4], pBt->autoVacuum);
   put4byte(&data[36 + 7*4], pBt->incrVacuum);
 #endif
+  pBt->nPage = 1;
+  data[31] = 1;
   return SQLITE_OK;
 }
 
@@ -2769,12 +2763,12 @@ static int allocateBtreePage(BtShared *, MemPage **, Pgno *, Pgno, u8);
 */
 static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg){
   Pgno nFreeList;           /* Number of pages still on the free-list */
+  int rc;
 
   assert( sqlite3_mutex_held(pBt->mutex) );
   assert( iLastPg>nFin );
 
   if( !PTRMAP_ISPAGE(pBt, iLastPg) && iLastPg!=PENDING_BYTE_PAGE(pBt) ){
-    int rc;
     u8 eType;
     Pgno iPtrPage;
 
@@ -2850,7 +2844,7 @@ static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg){
     while( iLastPg==PENDING_BYTE_PAGE(pBt)||PTRMAP_ISPAGE(pBt, iLastPg) ){
       if( PTRMAP_ISPAGE(pBt, iLastPg) ){
         MemPage *pPg;
-        int rc = btreeGetPage(pBt, iLastPg, &pPg, 0);
+        rc = btreeGetPage(pBt, iLastPg, &pPg, 0);
         if( rc!=SQLITE_OK ){
           return rc;
         }
@@ -2863,6 +2857,7 @@ static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg){
       iLastPg--;
     }
     sqlite3PagerTruncateImage(pBt->pPager, iLastPg);
+    pBt->nPage = iLastPg;
   }
   return SQLITE_OK;
 }
@@ -2886,6 +2881,10 @@ int sqlite3BtreeIncrVacuum(Btree *p){
   }else{
     invalidateAllOverflowCache(pBt);
     rc = incrVacuumStep(pBt, 0, pagerPagecount(pBt));
+    if( rc==SQLITE_OK ){
+      rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
+      put4byte(&pBt->pPage1->aData[28], pBt->nPage);
+    }
   }
   sqlite3BtreeLeave(p);
   return rc;
@@ -2941,11 +2940,12 @@ static int autoVacuumCommit(BtShared *pBt){
       rc = incrVacuumStep(pBt, nFin, iFree);
     }
     if( (rc==SQLITE_DONE || rc==SQLITE_OK) && nFree>0 ){
-      rc = SQLITE_OK;
       rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
       put4byte(&pBt->pPage1->aData[32], 0);
       put4byte(&pBt->pPage1->aData[36], 0);
+      put4byte(&pBt->pPage1->aData[28], nFin);
       sqlite3PagerTruncateImage(pBt->pPager, nFin);
+      pBt->nPage = nFin;
     }
     if( rc!=SQLITE_OK ){
       sqlite3PagerRollback(pPager);
@@ -3269,6 +3269,7 @@ int sqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){
     rc = sqlite3PagerSavepoint(pBt->pPager, op, iSavepoint);
     if( rc==SQLITE_OK ){
       rc = newDatabase(pBt);
+      pBt->nPage = get4byte(28 + pBt->pPage1->aData);
     }
     sqlite3BtreeLeave(p);
   }
@@ -4833,32 +4834,32 @@ static int allocateBtreePage(
   }else{
     /* There are no pages on the freelist, so create a new page at the
     ** end of the file */
-    int nPage = pagerPagecount(pBt);
-    *pPgno = nPage + 1;
-
-    if( *pPgno==PENDING_BYTE_PAGE(pBt) ){
-      (*pPgno)++;
-    }
+    rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
+    if( rc ) return rc;
+    pBt->nPage++;
+    if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ) pBt->nPage++;
 
 #ifndef SQLITE_OMIT_AUTOVACUUM
-    if( pBt->autoVacuum && PTRMAP_ISPAGE(pBt, *pPgno) ){
+    if( pBt->autoVacuum && PTRMAP_ISPAGE(pBt, pBt->nPage) ){
       /* If *pPgno refers to a pointer-map page, allocate two new pages
       ** at the end of the file instead of one. The first allocated page
       ** becomes a new pointer-map page, the second is used by the caller.
       */
       MemPage *pPg = 0;
-      TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", *pPgno));
-      assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
-      rc = btreeGetPage(pBt, *pPgno, &pPg, 0);
+      TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", pBt->nPage));
+      assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) );
+      rc = btreeGetPage(pBt, pBt->nPage, &pPg, 0);
       if( rc==SQLITE_OK ){
         rc = sqlite3PagerWrite(pPg->pDbPage);
         releasePage(pPg);
       }
       if( rc ) return rc;
-      (*pPgno)++;
-      if( *pPgno==PENDING_BYTE_PAGE(pBt) ){ (*pPgno)++; }
+      pBt->nPage++;
+      if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ){ pBt->nPage++; }
     }
 #endif
+    put4byte(28 + (u8*)pBt->pPage1->aData, pBt->nPage);
+    *pPgno = pBt->nPage;
 
     assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
     rc = btreeGetPage(pBt, *pPgno, ppPage, 0);
index f6d95e5047d0cf1e778d2cc6637ffa577d19de3c..ddb8e932e4616d44cc139da3b74024e4e23a12dc 100644 (file)
@@ -420,6 +420,7 @@ struct BtShared {
   u16 minLeaf;          /* Minimum local payload in a LEAFDATA table */
   u8 inTransaction;     /* Transaction state */
   int nTransaction;     /* Number of open transactions (read + write) */
+  u32 nPage;            /* Number of pages in the database */
   void *pSchema;        /* Pointer to space allocated by sqlite3BtreeSchema() */
   void (*xFreeSchema)(void*);  /* Destructor for BtShared.pSchema */
   sqlite3_mutex *mutex; /* Non-recursive mutex required to access this struct */
index 56becfcec24f6a91ef5ae604d1c6f8e54c744956..ced997b4e241b32ac4c418d4f11aaf91be611088 100644 (file)
@@ -4156,10 +4156,10 @@ static int pager_write(PgHdr *pPg){
   */
   assert( pPager->state>=PAGER_RESERVED );
 
-  /* If an error has been previously detected, we should not be
-  ** calling this routine.  Repeat the error for robustness.
+  /* If an error has been previously detected, report the same error
+  ** again.
   */
-  if( NEVER(pPager->errCode) )  return pPager->errCode;
+  if( pPager->errCode )  return pPager->errCode;
 
   /* Higher-level routines never call this function if database is not
   ** writable.  But check anyway, just for robustness. */
@@ -4489,10 +4489,6 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){
       change_counter++;
       put32bits(((char*)pPgHdr->pData)+24, change_counter);
 
-      /* Also store the current database size in bytes 28..31 */
-      assert( pPager->dbSizeValid );
-      put32bits(((char*)pPgHdr->pData)+28, pPager->dbSize);
-
       /* Also store the SQLite version number in bytes 96..99 */
       assert( pPager->dbSizeValid );
       put32bits(((char*)pPgHdr->pData)+96, SQLITE_VERSION_NUMBER);
@@ -4570,10 +4566,8 @@ int sqlite3PagerCommitPhaseOne(
   /* The dbOrigSize is never set if journal_mode=OFF */
   assert( pPager->journalMode!=PAGER_JOURNALMODE_OFF || pPager->dbOrigSize==0 );
 
-  /* If a prior error occurred, this routine should not be called.  ROLLBACK
-  ** is the appropriate response to an error, not COMMIT.  Guard against
-  ** coding errors by repeating the prior error. */
-  if( NEVER(pPager->errCode) ) return pPager->errCode;
+  /* If a prior error occurred, report that error again. */
+  if( pPager->errCode ) return pPager->errCode;
 
   PAGERTRACE(("DATABASE SYNC: File=%s zMaster=%s nSize=%d\n", 
       pPager->zFilename, zMaster, pPager->dbSize));
@@ -4925,6 +4919,9 @@ int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){
     int ii;                                 /* Iterator variable */
     PagerSavepoint *aNew;                   /* New Pager.aSavepoint array */
 
+    rc = sqlite3PagerPagecount(pPager, 0);
+    if( rc ) return rc;
+
     /* Grow the Pager.aSavepoint array using realloc(). Return SQLITE_NOMEM
     ** if the allocation fails. Otherwise, zero the new portion in case a 
     ** malloc failure occurs while populating it in the for(...) loop below.
index acda25436d8a3c4c204e107cb2d5c52b262f14af..12437c72a22f793eb8ef5fcd13ae995394250ca0 100644 (file)
@@ -334,6 +334,7 @@ ifcapable autovacuum {
     seek $fd 0 end
     puts -nonewline $fd [string repeat x $nAppend]
     close $fd
+    hexio_write corrupt.db 28 00000000
   } -test {
     do_test corrupt2-6.4 {
       catchsql { 
@@ -522,6 +523,7 @@ ifcapable autovacuum {
       file size corrupt.db
     } $::sqlite_pending_byte
     hexio_write corrupt.db [expr $::sqlite_pending_byte+1023] 00
+    hexio_write corrupt.db 28 00000000
   } -test {
     do_test corrupt2-13.2 {
       file size corrupt.db
index 46f7d6d516d26207a9774afe087641f6a3c95086..380a59e7072418bb90a42104d13a6b64fb184226 100644 (file)
@@ -317,6 +317,7 @@ ifcapable attach {
       puts -nonewline $out [read $in]
       close $in
       close $out
+      hexio_write testerr.db 28 00000000
       execsql {REINDEX t2}
       execsql {PRAGMA integrity_check}
     } {ok}