blob: 89fc85354fdd7bc0b234c25fc85a858be974c652 [file] [log] [blame]
danielk19778c0a7912008-08-20 14:49:23 +00001/*
2** 2008 August 05
3**
4** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
6**
7** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
10**
11*************************************************************************
12** This file implements that page cache.
13**
danielk197767e3da72008-08-21 12:19:44 +000014** @(#) $Id: pcache.c,v 1.4 2008/08/21 12:19:44 danielk1977 Exp $
danielk19778c0a7912008-08-20 14:49:23 +000015*/
16#include "sqliteInt.h"
17
18/*
19** A complete page cache is an instance of this structure.
20*/
21struct PCache {
22 PCache *pNextAll, *pPrevAll; /* List of all page caches */
23 int szPage; /* Size of every page in this cache */
24 int szExtra; /* Size of extra space for each page */
25 int nHash; /* Number of slots in apHash[] */
26 int nPage; /* Total number of pages in apHash */
27 int nMax; /* Configured cache size */
28 PgHdr **apHash; /* Hash table for fast lookup by pgno */
29 int bPurgeable; /* True if pages are on backing store */
30 void (*xDestroy)(PgHdr*); /* Called when refcnt goes 1->0 */
31 int (*xStress)(void*); /* Call to try to make pages clean */
32 void *pStress; /* Argument to xStress */
33 PgHdr *pClean; /* List of clean pages in use */
34 PgHdr *pDirty; /* List of dirty pages */
35 int nRef; /* Number of outstanding page refs */
36
37 int iInUseMM;
38 int iInUseDB;
39};
40
41/*
42** Free slots in the page block allocator
43*/
44typedef struct PgFreeslot PgFreeslot;
45struct PgFreeslot {
46 PgFreeslot *pNext; /* Next free slot */
47};
48
49/*
50** Global data for the page cache.
51**
52** The maximum number of cached pages stored by the system is determined
53** by the pcache.mxPage and pcache.mxPagePurgeable variables. If
54** mxPage is non-zero, then the system tries to limit the number of
55** cached pages stored to mxPage. In this case mxPagePurgeable is not
56** used.
57**
58** If mxPage is zero, then the system tries to limit the number of
59** pages held by purgable caches to mxPagePurgeable.
60*/
61static struct PCacheGlobal {
62 int isInit; /* True when initialized */
63 sqlite3_mutex *mutex_mem2; /* static mutex MUTEX_STATIC_MEM2 */
64 sqlite3_mutex *mutex_lru; /* static mutex MUTEX_STATIC_LRU */
65 PCache *pAll; /* list of all page caches */
66 int nPage; /* Number of pages */
67 int nPurgeable; /* Number of pages in purgable caches */
drh41d30272008-08-20 21:47:45 +000068 int mxPage; /* Globally configured page maximum */
danielk19778c0a7912008-08-20 14:49:23 +000069 int mxPagePurgeable; /* Purgeable page maximum */
70 PgHdr *pLruHead, *pLruTail; /* Global LRU list of unused pages */
71 int szSlot; /* Size of each free slot */
72 void *pStart, *pEnd; /* Bounds of pagecache malloc range */
73 PgFreeslot *pFree; /* Free page blocks */
74} pcache = {0};
75
76/*
77** All global variables used by this module (most of which are grouped
78** together in global structure "pcache" above) except the list of all
79** pager-caches starting with pcache.pAll, are protected by the static
80** SQLITE_MUTEX_STATIC_LRU mutex. A pointer to this mutex is stored in
81** variable "pcache.mutex_lru".
82**
83** The list of all pager-caches (PCache structures) headed by pcache.pAll
84** is protected by SQLITE_MUTEX_STATIC_MEM2.
85**
86** Access to the contents of the individual PCache structures is not
87** protected. It is the job of the caller to ensure that these structures
88** are accessed in a thread-safe manner. However, this module provides the
89** functions sqlite3PcacheLock() and sqlite3PcacheUnlock() that may be used
90** by the caller to increment/decrement a lock-count on an individual
91** pager-cache object. This module guarantees that the xStress() callback
92** will not be invoked on a pager-cache with a non-zero lock-count except
93** from within a call to sqlite3PcacheFetch() on the same pager. A call
94** to sqlite3PcacheLock() may block if such an xStress() call is currently
95** underway.
96**
97** Before the xStress callback of a pager-cache (PCache) is invoked, the
98** SQLITE_MUTEX_STATIC_MEM2 mutex is obtained and the SQLITE_MUTEX_STATIC_LRU
99** mutex released (in that order) before making the call.
100*/
101
drh41d30272008-08-20 21:47:45 +0000102#define pcacheEnterGlobal() sqlite3_mutex_enter(pcache.mutex_lru)
103#define pcacheExitGlobal() sqlite3_mutex_leave(pcache.mutex_lru)
danielk19778c0a7912008-08-20 14:49:23 +0000104
105/*
106** Increment the reference count on both page p and its cache by n.
107*/
drh41d30272008-08-20 21:47:45 +0000108static void pcacheRef(PgHdr *p, int n){
danielk19778c0a7912008-08-20 14:49:23 +0000109 /* This next block assert()s that the number of references to the
110 ** PCache is the sum of the number of references to all pages in
111 ** the PCache. This is a bit expensive to leave turned on all the
112 ** time, even in debugging builds.
113 */
114#if 0
115 PgHdr *pHdr;
116 int nRef = 0;
117 for(pHdr=p->pCache->pClean; pHdr; pHdr=pHdr->pNext) nRef += pHdr->nRef;
118 for(pHdr=p->pCache->pDirty; pHdr; pHdr=pHdr->pNext) nRef += pHdr->nRef;
119 assert( p->pCache->nRef==nRef );
120#endif
121 p->nRef += n;
122 p->pCache->nRef += n;
123}
124
125/********************************** Linked List Management ********************/
126
drh41d30272008-08-20 21:47:45 +0000127#ifndef NDEBUG
128/*
129** This routine verifies that the number of entries in the hash table
130** is pCache->nPage. This routine is used within assert() statements
131** only and is therefore disabled during production builds.
132*/
133static int pcacheCheckHashCount(PCache *pCache){
danielk19778c0a7912008-08-20 14:49:23 +0000134 int i;
135 int nPage = 0;
136 for(i=0; i<pCache->nHash; i++){
137 PgHdr *p;
138 for(p=pCache->apHash[i]; p; p=p->pNextHash){
139 nPage++;
140 }
141 }
142 assert( nPage==pCache->nPage );
143 return 1;
144}
drh41d30272008-08-20 21:47:45 +0000145#endif
danielk19778c0a7912008-08-20 14:49:23 +0000146
147/*
148** Remove a page from its hash table (PCache.apHash[]).
149*/
150static void pcacheRemoveFromHash(PgHdr *pPage){
151 if( pPage->pPrevHash ){
152 pPage->pPrevHash->pNextHash = pPage->pNextHash;
153 }else{
154 PCache *pCache = pPage->pCache;
155 u32 h = pPage->pgno % pCache->nHash;
156 assert( pCache->apHash[h]==pPage );
157 pCache->apHash[h] = pPage->pNextHash;
158 }
159 if( pPage->pNextHash ){
160 pPage->pNextHash->pPrevHash = pPage->pPrevHash;
161 }
162 pPage->pCache->nPage--;
drh41d30272008-08-20 21:47:45 +0000163 assert( pcacheCheckHashCount(pPage->pCache) );
danielk19778c0a7912008-08-20 14:49:23 +0000164}
165
166/*
167** Insert a page into the hash table
168*/
169static void pcacheAddToHash(PgHdr *pPage){
170 PCache *pCache = pPage->pCache;
171 u32 h = pPage->pgno % pCache->nHash;
172 pPage->pNextHash = pCache->apHash[h];
173 pPage->pPrevHash = 0;
174 if( pCache->apHash[h] ){
175 pCache->apHash[h]->pPrevHash = pPage;
176 }
177 pCache->apHash[h] = pPage;
178 pCache->nPage++;
drh41d30272008-08-20 21:47:45 +0000179 assert( pcacheCheckHashCount(pCache) );
danielk19778c0a7912008-08-20 14:49:23 +0000180}
181
182/*
drh41d30272008-08-20 21:47:45 +0000183** Attempt to increase the size the hash table to contain
184** at least nHash buckets.
danielk19778c0a7912008-08-20 14:49:23 +0000185*/
186static int pcacheResizeHash(PCache *pCache, int nHash){
187#ifdef SQLITE_MALLOC_SOFT_LIMIT
drh41d30272008-08-20 21:47:45 +0000188 if( nHash*sizeof(PgHdr*)>SQLITE_MALLOC_SOFT_LIMIT ){
danielk19778c0a7912008-08-20 14:49:23 +0000189 nHash = SQLITE_MALLOC_SOFT_LIMIT/sizeof(PgHdr *);
190 }
191#endif
192 if( nHash>pCache->nHash ){
193 PgHdr *p;
drh41d30272008-08-20 21:47:45 +0000194 PgHdr **pNew = (PgHdr **)sqlite3_malloc(sizeof(PgHdr*)*nHash);
danielk19778c0a7912008-08-20 14:49:23 +0000195 if( !pNew ){
196 return SQLITE_NOMEM;
197 }
198 memset(pNew, 0, sizeof(PgHdr *)*nHash);
199 sqlite3_free(pCache->apHash);
200 pCache->apHash = pNew;
201 pCache->nHash = nHash;
202 pCache->nPage = 0;
203
204 for(p=pCache->pClean; p; p=p->pNext){
205 pcacheAddToHash(p);
206 }
207 for(p=pCache->pDirty; p; p=p->pNext){
208 pcacheAddToHash(p);
209 }
210 }
211 return SQLITE_OK;
212}
213
214/*
215** Remove a page from a linked list that is headed by *ppHead.
216** *ppHead is either PCache.pClean or PCache.pDirty.
217*/
218static void pcacheRemoveFromList(PgHdr **ppHead, PgHdr *pPage){
219 if( pPage->pPrev ){
220 pPage->pPrev->pNext = pPage->pNext;
221 }else{
222 assert( *ppHead==pPage );
223 *ppHead = pPage->pNext;
224 }
225 if( pPage->pNext ){
226 pPage->pNext->pPrev = pPage->pPrev;
227 }
228}
229
230/*
231** Add a page from a linked list that is headed by *ppHead.
232** *ppHead is either PCache.pClean or PCache.pDirty.
233*/
234static void pcacheAddToList(PgHdr **ppHead, PgHdr *pPage){
235 if( (*ppHead) ){
236 (*ppHead)->pPrev = pPage;
237 }
238 pPage->pNext = *ppHead;
239 pPage->pPrev = 0;
240 *ppHead = pPage;
241}
242
243/*
244** Remove a page from the global LRU list
245*/
246static void pcacheRemoveFromLruList(PgHdr *pPage){
247 assert( sqlite3_mutex_held(pcache.mutex_lru) );
248 if( pPage->pCache->bPurgeable==0 ) return;
249 if( pPage->pNextLru ){
250 pPage->pNextLru->pPrevLru = pPage->pPrevLru;
251 }else{
252 assert( pcache.pLruTail==pPage );
253 pcache.pLruTail = pPage->pPrevLru;
254 }
255 if( pPage->pPrevLru ){
256 pPage->pPrevLru->pNextLru = pPage->pNextLru;
257 }else{
258 assert( pcache.pLruHead==pPage );
259 pcache.pLruHead = pPage->pNextLru;
260 }
261}
262
263/*
264** Add a page to the global LRU list. The page is normally added
265** to the front of the list so that it will be the last page recycled.
266** However, if the PGHDR_REUSE_UNLIKELY bit is set, the page is added
267** to the end of the LRU list so that it will be the next to be recycled.
268*/
269static void pcacheAddToLruList(PgHdr *pPage){
270 assert( sqlite3_mutex_held(pcache.mutex_lru) );
271 if( pPage->pCache->bPurgeable==0 ) return;
272 if( pcache.pLruTail && (pPage->flags & PGHDR_REUSE_UNLIKELY)!=0 ){
273 /* If reuse is unlikely. Put the page at the end of the LRU list
274 ** where it will be recycled sooner rather than later.
275 */
276 assert( pcache.pLruHead );
277 pPage->pNextLru = 0;
278 pPage->pPrevLru = pcache.pLruTail;
279 pcache.pLruTail->pNextLru = pPage;
280 pcache.pLruTail = pPage;
281 pPage->flags &= ~PGHDR_REUSE_UNLIKELY;
282 }else{
283 /* If reuse is possible. the page goes at the beginning of the LRU
284 ** list so that it will be the last to be recycled.
285 */
286 if( pcache.pLruHead ){
287 pcache.pLruHead->pPrevLru = pPage;
288 }
289 pPage->pNextLru = pcache.pLruHead;
290 pcache.pLruHead = pPage;
291 pPage->pPrevLru = 0;
292 if( pcache.pLruTail==0 ){
293 pcache.pLruTail = pPage;
294 }
295 }
296}
297
298/*********************************************** Memory Allocation ***********
299**
300** Initialize the page cache memory pool.
301**
302** This must be called at start-time when no page cache lines are
303** checked out. This function is not threadsafe.
304*/
305void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){
306 PgFreeslot *p;
307 sz &= ~7;
308 pcache.szSlot = sz;
309 pcache.pStart = pBuf;
310 pcache.pFree = 0;
311 while( n-- ){
312 p = (PgFreeslot*)pBuf;
313 p->pNext = pcache.pFree;
314 pcache.pFree = p;
315 pBuf = (void*)&((char*)pBuf)[sz];
316 }
317 pcache.pEnd = pBuf;
318}
319
320/*
321** Allocate a page cache line. Look in the page cache memory pool first
322** and use an element from it first if available. If nothing is available
323** in the page cache memory pool, go to the general purpose memory allocator.
324*/
325void *pcacheMalloc(int sz){
326 assert( sqlite3_mutex_held(pcache.mutex_lru) );
327 if( sz<=pcache.szSlot && pcache.pFree ){
328 PgFreeslot *p = pcache.pFree;
329 pcache.pFree = p->pNext;
330 sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, sz);
331 sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, 1);
332 return (void*)p;
333 }else{
danielk197767e3da72008-08-21 12:19:44 +0000334 void *p;
335 pcacheExitGlobal();
336 p = sqlite3Malloc(sz);
337 pcacheEnterGlobal();
danielk19778c0a7912008-08-20 14:49:23 +0000338 if( p ){
339 sz = sqlite3MallocSize(p);
340 sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
341 }
342 return p;
343 }
344}
345void *sqlite3PageMalloc(sz){
346 void *p;
drh41d30272008-08-20 21:47:45 +0000347 pcacheEnterGlobal();
danielk19778c0a7912008-08-20 14:49:23 +0000348 p = pcacheMalloc(sz);
drh41d30272008-08-20 21:47:45 +0000349 pcacheExitGlobal();
danielk19778c0a7912008-08-20 14:49:23 +0000350 return p;
351}
352
353/*
354** Release a pager memory allocation
355*/
356void pcacheFree(void *p){
357 assert( sqlite3_mutex_held(pcache.mutex_lru) );
358 if( p==0 ) return;
359 if( p>=pcache.pStart && p<pcache.pEnd ){
360 PgFreeslot *pSlot;
361 sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, -1);
362 pSlot = (PgFreeslot*)p;
363 pSlot->pNext = pcache.pFree;
364 pcache.pFree = pSlot;
365 }else{
366 int iSize = sqlite3MallocSize(p);
367 sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -iSize);
368 sqlite3_free(p);
369 }
370}
371void sqlite3PageFree(void *p){
drh41d30272008-08-20 21:47:45 +0000372 pcacheEnterGlobal();
danielk19778c0a7912008-08-20 14:49:23 +0000373 pcacheFree(p);
drh41d30272008-08-20 21:47:45 +0000374 pcacheExitGlobal();
danielk19778c0a7912008-08-20 14:49:23 +0000375}
376
377/*
378** Allocate a new page.
379*/
380static PgHdr *pcachePageAlloc(int szPage, int szExtra, int bPurgeable){
381 PgHdr *p;
382 int sz = sizeof(*p) + szPage + szExtra;
383 assert( sqlite3_mutex_held(pcache.mutex_lru) );
384 p = pcacheMalloc( sz );
385 if( p==0 ) return 0;
386 memset(p, 0, sizeof(PgHdr));
387 p->pData = (void*)&p[1];
388 p->pExtra = (void*)&((char*)p->pData)[szPage];
389
390 pcache.nPage++;
391 if( bPurgeable ){
392 pcache.nPurgeable++;
393 }
394
395 return p;
396}
397
398/*
399** Deallocate a page
400*/
401static void pcachePageFree(PgHdr *p){
402 assert( sqlite3_mutex_held(pcache.mutex_lru) );
403 pcache.nPage--;
404 if( p->pCache->bPurgeable ){
405 pcache.nPurgeable--;
406 }
407 pcacheFree(p->apSave[0]);
408 pcacheFree(p->apSave[1]);
409 pcacheFree(p);
410}
411
412/*
danielk197767e3da72008-08-21 12:19:44 +0000413** Return the number of bytes that will be returned to the heap when
414** the argument is passed to pcachePageFree().
415*/
416static int pcachePageSize(PgHdr *p){
417 assert( sqlite3_mutex_held(pcache.mutex_lru) );
418 assert( !pcache.pStart );
419 assert( p->apSave[0]==0 );
420 assert( p->apSave[1]==0 );
421 assert( p && p->pCache );
422 return sqlite3MallocSize(p);
423}
424
425static PgHdr *pcacheRecycle(PCache *pCache){
426 PCache *pCsr;
427 PgHdr *p = 0;
428
429 assert( pcache.isInit );
430 assert( sqlite3_mutex_held(pcache.mutex_lru) );
431
432 if( !pcache.pLruTail && SQLITE_OK==sqlite3_mutex_try(pcache.mutex_mem2) ){
433
434 /* Invoke xStress() callbacks until the LRU list contains at least one
435 ** page that can be reused or until the xStress() callback of all
436 ** caches has been invoked.
437 */
438 for(pCsr=pcache.pAll; pCsr&&!pcache.pLruTail; pCsr=pCsr->pNextAll){
439 assert( pCsr->iInUseMM==0 );
440 pCsr->iInUseMM = 1;
441 if( pCsr->xStress && (pCsr->iInUseDB==0 || pCache==pCsr) ){
442 pcacheExitGlobal();
443 pCsr->xStress(pCsr->pStress);
444 pcacheEnterGlobal();
445 }
446 pCsr->iInUseMM = 0;
447 }
448
449 sqlite3_mutex_leave(pcache.mutex_mem2);
450 }
451
452 p = pcache.pLruTail;
453
454 if( p ){
455 pcacheRemoveFromLruList(p);
456 pcacheRemoveFromHash(p);
457 pcacheRemoveFromList(&p->pCache->pClean, p);
458
459 /* If the always-rollback flag is set on the page being recycled, set
460 ** the always-rollback flag on the corresponding pager.
461 */
462 if( p->flags&PGHDR_ALWAYS_ROLLBACK ){
463 assert(p->pPager);
464 sqlite3PagerAlwaysRollback(p->pPager);
465 }
466 }
467
468 return p;
469}
470
471/*
danielk19778c0a7912008-08-20 14:49:23 +0000472** Obtain space for a page. Try to recycle an old page if the limit on the
473** number of pages has been reached. If the limit has not been reached or
474** there are no pages eligible for recycling, allocate a new page.
475**
476** Return a pointer to the new page, or NULL if an OOM condition occurs.
477*/
478static PgHdr *pcacheRecycleOrAlloc(PCache *pCache){
479 PgHdr *p = 0;
480
481 int szPage = pCache->szPage;
482 int szExtra = pCache->szExtra;
483 int bPurg = pCache->bPurgeable;
484
485 assert( pcache.isInit );
486 assert( sqlite3_mutex_notheld(pcache.mutex_lru) );
487
drh41d30272008-08-20 21:47:45 +0000488 pcacheEnterGlobal();
danielk19778c0a7912008-08-20 14:49:23 +0000489
490 if( (pcache.mxPage && pcache.nPage>=pcache.mxPage)
491 || (!pcache.mxPage && bPurg && pcache.nPurgeable>=pcache.mxPagePurgeable)
492 ){
danielk197767e3da72008-08-21 12:19:44 +0000493 /* If the above test succeeds, then try to obtain a buffer by recycling
494 ** an existing page. */
495 p = pcacheRecycle(pCache);
danielk19778c0a7912008-08-20 14:49:23 +0000496 }
497
danielk197767e3da72008-08-21 12:19:44 +0000498 if( p && (p->pCache->szPage!=szPage || p->pCache->szExtra!=szExtra) ){
499 pcachePageFree(p);
500 p = 0;
danielk19778c0a7912008-08-20 14:49:23 +0000501 }
502
503 if( !p ){
504 /* Allocate a new page object. */
505 p = pcachePageAlloc(szPage, szExtra, bPurg);
506 }
507
drh41d30272008-08-20 21:47:45 +0000508 pcacheExitGlobal();
danielk19778c0a7912008-08-20 14:49:23 +0000509 return p;
510}
511
512/*************************************************** General Interfaces ******
513**
514** Initialize and shutdown the page cache subsystem. Neither of these
515** functions are threadsafe.
516*/
517int sqlite3PcacheInitialize(void){
518 assert( pcache.isInit==0 );
519 memset(&pcache, 0, sizeof(pcache));
520 if( sqlite3Config.bCoreMutex ){
521 pcache.mutex_lru = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU);
522 pcache.mutex_mem2 = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM2);
523 if( pcache.mutex_lru==0 || pcache.mutex_mem2==0 ){
524 return SQLITE_NOMEM;
525 }
526 }
527 pcache.isInit = 1;
528 return SQLITE_OK;
529}
530void sqlite3PcacheShutdown(void){
531 memset(&pcache, 0, sizeof(pcache));
532}
533
534/*
535** Return the size in bytes of a PCache object.
536*/
537int sqlite3PcacheSize(void){ return sizeof(PCache); }
538
539/*
540** Create a new PCache object. Storage space to hold the object
541** has already been allocated and is passed in as the p pointer.
542*/
543void sqlite3PcacheOpen(
544 int szPage, /* Size of every page */
545 int szExtra, /* Extra space associated with each page */
546 int bPurgeable, /* True if pages are on backing store */
547 void (*xDestroy)(PgHdr*), /* Called to destroy a page */
548 int (*xStress)(void*), /* Call to try to make pages clean */
549 void *pStress, /* Argument to xStress */
550 PCache *p /* Preallocated space for the PCache */
551){
552 assert( pcache.isInit );
553 memset(p, 0, sizeof(PCache));
554 p->szPage = szPage;
555 p->szExtra = szExtra;
556 p->bPurgeable = bPurgeable;
557 p->xDestroy = xDestroy;
558 p->xStress = xStress;
559 p->pStress = pStress;
560 p->nMax = 100;
561
562 if( bPurgeable ){
drh41d30272008-08-20 21:47:45 +0000563 pcacheEnterGlobal();
danielk19778c0a7912008-08-20 14:49:23 +0000564 pcache.mxPagePurgeable += p->nMax;
drh41d30272008-08-20 21:47:45 +0000565 pcacheExitGlobal();
danielk19778c0a7912008-08-20 14:49:23 +0000566 }
567
568 /* Add the new pager-cache to the list of caches starting at pcache.pAll */
569 sqlite3_mutex_enter(pcache.mutex_mem2);
570 p->pNextAll = pcache.pAll;
571 if( pcache.pAll ){
572 pcache.pAll->pPrevAll = p;
573 }
574 p->pPrevAll = 0;
575 pcache.pAll = p;
576 sqlite3_mutex_leave(pcache.mutex_mem2);
577}
578
drh41d30272008-08-20 21:47:45 +0000579/*
580** Change the page size for PCache object. This can only happen
581** when the cache is empty.
582*/
danielk19778c0a7912008-08-20 14:49:23 +0000583void sqlite3PcacheSetPageSize(PCache *pCache, int szPage){
584 assert(pCache->nPage==0);
585 pCache->szPage = szPage;
586}
587
588/*
589** Try to obtain a page from the cache.
590*/
591int sqlite3PcacheFetch(
592 PCache *pCache, /* Obtain the page from this cache */
593 Pgno pgno, /* Page number to obtain */
594 int createFlag, /* If true, create page if it does not exist already */
595 PgHdr **ppPage /* Write the page here */
596){
597 PgHdr *pPage;
598 assert( pcache.isInit );
599 assert( pCache!=0 );
600 assert( pgno>0 );
601 assert( pCache->iInUseDB || pCache->iInUseMM );
602
603 /* Search the hash table for the requested page. Exit early if it is found. */
604 if( pCache->apHash ){
605 u32 h = pgno % pCache->nHash;
606 for(pPage=pCache->apHash[h]; pPage; pPage=pPage->pNextHash){
607 if( pPage->pgno==pgno ){
608 if( pPage->nRef==0 && (pPage->flags & PGHDR_DIRTY)==0 ){
drh41d30272008-08-20 21:47:45 +0000609 pcacheEnterGlobal();
danielk19778c0a7912008-08-20 14:49:23 +0000610 pcacheRemoveFromLruList(pPage);
drh41d30272008-08-20 21:47:45 +0000611 pcacheExitGlobal();
danielk19778c0a7912008-08-20 14:49:23 +0000612 }
drh41d30272008-08-20 21:47:45 +0000613 pcacheRef(pPage, 1);
danielk19778c0a7912008-08-20 14:49:23 +0000614 *ppPage = pPage;
615 return SQLITE_OK;
616 }
617 }
618 }
619
620 if( createFlag ){
621 if( pCache->nHash<=pCache->nPage ){
622 int rc = pcacheResizeHash(pCache, pCache->nHash<256?256:pCache->nHash*2);
623 if( rc!=SQLITE_OK ){
624 return rc;
625 }
626 }
627
628 pPage = pcacheRecycleOrAlloc(pCache);
629 *ppPage = pPage;
630 if( pPage==0 ){
631 return SQLITE_NOMEM;
632 }
633
634 pPage->pPager = 0;
635 pPage->flags = 0;
636 pPage->pDirty = 0;
637 pPage->nRef = 0;
638 pPage->pgno = pgno;
639 pPage->pCache = pCache;
drh41d30272008-08-20 21:47:45 +0000640 pcacheRef(pPage, 1);
danielk19778c0a7912008-08-20 14:49:23 +0000641 pcacheAddToList(&pCache->pClean, pPage);
642 pcacheAddToHash(pPage);
643 }else{
644 *ppPage = 0;
645 }
646
647 return SQLITE_OK;
648}
649
650/*
651** Dereference a page. When the reference count reaches zero,
652** move the page to the LRU list if it is clean.
653*/
654void sqlite3PcacheRelease(PgHdr *p){
655 assert( p->nRef>0 );
656 assert( p->pCache->iInUseDB || p->pCache->iInUseMM );
drh41d30272008-08-20 21:47:45 +0000657 pcacheRef(p, -1);
danielk19778c0a7912008-08-20 14:49:23 +0000658 if( p->nRef!=0 ) return;
659 if( p->pCache->xDestroy ){
660 p->pCache->xDestroy(p);
661 }
662 if( (p->flags & PGHDR_DIRTY)!=0 ) return;
drh41d30272008-08-20 21:47:45 +0000663 pcacheEnterGlobal();
danielk19778c0a7912008-08-20 14:49:23 +0000664 pcacheAddToLruList(p);
drh41d30272008-08-20 21:47:45 +0000665 pcacheExitGlobal();
danielk19778c0a7912008-08-20 14:49:23 +0000666}
667
668void sqlite3PcacheRef(PgHdr *p){
669 assert(p->nRef>=0);
drh41d30272008-08-20 21:47:45 +0000670 pcacheRef(p, 1);
danielk19778c0a7912008-08-20 14:49:23 +0000671}
672
673/*
674** Drop a page from the cache. This should be the only reference to
675** the page.
676*/
677void sqlite3PcacheDrop(PgHdr *p){
678 PCache *pCache;
679 assert( p->pCache->iInUseDB );
680 assert( p->nRef==1 );
681 pCache = p->pCache;
682 pCache->nRef--;
683 if( p->flags & PGHDR_DIRTY ){
684 pcacheRemoveFromList(&pCache->pDirty, p);
685 }else{
686 pcacheRemoveFromList(&pCache->pClean, p);
687 }
688 pcacheRemoveFromHash(p);
drh41d30272008-08-20 21:47:45 +0000689 pcacheEnterGlobal();
danielk19778c0a7912008-08-20 14:49:23 +0000690 pcachePageFree(p);
drh41d30272008-08-20 21:47:45 +0000691 pcacheExitGlobal();
danielk19778c0a7912008-08-20 14:49:23 +0000692}
693
694/*
695** Make sure the page is marked as dirty. If it isn't dirty already,
696** make it so.
697*/
698void sqlite3PcacheMakeDirty(PgHdr *p){
699 PCache *pCache;
700 assert( p->pCache->iInUseDB );
701 if( p->flags & PGHDR_DIRTY ) return;
702 assert( (p->flags & PGHDR_DIRTY)==0 );
703 assert( p->nRef>0 );
704 pCache = p->pCache;
705 pcacheRemoveFromList(&pCache->pClean, p);
706 pcacheAddToList(&pCache->pDirty, p);
707 p->flags |= PGHDR_DIRTY;
708}
709
710/*
711** Make sure the page is marked as clean. If it isn't clean already,
712** make it so.
713*/
714void sqlite3PcacheMakeClean(PgHdr *p){
715 PCache *pCache;
716 assert( p->pCache->iInUseDB || p->pCache->iInUseMM );
717 if( (p->flags & PGHDR_DIRTY)==0 ) return;
718 assert( p->apSave[0]==0 && p->apSave[1]==0 );
719 assert( p->flags & PGHDR_DIRTY );
720 /* assert( p->nRef>0 ); */
721 pCache = p->pCache;
722 pcacheRemoveFromList(&pCache->pDirty, p);
723 pcacheAddToList(&pCache->pClean, p);
724 p->flags &= ~PGHDR_DIRTY;
725 if( p->nRef==0 ){
drh41d30272008-08-20 21:47:45 +0000726 pcacheEnterGlobal();
danielk19778c0a7912008-08-20 14:49:23 +0000727 pcacheAddToLruList(p);
drh41d30272008-08-20 21:47:45 +0000728 pcacheExitGlobal();
danielk19778c0a7912008-08-20 14:49:23 +0000729 }
730}
731
732/*
733** Make every page in the cache clean.
734*/
735void sqlite3PcacheCleanAll(PCache *pCache){
736 PgHdr *p;
737 assert( pCache->iInUseDB );
738 while( (p = pCache->pDirty)!=0 ){
739 assert( p->apSave[0]==0 && p->apSave[1]==0 );
740 pcacheRemoveFromList(&pCache->pDirty, p);
741 pcacheAddToList(&pCache->pClean, p);
742 p->flags &= ~PGHDR_DIRTY;
743 if( p->nRef==0 ){
drh41d30272008-08-20 21:47:45 +0000744 pcacheEnterGlobal();
danielk19778c0a7912008-08-20 14:49:23 +0000745 pcacheAddToLruList(p);
drh41d30272008-08-20 21:47:45 +0000746 pcacheExitGlobal();
danielk19778c0a7912008-08-20 14:49:23 +0000747 }
748 }
749}
750
751/*
752** Change the page number of page p to newPgno. If newPgno is 0, then the
753** page object is added to the clean-list and the PGHDR_REUSE_UNLIKELY
754** flag set.
755*/
756void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){
757 assert( p->pCache->iInUseDB );
758 pcacheRemoveFromHash(p);
759 p->pgno = newPgno;
760 if( newPgno==0 ){
761 p->flags |= PGHDR_REUSE_UNLIKELY;
drh41d30272008-08-20 21:47:45 +0000762 pcacheEnterGlobal();
danielk19778c0a7912008-08-20 14:49:23 +0000763 pcacheFree(p->apSave[0]);
764 pcacheFree(p->apSave[1]);
drh41d30272008-08-20 21:47:45 +0000765 pcacheExitGlobal();
danielk19778c0a7912008-08-20 14:49:23 +0000766 p->apSave[0] = 0;
767 p->apSave[1] = 0;
768 sqlite3PcacheMakeClean(p);
769 }
770 pcacheAddToHash(p);
771}
772
773/*
774** Set the global maximum number of pages. Return the previous value.
775*/
776void sqlite3PcacheGlobalMax(int mx){
drh41d30272008-08-20 21:47:45 +0000777 pcacheEnterGlobal();
danielk19778c0a7912008-08-20 14:49:23 +0000778 pcache.mxPage = mx;
drh41d30272008-08-20 21:47:45 +0000779 pcacheExitGlobal();
danielk19778c0a7912008-08-20 14:49:23 +0000780}
781
782/*
783** Remove all content from a page cache
784*/
785void pcacheClear(PCache *pCache){
786 PgHdr *p, *pNext;
787 assert( sqlite3_mutex_held(pcache.mutex_lru) );
788 for(p=pCache->pClean; p; p=pNext){
789 pNext = p->pNext;
790 pcacheRemoveFromLruList(p);
791 pcachePageFree(p);
792 }
793 for(p=pCache->pDirty; p; p=pNext){
794 pNext = p->pNext;
795 pcachePageFree(p);
796 }
797 pCache->pClean = 0;
798 pCache->pDirty = 0;
799 pCache->nPage = 0;
800 memset(pCache->apHash, 0, pCache->nHash*sizeof(pCache->apHash[0]));
801}
802
803
804/*
805** Drop every cache entry whose page number is greater than "pgno".
806*/
807void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){
808 PgHdr *p, *pNext;
809 PgHdr *pDirty = pCache->pDirty;
810 assert( pCache->iInUseDB );
drh41d30272008-08-20 21:47:45 +0000811 pcacheEnterGlobal();
danielk19778c0a7912008-08-20 14:49:23 +0000812 for(p=pCache->pClean; p||pDirty; p=pNext){
813 if( !p ){
814 p = pDirty;
815 pDirty = 0;
816 }
817 pNext = p->pNext;
818 if( p->pgno>pgno ){
819 if( p->nRef==0 ){
820 pcacheRemoveFromHash(p);
821 if( p->flags&PGHDR_DIRTY ){
822 pcacheRemoveFromList(&pCache->pDirty, p);
823 }else{
824 pcacheRemoveFromLruList(p);
825 pcacheRemoveFromList(&pCache->pClean, p);
826 }
827 pcachePageFree(p);
828 }else{
829 /* If there are references to the page, it cannot be freed. In this
830 ** case, zero the page content instead.
831 */
832 memset(p->pData, 0, pCache->szPage);
833 }
834 }
835 }
drh41d30272008-08-20 21:47:45 +0000836 pcacheExitGlobal();
danielk19778c0a7912008-08-20 14:49:23 +0000837}
838
839
840/*
841** Close a cache.
842*/
843void sqlite3PcacheClose(PCache *pCache){
844 assert( pCache->iInUseDB==1 );
845
846 /* Free all the pages used by this pager and remove them from the LRU
847 ** list. This requires the protection of the MUTEX_STATIC_LRU mutex.
848 */
drh41d30272008-08-20 21:47:45 +0000849 pcacheEnterGlobal();
danielk19778c0a7912008-08-20 14:49:23 +0000850 pcacheClear(pCache);
851 if( pCache->bPurgeable ){
852 pcache.mxPagePurgeable -= pCache->nMax;
853 }
854 sqlite3_free(pCache->apHash);
drh41d30272008-08-20 21:47:45 +0000855 pcacheExitGlobal();
danielk19778c0a7912008-08-20 14:49:23 +0000856
857 /* Now remove the pager-cache structure itself from the list of
858 ** all such structures headed by pcache.pAll. This required the
859 ** MUTEX_STATIC_MEM2 mutex.
860 */
861 sqlite3_mutex_enter(pcache.mutex_mem2);
862 assert(pCache==pcache.pAll || pCache->pPrevAll);
863 assert(pCache->pNextAll==0 || pCache->pNextAll->pPrevAll==pCache);
864 assert(pCache->pPrevAll==0 || pCache->pPrevAll->pNextAll==pCache);
865 if( pCache->pPrevAll ){
866 pCache->pPrevAll->pNextAll = pCache->pNextAll;
867 }else{
868 pcache.pAll = pCache->pNextAll;
869 }
870 if( pCache->pNextAll ){
871 pCache->pNextAll->pPrevAll = pCache->pPrevAll;
872 }
873 sqlite3_mutex_leave(pcache.mutex_mem2);
874}
875
876/*
877** Preserve the content of the page, if it has not been preserved
878** already. If idJournal==0 then this is for the overall transaction.
879** If idJournal==1 then this is for the statement journal.
880**
881** This routine is used for in-memory databases only.
882**
883** Return SQLITE_OK or SQLITE_NOMEM if a memory allocation fails.
884*/
885int sqlite3PcachePreserve(PgHdr *p, int idJournal){
886 void *x;
887 int sz;
888 assert( p->pCache->iInUseDB );
889 assert( p->pCache->bPurgeable==0 );
890 if( !p->apSave[idJournal] ){
891 sz = p->pCache->szPage;
892 p->apSave[idJournal] = x = sqlite3PageMalloc( sz );
893 if( x==0 ) return SQLITE_NOMEM;
894 memcpy(x, p->pData, sz);
895 }
896 return SQLITE_OK;
897}
898
899/*
900** Commit a change previously preserved.
901*/
902void sqlite3PcacheCommit(PCache *pCache, int idJournal){
903 PgHdr *p;
904 assert( pCache->iInUseDB );
drh41d30272008-08-20 21:47:45 +0000905 pcacheEnterGlobal(); /* Mutex is required to call pcacheFree() */
danielk19778c0a7912008-08-20 14:49:23 +0000906 for(p=pCache->pDirty; p; p=p->pNext){
907 if( p->apSave[idJournal] ){
908 pcacheFree(p->apSave[idJournal]);
909 p->apSave[idJournal] = 0;
910 }
911 }
drh41d30272008-08-20 21:47:45 +0000912 pcacheExitGlobal();
danielk19778c0a7912008-08-20 14:49:23 +0000913}
914
915/*
916** Rollback a change previously preserved.
917*/
918void sqlite3PcacheRollback(PCache *pCache, int idJournal){
919 PgHdr *p;
920 int sz;
921 assert( pCache->iInUseDB );
drh41d30272008-08-20 21:47:45 +0000922 pcacheEnterGlobal(); /* Mutex is required to call pcacheFree() */
danielk19778c0a7912008-08-20 14:49:23 +0000923 sz = pCache->szPage;
924 for(p=pCache->pDirty; p; p=p->pNext){
925 if( p->apSave[idJournal] ){
926 memcpy(p->pData, p->apSave[idJournal], sz);
927 pcacheFree(p->apSave[idJournal]);
928 p->apSave[idJournal] = 0;
929 }
930 }
drh41d30272008-08-20 21:47:45 +0000931 pcacheExitGlobal();
danielk19778c0a7912008-08-20 14:49:23 +0000932}
933
934/*
935** Assert flags settings on all pages. Debugging only.
936*/
937void sqlite3PcacheAssertFlags(PCache *pCache, int trueMask, int falseMask){
938 PgHdr *p;
939 assert( pCache->iInUseDB || pCache->iInUseMM );
940 for(p=pCache->pDirty; p; p=p->pNext){
941 assert( (p->flags&trueMask)==trueMask );
942 assert( (p->flags&falseMask)==0 );
943 }
944 for(p=pCache->pClean; p; p=p->pNext){
945 assert( (p->flags&trueMask)==trueMask );
946 assert( (p->flags&falseMask)==0 );
947 }
948}
949
950/*
951** Discard the contents of the cache.
952*/
953int sqlite3PcacheClear(PCache *pCache){
954 assert( pCache->iInUseDB );
955 assert(pCache->nRef==0);
drh41d30272008-08-20 21:47:45 +0000956 pcacheEnterGlobal();
danielk19778c0a7912008-08-20 14:49:23 +0000957 pcacheClear(pCache);
drh41d30272008-08-20 21:47:45 +0000958 pcacheExitGlobal();
danielk19778c0a7912008-08-20 14:49:23 +0000959 return SQLITE_OK;
960}
961
962/*
963** Merge two lists of pages connected by pDirty and in pgno order.
964** Do not both fixing the pPrevDirty pointers.
965*/
966static PgHdr *pcacheMergeDirtyList(PgHdr *pA, PgHdr *pB){
967 PgHdr result, *pTail;
968 pTail = &result;
969 while( pA && pB ){
970 if( pA->pgno<pB->pgno ){
971 pTail->pDirty = pA;
972 pTail = pA;
973 pA = pA->pDirty;
974 }else{
975 pTail->pDirty = pB;
976 pTail = pB;
977 pB = pB->pDirty;
978 }
979 }
980 if( pA ){
981 pTail->pDirty = pA;
982 }else if( pB ){
983 pTail->pDirty = pB;
984 }else{
985 pTail->pDirty = 0;
986 }
987 return result.pDirty;
988}
989
990/*
991** Sort the list of pages in accending order by pgno. Pages are
992** connected by pDirty pointers. The pPrevDirty pointers are
993** corrupted by this sort.
994*/
995#define N_SORT_BUCKET_ALLOC 25
996#define N_SORT_BUCKET 25
997#ifdef SQLITE_TEST
998 int sqlite3_pager_n_sort_bucket = 0;
999 #undef N_SORT_BUCKET
1000 #define N_SORT_BUCKET \
1001 (sqlite3_pager_n_sort_bucket?sqlite3_pager_n_sort_bucket:N_SORT_BUCKET_ALLOC)
1002#endif
1003static PgHdr *pcacheSortDirtyList(PgHdr *pIn){
1004 PgHdr *a[N_SORT_BUCKET_ALLOC], *p;
1005 int i;
1006 memset(a, 0, sizeof(a));
1007 while( pIn ){
1008 p = pIn;
1009 pIn = p->pDirty;
1010 p->pDirty = 0;
1011 for(i=0; i<N_SORT_BUCKET-1; i++){
1012 if( a[i]==0 ){
1013 a[i] = p;
1014 break;
1015 }else{
1016 p = pcacheMergeDirtyList(a[i], p);
1017 a[i] = 0;
1018 }
1019 }
1020 if( i==N_SORT_BUCKET-1 ){
1021 /* Coverage: To get here, there need to be 2^(N_SORT_BUCKET)
1022 ** elements in the input list. This is possible, but impractical.
1023 ** Testing this line is the point of global variable
1024 ** sqlite3_pager_n_sort_bucket.
1025 */
1026 a[i] = pcacheMergeDirtyList(a[i], p);
1027 }
1028 }
1029 p = a[0];
1030 for(i=1; i<N_SORT_BUCKET; i++){
1031 p = pcacheMergeDirtyList(p, a[i]);
1032 }
1033 return p;
1034}
1035
1036/*
1037** Return a list of all dirty pages in the cache, sorted by page number.
1038*/
1039PgHdr *sqlite3PcacheDirtyList(PCache *pCache){
1040 PgHdr *p;
1041 assert( pCache->iInUseDB );
1042 for(p=pCache->pDirty; p; p=p->pNext){
1043 p->pDirty = p->pNext;
1044 }
1045 return pcacheSortDirtyList(pCache->pDirty);
1046}
1047
1048/*
1049** This function searches cache pCache for a dirty page for which the
1050** reference count is zero. If such a page can be found, the PgHdr.pDirty
1051** pointer is set to 0 and a pointer to the page is returned. If no
1052** such page is found, 0 is returned.
1053**
1054** This is used by the pager module to implement the xStress callback.
1055*/
1056PgHdr *sqlite3PcacheDirtyPage(PCache *pCache){
1057 PgHdr *p = 0;
danielk19778c0a7912008-08-20 14:49:23 +00001058#if 1
1059 PgHdr *pIter;
1060 Pgno min_pgno;
1061 for(pIter=pCache->pDirty; pIter; pIter=pIter->pNext){
1062 if( pIter->nRef==0 && (p==0 || pIter->pgno<min_pgno) ){
1063 p = pIter;
1064 min_pgno = pIter->pgno;
1065 }
1066 }
1067#else
1068 for(p=pCache->pDirty; p && p->nRef; p=p->pNext);
1069#endif
danielk19770d3c5d32008-08-21 04:41:01 +00001070 assert( pCache->iInUseMM );
danielk19778c0a7912008-08-20 14:49:23 +00001071 if( p ){
1072 p->pDirty = 0;
1073 }
1074 return p;
1075}
1076
1077/*
1078** Return the total number of outstanding page references.
1079*/
1080int sqlite3PcacheRefCount(PCache *pCache){
1081 return pCache->nRef;
1082}
1083
1084/*
1085** Return the total number of pages in the cache.
1086*/
1087int sqlite3PcachePagecount(PCache *pCache){
1088 assert( pCache->iInUseDB || pCache->iInUseMM );
1089 assert( pCache->nPage>=0 );
1090 return pCache->nPage;
1091}
1092
1093#ifdef SQLITE_CHECK_PAGES
1094/*
1095** This function is used by the pager.c module to iterate through all
1096** pages in the cache. At present, this is only required if the
1097** SQLITE_CHECK_PAGES macro (used for debugging) is specified.
1098*/
1099void sqlite3PcacheIterate(PCache *pCache, void (*xIter)(PgHdr *)){
1100 PgHdr *p;
1101 assert( pCache->iInUseDB || pCache->iInUseMM );
1102 for(p=pCache->pClean; p; p=p->pNext){
1103 xIter(p);
1104 }
1105 for(p=pCache->pDirty; p; p=p->pNext){
1106 xIter(p);
1107 }
1108}
1109#endif
1110
1111/*
1112** Set flags on all pages in the page cache
1113*/
1114void sqlite3PcacheSetFlags(PCache *pCache, int andMask, int orMask){
1115 PgHdr *p;
1116 assert( pCache->iInUseDB || pCache->iInUseMM );
1117 for(p=pCache->pDirty; p; p=p->pNext){
1118 p->flags = (p->flags&andMask)|orMask;
1119 }
1120 for(p=pCache->pClean; p; p=p->pNext){
1121 p->flags = (p->flags&andMask)|orMask;
1122 }
1123}
1124
1125/*
1126** Set the suggested cache-size value.
1127*/
1128int sqlite3PcacheGetCachesize(PCache *pCache){
1129 return pCache->nMax;
1130}
1131
1132/*
1133** Set the suggested cache-size value.
1134*/
1135void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){
1136 if( mxPage<10 ){
1137 mxPage = 10;
1138 }
1139 if( pCache->bPurgeable ){
drh41d30272008-08-20 21:47:45 +00001140 pcacheEnterGlobal();
danielk19778c0a7912008-08-20 14:49:23 +00001141 pcache.mxPagePurgeable -= pCache->nMax;
1142 pcache.mxPagePurgeable += mxPage;
drh41d30272008-08-20 21:47:45 +00001143 pcacheExitGlobal();
danielk19778c0a7912008-08-20 14:49:23 +00001144 }
1145 pCache->nMax = mxPage;
1146}
1147
1148/*
1149** Lock a pager-cache.
1150*/
1151void sqlite3PcacheLock(PCache *pCache){
1152 pCache->iInUseDB++;
1153 if( pCache->iInUseMM && pCache->iInUseDB==1 ){
1154 pCache->iInUseDB = 0;
1155 sqlite3_mutex_enter(pcache.mutex_mem2);
1156 assert( pCache->iInUseMM==0 && pCache->iInUseDB==0 );
1157 pCache->iInUseDB = 1;
1158 sqlite3_mutex_leave(pcache.mutex_mem2);
1159 }
1160}
1161
1162/*
1163** Unlock a pager-cache.
1164*/
1165void sqlite3PcacheUnlock(PCache *pCache){
1166 pCache->iInUseDB--;
1167 assert( pCache->iInUseDB>=0 );
1168}
danielk197767e3da72008-08-21 12:19:44 +00001169
1170#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
1171/*
1172** This function is called to free superfluous dynamically allocated memory
1173** held by the pager system. Memory in use by any SQLite pager allocated
1174** by the current thread may be sqlite3_free()ed.
1175**
1176** nReq is the number of bytes of memory required. Once this much has
1177** been released, the function returns. The return value is the total number
1178** of bytes of memory released.
1179*/
1180int sqlite3PcacheReleaseMemory(int nReq){
1181 int nFree = 0;
1182 if( pcache.pStart==0 ){
1183 PgHdr *p;
1184 pcacheEnterGlobal();
1185 while( (nReq<0 || nFree<nReq) && (p=pcacheRecycle(0)) ){
1186 nFree += pcachePageSize(p);
1187 pcachePageFree(p);
1188 }
1189 pcacheExitGlobal();
1190 }
1191 return nFree;
1192}
1193#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */
1194