/* ** If there are currently more than nMaxPage pages allocated, try ** to recycle pages to reduce the number allocated to nMaxPage. */ static void pcache1EnforceMaxPage(PGroup pGroup) { Debug.Assert(sqlite3_mutex_held(pGroup.mutex)); while (pGroup.nCurrentPage > pGroup.nMaxPage && pGroup.pLruTail != null) { PgHdr1 p = pGroup.pLruTail; Debug.Assert(p.pCache.pGroup == pGroup); pcache1PinPage(p); pcache1RemoveFromHash(p); pcache1FreePage(ref p); } }
/* ** Implementation of the sqlite3_pcache.xCachesize method. ** ** Configure the cache_size limit for a cache. */ static void pcache1Cachesize(sqlite3_pcache p, int nMax) { PCache1 pCache = (PCache1)p; if (pCache.bPurgeable) { PGroup pGroup = pCache.pGroup; pcache1EnterMutex(pGroup); pGroup.nMaxPage += nMax - pCache.nMax; pGroup.mxPinned = pGroup.nMaxPage + 10 - pGroup.nMinPage; pCache.nMax = nMax; pCache.n90pct = pCache.nMax * 9 / 10; pcache1EnforceMaxPage(pGroup); pcache1LeaveMutex(pGroup); } }
/* ** Implementation of the sqlite3_pcache.xDestroy method. ** ** Destroy a cache allocated using pcache1Create(). */ static void pcache1Destroy(ref sqlite3_pcache p) { PCache1 pCache = (PCache1)p; PGroup pGroup = pCache.pGroup; Debug.Assert(pCache.bPurgeable || (pCache.nMax == 0 && pCache.nMin == 0)); pcache1EnterMutex(pGroup); pcache1TruncateUnsafe(pCache, 0); pGroup.nMaxPage -= pCache.nMax; pGroup.nMinPage -= pCache.nMin; pGroup.mxPinned = pGroup.nMaxPage + 10 - pGroup.nMinPage; pcache1EnforceMaxPage(pGroup); pcache1LeaveMutex(pGroup); //sqlite3_free( pCache.apHash ); //sqlite3_free( pCache ); p = null; }
/* ** Implementation of the sqlite3_pcache.xUnpin method. ** ** Mark a page as unpinned (eligible for asynchronous recycling). */ static void pcache1Unpin(sqlite3_pcache p, PgHdr pPg, bool reuseUnlikely) { PCache1 pCache = (PCache1)p; PgHdr1 pPage = PAGE_TO_PGHDR1(pCache, pPg); PGroup pGroup = pCache.pGroup; Debug.Assert(pPage.pCache == pCache); pcache1EnterMutex(pGroup); /* It is an error to call this function if the page is already ** part of the PGroup LRU list. */ Debug.Assert(pPage.pLruPrev == null && pPage.pLruNext == null); Debug.Assert(pGroup.pLruHead != pPage && pGroup.pLruTail != pPage); if (reuseUnlikely || pGroup.nCurrentPage > pGroup.nMaxPage) { pcache1RemoveFromHash(pPage); pcache1FreePage(ref pPage); } else { /* Add the page to the PGroup LRU list. */ if (pGroup.pLruHead != null) { pGroup.pLruHead.pLruPrev = pPage; pPage.pLruNext = pGroup.pLruHead; pGroup.pLruHead = pPage; } else { pGroup.pLruTail = pPage; pGroup.pLruHead = pPage; } pCache.nRecyclable++; } pcache1LeaveMutex(pCache.pGroup); }
//#define pcache1LeaveMutex(X) sqlite3_mutex_leave((X).mutex) static void pcache1LeaveMutex(PGroup X) { sqlite3_mutex_leave(X.mutex); }
/* ** Macros to enter and leave the PCache LRU mutex. */ //#define pcache1EnterMutex(X) sqlite3_mutex_enter((X).mutex) static void pcache1EnterMutex(PGroup X) { sqlite3_mutex_enter(X.mutex); }
public bool bUnderPressure; /* True if low on PAGECACHE memory */ // C# public PCacheGlobal() { grp = new PGroup(); }