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

Change the page cache so that a new sqlite3_pcache object is allocated as

soon as the page cache is opened, not delayed until the first fetch request.
This give a noticable performance boost.  The interface between pager and
the page cache has changed slightly, which might break ZIPVFS.

FossilOrigin-Name: f1f94a971e031e784f8c30a6faf829df58709329
This commit is contained in:
drh
2014-08-26 15:06:49 +00:00
parent 05bbb2e824
commit c3031c61ef
5 changed files with 67 additions and 78 deletions

View File

@@ -1,5 +1,5 @@
C Add\san\sassert()\sand\sfive\stestcase()\smacros\sto\sthe\sOP_Cast\sopcode\simplementation\nto\shelp\sverify\sthat\sit\sis\sfully\stested. C Change\sthe\spage\scache\sso\sthat\sa\snew\ssqlite3_pcache\sobject\sis\sallocated\sas\nsoon\sas\sthe\spage\scache\sis\sopened,\snot\sdelayed\suntil\sthe\sfirst\sfetch\srequest.\nThis\sgive\sa\snoticable\sperformance\sboost.\s\sThe\sinterface\sbetween\spager\sand\nthe\spage\scache\shas\schanged\sslightly,\swhich\smight\sbreak\sZIPVFS.
D 2014-08-25T22:37:19.150 D 2014-08-26T15:06:49.829
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 5eb79e334a5de69c87740edd56af6527dd219308 F Makefile.in 5eb79e334a5de69c87740edd56af6527dd219308
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -211,11 +211,11 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
F src/os_unix.c bd7df3094a60915c148517504c76df4fca24e542 F src/os_unix.c bd7df3094a60915c148517504c76df4fca24e542
F src/os_win.c d067fce558a5032e6e6afe62899e5397bf63cf3e F src/os_win.c d067fce558a5032e6e6afe62899e5397bf63cf3e
F src/os_win.h 09e751b20bbc107ffbd46e13555dc73576d88e21 F src/os_win.h 09e751b20bbc107ffbd46e13555dc73576d88e21
F src/pager.c 53cc5e9d73afb74add79f49755c8ee240fbdbef7 F src/pager.c 27fb89e62e0ccf10218805ed31315ccb2d56c0ce
F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428
F src/parse.y 22d6a074e5f5a7258947a1dc55a9bf946b765dd0 F src/parse.y 22d6a074e5f5a7258947a1dc55a9bf946b765dd0
F src/pcache.c da602c5447051705cab41604bf3276815eb569d0 F src/pcache.c c216e4077449be57e9752a348490ffa467b85599
F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache.h 80a9c3f7d7b7080388e8654717cb45e7b99f14a6
F src/pcache1.c c5af6403a55178c9d1c09e4f77b0f9c88822762c F src/pcache1.c c5af6403a55178c9d1c09e4f77b0f9c88822762c
F src/pragma.c d10ef67c4de79f78188b965b4b7988aff1d66f2e F src/pragma.c d10ef67c4de79f78188b965b4b7988aff1d66f2e
F src/prepare.c 3842c1dfc0b053458e3adcf9f6efc48e03e3fe3d F src/prepare.c 3842c1dfc0b053458e3adcf9f6efc48e03e3fe3d
@@ -1188,7 +1188,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 1ad70ec550c004160d9c0c57e6c416812cdead5e P af364cce9da0961593ef876b646197f82df08ad5
R b751a4133861a7b502aa405ba96eea49 R e52a11dddfc2629a8399ec2b801365c3
U drh U drh
Z 0bd8a75e39f468a6e4b9b4599a579487 Z 1a77b3226c1f56b49ad44674617b7aa6

View File

@@ -1 +1 @@
af364cce9da0961593ef876b646197f82df08ad5 f1f94a971e031e784f8c30a6faf829df58709329

View File

@@ -3622,7 +3622,7 @@ int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nReserve){
pPager->pageSize = pageSize; pPager->pageSize = pageSize;
sqlite3PageFree(pPager->pTmpSpace); sqlite3PageFree(pPager->pTmpSpace);
pPager->pTmpSpace = pNew; pPager->pTmpSpace = pNew;
sqlite3PcacheSetPageSize(pPager->pPCache, pageSize); rc = sqlite3PcacheSetPageSize(pPager->pPCache, pageSize);
} }
} }
@@ -4385,7 +4385,7 @@ static int pagerStress(void *p, PgHdr *pPg){
** **
** Spilling is also prohibited when in an error state since that could ** Spilling is also prohibited when in an error state since that could
** lead to database corruption. In the current implementaton it ** lead to database corruption. In the current implementaton it
** is impossible for sqlite3PcacheFetch() to be called with createFlag==1 ** is impossible for sqlite3PcacheFetch() to be called with createFlag==3
** while in the error state, hence it is impossible for this routine to ** while in the error state, hence it is impossible for this routine to
** be called in the error state. Nevertheless, we include a NEVER() ** be called in the error state. Nevertheless, we include a NEVER()
** test for the error state as a safeguard against future changes. ** test for the error state as a safeguard against future changes.
@@ -4721,22 +4721,23 @@ act_like_temp_file:
testcase( rc!=SQLITE_OK ); testcase( rc!=SQLITE_OK );
} }
/* If an error occurred in either of the blocks above, free the /* Initialize the PCache object. */
** Pager structure and close the file. if( rc==SQLITE_OK ){
assert( nExtra<1000 );
nExtra = ROUND8(nExtra);
rc = sqlite3PcacheOpen(szPageDflt, nExtra, !memDb,
!memDb?pagerStress:0, (void *)pPager, pPager->pPCache);
}
/* If an error occurred above, free the Pager structure and close the file.
*/ */
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
assert( !pPager->pTmpSpace );
sqlite3OsClose(pPager->fd); sqlite3OsClose(pPager->fd);
sqlite3PageFree(pPager->pTmpSpace);
sqlite3_free(pPager); sqlite3_free(pPager);
return rc; return rc;
} }
/* Initialize the PCache object. */
assert( nExtra<1000 );
nExtra = ROUND8(nExtra);
sqlite3PcacheOpen(szPageDflt, nExtra, !memDb,
!memDb?pagerStress:0, (void *)pPager, pPager->pPCache);
PAGERTRACE(("OPEN %d %s\n", FILEHANDLEID(pPager->fd), pPager->zFilename)); PAGERTRACE(("OPEN %d %s\n", FILEHANDLEID(pPager->fd), pPager->zFilename));
IOTRACE(("OPEN %p %s\n", pPager, pPager->zFilename)) IOTRACE(("OPEN %p %s\n", pPager, pPager->zFilename))
@@ -5318,7 +5319,7 @@ int sqlite3PagerAcquire(
} }
} }
rc = sqlite3PcacheFetch(pPager->pPCache, pgno, 1, ppPage); rc = sqlite3PcacheFetch(pPager->pPCache, pgno, 3, ppPage);
} }
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){

View File

@@ -144,6 +144,17 @@ static void pcacheUnpin(PgHdr *p){
} }
} }
/*
** Compute the number of pages of cache requested.
*/
static int numberOfCachePages(PCache *p){
if( p->szCache>=0 ){
return p->szCache;
}else{
return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra));
}
}
/*************************************************** General Interfaces ****** /*************************************************** General Interfaces ******
** **
** Initialize and shutdown the page cache subsystem. Neither of these ** Initialize and shutdown the page cache subsystem. Neither of these
@@ -176,7 +187,7 @@ int sqlite3PcacheSize(void){ return sizeof(PCache); }
** The caller discovers how much space needs to be allocated by ** The caller discovers how much space needs to be allocated by
** calling sqlite3PcacheSize(). ** calling sqlite3PcacheSize().
*/ */
void sqlite3PcacheOpen( int sqlite3PcacheOpen(
int szPage, /* Size of every page */ int szPage, /* Size of every page */
int szExtra, /* Extra space associated with each page */ int szExtra, /* Extra space associated with each page */
int bPurgeable, /* True if pages are on backing store */ int bPurgeable, /* True if pages are on backing store */
@@ -185,38 +196,37 @@ void sqlite3PcacheOpen(
PCache *p /* Preallocated space for the PCache */ PCache *p /* Preallocated space for the PCache */
){ ){
memset(p, 0, sizeof(PCache)); memset(p, 0, sizeof(PCache));
p->szPage = szPage; p->szPage = 1;
p->szExtra = szExtra; p->szExtra = szExtra;
p->bPurgeable = bPurgeable; p->bPurgeable = bPurgeable;
p->eCreate = 2; p->eCreate = 2;
p->xStress = xStress; p->xStress = xStress;
p->pStress = pStress; p->pStress = pStress;
p->szCache = 100; p->szCache = 100;
return sqlite3PcacheSetPageSize(p, szPage);
} }
/* /*
** Change the page size for PCache object. The caller must ensure that there ** Change the page size for PCache object. The caller must ensure that there
** are no outstanding page references when this function is called. ** are no outstanding page references when this function is called.
*/ */
void sqlite3PcacheSetPageSize(PCache *pCache, int szPage){ int sqlite3PcacheSetPageSize(PCache *pCache, int szPage){
assert( pCache->nRef==0 && pCache->pDirty==0 ); assert( pCache->nRef==0 && pCache->pDirty==0 );
if( pCache->szPage ){
sqlite3_pcache *pNew;
pNew = sqlite3GlobalConfig.pcache2.xCreate(
szPage, pCache->szExtra + sizeof(PgHdr), pCache->bPurgeable
);
if( pNew==0 ) return SQLITE_NOMEM;
sqlite3GlobalConfig.pcache2.xCachesize(pNew, numberOfCachePages(pCache));
if( pCache->pCache ){ if( pCache->pCache ){
sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache); sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
pCache->pCache = 0; }
pCache->pCache = pNew;
pCache->pPage1 = 0; pCache->pPage1 = 0;
}
pCache->szPage = szPage; pCache->szPage = szPage;
}
/*
** Compute the number of pages of cache requested.
*/
static int numberOfCachePages(PCache *p){
if( p->szCache>=0 ){
return p->szCache;
}else{
return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra));
} }
return SQLITE_OK;
} }
/* /*
@@ -233,28 +243,10 @@ int sqlite3PcacheFetch(
int eCreate; int eCreate;
assert( pCache!=0 ); assert( pCache!=0 );
assert( createFlag==1 || createFlag==0 ); assert( pCache->pCache!=0 );
assert( createFlag==3 || createFlag==0 );
assert( pgno>0 ); assert( pgno>0 );
/* If the pluggable cache (sqlite3_pcache*) has not been allocated,
** allocate it now.
*/
if( !pCache->pCache ){
sqlite3_pcache *p;
if( !createFlag ){
*ppPage = 0;
return SQLITE_OK;
}
p = sqlite3GlobalConfig.pcache2.xCreate(
pCache->szPage, pCache->szExtra + sizeof(PgHdr), pCache->bPurgeable
);
if( !p ){
return SQLITE_NOMEM;
}
sqlite3GlobalConfig.pcache2.xCachesize(p, numberOfCachePages(pCache));
pCache->pCache = p;
}
/* eCreate defines what to do if the page does not exist. /* eCreate defines what to do if the page does not exist.
** 0 Do not allocate a new page. (createFlag==0) ** 0 Do not allocate a new page. (createFlag==0)
** 1 Allocate a new page if doing so is inexpensive. ** 1 Allocate a new page if doing so is inexpensive.
@@ -262,8 +254,10 @@ int sqlite3PcacheFetch(
** 2 Allocate a new page even it doing so is difficult. ** 2 Allocate a new page even it doing so is difficult.
** (createFlag==1 AND !(bPurgeable AND pDirty) ** (createFlag==1 AND !(bPurgeable AND pDirty)
*/ */
eCreate = createFlag==0 ? 0 : pCache->eCreate; eCreate = createFlag & pCache->eCreate;
assert( (createFlag*(1+(!pCache->bPurgeable||!pCache->pDirty)))==eCreate ); assert( eCreate==0 || eCreate==1 || eCreate==2 );
assert( createFlag==0 || pCache->eCreate==eCreate );
assert( createFlag==0 || eCreate==1+(!pCache->bPurgeable||!pCache->pDirty) );
pPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate); pPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate);
if( !pPage && eCreate==1 ){ if( !pPage && eCreate==1 ){
PgHdr *pPg; PgHdr *pPg;
@@ -471,9 +465,8 @@ void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){
** Close a cache. ** Close a cache.
*/ */
void sqlite3PcacheClose(PCache *pCache){ void sqlite3PcacheClose(PCache *pCache){
if( pCache->pCache ){ assert( pCache->pCache!=0 );
sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache); sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
}
} }
/* /*
@@ -582,11 +575,8 @@ int sqlite3PcachePageRefcount(PgHdr *p){
** Return the total number of pages in the cache. ** Return the total number of pages in the cache.
*/ */
int sqlite3PcachePagecount(PCache *pCache){ int sqlite3PcachePagecount(PCache *pCache){
int nPage = 0; assert( pCache->pCache!=0 );
if( pCache->pCache ){ return sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache);
nPage = sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache);
}
return nPage;
} }
#ifdef SQLITE_TEST #ifdef SQLITE_TEST
@@ -602,20 +592,18 @@ int sqlite3PcacheGetCachesize(PCache *pCache){
** Set the suggested cache-size value. ** Set the suggested cache-size value.
*/ */
void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){ void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){
assert( pCache->pCache!=0 );
pCache->szCache = mxPage; pCache->szCache = mxPage;
if( pCache->pCache ){
sqlite3GlobalConfig.pcache2.xCachesize(pCache->pCache, sqlite3GlobalConfig.pcache2.xCachesize(pCache->pCache,
numberOfCachePages(pCache)); numberOfCachePages(pCache));
}
} }
/* /*
** Free up as much memory as possible from the page cache. ** Free up as much memory as possible from the page cache.
*/ */
void sqlite3PcacheShrink(PCache *pCache){ void sqlite3PcacheShrink(PCache *pCache){
if( pCache->pCache ){ assert( pCache->pCache!=0 );
sqlite3GlobalConfig.pcache2.xShrink(pCache->pCache); sqlite3GlobalConfig.pcache2.xShrink(pCache->pCache);
}
} }
#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG) #if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)

View File

@@ -68,7 +68,7 @@ void sqlite3PCacheBufferSetup(void *, int sz, int n);
** Under memory stress, invoke xStress to try to make pages clean. ** Under memory stress, invoke xStress to try to make pages clean.
** Only clean and unpinned pages can be reclaimed. ** Only clean and unpinned pages can be reclaimed.
*/ */
void sqlite3PcacheOpen( int sqlite3PcacheOpen(
int szPage, /* Size of every page */ int szPage, /* Size of every page */
int szExtra, /* Extra space associated with each page */ int szExtra, /* Extra space associated with each page */
int bPurgeable, /* True if pages are on backing store */ int bPurgeable, /* True if pages are on backing store */
@@ -78,7 +78,7 @@ void sqlite3PcacheOpen(
); );
/* Modify the page-size after the cache has been created. */ /* Modify the page-size after the cache has been created. */
void sqlite3PcacheSetPageSize(PCache *, int); int sqlite3PcacheSetPageSize(PCache *, int);
/* Return the size in bytes of a PCache object. Used to preallocate /* Return the size in bytes of a PCache object. Used to preallocate
** storage space. ** storage space.