/ Hex Artifact Content
Login

Artifact d7e1dd55d9ecb78ede74a3a985a85dea02a01d24:


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 2a 0a 2a 2a 20 70 44 69 72  ture..**.** pDir
0200: 74 79 2c 20 70 44 69 72 74 79 54 61 69 6c 2c 20  ty, pDirtyTail, 
0210: 70 53 79 6e 63 65 64 3a 0a 2a 2a 20 20 20 41 6c  pSynced:.**   Al
0220: 6c 20 64 69 72 74 79 20 70 61 67 65 73 20 61 72  l dirty pages ar
0230: 65 20 6c 69 6e 6b 65 64 20 69 6e 74 6f 20 74 68  e linked into th
0240: 65 20 64 6f 75 62 6c 79 20 6c 69 6e 6b 65 64 20  e doubly linked 
0250: 6c 69 73 74 20 75 73 69 6e 67 0a 2a 2a 20 20 20  list using.**   
0260: 50 67 48 64 72 2e 70 44 69 72 74 79 4e 65 78 74  PgHdr.pDirtyNext
0270: 20 61 6e 64 20 70 44 69 72 74 79 50 72 65 76 2e   and pDirtyPrev.
0280: 20 54 68 65 20 6c 69 73 74 20 69 73 20 6d 61 69   The list is mai
0290: 6e 74 61 69 6e 65 64 20 69 6e 20 4c 52 55 20 6f  ntained in LRU o
02a0: 72 64 65 72 0a 2a 2a 20 20 20 73 75 63 68 20 74  rder.**   such t
02b0: 68 61 74 20 70 20 77 61 73 20 61 64 64 65 64 20  hat p was added 
02c0: 74 6f 20 74 68 65 20 6c 69 73 74 20 6d 6f 72 65  to the list more
02d0: 20 72 65 63 65 6e 74 6c 79 20 74 68 61 6e 20 70   recently than p
02e0: 2d 3e 70 44 69 72 74 79 4e 65 78 74 2e 0a 2a 2a  ->pDirtyNext..**
02f0: 20 20 20 50 43 61 63 68 65 2e 70 44 69 72 74 79     PCache.pDirty
0300: 20 70 6f 69 6e 74 73 20 74 6f 20 74 68 65 20 66   points to the f
0310: 69 72 73 74 20 28 6e 65 77 65 73 74 29 20 65 6c  irst (newest) el
0320: 65 6d 65 6e 74 20 69 6e 20 74 68 65 20 6c 69 73  ement in the lis
0330: 74 20 61 6e 64 0a 2a 2a 20 20 20 70 44 69 72 74  t and.**   pDirt
0340: 79 54 61 69 6c 20 74 6f 20 74 68 65 20 6c 61 73  yTail to the las
0350: 74 20 28 6f 6c 64 65 73 74 29 2e 0a 2a 2a 0a 2a  t (oldest)..**.*
0360: 2a 20 20 20 54 68 65 20 50 43 61 63 68 65 2e 70  *   The PCache.p
0370: 53 79 6e 63 65 64 20 76 61 72 69 61 62 6c 65 20  Synced variable 
0380: 69 73 20 75 73 65 64 20 74 6f 20 6f 70 74 69 6d  is used to optim
0390: 69 7a 65 20 73 65 61 72 63 68 69 6e 67 20 66 6f  ize searching fo
03a0: 72 20 61 20 64 69 72 74 79 0a 2a 2a 20 20 20 70  r a dirty.**   p
03b0: 61 67 65 20 74 6f 20 65 6a 65 63 74 20 66 72 6f  age to eject fro
03c0: 6d 20 74 68 65 20 63 61 63 68 65 20 6d 69 64 2d  m the cache mid-
03d0: 74 72 61 6e 73 61 63 74 69 6f 6e 2e 20 49 74 20  transaction. It 
03e0: 69 73 20 62 65 74 74 65 72 20 74 6f 20 65 6a 65  is better to eje
03f0: 63 74 0a 2a 2a 20 20 20 61 20 70 61 67 65 20 74  ct.**   a page t
0400: 68 61 74 20 64 6f 65 73 20 6e 6f 74 20 72 65 71  hat does not req
0410: 75 69 72 65 20 61 20 6a 6f 75 72 6e 61 6c 20 73  uire a journal s
0420: 79 6e 63 20 74 68 61 6e 20 6f 6e 65 20 74 68 61  ync than one tha
0430: 74 20 64 6f 65 73 2e 20 0a 2a 2a 20 20 20 54 68  t does. .**   Th
0440: 65 72 65 66 6f 72 65 2c 20 70 53 79 6e 63 65 64  erefore, pSynced
0450: 20 69 73 20 6d 61 69 6e 74 61 69 6e 65 64 20 74   is maintained t
0460: 6f 20 74 68 61 74 20 69 74 20 2a 61 6c 6d 6f 73  o that it *almos
0470: 74 2a 20 61 6c 77 61 79 73 20 70 6f 69 6e 74 73  t* always points
0480: 0a 2a 2a 20 20 20 74 6f 20 65 69 74 68 65 72 20  .**   to either 
0490: 74 68 65 20 6f 6c 64 65 73 74 20 70 61 67 65 20  the oldest page 
04a0: 69 6e 20 74 68 65 20 70 44 69 72 74 79 2f 70 44  in the pDirty/pD
04b0: 69 72 74 79 54 61 69 6c 20 6c 69 73 74 20 74 68  irtyTail list th
04c0: 61 74 20 68 61 73 20 61 0a 2a 2a 20 20 20 63 6c  at has a.**   cl
04d0: 65 61 72 20 50 47 48 44 52 5f 4e 45 45 44 5f 53  ear PGHDR_NEED_S
04e0: 59 4e 43 20 66 6c 61 67 20 6f 72 20 74 6f 20 61  YNC flag or to a
04f0: 20 70 61 67 65 20 74 68 61 74 20 69 73 20 6f 6c   page that is ol
0500: 64 65 72 20 74 68 61 6e 20 74 68 69 73 20 6f 6e  der than this on
0510: 65 0a 2a 2a 20 20 20 28 73 6f 20 74 68 61 74 20  e.**   (so that 
0520: 74 68 65 20 72 69 67 68 74 20 70 61 67 65 20 74  the right page t
0530: 6f 20 65 6a 65 63 74 20 63 61 6e 20 62 65 20 66  o eject can be f
0540: 6f 75 6e 64 20 62 79 20 66 6f 6c 6c 6f 77 69 6e  ound by followin
0550: 67 20 70 44 69 72 74 79 50 72 65 76 0a 2a 2a 20  g pDirtyPrev.** 
0560: 20 20 70 6f 69 6e 74 65 72 73 29 2e 0a 2a 2f 0a    pointers)..*/.
0570: 73 74 72 75 63 74 20 50 43 61 63 68 65 20 7b 0a  struct PCache {.
0580: 20 20 50 67 48 64 72 20 2a 70 44 69 72 74 79 2c    PgHdr *pDirty,
0590: 20 2a 70 44 69 72 74 79 54 61 69 6c 3b 20 20 20   *pDirtyTail;   
05a0: 20 20 20 20 20 20 2f 2a 20 4c 69 73 74 20 6f 66        /* List of
05b0: 20 64 69 72 74 79 20 70 61 67 65 73 20 69 6e 20   dirty pages in 
05c0: 4c 52 55 20 6f 72 64 65 72 20 2a 2f 0a 20 20 50  LRU order */.  P
05d0: 67 48 64 72 20 2a 70 53 79 6e 63 65 64 3b 20 20  gHdr *pSynced;  
05e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
05f0: 20 20 20 2f 2a 20 4c 61 73 74 20 73 79 6e 63 65     /* Last synce
0600: 64 20 70 61 67 65 20 69 6e 20 64 69 72 74 79 20  d page in dirty 
0610: 70 61 67 65 20 6c 69 73 74 20 2a 2f 0a 20 20 69  page list */.  i
0620: 6e 74 20 6e 52 65 66 53 75 6d 3b 20 20 20 20 20  nt nRefSum;     
0630: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0640: 20 20 20 2f 2a 20 53 75 6d 20 6f 66 20 72 65 66     /* Sum of ref
0650: 20 63 6f 75 6e 74 73 20 6f 76 65 72 20 61 6c 6c   counts over all
0660: 20 70 61 67 65 73 20 2a 2f 0a 20 20 69 6e 74 20   pages */.  int 
0670: 73 7a 43 61 63 68 65 3b 20 20 20 20 20 20 20 20  szCache;        
0680: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0690: 2f 2a 20 43 6f 6e 66 69 67 75 72 65 64 20 63 61  /* Configured ca
06a0: 63 68 65 20 73 69 7a 65 20 2a 2f 0a 20 20 69 6e  che size */.  in
06b0: 74 20 73 7a 53 70 69 6c 6c 3b 20 20 20 20 20 20  t szSpill;      
06c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
06d0: 20 20 2f 2a 20 53 69 7a 65 20 62 65 66 6f 72 65    /* Size before
06e0: 20 73 70 69 6c 6c 69 6e 67 20 6f 63 63 75 72 73   spilling occurs
06f0: 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 50 61 67 65   */.  int szPage
0700: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
0710: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a            /* Siz
0720: 65 20 6f 66 20 65 76 65 72 79 20 70 61 67 65 20  e of every page 
0730: 69 6e 20 74 68 69 73 20 63 61 63 68 65 20 2a 2f  in this cache */
0740: 0a 20 20 69 6e 74 20 73 7a 45 78 74 72 61 3b 20  .  int szExtra; 
0750: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0760: 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
0770: 66 20 65 78 74 72 61 20 73 70 61 63 65 20 66 6f  f extra space fo
0780: 72 20 65 61 63 68 20 70 61 67 65 20 2a 2f 0a 20  r each page */. 
0790: 20 75 38 20 62 50 75 72 67 65 61 62 6c 65 3b 20   u8 bPurgeable; 
07a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
07b0: 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20       /* True if 
07c0: 70 61 67 65 73 20 61 72 65 20 6f 6e 20 62 61 63  pages are on bac
07d0: 6b 69 6e 67 20 73 74 6f 72 65 20 2a 2f 0a 20 20  king store */.  
07e0: 75 38 20 65 43 72 65 61 74 65 3b 20 20 20 20 20  u8 eCreate;     
07f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0800: 20 20 20 20 2f 2a 20 65 43 72 65 61 74 65 20 76      /* eCreate v
0810: 61 6c 75 65 20 66 6f 72 20 66 6f 72 20 78 46 65  alue for for xFe
0820: 74 63 68 28 29 20 2a 2f 0a 20 20 69 6e 74 20 28  tch() */.  int (
0830: 2a 78 53 74 72 65 73 73 29 28 76 6f 69 64 2a 2c  *xStress)(void*,
0840: 50 67 48 64 72 2a 29 3b 20 20 20 20 20 20 20 2f  PgHdr*);       /
0850: 2a 20 43 61 6c 6c 20 74 6f 20 74 72 79 20 6d 61  * Call to try ma
0860: 6b 65 20 61 20 70 61 67 65 20 63 6c 65 61 6e 20  ke a page clean 
0870: 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 53 74 72 65  */.  void *pStre
0880: 73 73 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ss;             
0890: 20 20 20 20 20 20 20 20 20 2f 2a 20 41 72 67 75           /* Argu
08a0: 6d 65 6e 74 20 74 6f 20 78 53 74 72 65 73 73 20  ment to xStress 
08b0: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 70 63 61  */.  sqlite3_pca
08c0: 63 68 65 20 2a 70 43 61 63 68 65 3b 20 20 20 20  che *pCache;    
08d0: 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6c 75 67           /* Plug
08e0: 67 61 62 6c 65 20 63 61 63 68 65 20 6d 6f 64 75  gable cache modu
08f0: 6c 65 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20  le */.};../*.** 
0900: 44 65 62 75 67 20 74 72 61 63 69 6e 67 20 6d 61  Debug tracing ma
0910: 63 72 6f 73 0a 2a 2f 0a 23 69 66 20 64 65 66 69  cros.*/.#if defi
0920: 6e 65 64 28 53 51 4c 49 54 45 5f 44 45 42 55 47  ned(SQLITE_DEBUG
0930: 29 20 26 26 20 30 0a 20 20 69 6e 74 20 73 71 6c  ) && 0.  int sql
0940: 69 74 65 33 50 63 61 63 68 65 54 72 61 63 65 20  ite3PcacheTrace 
0950: 3d 20 31 3b 0a 23 20 64 65 66 69 6e 65 20 70 63  = 1;.# define pc
0960: 61 63 68 65 54 72 61 63 65 28 58 29 20 69 66 28  acheTrace(X) if(
0970: 73 71 6c 69 74 65 33 50 63 61 63 68 65 54 72 61  sqlite3PcacheTra
0980: 63 65 29 7b 73 71 6c 69 74 65 33 44 65 62 75 67  ce){sqlite3Debug
0990: 50 72 69 6e 74 66 20 58 3b 7d 0a 23 65 6c 73 65  Printf X;}.#else
09a0: 0a 23 20 64 65 66 69 6e 65 20 70 63 61 63 68 65  .# define pcache
09b0: 54 72 61 63 65 28 58 29 0a 23 65 6e 64 69 66 0a  Trace(X).#endif.
09c0: 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ./**************
09d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
09e0: 2a 2a 2a 2a 20 4c 69 6e 6b 65 64 20 4c 69 73 74  **** Linked List
09f0: 20 4d 61 6e 61 67 65 6d 65 6e 74 20 2a 2a 2a 2a   Management ****
0a00: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0a10: 2f 0a 0a 2f 2a 20 41 6c 6c 6f 77 65 64 20 76 61  /../* Allowed va
0a20: 6c 75 65 73 20 66 6f 72 20 73 65 63 6f 6e 64 20  lues for second 
0a30: 61 72 67 75 6d 65 6e 74 20 74 6f 20 70 63 61 63  argument to pcac
0a40: 68 65 4d 61 6e 61 67 65 44 69 72 74 79 4c 69 73  heManageDirtyLis
0a50: 74 28 29 20 2a 2f 0a 23 64 65 66 69 6e 65 20 50  t() */.#define P
0a60: 43 41 43 48 45 5f 44 49 52 54 59 4c 49 53 54 5f  CACHE_DIRTYLIST_
0a70: 52 45 4d 4f 56 45 20 20 20 31 20 20 20 20 2f 2a  REMOVE   1    /*
0a80: 20 52 65 6d 6f 76 65 20 70 50 61 67 65 20 66 72   Remove pPage fr
0a90: 6f 6d 20 64 69 72 74 79 20 6c 69 73 74 20 2a 2f  om dirty list */
0aa0: 0a 23 64 65 66 69 6e 65 20 50 43 41 43 48 45 5f  .#define PCACHE_
0ab0: 44 49 52 54 59 4c 49 53 54 5f 41 44 44 20 20 20  DIRTYLIST_ADD   
0ac0: 20 20 20 32 20 20 20 20 2f 2a 20 41 64 64 20 70     2    /* Add p
0ad0: 50 61 67 65 20 74 6f 20 74 68 65 20 64 69 72 74  Page to the dirt
0ae0: 79 20 6c 69 73 74 20 2a 2f 0a 23 64 65 66 69 6e  y list */.#defin
0af0: 65 20 50 43 41 43 48 45 5f 44 49 52 54 59 4c 49  e PCACHE_DIRTYLI
0b00: 53 54 5f 46 52 4f 4e 54 20 20 20 20 33 20 20 20  ST_FRONT    3   
0b10: 20 2f 2a 20 4d 6f 76 65 20 70 50 61 67 65 20 74   /* Move pPage t
0b20: 6f 20 74 68 65 20 66 72 6f 6e 74 20 6f 66 20 74  o the front of t
0b30: 68 65 20 6c 69 73 74 20 2a 2f 0a 0a 2f 2a 0a 2a  he list */../*.*
0b40: 2a 20 4d 61 6e 61 67 65 20 70 50 61 67 65 27 73  * Manage pPage's
0b50: 20 70 61 72 74 69 63 69 70 61 74 69 6f 6e 20 6f   participation o
0b60: 6e 20 74 68 65 20 64 69 72 74 79 20 6c 69 73 74  n the dirty list
0b70: 2e 20 20 42 69 74 73 20 6f 66 20 74 68 65 20 61  .  Bits of the a
0b80: 64 64 52 65 6d 6f 76 65 0a 2a 2a 20 61 72 67 75  ddRemove.** argu
0b90: 6d 65 6e 74 20 64 65 74 65 72 6d 69 6e 65 73 20  ment determines 
0ba0: 77 68 61 74 20 6f 70 65 72 61 74 69 6f 6e 20 74  what operation t
0bb0: 6f 20 64 6f 2e 20 20 54 68 65 20 30 78 30 31 20  o do.  The 0x01 
0bc0: 62 69 74 20 6d 65 61 6e 73 20 66 69 72 73 74 0a  bit means first.
0bd0: 2a 2a 20 72 65 6d 6f 76 65 20 70 50 61 67 65 20  ** remove pPage 
0be0: 66 72 6f 6d 20 74 68 65 20 64 69 72 74 79 20 6c  from the dirty l
0bf0: 69 73 74 2e 20 20 54 68 65 20 30 78 30 32 20 6d  ist.  The 0x02 m
0c00: 65 61 6e 73 20 61 64 64 20 70 50 61 67 65 20 62  eans add pPage b
0c10: 61 63 6b 20 74 6f 0a 2a 2a 20 74 68 65 20 64 69  ack to.** the di
0c20: 72 74 79 20 6c 69 73 74 2e 20 20 44 6f 69 6e 67  rty list.  Doing
0c30: 20 62 6f 74 68 20 6d 6f 76 65 73 20 70 50 61 67   both moves pPag
0c40: 65 20 74 6f 20 74 68 65 20 66 72 6f 6e 74 20 6f  e to the front o
0c50: 66 20 74 68 65 20 64 69 72 74 79 20 6c 69 73 74  f the dirty list
0c60: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
0c70: 20 70 63 61 63 68 65 4d 61 6e 61 67 65 44 69 72   pcacheManageDir
0c80: 74 79 4c 69 73 74 28 50 67 48 64 72 20 2a 70 50  tyList(PgHdr *pP
0c90: 61 67 65 2c 20 75 38 20 61 64 64 52 65 6d 6f 76  age, u8 addRemov
0ca0: 65 29 7b 0a 20 20 50 43 61 63 68 65 20 2a 70 20  e){.  PCache *p 
0cb0: 3d 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65 3b  = pPage->pCache;
0cc0: 0a 0a 20 20 70 63 61 63 68 65 54 72 61 63 65 28  ..  pcacheTrace(
0cd0: 28 22 25 70 2e 44 49 52 54 59 4c 49 53 54 2e 25  ("%p.DIRTYLIST.%
0ce0: 73 20 25 64 5c 6e 22 2c 20 70 2c 0a 20 20 20 20  s %d\n", p,.    
0cf0: 20 20 20 20 20 20 20 20 20 20 20 20 61 64 64 52              addR
0d00: 65 6d 6f 76 65 3d 3d 31 20 3f 20 22 52 45 4d 4f  emove==1 ? "REMO
0d10: 56 45 22 20 3a 20 61 64 64 52 65 6d 6f 76 65 3d  VE" : addRemove=
0d20: 3d 32 20 3f 20 22 41 44 44 22 20 3a 20 22 46 52  =2 ? "ADD" : "FR
0d30: 4f 4e 54 22 2c 0a 20 20 20 20 20 20 20 20 20 20  ONT",.          
0d40: 20 20 20 20 20 20 70 50 61 67 65 2d 3e 70 67 6e        pPage->pgn
0d50: 6f 29 29 3b 0a 20 20 69 66 28 20 61 64 64 52 65  o));.  if( addRe
0d60: 6d 6f 76 65 20 26 20 50 43 41 43 48 45 5f 44 49  move & PCACHE_DI
0d70: 52 54 59 4c 49 53 54 5f 52 45 4d 4f 56 45 20 29  RTYLIST_REMOVE )
0d80: 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 50  {.    assert( pP
0d90: 61 67 65 2d 3e 70 44 69 72 74 79 4e 65 78 74 20  age->pDirtyNext 
0da0: 7c 7c 20 70 50 61 67 65 3d 3d 70 2d 3e 70 44 69  || pPage==p->pDi
0db0: 72 74 79 54 61 69 6c 20 29 3b 0a 20 20 20 20 61  rtyTail );.    a
0dc0: 73 73 65 72 74 28 20 70 50 61 67 65 2d 3e 70 44  ssert( pPage->pD
0dd0: 69 72 74 79 50 72 65 76 20 7c 7c 20 70 50 61 67  irtyPrev || pPag
0de0: 65 3d 3d 70 2d 3e 70 44 69 72 74 79 20 29 3b 0a  e==p->pDirty );.
0df0: 20 20 0a 20 20 20 20 2f 2a 20 55 70 64 61 74 65    .    /* Update
0e00: 20 74 68 65 20 50 43 61 63 68 65 31 2e 70 53 79   the PCache1.pSy
0e10: 6e 63 65 64 20 76 61 72 69 61 62 6c 65 20 69 66  nced variable if
0e20: 20 6e 65 63 65 73 73 61 72 79 2e 20 2a 2f 0a 20   necessary. */. 
0e30: 20 20 20 69 66 28 20 70 2d 3e 70 53 79 6e 63 65     if( p->pSynce
0e40: 64 3d 3d 70 50 61 67 65 20 29 7b 0a 20 20 20 20  d==pPage ){.    
0e50: 20 20 70 2d 3e 70 53 79 6e 63 65 64 20 3d 20 70    p->pSynced = p
0e60: 50 61 67 65 2d 3e 70 44 69 72 74 79 50 72 65 76  Page->pDirtyPrev
0e70: 3b 0a 20 20 20 20 7d 0a 20 20 0a 20 20 20 20 69  ;.    }.  .    i
0e80: 66 28 20 70 50 61 67 65 2d 3e 70 44 69 72 74 79  f( pPage->pDirty
0e90: 4e 65 78 74 20 29 7b 0a 20 20 20 20 20 20 70 50  Next ){.      pP
0ea0: 61 67 65 2d 3e 70 44 69 72 74 79 4e 65 78 74 2d  age->pDirtyNext-
0eb0: 3e 70 44 69 72 74 79 50 72 65 76 20 3d 20 70 50  >pDirtyPrev = pP
0ec0: 61 67 65 2d 3e 70 44 69 72 74 79 50 72 65 76 3b  age->pDirtyPrev;
0ed0: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
0ee0: 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65 3d    assert( pPage=
0ef0: 3d 70 2d 3e 70 44 69 72 74 79 54 61 69 6c 20 29  =p->pDirtyTail )
0f00: 3b 0a 20 20 20 20 20 20 70 2d 3e 70 44 69 72 74  ;.      p->pDirt
0f10: 79 54 61 69 6c 20 3d 20 70 50 61 67 65 2d 3e 70  yTail = pPage->p
0f20: 44 69 72 74 79 50 72 65 76 3b 0a 20 20 20 20 7d  DirtyPrev;.    }
0f30: 0a 20 20 20 20 69 66 28 20 70 50 61 67 65 2d 3e  .    if( pPage->
0f40: 70 44 69 72 74 79 50 72 65 76 20 29 7b 0a 20 20  pDirtyPrev ){.  
0f50: 20 20 20 20 70 50 61 67 65 2d 3e 70 44 69 72 74      pPage->pDirt
0f60: 79 50 72 65 76 2d 3e 70 44 69 72 74 79 4e 65 78  yPrev->pDirtyNex
0f70: 74 20 3d 20 70 50 61 67 65 2d 3e 70 44 69 72 74  t = pPage->pDirt
0f80: 79 4e 65 78 74 3b 0a 20 20 20 20 7d 65 6c 73 65  yNext;.    }else
0f90: 7b 0a 20 20 20 20 20 20 2f 2a 20 49 66 20 74 68  {.      /* If th
0fa0: 65 72 65 20 61 72 65 20 6e 6f 77 20 6e 6f 20 64  ere are now no d
0fb0: 69 72 74 79 20 70 61 67 65 73 20 69 6e 20 74 68  irty pages in th
0fc0: 65 20 63 61 63 68 65 2c 20 73 65 74 20 65 43 72  e cache, set eCr
0fd0: 65 61 74 65 20 74 6f 20 32 2e 20 0a 20 20 20 20  eate to 2. .    
0fe0: 20 20 2a 2a 20 54 68 69 73 20 69 73 20 61 6e 20    ** This is an 
0ff0: 6f 70 74 69 6d 69 7a 61 74 69 6f 6e 20 74 68 61  optimization tha
1000: 74 20 61 6c 6c 6f 77 73 20 73 71 6c 69 74 65 33  t allows sqlite3
1010: 50 63 61 63 68 65 46 65 74 63 68 28 29 20 74 6f  PcacheFetch() to
1020: 20 73 6b 69 70 0a 20 20 20 20 20 20 2a 2a 20 73   skip.      ** s
1030: 65 61 72 63 68 69 6e 67 20 66 6f 72 20 61 20 64  earching for a d
1040: 69 72 74 79 20 70 61 67 65 20 74 6f 20 65 6a 65  irty page to eje
1050: 63 74 20 66 72 6f 6d 20 74 68 65 20 63 61 63 68  ct from the cach
1060: 65 20 77 68 65 6e 20 69 74 20 6d 69 67 68 74 0a  e when it might.
1070: 20 20 20 20 20 20 2a 2a 20 6f 74 68 65 72 77 69        ** otherwi
1080: 73 65 20 68 61 76 65 20 74 6f 2e 20 20 2a 2f 0a  se have to.  */.
1090: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70 50        assert( pP
10a0: 61 67 65 3d 3d 70 2d 3e 70 44 69 72 74 79 20 29  age==p->pDirty )
10b0: 3b 0a 20 20 20 20 20 20 70 2d 3e 70 44 69 72 74  ;.      p->pDirt
10c0: 79 20 3d 20 70 50 61 67 65 2d 3e 70 44 69 72 74  y = pPage->pDirt
10d0: 79 4e 65 78 74 3b 0a 20 20 20 20 20 20 61 73 73  yNext;.      ass
10e0: 65 72 74 28 20 70 2d 3e 62 50 75 72 67 65 61 62  ert( p->bPurgeab
10f0: 6c 65 20 7c 7c 20 70 2d 3e 65 43 72 65 61 74 65  le || p->eCreate
1100: 3d 3d 32 20 29 3b 0a 20 20 20 20 20 20 69 66 28  ==2 );.      if(
1110: 20 70 2d 3e 70 44 69 72 74 79 3d 3d 30 20 29 7b   p->pDirty==0 ){
1120: 20 20 20 20 20 20 20 20 20 2f 2a 4f 50 54 49 4d           /*OPTIM
1130: 49 5a 41 54 49 4f 4e 2d 49 46 2d 54 52 55 45 2a  IZATION-IF-TRUE*
1140: 2f 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74  /.        assert
1150: 28 20 70 2d 3e 62 50 75 72 67 65 61 62 6c 65 3d  ( p->bPurgeable=
1160: 3d 30 20 7c 7c 20 70 2d 3e 65 43 72 65 61 74 65  =0 || p->eCreate
1170: 3d 3d 31 20 29 3b 0a 20 20 20 20 20 20 20 20 70  ==1 );.        p
1180: 2d 3e 65 43 72 65 61 74 65 20 3d 20 32 3b 0a 20  ->eCreate = 2;. 
1190: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20       }.    }.   
11a0: 20 70 50 61 67 65 2d 3e 70 44 69 72 74 79 4e 65   pPage->pDirtyNe
11b0: 78 74 20 3d 20 30 3b 0a 20 20 20 20 70 50 61 67  xt = 0;.    pPag
11c0: 65 2d 3e 70 44 69 72 74 79 50 72 65 76 20 3d 20  e->pDirtyPrev = 
11d0: 30 3b 0a 20 20 7d 0a 20 20 69 66 28 20 61 64 64  0;.  }.  if( add
11e0: 52 65 6d 6f 76 65 20 26 20 50 43 41 43 48 45 5f  Remove & PCACHE_
11f0: 44 49 52 54 59 4c 49 53 54 5f 41 44 44 20 29 7b  DIRTYLIST_ADD ){
1200: 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 50 61  .    assert( pPa
1210: 67 65 2d 3e 70 44 69 72 74 79 4e 65 78 74 3d 3d  ge->pDirtyNext==
1220: 30 20 26 26 20 70 50 61 67 65 2d 3e 70 44 69 72  0 && pPage->pDir
1230: 74 79 50 72 65 76 3d 3d 30 20 26 26 20 70 2d 3e  tyPrev==0 && p->
1240: 70 44 69 72 74 79 21 3d 70 50 61 67 65 20 29 3b  pDirty!=pPage );
1250: 0a 20 20 0a 20 20 20 20 70 50 61 67 65 2d 3e 70  .  .    pPage->p
1260: 44 69 72 74 79 4e 65 78 74 20 3d 20 70 2d 3e 70  DirtyNext = p->p
1270: 44 69 72 74 79 3b 0a 20 20 20 20 69 66 28 20 70  Dirty;.    if( p
1280: 50 61 67 65 2d 3e 70 44 69 72 74 79 4e 65 78 74  Page->pDirtyNext
1290: 20 29 7b 0a 20 20 20 20 20 20 61 73 73 65 72 74   ){.      assert
12a0: 28 20 70 50 61 67 65 2d 3e 70 44 69 72 74 79 4e  ( pPage->pDirtyN
12b0: 65 78 74 2d 3e 70 44 69 72 74 79 50 72 65 76 3d  ext->pDirtyPrev=
12c0: 3d 30 20 29 3b 0a 20 20 20 20 20 20 70 50 61 67  =0 );.      pPag
12d0: 65 2d 3e 70 44 69 72 74 79 4e 65 78 74 2d 3e 70  e->pDirtyNext->p
12e0: 44 69 72 74 79 50 72 65 76 20 3d 20 70 50 61 67  DirtyPrev = pPag
12f0: 65 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  e;.    }else{.  
1300: 20 20 20 20 70 2d 3e 70 44 69 72 74 79 54 61 69      p->pDirtyTai
1310: 6c 20 3d 20 70 50 61 67 65 3b 0a 20 20 20 20 20  l = pPage;.     
1320: 20 69 66 28 20 70 2d 3e 62 50 75 72 67 65 61 62   if( p->bPurgeab
1330: 6c 65 20 29 7b 0a 20 20 20 20 20 20 20 20 61 73  le ){.        as
1340: 73 65 72 74 28 20 70 2d 3e 65 43 72 65 61 74 65  sert( p->eCreate
1350: 3d 3d 32 20 29 3b 0a 20 20 20 20 20 20 20 20 70  ==2 );.        p
1360: 2d 3e 65 43 72 65 61 74 65 20 3d 20 31 3b 0a 20  ->eCreate = 1;. 
1370: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20       }.    }.   
1380: 20 70 2d 3e 70 44 69 72 74 79 20 3d 20 70 50 61   p->pDirty = pPa
1390: 67 65 3b 0a 20 20 20 20 69 66 28 20 21 70 2d 3e  ge;.    if( !p->
13a0: 70 53 79 6e 63 65 64 20 26 26 20 30 3d 3d 28 70  pSynced && 0==(p
13b0: 50 61 67 65 2d 3e 66 6c 61 67 73 26 50 47 48 44  Page->flags&PGHD
13c0: 52 5f 4e 45 45 44 5f 53 59 4e 43 29 20 29 7b 0a  R_NEED_SYNC) ){.
13d0: 20 20 20 20 20 20 70 2d 3e 70 53 79 6e 63 65 64        p->pSynced
13e0: 20 3d 20 70 50 61 67 65 3b 0a 20 20 20 20 7d 0a   = pPage;.    }.
13f0: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 61    }.}../*.** Wra
1400: 70 70 65 72 20 61 72 6f 75 6e 64 20 74 68 65 20  pper around the 
1410: 70 6c 75 67 67 61 62 6c 65 20 63 61 63 68 65 73  pluggable caches
1420: 20 78 55 6e 70 69 6e 20 6d 65 74 68 6f 64 2e 20   xUnpin method. 
1430: 49 66 20 74 68 65 20 63 61 63 68 65 20 69 73 0a  If the cache is.
1440: 2a 2a 20 62 65 69 6e 67 20 75 73 65 64 20 66 6f  ** being used fo
1450: 72 20 61 6e 20 69 6e 2d 6d 65 6d 6f 72 79 20 64  r an in-memory d
1460: 61 74 61 62 61 73 65 2c 20 74 68 69 73 20 66 75  atabase, this fu
1470: 6e 63 74 69 6f 6e 20 69 73 20 61 20 6e 6f 2d 6f  nction is a no-o
1480: 70 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  p..*/.static voi
1490: 64 20 70 63 61 63 68 65 55 6e 70 69 6e 28 50 67  d pcacheUnpin(Pg
14a0: 48 64 72 20 2a 70 29 7b 0a 20 20 69 66 28 20 70  Hdr *p){.  if( p
14b0: 2d 3e 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65  ->pCache->bPurge
14c0: 61 62 6c 65 20 29 7b 0a 20 20 20 20 70 63 61 63  able ){.    pcac
14d0: 68 65 54 72 61 63 65 28 28 22 25 70 2e 55 4e 50  heTrace(("%p.UNP
14e0: 49 4e 20 25 64 5c 6e 22 2c 20 70 2d 3e 70 43 61  IN %d\n", p->pCa
14f0: 63 68 65 2c 20 70 2d 3e 70 67 6e 6f 29 29 3b 0a  che, p->pgno));.
1500: 20 20 20 20 73 71 6c 69 74 65 33 47 6c 6f 62 61      sqlite3Globa
1510: 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65 32 2e  lConfig.pcache2.
1520: 78 55 6e 70 69 6e 28 70 2d 3e 70 43 61 63 68 65  xUnpin(p->pCache
1530: 2d 3e 70 43 61 63 68 65 2c 20 70 2d 3e 70 50 61  ->pCache, p->pPa
1540: 67 65 2c 20 30 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f  ge, 0);.  }.}../
1550: 2a 0a 2a 2a 20 43 6f 6d 70 75 74 65 20 74 68 65  *.** Compute the
1560: 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73   number of pages
1570: 20 6f 66 20 63 61 63 68 65 20 72 65 71 75 65 73   of cache reques
1580: 74 65 64 2e 20 20 20 70 2d 3e 73 7a 43 61 63 68  ted.   p->szCach
1590: 65 20 69 73 20 74 68 65 0a 2a 2a 20 63 61 63 68  e is the.** cach
15a0: 65 20 73 69 7a 65 20 72 65 71 75 65 73 74 65 64  e size requested
15b0: 20 62 79 20 74 68 65 20 22 50 52 41 47 4d 41 20   by the "PRAGMA 
15c0: 63 61 63 68 65 5f 73 69 7a 65 22 20 73 74 61 74  cache_size" stat
15d0: 65 6d 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69 63  ement..*/.static
15e0: 20 69 6e 74 20 6e 75 6d 62 65 72 4f 66 43 61 63   int numberOfCac
15f0: 68 65 50 61 67 65 73 28 50 43 61 63 68 65 20 2a  hePages(PCache *
1600: 70 29 7b 0a 20 20 69 66 28 20 70 2d 3e 73 7a 43  p){.  if( p->szC
1610: 61 63 68 65 3e 3d 30 20 29 7b 0a 20 20 20 20 2f  ache>=0 ){.    /
1620: 2a 20 49 4d 50 4c 45 4d 45 4e 54 41 54 49 4f 4e  * IMPLEMENTATION
1630: 2d 4f 46 3a 20 52 2d 34 32 30 35 39 2d 34 37 32  -OF: R-42059-472
1640: 31 31 20 49 66 20 74 68 65 20 61 72 67 75 6d 65  11 If the argume
1650: 6e 74 20 4e 20 69 73 20 70 6f 73 69 74 69 76 65  nt N is positive
1660: 20 74 68 65 6e 20 74 68 65 0a 20 20 20 20 2a 2a   then the.    **
1670: 20 73 75 67 67 65 73 74 65 64 20 63 61 63 68 65   suggested cache
1680: 20 73 69 7a 65 20 69 73 20 73 65 74 20 74 6f 20   size is set to 
1690: 4e 2e 20 2a 2f 0a 20 20 20 20 72 65 74 75 72 6e  N. */.    return
16a0: 20 70 2d 3e 73 7a 43 61 63 68 65 3b 0a 20 20 7d   p->szCache;.  }
16b0: 65 6c 73 65 7b 0a 20 20 20 20 2f 2a 20 49 4d 50  else{.    /* IMP
16c0: 4c 45 4d 45 4e 54 41 54 49 4f 4e 2d 4f 46 3a 20  LEMENTATION-OF: 
16d0: 52 2d 36 31 34 33 36 2d 31 33 36 33 39 20 49 66  R-61436-13639 If
16e0: 20 74 68 65 20 61 72 67 75 6d 65 6e 74 20 4e 20   the argument N 
16f0: 69 73 20 6e 65 67 61 74 69 76 65 2c 20 74 68 65  is negative, the
1700: 6e 0a 20 20 20 20 2a 2a 20 74 68 65 20 6e 75 6d  n.    ** the num
1710: 62 65 72 20 6f 66 20 63 61 63 68 65 20 70 61 67  ber of cache pag
1720: 65 73 20 69 73 20 61 64 6a 75 73 74 65 64 20 74  es is adjusted t
1730: 6f 20 75 73 65 20 61 70 70 72 6f 78 69 6d 61 74  o use approximat
1740: 65 6c 79 20 61 62 73 28 4e 2a 31 30 32 34 29 0a  ely abs(N*1024).
1750: 20 20 20 20 2a 2a 20 62 79 74 65 73 20 6f 66 20      ** bytes of 
1760: 6d 65 6d 6f 72 79 2e 20 2a 2f 0a 20 20 20 20 72  memory. */.    r
1770: 65 74 75 72 6e 20 28 69 6e 74 29 28 28 2d 31 30  eturn (int)((-10
1780: 32 34 2a 28 69 36 34 29 70 2d 3e 73 7a 43 61 63  24*(i64)p->szCac
1790: 68 65 29 2f 28 70 2d 3e 73 7a 50 61 67 65 2b 70  he)/(p->szPage+p
17a0: 2d 3e 73 7a 45 78 74 72 61 29 29 3b 0a 20 20 7d  ->szExtra));.  }
17b0: 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  .}../***********
17c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
17d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
17e0: 2a 2a 2a 2a 2a 2a 2a 2a 20 47 65 6e 65 72 61 6c  ******** General
17f0: 20 49 6e 74 65 72 66 61 63 65 73 20 2a 2a 2a 2a   Interfaces ****
1800: 2a 2a 0a 2a 2a 0a 2a 2a 20 49 6e 69 74 69 61 6c  **.**.** Initial
1810: 69 7a 65 20 61 6e 64 20 73 68 75 74 64 6f 77 6e  ize and shutdown
1820: 20 74 68 65 20 70 61 67 65 20 63 61 63 68 65 20   the page cache 
1830: 73 75 62 73 79 73 74 65 6d 2e 20 4e 65 69 74 68  subsystem. Neith
1840: 65 72 20 6f 66 20 74 68 65 73 65 20 0a 2a 2a 20  er of these .** 
1850: 66 75 6e 63 74 69 6f 6e 73 20 61 72 65 20 74 68  functions are th
1860: 72 65 61 64 73 61 66 65 2e 0a 2a 2f 0a 69 6e 74  readsafe..*/.int
1870: 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 49 6e   sqlite3PcacheIn
1880: 69 74 69 61 6c 69 7a 65 28 76 6f 69 64 29 7b 0a  itialize(void){.
1890: 20 20 69 66 28 20 73 71 6c 69 74 65 33 47 6c 6f    if( sqlite3Glo
18a0: 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65  balConfig.pcache
18b0: 32 2e 78 49 6e 69 74 3d 3d 30 20 29 7b 0a 20 20  2.xInit==0 ){.  
18c0: 20 20 2f 2a 20 49 4d 50 4c 45 4d 45 4e 54 41 54    /* IMPLEMENTAT
18d0: 49 4f 4e 2d 4f 46 3a 20 52 2d 32 36 38 30 31 2d  ION-OF: R-26801-
18e0: 36 34 31 33 37 20 49 66 20 74 68 65 20 78 49 6e  64137 If the xIn
18f0: 69 74 28 29 20 6d 65 74 68 6f 64 20 69 73 20 4e  it() method is N
1900: 55 4c 4c 2c 20 74 68 65 6e 20 74 68 65 0a 20 20  ULL, then the.  
1910: 20 20 2a 2a 20 62 75 69 6c 74 2d 69 6e 20 64 65    ** built-in de
1920: 66 61 75 6c 74 20 70 61 67 65 20 63 61 63 68 65  fault page cache
1930: 20 69 73 20 75 73 65 64 20 69 6e 73 74 65 61 64   is used instead
1940: 20 6f 66 20 74 68 65 20 61 70 70 6c 69 63 61 74   of the applicat
1950: 69 6f 6e 20 64 65 66 69 6e 65 64 0a 20 20 20 20  ion defined.    
1960: 2a 2a 20 70 61 67 65 20 63 61 63 68 65 2e 20 2a  ** page cache. *
1970: 2f 0a 20 20 20 20 73 71 6c 69 74 65 33 50 43 61  /.    sqlite3PCa
1980: 63 68 65 53 65 74 44 65 66 61 75 6c 74 28 29 3b  cheSetDefault();
1990: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 73 71  .  }.  return sq
19a0: 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69  lite3GlobalConfi
19b0: 67 2e 70 63 61 63 68 65 32 2e 78 49 6e 69 74 28  g.pcache2.xInit(
19c0: 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e  sqlite3GlobalCon
19d0: 66 69 67 2e 70 63 61 63 68 65 32 2e 70 41 72 67  fig.pcache2.pArg
19e0: 29 3b 0a 7d 0a 76 6f 69 64 20 73 71 6c 69 74 65  );.}.void sqlite
19f0: 33 50 63 61 63 68 65 53 68 75 74 64 6f 77 6e 28  3PcacheShutdown(
1a00: 76 6f 69 64 29 7b 0a 20 20 69 66 28 20 73 71 6c  void){.  if( sql
1a10: 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67  ite3GlobalConfig
1a20: 2e 70 63 61 63 68 65 32 2e 78 53 68 75 74 64 6f  .pcache2.xShutdo
1a30: 77 6e 20 29 7b 0a 20 20 20 20 2f 2a 20 49 4d 50  wn ){.    /* IMP
1a40: 4c 45 4d 45 4e 54 41 54 49 4f 4e 2d 4f 46 3a 20  LEMENTATION-OF: 
1a50: 52 2d 32 36 30 30 30 2d 35 36 35 38 39 20 54 68  R-26000-56589 Th
1a60: 65 20 78 53 68 75 74 64 6f 77 6e 28 29 20 6d 65  e xShutdown() me
1a70: 74 68 6f 64 20 6d 61 79 20 62 65 20 4e 55 4c 4c  thod may be NULL
1a80: 2e 20 2a 2f 0a 20 20 20 20 73 71 6c 69 74 65 33  . */.    sqlite3
1a90: 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61  GlobalConfig.pca
1aa0: 63 68 65 32 2e 78 53 68 75 74 64 6f 77 6e 28 73  che2.xShutdown(s
1ab0: 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66  qlite3GlobalConf
1ac0: 69 67 2e 70 63 61 63 68 65 32 2e 70 41 72 67 29  ig.pcache2.pArg)
1ad0: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  ;.  }.}../*.** R
1ae0: 65 74 75 72 6e 20 74 68 65 20 73 69 7a 65 20 69  eturn the size i
1af0: 6e 20 62 79 74 65 73 20 6f 66 20 61 20 50 43 61  n bytes of a PCa
1b00: 63 68 65 20 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 69  che object..*/.i
1b10: 6e 74 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  nt sqlite3Pcache
1b20: 53 69 7a 65 28 76 6f 69 64 29 7b 20 72 65 74 75  Size(void){ retu
1b30: 72 6e 20 73 69 7a 65 6f 66 28 50 43 61 63 68 65  rn sizeof(PCache
1b40: 29 3b 20 7d 0a 0a 2f 2a 0a 2a 2a 20 43 72 65 61  ); }../*.** Crea
1b50: 74 65 20 61 20 6e 65 77 20 50 43 61 63 68 65 20  te a new PCache 
1b60: 6f 62 6a 65 63 74 2e 20 53 74 6f 72 61 67 65 20  object. Storage 
1b70: 73 70 61 63 65 20 74 6f 20 68 6f 6c 64 20 74 68  space to hold th
1b80: 65 20 6f 62 6a 65 63 74 0a 2a 2a 20 68 61 73 20  e object.** has 
1b90: 61 6c 72 65 61 64 79 20 62 65 65 6e 20 61 6c 6c  already been all
1ba0: 6f 63 61 74 65 64 20 61 6e 64 20 69 73 20 70 61  ocated and is pa
1bb0: 73 73 65 64 20 69 6e 20 61 73 20 74 68 65 20 70  ssed in as the p
1bc0: 20 70 6f 69 6e 74 65 72 2e 20 0a 2a 2a 20 54 68   pointer. .** Th
1bd0: 65 20 63 61 6c 6c 65 72 20 64 69 73 63 6f 76 65  e caller discove
1be0: 72 73 20 68 6f 77 20 6d 75 63 68 20 73 70 61 63  rs how much spac
1bf0: 65 20 6e 65 65 64 73 20 74 6f 20 62 65 20 61 6c  e needs to be al
1c00: 6c 6f 63 61 74 65 64 20 62 79 20 0a 2a 2a 20 63  located by .** c
1c10: 61 6c 6c 69 6e 67 20 73 71 6c 69 74 65 33 50 63  alling sqlite3Pc
1c20: 61 63 68 65 53 69 7a 65 28 29 2e 0a 2a 2f 0a 69  acheSize()..*/.i
1c30: 6e 74 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  nt sqlite3Pcache
1c40: 4f 70 65 6e 28 0a 20 20 69 6e 74 20 73 7a 50 61  Open(.  int szPa
1c50: 67 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ge,             
1c60: 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
1c70: 65 76 65 72 79 20 70 61 67 65 20 2a 2f 0a 20 20  every page */.  
1c80: 69 6e 74 20 73 7a 45 78 74 72 61 2c 20 20 20 20  int szExtra,    
1c90: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1ca0: 45 78 74 72 61 20 73 70 61 63 65 20 61 73 73 6f  Extra space asso
1cb0: 63 69 61 74 65 64 20 77 69 74 68 20 65 61 63 68  ciated with each
1cc0: 20 70 61 67 65 20 2a 2f 0a 20 20 69 6e 74 20 62   page */.  int b
1cd0: 50 75 72 67 65 61 62 6c 65 2c 20 20 20 20 20 20  Purgeable,      
1ce0: 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20          /* True 
1cf0: 69 66 20 70 61 67 65 73 20 61 72 65 20 6f 6e 20  if pages are on 
1d00: 62 61 63 6b 69 6e 67 20 73 74 6f 72 65 20 2a 2f  backing store */
1d10: 0a 20 20 69 6e 74 20 28 2a 78 53 74 72 65 73 73  .  int (*xStress
1d20: 29 28 76 6f 69 64 2a 2c 50 67 48 64 72 2a 29 2c  )(void*,PgHdr*),
1d30: 2f 2a 20 43 61 6c 6c 20 74 6f 20 74 72 79 20 74  /* Call to try t
1d40: 6f 20 6d 61 6b 65 20 70 61 67 65 73 20 63 6c 65  o make pages cle
1d50: 61 6e 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 53  an */.  void *pS
1d60: 74 72 65 73 73 2c 20 20 20 20 20 20 20 20 20 20  tress,          
1d70: 20 20 20 20 20 2f 2a 20 41 72 67 75 6d 65 6e 74       /* Argument
1d80: 20 74 6f 20 78 53 74 72 65 73 73 20 2a 2f 0a 20   to xStress */. 
1d90: 20 50 43 61 63 68 65 20 2a 70 20 20 20 20 20 20   PCache *p      
1da0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1db0: 20 50 72 65 61 6c 6c 6f 63 61 74 65 64 20 73 70   Preallocated sp
1dc0: 61 63 65 20 66 6f 72 20 74 68 65 20 50 43 61 63  ace for the PCac
1dd0: 68 65 20 2a 2f 0a 29 7b 0a 20 20 6d 65 6d 73 65  he */.){.  memse
1de0: 74 28 70 2c 20 30 2c 20 73 69 7a 65 6f 66 28 50  t(p, 0, sizeof(P
1df0: 43 61 63 68 65 29 29 3b 0a 20 20 70 2d 3e 73 7a  Cache));.  p->sz
1e00: 50 61 67 65 20 3d 20 31 3b 0a 20 20 70 2d 3e 73  Page = 1;.  p->s
1e10: 7a 45 78 74 72 61 20 3d 20 73 7a 45 78 74 72 61  zExtra = szExtra
1e20: 3b 0a 20 20 70 2d 3e 62 50 75 72 67 65 61 62 6c  ;.  p->bPurgeabl
1e30: 65 20 3d 20 62 50 75 72 67 65 61 62 6c 65 3b 0a  e = bPurgeable;.
1e40: 20 20 70 2d 3e 65 43 72 65 61 74 65 20 3d 20 32    p->eCreate = 2
1e50: 3b 0a 20 20 70 2d 3e 78 53 74 72 65 73 73 20 3d  ;.  p->xStress =
1e60: 20 78 53 74 72 65 73 73 3b 0a 20 20 70 2d 3e 70   xStress;.  p->p
1e70: 53 74 72 65 73 73 20 3d 20 70 53 74 72 65 73 73  Stress = pStress
1e80: 3b 0a 20 20 70 2d 3e 73 7a 43 61 63 68 65 20 3d  ;.  p->szCache =
1e90: 20 31 30 30 3b 0a 20 20 70 2d 3e 73 7a 53 70 69   100;.  p->szSpi
1ea0: 6c 6c 20 3d 20 31 3b 0a 20 20 70 63 61 63 68 65  ll = 1;.  pcache
1eb0: 54 72 61 63 65 28 28 22 25 70 2e 4f 50 45 4e 20  Trace(("%p.OPEN 
1ec0: 73 7a 50 61 67 65 20 25 64 20 62 50 75 72 67 65  szPage %d bPurge
1ed0: 61 62 6c 65 20 25 64 5c 6e 22 2c 70 2c 73 7a 50  able %d\n",p,szP
1ee0: 61 67 65 2c 62 50 75 72 67 65 61 62 6c 65 29 29  age,bPurgeable))
1ef0: 3b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74  ;.  return sqlit
1f00: 65 33 50 63 61 63 68 65 53 65 74 50 61 67 65 53  e3PcacheSetPageS
1f10: 69 7a 65 28 70 2c 20 73 7a 50 61 67 65 29 3b 0a  ize(p, szPage);.
1f20: 7d 0a 0a 2f 2a 0a 2a 2a 20 43 68 61 6e 67 65 20  }../*.** Change 
1f30: 74 68 65 20 70 61 67 65 20 73 69 7a 65 20 66 6f  the page size fo
1f40: 72 20 50 43 61 63 68 65 20 6f 62 6a 65 63 74 2e  r PCache object.
1f50: 20 54 68 65 20 63 61 6c 6c 65 72 20 6d 75 73 74   The caller must
1f60: 20 65 6e 73 75 72 65 20 74 68 61 74 20 74 68 65   ensure that the
1f70: 72 65 0a 2a 2a 20 61 72 65 20 6e 6f 20 6f 75 74  re.** are no out
1f80: 73 74 61 6e 64 69 6e 67 20 70 61 67 65 20 72 65  standing page re
1f90: 66 65 72 65 6e 63 65 73 20 77 68 65 6e 20 74 68  ferences when th
1fa0: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63  is function is c
1fb0: 61 6c 6c 65 64 2e 0a 2a 2f 0a 69 6e 74 20 73 71  alled..*/.int sq
1fc0: 6c 69 74 65 33 50 63 61 63 68 65 53 65 74 50 61  lite3PcacheSetPa
1fd0: 67 65 53 69 7a 65 28 50 43 61 63 68 65 20 2a 70  geSize(PCache *p
1fe0: 43 61 63 68 65 2c 20 69 6e 74 20 73 7a 50 61 67  Cache, int szPag
1ff0: 65 29 7b 0a 20 20 61 73 73 65 72 74 28 20 70 43  e){.  assert( pC
2000: 61 63 68 65 2d 3e 6e 52 65 66 53 75 6d 3d 3d 30  ache->nRefSum==0
2010: 20 26 26 20 70 43 61 63 68 65 2d 3e 70 44 69 72   && pCache->pDir
2020: 74 79 3d 3d 30 20 29 3b 0a 20 20 69 66 28 20 70  ty==0 );.  if( p
2030: 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 20 29 7b  Cache->szPage ){
2040: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 70 63 61  .    sqlite3_pca
2050: 63 68 65 20 2a 70 4e 65 77 3b 0a 20 20 20 20 70  che *pNew;.    p
2060: 4e 65 77 20 3d 20 73 71 6c 69 74 65 33 47 6c 6f  New = sqlite3Glo
2070: 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65  balConfig.pcache
2080: 32 2e 78 43 72 65 61 74 65 28 0a 20 20 20 20 20  2.xCreate(.     
2090: 20 20 20 20 20 20 20 20 20 20 20 73 7a 50 61 67             szPag
20a0: 65 2c 20 70 43 61 63 68 65 2d 3e 73 7a 45 78 74  e, pCache->szExt
20b0: 72 61 20 2b 20 52 4f 55 4e 44 38 28 73 69 7a 65  ra + ROUND8(size
20c0: 6f 66 28 50 67 48 64 72 29 29 2c 0a 20 20 20 20  of(PgHdr)),.    
20d0: 20 20 20 20 20 20 20 20 20 20 20 20 70 43 61 63              pCac
20e0: 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 0a 20  he->bPurgeable. 
20f0: 20 20 20 29 3b 0a 20 20 20 20 69 66 28 20 70 4e     );.    if( pN
2100: 65 77 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53  ew==0 ) return S
2110: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 5f 42 4b 50 54  QLITE_NOMEM_BKPT
2120: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 47 6c 6f  ;.    sqlite3Glo
2130: 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65  balConfig.pcache
2140: 32 2e 78 43 61 63 68 65 73 69 7a 65 28 70 4e 65  2.xCachesize(pNe
2150: 77 2c 20 6e 75 6d 62 65 72 4f 66 43 61 63 68 65  w, numberOfCache
2160: 50 61 67 65 73 28 70 43 61 63 68 65 29 29 3b 0a  Pages(pCache));.
2170: 20 20 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e      if( pCache->
2180: 70 43 61 63 68 65 20 29 7b 0a 20 20 20 20 20 20  pCache ){.      
2190: 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e  sqlite3GlobalCon
21a0: 66 69 67 2e 70 63 61 63 68 65 32 2e 78 44 65 73  fig.pcache2.xDes
21b0: 74 72 6f 79 28 70 43 61 63 68 65 2d 3e 70 43 61  troy(pCache->pCa
21c0: 63 68 65 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20  che);.    }.    
21d0: 70 43 61 63 68 65 2d 3e 70 43 61 63 68 65 20 3d  pCache->pCache =
21e0: 20 70 4e 65 77 3b 0a 20 20 20 20 70 43 61 63 68   pNew;.    pCach
21f0: 65 2d 3e 73 7a 50 61 67 65 20 3d 20 73 7a 50 61  e->szPage = szPa
2200: 67 65 3b 0a 20 20 20 20 70 63 61 63 68 65 54 72  ge;.    pcacheTr
2210: 61 63 65 28 28 22 25 70 2e 50 41 47 45 53 49 5a  ace(("%p.PAGESIZ
2220: 45 20 25 64 5c 6e 22 2c 70 43 61 63 68 65 2c 73  E %d\n",pCache,s
2230: 7a 50 61 67 65 29 29 3b 0a 20 20 7d 0a 20 20 72  zPage));.  }.  r
2240: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
2250: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 72 79 20 74 6f  .}../*.** Try to
2260: 20 6f 62 74 61 69 6e 20 61 20 70 61 67 65 20 66   obtain a page f
2270: 72 6f 6d 20 74 68 65 20 63 61 63 68 65 2e 0a 2a  rom the cache..*
2280: 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e  *.** This routin
2290: 65 20 72 65 74 75 72 6e 73 20 61 20 70 6f 69 6e  e returns a poin
22a0: 74 65 72 20 74 6f 20 61 6e 20 73 71 6c 69 74 65  ter to an sqlite
22b0: 33 5f 70 63 61 63 68 65 5f 70 61 67 65 20 6f 62  3_pcache_page ob
22c0: 6a 65 63 74 20 69 66 0a 2a 2a 20 73 75 63 68 20  ject if.** such 
22d0: 61 6e 20 6f 62 6a 65 63 74 20 69 73 20 61 6c 72  an object is alr
22e0: 65 61 64 79 20 69 6e 20 63 61 63 68 65 2c 20 6f  eady in cache, o
22f0: 72 20 69 66 20 61 20 6e 65 77 20 6f 6e 65 20 69  r if a new one i
2300: 73 20 63 72 65 61 74 65 64 2e 0a 2a 2a 20 54 68  s created..** Th
2310: 69 73 20 72 6f 75 74 69 6e 65 20 72 65 74 75 72  is routine retur
2320: 6e 73 20 61 20 4e 55 4c 4c 20 70 6f 69 6e 74 65  ns a NULL pointe
2330: 72 20 69 66 20 74 68 65 20 6f 62 6a 65 63 74 20  r if the object 
2340: 77 61 73 20 6e 6f 74 20 69 6e 20 63 61 63 68 65  was not in cache
2350: 0a 2a 2a 20 61 6e 64 20 63 6f 75 6c 64 20 6e 6f  .** and could no
2360: 74 20 62 65 20 63 72 65 61 74 65 64 2e 0a 2a 2a  t be created..**
2370: 0a 2a 2a 20 54 68 65 20 63 72 65 61 74 65 46 6c  .** The createFl
2380: 61 67 73 20 73 68 6f 75 6c 64 20 62 65 20 30 20  ags should be 0 
2390: 74 6f 20 63 68 65 63 6b 20 66 6f 72 20 65 78 69  to check for exi
23a0: 73 74 69 6e 67 20 70 61 67 65 73 20 61 6e 64 20  sting pages and 
23b0: 73 68 6f 75 6c 64 0a 2a 2a 20 62 65 20 33 20 28  should.** be 3 (
23c0: 6e 6f 74 20 31 2c 20 62 75 74 20 33 29 20 74 6f  not 1, but 3) to
23d0: 20 74 72 79 20 74 6f 20 63 72 65 61 74 65 20 61   try to create a
23e0: 20 6e 65 77 20 70 61 67 65 2e 0a 2a 2a 0a 2a 2a   new page..**.**
23f0: 20 49 66 20 74 68 65 20 63 72 65 61 74 65 46 6c   If the createFl
2400: 61 67 20 69 73 20 30 2c 20 74 68 65 6e 20 4e 55  ag is 0, then NU
2410: 4c 4c 20 69 73 20 61 6c 77 61 79 73 20 72 65 74  LL is always ret
2420: 75 72 6e 65 64 20 69 66 20 74 68 65 20 70 61 67  urned if the pag
2430: 65 0a 2a 2a 20 69 73 20 6e 6f 74 20 61 6c 72 65  e.** is not alre
2440: 61 64 79 20 69 6e 20 74 68 65 20 63 61 63 68 65  ady in the cache
2450: 2e 20 20 49 66 20 63 72 65 61 74 65 46 6c 61 67  .  If createFlag
2460: 20 69 73 20 31 2c 20 74 68 65 6e 20 61 20 6e 65   is 1, then a ne
2470: 77 20 70 61 67 65 0a 2a 2a 20 69 73 20 63 72 65  w page.** is cre
2480: 61 74 65 64 20 6f 6e 6c 79 20 69 66 20 74 68 61  ated only if tha
2490: 74 20 63 61 6e 20 62 65 20 64 6f 6e 65 20 77 69  t can be done wi
24a0: 74 68 6f 75 74 20 73 70 69 6c 6c 69 6e 67 20 64  thout spilling d
24b0: 69 72 74 79 20 70 61 67 65 73 0a 2a 2a 20 61 6e  irty pages.** an
24c0: 64 20 77 69 74 68 6f 75 74 20 65 78 63 65 65 64  d without exceed
24d0: 69 6e 67 20 74 68 65 20 63 61 63 68 65 20 73 69  ing the cache si
24e0: 7a 65 20 6c 69 6d 69 74 2e 0a 2a 2a 0a 2a 2a 20  ze limit..**.** 
24f0: 54 68 65 20 63 61 6c 6c 65 72 20 6e 65 65 64 73  The caller needs
2500: 20 74 6f 20 69 6e 76 6f 6b 65 20 73 71 6c 69 74   to invoke sqlit
2510: 65 33 50 63 61 63 68 65 46 65 74 63 68 46 69 6e  e3PcacheFetchFin
2520: 69 73 68 28 29 20 74 6f 20 70 72 6f 70 65 72 6c  ish() to properl
2530: 79 0a 2a 2a 20 69 6e 69 74 69 61 6c 69 7a 65 20  y.** initialize 
2540: 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63  the sqlite3_pcac
2550: 68 65 5f 70 61 67 65 20 6f 62 6a 65 63 74 20 61  he_page object a
2560: 6e 64 20 63 6f 6e 76 65 72 74 20 69 74 20 69 6e  nd convert it in
2570: 74 6f 20 61 0a 2a 2a 20 50 67 48 64 72 20 6f 62  to a.** PgHdr ob
2580: 6a 65 63 74 2e 20 20 54 68 65 20 73 71 6c 69 74  ject.  The sqlit
2590: 65 33 50 63 61 63 68 65 46 65 74 63 68 28 29 20  e3PcacheFetch() 
25a0: 61 6e 64 20 73 71 6c 69 74 65 33 50 63 61 63 68  and sqlite3Pcach
25b0: 65 46 65 74 63 68 46 69 6e 69 73 68 28 29 0a 2a  eFetchFinish().*
25c0: 2a 20 72 6f 75 74 69 6e 65 73 20 61 72 65 20 73  * routines are s
25d0: 70 6c 69 74 20 74 68 69 73 20 77 61 79 20 66 6f  plit this way fo
25e0: 72 20 70 65 72 66 6f 72 6d 61 6e 63 65 20 72 65  r performance re
25f0: 61 73 6f 6e 73 2e 20 57 68 65 6e 20 73 65 70 61  asons. When sepa
2600: 72 61 74 65 64 0a 2a 2a 20 74 68 65 79 20 63 61  rated.** they ca
2610: 6e 20 62 6f 74 68 20 28 75 73 75 61 6c 6c 79 29  n both (usually)
2620: 20 6f 70 65 72 61 74 65 20 77 69 74 68 6f 75 74   operate without
2630: 20 68 61 76 69 6e 67 20 74 6f 20 70 75 73 68 20   having to push 
2640: 76 61 6c 75 65 73 20 74 6f 0a 2a 2a 20 74 68 65  values to.** the
2650: 20 73 74 61 63 6b 20 6f 6e 20 65 6e 74 72 79 20   stack on entry 
2660: 61 6e 64 20 70 6f 70 20 74 68 65 6d 20 62 61 63  and pop them bac
2670: 6b 20 6f 66 66 20 6f 6e 20 65 78 69 74 2c 20 77  k off on exit, w
2680: 68 69 63 68 20 73 61 76 65 73 20 61 0a 2a 2a 20  hich saves a.** 
2690: 6c 6f 74 20 6f 66 20 70 75 73 68 69 6e 67 20 61  lot of pushing a
26a0: 6e 64 20 70 6f 70 70 69 6e 67 2e 0a 2a 2f 0a 73  nd popping..*/.s
26b0: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 5f 70 61  qlite3_pcache_pa
26c0: 67 65 20 2a 73 71 6c 69 74 65 33 50 63 61 63 68  ge *sqlite3Pcach
26d0: 65 46 65 74 63 68 28 0a 20 20 50 43 61 63 68 65  eFetch(.  PCache
26e0: 20 2a 70 43 61 63 68 65 2c 20 20 20 20 20 20 20   *pCache,       
26f0: 2f 2a 20 4f 62 74 61 69 6e 20 74 68 65 20 70 61  /* Obtain the pa
2700: 67 65 20 66 72 6f 6d 20 74 68 69 73 20 63 61 63  ge from this cac
2710: 68 65 20 2a 2f 0a 20 20 50 67 6e 6f 20 70 67 6e  he */.  Pgno pgn
2720: 6f 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  o,            /*
2730: 20 50 61 67 65 20 6e 75 6d 62 65 72 20 74 6f 20   Page number to 
2740: 6f 62 74 61 69 6e 20 2a 2f 0a 20 20 69 6e 74 20  obtain */.  int 
2750: 63 72 65 61 74 65 46 6c 61 67 20 20 20 20 20 20  createFlag      
2760: 20 20 2f 2a 20 49 66 20 74 72 75 65 2c 20 63 72    /* If true, cr
2770: 65 61 74 65 20 70 61 67 65 20 69 66 20 69 74 20  eate page if it 
2780: 64 6f 65 73 20 6e 6f 74 20 65 78 69 73 74 20 61  does not exist a
2790: 6c 72 65 61 64 79 20 2a 2f 0a 29 7b 0a 20 20 69  lready */.){.  i
27a0: 6e 74 20 65 43 72 65 61 74 65 3b 0a 20 20 73 71  nt eCreate;.  sq
27b0: 6c 69 74 65 33 5f 70 63 61 63 68 65 5f 70 61 67  lite3_pcache_pag
27c0: 65 20 2a 70 52 65 73 3b 0a 0a 20 20 61 73 73 65  e *pRes;..  asse
27d0: 72 74 28 20 70 43 61 63 68 65 21 3d 30 20 29 3b  rt( pCache!=0 );
27e0: 0a 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68  .  assert( pCach
27f0: 65 2d 3e 70 43 61 63 68 65 21 3d 30 20 29 3b 0a  e->pCache!=0 );.
2800: 20 20 61 73 73 65 72 74 28 20 63 72 65 61 74 65    assert( create
2810: 46 6c 61 67 3d 3d 33 20 7c 7c 20 63 72 65 61 74  Flag==3 || creat
2820: 65 46 6c 61 67 3d 3d 30 20 29 3b 0a 20 20 61 73  eFlag==0 );.  as
2830: 73 65 72 74 28 20 70 67 6e 6f 3e 30 20 29 3b 0a  sert( pgno>0 );.
2840: 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65    assert( pCache
2850: 2d 3e 65 43 72 65 61 74 65 3d 3d 28 28 70 43 61  ->eCreate==((pCa
2860: 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20  che->bPurgeable 
2870: 26 26 20 70 43 61 63 68 65 2d 3e 70 44 69 72 74  && pCache->pDirt
2880: 79 29 20 3f 20 32 20 3a 20 31 29 20 29 3b 0a 0a  y) ? 2 : 1) );..
2890: 20 20 2f 2a 20 65 43 72 65 61 74 65 20 64 65 66    /* eCreate def
28a0: 69 6e 65 73 20 77 68 61 74 20 74 6f 20 64 6f 20  ines what to do 
28b0: 69 66 20 74 68 65 20 70 61 67 65 20 64 6f 65 73  if the page does
28c0: 20 6e 6f 74 20 65 78 69 73 74 2e 0a 20 20 2a 2a   not exist..  **
28d0: 20 20 20 20 30 20 20 20 20 20 44 6f 20 6e 6f 74      0     Do not
28e0: 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20   allocate a new 
28f0: 70 61 67 65 2e 20 20 28 63 72 65 61 74 65 46 6c  page.  (createFl
2900: 61 67 3d 3d 30 29 0a 20 20 2a 2a 20 20 20 20 31  ag==0).  **    1
2910: 20 20 20 20 20 41 6c 6c 6f 63 61 74 65 20 61 20       Allocate a 
2920: 6e 65 77 20 70 61 67 65 20 69 66 20 64 6f 69 6e  new page if doin
2930: 67 20 73 6f 20 69 73 20 69 6e 65 78 70 65 6e 73  g so is inexpens
2940: 69 76 65 2e 0a 20 20 2a 2a 20 20 20 20 20 20 20  ive..  **       
2950: 20 20 20 28 63 72 65 61 74 65 46 6c 61 67 3d 3d     (createFlag==
2960: 31 20 41 4e 44 20 62 50 75 72 67 65 61 62 6c 65  1 AND bPurgeable
2970: 20 41 4e 44 20 70 44 69 72 74 79 29 0a 20 20 2a   AND pDirty).  *
2980: 2a 20 20 20 20 32 20 20 20 20 20 41 6c 6c 6f 63  *    2     Alloc
2990: 61 74 65 20 61 20 6e 65 77 20 70 61 67 65 20 65  ate a new page e
29a0: 76 65 6e 20 69 74 20 64 6f 69 6e 67 20 73 6f 20  ven it doing so 
29b0: 69 73 20 64 69 66 66 69 63 75 6c 74 2e 0a 20 20  is difficult..  
29c0: 2a 2a 20 20 20 20 20 20 20 20 20 20 28 63 72 65  **          (cre
29d0: 61 74 65 46 6c 61 67 3d 3d 31 20 41 4e 44 20 21  ateFlag==1 AND !
29e0: 28 62 50 75 72 67 65 61 62 6c 65 20 41 4e 44 20  (bPurgeable AND 
29f0: 70 44 69 72 74 79 29 0a 20 20 2a 2f 0a 20 20 65  pDirty).  */.  e
2a00: 43 72 65 61 74 65 20 3d 20 63 72 65 61 74 65 46  Create = createF
2a10: 6c 61 67 20 26 20 70 43 61 63 68 65 2d 3e 65 43  lag & pCache->eC
2a20: 72 65 61 74 65 3b 0a 20 20 61 73 73 65 72 74 28  reate;.  assert(
2a30: 20 65 43 72 65 61 74 65 3d 3d 30 20 7c 7c 20 65   eCreate==0 || e
2a40: 43 72 65 61 74 65 3d 3d 31 20 7c 7c 20 65 43 72  Create==1 || eCr
2a50: 65 61 74 65 3d 3d 32 20 29 3b 0a 20 20 61 73 73  eate==2 );.  ass
2a60: 65 72 74 28 20 63 72 65 61 74 65 46 6c 61 67 3d  ert( createFlag=
2a70: 3d 30 20 7c 7c 20 70 43 61 63 68 65 2d 3e 65 43  =0 || pCache->eC
2a80: 72 65 61 74 65 3d 3d 65 43 72 65 61 74 65 20 29  reate==eCreate )
2a90: 3b 0a 20 20 61 73 73 65 72 74 28 20 63 72 65 61  ;.  assert( crea
2aa0: 74 65 46 6c 61 67 3d 3d 30 20 7c 7c 20 65 43 72  teFlag==0 || eCr
2ab0: 65 61 74 65 3d 3d 31 2b 28 21 70 43 61 63 68 65  eate==1+(!pCache
2ac0: 2d 3e 62 50 75 72 67 65 61 62 6c 65 7c 7c 21 70  ->bPurgeable||!p
2ad0: 43 61 63 68 65 2d 3e 70 44 69 72 74 79 29 20 29  Cache->pDirty) )
2ae0: 3b 0a 20 20 70 52 65 73 20 3d 20 73 71 6c 69 74  ;.  pRes = sqlit
2af0: 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70  e3GlobalConfig.p
2b00: 63 61 63 68 65 32 2e 78 46 65 74 63 68 28 70 43  cache2.xFetch(pC
2b10: 61 63 68 65 2d 3e 70 43 61 63 68 65 2c 20 70 67  ache->pCache, pg
2b20: 6e 6f 2c 20 65 43 72 65 61 74 65 29 3b 0a 20 20  no, eCreate);.  
2b30: 70 63 61 63 68 65 54 72 61 63 65 28 28 22 25 70  pcacheTrace(("%p
2b40: 2e 46 45 54 43 48 20 25 64 25 73 20 28 72 65 73  .FETCH %d%s (res
2b50: 75 6c 74 3a 20 25 70 29 5c 6e 22 2c 70 43 61 63  ult: %p)\n",pCac
2b60: 68 65 2c 70 67 6e 6f 2c 0a 20 20 20 20 20 20 20  he,pgno,.       
2b70: 20 20 20 20 20 20 20 20 63 72 65 61 74 65 46 6c          createFl
2b80: 61 67 3f 22 20 63 72 65 61 74 65 22 3a 22 22 2c  ag?" create":"",
2b90: 70 52 65 73 29 29 3b 0a 20 20 72 65 74 75 72 6e  pRes));.  return
2ba0: 20 70 52 65 73 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20   pRes;.}../*.** 
2bb0: 49 66 20 74 68 65 20 73 71 6c 69 74 65 33 50 63  If the sqlite3Pc
2bc0: 61 63 68 65 46 65 74 63 68 28 29 20 72 6f 75 74  acheFetch() rout
2bd0: 69 6e 65 20 69 73 20 75 6e 61 62 6c 65 20 74 6f  ine is unable to
2be0: 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 0a   allocate a new.
2bf0: 2a 2a 20 70 61 67 65 20 62 65 63 61 75 73 65 20  ** page because 
2c00: 6e 6f 20 63 6c 65 61 6e 20 70 61 67 65 73 20 61  no clean pages a
2c10: 72 65 20 61 76 61 69 6c 61 62 6c 65 20 66 6f 72  re available for
2c20: 20 72 65 75 73 65 20 61 6e 64 20 74 68 65 20 63   reuse and the c
2c30: 61 63 68 65 0a 2a 2a 20 73 69 7a 65 20 6c 69 6d  ache.** size lim
2c40: 69 74 20 68 61 73 20 62 65 65 6e 20 72 65 61 63  it has been reac
2c50: 68 65 64 2c 20 74 68 65 6e 20 74 68 69 73 20 72  hed, then this r
2c60: 6f 75 74 69 6e 65 20 63 61 6e 20 62 65 20 69 6e  outine can be in
2c70: 76 6f 6b 65 64 20 74 6f 20 0a 2a 2a 20 74 72 79  voked to .** try
2c80: 20 68 61 72 64 65 72 20 74 6f 20 61 6c 6c 6f 63   harder to alloc
2c90: 61 74 65 20 61 20 70 61 67 65 2e 20 20 54 68 69  ate a page.  Thi
2ca0: 73 20 72 6f 75 74 69 6e 65 20 6d 69 67 68 74 20  s routine might 
2cb0: 69 6e 76 6f 6b 65 20 74 68 65 20 73 74 72 65 73  invoke the stres
2cc0: 73 0a 2a 2a 20 63 61 6c 6c 62 61 63 6b 20 74 6f  s.** callback to
2cd0: 20 73 70 69 6c 6c 20 64 69 72 74 79 20 70 61 67   spill dirty pag
2ce0: 65 73 20 74 6f 20 74 68 65 20 6a 6f 75 72 6e 61  es to the journa
2cf0: 6c 2e 20 20 49 74 20 77 69 6c 6c 20 74 68 65 6e  l.  It will then
2d00: 20 74 72 79 20 74 6f 0a 2a 2a 20 61 6c 6c 6f 63   try to.** alloc
2d10: 61 74 65 20 74 68 65 20 6e 65 77 20 70 61 67 65  ate the new page
2d20: 20 61 6e 64 20 77 69 6c 6c 20 6f 6e 6c 79 20 66   and will only f
2d30: 61 69 6c 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20  ail to allocate 
2d40: 61 20 6e 65 77 20 70 61 67 65 20 6f 6e 0a 2a 2a  a new page on.**
2d50: 20 61 6e 20 4f 4f 4d 20 65 72 72 6f 72 2e 0a 2a   an OOM error..*
2d60: 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e  *.** This routin
2d70: 65 20 73 68 6f 75 6c 64 20 62 65 20 69 6e 76 6f  e should be invo
2d80: 6b 65 64 20 6f 6e 6c 79 20 61 66 74 65 72 20 73  ked only after s
2d90: 71 6c 69 74 65 33 50 63 61 63 68 65 46 65 74 63  qlite3PcacheFetc
2da0: 68 28 29 20 66 61 69 6c 73 2e 0a 2a 2f 0a 69 6e  h() fails..*/.in
2db0: 74 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 46  t sqlite3PcacheF
2dc0: 65 74 63 68 53 74 72 65 73 73 28 0a 20 20 50 43  etchStress(.  PC
2dd0: 61 63 68 65 20 2a 70 43 61 63 68 65 2c 20 20 20  ache *pCache,   
2de0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
2df0: 20 4f 62 74 61 69 6e 20 74 68 65 20 70 61 67 65   Obtain the page
2e00: 20 66 72 6f 6d 20 74 68 69 73 20 63 61 63 68 65   from this cache
2e10: 20 2a 2f 0a 20 20 50 67 6e 6f 20 70 67 6e 6f 2c   */.  Pgno pgno,
2e20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2e30: 20 20 20 20 20 20 2f 2a 20 50 61 67 65 20 6e 75        /* Page nu
2e40: 6d 62 65 72 20 74 6f 20 6f 62 74 61 69 6e 20 2a  mber to obtain *
2e50: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 70 63 61 63  /.  sqlite3_pcac
2e60: 68 65 5f 70 61 67 65 20 2a 2a 70 70 50 61 67 65  he_page **ppPage
2e70: 20 20 20 20 2f 2a 20 57 72 69 74 65 20 72 65 73      /* Write res
2e80: 75 6c 74 20 68 65 72 65 20 2a 2f 0a 29 7b 0a 20  ult here */.){. 
2e90: 20 50 67 48 64 72 20 2a 70 50 67 3b 0a 20 20 69   PgHdr *pPg;.  i
2ea0: 66 28 20 70 43 61 63 68 65 2d 3e 65 43 72 65 61  f( pCache->eCrea
2eb0: 74 65 3d 3d 32 20 29 20 72 65 74 75 72 6e 20 30  te==2 ) return 0
2ec0: 3b 0a 0a 20 20 69 66 28 20 73 71 6c 69 74 65 33  ;..  if( sqlite3
2ed0: 50 63 61 63 68 65 50 61 67 65 63 6f 75 6e 74 28  PcachePagecount(
2ee0: 70 43 61 63 68 65 29 3e 70 43 61 63 68 65 2d 3e  pCache)>pCache->
2ef0: 73 7a 53 70 69 6c 6c 20 29 7b 0a 20 20 20 20 2f  szSpill ){.    /
2f00: 2a 20 46 69 6e 64 20 61 20 64 69 72 74 79 20 70  * Find a dirty p
2f10: 61 67 65 20 74 6f 20 77 72 69 74 65 2d 6f 75 74  age to write-out
2f20: 20 61 6e 64 20 72 65 63 79 63 6c 65 2e 20 46 69   and recycle. Fi
2f30: 72 73 74 20 74 72 79 20 74 6f 20 66 69 6e 64 20  rst try to find 
2f40: 61 20 0a 20 20 20 20 2a 2a 20 70 61 67 65 20 74  a .    ** page t
2f50: 68 61 74 20 64 6f 65 73 20 6e 6f 74 20 72 65 71  hat does not req
2f60: 75 69 72 65 20 61 20 6a 6f 75 72 6e 61 6c 2d 73  uire a journal-s
2f70: 79 6e 63 20 28 6f 6e 65 20 77 69 74 68 20 50 47  ync (one with PG
2f80: 48 44 52 5f 4e 45 45 44 5f 53 59 4e 43 0a 20 20  HDR_NEED_SYNC.  
2f90: 20 20 2a 2a 20 63 6c 65 61 72 65 64 29 2c 20 62    ** cleared), b
2fa0: 75 74 20 69 66 20 74 68 61 74 20 69 73 20 6e 6f  ut if that is no
2fb0: 74 20 70 6f 73 73 69 62 6c 65 20 73 65 74 74 6c  t possible settl
2fc0: 65 20 66 6f 72 20 61 6e 79 20 6f 74 68 65 72 20  e for any other 
2fd0: 0a 20 20 20 20 2a 2a 20 75 6e 72 65 66 65 72 65  .    ** unrefere
2fe0: 6e 63 65 64 20 64 69 72 74 79 20 70 61 67 65 2e  nced dirty page.
2ff0: 0a 20 20 20 20 2a 2a 0a 20 20 20 20 2a 2a 20 49  .    **.    ** I
3000: 66 20 74 68 65 20 4c 52 55 20 70 61 67 65 20 69  f the LRU page i
3010: 6e 20 74 68 65 20 64 69 72 74 79 20 6c 69 73 74  n the dirty list
3020: 20 74 68 61 74 20 68 61 73 20 61 20 63 6c 65 61   that has a clea
3030: 72 20 50 47 48 44 52 5f 4e 45 45 44 5f 53 59 4e  r PGHDR_NEED_SYN
3040: 43 0a 20 20 20 20 2a 2a 20 66 6c 61 67 20 69 73  C.    ** flag is
3050: 20 63 75 72 72 65 6e 74 6c 79 20 72 65 66 65 72   currently refer
3060: 65 6e 63 65 64 2c 20 74 68 65 6e 20 74 68 65 20  enced, then the 
3070: 66 6f 6c 6c 6f 77 69 6e 67 20 6d 61 79 20 6c 65  following may le
3080: 61 76 65 20 70 53 79 6e 63 65 64 0a 20 20 20 20  ave pSynced.    
3090: 2a 2a 20 73 65 74 20 69 6e 63 6f 72 72 65 63 74  ** set incorrect
30a0: 6c 79 20 28 70 6f 69 6e 74 69 6e 67 20 74 6f 20  ly (pointing to 
30b0: 6f 74 68 65 72 20 74 68 61 6e 20 74 68 65 20 4c  other than the L
30c0: 52 55 20 70 61 67 65 20 77 69 74 68 20 4e 45 45  RU page with NEE
30d0: 44 5f 53 59 4e 43 0a 20 20 20 20 2a 2a 20 63 6c  D_SYNC.    ** cl
30e0: 65 61 72 65 64 29 2e 20 54 68 69 73 20 69 73 20  eared). This is 
30f0: 4f 6b 2c 20 61 73 20 70 53 79 6e 63 65 64 20 69  Ok, as pSynced i
3100: 73 20 6a 75 73 74 20 61 6e 20 6f 70 74 69 6d 69  s just an optimi
3110: 7a 61 74 69 6f 6e 2e 20 20 2a 2f 0a 20 20 20 20  zation.  */.    
3120: 66 6f 72 28 70 50 67 3d 70 43 61 63 68 65 2d 3e  for(pPg=pCache->
3130: 70 53 79 6e 63 65 64 3b 20 0a 20 20 20 20 20 20  pSynced; .      
3140: 20 20 70 50 67 20 26 26 20 28 70 50 67 2d 3e 6e    pPg && (pPg->n
3150: 52 65 66 20 7c 7c 20 28 70 50 67 2d 3e 66 6c 61  Ref || (pPg->fla
3160: 67 73 26 50 47 48 44 52 5f 4e 45 45 44 5f 53 59  gs&PGHDR_NEED_SY
3170: 4e 43 29 29 3b 20 0a 20 20 20 20 20 20 20 20 70  NC)); .        p
3180: 50 67 3d 70 50 67 2d 3e 70 44 69 72 74 79 50 72  Pg=pPg->pDirtyPr
3190: 65 76 0a 20 20 20 20 29 3b 0a 20 20 20 20 70 43  ev.    );.    pC
31a0: 61 63 68 65 2d 3e 70 53 79 6e 63 65 64 20 3d 20  ache->pSynced = 
31b0: 70 50 67 3b 0a 20 20 20 20 69 66 28 20 21 70 50  pPg;.    if( !pP
31c0: 67 20 29 7b 0a 20 20 20 20 20 20 66 6f 72 28 70  g ){.      for(p
31d0: 50 67 3d 70 43 61 63 68 65 2d 3e 70 44 69 72 74  Pg=pCache->pDirt
31e0: 79 54 61 69 6c 3b 20 70 50 67 20 26 26 20 70 50  yTail; pPg && pP
31f0: 67 2d 3e 6e 52 65 66 3b 20 70 50 67 3d 70 50 67  g->nRef; pPg=pPg
3200: 2d 3e 70 44 69 72 74 79 50 72 65 76 29 3b 0a 20  ->pDirtyPrev);. 
3210: 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70 50 67     }.    if( pPg
3220: 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 72 63   ){.      int rc
3230: 3b 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f  ;.#ifdef SQLITE_
3240: 4c 4f 47 5f 43 41 43 48 45 5f 53 50 49 4c 4c 0a  LOG_CACHE_SPILL.
3250: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 6c 6f        sqlite3_lo
3260: 67 28 53 51 4c 49 54 45 5f 46 55 4c 4c 2c 20 0a  g(SQLITE_FULL, .
3270: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3280: 20 20 22 73 70 69 6c 6c 20 70 61 67 65 20 25 64    "spill page %d
3290: 20 6d 61 6b 69 6e 67 20 72 6f 6f 6d 20 66 6f 72   making room for
32a0: 20 25 64 20 2d 20 63 61 63 68 65 20 75 73 65 64   %d - cache used
32b0: 3a 20 25 64 2f 25 64 22 2c 0a 20 20 20 20 20 20  : %d/%d",.      
32c0: 20 20 20 20 20 20 20 20 20 20 20 20 70 50 67 2d              pPg-
32d0: 3e 70 67 6e 6f 2c 20 70 67 6e 6f 2c 0a 20 20 20  >pgno, pgno,.   
32e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73                 s
32f0: 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66  qlite3GlobalConf
3300: 69 67 2e 70 63 61 63 68 65 2e 78 50 61 67 65 63  ig.pcache.xPagec
3310: 6f 75 6e 74 28 70 43 61 63 68 65 2d 3e 70 43 61  ount(pCache->pCa
3320: 63 68 65 29 2c 0a 20 20 20 20 20 20 20 20 20 20  che),.          
3330: 20 20 20 20 20 20 6e 75 6d 62 65 72 4f 66 43 61        numberOfCa
3340: 63 68 65 50 61 67 65 73 28 70 43 61 63 68 65 29  chePages(pCache)
3350: 29 3b 0a 23 65 6e 64 69 66 0a 20 20 20 20 20 20  );.#endif.      
3360: 70 63 61 63 68 65 54 72 61 63 65 28 28 22 25 70  pcacheTrace(("%p
3370: 2e 53 50 49 4c 4c 20 25 64 5c 6e 22 2c 70 43 61  .SPILL %d\n",pCa
3380: 63 68 65 2c 70 50 67 2d 3e 70 67 6e 6f 29 29 3b  che,pPg->pgno));
3390: 0a 20 20 20 20 20 20 72 63 20 3d 20 70 43 61 63  .      rc = pCac
33a0: 68 65 2d 3e 78 53 74 72 65 73 73 28 70 43 61 63  he->xStress(pCac
33b0: 68 65 2d 3e 70 53 74 72 65 73 73 2c 20 70 50 67  he->pStress, pPg
33c0: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 21  );.      if( rc!
33d0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 72 63  =SQLITE_OK && rc
33e0: 21 3d 53 51 4c 49 54 45 5f 42 55 53 59 20 29 7b  !=SQLITE_BUSY ){
33f0: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
3400: 72 63 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  rc;.      }.    
3410: 7d 0a 20 20 7d 0a 20 20 2a 70 70 50 61 67 65 20  }.  }.  *ppPage 
3420: 3d 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43  = sqlite3GlobalC
3430: 6f 6e 66 69 67 2e 70 63 61 63 68 65 32 2e 78 46  onfig.pcache2.xF
3440: 65 74 63 68 28 70 43 61 63 68 65 2d 3e 70 43 61  etch(pCache->pCa
3450: 63 68 65 2c 20 70 67 6e 6f 2c 20 32 29 3b 0a 20  che, pgno, 2);. 
3460: 20 72 65 74 75 72 6e 20 2a 70 70 50 61 67 65 3d   return *ppPage=
3470: 3d 30 20 3f 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  =0 ? SQLITE_NOME
3480: 4d 5f 42 4b 50 54 20 3a 20 53 51 4c 49 54 45 5f  M_BKPT : SQLITE_
3490: 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69  OK;.}../*.** Thi
34a0: 73 20 69 73 20 61 20 68 65 6c 70 65 72 20 72 6f  s is a helper ro
34b0: 75 74 69 6e 65 20 66 6f 72 20 73 71 6c 69 74 65  utine for sqlite
34c0: 33 50 63 61 63 68 65 46 65 74 63 68 46 69 6e 69  3PcacheFetchFini
34d0: 73 68 28 29 0a 2a 2a 0a 2a 2a 20 49 6e 20 74 68  sh().**.** In th
34e0: 65 20 75 6e 63 6f 6d 6d 6f 6e 20 63 61 73 65 20  e uncommon case 
34f0: 77 68 65 72 65 20 74 68 65 20 70 61 67 65 20 62  where the page b
3500: 65 69 6e 67 20 66 65 74 63 68 65 64 20 68 61 73  eing fetched has
3510: 20 6e 6f 74 20 62 65 65 6e 0a 2a 2a 20 69 6e 69   not been.** ini
3520: 74 69 61 6c 69 7a 65 64 2c 20 74 68 69 73 20 72  tialized, this r
3530: 6f 75 74 69 6e 65 20 69 73 20 69 6e 76 6f 6b 65  outine is invoke
3540: 64 20 74 6f 20 64 6f 20 74 68 65 20 69 6e 69 74  d to do the init
3550: 69 61 6c 69 7a 61 74 69 6f 6e 2e 0a 2a 2a 20 54  ialization..** T
3560: 68 69 73 20 72 6f 75 74 69 6e 65 20 69 73 20 62  his routine is b
3570: 72 6f 6b 65 6e 20 6f 75 74 20 69 6e 74 6f 20 61  roken out into a
3580: 20 73 65 70 61 72 61 74 65 20 66 75 6e 63 74 69   separate functi
3590: 6f 6e 20 73 69 6e 63 65 20 69 74 0a 2a 2a 20 72  on since it.** r
35a0: 65 71 75 69 72 65 73 20 65 78 74 72 61 20 73 74  equires extra st
35b0: 61 63 6b 20 6d 61 6e 69 70 75 6c 61 74 69 6f 6e  ack manipulation
35c0: 20 74 68 61 74 20 63 61 6e 20 62 65 20 61 76 6f   that can be avo
35d0: 69 64 65 64 20 69 6e 20 74 68 65 20 63 6f 6d 6d  ided in the comm
35e0: 6f 6e 0a 2a 2a 20 63 61 73 65 2e 0a 2a 2f 0a 73  on.** case..*/.s
35f0: 74 61 74 69 63 20 53 51 4c 49 54 45 5f 4e 4f 49  tatic SQLITE_NOI
3600: 4e 4c 49 4e 45 20 50 67 48 64 72 20 2a 70 63 61  NLINE PgHdr *pca
3610: 63 68 65 46 65 74 63 68 46 69 6e 69 73 68 57 69  cheFetchFinishWi
3620: 74 68 49 6e 69 74 28 0a 20 20 50 43 61 63 68 65  thInit(.  PCache
3630: 20 2a 70 43 61 63 68 65 2c 20 20 20 20 20 20 20   *pCache,       
3640: 20 20 20 20 20 20 2f 2a 20 4f 62 74 61 69 6e 20        /* Obtain 
3650: 74 68 65 20 70 61 67 65 20 66 72 6f 6d 20 74 68  the page from th
3660: 69 73 20 63 61 63 68 65 20 2a 2f 0a 20 20 50 67  is cache */.  Pg
3670: 6e 6f 20 70 67 6e 6f 2c 20 20 20 20 20 20 20 20  no pgno,        
3680: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67            /* Pag
3690: 65 20 6e 75 6d 62 65 72 20 6f 62 74 61 69 6e 65  e number obtaine
36a0: 64 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 70  d */.  sqlite3_p
36b0: 63 61 63 68 65 5f 70 61 67 65 20 2a 70 50 61 67  cache_page *pPag
36c0: 65 20 20 2f 2a 20 50 61 67 65 20 6f 62 74 61 69  e  /* Page obtai
36d0: 6e 65 64 20 62 79 20 70 72 69 6f 72 20 50 63 61  ned by prior Pca
36e0: 63 68 65 46 65 74 63 68 28 29 20 63 61 6c 6c 20  cheFetch() call 
36f0: 2a 2f 0a 29 7b 0a 20 20 50 67 48 64 72 20 2a 70  */.){.  PgHdr *p
3700: 50 67 48 64 72 3b 0a 20 20 61 73 73 65 72 74 28  PgHdr;.  assert(
3710: 20 70 50 61 67 65 21 3d 30 20 29 3b 0a 20 20 70   pPage!=0 );.  p
3720: 50 67 48 64 72 20 3d 20 28 50 67 48 64 72 2a 29  PgHdr = (PgHdr*)
3730: 70 50 61 67 65 2d 3e 70 45 78 74 72 61 3b 0a 20  pPage->pExtra;. 
3740: 20 61 73 73 65 72 74 28 20 70 50 67 48 64 72 2d   assert( pPgHdr-
3750: 3e 70 50 61 67 65 3d 3d 30 20 29 3b 0a 20 20 6d  >pPage==0 );.  m
3760: 65 6d 73 65 74 28 70 50 67 48 64 72 2c 20 30 2c  emset(pPgHdr, 0,
3770: 20 73 69 7a 65 6f 66 28 50 67 48 64 72 29 29 3b   sizeof(PgHdr));
3780: 0a 20 20 70 50 67 48 64 72 2d 3e 70 50 61 67 65  .  pPgHdr->pPage
3790: 20 3d 20 70 50 61 67 65 3b 0a 20 20 70 50 67 48   = pPage;.  pPgH
37a0: 64 72 2d 3e 70 44 61 74 61 20 3d 20 70 50 61 67  dr->pData = pPag
37b0: 65 2d 3e 70 42 75 66 3b 0a 20 20 70 50 67 48 64  e->pBuf;.  pPgHd
37c0: 72 2d 3e 70 45 78 74 72 61 20 3d 20 28 76 6f 69  r->pExtra = (voi
37d0: 64 20 2a 29 26 70 50 67 48 64 72 5b 31 5d 3b 0a  d *)&pPgHdr[1];.
37e0: 20 20 6d 65 6d 73 65 74 28 70 50 67 48 64 72 2d    memset(pPgHdr-
37f0: 3e 70 45 78 74 72 61 2c 20 30 2c 20 70 43 61 63  >pExtra, 0, pCac
3800: 68 65 2d 3e 73 7a 45 78 74 72 61 29 3b 0a 20 20  he->szExtra);.  
3810: 70 50 67 48 64 72 2d 3e 70 43 61 63 68 65 20 3d  pPgHdr->pCache =
3820: 20 70 43 61 63 68 65 3b 0a 20 20 70 50 67 48 64   pCache;.  pPgHd
3830: 72 2d 3e 70 67 6e 6f 20 3d 20 70 67 6e 6f 3b 0a  r->pgno = pgno;.
3840: 20 20 70 50 67 48 64 72 2d 3e 66 6c 61 67 73 20    pPgHdr->flags 
3850: 3d 20 50 47 48 44 52 5f 43 4c 45 41 4e 3b 0a 20  = PGHDR_CLEAN;. 
3860: 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 50   return sqlite3P
3870: 63 61 63 68 65 46 65 74 63 68 46 69 6e 69 73 68  cacheFetchFinish
3880: 28 70 43 61 63 68 65 2c 70 67 6e 6f 2c 70 50 61  (pCache,pgno,pPa
3890: 67 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68  ge);.}../*.** Th
38a0: 69 73 20 72 6f 75 74 69 6e 65 20 63 6f 6e 76 65  is routine conve
38b0: 72 74 73 20 74 68 65 20 73 71 6c 69 74 65 33 5f  rts the sqlite3_
38c0: 70 63 61 63 68 65 5f 70 61 67 65 20 6f 62 6a 65  pcache_page obje
38d0: 63 74 20 72 65 74 75 72 6e 65 64 20 62 79 0a 2a  ct returned by.*
38e0: 2a 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 46  * sqlite3PcacheF
38f0: 65 74 63 68 28 29 20 69 6e 74 6f 20 61 6e 20 69  etch() into an i
3900: 6e 69 74 69 61 6c 69 7a 65 64 20 50 67 48 64 72  nitialized PgHdr
3910: 20 6f 62 6a 65 63 74 2e 20 20 54 68 69 73 20 72   object.  This r
3920: 6f 75 74 69 6e 65 0a 2a 2a 20 6d 75 73 74 20 62  outine.** must b
3930: 65 20 63 61 6c 6c 65 64 20 61 66 74 65 72 20 73  e called after s
3940: 71 6c 69 74 65 33 50 63 61 63 68 65 46 65 74 63  qlite3PcacheFetc
3950: 68 28 29 20 69 6e 20 6f 72 64 65 72 20 74 6f 20  h() in order to 
3960: 67 65 74 20 61 20 75 73 61 62 6c 65 0a 2a 2a 20  get a usable.** 
3970: 72 65 73 75 6c 74 2e 0a 2a 2f 0a 50 67 48 64 72  result..*/.PgHdr
3980: 20 2a 73 71 6c 69 74 65 33 50 63 61 63 68 65 46   *sqlite3PcacheF
3990: 65 74 63 68 46 69 6e 69 73 68 28 0a 20 20 50 43  etchFinish(.  PC
39a0: 61 63 68 65 20 2a 70 43 61 63 68 65 2c 20 20 20  ache *pCache,   
39b0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 62 74            /* Obt
39c0: 61 69 6e 20 74 68 65 20 70 61 67 65 20 66 72 6f  ain the page fro
39d0: 6d 20 74 68 69 73 20 63 61 63 68 65 20 2a 2f 0a  m this cache */.
39e0: 20 20 50 67 6e 6f 20 70 67 6e 6f 2c 20 20 20 20    Pgno pgno,    
39f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3a00: 20 50 61 67 65 20 6e 75 6d 62 65 72 20 6f 62 74   Page number obt
3a10: 61 69 6e 65 64 20 2a 2f 0a 20 20 73 71 6c 69 74  ained */.  sqlit
3a20: 65 33 5f 70 63 61 63 68 65 5f 70 61 67 65 20 2a  e3_pcache_page *
3a30: 70 50 61 67 65 20 20 2f 2a 20 50 61 67 65 20 6f  pPage  /* Page o
3a40: 62 74 61 69 6e 65 64 20 62 79 20 70 72 69 6f 72  btained by prior
3a50: 20 50 63 61 63 68 65 46 65 74 63 68 28 29 20 63   PcacheFetch() c
3a60: 61 6c 6c 20 2a 2f 0a 29 7b 0a 20 20 50 67 48 64  all */.){.  PgHd
3a70: 72 20 2a 70 50 67 48 64 72 3b 0a 0a 20 20 61 73  r *pPgHdr;..  as
3a80: 73 65 72 74 28 20 70 50 61 67 65 21 3d 30 20 29  sert( pPage!=0 )
3a90: 3b 0a 20 20 70 50 67 48 64 72 20 3d 20 28 50 67  ;.  pPgHdr = (Pg
3aa0: 48 64 72 20 2a 29 70 50 61 67 65 2d 3e 70 45 78  Hdr *)pPage->pEx
3ab0: 74 72 61 3b 0a 0a 20 20 69 66 28 20 21 70 50 67  tra;..  if( !pPg
3ac0: 48 64 72 2d 3e 70 50 61 67 65 20 29 7b 0a 20 20  Hdr->pPage ){.  
3ad0: 20 20 72 65 74 75 72 6e 20 70 63 61 63 68 65 46    return pcacheF
3ae0: 65 74 63 68 46 69 6e 69 73 68 57 69 74 68 49 6e  etchFinishWithIn
3af0: 69 74 28 70 43 61 63 68 65 2c 20 70 67 6e 6f 2c  it(pCache, pgno,
3b00: 20 70 50 61 67 65 29 3b 0a 20 20 7d 0a 20 20 70   pPage);.  }.  p
3b10: 43 61 63 68 65 2d 3e 6e 52 65 66 53 75 6d 2b 2b  Cache->nRefSum++
3b20: 3b 0a 20 20 70 50 67 48 64 72 2d 3e 6e 52 65 66  ;.  pPgHdr->nRef
3b30: 2b 2b 3b 0a 20 20 72 65 74 75 72 6e 20 70 50 67  ++;.  return pPg
3b40: 48 64 72 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65  Hdr;.}../*.** De
3b50: 63 72 65 6d 65 6e 74 20 74 68 65 20 72 65 66 65  crement the refe
3b60: 72 65 6e 63 65 20 63 6f 75 6e 74 20 6f 6e 20 61  rence count on a
3b70: 20 70 61 67 65 2e 20 49 66 20 74 68 65 20 70 61   page. If the pa
3b80: 67 65 20 69 73 20 63 6c 65 61 6e 20 61 6e 64 20  ge is clean and 
3b90: 74 68 65 0a 2a 2a 20 72 65 66 65 72 65 6e 63 65  the.** reference
3ba0: 20 63 6f 75 6e 74 20 64 72 6f 70 73 20 74 6f 20   count drops to 
3bb0: 30 2c 20 74 68 65 6e 20 69 74 20 69 73 20 6d 61  0, then it is ma
3bc0: 64 65 20 65 6c 69 67 69 62 6c 65 20 66 6f 72 20  de eligible for 
3bd0: 72 65 63 79 63 6c 69 6e 67 2e 0a 2a 2f 0a 76 6f  recycling..*/.vo
3be0: 69 64 20 53 51 4c 49 54 45 5f 4e 4f 49 4e 4c 49  id SQLITE_NOINLI
3bf0: 4e 45 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  NE sqlite3Pcache
3c00: 52 65 6c 65 61 73 65 28 50 67 48 64 72 20 2a 70  Release(PgHdr *p
3c10: 29 7b 0a 20 20 61 73 73 65 72 74 28 20 70 2d 3e  ){.  assert( p->
3c20: 6e 52 65 66 3e 30 20 29 3b 0a 20 20 70 2d 3e 70  nRef>0 );.  p->p
3c30: 43 61 63 68 65 2d 3e 6e 52 65 66 53 75 6d 2d 2d  Cache->nRefSum--
3c40: 3b 0a 20 20 69 66 28 20 28 2d 2d 70 2d 3e 6e 52  ;.  if( (--p->nR
3c50: 65 66 29 3d 3d 30 20 29 7b 0a 20 20 20 20 69 66  ef)==0 ){.    if
3c60: 28 20 70 2d 3e 66 6c 61 67 73 26 50 47 48 44 52  ( p->flags&PGHDR
3c70: 5f 43 4c 45 41 4e 20 29 7b 0a 20 20 20 20 20 20  _CLEAN ){.      
3c80: 70 63 61 63 68 65 55 6e 70 69 6e 28 70 29 3b 0a  pcacheUnpin(p);.
3c90: 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 70 2d      }else if( p-
3ca0: 3e 70 44 69 72 74 79 50 72 65 76 21 3d 30 20 29  >pDirtyPrev!=0 )
3cb0: 7b 0a 20 20 20 20 20 20 2f 2a 20 4d 6f 76 65 20  {.      /* Move 
3cc0: 74 68 65 20 70 61 67 65 20 74 6f 20 74 68 65 20  the page to the 
3cd0: 68 65 61 64 20 6f 66 20 74 68 65 20 64 69 72 74  head of the dirt
3ce0: 79 20 6c 69 73 74 2e 20 2a 2f 0a 20 20 20 20 20  y list. */.     
3cf0: 20 70 63 61 63 68 65 4d 61 6e 61 67 65 44 69 72   pcacheManageDir
3d00: 74 79 4c 69 73 74 28 70 2c 20 50 43 41 43 48 45  tyList(p, PCACHE
3d10: 5f 44 49 52 54 59 4c 49 53 54 5f 46 52 4f 4e 54  _DIRTYLIST_FRONT
3d20: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a  );.    }.  }.}..
3d30: 2f 2a 0a 2a 2a 20 49 6e 63 72 65 61 73 65 20 74  /*.** Increase t
3d40: 68 65 20 72 65 66 65 72 65 6e 63 65 20 63 6f 75  he reference cou
3d50: 6e 74 20 6f 66 20 61 20 73 75 70 70 6c 69 65 64  nt of a supplied
3d60: 20 70 61 67 65 20 62 79 20 31 2e 0a 2a 2f 0a 76   page by 1..*/.v
3d70: 6f 69 64 20 73 71 6c 69 74 65 33 50 63 61 63 68  oid sqlite3Pcach
3d80: 65 52 65 66 28 50 67 48 64 72 20 2a 70 29 7b 0a  eRef(PgHdr *p){.
3d90: 20 20 61 73 73 65 72 74 28 70 2d 3e 6e 52 65 66    assert(p->nRef
3da0: 3e 30 29 3b 0a 20 20 70 2d 3e 6e 52 65 66 2b 2b  >0);.  p->nRef++
3db0: 3b 0a 20 20 70 2d 3e 70 43 61 63 68 65 2d 3e 6e  ;.  p->pCache->n
3dc0: 52 65 66 53 75 6d 2b 2b 3b 0a 7d 0a 0a 2f 2a 0a  RefSum++;.}../*.
3dd0: 2a 2a 20 44 72 6f 70 20 61 20 70 61 67 65 20 66  ** Drop a page f
3de0: 72 6f 6d 20 74 68 65 20 63 61 63 68 65 2e 20 54  rom the cache. T
3df0: 68 65 72 65 20 6d 75 73 74 20 62 65 20 65 78 61  here must be exa
3e00: 63 74 6c 79 20 6f 6e 65 20 72 65 66 65 72 65 6e  ctly one referen
3e10: 63 65 20 74 6f 20 74 68 65 0a 2a 2a 20 70 61 67  ce to the.** pag
3e20: 65 2e 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  e. This function
3e30: 20 64 65 6c 65 74 65 73 20 74 68 61 74 20 72 65   deletes that re
3e40: 66 65 72 65 6e 63 65 2c 20 73 6f 20 61 66 74 65  ference, so afte
3e50: 72 20 69 74 20 72 65 74 75 72 6e 73 20 74 68 65  r it returns the
3e60: 0a 2a 2a 20 70 61 67 65 20 70 6f 69 6e 74 65 64  .** page pointed
3e70: 20 74 6f 20 62 79 20 70 20 69 73 20 69 6e 76 61   to by p is inva
3e80: 6c 69 64 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c  lid..*/.void sql
3e90: 69 74 65 33 50 63 61 63 68 65 44 72 6f 70 28 50  ite3PcacheDrop(P
3ea0: 67 48 64 72 20 2a 70 29 7b 0a 20 20 61 73 73 65  gHdr *p){.  asse
3eb0: 72 74 28 20 70 2d 3e 6e 52 65 66 3d 3d 31 20 29  rt( p->nRef==1 )
3ec0: 3b 0a 20 20 69 66 28 20 70 2d 3e 66 6c 61 67 73  ;.  if( p->flags
3ed0: 26 50 47 48 44 52 5f 44 49 52 54 59 20 29 7b 0a  &PGHDR_DIRTY ){.
3ee0: 20 20 20 20 70 63 61 63 68 65 4d 61 6e 61 67 65      pcacheManage
3ef0: 44 69 72 74 79 4c 69 73 74 28 70 2c 20 50 43 41  DirtyList(p, PCA
3f00: 43 48 45 5f 44 49 52 54 59 4c 49 53 54 5f 52 45  CHE_DIRTYLIST_RE
3f10: 4d 4f 56 45 29 3b 0a 20 20 7d 0a 20 20 70 2d 3e  MOVE);.  }.  p->
3f20: 70 43 61 63 68 65 2d 3e 6e 52 65 66 53 75 6d 2d  pCache->nRefSum-
3f30: 2d 3b 0a 20 20 73 71 6c 69 74 65 33 47 6c 6f 62  -;.  sqlite3Glob
3f40: 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65 32  alConfig.pcache2
3f50: 2e 78 55 6e 70 69 6e 28 70 2d 3e 70 43 61 63 68  .xUnpin(p->pCach
3f60: 65 2d 3e 70 43 61 63 68 65 2c 20 70 2d 3e 70 50  e->pCache, p->pP
3f70: 61 67 65 2c 20 31 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  age, 1);.}../*.*
3f80: 2a 20 4d 61 6b 65 20 73 75 72 65 20 74 68 65 20  * Make sure the 
3f90: 70 61 67 65 20 69 73 20 6d 61 72 6b 65 64 20 61  page is marked a
3fa0: 73 20 64 69 72 74 79 2e 20 49 66 20 69 74 20 69  s dirty. If it i
3fb0: 73 6e 27 74 20 64 69 72 74 79 20 61 6c 72 65 61  sn't dirty alrea
3fc0: 64 79 2c 0a 2a 2a 20 6d 61 6b 65 20 69 74 20 73  dy,.** make it s
3fd0: 6f 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74  o..*/.void sqlit
3fe0: 65 33 50 63 61 63 68 65 4d 61 6b 65 44 69 72 74  e3PcacheMakeDirt
3ff0: 79 28 50 67 48 64 72 20 2a 70 29 7b 0a 20 20 61  y(PgHdr *p){.  a
4000: 73 73 65 72 74 28 20 70 2d 3e 6e 52 65 66 3e 30  ssert( p->nRef>0
4010: 20 29 3b 0a 20 20 69 66 28 20 70 2d 3e 66 6c 61   );.  if( p->fla
4020: 67 73 20 26 20 28 50 47 48 44 52 5f 43 4c 45 41  gs & (PGHDR_CLEA
4030: 4e 7c 50 47 48 44 52 5f 44 4f 4e 54 5f 57 52 49  N|PGHDR_DONT_WRI
4040: 54 45 29 20 29 7b 0a 20 20 20 20 70 2d 3e 66 6c  TE) ){.    p->fl
4050: 61 67 73 20 26 3d 20 7e 50 47 48 44 52 5f 44 4f  ags &= ~PGHDR_DO
4060: 4e 54 5f 57 52 49 54 45 3b 0a 20 20 20 20 69 66  NT_WRITE;.    if
4070: 28 20 70 2d 3e 66 6c 61 67 73 20 26 20 50 47 48  ( p->flags & PGH
4080: 44 52 5f 43 4c 45 41 4e 20 29 7b 0a 20 20 20 20  DR_CLEAN ){.    
4090: 20 20 70 2d 3e 66 6c 61 67 73 20 5e 3d 20 28 50    p->flags ^= (P
40a0: 47 48 44 52 5f 44 49 52 54 59 7c 50 47 48 44 52  GHDR_DIRTY|PGHDR
40b0: 5f 43 4c 45 41 4e 29 3b 0a 20 20 20 20 20 20 70  _CLEAN);.      p
40c0: 63 61 63 68 65 54 72 61 63 65 28 28 22 25 70 2e  cacheTrace(("%p.
40d0: 44 49 52 54 59 20 25 64 5c 6e 22 2c 70 2d 3e 70  DIRTY %d\n",p->p
40e0: 43 61 63 68 65 2c 70 2d 3e 70 67 6e 6f 29 29 3b  Cache,p->pgno));
40f0: 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 28  .      assert( (
4100: 70 2d 3e 66 6c 61 67 73 20 26 20 28 50 47 48 44  p->flags & (PGHD
4110: 52 5f 44 49 52 54 59 7c 50 47 48 44 52 5f 43 4c  R_DIRTY|PGHDR_CL
4120: 45 41 4e 29 29 3d 3d 50 47 48 44 52 5f 44 49 52  EAN))==PGHDR_DIR
4130: 54 59 20 29 3b 0a 20 20 20 20 20 20 70 63 61 63  TY );.      pcac
4140: 68 65 4d 61 6e 61 67 65 44 69 72 74 79 4c 69 73  heManageDirtyLis
4150: 74 28 70 2c 20 50 43 41 43 48 45 5f 44 49 52 54  t(p, PCACHE_DIRT
4160: 59 4c 49 53 54 5f 41 44 44 29 3b 0a 20 20 20 20  YLIST_ADD);.    
4170: 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d  }.  }.}../*.** M
4180: 61 6b 65 20 73 75 72 65 20 74 68 65 20 70 61 67  ake sure the pag
4190: 65 20 69 73 20 6d 61 72 6b 65 64 20 61 73 20 63  e is marked as c
41a0: 6c 65 61 6e 2e 20 49 66 20 69 74 20 69 73 6e 27  lean. If it isn'
41b0: 74 20 63 6c 65 61 6e 20 61 6c 72 65 61 64 79 2c  t clean already,
41c0: 0a 2a 2a 20 6d 61 6b 65 20 69 74 20 73 6f 2e 0a  .** make it so..
41d0: 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50  */.void sqlite3P
41e0: 63 61 63 68 65 4d 61 6b 65 43 6c 65 61 6e 28 50  cacheMakeClean(P
41f0: 67 48 64 72 20 2a 70 29 7b 0a 20 20 69 66 28 20  gHdr *p){.  if( 
4200: 28 70 2d 3e 66 6c 61 67 73 20 26 20 50 47 48 44  (p->flags & PGHD
4210: 52 5f 44 49 52 54 59 29 20 29 7b 0a 20 20 20 20  R_DIRTY) ){.    
4220: 61 73 73 65 72 74 28 20 28 70 2d 3e 66 6c 61 67  assert( (p->flag
4230: 73 20 26 20 50 47 48 44 52 5f 43 4c 45 41 4e 29  s & PGHDR_CLEAN)
4240: 3d 3d 30 20 29 3b 0a 20 20 20 20 70 63 61 63 68  ==0 );.    pcach
4250: 65 4d 61 6e 61 67 65 44 69 72 74 79 4c 69 73 74  eManageDirtyList
4260: 28 70 2c 20 50 43 41 43 48 45 5f 44 49 52 54 59  (p, PCACHE_DIRTY
4270: 4c 49 53 54 5f 52 45 4d 4f 56 45 29 3b 0a 20 20  LIST_REMOVE);.  
4280: 20 20 70 2d 3e 66 6c 61 67 73 20 26 3d 20 7e 28    p->flags &= ~(
4290: 50 47 48 44 52 5f 44 49 52 54 59 7c 50 47 48 44  PGHDR_DIRTY|PGHD
42a0: 52 5f 4e 45 45 44 5f 53 59 4e 43 7c 50 47 48 44  R_NEED_SYNC|PGHD
42b0: 52 5f 57 52 49 54 45 41 42 4c 45 29 3b 0a 20 20  R_WRITEABLE);.  
42c0: 20 20 70 2d 3e 66 6c 61 67 73 20 7c 3d 20 50 47    p->flags |= PG
42d0: 48 44 52 5f 43 4c 45 41 4e 3b 0a 20 20 20 20 70  HDR_CLEAN;.    p
42e0: 63 61 63 68 65 54 72 61 63 65 28 28 22 25 70 2e  cacheTrace(("%p.
42f0: 43 4c 45 41 4e 20 25 64 5c 6e 22 2c 70 2d 3e 70  CLEAN %d\n",p->p
4300: 43 61 63 68 65 2c 70 2d 3e 70 67 6e 6f 29 29 3b  Cache,p->pgno));
4310: 0a 20 20 20 20 69 66 28 20 70 2d 3e 6e 52 65 66  .    if( p->nRef
4320: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 70 63 61  ==0 ){.      pca
4330: 63 68 65 55 6e 70 69 6e 28 70 29 3b 0a 20 20 20  cheUnpin(p);.   
4340: 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20   }.  }.}../*.** 
4350: 4d 61 6b 65 20 65 76 65 72 79 20 70 61 67 65 20  Make every page 
4360: 69 6e 20 74 68 65 20 63 61 63 68 65 20 63 6c 65  in the cache cle
4370: 61 6e 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69  an..*/.void sqli
4380: 74 65 33 50 63 61 63 68 65 43 6c 65 61 6e 41 6c  te3PcacheCleanAl
4390: 6c 28 50 43 61 63 68 65 20 2a 70 43 61 63 68 65  l(PCache *pCache
43a0: 29 7b 0a 20 20 50 67 48 64 72 20 2a 70 3b 0a 20  ){.  PgHdr *p;. 
43b0: 20 77 68 69 6c 65 28 20 28 70 20 3d 20 70 43 61   while( (p = pCa
43c0: 63 68 65 2d 3e 70 44 69 72 74 79 29 21 3d 30 20  che->pDirty)!=0 
43d0: 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 50 63  ){.    sqlite3Pc
43e0: 61 63 68 65 4d 61 6b 65 43 6c 65 61 6e 28 70 29  acheMakeClean(p)
43f0: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43  ;.  }.}../*.** C
4400: 6c 65 61 72 20 74 68 65 20 50 47 48 44 52 5f 4e  lear the PGHDR_N
4410: 45 45 44 5f 53 59 4e 43 20 61 6e 64 20 50 47 48  EED_SYNC and PGH
4420: 44 52 5f 57 52 49 54 45 41 42 4c 45 20 66 6c 61  DR_WRITEABLE fla
4430: 67 20 66 72 6f 6d 20 61 6c 6c 20 64 69 72 74 79  g from all dirty
4440: 20 70 61 67 65 73 2e 0a 2a 2f 0a 76 6f 69 64 20   pages..*/.void 
4450: 73 71 6c 69 74 65 33 50 63 61 63 68 65 43 6c 65  sqlite3PcacheCle
4460: 61 72 57 72 69 74 61 62 6c 65 28 50 43 61 63 68  arWritable(PCach
4470: 65 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 50 67  e *pCache){.  Pg
4480: 48 64 72 20 2a 70 3b 0a 20 20 66 6f 72 28 70 3d  Hdr *p;.  for(p=
4490: 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 3b 20  pCache->pDirty; 
44a0: 70 3b 20 70 3d 70 2d 3e 70 44 69 72 74 79 4e 65  p; p=p->pDirtyNe
44b0: 78 74 29 7b 0a 20 20 20 20 70 2d 3e 66 6c 61 67  xt){.    p->flag
44c0: 73 20 26 3d 20 7e 28 50 47 48 44 52 5f 4e 45 45  s &= ~(PGHDR_NEE
44d0: 44 5f 53 59 4e 43 7c 50 47 48 44 52 5f 57 52 49  D_SYNC|PGHDR_WRI
44e0: 54 45 41 42 4c 45 29 3b 0a 20 20 7d 0a 20 20 70  TEABLE);.  }.  p
44f0: 43 61 63 68 65 2d 3e 70 53 79 6e 63 65 64 20 3d  Cache->pSynced =
4500: 20 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 54   pCache->pDirtyT
4510: 61 69 6c 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c  ail;.}../*.** Cl
4520: 65 61 72 20 74 68 65 20 50 47 48 44 52 5f 4e 45  ear the PGHDR_NE
4530: 45 44 5f 53 59 4e 43 20 66 6c 61 67 20 66 72 6f  ED_SYNC flag fro
4540: 6d 20 61 6c 6c 20 64 69 72 74 79 20 70 61 67 65  m all dirty page
4550: 73 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74  s..*/.void sqlit
4560: 65 33 50 63 61 63 68 65 43 6c 65 61 72 53 79 6e  e3PcacheClearSyn
4570: 63 46 6c 61 67 73 28 50 43 61 63 68 65 20 2a 70  cFlags(PCache *p
4580: 43 61 63 68 65 29 7b 0a 20 20 50 67 48 64 72 20  Cache){.  PgHdr 
4590: 2a 70 3b 0a 20 20 66 6f 72 28 70 3d 70 43 61 63  *p;.  for(p=pCac
45a0: 68 65 2d 3e 70 44 69 72 74 79 3b 20 70 3b 20 70  he->pDirty; p; p
45b0: 3d 70 2d 3e 70 44 69 72 74 79 4e 65 78 74 29 7b  =p->pDirtyNext){
45c0: 0a 20 20 20 20 70 2d 3e 66 6c 61 67 73 20 26 3d  .    p->flags &=
45d0: 20 7e 50 47 48 44 52 5f 4e 45 45 44 5f 53 59 4e   ~PGHDR_NEED_SYN
45e0: 43 3b 0a 20 20 7d 0a 20 20 70 43 61 63 68 65 2d  C;.  }.  pCache-
45f0: 3e 70 53 79 6e 63 65 64 20 3d 20 70 43 61 63 68  >pSynced = pCach
4600: 65 2d 3e 70 44 69 72 74 79 54 61 69 6c 3b 0a 7d  e->pDirtyTail;.}
4610: 0a 0a 2f 2a 0a 2a 2a 20 43 68 61 6e 67 65 20 74  ../*.** Change t
4620: 68 65 20 70 61 67 65 20 6e 75 6d 62 65 72 20 6f  he page number o
4630: 66 20 70 61 67 65 20 70 20 74 6f 20 6e 65 77 50  f page p to newP
4640: 67 6e 6f 2e 20 0a 2a 2f 0a 76 6f 69 64 20 73 71  gno. .*/.void sq
4650: 6c 69 74 65 33 50 63 61 63 68 65 4d 6f 76 65 28  lite3PcacheMove(
4660: 50 67 48 64 72 20 2a 70 2c 20 50 67 6e 6f 20 6e  PgHdr *p, Pgno n
4670: 65 77 50 67 6e 6f 29 7b 0a 20 20 50 43 61 63 68  ewPgno){.  PCach
4680: 65 20 2a 70 43 61 63 68 65 20 3d 20 70 2d 3e 70  e *pCache = p->p
4690: 43 61 63 68 65 3b 0a 20 20 61 73 73 65 72 74 28  Cache;.  assert(
46a0: 20 70 2d 3e 6e 52 65 66 3e 30 20 29 3b 0a 20 20   p->nRef>0 );.  
46b0: 61 73 73 65 72 74 28 20 6e 65 77 50 67 6e 6f 3e  assert( newPgno>
46c0: 30 20 29 3b 0a 20 20 70 63 61 63 68 65 54 72 61  0 );.  pcacheTra
46d0: 63 65 28 28 22 25 70 2e 4d 4f 56 45 20 25 64 20  ce(("%p.MOVE %d 
46e0: 2d 3e 20 25 64 5c 6e 22 2c 70 43 61 63 68 65 2c  -> %d\n",pCache,
46f0: 70 2d 3e 70 67 6e 6f 2c 6e 65 77 50 67 6e 6f 29  p->pgno,newPgno)
4700: 29 3b 0a 20 20 73 71 6c 69 74 65 33 47 6c 6f 62  );.  sqlite3Glob
4710: 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65 32  alConfig.pcache2
4720: 2e 78 52 65 6b 65 79 28 70 43 61 63 68 65 2d 3e  .xRekey(pCache->
4730: 70 43 61 63 68 65 2c 20 70 2d 3e 70 50 61 67 65  pCache, p->pPage
4740: 2c 20 70 2d 3e 70 67 6e 6f 2c 6e 65 77 50 67 6e  , p->pgno,newPgn
4750: 6f 29 3b 0a 20 20 70 2d 3e 70 67 6e 6f 20 3d 20  o);.  p->pgno = 
4760: 6e 65 77 50 67 6e 6f 3b 0a 20 20 69 66 28 20 28  newPgno;.  if( (
4770: 70 2d 3e 66 6c 61 67 73 26 50 47 48 44 52 5f 44  p->flags&PGHDR_D
4780: 49 52 54 59 29 20 26 26 20 28 70 2d 3e 66 6c 61  IRTY) && (p->fla
4790: 67 73 26 50 47 48 44 52 5f 4e 45 45 44 5f 53 59  gs&PGHDR_NEED_SY
47a0: 4e 43 29 20 29 7b 0a 20 20 20 20 70 63 61 63 68  NC) ){.    pcach
47b0: 65 4d 61 6e 61 67 65 44 69 72 74 79 4c 69 73 74  eManageDirtyList
47c0: 28 70 2c 20 50 43 41 43 48 45 5f 44 49 52 54 59  (p, PCACHE_DIRTY
47d0: 4c 49 53 54 5f 46 52 4f 4e 54 29 3b 0a 20 20 7d  LIST_FRONT);.  }
47e0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 72 6f 70 20 65  .}../*.** Drop e
47f0: 76 65 72 79 20 63 61 63 68 65 20 65 6e 74 72 79  very cache entry
4800: 20 77 68 6f 73 65 20 70 61 67 65 20 6e 75 6d 62   whose page numb
4810: 65 72 20 69 73 20 67 72 65 61 74 65 72 20 74 68  er is greater th
4820: 61 6e 20 22 70 67 6e 6f 22 2e 20 54 68 65 0a 2a  an "pgno". The.*
4830: 2a 20 63 61 6c 6c 65 72 20 6d 75 73 74 20 65 6e  * caller must en
4840: 73 75 72 65 20 74 68 61 74 20 74 68 65 72 65 20  sure that there 
4850: 61 72 65 20 6e 6f 20 6f 75 74 73 74 61 6e 64 69  are no outstandi
4860: 6e 67 20 72 65 66 65 72 65 6e 63 65 73 20 74 6f  ng references to
4870: 20 61 6e 79 20 70 61 67 65 73 0a 2a 2a 20 6f 74   any pages.** ot
4880: 68 65 72 20 74 68 61 6e 20 70 61 67 65 20 31 20  her than page 1 
4890: 77 69 74 68 20 61 20 70 61 67 65 20 6e 75 6d 62  with a page numb
48a0: 65 72 20 67 72 65 61 74 65 72 20 74 68 61 6e 20  er greater than 
48b0: 70 67 6e 6f 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74  pgno..**.** If t
48c0: 68 65 72 65 20 69 73 20 61 20 72 65 66 65 72 65  here is a refere
48d0: 6e 63 65 20 74 6f 20 70 61 67 65 20 31 20 61 6e  nce to page 1 an
48e0: 64 20 74 68 65 20 70 67 6e 6f 20 70 61 72 61 6d  d the pgno param
48f0: 65 74 65 72 20 70 61 73 73 65 64 20 74 6f 20 74  eter passed to t
4900: 68 69 73 0a 2a 2a 20 66 75 6e 63 74 69 6f 6e 20  his.** function 
4910: 69 73 20 30 2c 20 74 68 65 6e 20 74 68 65 20 64  is 0, then the d
4920: 61 74 61 20 61 72 65 61 20 61 73 73 6f 63 69 61  ata area associa
4930: 74 65 64 20 77 69 74 68 20 70 61 67 65 20 31 20  ted with page 1 
4940: 69 73 20 7a 65 72 6f 65 64 2c 20 62 75 74 0a 2a  is zeroed, but.*
4950: 2a 20 74 68 65 20 70 61 67 65 20 6f 62 6a 65 63  * the page objec
4960: 74 20 69 73 20 6e 6f 74 20 64 72 6f 70 70 65 64  t is not dropped
4970: 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
4980: 33 50 63 61 63 68 65 54 72 75 6e 63 61 74 65 28  3PcacheTruncate(
4990: 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 2c 20  PCache *pCache, 
49a0: 50 67 6e 6f 20 70 67 6e 6f 29 7b 0a 20 20 69 66  Pgno pgno){.  if
49b0: 28 20 70 43 61 63 68 65 2d 3e 70 43 61 63 68 65  ( pCache->pCache
49c0: 20 29 7b 0a 20 20 20 20 50 67 48 64 72 20 2a 70   ){.    PgHdr *p
49d0: 3b 0a 20 20 20 20 50 67 48 64 72 20 2a 70 4e 65  ;.    PgHdr *pNe
49e0: 78 74 3b 0a 20 20 20 20 70 63 61 63 68 65 54 72  xt;.    pcacheTr
49f0: 61 63 65 28 28 22 25 70 2e 54 52 55 4e 43 41 54  ace(("%p.TRUNCAT
4a00: 45 20 25 64 5c 6e 22 2c 70 43 61 63 68 65 2c 70  E %d\n",pCache,p
4a10: 67 6e 6f 29 29 3b 0a 20 20 20 20 66 6f 72 28 70  gno));.    for(p
4a20: 3d 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 3b  =pCache->pDirty;
4a30: 20 70 3b 20 70 3d 70 4e 65 78 74 29 7b 0a 20 20   p; p=pNext){.  
4a40: 20 20 20 20 70 4e 65 78 74 20 3d 20 70 2d 3e 70      pNext = p->p
4a50: 44 69 72 74 79 4e 65 78 74 3b 0a 20 20 20 20 20  DirtyNext;.     
4a60: 20 2f 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65   /* This routine
4a70: 20 6e 65 76 65 72 20 67 65 74 73 20 63 61 6c 6c   never gets call
4a80: 20 77 69 74 68 20 61 20 70 6f 73 69 74 69 76 65   with a positive
4a90: 20 70 67 6e 6f 20 65 78 63 65 70 74 20 72 69 67   pgno except rig
4aa0: 68 74 0a 20 20 20 20 20 20 2a 2a 20 61 66 74 65  ht.      ** afte
4ab0: 72 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 43  r sqlite3PcacheC
4ac0: 6c 65 61 6e 41 6c 6c 28 29 2e 20 20 53 6f 20 69  leanAll().  So i
4ad0: 66 20 74 68 65 72 65 20 61 72 65 20 64 69 72 74  f there are dirt
4ae0: 79 20 70 61 67 65 73 2c 0a 20 20 20 20 20 20 2a  y pages,.      *
4af0: 2a 20 69 74 20 6d 75 73 74 20 62 65 20 74 68 61  * it must be tha
4b00: 74 20 70 67 6e 6f 3d 3d 30 2e 0a 20 20 20 20 20  t pgno==0..     
4b10: 20 2a 2f 0a 20 20 20 20 20 20 61 73 73 65 72 74   */.      assert
4b20: 28 20 70 2d 3e 70 67 6e 6f 3e 30 20 29 3b 0a 20  ( p->pgno>0 );. 
4b30: 20 20 20 20 20 69 66 28 20 70 2d 3e 70 67 6e 6f       if( p->pgno
4b40: 3e 70 67 6e 6f 20 29 7b 0a 20 20 20 20 20 20 20  >pgno ){.       
4b50: 20 61 73 73 65 72 74 28 20 70 2d 3e 66 6c 61 67   assert( p->flag
4b60: 73 26 50 47 48 44 52 5f 44 49 52 54 59 20 29 3b  s&PGHDR_DIRTY );
4b70: 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33  .        sqlite3
4b80: 50 63 61 63 68 65 4d 61 6b 65 43 6c 65 61 6e 28  PcacheMakeClean(
4b90: 70 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  p);.      }.    
4ba0: 7d 0a 20 20 20 20 69 66 28 20 70 67 6e 6f 3d 3d  }.    if( pgno==
4bb0: 30 20 26 26 20 70 43 61 63 68 65 2d 3e 6e 52 65  0 && pCache->nRe
4bc0: 66 53 75 6d 20 29 7b 0a 20 20 20 20 20 20 73 71  fSum ){.      sq
4bd0: 6c 69 74 65 33 5f 70 63 61 63 68 65 5f 70 61 67  lite3_pcache_pag
4be0: 65 20 2a 70 50 61 67 65 31 3b 0a 20 20 20 20 20  e *pPage1;.     
4bf0: 20 70 50 61 67 65 31 20 3d 20 73 71 6c 69 74 65   pPage1 = sqlite
4c00: 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63  3GlobalConfig.pc
4c10: 61 63 68 65 32 2e 78 46 65 74 63 68 28 70 43 61  ache2.xFetch(pCa
4c20: 63 68 65 2d 3e 70 43 61 63 68 65 2c 31 2c 30 29  che->pCache,1,0)
4c30: 3b 0a 20 20 20 20 20 20 69 66 28 20 41 4c 57 41  ;.      if( ALWA
4c40: 59 53 28 70 50 61 67 65 31 29 20 29 7b 20 20 2f  YS(pPage1) ){  /
4c50: 2a 20 50 61 67 65 20 31 20 69 73 20 61 6c 77 61  * Page 1 is alwa
4c60: 79 73 20 61 76 61 69 6c 61 62 6c 65 20 69 6e 20  ys available in 
4c70: 63 61 63 68 65 2c 20 62 65 63 61 75 73 65 0a 20  cache, because. 
4c80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4c90: 20 20 20 20 20 20 20 20 20 20 20 20 2a 2a 20 70              ** p
4ca0: 43 61 63 68 65 2d 3e 6e 52 65 66 53 75 6d 3e 30  Cache->nRefSum>0
4cb0: 20 2a 2f 0a 20 20 20 20 20 20 20 20 6d 65 6d 73   */.        mems
4cc0: 65 74 28 70 50 61 67 65 31 2d 3e 70 42 75 66 2c  et(pPage1->pBuf,
4cd0: 20 30 2c 20 70 43 61 63 68 65 2d 3e 73 7a 50 61   0, pCache->szPa
4ce0: 67 65 29 3b 0a 20 20 20 20 20 20 20 20 70 67 6e  ge);.        pgn
4cf0: 6f 20 3d 20 31 3b 0a 20 20 20 20 20 20 7d 0a 20  o = 1;.      }. 
4d00: 20 20 20 7d 0a 20 20 20 20 73 71 6c 69 74 65 33     }.    sqlite3
4d10: 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61  GlobalConfig.pca
4d20: 63 68 65 32 2e 78 54 72 75 6e 63 61 74 65 28 70  che2.xTruncate(p
4d30: 43 61 63 68 65 2d 3e 70 43 61 63 68 65 2c 20 70  Cache->pCache, p
4d40: 67 6e 6f 2b 31 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f  gno+1);.  }.}../
4d50: 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61 20 63 61 63  *.** Close a cac
4d60: 68 65 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69  he..*/.void sqli
4d70: 74 65 33 50 63 61 63 68 65 43 6c 6f 73 65 28 50  te3PcacheClose(P
4d80: 43 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b 0a  Cache *pCache){.
4d90: 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65    assert( pCache
4da0: 2d 3e 70 43 61 63 68 65 21 3d 30 20 29 3b 0a 20  ->pCache!=0 );. 
4db0: 20 70 63 61 63 68 65 54 72 61 63 65 28 28 22 25   pcacheTrace(("%
4dc0: 70 2e 43 4c 4f 53 45 5c 6e 22 2c 70 43 61 63 68  p.CLOSE\n",pCach
4dd0: 65 29 29 3b 0a 20 20 73 71 6c 69 74 65 33 47 6c  e));.  sqlite3Gl
4de0: 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68  obalConfig.pcach
4df0: 65 32 2e 78 44 65 73 74 72 6f 79 28 70 43 61 63  e2.xDestroy(pCac
4e00: 68 65 2d 3e 70 43 61 63 68 65 29 3b 0a 7d 0a 0a  he->pCache);.}..
4e10: 2f 2a 20 0a 2a 2a 20 44 69 73 63 61 72 64 20 74  /* .** Discard t
4e20: 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74  he contents of t
4e30: 68 65 20 63 61 63 68 65 2e 0a 2a 2f 0a 76 6f 69  he cache..*/.voi
4e40: 64 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 43  d sqlite3PcacheC
4e50: 6c 65 61 72 28 50 43 61 63 68 65 20 2a 70 43 61  lear(PCache *pCa
4e60: 63 68 65 29 7b 0a 20 20 73 71 6c 69 74 65 33 50  che){.  sqlite3P
4e70: 63 61 63 68 65 54 72 75 6e 63 61 74 65 28 70 43  cacheTruncate(pC
4e80: 61 63 68 65 2c 20 30 29 3b 0a 7d 0a 0a 2f 2a 0a  ache, 0);.}../*.
4e90: 2a 2a 20 4d 65 72 67 65 20 74 77 6f 20 6c 69 73  ** Merge two lis
4ea0: 74 73 20 6f 66 20 70 61 67 65 73 20 63 6f 6e 6e  ts of pages conn
4eb0: 65 63 74 65 64 20 62 79 20 70 44 69 72 74 79 20  ected by pDirty 
4ec0: 61 6e 64 20 69 6e 20 70 67 6e 6f 20 6f 72 64 65  and in pgno orde
4ed0: 72 2e 0a 2a 2a 20 44 6f 20 6e 6f 74 20 62 6f 74  r..** Do not bot
4ee0: 68 20 66 69 78 69 6e 67 20 74 68 65 20 70 44 69  h fixing the pDi
4ef0: 72 74 79 50 72 65 76 20 70 6f 69 6e 74 65 72 73  rtyPrev pointers
4f00: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 50 67 48 64  ..*/.static PgHd
4f10: 72 20 2a 70 63 61 63 68 65 4d 65 72 67 65 44 69  r *pcacheMergeDi
4f20: 72 74 79 4c 69 73 74 28 50 67 48 64 72 20 2a 70  rtyList(PgHdr *p
4f30: 41 2c 20 50 67 48 64 72 20 2a 70 42 29 7b 0a 20  A, PgHdr *pB){. 
4f40: 20 50 67 48 64 72 20 72 65 73 75 6c 74 2c 20 2a   PgHdr result, *
4f50: 70 54 61 69 6c 3b 0a 20 20 70 54 61 69 6c 20 3d  pTail;.  pTail =
4f60: 20 26 72 65 73 75 6c 74 3b 0a 20 20 77 68 69 6c   &result;.  whil
4f70: 65 28 20 70 41 20 26 26 20 70 42 20 29 7b 0a 20  e( pA && pB ){. 
4f80: 20 20 20 69 66 28 20 70 41 2d 3e 70 67 6e 6f 3c     if( pA->pgno<
4f90: 70 42 2d 3e 70 67 6e 6f 20 29 7b 0a 20 20 20 20  pB->pgno ){.    
4fa0: 20 20 70 54 61 69 6c 2d 3e 70 44 69 72 74 79 20    pTail->pDirty 
4fb0: 3d 20 70 41 3b 0a 20 20 20 20 20 20 70 54 61 69  = pA;.      pTai
4fc0: 6c 20 3d 20 70 41 3b 0a 20 20 20 20 20 20 70 41  l = pA;.      pA
4fd0: 20 3d 20 70 41 2d 3e 70 44 69 72 74 79 3b 0a 20   = pA->pDirty;. 
4fe0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
4ff0: 70 54 61 69 6c 2d 3e 70 44 69 72 74 79 20 3d 20  pTail->pDirty = 
5000: 70 42 3b 0a 20 20 20 20 20 20 70 54 61 69 6c 20  pB;.      pTail 
5010: 3d 20 70 42 3b 0a 20 20 20 20 20 20 70 42 20 3d  = pB;.      pB =
5020: 20 70 42 2d 3e 70 44 69 72 74 79 3b 0a 20 20 20   pB->pDirty;.   
5030: 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20 70 41 20   }.  }.  if( pA 
5040: 29 7b 0a 20 20 20 20 70 54 61 69 6c 2d 3e 70 44  ){.    pTail->pD
5050: 69 72 74 79 20 3d 20 70 41 3b 0a 20 20 7d 65 6c  irty = pA;.  }el
5060: 73 65 20 69 66 28 20 70 42 20 29 7b 0a 20 20 20  se if( pB ){.   
5070: 20 70 54 61 69 6c 2d 3e 70 44 69 72 74 79 20 3d   pTail->pDirty =
5080: 20 70 42 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20   pB;.  }else{.  
5090: 20 20 70 54 61 69 6c 2d 3e 70 44 69 72 74 79 20    pTail->pDirty 
50a0: 3d 20 30 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  = 0;.  }.  retur
50b0: 6e 20 72 65 73 75 6c 74 2e 70 44 69 72 74 79 3b  n result.pDirty;
50c0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 6f 72 74 20 74  .}../*.** Sort t
50d0: 68 65 20 6c 69 73 74 20 6f 66 20 70 61 67 65 73  he list of pages
50e0: 20 69 6e 20 61 63 63 65 6e 64 69 6e 67 20 6f 72   in accending or
50f0: 64 65 72 20 62 79 20 70 67 6e 6f 2e 20 20 50 61  der by pgno.  Pa
5100: 67 65 73 20 61 72 65 0a 2a 2a 20 63 6f 6e 6e 65  ges are.** conne
5110: 63 74 65 64 20 62 79 20 70 44 69 72 74 79 20 70  cted by pDirty p
5120: 6f 69 6e 74 65 72 73 2e 20 20 54 68 65 20 70 44  ointers.  The pD
5130: 69 72 74 79 50 72 65 76 20 70 6f 69 6e 74 65 72  irtyPrev pointer
5140: 73 20 61 72 65 0a 2a 2a 20 63 6f 72 72 75 70 74  s are.** corrupt
5150: 65 64 20 62 79 20 74 68 69 73 20 73 6f 72 74 2e  ed by this sort.
5160: 0a 2a 2a 0a 2a 2a 20 53 69 6e 63 65 20 74 68 65  .**.** Since the
5170: 72 65 20 63 61 6e 6e 6f 74 20 62 65 20 6d 6f 72  re cannot be mor
5180: 65 20 74 68 61 6e 20 32 5e 33 31 20 64 69 73 74  e than 2^31 dist
5190: 69 6e 63 74 20 70 61 67 65 73 20 69 6e 20 61 20  inct pages in a 
51a0: 64 61 74 61 62 61 73 65 2c 0a 2a 2a 20 74 68 65  database,.** the
51b0: 72 65 20 63 61 6e 6e 6f 74 20 62 65 20 6d 6f 72  re cannot be mor
51c0: 65 20 74 68 61 6e 20 33 31 20 62 75 63 6b 65 74  e than 31 bucket
51d0: 73 20 72 65 71 75 69 72 65 64 20 62 79 20 74 68  s required by th
51e0: 65 20 6d 65 72 67 65 20 73 6f 72 74 65 72 2e 0a  e merge sorter..
51f0: 2a 2a 20 4f 6e 65 20 65 78 74 72 61 20 62 75 63  ** One extra buc
5200: 6b 65 74 20 69 73 20 61 64 64 65 64 20 74 6f 20  ket is added to 
5210: 63 61 74 63 68 20 6f 76 65 72 66 6c 6f 77 20 69  catch overflow i
5220: 6e 20 63 61 73 65 20 73 6f 6d 65 74 68 69 6e 67  n case something
5230: 0a 2a 2a 20 65 76 65 72 20 63 68 61 6e 67 65 73  .** ever changes
5240: 20 74 6f 20 6d 61 6b 65 20 74 68 65 20 70 72 65   to make the pre
5250: 76 69 6f 75 73 20 73 65 6e 74 65 6e 63 65 20 69  vious sentence i
5260: 6e 63 6f 72 72 65 63 74 2e 0a 2a 2f 0a 23 64 65  ncorrect..*/.#de
5270: 66 69 6e 65 20 4e 5f 53 4f 52 54 5f 42 55 43 4b  fine N_SORT_BUCK
5280: 45 54 20 20 33 32 0a 73 74 61 74 69 63 20 50 67  ET  32.static Pg
5290: 48 64 72 20 2a 70 63 61 63 68 65 53 6f 72 74 44  Hdr *pcacheSortD
52a0: 69 72 74 79 4c 69 73 74 28 50 67 48 64 72 20 2a  irtyList(PgHdr *
52b0: 70 49 6e 29 7b 0a 20 20 50 67 48 64 72 20 2a 61  pIn){.  PgHdr *a
52c0: 5b 4e 5f 53 4f 52 54 5f 42 55 43 4b 45 54 5d 2c  [N_SORT_BUCKET],
52d0: 20 2a 70 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20   *p;.  int i;.  
52e0: 6d 65 6d 73 65 74 28 61 2c 20 30 2c 20 73 69 7a  memset(a, 0, siz
52f0: 65 6f 66 28 61 29 29 3b 0a 20 20 77 68 69 6c 65  eof(a));.  while
5300: 28 20 70 49 6e 20 29 7b 0a 20 20 20 20 70 20 3d  ( pIn ){.    p =
5310: 20 70 49 6e 3b 0a 20 20 20 20 70 49 6e 20 3d 20   pIn;.    pIn = 
5320: 70 2d 3e 70 44 69 72 74 79 3b 0a 20 20 20 20 70  p->pDirty;.    p
5330: 2d 3e 70 44 69 72 74 79 20 3d 20 30 3b 0a 20 20  ->pDirty = 0;.  
5340: 20 20 66 6f 72 28 69 3d 30 3b 20 41 4c 57 41 59    for(i=0; ALWAY
5350: 53 28 69 3c 4e 5f 53 4f 52 54 5f 42 55 43 4b 45  S(i<N_SORT_BUCKE
5360: 54 2d 31 29 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  T-1); i++){.    
5370: 20 20 69 66 28 20 61 5b 69 5d 3d 3d 30 20 29 7b    if( a[i]==0 ){
5380: 0a 20 20 20 20 20 20 20 20 61 5b 69 5d 20 3d 20  .        a[i] = 
5390: 70 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b  p;.        break
53a0: 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20  ;.      }else{. 
53b0: 20 20 20 20 20 20 20 70 20 3d 20 70 63 61 63 68         p = pcach
53c0: 65 4d 65 72 67 65 44 69 72 74 79 4c 69 73 74 28  eMergeDirtyList(
53d0: 61 5b 69 5d 2c 20 70 29 3b 0a 20 20 20 20 20 20  a[i], p);.      
53e0: 20 20 61 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20    a[i] = 0;.    
53f0: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66    }.    }.    if
5400: 28 20 4e 45 56 45 52 28 69 3d 3d 4e 5f 53 4f 52  ( NEVER(i==N_SOR
5410: 54 5f 42 55 43 4b 45 54 2d 31 29 20 29 7b 0a 20  T_BUCKET-1) ){. 
5420: 20 20 20 20 20 2f 2a 20 54 6f 20 67 65 74 20 68       /* To get h
5430: 65 72 65 2c 20 74 68 65 72 65 20 6e 65 65 64 20  ere, there need 
5440: 74 6f 20 62 65 20 32 5e 28 4e 5f 53 4f 52 54 5f  to be 2^(N_SORT_
5450: 42 55 43 4b 45 54 29 20 65 6c 65 6d 65 6e 74 73  BUCKET) elements
5460: 20 69 6e 0a 20 20 20 20 20 20 2a 2a 20 74 68 65   in.      ** the
5470: 20 69 6e 70 75 74 20 6c 69 73 74 2e 20 20 42 75   input list.  Bu
5480: 74 20 74 68 61 74 20 69 73 20 69 6d 70 6f 73 73  t that is imposs
5490: 69 62 6c 65 2e 0a 20 20 20 20 20 20 2a 2f 0a 20  ible..      */. 
54a0: 20 20 20 20 20 61 5b 69 5d 20 3d 20 70 63 61 63       a[i] = pcac
54b0: 68 65 4d 65 72 67 65 44 69 72 74 79 4c 69 73 74  heMergeDirtyList
54c0: 28 61 5b 69 5d 2c 20 70 29 3b 0a 20 20 20 20 7d  (a[i], p);.    }
54d0: 0a 20 20 7d 0a 20 20 70 20 3d 20 61 5b 30 5d 3b  .  }.  p = a[0];
54e0: 0a 20 20 66 6f 72 28 69 3d 31 3b 20 69 3c 4e 5f  .  for(i=1; i<N_
54f0: 53 4f 52 54 5f 42 55 43 4b 45 54 3b 20 69 2b 2b  SORT_BUCKET; i++
5500: 29 7b 0a 20 20 20 20 70 20 3d 20 70 63 61 63 68  ){.    p = pcach
5510: 65 4d 65 72 67 65 44 69 72 74 79 4c 69 73 74 28  eMergeDirtyList(
5520: 70 2c 20 61 5b 69 5d 29 3b 0a 20 20 7d 0a 20 20  p, a[i]);.  }.  
5530: 72 65 74 75 72 6e 20 70 3b 0a 7d 0a 0a 2f 2a 0a  return p;.}../*.
5540: 2a 2a 20 52 65 74 75 72 6e 20 61 20 6c 69 73 74  ** Return a list
5550: 20 6f 66 20 61 6c 6c 20 64 69 72 74 79 20 70 61   of all dirty pa
5560: 67 65 73 20 69 6e 20 74 68 65 20 63 61 63 68 65  ges in the cache
5570: 2c 20 73 6f 72 74 65 64 20 62 79 20 70 61 67 65  , sorted by page
5580: 20 6e 75 6d 62 65 72 2e 0a 2a 2f 0a 50 67 48 64   number..*/.PgHd
5590: 72 20 2a 73 71 6c 69 74 65 33 50 63 61 63 68 65  r *sqlite3Pcache
55a0: 44 69 72 74 79 4c 69 73 74 28 50 43 61 63 68 65  DirtyList(PCache
55b0: 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 50 67 48   *pCache){.  PgH
55c0: 64 72 20 2a 70 3b 0a 20 20 66 6f 72 28 70 3d 70  dr *p;.  for(p=p
55d0: 43 61 63 68 65 2d 3e 70 44 69 72 74 79 3b 20 70  Cache->pDirty; p
55e0: 3b 20 70 3d 70 2d 3e 70 44 69 72 74 79 4e 65 78  ; p=p->pDirtyNex
55f0: 74 29 7b 0a 20 20 20 20 70 2d 3e 70 44 69 72 74  t){.    p->pDirt
5600: 79 20 3d 20 70 2d 3e 70 44 69 72 74 79 4e 65 78  y = p->pDirtyNex
5610: 74 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  t;.  }.  return 
5620: 70 63 61 63 68 65 53 6f 72 74 44 69 72 74 79 4c  pcacheSortDirtyL
5630: 69 73 74 28 70 43 61 63 68 65 2d 3e 70 44 69 72  ist(pCache->pDir
5640: 74 79 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 52  ty);.}../* .** R
5650: 65 74 75 72 6e 20 74 68 65 20 74 6f 74 61 6c 20  eturn the total 
5660: 6e 75 6d 62 65 72 20 6f 66 20 72 65 66 65 72 65  number of refere
5670: 6e 63 65 73 20 74 6f 20 61 6c 6c 20 70 61 67 65  nces to all page
5680: 73 20 68 65 6c 64 20 62 79 20 74 68 65 20 63 61  s held by the ca
5690: 63 68 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  che..**.** This 
56a0: 69 73 20 6e 6f 74 20 74 68 65 20 74 6f 74 61 6c  is not the total
56b0: 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73   number of pages
56c0: 20 72 65 66 65 72 65 6e 63 65 64 2c 20 62 75 74   referenced, but
56d0: 20 74 68 65 20 73 75 6d 20 6f 66 20 74 68 65 0a   the sum of the.
56e0: 2a 2a 20 72 65 66 65 72 65 6e 63 65 20 63 6f 75  ** reference cou
56f0: 6e 74 20 66 6f 72 20 61 6c 6c 20 70 61 67 65 73  nt for all pages
5700: 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33  ..*/.int sqlite3
5710: 50 63 61 63 68 65 52 65 66 43 6f 75 6e 74 28 50  PcacheRefCount(P
5720: 43 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b 0a  Cache *pCache){.
5730: 20 20 72 65 74 75 72 6e 20 70 43 61 63 68 65 2d    return pCache-
5740: 3e 6e 52 65 66 53 75 6d 3b 0a 7d 0a 0a 2f 2a 0a  >nRefSum;.}../*.
5750: 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 6e 75  ** Return the nu
5760: 6d 62 65 72 20 6f 66 20 72 65 66 65 72 65 6e 63  mber of referenc
5770: 65 73 20 74 6f 20 74 68 65 20 70 61 67 65 20 73  es to the page s
5780: 75 70 70 6c 69 65 64 20 61 73 20 61 6e 20 61 72  upplied as an ar
5790: 67 75 6d 65 6e 74 2e 0a 2a 2f 0a 69 6e 74 20 73  gument..*/.int s
57a0: 71 6c 69 74 65 33 50 63 61 63 68 65 50 61 67 65  qlite3PcachePage
57b0: 52 65 66 63 6f 75 6e 74 28 50 67 48 64 72 20 2a  Refcount(PgHdr *
57c0: 70 29 7b 0a 20 20 72 65 74 75 72 6e 20 70 2d 3e  p){.  return p->
57d0: 6e 52 65 66 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20  nRef;.}../* .** 
57e0: 52 65 74 75 72 6e 20 74 68 65 20 74 6f 74 61 6c  Return the total
57f0: 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73   number of pages
5800: 20 69 6e 20 74 68 65 20 63 61 63 68 65 2e 0a 2a   in the cache..*
5810: 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 50 63 61  /.int sqlite3Pca
5820: 63 68 65 50 61 67 65 63 6f 75 6e 74 28 50 43 61  chePagecount(PCa
5830: 63 68 65 20 2a 70 43 61 63 68 65 29 7b 0a 20 20  che *pCache){.  
5840: 61 73 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e  assert( pCache->
5850: 70 43 61 63 68 65 21 3d 30 20 29 3b 0a 20 20 72  pCache!=0 );.  r
5860: 65 74 75 72 6e 20 73 71 6c 69 74 65 33 47 6c 6f  eturn sqlite3Glo
5870: 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65  balConfig.pcache
5880: 32 2e 78 50 61 67 65 63 6f 75 6e 74 28 70 43 61  2.xPagecount(pCa
5890: 63 68 65 2d 3e 70 43 61 63 68 65 29 3b 0a 7d 0a  che->pCache);.}.
58a0: 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 54  .#ifdef SQLITE_T
58b0: 45 53 54 0a 2f 2a 0a 2a 2a 20 47 65 74 20 74 68  EST./*.** Get th
58c0: 65 20 73 75 67 67 65 73 74 65 64 20 63 61 63 68  e suggested cach
58d0: 65 2d 73 69 7a 65 20 76 61 6c 75 65 2e 0a 2a 2f  e-size value..*/
58e0: 0a 69 6e 74 20 73 71 6c 69 74 65 33 50 63 61 63  .int sqlite3Pcac
58f0: 68 65 47 65 74 43 61 63 68 65 73 69 7a 65 28 50  heGetCachesize(P
5900: 43 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b 0a  Cache *pCache){.
5910: 20 20 72 65 74 75 72 6e 20 6e 75 6d 62 65 72 4f    return numberO
5920: 66 43 61 63 68 65 50 61 67 65 73 28 70 43 61 63  fCachePages(pCac
5930: 68 65 29 3b 0a 7d 0a 23 65 6e 64 69 66 0a 0a 2f  he);.}.#endif../
5940: 2a 0a 2a 2a 20 53 65 74 20 74 68 65 20 73 75 67  *.** Set the sug
5950: 67 65 73 74 65 64 20 63 61 63 68 65 2d 73 69 7a  gested cache-siz
5960: 65 20 76 61 6c 75 65 2e 0a 2a 2f 0a 76 6f 69 64  e value..*/.void
5970: 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 53 65   sqlite3PcacheSe
5980: 74 43 61 63 68 65 73 69 7a 65 28 50 43 61 63 68  tCachesize(PCach
5990: 65 20 2a 70 43 61 63 68 65 2c 20 69 6e 74 20 6d  e *pCache, int m
59a0: 78 50 61 67 65 29 7b 0a 20 20 61 73 73 65 72 74  xPage){.  assert
59b0: 28 20 70 43 61 63 68 65 2d 3e 70 43 61 63 68 65  ( pCache->pCache
59c0: 21 3d 30 20 29 3b 0a 20 20 70 43 61 63 68 65 2d  !=0 );.  pCache-
59d0: 3e 73 7a 43 61 63 68 65 20 3d 20 6d 78 50 61 67  >szCache = mxPag
59e0: 65 3b 0a 20 20 73 71 6c 69 74 65 33 47 6c 6f 62  e;.  sqlite3Glob
59f0: 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65 32  alConfig.pcache2
5a00: 2e 78 43 61 63 68 65 73 69 7a 65 28 70 43 61 63  .xCachesize(pCac
5a10: 68 65 2d 3e 70 43 61 63 68 65 2c 0a 20 20 20 20  he->pCache,.    
5a20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5a30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5a40: 20 20 20 20 20 6e 75 6d 62 65 72 4f 66 43 61 63       numberOfCac
5a50: 68 65 50 61 67 65 73 28 70 43 61 63 68 65 29 29  hePages(pCache))
5a60: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20 74  ;.}../*.** Set t
5a70: 68 65 20 73 75 67 67 65 73 74 65 64 20 63 61 63  he suggested cac
5a80: 68 65 2d 73 70 69 6c 6c 20 76 61 6c 75 65 2e 20  he-spill value. 
5a90: 20 4d 61 6b 65 20 6e 6f 20 63 68 61 6e 67 65 73   Make no changes
5aa0: 20 69 66 20 69 66 20 74 68 65 0a 2a 2a 20 61 72   if if the.** ar
5ab0: 67 75 6d 65 6e 74 20 69 73 20 7a 65 72 6f 2e 20  gument is zero. 
5ac0: 20 52 65 74 75 72 6e 20 74 68 65 20 65 66 66 65   Return the effe
5ad0: 63 74 69 76 65 20 63 61 63 68 65 2d 73 70 69 6c  ctive cache-spil
5ae0: 6c 20 73 69 7a 65 2c 20 77 68 69 63 68 20 77 69  l size, which wi
5af0: 6c 6c 0a 2a 2a 20 62 65 20 74 68 65 20 6c 61 72  ll.** be the lar
5b00: 67 65 72 20 6f 66 20 74 68 65 20 73 7a 53 70 69  ger of the szSpi
5b10: 6c 6c 20 61 6e 64 20 73 7a 43 61 63 68 65 2e 0a  ll and szCache..
5b20: 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 50 63  */.int sqlite3Pc
5b30: 61 63 68 65 53 65 74 53 70 69 6c 6c 73 69 7a 65  acheSetSpillsize
5b40: 28 50 43 61 63 68 65 20 2a 70 2c 20 69 6e 74 20  (PCache *p, int 
5b50: 6d 78 50 61 67 65 29 7b 0a 20 20 69 6e 74 20 72  mxPage){.  int r
5b60: 65 73 3b 0a 20 20 61 73 73 65 72 74 28 20 70 2d  es;.  assert( p-
5b70: 3e 70 43 61 63 68 65 21 3d 30 20 29 3b 0a 20 20  >pCache!=0 );.  
5b80: 69 66 28 20 6d 78 50 61 67 65 20 29 7b 0a 20 20  if( mxPage ){.  
5b90: 20 20 69 66 28 20 6d 78 50 61 67 65 3c 30 20 29    if( mxPage<0 )
5ba0: 7b 0a 20 20 20 20 20 20 6d 78 50 61 67 65 20 3d  {.      mxPage =
5bb0: 20 28 69 6e 74 29 28 28 2d 31 30 32 34 2a 28 69   (int)((-1024*(i
5bc0: 36 34 29 6d 78 50 61 67 65 29 2f 28 70 2d 3e 73  64)mxPage)/(p->s
5bd0: 7a 50 61 67 65 2b 70 2d 3e 73 7a 45 78 74 72 61  zPage+p->szExtra
5be0: 29 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 2d  ));.    }.    p-
5bf0: 3e 73 7a 53 70 69 6c 6c 20 3d 20 6d 78 50 61 67  >szSpill = mxPag
5c00: 65 3b 0a 20 20 7d 0a 20 20 72 65 73 20 3d 20 6e  e;.  }.  res = n
5c10: 75 6d 62 65 72 4f 66 43 61 63 68 65 50 61 67 65  umberOfCachePage
5c20: 73 28 70 29 3b 0a 20 20 69 66 28 20 72 65 73 3c  s(p);.  if( res<
5c30: 70 2d 3e 73 7a 53 70 69 6c 6c 20 29 20 72 65 73  p->szSpill ) res
5c40: 20 3d 20 70 2d 3e 73 7a 53 70 69 6c 6c 3b 20 0a   = p->szSpill; .
5c50: 20 20 72 65 74 75 72 6e 20 72 65 73 3b 0a 7d 0a    return res;.}.
5c60: 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 75 70 20 61  ./*.** Free up a
5c70: 73 20 6d 75 63 68 20 6d 65 6d 6f 72 79 20 61 73  s much memory as
5c80: 20 70 6f 73 73 69 62 6c 65 20 66 72 6f 6d 20 74   possible from t
5c90: 68 65 20 70 61 67 65 20 63 61 63 68 65 2e 0a 2a  he page cache..*
5ca0: 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63  /.void sqlite3Pc
5cb0: 61 63 68 65 53 68 72 69 6e 6b 28 50 43 61 63 68  acheShrink(PCach
5cc0: 65 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 61 73  e *pCache){.  as
5cd0: 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e 70 43  sert( pCache->pC
5ce0: 61 63 68 65 21 3d 30 20 29 3b 0a 20 20 73 71 6c  ache!=0 );.  sql
5cf0: 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67  ite3GlobalConfig
5d00: 2e 70 63 61 63 68 65 32 2e 78 53 68 72 69 6e 6b  .pcache2.xShrink
5d10: 28 70 43 61 63 68 65 2d 3e 70 43 61 63 68 65 29  (pCache->pCache)
5d20: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72  ;.}../*.** Retur
5d30: 6e 20 74 68 65 20 73 69 7a 65 20 6f 66 20 74 68  n the size of th
5d40: 65 20 68 65 61 64 65 72 20 61 64 64 65 64 20 62  e header added b
5d50: 79 20 74 68 69 73 20 6d 69 64 64 6c 65 77 61 72  y this middlewar
5d60: 65 20 6c 61 79 65 72 0a 2a 2a 20 69 6e 20 74 68  e layer.** in th
5d70: 65 20 70 61 67 65 2d 63 61 63 68 65 20 68 69 65  e page-cache hie
5d80: 72 61 72 63 68 79 2e 0a 2a 2f 0a 69 6e 74 20 73  rarchy..*/.int s
5d90: 71 6c 69 74 65 33 48 65 61 64 65 72 53 69 7a 65  qlite3HeaderSize
5da0: 50 63 61 63 68 65 28 76 6f 69 64 29 7b 20 72 65  Pcache(void){ re
5db0: 74 75 72 6e 20 52 4f 55 4e 44 38 28 73 69 7a 65  turn ROUND8(size
5dc0: 6f 66 28 50 67 48 64 72 29 29 3b 20 7d 0a 0a 2f  of(PgHdr)); }../
5dd0: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20  *.** Return the 
5de0: 6e 75 6d 62 65 72 20 6f 66 20 64 69 72 74 79 20  number of dirty 
5df0: 70 61 67 65 73 20 63 75 72 72 65 6e 74 6c 79 20  pages currently 
5e00: 69 6e 20 74 68 65 20 63 61 63 68 65 2c 20 61 73  in the cache, as
5e10: 20 61 20 70 65 72 63 65 6e 74 61 67 65 0a 2a 2a   a percentage.**
5e20: 20 6f 66 20 74 68 65 20 63 6f 6e 66 69 67 75 72   of the configur
5e30: 65 64 20 63 61 63 68 65 20 73 69 7a 65 2e 0a 2a  ed cache size..*
5e40: 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 50 43 61  /.int sqlite3PCa
5e50: 63 68 65 50 65 72 63 65 6e 74 44 69 72 74 79 28  chePercentDirty(
5e60: 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b  PCache *pCache){
5e70: 0a 20 20 50 67 48 64 72 20 2a 70 44 69 72 74 79  .  PgHdr *pDirty
5e80: 3b 0a 20 20 69 6e 74 20 6e 44 69 72 74 79 20 3d  ;.  int nDirty =
5e90: 20 30 3b 0a 20 20 69 6e 74 20 6e 43 61 63 68 65   0;.  int nCache
5ea0: 20 3d 20 6e 75 6d 62 65 72 4f 66 43 61 63 68 65   = numberOfCache
5eb0: 50 61 67 65 73 28 70 43 61 63 68 65 29 3b 0a 20  Pages(pCache);. 
5ec0: 20 66 6f 72 28 70 44 69 72 74 79 3d 70 43 61 63   for(pDirty=pCac
5ed0: 68 65 2d 3e 70 44 69 72 74 79 3b 20 70 44 69 72  he->pDirty; pDir
5ee0: 74 79 3b 20 70 44 69 72 74 79 3d 70 44 69 72 74  ty; pDirty=pDirt
5ef0: 79 2d 3e 70 44 69 72 74 79 4e 65 78 74 29 20 6e  y->pDirtyNext) n
5f00: 44 69 72 74 79 2b 2b 3b 0a 20 20 72 65 74 75 72  Dirty++;.  retur
5f10: 6e 20 6e 43 61 63 68 65 20 3f 20 28 69 6e 74 29  n nCache ? (int)
5f20: 28 28 28 69 36 34 29 6e 44 69 72 74 79 20 2a 20  (((i64)nDirty * 
5f30: 31 30 30 29 20 2f 20 6e 43 61 63 68 65 29 20 3a  100) / nCache) :
5f40: 20 30 3b 0a 7d 0a 0a 23 69 66 20 64 65 66 69 6e   0;.}..#if defin
5f50: 65 64 28 53 51 4c 49 54 45 5f 43 48 45 43 4b 5f  ed(SQLITE_CHECK_
5f60: 50 41 47 45 53 29 20 7c 7c 20 64 65 66 69 6e 65  PAGES) || define
5f70: 64 28 53 51 4c 49 54 45 5f 44 45 42 55 47 29 0a  d(SQLITE_DEBUG).
5f80: 2f 2a 0a 2a 2a 20 46 6f 72 20 61 6c 6c 20 64 69  /*.** For all di
5f90: 72 74 79 20 70 61 67 65 73 20 63 75 72 72 65 6e  rty pages curren
5fa0: 74 6c 79 20 69 6e 20 74 68 65 20 63 61 63 68 65  tly in the cache
5fb0: 2c 20 69 6e 76 6f 6b 65 20 74 68 65 20 73 70 65  , invoke the spe
5fc0: 63 69 66 69 65 64 0a 2a 2a 20 63 61 6c 6c 62 61  cified.** callba
5fd0: 63 6b 2e 20 54 68 69 73 20 69 73 20 6f 6e 6c 79  ck. This is only
5fe0: 20 75 73 65 64 20 69 66 20 74 68 65 20 53 51 4c   used if the SQL
5ff0: 49 54 45 5f 43 48 45 43 4b 5f 50 41 47 45 53 20  ITE_CHECK_PAGES 
6000: 6d 61 63 72 6f 20 69 73 0a 2a 2a 20 64 65 66 69  macro is.** defi
6010: 6e 65 64 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c  ned..*/.void sql
6020: 69 74 65 33 50 63 61 63 68 65 49 74 65 72 61 74  ite3PcacheIterat
6030: 65 44 69 72 74 79 28 50 43 61 63 68 65 20 2a 70  eDirty(PCache *p
6040: 43 61 63 68 65 2c 20 76 6f 69 64 20 28 2a 78 49  Cache, void (*xI
6050: 74 65 72 29 28 50 67 48 64 72 20 2a 29 29 7b 0a  ter)(PgHdr *)){.
6060: 20 20 50 67 48 64 72 20 2a 70 44 69 72 74 79 3b    PgHdr *pDirty;
6070: 0a 20 20 66 6f 72 28 70 44 69 72 74 79 3d 70 43  .  for(pDirty=pC
6080: 61 63 68 65 2d 3e 70 44 69 72 74 79 3b 20 70 44  ache->pDirty; pD
6090: 69 72 74 79 3b 20 70 44 69 72 74 79 3d 70 44 69  irty; pDirty=pDi
60a0: 72 74 79 2d 3e 70 44 69 72 74 79 4e 65 78 74 29  rty->pDirtyNext)
60b0: 7b 0a 20 20 20 20 78 49 74 65 72 28 70 44 69 72  {.    xIter(pDir
60c0: 74 79 29 3b 0a 20 20 7d 0a 7d 0a 23 65 6e 64 69  ty);.  }.}.#endi
60d0: 66 0a                                            f.