/ Hex Artifact Content
Login

Artifact ace8f6a5ecd4711cc66a1b23053be7109bd437cf:


0000: 2f 2a 0a 2a 2a 20 32 30 30 38 20 41 75 67 75 73  /*.** 2008 Augus
0010: 74 20 30 35 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61  t 05.**.** The a
0020: 75 74 68 6f 72 20 64 69 73 63 6c 61 69 6d 73 20  uthor disclaims 
0030: 63 6f 70 79 72 69 67 68 74 20 74 6f 20 74 68 69  copyright to thi
0040: 73 20 73 6f 75 72 63 65 20 63 6f 64 65 2e 20 20  s source code.  
0050: 49 6e 20 70 6c 61 63 65 20 6f 66 0a 2a 2a 20 61  In place of.** a
0060: 20 6c 65 67 61 6c 20 6e 6f 74 69 63 65 2c 20 68   legal notice, h
0070: 65 72 65 20 69 73 20 61 20 62 6c 65 73 73 69 6e  ere is a blessin
0080: 67 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79 20  g:.**.**    May 
0090: 79 6f 75 20 64 6f 20 67 6f 6f 64 20 61 6e 64 20  you do good and 
00a0: 6e 6f 74 20 65 76 69 6c 2e 0a 2a 2a 20 20 20 20  not evil..**    
00b0: 4d 61 79 20 79 6f 75 20 66 69 6e 64 20 66 6f 72  May you find for
00c0: 67 69 76 65 6e 65 73 73 20 66 6f 72 20 79 6f 75  giveness for you
00d0: 72 73 65 6c 66 20 61 6e 64 20 66 6f 72 67 69 76  rself and forgiv
00e0: 65 20 6f 74 68 65 72 73 2e 0a 2a 2a 20 20 20 20  e others..**    
00f0: 4d 61 79 20 79 6f 75 20 73 68 61 72 65 20 66 72  May you share fr
0100: 65 65 6c 79 2c 20 6e 65 76 65 72 20 74 61 6b 69  eely, never taki
0110: 6e 67 20 6d 6f 72 65 20 74 68 61 6e 20 79 6f 75  ng more than you
0120: 20 67 69 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a   give..**.******
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 2a 2a 2a 0a 2a 2a 20 54 68 69 73 20 66 69 6c 65  ***.** This file
0180: 20 69 6d 70 6c 65 6d 65 6e 74 73 20 74 68 61 74   implements that
0190: 20 70 61 67 65 20 63 61 63 68 65 2e 0a 2a 2f 0a   page cache..*/.
01a0: 23 69 6e 63 6c 75 64 65 20 22 73 71 6c 69 74 65  #include "sqlite
01b0: 49 6e 74 2e 68 22 0a 0a 2f 2a 0a 2a 2a 20 41 20  Int.h"../*.** A 
01c0: 63 6f 6d 70 6c 65 74 65 20 70 61 67 65 20 63 61  complete page ca
01d0: 63 68 65 20 69 73 20 61 6e 20 69 6e 73 74 61 6e  che is an instan
01e0: 63 65 20 6f 66 20 74 68 69 73 20 73 74 72 75 63  ce of this struc
01f0: 74 75 72 65 2e 0a 2a 2f 0a 73 74 72 75 63 74 20  ture..*/.struct 
0200: 50 43 61 63 68 65 20 7b 0a 20 20 50 67 48 64 72  PCache {.  PgHdr
0210: 20 2a 70 44 69 72 74 79 2c 20 2a 70 44 69 72 74   *pDirty, *pDirt
0220: 79 54 61 69 6c 3b 20 20 20 20 20 20 20 20 20 2f  yTail;         /
0230: 2a 20 4c 69 73 74 20 6f 66 20 64 69 72 74 79 20  * List of dirty 
0240: 70 61 67 65 73 20 69 6e 20 4c 52 55 20 6f 72 64  pages in LRU ord
0250: 65 72 20 2a 2f 0a 20 20 50 67 48 64 72 20 2a 70  er */.  PgHdr *p
0260: 53 79 6e 63 65 64 3b 20 20 20 20 20 20 20 20 20  Synced;         
0270: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c              /* L
0280: 61 73 74 20 73 79 6e 63 65 64 20 70 61 67 65 20  ast synced page 
0290: 69 6e 20 64 69 72 74 79 20 70 61 67 65 20 6c 69  in dirty page li
02a0: 73 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 52 65 66  st */.  int nRef
02b0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
02c0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
02d0: 75 6d 62 65 72 20 6f 66 20 72 65 66 65 72 65 6e  umber of referen
02e0: 63 65 64 20 70 61 67 65 73 20 2a 2f 0a 20 20 69  ced pages */.  i
02f0: 6e 74 20 6e 4d 61 78 3b 20 20 20 20 20 20 20 20  nt nMax;        
0300: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0310: 20 20 20 2f 2a 20 43 6f 6e 66 69 67 75 72 65 64     /* Configured
0320: 20 63 61 63 68 65 20 73 69 7a 65 20 2a 2f 0a 20   cache size */. 
0330: 20 69 6e 74 20 73 7a 50 61 67 65 3b 20 20 20 20   int szPage;    
0340: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0350: 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
0360: 65 76 65 72 79 20 70 61 67 65 20 69 6e 20 74 68  every page in th
0370: 69 73 20 63 61 63 68 65 20 2a 2f 0a 20 20 69 6e  is cache */.  in
0380: 74 20 73 7a 45 78 74 72 61 3b 20 20 20 20 20 20  t szExtra;      
0390: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
03a0: 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 65 78 74    /* Size of ext
03b0: 72 61 20 73 70 61 63 65 20 66 6f 72 20 65 61 63  ra space for eac
03c0: 68 20 70 61 67 65 20 2a 2f 0a 20 20 69 6e 74 20  h page */.  int 
03d0: 62 50 75 72 67 65 61 62 6c 65 3b 20 20 20 20 20  bPurgeable;     
03e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
03f0: 2f 2a 20 54 72 75 65 20 69 66 20 70 61 67 65 73  /* True if pages
0400: 20 61 72 65 20 6f 6e 20 62 61 63 6b 69 6e 67 20   are on backing 
0410: 73 74 6f 72 65 20 2a 2f 0a 20 20 69 6e 74 20 28  store */.  int (
0420: 2a 78 53 74 72 65 73 73 29 28 76 6f 69 64 2a 2c  *xStress)(void*,
0430: 50 67 48 64 72 2a 29 3b 20 20 20 20 20 20 20 2f  PgHdr*);       /
0440: 2a 20 43 61 6c 6c 20 74 6f 20 74 72 79 20 6d 61  * Call to try ma
0450: 6b 65 20 61 20 70 61 67 65 20 63 6c 65 61 6e 20  ke a page clean 
0460: 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 53 74 72 65  */.  void *pStre
0470: 73 73 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ss;             
0480: 20 20 20 20 20 20 20 20 20 2f 2a 20 41 72 67 75           /* Argu
0490: 6d 65 6e 74 20 74 6f 20 78 53 74 72 65 73 73 20  ment to xStress 
04a0: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 70 63 61  */.  sqlite3_pca
04b0: 63 68 65 20 2a 70 43 61 63 68 65 3b 20 20 20 20  che *pCache;    
04c0: 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6c 75 67           /* Plug
04d0: 67 61 62 6c 65 20 63 61 63 68 65 20 6d 6f 64 75  gable cache modu
04e0: 6c 65 20 2a 2f 0a 20 20 50 67 48 64 72 20 2a 70  le */.  PgHdr *p
04f0: 50 61 67 65 31 3b 20 20 20 20 20 20 20 20 20 20  Page1;          
0500: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
0510: 65 66 65 72 65 6e 63 65 20 74 6f 20 70 61 67 65  eference to page
0520: 20 31 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20   1 */.};../*.** 
0530: 53 6f 6d 65 20 6f 66 20 74 68 65 20 61 73 73 65  Some of the asse
0540: 72 74 28 29 20 6d 61 63 72 6f 73 20 69 6e 20 74  rt() macros in t
0550: 68 69 73 20 63 6f 64 65 20 61 72 65 20 74 6f 6f  his code are too
0560: 20 65 78 70 65 6e 73 69 76 65 20 74 6f 20 72 75   expensive to ru
0570: 6e 0a 2a 2a 20 65 76 65 6e 20 64 75 72 69 6e 67  n.** even during
0580: 20 6e 6f 72 6d 61 6c 20 64 65 62 75 67 67 69 6e   normal debuggin
0590: 67 2e 20 20 55 73 65 20 74 68 65 6d 20 6f 6e 6c  g.  Use them onl
05a0: 79 20 72 61 72 65 6c 79 20 6f 6e 20 6c 6f 6e 67  y rarely on long
05b0: 2d 72 75 6e 6e 69 6e 67 0a 2a 2a 20 74 65 73 74  -running.** test
05c0: 73 2e 20 20 45 6e 61 62 6c 65 20 74 68 65 20 65  s.  Enable the e
05d0: 78 70 65 6e 73 69 76 65 20 61 73 73 65 72 74 73  xpensive asserts
05e0: 20 75 73 69 6e 67 20 74 68 65 0a 2a 2a 20 2d 44   using the.** -D
05f0: 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 45 58  SQLITE_ENABLE_EX
0600: 50 45 4e 53 49 56 45 5f 41 53 53 45 52 54 3d 31  PENSIVE_ASSERT=1
0610: 20 63 6f 6d 70 69 6c 65 2d 74 69 6d 65 20 6f 70   compile-time op
0620: 74 69 6f 6e 2e 0a 2a 2f 0a 23 69 66 64 65 66 20  tion..*/.#ifdef 
0630: 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 45 58  SQLITE_ENABLE_EX
0640: 50 45 4e 53 49 56 45 5f 41 53 53 45 52 54 0a 23  PENSIVE_ASSERT.#
0650: 20 64 65 66 69 6e 65 20 65 78 70 65 6e 73 69 76   define expensiv
0660: 65 5f 61 73 73 65 72 74 28 58 29 20 20 61 73 73  e_assert(X)  ass
0670: 65 72 74 28 58 29 0a 23 65 6c 73 65 0a 23 20 64  ert(X).#else.# d
0680: 65 66 69 6e 65 20 65 78 70 65 6e 73 69 76 65 5f  efine expensive_
0690: 61 73 73 65 72 74 28 58 29 0a 23 65 6e 64 69 66  assert(X).#endif
06a0: 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ../*************
06b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
06c0: 2a 2a 2a 2a 2a 20 4c 69 6e 6b 65 64 20 4c 69 73  ***** Linked Lis
06d0: 74 20 4d 61 6e 61 67 65 6d 65 6e 74 20 2a 2a 2a  t Management ***
06e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
06f0: 2a 2f 0a 0a 23 69 66 20 21 64 65 66 69 6e 65 64  */..#if !defined
0700: 28 4e 44 45 42 55 47 29 20 26 26 20 64 65 66 69  (NDEBUG) && defi
0710: 6e 65 64 28 53 51 4c 49 54 45 5f 45 4e 41 42 4c  ned(SQLITE_ENABL
0720: 45 5f 45 58 50 45 4e 53 49 56 45 5f 41 53 53 45  E_EXPENSIVE_ASSE
0730: 52 54 29 0a 2f 2a 0a 2a 2a 20 43 68 65 63 6b 20  RT)./*.** Check 
0740: 74 68 61 74 20 74 68 65 20 70 43 61 63 68 65 2d  that the pCache-
0750: 3e 70 53 79 6e 63 65 64 20 76 61 72 69 61 62 6c  >pSynced variabl
0760: 65 20 69 73 20 73 65 74 20 63 6f 72 72 65 63 74  e is set correct
0770: 6c 79 2e 20 49 66 20 69 74 0a 2a 2a 20 69 73 20  ly. If it.** is 
0780: 6e 6f 74 2c 20 65 69 74 68 65 72 20 66 61 69 6c  not, either fail
0790: 20 61 6e 20 61 73 73 65 72 74 20 6f 72 20 72 65   an assert or re
07a0: 74 75 72 6e 20 7a 65 72 6f 2e 20 4f 74 68 65 72  turn zero. Other
07b0: 77 69 73 65 2c 20 72 65 74 75 72 6e 0a 2a 2a 20  wise, return.** 
07c0: 6e 6f 6e 2d 7a 65 72 6f 2e 20 54 68 69 73 20 69  non-zero. This i
07d0: 73 20 6f 6e 6c 79 20 75 73 65 64 20 69 6e 20 64  s only used in d
07e0: 65 62 75 67 67 69 6e 67 20 62 75 69 6c 64 73 2c  ebugging builds,
07f0: 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a   as follows:.**.
0800: 2a 2a 20 20 20 65 78 70 65 6e 73 69 76 65 5f 61  **   expensive_a
0810: 73 73 65 72 74 28 20 70 63 61 63 68 65 43 68 65  ssert( pcacheChe
0820: 63 6b 53 79 6e 63 65 64 28 70 43 61 63 68 65 29  ckSynced(pCache)
0830: 20 29 3b 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e   );.*/.static in
0840: 74 20 70 63 61 63 68 65 43 68 65 63 6b 53 79 6e  t pcacheCheckSyn
0850: 63 65 64 28 50 43 61 63 68 65 20 2a 70 43 61 63  ced(PCache *pCac
0860: 68 65 29 7b 0a 20 20 50 67 48 64 72 20 2a 70 3b  he){.  PgHdr *p;
0870: 0a 20 20 66 6f 72 28 70 3d 70 43 61 63 68 65 2d  .  for(p=pCache-
0880: 3e 70 44 69 72 74 79 54 61 69 6c 3b 20 70 21 3d  >pDirtyTail; p!=
0890: 70 43 61 63 68 65 2d 3e 70 53 79 6e 63 65 64 3b  pCache->pSynced;
08a0: 20 70 3d 70 2d 3e 70 44 69 72 74 79 50 72 65 76   p=p->pDirtyPrev
08b0: 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70  ){.    assert( p
08c0: 2d 3e 6e 52 65 66 20 7c 7c 20 28 70 2d 3e 66 6c  ->nRef || (p->fl
08d0: 61 67 73 26 50 47 48 44 52 5f 4e 45 45 44 5f 53  ags&PGHDR_NEED_S
08e0: 59 4e 43 29 20 29 3b 0a 20 20 7d 0a 20 20 72 65  YNC) );.  }.  re
08f0: 74 75 72 6e 20 28 70 3d 3d 30 20 7c 7c 20 70 2d  turn (p==0 || p-
0900: 3e 6e 52 65 66 20 7c 7c 20 28 70 2d 3e 66 6c 61  >nRef || (p->fla
0910: 67 73 26 50 47 48 44 52 5f 4e 45 45 44 5f 53 59  gs&PGHDR_NEED_SY
0920: 4e 43 29 3d 3d 30 29 3b 0a 7d 0a 23 65 6e 64 69  NC)==0);.}.#endi
0930: 66 20 2f 2a 20 21 4e 44 45 42 55 47 20 26 26 20  f /* !NDEBUG && 
0940: 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 45 58  SQLITE_ENABLE_EX
0950: 50 45 4e 53 49 56 45 5f 41 53 53 45 52 54 20 2a  PENSIVE_ASSERT *
0960: 2f 0a 0a 2f 2a 0a 2a 2a 20 52 65 6d 6f 76 65 20  /../*.** Remove 
0970: 70 61 67 65 20 70 50 61 67 65 20 66 72 6f 6d 20  page pPage from 
0980: 74 68 65 20 6c 69 73 74 20 6f 66 20 64 69 72 74  the list of dirt
0990: 79 20 70 61 67 65 73 2e 0a 2a 2f 0a 73 74 61 74  y pages..*/.stat
09a0: 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 52 65  ic void pcacheRe
09b0: 6d 6f 76 65 46 72 6f 6d 44 69 72 74 79 4c 69 73  moveFromDirtyLis
09c0: 74 28 50 67 48 64 72 20 2a 70 50 61 67 65 29 7b  t(PgHdr *pPage){
09d0: 0a 20 20 50 43 61 63 68 65 20 2a 70 20 3d 20 70  .  PCache *p = p
09e0: 50 61 67 65 2d 3e 70 43 61 63 68 65 3b 0a 0a 20  Page->pCache;.. 
09f0: 20 61 73 73 65 72 74 28 20 70 50 61 67 65 2d 3e   assert( pPage->
0a00: 70 44 69 72 74 79 4e 65 78 74 20 7c 7c 20 70 50  pDirtyNext || pP
0a10: 61 67 65 3d 3d 70 2d 3e 70 44 69 72 74 79 54 61  age==p->pDirtyTa
0a20: 69 6c 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  il );.  assert( 
0a30: 70 50 61 67 65 2d 3e 70 44 69 72 74 79 50 72 65  pPage->pDirtyPre
0a40: 76 20 7c 7c 20 70 50 61 67 65 3d 3d 70 2d 3e 70  v || pPage==p->p
0a50: 44 69 72 74 79 20 29 3b 0a 0a 20 20 2f 2a 20 55  Dirty );..  /* U
0a60: 70 64 61 74 65 20 74 68 65 20 50 43 61 63 68 65  pdate the PCache
0a70: 31 2e 70 53 79 6e 63 65 64 20 76 61 72 69 61 62  1.pSynced variab
0a80: 6c 65 20 69 66 20 6e 65 63 65 73 73 61 72 79 2e  le if necessary.
0a90: 20 2a 2f 0a 20 20 69 66 28 20 70 2d 3e 70 53 79   */.  if( p->pSy
0aa0: 6e 63 65 64 3d 3d 70 50 61 67 65 20 29 7b 0a 20  nced==pPage ){. 
0ab0: 20 20 20 50 67 48 64 72 20 2a 70 53 79 6e 63 65     PgHdr *pSynce
0ac0: 64 20 3d 20 70 50 61 67 65 2d 3e 70 44 69 72 74  d = pPage->pDirt
0ad0: 79 50 72 65 76 3b 0a 20 20 20 20 77 68 69 6c 65  yPrev;.    while
0ae0: 28 20 70 53 79 6e 63 65 64 20 26 26 20 28 70 53  ( pSynced && (pS
0af0: 79 6e 63 65 64 2d 3e 66 6c 61 67 73 26 50 47 48  ynced->flags&PGH
0b00: 44 52 5f 4e 45 45 44 5f 53 59 4e 43 29 20 29 7b  DR_NEED_SYNC) ){
0b10: 0a 20 20 20 20 20 20 70 53 79 6e 63 65 64 20 3d  .      pSynced =
0b20: 20 70 53 79 6e 63 65 64 2d 3e 70 44 69 72 74 79   pSynced->pDirty
0b30: 50 72 65 76 3b 0a 20 20 20 20 7d 0a 20 20 20 20  Prev;.    }.    
0b40: 70 2d 3e 70 53 79 6e 63 65 64 20 3d 20 70 53 79  p->pSynced = pSy
0b50: 6e 63 65 64 3b 0a 20 20 7d 0a 0a 20 20 69 66 28  nced;.  }..  if(
0b60: 20 70 50 61 67 65 2d 3e 70 44 69 72 74 79 4e 65   pPage->pDirtyNe
0b70: 78 74 20 29 7b 0a 20 20 20 20 70 50 61 67 65 2d  xt ){.    pPage-
0b80: 3e 70 44 69 72 74 79 4e 65 78 74 2d 3e 70 44 69  >pDirtyNext->pDi
0b90: 72 74 79 50 72 65 76 20 3d 20 70 50 61 67 65 2d  rtyPrev = pPage-
0ba0: 3e 70 44 69 72 74 79 50 72 65 76 3b 0a 20 20 7d  >pDirtyPrev;.  }
0bb0: 65 6c 73 65 7b 0a 20 20 20 20 61 73 73 65 72 74  else{.    assert
0bc0: 28 20 70 50 61 67 65 3d 3d 70 2d 3e 70 44 69 72  ( pPage==p->pDir
0bd0: 74 79 54 61 69 6c 20 29 3b 0a 20 20 20 20 70 2d  tyTail );.    p-
0be0: 3e 70 44 69 72 74 79 54 61 69 6c 20 3d 20 70 50  >pDirtyTail = pP
0bf0: 61 67 65 2d 3e 70 44 69 72 74 79 50 72 65 76 3b  age->pDirtyPrev;
0c00: 0a 20 20 7d 0a 20 20 69 66 28 20 70 50 61 67 65  .  }.  if( pPage
0c10: 2d 3e 70 44 69 72 74 79 50 72 65 76 20 29 7b 0a  ->pDirtyPrev ){.
0c20: 20 20 20 20 70 50 61 67 65 2d 3e 70 44 69 72 74      pPage->pDirt
0c30: 79 50 72 65 76 2d 3e 70 44 69 72 74 79 4e 65 78  yPrev->pDirtyNex
0c40: 74 20 3d 20 70 50 61 67 65 2d 3e 70 44 69 72 74  t = pPage->pDirt
0c50: 79 4e 65 78 74 3b 0a 20 20 7d 65 6c 73 65 7b 0a  yNext;.  }else{.
0c60: 20 20 20 20 61 73 73 65 72 74 28 20 70 50 61 67      assert( pPag
0c70: 65 3d 3d 70 2d 3e 70 44 69 72 74 79 20 29 3b 0a  e==p->pDirty );.
0c80: 20 20 20 20 70 2d 3e 70 44 69 72 74 79 20 3d 20      p->pDirty = 
0c90: 70 50 61 67 65 2d 3e 70 44 69 72 74 79 4e 65 78  pPage->pDirtyNex
0ca0: 74 3b 0a 20 20 7d 0a 20 20 70 50 61 67 65 2d 3e  t;.  }.  pPage->
0cb0: 70 44 69 72 74 79 4e 65 78 74 20 3d 20 30 3b 0a  pDirtyNext = 0;.
0cc0: 20 20 70 50 61 67 65 2d 3e 70 44 69 72 74 79 50    pPage->pDirtyP
0cd0: 72 65 76 20 3d 20 30 3b 0a 0a 20 20 65 78 70 65  rev = 0;..  expe
0ce0: 6e 73 69 76 65 5f 61 73 73 65 72 74 28 20 70 63  nsive_assert( pc
0cf0: 61 63 68 65 43 68 65 63 6b 53 79 6e 63 65 64 28  acheCheckSynced(
0d00: 70 29 20 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41  p) );.}../*.** A
0d10: 64 64 20 70 61 67 65 20 70 50 61 67 65 20 74 6f  dd page pPage to
0d20: 20 74 68 65 20 68 65 61 64 20 6f 66 20 74 68 65   the head of the
0d30: 20 64 69 72 74 79 20 6c 69 73 74 20 28 50 43 61   dirty list (PCa
0d40: 63 68 65 31 2e 70 44 69 72 74 79 20 69 73 20 73  che1.pDirty is s
0d50: 65 74 20 74 6f 0a 2a 2a 20 70 50 61 67 65 29 2e  et to.** pPage).
0d60: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
0d70: 70 63 61 63 68 65 41 64 64 54 6f 44 69 72 74 79  pcacheAddToDirty
0d80: 4c 69 73 74 28 50 67 48 64 72 20 2a 70 50 61 67  List(PgHdr *pPag
0d90: 65 29 7b 0a 20 20 50 43 61 63 68 65 20 2a 70 20  e){.  PCache *p 
0da0: 3d 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65 3b  = pPage->pCache;
0db0: 0a 0a 20 20 61 73 73 65 72 74 28 20 70 50 61 67  ..  assert( pPag
0dc0: 65 2d 3e 70 44 69 72 74 79 4e 65 78 74 3d 3d 30  e->pDirtyNext==0
0dd0: 20 26 26 20 70 50 61 67 65 2d 3e 70 44 69 72 74   && pPage->pDirt
0de0: 79 50 72 65 76 3d 3d 30 20 26 26 20 70 2d 3e 70  yPrev==0 && p->p
0df0: 44 69 72 74 79 21 3d 70 50 61 67 65 20 29 3b 0a  Dirty!=pPage );.
0e00: 0a 20 20 70 50 61 67 65 2d 3e 70 44 69 72 74 79  .  pPage->pDirty
0e10: 4e 65 78 74 20 3d 20 70 2d 3e 70 44 69 72 74 79  Next = p->pDirty
0e20: 3b 0a 20 20 69 66 28 20 70 50 61 67 65 2d 3e 70  ;.  if( pPage->p
0e30: 44 69 72 74 79 4e 65 78 74 20 29 7b 0a 20 20 20  DirtyNext ){.   
0e40: 20 61 73 73 65 72 74 28 20 70 50 61 67 65 2d 3e   assert( pPage->
0e50: 70 44 69 72 74 79 4e 65 78 74 2d 3e 70 44 69 72  pDirtyNext->pDir
0e60: 74 79 50 72 65 76 3d 3d 30 20 29 3b 0a 20 20 20  tyPrev==0 );.   
0e70: 20 70 50 61 67 65 2d 3e 70 44 69 72 74 79 4e 65   pPage->pDirtyNe
0e80: 78 74 2d 3e 70 44 69 72 74 79 50 72 65 76 20 3d  xt->pDirtyPrev =
0e90: 20 70 50 61 67 65 3b 0a 20 20 7d 0a 20 20 70 2d   pPage;.  }.  p-
0ea0: 3e 70 44 69 72 74 79 20 3d 20 70 50 61 67 65 3b  >pDirty = pPage;
0eb0: 0a 20 20 69 66 28 20 21 70 2d 3e 70 44 69 72 74  .  if( !p->pDirt
0ec0: 79 54 61 69 6c 20 29 7b 0a 20 20 20 20 70 2d 3e  yTail ){.    p->
0ed0: 70 44 69 72 74 79 54 61 69 6c 20 3d 20 70 50 61  pDirtyTail = pPa
0ee0: 67 65 3b 0a 20 20 7d 0a 20 20 69 66 28 20 21 70  ge;.  }.  if( !p
0ef0: 2d 3e 70 53 79 6e 63 65 64 20 26 26 20 30 3d 3d  ->pSynced && 0==
0f00: 28 70 50 61 67 65 2d 3e 66 6c 61 67 73 26 50 47  (pPage->flags&PG
0f10: 48 44 52 5f 4e 45 45 44 5f 53 59 4e 43 29 20 29  HDR_NEED_SYNC) )
0f20: 7b 0a 20 20 20 20 70 2d 3e 70 53 79 6e 63 65 64  {.    p->pSynced
0f30: 20 3d 20 70 50 61 67 65 3b 0a 20 20 7d 0a 20 20   = pPage;.  }.  
0f40: 65 78 70 65 6e 73 69 76 65 5f 61 73 73 65 72 74  expensive_assert
0f50: 28 20 70 63 61 63 68 65 43 68 65 63 6b 53 79 6e  ( pcacheCheckSyn
0f60: 63 65 64 28 70 29 20 29 3b 0a 7d 0a 0a 2f 2a 0a  ced(p) );.}../*.
0f70: 2a 2a 20 57 72 61 70 70 65 72 20 61 72 6f 75 6e  ** Wrapper aroun
0f80: 64 20 74 68 65 20 70 6c 75 67 67 61 62 6c 65 20  d the pluggable 
0f90: 63 61 63 68 65 73 20 78 55 6e 70 69 6e 20 6d 65  caches xUnpin me
0fa0: 74 68 6f 64 2e 20 49 66 20 74 68 65 20 63 61 63  thod. If the cac
0fb0: 68 65 20 69 73 0a 2a 2a 20 62 65 69 6e 67 20 75  he is.** being u
0fc0: 73 65 64 20 66 6f 72 20 61 6e 20 69 6e 2d 6d 65  sed for an in-me
0fd0: 6d 6f 72 79 20 64 61 74 61 62 61 73 65 2c 20 74  mory database, t
0fe0: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
0ff0: 61 20 6e 6f 2d 6f 70 2e 0a 2a 2f 0a 73 74 61 74  a no-op..*/.stat
1000: 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 55 6e  ic void pcacheUn
1010: 70 69 6e 28 50 67 48 64 72 20 2a 70 29 7b 0a 20  pin(PgHdr *p){. 
1020: 20 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 20   PCache *pCache 
1030: 3d 20 70 2d 3e 70 43 61 63 68 65 3b 0a 20 20 69  = p->pCache;.  i
1040: 66 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67  f( pCache->bPurg
1050: 65 61 62 6c 65 20 29 7b 0a 20 20 20 20 69 66 28  eable ){.    if(
1060: 20 70 2d 3e 70 67 6e 6f 3d 3d 31 20 29 7b 0a 20   p->pgno==1 ){. 
1070: 20 20 20 20 20 70 43 61 63 68 65 2d 3e 70 50 61       pCache->pPa
1080: 67 65 31 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20  ge1 = 0;.    }. 
1090: 20 20 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c     sqlite3Global
10a0: 43 6f 6e 66 69 67 2e 70 63 61 63 68 65 2e 78 55  Config.pcache.xU
10b0: 6e 70 69 6e 28 70 43 61 63 68 65 2d 3e 70 43 61  npin(pCache->pCa
10c0: 63 68 65 2c 20 70 2c 20 30 29 3b 0a 20 20 7d 0a  che, p, 0);.  }.
10d0: 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  }../************
10e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
10f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1100: 2a 2a 2a 2a 2a 2a 2a 20 47 65 6e 65 72 61 6c 20  ******* General 
1110: 49 6e 74 65 72 66 61 63 65 73 20 2a 2a 2a 2a 2a  Interfaces *****
1120: 2a 0a 2a 2a 0a 2a 2a 20 49 6e 69 74 69 61 6c 69  *.**.** Initiali
1130: 7a 65 20 61 6e 64 20 73 68 75 74 64 6f 77 6e 20  ze and shutdown 
1140: 74 68 65 20 70 61 67 65 20 63 61 63 68 65 20 73  the page cache s
1150: 75 62 73 79 73 74 65 6d 2e 20 4e 65 69 74 68 65  ubsystem. Neithe
1160: 72 20 6f 66 20 74 68 65 73 65 20 0a 2a 2a 20 66  r of these .** f
1170: 75 6e 63 74 69 6f 6e 73 20 61 72 65 20 74 68 72  unctions are thr
1180: 65 61 64 73 61 66 65 2e 0a 2a 2f 0a 69 6e 74 20  eadsafe..*/.int 
1190: 73 71 6c 69 74 65 33 50 63 61 63 68 65 49 6e 69  sqlite3PcacheIni
11a0: 74 69 61 6c 69 7a 65 28 76 6f 69 64 29 7b 0a 20  tialize(void){. 
11b0: 20 69 66 28 20 73 71 6c 69 74 65 33 47 6c 6f 62   if( sqlite3Glob
11c0: 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65 2e  alConfig.pcache.
11d0: 78 49 6e 69 74 3d 3d 30 20 29 7b 0a 20 20 20 20  xInit==0 ){.    
11e0: 73 71 6c 69 74 65 33 50 43 61 63 68 65 53 65 74  sqlite3PCacheSet
11f0: 44 65 66 61 75 6c 74 28 29 3b 0a 20 20 7d 0a 20  Default();.  }. 
1200: 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 47   return sqlite3G
1210: 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63  lobalConfig.pcac
1220: 68 65 2e 78 49 6e 69 74 28 73 71 6c 69 74 65 33  he.xInit(sqlite3
1230: 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61  GlobalConfig.pca
1240: 63 68 65 2e 70 41 72 67 29 3b 0a 7d 0a 76 6f 69  che.pArg);.}.voi
1250: 64 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 53  d sqlite3PcacheS
1260: 68 75 74 64 6f 77 6e 28 76 6f 69 64 29 7b 0a 20  hutdown(void){. 
1270: 20 69 66 28 20 73 71 6c 69 74 65 33 47 6c 6f 62   if( sqlite3Glob
1280: 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65 2e  alConfig.pcache.
1290: 78 53 68 75 74 64 6f 77 6e 20 29 7b 0a 20 20 20  xShutdown ){.   
12a0: 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f   sqlite3GlobalCo
12b0: 6e 66 69 67 2e 70 63 61 63 68 65 2e 78 53 68 75  nfig.pcache.xShu
12c0: 74 64 6f 77 6e 28 73 71 6c 69 74 65 33 47 6c 6f  tdown(sqlite3Glo
12d0: 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65  balConfig.pcache
12e0: 2e 70 41 72 67 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f  .pArg);.  }.}../
12f0: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20  *.** Return the 
1300: 73 69 7a 65 20 69 6e 20 62 79 74 65 73 20 6f 66  size in bytes of
1310: 20 61 20 50 43 61 63 68 65 20 6f 62 6a 65 63 74   a PCache object
1320: 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33  ..*/.int sqlite3
1330: 50 63 61 63 68 65 53 69 7a 65 28 76 6f 69 64 29  PcacheSize(void)
1340: 7b 20 72 65 74 75 72 6e 20 73 69 7a 65 6f 66 28  { return sizeof(
1350: 50 43 61 63 68 65 29 3b 20 7d 0a 0a 2f 2a 0a 2a  PCache); }../*.*
1360: 2a 20 43 72 65 61 74 65 20 61 20 6e 65 77 20 50  * Create a new P
1370: 43 61 63 68 65 20 6f 62 6a 65 63 74 2e 20 53 74  Cache object. St
1380: 6f 72 61 67 65 20 73 70 61 63 65 20 74 6f 20 68  orage space to h
1390: 6f 6c 64 20 74 68 65 20 6f 62 6a 65 63 74 0a 2a  old the object.*
13a0: 2a 20 68 61 73 20 61 6c 72 65 61 64 79 20 62 65  * has already be
13b0: 65 6e 20 61 6c 6c 6f 63 61 74 65 64 20 61 6e 64  en allocated and
13c0: 20 69 73 20 70 61 73 73 65 64 20 69 6e 20 61 73   is passed in as
13d0: 20 74 68 65 20 70 20 70 6f 69 6e 74 65 72 2e 20   the p pointer. 
13e0: 0a 2a 2a 20 54 68 65 20 63 61 6c 6c 65 72 20 64  .** The caller d
13f0: 69 73 63 6f 76 65 72 73 20 68 6f 77 20 6d 75 63  iscovers how muc
1400: 68 20 73 70 61 63 65 20 6e 65 65 64 73 20 74 6f  h space needs to
1410: 20 62 65 20 61 6c 6c 6f 63 61 74 65 64 20 62 79   be allocated by
1420: 20 0a 2a 2a 20 63 61 6c 6c 69 6e 67 20 73 71 6c   .** calling sql
1430: 69 74 65 33 50 63 61 63 68 65 53 69 7a 65 28 29  ite3PcacheSize()
1440: 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
1450: 33 50 63 61 63 68 65 4f 70 65 6e 28 0a 20 20 69  3PcacheOpen(.  i
1460: 6e 74 20 73 7a 50 61 67 65 2c 20 20 20 20 20 20  nt szPage,      
1470: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
1480: 69 7a 65 20 6f 66 20 65 76 65 72 79 20 70 61 67  ize of every pag
1490: 65 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 45 78 74  e */.  int szExt
14a0: 72 61 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ra,             
14b0: 20 20 20 20 2f 2a 20 45 78 74 72 61 20 73 70 61      /* Extra spa
14c0: 63 65 20 61 73 73 6f 63 69 61 74 65 64 20 77 69  ce associated wi
14d0: 74 68 20 65 61 63 68 20 70 61 67 65 20 2a 2f 0a  th each page */.
14e0: 20 20 69 6e 74 20 62 50 75 72 67 65 61 62 6c 65    int bPurgeable
14f0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ,              /
1500: 2a 20 54 72 75 65 20 69 66 20 70 61 67 65 73 20  * True if pages 
1510: 61 72 65 20 6f 6e 20 62 61 63 6b 69 6e 67 20 73  are on backing s
1520: 74 6f 72 65 20 2a 2f 0a 20 20 69 6e 74 20 28 2a  tore */.  int (*
1530: 78 53 74 72 65 73 73 29 28 76 6f 69 64 2a 2c 50  xStress)(void*,P
1540: 67 48 64 72 2a 29 2c 2f 2a 20 43 61 6c 6c 20 74  gHdr*),/* Call t
1550: 6f 20 74 72 79 20 74 6f 20 6d 61 6b 65 20 70 61  o try to make pa
1560: 67 65 73 20 63 6c 65 61 6e 20 2a 2f 0a 20 20 76  ges clean */.  v
1570: 6f 69 64 20 2a 70 53 74 72 65 73 73 2c 20 20 20  oid *pStress,   
1580: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41              /* A
1590: 72 67 75 6d 65 6e 74 20 74 6f 20 78 53 74 72 65  rgument to xStre
15a0: 73 73 20 2a 2f 0a 20 20 50 43 61 63 68 65 20 2a  ss */.  PCache *
15b0: 70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  p               
15c0: 20 20 20 20 20 2f 2a 20 50 72 65 61 6c 6c 6f 63       /* Prealloc
15d0: 61 74 65 64 20 73 70 61 63 65 20 66 6f 72 20 74  ated space for t
15e0: 68 65 20 50 43 61 63 68 65 20 2a 2f 0a 29 7b 0a  he PCache */.){.
15f0: 20 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20 73    memset(p, 0, s
1600: 69 7a 65 6f 66 28 50 43 61 63 68 65 29 29 3b 0a  izeof(PCache));.
1610: 20 20 70 2d 3e 73 7a 50 61 67 65 20 3d 20 73 7a    p->szPage = sz
1620: 50 61 67 65 3b 0a 20 20 70 2d 3e 73 7a 45 78 74  Page;.  p->szExt
1630: 72 61 20 3d 20 73 7a 45 78 74 72 61 3b 0a 20 20  ra = szExtra;.  
1640: 70 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 3d 20  p->bPurgeable = 
1650: 62 50 75 72 67 65 61 62 6c 65 3b 0a 20 20 70 2d  bPurgeable;.  p-
1660: 3e 78 53 74 72 65 73 73 20 3d 20 78 53 74 72 65  >xStress = xStre
1670: 73 73 3b 0a 20 20 70 2d 3e 70 53 74 72 65 73 73  ss;.  p->pStress
1680: 20 3d 20 70 53 74 72 65 73 73 3b 0a 20 20 70 2d   = pStress;.  p-
1690: 3e 6e 4d 61 78 20 3d 20 31 30 30 3b 0a 7d 0a 0a  >nMax = 100;.}..
16a0: 2f 2a 0a 2a 2a 20 43 68 61 6e 67 65 20 74 68 65  /*.** Change the
16b0: 20 70 61 67 65 20 73 69 7a 65 20 66 6f 72 20 50   page size for P
16c0: 43 61 63 68 65 20 6f 62 6a 65 63 74 2e 20 54 68  Cache object. Th
16d0: 65 20 63 61 6c 6c 65 72 20 6d 75 73 74 20 65 6e  e caller must en
16e0: 73 75 72 65 20 74 68 61 74 20 74 68 65 72 65 0a  sure that there.
16f0: 2a 2a 20 61 72 65 20 6e 6f 20 6f 75 74 73 74 61  ** are no outsta
1700: 6e 64 69 6e 67 20 70 61 67 65 20 72 65 66 65 72  nding page refer
1710: 65 6e 63 65 73 20 77 68 65 6e 20 74 68 69 73 20  ences when this 
1720: 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c  function is call
1730: 65 64 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69  ed..*/.void sqli
1740: 74 65 33 50 63 61 63 68 65 53 65 74 50 61 67 65  te3PcacheSetPage
1750: 53 69 7a 65 28 50 43 61 63 68 65 20 2a 70 43 61  Size(PCache *pCa
1760: 63 68 65 2c 20 69 6e 74 20 73 7a 50 61 67 65 29  che, int szPage)
1770: 7b 0a 20 20 61 73 73 65 72 74 28 20 70 43 61 63  {.  assert( pCac
1780: 68 65 2d 3e 6e 52 65 66 3d 3d 30 20 26 26 20 70  he->nRef==0 && p
1790: 43 61 63 68 65 2d 3e 70 44 69 72 74 79 3d 3d 30  Cache->pDirty==0
17a0: 20 29 3b 0a 20 20 69 66 28 20 70 43 61 63 68 65   );.  if( pCache
17b0: 2d 3e 70 43 61 63 68 65 20 29 7b 0a 20 20 20 20  ->pCache ){.    
17c0: 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e  sqlite3GlobalCon
17d0: 66 69 67 2e 70 63 61 63 68 65 2e 78 44 65 73 74  fig.pcache.xDest
17e0: 72 6f 79 28 70 43 61 63 68 65 2d 3e 70 43 61 63  roy(pCache->pCac
17f0: 68 65 29 3b 0a 20 20 20 20 70 43 61 63 68 65 2d  he);.    pCache-
1800: 3e 70 43 61 63 68 65 20 3d 20 30 3b 0a 20 20 20  >pCache = 0;.   
1810: 20 70 43 61 63 68 65 2d 3e 70 50 61 67 65 31 20   pCache->pPage1 
1820: 3d 20 30 3b 0a 20 20 7d 0a 20 20 70 43 61 63 68  = 0;.  }.  pCach
1830: 65 2d 3e 73 7a 50 61 67 65 20 3d 20 73 7a 50 61  e->szPage = szPa
1840: 67 65 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 72 79  ge;.}../*.** Try
1850: 20 74 6f 20 6f 62 74 61 69 6e 20 61 20 70 61 67   to obtain a pag
1860: 65 20 66 72 6f 6d 20 74 68 65 20 63 61 63 68 65  e from the cache
1870: 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33  ..*/.int sqlite3
1880: 50 63 61 63 68 65 46 65 74 63 68 28 0a 20 20 50  PcacheFetch(.  P
1890: 43 61 63 68 65 20 2a 70 43 61 63 68 65 2c 20 20  Cache *pCache,  
18a0: 20 20 20 20 20 2f 2a 20 4f 62 74 61 69 6e 20 74       /* Obtain t
18b0: 68 65 20 70 61 67 65 20 66 72 6f 6d 20 74 68 69  he page from thi
18c0: 73 20 63 61 63 68 65 20 2a 2f 0a 20 20 50 67 6e  s cache */.  Pgn
18d0: 6f 20 70 67 6e 6f 2c 20 20 20 20 20 20 20 20 20  o pgno,         
18e0: 20 20 20 2f 2a 20 50 61 67 65 20 6e 75 6d 62 65     /* Page numbe
18f0: 72 20 74 6f 20 6f 62 74 61 69 6e 20 2a 2f 0a 20  r to obtain */. 
1900: 20 69 6e 74 20 63 72 65 61 74 65 46 6c 61 67 2c   int createFlag,
1910: 20 20 20 20 20 20 20 2f 2a 20 49 66 20 74 72 75         /* If tru
1920: 65 2c 20 63 72 65 61 74 65 20 70 61 67 65 20 69  e, create page i
1930: 66 20 69 74 20 64 6f 65 73 20 6e 6f 74 20 65 78  f it does not ex
1940: 69 73 74 20 61 6c 72 65 61 64 79 20 2a 2f 0a 20  ist already */. 
1950: 20 50 67 48 64 72 20 2a 2a 70 70 50 61 67 65 20   PgHdr **ppPage 
1960: 20 20 20 20 20 20 20 2f 2a 20 57 72 69 74 65 20         /* Write 
1970: 74 68 65 20 70 61 67 65 20 68 65 72 65 20 2a 2f  the page here */
1980: 0a 29 7b 0a 20 20 50 67 48 64 72 20 2a 70 50 61  .){.  PgHdr *pPa
1990: 67 65 20 3d 20 30 3b 0a 20 20 69 6e 74 20 65 43  ge = 0;.  int eC
19a0: 72 65 61 74 65 3b 0a 0a 20 20 61 73 73 65 72 74  reate;..  assert
19b0: 28 20 70 43 61 63 68 65 21 3d 30 20 29 3b 0a 20  ( pCache!=0 );. 
19c0: 20 61 73 73 65 72 74 28 20 63 72 65 61 74 65 46   assert( createF
19d0: 6c 61 67 3d 3d 31 20 7c 7c 20 63 72 65 61 74 65  lag==1 || create
19e0: 46 6c 61 67 3d 3d 30 20 29 3b 0a 20 20 61 73 73  Flag==0 );.  ass
19f0: 65 72 74 28 20 70 67 6e 6f 3e 30 20 29 3b 0a 0a  ert( pgno>0 );..
1a00: 20 20 2f 2a 20 49 66 20 74 68 65 20 70 6c 75 67    /* If the plug
1a10: 67 61 62 6c 65 20 63 61 63 68 65 20 28 73 71 6c  gable cache (sql
1a20: 69 74 65 33 5f 70 63 61 63 68 65 2a 29 20 68 61  ite3_pcache*) ha
1a30: 73 20 6e 6f 74 20 62 65 65 6e 20 61 6c 6c 6f 63  s not been alloc
1a40: 61 74 65 64 2c 0a 20 20 2a 2a 20 61 6c 6c 6f 63  ated,.  ** alloc
1a50: 61 74 65 20 69 74 20 6e 6f 77 2e 0a 20 20 2a 2f  ate it now..  */
1a60: 0a 20 20 69 66 28 20 21 70 43 61 63 68 65 2d 3e  .  if( !pCache->
1a70: 70 43 61 63 68 65 20 26 26 20 63 72 65 61 74 65  pCache && create
1a80: 46 6c 61 67 20 29 7b 0a 20 20 20 20 73 71 6c 69  Flag ){.    sqli
1a90: 74 65 33 5f 70 63 61 63 68 65 20 2a 70 3b 0a 20  te3_pcache *p;. 
1aa0: 20 20 20 69 6e 74 20 6e 42 79 74 65 3b 0a 20 20     int nByte;.  
1ab0: 20 20 6e 42 79 74 65 20 3d 20 70 43 61 63 68 65    nByte = pCache
1ac0: 2d 3e 73 7a 50 61 67 65 20 2b 20 70 43 61 63 68  ->szPage + pCach
1ad0: 65 2d 3e 73 7a 45 78 74 72 61 20 2b 20 73 69 7a  e->szExtra + siz
1ae0: 65 6f 66 28 50 67 48 64 72 29 3b 0a 20 20 20 20  eof(PgHdr);.    
1af0: 70 20 3d 20 73 71 6c 69 74 65 33 47 6c 6f 62 61  p = sqlite3Globa
1b00: 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65 2e 78  lConfig.pcache.x
1b10: 43 72 65 61 74 65 28 6e 42 79 74 65 2c 20 70 43  Create(nByte, pC
1b20: 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65  ache->bPurgeable
1b30: 29 3b 0a 20 20 20 20 69 66 28 20 21 70 20 29 7b  );.    if( !p ){
1b40: 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 53 51  .      return SQ
1b50: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
1b60: 7d 0a 20 20 20 20 73 71 6c 69 74 65 33 47 6c 6f  }.    sqlite3Glo
1b70: 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65  balConfig.pcache
1b80: 2e 78 43 61 63 68 65 73 69 7a 65 28 70 2c 20 70  .xCachesize(p, p
1b90: 43 61 63 68 65 2d 3e 6e 4d 61 78 29 3b 0a 20 20  Cache->nMax);.  
1ba0: 20 20 70 43 61 63 68 65 2d 3e 70 43 61 63 68 65    pCache->pCache
1bb0: 20 3d 20 70 3b 0a 20 20 7d 0a 0a 20 20 65 43 72   = p;.  }..  eCr
1bc0: 65 61 74 65 20 3d 20 63 72 65 61 74 65 46 6c 61  eate = createFla
1bd0: 67 20 2a 20 28 31 20 2b 20 28 21 70 43 61 63 68  g * (1 + (!pCach
1be0: 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 7c 7c  e->bPurgeable ||
1bf0: 20 21 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79   !pCache->pDirty
1c00: 29 29 3b 0a 20 20 69 66 28 20 70 43 61 63 68 65  ));.  if( pCache
1c10: 2d 3e 70 43 61 63 68 65 20 29 7b 0a 20 20 20 20  ->pCache ){.    
1c20: 70 50 61 67 65 20 3d 20 73 71 6c 69 74 65 33 47  pPage = sqlite3G
1c30: 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63  lobalConfig.pcac
1c40: 68 65 2e 78 46 65 74 63 68 28 70 43 61 63 68 65  he.xFetch(pCache
1c50: 2d 3e 70 43 61 63 68 65 2c 20 70 67 6e 6f 2c 20  ->pCache, pgno, 
1c60: 65 43 72 65 61 74 65 29 3b 0a 20 20 7d 0a 0a 20  eCreate);.  }.. 
1c70: 20 69 66 28 20 21 70 50 61 67 65 20 26 26 20 65   if( !pPage && e
1c80: 43 72 65 61 74 65 3d 3d 31 20 29 7b 0a 20 20 20  Create==1 ){.   
1c90: 20 50 67 48 64 72 20 2a 70 50 67 3b 0a 0a 20 20   PgHdr *pPg;..  
1ca0: 20 20 2f 2a 20 46 69 6e 64 20 61 20 64 69 72 74    /* Find a dirt
1cb0: 79 20 70 61 67 65 20 74 6f 20 77 72 69 74 65 2d  y page to write-
1cc0: 6f 75 74 20 61 6e 64 20 72 65 63 79 63 6c 65 2e  out and recycle.
1cd0: 20 46 69 72 73 74 20 74 72 79 20 74 6f 20 66 69   First try to fi
1ce0: 6e 64 20 61 20 0a 20 20 20 20 2a 2a 20 70 61 67  nd a .    ** pag
1cf0: 65 20 74 68 61 74 20 64 6f 65 73 20 6e 6f 74 20  e that does not 
1d00: 72 65 71 75 69 72 65 20 61 20 6a 6f 75 72 6e 61  require a journa
1d10: 6c 2d 73 79 6e 63 20 28 6f 6e 65 20 77 69 74 68  l-sync (one with
1d20: 20 50 47 48 44 52 5f 4e 45 45 44 5f 53 59 4e 43   PGHDR_NEED_SYNC
1d30: 0a 20 20 20 20 2a 2a 20 63 6c 65 61 72 65 64 29  .    ** cleared)
1d40: 2c 20 62 75 74 20 69 66 20 74 68 61 74 20 69 73  , but if that is
1d50: 20 6e 6f 74 20 70 6f 73 73 69 62 6c 65 20 73 65   not possible se
1d60: 74 74 6c 65 20 66 6f 72 20 61 6e 79 20 6f 74 68  ttle for any oth
1d70: 65 72 20 0a 20 20 20 20 2a 2a 20 75 6e 72 65 66  er .    ** unref
1d80: 65 72 65 6e 63 65 64 20 64 69 72 74 79 20 70 61  erenced dirty pa
1d90: 67 65 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 65  ge..    */.    e
1da0: 78 70 65 6e 73 69 76 65 5f 61 73 73 65 72 74 28  xpensive_assert(
1db0: 20 70 63 61 63 68 65 43 68 65 63 6b 53 79 6e 63   pcacheCheckSync
1dc0: 65 64 28 70 43 61 63 68 65 29 20 29 3b 0a 20 20  ed(pCache) );.  
1dd0: 20 20 66 6f 72 28 70 50 67 3d 70 43 61 63 68 65    for(pPg=pCache
1de0: 2d 3e 70 53 79 6e 63 65 64 3b 20 0a 20 20 20 20  ->pSynced; .    
1df0: 20 20 20 20 70 50 67 20 26 26 20 28 70 50 67 2d      pPg && (pPg-
1e00: 3e 6e 52 65 66 20 7c 7c 20 28 70 50 67 2d 3e 66  >nRef || (pPg->f
1e10: 6c 61 67 73 26 50 47 48 44 52 5f 4e 45 45 44 5f  lags&PGHDR_NEED_
1e20: 53 59 4e 43 29 29 3b 20 0a 20 20 20 20 20 20 20  SYNC)); .       
1e30: 20 70 50 67 3d 70 50 67 2d 3e 70 44 69 72 74 79   pPg=pPg->pDirty
1e40: 50 72 65 76 0a 20 20 20 20 29 3b 0a 20 20 20 20  Prev.    );.    
1e50: 70 43 61 63 68 65 2d 3e 70 53 79 6e 63 65 64 20  pCache->pSynced 
1e60: 3d 20 70 50 67 3b 0a 20 20 20 20 69 66 28 20 21  = pPg;.    if( !
1e70: 70 50 67 20 29 7b 0a 20 20 20 20 20 20 66 6f 72  pPg ){.      for
1e80: 28 70 50 67 3d 70 43 61 63 68 65 2d 3e 70 44 69  (pPg=pCache->pDi
1e90: 72 74 79 54 61 69 6c 3b 20 70 50 67 20 26 26 20  rtyTail; pPg && 
1ea0: 70 50 67 2d 3e 6e 52 65 66 3b 20 70 50 67 3d 70  pPg->nRef; pPg=p
1eb0: 50 67 2d 3e 70 44 69 72 74 79 50 72 65 76 29 3b  Pg->pDirtyPrev);
1ec0: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70  .    }.    if( p
1ed0: 50 67 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20  Pg ){.      int 
1ee0: 72 63 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 70  rc;.      rc = p
1ef0: 43 61 63 68 65 2d 3e 78 53 74 72 65 73 73 28 70  Cache->xStress(p
1f00: 43 61 63 68 65 2d 3e 70 53 74 72 65 73 73 2c 20  Cache->pStress, 
1f10: 70 50 67 29 3b 0a 20 20 20 20 20 20 69 66 28 20  pPg);.      if( 
1f20: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26  rc!=SQLITE_OK &&
1f30: 20 72 63 21 3d 53 51 4c 49 54 45 5f 42 55 53 59   rc!=SQLITE_BUSY
1f40: 20 29 7b 0a 20 20 20 20 20 20 20 20 72 65 74 75   ){.        retu
1f50: 72 6e 20 72 63 3b 0a 20 20 20 20 20 20 7d 0a 20  rn rc;.      }. 
1f60: 20 20 20 7d 0a 0a 20 20 20 20 70 50 61 67 65 20     }..    pPage 
1f70: 3d 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43  = sqlite3GlobalC
1f80: 6f 6e 66 69 67 2e 70 63 61 63 68 65 2e 78 46 65  onfig.pcache.xFe
1f90: 74 63 68 28 70 43 61 63 68 65 2d 3e 70 43 61 63  tch(pCache->pCac
1fa0: 68 65 2c 20 70 67 6e 6f 2c 20 32 29 3b 0a 20 20  he, pgno, 2);.  
1fb0: 7d 0a 0a 20 20 69 66 28 20 70 50 61 67 65 20 29  }..  if( pPage )
1fc0: 7b 0a 20 20 20 20 69 66 28 20 21 70 50 61 67 65  {.    if( !pPage
1fd0: 2d 3e 70 44 61 74 61 20 29 7b 0a 20 20 20 20 20  ->pData ){.     
1fe0: 20 6d 65 6d 73 65 74 28 70 50 61 67 65 2c 20 30   memset(pPage, 0
1ff0: 2c 20 73 69 7a 65 6f 66 28 50 67 48 64 72 29 20  , sizeof(PgHdr) 
2000: 2b 20 70 43 61 63 68 65 2d 3e 73 7a 45 78 74 72  + pCache->szExtr
2010: 61 29 3b 0a 20 20 20 20 20 20 70 50 61 67 65 2d  a);.      pPage-
2020: 3e 70 45 78 74 72 61 20 3d 20 28 76 6f 69 64 2a  >pExtra = (void*
2030: 29 26 70 50 61 67 65 5b 31 5d 3b 0a 20 20 20 20  )&pPage[1];.    
2040: 20 20 70 50 61 67 65 2d 3e 70 44 61 74 61 20 3d    pPage->pData =
2050: 20 28 76 6f 69 64 20 2a 29 26 28 28 63 68 61 72   (void *)&((char
2060: 20 2a 29 70 50 61 67 65 29 5b 73 69 7a 65 6f 66   *)pPage)[sizeof
2070: 28 50 67 48 64 72 29 20 2b 20 70 43 61 63 68 65  (PgHdr) + pCache
2080: 2d 3e 73 7a 45 78 74 72 61 5d 3b 0a 20 20 20 20  ->szExtra];.    
2090: 20 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65 20    pPage->pCache 
20a0: 3d 20 70 43 61 63 68 65 3b 0a 20 20 20 20 20 20  = pCache;.      
20b0: 70 50 61 67 65 2d 3e 70 67 6e 6f 20 3d 20 70 67  pPage->pgno = pg
20c0: 6e 6f 3b 0a 20 20 20 20 7d 0a 20 20 20 20 61 73  no;.    }.    as
20d0: 73 65 72 74 28 20 70 50 61 67 65 2d 3e 70 43 61  sert( pPage->pCa
20e0: 63 68 65 3d 3d 70 43 61 63 68 65 20 29 3b 0a 20  che==pCache );. 
20f0: 20 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65     assert( pPage
2100: 2d 3e 70 67 6e 6f 3d 3d 70 67 6e 6f 20 29 3b 0a  ->pgno==pgno );.
2110: 20 20 20 20 61 73 73 65 72 74 28 20 70 50 61 67      assert( pPag
2120: 65 2d 3e 70 45 78 74 72 61 3d 3d 28 76 6f 69 64  e->pExtra==(void
2130: 20 2a 29 26 70 50 61 67 65 5b 31 5d 20 29 3b 0a   *)&pPage[1] );.
2140: 0a 20 20 20 20 69 66 28 20 30 3d 3d 70 50 61 67  .    if( 0==pPag
2150: 65 2d 3e 6e 52 65 66 20 29 7b 0a 20 20 20 20 20  e->nRef ){.     
2160: 20 70 43 61 63 68 65 2d 3e 6e 52 65 66 2b 2b 3b   pCache->nRef++;
2170: 0a 20 20 20 20 7d 0a 20 20 20 20 70 50 61 67 65  .    }.    pPage
2180: 2d 3e 6e 52 65 66 2b 2b 3b 0a 20 20 20 20 69 66  ->nRef++;.    if
2190: 28 20 70 67 6e 6f 3d 3d 31 20 29 7b 0a 20 20 20  ( pgno==1 ){.   
21a0: 20 20 20 70 43 61 63 68 65 2d 3e 70 50 61 67 65     pCache->pPage
21b0: 31 20 3d 20 70 50 61 67 65 3b 0a 20 20 20 20 7d  1 = pPage;.    }
21c0: 0a 20 20 7d 0a 20 20 2a 70 70 50 61 67 65 20 3d  .  }.  *ppPage =
21d0: 20 70 50 61 67 65 3b 0a 20 20 72 65 74 75 72 6e   pPage;.  return
21e0: 20 28 70 50 61 67 65 3d 3d 30 20 26 26 20 65 43   (pPage==0 && eC
21f0: 72 65 61 74 65 29 20 3f 20 53 51 4c 49 54 45 5f  reate) ? SQLITE_
2200: 4e 4f 4d 45 4d 20 3a 20 53 51 4c 49 54 45 5f 4f  NOMEM : SQLITE_O
2210: 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65 63 72  K;.}../*.** Decr
2220: 65 6d 65 6e 74 20 74 68 65 20 72 65 66 65 72 65  ement the refere
2230: 6e 63 65 20 63 6f 75 6e 74 20 6f 6e 20 61 20 70  nce count on a p
2240: 61 67 65 2e 20 49 66 20 74 68 65 20 70 61 67 65  age. If the page
2250: 20 69 73 20 63 6c 65 61 6e 20 61 6e 64 20 74 68   is clean and th
2260: 65 0a 2a 2a 20 72 65 66 65 72 65 6e 63 65 20 63  e.** reference c
2270: 6f 75 6e 74 20 64 72 6f 70 73 20 74 6f 20 30 2c  ount drops to 0,
2280: 20 74 68 65 6e 20 69 74 20 69 73 20 6d 61 64 65   then it is made
2290: 20 65 6c 69 62 6c 65 20 66 6f 72 20 72 65 63 79   elible for recy
22a0: 63 6c 69 6e 67 2e 0a 2a 2f 0a 76 6f 69 64 20 73  cling..*/.void s
22b0: 71 6c 69 74 65 33 50 63 61 63 68 65 52 65 6c 65  qlite3PcacheRele
22c0: 61 73 65 28 50 67 48 64 72 20 2a 70 29 7b 0a 20  ase(PgHdr *p){. 
22d0: 20 61 73 73 65 72 74 28 20 70 2d 3e 6e 52 65 66   assert( p->nRef
22e0: 3e 30 20 29 3b 0a 20 20 70 2d 3e 6e 52 65 66 2d  >0 );.  p->nRef-
22f0: 2d 3b 0a 20 20 69 66 28 20 70 2d 3e 6e 52 65 66  -;.  if( p->nRef
2300: 3d 3d 30 20 29 7b 0a 20 20 20 20 50 43 61 63 68  ==0 ){.    PCach
2310: 65 20 2a 70 43 61 63 68 65 20 3d 20 70 2d 3e 70  e *pCache = p->p
2320: 43 61 63 68 65 3b 0a 20 20 20 20 70 43 61 63 68  Cache;.    pCach
2330: 65 2d 3e 6e 52 65 66 2d 2d 3b 0a 20 20 20 20 69  e->nRef--;.    i
2340: 66 28 20 28 70 2d 3e 66 6c 61 67 73 26 50 47 48  f( (p->flags&PGH
2350: 44 52 5f 44 49 52 54 59 29 3d 3d 30 20 29 7b 0a  DR_DIRTY)==0 ){.
2360: 20 20 20 20 20 20 70 63 61 63 68 65 55 6e 70 69        pcacheUnpi
2370: 6e 28 70 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  n(p);.    }else{
2380: 0a 20 20 20 20 20 20 2f 2a 20 4d 6f 76 65 20 74  .      /* Move t
2390: 68 65 20 70 61 67 65 20 74 6f 20 74 68 65 20 68  he page to the h
23a0: 65 61 64 20 6f 66 20 74 68 65 20 64 69 72 74 79  ead of the dirty
23b0: 20 6c 69 73 74 2e 20 2a 2f 0a 20 20 20 20 20 20   list. */.      
23c0: 70 63 61 63 68 65 52 65 6d 6f 76 65 46 72 6f 6d  pcacheRemoveFrom
23d0: 44 69 72 74 79 4c 69 73 74 28 70 29 3b 0a 20 20  DirtyList(p);.  
23e0: 20 20 20 20 70 63 61 63 68 65 41 64 64 54 6f 44      pcacheAddToD
23f0: 69 72 74 79 4c 69 73 74 28 70 29 3b 0a 20 20 20  irtyList(p);.   
2400: 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20   }.  }.}../*.** 
2410: 49 6e 63 72 65 61 73 65 20 74 68 65 20 72 65 66  Increase the ref
2420: 65 72 65 6e 63 65 20 63 6f 75 6e 74 20 6f 66 20  erence count of 
2430: 61 20 73 75 70 70 6c 69 65 64 20 70 61 67 65 20  a supplied page 
2440: 62 79 20 31 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71  by 1..*/.void sq
2450: 6c 69 74 65 33 50 63 61 63 68 65 52 65 66 28 50  lite3PcacheRef(P
2460: 67 48 64 72 20 2a 70 29 7b 0a 20 20 61 73 73 65  gHdr *p){.  asse
2470: 72 74 28 70 2d 3e 6e 52 65 66 3e 30 29 3b 0a 20  rt(p->nRef>0);. 
2480: 20 70 2d 3e 6e 52 65 66 2b 2b 3b 0a 7d 0a 0a 2f   p->nRef++;.}../
2490: 2a 0a 2a 2a 20 44 72 6f 70 20 61 20 70 61 67 65  *.** Drop a page
24a0: 20 66 72 6f 6d 20 74 68 65 20 63 61 63 68 65 2e   from the cache.
24b0: 20 54 68 65 72 65 20 6d 75 73 74 20 62 65 20 65   There must be e
24c0: 78 61 63 74 6c 79 20 6f 6e 65 20 72 65 66 65 72  xactly one refer
24d0: 65 6e 63 65 20 74 6f 20 74 68 65 0a 2a 2a 20 70  ence to the.** p
24e0: 61 67 65 2e 20 54 68 69 73 20 66 75 6e 63 74 69  age. This functi
24f0: 6f 6e 20 64 65 6c 65 74 65 73 20 74 68 61 74 20  on deletes that 
2500: 72 65 66 65 72 65 6e 63 65 2c 20 73 6f 20 61 66  reference, so af
2510: 74 65 72 20 69 74 20 72 65 74 75 72 6e 73 20 74  ter it returns t
2520: 68 65 0a 2a 2a 20 70 61 67 65 20 70 6f 69 6e 74  he.** page point
2530: 65 64 20 74 6f 20 62 79 20 70 20 69 73 20 69 6e  ed to by p is in
2540: 76 61 6c 69 64 2e 0a 2a 2f 0a 76 6f 69 64 20 73  valid..*/.void s
2550: 71 6c 69 74 65 33 50 63 61 63 68 65 44 72 6f 70  qlite3PcacheDrop
2560: 28 50 67 48 64 72 20 2a 70 29 7b 0a 20 20 50 43  (PgHdr *p){.  PC
2570: 61 63 68 65 20 2a 70 43 61 63 68 65 3b 0a 20 20  ache *pCache;.  
2580: 61 73 73 65 72 74 28 20 70 2d 3e 6e 52 65 66 3d  assert( p->nRef=
2590: 3d 31 20 29 3b 0a 20 20 69 66 28 20 70 2d 3e 66  =1 );.  if( p->f
25a0: 6c 61 67 73 26 50 47 48 44 52 5f 44 49 52 54 59  lags&PGHDR_DIRTY
25b0: 20 29 7b 0a 20 20 20 20 70 63 61 63 68 65 52 65   ){.    pcacheRe
25c0: 6d 6f 76 65 46 72 6f 6d 44 69 72 74 79 4c 69 73  moveFromDirtyLis
25d0: 74 28 70 29 3b 0a 20 20 7d 0a 20 20 70 43 61 63  t(p);.  }.  pCac
25e0: 68 65 20 3d 20 70 2d 3e 70 43 61 63 68 65 3b 0a  he = p->pCache;.
25f0: 20 20 70 43 61 63 68 65 2d 3e 6e 52 65 66 2d 2d    pCache->nRef--
2600: 3b 0a 20 20 69 66 28 20 70 2d 3e 70 67 6e 6f 3d  ;.  if( p->pgno=
2610: 3d 31 20 29 7b 0a 20 20 20 20 70 43 61 63 68 65  =1 ){.    pCache
2620: 2d 3e 70 50 61 67 65 31 20 3d 20 30 3b 0a 20 20  ->pPage1 = 0;.  
2630: 7d 0a 20 20 73 71 6c 69 74 65 33 47 6c 6f 62 61  }.  sqlite3Globa
2640: 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65 2e 78  lConfig.pcache.x
2650: 55 6e 70 69 6e 28 70 43 61 63 68 65 2d 3e 70 43  Unpin(pCache->pC
2660: 61 63 68 65 2c 20 70 2c 20 31 29 3b 0a 7d 0a 0a  ache, p, 1);.}..
2670: 2f 2a 0a 2a 2a 20 4d 61 6b 65 20 73 75 72 65 20  /*.** Make sure 
2680: 74 68 65 20 70 61 67 65 20 69 73 20 6d 61 72 6b  the page is mark
2690: 65 64 20 61 73 20 64 69 72 74 79 2e 20 49 66 20  ed as dirty. If 
26a0: 69 74 20 69 73 6e 27 74 20 64 69 72 74 79 20 61  it isn't dirty a
26b0: 6c 72 65 61 64 79 2c 0a 2a 2a 20 6d 61 6b 65 20  lready,.** make 
26c0: 69 74 20 73 6f 2e 0a 2a 2f 0a 76 6f 69 64 20 73  it so..*/.void s
26d0: 71 6c 69 74 65 33 50 63 61 63 68 65 4d 61 6b 65  qlite3PcacheMake
26e0: 44 69 72 74 79 28 50 67 48 64 72 20 2a 70 29 7b  Dirty(PgHdr *p){
26f0: 0a 20 20 70 2d 3e 66 6c 61 67 73 20 26 3d 20 7e  .  p->flags &= ~
2700: 50 47 48 44 52 5f 44 4f 4e 54 5f 57 52 49 54 45  PGHDR_DONT_WRITE
2710: 3b 0a 20 20 61 73 73 65 72 74 28 20 70 2d 3e 6e  ;.  assert( p->n
2720: 52 65 66 3e 30 20 29 3b 0a 20 20 69 66 28 20 30  Ref>0 );.  if( 0
2730: 3d 3d 28 70 2d 3e 66 6c 61 67 73 20 26 20 50 47  ==(p->flags & PG
2740: 48 44 52 5f 44 49 52 54 59 29 20 29 7b 0a 20 20  HDR_DIRTY) ){.  
2750: 20 20 70 2d 3e 66 6c 61 67 73 20 7c 3d 20 50 47    p->flags |= PG
2760: 48 44 52 5f 44 49 52 54 59 3b 0a 20 20 20 20 70  HDR_DIRTY;.    p
2770: 63 61 63 68 65 41 64 64 54 6f 44 69 72 74 79 4c  cacheAddToDirtyL
2780: 69 73 74 28 20 70 29 3b 0a 20 20 7d 0a 7d 0a 0a  ist( p);.  }.}..
2790: 2f 2a 0a 2a 2a 20 4d 61 6b 65 20 73 75 72 65 20  /*.** Make sure 
27a0: 74 68 65 20 70 61 67 65 20 69 73 20 6d 61 72 6b  the page is mark
27b0: 65 64 20 61 73 20 63 6c 65 61 6e 2e 20 49 66 20  ed as clean. If 
27c0: 69 74 20 69 73 6e 27 74 20 63 6c 65 61 6e 20 61  it isn't clean a
27d0: 6c 72 65 61 64 79 2c 0a 2a 2a 20 6d 61 6b 65 20  lready,.** make 
27e0: 69 74 20 73 6f 2e 0a 2a 2f 0a 76 6f 69 64 20 73  it so..*/.void s
27f0: 71 6c 69 74 65 33 50 63 61 63 68 65 4d 61 6b 65  qlite3PcacheMake
2800: 43 6c 65 61 6e 28 50 67 48 64 72 20 2a 70 29 7b  Clean(PgHdr *p){
2810: 0a 20 20 69 66 28 20 28 70 2d 3e 66 6c 61 67 73  .  if( (p->flags
2820: 20 26 20 50 47 48 44 52 5f 44 49 52 54 59 29 20   & PGHDR_DIRTY) 
2830: 29 7b 0a 20 20 20 20 70 63 61 63 68 65 52 65 6d  ){.    pcacheRem
2840: 6f 76 65 46 72 6f 6d 44 69 72 74 79 4c 69 73 74  oveFromDirtyList
2850: 28 70 29 3b 0a 20 20 20 20 70 2d 3e 66 6c 61 67  (p);.    p->flag
2860: 73 20 26 3d 20 7e 28 50 47 48 44 52 5f 44 49 52  s &= ~(PGHDR_DIR
2870: 54 59 7c 50 47 48 44 52 5f 4e 45 45 44 5f 53 59  TY|PGHDR_NEED_SY
2880: 4e 43 29 3b 0a 20 20 20 20 69 66 28 20 70 2d 3e  NC);.    if( p->
2890: 6e 52 65 66 3d 3d 30 20 29 7b 0a 20 20 20 20 20  nRef==0 ){.     
28a0: 20 70 63 61 63 68 65 55 6e 70 69 6e 28 70 29 3b   pcacheUnpin(p);
28b0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a  .    }.  }.}../*
28c0: 0a 2a 2a 20 4d 61 6b 65 20 65 76 65 72 79 20 70  .** Make every p
28d0: 61 67 65 20 69 6e 20 74 68 65 20 63 61 63 68 65  age in the cache
28e0: 20 63 6c 65 61 6e 2e 0a 2a 2f 0a 76 6f 69 64 20   clean..*/.void 
28f0: 73 71 6c 69 74 65 33 50 63 61 63 68 65 43 6c 65  sqlite3PcacheCle
2900: 61 6e 41 6c 6c 28 50 43 61 63 68 65 20 2a 70 43  anAll(PCache *pC
2910: 61 63 68 65 29 7b 0a 20 20 50 67 48 64 72 20 2a  ache){.  PgHdr *
2920: 70 3b 0a 20 20 77 68 69 6c 65 28 20 28 70 20 3d  p;.  while( (p =
2930: 20 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 29   pCache->pDirty)
2940: 21 3d 30 20 29 7b 0a 20 20 20 20 73 71 6c 69 74  !=0 ){.    sqlit
2950: 65 33 50 63 61 63 68 65 4d 61 6b 65 43 6c 65 61  e3PcacheMakeClea
2960: 6e 28 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a  n(p);.  }.}../*.
2970: 2a 2a 20 43 6c 65 61 72 20 74 68 65 20 50 47 48  ** Clear the PGH
2980: 44 52 5f 4e 45 45 44 5f 53 59 4e 43 20 66 6c 61  DR_NEED_SYNC fla
2990: 67 20 66 72 6f 6d 20 61 6c 6c 20 64 69 72 74 79  g from all dirty
29a0: 20 70 61 67 65 73 2e 0a 2a 2f 0a 76 6f 69 64 20   pages..*/.void 
29b0: 73 71 6c 69 74 65 33 50 63 61 63 68 65 43 6c 65  sqlite3PcacheCle
29c0: 61 72 53 79 6e 63 46 6c 61 67 73 28 50 43 61 63  arSyncFlags(PCac
29d0: 68 65 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 50  he *pCache){.  P
29e0: 67 48 64 72 20 2a 70 3b 0a 20 20 66 6f 72 28 70  gHdr *p;.  for(p
29f0: 3d 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 3b  =pCache->pDirty;
2a00: 20 70 3b 20 70 3d 70 2d 3e 70 44 69 72 74 79 4e   p; p=p->pDirtyN
2a10: 65 78 74 29 7b 0a 20 20 20 20 70 2d 3e 66 6c 61  ext){.    p->fla
2a20: 67 73 20 26 3d 20 7e 50 47 48 44 52 5f 4e 45 45  gs &= ~PGHDR_NEE
2a30: 44 5f 53 59 4e 43 3b 0a 20 20 7d 0a 20 20 70 43  D_SYNC;.  }.  pC
2a40: 61 63 68 65 2d 3e 70 53 79 6e 63 65 64 20 3d 20  ache->pSynced = 
2a50: 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 54 61  pCache->pDirtyTa
2a60: 69 6c 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 68 61  il;.}../*.** Cha
2a70: 6e 67 65 20 74 68 65 20 70 61 67 65 20 6e 75 6d  nge the page num
2a80: 62 65 72 20 6f 66 20 70 61 67 65 20 70 20 74 6f  ber of page p to
2a90: 20 6e 65 77 50 67 6e 6f 2e 20 0a 2a 2f 0a 76 6f   newPgno. .*/.vo
2aa0: 69 64 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  id sqlite3Pcache
2ab0: 4d 6f 76 65 28 50 67 48 64 72 20 2a 70 2c 20 50  Move(PgHdr *p, P
2ac0: 67 6e 6f 20 6e 65 77 50 67 6e 6f 29 7b 0a 20 20  gno newPgno){.  
2ad0: 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 20 3d  PCache *pCache =
2ae0: 20 70 2d 3e 70 43 61 63 68 65 3b 0a 20 20 61 73   p->pCache;.  as
2af0: 73 65 72 74 28 20 70 2d 3e 6e 52 65 66 3e 30 20  sert( p->nRef>0 
2b00: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 6e 65 77  );.  assert( new
2b10: 50 67 6e 6f 3e 30 20 29 3b 0a 20 20 73 71 6c 69  Pgno>0 );.  sqli
2b20: 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e  te3GlobalConfig.
2b30: 70 63 61 63 68 65 2e 78 52 65 6b 65 79 28 70 43  pcache.xRekey(pC
2b40: 61 63 68 65 2d 3e 70 43 61 63 68 65 2c 20 70 2c  ache->pCache, p,
2b50: 20 70 2d 3e 70 67 6e 6f 2c 20 6e 65 77 50 67 6e   p->pgno, newPgn
2b60: 6f 29 3b 0a 20 20 70 2d 3e 70 67 6e 6f 20 3d 20  o);.  p->pgno = 
2b70: 6e 65 77 50 67 6e 6f 3b 0a 20 20 69 66 28 20 28  newPgno;.  if( (
2b80: 70 2d 3e 66 6c 61 67 73 26 50 47 48 44 52 5f 44  p->flags&PGHDR_D
2b90: 49 52 54 59 29 20 26 26 20 28 70 2d 3e 66 6c 61  IRTY) && (p->fla
2ba0: 67 73 26 50 47 48 44 52 5f 4e 45 45 44 5f 53 59  gs&PGHDR_NEED_SY
2bb0: 4e 43 29 20 29 7b 0a 20 20 20 20 70 63 61 63 68  NC) ){.    pcach
2bc0: 65 52 65 6d 6f 76 65 46 72 6f 6d 44 69 72 74 79  eRemoveFromDirty
2bd0: 4c 69 73 74 28 70 29 3b 0a 20 20 20 20 70 63 61  List(p);.    pca
2be0: 63 68 65 41 64 64 54 6f 44 69 72 74 79 4c 69 73  cheAddToDirtyLis
2bf0: 74 28 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a  t(p);.  }.}../*.
2c00: 2a 2a 20 44 72 6f 70 20 65 76 65 72 79 20 63 61  ** Drop every ca
2c10: 63 68 65 20 65 6e 74 72 79 20 77 68 6f 73 65 20  che entry whose 
2c20: 70 61 67 65 20 6e 75 6d 62 65 72 20 69 73 20 67  page number is g
2c30: 72 65 61 74 65 72 20 74 68 61 6e 20 22 70 67 6e  reater than "pgn
2c40: 6f 22 2e 20 54 68 65 0a 2a 2a 20 63 61 6c 6c 65  o". The.** calle
2c50: 72 20 6d 75 73 74 20 65 6e 73 75 72 65 20 74 68  r must ensure th
2c60: 61 74 20 74 68 65 72 65 20 61 72 65 20 6e 6f 20  at there are no 
2c70: 6f 75 74 73 74 61 6e 64 69 6e 67 20 72 65 66 65  outstanding refe
2c80: 72 65 6e 63 65 73 20 74 6f 20 61 6e 79 20 70 61  rences to any pa
2c90: 67 65 73 0a 2a 2a 20 6f 74 68 65 72 20 74 68 61  ges.** other tha
2ca0: 6e 20 70 61 67 65 20 31 20 77 69 74 68 20 61 20  n page 1 with a 
2cb0: 70 61 67 65 20 6e 75 6d 62 65 72 20 67 72 65 61  page number grea
2cc0: 74 65 72 20 74 68 61 6e 20 70 67 6e 6f 2e 0a 2a  ter than pgno..*
2cd0: 2a 0a 2a 2a 20 49 66 20 74 68 65 72 65 20 69 73  *.** If there is
2ce0: 20 61 20 72 65 66 65 72 65 6e 63 65 20 74 6f 20   a reference to 
2cf0: 70 61 67 65 20 31 20 61 6e 64 20 74 68 65 20 70  page 1 and the p
2d00: 67 6e 6f 20 70 61 72 61 6d 65 74 65 72 20 70 61  gno parameter pa
2d10: 73 73 65 64 20 74 6f 20 74 68 69 73 0a 2a 2a 20  ssed to this.** 
2d20: 66 75 6e 63 74 69 6f 6e 20 69 73 20 30 2c 20 74  function is 0, t
2d30: 68 65 6e 20 74 68 65 20 64 61 74 61 20 61 72 65  hen the data are
2d40: 61 20 61 73 73 6f 63 69 61 74 65 64 20 77 69 74  a associated wit
2d50: 68 20 70 61 67 65 20 31 20 69 73 20 7a 65 72 6f  h page 1 is zero
2d60: 65 64 2c 20 62 75 74 0a 2a 2a 20 74 68 65 20 70  ed, but.** the p
2d70: 61 67 65 20 6f 62 6a 65 63 74 20 69 73 20 6e 6f  age object is no
2d80: 74 20 64 72 6f 70 70 65 64 2e 0a 2a 2f 0a 76 6f  t dropped..*/.vo
2d90: 69 64 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  id sqlite3Pcache
2da0: 54 72 75 6e 63 61 74 65 28 50 43 61 63 68 65 20  Truncate(PCache 
2db0: 2a 70 43 61 63 68 65 2c 20 50 67 6e 6f 20 70 67  *pCache, Pgno pg
2dc0: 6e 6f 29 7b 0a 20 20 69 66 28 20 70 43 61 63 68  no){.  if( pCach
2dd0: 65 2d 3e 70 43 61 63 68 65 20 29 7b 0a 20 20 20  e->pCache ){.   
2de0: 20 50 67 48 64 72 20 2a 70 3b 0a 20 20 20 20 50   PgHdr *p;.    P
2df0: 67 48 64 72 20 2a 70 4e 65 78 74 3b 0a 20 20 20  gHdr *pNext;.   
2e00: 20 66 6f 72 28 70 3d 70 43 61 63 68 65 2d 3e 70   for(p=pCache->p
2e10: 44 69 72 74 79 3b 20 70 3b 20 70 3d 70 4e 65 78  Dirty; p; p=pNex
2e20: 74 29 7b 0a 20 20 20 20 20 20 70 4e 65 78 74 20  t){.      pNext 
2e30: 3d 20 70 2d 3e 70 44 69 72 74 79 4e 65 78 74 3b  = p->pDirtyNext;
2e40: 0a 20 20 20 20 20 20 2f 2a 20 54 68 69 73 20 72  .      /* This r
2e50: 6f 75 74 69 6e 65 20 6e 65 76 65 72 20 67 65 74  outine never get
2e60: 73 20 63 61 6c 6c 20 77 69 74 68 20 61 20 70 6f  s call with a po
2e70: 73 69 74 69 76 65 20 70 67 6e 6f 20 65 78 63 65  sitive pgno exce
2e80: 70 74 20 72 69 67 68 74 0a 20 20 20 20 20 20 2a  pt right.      *
2e90: 2a 20 61 66 74 65 72 20 73 71 6c 69 74 65 33 50  * after sqlite3P
2ea0: 63 61 63 68 65 43 6c 65 61 6e 41 6c 6c 28 29 2e  cacheCleanAll().
2eb0: 20 20 53 6f 20 69 66 20 74 68 65 72 65 20 61 72    So if there ar
2ec0: 65 20 64 69 72 74 79 20 70 61 67 65 73 2c 0a 20  e dirty pages,. 
2ed0: 20 20 20 20 20 2a 2a 20 69 74 20 6d 75 73 74 20       ** it must 
2ee0: 62 65 20 74 68 61 74 20 70 67 6e 6f 3d 3d 30 2e  be that pgno==0.
2ef0: 0a 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 20  .      */.      
2f00: 61 73 73 65 72 74 28 20 70 2d 3e 70 67 6e 6f 3e  assert( p->pgno>
2f10: 30 20 29 3b 0a 20 20 20 20 20 20 69 66 28 20 41  0 );.      if( A
2f20: 4c 57 41 59 53 28 70 2d 3e 70 67 6e 6f 3e 70 67  LWAYS(p->pgno>pg
2f30: 6e 6f 29 20 29 7b 0a 20 20 20 20 20 20 20 20 61  no) ){.        a
2f40: 73 73 65 72 74 28 20 70 2d 3e 66 6c 61 67 73 26  ssert( p->flags&
2f50: 50 47 48 44 52 5f 44 49 52 54 59 20 29 3b 0a 20  PGHDR_DIRTY );. 
2f60: 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 50 63         sqlite3Pc
2f70: 61 63 68 65 4d 61 6b 65 43 6c 65 61 6e 28 70 29  acheMakeClean(p)
2f80: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
2f90: 20 20 20 20 69 66 28 20 70 67 6e 6f 3d 3d 30 20      if( pgno==0 
2fa0: 26 26 20 70 43 61 63 68 65 2d 3e 70 50 61 67 65  && pCache->pPage
2fb0: 31 20 29 7b 0a 20 20 20 20 20 20 6d 65 6d 73 65  1 ){.      memse
2fc0: 74 28 70 43 61 63 68 65 2d 3e 70 50 61 67 65 31  t(pCache->pPage1
2fd0: 2d 3e 70 44 61 74 61 2c 20 30 2c 20 70 43 61 63  ->pData, 0, pCac
2fe0: 68 65 2d 3e 73 7a 50 61 67 65 29 3b 0a 20 20 20  he->szPage);.   
2ff0: 20 20 20 70 67 6e 6f 20 3d 20 31 3b 0a 20 20 20     pgno = 1;.   
3000: 20 7d 0a 20 20 20 20 73 71 6c 69 74 65 33 47 6c   }.    sqlite3Gl
3010: 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68  obalConfig.pcach
3020: 65 2e 78 54 72 75 6e 63 61 74 65 28 70 43 61 63  e.xTruncate(pCac
3030: 68 65 2d 3e 70 43 61 63 68 65 2c 20 70 67 6e 6f  he->pCache, pgno
3040: 2b 31 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a  +1);.  }.}../*.*
3050: 2a 20 43 6c 6f 73 65 20 61 20 63 61 63 68 65 2e  * Close a cache.
3060: 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33  .*/.void sqlite3
3070: 50 63 61 63 68 65 43 6c 6f 73 65 28 50 43 61 63  PcacheClose(PCac
3080: 68 65 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 69  he *pCache){.  i
3090: 66 28 20 70 43 61 63 68 65 2d 3e 70 43 61 63 68  f( pCache->pCach
30a0: 65 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33  e ){.    sqlite3
30b0: 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61  GlobalConfig.pca
30c0: 63 68 65 2e 78 44 65 73 74 72 6f 79 28 70 43 61  che.xDestroy(pCa
30d0: 63 68 65 2d 3e 70 43 61 63 68 65 29 3b 0a 20 20  che->pCache);.  
30e0: 7d 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 44 69 73 63  }.}../* .** Disc
30f0: 61 72 64 20 74 68 65 20 63 6f 6e 74 65 6e 74 73  ard the contents
3100: 20 6f 66 20 74 68 65 20 63 61 63 68 65 2e 0a 2a   of the cache..*
3110: 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63  /.void sqlite3Pc
3120: 61 63 68 65 43 6c 65 61 72 28 50 43 61 63 68 65  acheClear(PCache
3130: 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 73 71 6c   *pCache){.  sql
3140: 69 74 65 33 50 63 61 63 68 65 54 72 75 6e 63 61  ite3PcacheTrunca
3150: 74 65 28 70 43 61 63 68 65 2c 20 30 29 3b 0a 7d  te(pCache, 0);.}
3160: 0a 0a 2f 2a 0a 2a 2a 20 4d 65 72 67 65 20 74 77  ../*.** Merge tw
3170: 6f 20 6c 69 73 74 73 20 6f 66 20 70 61 67 65 73  o lists of pages
3180: 20 63 6f 6e 6e 65 63 74 65 64 20 62 79 20 70 44   connected by pD
3190: 69 72 74 79 20 61 6e 64 20 69 6e 20 70 67 6e 6f  irty and in pgno
31a0: 20 6f 72 64 65 72 2e 0a 2a 2a 20 44 6f 20 6e 6f   order..** Do no
31b0: 74 20 62 6f 74 68 20 66 69 78 69 6e 67 20 74 68  t both fixing th
31c0: 65 20 70 44 69 72 74 79 50 72 65 76 20 70 6f 69  e pDirtyPrev poi
31d0: 6e 74 65 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  nters..*/.static
31e0: 20 50 67 48 64 72 20 2a 70 63 61 63 68 65 4d 65   PgHdr *pcacheMe
31f0: 72 67 65 44 69 72 74 79 4c 69 73 74 28 50 67 48  rgeDirtyList(PgH
3200: 64 72 20 2a 70 41 2c 20 50 67 48 64 72 20 2a 70  dr *pA, PgHdr *p
3210: 42 29 7b 0a 20 20 50 67 48 64 72 20 72 65 73 75  B){.  PgHdr resu
3220: 6c 74 2c 20 2a 70 54 61 69 6c 3b 0a 20 20 70 54  lt, *pTail;.  pT
3230: 61 69 6c 20 3d 20 26 72 65 73 75 6c 74 3b 0a 20  ail = &result;. 
3240: 20 77 68 69 6c 65 28 20 70 41 20 26 26 20 70 42   while( pA && pB
3250: 20 29 7b 0a 20 20 20 20 69 66 28 20 70 41 2d 3e   ){.    if( pA->
3260: 70 67 6e 6f 3c 70 42 2d 3e 70 67 6e 6f 20 29 7b  pgno<pB->pgno ){
3270: 0a 20 20 20 20 20 20 70 54 61 69 6c 2d 3e 70 44  .      pTail->pD
3280: 69 72 74 79 20 3d 20 70 41 3b 0a 20 20 20 20 20  irty = pA;.     
3290: 20 70 54 61 69 6c 20 3d 20 70 41 3b 0a 20 20 20   pTail = pA;.   
32a0: 20 20 20 70 41 20 3d 20 70 41 2d 3e 70 44 69 72     pA = pA->pDir
32b0: 74 79 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  ty;.    }else{. 
32c0: 20 20 20 20 20 70 54 61 69 6c 2d 3e 70 44 69 72       pTail->pDir
32d0: 74 79 20 3d 20 70 42 3b 0a 20 20 20 20 20 20 70  ty = pB;.      p
32e0: 54 61 69 6c 20 3d 20 70 42 3b 0a 20 20 20 20 20  Tail = pB;.     
32f0: 20 70 42 20 3d 20 70 42 2d 3e 70 44 69 72 74 79   pB = pB->pDirty
3300: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66  ;.    }.  }.  if
3310: 28 20 70 41 20 29 7b 0a 20 20 20 20 70 54 61 69  ( pA ){.    pTai
3320: 6c 2d 3e 70 44 69 72 74 79 20 3d 20 70 41 3b 0a  l->pDirty = pA;.
3330: 20 20 7d 65 6c 73 65 20 69 66 28 20 70 42 20 29    }else if( pB )
3340: 7b 0a 20 20 20 20 70 54 61 69 6c 2d 3e 70 44 69  {.    pTail->pDi
3350: 72 74 79 20 3d 20 70 42 3b 0a 20 20 7d 65 6c 73  rty = pB;.  }els
3360: 65 7b 0a 20 20 20 20 70 54 61 69 6c 2d 3e 70 44  e{.    pTail->pD
3370: 69 72 74 79 20 3d 20 30 3b 0a 20 20 7d 0a 20 20  irty = 0;.  }.  
3380: 72 65 74 75 72 6e 20 72 65 73 75 6c 74 2e 70 44  return result.pD
3390: 69 72 74 79 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53  irty;.}../*.** S
33a0: 6f 72 74 20 74 68 65 20 6c 69 73 74 20 6f 66 20  ort the list of 
33b0: 70 61 67 65 73 20 69 6e 20 61 63 63 65 6e 64 69  pages in accendi
33c0: 6e 67 20 6f 72 64 65 72 20 62 79 20 70 67 6e 6f  ng order by pgno
33d0: 2e 20 20 50 61 67 65 73 20 61 72 65 0a 2a 2a 20  .  Pages are.** 
33e0: 63 6f 6e 6e 65 63 74 65 64 20 62 79 20 70 44 69  connected by pDi
33f0: 72 74 79 20 70 6f 69 6e 74 65 72 73 2e 20 20 54  rty pointers.  T
3400: 68 65 20 70 44 69 72 74 79 50 72 65 76 20 70 6f  he pDirtyPrev po
3410: 69 6e 74 65 72 73 20 61 72 65 0a 2a 2a 20 63 6f  inters are.** co
3420: 72 72 75 70 74 65 64 20 62 79 20 74 68 69 73 20  rrupted by this 
3430: 73 6f 72 74 2e 0a 2a 2a 0a 2a 2a 20 53 69 6e 63  sort..**.** Sinc
3440: 65 20 74 68 65 72 65 20 63 61 6e 6e 6f 74 20 62  e there cannot b
3450: 65 20 6d 6f 72 65 20 74 68 61 6e 20 32 5e 33 31  e more than 2^31
3460: 20 64 69 73 74 69 6e 63 74 20 70 61 67 65 73 20   distinct pages 
3470: 69 6e 20 61 20 64 61 74 61 62 61 73 65 2c 0a 2a  in a database,.*
3480: 2a 20 74 68 65 72 65 20 63 61 6e 6e 6f 74 20 62  * there cannot b
3490: 65 20 6d 6f 72 65 20 74 68 61 6e 20 33 31 20 62  e more than 31 b
34a0: 75 63 6b 65 74 73 20 72 65 71 75 69 72 65 64 20  uckets required 
34b0: 62 79 20 74 68 65 20 6d 65 72 67 65 20 73 6f 72  by the merge sor
34c0: 74 65 72 2e 0a 2a 2a 20 4f 6e 65 20 65 78 74 72  ter..** One extr
34d0: 61 20 62 75 63 6b 65 74 20 69 73 20 61 64 64 65  a bucket is adde
34e0: 64 20 74 6f 20 63 61 74 63 68 20 6f 76 65 72 66  d to catch overf
34f0: 6c 6f 77 20 69 6e 20 63 61 73 65 20 73 6f 6d 65  low in case some
3500: 74 68 69 6e 67 0a 2a 2a 20 65 76 65 72 20 63 68  thing.** ever ch
3510: 61 6e 67 65 73 20 74 6f 20 6d 61 6b 65 20 74 68  anges to make th
3520: 65 20 70 72 65 76 69 6f 75 73 20 73 65 6e 74 65  e previous sente
3530: 6e 63 65 20 69 6e 63 6f 72 72 65 63 74 2e 0a 2a  nce incorrect..*
3540: 2f 0a 23 64 65 66 69 6e 65 20 4e 5f 53 4f 52 54  /.#define N_SORT
3550: 5f 42 55 43 4b 45 54 20 20 33 32 0a 73 74 61 74  _BUCKET  32.stat
3560: 69 63 20 50 67 48 64 72 20 2a 70 63 61 63 68 65  ic PgHdr *pcache
3570: 53 6f 72 74 44 69 72 74 79 4c 69 73 74 28 50 67  SortDirtyList(Pg
3580: 48 64 72 20 2a 70 49 6e 29 7b 0a 20 20 50 67 48  Hdr *pIn){.  PgH
3590: 64 72 20 2a 61 5b 4e 5f 53 4f 52 54 5f 42 55 43  dr *a[N_SORT_BUC
35a0: 4b 45 54 5d 2c 20 2a 70 3b 0a 20 20 69 6e 74 20  KET], *p;.  int 
35b0: 69 3b 0a 20 20 6d 65 6d 73 65 74 28 61 2c 20 30  i;.  memset(a, 0
35c0: 2c 20 73 69 7a 65 6f 66 28 61 29 29 3b 0a 20 20  , sizeof(a));.  
35d0: 77 68 69 6c 65 28 20 70 49 6e 20 29 7b 0a 20 20  while( pIn ){.  
35e0: 20 20 70 20 3d 20 70 49 6e 3b 0a 20 20 20 20 70    p = pIn;.    p
35f0: 49 6e 20 3d 20 70 2d 3e 70 44 69 72 74 79 3b 0a  In = p->pDirty;.
3600: 20 20 20 20 70 2d 3e 70 44 69 72 74 79 20 3d 20      p->pDirty = 
3610: 30 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20  0;.    for(i=0; 
3620: 41 4c 57 41 59 53 28 69 3c 4e 5f 53 4f 52 54 5f  ALWAYS(i<N_SORT_
3630: 42 55 43 4b 45 54 2d 31 29 3b 20 69 2b 2b 29 7b  BUCKET-1); i++){
3640: 0a 20 20 20 20 20 20 69 66 28 20 61 5b 69 5d 3d  .      if( a[i]=
3650: 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 61 5b  =0 ){.        a[
3660: 69 5d 20 3d 20 70 3b 0a 20 20 20 20 20 20 20 20  i] = p;.        
3670: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 65 6c  break;.      }el
3680: 73 65 7b 0a 20 20 20 20 20 20 20 20 70 20 3d 20  se{.        p = 
3690: 70 63 61 63 68 65 4d 65 72 67 65 44 69 72 74 79  pcacheMergeDirty
36a0: 4c 69 73 74 28 61 5b 69 5d 2c 20 70 29 3b 0a 20  List(a[i], p);. 
36b0: 20 20 20 20 20 20 20 61 5b 69 5d 20 3d 20 30 3b         a[i] = 0;
36c0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
36d0: 20 20 20 69 66 28 20 4e 45 56 45 52 28 69 3d 3d     if( NEVER(i==
36e0: 4e 5f 53 4f 52 54 5f 42 55 43 4b 45 54 2d 31 29  N_SORT_BUCKET-1)
36f0: 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 54 6f 20   ){.      /* To 
3700: 67 65 74 20 68 65 72 65 2c 20 74 68 65 72 65 20  get here, there 
3710: 6e 65 65 64 20 74 6f 20 62 65 20 32 5e 28 4e 5f  need to be 2^(N_
3720: 53 4f 52 54 5f 42 55 43 4b 45 54 29 20 65 6c 65  SORT_BUCKET) ele
3730: 6d 65 6e 74 73 20 69 6e 0a 20 20 20 20 20 20 2a  ments in.      *
3740: 2a 20 74 68 65 20 69 6e 70 75 74 20 6c 69 73 74  * the input list
3750: 2e 20 20 42 75 74 20 74 68 61 74 20 69 73 20 69  .  But that is i
3760: 6d 70 6f 73 73 69 62 6c 65 2e 0a 20 20 20 20 20  mpossible..     
3770: 20 2a 2f 0a 20 20 20 20 20 20 61 5b 69 5d 20 3d   */.      a[i] =
3780: 20 70 63 61 63 68 65 4d 65 72 67 65 44 69 72 74   pcacheMergeDirt
3790: 79 4c 69 73 74 28 61 5b 69 5d 2c 20 70 29 3b 0a  yList(a[i], p);.
37a0: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 70 20 3d 20      }.  }.  p = 
37b0: 61 5b 30 5d 3b 0a 20 20 66 6f 72 28 69 3d 31 3b  a[0];.  for(i=1;
37c0: 20 69 3c 4e 5f 53 4f 52 54 5f 42 55 43 4b 45 54   i<N_SORT_BUCKET
37d0: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 70 20 3d 20  ; i++){.    p = 
37e0: 70 63 61 63 68 65 4d 65 72 67 65 44 69 72 74 79  pcacheMergeDirty
37f0: 4c 69 73 74 28 70 2c 20 61 5b 69 5d 29 3b 0a 20  List(p, a[i]);. 
3800: 20 7d 0a 20 20 72 65 74 75 72 6e 20 70 3b 0a 7d   }.  return p;.}
3810: 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61  ../*.** Return a
3820: 20 6c 69 73 74 20 6f 66 20 61 6c 6c 20 64 69 72   list of all dir
3830: 74 79 20 70 61 67 65 73 20 69 6e 20 74 68 65 20  ty pages in the 
3840: 63 61 63 68 65 2c 20 73 6f 72 74 65 64 20 62 79  cache, sorted by
3850: 20 70 61 67 65 20 6e 75 6d 62 65 72 2e 0a 2a 2f   page number..*/
3860: 0a 50 67 48 64 72 20 2a 73 71 6c 69 74 65 33 50  .PgHdr *sqlite3P
3870: 63 61 63 68 65 44 69 72 74 79 4c 69 73 74 28 50  cacheDirtyList(P
3880: 43 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b 0a  Cache *pCache){.
3890: 20 20 50 67 48 64 72 20 2a 70 3b 0a 20 20 66 6f    PgHdr *p;.  fo
38a0: 72 28 70 3d 70 43 61 63 68 65 2d 3e 70 44 69 72  r(p=pCache->pDir
38b0: 74 79 3b 20 70 3b 20 70 3d 70 2d 3e 70 44 69 72  ty; p; p=p->pDir
38c0: 74 79 4e 65 78 74 29 7b 0a 20 20 20 20 70 2d 3e  tyNext){.    p->
38d0: 70 44 69 72 74 79 20 3d 20 70 2d 3e 70 44 69 72  pDirty = p->pDir
38e0: 74 79 4e 65 78 74 3b 0a 20 20 7d 0a 20 20 72 65  tyNext;.  }.  re
38f0: 74 75 72 6e 20 70 63 61 63 68 65 53 6f 72 74 44  turn pcacheSortD
3900: 69 72 74 79 4c 69 73 74 28 70 43 61 63 68 65 2d  irtyList(pCache-
3910: 3e 70 44 69 72 74 79 29 3b 0a 7d 0a 0a 2f 2a 20  >pDirty);.}../* 
3920: 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 74  .** Return the t
3930: 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 72  otal number of r
3940: 65 66 65 72 65 6e 63 65 64 20 70 61 67 65 73 20  eferenced pages 
3950: 68 65 6c 64 20 62 79 20 74 68 65 20 63 61 63 68  held by the cach
3960: 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  e..*/.int sqlite
3970: 33 50 63 61 63 68 65 52 65 66 43 6f 75 6e 74 28  3PcacheRefCount(
3980: 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b  PCache *pCache){
3990: 0a 20 20 72 65 74 75 72 6e 20 70 43 61 63 68 65  .  return pCache
39a0: 2d 3e 6e 52 65 66 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ->nRef;.}../*.**
39b0: 20 52 65 74 75 72 6e 20 74 68 65 20 6e 75 6d 62   Return the numb
39c0: 65 72 20 6f 66 20 72 65 66 65 72 65 6e 63 65 73  er of references
39d0: 20 74 6f 20 74 68 65 20 70 61 67 65 20 73 75 70   to the page sup
39e0: 70 6c 69 65 64 20 61 73 20 61 6e 20 61 72 67 75  plied as an argu
39f0: 6d 65 6e 74 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c  ment..*/.int sql
3a00: 69 74 65 33 50 63 61 63 68 65 50 61 67 65 52 65  ite3PcachePageRe
3a10: 66 63 6f 75 6e 74 28 50 67 48 64 72 20 2a 70 29  fcount(PgHdr *p)
3a20: 7b 0a 20 20 72 65 74 75 72 6e 20 70 2d 3e 6e 52  {.  return p->nR
3a30: 65 66 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 52 65  ef;.}../* .** Re
3a40: 74 75 72 6e 20 74 68 65 20 74 6f 74 61 6c 20 6e  turn the total n
3a50: 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 69  umber of pages i
3a60: 6e 20 74 68 65 20 63 61 63 68 65 2e 0a 2a 2f 0a  n the cache..*/.
3a70: 69 6e 74 20 73 71 6c 69 74 65 33 50 63 61 63 68  int sqlite3Pcach
3a80: 65 50 61 67 65 63 6f 75 6e 74 28 50 43 61 63 68  ePagecount(PCach
3a90: 65 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 69 6e  e *pCache){.  in
3aa0: 74 20 6e 50 61 67 65 20 3d 20 30 3b 0a 20 20 69  t nPage = 0;.  i
3ab0: 66 28 20 70 43 61 63 68 65 2d 3e 70 43 61 63 68  f( pCache->pCach
3ac0: 65 20 29 7b 0a 20 20 20 20 6e 50 61 67 65 20 3d  e ){.    nPage =
3ad0: 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f   sqlite3GlobalCo
3ae0: 6e 66 69 67 2e 70 63 61 63 68 65 2e 78 50 61 67  nfig.pcache.xPag
3af0: 65 63 6f 75 6e 74 28 70 43 61 63 68 65 2d 3e 70  ecount(pCache->p
3b00: 43 61 63 68 65 29 3b 0a 20 20 7d 0a 20 20 72 65  Cache);.  }.  re
3b10: 74 75 72 6e 20 6e 50 61 67 65 3b 0a 7d 0a 0a 23  turn nPage;.}..#
3b20: 69 66 64 65 66 20 53 51 4c 49 54 45 5f 54 45 53  ifdef SQLITE_TES
3b30: 54 0a 2f 2a 0a 2a 2a 20 47 65 74 20 74 68 65 20  T./*.** Get the 
3b40: 73 75 67 67 65 73 74 65 64 20 63 61 63 68 65 2d  suggested cache-
3b50: 73 69 7a 65 20 76 61 6c 75 65 2e 0a 2a 2f 0a 69  size value..*/.i
3b60: 6e 74 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  nt sqlite3Pcache
3b70: 47 65 74 43 61 63 68 65 73 69 7a 65 28 50 43 61  GetCachesize(PCa
3b80: 63 68 65 20 2a 70 43 61 63 68 65 29 7b 0a 20 20  che *pCache){.  
3b90: 72 65 74 75 72 6e 20 70 43 61 63 68 65 2d 3e 6e  return pCache->n
3ba0: 4d 61 78 3b 0a 7d 0a 23 65 6e 64 69 66 0a 0a 2f  Max;.}.#endif../
3bb0: 2a 0a 2a 2a 20 53 65 74 20 74 68 65 20 73 75 67  *.** Set the sug
3bc0: 67 65 73 74 65 64 20 63 61 63 68 65 2d 73 69 7a  gested cache-siz
3bd0: 65 20 76 61 6c 75 65 2e 0a 2a 2f 0a 76 6f 69 64  e value..*/.void
3be0: 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 53 65   sqlite3PcacheSe
3bf0: 74 43 61 63 68 65 73 69 7a 65 28 50 43 61 63 68  tCachesize(PCach
3c00: 65 20 2a 70 43 61 63 68 65 2c 20 69 6e 74 20 6d  e *pCache, int m
3c10: 78 50 61 67 65 29 7b 0a 20 20 70 43 61 63 68 65  xPage){.  pCache
3c20: 2d 3e 6e 4d 61 78 20 3d 20 6d 78 50 61 67 65 3b  ->nMax = mxPage;
3c30: 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 70  .  if( pCache->p
3c40: 43 61 63 68 65 20 29 7b 0a 20 20 20 20 73 71 6c  Cache ){.    sql
3c50: 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67  ite3GlobalConfig
3c60: 2e 70 63 61 63 68 65 2e 78 43 61 63 68 65 73 69  .pcache.xCachesi
3c70: 7a 65 28 70 43 61 63 68 65 2d 3e 70 43 61 63 68  ze(pCache->pCach
3c80: 65 2c 20 6d 78 50 61 67 65 29 3b 0a 20 20 7d 0a  e, mxPage);.  }.
3c90: 7d 0a 0a 23 69 66 20 64 65 66 69 6e 65 64 28 53  }..#if defined(S
3ca0: 51 4c 49 54 45 5f 43 48 45 43 4b 5f 50 41 47 45  QLITE_CHECK_PAGE
3cb0: 53 29 20 7c 7c 20 64 65 66 69 6e 65 64 28 53 51  S) || defined(SQ
3cc0: 4c 49 54 45 5f 44 45 42 55 47 29 0a 2f 2a 0a 2a  LITE_DEBUG)./*.*
3cd0: 2a 20 46 6f 72 20 61 6c 6c 20 64 69 72 74 79 20  * For all dirty 
3ce0: 70 61 67 65 73 20 63 75 72 72 65 6e 74 6c 79 20  pages currently 
3cf0: 69 6e 20 74 68 65 20 63 61 63 68 65 2c 20 69 6e  in the cache, in
3d00: 76 6f 6b 65 20 74 68 65 20 73 70 65 63 69 66 69  voke the specifi
3d10: 65 64 0a 2a 2a 20 63 61 6c 6c 62 61 63 6b 2e 20  ed.** callback. 
3d20: 54 68 69 73 20 69 73 20 6f 6e 6c 79 20 75 73 65  This is only use
3d30: 64 20 69 66 20 74 68 65 20 53 51 4c 49 54 45 5f  d if the SQLITE_
3d40: 43 48 45 43 4b 5f 50 41 47 45 53 20 6d 61 63 72  CHECK_PAGES macr
3d50: 6f 20 69 73 0a 2a 2a 20 64 65 66 69 6e 65 64 2e  o is.** defined.
3d60: 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33  .*/.void sqlite3
3d70: 50 63 61 63 68 65 49 74 65 72 61 74 65 44 69 72  PcacheIterateDir
3d80: 74 79 28 50 43 61 63 68 65 20 2a 70 43 61 63 68  ty(PCache *pCach
3d90: 65 2c 20 76 6f 69 64 20 28 2a 78 49 74 65 72 29  e, void (*xIter)
3da0: 28 50 67 48 64 72 20 2a 29 29 7b 0a 20 20 50 67  (PgHdr *)){.  Pg
3db0: 48 64 72 20 2a 70 44 69 72 74 79 3b 0a 20 20 66  Hdr *pDirty;.  f
3dc0: 6f 72 28 70 44 69 72 74 79 3d 70 43 61 63 68 65  or(pDirty=pCache
3dd0: 2d 3e 70 44 69 72 74 79 3b 20 70 44 69 72 74 79  ->pDirty; pDirty
3de0: 3b 20 70 44 69 72 74 79 3d 70 44 69 72 74 79 2d  ; pDirty=pDirty-
3df0: 3e 70 44 69 72 74 79 4e 65 78 74 29 7b 0a 20 20  >pDirtyNext){.  
3e00: 20 20 78 49 74 65 72 28 70 44 69 72 74 79 29 3b    xIter(pDirty);
3e10: 0a 20 20 7d 0a 7d 0a 23 65 6e 64 69 66 0a        .  }.}.#endif.