diff --git a/manifest b/manifest index e289ceb2e6..1d01247464 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\smakefile\snow\sruns\smkkeywordhash.c.\s\sKeywords\sthat\sare\sunused\sare\nomitted\sfrom\sthe\skeyword\shash\stable.\s(CVS\s2045) -D 2004-11-03T03:59:57 +C Auto-vacuum\sbug:\sCorrectly\smanipulate\spage\scache\shash-table\sentries\sin\ssqlite3pager_movepage().\s(CVS\s2046) +D 2004-11-03T08:44:06 F Makefile.in c4d2416860f472a1e3393714d0372074197565df F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457 F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1 @@ -52,7 +52,7 @@ F src/os_unix.c 5824b22ba41fe9d514ef9169aac1b5fde73af229 F src/os_unix.h f3097815e041e82e24d92505e1ff61ba24172d13 F src/os_win.c 9482dfc92f289b68205bb2c9315757c7e3946bfb F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b -F src/pager.c 6b00c0d5aac601b9f556b8fdba25e69438245f1a +F src/pager.c 9ce238f9540eb56b21fef085dc038dffca75835b F src/pager.h cbe4ba356d9dd3f30260f322b3dc77408164df14 F src/parse.y 625750bf4b01a7c2b4c15e5367a7539a66e6c909 F src/pragma.c 44e192eb5928157bdb015926f858a7c6e3ef6c98 @@ -252,7 +252,7 @@ F www/tclsqlite.tcl 560ecd6a916b320e59f2917317398f3d59b7cc25 F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9 F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0 F www/whentouse.tcl fdacb0ba2d39831e8a6240d05a490026ad4c4e4c -P bd50fbb5fecd1829c87e8ca72c458c71f590274b -R c93f4ae3ede116e4f0e25ff57fd95e47 -U drh -Z 2a91aed8200460991cb047467354dda3 +P 007aec11333432e08d1091b728773011e9078bc3 +R 745d17de8251e17a5bf338dbe0b72b9d +U danielk1977 +Z 2233bf7f9ac4fbde946c01ae92386ee6 diff --git a/manifest.uuid b/manifest.uuid index 0b8c94064b..ba1f119215 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -007aec11333432e08d1091b728773011e9078bc3 \ No newline at end of file +719c1b79671c8cd7c5a6b5967ad4265b65e433d3 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index e6ab35b4a5..fcbd407c35 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.170 2004/11/02 12:56:41 danielk1977 Exp $ +** @(#) $Id: pager.c,v 1.171 2004/11/03 08:44:06 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -1635,6 +1635,33 @@ int sqlite3pager_pagecount(Pager *pPager){ static int syncJournal(Pager*); +/* +** Unlink pPg from it's hash chain. Also set the page number to 0 to indicate +** that the page is not part of any hash chain. This is required because the +** sqlite3pager_movepage() routine can leave a page in the +** pNextFree/pPrevFree list that is not a part of any hash-chain. +*/ +static void unlinkHashChain(Pager *pPager, PgHdr *pPg){ + if( pPg->pgno==0 ){ + /* If the page number is zero, then this page is not in any hash chain. */ + return; + } + if( pPg->pNextHash ){ + pPg->pNextHash->pPrevHash = pPg->pPrevHash; + } + if( pPg->pPrevHash ){ + assert( pPager->aHash[pager_hash(pPg->pgno)]!=pPg ); + pPg->pPrevHash->pNextHash = pPg->pNextHash; + }else{ + int h = pager_hash(pPg->pgno); + assert( pPager->aHash[h]==pPg ); + pPager->aHash[h] = pPg->pNextHash; + } + + pPg->pgno = 0; + pPg->pNextHash = pPg->pPrevHash = 0; +} + /* ** Unlink a page from the free list (the list of all pages where nRef==0) ** and from its hash collision chain. @@ -1665,6 +1692,8 @@ static void unlinkPage(PgHdr *pPg){ pPg->pNextFree = pPg->pPrevFree = 0; /* Unlink from the pgno hash table */ + unlinkHashChain(pPager, pPg); +/* if( pPg->pNextHash ){ pPg->pNextHash->pPrevHash = pPg->pPrevHash; } @@ -1676,6 +1705,7 @@ static void unlinkPage(PgHdr *pPg){ pPager->aHash[h] = pPg->pNextHash; } pPg->pNextHash = pPg->pPrevHash = 0; +*/ } /* @@ -3215,6 +3245,7 @@ sync_exit: } #ifndef SQLITE_OMIT_AUTOVACUUM + /* ** Move the page identified by pData to location pgno in the file. ** @@ -3233,55 +3264,35 @@ sync_exit: int sqlite3pager_movepage(Pager *pPager, void *pData, Pgno pgno){ PgHdr *pPg = DATA_TO_PGHDR(pData); PgHdr *pPgOld; + int h; assert( !pPager->stmtInUse ); - /* assert( pPg->pNextFree==0 && pPg->pPrevFree==0 && pPg->nRef>0 ); */ assert( pPg->nRef>0 ); /* Unlink pPg from it's hash-chain */ - if( pPg->pNextHash ){ - pPg->pNextHash->pPrevHash = pPg->pPrevHash; - } - if( pPg->pPrevHash ){ - pPg->pPrevHash->pNextHash = pPg->pNextHash; - }else{ - int h = pager_hash(pPg->pgno); - assert( pPager->aHash[h]==pPg ); - pPager->aHash[h] = pPg->pNextHash; - } - - /* Change the page number for pPg */ - pPg->pgno = pgno; + unlinkHashChain(pPager, pPg); + /* If the cache contains a page with page-number pgno exists, remove it + ** from it's hash chain. + */ pPgOld = pager_lookup(pPager, pgno); if( pPgOld ){ - /* Remove pPgOld from the page number hash-chain and insert pPg. */ - assert(pPgOld->nRef==0 && !pPgOld->pNextStmt && !pPgOld->pPrevStmt ); - if( pPgOld->pNextHash ){ - pPgOld->pNextHash->pPrevHash = pPg; - } - if( pPgOld->pPrevHash ){ - pPgOld->pPrevHash->pNextHash = pPg; - }else{ - int h = pager_hash(pgno); - assert( pPager->aHash[h]==pPgOld ); - pPager->aHash[h] = pPg; - } - pPgOld->pNextHash = pPgOld->pPrevHash = 0; - }else{ - /* Insert pPg into it's new hash-chain. */ - int h = pager_hash(pgno); - if( pPager->aHash[h] ){ - pPager->aHash[h]->pNextHash = pPg; - } - pPg->pNextHash = pPager->aHash[h]; - pPg->pPrevHash = 0; + assert( pPgOld->nRef==0 ); + unlinkHashChain(pPager, pPgOld); + pPgOld->dirty = 0; } - /* Don't write the old page when sqlite3pager_sync() is called. Do write - ** the new one. - */ - pPgOld->dirty = 0; + /* Change the page number for pPg and insert it into the new hash-chain. */ + pPg->pgno = pgno; + h = pager_hash(pgno); + if( pPager->aHash[h] ){ + assert( pPager->aHash[h]->pPrevHash==0 ); + pPager->aHash[h]->pPrevHash = pPg; + } + pPg->pNextHash = pPager->aHash[h]; + pPager->aHash[h] = pPg; + pPg->pPrevHash = 0; + pPg->dirty = 1; pPager->dirtyCache = 1;