1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Combine subjRequiresPage() and subjournalPage() into a single

subjournalPageIfRequired() routine.

FossilOrigin-Name: 3b65eb56c422855ca47f709247205f0c77d98a5c
This commit is contained in:
drh
2015-06-29 19:08:18 +00:00
parent 1aacbdb374
commit 60e32edba5
3 changed files with 19 additions and 50 deletions

View File

@@ -4320,8 +4320,6 @@ static int openSubJournal(Pager *pPager){
/*
** Append a record of the current state of page pPg to the sub-journal.
** It is the callers responsibility to use subjRequiresPage() to check
** that it is really required before calling this function.
**
** If successful, set the bit corresponding to pPg->pgno in the bitvecs
** for all open savepoints before returning.
@@ -4368,6 +4366,13 @@ static int subjournalPage(PgHdr *pPg){
}
return rc;
}
static int subjournalPageIfRequired(PgHdr *pPg){
if( subjRequiresPage(pPg) ){
return subjournalPage(pPg);
}else{
return SQLITE_OK;
}
}
/*
** This function is called by the pcache layer when it has reached some
@@ -4425,9 +4430,7 @@ static int pagerStress(void *p, PgHdr *pPg){
pPg->pDirty = 0;
if( pagerUseWal(pPager) ){
/* Write a single frame for this page to the log. */
if( subjRequiresPage(pPg) ){
rc = subjournalPage(pPg);
}
rc = subjournalPageIfRequired(pPg);
if( rc==SQLITE_OK ){
rc = pagerWalFrames(pPager, pPg, 0, 0);
}
@@ -4440,39 +4443,6 @@ static int pagerStress(void *p, PgHdr *pPg){
rc = syncJournal(pPager, 1);
}
/* If the page number of this page is larger than the current size of
** the database image, it may need to be written to the sub-journal.
** This is because the call to pager_write_pagelist() below will not
** actually write data to the file in this case.
**
** Consider the following sequence of events:
**
** BEGIN;
** <journal page X>
** <modify page X>
** SAVEPOINT sp;
** <shrink database file to Y pages>
** pagerStress(page X)
** ROLLBACK TO sp;
**
** If (X>Y), then when pagerStress is called page X will not be written
** out to the database file, but will be dropped from the cache. Then,
** following the "ROLLBACK TO sp" statement, reading page X will read
** data from the database file. This will be the copy of page X as it
** was when the transaction started, not as it was when "SAVEPOINT sp"
** was executed.
**
** The solution is to write the current data for page X into the
** sub-journal file now (if it is not already there), so that it will
** be restored to its current value when the "ROLLBACK TO sp" is
** executed.
*/
if( NEVER(
rc==SQLITE_OK && pPg->pgno>pPager->dbSize && subjRequiresPage(pPg)
) ){
rc = subjournalPage(pPg);
}
/* Write the contents of the page out to the database file. */
if( rc==SQLITE_OK ){
assert( (pPg->flags&PGHDR_NEED_SYNC)==0 );
@@ -5781,8 +5751,8 @@ static int pager_write(PgHdr *pPg){
/* If the statement journal is open and the page is not in it,
** then write the page into the statement journal.
*/
if( pPager->nSavepoint>0 && subjRequiresPage(pPg) ){
rc = subjournalPage(pPg);
if( pPager->nSavepoint>0 ){
rc = subjournalPageIfRequired(pPg);
}
/* Update the database size and return. */
@@ -6772,9 +6742,8 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){
** one or more savepoint bitvecs. This is the reason this function
** may return SQLITE_NOMEM.
*/
if( pPg->flags&PGHDR_DIRTY
&& subjRequiresPage(pPg)
&& SQLITE_OK!=(rc = subjournalPage(pPg))
if( (pPg->flags & PGHDR_DIRTY)!=0
&& SQLITE_OK!=(rc = subjournalPageIfRequired(pPg))
){
return rc;
}