1 | /* |
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 | */ |
14 | #include "sqliteInt.h" |
15 | |
16 | /* |
17 | ** A complete page cache is an instance of this structure. Every |
18 | ** entry in the cache holds a single page of the database file. The |
19 | ** btree layer only operates on the cached copy of the database pages. |
20 | ** |
21 | ** A page cache entry is "clean" if it exactly matches what is currently |
22 | ** on disk. A page is "dirty" if it has been modified and needs to be |
23 | ** persisted to disk. |
24 | ** |
25 | ** pDirty, pDirtyTail, pSynced: |
26 | ** All dirty pages are linked into the doubly linked list using |
27 | ** PgHdr.pDirtyNext and pDirtyPrev. The list is maintained in LRU order |
28 | ** such that p was added to the list more recently than p->pDirtyNext. |
29 | ** PCache.pDirty points to the first (newest) element in the list and |
30 | ** pDirtyTail to the last (oldest). |
31 | ** |
32 | ** The PCache.pSynced variable is used to optimize searching for a dirty |
33 | ** page to eject from the cache mid-transaction. It is better to eject |
34 | ** a page that does not require a journal sync than one that does. |
35 | ** Therefore, pSynced is maintained so that it *almost* always points |
36 | ** to either the oldest page in the pDirty/pDirtyTail list that has a |
37 | ** clear PGHDR_NEED_SYNC flag or to a page that is older than this one |
38 | ** (so that the right page to eject can be found by following pDirtyPrev |
39 | ** pointers). |
40 | */ |
41 | struct PCache { |
42 | PgHdr *pDirty, *pDirtyTail; /* List of dirty pages in LRU order */ |
43 | PgHdr *pSynced; /* Last synced page in dirty page list */ |
44 | int nRefSum; /* Sum of ref counts over all pages */ |
45 | int szCache; /* Configured cache size */ |
46 | int szSpill; /* Size before spilling occurs */ |
47 | int szPage; /* Size of every page in this cache */ |
48 | int ; /* Size of extra space for each page */ |
49 | u8 bPurgeable; /* True if pages are on backing store */ |
50 | u8 eCreate; /* eCreate value for for xFetch() */ |
51 | int (*xStress)(void*,PgHdr*); /* Call to try make a page clean */ |
52 | void *pStress; /* Argument to xStress */ |
53 | sqlite3_pcache *pCache; /* Pluggable cache module */ |
54 | }; |
55 | |
56 | /********************************** Test and Debug Logic **********************/ |
57 | /* |
58 | ** Debug tracing macros. Enable by by changing the "0" to "1" and |
59 | ** recompiling. |
60 | ** |
61 | ** When sqlite3PcacheTrace is 1, single line trace messages are issued. |
62 | ** When sqlite3PcacheTrace is 2, a dump of the pcache showing all cache entries |
63 | ** is displayed for many operations, resulting in a lot of output. |
64 | */ |
65 | #if defined(SQLITE_DEBUG) && 0 |
66 | int sqlite3PcacheTrace = 2; /* 0: off 1: simple 2: cache dumps */ |
67 | int sqlite3PcacheMxDump = 9999; /* Max cache entries for pcacheDump() */ |
68 | # define pcacheTrace(X) if(sqlite3PcacheTrace){sqlite3DebugPrintf X;} |
69 | static void pcachePageTrace(int i, sqlite3_pcache_page *pLower){ |
70 | PgHdr *pPg; |
71 | unsigned char *a; |
72 | int j; |
73 | pPg = (PgHdr*)pLower->pExtra; |
74 | printf("%3d: nRef %2d flgs %02x data " , i, pPg->nRef, pPg->flags); |
75 | a = (unsigned char *)pLower->pBuf; |
76 | for(j=0; j<12; j++) printf("%02x" , a[j]); |
77 | printf(" ptr %p\n" , pPg); |
78 | } |
79 | static void pcacheDump(PCache *pCache){ |
80 | int N; |
81 | int i; |
82 | sqlite3_pcache_page *pLower; |
83 | |
84 | if( sqlite3PcacheTrace<2 ) return; |
85 | if( pCache->pCache==0 ) return; |
86 | N = sqlite3PcachePagecount(pCache); |
87 | if( N>sqlite3PcacheMxDump ) N = sqlite3PcacheMxDump; |
88 | for(i=1; i<=N; i++){ |
89 | pLower = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, i, 0); |
90 | if( pLower==0 ) continue; |
91 | pcachePageTrace(i, pLower); |
92 | if( ((PgHdr*)pLower)->pPage==0 ){ |
93 | sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, pLower, 0); |
94 | } |
95 | } |
96 | } |
97 | #else |
98 | # define pcacheTrace(X) |
99 | # define pcachePageTrace(PGNO, X) |
100 | # define pcacheDump(X) |
101 | #endif |
102 | |
103 | /* |
104 | ** Return 1 if pPg is on the dirty list for pCache. Return 0 if not. |
105 | ** This routine runs inside of assert() statements only. |
106 | */ |
107 | #ifdef SQLITE_DEBUG |
108 | static int pageOnDirtyList(PCache *pCache, PgHdr *pPg){ |
109 | PgHdr *p; |
110 | for(p=pCache->pDirty; p; p=p->pDirtyNext){ |
111 | if( p==pPg ) return 1; |
112 | } |
113 | return 0; |
114 | } |
115 | #endif |
116 | |
117 | /* |
118 | ** Check invariants on a PgHdr entry. Return true if everything is OK. |
119 | ** Return false if any invariant is violated. |
120 | ** |
121 | ** This routine is for use inside of assert() statements only. For |
122 | ** example: |
123 | ** |
124 | ** assert( sqlite3PcachePageSanity(pPg) ); |
125 | */ |
126 | #ifdef SQLITE_DEBUG |
127 | int sqlite3PcachePageSanity(PgHdr *pPg){ |
128 | PCache *pCache; |
129 | assert( pPg!=0 ); |
130 | assert( pPg->pgno>0 || pPg->pPager==0 ); /* Page number is 1 or more */ |
131 | pCache = pPg->pCache; |
132 | assert( pCache!=0 ); /* Every page has an associated PCache */ |
133 | if( pPg->flags & PGHDR_CLEAN ){ |
134 | assert( (pPg->flags & PGHDR_DIRTY)==0 );/* Cannot be both CLEAN and DIRTY */ |
135 | assert( !pageOnDirtyList(pCache, pPg) );/* CLEAN pages not on dirty list */ |
136 | }else{ |
137 | assert( (pPg->flags & PGHDR_DIRTY)!=0 );/* If not CLEAN must be DIRTY */ |
138 | assert( pPg->pDirtyNext==0 || pPg->pDirtyNext->pDirtyPrev==pPg ); |
139 | assert( pPg->pDirtyPrev==0 || pPg->pDirtyPrev->pDirtyNext==pPg ); |
140 | assert( pPg->pDirtyPrev!=0 || pCache->pDirty==pPg ); |
141 | assert( pageOnDirtyList(pCache, pPg) ); |
142 | } |
143 | /* WRITEABLE pages must also be DIRTY */ |
144 | if( pPg->flags & PGHDR_WRITEABLE ){ |
145 | assert( pPg->flags & PGHDR_DIRTY ); /* WRITEABLE implies DIRTY */ |
146 | } |
147 | /* NEED_SYNC can be set independently of WRITEABLE. This can happen, |
148 | ** for example, when using the sqlite3PagerDontWrite() optimization: |
149 | ** (1) Page X is journalled, and gets WRITEABLE and NEED_SEEK. |
150 | ** (2) Page X moved to freelist, WRITEABLE is cleared |
151 | ** (3) Page X reused, WRITEABLE is set again |
152 | ** If NEED_SYNC had been cleared in step 2, then it would not be reset |
153 | ** in step 3, and page might be written into the database without first |
154 | ** syncing the rollback journal, which might cause corruption on a power |
155 | ** loss. |
156 | ** |
157 | ** Another example is when the database page size is smaller than the |
158 | ** disk sector size. When any page of a sector is journalled, all pages |
159 | ** in that sector are marked NEED_SYNC even if they are still CLEAN, just |
160 | ** in case they are later modified, since all pages in the same sector |
161 | ** must be journalled and synced before any of those pages can be safely |
162 | ** written. |
163 | */ |
164 | return 1; |
165 | } |
166 | #endif /* SQLITE_DEBUG */ |
167 | |
168 | |
169 | /********************************** Linked List Management ********************/ |
170 | |
171 | /* Allowed values for second argument to pcacheManageDirtyList() */ |
172 | #define PCACHE_DIRTYLIST_REMOVE 1 /* Remove pPage from dirty list */ |
173 | #define PCACHE_DIRTYLIST_ADD 2 /* Add pPage to the dirty list */ |
174 | #define PCACHE_DIRTYLIST_FRONT 3 /* Move pPage to the front of the list */ |
175 | |
176 | /* |
177 | ** Manage pPage's participation on the dirty list. Bits of the addRemove |
178 | ** argument determines what operation to do. The 0x01 bit means first |
179 | ** remove pPage from the dirty list. The 0x02 means add pPage back to |
180 | ** the dirty list. Doing both moves pPage to the front of the dirty list. |
181 | */ |
182 | static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){ |
183 | PCache *p = pPage->pCache; |
184 | |
185 | pcacheTrace(("%p.DIRTYLIST.%s %d\n" , p, |
186 | addRemove==1 ? "REMOVE" : addRemove==2 ? "ADD" : "FRONT" , |
187 | pPage->pgno)); |
188 | if( addRemove & PCACHE_DIRTYLIST_REMOVE ){ |
189 | assert( pPage->pDirtyNext || pPage==p->pDirtyTail ); |
190 | assert( pPage->pDirtyPrev || pPage==p->pDirty ); |
191 | |
192 | /* Update the PCache1.pSynced variable if necessary. */ |
193 | if( p->pSynced==pPage ){ |
194 | p->pSynced = pPage->pDirtyPrev; |
195 | } |
196 | |
197 | if( pPage->pDirtyNext ){ |
198 | pPage->pDirtyNext->pDirtyPrev = pPage->pDirtyPrev; |
199 | }else{ |
200 | assert( pPage==p->pDirtyTail ); |
201 | p->pDirtyTail = pPage->pDirtyPrev; |
202 | } |
203 | if( pPage->pDirtyPrev ){ |
204 | pPage->pDirtyPrev->pDirtyNext = pPage->pDirtyNext; |
205 | }else{ |
206 | /* If there are now no dirty pages in the cache, set eCreate to 2. |
207 | ** This is an optimization that allows sqlite3PcacheFetch() to skip |
208 | ** searching for a dirty page to eject from the cache when it might |
209 | ** otherwise have to. */ |
210 | assert( pPage==p->pDirty ); |
211 | p->pDirty = pPage->pDirtyNext; |
212 | assert( p->bPurgeable || p->eCreate==2 ); |
213 | if( p->pDirty==0 ){ /*OPTIMIZATION-IF-TRUE*/ |
214 | assert( p->bPurgeable==0 || p->eCreate==1 ); |
215 | p->eCreate = 2; |
216 | } |
217 | } |
218 | } |
219 | if( addRemove & PCACHE_DIRTYLIST_ADD ){ |
220 | pPage->pDirtyPrev = 0; |
221 | pPage->pDirtyNext = p->pDirty; |
222 | if( pPage->pDirtyNext ){ |
223 | assert( pPage->pDirtyNext->pDirtyPrev==0 ); |
224 | pPage->pDirtyNext->pDirtyPrev = pPage; |
225 | }else{ |
226 | p->pDirtyTail = pPage; |
227 | if( p->bPurgeable ){ |
228 | assert( p->eCreate==2 ); |
229 | p->eCreate = 1; |
230 | } |
231 | } |
232 | p->pDirty = pPage; |
233 | |
234 | /* If pSynced is NULL and this page has a clear NEED_SYNC flag, set |
235 | ** pSynced to point to it. Checking the NEED_SYNC flag is an |
236 | ** optimization, as if pSynced points to a page with the NEED_SYNC |
237 | ** flag set sqlite3PcacheFetchStress() searches through all newer |
238 | ** entries of the dirty-list for a page with NEED_SYNC clear anyway. */ |
239 | if( !p->pSynced |
240 | && 0==(pPage->flags&PGHDR_NEED_SYNC) /*OPTIMIZATION-IF-FALSE*/ |
241 | ){ |
242 | p->pSynced = pPage; |
243 | } |
244 | } |
245 | pcacheDump(p); |
246 | } |
247 | |
248 | /* |
249 | ** Wrapper around the pluggable caches xUnpin method. If the cache is |
250 | ** being used for an in-memory database, this function is a no-op. |
251 | */ |
252 | static void pcacheUnpin(PgHdr *p){ |
253 | if( p->pCache->bPurgeable ){ |
254 | pcacheTrace(("%p.UNPIN %d\n" , p->pCache, p->pgno)); |
255 | sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 0); |
256 | pcacheDump(p->pCache); |
257 | } |
258 | } |
259 | |
260 | /* |
261 | ** Compute the number of pages of cache requested. p->szCache is the |
262 | ** cache size requested by the "PRAGMA cache_size" statement. |
263 | */ |
264 | static int numberOfCachePages(PCache *p){ |
265 | if( p->szCache>=0 ){ |
266 | /* IMPLEMENTATION-OF: R-42059-47211 If the argument N is positive then the |
267 | ** suggested cache size is set to N. */ |
268 | return p->szCache; |
269 | }else{ |
270 | i64 n; |
271 | /* IMPLEMANTATION-OF: R-59858-46238 If the argument N is negative, then the |
272 | ** number of cache pages is adjusted to be a number of pages that would |
273 | ** use approximately abs(N*1024) bytes of memory based on the current |
274 | ** page size. */ |
275 | n = ((-1024*(i64)p->szCache)/(p->szPage+p->szExtra)); |
276 | if( n>1000000000 ) n = 1000000000; |
277 | return (int)n; |
278 | } |
279 | } |
280 | |
281 | /*************************************************** General Interfaces ****** |
282 | ** |
283 | ** Initialize and shutdown the page cache subsystem. Neither of these |
284 | ** functions are threadsafe. |
285 | */ |
286 | int sqlite3PcacheInitialize(void){ |
287 | if( sqlite3GlobalConfig.pcache2.xInit==0 ){ |
288 | /* IMPLEMENTATION-OF: R-26801-64137 If the xInit() method is NULL, then the |
289 | ** built-in default page cache is used instead of the application defined |
290 | ** page cache. */ |
291 | sqlite3PCacheSetDefault(); |
292 | assert( sqlite3GlobalConfig.pcache2.xInit!=0 ); |
293 | } |
294 | return sqlite3GlobalConfig.pcache2.xInit(sqlite3GlobalConfig.pcache2.pArg); |
295 | } |
296 | void sqlite3PcacheShutdown(void){ |
297 | if( sqlite3GlobalConfig.pcache2.xShutdown ){ |
298 | /* IMPLEMENTATION-OF: R-26000-56589 The xShutdown() method may be NULL. */ |
299 | sqlite3GlobalConfig.pcache2.xShutdown(sqlite3GlobalConfig.pcache2.pArg); |
300 | } |
301 | } |
302 | |
303 | /* |
304 | ** Return the size in bytes of a PCache object. |
305 | */ |
306 | int sqlite3PcacheSize(void){ return sizeof(PCache); } |
307 | |
308 | /* |
309 | ** Create a new PCache object. Storage space to hold the object |
310 | ** has already been allocated and is passed in as the p pointer. |
311 | ** The caller discovers how much space needs to be allocated by |
312 | ** calling sqlite3PcacheSize(). |
313 | ** |
314 | ** szExtra is some extra space allocated for each page. The first |
315 | ** 8 bytes of the extra space will be zeroed as the page is allocated, |
316 | ** but remaining content will be uninitialized. Though it is opaque |
317 | ** to this module, the extra space really ends up being the MemPage |
318 | ** structure in the pager. |
319 | */ |
320 | int sqlite3PcacheOpen( |
321 | int szPage, /* Size of every page */ |
322 | int , /* Extra space associated with each page */ |
323 | int bPurgeable, /* True if pages are on backing store */ |
324 | int (*xStress)(void*,PgHdr*),/* Call to try to make pages clean */ |
325 | void *pStress, /* Argument to xStress */ |
326 | PCache *p /* Preallocated space for the PCache */ |
327 | ){ |
328 | memset(p, 0, sizeof(PCache)); |
329 | p->szPage = 1; |
330 | p->szExtra = szExtra; |
331 | assert( szExtra>=8 ); /* First 8 bytes will be zeroed */ |
332 | p->bPurgeable = bPurgeable; |
333 | p->eCreate = 2; |
334 | p->xStress = xStress; |
335 | p->pStress = pStress; |
336 | p->szCache = 100; |
337 | p->szSpill = 1; |
338 | pcacheTrace(("%p.OPEN szPage %d bPurgeable %d\n" ,p,szPage,bPurgeable)); |
339 | return sqlite3PcacheSetPageSize(p, szPage); |
340 | } |
341 | |
342 | /* |
343 | ** Change the page size for PCache object. The caller must ensure that there |
344 | ** are no outstanding page references when this function is called. |
345 | */ |
346 | int sqlite3PcacheSetPageSize(PCache *pCache, int szPage){ |
347 | assert( pCache->nRefSum==0 && pCache->pDirty==0 ); |
348 | if( pCache->szPage ){ |
349 | sqlite3_pcache *pNew; |
350 | pNew = sqlite3GlobalConfig.pcache2.xCreate( |
351 | szPage, pCache->szExtra + ROUND8(sizeof(PgHdr)), |
352 | pCache->bPurgeable |
353 | ); |
354 | if( pNew==0 ) return SQLITE_NOMEM_BKPT; |
355 | sqlite3GlobalConfig.pcache2.xCachesize(pNew, numberOfCachePages(pCache)); |
356 | if( pCache->pCache ){ |
357 | sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache); |
358 | } |
359 | pCache->pCache = pNew; |
360 | pCache->szPage = szPage; |
361 | pcacheTrace(("%p.PAGESIZE %d\n" ,pCache,szPage)); |
362 | } |
363 | return SQLITE_OK; |
364 | } |
365 | |
366 | /* |
367 | ** Try to obtain a page from the cache. |
368 | ** |
369 | ** This routine returns a pointer to an sqlite3_pcache_page object if |
370 | ** such an object is already in cache, or if a new one is created. |
371 | ** This routine returns a NULL pointer if the object was not in cache |
372 | ** and could not be created. |
373 | ** |
374 | ** The createFlags should be 0 to check for existing pages and should |
375 | ** be 3 (not 1, but 3) to try to create a new page. |
376 | ** |
377 | ** If the createFlag is 0, then NULL is always returned if the page |
378 | ** is not already in the cache. If createFlag is 1, then a new page |
379 | ** is created only if that can be done without spilling dirty pages |
380 | ** and without exceeding the cache size limit. |
381 | ** |
382 | ** The caller needs to invoke sqlite3PcacheFetchFinish() to properly |
383 | ** initialize the sqlite3_pcache_page object and convert it into a |
384 | ** PgHdr object. The sqlite3PcacheFetch() and sqlite3PcacheFetchFinish() |
385 | ** routines are split this way for performance reasons. When separated |
386 | ** they can both (usually) operate without having to push values to |
387 | ** the stack on entry and pop them back off on exit, which saves a |
388 | ** lot of pushing and popping. |
389 | */ |
390 | sqlite3_pcache_page *sqlite3PcacheFetch( |
391 | PCache *pCache, /* Obtain the page from this cache */ |
392 | Pgno pgno, /* Page number to obtain */ |
393 | int createFlag /* If true, create page if it does not exist already */ |
394 | ){ |
395 | int eCreate; |
396 | sqlite3_pcache_page *pRes; |
397 | |
398 | assert( pCache!=0 ); |
399 | assert( pCache->pCache!=0 ); |
400 | assert( createFlag==3 || createFlag==0 ); |
401 | assert( pCache->eCreate==((pCache->bPurgeable && pCache->pDirty) ? 1 : 2) ); |
402 | |
403 | /* eCreate defines what to do if the page does not exist. |
404 | ** 0 Do not allocate a new page. (createFlag==0) |
405 | ** 1 Allocate a new page if doing so is inexpensive. |
406 | ** (createFlag==1 AND bPurgeable AND pDirty) |
407 | ** 2 Allocate a new page even it doing so is difficult. |
408 | ** (createFlag==1 AND !(bPurgeable AND pDirty) |
409 | */ |
410 | eCreate = createFlag & pCache->eCreate; |
411 | assert( eCreate==0 || eCreate==1 || eCreate==2 ); |
412 | assert( createFlag==0 || pCache->eCreate==eCreate ); |
413 | assert( createFlag==0 || eCreate==1+(!pCache->bPurgeable||!pCache->pDirty) ); |
414 | pRes = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate); |
415 | pcacheTrace(("%p.FETCH %d%s (result: %p) " ,pCache,pgno, |
416 | createFlag?" create" :"" ,pRes)); |
417 | pcachePageTrace(pgno, pRes); |
418 | return pRes; |
419 | } |
420 | |
421 | /* |
422 | ** If the sqlite3PcacheFetch() routine is unable to allocate a new |
423 | ** page because no clean pages are available for reuse and the cache |
424 | ** size limit has been reached, then this routine can be invoked to |
425 | ** try harder to allocate a page. This routine might invoke the stress |
426 | ** callback to spill dirty pages to the journal. It will then try to |
427 | ** allocate the new page and will only fail to allocate a new page on |
428 | ** an OOM error. |
429 | ** |
430 | ** This routine should be invoked only after sqlite3PcacheFetch() fails. |
431 | */ |
432 | int sqlite3PcacheFetchStress( |
433 | PCache *pCache, /* Obtain the page from this cache */ |
434 | Pgno pgno, /* Page number to obtain */ |
435 | sqlite3_pcache_page **ppPage /* Write result here */ |
436 | ){ |
437 | PgHdr *pPg; |
438 | if( pCache->eCreate==2 ) return 0; |
439 | |
440 | if( sqlite3PcachePagecount(pCache)>pCache->szSpill ){ |
441 | /* Find a dirty page to write-out and recycle. First try to find a |
442 | ** page that does not require a journal-sync (one with PGHDR_NEED_SYNC |
443 | ** cleared), but if that is not possible settle for any other |
444 | ** unreferenced dirty page. |
445 | ** |
446 | ** If the LRU page in the dirty list that has a clear PGHDR_NEED_SYNC |
447 | ** flag is currently referenced, then the following may leave pSynced |
448 | ** set incorrectly (pointing to other than the LRU page with NEED_SYNC |
449 | ** cleared). This is Ok, as pSynced is just an optimization. */ |
450 | for(pPg=pCache->pSynced; |
451 | pPg && (pPg->nRef || (pPg->flags&PGHDR_NEED_SYNC)); |
452 | pPg=pPg->pDirtyPrev |
453 | ); |
454 | pCache->pSynced = pPg; |
455 | if( !pPg ){ |
456 | for(pPg=pCache->pDirtyTail; pPg && pPg->nRef; pPg=pPg->pDirtyPrev); |
457 | } |
458 | if( pPg ){ |
459 | int rc; |
460 | #ifdef SQLITE_LOG_CACHE_SPILL |
461 | sqlite3_log(SQLITE_FULL, |
462 | "spill page %d making room for %d - cache used: %d/%d" , |
463 | pPg->pgno, pgno, |
464 | sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache), |
465 | numberOfCachePages(pCache)); |
466 | #endif |
467 | pcacheTrace(("%p.SPILL %d\n" ,pCache,pPg->pgno)); |
468 | rc = pCache->xStress(pCache->pStress, pPg); |
469 | pcacheDump(pCache); |
470 | if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){ |
471 | return rc; |
472 | } |
473 | } |
474 | } |
475 | *ppPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2); |
476 | return *ppPage==0 ? SQLITE_NOMEM_BKPT : SQLITE_OK; |
477 | } |
478 | |
479 | /* |
480 | ** This is a helper routine for sqlite3PcacheFetchFinish() |
481 | ** |
482 | ** In the uncommon case where the page being fetched has not been |
483 | ** initialized, this routine is invoked to do the initialization. |
484 | ** This routine is broken out into a separate function since it |
485 | ** requires extra stack manipulation that can be avoided in the common |
486 | ** case. |
487 | */ |
488 | static SQLITE_NOINLINE PgHdr *pcacheFetchFinishWithInit( |
489 | PCache *pCache, /* Obtain the page from this cache */ |
490 | Pgno pgno, /* Page number obtained */ |
491 | sqlite3_pcache_page *pPage /* Page obtained by prior PcacheFetch() call */ |
492 | ){ |
493 | PgHdr *pPgHdr; |
494 | assert( pPage!=0 ); |
495 | pPgHdr = (PgHdr*)pPage->pExtra; |
496 | assert( pPgHdr->pPage==0 ); |
497 | memset(&pPgHdr->pDirty, 0, sizeof(PgHdr) - offsetof(PgHdr,pDirty)); |
498 | pPgHdr->pPage = pPage; |
499 | pPgHdr->pData = pPage->pBuf; |
500 | pPgHdr->pExtra = (void *)&pPgHdr[1]; |
501 | memset(pPgHdr->pExtra, 0, 8); |
502 | pPgHdr->pCache = pCache; |
503 | pPgHdr->pgno = pgno; |
504 | pPgHdr->flags = PGHDR_CLEAN; |
505 | return sqlite3PcacheFetchFinish(pCache,pgno,pPage); |
506 | } |
507 | |
508 | /* |
509 | ** This routine converts the sqlite3_pcache_page object returned by |
510 | ** sqlite3PcacheFetch() into an initialized PgHdr object. This routine |
511 | ** must be called after sqlite3PcacheFetch() in order to get a usable |
512 | ** result. |
513 | */ |
514 | PgHdr *sqlite3PcacheFetchFinish( |
515 | PCache *pCache, /* Obtain the page from this cache */ |
516 | Pgno pgno, /* Page number obtained */ |
517 | sqlite3_pcache_page *pPage /* Page obtained by prior PcacheFetch() call */ |
518 | ){ |
519 | PgHdr *pPgHdr; |
520 | |
521 | assert( pPage!=0 ); |
522 | pPgHdr = (PgHdr *)pPage->pExtra; |
523 | |
524 | if( !pPgHdr->pPage ){ |
525 | return pcacheFetchFinishWithInit(pCache, pgno, pPage); |
526 | } |
527 | pCache->nRefSum++; |
528 | pPgHdr->nRef++; |
529 | assert( sqlite3PcachePageSanity(pPgHdr) ); |
530 | return pPgHdr; |
531 | } |
532 | |
533 | /* |
534 | ** Decrement the reference count on a page. If the page is clean and the |
535 | ** reference count drops to 0, then it is made eligible for recycling. |
536 | */ |
537 | void SQLITE_NOINLINE sqlite3PcacheRelease(PgHdr *p){ |
538 | assert( p->nRef>0 ); |
539 | p->pCache->nRefSum--; |
540 | if( (--p->nRef)==0 ){ |
541 | if( p->flags&PGHDR_CLEAN ){ |
542 | pcacheUnpin(p); |
543 | }else{ |
544 | pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT); |
545 | assert( sqlite3PcachePageSanity(p) ); |
546 | } |
547 | } |
548 | } |
549 | |
550 | /* |
551 | ** Increase the reference count of a supplied page by 1. |
552 | */ |
553 | void sqlite3PcacheRef(PgHdr *p){ |
554 | assert(p->nRef>0); |
555 | assert( sqlite3PcachePageSanity(p) ); |
556 | p->nRef++; |
557 | p->pCache->nRefSum++; |
558 | } |
559 | |
560 | /* |
561 | ** Drop a page from the cache. There must be exactly one reference to the |
562 | ** page. This function deletes that reference, so after it returns the |
563 | ** page pointed to by p is invalid. |
564 | */ |
565 | void sqlite3PcacheDrop(PgHdr *p){ |
566 | assert( p->nRef==1 ); |
567 | assert( sqlite3PcachePageSanity(p) ); |
568 | if( p->flags&PGHDR_DIRTY ){ |
569 | pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE); |
570 | } |
571 | p->pCache->nRefSum--; |
572 | sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 1); |
573 | } |
574 | |
575 | /* |
576 | ** Make sure the page is marked as dirty. If it isn't dirty already, |
577 | ** make it so. |
578 | */ |
579 | void sqlite3PcacheMakeDirty(PgHdr *p){ |
580 | assert( p->nRef>0 ); |
581 | assert( sqlite3PcachePageSanity(p) ); |
582 | if( p->flags & (PGHDR_CLEAN|PGHDR_DONT_WRITE) ){ /*OPTIMIZATION-IF-FALSE*/ |
583 | p->flags &= ~PGHDR_DONT_WRITE; |
584 | if( p->flags & PGHDR_CLEAN ){ |
585 | p->flags ^= (PGHDR_DIRTY|PGHDR_CLEAN); |
586 | pcacheTrace(("%p.DIRTY %d\n" ,p->pCache,p->pgno)); |
587 | assert( (p->flags & (PGHDR_DIRTY|PGHDR_CLEAN))==PGHDR_DIRTY ); |
588 | pcacheManageDirtyList(p, PCACHE_DIRTYLIST_ADD); |
589 | assert( sqlite3PcachePageSanity(p) ); |
590 | } |
591 | assert( sqlite3PcachePageSanity(p) ); |
592 | } |
593 | } |
594 | |
595 | /* |
596 | ** Make sure the page is marked as clean. If it isn't clean already, |
597 | ** make it so. |
598 | */ |
599 | void sqlite3PcacheMakeClean(PgHdr *p){ |
600 | assert( sqlite3PcachePageSanity(p) ); |
601 | assert( (p->flags & PGHDR_DIRTY)!=0 ); |
602 | assert( (p->flags & PGHDR_CLEAN)==0 ); |
603 | pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE); |
604 | p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC|PGHDR_WRITEABLE); |
605 | p->flags |= PGHDR_CLEAN; |
606 | pcacheTrace(("%p.CLEAN %d\n" ,p->pCache,p->pgno)); |
607 | assert( sqlite3PcachePageSanity(p) ); |
608 | if( p->nRef==0 ){ |
609 | pcacheUnpin(p); |
610 | } |
611 | } |
612 | |
613 | /* |
614 | ** Make every page in the cache clean. |
615 | */ |
616 | void sqlite3PcacheCleanAll(PCache *pCache){ |
617 | PgHdr *p; |
618 | pcacheTrace(("%p.CLEAN-ALL\n" ,pCache)); |
619 | while( (p = pCache->pDirty)!=0 ){ |
620 | sqlite3PcacheMakeClean(p); |
621 | } |
622 | } |
623 | |
624 | /* |
625 | ** Clear the PGHDR_NEED_SYNC and PGHDR_WRITEABLE flag from all dirty pages. |
626 | */ |
627 | void sqlite3PcacheClearWritable(PCache *pCache){ |
628 | PgHdr *p; |
629 | pcacheTrace(("%p.CLEAR-WRITEABLE\n" ,pCache)); |
630 | for(p=pCache->pDirty; p; p=p->pDirtyNext){ |
631 | p->flags &= ~(PGHDR_NEED_SYNC|PGHDR_WRITEABLE); |
632 | } |
633 | pCache->pSynced = pCache->pDirtyTail; |
634 | } |
635 | |
636 | /* |
637 | ** Clear the PGHDR_NEED_SYNC flag from all dirty pages. |
638 | */ |
639 | void sqlite3PcacheClearSyncFlags(PCache *pCache){ |
640 | PgHdr *p; |
641 | for(p=pCache->pDirty; p; p=p->pDirtyNext){ |
642 | p->flags &= ~PGHDR_NEED_SYNC; |
643 | } |
644 | pCache->pSynced = pCache->pDirtyTail; |
645 | } |
646 | |
647 | /* |
648 | ** Change the page number of page p to newPgno. |
649 | */ |
650 | void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){ |
651 | PCache *pCache = p->pCache; |
652 | sqlite3_pcache_page *pOther; |
653 | assert( p->nRef>0 ); |
654 | assert( newPgno>0 ); |
655 | assert( sqlite3PcachePageSanity(p) ); |
656 | pcacheTrace(("%p.MOVE %d -> %d\n" ,pCache,p->pgno,newPgno)); |
657 | pOther = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, newPgno, 0); |
658 | if( pOther ){ |
659 | PgHdr *pXPage = (PgHdr*)pOther->pExtra; |
660 | assert( pXPage->nRef==0 ); |
661 | pXPage->nRef++; |
662 | pCache->nRefSum++; |
663 | sqlite3PcacheDrop(pXPage); |
664 | } |
665 | sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno); |
666 | p->pgno = newPgno; |
667 | if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){ |
668 | pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT); |
669 | assert( sqlite3PcachePageSanity(p) ); |
670 | } |
671 | } |
672 | |
673 | /* |
674 | ** Drop every cache entry whose page number is greater than "pgno". The |
675 | ** caller must ensure that there are no outstanding references to any pages |
676 | ** other than page 1 with a page number greater than pgno. |
677 | ** |
678 | ** If there is a reference to page 1 and the pgno parameter passed to this |
679 | ** function is 0, then the data area associated with page 1 is zeroed, but |
680 | ** the page object is not dropped. |
681 | */ |
682 | void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){ |
683 | if( pCache->pCache ){ |
684 | PgHdr *p; |
685 | PgHdr *pNext; |
686 | pcacheTrace(("%p.TRUNCATE %d\n" ,pCache,pgno)); |
687 | for(p=pCache->pDirty; p; p=pNext){ |
688 | pNext = p->pDirtyNext; |
689 | /* This routine never gets call with a positive pgno except right |
690 | ** after sqlite3PcacheCleanAll(). So if there are dirty pages, |
691 | ** it must be that pgno==0. |
692 | */ |
693 | assert( p->pgno>0 ); |
694 | if( p->pgno>pgno ){ |
695 | assert( p->flags&PGHDR_DIRTY ); |
696 | sqlite3PcacheMakeClean(p); |
697 | } |
698 | } |
699 | if( pgno==0 && pCache->nRefSum ){ |
700 | sqlite3_pcache_page *pPage1; |
701 | pPage1 = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache,1,0); |
702 | if( ALWAYS(pPage1) ){ /* Page 1 is always available in cache, because |
703 | ** pCache->nRefSum>0 */ |
704 | memset(pPage1->pBuf, 0, pCache->szPage); |
705 | pgno = 1; |
706 | } |
707 | } |
708 | sqlite3GlobalConfig.pcache2.xTruncate(pCache->pCache, pgno+1); |
709 | } |
710 | } |
711 | |
712 | /* |
713 | ** Close a cache. |
714 | */ |
715 | void sqlite3PcacheClose(PCache *pCache){ |
716 | assert( pCache->pCache!=0 ); |
717 | pcacheTrace(("%p.CLOSE\n" ,pCache)); |
718 | sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache); |
719 | } |
720 | |
721 | /* |
722 | ** Discard the contents of the cache. |
723 | */ |
724 | void sqlite3PcacheClear(PCache *pCache){ |
725 | sqlite3PcacheTruncate(pCache, 0); |
726 | } |
727 | |
728 | /* |
729 | ** Merge two lists of pages connected by pDirty and in pgno order. |
730 | ** Do not bother fixing the pDirtyPrev pointers. |
731 | */ |
732 | static PgHdr *pcacheMergeDirtyList(PgHdr *pA, PgHdr *pB){ |
733 | PgHdr result, *pTail; |
734 | pTail = &result; |
735 | assert( pA!=0 && pB!=0 ); |
736 | for(;;){ |
737 | if( pA->pgno<pB->pgno ){ |
738 | pTail->pDirty = pA; |
739 | pTail = pA; |
740 | pA = pA->pDirty; |
741 | if( pA==0 ){ |
742 | pTail->pDirty = pB; |
743 | break; |
744 | } |
745 | }else{ |
746 | pTail->pDirty = pB; |
747 | pTail = pB; |
748 | pB = pB->pDirty; |
749 | if( pB==0 ){ |
750 | pTail->pDirty = pA; |
751 | break; |
752 | } |
753 | } |
754 | } |
755 | return result.pDirty; |
756 | } |
757 | |
758 | /* |
759 | ** Sort the list of pages in accending order by pgno. Pages are |
760 | ** connected by pDirty pointers. The pDirtyPrev pointers are |
761 | ** corrupted by this sort. |
762 | ** |
763 | ** Since there cannot be more than 2^31 distinct pages in a database, |
764 | ** there cannot be more than 31 buckets required by the merge sorter. |
765 | ** One extra bucket is added to catch overflow in case something |
766 | ** ever changes to make the previous sentence incorrect. |
767 | */ |
768 | #define N_SORT_BUCKET 32 |
769 | static PgHdr *pcacheSortDirtyList(PgHdr *pIn){ |
770 | PgHdr *a[N_SORT_BUCKET], *p; |
771 | int i; |
772 | memset(a, 0, sizeof(a)); |
773 | while( pIn ){ |
774 | p = pIn; |
775 | pIn = p->pDirty; |
776 | p->pDirty = 0; |
777 | for(i=0; ALWAYS(i<N_SORT_BUCKET-1); i++){ |
778 | if( a[i]==0 ){ |
779 | a[i] = p; |
780 | break; |
781 | }else{ |
782 | p = pcacheMergeDirtyList(a[i], p); |
783 | a[i] = 0; |
784 | } |
785 | } |
786 | if( NEVER(i==N_SORT_BUCKET-1) ){ |
787 | /* To get here, there need to be 2^(N_SORT_BUCKET) elements in |
788 | ** the input list. But that is impossible. |
789 | */ |
790 | a[i] = pcacheMergeDirtyList(a[i], p); |
791 | } |
792 | } |
793 | p = a[0]; |
794 | for(i=1; i<N_SORT_BUCKET; i++){ |
795 | if( a[i]==0 ) continue; |
796 | p = p ? pcacheMergeDirtyList(p, a[i]) : a[i]; |
797 | } |
798 | return p; |
799 | } |
800 | |
801 | /* |
802 | ** Return a list of all dirty pages in the cache, sorted by page number. |
803 | */ |
804 | PgHdr *sqlite3PcacheDirtyList(PCache *pCache){ |
805 | PgHdr *p; |
806 | for(p=pCache->pDirty; p; p=p->pDirtyNext){ |
807 | p->pDirty = p->pDirtyNext; |
808 | } |
809 | return pcacheSortDirtyList(pCache->pDirty); |
810 | } |
811 | |
812 | /* |
813 | ** Return the total number of references to all pages held by the cache. |
814 | ** |
815 | ** This is not the total number of pages referenced, but the sum of the |
816 | ** reference count for all pages. |
817 | */ |
818 | int sqlite3PcacheRefCount(PCache *pCache){ |
819 | return pCache->nRefSum; |
820 | } |
821 | |
822 | /* |
823 | ** Return the number of references to the page supplied as an argument. |
824 | */ |
825 | int (PgHdr *p){ |
826 | return p->nRef; |
827 | } |
828 | |
829 | /* |
830 | ** Return the total number of pages in the cache. |
831 | */ |
832 | int sqlite3PcachePagecount(PCache *pCache){ |
833 | assert( pCache->pCache!=0 ); |
834 | return sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache); |
835 | } |
836 | |
837 | #ifdef SQLITE_TEST |
838 | /* |
839 | ** Get the suggested cache-size value. |
840 | */ |
841 | int sqlite3PcacheGetCachesize(PCache *pCache){ |
842 | return numberOfCachePages(pCache); |
843 | } |
844 | #endif |
845 | |
846 | /* |
847 | ** Set the suggested cache-size value. |
848 | */ |
849 | void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){ |
850 | assert( pCache->pCache!=0 ); |
851 | pCache->szCache = mxPage; |
852 | sqlite3GlobalConfig.pcache2.xCachesize(pCache->pCache, |
853 | numberOfCachePages(pCache)); |
854 | } |
855 | |
856 | /* |
857 | ** Set the suggested cache-spill value. Make no changes if if the |
858 | ** argument is zero. Return the effective cache-spill size, which will |
859 | ** be the larger of the szSpill and szCache. |
860 | */ |
861 | int sqlite3PcacheSetSpillsize(PCache *p, int mxPage){ |
862 | int res; |
863 | assert( p->pCache!=0 ); |
864 | if( mxPage ){ |
865 | if( mxPage<0 ){ |
866 | mxPage = (int)((-1024*(i64)mxPage)/(p->szPage+p->szExtra)); |
867 | } |
868 | p->szSpill = mxPage; |
869 | } |
870 | res = numberOfCachePages(p); |
871 | if( res<p->szSpill ) res = p->szSpill; |
872 | return res; |
873 | } |
874 | |
875 | /* |
876 | ** Free up as much memory as possible from the page cache. |
877 | */ |
878 | void sqlite3PcacheShrink(PCache *pCache){ |
879 | assert( pCache->pCache!=0 ); |
880 | sqlite3GlobalConfig.pcache2.xShrink(pCache->pCache); |
881 | } |
882 | |
883 | /* |
884 | ** Return the size of the header added by this middleware layer |
885 | ** in the page-cache hierarchy. |
886 | */ |
887 | int (void){ return ROUND8(sizeof(PgHdr)); } |
888 | |
889 | /* |
890 | ** Return the number of dirty pages currently in the cache, as a percentage |
891 | ** of the configured cache size. |
892 | */ |
893 | int sqlite3PCachePercentDirty(PCache *pCache){ |
894 | PgHdr *pDirty; |
895 | int nDirty = 0; |
896 | int nCache = numberOfCachePages(pCache); |
897 | for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext) nDirty++; |
898 | return nCache ? (int)(((i64)nDirty * 100) / nCache) : 0; |
899 | } |
900 | |
901 | #ifdef SQLITE_DIRECT_OVERFLOW_READ |
902 | /* |
903 | ** Return true if there are one or more dirty pages in the cache. Else false. |
904 | */ |
905 | int sqlite3PCacheIsDirty(PCache *pCache){ |
906 | return (pCache->pDirty!=0); |
907 | } |
908 | #endif |
909 | |
910 | #if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG) |
911 | /* |
912 | ** For all dirty pages currently in the cache, invoke the specified |
913 | ** callback. This is only used if the SQLITE_CHECK_PAGES macro is |
914 | ** defined. |
915 | */ |
916 | void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *)){ |
917 | PgHdr *pDirty; |
918 | for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext){ |
919 | xIter(pDirty); |
920 | } |
921 | } |
922 | #endif |
923 | |