diff options
Diffstat (limited to 'src/pcache.c')
-rw-r--r-- | src/pcache.c | 105 |
1 files changed, 65 insertions, 40 deletions
diff --git a/src/pcache.c b/src/pcache.c index f37511e..482a188 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -20,7 +20,7 @@ struct PCache { PgHdr *pDirty, *pDirtyTail; /* List of dirty pages in LRU order */ PgHdr *pSynced; /* Last synced page in dirty page list */ int nRef; /* Number of referenced pages */ - int nMax; /* Configured cache size */ + int szCache; /* Configured cache size */ int szPage; /* Size of every page in this cache */ int szExtra; /* Size of extra space for each page */ int bPurgeable; /* True if pages are on backing store */ @@ -131,7 +131,7 @@ static void pcacheUnpin(PgHdr *p){ if( p->pgno==1 ){ pCache->pPage1 = 0; } - sqlite3GlobalConfig.pcache.xUnpin(pCache->pCache, p, 0); + sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, p->pPage, 0); } } @@ -141,18 +141,18 @@ static void pcacheUnpin(PgHdr *p){ ** functions are threadsafe. */ int sqlite3PcacheInitialize(void){ - if( sqlite3GlobalConfig.pcache.xInit==0 ){ + if( sqlite3GlobalConfig.pcache2.xInit==0 ){ /* IMPLEMENTATION-OF: R-26801-64137 If the xInit() method is NULL, then the ** built-in default page cache is used instead of the application defined ** page cache. */ sqlite3PCacheSetDefault(); } - return sqlite3GlobalConfig.pcache.xInit(sqlite3GlobalConfig.pcache.pArg); + return sqlite3GlobalConfig.pcache2.xInit(sqlite3GlobalConfig.pcache2.pArg); } void sqlite3PcacheShutdown(void){ - if( sqlite3GlobalConfig.pcache.xShutdown ){ + if( sqlite3GlobalConfig.pcache2.xShutdown ){ /* IMPLEMENTATION-OF: R-26000-56589 The xShutdown() method may be NULL. */ - sqlite3GlobalConfig.pcache.xShutdown(sqlite3GlobalConfig.pcache.pArg); + sqlite3GlobalConfig.pcache2.xShutdown(sqlite3GlobalConfig.pcache2.pArg); } } @@ -181,7 +181,7 @@ void sqlite3PcacheOpen( p->bPurgeable = bPurgeable; p->xStress = xStress; p->pStress = pStress; - p->nMax = 100; + p->szCache = 100; } /* @@ -191,7 +191,7 @@ void sqlite3PcacheOpen( void sqlite3PcacheSetPageSize(PCache *pCache, int szPage){ assert( pCache->nRef==0 && pCache->pDirty==0 ); if( pCache->pCache ){ - sqlite3GlobalConfig.pcache.xDestroy(pCache->pCache); + sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache); pCache->pCache = 0; pCache->pPage1 = 0; } @@ -199,6 +199,17 @@ void sqlite3PcacheSetPageSize(PCache *pCache, int 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)); + } +} + +/* ** Try to obtain a page from the cache. */ int sqlite3PcacheFetch( @@ -207,7 +218,8 @@ int sqlite3PcacheFetch( int createFlag, /* If true, create page if it does not exist already */ PgHdr **ppPage /* Write the page here */ ){ - PgHdr *pPage = 0; + sqlite3_pcache_page *pPage = 0; + PgHdr *pPgHdr = 0; int eCreate; assert( pCache!=0 ); @@ -219,19 +231,19 @@ int sqlite3PcacheFetch( */ if( !pCache->pCache && createFlag ){ sqlite3_pcache *p; - int nByte; - nByte = pCache->szPage + pCache->szExtra + sizeof(PgHdr); - p = sqlite3GlobalConfig.pcache.xCreate(nByte, pCache->bPurgeable); + p = sqlite3GlobalConfig.pcache2.xCreate( + pCache->szPage, pCache->szExtra + sizeof(PgHdr), pCache->bPurgeable + ); if( !p ){ return SQLITE_NOMEM; } - sqlite3GlobalConfig.pcache.xCachesize(p, pCache->nMax); + sqlite3GlobalConfig.pcache2.xCachesize(p, numberOfCachePages(pCache)); pCache->pCache = p; } eCreate = createFlag * (1 + (!pCache->bPurgeable || !pCache->pDirty)); if( pCache->pCache ){ - pPage = sqlite3GlobalConfig.pcache.xFetch(pCache->pCache, pgno, eCreate); + pPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate); } if( !pPage && eCreate==1 ){ @@ -258,7 +270,7 @@ int sqlite3PcacheFetch( "spill page %d making room for %d - cache used: %d/%d", pPg->pgno, pgno, sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache), - pCache->nMax); + numberOfCachePages(pCache)); #endif rc = pCache->xStress(pCache->pStress, pPg); if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){ @@ -266,33 +278,36 @@ int sqlite3PcacheFetch( } } - pPage = sqlite3GlobalConfig.pcache.xFetch(pCache->pCache, pgno, 2); + pPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2); } if( pPage ){ - if( !pPage->pData ){ - memset(pPage, 0, sizeof(PgHdr)); - pPage->pData = (void *)&pPage[1]; - pPage->pExtra = (void*)&((char *)pPage->pData)[pCache->szPage]; - memset(pPage->pExtra, 0, pCache->szExtra); - pPage->pCache = pCache; - pPage->pgno = pgno; + pPgHdr = (PgHdr *)pPage->pExtra; + + if( !pPgHdr->pPage ){ + memset(pPgHdr, 0, sizeof(PgHdr)); + pPgHdr->pPage = pPage; + pPgHdr->pData = pPage->pBuf; + pPgHdr->pExtra = (void *)&pPgHdr[1]; + memset(pPgHdr->pExtra, 0, pCache->szExtra); + pPgHdr->pCache = pCache; + pPgHdr->pgno = pgno; } - assert( pPage->pCache==pCache ); - assert( pPage->pgno==pgno ); - assert( pPage->pData==(void *)&pPage[1] ); - assert( pPage->pExtra==(void *)&((char *)&pPage[1])[pCache->szPage] ); + assert( pPgHdr->pCache==pCache ); + assert( pPgHdr->pgno==pgno ); + assert( pPgHdr->pData==pPage->pBuf ); + assert( pPgHdr->pExtra==(void *)&pPgHdr[1] ); - if( 0==pPage->nRef ){ + if( 0==pPgHdr->nRef ){ pCache->nRef++; } - pPage->nRef++; + pPgHdr->nRef++; if( pgno==1 ){ - pCache->pPage1 = pPage; + pCache->pPage1 = pPgHdr; } } - *ppPage = pPage; - return (pPage==0 && eCreate) ? SQLITE_NOMEM : SQLITE_OK; + *ppPage = pPgHdr; + return (pPgHdr==0 && eCreate) ? SQLITE_NOMEM : SQLITE_OK; } /* @@ -339,7 +354,7 @@ void sqlite3PcacheDrop(PgHdr *p){ if( p->pgno==1 ){ pCache->pPage1 = 0; } - sqlite3GlobalConfig.pcache.xUnpin(pCache->pCache, p, 1); + sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, p->pPage, 1); } /* @@ -397,7 +412,7 @@ void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){ PCache *pCache = p->pCache; assert( p->nRef>0 ); assert( newPgno>0 ); - sqlite3GlobalConfig.pcache.xRekey(pCache->pCache, p, p->pgno, newPgno); + sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno); p->pgno = newPgno; if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){ pcacheRemoveFromDirtyList(p); @@ -434,7 +449,7 @@ void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){ memset(pCache->pPage1->pData, 0, pCache->szPage); pgno = 1; } - sqlite3GlobalConfig.pcache.xTruncate(pCache->pCache, pgno+1); + sqlite3GlobalConfig.pcache2.xTruncate(pCache->pCache, pgno+1); } } @@ -443,7 +458,7 @@ void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){ */ void sqlite3PcacheClose(PCache *pCache){ if( pCache->pCache ){ - sqlite3GlobalConfig.pcache.xDestroy(pCache->pCache); + sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache); } } @@ -555,7 +570,7 @@ int sqlite3PcachePageRefcount(PgHdr *p){ int sqlite3PcachePagecount(PCache *pCache){ int nPage = 0; if( pCache->pCache ){ - nPage = sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache); + nPage = sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache); } return nPage; } @@ -565,7 +580,7 @@ int sqlite3PcachePagecount(PCache *pCache){ ** Get the suggested cache-size value. */ int sqlite3PcacheGetCachesize(PCache *pCache){ - return pCache->nMax; + return numberOfCachePages(pCache); } #endif @@ -573,9 +588,19 @@ int sqlite3PcacheGetCachesize(PCache *pCache){ ** Set the suggested cache-size value. */ void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){ - pCache->nMax = mxPage; + pCache->szCache = mxPage; + if( pCache->pCache ){ + sqlite3GlobalConfig.pcache2.xCachesize(pCache->pCache, + numberOfCachePages(pCache)); + } +} + +/* +** Free up as much memory as possible from the page cache. +*/ +void sqlite3PcacheShrink(PCache *pCache){ if( pCache->pCache ){ - sqlite3GlobalConfig.pcache.xCachesize(pCache->pCache, mxPage); + sqlite3GlobalConfig.pcache2.xShrink(pCache->pCache); } } |