00001 /* 00002 ** 2008 August 05 00003 ** 00004 ** The author disclaims copyright to this source code. In place of 00005 ** a legal notice, here is a blessing: 00006 ** 00007 ** May you do good and not evil. 00008 ** May you find forgiveness for yourself and forgive others. 00009 ** May you share freely, never taking more than you give. 00010 ** 00011 ************************************************************************* 00012 ** This file implements that page cache. 00013 ** 00014 ** @(#) $Id: pcache.c,v 1.36 2008/11/11 18:43:00 danielk1977 Exp $ 00015 */ 00016 #include "sqliteInt.h" 00017 00018 /* 00019 ** A complete page cache is an instance of this structure. 00020 ** 00021 ** A cache may only be deleted by its owner and while holding the 00022 ** SQLITE_MUTEX_STATUS_LRU mutex. 00023 */ 00024 struct PCache { 00025 /********************************************************************* 00026 ** The first group of elements may be read or written at any time by 00027 ** the cache owner without holding the mutex. No thread other than the 00028 ** cache owner is permitted to access these elements at any time. 00029 */ 00030 PgHdr *pDirty, *pDirtyTail; /* List of dirty pages in LRU order */ 00031 PgHdr *pSynced; /* Last synced page in dirty page list */ 00032 int nRef; /* Number of pinned pages */ 00033 int nPinned; /* Number of pinned and/or dirty pages */ 00034 int nMax; /* Configured cache size */ 00035 int nMin; /* Configured minimum cache size */ 00036 /********************************************************************** 00037 ** The next group of elements are fixed when the cache is created and 00038 ** may not be changed afterwards. These elements can read at any time by 00039 ** the cache owner or by any thread holding the the mutex. Non-owner 00040 ** threads must hold the mutex when reading these elements to prevent 00041 ** the entire PCache object from being deleted during the read. 00042 */ 00043 int szPage; /* Size of every page in this cache */ 00044 int szExtra; /* Size of extra space for each page */ 00045 int bPurgeable; /* True if pages are on backing store */ 00046 int (*xStress)(void*,PgHdr*); /* Call to try make a page clean */ 00047 void *pStress; /* Argument to xStress */ 00048 /********************************************************************** 00049 ** The final group of elements can only be accessed while holding the 00050 ** mutex. Both the cache owner and any other thread must hold the mutex 00051 ** to read or write any of these elements. 00052 */ 00053 int nPage; /* Total number of pages in apHash */ 00054 int nHash; /* Number of slots in apHash[] */ 00055 PgHdr **apHash; /* Hash table for fast lookup by pgno */ 00056 PgHdr *pClean; /* List of clean pages in use */ 00057 }; 00058 00059 /* 00060 ** Free slots in the page block allocator 00061 */ 00062 typedef struct PgFreeslot PgFreeslot; 00063 struct PgFreeslot { 00064 PgFreeslot *pNext; /* Next free slot */ 00065 }; 00066 00067 /* 00068 ** Global data for the page cache. 00069 */ 00070 static SQLITE_WSD struct PCacheGlobal { 00071 int isInit; /* True when initialized */ 00072 sqlite3_mutex *mutex; /* static mutex MUTEX_STATIC_LRU */ 00073 00074 int nMaxPage; /* Sum of nMaxPage for purgeable caches */ 00075 int nMinPage; /* Sum of nMinPage for purgeable caches */ 00076 int nCurrentPage; /* Number of purgeable pages allocated */ 00077 PgHdr *pLruHead, *pLruTail; /* LRU list of unused clean pgs */ 00078 00079 /* Variables related to SQLITE_CONFIG_PAGECACHE settings. */ 00080 int szSlot; /* Size of each free slot */ 00081 void *pStart, *pEnd; /* Bounds of pagecache malloc range */ 00082 PgFreeslot *pFree; /* Free page blocks */ 00083 } pcache = {0}; 00084 00085 /* 00086 ** All code in this file should access the global pcache structure via the 00087 ** alias "pcache_g". This ensures that the WSD emulation is used when 00088 ** compiling for systems that do not support real WSD. 00089 */ 00090 #define pcache_g (GLOBAL(struct PCacheGlobal, pcache)) 00091 00092 /* 00093 ** All global variables used by this module (all of which are grouped 00094 ** together in global structure "pcache" above) are protected by the static 00095 ** SQLITE_MUTEX_STATIC_LRU mutex. A pointer to this mutex is stored in 00096 ** variable "pcache.mutex". 00097 ** 00098 ** Some elements of the PCache and PgHdr structures are protected by the 00099 ** SQLITE_MUTEX_STATUS_LRU mutex and other are not. The protected 00100 ** elements are grouped at the end of the structures and are clearly 00101 ** marked. 00102 ** 00103 ** Use the following macros must surround all access (read or write) 00104 ** of protected elements. The mutex is not recursive and may not be 00105 ** entered more than once. The pcacheMutexHeld() macro should only be 00106 ** used within an assert() to verify that the mutex is being held. 00107 */ 00108 #define pcacheEnterMutex() sqlite3_mutex_enter(pcache_g.mutex) 00109 #define pcacheExitMutex() sqlite3_mutex_leave(pcache_g.mutex) 00110 #define pcacheMutexHeld() sqlite3_mutex_held(pcache_g.mutex) 00111 00112 /* 00113 ** Some of the assert() macros in this code are too expensive to run 00114 ** even during normal debugging. Use them only rarely on long-running 00115 ** tests. Enable the expensive asserts using the 00116 ** -DSQLITE_ENABLE_EXPENSIVE_ASSERT=1 compile-time option. 00117 */ 00118 #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT 00119 # define expensive_assert(X) assert(X) 00120 #else 00121 # define expensive_assert(X) 00122 #endif 00123 00124 /********************************** Linked List Management ********************/ 00125 00126 #if !defined(NDEBUG) && defined(SQLITE_ENABLE_EXPENSIVE_ASSERT) 00127 /* 00128 ** This routine verifies that the number of entries in the hash table 00129 ** is pCache->nPage. This routine is used within assert() statements 00130 ** only and is therefore disabled during production builds. 00131 */ 00132 static int pcacheCheckHashCount(PCache *pCache){ 00133 int i; 00134 int nPage = 0; 00135 for(i=0; i<pCache->nHash; i++){ 00136 PgHdr *p; 00137 for(p=pCache->apHash[i]; p; p=p->pNextHash){ 00138 nPage++; 00139 } 00140 } 00141 assert( nPage==pCache->nPage ); 00142 return 1; 00143 } 00144 #endif /* !NDEBUG && SQLITE_ENABLE_EXPENSIVE_ASSERT */ 00145 00146 00147 #if !defined(NDEBUG) && defined(SQLITE_ENABLE_EXPENSIVE_ASSERT) 00148 /* 00149 ** Based on the current value of PCache.nRef and the contents of the 00150 ** PCache.pDirty list, return the expected value of the PCache.nPinned 00151 ** counter. This is only used in debugging builds, as follows: 00152 ** 00153 ** expensive_assert( pCache->nPinned==pcachePinnedCount(pCache) ); 00154 */ 00155 static int pcachePinnedCount(PCache *pCache){ 00156 PgHdr *p; 00157 int nPinned = pCache->nRef; 00158 for(p=pCache->pDirty; p; p=p->pNext){ 00159 if( p->nRef==0 ){ 00160 nPinned++; 00161 } 00162 } 00163 return nPinned; 00164 } 00165 #endif /* !NDEBUG && SQLITE_ENABLE_EXPENSIVE_ASSERT */ 00166 00167 00168 #if !defined(NDEBUG) && defined(SQLITE_ENABLE_EXPENSIVE_ASSERT) 00169 /* 00170 ** Check that the pCache->pSynced variable is set correctly. If it 00171 ** is not, either fail an assert or return zero. Otherwise, return 00172 ** non-zero. This is only used in debugging builds, as follows: 00173 ** 00174 ** expensive_assert( pcacheCheckSynced(pCache) ); 00175 */ 00176 static int pcacheCheckSynced(PCache *pCache){ 00177 PgHdr *p = pCache->pDirtyTail; 00178 for(p=pCache->pDirtyTail; p!=pCache->pSynced; p=p->pPrev){ 00179 assert( p->nRef || (p->flags&PGHDR_NEED_SYNC) ); 00180 } 00181 return (p==0 || p->nRef || (p->flags&PGHDR_NEED_SYNC)==0); 00182 } 00183 #endif /* !NDEBUG && SQLITE_ENABLE_EXPENSIVE_ASSERT */ 00184 00185 00186 00187 /* 00188 ** Remove a page from its hash table (PCache.apHash[]). 00189 */ 00190 static void pcacheRemoveFromHash(PgHdr *pPage){ 00191 assert( pcacheMutexHeld() ); 00192 if( pPage->pPrevHash ){ 00193 pPage->pPrevHash->pNextHash = pPage->pNextHash; 00194 }else{ 00195 PCache *pCache = pPage->pCache; 00196 u32 h = pPage->pgno % pCache->nHash; 00197 assert( pCache->apHash[h]==pPage ); 00198 pCache->apHash[h] = pPage->pNextHash; 00199 } 00200 if( pPage->pNextHash ){ 00201 pPage->pNextHash->pPrevHash = pPage->pPrevHash; 00202 } 00203 pPage->pCache->nPage--; 00204 expensive_assert( pcacheCheckHashCount(pPage->pCache) ); 00205 } 00206 00207 /* 00208 ** Insert a page into the hash table 00209 ** 00210 ** The mutex must be held by the caller. 00211 */ 00212 static void pcacheAddToHash(PgHdr *pPage){ 00213 PCache *pCache = pPage->pCache; 00214 u32 h = pPage->pgno % pCache->nHash; 00215 assert( pcacheMutexHeld() ); 00216 pPage->pNextHash = pCache->apHash[h]; 00217 pPage->pPrevHash = 0; 00218 if( pCache->apHash[h] ){ 00219 pCache->apHash[h]->pPrevHash = pPage; 00220 } 00221 pCache->apHash[h] = pPage; 00222 pCache->nPage++; 00223 expensive_assert( pcacheCheckHashCount(pCache) ); 00224 } 00225 00226 /* 00227 ** Attempt to increase the size the hash table to contain 00228 ** at least nHash buckets. 00229 */ 00230 static int pcacheResizeHash(PCache *pCache, int nHash){ 00231 PgHdr *p; 00232 PgHdr **pNew; 00233 assert( pcacheMutexHeld() ); 00234 #ifdef SQLITE_MALLOC_SOFT_LIMIT 00235 if( nHash*sizeof(PgHdr*)>SQLITE_MALLOC_SOFT_LIMIT ){ 00236 nHash = SQLITE_MALLOC_SOFT_LIMIT/sizeof(PgHdr *); 00237 } 00238 #endif 00239 pcacheExitMutex(); 00240 pNew = (PgHdr **)sqlite3Malloc(sizeof(PgHdr*)*nHash); 00241 pcacheEnterMutex(); 00242 if( !pNew ){ 00243 return SQLITE_NOMEM; 00244 } 00245 memset(pNew, 0, sizeof(PgHdr *)*nHash); 00246 sqlite3_free(pCache->apHash); 00247 pCache->apHash = pNew; 00248 pCache->nHash = nHash; 00249 pCache->nPage = 0; 00250 00251 for(p=pCache->pClean; p; p=p->pNext){ 00252 pcacheAddToHash(p); 00253 } 00254 for(p=pCache->pDirty; p; p=p->pNext){ 00255 pcacheAddToHash(p); 00256 } 00257 return SQLITE_OK; 00258 } 00259 00260 /* 00261 ** Remove a page from a linked list that is headed by *ppHead. 00262 ** *ppHead is either PCache.pClean or PCache.pDirty. 00263 */ 00264 static void pcacheRemoveFromList(PgHdr **ppHead, PgHdr *pPage){ 00265 int isDirtyList = (ppHead==&pPage->pCache->pDirty); 00266 assert( ppHead==&pPage->pCache->pClean || ppHead==&pPage->pCache->pDirty ); 00267 assert( pcacheMutexHeld() || ppHead!=&pPage->pCache->pClean ); 00268 00269 if( pPage->pPrev ){ 00270 pPage->pPrev->pNext = pPage->pNext; 00271 }else{ 00272 assert( *ppHead==pPage ); 00273 *ppHead = pPage->pNext; 00274 } 00275 if( pPage->pNext ){ 00276 pPage->pNext->pPrev = pPage->pPrev; 00277 } 00278 00279 if( isDirtyList ){ 00280 PCache *pCache = pPage->pCache; 00281 assert( pPage->pNext || pCache->pDirtyTail==pPage ); 00282 if( !pPage->pNext ){ 00283 pCache->pDirtyTail = pPage->pPrev; 00284 } 00285 if( pCache->pSynced==pPage ){ 00286 PgHdr *pSynced = pPage->pPrev; 00287 while( pSynced && (pSynced->flags&PGHDR_NEED_SYNC) ){ 00288 pSynced = pSynced->pPrev; 00289 } 00290 pCache->pSynced = pSynced; 00291 } 00292 } 00293 } 00294 00295 /* 00296 ** Add a page from a linked list that is headed by *ppHead. 00297 ** *ppHead is either PCache.pClean or PCache.pDirty. 00298 */ 00299 static void pcacheAddToList(PgHdr **ppHead, PgHdr *pPage){ 00300 int isDirtyList = (ppHead==&pPage->pCache->pDirty); 00301 assert( ppHead==&pPage->pCache->pClean || ppHead==&pPage->pCache->pDirty ); 00302 00303 if( (*ppHead) ){ 00304 (*ppHead)->pPrev = pPage; 00305 } 00306 pPage->pNext = *ppHead; 00307 pPage->pPrev = 0; 00308 *ppHead = pPage; 00309 00310 if( isDirtyList ){ 00311 PCache *pCache = pPage->pCache; 00312 if( !pCache->pDirtyTail ){ 00313 assert( pPage->pNext==0 ); 00314 pCache->pDirtyTail = pPage; 00315 } 00316 if( !pCache->pSynced && 0==(pPage->flags&PGHDR_NEED_SYNC) ){ 00317 pCache->pSynced = pPage; 00318 } 00319 } 00320 } 00321 00322 /* 00323 ** Remove a page from the global LRU list 00324 */ 00325 static void pcacheRemoveFromLruList(PgHdr *pPage){ 00326 assert( sqlite3_mutex_held(pcache_g.mutex) ); 00327 assert( (pPage->flags&PGHDR_DIRTY)==0 ); 00328 if( pPage->pCache->bPurgeable==0 ) return; 00329 if( pPage->pNextLru ){ 00330 assert( pcache_g.pLruTail!=pPage ); 00331 pPage->pNextLru->pPrevLru = pPage->pPrevLru; 00332 }else{ 00333 assert( pcache_g.pLruTail==pPage ); 00334 pcache_g.pLruTail = pPage->pPrevLru; 00335 } 00336 if( pPage->pPrevLru ){ 00337 assert( pcache_g.pLruHead!=pPage ); 00338 pPage->pPrevLru->pNextLru = pPage->pNextLru; 00339 }else{ 00340 assert( pcache_g.pLruHead==pPage ); 00341 pcache_g.pLruHead = pPage->pNextLru; 00342 } 00343 } 00344 00345 /* 00346 ** Add a page to the global LRU list. The page is normally added 00347 ** to the front of the list so that it will be the last page recycled. 00348 ** However, if the PGHDR_REUSE_UNLIKELY bit is set, the page is added 00349 ** to the end of the LRU list so that it will be the next to be recycled. 00350 */ 00351 static void pcacheAddToLruList(PgHdr *pPage){ 00352 assert( sqlite3_mutex_held(pcache_g.mutex) ); 00353 assert( (pPage->flags&PGHDR_DIRTY)==0 ); 00354 if( pPage->pCache->bPurgeable==0 ) return; 00355 if( pcache_g.pLruTail && (pPage->flags & PGHDR_REUSE_UNLIKELY)!=0 ){ 00356 /* If reuse is unlikely. Put the page at the end of the LRU list 00357 ** where it will be recycled sooner rather than later. 00358 */ 00359 assert( pcache_g.pLruHead ); 00360 pPage->pNextLru = 0; 00361 pPage->pPrevLru = pcache_g.pLruTail; 00362 pcache_g.pLruTail->pNextLru = pPage; 00363 pcache_g.pLruTail = pPage; 00364 pPage->flags &= ~PGHDR_REUSE_UNLIKELY; 00365 }else{ 00366 /* If reuse is possible. the page goes at the beginning of the LRU 00367 ** list so that it will be the last to be recycled. 00368 */ 00369 if( pcache_g.pLruHead ){ 00370 pcache_g.pLruHead->pPrevLru = pPage; 00371 } 00372 pPage->pNextLru = pcache_g.pLruHead; 00373 pcache_g.pLruHead = pPage; 00374 pPage->pPrevLru = 0; 00375 if( pcache_g.pLruTail==0 ){ 00376 pcache_g.pLruTail = pPage; 00377 } 00378 } 00379 } 00380 00381 /*********************************************** Memory Allocation *********** 00382 ** 00383 ** Initialize the page cache memory pool. 00384 ** 00385 ** This must be called at start-time when no page cache lines are 00386 ** checked out. This function is not threadsafe. 00387 */ 00388 void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){ 00389 PgFreeslot *p; 00390 sz &= ~7; 00391 pcache_g.szSlot = sz; 00392 pcache_g.pStart = pBuf; 00393 pcache_g.pFree = 0; 00394 while( n-- ){ 00395 p = (PgFreeslot*)pBuf; 00396 p->pNext = pcache_g.pFree; 00397 pcache_g.pFree = p; 00398 pBuf = (void*)&((char*)pBuf)[sz]; 00399 } 00400 pcache_g.pEnd = pBuf; 00401 } 00402 00403 /* 00404 ** Allocate a page cache line. Look in the page cache memory pool first 00405 ** and use an element from it first if available. If nothing is available 00406 ** in the page cache memory pool, go to the general purpose memory allocator. 00407 */ 00408 static void *pcacheMalloc(int sz, PCache *pCache){ 00409 assert( sqlite3_mutex_held(pcache_g.mutex) ); 00410 if( sz<=pcache_g.szSlot && pcache_g.pFree ){ 00411 PgFreeslot *p = pcache_g.pFree; 00412 pcache_g.pFree = p->pNext; 00413 sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, sz); 00414 sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, 1); 00415 return (void*)p; 00416 }else{ 00417 void *p; 00418 00419 /* Allocate a new buffer using sqlite3Malloc. Before doing so, exit the 00420 ** global pcache mutex and unlock the pager-cache object pCache. This is 00421 ** so that if the attempt to allocate a new buffer causes the the 00422 ** configured soft-heap-limit to be breached, it will be possible to 00423 ** reclaim memory from this pager-cache. 00424 */ 00425 pcacheExitMutex(); 00426 p = sqlite3Malloc(sz); 00427 pcacheEnterMutex(); 00428 00429 if( p ){ 00430 sz = sqlite3MallocSize(p); 00431 sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz); 00432 } 00433 return p; 00434 } 00435 } 00436 void *sqlite3PageMalloc(int sz){ 00437 void *p; 00438 pcacheEnterMutex(); 00439 p = pcacheMalloc(sz, 0); 00440 pcacheExitMutex(); 00441 return p; 00442 } 00443 00444 /* 00445 ** Release a pager memory allocation 00446 */ 00447 static void pcacheFree(void *p){ 00448 assert( sqlite3_mutex_held(pcache_g.mutex) ); 00449 if( p==0 ) return; 00450 if( p>=pcache_g.pStart && p<pcache_g.pEnd ){ 00451 PgFreeslot *pSlot; 00452 sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, -1); 00453 pSlot = (PgFreeslot*)p; 00454 pSlot->pNext = pcache_g.pFree; 00455 pcache_g.pFree = pSlot; 00456 }else{ 00457 int iSize = sqlite3MallocSize(p); 00458 sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -iSize); 00459 sqlite3_free(p); 00460 } 00461 } 00462 void sqlite3PageFree(void *p){ 00463 pcacheEnterMutex(); 00464 pcacheFree(p); 00465 pcacheExitMutex(); 00466 } 00467 00468 /* 00469 ** Allocate a new page. 00470 */ 00471 static PgHdr *pcachePageAlloc(PCache *pCache){ 00472 PgHdr *p; 00473 int sz = sizeof(*p) + pCache->szPage + pCache->szExtra; 00474 assert( sqlite3_mutex_held(pcache_g.mutex) ); 00475 p = pcacheMalloc(sz, pCache); 00476 if( p==0 ) return 0; 00477 memset(p, 0, sizeof(PgHdr)); 00478 p->pData = (void*)&p[1]; 00479 p->pExtra = (void*)&((char*)p->pData)[pCache->szPage]; 00480 if( pCache->bPurgeable ){ 00481 pcache_g.nCurrentPage++; 00482 } 00483 return p; 00484 } 00485 00486 /* 00487 ** Deallocate a page 00488 */ 00489 static void pcachePageFree(PgHdr *p){ 00490 assert( sqlite3_mutex_held(pcache_g.mutex) ); 00491 if( p->pCache->bPurgeable ){ 00492 pcache_g.nCurrentPage--; 00493 } 00494 pcacheFree(p); 00495 } 00496 00497 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT 00498 /* 00499 ** Return the number of bytes that will be returned to the heap when 00500 ** the argument is passed to pcachePageFree(). 00501 */ 00502 static int pcachePageSize(PgHdr *p){ 00503 assert( sqlite3_mutex_held(pcache_g.mutex) ); 00504 assert( !pcache_g.pStart ); 00505 assert( p && p->pCache ); 00506 return sqlite3MallocSize(p); 00507 } 00508 #endif 00509 00510 /* 00511 ** Attempt to 'recycle' a page from the global LRU list. Only clean, 00512 ** unreferenced pages from purgeable caches are eligible for recycling. 00513 ** 00514 ** This function removes page pcache.pLruTail from the global LRU list, 00515 ** and from the hash-table and PCache.pClean list of the owner pcache. 00516 ** There should be no other references to the page. 00517 ** 00518 ** A pointer to the recycled page is returned, or NULL if no page is 00519 ** eligible for recycling. 00520 */ 00521 static PgHdr *pcacheRecyclePage(void){ 00522 PgHdr *p = 0; 00523 assert( sqlite3_mutex_held(pcache_g.mutex) ); 00524 00525 if( (p=pcache_g.pLruTail)!=0 ){ 00526 assert( (p->flags&PGHDR_DIRTY)==0 ); 00527 pcacheRemoveFromLruList(p); 00528 pcacheRemoveFromHash(p); 00529 pcacheRemoveFromList(&p->pCache->pClean, p); 00530 } 00531 00532 return p; 00533 } 00534 00535 /* 00536 ** Obtain space for a page. Try to recycle an old page if the limit on the 00537 ** number of pages has been reached. If the limit has not been reached or 00538 ** there are no pages eligible for recycling, allocate a new page. 00539 ** 00540 ** Return a pointer to the new page, or NULL if an OOM condition occurs. 00541 */ 00542 static int pcacheRecycleOrAlloc(PCache *pCache, PgHdr **ppPage){ 00543 PgHdr *p = 0; 00544 00545 int szPage = pCache->szPage; 00546 int szExtra = pCache->szExtra; 00547 00548 assert( pcache_g.isInit ); 00549 assert( sqlite3_mutex_held(pcache_g.mutex) ); 00550 00551 *ppPage = 0; 00552 00553 /* If we have reached either the global or the local limit for 00554 ** pinned+dirty pages, and there is at least one dirty page, 00555 ** invoke the xStress callback to cause a page to become clean. 00556 */ 00557 expensive_assert( pCache->nPinned==pcachePinnedCount(pCache) ); 00558 expensive_assert( pcacheCheckSynced(pCache) ); 00559 if( pCache->xStress 00560 && pCache->pDirty 00561 && (pCache->nPinned>=(pcache_g.nMaxPage+pCache->nMin-pcache_g.nMinPage) 00562 || pCache->nPinned>=pCache->nMax) 00563 ){ 00564 PgHdr *pPg; 00565 assert(pCache->pDirtyTail); 00566 00567 for(pPg=pCache->pSynced; 00568 pPg && (pPg->nRef || (pPg->flags&PGHDR_NEED_SYNC)); 00569 pPg=pPg->pPrev 00570 ); 00571 if( !pPg ){ 00572 for(pPg=pCache->pDirtyTail; pPg && pPg->nRef; pPg=pPg->pPrev); 00573 } 00574 if( pPg ){ 00575 int rc; 00576 pcacheExitMutex(); 00577 rc = pCache->xStress(pCache->pStress, pPg); 00578 pcacheEnterMutex(); 00579 if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){ 00580 return rc; 00581 } 00582 } 00583 } 00584 00585 /* If either the local or the global page limit has been reached, 00586 ** try to recycle a page. 00587 */ 00588 if( pCache->bPurgeable && (pCache->nPage>=pCache->nMax-1 || 00589 pcache_g.nCurrentPage>=pcache_g.nMaxPage) ){ 00590 p = pcacheRecyclePage(); 00591 } 00592 00593 /* If a page has been recycled but it is the wrong size, free it. */ 00594 if( p && (p->pCache->szPage!=szPage || p->pCache->szPage!=szExtra) ){ 00595 pcachePageFree(p); 00596 p = 0; 00597 } 00598 00599 if( !p ){ 00600 p = pcachePageAlloc(pCache); 00601 } 00602 00603 *ppPage = p; 00604 return (p?SQLITE_OK:SQLITE_NOMEM); 00605 } 00606 00607 /*************************************************** General Interfaces ****** 00608 ** 00609 ** Initialize and shutdown the page cache subsystem. Neither of these 00610 ** functions are threadsafe. 00611 */ 00612 int sqlite3PcacheInitialize(void){ 00613 assert( pcache_g.isInit==0 ); 00614 memset(&pcache_g, 0, sizeof(pcache)); 00615 if( sqlite3GlobalConfig.bCoreMutex ){ 00616 /* No need to check the return value of sqlite3_mutex_alloc(). 00617 ** Allocating a static mutex cannot fail. 00618 */ 00619 pcache_g.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU); 00620 } 00621 pcache_g.isInit = 1; 00622 return SQLITE_OK; 00623 } 00624 void sqlite3PcacheShutdown(void){ 00625 memset(&pcache_g, 0, sizeof(pcache)); 00626 } 00627 00628 /* 00629 ** Return the size in bytes of a PCache object. 00630 */ 00631 int sqlite3PcacheSize(void){ return sizeof(PCache); } 00632 00633 /* 00634 ** Create a new PCache object. Storage space to hold the object 00635 ** has already been allocated and is passed in as the p pointer. 00636 */ 00637 void sqlite3PcacheOpen( 00638 int szPage, /* Size of every page */ 00639 int szExtra, /* Extra space associated with each page */ 00640 int bPurgeable, /* True if pages are on backing store */ 00641 int (*xStress)(void*,PgHdr*),/* Call to try to make pages clean */ 00642 void *pStress, /* Argument to xStress */ 00643 PCache *p /* Preallocated space for the PCache */ 00644 ){ 00645 assert( pcache_g.isInit ); 00646 memset(p, 0, sizeof(PCache)); 00647 p->szPage = szPage; 00648 p->szExtra = szExtra; 00649 p->bPurgeable = bPurgeable; 00650 p->xStress = xStress; 00651 p->pStress = pStress; 00652 p->nMax = 100; 00653 p->nMin = 10; 00654 00655 pcacheEnterMutex(); 00656 if( bPurgeable ){ 00657 pcache_g.nMaxPage += p->nMax; 00658 pcache_g.nMinPage += p->nMin; 00659 } 00660 00661 pcacheExitMutex(); 00662 } 00663 00664 /* 00665 ** Change the page size for PCache object. This can only happen 00666 ** when the cache is empty. 00667 */ 00668 void sqlite3PcacheSetPageSize(PCache *pCache, int szPage){ 00669 assert(pCache->nPage==0); 00670 pCache->szPage = szPage; 00671 } 00672 00673 /* 00674 ** Try to obtain a page from the cache. 00675 */ 00676 int sqlite3PcacheFetch( 00677 PCache *pCache, /* Obtain the page from this cache */ 00678 Pgno pgno, /* Page number to obtain */ 00679 int createFlag, /* If true, create page if it does not exist already */ 00680 PgHdr **ppPage /* Write the page here */ 00681 ){ 00682 int rc = SQLITE_OK; 00683 PgHdr *pPage = 0; 00684 00685 assert( pcache_g.isInit ); 00686 assert( pCache!=0 ); 00687 assert( pgno>0 ); 00688 expensive_assert( pCache->nPinned==pcachePinnedCount(pCache) ); 00689 00690 pcacheEnterMutex(); 00691 00692 /* Search the hash table for the requested page. Exit early if it is found. */ 00693 if( pCache->apHash ){ 00694 u32 h = pgno % pCache->nHash; 00695 for(pPage=pCache->apHash[h]; pPage; pPage=pPage->pNextHash){ 00696 if( pPage->pgno==pgno ){ 00697 if( pPage->nRef==0 ){ 00698 if( 0==(pPage->flags&PGHDR_DIRTY) ){ 00699 pcacheRemoveFromLruList(pPage); 00700 pCache->nPinned++; 00701 } 00702 pCache->nRef++; 00703 } 00704 pPage->nRef++; 00705 break; 00706 } 00707 } 00708 } 00709 00710 if( !pPage && createFlag ){ 00711 if( pCache->nHash<=pCache->nPage ){ 00712 rc = pcacheResizeHash(pCache, pCache->nHash<256 ? 256 : pCache->nHash*2); 00713 } 00714 if( rc==SQLITE_OK ){ 00715 rc = pcacheRecycleOrAlloc(pCache, &pPage); 00716 } 00717 if( rc==SQLITE_OK ){ 00718 pPage->pPager = 0; 00719 pPage->flags = 0; 00720 pPage->pDirty = 0; 00721 pPage->pgno = pgno; 00722 pPage->pCache = pCache; 00723 pPage->nRef = 1; 00724 pCache->nRef++; 00725 pCache->nPinned++; 00726 pcacheAddToList(&pCache->pClean, pPage); 00727 pcacheAddToHash(pPage); 00728 } 00729 } 00730 00731 pcacheExitMutex(); 00732 00733 *ppPage = pPage; 00734 expensive_assert( pCache->nPinned==pcachePinnedCount(pCache) ); 00735 assert( pPage || !createFlag || rc!=SQLITE_OK ); 00736 return rc; 00737 } 00738 00739 /* 00740 ** Dereference a page. When the reference count reaches zero, 00741 ** move the page to the LRU list if it is clean. 00742 */ 00743 void sqlite3PcacheRelease(PgHdr *p){ 00744 assert( p->nRef>0 ); 00745 p->nRef--; 00746 if( p->nRef==0 ){ 00747 PCache *pCache = p->pCache; 00748 pCache->nRef--; 00749 if( (p->flags&PGHDR_DIRTY)==0 ){ 00750 pCache->nPinned--; 00751 pcacheEnterMutex(); 00752 if( pcache_g.nCurrentPage>pcache_g.nMaxPage ){ 00753 pcacheRemoveFromList(&pCache->pClean, p); 00754 pcacheRemoveFromHash(p); 00755 pcachePageFree(p); 00756 }else{ 00757 pcacheAddToLruList(p); 00758 } 00759 pcacheExitMutex(); 00760 }else{ 00761 /* Move the page to the head of the caches dirty list. */ 00762 pcacheRemoveFromList(&pCache->pDirty, p); 00763 pcacheAddToList(&pCache->pDirty, p); 00764 } 00765 } 00766 } 00767 00768 void sqlite3PcacheRef(PgHdr *p){ 00769 assert(p->nRef>0); 00770 p->nRef++; 00771 } 00772 00773 /* 00774 ** Drop a page from the cache. There must be exactly one reference to the 00775 ** page. This function deletes that reference, so after it returns the 00776 ** page pointed to by p is invalid. 00777 */ 00778 void sqlite3PcacheDrop(PgHdr *p){ 00779 PCache *pCache; 00780 assert( p->nRef==1 ); 00781 assert( 0==(p->flags&PGHDR_DIRTY) ); 00782 pCache = p->pCache; 00783 pCache->nRef--; 00784 pCache->nPinned--; 00785 pcacheEnterMutex(); 00786 pcacheRemoveFromList(&pCache->pClean, p); 00787 pcacheRemoveFromHash(p); 00788 pcachePageFree(p); 00789 pcacheExitMutex(); 00790 } 00791 00792 /* 00793 ** Make sure the page is marked as dirty. If it isn't dirty already, 00794 ** make it so. 00795 */ 00796 void sqlite3PcacheMakeDirty(PgHdr *p){ 00797 PCache *pCache; 00798 p->flags &= ~PGHDR_DONT_WRITE; 00799 if( p->flags & PGHDR_DIRTY ) return; 00800 assert( (p->flags & PGHDR_DIRTY)==0 ); 00801 assert( p->nRef>0 ); 00802 pCache = p->pCache; 00803 pcacheEnterMutex(); 00804 pcacheRemoveFromList(&pCache->pClean, p); 00805 pcacheAddToList(&pCache->pDirty, p); 00806 pcacheExitMutex(); 00807 p->flags |= PGHDR_DIRTY; 00808 } 00809 00810 static void pcacheMakeClean(PgHdr *p){ 00811 PCache *pCache = p->pCache; 00812 assert( p->flags & PGHDR_DIRTY ); 00813 pcacheRemoveFromList(&pCache->pDirty, p); 00814 pcacheAddToList(&pCache->pClean, p); 00815 p->flags &= ~PGHDR_DIRTY; 00816 if( p->nRef==0 ){ 00817 pcacheAddToLruList(p); 00818 pCache->nPinned--; 00819 } 00820 expensive_assert( pCache->nPinned==pcachePinnedCount(pCache) ); 00821 } 00822 00823 /* 00824 ** Make sure the page is marked as clean. If it isn't clean already, 00825 ** make it so. 00826 */ 00827 void sqlite3PcacheMakeClean(PgHdr *p){ 00828 if( (p->flags & PGHDR_DIRTY) ){ 00829 pcacheEnterMutex(); 00830 pcacheMakeClean(p); 00831 pcacheExitMutex(); 00832 } 00833 } 00834 00835 /* 00836 ** Make every page in the cache clean. 00837 */ 00838 void sqlite3PcacheCleanAll(PCache *pCache){ 00839 PgHdr *p; 00840 pcacheEnterMutex(); 00841 while( (p = pCache->pDirty)!=0 ){ 00842 pcacheRemoveFromList(&pCache->pDirty, p); 00843 p->flags &= ~PGHDR_DIRTY; 00844 pcacheAddToList(&pCache->pClean, p); 00845 if( p->nRef==0 ){ 00846 pcacheAddToLruList(p); 00847 pCache->nPinned--; 00848 } 00849 } 00850 sqlite3PcacheAssertFlags(pCache, 0, PGHDR_DIRTY); 00851 expensive_assert( pCache->nPinned==pcachePinnedCount(pCache) ); 00852 pcacheExitMutex(); 00853 } 00854 00855 /* 00856 ** Change the page number of page p to newPgno. If newPgno is 0, then the 00857 ** page object is added to the clean-list and the PGHDR_REUSE_UNLIKELY 00858 ** flag set. 00859 */ 00860 void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){ 00861 assert( p->nRef>0 ); 00862 pcacheEnterMutex(); 00863 pcacheRemoveFromHash(p); 00864 p->pgno = newPgno; 00865 if( newPgno==0 ){ 00866 if( (p->flags & PGHDR_DIRTY) ){ 00867 pcacheMakeClean(p); 00868 } 00869 p->flags = PGHDR_REUSE_UNLIKELY; 00870 } 00871 pcacheAddToHash(p); 00872 pcacheExitMutex(); 00873 } 00874 00875 /* 00876 ** Remove all content from a page cache 00877 */ 00878 static void pcacheClear(PCache *pCache){ 00879 PgHdr *p, *pNext; 00880 assert( sqlite3_mutex_held(pcache_g.mutex) ); 00881 for(p=pCache->pClean; p; p=pNext){ 00882 pNext = p->pNext; 00883 pcacheRemoveFromLruList(p); 00884 pcachePageFree(p); 00885 } 00886 for(p=pCache->pDirty; p; p=pNext){ 00887 pNext = p->pNext; 00888 pcachePageFree(p); 00889 } 00890 pCache->pClean = 0; 00891 pCache->pDirty = 0; 00892 pCache->pDirtyTail = 0; 00893 pCache->nPage = 0; 00894 pCache->nPinned = 0; 00895 memset(pCache->apHash, 0, pCache->nHash*sizeof(pCache->apHash[0])); 00896 } 00897 00898 00899 /* 00900 ** Drop every cache entry whose page number is greater than "pgno". 00901 */ 00902 void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){ 00903 PgHdr *p, *pNext; 00904 PgHdr *pDirty = pCache->pDirty; 00905 pcacheEnterMutex(); 00906 for(p=pCache->pClean; p||pDirty; p=pNext){ 00907 if( !p ){ 00908 p = pDirty; 00909 pDirty = 0; 00910 } 00911 pNext = p->pNext; 00912 if( p->pgno>pgno ){ 00913 if( p->nRef==0 ){ 00914 pcacheRemoveFromHash(p); 00915 if( p->flags&PGHDR_DIRTY ){ 00916 pcacheRemoveFromList(&pCache->pDirty, p); 00917 pCache->nPinned--; 00918 }else{ 00919 pcacheRemoveFromList(&pCache->pClean, p); 00920 pcacheRemoveFromLruList(p); 00921 } 00922 pcachePageFree(p); 00923 }else{ 00924 /* If there are references to the page, it cannot be freed. In this 00925 ** case, zero the page content instead. 00926 */ 00927 memset(p->pData, 0, pCache->szPage); 00928 } 00929 } 00930 } 00931 pcacheExitMutex(); 00932 } 00933 00934 /* 00935 ** If there are currently more than pcache.nMaxPage pages allocated, try 00936 ** to recycle pages to reduce the number allocated to pcache.nMaxPage. 00937 */ 00938 static void pcacheEnforceMaxPage(void){ 00939 PgHdr *p; 00940 assert( sqlite3_mutex_held(pcache_g.mutex) ); 00941 while( pcache_g.nCurrentPage>pcache_g.nMaxPage 00942 && (p = pcacheRecyclePage())!=0 ){ 00943 pcachePageFree(p); 00944 } 00945 } 00946 00947 /* 00948 ** Close a cache. 00949 */ 00950 void sqlite3PcacheClose(PCache *pCache){ 00951 pcacheEnterMutex(); 00952 00953 /* Free all the pages used by this pager and remove them from the LRU list. */ 00954 pcacheClear(pCache); 00955 if( pCache->bPurgeable ){ 00956 pcache_g.nMaxPage -= pCache->nMax; 00957 pcache_g.nMinPage -= pCache->nMin; 00958 pcacheEnforceMaxPage(); 00959 } 00960 sqlite3_free(pCache->apHash); 00961 pcacheExitMutex(); 00962 } 00963 00964 00965 #ifndef NDEBUG 00966 /* 00967 ** Assert flags settings on all pages. Debugging only. 00968 */ 00969 void sqlite3PcacheAssertFlags(PCache *pCache, int trueMask, int falseMask){ 00970 PgHdr *p; 00971 for(p=pCache->pDirty; p; p=p->pNext){ 00972 assert( (p->flags&trueMask)==trueMask ); 00973 assert( (p->flags&falseMask)==0 ); 00974 } 00975 for(p=pCache->pClean; p; p=p->pNext){ 00976 assert( (p->flags&trueMask)==trueMask ); 00977 assert( (p->flags&falseMask)==0 ); 00978 } 00979 } 00980 #endif 00981 00982 /* 00983 ** Discard the contents of the cache. 00984 */ 00985 int sqlite3PcacheClear(PCache *pCache){ 00986 assert(pCache->nRef==0); 00987 pcacheEnterMutex(); 00988 pcacheClear(pCache); 00989 pcacheExitMutex(); 00990 return SQLITE_OK; 00991 } 00992 00993 /* 00994 ** Merge two lists of pages connected by pDirty and in pgno order. 00995 ** Do not both fixing the pPrevDirty pointers. 00996 */ 00997 static PgHdr *pcacheMergeDirtyList(PgHdr *pA, PgHdr *pB){ 00998 PgHdr result, *pTail; 00999 pTail = &result; 01000 while( pA && pB ){ 01001 if( pA->pgno<pB->pgno ){ 01002 pTail->pDirty = pA; 01003 pTail = pA; 01004 pA = pA->pDirty; 01005 }else{ 01006 pTail->pDirty = pB; 01007 pTail = pB; 01008 pB = pB->pDirty; 01009 } 01010 } 01011 if( pA ){ 01012 pTail->pDirty = pA; 01013 }else if( pB ){ 01014 pTail->pDirty = pB; 01015 }else{ 01016 pTail->pDirty = 0; 01017 } 01018 return result.pDirty; 01019 } 01020 01021 /* 01022 ** Sort the list of pages in accending order by pgno. Pages are 01023 ** connected by pDirty pointers. The pPrevDirty pointers are 01024 ** corrupted by this sort. 01025 */ 01026 #define N_SORT_BUCKET_ALLOC 25 01027 #define N_SORT_BUCKET 25 01028 #ifdef SQLITE_TEST 01029 int sqlite3_pager_n_sort_bucket = 0; 01030 #undef N_SORT_BUCKET 01031 #define N_SORT_BUCKET \ 01032 (sqlite3_pager_n_sort_bucket?sqlite3_pager_n_sort_bucket:N_SORT_BUCKET_ALLOC) 01033 #endif 01034 static PgHdr *pcacheSortDirtyList(PgHdr *pIn){ 01035 PgHdr *a[N_SORT_BUCKET_ALLOC], *p; 01036 int i; 01037 memset(a, 0, sizeof(a)); 01038 while( pIn ){ 01039 p = pIn; 01040 pIn = p->pDirty; 01041 p->pDirty = 0; 01042 for(i=0; i<N_SORT_BUCKET-1; i++){ 01043 if( a[i]==0 ){ 01044 a[i] = p; 01045 break; 01046 }else{ 01047 p = pcacheMergeDirtyList(a[i], p); 01048 a[i] = 0; 01049 } 01050 } 01051 if( i==N_SORT_BUCKET-1 ){ 01052 /* Coverage: To get here, there need to be 2^(N_SORT_BUCKET) 01053 ** elements in the input list. This is possible, but impractical. 01054 ** Testing this line is the point of global variable 01055 ** sqlite3_pager_n_sort_bucket. 01056 */ 01057 a[i] = pcacheMergeDirtyList(a[i], p); 01058 } 01059 } 01060 p = a[0]; 01061 for(i=1; i<N_SORT_BUCKET; i++){ 01062 p = pcacheMergeDirtyList(p, a[i]); 01063 } 01064 return p; 01065 } 01066 01067 /* 01068 ** Return a list of all dirty pages in the cache, sorted by page number. 01069 */ 01070 PgHdr *sqlite3PcacheDirtyList(PCache *pCache){ 01071 PgHdr *p; 01072 for(p=pCache->pDirty; p; p=p->pNext){ 01073 p->pDirty = p->pNext; 01074 } 01075 return pcacheSortDirtyList(pCache->pDirty); 01076 } 01077 01078 /* 01079 ** Return the total number of outstanding page references. 01080 */ 01081 int sqlite3PcacheRefCount(PCache *pCache){ 01082 return pCache->nRef; 01083 } 01084 01085 int sqlite3PcachePageRefcount(PgHdr *p){ 01086 return p->nRef; 01087 } 01088 01089 /* 01090 ** Return the total number of pages in the cache. 01091 */ 01092 int sqlite3PcachePagecount(PCache *pCache){ 01093 assert( pCache->nPage>=0 ); 01094 return pCache->nPage; 01095 } 01096 01097 #ifdef SQLITE_CHECK_PAGES 01098 /* 01099 ** This function is used by the pager.c module to iterate through all 01100 ** pages in the cache. At present, this is only required if the 01101 ** SQLITE_CHECK_PAGES macro (used for debugging) is specified. 01102 */ 01103 void sqlite3PcacheIterate(PCache *pCache, void (*xIter)(PgHdr *)){ 01104 PgHdr *p; 01105 for(p=pCache->pClean; p; p=p->pNext){ 01106 xIter(p); 01107 } 01108 for(p=pCache->pDirty; p; p=p->pNext){ 01109 xIter(p); 01110 } 01111 } 01112 #endif 01113 01114 /* 01115 ** Set flags on all pages in the page cache 01116 */ 01117 void sqlite3PcacheClearFlags(PCache *pCache, int mask){ 01118 PgHdr *p; 01119 01120 /* Obtain the global mutex before modifying any PgHdr.flags variables 01121 ** or traversing the LRU list. 01122 */ 01123 pcacheEnterMutex(); 01124 01125 mask = ~mask; 01126 for(p=pCache->pDirty; p; p=p->pNext){ 01127 p->flags &= mask; 01128 } 01129 for(p=pCache->pClean; p; p=p->pNext){ 01130 p->flags &= mask; 01131 } 01132 01133 if( 0==(mask&PGHDR_NEED_SYNC) ){ 01134 pCache->pSynced = pCache->pDirtyTail; 01135 assert( !pCache->pSynced || (pCache->pSynced->flags&PGHDR_NEED_SYNC)==0 ); 01136 } 01137 01138 pcacheExitMutex(); 01139 } 01140 01141 /* 01142 ** Set the suggested cache-size value. 01143 */ 01144 int sqlite3PcacheGetCachesize(PCache *pCache){ 01145 return pCache->nMax; 01146 } 01147 01148 /* 01149 ** Set the suggested cache-size value. 01150 */ 01151 void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){ 01152 if( mxPage<10 ){ 01153 mxPage = 10; 01154 } 01155 if( pCache->bPurgeable ){ 01156 pcacheEnterMutex(); 01157 pcache_g.nMaxPage -= pCache->nMax; 01158 pcache_g.nMaxPage += mxPage; 01159 pcacheEnforceMaxPage(); 01160 pcacheExitMutex(); 01161 } 01162 pCache->nMax = mxPage; 01163 } 01164 01165 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT 01166 /* 01167 ** This function is called to free superfluous dynamically allocated memory 01168 ** held by the pager system. Memory in use by any SQLite pager allocated 01169 ** by the current thread may be sqlite3_free()ed. 01170 ** 01171 ** nReq is the number of bytes of memory required. Once this much has 01172 ** been released, the function returns. The return value is the total number 01173 ** of bytes of memory released. 01174 */ 01175 int sqlite3PcacheReleaseMemory(int nReq){ 01176 int nFree = 0; 01177 if( pcache_g.pStart==0 ){ 01178 PgHdr *p; 01179 pcacheEnterMutex(); 01180 while( (nReq<0 || nFree<nReq) && (p=pcacheRecyclePage()) ){ 01181 nFree += pcachePageSize(p); 01182 pcachePageFree(p); 01183 } 01184 pcacheExitMutex(); 01185 } 01186 return nFree; 01187 } 01188 #endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */ 01189 01190 #ifdef SQLITE_TEST 01191 void sqlite3PcacheStats( 01192 int *pnCurrent, 01193 int *pnMax, 01194 int *pnMin, 01195 int *pnRecyclable 01196 ){ 01197 PgHdr *p; 01198 int nRecyclable = 0; 01199 for(p=pcache_g.pLruHead; p; p=p->pNextLru){ 01200 nRecyclable++; 01201 } 01202 01203 *pnCurrent = pcache_g.nCurrentPage; 01204 *pnMax = pcache_g.nMaxPage; 01205 *pnMin = pcache_g.nMinPage; 01206 *pnRecyclable = nRecyclable; 01207 } 01208 #endif
ContextLogger2—ContextLogger2 Logger Daemon Internals—Generated on Mon May 2 13:49:55 2011 by Doxygen 1.6.1