1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-19 21:43:15 +03:00

If a page is made eligible for recycling when more than the configured maximum number of pages are allocated, free it immediately instead of adding it to the LRU list. (CVS 5638)

FossilOrigin-Name: 4b12922dcb4547bf3a7276d0542b2e1d12ad338d
This commit is contained in:
danielk1977
2008-08-29 09:10:02 +00:00
parent 8b213899e8
commit 062d4cb0ae
6 changed files with 234 additions and 15 deletions

View File

@@ -11,7 +11,7 @@
*************************************************************************
** This file implements that page cache.
**
** @(#) $Id: pcache.c,v 1.23 2008/08/28 17:46:19 drh Exp $
** @(#) $Id: pcache.c,v 1.24 2008/08/29 09:10:03 danielk1977 Exp $
*/
#include "sqliteInt.h"
@@ -748,7 +748,13 @@ void sqlite3PcacheRelease(PgHdr *p){
if( (p->flags&PGHDR_DIRTY)==0 ){
pCache->nPinned--;
pcacheEnterMutex();
pcacheAddToLruList(p);
if( pcache.nCurrentPage>pcache.nMaxPage ){
pcacheRemoveFromList(&pCache->pClean, p);
pcacheRemoveFromHash(p);
pcachePageFree(p);
}else{
pcacheAddToLruList(p);
}
pcacheExitMutex();
}else{
/* Move the page to the head of the caches dirty list. */
@@ -930,6 +936,17 @@ void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){
pcacheExitMutex();
}
/*
** If there are currently more than pcache.nMaxPage pages allocated, try
** to recycle pages to reduce the number allocated to pcache.nMaxPage.
*/
static void pcacheEnforceMaxPage(){
PgHdr *p;
assert( sqlite3_mutex_held(pcache.mutex) );
while( pcache.nCurrentPage>pcache.nMaxPage && (p = pcacheRecyclePage()) ){
pcachePageFree(p);
}
}
/*
** Close a cache.
@@ -942,9 +959,9 @@ void sqlite3PcacheClose(PCache *pCache){
if( pCache->bPurgeable ){
pcache.nMaxPage -= pCache->nMax;
pcache.nMinPage -= pCache->nMin;
pcacheEnforceMaxPage();
}
sqlite3_free(pCache->apHash);
pcacheExitMutex();
}
@@ -1193,6 +1210,7 @@ void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){
pcacheEnterMutex();
pcache.nMaxPage -= pCache->nMax;
pcache.nMaxPage += mxPage;
pcacheEnforceMaxPage();
pcacheExitMutex();
}
pCache->nMax = mxPage;
@@ -1222,3 +1240,24 @@ int sqlite3PcacheReleaseMemory(int nReq){
return nFree;
}
#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */
#ifdef SQLITE_TEST
void sqlite3PcacheStats(
int *pnCurrent,
int *pnMax,
int *pnMin,
int *pnRecyclable
){
PgHdr *p;
int nRecyclable = 0;
for(p=pcache.pLruHead; p; p=p->pNextLru){
nRecyclable++;
}
*pnCurrent = pcache.nCurrentPage;
*pnMax = pcache.nMaxPage;
*pnMin = pcache.nMinPage;
*pnRecyclable = nRecyclable;
}
#endif

View File

@@ -12,7 +12,7 @@
** This header file defines the interface that the sqlite page cache
** subsystem.
**
** @(#) $Id: pcache.h,v 1.8 2008/08/28 02:26:07 drh Exp $
** @(#) $Id: pcache.h,v 1.9 2008/08/29 09:10:03 danielk1977 Exp $
*/
#ifndef _PCACHE_H_
@@ -161,4 +161,6 @@ void sqlite3PcacheSetCachesize(PCache *, int);
/* Try to return memory used by the pcache module to the main memory heap */
int sqlite3PcacheReleaseMemory(int);
void sqlite3PcacheStats(int*,int*,int*,int*);
#endif /* _PCACHE_H_ */

View File

@@ -13,7 +13,7 @@
** is not included in the SQLite library. It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.320 2008/08/27 15:21:34 drh Exp $
** $Id: test1.c,v 1.321 2008/08/29 09:10:03 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
@@ -4501,6 +4501,38 @@ static int reset_prng_state(
return TCL_OK;
}
/*
** tclcmd: pcache_stats
*/
static int test_pcache_stats(
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int objc, /* Number of arguments */
Tcl_Obj *CONST objv[] /* Command arguments */
){
int nMin;
int nMax;
int nCurrent;
int nRecyclable;
Tcl_Obj *pRet;
sqlite3PcacheStats(&nCurrent, &nMax, &nMin, &nRecyclable);
pRet = Tcl_NewObj();
Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("current", -1));
Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(nCurrent));
Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("max", -1));
Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(nMax));
Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("min", -1));
Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(nMin));
Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("recyclable", -1));
Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(nRecyclable));
Tcl_SetObjResult(interp, pRet);
return TCL_OK;
}
/*
** Register commands with the TCL interpreter.
@@ -4675,6 +4707,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "sqlite3_blob_read", test_blob_read, 0 },
{ "sqlite3_blob_write", test_blob_write, 0 },
#endif
{ "pcache_stats", test_pcache_stats, 0 },
};
static int bitmask_size = sizeof(Bitmask)*8;
int i;