Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: third_party/sqlite/sqlite-src-3100200/src/pcache.c

Issue 1610543003: [sql] Import reference version of SQLite 3.10.2. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 ** 2008 August 05 2 ** 2008 August 05
3 ** 3 **
4 ** The author disclaims copyright to this source code. In place of 4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing: 5 ** a legal notice, here is a blessing:
6 ** 6 **
7 ** May you do good and not evil. 7 ** May you do good and not evil.
8 ** May you find forgiveness for yourself and forgive others. 8 ** May you find forgiveness for yourself and forgive others.
9 ** May you share freely, never taking more than you give. 9 ** May you share freely, never taking more than you give.
10 ** 10 **
11 ************************************************************************* 11 *************************************************************************
12 ** This file implements that page cache. 12 ** This file implements that page cache.
13 */ 13 */
14 #include "sqliteInt.h" 14 #include "sqliteInt.h"
15 15
16 /* 16 /*
17 ** A complete page cache is an instance of this structure. 17 ** A complete page cache is an instance of this structure.
18 */ 18 */
19 struct PCache { 19 struct PCache {
20 PgHdr *pDirty, *pDirtyTail; /* List of dirty pages in LRU order */ 20 PgHdr *pDirty, *pDirtyTail; /* List of dirty pages in LRU order */
21 PgHdr *pSynced; /* Last synced page in dirty page list */ 21 PgHdr *pSynced; /* Last synced page in dirty page list */
22 int nRef; /* Number of referenced pages */ 22 int nRefSum; /* Sum of ref counts over all pages */
23 int szCache; /* Configured cache size */ 23 int szCache; /* Configured cache size */
24 int szSpill; /* Size before spilling occurs */
24 int szPage; /* Size of every page in this cache */ 25 int szPage; /* Size of every page in this cache */
25 int szExtra; /* Size of extra space for each page */ 26 int szExtra; /* Size of extra space for each page */
26 u8 bPurgeable; /* True if pages are on backing store */ 27 u8 bPurgeable; /* True if pages are on backing store */
27 u8 eCreate; /* eCreate value for for xFetch() */ 28 u8 eCreate; /* eCreate value for for xFetch() */
28 int (*xStress)(void*,PgHdr*); /* Call to try make a page clean */ 29 int (*xStress)(void*,PgHdr*); /* Call to try make a page clean */
29 void *pStress; /* Argument to xStress */ 30 void *pStress; /* Argument to xStress */
30 sqlite3_pcache *pCache; /* Pluggable cache module */ 31 sqlite3_pcache *pCache; /* Pluggable cache module */
31 PgHdr *pPage1; /* Reference to page 1 */
32 }; 32 };
33 33
34 /*
35 ** Some of the assert() macros in this code are too expensive to run
36 ** even during normal debugging. Use them only rarely on long-running
37 ** tests. Enable the expensive asserts using the
38 ** -DSQLITE_ENABLE_EXPENSIVE_ASSERT=1 compile-time option.
39 */
40 #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
41 # define expensive_assert(X) assert(X)
42 #else
43 # define expensive_assert(X)
44 #endif
45
46 /********************************** Linked List Management ********************/ 34 /********************************** Linked List Management ********************/
47 35
48 /* Allowed values for second argument to pcacheManageDirtyList() */ 36 /* Allowed values for second argument to pcacheManageDirtyList() */
49 #define PCACHE_DIRTYLIST_REMOVE 1 /* Remove pPage from dirty list */ 37 #define PCACHE_DIRTYLIST_REMOVE 1 /* Remove pPage from dirty list */
50 #define PCACHE_DIRTYLIST_ADD 2 /* Add pPage to the dirty list */ 38 #define PCACHE_DIRTYLIST_ADD 2 /* Add pPage to the dirty list */
51 #define PCACHE_DIRTYLIST_FRONT 3 /* Move pPage to the front of the list */ 39 #define PCACHE_DIRTYLIST_FRONT 3 /* Move pPage to the front of the list */
52 40
53 /* 41 /*
54 ** Manage pPage's participation on the dirty list. Bits of the addRemove 42 ** Manage pPage's participation on the dirty list. Bits of the addRemove
55 ** argument determines what operation to do. The 0x01 bit means first 43 ** argument determines what operation to do. The 0x01 bit means first
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 } 99 }
112 } 100 }
113 } 101 }
114 102
115 /* 103 /*
116 ** Wrapper around the pluggable caches xUnpin method. If the cache is 104 ** Wrapper around the pluggable caches xUnpin method. If the cache is
117 ** being used for an in-memory database, this function is a no-op. 105 ** being used for an in-memory database, this function is a no-op.
118 */ 106 */
119 static void pcacheUnpin(PgHdr *p){ 107 static void pcacheUnpin(PgHdr *p){
120 if( p->pCache->bPurgeable ){ 108 if( p->pCache->bPurgeable ){
121 if( p->pgno==1 ){
122 p->pCache->pPage1 = 0;
123 }
124 sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 0); 109 sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 0);
125 } 110 }
126 } 111 }
127 112
128 /* 113 /*
129 ** Compute the number of pages of cache requested. 114 ** Compute the number of pages of cache requested. p->szCache is the
115 ** cache size requested by the "PRAGMA cache_size" statement.
130 */ 116 */
131 static int numberOfCachePages(PCache *p){ 117 static int numberOfCachePages(PCache *p){
132 if( p->szCache>=0 ){ 118 if( p->szCache>=0 ){
119 /* IMPLEMENTATION-OF: R-42059-47211 If the argument N is positive then the
120 ** suggested cache size is set to N. */
133 return p->szCache; 121 return p->szCache;
134 }else{ 122 }else{
123 /* IMPLEMENTATION-OF: R-61436-13639 If the argument N is negative, then
124 ** the number of cache pages is adjusted to use approximately abs(N*1024)
125 ** bytes of memory. */
135 return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra)); 126 return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra));
136 } 127 }
137 } 128 }
138 129
139 /*************************************************** General Interfaces ****** 130 /*************************************************** General Interfaces ******
140 ** 131 **
141 ** Initialize and shutdown the page cache subsystem. Neither of these 132 ** Initialize and shutdown the page cache subsystem. Neither of these
142 ** functions are threadsafe. 133 ** functions are threadsafe.
143 */ 134 */
144 int sqlite3PcacheInitialize(void){ 135 int sqlite3PcacheInitialize(void){
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 PCache *p /* Preallocated space for the PCache */ 168 PCache *p /* Preallocated space for the PCache */
178 ){ 169 ){
179 memset(p, 0, sizeof(PCache)); 170 memset(p, 0, sizeof(PCache));
180 p->szPage = 1; 171 p->szPage = 1;
181 p->szExtra = szExtra; 172 p->szExtra = szExtra;
182 p->bPurgeable = bPurgeable; 173 p->bPurgeable = bPurgeable;
183 p->eCreate = 2; 174 p->eCreate = 2;
184 p->xStress = xStress; 175 p->xStress = xStress;
185 p->pStress = pStress; 176 p->pStress = pStress;
186 p->szCache = 100; 177 p->szCache = 100;
178 p->szSpill = 1;
187 return sqlite3PcacheSetPageSize(p, szPage); 179 return sqlite3PcacheSetPageSize(p, szPage);
188 } 180 }
189 181
190 /* 182 /*
191 ** Change the page size for PCache object. The caller must ensure that there 183 ** Change the page size for PCache object. The caller must ensure that there
192 ** are no outstanding page references when this function is called. 184 ** are no outstanding page references when this function is called.
193 */ 185 */
194 int sqlite3PcacheSetPageSize(PCache *pCache, int szPage){ 186 int sqlite3PcacheSetPageSize(PCache *pCache, int szPage){
195 assert( pCache->nRef==0 && pCache->pDirty==0 ); 187 assert( pCache->nRefSum==0 && pCache->pDirty==0 );
196 if( pCache->szPage ){ 188 if( pCache->szPage ){
197 sqlite3_pcache *pNew; 189 sqlite3_pcache *pNew;
198 pNew = sqlite3GlobalConfig.pcache2.xCreate( 190 pNew = sqlite3GlobalConfig.pcache2.xCreate(
199 szPage, pCache->szExtra + sizeof(PgHdr), pCache->bPurgeable 191 szPage, pCache->szExtra + ROUND8(sizeof(PgHdr)),
192 pCache->bPurgeable
200 ); 193 );
201 if( pNew==0 ) return SQLITE_NOMEM; 194 if( pNew==0 ) return SQLITE_NOMEM;
202 sqlite3GlobalConfig.pcache2.xCachesize(pNew, numberOfCachePages(pCache)); 195 sqlite3GlobalConfig.pcache2.xCachesize(pNew, numberOfCachePages(pCache));
203 if( pCache->pCache ){ 196 if( pCache->pCache ){
204 sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache); 197 sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
205 } 198 }
206 pCache->pCache = pNew; 199 pCache->pCache = pNew;
207 pCache->pPage1 = 0;
208 pCache->szPage = szPage; 200 pCache->szPage = szPage;
209 } 201 }
210 return SQLITE_OK; 202 return SQLITE_OK;
211 } 203 }
212 204
213 /* 205 /*
214 ** Try to obtain a page from the cache. 206 ** Try to obtain a page from the cache.
215 ** 207 **
216 ** This routine returns a pointer to an sqlite3_pcache_page object if 208 ** This routine returns a pointer to an sqlite3_pcache_page object if
217 ** such an object is already in cache, or if a new one is created. 209 ** such an object is already in cache, or if a new one is created.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 ** This routine should be invoked only after sqlite3PcacheFetch() fails. 264 ** This routine should be invoked only after sqlite3PcacheFetch() fails.
273 */ 265 */
274 int sqlite3PcacheFetchStress( 266 int sqlite3PcacheFetchStress(
275 PCache *pCache, /* Obtain the page from this cache */ 267 PCache *pCache, /* Obtain the page from this cache */
276 Pgno pgno, /* Page number to obtain */ 268 Pgno pgno, /* Page number to obtain */
277 sqlite3_pcache_page **ppPage /* Write result here */ 269 sqlite3_pcache_page **ppPage /* Write result here */
278 ){ 270 ){
279 PgHdr *pPg; 271 PgHdr *pPg;
280 if( pCache->eCreate==2 ) return 0; 272 if( pCache->eCreate==2 ) return 0;
281 273
282 274 if( sqlite3PcachePagecount(pCache)>pCache->szSpill ){
283 /* Find a dirty page to write-out and recycle. First try to find a 275 /* Find a dirty page to write-out and recycle. First try to find a
284 ** page that does not require a journal-sync (one with PGHDR_NEED_SYNC 276 ** page that does not require a journal-sync (one with PGHDR_NEED_SYNC
285 ** cleared), but if that is not possible settle for any other 277 ** cleared), but if that is not possible settle for any other
286 ** unreferenced dirty page. 278 ** unreferenced dirty page.
287 */ 279 */
288 for(pPg=pCache->pSynced; 280 for(pPg=pCache->pSynced;
289 pPg && (pPg->nRef || (pPg->flags&PGHDR_NEED_SYNC)); 281 pPg && (pPg->nRef || (pPg->flags&PGHDR_NEED_SYNC));
290 pPg=pPg->pDirtyPrev 282 pPg=pPg->pDirtyPrev
291 ); 283 );
292 pCache->pSynced = pPg; 284 pCache->pSynced = pPg;
293 if( !pPg ){ 285 if( !pPg ){
294 for(pPg=pCache->pDirtyTail; pPg && pPg->nRef; pPg=pPg->pDirtyPrev); 286 for(pPg=pCache->pDirtyTail; pPg && pPg->nRef; pPg=pPg->pDirtyPrev);
295 } 287 }
296 if( pPg ){ 288 if( pPg ){
297 int rc; 289 int rc;
298 #ifdef SQLITE_LOG_CACHE_SPILL 290 #ifdef SQLITE_LOG_CACHE_SPILL
299 sqlite3_log(SQLITE_FULL, 291 sqlite3_log(SQLITE_FULL,
300 "spill page %d making room for %d - cache used: %d/%d", 292 "spill page %d making room for %d - cache used: %d/%d",
301 pPg->pgno, pgno, 293 pPg->pgno, pgno,
302 sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache), 294 sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache),
303 numberOfCachePages(pCache)); 295 numberOfCachePages(pCache));
304 #endif 296 #endif
305 rc = pCache->xStress(pCache->pStress, pPg); 297 rc = pCache->xStress(pCache->pStress, pPg);
306 if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){ 298 if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
307 return rc; 299 return rc;
300 }
308 } 301 }
309 } 302 }
310 *ppPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2); 303 *ppPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2);
311 return *ppPage==0 ? SQLITE_NOMEM : SQLITE_OK; 304 return *ppPage==0 ? SQLITE_NOMEM : SQLITE_OK;
312 } 305 }
313 306
314 /* 307 /*
315 ** This is a helper routine for sqlite3PcacheFetchFinish() 308 ** This is a helper routine for sqlite3PcacheFetchFinish()
316 ** 309 **
317 ** In the uncommon case where the page being fetched has not been 310 ** In the uncommon case where the page being fetched has not been
318 ** initialized, this routine is invoked to do the initialization. 311 ** initialized, this routine is invoked to do the initialization.
319 ** This routine is broken out into a separate function since it 312 ** This routine is broken out into a separate function since it
320 ** requires extra stack manipulation that can be avoided in the common 313 ** requires extra stack manipulation that can be avoided in the common
321 ** case. 314 ** case.
322 */ 315 */
323 static SQLITE_NOINLINE PgHdr *pcacheFetchFinishWithInit( 316 static SQLITE_NOINLINE PgHdr *pcacheFetchFinishWithInit(
324 PCache *pCache, /* Obtain the page from this cache */ 317 PCache *pCache, /* Obtain the page from this cache */
325 Pgno pgno, /* Page number obtained */ 318 Pgno pgno, /* Page number obtained */
326 sqlite3_pcache_page *pPage /* Page obtained by prior PcacheFetch() call */ 319 sqlite3_pcache_page *pPage /* Page obtained by prior PcacheFetch() call */
327 ){ 320 ){
328 PgHdr *pPgHdr; 321 PgHdr *pPgHdr;
329 assert( pPage!=0 ); 322 assert( pPage!=0 );
330 pPgHdr = (PgHdr*)pPage->pExtra; 323 pPgHdr = (PgHdr*)pPage->pExtra;
331 assert( pPgHdr->pPage==0 ); 324 assert( pPgHdr->pPage==0 );
332 memset(pPgHdr, 0, sizeof(PgHdr)); 325 memset(pPgHdr, 0, sizeof(PgHdr));
333 pPgHdr->pPage = pPage; 326 pPgHdr->pPage = pPage;
334 pPgHdr->pData = pPage->pBuf; 327 pPgHdr->pData = pPage->pBuf;
335 pPgHdr->pExtra = (void *)&pPgHdr[1]; 328 pPgHdr->pExtra = (void *)&pPgHdr[1];
336 memset(pPgHdr->pExtra, 0, pCache->szExtra); 329 memset(pPgHdr->pExtra, 0, pCache->szExtra);
337 pPgHdr->pCache = pCache; 330 pPgHdr->pCache = pCache;
338 pPgHdr->pgno = pgno; 331 pPgHdr->pgno = pgno;
332 pPgHdr->flags = PGHDR_CLEAN;
339 return sqlite3PcacheFetchFinish(pCache,pgno,pPage); 333 return sqlite3PcacheFetchFinish(pCache,pgno,pPage);
340 } 334 }
341 335
342 /* 336 /*
343 ** This routine converts the sqlite3_pcache_page object returned by 337 ** This routine converts the sqlite3_pcache_page object returned by
344 ** sqlite3PcacheFetch() into an initialized PgHdr object. This routine 338 ** sqlite3PcacheFetch() into an initialized PgHdr object. This routine
345 ** must be called after sqlite3PcacheFetch() in order to get a usable 339 ** must be called after sqlite3PcacheFetch() in order to get a usable
346 ** result. 340 ** result.
347 */ 341 */
348 PgHdr *sqlite3PcacheFetchFinish( 342 PgHdr *sqlite3PcacheFetchFinish(
349 PCache *pCache, /* Obtain the page from this cache */ 343 PCache *pCache, /* Obtain the page from this cache */
350 Pgno pgno, /* Page number obtained */ 344 Pgno pgno, /* Page number obtained */
351 sqlite3_pcache_page *pPage /* Page obtained by prior PcacheFetch() call */ 345 sqlite3_pcache_page *pPage /* Page obtained by prior PcacheFetch() call */
352 ){ 346 ){
353 PgHdr *pPgHdr; 347 PgHdr *pPgHdr;
354 348
355 if( pPage==0 ) return 0; 349 assert( pPage!=0 );
356 pPgHdr = (PgHdr *)pPage->pExtra; 350 pPgHdr = (PgHdr *)pPage->pExtra;
357 351
358 if( !pPgHdr->pPage ){ 352 if( !pPgHdr->pPage ){
359 return pcacheFetchFinishWithInit(pCache, pgno, pPage); 353 return pcacheFetchFinishWithInit(pCache, pgno, pPage);
360 } 354 }
361 if( 0==pPgHdr->nRef ){ 355 pCache->nRefSum++;
362 pCache->nRef++;
363 }
364 pPgHdr->nRef++; 356 pPgHdr->nRef++;
365 if( pgno==1 ){
366 pCache->pPage1 = pPgHdr;
367 }
368 return pPgHdr; 357 return pPgHdr;
369 } 358 }
370 359
371 /* 360 /*
372 ** Decrement the reference count on a page. If the page is clean and the 361 ** Decrement the reference count on a page. If the page is clean and the
373 ** reference count drops to 0, then it is made eligible for recycling. 362 ** reference count drops to 0, then it is made eligible for recycling.
374 */ 363 */
375 void SQLITE_NOINLINE sqlite3PcacheRelease(PgHdr *p){ 364 void SQLITE_NOINLINE sqlite3PcacheRelease(PgHdr *p){
376 assert( p->nRef>0 ); 365 assert( p->nRef>0 );
377 p->nRef--; 366 p->pCache->nRefSum--;
378 if( p->nRef==0 ){ 367 if( (--p->nRef)==0 ){
379 p->pCache->nRef--; 368 if( p->flags&PGHDR_CLEAN ){
380 if( (p->flags&PGHDR_DIRTY)==0 ){
381 pcacheUnpin(p); 369 pcacheUnpin(p);
382 }else if( p->pDirtyPrev!=0 ){ 370 }else if( p->pDirtyPrev!=0 ){
383 /* Move the page to the head of the dirty list. */ 371 /* Move the page to the head of the dirty list. */
384 pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT); 372 pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT);
385 } 373 }
386 } 374 }
387 } 375 }
388 376
389 /* 377 /*
390 ** Increase the reference count of a supplied page by 1. 378 ** Increase the reference count of a supplied page by 1.
391 */ 379 */
392 void sqlite3PcacheRef(PgHdr *p){ 380 void sqlite3PcacheRef(PgHdr *p){
393 assert(p->nRef>0); 381 assert(p->nRef>0);
394 p->nRef++; 382 p->nRef++;
383 p->pCache->nRefSum++;
395 } 384 }
396 385
397 /* 386 /*
398 ** Drop a page from the cache. There must be exactly one reference to the 387 ** Drop a page from the cache. There must be exactly one reference to the
399 ** page. This function deletes that reference, so after it returns the 388 ** page. This function deletes that reference, so after it returns the
400 ** page pointed to by p is invalid. 389 ** page pointed to by p is invalid.
401 */ 390 */
402 void sqlite3PcacheDrop(PgHdr *p){ 391 void sqlite3PcacheDrop(PgHdr *p){
403 assert( p->nRef==1 ); 392 assert( p->nRef==1 );
404 if( p->flags&PGHDR_DIRTY ){ 393 if( p->flags&PGHDR_DIRTY ){
405 pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE); 394 pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE);
406 } 395 }
407 p->pCache->nRef--; 396 p->pCache->nRefSum--;
408 if( p->pgno==1 ){
409 p->pCache->pPage1 = 0;
410 }
411 sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 1); 397 sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 1);
412 } 398 }
413 399
414 /* 400 /*
415 ** Make sure the page is marked as dirty. If it isn't dirty already, 401 ** Make sure the page is marked as dirty. If it isn't dirty already,
416 ** make it so. 402 ** make it so.
417 */ 403 */
418 void sqlite3PcacheMakeDirty(PgHdr *p){ 404 void sqlite3PcacheMakeDirty(PgHdr *p){
419 p->flags &= ~PGHDR_DONT_WRITE;
420 assert( p->nRef>0 ); 405 assert( p->nRef>0 );
421 if( 0==(p->flags & PGHDR_DIRTY) ){ 406 if( p->flags & (PGHDR_CLEAN|PGHDR_DONT_WRITE) ){
422 p->flags |= PGHDR_DIRTY; 407 p->flags &= ~PGHDR_DONT_WRITE;
423 pcacheManageDirtyList(p, PCACHE_DIRTYLIST_ADD); 408 if( p->flags & PGHDR_CLEAN ){
409 p->flags ^= (PGHDR_DIRTY|PGHDR_CLEAN);
410 assert( (p->flags & (PGHDR_DIRTY|PGHDR_CLEAN))==PGHDR_DIRTY );
411 pcacheManageDirtyList(p, PCACHE_DIRTYLIST_ADD);
412 }
424 } 413 }
425 } 414 }
426 415
427 /* 416 /*
428 ** Make sure the page is marked as clean. If it isn't clean already, 417 ** Make sure the page is marked as clean. If it isn't clean already,
429 ** make it so. 418 ** make it so.
430 */ 419 */
431 void sqlite3PcacheMakeClean(PgHdr *p){ 420 void sqlite3PcacheMakeClean(PgHdr *p){
432 if( (p->flags & PGHDR_DIRTY) ){ 421 if( (p->flags & PGHDR_DIRTY) ){
422 assert( (p->flags & PGHDR_CLEAN)==0 );
433 pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE); 423 pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE);
434 p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC); 424 p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC|PGHDR_WRITEABLE);
425 p->flags |= PGHDR_CLEAN;
435 if( p->nRef==0 ){ 426 if( p->nRef==0 ){
436 pcacheUnpin(p); 427 pcacheUnpin(p);
437 } 428 }
438 } 429 }
439 } 430 }
440 431
441 /* 432 /*
442 ** Make every page in the cache clean. 433 ** Make every page in the cache clean.
443 */ 434 */
444 void sqlite3PcacheCleanAll(PCache *pCache){ 435 void sqlite3PcacheCleanAll(PCache *pCache){
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 /* This routine never gets call with a positive pgno except right 482 /* This routine never gets call with a positive pgno except right
492 ** after sqlite3PcacheCleanAll(). So if there are dirty pages, 483 ** after sqlite3PcacheCleanAll(). So if there are dirty pages,
493 ** it must be that pgno==0. 484 ** it must be that pgno==0.
494 */ 485 */
495 assert( p->pgno>0 ); 486 assert( p->pgno>0 );
496 if( ALWAYS(p->pgno>pgno) ){ 487 if( ALWAYS(p->pgno>pgno) ){
497 assert( p->flags&PGHDR_DIRTY ); 488 assert( p->flags&PGHDR_DIRTY );
498 sqlite3PcacheMakeClean(p); 489 sqlite3PcacheMakeClean(p);
499 } 490 }
500 } 491 }
501 if( pgno==0 && pCache->pPage1 ){ 492 if( pgno==0 && pCache->nRefSum ){
502 memset(pCache->pPage1->pData, 0, pCache->szPage); 493 sqlite3_pcache_page *pPage1;
503 pgno = 1; 494 pPage1 = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache,1,0);
495 if( ALWAYS(pPage1) ){ /* Page 1 is always available in cache, because
496 ** pCache->nRefSum>0 */
497 memset(pPage1->pBuf, 0, pCache->szPage);
498 pgno = 1;
499 }
504 } 500 }
505 sqlite3GlobalConfig.pcache2.xTruncate(pCache->pCache, pgno+1); 501 sqlite3GlobalConfig.pcache2.xTruncate(pCache->pCache, pgno+1);
506 } 502 }
507 } 503 }
508 504
509 /* 505 /*
510 ** Close a cache. 506 ** Close a cache.
511 */ 507 */
512 void sqlite3PcacheClose(PCache *pCache){ 508 void sqlite3PcacheClose(PCache *pCache){
513 assert( pCache->pCache!=0 ); 509 assert( pCache->pCache!=0 );
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 */ 592 */
597 PgHdr *sqlite3PcacheDirtyList(PCache *pCache){ 593 PgHdr *sqlite3PcacheDirtyList(PCache *pCache){
598 PgHdr *p; 594 PgHdr *p;
599 for(p=pCache->pDirty; p; p=p->pDirtyNext){ 595 for(p=pCache->pDirty; p; p=p->pDirtyNext){
600 p->pDirty = p->pDirtyNext; 596 p->pDirty = p->pDirtyNext;
601 } 597 }
602 return pcacheSortDirtyList(pCache->pDirty); 598 return pcacheSortDirtyList(pCache->pDirty);
603 } 599 }
604 600
605 /* 601 /*
606 ** Return the total number of referenced pages held by the cache. 602 ** Return the total number of references to all pages held by the cache.
603 **
604 ** This is not the total number of pages referenced, but the sum of the
605 ** reference count for all pages.
607 */ 606 */
608 int sqlite3PcacheRefCount(PCache *pCache){ 607 int sqlite3PcacheRefCount(PCache *pCache){
609 return pCache->nRef; 608 return pCache->nRefSum;
610 } 609 }
611 610
612 /* 611 /*
613 ** Return the number of references to the page supplied as an argument. 612 ** Return the number of references to the page supplied as an argument.
614 */ 613 */
615 int sqlite3PcachePageRefcount(PgHdr *p){ 614 int sqlite3PcachePageRefcount(PgHdr *p){
616 return p->nRef; 615 return p->nRef;
617 } 616 }
618 617
619 /* 618 /*
(...skipping 17 matching lines...) Expand all
637 ** Set the suggested cache-size value. 636 ** Set the suggested cache-size value.
638 */ 637 */
639 void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){ 638 void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){
640 assert( pCache->pCache!=0 ); 639 assert( pCache->pCache!=0 );
641 pCache->szCache = mxPage; 640 pCache->szCache = mxPage;
642 sqlite3GlobalConfig.pcache2.xCachesize(pCache->pCache, 641 sqlite3GlobalConfig.pcache2.xCachesize(pCache->pCache,
643 numberOfCachePages(pCache)); 642 numberOfCachePages(pCache));
644 } 643 }
645 644
646 /* 645 /*
646 ** Set the suggested cache-spill value. Make no changes if if the
647 ** argument is zero. Return the effective cache-spill size, which will
648 ** be the larger of the szSpill and szCache.
649 */
650 int sqlite3PcacheSetSpillsize(PCache *p, int mxPage){
651 int res;
652 assert( p->pCache!=0 );
653 if( mxPage ){
654 if( mxPage<0 ){
655 mxPage = (int)((-1024*(i64)mxPage)/(p->szPage+p->szExtra));
656 }
657 p->szSpill = mxPage;
658 }
659 res = numberOfCachePages(p);
660 if( res<p->szSpill ) res = p->szSpill;
661 return res;
662 }
663
664 /*
647 ** Free up as much memory as possible from the page cache. 665 ** Free up as much memory as possible from the page cache.
648 */ 666 */
649 void sqlite3PcacheShrink(PCache *pCache){ 667 void sqlite3PcacheShrink(PCache *pCache){
650 assert( pCache->pCache!=0 ); 668 assert( pCache->pCache!=0 );
651 sqlite3GlobalConfig.pcache2.xShrink(pCache->pCache); 669 sqlite3GlobalConfig.pcache2.xShrink(pCache->pCache);
652 } 670 }
653 671
672 /*
673 ** Return the size of the header added by this middleware layer
674 ** in the page-cache hierarchy.
675 */
676 int sqlite3HeaderSizePcache(void){ return ROUND8(sizeof(PgHdr)); }
677
678
654 #if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG) 679 #if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
655 /* 680 /*
656 ** For all dirty pages currently in the cache, invoke the specified 681 ** For all dirty pages currently in the cache, invoke the specified
657 ** callback. This is only used if the SQLITE_CHECK_PAGES macro is 682 ** callback. This is only used if the SQLITE_CHECK_PAGES macro is
658 ** defined. 683 ** defined.
659 */ 684 */
660 void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *)){ 685 void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *)){
661 PgHdr *pDirty; 686 PgHdr *pDirty;
662 for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext){ 687 for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext){
663 xIter(pDirty); 688 xIter(pDirty);
664 } 689 }
665 } 690 }
666 #endif 691 #endif
OLDNEW
« no previous file with comments | « third_party/sqlite/sqlite-src-3100200/src/pcache.h ('k') | third_party/sqlite/sqlite-src-3100200/src/pcache1.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698