]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add variable pager.dbHintSize, used to limit the number of calls made to the xFileCon...
authordan <dan@noemail.net>
Tue, 10 Aug 2010 09:58:57 +0000 (09:58 +0000)
committerdan <dan@noemail.net>
Tue, 10 Aug 2010 09:58:57 +0000 (09:58 +0000)
FossilOrigin-Name: eb3ac895bd92c880ac6acca58de8cf9643c2b5e4

manifest
manifest.uuid
src/pager.c

index 866a7705bab929f0eff4c3e89abc3f9aa7ed5888..4ff62443c91ed50dabd42726bde5341ddc733800 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Modify\ssome\scomments\sin\spager.c.
-D 2010-08-09T19:17:29
+C Add\svariable\spager.dbHintSize,\sused\sto\slimit\sthe\snumber\sof\scalls\smade\sto\sthe\sxFileControl(FCNTL_SIZE_HINT)\smethod.
+D 2010-08-10T09:58:57
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in ec08dc838fd8110fe24c92e5130bcd91cbb1ff2e
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -156,7 +156,7 @@ F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f
 F src/os_os2.c 72d0b2e562952a2464308c4ce5f7913ac10bef3e
 F src/os_unix.c ae5ca8a6031380708f3fec7be325233d49944914
 F src/os_win.c 51cb62f76262d961ea4249489383d714501315a7
-F src/pager.c df8e60594f095c3bd6b74c7c8a2585655b055536
+F src/pager.c 6e8316c94f4ce46480f7f628c3e819d922af2111
 F src/pager.h 80726162dc3942f59ab27b738fb667b9ba0a89d5
 F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58
 F src/pcache.c 1e9aa2dbc0845b52e1b51cc39753b6d1e041cb07
@@ -843,7 +843,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P aecbd890327dc676d6c2366b07f3d2e636a4983e
-R f5e40f8996c812e7f2b0312f4a214200
+P 5662da6d4f648e5d07d7cbea6bbd92fa684c02c9
+R 016b700a84062c14051dadc45f2eaff7
 U dan
-Z 6addb6181e8f60b5f4d1be2660768d4f
+Z bdf1c4ed8f87e806444ebc6f32ecd642
index 2f79639b12f3547bae68f4ef3bb721732b811b39..4d160d37cb0bd38384c6274ea8e1c0cd8c225a50 100644 (file)
@@ -1 +1 @@
-5662da6d4f648e5d07d7cbea6bbd92fa684c02c9
\ No newline at end of file
+eb3ac895bd92c880ac6acca58de8cf9643c2b5e4
\ No newline at end of file
index 3544032e3d5572f7ab9fd370780884d65449fff2..e2c2f715a31ddb56c1b48a17a9a914b845de28d6 100644 (file)
@@ -565,7 +565,30 @@ struct PagerSavepoint {
 **   Throughout a write-transaction, dbFileSize contains the size of
 **   the file on disk in pages. It is set to a copy of dbSize when the
 **   write-transaction is first opened, and updated when VFS calls are made
-**   to write or truncate the database file on disk.
+**   to write or truncate the database file on disk. 
+**
+**   The only reason the dbFileSize variable is required is to suppress 
+**   unnecessary calls to xTruncate() after committing a transaction. If, 
+**   when a transaction is committed, the dbFileSize variable indicates 
+**   that the database file is larger than the database image (Pager.dbSize), 
+**   pager_truncate() is called. The pager_truncate() call uses xFilesize()
+**   to measure the database file on disk, and then truncates it if required.
+**   dbFileSize is not used when rolling back a transaction. In this case
+**   pager_truncate() is called unconditionally (which means there may be
+**   a call to xFilesize() that is not strictly required). In either case,
+**   pager_truncate() may cause the file to become smaller or larger.
+**
+** dbHintSize
+**
+**   The dbHintSize variable is used to limit the number of calls made to
+**   the VFS xFileControl(FCNTL_SIZE_HINT) method. 
+**
+**   dbHintSize is set to a copy of the dbSize variable when a
+**   write-transaction is opened (at the same time as dbFileSize and
+**   dbOrigSize). If the xFileControl(FCNTL_SIZE_HINT) method is called,
+**   dbHintSize is increased to the number of pages that correspond to the
+**   size-hint passed to the method call. See pager_write_pagelist() for 
+**   details.
 **
 ** errCode
 **
@@ -619,6 +642,7 @@ struct Pager {
   Pgno dbSize;                /* Number of pages in the database */
   Pgno dbOrigSize;            /* dbSize before the current transaction */
   Pgno dbFileSize;            /* Number of pages in the database file */
+  Pgno dbHintSize;            /* Value passed to FCNTL_SIZE_HINT call */
   int errCode;                /* One of several kinds of errors */
   int nRec;                   /* Pages journalled since last j-header written */
   u32 cksumInit;              /* Quasi-random value added to every checksum */
@@ -831,6 +855,7 @@ static int assert_pager_state(Pager *p){
       }
       assert( pPager->dbSize==pPager->dbOrigSize );
       assert( pPager->dbOrigSize==pPager->dbFileSize );
+      assert( pPager->dbOrigSize==pPager->dbHintSize );
       assert( pPager->setMaster==0 );
       break;
 
@@ -850,6 +875,7 @@ static int assert_pager_state(Pager *p){
         );
       }
       assert( pPager->dbOrigSize==pPager->dbFileSize );
+      assert( pPager->dbOrigSize==pPager->dbHintSize );
       break;
 
     case PAGER_WRITER_DBMOD:
@@ -861,6 +887,7 @@ static int assert_pager_state(Pager *p){
            || p->journalMode==PAGER_JOURNALMODE_OFF 
            || p->journalMode==PAGER_JOURNALMODE_WAL 
       );
+      assert( pPager->dbOrigSize<=pPager->dbHintSize );
       break;
 
     case PAGER_WRITER_FINISHED:
@@ -3829,41 +3856,12 @@ static int syncJournal(Pager *pPager, int newHdr){
 ** be obtained, SQLITE_BUSY is returned.
 */
 static int pager_write_pagelist(Pager *pPager, PgHdr *pList){
-  int rc;                              /* Return code */
+  int rc = SQLITE_OK;                  /* Return code */
 
-  /* Normally, this function is called in WRITER_DBMOD state.
-  **
-  ** However it may be called in WRITER_CACHEMOD state if the page being
-  ** written (and all other pages that reside on the same disk sector) was
-  ** a free-list leaf page at the start of the transaction. In that case
-  ** the database file is not really being modified, so it is Ok to write
-  ** to it in CACHEMOD state.
-  */
+  /* This function is only called for rollback pagers in WRITER_DBMOD state. */
   assert( !pagerUseWal(pPager) );
-  assert( pPager->eState==PAGER_WRITER_DBMOD
-       || pPager->eState==PAGER_WRITER_CACHEMOD 
-  );
-  assert( pPager->eState==PAGER_WRITER_DBMOD 
-       || (pList->pDirty==0 && pList->pgno<=pPager->dbFileSize)
-  );
-
-  /* At this point there may be either a RESERVED or EXCLUSIVE lock on the
-  ** database file. If there is already an EXCLUSIVE lock, the following
-  ** call is a no-op.
-  **
-  ** Moving the lock from RESERVED to EXCLUSIVE actually involves going
-  ** through an intermediate state PENDING.   A PENDING lock prevents new
-  ** readers from attaching to the database but is unsufficient for us to
-  ** write.  The idea of a PENDING lock is to prevent new readers from
-  ** coming in while we wait for existing readers to clear.
-  **
-  ** While the pager is in the RESERVED state, the original database file
-  ** is unchanged and we can rollback without having to playback the
-  ** journal into the original database file.  Once we transition to
-  ** EXCLUSIVE, it means the database file has been changed and any rollback
-  ** will require a journal playback.
-  */
-  rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
+  assert( pPager->eState==PAGER_WRITER_DBMOD );
+  assert( pPager->eLock==EXCLUSIVE_LOCK );
 
   /* If the file is a temp-file has not yet been opened, open it now. It
   ** is not possible for rc to be other than SQLITE_OK if this branch
@@ -3878,9 +3876,10 @@ static int pager_write_pagelist(Pager *pPager, PgHdr *pList){
   ** file size will be.
   */
   assert( rc!=SQLITE_OK || isOpen(pPager->fd) );
-  if( rc==SQLITE_OK && pPager->dbSize>pPager->dbOrigSize ){
+  if( rc==SQLITE_OK && pPager->dbSize>pPager->dbHintSize ){
     sqlite3_int64 szFile = pPager->pageSize * (sqlite3_int64)pPager->dbSize;
     sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &szFile);
+    pPager->dbHintSize = pPager->dbSize;
   }
 
   while( rc==SQLITE_OK && pList ){
@@ -4062,7 +4061,9 @@ static int pagerStress(void *p, PgHdr *pPg){
   }else{
   
     /* Sync the journal file if required. */
-    if( pPg->flags&PGHDR_NEED_SYNC ){
+    if( pPg->flags&PGHDR_NEED_SYNC 
+     || pPager->eState==PAGER_WRITER_CACHEMOD
+    ){
       rc = syncJournal(pPager, 1);
     }
   
@@ -5124,7 +5125,9 @@ int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory){
       ** WAL mode.
       */
       pPager->eState = PAGER_WRITER_LOCKED;
-      pPager->dbFileSize = pPager->dbOrigSize = pPager->dbSize;
+      pPager->dbHintSize = pPager->dbSize;
+      pPager->dbFileSize = pPager->dbSize;
+      pPager->dbOrigSize = pPager->dbSize;
       pPager->journalOff = 0;
     }