Add the new sqlite3PagerUnrefPageOne() pager method to deal with the special
case of unreferencing page1. FossilOrigin-Name: b2e2100cf766da1cb499aec0ca0a9969d7af5d93312ab8cf895fbf4a6ffb9b2f
This commit is contained in:
parent
dfcdc663f2
commit
3908fe90b1
16
manifest
16
manifest
@ -1,5 +1,5 @@
|
||||
C Remove\san\sobsolete\soptimization\sin\spcache\sthat\sdue\sto\smore\srecent\schanges\nwas\srecently\smaking\sthe\scode\sa\slittle\sslower.
|
||||
D 2017-09-01T12:57:33.041
|
||||
C Add\sthe\snew\ssqlite3PagerUnrefPageOne()\spager\smethod\sto\sdeal\swith\sthe\sspecial\ncase\sof\sunreferencing\spage1.
|
||||
D 2017-09-01T14:50:19.167
|
||||
F Makefile.in c644bbe8ebe4aae82ad6783eae6b6beea4c727b99ff97568b847ced5e2ac7afb
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc 25b154da7f0b3d4924f27378c1f8d006285b80811f1ccf3ed953dbebf6282136
|
||||
@ -399,7 +399,7 @@ F src/auth.c 6277d63837357549fe14e723490d6dc1a38768d71c795c5eb5c0f8a99f918f73
|
||||
F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b
|
||||
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
|
||||
F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca
|
||||
F src/btree.c 1033b88fe50aba7d364b5a19666a9a274caa8d4c25ab7f3914221997b46af44a
|
||||
F src/btree.c f1ac9509f4595d034fe432982c39d51ac2bfc9bd83136d16255aede35c526b45
|
||||
F src/btree.h 32ef5d3f25dc70ef1ee9cecf84a023c21378f06a57cd701d2e866e141b150f09
|
||||
F src/btreeInt.h 55b702efce17e5d1941865464227d3802cfc9c7c832fac81d4c94dced47a71fc
|
||||
F src/build.c e71e96a67daf3d1dd23188423e66cd6af38017e2ec73fead5d2b57da2d3c7e16
|
||||
@ -443,8 +443,8 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
|
||||
F src/os_unix.c 489aa972ccc34f7b4770b891694b32101c59ddd4be4ef0ddd9a4da58c145c1a6
|
||||
F src/os_win.c 964165b66cde03abc72fe948198b01be608436894732eadb94c8720d2467f223
|
||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||
F src/pager.c bf51378c57c8e05d7f4d7bb9861f403a2e40cde82e25513401216d1ed30bc3e5
|
||||
F src/pager.h f2a99646c5533ffe11afa43e9e0bea74054e4efa
|
||||
F src/pager.c 3936b32a0a45f1b80462b38ba1ed0556e62843554a089ab9c4be1a35c97f23bc
|
||||
F src/pager.h 581698f2177e8bd4008fe4760898ce20b6133d1df22139b9101b5155f900df7a
|
||||
F src/parse.y 52ef3cecd0934e9da4a45b585883a03243ad615d338ad94f44501a05891dcdfa
|
||||
F src/pcache.c 4bada070456980c3c1f16d58ec2e64e389ad77b935e3d77e0c96e7bbd397289c
|
||||
F src/pcache.h 072f94d29281cffd99e46c1539849f248c4b56ae7684c1f36626797fee375170
|
||||
@ -1651,7 +1651,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 919863b14859d958d6c078097faae02070c7bd082e2814cf3f84bd84921e4419
|
||||
R 0eee553fc228f3f42e4580f46005e756
|
||||
P c4e7e175eecfd79015f4fae99618dfce6baf97c21bf3c909ea535d4e12dcaaad
|
||||
R 6f9a52521f107a3c330b7cfcb23523cf
|
||||
U drh
|
||||
Z 71c472332c9be0857de95ba6da186b34
|
||||
Z f39368718f6b0d67941da00fc11a34d5
|
||||
|
@ -1 +1 @@
|
||||
c4e7e175eecfd79015f4fae99618dfce6baf97c21bf3c909ea535d4e12dcaaad
|
||||
b2e2100cf766da1cb499aec0ca0a9969d7af5d93312ab8cf895fbf4a6ffb9b2f
|
25
src/btree.c
25
src/btree.c
@ -439,7 +439,8 @@ static void downgradeAllSharedCacheTableLocks(Btree *p){
|
||||
|
||||
#endif /* SQLITE_OMIT_SHARED_CACHE */
|
||||
|
||||
static void releasePage(MemPage *pPage);
|
||||
static void releasePage(MemPage *pPage); /* Forward reference */
|
||||
static void releasePageOne(MemPage *pPage); /* Forward reference */
|
||||
static void releasePageNotNull(MemPage *pPage); /* Forward reference */
|
||||
|
||||
/*
|
||||
@ -2109,6 +2110,8 @@ getAndInitPage_error:
|
||||
/*
|
||||
** Release a MemPage. This should be called once for each prior
|
||||
** call to btreeGetPage.
|
||||
**
|
||||
** Page1 is a special case and must be released using releasePageOne().
|
||||
*/
|
||||
static void releasePageNotNull(MemPage *pPage){
|
||||
assert( pPage->aData );
|
||||
@ -2122,6 +2125,16 @@ static void releasePageNotNull(MemPage *pPage){
|
||||
static void releasePage(MemPage *pPage){
|
||||
if( pPage ) releasePageNotNull(pPage);
|
||||
}
|
||||
static void releasePageOne(MemPage *pPage){
|
||||
assert( pPage!=0 );
|
||||
assert( pPage->aData );
|
||||
assert( pPage->pBt );
|
||||
assert( pPage->pDbPage!=0 );
|
||||
assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage );
|
||||
assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData );
|
||||
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
|
||||
sqlite3PagerUnrefPageOne(pPage->pDbPage);
|
||||
}
|
||||
|
||||
/*
|
||||
** Get an unused page.
|
||||
@ -3000,7 +3013,7 @@ static int lockBtree(BtShared *pBt){
|
||||
}else{
|
||||
setDefaultSyncFlag(pBt, SQLITE_DEFAULT_WAL_SYNCHRONOUS+1);
|
||||
if( isOpen==0 ){
|
||||
releasePage(pPage1);
|
||||
releasePageOne(pPage1);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
}
|
||||
@ -3047,7 +3060,7 @@ static int lockBtree(BtShared *pBt){
|
||||
** zero and return SQLITE_OK. The caller will call this function
|
||||
** again with the correct page-size.
|
||||
*/
|
||||
releasePage(pPage1);
|
||||
releasePageOne(pPage1);
|
||||
pBt->usableSize = usableSize;
|
||||
pBt->pageSize = pageSize;
|
||||
freeTempSpace(pBt);
|
||||
@ -3101,7 +3114,7 @@ static int lockBtree(BtShared *pBt){
|
||||
return SQLITE_OK;
|
||||
|
||||
page1_init_failed:
|
||||
releasePage(pPage1);
|
||||
releasePageOne(pPage1);
|
||||
pBt->pPage1 = 0;
|
||||
return rc;
|
||||
}
|
||||
@ -3146,7 +3159,7 @@ static void unlockBtreeIfUnused(BtShared *pBt){
|
||||
assert( pPage1->aData );
|
||||
assert( sqlite3PagerRefcount(pBt->pPager)==1 );
|
||||
pBt->pPage1 = 0;
|
||||
releasePageNotNull(pPage1);
|
||||
releasePageOne(pPage1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4068,7 +4081,7 @@ int sqlite3BtreeRollback(Btree *p, int tripCode, int writeOnly){
|
||||
if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage);
|
||||
testcase( pBt->nPage!=nPage );
|
||||
pBt->nPage = nPage;
|
||||
releasePage(pPage1);
|
||||
releasePageOne(pPage1);
|
||||
}
|
||||
assert( countValidCursors(pBt, 1)==0 );
|
||||
pBt->inTransaction = TRANS_READ;
|
||||
|
31
src/pager.c
31
src/pager.c
@ -5350,7 +5350,8 @@ int sqlite3PagerSharedLock(Pager *pPager){
|
||||
** nothing to rollback, so this routine is a no-op.
|
||||
*/
|
||||
static void pagerUnlockIfUnused(Pager *pPager){
|
||||
if( pPager->nMmapOut==0 && (sqlite3PcacheRefCount(pPager->pPCache)==0) ){
|
||||
if( sqlite3PcacheRefCount(pPager->pPCache)==0 ){
|
||||
assert( pPager->nMmapOut==0 ); /* because page1 is never memory mapped */
|
||||
pagerUnlockAndRollback(pPager);
|
||||
}
|
||||
}
|
||||
@ -5636,25 +5637,39 @@ DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){
|
||||
/*
|
||||
** Release a page reference.
|
||||
**
|
||||
** If the number of references to the page drop to zero, then the
|
||||
** page is added to the LRU list. When all references to all pages
|
||||
** are released, a rollback occurs and the lock on the database is
|
||||
** removed.
|
||||
** The sqlite3PagerUnref() and sqlite3PagerUnrefNotNull() may only be
|
||||
** used if we know that the page being released is not the last page.
|
||||
** The btree layer always holds page1 open until the end, so these first
|
||||
** to routines can be used to release any page other than BtShared.pPage1.
|
||||
**
|
||||
** Use sqlite3PagerUnrefPageOne() to release page1. This latter routine
|
||||
** checks the total number of outstanding pages and if the number of
|
||||
** pages reaches zero it drops the database lock.
|
||||
*/
|
||||
void sqlite3PagerUnrefNotNull(DbPage *pPg){
|
||||
Pager *pPager;
|
||||
TESTONLY( Pager *pPager = pPg->pPager; )
|
||||
assert( pPg!=0 );
|
||||
pPager = pPg->pPager;
|
||||
if( pPg->flags & PGHDR_MMAP ){
|
||||
assert( pPg->pgno!=1 ); /* Page1 is never memory mapped */
|
||||
pagerReleaseMapPage(pPg);
|
||||
}else{
|
||||
sqlite3PcacheRelease(pPg);
|
||||
}
|
||||
pagerUnlockIfUnused(pPager);
|
||||
/* Do not use this routine to release the last reference to page1 */
|
||||
assert( sqlite3PcacheRefCount(pPager->pPCache)>0 );
|
||||
}
|
||||
void sqlite3PagerUnref(DbPage *pPg){
|
||||
if( pPg ) sqlite3PagerUnrefNotNull(pPg);
|
||||
}
|
||||
void sqlite3PagerUnrefPageOne(DbPage *pPg){
|
||||
Pager *pPager;
|
||||
assert( pPg!=0 );
|
||||
assert( pPg->pgno==1 );
|
||||
assert( (pPg->flags & PGHDR_MMAP)==0 ); /* Page1 is never memory mapped */
|
||||
pPager = pPg->pPager;
|
||||
sqlite3PcacheRelease(pPg);
|
||||
pagerUnlockIfUnused(pPager);
|
||||
}
|
||||
|
||||
/*
|
||||
** This function is called at the start of every write transaction.
|
||||
|
@ -151,6 +151,7 @@ DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno);
|
||||
void sqlite3PagerRef(DbPage*);
|
||||
void sqlite3PagerUnref(DbPage*);
|
||||
void sqlite3PagerUnrefNotNull(DbPage*);
|
||||
void sqlite3PagerUnrefPageOne(DbPage*);
|
||||
|
||||
/* Operations on page references. */
|
||||
int sqlite3PagerWrite(DbPage*);
|
||||
|
Loading…
Reference in New Issue
Block a user