/ Hex Artifact Content
Login

Artifact 3feb47f5ce4174570e7b76bd851faccf7df55e80:


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 31 30 20 32 30 30  che.c,v 1.10 200
01c0: 38 2f 30 38 2f 32 32 20 31 37 3a 33 34 3a 34 35  8/08/22 17:34:45
01d0: 20 64 72 68 20 45 78 70 20 24 0a 2a 2f 0a 23 69   drh Exp $.*/.#i
01e0: 6e 63 6c 75 64 65 20 22 73 71 6c 69 74 65 49 6e  nclude "sqliteIn
01f0: 74 2e 68 22 0a 0a 2f 2a 0a 2a 2a 20 41 20 63 6f  t.h"../*.** A co
0200: 6d 70 6c 65 74 65 20 70 61 67 65 20 63 61 63 68  mplete page cach
0210: 65 20 69 73 20 61 6e 20 69 6e 73 74 61 6e 63 65  e is an instance
0220: 20 6f 66 20 74 68 69 73 20 73 74 72 75 63 74 75   of this structu
0230: 72 65 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 50 43  re..*/.struct PC
0240: 61 63 68 65 20 7b 0a 20 20 50 43 61 63 68 65 20  ache {.  PCache 
0250: 2a 70 4e 65 78 74 41 6c 6c 2c 20 2a 70 50 72 65  *pNextAll, *pPre
0260: 76 41 6c 6c 3b 20 20 20 20 20 20 20 20 2f 2a 20  vAll;        /* 
0270: 4c 69 73 74 20 6f 66 20 61 6c 6c 20 70 61 67 65  List of all page
0280: 20 63 61 63 68 65 73 20 2a 2f 0a 20 20 69 6e 74   caches */.  int
0290: 20 73 7a 50 61 67 65 3b 20 20 20 20 20 20 20 20   szPage;        
02a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
02b0: 20 2f 2a 20 53 69 7a 65 20 6f 66 20 65 76 65 72   /* Size of ever
02c0: 79 20 70 61 67 65 20 69 6e 20 74 68 69 73 20 63  y page in this c
02d0: 61 63 68 65 20 2a 2f 0a 20 20 69 6e 74 20 73 7a  ache */.  int sz
02e0: 45 78 74 72 61 3b 20 20 20 20 20 20 20 20 20 20  Extra;          
02f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0300: 20 53 69 7a 65 20 6f 66 20 65 78 74 72 61 20 73   Size of extra s
0310: 70 61 63 65 20 66 6f 72 20 65 61 63 68 20 70 61  pace for each pa
0320: 67 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 48 61 73  ge */.  int nHas
0330: 68 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  h;              
0340: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
0350: 75 6d 62 65 72 20 6f 66 20 73 6c 6f 74 73 20 69  umber of slots i
0360: 6e 20 61 70 48 61 73 68 5b 5d 20 2a 2f 0a 20 20  n apHash[] */.  
0370: 69 6e 74 20 6e 50 61 67 65 3b 20 20 20 20 20 20  int nPage;      
0380: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0390: 20 20 20 20 2f 2a 20 54 6f 74 61 6c 20 6e 75 6d      /* Total num
03a0: 62 65 72 20 6f 66 20 70 61 67 65 73 20 69 6e 20  ber of pages in 
03b0: 61 70 48 61 73 68 20 2a 2f 0a 20 20 69 6e 74 20  apHash */.  int 
03c0: 6e 4d 61 78 3b 20 20 20 20 20 20 20 20 20 20 20  nMax;           
03d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
03e0: 2f 2a 20 43 6f 6e 66 69 67 75 72 65 64 20 63 61  /* Configured ca
03f0: 63 68 65 20 73 69 7a 65 20 2a 2f 0a 20 20 50 67  che size */.  Pg
0400: 48 64 72 20 2a 2a 61 70 48 61 73 68 3b 20 20 20  Hdr **apHash;   
0410: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0420: 20 20 2f 2a 20 48 61 73 68 20 74 61 62 6c 65 20    /* Hash table 
0430: 66 6f 72 20 66 61 73 74 20 6c 6f 6f 6b 75 70 20  for fast lookup 
0440: 62 79 20 70 67 6e 6f 20 2a 2f 0a 20 20 69 6e 74  by pgno */.  int
0450: 20 62 50 75 72 67 65 61 62 6c 65 3b 20 20 20 20   bPurgeable;    
0460: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0470: 20 2f 2a 20 54 72 75 65 20 69 66 20 70 61 67 65   /* True if page
0480: 73 20 61 72 65 20 6f 6e 20 62 61 63 6b 69 6e 67  s are on backing
0490: 20 73 74 6f 72 65 20 2a 2f 0a 20 20 76 6f 69 64   store */.  void
04a0: 20 28 2a 78 44 65 73 74 72 6f 79 29 28 50 67 48   (*xDestroy)(PgH
04b0: 64 72 2a 29 3b 20 20 20 20 20 20 20 20 20 20 20  dr*);           
04c0: 2f 2a 20 43 61 6c 6c 65 64 20 77 68 65 6e 20 72  /* Called when r
04d0: 65 66 63 6e 74 20 67 6f 65 73 20 31 2d 3e 30 20  efcnt goes 1->0 
04e0: 2a 2f 0a 20 20 69 6e 74 20 28 2a 78 53 74 72 65  */.  int (*xStre
04f0: 73 73 29 28 76 6f 69 64 2a 2c 50 67 48 64 72 2a  ss)(void*,PgHdr*
0500: 29 3b 20 20 20 20 20 20 20 2f 2a 20 43 61 6c 6c  );       /* Call
0510: 20 74 6f 20 74 72 79 20 6d 61 6b 65 20 61 20 70   to try make a p
0520: 61 67 65 20 63 6c 65 61 6e 20 2a 2f 0a 20 20 76  age clean */.  v
0530: 6f 69 64 20 2a 70 53 74 72 65 73 73 3b 20 20 20  oid *pStress;   
0540: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0550: 20 20 20 2f 2a 20 41 72 67 75 6d 65 6e 74 20 74     /* Argument t
0560: 6f 20 78 53 74 72 65 73 73 20 2a 2f 0a 20 20 50  o xStress */.  P
0570: 67 48 64 72 20 2a 70 43 6c 65 61 6e 3b 20 20 20  gHdr *pClean;   
0580: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0590: 20 20 20 2f 2a 20 4c 69 73 74 20 6f 66 20 63 6c     /* List of cl
05a0: 65 61 6e 20 70 61 67 65 73 20 69 6e 20 75 73 65  ean pages in use
05b0: 20 2a 2f 0a 20 20 50 67 48 64 72 20 2a 70 44 69   */.  PgHdr *pDi
05c0: 72 74 79 3b 20 20 20 20 20 20 20 20 20 20 20 20  rty;            
05d0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 69 73            /* Lis
05e0: 74 20 6f 66 20 64 69 72 74 79 20 70 61 67 65 73  t of dirty pages
05f0: 20 2a 2f 0a 20 20 69 6e 74 20 6e 52 65 66 3b 20   */.  int nRef; 
0600: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0610: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
0620: 62 65 72 20 6f 66 20 6f 75 74 73 74 61 6e 64 69  ber of outstandi
0630: 6e 67 20 70 61 67 65 20 72 65 66 73 20 2a 2f 0a  ng page refs */.
0640: 0a 20 20 69 6e 74 20 69 49 6e 55 73 65 4d 4d 3b  .  int iInUseMM;
0650: 0a 20 20 69 6e 74 20 69 49 6e 55 73 65 44 42 3b  .  int iInUseDB;
0660: 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20  .};../*.** Free 
0670: 73 6c 6f 74 73 20 69 6e 20 74 68 65 20 70 61 67  slots in the pag
0680: 65 20 62 6c 6f 63 6b 20 61 6c 6c 6f 63 61 74 6f  e block allocato
0690: 72 0a 2a 2f 0a 74 79 70 65 64 65 66 20 73 74 72  r.*/.typedef str
06a0: 75 63 74 20 50 67 46 72 65 65 73 6c 6f 74 20 50  uct PgFreeslot P
06b0: 67 46 72 65 65 73 6c 6f 74 3b 0a 73 74 72 75 63  gFreeslot;.struc
06c0: 74 20 50 67 46 72 65 65 73 6c 6f 74 20 7b 0a 20  t PgFreeslot {. 
06d0: 20 50 67 46 72 65 65 73 6c 6f 74 20 2a 70 4e 65   PgFreeslot *pNe
06e0: 78 74 3b 20 20 2f 2a 20 4e 65 78 74 20 66 72 65  xt;  /* Next fre
06f0: 65 20 73 6c 6f 74 20 2a 2f 0a 7d 3b 0a 0a 2f 2a  e slot */.};../*
0700: 0a 2a 2a 20 47 6c 6f 62 61 6c 20 64 61 74 61 20  .** Global data 
0710: 66 6f 72 20 74 68 65 20 70 61 67 65 20 63 61 63  for the page cac
0720: 68 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 6d 61  he..**.** The ma
0730: 78 69 6d 75 6d 20 6e 75 6d 62 65 72 20 6f 66 20  ximum number of 
0740: 63 61 63 68 65 64 20 70 61 67 65 73 20 73 74 6f  cached pages sto
0750: 72 65 64 20 62 79 20 74 68 65 20 73 79 73 74 65  red by the syste
0760: 6d 20 69 73 20 64 65 74 65 72 6d 69 6e 65 64 0a  m is determined.
0770: 2a 2a 20 62 79 20 74 68 65 20 70 63 61 63 68 65  ** by the pcache
0780: 2e 6d 78 50 61 67 65 20 61 6e 64 20 70 63 61 63  .mxPage and pcac
0790: 68 65 2e 6d 78 50 61 67 65 50 75 72 67 65 61 62  he.mxPagePurgeab
07a0: 6c 65 20 76 61 72 69 61 62 6c 65 73 2e 20 49 66  le variables. If
07b0: 0a 2a 2a 20 6d 78 50 61 67 65 20 69 73 20 6e 6f  .** mxPage is no
07c0: 6e 2d 7a 65 72 6f 2c 20 74 68 65 6e 20 74 68 65  n-zero, then the
07d0: 20 73 79 73 74 65 6d 20 74 72 69 65 73 20 74 6f   system tries to
07e0: 20 6c 69 6d 69 74 20 74 68 65 20 6e 75 6d 62 65   limit the numbe
07f0: 72 20 6f 66 0a 2a 2a 20 63 61 63 68 65 64 20 70  r of.** cached p
0800: 61 67 65 73 20 73 74 6f 72 65 64 20 74 6f 20 6d  ages stored to m
0810: 78 50 61 67 65 2e 20 49 6e 20 74 68 69 73 20 63  xPage. In this c
0820: 61 73 65 20 6d 78 50 61 67 65 50 75 72 67 65 61  ase mxPagePurgea
0830: 62 6c 65 20 69 73 20 6e 6f 74 20 0a 2a 2a 20 75  ble is not .** u
0840: 73 65 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 6d 78  sed..**.** If mx
0850: 50 61 67 65 20 69 73 20 7a 65 72 6f 2c 20 74 68  Page is zero, th
0860: 65 6e 20 74 68 65 20 73 79 73 74 65 6d 20 74 72  en the system tr
0870: 69 65 73 20 74 6f 20 6c 69 6d 69 74 20 74 68 65  ies to limit the
0880: 20 6e 75 6d 62 65 72 20 6f 66 0a 2a 2a 20 70 61   number of.** pa
0890: 67 65 73 20 68 65 6c 64 20 62 79 20 70 75 72 67  ges held by purg
08a0: 61 62 6c 65 20 63 61 63 68 65 73 20 74 6f 20 6d  able caches to m
08b0: 78 50 61 67 65 50 75 72 67 65 61 62 6c 65 2e 0a  xPagePurgeable..
08c0: 2a 2a 0a 2a 2a 20 54 68 65 20 64 6f 75 62 6c 79  **.** The doubly
08d0: 2d 6c 69 6e 6b 65 64 20 6c 69 73 74 20 74 68 61  -linked list tha
08e0: 74 20 72 75 6e 73 20 62 65 74 77 65 65 6e 20 70  t runs between p
08f0: 63 61 63 68 65 2e 70 4c 72 75 48 65 61 64 20 61  cache.pLruHead a
0900: 6e 64 20 0a 2a 2a 20 70 63 61 63 68 65 2e 70 4c  nd .** pcache.pL
0910: 72 75 54 61 69 6c 20 63 6f 6e 74 61 69 6e 73 20  ruTail contains 
0920: 61 6c 6c 20 70 61 67 65 73 20 69 6e 20 74 68 65  all pages in the
0930: 20 73 79 73 74 65 6d 20 77 69 74 68 20 61 20 7a   system with a z
0940: 65 72 6f 20 0a 2a 2a 20 72 65 66 65 72 65 6e 63  ero .** referenc
0950: 65 20 63 6f 75 6e 74 2e 20 54 68 65 20 70 63 61  e count. The pca
0960: 63 68 65 2e 70 4c 72 75 53 79 6e 63 65 64 20 76  che.pLruSynced v
0970: 61 72 69 61 62 6c 65 20 70 6f 69 6e 74 73 20 74  ariable points t
0980: 6f 20 74 68 65 20 6c 61 73 74 0a 2a 2a 20 28 63  o the last.** (c
0990: 6c 6f 73 65 73 74 20 74 6f 20 70 63 61 63 68 65  losest to pcache
09a0: 2e 70 4c 72 75 54 61 69 6c 29 20 65 6e 74 72 79  .pLruTail) entry
09b0: 20 69 6e 20 74 68 69 73 20 6c 69 73 74 20 74 68   in this list th
09c0: 61 74 20 64 6f 65 73 20 6e 6f 74 20 68 61 76 65  at does not have
09d0: 0a 2a 2a 20 74 68 65 20 50 47 48 44 52 5f 4e 45  .** the PGHDR_NE
09e0: 45 44 5f 53 59 4e 43 20 66 6c 61 67 20 73 65 74  ED_SYNC flag set
09f0: 2e 20 54 68 69 73 20 69 73 20 74 68 65 20 70 61  . This is the pa
0a00: 67 65 20 74 68 61 74 20 74 68 65 20 70 63 61 63  ge that the pcac
0a10: 68 65 52 65 63 79 63 6c 65 28 29 0a 2a 2a 20 66  heRecycle().** f
0a20: 75 6e 63 74 69 6f 6e 20 77 69 6c 6c 20 74 72 79  unction will try
0a30: 20 74 6f 20 72 65 63 79 63 6c 65 2e 0a 2a 2f 0a   to recycle..*/.
0a40: 73 74 61 74 69 63 20 73 74 72 75 63 74 20 50 43  static struct PC
0a50: 61 63 68 65 47 6c 6f 62 61 6c 20 7b 0a 20 20 69  acheGlobal {.  i
0a60: 6e 74 20 69 73 49 6e 69 74 3b 20 20 20 20 20 20  nt isInit;      
0a70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0a80: 20 20 20 2f 2a 20 54 72 75 65 20 77 68 65 6e 20     /* True when 
0a90: 69 6e 69 74 69 61 6c 69 7a 65 64 20 2a 2f 0a 20  initialized */. 
0aa0: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 20 2a   sqlite3_mutex *
0ab0: 6d 75 74 65 78 5f 6d 65 6d 32 3b 20 20 20 20 20  mutex_mem2;     
0ac0: 20 20 20 20 20 2f 2a 20 73 74 61 74 69 63 20 6d       /* static m
0ad0: 75 74 65 78 20 4d 55 54 45 58 5f 53 54 41 54 49  utex MUTEX_STATI
0ae0: 43 5f 4d 45 4d 32 20 2a 2f 0a 20 20 73 71 6c 69  C_MEM2 */.  sqli
0af0: 74 65 33 5f 6d 75 74 65 78 20 2a 6d 75 74 65 78  te3_mutex *mutex
0b00: 5f 6c 72 75 3b 20 20 20 20 20 20 20 20 20 20 20  _lru;           
0b10: 2f 2a 20 73 74 61 74 69 63 20 6d 75 74 65 78 20  /* static mutex 
0b20: 4d 55 54 45 58 5f 53 54 41 54 49 43 5f 4c 52 55  MUTEX_STATIC_LRU
0b30: 20 2a 2f 0a 20 20 50 43 61 63 68 65 20 2a 70 41   */.  PCache *pA
0b40: 6c 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ll;             
0b50: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 6c 69 73            /* lis
0b60: 74 20 6f 66 20 61 6c 6c 20 70 61 67 65 20 63 61  t of all page ca
0b70: 63 68 65 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 50  ches */.  int nP
0b80: 61 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  age;            
0b90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0ba0: 20 4e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73   Number of pages
0bb0: 20 2a 2f 0a 20 20 69 6e 74 20 6e 50 75 72 67 65   */.  int nPurge
0bc0: 61 62 6c 65 3b 20 20 20 20 20 20 20 20 20 20 20  able;           
0bd0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
0be0: 62 65 72 20 6f 66 20 70 61 67 65 73 20 69 6e 20  ber of pages in 
0bf0: 70 75 72 67 61 62 6c 65 20 63 61 63 68 65 73 20  purgable caches 
0c00: 2a 2f 0a 20 20 69 6e 74 20 6d 78 50 61 67 65 3b  */.  int mxPage;
0c10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c20: 20 20 20 20 20 20 20 20 20 2f 2a 20 47 6c 6f 62           /* Glob
0c30: 61 6c 6c 79 20 63 6f 6e 66 69 67 75 72 65 64 20  ally configured 
0c40: 70 61 67 65 20 6d 61 78 69 6d 75 6d 20 2a 2f 0a  page maximum */.
0c50: 20 20 69 6e 74 20 6d 78 50 61 67 65 50 75 72 67    int mxPagePurg
0c60: 65 61 62 6c 65 3b 20 20 20 20 20 20 20 20 20 20  eable;          
0c70: 20 20 20 20 20 20 2f 2a 20 50 75 72 67 65 61 62        /* Purgeab
0c80: 6c 65 20 70 61 67 65 20 6d 61 78 69 6d 75 6d 20  le page maximum 
0c90: 2a 2f 0a 20 20 50 67 48 64 72 20 2a 70 4c 72 75  */.  PgHdr *pLru
0ca0: 48 65 61 64 2c 20 2a 70 4c 72 75 54 61 69 6c 3b  Head, *pLruTail;
0cb0: 20 20 20 20 20 20 20 20 20 2f 2a 20 47 6c 6f 62           /* Glob
0cc0: 61 6c 20 4c 52 55 20 6c 69 73 74 20 6f 66 20 75  al LRU list of u
0cd0: 6e 75 73 65 64 20 70 61 67 65 73 20 2a 2f 0a 20  nused pages */. 
0ce0: 20 50 67 48 64 72 20 2a 70 4c 72 75 53 79 6e 63   PgHdr *pLruSync
0cf0: 65 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ed;             
0d00: 20 20 20 20 20 2f 2a 20 4c 61 73 74 20 73 79 6e       /* Last syn
0d10: 63 65 64 20 65 6e 74 72 79 20 69 6e 20 4c 52 55  ced entry in LRU
0d20: 20 6c 69 73 74 20 20 2a 2f 0a 0a 20 20 2f 2a 20   list  */..  /* 
0d30: 56 61 72 69 61 62 6c 65 73 20 72 65 6c 61 74 65  Variables relate
0d40: 64 20 74 6f 20 53 51 4c 49 54 45 5f 43 4f 4e 46  d to SQLITE_CONF
0d50: 49 47 5f 50 41 47 45 43 41 43 48 45 20 73 65 74  IG_PAGECACHE set
0d60: 74 69 6e 67 73 2e 20 2a 2f 0a 20 20 69 6e 74 20  tings. */.  int 
0d70: 73 7a 53 6c 6f 74 3b 20 20 20 20 20 20 20 20 20  szSlot;         
0d80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0d90: 2f 2a 20 53 69 7a 65 20 6f 66 20 65 61 63 68 20  /* Size of each 
0da0: 66 72 65 65 20 73 6c 6f 74 20 2a 2f 0a 20 20 76  free slot */.  v
0db0: 6f 69 64 20 2a 70 53 74 61 72 74 2c 20 2a 70 45  oid *pStart, *pE
0dc0: 6e 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  nd;             
0dd0: 20 20 20 2f 2a 20 42 6f 75 6e 64 73 20 6f 66 20     /* Bounds of 
0de0: 70 61 67 65 63 61 63 68 65 20 6d 61 6c 6c 6f 63  pagecache malloc
0df0: 20 72 61 6e 67 65 20 2a 2f 0a 20 20 50 67 46 72   range */.  PgFr
0e00: 65 65 73 6c 6f 74 20 2a 70 46 72 65 65 3b 20 20  eeslot *pFree;  
0e10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e20: 2f 2a 20 46 72 65 65 20 70 61 67 65 20 62 6c 6f  /* Free page blo
0e30: 63 6b 73 20 2a 2f 0a 7d 20 70 63 61 63 68 65 20  cks */.} pcache 
0e40: 3d 20 7b 30 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41 6c  = {0};../*.** Al
0e50: 6c 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c  l global variabl
0e60: 65 73 20 75 73 65 64 20 62 79 20 74 68 69 73 20  es used by this 
0e70: 6d 6f 64 75 6c 65 20 28 6d 6f 73 74 20 6f 66 20  module (most of 
0e80: 77 68 69 63 68 20 61 72 65 20 67 72 6f 75 70 65  which are groupe
0e90: 64 20 0a 2a 2a 20 74 6f 67 65 74 68 65 72 20 69  d .** together i
0ea0: 6e 20 67 6c 6f 62 61 6c 20 73 74 72 75 63 74 75  n global structu
0eb0: 72 65 20 22 70 63 61 63 68 65 22 20 61 62 6f 76  re "pcache" abov
0ec0: 65 29 20 65 78 63 65 70 74 20 74 68 65 20 6c 69  e) except the li
0ed0: 73 74 20 6f 66 20 61 6c 6c 0a 2a 2a 20 70 61 67  st of all.** pag
0ee0: 65 72 2d 63 61 63 68 65 73 20 73 74 61 72 74 69  er-caches starti
0ef0: 6e 67 20 77 69 74 68 20 70 63 61 63 68 65 2e 70  ng with pcache.p
0f00: 41 6c 6c 2c 20 61 72 65 20 70 72 6f 74 65 63 74  All, are protect
0f10: 65 64 20 62 79 20 74 68 65 20 73 74 61 74 69 63  ed by the static
0f20: 20 0a 2a 2a 20 53 51 4c 49 54 45 5f 4d 55 54 45   .** SQLITE_MUTE
0f30: 58 5f 53 54 41 54 49 43 5f 4c 52 55 20 6d 75 74  X_STATIC_LRU mut
0f40: 65 78 2e 20 41 20 70 6f 69 6e 74 65 72 20 74 6f  ex. A pointer to
0f50: 20 74 68 69 73 20 6d 75 74 65 78 20 69 73 20 73   this mutex is s
0f60: 74 6f 72 65 64 20 69 6e 0a 2a 2a 20 76 61 72 69  tored in.** vari
0f70: 61 62 6c 65 20 22 70 63 61 63 68 65 2e 6d 75 74  able "pcache.mut
0f80: 65 78 5f 6c 72 75 22 2e 0a 2a 2a 0a 2a 2a 20 41  ex_lru"..**.** A
0f90: 63 63 65 73 73 20 74 6f 20 74 68 65 20 63 6f 6e  ccess to the con
0fa0: 74 65 6e 74 73 20 6f 66 20 74 68 65 20 69 6e 64  tents of the ind
0fb0: 69 76 69 64 75 61 6c 20 50 43 61 63 68 65 20 73  ividual PCache s
0fc0: 74 72 75 63 74 75 72 65 73 20 69 73 20 6e 6f 74  tructures is not
0fd0: 20 0a 2a 2a 20 70 72 6f 74 65 63 74 65 64 2e 20   .** protected. 
0fe0: 49 74 20 69 73 20 74 68 65 20 6a 6f 62 20 6f 66  It is the job of
0ff0: 20 74 68 65 20 63 61 6c 6c 65 72 20 74 6f 20 65   the caller to e
1000: 6e 73 75 72 65 20 74 68 61 74 20 74 68 65 73 65  nsure that these
1010: 20 73 74 72 75 63 74 75 72 65 73 0a 2a 2a 20 61   structures.** a
1020: 72 65 20 61 63 63 65 73 73 65 64 20 69 6e 20 61  re accessed in a
1030: 20 74 68 72 65 61 64 2d 73 61 66 65 20 6d 61 6e   thread-safe man
1040: 6e 65 72 2e 20 48 6f 77 65 76 65 72 2c 20 74 68  ner. However, th
1050: 69 73 20 6d 6f 64 75 6c 65 20 70 72 6f 76 69 64  is module provid
1060: 65 73 20 74 68 65 0a 2a 2a 20 66 75 6e 63 74 69  es the.** functi
1070: 6f 6e 73 20 73 71 6c 69 74 65 33 50 63 61 63 68  ons sqlite3Pcach
1080: 65 4c 6f 63 6b 28 29 20 61 6e 64 20 73 71 6c 69  eLock() and sqli
1090: 74 65 33 50 63 61 63 68 65 55 6e 6c 6f 63 6b 28  te3PcacheUnlock(
10a0: 29 20 74 68 61 74 20 6d 61 79 20 62 65 20 75 73  ) that may be us
10b0: 65 64 0a 2a 2a 20 62 79 20 74 68 65 20 63 61 6c  ed.** by the cal
10c0: 6c 65 72 20 74 6f 20 69 6e 63 72 65 6d 65 6e 74  ler to increment
10d0: 2f 64 65 63 72 65 6d 65 6e 74 20 61 20 6c 6f 63  /decrement a loc
10e0: 6b 2d 63 6f 75 6e 74 20 6f 6e 20 61 6e 20 69 6e  k-count on an in
10f0: 64 69 76 69 64 75 61 6c 20 0a 2a 2a 20 70 61 67  dividual .** pag
1100: 65 72 2d 63 61 63 68 65 20 6f 62 6a 65 63 74 2e  er-cache object.
1110: 20 54 68 69 73 20 6d 6f 64 75 6c 65 20 67 75 61   This module gua
1120: 72 61 6e 74 65 65 73 20 74 68 61 74 20 74 68 65  rantees that the
1130: 20 78 53 74 72 65 73 73 28 29 20 63 61 6c 6c 62   xStress() callb
1140: 61 63 6b 0a 2a 2a 20 77 69 6c 6c 20 6e 6f 74 20  ack.** will not 
1150: 62 65 20 69 6e 76 6f 6b 65 64 20 6f 6e 20 61 20  be invoked on a 
1160: 70 61 67 65 72 2d 63 61 63 68 65 20 77 69 74 68  pager-cache with
1170: 20 61 20 6e 6f 6e 2d 7a 65 72 6f 20 6c 6f 63 6b   a non-zero lock
1180: 2d 63 6f 75 6e 74 20 65 78 63 65 70 74 0a 2a 2a  -count except.**
1190: 20 66 72 6f 6d 20 77 69 74 68 69 6e 20 61 20 63   from within a c
11a0: 61 6c 6c 20 74 6f 20 73 71 6c 69 74 65 33 50 63  all to sqlite3Pc
11b0: 61 63 68 65 46 65 74 63 68 28 29 20 6f 6e 20 74  acheFetch() on t
11c0: 68 65 20 73 61 6d 65 20 70 61 67 65 72 2e 20 41  he same pager. A
11d0: 20 63 61 6c 6c 0a 2a 2a 20 74 6f 20 73 71 6c 69   call.** to sqli
11e0: 74 65 33 50 63 61 63 68 65 4c 6f 63 6b 28 29 20  te3PcacheLock() 
11f0: 6d 61 79 20 62 6c 6f 63 6b 20 69 66 20 73 75 63  may block if suc
1200: 68 20 61 6e 20 78 53 74 72 65 73 73 28 29 20 63  h an xStress() c
1210: 61 6c 6c 20 69 73 20 63 75 72 72 65 6e 74 6c 79  all is currently
1220: 20 0a 2a 2a 20 75 6e 64 65 72 77 61 79 2e 0a 2a   .** underway..*
1230: 2a 0a 2a 2a 20 42 65 66 6f 72 65 20 74 68 65 20  *.** Before the 
1240: 78 53 74 72 65 73 73 20 63 61 6c 6c 62 61 63 6b  xStress callback
1250: 20 6f 66 20 61 20 70 61 67 65 72 2d 63 61 63 68   of a pager-cach
1260: 65 20 28 50 43 61 63 68 65 29 20 69 73 20 69 6e  e (PCache) is in
1270: 76 6f 6b 65 64 2c 20 74 68 65 0a 2a 2a 20 53 51  voked, the.** SQ
1280: 4c 49 54 45 5f 4d 55 54 45 58 5f 53 54 41 54 49  LITE_MUTEX_STATI
1290: 43 5f 4d 45 4d 32 20 6d 75 74 65 78 20 69 73 20  C_MEM2 mutex is 
12a0: 6f 62 74 61 69 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20  obtained..**.** 
12b0: 44 65 61 64 6c 6f 63 6b 20 77 69 74 68 69 6e 20  Deadlock within 
12c0: 74 68 65 20 6d 6f 64 75 6c 65 20 69 73 20 61 76  the module is av
12d0: 6f 69 64 65 64 20 62 79 20 6e 65 76 65 72 20 62  oided by never b
12e0: 6c 6f 63 6b 69 6e 67 20 6f 6e 20 74 68 65 20 4d  locking on the M
12f0: 45 4d 32 20 0a 2a 2a 20 6d 75 74 65 78 20 77 68  EM2 .** mutex wh
1300: 69 6c 65 20 74 68 65 20 4c 52 55 20 6d 75 74 65  ile the LRU mute
1310: 78 20 69 73 20 68 65 6c 64 2e 0a 2a 2f 0a 0a 23  x is held..*/..#
1320: 64 65 66 69 6e 65 20 70 63 61 63 68 65 45 6e 74  define pcacheEnt
1330: 65 72 47 6c 6f 62 61 6c 28 29 20 73 71 6c 69 74  erGlobal() sqlit
1340: 65 33 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28 70  e3_mutex_enter(p
1350: 63 61 63 68 65 2e 6d 75 74 65 78 5f 6c 72 75 29  cache.mutex_lru)
1360: 0a 23 64 65 66 69 6e 65 20 70 63 61 63 68 65 45  .#define pcacheE
1370: 78 69 74 47 6c 6f 62 61 6c 28 29 20 20 73 71 6c  xitGlobal()  sql
1380: 69 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65  ite3_mutex_leave
1390: 28 70 63 61 63 68 65 2e 6d 75 74 65 78 5f 6c 72  (pcache.mutex_lr
13a0: 75 29 0a 0a 2f 2a 0a 2a 2a 20 49 6e 63 72 65 6d  u)../*.** Increm
13b0: 65 6e 74 20 74 68 65 20 72 65 66 65 72 65 6e 63  ent the referenc
13c0: 65 20 63 6f 75 6e 74 20 6f 6e 20 62 6f 74 68 20  e count on both 
13d0: 70 61 67 65 20 70 20 61 6e 64 20 69 74 73 20 63  page p and its c
13e0: 61 63 68 65 20 62 79 20 6e 2e 0a 2a 2f 0a 73 74  ache by n..*/.st
13f0: 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65  atic void pcache
1400: 52 65 66 28 50 67 48 64 72 20 2a 70 2c 20 69 6e  Ref(PgHdr *p, in
1410: 74 20 6e 29 7b 0a 20 20 2f 2a 20 54 68 69 73 20  t n){.  /* This 
1420: 6e 65 78 74 20 62 6c 6f 63 6b 20 61 73 73 65 72  next block asser
1430: 74 28 29 73 20 74 68 61 74 20 74 68 65 20 6e 75  t()s that the nu
1440: 6d 62 65 72 20 6f 66 20 72 65 66 65 72 65 6e 63  mber of referenc
1450: 65 73 20 74 6f 20 74 68 65 20 0a 20 20 2a 2a 20  es to the .  ** 
1460: 50 43 61 63 68 65 20 69 73 20 74 68 65 20 73 75  PCache is the su
1470: 6d 20 6f 66 20 74 68 65 20 6e 75 6d 62 65 72 20  m of the number 
1480: 6f 66 20 72 65 66 65 72 65 6e 63 65 73 20 74 6f  of references to
1490: 20 61 6c 6c 20 70 61 67 65 73 20 69 6e 0a 20 20   all pages in.  
14a0: 2a 2a 20 74 68 65 20 50 43 61 63 68 65 2e 20 54  ** the PCache. T
14b0: 68 69 73 20 69 73 20 61 20 62 69 74 20 65 78 70  his is a bit exp
14c0: 65 6e 73 69 76 65 20 74 6f 20 6c 65 61 76 65 20  ensive to leave 
14d0: 74 75 72 6e 65 64 20 6f 6e 20 61 6c 6c 20 74 68  turned on all th
14e0: 65 20 0a 20 20 2a 2a 20 74 69 6d 65 2c 20 65 76  e .  ** time, ev
14f0: 65 6e 20 69 6e 20 64 65 62 75 67 67 69 6e 67 20  en in debugging 
1500: 62 75 69 6c 64 73 2e 0a 20 20 2a 2f 0a 23 69 66  builds..  */.#if
1510: 20 30 0a 20 20 50 67 48 64 72 20 2a 70 48 64 72   0.  PgHdr *pHdr
1520: 3b 0a 20 20 69 6e 74 20 6e 52 65 66 20 3d 20 30  ;.  int nRef = 0
1530: 3b 0a 20 20 66 6f 72 28 70 48 64 72 3d 70 2d 3e  ;.  for(pHdr=p->
1540: 70 43 61 63 68 65 2d 3e 70 43 6c 65 61 6e 3b 20  pCache->pClean; 
1550: 70 48 64 72 3b 20 70 48 64 72 3d 70 48 64 72 2d  pHdr; pHdr=pHdr-
1560: 3e 70 4e 65 78 74 29 20 6e 52 65 66 20 2b 3d 20  >pNext) nRef += 
1570: 70 48 64 72 2d 3e 6e 52 65 66 3b 0a 20 20 66 6f  pHdr->nRef;.  fo
1580: 72 28 70 48 64 72 3d 70 2d 3e 70 43 61 63 68 65  r(pHdr=p->pCache
1590: 2d 3e 70 44 69 72 74 79 3b 20 70 48 64 72 3b 20  ->pDirty; pHdr; 
15a0: 70 48 64 72 3d 70 48 64 72 2d 3e 70 4e 65 78 74  pHdr=pHdr->pNext
15b0: 29 20 6e 52 65 66 20 2b 3d 20 70 48 64 72 2d 3e  ) nRef += pHdr->
15c0: 6e 52 65 66 3b 0a 20 20 61 73 73 65 72 74 28 20  nRef;.  assert( 
15d0: 70 2d 3e 70 43 61 63 68 65 2d 3e 6e 52 65 66 3d  p->pCache->nRef=
15e0: 3d 6e 52 65 66 20 29 3b 0a 23 65 6e 64 69 66 0a  =nRef );.#endif.
15f0: 20 20 70 2d 3e 6e 52 65 66 20 2b 3d 20 6e 3b 0a    p->nRef += n;.
1600: 20 20 70 2d 3e 70 43 61 63 68 65 2d 3e 6e 52 65    p->pCache->nRe
1610: 66 20 2b 3d 20 6e 3b 0a 7d 0a 0a 2f 2a 2a 2a 2a  f += n;.}../****
1620: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1630: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 4c  ************** L
1640: 69 6e 6b 65 64 20 4c 69 73 74 20 4d 61 6e 61 67  inked List Manag
1650: 65 6d 65 6e 74 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ement **********
1660: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 23 69 66  **********/..#if
1670: 6e 64 65 66 20 4e 44 45 42 55 47 0a 2f 2a 0a 2a  ndef NDEBUG./*.*
1680: 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 76  * This routine v
1690: 65 72 69 66 69 65 73 20 74 68 61 74 20 74 68 65  erifies that the
16a0: 20 6e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72 69   number of entri
16b0: 65 73 20 69 6e 20 74 68 65 20 68 61 73 68 20 74  es in the hash t
16c0: 61 62 6c 65 0a 2a 2a 20 69 73 20 70 43 61 63 68  able.** is pCach
16d0: 65 2d 3e 6e 50 61 67 65 2e 20 20 54 68 69 73 20  e->nPage.  This 
16e0: 72 6f 75 74 69 6e 65 20 69 73 20 75 73 65 64 20  routine is used 
16f0: 77 69 74 68 69 6e 20 61 73 73 65 72 74 28 29 20  within assert() 
1700: 73 74 61 74 65 6d 65 6e 74 73 0a 2a 2a 20 6f 6e  statements.** on
1710: 6c 79 20 61 6e 64 20 69 73 20 74 68 65 72 65 66  ly and is theref
1720: 6f 72 65 20 64 69 73 61 62 6c 65 64 20 64 75 72  ore disabled dur
1730: 69 6e 67 20 70 72 6f 64 75 63 74 69 6f 6e 20 62  ing production b
1740: 75 69 6c 64 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  uilds..*/.static
1750: 20 69 6e 74 20 70 63 61 63 68 65 43 68 65 63 6b   int pcacheCheck
1760: 48 61 73 68 43 6f 75 6e 74 28 50 43 61 63 68 65  HashCount(PCache
1770: 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 69 6e 74   *pCache){.  int
1780: 20 69 3b 0a 20 20 69 6e 74 20 6e 50 61 67 65 20   i;.  int nPage 
1790: 3d 20 30 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20  = 0;.  for(i=0; 
17a0: 69 3c 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3b  i<pCache->nHash;
17b0: 20 69 2b 2b 29 7b 0a 20 20 20 20 50 67 48 64 72   i++){.    PgHdr
17c0: 20 2a 70 3b 0a 20 20 20 20 66 6f 72 28 70 3d 70   *p;.    for(p=p
17d0: 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 69 5d  Cache->apHash[i]
17e0: 3b 20 70 3b 20 70 3d 70 2d 3e 70 4e 65 78 74 48  ; p; p=p->pNextH
17f0: 61 73 68 29 7b 0a 20 20 20 20 20 20 6e 50 61 67  ash){.      nPag
1800: 65 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  e++;.    }.  }. 
1810: 20 61 73 73 65 72 74 28 20 6e 50 61 67 65 3d 3d   assert( nPage==
1820: 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 20 29 3b  pCache->nPage );
1830: 0a 20 20 72 65 74 75 72 6e 20 31 3b 0a 7d 0a 23  .  return 1;.}.#
1840: 65 6e 64 69 66 0a 0a 2f 2a 0a 2a 2a 20 52 65 6d  endif../*.** Rem
1850: 6f 76 65 20 61 20 70 61 67 65 20 66 72 6f 6d 20  ove a page from 
1860: 69 74 73 20 68 61 73 68 20 74 61 62 6c 65 20 28  its hash table (
1870: 50 43 61 63 68 65 2e 61 70 48 61 73 68 5b 5d 29  PCache.apHash[])
1880: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
1890: 20 70 63 61 63 68 65 52 65 6d 6f 76 65 46 72 6f   pcacheRemoveFro
18a0: 6d 48 61 73 68 28 50 67 48 64 72 20 2a 70 50 61  mHash(PgHdr *pPa
18b0: 67 65 29 7b 0a 20 20 69 66 28 20 70 50 61 67 65  ge){.  if( pPage
18c0: 2d 3e 70 50 72 65 76 48 61 73 68 20 29 7b 0a 20  ->pPrevHash ){. 
18d0: 20 20 20 70 50 61 67 65 2d 3e 70 50 72 65 76 48     pPage->pPrevH
18e0: 61 73 68 2d 3e 70 4e 65 78 74 48 61 73 68 20 3d  ash->pNextHash =
18f0: 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 48 61 73   pPage->pNextHas
1900: 68 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  h;.  }else{.    
1910: 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 20 3d  PCache *pCache =
1920: 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65 3b 0a   pPage->pCache;.
1930: 20 20 20 20 75 33 32 20 68 20 3d 20 70 50 61 67      u32 h = pPag
1940: 65 2d 3e 70 67 6e 6f 20 25 20 70 43 61 63 68 65  e->pgno % pCache
1950: 2d 3e 6e 48 61 73 68 3b 0a 20 20 20 20 61 73 73  ->nHash;.    ass
1960: 65 72 74 28 20 70 43 61 63 68 65 2d 3e 61 70 48  ert( pCache->apH
1970: 61 73 68 5b 68 5d 3d 3d 70 50 61 67 65 20 29 3b  ash[h]==pPage );
1980: 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 61 70 48  .    pCache->apH
1990: 61 73 68 5b 68 5d 20 3d 20 70 50 61 67 65 2d 3e  ash[h] = pPage->
19a0: 70 4e 65 78 74 48 61 73 68 3b 0a 20 20 7d 0a 20  pNextHash;.  }. 
19b0: 20 69 66 28 20 70 50 61 67 65 2d 3e 70 4e 65 78   if( pPage->pNex
19c0: 74 48 61 73 68 20 29 7b 0a 20 20 20 20 70 50 61  tHash ){.    pPa
19d0: 67 65 2d 3e 70 4e 65 78 74 48 61 73 68 2d 3e 70  ge->pNextHash->p
19e0: 50 72 65 76 48 61 73 68 20 3d 20 70 50 61 67 65  PrevHash = pPage
19f0: 2d 3e 70 50 72 65 76 48 61 73 68 3b 0a 20 20 7d  ->pPrevHash;.  }
1a00: 0a 20 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65  .  pPage->pCache
1a10: 2d 3e 6e 50 61 67 65 2d 2d 3b 0a 20 20 61 73 73  ->nPage--;.  ass
1a20: 65 72 74 28 20 70 63 61 63 68 65 43 68 65 63 6b  ert( pcacheCheck
1a30: 48 61 73 68 43 6f 75 6e 74 28 70 50 61 67 65 2d  HashCount(pPage-
1a40: 3e 70 43 61 63 68 65 29 20 29 3b 0a 7d 0a 0a 2f  >pCache) );.}../
1a50: 2a 0a 2a 2a 20 49 6e 73 65 72 74 20 61 20 70 61  *.** Insert a pa
1a60: 67 65 20 69 6e 74 6f 20 74 68 65 20 68 61 73 68  ge into the hash
1a70: 20 74 61 62 6c 65 0a 2a 2f 0a 73 74 61 74 69 63   table.*/.static
1a80: 20 76 6f 69 64 20 70 63 61 63 68 65 41 64 64 54   void pcacheAddT
1a90: 6f 48 61 73 68 28 50 67 48 64 72 20 2a 70 50 61  oHash(PgHdr *pPa
1aa0: 67 65 29 7b 0a 20 20 50 43 61 63 68 65 20 2a 70  ge){.  PCache *p
1ab0: 43 61 63 68 65 20 3d 20 70 50 61 67 65 2d 3e 70  Cache = pPage->p
1ac0: 43 61 63 68 65 3b 0a 20 20 75 33 32 20 68 20 3d  Cache;.  u32 h =
1ad0: 20 70 50 61 67 65 2d 3e 70 67 6e 6f 20 25 20 70   pPage->pgno % p
1ae0: 43 61 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20  Cache->nHash;.  
1af0: 70 50 61 67 65 2d 3e 70 4e 65 78 74 48 61 73 68  pPage->pNextHash
1b00: 20 3d 20 70 43 61 63 68 65 2d 3e 61 70 48 61 73   = pCache->apHas
1b10: 68 5b 68 5d 3b 0a 20 20 70 50 61 67 65 2d 3e 70  h[h];.  pPage->p
1b20: 50 72 65 76 48 61 73 68 20 3d 20 30 3b 0a 20 20  PrevHash = 0;.  
1b30: 69 66 28 20 70 43 61 63 68 65 2d 3e 61 70 48 61  if( pCache->apHa
1b40: 73 68 5b 68 5d 20 29 7b 0a 20 20 20 20 70 43 61  sh[h] ){.    pCa
1b50: 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 2d 3e  che->apHash[h]->
1b60: 70 50 72 65 76 48 61 73 68 20 3d 20 70 50 61 67  pPrevHash = pPag
1b70: 65 3b 0a 20 20 7d 0a 20 20 70 43 61 63 68 65 2d  e;.  }.  pCache-
1b80: 3e 61 70 48 61 73 68 5b 68 5d 20 3d 20 70 50 61  >apHash[h] = pPa
1b90: 67 65 3b 0a 20 20 70 43 61 63 68 65 2d 3e 6e 50  ge;.  pCache->nP
1ba0: 61 67 65 2b 2b 3b 0a 20 20 61 73 73 65 72 74 28  age++;.  assert(
1bb0: 20 70 63 61 63 68 65 43 68 65 63 6b 48 61 73 68   pcacheCheckHash
1bc0: 43 6f 75 6e 74 28 70 43 61 63 68 65 29 20 29 3b  Count(pCache) );
1bd0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 74 74 65 6d 70  .}../*.** Attemp
1be0: 74 20 74 6f 20 69 6e 63 72 65 61 73 65 20 74 68  t to increase th
1bf0: 65 20 73 69 7a 65 20 74 68 65 20 68 61 73 68 20  e size the hash 
1c00: 74 61 62 6c 65 20 74 6f 20 63 6f 6e 74 61 69 6e  table to contain
1c10: 0a 2a 2a 20 61 74 20 6c 65 61 73 74 20 6e 48 61  .** at least nHa
1c20: 73 68 20 62 75 63 6b 65 74 73 2e 0a 2a 2f 0a 73  sh buckets..*/.s
1c30: 74 61 74 69 63 20 69 6e 74 20 70 63 61 63 68 65  tatic int pcache
1c40: 52 65 73 69 7a 65 48 61 73 68 28 50 43 61 63 68  ResizeHash(PCach
1c50: 65 20 2a 70 43 61 63 68 65 2c 20 69 6e 74 20 6e  e *pCache, int n
1c60: 48 61 73 68 29 7b 0a 23 69 66 64 65 66 20 53 51  Hash){.#ifdef SQ
1c70: 4c 49 54 45 5f 4d 41 4c 4c 4f 43 5f 53 4f 46 54  LITE_MALLOC_SOFT
1c80: 5f 4c 49 4d 49 54 0a 20 20 69 66 28 20 6e 48 61  _LIMIT.  if( nHa
1c90: 73 68 2a 73 69 7a 65 6f 66 28 50 67 48 64 72 2a  sh*sizeof(PgHdr*
1ca0: 29 3e 53 51 4c 49 54 45 5f 4d 41 4c 4c 4f 43 5f  )>SQLITE_MALLOC_
1cb0: 53 4f 46 54 5f 4c 49 4d 49 54 20 29 7b 0a 20 20  SOFT_LIMIT ){.  
1cc0: 20 20 6e 48 61 73 68 20 3d 20 53 51 4c 49 54 45    nHash = SQLITE
1cd0: 5f 4d 41 4c 4c 4f 43 5f 53 4f 46 54 5f 4c 49 4d  _MALLOC_SOFT_LIM
1ce0: 49 54 2f 73 69 7a 65 6f 66 28 50 67 48 64 72 20  IT/sizeof(PgHdr 
1cf0: 2a 29 3b 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 20  *);.  }.#endif. 
1d00: 20 69 66 28 20 6e 48 61 73 68 3e 70 43 61 63 68   if( nHash>pCach
1d10: 65 2d 3e 6e 48 61 73 68 20 29 7b 0a 20 20 20 20  e->nHash ){.    
1d20: 50 67 48 64 72 20 2a 70 3b 0a 20 20 20 20 50 67  PgHdr *p;.    Pg
1d30: 48 64 72 20 2a 2a 70 4e 65 77 20 3d 20 28 50 67  Hdr **pNew = (Pg
1d40: 48 64 72 20 2a 2a 29 73 71 6c 69 74 65 33 5f 6d  Hdr **)sqlite3_m
1d50: 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 50 67 48  alloc(sizeof(PgH
1d60: 64 72 2a 29 2a 6e 48 61 73 68 29 3b 0a 20 20 20  dr*)*nHash);.   
1d70: 20 69 66 28 20 21 70 4e 65 77 20 29 7b 0a 20 20   if( !pNew ){.  
1d80: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
1d90: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20  E_NOMEM;.    }. 
1da0: 20 20 20 6d 65 6d 73 65 74 28 70 4e 65 77 2c 20     memset(pNew, 
1db0: 30 2c 20 73 69 7a 65 6f 66 28 50 67 48 64 72 20  0, sizeof(PgHdr 
1dc0: 2a 29 2a 6e 48 61 73 68 29 3b 0a 20 20 20 20 73  *)*nHash);.    s
1dd0: 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43 61 63  qlite3_free(pCac
1de0: 68 65 2d 3e 61 70 48 61 73 68 29 3b 0a 20 20 20  he->apHash);.   
1df0: 20 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 20   pCache->apHash 
1e00: 3d 20 70 4e 65 77 3b 0a 20 20 20 20 70 43 61 63  = pNew;.    pCac
1e10: 68 65 2d 3e 6e 48 61 73 68 20 3d 20 6e 48 61 73  he->nHash = nHas
1e20: 68 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 6e  h;.    pCache->n
1e30: 50 61 67 65 20 3d 20 30 3b 0a 20 20 20 0a 20 20  Page = 0;.   .  
1e40: 20 20 66 6f 72 28 70 3d 70 43 61 63 68 65 2d 3e    for(p=pCache->
1e50: 70 43 6c 65 61 6e 3b 20 70 3b 20 70 3d 70 2d 3e  pClean; p; p=p->
1e60: 70 4e 65 78 74 29 7b 0a 20 20 20 20 20 20 70 63  pNext){.      pc
1e70: 61 63 68 65 41 64 64 54 6f 48 61 73 68 28 70 29  acheAddToHash(p)
1e80: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 66 6f 72 28  ;.    }.    for(
1e90: 70 3d 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79  p=pCache->pDirty
1ea0: 3b 20 70 3b 20 70 3d 70 2d 3e 70 4e 65 78 74 29  ; p; p=p->pNext)
1eb0: 7b 0a 20 20 20 20 20 20 70 63 61 63 68 65 41 64  {.      pcacheAd
1ec0: 64 54 6f 48 61 73 68 28 70 29 3b 0a 20 20 20 20  dToHash(p);.    
1ed0: 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 53  }.  }.  return S
1ee0: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  QLITE_OK;.}../*.
1ef0: 2a 2a 20 52 65 6d 6f 76 65 20 61 20 70 61 67 65  ** Remove a page
1f00: 20 66 72 6f 6d 20 61 20 6c 69 6e 6b 65 64 20 6c   from a linked l
1f10: 69 73 74 20 74 68 61 74 20 69 73 20 68 65 61 64  ist that is head
1f20: 65 64 20 62 79 20 2a 70 70 48 65 61 64 2e 0a 2a  ed by *ppHead..*
1f30: 2a 20 2a 70 70 48 65 61 64 20 69 73 20 65 69 74  * *ppHead is eit
1f40: 68 65 72 20 50 43 61 63 68 65 2e 70 43 6c 65 61  her PCache.pClea
1f50: 6e 20 6f 72 20 50 43 61 63 68 65 2e 70 44 69 72  n or PCache.pDir
1f60: 74 79 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ty..*/.static vo
1f70: 69 64 20 70 63 61 63 68 65 52 65 6d 6f 76 65 46  id pcacheRemoveF
1f80: 72 6f 6d 4c 69 73 74 28 50 67 48 64 72 20 2a 2a  romList(PgHdr **
1f90: 70 70 48 65 61 64 2c 20 50 67 48 64 72 20 2a 70  ppHead, PgHdr *p
1fa0: 50 61 67 65 29 7b 0a 20 20 69 66 28 20 70 50 61  Page){.  if( pPa
1fb0: 67 65 2d 3e 70 50 72 65 76 20 29 7b 0a 20 20 20  ge->pPrev ){.   
1fc0: 20 70 50 61 67 65 2d 3e 70 50 72 65 76 2d 3e 70   pPage->pPrev->p
1fd0: 4e 65 78 74 20 3d 20 70 50 61 67 65 2d 3e 70 4e  Next = pPage->pN
1fe0: 65 78 74 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  ext;.  }else{.  
1ff0: 20 20 61 73 73 65 72 74 28 20 2a 70 70 48 65 61    assert( *ppHea
2000: 64 3d 3d 70 50 61 67 65 20 29 3b 0a 20 20 20 20  d==pPage );.    
2010: 2a 70 70 48 65 61 64 20 3d 20 70 50 61 67 65 2d  *ppHead = pPage-
2020: 3e 70 4e 65 78 74 3b 0a 20 20 7d 0a 20 20 69 66  >pNext;.  }.  if
2030: 28 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 20 29  ( pPage->pNext )
2040: 7b 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 4e 65  {.    pPage->pNe
2050: 78 74 2d 3e 70 50 72 65 76 20 3d 20 70 50 61 67  xt->pPrev = pPag
2060: 65 2d 3e 70 50 72 65 76 3b 0a 20 20 7d 0a 7d 0a  e->pPrev;.  }.}.
2070: 0a 2f 2a 0a 2a 2a 20 41 64 64 20 61 20 70 61 67  ./*.** Add a pag
2080: 65 20 66 72 6f 6d 20 61 20 6c 69 6e 6b 65 64 20  e from a linked 
2090: 6c 69 73 74 20 74 68 61 74 20 69 73 20 68 65 61  list that is hea
20a0: 64 65 64 20 62 79 20 2a 70 70 48 65 61 64 2e 0a  ded by *ppHead..
20b0: 2a 2a 20 2a 70 70 48 65 61 64 20 69 73 20 65 69  ** *ppHead is ei
20c0: 74 68 65 72 20 50 43 61 63 68 65 2e 70 43 6c 65  ther PCache.pCle
20d0: 61 6e 20 6f 72 20 50 43 61 63 68 65 2e 70 44 69  an or PCache.pDi
20e0: 72 74 79 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  rty..*/.static v
20f0: 6f 69 64 20 70 63 61 63 68 65 41 64 64 54 6f 4c  oid pcacheAddToL
2100: 69 73 74 28 50 67 48 64 72 20 2a 2a 70 70 48 65  ist(PgHdr **ppHe
2110: 61 64 2c 20 50 67 48 64 72 20 2a 70 50 61 67 65  ad, PgHdr *pPage
2120: 29 7b 0a 20 20 69 66 28 20 28 2a 70 70 48 65 61  ){.  if( (*ppHea
2130: 64 29 20 29 7b 0a 20 20 20 20 28 2a 70 70 48 65  d) ){.    (*ppHe
2140: 61 64 29 2d 3e 70 50 72 65 76 20 3d 20 70 50 61  ad)->pPrev = pPa
2150: 67 65 3b 0a 20 20 7d 0a 20 20 70 50 61 67 65 2d  ge;.  }.  pPage-
2160: 3e 70 4e 65 78 74 20 3d 20 2a 70 70 48 65 61 64  >pNext = *ppHead
2170: 3b 0a 20 20 70 50 61 67 65 2d 3e 70 50 72 65 76  ;.  pPage->pPrev
2180: 20 3d 20 30 3b 0a 20 20 2a 70 70 48 65 61 64 20   = 0;.  *ppHead 
2190: 3d 20 70 50 61 67 65 3b 0a 7d 0a 0a 2f 2a 0a 2a  = pPage;.}../*.*
21a0: 2a 20 52 65 6d 6f 76 65 20 61 20 70 61 67 65 20  * Remove a page 
21b0: 66 72 6f 6d 20 74 68 65 20 67 6c 6f 62 61 6c 20  from the global 
21c0: 4c 52 55 20 6c 69 73 74 0a 2a 2f 0a 73 74 61 74  LRU list.*/.stat
21d0: 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 52 65  ic void pcacheRe
21e0: 6d 6f 76 65 46 72 6f 6d 4c 72 75 4c 69 73 74 28  moveFromLruList(
21f0: 50 67 48 64 72 20 2a 70 50 61 67 65 29 7b 0a 20  PgHdr *pPage){. 
2200: 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33   assert( sqlite3
2210: 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 63 61 63  _mutex_held(pcac
2220: 68 65 2e 6d 75 74 65 78 5f 6c 72 75 29 20 29 3b  he.mutex_lru) );
2230: 0a 20 20 69 66 28 20 70 50 61 67 65 2d 3e 70 43  .  if( pPage->pC
2240: 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65  ache->bPurgeable
2250: 3d 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a 20 20  ==0 ) return;.  
2260: 69 66 28 20 70 50 61 67 65 3d 3d 70 63 61 63 68  if( pPage==pcach
2270: 65 2e 70 4c 72 75 53 79 6e 63 65 64 20 29 7b 0a  e.pLruSynced ){.
2280: 20 20 20 20 50 67 48 64 72 20 2a 70 3b 0a 20 20      PgHdr *p;.  
2290: 20 20 66 6f 72 28 70 3d 70 50 61 67 65 2d 3e 70    for(p=pPage->p
22a0: 50 72 65 76 4c 72 75 3b 20 70 20 26 26 20 28 70  PrevLru; p && (p
22b0: 2d 3e 66 6c 61 67 73 26 50 47 48 44 52 5f 4e 45  ->flags&PGHDR_NE
22c0: 45 44 5f 53 59 4e 43 29 3b 20 70 3d 70 2d 3e 70  ED_SYNC); p=p->p
22d0: 50 72 65 76 4c 72 75 29 3b 0a 20 20 20 20 70 63  PrevLru);.    pc
22e0: 61 63 68 65 2e 70 4c 72 75 53 79 6e 63 65 64 20  ache.pLruSynced 
22f0: 3d 20 70 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70  = p;.  }.  if( p
2300: 50 61 67 65 2d 3e 70 4e 65 78 74 4c 72 75 20 29  Page->pNextLru )
2310: 7b 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 4e 65  {.    pPage->pNe
2320: 78 74 4c 72 75 2d 3e 70 50 72 65 76 4c 72 75 20  xtLru->pPrevLru 
2330: 3d 20 70 50 61 67 65 2d 3e 70 50 72 65 76 4c 72  = pPage->pPrevLr
2340: 75 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  u;.  }else{.    
2350: 61 73 73 65 72 74 28 20 70 63 61 63 68 65 2e 70  assert( pcache.p
2360: 4c 72 75 54 61 69 6c 3d 3d 70 50 61 67 65 20 29  LruTail==pPage )
2370: 3b 0a 20 20 20 20 70 63 61 63 68 65 2e 70 4c 72  ;.    pcache.pLr
2380: 75 54 61 69 6c 20 3d 20 70 50 61 67 65 2d 3e 70  uTail = pPage->p
2390: 50 72 65 76 4c 72 75 3b 0a 20 20 7d 0a 20 20 69  PrevLru;.  }.  i
23a0: 66 28 20 70 50 61 67 65 2d 3e 70 50 72 65 76 4c  f( pPage->pPrevL
23b0: 72 75 20 29 7b 0a 20 20 20 20 70 50 61 67 65 2d  ru ){.    pPage-
23c0: 3e 70 50 72 65 76 4c 72 75 2d 3e 70 4e 65 78 74  >pPrevLru->pNext
23d0: 4c 72 75 20 3d 20 70 50 61 67 65 2d 3e 70 4e 65  Lru = pPage->pNe
23e0: 78 74 4c 72 75 3b 0a 20 20 7d 65 6c 73 65 7b 0a  xtLru;.  }else{.
23f0: 20 20 20 20 61 73 73 65 72 74 28 20 70 63 61 63      assert( pcac
2400: 68 65 2e 70 4c 72 75 48 65 61 64 3d 3d 70 50 61  he.pLruHead==pPa
2410: 67 65 20 29 3b 0a 20 20 20 20 70 63 61 63 68 65  ge );.    pcache
2420: 2e 70 4c 72 75 48 65 61 64 20 3d 20 70 50 61 67  .pLruHead = pPag
2430: 65 2d 3e 70 4e 65 78 74 4c 72 75 3b 0a 20 20 7d  e->pNextLru;.  }
2440: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 64 20 61 20  .}../*.** Add a 
2450: 70 61 67 65 20 74 6f 20 74 68 65 20 67 6c 6f 62  page to the glob
2460: 61 6c 20 4c 52 55 20 6c 69 73 74 2e 20 20 54 68  al LRU list.  Th
2470: 65 20 70 61 67 65 20 69 73 20 6e 6f 72 6d 61 6c  e page is normal
2480: 6c 79 20 61 64 64 65 64 0a 2a 2a 20 74 6f 20 74  ly added.** to t
2490: 68 65 20 66 72 6f 6e 74 20 6f 66 20 74 68 65 20  he front of the 
24a0: 6c 69 73 74 20 73 6f 20 74 68 61 74 20 69 74 20  list so that it 
24b0: 77 69 6c 6c 20 62 65 20 74 68 65 20 6c 61 73 74  will be the last
24c0: 20 70 61 67 65 20 72 65 63 79 63 6c 65 64 2e 0a   page recycled..
24d0: 2a 2a 20 48 6f 77 65 76 65 72 2c 20 69 66 20 74  ** However, if t
24e0: 68 65 20 50 47 48 44 52 5f 52 45 55 53 45 5f 55  he PGHDR_REUSE_U
24f0: 4e 4c 49 4b 45 4c 59 20 62 69 74 20 69 73 20 73  NLIKELY bit is s
2500: 65 74 2c 20 74 68 65 20 70 61 67 65 20 69 73 20  et, the page is 
2510: 61 64 64 65 64 0a 2a 2a 20 74 6f 20 74 68 65 20  added.** to the 
2520: 65 6e 64 20 6f 66 20 74 68 65 20 4c 52 55 20 6c  end of the LRU l
2530: 69 73 74 20 73 6f 20 74 68 61 74 20 69 74 20 77  ist so that it w
2540: 69 6c 6c 20 62 65 20 74 68 65 20 6e 65 78 74 20  ill be the next 
2550: 74 6f 20 62 65 20 72 65 63 79 63 6c 65 64 2e 0a  to be recycled..
2560: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70  */.static void p
2570: 63 61 63 68 65 41 64 64 54 6f 4c 72 75 4c 69 73  cacheAddToLruLis
2580: 74 28 50 67 48 64 72 20 2a 70 50 61 67 65 29 7b  t(PgHdr *pPage){
2590: 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74  .  assert( sqlit
25a0: 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 63  e3_mutex_held(pc
25b0: 61 63 68 65 2e 6d 75 74 65 78 5f 6c 72 75 29 20  ache.mutex_lru) 
25c0: 29 3b 0a 20 20 69 66 28 20 70 50 61 67 65 2d 3e  );.  if( pPage->
25d0: 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62  pCache->bPurgeab
25e0: 6c 65 3d 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a  le==0 ) return;.
25f0: 20 20 69 66 28 20 70 63 61 63 68 65 2e 70 4c 72    if( pcache.pLr
2600: 75 54 61 69 6c 20 26 26 20 28 70 50 61 67 65 2d  uTail && (pPage-
2610: 3e 66 6c 61 67 73 20 26 20 50 47 48 44 52 5f 52  >flags & PGHDR_R
2620: 45 55 53 45 5f 55 4e 4c 49 4b 45 4c 59 29 21 3d  EUSE_UNLIKELY)!=
2630: 30 20 29 7b 0a 20 20 20 20 2f 2a 20 49 66 20 72  0 ){.    /* If r
2640: 65 75 73 65 20 69 73 20 75 6e 6c 69 6b 65 6c 79  euse is unlikely
2650: 2e 20 20 50 75 74 20 74 68 65 20 70 61 67 65 20  .  Put the page 
2660: 61 74 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68  at the end of th
2670: 65 20 4c 52 55 20 6c 69 73 74 0a 20 20 20 20 2a  e LRU list.    *
2680: 2a 20 77 68 65 72 65 20 69 74 20 77 69 6c 6c 20  * where it will 
2690: 62 65 20 72 65 63 79 63 6c 65 64 20 73 6f 6f 6e  be recycled soon
26a0: 65 72 20 72 61 74 68 65 72 20 74 68 61 6e 20 6c  er rather than l
26b0: 61 74 65 72 2e 20 0a 20 20 20 20 2a 2f 0a 20 20  ater. .    */.  
26c0: 20 20 61 73 73 65 72 74 28 20 70 63 61 63 68 65    assert( pcache
26d0: 2e 70 4c 72 75 48 65 61 64 20 29 3b 0a 20 20 20  .pLruHead );.   
26e0: 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 4c 72 75   pPage->pNextLru
26f0: 20 3d 20 30 3b 0a 20 20 20 20 70 50 61 67 65 2d   = 0;.    pPage-
2700: 3e 70 50 72 65 76 4c 72 75 20 3d 20 70 63 61 63  >pPrevLru = pcac
2710: 68 65 2e 70 4c 72 75 54 61 69 6c 3b 0a 20 20 20  he.pLruTail;.   
2720: 20 70 63 61 63 68 65 2e 70 4c 72 75 54 61 69 6c   pcache.pLruTail
2730: 2d 3e 70 4e 65 78 74 4c 72 75 20 3d 20 70 50 61  ->pNextLru = pPa
2740: 67 65 3b 0a 20 20 20 20 70 63 61 63 68 65 2e 70  ge;.    pcache.p
2750: 4c 72 75 54 61 69 6c 20 3d 20 70 50 61 67 65 3b  LruTail = pPage;
2760: 0a 20 20 20 20 70 50 61 67 65 2d 3e 66 6c 61 67  .    pPage->flag
2770: 73 20 26 3d 20 7e 50 47 48 44 52 5f 52 45 55 53  s &= ~PGHDR_REUS
2780: 45 5f 55 4e 4c 49 4b 45 4c 59 3b 0a 20 20 20 20  E_UNLIKELY;.    
2790: 69 66 28 20 30 3d 3d 28 70 50 61 67 65 2d 3e 66  if( 0==(pPage->f
27a0: 6c 61 67 73 26 50 47 48 44 52 5f 4e 45 45 44 5f  lags&PGHDR_NEED_
27b0: 53 59 4e 43 29 20 29 7b 0a 20 20 20 20 20 20 70  SYNC) ){.      p
27c0: 63 61 63 68 65 2e 70 4c 72 75 53 79 6e 63 65 64  cache.pLruSynced
27d0: 20 3d 20 70 50 61 67 65 3b 0a 20 20 20 20 7d 0a   = pPage;.    }.
27e0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 2f 2a 20    }else{.    /* 
27f0: 49 66 20 72 65 75 73 65 20 69 73 20 70 6f 73 73  If reuse is poss
2800: 69 62 6c 65 2e 20 74 68 65 20 70 61 67 65 20 67  ible. the page g
2810: 6f 65 73 20 61 74 20 74 68 65 20 62 65 67 69 6e  oes at the begin
2820: 6e 69 6e 67 20 6f 66 20 74 68 65 20 4c 52 55 0a  ning of the LRU.
2830: 20 20 20 20 2a 2a 20 6c 69 73 74 20 73 6f 20 74      ** list so t
2840: 68 61 74 20 69 74 20 77 69 6c 6c 20 62 65 20 74  hat it will be t
2850: 68 65 20 6c 61 73 74 20 74 6f 20 62 65 20 72 65  he last to be re
2860: 63 79 63 6c 65 64 2e 0a 20 20 20 20 2a 2f 0a 20  cycled..    */. 
2870: 20 20 20 69 66 28 20 70 63 61 63 68 65 2e 70 4c     if( pcache.pL
2880: 72 75 48 65 61 64 20 29 7b 0a 20 20 20 20 20 20  ruHead ){.      
2890: 70 63 61 63 68 65 2e 70 4c 72 75 48 65 61 64 2d  pcache.pLruHead-
28a0: 3e 70 50 72 65 76 4c 72 75 20 3d 20 70 50 61 67  >pPrevLru = pPag
28b0: 65 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 50 61  e;.    }.    pPa
28c0: 67 65 2d 3e 70 4e 65 78 74 4c 72 75 20 3d 20 70  ge->pNextLru = p
28d0: 63 61 63 68 65 2e 70 4c 72 75 48 65 61 64 3b 0a  cache.pLruHead;.
28e0: 20 20 20 20 70 63 61 63 68 65 2e 70 4c 72 75 48      pcache.pLruH
28f0: 65 61 64 20 3d 20 70 50 61 67 65 3b 0a 20 20 20  ead = pPage;.   
2900: 20 70 50 61 67 65 2d 3e 70 50 72 65 76 4c 72 75   pPage->pPrevLru
2910: 20 3d 20 30 3b 0a 20 20 20 20 69 66 28 20 70 63   = 0;.    if( pc
2920: 61 63 68 65 2e 70 4c 72 75 54 61 69 6c 3d 3d 30  ache.pLruTail==0
2930: 20 29 7b 0a 20 20 20 20 20 20 70 63 61 63 68 65   ){.      pcache
2940: 2e 70 4c 72 75 54 61 69 6c 20 3d 20 70 50 61 67  .pLruTail = pPag
2950: 65 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28  e;.    }.    if(
2960: 20 70 63 61 63 68 65 2e 70 4c 72 75 53 79 6e 63   pcache.pLruSync
2970: 65 64 3d 3d 30 20 26 26 20 30 3d 3d 28 70 50 61  ed==0 && 0==(pPa
2980: 67 65 2d 3e 66 6c 61 67 73 26 50 47 48 44 52 5f  ge->flags&PGHDR_
2990: 4e 45 45 44 5f 53 59 4e 43 29 20 29 7b 0a 20 20  NEED_SYNC) ){.  
29a0: 20 20 20 20 70 63 61 63 68 65 2e 70 4c 72 75 53      pcache.pLruS
29b0: 79 6e 63 65 64 20 3d 20 70 50 61 67 65 3b 0a 20  ynced = pPage;. 
29c0: 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 2a 2a     }.  }.}../***
29d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
29e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
29f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 4d 65 6d  ************ Mem
2a00: 6f 72 79 20 41 6c 6c 6f 63 61 74 69 6f 6e 20 2a  ory Allocation *
2a10: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 2a 2a 0a 2a 2a  **********.**.**
2a20: 20 49 6e 69 74 69 61 6c 69 7a 65 20 74 68 65 20   Initialize the 
2a30: 70 61 67 65 20 63 61 63 68 65 20 6d 65 6d 6f 72  page cache memor
2a40: 79 20 70 6f 6f 6c 2e 0a 2a 2a 0a 2a 2a 20 54 68  y pool..**.** Th
2a50: 69 73 20 6d 75 73 74 20 62 65 20 63 61 6c 6c 65  is must be calle
2a60: 64 20 61 74 20 73 74 61 72 74 2d 74 69 6d 65 20  d at start-time 
2a70: 77 68 65 6e 20 6e 6f 20 70 61 67 65 20 63 61 63  when no page cac
2a80: 68 65 20 6c 69 6e 65 73 20 61 72 65 0a 2a 2a 20  he lines are.** 
2a90: 63 68 65 63 6b 65 64 20 6f 75 74 2e 20 54 68 69  checked out. Thi
2aa0: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 6e 6f  s function is no
2ab0: 74 20 74 68 72 65 61 64 73 61 66 65 2e 0a 2a 2f  t threadsafe..*/
2ac0: 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 43 61  .void sqlite3PCa
2ad0: 63 68 65 42 75 66 66 65 72 53 65 74 75 70 28 76  cheBufferSetup(v
2ae0: 6f 69 64 20 2a 70 42 75 66 2c 20 69 6e 74 20 73  oid *pBuf, int s
2af0: 7a 2c 20 69 6e 74 20 6e 29 7b 0a 20 20 50 67 46  z, int n){.  PgF
2b00: 72 65 65 73 6c 6f 74 20 2a 70 3b 0a 20 20 73 7a  reeslot *p;.  sz
2b10: 20 26 3d 20 7e 37 3b 0a 20 20 70 63 61 63 68 65   &= ~7;.  pcache
2b20: 2e 73 7a 53 6c 6f 74 20 3d 20 73 7a 3b 0a 20 20  .szSlot = sz;.  
2b30: 70 63 61 63 68 65 2e 70 53 74 61 72 74 20 3d 20  pcache.pStart = 
2b40: 70 42 75 66 3b 0a 20 20 70 63 61 63 68 65 2e 70  pBuf;.  pcache.p
2b50: 46 72 65 65 20 3d 20 30 3b 0a 20 20 77 68 69 6c  Free = 0;.  whil
2b60: 65 28 20 6e 2d 2d 20 29 7b 0a 20 20 20 20 70 20  e( n-- ){.    p 
2b70: 3d 20 28 50 67 46 72 65 65 73 6c 6f 74 2a 29 70  = (PgFreeslot*)p
2b80: 42 75 66 3b 0a 20 20 20 20 70 2d 3e 70 4e 65 78  Buf;.    p->pNex
2b90: 74 20 3d 20 70 63 61 63 68 65 2e 70 46 72 65 65  t = pcache.pFree
2ba0: 3b 0a 20 20 20 20 70 63 61 63 68 65 2e 70 46 72  ;.    pcache.pFr
2bb0: 65 65 20 3d 20 70 3b 0a 20 20 20 20 70 42 75 66  ee = p;.    pBuf
2bc0: 20 3d 20 28 76 6f 69 64 2a 29 26 28 28 63 68 61   = (void*)&((cha
2bd0: 72 2a 29 70 42 75 66 29 5b 73 7a 5d 3b 0a 20 20  r*)pBuf)[sz];.  
2be0: 7d 0a 20 20 70 63 61 63 68 65 2e 70 45 6e 64 20  }.  pcache.pEnd 
2bf0: 3d 20 70 42 75 66 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  = pBuf;.}../*.**
2c00: 20 41 6c 6c 6f 63 61 74 65 20 61 20 70 61 67 65   Allocate a page
2c10: 20 63 61 63 68 65 20 6c 69 6e 65 2e 20 20 4c 6f   cache line.  Lo
2c20: 6f 6b 20 69 6e 20 74 68 65 20 70 61 67 65 20 63  ok in the page c
2c30: 61 63 68 65 20 6d 65 6d 6f 72 79 20 70 6f 6f 6c  ache memory pool
2c40: 20 66 69 72 73 74 0a 2a 2a 20 61 6e 64 20 75 73   first.** and us
2c50: 65 20 61 6e 20 65 6c 65 6d 65 6e 74 20 66 72 6f  e an element fro
2c60: 6d 20 69 74 20 66 69 72 73 74 20 69 66 20 61 76  m it first if av
2c70: 61 69 6c 61 62 6c 65 2e 20 20 49 66 20 6e 6f 74  ailable.  If not
2c80: 68 69 6e 67 20 69 73 20 61 76 61 69 6c 61 62 6c  hing is availabl
2c90: 65 0a 2a 2a 20 69 6e 20 74 68 65 20 70 61 67 65  e.** in the page
2ca0: 20 63 61 63 68 65 20 6d 65 6d 6f 72 79 20 70 6f   cache memory po
2cb0: 6f 6c 2c 20 67 6f 20 74 6f 20 74 68 65 20 67 65  ol, go to the ge
2cc0: 6e 65 72 61 6c 20 70 75 72 70 6f 73 65 20 6d 65  neral purpose me
2cd0: 6d 6f 72 79 20 61 6c 6c 6f 63 61 74 6f 72 2e 0a  mory allocator..
2ce0: 2a 2f 0a 76 6f 69 64 20 2a 70 63 61 63 68 65 4d  */.void *pcacheM
2cf0: 61 6c 6c 6f 63 28 69 6e 74 20 73 7a 2c 20 50 43  alloc(int sz, PC
2d00: 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b 0a 20  ache *pCache){. 
2d10: 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33   assert( sqlite3
2d20: 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 63 61 63  _mutex_held(pcac
2d30: 68 65 2e 6d 75 74 65 78 5f 6c 72 75 29 20 29 3b  he.mutex_lru) );
2d40: 0a 20 20 69 66 28 20 73 7a 3c 3d 70 63 61 63 68  .  if( sz<=pcach
2d50: 65 2e 73 7a 53 6c 6f 74 20 26 26 20 70 63 61 63  e.szSlot && pcac
2d60: 68 65 2e 70 46 72 65 65 20 29 7b 0a 20 20 20 20  he.pFree ){.    
2d70: 50 67 46 72 65 65 73 6c 6f 74 20 2a 70 20 3d 20  PgFreeslot *p = 
2d80: 70 63 61 63 68 65 2e 70 46 72 65 65 3b 0a 20 20  pcache.pFree;.  
2d90: 20 20 70 63 61 63 68 65 2e 70 46 72 65 65 20 3d    pcache.pFree =
2da0: 20 70 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 73   p->pNext;.    s
2db0: 71 6c 69 74 65 33 53 74 61 74 75 73 53 65 74 28  qlite3StatusSet(
2dc0: 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41  SQLITE_STATUS_PA
2dd0: 47 45 43 41 43 48 45 5f 53 49 5a 45 2c 20 73 7a  GECACHE_SIZE, sz
2de0: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 53 74  );.    sqlite3St
2df0: 61 74 75 73 41 64 64 28 53 51 4c 49 54 45 5f 53  atusAdd(SQLITE_S
2e00: 54 41 54 55 53 5f 50 41 47 45 43 41 43 48 45 5f  TATUS_PAGECACHE_
2e10: 55 53 45 44 2c 20 31 29 3b 0a 20 20 20 20 72 65  USED, 1);.    re
2e20: 74 75 72 6e 20 28 76 6f 69 64 2a 29 70 3b 0a 20  turn (void*)p;. 
2e30: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 76 6f 69 64   }else{.    void
2e40: 20 2a 70 3b 0a 0a 20 20 20 20 2f 2a 20 41 6c 6c   *p;..    /* All
2e50: 6f 63 61 74 65 20 61 20 6e 65 77 20 62 75 66 66  ocate a new buff
2e60: 65 72 20 75 73 69 6e 67 20 73 71 6c 69 74 65 33  er using sqlite3
2e70: 4d 61 6c 6c 6f 63 2e 20 42 65 66 6f 72 65 20 64  Malloc. Before d
2e80: 6f 69 6e 67 20 73 6f 2c 20 65 78 69 74 20 74 68  oing so, exit th
2e90: 65 0a 20 20 20 20 2a 2a 20 67 6c 6f 62 61 6c 20  e.    ** global 
2ea0: 70 63 61 63 68 65 20 6d 75 74 65 78 20 61 6e 64  pcache mutex and
2eb0: 20 75 6e 6c 6f 63 6b 20 74 68 65 20 70 61 67 65   unlock the page
2ec0: 72 2d 63 61 63 68 65 20 6f 62 6a 65 63 74 20 70  r-cache object p
2ed0: 43 61 63 68 65 2e 20 54 68 69 73 20 69 73 20 0a  Cache. This is .
2ee0: 20 20 20 20 2a 2a 20 73 6f 20 74 68 61 74 20 69      ** so that i
2ef0: 66 20 74 68 65 20 61 74 74 65 6d 70 74 20 74 6f  f the attempt to
2f00: 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20   allocate a new 
2f10: 62 75 66 66 65 72 20 63 61 75 73 65 73 20 74 68  buffer causes th
2f20: 65 20 74 68 65 20 0a 20 20 20 20 2a 2a 20 63 6f  e the .    ** co
2f30: 6e 66 69 67 75 72 65 64 20 73 6f 66 74 2d 68 65  nfigured soft-he
2f40: 61 70 2d 6c 69 6d 69 74 20 74 6f 20 62 65 20 62  ap-limit to be b
2f50: 72 65 61 63 68 65 64 2c 20 69 74 20 77 69 6c 6c  reached, it will
2f60: 20 62 65 20 70 6f 73 73 69 62 6c 65 20 74 6f 0a   be possible to.
2f70: 20 20 20 20 2a 2a 20 72 65 63 6c 61 69 6d 20 6d      ** reclaim m
2f80: 65 6d 6f 72 79 20 66 72 6f 6d 20 74 68 69 73 20  emory from this 
2f90: 70 61 67 65 72 2d 63 61 63 68 65 2e 20 42 65 63  pager-cache. Bec
2fa0: 61 75 73 65 20 73 71 6c 69 74 65 33 50 63 61 63  ause sqlite3Pcac
2fb0: 68 65 4c 6f 63 6b 28 29 20 0a 20 20 20 20 2a 2a  heLock() .    **
2fc0: 20 6d 69 67 68 74 20 62 6c 6f 63 6b 20 6f 6e 20   might block on 
2fd0: 74 68 65 20 4d 45 4d 32 20 6d 75 74 65 78 2c 20  the MEM2 mutex, 
2fe0: 69 74 20 68 61 73 20 74 6f 20 62 65 20 63 61 6c  it has to be cal
2ff0: 6c 65 64 20 62 65 66 6f 72 65 20 72 65 2d 65 6e  led before re-en
3000: 74 65 72 69 6e 67 0a 20 20 20 20 2a 2a 20 74 68  tering.    ** th
3010: 65 20 67 6c 6f 62 61 6c 20 4c 52 55 20 6d 75 74  e global LRU mut
3020: 65 78 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 70  ex..    */.    p
3030: 63 61 63 68 65 45 78 69 74 47 6c 6f 62 61 6c 28  cacheExitGlobal(
3040: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 50 63  );.    sqlite3Pc
3050: 61 63 68 65 55 6e 6c 6f 63 6b 28 70 43 61 63 68  acheUnlock(pCach
3060: 65 29 3b 0a 20 20 20 20 70 20 3d 20 73 71 6c 69  e);.    p = sqli
3070: 74 65 33 4d 61 6c 6c 6f 63 28 73 7a 29 3b 0a 20  te3Malloc(sz);. 
3080: 20 20 20 73 71 6c 69 74 65 33 50 63 61 63 68 65     sqlite3Pcache
3090: 4c 6f 63 6b 28 70 43 61 63 68 65 29 3b 0a 20 20  Lock(pCache);.  
30a0: 20 20 70 63 61 63 68 65 45 6e 74 65 72 47 6c 6f    pcacheEnterGlo
30b0: 62 61 6c 28 29 3b 0a 0a 20 20 20 20 69 66 28 20  bal();..    if( 
30c0: 70 20 29 7b 0a 20 20 20 20 20 20 73 7a 20 3d 20  p ){.      sz = 
30d0: 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 53 69 7a  sqlite3MallocSiz
30e0: 65 28 70 29 3b 0a 20 20 20 20 20 20 73 71 6c 69  e(p);.      sqli
30f0: 74 65 33 53 74 61 74 75 73 41 64 64 28 53 51 4c  te3StatusAdd(SQL
3100: 49 54 45 5f 53 54 41 54 55 53 5f 50 41 47 45 43  ITE_STATUS_PAGEC
3110: 41 43 48 45 5f 4f 56 45 52 46 4c 4f 57 2c 20 73  ACHE_OVERFLOW, s
3120: 7a 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72 65  z);.    }.    re
3130: 74 75 72 6e 20 70 3b 0a 20 20 7d 0a 7d 0a 76 6f  turn p;.  }.}.vo
3140: 69 64 20 2a 73 71 6c 69 74 65 33 50 61 67 65 4d  id *sqlite3PageM
3150: 61 6c 6c 6f 63 28 73 7a 29 7b 0a 20 20 76 6f 69  alloc(sz){.  voi
3160: 64 20 2a 70 3b 0a 20 20 70 63 61 63 68 65 45 6e  d *p;.  pcacheEn
3170: 74 65 72 47 6c 6f 62 61 6c 28 29 3b 0a 20 20 70  terGlobal();.  p
3180: 20 3d 20 70 63 61 63 68 65 4d 61 6c 6c 6f 63 28   = pcacheMalloc(
3190: 73 7a 2c 20 30 29 3b 0a 20 20 70 63 61 63 68 65  sz, 0);.  pcache
31a0: 45 78 69 74 47 6c 6f 62 61 6c 28 29 3b 0a 20 20  ExitGlobal();.  
31b0: 72 65 74 75 72 6e 20 70 3b 0a 7d 0a 0a 2f 2a 0a  return p;.}../*.
31c0: 2a 2a 20 52 65 6c 65 61 73 65 20 61 20 70 61 67  ** Release a pag
31d0: 65 72 20 6d 65 6d 6f 72 79 20 61 6c 6c 6f 63 61  er memory alloca
31e0: 74 69 6f 6e 0a 2a 2f 0a 76 6f 69 64 20 70 63 61  tion.*/.void pca
31f0: 63 68 65 46 72 65 65 28 76 6f 69 64 20 2a 70 29  cheFree(void *p)
3200: 7b 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c 69  {.  assert( sqli
3210: 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70  te3_mutex_held(p
3220: 63 61 63 68 65 2e 6d 75 74 65 78 5f 6c 72 75 29  cache.mutex_lru)
3230: 20 29 3b 0a 20 20 69 66 28 20 70 3d 3d 30 20 29   );.  if( p==0 )
3240: 20 72 65 74 75 72 6e 3b 0a 20 20 69 66 28 20 70   return;.  if( p
3250: 3e 3d 70 63 61 63 68 65 2e 70 53 74 61 72 74 20  >=pcache.pStart 
3260: 26 26 20 70 3c 70 63 61 63 68 65 2e 70 45 6e 64  && p<pcache.pEnd
3270: 20 29 7b 0a 20 20 20 20 50 67 46 72 65 65 73 6c   ){.    PgFreesl
3280: 6f 74 20 2a 70 53 6c 6f 74 3b 0a 20 20 20 20 73  ot *pSlot;.    s
3290: 71 6c 69 74 65 33 53 74 61 74 75 73 41 64 64 28  qlite3StatusAdd(
32a0: 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41  SQLITE_STATUS_PA
32b0: 47 45 43 41 43 48 45 5f 55 53 45 44 2c 20 2d 31  GECACHE_USED, -1
32c0: 29 3b 0a 20 20 20 20 70 53 6c 6f 74 20 3d 20 28  );.    pSlot = (
32d0: 50 67 46 72 65 65 73 6c 6f 74 2a 29 70 3b 0a 20  PgFreeslot*)p;. 
32e0: 20 20 20 70 53 6c 6f 74 2d 3e 70 4e 65 78 74 20     pSlot->pNext 
32f0: 3d 20 70 63 61 63 68 65 2e 70 46 72 65 65 3b 0a  = pcache.pFree;.
3300: 20 20 20 20 70 63 61 63 68 65 2e 70 46 72 65 65      pcache.pFree
3310: 20 3d 20 70 53 6c 6f 74 3b 0a 20 20 7d 65 6c 73   = pSlot;.  }els
3320: 65 7b 0a 20 20 20 20 69 6e 74 20 69 53 69 7a 65  e{.    int iSize
3330: 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63   = sqlite3Malloc
3340: 53 69 7a 65 28 70 29 3b 0a 20 20 20 20 73 71 6c  Size(p);.    sql
3350: 69 74 65 33 53 74 61 74 75 73 41 64 64 28 53 51  ite3StatusAdd(SQ
3360: 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41 47 45  LITE_STATUS_PAGE
3370: 43 41 43 48 45 5f 4f 56 45 52 46 4c 4f 57 2c 20  CACHE_OVERFLOW, 
3380: 2d 69 53 69 7a 65 29 3b 0a 20 20 20 20 73 71 6c  -iSize);.    sql
3390: 69 74 65 33 5f 66 72 65 65 28 70 29 3b 0a 20 20  ite3_free(p);.  
33a0: 7d 0a 7d 0a 76 6f 69 64 20 73 71 6c 69 74 65 33  }.}.void sqlite3
33b0: 50 61 67 65 46 72 65 65 28 76 6f 69 64 20 2a 70  PageFree(void *p
33c0: 29 7b 0a 20 20 70 63 61 63 68 65 45 6e 74 65 72  ){.  pcacheEnter
33d0: 47 6c 6f 62 61 6c 28 29 3b 0a 20 20 70 63 61 63  Global();.  pcac
33e0: 68 65 46 72 65 65 28 70 29 3b 0a 20 20 70 63 61  heFree(p);.  pca
33f0: 63 68 65 45 78 69 74 47 6c 6f 62 61 6c 28 29 3b  cheExitGlobal();
3400: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c 6f 63 61  .}../*.** Alloca
3410: 74 65 20 61 20 6e 65 77 20 70 61 67 65 2e 0a 2a  te a new page..*
3420: 2f 0a 73 74 61 74 69 63 20 50 67 48 64 72 20 2a  /.static PgHdr *
3430: 70 63 61 63 68 65 50 61 67 65 41 6c 6c 6f 63 28  pcachePageAlloc(
3440: 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b  PCache *pCache){
3450: 0a 20 20 50 67 48 64 72 20 2a 70 3b 0a 20 20 69  .  PgHdr *p;.  i
3460: 6e 74 20 73 7a 20 3d 20 73 69 7a 65 6f 66 28 2a  nt sz = sizeof(*
3470: 70 29 20 2b 20 70 43 61 63 68 65 2d 3e 73 7a 50  p) + pCache->szP
3480: 61 67 65 20 2b 20 70 43 61 63 68 65 2d 3e 73 7a  age + pCache->sz
3490: 45 78 74 72 61 3b 0a 20 20 61 73 73 65 72 74 28  Extra;.  assert(
34a0: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68   sqlite3_mutex_h
34b0: 65 6c 64 28 70 63 61 63 68 65 2e 6d 75 74 65 78  eld(pcache.mutex
34c0: 5f 6c 72 75 29 20 29 3b 0a 20 20 70 20 3d 20 70  _lru) );.  p = p
34d0: 63 61 63 68 65 4d 61 6c 6c 6f 63 28 73 7a 2c 20  cacheMalloc(sz, 
34e0: 70 43 61 63 68 65 29 3b 0a 20 20 69 66 28 20 70  pCache);.  if( p
34f0: 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 30 3b 0a  ==0 ) return 0;.
3500: 20 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20 73    memset(p, 0, s
3510: 69 7a 65 6f 66 28 50 67 48 64 72 29 29 3b 0a 20  izeof(PgHdr));. 
3520: 20 70 2d 3e 70 44 61 74 61 20 3d 20 28 76 6f 69   p->pData = (voi
3530: 64 2a 29 26 70 5b 31 5d 3b 0a 20 20 70 2d 3e 70  d*)&p[1];.  p->p
3540: 45 78 74 72 61 20 3d 20 28 76 6f 69 64 2a 29 26  Extra = (void*)&
3550: 28 28 63 68 61 72 2a 29 70 2d 3e 70 44 61 74 61  ((char*)p->pData
3560: 29 5b 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65  )[pCache->szPage
3570: 5d 3b 0a 20 20 70 63 61 63 68 65 2e 6e 50 61 67  ];.  pcache.nPag
3580: 65 2b 2b 3b 0a 20 20 69 66 28 20 70 43 61 63 68  e++;.  if( pCach
3590: 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 29 7b  e->bPurgeable ){
35a0: 0a 20 20 20 20 70 63 61 63 68 65 2e 6e 50 75 72  .    pcache.nPur
35b0: 67 65 61 62 6c 65 2b 2b 3b 0a 20 20 7d 0a 0a 20  geable++;.  }.. 
35c0: 20 72 65 74 75 72 6e 20 70 3b 0a 7d 0a 0a 2f 2a   return p;.}../*
35d0: 0a 2a 2a 20 44 65 61 6c 6c 6f 63 61 74 65 20 61  .** Deallocate a
35e0: 20 70 61 67 65 0a 2a 2f 0a 73 74 61 74 69 63 20   page.*/.static 
35f0: 76 6f 69 64 20 70 63 61 63 68 65 50 61 67 65 46  void pcachePageF
3600: 72 65 65 28 50 67 48 64 72 20 2a 70 29 7b 0a 20  ree(PgHdr *p){. 
3610: 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33   assert( sqlite3
3620: 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 63 61 63  _mutex_held(pcac
3630: 68 65 2e 6d 75 74 65 78 5f 6c 72 75 29 20 29 3b  he.mutex_lru) );
3640: 0a 20 20 70 63 61 63 68 65 2e 6e 50 61 67 65 2d  .  pcache.nPage-
3650: 2d 3b 0a 20 20 69 66 28 20 70 2d 3e 70 43 61 63  -;.  if( p->pCac
3660: 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 29  he->bPurgeable )
3670: 7b 0a 20 20 20 20 70 63 61 63 68 65 2e 6e 50 75  {.    pcache.nPu
3680: 72 67 65 61 62 6c 65 2d 2d 3b 0a 20 20 7d 0a 20  rgeable--;.  }. 
3690: 20 70 63 61 63 68 65 46 72 65 65 28 70 2d 3e 61   pcacheFree(p->a
36a0: 70 53 61 76 65 5b 30 5d 29 3b 0a 20 20 70 63 61  pSave[0]);.  pca
36b0: 63 68 65 46 72 65 65 28 70 2d 3e 61 70 53 61 76  cheFree(p->apSav
36c0: 65 5b 31 5d 29 3b 0a 20 20 70 63 61 63 68 65 46  e[1]);.  pcacheF
36d0: 72 65 65 28 70 29 3b 0a 7d 0a 0a 23 69 66 64 65  ree(p);.}..#ifde
36e0: 66 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f  f SQLITE_ENABLE_
36f0: 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e  MEMORY_MANAGEMEN
3700: 54 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74  T./*.** Return t
3710: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 62 79 74  he number of byt
3720: 65 73 20 74 68 61 74 20 77 69 6c 6c 20 62 65 20  es that will be 
3730: 72 65 74 75 72 6e 65 64 20 74 6f 20 74 68 65 20  returned to the 
3740: 68 65 61 70 20 77 68 65 6e 0a 2a 2a 20 74 68 65  heap when.** the
3750: 20 61 72 67 75 6d 65 6e 74 20 69 73 20 70 61 73   argument is pas
3760: 73 65 64 20 74 6f 20 70 63 61 63 68 65 50 61 67  sed to pcachePag
3770: 65 46 72 65 65 28 29 2e 0a 2a 2f 0a 73 74 61 74  eFree()..*/.stat
3780: 69 63 20 69 6e 74 20 70 63 61 63 68 65 50 61 67  ic int pcachePag
3790: 65 53 69 7a 65 28 50 67 48 64 72 20 2a 70 29 7b  eSize(PgHdr *p){
37a0: 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74  .  assert( sqlit
37b0: 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 63  e3_mutex_held(pc
37c0: 61 63 68 65 2e 6d 75 74 65 78 5f 6c 72 75 29 20  ache.mutex_lru) 
37d0: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 21 70 63  );.  assert( !pc
37e0: 61 63 68 65 2e 70 53 74 61 72 74 20 29 3b 0a 20  ache.pStart );. 
37f0: 20 61 73 73 65 72 74 28 20 70 2d 3e 61 70 53 61   assert( p->apSa
3800: 76 65 5b 30 5d 3d 3d 30 20 29 3b 0a 20 20 61 73  ve[0]==0 );.  as
3810: 73 65 72 74 28 20 70 2d 3e 61 70 53 61 76 65 5b  sert( p->apSave[
3820: 31 5d 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72  1]==0 );.  asser
3830: 74 28 20 70 20 26 26 20 70 2d 3e 70 43 61 63 68  t( p && p->pCach
3840: 65 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 73 71  e );.  return sq
3850: 6c 69 74 65 33 4d 61 6c 6c 6f 63 53 69 7a 65 28  lite3MallocSize(
3860: 70 29 3b 0a 7d 0a 23 65 6e 64 69 66 0a 0a 2f 2a  p);.}.#endif../*
3870: 0a 2a 2a 20 52 65 63 79 63 6c 65 20 61 20 70 61  .** Recycle a pa
3880: 67 65 20 66 72 6f 6d 20 74 68 65 20 67 6c 6f 62  ge from the glob
3890: 61 6c 20 4c 52 55 20 6c 69 73 74 2e 20 49 66 20  al LRU list. If 
38a0: 6e 6f 20 70 61 67 65 20 63 61 6e 20 62 65 20 72  no page can be r
38b0: 65 63 79 63 6c 65 64 2c 20 0a 2a 2a 20 72 65 74  ecycled, .** ret
38c0: 75 72 6e 20 4e 55 4c 4c 2e 20 4f 74 68 65 72 77  urn NULL. Otherw
38d0: 69 73 65 2c 20 74 68 65 20 70 6f 69 6e 74 65 72  ise, the pointer
38e0: 20 72 65 74 75 72 6e 65 64 20 70 6f 69 6e 74 73   returned points
38f0: 20 74 6f 20 61 20 50 67 48 64 72 20 0a 2a 2a 20   to a PgHdr .** 
3900: 6f 62 6a 65 63 74 20 74 68 61 74 20 68 61 73 20  object that has 
3910: 62 65 65 6e 20 72 65 6d 6f 76 65 64 20 66 72 6f  been removed fro
3920: 6d 20 61 6c 6c 20 6c 69 73 74 73 20 61 6e 64 20  m all lists and 
3930: 68 61 73 68 20 74 61 62 6c 65 73 20 69 6e 0a 2a  hash tables in.*
3940: 2a 20 77 68 69 63 68 20 69 73 20 77 61 73 20 72  * which is was r
3950: 65 66 65 72 65 6e 63 65 64 2e 20 54 68 65 20 63  eferenced. The c
3960: 61 6c 6c 65 72 20 6d 61 79 20 72 65 75 73 65 20  aller may reuse 
3970: 74 68 65 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 64  the allocation d
3980: 69 72 65 63 74 6c 79 0a 2a 2a 20 6f 72 20 6d 61  irectly.** or ma
3990: 79 20 70 61 73 73 20 69 74 20 74 6f 20 70 63 61  y pass it to pca
39a0: 63 68 65 50 61 67 65 46 72 65 65 28 29 20 74 6f  chePageFree() to
39b0: 20 72 65 74 75 72 6e 20 74 68 65 20 6d 65 6d 6f   return the memo
39c0: 72 79 20 74 6f 20 74 68 65 20 68 65 61 70 0a 2a  ry to the heap.*
39d0: 2a 20 28 6f 72 20 70 63 61 63 68 65 2e 70 46 72  * (or pcache.pFr
39e0: 65 65 20 6c 69 73 74 29 2e 0a 2a 2f 20 0a 73 74  ee list)..*/ .st
39f0: 61 74 69 63 20 50 67 48 64 72 20 2a 70 63 61 63  atic PgHdr *pcac
3a00: 68 65 52 65 63 79 63 6c 65 28 50 43 61 63 68 65  heRecycle(PCache
3a10: 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 50 67 48   *pCache){.  PgH
3a20: 64 72 20 2a 70 20 3d 20 30 3b 0a 0a 20 20 61 73  dr *p = 0;..  as
3a30: 73 65 72 74 28 20 70 63 61 63 68 65 2e 69 73 49  sert( pcache.isI
3a40: 6e 69 74 20 29 3b 0a 20 20 61 73 73 65 72 74 28  nit );.  assert(
3a50: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68   sqlite3_mutex_h
3a60: 65 6c 64 28 70 63 61 63 68 65 2e 6d 75 74 65 78  eld(pcache.mutex
3a70: 5f 6c 72 75 29 20 29 3b 0a 0a 20 20 70 20 3d 20  _lru) );..  p = 
3a80: 70 63 61 63 68 65 2e 70 4c 72 75 53 79 6e 63 65  pcache.pLruSynce
3a90: 64 3b 0a 20 20 69 66 28 20 21 70 20 29 7b 0a 20  d;.  if( !p ){. 
3aa0: 20 20 20 70 20 3d 20 70 63 61 63 68 65 2e 70 4c     p = pcache.pL
3ab0: 72 75 54 61 69 6c 3b 0a 20 20 7d 0a 20 20 69 66  ruTail;.  }.  if
3ac0: 28 20 70 20 26 26 20 28 70 2d 3e 66 6c 61 67 73  ( p && (p->flags
3ad0: 26 50 47 48 44 52 5f 44 49 52 54 59 29 20 29 7b  &PGHDR_DIRTY) ){
3ae0: 0a 20 20 20 20 69 66 28 20 53 51 4c 49 54 45 5f  .    if( SQLITE_
3af0: 4f 4b 3d 3d 73 71 6c 69 74 65 33 5f 6d 75 74 65  OK==sqlite3_mute
3b00: 78 5f 74 72 79 28 70 63 61 63 68 65 2e 6d 75 74  x_try(pcache.mut
3b10: 65 78 5f 6d 65 6d 32 29 20 29 7b 0a 20 20 20 20  ex_mem2) ){.    
3b20: 20 20 50 43 61 63 68 65 20 2a 70 43 20 3d 20 70    PCache *pC = p
3b30: 2d 3e 70 43 61 63 68 65 3b 0a 20 20 20 20 20 20  ->pCache;.      
3b40: 61 73 73 65 72 74 28 20 70 43 2d 3e 69 49 6e 55  assert( pC->iInU
3b50: 73 65 4d 4d 3d 3d 30 20 29 3b 0a 20 20 20 20 20  seMM==0 );.     
3b60: 20 70 43 2d 3e 69 49 6e 55 73 65 4d 4d 20 3d 20   pC->iInUseMM = 
3b70: 31 3b 0a 20 20 20 20 20 20 69 66 28 20 70 43 2d  1;.      if( pC-
3b80: 3e 78 53 74 72 65 73 73 20 26 26 20 28 70 43 2d  >xStress && (pC-
3b90: 3e 69 49 6e 55 73 65 44 42 3d 3d 30 20 7c 7c 20  >iInUseDB==0 || 
3ba0: 70 43 3d 3d 70 43 61 63 68 65 29 20 29 7b 0a 20  pC==pCache) ){. 
3bb0: 20 20 20 20 20 20 20 70 63 61 63 68 65 45 78 69         pcacheExi
3bc0: 74 47 6c 6f 62 61 6c 28 29 3b 0a 20 20 20 20 20  tGlobal();.     
3bd0: 20 20 20 70 43 2d 3e 78 53 74 72 65 73 73 28 70     pC->xStress(p
3be0: 43 2d 3e 70 53 74 72 65 73 73 2c 20 70 29 3b 0a  C->pStress, p);.
3bf0: 20 20 20 20 20 20 20 20 70 63 61 63 68 65 45 6e          pcacheEn
3c00: 74 65 72 47 6c 6f 62 61 6c 28 29 3b 0a 20 20 20  terGlobal();.   
3c10: 20 20 20 7d 0a 20 20 20 20 20 20 70 43 2d 3e 69     }.      pC->i
3c20: 49 6e 55 73 65 4d 4d 20 3d 20 30 3b 0a 20 20 20  InUseMM = 0;.   
3c30: 20 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78     sqlite3_mutex
3c40: 5f 6c 65 61 76 65 28 70 63 61 63 68 65 2e 6d 75  _leave(pcache.mu
3c50: 74 65 78 5f 6d 65 6d 32 29 3b 0a 20 20 20 20 7d  tex_mem2);.    }
3c60: 0a 20 20 7d 0a 20 20 69 66 28 20 70 20 26 26 20  .  }.  if( p && 
3c70: 28 70 2d 3e 66 6c 61 67 73 26 50 47 48 44 52 5f  (p->flags&PGHDR_
3c80: 44 49 52 54 59 29 20 29 7b 0a 20 20 20 20 70 20  DIRTY) ){.    p 
3c90: 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20  = 0;.  }..  if( 
3ca0: 70 20 29 7b 0a 20 20 20 20 70 63 61 63 68 65 52  p ){.    pcacheR
3cb0: 65 6d 6f 76 65 46 72 6f 6d 4c 72 75 4c 69 73 74  emoveFromLruList
3cc0: 28 70 29 3b 0a 20 20 20 20 70 63 61 63 68 65 52  (p);.    pcacheR
3cd0: 65 6d 6f 76 65 46 72 6f 6d 48 61 73 68 28 70 29  emoveFromHash(p)
3ce0: 3b 0a 20 20 20 20 70 63 61 63 68 65 52 65 6d 6f  ;.    pcacheRemo
3cf0: 76 65 46 72 6f 6d 4c 69 73 74 28 26 70 2d 3e 70  veFromList(&p->p
3d00: 43 61 63 68 65 2d 3e 70 43 6c 65 61 6e 2c 20 70  Cache->pClean, p
3d10: 29 3b 0a 0a 20 20 20 20 2f 2a 20 49 66 20 74 68  );..    /* If th
3d20: 65 20 61 6c 77 61 79 73 2d 72 6f 6c 6c 62 61 63  e always-rollbac
3d30: 6b 20 66 6c 61 67 20 69 73 20 73 65 74 20 6f 6e  k flag is set on
3d40: 20 74 68 65 20 70 61 67 65 20 62 65 69 6e 67 20   the page being 
3d50: 72 65 63 79 63 6c 65 64 2c 20 73 65 74 20 0a 20  recycled, set . 
3d60: 20 20 20 2a 2a 20 74 68 65 20 61 6c 77 61 79 73     ** the always
3d70: 2d 72 6f 6c 6c 62 61 63 6b 20 66 6c 61 67 20 6f  -rollback flag o
3d80: 6e 20 74 68 65 20 63 6f 72 72 65 73 70 6f 6e 64  n the correspond
3d90: 69 6e 67 20 70 61 67 65 72 2e 0a 20 20 20 20 2a  ing pager..    *
3da0: 2f 0a 20 20 20 20 69 66 28 20 70 2d 3e 66 6c 61  /.    if( p->fla
3db0: 67 73 26 50 47 48 44 52 5f 41 4c 57 41 59 53 5f  gs&PGHDR_ALWAYS_
3dc0: 52 4f 4c 4c 42 41 43 4b 20 29 7b 0a 20 20 20 20  ROLLBACK ){.    
3dd0: 20 20 61 73 73 65 72 74 28 70 2d 3e 70 50 61 67    assert(p->pPag
3de0: 65 72 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74  er);.      sqlit
3df0: 65 33 50 61 67 65 72 41 6c 77 61 79 73 52 6f 6c  e3PagerAlwaysRol
3e00: 6c 62 61 63 6b 28 70 2d 3e 70 50 61 67 65 72 29  lback(p->pPager)
3e10: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72  ;.    }.  }..  r
3e20: 65 74 75 72 6e 20 70 3b 0a 7d 0a 0a 2f 2a 0a 2a  eturn p;.}../*.*
3e30: 2a 20 4f 62 74 61 69 6e 20 73 70 61 63 65 20 66  * Obtain space f
3e40: 6f 72 20 61 20 70 61 67 65 2e 20 54 72 79 20 74  or a page. Try t
3e50: 6f 20 72 65 63 79 63 6c 65 20 61 6e 20 6f 6c 64  o recycle an old
3e60: 20 70 61 67 65 20 69 66 20 74 68 65 20 6c 69 6d   page if the lim
3e70: 69 74 20 6f 6e 20 74 68 65 20 0a 2a 2a 20 6e 75  it on the .** nu
3e80: 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 68 61  mber of pages ha
3e90: 73 20 62 65 65 6e 20 72 65 61 63 68 65 64 2e 20  s been reached. 
3ea0: 49 66 20 74 68 65 20 6c 69 6d 69 74 20 68 61 73  If the limit has
3eb0: 20 6e 6f 74 20 62 65 65 6e 20 72 65 61 63 68 65   not been reache
3ec0: 64 20 6f 72 0a 2a 2a 20 74 68 65 72 65 20 61 72  d or.** there ar
3ed0: 65 20 6e 6f 20 70 61 67 65 73 20 65 6c 69 67 69  e no pages eligi
3ee0: 62 6c 65 20 66 6f 72 20 72 65 63 79 63 6c 69 6e  ble for recyclin
3ef0: 67 2c 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e 65  g, allocate a ne
3f00: 77 20 70 61 67 65 2e 0a 2a 2a 0a 2a 2a 20 52 65  w page..**.** Re
3f10: 74 75 72 6e 20 61 20 70 6f 69 6e 74 65 72 20 74  turn a pointer t
3f20: 6f 20 74 68 65 20 6e 65 77 20 70 61 67 65 2c 20  o the new page, 
3f30: 6f 72 20 4e 55 4c 4c 20 69 66 20 61 6e 20 4f 4f  or NULL if an OO
3f40: 4d 20 63 6f 6e 64 69 74 69 6f 6e 20 6f 63 63 75  M condition occu
3f50: 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 50 67  rs..*/.static Pg
3f60: 48 64 72 20 2a 70 63 61 63 68 65 52 65 63 79 63  Hdr *pcacheRecyc
3f70: 6c 65 4f 72 41 6c 6c 6f 63 28 50 43 61 63 68 65  leOrAlloc(PCache
3f80: 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 50 67 48   *pCache){.  PgH
3f90: 64 72 20 2a 70 20 3d 20 30 3b 0a 0a 20 20 69 6e  dr *p = 0;..  in
3fa0: 74 20 73 7a 50 61 67 65 20 3d 20 70 43 61 63 68  t szPage = pCach
3fb0: 65 2d 3e 73 7a 50 61 67 65 3b 0a 20 20 69 6e 74  e->szPage;.  int
3fc0: 20 73 7a 45 78 74 72 61 20 3d 20 70 43 61 63 68   szExtra = pCach
3fd0: 65 2d 3e 73 7a 45 78 74 72 61 3b 0a 20 20 69 6e  e->szExtra;.  in
3fe0: 74 20 62 50 75 72 67 20 3d 20 70 43 61 63 68 65  t bPurg = pCache
3ff0: 2d 3e 62 50 75 72 67 65 61 62 6c 65 3b 0a 0a 20  ->bPurgeable;.. 
4000: 20 61 73 73 65 72 74 28 20 70 63 61 63 68 65 2e   assert( pcache.
4010: 69 73 49 6e 69 74 20 29 3b 0a 20 20 61 73 73 65  isInit );.  asse
4020: 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65  rt( sqlite3_mute
4030: 78 5f 6e 6f 74 68 65 6c 64 28 70 63 61 63 68 65  x_notheld(pcache
4040: 2e 6d 75 74 65 78 5f 6c 72 75 29 20 29 3b 0a 0a  .mutex_lru) );..
4050: 20 20 70 63 61 63 68 65 45 6e 74 65 72 47 6c 6f    pcacheEnterGlo
4060: 62 61 6c 28 29 3b 0a 0a 20 20 69 66 28 20 28 70  bal();..  if( (p
4070: 63 61 63 68 65 2e 6d 78 50 61 67 65 20 26 26 20  cache.mxPage && 
4080: 70 63 61 63 68 65 2e 6e 50 61 67 65 3e 3d 70 63  pcache.nPage>=pc
4090: 61 63 68 65 2e 6d 78 50 61 67 65 29 20 0a 20 20  ache.mxPage) .  
40a0: 20 7c 7c 20 28 21 70 63 61 63 68 65 2e 6d 78 50   || (!pcache.mxP
40b0: 61 67 65 20 26 26 20 62 50 75 72 67 20 26 26 20  age && bPurg && 
40c0: 70 63 61 63 68 65 2e 6e 50 75 72 67 65 61 62 6c  pcache.nPurgeabl
40d0: 65 3e 3d 70 63 61 63 68 65 2e 6d 78 50 61 67 65  e>=pcache.mxPage
40e0: 50 75 72 67 65 61 62 6c 65 29 0a 20 20 29 7b 0a  Purgeable).  ){.
40f0: 20 20 20 20 2f 2a 20 49 66 20 74 68 65 20 61 62      /* If the ab
4100: 6f 76 65 20 74 65 73 74 20 73 75 63 63 65 65 64  ove test succeed
4110: 73 2c 20 74 68 65 6e 20 74 72 79 20 74 6f 20 6f  s, then try to o
4120: 62 74 61 69 6e 20 61 20 62 75 66 66 65 72 20 62  btain a buffer b
4130: 79 20 72 65 63 79 63 6c 69 6e 67 0a 20 20 20 20  y recycling.    
4140: 2a 2a 20 61 6e 20 65 78 69 73 74 69 6e 67 20 70  ** an existing p
4150: 61 67 65 2e 20 2a 2f 0a 20 20 20 20 70 20 3d 20  age. */.    p = 
4160: 70 63 61 63 68 65 52 65 63 79 63 6c 65 28 70 43  pcacheRecycle(pC
4170: 61 63 68 65 29 3b 0a 20 20 7d 0a 0a 20 20 69 66  ache);.  }..  if
4180: 28 20 70 20 26 26 20 28 70 2d 3e 70 43 61 63 68  ( p && (p->pCach
4190: 65 2d 3e 73 7a 50 61 67 65 21 3d 73 7a 50 61 67  e->szPage!=szPag
41a0: 65 20 7c 7c 20 70 2d 3e 70 43 61 63 68 65 2d 3e  e || p->pCache->
41b0: 73 7a 45 78 74 72 61 21 3d 73 7a 45 78 74 72 61  szExtra!=szExtra
41c0: 29 20 29 7b 0a 20 20 20 20 70 63 61 63 68 65 50  ) ){.    pcacheP
41d0: 61 67 65 46 72 65 65 28 70 29 3b 0a 20 20 20 20  ageFree(p);.    
41e0: 70 20 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20 69 66  p = 0;.  }..  if
41f0: 28 20 21 70 20 29 7b 0a 20 20 20 20 70 20 3d 20  ( !p ){.    p = 
4200: 70 63 61 63 68 65 50 61 67 65 41 6c 6c 6f 63 28  pcachePageAlloc(
4210: 70 43 61 63 68 65 29 3b 0a 20 20 7d 0a 0a 20 20  pCache);.  }..  
4220: 70 63 61 63 68 65 45 78 69 74 47 6c 6f 62 61 6c  pcacheExitGlobal
4230: 28 29 3b 0a 20 20 72 65 74 75 72 6e 20 70 3b 0a  ();.  return p;.
4240: 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  }../************
4250: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4260: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4270: 2a 2a 2a 2a 2a 2a 2a 20 47 65 6e 65 72 61 6c 20  ******* General 
4280: 49 6e 74 65 72 66 61 63 65 73 20 2a 2a 2a 2a 2a  Interfaces *****
4290: 2a 0a 2a 2a 0a 2a 2a 20 49 6e 69 74 69 61 6c 69  *.**.** Initiali
42a0: 7a 65 20 61 6e 64 20 73 68 75 74 64 6f 77 6e 20  ze and shutdown 
42b0: 74 68 65 20 70 61 67 65 20 63 61 63 68 65 20 73  the page cache s
42c0: 75 62 73 79 73 74 65 6d 2e 20 4e 65 69 74 68 65  ubsystem. Neithe
42d0: 72 20 6f 66 20 74 68 65 73 65 20 0a 2a 2a 20 66  r of these .** f
42e0: 75 6e 63 74 69 6f 6e 73 20 61 72 65 20 74 68 72  unctions are thr
42f0: 65 61 64 73 61 66 65 2e 0a 2a 2f 0a 69 6e 74 20  eadsafe..*/.int 
4300: 73 71 6c 69 74 65 33 50 63 61 63 68 65 49 6e 69  sqlite3PcacheIni
4310: 74 69 61 6c 69 7a 65 28 76 6f 69 64 29 7b 0a 20  tialize(void){. 
4320: 20 61 73 73 65 72 74 28 20 70 63 61 63 68 65 2e   assert( pcache.
4330: 69 73 49 6e 69 74 3d 3d 30 20 29 3b 0a 20 20 6d  isInit==0 );.  m
4340: 65 6d 73 65 74 28 26 70 63 61 63 68 65 2c 20 30  emset(&pcache, 0
4350: 2c 20 73 69 7a 65 6f 66 28 70 63 61 63 68 65 29  , sizeof(pcache)
4360: 29 3b 0a 20 20 69 66 28 20 73 71 6c 69 74 65 33  );.  if( sqlite3
4370: 43 6f 6e 66 69 67 2e 62 43 6f 72 65 4d 75 74 65  Config.bCoreMute
4380: 78 20 29 7b 0a 20 20 20 20 70 63 61 63 68 65 2e  x ){.    pcache.
4390: 6d 75 74 65 78 5f 6c 72 75 20 3d 20 73 71 6c 69  mutex_lru = sqli
43a0: 74 65 33 5f 6d 75 74 65 78 5f 61 6c 6c 6f 63 28  te3_mutex_alloc(
43b0: 53 51 4c 49 54 45 5f 4d 55 54 45 58 5f 53 54 41  SQLITE_MUTEX_STA
43c0: 54 49 43 5f 4c 52 55 29 3b 0a 20 20 20 20 70 63  TIC_LRU);.    pc
43d0: 61 63 68 65 2e 6d 75 74 65 78 5f 6d 65 6d 32 20  ache.mutex_mem2 
43e0: 3d 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f  = sqlite3_mutex_
43f0: 61 6c 6c 6f 63 28 53 51 4c 49 54 45 5f 4d 55 54  alloc(SQLITE_MUT
4400: 45 58 5f 53 54 41 54 49 43 5f 4d 45 4d 32 29 3b  EX_STATIC_MEM2);
4410: 0a 20 20 20 20 69 66 28 20 70 63 61 63 68 65 2e  .    if( pcache.
4420: 6d 75 74 65 78 5f 6c 72 75 3d 3d 30 20 7c 7c 20  mutex_lru==0 || 
4430: 70 63 61 63 68 65 2e 6d 75 74 65 78 5f 6d 65 6d  pcache.mutex_mem
4440: 32 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 72 65  2==0 ){.      re
4450: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  turn SQLITE_NOME
4460: 4d 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 70  M;.    }.  }.  p
4470: 63 61 63 68 65 2e 69 73 49 6e 69 74 20 3d 20 31  cache.isInit = 1
4480: 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ;.  return SQLIT
4490: 45 5f 4f 4b 3b 0a 7d 0a 76 6f 69 64 20 73 71 6c  E_OK;.}.void sql
44a0: 69 74 65 33 50 63 61 63 68 65 53 68 75 74 64 6f  ite3PcacheShutdo
44b0: 77 6e 28 76 6f 69 64 29 7b 0a 20 20 6d 65 6d 73  wn(void){.  mems
44c0: 65 74 28 26 70 63 61 63 68 65 2c 20 30 2c 20 73  et(&pcache, 0, s
44d0: 69 7a 65 6f 66 28 70 63 61 63 68 65 29 29 3b 0a  izeof(pcache));.
44e0: 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20  }../*.** Return 
44f0: 74 68 65 20 73 69 7a 65 20 69 6e 20 62 79 74 65  the size in byte
4500: 73 20 6f 66 20 61 20 50 43 61 63 68 65 20 6f 62  s of a PCache ob
4510: 6a 65 63 74 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c  ject..*/.int sql
4520: 69 74 65 33 50 63 61 63 68 65 53 69 7a 65 28 76  ite3PcacheSize(v
4530: 6f 69 64 29 7b 20 72 65 74 75 72 6e 20 73 69 7a  oid){ return siz
4540: 65 6f 66 28 50 43 61 63 68 65 29 3b 20 7d 0a 0a  eof(PCache); }..
4550: 2f 2a 0a 2a 2a 20 43 72 65 61 74 65 20 61 20 6e  /*.** Create a n
4560: 65 77 20 50 43 61 63 68 65 20 6f 62 6a 65 63 74  ew PCache object
4570: 2e 20 20 53 74 6f 72 61 67 65 20 73 70 61 63 65  .  Storage space
4580: 20 74 6f 20 68 6f 6c 64 20 74 68 65 20 6f 62 6a   to hold the obj
4590: 65 63 74 0a 2a 2a 20 68 61 73 20 61 6c 72 65 61  ect.** has alrea
45a0: 64 79 20 62 65 65 6e 20 61 6c 6c 6f 63 61 74 65  dy been allocate
45b0: 64 20 61 6e 64 20 69 73 20 70 61 73 73 65 64 20  d and is passed 
45c0: 69 6e 20 61 73 20 74 68 65 20 70 20 70 6f 69 6e  in as the p poin
45d0: 74 65 72 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c  ter..*/.void sql
45e0: 69 74 65 33 50 63 61 63 68 65 4f 70 65 6e 28 0a  ite3PcacheOpen(.
45f0: 20 20 69 6e 74 20 73 7a 50 61 67 65 2c 20 20 20    int szPage,   
4600: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
4610: 2a 20 53 69 7a 65 20 6f 66 20 65 76 65 72 79 20  * Size of every 
4620: 70 61 67 65 20 2a 2f 0a 20 20 69 6e 74 20 73 7a  page */.  int sz
4630: 45 78 74 72 61 2c 20 20 20 20 20 20 20 20 20 20  Extra,          
4640: 20 20 20 20 20 20 20 2f 2a 20 45 78 74 72 61 20         /* Extra 
4650: 73 70 61 63 65 20 61 73 73 6f 63 69 61 74 65 64  space associated
4660: 20 77 69 74 68 20 65 61 63 68 20 70 61 67 65 20   with each page 
4670: 2a 2f 0a 20 20 69 6e 74 20 62 50 75 72 67 65 61  */.  int bPurgea
4680: 62 6c 65 2c 20 20 20 20 20 20 20 20 20 20 20 20  ble,            
4690: 20 20 2f 2a 20 54 72 75 65 20 69 66 20 70 61 67    /* True if pag
46a0: 65 73 20 61 72 65 20 6f 6e 20 62 61 63 6b 69 6e  es are on backin
46b0: 67 20 73 74 6f 72 65 20 2a 2f 0a 20 20 76 6f 69  g store */.  voi
46c0: 64 20 28 2a 78 44 65 73 74 72 6f 79 29 28 50 67  d (*xDestroy)(Pg
46d0: 48 64 72 2a 29 2c 20 20 20 20 2f 2a 20 43 61 6c  Hdr*),    /* Cal
46e0: 6c 65 64 20 74 6f 20 64 65 73 74 72 6f 79 20 61  led to destroy a
46f0: 20 70 61 67 65 20 2a 2f 0a 20 20 69 6e 74 20 28   page */.  int (
4700: 2a 78 53 74 72 65 73 73 29 28 76 6f 69 64 2a 2c  *xStress)(void*,
4710: 50 67 48 64 72 2a 29 2c 2f 2a 20 43 61 6c 6c 20  PgHdr*),/* Call 
4720: 74 6f 20 74 72 79 20 74 6f 20 6d 61 6b 65 20 70  to try to make p
4730: 61 67 65 73 20 63 6c 65 61 6e 20 2a 2f 0a 20 20  ages clean */.  
4740: 76 6f 69 64 20 2a 70 53 74 72 65 73 73 2c 20 20  void *pStress,  
4750: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
4760: 41 72 67 75 6d 65 6e 74 20 74 6f 20 78 53 74 72  Argument to xStr
4770: 65 73 73 20 2a 2f 0a 20 20 50 43 61 63 68 65 20  ess */.  PCache 
4780: 2a 70 20 20 20 20 20 20 20 20 20 20 20 20 20 20  *p              
4790: 20 20 20 20 20 20 2f 2a 20 50 72 65 61 6c 6c 6f        /* Preallo
47a0: 63 61 74 65 64 20 73 70 61 63 65 20 66 6f 72 20  cated space for 
47b0: 74 68 65 20 50 43 61 63 68 65 20 2a 2f 0a 29 7b  the PCache */.){
47c0: 0a 20 20 61 73 73 65 72 74 28 20 70 63 61 63 68  .  assert( pcach
47d0: 65 2e 69 73 49 6e 69 74 20 29 3b 0a 20 20 6d 65  e.isInit );.  me
47e0: 6d 73 65 74 28 70 2c 20 30 2c 20 73 69 7a 65 6f  mset(p, 0, sizeo
47f0: 66 28 50 43 61 63 68 65 29 29 3b 0a 20 20 70 2d  f(PCache));.  p-
4800: 3e 73 7a 50 61 67 65 20 3d 20 73 7a 50 61 67 65  >szPage = szPage
4810: 3b 0a 20 20 70 2d 3e 73 7a 45 78 74 72 61 20 3d  ;.  p->szExtra =
4820: 20 73 7a 45 78 74 72 61 3b 0a 20 20 70 2d 3e 62   szExtra;.  p->b
4830: 50 75 72 67 65 61 62 6c 65 20 3d 20 62 50 75 72  Purgeable = bPur
4840: 67 65 61 62 6c 65 3b 0a 20 20 70 2d 3e 78 44 65  geable;.  p->xDe
4850: 73 74 72 6f 79 20 3d 20 78 44 65 73 74 72 6f 79  stroy = xDestroy
4860: 3b 0a 20 20 70 2d 3e 78 53 74 72 65 73 73 20 3d  ;.  p->xStress =
4870: 20 78 53 74 72 65 73 73 3b 0a 20 20 70 2d 3e 70   xStress;.  p->p
4880: 53 74 72 65 73 73 20 3d 20 70 53 74 72 65 73 73  Stress = pStress
4890: 3b 0a 20 20 70 2d 3e 6e 4d 61 78 20 3d 20 31 30  ;.  p->nMax = 10
48a0: 30 3b 0a 0a 20 20 69 66 28 20 62 50 75 72 67 65  0;..  if( bPurge
48b0: 61 62 6c 65 20 29 7b 0a 20 20 20 20 70 63 61 63  able ){.    pcac
48c0: 68 65 45 6e 74 65 72 47 6c 6f 62 61 6c 28 29 3b  heEnterGlobal();
48d0: 0a 20 20 20 20 70 63 61 63 68 65 2e 6d 78 50 61  .    pcache.mxPa
48e0: 67 65 50 75 72 67 65 61 62 6c 65 20 2b 3d 20 70  gePurgeable += p
48f0: 2d 3e 6e 4d 61 78 3b 0a 20 20 20 20 70 63 61 63  ->nMax;.    pcac
4900: 68 65 45 78 69 74 47 6c 6f 62 61 6c 28 29 3b 0a  heExitGlobal();.
4910: 20 20 7d 0a 0a 20 20 2f 2a 20 41 64 64 20 74 68    }..  /* Add th
4920: 65 20 6e 65 77 20 70 61 67 65 72 2d 63 61 63 68  e new pager-cach
4930: 65 20 74 6f 20 74 68 65 20 6c 69 73 74 20 6f 66  e to the list of
4940: 20 63 61 63 68 65 73 20 73 74 61 72 74 69 6e 67   caches starting
4950: 20 61 74 20 70 63 61 63 68 65 2e 70 41 6c 6c 20   at pcache.pAll 
4960: 2a 2f 0a 20 20 70 63 61 63 68 65 45 6e 74 65 72  */.  pcacheEnter
4970: 47 6c 6f 62 61 6c 28 29 3b 0a 20 20 70 2d 3e 70  Global();.  p->p
4980: 4e 65 78 74 41 6c 6c 20 3d 20 70 63 61 63 68 65  NextAll = pcache
4990: 2e 70 41 6c 6c 3b 0a 20 20 69 66 28 20 70 63 61  .pAll;.  if( pca
49a0: 63 68 65 2e 70 41 6c 6c 20 29 7b 0a 20 20 20 20  che.pAll ){.    
49b0: 70 63 61 63 68 65 2e 70 41 6c 6c 2d 3e 70 50 72  pcache.pAll->pPr
49c0: 65 76 41 6c 6c 20 3d 20 70 3b 0a 20 20 7d 0a 20  evAll = p;.  }. 
49d0: 20 70 2d 3e 70 50 72 65 76 41 6c 6c 20 3d 20 30   p->pPrevAll = 0
49e0: 3b 0a 20 20 70 63 61 63 68 65 2e 70 41 6c 6c 20  ;.  pcache.pAll 
49f0: 3d 20 70 3b 0a 20 20 70 63 61 63 68 65 45 78 69  = p;.  pcacheExi
4a00: 74 47 6c 6f 62 61 6c 28 29 3b 0a 7d 0a 0a 2f 2a  tGlobal();.}../*
4a10: 0a 2a 2a 20 43 68 61 6e 67 65 20 74 68 65 20 70  .** Change the p
4a20: 61 67 65 20 73 69 7a 65 20 66 6f 72 20 50 43 61  age size for PCa
4a30: 63 68 65 20 6f 62 6a 65 63 74 2e 20 20 54 68 69  che object.  Thi
4a40: 73 20 63 61 6e 20 6f 6e 6c 79 20 68 61 70 70 65  s can only happe
4a50: 6e 0a 2a 2a 20 77 68 65 6e 20 74 68 65 20 63 61  n.** when the ca
4a60: 63 68 65 20 69 73 20 65 6d 70 74 79 2e 0a 2a 2f  che is empty..*/
4a70: 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63 61  .void sqlite3Pca
4a80: 63 68 65 53 65 74 50 61 67 65 53 69 7a 65 28 50  cheSetPageSize(P
4a90: 43 61 63 68 65 20 2a 70 43 61 63 68 65 2c 20 69  Cache *pCache, i
4aa0: 6e 74 20 73 7a 50 61 67 65 29 7b 0a 20 20 61 73  nt szPage){.  as
4ab0: 73 65 72 74 28 70 43 61 63 68 65 2d 3e 6e 50 61  sert(pCache->nPa
4ac0: 67 65 3d 3d 30 29 3b 0a 20 20 70 43 61 63 68 65  ge==0);.  pCache
4ad0: 2d 3e 73 7a 50 61 67 65 20 3d 20 73 7a 50 61 67  ->szPage = szPag
4ae0: 65 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 72 79 20  e;.}../*.** Try 
4af0: 74 6f 20 6f 62 74 61 69 6e 20 61 20 70 61 67 65  to obtain a page
4b00: 20 66 72 6f 6d 20 74 68 65 20 63 61 63 68 65 2e   from the cache.
4b10: 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 50  .*/.int sqlite3P
4b20: 63 61 63 68 65 46 65 74 63 68 28 0a 20 20 50 43  cacheFetch(.  PC
4b30: 61 63 68 65 20 2a 70 43 61 63 68 65 2c 20 20 20  ache *pCache,   
4b40: 20 20 20 20 2f 2a 20 4f 62 74 61 69 6e 20 74 68      /* Obtain th
4b50: 65 20 70 61 67 65 20 66 72 6f 6d 20 74 68 69 73  e page from this
4b60: 20 63 61 63 68 65 20 2a 2f 0a 20 20 50 67 6e 6f   cache */.  Pgno
4b70: 20 70 67 6e 6f 2c 20 20 20 20 20 20 20 20 20 20   pgno,          
4b80: 20 20 2f 2a 20 50 61 67 65 20 6e 75 6d 62 65 72    /* Page number
4b90: 20 74 6f 20 6f 62 74 61 69 6e 20 2a 2f 0a 20 20   to obtain */.  
4ba0: 69 6e 74 20 63 72 65 61 74 65 46 6c 61 67 2c 20  int createFlag, 
4bb0: 20 20 20 20 20 20 2f 2a 20 49 66 20 74 72 75 65        /* If true
4bc0: 2c 20 63 72 65 61 74 65 20 70 61 67 65 20 69 66  , create page if
4bd0: 20 69 74 20 64 6f 65 73 20 6e 6f 74 20 65 78 69   it does not exi
4be0: 73 74 20 61 6c 72 65 61 64 79 20 2a 2f 0a 20 20  st already */.  
4bf0: 50 67 48 64 72 20 2a 2a 70 70 50 61 67 65 20 20  PgHdr **ppPage  
4c00: 20 20 20 20 20 20 2f 2a 20 57 72 69 74 65 20 74        /* Write t
4c10: 68 65 20 70 61 67 65 20 68 65 72 65 20 2a 2f 0a  he page here */.
4c20: 29 7b 0a 20 20 50 67 48 64 72 20 2a 70 50 61 67  ){.  PgHdr *pPag
4c30: 65 3b 0a 20 20 61 73 73 65 72 74 28 20 70 63 61  e;.  assert( pca
4c40: 63 68 65 2e 69 73 49 6e 69 74 20 29 3b 0a 20 20  che.isInit );.  
4c50: 61 73 73 65 72 74 28 20 70 43 61 63 68 65 21 3d  assert( pCache!=
4c60: 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70  0 );.  assert( p
4c70: 67 6e 6f 3e 30 20 29 3b 0a 20 20 61 73 73 65 72  gno>0 );.  asser
4c80: 74 28 20 70 43 61 63 68 65 2d 3e 69 49 6e 55 73  t( pCache->iInUs
4c90: 65 44 42 20 7c 7c 20 70 43 61 63 68 65 2d 3e 69  eDB || pCache->i
4ca0: 49 6e 55 73 65 4d 4d 20 29 3b 0a 0a 20 20 2f 2a  InUseMM );..  /*
4cb0: 20 53 65 61 72 63 68 20 74 68 65 20 68 61 73 68   Search the hash
4cc0: 20 74 61 62 6c 65 20 66 6f 72 20 74 68 65 20 72   table for the r
4cd0: 65 71 75 65 73 74 65 64 20 70 61 67 65 2e 20 45  equested page. E
4ce0: 78 69 74 20 65 61 72 6c 79 20 69 66 20 69 74 20  xit early if it 
4cf0: 69 73 20 66 6f 75 6e 64 2e 20 2a 2f 0a 20 20 69  is found. */.  i
4d00: 66 28 20 70 43 61 63 68 65 2d 3e 61 70 48 61 73  f( pCache->apHas
4d10: 68 20 29 7b 0a 20 20 20 20 75 33 32 20 68 20 3d  h ){.    u32 h =
4d20: 20 70 67 6e 6f 20 25 20 70 43 61 63 68 65 2d 3e   pgno % pCache->
4d30: 6e 48 61 73 68 3b 0a 20 20 20 20 66 6f 72 28 70  nHash;.    for(p
4d40: 50 61 67 65 3d 70 43 61 63 68 65 2d 3e 61 70 48  Page=pCache->apH
4d50: 61 73 68 5b 68 5d 3b 20 70 50 61 67 65 3b 20 70  ash[h]; pPage; p
4d60: 50 61 67 65 3d 70 50 61 67 65 2d 3e 70 4e 65 78  Page=pPage->pNex
4d70: 74 48 61 73 68 29 7b 0a 20 20 20 20 20 20 69 66  tHash){.      if
4d80: 28 20 70 50 61 67 65 2d 3e 70 67 6e 6f 3d 3d 70  ( pPage->pgno==p
4d90: 67 6e 6f 20 29 7b 0a 20 20 20 20 20 20 20 20 69  gno ){.        i
4da0: 66 28 20 70 50 61 67 65 2d 3e 6e 52 65 66 3d 3d  f( pPage->nRef==
4db0: 30 20 2f 2a 20 26 26 20 28 70 50 61 67 65 2d 3e  0 /* && (pPage->
4dc0: 66 6c 61 67 73 20 26 20 50 47 48 44 52 5f 44 49  flags & PGHDR_DI
4dd0: 52 54 59 29 3d 3d 30 20 2a 2f 20 29 7b 0a 20 20  RTY)==0 */ ){.  
4de0: 20 20 20 20 20 20 20 20 70 63 61 63 68 65 45 6e          pcacheEn
4df0: 74 65 72 47 6c 6f 62 61 6c 28 29 3b 0a 20 20 20  terGlobal();.   
4e00: 20 20 20 20 20 20 20 70 63 61 63 68 65 52 65 6d         pcacheRem
4e10: 6f 76 65 46 72 6f 6d 4c 72 75 4c 69 73 74 28 70  oveFromLruList(p
4e20: 50 61 67 65 29 3b 0a 20 20 20 20 20 20 20 20 20  Page);.         
4e30: 20 70 63 61 63 68 65 45 78 69 74 47 6c 6f 62 61   pcacheExitGloba
4e40: 6c 28 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  l();.        }. 
4e50: 20 20 20 20 20 20 20 70 63 61 63 68 65 52 65 66         pcacheRef
4e60: 28 70 50 61 67 65 2c 20 31 29 3b 0a 20 20 20 20  (pPage, 1);.    
4e70: 20 20 20 20 2a 70 70 50 61 67 65 20 3d 20 70 50      *ppPage = pP
4e80: 61 67 65 3b 0a 20 20 20 20 20 20 20 20 72 65 74  age;.        ret
4e90: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  urn SQLITE_OK;. 
4ea0: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d       }.    }.  }
4eb0: 0a 0a 20 20 69 66 28 20 63 72 65 61 74 65 46 6c  ..  if( createFl
4ec0: 61 67 20 29 7b 0a 20 20 20 20 69 66 28 20 70 43  ag ){.    if( pC
4ed0: 61 63 68 65 2d 3e 6e 48 61 73 68 3c 3d 70 43 61  ache->nHash<=pCa
4ee0: 63 68 65 2d 3e 6e 50 61 67 65 20 29 7b 0a 20 20  che->nPage ){.  
4ef0: 20 20 20 20 69 6e 74 20 72 63 20 3d 20 70 63 61      int rc = pca
4f00: 63 68 65 52 65 73 69 7a 65 48 61 73 68 28 70 43  cheResizeHash(pC
4f10: 61 63 68 65 2c 20 70 43 61 63 68 65 2d 3e 6e 48  ache, pCache->nH
4f20: 61 73 68 3c 32 35 36 3f 32 35 36 3a 70 43 61 63  ash<256?256:pCac
4f30: 68 65 2d 3e 6e 48 61 73 68 2a 32 29 3b 0a 20 20  he->nHash*2);.  
4f40: 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
4f50: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20  TE_OK ){.       
4f60: 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20   return rc;.    
4f70: 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 70    }.    }..    p
4f80: 50 61 67 65 20 3d 20 70 63 61 63 68 65 52 65 63  Page = pcacheRec
4f90: 79 63 6c 65 4f 72 41 6c 6c 6f 63 28 70 43 61 63  ycleOrAlloc(pCac
4fa0: 68 65 29 3b 0a 20 20 20 20 2a 70 70 50 61 67 65  he);.    *ppPage
4fb0: 20 3d 20 70 50 61 67 65 3b 0a 20 20 20 20 69 66   = pPage;.    if
4fc0: 28 20 70 50 61 67 65 3d 3d 30 20 29 7b 0a 20 20  ( pPage==0 ){.  
4fd0: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
4fe0: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 0a  E_NOMEM;.    }..
4ff0: 20 20 20 20 70 50 61 67 65 2d 3e 70 50 61 67 65      pPage->pPage
5000: 72 20 3d 20 30 3b 0a 20 20 20 20 70 50 61 67 65  r = 0;.    pPage
5010: 2d 3e 66 6c 61 67 73 20 3d 20 30 3b 0a 20 20 20  ->flags = 0;.   
5020: 20 70 50 61 67 65 2d 3e 70 44 69 72 74 79 20 3d   pPage->pDirty =
5030: 20 30 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 6e   0;.    pPage->n
5040: 52 65 66 20 3d 20 30 3b 0a 20 20 20 20 70 50 61  Ref = 0;.    pPa
5050: 67 65 2d 3e 70 67 6e 6f 20 3d 20 70 67 6e 6f 3b  ge->pgno = pgno;
5060: 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 43 61 63  .    pPage->pCac
5070: 68 65 20 3d 20 70 43 61 63 68 65 3b 0a 20 20 20  he = pCache;.   
5080: 20 70 63 61 63 68 65 52 65 66 28 70 50 61 67 65   pcacheRef(pPage
5090: 2c 20 31 29 3b 0a 20 20 20 20 70 63 61 63 68 65  , 1);.    pcache
50a0: 41 64 64 54 6f 4c 69 73 74 28 26 70 43 61 63 68  AddToList(&pCach
50b0: 65 2d 3e 70 43 6c 65 61 6e 2c 20 70 50 61 67 65  e->pClean, pPage
50c0: 29 3b 0a 20 20 20 20 70 63 61 63 68 65 41 64 64  );.    pcacheAdd
50d0: 54 6f 48 61 73 68 28 70 50 61 67 65 29 3b 0a 20  ToHash(pPage);. 
50e0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 2a 70 70 50   }else{.    *ppP
50f0: 61 67 65 20 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20  age = 0;.  }..  
5100: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
5110: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65 72 65 66  ;.}../*.** Deref
5120: 65 72 65 6e 63 65 20 61 20 70 61 67 65 2e 20 20  erence a page.  
5130: 57 68 65 6e 20 74 68 65 20 72 65 66 65 72 65 6e  When the referen
5140: 63 65 20 63 6f 75 6e 74 20 72 65 61 63 68 65 73  ce count reaches
5150: 20 7a 65 72 6f 2c 0a 2a 2a 20 6d 6f 76 65 20 74   zero,.** move t
5160: 68 65 20 70 61 67 65 20 74 6f 20 74 68 65 20 4c  he page to the L
5170: 52 55 20 6c 69 73 74 20 69 66 20 69 74 20 69 73  RU list if it is
5180: 20 63 6c 65 61 6e 2e 0a 2a 2f 0a 76 6f 69 64 20   clean..*/.void 
5190: 73 71 6c 69 74 65 33 50 63 61 63 68 65 52 65 6c  sqlite3PcacheRel
51a0: 65 61 73 65 28 50 67 48 64 72 20 2a 70 29 7b 0a  ease(PgHdr *p){.
51b0: 20 20 61 73 73 65 72 74 28 20 70 2d 3e 6e 52 65    assert( p->nRe
51c0: 66 3e 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28  f>0 );.  assert(
51d0: 20 70 2d 3e 70 43 61 63 68 65 2d 3e 69 49 6e 55   p->pCache->iInU
51e0: 73 65 44 42 20 7c 7c 20 70 2d 3e 70 43 61 63 68  seDB || p->pCach
51f0: 65 2d 3e 69 49 6e 55 73 65 4d 4d 20 29 3b 0a 20  e->iInUseMM );. 
5200: 20 70 63 61 63 68 65 52 65 66 28 70 2c 20 2d 31   pcacheRef(p, -1
5210: 29 3b 0a 20 20 69 66 28 20 70 2d 3e 6e 52 65 66  );.  if( p->nRef
5220: 21 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a 20 20  !=0 ) return;.  
5230: 69 66 28 20 70 2d 3e 70 43 61 63 68 65 2d 3e 78  if( p->pCache->x
5240: 44 65 73 74 72 6f 79 20 29 7b 0a 20 20 20 20 70  Destroy ){.    p
5250: 2d 3e 70 43 61 63 68 65 2d 3e 78 44 65 73 74 72  ->pCache->xDestr
5260: 6f 79 28 70 29 3b 0a 20 20 7d 0a 23 69 66 20 30  oy(p);.  }.#if 0
5270: 0a 20 20 69 66 28 20 28 70 2d 3e 66 6c 61 67 73  .  if( (p->flags
5280: 20 26 20 50 47 48 44 52 5f 44 49 52 54 59 29 21   & PGHDR_DIRTY)!
5290: 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a 23 65 6e  =0 ) return;.#en
52a0: 64 69 66 0a 20 20 70 63 61 63 68 65 45 6e 74 65  dif.  pcacheEnte
52b0: 72 47 6c 6f 62 61 6c 28 29 3b 0a 20 20 70 63 61  rGlobal();.  pca
52c0: 63 68 65 41 64 64 54 6f 4c 72 75 4c 69 73 74 28  cheAddToLruList(
52d0: 70 29 3b 0a 20 20 70 63 61 63 68 65 45 78 69 74  p);.  pcacheExit
52e0: 47 6c 6f 62 61 6c 28 29 3b 0a 7d 0a 0a 76 6f 69  Global();.}..voi
52f0: 64 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 52  d sqlite3PcacheR
5300: 65 66 28 50 67 48 64 72 20 2a 70 29 7b 0a 20 20  ef(PgHdr *p){.  
5310: 61 73 73 65 72 74 28 70 2d 3e 6e 52 65 66 3e 3d  assert(p->nRef>=
5320: 30 29 3b 0a 20 20 70 63 61 63 68 65 52 65 66 28  0);.  pcacheRef(
5330: 70 2c 20 31 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  p, 1);.}../*.** 
5340: 44 72 6f 70 20 61 20 70 61 67 65 20 66 72 6f 6d  Drop a page from
5350: 20 74 68 65 20 63 61 63 68 65 2e 20 20 54 68 69   the cache.  Thi
5360: 73 20 73 68 6f 75 6c 64 20 62 65 20 74 68 65 20  s should be the 
5370: 6f 6e 6c 79 20 72 65 66 65 72 65 6e 63 65 20 74  only reference t
5380: 6f 0a 2a 2a 20 74 68 65 20 70 61 67 65 2e 0a 2a  o.** the page..*
5390: 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63  /.void sqlite3Pc
53a0: 61 63 68 65 44 72 6f 70 28 50 67 48 64 72 20 2a  acheDrop(PgHdr *
53b0: 70 29 7b 0a 20 20 50 43 61 63 68 65 20 2a 70 43  p){.  PCache *pC
53c0: 61 63 68 65 3b 0a 20 20 61 73 73 65 72 74 28 20  ache;.  assert( 
53d0: 70 2d 3e 70 43 61 63 68 65 2d 3e 69 49 6e 55 73  p->pCache->iInUs
53e0: 65 44 42 20 29 3b 0a 20 20 61 73 73 65 72 74 28  eDB );.  assert(
53f0: 20 70 2d 3e 6e 52 65 66 3d 3d 31 20 29 3b 0a 20   p->nRef==1 );. 
5400: 20 70 43 61 63 68 65 20 3d 20 70 2d 3e 70 43 61   pCache = p->pCa
5410: 63 68 65 3b 0a 20 20 70 43 61 63 68 65 2d 3e 6e  che;.  pCache->n
5420: 52 65 66 2d 2d 3b 0a 20 20 69 66 28 20 70 2d 3e  Ref--;.  if( p->
5430: 66 6c 61 67 73 20 26 20 50 47 48 44 52 5f 44 49  flags & PGHDR_DI
5440: 52 54 59 20 29 7b 0a 20 20 20 20 70 63 61 63 68  RTY ){.    pcach
5450: 65 52 65 6d 6f 76 65 46 72 6f 6d 4c 69 73 74 28  eRemoveFromList(
5460: 26 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 2c  &pCache->pDirty,
5470: 20 70 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20   p);.  }else{.  
5480: 20 20 70 63 61 63 68 65 52 65 6d 6f 76 65 46 72    pcacheRemoveFr
5490: 6f 6d 4c 69 73 74 28 26 70 43 61 63 68 65 2d 3e  omList(&pCache->
54a0: 70 43 6c 65 61 6e 2c 20 70 29 3b 0a 20 20 7d 0a  pClean, p);.  }.
54b0: 20 20 70 63 61 63 68 65 52 65 6d 6f 76 65 46 72    pcacheRemoveFr
54c0: 6f 6d 48 61 73 68 28 70 29 3b 0a 20 20 70 63 61  omHash(p);.  pca
54d0: 63 68 65 45 6e 74 65 72 47 6c 6f 62 61 6c 28 29  cheEnterGlobal()
54e0: 3b 0a 20 20 70 63 61 63 68 65 50 61 67 65 46 72  ;.  pcachePageFr
54f0: 65 65 28 70 29 3b 0a 20 20 70 63 61 63 68 65 45  ee(p);.  pcacheE
5500: 78 69 74 47 6c 6f 62 61 6c 28 29 3b 0a 7d 0a 0a  xitGlobal();.}..
5510: 2f 2a 0a 2a 2a 20 4d 61 6b 65 20 73 75 72 65 20  /*.** Make sure 
5520: 74 68 65 20 70 61 67 65 20 69 73 20 6d 61 72 6b  the page is mark
5530: 65 64 20 61 73 20 64 69 72 74 79 2e 20 20 49 66  ed as dirty.  If
5540: 20 69 74 20 69 73 6e 27 74 20 64 69 72 74 79 20   it isn't dirty 
5550: 61 6c 72 65 61 64 79 2c 0a 2a 2a 20 6d 61 6b 65  already,.** make
5560: 20 69 74 20 73 6f 2e 0a 2a 2f 0a 76 6f 69 64 20   it so..*/.void 
5570: 73 71 6c 69 74 65 33 50 63 61 63 68 65 4d 61 6b  sqlite3PcacheMak
5580: 65 44 69 72 74 79 28 50 67 48 64 72 20 2a 70 29  eDirty(PgHdr *p)
5590: 7b 0a 20 20 50 43 61 63 68 65 20 2a 70 43 61 63  {.  PCache *pCac
55a0: 68 65 3b 0a 20 20 61 73 73 65 72 74 28 20 70 2d  he;.  assert( p-
55b0: 3e 70 43 61 63 68 65 2d 3e 69 49 6e 55 73 65 44  >pCache->iInUseD
55c0: 42 20 29 3b 0a 20 20 69 66 28 20 70 2d 3e 66 6c  B );.  if( p->fl
55d0: 61 67 73 20 26 20 50 47 48 44 52 5f 44 49 52 54  ags & PGHDR_DIRT
55e0: 59 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 61 73  Y ) return;.  as
55f0: 73 65 72 74 28 20 28 70 2d 3e 66 6c 61 67 73 20  sert( (p->flags 
5600: 26 20 50 47 48 44 52 5f 44 49 52 54 59 29 3d 3d  & PGHDR_DIRTY)==
5610: 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70  0 );.  assert( p
5620: 2d 3e 6e 52 65 66 3e 30 20 29 3b 0a 20 20 70 43  ->nRef>0 );.  pC
5630: 61 63 68 65 20 3d 20 70 2d 3e 70 43 61 63 68 65  ache = p->pCache
5640: 3b 0a 20 20 70 63 61 63 68 65 52 65 6d 6f 76 65  ;.  pcacheRemove
5650: 46 72 6f 6d 4c 69 73 74 28 26 70 43 61 63 68 65  FromList(&pCache
5660: 2d 3e 70 43 6c 65 61 6e 2c 20 70 29 3b 0a 20 20  ->pClean, p);.  
5670: 70 63 61 63 68 65 41 64 64 54 6f 4c 69 73 74 28  pcacheAddToList(
5680: 26 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 2c  &pCache->pDirty,
5690: 20 70 29 3b 0a 20 20 70 2d 3e 66 6c 61 67 73 20   p);.  p->flags 
56a0: 7c 3d 20 50 47 48 44 52 5f 44 49 52 54 59 3b 0a  |= PGHDR_DIRTY;.
56b0: 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6b 65 20 73 75  }../*.** Make su
56c0: 72 65 20 74 68 65 20 70 61 67 65 20 69 73 20 6d  re the page is m
56d0: 61 72 6b 65 64 20 61 73 20 63 6c 65 61 6e 2e 20  arked as clean. 
56e0: 20 49 66 20 69 74 20 69 73 6e 27 74 20 63 6c 65   If it isn't cle
56f0: 61 6e 20 61 6c 72 65 61 64 79 2c 0a 2a 2a 20 6d  an already,.** m
5700: 61 6b 65 20 69 74 20 73 6f 2e 0a 2a 2f 0a 76 6f  ake it so..*/.vo
5710: 69 64 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  id sqlite3Pcache
5720: 4d 61 6b 65 43 6c 65 61 6e 28 50 67 48 64 72 20  MakeClean(PgHdr 
5730: 2a 70 29 7b 0a 20 20 50 43 61 63 68 65 20 2a 70  *p){.  PCache *p
5740: 43 61 63 68 65 3b 0a 20 20 61 73 73 65 72 74 28  Cache;.  assert(
5750: 20 70 2d 3e 70 43 61 63 68 65 2d 3e 69 49 6e 55   p->pCache->iInU
5760: 73 65 44 42 20 7c 7c 20 70 2d 3e 70 43 61 63 68  seDB || p->pCach
5770: 65 2d 3e 69 49 6e 55 73 65 4d 4d 20 29 3b 0a 20  e->iInUseMM );. 
5780: 20 69 66 28 20 28 70 2d 3e 66 6c 61 67 73 20 26   if( (p->flags &
5790: 20 50 47 48 44 52 5f 44 49 52 54 59 29 3d 3d 30   PGHDR_DIRTY)==0
57a0: 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 61 73 73   ) return;.  ass
57b0: 65 72 74 28 20 70 2d 3e 61 70 53 61 76 65 5b 30  ert( p->apSave[0
57c0: 5d 3d 3d 30 20 26 26 20 70 2d 3e 61 70 53 61 76  ]==0 && p->apSav
57d0: 65 5b 31 5d 3d 3d 30 20 29 3b 0a 20 20 61 73 73  e[1]==0 );.  ass
57e0: 65 72 74 28 20 70 2d 3e 66 6c 61 67 73 20 26 20  ert( p->flags & 
57f0: 50 47 48 44 52 5f 44 49 52 54 59 20 29 3b 0a 20  PGHDR_DIRTY );. 
5800: 20 70 43 61 63 68 65 20 3d 20 70 2d 3e 70 43 61   pCache = p->pCa
5810: 63 68 65 3b 0a 20 20 70 63 61 63 68 65 52 65 6d  che;.  pcacheRem
5820: 6f 76 65 46 72 6f 6d 4c 69 73 74 28 26 70 43 61  oveFromList(&pCa
5830: 63 68 65 2d 3e 70 44 69 72 74 79 2c 20 70 29 3b  che->pDirty, p);
5840: 0a 20 20 70 63 61 63 68 65 41 64 64 54 6f 4c 69  .  pcacheAddToLi
5850: 73 74 28 26 70 43 61 63 68 65 2d 3e 70 43 6c 65  st(&pCache->pCle
5860: 61 6e 2c 20 70 29 3b 0a 20 20 70 2d 3e 66 6c 61  an, p);.  p->fla
5870: 67 73 20 26 3d 20 7e 50 47 48 44 52 5f 44 49 52  gs &= ~PGHDR_DIR
5880: 54 59 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6b  TY;.}../*.** Mak
5890: 65 20 65 76 65 72 79 20 70 61 67 65 20 69 6e 20  e every page in 
58a0: 74 68 65 20 63 61 63 68 65 20 63 6c 65 61 6e 2e  the cache clean.
58b0: 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33  .*/.void sqlite3
58c0: 50 63 61 63 68 65 43 6c 65 61 6e 41 6c 6c 28 50  PcacheCleanAll(P
58d0: 43 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b 0a  Cache *pCache){.
58e0: 20 20 50 67 48 64 72 20 2a 70 3b 0a 20 20 61 73    PgHdr *p;.  as
58f0: 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e 69 49  sert( pCache->iI
5900: 6e 55 73 65 44 42 20 29 3b 0a 20 20 70 63 61 63  nUseDB );.  pcac
5910: 68 65 45 6e 74 65 72 47 6c 6f 62 61 6c 28 29 3b  heEnterGlobal();
5920: 0a 20 20 77 68 69 6c 65 28 20 28 70 20 3d 20 70  .  while( (p = p
5930: 43 61 63 68 65 2d 3e 70 44 69 72 74 79 29 21 3d  Cache->pDirty)!=
5940: 30 20 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28  0 ){.    assert(
5950: 20 70 2d 3e 61 70 53 61 76 65 5b 30 5d 3d 3d 30   p->apSave[0]==0
5960: 20 26 26 20 70 2d 3e 61 70 53 61 76 65 5b 31 5d   && p->apSave[1]
5970: 3d 3d 30 20 29 3b 0a 20 20 20 20 70 63 61 63 68  ==0 );.    pcach
5980: 65 52 65 6d 6f 76 65 46 72 6f 6d 4c 69 73 74 28  eRemoveFromList(
5990: 26 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 2c  &pCache->pDirty,
59a0: 20 70 29 3b 0a 20 20 20 20 70 63 61 63 68 65 41   p);.    pcacheA
59b0: 64 64 54 6f 4c 69 73 74 28 26 70 43 61 63 68 65  ddToList(&pCache
59c0: 2d 3e 70 43 6c 65 61 6e 2c 20 70 29 3b 0a 20 20  ->pClean, p);.  
59d0: 20 20 70 2d 3e 66 6c 61 67 73 20 26 3d 20 7e 50    p->flags &= ~P
59e0: 47 48 44 52 5f 44 49 52 54 59 3b 0a 20 20 7d 0a  GHDR_DIRTY;.  }.
59f0: 20 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 41    sqlite3PcacheA
5a00: 73 73 65 72 74 46 6c 61 67 73 28 70 43 61 63 68  ssertFlags(pCach
5a10: 65 2c 20 30 2c 20 50 47 48 44 52 5f 44 49 52 54  e, 0, PGHDR_DIRT
5a20: 59 29 3b 0a 20 20 70 63 61 63 68 65 45 78 69 74  Y);.  pcacheExit
5a30: 47 6c 6f 62 61 6c 28 29 3b 0a 7d 0a 0a 2f 2a 0a  Global();.}../*.
5a40: 2a 2a 20 43 68 61 6e 67 65 20 74 68 65 20 70 61  ** Change the pa
5a50: 67 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67  ge number of pag
5a60: 65 20 70 20 74 6f 20 6e 65 77 50 67 6e 6f 2e 20  e p to newPgno. 
5a70: 49 66 20 6e 65 77 50 67 6e 6f 20 69 73 20 30 2c  If newPgno is 0,
5a80: 20 74 68 65 6e 20 74 68 65 0a 2a 2a 20 70 61 67   then the.** pag
5a90: 65 20 6f 62 6a 65 63 74 20 69 73 20 61 64 64 65  e object is adde
5aa0: 64 20 74 6f 20 74 68 65 20 63 6c 65 61 6e 2d 6c  d to the clean-l
5ab0: 69 73 74 20 61 6e 64 20 74 68 65 20 50 47 48 44  ist and the PGHD
5ac0: 52 5f 52 45 55 53 45 5f 55 4e 4c 49 4b 45 4c 59  R_REUSE_UNLIKELY
5ad0: 20 0a 2a 2a 20 66 6c 61 67 20 73 65 74 2e 0a 2a   .** flag set..*
5ae0: 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63  /.void sqlite3Pc
5af0: 61 63 68 65 4d 6f 76 65 28 50 67 48 64 72 20 2a  acheMove(PgHdr *
5b00: 70 2c 20 50 67 6e 6f 20 6e 65 77 50 67 6e 6f 29  p, Pgno newPgno)
5b10: 7b 0a 20 20 61 73 73 65 72 74 28 20 70 2d 3e 70  {.  assert( p->p
5b20: 43 61 63 68 65 2d 3e 69 49 6e 55 73 65 44 42 20  Cache->iInUseDB 
5b30: 29 3b 0a 20 20 70 63 61 63 68 65 52 65 6d 6f 76  );.  pcacheRemov
5b40: 65 46 72 6f 6d 48 61 73 68 28 70 29 3b 0a 20 20  eFromHash(p);.  
5b50: 70 2d 3e 70 67 6e 6f 20 3d 20 6e 65 77 50 67 6e  p->pgno = newPgn
5b60: 6f 3b 0a 20 20 69 66 28 20 6e 65 77 50 67 6e 6f  o;.  if( newPgno
5b70: 3d 3d 30 20 29 7b 0a 20 20 20 20 70 2d 3e 66 6c  ==0 ){.    p->fl
5b80: 61 67 73 20 7c 3d 20 50 47 48 44 52 5f 52 45 55  ags |= PGHDR_REU
5b90: 53 45 5f 55 4e 4c 49 4b 45 4c 59 3b 0a 20 20 20  SE_UNLIKELY;.   
5ba0: 20 70 63 61 63 68 65 45 6e 74 65 72 47 6c 6f 62   pcacheEnterGlob
5bb0: 61 6c 28 29 3b 0a 20 20 20 20 70 63 61 63 68 65  al();.    pcache
5bc0: 46 72 65 65 28 70 2d 3e 61 70 53 61 76 65 5b 30  Free(p->apSave[0
5bd0: 5d 29 3b 0a 20 20 20 20 70 63 61 63 68 65 46 72  ]);.    pcacheFr
5be0: 65 65 28 70 2d 3e 61 70 53 61 76 65 5b 31 5d 29  ee(p->apSave[1])
5bf0: 3b 0a 20 20 20 20 70 63 61 63 68 65 45 78 69 74  ;.    pcacheExit
5c00: 47 6c 6f 62 61 6c 28 29 3b 0a 20 20 20 20 70 2d  Global();.    p-
5c10: 3e 61 70 53 61 76 65 5b 30 5d 20 3d 20 30 3b 0a  >apSave[0] = 0;.
5c20: 20 20 20 20 70 2d 3e 61 70 53 61 76 65 5b 31 5d      p->apSave[1]
5c30: 20 3d 20 30 3b 0a 20 20 20 20 73 71 6c 69 74 65   = 0;.    sqlite
5c40: 33 50 63 61 63 68 65 4d 61 6b 65 43 6c 65 61 6e  3PcacheMakeClean
5c50: 28 70 29 3b 0a 20 20 7d 0a 20 20 70 63 61 63 68  (p);.  }.  pcach
5c60: 65 41 64 64 54 6f 48 61 73 68 28 70 29 3b 0a 7d  eAddToHash(p);.}
5c70: 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20 74 68 65 20  ../*.** Set the 
5c80: 67 6c 6f 62 61 6c 20 6d 61 78 69 6d 75 6d 20 6e  global maximum n
5c90: 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 2e 20  umber of pages. 
5ca0: 52 65 74 75 72 6e 20 74 68 65 20 70 72 65 76 69  Return the previ
5cb0: 6f 75 73 20 76 61 6c 75 65 2e 0a 2a 2f 0a 76 6f  ous value..*/.vo
5cc0: 69 64 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  id sqlite3Pcache
5cd0: 47 6c 6f 62 61 6c 4d 61 78 28 69 6e 74 20 6d 78  GlobalMax(int mx
5ce0: 29 7b 0a 20 20 70 63 61 63 68 65 45 6e 74 65 72  ){.  pcacheEnter
5cf0: 47 6c 6f 62 61 6c 28 29 3b 0a 20 20 70 63 61 63  Global();.  pcac
5d00: 68 65 2e 6d 78 50 61 67 65 20 3d 20 6d 78 3b 0a  he.mxPage = mx;.
5d10: 20 20 70 63 61 63 68 65 45 78 69 74 47 6c 6f 62    pcacheExitGlob
5d20: 61 6c 28 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  al();.}../*.** R
5d30: 65 6d 6f 76 65 20 61 6c 6c 20 63 6f 6e 74 65 6e  emove all conten
5d40: 74 20 66 72 6f 6d 20 61 20 70 61 67 65 20 63 61  t from a page ca
5d50: 63 68 65 0a 2a 2f 0a 76 6f 69 64 20 70 63 61 63  che.*/.void pcac
5d60: 68 65 43 6c 65 61 72 28 50 43 61 63 68 65 20 2a  heClear(PCache *
5d70: 70 43 61 63 68 65 29 7b 0a 20 20 50 67 48 64 72  pCache){.  PgHdr
5d80: 20 2a 70 2c 20 2a 70 4e 65 78 74 3b 0a 20 20 61   *p, *pNext;.  a
5d90: 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d  ssert( sqlite3_m
5da0: 75 74 65 78 5f 68 65 6c 64 28 70 63 61 63 68 65  utex_held(pcache
5db0: 2e 6d 75 74 65 78 5f 6c 72 75 29 20 29 3b 0a 20  .mutex_lru) );. 
5dc0: 20 66 6f 72 28 70 3d 70 43 61 63 68 65 2d 3e 70   for(p=pCache->p
5dd0: 43 6c 65 61 6e 3b 20 70 3b 20 70 3d 70 4e 65 78  Clean; p; p=pNex
5de0: 74 29 7b 0a 20 20 20 20 70 4e 65 78 74 20 3d 20  t){.    pNext = 
5df0: 70 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 70 63  p->pNext;.    pc
5e00: 61 63 68 65 52 65 6d 6f 76 65 46 72 6f 6d 4c 72  acheRemoveFromLr
5e10: 75 4c 69 73 74 28 70 29 3b 0a 20 20 20 20 70 63  uList(p);.    pc
5e20: 61 63 68 65 50 61 67 65 46 72 65 65 28 70 29 3b  achePageFree(p);
5e30: 0a 20 20 7d 0a 20 20 66 6f 72 28 70 3d 70 43 61  .  }.  for(p=pCa
5e40: 63 68 65 2d 3e 70 44 69 72 74 79 3b 20 70 3b 20  che->pDirty; p; 
5e50: 70 3d 70 4e 65 78 74 29 7b 0a 20 20 20 20 70 4e  p=pNext){.    pN
5e60: 65 78 74 20 3d 20 70 2d 3e 70 4e 65 78 74 3b 0a  ext = p->pNext;.
5e70: 20 20 20 20 70 63 61 63 68 65 52 65 6d 6f 76 65      pcacheRemove
5e80: 46 72 6f 6d 4c 72 75 4c 69 73 74 28 70 29 3b 0a  FromLruList(p);.
5e90: 20 20 20 20 70 63 61 63 68 65 50 61 67 65 46 72      pcachePageFr
5ea0: 65 65 28 70 29 3b 0a 20 20 7d 0a 20 20 70 43 61  ee(p);.  }.  pCa
5eb0: 63 68 65 2d 3e 70 43 6c 65 61 6e 20 3d 20 30 3b  che->pClean = 0;
5ec0: 0a 20 20 70 43 61 63 68 65 2d 3e 70 44 69 72 74  .  pCache->pDirt
5ed0: 79 20 3d 20 30 3b 0a 20 20 70 43 61 63 68 65 2d  y = 0;.  pCache-
5ee0: 3e 6e 50 61 67 65 20 3d 20 30 3b 0a 20 20 6d 65  >nPage = 0;.  me
5ef0: 6d 73 65 74 28 70 43 61 63 68 65 2d 3e 61 70 48  mset(pCache->apH
5f00: 61 73 68 2c 20 30 2c 20 70 43 61 63 68 65 2d 3e  ash, 0, pCache->
5f10: 6e 48 61 73 68 2a 73 69 7a 65 6f 66 28 70 43 61  nHash*sizeof(pCa
5f20: 63 68 65 2d 3e 61 70 48 61 73 68 5b 30 5d 29 29  che->apHash[0]))
5f30: 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 44 72 6f 70  ;.}.../*.** Drop
5f40: 20 65 76 65 72 79 20 63 61 63 68 65 20 65 6e 74   every cache ent
5f50: 72 79 20 77 68 6f 73 65 20 70 61 67 65 20 6e 75  ry whose page nu
5f60: 6d 62 65 72 20 69 73 20 67 72 65 61 74 65 72 20  mber is greater 
5f70: 74 68 61 6e 20 22 70 67 6e 6f 22 2e 0a 2a 2f 0a  than "pgno"..*/.
5f80: 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63 61 63  void sqlite3Pcac
5f90: 68 65 54 72 75 6e 63 61 74 65 28 50 43 61 63 68  heTruncate(PCach
5fa0: 65 20 2a 70 43 61 63 68 65 2c 20 50 67 6e 6f 20  e *pCache, Pgno 
5fb0: 70 67 6e 6f 29 7b 0a 20 20 50 67 48 64 72 20 2a  pgno){.  PgHdr *
5fc0: 70 2c 20 2a 70 4e 65 78 74 3b 0a 20 20 50 67 48  p, *pNext;.  PgH
5fd0: 64 72 20 2a 70 44 69 72 74 79 20 3d 20 70 43 61  dr *pDirty = pCa
5fe0: 63 68 65 2d 3e 70 44 69 72 74 79 3b 0a 20 20 61  che->pDirty;.  a
5ff0: 73 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e 69  ssert( pCache->i
6000: 49 6e 55 73 65 44 42 20 29 3b 0a 20 20 70 63 61  InUseDB );.  pca
6010: 63 68 65 45 6e 74 65 72 47 6c 6f 62 61 6c 28 29  cheEnterGlobal()
6020: 3b 0a 20 20 66 6f 72 28 70 3d 70 43 61 63 68 65  ;.  for(p=pCache
6030: 2d 3e 70 43 6c 65 61 6e 3b 20 70 7c 7c 70 44 69  ->pClean; p||pDi
6040: 72 74 79 3b 20 70 3d 70 4e 65 78 74 29 7b 0a 20  rty; p=pNext){. 
6050: 20 20 20 69 66 28 20 21 70 20 29 7b 0a 20 20 20     if( !p ){.   
6060: 20 20 20 70 20 3d 20 70 44 69 72 74 79 3b 0a 20     p = pDirty;. 
6070: 20 20 20 20 20 70 44 69 72 74 79 20 3d 20 30 3b       pDirty = 0;
6080: 0a 20 20 20 20 7d 0a 20 20 20 20 70 4e 65 78 74  .    }.    pNext
6090: 20 3d 20 70 2d 3e 70 4e 65 78 74 3b 0a 20 20 20   = p->pNext;.   
60a0: 20 69 66 28 20 70 2d 3e 70 67 6e 6f 3e 70 67 6e   if( p->pgno>pgn
60b0: 6f 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 70  o ){.      if( p
60c0: 2d 3e 6e 52 65 66 3d 3d 30 20 29 7b 0a 20 20 20  ->nRef==0 ){.   
60d0: 20 20 20 20 20 70 63 61 63 68 65 52 65 6d 6f 76       pcacheRemov
60e0: 65 46 72 6f 6d 48 61 73 68 28 70 29 3b 0a 20 20  eFromHash(p);.  
60f0: 20 20 20 20 20 20 69 66 28 20 70 2d 3e 66 6c 61        if( p->fla
6100: 67 73 26 50 47 48 44 52 5f 44 49 52 54 59 20 29  gs&PGHDR_DIRTY )
6110: 7b 0a 20 20 20 20 20 20 20 20 20 20 70 63 61 63  {.          pcac
6120: 68 65 52 65 6d 6f 76 65 46 72 6f 6d 4c 69 73 74  heRemoveFromList
6130: 28 26 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79  (&pCache->pDirty
6140: 2c 20 70 29 3b 0a 20 20 20 20 20 20 20 20 7d 65  , p);.        }e
6150: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 70  lse{.          p
6160: 63 61 63 68 65 52 65 6d 6f 76 65 46 72 6f 6d 4c  cacheRemoveFromL
6170: 69 73 74 28 26 70 43 61 63 68 65 2d 3e 70 43 6c  ist(&pCache->pCl
6180: 65 61 6e 2c 20 70 29 3b 0a 20 20 20 20 20 20 20  ean, p);.       
6190: 20 7d 0a 20 20 20 20 20 20 20 20 70 63 61 63 68   }.        pcach
61a0: 65 52 65 6d 6f 76 65 46 72 6f 6d 4c 72 75 4c 69  eRemoveFromLruLi
61b0: 73 74 28 70 29 3b 0a 20 20 20 20 20 20 20 20 70  st(p);.        p
61c0: 63 61 63 68 65 50 61 67 65 46 72 65 65 28 70 29  cachePageFree(p)
61d0: 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20  ;.      }else{. 
61e0: 20 20 20 20 20 20 20 2f 2a 20 49 66 20 74 68 65         /* If the
61f0: 72 65 20 61 72 65 20 72 65 66 65 72 65 6e 63 65  re are reference
6200: 73 20 74 6f 20 74 68 65 20 70 61 67 65 2c 20 69  s to the page, i
6210: 74 20 63 61 6e 6e 6f 74 20 62 65 20 66 72 65 65  t cannot be free
6220: 64 2e 20 49 6e 20 74 68 69 73 0a 20 20 20 20 20  d. In this.     
6230: 20 20 20 2a 2a 20 63 61 73 65 2c 20 7a 65 72 6f     ** case, zero
6240: 20 74 68 65 20 70 61 67 65 20 63 6f 6e 74 65 6e   the page conten
6250: 74 20 69 6e 73 74 65 61 64 2e 0a 20 20 20 20 20  t instead..     
6260: 20 20 20 2a 2f 0a 20 20 20 20 20 20 20 20 6d 65     */.        me
6270: 6d 73 65 74 28 70 2d 3e 70 44 61 74 61 2c 20 30  mset(p->pData, 0
6280: 2c 20 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65  , pCache->szPage
6290: 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  );.      }.    }
62a0: 0a 20 20 7d 0a 20 20 70 63 61 63 68 65 45 78 69  .  }.  pcacheExi
62b0: 74 47 6c 6f 62 61 6c 28 29 3b 0a 7d 0a 0a 0a 2f  tGlobal();.}.../
62c0: 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61 20 63 61 63  *.** Close a cac
62d0: 68 65 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69  he..*/.void sqli
62e0: 74 65 33 50 63 61 63 68 65 43 6c 6f 73 65 28 50  te3PcacheClose(P
62f0: 43 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b 0a  Cache *pCache){.
6300: 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65    assert( pCache
6310: 2d 3e 69 49 6e 55 73 65 44 42 3d 3d 31 20 29 3b  ->iInUseDB==1 );
6320: 0a 20 20 70 63 61 63 68 65 45 6e 74 65 72 47 6c  .  pcacheEnterGl
6330: 6f 62 61 6c 28 29 3b 0a 0a 20 20 2f 2a 20 46 72  obal();..  /* Fr
6340: 65 65 20 61 6c 6c 20 74 68 65 20 70 61 67 65 73  ee all the pages
6350: 20 75 73 65 64 20 62 79 20 74 68 69 73 20 70 61   used by this pa
6360: 67 65 72 20 61 6e 64 20 72 65 6d 6f 76 65 20 74  ger and remove t
6370: 68 65 6d 20 66 72 6f 6d 20 74 68 65 20 4c 52 55  hem from the LRU
6380: 20 6c 69 73 74 2e 20 2a 2f 0a 20 20 70 63 61 63   list. */.  pcac
6390: 68 65 43 6c 65 61 72 28 70 43 61 63 68 65 29 3b  heClear(pCache);
63a0: 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 62  .  if( pCache->b
63b0: 50 75 72 67 65 61 62 6c 65 20 29 7b 0a 20 20 20  Purgeable ){.   
63c0: 20 70 63 61 63 68 65 2e 6d 78 50 61 67 65 50 75   pcache.mxPagePu
63d0: 72 67 65 61 62 6c 65 20 2d 3d 20 70 43 61 63 68  rgeable -= pCach
63e0: 65 2d 3e 6e 4d 61 78 3b 0a 20 20 7d 0a 20 20 73  e->nMax;.  }.  s
63f0: 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43 61 63  qlite3_free(pCac
6400: 68 65 2d 3e 61 70 48 61 73 68 29 3b 0a 0a 20 20  he->apHash);..  
6410: 2f 2a 20 4e 6f 77 20 72 65 6d 6f 76 65 20 74 68  /* Now remove th
6420: 65 20 70 61 67 65 72 2d 63 61 63 68 65 20 73 74  e pager-cache st
6430: 72 75 63 74 75 72 65 20 69 74 73 65 6c 66 20 66  ructure itself f
6440: 72 6f 6d 20 74 68 65 20 6c 69 73 74 20 6f 66 0a  rom the list of.
6450: 20 20 2a 2a 20 61 6c 6c 20 73 75 63 68 20 73 74    ** all such st
6460: 72 75 63 74 75 72 65 73 20 68 65 61 64 65 64 20  ructures headed 
6470: 62 79 20 70 63 61 63 68 65 2e 70 41 6c 6c 2e 20  by pcache.pAll. 
6480: 0a 20 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 70  .  */.  assert(p
6490: 43 61 63 68 65 3d 3d 70 63 61 63 68 65 2e 70 41  Cache==pcache.pA
64a0: 6c 6c 20 7c 7c 20 70 43 61 63 68 65 2d 3e 70 50  ll || pCache->pP
64b0: 72 65 76 41 6c 6c 29 3b 0a 20 20 61 73 73 65 72  revAll);.  asser
64c0: 74 28 70 43 61 63 68 65 2d 3e 70 4e 65 78 74 41  t(pCache->pNextA
64d0: 6c 6c 3d 3d 30 20 7c 7c 20 70 43 61 63 68 65 2d  ll==0 || pCache-
64e0: 3e 70 4e 65 78 74 41 6c 6c 2d 3e 70 50 72 65 76  >pNextAll->pPrev
64f0: 41 6c 6c 3d 3d 70 43 61 63 68 65 29 3b 0a 20 20  All==pCache);.  
6500: 61 73 73 65 72 74 28 70 43 61 63 68 65 2d 3e 70  assert(pCache->p
6510: 50 72 65 76 41 6c 6c 3d 3d 30 20 7c 7c 20 70 43  PrevAll==0 || pC
6520: 61 63 68 65 2d 3e 70 50 72 65 76 41 6c 6c 2d 3e  ache->pPrevAll->
6530: 70 4e 65 78 74 41 6c 6c 3d 3d 70 43 61 63 68 65  pNextAll==pCache
6540: 29 3b 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d  );.  if( pCache-
6550: 3e 70 50 72 65 76 41 6c 6c 20 29 7b 0a 20 20 20  >pPrevAll ){.   
6560: 20 70 43 61 63 68 65 2d 3e 70 50 72 65 76 41 6c   pCache->pPrevAl
6570: 6c 2d 3e 70 4e 65 78 74 41 6c 6c 20 3d 20 70 43  l->pNextAll = pC
6580: 61 63 68 65 2d 3e 70 4e 65 78 74 41 6c 6c 3b 0a  ache->pNextAll;.
6590: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70 63 61    }else{.    pca
65a0: 63 68 65 2e 70 41 6c 6c 20 3d 20 70 43 61 63 68  che.pAll = pCach
65b0: 65 2d 3e 70 4e 65 78 74 41 6c 6c 3b 0a 20 20 7d  e->pNextAll;.  }
65c0: 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 70  .  if( pCache->p
65d0: 4e 65 78 74 41 6c 6c 20 29 7b 0a 20 20 20 20 70  NextAll ){.    p
65e0: 43 61 63 68 65 2d 3e 70 4e 65 78 74 41 6c 6c 2d  Cache->pNextAll-
65f0: 3e 70 50 72 65 76 41 6c 6c 20 3d 20 70 43 61 63  >pPrevAll = pCac
6600: 68 65 2d 3e 70 50 72 65 76 41 6c 6c 3b 0a 20 20  he->pPrevAll;.  
6610: 7d 0a 0a 20 20 70 63 61 63 68 65 45 78 69 74 47  }..  pcacheExitG
6620: 6c 6f 62 61 6c 28 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  lobal();.}../*.*
6630: 2a 20 50 72 65 73 65 72 76 65 20 74 68 65 20 63  * Preserve the c
6640: 6f 6e 74 65 6e 74 20 6f 66 20 74 68 65 20 70 61  ontent of the pa
6650: 67 65 2c 20 69 66 20 69 74 20 68 61 73 20 6e 6f  ge, if it has no
6660: 74 20 62 65 65 6e 20 70 72 65 73 65 72 76 65 64  t been preserved
6670: 0a 2a 2a 20 61 6c 72 65 61 64 79 2e 20 20 49 66  .** already.  If
6680: 20 69 64 4a 6f 75 72 6e 61 6c 3d 3d 30 20 74 68   idJournal==0 th
6690: 65 6e 20 74 68 69 73 20 69 73 20 66 6f 72 20 74  en this is for t
66a0: 68 65 20 6f 76 65 72 61 6c 6c 20 74 72 61 6e 73  he overall trans
66b0: 61 63 74 69 6f 6e 2e 0a 2a 2a 20 49 66 20 69 64  action..** If id
66c0: 4a 6f 75 72 6e 61 6c 3d 3d 31 20 74 68 65 6e 20  Journal==1 then 
66d0: 74 68 69 73 20 69 73 20 66 6f 72 20 74 68 65 20  this is for the 
66e0: 73 74 61 74 65 6d 65 6e 74 20 6a 6f 75 72 6e 61  statement journa
66f0: 6c 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 72 6f  l..**.** This ro
6700: 75 74 69 6e 65 20 69 73 20 75 73 65 64 20 66 6f  utine is used fo
6710: 72 20 69 6e 2d 6d 65 6d 6f 72 79 20 64 61 74 61  r in-memory data
6720: 62 61 73 65 73 20 6f 6e 6c 79 2e 0a 2a 2a 0a 2a  bases only..**.*
6730: 2a 20 52 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  * Return SQLITE_
6740: 4f 4b 20 6f 72 20 53 51 4c 49 54 45 5f 4e 4f 4d  OK or SQLITE_NOM
6750: 45 4d 20 69 66 20 61 20 6d 65 6d 6f 72 79 20 61  EM if a memory a
6760: 6c 6c 6f 63 61 74 69 6f 6e 20 66 61 69 6c 73 2e  llocation fails.
6770: 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 50  .*/.int sqlite3P
6780: 63 61 63 68 65 50 72 65 73 65 72 76 65 28 50 67  cachePreserve(Pg
6790: 48 64 72 20 2a 70 2c 20 69 6e 74 20 69 64 4a 6f  Hdr *p, int idJo
67a0: 75 72 6e 61 6c 29 7b 0a 20 20 76 6f 69 64 20 2a  urnal){.  void *
67b0: 78 3b 0a 20 20 69 6e 74 20 73 7a 3b 0a 20 20 61  x;.  int sz;.  a
67c0: 73 73 65 72 74 28 20 70 2d 3e 70 43 61 63 68 65  ssert( p->pCache
67d0: 2d 3e 69 49 6e 55 73 65 44 42 20 29 3b 0a 20 20  ->iInUseDB );.  
67e0: 61 73 73 65 72 74 28 20 70 2d 3e 70 43 61 63 68  assert( p->pCach
67f0: 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 3d 3d 30  e->bPurgeable==0
6800: 20 29 3b 0a 20 20 69 66 28 20 21 70 2d 3e 61 70   );.  if( !p->ap
6810: 53 61 76 65 5b 69 64 4a 6f 75 72 6e 61 6c 5d 20  Save[idJournal] 
6820: 29 7b 0a 20 20 20 20 73 7a 20 3d 20 70 2d 3e 70  ){.    sz = p->p
6830: 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 3b 0a 20  Cache->szPage;. 
6840: 20 20 20 70 2d 3e 61 70 53 61 76 65 5b 69 64 4a     p->apSave[idJ
6850: 6f 75 72 6e 61 6c 5d 20 3d 20 78 20 3d 20 73 71  ournal] = x = sq
6860: 6c 69 74 65 33 50 61 67 65 4d 61 6c 6c 6f 63 28  lite3PageMalloc(
6870: 20 73 7a 20 29 3b 0a 20 20 20 20 69 66 28 20 78   sz );.    if( x
6880: 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c  ==0 ) return SQL
6890: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 6d  ITE_NOMEM;.    m
68a0: 65 6d 63 70 79 28 78 2c 20 70 2d 3e 70 44 61 74  emcpy(x, p->pDat
68b0: 61 2c 20 73 7a 29 3b 0a 20 20 7d 0a 20 20 72 65  a, sz);.  }.  re
68c0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
68d0: 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 6d 69 74 20  }../*.** Commit 
68e0: 61 20 63 68 61 6e 67 65 20 70 72 65 76 69 6f 75  a change previou
68f0: 73 6c 79 20 70 72 65 73 65 72 76 65 64 2e 0a 2a  sly preserved..*
6900: 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63  /.void sqlite3Pc
6910: 61 63 68 65 43 6f 6d 6d 69 74 28 50 43 61 63 68  acheCommit(PCach
6920: 65 20 2a 70 43 61 63 68 65 2c 20 69 6e 74 20 69  e *pCache, int i
6930: 64 4a 6f 75 72 6e 61 6c 29 7b 0a 20 20 50 67 48  dJournal){.  PgH
6940: 64 72 20 2a 70 3b 0a 20 20 61 73 73 65 72 74 28  dr *p;.  assert(
6950: 20 70 43 61 63 68 65 2d 3e 69 49 6e 55 73 65 44   pCache->iInUseD
6960: 42 20 29 3b 0a 20 20 70 63 61 63 68 65 45 6e 74  B );.  pcacheEnt
6970: 65 72 47 6c 6f 62 61 6c 28 29 3b 20 20 20 20 20  erGlobal();     
6980: 2f 2a 20 4d 75 74 65 78 20 69 73 20 72 65 71 75  /* Mutex is requ
6990: 69 72 65 64 20 74 6f 20 63 61 6c 6c 20 70 63 61  ired to call pca
69a0: 63 68 65 46 72 65 65 28 29 20 2a 2f 0a 20 20 66  cheFree() */.  f
69b0: 6f 72 28 70 3d 70 43 61 63 68 65 2d 3e 70 44 69  or(p=pCache->pDi
69c0: 72 74 79 3b 20 70 3b 20 70 3d 70 2d 3e 70 4e 65  rty; p; p=p->pNe
69d0: 78 74 29 7b 0a 20 20 20 20 69 66 28 20 70 2d 3e  xt){.    if( p->
69e0: 61 70 53 61 76 65 5b 69 64 4a 6f 75 72 6e 61 6c  apSave[idJournal
69f0: 5d 20 29 7b 0a 20 20 20 20 20 20 70 63 61 63 68  ] ){.      pcach
6a00: 65 46 72 65 65 28 70 2d 3e 61 70 53 61 76 65 5b  eFree(p->apSave[
6a10: 69 64 4a 6f 75 72 6e 61 6c 5d 29 3b 0a 20 20 20  idJournal]);.   
6a20: 20 20 20 70 2d 3e 61 70 53 61 76 65 5b 69 64 4a     p->apSave[idJ
6a30: 6f 75 72 6e 61 6c 5d 20 3d 20 30 3b 0a 20 20 20  ournal] = 0;.   
6a40: 20 7d 0a 20 20 7d 0a 20 20 70 63 61 63 68 65 45   }.  }.  pcacheE
6a50: 78 69 74 47 6c 6f 62 61 6c 28 29 3b 0a 7d 0a 0a  xitGlobal();.}..
6a60: 2f 2a 0a 2a 2a 20 52 6f 6c 6c 62 61 63 6b 20 61  /*.** Rollback a
6a70: 20 63 68 61 6e 67 65 20 70 72 65 76 69 6f 75 73   change previous
6a80: 6c 79 20 70 72 65 73 65 72 76 65 64 2e 0a 2a 2f  ly preserved..*/
6a90: 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63 61  .void sqlite3Pca
6aa0: 63 68 65 52 6f 6c 6c 62 61 63 6b 28 50 43 61 63  cheRollback(PCac
6ab0: 68 65 20 2a 70 43 61 63 68 65 2c 20 69 6e 74 20  he *pCache, int 
6ac0: 69 64 4a 6f 75 72 6e 61 6c 29 7b 0a 20 20 50 67  idJournal){.  Pg
6ad0: 48 64 72 20 2a 70 3b 0a 20 20 69 6e 74 20 73 7a  Hdr *p;.  int sz
6ae0: 3b 0a 20 20 61 73 73 65 72 74 28 20 70 43 61 63  ;.  assert( pCac
6af0: 68 65 2d 3e 69 49 6e 55 73 65 44 42 20 29 3b 0a  he->iInUseDB );.
6b00: 20 20 70 63 61 63 68 65 45 6e 74 65 72 47 6c 6f    pcacheEnterGlo
6b10: 62 61 6c 28 29 3b 20 20 20 20 20 2f 2a 20 4d 75  bal();     /* Mu
6b20: 74 65 78 20 69 73 20 72 65 71 75 69 72 65 64 20  tex is required 
6b30: 74 6f 20 63 61 6c 6c 20 70 63 61 63 68 65 46 72  to call pcacheFr
6b40: 65 65 28 29 20 2a 2f 0a 20 20 73 7a 20 3d 20 70  ee() */.  sz = p
6b50: 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 3b 0a 20  Cache->szPage;. 
6b60: 20 66 6f 72 28 70 3d 70 43 61 63 68 65 2d 3e 70   for(p=pCache->p
6b70: 44 69 72 74 79 3b 20 70 3b 20 70 3d 70 2d 3e 70  Dirty; p; p=p->p
6b80: 4e 65 78 74 29 7b 0a 20 20 20 20 69 66 28 20 70  Next){.    if( p
6b90: 2d 3e 61 70 53 61 76 65 5b 69 64 4a 6f 75 72 6e  ->apSave[idJourn
6ba0: 61 6c 5d 20 29 7b 0a 20 20 20 20 20 20 6d 65 6d  al] ){.      mem
6bb0: 63 70 79 28 70 2d 3e 70 44 61 74 61 2c 20 70 2d  cpy(p->pData, p-
6bc0: 3e 61 70 53 61 76 65 5b 69 64 4a 6f 75 72 6e 61  >apSave[idJourna
6bd0: 6c 5d 2c 20 73 7a 29 3b 0a 20 20 20 20 20 20 70  l], sz);.      p
6be0: 63 61 63 68 65 46 72 65 65 28 70 2d 3e 61 70 53  cacheFree(p->apS
6bf0: 61 76 65 5b 69 64 4a 6f 75 72 6e 61 6c 5d 29 3b  ave[idJournal]);
6c00: 0a 20 20 20 20 20 20 70 2d 3e 61 70 53 61 76 65  .      p->apSave
6c10: 5b 69 64 4a 6f 75 72 6e 61 6c 5d 20 3d 20 30 3b  [idJournal] = 0;
6c20: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 70 63 61  .    }.  }.  pca
6c30: 63 68 65 45 78 69 74 47 6c 6f 62 61 6c 28 29 3b  cheExitGlobal();
6c40: 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 41 73 73 65 72  .}../* .** Asser
6c50: 74 20 66 6c 61 67 73 20 73 65 74 74 69 6e 67 73  t flags settings
6c60: 20 6f 6e 20 61 6c 6c 20 70 61 67 65 73 2e 20 20   on all pages.  
6c70: 44 65 62 75 67 67 69 6e 67 20 6f 6e 6c 79 2e 0a  Debugging only..
6c80: 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50  */.void sqlite3P
6c90: 63 61 63 68 65 41 73 73 65 72 74 46 6c 61 67 73  cacheAssertFlags
6ca0: 28 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 2c  (PCache *pCache,
6cb0: 20 69 6e 74 20 74 72 75 65 4d 61 73 6b 2c 20 69   int trueMask, i
6cc0: 6e 74 20 66 61 6c 73 65 4d 61 73 6b 29 7b 0a 20  nt falseMask){. 
6cd0: 20 50 67 48 64 72 20 2a 70 3b 0a 20 20 61 73 73   PgHdr *p;.  ass
6ce0: 65 72 74 28 20 70 43 61 63 68 65 2d 3e 69 49 6e  ert( pCache->iIn
6cf0: 55 73 65 44 42 20 7c 7c 20 70 43 61 63 68 65 2d  UseDB || pCache-
6d00: 3e 69 49 6e 55 73 65 4d 4d 20 29 3b 0a 20 20 66  >iInUseMM );.  f
6d10: 6f 72 28 70 3d 70 43 61 63 68 65 2d 3e 70 44 69  or(p=pCache->pDi
6d20: 72 74 79 3b 20 70 3b 20 70 3d 70 2d 3e 70 4e 65  rty; p; p=p->pNe
6d30: 78 74 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28  xt){.    assert(
6d40: 20 28 70 2d 3e 66 6c 61 67 73 26 74 72 75 65 4d   (p->flags&trueM
6d50: 61 73 6b 29 3d 3d 74 72 75 65 4d 61 73 6b 20 29  ask)==trueMask )
6d60: 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 28 70  ;.    assert( (p
6d70: 2d 3e 66 6c 61 67 73 26 66 61 6c 73 65 4d 61 73  ->flags&falseMas
6d80: 6b 29 3d 3d 30 20 29 3b 0a 20 20 7d 0a 20 20 66  k)==0 );.  }.  f
6d90: 6f 72 28 70 3d 70 43 61 63 68 65 2d 3e 70 43 6c  or(p=pCache->pCl
6da0: 65 61 6e 3b 20 70 3b 20 70 3d 70 2d 3e 70 4e 65  ean; p; p=p->pNe
6db0: 78 74 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28  xt){.    assert(
6dc0: 20 28 70 2d 3e 66 6c 61 67 73 26 74 72 75 65 4d   (p->flags&trueM
6dd0: 61 73 6b 29 3d 3d 74 72 75 65 4d 61 73 6b 20 29  ask)==trueMask )
6de0: 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 28 70  ;.    assert( (p
6df0: 2d 3e 66 6c 61 67 73 26 66 61 6c 73 65 4d 61 73  ->flags&falseMas
6e00: 6b 29 3d 3d 30 20 29 3b 0a 20 20 7d 0a 7d 0a 0a  k)==0 );.  }.}..
6e10: 2f 2a 20 0a 2a 2a 20 44 69 73 63 61 72 64 20 74  /* .** Discard t
6e20: 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74  he contents of t
6e30: 68 65 20 63 61 63 68 65 2e 0a 2a 2f 0a 69 6e 74  he cache..*/.int
6e40: 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 43 6c   sqlite3PcacheCl
6e50: 65 61 72 28 50 43 61 63 68 65 20 2a 70 43 61 63  ear(PCache *pCac
6e60: 68 65 29 7b 0a 20 20 61 73 73 65 72 74 28 20 70  he){.  assert( p
6e70: 43 61 63 68 65 2d 3e 69 49 6e 55 73 65 44 42 20  Cache->iInUseDB 
6e80: 29 3b 0a 20 20 61 73 73 65 72 74 28 70 43 61 63  );.  assert(pCac
6e90: 68 65 2d 3e 6e 52 65 66 3d 3d 30 29 3b 0a 20 20  he->nRef==0);.  
6ea0: 70 63 61 63 68 65 45 6e 74 65 72 47 6c 6f 62 61  pcacheEnterGloba
6eb0: 6c 28 29 3b 0a 20 20 70 63 61 63 68 65 43 6c 65  l();.  pcacheCle
6ec0: 61 72 28 70 43 61 63 68 65 29 3b 0a 20 20 70 63  ar(pCache);.  pc
6ed0: 61 63 68 65 45 78 69 74 47 6c 6f 62 61 6c 28 29  acheExitGlobal()
6ee0: 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ;.  return SQLIT
6ef0: 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d  E_OK;.}../*.** M
6f00: 65 72 67 65 20 74 77 6f 20 6c 69 73 74 73 20 6f  erge two lists o
6f10: 66 20 70 61 67 65 73 20 63 6f 6e 6e 65 63 74 65  f pages connecte
6f20: 64 20 62 79 20 70 44 69 72 74 79 20 61 6e 64 20  d by pDirty and 
6f30: 69 6e 20 70 67 6e 6f 20 6f 72 64 65 72 2e 0a 2a  in pgno order..*
6f40: 2a 20 44 6f 20 6e 6f 74 20 62 6f 74 68 20 66 69  * Do not both fi
6f50: 78 69 6e 67 20 74 68 65 20 70 50 72 65 76 44 69  xing the pPrevDi
6f60: 72 74 79 20 70 6f 69 6e 74 65 72 73 2e 0a 2a 2f  rty pointers..*/
6f70: 0a 73 74 61 74 69 63 20 50 67 48 64 72 20 2a 70  .static PgHdr *p
6f80: 63 61 63 68 65 4d 65 72 67 65 44 69 72 74 79 4c  cacheMergeDirtyL
6f90: 69 73 74 28 50 67 48 64 72 20 2a 70 41 2c 20 50  ist(PgHdr *pA, P
6fa0: 67 48 64 72 20 2a 70 42 29 7b 0a 20 20 50 67 48  gHdr *pB){.  PgH
6fb0: 64 72 20 72 65 73 75 6c 74 2c 20 2a 70 54 61 69  dr result, *pTai
6fc0: 6c 3b 0a 20 20 70 54 61 69 6c 20 3d 20 26 72 65  l;.  pTail = &re
6fd0: 73 75 6c 74 3b 0a 20 20 77 68 69 6c 65 28 20 70  sult;.  while( p
6fe0: 41 20 26 26 20 70 42 20 29 7b 0a 20 20 20 20 69  A && pB ){.    i
6ff0: 66 28 20 70 41 2d 3e 70 67 6e 6f 3c 70 42 2d 3e  f( pA->pgno<pB->
7000: 70 67 6e 6f 20 29 7b 0a 20 20 20 20 20 20 70 54  pgno ){.      pT
7010: 61 69 6c 2d 3e 70 44 69 72 74 79 20 3d 20 70 41  ail->pDirty = pA
7020: 3b 0a 20 20 20 20 20 20 70 54 61 69 6c 20 3d 20  ;.      pTail = 
7030: 70 41 3b 0a 20 20 20 20 20 20 70 41 20 3d 20 70  pA;.      pA = p
7040: 41 2d 3e 70 44 69 72 74 79 3b 0a 20 20 20 20 7d  A->pDirty;.    }
7050: 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 54 61 69  else{.      pTai
7060: 6c 2d 3e 70 44 69 72 74 79 20 3d 20 70 42 3b 0a  l->pDirty = pB;.
7070: 20 20 20 20 20 20 70 54 61 69 6c 20 3d 20 70 42        pTail = pB
7080: 3b 0a 20 20 20 20 20 20 70 42 20 3d 20 70 42 2d  ;.      pB = pB-
7090: 3e 70 44 69 72 74 79 3b 0a 20 20 20 20 7d 0a 20  >pDirty;.    }. 
70a0: 20 7d 0a 20 20 69 66 28 20 70 41 20 29 7b 0a 20   }.  if( pA ){. 
70b0: 20 20 20 70 54 61 69 6c 2d 3e 70 44 69 72 74 79     pTail->pDirty
70c0: 20 3d 20 70 41 3b 0a 20 20 7d 65 6c 73 65 20 69   = pA;.  }else i
70d0: 66 28 20 70 42 20 29 7b 0a 20 20 20 20 70 54 61  f( pB ){.    pTa
70e0: 69 6c 2d 3e 70 44 69 72 74 79 20 3d 20 70 42 3b  il->pDirty = pB;
70f0: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70 54  .  }else{.    pT
7100: 61 69 6c 2d 3e 70 44 69 72 74 79 20 3d 20 30 3b  ail->pDirty = 0;
7110: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 65  .  }.  return re
7120: 73 75 6c 74 2e 70 44 69 72 74 79 3b 0a 7d 0a 0a  sult.pDirty;.}..
7130: 2f 2a 0a 2a 2a 20 53 6f 72 74 20 74 68 65 20 6c  /*.** Sort the l
7140: 69 73 74 20 6f 66 20 70 61 67 65 73 20 69 6e 20  ist of pages in 
7150: 61 63 63 65 6e 64 69 6e 67 20 6f 72 64 65 72 20  accending order 
7160: 62 79 20 70 67 6e 6f 2e 20 20 50 61 67 65 73 20  by pgno.  Pages 
7170: 61 72 65 0a 2a 2a 20 63 6f 6e 6e 65 63 74 65 64  are.** connected
7180: 20 62 79 20 70 44 69 72 74 79 20 70 6f 69 6e 74   by pDirty point
7190: 65 72 73 2e 20 20 54 68 65 20 70 50 72 65 76 44  ers.  The pPrevD
71a0: 69 72 74 79 20 70 6f 69 6e 74 65 72 73 20 61 72  irty pointers ar
71b0: 65 0a 2a 2a 20 63 6f 72 72 75 70 74 65 64 20 62  e.** corrupted b
71c0: 79 20 74 68 69 73 20 73 6f 72 74 2e 0a 2a 2f 0a  y this sort..*/.
71d0: 23 64 65 66 69 6e 65 20 4e 5f 53 4f 52 54 5f 42  #define N_SORT_B
71e0: 55 43 4b 45 54 5f 41 4c 4c 4f 43 20 32 35 0a 23  UCKET_ALLOC 25.#
71f0: 64 65 66 69 6e 65 20 4e 5f 53 4f 52 54 5f 42 55  define N_SORT_BU
7200: 43 4b 45 54 20 20 20 20 20 20 20 32 35 0a 23 69  CKET       25.#i
7210: 66 64 65 66 20 53 51 4c 49 54 45 5f 54 45 53 54  fdef SQLITE_TEST
7220: 0a 20 20 69 6e 74 20 73 71 6c 69 74 65 33 5f 70  .  int sqlite3_p
7230: 61 67 65 72 5f 6e 5f 73 6f 72 74 5f 62 75 63 6b  ager_n_sort_buck
7240: 65 74 20 3d 20 30 3b 0a 20 20 23 75 6e 64 65 66  et = 0;.  #undef
7250: 20 4e 5f 53 4f 52 54 5f 42 55 43 4b 45 54 0a 20   N_SORT_BUCKET. 
7260: 20 23 64 65 66 69 6e 65 20 4e 5f 53 4f 52 54 5f   #define N_SORT_
7270: 42 55 43 4b 45 54 20 5c 0a 20 20 20 28 73 71 6c  BUCKET \.   (sql
7280: 69 74 65 33 5f 70 61 67 65 72 5f 6e 5f 73 6f 72  ite3_pager_n_sor
7290: 74 5f 62 75 63 6b 65 74 3f 73 71 6c 69 74 65 33  t_bucket?sqlite3
72a0: 5f 70 61 67 65 72 5f 6e 5f 73 6f 72 74 5f 62 75  _pager_n_sort_bu
72b0: 63 6b 65 74 3a 4e 5f 53 4f 52 54 5f 42 55 43 4b  cket:N_SORT_BUCK
72c0: 45 54 5f 41 4c 4c 4f 43 29 0a 23 65 6e 64 69 66  ET_ALLOC).#endif
72d0: 0a 73 74 61 74 69 63 20 50 67 48 64 72 20 2a 70  .static PgHdr *p
72e0: 63 61 63 68 65 53 6f 72 74 44 69 72 74 79 4c 69  cacheSortDirtyLi
72f0: 73 74 28 50 67 48 64 72 20 2a 70 49 6e 29 7b 0a  st(PgHdr *pIn){.
7300: 20 20 50 67 48 64 72 20 2a 61 5b 4e 5f 53 4f 52    PgHdr *a[N_SOR
7310: 54 5f 42 55 43 4b 45 54 5f 41 4c 4c 4f 43 5d 2c  T_BUCKET_ALLOC],
7320: 20 2a 70 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20   *p;.  int i;.  
7330: 6d 65 6d 73 65 74 28 61 2c 20 30 2c 20 73 69 7a  memset(a, 0, siz
7340: 65 6f 66 28 61 29 29 3b 0a 20 20 77 68 69 6c 65  eof(a));.  while
7350: 28 20 70 49 6e 20 29 7b 0a 20 20 20 20 70 20 3d  ( pIn ){.    p =
7360: 20 70 49 6e 3b 0a 20 20 20 20 70 49 6e 20 3d 20   pIn;.    pIn = 
7370: 70 2d 3e 70 44 69 72 74 79 3b 0a 20 20 20 20 70  p->pDirty;.    p
7380: 2d 3e 70 44 69 72 74 79 20 3d 20 30 3b 0a 20 20  ->pDirty = 0;.  
7390: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 4e 5f 53    for(i=0; i<N_S
73a0: 4f 52 54 5f 42 55 43 4b 45 54 2d 31 3b 20 69 2b  ORT_BUCKET-1; i+
73b0: 2b 29 7b 0a 20 20 20 20 20 20 69 66 28 20 61 5b  +){.      if( a[
73c0: 69 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20  i]==0 ){.       
73d0: 20 61 5b 69 5d 20 3d 20 70 3b 0a 20 20 20 20 20   a[i] = p;.     
73e0: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20     break;.      
73f0: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 70  }else{.        p
7400: 20 3d 20 70 63 61 63 68 65 4d 65 72 67 65 44 69   = pcacheMergeDi
7410: 72 74 79 4c 69 73 74 28 61 5b 69 5d 2c 20 70 29  rtyList(a[i], p)
7420: 3b 0a 20 20 20 20 20 20 20 20 61 5b 69 5d 20 3d  ;.        a[i] =
7430: 20 30 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20   0;.      }.    
7440: 7d 0a 20 20 20 20 69 66 28 20 69 3d 3d 4e 5f 53  }.    if( i==N_S
7450: 4f 52 54 5f 42 55 43 4b 45 54 2d 31 20 29 7b 0a  ORT_BUCKET-1 ){.
7460: 20 20 20 20 20 20 2f 2a 20 43 6f 76 65 72 61 67        /* Coverag
7470: 65 3a 20 54 6f 20 67 65 74 20 68 65 72 65 2c 20  e: To get here, 
7480: 74 68 65 72 65 20 6e 65 65 64 20 74 6f 20 62 65  there need to be
7490: 20 32 5e 28 4e 5f 53 4f 52 54 5f 42 55 43 4b 45   2^(N_SORT_BUCKE
74a0: 54 29 20 0a 20 20 20 20 20 20 2a 2a 20 65 6c 65  T) .      ** ele
74b0: 6d 65 6e 74 73 20 69 6e 20 74 68 65 20 69 6e 70  ments in the inp
74c0: 75 74 20 6c 69 73 74 2e 20 54 68 69 73 20 69 73  ut list. This is
74d0: 20 70 6f 73 73 69 62 6c 65 2c 20 62 75 74 20 69   possible, but i
74e0: 6d 70 72 61 63 74 69 63 61 6c 2e 0a 20 20 20 20  mpractical..    
74f0: 20 20 2a 2a 20 54 65 73 74 69 6e 67 20 74 68 69    ** Testing thi
7500: 73 20 6c 69 6e 65 20 69 73 20 74 68 65 20 70 6f  s line is the po
7510: 69 6e 74 20 6f 66 20 67 6c 6f 62 61 6c 20 76 61  int of global va
7520: 72 69 61 62 6c 65 0a 20 20 20 20 20 20 2a 2a 20  riable.      ** 
7530: 73 71 6c 69 74 65 33 5f 70 61 67 65 72 5f 6e 5f  sqlite3_pager_n_
7540: 73 6f 72 74 5f 62 75 63 6b 65 74 2e 0a 20 20 20  sort_bucket..   
7550: 20 20 20 2a 2f 0a 20 20 20 20 20 20 61 5b 69 5d     */.      a[i]
7560: 20 3d 20 70 63 61 63 68 65 4d 65 72 67 65 44 69   = pcacheMergeDi
7570: 72 74 79 4c 69 73 74 28 61 5b 69 5d 2c 20 70 29  rtyList(a[i], p)
7580: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 70 20  ;.    }.  }.  p 
7590: 3d 20 61 5b 30 5d 3b 0a 20 20 66 6f 72 28 69 3d  = a[0];.  for(i=
75a0: 31 3b 20 69 3c 4e 5f 53 4f 52 54 5f 42 55 43 4b  1; i<N_SORT_BUCK
75b0: 45 54 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 70 20  ET; i++){.    p 
75c0: 3d 20 70 63 61 63 68 65 4d 65 72 67 65 44 69 72  = pcacheMergeDir
75d0: 74 79 4c 69 73 74 28 70 2c 20 61 5b 69 5d 29 3b  tyList(p, a[i]);
75e0: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 70 3b  .  }.  return p;
75f0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e  .}../*.** Return
7600: 20 61 20 6c 69 73 74 20 6f 66 20 61 6c 6c 20 64   a list of all d
7610: 69 72 74 79 20 70 61 67 65 73 20 69 6e 20 74 68  irty pages in th
7620: 65 20 63 61 63 68 65 2c 20 73 6f 72 74 65 64 20  e cache, sorted 
7630: 62 79 20 70 61 67 65 20 6e 75 6d 62 65 72 2e 0a  by page number..
7640: 2a 2f 0a 50 67 48 64 72 20 2a 73 71 6c 69 74 65  */.PgHdr *sqlite
7650: 33 50 63 61 63 68 65 44 69 72 74 79 4c 69 73 74  3PcacheDirtyList
7660: 28 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 29  (PCache *pCache)
7670: 7b 0a 20 20 50 67 48 64 72 20 2a 70 3b 0a 20 20  {.  PgHdr *p;.  
7680: 61 73 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e  assert( pCache->
7690: 69 49 6e 55 73 65 44 42 20 29 3b 0a 20 20 66 6f  iInUseDB );.  fo
76a0: 72 28 70 3d 70 43 61 63 68 65 2d 3e 70 44 69 72  r(p=pCache->pDir
76b0: 74 79 3b 20 70 3b 20 70 3d 70 2d 3e 70 4e 65 78  ty; p; p=p->pNex
76c0: 74 29 7b 0a 20 20 20 20 70 2d 3e 70 44 69 72 74  t){.    p->pDirt
76d0: 79 20 3d 20 70 2d 3e 70 4e 65 78 74 3b 0a 20 20  y = p->pNext;.  
76e0: 7d 0a 20 20 72 65 74 75 72 6e 20 70 63 61 63 68  }.  return pcach
76f0: 65 53 6f 72 74 44 69 72 74 79 4c 69 73 74 28 70  eSortDirtyList(p
7700: 43 61 63 68 65 2d 3e 70 44 69 72 74 79 29 3b 0a  Cache->pDirty);.
7710: 7d 0a 0a 2f 2a 20 0a 2a 2a 20 52 65 74 75 72 6e  }../* .** Return
7720: 20 74 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65   the total numbe
7730: 72 20 6f 66 20 6f 75 74 73 74 61 6e 64 69 6e 67  r of outstanding
7740: 20 70 61 67 65 20 72 65 66 65 72 65 6e 63 65 73   page references
7750: 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33  ..*/.int sqlite3
7760: 50 63 61 63 68 65 52 65 66 43 6f 75 6e 74 28 50  PcacheRefCount(P
7770: 43 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b 0a  Cache *pCache){.
7780: 20 20 72 65 74 75 72 6e 20 70 43 61 63 68 65 2d    return pCache-
7790: 3e 6e 52 65 66 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a  >nRef;.}../* .**
77a0: 20 52 65 74 75 72 6e 20 74 68 65 20 74 6f 74 61   Return the tota
77b0: 6c 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65  l number of page
77c0: 73 20 69 6e 20 74 68 65 20 63 61 63 68 65 2e 0a  s in the cache..
77d0: 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 50 63  */.int sqlite3Pc
77e0: 61 63 68 65 50 61 67 65 63 6f 75 6e 74 28 50 43  achePagecount(PC
77f0: 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b 0a 20  ache *pCache){. 
7800: 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65 2d   assert( pCache-
7810: 3e 69 49 6e 55 73 65 44 42 20 7c 7c 20 70 43 61  >iInUseDB || pCa
7820: 63 68 65 2d 3e 69 49 6e 55 73 65 4d 4d 20 29 3b  che->iInUseMM );
7830: 0a 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68  .  assert( pCach
7840: 65 2d 3e 6e 50 61 67 65 3e 3d 30 20 29 3b 0a 20  e->nPage>=0 );. 
7850: 20 72 65 74 75 72 6e 20 70 43 61 63 68 65 2d 3e   return pCache->
7860: 6e 50 61 67 65 3b 0a 7d 0a 0a 23 69 66 64 65 66  nPage;.}..#ifdef
7870: 20 53 51 4c 49 54 45 5f 43 48 45 43 4b 5f 50 41   SQLITE_CHECK_PA
7880: 47 45 53 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66  GES./*.** This f
7890: 75 6e 63 74 69 6f 6e 20 69 73 20 75 73 65 64 20  unction is used 
78a0: 62 79 20 74 68 65 20 70 61 67 65 72 2e 63 20 6d  by the pager.c m
78b0: 6f 64 75 6c 65 20 74 6f 20 69 74 65 72 61 74 65  odule to iterate
78c0: 20 74 68 72 6f 75 67 68 20 61 6c 6c 20 0a 2a 2a   through all .**
78d0: 20 70 61 67 65 73 20 69 6e 20 74 68 65 20 63 61   pages in the ca
78e0: 63 68 65 2e 20 41 74 20 70 72 65 73 65 6e 74 2c  che. At present,
78f0: 20 74 68 69 73 20 69 73 20 6f 6e 6c 79 20 72 65   this is only re
7900: 71 75 69 72 65 64 20 69 66 20 74 68 65 0a 2a 2a  quired if the.**
7910: 20 53 51 4c 49 54 45 5f 43 48 45 43 4b 5f 50 41   SQLITE_CHECK_PA
7920: 47 45 53 20 6d 61 63 72 6f 20 28 75 73 65 64 20  GES macro (used 
7930: 66 6f 72 20 64 65 62 75 67 67 69 6e 67 29 20 69  for debugging) i
7940: 73 20 73 70 65 63 69 66 69 65 64 2e 0a 2a 2f 0a  s specified..*/.
7950: 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63 61 63  void sqlite3Pcac
7960: 68 65 49 74 65 72 61 74 65 28 50 43 61 63 68 65  heIterate(PCache
7970: 20 2a 70 43 61 63 68 65 2c 20 76 6f 69 64 20 28   *pCache, void (
7980: 2a 78 49 74 65 72 29 28 50 67 48 64 72 20 2a 29  *xIter)(PgHdr *)
7990: 29 7b 0a 20 20 50 67 48 64 72 20 2a 70 3b 0a 20  ){.  PgHdr *p;. 
79a0: 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65 2d   assert( pCache-
79b0: 3e 69 49 6e 55 73 65 44 42 20 7c 7c 20 70 43 61  >iInUseDB || pCa
79c0: 63 68 65 2d 3e 69 49 6e 55 73 65 4d 4d 20 29 3b  che->iInUseMM );
79d0: 0a 20 20 66 6f 72 28 70 3d 70 43 61 63 68 65 2d  .  for(p=pCache-
79e0: 3e 70 43 6c 65 61 6e 3b 20 70 3b 20 70 3d 70 2d  >pClean; p; p=p-
79f0: 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 78 49 74  >pNext){.    xIt
7a00: 65 72 28 70 29 3b 0a 20 20 7d 0a 20 20 66 6f 72  er(p);.  }.  for
7a10: 28 70 3d 70 43 61 63 68 65 2d 3e 70 44 69 72 74  (p=pCache->pDirt
7a20: 79 3b 20 70 3b 20 70 3d 70 2d 3e 70 4e 65 78 74  y; p; p=p->pNext
7a30: 29 7b 0a 20 20 20 20 78 49 74 65 72 28 70 29 3b  ){.    xIter(p);
7a40: 0a 20 20 7d 0a 7d 0a 23 65 6e 64 69 66 0a 0a 2f  .  }.}.#endif../
7a50: 2a 20 0a 2a 2a 20 53 65 74 20 66 6c 61 67 73 20  * .** Set flags 
7a60: 6f 6e 20 61 6c 6c 20 70 61 67 65 73 20 69 6e 20  on all pages in 
7a70: 74 68 65 20 70 61 67 65 20 63 61 63 68 65 20 0a  the page cache .
7a80: 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50  */.void sqlite3P
7a90: 63 61 63 68 65 53 65 74 46 6c 61 67 73 28 50 43  cacheSetFlags(PC
7aa0: 61 63 68 65 20 2a 70 43 61 63 68 65 2c 20 69 6e  ache *pCache, in
7ab0: 74 20 61 6e 64 4d 61 73 6b 2c 20 69 6e 74 20 6f  t andMask, int o
7ac0: 72 4d 61 73 6b 29 7b 0a 20 20 50 67 48 64 72 20  rMask){.  PgHdr 
7ad0: 2a 70 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 28  *p;..  assert( (
7ae0: 6f 72 4d 61 73 6b 26 50 47 48 44 52 5f 4e 45 45  orMask&PGHDR_NEE
7af0: 44 5f 53 59 4e 43 29 3d 3d 30 20 29 3b 0a 20 20  D_SYNC)==0 );.  
7b00: 61 73 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e  assert( pCache->
7b10: 69 49 6e 55 73 65 44 42 20 7c 7c 20 70 43 61 63  iInUseDB || pCac
7b20: 68 65 2d 3e 69 49 6e 55 73 65 4d 4d 20 29 3b 0a  he->iInUseMM );.
7b30: 0a 20 20 2f 2a 20 4f 62 74 61 69 6e 20 74 68 65  .  /* Obtain the
7b40: 20 67 6c 6f 62 61 6c 20 6d 75 74 65 78 20 62 65   global mutex be
7b50: 66 6f 72 65 20 6d 6f 64 69 66 79 69 6e 67 20 61  fore modifying a
7b60: 6e 79 20 50 67 48 64 72 2e 66 6c 61 67 73 20 76  ny PgHdr.flags v
7b70: 61 72 69 61 62 6c 65 73 20 0a 20 20 2a 2a 20 6f  ariables .  ** o
7b80: 72 20 74 72 61 76 65 72 73 69 6e 67 20 74 68 65  r traversing the
7b90: 20 4c 52 55 20 6c 69 73 74 2e 0a 20 20 2a 2f 20   LRU list..  */ 
7ba0: 0a 20 20 70 63 61 63 68 65 45 6e 74 65 72 47 6c  .  pcacheEnterGl
7bb0: 6f 62 61 6c 28 29 3b 0a 20 20 61 73 73 65 72 74  obal();.  assert
7bc0: 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f  ( sqlite3_mutex_
7bd0: 68 65 6c 64 28 70 63 61 63 68 65 2e 6d 75 74 65  held(pcache.mute
7be0: 78 5f 6c 72 75 29 20 29 3b 0a 0a 20 20 66 6f 72  x_lru) );..  for
7bf0: 28 70 3d 70 43 61 63 68 65 2d 3e 70 44 69 72 74  (p=pCache->pDirt
7c00: 79 3b 20 70 3b 20 70 3d 70 2d 3e 70 4e 65 78 74  y; p; p=p->pNext
7c10: 29 7b 0a 20 20 20 20 70 2d 3e 66 6c 61 67 73 20  ){.    p->flags 
7c20: 3d 20 28 70 2d 3e 66 6c 61 67 73 26 61 6e 64 4d  = (p->flags&andM
7c30: 61 73 6b 29 7c 6f 72 4d 61 73 6b 3b 0a 20 20 7d  ask)|orMask;.  }
7c40: 0a 20 20 66 6f 72 28 70 3d 70 43 61 63 68 65 2d  .  for(p=pCache-
7c50: 3e 70 43 6c 65 61 6e 3b 20 70 3b 20 70 3d 70 2d  >pClean; p; p=p-
7c60: 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 70 2d 3e  >pNext){.    p->
7c70: 66 6c 61 67 73 20 3d 20 28 70 2d 3e 66 6c 61 67  flags = (p->flag
7c80: 73 26 61 6e 64 4d 61 73 6b 29 7c 6f 72 4d 61 73  s&andMask)|orMas
7c90: 6b 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 30 3d  k;.  }..  if( 0=
7ca0: 3d 28 61 6e 64 4d 61 73 6b 26 50 47 48 44 52 5f  =(andMask&PGHDR_
7cb0: 4e 45 45 44 5f 53 59 4e 43 29 20 29 7b 0a 20 20  NEED_SYNC) ){.  
7cc0: 20 20 66 6f 72 28 70 3d 70 63 61 63 68 65 2e 70    for(p=pcache.p
7cd0: 4c 72 75 54 61 69 6c 3b 20 70 20 26 26 20 28 70  LruTail; p && (p
7ce0: 2d 3e 66 6c 61 67 73 26 50 47 48 44 52 5f 4e 45  ->flags&PGHDR_NE
7cf0: 45 44 5f 53 59 4e 43 29 3b 20 70 3d 70 2d 3e 70  ED_SYNC); p=p->p
7d00: 50 72 65 76 4c 72 75 29 3b 0a 20 20 20 20 70 63  PrevLru);.    pc
7d10: 61 63 68 65 2e 70 4c 72 75 53 79 6e 63 65 64 20  ache.pLruSynced 
7d20: 3d 20 70 3b 0a 20 20 7d 0a 0a 20 20 70 63 61 63  = p;.  }..  pcac
7d30: 68 65 45 78 69 74 47 6c 6f 62 61 6c 28 29 3b 0a  heExitGlobal();.
7d40: 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20 74 68 65  }../*.** Set the
7d50: 20 73 75 67 67 65 73 74 65 64 20 63 61 63 68 65   suggested cache
7d60: 2d 73 69 7a 65 20 76 61 6c 75 65 2e 0a 2a 2f 0a  -size value..*/.
7d70: 69 6e 74 20 73 71 6c 69 74 65 33 50 63 61 63 68  int sqlite3Pcach
7d80: 65 47 65 74 43 61 63 68 65 73 69 7a 65 28 50 43  eGetCachesize(PC
7d90: 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b 0a 20  ache *pCache){. 
7da0: 20 72 65 74 75 72 6e 20 70 43 61 63 68 65 2d 3e   return pCache->
7db0: 6e 4d 61 78 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53  nMax;.}../*.** S
7dc0: 65 74 20 74 68 65 20 73 75 67 67 65 73 74 65 64  et the suggested
7dd0: 20 63 61 63 68 65 2d 73 69 7a 65 20 76 61 6c 75   cache-size valu
7de0: 65 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74  e..*/.void sqlit
7df0: 65 33 50 63 61 63 68 65 53 65 74 43 61 63 68 65  e3PcacheSetCache
7e00: 73 69 7a 65 28 50 43 61 63 68 65 20 2a 70 43 61  size(PCache *pCa
7e10: 63 68 65 2c 20 69 6e 74 20 6d 78 50 61 67 65 29  che, int mxPage)
7e20: 7b 0a 20 20 69 66 28 20 6d 78 50 61 67 65 3c 31  {.  if( mxPage<1
7e30: 30 20 29 7b 0a 20 20 20 20 6d 78 50 61 67 65 20  0 ){.    mxPage 
7e40: 3d 20 31 30 3b 0a 20 20 7d 0a 20 20 69 66 28 20  = 10;.  }.  if( 
7e50: 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62  pCache->bPurgeab
7e60: 6c 65 20 29 7b 0a 20 20 20 20 70 63 61 63 68 65  le ){.    pcache
7e70: 45 6e 74 65 72 47 6c 6f 62 61 6c 28 29 3b 0a 20  EnterGlobal();. 
7e80: 20 20 20 70 63 61 63 68 65 2e 6d 78 50 61 67 65     pcache.mxPage
7e90: 50 75 72 67 65 61 62 6c 65 20 2d 3d 20 70 43 61  Purgeable -= pCa
7ea0: 63 68 65 2d 3e 6e 4d 61 78 3b 0a 20 20 20 20 70  che->nMax;.    p
7eb0: 63 61 63 68 65 2e 6d 78 50 61 67 65 50 75 72 67  cache.mxPagePurg
7ec0: 65 61 62 6c 65 20 2b 3d 20 6d 78 50 61 67 65 3b  eable += mxPage;
7ed0: 0a 20 20 20 20 70 63 61 63 68 65 45 78 69 74 47  .    pcacheExitG
7ee0: 6c 6f 62 61 6c 28 29 3b 0a 20 20 7d 0a 20 20 70  lobal();.  }.  p
7ef0: 43 61 63 68 65 2d 3e 6e 4d 61 78 20 3d 20 6d 78  Cache->nMax = mx
7f00: 50 61 67 65 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4c  Page;.}../*.** L
7f10: 6f 63 6b 20 61 20 70 61 67 65 72 2d 63 61 63 68  ock a pager-cach
7f20: 65 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74  e..*/.void sqlit
7f30: 65 33 50 63 61 63 68 65 4c 6f 63 6b 28 50 43 61  e3PcacheLock(PCa
7f40: 63 68 65 20 2a 70 43 61 63 68 65 29 7b 0a 20 20  che *pCache){.  
7f50: 69 66 28 20 70 43 61 63 68 65 20 29 7b 0a 20 20  if( pCache ){.  
7f60: 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65    assert( sqlite
7f70: 33 5f 6d 75 74 65 78 5f 6e 6f 74 68 65 6c 64 28  3_mutex_notheld(
7f80: 70 63 61 63 68 65 2e 6d 75 74 65 78 5f 6c 72 75  pcache.mutex_lru
7f90: 29 20 29 3b 0a 20 20 20 20 70 43 61 63 68 65 2d  ) );.    pCache-
7fa0: 3e 69 49 6e 55 73 65 44 42 2b 2b 3b 0a 20 20 20  >iInUseDB++;.   
7fb0: 20 69 66 28 20 70 43 61 63 68 65 2d 3e 69 49 6e   if( pCache->iIn
7fc0: 55 73 65 4d 4d 20 26 26 20 70 43 61 63 68 65 2d  UseMM && pCache-
7fd0: 3e 69 49 6e 55 73 65 44 42 3d 3d 31 20 29 7b 0a  >iInUseDB==1 ){.
7fe0: 20 20 20 20 20 20 70 43 61 63 68 65 2d 3e 69 49        pCache->iI
7ff0: 6e 55 73 65 44 42 20 3d 20 30 3b 0a 20 20 20 20  nUseDB = 0;.    
8000: 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f    sqlite3_mutex_
8010: 65 6e 74 65 72 28 70 63 61 63 68 65 2e 6d 75 74  enter(pcache.mut
8020: 65 78 5f 6d 65 6d 32 29 3b 0a 20 20 20 20 20 20  ex_mem2);.      
8030: 61 73 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e  assert( pCache->
8040: 69 49 6e 55 73 65 4d 4d 3d 3d 30 20 26 26 20 70  iInUseMM==0 && p
8050: 43 61 63 68 65 2d 3e 69 49 6e 55 73 65 44 42 3d  Cache->iInUseDB=
8060: 3d 30 20 29 3b 0a 20 20 20 20 20 20 70 43 61 63  =0 );.      pCac
8070: 68 65 2d 3e 69 49 6e 55 73 65 44 42 20 3d 20 31  he->iInUseDB = 1
8080: 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  ;.      sqlite3_
8090: 6d 75 74 65 78 5f 6c 65 61 76 65 28 70 63 61 63  mutex_leave(pcac
80a0: 68 65 2e 6d 75 74 65 78 5f 6d 65 6d 32 29 3b 0a  he.mutex_mem2);.
80b0: 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a      }.  }.}../*.
80c0: 2a 2a 20 55 6e 6c 6f 63 6b 20 61 20 70 61 67 65  ** Unlock a page
80d0: 72 2d 63 61 63 68 65 2e 0a 2a 2f 0a 76 6f 69 64  r-cache..*/.void
80e0: 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 55 6e   sqlite3PcacheUn
80f0: 6c 6f 63 6b 28 50 43 61 63 68 65 20 2a 70 43 61  lock(PCache *pCa
8100: 63 68 65 29 7b 0a 20 20 69 66 28 20 70 43 61 63  che){.  if( pCac
8110: 68 65 20 29 7b 0a 20 20 20 20 70 43 61 63 68 65  he ){.    pCache
8120: 2d 3e 69 49 6e 55 73 65 44 42 2d 2d 3b 0a 20 20  ->iInUseDB--;.  
8130: 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65    assert( pCache
8140: 2d 3e 69 49 6e 55 73 65 44 42 3e 3d 30 20 29 3b  ->iInUseDB>=0 );
8150: 0a 20 20 7d 0a 7d 0a 0a 23 69 66 64 65 66 20 53  .  }.}..#ifdef S
8160: 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d  QLITE_ENABLE_MEM
8170: 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 0a 2f  ORY_MANAGEMENT./
8180: 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69  *.** This functi
8190: 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 74 6f 20  on is called to 
81a0: 66 72 65 65 20 73 75 70 65 72 66 6c 75 6f 75 73  free superfluous
81b0: 20 64 79 6e 61 6d 69 63 61 6c 6c 79 20 61 6c 6c   dynamically all
81c0: 6f 63 61 74 65 64 20 6d 65 6d 6f 72 79 0a 2a 2a  ocated memory.**
81d0: 20 68 65 6c 64 20 62 79 20 74 68 65 20 70 61 67   held by the pag
81e0: 65 72 20 73 79 73 74 65 6d 2e 20 4d 65 6d 6f 72  er system. Memor
81f0: 79 20 69 6e 20 75 73 65 20 62 79 20 61 6e 79 20  y in use by any 
8200: 53 51 4c 69 74 65 20 70 61 67 65 72 20 61 6c 6c  SQLite pager all
8210: 6f 63 61 74 65 64 0a 2a 2a 20 62 79 20 74 68 65  ocated.** by the
8220: 20 63 75 72 72 65 6e 74 20 74 68 72 65 61 64 20   current thread 
8230: 6d 61 79 20 62 65 20 73 71 6c 69 74 65 33 5f 66  may be sqlite3_f
8240: 72 65 65 28 29 65 64 2e 0a 2a 2a 0a 2a 2a 20 6e  ree()ed..**.** n
8250: 52 65 71 20 69 73 20 74 68 65 20 6e 75 6d 62 65  Req is the numbe
8260: 72 20 6f 66 20 62 79 74 65 73 20 6f 66 20 6d 65  r of bytes of me
8270: 6d 6f 72 79 20 72 65 71 75 69 72 65 64 2e 20 4f  mory required. O
8280: 6e 63 65 20 74 68 69 73 20 6d 75 63 68 20 68 61  nce this much ha
8290: 73 0a 2a 2a 20 62 65 65 6e 20 72 65 6c 65 61 73  s.** been releas
82a0: 65 64 2c 20 74 68 65 20 66 75 6e 63 74 69 6f 6e  ed, the function
82b0: 20 72 65 74 75 72 6e 73 2e 20 54 68 65 20 72 65   returns. The re
82c0: 74 75 72 6e 20 76 61 6c 75 65 20 69 73 20 74 68  turn value is th
82d0: 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 0a  e total number .
82e0: 2a 2a 20 6f 66 20 62 79 74 65 73 20 6f 66 20 6d  ** of bytes of m
82f0: 65 6d 6f 72 79 20 72 65 6c 65 61 73 65 64 2e 0a  emory released..
8300: 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 50 63  */.int sqlite3Pc
8310: 61 63 68 65 52 65 6c 65 61 73 65 4d 65 6d 6f 72  acheReleaseMemor
8320: 79 28 69 6e 74 20 6e 52 65 71 29 7b 0a 20 20 69  y(int nReq){.  i
8330: 6e 74 20 6e 46 72 65 65 20 3d 20 30 3b 0a 20 20  nt nFree = 0;.  
8340: 69 66 28 20 70 63 61 63 68 65 2e 70 53 74 61 72  if( pcache.pStar
8350: 74 3d 3d 30 20 29 7b 0a 20 20 20 20 50 67 48 64  t==0 ){.    PgHd
8360: 72 20 2a 70 3b 0a 20 20 20 20 70 63 61 63 68 65  r *p;.    pcache
8370: 45 6e 74 65 72 47 6c 6f 62 61 6c 28 29 3b 0a 20  EnterGlobal();. 
8380: 20 20 20 77 68 69 6c 65 28 20 28 6e 52 65 71 3c     while( (nReq<
8390: 30 20 7c 7c 20 6e 46 72 65 65 3c 6e 52 65 71 29  0 || nFree<nReq)
83a0: 20 26 26 20 28 70 3d 70 63 61 63 68 65 52 65 63   && (p=pcacheRec
83b0: 79 63 6c 65 28 30 29 29 20 29 7b 0a 20 20 20 20  ycle(0)) ){.    
83c0: 20 20 6e 46 72 65 65 20 2b 3d 20 70 63 61 63 68    nFree += pcach
83d0: 65 50 61 67 65 53 69 7a 65 28 70 29 3b 0a 20 20  ePageSize(p);.  
83e0: 20 20 20 20 70 63 61 63 68 65 50 61 67 65 46 72      pcachePageFr
83f0: 65 65 28 70 29 3b 0a 20 20 20 20 7d 0a 20 20 20  ee(p);.    }.   
8400: 20 70 63 61 63 68 65 45 78 69 74 47 6c 6f 62 61   pcacheExitGloba
8410: 6c 28 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  l();.  }.  retur
8420: 6e 20 6e 46 72 65 65 3b 0a 7d 0a 23 65 6e 64 69  n nFree;.}.#endi
8430: 66 20 2f 2a 20 53 51 4c 49 54 45 5f 45 4e 41 42  f /* SQLITE_ENAB
8440: 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47 45  LE_MEMORY_MANAGE
8450: 4d 45 4e 54 20 2a 2f 0a                          MENT */.