/ Hex Artifact Content
Login

Artifact 48fbfc2208a2734c578b3223fcd4fea7d84f442b:


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 2a 0a   page cache..**.
01a0: 2a 2a 20 40 28 23 29 20 24 49 64 3a 20 70 63 61  ** @(#) $Id: pca
01b0: 63 68 65 2e 63 2c 76 20 31 2e 34 32 20 32 30 30  che.c,v 1.42 200
01c0: 39 2f 30 31 2f 32 30 20 31 37 3a 30 36 3a 32 37  9/01/20 17:06:27
01d0: 20 64 61 6e 69 65 6c 6b 31 39 37 37 20 45 78 70   danielk1977 Exp
01e0: 20 24 0a 2a 2f 0a 23 69 6e 63 6c 75 64 65 20 22   $.*/.#include "
01f0: 73 71 6c 69 74 65 49 6e 74 2e 68 22 0a 0a 2f 2a  sqliteInt.h"../*
0200: 0a 2a 2a 20 41 20 63 6f 6d 70 6c 65 74 65 20 70  .** A complete p
0210: 61 67 65 20 63 61 63 68 65 20 69 73 20 61 6e 20  age cache is an 
0220: 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 69 73  instance of this
0230: 20 73 74 72 75 63 74 75 72 65 2e 0a 2a 2f 0a 73   structure..*/.s
0240: 74 72 75 63 74 20 50 43 61 63 68 65 20 7b 0a 20  truct PCache {. 
0250: 20 50 67 48 64 72 20 2a 70 44 69 72 74 79 2c 20   PgHdr *pDirty, 
0260: 2a 70 44 69 72 74 79 54 61 69 6c 3b 20 20 20 20  *pDirtyTail;    
0270: 20 20 20 20 20 2f 2a 20 4c 69 73 74 20 6f 66 20       /* List of 
0280: 64 69 72 74 79 20 70 61 67 65 73 20 69 6e 20 4c  dirty pages in L
0290: 52 55 20 6f 72 64 65 72 20 2a 2f 0a 20 20 50 67  RU order */.  Pg
02a0: 48 64 72 20 2a 70 53 79 6e 63 65 64 3b 20 20 20  Hdr *pSynced;   
02b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
02c0: 20 20 2f 2a 20 4c 61 73 74 20 73 79 6e 63 65 64    /* Last synced
02d0: 20 70 61 67 65 20 69 6e 20 64 69 72 74 79 20 70   page in dirty p
02e0: 61 67 65 20 6c 69 73 74 20 2a 2f 0a 20 20 69 6e  age list */.  in
02f0: 74 20 6e 52 65 66 3b 20 20 20 20 20 20 20 20 20  t nRef;         
0300: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0310: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 72    /* Number of r
0320: 65 66 65 72 65 6e 63 65 64 20 70 61 67 65 73 20  eferenced pages 
0330: 2a 2f 0a 20 20 69 6e 74 20 6e 4d 61 78 3b 20 20  */.  int nMax;  
0340: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0350: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6e 66           /* Conf
0360: 69 67 75 72 65 64 20 63 61 63 68 65 20 73 69 7a  igured cache siz
0370: 65 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 50 61 67  e */.  int szPag
0380: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
0390: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69             /* Si
03a0: 7a 65 20 6f 66 20 65 76 65 72 79 20 70 61 67 65  ze of every page
03b0: 20 69 6e 20 74 68 69 73 20 63 61 63 68 65 20 2a   in this cache *
03c0: 2f 0a 20 20 69 6e 74 20 73 7a 45 78 74 72 61 3b  /.  int szExtra;
03d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
03e0: 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
03f0: 6f 66 20 65 78 74 72 61 20 73 70 61 63 65 20 66  of extra space f
0400: 6f 72 20 65 61 63 68 20 70 61 67 65 20 2a 2f 0a  or each page */.
0410: 20 20 69 6e 74 20 62 50 75 72 67 65 61 62 6c 65    int bPurgeable
0420: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
0430: 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66        /* True if
0440: 20 70 61 67 65 73 20 61 72 65 20 6f 6e 20 62 61   pages are on ba
0450: 63 6b 69 6e 67 20 73 74 6f 72 65 20 2a 2f 0a 20  cking store */. 
0460: 20 69 6e 74 20 28 2a 78 53 74 72 65 73 73 29 28   int (*xStress)(
0470: 76 6f 69 64 2a 2c 50 67 48 64 72 2a 29 3b 20 20  void*,PgHdr*);  
0480: 20 20 20 20 20 2f 2a 20 43 61 6c 6c 20 74 6f 20       /* Call to 
0490: 74 72 79 20 6d 61 6b 65 20 61 20 70 61 67 65 20  try make a page 
04a0: 63 6c 65 61 6e 20 2a 2f 0a 20 20 76 6f 69 64 20  clean */.  void 
04b0: 2a 70 53 74 72 65 73 73 3b 20 20 20 20 20 20 20  *pStress;       
04c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
04d0: 2a 20 41 72 67 75 6d 65 6e 74 20 74 6f 20 78 53  * Argument to xS
04e0: 74 72 65 73 73 20 2a 2f 0a 20 20 73 71 6c 69 74  tress */.  sqlit
04f0: 65 33 5f 70 63 61 63 68 65 20 2a 70 43 61 63 68  e3_pcache *pCach
0500: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  e;             /
0510: 2a 20 50 6c 75 67 67 61 62 6c 65 20 63 61 63 68  * Pluggable cach
0520: 65 20 6d 6f 64 75 6c 65 20 2a 2f 0a 20 20 50 67  e module */.  Pg
0530: 48 64 72 20 2a 70 50 61 67 65 31 3b 20 20 20 20  Hdr *pPage1;    
0540: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0550: 20 20 2f 2a 20 52 65 66 65 72 65 6e 63 65 20 74    /* Reference t
0560: 6f 20 70 61 67 65 20 31 20 2a 2f 0a 7d 3b 0a 0a  o page 1 */.};..
0570: 2f 2a 0a 2a 2a 20 53 6f 6d 65 20 6f 66 20 74 68  /*.** Some of th
0580: 65 20 61 73 73 65 72 74 28 29 20 6d 61 63 72 6f  e assert() macro
0590: 73 20 69 6e 20 74 68 69 73 20 63 6f 64 65 20 61  s in this code a
05a0: 72 65 20 74 6f 6f 20 65 78 70 65 6e 73 69 76 65  re too expensive
05b0: 20 74 6f 20 72 75 6e 0a 2a 2a 20 65 76 65 6e 20   to run.** even 
05c0: 64 75 72 69 6e 67 20 6e 6f 72 6d 61 6c 20 64 65  during normal de
05d0: 62 75 67 67 69 6e 67 2e 20 20 55 73 65 20 74 68  bugging.  Use th
05e0: 65 6d 20 6f 6e 6c 79 20 72 61 72 65 6c 79 20 6f  em only rarely o
05f0: 6e 20 6c 6f 6e 67 2d 72 75 6e 6e 69 6e 67 0a 2a  n long-running.*
0600: 2a 20 74 65 73 74 73 2e 20 20 45 6e 61 62 6c 65  * tests.  Enable
0610: 20 74 68 65 20 65 78 70 65 6e 73 69 76 65 20 61   the expensive a
0620: 73 73 65 72 74 73 20 75 73 69 6e 67 20 74 68 65  sserts using the
0630: 0a 2a 2a 20 2d 44 53 51 4c 49 54 45 5f 45 4e 41  .** -DSQLITE_ENA
0640: 42 4c 45 5f 45 58 50 45 4e 53 49 56 45 5f 41 53  BLE_EXPENSIVE_AS
0650: 53 45 52 54 3d 31 20 63 6f 6d 70 69 6c 65 2d 74  SERT=1 compile-t
0660: 69 6d 65 20 6f 70 74 69 6f 6e 2e 0a 2a 2f 0a 23  ime option..*/.#
0670: 69 66 64 65 66 20 53 51 4c 49 54 45 5f 45 4e 41  ifdef SQLITE_ENA
0680: 42 4c 45 5f 45 58 50 45 4e 53 49 56 45 5f 41 53  BLE_EXPENSIVE_AS
0690: 53 45 52 54 0a 23 20 64 65 66 69 6e 65 20 65 78  SERT.# define ex
06a0: 70 65 6e 73 69 76 65 5f 61 73 73 65 72 74 28 58  pensive_assert(X
06b0: 29 20 20 61 73 73 65 72 74 28 58 29 0a 23 65 6c  )  assert(X).#el
06c0: 73 65 0a 23 20 64 65 66 69 6e 65 20 65 78 70 65  se.# define expe
06d0: 6e 73 69 76 65 5f 61 73 73 65 72 74 28 58 29 0a  nsive_assert(X).
06e0: 23 65 6e 64 69 66 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a  #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 20 4c 69 6e 6b  *********** Link
0710: 65 64 20 4c 69 73 74 20 4d 61 6e 61 67 65 6d 65  ed List Manageme
0720: 6e 74 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  nt *************
0730: 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 23 69 66 20 21 64  *******/..#if !d
0740: 65 66 69 6e 65 64 28 4e 44 45 42 55 47 29 20 26  efined(NDEBUG) &
0750: 26 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45  & defined(SQLITE
0760: 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49 56  _ENABLE_EXPENSIV
0770: 45 5f 41 53 53 45 52 54 29 0a 2f 2a 0a 2a 2a 20  E_ASSERT)./*.** 
0780: 43 68 65 63 6b 20 74 68 61 74 20 74 68 65 20 70  Check that the p
0790: 43 61 63 68 65 2d 3e 70 53 79 6e 63 65 64 20 76  Cache->pSynced v
07a0: 61 72 69 61 62 6c 65 20 69 73 20 73 65 74 20 63  ariable is set c
07b0: 6f 72 72 65 63 74 6c 79 2e 20 49 66 20 69 74 0a  orrectly. If it.
07c0: 2a 2a 20 69 73 20 6e 6f 74 2c 20 65 69 74 68 65  ** is not, eithe
07d0: 72 20 66 61 69 6c 20 61 6e 20 61 73 73 65 72 74  r fail an assert
07e0: 20 6f 72 20 72 65 74 75 72 6e 20 7a 65 72 6f 2e   or return zero.
07f0: 20 4f 74 68 65 72 77 69 73 65 2c 20 72 65 74 75   Otherwise, retu
0800: 72 6e 0a 2a 2a 20 6e 6f 6e 2d 7a 65 72 6f 2e 20  rn.** non-zero. 
0810: 54 68 69 73 20 69 73 20 6f 6e 6c 79 20 75 73 65  This is only use
0820: 64 20 69 6e 20 64 65 62 75 67 67 69 6e 67 20 62  d in debugging b
0830: 75 69 6c 64 73 2c 20 61 73 20 66 6f 6c 6c 6f 77  uilds, as follow
0840: 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 65 78 70 65 6e  s:.**.**   expen
0850: 73 69 76 65 5f 61 73 73 65 72 74 28 20 70 63 61  sive_assert( pca
0860: 63 68 65 43 68 65 63 6b 53 79 6e 63 65 64 28 70  cheCheckSynced(p
0870: 43 61 63 68 65 29 20 29 3b 0a 2a 2f 0a 73 74 61  Cache) );.*/.sta
0880: 74 69 63 20 69 6e 74 20 70 63 61 63 68 65 43 68  tic int pcacheCh
0890: 65 63 6b 53 79 6e 63 65 64 28 50 43 61 63 68 65  eckSynced(PCache
08a0: 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 50 67 48   *pCache){.  PgH
08b0: 64 72 20 2a 70 3b 0a 20 20 66 6f 72 28 70 3d 70  dr *p;.  for(p=p
08c0: 43 61 63 68 65 2d 3e 70 44 69 72 74 79 54 61 69  Cache->pDirtyTai
08d0: 6c 3b 20 70 21 3d 70 43 61 63 68 65 2d 3e 70 53  l; p!=pCache->pS
08e0: 79 6e 63 65 64 3b 20 70 3d 70 2d 3e 70 44 69 72  ynced; p=p->pDir
08f0: 74 79 50 72 65 76 29 7b 0a 20 20 20 20 61 73 73  tyPrev){.    ass
0900: 65 72 74 28 20 70 2d 3e 6e 52 65 66 20 7c 7c 20  ert( p->nRef || 
0910: 28 70 2d 3e 66 6c 61 67 73 26 50 47 48 44 52 5f  (p->flags&PGHDR_
0920: 4e 45 45 44 5f 53 59 4e 43 29 20 29 3b 0a 20 20  NEED_SYNC) );.  
0930: 7d 0a 20 20 72 65 74 75 72 6e 20 28 70 3d 3d 30  }.  return (p==0
0940: 20 7c 7c 20 70 2d 3e 6e 52 65 66 20 7c 7c 20 28   || p->nRef || (
0950: 70 2d 3e 66 6c 61 67 73 26 50 47 48 44 52 5f 4e  p->flags&PGHDR_N
0960: 45 45 44 5f 53 59 4e 43 29 3d 3d 30 29 3b 0a 7d  EED_SYNC)==0);.}
0970: 0a 23 65 6e 64 69 66 20 2f 2a 20 21 4e 44 45 42  .#endif /* !NDEB
0980: 55 47 20 26 26 20 53 51 4c 49 54 45 5f 45 4e 41  UG && SQLITE_ENA
0990: 42 4c 45 5f 45 58 50 45 4e 53 49 56 45 5f 41 53  BLE_EXPENSIVE_AS
09a0: 53 45 52 54 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 52  SERT */../*.** R
09b0: 65 6d 6f 76 65 20 70 61 67 65 20 70 50 61 67 65  emove page pPage
09c0: 20 66 72 6f 6d 20 74 68 65 20 6c 69 73 74 20 6f   from the list o
09d0: 66 20 64 69 72 74 79 20 70 61 67 65 73 2e 0a 2a  f dirty pages..*
09e0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63  /.static void pc
09f0: 61 63 68 65 52 65 6d 6f 76 65 46 72 6f 6d 44 69  acheRemoveFromDi
0a00: 72 74 79 4c 69 73 74 28 50 67 48 64 72 20 2a 70  rtyList(PgHdr *p
0a10: 50 61 67 65 29 7b 0a 20 20 50 43 61 63 68 65 20  Page){.  PCache 
0a20: 2a 70 20 3d 20 70 50 61 67 65 2d 3e 70 43 61 63  *p = pPage->pCac
0a30: 68 65 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70  he;..  assert( p
0a40: 50 61 67 65 2d 3e 70 44 69 72 74 79 4e 65 78 74  Page->pDirtyNext
0a50: 20 7c 7c 20 70 50 61 67 65 3d 3d 70 2d 3e 70 44   || pPage==p->pD
0a60: 69 72 74 79 54 61 69 6c 20 29 3b 0a 20 20 61 73  irtyTail );.  as
0a70: 73 65 72 74 28 20 70 50 61 67 65 2d 3e 70 44 69  sert( pPage->pDi
0a80: 72 74 79 50 72 65 76 20 7c 7c 20 70 50 61 67 65  rtyPrev || pPage
0a90: 3d 3d 70 2d 3e 70 44 69 72 74 79 20 29 3b 0a 0a  ==p->pDirty );..
0aa0: 20 20 2f 2a 20 55 70 64 61 74 65 20 74 68 65 20    /* Update the 
0ab0: 50 43 61 63 68 65 31 2e 70 53 79 6e 63 65 64 20  PCache1.pSynced 
0ac0: 76 61 72 69 61 62 6c 65 20 69 66 20 6e 65 63 65  variable if nece
0ad0: 73 73 61 72 79 2e 20 2a 2f 0a 20 20 69 66 28 20  ssary. */.  if( 
0ae0: 70 2d 3e 70 53 79 6e 63 65 64 3d 3d 70 50 61 67  p->pSynced==pPag
0af0: 65 20 29 7b 0a 20 20 20 20 50 67 48 64 72 20 2a  e ){.    PgHdr *
0b00: 70 53 79 6e 63 65 64 20 3d 20 70 50 61 67 65 2d  pSynced = pPage-
0b10: 3e 70 44 69 72 74 79 50 72 65 76 3b 0a 20 20 20  >pDirtyPrev;.   
0b20: 20 77 68 69 6c 65 28 20 70 53 79 6e 63 65 64 20   while( pSynced 
0b30: 26 26 20 28 70 53 79 6e 63 65 64 2d 3e 66 6c 61  && (pSynced->fla
0b40: 67 73 26 50 47 48 44 52 5f 4e 45 45 44 5f 53 59  gs&PGHDR_NEED_SY
0b50: 4e 43 29 20 29 7b 0a 20 20 20 20 20 20 70 53 79  NC) ){.      pSy
0b60: 6e 63 65 64 20 3d 20 70 53 79 6e 63 65 64 2d 3e  nced = pSynced->
0b70: 70 44 69 72 74 79 50 72 65 76 3b 0a 20 20 20 20  pDirtyPrev;.    
0b80: 7d 0a 20 20 20 20 70 2d 3e 70 53 79 6e 63 65 64  }.    p->pSynced
0b90: 20 3d 20 70 53 79 6e 63 65 64 3b 0a 20 20 7d 0a   = pSynced;.  }.
0ba0: 0a 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: 70 50 61 67 65 2d 3e 70 44 69 72 74 79 4e 65 78  pPage->pDirtyNex
0bd0: 74 2d 3e 70 44 69 72 74 79 50 72 65 76 20 3d 20  t->pDirtyPrev = 
0be0: 70 50 61 67 65 2d 3e 70 44 69 72 74 79 50 72 65  pPage->pDirtyPre
0bf0: 76 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  v;.  }else{.    
0c00: 61 73 73 65 72 74 28 20 70 50 61 67 65 3d 3d 70  assert( pPage==p
0c10: 2d 3e 70 44 69 72 74 79 54 61 69 6c 20 29 3b 0a  ->pDirtyTail );.
0c20: 20 20 20 20 70 2d 3e 70 44 69 72 74 79 54 61 69      p->pDirtyTai
0c30: 6c 20 3d 20 70 50 61 67 65 2d 3e 70 44 69 72 74  l = pPage->pDirt
0c40: 79 50 72 65 76 3b 0a 20 20 7d 0a 20 20 69 66 28  yPrev;.  }.  if(
0c50: 20 70 50 61 67 65 2d 3e 70 44 69 72 74 79 50 72   pPage->pDirtyPr
0c60: 65 76 20 29 7b 0a 20 20 20 20 70 50 61 67 65 2d  ev ){.    pPage-
0c70: 3e 70 44 69 72 74 79 50 72 65 76 2d 3e 70 44 69  >pDirtyPrev->pDi
0c80: 72 74 79 4e 65 78 74 20 3d 20 70 50 61 67 65 2d  rtyNext = pPage-
0c90: 3e 70 44 69 72 74 79 4e 65 78 74 3b 0a 20 20 7d  >pDirtyNext;.  }
0ca0: 65 6c 73 65 7b 0a 20 20 20 20 61 73 73 65 72 74  else{.    assert
0cb0: 28 20 70 50 61 67 65 3d 3d 70 2d 3e 70 44 69 72  ( pPage==p->pDir
0cc0: 74 79 20 29 3b 0a 20 20 20 20 70 2d 3e 70 44 69  ty );.    p->pDi
0cd0: 72 74 79 20 3d 20 70 50 61 67 65 2d 3e 70 44 69  rty = pPage->pDi
0ce0: 72 74 79 4e 65 78 74 3b 0a 20 20 7d 0a 20 20 70  rtyNext;.  }.  p
0cf0: 50 61 67 65 2d 3e 70 44 69 72 74 79 4e 65 78 74  Page->pDirtyNext
0d00: 20 3d 20 30 3b 0a 20 20 70 50 61 67 65 2d 3e 70   = 0;.  pPage->p
0d10: 44 69 72 74 79 50 72 65 76 20 3d 20 30 3b 0a 0a  DirtyPrev = 0;..
0d20: 20 20 65 78 70 65 6e 73 69 76 65 5f 61 73 73 65    expensive_asse
0d30: 72 74 28 20 70 63 61 63 68 65 43 68 65 63 6b 53  rt( pcacheCheckS
0d40: 79 6e 63 65 64 28 70 29 20 29 3b 0a 7d 0a 0a 2f  ynced(p) );.}../
0d50: 2a 0a 2a 2a 20 41 64 64 20 70 61 67 65 20 70 50  *.** Add page pP
0d60: 61 67 65 20 74 6f 20 74 68 65 20 68 65 61 64 20  age to the head 
0d70: 6f 66 20 74 68 65 20 64 69 72 74 79 20 6c 69 73  of the dirty lis
0d80: 74 20 28 50 43 61 63 68 65 31 2e 70 44 69 72 74  t (PCache1.pDirt
0d90: 79 20 69 73 20 73 65 74 20 74 6f 0a 2a 2a 20 70  y is set to.** p
0da0: 50 61 67 65 29 2e 0a 2a 2f 0a 73 74 61 74 69 63  Page)..*/.static
0db0: 20 76 6f 69 64 20 70 63 61 63 68 65 41 64 64 54   void pcacheAddT
0dc0: 6f 44 69 72 74 79 4c 69 73 74 28 50 67 48 64 72  oDirtyList(PgHdr
0dd0: 20 2a 70 50 61 67 65 29 7b 0a 20 20 50 43 61 63   *pPage){.  PCac
0de0: 68 65 20 2a 70 20 3d 20 70 50 61 67 65 2d 3e 70  he *p = pPage->p
0df0: 43 61 63 68 65 3b 0a 0a 20 20 61 73 73 65 72 74  Cache;..  assert
0e00: 28 20 70 50 61 67 65 2d 3e 70 44 69 72 74 79 4e  ( pPage->pDirtyN
0e10: 65 78 74 3d 3d 30 20 26 26 20 70 50 61 67 65 2d  ext==0 && pPage-
0e20: 3e 70 44 69 72 74 79 50 72 65 76 3d 3d 30 20 26  >pDirtyPrev==0 &
0e30: 26 20 70 2d 3e 70 44 69 72 74 79 21 3d 70 50 61  & p->pDirty!=pPa
0e40: 67 65 20 29 3b 0a 0a 20 20 70 50 61 67 65 2d 3e  ge );..  pPage->
0e50: 70 44 69 72 74 79 4e 65 78 74 20 3d 20 70 2d 3e  pDirtyNext = p->
0e60: 70 44 69 72 74 79 3b 0a 20 20 69 66 28 20 70 50  pDirty;.  if( pP
0e70: 61 67 65 2d 3e 70 44 69 72 74 79 4e 65 78 74 20  age->pDirtyNext 
0e80: 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70  ){.    assert( p
0e90: 50 61 67 65 2d 3e 70 44 69 72 74 79 4e 65 78 74  Page->pDirtyNext
0ea0: 2d 3e 70 44 69 72 74 79 50 72 65 76 3d 3d 30 20  ->pDirtyPrev==0 
0eb0: 29 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 44  );.    pPage->pD
0ec0: 69 72 74 79 4e 65 78 74 2d 3e 70 44 69 72 74 79  irtyNext->pDirty
0ed0: 50 72 65 76 20 3d 20 70 50 61 67 65 3b 0a 20 20  Prev = pPage;.  
0ee0: 7d 0a 20 20 70 2d 3e 70 44 69 72 74 79 20 3d 20  }.  p->pDirty = 
0ef0: 70 50 61 67 65 3b 0a 20 20 69 66 28 20 21 70 2d  pPage;.  if( !p-
0f00: 3e 70 44 69 72 74 79 54 61 69 6c 20 29 7b 0a 20  >pDirtyTail ){. 
0f10: 20 20 20 70 2d 3e 70 44 69 72 74 79 54 61 69 6c     p->pDirtyTail
0f20: 20 3d 20 70 50 61 67 65 3b 0a 20 20 7d 0a 20 20   = pPage;.  }.  
0f30: 69 66 28 20 21 70 2d 3e 70 53 79 6e 63 65 64 20  if( !p->pSynced 
0f40: 26 26 20 30 3d 3d 28 70 50 61 67 65 2d 3e 66 6c  && 0==(pPage->fl
0f50: 61 67 73 26 50 47 48 44 52 5f 4e 45 45 44 5f 53  ags&PGHDR_NEED_S
0f60: 59 4e 43 29 20 29 7b 0a 20 20 20 20 70 2d 3e 70  YNC) ){.    p->p
0f70: 53 79 6e 63 65 64 20 3d 20 70 50 61 67 65 3b 0a  Synced = pPage;.
0f80: 20 20 7d 0a 20 20 65 78 70 65 6e 73 69 76 65 5f    }.  expensive_
0f90: 61 73 73 65 72 74 28 20 70 63 61 63 68 65 43 68  assert( pcacheCh
0fa0: 65 63 6b 53 79 6e 63 65 64 28 70 29 20 29 3b 0a  eckSynced(p) );.
0fb0: 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 61 70 70 65 72  }../*.** Wrapper
0fc0: 20 61 72 6f 75 6e 64 20 74 68 65 20 70 6c 75 67   around the plug
0fd0: 67 61 62 6c 65 20 63 61 63 68 65 73 20 78 55 6e  gable caches xUn
0fe0: 70 69 6e 20 6d 65 74 68 6f 64 2e 20 49 66 20 74  pin method. If t
0ff0: 68 65 20 63 61 63 68 65 20 69 73 0a 2a 2a 20 62  he cache is.** b
1000: 65 69 6e 67 20 75 73 65 64 20 66 6f 72 20 61 6e  eing used for an
1010: 20 69 6e 2d 6d 65 6d 6f 72 79 20 64 61 74 61 62   in-memory datab
1020: 61 73 65 2c 20 74 68 69 73 20 66 75 6e 63 74 69  ase, this functi
1030: 6f 6e 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a 2a  on is a no-op..*
1040: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63  /.static void pc
1050: 61 63 68 65 55 6e 70 69 6e 28 50 67 48 64 72 20  acheUnpin(PgHdr 
1060: 2a 70 29 7b 0a 20 20 50 43 61 63 68 65 20 2a 70  *p){.  PCache *p
1070: 43 61 63 68 65 20 3d 20 70 2d 3e 70 43 61 63 68  Cache = p->pCach
1080: 65 3b 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d  e;.  if( pCache-
1090: 3e 62 50 75 72 67 65 61 62 6c 65 20 29 7b 0a 20  >bPurgeable ){. 
10a0: 20 20 20 69 66 28 20 70 2d 3e 70 67 6e 6f 3d 3d     if( p->pgno==
10b0: 31 20 29 7b 0a 20 20 20 20 20 20 70 43 61 63 68  1 ){.      pCach
10c0: 65 2d 3e 70 50 61 67 65 31 20 3d 20 30 3b 0a 20  e->pPage1 = 0;. 
10d0: 20 20 20 7d 0a 20 20 20 20 73 71 6c 69 74 65 33     }.    sqlite3
10e0: 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61  GlobalConfig.pca
10f0: 63 68 65 2e 78 55 6e 70 69 6e 28 70 43 61 63 68  che.xUnpin(pCach
1100: 65 2d 3e 70 43 61 63 68 65 2c 20 70 2c 20 30 29  e->pCache, p, 0)
1110: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a  ;.  }.}../******
1120: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 47 65  ************* Ge
1150: 6e 65 72 61 6c 20 49 6e 74 65 72 66 61 63 65 73  neral Interfaces
1160: 20 2a 2a 2a 2a 2a 2a 0a 2a 2a 0a 2a 2a 20 49 6e   ******.**.** In
1170: 69 74 69 61 6c 69 7a 65 20 61 6e 64 20 73 68 75  itialize and shu
1180: 74 64 6f 77 6e 20 74 68 65 20 70 61 67 65 20 63  tdown the page c
1190: 61 63 68 65 20 73 75 62 73 79 73 74 65 6d 2e 20  ache subsystem. 
11a0: 4e 65 69 74 68 65 72 20 6f 66 20 74 68 65 73 65  Neither of these
11b0: 20 0a 2a 2a 20 66 75 6e 63 74 69 6f 6e 73 20 61   .** functions a
11c0: 72 65 20 74 68 72 65 61 64 73 61 66 65 2e 0a 2a  re threadsafe..*
11d0: 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 50 63 61  /.int sqlite3Pca
11e0: 63 68 65 49 6e 69 74 69 61 6c 69 7a 65 28 76 6f  cheInitialize(vo
11f0: 69 64 29 7b 0a 20 20 69 66 28 20 73 71 6c 69 74  id){.  if( sqlit
1200: 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70  e3GlobalConfig.p
1210: 63 61 63 68 65 2e 78 49 6e 69 74 3d 3d 30 20 29  cache.xInit==0 )
1220: 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 50 43 61  {.    sqlite3PCa
1230: 63 68 65 53 65 74 44 65 66 61 75 6c 74 28 29 3b  cheSetDefault();
1240: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 73 71  .  }.  return sq
1250: 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69  lite3GlobalConfi
1260: 67 2e 70 63 61 63 68 65 2e 78 49 6e 69 74 28 73  g.pcache.xInit(s
1270: 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66  qlite3GlobalConf
1280: 69 67 2e 70 63 61 63 68 65 2e 70 41 72 67 29 3b  ig.pcache.pArg);
1290: 0a 7d 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50  .}.void sqlite3P
12a0: 63 61 63 68 65 53 68 75 74 64 6f 77 6e 28 76 6f  cacheShutdown(vo
12b0: 69 64 29 7b 0a 20 20 69 66 28 20 73 71 6c 69 74  id){.  if( sqlit
12c0: 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70  e3GlobalConfig.p
12d0: 63 61 63 68 65 2e 78 53 68 75 74 64 6f 77 6e 20  cache.xShutdown 
12e0: 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 47 6c  ){.    sqlite3Gl
12f0: 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68  obalConfig.pcach
1300: 65 2e 78 53 68 75 74 64 6f 77 6e 28 73 71 6c 69  e.xShutdown(sqli
1310: 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e  te3GlobalConfig.
1320: 70 63 61 63 68 65 2e 70 41 72 67 29 3b 0a 20 20  pcache.pArg);.  
1330: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72  }.}../*.** Retur
1340: 6e 20 74 68 65 20 73 69 7a 65 20 69 6e 20 62 79  n the size in by
1350: 74 65 73 20 6f 66 20 61 20 50 43 61 63 68 65 20  tes of a PCache 
1360: 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 69 6e 74 20 73  object..*/.int s
1370: 71 6c 69 74 65 33 50 63 61 63 68 65 53 69 7a 65  qlite3PcacheSize
1380: 28 76 6f 69 64 29 7b 20 72 65 74 75 72 6e 20 73  (void){ return s
1390: 69 7a 65 6f 66 28 50 43 61 63 68 65 29 3b 20 7d  izeof(PCache); }
13a0: 0a 0a 2f 2a 0a 2a 2a 20 43 72 65 61 74 65 20 61  ../*.** Create a
13b0: 20 6e 65 77 20 50 43 61 63 68 65 20 6f 62 6a 65   new PCache obje
13c0: 63 74 2e 20 53 74 6f 72 61 67 65 20 73 70 61 63  ct. Storage spac
13d0: 65 20 74 6f 20 68 6f 6c 64 20 74 68 65 20 6f 62  e to hold the ob
13e0: 6a 65 63 74 0a 2a 2a 20 68 61 73 20 61 6c 72 65  ject.** has alre
13f0: 61 64 79 20 62 65 65 6e 20 61 6c 6c 6f 63 61 74  ady been allocat
1400: 65 64 20 61 6e 64 20 69 73 20 70 61 73 73 65 64  ed and is passed
1410: 20 69 6e 20 61 73 20 74 68 65 20 70 20 70 6f 69   in as the p poi
1420: 6e 74 65 72 2e 20 0a 2a 2a 20 54 68 65 20 63 61  nter. .** The ca
1430: 6c 6c 65 72 20 64 69 73 63 6f 76 65 72 73 20 68  ller discovers h
1440: 6f 77 20 6d 75 63 68 20 73 70 61 63 65 20 6e 65  ow much space ne
1450: 65 64 73 20 74 6f 20 62 65 20 61 6c 6c 6f 63 61  eds to be alloca
1460: 74 65 64 20 62 79 20 0a 2a 2a 20 63 61 6c 6c 69  ted by .** calli
1470: 6e 67 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  ng sqlite3Pcache
1480: 53 69 7a 65 28 29 2e 0a 2a 2f 0a 76 6f 69 64 20  Size()..*/.void 
1490: 73 71 6c 69 74 65 33 50 63 61 63 68 65 4f 70 65  sqlite3PcacheOpe
14a0: 6e 28 0a 20 20 69 6e 74 20 73 7a 50 61 67 65 2c  n(.  int szPage,
14b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14c0: 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 65 76 65    /* Size of eve
14d0: 72 79 20 70 61 67 65 20 2a 2f 0a 20 20 69 6e 74  ry page */.  int
14e0: 20 73 7a 45 78 74 72 61 2c 20 20 20 20 20 20 20   szExtra,       
14f0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 45 78 74            /* Ext
1500: 72 61 20 73 70 61 63 65 20 61 73 73 6f 63 69 61  ra space associa
1510: 74 65 64 20 77 69 74 68 20 65 61 63 68 20 70 61  ted with each pa
1520: 67 65 20 2a 2f 0a 20 20 69 6e 74 20 62 50 75 72  ge */.  int bPur
1530: 67 65 61 62 6c 65 2c 20 20 20 20 20 20 20 20 20  geable,         
1540: 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20       /* True if 
1550: 70 61 67 65 73 20 61 72 65 20 6f 6e 20 62 61 63  pages are on bac
1560: 6b 69 6e 67 20 73 74 6f 72 65 20 2a 2f 0a 20 20  king store */.  
1570: 69 6e 74 20 28 2a 78 53 74 72 65 73 73 29 28 76  int (*xStress)(v
1580: 6f 69 64 2a 2c 50 67 48 64 72 2a 29 2c 2f 2a 20  oid*,PgHdr*),/* 
1590: 43 61 6c 6c 20 74 6f 20 74 72 79 20 74 6f 20 6d  Call to try to m
15a0: 61 6b 65 20 70 61 67 65 73 20 63 6c 65 61 6e 20  ake pages clean 
15b0: 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 53 74 72 65  */.  void *pStre
15c0: 73 73 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ss,             
15d0: 20 20 2f 2a 20 41 72 67 75 6d 65 6e 74 20 74 6f    /* Argument to
15e0: 20 78 53 74 72 65 73 73 20 2a 2f 0a 20 20 50 43   xStress */.  PC
15f0: 61 63 68 65 20 2a 70 20 20 20 20 20 20 20 20 20  ache *p         
1600: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 72             /* Pr
1610: 65 61 6c 6c 6f 63 61 74 65 64 20 73 70 61 63 65  eallocated space
1620: 20 66 6f 72 20 74 68 65 20 50 43 61 63 68 65 20   for the PCache 
1630: 2a 2f 0a 29 7b 0a 20 20 6d 65 6d 73 65 74 28 70  */.){.  memset(p
1640: 2c 20 30 2c 20 73 69 7a 65 6f 66 28 50 43 61 63  , 0, sizeof(PCac
1650: 68 65 29 29 3b 0a 20 20 70 2d 3e 73 7a 50 61 67  he));.  p->szPag
1660: 65 20 3d 20 73 7a 50 61 67 65 3b 0a 20 20 70 2d  e = szPage;.  p-
1670: 3e 73 7a 45 78 74 72 61 20 3d 20 73 7a 45 78 74  >szExtra = szExt
1680: 72 61 3b 0a 20 20 70 2d 3e 62 50 75 72 67 65 61  ra;.  p->bPurgea
1690: 62 6c 65 20 3d 20 62 50 75 72 67 65 61 62 6c 65  ble = bPurgeable
16a0: 3b 0a 20 20 70 2d 3e 78 53 74 72 65 73 73 20 3d  ;.  p->xStress =
16b0: 20 78 53 74 72 65 73 73 3b 0a 20 20 70 2d 3e 70   xStress;.  p->p
16c0: 53 74 72 65 73 73 20 3d 20 70 53 74 72 65 73 73  Stress = pStress
16d0: 3b 0a 20 20 70 2d 3e 6e 4d 61 78 20 3d 20 31 30  ;.  p->nMax = 10
16e0: 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 68 61 6e  0;.}../*.** Chan
16f0: 67 65 20 74 68 65 20 70 61 67 65 20 73 69 7a 65  ge the page size
1700: 20 66 6f 72 20 50 43 61 63 68 65 20 6f 62 6a 65   for PCache obje
1710: 63 74 2e 20 54 68 65 20 63 61 6c 6c 65 72 20 6d  ct. The caller m
1720: 75 73 74 20 65 6e 73 75 72 65 20 74 68 61 74 20  ust ensure that 
1730: 74 68 65 72 65 0a 2a 2a 20 61 72 65 20 6e 6f 20  there.** are no 
1740: 6f 75 74 73 74 61 6e 64 69 6e 67 20 70 61 67 65  outstanding page
1750: 20 72 65 66 65 72 65 6e 63 65 73 20 77 68 65 6e   references when
1760: 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   this function i
1770: 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f 0a 76 6f 69  s called..*/.voi
1780: 64 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 53  d sqlite3PcacheS
1790: 65 74 50 61 67 65 53 69 7a 65 28 50 43 61 63 68  etPageSize(PCach
17a0: 65 20 2a 70 43 61 63 68 65 2c 20 69 6e 74 20 73  e *pCache, int s
17b0: 7a 50 61 67 65 29 7b 0a 20 20 61 73 73 65 72 74  zPage){.  assert
17c0: 28 20 70 43 61 63 68 65 2d 3e 6e 52 65 66 3d 3d  ( pCache->nRef==
17d0: 30 20 26 26 20 70 43 61 63 68 65 2d 3e 70 44 69  0 && pCache->pDi
17e0: 72 74 79 3d 3d 30 20 29 3b 0a 20 20 69 66 28 20  rty==0 );.  if( 
17f0: 70 43 61 63 68 65 2d 3e 70 43 61 63 68 65 20 29  pCache->pCache )
1800: 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 47 6c 6f  {.    sqlite3Glo
1810: 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65  balConfig.pcache
1820: 2e 78 44 65 73 74 72 6f 79 28 70 43 61 63 68 65  .xDestroy(pCache
1830: 2d 3e 70 43 61 63 68 65 29 3b 0a 20 20 20 20 70  ->pCache);.    p
1840: 43 61 63 68 65 2d 3e 70 43 61 63 68 65 20 3d 20  Cache->pCache = 
1850: 30 3b 0a 20 20 7d 0a 20 20 70 43 61 63 68 65 2d  0;.  }.  pCache-
1860: 3e 73 7a 50 61 67 65 20 3d 20 73 7a 50 61 67 65  >szPage = szPage
1870: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 72 79 20 74  ;.}../*.** Try t
1880: 6f 20 6f 62 74 61 69 6e 20 61 20 70 61 67 65 20  o obtain a page 
1890: 66 72 6f 6d 20 74 68 65 20 63 61 63 68 65 2e 0a  from the cache..
18a0: 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 50 63  */.int sqlite3Pc
18b0: 61 63 68 65 46 65 74 63 68 28 0a 20 20 50 43 61  acheFetch(.  PCa
18c0: 63 68 65 20 2a 70 43 61 63 68 65 2c 20 20 20 20  che *pCache,    
18d0: 20 20 20 2f 2a 20 4f 62 74 61 69 6e 20 74 68 65     /* Obtain the
18e0: 20 70 61 67 65 20 66 72 6f 6d 20 74 68 69 73 20   page from this 
18f0: 63 61 63 68 65 20 2a 2f 0a 20 20 50 67 6e 6f 20  cache */.  Pgno 
1900: 70 67 6e 6f 2c 20 20 20 20 20 20 20 20 20 20 20  pgno,           
1910: 20 2f 2a 20 50 61 67 65 20 6e 75 6d 62 65 72 20   /* Page number 
1920: 74 6f 20 6f 62 74 61 69 6e 20 2a 2f 0a 20 20 69  to obtain */.  i
1930: 6e 74 20 63 72 65 61 74 65 46 6c 61 67 2c 20 20  nt createFlag,  
1940: 20 20 20 20 20 2f 2a 20 49 66 20 74 72 75 65 2c       /* If true,
1950: 20 63 72 65 61 74 65 20 70 61 67 65 20 69 66 20   create page if 
1960: 69 74 20 64 6f 65 73 20 6e 6f 74 20 65 78 69 73  it does not exis
1970: 74 20 61 6c 72 65 61 64 79 20 2a 2f 0a 20 20 50  t already */.  P
1980: 67 48 64 72 20 2a 2a 70 70 50 61 67 65 20 20 20  gHdr **ppPage   
1990: 20 20 20 20 20 2f 2a 20 57 72 69 74 65 20 74 68       /* Write th
19a0: 65 20 70 61 67 65 20 68 65 72 65 20 2a 2f 0a 29  e page here */.)
19b0: 7b 0a 20 20 50 67 48 64 72 20 2a 70 50 61 67 65  {.  PgHdr *pPage
19c0: 20 3d 20 30 3b 0a 20 20 69 6e 74 20 65 43 72 65   = 0;.  int eCre
19d0: 61 74 65 3b 0a 0a 20 20 61 73 73 65 72 74 28 20  ate;..  assert( 
19e0: 70 43 61 63 68 65 21 3d 30 20 29 3b 0a 20 20 61  pCache!=0 );.  a
19f0: 73 73 65 72 74 28 20 70 67 6e 6f 3e 30 20 29 3b  ssert( pgno>0 );
1a00: 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 20 70 6c  ..  /* If the pl
1a10: 75 67 67 61 62 6c 65 20 63 61 63 68 65 20 28 73  uggable cache (s
1a20: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2a 29 20  qlite3_pcache*) 
1a30: 68 61 73 20 6e 6f 74 20 62 65 65 6e 20 61 6c 6c  has not been all
1a40: 6f 63 61 74 65 64 2c 0a 20 20 2a 2a 20 61 6c 6c  ocated,.  ** all
1a50: 6f 63 61 74 65 20 69 74 20 6e 6f 77 2e 0a 20 20  ocate it now..  
1a60: 2a 2f 0a 20 20 69 66 28 20 21 70 43 61 63 68 65  */.  if( !pCache
1a70: 2d 3e 70 43 61 63 68 65 20 26 26 20 63 72 65 61  ->pCache && crea
1a80: 74 65 46 6c 61 67 20 29 7b 0a 20 20 20 20 73 71  teFlag ){.    sq
1a90: 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70 3b  lite3_pcache *p;
1aa0: 0a 20 20 20 20 69 6e 74 20 6e 42 79 74 65 3b 0a  .    int nByte;.
1ab0: 20 20 20 20 6e 42 79 74 65 20 3d 20 70 43 61 63      nByte = pCac
1ac0: 68 65 2d 3e 73 7a 50 61 67 65 20 2b 20 70 43 61  he->szPage + pCa
1ad0: 63 68 65 2d 3e 73 7a 45 78 74 72 61 20 2b 20 73  che->szExtra + s
1ae0: 69 7a 65 6f 66 28 50 67 48 64 72 29 3b 0a 20 20  izeof(PgHdr);.  
1af0: 20 20 70 20 3d 20 73 71 6c 69 74 65 33 47 6c 6f    p = sqlite3Glo
1b00: 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65  balConfig.pcache
1b10: 2e 78 43 72 65 61 74 65 28 6e 42 79 74 65 2c 20  .xCreate(nByte, 
1b20: 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62  pCache->bPurgeab
1b30: 6c 65 29 3b 0a 20 20 20 20 69 66 28 20 21 70 20  le);.    if( !p 
1b40: 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  ){.      return 
1b50: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
1b60: 20 20 7d 0a 20 20 20 20 73 71 6c 69 74 65 33 47    }.    sqlite3G
1b70: 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63  lobalConfig.pcac
1b80: 68 65 2e 78 43 61 63 68 65 73 69 7a 65 28 70 2c  he.xCachesize(p,
1b90: 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 29 3b 0a   pCache->nMax);.
1ba0: 20 20 20 20 70 43 61 63 68 65 2d 3e 70 43 61 63      pCache->pCac
1bb0: 68 65 20 3d 20 70 3b 0a 20 20 7d 0a 0a 20 20 65  he = p;.  }..  e
1bc0: 43 72 65 61 74 65 20 3d 20 63 72 65 61 74 65 46  Create = createF
1bd0: 6c 61 67 20 3f 20 31 20 3a 20 30 3b 0a 20 20 69  lag ? 1 : 0;.  i
1be0: 66 28 20 65 43 72 65 61 74 65 20 26 26 20 28 21  f( eCreate && (!
1bf0: 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62  pCache->bPurgeab
1c00: 6c 65 20 7c 7c 20 21 70 43 61 63 68 65 2d 3e 70  le || !pCache->p
1c10: 44 69 72 74 79 29 20 29 7b 0a 20 20 20 20 65 43  Dirty) ){.    eC
1c20: 72 65 61 74 65 20 3d 20 32 3b 0a 20 20 7d 0a 20  reate = 2;.  }. 
1c30: 20 69 66 28 20 70 43 61 63 68 65 2d 3e 70 43 61   if( pCache->pCa
1c40: 63 68 65 20 29 7b 0a 20 20 20 20 70 50 61 67 65  che ){.    pPage
1c50: 20 3d 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c   = sqlite3Global
1c60: 43 6f 6e 66 69 67 2e 70 63 61 63 68 65 2e 78 46  Config.pcache.xF
1c70: 65 74 63 68 28 70 43 61 63 68 65 2d 3e 70 43 61  etch(pCache->pCa
1c80: 63 68 65 2c 20 70 67 6e 6f 2c 20 65 43 72 65 61  che, pgno, eCrea
1c90: 74 65 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20  te);.  }..  if( 
1ca0: 21 70 50 61 67 65 20 26 26 20 65 43 72 65 61 74  !pPage && eCreat
1cb0: 65 3d 3d 31 20 29 7b 0a 20 20 20 20 50 67 48 64  e==1 ){.    PgHd
1cc0: 72 20 2a 70 50 67 3b 0a 0a 20 20 20 20 2f 2a 20  r *pPg;..    /* 
1cd0: 46 69 6e 64 20 61 20 64 69 72 74 79 20 70 61 67  Find a dirty pag
1ce0: 65 20 74 6f 20 77 72 69 74 65 2d 6f 75 74 20 61  e to write-out a
1cf0: 6e 64 20 72 65 63 79 63 6c 65 2e 20 46 69 72 73  nd recycle. Firs
1d00: 74 20 74 72 79 20 74 6f 20 66 69 6e 64 20 61 20  t try to find a 
1d10: 0a 20 20 20 20 2a 2a 20 70 61 67 65 20 74 68 61  .    ** page tha
1d20: 74 20 64 6f 65 73 20 6e 6f 74 20 72 65 71 75 69  t does not requi
1d30: 72 65 20 61 20 6a 6f 75 72 6e 61 6c 2d 73 79 6e  re a journal-syn
1d40: 63 20 28 6f 6e 65 20 77 69 74 68 20 50 47 48 44  c (one with PGHD
1d50: 52 5f 4e 45 45 44 5f 53 59 4e 43 0a 20 20 20 20  R_NEED_SYNC.    
1d60: 2a 2a 20 63 6c 65 61 72 65 64 29 2c 20 62 75 74  ** cleared), but
1d70: 20 69 66 20 74 68 61 74 20 69 73 20 6e 6f 74 20   if that is not 
1d80: 70 6f 73 73 69 62 6c 65 20 73 65 74 74 6c 65 20  possible settle 
1d90: 66 6f 72 20 61 6e 79 20 6f 74 68 65 72 20 0a 20  for any other . 
1da0: 20 20 20 2a 2a 20 75 6e 72 65 66 65 72 65 6e 63     ** unreferenc
1db0: 65 64 20 64 69 72 74 79 20 70 61 67 65 2e 0a 20  ed dirty page.. 
1dc0: 20 20 20 2a 2f 0a 20 20 20 20 65 78 70 65 6e 73     */.    expens
1dd0: 69 76 65 5f 61 73 73 65 72 74 28 20 70 63 61 63  ive_assert( pcac
1de0: 68 65 43 68 65 63 6b 53 79 6e 63 65 64 28 70 43  heCheckSynced(pC
1df0: 61 63 68 65 29 20 29 3b 0a 20 20 20 20 66 6f 72  ache) );.    for
1e00: 28 70 50 67 3d 70 43 61 63 68 65 2d 3e 70 53 79  (pPg=pCache->pSy
1e10: 6e 63 65 64 3b 20 0a 20 20 20 20 20 20 20 20 70  nced; .        p
1e20: 50 67 20 26 26 20 28 70 50 67 2d 3e 6e 52 65 66  Pg && (pPg->nRef
1e30: 20 7c 7c 20 28 70 50 67 2d 3e 66 6c 61 67 73 26   || (pPg->flags&
1e40: 50 47 48 44 52 5f 4e 45 45 44 5f 53 59 4e 43 29  PGHDR_NEED_SYNC)
1e50: 29 3b 20 0a 20 20 20 20 20 20 20 20 70 50 67 3d  ); .        pPg=
1e60: 70 50 67 2d 3e 70 44 69 72 74 79 50 72 65 76 0a  pPg->pDirtyPrev.
1e70: 20 20 20 20 29 3b 0a 20 20 20 20 69 66 28 20 21      );.    if( !
1e80: 70 50 67 20 29 7b 0a 20 20 20 20 20 20 66 6f 72  pPg ){.      for
1e90: 28 70 50 67 3d 70 43 61 63 68 65 2d 3e 70 44 69  (pPg=pCache->pDi
1ea0: 72 74 79 54 61 69 6c 3b 20 70 50 67 20 26 26 20  rtyTail; pPg && 
1eb0: 70 50 67 2d 3e 6e 52 65 66 3b 20 70 50 67 3d 70  pPg->nRef; pPg=p
1ec0: 50 67 2d 3e 70 44 69 72 74 79 50 72 65 76 29 3b  Pg->pDirtyPrev);
1ed0: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70  .    }.    if( p
1ee0: 50 67 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20  Pg ){.      int 
1ef0: 72 63 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 70  rc;.      rc = p
1f00: 43 61 63 68 65 2d 3e 78 53 74 72 65 73 73 28 70  Cache->xStress(p
1f10: 43 61 63 68 65 2d 3e 70 53 74 72 65 73 73 2c 20  Cache->pStress, 
1f20: 70 50 67 29 3b 0a 20 20 20 20 20 20 69 66 28 20  pPg);.      if( 
1f30: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26  rc!=SQLITE_OK &&
1f40: 20 72 63 21 3d 53 51 4c 49 54 45 5f 42 55 53 59   rc!=SQLITE_BUSY
1f50: 20 29 7b 0a 20 20 20 20 20 20 20 20 72 65 74 75   ){.        retu
1f60: 72 6e 20 72 63 3b 0a 20 20 20 20 20 20 7d 0a 20  rn rc;.      }. 
1f70: 20 20 20 7d 0a 0a 20 20 20 20 70 50 61 67 65 20     }..    pPage 
1f80: 3d 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43  = sqlite3GlobalC
1f90: 6f 6e 66 69 67 2e 70 63 61 63 68 65 2e 78 46 65  onfig.pcache.xFe
1fa0: 74 63 68 28 70 43 61 63 68 65 2d 3e 70 43 61 63  tch(pCache->pCac
1fb0: 68 65 2c 20 70 67 6e 6f 2c 20 32 29 3b 0a 20 20  he, pgno, 2);.  
1fc0: 7d 0a 0a 20 20 69 66 28 20 70 50 61 67 65 20 29  }..  if( pPage )
1fd0: 7b 0a 20 20 20 20 69 66 28 20 30 3d 3d 70 50 61  {.    if( 0==pPa
1fe0: 67 65 2d 3e 6e 52 65 66 20 29 7b 0a 20 20 20 20  ge->nRef ){.    
1ff0: 20 20 70 43 61 63 68 65 2d 3e 6e 52 65 66 2b 2b    pCache->nRef++
2000: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 50 61 67  ;.    }.    pPag
2010: 65 2d 3e 6e 52 65 66 2b 2b 3b 0a 20 20 20 20 70  e->nRef++;.    p
2020: 50 61 67 65 2d 3e 70 44 61 74 61 20 3d 20 28 76  Page->pData = (v
2030: 6f 69 64 2a 29 26 70 50 61 67 65 5b 31 5d 3b 0a  oid*)&pPage[1];.
2040: 20 20 20 20 70 50 61 67 65 2d 3e 70 45 78 74 72      pPage->pExtr
2050: 61 20 3d 20 28 76 6f 69 64 2a 29 26 28 28 63 68  a = (void*)&((ch
2060: 61 72 2a 29 70 50 61 67 65 2d 3e 70 44 61 74 61  ar*)pPage->pData
2070: 29 5b 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65  )[pCache->szPage
2080: 5d 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 43  ];.    pPage->pC
2090: 61 63 68 65 20 3d 20 70 43 61 63 68 65 3b 0a 20  ache = pCache;. 
20a0: 20 20 20 70 50 61 67 65 2d 3e 70 67 6e 6f 20 3d     pPage->pgno =
20b0: 20 70 67 6e 6f 3b 0a 20 20 20 20 69 66 28 20 70   pgno;.    if( p
20c0: 67 6e 6f 3d 3d 31 20 29 7b 0a 20 20 20 20 20 20  gno==1 ){.      
20d0: 70 43 61 63 68 65 2d 3e 70 50 61 67 65 31 20 3d  pCache->pPage1 =
20e0: 20 70 50 61 67 65 3b 0a 20 20 20 20 7d 0a 20 20   pPage;.    }.  
20f0: 7d 0a 20 20 2a 70 70 50 61 67 65 20 3d 20 70 50  }.  *ppPage = pP
2100: 61 67 65 3b 0a 20 20 72 65 74 75 72 6e 20 28 70  age;.  return (p
2110: 50 61 67 65 3d 3d 30 20 26 26 20 65 43 72 65 61  Page==0 && eCrea
2120: 74 65 29 20 3f 20 53 51 4c 49 54 45 5f 4e 4f 4d  te) ? SQLITE_NOM
2130: 45 4d 20 3a 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  EM : SQLITE_OK;.
2140: 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65 63 72 65 6d 65  }../*.** Decreme
2150: 6e 74 20 74 68 65 20 72 65 66 65 72 65 6e 63 65  nt the reference
2160: 20 63 6f 75 6e 74 20 6f 6e 20 61 20 70 61 67 65   count on a page
2170: 2e 20 49 66 20 74 68 65 20 70 61 67 65 20 69 73  . If the page is
2180: 20 63 6c 65 61 6e 20 61 6e 64 20 74 68 65 0a 2a   clean and the.*
2190: 2a 20 72 65 66 65 72 65 6e 63 65 20 63 6f 75 6e  * reference coun
21a0: 74 20 64 72 6f 70 73 20 74 6f 20 30 2c 20 74 68  t drops to 0, th
21b0: 65 6e 20 69 74 20 69 73 20 6d 61 64 65 20 65 6c  en it is made el
21c0: 69 62 6c 65 20 66 6f 72 20 72 65 63 79 63 6c 69  ible for recycli
21d0: 6e 67 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69  ng..*/.void sqli
21e0: 74 65 33 50 63 61 63 68 65 52 65 6c 65 61 73 65  te3PcacheRelease
21f0: 28 50 67 48 64 72 20 2a 70 29 7b 0a 20 20 61 73  (PgHdr *p){.  as
2200: 73 65 72 74 28 20 70 2d 3e 6e 52 65 66 3e 30 20  sert( p->nRef>0 
2210: 29 3b 0a 20 20 70 2d 3e 6e 52 65 66 2d 2d 3b 0a  );.  p->nRef--;.
2220: 20 20 69 66 28 20 70 2d 3e 6e 52 65 66 3d 3d 30    if( p->nRef==0
2230: 20 29 7b 0a 20 20 20 20 50 43 61 63 68 65 20 2a   ){.    PCache *
2240: 70 43 61 63 68 65 20 3d 20 70 2d 3e 70 43 61 63  pCache = p->pCac
2250: 68 65 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e  he;.    pCache->
2260: 6e 52 65 66 2d 2d 3b 0a 20 20 20 20 69 66 28 20  nRef--;.    if( 
2270: 28 70 2d 3e 66 6c 61 67 73 26 50 47 48 44 52 5f  (p->flags&PGHDR_
2280: 44 49 52 54 59 29 3d 3d 30 20 29 7b 0a 20 20 20  DIRTY)==0 ){.   
2290: 20 20 20 70 63 61 63 68 65 55 6e 70 69 6e 28 70     pcacheUnpin(p
22a0: 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  );.    }else{.  
22b0: 20 20 20 20 2f 2a 20 4d 6f 76 65 20 74 68 65 20      /* Move the 
22c0: 70 61 67 65 20 74 6f 20 74 68 65 20 68 65 61 64  page to the head
22d0: 20 6f 66 20 74 68 65 20 64 69 72 74 79 20 6c 69   of the dirty li
22e0: 73 74 2e 20 2a 2f 0a 20 20 20 20 20 20 70 63 61  st. */.      pca
22f0: 63 68 65 52 65 6d 6f 76 65 46 72 6f 6d 44 69 72  cheRemoveFromDir
2300: 74 79 4c 69 73 74 28 70 29 3b 0a 20 20 20 20 20  tyList(p);.     
2310: 20 70 63 61 63 68 65 41 64 64 54 6f 44 69 72 74   pcacheAddToDirt
2320: 79 4c 69 73 74 28 70 29 3b 0a 20 20 20 20 7d 0a  yList(p);.    }.
2330: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 63    }.}../*.** Inc
2340: 72 65 61 73 65 20 74 68 65 20 72 65 66 65 72 65  rease the refere
2350: 6e 63 65 20 63 6f 75 6e 74 20 6f 66 20 61 20 73  nce count of a s
2360: 75 70 70 6c 69 65 64 20 70 61 67 65 20 62 79 20  upplied page by 
2370: 31 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74  1..*/.void sqlit
2380: 65 33 50 63 61 63 68 65 52 65 66 28 50 67 48 64  e3PcacheRef(PgHd
2390: 72 20 2a 70 29 7b 0a 20 20 61 73 73 65 72 74 28  r *p){.  assert(
23a0: 70 2d 3e 6e 52 65 66 3e 30 29 3b 0a 20 20 70 2d  p->nRef>0);.  p-
23b0: 3e 6e 52 65 66 2b 2b 3b 0a 7d 0a 0a 2f 2a 0a 2a  >nRef++;.}../*.*
23c0: 2a 20 44 72 6f 70 20 61 20 70 61 67 65 20 66 72  * Drop a page fr
23d0: 6f 6d 20 74 68 65 20 63 61 63 68 65 2e 20 54 68  om the cache. Th
23e0: 65 72 65 20 6d 75 73 74 20 62 65 20 65 78 61 63  ere must be exac
23f0: 74 6c 79 20 6f 6e 65 20 72 65 66 65 72 65 6e 63  tly one referenc
2400: 65 20 74 6f 20 74 68 65 0a 2a 2a 20 70 61 67 65  e to the.** page
2410: 2e 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  . This function 
2420: 64 65 6c 65 74 65 73 20 74 68 61 74 20 72 65 66  deletes that ref
2430: 65 72 65 6e 63 65 2c 20 73 6f 20 61 66 74 65 72  erence, so after
2440: 20 69 74 20 72 65 74 75 72 6e 73 20 74 68 65 0a   it returns the.
2450: 2a 2a 20 70 61 67 65 20 70 6f 69 6e 74 65 64 20  ** page pointed 
2460: 74 6f 20 62 79 20 70 20 69 73 20 69 6e 76 61 6c  to by p is inval
2470: 69 64 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69  id..*/.void sqli
2480: 74 65 33 50 63 61 63 68 65 44 72 6f 70 28 50 67  te3PcacheDrop(Pg
2490: 48 64 72 20 2a 70 29 7b 0a 20 20 50 43 61 63 68  Hdr *p){.  PCach
24a0: 65 20 2a 70 43 61 63 68 65 3b 0a 20 20 61 73 73  e *pCache;.  ass
24b0: 65 72 74 28 20 70 2d 3e 6e 52 65 66 3d 3d 31 20  ert( p->nRef==1 
24c0: 29 3b 0a 20 20 69 66 28 20 70 2d 3e 66 6c 61 67  );.  if( p->flag
24d0: 73 26 50 47 48 44 52 5f 44 49 52 54 59 20 29 7b  s&PGHDR_DIRTY ){
24e0: 0a 20 20 20 20 70 63 61 63 68 65 52 65 6d 6f 76  .    pcacheRemov
24f0: 65 46 72 6f 6d 44 69 72 74 79 4c 69 73 74 28 70  eFromDirtyList(p
2500: 29 3b 0a 20 20 7d 0a 20 20 70 43 61 63 68 65 20  );.  }.  pCache 
2510: 3d 20 70 2d 3e 70 43 61 63 68 65 3b 0a 20 20 70  = p->pCache;.  p
2520: 43 61 63 68 65 2d 3e 6e 52 65 66 2d 2d 3b 0a 20  Cache->nRef--;. 
2530: 20 69 66 28 20 70 2d 3e 70 67 6e 6f 3d 3d 31 20   if( p->pgno==1 
2540: 29 7b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 70  ){.    pCache->p
2550: 50 61 67 65 31 20 3d 20 30 3b 0a 20 20 7d 0a 20  Page1 = 0;.  }. 
2560: 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f   sqlite3GlobalCo
2570: 6e 66 69 67 2e 70 63 61 63 68 65 2e 78 55 6e 70  nfig.pcache.xUnp
2580: 69 6e 28 70 43 61 63 68 65 2d 3e 70 43 61 63 68  in(pCache->pCach
2590: 65 2c 20 70 2c 20 31 29 3b 0a 7d 0a 0a 2f 2a 0a  e, p, 1);.}../*.
25a0: 2a 2a 20 4d 61 6b 65 20 73 75 72 65 20 74 68 65  ** Make sure the
25b0: 20 70 61 67 65 20 69 73 20 6d 61 72 6b 65 64 20   page is marked 
25c0: 61 73 20 64 69 72 74 79 2e 20 49 66 20 69 74 20  as dirty. If it 
25d0: 69 73 6e 27 74 20 64 69 72 74 79 20 61 6c 72 65  isn't dirty alre
25e0: 61 64 79 2c 0a 2a 2a 20 6d 61 6b 65 20 69 74 20  ady,.** make it 
25f0: 73 6f 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69  so..*/.void sqli
2600: 74 65 33 50 63 61 63 68 65 4d 61 6b 65 44 69 72  te3PcacheMakeDir
2610: 74 79 28 50 67 48 64 72 20 2a 70 29 7b 0a 20 20  ty(PgHdr *p){.  
2620: 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 3b 0a  PCache *pCache;.
2630: 20 20 70 2d 3e 66 6c 61 67 73 20 26 3d 20 7e 50    p->flags &= ~P
2640: 47 48 44 52 5f 44 4f 4e 54 5f 57 52 49 54 45 3b  GHDR_DONT_WRITE;
2650: 0a 20 20 61 73 73 65 72 74 28 20 70 2d 3e 6e 52  .  assert( p->nR
2660: 65 66 3e 30 20 29 3b 0a 20 20 69 66 28 20 30 3d  ef>0 );.  if( 0=
2670: 3d 28 70 2d 3e 66 6c 61 67 73 20 26 20 50 47 48  =(p->flags & PGH
2680: 44 52 5f 44 49 52 54 59 29 20 29 7b 0a 20 20 20  DR_DIRTY) ){.   
2690: 20 70 43 61 63 68 65 20 3d 20 70 2d 3e 70 43 61   pCache = p->pCa
26a0: 63 68 65 3b 0a 20 20 20 20 70 2d 3e 66 6c 61 67  che;.    p->flag
26b0: 73 20 7c 3d 20 50 47 48 44 52 5f 44 49 52 54 59  s |= PGHDR_DIRTY
26c0: 3b 0a 20 20 20 20 70 63 61 63 68 65 41 64 64 54  ;.    pcacheAddT
26d0: 6f 44 69 72 74 79 4c 69 73 74 28 20 70 29 3b 0a  oDirtyList( p);.
26e0: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6b    }.}../*.** Mak
26f0: 65 20 73 75 72 65 20 74 68 65 20 70 61 67 65 20  e sure the page 
2700: 69 73 20 6d 61 72 6b 65 64 20 61 73 20 63 6c 65  is marked as cle
2710: 61 6e 2e 20 49 66 20 69 74 20 69 73 6e 27 74 20  an. If it isn't 
2720: 63 6c 65 61 6e 20 61 6c 72 65 61 64 79 2c 0a 2a  clean already,.*
2730: 2a 20 6d 61 6b 65 20 69 74 20 73 6f 2e 0a 2a 2f  * make it so..*/
2740: 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63 61  .void sqlite3Pca
2750: 63 68 65 4d 61 6b 65 43 6c 65 61 6e 28 50 67 48  cheMakeClean(PgH
2760: 64 72 20 2a 70 29 7b 0a 20 20 69 66 28 20 28 70  dr *p){.  if( (p
2770: 2d 3e 66 6c 61 67 73 20 26 20 50 47 48 44 52 5f  ->flags & PGHDR_
2780: 44 49 52 54 59 29 20 29 7b 0a 20 20 20 20 70 63  DIRTY) ){.    pc
2790: 61 63 68 65 52 65 6d 6f 76 65 46 72 6f 6d 44 69  acheRemoveFromDi
27a0: 72 74 79 4c 69 73 74 28 70 29 3b 0a 20 20 20 20  rtyList(p);.    
27b0: 70 2d 3e 66 6c 61 67 73 20 26 3d 20 7e 28 50 47  p->flags &= ~(PG
27c0: 48 44 52 5f 44 49 52 54 59 7c 50 47 48 44 52 5f  HDR_DIRTY|PGHDR_
27d0: 4e 45 45 44 5f 53 59 4e 43 29 3b 0a 20 20 20 20  NEED_SYNC);.    
27e0: 69 66 28 20 70 2d 3e 6e 52 65 66 3d 3d 30 20 29  if( p->nRef==0 )
27f0: 7b 0a 20 20 20 20 20 20 70 63 61 63 68 65 55 6e  {.      pcacheUn
2800: 70 69 6e 28 70 29 3b 0a 20 20 20 20 7d 0a 20 20  pin(p);.    }.  
2810: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6b 65 20  }.}../*.** Make 
2820: 65 76 65 72 79 20 70 61 67 65 20 69 6e 20 74 68  every page in th
2830: 65 20 63 61 63 68 65 20 63 6c 65 61 6e 2e 0a 2a  e cache clean..*
2840: 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63  /.void sqlite3Pc
2850: 61 63 68 65 43 6c 65 61 6e 41 6c 6c 28 50 43 61  acheCleanAll(PCa
2860: 63 68 65 20 2a 70 43 61 63 68 65 29 7b 0a 20 20  che *pCache){.  
2870: 50 67 48 64 72 20 2a 70 3b 0a 20 20 77 68 69 6c  PgHdr *p;.  whil
2880: 65 28 20 28 70 20 3d 20 70 43 61 63 68 65 2d 3e  e( (p = pCache->
2890: 70 44 69 72 74 79 29 21 3d 30 20 29 7b 0a 20 20  pDirty)!=0 ){.  
28a0: 20 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 4d    sqlite3PcacheM
28b0: 61 6b 65 43 6c 65 61 6e 28 70 29 3b 0a 20 20 7d  akeClean(p);.  }
28c0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 65 61 72 20  .}../*.** Clear 
28d0: 74 68 65 20 50 47 48 44 52 5f 4e 45 45 44 5f 53  the PGHDR_NEED_S
28e0: 59 4e 43 20 66 6c 61 67 20 66 72 6f 6d 20 61 6c  YNC flag from al
28f0: 6c 20 64 69 72 74 79 20 70 61 67 65 73 2e 0a 2a  l dirty pages..*
2900: 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63  /.void sqlite3Pc
2910: 61 63 68 65 43 6c 65 61 72 53 79 6e 63 46 6c 61  acheClearSyncFla
2920: 67 73 28 50 43 61 63 68 65 20 2a 70 43 61 63 68  gs(PCache *pCach
2930: 65 29 7b 0a 20 20 50 67 48 64 72 20 2a 70 3b 0a  e){.  PgHdr *p;.
2940: 20 20 66 6f 72 28 70 3d 70 43 61 63 68 65 2d 3e    for(p=pCache->
2950: 70 44 69 72 74 79 3b 20 70 3b 20 70 3d 70 2d 3e  pDirty; p; p=p->
2960: 70 44 69 72 74 79 4e 65 78 74 29 7b 0a 20 20 20  pDirtyNext){.   
2970: 20 70 2d 3e 66 6c 61 67 73 20 26 3d 20 7e 50 47   p->flags &= ~PG
2980: 48 44 52 5f 4e 45 45 44 5f 53 59 4e 43 3b 0a 20  HDR_NEED_SYNC;. 
2990: 20 7d 0a 20 20 70 43 61 63 68 65 2d 3e 70 53 79   }.  pCache->pSy
29a0: 6e 63 65 64 20 3d 20 70 43 61 63 68 65 2d 3e 70  nced = pCache->p
29b0: 44 69 72 74 79 54 61 69 6c 3b 0a 7d 0a 0a 2f 2a  DirtyTail;.}../*
29c0: 0a 2a 2a 20 43 68 61 6e 67 65 20 74 68 65 20 70  .** Change the p
29d0: 61 67 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 61  age number of pa
29e0: 67 65 20 70 20 74 6f 20 6e 65 77 50 67 6e 6f 2e  ge p to newPgno.
29f0: 20 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65   .*/.void sqlite
2a00: 33 50 63 61 63 68 65 4d 6f 76 65 28 50 67 48 64  3PcacheMove(PgHd
2a10: 72 20 2a 70 2c 20 50 67 6e 6f 20 6e 65 77 50 67  r *p, Pgno newPg
2a20: 6e 6f 29 7b 0a 20 20 50 43 61 63 68 65 20 2a 70  no){.  PCache *p
2a30: 43 61 63 68 65 20 3d 20 70 2d 3e 70 43 61 63 68  Cache = p->pCach
2a40: 65 3b 0a 20 20 61 73 73 65 72 74 28 20 70 2d 3e  e;.  assert( p->
2a50: 6e 52 65 66 3e 30 20 29 3b 0a 20 20 61 73 73 65  nRef>0 );.  asse
2a60: 72 74 28 20 6e 65 77 50 67 6e 6f 3e 30 20 29 3b  rt( newPgno>0 );
2a70: 0a 20 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c  .  sqlite3Global
2a80: 43 6f 6e 66 69 67 2e 70 63 61 63 68 65 2e 78 52  Config.pcache.xR
2a90: 65 6b 65 79 28 70 43 61 63 68 65 2d 3e 70 43 61  ekey(pCache->pCa
2aa0: 63 68 65 2c 20 70 2c 20 70 2d 3e 70 67 6e 6f 2c  che, p, p->pgno,
2ab0: 20 6e 65 77 50 67 6e 6f 29 3b 0a 20 20 70 2d 3e   newPgno);.  p->
2ac0: 70 67 6e 6f 20 3d 20 6e 65 77 50 67 6e 6f 3b 0a  pgno = newPgno;.
2ad0: 20 20 69 66 28 20 28 70 2d 3e 66 6c 61 67 73 26    if( (p->flags&
2ae0: 50 47 48 44 52 5f 44 49 52 54 59 29 20 26 26 20  PGHDR_DIRTY) && 
2af0: 28 70 2d 3e 66 6c 61 67 73 26 50 47 48 44 52 5f  (p->flags&PGHDR_
2b00: 4e 45 45 44 5f 53 59 4e 43 29 20 29 7b 0a 20 20  NEED_SYNC) ){.  
2b10: 20 20 70 63 61 63 68 65 52 65 6d 6f 76 65 46 72    pcacheRemoveFr
2b20: 6f 6d 44 69 72 74 79 4c 69 73 74 28 70 29 3b 0a  omDirtyList(p);.
2b30: 20 20 20 20 70 63 61 63 68 65 41 64 64 54 6f 44      pcacheAddToD
2b40: 69 72 74 79 4c 69 73 74 28 70 29 3b 0a 20 20 7d  irtyList(p);.  }
2b50: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 72 6f 70 20 65  .}../*.** Drop e
2b60: 76 65 72 79 20 63 61 63 68 65 20 65 6e 74 72 79  very cache entry
2b70: 20 77 68 6f 73 65 20 70 61 67 65 20 6e 75 6d 62   whose page numb
2b80: 65 72 20 69 73 20 67 72 65 61 74 65 72 20 74 68  er is greater th
2b90: 61 6e 20 22 70 67 6e 6f 22 2e 20 54 68 65 0a 2a  an "pgno". The.*
2ba0: 2a 20 63 61 6c 6c 65 72 20 6d 75 73 74 20 65 6e  * caller must en
2bb0: 73 75 72 65 20 74 68 61 74 20 74 68 65 72 65 20  sure that there 
2bc0: 61 72 65 20 6e 6f 20 6f 75 74 73 74 61 6e 64 69  are no outstandi
2bd0: 6e 67 20 72 65 66 65 72 65 6e 63 65 73 20 74 6f  ng references to
2be0: 20 61 6e 79 20 70 61 67 65 73 0a 2a 2a 20 6f 74   any pages.** ot
2bf0: 68 65 72 20 74 68 61 6e 20 70 61 67 65 20 31 20  her than page 1 
2c00: 77 69 74 68 20 61 20 70 61 67 65 20 6e 75 6d 62  with a page numb
2c10: 65 72 20 67 72 65 61 74 65 72 20 74 68 61 6e 20  er greater than 
2c20: 70 67 6e 6f 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74  pgno..**.** If t
2c30: 68 65 72 65 20 69 73 20 61 20 72 65 66 65 72 65  here is a refere
2c40: 6e 63 65 20 74 6f 20 70 61 67 65 20 31 20 61 6e  nce to page 1 an
2c50: 64 20 74 68 65 20 70 67 6e 6f 20 70 61 72 61 6d  d the pgno param
2c60: 65 74 65 72 20 70 61 73 73 65 64 20 74 6f 20 74  eter passed to t
2c70: 68 69 73 0a 2a 2a 20 66 75 6e 63 74 69 6f 6e 20  his.** function 
2c80: 69 73 20 30 2c 20 74 68 65 6e 20 74 68 65 20 64  is 0, then the d
2c90: 61 74 61 20 61 72 65 61 20 61 73 73 6f 63 69 61  ata area associa
2ca0: 74 65 64 20 77 69 74 68 20 70 61 67 65 20 31 20  ted with page 1 
2cb0: 69 73 20 7a 65 72 6f 65 64 2c 20 62 75 74 0a 2a  is zeroed, but.*
2cc0: 2a 20 74 68 65 20 70 61 67 65 20 6f 62 6a 65 63  * the page objec
2cd0: 74 20 69 73 20 6e 6f 74 20 64 72 6f 70 70 65 64  t is not dropped
2ce0: 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
2cf0: 33 50 63 61 63 68 65 54 72 75 6e 63 61 74 65 28  3PcacheTruncate(
2d00: 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 2c 20  PCache *pCache, 
2d10: 50 67 6e 6f 20 70 67 6e 6f 29 7b 0a 20 20 69 66  Pgno pgno){.  if
2d20: 28 20 70 43 61 63 68 65 2d 3e 70 43 61 63 68 65  ( pCache->pCache
2d30: 20 29 7b 0a 20 20 20 20 50 67 48 64 72 20 2a 70   ){.    PgHdr *p
2d40: 3b 0a 20 20 20 20 50 67 48 64 72 20 2a 70 4e 65  ;.    PgHdr *pNe
2d50: 78 74 3b 0a 20 20 20 20 66 6f 72 28 70 3d 70 43  xt;.    for(p=pC
2d60: 61 63 68 65 2d 3e 70 44 69 72 74 79 3b 20 70 3b  ache->pDirty; p;
2d70: 20 70 3d 70 4e 65 78 74 29 7b 0a 20 20 20 20 20   p=pNext){.     
2d80: 20 70 4e 65 78 74 20 3d 20 70 2d 3e 70 44 69 72   pNext = p->pDir
2d90: 74 79 4e 65 78 74 3b 0a 20 20 20 20 20 20 69 66  tyNext;.      if
2da0: 28 20 70 2d 3e 70 67 6e 6f 3e 70 67 6e 6f 20 29  ( p->pgno>pgno )
2db0: 7b 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74  {.        assert
2dc0: 28 20 70 2d 3e 66 6c 61 67 73 26 50 47 48 44 52  ( p->flags&PGHDR
2dd0: 5f 44 49 52 54 59 20 29 3b 0a 20 20 20 20 20 20  _DIRTY );.      
2de0: 20 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 4d    sqlite3PcacheM
2df0: 61 6b 65 43 6c 65 61 6e 28 70 29 3b 0a 20 20 20  akeClean(p);.   
2e00: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69     }.    }.    i
2e10: 66 28 20 70 67 6e 6f 3d 3d 30 20 26 26 20 70 43  f( pgno==0 && pC
2e20: 61 63 68 65 2d 3e 70 50 61 67 65 31 20 29 7b 0a  ache->pPage1 ){.
2e30: 20 20 20 20 20 20 6d 65 6d 73 65 74 28 70 43 61        memset(pCa
2e40: 63 68 65 2d 3e 70 50 61 67 65 31 2d 3e 70 44 61  che->pPage1->pDa
2e50: 74 61 2c 20 30 2c 20 70 43 61 63 68 65 2d 3e 73  ta, 0, pCache->s
2e60: 7a 50 61 67 65 29 3b 0a 20 20 20 20 20 20 70 67  zPage);.      pg
2e70: 6e 6f 20 3d 20 31 3b 0a 20 20 20 20 7d 0a 20 20  no = 1;.    }.  
2e80: 20 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43    sqlite3GlobalC
2e90: 6f 6e 66 69 67 2e 70 63 61 63 68 65 2e 78 54 72  onfig.pcache.xTr
2ea0: 75 6e 63 61 74 65 28 70 43 61 63 68 65 2d 3e 70  uncate(pCache->p
2eb0: 43 61 63 68 65 2c 20 70 67 6e 6f 2b 31 29 3b 0a  Cache, pgno+1);.
2ec0: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f    }.}../*.** Clo
2ed0: 73 65 20 61 20 63 61 63 68 65 2e 0a 2a 2f 0a 76  se a cache..*/.v
2ee0: 6f 69 64 20 73 71 6c 69 74 65 33 50 63 61 63 68  oid sqlite3Pcach
2ef0: 65 43 6c 6f 73 65 28 50 43 61 63 68 65 20 2a 70  eClose(PCache *p
2f00: 43 61 63 68 65 29 7b 0a 20 20 69 66 28 20 70 43  Cache){.  if( pC
2f10: 61 63 68 65 2d 3e 70 43 61 63 68 65 20 29 7b 0a  ache->pCache ){.
2f20: 20 20 20 20 73 71 6c 69 74 65 33 47 6c 6f 62 61      sqlite3Globa
2f30: 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68 65 2e 78  lConfig.pcache.x
2f40: 44 65 73 74 72 6f 79 28 70 43 61 63 68 65 2d 3e  Destroy(pCache->
2f50: 70 43 61 63 68 65 29 3b 0a 20 20 7d 0a 7d 0a 0a  pCache);.  }.}..
2f60: 2f 2a 20 0a 2a 2a 20 44 69 73 63 61 72 64 20 74  /* .** Discard t
2f70: 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74  he contents of t
2f80: 68 65 20 63 61 63 68 65 2e 0a 2a 2f 0a 76 6f 69  he cache..*/.voi
2f90: 64 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 43  d sqlite3PcacheC
2fa0: 6c 65 61 72 28 50 43 61 63 68 65 20 2a 70 43 61  lear(PCache *pCa
2fb0: 63 68 65 29 7b 0a 20 20 73 71 6c 69 74 65 33 50  che){.  sqlite3P
2fc0: 63 61 63 68 65 54 72 75 6e 63 61 74 65 28 70 43  cacheTruncate(pC
2fd0: 61 63 68 65 2c 20 30 29 3b 0a 7d 0a 0a 2f 2a 0a  ache, 0);.}../*.
2fe0: 2a 2a 20 4d 65 72 67 65 20 74 77 6f 20 6c 69 73  ** Merge two lis
2ff0: 74 73 20 6f 66 20 70 61 67 65 73 20 63 6f 6e 6e  ts of pages conn
3000: 65 63 74 65 64 20 62 79 20 70 44 69 72 74 79 20  ected by pDirty 
3010: 61 6e 64 20 69 6e 20 70 67 6e 6f 20 6f 72 64 65  and in pgno orde
3020: 72 2e 0a 2a 2a 20 44 6f 20 6e 6f 74 20 62 6f 74  r..** Do not bot
3030: 68 20 66 69 78 69 6e 67 20 74 68 65 20 70 44 69  h fixing the pDi
3040: 72 74 79 50 72 65 76 20 70 6f 69 6e 74 65 72 73  rtyPrev pointers
3050: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 50 67 48 64  ..*/.static PgHd
3060: 72 20 2a 70 63 61 63 68 65 4d 65 72 67 65 44 69  r *pcacheMergeDi
3070: 72 74 79 4c 69 73 74 28 50 67 48 64 72 20 2a 70  rtyList(PgHdr *p
3080: 41 2c 20 50 67 48 64 72 20 2a 70 42 29 7b 0a 20  A, PgHdr *pB){. 
3090: 20 50 67 48 64 72 20 72 65 73 75 6c 74 2c 20 2a   PgHdr result, *
30a0: 70 54 61 69 6c 3b 0a 20 20 70 54 61 69 6c 20 3d  pTail;.  pTail =
30b0: 20 26 72 65 73 75 6c 74 3b 0a 20 20 77 68 69 6c   &result;.  whil
30c0: 65 28 20 70 41 20 26 26 20 70 42 20 29 7b 0a 20  e( pA && pB ){. 
30d0: 20 20 20 69 66 28 20 70 41 2d 3e 70 67 6e 6f 3c     if( pA->pgno<
30e0: 70 42 2d 3e 70 67 6e 6f 20 29 7b 0a 20 20 20 20  pB->pgno ){.    
30f0: 20 20 70 54 61 69 6c 2d 3e 70 44 69 72 74 79 20    pTail->pDirty 
3100: 3d 20 70 41 3b 0a 20 20 20 20 20 20 70 54 61 69  = pA;.      pTai
3110: 6c 20 3d 20 70 41 3b 0a 20 20 20 20 20 20 70 41  l = pA;.      pA
3120: 20 3d 20 70 41 2d 3e 70 44 69 72 74 79 3b 0a 20   = pA->pDirty;. 
3130: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
3140: 70 54 61 69 6c 2d 3e 70 44 69 72 74 79 20 3d 20  pTail->pDirty = 
3150: 70 42 3b 0a 20 20 20 20 20 20 70 54 61 69 6c 20  pB;.      pTail 
3160: 3d 20 70 42 3b 0a 20 20 20 20 20 20 70 42 20 3d  = pB;.      pB =
3170: 20 70 42 2d 3e 70 44 69 72 74 79 3b 0a 20 20 20   pB->pDirty;.   
3180: 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20 70 41 20   }.  }.  if( pA 
3190: 29 7b 0a 20 20 20 20 70 54 61 69 6c 2d 3e 70 44  ){.    pTail->pD
31a0: 69 72 74 79 20 3d 20 70 41 3b 0a 20 20 7d 65 6c  irty = pA;.  }el
31b0: 73 65 20 69 66 28 20 70 42 20 29 7b 0a 20 20 20  se if( pB ){.   
31c0: 20 70 54 61 69 6c 2d 3e 70 44 69 72 74 79 20 3d   pTail->pDirty =
31d0: 20 70 42 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20   pB;.  }else{.  
31e0: 20 20 70 54 61 69 6c 2d 3e 70 44 69 72 74 79 20    pTail->pDirty 
31f0: 3d 20 30 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  = 0;.  }.  retur
3200: 6e 20 72 65 73 75 6c 74 2e 70 44 69 72 74 79 3b  n result.pDirty;
3210: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 6f 72 74 20 74  .}../*.** Sort t
3220: 68 65 20 6c 69 73 74 20 6f 66 20 70 61 67 65 73  he list of pages
3230: 20 69 6e 20 61 63 63 65 6e 64 69 6e 67 20 6f 72   in accending or
3240: 64 65 72 20 62 79 20 70 67 6e 6f 2e 20 20 50 61  der by pgno.  Pa
3250: 67 65 73 20 61 72 65 0a 2a 2a 20 63 6f 6e 6e 65  ges are.** conne
3260: 63 74 65 64 20 62 79 20 70 44 69 72 74 79 20 70  cted by pDirty p
3270: 6f 69 6e 74 65 72 73 2e 20 20 54 68 65 20 70 44  ointers.  The pD
3280: 69 72 74 79 50 72 65 76 20 70 6f 69 6e 74 65 72  irtyPrev pointer
3290: 73 20 61 72 65 0a 2a 2a 20 63 6f 72 72 75 70 74  s are.** corrupt
32a0: 65 64 20 62 79 20 74 68 69 73 20 73 6f 72 74 2e  ed by this sort.
32b0: 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 4e 5f 53 4f  .*/.#define N_SO
32c0: 52 54 5f 42 55 43 4b 45 54 5f 41 4c 4c 4f 43 20  RT_BUCKET_ALLOC 
32d0: 32 35 0a 23 64 65 66 69 6e 65 20 4e 5f 53 4f 52  25.#define N_SOR
32e0: 54 5f 42 55 43 4b 45 54 20 20 20 20 20 20 20 32  T_BUCKET       2
32f0: 35 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f  5.#ifdef SQLITE_
3300: 54 45 53 54 0a 20 20 69 6e 74 20 73 71 6c 69 74  TEST.  int sqlit
3310: 65 33 5f 70 61 67 65 72 5f 6e 5f 73 6f 72 74 5f  e3_pager_n_sort_
3320: 62 75 63 6b 65 74 20 3d 20 30 3b 0a 20 20 23 75  bucket = 0;.  #u
3330: 6e 64 65 66 20 4e 5f 53 4f 52 54 5f 42 55 43 4b  ndef N_SORT_BUCK
3340: 45 54 0a 20 20 23 64 65 66 69 6e 65 20 4e 5f 53  ET.  #define N_S
3350: 4f 52 54 5f 42 55 43 4b 45 54 20 5c 0a 20 20 20  ORT_BUCKET \.   
3360: 28 73 71 6c 69 74 65 33 5f 70 61 67 65 72 5f 6e  (sqlite3_pager_n
3370: 5f 73 6f 72 74 5f 62 75 63 6b 65 74 3f 73 71 6c  _sort_bucket?sql
3380: 69 74 65 33 5f 70 61 67 65 72 5f 6e 5f 73 6f 72  ite3_pager_n_sor
3390: 74 5f 62 75 63 6b 65 74 3a 4e 5f 53 4f 52 54 5f  t_bucket:N_SORT_
33a0: 42 55 43 4b 45 54 5f 41 4c 4c 4f 43 29 0a 23 65  BUCKET_ALLOC).#e
33b0: 6e 64 69 66 0a 73 74 61 74 69 63 20 50 67 48 64  ndif.static PgHd
33c0: 72 20 2a 70 63 61 63 68 65 53 6f 72 74 44 69 72  r *pcacheSortDir
33d0: 74 79 4c 69 73 74 28 50 67 48 64 72 20 2a 70 49  tyList(PgHdr *pI
33e0: 6e 29 7b 0a 20 20 50 67 48 64 72 20 2a 61 5b 4e  n){.  PgHdr *a[N
33f0: 5f 53 4f 52 54 5f 42 55 43 4b 45 54 5f 41 4c 4c  _SORT_BUCKET_ALL
3400: 4f 43 5d 2c 20 2a 70 3b 0a 20 20 69 6e 74 20 69  OC], *p;.  int i
3410: 3b 0a 20 20 6d 65 6d 73 65 74 28 61 2c 20 30 2c  ;.  memset(a, 0,
3420: 20 73 69 7a 65 6f 66 28 61 29 29 3b 0a 20 20 77   sizeof(a));.  w
3430: 68 69 6c 65 28 20 70 49 6e 20 29 7b 0a 20 20 20  hile( pIn ){.   
3440: 20 70 20 3d 20 70 49 6e 3b 0a 20 20 20 20 70 49   p = pIn;.    pI
3450: 6e 20 3d 20 70 2d 3e 70 44 69 72 74 79 3b 0a 20  n = p->pDirty;. 
3460: 20 20 20 70 2d 3e 70 44 69 72 74 79 20 3d 20 30     p->pDirty = 0
3470: 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69  ;.    for(i=0; i
3480: 3c 4e 5f 53 4f 52 54 5f 42 55 43 4b 45 54 2d 31  <N_SORT_BUCKET-1
3490: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 69 66  ; i++){.      if
34a0: 28 20 61 5b 69 5d 3d 3d 30 20 29 7b 0a 20 20 20  ( a[i]==0 ){.   
34b0: 20 20 20 20 20 61 5b 69 5d 20 3d 20 70 3b 0a 20       a[i] = p;. 
34c0: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
34d0: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
34e0: 20 20 20 70 20 3d 20 70 63 61 63 68 65 4d 65 72     p = pcacheMer
34f0: 67 65 44 69 72 74 79 4c 69 73 74 28 61 5b 69 5d  geDirtyList(a[i]
3500: 2c 20 70 29 3b 0a 20 20 20 20 20 20 20 20 61 5b  , p);.        a[
3510: 69 5d 20 3d 20 30 3b 0a 20 20 20 20 20 20 7d 0a  i] = 0;.      }.
3520: 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 69 3d      }.    if( i=
3530: 3d 4e 5f 53 4f 52 54 5f 42 55 43 4b 45 54 2d 31  =N_SORT_BUCKET-1
3540: 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 43 6f 76   ){.      /* Cov
3550: 65 72 61 67 65 3a 20 54 6f 20 67 65 74 20 68 65  erage: To get he
3560: 72 65 2c 20 74 68 65 72 65 20 6e 65 65 64 20 74  re, there need t
3570: 6f 20 62 65 20 32 5e 28 4e 5f 53 4f 52 54 5f 42  o be 2^(N_SORT_B
3580: 55 43 4b 45 54 29 20 0a 20 20 20 20 20 20 2a 2a  UCKET) .      **
3590: 20 65 6c 65 6d 65 6e 74 73 20 69 6e 20 74 68 65   elements in the
35a0: 20 69 6e 70 75 74 20 6c 69 73 74 2e 20 54 68 69   input list. Thi
35b0: 73 20 69 73 20 70 6f 73 73 69 62 6c 65 2c 20 62  s is possible, b
35c0: 75 74 20 69 6d 70 72 61 63 74 69 63 61 6c 2e 0a  ut impractical..
35d0: 20 20 20 20 20 20 2a 2a 20 54 65 73 74 69 6e 67        ** Testing
35e0: 20 74 68 69 73 20 6c 69 6e 65 20 69 73 20 74 68   this line is th
35f0: 65 20 70 6f 69 6e 74 20 6f 66 20 67 6c 6f 62 61  e point of globa
3600: 6c 20 76 61 72 69 61 62 6c 65 0a 20 20 20 20 20  l variable.     
3610: 20 2a 2a 20 73 71 6c 69 74 65 33 5f 70 61 67 65   ** sqlite3_page
3620: 72 5f 6e 5f 73 6f 72 74 5f 62 75 63 6b 65 74 2e  r_n_sort_bucket.
3630: 0a 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 20  .      */.      
3640: 61 5b 69 5d 20 3d 20 70 63 61 63 68 65 4d 65 72  a[i] = pcacheMer
3650: 67 65 44 69 72 74 79 4c 69 73 74 28 61 5b 69 5d  geDirtyList(a[i]
3660: 2c 20 70 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  , p);.    }.  }.
3670: 20 20 70 20 3d 20 61 5b 30 5d 3b 0a 20 20 66 6f    p = a[0];.  fo
3680: 72 28 69 3d 31 3b 20 69 3c 4e 5f 53 4f 52 54 5f  r(i=1; i<N_SORT_
3690: 42 55 43 4b 45 54 3b 20 69 2b 2b 29 7b 0a 20 20  BUCKET; i++){.  
36a0: 20 20 70 20 3d 20 70 63 61 63 68 65 4d 65 72 67    p = pcacheMerg
36b0: 65 44 69 72 74 79 4c 69 73 74 28 70 2c 20 61 5b  eDirtyList(p, a[
36c0: 69 5d 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  i]);.  }.  retur
36d0: 6e 20 70 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65  n p;.}../*.** Re
36e0: 74 75 72 6e 20 61 20 6c 69 73 74 20 6f 66 20 61  turn a list of a
36f0: 6c 6c 20 64 69 72 74 79 20 70 61 67 65 73 20 69  ll dirty pages i
3700: 6e 20 74 68 65 20 63 61 63 68 65 2c 20 73 6f 72  n the cache, sor
3710: 74 65 64 20 62 79 20 70 61 67 65 20 6e 75 6d 62  ted by page numb
3720: 65 72 2e 0a 2a 2f 0a 50 67 48 64 72 20 2a 73 71  er..*/.PgHdr *sq
3730: 6c 69 74 65 33 50 63 61 63 68 65 44 69 72 74 79  lite3PcacheDirty
3740: 4c 69 73 74 28 50 43 61 63 68 65 20 2a 70 43 61  List(PCache *pCa
3750: 63 68 65 29 7b 0a 20 20 50 67 48 64 72 20 2a 70  che){.  PgHdr *p
3760: 3b 0a 20 20 66 6f 72 28 70 3d 70 43 61 63 68 65  ;.  for(p=pCache
3770: 2d 3e 70 44 69 72 74 79 3b 20 70 3b 20 70 3d 70  ->pDirty; p; p=p
3780: 2d 3e 70 44 69 72 74 79 4e 65 78 74 29 7b 0a 20  ->pDirtyNext){. 
3790: 20 20 20 70 2d 3e 70 44 69 72 74 79 20 3d 20 70     p->pDirty = p
37a0: 2d 3e 70 44 69 72 74 79 4e 65 78 74 3b 0a 20 20  ->pDirtyNext;.  
37b0: 7d 0a 20 20 72 65 74 75 72 6e 20 70 63 61 63 68  }.  return pcach
37c0: 65 53 6f 72 74 44 69 72 74 79 4c 69 73 74 28 70  eSortDirtyList(p
37d0: 43 61 63 68 65 2d 3e 70 44 69 72 74 79 29 3b 0a  Cache->pDirty);.
37e0: 7d 0a 0a 2f 2a 20 0a 2a 2a 20 52 65 74 75 72 6e  }../* .** Return
37f0: 20 74 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65   the total numbe
3800: 72 20 6f 66 20 72 65 66 65 72 65 6e 63 65 64 20  r of referenced 
3810: 70 61 67 65 73 20 68 65 6c 64 20 62 79 20 74 68  pages held by th
3820: 65 20 63 61 63 68 65 2e 0a 2a 2f 0a 69 6e 74 20  e cache..*/.int 
3830: 73 71 6c 69 74 65 33 50 63 61 63 68 65 52 65 66  sqlite3PcacheRef
3840: 43 6f 75 6e 74 28 50 43 61 63 68 65 20 2a 70 43  Count(PCache *pC
3850: 61 63 68 65 29 7b 0a 20 20 72 65 74 75 72 6e 20  ache){.  return 
3860: 70 43 61 63 68 65 2d 3e 6e 52 65 66 3b 0a 7d 0a  pCache->nRef;.}.
3870: 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68  ./*.** Return th
3880: 65 20 6e 75 6d 62 65 72 20 6f 66 20 72 65 66 65  e number of refe
3890: 72 65 6e 63 65 73 20 74 6f 20 74 68 65 20 70 61  rences to the pa
38a0: 67 65 20 73 75 70 70 6c 69 65 64 20 61 73 20 61  ge supplied as a
38b0: 6e 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2f 0a 69  n argument..*/.i
38c0: 6e 74 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  nt sqlite3Pcache
38d0: 50 61 67 65 52 65 66 63 6f 75 6e 74 28 50 67 48  PageRefcount(PgH
38e0: 64 72 20 2a 70 29 7b 0a 20 20 72 65 74 75 72 6e  dr *p){.  return
38f0: 20 70 2d 3e 6e 52 65 66 3b 0a 7d 0a 0a 2f 2a 20   p->nRef;.}../* 
3900: 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 74  .** Return the t
3910: 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 70  otal number of p
3920: 61 67 65 73 20 69 6e 20 74 68 65 20 63 61 63 68  ages in the cach
3930: 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  e..*/.int sqlite
3940: 33 50 63 61 63 68 65 50 61 67 65 63 6f 75 6e 74  3PcachePagecount
3950: 28 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 29  (PCache *pCache)
3960: 7b 0a 20 20 69 6e 74 20 6e 50 61 67 65 20 3d 20  {.  int nPage = 
3970: 30 3b 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d  0;.  if( pCache-
3980: 3e 70 43 61 63 68 65 20 29 7b 0a 20 20 20 20 6e  >pCache ){.    n
3990: 50 61 67 65 20 3d 20 73 71 6c 69 74 65 33 47 6c  Page = sqlite3Gl
39a0: 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 63 61 63 68  obalConfig.pcach
39b0: 65 2e 78 50 61 67 65 63 6f 75 6e 74 28 70 43 61  e.xPagecount(pCa
39c0: 63 68 65 2d 3e 70 43 61 63 68 65 29 3b 0a 20 20  che->pCache);.  
39d0: 7d 0a 20 20 72 65 74 75 72 6e 20 6e 50 61 67 65  }.  return nPage
39e0: 3b 0a 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c 49  ;.}..#ifdef SQLI
39f0: 54 45 5f 54 45 53 54 0a 2f 2a 0a 2a 2a 20 47 65  TE_TEST./*.** Ge
3a00: 74 20 74 68 65 20 73 75 67 67 65 73 74 65 64 20  t the suggested 
3a10: 63 61 63 68 65 2d 73 69 7a 65 20 76 61 6c 75 65  cache-size value
3a20: 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33  ..*/.int sqlite3
3a30: 50 63 61 63 68 65 47 65 74 43 61 63 68 65 73 69  PcacheGetCachesi
3a40: 7a 65 28 50 43 61 63 68 65 20 2a 70 43 61 63 68  ze(PCache *pCach
3a50: 65 29 7b 0a 20 20 72 65 74 75 72 6e 20 70 43 61  e){.  return pCa
3a60: 63 68 65 2d 3e 6e 4d 61 78 3b 0a 7d 0a 23 65 6e  che->nMax;.}.#en
3a70: 64 69 66 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20 74  dif../*.** Set t
3a80: 68 65 20 73 75 67 67 65 73 74 65 64 20 63 61 63  he suggested cac
3a90: 68 65 2d 73 69 7a 65 20 76 61 6c 75 65 2e 0a 2a  he-size value..*
3aa0: 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63  /.void sqlite3Pc
3ab0: 61 63 68 65 53 65 74 43 61 63 68 65 73 69 7a 65  acheSetCachesize
3ac0: 28 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 2c  (PCache *pCache,
3ad0: 20 69 6e 74 20 6d 78 50 61 67 65 29 7b 0a 20 20   int mxPage){.  
3ae0: 70 43 61 63 68 65 2d 3e 6e 4d 61 78 20 3d 20 6d  pCache->nMax = m
3af0: 78 50 61 67 65 3b 0a 20 20 69 66 28 20 70 43 61  xPage;.  if( pCa
3b00: 63 68 65 2d 3e 70 43 61 63 68 65 20 29 7b 0a 20  che->pCache ){. 
3b10: 20 20 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c     sqlite3Global
3b20: 43 6f 6e 66 69 67 2e 70 63 61 63 68 65 2e 78 43  Config.pcache.xC
3b30: 61 63 68 65 73 69 7a 65 28 70 43 61 63 68 65 2d  achesize(pCache-
3b40: 3e 70 43 61 63 68 65 2c 20 6d 78 50 61 67 65 29  >pCache, mxPage)
3b50: 3b 0a 20 20 7d 0a 7d 0a 0a 23 69 66 64 65 66 20  ;.  }.}..#ifdef 
3b60: 53 51 4c 49 54 45 5f 43 48 45 43 4b 5f 50 41 47  SQLITE_CHECK_PAG
3b70: 45 53 0a 2f 2a 0a 2a 2a 20 46 6f 72 20 61 6c 6c  ES./*.** For all
3b80: 20 64 69 72 74 79 20 70 61 67 65 73 20 63 75 72   dirty pages cur
3b90: 72 65 6e 74 6c 79 20 69 6e 20 74 68 65 20 63 61  rently in the ca
3ba0: 63 68 65 2c 20 69 6e 76 6f 6b 65 20 74 68 65 20  che, invoke the 
3bb0: 73 70 65 63 69 66 69 65 64 0a 2a 2a 20 63 61 6c  specified.** cal
3bc0: 6c 62 61 63 6b 2e 20 54 68 69 73 20 69 73 20 6f  lback. This is o
3bd0: 6e 6c 79 20 75 73 65 64 20 69 66 20 74 68 65 20  nly used if the 
3be0: 53 51 4c 49 54 45 5f 43 48 45 43 4b 5f 50 41 47  SQLITE_CHECK_PAG
3bf0: 45 53 20 6d 61 63 72 6f 20 69 73 0a 2a 2a 20 64  ES macro is.** d
3c00: 65 66 69 6e 65 64 2e 0a 2a 2f 0a 76 6f 69 64 20  efined..*/.void 
3c10: 73 71 6c 69 74 65 33 50 63 61 63 68 65 49 74 65  sqlite3PcacheIte
3c20: 72 61 74 65 44 69 72 74 79 28 50 43 61 63 68 65  rateDirty(PCache
3c30: 20 2a 70 43 61 63 68 65 2c 20 76 6f 69 64 20 28   *pCache, void (
3c40: 2a 78 49 74 65 72 29 28 50 67 48 64 72 20 2a 29  *xIter)(PgHdr *)
3c50: 29 7b 0a 20 20 50 67 48 64 72 20 2a 70 44 69 72  ){.  PgHdr *pDir
3c60: 74 79 3b 0a 20 20 66 6f 72 28 70 44 69 72 74 79  ty;.  for(pDirty
3c70: 3d 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 3b  =pCache->pDirty;
3c80: 20 70 44 69 72 74 79 3b 20 70 44 69 72 74 79 3d   pDirty; pDirty=
3c90: 70 44 69 72 74 79 2d 3e 70 44 69 72 74 79 4e 65  pDirty->pDirtyNe
3ca0: 78 74 29 7b 0a 20 20 20 20 78 49 74 65 72 28 70  xt){.    xIter(p
3cb0: 44 69 72 74 79 29 3b 0a 20 20 7d 0a 7d 0a 23 65  Dirty);.  }.}.#e
3cc0: 6e 64 69 66 0a                                   ndif.