/ Hex Artifact Content
Login

Artifact 379fd77feb732b39750eb733260d9c227d8a4314:


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 7d 3b 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  .};../**********
0540: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0550: 2a 2a 2a 2a 2a 2a 2a 2a 20 4c 69 6e 6b 65 64 20  ******** Linked 
0560: 4c 69 73 74 20 4d 61 6e 61 67 65 6d 65 6e 74 20  List Management 
0570: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0580: 2a 2a 2a 2a 2f 0a 0a 2f 2a 20 41 6c 6c 6f 77 65  ****/../* Allowe
0590: 64 20 76 61 6c 75 65 73 20 66 6f 72 20 73 65 63  d values for sec
05a0: 6f 6e 64 20 61 72 67 75 6d 65 6e 74 20 74 6f 20  ond argument to 
05b0: 70 63 61 63 68 65 4d 61 6e 61 67 65 44 69 72 74  pcacheManageDirt
05c0: 79 4c 69 73 74 28 29 20 2a 2f 0a 23 64 65 66 69  yList() */.#defi
05d0: 6e 65 20 50 43 41 43 48 45 5f 44 49 52 54 59 4c  ne PCACHE_DIRTYL
05e0: 49 53 54 5f 52 45 4d 4f 56 45 20 20 20 31 20 20  IST_REMOVE   1  
05f0: 20 20 2f 2a 20 52 65 6d 6f 76 65 20 70 50 61 67    /* Remove pPag
0600: 65 20 66 72 6f 6d 20 64 69 72 74 79 20 6c 69 73  e from dirty lis
0610: 74 20 2a 2f 0a 23 64 65 66 69 6e 65 20 50 43 41  t */.#define PCA
0620: 43 48 45 5f 44 49 52 54 59 4c 49 53 54 5f 41 44  CHE_DIRTYLIST_AD
0630: 44 20 20 20 20 20 20 32 20 20 20 20 2f 2a 20 41  D      2    /* A
0640: 64 64 20 70 50 61 67 65 20 74 6f 20 74 68 65 20  dd pPage to the 
0650: 64 69 72 74 79 20 6c 69 73 74 20 2a 2f 0a 23 64  dirty list */.#d
0660: 65 66 69 6e 65 20 50 43 41 43 48 45 5f 44 49 52  efine PCACHE_DIR
0670: 54 59 4c 49 53 54 5f 46 52 4f 4e 54 20 20 20 20  TYLIST_FRONT    
0680: 33 20 20 20 20 2f 2a 20 4d 6f 76 65 20 70 50 61  3    /* Move pPa
0690: 67 65 20 74 6f 20 74 68 65 20 66 72 6f 6e 74 20  ge to the front 
06a0: 6f 66 20 74 68 65 20 6c 69 73 74 20 2a 2f 0a 0a  of the list */..
06b0: 2f 2a 0a 2a 2a 20 4d 61 6e 61 67 65 20 70 50 61  /*.** Manage pPa
06c0: 67 65 27 73 20 70 61 72 74 69 63 69 70 61 74 69  ge's participati
06d0: 6f 6e 20 6f 6e 20 74 68 65 20 64 69 72 74 79 20  on on the dirty 
06e0: 6c 69 73 74 2e 20 20 42 69 74 73 20 6f 66 20 74  list.  Bits of t
06f0: 68 65 20 61 64 64 52 65 6d 6f 76 65 0a 2a 2a 20  he addRemove.** 
0700: 61 72 67 75 6d 65 6e 74 20 64 65 74 65 72 6d 69  argument determi
0710: 6e 65 73 20 77 68 61 74 20 6f 70 65 72 61 74 69  nes what operati
0720: 6f 6e 20 74 6f 20 64 6f 2e 20 20 54 68 65 20 30  on to do.  The 0
0730: 78 30 31 20 62 69 74 20 6d 65 61 6e 73 20 66 69  x01 bit means fi
0740: 72 73 74 0a 2a 2a 20 72 65 6d 6f 76 65 20 70 50  rst.** remove pP
0750: 61 67 65 20 66 72 6f 6d 20 74 68 65 20 64 69 72  age from the dir
0760: 74 79 20 6c 69 73 74 2e 20 20 54 68 65 20 30 78  ty list.  The 0x
0770: 30 32 20 6d 65 61 6e 73 20 61 64 64 20 70 50 61  02 means add pPa
0780: 67 65 20 62 61 63 6b 20 74 6f 0a 2a 2a 20 74 68  ge back to.** th
0790: 65 20 64 69 72 74 79 20 6c 69 73 74 2e 20 20 44  e dirty list.  D
07a0: 6f 69 6e 67 20 62 6f 74 68 20 6d 6f 76 65 73 20  oing both moves 
07b0: 70 50 61 67 65 20 74 6f 20 74 68 65 20 66 72 6f  pPage to the fro
07c0: 6e 74 20 6f 66 20 74 68 65 20 64 69 72 74 79 20  nt of the dirty 
07d0: 6c 69 73 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  list..*/.static 
07e0: 76 6f 69 64 20 70 63 61 63 68 65 4d 61 6e 61 67  void pcacheManag
07f0: 65 44 69 72 74 79 4c 69 73 74 28 50 67 48 64 72  eDirtyList(PgHdr
0800: 20 2a 70 50 61 67 65 2c 20 75 38 20 61 64 64 52   *pPage, u8 addR
0810: 65 6d 6f 76 65 29 7b 0a 20 20 50 43 61 63 68 65  emove){.  PCache
0820: 20 2a 70 20 3d 20 70 50 61 67 65 2d 3e 70 43 61   *p = pPage->pCa
0830: 63 68 65 3b 0a 0a 20 20 69 66 28 20 61 64 64 52  che;..  if( addR
0840: 65 6d 6f 76 65 20 26 20 50 43 41 43 48 45 5f 44  emove & PCACHE_D
0850: 49 52 54 59 4c 49 53 54 5f 52 45 4d 4f 56 45 20  IRTYLIST_REMOVE 
0860: 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70  ){.    assert( p
0870: 50 61 67 65 2d 3e 70 44 69 72 74 79 4e 65 78 74  Page->pDirtyNext
0880: 20 7c 7c 20 70 50 61 67 65 3d 3d 70 2d 3e 70 44   || pPage==p->pD
0890: 69 72 74 79 54 61 69 6c 20 29 3b 0a 20 20 20 20  irtyTail );.    
08a0: 61 73 73 65 72 74 28 20 70 50 61 67 65 2d 3e 70  assert( pPage->p
08b0: 44 69 72 74 79 50 72 65 76 20 7c 7c 20 70 50 61  DirtyPrev || pPa
08c0: 67 65 3d 3d 70 2d 3e 70 44 69 72 74 79 20 29 3b  ge==p->pDirty );
08d0: 0a 20 20 0a 20 20 20 20 2f 2a 20 55 70 64 61 74  .  .    /* Updat
08e0: 65 20 74 68 65 20 50 43 61 63 68 65 31 2e 70 53  e the PCache1.pS
08f0: 79 6e 63 65 64 20 76 61 72 69 61 62 6c 65 20 69  ynced variable i
0900: 66 20 6e 65 63 65 73 73 61 72 79 2e 20 2a 2f 0a  f necessary. */.
0910: 20 20 20 20 69 66 28 20 70 2d 3e 70 53 79 6e 63      if( p->pSync
0920: 65 64 3d 3d 70 50 61 67 65 20 29 7b 0a 20 20 20  ed==pPage ){.   
0930: 20 20 20 50 67 48 64 72 20 2a 70 53 79 6e 63 65     PgHdr *pSynce
0940: 64 20 3d 20 70 50 61 67 65 2d 3e 70 44 69 72 74  d = pPage->pDirt
0950: 79 50 72 65 76 3b 0a 20 20 20 20 20 20 77 68 69  yPrev;.      whi
0960: 6c 65 28 20 70 53 79 6e 63 65 64 20 26 26 20 28  le( pSynced && (
0970: 70 53 79 6e 63 65 64 2d 3e 66 6c 61 67 73 26 50  pSynced->flags&P
0980: 47 48 44 52 5f 4e 45 45 44 5f 53 59 4e 43 29 20  GHDR_NEED_SYNC) 
0990: 29 7b 0a 20 20 20 20 20 20 20 20 70 53 79 6e 63  ){.        pSync
09a0: 65 64 20 3d 20 70 53 79 6e 63 65 64 2d 3e 70 44  ed = pSynced->pD
09b0: 69 72 74 79 50 72 65 76 3b 0a 20 20 20 20 20 20  irtyPrev;.      
09c0: 7d 0a 20 20 20 20 20 20 70 2d 3e 70 53 79 6e 63  }.      p->pSync
09d0: 65 64 20 3d 20 70 53 79 6e 63 65 64 3b 0a 20 20  ed = pSynced;.  
09e0: 20 20 7d 0a 20 20 0a 20 20 20 20 69 66 28 20 70    }.  .    if( p
09f0: 50 61 67 65 2d 3e 70 44 69 72 74 79 4e 65 78 74  Page->pDirtyNext
0a00: 20 29 7b 0a 20 20 20 20 20 20 70 50 61 67 65 2d   ){.      pPage-
0a10: 3e 70 44 69 72 74 79 4e 65 78 74 2d 3e 70 44 69  >pDirtyNext->pDi
0a20: 72 74 79 50 72 65 76 20 3d 20 70 50 61 67 65 2d  rtyPrev = pPage-
0a30: 3e 70 44 69 72 74 79 50 72 65 76 3b 0a 20 20 20  >pDirtyPrev;.   
0a40: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 61 73   }else{.      as
0a50: 73 65 72 74 28 20 70 50 61 67 65 3d 3d 70 2d 3e  sert( pPage==p->
0a60: 70 44 69 72 74 79 54 61 69 6c 20 29 3b 0a 20 20  pDirtyTail );.  
0a70: 20 20 20 20 70 2d 3e 70 44 69 72 74 79 54 61 69      p->pDirtyTai
0a80: 6c 20 3d 20 70 50 61 67 65 2d 3e 70 44 69 72 74  l = pPage->pDirt
0a90: 79 50 72 65 76 3b 0a 20 20 20 20 7d 0a 20 20 20  yPrev;.    }.   
0aa0: 20 69 66 28 20 70 50 61 67 65 2d 3e 70 44 69 72   if( pPage->pDir
0ab0: 74 79 50 72 65 76 20 29 7b 0a 20 20 20 20 20 20  tyPrev ){.      
0ac0: 70 50 61 67 65 2d 3e 70 44 69 72 74 79 50 72 65  pPage->pDirtyPre
0ad0: 76 2d 3e 70 44 69 72 74 79 4e 65 78 74 20 3d 20  v->pDirtyNext = 
0ae0: 70 50 61 67 65 2d 3e 70 44 69 72 74 79 4e 65 78  pPage->pDirtyNex
0af0: 74 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  t;.    }else{.  
0b00: 20 20 20 20 61 73 73 65 72 74 28 20 70 50 61 67      assert( pPag
0b10: 65 3d 3d 70 2d 3e 70 44 69 72 74 79 20 29 3b 0a  e==p->pDirty );.
0b20: 20 20 20 20 20 20 70 2d 3e 70 44 69 72 74 79 20        p->pDirty 
0b30: 3d 20 70 50 61 67 65 2d 3e 70 44 69 72 74 79 4e  = pPage->pDirtyN
0b40: 65 78 74 3b 0a 20 20 20 20 20 20 69 66 28 20 70  ext;.      if( p
0b50: 2d 3e 70 44 69 72 74 79 3d 3d 30 20 26 26 20 70  ->pDirty==0 && p
0b60: 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 29 7b 0a  ->bPurgeable ){.
0b70: 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28 20          assert( 
0b80: 70 2d 3e 65 43 72 65 61 74 65 3d 3d 31 20 29 3b  p->eCreate==1 );
0b90: 0a 20 20 20 20 20 20 20 20 70 2d 3e 65 43 72 65  .        p->eCre
0ba0: 61 74 65 20 3d 20 32 3b 0a 20 20 20 20 20 20 7d  ate = 2;.      }
0bb0: 0a 20 20 20 20 7d 0a 20 20 20 20 70 50 61 67 65  .    }.    pPage
0bc0: 2d 3e 70 44 69 72 74 79 4e 65 78 74 20 3d 20 30  ->pDirtyNext = 0
0bd0: 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 44 69  ;.    pPage->pDi
0be0: 72 74 79 50 72 65 76 20 3d 20 30 3b 0a 20 20 7d  rtyPrev = 0;.  }
0bf0: 0a 20 20 69 66 28 20 61 64 64 52 65 6d 6f 76 65  .  if( addRemove
0c00: 20 26 20 50 43 41 43 48 45 5f 44 49 52 54 59 4c   & PCACHE_DIRTYL
0c10: 49 53 54 5f 41 44 44 20 29 7b 0a 20 20 20 20 61  IST_ADD ){.    a
0c20: 73 73 65 72 74 28 20 70 50 61 67 65 2d 3e 70 44  ssert( pPage->pD
0c30: 69 72 74 79 4e 65 78 74 3d 3d 30 20 26 26 20 70  irtyNext==0 && p
0c40: 50 61 67 65 2d 3e 70 44 69 72 74 79 50 72 65 76  Page->pDirtyPrev
0c50: 3d 3d 30 20 26 26 20 70 2d 3e 70 44 69 72 74 79  ==0 && p->pDirty
0c60: 21 3d 70 50 61 67 65 20 29 3b 0a 20 20 0a 20 20  !=pPage );.  .  
0c70: 20 20 70 50 61 67 65 2d 3e 70 44 69 72 74 79 4e    pPage->pDirtyN
0c80: 65 78 74 20 3d 20 70 2d 3e 70 44 69 72 74 79 3b  ext = p->pDirty;
0c90: 0a 20 20 20 20 69 66 28 20 70 50 61 67 65 2d 3e  .    if( pPage->
0ca0: 70 44 69 72 74 79 4e 65 78 74 20 29 7b 0a 20 20  pDirtyNext ){.  
0cb0: 20 20 20 20 61 73 73 65 72 74 28 20 70 50 61 67      assert( pPag
0cc0: 65 2d 3e 70 44 69 72 74 79 4e 65 78 74 2d 3e 70  e->pDirtyNext->p
0cd0: 44 69 72 74 79 50 72 65 76 3d 3d 30 20 29 3b 0a  DirtyPrev==0 );.
0ce0: 20 20 20 20 20 20 70 50 61 67 65 2d 3e 70 44 69        pPage->pDi
0cf0: 72 74 79 4e 65 78 74 2d 3e 70 44 69 72 74 79 50  rtyNext->pDirtyP
0d00: 72 65 76 20 3d 20 70 50 61 67 65 3b 0a 20 20 20  rev = pPage;.   
0d10: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 2d   }else{.      p-
0d20: 3e 70 44 69 72 74 79 54 61 69 6c 20 3d 20 70 50  >pDirtyTail = pP
0d30: 61 67 65 3b 0a 20 20 20 20 20 20 69 66 28 20 70  age;.      if( p
0d40: 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 29 7b 0a  ->bPurgeable ){.
0d50: 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28 20          assert( 
0d60: 70 2d 3e 65 43 72 65 61 74 65 3d 3d 32 20 29 3b  p->eCreate==2 );
0d70: 0a 20 20 20 20 20 20 20 20 70 2d 3e 65 43 72 65  .        p->eCre
0d80: 61 74 65 20 3d 20 31 3b 0a 20 20 20 20 20 20 7d  ate = 1;.      }
0d90: 0a 20 20 20 20 7d 0a 20 20 20 20 70 2d 3e 70 44  .    }.    p->pD
0da0: 69 72 74 79 20 3d 20 70 50 61 67 65 3b 0a 20 20  irty = pPage;.  
0db0: 20 20 69 66 28 20 21 70 2d 3e 70 53 79 6e 63 65    if( !p->pSynce
0dc0: 64 20 26 26 20 30 3d 3d 28 70 50 61 67 65 2d 3e  d && 0==(pPage->
0dd0: 66 6c 61 67 73 26 50 47 48 44 52 5f 4e 45 45 44  flags&PGHDR_NEED
0de0: 5f 53 59 4e 43 29 20 29 7b 0a 20 20 20 20 20 20  _SYNC) ){.      
0df0: 70 2d 3e 70 53 79 6e 63 65 64 20 3d 20 70 50 61  p->pSynced = pPa
0e00: 67 65 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a  ge;.    }.  }.}.
0e10: 0a 2f 2a 0a 2a 2a 20 57 72 61 70 70 65 72 20 61  ./*.** Wrapper a
0e20: 72 6f 75 6e 64 20 74 68 65 20 70 6c 75 67 67 61  round the plugga
0e30: 62 6c 65 20 63 61 63 68 65 73 20 78 55 6e 70 69  ble caches xUnpi
0e40: 6e 20 6d 65 74 68 6f 64 2e 20 49 66 20 74 68 65  n method. If the
0e50: 20 63 61 63 68 65 20 69 73 0a 2a 2a 20 62 65 69   cache is.** bei
0e60: 6e 67 20 75 73 65 64 20 66 6f 72 20 61 6e 20 69  ng used for an i
0e70: 6e 2d 6d 65 6d 6f 72 79 20 64 61 74 61 62 61 73  n-memory databas
0e80: 65 2c 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  e, this function
0e90: 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a 2a 2f 0a   is a no-op..*/.
0ea0: 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63  static void pcac
0eb0: 68 65 55 6e 70 69 6e 28 50 67 48 64 72 20 2a 70  heUnpin(PgHdr *p
0ec0: 29 7b 0a 20 20 69 66 28 20 70 2d 3e 70 43 61 63  ){.  if( p->pCac
0ed0: 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 29  he->bPurgeable )
0ee0: 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 47 6c 6f  {.    sqlite3Glo
0ef0: 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65  balConfig.pcache
0f00: 32 2e 78 55 6e 70 69 6e 28 70 2d 3e 70 43 61 63  2.xUnpin(p->pCac
0f10: 68 65 2d 3e 70 43 61 63 68 65 2c 20 70 2d 3e 70  he->pCache, p->p
0f20: 50 61 67 65 2c 20 30 29 3b 0a 20 20 7d 0a 7d 0a  Page, 0);.  }.}.
0f30: 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70 75 74 65 20 74  ./*.** Compute t
0f40: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67  he number of pag
0f50: 65 73 20 6f 66 20 63 61 63 68 65 20 72 65 71 75  es of cache requ
0f60: 65 73 74 65 64 2e 20 20 70 2d 3e 73 7a 43 61 63  ested.  p->szCac
0f70: 68 65 20 69 73 20 74 68 65 0a 2a 2a 20 63 61 63  he is the.** cac
0f80: 68 65 20 73 69 7a 65 20 72 65 71 75 65 73 74 65  he size requeste
0f90: 64 20 62 79 20 74 68 65 20 22 50 52 41 47 4d 41  d by the "PRAGMA
0fa0: 20 63 61 63 68 65 5f 73 69 7a 65 22 20 73 74 61   cache_size" sta
0fb0: 74 65 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a 0a 2a 2f  tement..**.**.*/
0fc0: 0a 73 74 61 74 69 63 20 69 6e 74 20 6e 75 6d 62  .static int numb
0fd0: 65 72 4f 66 43 61 63 68 65 50 61 67 65 73 28 50  erOfCachePages(P
0fe0: 43 61 63 68 65 20 2a 70 29 7b 0a 20 20 69 66 28  Cache *p){.  if(
0ff0: 20 70 2d 3e 73 7a 43 61 63 68 65 3e 3d 30 20 29   p->szCache>=0 )
1000: 7b 0a 20 20 20 20 2f 2a 20 49 4d 50 4c 45 4d 45  {.    /* IMPLEME
1010: 4e 54 41 54 49 4f 4e 2d 4f 46 3a 20 52 2d 34 32  NTATION-OF: R-42
1020: 30 35 39 2d 34 37 32 31 31 20 49 66 20 74 68 65  059-47211 If the
1030: 20 61 72 67 75 6d 65 6e 74 20 4e 20 69 73 20 70   argument N is p
1040: 6f 73 69 74 69 76 65 20 74 68 65 6e 20 74 68 65  ositive then the
1050: 0a 20 20 20 20 2a 2a 20 73 75 67 67 65 73 74 65  .    ** suggeste
1060: 64 20 63 61 63 68 65 20 73 69 7a 65 20 69 73 20  d cache size is 
1070: 73 65 74 20 74 6f 20 4e 2e 20 2a 2f 0a 20 20 20  set to N. */.   
1080: 20 72 65 74 75 72 6e 20 70 2d 3e 73 7a 43 61 63   return p->szCac
1090: 68 65 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  he;.  }else{.   
10a0: 20 2f 2a 20 49 4d 50 4c 45 4d 45 4e 54 41 54 49   /* IMPLEMENTATI
10b0: 4f 4e 2d 4f 46 3a 20 52 2d 36 31 34 33 36 2d 31  ON-OF: R-61436-1
10c0: 33 36 33 39 20 49 66 20 74 68 65 20 61 72 67 75  3639 If the argu
10d0: 6d 65 6e 74 20 4e 20 69 73 20 6e 65 67 61 74 69  ment N is negati
10e0: 76 65 2c 20 74 68 65 6e 0a 20 20 20 20 2a 2a 20  ve, then.    ** 
10f0: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 63 61  the number of ca
1100: 63 68 65 20 70 61 67 65 73 20 69 73 20 61 64 6a  che pages is adj
1110: 75 73 74 65 64 20 74 6f 20 75 73 65 20 61 70 70  usted to use app
1120: 72 6f 78 69 6d 61 74 65 6c 79 20 61 62 73 28 4e  roximately abs(N
1130: 2a 31 30 32 34 29 0a 20 20 20 20 2a 2a 20 62 79  *1024).    ** by
1140: 74 65 73 20 6f 66 20 6d 65 6d 6f 72 79 2e 20 2a  tes of memory. *
1150: 2f 0a 20 20 20 20 72 65 74 75 72 6e 20 28 69 6e  /.    return (in
1160: 74 29 28 28 2d 31 30 32 34 2a 28 69 36 34 29 70  t)((-1024*(i64)p
1170: 2d 3e 73 7a 43 61 63 68 65 29 2f 28 70 2d 3e 73  ->szCache)/(p->s
1180: 7a 50 61 67 65 2b 70 2d 3e 73 7a 45 78 74 72 61  zPage+p->szExtra
1190: 29 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 2a 2a 2a  ));.  }.}../****
11a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
11b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
11c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 20  *************** 
11d0: 47 65 6e 65 72 61 6c 20 49 6e 74 65 72 66 61 63  General Interfac
11e0: 65 73 20 2a 2a 2a 2a 2a 2a 0a 2a 2a 0a 2a 2a 20  es ******.**.** 
11f0: 49 6e 69 74 69 61 6c 69 7a 65 20 61 6e 64 20 73  Initialize and s
1200: 68 75 74 64 6f 77 6e 20 74 68 65 20 70 61 67 65  hutdown the page
1210: 20 63 61 63 68 65 20 73 75 62 73 79 73 74 65 6d   cache subsystem
1220: 2e 20 4e 65 69 74 68 65 72 20 6f 66 20 74 68 65  . Neither of the
1230: 73 65 20 0a 2a 2a 20 66 75 6e 63 74 69 6f 6e 73  se .** functions
1240: 20 61 72 65 20 74 68 72 65 61 64 73 61 66 65 2e   are threadsafe.
1250: 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 50  .*/.int sqlite3P
1260: 63 61 63 68 65 49 6e 69 74 69 61 6c 69 7a 65 28  cacheInitialize(
1270: 76 6f 69 64 29 7b 0a 20 20 69 66 28 20 73 71 6c  void){.  if( sql
1280: 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67  ite3GlobalConfig
1290: 2e 70 63 61 63 68 65 32 2e 78 49 6e 69 74 3d 3d  .pcache2.xInit==
12a0: 30 20 29 7b 0a 20 20 20 20 2f 2a 20 49 4d 50 4c  0 ){.    /* IMPL
12b0: 45 4d 45 4e 54 41 54 49 4f 4e 2d 4f 46 3a 20 52  EMENTATION-OF: R
12c0: 2d 32 36 38 30 31 2d 36 34 31 33 37 20 49 66 20  -26801-64137 If 
12d0: 74 68 65 20 78 49 6e 69 74 28 29 20 6d 65 74 68  the xInit() meth
12e0: 6f 64 20 69 73 20 4e 55 4c 4c 2c 20 74 68 65 6e  od is NULL, then
12f0: 20 74 68 65 0a 20 20 20 20 2a 2a 20 62 75 69 6c   the.    ** buil
1300: 74 2d 69 6e 20 64 65 66 61 75 6c 74 20 70 61 67  t-in default pag
1310: 65 20 63 61 63 68 65 20 69 73 20 75 73 65 64 20  e cache is used 
1320: 69 6e 73 74 65 61 64 20 6f 66 20 74 68 65 20 61  instead of the a
1330: 70 70 6c 69 63 61 74 69 6f 6e 20 64 65 66 69 6e  pplication defin
1340: 65 64 0a 20 20 20 20 2a 2a 20 70 61 67 65 20 63  ed.    ** page c
1350: 61 63 68 65 2e 20 2a 2f 0a 20 20 20 20 73 71 6c  ache. */.    sql
1360: 69 74 65 33 50 43 61 63 68 65 53 65 74 44 65 66  ite3PCacheSetDef
1370: 61 75 6c 74 28 29 3b 0a 20 20 7d 0a 20 20 72 65  ault();.  }.  re
1380: 74 75 72 6e 20 73 71 6c 69 74 65 33 47 6c 6f 62  turn sqlite3Glob
1390: 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65 32  alConfig.pcache2
13a0: 2e 78 49 6e 69 74 28 73 71 6c 69 74 65 33 47 6c  .xInit(sqlite3Gl
13b0: 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68  obalConfig.pcach
13c0: 65 32 2e 70 41 72 67 29 3b 0a 7d 0a 76 6f 69 64  e2.pArg);.}.void
13d0: 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 53 68   sqlite3PcacheSh
13e0: 75 74 64 6f 77 6e 28 76 6f 69 64 29 7b 0a 20 20  utdown(void){.  
13f0: 69 66 28 20 73 71 6c 69 74 65 33 47 6c 6f 62 61  if( sqlite3Globa
1400: 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65 32 2e  lConfig.pcache2.
1410: 78 53 68 75 74 64 6f 77 6e 20 29 7b 0a 20 20 20  xShutdown ){.   
1420: 20 2f 2a 20 49 4d 50 4c 45 4d 45 4e 54 41 54 49   /* IMPLEMENTATI
1430: 4f 4e 2d 4f 46 3a 20 52 2d 32 36 30 30 30 2d 35  ON-OF: R-26000-5
1440: 36 35 38 39 20 54 68 65 20 78 53 68 75 74 64 6f  6589 The xShutdo
1450: 77 6e 28 29 20 6d 65 74 68 6f 64 20 6d 61 79 20  wn() method may 
1460: 62 65 20 4e 55 4c 4c 2e 20 2a 2f 0a 20 20 20 20  be NULL. */.    
1470: 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e  sqlite3GlobalCon
1480: 66 69 67 2e 70 63 61 63 68 65 32 2e 78 53 68 75  fig.pcache2.xShu
1490: 74 64 6f 77 6e 28 73 71 6c 69 74 65 33 47 6c 6f  tdown(sqlite3Glo
14a0: 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65  balConfig.pcache
14b0: 32 2e 70 41 72 67 29 3b 0a 20 20 7d 0a 7d 0a 0a  2.pArg);.  }.}..
14c0: 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65  /*.** Return the
14d0: 20 73 69 7a 65 20 69 6e 20 62 79 74 65 73 20 6f   size in bytes o
14e0: 66 20 61 20 50 43 61 63 68 65 20 6f 62 6a 65 63  f a PCache objec
14f0: 74 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  t..*/.int sqlite
1500: 33 50 63 61 63 68 65 53 69 7a 65 28 76 6f 69 64  3PcacheSize(void
1510: 29 7b 20 72 65 74 75 72 6e 20 73 69 7a 65 6f 66  ){ return sizeof
1520: 28 50 43 61 63 68 65 29 3b 20 7d 0a 0a 2f 2a 0a  (PCache); }../*.
1530: 2a 2a 20 43 72 65 61 74 65 20 61 20 6e 65 77 20  ** Create a new 
1540: 50 43 61 63 68 65 20 6f 62 6a 65 63 74 2e 20 53  PCache object. S
1550: 74 6f 72 61 67 65 20 73 70 61 63 65 20 74 6f 20  torage space to 
1560: 68 6f 6c 64 20 74 68 65 20 6f 62 6a 65 63 74 0a  hold the object.
1570: 2a 2a 20 68 61 73 20 61 6c 72 65 61 64 79 20 62  ** has already b
1580: 65 65 6e 20 61 6c 6c 6f 63 61 74 65 64 20 61 6e  een allocated an
1590: 64 20 69 73 20 70 61 73 73 65 64 20 69 6e 20 61  d is passed in a
15a0: 73 20 74 68 65 20 70 20 70 6f 69 6e 74 65 72 2e  s the p pointer.
15b0: 20 0a 2a 2a 20 54 68 65 20 63 61 6c 6c 65 72 20   .** The caller 
15c0: 64 69 73 63 6f 76 65 72 73 20 68 6f 77 20 6d 75  discovers how mu
15d0: 63 68 20 73 70 61 63 65 20 6e 65 65 64 73 20 74  ch space needs t
15e0: 6f 20 62 65 20 61 6c 6c 6f 63 61 74 65 64 20 62  o be allocated b
15f0: 79 20 0a 2a 2a 20 63 61 6c 6c 69 6e 67 20 73 71  y .** calling sq
1600: 6c 69 74 65 33 50 63 61 63 68 65 53 69 7a 65 28  lite3PcacheSize(
1610: 29 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  )..*/.int sqlite
1620: 33 50 63 61 63 68 65 4f 70 65 6e 28 0a 20 20 69  3PcacheOpen(.  i
1630: 6e 74 20 73 7a 50 61 67 65 2c 20 20 20 20 20 20  nt szPage,      
1640: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
1650: 69 7a 65 20 6f 66 20 65 76 65 72 79 20 70 61 67  ize of every pag
1660: 65 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 45 78 74  e */.  int szExt
1670: 72 61 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ra,             
1680: 20 20 20 20 2f 2a 20 45 78 74 72 61 20 73 70 61      /* Extra spa
1690: 63 65 20 61 73 73 6f 63 69 61 74 65 64 20 77 69  ce associated wi
16a0: 74 68 20 65 61 63 68 20 70 61 67 65 20 2a 2f 0a  th each page */.
16b0: 20 20 69 6e 74 20 62 50 75 72 67 65 61 62 6c 65    int bPurgeable
16c0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ,              /
16d0: 2a 20 54 72 75 65 20 69 66 20 70 61 67 65 73 20  * True if pages 
16e0: 61 72 65 20 6f 6e 20 62 61 63 6b 69 6e 67 20 73  are on backing s
16f0: 74 6f 72 65 20 2a 2f 0a 20 20 69 6e 74 20 28 2a  tore */.  int (*
1700: 78 53 74 72 65 73 73 29 28 76 6f 69 64 2a 2c 50  xStress)(void*,P
1710: 67 48 64 72 2a 29 2c 2f 2a 20 43 61 6c 6c 20 74  gHdr*),/* Call t
1720: 6f 20 74 72 79 20 74 6f 20 6d 61 6b 65 20 70 61  o try to make pa
1730: 67 65 73 20 63 6c 65 61 6e 20 2a 2f 0a 20 20 76  ges clean */.  v
1740: 6f 69 64 20 2a 70 53 74 72 65 73 73 2c 20 20 20  oid *pStress,   
1750: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41              /* A
1760: 72 67 75 6d 65 6e 74 20 74 6f 20 78 53 74 72 65  rgument to xStre
1770: 73 73 20 2a 2f 0a 20 20 50 43 61 63 68 65 20 2a  ss */.  PCache *
1780: 70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  p               
1790: 20 20 20 20 20 2f 2a 20 50 72 65 61 6c 6c 6f 63       /* Prealloc
17a0: 61 74 65 64 20 73 70 61 63 65 20 66 6f 72 20 74  ated space for t
17b0: 68 65 20 50 43 61 63 68 65 20 2a 2f 0a 29 7b 0a  he PCache */.){.
17c0: 20 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20 73    memset(p, 0, s
17d0: 69 7a 65 6f 66 28 50 43 61 63 68 65 29 29 3b 0a  izeof(PCache));.
17e0: 20 20 70 2d 3e 73 7a 50 61 67 65 20 3d 20 31 3b    p->szPage = 1;
17f0: 0a 20 20 70 2d 3e 73 7a 45 78 74 72 61 20 3d 20  .  p->szExtra = 
1800: 73 7a 45 78 74 72 61 3b 0a 20 20 70 2d 3e 62 50  szExtra;.  p->bP
1810: 75 72 67 65 61 62 6c 65 20 3d 20 62 50 75 72 67  urgeable = bPurg
1820: 65 61 62 6c 65 3b 0a 20 20 70 2d 3e 65 43 72 65  eable;.  p->eCre
1830: 61 74 65 20 3d 20 32 3b 0a 20 20 70 2d 3e 78 53  ate = 2;.  p->xS
1840: 74 72 65 73 73 20 3d 20 78 53 74 72 65 73 73 3b  tress = xStress;
1850: 0a 20 20 70 2d 3e 70 53 74 72 65 73 73 20 3d 20  .  p->pStress = 
1860: 70 53 74 72 65 73 73 3b 0a 20 20 70 2d 3e 73 7a  pStress;.  p->sz
1870: 43 61 63 68 65 20 3d 20 31 30 30 3b 0a 20 20 72  Cache = 100;.  r
1880: 65 74 75 72 6e 20 73 71 6c 69 74 65 33 50 63 61  eturn sqlite3Pca
1890: 63 68 65 53 65 74 50 61 67 65 53 69 7a 65 28 70  cheSetPageSize(p
18a0: 2c 20 73 7a 50 61 67 65 29 3b 0a 7d 0a 0a 2f 2a  , szPage);.}../*
18b0: 0a 2a 2a 20 43 68 61 6e 67 65 20 74 68 65 20 70  .** Change the p
18c0: 61 67 65 20 73 69 7a 65 20 66 6f 72 20 50 43 61  age size for PCa
18d0: 63 68 65 20 6f 62 6a 65 63 74 2e 20 54 68 65 20  che object. The 
18e0: 63 61 6c 6c 65 72 20 6d 75 73 74 20 65 6e 73 75  caller must ensu
18f0: 72 65 20 74 68 61 74 20 74 68 65 72 65 0a 2a 2a  re that there.**
1900: 20 61 72 65 20 6e 6f 20 6f 75 74 73 74 61 6e 64   are no outstand
1910: 69 6e 67 20 70 61 67 65 20 72 65 66 65 72 65 6e  ing page referen
1920: 63 65 73 20 77 68 65 6e 20 74 68 69 73 20 66 75  ces when this fu
1930: 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64  nction is called
1940: 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33  ..*/.int sqlite3
1950: 50 63 61 63 68 65 53 65 74 50 61 67 65 53 69 7a  PcacheSetPageSiz
1960: 65 28 50 43 61 63 68 65 20 2a 70 43 61 63 68 65  e(PCache *pCache
1970: 2c 20 69 6e 74 20 73 7a 50 61 67 65 29 7b 0a 20  , int szPage){. 
1980: 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65 2d   assert( pCache-
1990: 3e 6e 52 65 66 3d 3d 30 20 26 26 20 70 43 61 63  >nRef==0 && pCac
19a0: 68 65 2d 3e 70 44 69 72 74 79 3d 3d 30 20 29 3b  he->pDirty==0 );
19b0: 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 73  .  if( pCache->s
19c0: 7a 50 61 67 65 20 29 7b 0a 20 20 20 20 73 71 6c  zPage ){.    sql
19d0: 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70 4e 65  ite3_pcache *pNe
19e0: 77 3b 0a 20 20 20 20 70 4e 65 77 20 3d 20 73 71  w;.    pNew = sq
19f0: 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69  lite3GlobalConfi
1a00: 67 2e 70 63 61 63 68 65 32 2e 78 43 72 65 61 74  g.pcache2.xCreat
1a10: 65 28 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  e(.             
1a20: 20 20 20 73 7a 50 61 67 65 2c 20 70 43 61 63 68     szPage, pCach
1a30: 65 2d 3e 73 7a 45 78 74 72 61 20 2b 20 52 4f 55  e->szExtra + ROU
1a40: 4e 44 38 28 73 69 7a 65 6f 66 28 50 67 48 64 72  ND8(sizeof(PgHdr
1a50: 29 29 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  )),.            
1a60: 20 20 20 20 70 43 61 63 68 65 2d 3e 62 50 75 72      pCache->bPur
1a70: 67 65 61 62 6c 65 0a 20 20 20 20 29 3b 0a 20 20  geable.    );.  
1a80: 20 20 69 66 28 20 70 4e 65 77 3d 3d 30 20 29 20    if( pNew==0 ) 
1a90: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f  return SQLITE_NO
1aa0: 4d 45 4d 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  MEM;.    sqlite3
1ab0: 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61  GlobalConfig.pca
1ac0: 63 68 65 32 2e 78 43 61 63 68 65 73 69 7a 65 28  che2.xCachesize(
1ad0: 70 4e 65 77 2c 20 6e 75 6d 62 65 72 4f 66 43 61  pNew, numberOfCa
1ae0: 63 68 65 50 61 67 65 73 28 70 43 61 63 68 65 29  chePages(pCache)
1af0: 29 3b 0a 20 20 20 20 69 66 28 20 70 43 61 63 68  );.    if( pCach
1b00: 65 2d 3e 70 43 61 63 68 65 20 29 7b 0a 20 20 20  e->pCache ){.   
1b10: 20 20 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c     sqlite3Global
1b20: 43 6f 6e 66 69 67 2e 70 63 61 63 68 65 32 2e 78  Config.pcache2.x
1b30: 44 65 73 74 72 6f 79 28 70 43 61 63 68 65 2d 3e  Destroy(pCache->
1b40: 70 43 61 63 68 65 29 3b 0a 20 20 20 20 7d 0a 20  pCache);.    }. 
1b50: 20 20 20 70 43 61 63 68 65 2d 3e 70 43 61 63 68     pCache->pCach
1b60: 65 20 3d 20 70 4e 65 77 3b 0a 20 20 20 20 70 43  e = pNew;.    pC
1b70: 61 63 68 65 2d 3e 73 7a 50 61 67 65 20 3d 20 73  ache->szPage = s
1b80: 7a 50 61 67 65 3b 0a 20 20 7d 0a 20 20 72 65 74  zPage;.  }.  ret
1b90: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
1ba0: 0a 0a 2f 2a 0a 2a 2a 20 54 72 79 20 74 6f 20 6f  ../*.** Try to o
1bb0: 62 74 61 69 6e 20 61 20 70 61 67 65 20 66 72 6f  btain a page fro
1bc0: 6d 20 74 68 65 20 63 61 63 68 65 2e 0a 2a 2a 0a  m the cache..**.
1bd0: 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20  ** This routine 
1be0: 72 65 74 75 72 6e 73 20 61 20 70 6f 69 6e 74 65  returns a pointe
1bf0: 72 20 74 6f 20 61 6e 20 73 71 6c 69 74 65 33 5f  r to an sqlite3_
1c00: 70 63 61 63 68 65 5f 70 61 67 65 20 6f 62 6a 65  pcache_page obje
1c10: 63 74 20 69 66 0a 2a 2a 20 73 75 63 68 20 61 6e  ct if.** such an
1c20: 20 6f 62 6a 65 63 74 20 69 73 20 61 6c 72 65 61   object is alrea
1c30: 64 79 20 69 6e 20 63 61 63 68 65 2c 20 6f 72 20  dy in cache, or 
1c40: 69 66 20 61 20 6e 65 77 20 6f 6e 65 20 69 73 20  if a new one is 
1c50: 63 72 65 61 74 65 64 2e 0a 2a 2a 20 54 68 69 73  created..** This
1c60: 20 72 6f 75 74 69 6e 65 20 72 65 74 75 72 6e 73   routine returns
1c70: 20 61 20 4e 55 4c 4c 20 70 6f 69 6e 74 65 72 20   a NULL pointer 
1c80: 69 66 20 74 68 65 20 6f 62 6a 65 63 74 20 77 61  if the object wa
1c90: 73 20 6e 6f 74 20 69 6e 20 63 61 63 68 65 0a 2a  s not in cache.*
1ca0: 2a 20 61 6e 64 20 63 6f 75 6c 64 20 6e 6f 74 20  * and could not 
1cb0: 62 65 20 63 72 65 61 74 65 64 2e 0a 2a 2a 0a 2a  be created..**.*
1cc0: 2a 20 54 68 65 20 63 72 65 61 74 65 46 6c 61 67  * The createFlag
1cd0: 73 20 73 68 6f 75 6c 64 20 62 65 20 30 20 74 6f  s should be 0 to
1ce0: 20 63 68 65 63 6b 20 66 6f 72 20 65 78 69 73 74   check for exist
1cf0: 69 6e 67 20 70 61 67 65 73 20 61 6e 64 20 73 68  ing pages and sh
1d00: 6f 75 6c 64 0a 2a 2a 20 62 65 20 33 20 28 6e 6f  ould.** be 3 (no
1d10: 74 20 31 2c 20 62 75 74 20 33 29 20 74 6f 20 74  t 1, but 3) to t
1d20: 72 79 20 74 6f 20 63 72 65 61 74 65 20 61 20 6e  ry to create a n
1d30: 65 77 20 70 61 67 65 2e 0a 2a 2a 0a 2a 2a 20 49  ew page..**.** I
1d40: 66 20 74 68 65 20 63 72 65 61 74 65 46 6c 61 67  f the createFlag
1d50: 20 69 73 20 30 2c 20 74 68 65 6e 20 4e 55 4c 4c   is 0, then NULL
1d60: 20 69 73 20 61 6c 77 61 79 73 20 72 65 74 75 72   is always retur
1d70: 6e 65 64 20 69 66 20 74 68 65 20 70 61 67 65 0a  ned if the page.
1d80: 2a 2a 20 69 73 20 6e 6f 74 20 61 6c 72 65 61 64  ** is not alread
1d90: 79 20 69 6e 20 74 68 65 20 63 61 63 68 65 2e 20  y in the cache. 
1da0: 20 49 66 20 63 72 65 61 74 65 46 6c 61 67 20 69   If createFlag i
1db0: 73 20 31 2c 20 74 68 65 6e 20 61 20 6e 65 77 20  s 1, then a new 
1dc0: 70 61 67 65 0a 2a 2a 20 69 73 20 63 72 65 61 74  page.** is creat
1dd0: 65 64 20 6f 6e 6c 79 20 69 66 20 74 68 61 74 20  ed only if that 
1de0: 63 61 6e 20 62 65 20 64 6f 6e 65 20 77 69 74 68  can be done with
1df0: 6f 75 74 20 73 70 69 6c 6c 69 6e 67 20 64 69 72  out spilling dir
1e00: 74 79 20 70 61 67 65 73 0a 2a 2a 20 61 6e 64 20  ty pages.** and 
1e10: 77 69 74 68 6f 75 74 20 65 78 63 65 65 64 69 6e  without exceedin
1e20: 67 20 74 68 65 20 63 61 63 68 65 20 73 69 7a 65  g the cache size
1e30: 20 6c 69 6d 69 74 2e 0a 2a 2a 0a 2a 2a 20 54 68   limit..**.** Th
1e40: 65 20 63 61 6c 6c 65 72 20 6e 65 65 64 73 20 74  e caller needs t
1e50: 6f 20 69 6e 76 6f 6b 65 20 73 71 6c 69 74 65 33  o invoke sqlite3
1e60: 50 63 61 63 68 65 46 65 74 63 68 46 69 6e 69 73  PcacheFetchFinis
1e70: 68 28 29 20 74 6f 20 70 72 6f 70 65 72 6c 79 0a  h() to properly.
1e80: 2a 2a 20 69 6e 69 74 69 61 6c 69 7a 65 20 74 68  ** initialize th
1e90: 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  e sqlite3_pcache
1ea0: 5f 70 61 67 65 20 6f 62 6a 65 63 74 20 61 6e 64  _page object and
1eb0: 20 63 6f 6e 76 65 72 74 20 69 74 20 69 6e 74 6f   convert it into
1ec0: 20 61 0a 2a 2a 20 50 67 48 64 72 20 6f 62 6a 65   a.** PgHdr obje
1ed0: 63 74 2e 20 20 54 68 65 20 73 71 6c 69 74 65 33  ct.  The sqlite3
1ee0: 50 63 61 63 68 65 46 65 74 63 68 28 29 20 61 6e  PcacheFetch() an
1ef0: 64 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 46  d sqlite3PcacheF
1f00: 65 74 63 68 46 69 6e 69 73 68 28 29 0a 2a 2a 20  etchFinish().** 
1f10: 72 6f 75 74 69 6e 65 73 20 61 72 65 20 73 70 6c  routines are spl
1f20: 69 74 20 74 68 69 73 20 77 61 79 20 66 6f 72 20  it this way for 
1f30: 70 65 72 66 6f 72 6d 61 6e 63 65 20 72 65 61 73  performance reas
1f40: 6f 6e 73 2e 20 57 68 65 6e 20 73 65 70 61 72 61  ons. When separa
1f50: 74 65 64 0a 2a 2a 20 74 68 65 79 20 63 61 6e 20  ted.** they can 
1f60: 62 6f 74 68 20 28 75 73 75 61 6c 6c 79 29 20 6f  both (usually) o
1f70: 70 65 72 61 74 65 20 77 69 74 68 6f 75 74 20 68  perate without h
1f80: 61 76 69 6e 67 20 74 6f 20 70 75 73 68 20 76 61  aving to push va
1f90: 6c 75 65 73 20 74 6f 0a 2a 2a 20 74 68 65 20 73  lues to.** the s
1fa0: 74 61 63 6b 20 6f 6e 20 65 6e 74 72 79 20 61 6e  tack on entry an
1fb0: 64 20 70 6f 70 20 74 68 65 6d 20 62 61 63 6b 20  d pop them back 
1fc0: 6f 66 66 20 6f 6e 20 65 78 69 74 2c 20 77 68 69  off on exit, whi
1fd0: 63 68 20 73 61 76 65 73 20 61 0a 2a 2a 20 6c 6f  ch saves a.** lo
1fe0: 74 20 6f 66 20 70 75 73 68 69 6e 67 20 61 6e 64  t of pushing and
1ff0: 20 70 6f 70 70 69 6e 67 2e 0a 2a 2f 0a 73 71 6c   popping..*/.sql
2000: 69 74 65 33 5f 70 63 61 63 68 65 5f 70 61 67 65  ite3_pcache_page
2010: 20 2a 73 71 6c 69 74 65 33 50 63 61 63 68 65 46   *sqlite3PcacheF
2020: 65 74 63 68 28 0a 20 20 50 43 61 63 68 65 20 2a  etch(.  PCache *
2030: 70 43 61 63 68 65 2c 20 20 20 20 20 20 20 2f 2a  pCache,       /*
2040: 20 4f 62 74 61 69 6e 20 74 68 65 20 70 61 67 65   Obtain the page
2050: 20 66 72 6f 6d 20 74 68 69 73 20 63 61 63 68 65   from this cache
2060: 20 2a 2f 0a 20 20 50 67 6e 6f 20 70 67 6e 6f 2c   */.  Pgno pgno,
2070: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
2080: 61 67 65 20 6e 75 6d 62 65 72 20 74 6f 20 6f 62  age number to ob
2090: 74 61 69 6e 20 2a 2f 0a 20 20 69 6e 74 20 63 72  tain */.  int cr
20a0: 65 61 74 65 46 6c 61 67 20 20 20 20 20 20 20 20  eateFlag        
20b0: 2f 2a 20 49 66 20 74 72 75 65 2c 20 63 72 65 61  /* If true, crea
20c0: 74 65 20 70 61 67 65 20 69 66 20 69 74 20 64 6f  te page if it do
20d0: 65 73 20 6e 6f 74 20 65 78 69 73 74 20 61 6c 72  es not exist alr
20e0: 65 61 64 79 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74  eady */.){.  int
20f0: 20 65 43 72 65 61 74 65 3b 0a 0a 20 20 61 73 73   eCreate;..  ass
2100: 65 72 74 28 20 70 43 61 63 68 65 21 3d 30 20 29  ert( pCache!=0 )
2110: 3b 0a 20 20 61 73 73 65 72 74 28 20 70 43 61 63  ;.  assert( pCac
2120: 68 65 2d 3e 70 43 61 63 68 65 21 3d 30 20 29 3b  he->pCache!=0 );
2130: 0a 20 20 61 73 73 65 72 74 28 20 63 72 65 61 74  .  assert( creat
2140: 65 46 6c 61 67 3d 3d 33 20 7c 7c 20 63 72 65 61  eFlag==3 || crea
2150: 74 65 46 6c 61 67 3d 3d 30 20 29 3b 0a 20 20 61  teFlag==0 );.  a
2160: 73 73 65 72 74 28 20 70 67 6e 6f 3e 30 20 29 3b  ssert( pgno>0 );
2170: 0a 0a 20 20 2f 2a 20 65 43 72 65 61 74 65 20 64  ..  /* eCreate d
2180: 65 66 69 6e 65 73 20 77 68 61 74 20 74 6f 20 64  efines what to d
2190: 6f 20 69 66 20 74 68 65 20 70 61 67 65 20 64 6f  o if the page do
21a0: 65 73 20 6e 6f 74 20 65 78 69 73 74 2e 0a 20 20  es not exist..  
21b0: 2a 2a 20 20 20 20 30 20 20 20 20 20 44 6f 20 6e  **    0     Do n
21c0: 6f 74 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e 65  ot allocate a ne
21d0: 77 20 70 61 67 65 2e 20 20 28 63 72 65 61 74 65  w page.  (create
21e0: 46 6c 61 67 3d 3d 30 29 0a 20 20 2a 2a 20 20 20  Flag==0).  **   
21f0: 20 31 20 20 20 20 20 41 6c 6c 6f 63 61 74 65 20   1     Allocate 
2200: 61 20 6e 65 77 20 70 61 67 65 20 69 66 20 64 6f  a new page if do
2210: 69 6e 67 20 73 6f 20 69 73 20 69 6e 65 78 70 65  ing so is inexpe
2220: 6e 73 69 76 65 2e 0a 20 20 2a 2a 20 20 20 20 20  nsive..  **     
2230: 20 20 20 20 20 28 63 72 65 61 74 65 46 6c 61 67       (createFlag
2240: 3d 3d 31 20 41 4e 44 20 62 50 75 72 67 65 61 62  ==1 AND bPurgeab
2250: 6c 65 20 41 4e 44 20 70 44 69 72 74 79 29 0a 20  le AND pDirty). 
2260: 20 2a 2a 20 20 20 20 32 20 20 20 20 20 41 6c 6c   **    2     All
2270: 6f 63 61 74 65 20 61 20 6e 65 77 20 70 61 67 65  ocate a new page
2280: 20 65 76 65 6e 20 69 74 20 64 6f 69 6e 67 20 73   even it doing s
2290: 6f 20 69 73 20 64 69 66 66 69 63 75 6c 74 2e 0a  o is difficult..
22a0: 20 20 2a 2a 20 20 20 20 20 20 20 20 20 20 28 63    **          (c
22b0: 72 65 61 74 65 46 6c 61 67 3d 3d 31 20 41 4e 44  reateFlag==1 AND
22c0: 20 21 28 62 50 75 72 67 65 61 62 6c 65 20 41 4e   !(bPurgeable AN
22d0: 44 20 70 44 69 72 74 79 29 0a 20 20 2a 2f 0a 20  D pDirty).  */. 
22e0: 20 65 43 72 65 61 74 65 20 3d 20 63 72 65 61 74   eCreate = creat
22f0: 65 46 6c 61 67 20 26 20 70 43 61 63 68 65 2d 3e  eFlag & pCache->
2300: 65 43 72 65 61 74 65 3b 0a 20 20 61 73 73 65 72  eCreate;.  asser
2310: 74 28 20 65 43 72 65 61 74 65 3d 3d 30 20 7c 7c  t( eCreate==0 ||
2320: 20 65 43 72 65 61 74 65 3d 3d 31 20 7c 7c 20 65   eCreate==1 || e
2330: 43 72 65 61 74 65 3d 3d 32 20 29 3b 0a 20 20 61  Create==2 );.  a
2340: 73 73 65 72 74 28 20 63 72 65 61 74 65 46 6c 61  ssert( createFla
2350: 67 3d 3d 30 20 7c 7c 20 70 43 61 63 68 65 2d 3e  g==0 || pCache->
2360: 65 43 72 65 61 74 65 3d 3d 65 43 72 65 61 74 65  eCreate==eCreate
2370: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 63 72   );.  assert( cr
2380: 65 61 74 65 46 6c 61 67 3d 3d 30 20 7c 7c 20 65  eateFlag==0 || e
2390: 43 72 65 61 74 65 3d 3d 31 2b 28 21 70 43 61 63  Create==1+(!pCac
23a0: 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 7c 7c  he->bPurgeable||
23b0: 21 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 29  !pCache->pDirty)
23c0: 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c   );.  return sql
23d0: 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67  ite3GlobalConfig
23e0: 2e 70 63 61 63 68 65 32 2e 78 46 65 74 63 68 28  .pcache2.xFetch(
23f0: 70 43 61 63 68 65 2d 3e 70 43 61 63 68 65 2c 20  pCache->pCache, 
2400: 70 67 6e 6f 2c 20 65 43 72 65 61 74 65 29 3b 0a  pgno, eCreate);.
2410: 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 74 68 65 20  }../*.** If the 
2420: 73 71 6c 69 74 65 33 50 63 61 63 68 65 46 65 74  sqlite3PcacheFet
2430: 63 68 28 29 20 72 6f 75 74 69 6e 65 20 69 73 20  ch() routine is 
2440: 75 6e 61 62 6c 65 20 74 6f 20 61 6c 6c 6f 63 61  unable to alloca
2450: 74 65 20 61 20 6e 65 77 0a 2a 2a 20 70 61 67 65  te a new.** page
2460: 20 62 65 63 61 75 73 65 20 6e 65 77 20 63 6c 65   because new cle
2470: 61 6e 20 70 61 67 65 73 20 61 72 65 20 61 76 61  an pages are ava
2480: 69 6c 61 62 6c 65 20 66 6f 72 20 72 65 75 73 65  ilable for reuse
2490: 20 61 6e 64 20 74 68 65 20 63 61 63 68 65 0a 2a   and the cache.*
24a0: 2a 20 73 69 7a 65 20 6c 69 6d 69 74 20 68 61 73  * size limit has
24b0: 20 62 65 65 6e 20 72 65 61 63 68 65 64 2c 20 74   been reached, t
24c0: 68 65 6e 20 74 68 69 73 20 72 6f 75 74 69 6e 65  hen this routine
24d0: 20 63 61 6e 20 62 65 20 69 6e 76 6f 6b 65 64 20   can be invoked 
24e0: 74 6f 20 0a 2a 2a 20 74 72 79 20 68 61 72 64 65  to .** try harde
24f0: 72 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 61 20  r to allocate a 
2500: 70 61 67 65 2e 20 20 54 68 69 73 20 72 6f 75 74  page.  This rout
2510: 69 6e 65 20 6d 69 67 68 74 20 69 6e 76 6f 6b 65  ine might invoke
2520: 20 74 68 65 20 73 74 72 65 73 73 0a 2a 2a 20 63   the stress.** c
2530: 61 6c 6c 62 61 63 6b 20 74 6f 20 73 70 69 6c 6c  allback to spill
2540: 20 64 69 72 74 79 20 70 61 67 65 73 20 74 6f 20   dirty pages to 
2550: 74 68 65 20 6a 6f 75 72 6e 61 6c 2e 20 20 49 74  the journal.  It
2560: 20 77 69 6c 6c 20 74 68 65 6e 20 74 72 79 20 74   will then try t
2570: 6f 0a 2a 2a 20 61 6c 6c 6f 63 61 74 65 20 74 68  o.** allocate th
2580: 65 20 6e 65 77 20 70 61 67 65 20 61 6e 64 20 77  e new page and w
2590: 69 6c 6c 20 6f 6e 6c 79 20 66 61 69 6c 20 74 6f  ill only fail to
25a0: 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20   allocate a new 
25b0: 70 61 67 65 20 6f 6e 0a 2a 2a 20 61 6e 20 4f 4f  page on.** an OO
25c0: 4d 20 65 72 72 6f 72 2e 0a 2a 2a 0a 2a 2a 20 54  M error..**.** T
25d0: 68 69 73 20 72 6f 75 74 69 6e 65 20 73 68 6f 75  his routine shou
25e0: 6c 64 20 62 65 20 69 6e 76 6f 6b 65 64 20 6f 6e  ld be invoked on
25f0: 6c 79 20 61 66 74 65 72 20 73 71 6c 69 74 65 33  ly after sqlite3
2600: 50 63 61 63 68 65 46 65 74 63 68 28 29 20 66 61  PcacheFetch() fa
2610: 69 6c 73 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  ils..*/.int sqli
2620: 74 65 33 50 63 61 63 68 65 46 65 74 63 68 53 74  te3PcacheFetchSt
2630: 72 65 73 73 28 0a 20 20 50 43 61 63 68 65 20 2a  ress(.  PCache *
2640: 70 43 61 63 68 65 2c 20 20 20 20 20 20 20 20 20  pCache,         
2650: 20 20 20 20 20 20 20 20 2f 2a 20 4f 62 74 61 69          /* Obtai
2660: 6e 20 74 68 65 20 70 61 67 65 20 66 72 6f 6d 20  n the page from 
2670: 74 68 69 73 20 63 61 63 68 65 20 2a 2f 0a 20 20  this cache */.  
2680: 50 67 6e 6f 20 70 67 6e 6f 2c 20 20 20 20 20 20  Pgno pgno,      
2690: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
26a0: 2f 2a 20 50 61 67 65 20 6e 75 6d 62 65 72 20 74  /* Page number t
26b0: 6f 20 6f 62 74 61 69 6e 20 2a 2f 0a 20 20 73 71  o obtain */.  sq
26c0: 6c 69 74 65 33 5f 70 63 61 63 68 65 5f 70 61 67  lite3_pcache_pag
26d0: 65 20 2a 2a 70 70 50 61 67 65 20 20 20 20 2f 2a  e **ppPage    /*
26e0: 20 57 72 69 74 65 20 72 65 73 75 6c 74 20 68 65   Write result he
26f0: 72 65 20 2a 2f 0a 29 7b 0a 20 20 50 67 48 64 72  re */.){.  PgHdr
2700: 20 2a 70 50 67 3b 0a 20 20 69 66 28 20 70 43 61   *pPg;.  if( pCa
2710: 63 68 65 2d 3e 65 43 72 65 61 74 65 3d 3d 32 20  che->eCreate==2 
2720: 29 20 72 65 74 75 72 6e 20 30 3b 0a 0a 0a 20 20  ) return 0;...  
2730: 2f 2a 20 46 69 6e 64 20 61 20 64 69 72 74 79 20  /* Find a dirty 
2740: 70 61 67 65 20 74 6f 20 77 72 69 74 65 2d 6f 75  page to write-ou
2750: 74 20 61 6e 64 20 72 65 63 79 63 6c 65 2e 20 46  t and recycle. F
2760: 69 72 73 74 20 74 72 79 20 74 6f 20 66 69 6e 64  irst try to find
2770: 20 61 20 0a 20 20 2a 2a 20 70 61 67 65 20 74 68   a .  ** page th
2780: 61 74 20 64 6f 65 73 20 6e 6f 74 20 72 65 71 75  at does not requ
2790: 69 72 65 20 61 20 6a 6f 75 72 6e 61 6c 2d 73 79  ire a journal-sy
27a0: 6e 63 20 28 6f 6e 65 20 77 69 74 68 20 50 47 48  nc (one with PGH
27b0: 44 52 5f 4e 45 45 44 5f 53 59 4e 43 0a 20 20 2a  DR_NEED_SYNC.  *
27c0: 2a 20 63 6c 65 61 72 65 64 29 2c 20 62 75 74 20  * cleared), but 
27d0: 69 66 20 74 68 61 74 20 69 73 20 6e 6f 74 20 70  if that is not p
27e0: 6f 73 73 69 62 6c 65 20 73 65 74 74 6c 65 20 66  ossible settle f
27f0: 6f 72 20 61 6e 79 20 6f 74 68 65 72 20 0a 20 20  or any other .  
2800: 2a 2a 20 75 6e 72 65 66 65 72 65 6e 63 65 64 20  ** unreferenced 
2810: 64 69 72 74 79 20 70 61 67 65 2e 0a 20 20 2a 2f  dirty page..  */
2820: 0a 20 20 66 6f 72 28 70 50 67 3d 70 43 61 63 68  .  for(pPg=pCach
2830: 65 2d 3e 70 53 79 6e 63 65 64 3b 20 0a 20 20 20  e->pSynced; .   
2840: 20 20 20 70 50 67 20 26 26 20 28 70 50 67 2d 3e     pPg && (pPg->
2850: 6e 52 65 66 20 7c 7c 20 28 70 50 67 2d 3e 66 6c  nRef || (pPg->fl
2860: 61 67 73 26 50 47 48 44 52 5f 4e 45 45 44 5f 53  ags&PGHDR_NEED_S
2870: 59 4e 43 29 29 3b 20 0a 20 20 20 20 20 20 70 50  YNC)); .      pP
2880: 67 3d 70 50 67 2d 3e 70 44 69 72 74 79 50 72 65  g=pPg->pDirtyPre
2890: 76 0a 20 20 29 3b 0a 20 20 70 43 61 63 68 65 2d  v.  );.  pCache-
28a0: 3e 70 53 79 6e 63 65 64 20 3d 20 70 50 67 3b 0a  >pSynced = pPg;.
28b0: 20 20 69 66 28 20 21 70 50 67 20 29 7b 0a 20 20    if( !pPg ){.  
28c0: 20 20 66 6f 72 28 70 50 67 3d 70 43 61 63 68 65    for(pPg=pCache
28d0: 2d 3e 70 44 69 72 74 79 54 61 69 6c 3b 20 70 50  ->pDirtyTail; pP
28e0: 67 20 26 26 20 70 50 67 2d 3e 6e 52 65 66 3b 20  g && pPg->nRef; 
28f0: 70 50 67 3d 70 50 67 2d 3e 70 44 69 72 74 79 50  pPg=pPg->pDirtyP
2900: 72 65 76 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20  rev);.  }.  if( 
2910: 70 50 67 20 29 7b 0a 20 20 20 20 69 6e 74 20 72  pPg ){.    int r
2920: 63 3b 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45  c;.#ifdef SQLITE
2930: 5f 4c 4f 47 5f 43 41 43 48 45 5f 53 50 49 4c 4c  _LOG_CACHE_SPILL
2940: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 6c 6f 67  .    sqlite3_log
2950: 28 53 51 4c 49 54 45 5f 46 55 4c 4c 2c 20 0a 20  (SQLITE_FULL, . 
2960: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 22                 "
2970: 73 70 69 6c 6c 20 70 61 67 65 20 25 64 20 6d 61  spill page %d ma
2980: 6b 69 6e 67 20 72 6f 6f 6d 20 66 6f 72 20 25 64  king room for %d
2990: 20 2d 20 63 61 63 68 65 20 75 73 65 64 3a 20 25   - cache used: %
29a0: 64 2f 25 64 22 2c 0a 20 20 20 20 20 20 20 20 20  d/%d",.         
29b0: 20 20 20 20 20 20 20 70 50 67 2d 3e 70 67 6e 6f         pPg->pgno
29c0: 2c 20 70 67 6e 6f 2c 0a 20 20 20 20 20 20 20 20  , pgno,.        
29d0: 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 47          sqlite3G
29e0: 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63  lobalConfig.pcac
29f0: 68 65 2e 78 50 61 67 65 63 6f 75 6e 74 28 70 43  he.xPagecount(pC
2a00: 61 63 68 65 2d 3e 70 43 61 63 68 65 29 2c 0a 20  ache->pCache),. 
2a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6e                 n
2a20: 75 6d 62 65 72 4f 66 43 61 63 68 65 50 61 67 65  umberOfCachePage
2a30: 73 28 70 43 61 63 68 65 29 29 3b 0a 23 65 6e 64  s(pCache));.#end
2a40: 69 66 0a 20 20 20 20 72 63 20 3d 20 70 43 61 63  if.    rc = pCac
2a50: 68 65 2d 3e 78 53 74 72 65 73 73 28 70 43 61 63  he->xStress(pCac
2a60: 68 65 2d 3e 70 53 74 72 65 73 73 2c 20 70 50 67  he->pStress, pPg
2a70: 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53  );.    if( rc!=S
2a80: 51 4c 49 54 45 5f 4f 4b 20 26 26 20 72 63 21 3d  QLITE_OK && rc!=
2a90: 53 51 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a 20  SQLITE_BUSY ){. 
2aa0: 20 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a       return rc;.
2ab0: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 2a 70 70 50      }.  }.  *ppP
2ac0: 61 67 65 20 3d 20 73 71 6c 69 74 65 33 47 6c 6f  age = sqlite3Glo
2ad0: 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65  balConfig.pcache
2ae0: 32 2e 78 46 65 74 63 68 28 70 43 61 63 68 65 2d  2.xFetch(pCache-
2af0: 3e 70 43 61 63 68 65 2c 20 70 67 6e 6f 2c 20 32  >pCache, pgno, 2
2b00: 29 3b 0a 20 20 72 65 74 75 72 6e 20 2a 70 70 50  );.  return *ppP
2b10: 61 67 65 3d 3d 30 20 3f 20 53 51 4c 49 54 45 5f  age==0 ? SQLITE_
2b20: 4e 4f 4d 45 4d 20 3a 20 53 51 4c 49 54 45 5f 4f  NOMEM : SQLITE_O
2b30: 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  K;.}../*.** This
2b40: 20 69 73 20 61 20 68 65 6c 70 65 72 20 72 6f 75   is a helper rou
2b50: 74 69 6e 65 20 66 6f 72 20 73 71 6c 69 74 65 33  tine for sqlite3
2b60: 50 63 61 63 68 65 46 65 74 63 68 46 69 6e 69 73  PcacheFetchFinis
2b70: 68 28 29 0a 2a 2a 0a 2a 2a 20 49 6e 20 74 68 65  h().**.** In the
2b80: 20 75 6e 63 6f 6d 6d 6f 6e 20 63 61 73 65 20 77   uncommon case w
2b90: 68 65 72 65 20 74 68 65 20 70 61 67 65 20 62 65  here the page be
2ba0: 69 6e 67 20 66 65 74 63 68 65 64 20 68 61 73 20  ing fetched has 
2bb0: 6e 6f 74 20 62 65 65 6e 0a 2a 2a 20 69 6e 69 74  not been.** init
2bc0: 69 61 6c 69 7a 65 64 2c 20 74 68 69 73 20 72 6f  ialized, this ro
2bd0: 75 74 69 6e 65 20 69 73 20 69 6e 76 6f 6b 65 64  utine is invoked
2be0: 20 74 6f 20 64 6f 20 74 68 65 20 69 6e 69 74 69   to do the initi
2bf0: 61 6c 69 7a 61 74 69 6f 6e 2e 0a 2a 2a 20 54 68  alization..** Th
2c00: 69 73 20 72 6f 75 74 69 6e 65 20 69 73 20 62 72  is routine is br
2c10: 6f 6b 65 6e 20 6f 75 74 20 69 6e 74 6f 20 61 20  oken out into a 
2c20: 73 65 70 61 72 61 74 65 20 66 75 6e 63 74 69 6f  separate functio
2c30: 6e 20 73 69 6e 63 65 20 69 74 0a 2a 2a 20 72 65  n since it.** re
2c40: 71 75 69 72 65 73 20 65 78 74 72 61 20 73 74 61  quires extra sta
2c50: 63 6b 20 6d 61 6e 69 70 75 6c 61 74 69 6f 6e 20  ck manipulation 
2c60: 74 68 61 74 20 63 61 6e 20 62 65 20 61 76 6f 69  that can be avoi
2c70: 64 65 64 20 69 6e 20 74 68 65 20 63 6f 6d 6d 6f  ded in the commo
2c80: 6e 0a 2a 2a 20 63 61 73 65 2e 0a 2a 2f 0a 73 74  n.** case..*/.st
2c90: 61 74 69 63 20 53 51 4c 49 54 45 5f 4e 4f 49 4e  atic SQLITE_NOIN
2ca0: 4c 49 4e 45 20 50 67 48 64 72 20 2a 70 63 61 63  LINE PgHdr *pcac
2cb0: 68 65 46 65 74 63 68 46 69 6e 69 73 68 57 69 74  heFetchFinishWit
2cc0: 68 49 6e 69 74 28 0a 20 20 50 43 61 63 68 65 20  hInit(.  PCache 
2cd0: 2a 70 43 61 63 68 65 2c 20 20 20 20 20 20 20 20  *pCache,        
2ce0: 20 20 20 20 20 2f 2a 20 4f 62 74 61 69 6e 20 74       /* Obtain t
2cf0: 68 65 20 70 61 67 65 20 66 72 6f 6d 20 74 68 69  he page from thi
2d00: 73 20 63 61 63 68 65 20 2a 2f 0a 20 20 50 67 6e  s cache */.  Pgn
2d10: 6f 20 70 67 6e 6f 2c 20 20 20 20 20 20 20 20 20  o pgno,         
2d20: 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65           /* Page
2d30: 20 6e 75 6d 62 65 72 20 6f 62 74 61 69 6e 65 64   number obtained
2d40: 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 70 63   */.  sqlite3_pc
2d50: 61 63 68 65 5f 70 61 67 65 20 2a 70 50 61 67 65  ache_page *pPage
2d60: 20 20 2f 2a 20 50 61 67 65 20 6f 62 74 61 69 6e    /* Page obtain
2d70: 65 64 20 62 79 20 70 72 69 6f 72 20 50 63 61 63  ed by prior Pcac
2d80: 68 65 46 65 74 63 68 28 29 20 63 61 6c 6c 20 2a  heFetch() call *
2d90: 2f 0a 29 7b 0a 20 20 50 67 48 64 72 20 2a 70 50  /.){.  PgHdr *pP
2da0: 67 48 64 72 3b 0a 20 20 61 73 73 65 72 74 28 20  gHdr;.  assert( 
2db0: 70 50 61 67 65 21 3d 30 20 29 3b 0a 20 20 70 50  pPage!=0 );.  pP
2dc0: 67 48 64 72 20 3d 20 28 50 67 48 64 72 2a 29 70  gHdr = (PgHdr*)p
2dd0: 50 61 67 65 2d 3e 70 45 78 74 72 61 3b 0a 20 20  Page->pExtra;.  
2de0: 61 73 73 65 72 74 28 20 70 50 67 48 64 72 2d 3e  assert( pPgHdr->
2df0: 70 50 61 67 65 3d 3d 30 20 29 3b 0a 20 6d 65 6d  pPage==0 );. mem
2e00: 73 65 74 28 70 50 67 48 64 72 2c 20 30 2c 20 73  set(pPgHdr, 0, s
2e10: 69 7a 65 6f 66 28 50 67 48 64 72 29 29 3b 0a 20  izeof(PgHdr));. 
2e20: 20 70 50 67 48 64 72 2d 3e 70 50 61 67 65 20 3d   pPgHdr->pPage =
2e30: 20 70 50 61 67 65 3b 0a 20 20 70 50 67 48 64 72   pPage;.  pPgHdr
2e40: 2d 3e 70 44 61 74 61 20 3d 20 70 50 61 67 65 2d  ->pData = pPage-
2e50: 3e 70 42 75 66 3b 0a 20 20 70 50 67 48 64 72 2d  >pBuf;.  pPgHdr-
2e60: 3e 70 45 78 74 72 61 20 3d 20 28 76 6f 69 64 20  >pExtra = (void 
2e70: 2a 29 26 70 50 67 48 64 72 5b 31 5d 3b 0a 20 20  *)&pPgHdr[1];.  
2e80: 6d 65 6d 73 65 74 28 70 50 67 48 64 72 2d 3e 70  memset(pPgHdr->p
2e90: 45 78 74 72 61 2c 20 30 2c 20 70 43 61 63 68 65  Extra, 0, pCache
2ea0: 2d 3e 73 7a 45 78 74 72 61 29 3b 0a 20 20 70 50  ->szExtra);.  pP
2eb0: 67 48 64 72 2d 3e 70 43 61 63 68 65 20 3d 20 70  gHdr->pCache = p
2ec0: 43 61 63 68 65 3b 0a 20 20 70 50 67 48 64 72 2d  Cache;.  pPgHdr-
2ed0: 3e 70 67 6e 6f 20 3d 20 70 67 6e 6f 3b 0a 20 20  >pgno = pgno;.  
2ee0: 70 50 67 48 64 72 2d 3e 66 6c 61 67 73 20 3d 20  pPgHdr->flags = 
2ef0: 50 47 48 44 52 5f 43 4c 45 41 4e 3b 0a 20 20 72  PGHDR_CLEAN;.  r
2f00: 65 74 75 72 6e 20 73 71 6c 69 74 65 33 50 63 61  eturn sqlite3Pca
2f10: 63 68 65 46 65 74 63 68 46 69 6e 69 73 68 28 70  cheFetchFinish(p
2f20: 43 61 63 68 65 2c 70 67 6e 6f 2c 70 50 61 67 65  Cache,pgno,pPage
2f30: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  );.}../*.** This
2f40: 20 72 6f 75 74 69 6e 65 20 63 6f 6e 76 65 72 74   routine convert
2f50: 73 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63  s the sqlite3_pc
2f60: 61 63 68 65 5f 70 61 67 65 20 6f 62 6a 65 63 74  ache_page object
2f70: 20 72 65 74 75 72 6e 65 64 20 62 79 0a 2a 2a 20   returned by.** 
2f80: 73 71 6c 69 74 65 33 50 63 61 63 68 65 46 65 74  sqlite3PcacheFet
2f90: 63 68 28 29 20 69 6e 74 6f 20 61 6e 20 69 6e 69  ch() into an ini
2fa0: 74 69 61 6c 69 7a 65 64 20 50 67 48 64 72 20 6f  tialized PgHdr o
2fb0: 62 6a 65 63 74 2e 20 20 54 68 69 73 20 72 6f 75  bject.  This rou
2fc0: 74 69 6e 65 0a 2a 2a 20 6d 75 73 74 20 62 65 20  tine.** must be 
2fd0: 63 61 6c 6c 65 64 20 61 66 74 65 72 20 73 71 6c  called after sql
2fe0: 69 74 65 33 50 63 61 63 68 65 46 65 74 63 68 28  ite3PcacheFetch(
2ff0: 29 20 69 6e 20 6f 72 64 65 72 20 74 6f 20 67 65  ) in order to ge
3000: 74 20 61 20 75 73 61 62 6c 65 0a 2a 2a 20 72 65  t a usable.** re
3010: 73 75 6c 74 2e 0a 2a 2f 0a 50 67 48 64 72 20 2a  sult..*/.PgHdr *
3020: 73 71 6c 69 74 65 33 50 63 61 63 68 65 46 65 74  sqlite3PcacheFet
3030: 63 68 46 69 6e 69 73 68 28 0a 20 20 50 43 61 63  chFinish(.  PCac
3040: 68 65 20 2a 70 43 61 63 68 65 2c 20 20 20 20 20  he *pCache,     
3050: 20 20 20 20 20 20 20 20 2f 2a 20 4f 62 74 61 69          /* Obtai
3060: 6e 20 74 68 65 20 70 61 67 65 20 66 72 6f 6d 20  n the page from 
3070: 74 68 69 73 20 63 61 63 68 65 20 2a 2f 0a 20 20  this cache */.  
3080: 50 67 6e 6f 20 70 67 6e 6f 2c 20 20 20 20 20 20  Pgno pgno,      
3090: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
30a0: 61 67 65 20 6e 75 6d 62 65 72 20 6f 62 74 61 69  age number obtai
30b0: 6e 65 64 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  ned */.  sqlite3
30c0: 5f 70 63 61 63 68 65 5f 70 61 67 65 20 2a 70 50  _pcache_page *pP
30d0: 61 67 65 20 20 2f 2a 20 50 61 67 65 20 6f 62 74  age  /* Page obt
30e0: 61 69 6e 65 64 20 62 79 20 70 72 69 6f 72 20 50  ained by prior P
30f0: 63 61 63 68 65 46 65 74 63 68 28 29 20 63 61 6c  cacheFetch() cal
3100: 6c 20 2a 2f 0a 29 7b 0a 20 20 50 67 48 64 72 20  l */.){.  PgHdr 
3110: 2a 70 50 67 48 64 72 3b 0a 0a 20 20 69 66 28 20  *pPgHdr;..  if( 
3120: 70 50 61 67 65 3d 3d 30 20 29 20 72 65 74 75 72  pPage==0 ) retur
3130: 6e 20 30 3b 0a 20 20 70 50 67 48 64 72 20 3d 20  n 0;.  pPgHdr = 
3140: 28 50 67 48 64 72 20 2a 29 70 50 61 67 65 2d 3e  (PgHdr *)pPage->
3150: 70 45 78 74 72 61 3b 0a 0a 20 20 69 66 28 20 21  pExtra;..  if( !
3160: 70 50 67 48 64 72 2d 3e 70 50 61 67 65 20 29 7b  pPgHdr->pPage ){
3170: 0a 20 20 20 20 72 65 74 75 72 6e 20 70 63 61 63  .    return pcac
3180: 68 65 46 65 74 63 68 46 69 6e 69 73 68 57 69 74  heFetchFinishWit
3190: 68 49 6e 69 74 28 70 43 61 63 68 65 2c 20 70 67  hInit(pCache, pg
31a0: 6e 6f 2c 20 70 50 61 67 65 29 3b 0a 20 20 7d 0a  no, pPage);.  }.
31b0: 20 20 69 66 28 20 30 3d 3d 70 50 67 48 64 72 2d    if( 0==pPgHdr-
31c0: 3e 6e 52 65 66 20 29 7b 0a 20 20 20 20 70 43 61  >nRef ){.    pCa
31d0: 63 68 65 2d 3e 6e 52 65 66 2b 2b 3b 0a 20 20 7d  che->nRef++;.  }
31e0: 0a 20 20 70 50 67 48 64 72 2d 3e 6e 52 65 66 2b  .  pPgHdr->nRef+
31f0: 2b 3b 0a 20 20 72 65 74 75 72 6e 20 70 50 67 48  +;.  return pPgH
3200: 64 72 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65 63  dr;.}../*.** Dec
3210: 72 65 6d 65 6e 74 20 74 68 65 20 72 65 66 65 72  rement the refer
3220: 65 6e 63 65 20 63 6f 75 6e 74 20 6f 6e 20 61 20  ence count on a 
3230: 70 61 67 65 2e 20 49 66 20 74 68 65 20 70 61 67  page. If the pag
3240: 65 20 69 73 20 63 6c 65 61 6e 20 61 6e 64 20 74  e is clean and t
3250: 68 65 0a 2a 2a 20 72 65 66 65 72 65 6e 63 65 20  he.** reference 
3260: 63 6f 75 6e 74 20 64 72 6f 70 73 20 74 6f 20 30  count drops to 0
3270: 2c 20 74 68 65 6e 20 69 74 20 69 73 20 6d 61 64  , then it is mad
3280: 65 20 65 6c 69 67 69 62 6c 65 20 66 6f 72 20 72  e eligible for r
3290: 65 63 79 63 6c 69 6e 67 2e 0a 2a 2f 0a 76 6f 69  ecycling..*/.voi
32a0: 64 20 53 51 4c 49 54 45 5f 4e 4f 49 4e 4c 49 4e  d SQLITE_NOINLIN
32b0: 45 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 52  E sqlite3PcacheR
32c0: 65 6c 65 61 73 65 28 50 67 48 64 72 20 2a 70 29  elease(PgHdr *p)
32d0: 7b 0a 20 20 61 73 73 65 72 74 28 20 70 2d 3e 6e  {.  assert( p->n
32e0: 52 65 66 3e 30 20 29 3b 0a 20 20 70 2d 3e 6e 52  Ref>0 );.  p->nR
32f0: 65 66 2d 2d 3b 0a 20 20 69 66 28 20 70 2d 3e 6e  ef--;.  if( p->n
3300: 52 65 66 3d 3d 30 20 29 7b 0a 20 20 20 20 70 2d  Ref==0 ){.    p-
3310: 3e 70 43 61 63 68 65 2d 3e 6e 52 65 66 2d 2d 3b  >pCache->nRef--;
3320: 0a 20 20 20 20 69 66 28 20 70 2d 3e 66 6c 61 67  .    if( p->flag
3330: 73 26 50 47 48 44 52 5f 43 4c 45 41 4e 20 29 7b  s&PGHDR_CLEAN ){
3340: 0a 20 20 20 20 20 20 70 63 61 63 68 65 55 6e 70  .      pcacheUnp
3350: 69 6e 28 70 29 3b 0a 20 20 20 20 7d 65 6c 73 65  in(p);.    }else
3360: 20 69 66 28 20 70 2d 3e 70 44 69 72 74 79 50 72   if( p->pDirtyPr
3370: 65 76 21 3d 30 20 29 7b 0a 20 20 20 20 20 20 2f  ev!=0 ){.      /
3380: 2a 20 4d 6f 76 65 20 74 68 65 20 70 61 67 65 20  * Move the page 
3390: 74 6f 20 74 68 65 20 68 65 61 64 20 6f 66 20 74  to the head of t
33a0: 68 65 20 64 69 72 74 79 20 6c 69 73 74 2e 20 2a  he dirty list. *
33b0: 2f 0a 20 20 20 20 20 20 70 63 61 63 68 65 4d 61  /.      pcacheMa
33c0: 6e 61 67 65 44 69 72 74 79 4c 69 73 74 28 70 2c  nageDirtyList(p,
33d0: 20 50 43 41 43 48 45 5f 44 49 52 54 59 4c 49 53   PCACHE_DIRTYLIS
33e0: 54 5f 46 52 4f 4e 54 29 3b 0a 20 20 20 20 7d 0a  T_FRONT);.    }.
33f0: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 63    }.}../*.** Inc
3400: 72 65 61 73 65 20 74 68 65 20 72 65 66 65 72 65  rease the refere
3410: 6e 63 65 20 63 6f 75 6e 74 20 6f 66 20 61 20 73  nce count of a s
3420: 75 70 70 6c 69 65 64 20 70 61 67 65 20 62 79 20  upplied page by 
3430: 31 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74  1..*/.void sqlit
3440: 65 33 50 63 61 63 68 65 52 65 66 28 50 67 48 64  e3PcacheRef(PgHd
3450: 72 20 2a 70 29 7b 0a 20 20 61 73 73 65 72 74 28  r *p){.  assert(
3460: 70 2d 3e 6e 52 65 66 3e 30 29 3b 0a 20 20 70 2d  p->nRef>0);.  p-
3470: 3e 6e 52 65 66 2b 2b 3b 0a 7d 0a 0a 2f 2a 0a 2a  >nRef++;.}../*.*
3480: 2a 20 44 72 6f 70 20 61 20 70 61 67 65 20 66 72  * Drop a page fr
3490: 6f 6d 20 74 68 65 20 63 61 63 68 65 2e 20 54 68  om the cache. Th
34a0: 65 72 65 20 6d 75 73 74 20 62 65 20 65 78 61 63  ere must be exac
34b0: 74 6c 79 20 6f 6e 65 20 72 65 66 65 72 65 6e 63  tly one referenc
34c0: 65 20 74 6f 20 74 68 65 0a 2a 2a 20 70 61 67 65  e to the.** page
34d0: 2e 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  . This function 
34e0: 64 65 6c 65 74 65 73 20 74 68 61 74 20 72 65 66  deletes that ref
34f0: 65 72 65 6e 63 65 2c 20 73 6f 20 61 66 74 65 72  erence, so after
3500: 20 69 74 20 72 65 74 75 72 6e 73 20 74 68 65 0a   it returns the.
3510: 2a 2a 20 70 61 67 65 20 70 6f 69 6e 74 65 64 20  ** page pointed 
3520: 74 6f 20 62 79 20 70 20 69 73 20 69 6e 76 61 6c  to by p is inval
3530: 69 64 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69  id..*/.void sqli
3540: 74 65 33 50 63 61 63 68 65 44 72 6f 70 28 50 67  te3PcacheDrop(Pg
3550: 48 64 72 20 2a 70 29 7b 0a 20 20 61 73 73 65 72  Hdr *p){.  asser
3560: 74 28 20 70 2d 3e 6e 52 65 66 3d 3d 31 20 29 3b  t( p->nRef==1 );
3570: 0a 20 20 69 66 28 20 70 2d 3e 66 6c 61 67 73 26  .  if( p->flags&
3580: 50 47 48 44 52 5f 44 49 52 54 59 20 29 7b 0a 20  PGHDR_DIRTY ){. 
3590: 20 20 20 70 63 61 63 68 65 4d 61 6e 61 67 65 44     pcacheManageD
35a0: 69 72 74 79 4c 69 73 74 28 70 2c 20 50 43 41 43  irtyList(p, PCAC
35b0: 48 45 5f 44 49 52 54 59 4c 49 53 54 5f 52 45 4d  HE_DIRTYLIST_REM
35c0: 4f 56 45 29 3b 0a 20 20 7d 0a 20 20 70 2d 3e 70  OVE);.  }.  p->p
35d0: 43 61 63 68 65 2d 3e 6e 52 65 66 2d 2d 3b 0a 20  Cache->nRef--;. 
35e0: 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f   sqlite3GlobalCo
35f0: 6e 66 69 67 2e 70 63 61 63 68 65 32 2e 78 55 6e  nfig.pcache2.xUn
3600: 70 69 6e 28 70 2d 3e 70 43 61 63 68 65 2d 3e 70  pin(p->pCache->p
3610: 43 61 63 68 65 2c 20 70 2d 3e 70 50 61 67 65 2c  Cache, p->pPage,
3620: 20 31 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61   1);.}../*.** Ma
3630: 6b 65 20 73 75 72 65 20 74 68 65 20 70 61 67 65  ke sure the page
3640: 20 69 73 20 6d 61 72 6b 65 64 20 61 73 20 64 69   is marked as di
3650: 72 74 79 2e 20 49 66 20 69 74 20 69 73 6e 27 74  rty. If it isn't
3660: 20 64 69 72 74 79 20 61 6c 72 65 61 64 79 2c 0a   dirty already,.
3670: 2a 2a 20 6d 61 6b 65 20 69 74 20 73 6f 2e 0a 2a  ** make it so..*
3680: 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63  /.void sqlite3Pc
3690: 61 63 68 65 4d 61 6b 65 44 69 72 74 79 28 50 67  acheMakeDirty(Pg
36a0: 48 64 72 20 2a 70 29 7b 0a 20 20 61 73 73 65 72  Hdr *p){.  asser
36b0: 74 28 20 70 2d 3e 6e 52 65 66 3e 30 20 29 3b 0a  t( p->nRef>0 );.
36c0: 20 20 69 66 28 20 70 2d 3e 66 6c 61 67 73 20 26    if( p->flags &
36d0: 20 28 50 47 48 44 52 5f 43 4c 45 41 4e 7c 50 47   (PGHDR_CLEAN|PG
36e0: 48 44 52 5f 44 4f 4e 54 5f 57 52 49 54 45 29 20  HDR_DONT_WRITE) 
36f0: 29 7b 0a 20 20 20 20 70 2d 3e 66 6c 61 67 73 20  ){.    p->flags 
3700: 26 3d 20 7e 50 47 48 44 52 5f 44 4f 4e 54 5f 57  &= ~PGHDR_DONT_W
3710: 52 49 54 45 3b 0a 20 20 20 20 69 66 28 20 70 2d  RITE;.    if( p-
3720: 3e 66 6c 61 67 73 20 26 20 50 47 48 44 52 5f 43  >flags & PGHDR_C
3730: 4c 45 41 4e 20 29 7b 0a 20 20 20 20 20 20 70 2d  LEAN ){.      p-
3740: 3e 66 6c 61 67 73 20 5e 3d 20 28 50 47 48 44 52  >flags ^= (PGHDR
3750: 5f 44 49 52 54 59 7c 50 47 48 44 52 5f 43 4c 45  _DIRTY|PGHDR_CLE
3760: 41 4e 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72  AN);.      asser
3770: 74 28 20 28 70 2d 3e 66 6c 61 67 73 20 26 20 28  t( (p->flags & (
3780: 50 47 48 44 52 5f 44 49 52 54 59 7c 50 47 48 44  PGHDR_DIRTY|PGHD
3790: 52 5f 43 4c 45 41 4e 29 29 3d 3d 50 47 48 44 52  R_CLEAN))==PGHDR
37a0: 5f 44 49 52 54 59 20 29 3b 0a 20 20 20 20 20 20  _DIRTY );.      
37b0: 70 63 61 63 68 65 4d 61 6e 61 67 65 44 69 72 74  pcacheManageDirt
37c0: 79 4c 69 73 74 28 70 2c 20 50 43 41 43 48 45 5f  yList(p, PCACHE_
37d0: 44 49 52 54 59 4c 49 53 54 5f 41 44 44 29 3b 0a  DIRTYLIST_ADD);.
37e0: 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a      }.  }.}../*.
37f0: 2a 2a 20 4d 61 6b 65 20 73 75 72 65 20 74 68 65  ** Make sure the
3800: 20 70 61 67 65 20 69 73 20 6d 61 72 6b 65 64 20   page is marked 
3810: 61 73 20 63 6c 65 61 6e 2e 20 49 66 20 69 74 20  as clean. If it 
3820: 69 73 6e 27 74 20 63 6c 65 61 6e 20 61 6c 72 65  isn't clean alre
3830: 61 64 79 2c 0a 2a 2a 20 6d 61 6b 65 20 69 74 20  ady,.** make it 
3840: 73 6f 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69  so..*/.void sqli
3850: 74 65 33 50 63 61 63 68 65 4d 61 6b 65 43 6c 65  te3PcacheMakeCle
3860: 61 6e 28 50 67 48 64 72 20 2a 70 29 7b 0a 20 20  an(PgHdr *p){.  
3870: 69 66 28 20 28 70 2d 3e 66 6c 61 67 73 20 26 20  if( (p->flags & 
3880: 50 47 48 44 52 5f 44 49 52 54 59 29 20 29 7b 0a  PGHDR_DIRTY) ){.
3890: 20 20 20 20 61 73 73 65 72 74 28 20 28 70 2d 3e      assert( (p->
38a0: 66 6c 61 67 73 20 26 20 50 47 48 44 52 5f 43 4c  flags & PGHDR_CL
38b0: 45 41 4e 29 3d 3d 30 20 29 3b 0a 20 20 20 20 70  EAN)==0 );.    p
38c0: 63 61 63 68 65 4d 61 6e 61 67 65 44 69 72 74 79  cacheManageDirty
38d0: 4c 69 73 74 28 70 2c 20 50 43 41 43 48 45 5f 44  List(p, PCACHE_D
38e0: 49 52 54 59 4c 49 53 54 5f 52 45 4d 4f 56 45 29  IRTYLIST_REMOVE)
38f0: 3b 0a 20 20 20 20 70 2d 3e 66 6c 61 67 73 20 26  ;.    p->flags &
3900: 3d 20 7e 28 50 47 48 44 52 5f 44 49 52 54 59 7c  = ~(PGHDR_DIRTY|
3910: 50 47 48 44 52 5f 4e 45 45 44 5f 53 59 4e 43 7c  PGHDR_NEED_SYNC|
3920: 50 47 48 44 52 5f 57 52 49 54 45 41 42 4c 45 29  PGHDR_WRITEABLE)
3930: 3b 0a 20 20 20 20 70 2d 3e 66 6c 61 67 73 20 7c  ;.    p->flags |
3940: 3d 20 50 47 48 44 52 5f 43 4c 45 41 4e 3b 0a 20  = PGHDR_CLEAN;. 
3950: 20 20 20 69 66 28 20 70 2d 3e 6e 52 65 66 3d 3d     if( p->nRef==
3960: 30 20 29 7b 0a 20 20 20 20 20 20 70 63 61 63 68  0 ){.      pcach
3970: 65 55 6e 70 69 6e 28 70 29 3b 0a 20 20 20 20 7d  eUnpin(p);.    }
3980: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61  .  }.}../*.** Ma
3990: 6b 65 20 65 76 65 72 79 20 70 61 67 65 20 69 6e  ke every page in
39a0: 20 74 68 65 20 63 61 63 68 65 20 63 6c 65 61 6e   the cache clean
39b0: 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
39c0: 33 50 63 61 63 68 65 43 6c 65 61 6e 41 6c 6c 28  3PcacheCleanAll(
39d0: 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b  PCache *pCache){
39e0: 0a 20 20 50 67 48 64 72 20 2a 70 3b 0a 20 20 77  .  PgHdr *p;.  w
39f0: 68 69 6c 65 28 20 28 70 20 3d 20 70 43 61 63 68  hile( (p = pCach
3a00: 65 2d 3e 70 44 69 72 74 79 29 21 3d 30 20 29 7b  e->pDirty)!=0 ){
3a10: 0a 20 20 20 20 73 71 6c 69 74 65 33 50 63 61 63  .    sqlite3Pcac
3a20: 68 65 4d 61 6b 65 43 6c 65 61 6e 28 70 29 3b 0a  heMakeClean(p);.
3a30: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 65    }.}../*.** Cle
3a40: 61 72 20 74 68 65 20 50 47 48 44 52 5f 4e 45 45  ar the PGHDR_NEE
3a50: 44 5f 53 59 4e 43 20 66 6c 61 67 20 66 72 6f 6d  D_SYNC flag from
3a60: 20 61 6c 6c 20 64 69 72 74 79 20 70 61 67 65 73   all dirty pages
3a70: 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
3a80: 33 50 63 61 63 68 65 43 6c 65 61 72 53 79 6e 63  3PcacheClearSync
3a90: 46 6c 61 67 73 28 50 43 61 63 68 65 20 2a 70 43  Flags(PCache *pC
3aa0: 61 63 68 65 29 7b 0a 20 20 50 67 48 64 72 20 2a  ache){.  PgHdr *
3ab0: 70 3b 0a 20 20 66 6f 72 28 70 3d 70 43 61 63 68  p;.  for(p=pCach
3ac0: 65 2d 3e 70 44 69 72 74 79 3b 20 70 3b 20 70 3d  e->pDirty; p; p=
3ad0: 70 2d 3e 70 44 69 72 74 79 4e 65 78 74 29 7b 0a  p->pDirtyNext){.
3ae0: 20 20 20 20 70 2d 3e 66 6c 61 67 73 20 26 3d 20      p->flags &= 
3af0: 7e 50 47 48 44 52 5f 4e 45 45 44 5f 53 59 4e 43  ~PGHDR_NEED_SYNC
3b00: 3b 0a 20 20 7d 0a 20 20 70 43 61 63 68 65 2d 3e  ;.  }.  pCache->
3b10: 70 53 79 6e 63 65 64 20 3d 20 70 43 61 63 68 65  pSynced = pCache
3b20: 2d 3e 70 44 69 72 74 79 54 61 69 6c 3b 0a 7d 0a  ->pDirtyTail;.}.
3b30: 0a 2f 2a 0a 2a 2a 20 43 68 61 6e 67 65 20 74 68  ./*.** Change th
3b40: 65 20 70 61 67 65 20 6e 75 6d 62 65 72 20 6f 66  e page number of
3b50: 20 70 61 67 65 20 70 20 74 6f 20 6e 65 77 50 67   page p to newPg
3b60: 6e 6f 2e 20 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c  no. .*/.void sql
3b70: 69 74 65 33 50 63 61 63 68 65 4d 6f 76 65 28 50  ite3PcacheMove(P
3b80: 67 48 64 72 20 2a 70 2c 20 50 67 6e 6f 20 6e 65  gHdr *p, Pgno ne
3b90: 77 50 67 6e 6f 29 7b 0a 20 20 50 43 61 63 68 65  wPgno){.  PCache
3ba0: 20 2a 70 43 61 63 68 65 20 3d 20 70 2d 3e 70 43   *pCache = p->pC
3bb0: 61 63 68 65 3b 0a 20 20 61 73 73 65 72 74 28 20  ache;.  assert( 
3bc0: 70 2d 3e 6e 52 65 66 3e 30 20 29 3b 0a 20 20 61  p->nRef>0 );.  a
3bd0: 73 73 65 72 74 28 20 6e 65 77 50 67 6e 6f 3e 30  ssert( newPgno>0
3be0: 20 29 3b 0a 20 20 73 71 6c 69 74 65 33 47 6c 6f   );.  sqlite3Glo
3bf0: 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65  balConfig.pcache
3c00: 32 2e 78 52 65 6b 65 79 28 70 43 61 63 68 65 2d  2.xRekey(pCache-
3c10: 3e 70 43 61 63 68 65 2c 20 70 2d 3e 70 50 61 67  >pCache, p->pPag
3c20: 65 2c 20 70 2d 3e 70 67 6e 6f 2c 6e 65 77 50 67  e, p->pgno,newPg
3c30: 6e 6f 29 3b 0a 20 20 70 2d 3e 70 67 6e 6f 20 3d  no);.  p->pgno =
3c40: 20 6e 65 77 50 67 6e 6f 3b 0a 20 20 69 66 28 20   newPgno;.  if( 
3c50: 28 70 2d 3e 66 6c 61 67 73 26 50 47 48 44 52 5f  (p->flags&PGHDR_
3c60: 44 49 52 54 59 29 20 26 26 20 28 70 2d 3e 66 6c  DIRTY) && (p->fl
3c70: 61 67 73 26 50 47 48 44 52 5f 4e 45 45 44 5f 53  ags&PGHDR_NEED_S
3c80: 59 4e 43 29 20 29 7b 0a 20 20 20 20 70 63 61 63  YNC) ){.    pcac
3c90: 68 65 4d 61 6e 61 67 65 44 69 72 74 79 4c 69 73  heManageDirtyLis
3ca0: 74 28 70 2c 20 50 43 41 43 48 45 5f 44 49 52 54  t(p, PCACHE_DIRT
3cb0: 59 4c 49 53 54 5f 46 52 4f 4e 54 29 3b 0a 20 20  YLIST_FRONT);.  
3cc0: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 72 6f 70 20  }.}../*.** Drop 
3cd0: 65 76 65 72 79 20 63 61 63 68 65 20 65 6e 74 72  every cache entr
3ce0: 79 20 77 68 6f 73 65 20 70 61 67 65 20 6e 75 6d  y whose page num
3cf0: 62 65 72 20 69 73 20 67 72 65 61 74 65 72 20 74  ber is greater t
3d00: 68 61 6e 20 22 70 67 6e 6f 22 2e 20 54 68 65 0a  han "pgno". The.
3d10: 2a 2a 20 63 61 6c 6c 65 72 20 6d 75 73 74 20 65  ** caller must e
3d20: 6e 73 75 72 65 20 74 68 61 74 20 74 68 65 72 65  nsure that there
3d30: 20 61 72 65 20 6e 6f 20 6f 75 74 73 74 61 6e 64   are no outstand
3d40: 69 6e 67 20 72 65 66 65 72 65 6e 63 65 73 20 74  ing references t
3d50: 6f 20 61 6e 79 20 70 61 67 65 73 0a 2a 2a 20 6f  o any pages.** o
3d60: 74 68 65 72 20 74 68 61 6e 20 70 61 67 65 20 31  ther than page 1
3d70: 20 77 69 74 68 20 61 20 70 61 67 65 20 6e 75 6d   with a page num
3d80: 62 65 72 20 67 72 65 61 74 65 72 20 74 68 61 6e  ber greater than
3d90: 20 70 67 6e 6f 2e 0a 2a 2a 0a 2a 2a 20 49 66 20   pgno..**.** If 
3da0: 74 68 65 72 65 20 69 73 20 61 20 72 65 66 65 72  there is a refer
3db0: 65 6e 63 65 20 74 6f 20 70 61 67 65 20 31 20 61  ence to page 1 a
3dc0: 6e 64 20 74 68 65 20 70 67 6e 6f 20 70 61 72 61  nd the pgno para
3dd0: 6d 65 74 65 72 20 70 61 73 73 65 64 20 74 6f 20  meter passed to 
3de0: 74 68 69 73 0a 2a 2a 20 66 75 6e 63 74 69 6f 6e  this.** function
3df0: 20 69 73 20 30 2c 20 74 68 65 6e 20 74 68 65 20   is 0, then the 
3e00: 64 61 74 61 20 61 72 65 61 20 61 73 73 6f 63 69  data area associ
3e10: 61 74 65 64 20 77 69 74 68 20 70 61 67 65 20 31  ated with page 1
3e20: 20 69 73 20 7a 65 72 6f 65 64 2c 20 62 75 74 0a   is zeroed, but.
3e30: 2a 2a 20 74 68 65 20 70 61 67 65 20 6f 62 6a 65  ** the page obje
3e40: 63 74 20 69 73 20 6e 6f 74 20 64 72 6f 70 70 65  ct is not droppe
3e50: 64 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74  d..*/.void sqlit
3e60: 65 33 50 63 61 63 68 65 54 72 75 6e 63 61 74 65  e3PcacheTruncate
3e70: 28 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 2c  (PCache *pCache,
3e80: 20 50 67 6e 6f 20 70 67 6e 6f 29 7b 0a 20 20 69   Pgno pgno){.  i
3e90: 66 28 20 70 43 61 63 68 65 2d 3e 70 43 61 63 68  f( pCache->pCach
3ea0: 65 20 29 7b 0a 20 20 20 20 50 67 48 64 72 20 2a  e ){.    PgHdr *
3eb0: 70 3b 0a 20 20 20 20 50 67 48 64 72 20 2a 70 4e  p;.    PgHdr *pN
3ec0: 65 78 74 3b 0a 20 20 20 20 66 6f 72 28 70 3d 70  ext;.    for(p=p
3ed0: 43 61 63 68 65 2d 3e 70 44 69 72 74 79 3b 20 70  Cache->pDirty; p
3ee0: 3b 20 70 3d 70 4e 65 78 74 29 7b 0a 20 20 20 20  ; p=pNext){.    
3ef0: 20 20 70 4e 65 78 74 20 3d 20 70 2d 3e 70 44 69    pNext = p->pDi
3f00: 72 74 79 4e 65 78 74 3b 0a 20 20 20 20 20 20 2f  rtyNext;.      /
3f10: 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 6e  * This routine n
3f20: 65 76 65 72 20 67 65 74 73 20 63 61 6c 6c 20 77  ever gets call w
3f30: 69 74 68 20 61 20 70 6f 73 69 74 69 76 65 20 70  ith a positive p
3f40: 67 6e 6f 20 65 78 63 65 70 74 20 72 69 67 68 74  gno except right
3f50: 0a 20 20 20 20 20 20 2a 2a 20 61 66 74 65 72 20  .      ** after 
3f60: 73 71 6c 69 74 65 33 50 63 61 63 68 65 43 6c 65  sqlite3PcacheCle
3f70: 61 6e 41 6c 6c 28 29 2e 20 20 53 6f 20 69 66 20  anAll().  So if 
3f80: 74 68 65 72 65 20 61 72 65 20 64 69 72 74 79 20  there are dirty 
3f90: 70 61 67 65 73 2c 0a 20 20 20 20 20 20 2a 2a 20  pages,.      ** 
3fa0: 69 74 20 6d 75 73 74 20 62 65 20 74 68 61 74 20  it must be that 
3fb0: 70 67 6e 6f 3d 3d 30 2e 0a 20 20 20 20 20 20 2a  pgno==0..      *
3fc0: 2f 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20  /.      assert( 
3fd0: 70 2d 3e 70 67 6e 6f 3e 30 20 29 3b 0a 20 20 20  p->pgno>0 );.   
3fe0: 20 20 20 69 66 28 20 41 4c 57 41 59 53 28 70 2d     if( ALWAYS(p-
3ff0: 3e 70 67 6e 6f 3e 70 67 6e 6f 29 20 29 7b 0a 20  >pgno>pgno) ){. 
4000: 20 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70         assert( p
4010: 2d 3e 66 6c 61 67 73 26 50 47 48 44 52 5f 44 49  ->flags&PGHDR_DI
4020: 52 54 59 20 29 3b 0a 20 20 20 20 20 20 20 20 73  RTY );.        s
4030: 71 6c 69 74 65 33 50 63 61 63 68 65 4d 61 6b 65  qlite3PcacheMake
4040: 43 6c 65 61 6e 28 70 29 3b 0a 20 20 20 20 20 20  Clean(p);.      
4050: 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20  }.    }.    if( 
4060: 70 67 6e 6f 3d 3d 30 20 26 26 20 70 43 61 63 68  pgno==0 && pCach
4070: 65 2d 3e 6e 52 65 66 20 29 7b 0a 20 20 20 20 20  e->nRef ){.     
4080: 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 5f   sqlite3_pcache_
4090: 70 61 67 65 20 2a 70 50 61 67 65 31 3b 0a 20 20  page *pPage1;.  
40a0: 20 20 20 20 70 50 61 67 65 31 20 3d 20 73 71 6c      pPage1 = sql
40b0: 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67  ite3GlobalConfig
40c0: 2e 70 63 61 63 68 65 32 2e 78 46 65 74 63 68 28  .pcache2.xFetch(
40d0: 70 43 61 63 68 65 2d 3e 70 43 61 63 68 65 2c 31  pCache->pCache,1
40e0: 2c 30 29 3b 0a 20 20 20 20 20 20 69 66 28 20 41  ,0);.      if( A
40f0: 4c 57 41 59 53 28 70 50 61 67 65 31 29 20 29 7b  LWAYS(pPage1) ){
4100: 20 20 2f 2a 20 50 61 67 65 20 31 20 69 73 20 61    /* Page 1 is a
4110: 6c 77 61 79 73 20 61 76 61 69 6c 61 62 6c 65 20  lways available 
4120: 69 6e 20 63 61 63 68 65 2c 20 62 65 63 61 75 73  in cache, becaus
4130: 65 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e.              
4140: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2a                 *
4150: 2a 20 70 43 61 63 68 65 2d 3e 6e 52 65 66 3e 30  * pCache->nRef>0
4160: 20 2a 2f 0a 20 20 20 20 20 20 20 20 6d 65 6d 73   */.        mems
4170: 65 74 28 70 50 61 67 65 31 2d 3e 70 42 75 66 2c  et(pPage1->pBuf,
4180: 20 30 2c 20 70 43 61 63 68 65 2d 3e 73 7a 50 61   0, pCache->szPa
4190: 67 65 29 3b 0a 20 20 20 20 20 20 20 20 70 67 6e  ge);.        pgn
41a0: 6f 20 3d 20 31 3b 0a 20 20 20 20 20 20 7d 0a 20  o = 1;.      }. 
41b0: 20 20 20 7d 0a 20 20 20 20 73 71 6c 69 74 65 33     }.    sqlite3
41c0: 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61  GlobalConfig.pca
41d0: 63 68 65 32 2e 78 54 72 75 6e 63 61 74 65 28 70  che2.xTruncate(p
41e0: 43 61 63 68 65 2d 3e 70 43 61 63 68 65 2c 20 70  Cache->pCache, p
41f0: 67 6e 6f 2b 31 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f  gno+1);.  }.}../
4200: 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61 20 63 61 63  *.** Close a cac
4210: 68 65 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69  he..*/.void sqli
4220: 74 65 33 50 63 61 63 68 65 43 6c 6f 73 65 28 50  te3PcacheClose(P
4230: 43 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b 0a  Cache *pCache){.
4240: 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65    assert( pCache
4250: 2d 3e 70 43 61 63 68 65 21 3d 30 20 29 3b 0a 20  ->pCache!=0 );. 
4260: 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f   sqlite3GlobalCo
4270: 6e 66 69 67 2e 70 63 61 63 68 65 32 2e 78 44 65  nfig.pcache2.xDe
4280: 73 74 72 6f 79 28 70 43 61 63 68 65 2d 3e 70 43  stroy(pCache->pC
4290: 61 63 68 65 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a  ache);.}../* .**
42a0: 20 44 69 73 63 61 72 64 20 74 68 65 20 63 6f 6e   Discard the con
42b0: 74 65 6e 74 73 20 6f 66 20 74 68 65 20 63 61 63  tents of the cac
42c0: 68 65 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69  he..*/.void sqli
42d0: 74 65 33 50 63 61 63 68 65 43 6c 65 61 72 28 50  te3PcacheClear(P
42e0: 43 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b 0a  Cache *pCache){.
42f0: 20 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 54    sqlite3PcacheT
4300: 72 75 6e 63 61 74 65 28 70 43 61 63 68 65 2c 20  runcate(pCache, 
4310: 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 65 72  0);.}../*.** Mer
4320: 67 65 20 74 77 6f 20 6c 69 73 74 73 20 6f 66 20  ge two lists of 
4330: 70 61 67 65 73 20 63 6f 6e 6e 65 63 74 65 64 20  pages connected 
4340: 62 79 20 70 44 69 72 74 79 20 61 6e 64 20 69 6e  by pDirty and in
4350: 20 70 67 6e 6f 20 6f 72 64 65 72 2e 0a 2a 2a 20   pgno order..** 
4360: 44 6f 20 6e 6f 74 20 62 6f 74 68 20 66 69 78 69  Do not both fixi
4370: 6e 67 20 74 68 65 20 70 44 69 72 74 79 50 72 65  ng the pDirtyPre
4380: 76 20 70 6f 69 6e 74 65 72 73 2e 0a 2a 2f 0a 73  v pointers..*/.s
4390: 74 61 74 69 63 20 50 67 48 64 72 20 2a 70 63 61  tatic PgHdr *pca
43a0: 63 68 65 4d 65 72 67 65 44 69 72 74 79 4c 69 73  cheMergeDirtyLis
43b0: 74 28 50 67 48 64 72 20 2a 70 41 2c 20 50 67 48  t(PgHdr *pA, PgH
43c0: 64 72 20 2a 70 42 29 7b 0a 20 20 50 67 48 64 72  dr *pB){.  PgHdr
43d0: 20 72 65 73 75 6c 74 2c 20 2a 70 54 61 69 6c 3b   result, *pTail;
43e0: 0a 20 20 70 54 61 69 6c 20 3d 20 26 72 65 73 75  .  pTail = &resu
43f0: 6c 74 3b 0a 20 20 77 68 69 6c 65 28 20 70 41 20  lt;.  while( pA 
4400: 26 26 20 70 42 20 29 7b 0a 20 20 20 20 69 66 28  && pB ){.    if(
4410: 20 70 41 2d 3e 70 67 6e 6f 3c 70 42 2d 3e 70 67   pA->pgno<pB->pg
4420: 6e 6f 20 29 7b 0a 20 20 20 20 20 20 70 54 61 69  no ){.      pTai
4430: 6c 2d 3e 70 44 69 72 74 79 20 3d 20 70 41 3b 0a  l->pDirty = pA;.
4440: 20 20 20 20 20 20 70 54 61 69 6c 20 3d 20 70 41        pTail = pA
4450: 3b 0a 20 20 20 20 20 20 70 41 20 3d 20 70 41 2d  ;.      pA = pA-
4460: 3e 70 44 69 72 74 79 3b 0a 20 20 20 20 7d 65 6c  >pDirty;.    }el
4470: 73 65 7b 0a 20 20 20 20 20 20 70 54 61 69 6c 2d  se{.      pTail-
4480: 3e 70 44 69 72 74 79 20 3d 20 70 42 3b 0a 20 20  >pDirty = pB;.  
4490: 20 20 20 20 70 54 61 69 6c 20 3d 20 70 42 3b 0a      pTail = pB;.
44a0: 20 20 20 20 20 20 70 42 20 3d 20 70 42 2d 3e 70        pB = pB->p
44b0: 44 69 72 74 79 3b 0a 20 20 20 20 7d 0a 20 20 7d  Dirty;.    }.  }
44c0: 0a 20 20 69 66 28 20 70 41 20 29 7b 0a 20 20 20  .  if( pA ){.   
44d0: 20 70 54 61 69 6c 2d 3e 70 44 69 72 74 79 20 3d   pTail->pDirty =
44e0: 20 70 41 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28   pA;.  }else if(
44f0: 20 70 42 20 29 7b 0a 20 20 20 20 70 54 61 69 6c   pB ){.    pTail
4500: 2d 3e 70 44 69 72 74 79 20 3d 20 70 42 3b 0a 20  ->pDirty = pB;. 
4510: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70 54 61 69   }else{.    pTai
4520: 6c 2d 3e 70 44 69 72 74 79 20 3d 20 30 3b 0a 20  l->pDirty = 0;. 
4530: 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 65 73 75   }.  return resu
4540: 6c 74 2e 70 44 69 72 74 79 3b 0a 7d 0a 0a 2f 2a  lt.pDirty;.}../*
4550: 0a 2a 2a 20 53 6f 72 74 20 74 68 65 20 6c 69 73  .** Sort the lis
4560: 74 20 6f 66 20 70 61 67 65 73 20 69 6e 20 61 63  t of pages in ac
4570: 63 65 6e 64 69 6e 67 20 6f 72 64 65 72 20 62 79  cending order by
4580: 20 70 67 6e 6f 2e 20 20 50 61 67 65 73 20 61 72   pgno.  Pages ar
4590: 65 0a 2a 2a 20 63 6f 6e 6e 65 63 74 65 64 20 62  e.** connected b
45a0: 79 20 70 44 69 72 74 79 20 70 6f 69 6e 74 65 72  y pDirty pointer
45b0: 73 2e 20 20 54 68 65 20 70 44 69 72 74 79 50 72  s.  The pDirtyPr
45c0: 65 76 20 70 6f 69 6e 74 65 72 73 20 61 72 65 0a  ev pointers are.
45d0: 2a 2a 20 63 6f 72 72 75 70 74 65 64 20 62 79 20  ** corrupted by 
45e0: 74 68 69 73 20 73 6f 72 74 2e 0a 2a 2a 0a 2a 2a  this sort..**.**
45f0: 20 53 69 6e 63 65 20 74 68 65 72 65 20 63 61 6e   Since there can
4600: 6e 6f 74 20 62 65 20 6d 6f 72 65 20 74 68 61 6e  not be more than
4610: 20 32 5e 33 31 20 64 69 73 74 69 6e 63 74 20 70   2^31 distinct p
4620: 61 67 65 73 20 69 6e 20 61 20 64 61 74 61 62 61  ages in a databa
4630: 73 65 2c 0a 2a 2a 20 74 68 65 72 65 20 63 61 6e  se,.** there can
4640: 6e 6f 74 20 62 65 20 6d 6f 72 65 20 74 68 61 6e  not be more than
4650: 20 33 31 20 62 75 63 6b 65 74 73 20 72 65 71 75   31 buckets requ
4660: 69 72 65 64 20 62 79 20 74 68 65 20 6d 65 72 67  ired by the merg
4670: 65 20 73 6f 72 74 65 72 2e 0a 2a 2a 20 4f 6e 65  e sorter..** One
4680: 20 65 78 74 72 61 20 62 75 63 6b 65 74 20 69 73   extra bucket is
4690: 20 61 64 64 65 64 20 74 6f 20 63 61 74 63 68 20   added to catch 
46a0: 6f 76 65 72 66 6c 6f 77 20 69 6e 20 63 61 73 65  overflow in case
46b0: 20 73 6f 6d 65 74 68 69 6e 67 0a 2a 2a 20 65 76   something.** ev
46c0: 65 72 20 63 68 61 6e 67 65 73 20 74 6f 20 6d 61  er changes to ma
46d0: 6b 65 20 74 68 65 20 70 72 65 76 69 6f 75 73 20  ke the previous 
46e0: 73 65 6e 74 65 6e 63 65 20 69 6e 63 6f 72 72 65  sentence incorre
46f0: 63 74 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 4e  ct..*/.#define N
4700: 5f 53 4f 52 54 5f 42 55 43 4b 45 54 20 20 33 32  _SORT_BUCKET  32
4710: 0a 73 74 61 74 69 63 20 50 67 48 64 72 20 2a 70  .static PgHdr *p
4720: 63 61 63 68 65 53 6f 72 74 44 69 72 74 79 4c 69  cacheSortDirtyLi
4730: 73 74 28 50 67 48 64 72 20 2a 70 49 6e 29 7b 0a  st(PgHdr *pIn){.
4740: 20 20 50 67 48 64 72 20 2a 61 5b 4e 5f 53 4f 52    PgHdr *a[N_SOR
4750: 54 5f 42 55 43 4b 45 54 5d 2c 20 2a 70 3b 0a 20  T_BUCKET], *p;. 
4760: 20 69 6e 74 20 69 3b 0a 20 20 6d 65 6d 73 65 74   int i;.  memset
4770: 28 61 2c 20 30 2c 20 73 69 7a 65 6f 66 28 61 29  (a, 0, sizeof(a)
4780: 29 3b 0a 20 20 77 68 69 6c 65 28 20 70 49 6e 20  );.  while( pIn 
4790: 29 7b 0a 20 20 20 20 70 20 3d 20 70 49 6e 3b 0a  ){.    p = pIn;.
47a0: 20 20 20 20 70 49 6e 20 3d 20 70 2d 3e 70 44 69      pIn = p->pDi
47b0: 72 74 79 3b 0a 20 20 20 20 70 2d 3e 70 44 69 72  rty;.    p->pDir
47c0: 74 79 20 3d 20 30 3b 0a 20 20 20 20 66 6f 72 28  ty = 0;.    for(
47d0: 69 3d 30 3b 20 41 4c 57 41 59 53 28 69 3c 4e 5f  i=0; ALWAYS(i<N_
47e0: 53 4f 52 54 5f 42 55 43 4b 45 54 2d 31 29 3b 20  SORT_BUCKET-1); 
47f0: 69 2b 2b 29 7b 0a 20 20 20 20 20 20 69 66 28 20  i++){.      if( 
4800: 61 5b 69 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 20  a[i]==0 ){.     
4810: 20 20 20 61 5b 69 5d 20 3d 20 70 3b 0a 20 20 20     a[i] = p;.   
4820: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
4830: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20    }else{.       
4840: 20 70 20 3d 20 70 63 61 63 68 65 4d 65 72 67 65   p = pcacheMerge
4850: 44 69 72 74 79 4c 69 73 74 28 61 5b 69 5d 2c 20  DirtyList(a[i], 
4860: 70 29 3b 0a 20 20 20 20 20 20 20 20 61 5b 69 5d  p);.        a[i]
4870: 20 3d 20 30 3b 0a 20 20 20 20 20 20 7d 0a 20 20   = 0;.      }.  
4880: 20 20 7d 0a 20 20 20 20 69 66 28 20 4e 45 56 45    }.    if( NEVE
4890: 52 28 69 3d 3d 4e 5f 53 4f 52 54 5f 42 55 43 4b  R(i==N_SORT_BUCK
48a0: 45 54 2d 31 29 20 29 7b 0a 20 20 20 20 20 20 2f  ET-1) ){.      /
48b0: 2a 20 54 6f 20 67 65 74 20 68 65 72 65 2c 20 74  * To get here, t
48c0: 68 65 72 65 20 6e 65 65 64 20 74 6f 20 62 65 20  here need to be 
48d0: 32 5e 28 4e 5f 53 4f 52 54 5f 42 55 43 4b 45 54  2^(N_SORT_BUCKET
48e0: 29 20 65 6c 65 6d 65 6e 74 73 20 69 6e 0a 20 20  ) elements in.  
48f0: 20 20 20 20 2a 2a 20 74 68 65 20 69 6e 70 75 74      ** the input
4900: 20 6c 69 73 74 2e 20 20 42 75 74 20 74 68 61 74   list.  But that
4910: 20 69 73 20 69 6d 70 6f 73 73 69 62 6c 65 2e 0a   is impossible..
4920: 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 20 61        */.      a
4930: 5b 69 5d 20 3d 20 70 63 61 63 68 65 4d 65 72 67  [i] = pcacheMerg
4940: 65 44 69 72 74 79 4c 69 73 74 28 61 5b 69 5d 2c  eDirtyList(a[i],
4950: 20 70 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20   p);.    }.  }. 
4960: 20 70 20 3d 20 61 5b 30 5d 3b 0a 20 20 66 6f 72   p = a[0];.  for
4970: 28 69 3d 31 3b 20 69 3c 4e 5f 53 4f 52 54 5f 42  (i=1; i<N_SORT_B
4980: 55 43 4b 45 54 3b 20 69 2b 2b 29 7b 0a 20 20 20  UCKET; i++){.   
4990: 20 70 20 3d 20 70 63 61 63 68 65 4d 65 72 67 65   p = pcacheMerge
49a0: 44 69 72 74 79 4c 69 73 74 28 70 2c 20 61 5b 69  DirtyList(p, a[i
49b0: 5d 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  ]);.  }.  return
49c0: 20 70 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74   p;.}../*.** Ret
49d0: 75 72 6e 20 61 20 6c 69 73 74 20 6f 66 20 61 6c  urn a list of al
49e0: 6c 20 64 69 72 74 79 20 70 61 67 65 73 20 69 6e  l dirty pages in
49f0: 20 74 68 65 20 63 61 63 68 65 2c 20 73 6f 72 74   the cache, sort
4a00: 65 64 20 62 79 20 70 61 67 65 20 6e 75 6d 62 65  ed by page numbe
4a10: 72 2e 0a 2a 2f 0a 50 67 48 64 72 20 2a 73 71 6c  r..*/.PgHdr *sql
4a20: 69 74 65 33 50 63 61 63 68 65 44 69 72 74 79 4c  ite3PcacheDirtyL
4a30: 69 73 74 28 50 43 61 63 68 65 20 2a 70 43 61 63  ist(PCache *pCac
4a40: 68 65 29 7b 0a 20 20 50 67 48 64 72 20 2a 70 3b  he){.  PgHdr *p;
4a50: 0a 20 20 66 6f 72 28 70 3d 70 43 61 63 68 65 2d  .  for(p=pCache-
4a60: 3e 70 44 69 72 74 79 3b 20 70 3b 20 70 3d 70 2d  >pDirty; p; p=p-
4a70: 3e 70 44 69 72 74 79 4e 65 78 74 29 7b 0a 20 20  >pDirtyNext){.  
4a80: 20 20 70 2d 3e 70 44 69 72 74 79 20 3d 20 70 2d    p->pDirty = p-
4a90: 3e 70 44 69 72 74 79 4e 65 78 74 3b 0a 20 20 7d  >pDirtyNext;.  }
4aa0: 0a 20 20 72 65 74 75 72 6e 20 70 63 61 63 68 65  .  return pcache
4ab0: 53 6f 72 74 44 69 72 74 79 4c 69 73 74 28 70 43  SortDirtyList(pC
4ac0: 61 63 68 65 2d 3e 70 44 69 72 74 79 29 3b 0a 7d  ache->pDirty);.}
4ad0: 0a 0a 2f 2a 20 0a 2a 2a 20 52 65 74 75 72 6e 20  ../* .** Return 
4ae0: 74 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72  the total number
4af0: 20 6f 66 20 72 65 66 65 72 65 6e 63 65 64 20 70   of referenced p
4b00: 61 67 65 73 20 68 65 6c 64 20 62 79 20 74 68 65  ages held by the
4b10: 20 63 61 63 68 65 2e 0a 2a 2f 0a 69 6e 74 20 73   cache..*/.int s
4b20: 71 6c 69 74 65 33 50 63 61 63 68 65 52 65 66 43  qlite3PcacheRefC
4b30: 6f 75 6e 74 28 50 43 61 63 68 65 20 2a 70 43 61  ount(PCache *pCa
4b40: 63 68 65 29 7b 0a 20 20 72 65 74 75 72 6e 20 70  che){.  return p
4b50: 43 61 63 68 65 2d 3e 6e 52 65 66 3b 0a 7d 0a 0a  Cache->nRef;.}..
4b60: 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65  /*.** Return the
4b70: 20 6e 75 6d 62 65 72 20 6f 66 20 72 65 66 65 72   number of refer
4b80: 65 6e 63 65 73 20 74 6f 20 74 68 65 20 70 61 67  ences to the pag
4b90: 65 20 73 75 70 70 6c 69 65 64 20 61 73 20 61 6e  e supplied as an
4ba0: 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2f 0a 69 6e   argument..*/.in
4bb0: 74 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 50  t sqlite3PcacheP
4bc0: 61 67 65 52 65 66 63 6f 75 6e 74 28 50 67 48 64  ageRefcount(PgHd
4bd0: 72 20 2a 70 29 7b 0a 20 20 72 65 74 75 72 6e 20  r *p){.  return 
4be0: 70 2d 3e 6e 52 65 66 3b 0a 7d 0a 0a 2f 2a 20 0a  p->nRef;.}../* .
4bf0: 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 74 6f  ** Return the to
4c00: 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 70 61  tal number of pa
4c10: 67 65 73 20 69 6e 20 74 68 65 20 63 61 63 68 65  ges in the cache
4c20: 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33  ..*/.int sqlite3
4c30: 50 63 61 63 68 65 50 61 67 65 63 6f 75 6e 74 28  PcachePagecount(
4c40: 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b  PCache *pCache){
4c50: 0a 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68  .  assert( pCach
4c60: 65 2d 3e 70 43 61 63 68 65 21 3d 30 20 29 3b 0a  e->pCache!=0 );.
4c70: 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33    return sqlite3
4c80: 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61  GlobalConfig.pca
4c90: 63 68 65 32 2e 78 50 61 67 65 63 6f 75 6e 74 28  che2.xPagecount(
4ca0: 70 43 61 63 68 65 2d 3e 70 43 61 63 68 65 29 3b  pCache->pCache);
4cb0: 0a 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54  .}..#ifdef SQLIT
4cc0: 45 5f 54 45 53 54 0a 2f 2a 0a 2a 2a 20 47 65 74  E_TEST./*.** Get
4cd0: 20 74 68 65 20 73 75 67 67 65 73 74 65 64 20 63   the suggested c
4ce0: 61 63 68 65 2d 73 69 7a 65 20 76 61 6c 75 65 2e  ache-size value.
4cf0: 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 50  .*/.int sqlite3P
4d00: 63 61 63 68 65 47 65 74 43 61 63 68 65 73 69 7a  cacheGetCachesiz
4d10: 65 28 50 43 61 63 68 65 20 2a 70 43 61 63 68 65  e(PCache *pCache
4d20: 29 7b 0a 20 20 72 65 74 75 72 6e 20 6e 75 6d 62  ){.  return numb
4d30: 65 72 4f 66 43 61 63 68 65 50 61 67 65 73 28 70  erOfCachePages(p
4d40: 43 61 63 68 65 29 3b 0a 7d 0a 23 65 6e 64 69 66  Cache);.}.#endif
4d50: 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20 74 68 65 20  ../*.** Set the 
4d60: 73 75 67 67 65 73 74 65 64 20 63 61 63 68 65 2d  suggested cache-
4d70: 73 69 7a 65 20 76 61 6c 75 65 2e 0a 2a 2f 0a 76  size value..*/.v
4d80: 6f 69 64 20 73 71 6c 69 74 65 33 50 63 61 63 68  oid sqlite3Pcach
4d90: 65 53 65 74 43 61 63 68 65 73 69 7a 65 28 50 43  eSetCachesize(PC
4da0: 61 63 68 65 20 2a 70 43 61 63 68 65 2c 20 69 6e  ache *pCache, in
4db0: 74 20 6d 78 50 61 67 65 29 7b 0a 20 20 61 73 73  t mxPage){.  ass
4dc0: 65 72 74 28 20 70 43 61 63 68 65 2d 3e 70 43 61  ert( pCache->pCa
4dd0: 63 68 65 21 3d 30 20 29 3b 0a 20 20 70 43 61 63  che!=0 );.  pCac
4de0: 68 65 2d 3e 73 7a 43 61 63 68 65 20 3d 20 6d 78  he->szCache = mx
4df0: 50 61 67 65 3b 0a 20 20 73 71 6c 69 74 65 33 47  Page;.  sqlite3G
4e00: 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63  lobalConfig.pcac
4e10: 68 65 32 2e 78 43 61 63 68 65 73 69 7a 65 28 70  he2.xCachesize(p
4e20: 43 61 63 68 65 2d 3e 70 43 61 63 68 65 2c 0a 20  Cache->pCache,. 
4e30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4e40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4e50: 20 20 20 20 20 20 20 20 6e 75 6d 62 65 72 4f 66          numberOf
4e60: 43 61 63 68 65 50 61 67 65 73 28 70 43 61 63 68  CachePages(pCach
4e70: 65 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72  e));.}../*.** Fr
4e80: 65 65 20 75 70 20 61 73 20 6d 75 63 68 20 6d 65  ee up as much me
4e90: 6d 6f 72 79 20 61 73 20 70 6f 73 73 69 62 6c 65  mory as possible
4ea0: 20 66 72 6f 6d 20 74 68 65 20 70 61 67 65 20 63   from the page c
4eb0: 61 63 68 65 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71  ache..*/.void sq
4ec0: 6c 69 74 65 33 50 63 61 63 68 65 53 68 72 69 6e  lite3PcacheShrin
4ed0: 6b 28 50 43 61 63 68 65 20 2a 70 43 61 63 68 65  k(PCache *pCache
4ee0: 29 7b 0a 20 20 61 73 73 65 72 74 28 20 70 43 61  ){.  assert( pCa
4ef0: 63 68 65 2d 3e 70 43 61 63 68 65 21 3d 30 20 29  che->pCache!=0 )
4f00: 3b 0a 20 20 73 71 6c 69 74 65 33 47 6c 6f 62 61  ;.  sqlite3Globa
4f10: 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65 32 2e  lConfig.pcache2.
4f20: 78 53 68 72 69 6e 6b 28 70 43 61 63 68 65 2d 3e  xShrink(pCache->
4f30: 70 43 61 63 68 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  pCache);.}../*.*
4f40: 2a 20 52 65 74 75 72 6e 20 74 68 65 20 73 69 7a  * Return the siz
4f50: 65 20 6f 66 20 74 68 65 20 68 65 61 64 65 72 20  e of the header 
4f60: 61 64 64 65 64 20 62 79 20 74 68 69 73 20 6d 69  added by this mi
4f70: 64 64 6c 65 77 61 72 65 20 6c 61 79 65 72 0a 2a  ddleware layer.*
4f80: 2a 20 69 6e 20 74 68 65 20 70 61 67 65 2d 63 61  * in the page-ca
4f90: 63 68 65 20 68 69 65 72 61 72 63 68 79 2e 0a 2a  che hierarchy..*
4fa0: 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 48 65 61  /.int sqlite3Hea
4fb0: 64 65 72 53 69 7a 65 50 63 61 63 68 65 28 76 6f  derSizePcache(vo
4fc0: 69 64 29 7b 20 72 65 74 75 72 6e 20 52 4f 55 4e  id){ return ROUN
4fd0: 44 38 28 73 69 7a 65 6f 66 28 50 67 48 64 72 29  D8(sizeof(PgHdr)
4fe0: 29 3b 20 7d 0a 0a 0a 23 69 66 20 64 65 66 69 6e  ); }...#if defin
4ff0: 65 64 28 53 51 4c 49 54 45 5f 43 48 45 43 4b 5f  ed(SQLITE_CHECK_
5000: 50 41 47 45 53 29 20 7c 7c 20 64 65 66 69 6e 65  PAGES) || define
5010: 64 28 53 51 4c 49 54 45 5f 44 45 42 55 47 29 0a  d(SQLITE_DEBUG).
5020: 2f 2a 0a 2a 2a 20 46 6f 72 20 61 6c 6c 20 64 69  /*.** For all di
5030: 72 74 79 20 70 61 67 65 73 20 63 75 72 72 65 6e  rty pages curren
5040: 74 6c 79 20 69 6e 20 74 68 65 20 63 61 63 68 65  tly in the cache
5050: 2c 20 69 6e 76 6f 6b 65 20 74 68 65 20 73 70 65  , invoke the spe
5060: 63 69 66 69 65 64 0a 2a 2a 20 63 61 6c 6c 62 61  cified.** callba
5070: 63 6b 2e 20 54 68 69 73 20 69 73 20 6f 6e 6c 79  ck. This is only
5080: 20 75 73 65 64 20 69 66 20 74 68 65 20 53 51 4c   used if the SQL
5090: 49 54 45 5f 43 48 45 43 4b 5f 50 41 47 45 53 20  ITE_CHECK_PAGES 
50a0: 6d 61 63 72 6f 20 69 73 0a 2a 2a 20 64 65 66 69  macro is.** defi
50b0: 6e 65 64 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c  ned..*/.void sql
50c0: 69 74 65 33 50 63 61 63 68 65 49 74 65 72 61 74  ite3PcacheIterat
50d0: 65 44 69 72 74 79 28 50 43 61 63 68 65 20 2a 70  eDirty(PCache *p
50e0: 43 61 63 68 65 2c 20 76 6f 69 64 20 28 2a 78 49  Cache, void (*xI
50f0: 74 65 72 29 28 50 67 48 64 72 20 2a 29 29 7b 0a  ter)(PgHdr *)){.
5100: 20 20 50 67 48 64 72 20 2a 70 44 69 72 74 79 3b    PgHdr *pDirty;
5110: 0a 20 20 66 6f 72 28 70 44 69 72 74 79 3d 70 43  .  for(pDirty=pC
5120: 61 63 68 65 2d 3e 70 44 69 72 74 79 3b 20 70 44  ache->pDirty; pD
5130: 69 72 74 79 3b 20 70 44 69 72 74 79 3d 70 44 69  irty; pDirty=pDi
5140: 72 74 79 2d 3e 70 44 69 72 74 79 4e 65 78 74 29  rty->pDirtyNext)
5150: 7b 0a 20 20 20 20 78 49 74 65 72 28 70 44 69 72  {.    xIter(pDir
5160: 74 79 29 3b 0a 20 20 7d 0a 7d 0a 23 65 6e 64 69  ty);.  }.}.#endi
5170: 66 0a                                            f.