diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/btree.c | 6 | ||||
-rw-r--r-- | src/pager.c | 52 | ||||
-rw-r--r-- | src/pager.h | 4 | ||||
-rw-r--r-- | src/pcache.c | 11 | ||||
-rw-r--r-- | src/pcache.h | 3 |
5 files changed, 40 insertions, 36 deletions
diff --git a/src/btree.c b/src/btree.c index 45184c422..e4eff2181 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btree.c,v 1.503 2008/08/25 11:57:17 danielk1977 Exp $ +** $Id: btree.c,v 1.504 2008/08/27 15:16:34 danielk1977 Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. @@ -4347,7 +4347,7 @@ static int freePage(MemPage *pPage){ put4byte(&pTrunk->aData[4], k+1); put4byte(&pTrunk->aData[8+k*4], pPage->pgno); #ifndef SQLITE_SECURE_DELETE - sqlite3PagerDontWrite(pPage->pDbPage); + rc = sqlite3PagerDontWrite(pPage->pDbPage); #endif } TRACE(("FREE-PAGE: %d leaf on trunk page %d\n",pPage->pgno,pTrunk->pgno)); @@ -7039,7 +7039,7 @@ static int btreeCopyFile(Btree *pTo, Btree *pFrom){ ** page is still on the rollback journal, though. And that is the ** whole point of this block: to put pages on the rollback journal. */ - sqlite3PagerDontWrite(pDbPage); + rc = sqlite3PagerDontWrite(pDbPage); } sqlite3PagerUnref(pDbPage); } diff --git a/src/pager.c b/src/pager.c index 7d122aee0..196e23e25 100644 --- a/src/pager.c +++ b/src/pager.c @@ -18,7 +18,7 @@ ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.482 2008/08/27 09:44:40 danielk1977 Exp $ +** @(#) $Id: pager.c,v 1.483 2008/08/27 15:16:34 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" @@ -191,6 +191,7 @@ struct Pager { Pgno mxPgno; /* Maximum allowed size of the database */ Bitvec *pInJournal; /* One bit for each page in the database file */ Bitvec *pInStmt; /* One bit for each page in the database */ + Bitvec *pAlwaysRollback; /* One bit for each page marked always-rollback */ char *zFilename; /* Name of the database file */ char *zJournal; /* Name of the journal file */ char *zDirectory; /* Directory hold database and journal files */ @@ -895,6 +896,8 @@ static void pager_unlock(Pager *pPager){ pPager->journalOpen = 0; sqlite3BitvecDestroy(pPager->pInJournal); pPager->pInJournal = 0; + sqlite3BitvecDestroy(pPager->pAlwaysRollback); + pPager->pAlwaysRollback = 0; } /* If Pager.errCode is set, the contents of the pager cache cannot be @@ -985,12 +988,14 @@ static int pager_end_transaction(Pager *pPager, int hasMaster){ } sqlite3BitvecDestroy(pPager->pInJournal); pPager->pInJournal = 0; + sqlite3BitvecDestroy(pPager->pAlwaysRollback); + pPager->pAlwaysRollback = 0; sqlite3PcacheCleanAll(pPager->pPCache); #ifdef SQLITE_CHECK_PAGES sqlite3PcacheIterate(pPager->pPCache, pager_set_pagehash); #endif - sqlite3PcacheSetFlags(pPager->pPCache, - ~(PGHDR_IN_JOURNAL | PGHDR_NEED_SYNC | PGHDR_ALWAYS_ROLLBACK), 0 + sqlite3PcacheSetFlags(pPager->pPCache, + ~(PGHDR_IN_JOURNAL | PGHDR_NEED_SYNC), 0 ); pPager->dirtyCache = 0; pPager->nRec = 0; @@ -2201,6 +2206,7 @@ int sqlite3PagerClose(Pager *pPager){ sqlite3OsClose(pPager->jfd); } sqlite3BitvecDestroy(pPager->pInJournal); + sqlite3BitvecDestroy(pPager->pAlwaysRollback); if( pPager->stmtOpen ){ sqlite3OsClose(pPager->stfd); } @@ -2843,13 +2849,13 @@ static int pagerAcquire( return rc; } - if( nMax<(int)pgno || MEMDB || (noContent && !pPager->alwaysRollback) ){ + if( nMax<(int)pgno || MEMDB || noContent ){ if( pgno>pPager->mxPgno ){ sqlite3PagerUnref(pPg); return SQLITE_FULL; } memset(pPg->pData, 0, pPager->pageSize); - if( noContent && !pPager->alwaysRollback ){ + if( noContent ){ pPg->flags |= PGHDR_NEED_READ; } IOTRACE(("ZERO %p %d\n", pPager, pgno)); @@ -2985,7 +2991,6 @@ static int pager_open_journal(Pager *pPager){ pPager->journalOpen = 1; pPager->journalStarted = 0; pPager->needSync = 0; - pPager->alwaysRollback = 0; pPager->nRec = 0; if( pPager->errCode ){ rc = pPager->errCode; @@ -3434,13 +3439,24 @@ int sqlite3PagerIswriteable(DbPage *pPg){ ** page contains critical data, we still need to be sure it gets ** rolled back in spite of the sqlite3PagerDontRollback() call. */ -void sqlite3PagerDontWrite(DbPage *pDbPage){ +int sqlite3PagerDontWrite(DbPage *pDbPage){ PgHdr *pPg = pDbPage; Pager *pPager = pPg->pPager; + int rc; - if( MEMDB ) return; - pPg->flags |= PGHDR_ALWAYS_ROLLBACK; - if( (pPg->flags&PGHDR_DIRTY) && !pPager->stmtInUse ){ + if( MEMDB || pPg->pgno>pPager->origDbSize ){ + return SQLITE_OK; + } + if( pPager->pAlwaysRollback==0 ){ + assert( pPager->pInJournal ); + pPager->pAlwaysRollback = sqlite3BitvecCreate(pPager->origDbSize); + if( !pPager->pAlwaysRollback ){ + return SQLITE_NOMEM; + } + } + rc = sqlite3BitvecSet(pPager->pAlwaysRollback, pPg->pgno); + + if( rc==SQLITE_OK && (pPg->flags&PGHDR_DIRTY) && !pPager->stmtInUse ){ assert( pPager->state>=PAGER_SHARED ); if( pPager->dbSize==(int)pPg->pgno && pPager->origDbSize<pPager->dbSize ){ /* If this pages is the last page in the file and the file has grown @@ -3460,6 +3476,7 @@ void sqlite3PagerDontWrite(DbPage *pDbPage){ #endif } } + return rc; } /* @@ -3482,15 +3499,16 @@ void sqlite3PagerDontRollback(DbPage *pPg){ ** this page (DontWrite() sets the alwaysRollback flag), then this ** function is a no-op. */ - if( pPager->journalOpen==0 || (pPg->flags&PGHDR_ALWAYS_ROLLBACK) - || pPager->alwaysRollback + if( pPager->journalOpen==0 + || sqlite3BitvecTest(pPager->pAlwaysRollback, pPg->pgno) + || pPg->pgno>pPager->origDbSize ){ return; } assert( !MEMDB ); /* For a memdb, pPager->journalOpen is always 0 */ #ifdef SQLITE_SECURE_DELETE - if( pPg->inJournal || (int)pPg->pgno > pPager->origDbSize ){ + if( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize ){ return; } #endif @@ -3782,7 +3800,7 @@ int sqlite3PagerCommitPhaseTwo(Pager *pPager){ sqlite3PcacheCommit(pPager->pPCache, 0); sqlite3PcacheCleanAll(pPager->pPCache); sqlite3PcacheSetFlags(pPager->pPCache, - ~(PGHDR_IN_JOURNAL | PGHDR_NEED_SYNC | PGHDR_ALWAYS_ROLLBACK), 0 + ~(PGHDR_IN_JOURNAL | PGHDR_NEED_SYNC), 0 ); pPager->state = PAGER_SHARED; }else{ @@ -3813,7 +3831,7 @@ int sqlite3PagerRollback(Pager *pPager){ sqlite3PcacheRollback(pPager->pPCache, 0); sqlite3PcacheCleanAll(pPager->pPCache); sqlite3PcacheSetFlags(pPager->pPCache, - ~(PGHDR_IN_JOURNAL | PGHDR_NEED_SYNC | PGHDR_ALWAYS_ROLLBACK), 0 + ~(PGHDR_IN_JOURNAL | PGHDR_NEED_SYNC), 0 ); pPager->dbSize = pPager->origDbSize; pager_truncate_cache(pPager); @@ -4232,8 +4250,4 @@ i64 sqlite3PagerJournalSizeLimit(Pager *pPager, i64 iLimit){ return pPager->journalSizeLimit; } -void sqlite3PagerAlwaysRollback(Pager *pPager){ - pPager->alwaysRollback = 1; -} - #endif /* SQLITE_OMIT_DISKIO */ diff --git a/src/pager.h b/src/pager.h index 50bce8a3f..305eff1c8 100644 --- a/src/pager.h +++ b/src/pager.h @@ -13,7 +13,7 @@ ** subsystem. The page cache subsystem reads and writes a file a page ** at a time and provides a journal for rollback. ** -** @(#) $Id: pager.h,v 1.80 2008/08/22 17:34:45 drh Exp $ +** @(#) $Id: pager.h,v 1.81 2008/08/27 15:16:34 danielk1977 Exp $ */ #ifndef _PAGER_H_ @@ -95,7 +95,7 @@ int sqlite3PagerStmtBegin(Pager*); int sqlite3PagerStmtCommit(Pager*); int sqlite3PagerStmtRollback(Pager*); void sqlite3PagerDontRollback(DbPage*); -void sqlite3PagerDontWrite(DbPage*); +int sqlite3PagerDontWrite(DbPage*); int sqlite3PagerRefcount(Pager*); void sqlite3PagerSetSafetyLevel(Pager*,int,int); const char *sqlite3PagerFilename(Pager*); diff --git a/src/pcache.c b/src/pcache.c index db2ec83b0..07300ade8 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -11,7 +11,7 @@ ************************************************************************* ** This file implements that page cache. ** -** @(#) $Id: pcache.c,v 1.16 2008/08/27 09:44:40 danielk1977 Exp $ +** @(#) $Id: pcache.c,v 1.17 2008/08/27 15:16:34 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -497,15 +497,6 @@ static PgHdr *pcacheRecyclePage(){ pcacheRemoveFromLruList(p); pcacheRemoveFromHash(p); pcacheRemoveFromList(&p->pCache->pClean, p); - - /* If the always-rollback flag is set on the page being recycled, set - ** the always-rollback flag on the corresponding pager. TODO: This is - ** a thread-safety problem. - */ - if( p->flags&PGHDR_ALWAYS_ROLLBACK ){ - assert(p->pPager); - sqlite3PagerAlwaysRollback(p->pPager); - } } return p; diff --git a/src/pcache.h b/src/pcache.h index 0fc3b7df3..8dcc3655a 100644 --- a/src/pcache.h +++ b/src/pcache.h @@ -12,7 +12,7 @@ ** This header file defines the interface that the sqlite page cache ** subsystem. ** -** @(#) $Id: pcache.h,v 1.6 2008/08/26 18:05:48 danielk1977 Exp $ +** @(#) $Id: pcache.h,v 1.7 2008/08/27 15:16:34 danielk1977 Exp $ */ #ifndef _PCACHE_H_ @@ -48,7 +48,6 @@ struct PgHdr { #define PGHDR_IN_STMTJRNL 0x002 /* Page is in the statement journal */ #define PGHDR_DIRTY 0x004 /* Page has changed */ #define PGHDR_NEED_SYNC 0x008 /* Peed to fsync this page */ -#define PGHDR_ALWAYS_ROLLBACK 0x010 /* Force writing to journal */ #define PGHDR_NEED_READ 0x020 /* Content is unread */ #define PGHDR_IS_INIT 0x040 /* pData is initialized */ #define PGHDR_REUSE_UNLIKELY 0x080 /* Hint: Reuse is unlikely */ |