/* ** Dereference a page. When the reference count reaches zero, ** move the page to the LRU list if it is clean. */ void sqlite3PcacheRelease(PgHdr *p) { assert( p->nRef>0 ); p->nRef--; if( p->nRef==0 ) { PCache *pCache = p->pCache; if( p->pCache->xDestroy ) { p->pCache->xDestroy(p); } pCache->nRef--; if( (p->flags&PGHDR_DIRTY)==0 ) { pCache->nPinned--; pcacheEnterMutex(); 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. */ pcacheRemoveFromList(&pCache->pDirty, p); pcacheAddToList(&pCache->pDirty, p); } } }
static void pcacheMakeClean(PgHdr *p){ PCache *pCache = p->pCache; assert( p->flags & PGHDR_DIRTY ); pcacheRemoveFromList(&pCache->pDirty, p); pcacheAddToList(&pCache->pClean, p); p->flags &= ~PGHDR_DIRTY; if( p->nRef==0 ){ pcacheAddToLruList(p); pCache->nPinned--; } expensive_assert( pCache->nPinned==pcachePinnedCount(pCache) ); }
/* ** Make every page in the cache clean. */ void sqlite3PcacheCleanAll(PCache *pCache){ PgHdr *p; pcacheEnterMutex(); while( (p = pCache->pDirty)!=0 ){ pcacheRemoveFromList(&pCache->pDirty, p); p->flags &= ~PGHDR_DIRTY; pcacheAddToList(&pCache->pClean, p); if( p->nRef==0 ){ pcacheAddToLruList(p); pCache->nPinned--; } } sqlite3PcacheAssertFlags(pCache, 0, PGHDR_DIRTY); expensive_assert( pCache->nPinned==pcachePinnedCount(pCache) ); pcacheExitMutex(); }