-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
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
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
** 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
**
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 */
}
assert( pPager->dbSize==pPager->dbOrigSize );
assert( pPager->dbOrigSize==pPager->dbFileSize );
+ assert( pPager->dbOrigSize==pPager->dbHintSize );
assert( pPager->setMaster==0 );
break;
);
}
assert( pPager->dbOrigSize==pPager->dbFileSize );
+ assert( pPager->dbOrigSize==pPager->dbHintSize );
break;
case PAGER_WRITER_DBMOD:
|| p->journalMode==PAGER_JOURNALMODE_OFF
|| p->journalMode==PAGER_JOURNALMODE_WAL
);
+ assert( pPager->dbOrigSize<=pPager->dbHintSize );
break;
case PAGER_WRITER_FINISHED:
** 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
** 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 ){
}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);
}
** 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;
}