/ Hex Artifact Content
Login

Artifact ad5ce697dc5a734caddb2b1eac83b195da95ddbe:


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 20 20 45 76 65 72 79 0a 2a 2a 20  ture.  Every.** 
0200: 65 6e 74 72 79 20 69 6e 20 74 68 65 20 63 61 63  entry in the cac
0210: 68 65 20 68 6f 6c 64 73 20 61 20 73 69 6e 67 6c  he holds a singl
0220: 65 20 70 61 67 65 20 6f 66 20 74 68 65 20 64 61  e page of the da
0230: 74 61 62 61 73 65 20 66 69 6c 65 2e 20 20 54 68  tabase file.  Th
0240: 65 0a 2a 2a 20 62 74 72 65 65 20 6c 61 79 65 72  e.** btree layer
0250: 20 6f 6e 6c 79 20 6f 70 65 72 61 74 65 73 20 6f   only operates o
0260: 6e 20 74 68 65 20 63 61 63 68 65 64 20 63 6f 70  n the cached cop
0270: 79 20 6f 66 20 74 68 65 20 64 61 74 61 62 61 73  y of the databas
0280: 65 20 70 61 67 65 73 2e 0a 2a 2a 0a 2a 2a 20 41  e pages..**.** A
0290: 20 70 61 67 65 20 63 61 63 68 65 20 65 6e 74 72   page cache entr
02a0: 79 20 69 73 20 22 63 6c 65 61 6e 22 20 69 66 20  y is "clean" if 
02b0: 69 74 20 65 78 61 63 74 6c 79 20 6d 61 74 63 68  it exactly match
02c0: 65 73 20 77 68 61 74 20 69 73 20 63 75 72 72 65  es what is curre
02d0: 6e 74 6c 79 0a 2a 2a 20 6f 6e 20 64 69 73 6b 2e  ntly.** on disk.
02e0: 20 20 41 20 70 61 67 65 20 69 73 20 22 64 69 72    A page is "dir
02f0: 74 79 22 20 69 66 20 69 74 20 68 61 73 20 62 65  ty" if it has be
0300: 65 6e 20 6d 6f 64 69 66 69 65 64 20 61 6e 64 20  en modified and 
0310: 6e 65 65 64 73 20 74 6f 20 62 65 0a 2a 2a 20 70  needs to be.** p
0320: 65 72 73 69 73 74 65 64 20 74 6f 20 64 69 73 6b  ersisted to disk
0330: 2e 0a 2a 2a 0a 2a 2a 20 70 44 69 72 74 79 2c 20  ..**.** pDirty, 
0340: 70 44 69 72 74 79 54 61 69 6c 2c 20 70 53 79 6e  pDirtyTail, pSyn
0350: 63 65 64 3a 0a 2a 2a 20 20 20 41 6c 6c 20 64 69  ced:.**   All di
0360: 72 74 79 20 70 61 67 65 73 20 61 72 65 20 6c 69  rty pages are li
0370: 6e 6b 65 64 20 69 6e 74 6f 20 74 68 65 20 64 6f  nked into the do
0380: 75 62 6c 79 20 6c 69 6e 6b 65 64 20 6c 69 73 74  ubly linked list
0390: 20 75 73 69 6e 67 0a 2a 2a 20 20 20 50 67 48 64   using.**   PgHd
03a0: 72 2e 70 44 69 72 74 79 4e 65 78 74 20 61 6e 64  r.pDirtyNext and
03b0: 20 70 44 69 72 74 79 50 72 65 76 2e 20 54 68 65   pDirtyPrev. The
03c0: 20 6c 69 73 74 20 69 73 20 6d 61 69 6e 74 61 69   list is maintai
03d0: 6e 65 64 20 69 6e 20 4c 52 55 20 6f 72 64 65 72  ned in LRU order
03e0: 0a 2a 2a 20 20 20 73 75 63 68 20 74 68 61 74 20  .**   such that 
03f0: 70 20 77 61 73 20 61 64 64 65 64 20 74 6f 20 74  p was added to t
0400: 68 65 20 6c 69 73 74 20 6d 6f 72 65 20 72 65 63  he list more rec
0410: 65 6e 74 6c 79 20 74 68 61 6e 20 70 2d 3e 70 44  ently than p->pD
0420: 69 72 74 79 4e 65 78 74 2e 0a 2a 2a 20 20 20 50  irtyNext..**   P
0430: 43 61 63 68 65 2e 70 44 69 72 74 79 20 70 6f 69  Cache.pDirty poi
0440: 6e 74 73 20 74 6f 20 74 68 65 20 66 69 72 73 74  nts to the first
0450: 20 28 6e 65 77 65 73 74 29 20 65 6c 65 6d 65 6e   (newest) elemen
0460: 74 20 69 6e 20 74 68 65 20 6c 69 73 74 20 61 6e  t in the list an
0470: 64 0a 2a 2a 20 20 20 70 44 69 72 74 79 54 61 69  d.**   pDirtyTai
0480: 6c 20 74 6f 20 74 68 65 20 6c 61 73 74 20 28 6f  l to the last (o
0490: 6c 64 65 73 74 29 2e 0a 2a 2a 0a 2a 2a 20 20 20  ldest)..**.**   
04a0: 54 68 65 20 50 43 61 63 68 65 2e 70 53 79 6e 63  The PCache.pSync
04b0: 65 64 20 76 61 72 69 61 62 6c 65 20 69 73 20 75  ed variable is u
04c0: 73 65 64 20 74 6f 20 6f 70 74 69 6d 69 7a 65 20  sed to optimize 
04d0: 73 65 61 72 63 68 69 6e 67 20 66 6f 72 20 61 20  searching for a 
04e0: 64 69 72 74 79 0a 2a 2a 20 20 20 70 61 67 65 20  dirty.**   page 
04f0: 74 6f 20 65 6a 65 63 74 20 66 72 6f 6d 20 74 68  to eject from th
0500: 65 20 63 61 63 68 65 20 6d 69 64 2d 74 72 61 6e  e cache mid-tran
0510: 73 61 63 74 69 6f 6e 2e 20 49 74 20 69 73 20 62  saction. It is b
0520: 65 74 74 65 72 20 74 6f 20 65 6a 65 63 74 0a 2a  etter to eject.*
0530: 2a 20 20 20 61 20 70 61 67 65 20 74 68 61 74 20  *   a page that 
0540: 64 6f 65 73 20 6e 6f 74 20 72 65 71 75 69 72 65  does not require
0550: 20 61 20 6a 6f 75 72 6e 61 6c 20 73 79 6e 63 20   a journal sync 
0560: 74 68 61 6e 20 6f 6e 65 20 74 68 61 74 20 64 6f  than one that do
0570: 65 73 2e 20 0a 2a 2a 20 20 20 54 68 65 72 65 66  es. .**   Theref
0580: 6f 72 65 2c 20 70 53 79 6e 63 65 64 20 69 73 20  ore, pSynced is 
0590: 6d 61 69 6e 74 61 69 6e 65 64 20 74 6f 20 74 68  maintained to th
05a0: 61 74 20 69 74 20 2a 61 6c 6d 6f 73 74 2a 20 61  at it *almost* a
05b0: 6c 77 61 79 73 20 70 6f 69 6e 74 73 0a 2a 2a 20  lways points.** 
05c0: 20 20 74 6f 20 65 69 74 68 65 72 20 74 68 65 20    to either the 
05d0: 6f 6c 64 65 73 74 20 70 61 67 65 20 69 6e 20 74  oldest page in t
05e0: 68 65 20 70 44 69 72 74 79 2f 70 44 69 72 74 79  he pDirty/pDirty
05f0: 54 61 69 6c 20 6c 69 73 74 20 74 68 61 74 20 68  Tail list that h
0600: 61 73 20 61 0a 2a 2a 20 20 20 63 6c 65 61 72 20  as a.**   clear 
0610: 50 47 48 44 52 5f 4e 45 45 44 5f 53 59 4e 43 20  PGHDR_NEED_SYNC 
0620: 66 6c 61 67 20 6f 72 20 74 6f 20 61 20 70 61 67  flag or to a pag
0630: 65 20 74 68 61 74 20 69 73 20 6f 6c 64 65 72 20  e that is older 
0640: 74 68 61 6e 20 74 68 69 73 20 6f 6e 65 0a 2a 2a  than this one.**
0650: 20 20 20 28 73 6f 20 74 68 61 74 20 74 68 65 20     (so that the 
0660: 72 69 67 68 74 20 70 61 67 65 20 74 6f 20 65 6a  right page to ej
0670: 65 63 74 20 63 61 6e 20 62 65 20 66 6f 75 6e 64  ect can be found
0680: 20 62 79 20 66 6f 6c 6c 6f 77 69 6e 67 20 70 44   by following pD
0690: 69 72 74 79 50 72 65 76 0a 2a 2a 20 20 20 70 6f  irtyPrev.**   po
06a0: 69 6e 74 65 72 73 29 2e 0a 2a 2f 0a 73 74 72 75  inters)..*/.stru
06b0: 63 74 20 50 43 61 63 68 65 20 7b 0a 20 20 50 67  ct PCache {.  Pg
06c0: 48 64 72 20 2a 70 44 69 72 74 79 2c 20 2a 70 44  Hdr *pDirty, *pD
06d0: 69 72 74 79 54 61 69 6c 3b 20 20 20 20 20 20 20  irtyTail;       
06e0: 20 20 2f 2a 20 4c 69 73 74 20 6f 66 20 64 69 72    /* List of dir
06f0: 74 79 20 70 61 67 65 73 20 69 6e 20 4c 52 55 20  ty pages in LRU 
0700: 6f 72 64 65 72 20 2a 2f 0a 20 20 50 67 48 64 72  order */.  PgHdr
0710: 20 2a 70 53 79 6e 63 65 64 3b 20 20 20 20 20 20   *pSynced;      
0720: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0730: 2a 20 4c 61 73 74 20 73 79 6e 63 65 64 20 70 61  * Last synced pa
0740: 67 65 20 69 6e 20 64 69 72 74 79 20 70 61 67 65  ge in dirty page
0750: 20 6c 69 73 74 20 2a 2f 0a 20 20 69 6e 74 20 6e   list */.  int n
0760: 52 65 66 53 75 6d 3b 20 20 20 20 20 20 20 20 20  RefSum;         
0770: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0780: 2a 20 53 75 6d 20 6f 66 20 72 65 66 20 63 6f 75  * Sum of ref cou
0790: 6e 74 73 20 6f 76 65 72 20 61 6c 6c 20 70 61 67  nts over all pag
07a0: 65 73 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 43 61  es */.  int szCa
07b0: 63 68 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  che;            
07c0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
07d0: 6f 6e 66 69 67 75 72 65 64 20 63 61 63 68 65 20  onfigured cache 
07e0: 73 69 7a 65 20 2a 2f 0a 20 20 69 6e 74 20 73 7a  size */.  int sz
07f0: 53 70 69 6c 6c 3b 20 20 20 20 20 20 20 20 20 20  Spill;          
0800: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0810: 20 53 69 7a 65 20 62 65 66 6f 72 65 20 73 70 69   Size before spi
0820: 6c 6c 69 6e 67 20 6f 63 63 75 72 73 20 2a 2f 0a  lling occurs */.
0830: 20 20 69 6e 74 20 73 7a 50 61 67 65 3b 20 20 20    int szPage;   
0840: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0850: 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66        /* Size of
0860: 20 65 76 65 72 79 20 70 61 67 65 20 69 6e 20 74   every page in t
0870: 68 69 73 20 63 61 63 68 65 20 2a 2f 0a 20 20 69  his cache */.  i
0880: 6e 74 20 73 7a 45 78 74 72 61 3b 20 20 20 20 20  nt szExtra;     
0890: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
08a0: 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 65 78     /* Size of ex
08b0: 74 72 61 20 73 70 61 63 65 20 66 6f 72 20 65 61  tra space for ea
08c0: 63 68 20 70 61 67 65 20 2a 2f 0a 20 20 75 38 20  ch page */.  u8 
08d0: 62 50 75 72 67 65 61 62 6c 65 3b 20 20 20 20 20  bPurgeable;     
08e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
08f0: 20 2f 2a 20 54 72 75 65 20 69 66 20 70 61 67 65   /* True if page
0900: 73 20 61 72 65 20 6f 6e 20 62 61 63 6b 69 6e 67  s are on backing
0910: 20 73 74 6f 72 65 20 2a 2f 0a 20 20 75 38 20 65   store */.  u8 e
0920: 43 72 65 61 74 65 3b 20 20 20 20 20 20 20 20 20  Create;         
0930: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0940: 2f 2a 20 65 43 72 65 61 74 65 20 76 61 6c 75 65  /* eCreate value
0950: 20 66 6f 72 20 66 6f 72 20 78 46 65 74 63 68 28   for for xFetch(
0960: 29 20 2a 2f 0a 20 20 69 6e 74 20 28 2a 78 53 74  ) */.  int (*xSt
0970: 72 65 73 73 29 28 76 6f 69 64 2a 2c 50 67 48 64  ress)(void*,PgHd
0980: 72 2a 29 3b 20 20 20 20 20 20 20 2f 2a 20 43 61  r*);       /* Ca
0990: 6c 6c 20 74 6f 20 74 72 79 20 6d 61 6b 65 20 61  ll to try make a
09a0: 20 70 61 67 65 20 63 6c 65 61 6e 20 2a 2f 0a 20   page clean */. 
09b0: 20 76 6f 69 64 20 2a 70 53 74 72 65 73 73 3b 20   void *pStress; 
09c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
09d0: 20 20 20 20 20 2f 2a 20 41 72 67 75 6d 65 6e 74       /* Argument
09e0: 20 74 6f 20 78 53 74 72 65 73 73 20 2a 2f 0a 20   to xStress */. 
09f0: 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20   sqlite3_pcache 
0a00: 2a 70 43 61 63 68 65 3b 20 20 20 20 20 20 20 20  *pCache;        
0a10: 20 20 20 20 20 2f 2a 20 50 6c 75 67 67 61 62 6c       /* Pluggabl
0a20: 65 20 63 61 63 68 65 20 6d 6f 64 75 6c 65 20 2a  e cache module *
0a30: 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 44 65 62 75  /.};../*.** Debu
0a40: 67 20 74 72 61 63 69 6e 67 20 6d 61 63 72 6f 73  g tracing macros
0a50: 0a 2a 2f 0a 23 69 66 20 64 65 66 69 6e 65 64 28  .*/.#if defined(
0a60: 53 51 4c 49 54 45 5f 44 45 42 55 47 29 20 26 26  SQLITE_DEBUG) &&
0a70: 20 30 0a 20 20 69 6e 74 20 73 71 6c 69 74 65 33   0.  int sqlite3
0a80: 50 63 61 63 68 65 54 72 61 63 65 20 3d 20 32 3b  PcacheTrace = 2;
0a90: 0a 23 20 64 65 66 69 6e 65 20 70 63 61 63 68 65  .# define pcache
0aa0: 54 72 61 63 65 28 58 29 20 69 66 28 73 71 6c 69  Trace(X) if(sqli
0ab0: 74 65 33 50 63 61 63 68 65 54 72 61 63 65 29 7b  te3PcacheTrace){
0ac0: 73 71 6c 69 74 65 33 44 65 62 75 67 50 72 69 6e  sqlite3DebugPrin
0ad0: 74 66 20 58 3b 7d 0a 20 20 76 6f 69 64 20 70 63  tf X;}.  void pc
0ae0: 61 63 68 65 44 75 6d 70 28 50 43 61 63 68 65 20  acheDump(PCache 
0af0: 2a 70 43 61 63 68 65 29 7b 0a 20 20 20 20 69 6e  *pCache){.    in
0b00: 74 20 4e 3b 0a 20 20 20 20 69 6e 74 20 69 2c 20  t N;.    int i, 
0b10: 6a 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 70  j;.    sqlite3_p
0b20: 63 61 63 68 65 5f 70 61 67 65 20 2a 70 4c 6f 77  cache_page *pLow
0b30: 65 72 3b 0a 20 20 20 20 50 67 48 64 72 20 2a 70  er;.    PgHdr *p
0b40: 50 67 3b 0a 20 20 20 20 75 6e 73 69 67 6e 65 64  Pg;.    unsigned
0b50: 20 63 68 61 72 20 2a 61 3b 0a 20 20 0a 20 20 20   char *a;.  .   
0b60: 20 69 66 28 20 73 71 6c 69 74 65 33 50 63 61 63   if( sqlite3Pcac
0b70: 68 65 54 72 61 63 65 3c 32 20 29 20 72 65 74 75  heTrace<2 ) retu
0b80: 72 6e 3b 0a 20 20 20 20 69 66 28 20 70 43 61 63  rn;.    if( pCac
0b90: 68 65 2d 3e 70 43 61 63 68 65 3d 3d 30 20 29 20  he->pCache==0 ) 
0ba0: 72 65 74 75 72 6e 3b 0a 20 20 20 20 4e 20 3d 20  return;.    N = 
0bb0: 73 71 6c 69 74 65 33 50 63 61 63 68 65 50 61 67  sqlite3PcachePag
0bc0: 65 63 6f 75 6e 74 28 70 43 61 63 68 65 29 3b 0a  ecount(pCache);.
0bd0: 20 20 20 20 69 66 28 20 4e 3e 35 20 29 20 4e 20      if( N>5 ) N 
0be0: 3d 20 35 3b 0a 20 20 20 20 66 6f 72 28 69 3d 31  = 5;.    for(i=1
0bf0: 3b 20 69 3c 3d 4e 3b 20 69 2b 2b 29 7b 0a 20 20  ; i<=N; i++){.  
0c00: 20 20 20 20 20 70 4c 6f 77 65 72 20 3d 20 73 71       pLower = sq
0c10: 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69  lite3GlobalConfi
0c20: 67 2e 70 63 61 63 68 65 32 2e 78 46 65 74 63 68  g.pcache2.xFetch
0c30: 28 70 43 61 63 68 65 2d 3e 70 43 61 63 68 65 2c  (pCache->pCache,
0c40: 20 69 2c 20 30 29 3b 0a 20 20 20 20 20 20 20 69   i, 0);.       i
0c50: 66 28 20 70 4c 6f 77 65 72 3d 3d 30 20 29 20 63  f( pLower==0 ) c
0c60: 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20 20 20  ontinue;.       
0c70: 70 50 67 20 3d 20 28 50 67 48 64 72 2a 29 70 4c  pPg = (PgHdr*)pL
0c80: 6f 77 65 72 2d 3e 70 45 78 74 72 61 3b 0a 20 20  ower->pExtra;.  
0c90: 20 20 20 20 20 70 72 69 6e 74 66 28 22 25 33 64       printf("%3d
0ca0: 3a 20 6e 52 65 66 20 25 32 64 20 66 6c 67 73 20  : nRef %2d flgs 
0cb0: 25 30 32 78 20 64 61 74 61 20 22 2c 20 69 2c 20  %02x data ", i, 
0cc0: 70 50 67 2d 3e 6e 52 65 66 2c 20 70 50 67 2d 3e  pPg->nRef, pPg->
0cd0: 66 6c 61 67 73 29 3b 0a 20 20 20 20 20 20 20 61  flags);.       a
0ce0: 20 3d 20 28 75 6e 73 69 67 6e 65 64 20 63 68 61   = (unsigned cha
0cf0: 72 20 2a 29 70 4c 6f 77 65 72 2d 3e 70 42 75 66  r *)pLower->pBuf
0d00: 3b 0a 20 20 20 20 20 20 20 66 6f 72 28 6a 3d 30  ;.       for(j=0
0d10: 3b 20 6a 3c 31 32 3b 20 6a 2b 2b 29 20 70 72 69  ; j<12; j++) pri
0d20: 6e 74 66 28 22 25 30 32 78 22 2c 20 61 5b 6a 5d  ntf("%02x", a[j]
0d30: 29 3b 0a 20 20 20 20 20 20 20 70 72 69 6e 74 66  );.       printf
0d40: 28 22 5c 6e 22 29 3b 0a 20 20 20 20 20 20 20 69  ("\n");.       i
0d50: 66 28 20 70 50 67 2d 3e 70 50 61 67 65 3d 3d 30  f( pPg->pPage==0
0d60: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 73 71 6c   ){.         sql
0d70: 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67  ite3GlobalConfig
0d80: 2e 70 63 61 63 68 65 32 2e 78 55 6e 70 69 6e 28  .pcache2.xUnpin(
0d90: 70 43 61 63 68 65 2d 3e 70 43 61 63 68 65 2c 20  pCache->pCache, 
0da0: 70 4c 6f 77 65 72 2c 20 30 29 3b 0a 20 20 20 20  pLower, 0);.    
0db0: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20     }.    }.  }. 
0dc0: 20 23 65 6c 73 65 0a 23 20 64 65 66 69 6e 65 20   #else.# define 
0dd0: 70 63 61 63 68 65 54 72 61 63 65 28 58 29 0a 23  pcacheTrace(X).#
0de0: 20 64 65 66 69 6e 65 20 70 63 61 63 68 65 44 75   define pcacheDu
0df0: 6d 70 28 58 29 0a 23 65 6e 64 69 66 0a 0a 2f 2a  mp(X).#endif../*
0e00: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0e10: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0e20: 2a 20 4c 69 6e 6b 65 64 20 4c 69 73 74 20 4d 61  * Linked List Ma
0e30: 6e 61 67 65 6d 65 6e 74 20 2a 2a 2a 2a 2a 2a 2a  nagement *******
0e40: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a  *************/..
0e50: 2f 2a 20 41 6c 6c 6f 77 65 64 20 76 61 6c 75 65  /* Allowed value
0e60: 73 20 66 6f 72 20 73 65 63 6f 6e 64 20 61 72 67  s for second arg
0e70: 75 6d 65 6e 74 20 74 6f 20 70 63 61 63 68 65 4d  ument to pcacheM
0e80: 61 6e 61 67 65 44 69 72 74 79 4c 69 73 74 28 29  anageDirtyList()
0e90: 20 2a 2f 0a 23 64 65 66 69 6e 65 20 50 43 41 43   */.#define PCAC
0ea0: 48 45 5f 44 49 52 54 59 4c 49 53 54 5f 52 45 4d  HE_DIRTYLIST_REM
0eb0: 4f 56 45 20 20 20 31 20 20 20 20 2f 2a 20 52 65  OVE   1    /* Re
0ec0: 6d 6f 76 65 20 70 50 61 67 65 20 66 72 6f 6d 20  move pPage from 
0ed0: 64 69 72 74 79 20 6c 69 73 74 20 2a 2f 0a 23 64  dirty list */.#d
0ee0: 65 66 69 6e 65 20 50 43 41 43 48 45 5f 44 49 52  efine PCACHE_DIR
0ef0: 54 59 4c 49 53 54 5f 41 44 44 20 20 20 20 20 20  TYLIST_ADD      
0f00: 32 20 20 20 20 2f 2a 20 41 64 64 20 70 50 61 67  2    /* Add pPag
0f10: 65 20 74 6f 20 74 68 65 20 64 69 72 74 79 20 6c  e to the dirty l
0f20: 69 73 74 20 2a 2f 0a 23 64 65 66 69 6e 65 20 50  ist */.#define P
0f30: 43 41 43 48 45 5f 44 49 52 54 59 4c 49 53 54 5f  CACHE_DIRTYLIST_
0f40: 46 52 4f 4e 54 20 20 20 20 33 20 20 20 20 2f 2a  FRONT    3    /*
0f50: 20 4d 6f 76 65 20 70 50 61 67 65 20 74 6f 20 74   Move pPage to t
0f60: 68 65 20 66 72 6f 6e 74 20 6f 66 20 74 68 65 20  he front of the 
0f70: 6c 69 73 74 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 4d  list */../*.** M
0f80: 61 6e 61 67 65 20 70 50 61 67 65 27 73 20 70 61  anage pPage's pa
0f90: 72 74 69 63 69 70 61 74 69 6f 6e 20 6f 6e 20 74  rticipation on t
0fa0: 68 65 20 64 69 72 74 79 20 6c 69 73 74 2e 20 20  he dirty list.  
0fb0: 42 69 74 73 20 6f 66 20 74 68 65 20 61 64 64 52  Bits of the addR
0fc0: 65 6d 6f 76 65 0a 2a 2a 20 61 72 67 75 6d 65 6e  emove.** argumen
0fd0: 74 20 64 65 74 65 72 6d 69 6e 65 73 20 77 68 61  t determines wha
0fe0: 74 20 6f 70 65 72 61 74 69 6f 6e 20 74 6f 20 64  t operation to d
0ff0: 6f 2e 20 20 54 68 65 20 30 78 30 31 20 62 69 74  o.  The 0x01 bit
1000: 20 6d 65 61 6e 73 20 66 69 72 73 74 0a 2a 2a 20   means first.** 
1010: 72 65 6d 6f 76 65 20 70 50 61 67 65 20 66 72 6f  remove pPage fro
1020: 6d 20 74 68 65 20 64 69 72 74 79 20 6c 69 73 74  m the dirty list
1030: 2e 20 20 54 68 65 20 30 78 30 32 20 6d 65 61 6e  .  The 0x02 mean
1040: 73 20 61 64 64 20 70 50 61 67 65 20 62 61 63 6b  s add pPage back
1050: 20 74 6f 0a 2a 2a 20 74 68 65 20 64 69 72 74 79   to.** the dirty
1060: 20 6c 69 73 74 2e 20 20 44 6f 69 6e 67 20 62 6f   list.  Doing bo
1070: 74 68 20 6d 6f 76 65 73 20 70 50 61 67 65 20 74  th moves pPage t
1080: 6f 20 74 68 65 20 66 72 6f 6e 74 20 6f 66 20 74  o the front of t
1090: 68 65 20 64 69 72 74 79 20 6c 69 73 74 2e 0a 2a  he dirty list..*
10a0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63  /.static void pc
10b0: 61 63 68 65 4d 61 6e 61 67 65 44 69 72 74 79 4c  acheManageDirtyL
10c0: 69 73 74 28 50 67 48 64 72 20 2a 70 50 61 67 65  ist(PgHdr *pPage
10d0: 2c 20 75 38 20 61 64 64 52 65 6d 6f 76 65 29 7b  , u8 addRemove){
10e0: 0a 20 20 50 43 61 63 68 65 20 2a 70 20 3d 20 70  .  PCache *p = p
10f0: 50 61 67 65 2d 3e 70 43 61 63 68 65 3b 0a 0a 20  Page->pCache;.. 
1100: 20 70 63 61 63 68 65 54 72 61 63 65 28 28 22 25   pcacheTrace(("%
1110: 70 2e 44 49 52 54 59 4c 49 53 54 2e 25 73 20 25  p.DIRTYLIST.%s %
1120: 64 5c 6e 22 2c 20 70 2c 0a 20 20 20 20 20 20 20  d\n", p,.       
1130: 20 20 20 20 20 20 20 20 20 61 64 64 52 65 6d 6f           addRemo
1140: 76 65 3d 3d 31 20 3f 20 22 52 45 4d 4f 56 45 22  ve==1 ? "REMOVE"
1150: 20 3a 20 61 64 64 52 65 6d 6f 76 65 3d 3d 32 20   : addRemove==2 
1160: 3f 20 22 41 44 44 22 20 3a 20 22 46 52 4f 4e 54  ? "ADD" : "FRONT
1170: 22 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ",.             
1180: 20 20 20 70 50 61 67 65 2d 3e 70 67 6e 6f 29 29     pPage->pgno))
1190: 3b 0a 20 20 69 66 28 20 61 64 64 52 65 6d 6f 76  ;.  if( addRemov
11a0: 65 20 26 20 50 43 41 43 48 45 5f 44 49 52 54 59  e & PCACHE_DIRTY
11b0: 4c 49 53 54 5f 52 45 4d 4f 56 45 20 29 7b 0a 20  LIST_REMOVE ){. 
11c0: 20 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65     assert( pPage
11d0: 2d 3e 70 44 69 72 74 79 4e 65 78 74 20 7c 7c 20  ->pDirtyNext || 
11e0: 70 50 61 67 65 3d 3d 70 2d 3e 70 44 69 72 74 79  pPage==p->pDirty
11f0: 54 61 69 6c 20 29 3b 0a 20 20 20 20 61 73 73 65  Tail );.    asse
1200: 72 74 28 20 70 50 61 67 65 2d 3e 70 44 69 72 74  rt( pPage->pDirt
1210: 79 50 72 65 76 20 7c 7c 20 70 50 61 67 65 3d 3d  yPrev || pPage==
1220: 70 2d 3e 70 44 69 72 74 79 20 29 3b 0a 20 20 0a  p->pDirty );.  .
1230: 20 20 20 20 2f 2a 20 55 70 64 61 74 65 20 74 68      /* Update th
1240: 65 20 50 43 61 63 68 65 31 2e 70 53 79 6e 63 65  e PCache1.pSynce
1250: 64 20 76 61 72 69 61 62 6c 65 20 69 66 20 6e 65  d variable if ne
1260: 63 65 73 73 61 72 79 2e 20 2a 2f 0a 20 20 20 20  cessary. */.    
1270: 69 66 28 20 70 2d 3e 70 53 79 6e 63 65 64 3d 3d  if( p->pSynced==
1280: 70 50 61 67 65 20 29 7b 0a 20 20 20 20 20 20 70  pPage ){.      p
1290: 2d 3e 70 53 79 6e 63 65 64 20 3d 20 70 50 61 67  ->pSynced = pPag
12a0: 65 2d 3e 70 44 69 72 74 79 50 72 65 76 3b 0a 20  e->pDirtyPrev;. 
12b0: 20 20 20 7d 0a 20 20 0a 20 20 20 20 69 66 28 20     }.  .    if( 
12c0: 70 50 61 67 65 2d 3e 70 44 69 72 74 79 4e 65 78  pPage->pDirtyNex
12d0: 74 20 29 7b 0a 20 20 20 20 20 20 70 50 61 67 65  t ){.      pPage
12e0: 2d 3e 70 44 69 72 74 79 4e 65 78 74 2d 3e 70 44  ->pDirtyNext->pD
12f0: 69 72 74 79 50 72 65 76 20 3d 20 70 50 61 67 65  irtyPrev = pPage
1300: 2d 3e 70 44 69 72 74 79 50 72 65 76 3b 0a 20 20  ->pDirtyPrev;.  
1310: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 61    }else{.      a
1320: 73 73 65 72 74 28 20 70 50 61 67 65 3d 3d 70 2d  ssert( pPage==p-
1330: 3e 70 44 69 72 74 79 54 61 69 6c 20 29 3b 0a 20  >pDirtyTail );. 
1340: 20 20 20 20 20 70 2d 3e 70 44 69 72 74 79 54 61       p->pDirtyTa
1350: 69 6c 20 3d 20 70 50 61 67 65 2d 3e 70 44 69 72  il = pPage->pDir
1360: 74 79 50 72 65 76 3b 0a 20 20 20 20 7d 0a 20 20  tyPrev;.    }.  
1370: 20 20 69 66 28 20 70 50 61 67 65 2d 3e 70 44 69    if( pPage->pDi
1380: 72 74 79 50 72 65 76 20 29 7b 0a 20 20 20 20 20  rtyPrev ){.     
1390: 20 70 50 61 67 65 2d 3e 70 44 69 72 74 79 50 72   pPage->pDirtyPr
13a0: 65 76 2d 3e 70 44 69 72 74 79 4e 65 78 74 20 3d  ev->pDirtyNext =
13b0: 20 70 50 61 67 65 2d 3e 70 44 69 72 74 79 4e 65   pPage->pDirtyNe
13c0: 78 74 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  xt;.    }else{. 
13d0: 20 20 20 20 20 2f 2a 20 49 66 20 74 68 65 72 65       /* If there
13e0: 20 61 72 65 20 6e 6f 77 20 6e 6f 20 64 69 72 74   are now no dirt
13f0: 79 20 70 61 67 65 73 20 69 6e 20 74 68 65 20 63  y pages in the c
1400: 61 63 68 65 2c 20 73 65 74 20 65 43 72 65 61 74  ache, set eCreat
1410: 65 20 74 6f 20 32 2e 20 0a 20 20 20 20 20 20 2a  e to 2. .      *
1420: 2a 20 54 68 69 73 20 69 73 20 61 6e 20 6f 70 74  * This is an opt
1430: 69 6d 69 7a 61 74 69 6f 6e 20 74 68 61 74 20 61  imization that a
1440: 6c 6c 6f 77 73 20 73 71 6c 69 74 65 33 50 63 61  llows sqlite3Pca
1450: 63 68 65 46 65 74 63 68 28 29 20 74 6f 20 73 6b  cheFetch() to sk
1460: 69 70 0a 20 20 20 20 20 20 2a 2a 20 73 65 61 72  ip.      ** sear
1470: 63 68 69 6e 67 20 66 6f 72 20 61 20 64 69 72 74  ching for a dirt
1480: 79 20 70 61 67 65 20 74 6f 20 65 6a 65 63 74 20  y page to eject 
1490: 66 72 6f 6d 20 74 68 65 20 63 61 63 68 65 20 77  from the cache w
14a0: 68 65 6e 20 69 74 20 6d 69 67 68 74 0a 20 20 20  hen it might.   
14b0: 20 20 20 2a 2a 20 6f 74 68 65 72 77 69 73 65 20     ** otherwise 
14c0: 68 61 76 65 20 74 6f 2e 20 20 2a 2f 0a 20 20 20  have to.  */.   
14d0: 20 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65     assert( pPage
14e0: 3d 3d 70 2d 3e 70 44 69 72 74 79 20 29 3b 0a 20  ==p->pDirty );. 
14f0: 20 20 20 20 20 70 2d 3e 70 44 69 72 74 79 20 3d       p->pDirty =
1500: 20 70 50 61 67 65 2d 3e 70 44 69 72 74 79 4e 65   pPage->pDirtyNe
1510: 78 74 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74  xt;.      assert
1520: 28 20 70 2d 3e 62 50 75 72 67 65 61 62 6c 65 20  ( p->bPurgeable 
1530: 7c 7c 20 70 2d 3e 65 43 72 65 61 74 65 3d 3d 32  || p->eCreate==2
1540: 20 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70 2d   );.      if( p-
1550: 3e 70 44 69 72 74 79 3d 3d 30 20 29 7b 20 20 20  >pDirty==0 ){   
1560: 20 20 20 20 20 20 2f 2a 4f 50 54 49 4d 49 5a 41        /*OPTIMIZA
1570: 54 49 4f 4e 2d 49 46 2d 54 52 55 45 2a 2f 0a 20  TION-IF-TRUE*/. 
1580: 20 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70         assert( p
1590: 2d 3e 62 50 75 72 67 65 61 62 6c 65 3d 3d 30 20  ->bPurgeable==0 
15a0: 7c 7c 20 70 2d 3e 65 43 72 65 61 74 65 3d 3d 31  || p->eCreate==1
15b0: 20 29 3b 0a 20 20 20 20 20 20 20 20 70 2d 3e 65   );.        p->e
15c0: 43 72 65 61 74 65 20 3d 20 32 3b 0a 20 20 20 20  Create = 2;.    
15d0: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 70 50    }.    }.    pP
15e0: 61 67 65 2d 3e 70 44 69 72 74 79 4e 65 78 74 20  age->pDirtyNext 
15f0: 3d 20 30 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e  = 0;.    pPage->
1600: 70 44 69 72 74 79 50 72 65 76 20 3d 20 30 3b 0a  pDirtyPrev = 0;.
1610: 20 20 7d 0a 20 20 69 66 28 20 61 64 64 52 65 6d    }.  if( addRem
1620: 6f 76 65 20 26 20 50 43 41 43 48 45 5f 44 49 52  ove & PCACHE_DIR
1630: 54 59 4c 49 53 54 5f 41 44 44 20 29 7b 0a 20 20  TYLIST_ADD ){.  
1640: 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65 2d    assert( pPage-
1650: 3e 70 44 69 72 74 79 4e 65 78 74 3d 3d 30 20 26  >pDirtyNext==0 &
1660: 26 20 70 50 61 67 65 2d 3e 70 44 69 72 74 79 50  & pPage->pDirtyP
1670: 72 65 76 3d 3d 30 20 26 26 20 70 2d 3e 70 44 69  rev==0 && p->pDi
1680: 72 74 79 21 3d 70 50 61 67 65 20 29 3b 0a 20 20  rty!=pPage );.  
1690: 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 44 69 72  .    pPage->pDir
16a0: 74 79 4e 65 78 74 20 3d 20 70 2d 3e 70 44 69 72  tyNext = p->pDir
16b0: 74 79 3b 0a 20 20 20 20 69 66 28 20 70 50 61 67  ty;.    if( pPag
16c0: 65 2d 3e 70 44 69 72 74 79 4e 65 78 74 20 29 7b  e->pDirtyNext ){
16d0: 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70  .      assert( p
16e0: 50 61 67 65 2d 3e 70 44 69 72 74 79 4e 65 78 74  Page->pDirtyNext
16f0: 2d 3e 70 44 69 72 74 79 50 72 65 76 3d 3d 30 20  ->pDirtyPrev==0 
1700: 29 3b 0a 20 20 20 20 20 20 70 50 61 67 65 2d 3e  );.      pPage->
1710: 70 44 69 72 74 79 4e 65 78 74 2d 3e 70 44 69 72  pDirtyNext->pDir
1720: 74 79 50 72 65 76 20 3d 20 70 50 61 67 65 3b 0a  tyPrev = pPage;.
1730: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
1740: 20 70 2d 3e 70 44 69 72 74 79 54 61 69 6c 20 3d   p->pDirtyTail =
1750: 20 70 50 61 67 65 3b 0a 20 20 20 20 20 20 69 66   pPage;.      if
1760: 28 20 70 2d 3e 62 50 75 72 67 65 61 62 6c 65 20  ( p->bPurgeable 
1770: 29 7b 0a 20 20 20 20 20 20 20 20 61 73 73 65 72  ){.        asser
1780: 74 28 20 70 2d 3e 65 43 72 65 61 74 65 3d 3d 32  t( p->eCreate==2
1790: 20 29 3b 0a 20 20 20 20 20 20 20 20 70 2d 3e 65   );.        p->e
17a0: 43 72 65 61 74 65 20 3d 20 31 3b 0a 20 20 20 20  Create = 1;.    
17b0: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 70 2d    }.    }.    p-
17c0: 3e 70 44 69 72 74 79 20 3d 20 70 50 61 67 65 3b  >pDirty = pPage;
17d0: 0a 0a 20 20 20 20 2f 2a 20 49 66 20 70 53 79 6e  ..    /* If pSyn
17e0: 63 65 64 20 69 73 20 4e 55 4c 4c 20 61 6e 64 20  ced is NULL and 
17f0: 74 68 69 73 20 70 61 67 65 20 68 61 73 20 61 20  this page has a 
1800: 63 6c 65 61 72 20 4e 45 45 44 5f 53 59 4e 43 20  clear NEED_SYNC 
1810: 66 6c 61 67 2c 20 73 65 74 0a 20 20 20 20 2a 2a  flag, set.    **
1820: 20 70 53 79 6e 63 65 64 20 74 6f 20 70 6f 69 6e   pSynced to poin
1830: 74 20 74 6f 20 69 74 2e 20 43 68 65 63 6b 69 6e  t to it. Checkin
1840: 67 20 74 68 65 20 4e 45 45 44 5f 53 59 4e 43 20  g the NEED_SYNC 
1850: 66 6c 61 67 20 69 73 20 61 6e 20 0a 20 20 20 20  flag is an .    
1860: 2a 2a 20 6f 70 74 69 6d 69 7a 61 74 69 6f 6e 2c  ** optimization,
1870: 20 61 73 20 69 66 20 70 53 79 6e 63 65 64 20 70   as if pSynced p
1880: 6f 69 6e 74 73 20 74 6f 20 61 20 70 61 67 65 20  oints to a page 
1890: 77 69 74 68 20 74 68 65 20 4e 45 45 44 5f 53 59  with the NEED_SY
18a0: 4e 43 0a 20 20 20 20 2a 2a 20 66 6c 61 67 20 73  NC.    ** flag s
18b0: 65 74 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  et sqlite3Pcache
18c0: 46 65 74 63 68 53 74 72 65 73 73 28 29 20 73 65  FetchStress() se
18d0: 61 72 63 68 65 73 20 74 68 72 6f 75 67 68 20 61  arches through a
18e0: 6c 6c 20 6e 65 77 65 72 20 0a 20 20 20 20 2a 2a  ll newer .    **
18f0: 20 65 6e 74 72 69 65 73 20 6f 66 20 74 68 65 20   entries of the 
1900: 64 69 72 74 79 2d 6c 69 73 74 20 66 6f 72 20 61  dirty-list for a
1910: 20 70 61 67 65 20 77 69 74 68 20 4e 45 45 44 5f   page with NEED_
1920: 53 59 4e 43 20 63 6c 65 61 72 20 61 6e 79 77 61  SYNC clear anywa
1930: 79 2e 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 21  y.  */.    if( !
1940: 70 2d 3e 70 53 79 6e 63 65 64 20 0a 20 20 20 20  p->pSynced .    
1950: 20 26 26 20 30 3d 3d 28 70 50 61 67 65 2d 3e 66   && 0==(pPage->f
1960: 6c 61 67 73 26 50 47 48 44 52 5f 4e 45 45 44 5f  lags&PGHDR_NEED_
1970: 53 59 4e 43 29 20 20 20 2f 2a 4f 50 54 49 4d 49  SYNC)   /*OPTIMI
1980: 5a 41 54 49 4f 4e 2d 49 46 2d 46 41 4c 53 45 2a  ZATION-IF-FALSE*
1990: 2f 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20 70  /.    ){.      p
19a0: 2d 3e 70 53 79 6e 63 65 64 20 3d 20 70 50 61 67  ->pSynced = pPag
19b0: 65 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 70  e;.    }.  }.  p
19c0: 63 61 63 68 65 44 75 6d 70 28 70 29 3b 0a 7d 0a  cacheDump(p);.}.
19d0: 0a 2f 2a 0a 2a 2a 20 57 72 61 70 70 65 72 20 61  ./*.** Wrapper a
19e0: 72 6f 75 6e 64 20 74 68 65 20 70 6c 75 67 67 61  round the plugga
19f0: 62 6c 65 20 63 61 63 68 65 73 20 78 55 6e 70 69  ble caches xUnpi
1a00: 6e 20 6d 65 74 68 6f 64 2e 20 49 66 20 74 68 65  n method. If the
1a10: 20 63 61 63 68 65 20 69 73 0a 2a 2a 20 62 65 69   cache is.** bei
1a20: 6e 67 20 75 73 65 64 20 66 6f 72 20 61 6e 20 69  ng used for an i
1a30: 6e 2d 6d 65 6d 6f 72 79 20 64 61 74 61 62 61 73  n-memory databas
1a40: 65 2c 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  e, this function
1a50: 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a 2a 2f 0a   is a no-op..*/.
1a60: 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63  static void pcac
1a70: 68 65 55 6e 70 69 6e 28 50 67 48 64 72 20 2a 70  heUnpin(PgHdr *p
1a80: 29 7b 0a 20 20 69 66 28 20 70 2d 3e 70 43 61 63  ){.  if( p->pCac
1a90: 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 29  he->bPurgeable )
1aa0: 7b 0a 20 20 20 20 70 63 61 63 68 65 54 72 61 63  {.    pcacheTrac
1ab0: 65 28 28 22 25 70 2e 55 4e 50 49 4e 20 25 64 5c  e(("%p.UNPIN %d\
1ac0: 6e 22 2c 20 70 2d 3e 70 43 61 63 68 65 2c 20 70  n", p->pCache, p
1ad0: 2d 3e 70 67 6e 6f 29 29 3b 0a 20 20 20 20 73 71  ->pgno));.    sq
1ae0: 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69  lite3GlobalConfi
1af0: 67 2e 70 63 61 63 68 65 32 2e 78 55 6e 70 69 6e  g.pcache2.xUnpin
1b00: 28 70 2d 3e 70 43 61 63 68 65 2d 3e 70 43 61 63  (p->pCache->pCac
1b10: 68 65 2c 20 70 2d 3e 70 50 61 67 65 2c 20 30 29  he, p->pPage, 0)
1b20: 3b 0a 20 20 20 20 70 63 61 63 68 65 44 75 6d 70  ;.    pcacheDump
1b30: 28 70 2d 3e 70 43 61 63 68 65 29 3b 0a 20 20 7d  (p->pCache);.  }
1b40: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70 75 74  .}../*.** Comput
1b50: 65 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  e the number of 
1b60: 70 61 67 65 73 20 6f 66 20 63 61 63 68 65 20 72  pages of cache r
1b70: 65 71 75 65 73 74 65 64 2e 20 20 20 70 2d 3e 73  equested.   p->s
1b80: 7a 43 61 63 68 65 20 69 73 20 74 68 65 0a 2a 2a  zCache is the.**
1b90: 20 63 61 63 68 65 20 73 69 7a 65 20 72 65 71 75   cache size requ
1ba0: 65 73 74 65 64 20 62 79 20 74 68 65 20 22 50 52  ested by the "PR
1bb0: 41 47 4d 41 20 63 61 63 68 65 5f 73 69 7a 65 22  AGMA cache_size"
1bc0: 20 73 74 61 74 65 6d 65 6e 74 2e 0a 2a 2f 0a 73   statement..*/.s
1bd0: 74 61 74 69 63 20 69 6e 74 20 6e 75 6d 62 65 72  tatic int number
1be0: 4f 66 43 61 63 68 65 50 61 67 65 73 28 50 43 61  OfCachePages(PCa
1bf0: 63 68 65 20 2a 70 29 7b 0a 20 20 69 66 28 20 70  che *p){.  if( p
1c00: 2d 3e 73 7a 43 61 63 68 65 3e 3d 30 20 29 7b 0a  ->szCache>=0 ){.
1c10: 20 20 20 20 2f 2a 20 49 4d 50 4c 45 4d 45 4e 54      /* IMPLEMENT
1c20: 41 54 49 4f 4e 2d 4f 46 3a 20 52 2d 34 32 30 35  ATION-OF: R-4205
1c30: 39 2d 34 37 32 31 31 20 49 66 20 74 68 65 20 61  9-47211 If the a
1c40: 72 67 75 6d 65 6e 74 20 4e 20 69 73 20 70 6f 73  rgument N is pos
1c50: 69 74 69 76 65 20 74 68 65 6e 20 74 68 65 0a 20  itive then the. 
1c60: 20 20 20 2a 2a 20 73 75 67 67 65 73 74 65 64 20     ** suggested 
1c70: 63 61 63 68 65 20 73 69 7a 65 20 69 73 20 73 65  cache size is se
1c80: 74 20 74 6f 20 4e 2e 20 2a 2f 0a 20 20 20 20 72  t to N. */.    r
1c90: 65 74 75 72 6e 20 70 2d 3e 73 7a 43 61 63 68 65  eturn p->szCache
1ca0: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 2f  ;.  }else{.    /
1cb0: 2a 20 49 4d 50 4c 45 4d 45 4e 54 41 54 49 4f 4e  * IMPLEMENTATION
1cc0: 2d 4f 46 3a 20 52 2d 36 31 34 33 36 2d 31 33 36  -OF: R-61436-136
1cd0: 33 39 20 49 66 20 74 68 65 20 61 72 67 75 6d 65  39 If the argume
1ce0: 6e 74 20 4e 20 69 73 20 6e 65 67 61 74 69 76 65  nt N is negative
1cf0: 2c 20 74 68 65 6e 0a 20 20 20 20 2a 2a 20 74 68  , then.    ** th
1d00: 65 20 6e 75 6d 62 65 72 20 6f 66 20 63 61 63 68  e number of cach
1d10: 65 20 70 61 67 65 73 20 69 73 20 61 64 6a 75 73  e pages is adjus
1d20: 74 65 64 20 74 6f 20 75 73 65 20 61 70 70 72 6f  ted to use appro
1d30: 78 69 6d 61 74 65 6c 79 20 61 62 73 28 4e 2a 31  ximately abs(N*1
1d40: 30 32 34 29 0a 20 20 20 20 2a 2a 20 62 79 74 65  024).    ** byte
1d50: 73 20 6f 66 20 6d 65 6d 6f 72 79 2e 20 2a 2f 0a  s of memory. */.
1d60: 20 20 20 20 72 65 74 75 72 6e 20 28 69 6e 74 29      return (int)
1d70: 28 28 2d 31 30 32 34 2a 28 69 36 34 29 70 2d 3e  ((-1024*(i64)p->
1d80: 73 7a 43 61 63 68 65 29 2f 28 70 2d 3e 73 7a 50  szCache)/(p->szP
1d90: 61 67 65 2b 70 2d 3e 73 7a 45 78 74 72 61 29 29  age+p->szExtra))
1da0: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a  ;.  }.}../******
1db0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1dc0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1dd0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 47 65  ************* Ge
1de0: 6e 65 72 61 6c 20 49 6e 74 65 72 66 61 63 65 73  neral Interfaces
1df0: 20 2a 2a 2a 2a 2a 2a 0a 2a 2a 0a 2a 2a 20 49 6e   ******.**.** In
1e00: 69 74 69 61 6c 69 7a 65 20 61 6e 64 20 73 68 75  itialize and shu
1e10: 74 64 6f 77 6e 20 74 68 65 20 70 61 67 65 20 63  tdown the page c
1e20: 61 63 68 65 20 73 75 62 73 79 73 74 65 6d 2e 20  ache subsystem. 
1e30: 4e 65 69 74 68 65 72 20 6f 66 20 74 68 65 73 65  Neither of these
1e40: 20 0a 2a 2a 20 66 75 6e 63 74 69 6f 6e 73 20 61   .** functions a
1e50: 72 65 20 74 68 72 65 61 64 73 61 66 65 2e 0a 2a  re threadsafe..*
1e60: 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 50 63 61  /.int sqlite3Pca
1e70: 63 68 65 49 6e 69 74 69 61 6c 69 7a 65 28 76 6f  cheInitialize(vo
1e80: 69 64 29 7b 0a 20 20 69 66 28 20 73 71 6c 69 74  id){.  if( sqlit
1e90: 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70  e3GlobalConfig.p
1ea0: 63 61 63 68 65 32 2e 78 49 6e 69 74 3d 3d 30 20  cache2.xInit==0 
1eb0: 29 7b 0a 20 20 20 20 2f 2a 20 49 4d 50 4c 45 4d  ){.    /* IMPLEM
1ec0: 45 4e 54 41 54 49 4f 4e 2d 4f 46 3a 20 52 2d 32  ENTATION-OF: R-2
1ed0: 36 38 30 31 2d 36 34 31 33 37 20 49 66 20 74 68  6801-64137 If th
1ee0: 65 20 78 49 6e 69 74 28 29 20 6d 65 74 68 6f 64  e xInit() method
1ef0: 20 69 73 20 4e 55 4c 4c 2c 20 74 68 65 6e 20 74   is NULL, then t
1f00: 68 65 0a 20 20 20 20 2a 2a 20 62 75 69 6c 74 2d  he.    ** built-
1f10: 69 6e 20 64 65 66 61 75 6c 74 20 70 61 67 65 20  in default page 
1f20: 63 61 63 68 65 20 69 73 20 75 73 65 64 20 69 6e  cache is used in
1f30: 73 74 65 61 64 20 6f 66 20 74 68 65 20 61 70 70  stead of the app
1f40: 6c 69 63 61 74 69 6f 6e 20 64 65 66 69 6e 65 64  lication defined
1f50: 0a 20 20 20 20 2a 2a 20 70 61 67 65 20 63 61 63  .    ** page cac
1f60: 68 65 2e 20 2a 2f 0a 20 20 20 20 73 71 6c 69 74  he. */.    sqlit
1f70: 65 33 50 43 61 63 68 65 53 65 74 44 65 66 61 75  e3PCacheSetDefau
1f80: 6c 74 28 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75  lt();.  }.  retu
1f90: 72 6e 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c  rn sqlite3Global
1fa0: 43 6f 6e 66 69 67 2e 70 63 61 63 68 65 32 2e 78  Config.pcache2.x
1fb0: 49 6e 69 74 28 73 71 6c 69 74 65 33 47 6c 6f 62  Init(sqlite3Glob
1fc0: 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65 32  alConfig.pcache2
1fd0: 2e 70 41 72 67 29 3b 0a 7d 0a 76 6f 69 64 20 73  .pArg);.}.void s
1fe0: 71 6c 69 74 65 33 50 63 61 63 68 65 53 68 75 74  qlite3PcacheShut
1ff0: 64 6f 77 6e 28 76 6f 69 64 29 7b 0a 20 20 69 66  down(void){.  if
2000: 28 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43  ( sqlite3GlobalC
2010: 6f 6e 66 69 67 2e 70 63 61 63 68 65 32 2e 78 53  onfig.pcache2.xS
2020: 68 75 74 64 6f 77 6e 20 29 7b 0a 20 20 20 20 2f  hutdown ){.    /
2030: 2a 20 49 4d 50 4c 45 4d 45 4e 54 41 54 49 4f 4e  * IMPLEMENTATION
2040: 2d 4f 46 3a 20 52 2d 32 36 30 30 30 2d 35 36 35  -OF: R-26000-565
2050: 38 39 20 54 68 65 20 78 53 68 75 74 64 6f 77 6e  89 The xShutdown
2060: 28 29 20 6d 65 74 68 6f 64 20 6d 61 79 20 62 65  () method may be
2070: 20 4e 55 4c 4c 2e 20 2a 2f 0a 20 20 20 20 73 71   NULL. */.    sq
2080: 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69  lite3GlobalConfi
2090: 67 2e 70 63 61 63 68 65 32 2e 78 53 68 75 74 64  g.pcache2.xShutd
20a0: 6f 77 6e 28 73 71 6c 69 74 65 33 47 6c 6f 62 61  own(sqlite3Globa
20b0: 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65 32 2e  lConfig.pcache2.
20c0: 70 41 72 67 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a  pArg);.  }.}../*
20d0: 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 73  .** Return the s
20e0: 69 7a 65 20 69 6e 20 62 79 74 65 73 20 6f 66 20  ize in bytes of 
20f0: 61 20 50 43 61 63 68 65 20 6f 62 6a 65 63 74 2e  a PCache object.
2100: 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 50  .*/.int sqlite3P
2110: 63 61 63 68 65 53 69 7a 65 28 76 6f 69 64 29 7b  cacheSize(void){
2120: 20 72 65 74 75 72 6e 20 73 69 7a 65 6f 66 28 50   return sizeof(P
2130: 43 61 63 68 65 29 3b 20 7d 0a 0a 2f 2a 0a 2a 2a  Cache); }../*.**
2140: 20 43 72 65 61 74 65 20 61 20 6e 65 77 20 50 43   Create a new PC
2150: 61 63 68 65 20 6f 62 6a 65 63 74 2e 20 53 74 6f  ache object. Sto
2160: 72 61 67 65 20 73 70 61 63 65 20 74 6f 20 68 6f  rage space to ho
2170: 6c 64 20 74 68 65 20 6f 62 6a 65 63 74 0a 2a 2a  ld the object.**
2180: 20 68 61 73 20 61 6c 72 65 61 64 79 20 62 65 65   has already bee
2190: 6e 20 61 6c 6c 6f 63 61 74 65 64 20 61 6e 64 20  n allocated and 
21a0: 69 73 20 70 61 73 73 65 64 20 69 6e 20 61 73 20  is passed in as 
21b0: 74 68 65 20 70 20 70 6f 69 6e 74 65 72 2e 20 0a  the p pointer. .
21c0: 2a 2a 20 54 68 65 20 63 61 6c 6c 65 72 20 64 69  ** The caller di
21d0: 73 63 6f 76 65 72 73 20 68 6f 77 20 6d 75 63 68  scovers how much
21e0: 20 73 70 61 63 65 20 6e 65 65 64 73 20 74 6f 20   space needs to 
21f0: 62 65 20 61 6c 6c 6f 63 61 74 65 64 20 62 79 20  be allocated by 
2200: 0a 2a 2a 20 63 61 6c 6c 69 6e 67 20 73 71 6c 69  .** calling sqli
2210: 74 65 33 50 63 61 63 68 65 53 69 7a 65 28 29 2e  te3PcacheSize().
2220: 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 50  .*/.int sqlite3P
2230: 63 61 63 68 65 4f 70 65 6e 28 0a 20 20 69 6e 74  cacheOpen(.  int
2240: 20 73 7a 50 61 67 65 2c 20 20 20 20 20 20 20 20   szPage,        
2250: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a            /* Siz
2260: 65 20 6f 66 20 65 76 65 72 79 20 70 61 67 65 20  e of every page 
2270: 2a 2f 0a 20 20 69 6e 74 20 73 7a 45 78 74 72 61  */.  int szExtra
2280: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
2290: 20 20 2f 2a 20 45 78 74 72 61 20 73 70 61 63 65    /* Extra space
22a0: 20 61 73 73 6f 63 69 61 74 65 64 20 77 69 74 68   associated with
22b0: 20 65 61 63 68 20 70 61 67 65 20 2a 2f 0a 20 20   each page */.  
22c0: 69 6e 74 20 62 50 75 72 67 65 61 62 6c 65 2c 20  int bPurgeable, 
22d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
22e0: 54 72 75 65 20 69 66 20 70 61 67 65 73 20 61 72  True if pages ar
22f0: 65 20 6f 6e 20 62 61 63 6b 69 6e 67 20 73 74 6f  e on backing sto
2300: 72 65 20 2a 2f 0a 20 20 69 6e 74 20 28 2a 78 53  re */.  int (*xS
2310: 74 72 65 73 73 29 28 76 6f 69 64 2a 2c 50 67 48  tress)(void*,PgH
2320: 64 72 2a 29 2c 2f 2a 20 43 61 6c 6c 20 74 6f 20  dr*),/* Call to 
2330: 74 72 79 20 74 6f 20 6d 61 6b 65 20 70 61 67 65  try to make page
2340: 73 20 63 6c 65 61 6e 20 2a 2f 0a 20 20 76 6f 69  s clean */.  voi
2350: 64 20 2a 70 53 74 72 65 73 73 2c 20 20 20 20 20  d *pStress,     
2360: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41 72 67            /* Arg
2370: 75 6d 65 6e 74 20 74 6f 20 78 53 74 72 65 73 73  ument to xStress
2380: 20 2a 2f 0a 20 20 50 43 61 63 68 65 20 2a 70 20   */.  PCache *p 
2390: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
23a0: 20 20 20 2f 2a 20 50 72 65 61 6c 6c 6f 63 61 74     /* Preallocat
23b0: 65 64 20 73 70 61 63 65 20 66 6f 72 20 74 68 65  ed space for the
23c0: 20 50 43 61 63 68 65 20 2a 2f 0a 29 7b 0a 20 20   PCache */.){.  
23d0: 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20 73 69 7a  memset(p, 0, siz
23e0: 65 6f 66 28 50 43 61 63 68 65 29 29 3b 0a 20 20  eof(PCache));.  
23f0: 70 2d 3e 73 7a 50 61 67 65 20 3d 20 31 3b 0a 20  p->szPage = 1;. 
2400: 20 70 2d 3e 73 7a 45 78 74 72 61 20 3d 20 73 7a   p->szExtra = sz
2410: 45 78 74 72 61 3b 0a 20 20 70 2d 3e 62 50 75 72  Extra;.  p->bPur
2420: 67 65 61 62 6c 65 20 3d 20 62 50 75 72 67 65 61  geable = bPurgea
2430: 62 6c 65 3b 0a 20 20 70 2d 3e 65 43 72 65 61 74  ble;.  p->eCreat
2440: 65 20 3d 20 32 3b 0a 20 20 70 2d 3e 78 53 74 72  e = 2;.  p->xStr
2450: 65 73 73 20 3d 20 78 53 74 72 65 73 73 3b 0a 20  ess = xStress;. 
2460: 20 70 2d 3e 70 53 74 72 65 73 73 20 3d 20 70 53   p->pStress = pS
2470: 74 72 65 73 73 3b 0a 20 20 70 2d 3e 73 7a 43 61  tress;.  p->szCa
2480: 63 68 65 20 3d 20 31 30 30 3b 0a 20 20 70 2d 3e  che = 100;.  p->
2490: 73 7a 53 70 69 6c 6c 20 3d 20 31 3b 0a 20 20 70  szSpill = 1;.  p
24a0: 63 61 63 68 65 54 72 61 63 65 28 28 22 25 70 2e  cacheTrace(("%p.
24b0: 4f 50 45 4e 20 73 7a 50 61 67 65 20 25 64 20 62  OPEN szPage %d b
24c0: 50 75 72 67 65 61 62 6c 65 20 25 64 5c 6e 22 2c  Purgeable %d\n",
24d0: 70 2c 73 7a 50 61 67 65 2c 62 50 75 72 67 65 61  p,szPage,bPurgea
24e0: 62 6c 65 29 29 3b 0a 20 20 72 65 74 75 72 6e 20  ble));.  return 
24f0: 73 71 6c 69 74 65 33 50 63 61 63 68 65 53 65 74  sqlite3PcacheSet
2500: 50 61 67 65 53 69 7a 65 28 70 2c 20 73 7a 50 61  PageSize(p, szPa
2510: 67 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 68  ge);.}../*.** Ch
2520: 61 6e 67 65 20 74 68 65 20 70 61 67 65 20 73 69  ange the page si
2530: 7a 65 20 66 6f 72 20 50 43 61 63 68 65 20 6f 62  ze for PCache ob
2540: 6a 65 63 74 2e 20 54 68 65 20 63 61 6c 6c 65 72  ject. The caller
2550: 20 6d 75 73 74 20 65 6e 73 75 72 65 20 74 68 61   must ensure tha
2560: 74 20 74 68 65 72 65 0a 2a 2a 20 61 72 65 20 6e  t there.** are n
2570: 6f 20 6f 75 74 73 74 61 6e 64 69 6e 67 20 70 61  o outstanding pa
2580: 67 65 20 72 65 66 65 72 65 6e 63 65 73 20 77 68  ge references wh
2590: 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  en this function
25a0: 20 69 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f 0a 69   is called..*/.i
25b0: 6e 74 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  nt sqlite3Pcache
25c0: 53 65 74 50 61 67 65 53 69 7a 65 28 50 43 61 63  SetPageSize(PCac
25d0: 68 65 20 2a 70 43 61 63 68 65 2c 20 69 6e 74 20  he *pCache, int 
25e0: 73 7a 50 61 67 65 29 7b 0a 20 20 61 73 73 65 72  szPage){.  asser
25f0: 74 28 20 70 43 61 63 68 65 2d 3e 6e 52 65 66 53  t( pCache->nRefS
2600: 75 6d 3d 3d 30 20 26 26 20 70 43 61 63 68 65 2d  um==0 && pCache-
2610: 3e 70 44 69 72 74 79 3d 3d 30 20 29 3b 0a 20 20  >pDirty==0 );.  
2620: 69 66 28 20 70 43 61 63 68 65 2d 3e 73 7a 50 61  if( pCache->szPa
2630: 67 65 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  ge ){.    sqlite
2640: 33 5f 70 63 61 63 68 65 20 2a 70 4e 65 77 3b 0a  3_pcache *pNew;.
2650: 20 20 20 20 70 4e 65 77 20 3d 20 73 71 6c 69 74      pNew = sqlit
2660: 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70  e3GlobalConfig.p
2670: 63 61 63 68 65 32 2e 78 43 72 65 61 74 65 28 0a  cache2.xCreate(.
2680: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2690: 73 7a 50 61 67 65 2c 20 70 43 61 63 68 65 2d 3e  szPage, pCache->
26a0: 73 7a 45 78 74 72 61 20 2b 20 52 4f 55 4e 44 38  szExtra + ROUND8
26b0: 28 73 69 7a 65 6f 66 28 50 67 48 64 72 29 29 2c  (sizeof(PgHdr)),
26c0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
26d0: 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61   pCache->bPurgea
26e0: 62 6c 65 0a 20 20 20 20 29 3b 0a 20 20 20 20 69  ble.    );.    i
26f0: 66 28 20 70 4e 65 77 3d 3d 30 20 29 20 72 65 74  f( pNew==0 ) ret
2700: 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
2710: 5f 42 4b 50 54 3b 0a 20 20 20 20 73 71 6c 69 74  _BKPT;.    sqlit
2720: 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70  e3GlobalConfig.p
2730: 63 61 63 68 65 32 2e 78 43 61 63 68 65 73 69 7a  cache2.xCachesiz
2740: 65 28 70 4e 65 77 2c 20 6e 75 6d 62 65 72 4f 66  e(pNew, numberOf
2750: 43 61 63 68 65 50 61 67 65 73 28 70 43 61 63 68  CachePages(pCach
2760: 65 29 29 3b 0a 20 20 20 20 69 66 28 20 70 43 61  e));.    if( pCa
2770: 63 68 65 2d 3e 70 43 61 63 68 65 20 29 7b 0a 20  che->pCache ){. 
2780: 20 20 20 20 20 73 71 6c 69 74 65 33 47 6c 6f 62       sqlite3Glob
2790: 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65 32  alConfig.pcache2
27a0: 2e 78 44 65 73 74 72 6f 79 28 70 43 61 63 68 65  .xDestroy(pCache
27b0: 2d 3e 70 43 61 63 68 65 29 3b 0a 20 20 20 20 7d  ->pCache);.    }
27c0: 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 70 43 61  .    pCache->pCa
27d0: 63 68 65 20 3d 20 70 4e 65 77 3b 0a 20 20 20 20  che = pNew;.    
27e0: 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 20 3d  pCache->szPage =
27f0: 20 73 7a 50 61 67 65 3b 0a 20 20 20 20 70 63 61   szPage;.    pca
2800: 63 68 65 54 72 61 63 65 28 28 22 25 70 2e 50 41  cheTrace(("%p.PA
2810: 47 45 53 49 5a 45 20 25 64 5c 6e 22 2c 70 43 61  GESIZE %d\n",pCa
2820: 63 68 65 2c 73 7a 50 61 67 65 29 29 3b 0a 20 20  che,szPage));.  
2830: 7d 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  }.  return SQLIT
2840: 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  E_OK;.}../*.** T
2850: 72 79 20 74 6f 20 6f 62 74 61 69 6e 20 61 20 70  ry to obtain a p
2860: 61 67 65 20 66 72 6f 6d 20 74 68 65 20 63 61 63  age from the cac
2870: 68 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 72  he..**.** This r
2880: 6f 75 74 69 6e 65 20 72 65 74 75 72 6e 73 20 61  outine returns a
2890: 20 70 6f 69 6e 74 65 72 20 74 6f 20 61 6e 20 73   pointer to an s
28a0: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 5f 70 61  qlite3_pcache_pa
28b0: 67 65 20 6f 62 6a 65 63 74 20 69 66 0a 2a 2a 20  ge object if.** 
28c0: 73 75 63 68 20 61 6e 20 6f 62 6a 65 63 74 20 69  such an object i
28d0: 73 20 61 6c 72 65 61 64 79 20 69 6e 20 63 61 63  s already in cac
28e0: 68 65 2c 20 6f 72 20 69 66 20 61 20 6e 65 77 20  he, or if a new 
28f0: 6f 6e 65 20 69 73 20 63 72 65 61 74 65 64 2e 0a  one is created..
2900: 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20  ** This routine 
2910: 72 65 74 75 72 6e 73 20 61 20 4e 55 4c 4c 20 70  returns a NULL p
2920: 6f 69 6e 74 65 72 20 69 66 20 74 68 65 20 6f 62  ointer if the ob
2930: 6a 65 63 74 20 77 61 73 20 6e 6f 74 20 69 6e 20  ject was not in 
2940: 63 61 63 68 65 0a 2a 2a 20 61 6e 64 20 63 6f 75  cache.** and cou
2950: 6c 64 20 6e 6f 74 20 62 65 20 63 72 65 61 74 65  ld not be create
2960: 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 72 65  d..**.** The cre
2970: 61 74 65 46 6c 61 67 73 20 73 68 6f 75 6c 64 20  ateFlags should 
2980: 62 65 20 30 20 74 6f 20 63 68 65 63 6b 20 66 6f  be 0 to check fo
2990: 72 20 65 78 69 73 74 69 6e 67 20 70 61 67 65 73  r existing pages
29a0: 20 61 6e 64 20 73 68 6f 75 6c 64 0a 2a 2a 20 62   and should.** b
29b0: 65 20 33 20 28 6e 6f 74 20 31 2c 20 62 75 74 20  e 3 (not 1, but 
29c0: 33 29 20 74 6f 20 74 72 79 20 74 6f 20 63 72 65  3) to try to cre
29d0: 61 74 65 20 61 20 6e 65 77 20 70 61 67 65 2e 0a  ate a new page..
29e0: 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20 63 72 65  **.** If the cre
29f0: 61 74 65 46 6c 61 67 20 69 73 20 30 2c 20 74 68  ateFlag is 0, th
2a00: 65 6e 20 4e 55 4c 4c 20 69 73 20 61 6c 77 61 79  en NULL is alway
2a10: 73 20 72 65 74 75 72 6e 65 64 20 69 66 20 74 68  s returned if th
2a20: 65 20 70 61 67 65 0a 2a 2a 20 69 73 20 6e 6f 74  e page.** is not
2a30: 20 61 6c 72 65 61 64 79 20 69 6e 20 74 68 65 20   already in the 
2a40: 63 61 63 68 65 2e 20 20 49 66 20 63 72 65 61 74  cache.  If creat
2a50: 65 46 6c 61 67 20 69 73 20 31 2c 20 74 68 65 6e  eFlag is 1, then
2a60: 20 61 20 6e 65 77 20 70 61 67 65 0a 2a 2a 20 69   a new page.** i
2a70: 73 20 63 72 65 61 74 65 64 20 6f 6e 6c 79 20 69  s created only i
2a80: 66 20 74 68 61 74 20 63 61 6e 20 62 65 20 64 6f  f that can be do
2a90: 6e 65 20 77 69 74 68 6f 75 74 20 73 70 69 6c 6c  ne without spill
2aa0: 69 6e 67 20 64 69 72 74 79 20 70 61 67 65 73 0a  ing dirty pages.
2ab0: 2a 2a 20 61 6e 64 20 77 69 74 68 6f 75 74 20 65  ** and without e
2ac0: 78 63 65 65 64 69 6e 67 20 74 68 65 20 63 61 63  xceeding the cac
2ad0: 68 65 20 73 69 7a 65 20 6c 69 6d 69 74 2e 0a 2a  he size limit..*
2ae0: 2a 0a 2a 2a 20 54 68 65 20 63 61 6c 6c 65 72 20  *.** The caller 
2af0: 6e 65 65 64 73 20 74 6f 20 69 6e 76 6f 6b 65 20  needs to invoke 
2b00: 73 71 6c 69 74 65 33 50 63 61 63 68 65 46 65 74  sqlite3PcacheFet
2b10: 63 68 46 69 6e 69 73 68 28 29 20 74 6f 20 70 72  chFinish() to pr
2b20: 6f 70 65 72 6c 79 0a 2a 2a 20 69 6e 69 74 69 61  operly.** initia
2b30: 6c 69 7a 65 20 74 68 65 20 73 71 6c 69 74 65 33  lize the sqlite3
2b40: 5f 70 63 61 63 68 65 5f 70 61 67 65 20 6f 62 6a  _pcache_page obj
2b50: 65 63 74 20 61 6e 64 20 63 6f 6e 76 65 72 74 20  ect and convert 
2b60: 69 74 20 69 6e 74 6f 20 61 0a 2a 2a 20 50 67 48  it into a.** PgH
2b70: 64 72 20 6f 62 6a 65 63 74 2e 20 20 54 68 65 20  dr object.  The 
2b80: 73 71 6c 69 74 65 33 50 63 61 63 68 65 46 65 74  sqlite3PcacheFet
2b90: 63 68 28 29 20 61 6e 64 20 73 71 6c 69 74 65 33  ch() and sqlite3
2ba0: 50 63 61 63 68 65 46 65 74 63 68 46 69 6e 69 73  PcacheFetchFinis
2bb0: 68 28 29 0a 2a 2a 20 72 6f 75 74 69 6e 65 73 20  h().** routines 
2bc0: 61 72 65 20 73 70 6c 69 74 20 74 68 69 73 20 77  are split this w
2bd0: 61 79 20 66 6f 72 20 70 65 72 66 6f 72 6d 61 6e  ay for performan
2be0: 63 65 20 72 65 61 73 6f 6e 73 2e 20 57 68 65 6e  ce reasons. When
2bf0: 20 73 65 70 61 72 61 74 65 64 0a 2a 2a 20 74 68   separated.** th
2c00: 65 79 20 63 61 6e 20 62 6f 74 68 20 28 75 73 75  ey can both (usu
2c10: 61 6c 6c 79 29 20 6f 70 65 72 61 74 65 20 77 69  ally) operate wi
2c20: 74 68 6f 75 74 20 68 61 76 69 6e 67 20 74 6f 20  thout having to 
2c30: 70 75 73 68 20 76 61 6c 75 65 73 20 74 6f 0a 2a  push values to.*
2c40: 2a 20 74 68 65 20 73 74 61 63 6b 20 6f 6e 20 65  * the stack on e
2c50: 6e 74 72 79 20 61 6e 64 20 70 6f 70 20 74 68 65  ntry and pop the
2c60: 6d 20 62 61 63 6b 20 6f 66 66 20 6f 6e 20 65 78  m back off on ex
2c70: 69 74 2c 20 77 68 69 63 68 20 73 61 76 65 73 20  it, which saves 
2c80: 61 0a 2a 2a 20 6c 6f 74 20 6f 66 20 70 75 73 68  a.** lot of push
2c90: 69 6e 67 20 61 6e 64 20 70 6f 70 70 69 6e 67 2e  ing and popping.
2ca0: 0a 2a 2f 0a 73 71 6c 69 74 65 33 5f 70 63 61 63  .*/.sqlite3_pcac
2cb0: 68 65 5f 70 61 67 65 20 2a 73 71 6c 69 74 65 33  he_page *sqlite3
2cc0: 50 63 61 63 68 65 46 65 74 63 68 28 0a 20 20 50  PcacheFetch(.  P
2cd0: 43 61 63 68 65 20 2a 70 43 61 63 68 65 2c 20 20  Cache *pCache,  
2ce0: 20 20 20 20 20 2f 2a 20 4f 62 74 61 69 6e 20 74       /* Obtain t
2cf0: 68 65 20 70 61 67 65 20 66 72 6f 6d 20 74 68 69  he page from thi
2d00: 73 20 63 61 63 68 65 20 2a 2f 0a 20 20 50 67 6e  s cache */.  Pgn
2d10: 6f 20 70 67 6e 6f 2c 20 20 20 20 20 20 20 20 20  o pgno,         
2d20: 20 20 20 2f 2a 20 50 61 67 65 20 6e 75 6d 62 65     /* Page numbe
2d30: 72 20 74 6f 20 6f 62 74 61 69 6e 20 2a 2f 0a 20  r to obtain */. 
2d40: 20 69 6e 74 20 63 72 65 61 74 65 46 6c 61 67 20   int createFlag 
2d50: 20 20 20 20 20 20 20 2f 2a 20 49 66 20 74 72 75         /* If tru
2d60: 65 2c 20 63 72 65 61 74 65 20 70 61 67 65 20 69  e, create page i
2d70: 66 20 69 74 20 64 6f 65 73 20 6e 6f 74 20 65 78  f it does not ex
2d80: 69 73 74 20 61 6c 72 65 61 64 79 20 2a 2f 0a 29  ist already */.)
2d90: 7b 0a 20 20 69 6e 74 20 65 43 72 65 61 74 65 3b  {.  int eCreate;
2da0: 0a 20 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68  .  sqlite3_pcach
2db0: 65 5f 70 61 67 65 20 2a 70 52 65 73 3b 0a 0a 20  e_page *pRes;.. 
2dc0: 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65 21   assert( pCache!
2dd0: 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  =0 );.  assert( 
2de0: 70 43 61 63 68 65 2d 3e 70 43 61 63 68 65 21 3d  pCache->pCache!=
2df0: 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 63  0 );.  assert( c
2e00: 72 65 61 74 65 46 6c 61 67 3d 3d 33 20 7c 7c 20  reateFlag==3 || 
2e10: 63 72 65 61 74 65 46 6c 61 67 3d 3d 30 20 29 3b  createFlag==0 );
2e20: 0a 20 20 61 73 73 65 72 74 28 20 70 67 6e 6f 3e  .  assert( pgno>
2e30: 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70  0 );.  assert( p
2e40: 43 61 63 68 65 2d 3e 65 43 72 65 61 74 65 3d 3d  Cache->eCreate==
2e50: 28 28 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65  ((pCache->bPurge
2e60: 61 62 6c 65 20 26 26 20 70 43 61 63 68 65 2d 3e  able && pCache->
2e70: 70 44 69 72 74 79 29 20 3f 20 31 20 3a 20 32 29  pDirty) ? 1 : 2)
2e80: 20 29 3b 0a 0a 20 20 2f 2a 20 65 43 72 65 61 74   );..  /* eCreat
2e90: 65 20 64 65 66 69 6e 65 73 20 77 68 61 74 20 74  e defines what t
2ea0: 6f 20 64 6f 20 69 66 20 74 68 65 20 70 61 67 65  o do if the page
2eb0: 20 64 6f 65 73 20 6e 6f 74 20 65 78 69 73 74 2e   does not exist.
2ec0: 0a 20 20 2a 2a 20 20 20 20 30 20 20 20 20 20 44  .  **    0     D
2ed0: 6f 20 6e 6f 74 20 61 6c 6c 6f 63 61 74 65 20 61  o not allocate a
2ee0: 20 6e 65 77 20 70 61 67 65 2e 20 20 28 63 72 65   new page.  (cre
2ef0: 61 74 65 46 6c 61 67 3d 3d 30 29 0a 20 20 2a 2a  ateFlag==0).  **
2f00: 20 20 20 20 31 20 20 20 20 20 41 6c 6c 6f 63 61      1     Alloca
2f10: 74 65 20 61 20 6e 65 77 20 70 61 67 65 20 69 66  te a new page if
2f20: 20 64 6f 69 6e 67 20 73 6f 20 69 73 20 69 6e 65   doing so is ine
2f30: 78 70 65 6e 73 69 76 65 2e 0a 20 20 2a 2a 20 20  xpensive..  **  
2f40: 20 20 20 20 20 20 20 20 28 63 72 65 61 74 65 46          (createF
2f50: 6c 61 67 3d 3d 31 20 41 4e 44 20 62 50 75 72 67  lag==1 AND bPurg
2f60: 65 61 62 6c 65 20 41 4e 44 20 70 44 69 72 74 79  eable AND pDirty
2f70: 29 0a 20 20 2a 2a 20 20 20 20 32 20 20 20 20 20  ).  **    2     
2f80: 41 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 70  Allocate a new p
2f90: 61 67 65 20 65 76 65 6e 20 69 74 20 64 6f 69 6e  age even it doin
2fa0: 67 20 73 6f 20 69 73 20 64 69 66 66 69 63 75 6c  g so is difficul
2fb0: 74 2e 0a 20 20 2a 2a 20 20 20 20 20 20 20 20 20  t..  **         
2fc0: 20 28 63 72 65 61 74 65 46 6c 61 67 3d 3d 31 20   (createFlag==1 
2fd0: 41 4e 44 20 21 28 62 50 75 72 67 65 61 62 6c 65  AND !(bPurgeable
2fe0: 20 41 4e 44 20 70 44 69 72 74 79 29 0a 20 20 2a   AND pDirty).  *
2ff0: 2f 0a 20 20 65 43 72 65 61 74 65 20 3d 20 63 72  /.  eCreate = cr
3000: 65 61 74 65 46 6c 61 67 20 26 20 70 43 61 63 68  eateFlag & pCach
3010: 65 2d 3e 65 43 72 65 61 74 65 3b 0a 20 20 61 73  e->eCreate;.  as
3020: 73 65 72 74 28 20 65 43 72 65 61 74 65 3d 3d 30  sert( eCreate==0
3030: 20 7c 7c 20 65 43 72 65 61 74 65 3d 3d 31 20 7c   || eCreate==1 |
3040: 7c 20 65 43 72 65 61 74 65 3d 3d 32 20 29 3b 0a  | eCreate==2 );.
3050: 20 20 61 73 73 65 72 74 28 20 63 72 65 61 74 65    assert( create
3060: 46 6c 61 67 3d 3d 30 20 7c 7c 20 70 43 61 63 68  Flag==0 || pCach
3070: 65 2d 3e 65 43 72 65 61 74 65 3d 3d 65 43 72 65  e->eCreate==eCre
3080: 61 74 65 20 29 3b 0a 20 20 61 73 73 65 72 74 28  ate );.  assert(
3090: 20 63 72 65 61 74 65 46 6c 61 67 3d 3d 30 20 7c   createFlag==0 |
30a0: 7c 20 65 43 72 65 61 74 65 3d 3d 31 2b 28 21 70  | eCreate==1+(!p
30b0: 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c  Cache->bPurgeabl
30c0: 65 7c 7c 21 70 43 61 63 68 65 2d 3e 70 44 69 72  e||!pCache->pDir
30d0: 74 79 29 20 29 3b 0a 20 20 70 52 65 73 20 3d 20  ty) );.  pRes = 
30e0: 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e  sqlite3GlobalCon
30f0: 66 69 67 2e 70 63 61 63 68 65 32 2e 78 46 65 74  fig.pcache2.xFet
3100: 63 68 28 70 43 61 63 68 65 2d 3e 70 43 61 63 68  ch(pCache->pCach
3110: 65 2c 20 70 67 6e 6f 2c 20 65 43 72 65 61 74 65  e, pgno, eCreate
3120: 29 3b 0a 20 20 70 63 61 63 68 65 54 72 61 63 65  );.  pcacheTrace
3130: 28 28 22 25 70 2e 46 45 54 43 48 20 25 64 25 73  (("%p.FETCH %d%s
3140: 20 28 72 65 73 75 6c 74 3a 20 25 70 29 5c 6e 22   (result: %p)\n"
3150: 2c 70 43 61 63 68 65 2c 70 67 6e 6f 2c 0a 20 20  ,pCache,pgno,.  
3160: 20 20 20 20 20 20 20 20 20 20 20 20 20 63 72 65               cre
3170: 61 74 65 46 6c 61 67 3f 22 20 63 72 65 61 74 65  ateFlag?" create
3180: 22 3a 22 22 2c 70 52 65 73 29 29 3b 0a 20 20 72  ":"",pRes));.  r
3190: 65 74 75 72 6e 20 70 52 65 73 3b 0a 7d 0a 0a 2f  eturn pRes;.}../
31a0: 2a 0a 2a 2a 20 49 66 20 74 68 65 20 73 71 6c 69  *.** If the sqli
31b0: 74 65 33 50 63 61 63 68 65 46 65 74 63 68 28 29  te3PcacheFetch()
31c0: 20 72 6f 75 74 69 6e 65 20 69 73 20 75 6e 61 62   routine is unab
31d0: 6c 65 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 61  le to allocate a
31e0: 20 6e 65 77 0a 2a 2a 20 70 61 67 65 20 62 65 63   new.** page bec
31f0: 61 75 73 65 20 6e 6f 20 63 6c 65 61 6e 20 70 61  ause no clean pa
3200: 67 65 73 20 61 72 65 20 61 76 61 69 6c 61 62 6c  ges are availabl
3210: 65 20 66 6f 72 20 72 65 75 73 65 20 61 6e 64 20  e for reuse and 
3220: 74 68 65 20 63 61 63 68 65 0a 2a 2a 20 73 69 7a  the cache.** siz
3230: 65 20 6c 69 6d 69 74 20 68 61 73 20 62 65 65 6e  e limit has been
3240: 20 72 65 61 63 68 65 64 2c 20 74 68 65 6e 20 74   reached, then t
3250: 68 69 73 20 72 6f 75 74 69 6e 65 20 63 61 6e 20  his routine can 
3260: 62 65 20 69 6e 76 6f 6b 65 64 20 74 6f 20 0a 2a  be invoked to .*
3270: 2a 20 74 72 79 20 68 61 72 64 65 72 20 74 6f 20  * try harder to 
3280: 61 6c 6c 6f 63 61 74 65 20 61 20 70 61 67 65 2e  allocate a page.
3290: 20 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 6d    This routine m
32a0: 69 67 68 74 20 69 6e 76 6f 6b 65 20 74 68 65 20  ight invoke the 
32b0: 73 74 72 65 73 73 0a 2a 2a 20 63 61 6c 6c 62 61  stress.** callba
32c0: 63 6b 20 74 6f 20 73 70 69 6c 6c 20 64 69 72 74  ck to spill dirt
32d0: 79 20 70 61 67 65 73 20 74 6f 20 74 68 65 20 6a  y pages to the j
32e0: 6f 75 72 6e 61 6c 2e 20 20 49 74 20 77 69 6c 6c  ournal.  It will
32f0: 20 74 68 65 6e 20 74 72 79 20 74 6f 0a 2a 2a 20   then try to.** 
3300: 61 6c 6c 6f 63 61 74 65 20 74 68 65 20 6e 65 77  allocate the new
3310: 20 70 61 67 65 20 61 6e 64 20 77 69 6c 6c 20 6f   page and will o
3320: 6e 6c 79 20 66 61 69 6c 20 74 6f 20 61 6c 6c 6f  nly fail to allo
3330: 63 61 74 65 20 61 20 6e 65 77 20 70 61 67 65 20  cate a new page 
3340: 6f 6e 0a 2a 2a 20 61 6e 20 4f 4f 4d 20 65 72 72  on.** an OOM err
3350: 6f 72 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 72  or..**.** This r
3360: 6f 75 74 69 6e 65 20 73 68 6f 75 6c 64 20 62 65  outine should be
3370: 20 69 6e 76 6f 6b 65 64 20 6f 6e 6c 79 20 61 66   invoked only af
3380: 74 65 72 20 73 71 6c 69 74 65 33 50 63 61 63 68  ter sqlite3Pcach
3390: 65 46 65 74 63 68 28 29 20 66 61 69 6c 73 2e 0a  eFetch() fails..
33a0: 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 50 63  */.int sqlite3Pc
33b0: 61 63 68 65 46 65 74 63 68 53 74 72 65 73 73 28  acheFetchStress(
33c0: 0a 20 20 50 43 61 63 68 65 20 2a 70 43 61 63 68  .  PCache *pCach
33d0: 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e,              
33e0: 20 20 20 2f 2a 20 4f 62 74 61 69 6e 20 74 68 65     /* Obtain the
33f0: 20 70 61 67 65 20 66 72 6f 6d 20 74 68 69 73 20   page from this 
3400: 63 61 63 68 65 20 2a 2f 0a 20 20 50 67 6e 6f 20  cache */.  Pgno 
3410: 70 67 6e 6f 2c 20 20 20 20 20 20 20 20 20 20 20  pgno,           
3420: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61             /* Pa
3430: 67 65 20 6e 75 6d 62 65 72 20 74 6f 20 6f 62 74  ge number to obt
3440: 61 69 6e 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  ain */.  sqlite3
3450: 5f 70 63 61 63 68 65 5f 70 61 67 65 20 2a 2a 70  _pcache_page **p
3460: 70 50 61 67 65 20 20 20 20 2f 2a 20 57 72 69 74  pPage    /* Writ
3470: 65 20 72 65 73 75 6c 74 20 68 65 72 65 20 2a 2f  e result here */
3480: 0a 29 7b 0a 20 20 50 67 48 64 72 20 2a 70 50 67  .){.  PgHdr *pPg
3490: 3b 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e  ;.  if( pCache->
34a0: 65 43 72 65 61 74 65 3d 3d 32 20 29 20 72 65 74  eCreate==2 ) ret
34b0: 75 72 6e 20 30 3b 0a 0a 20 20 69 66 28 20 73 71  urn 0;..  if( sq
34c0: 6c 69 74 65 33 50 63 61 63 68 65 50 61 67 65 63  lite3PcachePagec
34d0: 6f 75 6e 74 28 70 43 61 63 68 65 29 3e 70 43 61  ount(pCache)>pCa
34e0: 63 68 65 2d 3e 73 7a 53 70 69 6c 6c 20 29 7b 0a  che->szSpill ){.
34f0: 20 20 20 20 2f 2a 20 46 69 6e 64 20 61 20 64 69      /* Find a di
3500: 72 74 79 20 70 61 67 65 20 74 6f 20 77 72 69 74  rty page to writ
3510: 65 2d 6f 75 74 20 61 6e 64 20 72 65 63 79 63 6c  e-out and recycl
3520: 65 2e 20 46 69 72 73 74 20 74 72 79 20 74 6f 20  e. First try to 
3530: 66 69 6e 64 20 61 20 0a 20 20 20 20 2a 2a 20 70  find a .    ** p
3540: 61 67 65 20 74 68 61 74 20 64 6f 65 73 20 6e 6f  age that does no
3550: 74 20 72 65 71 75 69 72 65 20 61 20 6a 6f 75 72  t require a jour
3560: 6e 61 6c 2d 73 79 6e 63 20 28 6f 6e 65 20 77 69  nal-sync (one wi
3570: 74 68 20 50 47 48 44 52 5f 4e 45 45 44 5f 53 59  th PGHDR_NEED_SY
3580: 4e 43 0a 20 20 20 20 2a 2a 20 63 6c 65 61 72 65  NC.    ** cleare
3590: 64 29 2c 20 62 75 74 20 69 66 20 74 68 61 74 20  d), but if that 
35a0: 69 73 20 6e 6f 74 20 70 6f 73 73 69 62 6c 65 20  is not possible 
35b0: 73 65 74 74 6c 65 20 66 6f 72 20 61 6e 79 20 6f  settle for any o
35c0: 74 68 65 72 20 0a 20 20 20 20 2a 2a 20 75 6e 72  ther .    ** unr
35d0: 65 66 65 72 65 6e 63 65 64 20 64 69 72 74 79 20  eferenced dirty 
35e0: 70 61 67 65 2e 0a 20 20 20 20 2a 2a 0a 20 20 20  page..    **.   
35f0: 20 2a 2a 20 49 66 20 74 68 65 20 4c 52 55 20 70   ** If the LRU p
3600: 61 67 65 20 69 6e 20 74 68 65 20 64 69 72 74 79  age in the dirty
3610: 20 6c 69 73 74 20 74 68 61 74 20 68 61 73 20 61   list that has a
3620: 20 63 6c 65 61 72 20 50 47 48 44 52 5f 4e 45 45   clear PGHDR_NEE
3630: 44 5f 53 59 4e 43 0a 20 20 20 20 2a 2a 20 66 6c  D_SYNC.    ** fl
3640: 61 67 20 69 73 20 63 75 72 72 65 6e 74 6c 79 20  ag is currently 
3650: 72 65 66 65 72 65 6e 63 65 64 2c 20 74 68 65 6e  referenced, then
3660: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6d   the following m
3670: 61 79 20 6c 65 61 76 65 20 70 53 79 6e 63 65 64  ay leave pSynced
3680: 0a 20 20 20 20 2a 2a 20 73 65 74 20 69 6e 63 6f  .    ** set inco
3690: 72 72 65 63 74 6c 79 20 28 70 6f 69 6e 74 69 6e  rrectly (pointin
36a0: 67 20 74 6f 20 6f 74 68 65 72 20 74 68 61 6e 20  g to other than 
36b0: 74 68 65 20 4c 52 55 20 70 61 67 65 20 77 69 74  the LRU page wit
36c0: 68 20 4e 45 45 44 5f 53 59 4e 43 0a 20 20 20 20  h NEED_SYNC.    
36d0: 2a 2a 20 63 6c 65 61 72 65 64 29 2e 20 54 68 69  ** cleared). Thi
36e0: 73 20 69 73 20 4f 6b 2c 20 61 73 20 70 53 79 6e  s is Ok, as pSyn
36f0: 63 65 64 20 69 73 20 6a 75 73 74 20 61 6e 20 6f  ced is just an o
3700: 70 74 69 6d 69 7a 61 74 69 6f 6e 2e 20 20 2a 2f  ptimization.  */
3710: 0a 20 20 20 20 66 6f 72 28 70 50 67 3d 70 43 61  .    for(pPg=pCa
3720: 63 68 65 2d 3e 70 53 79 6e 63 65 64 3b 20 0a 20  che->pSynced; . 
3730: 20 20 20 20 20 20 20 70 50 67 20 26 26 20 28 70         pPg && (p
3740: 50 67 2d 3e 6e 52 65 66 20 7c 7c 20 28 70 50 67  Pg->nRef || (pPg
3750: 2d 3e 66 6c 61 67 73 26 50 47 48 44 52 5f 4e 45  ->flags&PGHDR_NE
3760: 45 44 5f 53 59 4e 43 29 29 3b 20 0a 20 20 20 20  ED_SYNC)); .    
3770: 20 20 20 20 70 50 67 3d 70 50 67 2d 3e 70 44 69      pPg=pPg->pDi
3780: 72 74 79 50 72 65 76 0a 20 20 20 20 29 3b 0a 20  rtyPrev.    );. 
3790: 20 20 20 70 43 61 63 68 65 2d 3e 70 53 79 6e 63     pCache->pSync
37a0: 65 64 20 3d 20 70 50 67 3b 0a 20 20 20 20 69 66  ed = pPg;.    if
37b0: 28 20 21 70 50 67 20 29 7b 0a 20 20 20 20 20 20  ( !pPg ){.      
37c0: 66 6f 72 28 70 50 67 3d 70 43 61 63 68 65 2d 3e  for(pPg=pCache->
37d0: 70 44 69 72 74 79 54 61 69 6c 3b 20 70 50 67 20  pDirtyTail; pPg 
37e0: 26 26 20 70 50 67 2d 3e 6e 52 65 66 3b 20 70 50  && pPg->nRef; pP
37f0: 67 3d 70 50 67 2d 3e 70 44 69 72 74 79 50 72 65  g=pPg->pDirtyPre
3800: 76 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66  v);.    }.    if
3810: 28 20 70 50 67 20 29 7b 0a 20 20 20 20 20 20 69  ( pPg ){.      i
3820: 6e 74 20 72 63 3b 0a 23 69 66 64 65 66 20 53 51  nt rc;.#ifdef SQ
3830: 4c 49 54 45 5f 4c 4f 47 5f 43 41 43 48 45 5f 53  LITE_LOG_CACHE_S
3840: 50 49 4c 4c 0a 20 20 20 20 20 20 73 71 6c 69 74  PILL.      sqlit
3850: 65 33 5f 6c 6f 67 28 53 51 4c 49 54 45 5f 46 55  e3_log(SQLITE_FU
3860: 4c 4c 2c 20 0a 20 20 20 20 20 20 20 20 20 20 20  LL, .           
3870: 20 20 20 20 20 20 20 22 73 70 69 6c 6c 20 70 61         "spill pa
3880: 67 65 20 25 64 20 6d 61 6b 69 6e 67 20 72 6f 6f  ge %d making roo
3890: 6d 20 66 6f 72 20 25 64 20 2d 20 63 61 63 68 65  m for %d - cache
38a0: 20 75 73 65 64 3a 20 25 64 2f 25 64 22 2c 0a 20   used: %d/%d",. 
38b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
38c0: 20 70 50 67 2d 3e 70 67 6e 6f 2c 20 70 67 6e 6f   pPg->pgno, pgno
38d0: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
38e0: 20 20 20 20 73 71 6c 69 74 65 33 47 6c 6f 62 61      sqlite3Globa
38f0: 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65 2e 78  lConfig.pcache.x
3900: 50 61 67 65 63 6f 75 6e 74 28 70 43 61 63 68 65  Pagecount(pCache
3910: 2d 3e 70 43 61 63 68 65 29 2c 0a 20 20 20 20 20  ->pCache),.     
3920: 20 20 20 20 20 20 20 20 20 20 20 6e 75 6d 62 65             numbe
3930: 72 4f 66 43 61 63 68 65 50 61 67 65 73 28 70 43  rOfCachePages(pC
3940: 61 63 68 65 29 29 3b 0a 23 65 6e 64 69 66 0a 20  ache));.#endif. 
3950: 20 20 20 20 20 70 63 61 63 68 65 54 72 61 63 65       pcacheTrace
3960: 28 28 22 25 70 2e 53 50 49 4c 4c 20 25 64 5c 6e  (("%p.SPILL %d\n
3970: 22 2c 70 43 61 63 68 65 2c 70 50 67 2d 3e 70 67  ",pCache,pPg->pg
3980: 6e 6f 29 29 3b 0a 20 20 20 20 20 20 72 63 20 3d  no));.      rc =
3990: 20 70 43 61 63 68 65 2d 3e 78 53 74 72 65 73 73   pCache->xStress
39a0: 28 70 43 61 63 68 65 2d 3e 70 53 74 72 65 73 73  (pCache->pStress
39b0: 2c 20 70 50 67 29 3b 0a 20 20 20 20 20 20 70 63  , pPg);.      pc
39c0: 61 63 68 65 44 75 6d 70 28 70 43 61 63 68 65 29  acheDump(pCache)
39d0: 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 21 3d  ;.      if( rc!=
39e0: 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 72 63 21  SQLITE_OK && rc!
39f0: 3d 53 51 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a  =SQLITE_BUSY ){.
3a00: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 72          return r
3a10: 63 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  c;.      }.    }
3a20: 0a 20 20 7d 0a 20 20 2a 70 70 50 61 67 65 20 3d  .  }.  *ppPage =
3a30: 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f   sqlite3GlobalCo
3a40: 6e 66 69 67 2e 70 63 61 63 68 65 32 2e 78 46 65  nfig.pcache2.xFe
3a50: 74 63 68 28 70 43 61 63 68 65 2d 3e 70 43 61 63  tch(pCache->pCac
3a60: 68 65 2c 20 70 67 6e 6f 2c 20 32 29 3b 0a 20 20  he, pgno, 2);.  
3a70: 72 65 74 75 72 6e 20 2a 70 70 50 61 67 65 3d 3d  return *ppPage==
3a80: 30 20 3f 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  0 ? SQLITE_NOMEM
3a90: 5f 42 4b 50 54 20 3a 20 53 51 4c 49 54 45 5f 4f  _BKPT : SQLITE_O
3aa0: 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  K;.}../*.** This
3ab0: 20 69 73 20 61 20 68 65 6c 70 65 72 20 72 6f 75   is a helper rou
3ac0: 74 69 6e 65 20 66 6f 72 20 73 71 6c 69 74 65 33  tine for sqlite3
3ad0: 50 63 61 63 68 65 46 65 74 63 68 46 69 6e 69 73  PcacheFetchFinis
3ae0: 68 28 29 0a 2a 2a 0a 2a 2a 20 49 6e 20 74 68 65  h().**.** In the
3af0: 20 75 6e 63 6f 6d 6d 6f 6e 20 63 61 73 65 20 77   uncommon case w
3b00: 68 65 72 65 20 74 68 65 20 70 61 67 65 20 62 65  here the page be
3b10: 69 6e 67 20 66 65 74 63 68 65 64 20 68 61 73 20  ing fetched has 
3b20: 6e 6f 74 20 62 65 65 6e 0a 2a 2a 20 69 6e 69 74  not been.** init
3b30: 69 61 6c 69 7a 65 64 2c 20 74 68 69 73 20 72 6f  ialized, this ro
3b40: 75 74 69 6e 65 20 69 73 20 69 6e 76 6f 6b 65 64  utine is invoked
3b50: 20 74 6f 20 64 6f 20 74 68 65 20 69 6e 69 74 69   to do the initi
3b60: 61 6c 69 7a 61 74 69 6f 6e 2e 0a 2a 2a 20 54 68  alization..** Th
3b70: 69 73 20 72 6f 75 74 69 6e 65 20 69 73 20 62 72  is routine is br
3b80: 6f 6b 65 6e 20 6f 75 74 20 69 6e 74 6f 20 61 20  oken out into a 
3b90: 73 65 70 61 72 61 74 65 20 66 75 6e 63 74 69 6f  separate functio
3ba0: 6e 20 73 69 6e 63 65 20 69 74 0a 2a 2a 20 72 65  n since it.** re
3bb0: 71 75 69 72 65 73 20 65 78 74 72 61 20 73 74 61  quires extra sta
3bc0: 63 6b 20 6d 61 6e 69 70 75 6c 61 74 69 6f 6e 20  ck manipulation 
3bd0: 74 68 61 74 20 63 61 6e 20 62 65 20 61 76 6f 69  that can be avoi
3be0: 64 65 64 20 69 6e 20 74 68 65 20 63 6f 6d 6d 6f  ded in the commo
3bf0: 6e 0a 2a 2a 20 63 61 73 65 2e 0a 2a 2f 0a 73 74  n.** case..*/.st
3c00: 61 74 69 63 20 53 51 4c 49 54 45 5f 4e 4f 49 4e  atic SQLITE_NOIN
3c10: 4c 49 4e 45 20 50 67 48 64 72 20 2a 70 63 61 63  LINE PgHdr *pcac
3c20: 68 65 46 65 74 63 68 46 69 6e 69 73 68 57 69 74  heFetchFinishWit
3c30: 68 49 6e 69 74 28 0a 20 20 50 43 61 63 68 65 20  hInit(.  PCache 
3c40: 2a 70 43 61 63 68 65 2c 20 20 20 20 20 20 20 20  *pCache,        
3c50: 20 20 20 20 20 2f 2a 20 4f 62 74 61 69 6e 20 74       /* Obtain t
3c60: 68 65 20 70 61 67 65 20 66 72 6f 6d 20 74 68 69  he page from thi
3c70: 73 20 63 61 63 68 65 20 2a 2f 0a 20 20 50 67 6e  s cache */.  Pgn
3c80: 6f 20 70 67 6e 6f 2c 20 20 20 20 20 20 20 20 20  o pgno,         
3c90: 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65           /* Page
3ca0: 20 6e 75 6d 62 65 72 20 6f 62 74 61 69 6e 65 64   number obtained
3cb0: 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 70 63   */.  sqlite3_pc
3cc0: 61 63 68 65 5f 70 61 67 65 20 2a 70 50 61 67 65  ache_page *pPage
3cd0: 20 20 2f 2a 20 50 61 67 65 20 6f 62 74 61 69 6e    /* Page obtain
3ce0: 65 64 20 62 79 20 70 72 69 6f 72 20 50 63 61 63  ed by prior Pcac
3cf0: 68 65 46 65 74 63 68 28 29 20 63 61 6c 6c 20 2a  heFetch() call *
3d00: 2f 0a 29 7b 0a 20 20 50 67 48 64 72 20 2a 70 50  /.){.  PgHdr *pP
3d10: 67 48 64 72 3b 0a 20 20 61 73 73 65 72 74 28 20  gHdr;.  assert( 
3d20: 70 50 61 67 65 21 3d 30 20 29 3b 0a 20 20 70 50  pPage!=0 );.  pP
3d30: 67 48 64 72 20 3d 20 28 50 67 48 64 72 2a 29 70  gHdr = (PgHdr*)p
3d40: 50 61 67 65 2d 3e 70 45 78 74 72 61 3b 0a 20 20  Page->pExtra;.  
3d50: 61 73 73 65 72 74 28 20 70 50 67 48 64 72 2d 3e  assert( pPgHdr->
3d60: 70 50 61 67 65 3d 3d 30 20 29 3b 0a 20 20 6d 65  pPage==0 );.  me
3d70: 6d 73 65 74 28 70 50 67 48 64 72 2c 20 30 2c 20  mset(pPgHdr, 0, 
3d80: 73 69 7a 65 6f 66 28 50 67 48 64 72 29 29 3b 0a  sizeof(PgHdr));.
3d90: 20 20 70 50 67 48 64 72 2d 3e 70 50 61 67 65 20    pPgHdr->pPage 
3da0: 3d 20 70 50 61 67 65 3b 0a 20 20 70 50 67 48 64  = pPage;.  pPgHd
3db0: 72 2d 3e 70 44 61 74 61 20 3d 20 70 50 61 67 65  r->pData = pPage
3dc0: 2d 3e 70 42 75 66 3b 0a 20 20 70 50 67 48 64 72  ->pBuf;.  pPgHdr
3dd0: 2d 3e 70 45 78 74 72 61 20 3d 20 28 76 6f 69 64  ->pExtra = (void
3de0: 20 2a 29 26 70 50 67 48 64 72 5b 31 5d 3b 0a 20   *)&pPgHdr[1];. 
3df0: 20 6d 65 6d 73 65 74 28 70 50 67 48 64 72 2d 3e   memset(pPgHdr->
3e00: 70 45 78 74 72 61 2c 20 30 2c 20 70 43 61 63 68  pExtra, 0, pCach
3e10: 65 2d 3e 73 7a 45 78 74 72 61 29 3b 0a 20 20 70  e->szExtra);.  p
3e20: 50 67 48 64 72 2d 3e 70 43 61 63 68 65 20 3d 20  PgHdr->pCache = 
3e30: 70 43 61 63 68 65 3b 0a 20 20 70 50 67 48 64 72  pCache;.  pPgHdr
3e40: 2d 3e 70 67 6e 6f 20 3d 20 70 67 6e 6f 3b 0a 20  ->pgno = pgno;. 
3e50: 20 70 50 67 48 64 72 2d 3e 66 6c 61 67 73 20 3d   pPgHdr->flags =
3e60: 20 50 47 48 44 52 5f 43 4c 45 41 4e 3b 0a 20 20   PGHDR_CLEAN;.  
3e70: 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 50 63  return sqlite3Pc
3e80: 61 63 68 65 46 65 74 63 68 46 69 6e 69 73 68 28  acheFetchFinish(
3e90: 70 43 61 63 68 65 2c 70 67 6e 6f 2c 70 50 61 67  pCache,pgno,pPag
3ea0: 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69  e);.}../*.** Thi
3eb0: 73 20 72 6f 75 74 69 6e 65 20 63 6f 6e 76 65 72  s routine conver
3ec0: 74 73 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70  ts the sqlite3_p
3ed0: 63 61 63 68 65 5f 70 61 67 65 20 6f 62 6a 65 63  cache_page objec
3ee0: 74 20 72 65 74 75 72 6e 65 64 20 62 79 0a 2a 2a  t returned by.**
3ef0: 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 46 65   sqlite3PcacheFe
3f00: 74 63 68 28 29 20 69 6e 74 6f 20 61 6e 20 69 6e  tch() into an in
3f10: 69 74 69 61 6c 69 7a 65 64 20 50 67 48 64 72 20  itialized PgHdr 
3f20: 6f 62 6a 65 63 74 2e 20 20 54 68 69 73 20 72 6f  object.  This ro
3f30: 75 74 69 6e 65 0a 2a 2a 20 6d 75 73 74 20 62 65  utine.** must be
3f40: 20 63 61 6c 6c 65 64 20 61 66 74 65 72 20 73 71   called after sq
3f50: 6c 69 74 65 33 50 63 61 63 68 65 46 65 74 63 68  lite3PcacheFetch
3f60: 28 29 20 69 6e 20 6f 72 64 65 72 20 74 6f 20 67  () in order to g
3f70: 65 74 20 61 20 75 73 61 62 6c 65 0a 2a 2a 20 72  et a usable.** r
3f80: 65 73 75 6c 74 2e 0a 2a 2f 0a 50 67 48 64 72 20  esult..*/.PgHdr 
3f90: 2a 73 71 6c 69 74 65 33 50 63 61 63 68 65 46 65  *sqlite3PcacheFe
3fa0: 74 63 68 46 69 6e 69 73 68 28 0a 20 20 50 43 61  tchFinish(.  PCa
3fb0: 63 68 65 20 2a 70 43 61 63 68 65 2c 20 20 20 20  che *pCache,    
3fc0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 62 74 61           /* Obta
3fd0: 69 6e 20 74 68 65 20 70 61 67 65 20 66 72 6f 6d  in the page from
3fe0: 20 74 68 69 73 20 63 61 63 68 65 20 2a 2f 0a 20   this cache */. 
3ff0: 20 50 67 6e 6f 20 70 67 6e 6f 2c 20 20 20 20 20   Pgno pgno,     
4000: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
4010: 50 61 67 65 20 6e 75 6d 62 65 72 20 6f 62 74 61  Page number obta
4020: 69 6e 65 64 20 2a 2f 0a 20 20 73 71 6c 69 74 65  ined */.  sqlite
4030: 33 5f 70 63 61 63 68 65 5f 70 61 67 65 20 2a 70  3_pcache_page *p
4040: 50 61 67 65 20 20 2f 2a 20 50 61 67 65 20 6f 62  Page  /* Page ob
4050: 74 61 69 6e 65 64 20 62 79 20 70 72 69 6f 72 20  tained by prior 
4060: 50 63 61 63 68 65 46 65 74 63 68 28 29 20 63 61  PcacheFetch() ca
4070: 6c 6c 20 2a 2f 0a 29 7b 0a 20 20 50 67 48 64 72  ll */.){.  PgHdr
4080: 20 2a 70 50 67 48 64 72 3b 0a 0a 20 20 61 73 73   *pPgHdr;..  ass
4090: 65 72 74 28 20 70 50 61 67 65 21 3d 30 20 29 3b  ert( pPage!=0 );
40a0: 0a 20 20 70 50 67 48 64 72 20 3d 20 28 50 67 48  .  pPgHdr = (PgH
40b0: 64 72 20 2a 29 70 50 61 67 65 2d 3e 70 45 78 74  dr *)pPage->pExt
40c0: 72 61 3b 0a 0a 20 20 69 66 28 20 21 70 50 67 48  ra;..  if( !pPgH
40d0: 64 72 2d 3e 70 50 61 67 65 20 29 7b 0a 20 20 20  dr->pPage ){.   
40e0: 20 72 65 74 75 72 6e 20 70 63 61 63 68 65 46 65   return pcacheFe
40f0: 74 63 68 46 69 6e 69 73 68 57 69 74 68 49 6e 69  tchFinishWithIni
4100: 74 28 70 43 61 63 68 65 2c 20 70 67 6e 6f 2c 20  t(pCache, pgno, 
4110: 70 50 61 67 65 29 3b 0a 20 20 7d 0a 20 20 70 43  pPage);.  }.  pC
4120: 61 63 68 65 2d 3e 6e 52 65 66 53 75 6d 2b 2b 3b  ache->nRefSum++;
4130: 0a 20 20 70 50 67 48 64 72 2d 3e 6e 52 65 66 2b  .  pPgHdr->nRef+
4140: 2b 3b 0a 20 20 72 65 74 75 72 6e 20 70 50 67 48  +;.  return pPgH
4150: 64 72 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65 63  dr;.}../*.** Dec
4160: 72 65 6d 65 6e 74 20 74 68 65 20 72 65 66 65 72  rement the refer
4170: 65 6e 63 65 20 63 6f 75 6e 74 20 6f 6e 20 61 20  ence count on a 
4180: 70 61 67 65 2e 20 49 66 20 74 68 65 20 70 61 67  page. If the pag
4190: 65 20 69 73 20 63 6c 65 61 6e 20 61 6e 64 20 74  e is clean and t
41a0: 68 65 0a 2a 2a 20 72 65 66 65 72 65 6e 63 65 20  he.** reference 
41b0: 63 6f 75 6e 74 20 64 72 6f 70 73 20 74 6f 20 30  count drops to 0
41c0: 2c 20 74 68 65 6e 20 69 74 20 69 73 20 6d 61 64  , then it is mad
41d0: 65 20 65 6c 69 67 69 62 6c 65 20 66 6f 72 20 72  e eligible for r
41e0: 65 63 79 63 6c 69 6e 67 2e 0a 2a 2f 0a 76 6f 69  ecycling..*/.voi
41f0: 64 20 53 51 4c 49 54 45 5f 4e 4f 49 4e 4c 49 4e  d SQLITE_NOINLIN
4200: 45 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 52  E sqlite3PcacheR
4210: 65 6c 65 61 73 65 28 50 67 48 64 72 20 2a 70 29  elease(PgHdr *p)
4220: 7b 0a 20 20 61 73 73 65 72 74 28 20 70 2d 3e 6e  {.  assert( p->n
4230: 52 65 66 3e 30 20 29 3b 0a 20 20 70 2d 3e 70 43  Ref>0 );.  p->pC
4240: 61 63 68 65 2d 3e 6e 52 65 66 53 75 6d 2d 2d 3b  ache->nRefSum--;
4250: 0a 20 20 69 66 28 20 28 2d 2d 70 2d 3e 6e 52 65  .  if( (--p->nRe
4260: 66 29 3d 3d 30 20 29 7b 0a 20 20 20 20 69 66 28  f)==0 ){.    if(
4270: 20 70 2d 3e 66 6c 61 67 73 26 50 47 48 44 52 5f   p->flags&PGHDR_
4280: 43 4c 45 41 4e 20 29 7b 0a 20 20 20 20 20 20 70  CLEAN ){.      p
4290: 63 61 63 68 65 55 6e 70 69 6e 28 70 29 3b 0a 20  cacheUnpin(p);. 
42a0: 20 20 20 7d 65 6c 73 65 20 69 66 28 20 70 2d 3e     }else if( p->
42b0: 70 44 69 72 74 79 50 72 65 76 21 3d 30 20 29 7b  pDirtyPrev!=0 ){
42c0: 20 2f 2a 4f 50 54 49 4d 49 5a 41 54 49 4f 4e 2d   /*OPTIMIZATION-
42d0: 49 46 2d 46 41 4c 53 45 2a 2f 0a 20 20 20 20 20  IF-FALSE*/.     
42e0: 20 2f 2a 20 4d 6f 76 65 20 74 68 65 20 70 61 67   /* Move the pag
42f0: 65 20 74 6f 20 74 68 65 20 68 65 61 64 20 6f 66  e to the head of
4300: 20 74 68 65 20 64 69 72 74 79 20 6c 69 73 74 2e   the dirty list.
4310: 20 49 66 20 70 2d 3e 70 44 69 72 74 79 50 72 65   If p->pDirtyPre
4320: 76 3d 3d 30 2c 0a 20 20 20 20 20 20 2a 2a 20 74  v==0,.      ** t
4330: 68 65 6e 20 70 61 67 65 20 70 20 69 73 20 61 6c  hen page p is al
4340: 72 65 61 64 79 20 61 74 20 74 68 65 20 68 65 61  ready at the hea
4350: 64 20 6f 66 20 74 68 65 20 64 69 72 74 79 20 6c  d of the dirty l
4360: 69 73 74 20 61 6e 64 20 74 68 65 0a 20 20 20 20  ist and the.    
4370: 20 20 2a 2a 20 66 6f 6c 6c 6f 77 69 6e 67 20 63    ** following c
4380: 61 6c 6c 20 77 6f 75 6c 64 20 62 65 20 61 20 6e  all would be a n
4390: 6f 2d 6f 70 2e 20 48 65 6e 63 65 20 74 68 65 20  o-op. Hence the 
43a0: 4f 50 54 49 4d 49 5a 41 54 49 4f 4e 2d 49 46 2d  OPTIMIZATION-IF-
43b0: 46 41 4c 53 45 0a 20 20 20 20 20 20 2a 2a 20 74  FALSE.      ** t
43c0: 61 67 20 61 62 6f 76 65 2e 20 20 2a 2f 0a 20 20  ag above.  */.  
43d0: 20 20 20 20 70 63 61 63 68 65 4d 61 6e 61 67 65      pcacheManage
43e0: 44 69 72 74 79 4c 69 73 74 28 70 2c 20 50 43 41  DirtyList(p, PCA
43f0: 43 48 45 5f 44 49 52 54 59 4c 49 53 54 5f 46 52  CHE_DIRTYLIST_FR
4400: 4f 4e 54 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  ONT);.    }.  }.
4410: 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 63 72 65 61 73  }../*.** Increas
4420: 65 20 74 68 65 20 72 65 66 65 72 65 6e 63 65 20  e the reference 
4430: 63 6f 75 6e 74 20 6f 66 20 61 20 73 75 70 70 6c  count of a suppl
4440: 69 65 64 20 70 61 67 65 20 62 79 20 31 2e 0a 2a  ied page by 1..*
4450: 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63  /.void sqlite3Pc
4460: 61 63 68 65 52 65 66 28 50 67 48 64 72 20 2a 70  acheRef(PgHdr *p
4470: 29 7b 0a 20 20 61 73 73 65 72 74 28 70 2d 3e 6e  ){.  assert(p->n
4480: 52 65 66 3e 30 29 3b 0a 20 20 70 2d 3e 6e 52 65  Ref>0);.  p->nRe
4490: 66 2b 2b 3b 0a 20 20 70 2d 3e 70 43 61 63 68 65  f++;.  p->pCache
44a0: 2d 3e 6e 52 65 66 53 75 6d 2b 2b 3b 0a 7d 0a 0a  ->nRefSum++;.}..
44b0: 2f 2a 0a 2a 2a 20 44 72 6f 70 20 61 20 70 61 67  /*.** Drop a pag
44c0: 65 20 66 72 6f 6d 20 74 68 65 20 63 61 63 68 65  e from the cache
44d0: 2e 20 54 68 65 72 65 20 6d 75 73 74 20 62 65 20  . There must be 
44e0: 65 78 61 63 74 6c 79 20 6f 6e 65 20 72 65 66 65  exactly one refe
44f0: 72 65 6e 63 65 20 74 6f 20 74 68 65 0a 2a 2a 20  rence to the.** 
4500: 70 61 67 65 2e 20 54 68 69 73 20 66 75 6e 63 74  page. This funct
4510: 69 6f 6e 20 64 65 6c 65 74 65 73 20 74 68 61 74  ion deletes that
4520: 20 72 65 66 65 72 65 6e 63 65 2c 20 73 6f 20 61   reference, so a
4530: 66 74 65 72 20 69 74 20 72 65 74 75 72 6e 73 20  fter it returns 
4540: 74 68 65 0a 2a 2a 20 70 61 67 65 20 70 6f 69 6e  the.** page poin
4550: 74 65 64 20 74 6f 20 62 79 20 70 20 69 73 20 69  ted to by p is i
4560: 6e 76 61 6c 69 64 2e 0a 2a 2f 0a 76 6f 69 64 20  nvalid..*/.void 
4570: 73 71 6c 69 74 65 33 50 63 61 63 68 65 44 72 6f  sqlite3PcacheDro
4580: 70 28 50 67 48 64 72 20 2a 70 29 7b 0a 20 20 61  p(PgHdr *p){.  a
4590: 73 73 65 72 74 28 20 70 2d 3e 6e 52 65 66 3d 3d  ssert( p->nRef==
45a0: 31 20 29 3b 0a 20 20 69 66 28 20 70 2d 3e 66 6c  1 );.  if( p->fl
45b0: 61 67 73 26 50 47 48 44 52 5f 44 49 52 54 59 20  ags&PGHDR_DIRTY 
45c0: 29 7b 0a 20 20 20 20 70 63 61 63 68 65 4d 61 6e  ){.    pcacheMan
45d0: 61 67 65 44 69 72 74 79 4c 69 73 74 28 70 2c 20  ageDirtyList(p, 
45e0: 50 43 41 43 48 45 5f 44 49 52 54 59 4c 49 53 54  PCACHE_DIRTYLIST
45f0: 5f 52 45 4d 4f 56 45 29 3b 0a 20 20 7d 0a 20 20  _REMOVE);.  }.  
4600: 70 2d 3e 70 43 61 63 68 65 2d 3e 6e 52 65 66 53  p->pCache->nRefS
4610: 75 6d 2d 2d 3b 0a 20 20 73 71 6c 69 74 65 33 47  um--;.  sqlite3G
4620: 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63  lobalConfig.pcac
4630: 68 65 32 2e 78 55 6e 70 69 6e 28 70 2d 3e 70 43  he2.xUnpin(p->pC
4640: 61 63 68 65 2d 3e 70 43 61 63 68 65 2c 20 70 2d  ache->pCache, p-
4650: 3e 70 50 61 67 65 2c 20 31 29 3b 0a 7d 0a 0a 2f  >pPage, 1);.}../
4660: 2a 0a 2a 2a 20 4d 61 6b 65 20 73 75 72 65 20 74  *.** Make sure t
4670: 68 65 20 70 61 67 65 20 69 73 20 6d 61 72 6b 65  he page is marke
4680: 64 20 61 73 20 64 69 72 74 79 2e 20 49 66 20 69  d as dirty. If i
4690: 74 20 69 73 6e 27 74 20 64 69 72 74 79 20 61 6c  t isn't dirty al
46a0: 72 65 61 64 79 2c 0a 2a 2a 20 6d 61 6b 65 20 69  ready,.** make i
46b0: 74 20 73 6f 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71  t so..*/.void sq
46c0: 6c 69 74 65 33 50 63 61 63 68 65 4d 61 6b 65 44  lite3PcacheMakeD
46d0: 69 72 74 79 28 50 67 48 64 72 20 2a 70 29 7b 0a  irty(PgHdr *p){.
46e0: 20 20 61 73 73 65 72 74 28 20 70 2d 3e 6e 52 65    assert( p->nRe
46f0: 66 3e 30 20 29 3b 0a 20 20 69 66 28 20 70 2d 3e  f>0 );.  if( p->
4700: 66 6c 61 67 73 20 26 20 28 50 47 48 44 52 5f 43  flags & (PGHDR_C
4710: 4c 45 41 4e 7c 50 47 48 44 52 5f 44 4f 4e 54 5f  LEAN|PGHDR_DONT_
4720: 57 52 49 54 45 29 20 29 7b 20 20 20 20 2f 2a 4f  WRITE) ){    /*O
4730: 50 54 49 4d 49 5a 41 54 49 4f 4e 2d 49 46 2d 46  PTIMIZATION-IF-F
4740: 41 4c 53 45 2a 2f 0a 20 20 20 20 70 2d 3e 66 6c  ALSE*/.    p->fl
4750: 61 67 73 20 26 3d 20 7e 50 47 48 44 52 5f 44 4f  ags &= ~PGHDR_DO
4760: 4e 54 5f 57 52 49 54 45 3b 0a 20 20 20 20 69 66  NT_WRITE;.    if
4770: 28 20 70 2d 3e 66 6c 61 67 73 20 26 20 50 47 48  ( p->flags & PGH
4780: 44 52 5f 43 4c 45 41 4e 20 29 7b 0a 20 20 20 20  DR_CLEAN ){.    
4790: 20 20 70 2d 3e 66 6c 61 67 73 20 5e 3d 20 28 50    p->flags ^= (P
47a0: 47 48 44 52 5f 44 49 52 54 59 7c 50 47 48 44 52  GHDR_DIRTY|PGHDR
47b0: 5f 43 4c 45 41 4e 29 3b 0a 20 20 20 20 20 20 70  _CLEAN);.      p
47c0: 63 61 63 68 65 54 72 61 63 65 28 28 22 25 70 2e  cacheTrace(("%p.
47d0: 44 49 52 54 59 20 25 64 5c 6e 22 2c 70 2d 3e 70  DIRTY %d\n",p->p
47e0: 43 61 63 68 65 2c 70 2d 3e 70 67 6e 6f 29 29 3b  Cache,p->pgno));
47f0: 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 28  .      assert( (
4800: 70 2d 3e 66 6c 61 67 73 20 26 20 28 50 47 48 44  p->flags & (PGHD
4810: 52 5f 44 49 52 54 59 7c 50 47 48 44 52 5f 43 4c  R_DIRTY|PGHDR_CL
4820: 45 41 4e 29 29 3d 3d 50 47 48 44 52 5f 44 49 52  EAN))==PGHDR_DIR
4830: 54 59 20 29 3b 0a 20 20 20 20 20 20 70 63 61 63  TY );.      pcac
4840: 68 65 4d 61 6e 61 67 65 44 69 72 74 79 4c 69 73  heManageDirtyLis
4850: 74 28 70 2c 20 50 43 41 43 48 45 5f 44 49 52 54  t(p, PCACHE_DIRT
4860: 59 4c 49 53 54 5f 41 44 44 29 3b 0a 20 20 20 20  YLIST_ADD);.    
4870: 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d  }.  }.}../*.** M
4880: 61 6b 65 20 73 75 72 65 20 74 68 65 20 70 61 67  ake sure the pag
4890: 65 20 69 73 20 6d 61 72 6b 65 64 20 61 73 20 63  e is marked as c
48a0: 6c 65 61 6e 2e 20 49 66 20 69 74 20 69 73 6e 27  lean. If it isn'
48b0: 74 20 63 6c 65 61 6e 20 61 6c 72 65 61 64 79 2c  t clean already,
48c0: 0a 2a 2a 20 6d 61 6b 65 20 69 74 20 73 6f 2e 0a  .** make it so..
48d0: 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50  */.void sqlite3P
48e0: 63 61 63 68 65 4d 61 6b 65 43 6c 65 61 6e 28 50  cacheMakeClean(P
48f0: 67 48 64 72 20 2a 70 29 7b 0a 20 20 69 66 28 20  gHdr *p){.  if( 
4900: 41 4c 57 41 59 53 28 28 70 2d 3e 66 6c 61 67 73  ALWAYS((p->flags
4910: 20 26 20 50 47 48 44 52 5f 44 49 52 54 59 29 21   & PGHDR_DIRTY)!
4920: 3d 30 29 20 29 7b 0a 20 20 20 20 61 73 73 65 72  =0) ){.    asser
4930: 74 28 20 28 70 2d 3e 66 6c 61 67 73 20 26 20 50  t( (p->flags & P
4940: 47 48 44 52 5f 43 4c 45 41 4e 29 3d 3d 30 20 29  GHDR_CLEAN)==0 )
4950: 3b 0a 20 20 20 20 70 63 61 63 68 65 4d 61 6e 61  ;.    pcacheMana
4960: 67 65 44 69 72 74 79 4c 69 73 74 28 70 2c 20 50  geDirtyList(p, P
4970: 43 41 43 48 45 5f 44 49 52 54 59 4c 49 53 54 5f  CACHE_DIRTYLIST_
4980: 52 45 4d 4f 56 45 29 3b 0a 20 20 20 20 70 2d 3e  REMOVE);.    p->
4990: 66 6c 61 67 73 20 26 3d 20 7e 28 50 47 48 44 52  flags &= ~(PGHDR
49a0: 5f 44 49 52 54 59 7c 50 47 48 44 52 5f 4e 45 45  _DIRTY|PGHDR_NEE
49b0: 44 5f 53 59 4e 43 7c 50 47 48 44 52 5f 57 52 49  D_SYNC|PGHDR_WRI
49c0: 54 45 41 42 4c 45 29 3b 0a 20 20 20 20 70 2d 3e  TEABLE);.    p->
49d0: 66 6c 61 67 73 20 7c 3d 20 50 47 48 44 52 5f 43  flags |= PGHDR_C
49e0: 4c 45 41 4e 3b 0a 20 20 20 20 70 63 61 63 68 65  LEAN;.    pcache
49f0: 54 72 61 63 65 28 28 22 25 70 2e 43 4c 45 41 4e  Trace(("%p.CLEAN
4a00: 20 25 64 5c 6e 22 2c 70 2d 3e 70 43 61 63 68 65   %d\n",p->pCache
4a10: 2c 70 2d 3e 70 67 6e 6f 29 29 3b 0a 20 20 20 20  ,p->pgno));.    
4a20: 69 66 28 20 70 2d 3e 6e 52 65 66 3d 3d 30 20 29  if( p->nRef==0 )
4a30: 7b 0a 20 20 20 20 20 20 70 63 61 63 68 65 55 6e  {.      pcacheUn
4a40: 70 69 6e 28 70 29 3b 0a 20 20 20 20 7d 0a 20 20  pin(p);.    }.  
4a50: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6b 65 20  }.}../*.** Make 
4a60: 65 76 65 72 79 20 70 61 67 65 20 69 6e 20 74 68  every page in th
4a70: 65 20 63 61 63 68 65 20 63 6c 65 61 6e 2e 0a 2a  e cache clean..*
4a80: 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63  /.void sqlite3Pc
4a90: 61 63 68 65 43 6c 65 61 6e 41 6c 6c 28 50 43 61  acheCleanAll(PCa
4aa0: 63 68 65 20 2a 70 43 61 63 68 65 29 7b 0a 20 20  che *pCache){.  
4ab0: 50 67 48 64 72 20 2a 70 3b 0a 20 20 70 63 61 63  PgHdr *p;.  pcac
4ac0: 68 65 54 72 61 63 65 28 28 22 25 70 2e 43 4c 45  heTrace(("%p.CLE
4ad0: 41 4e 2d 41 4c 4c 5c 6e 22 2c 70 43 61 63 68 65  AN-ALL\n",pCache
4ae0: 29 29 3b 0a 20 20 77 68 69 6c 65 28 20 28 70 20  ));.  while( (p 
4af0: 3d 20 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79  = pCache->pDirty
4b00: 29 21 3d 30 20 29 7b 0a 20 20 20 20 73 71 6c 69  )!=0 ){.    sqli
4b10: 74 65 33 50 63 61 63 68 65 4d 61 6b 65 43 6c 65  te3PcacheMakeCle
4b20: 61 6e 28 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a  an(p);.  }.}../*
4b30: 0a 2a 2a 20 43 6c 65 61 72 20 74 68 65 20 50 47  .** Clear the PG
4b40: 48 44 52 5f 4e 45 45 44 5f 53 59 4e 43 20 61 6e  HDR_NEED_SYNC an
4b50: 64 20 50 47 48 44 52 5f 57 52 49 54 45 41 42 4c  d PGHDR_WRITEABL
4b60: 45 20 66 6c 61 67 20 66 72 6f 6d 20 61 6c 6c 20  E flag from all 
4b70: 64 69 72 74 79 20 70 61 67 65 73 2e 0a 2a 2f 0a  dirty pages..*/.
4b80: 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63 61 63  void sqlite3Pcac
4b90: 68 65 43 6c 65 61 72 57 72 69 74 61 62 6c 65 28  heClearWritable(
4ba0: 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b  PCache *pCache){
4bb0: 0a 20 20 50 67 48 64 72 20 2a 70 3b 0a 20 20 70  .  PgHdr *p;.  p
4bc0: 63 61 63 68 65 54 72 61 63 65 28 28 22 25 70 2e  cacheTrace(("%p.
4bd0: 43 4c 45 41 52 2d 57 52 49 54 45 41 42 4c 45 5c  CLEAR-WRITEABLE\
4be0: 6e 22 2c 70 43 61 63 68 65 29 29 3b 0a 20 20 66  n",pCache));.  f
4bf0: 6f 72 28 70 3d 70 43 61 63 68 65 2d 3e 70 44 69  or(p=pCache->pDi
4c00: 72 74 79 3b 20 70 3b 20 70 3d 70 2d 3e 70 44 69  rty; p; p=p->pDi
4c10: 72 74 79 4e 65 78 74 29 7b 0a 20 20 20 20 70 2d  rtyNext){.    p-
4c20: 3e 66 6c 61 67 73 20 26 3d 20 7e 28 50 47 48 44  >flags &= ~(PGHD
4c30: 52 5f 4e 45 45 44 5f 53 59 4e 43 7c 50 47 48 44  R_NEED_SYNC|PGHD
4c40: 52 5f 57 52 49 54 45 41 42 4c 45 29 3b 0a 20 20  R_WRITEABLE);.  
4c50: 7d 0a 20 20 70 43 61 63 68 65 2d 3e 70 53 79 6e  }.  pCache->pSyn
4c60: 63 65 64 20 3d 20 70 43 61 63 68 65 2d 3e 70 44  ced = pCache->pD
4c70: 69 72 74 79 54 61 69 6c 3b 0a 7d 0a 0a 2f 2a 0a  irtyTail;.}../*.
4c80: 2a 2a 20 43 6c 65 61 72 20 74 68 65 20 50 47 48  ** Clear the PGH
4c90: 44 52 5f 4e 45 45 44 5f 53 59 4e 43 20 66 6c 61  DR_NEED_SYNC fla
4ca0: 67 20 66 72 6f 6d 20 61 6c 6c 20 64 69 72 74 79  g from all dirty
4cb0: 20 70 61 67 65 73 2e 0a 2a 2f 0a 76 6f 69 64 20   pages..*/.void 
4cc0: 73 71 6c 69 74 65 33 50 63 61 63 68 65 43 6c 65  sqlite3PcacheCle
4cd0: 61 72 53 79 6e 63 46 6c 61 67 73 28 50 43 61 63  arSyncFlags(PCac
4ce0: 68 65 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 50  he *pCache){.  P
4cf0: 67 48 64 72 20 2a 70 3b 0a 20 20 66 6f 72 28 70  gHdr *p;.  for(p
4d00: 3d 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 3b  =pCache->pDirty;
4d10: 20 70 3b 20 70 3d 70 2d 3e 70 44 69 72 74 79 4e   p; p=p->pDirtyN
4d20: 65 78 74 29 7b 0a 20 20 20 20 70 2d 3e 66 6c 61  ext){.    p->fla
4d30: 67 73 20 26 3d 20 7e 50 47 48 44 52 5f 4e 45 45  gs &= ~PGHDR_NEE
4d40: 44 5f 53 59 4e 43 3b 0a 20 20 7d 0a 20 20 70 43  D_SYNC;.  }.  pC
4d50: 61 63 68 65 2d 3e 70 53 79 6e 63 65 64 20 3d 20  ache->pSynced = 
4d60: 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 54 61  pCache->pDirtyTa
4d70: 69 6c 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 68 61  il;.}../*.** Cha
4d80: 6e 67 65 20 74 68 65 20 70 61 67 65 20 6e 75 6d  nge the page num
4d90: 62 65 72 20 6f 66 20 70 61 67 65 20 70 20 74 6f  ber of page p to
4da0: 20 6e 65 77 50 67 6e 6f 2e 20 0a 2a 2f 0a 76 6f   newPgno. .*/.vo
4db0: 69 64 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  id sqlite3Pcache
4dc0: 4d 6f 76 65 28 50 67 48 64 72 20 2a 70 2c 20 50  Move(PgHdr *p, P
4dd0: 67 6e 6f 20 6e 65 77 50 67 6e 6f 29 7b 0a 20 20  gno newPgno){.  
4de0: 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 20 3d  PCache *pCache =
4df0: 20 70 2d 3e 70 43 61 63 68 65 3b 0a 20 20 61 73   p->pCache;.  as
4e00: 73 65 72 74 28 20 70 2d 3e 6e 52 65 66 3e 30 20  sert( p->nRef>0 
4e10: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 6e 65 77  );.  assert( new
4e20: 50 67 6e 6f 3e 30 20 29 3b 0a 20 20 70 63 61 63  Pgno>0 );.  pcac
4e30: 68 65 54 72 61 63 65 28 28 22 25 70 2e 4d 4f 56  heTrace(("%p.MOV
4e40: 45 20 25 64 20 2d 3e 20 25 64 5c 6e 22 2c 70 43  E %d -> %d\n",pC
4e50: 61 63 68 65 2c 70 2d 3e 70 67 6e 6f 2c 6e 65 77  ache,p->pgno,new
4e60: 50 67 6e 6f 29 29 3b 0a 20 20 73 71 6c 69 74 65  Pgno));.  sqlite
4e70: 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63  3GlobalConfig.pc
4e80: 61 63 68 65 32 2e 78 52 65 6b 65 79 28 70 43 61  ache2.xRekey(pCa
4e90: 63 68 65 2d 3e 70 43 61 63 68 65 2c 20 70 2d 3e  che->pCache, p->
4ea0: 70 50 61 67 65 2c 20 70 2d 3e 70 67 6e 6f 2c 6e  pPage, p->pgno,n
4eb0: 65 77 50 67 6e 6f 29 3b 0a 20 20 70 2d 3e 70 67  ewPgno);.  p->pg
4ec0: 6e 6f 20 3d 20 6e 65 77 50 67 6e 6f 3b 0a 20 20  no = newPgno;.  
4ed0: 69 66 28 20 28 70 2d 3e 66 6c 61 67 73 26 50 47  if( (p->flags&PG
4ee0: 48 44 52 5f 44 49 52 54 59 29 20 26 26 20 28 70  HDR_DIRTY) && (p
4ef0: 2d 3e 66 6c 61 67 73 26 50 47 48 44 52 5f 4e 45  ->flags&PGHDR_NE
4f00: 45 44 5f 53 59 4e 43 29 20 29 7b 0a 20 20 20 20  ED_SYNC) ){.    
4f10: 70 63 61 63 68 65 4d 61 6e 61 67 65 44 69 72 74  pcacheManageDirt
4f20: 79 4c 69 73 74 28 70 2c 20 50 43 41 43 48 45 5f  yList(p, PCACHE_
4f30: 44 49 52 54 59 4c 49 53 54 5f 46 52 4f 4e 54 29  DIRTYLIST_FRONT)
4f40: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44  ;.  }.}../*.** D
4f50: 72 6f 70 20 65 76 65 72 79 20 63 61 63 68 65 20  rop every cache 
4f60: 65 6e 74 72 79 20 77 68 6f 73 65 20 70 61 67 65  entry whose page
4f70: 20 6e 75 6d 62 65 72 20 69 73 20 67 72 65 61 74   number is great
4f80: 65 72 20 74 68 61 6e 20 22 70 67 6e 6f 22 2e 20  er than "pgno". 
4f90: 54 68 65 0a 2a 2a 20 63 61 6c 6c 65 72 20 6d 75  The.** caller mu
4fa0: 73 74 20 65 6e 73 75 72 65 20 74 68 61 74 20 74  st ensure that t
4fb0: 68 65 72 65 20 61 72 65 20 6e 6f 20 6f 75 74 73  here are no outs
4fc0: 74 61 6e 64 69 6e 67 20 72 65 66 65 72 65 6e 63  tanding referenc
4fd0: 65 73 20 74 6f 20 61 6e 79 20 70 61 67 65 73 0a  es to any pages.
4fe0: 2a 2a 20 6f 74 68 65 72 20 74 68 61 6e 20 70 61  ** other than pa
4ff0: 67 65 20 31 20 77 69 74 68 20 61 20 70 61 67 65  ge 1 with a page
5000: 20 6e 75 6d 62 65 72 20 67 72 65 61 74 65 72 20   number greater 
5010: 74 68 61 6e 20 70 67 6e 6f 2e 0a 2a 2a 0a 2a 2a  than pgno..**.**
5020: 20 49 66 20 74 68 65 72 65 20 69 73 20 61 20 72   If there is a r
5030: 65 66 65 72 65 6e 63 65 20 74 6f 20 70 61 67 65  eference to page
5040: 20 31 20 61 6e 64 20 74 68 65 20 70 67 6e 6f 20   1 and the pgno 
5050: 70 61 72 61 6d 65 74 65 72 20 70 61 73 73 65 64  parameter passed
5060: 20 74 6f 20 74 68 69 73 0a 2a 2a 20 66 75 6e 63   to this.** func
5070: 74 69 6f 6e 20 69 73 20 30 2c 20 74 68 65 6e 20  tion is 0, then 
5080: 74 68 65 20 64 61 74 61 20 61 72 65 61 20 61 73  the data area as
5090: 73 6f 63 69 61 74 65 64 20 77 69 74 68 20 70 61  sociated with pa
50a0: 67 65 20 31 20 69 73 20 7a 65 72 6f 65 64 2c 20  ge 1 is zeroed, 
50b0: 62 75 74 0a 2a 2a 20 74 68 65 20 70 61 67 65 20  but.** the page 
50c0: 6f 62 6a 65 63 74 20 69 73 20 6e 6f 74 20 64 72  object is not dr
50d0: 6f 70 70 65 64 2e 0a 2a 2f 0a 76 6f 69 64 20 73  opped..*/.void s
50e0: 71 6c 69 74 65 33 50 63 61 63 68 65 54 72 75 6e  qlite3PcacheTrun
50f0: 63 61 74 65 28 50 43 61 63 68 65 20 2a 70 43 61  cate(PCache *pCa
5100: 63 68 65 2c 20 50 67 6e 6f 20 70 67 6e 6f 29 7b  che, Pgno pgno){
5110: 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 70  .  if( pCache->p
5120: 43 61 63 68 65 20 29 7b 0a 20 20 20 20 50 67 48  Cache ){.    PgH
5130: 64 72 20 2a 70 3b 0a 20 20 20 20 50 67 48 64 72  dr *p;.    PgHdr
5140: 20 2a 70 4e 65 78 74 3b 0a 20 20 20 20 70 63 61   *pNext;.    pca
5150: 63 68 65 54 72 61 63 65 28 28 22 25 70 2e 54 52  cheTrace(("%p.TR
5160: 55 4e 43 41 54 45 20 25 64 5c 6e 22 2c 70 43 61  UNCATE %d\n",pCa
5170: 63 68 65 2c 70 67 6e 6f 29 29 3b 0a 20 20 20 20  che,pgno));.    
5180: 66 6f 72 28 70 3d 70 43 61 63 68 65 2d 3e 70 44  for(p=pCache->pD
5190: 69 72 74 79 3b 20 70 3b 20 70 3d 70 4e 65 78 74  irty; p; p=pNext
51a0: 29 7b 0a 20 20 20 20 20 20 70 4e 65 78 74 20 3d  ){.      pNext =
51b0: 20 70 2d 3e 70 44 69 72 74 79 4e 65 78 74 3b 0a   p->pDirtyNext;.
51c0: 20 20 20 20 20 20 2f 2a 20 54 68 69 73 20 72 6f        /* This ro
51d0: 75 74 69 6e 65 20 6e 65 76 65 72 20 67 65 74 73  utine never gets
51e0: 20 63 61 6c 6c 20 77 69 74 68 20 61 20 70 6f 73   call with a pos
51f0: 69 74 69 76 65 20 70 67 6e 6f 20 65 78 63 65 70  itive pgno excep
5200: 74 20 72 69 67 68 74 0a 20 20 20 20 20 20 2a 2a  t right.      **
5210: 20 61 66 74 65 72 20 73 71 6c 69 74 65 33 50 63   after sqlite3Pc
5220: 61 63 68 65 43 6c 65 61 6e 41 6c 6c 28 29 2e 20  acheCleanAll(). 
5230: 20 53 6f 20 69 66 20 74 68 65 72 65 20 61 72 65   So if there are
5240: 20 64 69 72 74 79 20 70 61 67 65 73 2c 0a 20 20   dirty pages,.  
5250: 20 20 20 20 2a 2a 20 69 74 20 6d 75 73 74 20 62      ** it must b
5260: 65 20 74 68 61 74 20 70 67 6e 6f 3d 3d 30 2e 0a  e that pgno==0..
5270: 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 20 61        */.      a
5280: 73 73 65 72 74 28 20 70 2d 3e 70 67 6e 6f 3e 30  ssert( p->pgno>0
5290: 20 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70 2d   );.      if( p-
52a0: 3e 70 67 6e 6f 3e 70 67 6e 6f 20 29 7b 0a 20 20  >pgno>pgno ){.  
52b0: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70 2d        assert( p-
52c0: 3e 66 6c 61 67 73 26 50 47 48 44 52 5f 44 49 52  >flags&PGHDR_DIR
52d0: 54 59 20 29 3b 0a 20 20 20 20 20 20 20 20 73 71  TY );.        sq
52e0: 6c 69 74 65 33 50 63 61 63 68 65 4d 61 6b 65 43  lite3PcacheMakeC
52f0: 6c 65 61 6e 28 70 29 3b 0a 20 20 20 20 20 20 7d  lean(p);.      }
5300: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70  .    }.    if( p
5310: 67 6e 6f 3d 3d 30 20 26 26 20 70 43 61 63 68 65  gno==0 && pCache
5320: 2d 3e 6e 52 65 66 53 75 6d 20 29 7b 0a 20 20 20  ->nRefSum ){.   
5330: 20 20 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68     sqlite3_pcach
5340: 65 5f 70 61 67 65 20 2a 70 50 61 67 65 31 3b 0a  e_page *pPage1;.
5350: 20 20 20 20 20 20 70 50 61 67 65 31 20 3d 20 73        pPage1 = s
5360: 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66  qlite3GlobalConf
5370: 69 67 2e 70 63 61 63 68 65 32 2e 78 46 65 74 63  ig.pcache2.xFetc
5380: 68 28 70 43 61 63 68 65 2d 3e 70 43 61 63 68 65  h(pCache->pCache
5390: 2c 31 2c 30 29 3b 0a 20 20 20 20 20 20 69 66 28  ,1,0);.      if(
53a0: 20 41 4c 57 41 59 53 28 70 50 61 67 65 31 29 20   ALWAYS(pPage1) 
53b0: 29 7b 20 20 2f 2a 20 50 61 67 65 20 31 20 69 73  ){  /* Page 1 is
53c0: 20 61 6c 77 61 79 73 20 61 76 61 69 6c 61 62 6c   always availabl
53d0: 65 20 69 6e 20 63 61 63 68 65 2c 20 62 65 63 61  e in cache, beca
53e0: 75 73 65 0a 20 20 20 20 20 20 20 20 20 20 20 20  use.            
53f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5400: 20 2a 2a 20 70 43 61 63 68 65 2d 3e 6e 52 65 66   ** pCache->nRef
5410: 53 75 6d 3e 30 20 2a 2f 0a 20 20 20 20 20 20 20  Sum>0 */.       
5420: 20 6d 65 6d 73 65 74 28 70 50 61 67 65 31 2d 3e   memset(pPage1->
5430: 70 42 75 66 2c 20 30 2c 20 70 43 61 63 68 65 2d  pBuf, 0, pCache-
5440: 3e 73 7a 50 61 67 65 29 3b 0a 20 20 20 20 20 20  >szPage);.      
5450: 20 20 70 67 6e 6f 20 3d 20 31 3b 0a 20 20 20 20    pgno = 1;.    
5460: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 73 71    }.    }.    sq
5470: 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69  lite3GlobalConfi
5480: 67 2e 70 63 61 63 68 65 32 2e 78 54 72 75 6e 63  g.pcache2.xTrunc
5490: 61 74 65 28 70 43 61 63 68 65 2d 3e 70 43 61 63  ate(pCache->pCac
54a0: 68 65 2c 20 70 67 6e 6f 2b 31 29 3b 0a 20 20 7d  he, pgno+1);.  }
54b0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20  .}../*.** Close 
54c0: 61 20 63 61 63 68 65 2e 0a 2a 2f 0a 76 6f 69 64  a cache..*/.void
54d0: 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 43 6c   sqlite3PcacheCl
54e0: 6f 73 65 28 50 43 61 63 68 65 20 2a 70 43 61 63  ose(PCache *pCac
54f0: 68 65 29 7b 0a 20 20 61 73 73 65 72 74 28 20 70  he){.  assert( p
5500: 43 61 63 68 65 2d 3e 70 43 61 63 68 65 21 3d 30  Cache->pCache!=0
5510: 20 29 3b 0a 20 20 70 63 61 63 68 65 54 72 61 63   );.  pcacheTrac
5520: 65 28 28 22 25 70 2e 43 4c 4f 53 45 5c 6e 22 2c  e(("%p.CLOSE\n",
5530: 70 43 61 63 68 65 29 29 3b 0a 20 20 73 71 6c 69  pCache));.  sqli
5540: 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e  te3GlobalConfig.
5550: 70 63 61 63 68 65 32 2e 78 44 65 73 74 72 6f 79  pcache2.xDestroy
5560: 28 70 43 61 63 68 65 2d 3e 70 43 61 63 68 65 29  (pCache->pCache)
5570: 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 44 69 73 63  ;.}../* .** Disc
5580: 61 72 64 20 74 68 65 20 63 6f 6e 74 65 6e 74 73  ard the contents
5590: 20 6f 66 20 74 68 65 20 63 61 63 68 65 2e 0a 2a   of the cache..*
55a0: 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63  /.void sqlite3Pc
55b0: 61 63 68 65 43 6c 65 61 72 28 50 43 61 63 68 65  acheClear(PCache
55c0: 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 73 71 6c   *pCache){.  sql
55d0: 69 74 65 33 50 63 61 63 68 65 54 72 75 6e 63 61  ite3PcacheTrunca
55e0: 74 65 28 70 43 61 63 68 65 2c 20 30 29 3b 0a 7d  te(pCache, 0);.}
55f0: 0a 0a 2f 2a 0a 2a 2a 20 4d 65 72 67 65 20 74 77  ../*.** Merge tw
5600: 6f 20 6c 69 73 74 73 20 6f 66 20 70 61 67 65 73  o lists of pages
5610: 20 63 6f 6e 6e 65 63 74 65 64 20 62 79 20 70 44   connected by pD
5620: 69 72 74 79 20 61 6e 64 20 69 6e 20 70 67 6e 6f  irty and in pgno
5630: 20 6f 72 64 65 72 2e 0a 2a 2a 20 44 6f 20 6e 6f   order..** Do no
5640: 74 20 62 6f 74 68 20 66 69 78 69 6e 67 20 74 68  t both fixing th
5650: 65 20 70 44 69 72 74 79 50 72 65 76 20 70 6f 69  e pDirtyPrev poi
5660: 6e 74 65 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  nters..*/.static
5670: 20 50 67 48 64 72 20 2a 70 63 61 63 68 65 4d 65   PgHdr *pcacheMe
5680: 72 67 65 44 69 72 74 79 4c 69 73 74 28 50 67 48  rgeDirtyList(PgH
5690: 64 72 20 2a 70 41 2c 20 50 67 48 64 72 20 2a 70  dr *pA, PgHdr *p
56a0: 42 29 7b 0a 20 20 50 67 48 64 72 20 72 65 73 75  B){.  PgHdr resu
56b0: 6c 74 2c 20 2a 70 54 61 69 6c 3b 0a 20 20 70 54  lt, *pTail;.  pT
56c0: 61 69 6c 20 3d 20 26 72 65 73 75 6c 74 3b 0a 20  ail = &result;. 
56d0: 20 77 68 69 6c 65 28 20 70 41 20 26 26 20 70 42   while( pA && pB
56e0: 20 29 7b 0a 20 20 20 20 69 66 28 20 70 41 2d 3e   ){.    if( pA->
56f0: 70 67 6e 6f 3c 70 42 2d 3e 70 67 6e 6f 20 29 7b  pgno<pB->pgno ){
5700: 0a 20 20 20 20 20 20 70 54 61 69 6c 2d 3e 70 44  .      pTail->pD
5710: 69 72 74 79 20 3d 20 70 41 3b 0a 20 20 20 20 20  irty = pA;.     
5720: 20 70 54 61 69 6c 20 3d 20 70 41 3b 0a 20 20 20   pTail = pA;.   
5730: 20 20 20 70 41 20 3d 20 70 41 2d 3e 70 44 69 72     pA = pA->pDir
5740: 74 79 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  ty;.    }else{. 
5750: 20 20 20 20 20 70 54 61 69 6c 2d 3e 70 44 69 72       pTail->pDir
5760: 74 79 20 3d 20 70 42 3b 0a 20 20 20 20 20 20 70  ty = pB;.      p
5770: 54 61 69 6c 20 3d 20 70 42 3b 0a 20 20 20 20 20  Tail = pB;.     
5780: 20 70 42 20 3d 20 70 42 2d 3e 70 44 69 72 74 79   pB = pB->pDirty
5790: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66  ;.    }.  }.  if
57a0: 28 20 70 41 20 29 7b 0a 20 20 20 20 70 54 61 69  ( pA ){.    pTai
57b0: 6c 2d 3e 70 44 69 72 74 79 20 3d 20 70 41 3b 0a  l->pDirty = pA;.
57c0: 20 20 7d 65 6c 73 65 20 69 66 28 20 70 42 20 29    }else if( pB )
57d0: 7b 0a 20 20 20 20 70 54 61 69 6c 2d 3e 70 44 69  {.    pTail->pDi
57e0: 72 74 79 20 3d 20 70 42 3b 0a 20 20 7d 65 6c 73  rty = pB;.  }els
57f0: 65 7b 0a 20 20 20 20 70 54 61 69 6c 2d 3e 70 44  e{.    pTail->pD
5800: 69 72 74 79 20 3d 20 30 3b 0a 20 20 7d 0a 20 20  irty = 0;.  }.  
5810: 72 65 74 75 72 6e 20 72 65 73 75 6c 74 2e 70 44  return result.pD
5820: 69 72 74 79 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53  irty;.}../*.** S
5830: 6f 72 74 20 74 68 65 20 6c 69 73 74 20 6f 66 20  ort the list of 
5840: 70 61 67 65 73 20 69 6e 20 61 63 63 65 6e 64 69  pages in accendi
5850: 6e 67 20 6f 72 64 65 72 20 62 79 20 70 67 6e 6f  ng order by pgno
5860: 2e 20 20 50 61 67 65 73 20 61 72 65 0a 2a 2a 20  .  Pages are.** 
5870: 63 6f 6e 6e 65 63 74 65 64 20 62 79 20 70 44 69  connected by pDi
5880: 72 74 79 20 70 6f 69 6e 74 65 72 73 2e 20 20 54  rty pointers.  T
5890: 68 65 20 70 44 69 72 74 79 50 72 65 76 20 70 6f  he pDirtyPrev po
58a0: 69 6e 74 65 72 73 20 61 72 65 0a 2a 2a 20 63 6f  inters are.** co
58b0: 72 72 75 70 74 65 64 20 62 79 20 74 68 69 73 20  rrupted by this 
58c0: 73 6f 72 74 2e 0a 2a 2a 0a 2a 2a 20 53 69 6e 63  sort..**.** Sinc
58d0: 65 20 74 68 65 72 65 20 63 61 6e 6e 6f 74 20 62  e there cannot b
58e0: 65 20 6d 6f 72 65 20 74 68 61 6e 20 32 5e 33 31  e more than 2^31
58f0: 20 64 69 73 74 69 6e 63 74 20 70 61 67 65 73 20   distinct pages 
5900: 69 6e 20 61 20 64 61 74 61 62 61 73 65 2c 0a 2a  in a database,.*
5910: 2a 20 74 68 65 72 65 20 63 61 6e 6e 6f 74 20 62  * there cannot b
5920: 65 20 6d 6f 72 65 20 74 68 61 6e 20 33 31 20 62  e more than 31 b
5930: 75 63 6b 65 74 73 20 72 65 71 75 69 72 65 64 20  uckets required 
5940: 62 79 20 74 68 65 20 6d 65 72 67 65 20 73 6f 72  by the merge sor
5950: 74 65 72 2e 0a 2a 2a 20 4f 6e 65 20 65 78 74 72  ter..** One extr
5960: 61 20 62 75 63 6b 65 74 20 69 73 20 61 64 64 65  a bucket is adde
5970: 64 20 74 6f 20 63 61 74 63 68 20 6f 76 65 72 66  d to catch overf
5980: 6c 6f 77 20 69 6e 20 63 61 73 65 20 73 6f 6d 65  low in case some
5990: 74 68 69 6e 67 0a 2a 2a 20 65 76 65 72 20 63 68  thing.** ever ch
59a0: 61 6e 67 65 73 20 74 6f 20 6d 61 6b 65 20 74 68  anges to make th
59b0: 65 20 70 72 65 76 69 6f 75 73 20 73 65 6e 74 65  e previous sente
59c0: 6e 63 65 20 69 6e 63 6f 72 72 65 63 74 2e 0a 2a  nce incorrect..*
59d0: 2f 0a 23 64 65 66 69 6e 65 20 4e 5f 53 4f 52 54  /.#define N_SORT
59e0: 5f 42 55 43 4b 45 54 20 20 33 32 0a 73 74 61 74  _BUCKET  32.stat
59f0: 69 63 20 50 67 48 64 72 20 2a 70 63 61 63 68 65  ic PgHdr *pcache
5a00: 53 6f 72 74 44 69 72 74 79 4c 69 73 74 28 50 67  SortDirtyList(Pg
5a10: 48 64 72 20 2a 70 49 6e 29 7b 0a 20 20 50 67 48  Hdr *pIn){.  PgH
5a20: 64 72 20 2a 61 5b 4e 5f 53 4f 52 54 5f 42 55 43  dr *a[N_SORT_BUC
5a30: 4b 45 54 5d 2c 20 2a 70 3b 0a 20 20 69 6e 74 20  KET], *p;.  int 
5a40: 69 3b 0a 20 20 6d 65 6d 73 65 74 28 61 2c 20 30  i;.  memset(a, 0
5a50: 2c 20 73 69 7a 65 6f 66 28 61 29 29 3b 0a 20 20  , sizeof(a));.  
5a60: 77 68 69 6c 65 28 20 70 49 6e 20 29 7b 0a 20 20  while( pIn ){.  
5a70: 20 20 70 20 3d 20 70 49 6e 3b 0a 20 20 20 20 70    p = pIn;.    p
5a80: 49 6e 20 3d 20 70 2d 3e 70 44 69 72 74 79 3b 0a  In = p->pDirty;.
5a90: 20 20 20 20 70 2d 3e 70 44 69 72 74 79 20 3d 20      p->pDirty = 
5aa0: 30 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20  0;.    for(i=0; 
5ab0: 41 4c 57 41 59 53 28 69 3c 4e 5f 53 4f 52 54 5f  ALWAYS(i<N_SORT_
5ac0: 42 55 43 4b 45 54 2d 31 29 3b 20 69 2b 2b 29 7b  BUCKET-1); i++){
5ad0: 0a 20 20 20 20 20 20 69 66 28 20 61 5b 69 5d 3d  .      if( a[i]=
5ae0: 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 61 5b  =0 ){.        a[
5af0: 69 5d 20 3d 20 70 3b 0a 20 20 20 20 20 20 20 20  i] = p;.        
5b00: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 65 6c  break;.      }el
5b10: 73 65 7b 0a 20 20 20 20 20 20 20 20 70 20 3d 20  se{.        p = 
5b20: 70 63 61 63 68 65 4d 65 72 67 65 44 69 72 74 79  pcacheMergeDirty
5b30: 4c 69 73 74 28 61 5b 69 5d 2c 20 70 29 3b 0a 20  List(a[i], p);. 
5b40: 20 20 20 20 20 20 20 61 5b 69 5d 20 3d 20 30 3b         a[i] = 0;
5b50: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
5b60: 20 20 20 69 66 28 20 4e 45 56 45 52 28 69 3d 3d     if( NEVER(i==
5b70: 4e 5f 53 4f 52 54 5f 42 55 43 4b 45 54 2d 31 29  N_SORT_BUCKET-1)
5b80: 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 54 6f 20   ){.      /* To 
5b90: 67 65 74 20 68 65 72 65 2c 20 74 68 65 72 65 20  get here, there 
5ba0: 6e 65 65 64 20 74 6f 20 62 65 20 32 5e 28 4e 5f  need to be 2^(N_
5bb0: 53 4f 52 54 5f 42 55 43 4b 45 54 29 20 65 6c 65  SORT_BUCKET) ele
5bc0: 6d 65 6e 74 73 20 69 6e 0a 20 20 20 20 20 20 2a  ments in.      *
5bd0: 2a 20 74 68 65 20 69 6e 70 75 74 20 6c 69 73 74  * the input list
5be0: 2e 20 20 42 75 74 20 74 68 61 74 20 69 73 20 69  .  But that is i
5bf0: 6d 70 6f 73 73 69 62 6c 65 2e 0a 20 20 20 20 20  mpossible..     
5c00: 20 2a 2f 0a 20 20 20 20 20 20 61 5b 69 5d 20 3d   */.      a[i] =
5c10: 20 70 63 61 63 68 65 4d 65 72 67 65 44 69 72 74   pcacheMergeDirt
5c20: 79 4c 69 73 74 28 61 5b 69 5d 2c 20 70 29 3b 0a  yList(a[i], p);.
5c30: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 70 20 3d 20      }.  }.  p = 
5c40: 61 5b 30 5d 3b 0a 20 20 66 6f 72 28 69 3d 31 3b  a[0];.  for(i=1;
5c50: 20 69 3c 4e 5f 53 4f 52 54 5f 42 55 43 4b 45 54   i<N_SORT_BUCKET
5c60: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 70 20 3d 20  ; i++){.    p = 
5c70: 70 63 61 63 68 65 4d 65 72 67 65 44 69 72 74 79  pcacheMergeDirty
5c80: 4c 69 73 74 28 70 2c 20 61 5b 69 5d 29 3b 0a 20  List(p, a[i]);. 
5c90: 20 7d 0a 20 20 72 65 74 75 72 6e 20 70 3b 0a 7d   }.  return p;.}
5ca0: 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61  ../*.** Return a
5cb0: 20 6c 69 73 74 20 6f 66 20 61 6c 6c 20 64 69 72   list of all dir
5cc0: 74 79 20 70 61 67 65 73 20 69 6e 20 74 68 65 20  ty pages in the 
5cd0: 63 61 63 68 65 2c 20 73 6f 72 74 65 64 20 62 79  cache, sorted by
5ce0: 20 70 61 67 65 20 6e 75 6d 62 65 72 2e 0a 2a 2f   page number..*/
5cf0: 0a 50 67 48 64 72 20 2a 73 71 6c 69 74 65 33 50  .PgHdr *sqlite3P
5d00: 63 61 63 68 65 44 69 72 74 79 4c 69 73 74 28 50  cacheDirtyList(P
5d10: 43 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b 0a  Cache *pCache){.
5d20: 20 20 50 67 48 64 72 20 2a 70 3b 0a 20 20 66 6f    PgHdr *p;.  fo
5d30: 72 28 70 3d 70 43 61 63 68 65 2d 3e 70 44 69 72  r(p=pCache->pDir
5d40: 74 79 3b 20 70 3b 20 70 3d 70 2d 3e 70 44 69 72  ty; p; p=p->pDir
5d50: 74 79 4e 65 78 74 29 7b 0a 20 20 20 20 70 2d 3e  tyNext){.    p->
5d60: 70 44 69 72 74 79 20 3d 20 70 2d 3e 70 44 69 72  pDirty = p->pDir
5d70: 74 79 4e 65 78 74 3b 0a 20 20 7d 0a 20 20 72 65  tyNext;.  }.  re
5d80: 74 75 72 6e 20 70 63 61 63 68 65 53 6f 72 74 44  turn pcacheSortD
5d90: 69 72 74 79 4c 69 73 74 28 70 43 61 63 68 65 2d  irtyList(pCache-
5da0: 3e 70 44 69 72 74 79 29 3b 0a 7d 0a 0a 2f 2a 20  >pDirty);.}../* 
5db0: 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 74  .** Return the t
5dc0: 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 72  otal number of r
5dd0: 65 66 65 72 65 6e 63 65 73 20 74 6f 20 61 6c 6c  eferences to all
5de0: 20 70 61 67 65 73 20 68 65 6c 64 20 62 79 20 74   pages held by t
5df0: 68 65 20 63 61 63 68 65 2e 0a 2a 2a 0a 2a 2a 20  he cache..**.** 
5e00: 54 68 69 73 20 69 73 20 6e 6f 74 20 74 68 65 20  This is not the 
5e10: 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20  total number of 
5e20: 70 61 67 65 73 20 72 65 66 65 72 65 6e 63 65 64  pages referenced
5e30: 2c 20 62 75 74 20 74 68 65 20 73 75 6d 20 6f 66  , but the sum of
5e40: 20 74 68 65 0a 2a 2a 20 72 65 66 65 72 65 6e 63   the.** referenc
5e50: 65 20 63 6f 75 6e 74 20 66 6f 72 20 61 6c 6c 20  e count for all 
5e60: 70 61 67 65 73 2e 0a 2a 2f 0a 69 6e 74 20 73 71  pages..*/.int sq
5e70: 6c 69 74 65 33 50 63 61 63 68 65 52 65 66 43 6f  lite3PcacheRefCo
5e80: 75 6e 74 28 50 43 61 63 68 65 20 2a 70 43 61 63  unt(PCache *pCac
5e90: 68 65 29 7b 0a 20 20 72 65 74 75 72 6e 20 70 43  he){.  return pC
5ea0: 61 63 68 65 2d 3e 6e 52 65 66 53 75 6d 3b 0a 7d  ache->nRefSum;.}
5eb0: 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74  ../*.** Return t
5ec0: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 72 65 66  he number of ref
5ed0: 65 72 65 6e 63 65 73 20 74 6f 20 74 68 65 20 70  erences to the p
5ee0: 61 67 65 20 73 75 70 70 6c 69 65 64 20 61 73 20  age supplied as 
5ef0: 61 6e 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2f 0a  an argument..*/.
5f00: 69 6e 74 20 73 71 6c 69 74 65 33 50 63 61 63 68  int sqlite3Pcach
5f10: 65 50 61 67 65 52 65 66 63 6f 75 6e 74 28 50 67  ePageRefcount(Pg
5f20: 48 64 72 20 2a 70 29 7b 0a 20 20 72 65 74 75 72  Hdr *p){.  retur
5f30: 6e 20 70 2d 3e 6e 52 65 66 3b 0a 7d 0a 0a 2f 2a  n p->nRef;.}../*
5f40: 20 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20   .** Return the 
5f50: 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20  total number of 
5f60: 70 61 67 65 73 20 69 6e 20 74 68 65 20 63 61 63  pages in the cac
5f70: 68 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  he..*/.int sqlit
5f80: 65 33 50 63 61 63 68 65 50 61 67 65 63 6f 75 6e  e3PcachePagecoun
5f90: 74 28 50 43 61 63 68 65 20 2a 70 43 61 63 68 65  t(PCache *pCache
5fa0: 29 7b 0a 20 20 61 73 73 65 72 74 28 20 70 43 61  ){.  assert( pCa
5fb0: 63 68 65 2d 3e 70 43 61 63 68 65 21 3d 30 20 29  che->pCache!=0 )
5fc0: 3b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74  ;.  return sqlit
5fd0: 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70  e3GlobalConfig.p
5fe0: 63 61 63 68 65 32 2e 78 50 61 67 65 63 6f 75 6e  cache2.xPagecoun
5ff0: 74 28 70 43 61 63 68 65 2d 3e 70 43 61 63 68 65  t(pCache->pCache
6000: 29 3b 0a 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c  );.}..#ifdef SQL
6010: 49 54 45 5f 54 45 53 54 0a 2f 2a 0a 2a 2a 20 47  ITE_TEST./*.** G
6020: 65 74 20 74 68 65 20 73 75 67 67 65 73 74 65 64  et the suggested
6030: 20 63 61 63 68 65 2d 73 69 7a 65 20 76 61 6c 75   cache-size valu
6040: 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  e..*/.int sqlite
6050: 33 50 63 61 63 68 65 47 65 74 43 61 63 68 65 73  3PcacheGetCaches
6060: 69 7a 65 28 50 43 61 63 68 65 20 2a 70 43 61 63  ize(PCache *pCac
6070: 68 65 29 7b 0a 20 20 72 65 74 75 72 6e 20 6e 75  he){.  return nu
6080: 6d 62 65 72 4f 66 43 61 63 68 65 50 61 67 65 73  mberOfCachePages
6090: 28 70 43 61 63 68 65 29 3b 0a 7d 0a 23 65 6e 64  (pCache);.}.#end
60a0: 69 66 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20 74 68  if../*.** Set th
60b0: 65 20 73 75 67 67 65 73 74 65 64 20 63 61 63 68  e suggested cach
60c0: 65 2d 73 69 7a 65 20 76 61 6c 75 65 2e 0a 2a 2f  e-size value..*/
60d0: 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63 61  .void sqlite3Pca
60e0: 63 68 65 53 65 74 43 61 63 68 65 73 69 7a 65 28  cheSetCachesize(
60f0: 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 2c 20  PCache *pCache, 
6100: 69 6e 74 20 6d 78 50 61 67 65 29 7b 0a 20 20 61  int mxPage){.  a
6110: 73 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e 70  ssert( pCache->p
6120: 43 61 63 68 65 21 3d 30 20 29 3b 0a 20 20 70 43  Cache!=0 );.  pC
6130: 61 63 68 65 2d 3e 73 7a 43 61 63 68 65 20 3d 20  ache->szCache = 
6140: 6d 78 50 61 67 65 3b 0a 20 20 73 71 6c 69 74 65  mxPage;.  sqlite
6150: 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63  3GlobalConfig.pc
6160: 61 63 68 65 32 2e 78 43 61 63 68 65 73 69 7a 65  ache2.xCachesize
6170: 28 70 43 61 63 68 65 2d 3e 70 43 61 63 68 65 2c  (pCache->pCache,
6180: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
6190: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
61a0: 20 20 20 20 20 20 20 20 20 20 6e 75 6d 62 65 72            number
61b0: 4f 66 43 61 63 68 65 50 61 67 65 73 28 70 43 61  OfCachePages(pCa
61c0: 63 68 65 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  che));.}../*.** 
61d0: 53 65 74 20 74 68 65 20 73 75 67 67 65 73 74 65  Set the suggeste
61e0: 64 20 63 61 63 68 65 2d 73 70 69 6c 6c 20 76 61  d cache-spill va
61f0: 6c 75 65 2e 20 20 4d 61 6b 65 20 6e 6f 20 63 68  lue.  Make no ch
6200: 61 6e 67 65 73 20 69 66 20 69 66 20 74 68 65 0a  anges if if the.
6210: 2a 2a 20 61 72 67 75 6d 65 6e 74 20 69 73 20 7a  ** argument is z
6220: 65 72 6f 2e 20 20 52 65 74 75 72 6e 20 74 68 65  ero.  Return the
6230: 20 65 66 66 65 63 74 69 76 65 20 63 61 63 68 65   effective cache
6240: 2d 73 70 69 6c 6c 20 73 69 7a 65 2c 20 77 68 69  -spill size, whi
6250: 63 68 20 77 69 6c 6c 0a 2a 2a 20 62 65 20 74 68  ch will.** be th
6260: 65 20 6c 61 72 67 65 72 20 6f 66 20 74 68 65 20  e larger of the 
6270: 73 7a 53 70 69 6c 6c 20 61 6e 64 20 73 7a 43 61  szSpill and szCa
6280: 63 68 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  che..*/.int sqli
6290: 74 65 33 50 63 61 63 68 65 53 65 74 53 70 69 6c  te3PcacheSetSpil
62a0: 6c 73 69 7a 65 28 50 43 61 63 68 65 20 2a 70 2c  lsize(PCache *p,
62b0: 20 69 6e 74 20 6d 78 50 61 67 65 29 7b 0a 20 20   int mxPage){.  
62c0: 69 6e 74 20 72 65 73 3b 0a 20 20 61 73 73 65 72  int res;.  asser
62d0: 74 28 20 70 2d 3e 70 43 61 63 68 65 21 3d 30 20  t( p->pCache!=0 
62e0: 29 3b 0a 20 20 69 66 28 20 6d 78 50 61 67 65 20  );.  if( mxPage 
62f0: 29 7b 0a 20 20 20 20 69 66 28 20 6d 78 50 61 67  ){.    if( mxPag
6300: 65 3c 30 20 29 7b 0a 20 20 20 20 20 20 6d 78 50  e<0 ){.      mxP
6310: 61 67 65 20 3d 20 28 69 6e 74 29 28 28 2d 31 30  age = (int)((-10
6320: 32 34 2a 28 69 36 34 29 6d 78 50 61 67 65 29 2f  24*(i64)mxPage)/
6330: 28 70 2d 3e 73 7a 50 61 67 65 2b 70 2d 3e 73 7a  (p->szPage+p->sz
6340: 45 78 74 72 61 29 29 3b 0a 20 20 20 20 7d 0a 20  Extra));.    }. 
6350: 20 20 20 70 2d 3e 73 7a 53 70 69 6c 6c 20 3d 20     p->szSpill = 
6360: 6d 78 50 61 67 65 3b 0a 20 20 7d 0a 20 20 72 65  mxPage;.  }.  re
6370: 73 20 3d 20 6e 75 6d 62 65 72 4f 66 43 61 63 68  s = numberOfCach
6380: 65 50 61 67 65 73 28 70 29 3b 0a 20 20 69 66 28  ePages(p);.  if(
6390: 20 72 65 73 3c 70 2d 3e 73 7a 53 70 69 6c 6c 20   res<p->szSpill 
63a0: 29 20 72 65 73 20 3d 20 70 2d 3e 73 7a 53 70 69  ) res = p->szSpi
63b0: 6c 6c 3b 20 0a 20 20 72 65 74 75 72 6e 20 72 65  ll; .  return re
63c0: 73 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65  s;.}../*.** Free
63d0: 20 75 70 20 61 73 20 6d 75 63 68 20 6d 65 6d 6f   up as much memo
63e0: 72 79 20 61 73 20 70 6f 73 73 69 62 6c 65 20 66  ry as possible f
63f0: 72 6f 6d 20 74 68 65 20 70 61 67 65 20 63 61 63  rom the page cac
6400: 68 65 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69  he..*/.void sqli
6410: 74 65 33 50 63 61 63 68 65 53 68 72 69 6e 6b 28  te3PcacheShrink(
6420: 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b  PCache *pCache){
6430: 0a 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68  .  assert( pCach
6440: 65 2d 3e 70 43 61 63 68 65 21 3d 30 20 29 3b 0a  e->pCache!=0 );.
6450: 20 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43    sqlite3GlobalC
6460: 6f 6e 66 69 67 2e 70 63 61 63 68 65 32 2e 78 53  onfig.pcache2.xS
6470: 68 72 69 6e 6b 28 70 43 61 63 68 65 2d 3e 70 43  hrink(pCache->pC
6480: 61 63 68 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  ache);.}../*.** 
6490: 52 65 74 75 72 6e 20 74 68 65 20 73 69 7a 65 20  Return the size 
64a0: 6f 66 20 74 68 65 20 68 65 61 64 65 72 20 61 64  of the header ad
64b0: 64 65 64 20 62 79 20 74 68 69 73 20 6d 69 64 64  ded by this midd
64c0: 6c 65 77 61 72 65 20 6c 61 79 65 72 0a 2a 2a 20  leware layer.** 
64d0: 69 6e 20 74 68 65 20 70 61 67 65 2d 63 61 63 68  in the page-cach
64e0: 65 20 68 69 65 72 61 72 63 68 79 2e 0a 2a 2f 0a  e hierarchy..*/.
64f0: 69 6e 74 20 73 71 6c 69 74 65 33 48 65 61 64 65  int sqlite3Heade
6500: 72 53 69 7a 65 50 63 61 63 68 65 28 76 6f 69 64  rSizePcache(void
6510: 29 7b 20 72 65 74 75 72 6e 20 52 4f 55 4e 44 38  ){ return ROUND8
6520: 28 73 69 7a 65 6f 66 28 50 67 48 64 72 29 29 3b  (sizeof(PgHdr));
6530: 20 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e   }../*.** Return
6540: 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 64   the number of d
6550: 69 72 74 79 20 70 61 67 65 73 20 63 75 72 72 65  irty pages curre
6560: 6e 74 6c 79 20 69 6e 20 74 68 65 20 63 61 63 68  ntly in the cach
6570: 65 2c 20 61 73 20 61 20 70 65 72 63 65 6e 74 61  e, as a percenta
6580: 67 65 0a 2a 2a 20 6f 66 20 74 68 65 20 63 6f 6e  ge.** of the con
6590: 66 69 67 75 72 65 64 20 63 61 63 68 65 20 73 69  figured cache si
65a0: 7a 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  ze..*/.int sqlit
65b0: 65 33 50 43 61 63 68 65 50 65 72 63 65 6e 74 44  e3PCachePercentD
65c0: 69 72 74 79 28 50 43 61 63 68 65 20 2a 70 43 61  irty(PCache *pCa
65d0: 63 68 65 29 7b 0a 20 20 50 67 48 64 72 20 2a 70  che){.  PgHdr *p
65e0: 44 69 72 74 79 3b 0a 20 20 69 6e 74 20 6e 44 69  Dirty;.  int nDi
65f0: 72 74 79 20 3d 20 30 3b 0a 20 20 69 6e 74 20 6e  rty = 0;.  int n
6600: 43 61 63 68 65 20 3d 20 6e 75 6d 62 65 72 4f 66  Cache = numberOf
6610: 43 61 63 68 65 50 61 67 65 73 28 70 43 61 63 68  CachePages(pCach
6620: 65 29 3b 0a 20 20 66 6f 72 28 70 44 69 72 74 79  e);.  for(pDirty
6630: 3d 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 3b  =pCache->pDirty;
6640: 20 70 44 69 72 74 79 3b 20 70 44 69 72 74 79 3d   pDirty; pDirty=
6650: 70 44 69 72 74 79 2d 3e 70 44 69 72 74 79 4e 65  pDirty->pDirtyNe
6660: 78 74 29 20 6e 44 69 72 74 79 2b 2b 3b 0a 20 20  xt) nDirty++;.  
6670: 72 65 74 75 72 6e 20 6e 43 61 63 68 65 20 3f 20  return nCache ? 
6680: 28 69 6e 74 29 28 28 28 69 36 34 29 6e 44 69 72  (int)(((i64)nDir
6690: 74 79 20 2a 20 31 30 30 29 20 2f 20 6e 43 61 63  ty * 100) / nCac
66a0: 68 65 29 20 3a 20 30 3b 0a 7d 0a 0a 23 69 66 20  he) : 0;.}..#if 
66b0: 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 43  defined(SQLITE_C
66c0: 48 45 43 4b 5f 50 41 47 45 53 29 20 7c 7c 20 64  HECK_PAGES) || d
66d0: 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 44 45  efined(SQLITE_DE
66e0: 42 55 47 29 0a 2f 2a 0a 2a 2a 20 46 6f 72 20 61  BUG)./*.** For a
66f0: 6c 6c 20 64 69 72 74 79 20 70 61 67 65 73 20 63  ll dirty pages c
6700: 75 72 72 65 6e 74 6c 79 20 69 6e 20 74 68 65 20  urrently in the 
6710: 63 61 63 68 65 2c 20 69 6e 76 6f 6b 65 20 74 68  cache, invoke th
6720: 65 20 73 70 65 63 69 66 69 65 64 0a 2a 2a 20 63  e specified.** c
6730: 61 6c 6c 62 61 63 6b 2e 20 54 68 69 73 20 69 73  allback. This is
6740: 20 6f 6e 6c 79 20 75 73 65 64 20 69 66 20 74 68   only used if th
6750: 65 20 53 51 4c 49 54 45 5f 43 48 45 43 4b 5f 50  e SQLITE_CHECK_P
6760: 41 47 45 53 20 6d 61 63 72 6f 20 69 73 0a 2a 2a  AGES macro is.**
6770: 20 64 65 66 69 6e 65 64 2e 0a 2a 2f 0a 76 6f 69   defined..*/.voi
6780: 64 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 49  d sqlite3PcacheI
6790: 74 65 72 61 74 65 44 69 72 74 79 28 50 43 61 63  terateDirty(PCac
67a0: 68 65 20 2a 70 43 61 63 68 65 2c 20 76 6f 69 64  he *pCache, void
67b0: 20 28 2a 78 49 74 65 72 29 28 50 67 48 64 72 20   (*xIter)(PgHdr 
67c0: 2a 29 29 7b 0a 20 20 50 67 48 64 72 20 2a 70 44  *)){.  PgHdr *pD
67d0: 69 72 74 79 3b 0a 20 20 66 6f 72 28 70 44 69 72  irty;.  for(pDir
67e0: 74 79 3d 70 43 61 63 68 65 2d 3e 70 44 69 72 74  ty=pCache->pDirt
67f0: 79 3b 20 70 44 69 72 74 79 3b 20 70 44 69 72 74  y; pDirty; pDirt
6800: 79 3d 70 44 69 72 74 79 2d 3e 70 44 69 72 74 79  y=pDirty->pDirty
6810: 4e 65 78 74 29 7b 0a 20 20 20 20 78 49 74 65 72  Next){.    xIter
6820: 28 70 44 69 72 74 79 29 3b 0a 20 20 7d 0a 7d 0a  (pDirty);.  }.}.
6830: 23 65 6e 64 69 66 0a                             #endif.