/ Hex Artifact Content
Login

Artifact 815bcb3cf0e14b23212efd3f4981f667a5fd633e:


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 7d  >pCache = 0;.  }
1810: 0a 20 20 70 43 61 63 68 65 2d 3e 73 7a 50 61 67  .  pCache->szPag
1820: 65 20 3d 20 73 7a 50 61 67 65 3b 0a 7d 0a 0a 2f  e = szPage;.}../
1830: 2a 0a 2a 2a 20 54 72 79 20 74 6f 20 6f 62 74 61  *.** Try to obta
1840: 69 6e 20 61 20 70 61 67 65 20 66 72 6f 6d 20 74  in a page from t
1850: 68 65 20 63 61 63 68 65 2e 0a 2a 2f 0a 69 6e 74  he cache..*/.int
1860: 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 46 65   sqlite3PcacheFe
1870: 74 63 68 28 0a 20 20 50 43 61 63 68 65 20 2a 70  tch(.  PCache *p
1880: 43 61 63 68 65 2c 20 20 20 20 20 20 20 2f 2a 20  Cache,       /* 
1890: 4f 62 74 61 69 6e 20 74 68 65 20 70 61 67 65 20  Obtain the page 
18a0: 66 72 6f 6d 20 74 68 69 73 20 63 61 63 68 65 20  from this cache 
18b0: 2a 2f 0a 20 20 50 67 6e 6f 20 70 67 6e 6f 2c 20  */.  Pgno pgno, 
18c0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61             /* Pa
18d0: 67 65 20 6e 75 6d 62 65 72 20 74 6f 20 6f 62 74  ge number to obt
18e0: 61 69 6e 20 2a 2f 0a 20 20 69 6e 74 20 63 72 65  ain */.  int cre
18f0: 61 74 65 46 6c 61 67 2c 20 20 20 20 20 20 20 2f  ateFlag,       /
1900: 2a 20 49 66 20 74 72 75 65 2c 20 63 72 65 61 74  * If true, creat
1910: 65 20 70 61 67 65 20 69 66 20 69 74 20 64 6f 65  e page if it doe
1920: 73 20 6e 6f 74 20 65 78 69 73 74 20 61 6c 72 65  s not exist alre
1930: 61 64 79 20 2a 2f 0a 20 20 50 67 48 64 72 20 2a  ady */.  PgHdr *
1940: 2a 70 70 50 61 67 65 20 20 20 20 20 20 20 20 2f  *ppPage        /
1950: 2a 20 57 72 69 74 65 20 74 68 65 20 70 61 67 65  * Write the page
1960: 20 68 65 72 65 20 2a 2f 0a 29 7b 0a 20 20 50 67   here */.){.  Pg
1970: 48 64 72 20 2a 70 50 61 67 65 20 3d 20 30 3b 0a  Hdr *pPage = 0;.
1980: 20 20 69 6e 74 20 65 43 72 65 61 74 65 3b 0a 0a    int eCreate;..
1990: 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65    assert( pCache
19a0: 21 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28  !=0 );.  assert(
19b0: 20 63 72 65 61 74 65 46 6c 61 67 3d 3d 31 20 7c   createFlag==1 |
19c0: 7c 20 63 72 65 61 74 65 46 6c 61 67 3d 3d 30 20  | createFlag==0 
19d0: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 67 6e  );.  assert( pgn
19e0: 6f 3e 30 20 29 3b 0a 0a 20 20 2f 2a 20 49 66 20  o>0 );..  /* If 
19f0: 74 68 65 20 70 6c 75 67 67 61 62 6c 65 20 63 61  the pluggable ca
1a00: 63 68 65 20 28 73 71 6c 69 74 65 33 5f 70 63 61  che (sqlite3_pca
1a10: 63 68 65 2a 29 20 68 61 73 20 6e 6f 74 20 62 65  che*) has not be
1a20: 65 6e 20 61 6c 6c 6f 63 61 74 65 64 2c 0a 20 20  en allocated,.  
1a30: 2a 2a 20 61 6c 6c 6f 63 61 74 65 20 69 74 20 6e  ** allocate it n
1a40: 6f 77 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 21  ow..  */.  if( !
1a50: 70 43 61 63 68 65 2d 3e 70 43 61 63 68 65 20 26  pCache->pCache &
1a60: 26 20 63 72 65 61 74 65 46 6c 61 67 20 29 7b 0a  & createFlag ){.
1a70: 20 20 20 20 73 71 6c 69 74 65 33 5f 70 63 61 63      sqlite3_pcac
1a80: 68 65 20 2a 70 3b 0a 20 20 20 20 69 6e 74 20 6e  he *p;.    int n
1a90: 42 79 74 65 3b 0a 20 20 20 20 6e 42 79 74 65 20  Byte;.    nByte 
1aa0: 3d 20 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65  = pCache->szPage
1ab0: 20 2b 20 70 43 61 63 68 65 2d 3e 73 7a 45 78 74   + pCache->szExt
1ac0: 72 61 20 2b 20 73 69 7a 65 6f 66 28 50 67 48 64  ra + sizeof(PgHd
1ad0: 72 29 3b 0a 20 20 20 20 70 20 3d 20 73 71 6c 69  r);.    p = sqli
1ae0: 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e  te3GlobalConfig.
1af0: 70 63 61 63 68 65 2e 78 43 72 65 61 74 65 28 6e  pcache.xCreate(n
1b00: 42 79 74 65 2c 20 70 43 61 63 68 65 2d 3e 62 50  Byte, pCache->bP
1b10: 75 72 67 65 61 62 6c 65 29 3b 0a 20 20 20 20 69  urgeable);.    i
1b20: 66 28 20 21 70 20 29 7b 0a 20 20 20 20 20 20 72  f( !p ){.      r
1b30: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d  eturn SQLITE_NOM
1b40: 45 4d 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73 71  EM;.    }.    sq
1b50: 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69  lite3GlobalConfi
1b60: 67 2e 70 63 61 63 68 65 2e 78 43 61 63 68 65 73  g.pcache.xCaches
1b70: 69 7a 65 28 70 2c 20 70 43 61 63 68 65 2d 3e 6e  ize(p, pCache->n
1b80: 4d 61 78 29 3b 0a 20 20 20 20 70 43 61 63 68 65  Max);.    pCache
1b90: 2d 3e 70 43 61 63 68 65 20 3d 20 70 3b 0a 20 20  ->pCache = p;.  
1ba0: 7d 0a 0a 20 20 65 43 72 65 61 74 65 20 3d 20 63  }..  eCreate = c
1bb0: 72 65 61 74 65 46 6c 61 67 20 2a 20 28 31 20 2b  reateFlag * (1 +
1bc0: 20 28 21 70 43 61 63 68 65 2d 3e 62 50 75 72 67   (!pCache->bPurg
1bd0: 65 61 62 6c 65 20 7c 7c 20 21 70 43 61 63 68 65  eable || !pCache
1be0: 2d 3e 70 44 69 72 74 79 29 29 3b 0a 20 20 69 66  ->pDirty));.  if
1bf0: 28 20 70 43 61 63 68 65 2d 3e 70 43 61 63 68 65  ( pCache->pCache
1c00: 20 29 7b 0a 20 20 20 20 70 50 61 67 65 20 3d 20   ){.    pPage = 
1c10: 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e  sqlite3GlobalCon
1c20: 66 69 67 2e 70 63 61 63 68 65 2e 78 46 65 74 63  fig.pcache.xFetc
1c30: 68 28 70 43 61 63 68 65 2d 3e 70 43 61 63 68 65  h(pCache->pCache
1c40: 2c 20 70 67 6e 6f 2c 20 65 43 72 65 61 74 65 29  , pgno, eCreate)
1c50: 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 21 70 50  ;.  }..  if( !pP
1c60: 61 67 65 20 26 26 20 65 43 72 65 61 74 65 3d 3d  age && eCreate==
1c70: 31 20 29 7b 0a 20 20 20 20 50 67 48 64 72 20 2a  1 ){.    PgHdr *
1c80: 70 50 67 3b 0a 0a 20 20 20 20 2f 2a 20 46 69 6e  pPg;..    /* Fin
1c90: 64 20 61 20 64 69 72 74 79 20 70 61 67 65 20 74  d a dirty page t
1ca0: 6f 20 77 72 69 74 65 2d 6f 75 74 20 61 6e 64 20  o write-out and 
1cb0: 72 65 63 79 63 6c 65 2e 20 46 69 72 73 74 20 74  recycle. First t
1cc0: 72 79 20 74 6f 20 66 69 6e 64 20 61 20 0a 20 20  ry to find a .  
1cd0: 20 20 2a 2a 20 70 61 67 65 20 74 68 61 74 20 64    ** page that d
1ce0: 6f 65 73 20 6e 6f 74 20 72 65 71 75 69 72 65 20  oes not require 
1cf0: 61 20 6a 6f 75 72 6e 61 6c 2d 73 79 6e 63 20 28  a journal-sync (
1d00: 6f 6e 65 20 77 69 74 68 20 50 47 48 44 52 5f 4e  one with PGHDR_N
1d10: 45 45 44 5f 53 59 4e 43 0a 20 20 20 20 2a 2a 20  EED_SYNC.    ** 
1d20: 63 6c 65 61 72 65 64 29 2c 20 62 75 74 20 69 66  cleared), but if
1d30: 20 74 68 61 74 20 69 73 20 6e 6f 74 20 70 6f 73   that is not pos
1d40: 73 69 62 6c 65 20 73 65 74 74 6c 65 20 66 6f 72  sible settle for
1d50: 20 61 6e 79 20 6f 74 68 65 72 20 0a 20 20 20 20   any other .    
1d60: 2a 2a 20 75 6e 72 65 66 65 72 65 6e 63 65 64 20  ** unreferenced 
1d70: 64 69 72 74 79 20 70 61 67 65 2e 0a 20 20 20 20  dirty page..    
1d80: 2a 2f 0a 20 20 20 20 65 78 70 65 6e 73 69 76 65  */.    expensive
1d90: 5f 61 73 73 65 72 74 28 20 70 63 61 63 68 65 43  _assert( pcacheC
1da0: 68 65 63 6b 53 79 6e 63 65 64 28 70 43 61 63 68  heckSynced(pCach
1db0: 65 29 20 29 3b 0a 20 20 20 20 66 6f 72 28 70 50  e) );.    for(pP
1dc0: 67 3d 70 43 61 63 68 65 2d 3e 70 53 79 6e 63 65  g=pCache->pSynce
1dd0: 64 3b 20 0a 20 20 20 20 20 20 20 20 70 50 67 20  d; .        pPg 
1de0: 26 26 20 28 70 50 67 2d 3e 6e 52 65 66 20 7c 7c  && (pPg->nRef ||
1df0: 20 28 70 50 67 2d 3e 66 6c 61 67 73 26 50 47 48   (pPg->flags&PGH
1e00: 44 52 5f 4e 45 45 44 5f 53 59 4e 43 29 29 3b 20  DR_NEED_SYNC)); 
1e10: 0a 20 20 20 20 20 20 20 20 70 50 67 3d 70 50 67  .        pPg=pPg
1e20: 2d 3e 70 44 69 72 74 79 50 72 65 76 0a 20 20 20  ->pDirtyPrev.   
1e30: 20 29 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e   );.    pCache->
1e40: 70 53 79 6e 63 65 64 20 3d 20 70 50 67 3b 0a 20  pSynced = pPg;. 
1e50: 20 20 20 69 66 28 20 21 70 50 67 20 29 7b 0a 20     if( !pPg ){. 
1e60: 20 20 20 20 20 66 6f 72 28 70 50 67 3d 70 43 61       for(pPg=pCa
1e70: 63 68 65 2d 3e 70 44 69 72 74 79 54 61 69 6c 3b  che->pDirtyTail;
1e80: 20 70 50 67 20 26 26 20 70 50 67 2d 3e 6e 52 65   pPg && pPg->nRe
1e90: 66 3b 20 70 50 67 3d 70 50 67 2d 3e 70 44 69 72  f; pPg=pPg->pDir
1ea0: 74 79 50 72 65 76 29 3b 0a 20 20 20 20 7d 0a 20  tyPrev);.    }. 
1eb0: 20 20 20 69 66 28 20 70 50 67 20 29 7b 0a 20 20     if( pPg ){.  
1ec0: 20 20 20 20 69 6e 74 20 72 63 3b 0a 20 20 20 20      int rc;.    
1ed0: 20 20 72 63 20 3d 20 70 43 61 63 68 65 2d 3e 78    rc = pCache->x
1ee0: 53 74 72 65 73 73 28 70 43 61 63 68 65 2d 3e 70  Stress(pCache->p
1ef0: 53 74 72 65 73 73 2c 20 70 50 67 29 3b 0a 20 20  Stress, pPg);.  
1f00: 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
1f10: 54 45 5f 4f 4b 20 26 26 20 72 63 21 3d 53 51 4c  TE_OK && rc!=SQL
1f20: 49 54 45 5f 42 55 53 59 20 29 7b 0a 20 20 20 20  ITE_BUSY ){.    
1f30: 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20      return rc;. 
1f40: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20       }.    }..  
1f50: 20 20 70 50 61 67 65 20 3d 20 73 71 6c 69 74 65    pPage = sqlite
1f60: 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63  3GlobalConfig.pc
1f70: 61 63 68 65 2e 78 46 65 74 63 68 28 70 43 61 63  ache.xFetch(pCac
1f80: 68 65 2d 3e 70 43 61 63 68 65 2c 20 70 67 6e 6f  he->pCache, pgno
1f90: 2c 20 32 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28  , 2);.  }..  if(
1fa0: 20 70 50 61 67 65 20 29 7b 0a 20 20 20 20 69 66   pPage ){.    if
1fb0: 28 20 21 70 50 61 67 65 2d 3e 70 44 61 74 61 20  ( !pPage->pData 
1fc0: 29 7b 0a 20 20 20 20 20 20 6d 65 6d 73 65 74 28  ){.      memset(
1fd0: 70 50 61 67 65 2c 20 30 2c 20 73 69 7a 65 6f 66  pPage, 0, sizeof
1fe0: 28 50 67 48 64 72 29 20 2b 20 70 43 61 63 68 65  (PgHdr) + pCache
1ff0: 2d 3e 73 7a 45 78 74 72 61 29 3b 0a 20 20 20 20  ->szExtra);.    
2000: 20 20 70 50 61 67 65 2d 3e 70 45 78 74 72 61 20    pPage->pExtra 
2010: 3d 20 28 76 6f 69 64 2a 29 26 70 50 61 67 65 5b  = (void*)&pPage[
2020: 31 5d 3b 0a 20 20 20 20 20 20 70 50 61 67 65 2d  1];.      pPage-
2030: 3e 70 44 61 74 61 20 3d 20 28 76 6f 69 64 20 2a  >pData = (void *
2040: 29 26 28 28 63 68 61 72 20 2a 29 70 50 61 67 65  )&((char *)pPage
2050: 29 5b 73 69 7a 65 6f 66 28 50 67 48 64 72 29 20  )[sizeof(PgHdr) 
2060: 2b 20 70 43 61 63 68 65 2d 3e 73 7a 45 78 74 72  + pCache->szExtr
2070: 61 5d 3b 0a 20 20 20 20 20 20 70 50 61 67 65 2d  a];.      pPage-
2080: 3e 70 43 61 63 68 65 20 3d 20 70 43 61 63 68 65  >pCache = pCache
2090: 3b 0a 20 20 20 20 20 20 70 50 61 67 65 2d 3e 70  ;.      pPage->p
20a0: 67 6e 6f 20 3d 20 70 67 6e 6f 3b 0a 20 20 20 20  gno = pgno;.    
20b0: 7d 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 50  }.    assert( pP
20c0: 61 67 65 2d 3e 70 43 61 63 68 65 3d 3d 70 43 61  age->pCache==pCa
20d0: 63 68 65 20 29 3b 0a 20 20 20 20 61 73 73 65 72  che );.    asser
20e0: 74 28 20 70 50 61 67 65 2d 3e 70 67 6e 6f 3d 3d  t( pPage->pgno==
20f0: 70 67 6e 6f 20 29 3b 0a 20 20 20 20 61 73 73 65  pgno );.    asse
2100: 72 74 28 20 70 50 61 67 65 2d 3e 70 45 78 74 72  rt( pPage->pExtr
2110: 61 3d 3d 28 76 6f 69 64 20 2a 29 26 70 50 61 67  a==(void *)&pPag
2120: 65 5b 31 5d 20 29 3b 0a 0a 20 20 20 20 69 66 28  e[1] );..    if(
2130: 20 30 3d 3d 70 50 61 67 65 2d 3e 6e 52 65 66 20   0==pPage->nRef 
2140: 29 7b 0a 20 20 20 20 20 20 70 43 61 63 68 65 2d  ){.      pCache-
2150: 3e 6e 52 65 66 2b 2b 3b 0a 20 20 20 20 7d 0a 20  >nRef++;.    }. 
2160: 20 20 20 70 50 61 67 65 2d 3e 6e 52 65 66 2b 2b     pPage->nRef++
2170: 3b 0a 20 20 20 20 69 66 28 20 70 67 6e 6f 3d 3d  ;.    if( pgno==
2180: 31 20 29 7b 0a 20 20 20 20 20 20 70 43 61 63 68  1 ){.      pCach
2190: 65 2d 3e 70 50 61 67 65 31 20 3d 20 70 50 61 67  e->pPage1 = pPag
21a0: 65 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 2a  e;.    }.  }.  *
21b0: 70 70 50 61 67 65 20 3d 20 70 50 61 67 65 3b 0a  ppPage = pPage;.
21c0: 20 20 72 65 74 75 72 6e 20 28 70 50 61 67 65 3d    return (pPage=
21d0: 3d 30 20 26 26 20 65 43 72 65 61 74 65 29 20 3f  =0 && eCreate) ?
21e0: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 20 3a 20   SQLITE_NOMEM : 
21f0: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a  SQLITE_OK;.}../*
2200: 0a 2a 2a 20 44 65 63 72 65 6d 65 6e 74 20 74 68  .** Decrement th
2210: 65 20 72 65 66 65 72 65 6e 63 65 20 63 6f 75 6e  e reference coun
2220: 74 20 6f 6e 20 61 20 70 61 67 65 2e 20 49 66 20  t on a page. If 
2230: 74 68 65 20 70 61 67 65 20 69 73 20 63 6c 65 61  the page is clea
2240: 6e 20 61 6e 64 20 74 68 65 0a 2a 2a 20 72 65 66  n and the.** ref
2250: 65 72 65 6e 63 65 20 63 6f 75 6e 74 20 64 72 6f  erence count dro
2260: 70 73 20 74 6f 20 30 2c 20 74 68 65 6e 20 69 74  ps to 0, then it
2270: 20 69 73 20 6d 61 64 65 20 65 6c 69 62 6c 65 20   is made elible 
2280: 66 6f 72 20 72 65 63 79 63 6c 69 6e 67 2e 0a 2a  for recycling..*
2290: 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63  /.void sqlite3Pc
22a0: 61 63 68 65 52 65 6c 65 61 73 65 28 50 67 48 64  acheRelease(PgHd
22b0: 72 20 2a 70 29 7b 0a 20 20 61 73 73 65 72 74 28  r *p){.  assert(
22c0: 20 70 2d 3e 6e 52 65 66 3e 30 20 29 3b 0a 20 20   p->nRef>0 );.  
22d0: 70 2d 3e 6e 52 65 66 2d 2d 3b 0a 20 20 69 66 28  p->nRef--;.  if(
22e0: 20 70 2d 3e 6e 52 65 66 3d 3d 30 20 29 7b 0a 20   p->nRef==0 ){. 
22f0: 20 20 20 50 43 61 63 68 65 20 2a 70 43 61 63 68     PCache *pCach
2300: 65 20 3d 20 70 2d 3e 70 43 61 63 68 65 3b 0a 20  e = p->pCache;. 
2310: 20 20 20 70 43 61 63 68 65 2d 3e 6e 52 65 66 2d     pCache->nRef-
2320: 2d 3b 0a 20 20 20 20 69 66 28 20 28 70 2d 3e 66  -;.    if( (p->f
2330: 6c 61 67 73 26 50 47 48 44 52 5f 44 49 52 54 59  lags&PGHDR_DIRTY
2340: 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 70 63  )==0 ){.      pc
2350: 61 63 68 65 55 6e 70 69 6e 28 70 29 3b 0a 20 20  acheUnpin(p);.  
2360: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 2f    }else{.      /
2370: 2a 20 4d 6f 76 65 20 74 68 65 20 70 61 67 65 20  * Move the page 
2380: 74 6f 20 74 68 65 20 68 65 61 64 20 6f 66 20 74  to the head of t
2390: 68 65 20 64 69 72 74 79 20 6c 69 73 74 2e 20 2a  he dirty list. *
23a0: 2f 0a 20 20 20 20 20 20 70 63 61 63 68 65 52 65  /.      pcacheRe
23b0: 6d 6f 76 65 46 72 6f 6d 44 69 72 74 79 4c 69 73  moveFromDirtyLis
23c0: 74 28 70 29 3b 0a 20 20 20 20 20 20 70 63 61 63  t(p);.      pcac
23d0: 68 65 41 64 64 54 6f 44 69 72 74 79 4c 69 73 74  heAddToDirtyList
23e0: 28 70 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d  (p);.    }.  }.}
23f0: 0a 0a 2f 2a 0a 2a 2a 20 49 6e 63 72 65 61 73 65  ../*.** Increase
2400: 20 74 68 65 20 72 65 66 65 72 65 6e 63 65 20 63   the reference c
2410: 6f 75 6e 74 20 6f 66 20 61 20 73 75 70 70 6c 69  ount of a suppli
2420: 65 64 20 70 61 67 65 20 62 79 20 31 2e 0a 2a 2f  ed page by 1..*/
2430: 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63 61  .void sqlite3Pca
2440: 63 68 65 52 65 66 28 50 67 48 64 72 20 2a 70 29  cheRef(PgHdr *p)
2450: 7b 0a 20 20 61 73 73 65 72 74 28 70 2d 3e 6e 52  {.  assert(p->nR
2460: 65 66 3e 30 29 3b 0a 20 20 70 2d 3e 6e 52 65 66  ef>0);.  p->nRef
2470: 2b 2b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 72 6f  ++;.}../*.** Dro
2480: 70 20 61 20 70 61 67 65 20 66 72 6f 6d 20 74 68  p a page from th
2490: 65 20 63 61 63 68 65 2e 20 54 68 65 72 65 20 6d  e cache. There m
24a0: 75 73 74 20 62 65 20 65 78 61 63 74 6c 79 20 6f  ust be exactly o
24b0: 6e 65 20 72 65 66 65 72 65 6e 63 65 20 74 6f 20  ne reference to 
24c0: 74 68 65 0a 2a 2a 20 70 61 67 65 2e 20 54 68 69  the.** page. Thi
24d0: 73 20 66 75 6e 63 74 69 6f 6e 20 64 65 6c 65 74  s function delet
24e0: 65 73 20 74 68 61 74 20 72 65 66 65 72 65 6e 63  es that referenc
24f0: 65 2c 20 73 6f 20 61 66 74 65 72 20 69 74 20 72  e, so after it r
2500: 65 74 75 72 6e 73 20 74 68 65 0a 2a 2a 20 70 61  eturns the.** pa
2510: 67 65 20 70 6f 69 6e 74 65 64 20 74 6f 20 62 79  ge pointed to by
2520: 20 70 20 69 73 20 69 6e 76 61 6c 69 64 2e 0a 2a   p is invalid..*
2530: 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63  /.void sqlite3Pc
2540: 61 63 68 65 44 72 6f 70 28 50 67 48 64 72 20 2a  acheDrop(PgHdr *
2550: 70 29 7b 0a 20 20 50 43 61 63 68 65 20 2a 70 43  p){.  PCache *pC
2560: 61 63 68 65 3b 0a 20 20 61 73 73 65 72 74 28 20  ache;.  assert( 
2570: 70 2d 3e 6e 52 65 66 3d 3d 31 20 29 3b 0a 20 20  p->nRef==1 );.  
2580: 69 66 28 20 70 2d 3e 66 6c 61 67 73 26 50 47 48  if( p->flags&PGH
2590: 44 52 5f 44 49 52 54 59 20 29 7b 0a 20 20 20 20  DR_DIRTY ){.    
25a0: 70 63 61 63 68 65 52 65 6d 6f 76 65 46 72 6f 6d  pcacheRemoveFrom
25b0: 44 69 72 74 79 4c 69 73 74 28 70 29 3b 0a 20 20  DirtyList(p);.  
25c0: 7d 0a 20 20 70 43 61 63 68 65 20 3d 20 70 2d 3e  }.  pCache = p->
25d0: 70 43 61 63 68 65 3b 0a 20 20 70 43 61 63 68 65  pCache;.  pCache
25e0: 2d 3e 6e 52 65 66 2d 2d 3b 0a 20 20 69 66 28 20  ->nRef--;.  if( 
25f0: 70 2d 3e 70 67 6e 6f 3d 3d 31 20 29 7b 0a 20 20  p->pgno==1 ){.  
2600: 20 20 70 43 61 63 68 65 2d 3e 70 50 61 67 65 31    pCache->pPage1
2610: 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 73 71 6c 69   = 0;.  }.  sqli
2620: 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e  te3GlobalConfig.
2630: 70 63 61 63 68 65 2e 78 55 6e 70 69 6e 28 70 43  pcache.xUnpin(pC
2640: 61 63 68 65 2d 3e 70 43 61 63 68 65 2c 20 70 2c  ache->pCache, p,
2650: 20 31 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61   1);.}../*.** Ma
2660: 6b 65 20 73 75 72 65 20 74 68 65 20 70 61 67 65  ke sure the page
2670: 20 69 73 20 6d 61 72 6b 65 64 20 61 73 20 64 69   is marked as di
2680: 72 74 79 2e 20 49 66 20 69 74 20 69 73 6e 27 74  rty. If it isn't
2690: 20 64 69 72 74 79 20 61 6c 72 65 61 64 79 2c 0a   dirty already,.
26a0: 2a 2a 20 6d 61 6b 65 20 69 74 20 73 6f 2e 0a 2a  ** make it so..*
26b0: 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63  /.void sqlite3Pc
26c0: 61 63 68 65 4d 61 6b 65 44 69 72 74 79 28 50 67  acheMakeDirty(Pg
26d0: 48 64 72 20 2a 70 29 7b 0a 20 20 70 2d 3e 66 6c  Hdr *p){.  p->fl
26e0: 61 67 73 20 26 3d 20 7e 50 47 48 44 52 5f 44 4f  ags &= ~PGHDR_DO
26f0: 4e 54 5f 57 52 49 54 45 3b 0a 20 20 61 73 73 65  NT_WRITE;.  asse
2700: 72 74 28 20 70 2d 3e 6e 52 65 66 3e 30 20 29 3b  rt( p->nRef>0 );
2710: 0a 20 20 69 66 28 20 30 3d 3d 28 70 2d 3e 66 6c  .  if( 0==(p->fl
2720: 61 67 73 20 26 20 50 47 48 44 52 5f 44 49 52 54  ags & PGHDR_DIRT
2730: 59 29 20 29 7b 0a 20 20 20 20 70 2d 3e 66 6c 61  Y) ){.    p->fla
2740: 67 73 20 7c 3d 20 50 47 48 44 52 5f 44 49 52 54  gs |= PGHDR_DIRT
2750: 59 3b 0a 20 20 20 20 70 63 61 63 68 65 41 64 64  Y;.    pcacheAdd
2760: 54 6f 44 69 72 74 79 4c 69 73 74 28 20 70 29 3b  ToDirtyList( p);
2770: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61  .  }.}../*.** Ma
2780: 6b 65 20 73 75 72 65 20 74 68 65 20 70 61 67 65  ke sure the page
2790: 20 69 73 20 6d 61 72 6b 65 64 20 61 73 20 63 6c   is marked as cl
27a0: 65 61 6e 2e 20 49 66 20 69 74 20 69 73 6e 27 74  ean. If it isn't
27b0: 20 63 6c 65 61 6e 20 61 6c 72 65 61 64 79 2c 0a   clean already,.
27c0: 2a 2a 20 6d 61 6b 65 20 69 74 20 73 6f 2e 0a 2a  ** make it so..*
27d0: 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63  /.void sqlite3Pc
27e0: 61 63 68 65 4d 61 6b 65 43 6c 65 61 6e 28 50 67  acheMakeClean(Pg
27f0: 48 64 72 20 2a 70 29 7b 0a 20 20 69 66 28 20 28  Hdr *p){.  if( (
2800: 70 2d 3e 66 6c 61 67 73 20 26 20 50 47 48 44 52  p->flags & PGHDR
2810: 5f 44 49 52 54 59 29 20 29 7b 0a 20 20 20 20 70  _DIRTY) ){.    p
2820: 63 61 63 68 65 52 65 6d 6f 76 65 46 72 6f 6d 44  cacheRemoveFromD
2830: 69 72 74 79 4c 69 73 74 28 70 29 3b 0a 20 20 20  irtyList(p);.   
2840: 20 70 2d 3e 66 6c 61 67 73 20 26 3d 20 7e 28 50   p->flags &= ~(P
2850: 47 48 44 52 5f 44 49 52 54 59 7c 50 47 48 44 52  GHDR_DIRTY|PGHDR
2860: 5f 4e 45 45 44 5f 53 59 4e 43 29 3b 0a 20 20 20  _NEED_SYNC);.   
2870: 20 69 66 28 20 70 2d 3e 6e 52 65 66 3d 3d 30 20   if( p->nRef==0 
2880: 29 7b 0a 20 20 20 20 20 20 70 63 61 63 68 65 55  ){.      pcacheU
2890: 6e 70 69 6e 28 70 29 3b 0a 20 20 20 20 7d 0a 20  npin(p);.    }. 
28a0: 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6b 65   }.}../*.** Make
28b0: 20 65 76 65 72 79 20 70 61 67 65 20 69 6e 20 74   every page in t
28c0: 68 65 20 63 61 63 68 65 20 63 6c 65 61 6e 2e 0a  he cache clean..
28d0: 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50  */.void sqlite3P
28e0: 63 61 63 68 65 43 6c 65 61 6e 41 6c 6c 28 50 43  cacheCleanAll(PC
28f0: 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b 0a 20  ache *pCache){. 
2900: 20 50 67 48 64 72 20 2a 70 3b 0a 20 20 77 68 69   PgHdr *p;.  whi
2910: 6c 65 28 20 28 70 20 3d 20 70 43 61 63 68 65 2d  le( (p = pCache-
2920: 3e 70 44 69 72 74 79 29 21 3d 30 20 29 7b 0a 20  >pDirty)!=0 ){. 
2930: 20 20 20 73 71 6c 69 74 65 33 50 63 61 63 68 65     sqlite3Pcache
2940: 4d 61 6b 65 43 6c 65 61 6e 28 70 29 3b 0a 20 20  MakeClean(p);.  
2950: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 65 61 72  }.}../*.** Clear
2960: 20 74 68 65 20 50 47 48 44 52 5f 4e 45 45 44 5f   the PGHDR_NEED_
2970: 53 59 4e 43 20 66 6c 61 67 20 66 72 6f 6d 20 61  SYNC flag from a
2980: 6c 6c 20 64 69 72 74 79 20 70 61 67 65 73 2e 0a  ll dirty pages..
2990: 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50  */.void sqlite3P
29a0: 63 61 63 68 65 43 6c 65 61 72 53 79 6e 63 46 6c  cacheClearSyncFl
29b0: 61 67 73 28 50 43 61 63 68 65 20 2a 70 43 61 63  ags(PCache *pCac
29c0: 68 65 29 7b 0a 20 20 50 67 48 64 72 20 2a 70 3b  he){.  PgHdr *p;
29d0: 0a 20 20 66 6f 72 28 70 3d 70 43 61 63 68 65 2d  .  for(p=pCache-
29e0: 3e 70 44 69 72 74 79 3b 20 70 3b 20 70 3d 70 2d  >pDirty; p; p=p-
29f0: 3e 70 44 69 72 74 79 4e 65 78 74 29 7b 0a 20 20  >pDirtyNext){.  
2a00: 20 20 70 2d 3e 66 6c 61 67 73 20 26 3d 20 7e 50    p->flags &= ~P
2a10: 47 48 44 52 5f 4e 45 45 44 5f 53 59 4e 43 3b 0a  GHDR_NEED_SYNC;.
2a20: 20 20 7d 0a 20 20 70 43 61 63 68 65 2d 3e 70 53    }.  pCache->pS
2a30: 79 6e 63 65 64 20 3d 20 70 43 61 63 68 65 2d 3e  ynced = pCache->
2a40: 70 44 69 72 74 79 54 61 69 6c 3b 0a 7d 0a 0a 2f  pDirtyTail;.}../
2a50: 2a 0a 2a 2a 20 43 68 61 6e 67 65 20 74 68 65 20  *.** Change the 
2a60: 70 61 67 65 20 6e 75 6d 62 65 72 20 6f 66 20 70  page number of p
2a70: 61 67 65 20 70 20 74 6f 20 6e 65 77 50 67 6e 6f  age p to newPgno
2a80: 2e 20 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74  . .*/.void sqlit
2a90: 65 33 50 63 61 63 68 65 4d 6f 76 65 28 50 67 48  e3PcacheMove(PgH
2aa0: 64 72 20 2a 70 2c 20 50 67 6e 6f 20 6e 65 77 50  dr *p, Pgno newP
2ab0: 67 6e 6f 29 7b 0a 20 20 50 43 61 63 68 65 20 2a  gno){.  PCache *
2ac0: 70 43 61 63 68 65 20 3d 20 70 2d 3e 70 43 61 63  pCache = p->pCac
2ad0: 68 65 3b 0a 20 20 61 73 73 65 72 74 28 20 70 2d  he;.  assert( p-
2ae0: 3e 6e 52 65 66 3e 30 20 29 3b 0a 20 20 61 73 73  >nRef>0 );.  ass
2af0: 65 72 74 28 20 6e 65 77 50 67 6e 6f 3e 30 20 29  ert( newPgno>0 )
2b00: 3b 0a 20 20 73 71 6c 69 74 65 33 47 6c 6f 62 61  ;.  sqlite3Globa
2b10: 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65 2e 78  lConfig.pcache.x
2b20: 52 65 6b 65 79 28 70 43 61 63 68 65 2d 3e 70 43  Rekey(pCache->pC
2b30: 61 63 68 65 2c 20 70 2c 20 70 2d 3e 70 67 6e 6f  ache, p, p->pgno
2b40: 2c 20 6e 65 77 50 67 6e 6f 29 3b 0a 20 20 70 2d  , newPgno);.  p-
2b50: 3e 70 67 6e 6f 20 3d 20 6e 65 77 50 67 6e 6f 3b  >pgno = newPgno;
2b60: 0a 20 20 69 66 28 20 28 70 2d 3e 66 6c 61 67 73  .  if( (p->flags
2b70: 26 50 47 48 44 52 5f 44 49 52 54 59 29 20 26 26  &PGHDR_DIRTY) &&
2b80: 20 28 70 2d 3e 66 6c 61 67 73 26 50 47 48 44 52   (p->flags&PGHDR
2b90: 5f 4e 45 45 44 5f 53 59 4e 43 29 20 29 7b 0a 20  _NEED_SYNC) ){. 
2ba0: 20 20 20 70 63 61 63 68 65 52 65 6d 6f 76 65 46     pcacheRemoveF
2bb0: 72 6f 6d 44 69 72 74 79 4c 69 73 74 28 70 29 3b  romDirtyList(p);
2bc0: 0a 20 20 20 20 70 63 61 63 68 65 41 64 64 54 6f  .    pcacheAddTo
2bd0: 44 69 72 74 79 4c 69 73 74 28 70 29 3b 0a 20 20  DirtyList(p);.  
2be0: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 72 6f 70 20  }.}../*.** Drop 
2bf0: 65 76 65 72 79 20 63 61 63 68 65 20 65 6e 74 72  every cache entr
2c00: 79 20 77 68 6f 73 65 20 70 61 67 65 20 6e 75 6d  y whose page num
2c10: 62 65 72 20 69 73 20 67 72 65 61 74 65 72 20 74  ber is greater t
2c20: 68 61 6e 20 22 70 67 6e 6f 22 2e 20 54 68 65 0a  han "pgno". The.
2c30: 2a 2a 20 63 61 6c 6c 65 72 20 6d 75 73 74 20 65  ** caller must e
2c40: 6e 73 75 72 65 20 74 68 61 74 20 74 68 65 72 65  nsure that there
2c50: 20 61 72 65 20 6e 6f 20 6f 75 74 73 74 61 6e 64   are no outstand
2c60: 69 6e 67 20 72 65 66 65 72 65 6e 63 65 73 20 74  ing references t
2c70: 6f 20 61 6e 79 20 70 61 67 65 73 0a 2a 2a 20 6f  o any pages.** o
2c80: 74 68 65 72 20 74 68 61 6e 20 70 61 67 65 20 31  ther than page 1
2c90: 20 77 69 74 68 20 61 20 70 61 67 65 20 6e 75 6d   with a page num
2ca0: 62 65 72 20 67 72 65 61 74 65 72 20 74 68 61 6e  ber greater than
2cb0: 20 70 67 6e 6f 2e 0a 2a 2a 0a 2a 2a 20 49 66 20   pgno..**.** If 
2cc0: 74 68 65 72 65 20 69 73 20 61 20 72 65 66 65 72  there is a refer
2cd0: 65 6e 63 65 20 74 6f 20 70 61 67 65 20 31 20 61  ence to page 1 a
2ce0: 6e 64 20 74 68 65 20 70 67 6e 6f 20 70 61 72 61  nd the pgno para
2cf0: 6d 65 74 65 72 20 70 61 73 73 65 64 20 74 6f 20  meter passed to 
2d00: 74 68 69 73 0a 2a 2a 20 66 75 6e 63 74 69 6f 6e  this.** function
2d10: 20 69 73 20 30 2c 20 74 68 65 6e 20 74 68 65 20   is 0, then the 
2d20: 64 61 74 61 20 61 72 65 61 20 61 73 73 6f 63 69  data area associ
2d30: 61 74 65 64 20 77 69 74 68 20 70 61 67 65 20 31  ated with page 1
2d40: 20 69 73 20 7a 65 72 6f 65 64 2c 20 62 75 74 0a   is zeroed, but.
2d50: 2a 2a 20 74 68 65 20 70 61 67 65 20 6f 62 6a 65  ** the page obje
2d60: 63 74 20 69 73 20 6e 6f 74 20 64 72 6f 70 70 65  ct is not droppe
2d70: 64 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74  d..*/.void sqlit
2d80: 65 33 50 63 61 63 68 65 54 72 75 6e 63 61 74 65  e3PcacheTruncate
2d90: 28 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 2c  (PCache *pCache,
2da0: 20 50 67 6e 6f 20 70 67 6e 6f 29 7b 0a 20 20 69   Pgno pgno){.  i
2db0: 66 28 20 70 43 61 63 68 65 2d 3e 70 43 61 63 68  f( pCache->pCach
2dc0: 65 20 29 7b 0a 20 20 20 20 50 67 48 64 72 20 2a  e ){.    PgHdr *
2dd0: 70 3b 0a 20 20 20 20 50 67 48 64 72 20 2a 70 4e  p;.    PgHdr *pN
2de0: 65 78 74 3b 0a 20 20 20 20 66 6f 72 28 70 3d 70  ext;.    for(p=p
2df0: 43 61 63 68 65 2d 3e 70 44 69 72 74 79 3b 20 70  Cache->pDirty; p
2e00: 3b 20 70 3d 70 4e 65 78 74 29 7b 0a 20 20 20 20  ; p=pNext){.    
2e10: 20 20 70 4e 65 78 74 20 3d 20 70 2d 3e 70 44 69    pNext = p->pDi
2e20: 72 74 79 4e 65 78 74 3b 0a 20 20 20 20 20 20 69  rtyNext;.      i
2e30: 66 28 20 70 2d 3e 70 67 6e 6f 3e 70 67 6e 6f 20  f( p->pgno>pgno 
2e40: 29 7b 0a 20 20 20 20 20 20 20 20 61 73 73 65 72  ){.        asser
2e50: 74 28 20 70 2d 3e 66 6c 61 67 73 26 50 47 48 44  t( p->flags&PGHD
2e60: 52 5f 44 49 52 54 59 20 29 3b 0a 20 20 20 20 20  R_DIRTY );.     
2e70: 20 20 20 73 71 6c 69 74 65 33 50 63 61 63 68 65     sqlite3Pcache
2e80: 4d 61 6b 65 43 6c 65 61 6e 28 70 29 3b 0a 20 20  MakeClean(p);.  
2e90: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20      }.    }.    
2ea0: 69 66 28 20 70 67 6e 6f 3d 3d 30 20 26 26 20 70  if( pgno==0 && p
2eb0: 43 61 63 68 65 2d 3e 70 50 61 67 65 31 20 29 7b  Cache->pPage1 ){
2ec0: 0a 20 20 20 20 20 20 6d 65 6d 73 65 74 28 70 43  .      memset(pC
2ed0: 61 63 68 65 2d 3e 70 50 61 67 65 31 2d 3e 70 44  ache->pPage1->pD
2ee0: 61 74 61 2c 20 30 2c 20 70 43 61 63 68 65 2d 3e  ata, 0, pCache->
2ef0: 73 7a 50 61 67 65 29 3b 0a 20 20 20 20 20 20 70  szPage);.      p
2f00: 67 6e 6f 20 3d 20 31 3b 0a 20 20 20 20 7d 0a 20  gno = 1;.    }. 
2f10: 20 20 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c     sqlite3Global
2f20: 43 6f 6e 66 69 67 2e 70 63 61 63 68 65 2e 78 54  Config.pcache.xT
2f30: 72 75 6e 63 61 74 65 28 70 43 61 63 68 65 2d 3e  runcate(pCache->
2f40: 70 43 61 63 68 65 2c 20 70 67 6e 6f 2b 31 29 3b  pCache, pgno+1);
2f50: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c  .  }.}../*.** Cl
2f60: 6f 73 65 20 61 20 63 61 63 68 65 2e 0a 2a 2f 0a  ose a cache..*/.
2f70: 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63 61 63  void sqlite3Pcac
2f80: 68 65 43 6c 6f 73 65 28 50 43 61 63 68 65 20 2a  heClose(PCache *
2f90: 70 43 61 63 68 65 29 7b 0a 20 20 69 66 28 20 70  pCache){.  if( p
2fa0: 43 61 63 68 65 2d 3e 70 43 61 63 68 65 20 29 7b  Cache->pCache ){
2fb0: 0a 20 20 20 20 73 71 6c 69 74 65 33 47 6c 6f 62  .    sqlite3Glob
2fc0: 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65 2e  alConfig.pcache.
2fd0: 78 44 65 73 74 72 6f 79 28 70 43 61 63 68 65 2d  xDestroy(pCache-
2fe0: 3e 70 43 61 63 68 65 29 3b 0a 20 20 7d 0a 7d 0a  >pCache);.  }.}.
2ff0: 0a 2f 2a 20 0a 2a 2a 20 44 69 73 63 61 72 64 20  ./* .** Discard 
3000: 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20  the contents of 
3010: 74 68 65 20 63 61 63 68 65 2e 0a 2a 2f 0a 76 6f  the cache..*/.vo
3020: 69 64 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  id sqlite3Pcache
3030: 43 6c 65 61 72 28 50 43 61 63 68 65 20 2a 70 43  Clear(PCache *pC
3040: 61 63 68 65 29 7b 0a 20 20 73 71 6c 69 74 65 33  ache){.  sqlite3
3050: 50 63 61 63 68 65 54 72 75 6e 63 61 74 65 28 70  PcacheTruncate(p
3060: 43 61 63 68 65 2c 20 30 29 3b 0a 7d 0a 0a 2f 2a  Cache, 0);.}../*
3070: 0a 2a 2a 20 4d 65 72 67 65 20 74 77 6f 20 6c 69  .** Merge two li
3080: 73 74 73 20 6f 66 20 70 61 67 65 73 20 63 6f 6e  sts of pages con
3090: 6e 65 63 74 65 64 20 62 79 20 70 44 69 72 74 79  nected by pDirty
30a0: 20 61 6e 64 20 69 6e 20 70 67 6e 6f 20 6f 72 64   and in pgno ord
30b0: 65 72 2e 0a 2a 2a 20 44 6f 20 6e 6f 74 20 62 6f  er..** Do not bo
30c0: 74 68 20 66 69 78 69 6e 67 20 74 68 65 20 70 44  th fixing the pD
30d0: 69 72 74 79 50 72 65 76 20 70 6f 69 6e 74 65 72  irtyPrev pointer
30e0: 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 50 67 48  s..*/.static PgH
30f0: 64 72 20 2a 70 63 61 63 68 65 4d 65 72 67 65 44  dr *pcacheMergeD
3100: 69 72 74 79 4c 69 73 74 28 50 67 48 64 72 20 2a  irtyList(PgHdr *
3110: 70 41 2c 20 50 67 48 64 72 20 2a 70 42 29 7b 0a  pA, PgHdr *pB){.
3120: 20 20 50 67 48 64 72 20 72 65 73 75 6c 74 2c 20    PgHdr result, 
3130: 2a 70 54 61 69 6c 3b 0a 20 20 70 54 61 69 6c 20  *pTail;.  pTail 
3140: 3d 20 26 72 65 73 75 6c 74 3b 0a 20 20 77 68 69  = &result;.  whi
3150: 6c 65 28 20 70 41 20 26 26 20 70 42 20 29 7b 0a  le( pA && pB ){.
3160: 20 20 20 20 69 66 28 20 70 41 2d 3e 70 67 6e 6f      if( pA->pgno
3170: 3c 70 42 2d 3e 70 67 6e 6f 20 29 7b 0a 20 20 20  <pB->pgno ){.   
3180: 20 20 20 70 54 61 69 6c 2d 3e 70 44 69 72 74 79     pTail->pDirty
3190: 20 3d 20 70 41 3b 0a 20 20 20 20 20 20 70 54 61   = pA;.      pTa
31a0: 69 6c 20 3d 20 70 41 3b 0a 20 20 20 20 20 20 70  il = pA;.      p
31b0: 41 20 3d 20 70 41 2d 3e 70 44 69 72 74 79 3b 0a  A = pA->pDirty;.
31c0: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
31d0: 20 70 54 61 69 6c 2d 3e 70 44 69 72 74 79 20 3d   pTail->pDirty =
31e0: 20 70 42 3b 0a 20 20 20 20 20 20 70 54 61 69 6c   pB;.      pTail
31f0: 20 3d 20 70 42 3b 0a 20 20 20 20 20 20 70 42 20   = pB;.      pB 
3200: 3d 20 70 42 2d 3e 70 44 69 72 74 79 3b 0a 20 20  = pB->pDirty;.  
3210: 20 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20 70 41    }.  }.  if( pA
3220: 20 29 7b 0a 20 20 20 20 70 54 61 69 6c 2d 3e 70   ){.    pTail->p
3230: 44 69 72 74 79 20 3d 20 70 41 3b 0a 20 20 7d 65  Dirty = pA;.  }e
3240: 6c 73 65 20 69 66 28 20 70 42 20 29 7b 0a 20 20  lse if( pB ){.  
3250: 20 20 70 54 61 69 6c 2d 3e 70 44 69 72 74 79 20    pTail->pDirty 
3260: 3d 20 70 42 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  = pB;.  }else{. 
3270: 20 20 20 70 54 61 69 6c 2d 3e 70 44 69 72 74 79     pTail->pDirty
3280: 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 72 65 74 75   = 0;.  }.  retu
3290: 72 6e 20 72 65 73 75 6c 74 2e 70 44 69 72 74 79  rn result.pDirty
32a0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 6f 72 74 20  ;.}../*.** Sort 
32b0: 74 68 65 20 6c 69 73 74 20 6f 66 20 70 61 67 65  the list of page
32c0: 73 20 69 6e 20 61 63 63 65 6e 64 69 6e 67 20 6f  s in accending o
32d0: 72 64 65 72 20 62 79 20 70 67 6e 6f 2e 20 20 50  rder by pgno.  P
32e0: 61 67 65 73 20 61 72 65 0a 2a 2a 20 63 6f 6e 6e  ages are.** conn
32f0: 65 63 74 65 64 20 62 79 20 70 44 69 72 74 79 20  ected by pDirty 
3300: 70 6f 69 6e 74 65 72 73 2e 20 20 54 68 65 20 70  pointers.  The p
3310: 44 69 72 74 79 50 72 65 76 20 70 6f 69 6e 74 65  DirtyPrev pointe
3320: 72 73 20 61 72 65 0a 2a 2a 20 63 6f 72 72 75 70  rs are.** corrup
3330: 74 65 64 20 62 79 20 74 68 69 73 20 73 6f 72 74  ted by this sort
3340: 2e 0a 2a 2a 0a 2a 2a 20 53 69 6e 63 65 20 74 68  ..**.** Since th
3350: 65 72 65 20 63 61 6e 6e 6f 74 20 62 65 20 6d 6f  ere cannot be mo
3360: 72 65 20 74 68 61 6e 20 32 5e 33 31 20 64 69 73  re than 2^31 dis
3370: 74 69 6e 63 74 20 70 61 67 65 73 20 69 6e 20 61  tinct pages in a
3380: 20 64 61 74 61 62 61 73 65 2c 0a 2a 2a 20 74 68   database,.** th
3390: 65 72 65 20 63 61 6e 6e 6f 74 20 62 65 20 6d 6f  ere cannot be mo
33a0: 72 65 20 74 68 61 6e 20 33 31 20 62 75 63 6b 65  re than 31 bucke
33b0: 74 73 20 72 65 71 75 69 72 65 64 20 62 79 20 74  ts required by t
33c0: 68 65 20 6d 65 72 67 65 20 73 6f 72 74 65 72 2e  he merge sorter.
33d0: 0a 2a 2a 20 4f 6e 65 20 65 78 74 72 61 20 62 75  .** One extra bu
33e0: 63 6b 65 74 20 69 73 20 61 64 64 65 64 20 74 6f  cket is added to
33f0: 20 63 61 74 63 68 20 6f 76 65 72 66 6c 6f 77 20   catch overflow 
3400: 69 6e 20 63 61 73 65 20 73 6f 6d 65 74 68 69 6e  in case somethin
3410: 67 0a 2a 2a 20 65 76 65 72 20 63 68 61 6e 67 65  g.** ever change
3420: 73 20 74 6f 20 6d 61 6b 65 20 74 68 65 20 70 72  s to make the pr
3430: 65 76 69 6f 75 73 20 73 65 6e 74 65 6e 63 65 20  evious sentence 
3440: 69 6e 63 6f 72 72 65 63 74 2e 0a 2a 2f 0a 23 64  incorrect..*/.#d
3450: 65 66 69 6e 65 20 4e 5f 53 4f 52 54 5f 42 55 43  efine N_SORT_BUC
3460: 4b 45 54 20 20 33 32 0a 73 74 61 74 69 63 20 50  KET  32.static P
3470: 67 48 64 72 20 2a 70 63 61 63 68 65 53 6f 72 74  gHdr *pcacheSort
3480: 44 69 72 74 79 4c 69 73 74 28 50 67 48 64 72 20  DirtyList(PgHdr 
3490: 2a 70 49 6e 29 7b 0a 20 20 50 67 48 64 72 20 2a  *pIn){.  PgHdr *
34a0: 61 5b 4e 5f 53 4f 52 54 5f 42 55 43 4b 45 54 5d  a[N_SORT_BUCKET]
34b0: 2c 20 2a 70 3b 0a 20 20 69 6e 74 20 69 3b 0a 20  , *p;.  int i;. 
34c0: 20 6d 65 6d 73 65 74 28 61 2c 20 30 2c 20 73 69   memset(a, 0, si
34d0: 7a 65 6f 66 28 61 29 29 3b 0a 20 20 77 68 69 6c  zeof(a));.  whil
34e0: 65 28 20 70 49 6e 20 29 7b 0a 20 20 20 20 70 20  e( pIn ){.    p 
34f0: 3d 20 70 49 6e 3b 0a 20 20 20 20 70 49 6e 20 3d  = pIn;.    pIn =
3500: 20 70 2d 3e 70 44 69 72 74 79 3b 0a 20 20 20 20   p->pDirty;.    
3510: 70 2d 3e 70 44 69 72 74 79 20 3d 20 30 3b 0a 20  p->pDirty = 0;. 
3520: 20 20 20 66 6f 72 28 69 3d 30 3b 20 41 4c 57 41     for(i=0; ALWA
3530: 59 53 28 69 3c 4e 5f 53 4f 52 54 5f 42 55 43 4b  YS(i<N_SORT_BUCK
3540: 45 54 2d 31 29 3b 20 69 2b 2b 29 7b 0a 20 20 20  ET-1); i++){.   
3550: 20 20 20 69 66 28 20 61 5b 69 5d 3d 3d 30 20 29     if( a[i]==0 )
3560: 7b 0a 20 20 20 20 20 20 20 20 61 5b 69 5d 20 3d  {.        a[i] =
3570: 20 70 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61   p;.        brea
3580: 6b 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a  k;.      }else{.
3590: 20 20 20 20 20 20 20 20 70 20 3d 20 70 63 61 63          p = pcac
35a0: 68 65 4d 65 72 67 65 44 69 72 74 79 4c 69 73 74  heMergeDirtyList
35b0: 28 61 5b 69 5d 2c 20 70 29 3b 0a 20 20 20 20 20  (a[i], p);.     
35c0: 20 20 20 61 5b 69 5d 20 3d 20 30 3b 0a 20 20 20     a[i] = 0;.   
35d0: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69     }.    }.    i
35e0: 66 28 20 4e 45 56 45 52 28 69 3d 3d 4e 5f 53 4f  f( NEVER(i==N_SO
35f0: 52 54 5f 42 55 43 4b 45 54 2d 31 29 20 29 7b 0a  RT_BUCKET-1) ){.
3600: 20 20 20 20 20 20 2f 2a 20 54 6f 20 67 65 74 20        /* To get 
3610: 68 65 72 65 2c 20 74 68 65 72 65 20 6e 65 65 64  here, there need
3620: 20 74 6f 20 62 65 20 32 5e 28 4e 5f 53 4f 52 54   to be 2^(N_SORT
3630: 5f 42 55 43 4b 45 54 29 20 65 6c 65 6d 65 6e 74  _BUCKET) element
3640: 73 20 69 6e 0a 20 20 20 20 20 20 2a 2a 20 74 68  s in.      ** th
3650: 65 20 69 6e 70 75 74 20 6c 69 73 74 2e 20 20 42  e input list.  B
3660: 75 74 20 74 68 61 74 20 69 73 20 69 6d 70 6f 73  ut that is impos
3670: 73 69 62 6c 65 2e 0a 20 20 20 20 20 20 2a 2f 0a  sible..      */.
3680: 20 20 20 20 20 20 61 5b 69 5d 20 3d 20 70 63 61        a[i] = pca
3690: 63 68 65 4d 65 72 67 65 44 69 72 74 79 4c 69 73  cheMergeDirtyLis
36a0: 74 28 61 5b 69 5d 2c 20 70 29 3b 0a 20 20 20 20  t(a[i], p);.    
36b0: 7d 0a 20 20 7d 0a 20 20 70 20 3d 20 61 5b 30 5d  }.  }.  p = a[0]
36c0: 3b 0a 20 20 66 6f 72 28 69 3d 31 3b 20 69 3c 4e  ;.  for(i=1; i<N
36d0: 5f 53 4f 52 54 5f 42 55 43 4b 45 54 3b 20 69 2b  _SORT_BUCKET; i+
36e0: 2b 29 7b 0a 20 20 20 20 70 20 3d 20 70 63 61 63  +){.    p = pcac
36f0: 68 65 4d 65 72 67 65 44 69 72 74 79 4c 69 73 74  heMergeDirtyList
3700: 28 70 2c 20 61 5b 69 5d 29 3b 0a 20 20 7d 0a 20  (p, a[i]);.  }. 
3710: 20 72 65 74 75 72 6e 20 70 3b 0a 7d 0a 0a 2f 2a   return p;.}../*
3720: 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20 6c 69 73  .** Return a lis
3730: 74 20 6f 66 20 61 6c 6c 20 64 69 72 74 79 20 70  t of all dirty p
3740: 61 67 65 73 20 69 6e 20 74 68 65 20 63 61 63 68  ages in the cach
3750: 65 2c 20 73 6f 72 74 65 64 20 62 79 20 70 61 67  e, sorted by pag
3760: 65 20 6e 75 6d 62 65 72 2e 0a 2a 2f 0a 50 67 48  e number..*/.PgH
3770: 64 72 20 2a 73 71 6c 69 74 65 33 50 63 61 63 68  dr *sqlite3Pcach
3780: 65 44 69 72 74 79 4c 69 73 74 28 50 43 61 63 68  eDirtyList(PCach
3790: 65 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 50 67  e *pCache){.  Pg
37a0: 48 64 72 20 2a 70 3b 0a 20 20 66 6f 72 28 70 3d  Hdr *p;.  for(p=
37b0: 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 3b 20  pCache->pDirty; 
37c0: 70 3b 20 70 3d 70 2d 3e 70 44 69 72 74 79 4e 65  p; p=p->pDirtyNe
37d0: 78 74 29 7b 0a 20 20 20 20 70 2d 3e 70 44 69 72  xt){.    p->pDir
37e0: 74 79 20 3d 20 70 2d 3e 70 44 69 72 74 79 4e 65  ty = p->pDirtyNe
37f0: 78 74 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  xt;.  }.  return
3800: 20 70 63 61 63 68 65 53 6f 72 74 44 69 72 74 79   pcacheSortDirty
3810: 4c 69 73 74 28 70 43 61 63 68 65 2d 3e 70 44 69  List(pCache->pDi
3820: 72 74 79 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20  rty);.}../* .** 
3830: 52 65 74 75 72 6e 20 74 68 65 20 74 6f 74 61 6c  Return the total
3840: 20 6e 75 6d 62 65 72 20 6f 66 20 72 65 66 65 72   number of refer
3850: 65 6e 63 65 64 20 70 61 67 65 73 20 68 65 6c 64  enced pages held
3860: 20 62 79 20 74 68 65 20 63 61 63 68 65 2e 0a 2a   by the cache..*
3870: 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 50 63 61  /.int sqlite3Pca
3880: 63 68 65 52 65 66 43 6f 75 6e 74 28 50 43 61 63  cheRefCount(PCac
3890: 68 65 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 72  he *pCache){.  r
38a0: 65 74 75 72 6e 20 70 43 61 63 68 65 2d 3e 6e 52  eturn pCache->nR
38b0: 65 66 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74  ef;.}../*.** Ret
38c0: 75 72 6e 20 74 68 65 20 6e 75 6d 62 65 72 20 6f  urn the number o
38d0: 66 20 72 65 66 65 72 65 6e 63 65 73 20 74 6f 20  f references to 
38e0: 74 68 65 20 70 61 67 65 20 73 75 70 70 6c 69 65  the page supplie
38f0: 64 20 61 73 20 61 6e 20 61 72 67 75 6d 65 6e 74  d as an argument
3900: 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33  ..*/.int sqlite3
3910: 50 63 61 63 68 65 50 61 67 65 52 65 66 63 6f 75  PcachePageRefcou
3920: 6e 74 28 50 67 48 64 72 20 2a 70 29 7b 0a 20 20  nt(PgHdr *p){.  
3930: 72 65 74 75 72 6e 20 70 2d 3e 6e 52 65 66 3b 0a  return p->nRef;.
3940: 7d 0a 0a 2f 2a 20 0a 2a 2a 20 52 65 74 75 72 6e  }../* .** Return
3950: 20 74 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65   the total numbe
3960: 72 20 6f 66 20 70 61 67 65 73 20 69 6e 20 74 68  r of pages in th
3970: 65 20 63 61 63 68 65 2e 0a 2a 2f 0a 69 6e 74 20  e cache..*/.int 
3980: 73 71 6c 69 74 65 33 50 63 61 63 68 65 50 61 67  sqlite3PcachePag
3990: 65 63 6f 75 6e 74 28 50 43 61 63 68 65 20 2a 70  ecount(PCache *p
39a0: 43 61 63 68 65 29 7b 0a 20 20 69 6e 74 20 6e 50  Cache){.  int nP
39b0: 61 67 65 20 3d 20 30 3b 0a 20 20 69 66 28 20 70  age = 0;.  if( p
39c0: 43 61 63 68 65 2d 3e 70 43 61 63 68 65 20 29 7b  Cache->pCache ){
39d0: 0a 20 20 20 20 6e 50 61 67 65 20 3d 20 73 71 6c  .    nPage = sql
39e0: 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67  ite3GlobalConfig
39f0: 2e 70 63 61 63 68 65 2e 78 50 61 67 65 63 6f 75  .pcache.xPagecou
3a00: 6e 74 28 70 43 61 63 68 65 2d 3e 70 43 61 63 68  nt(pCache->pCach
3a10: 65 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  e);.  }.  return
3a20: 20 6e 50 61 67 65 3b 0a 7d 0a 0a 23 69 66 64 65   nPage;.}..#ifde
3a30: 66 20 53 51 4c 49 54 45 5f 54 45 53 54 0a 2f 2a  f SQLITE_TEST./*
3a40: 0a 2a 2a 20 47 65 74 20 74 68 65 20 73 75 67 67  .** Get the sugg
3a50: 65 73 74 65 64 20 63 61 63 68 65 2d 73 69 7a 65  ested cache-size
3a60: 20 76 61 6c 75 65 2e 0a 2a 2f 0a 69 6e 74 20 73   value..*/.int s
3a70: 71 6c 69 74 65 33 50 63 61 63 68 65 47 65 74 43  qlite3PcacheGetC
3a80: 61 63 68 65 73 69 7a 65 28 50 43 61 63 68 65 20  achesize(PCache 
3a90: 2a 70 43 61 63 68 65 29 7b 0a 20 20 72 65 74 75  *pCache){.  retu
3aa0: 72 6e 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 3b  rn pCache->nMax;
3ab0: 0a 7d 0a 23 65 6e 64 69 66 0a 0a 2f 2a 0a 2a 2a  .}.#endif../*.**
3ac0: 20 53 65 74 20 74 68 65 20 73 75 67 67 65 73 74   Set the suggest
3ad0: 65 64 20 63 61 63 68 65 2d 73 69 7a 65 20 76 61  ed cache-size va
3ae0: 6c 75 65 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c  lue..*/.void sql
3af0: 69 74 65 33 50 63 61 63 68 65 53 65 74 43 61 63  ite3PcacheSetCac
3b00: 68 65 73 69 7a 65 28 50 43 61 63 68 65 20 2a 70  hesize(PCache *p
3b10: 43 61 63 68 65 2c 20 69 6e 74 20 6d 78 50 61 67  Cache, int mxPag
3b20: 65 29 7b 0a 20 20 70 43 61 63 68 65 2d 3e 6e 4d  e){.  pCache->nM
3b30: 61 78 20 3d 20 6d 78 50 61 67 65 3b 0a 20 20 69  ax = mxPage;.  i
3b40: 66 28 20 70 43 61 63 68 65 2d 3e 70 43 61 63 68  f( pCache->pCach
3b50: 65 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33  e ){.    sqlite3
3b60: 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61  GlobalConfig.pca
3b70: 63 68 65 2e 78 43 61 63 68 65 73 69 7a 65 28 70  che.xCachesize(p
3b80: 43 61 63 68 65 2d 3e 70 43 61 63 68 65 2c 20 6d  Cache->pCache, m
3b90: 78 50 61 67 65 29 3b 0a 20 20 7d 0a 7d 0a 0a 23  xPage);.  }.}..#
3ba0: 69 66 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54  if defined(SQLIT
3bb0: 45 5f 43 48 45 43 4b 5f 50 41 47 45 53 29 20 7c  E_CHECK_PAGES) |
3bc0: 7c 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45  | defined(SQLITE
3bd0: 5f 44 45 42 55 47 29 0a 2f 2a 0a 2a 2a 20 46 6f  _DEBUG)./*.** Fo
3be0: 72 20 61 6c 6c 20 64 69 72 74 79 20 70 61 67 65  r all dirty page
3bf0: 73 20 63 75 72 72 65 6e 74 6c 79 20 69 6e 20 74  s currently in t
3c00: 68 65 20 63 61 63 68 65 2c 20 69 6e 76 6f 6b 65  he cache, invoke
3c10: 20 74 68 65 20 73 70 65 63 69 66 69 65 64 0a 2a   the specified.*
3c20: 2a 20 63 61 6c 6c 62 61 63 6b 2e 20 54 68 69 73  * callback. This
3c30: 20 69 73 20 6f 6e 6c 79 20 75 73 65 64 20 69 66   is only used if
3c40: 20 74 68 65 20 53 51 4c 49 54 45 5f 43 48 45 43   the SQLITE_CHEC
3c50: 4b 5f 50 41 47 45 53 20 6d 61 63 72 6f 20 69 73  K_PAGES macro is
3c60: 0a 2a 2a 20 64 65 66 69 6e 65 64 2e 0a 2a 2f 0a  .** defined..*/.
3c70: 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63 61 63  void sqlite3Pcac
3c80: 68 65 49 74 65 72 61 74 65 44 69 72 74 79 28 50  heIterateDirty(P
3c90: 43 61 63 68 65 20 2a 70 43 61 63 68 65 2c 20 76  Cache *pCache, v
3ca0: 6f 69 64 20 28 2a 78 49 74 65 72 29 28 50 67 48  oid (*xIter)(PgH
3cb0: 64 72 20 2a 29 29 7b 0a 20 20 50 67 48 64 72 20  dr *)){.  PgHdr 
3cc0: 2a 70 44 69 72 74 79 3b 0a 20 20 66 6f 72 28 70  *pDirty;.  for(p
3cd0: 44 69 72 74 79 3d 70 43 61 63 68 65 2d 3e 70 44  Dirty=pCache->pD
3ce0: 69 72 74 79 3b 20 70 44 69 72 74 79 3b 20 70 44  irty; pDirty; pD
3cf0: 69 72 74 79 3d 70 44 69 72 74 79 2d 3e 70 44 69  irty=pDirty->pDi
3d00: 72 74 79 4e 65 78 74 29 7b 0a 20 20 20 20 78 49  rtyNext){.    xI
3d10: 74 65 72 28 70 44 69 72 74 79 29 3b 0a 20 20 7d  ter(pDirty);.  }
3d20: 0a 7d 0a 23 65 6e 64 69 66 0a                    .}.#endif.