diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/pager.c | 58 |
1 files changed, 33 insertions, 25 deletions
diff --git a/src/pager.c b/src/pager.c index 57cf9a637..b7fae8ed8 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.328 2007/04/13 04:01:59 drh Exp $ +** @(#) $Id: pager.c,v 1.329 2007/04/16 15:02:19 drh Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" @@ -294,7 +294,7 @@ struct Pager { Pager *pNext; /* Linked list of pagers in this thread */ #endif char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ - u32 iChangeCount; /* Db change-counter for which cache is valid */ + char dbFileVers[16]; /* Changes whenever database file changes */ }; /* @@ -1131,12 +1131,14 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){ #ifdef SQLITE_CHECK_PAGES pPg->pageHash = pager_pagehash(pPg); #endif - CODEC1(pPager, pData, pPg->pgno, 3); - - /* If this was page 1, then restore the value of Pager.iChangeCount */ + /* If this was page 1, then restore the value of Pager.dbFileVers. + ** Do this before any decoding. */ if( pgno==1 ){ - pPager->iChangeCount = retrieve32bits(pPg, 24); + memcpy(&pPager->dbFileVers, &((u8*)pData)[24],sizeof(pPager->dbFileVers)); } + + /* Decode the page just read from disk */ + CODEC1(pPager, pData, pPg->pgno, 3); } return rc; } @@ -2441,6 +2443,9 @@ static int pager_write_pagelist(PgHdr *pList){ rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize); PAGER_INCR(sqlite3_pager_writedb_count); PAGER_INCR(pPager->nWrite); + if( pList->pgno==1 ){ + memcpy(&pPager->dbFileVers, &pData[24], sizeof(pPager->dbFileVers)); + } } #ifndef NDEBUG else{ @@ -2680,6 +2685,10 @@ static int readDbPage(Pager *pPager, PgHdr *pPg, Pgno pgno){ PAGER_INCR(pPager->nRead); IOTRACE(("PGIN %p %d\n", pPager, pgno)); PAGERTRACE3("FETCH %d page %d\n", PAGERID(pPager), pPg->pgno); + if( pgno==1 ){ + memcpy(&pPager->dbFileVers, &((u8*)PGHDR_TO_DATA(pPg))[24], + sizeof(pPager->dbFileVers)); + } CODEC1(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3); return rc; } @@ -2780,16 +2789,21 @@ static int pagerSharedLock(Pager *pPager){ if( pPager->pAll ){ /* The shared-lock has just been acquired on the database file ** and there are already pages in the cache (from a previous - ** read or write transaction). If the value of the change-counter - ** stored in Pager.iChangeCount matches that found on page 1 of - ** the database file, then no database changes have occured since - ** the cache was last valid and it is safe to retain the cached - ** pages. Otherwise, if Pager.iChangeCount does not match the - ** change-counter on page 1 of the file, the current cache contents - ** must be discarded. + ** read or write transaction). Check to see if the database + ** has been modified. If the database has changed, flush the + ** cache. + ** + ** Database changes is detected by looking at 15 bytes beginning + ** at offset 24 into the file. The first 4 of these 16 bytes are + ** a 32-bit counter that is incremented with each change. The + ** other bytes change randomly with each file change when + ** a codec is in use. + ** + ** There is a vanishingly small chance that a change will not be + ** deteched. The chance of an undetected change is so small that + ** it can be neglected. */ - u8 zC[4]; - u32 iChangeCounter = 0; + char dbFileVers[sizeof(pPager->dbFileVers)]; sqlite3PagerPagecount(pPager); if( pPager->errCode ){ @@ -2797,21 +2811,20 @@ static int pagerSharedLock(Pager *pPager){ } if( pPager->dbSize>0 ){ - /* Read the 4-byte change counter directly from the file. */ rc = sqlite3OsSeek(pPager->fd, 24); if( rc!=SQLITE_OK ){ return rc; } - rc = sqlite3OsRead(pPager->fd, zC, 4); + rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers)); if( rc!=SQLITE_OK ){ return rc; } - iChangeCounter = (zC[0]<<24) + (zC[1]<<16) + (zC[2]<<8) + zC[3]; + }else{ + memset(dbFileVers, 0, sizeof(dbFileVers)); } - if( iChangeCounter!=pPager->iChangeCount ){ + if( memcmp(pPager->dbFileVers, dbFileVers, sizeof(dbFileVers))!=0 ){ pager_reset(pPager); - pPager->iChangeCount = iChangeCounter; } } } @@ -3029,10 +3042,6 @@ int sqlite3PagerAcquire( return rc; } } - /* If this was page 1, then restore the value of Pager.iChangeCount */ - if( pgno==1 ){ - pPager->iChangeCount = retrieve32bits(pPg, 24); - } /* Link the page into the page hash table */ h = pgno & (pPager->nHash-1); @@ -3722,7 +3731,6 @@ static int pager_incr_changecounter(Pager *pPager){ /* Increment the value just read and write it back to byte 24. */ change_counter++; put32bits(((char*)PGHDR_TO_DATA(pPgHdr))+24, change_counter); - pPager->iChangeCount = change_counter; /* Release the page reference. */ sqlite3PagerUnref(pPgHdr); |