/ Hex Artifact Content
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Artifact d210cf90d04365a74f85d21374dded65af67b0cb:


0000: 2f 2a 0a 2a 2a 20 32 30 30 38 20 41 75 67 75 73  /*.** 2008 Augus
0010: 74 20 30 35 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61  t 05.**.** The a
0020: 75 74 68 6f 72 20 64 69 73 63 6c 61 69 6d 73 20  uthor disclaims 
0030: 63 6f 70 79 72 69 67 68 74 20 74 6f 20 74 68 69  copyright to thi
0040: 73 20 73 6f 75 72 63 65 20 63 6f 64 65 2e 20 20  s source code.  
0050: 49 6e 20 70 6c 61 63 65 20 6f 66 0a 2a 2a 20 61  In place of.** a
0060: 20 6c 65 67 61 6c 20 6e 6f 74 69 63 65 2c 20 68   legal notice, h
0070: 65 72 65 20 69 73 20 61 20 62 6c 65 73 73 69 6e  ere is a blessin
0080: 67 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79 20  g:.**.**    May 
0090: 79 6f 75 20 64 6f 20 67 6f 6f 64 20 61 6e 64 20  you do good and 
00a0: 6e 6f 74 20 65 76 69 6c 2e 0a 2a 2a 20 20 20 20  not evil..**    
00b0: 4d 61 79 20 79 6f 75 20 66 69 6e 64 20 66 6f 72  May you find for
00c0: 67 69 76 65 6e 65 73 73 20 66 6f 72 20 79 6f 75  giveness for you
00d0: 72 73 65 6c 66 20 61 6e 64 20 66 6f 72 67 69 76  rself and forgiv
00e0: 65 20 6f 74 68 65 72 73 2e 0a 2a 2a 20 20 20 20  e others..**    
00f0: 4d 61 79 20 79 6f 75 20 73 68 61 72 65 20 66 72  May you share fr
0100: 65 65 6c 79 2c 20 6e 65 76 65 72 20 74 61 6b 69  eely, never taki
0110: 6e 67 20 6d 6f 72 65 20 74 68 61 6e 20 79 6f 75  ng more than you
0120: 20 67 69 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a   give..**.******
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 2a 2a 2a 0a 2a 2a 20 54 68 69 73 20 66 69 6c 65  ***.** This file
0180: 20 69 6d 70 6c 65 6d 65 6e 74 73 20 74 68 61 74   implements that
0190: 20 70 61 67 65 20 63 61 63 68 65 2e 0a 2a 2f 0a   page cache..*/.
01a0: 23 69 6e 63 6c 75 64 65 20 22 73 71 6c 69 74 65  #include "sqlite
01b0: 49 6e 74 2e 68 22 0a 0a 2f 2a 0a 2a 2a 20 41 20  Int.h"../*.** A 
01c0: 63 6f 6d 70 6c 65 74 65 20 70 61 67 65 20 63 61  complete page ca
01d0: 63 68 65 20 69 73 20 61 6e 20 69 6e 73 74 61 6e  che is an instan
01e0: 63 65 20 6f 66 20 74 68 69 73 20 73 74 72 75 63  ce of this struc
01f0: 74 75 72 65 2e 0a 2a 2f 0a 73 74 72 75 63 74 20  ture..*/.struct 
0200: 50 43 61 63 68 65 20 7b 0a 20 20 50 67 48 64 72  PCache {.  PgHdr
0210: 20 2a 70 44 69 72 74 79 2c 20 2a 70 44 69 72 74   *pDirty, *pDirt
0220: 79 54 61 69 6c 3b 20 20 20 20 20 20 20 20 20 2f  yTail;         /
0230: 2a 20 4c 69 73 74 20 6f 66 20 64 69 72 74 79 20  * List of dirty 
0240: 70 61 67 65 73 20 69 6e 20 4c 52 55 20 6f 72 64  pages in LRU ord
0250: 65 72 20 2a 2f 0a 20 20 50 67 48 64 72 20 2a 70  er */.  PgHdr *p
0260: 53 79 6e 63 65 64 3b 20 20 20 20 20 20 20 20 20  Synced;         
0270: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c              /* L
0280: 61 73 74 20 73 79 6e 63 65 64 20 70 61 67 65 20  ast synced page 
0290: 69 6e 20 64 69 72 74 79 20 70 61 67 65 20 6c 69  in dirty page li
02a0: 73 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 52 65 66  st */.  int nRef
02b0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
02c0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
02d0: 75 6d 62 65 72 20 6f 66 20 72 65 66 65 72 65 6e  umber of referen
02e0: 63 65 64 20 70 61 67 65 73 20 2a 2f 0a 20 20 69  ced pages */.  i
02f0: 6e 74 20 73 7a 43 61 63 68 65 3b 20 20 20 20 20  nt szCache;     
0300: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0310: 20 20 20 2f 2a 20 43 6f 6e 66 69 67 75 72 65 64     /* Configured
0320: 20 63 61 63 68 65 20 73 69 7a 65 20 2a 2f 0a 20   cache size */. 
0330: 20 69 6e 74 20 73 7a 50 61 67 65 3b 20 20 20 20   int szPage;    
0340: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0350: 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
0360: 65 76 65 72 79 20 70 61 67 65 20 69 6e 20 74 68  every page in th
0370: 69 73 20 63 61 63 68 65 20 2a 2f 0a 20 20 69 6e  is cache */.  in
0380: 74 20 73 7a 45 78 74 72 61 3b 20 20 20 20 20 20  t szExtra;      
0390: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
03a0: 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 65 78 74    /* Size of ext
03b0: 72 61 20 73 70 61 63 65 20 66 6f 72 20 65 61 63  ra space for eac
03c0: 68 20 70 61 67 65 20 2a 2f 0a 20 20 75 38 20 62  h page */.  u8 b
03d0: 50 75 72 67 65 61 62 6c 65 3b 20 20 20 20 20 20  Purgeable;      
03e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
03f0: 2f 2a 20 54 72 75 65 20 69 66 20 70 61 67 65 73  /* True if pages
0400: 20 61 72 65 20 6f 6e 20 62 61 63 6b 69 6e 67 20   are on backing 
0410: 73 74 6f 72 65 20 2a 2f 0a 20 20 75 38 20 65 43  store */.  u8 eC
0420: 72 65 61 74 65 3b 20 20 20 20 20 20 20 20 20 20  reate;          
0430: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0440: 2a 20 65 43 72 65 61 74 65 20 76 61 6c 75 65 20  * eCreate value 
0450: 66 6f 72 20 66 6f 72 20 78 46 65 74 63 68 28 29  for for xFetch()
0460: 20 2a 2f 0a 20 20 69 6e 74 20 28 2a 78 53 74 72   */.  int (*xStr
0470: 65 73 73 29 28 76 6f 69 64 2a 2c 50 67 48 64 72  ess)(void*,PgHdr
0480: 2a 29 3b 20 20 20 20 20 20 20 2f 2a 20 43 61 6c  *);       /* Cal
0490: 6c 20 74 6f 20 74 72 79 20 6d 61 6b 65 20 61 20  l to try make a 
04a0: 70 61 67 65 20 63 6c 65 61 6e 20 2a 2f 0a 20 20  page clean */.  
04b0: 76 6f 69 64 20 2a 70 53 74 72 65 73 73 3b 20 20  void *pStress;  
04c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
04d0: 20 20 20 20 2f 2a 20 41 72 67 75 6d 65 6e 74 20      /* Argument 
04e0: 74 6f 20 78 53 74 72 65 73 73 20 2a 2f 0a 20 20  to xStress */.  
04f0: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a  sqlite3_pcache *
0500: 70 43 61 63 68 65 3b 20 20 20 20 20 20 20 20 20  pCache;         
0510: 20 20 20 20 2f 2a 20 50 6c 75 67 67 61 62 6c 65      /* Pluggable
0520: 20 63 61 63 68 65 20 6d 6f 64 75 6c 65 20 2a 2f   cache module */
0530: 0a 20 20 50 67 48 64 72 20 2a 70 50 61 67 65 31  .  PgHdr *pPage1
0540: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
0550: 20 20 20 20 20 20 20 2f 2a 20 52 65 66 65 72 65         /* Refere
0560: 6e 63 65 20 74 6f 20 70 61 67 65 20 31 20 2a 2f  nce to page 1 */
0570: 0a 7d 3b 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  .};../**********
0580: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0590: 2a 2a 2a 2a 2a 2a 2a 2a 20 4c 69 6e 6b 65 64 20  ******** Linked 
05a0: 4c 69 73 74 20 4d 61 6e 61 67 65 6d 65 6e 74 20  List Management 
05b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
05c0: 2a 2a 2a 2a 2f 0a 0a 2f 2a 20 41 6c 6c 6f 77 65  ****/../* Allowe
05d0: 64 20 76 61 6c 75 65 73 20 66 6f 72 20 73 65 63  d values for sec
05e0: 6f 6e 64 20 61 72 67 75 6d 65 6e 74 20 74 6f 20  ond argument to 
05f0: 70 63 61 63 68 65 4d 61 6e 61 67 65 44 69 72 74  pcacheManageDirt
0600: 79 4c 69 73 74 28 29 20 2a 2f 0a 23 64 65 66 69  yList() */.#defi
0610: 6e 65 20 50 43 41 43 48 45 5f 44 49 52 54 59 4c  ne PCACHE_DIRTYL
0620: 49 53 54 5f 52 45 4d 4f 56 45 20 20 20 31 20 20  IST_REMOVE   1  
0630: 20 20 2f 2a 20 52 65 6d 6f 76 65 20 70 50 61 67    /* Remove pPag
0640: 65 20 66 72 6f 6d 20 64 69 72 74 79 20 6c 69 73  e from dirty lis
0650: 74 20 2a 2f 0a 23 64 65 66 69 6e 65 20 50 43 41  t */.#define PCA
0660: 43 48 45 5f 44 49 52 54 59 4c 49 53 54 5f 41 44  CHE_DIRTYLIST_AD
0670: 44 20 20 20 20 20 20 32 20 20 20 20 2f 2a 20 41  D      2    /* A
0680: 64 64 20 70 50 61 67 65 20 74 6f 20 74 68 65 20  dd pPage to the 
0690: 64 69 72 74 79 20 6c 69 73 74 20 2a 2f 0a 23 64  dirty list */.#d
06a0: 65 66 69 6e 65 20 50 43 41 43 48 45 5f 44 49 52  efine PCACHE_DIR
06b0: 54 59 4c 49 53 54 5f 46 52 4f 4e 54 20 20 20 20  TYLIST_FRONT    
06c0: 33 20 20 20 20 2f 2a 20 4d 6f 76 65 20 70 50 61  3    /* Move pPa
06d0: 67 65 20 74 6f 20 74 68 65 20 66 72 6f 6e 74 20  ge to the front 
06e0: 6f 66 20 74 68 65 20 6c 69 73 74 20 2a 2f 0a 0a  of the list */..
06f0: 2f 2a 0a 2a 2a 20 4d 61 6e 61 67 65 20 70 50 61  /*.** Manage pPa
0700: 67 65 27 73 20 70 61 72 74 69 63 69 70 61 74 69  ge's participati
0710: 6f 6e 20 6f 6e 20 74 68 65 20 64 69 72 74 79 20  on on the dirty 
0720: 6c 69 73 74 2e 20 20 42 69 74 73 20 6f 66 20 74  list.  Bits of t
0730: 68 65 20 61 64 64 52 65 6d 6f 76 65 0a 2a 2a 20  he addRemove.** 
0740: 61 72 67 75 6d 65 6e 74 20 64 65 74 65 72 6d 69  argument determi
0750: 6e 65 73 20 77 68 61 74 20 6f 70 65 72 61 74 69  nes what operati
0760: 6f 6e 20 74 6f 20 64 6f 2e 20 20 54 68 65 20 30  on to do.  The 0
0770: 78 30 31 20 62 69 74 20 6d 65 61 6e 73 20 66 69  x01 bit means fi
0780: 72 73 74 0a 2a 2a 20 72 65 6d 6f 76 65 20 70 50  rst.** remove pP
0790: 61 67 65 20 66 72 6f 6d 20 74 68 65 20 64 69 72  age from the dir
07a0: 74 79 20 6c 69 73 74 2e 20 20 54 68 65 20 30 78  ty list.  The 0x
07b0: 30 32 20 6d 65 61 6e 73 20 61 64 64 20 70 50 61  02 means add pPa
07c0: 67 65 20 62 61 63 6b 20 74 6f 0a 2a 2a 20 74 68  ge back to.** th
07d0: 65 20 64 69 72 74 79 20 6c 69 73 74 2e 20 20 44  e dirty list.  D
07e0: 6f 69 6e 67 20 62 6f 74 68 20 6d 6f 76 65 73 20  oing both moves 
07f0: 70 50 61 67 65 20 74 6f 20 74 68 65 20 66 72 6f  pPage to the fro
0800: 6e 74 20 6f 66 20 74 68 65 20 64 69 72 74 79 20  nt of the dirty 
0810: 6c 69 73 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  list..*/.static 
0820: 76 6f 69 64 20 70 63 61 63 68 65 4d 61 6e 61 67  void pcacheManag
0830: 65 44 69 72 74 79 4c 69 73 74 28 50 67 48 64 72  eDirtyList(PgHdr
0840: 20 2a 70 50 61 67 65 2c 20 75 38 20 61 64 64 52   *pPage, u8 addR
0850: 65 6d 6f 76 65 29 7b 0a 20 20 50 43 61 63 68 65  emove){.  PCache
0860: 20 2a 70 20 3d 20 70 50 61 67 65 2d 3e 70 43 61   *p = pPage->pCa
0870: 63 68 65 3b 0a 0a 20 20 69 66 28 20 61 64 64 52  che;..  if( addR
0880: 65 6d 6f 76 65 20 26 20 50 43 41 43 48 45 5f 44  emove & PCACHE_D
0890: 49 52 54 59 4c 49 53 54 5f 52 45 4d 4f 56 45 20  IRTYLIST_REMOVE 
08a0: 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70  ){.    assert( p
08b0: 50 61 67 65 2d 3e 70 44 69 72 74 79 4e 65 78 74  Page->pDirtyNext
08c0: 20 7c 7c 20 70 50 61 67 65 3d 3d 70 2d 3e 70 44   || pPage==p->pD
08d0: 69 72 74 79 54 61 69 6c 20 29 3b 0a 20 20 20 20  irtyTail );.    
08e0: 61 73 73 65 72 74 28 20 70 50 61 67 65 2d 3e 70  assert( pPage->p
08f0: 44 69 72 74 79 50 72 65 76 20 7c 7c 20 70 50 61  DirtyPrev || pPa
0900: 67 65 3d 3d 70 2d 3e 70 44 69 72 74 79 20 29 3b  ge==p->pDirty );
0910: 0a 20 20 0a 20 20 20 20 2f 2a 20 55 70 64 61 74  .  .    /* Updat
0920: 65 20 74 68 65 20 50 43 61 63 68 65 31 2e 70 53  e the PCache1.pS
0930: 79 6e 63 65 64 20 76 61 72 69 61 62 6c 65 20 69  ynced variable i
0940: 66 20 6e 65 63 65 73 73 61 72 79 2e 20 2a 2f 0a  f necessary. */.
0950: 20 20 20 20 69 66 28 20 70 2d 3e 70 53 79 6e 63      if( p->pSync
0960: 65 64 3d 3d 70 50 61 67 65 20 29 7b 0a 20 20 20  ed==pPage ){.   
0970: 20 20 20 50 67 48 64 72 20 2a 70 53 79 6e 63 65     PgHdr *pSynce
0980: 64 20 3d 20 70 50 61 67 65 2d 3e 70 44 69 72 74  d = pPage->pDirt
0990: 79 50 72 65 76 3b 0a 20 20 20 20 20 20 77 68 69  yPrev;.      whi
09a0: 6c 65 28 20 70 53 79 6e 63 65 64 20 26 26 20 28  le( pSynced && (
09b0: 70 53 79 6e 63 65 64 2d 3e 66 6c 61 67 73 26 50  pSynced->flags&P
09c0: 47 48 44 52 5f 4e 45 45 44 5f 53 59 4e 43 29 20  GHDR_NEED_SYNC) 
09d0: 29 7b 0a 20 20 20 20 20 20 20 20 70 53 79 6e 63  ){.        pSync
09e0: 65 64 20 3d 20 70 53 79 6e 63 65 64 2d 3e 70 44  ed = pSynced->pD
09f0: 69 72 74 79 50 72 65 76 3b 0a 20 20 20 20 20 20  irtyPrev;.      
0a00: 7d 0a 20 20 20 20 20 20 70 2d 3e 70 53 79 6e 63  }.      p->pSync
0a10: 65 64 20 3d 20 70 53 79 6e 63 65 64 3b 0a 20 20  ed = pSynced;.  
0a20: 20 20 7d 0a 20 20 0a 20 20 20 20 69 66 28 20 70    }.  .    if( p
0a30: 50 61 67 65 2d 3e 70 44 69 72 74 79 4e 65 78 74  Page->pDirtyNext
0a40: 20 29 7b 0a 20 20 20 20 20 20 70 50 61 67 65 2d   ){.      pPage-
0a50: 3e 70 44 69 72 74 79 4e 65 78 74 2d 3e 70 44 69  >pDirtyNext->pDi
0a60: 72 74 79 50 72 65 76 20 3d 20 70 50 61 67 65 2d  rtyPrev = pPage-
0a70: 3e 70 44 69 72 74 79 50 72 65 76 3b 0a 20 20 20  >pDirtyPrev;.   
0a80: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 61 73   }else{.      as
0a90: 73 65 72 74 28 20 70 50 61 67 65 3d 3d 70 2d 3e  sert( pPage==p->
0aa0: 70 44 69 72 74 79 54 61 69 6c 20 29 3b 0a 20 20  pDirtyTail );.  
0ab0: 20 20 20 20 70 2d 3e 70 44 69 72 74 79 54 61 69      p->pDirtyTai
0ac0: 6c 20 3d 20 70 50 61 67 65 2d 3e 70 44 69 72 74  l = pPage->pDirt
0ad0: 79 50 72 65 76 3b 0a 20 20 20 20 7d 0a 20 20 20  yPrev;.    }.   
0ae0: 20 69 66 28 20 70 50 61 67 65 2d 3e 70 44 69 72   if( pPage->pDir
0af0: 74 79 50 72 65 76 20 29 7b 0a 20 20 20 20 20 20  tyPrev ){.      
0b00: 70 50 61 67 65 2d 3e 70 44 69 72 74 79 50 72 65  pPage->pDirtyPre
0b10: 76 2d 3e 70 44 69 72 74 79 4e 65 78 74 20 3d 20  v->pDirtyNext = 
0b20: 70 50 61 67 65 2d 3e 70 44 69 72 74 79 4e 65 78  pPage->pDirtyNex
0b30: 74 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  t;.    }else{.  
0b40: 20 20 20 20 61 73 73 65 72 74 28 20 70 50 61 67      assert( pPag
0b50: 65 3d 3d 70 2d 3e 70 44 69 72 74 79 20 29 3b 0a  e==p->pDirty );.
0b60: 20 20 20 20 20 20 70 2d 3e 70 44 69 72 74 79 20        p->pDirty 
0b70: 3d 20 70 50 61 67 65 2d 3e 70 44 69 72 74 79 4e  = pPage->pDirtyN
0b80: 65 78 74 3b 0a 20 20 20 20 20 20 69 66 28 20 70  ext;.      if( p
0b90: 2d 3e 70 44 69 72 74 79 3d 3d 30 20 26 26 20 70  ->pDirty==0 && p
0ba0: 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 29 7b 0a  ->bPurgeable ){.
0bb0: 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28 20          assert( 
0bc0: 70 2d 3e 65 43 72 65 61 74 65 3d 3d 31 20 29 3b  p->eCreate==1 );
0bd0: 0a 20 20 20 20 20 20 20 20 70 2d 3e 65 43 72 65  .        p->eCre
0be0: 61 74 65 20 3d 20 32 3b 0a 20 20 20 20 20 20 7d  ate = 2;.      }
0bf0: 0a 20 20 20 20 7d 0a 20 20 20 20 70 50 61 67 65  .    }.    pPage
0c00: 2d 3e 70 44 69 72 74 79 4e 65 78 74 20 3d 20 30  ->pDirtyNext = 0
0c10: 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 44 69  ;.    pPage->pDi
0c20: 72 74 79 50 72 65 76 20 3d 20 30 3b 0a 20 20 7d  rtyPrev = 0;.  }
0c30: 0a 20 20 69 66 28 20 61 64 64 52 65 6d 6f 76 65  .  if( addRemove
0c40: 20 26 20 50 43 41 43 48 45 5f 44 49 52 54 59 4c   & PCACHE_DIRTYL
0c50: 49 53 54 5f 41 44 44 20 29 7b 0a 20 20 20 20 61  IST_ADD ){.    a
0c60: 73 73 65 72 74 28 20 70 50 61 67 65 2d 3e 70 44  ssert( pPage->pD
0c70: 69 72 74 79 4e 65 78 74 3d 3d 30 20 26 26 20 70  irtyNext==0 && p
0c80: 50 61 67 65 2d 3e 70 44 69 72 74 79 50 72 65 76  Page->pDirtyPrev
0c90: 3d 3d 30 20 26 26 20 70 2d 3e 70 44 69 72 74 79  ==0 && p->pDirty
0ca0: 21 3d 70 50 61 67 65 20 29 3b 0a 20 20 0a 20 20  !=pPage );.  .  
0cb0: 20 20 70 50 61 67 65 2d 3e 70 44 69 72 74 79 4e    pPage->pDirtyN
0cc0: 65 78 74 20 3d 20 70 2d 3e 70 44 69 72 74 79 3b  ext = p->pDirty;
0cd0: 0a 20 20 20 20 69 66 28 20 70 50 61 67 65 2d 3e  .    if( pPage->
0ce0: 70 44 69 72 74 79 4e 65 78 74 20 29 7b 0a 20 20  pDirtyNext ){.  
0cf0: 20 20 20 20 61 73 73 65 72 74 28 20 70 50 61 67      assert( pPag
0d00: 65 2d 3e 70 44 69 72 74 79 4e 65 78 74 2d 3e 70  e->pDirtyNext->p
0d10: 44 69 72 74 79 50 72 65 76 3d 3d 30 20 29 3b 0a  DirtyPrev==0 );.
0d20: 20 20 20 20 20 20 70 50 61 67 65 2d 3e 70 44 69        pPage->pDi
0d30: 72 74 79 4e 65 78 74 2d 3e 70 44 69 72 74 79 50  rtyNext->pDirtyP
0d40: 72 65 76 20 3d 20 70 50 61 67 65 3b 0a 20 20 20  rev = pPage;.   
0d50: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 2d   }else{.      p-
0d60: 3e 70 44 69 72 74 79 54 61 69 6c 20 3d 20 70 50  >pDirtyTail = pP
0d70: 61 67 65 3b 0a 20 20 20 20 20 20 69 66 28 20 70  age;.      if( p
0d80: 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 29 7b 0a  ->bPurgeable ){.
0d90: 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28 20          assert( 
0da0: 70 2d 3e 65 43 72 65 61 74 65 3d 3d 32 20 29 3b  p->eCreate==2 );
0db0: 0a 20 20 20 20 20 20 20 20 70 2d 3e 65 43 72 65  .        p->eCre
0dc0: 61 74 65 20 3d 20 31 3b 0a 20 20 20 20 20 20 7d  ate = 1;.      }
0dd0: 0a 20 20 20 20 7d 0a 20 20 20 20 70 2d 3e 70 44  .    }.    p->pD
0de0: 69 72 74 79 20 3d 20 70 50 61 67 65 3b 0a 20 20  irty = pPage;.  
0df0: 20 20 69 66 28 20 21 70 2d 3e 70 53 79 6e 63 65    if( !p->pSynce
0e00: 64 20 26 26 20 30 3d 3d 28 70 50 61 67 65 2d 3e  d && 0==(pPage->
0e10: 66 6c 61 67 73 26 50 47 48 44 52 5f 4e 45 45 44  flags&PGHDR_NEED
0e20: 5f 53 59 4e 43 29 20 29 7b 0a 20 20 20 20 20 20  _SYNC) ){.      
0e30: 70 2d 3e 70 53 79 6e 63 65 64 20 3d 20 70 50 61  p->pSynced = pPa
0e40: 67 65 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a  ge;.    }.  }.}.
0e50: 0a 2f 2a 0a 2a 2a 20 57 72 61 70 70 65 72 20 61  ./*.** Wrapper a
0e60: 72 6f 75 6e 64 20 74 68 65 20 70 6c 75 67 67 61  round the plugga
0e70: 62 6c 65 20 63 61 63 68 65 73 20 78 55 6e 70 69  ble caches xUnpi
0e80: 6e 20 6d 65 74 68 6f 64 2e 20 49 66 20 74 68 65  n method. If the
0e90: 20 63 61 63 68 65 20 69 73 0a 2a 2a 20 62 65 69   cache is.** bei
0ea0: 6e 67 20 75 73 65 64 20 66 6f 72 20 61 6e 20 69  ng used for an i
0eb0: 6e 2d 6d 65 6d 6f 72 79 20 64 61 74 61 62 61 73  n-memory databas
0ec0: 65 2c 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  e, this function
0ed0: 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a 2a 2f 0a   is a no-op..*/.
0ee0: 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63  static void pcac
0ef0: 68 65 55 6e 70 69 6e 28 50 67 48 64 72 20 2a 70  heUnpin(PgHdr *p
0f00: 29 7b 0a 20 20 69 66 28 20 70 2d 3e 70 43 61 63  ){.  if( p->pCac
0f10: 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 29  he->bPurgeable )
0f20: 7b 0a 20 20 20 20 69 66 28 20 70 2d 3e 70 67 6e  {.    if( p->pgn
0f30: 6f 3d 3d 31 20 29 7b 0a 20 20 20 20 20 20 70 2d  o==1 ){.      p-
0f40: 3e 70 43 61 63 68 65 2d 3e 70 50 61 67 65 31 20  >pCache->pPage1 
0f50: 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73  = 0;.    }.    s
0f60: 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66  qlite3GlobalConf
0f70: 69 67 2e 70 63 61 63 68 65 32 2e 78 55 6e 70 69  ig.pcache2.xUnpi
0f80: 6e 28 70 2d 3e 70 43 61 63 68 65 2d 3e 70 43 61  n(p->pCache->pCa
0f90: 63 68 65 2c 20 70 2d 3e 70 50 61 67 65 2c 20 30  che, p->pPage, 0
0fa0: 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  );.  }.}../*.** 
0fb0: 43 6f 6d 70 75 74 65 20 74 68 65 20 6e 75 6d 62  Compute the numb
0fc0: 65 72 20 6f 66 20 70 61 67 65 73 20 6f 66 20 63  er of pages of c
0fd0: 61 63 68 65 20 72 65 71 75 65 73 74 65 64 2e 0a  ache requested..
0fe0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 6e 75  */.static int nu
0ff0: 6d 62 65 72 4f 66 43 61 63 68 65 50 61 67 65 73  mberOfCachePages
1000: 28 50 43 61 63 68 65 20 2a 70 29 7b 0a 20 20 69  (PCache *p){.  i
1010: 66 28 20 70 2d 3e 73 7a 43 61 63 68 65 3e 3d 30  f( p->szCache>=0
1020: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 70   ){.    return p
1030: 2d 3e 73 7a 43 61 63 68 65 3b 0a 20 20 7d 65 6c  ->szCache;.  }el
1040: 73 65 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 28  se{.    return (
1050: 69 6e 74 29 28 28 2d 31 30 32 34 2a 28 69 36 34  int)((-1024*(i64
1060: 29 70 2d 3e 73 7a 43 61 63 68 65 29 2f 28 70 2d  )p->szCache)/(p-
1070: 3e 73 7a 50 61 67 65 2b 70 2d 3e 73 7a 45 78 74  >szPage+p->szExt
1080: 72 61 29 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 2a  ra));.  }.}../**
1090: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
10a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
10b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
10c0: 2a 20 47 65 6e 65 72 61 6c 20 49 6e 74 65 72 66  * General Interf
10d0: 61 63 65 73 20 2a 2a 2a 2a 2a 2a 0a 2a 2a 0a 2a  aces ******.**.*
10e0: 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 61 6e 64  * Initialize and
10f0: 20 73 68 75 74 64 6f 77 6e 20 74 68 65 20 70 61   shutdown the pa
1100: 67 65 20 63 61 63 68 65 20 73 75 62 73 79 73 74  ge cache subsyst
1110: 65 6d 2e 20 4e 65 69 74 68 65 72 20 6f 66 20 74  em. Neither of t
1120: 68 65 73 65 20 0a 2a 2a 20 66 75 6e 63 74 69 6f  hese .** functio
1130: 6e 73 20 61 72 65 20 74 68 72 65 61 64 73 61 66  ns are threadsaf
1140: 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  e..*/.int sqlite
1150: 33 50 63 61 63 68 65 49 6e 69 74 69 61 6c 69 7a  3PcacheInitializ
1160: 65 28 76 6f 69 64 29 7b 0a 20 20 69 66 28 20 73  e(void){.  if( s
1170: 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66  qlite3GlobalConf
1180: 69 67 2e 70 63 61 63 68 65 32 2e 78 49 6e 69 74  ig.pcache2.xInit
1190: 3d 3d 30 20 29 7b 0a 20 20 20 20 2f 2a 20 49 4d  ==0 ){.    /* IM
11a0: 50 4c 45 4d 45 4e 54 41 54 49 4f 4e 2d 4f 46 3a  PLEMENTATION-OF:
11b0: 20 52 2d 32 36 38 30 31 2d 36 34 31 33 37 20 49   R-26801-64137 I
11c0: 66 20 74 68 65 20 78 49 6e 69 74 28 29 20 6d 65  f the xInit() me
11d0: 74 68 6f 64 20 69 73 20 4e 55 4c 4c 2c 20 74 68  thod is NULL, th
11e0: 65 6e 20 74 68 65 0a 20 20 20 20 2a 2a 20 62 75  en the.    ** bu
11f0: 69 6c 74 2d 69 6e 20 64 65 66 61 75 6c 74 20 70  ilt-in default p
1200: 61 67 65 20 63 61 63 68 65 20 69 73 20 75 73 65  age cache is use
1210: 64 20 69 6e 73 74 65 61 64 20 6f 66 20 74 68 65  d instead of the
1220: 20 61 70 70 6c 69 63 61 74 69 6f 6e 20 64 65 66   application def
1230: 69 6e 65 64 0a 20 20 20 20 2a 2a 20 70 61 67 65  ined.    ** page
1240: 20 63 61 63 68 65 2e 20 2a 2f 0a 20 20 20 20 73   cache. */.    s
1250: 71 6c 69 74 65 33 50 43 61 63 68 65 53 65 74 44  qlite3PCacheSetD
1260: 65 66 61 75 6c 74 28 29 3b 0a 20 20 7d 0a 20 20  efault();.  }.  
1270: 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 47 6c  return sqlite3Gl
1280: 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68  obalConfig.pcach
1290: 65 32 2e 78 49 6e 69 74 28 73 71 6c 69 74 65 33  e2.xInit(sqlite3
12a0: 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61  GlobalConfig.pca
12b0: 63 68 65 32 2e 70 41 72 67 29 3b 0a 7d 0a 76 6f  che2.pArg);.}.vo
12c0: 69 64 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  id sqlite3Pcache
12d0: 53 68 75 74 64 6f 77 6e 28 76 6f 69 64 29 7b 0a  Shutdown(void){.
12e0: 20 20 69 66 28 20 73 71 6c 69 74 65 33 47 6c 6f    if( sqlite3Glo
12f0: 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65  balConfig.pcache
1300: 32 2e 78 53 68 75 74 64 6f 77 6e 20 29 7b 0a 20  2.xShutdown ){. 
1310: 20 20 20 2f 2a 20 49 4d 50 4c 45 4d 45 4e 54 41     /* IMPLEMENTA
1320: 54 49 4f 4e 2d 4f 46 3a 20 52 2d 32 36 30 30 30  TION-OF: R-26000
1330: 2d 35 36 35 38 39 20 54 68 65 20 78 53 68 75 74  -56589 The xShut
1340: 64 6f 77 6e 28 29 20 6d 65 74 68 6f 64 20 6d 61  down() method ma
1350: 79 20 62 65 20 4e 55 4c 4c 2e 20 2a 2f 0a 20 20  y be NULL. */.  
1360: 20 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43    sqlite3GlobalC
1370: 6f 6e 66 69 67 2e 70 63 61 63 68 65 32 2e 78 53  onfig.pcache2.xS
1380: 68 75 74 64 6f 77 6e 28 73 71 6c 69 74 65 33 47  hutdown(sqlite3G
1390: 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63  lobalConfig.pcac
13a0: 68 65 32 2e 70 41 72 67 29 3b 0a 20 20 7d 0a 7d  he2.pArg);.  }.}
13b0: 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74  ../*.** Return t
13c0: 68 65 20 73 69 7a 65 20 69 6e 20 62 79 74 65 73  he size in bytes
13d0: 20 6f 66 20 61 20 50 43 61 63 68 65 20 6f 62 6a   of a PCache obj
13e0: 65 63 74 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  ect..*/.int sqli
13f0: 74 65 33 50 63 61 63 68 65 53 69 7a 65 28 76 6f  te3PcacheSize(vo
1400: 69 64 29 7b 20 72 65 74 75 72 6e 20 73 69 7a 65  id){ return size
1410: 6f 66 28 50 43 61 63 68 65 29 3b 20 7d 0a 0a 2f  of(PCache); }../
1420: 2a 0a 2a 2a 20 43 72 65 61 74 65 20 61 20 6e 65  *.** Create a ne
1430: 77 20 50 43 61 63 68 65 20 6f 62 6a 65 63 74 2e  w PCache object.
1440: 20 53 74 6f 72 61 67 65 20 73 70 61 63 65 20 74   Storage space t
1450: 6f 20 68 6f 6c 64 20 74 68 65 20 6f 62 6a 65 63  o hold the objec
1460: 74 0a 2a 2a 20 68 61 73 20 61 6c 72 65 61 64 79  t.** has already
1470: 20 62 65 65 6e 20 61 6c 6c 6f 63 61 74 65 64 20   been allocated 
1480: 61 6e 64 20 69 73 20 70 61 73 73 65 64 20 69 6e  and is passed in
1490: 20 61 73 20 74 68 65 20 70 20 70 6f 69 6e 74 65   as the p pointe
14a0: 72 2e 20 0a 2a 2a 20 54 68 65 20 63 61 6c 6c 65  r. .** The calle
14b0: 72 20 64 69 73 63 6f 76 65 72 73 20 68 6f 77 20  r discovers how 
14c0: 6d 75 63 68 20 73 70 61 63 65 20 6e 65 65 64 73  much space needs
14d0: 20 74 6f 20 62 65 20 61 6c 6c 6f 63 61 74 65 64   to be allocated
14e0: 20 62 79 20 0a 2a 2a 20 63 61 6c 6c 69 6e 67 20   by .** calling 
14f0: 73 71 6c 69 74 65 33 50 63 61 63 68 65 53 69 7a  sqlite3PcacheSiz
1500: 65 28 29 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  e()..*/.int sqli
1510: 74 65 33 50 63 61 63 68 65 4f 70 65 6e 28 0a 20  te3PcacheOpen(. 
1520: 20 69 6e 74 20 73 7a 50 61 67 65 2c 20 20 20 20   int szPage,    
1530: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1540: 20 53 69 7a 65 20 6f 66 20 65 76 65 72 79 20 70   Size of every p
1550: 61 67 65 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 45  age */.  int szE
1560: 78 74 72 61 2c 20 20 20 20 20 20 20 20 20 20 20  xtra,           
1570: 20 20 20 20 20 20 2f 2a 20 45 78 74 72 61 20 73        /* Extra s
1580: 70 61 63 65 20 61 73 73 6f 63 69 61 74 65 64 20  pace associated 
1590: 77 69 74 68 20 65 61 63 68 20 70 61 67 65 20 2a  with each page *
15a0: 2f 0a 20 20 69 6e 74 20 62 50 75 72 67 65 61 62  /.  int bPurgeab
15b0: 6c 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  le,             
15c0: 20 2f 2a 20 54 72 75 65 20 69 66 20 70 61 67 65   /* True if page
15d0: 73 20 61 72 65 20 6f 6e 20 62 61 63 6b 69 6e 67  s are on backing
15e0: 20 73 74 6f 72 65 20 2a 2f 0a 20 20 69 6e 74 20   store */.  int 
15f0: 28 2a 78 53 74 72 65 73 73 29 28 76 6f 69 64 2a  (*xStress)(void*
1600: 2c 50 67 48 64 72 2a 29 2c 2f 2a 20 43 61 6c 6c  ,PgHdr*),/* Call
1610: 20 74 6f 20 74 72 79 20 74 6f 20 6d 61 6b 65 20   to try to make 
1620: 70 61 67 65 73 20 63 6c 65 61 6e 20 2a 2f 0a 20  pages clean */. 
1630: 20 76 6f 69 64 20 2a 70 53 74 72 65 73 73 2c 20   void *pStress, 
1640: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1650: 20 41 72 67 75 6d 65 6e 74 20 74 6f 20 78 53 74   Argument to xSt
1660: 72 65 73 73 20 2a 2f 0a 20 20 50 43 61 63 68 65  ress */.  PCache
1670: 20 2a 70 20 20 20 20 20 20 20 20 20 20 20 20 20   *p             
1680: 20 20 20 20 20 20 20 2f 2a 20 50 72 65 61 6c 6c         /* Preall
1690: 6f 63 61 74 65 64 20 73 70 61 63 65 20 66 6f 72  ocated space for
16a0: 20 74 68 65 20 50 43 61 63 68 65 20 2a 2f 0a 29   the PCache */.)
16b0: 7b 0a 20 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c  {.  memset(p, 0,
16c0: 20 73 69 7a 65 6f 66 28 50 43 61 63 68 65 29 29   sizeof(PCache))
16d0: 3b 0a 20 20 70 2d 3e 73 7a 50 61 67 65 20 3d 20  ;.  p->szPage = 
16e0: 31 3b 0a 20 20 70 2d 3e 73 7a 45 78 74 72 61 20  1;.  p->szExtra 
16f0: 3d 20 73 7a 45 78 74 72 61 3b 0a 20 20 70 2d 3e  = szExtra;.  p->
1700: 62 50 75 72 67 65 61 62 6c 65 20 3d 20 62 50 75  bPurgeable = bPu
1710: 72 67 65 61 62 6c 65 3b 0a 20 20 70 2d 3e 65 43  rgeable;.  p->eC
1720: 72 65 61 74 65 20 3d 20 32 3b 0a 20 20 70 2d 3e  reate = 2;.  p->
1730: 78 53 74 72 65 73 73 20 3d 20 78 53 74 72 65 73  xStress = xStres
1740: 73 3b 0a 20 20 70 2d 3e 70 53 74 72 65 73 73 20  s;.  p->pStress 
1750: 3d 20 70 53 74 72 65 73 73 3b 0a 20 20 70 2d 3e  = pStress;.  p->
1760: 73 7a 43 61 63 68 65 20 3d 20 31 30 30 3b 0a 20  szCache = 100;. 
1770: 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 50   return sqlite3P
1780: 63 61 63 68 65 53 65 74 50 61 67 65 53 69 7a 65  cacheSetPageSize
1790: 28 70 2c 20 73 7a 50 61 67 65 29 3b 0a 7d 0a 0a  (p, szPage);.}..
17a0: 2f 2a 0a 2a 2a 20 43 68 61 6e 67 65 20 74 68 65  /*.** Change the
17b0: 20 70 61 67 65 20 73 69 7a 65 20 66 6f 72 20 50   page size for P
17c0: 43 61 63 68 65 20 6f 62 6a 65 63 74 2e 20 54 68  Cache object. Th
17d0: 65 20 63 61 6c 6c 65 72 20 6d 75 73 74 20 65 6e  e caller must en
17e0: 73 75 72 65 20 74 68 61 74 20 74 68 65 72 65 0a  sure that there.
17f0: 2a 2a 20 61 72 65 20 6e 6f 20 6f 75 74 73 74 61  ** are no outsta
1800: 6e 64 69 6e 67 20 70 61 67 65 20 72 65 66 65 72  nding page refer
1810: 65 6e 63 65 73 20 77 68 65 6e 20 74 68 69 73 20  ences when this 
1820: 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c  function is call
1830: 65 64 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  ed..*/.int sqlit
1840: 65 33 50 63 61 63 68 65 53 65 74 50 61 67 65 53  e3PcacheSetPageS
1850: 69 7a 65 28 50 43 61 63 68 65 20 2a 70 43 61 63  ize(PCache *pCac
1860: 68 65 2c 20 69 6e 74 20 73 7a 50 61 67 65 29 7b  he, int szPage){
1870: 0a 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68  .  assert( pCach
1880: 65 2d 3e 6e 52 65 66 3d 3d 30 20 26 26 20 70 43  e->nRef==0 && pC
1890: 61 63 68 65 2d 3e 70 44 69 72 74 79 3d 3d 30 20  ache->pDirty==0 
18a0: 29 3b 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d  );.  if( pCache-
18b0: 3e 73 7a 50 61 67 65 20 29 7b 0a 20 20 20 20 73  >szPage ){.    s
18c0: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70  qlite3_pcache *p
18d0: 4e 65 77 3b 0a 20 20 20 20 70 4e 65 77 20 3d 20  New;.    pNew = 
18e0: 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e  sqlite3GlobalCon
18f0: 66 69 67 2e 70 63 61 63 68 65 32 2e 78 43 72 65  fig.pcache2.xCre
1900: 61 74 65 28 0a 20 20 20 20 20 20 20 20 20 20 20  ate(.           
1910: 20 20 20 20 20 73 7a 50 61 67 65 2c 20 70 43 61       szPage, pCa
1920: 63 68 65 2d 3e 73 7a 45 78 74 72 61 20 2b 20 52  che->szExtra + R
1930: 4f 55 4e 44 38 28 73 69 7a 65 6f 66 28 50 67 48  OUND8(sizeof(PgH
1940: 64 72 29 29 2c 0a 20 20 20 20 20 20 20 20 20 20  dr)),.          
1950: 20 20 20 20 20 20 70 43 61 63 68 65 2d 3e 62 50        pCache->bP
1960: 75 72 67 65 61 62 6c 65 0a 20 20 20 20 29 3b 0a  urgeable.    );.
1970: 20 20 20 20 69 66 28 20 70 4e 65 77 3d 3d 30 20      if( pNew==0 
1980: 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  ) return SQLITE_
1990: 4e 4f 4d 45 4d 3b 0a 20 20 20 20 73 71 6c 69 74  NOMEM;.    sqlit
19a0: 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70  e3GlobalConfig.p
19b0: 63 61 63 68 65 32 2e 78 43 61 63 68 65 73 69 7a  cache2.xCachesiz
19c0: 65 28 70 4e 65 77 2c 20 6e 75 6d 62 65 72 4f 66  e(pNew, numberOf
19d0: 43 61 63 68 65 50 61 67 65 73 28 70 43 61 63 68  CachePages(pCach
19e0: 65 29 29 3b 0a 20 20 20 20 69 66 28 20 70 43 61  e));.    if( pCa
19f0: 63 68 65 2d 3e 70 43 61 63 68 65 20 29 7b 0a 20  che->pCache ){. 
1a00: 20 20 20 20 20 73 71 6c 69 74 65 33 47 6c 6f 62       sqlite3Glob
1a10: 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65 32  alConfig.pcache2
1a20: 2e 78 44 65 73 74 72 6f 79 28 70 43 61 63 68 65  .xDestroy(pCache
1a30: 2d 3e 70 43 61 63 68 65 29 3b 0a 20 20 20 20 7d  ->pCache);.    }
1a40: 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 70 43 61  .    pCache->pCa
1a50: 63 68 65 20 3d 20 70 4e 65 77 3b 0a 20 20 20 20  che = pNew;.    
1a60: 70 43 61 63 68 65 2d 3e 70 50 61 67 65 31 20 3d  pCache->pPage1 =
1a70: 20 30 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e   0;.    pCache->
1a80: 73 7a 50 61 67 65 20 3d 20 73 7a 50 61 67 65 3b  szPage = szPage;
1a90: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 53 51  .  }.  return SQ
1aa0: 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a  LITE_OK;.}../*.*
1ab0: 2a 20 54 72 79 20 74 6f 20 6f 62 74 61 69 6e 20  * Try to obtain 
1ac0: 61 20 70 61 67 65 20 66 72 6f 6d 20 74 68 65 20  a page from the 
1ad0: 63 61 63 68 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 69  cache..**.** Thi
1ae0: 73 20 72 6f 75 74 69 6e 65 20 72 65 74 75 72 6e  s routine return
1af0: 73 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 61  s a pointer to a
1b00: 6e 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  n sqlite3_pcache
1b10: 5f 70 61 67 65 20 6f 62 6a 65 63 74 20 69 66 0a  _page object if.
1b20: 2a 2a 20 73 75 63 68 20 61 6e 20 6f 62 6a 65 63  ** such an objec
1b30: 74 20 69 73 20 61 6c 72 65 61 64 79 20 69 6e 20  t is already in 
1b40: 63 61 63 68 65 2c 20 6f 72 20 69 66 20 61 20 6e  cache, or if a n
1b50: 65 77 20 6f 6e 65 20 69 73 20 63 72 65 61 74 65  ew one is create
1b60: 64 2e 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69  d..** This routi
1b70: 6e 65 20 72 65 74 75 72 6e 73 20 61 20 4e 55 4c  ne returns a NUL
1b80: 4c 20 70 6f 69 6e 74 65 72 20 69 66 20 74 68 65  L pointer if the
1b90: 20 6f 62 6a 65 63 74 20 77 61 73 20 6e 6f 74 20   object was not 
1ba0: 69 6e 20 63 61 63 68 65 0a 2a 2a 20 61 6e 64 20  in cache.** and 
1bb0: 63 6f 75 6c 64 20 6e 6f 74 20 62 65 20 63 72 65  could not be cre
1bc0: 61 74 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  ated..**.** The 
1bd0: 63 72 65 61 74 65 46 6c 61 67 73 20 73 68 6f 75  createFlags shou
1be0: 6c 64 20 62 65 20 30 20 74 6f 20 63 68 65 63 6b  ld be 0 to check
1bf0: 20 66 6f 72 20 65 78 69 73 74 69 6e 67 20 70 61   for existing pa
1c00: 67 65 73 20 61 6e 64 20 73 68 6f 75 6c 64 0a 2a  ges and should.*
1c10: 2a 20 62 65 20 33 20 28 6e 6f 74 20 31 2c 20 62  * be 3 (not 1, b
1c20: 75 74 20 33 29 20 74 6f 20 74 72 79 20 74 6f 20  ut 3) to try to 
1c30: 63 72 65 61 74 65 20 61 20 6e 65 77 20 70 61 67  create a new pag
1c40: 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20  e..**.** If the 
1c50: 63 72 65 61 74 65 46 6c 61 67 20 69 73 20 30 2c  createFlag is 0,
1c60: 20 74 68 65 6e 20 4e 55 4c 4c 20 69 73 20 61 6c   then NULL is al
1c70: 77 61 79 73 20 72 65 74 75 72 6e 65 64 20 69 66  ways returned if
1c80: 20 74 68 65 20 70 61 67 65 0a 2a 2a 20 69 73 20   the page.** is 
1c90: 6e 6f 74 20 61 6c 72 65 61 64 79 20 69 6e 20 74  not already in t
1ca0: 68 65 20 63 61 63 68 65 2e 20 20 49 66 20 63 72  he cache.  If cr
1cb0: 65 61 74 65 46 6c 61 67 20 69 73 20 31 2c 20 74  eateFlag is 1, t
1cc0: 68 65 6e 20 61 20 6e 65 77 20 70 61 67 65 0a 2a  hen a new page.*
1cd0: 2a 20 69 73 20 63 72 65 61 74 65 64 20 6f 6e 6c  * is created onl
1ce0: 79 20 69 66 20 74 68 61 74 20 63 61 6e 20 62 65  y if that can be
1cf0: 20 64 6f 6e 65 20 77 69 74 68 6f 75 74 20 73 70   done without sp
1d00: 69 6c 6c 69 6e 67 20 64 69 72 74 79 20 70 61 67  illing dirty pag
1d10: 65 73 0a 2a 2a 20 61 6e 64 20 77 69 74 68 6f 75  es.** and withou
1d20: 74 20 65 78 63 65 65 64 69 6e 67 20 74 68 65 20  t exceeding the 
1d30: 63 61 63 68 65 20 73 69 7a 65 20 6c 69 6d 69 74  cache size limit
1d40: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 61 6c 6c  ..**.** The call
1d50: 65 72 20 6e 65 65 64 73 20 74 6f 20 69 6e 76 6f  er needs to invo
1d60: 6b 65 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  ke sqlite3Pcache
1d70: 46 65 74 63 68 46 69 6e 69 73 68 28 29 20 74 6f  FetchFinish() to
1d80: 20 70 72 6f 70 65 72 6c 79 0a 2a 2a 20 69 6e 69   properly.** ini
1d90: 74 69 61 6c 69 7a 65 20 74 68 65 20 73 71 6c 69  tialize the sqli
1da0: 74 65 33 5f 70 63 61 63 68 65 5f 70 61 67 65 20  te3_pcache_page 
1db0: 6f 62 6a 65 63 74 20 61 6e 64 20 63 6f 6e 76 65  object and conve
1dc0: 72 74 20 69 74 20 69 6e 74 6f 20 61 0a 2a 2a 20  rt it into a.** 
1dd0: 50 67 48 64 72 20 6f 62 6a 65 63 74 2e 20 20 54  PgHdr object.  T
1de0: 68 65 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  he sqlite3Pcache
1df0: 46 65 74 63 68 28 29 20 61 6e 64 20 73 71 6c 69  Fetch() and sqli
1e00: 74 65 33 50 63 61 63 68 65 46 65 74 63 68 46 69  te3PcacheFetchFi
1e10: 6e 69 73 68 28 29 0a 2a 2a 20 72 6f 75 74 69 6e  nish().** routin
1e20: 65 73 20 61 72 65 20 73 70 6c 69 74 20 74 68 69  es are split thi
1e30: 73 20 77 61 79 20 66 6f 72 20 70 65 72 66 6f 72  s way for perfor
1e40: 6d 61 6e 63 65 20 72 65 61 73 6f 6e 73 2e 20 57  mance reasons. W
1e50: 68 65 6e 20 73 65 70 61 72 61 74 65 64 0a 2a 2a  hen separated.**
1e60: 20 74 68 65 79 20 63 61 6e 20 62 6f 74 68 20 28   they can both (
1e70: 75 73 75 61 6c 6c 79 29 20 6f 70 65 72 61 74 65  usually) operate
1e80: 20 77 69 74 68 6f 75 74 20 68 61 76 69 6e 67 20   without having 
1e90: 74 6f 20 70 75 73 68 20 76 61 6c 75 65 73 20 74  to push values t
1ea0: 6f 0a 2a 2a 20 74 68 65 20 73 74 61 63 6b 20 6f  o.** the stack o
1eb0: 6e 20 65 6e 74 72 79 20 61 6e 64 20 70 6f 70 20  n entry and pop 
1ec0: 74 68 65 6d 20 62 61 63 6b 20 6f 66 66 20 6f 6e  them back off on
1ed0: 20 65 78 69 74 2c 20 77 68 69 63 68 20 73 61 76   exit, which sav
1ee0: 65 73 20 61 0a 2a 2a 20 6c 6f 74 20 6f 66 20 70  es a.** lot of p
1ef0: 75 73 68 69 6e 67 20 61 6e 64 20 70 6f 70 70 69  ushing and poppi
1f00: 6e 67 2e 0a 2a 2f 0a 73 71 6c 69 74 65 33 5f 70  ng..*/.sqlite3_p
1f10: 63 61 63 68 65 5f 70 61 67 65 20 2a 73 71 6c 69  cache_page *sqli
1f20: 74 65 33 50 63 61 63 68 65 46 65 74 63 68 28 0a  te3PcacheFetch(.
1f30: 20 20 50 43 61 63 68 65 20 2a 70 43 61 63 68 65    PCache *pCache
1f40: 2c 20 20 20 20 20 20 20 2f 2a 20 4f 62 74 61 69  ,       /* Obtai
1f50: 6e 20 74 68 65 20 70 61 67 65 20 66 72 6f 6d 20  n the page from 
1f60: 74 68 69 73 20 63 61 63 68 65 20 2a 2f 0a 20 20  this cache */.  
1f70: 50 67 6e 6f 20 70 67 6e 6f 2c 20 20 20 20 20 20  Pgno pgno,      
1f80: 20 20 20 20 20 20 2f 2a 20 50 61 67 65 20 6e 75        /* Page nu
1f90: 6d 62 65 72 20 74 6f 20 6f 62 74 61 69 6e 20 2a  mber to obtain *
1fa0: 2f 0a 20 20 69 6e 74 20 63 72 65 61 74 65 46 6c  /.  int createFl
1fb0: 61 67 20 20 20 20 20 20 20 20 2f 2a 20 49 66 20  ag        /* If 
1fc0: 74 72 75 65 2c 20 63 72 65 61 74 65 20 70 61 67  true, create pag
1fd0: 65 20 69 66 20 69 74 20 64 6f 65 73 20 6e 6f 74  e if it does not
1fe0: 20 65 78 69 73 74 20 61 6c 72 65 61 64 79 20 2a   exist already *
1ff0: 2f 0a 29 7b 0a 20 20 69 6e 74 20 65 43 72 65 61  /.){.  int eCrea
2000: 74 65 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70  te;..  assert( p
2010: 43 61 63 68 65 21 3d 30 20 29 3b 0a 20 20 61 73  Cache!=0 );.  as
2020: 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e 70 43  sert( pCache->pC
2030: 61 63 68 65 21 3d 30 20 29 3b 0a 20 20 61 73 73  ache!=0 );.  ass
2040: 65 72 74 28 20 63 72 65 61 74 65 46 6c 61 67 3d  ert( createFlag=
2050: 3d 33 20 7c 7c 20 63 72 65 61 74 65 46 6c 61 67  =3 || createFlag
2060: 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28  ==0 );.  assert(
2070: 20 70 67 6e 6f 3e 30 20 29 3b 0a 0a 20 20 2f 2a   pgno>0 );..  /*
2080: 20 65 43 72 65 61 74 65 20 64 65 66 69 6e 65 73   eCreate defines
2090: 20 77 68 61 74 20 74 6f 20 64 6f 20 69 66 20 74   what to do if t
20a0: 68 65 20 70 61 67 65 20 64 6f 65 73 20 6e 6f 74  he page does not
20b0: 20 65 78 69 73 74 2e 0a 20 20 2a 2a 20 20 20 20   exist..  **    
20c0: 30 20 20 20 20 20 44 6f 20 6e 6f 74 20 61 6c 6c  0     Do not all
20d0: 6f 63 61 74 65 20 61 20 6e 65 77 20 70 61 67 65  ocate a new page
20e0: 2e 20 20 28 63 72 65 61 74 65 46 6c 61 67 3d 3d  .  (createFlag==
20f0: 30 29 0a 20 20 2a 2a 20 20 20 20 31 20 20 20 20  0).  **    1    
2100: 20 41 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20   Allocate a new 
2110: 70 61 67 65 20 69 66 20 64 6f 69 6e 67 20 73 6f  page if doing so
2120: 20 69 73 20 69 6e 65 78 70 65 6e 73 69 76 65 2e   is inexpensive.
2130: 0a 20 20 2a 2a 20 20 20 20 20 20 20 20 20 20 28  .  **          (
2140: 63 72 65 61 74 65 46 6c 61 67 3d 3d 31 20 41 4e  createFlag==1 AN
2150: 44 20 62 50 75 72 67 65 61 62 6c 65 20 41 4e 44  D bPurgeable AND
2160: 20 70 44 69 72 74 79 29 0a 20 20 2a 2a 20 20 20   pDirty).  **   
2170: 20 32 20 20 20 20 20 41 6c 6c 6f 63 61 74 65 20   2     Allocate 
2180: 61 20 6e 65 77 20 70 61 67 65 20 65 76 65 6e 20  a new page even 
2190: 69 74 20 64 6f 69 6e 67 20 73 6f 20 69 73 20 64  it doing so is d
21a0: 69 66 66 69 63 75 6c 74 2e 0a 20 20 2a 2a 20 20  ifficult..  **  
21b0: 20 20 20 20 20 20 20 20 28 63 72 65 61 74 65 46          (createF
21c0: 6c 61 67 3d 3d 31 20 41 4e 44 20 21 28 62 50 75  lag==1 AND !(bPu
21d0: 72 67 65 61 62 6c 65 20 41 4e 44 20 70 44 69 72  rgeable AND pDir
21e0: 74 79 29 0a 20 20 2a 2f 0a 20 20 65 43 72 65 61  ty).  */.  eCrea
21f0: 74 65 20 3d 20 63 72 65 61 74 65 46 6c 61 67 20  te = createFlag 
2200: 26 20 70 43 61 63 68 65 2d 3e 65 43 72 65 61 74  & pCache->eCreat
2210: 65 3b 0a 20 20 61 73 73 65 72 74 28 20 65 43 72  e;.  assert( eCr
2220: 65 61 74 65 3d 3d 30 20 7c 7c 20 65 43 72 65 61  eate==0 || eCrea
2230: 74 65 3d 3d 31 20 7c 7c 20 65 43 72 65 61 74 65  te==1 || eCreate
2240: 3d 3d 32 20 29 3b 0a 20 20 61 73 73 65 72 74 28  ==2 );.  assert(
2250: 20 63 72 65 61 74 65 46 6c 61 67 3d 3d 30 20 7c   createFlag==0 |
2260: 7c 20 70 43 61 63 68 65 2d 3e 65 43 72 65 61 74  | pCache->eCreat
2270: 65 3d 3d 65 43 72 65 61 74 65 20 29 3b 0a 20 20  e==eCreate );.  
2280: 61 73 73 65 72 74 28 20 63 72 65 61 74 65 46 6c  assert( createFl
2290: 61 67 3d 3d 30 20 7c 7c 20 65 43 72 65 61 74 65  ag==0 || eCreate
22a0: 3d 3d 31 2b 28 21 70 43 61 63 68 65 2d 3e 62 50  ==1+(!pCache->bP
22b0: 75 72 67 65 61 62 6c 65 7c 7c 21 70 43 61 63 68  urgeable||!pCach
22c0: 65 2d 3e 70 44 69 72 74 79 29 20 29 3b 0a 20 20  e->pDirty) );.  
22d0: 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 47 6c  return sqlite3Gl
22e0: 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68  obalConfig.pcach
22f0: 65 32 2e 78 46 65 74 63 68 28 70 43 61 63 68 65  e2.xFetch(pCache
2300: 2d 3e 70 43 61 63 68 65 2c 20 70 67 6e 6f 2c 20  ->pCache, pgno, 
2310: 65 43 72 65 61 74 65 29 3b 0a 7d 0a 0a 2f 2a 0a  eCreate);.}../*.
2320: 2a 2a 20 49 66 20 74 68 65 20 73 71 6c 69 74 65  ** If the sqlite
2330: 33 50 63 61 63 68 65 46 65 74 63 68 28 29 20 72  3PcacheFetch() r
2340: 6f 75 74 69 6e 65 20 69 73 20 75 6e 61 62 6c 65  outine is unable
2350: 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e   to allocate a n
2360: 65 77 0a 2a 2a 20 70 61 67 65 20 62 65 63 61 75  ew.** page becau
2370: 73 65 20 6e 65 77 20 63 6c 65 61 6e 20 70 61 67  se new clean pag
2380: 65 73 20 61 72 65 20 61 76 61 69 6c 61 62 6c 65  es are available
2390: 20 66 6f 72 20 72 65 75 73 65 20 61 6e 64 20 74   for reuse and t
23a0: 68 65 20 63 61 63 68 65 0a 2a 2a 20 73 69 7a 65  he cache.** size
23b0: 20 6c 69 6d 69 74 20 68 61 73 20 62 65 65 6e 20   limit has been 
23c0: 72 65 61 63 68 65 64 2c 20 74 68 65 6e 20 74 68  reached, then th
23d0: 69 73 20 72 6f 75 74 69 6e 65 20 63 61 6e 20 62  is routine can b
23e0: 65 20 69 6e 76 6f 6b 65 64 20 74 6f 20 0a 2a 2a  e invoked to .**
23f0: 20 74 72 79 20 68 61 72 64 65 72 20 74 6f 20 61   try harder to a
2400: 6c 6c 6f 63 61 74 65 20 61 20 70 61 67 65 2e 20  llocate a page. 
2410: 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 6d 69   This routine mi
2420: 67 68 74 20 69 6e 76 6f 6b 65 20 74 68 65 20 73  ght invoke the s
2430: 74 72 65 73 73 0a 2a 2a 20 63 61 6c 6c 62 61 63  tress.** callbac
2440: 6b 20 74 6f 20 73 70 69 6c 6c 20 64 69 72 74 79  k to spill dirty
2450: 20 70 61 67 65 73 20 74 6f 20 74 68 65 20 6a 6f   pages to the jo
2460: 75 72 6e 61 6c 2e 20 20 49 74 20 77 69 6c 6c 20  urnal.  It will 
2470: 74 68 65 6e 20 74 72 79 20 74 6f 0a 2a 2a 20 61  then try to.** a
2480: 6c 6c 6f 63 61 74 65 20 74 68 65 20 6e 65 77 20  llocate the new 
2490: 70 61 67 65 20 61 6e 64 20 77 69 6c 6c 20 6f 6e  page and will on
24a0: 6c 79 20 66 61 69 6c 20 74 6f 20 61 6c 6c 6f 63  ly fail to alloc
24b0: 61 74 65 20 61 20 6e 65 77 20 70 61 67 65 20 6f  ate a new page o
24c0: 6e 0a 2a 2a 20 61 6e 20 4f 4f 4d 20 65 72 72 6f  n.** an OOM erro
24d0: 72 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 72 6f  r..**.** This ro
24e0: 75 74 69 6e 65 20 73 68 6f 75 6c 64 20 62 65 20  utine should be 
24f0: 69 6e 76 6f 6b 65 64 20 6f 6e 6c 79 20 61 66 74  invoked only aft
2500: 65 72 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  er sqlite3Pcache
2510: 46 65 74 63 68 28 29 20 66 61 69 6c 73 2e 0a 2a  Fetch() fails..*
2520: 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 50 63 61  /.int sqlite3Pca
2530: 63 68 65 46 65 74 63 68 53 74 72 65 73 73 28 0a  cheFetchStress(.
2540: 20 20 50 43 61 63 68 65 20 2a 70 43 61 63 68 65    PCache *pCache
2550: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
2560: 20 20 2f 2a 20 4f 62 74 61 69 6e 20 74 68 65 20    /* Obtain the 
2570: 70 61 67 65 20 66 72 6f 6d 20 74 68 69 73 20 63  page from this c
2580: 61 63 68 65 20 2a 2f 0a 20 20 50 67 6e 6f 20 70  ache */.  Pgno p
2590: 67 6e 6f 2c 20 20 20 20 20 20 20 20 20 20 20 20  gno,            
25a0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67            /* Pag
25b0: 65 20 6e 75 6d 62 65 72 20 74 6f 20 6f 62 74 61  e number to obta
25c0: 69 6e 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f  in */.  sqlite3_
25d0: 70 63 61 63 68 65 5f 70 61 67 65 20 2a 2a 70 70  pcache_page **pp
25e0: 50 61 67 65 20 20 20 20 2f 2a 20 57 72 69 74 65  Page    /* Write
25f0: 20 72 65 73 75 6c 74 20 68 65 72 65 20 2a 2f 0a   result here */.
2600: 29 7b 0a 20 20 50 67 48 64 72 20 2a 70 50 67 3b  ){.  PgHdr *pPg;
2610: 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 65  .  if( pCache->e
2620: 43 72 65 61 74 65 3d 3d 32 20 29 20 72 65 74 75  Create==2 ) retu
2630: 72 6e 20 30 3b 0a 0a 0a 20 20 2f 2a 20 46 69 6e  rn 0;...  /* Fin
2640: 64 20 61 20 64 69 72 74 79 20 70 61 67 65 20 74  d a dirty page t
2650: 6f 20 77 72 69 74 65 2d 6f 75 74 20 61 6e 64 20  o write-out and 
2660: 72 65 63 79 63 6c 65 2e 20 46 69 72 73 74 20 74  recycle. First t
2670: 72 79 20 74 6f 20 66 69 6e 64 20 61 20 0a 20 20  ry to find a .  
2680: 2a 2a 20 70 61 67 65 20 74 68 61 74 20 64 6f 65  ** page that doe
2690: 73 20 6e 6f 74 20 72 65 71 75 69 72 65 20 61 20  s not require a 
26a0: 6a 6f 75 72 6e 61 6c 2d 73 79 6e 63 20 28 6f 6e  journal-sync (on
26b0: 65 20 77 69 74 68 20 50 47 48 44 52 5f 4e 45 45  e with PGHDR_NEE
26c0: 44 5f 53 59 4e 43 0a 20 20 2a 2a 20 63 6c 65 61  D_SYNC.  ** clea
26d0: 72 65 64 29 2c 20 62 75 74 20 69 66 20 74 68 61  red), but if tha
26e0: 74 20 69 73 20 6e 6f 74 20 70 6f 73 73 69 62 6c  t is not possibl
26f0: 65 20 73 65 74 74 6c 65 20 66 6f 72 20 61 6e 79  e settle for any
2700: 20 6f 74 68 65 72 20 0a 20 20 2a 2a 20 75 6e 72   other .  ** unr
2710: 65 66 65 72 65 6e 63 65 64 20 64 69 72 74 79 20  eferenced dirty 
2720: 70 61 67 65 2e 0a 20 20 2a 2f 0a 20 20 66 6f 72  page..  */.  for
2730: 28 70 50 67 3d 70 43 61 63 68 65 2d 3e 70 53 79  (pPg=pCache->pSy
2740: 6e 63 65 64 3b 20 0a 20 20 20 20 20 20 70 50 67  nced; .      pPg
2750: 20 26 26 20 28 70 50 67 2d 3e 6e 52 65 66 20 7c   && (pPg->nRef |
2760: 7c 20 28 70 50 67 2d 3e 66 6c 61 67 73 26 50 47  | (pPg->flags&PG
2770: 48 44 52 5f 4e 45 45 44 5f 53 59 4e 43 29 29 3b  HDR_NEED_SYNC));
2780: 20 0a 20 20 20 20 20 20 70 50 67 3d 70 50 67 2d   .      pPg=pPg-
2790: 3e 70 44 69 72 74 79 50 72 65 76 0a 20 20 29 3b  >pDirtyPrev.  );
27a0: 0a 20 20 70 43 61 63 68 65 2d 3e 70 53 79 6e 63  .  pCache->pSync
27b0: 65 64 20 3d 20 70 50 67 3b 0a 20 20 69 66 28 20  ed = pPg;.  if( 
27c0: 21 70 50 67 20 29 7b 0a 20 20 20 20 66 6f 72 28  !pPg ){.    for(
27d0: 70 50 67 3d 70 43 61 63 68 65 2d 3e 70 44 69 72  pPg=pCache->pDir
27e0: 74 79 54 61 69 6c 3b 20 70 50 67 20 26 26 20 70  tyTail; pPg && p
27f0: 50 67 2d 3e 6e 52 65 66 3b 20 70 50 67 3d 70 50  Pg->nRef; pPg=pP
2800: 67 2d 3e 70 44 69 72 74 79 50 72 65 76 29 3b 0a  g->pDirtyPrev);.
2810: 20 20 7d 0a 20 20 69 66 28 20 70 50 67 20 29 7b    }.  if( pPg ){
2820: 0a 20 20 20 20 69 6e 74 20 72 63 3b 0a 23 69 66  .    int rc;.#if
2830: 64 65 66 20 53 51 4c 49 54 45 5f 4c 4f 47 5f 43  def SQLITE_LOG_C
2840: 41 43 48 45 5f 53 50 49 4c 4c 0a 20 20 20 20 73  ACHE_SPILL.    s
2850: 71 6c 69 74 65 33 5f 6c 6f 67 28 53 51 4c 49 54  qlite3_log(SQLIT
2860: 45 5f 46 55 4c 4c 2c 20 0a 20 20 20 20 20 20 20  E_FULL, .       
2870: 20 20 20 20 20 20 20 20 20 22 73 70 69 6c 6c 20           "spill 
2880: 70 61 67 65 20 25 64 20 6d 61 6b 69 6e 67 20 72  page %d making r
2890: 6f 6f 6d 20 66 6f 72 20 25 64 20 2d 20 63 61 63  oom for %d - cac
28a0: 68 65 20 75 73 65 64 3a 20 25 64 2f 25 64 22 2c  he used: %d/%d",
28b0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
28c0: 20 70 50 67 2d 3e 70 67 6e 6f 2c 20 70 67 6e 6f   pPg->pgno, pgno
28d0: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
28e0: 20 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43    sqlite3GlobalC
28f0: 6f 6e 66 69 67 2e 70 63 61 63 68 65 2e 78 50 61  onfig.pcache.xPa
2900: 67 65 63 6f 75 6e 74 28 70 43 61 63 68 65 2d 3e  gecount(pCache->
2910: 70 43 61 63 68 65 29 2c 0a 20 20 20 20 20 20 20  pCache),.       
2920: 20 20 20 20 20 20 20 20 20 6e 75 6d 62 65 72 4f           numberO
2930: 66 43 61 63 68 65 50 61 67 65 73 28 70 43 61 63  fCachePages(pCac
2940: 68 65 29 29 3b 0a 23 65 6e 64 69 66 0a 20 20 20  he));.#endif.   
2950: 20 72 63 20 3d 20 70 43 61 63 68 65 2d 3e 78 53   rc = pCache->xS
2960: 74 72 65 73 73 28 70 43 61 63 68 65 2d 3e 70 53  tress(pCache->pS
2970: 74 72 65 73 73 2c 20 70 50 67 29 3b 0a 20 20 20  tress, pPg);.   
2980: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
2990: 4f 4b 20 26 26 20 72 63 21 3d 53 51 4c 49 54 45  OK && rc!=SQLITE
29a0: 5f 42 55 53 59 20 29 7b 0a 20 20 20 20 20 20 72  _BUSY ){.      r
29b0: 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a  eturn rc;.    }.
29c0: 20 20 7d 0a 20 20 2a 70 70 50 61 67 65 20 3d 20    }.  *ppPage = 
29d0: 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e  sqlite3GlobalCon
29e0: 66 69 67 2e 70 63 61 63 68 65 32 2e 78 46 65 74  fig.pcache2.xFet
29f0: 63 68 28 70 43 61 63 68 65 2d 3e 70 43 61 63 68  ch(pCache->pCach
2a00: 65 2c 20 70 67 6e 6f 2c 20 32 29 3b 0a 20 20 72  e, pgno, 2);.  r
2a10: 65 74 75 72 6e 20 2a 70 70 50 61 67 65 3d 3d 30  eturn *ppPage==0
2a20: 20 3f 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 20   ? SQLITE_NOMEM 
2a30: 3a 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a  : SQLITE_OK;.}..
2a40: 2f 2a 0a 2a 2a 20 54 68 69 73 20 69 73 20 61 20  /*.** This is a 
2a50: 68 65 6c 70 65 72 20 72 6f 75 74 69 6e 65 20 66  helper routine f
2a60: 6f 72 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  or sqlite3Pcache
2a70: 46 65 74 63 68 46 69 6e 69 73 68 28 29 0a 2a 2a  FetchFinish().**
2a80: 0a 2a 2a 20 49 6e 20 74 68 65 20 75 6e 63 6f 6d  .** In the uncom
2a90: 6d 6f 6e 20 63 61 73 65 20 77 68 65 72 65 20 74  mon case where t
2aa0: 68 65 20 70 61 67 65 20 62 65 69 6e 67 20 66 65  he page being fe
2ab0: 74 63 68 65 64 20 68 61 73 20 6e 6f 74 20 62 65  tched has not be
2ac0: 65 6e 0a 2a 2a 20 69 6e 69 74 69 61 6c 69 7a 65  en.** initialize
2ad0: 64 2c 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20  d, this routine 
2ae0: 69 73 20 69 6e 76 6f 6b 65 64 20 74 6f 20 64 6f  is invoked to do
2af0: 20 74 68 65 20 69 6e 69 74 69 61 6c 69 7a 61 74   the initializat
2b00: 69 6f 6e 2e 0a 2a 2a 20 54 68 69 73 20 72 6f 75  ion..** This rou
2b10: 74 69 6e 65 20 69 73 20 62 72 6f 6b 65 6e 20 6f  tine is broken o
2b20: 75 74 20 69 6e 74 6f 20 61 20 73 65 70 61 72 61  ut into a separa
2b30: 74 65 20 66 75 6e 63 74 69 6f 6e 20 73 69 6e 63  te function sinc
2b40: 65 20 69 74 0a 2a 2a 20 72 65 71 75 69 72 65 73  e it.** requires
2b50: 20 65 78 74 72 61 20 73 74 61 63 6b 20 6d 61 6e   extra stack man
2b60: 69 70 75 6c 61 74 69 6f 6e 20 74 68 61 74 20 63  ipulation that c
2b70: 61 6e 20 62 65 20 61 76 6f 69 64 65 64 20 69 6e  an be avoided in
2b80: 20 74 68 65 20 63 6f 6d 6d 6f 6e 0a 2a 2a 20 63   the common.** c
2b90: 61 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 53  ase..*/.static S
2ba0: 51 4c 49 54 45 5f 4e 4f 49 4e 4c 49 4e 45 20 50  QLITE_NOINLINE P
2bb0: 67 48 64 72 20 2a 70 63 61 63 68 65 46 65 74 63  gHdr *pcacheFetc
2bc0: 68 46 69 6e 69 73 68 57 69 74 68 49 6e 69 74 28  hFinishWithInit(
2bd0: 0a 20 20 50 43 61 63 68 65 20 2a 70 43 61 63 68  .  PCache *pCach
2be0: 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  e,             /
2bf0: 2a 20 4f 62 74 61 69 6e 20 74 68 65 20 70 61 67  * Obtain the pag
2c00: 65 20 66 72 6f 6d 20 74 68 69 73 20 63 61 63 68  e from this cach
2c10: 65 20 2a 2f 0a 20 20 50 67 6e 6f 20 70 67 6e 6f  e */.  Pgno pgno
2c20: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
2c30: 20 20 20 2f 2a 20 50 61 67 65 20 6e 75 6d 62 65     /* Page numbe
2c40: 72 20 6f 62 74 61 69 6e 65 64 20 2a 2f 0a 20 20  r obtained */.  
2c50: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 5f 70  sqlite3_pcache_p
2c60: 61 67 65 20 2a 70 50 61 67 65 20 20 2f 2a 20 50  age *pPage  /* P
2c70: 61 67 65 20 6f 62 74 61 69 6e 65 64 20 62 79 20  age obtained by 
2c80: 70 72 69 6f 72 20 50 63 61 63 68 65 46 65 74 63  prior PcacheFetc
2c90: 68 28 29 20 63 61 6c 6c 20 2a 2f 0a 29 7b 0a 20  h() call */.){. 
2ca0: 20 50 67 48 64 72 20 2a 70 50 67 48 64 72 3b 0a   PgHdr *pPgHdr;.
2cb0: 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65 21    assert( pPage!
2cc0: 3d 30 20 29 3b 0a 20 20 70 50 67 48 64 72 20 3d  =0 );.  pPgHdr =
2cd0: 20 28 50 67 48 64 72 2a 29 70 50 61 67 65 2d 3e   (PgHdr*)pPage->
2ce0: 70 45 78 74 72 61 3b 0a 20 20 61 73 73 65 72 74  pExtra;.  assert
2cf0: 28 20 70 50 67 48 64 72 2d 3e 70 50 61 67 65 3d  ( pPgHdr->pPage=
2d00: 3d 30 20 29 3b 0a 20 6d 65 6d 73 65 74 28 70 50  =0 );. memset(pP
2d10: 67 48 64 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28  gHdr, 0, sizeof(
2d20: 50 67 48 64 72 29 29 3b 0a 20 20 70 50 67 48 64  PgHdr));.  pPgHd
2d30: 72 2d 3e 70 50 61 67 65 20 3d 20 70 50 61 67 65  r->pPage = pPage
2d40: 3b 0a 20 20 70 50 67 48 64 72 2d 3e 70 44 61 74  ;.  pPgHdr->pDat
2d50: 61 20 3d 20 70 50 61 67 65 2d 3e 70 42 75 66 3b  a = pPage->pBuf;
2d60: 0a 20 20 70 50 67 48 64 72 2d 3e 70 45 78 74 72  .  pPgHdr->pExtr
2d70: 61 20 3d 20 28 76 6f 69 64 20 2a 29 26 70 50 67  a = (void *)&pPg
2d80: 48 64 72 5b 31 5d 3b 0a 20 20 6d 65 6d 73 65 74  Hdr[1];.  memset
2d90: 28 70 50 67 48 64 72 2d 3e 70 45 78 74 72 61 2c  (pPgHdr->pExtra,
2da0: 20 30 2c 20 70 43 61 63 68 65 2d 3e 73 7a 45 78   0, pCache->szEx
2db0: 74 72 61 29 3b 0a 20 20 70 50 67 48 64 72 2d 3e  tra);.  pPgHdr->
2dc0: 70 43 61 63 68 65 20 3d 20 70 43 61 63 68 65 3b  pCache = pCache;
2dd0: 0a 20 20 70 50 67 48 64 72 2d 3e 70 67 6e 6f 20  .  pPgHdr->pgno 
2de0: 3d 20 70 67 6e 6f 3b 0a 20 20 72 65 74 75 72 6e  = pgno;.  return
2df0: 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 46 65   sqlite3PcacheFe
2e00: 74 63 68 46 69 6e 69 73 68 28 70 43 61 63 68 65  tchFinish(pCache
2e10: 2c 70 67 6e 6f 2c 70 50 61 67 65 29 3b 0a 7d 0a  ,pgno,pPage);.}.
2e20: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74  ./*.** This rout
2e30: 69 6e 65 20 63 6f 6e 76 65 72 74 73 20 74 68 65  ine converts the
2e40: 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 5f   sqlite3_pcache_
2e50: 70 61 67 65 20 6f 62 6a 65 63 74 20 72 65 74 75  page object retu
2e60: 72 6e 65 64 20 62 79 0a 2a 2a 20 73 71 6c 69 74  rned by.** sqlit
2e70: 65 33 50 63 61 63 68 65 46 65 74 63 68 28 29 20  e3PcacheFetch() 
2e80: 69 6e 74 6f 20 61 6e 20 69 6e 69 74 69 61 6c 69  into an initiali
2e90: 7a 65 64 20 50 67 48 64 72 20 6f 62 6a 65 63 74  zed PgHdr object
2ea0: 2e 20 20 54 68 69 73 20 72 6f 75 74 69 6e 65 0a  .  This routine.
2eb0: 2a 2a 20 6d 75 73 74 20 62 65 20 63 61 6c 6c 65  ** must be calle
2ec0: 64 20 61 66 74 65 72 20 73 71 6c 69 74 65 33 50  d after sqlite3P
2ed0: 63 61 63 68 65 46 65 74 63 68 28 29 20 69 6e 20  cacheFetch() in 
2ee0: 6f 72 64 65 72 20 74 6f 20 67 65 74 20 61 20 75  order to get a u
2ef0: 73 61 62 6c 65 0a 2a 2a 20 72 65 73 75 6c 74 2e  sable.** result.
2f00: 0a 2a 2f 0a 50 67 48 64 72 20 2a 73 71 6c 69 74  .*/.PgHdr *sqlit
2f10: 65 33 50 63 61 63 68 65 46 65 74 63 68 46 69 6e  e3PcacheFetchFin
2f20: 69 73 68 28 0a 20 20 50 43 61 63 68 65 20 2a 70  ish(.  PCache *p
2f30: 43 61 63 68 65 2c 20 20 20 20 20 20 20 20 20 20  Cache,          
2f40: 20 20 20 2f 2a 20 4f 62 74 61 69 6e 20 74 68 65     /* Obtain the
2f50: 20 70 61 67 65 20 66 72 6f 6d 20 74 68 69 73 20   page from this 
2f60: 63 61 63 68 65 20 2a 2f 0a 20 20 50 67 6e 6f 20  cache */.  Pgno 
2f70: 70 67 6e 6f 2c 20 20 20 20 20 20 20 20 20 20 20  pgno,           
2f80: 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65 20 6e         /* Page n
2f90: 75 6d 62 65 72 20 6f 62 74 61 69 6e 65 64 20 2a  umber obtained *
2fa0: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 70 63 61 63  /.  sqlite3_pcac
2fb0: 68 65 5f 70 61 67 65 20 2a 70 50 61 67 65 20 20  he_page *pPage  
2fc0: 2f 2a 20 50 61 67 65 20 6f 62 74 61 69 6e 65 64  /* Page obtained
2fd0: 20 62 79 20 70 72 69 6f 72 20 50 63 61 63 68 65   by prior Pcache
2fe0: 46 65 74 63 68 28 29 20 63 61 6c 6c 20 2a 2f 0a  Fetch() call */.
2ff0: 29 7b 0a 20 20 50 67 48 64 72 20 2a 70 50 67 48  ){.  PgHdr *pPgH
3000: 64 72 3b 0a 0a 20 20 69 66 28 20 70 50 61 67 65  dr;..  if( pPage
3010: 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 30 3b 0a  ==0 ) return 0;.
3020: 20 20 70 50 67 48 64 72 20 3d 20 28 50 67 48 64    pPgHdr = (PgHd
3030: 72 20 2a 29 70 50 61 67 65 2d 3e 70 45 78 74 72  r *)pPage->pExtr
3040: 61 3b 0a 0a 20 20 69 66 28 20 21 70 50 67 48 64  a;..  if( !pPgHd
3050: 72 2d 3e 70 50 61 67 65 20 29 7b 0a 20 20 20 20  r->pPage ){.    
3060: 72 65 74 75 72 6e 20 70 63 61 63 68 65 46 65 74  return pcacheFet
3070: 63 68 46 69 6e 69 73 68 57 69 74 68 49 6e 69 74  chFinishWithInit
3080: 28 70 43 61 63 68 65 2c 20 70 67 6e 6f 2c 20 70  (pCache, pgno, p
3090: 50 61 67 65 29 3b 0a 20 20 7d 0a 20 20 69 66 28  Page);.  }.  if(
30a0: 20 30 3d 3d 70 50 67 48 64 72 2d 3e 6e 52 65 66   0==pPgHdr->nRef
30b0: 20 29 7b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e   ){.    pCache->
30c0: 6e 52 65 66 2b 2b 3b 0a 20 20 7d 0a 20 20 70 50  nRef++;.  }.  pP
30d0: 67 48 64 72 2d 3e 6e 52 65 66 2b 2b 3b 0a 20 20  gHdr->nRef++;.  
30e0: 69 66 28 20 70 67 6e 6f 3d 3d 31 20 29 7b 0a 20  if( pgno==1 ){. 
30f0: 20 20 20 70 43 61 63 68 65 2d 3e 70 50 61 67 65     pCache->pPage
3100: 31 20 3d 20 70 50 67 48 64 72 3b 0a 20 20 7d 0a  1 = pPgHdr;.  }.
3110: 20 20 72 65 74 75 72 6e 20 70 50 67 48 64 72 3b    return pPgHdr;
3120: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65 63 72 65 6d  .}../*.** Decrem
3130: 65 6e 74 20 74 68 65 20 72 65 66 65 72 65 6e 63  ent the referenc
3140: 65 20 63 6f 75 6e 74 20 6f 6e 20 61 20 70 61 67  e count on a pag
3150: 65 2e 20 49 66 20 74 68 65 20 70 61 67 65 20 69  e. If the page i
3160: 73 20 63 6c 65 61 6e 20 61 6e 64 20 74 68 65 0a  s clean and the.
3170: 2a 2a 20 72 65 66 65 72 65 6e 63 65 20 63 6f 75  ** reference cou
3180: 6e 74 20 64 72 6f 70 73 20 74 6f 20 30 2c 20 74  nt drops to 0, t
3190: 68 65 6e 20 69 74 20 69 73 20 6d 61 64 65 20 65  hen it is made e
31a0: 6c 69 67 69 62 6c 65 20 66 6f 72 20 72 65 63 79  ligible for recy
31b0: 63 6c 69 6e 67 2e 0a 2a 2f 0a 76 6f 69 64 20 53  cling..*/.void S
31c0: 51 4c 49 54 45 5f 4e 4f 49 4e 4c 49 4e 45 20 73  QLITE_NOINLINE s
31d0: 71 6c 69 74 65 33 50 63 61 63 68 65 52 65 6c 65  qlite3PcacheRele
31e0: 61 73 65 28 50 67 48 64 72 20 2a 70 29 7b 0a 20  ase(PgHdr *p){. 
31f0: 20 61 73 73 65 72 74 28 20 70 2d 3e 6e 52 65 66   assert( p->nRef
3200: 3e 30 20 29 3b 0a 20 20 70 2d 3e 6e 52 65 66 2d  >0 );.  p->nRef-
3210: 2d 3b 0a 20 20 69 66 28 20 70 2d 3e 6e 52 65 66  -;.  if( p->nRef
3220: 3d 3d 30 20 29 7b 0a 20 20 20 20 70 2d 3e 70 43  ==0 ){.    p->pC
3230: 61 63 68 65 2d 3e 6e 52 65 66 2d 2d 3b 0a 20 20  ache->nRef--;.  
3240: 20 20 69 66 28 20 28 70 2d 3e 66 6c 61 67 73 26    if( (p->flags&
3250: 50 47 48 44 52 5f 44 49 52 54 59 29 3d 3d 30 20  PGHDR_DIRTY)==0 
3260: 29 7b 0a 20 20 20 20 20 20 70 63 61 63 68 65 55  ){.      pcacheU
3270: 6e 70 69 6e 28 70 29 3b 0a 20 20 20 20 7d 65 6c  npin(p);.    }el
3280: 73 65 20 69 66 28 20 70 2d 3e 70 44 69 72 74 79  se if( p->pDirty
3290: 50 72 65 76 21 3d 30 20 29 7b 0a 20 20 20 20 20  Prev!=0 ){.     
32a0: 20 2f 2a 20 4d 6f 76 65 20 74 68 65 20 70 61 67   /* Move the pag
32b0: 65 20 74 6f 20 74 68 65 20 68 65 61 64 20 6f 66  e to the head of
32c0: 20 74 68 65 20 64 69 72 74 79 20 6c 69 73 74 2e   the dirty list.
32d0: 20 2a 2f 0a 20 20 20 20 20 20 70 63 61 63 68 65   */.      pcache
32e0: 4d 61 6e 61 67 65 44 69 72 74 79 4c 69 73 74 28  ManageDirtyList(
32f0: 70 2c 20 50 43 41 43 48 45 5f 44 49 52 54 59 4c  p, PCACHE_DIRTYL
3300: 49 53 54 5f 46 52 4f 4e 54 29 3b 0a 20 20 20 20  IST_FRONT);.    
3310: 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49  }.  }.}../*.** I
3320: 6e 63 72 65 61 73 65 20 74 68 65 20 72 65 66 65  ncrease the refe
3330: 72 65 6e 63 65 20 63 6f 75 6e 74 20 6f 66 20 61  rence count of a
3340: 20 73 75 70 70 6c 69 65 64 20 70 61 67 65 20 62   supplied page b
3350: 79 20 31 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c  y 1..*/.void sql
3360: 69 74 65 33 50 63 61 63 68 65 52 65 66 28 50 67  ite3PcacheRef(Pg
3370: 48 64 72 20 2a 70 29 7b 0a 20 20 61 73 73 65 72  Hdr *p){.  asser
3380: 74 28 70 2d 3e 6e 52 65 66 3e 30 29 3b 0a 20 20  t(p->nRef>0);.  
3390: 70 2d 3e 6e 52 65 66 2b 2b 3b 0a 7d 0a 0a 2f 2a  p->nRef++;.}../*
33a0: 0a 2a 2a 20 44 72 6f 70 20 61 20 70 61 67 65 20  .** Drop a page 
33b0: 66 72 6f 6d 20 74 68 65 20 63 61 63 68 65 2e 20  from the cache. 
33c0: 54 68 65 72 65 20 6d 75 73 74 20 62 65 20 65 78  There must be ex
33d0: 61 63 74 6c 79 20 6f 6e 65 20 72 65 66 65 72 65  actly one refere
33e0: 6e 63 65 20 74 6f 20 74 68 65 0a 2a 2a 20 70 61  nce to the.** pa
33f0: 67 65 2e 20 54 68 69 73 20 66 75 6e 63 74 69 6f  ge. This functio
3400: 6e 20 64 65 6c 65 74 65 73 20 74 68 61 74 20 72  n deletes that r
3410: 65 66 65 72 65 6e 63 65 2c 20 73 6f 20 61 66 74  eference, so aft
3420: 65 72 20 69 74 20 72 65 74 75 72 6e 73 20 74 68  er it returns th
3430: 65 0a 2a 2a 20 70 61 67 65 20 70 6f 69 6e 74 65  e.** page pointe
3440: 64 20 74 6f 20 62 79 20 70 20 69 73 20 69 6e 76  d to by p is inv
3450: 61 6c 69 64 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71  alid..*/.void sq
3460: 6c 69 74 65 33 50 63 61 63 68 65 44 72 6f 70 28  lite3PcacheDrop(
3470: 50 67 48 64 72 20 2a 70 29 7b 0a 20 20 61 73 73  PgHdr *p){.  ass
3480: 65 72 74 28 20 70 2d 3e 6e 52 65 66 3d 3d 31 20  ert( p->nRef==1 
3490: 29 3b 0a 20 20 69 66 28 20 70 2d 3e 66 6c 61 67  );.  if( p->flag
34a0: 73 26 50 47 48 44 52 5f 44 49 52 54 59 20 29 7b  s&PGHDR_DIRTY ){
34b0: 0a 20 20 20 20 70 63 61 63 68 65 4d 61 6e 61 67  .    pcacheManag
34c0: 65 44 69 72 74 79 4c 69 73 74 28 70 2c 20 50 43  eDirtyList(p, PC
34d0: 41 43 48 45 5f 44 49 52 54 59 4c 49 53 54 5f 52  ACHE_DIRTYLIST_R
34e0: 45 4d 4f 56 45 29 3b 0a 20 20 7d 0a 20 20 70 2d  EMOVE);.  }.  p-
34f0: 3e 70 43 61 63 68 65 2d 3e 6e 52 65 66 2d 2d 3b  >pCache->nRef--;
3500: 0a 20 20 69 66 28 20 70 2d 3e 70 67 6e 6f 3d 3d  .  if( p->pgno==
3510: 31 20 29 7b 0a 20 20 20 20 70 2d 3e 70 43 61 63  1 ){.    p->pCac
3520: 68 65 2d 3e 70 50 61 67 65 31 20 3d 20 30 3b 0a  he->pPage1 = 0;.
3530: 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 47 6c 6f    }.  sqlite3Glo
3540: 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65  balConfig.pcache
3550: 32 2e 78 55 6e 70 69 6e 28 70 2d 3e 70 43 61 63  2.xUnpin(p->pCac
3560: 68 65 2d 3e 70 43 61 63 68 65 2c 20 70 2d 3e 70  he->pCache, p->p
3570: 50 61 67 65 2c 20 31 29 3b 0a 7d 0a 0a 2f 2a 0a  Page, 1);.}../*.
3580: 2a 2a 20 4d 61 6b 65 20 73 75 72 65 20 74 68 65  ** Make sure the
3590: 20 70 61 67 65 20 69 73 20 6d 61 72 6b 65 64 20   page is marked 
35a0: 61 73 20 64 69 72 74 79 2e 20 49 66 20 69 74 20  as dirty. If it 
35b0: 69 73 6e 27 74 20 64 69 72 74 79 20 61 6c 72 65  isn't dirty alre
35c0: 61 64 79 2c 0a 2a 2a 20 6d 61 6b 65 20 69 74 20  ady,.** make it 
35d0: 73 6f 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69  so..*/.void sqli
35e0: 74 65 33 50 63 61 63 68 65 4d 61 6b 65 44 69 72  te3PcacheMakeDir
35f0: 74 79 28 50 67 48 64 72 20 2a 70 29 7b 0a 20 20  ty(PgHdr *p){.  
3600: 70 2d 3e 66 6c 61 67 73 20 26 3d 20 7e 50 47 48  p->flags &= ~PGH
3610: 44 52 5f 44 4f 4e 54 5f 57 52 49 54 45 3b 0a 20  DR_DONT_WRITE;. 
3620: 20 61 73 73 65 72 74 28 20 70 2d 3e 6e 52 65 66   assert( p->nRef
3630: 3e 30 20 29 3b 0a 20 20 69 66 28 20 30 3d 3d 28  >0 );.  if( 0==(
3640: 70 2d 3e 66 6c 61 67 73 20 26 20 50 47 48 44 52  p->flags & PGHDR
3650: 5f 44 49 52 54 59 29 20 29 7b 0a 20 20 20 20 70  _DIRTY) ){.    p
3660: 2d 3e 66 6c 61 67 73 20 7c 3d 20 50 47 48 44 52  ->flags |= PGHDR
3670: 5f 44 49 52 54 59 3b 0a 20 20 20 20 70 63 61 63  _DIRTY;.    pcac
3680: 68 65 4d 61 6e 61 67 65 44 69 72 74 79 4c 69 73  heManageDirtyLis
3690: 74 28 70 2c 20 50 43 41 43 48 45 5f 44 49 52 54  t(p, PCACHE_DIRT
36a0: 59 4c 49 53 54 5f 41 44 44 29 3b 0a 20 20 7d 0a  YLIST_ADD);.  }.
36b0: 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6b 65 20 73 75  }../*.** Make su
36c0: 72 65 20 74 68 65 20 70 61 67 65 20 69 73 20 6d  re the page is m
36d0: 61 72 6b 65 64 20 61 73 20 63 6c 65 61 6e 2e 20  arked as clean. 
36e0: 49 66 20 69 74 20 69 73 6e 27 74 20 63 6c 65 61  If it isn't clea
36f0: 6e 20 61 6c 72 65 61 64 79 2c 0a 2a 2a 20 6d 61  n already,.** ma
3700: 6b 65 20 69 74 20 73 6f 2e 0a 2a 2f 0a 76 6f 69  ke it so..*/.voi
3710: 64 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 4d  d sqlite3PcacheM
3720: 61 6b 65 43 6c 65 61 6e 28 50 67 48 64 72 20 2a  akeClean(PgHdr *
3730: 70 29 7b 0a 20 20 69 66 28 20 28 70 2d 3e 66 6c  p){.  if( (p->fl
3740: 61 67 73 20 26 20 50 47 48 44 52 5f 44 49 52 54  ags & PGHDR_DIRT
3750: 59 29 20 29 7b 0a 20 20 20 20 70 63 61 63 68 65  Y) ){.    pcache
3760: 4d 61 6e 61 67 65 44 69 72 74 79 4c 69 73 74 28  ManageDirtyList(
3770: 70 2c 20 50 43 41 43 48 45 5f 44 49 52 54 59 4c  p, PCACHE_DIRTYL
3780: 49 53 54 5f 52 45 4d 4f 56 45 29 3b 0a 20 20 20  IST_REMOVE);.   
3790: 20 70 2d 3e 66 6c 61 67 73 20 26 3d 20 7e 28 50   p->flags &= ~(P
37a0: 47 48 44 52 5f 44 49 52 54 59 7c 50 47 48 44 52  GHDR_DIRTY|PGHDR
37b0: 5f 4e 45 45 44 5f 53 59 4e 43 29 3b 0a 20 20 20  _NEED_SYNC);.   
37c0: 20 69 66 28 20 70 2d 3e 6e 52 65 66 3d 3d 30 20   if( p->nRef==0 
37d0: 29 7b 0a 20 20 20 20 20 20 70 63 61 63 68 65 55  ){.      pcacheU
37e0: 6e 70 69 6e 28 70 29 3b 0a 20 20 20 20 7d 0a 20  npin(p);.    }. 
37f0: 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6b 65   }.}../*.** Make
3800: 20 65 76 65 72 79 20 70 61 67 65 20 69 6e 20 74   every page in t
3810: 68 65 20 63 61 63 68 65 20 63 6c 65 61 6e 2e 0a  he cache clean..
3820: 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50  */.void sqlite3P
3830: 63 61 63 68 65 43 6c 65 61 6e 41 6c 6c 28 50 43  cacheCleanAll(PC
3840: 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b 0a 20  ache *pCache){. 
3850: 20 50 67 48 64 72 20 2a 70 3b 0a 20 20 77 68 69   PgHdr *p;.  whi
3860: 6c 65 28 20 28 70 20 3d 20 70 43 61 63 68 65 2d  le( (p = pCache-
3870: 3e 70 44 69 72 74 79 29 21 3d 30 20 29 7b 0a 20  >pDirty)!=0 ){. 
3880: 20 20 20 73 71 6c 69 74 65 33 50 63 61 63 68 65     sqlite3Pcache
3890: 4d 61 6b 65 43 6c 65 61 6e 28 70 29 3b 0a 20 20  MakeClean(p);.  
38a0: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 65 61 72  }.}../*.** Clear
38b0: 20 74 68 65 20 50 47 48 44 52 5f 4e 45 45 44 5f   the PGHDR_NEED_
38c0: 53 59 4e 43 20 66 6c 61 67 20 66 72 6f 6d 20 61  SYNC flag from a
38d0: 6c 6c 20 64 69 72 74 79 20 70 61 67 65 73 2e 0a  ll dirty pages..
38e0: 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50  */.void sqlite3P
38f0: 63 61 63 68 65 43 6c 65 61 72 53 79 6e 63 46 6c  cacheClearSyncFl
3900: 61 67 73 28 50 43 61 63 68 65 20 2a 70 43 61 63  ags(PCache *pCac
3910: 68 65 29 7b 0a 20 20 50 67 48 64 72 20 2a 70 3b  he){.  PgHdr *p;
3920: 0a 20 20 66 6f 72 28 70 3d 70 43 61 63 68 65 2d  .  for(p=pCache-
3930: 3e 70 44 69 72 74 79 3b 20 70 3b 20 70 3d 70 2d  >pDirty; p; p=p-
3940: 3e 70 44 69 72 74 79 4e 65 78 74 29 7b 0a 20 20  >pDirtyNext){.  
3950: 20 20 70 2d 3e 66 6c 61 67 73 20 26 3d 20 7e 50    p->flags &= ~P
3960: 47 48 44 52 5f 4e 45 45 44 5f 53 59 4e 43 3b 0a  GHDR_NEED_SYNC;.
3970: 20 20 7d 0a 20 20 70 43 61 63 68 65 2d 3e 70 53    }.  pCache->pS
3980: 79 6e 63 65 64 20 3d 20 70 43 61 63 68 65 2d 3e  ynced = pCache->
3990: 70 44 69 72 74 79 54 61 69 6c 3b 0a 7d 0a 0a 2f  pDirtyTail;.}../
39a0: 2a 0a 2a 2a 20 43 68 61 6e 67 65 20 74 68 65 20  *.** Change the 
39b0: 70 61 67 65 20 6e 75 6d 62 65 72 20 6f 66 20 70  page number of p
39c0: 61 67 65 20 70 20 74 6f 20 6e 65 77 50 67 6e 6f  age p to newPgno
39d0: 2e 20 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74  . .*/.void sqlit
39e0: 65 33 50 63 61 63 68 65 4d 6f 76 65 28 50 67 48  e3PcacheMove(PgH
39f0: 64 72 20 2a 70 2c 20 50 67 6e 6f 20 6e 65 77 50  dr *p, Pgno newP
3a00: 67 6e 6f 29 7b 0a 20 20 50 43 61 63 68 65 20 2a  gno){.  PCache *
3a10: 70 43 61 63 68 65 20 3d 20 70 2d 3e 70 43 61 63  pCache = p->pCac
3a20: 68 65 3b 0a 20 20 61 73 73 65 72 74 28 20 70 2d  he;.  assert( p-
3a30: 3e 6e 52 65 66 3e 30 20 29 3b 0a 20 20 61 73 73  >nRef>0 );.  ass
3a40: 65 72 74 28 20 6e 65 77 50 67 6e 6f 3e 30 20 29  ert( newPgno>0 )
3a50: 3b 0a 20 20 73 71 6c 69 74 65 33 47 6c 6f 62 61  ;.  sqlite3Globa
3a60: 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65 32 2e  lConfig.pcache2.
3a70: 78 52 65 6b 65 79 28 70 43 61 63 68 65 2d 3e 70  xRekey(pCache->p
3a80: 43 61 63 68 65 2c 20 70 2d 3e 70 50 61 67 65 2c  Cache, p->pPage,
3a90: 20 70 2d 3e 70 67 6e 6f 2c 6e 65 77 50 67 6e 6f   p->pgno,newPgno
3aa0: 29 3b 0a 20 20 70 2d 3e 70 67 6e 6f 20 3d 20 6e  );.  p->pgno = n
3ab0: 65 77 50 67 6e 6f 3b 0a 20 20 69 66 28 20 28 70  ewPgno;.  if( (p
3ac0: 2d 3e 66 6c 61 67 73 26 50 47 48 44 52 5f 44 49  ->flags&PGHDR_DI
3ad0: 52 54 59 29 20 26 26 20 28 70 2d 3e 66 6c 61 67  RTY) && (p->flag
3ae0: 73 26 50 47 48 44 52 5f 4e 45 45 44 5f 53 59 4e  s&PGHDR_NEED_SYN
3af0: 43 29 20 29 7b 0a 20 20 20 20 70 63 61 63 68 65  C) ){.    pcache
3b00: 4d 61 6e 61 67 65 44 69 72 74 79 4c 69 73 74 28  ManageDirtyList(
3b10: 70 2c 20 50 43 41 43 48 45 5f 44 49 52 54 59 4c  p, PCACHE_DIRTYL
3b20: 49 53 54 5f 46 52 4f 4e 54 29 3b 0a 20 20 7d 0a  IST_FRONT);.  }.
3b30: 7d 0a 0a 2f 2a 0a 2a 2a 20 44 72 6f 70 20 65 76  }../*.** Drop ev
3b40: 65 72 79 20 63 61 63 68 65 20 65 6e 74 72 79 20  ery cache entry 
3b50: 77 68 6f 73 65 20 70 61 67 65 20 6e 75 6d 62 65  whose page numbe
3b60: 72 20 69 73 20 67 72 65 61 74 65 72 20 74 68 61  r is greater tha
3b70: 6e 20 22 70 67 6e 6f 22 2e 20 54 68 65 0a 2a 2a  n "pgno". The.**
3b80: 20 63 61 6c 6c 65 72 20 6d 75 73 74 20 65 6e 73   caller must ens
3b90: 75 72 65 20 74 68 61 74 20 74 68 65 72 65 20 61  ure that there a
3ba0: 72 65 20 6e 6f 20 6f 75 74 73 74 61 6e 64 69 6e  re no outstandin
3bb0: 67 20 72 65 66 65 72 65 6e 63 65 73 20 74 6f 20  g references to 
3bc0: 61 6e 79 20 70 61 67 65 73 0a 2a 2a 20 6f 74 68  any pages.** oth
3bd0: 65 72 20 74 68 61 6e 20 70 61 67 65 20 31 20 77  er than page 1 w
3be0: 69 74 68 20 61 20 70 61 67 65 20 6e 75 6d 62 65  ith a page numbe
3bf0: 72 20 67 72 65 61 74 65 72 20 74 68 61 6e 20 70  r greater than p
3c00: 67 6e 6f 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68  gno..**.** If th
3c10: 65 72 65 20 69 73 20 61 20 72 65 66 65 72 65 6e  ere is a referen
3c20: 63 65 20 74 6f 20 70 61 67 65 20 31 20 61 6e 64  ce to page 1 and
3c30: 20 74 68 65 20 70 67 6e 6f 20 70 61 72 61 6d 65   the pgno parame
3c40: 74 65 72 20 70 61 73 73 65 64 20 74 6f 20 74 68  ter passed to th
3c50: 69 73 0a 2a 2a 20 66 75 6e 63 74 69 6f 6e 20 69  is.** function i
3c60: 73 20 30 2c 20 74 68 65 6e 20 74 68 65 20 64 61  s 0, then the da
3c70: 74 61 20 61 72 65 61 20 61 73 73 6f 63 69 61 74  ta area associat
3c80: 65 64 20 77 69 74 68 20 70 61 67 65 20 31 20 69  ed with page 1 i
3c90: 73 20 7a 65 72 6f 65 64 2c 20 62 75 74 0a 2a 2a  s zeroed, but.**
3ca0: 20 74 68 65 20 70 61 67 65 20 6f 62 6a 65 63 74   the page object
3cb0: 20 69 73 20 6e 6f 74 20 64 72 6f 70 70 65 64 2e   is not dropped.
3cc0: 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33  .*/.void sqlite3
3cd0: 50 63 61 63 68 65 54 72 75 6e 63 61 74 65 28 50  PcacheTruncate(P
3ce0: 43 61 63 68 65 20 2a 70 43 61 63 68 65 2c 20 50  Cache *pCache, P
3cf0: 67 6e 6f 20 70 67 6e 6f 29 7b 0a 20 20 69 66 28  gno pgno){.  if(
3d00: 20 70 43 61 63 68 65 2d 3e 70 43 61 63 68 65 20   pCache->pCache 
3d10: 29 7b 0a 20 20 20 20 50 67 48 64 72 20 2a 70 3b  ){.    PgHdr *p;
3d20: 0a 20 20 20 20 50 67 48 64 72 20 2a 70 4e 65 78  .    PgHdr *pNex
3d30: 74 3b 0a 20 20 20 20 66 6f 72 28 70 3d 70 43 61  t;.    for(p=pCa
3d40: 63 68 65 2d 3e 70 44 69 72 74 79 3b 20 70 3b 20  che->pDirty; p; 
3d50: 70 3d 70 4e 65 78 74 29 7b 0a 20 20 20 20 20 20  p=pNext){.      
3d60: 70 4e 65 78 74 20 3d 20 70 2d 3e 70 44 69 72 74  pNext = p->pDirt
3d70: 79 4e 65 78 74 3b 0a 20 20 20 20 20 20 2f 2a 20  yNext;.      /* 
3d80: 54 68 69 73 20 72 6f 75 74 69 6e 65 20 6e 65 76  This routine nev
3d90: 65 72 20 67 65 74 73 20 63 61 6c 6c 20 77 69 74  er gets call wit
3da0: 68 20 61 20 70 6f 73 69 74 69 76 65 20 70 67 6e  h a positive pgn
3db0: 6f 20 65 78 63 65 70 74 20 72 69 67 68 74 0a 20  o except right. 
3dc0: 20 20 20 20 20 2a 2a 20 61 66 74 65 72 20 73 71       ** after sq
3dd0: 6c 69 74 65 33 50 63 61 63 68 65 43 6c 65 61 6e  lite3PcacheClean
3de0: 41 6c 6c 28 29 2e 20 20 53 6f 20 69 66 20 74 68  All().  So if th
3df0: 65 72 65 20 61 72 65 20 64 69 72 74 79 20 70 61  ere are dirty pa
3e00: 67 65 73 2c 0a 20 20 20 20 20 20 2a 2a 20 69 74  ges,.      ** it
3e10: 20 6d 75 73 74 20 62 65 20 74 68 61 74 20 70 67   must be that pg
3e20: 6e 6f 3d 3d 30 2e 0a 20 20 20 20 20 20 2a 2f 0a  no==0..      */.
3e30: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70 2d        assert( p-
3e40: 3e 70 67 6e 6f 3e 30 20 29 3b 0a 20 20 20 20 20  >pgno>0 );.     
3e50: 20 69 66 28 20 41 4c 57 41 59 53 28 70 2d 3e 70   if( ALWAYS(p->p
3e60: 67 6e 6f 3e 70 67 6e 6f 29 20 29 7b 0a 20 20 20  gno>pgno) ){.   
3e70: 20 20 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e       assert( p->
3e80: 66 6c 61 67 73 26 50 47 48 44 52 5f 44 49 52 54  flags&PGHDR_DIRT
3e90: 59 20 29 3b 0a 20 20 20 20 20 20 20 20 73 71 6c  Y );.        sql
3ea0: 69 74 65 33 50 63 61 63 68 65 4d 61 6b 65 43 6c  ite3PcacheMakeCl
3eb0: 65 61 6e 28 70 29 3b 0a 20 20 20 20 20 20 7d 0a  ean(p);.      }.
3ec0: 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70 67      }.    if( pg
3ed0: 6e 6f 3d 3d 30 20 26 26 20 70 43 61 63 68 65 2d  no==0 && pCache-
3ee0: 3e 70 50 61 67 65 31 20 29 7b 0a 20 20 20 20 20  >pPage1 ){.     
3ef0: 20 6d 65 6d 73 65 74 28 70 43 61 63 68 65 2d 3e   memset(pCache->
3f00: 70 50 61 67 65 31 2d 3e 70 44 61 74 61 2c 20 30  pPage1->pData, 0
3f10: 2c 20 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65  , pCache->szPage
3f20: 29 3b 0a 20 20 20 20 20 20 70 67 6e 6f 20 3d 20  );.      pgno = 
3f30: 31 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 6c  1;.    }.    sql
3f40: 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67  ite3GlobalConfig
3f50: 2e 70 63 61 63 68 65 32 2e 78 54 72 75 6e 63 61  .pcache2.xTrunca
3f60: 74 65 28 70 43 61 63 68 65 2d 3e 70 43 61 63 68  te(pCache->pCach
3f70: 65 2c 20 70 67 6e 6f 2b 31 29 3b 0a 20 20 7d 0a  e, pgno+1);.  }.
3f80: 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61  }../*.** Close a
3f90: 20 63 61 63 68 65 2e 0a 2a 2f 0a 76 6f 69 64 20   cache..*/.void 
3fa0: 73 71 6c 69 74 65 33 50 63 61 63 68 65 43 6c 6f  sqlite3PcacheClo
3fb0: 73 65 28 50 43 61 63 68 65 20 2a 70 43 61 63 68  se(PCache *pCach
3fc0: 65 29 7b 0a 20 20 61 73 73 65 72 74 28 20 70 43  e){.  assert( pC
3fd0: 61 63 68 65 2d 3e 70 43 61 63 68 65 21 3d 30 20  ache->pCache!=0 
3fe0: 29 3b 0a 20 20 73 71 6c 69 74 65 33 47 6c 6f 62  );.  sqlite3Glob
3ff0: 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65 32  alConfig.pcache2
4000: 2e 78 44 65 73 74 72 6f 79 28 70 43 61 63 68 65  .xDestroy(pCache
4010: 2d 3e 70 43 61 63 68 65 29 3b 0a 7d 0a 0a 2f 2a  ->pCache);.}../*
4020: 20 0a 2a 2a 20 44 69 73 63 61 72 64 20 74 68 65   .** Discard the
4030: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65   contents of the
4040: 20 63 61 63 68 65 2e 0a 2a 2f 0a 76 6f 69 64 20   cache..*/.void 
4050: 73 71 6c 69 74 65 33 50 63 61 63 68 65 43 6c 65  sqlite3PcacheCle
4060: 61 72 28 50 43 61 63 68 65 20 2a 70 43 61 63 68  ar(PCache *pCach
4070: 65 29 7b 0a 20 20 73 71 6c 69 74 65 33 50 63 61  e){.  sqlite3Pca
4080: 63 68 65 54 72 75 6e 63 61 74 65 28 70 43 61 63  cheTruncate(pCac
4090: 68 65 2c 20 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  he, 0);.}../*.**
40a0: 20 4d 65 72 67 65 20 74 77 6f 20 6c 69 73 74 73   Merge two lists
40b0: 20 6f 66 20 70 61 67 65 73 20 63 6f 6e 6e 65 63   of pages connec
40c0: 74 65 64 20 62 79 20 70 44 69 72 74 79 20 61 6e  ted by pDirty an
40d0: 64 20 69 6e 20 70 67 6e 6f 20 6f 72 64 65 72 2e  d in pgno order.
40e0: 0a 2a 2a 20 44 6f 20 6e 6f 74 20 62 6f 74 68 20  .** Do not both 
40f0: 66 69 78 69 6e 67 20 74 68 65 20 70 44 69 72 74  fixing the pDirt
4100: 79 50 72 65 76 20 70 6f 69 6e 74 65 72 73 2e 0a  yPrev pointers..
4110: 2a 2f 0a 73 74 61 74 69 63 20 50 67 48 64 72 20  */.static PgHdr 
4120: 2a 70 63 61 63 68 65 4d 65 72 67 65 44 69 72 74  *pcacheMergeDirt
4130: 79 4c 69 73 74 28 50 67 48 64 72 20 2a 70 41 2c  yList(PgHdr *pA,
4140: 20 50 67 48 64 72 20 2a 70 42 29 7b 0a 20 20 50   PgHdr *pB){.  P
4150: 67 48 64 72 20 72 65 73 75 6c 74 2c 20 2a 70 54  gHdr result, *pT
4160: 61 69 6c 3b 0a 20 20 70 54 61 69 6c 20 3d 20 26  ail;.  pTail = &
4170: 72 65 73 75 6c 74 3b 0a 20 20 77 68 69 6c 65 28  result;.  while(
4180: 20 70 41 20 26 26 20 70 42 20 29 7b 0a 20 20 20   pA && pB ){.   
4190: 20 69 66 28 20 70 41 2d 3e 70 67 6e 6f 3c 70 42   if( pA->pgno<pB
41a0: 2d 3e 70 67 6e 6f 20 29 7b 0a 20 20 20 20 20 20  ->pgno ){.      
41b0: 70 54 61 69 6c 2d 3e 70 44 69 72 74 79 20 3d 20  pTail->pDirty = 
41c0: 70 41 3b 0a 20 20 20 20 20 20 70 54 61 69 6c 20  pA;.      pTail 
41d0: 3d 20 70 41 3b 0a 20 20 20 20 20 20 70 41 20 3d  = pA;.      pA =
41e0: 20 70 41 2d 3e 70 44 69 72 74 79 3b 0a 20 20 20   pA->pDirty;.   
41f0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 54   }else{.      pT
4200: 61 69 6c 2d 3e 70 44 69 72 74 79 20 3d 20 70 42  ail->pDirty = pB
4210: 3b 0a 20 20 20 20 20 20 70 54 61 69 6c 20 3d 20  ;.      pTail = 
4220: 70 42 3b 0a 20 20 20 20 20 20 70 42 20 3d 20 70  pB;.      pB = p
4230: 42 2d 3e 70 44 69 72 74 79 3b 0a 20 20 20 20 7d  B->pDirty;.    }
4240: 0a 20 20 7d 0a 20 20 69 66 28 20 70 41 20 29 7b  .  }.  if( pA ){
4250: 0a 20 20 20 20 70 54 61 69 6c 2d 3e 70 44 69 72  .    pTail->pDir
4260: 74 79 20 3d 20 70 41 3b 0a 20 20 7d 65 6c 73 65  ty = pA;.  }else
4270: 20 69 66 28 20 70 42 20 29 7b 0a 20 20 20 20 70   if( pB ){.    p
4280: 54 61 69 6c 2d 3e 70 44 69 72 74 79 20 3d 20 70  Tail->pDirty = p
4290: 42 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  B;.  }else{.    
42a0: 70 54 61 69 6c 2d 3e 70 44 69 72 74 79 20 3d 20  pTail->pDirty = 
42b0: 30 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  0;.  }.  return 
42c0: 72 65 73 75 6c 74 2e 70 44 69 72 74 79 3b 0a 7d  result.pDirty;.}
42d0: 0a 0a 2f 2a 0a 2a 2a 20 53 6f 72 74 20 74 68 65  ../*.** Sort the
42e0: 20 6c 69 73 74 20 6f 66 20 70 61 67 65 73 20 69   list of pages i
42f0: 6e 20 61 63 63 65 6e 64 69 6e 67 20 6f 72 64 65  n accending orde
4300: 72 20 62 79 20 70 67 6e 6f 2e 20 20 50 61 67 65  r by pgno.  Page
4310: 73 20 61 72 65 0a 2a 2a 20 63 6f 6e 6e 65 63 74  s are.** connect
4320: 65 64 20 62 79 20 70 44 69 72 74 79 20 70 6f 69  ed by pDirty poi
4330: 6e 74 65 72 73 2e 20 20 54 68 65 20 70 44 69 72  nters.  The pDir
4340: 74 79 50 72 65 76 20 70 6f 69 6e 74 65 72 73 20  tyPrev pointers 
4350: 61 72 65 0a 2a 2a 20 63 6f 72 72 75 70 74 65 64  are.** corrupted
4360: 20 62 79 20 74 68 69 73 20 73 6f 72 74 2e 0a 2a   by this sort..*
4370: 2a 0a 2a 2a 20 53 69 6e 63 65 20 74 68 65 72 65  *.** Since there
4380: 20 63 61 6e 6e 6f 74 20 62 65 20 6d 6f 72 65 20   cannot be more 
4390: 74 68 61 6e 20 32 5e 33 31 20 64 69 73 74 69 6e  than 2^31 distin
43a0: 63 74 20 70 61 67 65 73 20 69 6e 20 61 20 64 61  ct pages in a da
43b0: 74 61 62 61 73 65 2c 0a 2a 2a 20 74 68 65 72 65  tabase,.** there
43c0: 20 63 61 6e 6e 6f 74 20 62 65 20 6d 6f 72 65 20   cannot be more 
43d0: 74 68 61 6e 20 33 31 20 62 75 63 6b 65 74 73 20  than 31 buckets 
43e0: 72 65 71 75 69 72 65 64 20 62 79 20 74 68 65 20  required by the 
43f0: 6d 65 72 67 65 20 73 6f 72 74 65 72 2e 0a 2a 2a  merge sorter..**
4400: 20 4f 6e 65 20 65 78 74 72 61 20 62 75 63 6b 65   One extra bucke
4410: 74 20 69 73 20 61 64 64 65 64 20 74 6f 20 63 61  t is added to ca
4420: 74 63 68 20 6f 76 65 72 66 6c 6f 77 20 69 6e 20  tch overflow in 
4430: 63 61 73 65 20 73 6f 6d 65 74 68 69 6e 67 0a 2a  case something.*
4440: 2a 20 65 76 65 72 20 63 68 61 6e 67 65 73 20 74  * ever changes t
4450: 6f 20 6d 61 6b 65 20 74 68 65 20 70 72 65 76 69  o make the previ
4460: 6f 75 73 20 73 65 6e 74 65 6e 63 65 20 69 6e 63  ous sentence inc
4470: 6f 72 72 65 63 74 2e 0a 2a 2f 0a 23 64 65 66 69  orrect..*/.#defi
4480: 6e 65 20 4e 5f 53 4f 52 54 5f 42 55 43 4b 45 54  ne N_SORT_BUCKET
4490: 20 20 33 32 0a 73 74 61 74 69 63 20 50 67 48 64    32.static PgHd
44a0: 72 20 2a 70 63 61 63 68 65 53 6f 72 74 44 69 72  r *pcacheSortDir
44b0: 74 79 4c 69 73 74 28 50 67 48 64 72 20 2a 70 49  tyList(PgHdr *pI
44c0: 6e 29 7b 0a 20 20 50 67 48 64 72 20 2a 61 5b 4e  n){.  PgHdr *a[N
44d0: 5f 53 4f 52 54 5f 42 55 43 4b 45 54 5d 2c 20 2a  _SORT_BUCKET], *
44e0: 70 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 6d 65  p;.  int i;.  me
44f0: 6d 73 65 74 28 61 2c 20 30 2c 20 73 69 7a 65 6f  mset(a, 0, sizeo
4500: 66 28 61 29 29 3b 0a 20 20 77 68 69 6c 65 28 20  f(a));.  while( 
4510: 70 49 6e 20 29 7b 0a 20 20 20 20 70 20 3d 20 70  pIn ){.    p = p
4520: 49 6e 3b 0a 20 20 20 20 70 49 6e 20 3d 20 70 2d  In;.    pIn = p-
4530: 3e 70 44 69 72 74 79 3b 0a 20 20 20 20 70 2d 3e  >pDirty;.    p->
4540: 70 44 69 72 74 79 20 3d 20 30 3b 0a 20 20 20 20  pDirty = 0;.    
4550: 66 6f 72 28 69 3d 30 3b 20 41 4c 57 41 59 53 28  for(i=0; ALWAYS(
4560: 69 3c 4e 5f 53 4f 52 54 5f 42 55 43 4b 45 54 2d  i<N_SORT_BUCKET-
4570: 31 29 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  1); i++){.      
4580: 69 66 28 20 61 5b 69 5d 3d 3d 30 20 29 7b 0a 20  if( a[i]==0 ){. 
4590: 20 20 20 20 20 20 20 61 5b 69 5d 20 3d 20 70 3b         a[i] = p;
45a0: 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  .        break;.
45b0: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
45c0: 20 20 20 20 20 70 20 3d 20 70 63 61 63 68 65 4d       p = pcacheM
45d0: 65 72 67 65 44 69 72 74 79 4c 69 73 74 28 61 5b  ergeDirtyList(a[
45e0: 69 5d 2c 20 70 29 3b 0a 20 20 20 20 20 20 20 20  i], p);.        
45f0: 61 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20 20 20  a[i] = 0;.      
4600: 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20  }.    }.    if( 
4610: 4e 45 56 45 52 28 69 3d 3d 4e 5f 53 4f 52 54 5f  NEVER(i==N_SORT_
4620: 42 55 43 4b 45 54 2d 31 29 20 29 7b 0a 20 20 20  BUCKET-1) ){.   
4630: 20 20 20 2f 2a 20 54 6f 20 67 65 74 20 68 65 72     /* To get her
4640: 65 2c 20 74 68 65 72 65 20 6e 65 65 64 20 74 6f  e, there need to
4650: 20 62 65 20 32 5e 28 4e 5f 53 4f 52 54 5f 42 55   be 2^(N_SORT_BU
4660: 43 4b 45 54 29 20 65 6c 65 6d 65 6e 74 73 20 69  CKET) elements i
4670: 6e 0a 20 20 20 20 20 20 2a 2a 20 74 68 65 20 69  n.      ** the i
4680: 6e 70 75 74 20 6c 69 73 74 2e 20 20 42 75 74 20  nput list.  But 
4690: 74 68 61 74 20 69 73 20 69 6d 70 6f 73 73 69 62  that is impossib
46a0: 6c 65 2e 0a 20 20 20 20 20 20 2a 2f 0a 20 20 20  le..      */.   
46b0: 20 20 20 61 5b 69 5d 20 3d 20 70 63 61 63 68 65     a[i] = pcache
46c0: 4d 65 72 67 65 44 69 72 74 79 4c 69 73 74 28 61  MergeDirtyList(a
46d0: 5b 69 5d 2c 20 70 29 3b 0a 20 20 20 20 7d 0a 20  [i], p);.    }. 
46e0: 20 7d 0a 20 20 70 20 3d 20 61 5b 30 5d 3b 0a 20   }.  p = a[0];. 
46f0: 20 66 6f 72 28 69 3d 31 3b 20 69 3c 4e 5f 53 4f   for(i=1; i<N_SO
4700: 52 54 5f 42 55 43 4b 45 54 3b 20 69 2b 2b 29 7b  RT_BUCKET; i++){
4710: 0a 20 20 20 20 70 20 3d 20 70 63 61 63 68 65 4d  .    p = pcacheM
4720: 65 72 67 65 44 69 72 74 79 4c 69 73 74 28 70 2c  ergeDirtyList(p,
4730: 20 61 5b 69 5d 29 3b 0a 20 20 7d 0a 20 20 72 65   a[i]);.  }.  re
4740: 74 75 72 6e 20 70 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  turn p;.}../*.**
4750: 20 52 65 74 75 72 6e 20 61 20 6c 69 73 74 20 6f   Return a list o
4760: 66 20 61 6c 6c 20 64 69 72 74 79 20 70 61 67 65  f all dirty page
4770: 73 20 69 6e 20 74 68 65 20 63 61 63 68 65 2c 20  s in the cache, 
4780: 73 6f 72 74 65 64 20 62 79 20 70 61 67 65 20 6e  sorted by page n
4790: 75 6d 62 65 72 2e 0a 2a 2f 0a 50 67 48 64 72 20  umber..*/.PgHdr 
47a0: 2a 73 71 6c 69 74 65 33 50 63 61 63 68 65 44 69  *sqlite3PcacheDi
47b0: 72 74 79 4c 69 73 74 28 50 43 61 63 68 65 20 2a  rtyList(PCache *
47c0: 70 43 61 63 68 65 29 7b 0a 20 20 50 67 48 64 72  pCache){.  PgHdr
47d0: 20 2a 70 3b 0a 20 20 66 6f 72 28 70 3d 70 43 61   *p;.  for(p=pCa
47e0: 63 68 65 2d 3e 70 44 69 72 74 79 3b 20 70 3b 20  che->pDirty; p; 
47f0: 70 3d 70 2d 3e 70 44 69 72 74 79 4e 65 78 74 29  p=p->pDirtyNext)
4800: 7b 0a 20 20 20 20 70 2d 3e 70 44 69 72 74 79 20  {.    p->pDirty 
4810: 3d 20 70 2d 3e 70 44 69 72 74 79 4e 65 78 74 3b  = p->pDirtyNext;
4820: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 70 63  .  }.  return pc
4830: 61 63 68 65 53 6f 72 74 44 69 72 74 79 4c 69 73  acheSortDirtyLis
4840: 74 28 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79  t(pCache->pDirty
4850: 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 52 65 74  );.}../* .** Ret
4860: 75 72 6e 20 74 68 65 20 74 6f 74 61 6c 20 6e 75  urn the total nu
4870: 6d 62 65 72 20 6f 66 20 72 65 66 65 72 65 6e 63  mber of referenc
4880: 65 64 20 70 61 67 65 73 20 68 65 6c 64 20 62 79  ed pages held by
4890: 20 74 68 65 20 63 61 63 68 65 2e 0a 2a 2f 0a 69   the cache..*/.i
48a0: 6e 74 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  nt sqlite3Pcache
48b0: 52 65 66 43 6f 75 6e 74 28 50 43 61 63 68 65 20  RefCount(PCache 
48c0: 2a 70 43 61 63 68 65 29 7b 0a 20 20 72 65 74 75  *pCache){.  retu
48d0: 72 6e 20 70 43 61 63 68 65 2d 3e 6e 52 65 66 3b  rn pCache->nRef;
48e0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e  .}../*.** Return
48f0: 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 72   the number of r
4900: 65 66 65 72 65 6e 63 65 73 20 74 6f 20 74 68 65  eferences to the
4910: 20 70 61 67 65 20 73 75 70 70 6c 69 65 64 20 61   page supplied a
4920: 73 20 61 6e 20 61 72 67 75 6d 65 6e 74 2e 0a 2a  s an argument..*
4930: 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 50 63 61  /.int sqlite3Pca
4940: 63 68 65 50 61 67 65 52 65 66 63 6f 75 6e 74 28  chePageRefcount(
4950: 50 67 48 64 72 20 2a 70 29 7b 0a 20 20 72 65 74  PgHdr *p){.  ret
4960: 75 72 6e 20 70 2d 3e 6e 52 65 66 3b 0a 7d 0a 0a  urn p->nRef;.}..
4970: 2f 2a 20 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68  /* .** Return th
4980: 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f  e total number o
4990: 66 20 70 61 67 65 73 20 69 6e 20 74 68 65 20 63  f pages in the c
49a0: 61 63 68 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c  ache..*/.int sql
49b0: 69 74 65 33 50 63 61 63 68 65 50 61 67 65 63 6f  ite3PcachePageco
49c0: 75 6e 74 28 50 43 61 63 68 65 20 2a 70 43 61 63  unt(PCache *pCac
49d0: 68 65 29 7b 0a 20 20 61 73 73 65 72 74 28 20 70  he){.  assert( p
49e0: 43 61 63 68 65 2d 3e 70 43 61 63 68 65 21 3d 30  Cache->pCache!=0
49f0: 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c   );.  return sql
4a00: 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67  ite3GlobalConfig
4a10: 2e 70 63 61 63 68 65 32 2e 78 50 61 67 65 63 6f  .pcache2.xPageco
4a20: 75 6e 74 28 70 43 61 63 68 65 2d 3e 70 43 61 63  unt(pCache->pCac
4a30: 68 65 29 3b 0a 7d 0a 0a 23 69 66 64 65 66 20 53  he);.}..#ifdef S
4a40: 51 4c 49 54 45 5f 54 45 53 54 0a 2f 2a 0a 2a 2a  QLITE_TEST./*.**
4a50: 20 47 65 74 20 74 68 65 20 73 75 67 67 65 73 74   Get the suggest
4a60: 65 64 20 63 61 63 68 65 2d 73 69 7a 65 20 76 61  ed cache-size va
4a70: 6c 75 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  lue..*/.int sqli
4a80: 74 65 33 50 63 61 63 68 65 47 65 74 43 61 63 68  te3PcacheGetCach
4a90: 65 73 69 7a 65 28 50 43 61 63 68 65 20 2a 70 43  esize(PCache *pC
4aa0: 61 63 68 65 29 7b 0a 20 20 72 65 74 75 72 6e 20  ache){.  return 
4ab0: 6e 75 6d 62 65 72 4f 66 43 61 63 68 65 50 61 67  numberOfCachePag
4ac0: 65 73 28 70 43 61 63 68 65 29 3b 0a 7d 0a 23 65  es(pCache);.}.#e
4ad0: 6e 64 69 66 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20  ndif../*.** Set 
4ae0: 74 68 65 20 73 75 67 67 65 73 74 65 64 20 63 61  the suggested ca
4af0: 63 68 65 2d 73 69 7a 65 20 76 61 6c 75 65 2e 0a  che-size value..
4b00: 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50  */.void sqlite3P
4b10: 63 61 63 68 65 53 65 74 43 61 63 68 65 73 69 7a  cacheSetCachesiz
4b20: 65 28 50 43 61 63 68 65 20 2a 70 43 61 63 68 65  e(PCache *pCache
4b30: 2c 20 69 6e 74 20 6d 78 50 61 67 65 29 7b 0a 20  , int mxPage){. 
4b40: 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65 2d   assert( pCache-
4b50: 3e 70 43 61 63 68 65 21 3d 30 20 29 3b 0a 20 20  >pCache!=0 );.  
4b60: 70 43 61 63 68 65 2d 3e 73 7a 43 61 63 68 65 20  pCache->szCache 
4b70: 3d 20 6d 78 50 61 67 65 3b 0a 20 20 73 71 6c 69  = mxPage;.  sqli
4b80: 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e  te3GlobalConfig.
4b90: 70 63 61 63 68 65 32 2e 78 43 61 63 68 65 73 69  pcache2.xCachesi
4ba0: 7a 65 28 70 43 61 63 68 65 2d 3e 70 43 61 63 68  ze(pCache->pCach
4bb0: 65 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  e,.             
4bc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4bd0: 20 20 20 20 20 20 20 20 20 20 20 20 6e 75 6d 62              numb
4be0: 65 72 4f 66 43 61 63 68 65 50 61 67 65 73 28 70  erOfCachePages(p
4bf0: 43 61 63 68 65 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  Cache));.}../*.*
4c00: 2a 20 46 72 65 65 20 75 70 20 61 73 20 6d 75 63  * Free up as muc
4c10: 68 20 6d 65 6d 6f 72 79 20 61 73 20 70 6f 73 73  h memory as poss
4c20: 69 62 6c 65 20 66 72 6f 6d 20 74 68 65 20 70 61  ible from the pa
4c30: 67 65 20 63 61 63 68 65 2e 0a 2a 2f 0a 76 6f 69  ge cache..*/.voi
4c40: 64 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 53  d sqlite3PcacheS
4c50: 68 72 69 6e 6b 28 50 43 61 63 68 65 20 2a 70 43  hrink(PCache *pC
4c60: 61 63 68 65 29 7b 0a 20 20 61 73 73 65 72 74 28  ache){.  assert(
4c70: 20 70 43 61 63 68 65 2d 3e 70 43 61 63 68 65 21   pCache->pCache!
4c80: 3d 30 20 29 3b 0a 20 20 73 71 6c 69 74 65 33 47  =0 );.  sqlite3G
4c90: 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63  lobalConfig.pcac
4ca0: 68 65 32 2e 78 53 68 72 69 6e 6b 28 70 43 61 63  he2.xShrink(pCac
4cb0: 68 65 2d 3e 70 43 61 63 68 65 29 3b 0a 7d 0a 0a  he->pCache);.}..
4cc0: 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65  /*.** Return the
4cd0: 20 73 69 7a 65 20 6f 66 20 74 68 65 20 68 65 61   size of the hea
4ce0: 64 65 72 20 61 64 64 65 64 20 62 79 20 74 68 69  der added by thi
4cf0: 73 20 6d 69 64 64 6c 65 77 61 72 65 20 6c 61 79  s middleware lay
4d00: 65 72 0a 2a 2a 20 69 6e 20 74 68 65 20 70 61 67  er.** in the pag
4d10: 65 2d 63 61 63 68 65 20 68 69 65 72 61 72 63 68  e-cache hierarch
4d20: 79 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  y..*/.int sqlite
4d30: 33 48 65 61 64 65 72 53 69 7a 65 50 63 61 63 68  3HeaderSizePcach
4d40: 65 28 76 6f 69 64 29 7b 20 72 65 74 75 72 6e 20  e(void){ return 
4d50: 52 4f 55 4e 44 38 28 73 69 7a 65 6f 66 28 50 67  ROUND8(sizeof(Pg
4d60: 48 64 72 29 29 3b 20 7d 0a 0a 0a 23 69 66 20 64  Hdr)); }...#if d
4d70: 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 43 48  efined(SQLITE_CH
4d80: 45 43 4b 5f 50 41 47 45 53 29 20 7c 7c 20 64 65  ECK_PAGES) || de
4d90: 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 44 45 42  fined(SQLITE_DEB
4da0: 55 47 29 0a 2f 2a 0a 2a 2a 20 46 6f 72 20 61 6c  UG)./*.** For al
4db0: 6c 20 64 69 72 74 79 20 70 61 67 65 73 20 63 75  l dirty pages cu
4dc0: 72 72 65 6e 74 6c 79 20 69 6e 20 74 68 65 20 63  rrently in the c
4dd0: 61 63 68 65 2c 20 69 6e 76 6f 6b 65 20 74 68 65  ache, invoke the
4de0: 20 73 70 65 63 69 66 69 65 64 0a 2a 2a 20 63 61   specified.** ca
4df0: 6c 6c 62 61 63 6b 2e 20 54 68 69 73 20 69 73 20  llback. This is 
4e00: 6f 6e 6c 79 20 75 73 65 64 20 69 66 20 74 68 65  only used if the
4e10: 20 53 51 4c 49 54 45 5f 43 48 45 43 4b 5f 50 41   SQLITE_CHECK_PA
4e20: 47 45 53 20 6d 61 63 72 6f 20 69 73 0a 2a 2a 20  GES macro is.** 
4e30: 64 65 66 69 6e 65 64 2e 0a 2a 2f 0a 76 6f 69 64  defined..*/.void
4e40: 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 49 74   sqlite3PcacheIt
4e50: 65 72 61 74 65 44 69 72 74 79 28 50 43 61 63 68  erateDirty(PCach
4e60: 65 20 2a 70 43 61 63 68 65 2c 20 76 6f 69 64 20  e *pCache, void 
4e70: 28 2a 78 49 74 65 72 29 28 50 67 48 64 72 20 2a  (*xIter)(PgHdr *
4e80: 29 29 7b 0a 20 20 50 67 48 64 72 20 2a 70 44 69  )){.  PgHdr *pDi
4e90: 72 74 79 3b 0a 20 20 66 6f 72 28 70 44 69 72 74  rty;.  for(pDirt
4ea0: 79 3d 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79  y=pCache->pDirty
4eb0: 3b 20 70 44 69 72 74 79 3b 20 70 44 69 72 74 79  ; pDirty; pDirty
4ec0: 3d 70 44 69 72 74 79 2d 3e 70 44 69 72 74 79 4e  =pDirty->pDirtyN
4ed0: 65 78 74 29 7b 0a 20 20 20 20 78 49 74 65 72 28  ext){.    xIter(
4ee0: 70 44 69 72 74 79 29 3b 0a 20 20 7d 0a 7d 0a 23  pDirty);.  }.}.#
4ef0: 65 6e 64 69 66 0a                                endif.