/ Hex Artifact Content
Login

Artifact b83d160ce81ca101f98f0d27498e6d6bd49f1599:


0000: 2f 2a 0a 2a 2a 20 32 30 30 38 20 41 75 67 75 73  /*.** 2008 Augus
0010: 74 20 30 35 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61  t 05.**.** The a
0020: 75 74 68 6f 72 20 64 69 73 63 6c 61 69 6d 73 20  uthor disclaims 
0030: 63 6f 70 79 72 69 67 68 74 20 74 6f 20 74 68 69  copyright to thi
0040: 73 20 73 6f 75 72 63 65 20 63 6f 64 65 2e 20 20  s source code.  
0050: 49 6e 20 70 6c 61 63 65 20 6f 66 0a 2a 2a 20 61  In place of.** a
0060: 20 6c 65 67 61 6c 20 6e 6f 74 69 63 65 2c 20 68   legal notice, h
0070: 65 72 65 20 69 73 20 61 20 62 6c 65 73 73 69 6e  ere is a blessin
0080: 67 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79 20  g:.**.**    May 
0090: 79 6f 75 20 64 6f 20 67 6f 6f 64 20 61 6e 64 20  you do good and 
00a0: 6e 6f 74 20 65 76 69 6c 2e 0a 2a 2a 20 20 20 20  not evil..**    
00b0: 4d 61 79 20 79 6f 75 20 66 69 6e 64 20 66 6f 72  May you find for
00c0: 67 69 76 65 6e 65 73 73 20 66 6f 72 20 79 6f 75  giveness for you
00d0: 72 73 65 6c 66 20 61 6e 64 20 66 6f 72 67 69 76  rself and forgiv
00e0: 65 20 6f 74 68 65 72 73 2e 0a 2a 2a 20 20 20 20  e others..**    
00f0: 4d 61 79 20 79 6f 75 20 73 68 61 72 65 20 66 72  May you share fr
0100: 65 65 6c 79 2c 20 6e 65 76 65 72 20 74 61 6b 69  eely, never taki
0110: 6e 67 20 6d 6f 72 65 20 74 68 61 6e 20 79 6f 75  ng more than you
0120: 20 67 69 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a   give..**.******
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 2a 2a 2a 0a 2a 2a 20 54 68 69 73 20 66 69 6c 65  ***.** This file
0180: 20 69 6d 70 6c 65 6d 65 6e 74 73 20 74 68 61 74   implements that
0190: 20 70 61 67 65 20 63 61 63 68 65 2e 0a 2a 2f 0a   page cache..*/.
01a0: 23 69 6e 63 6c 75 64 65 20 22 73 71 6c 69 74 65  #include "sqlite
01b0: 49 6e 74 2e 68 22 0a 0a 2f 2a 0a 2a 2a 20 41 20  Int.h"../*.** A 
01c0: 63 6f 6d 70 6c 65 74 65 20 70 61 67 65 20 63 61  complete page ca
01d0: 63 68 65 20 69 73 20 61 6e 20 69 6e 73 74 61 6e  che is an instan
01e0: 63 65 20 6f 66 20 74 68 69 73 20 73 74 72 75 63  ce of this struc
01f0: 74 75 72 65 2e 0a 2a 2f 0a 73 74 72 75 63 74 20  ture..*/.struct 
0200: 50 43 61 63 68 65 20 7b 0a 20 20 50 67 48 64 72  PCache {.  PgHdr
0210: 20 2a 70 44 69 72 74 79 2c 20 2a 70 44 69 72 74   *pDirty, *pDirt
0220: 79 54 61 69 6c 3b 20 20 20 20 20 20 20 20 20 2f  yTail;         /
0230: 2a 20 4c 69 73 74 20 6f 66 20 64 69 72 74 79 20  * List of dirty 
0240: 70 61 67 65 73 20 69 6e 20 4c 52 55 20 6f 72 64  pages in LRU ord
0250: 65 72 20 2a 2f 0a 20 20 50 67 48 64 72 20 2a 70  er */.  PgHdr *p
0260: 53 79 6e 63 65 64 3b 20 20 20 20 20 20 20 20 20  Synced;         
0270: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c              /* L
0280: 61 73 74 20 73 79 6e 63 65 64 20 70 61 67 65 20  ast synced page 
0290: 69 6e 20 64 69 72 74 79 20 70 61 67 65 20 6c 69  in dirty page li
02a0: 73 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 52 65 66  st */.  int nRef
02b0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
02c0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
02d0: 75 6d 62 65 72 20 6f 66 20 72 65 66 65 72 65 6e  umber of referen
02e0: 63 65 64 20 70 61 67 65 73 20 2a 2f 0a 20 20 69  ced pages */.  i
02f0: 6e 74 20 73 7a 43 61 63 68 65 3b 20 20 20 20 20  nt szCache;     
0300: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0310: 20 20 20 2f 2a 20 43 6f 6e 66 69 67 75 72 65 64     /* Configured
0320: 20 63 61 63 68 65 20 73 69 7a 65 20 2a 2f 0a 20   cache size */. 
0330: 20 69 6e 74 20 73 7a 50 61 67 65 3b 20 20 20 20   int szPage;    
0340: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0350: 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
0360: 65 76 65 72 79 20 70 61 67 65 20 69 6e 20 74 68  every page in th
0370: 69 73 20 63 61 63 68 65 20 2a 2f 0a 20 20 69 6e  is cache */.  in
0380: 74 20 73 7a 45 78 74 72 61 3b 20 20 20 20 20 20  t szExtra;      
0390: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
03a0: 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 65 78 74    /* Size of ext
03b0: 72 61 20 73 70 61 63 65 20 66 6f 72 20 65 61 63  ra space for eac
03c0: 68 20 70 61 67 65 20 2a 2f 0a 20 20 75 38 20 62  h page */.  u8 b
03d0: 50 75 72 67 65 61 62 6c 65 3b 20 20 20 20 20 20  Purgeable;      
03e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
03f0: 2f 2a 20 54 72 75 65 20 69 66 20 70 61 67 65 73  /* True if pages
0400: 20 61 72 65 20 6f 6e 20 62 61 63 6b 69 6e 67 20   are on backing 
0410: 73 74 6f 72 65 20 2a 2f 0a 20 20 75 38 20 65 43  store */.  u8 eC
0420: 72 65 61 74 65 3b 20 20 20 20 20 20 20 20 20 20  reate;          
0430: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0440: 2a 20 65 43 72 65 61 74 65 20 76 61 6c 75 65 20  * eCreate value 
0450: 66 6f 72 20 66 6f 72 20 78 46 65 74 63 68 28 29  for for xFetch()
0460: 20 2a 2f 0a 20 20 69 6e 74 20 28 2a 78 53 74 72   */.  int (*xStr
0470: 65 73 73 29 28 76 6f 69 64 2a 2c 50 67 48 64 72  ess)(void*,PgHdr
0480: 2a 29 3b 20 20 20 20 20 20 20 2f 2a 20 43 61 6c  *);       /* Cal
0490: 6c 20 74 6f 20 74 72 79 20 6d 61 6b 65 20 61 20  l to try make a 
04a0: 70 61 67 65 20 63 6c 65 61 6e 20 2a 2f 0a 20 20  page clean */.  
04b0: 76 6f 69 64 20 2a 70 53 74 72 65 73 73 3b 20 20  void *pStress;  
04c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
04d0: 20 20 20 20 2f 2a 20 41 72 67 75 6d 65 6e 74 20      /* Argument 
04e0: 74 6f 20 78 53 74 72 65 73 73 20 2a 2f 0a 20 20  to xStress */.  
04f0: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a  sqlite3_pcache *
0500: 70 43 61 63 68 65 3b 20 20 20 20 20 20 20 20 20  pCache;         
0510: 20 20 20 20 2f 2a 20 50 6c 75 67 67 61 62 6c 65      /* Pluggable
0520: 20 63 61 63 68 65 20 6d 6f 64 75 6c 65 20 2a 2f   cache module */
0530: 0a 20 20 50 67 48 64 72 20 2a 70 50 61 67 65 31  .  PgHdr *pPage1
0540: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
0550: 20 20 20 20 20 20 20 2f 2a 20 52 65 66 65 72 65         /* Refere
0560: 6e 63 65 20 74 6f 20 70 61 67 65 20 31 20 2a 2f  nce to page 1 */
0570: 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 53 6f 6d 65 20  .};../*.** Some 
0580: 6f 66 20 74 68 65 20 61 73 73 65 72 74 28 29 20  of the assert() 
0590: 6d 61 63 72 6f 73 20 69 6e 20 74 68 69 73 20 63  macros in this c
05a0: 6f 64 65 20 61 72 65 20 74 6f 6f 20 65 78 70 65  ode are too expe
05b0: 6e 73 69 76 65 20 74 6f 20 72 75 6e 0a 2a 2a 20  nsive to run.** 
05c0: 65 76 65 6e 20 64 75 72 69 6e 67 20 6e 6f 72 6d  even during norm
05d0: 61 6c 20 64 65 62 75 67 67 69 6e 67 2e 20 20 55  al debugging.  U
05e0: 73 65 20 74 68 65 6d 20 6f 6e 6c 79 20 72 61 72  se them only rar
05f0: 65 6c 79 20 6f 6e 20 6c 6f 6e 67 2d 72 75 6e 6e  ely on long-runn
0600: 69 6e 67 0a 2a 2a 20 74 65 73 74 73 2e 20 20 45  ing.** tests.  E
0610: 6e 61 62 6c 65 20 74 68 65 20 65 78 70 65 6e 73  nable the expens
0620: 69 76 65 20 61 73 73 65 72 74 73 20 75 73 69 6e  ive asserts usin
0630: 67 20 74 68 65 0a 2a 2a 20 2d 44 53 51 4c 49 54  g the.** -DSQLIT
0640: 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49  E_ENABLE_EXPENSI
0650: 56 45 5f 41 53 53 45 52 54 3d 31 20 63 6f 6d 70  VE_ASSERT=1 comp
0660: 69 6c 65 2d 74 69 6d 65 20 6f 70 74 69 6f 6e 2e  ile-time option.
0670: 0a 2a 2f 0a 23 69 66 64 65 66 20 53 51 4c 49 54  .*/.#ifdef SQLIT
0680: 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49  E_ENABLE_EXPENSI
0690: 56 45 5f 41 53 53 45 52 54 0a 23 20 64 65 66 69  VE_ASSERT.# defi
06a0: 6e 65 20 65 78 70 65 6e 73 69 76 65 5f 61 73 73  ne expensive_ass
06b0: 65 72 74 28 58 29 20 20 61 73 73 65 72 74 28 58  ert(X)  assert(X
06c0: 29 0a 23 65 6c 73 65 0a 23 20 64 65 66 69 6e 65  ).#else.# define
06d0: 20 65 78 70 65 6e 73 69 76 65 5f 61 73 73 65 72   expensive_asser
06e0: 74 28 58 29 0a 23 65 6e 64 69 66 0a 0a 2f 2a 2a  t(X).#endif../**
06f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0700: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0710: 20 4c 69 6e 6b 65 64 20 4c 69 73 74 20 4d 61 6e   Linked List Man
0720: 61 67 65 6d 65 6e 74 20 2a 2a 2a 2a 2a 2a 2a 2a  agement ********
0730: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f  ************/../
0740: 2a 20 41 6c 6c 6f 77 65 64 20 76 61 6c 75 65 73  * Allowed values
0750: 20 66 6f 72 20 73 65 63 6f 6e 64 20 61 72 67 75   for second argu
0760: 6d 65 6e 74 20 74 6f 20 70 63 61 63 68 65 4d 61  ment to pcacheMa
0770: 6e 61 67 65 44 69 72 74 79 4c 69 73 74 28 29 20  nageDirtyList() 
0780: 2a 2f 0a 23 64 65 66 69 6e 65 20 50 43 41 43 48  */.#define PCACH
0790: 45 5f 44 49 52 54 59 4c 49 53 54 5f 52 45 4d 4f  E_DIRTYLIST_REMO
07a0: 56 45 20 20 20 31 20 20 20 20 2f 2a 20 52 65 6d  VE   1    /* Rem
07b0: 6f 76 65 20 70 50 61 67 65 20 66 72 6f 6d 20 64  ove pPage from d
07c0: 69 72 74 79 20 6c 69 73 74 20 2a 2f 0a 23 64 65  irty list */.#de
07d0: 66 69 6e 65 20 50 43 41 43 48 45 5f 44 49 52 54  fine PCACHE_DIRT
07e0: 59 4c 49 53 54 5f 41 44 44 20 20 20 20 20 20 32  YLIST_ADD      2
07f0: 20 20 20 20 2f 2a 20 41 64 64 20 70 50 61 67 65      /* Add pPage
0800: 20 74 6f 20 74 68 65 20 64 69 72 74 79 20 6c 69   to the dirty li
0810: 73 74 20 2a 2f 0a 23 64 65 66 69 6e 65 20 50 43  st */.#define PC
0820: 41 43 48 45 5f 44 49 52 54 59 4c 49 53 54 5f 46  ACHE_DIRTYLIST_F
0830: 52 4f 4e 54 20 20 20 20 33 20 20 20 20 2f 2a 20  RONT    3    /* 
0840: 4d 6f 76 65 20 70 50 61 67 65 20 74 6f 20 74 68  Move pPage to th
0850: 65 20 66 72 6f 6e 74 20 6f 66 20 74 68 65 20 6c  e front of the l
0860: 69 73 74 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 4d 61  ist */../*.** Ma
0870: 6e 61 67 65 20 70 50 61 67 65 27 73 20 70 61 72  nage pPage's par
0880: 74 69 63 69 70 61 74 69 6f 6e 20 6f 6e 20 74 68  ticipation on th
0890: 65 20 64 69 72 74 79 20 6c 69 73 74 2e 20 20 42  e dirty list.  B
08a0: 69 74 73 20 6f 66 20 74 68 65 20 61 64 64 52 65  its of the addRe
08b0: 6d 6f 76 65 0a 2a 2a 20 61 72 67 75 6d 65 6e 74  move.** argument
08c0: 20 64 65 74 65 72 6d 69 6e 65 73 20 77 68 61 74   determines what
08d0: 20 6f 70 65 72 61 74 69 6f 6e 20 74 6f 20 64 6f   operation to do
08e0: 2e 20 20 54 68 65 20 30 78 30 31 20 62 69 74 20  .  The 0x01 bit 
08f0: 6d 65 61 6e 73 20 66 69 72 73 74 0a 2a 2a 20 72  means first.** r
0900: 65 6d 6f 76 65 20 70 50 61 67 65 20 66 72 6f 6d  emove pPage from
0910: 20 74 68 65 20 64 69 72 74 79 20 6c 69 73 74 2e   the dirty list.
0920: 20 20 54 68 65 20 30 78 30 32 20 6d 65 61 6e 73    The 0x02 means
0930: 20 61 64 64 20 70 50 61 67 65 20 62 61 63 6b 20   add pPage back 
0940: 74 6f 0a 2a 2a 20 74 68 65 20 64 69 72 74 79 20  to.** the dirty 
0950: 6c 69 73 74 2e 20 20 44 6f 69 6e 67 20 62 6f 74  list.  Doing bot
0960: 68 20 6d 6f 76 65 73 20 70 50 61 67 65 20 74 6f  h moves pPage to
0970: 20 74 68 65 20 66 72 6f 6e 74 20 6f 66 20 74 68   the front of th
0980: 65 20 64 69 72 74 79 20 6c 69 73 74 2e 0a 2a 2f  e dirty list..*/
0990: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61  .static void pca
09a0: 63 68 65 4d 61 6e 61 67 65 44 69 72 74 79 4c 69  cheManageDirtyLi
09b0: 73 74 28 50 67 48 64 72 20 2a 70 50 61 67 65 2c  st(PgHdr *pPage,
09c0: 20 75 38 20 61 64 64 52 65 6d 6f 76 65 29 7b 0a   u8 addRemove){.
09d0: 20 20 50 43 61 63 68 65 20 2a 70 20 3d 20 70 50    PCache *p = pP
09e0: 61 67 65 2d 3e 70 43 61 63 68 65 3b 0a 0a 20 20  age->pCache;..  
09f0: 69 66 28 20 61 64 64 52 65 6d 6f 76 65 20 26 20  if( addRemove & 
0a00: 50 43 41 43 48 45 5f 44 49 52 54 59 4c 49 53 54  PCACHE_DIRTYLIST
0a10: 5f 52 45 4d 4f 56 45 20 29 7b 0a 20 20 20 20 61  _REMOVE ){.    a
0a20: 73 73 65 72 74 28 20 70 50 61 67 65 2d 3e 70 44  ssert( pPage->pD
0a30: 69 72 74 79 4e 65 78 74 20 7c 7c 20 70 50 61 67  irtyNext || pPag
0a40: 65 3d 3d 70 2d 3e 70 44 69 72 74 79 54 61 69 6c  e==p->pDirtyTail
0a50: 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20   );.    assert( 
0a60: 70 50 61 67 65 2d 3e 70 44 69 72 74 79 50 72 65  pPage->pDirtyPre
0a70: 76 20 7c 7c 20 70 50 61 67 65 3d 3d 70 2d 3e 70  v || pPage==p->p
0a80: 44 69 72 74 79 20 29 3b 0a 20 20 0a 20 20 20 20  Dirty );.  .    
0a90: 2f 2a 20 55 70 64 61 74 65 20 74 68 65 20 50 43  /* Update the PC
0aa0: 61 63 68 65 31 2e 70 53 79 6e 63 65 64 20 76 61  ache1.pSynced va
0ab0: 72 69 61 62 6c 65 20 69 66 20 6e 65 63 65 73 73  riable if necess
0ac0: 61 72 79 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20  ary. */.    if( 
0ad0: 70 2d 3e 70 53 79 6e 63 65 64 3d 3d 70 50 61 67  p->pSynced==pPag
0ae0: 65 20 29 7b 0a 20 20 20 20 20 20 50 67 48 64 72  e ){.      PgHdr
0af0: 20 2a 70 53 79 6e 63 65 64 20 3d 20 70 50 61 67   *pSynced = pPag
0b00: 65 2d 3e 70 44 69 72 74 79 50 72 65 76 3b 0a 20  e->pDirtyPrev;. 
0b10: 20 20 20 20 20 77 68 69 6c 65 28 20 70 53 79 6e       while( pSyn
0b20: 63 65 64 20 26 26 20 28 70 53 79 6e 63 65 64 2d  ced && (pSynced-
0b30: 3e 66 6c 61 67 73 26 50 47 48 44 52 5f 4e 45 45  >flags&PGHDR_NEE
0b40: 44 5f 53 59 4e 43 29 20 29 7b 0a 20 20 20 20 20  D_SYNC) ){.     
0b50: 20 20 20 70 53 79 6e 63 65 64 20 3d 20 70 53 79     pSynced = pSy
0b60: 6e 63 65 64 2d 3e 70 44 69 72 74 79 50 72 65 76  nced->pDirtyPrev
0b70: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
0b80: 70 2d 3e 70 53 79 6e 63 65 64 20 3d 20 70 53 79  p->pSynced = pSy
0b90: 6e 63 65 64 3b 0a 20 20 20 20 7d 0a 20 20 0a 20  nced;.    }.  . 
0ba0: 20 20 20 69 66 28 20 70 50 61 67 65 2d 3e 70 44     if( pPage->pD
0bb0: 69 72 74 79 4e 65 78 74 20 29 7b 0a 20 20 20 20  irtyNext ){.    
0bc0: 20 20 70 50 61 67 65 2d 3e 70 44 69 72 74 79 4e    pPage->pDirtyN
0bd0: 65 78 74 2d 3e 70 44 69 72 74 79 50 72 65 76 20  ext->pDirtyPrev 
0be0: 3d 20 70 50 61 67 65 2d 3e 70 44 69 72 74 79 50  = pPage->pDirtyP
0bf0: 72 65 76 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  rev;.    }else{.
0c00: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70 50        assert( pP
0c10: 61 67 65 3d 3d 70 2d 3e 70 44 69 72 74 79 54 61  age==p->pDirtyTa
0c20: 69 6c 20 29 3b 0a 20 20 20 20 20 20 70 2d 3e 70  il );.      p->p
0c30: 44 69 72 74 79 54 61 69 6c 20 3d 20 70 50 61 67  DirtyTail = pPag
0c40: 65 2d 3e 70 44 69 72 74 79 50 72 65 76 3b 0a 20  e->pDirtyPrev;. 
0c50: 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70 50 61     }.    if( pPa
0c60: 67 65 2d 3e 70 44 69 72 74 79 50 72 65 76 20 29  ge->pDirtyPrev )
0c70: 7b 0a 20 20 20 20 20 20 70 50 61 67 65 2d 3e 70  {.      pPage->p
0c80: 44 69 72 74 79 50 72 65 76 2d 3e 70 44 69 72 74  DirtyPrev->pDirt
0c90: 79 4e 65 78 74 20 3d 20 70 50 61 67 65 2d 3e 70  yNext = pPage->p
0ca0: 44 69 72 74 79 4e 65 78 74 3b 0a 20 20 20 20 7d  DirtyNext;.    }
0cb0: 65 6c 73 65 7b 0a 20 20 20 20 20 20 61 73 73 65  else{.      asse
0cc0: 72 74 28 20 70 50 61 67 65 3d 3d 70 2d 3e 70 44  rt( pPage==p->pD
0cd0: 69 72 74 79 20 29 3b 0a 20 20 20 20 20 20 70 2d  irty );.      p-
0ce0: 3e 70 44 69 72 74 79 20 3d 20 70 50 61 67 65 2d  >pDirty = pPage-
0cf0: 3e 70 44 69 72 74 79 4e 65 78 74 3b 0a 20 20 20  >pDirtyNext;.   
0d00: 20 20 20 69 66 28 20 70 2d 3e 70 44 69 72 74 79     if( p->pDirty
0d10: 3d 3d 30 20 26 26 20 70 2d 3e 62 50 75 72 67 65  ==0 && p->bPurge
0d20: 61 62 6c 65 20 29 7b 0a 20 20 20 20 20 20 20 20  able ){.        
0d30: 61 73 73 65 72 74 28 20 70 2d 3e 65 43 72 65 61  assert( p->eCrea
0d40: 74 65 3d 3d 31 20 29 3b 0a 20 20 20 20 20 20 20  te==1 );.       
0d50: 20 70 2d 3e 65 43 72 65 61 74 65 20 3d 20 32 3b   p->eCreate = 2;
0d60: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
0d70: 20 20 20 70 50 61 67 65 2d 3e 70 44 69 72 74 79     pPage->pDirty
0d80: 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20 20 70 50  Next = 0;.    pP
0d90: 61 67 65 2d 3e 70 44 69 72 74 79 50 72 65 76 20  age->pDirtyPrev 
0da0: 3d 20 30 3b 0a 20 20 7d 0a 20 20 69 66 28 20 61  = 0;.  }.  if( a
0db0: 64 64 52 65 6d 6f 76 65 20 26 20 50 43 41 43 48  ddRemove & PCACH
0dc0: 45 5f 44 49 52 54 59 4c 49 53 54 5f 41 44 44 20  E_DIRTYLIST_ADD 
0dd0: 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70  ){.    assert( p
0de0: 50 61 67 65 2d 3e 70 44 69 72 74 79 4e 65 78 74  Page->pDirtyNext
0df0: 3d 3d 30 20 26 26 20 70 50 61 67 65 2d 3e 70 44  ==0 && pPage->pD
0e00: 69 72 74 79 50 72 65 76 3d 3d 30 20 26 26 20 70  irtyPrev==0 && p
0e10: 2d 3e 70 44 69 72 74 79 21 3d 70 50 61 67 65 20  ->pDirty!=pPage 
0e20: 29 3b 0a 20 20 0a 20 20 20 20 70 50 61 67 65 2d  );.  .    pPage-
0e30: 3e 70 44 69 72 74 79 4e 65 78 74 20 3d 20 70 2d  >pDirtyNext = p-
0e40: 3e 70 44 69 72 74 79 3b 0a 20 20 20 20 69 66 28  >pDirty;.    if(
0e50: 20 70 50 61 67 65 2d 3e 70 44 69 72 74 79 4e 65   pPage->pDirtyNe
0e60: 78 74 20 29 7b 0a 20 20 20 20 20 20 61 73 73 65  xt ){.      asse
0e70: 72 74 28 20 70 50 61 67 65 2d 3e 70 44 69 72 74  rt( pPage->pDirt
0e80: 79 4e 65 78 74 2d 3e 70 44 69 72 74 79 50 72 65  yNext->pDirtyPre
0e90: 76 3d 3d 30 20 29 3b 0a 20 20 20 20 20 20 70 50  v==0 );.      pP
0ea0: 61 67 65 2d 3e 70 44 69 72 74 79 4e 65 78 74 2d  age->pDirtyNext-
0eb0: 3e 70 44 69 72 74 79 50 72 65 76 20 3d 20 70 50  >pDirtyPrev = pP
0ec0: 61 67 65 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  age;.    }else{.
0ed0: 20 20 20 20 20 20 70 2d 3e 70 44 69 72 74 79 54        p->pDirtyT
0ee0: 61 69 6c 20 3d 20 70 50 61 67 65 3b 0a 20 20 20  ail = pPage;.   
0ef0: 20 20 20 69 66 28 20 70 2d 3e 62 50 75 72 67 65     if( p->bPurge
0f00: 61 62 6c 65 20 29 7b 0a 20 20 20 20 20 20 20 20  able ){.        
0f10: 61 73 73 65 72 74 28 20 70 2d 3e 65 43 72 65 61  assert( p->eCrea
0f20: 74 65 3d 3d 32 20 29 3b 0a 20 20 20 20 20 20 20  te==2 );.       
0f30: 20 70 2d 3e 65 43 72 65 61 74 65 20 3d 20 31 3b   p->eCreate = 1;
0f40: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
0f50: 20 20 20 70 2d 3e 70 44 69 72 74 79 20 3d 20 70     p->pDirty = p
0f60: 50 61 67 65 3b 0a 20 20 20 20 69 66 28 20 21 70  Page;.    if( !p
0f70: 2d 3e 70 53 79 6e 63 65 64 20 26 26 20 30 3d 3d  ->pSynced && 0==
0f80: 28 70 50 61 67 65 2d 3e 66 6c 61 67 73 26 50 47  (pPage->flags&PG
0f90: 48 44 52 5f 4e 45 45 44 5f 53 59 4e 43 29 20 29  HDR_NEED_SYNC) )
0fa0: 7b 0a 20 20 20 20 20 20 70 2d 3e 70 53 79 6e 63  {.      p->pSync
0fb0: 65 64 20 3d 20 70 50 61 67 65 3b 0a 20 20 20 20  ed = pPage;.    
0fc0: 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57  }.  }.}../*.** W
0fd0: 72 61 70 70 65 72 20 61 72 6f 75 6e 64 20 74 68  rapper around th
0fe0: 65 20 70 6c 75 67 67 61 62 6c 65 20 63 61 63 68  e pluggable cach
0ff0: 65 73 20 78 55 6e 70 69 6e 20 6d 65 74 68 6f 64  es xUnpin method
1000: 2e 20 49 66 20 74 68 65 20 63 61 63 68 65 20 69  . If the cache i
1010: 73 0a 2a 2a 20 62 65 69 6e 67 20 75 73 65 64 20  s.** being used 
1020: 66 6f 72 20 61 6e 20 69 6e 2d 6d 65 6d 6f 72 79  for an in-memory
1030: 20 64 61 74 61 62 61 73 65 2c 20 74 68 69 73 20   database, this 
1040: 66 75 6e 63 74 69 6f 6e 20 69 73 20 61 20 6e 6f  function is a no
1050: 2d 6f 70 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  -op..*/.static v
1060: 6f 69 64 20 70 63 61 63 68 65 55 6e 70 69 6e 28  oid pcacheUnpin(
1070: 50 67 48 64 72 20 2a 70 29 7b 0a 20 20 69 66 28  PgHdr *p){.  if(
1080: 20 70 2d 3e 70 43 61 63 68 65 2d 3e 62 50 75 72   p->pCache->bPur
1090: 67 65 61 62 6c 65 20 29 7b 0a 20 20 20 20 69 66  geable ){.    if
10a0: 28 20 70 2d 3e 70 67 6e 6f 3d 3d 31 20 29 7b 0a  ( p->pgno==1 ){.
10b0: 20 20 20 20 20 20 70 2d 3e 70 43 61 63 68 65 2d        p->pCache-
10c0: 3e 70 50 61 67 65 31 20 3d 20 30 3b 0a 20 20 20  >pPage1 = 0;.   
10d0: 20 7d 0a 20 20 20 20 73 71 6c 69 74 65 33 47 6c   }.    sqlite3Gl
10e0: 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68  obalConfig.pcach
10f0: 65 32 2e 78 55 6e 70 69 6e 28 70 2d 3e 70 43 61  e2.xUnpin(p->pCa
1100: 63 68 65 2d 3e 70 43 61 63 68 65 2c 20 70 2d 3e  che->pCache, p->
1110: 70 50 61 67 65 2c 20 30 29 3b 0a 20 20 7d 0a 7d  pPage, 0);.  }.}
1120: 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70 75 74 65 20  ../*.** Compute 
1130: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 61  the number of pa
1140: 67 65 73 20 6f 66 20 63 61 63 68 65 20 72 65 71  ges of cache req
1150: 75 65 73 74 65 64 2e 0a 2a 2f 0a 73 74 61 74 69  uested..*/.stati
1160: 63 20 69 6e 74 20 6e 75 6d 62 65 72 4f 66 43 61  c int numberOfCa
1170: 63 68 65 50 61 67 65 73 28 50 43 61 63 68 65 20  chePages(PCache 
1180: 2a 70 29 7b 0a 20 20 69 66 28 20 70 2d 3e 73 7a  *p){.  if( p->sz
1190: 43 61 63 68 65 3e 3d 30 20 29 7b 0a 20 20 20 20  Cache>=0 ){.    
11a0: 72 65 74 75 72 6e 20 70 2d 3e 73 7a 43 61 63 68  return p->szCach
11b0: 65 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  e;.  }else{.    
11c0: 72 65 74 75 72 6e 20 28 69 6e 74 29 28 28 2d 31  return (int)((-1
11d0: 30 32 34 2a 28 69 36 34 29 70 2d 3e 73 7a 43 61  024*(i64)p->szCa
11e0: 63 68 65 29 2f 28 70 2d 3e 73 7a 50 61 67 65 2b  che)/(p->szPage+
11f0: 70 2d 3e 73 7a 45 78 74 72 61 29 29 3b 0a 20 20  p->szExtra));.  
1200: 7d 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  }.}../**********
1210: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1220: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1230: 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 47 65 6e 65 72 61  ********* Genera
1240: 6c 20 49 6e 74 65 72 66 61 63 65 73 20 2a 2a 2a  l Interfaces ***
1250: 2a 2a 2a 0a 2a 2a 0a 2a 2a 20 49 6e 69 74 69 61  ***.**.** Initia
1260: 6c 69 7a 65 20 61 6e 64 20 73 68 75 74 64 6f 77  lize and shutdow
1270: 6e 20 74 68 65 20 70 61 67 65 20 63 61 63 68 65  n the page cache
1280: 20 73 75 62 73 79 73 74 65 6d 2e 20 4e 65 69 74   subsystem. Neit
1290: 68 65 72 20 6f 66 20 74 68 65 73 65 20 0a 2a 2a  her of these .**
12a0: 20 66 75 6e 63 74 69 6f 6e 73 20 61 72 65 20 74   functions are t
12b0: 68 72 65 61 64 73 61 66 65 2e 0a 2a 2f 0a 69 6e  hreadsafe..*/.in
12c0: 74 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 49  t sqlite3PcacheI
12d0: 6e 69 74 69 61 6c 69 7a 65 28 76 6f 69 64 29 7b  nitialize(void){
12e0: 0a 20 20 69 66 28 20 73 71 6c 69 74 65 33 47 6c  .  if( sqlite3Gl
12f0: 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68  obalConfig.pcach
1300: 65 32 2e 78 49 6e 69 74 3d 3d 30 20 29 7b 0a 20  e2.xInit==0 ){. 
1310: 20 20 20 2f 2a 20 49 4d 50 4c 45 4d 45 4e 54 41     /* IMPLEMENTA
1320: 54 49 4f 4e 2d 4f 46 3a 20 52 2d 32 36 38 30 31  TION-OF: R-26801
1330: 2d 36 34 31 33 37 20 49 66 20 74 68 65 20 78 49  -64137 If the xI
1340: 6e 69 74 28 29 20 6d 65 74 68 6f 64 20 69 73 20  nit() method is 
1350: 4e 55 4c 4c 2c 20 74 68 65 6e 20 74 68 65 0a 20  NULL, then the. 
1360: 20 20 20 2a 2a 20 62 75 69 6c 74 2d 69 6e 20 64     ** built-in d
1370: 65 66 61 75 6c 74 20 70 61 67 65 20 63 61 63 68  efault page cach
1380: 65 20 69 73 20 75 73 65 64 20 69 6e 73 74 65 61  e is used instea
1390: 64 20 6f 66 20 74 68 65 20 61 70 70 6c 69 63 61  d of the applica
13a0: 74 69 6f 6e 20 64 65 66 69 6e 65 64 0a 20 20 20  tion defined.   
13b0: 20 2a 2a 20 70 61 67 65 20 63 61 63 68 65 2e 20   ** page cache. 
13c0: 2a 2f 0a 20 20 20 20 73 71 6c 69 74 65 33 50 43  */.    sqlite3PC
13d0: 61 63 68 65 53 65 74 44 65 66 61 75 6c 74 28 29  acheSetDefault()
13e0: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 73  ;.  }.  return s
13f0: 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66  qlite3GlobalConf
1400: 69 67 2e 70 63 61 63 68 65 32 2e 78 49 6e 69 74  ig.pcache2.xInit
1410: 28 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f  (sqlite3GlobalCo
1420: 6e 66 69 67 2e 70 63 61 63 68 65 32 2e 70 41 72  nfig.pcache2.pAr
1430: 67 29 3b 0a 7d 0a 76 6f 69 64 20 73 71 6c 69 74  g);.}.void sqlit
1440: 65 33 50 63 61 63 68 65 53 68 75 74 64 6f 77 6e  e3PcacheShutdown
1450: 28 76 6f 69 64 29 7b 0a 20 20 69 66 28 20 73 71  (void){.  if( sq
1460: 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69  lite3GlobalConfi
1470: 67 2e 70 63 61 63 68 65 32 2e 78 53 68 75 74 64  g.pcache2.xShutd
1480: 6f 77 6e 20 29 7b 0a 20 20 20 20 2f 2a 20 49 4d  own ){.    /* IM
1490: 50 4c 45 4d 45 4e 54 41 54 49 4f 4e 2d 4f 46 3a  PLEMENTATION-OF:
14a0: 20 52 2d 32 36 30 30 30 2d 35 36 35 38 39 20 54   R-26000-56589 T
14b0: 68 65 20 78 53 68 75 74 64 6f 77 6e 28 29 20 6d  he xShutdown() m
14c0: 65 74 68 6f 64 20 6d 61 79 20 62 65 20 4e 55 4c  ethod may be NUL
14d0: 4c 2e 20 2a 2f 0a 20 20 20 20 73 71 6c 69 74 65  L. */.    sqlite
14e0: 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63  3GlobalConfig.pc
14f0: 61 63 68 65 32 2e 78 53 68 75 74 64 6f 77 6e 28  ache2.xShutdown(
1500: 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e  sqlite3GlobalCon
1510: 66 69 67 2e 70 63 61 63 68 65 32 2e 70 41 72 67  fig.pcache2.pArg
1520: 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  );.  }.}../*.** 
1530: 52 65 74 75 72 6e 20 74 68 65 20 73 69 7a 65 20  Return the size 
1540: 69 6e 20 62 79 74 65 73 20 6f 66 20 61 20 50 43  in bytes of a PC
1550: 61 63 68 65 20 6f 62 6a 65 63 74 2e 0a 2a 2f 0a  ache object..*/.
1560: 69 6e 74 20 73 71 6c 69 74 65 33 50 63 61 63 68  int sqlite3Pcach
1570: 65 53 69 7a 65 28 76 6f 69 64 29 7b 20 72 65 74  eSize(void){ ret
1580: 75 72 6e 20 73 69 7a 65 6f 66 28 50 43 61 63 68  urn sizeof(PCach
1590: 65 29 3b 20 7d 0a 0a 2f 2a 0a 2a 2a 20 43 72 65  e); }../*.** Cre
15a0: 61 74 65 20 61 20 6e 65 77 20 50 43 61 63 68 65  ate a new PCache
15b0: 20 6f 62 6a 65 63 74 2e 20 53 74 6f 72 61 67 65   object. Storage
15c0: 20 73 70 61 63 65 20 74 6f 20 68 6f 6c 64 20 74   space to hold t
15d0: 68 65 20 6f 62 6a 65 63 74 0a 2a 2a 20 68 61 73  he object.** has
15e0: 20 61 6c 72 65 61 64 79 20 62 65 65 6e 20 61 6c   already been al
15f0: 6c 6f 63 61 74 65 64 20 61 6e 64 20 69 73 20 70  located and is p
1600: 61 73 73 65 64 20 69 6e 20 61 73 20 74 68 65 20  assed in as the 
1610: 70 20 70 6f 69 6e 74 65 72 2e 20 0a 2a 2a 20 54  p pointer. .** T
1620: 68 65 20 63 61 6c 6c 65 72 20 64 69 73 63 6f 76  he caller discov
1630: 65 72 73 20 68 6f 77 20 6d 75 63 68 20 73 70 61  ers how much spa
1640: 63 65 20 6e 65 65 64 73 20 74 6f 20 62 65 20 61  ce needs to be a
1650: 6c 6c 6f 63 61 74 65 64 20 62 79 20 0a 2a 2a 20  llocated by .** 
1660: 63 61 6c 6c 69 6e 67 20 73 71 6c 69 74 65 33 50  calling sqlite3P
1670: 63 61 63 68 65 53 69 7a 65 28 29 2e 0a 2a 2f 0a  cacheSize()..*/.
1680: 69 6e 74 20 73 71 6c 69 74 65 33 50 63 61 63 68  int sqlite3Pcach
1690: 65 4f 70 65 6e 28 0a 20 20 69 6e 74 20 73 7a 50  eOpen(.  int szP
16a0: 61 67 65 2c 20 20 20 20 20 20 20 20 20 20 20 20  age,            
16b0: 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66        /* Size of
16c0: 20 65 76 65 72 79 20 70 61 67 65 20 2a 2f 0a 20   every page */. 
16d0: 20 69 6e 74 20 73 7a 45 78 74 72 61 2c 20 20 20   int szExtra,   
16e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
16f0: 20 45 78 74 72 61 20 73 70 61 63 65 20 61 73 73   Extra space ass
1700: 6f 63 69 61 74 65 64 20 77 69 74 68 20 65 61 63  ociated with eac
1710: 68 20 70 61 67 65 20 2a 2f 0a 20 20 69 6e 74 20  h page */.  int 
1720: 62 50 75 72 67 65 61 62 6c 65 2c 20 20 20 20 20  bPurgeable,     
1730: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
1740: 20 69 66 20 70 61 67 65 73 20 61 72 65 20 6f 6e   if pages are on
1750: 20 62 61 63 6b 69 6e 67 20 73 74 6f 72 65 20 2a   backing store *
1760: 2f 0a 20 20 69 6e 74 20 28 2a 78 53 74 72 65 73  /.  int (*xStres
1770: 73 29 28 76 6f 69 64 2a 2c 50 67 48 64 72 2a 29  s)(void*,PgHdr*)
1780: 2c 2f 2a 20 43 61 6c 6c 20 74 6f 20 74 72 79 20  ,/* Call to try 
1790: 74 6f 20 6d 61 6b 65 20 70 61 67 65 73 20 63 6c  to make pages cl
17a0: 65 61 6e 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70  ean */.  void *p
17b0: 53 74 72 65 73 73 2c 20 20 20 20 20 20 20 20 20  Stress,         
17c0: 20 20 20 20 20 20 2f 2a 20 41 72 67 75 6d 65 6e        /* Argumen
17d0: 74 20 74 6f 20 78 53 74 72 65 73 73 20 2a 2f 0a  t to xStress */.
17e0: 20 20 50 43 61 63 68 65 20 2a 70 20 20 20 20 20    PCache *p     
17f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1800: 2a 20 50 72 65 61 6c 6c 6f 63 61 74 65 64 20 73  * Preallocated s
1810: 70 61 63 65 20 66 6f 72 20 74 68 65 20 50 43 61  pace for the PCa
1820: 63 68 65 20 2a 2f 0a 29 7b 0a 20 20 6d 65 6d 73  che */.){.  mems
1830: 65 74 28 70 2c 20 30 2c 20 73 69 7a 65 6f 66 28  et(p, 0, sizeof(
1840: 50 43 61 63 68 65 29 29 3b 0a 20 20 70 2d 3e 73  PCache));.  p->s
1850: 7a 50 61 67 65 20 3d 20 31 3b 0a 20 20 70 2d 3e  zPage = 1;.  p->
1860: 73 7a 45 78 74 72 61 20 3d 20 73 7a 45 78 74 72  szExtra = szExtr
1870: 61 3b 0a 20 20 70 2d 3e 62 50 75 72 67 65 61 62  a;.  p->bPurgeab
1880: 6c 65 20 3d 20 62 50 75 72 67 65 61 62 6c 65 3b  le = bPurgeable;
1890: 0a 20 20 70 2d 3e 65 43 72 65 61 74 65 20 3d 20  .  p->eCreate = 
18a0: 32 3b 0a 20 20 70 2d 3e 78 53 74 72 65 73 73 20  2;.  p->xStress 
18b0: 3d 20 78 53 74 72 65 73 73 3b 0a 20 20 70 2d 3e  = xStress;.  p->
18c0: 70 53 74 72 65 73 73 20 3d 20 70 53 74 72 65 73  pStress = pStres
18d0: 73 3b 0a 20 20 70 2d 3e 73 7a 43 61 63 68 65 20  s;.  p->szCache 
18e0: 3d 20 31 30 30 3b 0a 20 20 72 65 74 75 72 6e 20  = 100;.  return 
18f0: 73 71 6c 69 74 65 33 50 63 61 63 68 65 53 65 74  sqlite3PcacheSet
1900: 50 61 67 65 53 69 7a 65 28 70 2c 20 73 7a 50 61  PageSize(p, szPa
1910: 67 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 68  ge);.}../*.** Ch
1920: 61 6e 67 65 20 74 68 65 20 70 61 67 65 20 73 69  ange the page si
1930: 7a 65 20 66 6f 72 20 50 43 61 63 68 65 20 6f 62  ze for PCache ob
1940: 6a 65 63 74 2e 20 54 68 65 20 63 61 6c 6c 65 72  ject. The caller
1950: 20 6d 75 73 74 20 65 6e 73 75 72 65 20 74 68 61   must ensure tha
1960: 74 20 74 68 65 72 65 0a 2a 2a 20 61 72 65 20 6e  t there.** are n
1970: 6f 20 6f 75 74 73 74 61 6e 64 69 6e 67 20 70 61  o outstanding pa
1980: 67 65 20 72 65 66 65 72 65 6e 63 65 73 20 77 68  ge references wh
1990: 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  en this function
19a0: 20 69 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f 0a 69   is called..*/.i
19b0: 6e 74 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  nt sqlite3Pcache
19c0: 53 65 74 50 61 67 65 53 69 7a 65 28 50 43 61 63  SetPageSize(PCac
19d0: 68 65 20 2a 70 43 61 63 68 65 2c 20 69 6e 74 20  he *pCache, int 
19e0: 73 7a 50 61 67 65 29 7b 0a 20 20 61 73 73 65 72  szPage){.  asser
19f0: 74 28 20 70 43 61 63 68 65 2d 3e 6e 52 65 66 3d  t( pCache->nRef=
1a00: 3d 30 20 26 26 20 70 43 61 63 68 65 2d 3e 70 44  =0 && pCache->pD
1a10: 69 72 74 79 3d 3d 30 20 29 3b 0a 20 20 69 66 28  irty==0 );.  if(
1a20: 20 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 20   pCache->szPage 
1a30: 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 70  ){.    sqlite3_p
1a40: 63 61 63 68 65 20 2a 70 4e 65 77 3b 0a 20 20 20  cache *pNew;.   
1a50: 20 70 4e 65 77 20 3d 20 73 71 6c 69 74 65 33 47   pNew = sqlite3G
1a60: 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63  lobalConfig.pcac
1a70: 68 65 32 2e 78 43 72 65 61 74 65 28 0a 20 20 20  he2.xCreate(.   
1a80: 20 20 20 20 20 20 20 20 20 20 20 20 20 73 7a 50               szP
1a90: 61 67 65 2c 20 70 43 61 63 68 65 2d 3e 73 7a 45  age, pCache->szE
1aa0: 78 74 72 61 20 2b 20 52 4f 55 4e 44 38 28 73 69  xtra + ROUND8(si
1ab0: 7a 65 6f 66 28 50 67 48 64 72 29 29 2c 0a 20 20  zeof(PgHdr)),.  
1ac0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 43                pC
1ad0: 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65  ache->bPurgeable
1ae0: 0a 20 20 20 20 29 3b 0a 20 20 20 20 69 66 28 20  .    );.    if( 
1af0: 70 4e 65 77 3d 3d 30 20 29 20 72 65 74 75 72 6e  pNew==0 ) return
1b00: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
1b10: 20 20 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c     sqlite3Global
1b20: 43 6f 6e 66 69 67 2e 70 63 61 63 68 65 32 2e 78  Config.pcache2.x
1b30: 43 61 63 68 65 73 69 7a 65 28 70 4e 65 77 2c 20  Cachesize(pNew, 
1b40: 6e 75 6d 62 65 72 4f 66 43 61 63 68 65 50 61 67  numberOfCachePag
1b50: 65 73 28 70 43 61 63 68 65 29 29 3b 0a 20 20 20  es(pCache));.   
1b60: 20 69 66 28 20 70 43 61 63 68 65 2d 3e 70 43 61   if( pCache->pCa
1b70: 63 68 65 20 29 7b 0a 20 20 20 20 20 20 73 71 6c  che ){.      sql
1b80: 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67  ite3GlobalConfig
1b90: 2e 70 63 61 63 68 65 32 2e 78 44 65 73 74 72 6f  .pcache2.xDestro
1ba0: 79 28 70 43 61 63 68 65 2d 3e 70 43 61 63 68 65  y(pCache->pCache
1bb0: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 43 61  );.    }.    pCa
1bc0: 63 68 65 2d 3e 70 43 61 63 68 65 20 3d 20 70 4e  che->pCache = pN
1bd0: 65 77 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e  ew;.    pCache->
1be0: 70 50 61 67 65 31 20 3d 20 30 3b 0a 20 20 20 20  pPage1 = 0;.    
1bf0: 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 20 3d  pCache->szPage =
1c00: 20 73 7a 50 61 67 65 3b 0a 20 20 7d 0a 20 20 72   szPage;.  }.  r
1c10: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
1c20: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 72 79 20 74 6f  .}../*.** Try to
1c30: 20 6f 62 74 61 69 6e 20 61 20 70 61 67 65 20 66   obtain a page f
1c40: 72 6f 6d 20 74 68 65 20 63 61 63 68 65 2e 0a 2a  rom the cache..*
1c50: 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e  *.** This routin
1c60: 65 20 72 65 74 75 72 6e 73 20 61 20 70 6f 69 6e  e returns a poin
1c70: 74 65 72 20 74 6f 20 61 6e 20 73 71 6c 69 74 65  ter to an sqlite
1c80: 33 5f 70 63 61 63 68 65 5f 70 61 67 65 20 6f 62  3_pcache_page ob
1c90: 6a 65 63 74 20 69 66 0a 2a 2a 20 73 75 63 68 20  ject if.** such 
1ca0: 61 6e 20 6f 62 6a 65 63 74 20 69 73 20 61 6c 72  an object is alr
1cb0: 65 61 64 79 20 69 6e 20 63 61 63 68 65 2c 20 6f  eady in cache, o
1cc0: 72 20 69 66 20 61 20 6e 65 77 20 6f 6e 65 20 69  r if a new one i
1cd0: 73 20 63 72 65 61 74 65 64 2e 0a 2a 2a 20 54 68  s created..** Th
1ce0: 69 73 20 72 6f 75 74 69 6e 65 20 72 65 74 75 72  is routine retur
1cf0: 6e 73 20 61 20 4e 55 4c 4c 20 70 6f 69 6e 74 65  ns a NULL pointe
1d00: 72 20 69 66 20 74 68 65 20 6f 62 6a 65 63 74 20  r if the object 
1d10: 77 61 73 20 6e 6f 74 20 69 6e 20 63 61 63 68 65  was not in cache
1d20: 0a 2a 2a 20 61 6e 64 20 63 6f 75 6c 64 20 6e 6f  .** and could no
1d30: 74 20 62 65 20 63 72 65 61 74 65 64 2e 0a 2a 2a  t be created..**
1d40: 0a 2a 2a 20 54 68 65 20 63 72 65 61 74 65 46 6c  .** The createFl
1d50: 61 67 73 20 73 68 6f 75 6c 64 20 62 65 20 30 20  ags should be 0 
1d60: 74 6f 20 63 68 65 63 6b 20 66 6f 72 20 65 78 69  to check for exi
1d70: 73 74 69 6e 67 20 70 61 67 65 73 20 61 6e 64 20  sting pages and 
1d80: 73 68 6f 75 6c 64 0a 2a 2a 20 62 65 20 33 20 28  should.** be 3 (
1d90: 6e 6f 74 20 31 2c 20 62 75 74 20 33 29 20 74 6f  not 1, but 3) to
1da0: 20 74 72 79 20 74 6f 20 63 72 65 61 74 65 20 61   try to create a
1db0: 20 6e 65 77 20 70 61 67 65 2e 0a 2a 2a 0a 2a 2a   new page..**.**
1dc0: 20 49 66 20 74 68 65 20 63 72 65 61 74 65 46 6c   If the createFl
1dd0: 61 67 20 69 73 20 30 2c 20 74 68 65 6e 20 4e 55  ag is 0, then NU
1de0: 4c 4c 20 69 73 20 61 6c 77 61 79 73 20 72 65 74  LL is always ret
1df0: 75 72 6e 65 64 20 69 66 20 74 68 65 20 70 61 67  urned if the pag
1e00: 65 0a 2a 2a 20 69 73 20 6e 6f 74 20 61 6c 72 65  e.** is not alre
1e10: 61 64 79 20 69 6e 20 74 68 65 20 63 61 63 68 65  ady in the cache
1e20: 2e 20 20 49 66 20 63 72 65 61 74 65 46 6c 61 67  .  If createFlag
1e30: 20 69 73 20 31 2c 20 74 68 65 6e 20 61 20 6e 65   is 1, then a ne
1e40: 77 20 70 61 67 65 0a 2a 2a 20 69 73 20 63 72 65  w page.** is cre
1e50: 61 74 65 64 20 6f 6e 6c 79 20 69 66 20 74 68 61  ated only if tha
1e60: 74 20 63 61 6e 20 62 65 20 64 6f 6e 65 20 77 69  t can be done wi
1e70: 74 68 6f 75 74 20 73 70 69 6c 6c 69 6e 67 20 64  thout spilling d
1e80: 69 72 74 79 20 70 61 67 65 73 0a 2a 2a 20 61 6e  irty pages.** an
1e90: 64 20 77 69 74 68 6f 75 74 20 65 78 63 65 65 64  d without exceed
1ea0: 69 6e 67 20 74 68 65 20 63 61 63 68 65 20 73 69  ing the cache si
1eb0: 7a 65 20 6c 69 6d 69 74 2e 0a 2a 2a 0a 2a 2a 20  ze limit..**.** 
1ec0: 54 68 65 20 63 61 6c 6c 65 72 20 6e 65 65 64 73  The caller needs
1ed0: 20 74 6f 20 69 6e 76 6f 6b 65 20 73 71 6c 69 74   to invoke sqlit
1ee0: 65 33 50 63 61 63 68 65 46 65 74 63 68 46 69 6e  e3PcacheFetchFin
1ef0: 69 73 68 28 29 20 74 6f 20 70 72 6f 70 65 72 6c  ish() to properl
1f00: 79 0a 2a 2a 20 69 6e 69 74 69 61 6c 69 7a 65 20  y.** initialize 
1f10: 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63  the sqlite3_pcac
1f20: 68 65 5f 70 61 67 65 20 6f 62 6a 65 63 74 20 61  he_page object a
1f30: 6e 64 20 63 6f 6e 76 65 72 74 20 69 74 20 69 6e  nd convert it in
1f40: 74 6f 20 61 0a 2a 2a 20 50 67 48 64 72 20 6f 62  to a.** PgHdr ob
1f50: 6a 65 63 74 2e 20 20 54 68 65 20 73 71 6c 69 74  ject.  The sqlit
1f60: 65 33 50 63 61 63 68 65 46 65 74 63 68 28 29 20  e3PcacheFetch() 
1f70: 61 6e 64 20 73 71 6c 69 74 65 33 50 63 61 63 68  and sqlite3Pcach
1f80: 65 46 65 74 63 68 46 69 6e 69 73 68 28 29 0a 2a  eFetchFinish().*
1f90: 2a 20 72 6f 75 74 69 6e 65 73 20 61 72 65 20 73  * routines are s
1fa0: 70 6c 69 74 20 74 68 69 73 20 77 61 79 20 66 6f  plit this way fo
1fb0: 72 20 70 65 72 66 6f 72 6d 61 6e 63 65 20 72 65  r performance re
1fc0: 61 73 6f 6e 73 2e 20 57 68 65 6e 20 73 65 70 61  asons. When sepa
1fd0: 72 61 74 65 64 0a 2a 2a 20 74 68 65 79 20 63 61  rated.** they ca
1fe0: 6e 20 62 6f 74 68 20 28 75 73 75 61 6c 6c 79 29  n both (usually)
1ff0: 20 6f 70 65 72 61 74 65 20 77 69 74 68 6f 75 74   operate without
2000: 20 68 61 76 69 6e 67 20 74 6f 20 70 75 73 68 20   having to push 
2010: 76 61 6c 75 65 73 20 74 6f 0a 2a 2a 20 74 68 65  values to.** the
2020: 20 73 74 61 63 6b 20 6f 6e 20 65 6e 74 72 79 20   stack on entry 
2030: 61 6e 64 20 70 6f 70 20 74 68 65 6d 20 62 61 63  and pop them bac
2040: 6b 20 6f 66 66 20 6f 6e 20 65 78 69 74 2c 20 77  k off on exit, w
2050: 68 69 63 68 20 73 61 76 65 73 20 61 0a 2a 2a 20  hich saves a.** 
2060: 6c 6f 74 20 6f 66 20 70 75 73 68 69 6e 67 20 61  lot of pushing a
2070: 6e 64 20 70 6f 70 70 69 6e 67 2e 0a 2a 2f 0a 73  nd popping..*/.s
2080: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 5f 70 61  qlite3_pcache_pa
2090: 67 65 20 2a 73 71 6c 69 74 65 33 50 63 61 63 68  ge *sqlite3Pcach
20a0: 65 46 65 74 63 68 28 0a 20 20 50 43 61 63 68 65  eFetch(.  PCache
20b0: 20 2a 70 43 61 63 68 65 2c 20 20 20 20 20 20 20   *pCache,       
20c0: 2f 2a 20 4f 62 74 61 69 6e 20 74 68 65 20 70 61  /* Obtain the pa
20d0: 67 65 20 66 72 6f 6d 20 74 68 69 73 20 63 61 63  ge from this cac
20e0: 68 65 20 2a 2f 0a 20 20 50 67 6e 6f 20 70 67 6e  he */.  Pgno pgn
20f0: 6f 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  o,            /*
2100: 20 50 61 67 65 20 6e 75 6d 62 65 72 20 74 6f 20   Page number to 
2110: 6f 62 74 61 69 6e 20 2a 2f 0a 20 20 69 6e 74 20  obtain */.  int 
2120: 63 72 65 61 74 65 46 6c 61 67 20 20 20 20 20 20  createFlag      
2130: 20 20 2f 2a 20 49 66 20 74 72 75 65 2c 20 63 72    /* If true, cr
2140: 65 61 74 65 20 70 61 67 65 20 69 66 20 69 74 20  eate page if it 
2150: 64 6f 65 73 20 6e 6f 74 20 65 78 69 73 74 20 61  does not exist a
2160: 6c 72 65 61 64 79 20 2a 2f 0a 29 7b 0a 20 20 69  lready */.){.  i
2170: 6e 74 20 65 43 72 65 61 74 65 3b 0a 0a 20 20 61  nt eCreate;..  a
2180: 73 73 65 72 74 28 20 70 43 61 63 68 65 21 3d 30  ssert( pCache!=0
2190: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 43   );.  assert( pC
21a0: 61 63 68 65 2d 3e 70 43 61 63 68 65 21 3d 30 20  ache->pCache!=0 
21b0: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 63 72 65  );.  assert( cre
21c0: 61 74 65 46 6c 61 67 3d 3d 33 20 7c 7c 20 63 72  ateFlag==3 || cr
21d0: 65 61 74 65 46 6c 61 67 3d 3d 30 20 29 3b 0a 20  eateFlag==0 );. 
21e0: 20 61 73 73 65 72 74 28 20 70 67 6e 6f 3e 30 20   assert( pgno>0 
21f0: 29 3b 0a 0a 20 20 2f 2a 20 65 43 72 65 61 74 65  );..  /* eCreate
2200: 20 64 65 66 69 6e 65 73 20 77 68 61 74 20 74 6f   defines what to
2210: 20 64 6f 20 69 66 20 74 68 65 20 70 61 67 65 20   do if the page 
2220: 64 6f 65 73 20 6e 6f 74 20 65 78 69 73 74 2e 0a  does not exist..
2230: 20 20 2a 2a 20 20 20 20 30 20 20 20 20 20 44 6f    **    0     Do
2240: 20 6e 6f 74 20 61 6c 6c 6f 63 61 74 65 20 61 20   not allocate a 
2250: 6e 65 77 20 70 61 67 65 2e 20 20 28 63 72 65 61  new page.  (crea
2260: 74 65 46 6c 61 67 3d 3d 30 29 0a 20 20 2a 2a 20  teFlag==0).  ** 
2270: 20 20 20 31 20 20 20 20 20 41 6c 6c 6f 63 61 74     1     Allocat
2280: 65 20 61 20 6e 65 77 20 70 61 67 65 20 69 66 20  e a new page if 
2290: 64 6f 69 6e 67 20 73 6f 20 69 73 20 69 6e 65 78  doing so is inex
22a0: 70 65 6e 73 69 76 65 2e 0a 20 20 2a 2a 20 20 20  pensive..  **   
22b0: 20 20 20 20 20 20 20 28 63 72 65 61 74 65 46 6c         (createFl
22c0: 61 67 3d 3d 31 20 41 4e 44 20 62 50 75 72 67 65  ag==1 AND bPurge
22d0: 61 62 6c 65 20 41 4e 44 20 70 44 69 72 74 79 29  able AND pDirty)
22e0: 0a 20 20 2a 2a 20 20 20 20 32 20 20 20 20 20 41  .  **    2     A
22f0: 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 70 61  llocate a new pa
2300: 67 65 20 65 76 65 6e 20 69 74 20 64 6f 69 6e 67  ge even it doing
2310: 20 73 6f 20 69 73 20 64 69 66 66 69 63 75 6c 74   so is difficult
2320: 2e 0a 20 20 2a 2a 20 20 20 20 20 20 20 20 20 20  ..  **          
2330: 28 63 72 65 61 74 65 46 6c 61 67 3d 3d 31 20 41  (createFlag==1 A
2340: 4e 44 20 21 28 62 50 75 72 67 65 61 62 6c 65 20  ND !(bPurgeable 
2350: 41 4e 44 20 70 44 69 72 74 79 29 0a 20 20 2a 2f  AND pDirty).  */
2360: 0a 20 20 65 43 72 65 61 74 65 20 3d 20 63 72 65  .  eCreate = cre
2370: 61 74 65 46 6c 61 67 20 26 20 70 43 61 63 68 65  ateFlag & pCache
2380: 2d 3e 65 43 72 65 61 74 65 3b 0a 20 20 61 73 73  ->eCreate;.  ass
2390: 65 72 74 28 20 65 43 72 65 61 74 65 3d 3d 30 20  ert( eCreate==0 
23a0: 7c 7c 20 65 43 72 65 61 74 65 3d 3d 31 20 7c 7c  || eCreate==1 ||
23b0: 20 65 43 72 65 61 74 65 3d 3d 32 20 29 3b 0a 20   eCreate==2 );. 
23c0: 20 61 73 73 65 72 74 28 20 63 72 65 61 74 65 46   assert( createF
23d0: 6c 61 67 3d 3d 30 20 7c 7c 20 70 43 61 63 68 65  lag==0 || pCache
23e0: 2d 3e 65 43 72 65 61 74 65 3d 3d 65 43 72 65 61  ->eCreate==eCrea
23f0: 74 65 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  te );.  assert( 
2400: 63 72 65 61 74 65 46 6c 61 67 3d 3d 30 20 7c 7c  createFlag==0 ||
2410: 20 65 43 72 65 61 74 65 3d 3d 31 2b 28 21 70 43   eCreate==1+(!pC
2420: 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65  ache->bPurgeable
2430: 7c 7c 21 70 43 61 63 68 65 2d 3e 70 44 69 72 74  ||!pCache->pDirt
2440: 79 29 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 73  y) );.  return s
2450: 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66  qlite3GlobalConf
2460: 69 67 2e 70 63 61 63 68 65 32 2e 78 46 65 74 63  ig.pcache2.xFetc
2470: 68 28 70 43 61 63 68 65 2d 3e 70 43 61 63 68 65  h(pCache->pCache
2480: 2c 20 70 67 6e 6f 2c 20 65 43 72 65 61 74 65 29  , pgno, eCreate)
2490: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 74 68  ;.}../*.** If th
24a0: 65 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 46  e sqlite3PcacheF
24b0: 65 74 63 68 28 29 20 72 6f 75 74 69 6e 65 20 69  etch() routine i
24c0: 73 20 75 6e 61 62 6c 65 20 74 6f 20 61 6c 6c 6f  s unable to allo
24d0: 63 61 74 65 20 61 20 6e 65 77 0a 2a 2a 20 70 61  cate a new.** pa
24e0: 67 65 20 62 65 63 61 75 73 65 20 6e 65 77 20 63  ge because new c
24f0: 6c 65 61 6e 20 70 61 67 65 73 20 61 72 65 20 61  lean pages are a
2500: 76 61 69 6c 61 62 6c 65 20 66 6f 72 20 72 65 75  vailable for reu
2510: 73 65 20 61 6e 64 20 74 68 65 20 63 61 63 68 65  se and the cache
2520: 0a 2a 2a 20 73 69 7a 65 20 6c 69 6d 69 74 20 68  .** size limit h
2530: 61 73 20 62 65 65 6e 20 72 65 61 63 68 65 64 2c  as been reached,
2540: 20 74 68 65 6e 20 74 68 69 73 20 72 6f 75 74 69   then this routi
2550: 6e 65 20 63 61 6e 20 62 65 20 69 6e 76 6f 6b 65  ne can be invoke
2560: 64 20 74 6f 20 0a 2a 2a 20 74 72 79 20 68 61 72  d to .** try har
2570: 64 65 72 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20  der to allocate 
2580: 61 20 70 61 67 65 2e 20 20 54 68 69 73 20 72 6f  a page.  This ro
2590: 75 74 69 6e 65 20 6d 69 67 68 74 20 69 6e 76 6f  utine might invo
25a0: 6b 65 20 74 68 65 20 73 74 72 65 73 73 0a 2a 2a  ke the stress.**
25b0: 20 63 61 6c 6c 62 61 63 6b 20 74 6f 20 73 70 69   callback to spi
25c0: 6c 6c 20 64 69 72 74 79 20 70 61 67 65 73 20 74  ll dirty pages t
25d0: 6f 20 74 68 65 20 6a 6f 75 72 6e 61 6c 2e 20 20  o the journal.  
25e0: 49 74 20 77 69 6c 6c 20 74 68 65 6e 20 74 72 79  It will then try
25f0: 20 74 6f 0a 2a 2a 20 61 6c 6c 6f 63 61 74 65 20   to.** allocate 
2600: 74 68 65 20 6e 65 77 20 70 61 67 65 20 61 6e 64  the new page and
2610: 20 77 69 6c 6c 20 6f 6e 6c 79 20 66 61 69 6c 20   will only fail 
2620: 74 6f 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e 65  to allocate a ne
2630: 77 20 70 61 67 65 20 6f 6e 0a 2a 2a 20 61 6e 20  w page on.** an 
2640: 4f 4f 4d 20 65 72 72 6f 72 2e 0a 2a 2a 0a 2a 2a  OOM error..**.**
2650: 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 73 68   This routine sh
2660: 6f 75 6c 64 20 62 65 20 69 6e 76 6f 6b 65 64 20  ould be invoked 
2670: 6f 6e 6c 79 20 61 66 74 65 72 20 73 71 6c 69 74  only after sqlit
2680: 65 33 50 63 61 63 68 65 46 65 74 63 68 28 29 20  e3PcacheFetch() 
2690: 66 61 69 6c 73 2e 0a 2a 2f 0a 69 6e 74 20 73 71  fails..*/.int sq
26a0: 6c 69 74 65 33 50 63 61 63 68 65 46 65 74 63 68  lite3PcacheFetch
26b0: 53 74 72 65 73 73 28 0a 20 20 50 43 61 63 68 65  Stress(.  PCache
26c0: 20 2a 70 43 61 63 68 65 2c 20 20 20 20 20 20 20   *pCache,       
26d0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 62 74            /* Obt
26e0: 61 69 6e 20 74 68 65 20 70 61 67 65 20 66 72 6f  ain the page fro
26f0: 6d 20 74 68 69 73 20 63 61 63 68 65 20 2a 2f 0a  m this cache */.
2700: 20 20 50 67 6e 6f 20 70 67 6e 6f 2c 20 20 20 20    Pgno pgno,    
2710: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2720: 20 20 2f 2a 20 50 61 67 65 20 6e 75 6d 62 65 72    /* Page number
2730: 20 74 6f 20 6f 62 74 61 69 6e 20 2a 2f 0a 20 20   to obtain */.  
2740: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 5f 70  sqlite3_pcache_p
2750: 61 67 65 20 2a 2a 70 70 50 61 67 65 20 20 20 20  age **ppPage    
2760: 2f 2a 20 57 72 69 74 65 20 72 65 73 75 6c 74 20  /* Write result 
2770: 68 65 72 65 20 2a 2f 0a 29 7b 0a 20 20 50 67 48  here */.){.  PgH
2780: 64 72 20 2a 70 50 67 3b 0a 20 20 69 66 28 20 70  dr *pPg;.  if( p
2790: 43 61 63 68 65 2d 3e 65 43 72 65 61 74 65 3d 3d  Cache->eCreate==
27a0: 32 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 0a 0a  2 ) return 0;...
27b0: 20 20 2f 2a 20 46 69 6e 64 20 61 20 64 69 72 74    /* Find a dirt
27c0: 79 20 70 61 67 65 20 74 6f 20 77 72 69 74 65 2d  y page to write-
27d0: 6f 75 74 20 61 6e 64 20 72 65 63 79 63 6c 65 2e  out and recycle.
27e0: 20 46 69 72 73 74 20 74 72 79 20 74 6f 20 66 69   First try to fi
27f0: 6e 64 20 61 20 0a 20 20 2a 2a 20 70 61 67 65 20  nd a .  ** page 
2800: 74 68 61 74 20 64 6f 65 73 20 6e 6f 74 20 72 65  that does not re
2810: 71 75 69 72 65 20 61 20 6a 6f 75 72 6e 61 6c 2d  quire a journal-
2820: 73 79 6e 63 20 28 6f 6e 65 20 77 69 74 68 20 50  sync (one with P
2830: 47 48 44 52 5f 4e 45 45 44 5f 53 59 4e 43 0a 20  GHDR_NEED_SYNC. 
2840: 20 2a 2a 20 63 6c 65 61 72 65 64 29 2c 20 62 75   ** cleared), bu
2850: 74 20 69 66 20 74 68 61 74 20 69 73 20 6e 6f 74  t if that is not
2860: 20 70 6f 73 73 69 62 6c 65 20 73 65 74 74 6c 65   possible settle
2870: 20 66 6f 72 20 61 6e 79 20 6f 74 68 65 72 20 0a   for any other .
2880: 20 20 2a 2a 20 75 6e 72 65 66 65 72 65 6e 63 65    ** unreference
2890: 64 20 64 69 72 74 79 20 70 61 67 65 2e 0a 20 20  d dirty page..  
28a0: 2a 2f 0a 20 20 66 6f 72 28 70 50 67 3d 70 43 61  */.  for(pPg=pCa
28b0: 63 68 65 2d 3e 70 53 79 6e 63 65 64 3b 20 0a 20  che->pSynced; . 
28c0: 20 20 20 20 20 70 50 67 20 26 26 20 28 70 50 67       pPg && (pPg
28d0: 2d 3e 6e 52 65 66 20 7c 7c 20 28 70 50 67 2d 3e  ->nRef || (pPg->
28e0: 66 6c 61 67 73 26 50 47 48 44 52 5f 4e 45 45 44  flags&PGHDR_NEED
28f0: 5f 53 59 4e 43 29 29 3b 20 0a 20 20 20 20 20 20  _SYNC)); .      
2900: 70 50 67 3d 70 50 67 2d 3e 70 44 69 72 74 79 50  pPg=pPg->pDirtyP
2910: 72 65 76 0a 20 20 29 3b 0a 20 20 70 43 61 63 68  rev.  );.  pCach
2920: 65 2d 3e 70 53 79 6e 63 65 64 20 3d 20 70 50 67  e->pSynced = pPg
2930: 3b 0a 20 20 69 66 28 20 21 70 50 67 20 29 7b 0a  ;.  if( !pPg ){.
2940: 20 20 20 20 66 6f 72 28 70 50 67 3d 70 43 61 63      for(pPg=pCac
2950: 68 65 2d 3e 70 44 69 72 74 79 54 61 69 6c 3b 20  he->pDirtyTail; 
2960: 70 50 67 20 26 26 20 70 50 67 2d 3e 6e 52 65 66  pPg && pPg->nRef
2970: 3b 20 70 50 67 3d 70 50 67 2d 3e 70 44 69 72 74  ; pPg=pPg->pDirt
2980: 79 50 72 65 76 29 3b 0a 20 20 7d 0a 20 20 69 66  yPrev);.  }.  if
2990: 28 20 70 50 67 20 29 7b 0a 20 20 20 20 69 6e 74  ( pPg ){.    int
29a0: 20 72 63 3b 0a 23 69 66 64 65 66 20 53 51 4c 49   rc;.#ifdef SQLI
29b0: 54 45 5f 4c 4f 47 5f 43 41 43 48 45 5f 53 50 49  TE_LOG_CACHE_SPI
29c0: 4c 4c 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 6c  LL.    sqlite3_l
29d0: 6f 67 28 53 51 4c 49 54 45 5f 46 55 4c 4c 2c 20  og(SQLITE_FULL, 
29e0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
29f0: 20 22 73 70 69 6c 6c 20 70 61 67 65 20 25 64 20   "spill page %d 
2a00: 6d 61 6b 69 6e 67 20 72 6f 6f 6d 20 66 6f 72 20  making room for 
2a10: 25 64 20 2d 20 63 61 63 68 65 20 75 73 65 64 3a  %d - cache used:
2a20: 20 25 64 2f 25 64 22 2c 0a 20 20 20 20 20 20 20   %d/%d",.       
2a30: 20 20 20 20 20 20 20 20 20 70 50 67 2d 3e 70 67           pPg->pg
2a40: 6e 6f 2c 20 70 67 6e 6f 2c 0a 20 20 20 20 20 20  no, pgno,.      
2a50: 20 20 20 20 20 20 20 20 20 20 73 71 6c 69 74 65            sqlite
2a60: 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63  3GlobalConfig.pc
2a70: 61 63 68 65 2e 78 50 61 67 65 63 6f 75 6e 74 28  ache.xPagecount(
2a80: 70 43 61 63 68 65 2d 3e 70 43 61 63 68 65 29 2c  pCache->pCache),
2a90: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
2aa0: 20 6e 75 6d 62 65 72 4f 66 43 61 63 68 65 50 61   numberOfCachePa
2ab0: 67 65 73 28 70 43 61 63 68 65 29 29 3b 0a 23 65  ges(pCache));.#e
2ac0: 6e 64 69 66 0a 20 20 20 20 72 63 20 3d 20 70 43  ndif.    rc = pC
2ad0: 61 63 68 65 2d 3e 78 53 74 72 65 73 73 28 70 43  ache->xStress(pC
2ae0: 61 63 68 65 2d 3e 70 53 74 72 65 73 73 2c 20 70  ache->pStress, p
2af0: 50 67 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21  Pg);.    if( rc!
2b00: 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 72 63  =SQLITE_OK && rc
2b10: 21 3d 53 51 4c 49 54 45 5f 42 55 53 59 20 29 7b  !=SQLITE_BUSY ){
2b20: 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63  .      return rc
2b30: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 2a 70  ;.    }.  }.  *p
2b40: 70 50 61 67 65 20 3d 20 73 71 6c 69 74 65 33 47  pPage = sqlite3G
2b50: 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63  lobalConfig.pcac
2b60: 68 65 32 2e 78 46 65 74 63 68 28 70 43 61 63 68  he2.xFetch(pCach
2b70: 65 2d 3e 70 43 61 63 68 65 2c 20 70 67 6e 6f 2c  e->pCache, pgno,
2b80: 20 32 29 3b 0a 20 20 72 65 74 75 72 6e 20 2a 70   2);.  return *p
2b90: 70 50 61 67 65 3d 3d 30 20 3f 20 53 51 4c 49 54  pPage==0 ? SQLIT
2ba0: 45 5f 4e 4f 4d 45 4d 20 3a 20 53 51 4c 49 54 45  E_NOMEM : SQLITE
2bb0: 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68  _OK;.}../*.** Th
2bc0: 69 73 20 69 73 20 61 20 68 65 6c 70 65 72 20 72  is is a helper r
2bd0: 6f 75 74 69 6e 65 20 66 6f 72 20 73 71 6c 69 74  outine for sqlit
2be0: 65 33 50 63 61 63 68 65 46 65 74 63 68 46 69 6e  e3PcacheFetchFin
2bf0: 69 73 68 28 29 0a 2a 2a 0a 2a 2a 20 49 6e 20 74  ish().**.** In t
2c00: 68 65 20 75 6e 63 6f 6d 6d 6f 6e 20 63 61 73 65  he uncommon case
2c10: 20 77 68 65 72 65 20 74 68 65 20 70 61 67 65 20   where the page 
2c20: 62 65 69 6e 67 20 66 65 74 63 68 65 64 20 68 61  being fetched ha
2c30: 73 20 6e 6f 74 20 62 65 65 6e 0a 2a 2a 20 69 6e  s not been.** in
2c40: 69 74 69 61 6c 69 7a 65 64 2c 20 74 68 69 73 20  itialized, this 
2c50: 72 6f 75 74 69 6e 65 20 69 73 20 69 6e 76 6f 6b  routine is invok
2c60: 65 64 20 74 6f 20 64 6f 20 74 68 65 20 69 6e 69  ed to do the ini
2c70: 74 69 61 6c 69 7a 61 74 69 6f 6e 2e 0a 2a 2a 20  tialization..** 
2c80: 54 68 69 73 20 72 6f 75 74 69 6e 65 20 69 73 20  This routine is 
2c90: 62 72 6f 6b 65 6e 20 6f 75 74 20 69 6e 74 6f 20  broken out into 
2ca0: 61 20 73 65 70 61 72 61 74 65 20 66 75 6e 63 74  a separate funct
2cb0: 69 6f 6e 20 73 69 6e 63 65 20 69 74 0a 2a 2a 20  ion since it.** 
2cc0: 72 65 71 75 69 72 65 73 20 65 78 74 72 61 20 73  requires extra s
2cd0: 74 61 63 6b 20 6d 61 6e 69 70 75 6c 61 74 69 6f  tack manipulatio
2ce0: 6e 20 74 68 61 74 20 63 61 6e 20 62 65 20 61 76  n that can be av
2cf0: 6f 69 64 65 64 20 69 6e 20 74 68 65 20 63 6f 6d  oided in the com
2d00: 6d 6f 6e 0a 2a 2a 20 63 61 73 65 2e 0a 2a 2f 0a  mon.** case..*/.
2d10: 73 74 61 74 69 63 20 53 51 4c 49 54 45 5f 4e 4f  static SQLITE_NO
2d20: 49 4e 4c 49 4e 45 20 50 67 48 64 72 20 2a 70 63  INLINE PgHdr *pc
2d30: 61 63 68 65 46 65 74 63 68 46 69 6e 69 73 68 57  acheFetchFinishW
2d40: 69 74 68 49 6e 69 74 28 0a 20 20 50 43 61 63 68  ithInit(.  PCach
2d50: 65 20 2a 70 43 61 63 68 65 2c 20 20 20 20 20 20  e *pCache,      
2d60: 20 20 20 20 20 20 20 2f 2a 20 4f 62 74 61 69 6e         /* Obtain
2d70: 20 74 68 65 20 70 61 67 65 20 66 72 6f 6d 20 74   the page from t
2d80: 68 69 73 20 63 61 63 68 65 20 2a 2f 0a 20 20 50  his cache */.  P
2d90: 67 6e 6f 20 70 67 6e 6f 2c 20 20 20 20 20 20 20  gno pgno,       
2da0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61             /* Pa
2db0: 67 65 20 6e 75 6d 62 65 72 20 6f 62 74 61 69 6e  ge number obtain
2dc0: 65 64 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f  ed */.  sqlite3_
2dd0: 70 63 61 63 68 65 5f 70 61 67 65 20 2a 70 50 61  pcache_page *pPa
2de0: 67 65 20 20 2f 2a 20 50 61 67 65 20 6f 62 74 61  ge  /* Page obta
2df0: 69 6e 65 64 20 62 79 20 70 72 69 6f 72 20 50 63  ined by prior Pc
2e00: 61 63 68 65 46 65 74 63 68 28 29 20 63 61 6c 6c  acheFetch() call
2e10: 20 2a 2f 0a 29 7b 0a 20 20 50 67 48 64 72 20 2a   */.){.  PgHdr *
2e20: 70 50 67 48 64 72 3b 0a 20 20 61 73 73 65 72 74  pPgHdr;.  assert
2e30: 28 20 70 50 61 67 65 21 3d 30 20 29 3b 0a 20 20  ( pPage!=0 );.  
2e40: 70 50 67 48 64 72 20 3d 20 28 50 67 48 64 72 2a  pPgHdr = (PgHdr*
2e50: 29 70 50 61 67 65 2d 3e 70 45 78 74 72 61 3b 0a  )pPage->pExtra;.
2e60: 20 20 61 73 73 65 72 74 28 20 70 50 67 48 64 72    assert( pPgHdr
2e70: 2d 3e 70 50 61 67 65 3d 3d 30 20 29 3b 0a 20 6d  ->pPage==0 );. m
2e80: 65 6d 73 65 74 28 70 50 67 48 64 72 2c 20 30 2c  emset(pPgHdr, 0,
2e90: 20 73 69 7a 65 6f 66 28 50 67 48 64 72 29 29 3b   sizeof(PgHdr));
2ea0: 0a 20 20 70 50 67 48 64 72 2d 3e 70 50 61 67 65  .  pPgHdr->pPage
2eb0: 20 3d 20 70 50 61 67 65 3b 0a 20 20 70 50 67 48   = pPage;.  pPgH
2ec0: 64 72 2d 3e 70 44 61 74 61 20 3d 20 70 50 61 67  dr->pData = pPag
2ed0: 65 2d 3e 70 42 75 66 3b 0a 20 20 70 50 67 48 64  e->pBuf;.  pPgHd
2ee0: 72 2d 3e 70 45 78 74 72 61 20 3d 20 28 76 6f 69  r->pExtra = (voi
2ef0: 64 20 2a 29 26 70 50 67 48 64 72 5b 31 5d 3b 0a  d *)&pPgHdr[1];.
2f00: 20 20 6d 65 6d 73 65 74 28 70 50 67 48 64 72 2d    memset(pPgHdr-
2f10: 3e 70 45 78 74 72 61 2c 20 30 2c 20 70 43 61 63  >pExtra, 0, pCac
2f20: 68 65 2d 3e 73 7a 45 78 74 72 61 29 3b 0a 20 20  he->szExtra);.  
2f30: 70 50 67 48 64 72 2d 3e 70 43 61 63 68 65 20 3d  pPgHdr->pCache =
2f40: 20 70 43 61 63 68 65 3b 0a 20 20 70 50 67 48 64   pCache;.  pPgHd
2f50: 72 2d 3e 70 67 6e 6f 20 3d 20 70 67 6e 6f 3b 0a  r->pgno = pgno;.
2f60: 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33    return sqlite3
2f70: 50 63 61 63 68 65 46 65 74 63 68 46 69 6e 69 73  PcacheFetchFinis
2f80: 68 28 70 43 61 63 68 65 2c 70 67 6e 6f 2c 70 50  h(pCache,pgno,pP
2f90: 61 67 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  age);.}../*.** T
2fa0: 68 69 73 20 72 6f 75 74 69 6e 65 20 63 6f 6e 76  his routine conv
2fb0: 65 72 74 73 20 74 68 65 20 73 71 6c 69 74 65 33  erts the sqlite3
2fc0: 5f 70 63 61 63 68 65 5f 70 61 67 65 20 6f 62 6a  _pcache_page obj
2fd0: 65 63 74 20 72 65 74 75 72 6e 65 64 20 62 79 0a  ect returned by.
2fe0: 2a 2a 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  ** sqlite3Pcache
2ff0: 46 65 74 63 68 28 29 20 69 6e 74 6f 20 61 6e 20  Fetch() into an 
3000: 69 6e 69 74 69 61 6c 69 7a 65 64 20 50 67 48 64  initialized PgHd
3010: 72 20 6f 62 6a 65 63 74 2e 20 20 54 68 69 73 20  r object.  This 
3020: 72 6f 75 74 69 6e 65 0a 2a 2a 20 6d 75 73 74 20  routine.** must 
3030: 62 65 20 63 61 6c 6c 65 64 20 61 66 74 65 72 20  be called after 
3040: 73 71 6c 69 74 65 33 50 63 61 63 68 65 46 65 74  sqlite3PcacheFet
3050: 63 68 28 29 20 69 6e 20 6f 72 64 65 72 20 74 6f  ch() in order to
3060: 20 67 65 74 20 61 20 75 73 61 62 6c 65 0a 2a 2a   get a usable.**
3070: 20 72 65 73 75 6c 74 2e 0a 2a 2f 0a 50 67 48 64   result..*/.PgHd
3080: 72 20 2a 73 71 6c 69 74 65 33 50 63 61 63 68 65  r *sqlite3Pcache
3090: 46 65 74 63 68 46 69 6e 69 73 68 28 0a 20 20 50  FetchFinish(.  P
30a0: 43 61 63 68 65 20 2a 70 43 61 63 68 65 2c 20 20  Cache *pCache,  
30b0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 62             /* Ob
30c0: 74 61 69 6e 20 74 68 65 20 70 61 67 65 20 66 72  tain the page fr
30d0: 6f 6d 20 74 68 69 73 20 63 61 63 68 65 20 2a 2f  om this cache */
30e0: 0a 20 20 50 67 6e 6f 20 70 67 6e 6f 2c 20 20 20  .  Pgno pgno,   
30f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3100: 2a 20 50 61 67 65 20 6e 75 6d 62 65 72 20 6f 62  * Page number ob
3110: 74 61 69 6e 65 64 20 2a 2f 0a 20 20 73 71 6c 69  tained */.  sqli
3120: 74 65 33 5f 70 63 61 63 68 65 5f 70 61 67 65 20  te3_pcache_page 
3130: 2a 70 50 61 67 65 20 20 2f 2a 20 50 61 67 65 20  *pPage  /* Page 
3140: 6f 62 74 61 69 6e 65 64 20 62 79 20 70 72 69 6f  obtained by prio
3150: 72 20 50 63 61 63 68 65 46 65 74 63 68 28 29 20  r PcacheFetch() 
3160: 63 61 6c 6c 20 2a 2f 0a 29 7b 0a 20 20 50 67 48  call */.){.  PgH
3170: 64 72 20 2a 70 50 67 48 64 72 3b 0a 0a 20 20 69  dr *pPgHdr;..  i
3180: 66 28 20 70 50 61 67 65 3d 3d 30 20 29 20 72 65  f( pPage==0 ) re
3190: 74 75 72 6e 20 30 3b 0a 20 20 70 50 67 48 64 72  turn 0;.  pPgHdr
31a0: 20 3d 20 28 50 67 48 64 72 20 2a 29 70 50 61 67   = (PgHdr *)pPag
31b0: 65 2d 3e 70 45 78 74 72 61 3b 0a 0a 20 20 69 66  e->pExtra;..  if
31c0: 28 20 21 70 50 67 48 64 72 2d 3e 70 50 61 67 65  ( !pPgHdr->pPage
31d0: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 70   ){.    return p
31e0: 63 61 63 68 65 46 65 74 63 68 46 69 6e 69 73 68  cacheFetchFinish
31f0: 57 69 74 68 49 6e 69 74 28 70 43 61 63 68 65 2c  WithInit(pCache,
3200: 20 70 67 6e 6f 2c 20 70 50 61 67 65 29 3b 0a 20   pgno, pPage);. 
3210: 20 7d 0a 20 20 69 66 28 20 30 3d 3d 70 50 67 48   }.  if( 0==pPgH
3220: 64 72 2d 3e 6e 52 65 66 20 29 7b 0a 20 20 20 20  dr->nRef ){.    
3230: 70 43 61 63 68 65 2d 3e 6e 52 65 66 2b 2b 3b 0a  pCache->nRef++;.
3240: 20 20 7d 0a 20 20 70 50 67 48 64 72 2d 3e 6e 52    }.  pPgHdr->nR
3250: 65 66 2b 2b 3b 0a 20 20 69 66 28 20 70 67 6e 6f  ef++;.  if( pgno
3260: 3d 3d 31 20 29 7b 0a 20 20 20 20 70 43 61 63 68  ==1 ){.    pCach
3270: 65 2d 3e 70 50 61 67 65 31 20 3d 20 70 50 67 48  e->pPage1 = pPgH
3280: 64 72 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  dr;.  }.  return
3290: 20 70 50 67 48 64 72 3b 0a 7d 0a 0a 2f 2a 0a 2a   pPgHdr;.}../*.*
32a0: 2a 20 44 65 63 72 65 6d 65 6e 74 20 74 68 65 20  * Decrement the 
32b0: 72 65 66 65 72 65 6e 63 65 20 63 6f 75 6e 74 20  reference count 
32c0: 6f 6e 20 61 20 70 61 67 65 2e 20 49 66 20 74 68  on a page. If th
32d0: 65 20 70 61 67 65 20 69 73 20 63 6c 65 61 6e 20  e page is clean 
32e0: 61 6e 64 20 74 68 65 0a 2a 2a 20 72 65 66 65 72  and the.** refer
32f0: 65 6e 63 65 20 63 6f 75 6e 74 20 64 72 6f 70 73  ence count drops
3300: 20 74 6f 20 30 2c 20 74 68 65 6e 20 69 74 20 69   to 0, then it i
3310: 73 20 6d 61 64 65 20 65 6c 69 67 69 62 6c 65 20  s made eligible 
3320: 66 6f 72 20 72 65 63 79 63 6c 69 6e 67 2e 0a 2a  for recycling..*
3330: 2f 0a 76 6f 69 64 20 53 51 4c 49 54 45 5f 4e 4f  /.void SQLITE_NO
3340: 49 4e 4c 49 4e 45 20 73 71 6c 69 74 65 33 50 63  INLINE sqlite3Pc
3350: 61 63 68 65 52 65 6c 65 61 73 65 28 50 67 48 64  acheRelease(PgHd
3360: 72 20 2a 70 29 7b 0a 20 20 61 73 73 65 72 74 28  r *p){.  assert(
3370: 20 70 2d 3e 6e 52 65 66 3e 30 20 29 3b 0a 20 20   p->nRef>0 );.  
3380: 70 2d 3e 6e 52 65 66 2d 2d 3b 0a 20 20 69 66 28  p->nRef--;.  if(
3390: 20 70 2d 3e 6e 52 65 66 3d 3d 30 20 29 7b 0a 20   p->nRef==0 ){. 
33a0: 20 20 20 70 2d 3e 70 43 61 63 68 65 2d 3e 6e 52     p->pCache->nR
33b0: 65 66 2d 2d 3b 0a 20 20 20 20 69 66 28 20 28 70  ef--;.    if( (p
33c0: 2d 3e 66 6c 61 67 73 26 50 47 48 44 52 5f 44 49  ->flags&PGHDR_DI
33d0: 52 54 59 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20  RTY)==0 ){.     
33e0: 20 70 63 61 63 68 65 55 6e 70 69 6e 28 70 29 3b   pcacheUnpin(p);
33f0: 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 70  .    }else if( p
3400: 2d 3e 70 44 69 72 74 79 50 72 65 76 21 3d 30 20  ->pDirtyPrev!=0 
3410: 29 7b 0a 20 20 20 20 20 20 2f 2a 20 4d 6f 76 65  ){.      /* Move
3420: 20 74 68 65 20 70 61 67 65 20 74 6f 20 74 68 65   the page to the
3430: 20 68 65 61 64 20 6f 66 20 74 68 65 20 64 69 72   head of the dir
3440: 74 79 20 6c 69 73 74 2e 20 2a 2f 0a 20 20 20 20  ty list. */.    
3450: 20 20 70 63 61 63 68 65 4d 61 6e 61 67 65 44 69    pcacheManageDi
3460: 72 74 79 4c 69 73 74 28 70 2c 20 50 43 41 43 48  rtyList(p, PCACH
3470: 45 5f 44 49 52 54 59 4c 49 53 54 5f 46 52 4f 4e  E_DIRTYLIST_FRON
3480: 54 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a  T);.    }.  }.}.
3490: 0a 2f 2a 0a 2a 2a 20 49 6e 63 72 65 61 73 65 20  ./*.** Increase 
34a0: 74 68 65 20 72 65 66 65 72 65 6e 63 65 20 63 6f  the reference co
34b0: 75 6e 74 20 6f 66 20 61 20 73 75 70 70 6c 69 65  unt of a supplie
34c0: 64 20 70 61 67 65 20 62 79 20 31 2e 0a 2a 2f 0a  d page by 1..*/.
34d0: 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63 61 63  void sqlite3Pcac
34e0: 68 65 52 65 66 28 50 67 48 64 72 20 2a 70 29 7b  heRef(PgHdr *p){
34f0: 0a 20 20 61 73 73 65 72 74 28 70 2d 3e 6e 52 65  .  assert(p->nRe
3500: 66 3e 30 29 3b 0a 20 20 70 2d 3e 6e 52 65 66 2b  f>0);.  p->nRef+
3510: 2b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 72 6f 70  +;.}../*.** Drop
3520: 20 61 20 70 61 67 65 20 66 72 6f 6d 20 74 68 65   a page from the
3530: 20 63 61 63 68 65 2e 20 54 68 65 72 65 20 6d 75   cache. There mu
3540: 73 74 20 62 65 20 65 78 61 63 74 6c 79 20 6f 6e  st be exactly on
3550: 65 20 72 65 66 65 72 65 6e 63 65 20 74 6f 20 74  e reference to t
3560: 68 65 0a 2a 2a 20 70 61 67 65 2e 20 54 68 69 73  he.** page. This
3570: 20 66 75 6e 63 74 69 6f 6e 20 64 65 6c 65 74 65   function delete
3580: 73 20 74 68 61 74 20 72 65 66 65 72 65 6e 63 65  s that reference
3590: 2c 20 73 6f 20 61 66 74 65 72 20 69 74 20 72 65  , so after it re
35a0: 74 75 72 6e 73 20 74 68 65 0a 2a 2a 20 70 61 67  turns the.** pag
35b0: 65 20 70 6f 69 6e 74 65 64 20 74 6f 20 62 79 20  e pointed to by 
35c0: 70 20 69 73 20 69 6e 76 61 6c 69 64 2e 0a 2a 2f  p is invalid..*/
35d0: 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63 61  .void sqlite3Pca
35e0: 63 68 65 44 72 6f 70 28 50 67 48 64 72 20 2a 70  cheDrop(PgHdr *p
35f0: 29 7b 0a 20 20 61 73 73 65 72 74 28 20 70 2d 3e  ){.  assert( p->
3600: 6e 52 65 66 3d 3d 31 20 29 3b 0a 20 20 69 66 28  nRef==1 );.  if(
3610: 20 70 2d 3e 66 6c 61 67 73 26 50 47 48 44 52 5f   p->flags&PGHDR_
3620: 44 49 52 54 59 20 29 7b 0a 20 20 20 20 70 63 61  DIRTY ){.    pca
3630: 63 68 65 4d 61 6e 61 67 65 44 69 72 74 79 4c 69  cheManageDirtyLi
3640: 73 74 28 70 2c 20 50 43 41 43 48 45 5f 44 49 52  st(p, PCACHE_DIR
3650: 54 59 4c 49 53 54 5f 52 45 4d 4f 56 45 29 3b 0a  TYLIST_REMOVE);.
3660: 20 20 7d 0a 20 20 70 2d 3e 70 43 61 63 68 65 2d    }.  p->pCache-
3670: 3e 6e 52 65 66 2d 2d 3b 0a 20 20 69 66 28 20 70  >nRef--;.  if( p
3680: 2d 3e 70 67 6e 6f 3d 3d 31 20 29 7b 0a 20 20 20  ->pgno==1 ){.   
3690: 20 70 2d 3e 70 43 61 63 68 65 2d 3e 70 50 61 67   p->pCache->pPag
36a0: 65 31 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 73 71  e1 = 0;.  }.  sq
36b0: 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69  lite3GlobalConfi
36c0: 67 2e 70 63 61 63 68 65 32 2e 78 55 6e 70 69 6e  g.pcache2.xUnpin
36d0: 28 70 2d 3e 70 43 61 63 68 65 2d 3e 70 43 61 63  (p->pCache->pCac
36e0: 68 65 2c 20 70 2d 3e 70 50 61 67 65 2c 20 31 29  he, p->pPage, 1)
36f0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6b 65 20  ;.}../*.** Make 
3700: 73 75 72 65 20 74 68 65 20 70 61 67 65 20 69 73  sure the page is
3710: 20 6d 61 72 6b 65 64 20 61 73 20 64 69 72 74 79   marked as dirty
3720: 2e 20 49 66 20 69 74 20 69 73 6e 27 74 20 64 69  . If it isn't di
3730: 72 74 79 20 61 6c 72 65 61 64 79 2c 0a 2a 2a 20  rty already,.** 
3740: 6d 61 6b 65 20 69 74 20 73 6f 2e 0a 2a 2f 0a 76  make it so..*/.v
3750: 6f 69 64 20 73 71 6c 69 74 65 33 50 63 61 63 68  oid sqlite3Pcach
3760: 65 4d 61 6b 65 44 69 72 74 79 28 50 67 48 64 72  eMakeDirty(PgHdr
3770: 20 2a 70 29 7b 0a 20 20 70 2d 3e 66 6c 61 67 73   *p){.  p->flags
3780: 20 26 3d 20 7e 50 47 48 44 52 5f 44 4f 4e 54 5f   &= ~PGHDR_DONT_
3790: 57 52 49 54 45 3b 0a 20 20 61 73 73 65 72 74 28  WRITE;.  assert(
37a0: 20 70 2d 3e 6e 52 65 66 3e 30 20 29 3b 0a 20 20   p->nRef>0 );.  
37b0: 69 66 28 20 30 3d 3d 28 70 2d 3e 66 6c 61 67 73  if( 0==(p->flags
37c0: 20 26 20 50 47 48 44 52 5f 44 49 52 54 59 29 20   & PGHDR_DIRTY) 
37d0: 29 7b 0a 20 20 20 20 70 2d 3e 66 6c 61 67 73 20  ){.    p->flags 
37e0: 7c 3d 20 50 47 48 44 52 5f 44 49 52 54 59 3b 0a  |= PGHDR_DIRTY;.
37f0: 20 20 20 20 70 63 61 63 68 65 4d 61 6e 61 67 65      pcacheManage
3800: 44 69 72 74 79 4c 69 73 74 28 70 2c 20 50 43 41  DirtyList(p, PCA
3810: 43 48 45 5f 44 49 52 54 59 4c 49 53 54 5f 41 44  CHE_DIRTYLIST_AD
3820: 44 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a  D);.  }.}../*.**
3830: 20 4d 61 6b 65 20 73 75 72 65 20 74 68 65 20 70   Make sure the p
3840: 61 67 65 20 69 73 20 6d 61 72 6b 65 64 20 61 73  age is marked as
3850: 20 63 6c 65 61 6e 2e 20 49 66 20 69 74 20 69 73   clean. If it is
3860: 6e 27 74 20 63 6c 65 61 6e 20 61 6c 72 65 61 64  n't clean alread
3870: 79 2c 0a 2a 2a 20 6d 61 6b 65 20 69 74 20 73 6f  y,.** make it so
3880: 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
3890: 33 50 63 61 63 68 65 4d 61 6b 65 43 6c 65 61 6e  3PcacheMakeClean
38a0: 28 50 67 48 64 72 20 2a 70 29 7b 0a 20 20 69 66  (PgHdr *p){.  if
38b0: 28 20 28 70 2d 3e 66 6c 61 67 73 20 26 20 50 47  ( (p->flags & PG
38c0: 48 44 52 5f 44 49 52 54 59 29 20 29 7b 0a 20 20  HDR_DIRTY) ){.  
38d0: 20 20 70 63 61 63 68 65 4d 61 6e 61 67 65 44 69    pcacheManageDi
38e0: 72 74 79 4c 69 73 74 28 70 2c 20 50 43 41 43 48  rtyList(p, PCACH
38f0: 45 5f 44 49 52 54 59 4c 49 53 54 5f 52 45 4d 4f  E_DIRTYLIST_REMO
3900: 56 45 29 3b 0a 20 20 20 20 70 2d 3e 66 6c 61 67  VE);.    p->flag
3910: 73 20 26 3d 20 7e 28 50 47 48 44 52 5f 44 49 52  s &= ~(PGHDR_DIR
3920: 54 59 7c 50 47 48 44 52 5f 4e 45 45 44 5f 53 59  TY|PGHDR_NEED_SY
3930: 4e 43 29 3b 0a 20 20 20 20 69 66 28 20 70 2d 3e  NC);.    if( p->
3940: 6e 52 65 66 3d 3d 30 20 29 7b 0a 20 20 20 20 20  nRef==0 ){.     
3950: 20 70 63 61 63 68 65 55 6e 70 69 6e 28 70 29 3b   pcacheUnpin(p);
3960: 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a  .    }.  }.}../*
3970: 0a 2a 2a 20 4d 61 6b 65 20 65 76 65 72 79 20 70  .** Make every p
3980: 61 67 65 20 69 6e 20 74 68 65 20 63 61 63 68 65  age in the cache
3990: 20 63 6c 65 61 6e 2e 0a 2a 2f 0a 76 6f 69 64 20   clean..*/.void 
39a0: 73 71 6c 69 74 65 33 50 63 61 63 68 65 43 6c 65  sqlite3PcacheCle
39b0: 61 6e 41 6c 6c 28 50 43 61 63 68 65 20 2a 70 43  anAll(PCache *pC
39c0: 61 63 68 65 29 7b 0a 20 20 50 67 48 64 72 20 2a  ache){.  PgHdr *
39d0: 70 3b 0a 20 20 77 68 69 6c 65 28 20 28 70 20 3d  p;.  while( (p =
39e0: 20 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 29   pCache->pDirty)
39f0: 21 3d 30 20 29 7b 0a 20 20 20 20 73 71 6c 69 74  !=0 ){.    sqlit
3a00: 65 33 50 63 61 63 68 65 4d 61 6b 65 43 6c 65 61  e3PcacheMakeClea
3a10: 6e 28 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a  n(p);.  }.}../*.
3a20: 2a 2a 20 43 6c 65 61 72 20 74 68 65 20 50 47 48  ** Clear the PGH
3a30: 44 52 5f 4e 45 45 44 5f 53 59 4e 43 20 66 6c 61  DR_NEED_SYNC fla
3a40: 67 20 66 72 6f 6d 20 61 6c 6c 20 64 69 72 74 79  g from all dirty
3a50: 20 70 61 67 65 73 2e 0a 2a 2f 0a 76 6f 69 64 20   pages..*/.void 
3a60: 73 71 6c 69 74 65 33 50 63 61 63 68 65 43 6c 65  sqlite3PcacheCle
3a70: 61 72 53 79 6e 63 46 6c 61 67 73 28 50 43 61 63  arSyncFlags(PCac
3a80: 68 65 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 50  he *pCache){.  P
3a90: 67 48 64 72 20 2a 70 3b 0a 20 20 66 6f 72 28 70  gHdr *p;.  for(p
3aa0: 3d 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 3b  =pCache->pDirty;
3ab0: 20 70 3b 20 70 3d 70 2d 3e 70 44 69 72 74 79 4e   p; p=p->pDirtyN
3ac0: 65 78 74 29 7b 0a 20 20 20 20 70 2d 3e 66 6c 61  ext){.    p->fla
3ad0: 67 73 20 26 3d 20 7e 50 47 48 44 52 5f 4e 45 45  gs &= ~PGHDR_NEE
3ae0: 44 5f 53 59 4e 43 3b 0a 20 20 7d 0a 20 20 70 43  D_SYNC;.  }.  pC
3af0: 61 63 68 65 2d 3e 70 53 79 6e 63 65 64 20 3d 20  ache->pSynced = 
3b00: 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 54 61  pCache->pDirtyTa
3b10: 69 6c 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 68 61  il;.}../*.** Cha
3b20: 6e 67 65 20 74 68 65 20 70 61 67 65 20 6e 75 6d  nge the page num
3b30: 62 65 72 20 6f 66 20 70 61 67 65 20 70 20 74 6f  ber of page p to
3b40: 20 6e 65 77 50 67 6e 6f 2e 20 0a 2a 2f 0a 76 6f   newPgno. .*/.vo
3b50: 69 64 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  id sqlite3Pcache
3b60: 4d 6f 76 65 28 50 67 48 64 72 20 2a 70 2c 20 50  Move(PgHdr *p, P
3b70: 67 6e 6f 20 6e 65 77 50 67 6e 6f 29 7b 0a 20 20  gno newPgno){.  
3b80: 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 20 3d  PCache *pCache =
3b90: 20 70 2d 3e 70 43 61 63 68 65 3b 0a 20 20 61 73   p->pCache;.  as
3ba0: 73 65 72 74 28 20 70 2d 3e 6e 52 65 66 3e 30 20  sert( p->nRef>0 
3bb0: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 6e 65 77  );.  assert( new
3bc0: 50 67 6e 6f 3e 30 20 29 3b 0a 20 20 73 71 6c 69  Pgno>0 );.  sqli
3bd0: 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e  te3GlobalConfig.
3be0: 70 63 61 63 68 65 32 2e 78 52 65 6b 65 79 28 70  pcache2.xRekey(p
3bf0: 43 61 63 68 65 2d 3e 70 43 61 63 68 65 2c 20 70  Cache->pCache, p
3c00: 2d 3e 70 50 61 67 65 2c 20 70 2d 3e 70 67 6e 6f  ->pPage, p->pgno
3c10: 2c 6e 65 77 50 67 6e 6f 29 3b 0a 20 20 70 2d 3e  ,newPgno);.  p->
3c20: 70 67 6e 6f 20 3d 20 6e 65 77 50 67 6e 6f 3b 0a  pgno = newPgno;.
3c30: 20 20 69 66 28 20 28 70 2d 3e 66 6c 61 67 73 26    if( (p->flags&
3c40: 50 47 48 44 52 5f 44 49 52 54 59 29 20 26 26 20  PGHDR_DIRTY) && 
3c50: 28 70 2d 3e 66 6c 61 67 73 26 50 47 48 44 52 5f  (p->flags&PGHDR_
3c60: 4e 45 45 44 5f 53 59 4e 43 29 20 29 7b 0a 20 20  NEED_SYNC) ){.  
3c70: 20 20 70 63 61 63 68 65 4d 61 6e 61 67 65 44 69    pcacheManageDi
3c80: 72 74 79 4c 69 73 74 28 70 2c 20 50 43 41 43 48  rtyList(p, PCACH
3c90: 45 5f 44 49 52 54 59 4c 49 53 54 5f 46 52 4f 4e  E_DIRTYLIST_FRON
3ca0: 54 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a  T);.  }.}../*.**
3cb0: 20 44 72 6f 70 20 65 76 65 72 79 20 63 61 63 68   Drop every cach
3cc0: 65 20 65 6e 74 72 79 20 77 68 6f 73 65 20 70 61  e entry whose pa
3cd0: 67 65 20 6e 75 6d 62 65 72 20 69 73 20 67 72 65  ge number is gre
3ce0: 61 74 65 72 20 74 68 61 6e 20 22 70 67 6e 6f 22  ater than "pgno"
3cf0: 2e 20 54 68 65 0a 2a 2a 20 63 61 6c 6c 65 72 20  . The.** caller 
3d00: 6d 75 73 74 20 65 6e 73 75 72 65 20 74 68 61 74  must ensure that
3d10: 20 74 68 65 72 65 20 61 72 65 20 6e 6f 20 6f 75   there are no ou
3d20: 74 73 74 61 6e 64 69 6e 67 20 72 65 66 65 72 65  tstanding refere
3d30: 6e 63 65 73 20 74 6f 20 61 6e 79 20 70 61 67 65  nces to any page
3d40: 73 0a 2a 2a 20 6f 74 68 65 72 20 74 68 61 6e 20  s.** other than 
3d50: 70 61 67 65 20 31 20 77 69 74 68 20 61 20 70 61  page 1 with a pa
3d60: 67 65 20 6e 75 6d 62 65 72 20 67 72 65 61 74 65  ge number greate
3d70: 72 20 74 68 61 6e 20 70 67 6e 6f 2e 0a 2a 2a 0a  r than pgno..**.
3d80: 2a 2a 20 49 66 20 74 68 65 72 65 20 69 73 20 61  ** If there is a
3d90: 20 72 65 66 65 72 65 6e 63 65 20 74 6f 20 70 61   reference to pa
3da0: 67 65 20 31 20 61 6e 64 20 74 68 65 20 70 67 6e  ge 1 and the pgn
3db0: 6f 20 70 61 72 61 6d 65 74 65 72 20 70 61 73 73  o parameter pass
3dc0: 65 64 20 74 6f 20 74 68 69 73 0a 2a 2a 20 66 75  ed to this.** fu
3dd0: 6e 63 74 69 6f 6e 20 69 73 20 30 2c 20 74 68 65  nction is 0, the
3de0: 6e 20 74 68 65 20 64 61 74 61 20 61 72 65 61 20  n the data area 
3df0: 61 73 73 6f 63 69 61 74 65 64 20 77 69 74 68 20  associated with 
3e00: 70 61 67 65 20 31 20 69 73 20 7a 65 72 6f 65 64  page 1 is zeroed
3e10: 2c 20 62 75 74 0a 2a 2a 20 74 68 65 20 70 61 67  , but.** the pag
3e20: 65 20 6f 62 6a 65 63 74 20 69 73 20 6e 6f 74 20  e object is not 
3e30: 64 72 6f 70 70 65 64 2e 0a 2a 2f 0a 76 6f 69 64  dropped..*/.void
3e40: 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 54 72   sqlite3PcacheTr
3e50: 75 6e 63 61 74 65 28 50 43 61 63 68 65 20 2a 70  uncate(PCache *p
3e60: 43 61 63 68 65 2c 20 50 67 6e 6f 20 70 67 6e 6f  Cache, Pgno pgno
3e70: 29 7b 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d  ){.  if( pCache-
3e80: 3e 70 43 61 63 68 65 20 29 7b 0a 20 20 20 20 50  >pCache ){.    P
3e90: 67 48 64 72 20 2a 70 3b 0a 20 20 20 20 50 67 48  gHdr *p;.    PgH
3ea0: 64 72 20 2a 70 4e 65 78 74 3b 0a 20 20 20 20 66  dr *pNext;.    f
3eb0: 6f 72 28 70 3d 70 43 61 63 68 65 2d 3e 70 44 69  or(p=pCache->pDi
3ec0: 72 74 79 3b 20 70 3b 20 70 3d 70 4e 65 78 74 29  rty; p; p=pNext)
3ed0: 7b 0a 20 20 20 20 20 20 70 4e 65 78 74 20 3d 20  {.      pNext = 
3ee0: 70 2d 3e 70 44 69 72 74 79 4e 65 78 74 3b 0a 20  p->pDirtyNext;. 
3ef0: 20 20 20 20 20 2f 2a 20 54 68 69 73 20 72 6f 75       /* This rou
3f00: 74 69 6e 65 20 6e 65 76 65 72 20 67 65 74 73 20  tine never gets 
3f10: 63 61 6c 6c 20 77 69 74 68 20 61 20 70 6f 73 69  call with a posi
3f20: 74 69 76 65 20 70 67 6e 6f 20 65 78 63 65 70 74  tive pgno except
3f30: 20 72 69 67 68 74 0a 20 20 20 20 20 20 2a 2a 20   right.      ** 
3f40: 61 66 74 65 72 20 73 71 6c 69 74 65 33 50 63 61  after sqlite3Pca
3f50: 63 68 65 43 6c 65 61 6e 41 6c 6c 28 29 2e 20 20  cheCleanAll().  
3f60: 53 6f 20 69 66 20 74 68 65 72 65 20 61 72 65 20  So if there are 
3f70: 64 69 72 74 79 20 70 61 67 65 73 2c 0a 20 20 20  dirty pages,.   
3f80: 20 20 20 2a 2a 20 69 74 20 6d 75 73 74 20 62 65     ** it must be
3f90: 20 74 68 61 74 20 70 67 6e 6f 3d 3d 30 2e 0a 20   that pgno==0.. 
3fa0: 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 20 61 73       */.      as
3fb0: 73 65 72 74 28 20 70 2d 3e 70 67 6e 6f 3e 30 20  sert( p->pgno>0 
3fc0: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 41 4c 57  );.      if( ALW
3fd0: 41 59 53 28 70 2d 3e 70 67 6e 6f 3e 70 67 6e 6f  AYS(p->pgno>pgno
3fe0: 29 20 29 7b 0a 20 20 20 20 20 20 20 20 61 73 73  ) ){.        ass
3ff0: 65 72 74 28 20 70 2d 3e 66 6c 61 67 73 26 50 47  ert( p->flags&PG
4000: 48 44 52 5f 44 49 52 54 59 20 29 3b 0a 20 20 20  HDR_DIRTY );.   
4010: 20 20 20 20 20 73 71 6c 69 74 65 33 50 63 61 63       sqlite3Pcac
4020: 68 65 4d 61 6b 65 43 6c 65 61 6e 28 70 29 3b 0a  heMakeClean(p);.
4030: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
4040: 20 20 69 66 28 20 70 67 6e 6f 3d 3d 30 20 26 26    if( pgno==0 &&
4050: 20 70 43 61 63 68 65 2d 3e 70 50 61 67 65 31 20   pCache->pPage1 
4060: 29 7b 0a 20 20 20 20 20 20 6d 65 6d 73 65 74 28  ){.      memset(
4070: 70 43 61 63 68 65 2d 3e 70 50 61 67 65 31 2d 3e  pCache->pPage1->
4080: 70 44 61 74 61 2c 20 30 2c 20 70 43 61 63 68 65  pData, 0, pCache
4090: 2d 3e 73 7a 50 61 67 65 29 3b 0a 20 20 20 20 20  ->szPage);.     
40a0: 20 70 67 6e 6f 20 3d 20 31 3b 0a 20 20 20 20 7d   pgno = 1;.    }
40b0: 0a 20 20 20 20 73 71 6c 69 74 65 33 47 6c 6f 62  .    sqlite3Glob
40c0: 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65 32  alConfig.pcache2
40d0: 2e 78 54 72 75 6e 63 61 74 65 28 70 43 61 63 68  .xTruncate(pCach
40e0: 65 2d 3e 70 43 61 63 68 65 2c 20 70 67 6e 6f 2b  e->pCache, pgno+
40f0: 31 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a  1);.  }.}../*.**
4100: 20 43 6c 6f 73 65 20 61 20 63 61 63 68 65 2e 0a   Close a cache..
4110: 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50  */.void sqlite3P
4120: 63 61 63 68 65 43 6c 6f 73 65 28 50 43 61 63 68  cacheClose(PCach
4130: 65 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 61 73  e *pCache){.  as
4140: 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e 70 43  sert( pCache->pC
4150: 61 63 68 65 21 3d 30 20 29 3b 0a 20 20 73 71 6c  ache!=0 );.  sql
4160: 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67  ite3GlobalConfig
4170: 2e 70 63 61 63 68 65 32 2e 78 44 65 73 74 72 6f  .pcache2.xDestro
4180: 79 28 70 43 61 63 68 65 2d 3e 70 43 61 63 68 65  y(pCache->pCache
4190: 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 44 69 73  );.}../* .** Dis
41a0: 63 61 72 64 20 74 68 65 20 63 6f 6e 74 65 6e 74  card the content
41b0: 73 20 6f 66 20 74 68 65 20 63 61 63 68 65 2e 0a  s of the cache..
41c0: 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50  */.void sqlite3P
41d0: 63 61 63 68 65 43 6c 65 61 72 28 50 43 61 63 68  cacheClear(PCach
41e0: 65 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 73 71  e *pCache){.  sq
41f0: 6c 69 74 65 33 50 63 61 63 68 65 54 72 75 6e 63  lite3PcacheTrunc
4200: 61 74 65 28 70 43 61 63 68 65 2c 20 30 29 3b 0a  ate(pCache, 0);.
4210: 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 65 72 67 65 20 74  }../*.** Merge t
4220: 77 6f 20 6c 69 73 74 73 20 6f 66 20 70 61 67 65  wo lists of page
4230: 73 20 63 6f 6e 6e 65 63 74 65 64 20 62 79 20 70  s connected by p
4240: 44 69 72 74 79 20 61 6e 64 20 69 6e 20 70 67 6e  Dirty and in pgn
4250: 6f 20 6f 72 64 65 72 2e 0a 2a 2a 20 44 6f 20 6e  o order..** Do n
4260: 6f 74 20 62 6f 74 68 20 66 69 78 69 6e 67 20 74  ot both fixing t
4270: 68 65 20 70 44 69 72 74 79 50 72 65 76 20 70 6f  he pDirtyPrev po
4280: 69 6e 74 65 72 73 2e 0a 2a 2f 0a 73 74 61 74 69  inters..*/.stati
4290: 63 20 50 67 48 64 72 20 2a 70 63 61 63 68 65 4d  c PgHdr *pcacheM
42a0: 65 72 67 65 44 69 72 74 79 4c 69 73 74 28 50 67  ergeDirtyList(Pg
42b0: 48 64 72 20 2a 70 41 2c 20 50 67 48 64 72 20 2a  Hdr *pA, PgHdr *
42c0: 70 42 29 7b 0a 20 20 50 67 48 64 72 20 72 65 73  pB){.  PgHdr res
42d0: 75 6c 74 2c 20 2a 70 54 61 69 6c 3b 0a 20 20 70  ult, *pTail;.  p
42e0: 54 61 69 6c 20 3d 20 26 72 65 73 75 6c 74 3b 0a  Tail = &result;.
42f0: 20 20 77 68 69 6c 65 28 20 70 41 20 26 26 20 70    while( pA && p
4300: 42 20 29 7b 0a 20 20 20 20 69 66 28 20 70 41 2d  B ){.    if( pA-
4310: 3e 70 67 6e 6f 3c 70 42 2d 3e 70 67 6e 6f 20 29  >pgno<pB->pgno )
4320: 7b 0a 20 20 20 20 20 20 70 54 61 69 6c 2d 3e 70  {.      pTail->p
4330: 44 69 72 74 79 20 3d 20 70 41 3b 0a 20 20 20 20  Dirty = pA;.    
4340: 20 20 70 54 61 69 6c 20 3d 20 70 41 3b 0a 20 20    pTail = pA;.  
4350: 20 20 20 20 70 41 20 3d 20 70 41 2d 3e 70 44 69      pA = pA->pDi
4360: 72 74 79 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  rty;.    }else{.
4370: 20 20 20 20 20 20 70 54 61 69 6c 2d 3e 70 44 69        pTail->pDi
4380: 72 74 79 20 3d 20 70 42 3b 0a 20 20 20 20 20 20  rty = pB;.      
4390: 70 54 61 69 6c 20 3d 20 70 42 3b 0a 20 20 20 20  pTail = pB;.    
43a0: 20 20 70 42 20 3d 20 70 42 2d 3e 70 44 69 72 74    pB = pB->pDirt
43b0: 79 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69  y;.    }.  }.  i
43c0: 66 28 20 70 41 20 29 7b 0a 20 20 20 20 70 54 61  f( pA ){.    pTa
43d0: 69 6c 2d 3e 70 44 69 72 74 79 20 3d 20 70 41 3b  il->pDirty = pA;
43e0: 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 70 42 20  .  }else if( pB 
43f0: 29 7b 0a 20 20 20 20 70 54 61 69 6c 2d 3e 70 44  ){.    pTail->pD
4400: 69 72 74 79 20 3d 20 70 42 3b 0a 20 20 7d 65 6c  irty = pB;.  }el
4410: 73 65 7b 0a 20 20 20 20 70 54 61 69 6c 2d 3e 70  se{.    pTail->p
4420: 44 69 72 74 79 20 3d 20 30 3b 0a 20 20 7d 0a 20  Dirty = 0;.  }. 
4430: 20 72 65 74 75 72 6e 20 72 65 73 75 6c 74 2e 70   return result.p
4440: 44 69 72 74 79 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  Dirty;.}../*.** 
4450: 53 6f 72 74 20 74 68 65 20 6c 69 73 74 20 6f 66  Sort the list of
4460: 20 70 61 67 65 73 20 69 6e 20 61 63 63 65 6e 64   pages in accend
4470: 69 6e 67 20 6f 72 64 65 72 20 62 79 20 70 67 6e  ing order by pgn
4480: 6f 2e 20 20 50 61 67 65 73 20 61 72 65 0a 2a 2a  o.  Pages are.**
4490: 20 63 6f 6e 6e 65 63 74 65 64 20 62 79 20 70 44   connected by pD
44a0: 69 72 74 79 20 70 6f 69 6e 74 65 72 73 2e 20 20  irty pointers.  
44b0: 54 68 65 20 70 44 69 72 74 79 50 72 65 76 20 70  The pDirtyPrev p
44c0: 6f 69 6e 74 65 72 73 20 61 72 65 0a 2a 2a 20 63  ointers are.** c
44d0: 6f 72 72 75 70 74 65 64 20 62 79 20 74 68 69 73  orrupted by this
44e0: 20 73 6f 72 74 2e 0a 2a 2a 0a 2a 2a 20 53 69 6e   sort..**.** Sin
44f0: 63 65 20 74 68 65 72 65 20 63 61 6e 6e 6f 74 20  ce there cannot 
4500: 62 65 20 6d 6f 72 65 20 74 68 61 6e 20 32 5e 33  be more than 2^3
4510: 31 20 64 69 73 74 69 6e 63 74 20 70 61 67 65 73  1 distinct pages
4520: 20 69 6e 20 61 20 64 61 74 61 62 61 73 65 2c 0a   in a database,.
4530: 2a 2a 20 74 68 65 72 65 20 63 61 6e 6e 6f 74 20  ** there cannot 
4540: 62 65 20 6d 6f 72 65 20 74 68 61 6e 20 33 31 20  be more than 31 
4550: 62 75 63 6b 65 74 73 20 72 65 71 75 69 72 65 64  buckets required
4560: 20 62 79 20 74 68 65 20 6d 65 72 67 65 20 73 6f   by the merge so
4570: 72 74 65 72 2e 0a 2a 2a 20 4f 6e 65 20 65 78 74  rter..** One ext
4580: 72 61 20 62 75 63 6b 65 74 20 69 73 20 61 64 64  ra bucket is add
4590: 65 64 20 74 6f 20 63 61 74 63 68 20 6f 76 65 72  ed to catch over
45a0: 66 6c 6f 77 20 69 6e 20 63 61 73 65 20 73 6f 6d  flow in case som
45b0: 65 74 68 69 6e 67 0a 2a 2a 20 65 76 65 72 20 63  ething.** ever c
45c0: 68 61 6e 67 65 73 20 74 6f 20 6d 61 6b 65 20 74  hanges to make t
45d0: 68 65 20 70 72 65 76 69 6f 75 73 20 73 65 6e 74  he previous sent
45e0: 65 6e 63 65 20 69 6e 63 6f 72 72 65 63 74 2e 0a  ence incorrect..
45f0: 2a 2f 0a 23 64 65 66 69 6e 65 20 4e 5f 53 4f 52  */.#define N_SOR
4600: 54 5f 42 55 43 4b 45 54 20 20 33 32 0a 73 74 61  T_BUCKET  32.sta
4610: 74 69 63 20 50 67 48 64 72 20 2a 70 63 61 63 68  tic PgHdr *pcach
4620: 65 53 6f 72 74 44 69 72 74 79 4c 69 73 74 28 50  eSortDirtyList(P
4630: 67 48 64 72 20 2a 70 49 6e 29 7b 0a 20 20 50 67  gHdr *pIn){.  Pg
4640: 48 64 72 20 2a 61 5b 4e 5f 53 4f 52 54 5f 42 55  Hdr *a[N_SORT_BU
4650: 43 4b 45 54 5d 2c 20 2a 70 3b 0a 20 20 69 6e 74  CKET], *p;.  int
4660: 20 69 3b 0a 20 20 6d 65 6d 73 65 74 28 61 2c 20   i;.  memset(a, 
4670: 30 2c 20 73 69 7a 65 6f 66 28 61 29 29 3b 0a 20  0, sizeof(a));. 
4680: 20 77 68 69 6c 65 28 20 70 49 6e 20 29 7b 0a 20   while( pIn ){. 
4690: 20 20 20 70 20 3d 20 70 49 6e 3b 0a 20 20 20 20     p = pIn;.    
46a0: 70 49 6e 20 3d 20 70 2d 3e 70 44 69 72 74 79 3b  pIn = p->pDirty;
46b0: 0a 20 20 20 20 70 2d 3e 70 44 69 72 74 79 20 3d  .    p->pDirty =
46c0: 20 30 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b   0;.    for(i=0;
46d0: 20 41 4c 57 41 59 53 28 69 3c 4e 5f 53 4f 52 54   ALWAYS(i<N_SORT
46e0: 5f 42 55 43 4b 45 54 2d 31 29 3b 20 69 2b 2b 29  _BUCKET-1); i++)
46f0: 7b 0a 20 20 20 20 20 20 69 66 28 20 61 5b 69 5d  {.      if( a[i]
4700: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 61  ==0 ){.        a
4710: 5b 69 5d 20 3d 20 70 3b 0a 20 20 20 20 20 20 20  [i] = p;.       
4720: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 65   break;.      }e
4730: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 70 20 3d  lse{.        p =
4740: 20 70 63 61 63 68 65 4d 65 72 67 65 44 69 72 74   pcacheMergeDirt
4750: 79 4c 69 73 74 28 61 5b 69 5d 2c 20 70 29 3b 0a  yList(a[i], p);.
4760: 20 20 20 20 20 20 20 20 61 5b 69 5d 20 3d 20 30          a[i] = 0
4770: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
4780: 20 20 20 20 69 66 28 20 4e 45 56 45 52 28 69 3d      if( NEVER(i=
4790: 3d 4e 5f 53 4f 52 54 5f 42 55 43 4b 45 54 2d 31  =N_SORT_BUCKET-1
47a0: 29 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 54 6f  ) ){.      /* To
47b0: 20 67 65 74 20 68 65 72 65 2c 20 74 68 65 72 65   get here, there
47c0: 20 6e 65 65 64 20 74 6f 20 62 65 20 32 5e 28 4e   need to be 2^(N
47d0: 5f 53 4f 52 54 5f 42 55 43 4b 45 54 29 20 65 6c  _SORT_BUCKET) el
47e0: 65 6d 65 6e 74 73 20 69 6e 0a 20 20 20 20 20 20  ements in.      
47f0: 2a 2a 20 74 68 65 20 69 6e 70 75 74 20 6c 69 73  ** the input lis
4800: 74 2e 20 20 42 75 74 20 74 68 61 74 20 69 73 20  t.  But that is 
4810: 69 6d 70 6f 73 73 69 62 6c 65 2e 0a 20 20 20 20  impossible..    
4820: 20 20 2a 2f 0a 20 20 20 20 20 20 61 5b 69 5d 20    */.      a[i] 
4830: 3d 20 70 63 61 63 68 65 4d 65 72 67 65 44 69 72  = pcacheMergeDir
4840: 74 79 4c 69 73 74 28 61 5b 69 5d 2c 20 70 29 3b  tyList(a[i], p);
4850: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 70 20 3d  .    }.  }.  p =
4860: 20 61 5b 30 5d 3b 0a 20 20 66 6f 72 28 69 3d 31   a[0];.  for(i=1
4870: 3b 20 69 3c 4e 5f 53 4f 52 54 5f 42 55 43 4b 45  ; i<N_SORT_BUCKE
4880: 54 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 70 20 3d  T; i++){.    p =
4890: 20 70 63 61 63 68 65 4d 65 72 67 65 44 69 72 74   pcacheMergeDirt
48a0: 79 4c 69 73 74 28 70 2c 20 61 5b 69 5d 29 3b 0a  yList(p, a[i]);.
48b0: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 70 3b 0a    }.  return p;.
48c0: 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20  }../*.** Return 
48d0: 61 20 6c 69 73 74 20 6f 66 20 61 6c 6c 20 64 69  a list of all di
48e0: 72 74 79 20 70 61 67 65 73 20 69 6e 20 74 68 65  rty pages in the
48f0: 20 63 61 63 68 65 2c 20 73 6f 72 74 65 64 20 62   cache, sorted b
4900: 79 20 70 61 67 65 20 6e 75 6d 62 65 72 2e 0a 2a  y page number..*
4910: 2f 0a 50 67 48 64 72 20 2a 73 71 6c 69 74 65 33  /.PgHdr *sqlite3
4920: 50 63 61 63 68 65 44 69 72 74 79 4c 69 73 74 28  PcacheDirtyList(
4930: 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b  PCache *pCache){
4940: 0a 20 20 50 67 48 64 72 20 2a 70 3b 0a 20 20 66  .  PgHdr *p;.  f
4950: 6f 72 28 70 3d 70 43 61 63 68 65 2d 3e 70 44 69  or(p=pCache->pDi
4960: 72 74 79 3b 20 70 3b 20 70 3d 70 2d 3e 70 44 69  rty; p; p=p->pDi
4970: 72 74 79 4e 65 78 74 29 7b 0a 20 20 20 20 70 2d  rtyNext){.    p-
4980: 3e 70 44 69 72 74 79 20 3d 20 70 2d 3e 70 44 69  >pDirty = p->pDi
4990: 72 74 79 4e 65 78 74 3b 0a 20 20 7d 0a 20 20 72  rtyNext;.  }.  r
49a0: 65 74 75 72 6e 20 70 63 61 63 68 65 53 6f 72 74  eturn pcacheSort
49b0: 44 69 72 74 79 4c 69 73 74 28 70 43 61 63 68 65  DirtyList(pCache
49c0: 2d 3e 70 44 69 72 74 79 29 3b 0a 7d 0a 0a 2f 2a  ->pDirty);.}../*
49d0: 20 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20   .** Return the 
49e0: 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20  total number of 
49f0: 72 65 66 65 72 65 6e 63 65 64 20 70 61 67 65 73  referenced pages
4a00: 20 68 65 6c 64 20 62 79 20 74 68 65 20 63 61 63   held by the cac
4a10: 68 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  he..*/.int sqlit
4a20: 65 33 50 63 61 63 68 65 52 65 66 43 6f 75 6e 74  e3PcacheRefCount
4a30: 28 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 29  (PCache *pCache)
4a40: 7b 0a 20 20 72 65 74 75 72 6e 20 70 43 61 63 68  {.  return pCach
4a50: 65 2d 3e 6e 52 65 66 3b 0a 7d 0a 0a 2f 2a 0a 2a  e->nRef;.}../*.*
4a60: 2a 20 52 65 74 75 72 6e 20 74 68 65 20 6e 75 6d  * Return the num
4a70: 62 65 72 20 6f 66 20 72 65 66 65 72 65 6e 63 65  ber of reference
4a80: 73 20 74 6f 20 74 68 65 20 70 61 67 65 20 73 75  s to the page su
4a90: 70 70 6c 69 65 64 20 61 73 20 61 6e 20 61 72 67  pplied as an arg
4aa0: 75 6d 65 6e 74 2e 0a 2a 2f 0a 69 6e 74 20 73 71  ument..*/.int sq
4ab0: 6c 69 74 65 33 50 63 61 63 68 65 50 61 67 65 52  lite3PcachePageR
4ac0: 65 66 63 6f 75 6e 74 28 50 67 48 64 72 20 2a 70  efcount(PgHdr *p
4ad0: 29 7b 0a 20 20 72 65 74 75 72 6e 20 70 2d 3e 6e  ){.  return p->n
4ae0: 52 65 66 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 52  Ref;.}../* .** R
4af0: 65 74 75 72 6e 20 74 68 65 20 74 6f 74 61 6c 20  eturn the total 
4b00: 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20  number of pages 
4b10: 69 6e 20 74 68 65 20 63 61 63 68 65 2e 0a 2a 2f  in the cache..*/
4b20: 0a 69 6e 74 20 73 71 6c 69 74 65 33 50 63 61 63  .int sqlite3Pcac
4b30: 68 65 50 61 67 65 63 6f 75 6e 74 28 50 43 61 63  hePagecount(PCac
4b40: 68 65 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 61  he *pCache){.  a
4b50: 73 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e 70  ssert( pCache->p
4b60: 43 61 63 68 65 21 3d 30 20 29 3b 0a 20 20 72 65  Cache!=0 );.  re
4b70: 74 75 72 6e 20 73 71 6c 69 74 65 33 47 6c 6f 62  turn sqlite3Glob
4b80: 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65 32  alConfig.pcache2
4b90: 2e 78 50 61 67 65 63 6f 75 6e 74 28 70 43 61 63  .xPagecount(pCac
4ba0: 68 65 2d 3e 70 43 61 63 68 65 29 3b 0a 7d 0a 0a  he->pCache);.}..
4bb0: 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 54 45  #ifdef SQLITE_TE
4bc0: 53 54 0a 2f 2a 0a 2a 2a 20 47 65 74 20 74 68 65  ST./*.** Get the
4bd0: 20 73 75 67 67 65 73 74 65 64 20 63 61 63 68 65   suggested cache
4be0: 2d 73 69 7a 65 20 76 61 6c 75 65 2e 0a 2a 2f 0a  -size value..*/.
4bf0: 69 6e 74 20 73 71 6c 69 74 65 33 50 63 61 63 68  int sqlite3Pcach
4c00: 65 47 65 74 43 61 63 68 65 73 69 7a 65 28 50 43  eGetCachesize(PC
4c10: 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b 0a 20  ache *pCache){. 
4c20: 20 72 65 74 75 72 6e 20 6e 75 6d 62 65 72 4f 66   return numberOf
4c30: 43 61 63 68 65 50 61 67 65 73 28 70 43 61 63 68  CachePages(pCach
4c40: 65 29 3b 0a 7d 0a 23 65 6e 64 69 66 0a 0a 2f 2a  e);.}.#endif../*
4c50: 0a 2a 2a 20 53 65 74 20 74 68 65 20 73 75 67 67  .** Set the sugg
4c60: 65 73 74 65 64 20 63 61 63 68 65 2d 73 69 7a 65  ested cache-size
4c70: 20 76 61 6c 75 65 2e 0a 2a 2f 0a 76 6f 69 64 20   value..*/.void 
4c80: 73 71 6c 69 74 65 33 50 63 61 63 68 65 53 65 74  sqlite3PcacheSet
4c90: 43 61 63 68 65 73 69 7a 65 28 50 43 61 63 68 65  Cachesize(PCache
4ca0: 20 2a 70 43 61 63 68 65 2c 20 69 6e 74 20 6d 78   *pCache, int mx
4cb0: 50 61 67 65 29 7b 0a 20 20 61 73 73 65 72 74 28  Page){.  assert(
4cc0: 20 70 43 61 63 68 65 2d 3e 70 43 61 63 68 65 21   pCache->pCache!
4cd0: 3d 30 20 29 3b 0a 20 20 70 43 61 63 68 65 2d 3e  =0 );.  pCache->
4ce0: 73 7a 43 61 63 68 65 20 3d 20 6d 78 50 61 67 65  szCache = mxPage
4cf0: 3b 0a 20 20 73 71 6c 69 74 65 33 47 6c 6f 62 61  ;.  sqlite3Globa
4d00: 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65 32 2e  lConfig.pcache2.
4d10: 78 43 61 63 68 65 73 69 7a 65 28 70 43 61 63 68  xCachesize(pCach
4d20: 65 2d 3e 70 43 61 63 68 65 2c 0a 20 20 20 20 20  e->pCache,.     
4d30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4d40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4d50: 20 20 20 20 6e 75 6d 62 65 72 4f 66 43 61 63 68      numberOfCach
4d60: 65 50 61 67 65 73 28 70 43 61 63 68 65 29 29 3b  ePages(pCache));
4d70: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 75  .}../*.** Free u
4d80: 70 20 61 73 20 6d 75 63 68 20 6d 65 6d 6f 72 79  p as much memory
4d90: 20 61 73 20 70 6f 73 73 69 62 6c 65 20 66 72 6f   as possible fro
4da0: 6d 20 74 68 65 20 70 61 67 65 20 63 61 63 68 65  m the page cache
4db0: 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
4dc0: 33 50 63 61 63 68 65 53 68 72 69 6e 6b 28 50 43  3PcacheShrink(PC
4dd0: 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b 0a 20  ache *pCache){. 
4de0: 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65 2d   assert( pCache-
4df0: 3e 70 43 61 63 68 65 21 3d 30 20 29 3b 0a 20 20  >pCache!=0 );.  
4e00: 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e  sqlite3GlobalCon
4e10: 66 69 67 2e 70 63 61 63 68 65 32 2e 78 53 68 72  fig.pcache2.xShr
4e20: 69 6e 6b 28 70 43 61 63 68 65 2d 3e 70 43 61 63  ink(pCache->pCac
4e30: 68 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65  he);.}../*.** Re
4e40: 74 75 72 6e 20 74 68 65 20 73 69 7a 65 20 6f 66  turn the size of
4e50: 20 74 68 65 20 68 65 61 64 65 72 20 61 64 64 65   the header adde
4e60: 64 20 62 79 20 74 68 69 73 20 6d 69 64 64 6c 65  d by this middle
4e70: 77 61 72 65 20 6c 61 79 65 72 0a 2a 2a 20 69 6e  ware layer.** in
4e80: 20 74 68 65 20 70 61 67 65 2d 63 61 63 68 65 20   the page-cache 
4e90: 68 69 65 72 61 72 63 68 79 2e 0a 2a 2f 0a 69 6e  hierarchy..*/.in
4ea0: 74 20 73 71 6c 69 74 65 33 48 65 61 64 65 72 53  t sqlite3HeaderS
4eb0: 69 7a 65 50 63 61 63 68 65 28 76 6f 69 64 29 7b  izePcache(void){
4ec0: 20 72 65 74 75 72 6e 20 52 4f 55 4e 44 38 28 73   return ROUND8(s
4ed0: 69 7a 65 6f 66 28 50 67 48 64 72 29 29 3b 20 7d  izeof(PgHdr)); }
4ee0: 0a 0a 0a 23 69 66 20 64 65 66 69 6e 65 64 28 53  ...#if defined(S
4ef0: 51 4c 49 54 45 5f 43 48 45 43 4b 5f 50 41 47 45  QLITE_CHECK_PAGE
4f00: 53 29 20 7c 7c 20 64 65 66 69 6e 65 64 28 53 51  S) || defined(SQ
4f10: 4c 49 54 45 5f 44 45 42 55 47 29 0a 2f 2a 0a 2a  LITE_DEBUG)./*.*
4f20: 2a 20 46 6f 72 20 61 6c 6c 20 64 69 72 74 79 20  * For all dirty 
4f30: 70 61 67 65 73 20 63 75 72 72 65 6e 74 6c 79 20  pages currently 
4f40: 69 6e 20 74 68 65 20 63 61 63 68 65 2c 20 69 6e  in the cache, in
4f50: 76 6f 6b 65 20 74 68 65 20 73 70 65 63 69 66 69  voke the specifi
4f60: 65 64 0a 2a 2a 20 63 61 6c 6c 62 61 63 6b 2e 20  ed.** callback. 
4f70: 54 68 69 73 20 69 73 20 6f 6e 6c 79 20 75 73 65  This is only use
4f80: 64 20 69 66 20 74 68 65 20 53 51 4c 49 54 45 5f  d if the SQLITE_
4f90: 43 48 45 43 4b 5f 50 41 47 45 53 20 6d 61 63 72  CHECK_PAGES macr
4fa0: 6f 20 69 73 0a 2a 2a 20 64 65 66 69 6e 65 64 2e  o is.** defined.
4fb0: 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33  .*/.void sqlite3
4fc0: 50 63 61 63 68 65 49 74 65 72 61 74 65 44 69 72  PcacheIterateDir
4fd0: 74 79 28 50 43 61 63 68 65 20 2a 70 43 61 63 68  ty(PCache *pCach
4fe0: 65 2c 20 76 6f 69 64 20 28 2a 78 49 74 65 72 29  e, void (*xIter)
4ff0: 28 50 67 48 64 72 20 2a 29 29 7b 0a 20 20 50 67  (PgHdr *)){.  Pg
5000: 48 64 72 20 2a 70 44 69 72 74 79 3b 0a 20 20 66  Hdr *pDirty;.  f
5010: 6f 72 28 70 44 69 72 74 79 3d 70 43 61 63 68 65  or(pDirty=pCache
5020: 2d 3e 70 44 69 72 74 79 3b 20 70 44 69 72 74 79  ->pDirty; pDirty
5030: 3b 20 70 44 69 72 74 79 3d 70 44 69 72 74 79 2d  ; pDirty=pDirty-
5040: 3e 70 44 69 72 74 79 4e 65 78 74 29 7b 0a 20 20  >pDirtyNext){.  
5050: 20 20 78 49 74 65 72 28 70 44 69 72 74 79 29 3b    xIter(pDirty);
5060: 0a 20 20 7d 0a 7d 0a 23 65 6e 64 69 66 0a        .  }.}.#endif.