/ Hex Artifact Content
Login

Artifact 03c2ad23aa6f9cf008a6fe4ee68a07b3948d331f:


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 34 20 32 30 30  che.c,v 1.14 200
01c0: 38 2f 30 38 2f 32 36 20 31 38 3a 30 35 3a 34 38  8/08/26 18:05:48
01d0: 20 64 61 6e 69 65 6c 6b 31 39 37 37 20 45 78 70   danielk1977 Exp
01e0: 20 24 0a 2a 2f 0a 23 69 6e 63 6c 75 64 65 20 22   $.*/.#include "
01f0: 73 71 6c 69 74 65 49 6e 74 2e 68 22 0a 0a 2f 2a  sqliteInt.h"../*
0200: 0a 2a 2a 20 41 20 63 6f 6d 70 6c 65 74 65 20 70  .** A complete p
0210: 61 67 65 20 63 61 63 68 65 20 69 73 20 61 6e 20  age cache is an 
0220: 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 69 73  instance of this
0230: 20 73 74 72 75 63 74 75 72 65 2e 0a 2a 2f 0a 73   structure..*/.s
0240: 74 72 75 63 74 20 50 43 61 63 68 65 20 7b 0a 20  truct PCache {. 
0250: 20 69 6e 74 20 73 7a 50 61 67 65 3b 20 20 20 20   int szPage;    
0260: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0270: 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
0280: 65 76 65 72 79 20 70 61 67 65 20 69 6e 20 74 68  every page in th
0290: 69 73 20 63 61 63 68 65 20 2a 2f 0a 20 20 69 6e  is cache */.  in
02a0: 74 20 73 7a 45 78 74 72 61 3b 20 20 20 20 20 20  t szExtra;      
02b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
02c0: 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 65 78 74    /* Size of ext
02d0: 72 61 20 73 70 61 63 65 20 66 6f 72 20 65 61 63  ra space for eac
02e0: 68 20 70 61 67 65 20 2a 2f 0a 20 20 69 6e 74 20  h page */.  int 
02f0: 6e 48 61 73 68 3b 20 20 20 20 20 20 20 20 20 20  nHash;          
0300: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0310: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 73 6c 6f  /* Number of slo
0320: 74 73 20 69 6e 20 61 70 48 61 73 68 5b 5d 20 2a  ts in apHash[] *
0330: 2f 0a 20 20 69 6e 74 20 6e 50 61 67 65 3b 20 20  /.  int nPage;  
0340: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0350: 20 20 20 20 20 20 20 20 2f 2a 20 54 6f 74 61 6c          /* Total
0360: 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73   number of pages
0370: 20 69 6e 20 61 70 48 61 73 68 20 2a 2f 0a 20 20   in apHash */.  
0380: 69 6e 74 20 6e 4d 61 78 3b 20 20 20 20 20 20 20  int nMax;       
0390: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
03a0: 20 20 20 20 2f 2a 20 43 6f 6e 66 69 67 75 72 65      /* Configure
03b0: 64 20 63 61 63 68 65 20 73 69 7a 65 20 2a 2f 0a  d cache size */.
03c0: 20 20 69 6e 74 20 6e 4d 69 6e 3b 20 20 20 20 20    int nMin;     
03d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
03e0: 20 20 20 20 20 20 2f 2a 20 43 6f 6e 66 69 67 75        /* Configu
03f0: 72 65 64 20 6d 69 6e 69 6d 75 6d 20 63 61 63 68  red minimum cach
0400: 65 20 73 69 7a 65 20 2a 2f 0a 20 20 50 67 48 64  e size */.  PgHd
0410: 72 20 2a 2a 61 70 48 61 73 68 3b 20 20 20 20 20  r **apHash;     
0420: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0430: 2f 2a 20 48 61 73 68 20 74 61 62 6c 65 20 66 6f  /* Hash table fo
0440: 72 20 66 61 73 74 20 6c 6f 6f 6b 75 70 20 62 79  r fast lookup by
0450: 20 70 67 6e 6f 20 2a 2f 0a 20 20 69 6e 74 20 62   pgno */.  int b
0460: 50 75 72 67 65 61 62 6c 65 3b 20 20 20 20 20 20  Purgeable;      
0470: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0480: 2a 20 54 72 75 65 20 69 66 20 70 61 67 65 73 20  * True if pages 
0490: 61 72 65 20 6f 6e 20 62 61 63 6b 69 6e 67 20 73  are on backing s
04a0: 74 6f 72 65 20 2a 2f 0a 20 20 76 6f 69 64 20 28  tore */.  void (
04b0: 2a 78 44 65 73 74 72 6f 79 29 28 50 67 48 64 72  *xDestroy)(PgHdr
04c0: 2a 29 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a  *);           /*
04d0: 20 43 61 6c 6c 65 64 20 77 68 65 6e 20 72 65 66   Called when ref
04e0: 63 6e 74 20 67 6f 65 73 20 31 2d 3e 30 20 2a 2f  cnt goes 1->0 */
04f0: 0a 20 20 69 6e 74 20 28 2a 78 53 74 72 65 73 73  .  int (*xStress
0500: 29 28 76 6f 69 64 2a 2c 50 67 48 64 72 2a 29 3b  )(void*,PgHdr*);
0510: 20 20 20 20 20 20 20 2f 2a 20 43 61 6c 6c 20 74         /* Call t
0520: 6f 20 74 72 79 20 6d 61 6b 65 20 61 20 70 61 67  o try make a pag
0530: 65 20 63 6c 65 61 6e 20 2a 2f 0a 20 20 76 6f 69  e clean */.  voi
0540: 64 20 2a 70 53 74 72 65 73 73 3b 20 20 20 20 20  d *pStress;     
0550: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0560: 20 2f 2a 20 41 72 67 75 6d 65 6e 74 20 74 6f 20   /* Argument to 
0570: 78 53 74 72 65 73 73 20 2a 2f 0a 20 20 50 67 48  xStress */.  PgH
0580: 64 72 20 2a 70 43 6c 65 61 6e 3b 20 20 20 20 20  dr *pClean;     
0590: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
05a0: 20 2f 2a 20 4c 69 73 74 20 6f 66 20 63 6c 65 61   /* List of clea
05b0: 6e 20 70 61 67 65 73 20 69 6e 20 75 73 65 20 2a  n pages in use *
05c0: 2f 0a 20 20 50 67 48 64 72 20 2a 70 44 69 72 74  /.  PgHdr *pDirt
05d0: 79 2c 20 2a 70 44 69 72 74 79 54 61 69 6c 3b 20  y, *pDirtyTail; 
05e0: 20 20 20 20 20 20 20 20 2f 2a 20 4c 69 73 74 20          /* List 
05f0: 6f 66 20 64 69 72 74 79 20 70 61 67 65 73 20 69  of dirty pages i
0600: 6e 20 4c 52 55 20 6f 72 64 65 72 20 2a 2f 0a 20  n LRU order */. 
0610: 20 50 67 48 64 72 20 2a 70 53 79 6e 63 65 64 3b   PgHdr *pSynced;
0620: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0630: 20 20 20 20 20 2f 2a 20 4c 61 73 74 20 73 79 6e       /* Last syn
0640: 63 65 64 20 70 61 67 65 20 69 6e 20 64 69 72 74  ced page in dirt
0650: 79 20 70 61 67 65 20 6c 69 73 74 20 2a 2f 0a 20  y page list */. 
0660: 20 69 6e 74 20 6e 52 65 66 3b 20 20 20 20 20 20   int nRef;      
0670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0680: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
0690: 66 20 70 69 6e 6e 65 64 20 70 61 67 65 73 20 2a  f pinned pages *
06a0: 2f 0a 20 20 69 6e 74 20 6e 50 69 6e 6e 65 64 3b  /.  int nPinned;
06b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
06c0: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
06d0: 72 20 6f 66 20 70 69 6e 6e 65 64 20 61 6e 64 2f  r of pinned and/
06e0: 6f 72 20 64 69 72 74 79 20 70 61 67 65 73 20 2a  or dirty pages *
06f0: 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65  /.};../*.** Free
0700: 20 73 6c 6f 74 73 20 69 6e 20 74 68 65 20 70 61   slots in the pa
0710: 67 65 20 62 6c 6f 63 6b 20 61 6c 6c 6f 63 61 74  ge block allocat
0720: 6f 72 0a 2a 2f 0a 74 79 70 65 64 65 66 20 73 74  or.*/.typedef st
0730: 72 75 63 74 20 50 67 46 72 65 65 73 6c 6f 74 20  ruct PgFreeslot 
0740: 50 67 46 72 65 65 73 6c 6f 74 3b 0a 73 74 72 75  PgFreeslot;.stru
0750: 63 74 20 50 67 46 72 65 65 73 6c 6f 74 20 7b 0a  ct PgFreeslot {.
0760: 20 20 50 67 46 72 65 65 73 6c 6f 74 20 2a 70 4e    PgFreeslot *pN
0770: 65 78 74 3b 20 20 2f 2a 20 4e 65 78 74 20 66 72  ext;  /* Next fr
0780: 65 65 20 73 6c 6f 74 20 2a 2f 0a 7d 3b 0a 0a 2f  ee slot */.};../
0790: 2a 0a 2a 2a 20 47 6c 6f 62 61 6c 20 64 61 74 61  *.** Global data
07a0: 20 66 6f 72 20 74 68 65 20 70 61 67 65 20 63 61   for the page ca
07b0: 63 68 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 6d  che..**.** The m
07c0: 61 78 69 6d 75 6d 20 6e 75 6d 62 65 72 20 6f 66  aximum number of
07d0: 20 63 61 63 68 65 64 20 70 61 67 65 73 20 73 74   cached pages st
07e0: 6f 72 65 64 20 62 79 20 74 68 65 20 73 79 73 74  ored by the syst
07f0: 65 6d 20 69 73 20 64 65 74 65 72 6d 69 6e 65 64  em is determined
0800: 0a 2a 2a 20 62 79 20 74 68 65 20 70 63 61 63 68  .** by the pcach
0810: 65 2e 6d 78 50 61 67 65 20 61 6e 64 20 70 63 61  e.mxPage and pca
0820: 63 68 65 2e 6d 78 50 61 67 65 50 75 72 67 65 61  che.mxPagePurgea
0830: 62 6c 65 20 76 61 72 69 61 62 6c 65 73 2e 20 49  ble variables. I
0840: 66 0a 2a 2a 20 6d 78 50 61 67 65 20 69 73 20 6e  f.** mxPage is n
0850: 6f 6e 2d 7a 65 72 6f 2c 20 74 68 65 6e 20 74 68  on-zero, then th
0860: 65 20 73 79 73 74 65 6d 20 74 72 69 65 73 20 74  e system tries t
0870: 6f 20 6c 69 6d 69 74 20 74 68 65 20 6e 75 6d 62  o limit the numb
0880: 65 72 20 6f 66 0a 2a 2a 20 63 61 63 68 65 64 20  er of.** cached 
0890: 70 61 67 65 73 20 73 74 6f 72 65 64 20 74 6f 20  pages stored to 
08a0: 6d 78 50 61 67 65 2e 20 49 6e 20 74 68 69 73 20  mxPage. In this 
08b0: 63 61 73 65 20 6d 78 50 61 67 65 50 75 72 67 65  case mxPagePurge
08c0: 61 62 6c 65 20 69 73 20 6e 6f 74 20 0a 2a 2a 20  able is not .** 
08d0: 75 73 65 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 6d  used..**.** If m
08e0: 78 50 61 67 65 20 69 73 20 7a 65 72 6f 2c 20 74  xPage is zero, t
08f0: 68 65 6e 20 74 68 65 20 73 79 73 74 65 6d 20 74  hen the system t
0900: 72 69 65 73 20 74 6f 20 6c 69 6d 69 74 20 74 68  ries to limit th
0910: 65 20 6e 75 6d 62 65 72 20 6f 66 0a 2a 2a 20 70  e number of.** p
0920: 61 67 65 73 20 68 65 6c 64 20 62 79 20 70 75 72  ages held by pur
0930: 67 61 62 6c 65 20 63 61 63 68 65 73 20 74 6f 20  gable caches to 
0940: 6d 78 50 61 67 65 50 75 72 67 65 61 62 6c 65 2e  mxPagePurgeable.
0950: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 64 6f 75 62 6c  .**.** The doubl
0960: 79 2d 6c 69 6e 6b 65 64 20 6c 69 73 74 20 74 68  y-linked list th
0970: 61 74 20 72 75 6e 73 20 62 65 74 77 65 65 6e 20  at runs between 
0980: 70 63 61 63 68 65 2e 70 4c 72 75 48 65 61 64 20  pcache.pLruHead 
0990: 61 6e 64 20 0a 2a 2a 20 70 63 61 63 68 65 2e 70  and .** pcache.p
09a0: 4c 72 75 54 61 69 6c 20 63 6f 6e 74 61 69 6e 73  LruTail contains
09b0: 20 61 6c 6c 20 63 6c 65 61 6e 20 70 75 72 67 61   all clean purga
09c0: 62 6c 65 20 70 61 67 65 73 20 69 6e 20 74 68 65  ble pages in the
09d0: 20 73 79 73 74 65 6d 20 0a 2a 2a 20 77 69 74 68   system .** with
09e0: 20 61 20 7a 65 72 6f 20 72 65 66 65 72 65 6e 63   a zero referenc
09f0: 65 20 63 6f 75 6e 74 2e 20 70 63 61 63 68 65 2e  e count. pcache.
0a00: 70 4c 72 75 54 61 69 6c 20 69 73 20 74 68 65 20  pLruTail is the 
0a10: 6e 65 78 74 20 70 61 67 65 20 74 6f 0a 2a 2a 20  next page to.** 
0a20: 62 65 20 72 65 63 79 63 6c 65 64 2e 0a 2a 2f 0a  be recycled..*/.
0a30: 73 74 61 74 69 63 20 73 74 72 75 63 74 20 50 43  static struct PC
0a40: 61 63 68 65 47 6c 6f 62 61 6c 20 7b 0a 20 20 69  acheGlobal {.  i
0a50: 6e 74 20 69 73 49 6e 69 74 3b 20 20 20 20 20 20  nt isInit;      
0a60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0a70: 20 20 20 2f 2a 20 54 72 75 65 20 77 68 65 6e 20     /* True when 
0a80: 69 6e 69 74 69 61 6c 69 7a 65 64 20 2a 2f 0a 20  initialized */. 
0a90: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 20 2a   sqlite3_mutex *
0aa0: 6d 75 74 65 78 3b 20 20 20 20 20 20 20 20 20 20  mutex;          
0ab0: 20 20 20 20 20 2f 2a 20 73 74 61 74 69 63 20 6d       /* static m
0ac0: 75 74 65 78 20 4d 55 54 45 58 5f 53 54 41 54 49  utex MUTEX_STATI
0ad0: 43 5f 4c 52 55 20 2a 2f 0a 0a 20 20 69 6e 74 20  C_LRU */..  int 
0ae0: 6e 4d 61 78 50 61 67 65 3b 20 20 20 20 20 20 20  nMaxPage;       
0af0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0b00: 2f 2a 20 53 75 6d 20 6f 66 20 6e 4d 61 78 50 61  /* Sum of nMaxPa
0b10: 67 65 20 66 6f 72 20 70 75 72 67 65 61 62 6c 65  ge for purgeable
0b20: 20 63 61 63 68 65 73 20 2a 2f 0a 20 20 69 6e 74   caches */.  int
0b30: 20 6e 4d 69 6e 50 61 67 65 3b 20 20 20 20 20 20   nMinPage;      
0b40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0b50: 20 2f 2a 20 53 75 6d 20 6f 66 20 6e 4d 69 6e 50   /* Sum of nMinP
0b60: 61 67 65 20 66 6f 72 20 70 75 72 67 65 61 62 6c  age for purgeabl
0b70: 65 20 63 61 63 68 65 73 20 2a 2f 0a 20 20 69 6e  e caches */.  in
0b80: 74 20 6e 43 75 72 72 65 6e 74 50 61 67 65 3b 20  t nCurrentPage; 
0b90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ba0: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 70    /* Number of p
0bb0: 75 72 67 65 61 62 6c 65 20 70 61 67 65 73 20 61  urgeable pages a
0bc0: 6c 6c 6f 63 61 74 65 64 20 2a 2f 0a 20 20 50 67  llocated */.  Pg
0bd0: 48 64 72 20 2a 70 4c 72 75 48 65 61 64 2c 20 2a  Hdr *pLruHead, *
0be0: 70 4c 72 75 54 61 69 6c 3b 20 20 20 20 20 20 20  pLruTail;       
0bf0: 20 20 2f 2a 20 4c 52 55 20 6c 69 73 74 20 6f 66    /* LRU list of
0c00: 20 75 6e 75 73 65 64 20 63 6c 65 61 6e 20 70 67   unused clean pg
0c10: 73 20 2a 2f 0a 0a 20 20 2f 2a 20 56 61 72 69 61  s */..  /* Varia
0c20: 62 6c 65 73 20 72 65 6c 61 74 65 64 20 74 6f 20  bles related to 
0c30: 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41  SQLITE_CONFIG_PA
0c40: 47 45 43 41 43 48 45 20 73 65 74 74 69 6e 67 73  GECACHE settings
0c50: 2e 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 53 6c 6f  . */.  int szSlo
0c60: 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t;              
0c70: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69             /* Si
0c80: 7a 65 20 6f 66 20 65 61 63 68 20 66 72 65 65 20  ze of each free 
0c90: 73 6c 6f 74 20 2a 2f 0a 20 20 76 6f 69 64 20 2a  slot */.  void *
0ca0: 70 53 74 61 72 74 2c 20 2a 70 45 6e 64 3b 20 20  pStart, *pEnd;  
0cb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0cc0: 20 42 6f 75 6e 64 73 20 6f 66 20 70 61 67 65 63   Bounds of pagec
0cd0: 61 63 68 65 20 6d 61 6c 6c 6f 63 20 72 61 6e 67  ache malloc rang
0ce0: 65 20 2a 2f 0a 20 20 50 67 46 72 65 65 73 6c 6f  e */.  PgFreeslo
0cf0: 74 20 2a 70 46 72 65 65 3b 20 20 20 20 20 20 20  t *pFree;       
0d00: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 72             /* Fr
0d10: 65 65 20 70 61 67 65 20 62 6c 6f 63 6b 73 20 2a  ee page blocks *
0d20: 2f 0a 7d 20 70 63 61 63 68 65 20 3d 20 7b 30 7d  /.} pcache = {0}
0d30: 3b 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c 20 67 6c 6f  ;../*.** All glo
0d40: 62 61 6c 20 76 61 72 69 61 62 6c 65 73 20 75 73  bal variables us
0d50: 65 64 20 62 79 20 74 68 69 73 20 6d 6f 64 75 6c  ed by this modul
0d60: 65 20 28 6d 6f 73 74 20 6f 66 20 77 68 69 63 68  e (most of which
0d70: 20 61 72 65 20 67 72 6f 75 70 65 64 20 0a 2a 2a   are grouped .**
0d80: 20 74 6f 67 65 74 68 65 72 20 69 6e 20 67 6c 6f   together in glo
0d90: 62 61 6c 20 73 74 72 75 63 74 75 72 65 20 22 70  bal structure "p
0da0: 63 61 63 68 65 22 20 61 62 6f 76 65 29 20 61 72  cache" above) ar
0db0: 65 20 70 72 6f 74 65 63 74 65 64 20 62 79 20 74  e protected by t
0dc0: 68 65 20 73 74 61 74 69 63 20 0a 2a 2a 20 53 51  he static .** SQ
0dd0: 4c 49 54 45 5f 4d 55 54 45 58 5f 53 54 41 54 49  LITE_MUTEX_STATI
0de0: 43 5f 4c 52 55 20 6d 75 74 65 78 2e 20 41 20 70  C_LRU mutex. A p
0df0: 6f 69 6e 74 65 72 20 74 6f 20 74 68 69 73 20 6d  ointer to this m
0e00: 75 74 65 78 20 69 73 20 73 74 6f 72 65 64 20 69  utex is stored i
0e10: 6e 0a 2a 2a 20 76 61 72 69 61 62 6c 65 20 22 70  n.** variable "p
0e20: 63 61 63 68 65 2e 6d 75 74 65 78 22 2e 0a 2a 2a  cache.mutex"..**
0e30: 0a 2a 2a 20 41 63 63 65 73 73 20 74 6f 20 74 68  .** Access to th
0e40: 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68  e contents of th
0e50: 65 20 69 6e 64 69 76 69 64 75 61 6c 20 50 43 61  e individual PCa
0e60: 63 68 65 20 73 74 72 75 63 74 75 72 65 73 20 69  che structures i
0e70: 73 20 6e 6f 74 20 0a 2a 2a 20 70 72 6f 74 65 63  s not .** protec
0e80: 74 65 64 2e 20 49 74 20 69 73 20 74 68 65 20 6a  ted. It is the j
0e90: 6f 62 20 6f 66 20 74 68 65 20 63 61 6c 6c 65 72  ob of the caller
0ea0: 20 74 6f 20 65 6e 73 75 72 65 20 74 68 61 74 20   to ensure that 
0eb0: 74 68 65 73 65 20 73 74 72 75 63 74 75 72 65 73  these structures
0ec0: 0a 2a 2a 20 61 72 65 20 61 63 63 65 73 73 65 64  .** are accessed
0ed0: 20 69 6e 20 61 20 74 68 72 65 61 64 2d 73 61 66   in a thread-saf
0ee0: 65 20 6d 61 6e 6e 65 72 2e 0a 2a 2f 0a 0a 23 64  e manner..*/..#d
0ef0: 65 66 69 6e 65 20 70 63 61 63 68 65 45 6e 74 65  efine pcacheEnte
0f00: 72 47 6c 6f 62 61 6c 28 29 20 73 71 6c 69 74 65  rGlobal() sqlite
0f10: 33 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28 70 63  3_mutex_enter(pc
0f20: 61 63 68 65 2e 6d 75 74 65 78 29 0a 23 64 65 66  ache.mutex).#def
0f30: 69 6e 65 20 70 63 61 63 68 65 45 78 69 74 47 6c  ine pcacheExitGl
0f40: 6f 62 61 6c 28 29 20 20 73 71 6c 69 74 65 33 5f  obal()  sqlite3_
0f50: 6d 75 74 65 78 5f 6c 65 61 76 65 28 70 63 61 63  mutex_leave(pcac
0f60: 68 65 2e 6d 75 74 65 78 29 0a 0a 2f 2a 2a 2a 2a  he.mutex)../****
0f70: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0f80: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 4c  ************** L
0f90: 69 6e 6b 65 64 20 4c 69 73 74 20 4d 61 6e 61 67  inked List Manag
0fa0: 65 6d 65 6e 74 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ement **********
0fb0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 23 69 66  **********/..#if
0fc0: 6e 64 65 66 20 4e 44 45 42 55 47 0a 2f 2a 0a 2a  ndef NDEBUG./*.*
0fd0: 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 76  * This routine v
0fe0: 65 72 69 66 69 65 73 20 74 68 61 74 20 74 68 65  erifies that the
0ff0: 20 6e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72 69   number of entri
1000: 65 73 20 69 6e 20 74 68 65 20 68 61 73 68 20 74  es in the hash t
1010: 61 62 6c 65 0a 2a 2a 20 69 73 20 70 43 61 63 68  able.** is pCach
1020: 65 2d 3e 6e 50 61 67 65 2e 20 20 54 68 69 73 20  e->nPage.  This 
1030: 72 6f 75 74 69 6e 65 20 69 73 20 75 73 65 64 20  routine is used 
1040: 77 69 74 68 69 6e 20 61 73 73 65 72 74 28 29 20  within assert() 
1050: 73 74 61 74 65 6d 65 6e 74 73 0a 2a 2a 20 6f 6e  statements.** on
1060: 6c 79 20 61 6e 64 20 69 73 20 74 68 65 72 65 66  ly and is theref
1070: 6f 72 65 20 64 69 73 61 62 6c 65 64 20 64 75 72  ore disabled dur
1080: 69 6e 67 20 70 72 6f 64 75 63 74 69 6f 6e 20 62  ing production b
1090: 75 69 6c 64 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  uilds..*/.static
10a0: 20 69 6e 74 20 70 63 61 63 68 65 43 68 65 63 6b   int pcacheCheck
10b0: 48 61 73 68 43 6f 75 6e 74 28 50 43 61 63 68 65  HashCount(PCache
10c0: 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 69 6e 74   *pCache){.  int
10d0: 20 69 3b 0a 20 20 69 6e 74 20 6e 50 61 67 65 20   i;.  int nPage 
10e0: 3d 20 30 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20  = 0;.  for(i=0; 
10f0: 69 3c 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3b  i<pCache->nHash;
1100: 20 69 2b 2b 29 7b 0a 20 20 20 20 50 67 48 64 72   i++){.    PgHdr
1110: 20 2a 70 3b 0a 20 20 20 20 66 6f 72 28 70 3d 70   *p;.    for(p=p
1120: 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 69 5d  Cache->apHash[i]
1130: 3b 20 70 3b 20 70 3d 70 2d 3e 70 4e 65 78 74 48  ; p; p=p->pNextH
1140: 61 73 68 29 7b 0a 20 20 20 20 20 20 6e 50 61 67  ash){.      nPag
1150: 65 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  e++;.    }.  }. 
1160: 20 61 73 73 65 72 74 28 20 6e 50 61 67 65 3d 3d   assert( nPage==
1170: 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 20 29 3b  pCache->nPage );
1180: 0a 20 20 72 65 74 75 72 6e 20 31 3b 0a 7d 0a 0a  .  return 1;.}..
1190: 2f 2a 0a 2a 2a 20 42 61 73 65 64 20 6f 6e 20 74  /*.** Based on t
11a0: 68 65 20 63 75 72 72 65 6e 74 20 76 61 6c 75 65  he current value
11b0: 20 6f 66 20 50 43 61 63 68 65 2e 6e 52 65 66 20   of PCache.nRef 
11c0: 61 6e 64 20 74 68 65 20 63 6f 6e 74 65 6e 74 73  and the contents
11d0: 20 6f 66 20 74 68 65 0a 2a 2a 20 50 43 61 63 68   of the.** PCach
11e0: 65 2e 70 44 69 72 74 79 20 6c 69 73 74 2c 20 72  e.pDirty list, r
11f0: 65 74 75 72 6e 20 74 68 65 20 65 78 70 65 63 74  eturn the expect
1200: 65 64 20 76 61 6c 75 65 20 6f 66 20 74 68 65 20  ed value of the 
1210: 50 43 61 63 68 65 2e 6e 50 69 6e 6e 65 64 0a 2a  PCache.nPinned.*
1220: 2a 20 63 6f 75 6e 74 65 72 2e 20 54 68 69 73 20  * counter. This 
1230: 69 73 20 6f 6e 6c 79 20 75 73 65 64 20 69 6e 20  is only used in 
1240: 64 65 62 75 67 67 69 6e 67 20 62 75 69 6c 64 73  debugging builds
1250: 2c 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a  , as follows:.**
1260: 0a 2a 2a 20 20 20 61 73 73 65 72 74 28 20 70 43  .**   assert( pC
1270: 61 63 68 65 2d 3e 6e 50 69 6e 6e 65 64 3d 3d 70  ache->nPinned==p
1280: 63 61 63 68 65 50 69 6e 6e 65 64 43 6f 75 6e 74  cachePinnedCount
1290: 28 70 43 61 63 68 65 29 20 29 3b 0a 2a 2f 0a 73  (pCache) );.*/.s
12a0: 74 61 74 69 63 20 69 6e 74 20 70 63 61 63 68 65  tatic int pcache
12b0: 50 69 6e 6e 65 64 43 6f 75 6e 74 28 50 43 61 63  PinnedCount(PCac
12c0: 68 65 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 50  he *pCache){.  P
12d0: 67 48 64 72 20 2a 70 3b 0a 20 20 69 6e 74 20 6e  gHdr *p;.  int n
12e0: 50 69 6e 6e 65 64 20 3d 20 70 43 61 63 68 65 2d  Pinned = pCache-
12f0: 3e 6e 52 65 66 3b 0a 20 20 66 6f 72 28 70 3d 70  >nRef;.  for(p=p
1300: 43 61 63 68 65 2d 3e 70 44 69 72 74 79 3b 20 70  Cache->pDirty; p
1310: 3b 20 70 3d 70 2d 3e 70 4e 65 78 74 29 7b 0a 20  ; p=p->pNext){. 
1320: 20 20 20 69 66 28 20 70 2d 3e 6e 52 65 66 3d 3d     if( p->nRef==
1330: 30 20 29 7b 0a 20 20 20 20 20 20 6e 50 69 6e 6e  0 ){.      nPinn
1340: 65 64 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  ed++;.    }.  }.
1350: 20 20 72 65 74 75 72 6e 20 6e 50 69 6e 6e 65 64    return nPinned
1360: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 68 65 63 6b  ;.}../*.** Check
1370: 20 74 68 61 74 20 74 68 65 20 70 43 61 63 68 65   that the pCache
1380: 2d 3e 70 53 79 6e 63 65 64 20 76 61 72 69 61 62  ->pSynced variab
1390: 6c 65 20 69 73 20 73 65 74 20 63 6f 72 72 65 63  le is set correc
13a0: 74 6c 79 2e 20 49 66 20 69 74 0a 2a 2a 20 69 73  tly. If it.** is
13b0: 20 6e 6f 74 2c 20 65 69 74 68 65 72 20 66 61 69   not, either fai
13c0: 6c 20 61 6e 20 61 73 73 65 72 74 20 6f 72 20 72  l an assert or r
13d0: 65 74 75 72 6e 20 7a 65 72 6f 2e 20 4f 74 68 65  eturn zero. Othe
13e0: 72 77 69 73 65 2c 20 72 65 74 75 72 6e 0a 2a 2a  rwise, return.**
13f0: 20 6e 6f 6e 2d 7a 65 72 6f 2e 20 54 68 69 73 20   non-zero. This 
1400: 69 73 20 6f 6e 6c 79 20 75 73 65 64 20 69 6e 20  is only used in 
1410: 64 65 62 75 67 67 69 6e 67 20 62 75 69 6c 64 73  debugging builds
1420: 2c 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a  , as follows:.**
1430: 0a 2a 2a 20 20 20 61 73 73 65 72 74 28 20 70 63  .**   assert( pc
1440: 61 63 68 65 43 68 65 63 6b 53 79 6e 63 65 64 28  acheCheckSynced(
1450: 70 43 61 63 68 65 29 20 29 3b 0a 2a 2f 0a 73 74  pCache) );.*/.st
1460: 61 74 69 63 20 69 6e 74 20 70 63 61 63 68 65 43  atic int pcacheC
1470: 68 65 63 6b 53 79 6e 63 65 64 28 50 43 61 63 68  heckSynced(PCach
1480: 65 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 50 67  e *pCache){.  Pg
1490: 48 64 72 20 2a 70 20 3d 20 70 43 61 63 68 65 2d  Hdr *p = pCache-
14a0: 3e 70 44 69 72 74 79 54 61 69 6c 3b 0a 20 20 66  >pDirtyTail;.  f
14b0: 6f 72 28 70 3d 70 43 61 63 68 65 2d 3e 70 44 69  or(p=pCache->pDi
14c0: 72 74 79 54 61 69 6c 3b 20 70 21 3d 70 43 61 63  rtyTail; p!=pCac
14d0: 68 65 2d 3e 70 53 79 6e 63 65 64 3b 20 70 3d 70  he->pSynced; p=p
14e0: 2d 3e 70 50 72 65 76 29 7b 0a 20 20 20 20 61 73  ->pPrev){.    as
14f0: 73 65 72 74 28 20 70 2d 3e 6e 52 65 66 20 7c 7c  sert( p->nRef ||
1500: 20 28 70 2d 3e 66 6c 61 67 73 26 50 47 48 44 52   (p->flags&PGHDR
1510: 5f 4e 45 45 44 5f 53 59 4e 43 29 20 29 3b 0a 20  _NEED_SYNC) );. 
1520: 20 7d 0a 20 20 72 65 74 75 72 6e 20 28 70 3d 3d   }.  return (p==
1530: 30 20 7c 7c 20 70 2d 3e 6e 52 65 66 20 7c 7c 20  0 || p->nRef || 
1540: 28 70 2d 3e 66 6c 61 67 73 26 50 47 48 44 52 5f  (p->flags&PGHDR_
1550: 4e 45 45 44 5f 53 59 4e 43 29 3d 3d 30 29 3b 0a  NEED_SYNC)==0);.
1560: 7d 0a 0a 23 65 6e 64 69 66 0a 0a 2f 2a 0a 2a 2a  }..#endif../*.**
1570: 20 52 65 6d 6f 76 65 20 61 20 70 61 67 65 20 66   Remove a page f
1580: 72 6f 6d 20 69 74 73 20 68 61 73 68 20 74 61 62  rom its hash tab
1590: 6c 65 20 28 50 43 61 63 68 65 2e 61 70 48 61 73  le (PCache.apHas
15a0: 68 5b 5d 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  h[])..*/.static 
15b0: 76 6f 69 64 20 70 63 61 63 68 65 52 65 6d 6f 76  void pcacheRemov
15c0: 65 46 72 6f 6d 48 61 73 68 28 50 67 48 64 72 20  eFromHash(PgHdr 
15d0: 2a 70 50 61 67 65 29 7b 0a 20 20 69 66 28 20 70  *pPage){.  if( p
15e0: 50 61 67 65 2d 3e 70 50 72 65 76 48 61 73 68 20  Page->pPrevHash 
15f0: 29 7b 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 50  ){.    pPage->pP
1600: 72 65 76 48 61 73 68 2d 3e 70 4e 65 78 74 48 61  revHash->pNextHa
1610: 73 68 20 3d 20 70 50 61 67 65 2d 3e 70 4e 65 78  sh = pPage->pNex
1620: 74 48 61 73 68 3b 0a 20 20 7d 65 6c 73 65 7b 0a  tHash;.  }else{.
1630: 20 20 20 20 50 43 61 63 68 65 20 2a 70 43 61 63      PCache *pCac
1640: 68 65 20 3d 20 70 50 61 67 65 2d 3e 70 43 61 63  he = pPage->pCac
1650: 68 65 3b 0a 20 20 20 20 75 33 32 20 68 20 3d 20  he;.    u32 h = 
1660: 70 50 61 67 65 2d 3e 70 67 6e 6f 20 25 20 70 43  pPage->pgno % pC
1670: 61 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 20  ache->nHash;.   
1680: 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65 2d   assert( pCache-
1690: 3e 61 70 48 61 73 68 5b 68 5d 3d 3d 70 50 61 67  >apHash[h]==pPag
16a0: 65 20 29 3b 0a 20 20 20 20 70 43 61 63 68 65 2d  e );.    pCache-
16b0: 3e 61 70 48 61 73 68 5b 68 5d 20 3d 20 70 50 61  >apHash[h] = pPa
16c0: 67 65 2d 3e 70 4e 65 78 74 48 61 73 68 3b 0a 20  ge->pNextHash;. 
16d0: 20 7d 0a 20 20 69 66 28 20 70 50 61 67 65 2d 3e   }.  if( pPage->
16e0: 70 4e 65 78 74 48 61 73 68 20 29 7b 0a 20 20 20  pNextHash ){.   
16f0: 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 48 61 73   pPage->pNextHas
1700: 68 2d 3e 70 50 72 65 76 48 61 73 68 20 3d 20 70  h->pPrevHash = p
1710: 50 61 67 65 2d 3e 70 50 72 65 76 48 61 73 68 3b  Page->pPrevHash;
1720: 0a 20 20 7d 0a 20 20 70 50 61 67 65 2d 3e 70 43  .  }.  pPage->pC
1730: 61 63 68 65 2d 3e 6e 50 61 67 65 2d 2d 3b 0a 20  ache->nPage--;. 
1740: 20 61 73 73 65 72 74 28 20 70 63 61 63 68 65 43   assert( pcacheC
1750: 68 65 63 6b 48 61 73 68 43 6f 75 6e 74 28 70 50  heckHashCount(pP
1760: 61 67 65 2d 3e 70 43 61 63 68 65 29 20 29 3b 0a  age->pCache) );.
1770: 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 73 65 72 74 20  }../*.** Insert 
1780: 61 20 70 61 67 65 20 69 6e 74 6f 20 74 68 65 20  a page into the 
1790: 68 61 73 68 20 74 61 62 6c 65 0a 2a 2f 0a 73 74  hash table.*/.st
17a0: 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65  atic void pcache
17b0: 41 64 64 54 6f 48 61 73 68 28 50 67 48 64 72 20  AddToHash(PgHdr 
17c0: 2a 70 50 61 67 65 29 7b 0a 20 20 50 43 61 63 68  *pPage){.  PCach
17d0: 65 20 2a 70 43 61 63 68 65 20 3d 20 70 50 61 67  e *pCache = pPag
17e0: 65 2d 3e 70 43 61 63 68 65 3b 0a 20 20 75 33 32  e->pCache;.  u32
17f0: 20 68 20 3d 20 70 50 61 67 65 2d 3e 70 67 6e 6f   h = pPage->pgno
1800: 20 25 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68   % pCache->nHash
1810: 3b 0a 20 20 70 50 61 67 65 2d 3e 70 4e 65 78 74  ;.  pPage->pNext
1820: 48 61 73 68 20 3d 20 70 43 61 63 68 65 2d 3e 61  Hash = pCache->a
1830: 70 48 61 73 68 5b 68 5d 3b 0a 20 20 70 50 61 67  pHash[h];.  pPag
1840: 65 2d 3e 70 50 72 65 76 48 61 73 68 20 3d 20 30  e->pPrevHash = 0
1850: 3b 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e  ;.  if( pCache->
1860: 61 70 48 61 73 68 5b 68 5d 20 29 7b 0a 20 20 20  apHash[h] ){.   
1870: 20 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b   pCache->apHash[
1880: 68 5d 2d 3e 70 50 72 65 76 48 61 73 68 20 3d 20  h]->pPrevHash = 
1890: 70 50 61 67 65 3b 0a 20 20 7d 0a 20 20 70 43 61  pPage;.  }.  pCa
18a0: 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 20 3d  che->apHash[h] =
18b0: 20 70 50 61 67 65 3b 0a 20 20 70 43 61 63 68 65   pPage;.  pCache
18c0: 2d 3e 6e 50 61 67 65 2b 2b 3b 0a 20 20 61 73 73  ->nPage++;.  ass
18d0: 65 72 74 28 20 70 63 61 63 68 65 43 68 65 63 6b  ert( pcacheCheck
18e0: 48 61 73 68 43 6f 75 6e 74 28 70 43 61 63 68 65  HashCount(pCache
18f0: 29 20 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 74  ) );.}../*.** At
1900: 74 65 6d 70 74 20 74 6f 20 69 6e 63 72 65 61 73  tempt to increas
1910: 65 20 74 68 65 20 73 69 7a 65 20 74 68 65 20 68  e the size the h
1920: 61 73 68 20 74 61 62 6c 65 20 74 6f 20 63 6f 6e  ash table to con
1930: 74 61 69 6e 0a 2a 2a 20 61 74 20 6c 65 61 73 74  tain.** at least
1940: 20 6e 48 61 73 68 20 62 75 63 6b 65 74 73 2e 0a   nHash buckets..
1950: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 70 63  */.static int pc
1960: 61 63 68 65 52 65 73 69 7a 65 48 61 73 68 28 50  acheResizeHash(P
1970: 43 61 63 68 65 20 2a 70 43 61 63 68 65 2c 20 69  Cache *pCache, i
1980: 6e 74 20 6e 48 61 73 68 29 7b 0a 23 69 66 64 65  nt nHash){.#ifde
1990: 66 20 53 51 4c 49 54 45 5f 4d 41 4c 4c 4f 43 5f  f SQLITE_MALLOC_
19a0: 53 4f 46 54 5f 4c 49 4d 49 54 0a 20 20 69 66 28  SOFT_LIMIT.  if(
19b0: 20 6e 48 61 73 68 2a 73 69 7a 65 6f 66 28 50 67   nHash*sizeof(Pg
19c0: 48 64 72 2a 29 3e 53 51 4c 49 54 45 5f 4d 41 4c  Hdr*)>SQLITE_MAL
19d0: 4c 4f 43 5f 53 4f 46 54 5f 4c 49 4d 49 54 20 29  LOC_SOFT_LIMIT )
19e0: 7b 0a 20 20 20 20 6e 48 61 73 68 20 3d 20 53 51  {.    nHash = SQ
19f0: 4c 49 54 45 5f 4d 41 4c 4c 4f 43 5f 53 4f 46 54  LITE_MALLOC_SOFT
1a00: 5f 4c 49 4d 49 54 2f 73 69 7a 65 6f 66 28 50 67  _LIMIT/sizeof(Pg
1a10: 48 64 72 20 2a 29 3b 0a 20 20 7d 0a 23 65 6e 64  Hdr *);.  }.#end
1a20: 69 66 0a 20 20 69 66 28 20 6e 48 61 73 68 3e 70  if.  if( nHash>p
1a30: 43 61 63 68 65 2d 3e 6e 48 61 73 68 20 29 7b 0a  Cache->nHash ){.
1a40: 20 20 20 20 50 67 48 64 72 20 2a 70 3b 0a 20 20      PgHdr *p;.  
1a50: 20 20 50 67 48 64 72 20 2a 2a 70 4e 65 77 20 3d    PgHdr **pNew =
1a60: 20 28 50 67 48 64 72 20 2a 2a 29 73 71 6c 69 74   (PgHdr **)sqlit
1a70: 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66  e3_malloc(sizeof
1a80: 28 50 67 48 64 72 2a 29 2a 6e 48 61 73 68 29 3b  (PgHdr*)*nHash);
1a90: 0a 20 20 20 20 69 66 28 20 21 70 4e 65 77 20 29  .    if( !pNew )
1aa0: 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 53  {.      return S
1ab0: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
1ac0: 20 7d 0a 20 20 20 20 6d 65 6d 73 65 74 28 70 4e   }.    memset(pN
1ad0: 65 77 2c 20 30 2c 20 73 69 7a 65 6f 66 28 50 67  ew, 0, sizeof(Pg
1ae0: 48 64 72 20 2a 29 2a 6e 48 61 73 68 29 3b 0a 20  Hdr *)*nHash);. 
1af0: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
1b00: 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 29 3b  pCache->apHash);
1b10: 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 61 70 48  .    pCache->apH
1b20: 61 73 68 20 3d 20 70 4e 65 77 3b 0a 20 20 20 20  ash = pNew;.    
1b30: 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 20 3d 20  pCache->nHash = 
1b40: 6e 48 61 73 68 3b 0a 20 20 20 20 70 43 61 63 68  nHash;.    pCach
1b50: 65 2d 3e 6e 50 61 67 65 20 3d 20 30 3b 0a 20 20  e->nPage = 0;.  
1b60: 20 0a 20 20 20 20 66 6f 72 28 70 3d 70 43 61 63   .    for(p=pCac
1b70: 68 65 2d 3e 70 43 6c 65 61 6e 3b 20 70 3b 20 70  he->pClean; p; p
1b80: 3d 70 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20  =p->pNext){.    
1b90: 20 20 70 63 61 63 68 65 41 64 64 54 6f 48 61 73    pcacheAddToHas
1ba0: 68 28 70 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20  h(p);.    }.    
1bb0: 66 6f 72 28 70 3d 70 43 61 63 68 65 2d 3e 70 44  for(p=pCache->pD
1bc0: 69 72 74 79 3b 20 70 3b 20 70 3d 70 2d 3e 70 4e  irty; p; p=p->pN
1bd0: 65 78 74 29 7b 0a 20 20 20 20 20 20 70 63 61 63  ext){.      pcac
1be0: 68 65 41 64 64 54 6f 48 61 73 68 28 70 29 3b 0a  heAddToHash(p);.
1bf0: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75      }.  }.  retu
1c00: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a  rn SQLITE_OK;.}.
1c10: 0a 2f 2a 0a 2a 2a 20 52 65 6d 6f 76 65 20 61 20  ./*.** Remove a 
1c20: 70 61 67 65 20 66 72 6f 6d 20 61 20 6c 69 6e 6b  page from a link
1c30: 65 64 20 6c 69 73 74 20 74 68 61 74 20 69 73 20  ed list that is 
1c40: 68 65 61 64 65 64 20 62 79 20 2a 70 70 48 65 61  headed by *ppHea
1c50: 64 2e 0a 2a 2a 20 2a 70 70 48 65 61 64 20 69 73  d..** *ppHead is
1c60: 20 65 69 74 68 65 72 20 50 43 61 63 68 65 2e 70   either PCache.p
1c70: 43 6c 65 61 6e 20 6f 72 20 50 43 61 63 68 65 2e  Clean or PCache.
1c80: 70 44 69 72 74 79 2e 0a 2a 2f 0a 73 74 61 74 69  pDirty..*/.stati
1c90: 63 20 76 6f 69 64 20 70 63 61 63 68 65 52 65 6d  c void pcacheRem
1ca0: 6f 76 65 46 72 6f 6d 4c 69 73 74 28 50 67 48 64  oveFromList(PgHd
1cb0: 72 20 2a 2a 70 70 48 65 61 64 2c 20 50 67 48 64  r **ppHead, PgHd
1cc0: 72 20 2a 70 50 61 67 65 29 7b 0a 20 20 69 6e 74  r *pPage){.  int
1cd0: 20 69 73 44 69 72 74 79 4c 69 73 74 20 3d 20 28   isDirtyList = (
1ce0: 70 70 48 65 61 64 3d 3d 26 70 50 61 67 65 2d 3e  ppHead==&pPage->
1cf0: 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 29 3b  pCache->pDirty);
1d00: 0a 20 20 61 73 73 65 72 74 28 20 70 70 48 65 61  .  assert( ppHea
1d10: 64 3d 3d 26 70 50 61 67 65 2d 3e 70 43 61 63 68  d==&pPage->pCach
1d20: 65 2d 3e 70 43 6c 65 61 6e 20 7c 7c 20 70 70 48  e->pClean || ppH
1d30: 65 61 64 3d 3d 26 70 50 61 67 65 2d 3e 70 43 61  ead==&pPage->pCa
1d40: 63 68 65 2d 3e 70 44 69 72 74 79 20 29 3b 0a 0a  che->pDirty );..
1d50: 20 20 69 66 28 20 70 50 61 67 65 2d 3e 70 50 72    if( pPage->pPr
1d60: 65 76 20 29 7b 0a 20 20 20 20 70 50 61 67 65 2d  ev ){.    pPage-
1d70: 3e 70 50 72 65 76 2d 3e 70 4e 65 78 74 20 3d 20  >pPrev->pNext = 
1d80: 70 50 61 67 65 2d 3e 70 4e 65 78 74 3b 0a 20 20  pPage->pNext;.  
1d90: 7d 65 6c 73 65 7b 0a 20 20 20 20 61 73 73 65 72  }else{.    asser
1da0: 74 28 20 2a 70 70 48 65 61 64 3d 3d 70 50 61 67  t( *ppHead==pPag
1db0: 65 20 29 3b 0a 20 20 20 20 2a 70 70 48 65 61 64  e );.    *ppHead
1dc0: 20 3d 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 3b   = pPage->pNext;
1dd0: 0a 20 20 7d 0a 20 20 69 66 28 20 70 50 61 67 65  .  }.  if( pPage
1de0: 2d 3e 70 4e 65 78 74 20 29 7b 0a 20 20 20 20 70  ->pNext ){.    p
1df0: 50 61 67 65 2d 3e 70 4e 65 78 74 2d 3e 70 50 72  Page->pNext->pPr
1e00: 65 76 20 3d 20 70 50 61 67 65 2d 3e 70 50 72 65  ev = pPage->pPre
1e10: 76 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 69 73  v;.  }..  if( is
1e20: 44 69 72 74 79 4c 69 73 74 20 29 7b 0a 20 20 20  DirtyList ){.   
1e30: 20 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 20   PCache *pCache 
1e40: 3d 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65 3b  = pPage->pCache;
1e50: 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 50 61  .    assert( pPa
1e60: 67 65 2d 3e 70 4e 65 78 74 20 7c 7c 20 70 43 61  ge->pNext || pCa
1e70: 63 68 65 2d 3e 70 44 69 72 74 79 54 61 69 6c 3d  che->pDirtyTail=
1e80: 3d 70 50 61 67 65 20 29 3b 0a 20 20 20 20 69 66  =pPage );.    if
1e90: 28 20 21 70 50 61 67 65 2d 3e 70 4e 65 78 74 20  ( !pPage->pNext 
1ea0: 29 7b 0a 20 20 20 20 20 20 70 43 61 63 68 65 2d  ){.      pCache-
1eb0: 3e 70 44 69 72 74 79 54 61 69 6c 20 3d 20 70 50  >pDirtyTail = pP
1ec0: 61 67 65 2d 3e 70 50 72 65 76 3b 0a 20 20 20 20  age->pPrev;.    
1ed0: 7d 0a 20 20 20 20 69 66 28 20 70 43 61 63 68 65  }.    if( pCache
1ee0: 2d 3e 70 53 79 6e 63 65 64 3d 3d 70 50 61 67 65  ->pSynced==pPage
1ef0: 20 29 7b 0a 20 20 20 20 20 20 50 67 48 64 72 20   ){.      PgHdr 
1f00: 2a 70 53 79 6e 63 65 64 20 3d 20 70 50 61 67 65  *pSynced = pPage
1f10: 2d 3e 70 50 72 65 76 3b 0a 20 20 20 20 20 20 77  ->pPrev;.      w
1f20: 68 69 6c 65 28 20 70 53 79 6e 63 65 64 20 26 26  hile( pSynced &&
1f30: 20 28 70 53 79 6e 63 65 64 2d 3e 66 6c 61 67 73   (pSynced->flags
1f40: 26 50 47 48 44 52 5f 4e 45 45 44 5f 53 59 4e 43  &PGHDR_NEED_SYNC
1f50: 29 20 29 7b 0a 20 20 20 20 20 20 20 20 70 53 79  ) ){.        pSy
1f60: 6e 63 65 64 20 3d 20 70 53 79 6e 63 65 64 2d 3e  nced = pSynced->
1f70: 70 50 72 65 76 3b 0a 20 20 20 20 20 20 7d 0a 20  pPrev;.      }. 
1f80: 20 20 20 20 20 70 43 61 63 68 65 2d 3e 70 53 79       pCache->pSy
1f90: 6e 63 65 64 20 3d 20 70 53 79 6e 63 65 64 3b 0a  nced = pSynced;.
1fa0: 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a      }.  }.}../*.
1fb0: 2a 2a 20 41 64 64 20 61 20 70 61 67 65 20 66 72  ** Add a page fr
1fc0: 6f 6d 20 61 20 6c 69 6e 6b 65 64 20 6c 69 73 74  om a linked list
1fd0: 20 74 68 61 74 20 69 73 20 68 65 61 64 65 64 20   that is headed 
1fe0: 62 79 20 2a 70 70 48 65 61 64 2e 0a 2a 2a 20 2a  by *ppHead..** *
1ff0: 70 70 48 65 61 64 20 69 73 20 65 69 74 68 65 72  ppHead is either
2000: 20 50 43 61 63 68 65 2e 70 43 6c 65 61 6e 20 6f   PCache.pClean o
2010: 72 20 50 43 61 63 68 65 2e 70 44 69 72 74 79 2e  r PCache.pDirty.
2020: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
2030: 70 63 61 63 68 65 41 64 64 54 6f 4c 69 73 74 28  pcacheAddToList(
2040: 50 67 48 64 72 20 2a 2a 70 70 48 65 61 64 2c 20  PgHdr **ppHead, 
2050: 50 67 48 64 72 20 2a 70 50 61 67 65 29 7b 0a 20  PgHdr *pPage){. 
2060: 20 69 6e 74 20 69 73 44 69 72 74 79 4c 69 73 74   int isDirtyList
2070: 20 3d 20 28 70 70 48 65 61 64 3d 3d 26 70 50 61   = (ppHead==&pPa
2080: 67 65 2d 3e 70 43 61 63 68 65 2d 3e 70 44 69 72  ge->pCache->pDir
2090: 74 79 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70  ty);.  assert( p
20a0: 70 48 65 61 64 3d 3d 26 70 50 61 67 65 2d 3e 70  pHead==&pPage->p
20b0: 43 61 63 68 65 2d 3e 70 43 6c 65 61 6e 20 7c 7c  Cache->pClean ||
20c0: 20 70 70 48 65 61 64 3d 3d 26 70 50 61 67 65 2d   ppHead==&pPage-
20d0: 3e 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 20  >pCache->pDirty 
20e0: 29 3b 0a 0a 20 20 69 66 28 20 28 2a 70 70 48 65  );..  if( (*ppHe
20f0: 61 64 29 20 29 7b 0a 20 20 20 20 28 2a 70 70 48  ad) ){.    (*ppH
2100: 65 61 64 29 2d 3e 70 50 72 65 76 20 3d 20 70 50  ead)->pPrev = pP
2110: 61 67 65 3b 0a 20 20 7d 0a 20 20 70 50 61 67 65  age;.  }.  pPage
2120: 2d 3e 70 4e 65 78 74 20 3d 20 2a 70 70 48 65 61  ->pNext = *ppHea
2130: 64 3b 0a 20 20 70 50 61 67 65 2d 3e 70 50 72 65  d;.  pPage->pPre
2140: 76 20 3d 20 30 3b 0a 20 20 2a 70 70 48 65 61 64  v = 0;.  *ppHead
2150: 20 3d 20 70 50 61 67 65 3b 0a 0a 20 20 69 66 28   = pPage;..  if(
2160: 20 69 73 44 69 72 74 79 4c 69 73 74 20 29 7b 0a   isDirtyList ){.
2170: 20 20 20 20 50 43 61 63 68 65 20 2a 70 43 61 63      PCache *pCac
2180: 68 65 20 3d 20 70 50 61 67 65 2d 3e 70 43 61 63  he = pPage->pCac
2190: 68 65 3b 0a 20 20 20 20 69 66 28 20 21 70 43 61  he;.    if( !pCa
21a0: 63 68 65 2d 3e 70 44 69 72 74 79 54 61 69 6c 20  che->pDirtyTail 
21b0: 29 7b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28  ){.      assert(
21c0: 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 3d 3d 30   pPage->pNext==0
21d0: 20 29 3b 0a 20 20 20 20 20 20 70 43 61 63 68 65   );.      pCache
21e0: 2d 3e 70 44 69 72 74 79 54 61 69 6c 20 3d 20 70  ->pDirtyTail = p
21f0: 50 61 67 65 3b 0a 20 20 20 20 7d 0a 20 20 20 20  Page;.    }.    
2200: 69 66 28 20 21 70 43 61 63 68 65 2d 3e 70 53 79  if( !pCache->pSy
2210: 6e 63 65 64 20 26 26 20 30 3d 3d 28 70 50 61 67  nced && 0==(pPag
2220: 65 2d 3e 66 6c 61 67 73 26 50 47 48 44 52 5f 4e  e->flags&PGHDR_N
2230: 45 45 44 5f 53 59 4e 43 29 20 29 7b 0a 20 20 20  EED_SYNC) ){.   
2240: 20 20 20 70 43 61 63 68 65 2d 3e 70 53 79 6e 63     pCache->pSync
2250: 65 64 20 3d 20 70 50 61 67 65 3b 0a 20 20 20 20  ed = pPage;.    
2260: 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  }.  }.}../*.** R
2270: 65 6d 6f 76 65 20 61 20 70 61 67 65 20 66 72 6f  emove a page fro
2280: 6d 20 74 68 65 20 67 6c 6f 62 61 6c 20 4c 52 55  m the global LRU
2290: 20 6c 69 73 74 0a 2a 2f 0a 73 74 61 74 69 63 20   list.*/.static 
22a0: 76 6f 69 64 20 70 63 61 63 68 65 52 65 6d 6f 76  void pcacheRemov
22b0: 65 46 72 6f 6d 4c 72 75 4c 69 73 74 28 50 67 48  eFromLruList(PgH
22c0: 64 72 20 2a 70 50 61 67 65 29 7b 0a 20 20 61 73  dr *pPage){.  as
22d0: 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75  sert( sqlite3_mu
22e0: 74 65 78 5f 68 65 6c 64 28 70 63 61 63 68 65 2e  tex_held(pcache.
22f0: 6d 75 74 65 78 29 20 29 3b 0a 20 20 61 73 73 65  mutex) );.  asse
2300: 72 74 28 20 28 70 50 61 67 65 2d 3e 66 6c 61 67  rt( (pPage->flag
2310: 73 26 50 47 48 44 52 5f 44 49 52 54 59 29 3d 3d  s&PGHDR_DIRTY)==
2320: 30 20 29 3b 0a 20 20 69 66 28 20 70 50 61 67 65  0 );.  if( pPage
2330: 2d 3e 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65  ->pCache->bPurge
2340: 61 62 6c 65 3d 3d 30 20 29 20 72 65 74 75 72 6e  able==0 ) return
2350: 3b 0a 20 20 69 66 28 20 70 50 61 67 65 2d 3e 70  ;.  if( pPage->p
2360: 4e 65 78 74 4c 72 75 20 29 7b 0a 20 20 20 20 61  NextLru ){.    a
2370: 73 73 65 72 74 28 20 70 63 61 63 68 65 2e 70 4c  ssert( pcache.pL
2380: 72 75 54 61 69 6c 21 3d 70 50 61 67 65 20 29 3b  ruTail!=pPage );
2390: 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 4e 65 78  .    pPage->pNex
23a0: 74 4c 72 75 2d 3e 70 50 72 65 76 4c 72 75 20 3d  tLru->pPrevLru =
23b0: 20 70 50 61 67 65 2d 3e 70 50 72 65 76 4c 72 75   pPage->pPrevLru
23c0: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 61  ;.  }else{.    a
23d0: 73 73 65 72 74 28 20 70 63 61 63 68 65 2e 70 4c  ssert( pcache.pL
23e0: 72 75 54 61 69 6c 3d 3d 70 50 61 67 65 20 29 3b  ruTail==pPage );
23f0: 0a 20 20 20 20 70 63 61 63 68 65 2e 70 4c 72 75  .    pcache.pLru
2400: 54 61 69 6c 20 3d 20 70 50 61 67 65 2d 3e 70 50  Tail = pPage->pP
2410: 72 65 76 4c 72 75 3b 0a 20 20 7d 0a 20 20 69 66  revLru;.  }.  if
2420: 28 20 70 50 61 67 65 2d 3e 70 50 72 65 76 4c 72  ( pPage->pPrevLr
2430: 75 20 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28  u ){.    assert(
2440: 20 70 63 61 63 68 65 2e 70 4c 72 75 48 65 61 64   pcache.pLruHead
2450: 21 3d 70 50 61 67 65 20 29 3b 0a 20 20 20 20 70  !=pPage );.    p
2460: 50 61 67 65 2d 3e 70 50 72 65 76 4c 72 75 2d 3e  Page->pPrevLru->
2470: 70 4e 65 78 74 4c 72 75 20 3d 20 70 50 61 67 65  pNextLru = pPage
2480: 2d 3e 70 4e 65 78 74 4c 72 75 3b 0a 20 20 7d 65  ->pNextLru;.  }e
2490: 6c 73 65 7b 0a 20 20 20 20 61 73 73 65 72 74 28  lse{.    assert(
24a0: 20 70 63 61 63 68 65 2e 70 4c 72 75 48 65 61 64   pcache.pLruHead
24b0: 3d 3d 70 50 61 67 65 20 29 3b 0a 20 20 20 20 70  ==pPage );.    p
24c0: 63 61 63 68 65 2e 70 4c 72 75 48 65 61 64 20 3d  cache.pLruHead =
24d0: 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 4c 72 75   pPage->pNextLru
24e0: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41  ;.  }.}../*.** A
24f0: 64 64 20 61 20 70 61 67 65 20 74 6f 20 74 68 65  dd a page to the
2500: 20 67 6c 6f 62 61 6c 20 4c 52 55 20 6c 69 73 74   global LRU list
2510: 2e 20 20 54 68 65 20 70 61 67 65 20 69 73 20 6e  .  The page is n
2520: 6f 72 6d 61 6c 6c 79 20 61 64 64 65 64 0a 2a 2a  ormally added.**
2530: 20 74 6f 20 74 68 65 20 66 72 6f 6e 74 20 6f 66   to the front of
2540: 20 74 68 65 20 6c 69 73 74 20 73 6f 20 74 68 61   the list so tha
2550: 74 20 69 74 20 77 69 6c 6c 20 62 65 20 74 68 65  t it will be the
2560: 20 6c 61 73 74 20 70 61 67 65 20 72 65 63 79 63   last page recyc
2570: 6c 65 64 2e 0a 2a 2a 20 48 6f 77 65 76 65 72 2c  led..** However,
2580: 20 69 66 20 74 68 65 20 50 47 48 44 52 5f 52 45   if the PGHDR_RE
2590: 55 53 45 5f 55 4e 4c 49 4b 45 4c 59 20 62 69 74  USE_UNLIKELY bit
25a0: 20 69 73 20 73 65 74 2c 20 74 68 65 20 70 61 67   is set, the pag
25b0: 65 20 69 73 20 61 64 64 65 64 0a 2a 2a 20 74 6f  e is added.** to
25c0: 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68 65 20   the end of the 
25d0: 4c 52 55 20 6c 69 73 74 20 73 6f 20 74 68 61 74  LRU list so that
25e0: 20 69 74 20 77 69 6c 6c 20 62 65 20 74 68 65 20   it will be the 
25f0: 6e 65 78 74 20 74 6f 20 62 65 20 72 65 63 79 63  next to be recyc
2600: 6c 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  led..*/.static v
2610: 6f 69 64 20 70 63 61 63 68 65 41 64 64 54 6f 4c  oid pcacheAddToL
2620: 72 75 4c 69 73 74 28 50 67 48 64 72 20 2a 70 50  ruList(PgHdr *pP
2630: 61 67 65 29 7b 0a 20 20 61 73 73 65 72 74 28 20  age){.  assert( 
2640: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65  sqlite3_mutex_he
2650: 6c 64 28 70 63 61 63 68 65 2e 6d 75 74 65 78 29  ld(pcache.mutex)
2660: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 28 70   );.  assert( (p
2670: 50 61 67 65 2d 3e 66 6c 61 67 73 26 50 47 48 44  Page->flags&PGHD
2680: 52 5f 44 49 52 54 59 29 3d 3d 30 20 29 3b 0a 20  R_DIRTY)==0 );. 
2690: 20 69 66 28 20 70 50 61 67 65 2d 3e 70 43 61 63   if( pPage->pCac
26a0: 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 3d 3d  he->bPurgeable==
26b0: 30 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 69 66  0 ) return;.  if
26c0: 28 20 70 63 61 63 68 65 2e 70 4c 72 75 54 61 69  ( pcache.pLruTai
26d0: 6c 20 26 26 20 28 70 50 61 67 65 2d 3e 66 6c 61  l && (pPage->fla
26e0: 67 73 20 26 20 50 47 48 44 52 5f 52 45 55 53 45  gs & PGHDR_REUSE
26f0: 5f 55 4e 4c 49 4b 45 4c 59 29 21 3d 30 20 29 7b  _UNLIKELY)!=0 ){
2700: 0a 20 20 20 20 2f 2a 20 49 66 20 72 65 75 73 65  .    /* If reuse
2710: 20 69 73 20 75 6e 6c 69 6b 65 6c 79 2e 20 20 50   is unlikely.  P
2720: 75 74 20 74 68 65 20 70 61 67 65 20 61 74 20 74  ut the page at t
2730: 68 65 20 65 6e 64 20 6f 66 20 74 68 65 20 4c 52  he end of the LR
2740: 55 20 6c 69 73 74 0a 20 20 20 20 2a 2a 20 77 68  U list.    ** wh
2750: 65 72 65 20 69 74 20 77 69 6c 6c 20 62 65 20 72  ere it will be r
2760: 65 63 79 63 6c 65 64 20 73 6f 6f 6e 65 72 20 72  ecycled sooner r
2770: 61 74 68 65 72 20 74 68 61 6e 20 6c 61 74 65 72  ather than later
2780: 2e 20 0a 20 20 20 20 2a 2f 0a 20 20 20 20 61 73  . .    */.    as
2790: 73 65 72 74 28 20 70 63 61 63 68 65 2e 70 4c 72  sert( pcache.pLr
27a0: 75 48 65 61 64 20 29 3b 0a 20 20 20 20 70 50 61  uHead );.    pPa
27b0: 67 65 2d 3e 70 4e 65 78 74 4c 72 75 20 3d 20 30  ge->pNextLru = 0
27c0: 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 50 72  ;.    pPage->pPr
27d0: 65 76 4c 72 75 20 3d 20 70 63 61 63 68 65 2e 70  evLru = pcache.p
27e0: 4c 72 75 54 61 69 6c 3b 0a 20 20 20 20 70 63 61  LruTail;.    pca
27f0: 63 68 65 2e 70 4c 72 75 54 61 69 6c 2d 3e 70 4e  che.pLruTail->pN
2800: 65 78 74 4c 72 75 20 3d 20 70 50 61 67 65 3b 0a  extLru = pPage;.
2810: 20 20 20 20 70 63 61 63 68 65 2e 70 4c 72 75 54      pcache.pLruT
2820: 61 69 6c 20 3d 20 70 50 61 67 65 3b 0a 20 20 20  ail = pPage;.   
2830: 20 70 50 61 67 65 2d 3e 66 6c 61 67 73 20 26 3d   pPage->flags &=
2840: 20 7e 50 47 48 44 52 5f 52 45 55 53 45 5f 55 4e   ~PGHDR_REUSE_UN
2850: 4c 49 4b 45 4c 59 3b 0a 20 20 7d 65 6c 73 65 7b  LIKELY;.  }else{
2860: 0a 20 20 20 20 2f 2a 20 49 66 20 72 65 75 73 65  .    /* If reuse
2870: 20 69 73 20 70 6f 73 73 69 62 6c 65 2e 20 74 68   is possible. th
2880: 65 20 70 61 67 65 20 67 6f 65 73 20 61 74 20 74  e page goes at t
2890: 68 65 20 62 65 67 69 6e 6e 69 6e 67 20 6f 66 20  he beginning of 
28a0: 74 68 65 20 4c 52 55 0a 20 20 20 20 2a 2a 20 6c  the LRU.    ** l
28b0: 69 73 74 20 73 6f 20 74 68 61 74 20 69 74 20 77  ist so that it w
28c0: 69 6c 6c 20 62 65 20 74 68 65 20 6c 61 73 74 20  ill be the last 
28d0: 74 6f 20 62 65 20 72 65 63 79 63 6c 65 64 2e 0a  to be recycled..
28e0: 20 20 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 70      */.    if( p
28f0: 63 61 63 68 65 2e 70 4c 72 75 48 65 61 64 20 29  cache.pLruHead )
2900: 7b 0a 20 20 20 20 20 20 70 63 61 63 68 65 2e 70  {.      pcache.p
2910: 4c 72 75 48 65 61 64 2d 3e 70 50 72 65 76 4c 72  LruHead->pPrevLr
2920: 75 20 3d 20 70 50 61 67 65 3b 0a 20 20 20 20 7d  u = pPage;.    }
2930: 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 4e 65 78  .    pPage->pNex
2940: 74 4c 72 75 20 3d 20 70 63 61 63 68 65 2e 70 4c  tLru = pcache.pL
2950: 72 75 48 65 61 64 3b 0a 20 20 20 20 70 63 61 63  ruHead;.    pcac
2960: 68 65 2e 70 4c 72 75 48 65 61 64 20 3d 20 70 50  he.pLruHead = pP
2970: 61 67 65 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e  age;.    pPage->
2980: 70 50 72 65 76 4c 72 75 20 3d 20 30 3b 0a 20 20  pPrevLru = 0;.  
2990: 20 20 69 66 28 20 70 63 61 63 68 65 2e 70 4c 72    if( pcache.pLr
29a0: 75 54 61 69 6c 3d 3d 30 20 29 7b 0a 20 20 20 20  uTail==0 ){.    
29b0: 20 20 70 63 61 63 68 65 2e 70 4c 72 75 54 61 69    pcache.pLruTai
29c0: 6c 20 3d 20 70 50 61 67 65 3b 0a 20 20 20 20 7d  l = pPage;.    }
29d0: 0a 20 20 7d 0a 7d 0a 0a 2f 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 2a 2a 2a 2a  ****************
2a00: 2a 2a 2a 2a 2a 2a 2a 2a 20 4d 65 6d 6f 72 79 20  ******** Memory 
2a10: 41 6c 6c 6f 63 61 74 69 6f 6e 20 2a 2a 2a 2a 2a  Allocation *****
2a20: 2a 2a 2a 2a 2a 2a 0a 2a 2a 0a 2a 2a 20 49 6e 69  ******.**.** Ini
2a30: 74 69 61 6c 69 7a 65 20 74 68 65 20 70 61 67 65  tialize the page
2a40: 20 63 61 63 68 65 20 6d 65 6d 6f 72 79 20 70 6f   cache memory po
2a50: 6f 6c 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 6d  ol..**.** This m
2a60: 75 73 74 20 62 65 20 63 61 6c 6c 65 64 20 61 74  ust be called at
2a70: 20 73 74 61 72 74 2d 74 69 6d 65 20 77 68 65 6e   start-time when
2a80: 20 6e 6f 20 70 61 67 65 20 63 61 63 68 65 20 6c   no page cache l
2a90: 69 6e 65 73 20 61 72 65 0a 2a 2a 20 63 68 65 63  ines are.** chec
2aa0: 6b 65 64 20 6f 75 74 2e 20 54 68 69 73 20 66 75  ked out. This fu
2ab0: 6e 63 74 69 6f 6e 20 69 73 20 6e 6f 74 20 74 68  nction is not th
2ac0: 72 65 61 64 73 61 66 65 2e 0a 2a 2f 0a 76 6f 69  readsafe..*/.voi
2ad0: 64 20 73 71 6c 69 74 65 33 50 43 61 63 68 65 42  d sqlite3PCacheB
2ae0: 75 66 66 65 72 53 65 74 75 70 28 76 6f 69 64 20  ufferSetup(void 
2af0: 2a 70 42 75 66 2c 20 69 6e 74 20 73 7a 2c 20 69  *pBuf, int sz, i
2b00: 6e 74 20 6e 29 7b 0a 20 20 50 67 46 72 65 65 73  nt n){.  PgFrees
2b10: 6c 6f 74 20 2a 70 3b 0a 20 20 73 7a 20 26 3d 20  lot *p;.  sz &= 
2b20: 7e 37 3b 0a 20 20 70 63 61 63 68 65 2e 73 7a 53  ~7;.  pcache.szS
2b30: 6c 6f 74 20 3d 20 73 7a 3b 0a 20 20 70 63 61 63  lot = sz;.  pcac
2b40: 68 65 2e 70 53 74 61 72 74 20 3d 20 70 42 75 66  he.pStart = pBuf
2b50: 3b 0a 20 20 70 63 61 63 68 65 2e 70 46 72 65 65  ;.  pcache.pFree
2b60: 20 3d 20 30 3b 0a 20 20 77 68 69 6c 65 28 20 6e   = 0;.  while( n
2b70: 2d 2d 20 29 7b 0a 20 20 20 20 70 20 3d 20 28 50  -- ){.    p = (P
2b80: 67 46 72 65 65 73 6c 6f 74 2a 29 70 42 75 66 3b  gFreeslot*)pBuf;
2b90: 0a 20 20 20 20 70 2d 3e 70 4e 65 78 74 20 3d 20  .    p->pNext = 
2ba0: 70 63 61 63 68 65 2e 70 46 72 65 65 3b 0a 20 20  pcache.pFree;.  
2bb0: 20 20 70 63 61 63 68 65 2e 70 46 72 65 65 20 3d    pcache.pFree =
2bc0: 20 70 3b 0a 20 20 20 20 70 42 75 66 20 3d 20 28   p;.    pBuf = (
2bd0: 76 6f 69 64 2a 29 26 28 28 63 68 61 72 2a 29 70  void*)&((char*)p
2be0: 42 75 66 29 5b 73 7a 5d 3b 0a 20 20 7d 0a 20 20  Buf)[sz];.  }.  
2bf0: 70 63 61 63 68 65 2e 70 45 6e 64 20 3d 20 70 42  pcache.pEnd = pB
2c00: 75 66 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c  uf;.}../*.** All
2c10: 6f 63 61 74 65 20 61 20 70 61 67 65 20 63 61 63  ocate a page cac
2c20: 68 65 20 6c 69 6e 65 2e 20 20 4c 6f 6f 6b 20 69  he line.  Look i
2c30: 6e 20 74 68 65 20 70 61 67 65 20 63 61 63 68 65  n the page cache
2c40: 20 6d 65 6d 6f 72 79 20 70 6f 6f 6c 20 66 69 72   memory pool fir
2c50: 73 74 0a 2a 2a 20 61 6e 64 20 75 73 65 20 61 6e  st.** and use an
2c60: 20 65 6c 65 6d 65 6e 74 20 66 72 6f 6d 20 69 74   element from it
2c70: 20 66 69 72 73 74 20 69 66 20 61 76 61 69 6c 61   first if availa
2c80: 62 6c 65 2e 20 20 49 66 20 6e 6f 74 68 69 6e 67  ble.  If nothing
2c90: 20 69 73 20 61 76 61 69 6c 61 62 6c 65 0a 2a 2a   is available.**
2ca0: 20 69 6e 20 74 68 65 20 70 61 67 65 20 63 61 63   in the page cac
2cb0: 68 65 20 6d 65 6d 6f 72 79 20 70 6f 6f 6c 2c 20  he memory pool, 
2cc0: 67 6f 20 74 6f 20 74 68 65 20 67 65 6e 65 72 61  go to the genera
2cd0: 6c 20 70 75 72 70 6f 73 65 20 6d 65 6d 6f 72 79  l purpose memory
2ce0: 20 61 6c 6c 6f 63 61 74 6f 72 2e 0a 2a 2f 0a 76   allocator..*/.v
2cf0: 6f 69 64 20 2a 70 63 61 63 68 65 4d 61 6c 6c 6f  oid *pcacheMallo
2d00: 63 28 69 6e 74 20 73 7a 2c 20 50 43 61 63 68 65  c(int sz, PCache
2d10: 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 61 73 73   *pCache){.  ass
2d20: 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74  ert( sqlite3_mut
2d30: 65 78 5f 68 65 6c 64 28 70 63 61 63 68 65 2e 6d  ex_held(pcache.m
2d40: 75 74 65 78 29 20 29 3b 0a 20 20 69 66 28 20 73  utex) );.  if( s
2d50: 7a 3c 3d 70 63 61 63 68 65 2e 73 7a 53 6c 6f 74  z<=pcache.szSlot
2d60: 20 26 26 20 70 63 61 63 68 65 2e 70 46 72 65 65   && pcache.pFree
2d70: 20 29 7b 0a 20 20 20 20 50 67 46 72 65 65 73 6c   ){.    PgFreesl
2d80: 6f 74 20 2a 70 20 3d 20 70 63 61 63 68 65 2e 70  ot *p = pcache.p
2d90: 46 72 65 65 3b 0a 20 20 20 20 70 63 61 63 68 65  Free;.    pcache
2da0: 2e 70 46 72 65 65 20 3d 20 70 2d 3e 70 4e 65 78  .pFree = p->pNex
2db0: 74 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 53 74  t;.    sqlite3St
2dc0: 61 74 75 73 53 65 74 28 53 51 4c 49 54 45 5f 53  atusSet(SQLITE_S
2dd0: 54 41 54 55 53 5f 50 41 47 45 43 41 43 48 45 5f  TATUS_PAGECACHE_
2de0: 53 49 5a 45 2c 20 73 7a 29 3b 0a 20 20 20 20 73  SIZE, sz);.    s
2df0: 71 6c 69 74 65 33 53 74 61 74 75 73 41 64 64 28  qlite3StatusAdd(
2e00: 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41  SQLITE_STATUS_PA
2e10: 47 45 43 41 43 48 45 5f 55 53 45 44 2c 20 31 29  GECACHE_USED, 1)
2e20: 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 28 76 6f  ;.    return (vo
2e30: 69 64 2a 29 70 3b 0a 20 20 7d 65 6c 73 65 7b 0a  id*)p;.  }else{.
2e40: 20 20 20 20 76 6f 69 64 20 2a 70 3b 0a 0a 20 20      void *p;..  
2e50: 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 61 20    /* Allocate a 
2e60: 6e 65 77 20 62 75 66 66 65 72 20 75 73 69 6e 67  new buffer using
2e70: 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 2e 20   sqlite3Malloc. 
2e80: 42 65 66 6f 72 65 20 64 6f 69 6e 67 20 73 6f 2c  Before doing so,
2e90: 20 65 78 69 74 20 74 68 65 0a 20 20 20 20 2a 2a   exit the.    **
2ea0: 20 67 6c 6f 62 61 6c 20 70 63 61 63 68 65 20 6d   global pcache m
2eb0: 75 74 65 78 20 61 6e 64 20 75 6e 6c 6f 63 6b 20  utex and unlock 
2ec0: 74 68 65 20 70 61 67 65 72 2d 63 61 63 68 65 20  the pager-cache 
2ed0: 6f 62 6a 65 63 74 20 70 43 61 63 68 65 2e 20 54  object pCache. T
2ee0: 68 69 73 20 69 73 20 0a 20 20 20 20 2a 2a 20 73  his is .    ** s
2ef0: 6f 20 74 68 61 74 20 69 66 20 74 68 65 20 61 74  o that if the at
2f00: 74 65 6d 70 74 20 74 6f 20 61 6c 6c 6f 63 61 74  tempt to allocat
2f10: 65 20 61 20 6e 65 77 20 62 75 66 66 65 72 20 63  e a new buffer c
2f20: 61 75 73 65 73 20 74 68 65 20 74 68 65 20 0a 20  auses the the . 
2f30: 20 20 20 2a 2a 20 63 6f 6e 66 69 67 75 72 65 64     ** configured
2f40: 20 73 6f 66 74 2d 68 65 61 70 2d 6c 69 6d 69 74   soft-heap-limit
2f50: 20 74 6f 20 62 65 20 62 72 65 61 63 68 65 64 2c   to be breached,
2f60: 20 69 74 20 77 69 6c 6c 20 62 65 20 70 6f 73 73   it will be poss
2f70: 69 62 6c 65 20 74 6f 0a 20 20 20 20 2a 2a 20 72  ible to.    ** r
2f80: 65 63 6c 61 69 6d 20 6d 65 6d 6f 72 79 20 66 72  eclaim memory fr
2f90: 6f 6d 20 74 68 69 73 20 70 61 67 65 72 2d 63 61  om this pager-ca
2fa0: 63 68 65 2e 20 42 65 63 61 75 73 65 20 73 71 6c  che. Because sql
2fb0: 69 74 65 33 50 63 61 63 68 65 4c 6f 63 6b 28 29  ite3PcacheLock()
2fc0: 20 0a 20 20 20 20 2a 2a 20 6d 69 67 68 74 20 62   .    ** might b
2fd0: 6c 6f 63 6b 20 6f 6e 20 74 68 65 20 4d 45 4d 32  lock on the MEM2
2fe0: 20 6d 75 74 65 78 2c 20 69 74 20 68 61 73 20 74   mutex, it has t
2ff0: 6f 20 62 65 20 63 61 6c 6c 65 64 20 62 65 66 6f  o be called befo
3000: 72 65 20 72 65 2d 65 6e 74 65 72 69 6e 67 0a 20  re re-entering. 
3010: 20 20 20 2a 2a 20 74 68 65 20 67 6c 6f 62 61 6c     ** the global
3020: 20 4c 52 55 20 6d 75 74 65 78 2e 0a 20 20 20 20   LRU mutex..    
3030: 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 45 78 69  */.    pcacheExi
3040: 74 47 6c 6f 62 61 6c 28 29 3b 0a 20 20 20 20 70  tGlobal();.    p
3050: 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63   = sqlite3Malloc
3060: 28 73 7a 29 3b 0a 20 20 20 20 70 63 61 63 68 65  (sz);.    pcache
3070: 45 6e 74 65 72 47 6c 6f 62 61 6c 28 29 3b 0a 0a  EnterGlobal();..
3080: 20 20 20 20 69 66 28 20 70 20 29 7b 0a 20 20 20      if( p ){.   
3090: 20 20 20 73 7a 20 3d 20 73 71 6c 69 74 65 33 4d     sz = sqlite3M
30a0: 61 6c 6c 6f 63 53 69 7a 65 28 70 29 3b 0a 20 20  allocSize(p);.  
30b0: 20 20 20 20 73 71 6c 69 74 65 33 53 74 61 74 75      sqlite3Statu
30c0: 73 41 64 64 28 53 51 4c 49 54 45 5f 53 54 41 54  sAdd(SQLITE_STAT
30d0: 55 53 5f 50 41 47 45 43 41 43 48 45 5f 4f 56 45  US_PAGECACHE_OVE
30e0: 52 46 4c 4f 57 2c 20 73 7a 29 3b 0a 20 20 20 20  RFLOW, sz);.    
30f0: 7d 0a 20 20 20 20 72 65 74 75 72 6e 20 70 3b 0a  }.    return p;.
3100: 20 20 7d 0a 7d 0a 76 6f 69 64 20 2a 73 71 6c 69    }.}.void *sqli
3110: 74 65 33 50 61 67 65 4d 61 6c 6c 6f 63 28 73 7a  te3PageMalloc(sz
3120: 29 7b 0a 20 20 76 6f 69 64 20 2a 70 3b 0a 20 20  ){.  void *p;.  
3130: 70 63 61 63 68 65 45 6e 74 65 72 47 6c 6f 62 61  pcacheEnterGloba
3140: 6c 28 29 3b 0a 20 20 70 20 3d 20 70 63 61 63 68  l();.  p = pcach
3150: 65 4d 61 6c 6c 6f 63 28 73 7a 2c 20 30 29 3b 0a  eMalloc(sz, 0);.
3160: 20 20 70 63 61 63 68 65 45 78 69 74 47 6c 6f 62    pcacheExitGlob
3170: 61 6c 28 29 3b 0a 20 20 72 65 74 75 72 6e 20 70  al();.  return p
3180: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 6c 65 61  ;.}../*.** Relea
3190: 73 65 20 61 20 70 61 67 65 72 20 6d 65 6d 6f 72  se a pager memor
31a0: 79 20 61 6c 6c 6f 63 61 74 69 6f 6e 0a 2a 2f 0a  y allocation.*/.
31b0: 76 6f 69 64 20 70 63 61 63 68 65 46 72 65 65 28  void pcacheFree(
31c0: 76 6f 69 64 20 2a 70 29 7b 0a 20 20 61 73 73 65  void *p){.  asse
31d0: 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65  rt( sqlite3_mute
31e0: 78 5f 68 65 6c 64 28 70 63 61 63 68 65 2e 6d 75  x_held(pcache.mu
31f0: 74 65 78 29 20 29 3b 0a 20 20 69 66 28 20 70 3d  tex) );.  if( p=
3200: 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 69  =0 ) return;.  i
3210: 66 28 20 70 3e 3d 70 63 61 63 68 65 2e 70 53 74  f( p>=pcache.pSt
3220: 61 72 74 20 26 26 20 70 3c 70 63 61 63 68 65 2e  art && p<pcache.
3230: 70 45 6e 64 20 29 7b 0a 20 20 20 20 50 67 46 72  pEnd ){.    PgFr
3240: 65 65 73 6c 6f 74 20 2a 70 53 6c 6f 74 3b 0a 20  eeslot *pSlot;. 
3250: 20 20 20 73 71 6c 69 74 65 33 53 74 61 74 75 73     sqlite3Status
3260: 41 64 64 28 53 51 4c 49 54 45 5f 53 54 41 54 55  Add(SQLITE_STATU
3270: 53 5f 50 41 47 45 43 41 43 48 45 5f 55 53 45 44  S_PAGECACHE_USED
3280: 2c 20 2d 31 29 3b 0a 20 20 20 20 70 53 6c 6f 74  , -1);.    pSlot
3290: 20 3d 20 28 50 67 46 72 65 65 73 6c 6f 74 2a 29   = (PgFreeslot*)
32a0: 70 3b 0a 20 20 20 20 70 53 6c 6f 74 2d 3e 70 4e  p;.    pSlot->pN
32b0: 65 78 74 20 3d 20 70 63 61 63 68 65 2e 70 46 72  ext = pcache.pFr
32c0: 65 65 3b 0a 20 20 20 20 70 63 61 63 68 65 2e 70  ee;.    pcache.p
32d0: 46 72 65 65 20 3d 20 70 53 6c 6f 74 3b 0a 20 20  Free = pSlot;.  
32e0: 7d 65 6c 73 65 7b 0a 20 20 20 20 69 6e 74 20 69  }else{.    int i
32f0: 53 69 7a 65 20 3d 20 73 71 6c 69 74 65 33 4d 61  Size = sqlite3Ma
3300: 6c 6c 6f 63 53 69 7a 65 28 70 29 3b 0a 20 20 20  llocSize(p);.   
3310: 20 73 71 6c 69 74 65 33 53 74 61 74 75 73 41 64   sqlite3StatusAd
3320: 64 28 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f  d(SQLITE_STATUS_
3330: 50 41 47 45 43 41 43 48 45 5f 4f 56 45 52 46 4c  PAGECACHE_OVERFL
3340: 4f 57 2c 20 2d 69 53 69 7a 65 29 3b 0a 20 20 20  OW, -iSize);.   
3350: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 29   sqlite3_free(p)
3360: 3b 0a 20 20 7d 0a 7d 0a 76 6f 69 64 20 73 71 6c  ;.  }.}.void sql
3370: 69 74 65 33 50 61 67 65 46 72 65 65 28 76 6f 69  ite3PageFree(voi
3380: 64 20 2a 70 29 7b 0a 20 20 70 63 61 63 68 65 45  d *p){.  pcacheE
3390: 6e 74 65 72 47 6c 6f 62 61 6c 28 29 3b 0a 20 20  nterGlobal();.  
33a0: 70 63 61 63 68 65 46 72 65 65 28 70 29 3b 0a 20  pcacheFree(p);. 
33b0: 20 70 63 61 63 68 65 45 78 69 74 47 6c 6f 62 61   pcacheExitGloba
33c0: 6c 28 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 6c  l();.}../*.** Al
33d0: 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 70 61 67  locate a new pag
33e0: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 50 67 48  e..*/.static PgH
33f0: 64 72 20 2a 70 63 61 63 68 65 50 61 67 65 41 6c  dr *pcachePageAl
3400: 6c 6f 63 28 50 43 61 63 68 65 20 2a 70 43 61 63  loc(PCache *pCac
3410: 68 65 29 7b 0a 20 20 50 67 48 64 72 20 2a 70 3b  he){.  PgHdr *p;
3420: 0a 20 20 69 6e 74 20 73 7a 20 3d 20 73 69 7a 65  .  int sz = size
3430: 6f 66 28 2a 70 29 20 2b 20 70 43 61 63 68 65 2d  of(*p) + pCache-
3440: 3e 73 7a 50 61 67 65 20 2b 20 70 43 61 63 68 65  >szPage + pCache
3450: 2d 3e 73 7a 45 78 74 72 61 3b 0a 20 20 61 73 73  ->szExtra;.  ass
3460: 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74  ert( sqlite3_mut
3470: 65 78 5f 68 65 6c 64 28 70 63 61 63 68 65 2e 6d  ex_held(pcache.m
3480: 75 74 65 78 29 20 29 3b 0a 20 20 70 20 3d 20 70  utex) );.  p = p
3490: 63 61 63 68 65 4d 61 6c 6c 6f 63 28 73 7a 2c 20  cacheMalloc(sz, 
34a0: 70 43 61 63 68 65 29 3b 0a 20 20 69 66 28 20 70  pCache);.  if( p
34b0: 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 30 3b 0a  ==0 ) return 0;.
34c0: 20 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20 73    memset(p, 0, s
34d0: 69 7a 65 6f 66 28 50 67 48 64 72 29 29 3b 0a 20  izeof(PgHdr));. 
34e0: 20 70 2d 3e 70 44 61 74 61 20 3d 20 28 76 6f 69   p->pData = (voi
34f0: 64 2a 29 26 70 5b 31 5d 3b 0a 20 20 70 2d 3e 70  d*)&p[1];.  p->p
3500: 45 78 74 72 61 20 3d 20 28 76 6f 69 64 2a 29 26  Extra = (void*)&
3510: 28 28 63 68 61 72 2a 29 70 2d 3e 70 44 61 74 61  ((char*)p->pData
3520: 29 5b 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65  )[pCache->szPage
3530: 5d 3b 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d  ];.  if( pCache-
3540: 3e 62 50 75 72 67 65 61 62 6c 65 20 29 7b 0a 20  >bPurgeable ){. 
3550: 20 20 20 70 63 61 63 68 65 2e 6e 43 75 72 72 65     pcache.nCurre
3560: 6e 74 50 61 67 65 2b 2b 3b 0a 20 20 7d 0a 20 20  ntPage++;.  }.  
3570: 72 65 74 75 72 6e 20 70 3b 0a 7d 0a 0a 2f 2a 0a  return p;.}../*.
3580: 2a 2a 20 44 65 61 6c 6c 6f 63 61 74 65 20 61 20  ** Deallocate a 
3590: 70 61 67 65 0a 2a 2f 0a 73 74 61 74 69 63 20 76  page.*/.static v
35a0: 6f 69 64 20 70 63 61 63 68 65 50 61 67 65 46 72  oid pcachePageFr
35b0: 65 65 28 50 67 48 64 72 20 2a 70 29 7b 0a 20 20  ee(PgHdr *p){.  
35c0: 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f  assert( sqlite3_
35d0: 6d 75 74 65 78 5f 68 65 6c 64 28 70 63 61 63 68  mutex_held(pcach
35e0: 65 2e 6d 75 74 65 78 29 20 29 3b 0a 20 20 69 66  e.mutex) );.  if
35f0: 28 20 70 2d 3e 70 43 61 63 68 65 2d 3e 62 50 75  ( p->pCache->bPu
3600: 72 67 65 61 62 6c 65 20 29 7b 0a 20 20 20 20 70  rgeable ){.    p
3610: 63 61 63 68 65 2e 6e 43 75 72 72 65 6e 74 50 61  cache.nCurrentPa
3620: 67 65 2d 2d 3b 0a 20 20 7d 0a 20 20 70 63 61 63  ge--;.  }.  pcac
3630: 68 65 46 72 65 65 28 70 2d 3e 61 70 53 61 76 65  heFree(p->apSave
3640: 5b 30 5d 29 3b 0a 20 20 70 63 61 63 68 65 46 72  [0]);.  pcacheFr
3650: 65 65 28 70 2d 3e 61 70 53 61 76 65 5b 31 5d 29  ee(p->apSave[1])
3660: 3b 0a 20 20 70 63 61 63 68 65 46 72 65 65 28 70  ;.  pcacheFree(p
3670: 29 3b 0a 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c  );.}..#ifdef SQL
3680: 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52  ITE_ENABLE_MEMOR
3690: 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 0a 2f 2a 0a  Y_MANAGEMENT./*.
36a0: 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 6e 75  ** Return the nu
36b0: 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 74 68  mber of bytes th
36c0: 61 74 20 77 69 6c 6c 20 62 65 20 72 65 74 75 72  at will be retur
36d0: 6e 65 64 20 74 6f 20 74 68 65 20 68 65 61 70 20  ned to the heap 
36e0: 77 68 65 6e 0a 2a 2a 20 74 68 65 20 61 72 67 75  when.** the argu
36f0: 6d 65 6e 74 20 69 73 20 70 61 73 73 65 64 20 74  ment is passed t
3700: 6f 20 70 63 61 63 68 65 50 61 67 65 46 72 65 65  o pcachePageFree
3710: 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ()..*/.static in
3720: 74 20 70 63 61 63 68 65 50 61 67 65 53 69 7a 65  t pcachePageSize
3730: 28 50 67 48 64 72 20 2a 70 29 7b 0a 20 20 61 73  (PgHdr *p){.  as
3740: 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75  sert( sqlite3_mu
3750: 74 65 78 5f 68 65 6c 64 28 70 63 61 63 68 65 2e  tex_held(pcache.
3760: 6d 75 74 65 78 29 20 29 3b 0a 20 20 61 73 73 65  mutex) );.  asse
3770: 72 74 28 20 21 70 63 61 63 68 65 2e 70 53 74 61  rt( !pcache.pSta
3780: 72 74 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  rt );.  assert( 
3790: 70 2d 3e 61 70 53 61 76 65 5b 30 5d 3d 3d 30 20  p->apSave[0]==0 
37a0: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 2d 3e  );.  assert( p->
37b0: 61 70 53 61 76 65 5b 31 5d 3d 3d 30 20 29 3b 0a  apSave[1]==0 );.
37c0: 20 20 61 73 73 65 72 74 28 20 70 20 26 26 20 70    assert( p && p
37d0: 2d 3e 70 43 61 63 68 65 20 29 3b 0a 20 20 72 65  ->pCache );.  re
37e0: 74 75 72 6e 20 73 71 6c 69 74 65 33 4d 61 6c 6c  turn sqlite3Mall
37f0: 6f 63 53 69 7a 65 28 70 29 3b 0a 7d 0a 23 65 6e  ocSize(p);.}.#en
3800: 64 69 66 0a 0a 2f 2a 0a 2a 2a 20 41 74 74 65 6d  dif../*.** Attem
3810: 70 74 20 74 6f 20 27 72 65 63 79 63 6c 65 27 20  pt to 'recycle' 
3820: 61 20 70 61 67 65 20 66 72 6f 6d 20 74 68 65 20  a page from the 
3830: 67 6c 6f 62 61 6c 20 4c 52 55 20 6c 69 73 74 2e  global LRU list.
3840: 20 4f 6e 6c 79 20 63 6c 65 61 6e 2c 0a 2a 2a 20   Only clean,.** 
3850: 75 6e 72 65 66 65 72 65 6e 63 65 64 20 70 61 67  unreferenced pag
3860: 65 73 20 66 72 6f 6d 20 70 75 72 67 65 61 62 6c  es from purgeabl
3870: 65 20 63 61 63 68 65 73 20 61 72 65 20 65 6c 69  e caches are eli
3880: 67 69 62 6c 65 20 66 6f 72 20 72 65 63 79 63 6c  gible for recycl
3890: 69 6e 67 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  ing..**.** This 
38a0: 66 75 6e 63 74 69 6f 6e 20 72 65 6d 6f 76 65 73  function removes
38b0: 20 70 61 67 65 20 70 63 61 63 68 65 2e 70 4c 72   page pcache.pLr
38c0: 75 54 61 69 6c 20 66 72 6f 6d 20 74 68 65 20 67  uTail from the g
38d0: 6c 6f 62 61 6c 20 4c 52 55 20 6c 69 73 74 2c 0a  lobal LRU list,.
38e0: 2a 2a 20 61 6e 64 20 66 72 6f 6d 20 74 68 65 20  ** and from the 
38f0: 68 61 73 68 2d 74 61 62 6c 65 20 61 6e 64 20 50  hash-table and P
3900: 43 61 63 68 65 2e 70 43 6c 65 61 6e 20 6c 69 73  Cache.pClean lis
3910: 74 20 6f 66 20 74 68 65 20 6f 77 6e 65 72 20 70  t of the owner p
3920: 63 61 63 68 65 2e 0a 2a 2a 20 54 68 65 72 65 20  cache..** There 
3930: 73 68 6f 75 6c 64 20 62 65 20 6e 6f 20 6f 74 68  should be no oth
3940: 65 72 20 72 65 66 65 72 65 6e 63 65 73 20 74 6f  er references to
3950: 20 74 68 65 20 70 61 67 65 2e 0a 2a 2a 0a 2a 2a   the page..**.**
3960: 20 41 20 70 6f 69 6e 74 65 72 20 74 6f 20 74 68   A pointer to th
3970: 65 20 72 65 63 79 63 6c 65 64 20 70 61 67 65 20  e recycled page 
3980: 69 73 20 72 65 74 75 72 6e 65 64 2c 20 6f 72 20  is returned, or 
3990: 4e 55 4c 4c 20 69 66 20 6e 6f 20 70 61 67 65 20  NULL if no page 
39a0: 69 73 0a 2a 2a 20 65 6c 69 67 69 62 6c 65 20 66  is.** eligible f
39b0: 6f 72 20 72 65 63 79 63 6c 69 6e 67 2e 0a 2a 2f  or recycling..*/
39c0: 0a 73 74 61 74 69 63 20 50 67 48 64 72 20 2a 70  .static PgHdr *p
39d0: 63 61 63 68 65 52 65 63 79 63 6c 65 50 61 67 65  cacheRecyclePage
39e0: 28 29 7b 0a 20 20 50 67 48 64 72 20 2a 70 20 3d  (){.  PgHdr *p =
39f0: 20 30 3b 0a 20 20 61 73 73 65 72 74 28 20 73 71   0;.  assert( sq
3a00: 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64  lite3_mutex_held
3a10: 28 70 63 61 63 68 65 2e 6d 75 74 65 78 29 20 29  (pcache.mutex) )
3a20: 3b 0a 0a 20 20 69 66 28 20 28 70 3d 70 63 61 63  ;..  if( (p=pcac
3a30: 68 65 2e 70 4c 72 75 54 61 69 6c 29 20 29 7b 0a  he.pLruTail) ){.
3a40: 20 20 20 20 61 73 73 65 72 74 28 20 28 70 2d 3e      assert( (p->
3a50: 66 6c 61 67 73 26 50 47 48 44 52 5f 44 49 52 54  flags&PGHDR_DIRT
3a60: 59 29 3d 3d 30 20 29 3b 0a 20 20 20 20 70 63 61  Y)==0 );.    pca
3a70: 63 68 65 52 65 6d 6f 76 65 46 72 6f 6d 4c 72 75  cheRemoveFromLru
3a80: 4c 69 73 74 28 70 29 3b 0a 20 20 20 20 70 63 61  List(p);.    pca
3a90: 63 68 65 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73  cheRemoveFromHas
3aa0: 68 28 70 29 3b 0a 20 20 20 20 70 63 61 63 68 65  h(p);.    pcache
3ab0: 52 65 6d 6f 76 65 46 72 6f 6d 4c 69 73 74 28 26  RemoveFromList(&
3ac0: 70 2d 3e 70 43 61 63 68 65 2d 3e 70 43 6c 65 61  p->pCache->pClea
3ad0: 6e 2c 20 70 29 3b 0a 0a 20 20 20 20 2f 2a 20 49  n, p);..    /* I
3ae0: 66 20 74 68 65 20 61 6c 77 61 79 73 2d 72 6f 6c  f the always-rol
3af0: 6c 62 61 63 6b 20 66 6c 61 67 20 69 73 20 73 65  lback flag is se
3b00: 74 20 6f 6e 20 74 68 65 20 70 61 67 65 20 62 65  t on the page be
3b10: 69 6e 67 20 72 65 63 79 63 6c 65 64 2c 20 73 65  ing recycled, se
3b20: 74 20 0a 20 20 20 20 2a 2a 20 74 68 65 20 61 6c  t .    ** the al
3b30: 77 61 79 73 2d 72 6f 6c 6c 62 61 63 6b 20 66 6c  ways-rollback fl
3b40: 61 67 20 6f 6e 20 74 68 65 20 63 6f 72 72 65 73  ag on the corres
3b50: 70 6f 6e 64 69 6e 67 20 70 61 67 65 72 2e 20 54  ponding pager. T
3b60: 4f 44 4f 3a 20 54 68 69 73 20 69 73 0a 20 20 20  ODO: This is.   
3b70: 20 2a 2a 20 61 20 74 68 72 65 61 64 2d 73 61 66   ** a thread-saf
3b80: 65 74 79 20 70 72 6f 62 6c 65 6d 2e 0a 20 20 20  ety problem..   
3b90: 20 2a 2f 0a 20 20 20 20 69 66 28 20 70 2d 3e 66   */.    if( p->f
3ba0: 6c 61 67 73 26 50 47 48 44 52 5f 41 4c 57 41 59  lags&PGHDR_ALWAY
3bb0: 53 5f 52 4f 4c 4c 42 41 43 4b 20 29 7b 0a 20 20  S_ROLLBACK ){.  
3bc0: 20 20 20 20 61 73 73 65 72 74 28 70 2d 3e 70 50      assert(p->pP
3bd0: 61 67 65 72 29 3b 0a 20 20 20 20 20 20 73 71 6c  ager);.      sql
3be0: 69 74 65 33 50 61 67 65 72 41 6c 77 61 79 73 52  ite3PagerAlwaysR
3bf0: 6f 6c 6c 62 61 63 6b 28 70 2d 3e 70 50 61 67 65  ollback(p->pPage
3c00: 72 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  r);.    }.  }.. 
3c10: 20 72 65 74 75 72 6e 20 70 3b 0a 7d 0a 0a 2f 2a   return p;.}../*
3c20: 0a 2a 2a 20 4f 62 74 61 69 6e 20 73 70 61 63 65  .** Obtain space
3c30: 20 66 6f 72 20 61 20 70 61 67 65 2e 20 54 72 79   for a page. Try
3c40: 20 74 6f 20 72 65 63 79 63 6c 65 20 61 6e 20 6f   to recycle an o
3c50: 6c 64 20 70 61 67 65 20 69 66 20 74 68 65 20 6c  ld page if the l
3c60: 69 6d 69 74 20 6f 6e 20 74 68 65 20 0a 2a 2a 20  imit on the .** 
3c70: 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20  number of pages 
3c80: 68 61 73 20 62 65 65 6e 20 72 65 61 63 68 65 64  has been reached
3c90: 2e 20 49 66 20 74 68 65 20 6c 69 6d 69 74 20 68  . If the limit h
3ca0: 61 73 20 6e 6f 74 20 62 65 65 6e 20 72 65 61 63  as not been reac
3cb0: 68 65 64 20 6f 72 0a 2a 2a 20 74 68 65 72 65 20  hed or.** there 
3cc0: 61 72 65 20 6e 6f 20 70 61 67 65 73 20 65 6c 69  are no pages eli
3cd0: 67 69 62 6c 65 20 66 6f 72 20 72 65 63 79 63 6c  gible for recycl
3ce0: 69 6e 67 2c 20 61 6c 6c 6f 63 61 74 65 20 61 20  ing, allocate a 
3cf0: 6e 65 77 20 70 61 67 65 2e 0a 2a 2a 0a 2a 2a 20  new page..**.** 
3d00: 52 65 74 75 72 6e 20 61 20 70 6f 69 6e 74 65 72  Return a pointer
3d10: 20 74 6f 20 74 68 65 20 6e 65 77 20 70 61 67 65   to the new page
3d20: 2c 20 6f 72 20 4e 55 4c 4c 20 69 66 20 61 6e 20  , or NULL if an 
3d30: 4f 4f 4d 20 63 6f 6e 64 69 74 69 6f 6e 20 6f 63  OOM condition oc
3d40: 63 75 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  curs..*/.static 
3d50: 50 67 48 64 72 20 2a 70 63 61 63 68 65 52 65 63  PgHdr *pcacheRec
3d60: 79 63 6c 65 4f 72 41 6c 6c 6f 63 28 50 43 61 63  ycleOrAlloc(PCac
3d70: 68 65 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 50  he *pCache){.  P
3d80: 67 48 64 72 20 2a 70 20 3d 20 30 3b 0a 0a 20 20  gHdr *p = 0;..  
3d90: 69 6e 74 20 73 7a 50 61 67 65 20 3d 20 70 43 61  int szPage = pCa
3da0: 63 68 65 2d 3e 73 7a 50 61 67 65 3b 0a 20 20 69  che->szPage;.  i
3db0: 6e 74 20 73 7a 45 78 74 72 61 20 3d 20 70 43 61  nt szExtra = pCa
3dc0: 63 68 65 2d 3e 73 7a 45 78 74 72 61 3b 0a 0a 20  che->szExtra;.. 
3dd0: 20 61 73 73 65 72 74 28 20 70 63 61 63 68 65 2e   assert( pcache.
3de0: 69 73 49 6e 69 74 20 29 3b 0a 20 20 61 73 73 65  isInit );.  asse
3df0: 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65  rt( sqlite3_mute
3e00: 78 5f 6e 6f 74 68 65 6c 64 28 70 63 61 63 68 65  x_notheld(pcache
3e10: 2e 6d 75 74 65 78 29 20 29 3b 0a 0a 20 20 70 63  .mutex) );..  pc
3e20: 61 63 68 65 45 6e 74 65 72 47 6c 6f 62 61 6c 28  acheEnterGlobal(
3e30: 29 3b 0a 0a 20 20 2f 2a 20 49 66 20 77 65 20 68  );..  /* If we h
3e40: 61 76 65 20 72 65 61 63 68 65 64 20 74 68 65 20  ave reached the 
3e50: 6c 69 6d 69 74 20 66 6f 72 20 70 69 6e 6e 65 64  limit for pinned
3e60: 2f 64 69 72 74 79 20 70 61 67 65 73 2c 20 61 6e  /dirty pages, an
3e70: 64 20 74 68 65 72 65 20 69 73 20 61 74 0a 20 20  d there is at.  
3e80: 2a 2a 20 6c 65 61 73 74 20 6f 6e 65 20 64 69 72  ** least one dir
3e90: 74 79 20 70 61 67 65 2c 20 69 6e 76 6f 6b 65 20  ty page, invoke 
3ea0: 74 68 65 20 78 53 74 72 65 73 73 20 63 61 6c 6c  the xStress call
3eb0: 62 61 63 6b 20 74 6f 20 63 61 75 73 65 20 61 20  back to cause a 
3ec0: 70 61 67 65 20 74 6f 0a 20 20 2a 2a 20 62 65 63  page to.  ** bec
3ed0: 6f 6d 65 20 63 6c 65 61 6e 2e 0a 20 20 2a 2f 0a  ome clean..  */.
3ee0: 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65    assert( pCache
3ef0: 2d 3e 6e 50 69 6e 6e 65 64 3d 3d 70 63 61 63 68  ->nPinned==pcach
3f00: 65 50 69 6e 6e 65 64 43 6f 75 6e 74 28 70 43 61  ePinnedCount(pCa
3f10: 63 68 65 29 20 29 3b 0a 20 20 61 73 73 65 72 74  che) );.  assert
3f20: 28 20 70 63 61 63 68 65 43 68 65 63 6b 53 79 6e  ( pcacheCheckSyn
3f30: 63 65 64 28 70 43 61 63 68 65 29 20 29 3b 0a 20  ced(pCache) );. 
3f40: 20 69 66 28 20 70 43 61 63 68 65 2d 3e 78 53 74   if( pCache->xSt
3f50: 72 65 73 73 0a 20 20 20 26 26 20 70 43 61 63 68  ress.   && pCach
3f60: 65 2d 3e 70 44 69 72 74 79 0a 20 20 20 26 26 20  e->pDirty.   && 
3f70: 70 43 61 63 68 65 2d 3e 6e 50 69 6e 6e 65 64 3e  pCache->nPinned>
3f80: 3d 28 70 63 61 63 68 65 2e 6e 4d 61 78 50 61 67  =(pcache.nMaxPag
3f90: 65 2b 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 2d 70  e+pCache->nMin-p
3fa0: 63 61 63 68 65 2e 6e 4d 69 6e 50 61 67 65 29 0a  cache.nMinPage).
3fb0: 20 20 29 7b 0a 20 20 20 20 50 67 48 64 72 20 2a    ){.    PgHdr *
3fc0: 70 50 67 3b 0a 20 20 20 20 61 73 73 65 72 74 28  pPg;.    assert(
3fd0: 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 54 61  pCache->pDirtyTa
3fe0: 69 6c 29 3b 0a 0a 20 20 20 20 66 6f 72 28 70 50  il);..    for(pP
3ff0: 67 3d 70 43 61 63 68 65 2d 3e 70 53 79 6e 63 65  g=pCache->pSynce
4000: 64 3b 20 0a 20 20 20 20 20 20 20 20 70 50 67 20  d; .        pPg 
4010: 26 26 20 28 70 50 67 2d 3e 6e 52 65 66 20 7c 7c  && (pPg->nRef ||
4020: 20 28 70 50 67 2d 3e 66 6c 61 67 73 26 50 47 48   (pPg->flags&PGH
4030: 44 52 5f 4e 45 45 44 5f 53 59 4e 43 29 29 3b 20  DR_NEED_SYNC)); 
4040: 0a 20 20 20 20 20 20 20 20 70 50 67 3d 70 50 67  .        pPg=pPg
4050: 2d 3e 70 50 72 65 76 0a 20 20 20 20 29 3b 0a 20  ->pPrev.    );. 
4060: 20 20 20 69 66 28 20 21 70 50 67 20 29 7b 0a 20     if( !pPg ){. 
4070: 20 20 20 20 20 66 6f 72 28 70 50 67 3d 70 43 61       for(pPg=pCa
4080: 63 68 65 2d 3e 70 44 69 72 74 79 54 61 69 6c 3b  che->pDirtyTail;
4090: 20 70 50 67 20 26 26 20 70 50 67 2d 3e 6e 52 65   pPg && pPg->nRe
40a0: 66 3b 20 70 50 67 3d 70 50 67 2d 3e 70 50 72 65  f; pPg=pPg->pPre
40b0: 76 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66  v);.    }.    if
40c0: 28 20 70 50 67 20 29 7b 0a 20 20 20 20 20 20 70  ( pPg ){.      p
40d0: 63 61 63 68 65 45 78 69 74 47 6c 6f 62 61 6c 28  cacheExitGlobal(
40e0: 29 3b 0a 20 20 20 20 20 20 70 43 61 63 68 65 2d  );.      pCache-
40f0: 3e 78 53 74 72 65 73 73 28 70 43 61 63 68 65 2d  >xStress(pCache-
4100: 3e 70 53 74 72 65 73 73 2c 20 70 50 67 29 3b 0a  >pStress, pPg);.
4110: 20 20 20 20 20 20 70 63 61 63 68 65 45 6e 74 65        pcacheEnte
4120: 72 47 6c 6f 62 61 6c 28 29 3b 0a 20 20 20 20 7d  rGlobal();.    }
4130: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 74 68  .  }..  /* If th
4140: 65 20 67 6c 6f 62 61 6c 20 70 61 67 65 20 6c 69  e global page li
4150: 6d 69 74 20 68 61 73 20 62 65 65 6e 20 72 65 61  mit has been rea
4160: 63 68 65 64 2c 20 74 72 79 20 74 6f 20 72 65 63  ched, try to rec
4170: 79 63 6c 65 20 61 20 70 61 67 65 2e 20 2a 2f 0a  ycle a page. */.
4180: 20 20 69 66 28 20 70 63 61 63 68 65 2e 6e 43 75    if( pcache.nCu
4190: 72 72 65 6e 74 50 61 67 65 3e 3d 70 63 61 63 68  rrentPage>=pcach
41a0: 65 2e 6e 4d 61 78 50 61 67 65 20 29 7b 0a 20 20  e.nMaxPage ){.  
41b0: 20 20 70 20 3d 20 70 63 61 63 68 65 52 65 63 79    p = pcacheRecy
41c0: 63 6c 65 50 61 67 65 28 29 3b 0a 20 20 7d 0a 0a  clePage();.  }..
41d0: 20 20 2f 2a 20 49 66 20 61 20 70 61 67 65 20 68    /* If a page h
41e0: 61 73 20 62 65 65 6e 20 72 65 63 79 63 6c 65 64  as been recycled
41f0: 20 62 75 74 20 69 74 20 69 73 20 74 68 65 20 77   but it is the w
4200: 72 6f 6e 67 20 73 69 7a 65 2c 20 66 72 65 65 20  rong size, free 
4210: 69 74 2e 20 2a 2f 0a 20 20 69 66 28 20 70 20 26  it. */.  if( p &
4220: 26 20 28 70 2d 3e 70 43 61 63 68 65 2d 3e 73 7a  & (p->pCache->sz
4230: 50 61 67 65 21 3d 73 7a 50 61 67 65 20 7c 7c 20  Page!=szPage || 
4240: 70 2d 3e 70 43 61 63 68 65 2d 3e 73 7a 45 78 74  p->pCache->szExt
4250: 72 61 21 3d 73 7a 45 78 74 72 61 29 20 29 7b 0a  ra!=szExtra) ){.
4260: 20 20 20 20 70 63 61 63 68 65 50 61 67 65 46 72      pcachePageFr
4270: 65 65 28 70 29 3b 0a 20 20 20 20 70 20 3d 20 30  ee(p);.    p = 0
4280: 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 21 70 20  ;.  }..  if( !p 
4290: 29 7b 0a 20 20 20 20 70 20 3d 20 70 63 61 63 68  ){.    p = pcach
42a0: 65 50 61 67 65 41 6c 6c 6f 63 28 70 43 61 63 68  ePageAlloc(pCach
42b0: 65 29 3b 0a 20 20 7d 0a 0a 20 20 70 63 61 63 68  e);.  }..  pcach
42c0: 65 45 78 69 74 47 6c 6f 62 61 6c 28 29 3b 0a 20  eExitGlobal();. 
42d0: 20 72 65 74 75 72 6e 20 70 3b 0a 7d 0a 0a 2f 2a   return p;.}../*
42e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
42f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4300: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4310: 2a 2a 20 47 65 6e 65 72 61 6c 20 49 6e 74 65 72  ** General Inter
4320: 66 61 63 65 73 20 2a 2a 2a 2a 2a 2a 0a 2a 2a 0a  faces ******.**.
4330: 2a 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 61 6e  ** Initialize an
4340: 64 20 73 68 75 74 64 6f 77 6e 20 74 68 65 20 70  d shutdown the p
4350: 61 67 65 20 63 61 63 68 65 20 73 75 62 73 79 73  age cache subsys
4360: 74 65 6d 2e 20 4e 65 69 74 68 65 72 20 6f 66 20  tem. Neither of 
4370: 74 68 65 73 65 20 0a 2a 2a 20 66 75 6e 63 74 69  these .** functi
4380: 6f 6e 73 20 61 72 65 20 74 68 72 65 61 64 73 61  ons are threadsa
4390: 66 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  fe..*/.int sqlit
43a0: 65 33 50 63 61 63 68 65 49 6e 69 74 69 61 6c 69  e3PcacheInitiali
43b0: 7a 65 28 76 6f 69 64 29 7b 0a 20 20 61 73 73 65  ze(void){.  asse
43c0: 72 74 28 20 70 63 61 63 68 65 2e 69 73 49 6e 69  rt( pcache.isIni
43d0: 74 3d 3d 30 20 29 3b 0a 20 20 6d 65 6d 73 65 74  t==0 );.  memset
43e0: 28 26 70 63 61 63 68 65 2c 20 30 2c 20 73 69 7a  (&pcache, 0, siz
43f0: 65 6f 66 28 70 63 61 63 68 65 29 29 3b 0a 20 20  eof(pcache));.  
4400: 69 66 28 20 73 71 6c 69 74 65 33 43 6f 6e 66 69  if( sqlite3Confi
4410: 67 2e 62 43 6f 72 65 4d 75 74 65 78 20 29 7b 0a  g.bCoreMutex ){.
4420: 20 20 20 20 70 63 61 63 68 65 2e 6d 75 74 65 78      pcache.mutex
4430: 20 3d 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78   = sqlite3_mutex
4440: 5f 61 6c 6c 6f 63 28 53 51 4c 49 54 45 5f 4d 55  _alloc(SQLITE_MU
4450: 54 45 58 5f 53 54 41 54 49 43 5f 4c 52 55 29 3b  TEX_STATIC_LRU);
4460: 0a 20 20 20 20 69 66 28 20 70 63 61 63 68 65 2e  .    if( pcache.
4470: 6d 75 74 65 78 3d 3d 30 20 29 7b 0a 20 20 20 20  mutex==0 ){.    
4480: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
4490: 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20 20 7d  NOMEM;.    }.  }
44a0: 0a 20 20 70 63 61 63 68 65 2e 69 73 49 6e 69 74  .  pcache.isInit
44b0: 20 3d 20 31 3b 0a 20 20 72 65 74 75 72 6e 20 53   = 1;.  return S
44c0: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 76 6f 69 64  QLITE_OK;.}.void
44d0: 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 53 68   sqlite3PcacheSh
44e0: 75 74 64 6f 77 6e 28 76 6f 69 64 29 7b 0a 20 20  utdown(void){.  
44f0: 6d 65 6d 73 65 74 28 26 70 63 61 63 68 65 2c 20  memset(&pcache, 
4500: 30 2c 20 73 69 7a 65 6f 66 28 70 63 61 63 68 65  0, sizeof(pcache
4510: 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74  ));.}../*.** Ret
4520: 75 72 6e 20 74 68 65 20 73 69 7a 65 20 69 6e 20  urn the size in 
4530: 62 79 74 65 73 20 6f 66 20 61 20 50 43 61 63 68  bytes of a PCach
4540: 65 20 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 69 6e 74  e object..*/.int
4550: 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 53 69   sqlite3PcacheSi
4560: 7a 65 28 76 6f 69 64 29 7b 20 72 65 74 75 72 6e  ze(void){ return
4570: 20 73 69 7a 65 6f 66 28 50 43 61 63 68 65 29 3b   sizeof(PCache);
4580: 20 7d 0a 0a 2f 2a 0a 2a 2a 20 43 72 65 61 74 65   }../*.** Create
4590: 20 61 20 6e 65 77 20 50 43 61 63 68 65 20 6f 62   a new PCache ob
45a0: 6a 65 63 74 2e 20 20 53 74 6f 72 61 67 65 20 73  ject.  Storage s
45b0: 70 61 63 65 20 74 6f 20 68 6f 6c 64 20 74 68 65  pace to hold the
45c0: 20 6f 62 6a 65 63 74 0a 2a 2a 20 68 61 73 20 61   object.** has a
45d0: 6c 72 65 61 64 79 20 62 65 65 6e 20 61 6c 6c 6f  lready been allo
45e0: 63 61 74 65 64 20 61 6e 64 20 69 73 20 70 61 73  cated and is pas
45f0: 73 65 64 20 69 6e 20 61 73 20 74 68 65 20 70 20  sed in as the p 
4600: 70 6f 69 6e 74 65 72 2e 0a 2a 2f 0a 76 6f 69 64  pointer..*/.void
4610: 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 4f 70   sqlite3PcacheOp
4620: 65 6e 28 0a 20 20 69 6e 74 20 73 7a 50 61 67 65  en(.  int szPage
4630: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
4640: 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 65 76     /* Size of ev
4650: 65 72 79 20 70 61 67 65 20 2a 2f 0a 20 20 69 6e  ery page */.  in
4660: 74 20 73 7a 45 78 74 72 61 2c 20 20 20 20 20 20  t szExtra,      
4670: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 45 78             /* Ex
4680: 74 72 61 20 73 70 61 63 65 20 61 73 73 6f 63 69  tra space associ
4690: 61 74 65 64 20 77 69 74 68 20 65 61 63 68 20 70  ated with each p
46a0: 61 67 65 20 2a 2f 0a 20 20 69 6e 74 20 62 50 75  age */.  int bPu
46b0: 72 67 65 61 62 6c 65 2c 20 20 20 20 20 20 20 20  rgeable,        
46c0: 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66        /* True if
46d0: 20 70 61 67 65 73 20 61 72 65 20 6f 6e 20 62 61   pages are on ba
46e0: 63 6b 69 6e 67 20 73 74 6f 72 65 20 2a 2f 0a 20  cking store */. 
46f0: 20 76 6f 69 64 20 28 2a 78 44 65 73 74 72 6f 79   void (*xDestroy
4700: 29 28 50 67 48 64 72 2a 29 2c 20 20 20 20 2f 2a  )(PgHdr*),    /*
4710: 20 43 61 6c 6c 65 64 20 74 6f 20 64 65 73 74 72   Called to destr
4720: 6f 79 20 61 20 70 61 67 65 20 2a 2f 0a 20 20 69  oy a page */.  i
4730: 6e 74 20 28 2a 78 53 74 72 65 73 73 29 28 76 6f  nt (*xStress)(vo
4740: 69 64 2a 2c 50 67 48 64 72 2a 29 2c 2f 2a 20 43  id*,PgHdr*),/* C
4750: 61 6c 6c 20 74 6f 20 74 72 79 20 74 6f 20 6d 61  all to try to ma
4760: 6b 65 20 70 61 67 65 73 20 63 6c 65 61 6e 20 2a  ke pages clean *
4770: 2f 0a 20 20 76 6f 69 64 20 2a 70 53 74 72 65 73  /.  void *pStres
4780: 73 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  s,              
4790: 20 2f 2a 20 41 72 67 75 6d 65 6e 74 20 74 6f 20   /* Argument to 
47a0: 78 53 74 72 65 73 73 20 2a 2f 0a 20 20 50 43 61  xStress */.  PCa
47b0: 63 68 65 20 2a 70 20 20 20 20 20 20 20 20 20 20  che *p          
47c0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 72 65            /* Pre
47d0: 61 6c 6c 6f 63 61 74 65 64 20 73 70 61 63 65 20  allocated space 
47e0: 66 6f 72 20 74 68 65 20 50 43 61 63 68 65 20 2a  for the PCache *
47f0: 2f 0a 29 7b 0a 20 20 61 73 73 65 72 74 28 20 70  /.){.  assert( p
4800: 63 61 63 68 65 2e 69 73 49 6e 69 74 20 29 3b 0a  cache.isInit );.
4810: 20 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20 73    memset(p, 0, s
4820: 69 7a 65 6f 66 28 50 43 61 63 68 65 29 29 3b 0a  izeof(PCache));.
4830: 20 20 70 2d 3e 73 7a 50 61 67 65 20 3d 20 73 7a    p->szPage = sz
4840: 50 61 67 65 3b 0a 20 20 70 2d 3e 73 7a 45 78 74  Page;.  p->szExt
4850: 72 61 20 3d 20 73 7a 45 78 74 72 61 3b 0a 20 20  ra = szExtra;.  
4860: 70 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 3d 20  p->bPurgeable = 
4870: 62 50 75 72 67 65 61 62 6c 65 3b 0a 20 20 70 2d  bPurgeable;.  p-
4880: 3e 78 44 65 73 74 72 6f 79 20 3d 20 78 44 65 73  >xDestroy = xDes
4890: 74 72 6f 79 3b 0a 20 20 70 2d 3e 78 53 74 72 65  troy;.  p->xStre
48a0: 73 73 20 3d 20 78 53 74 72 65 73 73 3b 0a 20 20  ss = xStress;.  
48b0: 70 2d 3e 70 53 74 72 65 73 73 20 3d 20 70 53 74  p->pStress = pSt
48c0: 72 65 73 73 3b 0a 20 20 70 2d 3e 6e 4d 61 78 20  ress;.  p->nMax 
48d0: 3d 20 31 30 30 3b 0a 20 20 70 2d 3e 6e 4d 69 6e  = 100;.  p->nMin
48e0: 20 3d 20 32 30 3b 0a 0a 20 20 70 63 61 63 68 65   = 20;..  pcache
48f0: 45 6e 74 65 72 47 6c 6f 62 61 6c 28 29 3b 0a 20  EnterGlobal();. 
4900: 20 69 66 28 20 62 50 75 72 67 65 61 62 6c 65 20   if( bPurgeable 
4910: 29 7b 0a 20 20 20 20 70 63 61 63 68 65 2e 6e 4d  ){.    pcache.nM
4920: 61 78 50 61 67 65 20 2b 3d 20 70 2d 3e 6e 4d 61  axPage += p->nMa
4930: 78 3b 0a 20 20 20 20 70 63 61 63 68 65 2e 6e 4d  x;.    pcache.nM
4940: 69 6e 50 61 67 65 20 2b 3d 20 70 2d 3e 6e 4d 69  inPage += p->nMi
4950: 6e 3b 0a 20 20 7d 0a 0a 20 20 70 63 61 63 68 65  n;.  }..  pcache
4960: 45 78 69 74 47 6c 6f 62 61 6c 28 29 3b 0a 7d 0a  ExitGlobal();.}.
4970: 0a 2f 2a 0a 2a 2a 20 43 68 61 6e 67 65 20 74 68  ./*.** Change th
4980: 65 20 70 61 67 65 20 73 69 7a 65 20 66 6f 72 20  e page size for 
4990: 50 43 61 63 68 65 20 6f 62 6a 65 63 74 2e 20 20  PCache object.  
49a0: 54 68 69 73 20 63 61 6e 20 6f 6e 6c 79 20 68 61  This can only ha
49b0: 70 70 65 6e 0a 2a 2a 20 77 68 65 6e 20 74 68 65  ppen.** when the
49c0: 20 63 61 63 68 65 20 69 73 20 65 6d 70 74 79 2e   cache is empty.
49d0: 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33  .*/.void sqlite3
49e0: 50 63 61 63 68 65 53 65 74 50 61 67 65 53 69 7a  PcacheSetPageSiz
49f0: 65 28 50 43 61 63 68 65 20 2a 70 43 61 63 68 65  e(PCache *pCache
4a00: 2c 20 69 6e 74 20 73 7a 50 61 67 65 29 7b 0a 20  , int szPage){. 
4a10: 20 61 73 73 65 72 74 28 70 43 61 63 68 65 2d 3e   assert(pCache->
4a20: 6e 50 61 67 65 3d 3d 30 29 3b 0a 20 20 70 43 61  nPage==0);.  pCa
4a30: 63 68 65 2d 3e 73 7a 50 61 67 65 20 3d 20 73 7a  che->szPage = sz
4a40: 50 61 67 65 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  Page;.}../*.** T
4a50: 72 79 20 74 6f 20 6f 62 74 61 69 6e 20 61 20 70  ry to obtain a p
4a60: 61 67 65 20 66 72 6f 6d 20 74 68 65 20 63 61 63  age from the cac
4a70: 68 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  he..*/.int sqlit
4a80: 65 33 50 63 61 63 68 65 46 65 74 63 68 28 0a 20  e3PcacheFetch(. 
4a90: 20 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 2c   PCache *pCache,
4aa0: 20 20 20 20 20 20 20 2f 2a 20 4f 62 74 61 69 6e         /* Obtain
4ab0: 20 74 68 65 20 70 61 67 65 20 66 72 6f 6d 20 74   the page from t
4ac0: 68 69 73 20 63 61 63 68 65 20 2a 2f 0a 20 20 50  his cache */.  P
4ad0: 67 6e 6f 20 70 67 6e 6f 2c 20 20 20 20 20 20 20  gno pgno,       
4ae0: 20 20 20 20 20 2f 2a 20 50 61 67 65 20 6e 75 6d       /* Page num
4af0: 62 65 72 20 74 6f 20 6f 62 74 61 69 6e 20 2a 2f  ber to obtain */
4b00: 0a 20 20 69 6e 74 20 63 72 65 61 74 65 46 6c 61  .  int createFla
4b10: 67 2c 20 20 20 20 20 20 20 2f 2a 20 49 66 20 74  g,       /* If t
4b20: 72 75 65 2c 20 63 72 65 61 74 65 20 70 61 67 65  rue, create page
4b30: 20 69 66 20 69 74 20 64 6f 65 73 20 6e 6f 74 20   if it does not 
4b40: 65 78 69 73 74 20 61 6c 72 65 61 64 79 20 2a 2f  exist already */
4b50: 0a 20 20 50 67 48 64 72 20 2a 2a 70 70 50 61 67  .  PgHdr **ppPag
4b60: 65 20 20 20 20 20 20 20 20 2f 2a 20 57 72 69 74  e        /* Writ
4b70: 65 20 74 68 65 20 70 61 67 65 20 68 65 72 65 20  e the page here 
4b80: 2a 2f 0a 29 7b 0a 20 20 50 67 48 64 72 20 2a 70  */.){.  PgHdr *p
4b90: 50 61 67 65 3b 0a 20 20 61 73 73 65 72 74 28 20  Page;.  assert( 
4ba0: 70 63 61 63 68 65 2e 69 73 49 6e 69 74 20 29 3b  pcache.isInit );
4bb0: 0a 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68  .  assert( pCach
4bc0: 65 21 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74  e!=0 );.  assert
4bd0: 28 20 70 67 6e 6f 3e 30 20 29 3b 0a 20 20 61 73  ( pgno>0 );.  as
4be0: 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e 6e 50  sert( pCache->nP
4bf0: 69 6e 6e 65 64 3d 3d 70 63 61 63 68 65 50 69 6e  inned==pcachePin
4c00: 6e 65 64 43 6f 75 6e 74 28 70 43 61 63 68 65 29  nedCount(pCache)
4c10: 20 29 3b 0a 0a 20 20 2f 2a 20 53 65 61 72 63 68   );..  /* Search
4c20: 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 20   the hash table 
4c30: 66 6f 72 20 74 68 65 20 72 65 71 75 65 73 74 65  for the requeste
4c40: 64 20 70 61 67 65 2e 20 45 78 69 74 20 65 61 72  d page. Exit ear
4c50: 6c 79 20 69 66 20 69 74 20 69 73 20 66 6f 75 6e  ly if it is foun
4c60: 64 2e 20 2a 2f 0a 20 20 69 66 28 20 70 43 61 63  d. */.  if( pCac
4c70: 68 65 2d 3e 61 70 48 61 73 68 20 29 7b 0a 20 20  he->apHash ){.  
4c80: 20 20 75 33 32 20 68 20 3d 20 70 67 6e 6f 20 25    u32 h = pgno %
4c90: 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3b 0a   pCache->nHash;.
4ca0: 20 20 20 20 66 6f 72 28 70 50 61 67 65 3d 70 43      for(pPage=pC
4cb0: 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b  ache->apHash[h];
4cc0: 20 70 50 61 67 65 3b 20 70 50 61 67 65 3d 70 50   pPage; pPage=pP
4cd0: 61 67 65 2d 3e 70 4e 65 78 74 48 61 73 68 29 7b  age->pNextHash){
4ce0: 0a 20 20 20 20 20 20 69 66 28 20 70 50 61 67 65  .      if( pPage
4cf0: 2d 3e 70 67 6e 6f 3d 3d 70 67 6e 6f 20 29 7b 0a  ->pgno==pgno ){.
4d00: 20 20 20 20 20 20 20 20 69 66 28 20 70 50 61 67          if( pPag
4d10: 65 2d 3e 6e 52 65 66 3d 3d 30 20 29 7b 0a 20 20  e->nRef==0 ){.  
4d20: 20 20 20 20 20 20 20 20 69 66 28 20 30 3d 3d 28          if( 0==(
4d30: 70 50 61 67 65 2d 3e 66 6c 61 67 73 26 50 47 48  pPage->flags&PGH
4d40: 44 52 5f 44 49 52 54 59 29 20 29 7b 0a 20 20 20  DR_DIRTY) ){.   
4d50: 20 20 20 20 20 20 20 20 20 70 63 61 63 68 65 45           pcacheE
4d60: 6e 74 65 72 47 6c 6f 62 61 6c 28 29 3b 0a 20 20  nterGlobal();.  
4d70: 20 20 20 20 20 20 20 20 20 20 70 63 61 63 68 65            pcache
4d80: 52 65 6d 6f 76 65 46 72 6f 6d 4c 72 75 4c 69 73  RemoveFromLruLis
4d90: 74 28 70 50 61 67 65 29 3b 0a 20 20 20 20 20 20  t(pPage);.      
4da0: 20 20 20 20 20 20 70 63 61 63 68 65 45 78 69 74        pcacheExit
4db0: 47 6c 6f 62 61 6c 28 29 3b 0a 20 20 20 20 20 20  Global();.      
4dc0: 20 20 20 20 20 20 70 43 61 63 68 65 2d 3e 6e 50        pCache->nP
4dd0: 69 6e 6e 65 64 2b 2b 3b 0a 20 20 20 20 20 20 20  inned++;.       
4de0: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 70     }.          p
4df0: 43 61 63 68 65 2d 3e 6e 52 65 66 2b 2b 3b 0a 20  Cache->nRef++;. 
4e00: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
4e10: 20 70 50 61 67 65 2d 3e 6e 52 65 66 2b 2b 3b 0a   pPage->nRef++;.
4e20: 20 20 20 20 20 20 20 20 2a 70 70 50 61 67 65 20          *ppPage 
4e30: 3d 20 70 50 61 67 65 3b 0a 20 20 20 20 20 20 20  = pPage;.       
4e40: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
4e50: 4b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  K;.      }.    }
4e60: 0a 20 20 7d 0a 0a 20 20 69 66 28 20 63 72 65 61  .  }..  if( crea
4e70: 74 65 46 6c 61 67 20 29 7b 0a 20 20 20 20 69 66  teFlag ){.    if
4e80: 28 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3c  ( pCache->nHash<
4e90: 3d 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 20 29  =pCache->nPage )
4ea0: 7b 0a 20 20 20 20 20 20 69 6e 74 20 72 63 20 3d  {.      int rc =
4eb0: 20 70 63 61 63 68 65 52 65 73 69 7a 65 48 61 73   pcacheResizeHas
4ec0: 68 28 70 43 61 63 68 65 2c 20 70 43 61 63 68 65  h(pCache, pCache
4ed0: 2d 3e 6e 48 61 73 68 3c 32 35 36 3f 32 35 36 3a  ->nHash<256?256:
4ee0: 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 2a 32 29  pCache->nHash*2)
4ef0: 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 21 3d  ;.      if( rc!=
4f00: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
4f10: 20 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a       return rc;.
4f20: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20        }.    }.. 
4f30: 20 20 20 70 50 61 67 65 20 3d 20 70 63 61 63 68     pPage = pcach
4f40: 65 52 65 63 79 63 6c 65 4f 72 41 6c 6c 6f 63 28  eRecycleOrAlloc(
4f50: 70 43 61 63 68 65 29 3b 0a 20 20 20 20 2a 70 70  pCache);.    *pp
4f60: 50 61 67 65 20 3d 20 70 50 61 67 65 3b 0a 20 20  Page = pPage;.  
4f70: 20 20 69 66 28 20 70 50 61 67 65 3d 3d 30 20 29    if( pPage==0 )
4f80: 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 53  {.      return S
4f90: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
4fa0: 20 7d 0a 0a 20 20 20 20 70 50 61 67 65 2d 3e 70   }..    pPage->p
4fb0: 50 61 67 65 72 20 3d 20 30 3b 0a 20 20 20 20 70  Pager = 0;.    p
4fc0: 50 61 67 65 2d 3e 66 6c 61 67 73 20 3d 20 30 3b  Page->flags = 0;
4fd0: 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 44 69 72  .    pPage->pDir
4fe0: 74 79 20 3d 20 30 3b 0a 20 20 20 20 70 50 61 67  ty = 0;.    pPag
4ff0: 65 2d 3e 70 67 6e 6f 20 3d 20 70 67 6e 6f 3b 0a  e->pgno = pgno;.
5000: 20 20 20 20 70 50 61 67 65 2d 3e 70 43 61 63 68      pPage->pCach
5010: 65 20 3d 20 70 43 61 63 68 65 3b 0a 20 20 20 20  e = pCache;.    
5020: 70 50 61 67 65 2d 3e 6e 52 65 66 20 3d 20 31 3b  pPage->nRef = 1;
5030: 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 6e 52 65  .    pCache->nRe
5040: 66 2b 2b 3b 0a 20 20 20 20 70 43 61 63 68 65 2d  f++;.    pCache-
5050: 3e 6e 50 69 6e 6e 65 64 2b 2b 3b 0a 20 20 20 20  >nPinned++;.    
5060: 70 63 61 63 68 65 41 64 64 54 6f 4c 69 73 74 28  pcacheAddToList(
5070: 26 70 43 61 63 68 65 2d 3e 70 43 6c 65 61 6e 2c  &pCache->pClean,
5080: 20 70 50 61 67 65 29 3b 0a 20 20 20 20 70 63 61   pPage);.    pca
5090: 63 68 65 41 64 64 54 6f 48 61 73 68 28 70 50 61  cheAddToHash(pPa
50a0: 67 65 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  ge);.  }else{.  
50b0: 20 20 2a 70 70 50 61 67 65 20 3d 20 30 3b 0a 20    *ppPage = 0;. 
50c0: 20 7d 0a 0a 20 20 61 73 73 65 72 74 28 20 70 43   }..  assert( pC
50d0: 61 63 68 65 2d 3e 6e 50 69 6e 6e 65 64 3d 3d 70  ache->nPinned==p
50e0: 63 61 63 68 65 50 69 6e 6e 65 64 43 6f 75 6e 74  cachePinnedCount
50f0: 28 70 43 61 63 68 65 29 20 29 3b 0a 20 20 72 65  (pCache) );.  re
5100: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
5110: 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65 72 65 66 65 72  }../*.** Derefer
5120: 65 6e 63 65 20 61 20 70 61 67 65 2e 20 20 57 68  ence a page.  Wh
5130: 65 6e 20 74 68 65 20 72 65 66 65 72 65 6e 63 65  en the reference
5140: 20 63 6f 75 6e 74 20 72 65 61 63 68 65 73 20 7a   count reaches z
5150: 65 72 6f 2c 0a 2a 2a 20 6d 6f 76 65 20 74 68 65  ero,.** move the
5160: 20 70 61 67 65 20 74 6f 20 74 68 65 20 4c 52 55   page to the LRU
5170: 20 6c 69 73 74 20 69 66 20 69 74 20 69 73 20 63   list if it is c
5180: 6c 65 61 6e 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71  lean..*/.void sq
5190: 6c 69 74 65 33 50 63 61 63 68 65 52 65 6c 65 61  lite3PcacheRelea
51a0: 73 65 28 50 67 48 64 72 20 2a 70 29 7b 0a 20 20  se(PgHdr *p){.  
51b0: 61 73 73 65 72 74 28 20 70 2d 3e 6e 52 65 66 3e  assert( p->nRef>
51c0: 30 20 29 3b 0a 20 20 70 2d 3e 6e 52 65 66 2d 2d  0 );.  p->nRef--
51d0: 3b 0a 20 20 69 66 28 20 70 2d 3e 6e 52 65 66 3d  ;.  if( p->nRef=
51e0: 3d 30 20 29 7b 0a 20 20 20 20 50 43 61 63 68 65  =0 ){.    PCache
51f0: 20 2a 70 43 61 63 68 65 20 3d 20 70 2d 3e 70 43   *pCache = p->pC
5200: 61 63 68 65 3b 0a 20 20 20 20 69 66 28 20 70 2d  ache;.    if( p-
5210: 3e 70 43 61 63 68 65 2d 3e 78 44 65 73 74 72 6f  >pCache->xDestro
5220: 79 20 29 7b 0a 20 20 20 20 20 20 70 2d 3e 70 43  y ){.      p->pC
5230: 61 63 68 65 2d 3e 78 44 65 73 74 72 6f 79 28 70  ache->xDestroy(p
5240: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 43 61  );.    }.    pCa
5250: 63 68 65 2d 3e 6e 52 65 66 2d 2d 3b 0a 20 20 20  che->nRef--;.   
5260: 20 69 66 28 20 28 70 2d 3e 66 6c 61 67 73 26 50   if( (p->flags&P
5270: 47 48 44 52 5f 44 49 52 54 59 29 3d 3d 30 20 29  GHDR_DIRTY)==0 )
5280: 7b 0a 20 20 20 20 20 20 70 43 61 63 68 65 2d 3e  {.      pCache->
5290: 6e 50 69 6e 6e 65 64 2d 2d 3b 0a 20 20 20 20 20  nPinned--;.     
52a0: 20 70 63 61 63 68 65 45 6e 74 65 72 47 6c 6f 62   pcacheEnterGlob
52b0: 61 6c 28 29 3b 0a 20 20 20 20 20 20 70 63 61 63  al();.      pcac
52c0: 68 65 41 64 64 54 6f 4c 72 75 4c 69 73 74 28 70  heAddToLruList(p
52d0: 29 3b 0a 20 20 20 20 20 20 70 63 61 63 68 65 45  );.      pcacheE
52e0: 78 69 74 47 6c 6f 62 61 6c 28 29 3b 0a 20 20 20  xitGlobal();.   
52f0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 2f 2a   }else{.      /*
5300: 20 4d 6f 76 65 20 74 68 65 20 70 61 67 65 20 74   Move the page t
5310: 6f 20 74 68 65 20 68 65 61 64 20 6f 66 20 74 68  o the head of th
5320: 65 20 63 61 63 68 65 73 20 64 69 72 74 79 20 6c  e caches dirty l
5330: 69 73 74 2e 20 2a 2f 0a 20 20 20 20 20 20 70 63  ist. */.      pc
5340: 61 63 68 65 52 65 6d 6f 76 65 46 72 6f 6d 4c 69  acheRemoveFromLi
5350: 73 74 28 26 70 43 61 63 68 65 2d 3e 70 44 69 72  st(&pCache->pDir
5360: 74 79 2c 20 70 29 3b 0a 20 20 20 20 20 20 70 63  ty, p);.      pc
5370: 61 63 68 65 41 64 64 54 6f 4c 69 73 74 28 26 70  acheAddToList(&p
5380: 43 61 63 68 65 2d 3e 70 44 69 72 74 79 2c 20 70  Cache->pDirty, p
5390: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a  );.    }.  }.}..
53a0: 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63 61 63  void sqlite3Pcac
53b0: 68 65 52 65 66 28 50 67 48 64 72 20 2a 70 29 7b  heRef(PgHdr *p){
53c0: 0a 20 20 61 73 73 65 72 74 28 70 2d 3e 6e 52 65  .  assert(p->nRe
53d0: 66 3e 30 29 3b 0a 20 20 70 2d 3e 6e 52 65 66 2b  f>0);.  p->nRef+
53e0: 2b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 72 6f 70  +;.}../*.** Drop
53f0: 20 61 20 70 61 67 65 20 66 72 6f 6d 20 74 68 65   a page from the
5400: 20 63 61 63 68 65 2e 20 20 54 68 69 73 20 73 68   cache.  This sh
5410: 6f 75 6c 64 20 62 65 20 74 68 65 20 6f 6e 6c 79  ould be the only
5420: 20 72 65 66 65 72 65 6e 63 65 20 74 6f 0a 2a 2a   reference to.**
5430: 20 74 68 65 20 70 61 67 65 2e 0a 2a 2f 0a 76 6f   the page..*/.vo
5440: 69 64 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  id sqlite3Pcache
5450: 44 72 6f 70 28 50 67 48 64 72 20 2a 70 29 7b 0a  Drop(PgHdr *p){.
5460: 20 20 50 43 61 63 68 65 20 2a 70 43 61 63 68 65    PCache *pCache
5470: 3b 0a 20 20 61 73 73 65 72 74 28 20 70 2d 3e 6e  ;.  assert( p->n
5480: 52 65 66 3d 3d 31 20 29 3b 0a 20 20 70 43 61 63  Ref==1 );.  pCac
5490: 68 65 20 3d 20 70 2d 3e 70 43 61 63 68 65 3b 0a  he = p->pCache;.
54a0: 20 20 70 43 61 63 68 65 2d 3e 6e 52 65 66 2d 2d    pCache->nRef--
54b0: 3b 0a 20 20 70 43 61 63 68 65 2d 3e 6e 50 69 6e  ;.  pCache->nPin
54c0: 6e 65 64 2d 2d 3b 0a 20 20 69 66 28 20 70 2d 3e  ned--;.  if( p->
54d0: 66 6c 61 67 73 20 26 20 50 47 48 44 52 5f 44 49  flags & PGHDR_DI
54e0: 52 54 59 20 29 7b 0a 20 20 20 20 70 63 61 63 68  RTY ){.    pcach
54f0: 65 52 65 6d 6f 76 65 46 72 6f 6d 4c 69 73 74 28  eRemoveFromList(
5500: 26 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 2c  &pCache->pDirty,
5510: 20 70 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20   p);.  }else{.  
5520: 20 20 70 63 61 63 68 65 52 65 6d 6f 76 65 46 72    pcacheRemoveFr
5530: 6f 6d 4c 69 73 74 28 26 70 43 61 63 68 65 2d 3e  omList(&pCache->
5540: 70 43 6c 65 61 6e 2c 20 70 29 3b 0a 20 20 7d 0a  pClean, p);.  }.
5550: 20 20 70 63 61 63 68 65 52 65 6d 6f 76 65 46 72    pcacheRemoveFr
5560: 6f 6d 48 61 73 68 28 70 29 3b 0a 20 20 70 63 61  omHash(p);.  pca
5570: 63 68 65 45 6e 74 65 72 47 6c 6f 62 61 6c 28 29  cheEnterGlobal()
5580: 3b 0a 20 20 70 63 61 63 68 65 50 61 67 65 46 72  ;.  pcachePageFr
5590: 65 65 28 70 29 3b 0a 20 20 70 63 61 63 68 65 45  ee(p);.  pcacheE
55a0: 78 69 74 47 6c 6f 62 61 6c 28 29 3b 0a 7d 0a 0a  xitGlobal();.}..
55b0: 2f 2a 0a 2a 2a 20 4d 61 6b 65 20 73 75 72 65 20  /*.** Make sure 
55c0: 74 68 65 20 70 61 67 65 20 69 73 20 6d 61 72 6b  the page is mark
55d0: 65 64 20 61 73 20 64 69 72 74 79 2e 20 20 49 66  ed as dirty.  If
55e0: 20 69 74 20 69 73 6e 27 74 20 64 69 72 74 79 20   it isn't dirty 
55f0: 61 6c 72 65 61 64 79 2c 0a 2a 2a 20 6d 61 6b 65  already,.** make
5600: 20 69 74 20 73 6f 2e 0a 2a 2f 0a 76 6f 69 64 20   it so..*/.void 
5610: 73 71 6c 69 74 65 33 50 63 61 63 68 65 4d 61 6b  sqlite3PcacheMak
5620: 65 44 69 72 74 79 28 50 67 48 64 72 20 2a 70 29  eDirty(PgHdr *p)
5630: 7b 0a 20 20 50 43 61 63 68 65 20 2a 70 43 61 63  {.  PCache *pCac
5640: 68 65 3b 0a 20 20 70 2d 3e 66 6c 61 67 73 20 26  he;.  p->flags &
5650: 3d 20 7e 50 47 48 44 52 5f 44 4f 4e 54 5f 57 52  = ~PGHDR_DONT_WR
5660: 49 54 45 3b 0a 20 20 69 66 28 20 70 2d 3e 66 6c  ITE;.  if( p->fl
5670: 61 67 73 20 26 20 50 47 48 44 52 5f 44 49 52 54  ags & PGHDR_DIRT
5680: 59 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 61 73  Y ) return;.  as
5690: 73 65 72 74 28 20 28 70 2d 3e 66 6c 61 67 73 20  sert( (p->flags 
56a0: 26 20 50 47 48 44 52 5f 44 49 52 54 59 29 3d 3d  & PGHDR_DIRTY)==
56b0: 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70  0 );.  assert( p
56c0: 2d 3e 6e 52 65 66 3e 30 20 29 3b 0a 20 20 70 43  ->nRef>0 );.  pC
56d0: 61 63 68 65 20 3d 20 70 2d 3e 70 43 61 63 68 65  ache = p->pCache
56e0: 3b 0a 20 20 70 63 61 63 68 65 52 65 6d 6f 76 65  ;.  pcacheRemove
56f0: 46 72 6f 6d 4c 69 73 74 28 26 70 43 61 63 68 65  FromList(&pCache
5700: 2d 3e 70 43 6c 65 61 6e 2c 20 70 29 3b 0a 20 20  ->pClean, p);.  
5710: 70 63 61 63 68 65 41 64 64 54 6f 4c 69 73 74 28  pcacheAddToList(
5720: 26 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 2c  &pCache->pDirty,
5730: 20 70 29 3b 0a 20 20 70 2d 3e 66 6c 61 67 73 20   p);.  p->flags 
5740: 7c 3d 20 50 47 48 44 52 5f 44 49 52 54 59 3b 0a  |= PGHDR_DIRTY;.
5750: 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6b 65 20 73 75  }../*.** Make su
5760: 72 65 20 74 68 65 20 70 61 67 65 20 69 73 20 6d  re the page is m
5770: 61 72 6b 65 64 20 61 73 20 63 6c 65 61 6e 2e 20  arked as clean. 
5780: 20 49 66 20 69 74 20 69 73 6e 27 74 20 63 6c 65   If it isn't cle
5790: 61 6e 20 61 6c 72 65 61 64 79 2c 0a 2a 2a 20 6d  an already,.** m
57a0: 61 6b 65 20 69 74 20 73 6f 2e 0a 2a 2f 0a 76 6f  ake it so..*/.vo
57b0: 69 64 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  id sqlite3Pcache
57c0: 4d 61 6b 65 43 6c 65 61 6e 28 50 67 48 64 72 20  MakeClean(PgHdr 
57d0: 2a 70 29 7b 0a 20 20 50 43 61 63 68 65 20 2a 70  *p){.  PCache *p
57e0: 43 61 63 68 65 3b 0a 20 20 69 66 28 20 28 70 2d  Cache;.  if( (p-
57f0: 3e 66 6c 61 67 73 20 26 20 50 47 48 44 52 5f 44  >flags & PGHDR_D
5800: 49 52 54 59 29 3d 3d 30 20 29 20 72 65 74 75 72  IRTY)==0 ) retur
5810: 6e 3b 0a 20 20 61 73 73 65 72 74 28 20 70 2d 3e  n;.  assert( p->
5820: 61 70 53 61 76 65 5b 30 5d 3d 3d 30 20 26 26 20  apSave[0]==0 && 
5830: 70 2d 3e 61 70 53 61 76 65 5b 31 5d 3d 3d 30 20  p->apSave[1]==0 
5840: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 2d 3e  );.  assert( p->
5850: 66 6c 61 67 73 20 26 20 50 47 48 44 52 5f 44 49  flags & PGHDR_DI
5860: 52 54 59 20 29 3b 0a 20 20 70 43 61 63 68 65 20  RTY );.  pCache 
5870: 3d 20 70 2d 3e 70 43 61 63 68 65 3b 0a 20 20 70  = p->pCache;.  p
5880: 63 61 63 68 65 52 65 6d 6f 76 65 46 72 6f 6d 4c  cacheRemoveFromL
5890: 69 73 74 28 26 70 43 61 63 68 65 2d 3e 70 44 69  ist(&pCache->pDi
58a0: 72 74 79 2c 20 70 29 3b 0a 20 20 70 63 61 63 68  rty, p);.  pcach
58b0: 65 45 6e 74 65 72 47 6c 6f 62 61 6c 28 29 3b 0a  eEnterGlobal();.
58c0: 20 20 70 63 61 63 68 65 41 64 64 54 6f 4c 69 73    pcacheAddToLis
58d0: 74 28 26 70 43 61 63 68 65 2d 3e 70 43 6c 65 61  t(&pCache->pClea
58e0: 6e 2c 20 70 29 3b 0a 20 20 70 2d 3e 66 6c 61 67  n, p);.  p->flag
58f0: 73 20 26 3d 20 7e 50 47 48 44 52 5f 44 49 52 54  s &= ~PGHDR_DIRT
5900: 59 3b 0a 20 20 69 66 28 20 70 2d 3e 6e 52 65 66  Y;.  if( p->nRef
5910: 3d 3d 30 20 29 7b 0a 20 20 20 20 70 63 61 63 68  ==0 ){.    pcach
5920: 65 41 64 64 54 6f 4c 72 75 4c 69 73 74 28 70 29  eAddToLruList(p)
5930: 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 6e 50  ;.    pCache->nP
5940: 69 6e 6e 65 64 2d 2d 3b 0a 20 20 7d 0a 20 20 61  inned--;.  }.  a
5950: 73 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e 6e  ssert( pCache->n
5960: 50 69 6e 6e 65 64 3d 3d 70 63 61 63 68 65 50 69  Pinned==pcachePi
5970: 6e 6e 65 64 43 6f 75 6e 74 28 70 43 61 63 68 65  nnedCount(pCache
5980: 29 20 29 3b 0a 20 20 70 63 61 63 68 65 45 78 69  ) );.  pcacheExi
5990: 74 47 6c 6f 62 61 6c 28 29 3b 0a 7d 0a 0a 2f 2a  tGlobal();.}../*
59a0: 0a 2a 2a 20 4d 61 6b 65 20 65 76 65 72 79 20 70  .** Make every p
59b0: 61 67 65 20 69 6e 20 74 68 65 20 63 61 63 68 65  age in the cache
59c0: 20 63 6c 65 61 6e 2e 0a 2a 2f 0a 76 6f 69 64 20   clean..*/.void 
59d0: 73 71 6c 69 74 65 33 50 63 61 63 68 65 43 6c 65  sqlite3PcacheCle
59e0: 61 6e 41 6c 6c 28 50 43 61 63 68 65 20 2a 70 43  anAll(PCache *pC
59f0: 61 63 68 65 29 7b 0a 20 20 50 67 48 64 72 20 2a  ache){.  PgHdr *
5a00: 70 3b 0a 20 20 70 63 61 63 68 65 45 6e 74 65 72  p;.  pcacheEnter
5a10: 47 6c 6f 62 61 6c 28 29 3b 0a 20 20 77 68 69 6c  Global();.  whil
5a20: 65 28 20 28 70 20 3d 20 70 43 61 63 68 65 2d 3e  e( (p = pCache->
5a30: 70 44 69 72 74 79 29 21 3d 30 20 29 7b 0a 20 20  pDirty)!=0 ){.  
5a40: 20 20 61 73 73 65 72 74 28 20 70 2d 3e 61 70 53    assert( p->apS
5a50: 61 76 65 5b 30 5d 3d 3d 30 20 26 26 20 70 2d 3e  ave[0]==0 && p->
5a60: 61 70 53 61 76 65 5b 31 5d 3d 3d 30 20 29 3b 0a  apSave[1]==0 );.
5a70: 20 20 20 20 70 63 61 63 68 65 52 65 6d 6f 76 65      pcacheRemove
5a80: 46 72 6f 6d 4c 69 73 74 28 26 70 43 61 63 68 65  FromList(&pCache
5a90: 2d 3e 70 44 69 72 74 79 2c 20 70 29 3b 0a 20 20  ->pDirty, p);.  
5aa0: 20 20 70 2d 3e 66 6c 61 67 73 20 26 3d 20 7e 50    p->flags &= ~P
5ab0: 47 48 44 52 5f 44 49 52 54 59 3b 0a 20 20 20 20  GHDR_DIRTY;.    
5ac0: 70 63 61 63 68 65 41 64 64 54 6f 4c 69 73 74 28  pcacheAddToList(
5ad0: 26 70 43 61 63 68 65 2d 3e 70 43 6c 65 61 6e 2c  &pCache->pClean,
5ae0: 20 70 29 3b 0a 20 20 20 20 69 66 28 20 70 2d 3e   p);.    if( p->
5af0: 6e 52 65 66 3d 3d 30 20 29 7b 0a 20 20 20 20 20  nRef==0 ){.     
5b00: 20 70 63 61 63 68 65 41 64 64 54 6f 4c 72 75 4c   pcacheAddToLruL
5b10: 69 73 74 28 70 29 3b 0a 20 20 20 20 20 20 70 43  ist(p);.      pC
5b20: 61 63 68 65 2d 3e 6e 50 69 6e 6e 65 64 2d 2d 3b  ache->nPinned--;
5b30: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 73 71 6c  .    }.  }.  sql
5b40: 69 74 65 33 50 63 61 63 68 65 41 73 73 65 72 74  ite3PcacheAssert
5b50: 46 6c 61 67 73 28 70 43 61 63 68 65 2c 20 30 2c  Flags(pCache, 0,
5b60: 20 50 47 48 44 52 5f 44 49 52 54 59 29 3b 0a 20   PGHDR_DIRTY);. 
5b70: 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65 2d   assert( pCache-
5b80: 3e 6e 50 69 6e 6e 65 64 3d 3d 70 63 61 63 68 65  >nPinned==pcache
5b90: 50 69 6e 6e 65 64 43 6f 75 6e 74 28 70 43 61 63  PinnedCount(pCac
5ba0: 68 65 29 20 29 3b 0a 20 20 70 63 61 63 68 65 45  he) );.  pcacheE
5bb0: 78 69 74 47 6c 6f 62 61 6c 28 29 3b 0a 7d 0a 0a  xitGlobal();.}..
5bc0: 2f 2a 0a 2a 2a 20 43 68 61 6e 67 65 20 74 68 65  /*.** Change the
5bd0: 20 70 61 67 65 20 6e 75 6d 62 65 72 20 6f 66 20   page number of 
5be0: 70 61 67 65 20 70 20 74 6f 20 6e 65 77 50 67 6e  page p to newPgn
5bf0: 6f 2e 20 49 66 20 6e 65 77 50 67 6e 6f 20 69 73  o. If newPgno is
5c00: 20 30 2c 20 74 68 65 6e 20 74 68 65 0a 2a 2a 20   0, then the.** 
5c10: 70 61 67 65 20 6f 62 6a 65 63 74 20 69 73 20 61  page object is a
5c20: 64 64 65 64 20 74 6f 20 74 68 65 20 63 6c 65 61  dded to the clea
5c30: 6e 2d 6c 69 73 74 20 61 6e 64 20 74 68 65 20 50  n-list and the P
5c40: 47 48 44 52 5f 52 45 55 53 45 5f 55 4e 4c 49 4b  GHDR_REUSE_UNLIK
5c50: 45 4c 59 20 0a 2a 2a 20 66 6c 61 67 20 73 65 74  ELY .** flag set
5c60: 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
5c70: 33 50 63 61 63 68 65 4d 6f 76 65 28 50 67 48 64  3PcacheMove(PgHd
5c80: 72 20 2a 70 2c 20 50 67 6e 6f 20 6e 65 77 50 67  r *p, Pgno newPg
5c90: 6e 6f 29 7b 0a 20 20 61 73 73 65 72 74 28 20 70  no){.  assert( p
5ca0: 2d 3e 6e 52 65 66 3e 30 20 29 3b 0a 20 20 70 63  ->nRef>0 );.  pc
5cb0: 61 63 68 65 52 65 6d 6f 76 65 46 72 6f 6d 48 61  acheRemoveFromHa
5cc0: 73 68 28 70 29 3b 0a 20 20 70 2d 3e 70 67 6e 6f  sh(p);.  p->pgno
5cd0: 20 3d 20 6e 65 77 50 67 6e 6f 3b 0a 20 20 69 66   = newPgno;.  if
5ce0: 28 20 6e 65 77 50 67 6e 6f 3d 3d 30 20 29 7b 0a  ( newPgno==0 ){.
5cf0: 20 20 20 20 70 2d 3e 66 6c 61 67 73 20 7c 3d 20      p->flags |= 
5d00: 50 47 48 44 52 5f 52 45 55 53 45 5f 55 4e 4c 49  PGHDR_REUSE_UNLI
5d10: 4b 45 4c 59 3b 0a 20 20 20 20 70 63 61 63 68 65  KELY;.    pcache
5d20: 45 6e 74 65 72 47 6c 6f 62 61 6c 28 29 3b 0a 20  EnterGlobal();. 
5d30: 20 20 20 70 63 61 63 68 65 46 72 65 65 28 70 2d     pcacheFree(p-
5d40: 3e 61 70 53 61 76 65 5b 30 5d 29 3b 0a 20 20 20  >apSave[0]);.   
5d50: 20 70 63 61 63 68 65 46 72 65 65 28 70 2d 3e 61   pcacheFree(p->a
5d60: 70 53 61 76 65 5b 31 5d 29 3b 0a 20 20 20 20 70  pSave[1]);.    p
5d70: 63 61 63 68 65 45 78 69 74 47 6c 6f 62 61 6c 28  cacheExitGlobal(
5d80: 29 3b 0a 20 20 20 20 70 2d 3e 61 70 53 61 76 65  );.    p->apSave
5d90: 5b 30 5d 20 3d 20 30 3b 0a 20 20 20 20 70 2d 3e  [0] = 0;.    p->
5da0: 61 70 53 61 76 65 5b 31 5d 20 3d 20 30 3b 0a 20  apSave[1] = 0;. 
5db0: 20 20 20 73 71 6c 69 74 65 33 50 63 61 63 68 65     sqlite3Pcache
5dc0: 4d 61 6b 65 43 6c 65 61 6e 28 70 29 3b 0a 20 20  MakeClean(p);.  
5dd0: 7d 0a 20 20 70 63 61 63 68 65 41 64 64 54 6f 48  }.  pcacheAddToH
5de0: 61 73 68 28 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ash(p);.}../*.**
5df0: 20 52 65 6d 6f 76 65 20 61 6c 6c 20 63 6f 6e 74   Remove all cont
5e00: 65 6e 74 20 66 72 6f 6d 20 61 20 70 61 67 65 20  ent from a page 
5e10: 63 61 63 68 65 0a 2a 2f 0a 76 6f 69 64 20 70 63  cache.*/.void pc
5e20: 61 63 68 65 43 6c 65 61 72 28 50 43 61 63 68 65  acheClear(PCache
5e30: 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 50 67 48   *pCache){.  PgH
5e40: 64 72 20 2a 70 2c 20 2a 70 4e 65 78 74 3b 0a 20  dr *p, *pNext;. 
5e50: 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33   assert( sqlite3
5e60: 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 63 61 63  _mutex_held(pcac
5e70: 68 65 2e 6d 75 74 65 78 29 20 29 3b 0a 20 20 66  he.mutex) );.  f
5e80: 6f 72 28 70 3d 70 43 61 63 68 65 2d 3e 70 43 6c  or(p=pCache->pCl
5e90: 65 61 6e 3b 20 70 3b 20 70 3d 70 4e 65 78 74 29  ean; p; p=pNext)
5ea0: 7b 0a 20 20 20 20 70 4e 65 78 74 20 3d 20 70 2d  {.    pNext = p-
5eb0: 3e 70 4e 65 78 74 3b 0a 20 20 20 20 70 63 61 63  >pNext;.    pcac
5ec0: 68 65 52 65 6d 6f 76 65 46 72 6f 6d 4c 72 75 4c  heRemoveFromLruL
5ed0: 69 73 74 28 70 29 3b 0a 20 20 20 20 70 63 61 63  ist(p);.    pcac
5ee0: 68 65 50 61 67 65 46 72 65 65 28 70 29 3b 0a 20  hePageFree(p);. 
5ef0: 20 7d 0a 20 20 66 6f 72 28 70 3d 70 43 61 63 68   }.  for(p=pCach
5f00: 65 2d 3e 70 44 69 72 74 79 3b 20 70 3b 20 70 3d  e->pDirty; p; p=
5f10: 70 4e 65 78 74 29 7b 0a 20 20 20 20 70 4e 65 78  pNext){.    pNex
5f20: 74 20 3d 20 70 2d 3e 70 4e 65 78 74 3b 0a 20 20  t = p->pNext;.  
5f30: 20 20 70 63 61 63 68 65 50 61 67 65 46 72 65 65    pcachePageFree
5f40: 28 70 29 3b 0a 20 20 7d 0a 20 20 70 43 61 63 68  (p);.  }.  pCach
5f50: 65 2d 3e 70 43 6c 65 61 6e 20 3d 20 30 3b 0a 20  e->pClean = 0;. 
5f60: 20 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 20   pCache->pDirty 
5f70: 3d 20 30 3b 0a 20 20 70 43 61 63 68 65 2d 3e 70  = 0;.  pCache->p
5f80: 44 69 72 74 79 54 61 69 6c 20 3d 20 30 3b 0a 20  DirtyTail = 0;. 
5f90: 20 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 20 3d   pCache->nPage =
5fa0: 20 30 3b 0a 20 20 70 43 61 63 68 65 2d 3e 6e 50   0;.  pCache->nP
5fb0: 69 6e 6e 65 64 20 3d 20 30 3b 0a 20 20 6d 65 6d  inned = 0;.  mem
5fc0: 73 65 74 28 70 43 61 63 68 65 2d 3e 61 70 48 61  set(pCache->apHa
5fd0: 73 68 2c 20 30 2c 20 70 43 61 63 68 65 2d 3e 6e  sh, 0, pCache->n
5fe0: 48 61 73 68 2a 73 69 7a 65 6f 66 28 70 43 61 63  Hash*sizeof(pCac
5ff0: 68 65 2d 3e 61 70 48 61 73 68 5b 30 5d 29 29 3b  he->apHash[0]));
6000: 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 44 72 6f 70 20  .}.../*.** Drop 
6010: 65 76 65 72 79 20 63 61 63 68 65 20 65 6e 74 72  every cache entr
6020: 79 20 77 68 6f 73 65 20 70 61 67 65 20 6e 75 6d  y whose page num
6030: 62 65 72 20 69 73 20 67 72 65 61 74 65 72 20 74  ber is greater t
6040: 68 61 6e 20 22 70 67 6e 6f 22 2e 0a 2a 2f 0a 76  han "pgno"..*/.v
6050: 6f 69 64 20 73 71 6c 69 74 65 33 50 63 61 63 68  oid sqlite3Pcach
6060: 65 54 72 75 6e 63 61 74 65 28 50 43 61 63 68 65  eTruncate(PCache
6070: 20 2a 70 43 61 63 68 65 2c 20 50 67 6e 6f 20 70   *pCache, Pgno p
6080: 67 6e 6f 29 7b 0a 20 20 50 67 48 64 72 20 2a 70  gno){.  PgHdr *p
6090: 2c 20 2a 70 4e 65 78 74 3b 0a 20 20 50 67 48 64  , *pNext;.  PgHd
60a0: 72 20 2a 70 44 69 72 74 79 20 3d 20 70 43 61 63  r *pDirty = pCac
60b0: 68 65 2d 3e 70 44 69 72 74 79 3b 0a 20 20 70 63  he->pDirty;.  pc
60c0: 61 63 68 65 45 6e 74 65 72 47 6c 6f 62 61 6c 28  acheEnterGlobal(
60d0: 29 3b 0a 20 20 66 6f 72 28 70 3d 70 43 61 63 68  );.  for(p=pCach
60e0: 65 2d 3e 70 43 6c 65 61 6e 3b 20 70 7c 7c 70 44  e->pClean; p||pD
60f0: 69 72 74 79 3b 20 70 3d 70 4e 65 78 74 29 7b 0a  irty; p=pNext){.
6100: 20 20 20 20 69 66 28 20 21 70 20 29 7b 0a 20 20      if( !p ){.  
6110: 20 20 20 20 70 20 3d 20 70 44 69 72 74 79 3b 0a      p = pDirty;.
6120: 20 20 20 20 20 20 70 44 69 72 74 79 20 3d 20 30        pDirty = 0
6130: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 4e 65 78  ;.    }.    pNex
6140: 74 20 3d 20 70 2d 3e 70 4e 65 78 74 3b 0a 20 20  t = p->pNext;.  
6150: 20 20 69 66 28 20 70 2d 3e 70 67 6e 6f 3e 70 67    if( p->pgno>pg
6160: 6e 6f 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20  no ){.      if( 
6170: 70 2d 3e 6e 52 65 66 3d 3d 30 20 29 7b 0a 20 20  p->nRef==0 ){.  
6180: 20 20 20 20 20 20 70 63 61 63 68 65 52 65 6d 6f        pcacheRemo
6190: 76 65 46 72 6f 6d 48 61 73 68 28 70 29 3b 0a 20  veFromHash(p);. 
61a0: 20 20 20 20 20 20 20 69 66 28 20 70 2d 3e 66 6c         if( p->fl
61b0: 61 67 73 26 50 47 48 44 52 5f 44 49 52 54 59 20  ags&PGHDR_DIRTY 
61c0: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 70 63 61  ){.          pca
61d0: 63 68 65 52 65 6d 6f 76 65 46 72 6f 6d 4c 69 73  cheRemoveFromLis
61e0: 74 28 26 70 43 61 63 68 65 2d 3e 70 44 69 72 74  t(&pCache->pDirt
61f0: 79 2c 20 70 29 3b 0a 20 20 20 20 20 20 20 20 20  y, p);.         
6200: 20 70 43 61 63 68 65 2d 3e 6e 50 69 6e 6e 65 64   pCache->nPinned
6210: 2d 2d 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73  --;.        }els
6220: 65 7b 0a 20 20 20 20 20 20 20 20 20 20 70 63 61  e{.          pca
6230: 63 68 65 52 65 6d 6f 76 65 46 72 6f 6d 4c 69 73  cheRemoveFromLis
6240: 74 28 26 70 43 61 63 68 65 2d 3e 70 43 6c 65 61  t(&pCache->pClea
6250: 6e 2c 20 70 29 3b 0a 20 20 20 20 20 20 20 20 20  n, p);.         
6260: 20 70 63 61 63 68 65 52 65 6d 6f 76 65 46 72 6f   pcacheRemoveFro
6270: 6d 4c 72 75 4c 69 73 74 28 70 29 3b 0a 20 20 20  mLruList(p);.   
6280: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 70       }.        p
6290: 63 61 63 68 65 50 61 67 65 46 72 65 65 28 70 29  cachePageFree(p)
62a0: 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20  ;.      }else{. 
62b0: 20 20 20 20 20 20 20 2f 2a 20 49 66 20 74 68 65         /* If the
62c0: 72 65 20 61 72 65 20 72 65 66 65 72 65 6e 63 65  re are reference
62d0: 73 20 74 6f 20 74 68 65 20 70 61 67 65 2c 20 69  s to the page, i
62e0: 74 20 63 61 6e 6e 6f 74 20 62 65 20 66 72 65 65  t cannot be free
62f0: 64 2e 20 49 6e 20 74 68 69 73 0a 20 20 20 20 20  d. In this.     
6300: 20 20 20 2a 2a 20 63 61 73 65 2c 20 7a 65 72 6f     ** case, zero
6310: 20 74 68 65 20 70 61 67 65 20 63 6f 6e 74 65 6e   the page conten
6320: 74 20 69 6e 73 74 65 61 64 2e 0a 20 20 20 20 20  t instead..     
6330: 20 20 20 2a 2f 0a 20 20 20 20 20 20 20 20 6d 65     */.        me
6340: 6d 73 65 74 28 70 2d 3e 70 44 61 74 61 2c 20 30  mset(p->pData, 0
6350: 2c 20 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65  , pCache->szPage
6360: 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  );.      }.    }
6370: 0a 20 20 7d 0a 20 20 70 63 61 63 68 65 45 78 69  .  }.  pcacheExi
6380: 74 47 6c 6f 62 61 6c 28 29 3b 0a 7d 0a 0a 0a 2f  tGlobal();.}.../
6390: 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61 20 63 61 63  *.** Close a cac
63a0: 68 65 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69  he..*/.void sqli
63b0: 74 65 33 50 63 61 63 68 65 43 6c 6f 73 65 28 50  te3PcacheClose(P
63c0: 43 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b 0a  Cache *pCache){.
63d0: 20 20 70 63 61 63 68 65 45 6e 74 65 72 47 6c 6f    pcacheEnterGlo
63e0: 62 61 6c 28 29 3b 0a 0a 20 20 2f 2a 20 46 72 65  bal();..  /* Fre
63f0: 65 20 61 6c 6c 20 74 68 65 20 70 61 67 65 73 20  e all the pages 
6400: 75 73 65 64 20 62 79 20 74 68 69 73 20 70 61 67  used by this pag
6410: 65 72 20 61 6e 64 20 72 65 6d 6f 76 65 20 74 68  er and remove th
6420: 65 6d 20 66 72 6f 6d 20 74 68 65 20 4c 52 55 20  em from the LRU 
6430: 6c 69 73 74 2e 20 2a 2f 0a 20 20 70 63 61 63 68  list. */.  pcach
6440: 65 43 6c 65 61 72 28 70 43 61 63 68 65 29 3b 0a  eClear(pCache);.
6450: 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 62 50    if( pCache->bP
6460: 75 72 67 65 61 62 6c 65 20 29 7b 0a 20 20 20 20  urgeable ){.    
6470: 70 63 61 63 68 65 2e 6e 4d 61 78 50 61 67 65 20  pcache.nMaxPage 
6480: 2d 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 3b  -= pCache->nMax;
6490: 0a 20 20 20 20 70 63 61 63 68 65 2e 6e 4d 69 6e  .    pcache.nMin
64a0: 50 61 67 65 20 2d 3d 20 70 43 61 63 68 65 2d 3e  Page -= pCache->
64b0: 6e 4d 69 6e 3b 0a 20 20 7d 0a 20 20 73 71 6c 69  nMin;.  }.  sqli
64c0: 74 65 33 5f 66 72 65 65 28 70 43 61 63 68 65 2d  te3_free(pCache-
64d0: 3e 61 70 48 61 73 68 29 3b 0a 0a 20 20 70 63 61  >apHash);..  pca
64e0: 63 68 65 45 78 69 74 47 6c 6f 62 61 6c 28 29 3b  cheExitGlobal();
64f0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 72 65 73 65 72  .}../*.** Preser
6500: 76 65 20 74 68 65 20 63 6f 6e 74 65 6e 74 20 6f  ve the content o
6510: 66 20 74 68 65 20 70 61 67 65 2c 20 69 66 20 69  f the page, if i
6520: 74 20 68 61 73 20 6e 6f 74 20 62 65 65 6e 20 70  t has not been p
6530: 72 65 73 65 72 76 65 64 0a 2a 2a 20 61 6c 72 65  reserved.** alre
6540: 61 64 79 2e 20 20 49 66 20 69 64 4a 6f 75 72 6e  ady.  If idJourn
6550: 61 6c 3d 3d 30 20 74 68 65 6e 20 74 68 69 73 20  al==0 then this 
6560: 69 73 20 66 6f 72 20 74 68 65 20 6f 76 65 72 61  is for the overa
6570: 6c 6c 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 0a  ll transaction..
6580: 2a 2a 20 49 66 20 69 64 4a 6f 75 72 6e 61 6c 3d  ** If idJournal=
6590: 3d 31 20 74 68 65 6e 20 74 68 69 73 20 69 73 20  =1 then this is 
65a0: 66 6f 72 20 74 68 65 20 73 74 61 74 65 6d 65 6e  for the statemen
65b0: 74 20 6a 6f 75 72 6e 61 6c 2e 0a 2a 2a 0a 2a 2a  t journal..**.**
65c0: 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 69 73   This routine is
65d0: 20 75 73 65 64 20 66 6f 72 20 69 6e 2d 6d 65 6d   used for in-mem
65e0: 6f 72 79 20 64 61 74 61 62 61 73 65 73 20 6f 6e  ory databases on
65f0: 6c 79 2e 0a 2a 2a 0a 2a 2a 20 52 65 74 75 72 6e  ly..**.** Return
6600: 20 53 51 4c 49 54 45 5f 4f 4b 20 6f 72 20 53 51   SQLITE_OK or SQ
6610: 4c 49 54 45 5f 4e 4f 4d 45 4d 20 69 66 20 61 20  LITE_NOMEM if a 
6620: 6d 65 6d 6f 72 79 20 61 6c 6c 6f 63 61 74 69 6f  memory allocatio
6630: 6e 20 66 61 69 6c 73 2e 0a 2a 2f 0a 69 6e 74 20  n fails..*/.int 
6640: 73 71 6c 69 74 65 33 50 63 61 63 68 65 50 72 65  sqlite3PcachePre
6650: 73 65 72 76 65 28 50 67 48 64 72 20 2a 70 2c 20  serve(PgHdr *p, 
6660: 69 6e 74 20 69 64 4a 6f 75 72 6e 61 6c 29 7b 0a  int idJournal){.
6670: 20 20 76 6f 69 64 20 2a 78 3b 0a 20 20 69 6e 74    void *x;.  int
6680: 20 73 7a 3b 0a 20 20 61 73 73 65 72 74 28 20 70   sz;.  assert( p
6690: 2d 3e 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65  ->pCache->bPurge
66a0: 61 62 6c 65 3d 3d 30 20 29 3b 0a 20 20 69 66 28  able==0 );.  if(
66b0: 20 21 70 2d 3e 61 70 53 61 76 65 5b 69 64 4a 6f   !p->apSave[idJo
66c0: 75 72 6e 61 6c 5d 20 29 7b 0a 20 20 20 20 73 7a  urnal] ){.    sz
66d0: 20 3d 20 70 2d 3e 70 43 61 63 68 65 2d 3e 73 7a   = p->pCache->sz
66e0: 50 61 67 65 3b 0a 20 20 20 20 70 2d 3e 61 70 53  Page;.    p->apS
66f0: 61 76 65 5b 69 64 4a 6f 75 72 6e 61 6c 5d 20 3d  ave[idJournal] =
6700: 20 78 20 3d 20 73 71 6c 69 74 65 33 50 61 67 65   x = sqlite3Page
6710: 4d 61 6c 6c 6f 63 28 20 73 7a 20 29 3b 0a 20 20  Malloc( sz );.  
6720: 20 20 69 66 28 20 78 3d 3d 30 20 29 20 72 65 74    if( x==0 ) ret
6730: 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
6740: 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28 78 2c 20  ;.    memcpy(x, 
6750: 70 2d 3e 70 44 61 74 61 2c 20 73 7a 29 3b 0a 20  p->pData, sz);. 
6760: 20 7d 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49   }.  return SQLI
6770: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  TE_OK;.}../*.** 
6780: 43 6f 6d 6d 69 74 20 61 20 63 68 61 6e 67 65 20  Commit a change 
6790: 70 72 65 76 69 6f 75 73 6c 79 20 70 72 65 73 65  previously prese
67a0: 72 76 65 64 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71  rved..*/.void sq
67b0: 6c 69 74 65 33 50 63 61 63 68 65 43 6f 6d 6d 69  lite3PcacheCommi
67c0: 74 28 50 43 61 63 68 65 20 2a 70 43 61 63 68 65  t(PCache *pCache
67d0: 2c 20 69 6e 74 20 69 64 4a 6f 75 72 6e 61 6c 29  , int idJournal)
67e0: 7b 0a 20 20 50 67 48 64 72 20 2a 70 3b 0a 20 20  {.  PgHdr *p;.  
67f0: 70 63 61 63 68 65 45 6e 74 65 72 47 6c 6f 62 61  pcacheEnterGloba
6800: 6c 28 29 3b 20 20 20 20 20 2f 2a 20 4d 75 74 65  l();     /* Mute
6810: 78 20 69 73 20 72 65 71 75 69 72 65 64 20 74 6f  x is required to
6820: 20 63 61 6c 6c 20 70 63 61 63 68 65 46 72 65 65   call pcacheFree
6830: 28 29 20 2a 2f 0a 20 20 66 6f 72 28 70 3d 70 43  () */.  for(p=pC
6840: 61 63 68 65 2d 3e 70 44 69 72 74 79 3b 20 70 3b  ache->pDirty; p;
6850: 20 70 3d 70 2d 3e 70 4e 65 78 74 29 7b 0a 20 20   p=p->pNext){.  
6860: 20 20 69 66 28 20 70 2d 3e 61 70 53 61 76 65 5b    if( p->apSave[
6870: 69 64 4a 6f 75 72 6e 61 6c 5d 20 29 7b 0a 20 20  idJournal] ){.  
6880: 20 20 20 20 70 63 61 63 68 65 46 72 65 65 28 70      pcacheFree(p
6890: 2d 3e 61 70 53 61 76 65 5b 69 64 4a 6f 75 72 6e  ->apSave[idJourn
68a0: 61 6c 5d 29 3b 0a 20 20 20 20 20 20 70 2d 3e 61  al]);.      p->a
68b0: 70 53 61 76 65 5b 69 64 4a 6f 75 72 6e 61 6c 5d  pSave[idJournal]
68c0: 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a   = 0;.    }.  }.
68d0: 20 20 70 63 61 63 68 65 45 78 69 74 47 6c 6f 62    pcacheExitGlob
68e0: 61 6c 28 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  al();.}../*.** R
68f0: 6f 6c 6c 62 61 63 6b 20 61 20 63 68 61 6e 67 65  ollback a change
6900: 20 70 72 65 76 69 6f 75 73 6c 79 20 70 72 65 73   previously pres
6910: 65 72 76 65 64 2e 0a 2a 2f 0a 76 6f 69 64 20 73  erved..*/.void s
6920: 71 6c 69 74 65 33 50 63 61 63 68 65 52 6f 6c 6c  qlite3PcacheRoll
6930: 62 61 63 6b 28 50 43 61 63 68 65 20 2a 70 43 61  back(PCache *pCa
6940: 63 68 65 2c 20 69 6e 74 20 69 64 4a 6f 75 72 6e  che, int idJourn
6950: 61 6c 29 7b 0a 20 20 50 67 48 64 72 20 2a 70 3b  al){.  PgHdr *p;
6960: 0a 20 20 69 6e 74 20 73 7a 3b 0a 20 20 70 63 61  .  int sz;.  pca
6970: 63 68 65 45 6e 74 65 72 47 6c 6f 62 61 6c 28 29  cheEnterGlobal()
6980: 3b 20 20 20 20 20 2f 2a 20 4d 75 74 65 78 20 69  ;     /* Mutex i
6990: 73 20 72 65 71 75 69 72 65 64 20 74 6f 20 63 61  s required to ca
69a0: 6c 6c 20 70 63 61 63 68 65 46 72 65 65 28 29 20  ll pcacheFree() 
69b0: 2a 2f 0a 20 20 73 7a 20 3d 20 70 43 61 63 68 65  */.  sz = pCache
69c0: 2d 3e 73 7a 50 61 67 65 3b 0a 20 20 66 6f 72 28  ->szPage;.  for(
69d0: 70 3d 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79  p=pCache->pDirty
69e0: 3b 20 70 3b 20 70 3d 70 2d 3e 70 4e 65 78 74 29  ; p; p=p->pNext)
69f0: 7b 0a 20 20 20 20 69 66 28 20 70 2d 3e 61 70 53  {.    if( p->apS
6a00: 61 76 65 5b 69 64 4a 6f 75 72 6e 61 6c 5d 20 29  ave[idJournal] )
6a10: 7b 0a 20 20 20 20 20 20 6d 65 6d 63 70 79 28 70  {.      memcpy(p
6a20: 2d 3e 70 44 61 74 61 2c 20 70 2d 3e 61 70 53 61  ->pData, p->apSa
6a30: 76 65 5b 69 64 4a 6f 75 72 6e 61 6c 5d 2c 20 73  ve[idJournal], s
6a40: 7a 29 3b 0a 20 20 20 20 20 20 70 63 61 63 68 65  z);.      pcache
6a50: 46 72 65 65 28 70 2d 3e 61 70 53 61 76 65 5b 69  Free(p->apSave[i
6a60: 64 4a 6f 75 72 6e 61 6c 5d 29 3b 0a 20 20 20 20  dJournal]);.    
6a70: 20 20 70 2d 3e 61 70 53 61 76 65 5b 69 64 4a 6f    p->apSave[idJo
6a80: 75 72 6e 61 6c 5d 20 3d 20 30 3b 0a 20 20 20 20  urnal] = 0;.    
6a90: 7d 0a 20 20 7d 0a 20 20 70 63 61 63 68 65 45 78  }.  }.  pcacheEx
6aa0: 69 74 47 6c 6f 62 61 6c 28 29 3b 0a 7d 0a 0a 2f  itGlobal();.}../
6ab0: 2a 20 0a 2a 2a 20 41 73 73 65 72 74 20 66 6c 61  * .** Assert fla
6ac0: 67 73 20 73 65 74 74 69 6e 67 73 20 6f 6e 20 61  gs settings on a
6ad0: 6c 6c 20 70 61 67 65 73 2e 20 20 44 65 62 75 67  ll pages.  Debug
6ae0: 67 69 6e 67 20 6f 6e 6c 79 2e 0a 2a 2f 0a 76 6f  ging only..*/.vo
6af0: 69 64 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  id sqlite3Pcache
6b00: 41 73 73 65 72 74 46 6c 61 67 73 28 50 43 61 63  AssertFlags(PCac
6b10: 68 65 20 2a 70 43 61 63 68 65 2c 20 69 6e 74 20  he *pCache, int 
6b20: 74 72 75 65 4d 61 73 6b 2c 20 69 6e 74 20 66 61  trueMask, int fa
6b30: 6c 73 65 4d 61 73 6b 29 7b 0a 20 20 50 67 48 64  lseMask){.  PgHd
6b40: 72 20 2a 70 3b 0a 20 20 66 6f 72 28 70 3d 70 43  r *p;.  for(p=pC
6b50: 61 63 68 65 2d 3e 70 44 69 72 74 79 3b 20 70 3b  ache->pDirty; p;
6b60: 20 70 3d 70 2d 3e 70 4e 65 78 74 29 7b 0a 20 20   p=p->pNext){.  
6b70: 20 20 61 73 73 65 72 74 28 20 28 70 2d 3e 66 6c    assert( (p->fl
6b80: 61 67 73 26 74 72 75 65 4d 61 73 6b 29 3d 3d 74  ags&trueMask)==t
6b90: 72 75 65 4d 61 73 6b 20 29 3b 0a 20 20 20 20 61  rueMask );.    a
6ba0: 73 73 65 72 74 28 20 28 70 2d 3e 66 6c 61 67 73  ssert( (p->flags
6bb0: 26 66 61 6c 73 65 4d 61 73 6b 29 3d 3d 30 20 29  &falseMask)==0 )
6bc0: 3b 0a 20 20 7d 0a 20 20 66 6f 72 28 70 3d 70 43  ;.  }.  for(p=pC
6bd0: 61 63 68 65 2d 3e 70 43 6c 65 61 6e 3b 20 70 3b  ache->pClean; p;
6be0: 20 70 3d 70 2d 3e 70 4e 65 78 74 29 7b 0a 20 20   p=p->pNext){.  
6bf0: 20 20 61 73 73 65 72 74 28 20 28 70 2d 3e 66 6c    assert( (p->fl
6c00: 61 67 73 26 74 72 75 65 4d 61 73 6b 29 3d 3d 74  ags&trueMask)==t
6c10: 72 75 65 4d 61 73 6b 20 29 3b 0a 20 20 20 20 61  rueMask );.    a
6c20: 73 73 65 72 74 28 20 28 70 2d 3e 66 6c 61 67 73  ssert( (p->flags
6c30: 26 66 61 6c 73 65 4d 61 73 6b 29 3d 3d 30 20 29  &falseMask)==0 )
6c40: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20  ;.  }.}../* .** 
6c50: 44 69 73 63 61 72 64 20 74 68 65 20 63 6f 6e 74  Discard the cont
6c60: 65 6e 74 73 20 6f 66 20 74 68 65 20 63 61 63 68  ents of the cach
6c70: 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  e..*/.int sqlite
6c80: 33 50 63 61 63 68 65 43 6c 65 61 72 28 50 43 61  3PcacheClear(PCa
6c90: 63 68 65 20 2a 70 43 61 63 68 65 29 7b 0a 20 20  che *pCache){.  
6ca0: 61 73 73 65 72 74 28 70 43 61 63 68 65 2d 3e 6e  assert(pCache->n
6cb0: 52 65 66 3d 3d 30 29 3b 0a 20 20 70 63 61 63 68  Ref==0);.  pcach
6cc0: 65 45 6e 74 65 72 47 6c 6f 62 61 6c 28 29 3b 0a  eEnterGlobal();.
6cd0: 20 20 70 63 61 63 68 65 43 6c 65 61 72 28 70 43    pcacheClear(pC
6ce0: 61 63 68 65 29 3b 0a 20 20 70 63 61 63 68 65 45  ache);.  pcacheE
6cf0: 78 69 74 47 6c 6f 62 61 6c 28 29 3b 0a 20 20 72  xitGlobal();.  r
6d00: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
6d10: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 65 72 67 65 20  .}../*.** Merge 
6d20: 74 77 6f 20 6c 69 73 74 73 20 6f 66 20 70 61 67  two lists of pag
6d30: 65 73 20 63 6f 6e 6e 65 63 74 65 64 20 62 79 20  es connected by 
6d40: 70 44 69 72 74 79 20 61 6e 64 20 69 6e 20 70 67  pDirty and in pg
6d50: 6e 6f 20 6f 72 64 65 72 2e 0a 2a 2a 20 44 6f 20  no order..** Do 
6d60: 6e 6f 74 20 62 6f 74 68 20 66 69 78 69 6e 67 20  not both fixing 
6d70: 74 68 65 20 70 50 72 65 76 44 69 72 74 79 20 70  the pPrevDirty p
6d80: 6f 69 6e 74 65 72 73 2e 0a 2a 2f 0a 73 74 61 74  ointers..*/.stat
6d90: 69 63 20 50 67 48 64 72 20 2a 70 63 61 63 68 65  ic PgHdr *pcache
6da0: 4d 65 72 67 65 44 69 72 74 79 4c 69 73 74 28 50  MergeDirtyList(P
6db0: 67 48 64 72 20 2a 70 41 2c 20 50 67 48 64 72 20  gHdr *pA, PgHdr 
6dc0: 2a 70 42 29 7b 0a 20 20 50 67 48 64 72 20 72 65  *pB){.  PgHdr re
6dd0: 73 75 6c 74 2c 20 2a 70 54 61 69 6c 3b 0a 20 20  sult, *pTail;.  
6de0: 70 54 61 69 6c 20 3d 20 26 72 65 73 75 6c 74 3b  pTail = &result;
6df0: 0a 20 20 77 68 69 6c 65 28 20 70 41 20 26 26 20  .  while( pA && 
6e00: 70 42 20 29 7b 0a 20 20 20 20 69 66 28 20 70 41  pB ){.    if( pA
6e10: 2d 3e 70 67 6e 6f 3c 70 42 2d 3e 70 67 6e 6f 20  ->pgno<pB->pgno 
6e20: 29 7b 0a 20 20 20 20 20 20 70 54 61 69 6c 2d 3e  ){.      pTail->
6e30: 70 44 69 72 74 79 20 3d 20 70 41 3b 0a 20 20 20  pDirty = pA;.   
6e40: 20 20 20 70 54 61 69 6c 20 3d 20 70 41 3b 0a 20     pTail = pA;. 
6e50: 20 20 20 20 20 70 41 20 3d 20 70 41 2d 3e 70 44       pA = pA->pD
6e60: 69 72 74 79 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  irty;.    }else{
6e70: 0a 20 20 20 20 20 20 70 54 61 69 6c 2d 3e 70 44  .      pTail->pD
6e80: 69 72 74 79 20 3d 20 70 42 3b 0a 20 20 20 20 20  irty = pB;.     
6e90: 20 70 54 61 69 6c 20 3d 20 70 42 3b 0a 20 20 20   pTail = pB;.   
6ea0: 20 20 20 70 42 20 3d 20 70 42 2d 3e 70 44 69 72     pB = pB->pDir
6eb0: 74 79 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20  ty;.    }.  }.  
6ec0: 69 66 28 20 70 41 20 29 7b 0a 20 20 20 20 70 54  if( pA ){.    pT
6ed0: 61 69 6c 2d 3e 70 44 69 72 74 79 20 3d 20 70 41  ail->pDirty = pA
6ee0: 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 70 42  ;.  }else if( pB
6ef0: 20 29 7b 0a 20 20 20 20 70 54 61 69 6c 2d 3e 70   ){.    pTail->p
6f00: 44 69 72 74 79 20 3d 20 70 42 3b 0a 20 20 7d 65  Dirty = pB;.  }e
6f10: 6c 73 65 7b 0a 20 20 20 20 70 54 61 69 6c 2d 3e  lse{.    pTail->
6f20: 70 44 69 72 74 79 20 3d 20 30 3b 0a 20 20 7d 0a  pDirty = 0;.  }.
6f30: 20 20 72 65 74 75 72 6e 20 72 65 73 75 6c 74 2e    return result.
6f40: 70 44 69 72 74 79 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  pDirty;.}../*.**
6f50: 20 53 6f 72 74 20 74 68 65 20 6c 69 73 74 20 6f   Sort the list o
6f60: 66 20 70 61 67 65 73 20 69 6e 20 61 63 63 65 6e  f pages in accen
6f70: 64 69 6e 67 20 6f 72 64 65 72 20 62 79 20 70 67  ding order by pg
6f80: 6e 6f 2e 20 20 50 61 67 65 73 20 61 72 65 0a 2a  no.  Pages are.*
6f90: 2a 20 63 6f 6e 6e 65 63 74 65 64 20 62 79 20 70  * connected by p
6fa0: 44 69 72 74 79 20 70 6f 69 6e 74 65 72 73 2e 20  Dirty pointers. 
6fb0: 20 54 68 65 20 70 50 72 65 76 44 69 72 74 79 20   The pPrevDirty 
6fc0: 70 6f 69 6e 74 65 72 73 20 61 72 65 0a 2a 2a 20  pointers are.** 
6fd0: 63 6f 72 72 75 70 74 65 64 20 62 79 20 74 68 69  corrupted by thi
6fe0: 73 20 73 6f 72 74 2e 0a 2a 2f 0a 23 64 65 66 69  s sort..*/.#defi
6ff0: 6e 65 20 4e 5f 53 4f 52 54 5f 42 55 43 4b 45 54  ne N_SORT_BUCKET
7000: 5f 41 4c 4c 4f 43 20 32 35 0a 23 64 65 66 69 6e  _ALLOC 25.#defin
7010: 65 20 4e 5f 53 4f 52 54 5f 42 55 43 4b 45 54 20  e N_SORT_BUCKET 
7020: 20 20 20 20 20 20 32 35 0a 23 69 66 64 65 66 20        25.#ifdef 
7030: 53 51 4c 49 54 45 5f 54 45 53 54 0a 20 20 69 6e  SQLITE_TEST.  in
7040: 74 20 73 71 6c 69 74 65 33 5f 70 61 67 65 72 5f  t sqlite3_pager_
7050: 6e 5f 73 6f 72 74 5f 62 75 63 6b 65 74 20 3d 20  n_sort_bucket = 
7060: 30 3b 0a 20 20 23 75 6e 64 65 66 20 4e 5f 53 4f  0;.  #undef N_SO
7070: 52 54 5f 42 55 43 4b 45 54 0a 20 20 23 64 65 66  RT_BUCKET.  #def
7080: 69 6e 65 20 4e 5f 53 4f 52 54 5f 42 55 43 4b 45  ine N_SORT_BUCKE
7090: 54 20 5c 0a 20 20 20 28 73 71 6c 69 74 65 33 5f  T \.   (sqlite3_
70a0: 70 61 67 65 72 5f 6e 5f 73 6f 72 74 5f 62 75 63  pager_n_sort_buc
70b0: 6b 65 74 3f 73 71 6c 69 74 65 33 5f 70 61 67 65  ket?sqlite3_page
70c0: 72 5f 6e 5f 73 6f 72 74 5f 62 75 63 6b 65 74 3a  r_n_sort_bucket:
70d0: 4e 5f 53 4f 52 54 5f 42 55 43 4b 45 54 5f 41 4c  N_SORT_BUCKET_AL
70e0: 4c 4f 43 29 0a 23 65 6e 64 69 66 0a 73 74 61 74  LOC).#endif.stat
70f0: 69 63 20 50 67 48 64 72 20 2a 70 63 61 63 68 65  ic PgHdr *pcache
7100: 53 6f 72 74 44 69 72 74 79 4c 69 73 74 28 50 67  SortDirtyList(Pg
7110: 48 64 72 20 2a 70 49 6e 29 7b 0a 20 20 50 67 48  Hdr *pIn){.  PgH
7120: 64 72 20 2a 61 5b 4e 5f 53 4f 52 54 5f 42 55 43  dr *a[N_SORT_BUC
7130: 4b 45 54 5f 41 4c 4c 4f 43 5d 2c 20 2a 70 3b 0a  KET_ALLOC], *p;.
7140: 20 20 69 6e 74 20 69 3b 0a 20 20 6d 65 6d 73 65    int i;.  memse
7150: 74 28 61 2c 20 30 2c 20 73 69 7a 65 6f 66 28 61  t(a, 0, sizeof(a
7160: 29 29 3b 0a 20 20 77 68 69 6c 65 28 20 70 49 6e  ));.  while( pIn
7170: 20 29 7b 0a 20 20 20 20 70 20 3d 20 70 49 6e 3b   ){.    p = pIn;
7180: 0a 20 20 20 20 70 49 6e 20 3d 20 70 2d 3e 70 44  .    pIn = p->pD
7190: 69 72 74 79 3b 0a 20 20 20 20 70 2d 3e 70 44 69  irty;.    p->pDi
71a0: 72 74 79 20 3d 20 30 3b 0a 20 20 20 20 66 6f 72  rty = 0;.    for
71b0: 28 69 3d 30 3b 20 69 3c 4e 5f 53 4f 52 54 5f 42  (i=0; i<N_SORT_B
71c0: 55 43 4b 45 54 2d 31 3b 20 69 2b 2b 29 7b 0a 20  UCKET-1; i++){. 
71d0: 20 20 20 20 20 69 66 28 20 61 5b 69 5d 3d 3d 30       if( a[i]==0
71e0: 20 29 7b 0a 20 20 20 20 20 20 20 20 61 5b 69 5d   ){.        a[i]
71f0: 20 3d 20 70 3b 0a 20 20 20 20 20 20 20 20 62 72   = p;.        br
7200: 65 61 6b 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65  eak;.      }else
7210: 7b 0a 20 20 20 20 20 20 20 20 70 20 3d 20 70 63  {.        p = pc
7220: 61 63 68 65 4d 65 72 67 65 44 69 72 74 79 4c 69  acheMergeDirtyLi
7230: 73 74 28 61 5b 69 5d 2c 20 70 29 3b 0a 20 20 20  st(a[i], p);.   
7240: 20 20 20 20 20 61 5b 69 5d 20 3d 20 30 3b 0a 20       a[i] = 0;. 
7250: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20       }.    }.   
7260: 20 69 66 28 20 69 3d 3d 4e 5f 53 4f 52 54 5f 42   if( i==N_SORT_B
7270: 55 43 4b 45 54 2d 31 20 29 7b 0a 20 20 20 20 20  UCKET-1 ){.     
7280: 20 2f 2a 20 43 6f 76 65 72 61 67 65 3a 20 54 6f   /* Coverage: To
7290: 20 67 65 74 20 68 65 72 65 2c 20 74 68 65 72 65   get here, there
72a0: 20 6e 65 65 64 20 74 6f 20 62 65 20 32 5e 28 4e   need to be 2^(N
72b0: 5f 53 4f 52 54 5f 42 55 43 4b 45 54 29 20 0a 20  _SORT_BUCKET) . 
72c0: 20 20 20 20 20 2a 2a 20 65 6c 65 6d 65 6e 74 73       ** elements
72d0: 20 69 6e 20 74 68 65 20 69 6e 70 75 74 20 6c 69   in the input li
72e0: 73 74 2e 20 54 68 69 73 20 69 73 20 70 6f 73 73  st. This is poss
72f0: 69 62 6c 65 2c 20 62 75 74 20 69 6d 70 72 61 63  ible, but imprac
7300: 74 69 63 61 6c 2e 0a 20 20 20 20 20 20 2a 2a 20  tical..      ** 
7310: 54 65 73 74 69 6e 67 20 74 68 69 73 20 6c 69 6e  Testing this lin
7320: 65 20 69 73 20 74 68 65 20 70 6f 69 6e 74 20 6f  e is the point o
7330: 66 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c  f global variabl
7340: 65 0a 20 20 20 20 20 20 2a 2a 20 73 71 6c 69 74  e.      ** sqlit
7350: 65 33 5f 70 61 67 65 72 5f 6e 5f 73 6f 72 74 5f  e3_pager_n_sort_
7360: 62 75 63 6b 65 74 2e 0a 20 20 20 20 20 20 2a 2f  bucket..      */
7370: 0a 20 20 20 20 20 20 61 5b 69 5d 20 3d 20 70 63  .      a[i] = pc
7380: 61 63 68 65 4d 65 72 67 65 44 69 72 74 79 4c 69  acheMergeDirtyLi
7390: 73 74 28 61 5b 69 5d 2c 20 70 29 3b 0a 20 20 20  st(a[i], p);.   
73a0: 20 7d 0a 20 20 7d 0a 20 20 70 20 3d 20 61 5b 30   }.  }.  p = a[0
73b0: 5d 3b 0a 20 20 66 6f 72 28 69 3d 31 3b 20 69 3c  ];.  for(i=1; i<
73c0: 4e 5f 53 4f 52 54 5f 42 55 43 4b 45 54 3b 20 69  N_SORT_BUCKET; i
73d0: 2b 2b 29 7b 0a 20 20 20 20 70 20 3d 20 70 63 61  ++){.    p = pca
73e0: 63 68 65 4d 65 72 67 65 44 69 72 74 79 4c 69 73  cheMergeDirtyLis
73f0: 74 28 70 2c 20 61 5b 69 5d 29 3b 0a 20 20 7d 0a  t(p, a[i]);.  }.
7400: 20 20 72 65 74 75 72 6e 20 70 3b 0a 7d 0a 0a 2f    return p;.}../
7410: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20 6c 69  *.** Return a li
7420: 73 74 20 6f 66 20 61 6c 6c 20 64 69 72 74 79 20  st of all dirty 
7430: 70 61 67 65 73 20 69 6e 20 74 68 65 20 63 61 63  pages in the cac
7440: 68 65 2c 20 73 6f 72 74 65 64 20 62 79 20 70 61  he, sorted by pa
7450: 67 65 20 6e 75 6d 62 65 72 2e 0a 2a 2f 0a 50 67  ge number..*/.Pg
7460: 48 64 72 20 2a 73 71 6c 69 74 65 33 50 63 61 63  Hdr *sqlite3Pcac
7470: 68 65 44 69 72 74 79 4c 69 73 74 28 50 43 61 63  heDirtyList(PCac
7480: 68 65 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 50  he *pCache){.  P
7490: 67 48 64 72 20 2a 70 3b 0a 20 20 66 6f 72 28 70  gHdr *p;.  for(p
74a0: 3d 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 3b  =pCache->pDirty;
74b0: 20 70 3b 20 70 3d 70 2d 3e 70 4e 65 78 74 29 7b   p; p=p->pNext){
74c0: 0a 20 20 20 20 70 2d 3e 70 44 69 72 74 79 20 3d  .    p->pDirty =
74d0: 20 70 2d 3e 70 4e 65 78 74 3b 0a 20 20 7d 0a 20   p->pNext;.  }. 
74e0: 20 72 65 74 75 72 6e 20 70 63 61 63 68 65 53 6f   return pcacheSo
74f0: 72 74 44 69 72 74 79 4c 69 73 74 28 70 43 61 63  rtDirtyList(pCac
7500: 68 65 2d 3e 70 44 69 72 74 79 29 3b 0a 7d 0a 0a  he->pDirty);.}..
7510: 2f 2a 20 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68  /* .** Return th
7520: 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f  e total number o
7530: 66 20 6f 75 74 73 74 61 6e 64 69 6e 67 20 70 61  f outstanding pa
7540: 67 65 20 72 65 66 65 72 65 6e 63 65 73 2e 0a 2a  ge references..*
7550: 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 50 63 61  /.int sqlite3Pca
7560: 63 68 65 52 65 66 43 6f 75 6e 74 28 50 43 61 63  cheRefCount(PCac
7570: 68 65 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 72  he *pCache){.  r
7580: 65 74 75 72 6e 20 70 43 61 63 68 65 2d 3e 6e 52  eturn pCache->nR
7590: 65 66 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 52 65  ef;.}../* .** Re
75a0: 74 75 72 6e 20 74 68 65 20 74 6f 74 61 6c 20 6e  turn the total n
75b0: 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 69  umber of pages i
75c0: 6e 20 74 68 65 20 63 61 63 68 65 2e 0a 2a 2f 0a  n the cache..*/.
75d0: 69 6e 74 20 73 71 6c 69 74 65 33 50 63 61 63 68  int sqlite3Pcach
75e0: 65 50 61 67 65 63 6f 75 6e 74 28 50 43 61 63 68  ePagecount(PCach
75f0: 65 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 61 73  e *pCache){.  as
7600: 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e 6e 50  sert( pCache->nP
7610: 61 67 65 3e 3d 30 20 29 3b 0a 20 20 72 65 74 75  age>=0 );.  retu
7620: 72 6e 20 70 43 61 63 68 65 2d 3e 6e 50 61 67 65  rn pCache->nPage
7630: 3b 0a 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c 49  ;.}..#ifdef SQLI
7640: 54 45 5f 43 48 45 43 4b 5f 50 41 47 45 53 0a 2f  TE_CHECK_PAGES./
7650: 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69  *.** This functi
7660: 6f 6e 20 69 73 20 75 73 65 64 20 62 79 20 74 68  on is used by th
7670: 65 20 70 61 67 65 72 2e 63 20 6d 6f 64 75 6c 65  e pager.c module
7680: 20 74 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f   to iterate thro
7690: 75 67 68 20 61 6c 6c 20 0a 2a 2a 20 70 61 67 65  ugh all .** page
76a0: 73 20 69 6e 20 74 68 65 20 63 61 63 68 65 2e 20  s in the cache. 
76b0: 41 74 20 70 72 65 73 65 6e 74 2c 20 74 68 69 73  At present, this
76c0: 20 69 73 20 6f 6e 6c 79 20 72 65 71 75 69 72 65   is only require
76d0: 64 20 69 66 20 74 68 65 0a 2a 2a 20 53 51 4c 49  d if the.** SQLI
76e0: 54 45 5f 43 48 45 43 4b 5f 50 41 47 45 53 20 6d  TE_CHECK_PAGES m
76f0: 61 63 72 6f 20 28 75 73 65 64 20 66 6f 72 20 64  acro (used for d
7700: 65 62 75 67 67 69 6e 67 29 20 69 73 20 73 70 65  ebugging) is spe
7710: 63 69 66 69 65 64 2e 0a 2a 2f 0a 76 6f 69 64 20  cified..*/.void 
7720: 73 71 6c 69 74 65 33 50 63 61 63 68 65 49 74 65  sqlite3PcacheIte
7730: 72 61 74 65 28 50 43 61 63 68 65 20 2a 70 43 61  rate(PCache *pCa
7740: 63 68 65 2c 20 76 6f 69 64 20 28 2a 78 49 74 65  che, void (*xIte
7750: 72 29 28 50 67 48 64 72 20 2a 29 29 7b 0a 20 20  r)(PgHdr *)){.  
7760: 50 67 48 64 72 20 2a 70 3b 0a 20 20 66 6f 72 28  PgHdr *p;.  for(
7770: 70 3d 70 43 61 63 68 65 2d 3e 70 43 6c 65 61 6e  p=pCache->pClean
7780: 3b 20 70 3b 20 70 3d 70 2d 3e 70 4e 65 78 74 29  ; p; p=p->pNext)
7790: 7b 0a 20 20 20 20 78 49 74 65 72 28 70 29 3b 0a  {.    xIter(p);.
77a0: 20 20 7d 0a 20 20 66 6f 72 28 70 3d 70 43 61 63    }.  for(p=pCac
77b0: 68 65 2d 3e 70 44 69 72 74 79 3b 20 70 3b 20 70  he->pDirty; p; p
77c0: 3d 70 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20  =p->pNext){.    
77d0: 78 49 74 65 72 28 70 29 3b 0a 20 20 7d 0a 7d 0a  xIter(p);.  }.}.
77e0: 23 65 6e 64 69 66 0a 0a 2f 2a 20 0a 2a 2a 20 53  #endif../* .** S
77f0: 65 74 20 66 6c 61 67 73 20 6f 6e 20 61 6c 6c 20  et flags on all 
7800: 70 61 67 65 73 20 69 6e 20 74 68 65 20 70 61 67  pages in the pag
7810: 65 20 63 61 63 68 65 20 0a 2a 2f 0a 76 6f 69 64  e cache .*/.void
7820: 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 53 65   sqlite3PcacheSe
7830: 74 46 6c 61 67 73 28 50 43 61 63 68 65 20 2a 70  tFlags(PCache *p
7840: 43 61 63 68 65 2c 20 69 6e 74 20 61 6e 64 4d 61  Cache, int andMa
7850: 73 6b 2c 20 69 6e 74 20 6f 72 4d 61 73 6b 29 7b  sk, int orMask){
7860: 0a 20 20 50 67 48 64 72 20 2a 70 3b 0a 0a 20 20  .  PgHdr *p;..  
7870: 61 73 73 65 72 74 28 20 28 6f 72 4d 61 73 6b 26  assert( (orMask&
7880: 50 47 48 44 52 5f 4e 45 45 44 5f 53 59 4e 43 29  PGHDR_NEED_SYNC)
7890: 3d 3d 30 20 29 3b 0a 0a 20 20 2f 2a 20 4f 62 74  ==0 );..  /* Obt
78a0: 61 69 6e 20 74 68 65 20 67 6c 6f 62 61 6c 20 6d  ain the global m
78b0: 75 74 65 78 20 62 65 66 6f 72 65 20 6d 6f 64 69  utex before modi
78c0: 66 79 69 6e 67 20 61 6e 79 20 50 67 48 64 72 2e  fying any PgHdr.
78d0: 66 6c 61 67 73 20 76 61 72 69 61 62 6c 65 73 20  flags variables 
78e0: 0a 20 20 2a 2a 20 6f 72 20 74 72 61 76 65 72 73  .  ** or travers
78f0: 69 6e 67 20 74 68 65 20 4c 52 55 20 6c 69 73 74  ing the LRU list
7900: 2e 0a 20 20 2a 2f 20 0a 20 20 70 63 61 63 68 65  ..  */ .  pcache
7910: 45 6e 74 65 72 47 6c 6f 62 61 6c 28 29 3b 0a 0a  EnterGlobal();..
7920: 20 20 66 6f 72 28 70 3d 70 43 61 63 68 65 2d 3e    for(p=pCache->
7930: 70 44 69 72 74 79 3b 20 70 3b 20 70 3d 70 2d 3e  pDirty; p; p=p->
7940: 70 4e 65 78 74 29 7b 0a 20 20 20 20 70 2d 3e 66  pNext){.    p->f
7950: 6c 61 67 73 20 3d 20 28 70 2d 3e 66 6c 61 67 73  lags = (p->flags
7960: 26 61 6e 64 4d 61 73 6b 29 7c 6f 72 4d 61 73 6b  &andMask)|orMask
7970: 3b 0a 20 20 7d 0a 20 20 66 6f 72 28 70 3d 70 43  ;.  }.  for(p=pC
7980: 61 63 68 65 2d 3e 70 43 6c 65 61 6e 3b 20 70 3b  ache->pClean; p;
7990: 20 70 3d 70 2d 3e 70 4e 65 78 74 29 7b 0a 20 20   p=p->pNext){.  
79a0: 20 20 70 2d 3e 66 6c 61 67 73 20 3d 20 28 70 2d    p->flags = (p-
79b0: 3e 66 6c 61 67 73 26 61 6e 64 4d 61 73 6b 29 7c  >flags&andMask)|
79c0: 6f 72 4d 61 73 6b 3b 0a 20 20 7d 0a 0a 20 20 69  orMask;.  }..  i
79d0: 66 28 20 30 3d 3d 28 61 6e 64 4d 61 73 6b 26 50  f( 0==(andMask&P
79e0: 47 48 44 52 5f 4e 45 45 44 5f 53 59 4e 43 29 20  GHDR_NEED_SYNC) 
79f0: 29 7b 0a 20 20 20 20 50 67 48 64 72 20 2a 70 53  ){.    PgHdr *pS
7a00: 79 6e 63 65 64 20 3d 20 70 43 61 63 68 65 2d 3e  ynced = pCache->
7a10: 70 44 69 72 74 79 54 61 69 6c 3b 0a 20 20 20 20  pDirtyTail;.    
7a20: 77 68 69 6c 65 28 20 70 53 79 6e 63 65 64 20 26  while( pSynced &
7a30: 26 20 28 70 53 79 6e 63 65 64 2d 3e 66 6c 61 67  & (pSynced->flag
7a40: 73 26 50 47 48 44 52 5f 4e 45 45 44 5f 53 59 4e  s&PGHDR_NEED_SYN
7a50: 43 29 20 29 7b 0a 20 20 20 20 20 20 70 53 79 6e  C) ){.      pSyn
7a60: 63 65 64 20 3d 20 70 53 79 6e 63 65 64 2d 3e 70  ced = pSynced->p
7a70: 50 72 65 76 3b 0a 20 20 20 20 7d 0a 20 20 20 20  Prev;.    }.    
7a80: 70 43 61 63 68 65 2d 3e 70 53 79 6e 63 65 64 20  pCache->pSynced 
7a90: 3d 20 70 53 79 6e 63 65 64 3b 0a 20 20 7d 0a 0a  = pSynced;.  }..
7aa0: 20 20 70 63 61 63 68 65 45 78 69 74 47 6c 6f 62    pcacheExitGlob
7ab0: 61 6c 28 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53  al();.}../*.** S
7ac0: 65 74 20 74 68 65 20 73 75 67 67 65 73 74 65 64  et the suggested
7ad0: 20 63 61 63 68 65 2d 73 69 7a 65 20 76 61 6c 75   cache-size valu
7ae0: 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  e..*/.int sqlite
7af0: 33 50 63 61 63 68 65 47 65 74 43 61 63 68 65 73  3PcacheGetCaches
7b00: 69 7a 65 28 50 43 61 63 68 65 20 2a 70 43 61 63  ize(PCache *pCac
7b10: 68 65 29 7b 0a 20 20 72 65 74 75 72 6e 20 70 43  he){.  return pC
7b20: 61 63 68 65 2d 3e 6e 4d 61 78 3b 0a 7d 0a 0a 2f  ache->nMax;.}../
7b30: 2a 0a 2a 2a 20 53 65 74 20 74 68 65 20 73 75 67  *.** Set the sug
7b40: 67 65 73 74 65 64 20 63 61 63 68 65 2d 73 69 7a  gested cache-siz
7b50: 65 20 76 61 6c 75 65 2e 0a 2a 2f 0a 76 6f 69 64  e value..*/.void
7b60: 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 53 65   sqlite3PcacheSe
7b70: 74 43 61 63 68 65 73 69 7a 65 28 50 43 61 63 68  tCachesize(PCach
7b80: 65 20 2a 70 43 61 63 68 65 2c 20 69 6e 74 20 6d  e *pCache, int m
7b90: 78 50 61 67 65 29 7b 0a 20 20 69 66 28 20 6d 78  xPage){.  if( mx
7ba0: 50 61 67 65 3c 31 30 20 29 7b 0a 20 20 20 20 6d  Page<10 ){.    m
7bb0: 78 50 61 67 65 20 3d 20 31 30 3b 0a 20 20 7d 0a  xPage = 10;.  }.
7bc0: 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 62 50    if( pCache->bP
7bd0: 75 72 67 65 61 62 6c 65 20 29 7b 0a 20 20 20 20  urgeable ){.    
7be0: 70 63 61 63 68 65 45 6e 74 65 72 47 6c 6f 62 61  pcacheEnterGloba
7bf0: 6c 28 29 3b 0a 20 20 20 20 70 63 61 63 68 65 2e  l();.    pcache.
7c00: 6e 4d 61 78 50 61 67 65 20 2d 3d 20 70 43 61 63  nMaxPage -= pCac
7c10: 68 65 2d 3e 6e 4d 61 78 3b 0a 20 20 20 20 70 63  he->nMax;.    pc
7c20: 61 63 68 65 2e 6e 4d 61 78 50 61 67 65 20 2b 3d  ache.nMaxPage +=
7c30: 20 6d 78 50 61 67 65 3b 0a 20 20 20 20 70 63 61   mxPage;.    pca
7c40: 63 68 65 45 78 69 74 47 6c 6f 62 61 6c 28 29 3b  cheExitGlobal();
7c50: 0a 20 20 7d 0a 20 20 70 43 61 63 68 65 2d 3e 6e  .  }.  pCache->n
7c60: 4d 61 78 20 3d 20 6d 78 50 61 67 65 3b 0a 7d 0a  Max = mxPage;.}.
7c70: 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 45  .#ifdef SQLITE_E
7c80: 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e  NABLE_MEMORY_MAN
7c90: 41 47 45 4d 45 4e 54 0a 2f 2a 0a 2a 2a 20 54 68  AGEMENT./*.** Th
7ca0: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63  is function is c
7cb0: 61 6c 6c 65 64 20 74 6f 20 66 72 65 65 20 73 75  alled to free su
7cc0: 70 65 72 66 6c 75 6f 75 73 20 64 79 6e 61 6d 69  perfluous dynami
7cd0: 63 61 6c 6c 79 20 61 6c 6c 6f 63 61 74 65 64 20  cally allocated 
7ce0: 6d 65 6d 6f 72 79 0a 2a 2a 20 68 65 6c 64 20 62  memory.** held b
7cf0: 79 20 74 68 65 20 70 61 67 65 72 20 73 79 73 74  y the pager syst
7d00: 65 6d 2e 20 4d 65 6d 6f 72 79 20 69 6e 20 75 73  em. Memory in us
7d10: 65 20 62 79 20 61 6e 79 20 53 51 4c 69 74 65 20  e by any SQLite 
7d20: 70 61 67 65 72 20 61 6c 6c 6f 63 61 74 65 64 0a  pager allocated.
7d30: 2a 2a 20 62 79 20 74 68 65 20 63 75 72 72 65 6e  ** by the curren
7d40: 74 20 74 68 72 65 61 64 20 6d 61 79 20 62 65 20  t thread may be 
7d50: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 29 65 64  sqlite3_free()ed
7d60: 2e 0a 2a 2a 0a 2a 2a 20 6e 52 65 71 20 69 73 20  ..**.** nReq is 
7d70: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 62 79  the number of by
7d80: 74 65 73 20 6f 66 20 6d 65 6d 6f 72 79 20 72 65  tes of memory re
7d90: 71 75 69 72 65 64 2e 20 4f 6e 63 65 20 74 68 69  quired. Once thi
7da0: 73 20 6d 75 63 68 20 68 61 73 0a 2a 2a 20 62 65  s much has.** be
7db0: 65 6e 20 72 65 6c 65 61 73 65 64 2c 20 74 68 65  en released, the
7dc0: 20 66 75 6e 63 74 69 6f 6e 20 72 65 74 75 72 6e   function return
7dd0: 73 2e 20 54 68 65 20 72 65 74 75 72 6e 20 76 61  s. The return va
7de0: 6c 75 65 20 69 73 20 74 68 65 20 74 6f 74 61 6c  lue is the total
7df0: 20 6e 75 6d 62 65 72 20 0a 2a 2a 20 6f 66 20 62   number .** of b
7e00: 79 74 65 73 20 6f 66 20 6d 65 6d 6f 72 79 20 72  ytes of memory r
7e10: 65 6c 65 61 73 65 64 2e 0a 2a 2f 0a 69 6e 74 20  eleased..*/.int 
7e20: 73 71 6c 69 74 65 33 50 63 61 63 68 65 52 65 6c  sqlite3PcacheRel
7e30: 65 61 73 65 4d 65 6d 6f 72 79 28 69 6e 74 20 6e  easeMemory(int n
7e40: 52 65 71 29 7b 0a 20 20 69 6e 74 20 6e 46 72 65  Req){.  int nFre
7e50: 65 20 3d 20 30 3b 0a 20 20 69 66 28 20 70 63 61  e = 0;.  if( pca
7e60: 63 68 65 2e 70 53 74 61 72 74 3d 3d 30 20 29 7b  che.pStart==0 ){
7e70: 0a 20 20 20 20 50 67 48 64 72 20 2a 70 3b 0a 20  .    PgHdr *p;. 
7e80: 20 20 20 70 63 61 63 68 65 45 6e 74 65 72 47 6c     pcacheEnterGl
7e90: 6f 62 61 6c 28 29 3b 0a 20 20 20 20 77 68 69 6c  obal();.    whil
7ea0: 65 28 20 28 6e 52 65 71 3c 30 20 7c 7c 20 6e 46  e( (nReq<0 || nF
7eb0: 72 65 65 3c 6e 52 65 71 29 20 26 26 20 28 70 3d  ree<nReq) && (p=
7ec0: 70 63 61 63 68 65 52 65 63 79 63 6c 65 50 61 67  pcacheRecyclePag
7ed0: 65 28 29 29 20 29 7b 0a 20 20 20 20 20 20 6e 46  e()) ){.      nF
7ee0: 72 65 65 20 2b 3d 20 70 63 61 63 68 65 50 61 67  ree += pcachePag
7ef0: 65 53 69 7a 65 28 70 29 3b 0a 20 20 20 20 20 20  eSize(p);.      
7f00: 70 63 61 63 68 65 50 61 67 65 46 72 65 65 28 70  pcachePageFree(p
7f10: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 63 61  );.    }.    pca
7f20: 63 68 65 45 78 69 74 47 6c 6f 62 61 6c 28 29 3b  cheExitGlobal();
7f30: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 6e 46  .  }.  return nF
7f40: 72 65 65 3b 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a  ree;.}.#endif /*
7f50: 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d   SQLITE_ENABLE_M
7f60: 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54  EMORY_MANAGEMENT
7f70: 20 2a 2f 0a                                       */.