/ Hex Artifact Content
Login

Artifact 5b80676e664019c1ebc8356cc25332dd69da6269:


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 33 34 20 32 30 30  che.c,v 1.34 200
01c0: 38 2f 31 30 2f 31 37 20 31 38 3a 35 31 3a 35 33  8/10/17 18:51:53
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 2a 0a 2a   structure..**.*
0240: 2a 20 41 20 63 61 63 68 65 20 6d 61 79 20 6f 6e  * A cache may on
0250: 6c 79 20 62 65 20 64 65 6c 65 74 65 64 20 62 79  ly be deleted by
0260: 20 69 74 73 20 6f 77 6e 65 72 20 61 6e 64 20 77   its owner and w
0270: 68 69 6c 65 20 68 6f 6c 64 69 6e 67 20 74 68 65  hile holding the
0280: 0a 2a 2a 20 53 51 4c 49 54 45 5f 4d 55 54 45 58  .** SQLITE_MUTEX
0290: 5f 53 54 41 54 55 53 5f 4c 52 55 20 6d 75 74 65  _STATUS_LRU mute
02a0: 78 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 50 43 61  x..*/.struct PCa
02b0: 63 68 65 20 7b 0a 20 20 2f 2a 2a 2a 2a 2a 2a 2a  che {.  /*******
02c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
02d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
02e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
02f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 20  **************. 
0300: 20 2a 2a 20 54 68 65 20 66 69 72 73 74 20 67 72   ** The first gr
0310: 6f 75 70 20 6f 66 20 65 6c 65 6d 65 6e 74 73 20  oup of elements 
0320: 6d 61 79 20 62 65 20 72 65 61 64 20 6f 72 20 77  may be read or w
0330: 72 69 74 74 65 6e 20 61 74 20 61 6e 79 20 74 69  ritten at any ti
0340: 6d 65 20 62 79 0a 20 20 2a 2a 20 74 68 65 20 63  me by.  ** the c
0350: 61 63 68 65 20 6f 77 6e 65 72 20 77 69 74 68 6f  ache owner witho
0360: 75 74 20 68 6f 6c 64 69 6e 67 20 74 68 65 20 6d  ut holding the m
0370: 75 74 65 78 2e 20 20 4e 6f 20 74 68 72 65 61 64  utex.  No thread
0380: 20 6f 74 68 65 72 20 74 68 61 6e 20 74 68 65 0a   other than the.
0390: 20 20 2a 2a 20 63 61 63 68 65 20 6f 77 6e 65 72    ** cache owner
03a0: 20 69 73 20 70 65 72 6d 69 74 74 65 64 20 74 6f   is permitted to
03b0: 20 61 63 63 65 73 73 20 74 68 65 73 65 20 65 6c   access these el
03c0: 65 6d 65 6e 74 73 20 61 74 20 61 6e 79 20 74 69  ements at any ti
03d0: 6d 65 2e 0a 20 20 2a 2f 0a 20 20 50 67 48 64 72  me..  */.  PgHdr
03e0: 20 2a 70 44 69 72 74 79 2c 20 2a 70 44 69 72 74   *pDirty, *pDirt
03f0: 79 54 61 69 6c 3b 20 20 20 20 20 20 20 20 20 2f  yTail;         /
0400: 2a 20 4c 69 73 74 20 6f 66 20 64 69 72 74 79 20  * List of dirty 
0410: 70 61 67 65 73 20 69 6e 20 4c 52 55 20 6f 72 64  pages in LRU ord
0420: 65 72 20 2a 2f 0a 20 20 50 67 48 64 72 20 2a 70  er */.  PgHdr *p
0430: 53 79 6e 63 65 64 3b 20 20 20 20 20 20 20 20 20  Synced;         
0440: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c              /* L
0450: 61 73 74 20 73 79 6e 63 65 64 20 70 61 67 65 20  ast synced page 
0460: 69 6e 20 64 69 72 74 79 20 70 61 67 65 20 6c 69  in dirty page li
0470: 73 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 52 65 66  st */.  int nRef
0480: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
0490: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
04a0: 75 6d 62 65 72 20 6f 66 20 70 69 6e 6e 65 64 20  umber of pinned 
04b0: 70 61 67 65 73 20 2a 2f 0a 20 20 69 6e 74 20 6e  pages */.  int n
04c0: 50 69 6e 6e 65 64 3b 20 20 20 20 20 20 20 20 20  Pinned;         
04d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
04e0: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 70 69 6e 6e  * Number of pinn
04f0: 65 64 20 61 6e 64 2f 6f 72 20 64 69 72 74 79 20  ed and/or dirty 
0500: 70 61 67 65 73 20 2a 2f 0a 20 20 69 6e 74 20 6e  pages */.  int n
0510: 4d 61 78 3b 20 20 20 20 20 20 20 20 20 20 20 20  Max;            
0520: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0530: 2a 20 43 6f 6e 66 69 67 75 72 65 64 20 63 61 63  * Configured cac
0540: 68 65 20 73 69 7a 65 20 2a 2f 0a 20 20 69 6e 74  he size */.  int
0550: 20 6e 4d 69 6e 3b 20 20 20 20 20 20 20 20 20 20   nMin;          
0560: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0570: 20 2f 2a 20 43 6f 6e 66 69 67 75 72 65 64 20 6d   /* Configured m
0580: 69 6e 69 6d 75 6d 20 63 61 63 68 65 20 73 69 7a  inimum cache siz
0590: 65 20 2a 2f 0a 20 20 2f 2a 2a 2a 2a 2a 2a 2a 2a  e */.  /********
05a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
05b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
05c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
05d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 20  **************. 
05e0: 20 2a 2a 20 54 68 65 20 6e 65 78 74 20 67 72 6f   ** The next gro
05f0: 75 70 20 6f 66 20 65 6c 65 6d 65 6e 74 73 20 61  up of elements a
0600: 72 65 20 66 69 78 65 64 20 77 68 65 6e 20 74 68  re fixed when th
0610: 65 20 63 61 63 68 65 20 69 73 20 63 72 65 61 74  e cache is creat
0620: 65 64 20 61 6e 64 0a 20 20 2a 2a 20 6d 61 79 20  ed and.  ** may 
0630: 6e 6f 74 20 62 65 20 63 68 61 6e 67 65 64 20 61  not be changed a
0640: 66 74 65 72 77 61 72 64 73 2e 20 20 54 68 65 73  fterwards.  Thes
0650: 65 20 65 6c 65 6d 65 6e 74 73 20 63 61 6e 20 72  e elements can r
0660: 65 61 64 20 61 74 20 61 6e 79 20 74 69 6d 65 20  ead at any time 
0670: 62 79 0a 20 20 2a 2a 20 74 68 65 20 63 61 63 68  by.  ** the cach
0680: 65 20 6f 77 6e 65 72 20 6f 72 20 62 79 20 61 6e  e owner or by an
0690: 79 20 74 68 72 65 61 64 20 68 6f 6c 64 69 6e 67  y thread holding
06a0: 20 74 68 65 20 74 68 65 20 6d 75 74 65 78 2e 20   the the mutex. 
06b0: 20 4e 6f 6e 2d 6f 77 6e 65 72 0a 20 20 2a 2a 20   Non-owner.  ** 
06c0: 74 68 72 65 61 64 73 20 6d 75 73 74 20 68 6f 6c  threads must hol
06d0: 64 20 74 68 65 20 6d 75 74 65 78 20 77 68 65 6e  d the mutex when
06e0: 20 72 65 61 64 69 6e 67 20 74 68 65 73 65 20 65   reading these e
06f0: 6c 65 6d 65 6e 74 73 20 74 6f 20 70 72 65 76 65  lements to preve
0700: 6e 74 0a 20 20 2a 2a 20 74 68 65 20 65 6e 74 69  nt.  ** the enti
0710: 72 65 20 50 43 61 63 68 65 20 6f 62 6a 65 63 74  re PCache object
0720: 20 66 72 6f 6d 20 62 65 69 6e 67 20 64 65 6c 65   from being dele
0730: 74 65 64 20 64 75 72 69 6e 67 20 74 68 65 20 72  ted during the r
0740: 65 61 64 2e 0a 20 20 2a 2f 0a 20 20 69 6e 74 20  ead..  */.  int 
0750: 73 7a 50 61 67 65 3b 20 20 20 20 20 20 20 20 20  szPage;         
0760: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0770: 2f 2a 20 53 69 7a 65 20 6f 66 20 65 76 65 72 79  /* Size of every
0780: 20 70 61 67 65 20 69 6e 20 74 68 69 73 20 63 61   page in this ca
0790: 63 68 65 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 45  che */.  int szE
07a0: 78 74 72 61 3b 20 20 20 20 20 20 20 20 20 20 20  xtra;           
07b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
07c0: 53 69 7a 65 20 6f 66 20 65 78 74 72 61 20 73 70  Size of extra sp
07d0: 61 63 65 20 66 6f 72 20 65 61 63 68 20 70 61 67  ace for each pag
07e0: 65 20 2a 2f 0a 20 20 69 6e 74 20 62 50 75 72 67  e */.  int bPurg
07f0: 65 61 62 6c 65 3b 20 20 20 20 20 20 20 20 20 20  eable;          
0800: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72             /* Tr
0810: 75 65 20 69 66 20 70 61 67 65 73 20 61 72 65 20  ue if pages are 
0820: 6f 6e 20 62 61 63 6b 69 6e 67 20 73 74 6f 72 65  on backing store
0830: 20 2a 2f 0a 20 20 69 6e 74 20 28 2a 78 53 74 72   */.  int (*xStr
0840: 65 73 73 29 28 76 6f 69 64 2a 2c 50 67 48 64 72  ess)(void*,PgHdr
0850: 2a 29 3b 20 20 20 20 20 20 20 2f 2a 20 43 61 6c  *);       /* Cal
0860: 6c 20 74 6f 20 74 72 79 20 6d 61 6b 65 20 61 20  l to try make a 
0870: 70 61 67 65 20 63 6c 65 61 6e 20 2a 2f 0a 20 20  page clean */.  
0880: 76 6f 69 64 20 2a 70 53 74 72 65 73 73 3b 20 20  void *pStress;  
0890: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
08a0: 20 20 20 20 2f 2a 20 41 72 67 75 6d 65 6e 74 20      /* Argument 
08b0: 74 6f 20 78 53 74 72 65 73 73 20 2a 2f 0a 20 20  to xStress */.  
08c0: 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  /***************
08d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
08e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
08f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0900: 2a 2a 2a 2a 2a 2a 2a 0a 20 20 2a 2a 20 54 68 65  *******.  ** The
0910: 20 66 69 6e 61 6c 20 67 72 6f 75 70 20 6f 66 20   final group of 
0920: 65 6c 65 6d 65 6e 74 73 20 63 61 6e 20 6f 6e 6c  elements can onl
0930: 79 20 62 65 20 61 63 63 65 73 73 65 64 20 77 68  y be accessed wh
0940: 69 6c 65 20 68 6f 6c 64 69 6e 67 20 74 68 65 0a  ile holding the.
0950: 20 20 2a 2a 20 6d 75 74 65 78 2e 20 20 42 6f 74    ** mutex.  Bot
0960: 68 20 74 68 65 20 63 61 63 68 65 20 6f 77 6e 65  h the cache owne
0970: 72 20 61 6e 64 20 61 6e 79 20 6f 74 68 65 72 20  r and any other 
0980: 74 68 72 65 61 64 20 6d 75 73 74 20 68 6f 6c 64  thread must hold
0990: 20 74 68 65 20 6d 75 74 65 78 0a 20 20 2a 2a 20   the mutex.  ** 
09a0: 74 6f 20 72 65 61 64 20 6f 72 20 77 72 69 74 65  to read or write
09b0: 20 61 6e 79 20 6f 66 20 74 68 65 73 65 20 65 6c   any of these el
09c0: 65 6d 65 6e 74 73 2e 0a 20 20 2a 2f 0a 20 20 69  ements..  */.  i
09d0: 6e 74 20 6e 50 61 67 65 3b 20 20 20 20 20 20 20  nt nPage;       
09e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
09f0: 20 20 20 2f 2a 20 54 6f 74 61 6c 20 6e 75 6d 62     /* Total numb
0a00: 65 72 20 6f 66 20 70 61 67 65 73 20 69 6e 20 61  er of pages in a
0a10: 70 48 61 73 68 20 2a 2f 0a 20 20 69 6e 74 20 6e  pHash */.  int n
0a20: 48 61 73 68 3b 20 20 20 20 20 20 20 20 20 20 20  Hash;           
0a30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0a40: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 73 6c 6f 74  * Number of slot
0a50: 73 20 69 6e 20 61 70 48 61 73 68 5b 5d 20 2a 2f  s in apHash[] */
0a60: 0a 20 20 50 67 48 64 72 20 2a 2a 61 70 48 61 73  .  PgHdr **apHas
0a70: 68 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  h;              
0a80: 20 20 20 20 20 20 20 2f 2a 20 48 61 73 68 20 74         /* Hash t
0a90: 61 62 6c 65 20 66 6f 72 20 66 61 73 74 20 6c 6f  able for fast lo
0aa0: 6f 6b 75 70 20 62 79 20 70 67 6e 6f 20 2a 2f 0a  okup by pgno */.
0ab0: 20 20 50 67 48 64 72 20 2a 70 43 6c 65 61 6e 3b    PgHdr *pClean;
0ac0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ad0: 20 20 20 20 20 20 2f 2a 20 4c 69 73 74 20 6f 66        /* List of
0ae0: 20 63 6c 65 61 6e 20 70 61 67 65 73 20 69 6e 20   clean pages in 
0af0: 75 73 65 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a  use */.};../*.**
0b00: 20 46 72 65 65 20 73 6c 6f 74 73 20 69 6e 20 74   Free slots in t
0b10: 68 65 20 70 61 67 65 20 62 6c 6f 63 6b 20 61 6c  he page block al
0b20: 6c 6f 63 61 74 6f 72 0a 2a 2f 0a 74 79 70 65 64  locator.*/.typed
0b30: 65 66 20 73 74 72 75 63 74 20 50 67 46 72 65 65  ef struct PgFree
0b40: 73 6c 6f 74 20 50 67 46 72 65 65 73 6c 6f 74 3b  slot PgFreeslot;
0b50: 0a 73 74 72 75 63 74 20 50 67 46 72 65 65 73 6c  .struct PgFreesl
0b60: 6f 74 20 7b 0a 20 20 50 67 46 72 65 65 73 6c 6f  ot {.  PgFreeslo
0b70: 74 20 2a 70 4e 65 78 74 3b 20 20 2f 2a 20 4e 65  t *pNext;  /* Ne
0b80: 78 74 20 66 72 65 65 20 73 6c 6f 74 20 2a 2f 0a  xt free slot */.
0b90: 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 47 6c 6f 62 61 6c  };../*.** Global
0ba0: 20 64 61 74 61 20 66 6f 72 20 74 68 65 20 70 61   data for the pa
0bb0: 67 65 20 63 61 63 68 65 2e 0a 2a 2f 0a 73 74 61  ge cache..*/.sta
0bc0: 74 69 63 20 53 51 4c 49 54 45 5f 57 53 44 20 73  tic SQLITE_WSD s
0bd0: 74 72 75 63 74 20 50 43 61 63 68 65 47 6c 6f 62  truct PCacheGlob
0be0: 61 6c 20 7b 0a 20 20 69 6e 74 20 69 73 49 6e 69  al {.  int isIni
0bf0: 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t;              
0c00: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72             /* Tr
0c10: 75 65 20 77 68 65 6e 20 69 6e 69 74 69 61 6c 69  ue when initiali
0c20: 7a 65 64 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  zed */.  sqlite3
0c30: 5f 6d 75 74 65 78 20 2a 6d 75 74 65 78 3b 20 20  _mutex *mutex;  
0c40: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0c50: 73 74 61 74 69 63 20 6d 75 74 65 78 20 4d 55 54  static mutex MUT
0c60: 45 58 5f 53 54 41 54 49 43 5f 4c 52 55 20 2a 2f  EX_STATIC_LRU */
0c70: 0a 0a 20 20 69 6e 74 20 6e 4d 61 78 50 61 67 65  ..  int nMaxPage
0c80: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
0c90: 20 20 20 20 20 20 20 20 2f 2a 20 53 75 6d 20 6f          /* Sum o
0ca0: 66 20 6e 4d 61 78 50 61 67 65 20 66 6f 72 20 70  f nMaxPage for p
0cb0: 75 72 67 65 61 62 6c 65 20 63 61 63 68 65 73 20  urgeable caches 
0cc0: 2a 2f 0a 20 20 69 6e 74 20 6e 4d 69 6e 50 61 67  */.  int nMinPag
0cd0: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
0ce0: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 75 6d 20           /* Sum 
0cf0: 6f 66 20 6e 4d 69 6e 50 61 67 65 20 66 6f 72 20  of nMinPage for 
0d00: 70 75 72 67 65 61 62 6c 65 20 63 61 63 68 65 73  purgeable caches
0d10: 20 2a 2f 0a 20 20 69 6e 74 20 6e 43 75 72 72 65   */.  int nCurre
0d20: 6e 74 50 61 67 65 3b 20 20 20 20 20 20 20 20 20  ntPage;         
0d30: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
0d40: 62 65 72 20 6f 66 20 70 75 72 67 65 61 62 6c 65  ber of purgeable
0d50: 20 70 61 67 65 73 20 61 6c 6c 6f 63 61 74 65 64   pages allocated
0d60: 20 2a 2f 0a 20 20 50 67 48 64 72 20 2a 70 4c 72   */.  PgHdr *pLr
0d70: 75 48 65 61 64 2c 20 2a 70 4c 72 75 54 61 69 6c  uHead, *pLruTail
0d80: 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 52 55  ;         /* LRU
0d90: 20 6c 69 73 74 20 6f 66 20 75 6e 75 73 65 64 20   list of unused 
0da0: 63 6c 65 61 6e 20 70 67 73 20 2a 2f 0a 0a 20 20  clean pgs */..  
0db0: 2f 2a 20 56 61 72 69 61 62 6c 65 73 20 72 65 6c  /* Variables rel
0dc0: 61 74 65 64 20 74 6f 20 53 51 4c 49 54 45 5f 43  ated to SQLITE_C
0dd0: 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48 45 20  ONFIG_PAGECACHE 
0de0: 73 65 74 74 69 6e 67 73 2e 20 2a 2f 0a 20 20 69  settings. */.  i
0df0: 6e 74 20 73 7a 53 6c 6f 74 3b 20 20 20 20 20 20  nt szSlot;      
0e00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e10: 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 65 61     /* Size of ea
0e20: 63 68 20 66 72 65 65 20 73 6c 6f 74 20 2a 2f 0a  ch free slot */.
0e30: 20 20 76 6f 69 64 20 2a 70 53 74 61 72 74 2c 20    void *pStart, 
0e40: 2a 70 45 6e 64 3b 20 20 20 20 20 20 20 20 20 20  *pEnd;          
0e50: 20 20 20 20 20 20 2f 2a 20 42 6f 75 6e 64 73 20        /* Bounds 
0e60: 6f 66 20 70 61 67 65 63 61 63 68 65 20 6d 61 6c  of pagecache mal
0e70: 6c 6f 63 20 72 61 6e 67 65 20 2a 2f 0a 20 20 50  loc range */.  P
0e80: 67 46 72 65 65 73 6c 6f 74 20 2a 70 46 72 65 65  gFreeslot *pFree
0e90: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
0ea0: 20 20 20 2f 2a 20 46 72 65 65 20 70 61 67 65 20     /* Free page 
0eb0: 62 6c 6f 63 6b 73 20 2a 2f 0a 7d 20 70 63 61 63  blocks */.} pcac
0ec0: 68 65 20 3d 20 7b 30 7d 3b 0a 0a 2f 2a 0a 2a 2a  he = {0};../*.**
0ed0: 20 41 6c 6c 20 63 6f 64 65 20 69 6e 20 74 68 69   All code in thi
0ee0: 73 20 66 69 6c 65 20 73 68 6f 75 6c 64 20 61 63  s file should ac
0ef0: 63 65 73 73 20 74 68 65 20 67 6c 6f 62 61 6c 20  cess the global 
0f00: 70 63 61 63 68 65 20 73 74 72 75 63 74 75 72 65  pcache structure
0f10: 20 76 69 61 20 74 68 65 0a 2a 2a 20 61 6c 69 61   via the.** alia
0f20: 73 20 22 70 63 61 63 68 65 5f 67 22 2e 20 54 68  s "pcache_g". Th
0f30: 69 73 20 65 6e 73 75 72 65 73 20 74 68 61 74 20  is ensures that 
0f40: 74 68 65 20 57 53 44 20 65 6d 75 6c 61 74 69 6f  the WSD emulatio
0f50: 6e 20 69 73 20 75 73 65 64 20 77 68 65 6e 0a 2a  n is used when.*
0f60: 2a 20 63 6f 6d 70 69 6c 69 6e 67 20 66 6f 72 20  * compiling for 
0f70: 73 79 73 74 65 6d 73 20 74 68 61 74 20 64 6f 20  systems that do 
0f80: 6e 6f 74 20 73 75 70 70 6f 72 74 20 72 65 61 6c  not support real
0f90: 20 57 53 44 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65   WSD..*/.#define
0fa0: 20 70 63 61 63 68 65 5f 67 20 28 47 4c 4f 42 41   pcache_g (GLOBA
0fb0: 4c 28 73 74 72 75 63 74 20 50 43 61 63 68 65 47  L(struct PCacheG
0fc0: 6c 6f 62 61 6c 2c 20 70 63 61 63 68 65 29 29 0a  lobal, pcache)).
0fd0: 0a 2f 2a 0a 2a 2a 20 41 6c 6c 20 67 6c 6f 62 61  ./*.** All globa
0fe0: 6c 20 76 61 72 69 61 62 6c 65 73 20 75 73 65 64  l variables used
0ff0: 20 62 79 20 74 68 69 73 20 6d 6f 64 75 6c 65 20   by this module 
1000: 28 61 6c 6c 20 6f 66 20 77 68 69 63 68 20 61 72  (all of which ar
1010: 65 20 67 72 6f 75 70 65 64 20 0a 2a 2a 20 74 6f  e grouped .** to
1020: 67 65 74 68 65 72 20 69 6e 20 67 6c 6f 62 61 6c  gether in global
1030: 20 73 74 72 75 63 74 75 72 65 20 22 70 63 61 63   structure "pcac
1040: 68 65 22 20 61 62 6f 76 65 29 20 61 72 65 20 70  he" above) are p
1050: 72 6f 74 65 63 74 65 64 20 62 79 20 74 68 65 20  rotected by the 
1060: 73 74 61 74 69 63 20 0a 2a 2a 20 53 51 4c 49 54  static .** SQLIT
1070: 45 5f 4d 55 54 45 58 5f 53 54 41 54 49 43 5f 4c  E_MUTEX_STATIC_L
1080: 52 55 20 6d 75 74 65 78 2e 20 41 20 70 6f 69 6e  RU mutex. A poin
1090: 74 65 72 20 74 6f 20 74 68 69 73 20 6d 75 74 65  ter to this mute
10a0: 78 20 69 73 20 73 74 6f 72 65 64 20 69 6e 0a 2a  x is stored in.*
10b0: 2a 20 76 61 72 69 61 62 6c 65 20 22 70 63 61 63  * variable "pcac
10c0: 68 65 2e 6d 75 74 65 78 22 2e 0a 2a 2a 0a 2a 2a  he.mutex"..**.**
10d0: 20 53 6f 6d 65 20 65 6c 65 6d 65 6e 74 73 20 6f   Some elements o
10e0: 66 20 74 68 65 20 50 43 61 63 68 65 20 61 6e 64  f the PCache and
10f0: 20 50 67 48 64 72 20 73 74 72 75 63 74 75 72 65   PgHdr structure
1100: 73 20 61 72 65 20 70 72 6f 74 65 63 74 65 64 20  s are protected 
1110: 62 79 20 74 68 65 20 0a 2a 2a 20 53 51 4c 49 54  by the .** SQLIT
1120: 45 5f 4d 55 54 45 58 5f 53 54 41 54 55 53 5f 4c  E_MUTEX_STATUS_L
1130: 52 55 20 6d 75 74 65 78 20 61 6e 64 20 6f 74 68  RU mutex and oth
1140: 65 72 20 61 72 65 20 6e 6f 74 2e 20 20 54 68 65  er are not.  The
1150: 20 70 72 6f 74 65 63 74 65 64 0a 2a 2a 20 65 6c   protected.** el
1160: 65 6d 65 6e 74 73 20 61 72 65 20 67 72 6f 75 70  ements are group
1170: 65 64 20 61 74 20 74 68 65 20 65 6e 64 20 6f 66  ed at the end of
1180: 20 74 68 65 20 73 74 72 75 63 74 75 72 65 73 20   the structures 
1190: 61 6e 64 20 61 72 65 20 63 6c 65 61 72 6c 79 0a  and are clearly.
11a0: 2a 2a 20 6d 61 72 6b 65 64 2e 0a 2a 2a 0a 2a 2a  ** marked..**.**
11b0: 20 55 73 65 20 74 68 65 20 66 6f 6c 6c 6f 77 69   Use the followi
11c0: 6e 67 20 6d 61 63 72 6f 73 20 6d 75 73 74 20 73  ng macros must s
11d0: 75 72 72 6f 75 6e 64 20 61 6c 6c 20 61 63 63 65  urround all acce
11e0: 73 73 20 28 72 65 61 64 20 6f 72 20 77 72 69 74  ss (read or writ
11f0: 65 29 0a 2a 2a 20 6f 66 20 70 72 6f 74 65 63 74  e).** of protect
1200: 65 64 20 65 6c 65 6d 65 6e 74 73 2e 20 20 54 68  ed elements.  Th
1210: 65 20 6d 75 74 65 78 20 69 73 20 6e 6f 74 20 72  e mutex is not r
1220: 65 63 75 72 73 69 76 65 20 61 6e 64 20 6d 61 79  ecursive and may
1230: 20 6e 6f 74 20 62 65 0a 2a 2a 20 65 6e 74 65 72   not be.** enter
1240: 65 64 20 6d 6f 72 65 20 74 68 61 6e 20 6f 6e 63  ed more than onc
1250: 65 2e 20 20 54 68 65 20 70 63 61 63 68 65 4d 75  e.  The pcacheMu
1260: 74 65 78 48 65 6c 64 28 29 20 6d 61 63 72 6f 20  texHeld() macro 
1270: 73 68 6f 75 6c 64 20 6f 6e 6c 79 20 62 65 0a 2a  should only be.*
1280: 2a 20 75 73 65 64 20 77 69 74 68 69 6e 20 61 6e  * used within an
1290: 20 61 73 73 65 72 74 28 29 20 74 6f 20 76 65 72   assert() to ver
12a0: 69 66 79 20 74 68 61 74 20 74 68 65 20 6d 75 74  ify that the mut
12b0: 65 78 20 69 73 20 62 65 69 6e 67 20 68 65 6c 64  ex is being held
12c0: 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 70 63 61  ..*/.#define pca
12d0: 63 68 65 45 6e 74 65 72 4d 75 74 65 78 28 29 20  cheEnterMutex() 
12e0: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e  sqlite3_mutex_en
12f0: 74 65 72 28 70 63 61 63 68 65 5f 67 2e 6d 75 74  ter(pcache_g.mut
1300: 65 78 29 0a 23 64 65 66 69 6e 65 20 70 63 61 63  ex).#define pcac
1310: 68 65 45 78 69 74 4d 75 74 65 78 28 29 20 20 73  heExitMutex()  s
1320: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61  qlite3_mutex_lea
1330: 76 65 28 70 63 61 63 68 65 5f 67 2e 6d 75 74 65  ve(pcache_g.mute
1340: 78 29 0a 23 64 65 66 69 6e 65 20 70 63 61 63 68  x).#define pcach
1350: 65 4d 75 74 65 78 48 65 6c 64 28 29 20 20 73 71  eMutexHeld()  sq
1360: 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64  lite3_mutex_held
1370: 28 70 63 61 63 68 65 5f 67 2e 6d 75 74 65 78 29  (pcache_g.mutex)
1380: 0a 0a 2f 2a 0a 2a 2a 20 53 6f 6d 65 20 6f 66 20  ../*.** Some of 
1390: 74 68 65 20 61 73 73 65 72 74 28 29 20 6d 61 63  the assert() mac
13a0: 72 6f 73 20 69 6e 20 74 68 69 73 20 63 6f 64 65  ros in this code
13b0: 20 61 72 65 20 74 6f 6f 20 65 78 70 65 6e 73 69   are too expensi
13c0: 76 65 20 74 6f 20 72 75 6e 0a 2a 2a 20 65 76 65  ve to run.** eve
13d0: 6e 20 64 75 72 69 6e 67 20 6e 6f 72 6d 61 6c 20  n during normal 
13e0: 64 65 62 75 67 67 69 6e 67 2e 20 20 55 73 65 20  debugging.  Use 
13f0: 74 68 65 6d 20 6f 6e 6c 79 20 72 61 72 65 6c 79  them only rarely
1400: 20 6f 6e 20 6c 6f 6e 67 2d 72 75 6e 6e 69 6e 67   on long-running
1410: 0a 2a 2a 20 74 65 73 74 73 2e 20 20 45 6e 61 62  .** tests.  Enab
1420: 6c 65 20 74 68 65 20 65 78 70 65 6e 73 69 76 65  le the expensive
1430: 20 61 73 73 65 72 74 73 20 75 73 69 6e 67 20 74   asserts using t
1440: 68 65 0a 2a 2a 20 2d 44 53 51 4c 49 54 45 5f 45  he.** -DSQLITE_E
1450: 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49 56 45 5f  NABLE_EXPENSIVE_
1460: 41 53 53 45 52 54 3d 31 20 63 6f 6d 70 69 6c 65  ASSERT=1 compile
1470: 2d 74 69 6d 65 20 6f 70 74 69 6f 6e 2e 0a 2a 2f  -time option..*/
1480: 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 45  .#ifdef SQLITE_E
1490: 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49 56 45 5f  NABLE_EXPENSIVE_
14a0: 41 53 53 45 52 54 0a 23 20 64 65 66 69 6e 65 20  ASSERT.# define 
14b0: 65 78 70 65 6e 73 69 76 65 5f 61 73 73 65 72 74  expensive_assert
14c0: 28 58 29 20 20 61 73 73 65 72 74 28 58 29 0a 23  (X)  assert(X).#
14d0: 65 6c 73 65 0a 23 20 64 65 66 69 6e 65 20 65 78  else.# define ex
14e0: 70 65 6e 73 69 76 65 5f 61 73 73 65 72 74 28 58  pensive_assert(X
14f0: 29 0a 23 65 6e 64 69 66 0a 0a 2f 2a 2a 2a 2a 2a  ).#endif../*****
1500: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1510: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 4c 69  ************* Li
1520: 6e 6b 65 64 20 4c 69 73 74 20 4d 61 6e 61 67 65  nked List Manage
1530: 6d 65 6e 74 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ment ***********
1540: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 23 69 66 20  *********/..#if 
1550: 21 64 65 66 69 6e 65 64 28 4e 44 45 42 55 47 29  !defined(NDEBUG)
1560: 20 26 26 20 64 65 66 69 6e 65 64 28 53 51 4c 49   && defined(SQLI
1570: 54 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53  TE_ENABLE_EXPENS
1580: 49 56 45 5f 41 53 53 45 52 54 29 0a 2f 2a 0a 2a  IVE_ASSERT)./*.*
1590: 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 76  * This routine v
15a0: 65 72 69 66 69 65 73 20 74 68 61 74 20 74 68 65  erifies that the
15b0: 20 6e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72 69   number of entri
15c0: 65 73 20 69 6e 20 74 68 65 20 68 61 73 68 20 74  es in the hash t
15d0: 61 62 6c 65 0a 2a 2a 20 69 73 20 70 43 61 63 68  able.** is pCach
15e0: 65 2d 3e 6e 50 61 67 65 2e 20 20 54 68 69 73 20  e->nPage.  This 
15f0: 72 6f 75 74 69 6e 65 20 69 73 20 75 73 65 64 20  routine is used 
1600: 77 69 74 68 69 6e 20 61 73 73 65 72 74 28 29 20  within assert() 
1610: 73 74 61 74 65 6d 65 6e 74 73 0a 2a 2a 20 6f 6e  statements.** on
1620: 6c 79 20 61 6e 64 20 69 73 20 74 68 65 72 65 66  ly and is theref
1630: 6f 72 65 20 64 69 73 61 62 6c 65 64 20 64 75 72  ore disabled dur
1640: 69 6e 67 20 70 72 6f 64 75 63 74 69 6f 6e 20 62  ing production b
1650: 75 69 6c 64 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  uilds..*/.static
1660: 20 69 6e 74 20 70 63 61 63 68 65 43 68 65 63 6b   int pcacheCheck
1670: 48 61 73 68 43 6f 75 6e 74 28 50 43 61 63 68 65  HashCount(PCache
1680: 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 69 6e 74   *pCache){.  int
1690: 20 69 3b 0a 20 20 69 6e 74 20 6e 50 61 67 65 20   i;.  int nPage 
16a0: 3d 20 30 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20  = 0;.  for(i=0; 
16b0: 69 3c 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3b  i<pCache->nHash;
16c0: 20 69 2b 2b 29 7b 0a 20 20 20 20 50 67 48 64 72   i++){.    PgHdr
16d0: 20 2a 70 3b 0a 20 20 20 20 66 6f 72 28 70 3d 70   *p;.    for(p=p
16e0: 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 69 5d  Cache->apHash[i]
16f0: 3b 20 70 3b 20 70 3d 70 2d 3e 70 4e 65 78 74 48  ; p; p=p->pNextH
1700: 61 73 68 29 7b 0a 20 20 20 20 20 20 6e 50 61 67  ash){.      nPag
1710: 65 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  e++;.    }.  }. 
1720: 20 61 73 73 65 72 74 28 20 6e 50 61 67 65 3d 3d   assert( nPage==
1730: 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 20 29 3b  pCache->nPage );
1740: 0a 20 20 72 65 74 75 72 6e 20 31 3b 0a 7d 0a 23  .  return 1;.}.#
1750: 65 6e 64 69 66 20 2f 2a 20 21 4e 44 45 42 55 47  endif /* !NDEBUG
1760: 20 26 26 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c   && SQLITE_ENABL
1770: 45 5f 45 58 50 45 4e 53 49 56 45 5f 41 53 53 45  E_EXPENSIVE_ASSE
1780: 52 54 20 2a 2f 0a 0a 0a 23 69 66 20 21 64 65 66  RT */...#if !def
1790: 69 6e 65 64 28 4e 44 45 42 55 47 29 20 26 26 20  ined(NDEBUG) && 
17a0: 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 45  defined(SQLITE_E
17b0: 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49 56 45 5f  NABLE_EXPENSIVE_
17c0: 41 53 53 45 52 54 29 0a 2f 2a 0a 2a 2a 20 42 61  ASSERT)./*.** Ba
17d0: 73 65 64 20 6f 6e 20 74 68 65 20 63 75 72 72 65  sed on the curre
17e0: 6e 74 20 76 61 6c 75 65 20 6f 66 20 50 43 61 63  nt value of PCac
17f0: 68 65 2e 6e 52 65 66 20 61 6e 64 20 74 68 65 20  he.nRef and the 
1800: 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 0a  contents of the.
1810: 2a 2a 20 50 43 61 63 68 65 2e 70 44 69 72 74 79  ** PCache.pDirty
1820: 20 6c 69 73 74 2c 20 72 65 74 75 72 6e 20 74 68   list, return th
1830: 65 20 65 78 70 65 63 74 65 64 20 76 61 6c 75 65  e expected value
1840: 20 6f 66 20 74 68 65 20 50 43 61 63 68 65 2e 6e   of the PCache.n
1850: 50 69 6e 6e 65 64 0a 2a 2a 20 63 6f 75 6e 74 65  Pinned.** counte
1860: 72 2e 20 54 68 69 73 20 69 73 20 6f 6e 6c 79 20  r. This is only 
1870: 75 73 65 64 20 69 6e 20 64 65 62 75 67 67 69 6e  used in debuggin
1880: 67 20 62 75 69 6c 64 73 2c 20 61 73 20 66 6f 6c  g builds, as fol
1890: 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 65 78  lows:.**.**   ex
18a0: 70 65 6e 73 69 76 65 5f 61 73 73 65 72 74 28 20  pensive_assert( 
18b0: 70 43 61 63 68 65 2d 3e 6e 50 69 6e 6e 65 64 3d  pCache->nPinned=
18c0: 3d 70 63 61 63 68 65 50 69 6e 6e 65 64 43 6f 75  =pcachePinnedCou
18d0: 6e 74 28 70 43 61 63 68 65 29 20 29 3b 0a 2a 2f  nt(pCache) );.*/
18e0: 0a 73 74 61 74 69 63 20 69 6e 74 20 70 63 61 63  .static int pcac
18f0: 68 65 50 69 6e 6e 65 64 43 6f 75 6e 74 28 50 43  hePinnedCount(PC
1900: 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b 0a 20  ache *pCache){. 
1910: 20 50 67 48 64 72 20 2a 70 3b 0a 20 20 69 6e 74   PgHdr *p;.  int
1920: 20 6e 50 69 6e 6e 65 64 20 3d 20 70 43 61 63 68   nPinned = pCach
1930: 65 2d 3e 6e 52 65 66 3b 0a 20 20 66 6f 72 28 70  e->nRef;.  for(p
1940: 3d 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 3b  =pCache->pDirty;
1950: 20 70 3b 20 70 3d 70 2d 3e 70 4e 65 78 74 29 7b   p; p=p->pNext){
1960: 0a 20 20 20 20 69 66 28 20 70 2d 3e 6e 52 65 66  .    if( p->nRef
1970: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 6e 50 69  ==0 ){.      nPi
1980: 6e 6e 65 64 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20  nned++;.    }.  
1990: 7d 0a 20 20 72 65 74 75 72 6e 20 6e 50 69 6e 6e  }.  return nPinn
19a0: 65 64 3b 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a 20  ed;.}.#endif /* 
19b0: 21 4e 44 45 42 55 47 20 26 26 20 53 51 4c 49 54  !NDEBUG && SQLIT
19c0: 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49  E_ENABLE_EXPENSI
19d0: 56 45 5f 41 53 53 45 52 54 20 2a 2f 0a 0a 0a 23  VE_ASSERT */...#
19e0: 69 66 20 21 64 65 66 69 6e 65 64 28 4e 44 45 42  if !defined(NDEB
19f0: 55 47 29 20 26 26 20 64 65 66 69 6e 65 64 28 53  UG) && defined(S
1a00: 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 45 58 50  QLITE_ENABLE_EXP
1a10: 45 4e 53 49 56 45 5f 41 53 53 45 52 54 29 0a 2f  ENSIVE_ASSERT)./
1a20: 2a 0a 2a 2a 20 43 68 65 63 6b 20 74 68 61 74 20  *.** Check that 
1a30: 74 68 65 20 70 43 61 63 68 65 2d 3e 70 53 79 6e  the pCache->pSyn
1a40: 63 65 64 20 76 61 72 69 61 62 6c 65 20 69 73 20  ced variable is 
1a50: 73 65 74 20 63 6f 72 72 65 63 74 6c 79 2e 20 49  set correctly. I
1a60: 66 20 69 74 0a 2a 2a 20 69 73 20 6e 6f 74 2c 20  f it.** is not, 
1a70: 65 69 74 68 65 72 20 66 61 69 6c 20 61 6e 20 61  either fail an a
1a80: 73 73 65 72 74 20 6f 72 20 72 65 74 75 72 6e 20  ssert or return 
1a90: 7a 65 72 6f 2e 20 4f 74 68 65 72 77 69 73 65 2c  zero. Otherwise,
1aa0: 20 72 65 74 75 72 6e 0a 2a 2a 20 6e 6f 6e 2d 7a   return.** non-z
1ab0: 65 72 6f 2e 20 54 68 69 73 20 69 73 20 6f 6e 6c  ero. This is onl
1ac0: 79 20 75 73 65 64 20 69 6e 20 64 65 62 75 67 67  y used in debugg
1ad0: 69 6e 67 20 62 75 69 6c 64 73 2c 20 61 73 20 66  ing builds, as f
1ae0: 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 20 20  ollows:.**.**   
1af0: 65 78 70 65 6e 73 69 76 65 5f 61 73 73 65 72 74  expensive_assert
1b00: 28 20 70 63 61 63 68 65 43 68 65 63 6b 53 79 6e  ( pcacheCheckSyn
1b10: 63 65 64 28 70 43 61 63 68 65 29 20 29 3b 0a 2a  ced(pCache) );.*
1b20: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 70 63 61  /.static int pca
1b30: 63 68 65 43 68 65 63 6b 53 79 6e 63 65 64 28 50  cheCheckSynced(P
1b40: 43 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b 0a  Cache *pCache){.
1b50: 20 20 50 67 48 64 72 20 2a 70 20 3d 20 70 43 61    PgHdr *p = pCa
1b60: 63 68 65 2d 3e 70 44 69 72 74 79 54 61 69 6c 3b  che->pDirtyTail;
1b70: 0a 20 20 66 6f 72 28 70 3d 70 43 61 63 68 65 2d  .  for(p=pCache-
1b80: 3e 70 44 69 72 74 79 54 61 69 6c 3b 20 70 21 3d  >pDirtyTail; p!=
1b90: 70 43 61 63 68 65 2d 3e 70 53 79 6e 63 65 64 3b  pCache->pSynced;
1ba0: 20 70 3d 70 2d 3e 70 50 72 65 76 29 7b 0a 20 20   p=p->pPrev){.  
1bb0: 20 20 61 73 73 65 72 74 28 20 70 2d 3e 6e 52 65    assert( p->nRe
1bc0: 66 20 7c 7c 20 28 70 2d 3e 66 6c 61 67 73 26 50  f || (p->flags&P
1bd0: 47 48 44 52 5f 4e 45 45 44 5f 53 59 4e 43 29 20  GHDR_NEED_SYNC) 
1be0: 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  );.  }.  return 
1bf0: 28 70 3d 3d 30 20 7c 7c 20 70 2d 3e 6e 52 65 66  (p==0 || p->nRef
1c00: 20 7c 7c 20 28 70 2d 3e 66 6c 61 67 73 26 50 47   || (p->flags&PG
1c10: 48 44 52 5f 4e 45 45 44 5f 53 59 4e 43 29 3d 3d  HDR_NEED_SYNC)==
1c20: 30 29 3b 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a 20  0);.}.#endif /* 
1c30: 21 4e 44 45 42 55 47 20 26 26 20 53 51 4c 49 54  !NDEBUG && SQLIT
1c40: 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49  E_ENABLE_EXPENSI
1c50: 56 45 5f 41 53 53 45 52 54 20 2a 2f 0a 0a 0a 0a  VE_ASSERT */....
1c60: 2f 2a 0a 2a 2a 20 52 65 6d 6f 76 65 20 61 20 70  /*.** Remove a p
1c70: 61 67 65 20 66 72 6f 6d 20 69 74 73 20 68 61 73  age from its has
1c80: 68 20 74 61 62 6c 65 20 28 50 43 61 63 68 65 2e  h table (PCache.
1c90: 61 70 48 61 73 68 5b 5d 29 2e 0a 2a 2f 0a 73 74  apHash[])..*/.st
1ca0: 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65  atic void pcache
1cb0: 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73 68 28 50  RemoveFromHash(P
1cc0: 67 48 64 72 20 2a 70 50 61 67 65 29 7b 0a 20 20  gHdr *pPage){.  
1cd0: 61 73 73 65 72 74 28 20 70 63 61 63 68 65 4d 75  assert( pcacheMu
1ce0: 74 65 78 48 65 6c 64 28 29 20 29 3b 0a 20 20 69  texHeld() );.  i
1cf0: 66 28 20 70 50 61 67 65 2d 3e 70 50 72 65 76 48  f( pPage->pPrevH
1d00: 61 73 68 20 29 7b 0a 20 20 20 20 70 50 61 67 65  ash ){.    pPage
1d10: 2d 3e 70 50 72 65 76 48 61 73 68 2d 3e 70 4e 65  ->pPrevHash->pNe
1d20: 78 74 48 61 73 68 20 3d 20 70 50 61 67 65 2d 3e  xtHash = pPage->
1d30: 70 4e 65 78 74 48 61 73 68 3b 0a 20 20 7d 65 6c  pNextHash;.  }el
1d40: 73 65 7b 0a 20 20 20 20 50 43 61 63 68 65 20 2a  se{.    PCache *
1d50: 70 43 61 63 68 65 20 3d 20 70 50 61 67 65 2d 3e  pCache = pPage->
1d60: 70 43 61 63 68 65 3b 0a 20 20 20 20 75 33 32 20  pCache;.    u32 
1d70: 68 20 3d 20 70 50 61 67 65 2d 3e 70 67 6e 6f 20  h = pPage->pgno 
1d80: 25 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3b  % pCache->nHash;
1d90: 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 43 61  .    assert( pCa
1da0: 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3d 3d  che->apHash[h]==
1db0: 70 50 61 67 65 20 29 3b 0a 20 20 20 20 70 43 61  pPage );.    pCa
1dc0: 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 20 3d  che->apHash[h] =
1dd0: 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 48 61 73   pPage->pNextHas
1de0: 68 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 50 61  h;.  }.  if( pPa
1df0: 67 65 2d 3e 70 4e 65 78 74 48 61 73 68 20 29 7b  ge->pNextHash ){
1e00: 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 4e 65 78  .    pPage->pNex
1e10: 74 48 61 73 68 2d 3e 70 50 72 65 76 48 61 73 68  tHash->pPrevHash
1e20: 20 3d 20 70 50 61 67 65 2d 3e 70 50 72 65 76 48   = pPage->pPrevH
1e30: 61 73 68 3b 0a 20 20 7d 0a 20 20 70 50 61 67 65  ash;.  }.  pPage
1e40: 2d 3e 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 2d  ->pCache->nPage-
1e50: 2d 3b 0a 20 20 65 78 70 65 6e 73 69 76 65 5f 61  -;.  expensive_a
1e60: 73 73 65 72 74 28 20 70 63 61 63 68 65 43 68 65  ssert( pcacheChe
1e70: 63 6b 48 61 73 68 43 6f 75 6e 74 28 70 50 61 67  ckHashCount(pPag
1e80: 65 2d 3e 70 43 61 63 68 65 29 20 29 3b 0a 7d 0a  e->pCache) );.}.
1e90: 0a 2f 2a 0a 2a 2a 20 49 6e 73 65 72 74 20 61 20  ./*.** Insert a 
1ea0: 70 61 67 65 20 69 6e 74 6f 20 74 68 65 20 68 61  page into the ha
1eb0: 73 68 20 74 61 62 6c 65 0a 2a 2a 0a 2a 2a 20 54  sh table.**.** T
1ec0: 68 65 20 6d 75 74 65 78 20 6d 75 73 74 20 62 65  he mutex must be
1ed0: 20 68 65 6c 64 20 62 79 20 74 68 65 20 63 61 6c   held by the cal
1ee0: 6c 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ler..*/.static v
1ef0: 6f 69 64 20 70 63 61 63 68 65 41 64 64 54 6f 48  oid pcacheAddToH
1f00: 61 73 68 28 50 67 48 64 72 20 2a 70 50 61 67 65  ash(PgHdr *pPage
1f10: 29 7b 0a 20 20 50 43 61 63 68 65 20 2a 70 43 61  ){.  PCache *pCa
1f20: 63 68 65 20 3d 20 70 50 61 67 65 2d 3e 70 43 61  che = pPage->pCa
1f30: 63 68 65 3b 0a 20 20 75 33 32 20 68 20 3d 20 70  che;.  u32 h = p
1f40: 50 61 67 65 2d 3e 70 67 6e 6f 20 25 20 70 43 61  Page->pgno % pCa
1f50: 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 61 73  che->nHash;.  as
1f60: 73 65 72 74 28 20 70 63 61 63 68 65 4d 75 74 65  sert( pcacheMute
1f70: 78 48 65 6c 64 28 29 20 29 3b 0a 20 20 70 50 61  xHeld() );.  pPa
1f80: 67 65 2d 3e 70 4e 65 78 74 48 61 73 68 20 3d 20  ge->pNextHash = 
1f90: 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68  pCache->apHash[h
1fa0: 5d 3b 0a 20 20 70 50 61 67 65 2d 3e 70 50 72 65  ];.  pPage->pPre
1fb0: 76 48 61 73 68 20 3d 20 30 3b 0a 20 20 69 66 28  vHash = 0;.  if(
1fc0: 20 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b   pCache->apHash[
1fd0: 68 5d 20 29 7b 0a 20 20 20 20 70 43 61 63 68 65  h] ){.    pCache
1fe0: 2d 3e 61 70 48 61 73 68 5b 68 5d 2d 3e 70 50 72  ->apHash[h]->pPr
1ff0: 65 76 48 61 73 68 20 3d 20 70 50 61 67 65 3b 0a  evHash = pPage;.
2000: 20 20 7d 0a 20 20 70 43 61 63 68 65 2d 3e 61 70    }.  pCache->ap
2010: 48 61 73 68 5b 68 5d 20 3d 20 70 50 61 67 65 3b  Hash[h] = pPage;
2020: 0a 20 20 70 43 61 63 68 65 2d 3e 6e 50 61 67 65  .  pCache->nPage
2030: 2b 2b 3b 0a 20 20 65 78 70 65 6e 73 69 76 65 5f  ++;.  expensive_
2040: 61 73 73 65 72 74 28 20 70 63 61 63 68 65 43 68  assert( pcacheCh
2050: 65 63 6b 48 61 73 68 43 6f 75 6e 74 28 70 43 61  eckHashCount(pCa
2060: 63 68 65 29 20 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  che) );.}../*.**
2070: 20 41 74 74 65 6d 70 74 20 74 6f 20 69 6e 63 72   Attempt to incr
2080: 65 61 73 65 20 74 68 65 20 73 69 7a 65 20 74 68  ease the size th
2090: 65 20 68 61 73 68 20 74 61 62 6c 65 20 74 6f 20  e hash table to 
20a0: 63 6f 6e 74 61 69 6e 0a 2a 2a 20 61 74 20 6c 65  contain.** at le
20b0: 61 73 74 20 6e 48 61 73 68 20 62 75 63 6b 65 74  ast nHash bucket
20c0: 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  s..*/.static int
20d0: 20 70 63 61 63 68 65 52 65 73 69 7a 65 48 61 73   pcacheResizeHas
20e0: 68 28 50 43 61 63 68 65 20 2a 70 43 61 63 68 65  h(PCache *pCache
20f0: 2c 20 69 6e 74 20 6e 48 61 73 68 29 7b 0a 20 20  , int nHash){.  
2100: 50 67 48 64 72 20 2a 70 3b 0a 20 20 50 67 48 64  PgHdr *p;.  PgHd
2110: 72 20 2a 2a 70 4e 65 77 3b 0a 20 20 61 73 73 65  r **pNew;.  asse
2120: 72 74 28 20 70 63 61 63 68 65 4d 75 74 65 78 48  rt( pcacheMutexH
2130: 65 6c 64 28 29 20 29 3b 0a 23 69 66 64 65 66 20  eld() );.#ifdef 
2140: 53 51 4c 49 54 45 5f 4d 41 4c 4c 4f 43 5f 53 4f  SQLITE_MALLOC_SO
2150: 46 54 5f 4c 49 4d 49 54 0a 20 20 69 66 28 20 6e  FT_LIMIT.  if( n
2160: 48 61 73 68 2a 73 69 7a 65 6f 66 28 50 67 48 64  Hash*sizeof(PgHd
2170: 72 2a 29 3e 53 51 4c 49 54 45 5f 4d 41 4c 4c 4f  r*)>SQLITE_MALLO
2180: 43 5f 53 4f 46 54 5f 4c 49 4d 49 54 20 29 7b 0a  C_SOFT_LIMIT ){.
2190: 20 20 20 20 6e 48 61 73 68 20 3d 20 53 51 4c 49      nHash = SQLI
21a0: 54 45 5f 4d 41 4c 4c 4f 43 5f 53 4f 46 54 5f 4c  TE_MALLOC_SOFT_L
21b0: 49 4d 49 54 2f 73 69 7a 65 6f 66 28 50 67 48 64  IMIT/sizeof(PgHd
21c0: 72 20 2a 29 3b 0a 20 20 7d 0a 23 65 6e 64 69 66  r *);.  }.#endif
21d0: 0a 20 20 70 63 61 63 68 65 45 78 69 74 4d 75 74  .  pcacheExitMut
21e0: 65 78 28 29 3b 0a 20 20 70 4e 65 77 20 3d 20 28  ex();.  pNew = (
21f0: 50 67 48 64 72 20 2a 2a 29 73 71 6c 69 74 65 33  PgHdr **)sqlite3
2200: 4d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 50 67  Malloc(sizeof(Pg
2210: 48 64 72 2a 29 2a 6e 48 61 73 68 29 3b 0a 20 20  Hdr*)*nHash);.  
2220: 70 63 61 63 68 65 45 6e 74 65 72 4d 75 74 65 78  pcacheEnterMutex
2230: 28 29 3b 0a 20 20 69 66 28 20 21 70 4e 65 77 20  ();.  if( !pNew 
2240: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51  ){.    return SQ
2250: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a  LITE_NOMEM;.  }.
2260: 20 20 6d 65 6d 73 65 74 28 70 4e 65 77 2c 20 30    memset(pNew, 0
2270: 2c 20 73 69 7a 65 6f 66 28 50 67 48 64 72 20 2a  , sizeof(PgHdr *
2280: 29 2a 6e 48 61 73 68 29 3b 0a 20 20 73 71 6c 69  )*nHash);.  sqli
2290: 74 65 33 5f 66 72 65 65 28 70 43 61 63 68 65 2d  te3_free(pCache-
22a0: 3e 61 70 48 61 73 68 29 3b 0a 20 20 70 43 61 63  >apHash);.  pCac
22b0: 68 65 2d 3e 61 70 48 61 73 68 20 3d 20 70 4e 65  he->apHash = pNe
22c0: 77 3b 0a 20 20 70 43 61 63 68 65 2d 3e 6e 48 61  w;.  pCache->nHa
22d0: 73 68 20 3d 20 6e 48 61 73 68 3b 0a 20 20 70 43  sh = nHash;.  pC
22e0: 61 63 68 65 2d 3e 6e 50 61 67 65 20 3d 20 30 3b  ache->nPage = 0;
22f0: 0a 20 0a 20 20 66 6f 72 28 70 3d 70 43 61 63 68  . .  for(p=pCach
2300: 65 2d 3e 70 43 6c 65 61 6e 3b 20 70 3b 20 70 3d  e->pClean; p; p=
2310: 70 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 70  p->pNext){.    p
2320: 63 61 63 68 65 41 64 64 54 6f 48 61 73 68 28 70  cacheAddToHash(p
2330: 29 3b 0a 20 20 7d 0a 20 20 66 6f 72 28 70 3d 70  );.  }.  for(p=p
2340: 43 61 63 68 65 2d 3e 70 44 69 72 74 79 3b 20 70  Cache->pDirty; p
2350: 3b 20 70 3d 70 2d 3e 70 4e 65 78 74 29 7b 0a 20  ; p=p->pNext){. 
2360: 20 20 20 70 63 61 63 68 65 41 64 64 54 6f 48 61     pcacheAddToHa
2370: 73 68 28 70 29 3b 0a 20 20 7d 0a 20 20 72 65 74  sh(p);.  }.  ret
2380: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
2390: 0a 0a 2f 2a 0a 2a 2a 20 52 65 6d 6f 76 65 20 61  ../*.** Remove a
23a0: 20 70 61 67 65 20 66 72 6f 6d 20 61 20 6c 69 6e   page from a lin
23b0: 6b 65 64 20 6c 69 73 74 20 74 68 61 74 20 69 73  ked list that is
23c0: 20 68 65 61 64 65 64 20 62 79 20 2a 70 70 48 65   headed by *ppHe
23d0: 61 64 2e 0a 2a 2a 20 2a 70 70 48 65 61 64 20 69  ad..** *ppHead i
23e0: 73 20 65 69 74 68 65 72 20 50 43 61 63 68 65 2e  s either PCache.
23f0: 70 43 6c 65 61 6e 20 6f 72 20 50 43 61 63 68 65  pClean or PCache
2400: 2e 70 44 69 72 74 79 2e 0a 2a 2f 0a 73 74 61 74  .pDirty..*/.stat
2410: 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 52 65  ic void pcacheRe
2420: 6d 6f 76 65 46 72 6f 6d 4c 69 73 74 28 50 67 48  moveFromList(PgH
2430: 64 72 20 2a 2a 70 70 48 65 61 64 2c 20 50 67 48  dr **ppHead, PgH
2440: 64 72 20 2a 70 50 61 67 65 29 7b 0a 20 20 69 6e  dr *pPage){.  in
2450: 74 20 69 73 44 69 72 74 79 4c 69 73 74 20 3d 20  t isDirtyList = 
2460: 28 70 70 48 65 61 64 3d 3d 26 70 50 61 67 65 2d  (ppHead==&pPage-
2470: 3e 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 29  >pCache->pDirty)
2480: 3b 0a 20 20 61 73 73 65 72 74 28 20 70 70 48 65  ;.  assert( ppHe
2490: 61 64 3d 3d 26 70 50 61 67 65 2d 3e 70 43 61 63  ad==&pPage->pCac
24a0: 68 65 2d 3e 70 43 6c 65 61 6e 20 7c 7c 20 70 70  he->pClean || pp
24b0: 48 65 61 64 3d 3d 26 70 50 61 67 65 2d 3e 70 43  Head==&pPage->pC
24c0: 61 63 68 65 2d 3e 70 44 69 72 74 79 20 29 3b 0a  ache->pDirty );.
24d0: 20 20 61 73 73 65 72 74 28 20 70 63 61 63 68 65    assert( pcache
24e0: 4d 75 74 65 78 48 65 6c 64 28 29 20 7c 7c 20 70  MutexHeld() || p
24f0: 70 48 65 61 64 21 3d 26 70 50 61 67 65 2d 3e 70  pHead!=&pPage->p
2500: 43 61 63 68 65 2d 3e 70 43 6c 65 61 6e 20 29 3b  Cache->pClean );
2510: 0a 0a 20 20 69 66 28 20 70 50 61 67 65 2d 3e 70  ..  if( pPage->p
2520: 50 72 65 76 20 29 7b 0a 20 20 20 20 70 50 61 67  Prev ){.    pPag
2530: 65 2d 3e 70 50 72 65 76 2d 3e 70 4e 65 78 74 20  e->pPrev->pNext 
2540: 3d 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 3b 0a  = pPage->pNext;.
2550: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 61 73 73    }else{.    ass
2560: 65 72 74 28 20 2a 70 70 48 65 61 64 3d 3d 70 50  ert( *ppHead==pP
2570: 61 67 65 20 29 3b 0a 20 20 20 20 2a 70 70 48 65  age );.    *ppHe
2580: 61 64 20 3d 20 70 50 61 67 65 2d 3e 70 4e 65 78  ad = pPage->pNex
2590: 74 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 50 61  t;.  }.  if( pPa
25a0: 67 65 2d 3e 70 4e 65 78 74 20 29 7b 0a 20 20 20  ge->pNext ){.   
25b0: 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 2d 3e 70   pPage->pNext->p
25c0: 50 72 65 76 20 3d 20 70 50 61 67 65 2d 3e 70 50  Prev = pPage->pP
25d0: 72 65 76 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20  rev;.  }..  if( 
25e0: 69 73 44 69 72 74 79 4c 69 73 74 20 29 7b 0a 20  isDirtyList ){. 
25f0: 20 20 20 50 43 61 63 68 65 20 2a 70 43 61 63 68     PCache *pCach
2600: 65 20 3d 20 70 50 61 67 65 2d 3e 70 43 61 63 68  e = pPage->pCach
2610: 65 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70  e;.    assert( p
2620: 50 61 67 65 2d 3e 70 4e 65 78 74 20 7c 7c 20 70  Page->pNext || p
2630: 43 61 63 68 65 2d 3e 70 44 69 72 74 79 54 61 69  Cache->pDirtyTai
2640: 6c 3d 3d 70 50 61 67 65 20 29 3b 0a 20 20 20 20  l==pPage );.    
2650: 69 66 28 20 21 70 50 61 67 65 2d 3e 70 4e 65 78  if( !pPage->pNex
2660: 74 20 29 7b 0a 20 20 20 20 20 20 70 43 61 63 68  t ){.      pCach
2670: 65 2d 3e 70 44 69 72 74 79 54 61 69 6c 20 3d 20  e->pDirtyTail = 
2680: 70 50 61 67 65 2d 3e 70 50 72 65 76 3b 0a 20 20  pPage->pPrev;.  
2690: 20 20 7d 0a 20 20 20 20 69 66 28 20 70 43 61 63    }.    if( pCac
26a0: 68 65 2d 3e 70 53 79 6e 63 65 64 3d 3d 70 50 61  he->pSynced==pPa
26b0: 67 65 20 29 7b 0a 20 20 20 20 20 20 50 67 48 64  ge ){.      PgHd
26c0: 72 20 2a 70 53 79 6e 63 65 64 20 3d 20 70 50 61  r *pSynced = pPa
26d0: 67 65 2d 3e 70 50 72 65 76 3b 0a 20 20 20 20 20  ge->pPrev;.     
26e0: 20 77 68 69 6c 65 28 20 70 53 79 6e 63 65 64 20   while( pSynced 
26f0: 26 26 20 28 70 53 79 6e 63 65 64 2d 3e 66 6c 61  && (pSynced->fla
2700: 67 73 26 50 47 48 44 52 5f 4e 45 45 44 5f 53 59  gs&PGHDR_NEED_SY
2710: 4e 43 29 20 29 7b 0a 20 20 20 20 20 20 20 20 70  NC) ){.        p
2720: 53 79 6e 63 65 64 20 3d 20 70 53 79 6e 63 65 64  Synced = pSynced
2730: 2d 3e 70 50 72 65 76 3b 0a 20 20 20 20 20 20 7d  ->pPrev;.      }
2740: 0a 20 20 20 20 20 20 70 43 61 63 68 65 2d 3e 70  .      pCache->p
2750: 53 79 6e 63 65 64 20 3d 20 70 53 79 6e 63 65 64  Synced = pSynced
2760: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f  ;.    }.  }.}../
2770: 2a 0a 2a 2a 20 41 64 64 20 61 20 70 61 67 65 20  *.** Add a page 
2780: 66 72 6f 6d 20 61 20 6c 69 6e 6b 65 64 20 6c 69  from a linked li
2790: 73 74 20 74 68 61 74 20 69 73 20 68 65 61 64 65  st that is heade
27a0: 64 20 62 79 20 2a 70 70 48 65 61 64 2e 0a 2a 2a  d by *ppHead..**
27b0: 20 2a 70 70 48 65 61 64 20 69 73 20 65 69 74 68   *ppHead is eith
27c0: 65 72 20 50 43 61 63 68 65 2e 70 43 6c 65 61 6e  er PCache.pClean
27d0: 20 6f 72 20 50 43 61 63 68 65 2e 70 44 69 72 74   or PCache.pDirt
27e0: 79 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  y..*/.static voi
27f0: 64 20 70 63 61 63 68 65 41 64 64 54 6f 4c 69 73  d pcacheAddToLis
2800: 74 28 50 67 48 64 72 20 2a 2a 70 70 48 65 61 64  t(PgHdr **ppHead
2810: 2c 20 50 67 48 64 72 20 2a 70 50 61 67 65 29 7b  , PgHdr *pPage){
2820: 0a 20 20 69 6e 74 20 69 73 44 69 72 74 79 4c 69  .  int isDirtyLi
2830: 73 74 20 3d 20 28 70 70 48 65 61 64 3d 3d 26 70  st = (ppHead==&p
2840: 50 61 67 65 2d 3e 70 43 61 63 68 65 2d 3e 70 44  Page->pCache->pD
2850: 69 72 74 79 29 3b 0a 20 20 61 73 73 65 72 74 28  irty);.  assert(
2860: 20 70 70 48 65 61 64 3d 3d 26 70 50 61 67 65 2d   ppHead==&pPage-
2870: 3e 70 43 61 63 68 65 2d 3e 70 43 6c 65 61 6e 20  >pCache->pClean 
2880: 7c 7c 20 70 70 48 65 61 64 3d 3d 26 70 50 61 67  || ppHead==&pPag
2890: 65 2d 3e 70 43 61 63 68 65 2d 3e 70 44 69 72 74  e->pCache->pDirt
28a0: 79 20 29 3b 0a 0a 20 20 69 66 28 20 28 2a 70 70  y );..  if( (*pp
28b0: 48 65 61 64 29 20 29 7b 0a 20 20 20 20 28 2a 70  Head) ){.    (*p
28c0: 70 48 65 61 64 29 2d 3e 70 50 72 65 76 20 3d 20  pHead)->pPrev = 
28d0: 70 50 61 67 65 3b 0a 20 20 7d 0a 20 20 70 50 61  pPage;.  }.  pPa
28e0: 67 65 2d 3e 70 4e 65 78 74 20 3d 20 2a 70 70 48  ge->pNext = *ppH
28f0: 65 61 64 3b 0a 20 20 70 50 61 67 65 2d 3e 70 50  ead;.  pPage->pP
2900: 72 65 76 20 3d 20 30 3b 0a 20 20 2a 70 70 48 65  rev = 0;.  *ppHe
2910: 61 64 20 3d 20 70 50 61 67 65 3b 0a 0a 20 20 69  ad = pPage;..  i
2920: 66 28 20 69 73 44 69 72 74 79 4c 69 73 74 20 29  f( isDirtyList )
2930: 7b 0a 20 20 20 20 50 43 61 63 68 65 20 2a 70 43  {.    PCache *pC
2940: 61 63 68 65 20 3d 20 70 50 61 67 65 2d 3e 70 43  ache = pPage->pC
2950: 61 63 68 65 3b 0a 20 20 20 20 69 66 28 20 21 70  ache;.    if( !p
2960: 43 61 63 68 65 2d 3e 70 44 69 72 74 79 54 61 69  Cache->pDirtyTai
2970: 6c 20 29 7b 0a 20 20 20 20 20 20 61 73 73 65 72  l ){.      asser
2980: 74 28 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 3d  t( pPage->pNext=
2990: 3d 30 20 29 3b 0a 20 20 20 20 20 20 70 43 61 63  =0 );.      pCac
29a0: 68 65 2d 3e 70 44 69 72 74 79 54 61 69 6c 20 3d  he->pDirtyTail =
29b0: 20 70 50 61 67 65 3b 0a 20 20 20 20 7d 0a 20 20   pPage;.    }.  
29c0: 20 20 69 66 28 20 21 70 43 61 63 68 65 2d 3e 70    if( !pCache->p
29d0: 53 79 6e 63 65 64 20 26 26 20 30 3d 3d 28 70 50  Synced && 0==(pP
29e0: 61 67 65 2d 3e 66 6c 61 67 73 26 50 47 48 44 52  age->flags&PGHDR
29f0: 5f 4e 45 45 44 5f 53 59 4e 43 29 20 29 7b 0a 20  _NEED_SYNC) ){. 
2a00: 20 20 20 20 20 70 43 61 63 68 65 2d 3e 70 53 79       pCache->pSy
2a10: 6e 63 65 64 20 3d 20 70 50 61 67 65 3b 0a 20 20  nced = pPage;.  
2a20: 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a    }.  }.}../*.**
2a30: 20 52 65 6d 6f 76 65 20 61 20 70 61 67 65 20 66   Remove a page f
2a40: 72 6f 6d 20 74 68 65 20 67 6c 6f 62 61 6c 20 4c  rom the global L
2a50: 52 55 20 6c 69 73 74 0a 2a 2f 0a 73 74 61 74 69  RU list.*/.stati
2a60: 63 20 76 6f 69 64 20 70 63 61 63 68 65 52 65 6d  c void pcacheRem
2a70: 6f 76 65 46 72 6f 6d 4c 72 75 4c 69 73 74 28 50  oveFromLruList(P
2a80: 67 48 64 72 20 2a 70 50 61 67 65 29 7b 0a 20 20  gHdr *pPage){.  
2a90: 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f  assert( sqlite3_
2aa0: 6d 75 74 65 78 5f 68 65 6c 64 28 70 63 61 63 68  mutex_held(pcach
2ab0: 65 5f 67 2e 6d 75 74 65 78 29 20 29 3b 0a 20 20  e_g.mutex) );.  
2ac0: 61 73 73 65 72 74 28 20 28 70 50 61 67 65 2d 3e  assert( (pPage->
2ad0: 66 6c 61 67 73 26 50 47 48 44 52 5f 44 49 52 54  flags&PGHDR_DIRT
2ae0: 59 29 3d 3d 30 20 29 3b 0a 20 20 69 66 28 20 70  Y)==0 );.  if( p
2af0: 50 61 67 65 2d 3e 70 43 61 63 68 65 2d 3e 62 50  Page->pCache->bP
2b00: 75 72 67 65 61 62 6c 65 3d 3d 30 20 29 20 72 65  urgeable==0 ) re
2b10: 74 75 72 6e 3b 0a 20 20 69 66 28 20 70 50 61 67  turn;.  if( pPag
2b20: 65 2d 3e 70 4e 65 78 74 4c 72 75 20 29 7b 0a 20  e->pNextLru ){. 
2b30: 20 20 20 61 73 73 65 72 74 28 20 70 63 61 63 68     assert( pcach
2b40: 65 5f 67 2e 70 4c 72 75 54 61 69 6c 21 3d 70 50  e_g.pLruTail!=pP
2b50: 61 67 65 20 29 3b 0a 20 20 20 20 70 50 61 67 65  age );.    pPage
2b60: 2d 3e 70 4e 65 78 74 4c 72 75 2d 3e 70 50 72 65  ->pNextLru->pPre
2b70: 76 4c 72 75 20 3d 20 70 50 61 67 65 2d 3e 70 50  vLru = pPage->pP
2b80: 72 65 76 4c 72 75 3b 0a 20 20 7d 65 6c 73 65 7b  revLru;.  }else{
2b90: 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 63 61  .    assert( pca
2ba0: 63 68 65 5f 67 2e 70 4c 72 75 54 61 69 6c 3d 3d  che_g.pLruTail==
2bb0: 70 50 61 67 65 20 29 3b 0a 20 20 20 20 70 63 61  pPage );.    pca
2bc0: 63 68 65 5f 67 2e 70 4c 72 75 54 61 69 6c 20 3d  che_g.pLruTail =
2bd0: 20 70 50 61 67 65 2d 3e 70 50 72 65 76 4c 72 75   pPage->pPrevLru
2be0: 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 50 61 67  ;.  }.  if( pPag
2bf0: 65 2d 3e 70 50 72 65 76 4c 72 75 20 29 7b 0a 20  e->pPrevLru ){. 
2c00: 20 20 20 61 73 73 65 72 74 28 20 70 63 61 63 68     assert( pcach
2c10: 65 5f 67 2e 70 4c 72 75 48 65 61 64 21 3d 70 50  e_g.pLruHead!=pP
2c20: 61 67 65 20 29 3b 0a 20 20 20 20 70 50 61 67 65  age );.    pPage
2c30: 2d 3e 70 50 72 65 76 4c 72 75 2d 3e 70 4e 65 78  ->pPrevLru->pNex
2c40: 74 4c 72 75 20 3d 20 70 50 61 67 65 2d 3e 70 4e  tLru = pPage->pN
2c50: 65 78 74 4c 72 75 3b 0a 20 20 7d 65 6c 73 65 7b  extLru;.  }else{
2c60: 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 63 61  .    assert( pca
2c70: 63 68 65 5f 67 2e 70 4c 72 75 48 65 61 64 3d 3d  che_g.pLruHead==
2c80: 70 50 61 67 65 20 29 3b 0a 20 20 20 20 70 63 61  pPage );.    pca
2c90: 63 68 65 5f 67 2e 70 4c 72 75 48 65 61 64 20 3d  che_g.pLruHead =
2ca0: 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 4c 72 75   pPage->pNextLru
2cb0: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41  ;.  }.}../*.** A
2cc0: 64 64 20 61 20 70 61 67 65 20 74 6f 20 74 68 65  dd a page to the
2cd0: 20 67 6c 6f 62 61 6c 20 4c 52 55 20 6c 69 73 74   global LRU list
2ce0: 2e 20 20 54 68 65 20 70 61 67 65 20 69 73 20 6e  .  The page is n
2cf0: 6f 72 6d 61 6c 6c 79 20 61 64 64 65 64 0a 2a 2a  ormally added.**
2d00: 20 74 6f 20 74 68 65 20 66 72 6f 6e 74 20 6f 66   to the front of
2d10: 20 74 68 65 20 6c 69 73 74 20 73 6f 20 74 68 61   the list so tha
2d20: 74 20 69 74 20 77 69 6c 6c 20 62 65 20 74 68 65  t it will be the
2d30: 20 6c 61 73 74 20 70 61 67 65 20 72 65 63 79 63   last page recyc
2d40: 6c 65 64 2e 0a 2a 2a 20 48 6f 77 65 76 65 72 2c  led..** However,
2d50: 20 69 66 20 74 68 65 20 50 47 48 44 52 5f 52 45   if the PGHDR_RE
2d60: 55 53 45 5f 55 4e 4c 49 4b 45 4c 59 20 62 69 74  USE_UNLIKELY bit
2d70: 20 69 73 20 73 65 74 2c 20 74 68 65 20 70 61 67   is set, the pag
2d80: 65 20 69 73 20 61 64 64 65 64 0a 2a 2a 20 74 6f  e is added.** to
2d90: 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68 65 20   the end of the 
2da0: 4c 52 55 20 6c 69 73 74 20 73 6f 20 74 68 61 74  LRU list so that
2db0: 20 69 74 20 77 69 6c 6c 20 62 65 20 74 68 65 20   it will be the 
2dc0: 6e 65 78 74 20 74 6f 20 62 65 20 72 65 63 79 63  next to be recyc
2dd0: 6c 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  led..*/.static v
2de0: 6f 69 64 20 70 63 61 63 68 65 41 64 64 54 6f 4c  oid pcacheAddToL
2df0: 72 75 4c 69 73 74 28 50 67 48 64 72 20 2a 70 50  ruList(PgHdr *pP
2e00: 61 67 65 29 7b 0a 20 20 61 73 73 65 72 74 28 20  age){.  assert( 
2e10: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65  sqlite3_mutex_he
2e20: 6c 64 28 70 63 61 63 68 65 5f 67 2e 6d 75 74 65  ld(pcache_g.mute
2e30: 78 29 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  x) );.  assert( 
2e40: 28 70 50 61 67 65 2d 3e 66 6c 61 67 73 26 50 47  (pPage->flags&PG
2e50: 48 44 52 5f 44 49 52 54 59 29 3d 3d 30 20 29 3b  HDR_DIRTY)==0 );
2e60: 0a 20 20 69 66 28 20 70 50 61 67 65 2d 3e 70 43  .  if( pPage->pC
2e70: 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65  ache->bPurgeable
2e80: 3d 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a 20 20  ==0 ) return;.  
2e90: 69 66 28 20 70 63 61 63 68 65 5f 67 2e 70 4c 72  if( pcache_g.pLr
2ea0: 75 54 61 69 6c 20 26 26 20 28 70 50 61 67 65 2d  uTail && (pPage-
2eb0: 3e 66 6c 61 67 73 20 26 20 50 47 48 44 52 5f 52  >flags & PGHDR_R
2ec0: 45 55 53 45 5f 55 4e 4c 49 4b 45 4c 59 29 21 3d  EUSE_UNLIKELY)!=
2ed0: 30 20 29 7b 0a 20 20 20 20 2f 2a 20 49 66 20 72  0 ){.    /* If r
2ee0: 65 75 73 65 20 69 73 20 75 6e 6c 69 6b 65 6c 79  euse is unlikely
2ef0: 2e 20 20 50 75 74 20 74 68 65 20 70 61 67 65 20  .  Put the page 
2f00: 61 74 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68  at the end of th
2f10: 65 20 4c 52 55 20 6c 69 73 74 0a 20 20 20 20 2a  e LRU list.    *
2f20: 2a 20 77 68 65 72 65 20 69 74 20 77 69 6c 6c 20  * where it will 
2f30: 62 65 20 72 65 63 79 63 6c 65 64 20 73 6f 6f 6e  be recycled soon
2f40: 65 72 20 72 61 74 68 65 72 20 74 68 61 6e 20 6c  er rather than l
2f50: 61 74 65 72 2e 20 0a 20 20 20 20 2a 2f 0a 20 20  ater. .    */.  
2f60: 20 20 61 73 73 65 72 74 28 20 70 63 61 63 68 65    assert( pcache
2f70: 5f 67 2e 70 4c 72 75 48 65 61 64 20 29 3b 0a 20  _g.pLruHead );. 
2f80: 20 20 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 4c     pPage->pNextL
2f90: 72 75 20 3d 20 30 3b 0a 20 20 20 20 70 50 61 67  ru = 0;.    pPag
2fa0: 65 2d 3e 70 50 72 65 76 4c 72 75 20 3d 20 70 63  e->pPrevLru = pc
2fb0: 61 63 68 65 5f 67 2e 70 4c 72 75 54 61 69 6c 3b  ache_g.pLruTail;
2fc0: 0a 20 20 20 20 70 63 61 63 68 65 5f 67 2e 70 4c  .    pcache_g.pL
2fd0: 72 75 54 61 69 6c 2d 3e 70 4e 65 78 74 4c 72 75  ruTail->pNextLru
2fe0: 20 3d 20 70 50 61 67 65 3b 0a 20 20 20 20 70 63   = pPage;.    pc
2ff0: 61 63 68 65 5f 67 2e 70 4c 72 75 54 61 69 6c 20  ache_g.pLruTail 
3000: 3d 20 70 50 61 67 65 3b 0a 20 20 20 20 70 50 61  = pPage;.    pPa
3010: 67 65 2d 3e 66 6c 61 67 73 20 26 3d 20 7e 50 47  ge->flags &= ~PG
3020: 48 44 52 5f 52 45 55 53 45 5f 55 4e 4c 49 4b 45  HDR_REUSE_UNLIKE
3030: 4c 59 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  LY;.  }else{.   
3040: 20 2f 2a 20 49 66 20 72 65 75 73 65 20 69 73 20   /* If reuse is 
3050: 70 6f 73 73 69 62 6c 65 2e 20 74 68 65 20 70 61  possible. the pa
3060: 67 65 20 67 6f 65 73 20 61 74 20 74 68 65 20 62  ge goes at the b
3070: 65 67 69 6e 6e 69 6e 67 20 6f 66 20 74 68 65 20  eginning of the 
3080: 4c 52 55 0a 20 20 20 20 2a 2a 20 6c 69 73 74 20  LRU.    ** list 
3090: 73 6f 20 74 68 61 74 20 69 74 20 77 69 6c 6c 20  so that it will 
30a0: 62 65 20 74 68 65 20 6c 61 73 74 20 74 6f 20 62  be the last to b
30b0: 65 20 72 65 63 79 63 6c 65 64 2e 0a 20 20 20 20  e recycled..    
30c0: 2a 2f 0a 20 20 20 20 69 66 28 20 70 63 61 63 68  */.    if( pcach
30d0: 65 5f 67 2e 70 4c 72 75 48 65 61 64 20 29 7b 0a  e_g.pLruHead ){.
30e0: 20 20 20 20 20 20 70 63 61 63 68 65 5f 67 2e 70        pcache_g.p
30f0: 4c 72 75 48 65 61 64 2d 3e 70 50 72 65 76 4c 72  LruHead->pPrevLr
3100: 75 20 3d 20 70 50 61 67 65 3b 0a 20 20 20 20 7d  u = pPage;.    }
3110: 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 4e 65 78  .    pPage->pNex
3120: 74 4c 72 75 20 3d 20 70 63 61 63 68 65 5f 67 2e  tLru = pcache_g.
3130: 70 4c 72 75 48 65 61 64 3b 0a 20 20 20 20 70 63  pLruHead;.    pc
3140: 61 63 68 65 5f 67 2e 70 4c 72 75 48 65 61 64 20  ache_g.pLruHead 
3150: 3d 20 70 50 61 67 65 3b 0a 20 20 20 20 70 50 61  = pPage;.    pPa
3160: 67 65 2d 3e 70 50 72 65 76 4c 72 75 20 3d 20 30  ge->pPrevLru = 0
3170: 3b 0a 20 20 20 20 69 66 28 20 70 63 61 63 68 65  ;.    if( pcache
3180: 5f 67 2e 70 4c 72 75 54 61 69 6c 3d 3d 30 20 29  _g.pLruTail==0 )
3190: 7b 0a 20 20 20 20 20 20 70 63 61 63 68 65 5f 67  {.      pcache_g
31a0: 2e 70 4c 72 75 54 61 69 6c 20 3d 20 70 50 61 67  .pLruTail = pPag
31b0: 65 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a  e;.    }.  }.}..
31c0: 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  /***************
31d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
31e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
31f0: 20 4d 65 6d 6f 72 79 20 41 6c 6c 6f 63 61 74 69   Memory Allocati
3200: 6f 6e 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 2a  on ***********.*
3210: 2a 0a 2a 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20  *.** Initialize 
3220: 74 68 65 20 70 61 67 65 20 63 61 63 68 65 20 6d  the page cache m
3230: 65 6d 6f 72 79 20 70 6f 6f 6c 2e 0a 2a 2a 0a 2a  emory pool..**.*
3240: 2a 20 54 68 69 73 20 6d 75 73 74 20 62 65 20 63  * This must be c
3250: 61 6c 6c 65 64 20 61 74 20 73 74 61 72 74 2d 74  alled at start-t
3260: 69 6d 65 20 77 68 65 6e 20 6e 6f 20 70 61 67 65  ime when no page
3270: 20 63 61 63 68 65 20 6c 69 6e 65 73 20 61 72 65   cache lines are
3280: 0a 2a 2a 20 63 68 65 63 6b 65 64 20 6f 75 74 2e  .** checked out.
3290: 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   This function i
32a0: 73 20 6e 6f 74 20 74 68 72 65 61 64 73 61 66 65  s not threadsafe
32b0: 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
32c0: 33 50 43 61 63 68 65 42 75 66 66 65 72 53 65 74  3PCacheBufferSet
32d0: 75 70 28 76 6f 69 64 20 2a 70 42 75 66 2c 20 69  up(void *pBuf, i
32e0: 6e 74 20 73 7a 2c 20 69 6e 74 20 6e 29 7b 0a 20  nt sz, int n){. 
32f0: 20 50 67 46 72 65 65 73 6c 6f 74 20 2a 70 3b 0a   PgFreeslot *p;.
3300: 20 20 73 7a 20 26 3d 20 7e 37 3b 0a 20 20 70 63    sz &= ~7;.  pc
3310: 61 63 68 65 5f 67 2e 73 7a 53 6c 6f 74 20 3d 20  ache_g.szSlot = 
3320: 73 7a 3b 0a 20 20 70 63 61 63 68 65 5f 67 2e 70  sz;.  pcache_g.p
3330: 53 74 61 72 74 20 3d 20 70 42 75 66 3b 0a 20 20  Start = pBuf;.  
3340: 70 63 61 63 68 65 5f 67 2e 70 46 72 65 65 20 3d  pcache_g.pFree =
3350: 20 30 3b 0a 20 20 77 68 69 6c 65 28 20 6e 2d 2d   0;.  while( n--
3360: 20 29 7b 0a 20 20 20 20 70 20 3d 20 28 50 67 46   ){.    p = (PgF
3370: 72 65 65 73 6c 6f 74 2a 29 70 42 75 66 3b 0a 20  reeslot*)pBuf;. 
3380: 20 20 20 70 2d 3e 70 4e 65 78 74 20 3d 20 70 63     p->pNext = pc
3390: 61 63 68 65 5f 67 2e 70 46 72 65 65 3b 0a 20 20  ache_g.pFree;.  
33a0: 20 20 70 63 61 63 68 65 5f 67 2e 70 46 72 65 65    pcache_g.pFree
33b0: 20 3d 20 70 3b 0a 20 20 20 20 70 42 75 66 20 3d   = p;.    pBuf =
33c0: 20 28 76 6f 69 64 2a 29 26 28 28 63 68 61 72 2a   (void*)&((char*
33d0: 29 70 42 75 66 29 5b 73 7a 5d 3b 0a 20 20 7d 0a  )pBuf)[sz];.  }.
33e0: 20 20 70 63 61 63 68 65 5f 67 2e 70 45 6e 64 20    pcache_g.pEnd 
33f0: 3d 20 70 42 75 66 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  = pBuf;.}../*.**
3400: 20 41 6c 6c 6f 63 61 74 65 20 61 20 70 61 67 65   Allocate a page
3410: 20 63 61 63 68 65 20 6c 69 6e 65 2e 20 20 4c 6f   cache line.  Lo
3420: 6f 6b 20 69 6e 20 74 68 65 20 70 61 67 65 20 63  ok in the page c
3430: 61 63 68 65 20 6d 65 6d 6f 72 79 20 70 6f 6f 6c  ache memory pool
3440: 20 66 69 72 73 74 0a 2a 2a 20 61 6e 64 20 75 73   first.** and us
3450: 65 20 61 6e 20 65 6c 65 6d 65 6e 74 20 66 72 6f  e an element fro
3460: 6d 20 69 74 20 66 69 72 73 74 20 69 66 20 61 76  m it first if av
3470: 61 69 6c 61 62 6c 65 2e 20 20 49 66 20 6e 6f 74  ailable.  If not
3480: 68 69 6e 67 20 69 73 20 61 76 61 69 6c 61 62 6c  hing is availabl
3490: 65 0a 2a 2a 20 69 6e 20 74 68 65 20 70 61 67 65  e.** in the page
34a0: 20 63 61 63 68 65 20 6d 65 6d 6f 72 79 20 70 6f   cache memory po
34b0: 6f 6c 2c 20 67 6f 20 74 6f 20 74 68 65 20 67 65  ol, go to the ge
34c0: 6e 65 72 61 6c 20 70 75 72 70 6f 73 65 20 6d 65  neral purpose me
34d0: 6d 6f 72 79 20 61 6c 6c 6f 63 61 74 6f 72 2e 0a  mory allocator..
34e0: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 2a  */.static void *
34f0: 70 63 61 63 68 65 4d 61 6c 6c 6f 63 28 69 6e 74  pcacheMalloc(int
3500: 20 73 7a 2c 20 50 43 61 63 68 65 20 2a 70 43 61   sz, PCache *pCa
3510: 63 68 65 29 7b 0a 20 20 61 73 73 65 72 74 28 20  che){.  assert( 
3520: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65  sqlite3_mutex_he
3530: 6c 64 28 70 63 61 63 68 65 5f 67 2e 6d 75 74 65  ld(pcache_g.mute
3540: 78 29 20 29 3b 0a 20 20 69 66 28 20 73 7a 3c 3d  x) );.  if( sz<=
3550: 70 63 61 63 68 65 5f 67 2e 73 7a 53 6c 6f 74 20  pcache_g.szSlot 
3560: 26 26 20 70 63 61 63 68 65 5f 67 2e 70 46 72 65  && pcache_g.pFre
3570: 65 20 29 7b 0a 20 20 20 20 50 67 46 72 65 65 73  e ){.    PgFrees
3580: 6c 6f 74 20 2a 70 20 3d 20 70 63 61 63 68 65 5f  lot *p = pcache_
3590: 67 2e 70 46 72 65 65 3b 0a 20 20 20 20 70 63 61  g.pFree;.    pca
35a0: 63 68 65 5f 67 2e 70 46 72 65 65 20 3d 20 70 2d  che_g.pFree = p-
35b0: 3e 70 4e 65 78 74 3b 0a 20 20 20 20 73 71 6c 69  >pNext;.    sqli
35c0: 74 65 33 53 74 61 74 75 73 53 65 74 28 53 51 4c  te3StatusSet(SQL
35d0: 49 54 45 5f 53 54 41 54 55 53 5f 50 41 47 45 43  ITE_STATUS_PAGEC
35e0: 41 43 48 45 5f 53 49 5a 45 2c 20 73 7a 29 3b 0a  ACHE_SIZE, sz);.
35f0: 20 20 20 20 73 71 6c 69 74 65 33 53 74 61 74 75      sqlite3Statu
3600: 73 41 64 64 28 53 51 4c 49 54 45 5f 53 54 41 54  sAdd(SQLITE_STAT
3610: 55 53 5f 50 41 47 45 43 41 43 48 45 5f 55 53 45  US_PAGECACHE_USE
3620: 44 2c 20 31 29 3b 0a 20 20 20 20 72 65 74 75 72  D, 1);.    retur
3630: 6e 20 28 76 6f 69 64 2a 29 70 3b 0a 20 20 7d 65  n (void*)p;.  }e
3640: 6c 73 65 7b 0a 20 20 20 20 76 6f 69 64 20 2a 70  lse{.    void *p
3650: 3b 0a 0a 20 20 20 20 2f 2a 20 41 6c 6c 6f 63 61  ;..    /* Alloca
3660: 74 65 20 61 20 6e 65 77 20 62 75 66 66 65 72 20  te a new buffer 
3670: 75 73 69 6e 67 20 73 71 6c 69 74 65 33 4d 61 6c  using sqlite3Mal
3680: 6c 6f 63 2e 20 42 65 66 6f 72 65 20 64 6f 69 6e  loc. Before doin
3690: 67 20 73 6f 2c 20 65 78 69 74 20 74 68 65 0a 20  g so, exit the. 
36a0: 20 20 20 2a 2a 20 67 6c 6f 62 61 6c 20 70 63 61     ** global pca
36b0: 63 68 65 20 6d 75 74 65 78 20 61 6e 64 20 75 6e  che mutex and un
36c0: 6c 6f 63 6b 20 74 68 65 20 70 61 67 65 72 2d 63  lock the pager-c
36d0: 61 63 68 65 20 6f 62 6a 65 63 74 20 70 43 61 63  ache object pCac
36e0: 68 65 2e 20 54 68 69 73 20 69 73 20 0a 20 20 20  he. This is .   
36f0: 20 2a 2a 20 73 6f 20 74 68 61 74 20 69 66 20 74   ** so that if t
3700: 68 65 20 61 74 74 65 6d 70 74 20 74 6f 20 61 6c  he attempt to al
3710: 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 62 75 66  locate a new buf
3720: 66 65 72 20 63 61 75 73 65 73 20 74 68 65 20 74  fer causes the t
3730: 68 65 20 0a 20 20 20 20 2a 2a 20 63 6f 6e 66 69  he .    ** confi
3740: 67 75 72 65 64 20 73 6f 66 74 2d 68 65 61 70 2d  gured soft-heap-
3750: 6c 69 6d 69 74 20 74 6f 20 62 65 20 62 72 65 61  limit to be brea
3760: 63 68 65 64 2c 20 69 74 20 77 69 6c 6c 20 62 65  ched, it will be
3770: 20 70 6f 73 73 69 62 6c 65 20 74 6f 0a 20 20 20   possible to.   
3780: 20 2a 2a 20 72 65 63 6c 61 69 6d 20 6d 65 6d 6f   ** reclaim memo
3790: 72 79 20 66 72 6f 6d 20 74 68 69 73 20 70 61 67  ry from this pag
37a0: 65 72 2d 63 61 63 68 65 2e 0a 20 20 20 20 2a 2f  er-cache..    */
37b0: 0a 20 20 20 20 70 63 61 63 68 65 45 78 69 74 4d  .    pcacheExitM
37c0: 75 74 65 78 28 29 3b 0a 20 20 20 20 70 20 3d 20  utex();.    p = 
37d0: 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 73 7a  sqlite3Malloc(sz
37e0: 29 3b 0a 20 20 20 20 70 63 61 63 68 65 45 6e 74  );.    pcacheEnt
37f0: 65 72 4d 75 74 65 78 28 29 3b 0a 0a 20 20 20 20  erMutex();..    
3800: 69 66 28 20 70 20 29 7b 0a 20 20 20 20 20 20 73  if( p ){.      s
3810: 7a 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f  z = sqlite3Mallo
3820: 63 53 69 7a 65 28 70 29 3b 0a 20 20 20 20 20 20  cSize(p);.      
3830: 73 71 6c 69 74 65 33 53 74 61 74 75 73 41 64 64  sqlite3StatusAdd
3840: 28 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50  (SQLITE_STATUS_P
3850: 41 47 45 43 41 43 48 45 5f 4f 56 45 52 46 4c 4f  AGECACHE_OVERFLO
3860: 57 2c 20 73 7a 29 3b 0a 20 20 20 20 7d 0a 20 20  W, sz);.    }.  
3870: 20 20 72 65 74 75 72 6e 20 70 3b 0a 20 20 7d 0a    return p;.  }.
3880: 7d 0a 76 6f 69 64 20 2a 73 71 6c 69 74 65 33 50  }.void *sqlite3P
3890: 61 67 65 4d 61 6c 6c 6f 63 28 69 6e 74 20 73 7a  ageMalloc(int sz
38a0: 29 7b 0a 20 20 76 6f 69 64 20 2a 70 3b 0a 20 20  ){.  void *p;.  
38b0: 70 63 61 63 68 65 45 6e 74 65 72 4d 75 74 65 78  pcacheEnterMutex
38c0: 28 29 3b 0a 20 20 70 20 3d 20 70 63 61 63 68 65  ();.  p = pcache
38d0: 4d 61 6c 6c 6f 63 28 73 7a 2c 20 30 29 3b 0a 20  Malloc(sz, 0);. 
38e0: 20 70 63 61 63 68 65 45 78 69 74 4d 75 74 65 78   pcacheExitMutex
38f0: 28 29 3b 0a 20 20 72 65 74 75 72 6e 20 70 3b 0a  ();.  return p;.
3900: 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 6c 65 61 73 65  }../*.** Release
3910: 20 61 20 70 61 67 65 72 20 6d 65 6d 6f 72 79 20   a pager memory 
3920: 61 6c 6c 6f 63 61 74 69 6f 6e 0a 2a 2f 0a 73 74  allocation.*/.st
3930: 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65  atic void pcache
3940: 46 72 65 65 28 76 6f 69 64 20 2a 70 29 7b 0a 20  Free(void *p){. 
3950: 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33   assert( sqlite3
3960: 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 63 61 63  _mutex_held(pcac
3970: 68 65 5f 67 2e 6d 75 74 65 78 29 20 29 3b 0a 20  he_g.mutex) );. 
3980: 20 69 66 28 20 70 3d 3d 30 20 29 20 72 65 74 75   if( p==0 ) retu
3990: 72 6e 3b 0a 20 20 69 66 28 20 70 3e 3d 70 63 61  rn;.  if( p>=pca
39a0: 63 68 65 5f 67 2e 70 53 74 61 72 74 20 26 26 20  che_g.pStart && 
39b0: 70 3c 70 63 61 63 68 65 5f 67 2e 70 45 6e 64 20  p<pcache_g.pEnd 
39c0: 29 7b 0a 20 20 20 20 50 67 46 72 65 65 73 6c 6f  ){.    PgFreeslo
39d0: 74 20 2a 70 53 6c 6f 74 3b 0a 20 20 20 20 73 71  t *pSlot;.    sq
39e0: 6c 69 74 65 33 53 74 61 74 75 73 41 64 64 28 53  lite3StatusAdd(S
39f0: 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41 47  QLITE_STATUS_PAG
3a00: 45 43 41 43 48 45 5f 55 53 45 44 2c 20 2d 31 29  ECACHE_USED, -1)
3a10: 3b 0a 20 20 20 20 70 53 6c 6f 74 20 3d 20 28 50  ;.    pSlot = (P
3a20: 67 46 72 65 65 73 6c 6f 74 2a 29 70 3b 0a 20 20  gFreeslot*)p;.  
3a30: 20 20 70 53 6c 6f 74 2d 3e 70 4e 65 78 74 20 3d    pSlot->pNext =
3a40: 20 70 63 61 63 68 65 5f 67 2e 70 46 72 65 65 3b   pcache_g.pFree;
3a50: 0a 20 20 20 20 70 63 61 63 68 65 5f 67 2e 70 46  .    pcache_g.pF
3a60: 72 65 65 20 3d 20 70 53 6c 6f 74 3b 0a 20 20 7d  ree = pSlot;.  }
3a70: 65 6c 73 65 7b 0a 20 20 20 20 69 6e 74 20 69 53  else{.    int iS
3a80: 69 7a 65 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c  ize = sqlite3Mal
3a90: 6c 6f 63 53 69 7a 65 28 70 29 3b 0a 20 20 20 20  locSize(p);.    
3aa0: 73 71 6c 69 74 65 33 53 74 61 74 75 73 41 64 64  sqlite3StatusAdd
3ab0: 28 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50  (SQLITE_STATUS_P
3ac0: 41 47 45 43 41 43 48 45 5f 4f 56 45 52 46 4c 4f  AGECACHE_OVERFLO
3ad0: 57 2c 20 2d 69 53 69 7a 65 29 3b 0a 20 20 20 20  W, -iSize);.    
3ae0: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 29 3b  sqlite3_free(p);
3af0: 0a 20 20 7d 0a 7d 0a 76 6f 69 64 20 73 71 6c 69  .  }.}.void sqli
3b00: 74 65 33 50 61 67 65 46 72 65 65 28 76 6f 69 64  te3PageFree(void
3b10: 20 2a 70 29 7b 0a 20 20 70 63 61 63 68 65 45 6e   *p){.  pcacheEn
3b20: 74 65 72 4d 75 74 65 78 28 29 3b 0a 20 20 70 63  terMutex();.  pc
3b30: 61 63 68 65 46 72 65 65 28 70 29 3b 0a 20 20 70  acheFree(p);.  p
3b40: 63 61 63 68 65 45 78 69 74 4d 75 74 65 78 28 29  cacheExitMutex()
3b50: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c 6f 63  ;.}../*.** Alloc
3b60: 61 74 65 20 61 20 6e 65 77 20 70 61 67 65 2e 0a  ate a new page..
3b70: 2a 2f 0a 73 74 61 74 69 63 20 50 67 48 64 72 20  */.static PgHdr 
3b80: 2a 70 63 61 63 68 65 50 61 67 65 41 6c 6c 6f 63  *pcachePageAlloc
3b90: 28 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 29  (PCache *pCache)
3ba0: 7b 0a 20 20 50 67 48 64 72 20 2a 70 3b 0a 20 20  {.  PgHdr *p;.  
3bb0: 69 6e 74 20 73 7a 20 3d 20 73 69 7a 65 6f 66 28  int sz = sizeof(
3bc0: 2a 70 29 20 2b 20 70 43 61 63 68 65 2d 3e 73 7a  *p) + pCache->sz
3bd0: 50 61 67 65 20 2b 20 70 43 61 63 68 65 2d 3e 73  Page + pCache->s
3be0: 7a 45 78 74 72 61 3b 0a 20 20 61 73 73 65 72 74  zExtra;.  assert
3bf0: 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f  ( sqlite3_mutex_
3c00: 68 65 6c 64 28 70 63 61 63 68 65 5f 67 2e 6d 75  held(pcache_g.mu
3c10: 74 65 78 29 20 29 3b 0a 20 20 70 20 3d 20 70 63  tex) );.  p = pc
3c20: 61 63 68 65 4d 61 6c 6c 6f 63 28 73 7a 2c 20 70  acheMalloc(sz, p
3c30: 43 61 63 68 65 29 3b 0a 20 20 69 66 28 20 70 3d  Cache);.  if( p=
3c40: 3d 30 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20  =0 ) return 0;. 
3c50: 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20 73 69   memset(p, 0, si
3c60: 7a 65 6f 66 28 50 67 48 64 72 29 29 3b 0a 20 20  zeof(PgHdr));.  
3c70: 70 2d 3e 70 44 61 74 61 20 3d 20 28 76 6f 69 64  p->pData = (void
3c80: 2a 29 26 70 5b 31 5d 3b 0a 20 20 70 2d 3e 70 45  *)&p[1];.  p->pE
3c90: 78 74 72 61 20 3d 20 28 76 6f 69 64 2a 29 26 28  xtra = (void*)&(
3ca0: 28 63 68 61 72 2a 29 70 2d 3e 70 44 61 74 61 29  (char*)p->pData)
3cb0: 5b 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 5d  [pCache->szPage]
3cc0: 3b 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e  ;.  if( pCache->
3cd0: 62 50 75 72 67 65 61 62 6c 65 20 29 7b 0a 20 20  bPurgeable ){.  
3ce0: 20 20 70 63 61 63 68 65 5f 67 2e 6e 43 75 72 72    pcache_g.nCurr
3cf0: 65 6e 74 50 61 67 65 2b 2b 3b 0a 20 20 7d 0a 20  entPage++;.  }. 
3d00: 20 72 65 74 75 72 6e 20 70 3b 0a 7d 0a 0a 2f 2a   return p;.}../*
3d10: 0a 2a 2a 20 44 65 61 6c 6c 6f 63 61 74 65 20 61  .** Deallocate a
3d20: 20 70 61 67 65 0a 2a 2f 0a 73 74 61 74 69 63 20   page.*/.static 
3d30: 76 6f 69 64 20 70 63 61 63 68 65 50 61 67 65 46  void pcachePageF
3d40: 72 65 65 28 50 67 48 64 72 20 2a 70 29 7b 0a 20  ree(PgHdr *p){. 
3d50: 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33   assert( sqlite3
3d60: 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 63 61 63  _mutex_held(pcac
3d70: 68 65 5f 67 2e 6d 75 74 65 78 29 20 29 3b 0a 20  he_g.mutex) );. 
3d80: 20 69 66 28 20 70 2d 3e 70 43 61 63 68 65 2d 3e   if( p->pCache->
3d90: 62 50 75 72 67 65 61 62 6c 65 20 29 7b 0a 20 20  bPurgeable ){.  
3da0: 20 20 70 63 61 63 68 65 5f 67 2e 6e 43 75 72 72    pcache_g.nCurr
3db0: 65 6e 74 50 61 67 65 2d 2d 3b 0a 20 20 7d 0a 20  entPage--;.  }. 
3dc0: 20 70 63 61 63 68 65 46 72 65 65 28 70 29 3b 0a   pcacheFree(p);.
3dd0: 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45  }..#ifdef SQLITE
3de0: 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d  _ENABLE_MEMORY_M
3df0: 41 4e 41 47 45 4d 45 4e 54 0a 2f 2a 0a 2a 2a 20  ANAGEMENT./*.** 
3e00: 52 65 74 75 72 6e 20 74 68 65 20 6e 75 6d 62 65  Return the numbe
3e10: 72 20 6f 66 20 62 79 74 65 73 20 74 68 61 74 20  r of bytes that 
3e20: 77 69 6c 6c 20 62 65 20 72 65 74 75 72 6e 65 64  will be returned
3e30: 20 74 6f 20 74 68 65 20 68 65 61 70 20 77 68 65   to the heap whe
3e40: 6e 0a 2a 2a 20 74 68 65 20 61 72 67 75 6d 65 6e  n.** the argumen
3e50: 74 20 69 73 20 70 61 73 73 65 64 20 74 6f 20 70  t is passed to p
3e60: 63 61 63 68 65 50 61 67 65 46 72 65 65 28 29 2e  cachePageFree().
3e70: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 70  .*/.static int p
3e80: 63 61 63 68 65 50 61 67 65 53 69 7a 65 28 50 67  cachePageSize(Pg
3e90: 48 64 72 20 2a 70 29 7b 0a 20 20 61 73 73 65 72  Hdr *p){.  asser
3ea0: 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78  t( sqlite3_mutex
3eb0: 5f 68 65 6c 64 28 70 63 61 63 68 65 5f 67 2e 6d  _held(pcache_g.m
3ec0: 75 74 65 78 29 20 29 3b 0a 20 20 61 73 73 65 72  utex) );.  asser
3ed0: 74 28 20 21 70 63 61 63 68 65 5f 67 2e 70 53 74  t( !pcache_g.pSt
3ee0: 61 72 74 20 29 3b 0a 20 20 61 73 73 65 72 74 28  art );.  assert(
3ef0: 20 70 2d 3e 61 70 53 61 76 65 5b 30 5d 3d 3d 30   p->apSave[0]==0
3f00: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 2d   );.  assert( p-
3f10: 3e 61 70 53 61 76 65 5b 31 5d 3d 3d 30 20 29 3b  >apSave[1]==0 );
3f20: 0a 20 20 61 73 73 65 72 74 28 20 70 20 26 26 20  .  assert( p && 
3f30: 70 2d 3e 70 43 61 63 68 65 20 29 3b 0a 20 20 72  p->pCache );.  r
3f40: 65 74 75 72 6e 20 73 71 6c 69 74 65 33 4d 61 6c  eturn sqlite3Mal
3f50: 6c 6f 63 53 69 7a 65 28 70 29 3b 0a 7d 0a 23 65  locSize(p);.}.#e
3f60: 6e 64 69 66 0a 0a 2f 2a 0a 2a 2a 20 41 74 74 65  ndif../*.** Atte
3f70: 6d 70 74 20 74 6f 20 27 72 65 63 79 63 6c 65 27  mpt to 'recycle'
3f80: 20 61 20 70 61 67 65 20 66 72 6f 6d 20 74 68 65   a page from the
3f90: 20 67 6c 6f 62 61 6c 20 4c 52 55 20 6c 69 73 74   global LRU list
3fa0: 2e 20 4f 6e 6c 79 20 63 6c 65 61 6e 2c 0a 2a 2a  . Only clean,.**
3fb0: 20 75 6e 72 65 66 65 72 65 6e 63 65 64 20 70 61   unreferenced pa
3fc0: 67 65 73 20 66 72 6f 6d 20 70 75 72 67 65 61 62  ges from purgeab
3fd0: 6c 65 20 63 61 63 68 65 73 20 61 72 65 20 65 6c  le caches are el
3fe0: 69 67 69 62 6c 65 20 66 6f 72 20 72 65 63 79 63  igible for recyc
3ff0: 6c 69 6e 67 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73  ling..**.** This
4000: 20 66 75 6e 63 74 69 6f 6e 20 72 65 6d 6f 76 65   function remove
4010: 73 20 70 61 67 65 20 70 63 61 63 68 65 2e 70 4c  s page pcache.pL
4020: 72 75 54 61 69 6c 20 66 72 6f 6d 20 74 68 65 20  ruTail from the 
4030: 67 6c 6f 62 61 6c 20 4c 52 55 20 6c 69 73 74 2c  global LRU list,
4040: 0a 2a 2a 20 61 6e 64 20 66 72 6f 6d 20 74 68 65  .** and from the
4050: 20 68 61 73 68 2d 74 61 62 6c 65 20 61 6e 64 20   hash-table and 
4060: 50 43 61 63 68 65 2e 70 43 6c 65 61 6e 20 6c 69  PCache.pClean li
4070: 73 74 20 6f 66 20 74 68 65 20 6f 77 6e 65 72 20  st of the owner 
4080: 70 63 61 63 68 65 2e 0a 2a 2a 20 54 68 65 72 65  pcache..** There
4090: 20 73 68 6f 75 6c 64 20 62 65 20 6e 6f 20 6f 74   should be no ot
40a0: 68 65 72 20 72 65 66 65 72 65 6e 63 65 73 20 74  her references t
40b0: 6f 20 74 68 65 20 70 61 67 65 2e 0a 2a 2a 0a 2a  o the page..**.*
40c0: 2a 20 41 20 70 6f 69 6e 74 65 72 20 74 6f 20 74  * A pointer to t
40d0: 68 65 20 72 65 63 79 63 6c 65 64 20 70 61 67 65  he recycled page
40e0: 20 69 73 20 72 65 74 75 72 6e 65 64 2c 20 6f 72   is returned, or
40f0: 20 4e 55 4c 4c 20 69 66 20 6e 6f 20 70 61 67 65   NULL if no page
4100: 20 69 73 0a 2a 2a 20 65 6c 69 67 69 62 6c 65 20   is.** eligible 
4110: 66 6f 72 20 72 65 63 79 63 6c 69 6e 67 2e 0a 2a  for recycling..*
4120: 2f 0a 73 74 61 74 69 63 20 50 67 48 64 72 20 2a  /.static PgHdr *
4130: 70 63 61 63 68 65 52 65 63 79 63 6c 65 50 61 67  pcacheRecyclePag
4140: 65 28 76 6f 69 64 29 7b 0a 20 20 50 67 48 64 72  e(void){.  PgHdr
4150: 20 2a 70 20 3d 20 30 3b 0a 20 20 61 73 73 65 72   *p = 0;.  asser
4160: 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78  t( sqlite3_mutex
4170: 5f 68 65 6c 64 28 70 63 61 63 68 65 5f 67 2e 6d  _held(pcache_g.m
4180: 75 74 65 78 29 20 29 3b 0a 0a 20 20 69 66 28 20  utex) );..  if( 
4190: 28 70 3d 70 63 61 63 68 65 5f 67 2e 70 4c 72 75  (p=pcache_g.pLru
41a0: 54 61 69 6c 29 20 29 7b 0a 20 20 20 20 61 73 73  Tail) ){.    ass
41b0: 65 72 74 28 20 28 70 2d 3e 66 6c 61 67 73 26 50  ert( (p->flags&P
41c0: 47 48 44 52 5f 44 49 52 54 59 29 3d 3d 30 20 29  GHDR_DIRTY)==0 )
41d0: 3b 0a 20 20 20 20 70 63 61 63 68 65 52 65 6d 6f  ;.    pcacheRemo
41e0: 76 65 46 72 6f 6d 4c 72 75 4c 69 73 74 28 70 29  veFromLruList(p)
41f0: 3b 0a 20 20 20 20 70 63 61 63 68 65 52 65 6d 6f  ;.    pcacheRemo
4200: 76 65 46 72 6f 6d 48 61 73 68 28 70 29 3b 0a 20  veFromHash(p);. 
4210: 20 20 20 70 63 61 63 68 65 52 65 6d 6f 76 65 46     pcacheRemoveF
4220: 72 6f 6d 4c 69 73 74 28 26 70 2d 3e 70 43 61 63  romList(&p->pCac
4230: 68 65 2d 3e 70 43 6c 65 61 6e 2c 20 70 29 3b 0a  he->pClean, p);.
4240: 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 70 3b    }..  return p;
4250: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4f 62 74 61 69 6e  .}../*.** Obtain
4260: 20 73 70 61 63 65 20 66 6f 72 20 61 20 70 61 67   space for a pag
4270: 65 2e 20 54 72 79 20 74 6f 20 72 65 63 79 63 6c  e. Try to recycl
4280: 65 20 61 6e 20 6f 6c 64 20 70 61 67 65 20 69 66  e an old page if
4290: 20 74 68 65 20 6c 69 6d 69 74 20 6f 6e 20 74 68   the limit on th
42a0: 65 20 0a 2a 2a 20 6e 75 6d 62 65 72 20 6f 66 20  e .** number of 
42b0: 70 61 67 65 73 20 68 61 73 20 62 65 65 6e 20 72  pages has been r
42c0: 65 61 63 68 65 64 2e 20 49 66 20 74 68 65 20 6c  eached. If the l
42d0: 69 6d 69 74 20 68 61 73 20 6e 6f 74 20 62 65 65  imit has not bee
42e0: 6e 20 72 65 61 63 68 65 64 20 6f 72 0a 2a 2a 20  n reached or.** 
42f0: 74 68 65 72 65 20 61 72 65 20 6e 6f 20 70 61 67  there are no pag
4300: 65 73 20 65 6c 69 67 69 62 6c 65 20 66 6f 72 20  es eligible for 
4310: 72 65 63 79 63 6c 69 6e 67 2c 20 61 6c 6c 6f 63  recycling, alloc
4320: 61 74 65 20 61 20 6e 65 77 20 70 61 67 65 2e 0a  ate a new page..
4330: 2a 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20 70  **.** Return a p
4340: 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20 6e 65  ointer to the ne
4350: 77 20 70 61 67 65 2c 20 6f 72 20 4e 55 4c 4c 20  w page, or NULL 
4360: 69 66 20 61 6e 20 4f 4f 4d 20 63 6f 6e 64 69 74  if an OOM condit
4370: 69 6f 6e 20 6f 63 63 75 72 73 2e 0a 2a 2f 0a 73  ion occurs..*/.s
4380: 74 61 74 69 63 20 69 6e 74 20 70 63 61 63 68 65  tatic int pcache
4390: 52 65 63 79 63 6c 65 4f 72 41 6c 6c 6f 63 28 50  RecycleOrAlloc(P
43a0: 43 61 63 68 65 20 2a 70 43 61 63 68 65 2c 20 50  Cache *pCache, P
43b0: 67 48 64 72 20 2a 2a 70 70 50 61 67 65 29 7b 0a  gHdr **ppPage){.
43c0: 20 20 50 67 48 64 72 20 2a 70 20 3d 20 30 3b 0a    PgHdr *p = 0;.
43d0: 0a 20 20 69 6e 74 20 73 7a 50 61 67 65 20 3d 20  .  int szPage = 
43e0: 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 3b 0a  pCache->szPage;.
43f0: 20 20 69 6e 74 20 73 7a 45 78 74 72 61 20 3d 20    int szExtra = 
4400: 70 43 61 63 68 65 2d 3e 73 7a 45 78 74 72 61 3b  pCache->szExtra;
4410: 0a 0a 20 20 61 73 73 65 72 74 28 20 70 63 61 63  ..  assert( pcac
4420: 68 65 5f 67 2e 69 73 49 6e 69 74 20 29 3b 0a 20  he_g.isInit );. 
4430: 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33   assert( sqlite3
4440: 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 63 61 63  _mutex_held(pcac
4450: 68 65 5f 67 2e 6d 75 74 65 78 29 20 29 3b 0a 0a  he_g.mutex) );..
4460: 20 20 2a 70 70 50 61 67 65 20 3d 20 30 3b 0a 0a    *ppPage = 0;..
4470: 20 20 2f 2a 20 49 66 20 77 65 20 68 61 76 65 20    /* If we have 
4480: 72 65 61 63 68 65 64 20 65 69 74 68 65 72 20 74  reached either t
4490: 68 65 20 67 6c 6f 62 61 6c 20 6f 72 20 74 68 65  he global or the
44a0: 20 6c 6f 63 61 6c 20 6c 69 6d 69 74 20 66 6f 72   local limit for
44b0: 20 0a 20 20 2a 2a 20 70 69 6e 6e 65 64 2b 64 69   .  ** pinned+di
44c0: 72 74 79 20 70 61 67 65 73 2c 20 61 6e 64 20 74  rty pages, and t
44d0: 68 65 72 65 20 69 73 20 61 74 20 6c 65 61 73 74  here is at least
44e0: 20 6f 6e 65 20 64 69 72 74 79 20 70 61 67 65 2c   one dirty page,
44f0: 0a 20 20 2a 2a 20 69 6e 76 6f 6b 65 20 74 68 65  .  ** invoke the
4500: 20 78 53 74 72 65 73 73 20 63 61 6c 6c 62 61 63   xStress callbac
4510: 6b 20 74 6f 20 63 61 75 73 65 20 61 20 70 61 67  k to cause a pag
4520: 65 20 74 6f 20 62 65 63 6f 6d 65 20 63 6c 65 61  e to become clea
4530: 6e 2e 0a 20 20 2a 2f 0a 20 20 65 78 70 65 6e 73  n..  */.  expens
4540: 69 76 65 5f 61 73 73 65 72 74 28 20 70 43 61 63  ive_assert( pCac
4550: 68 65 2d 3e 6e 50 69 6e 6e 65 64 3d 3d 70 63 61  he->nPinned==pca
4560: 63 68 65 50 69 6e 6e 65 64 43 6f 75 6e 74 28 70  chePinnedCount(p
4570: 43 61 63 68 65 29 20 29 3b 0a 20 20 65 78 70 65  Cache) );.  expe
4580: 6e 73 69 76 65 5f 61 73 73 65 72 74 28 20 70 63  nsive_assert( pc
4590: 61 63 68 65 43 68 65 63 6b 53 79 6e 63 65 64 28  acheCheckSynced(
45a0: 70 43 61 63 68 65 29 20 29 3b 0a 20 20 69 66 28  pCache) );.  if(
45b0: 20 70 43 61 63 68 65 2d 3e 78 53 74 72 65 73 73   pCache->xStress
45c0: 0a 20 20 20 26 26 20 70 43 61 63 68 65 2d 3e 70  .   && pCache->p
45d0: 44 69 72 74 79 0a 20 20 20 26 26 20 28 70 43 61  Dirty.   && (pCa
45e0: 63 68 65 2d 3e 6e 50 69 6e 6e 65 64 3e 3d 28 70  che->nPinned>=(p
45f0: 63 61 63 68 65 5f 67 2e 6e 4d 61 78 50 61 67 65  cache_g.nMaxPage
4600: 2b 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 2d 70 63  +pCache->nMin-pc
4610: 61 63 68 65 5f 67 2e 6e 4d 69 6e 50 61 67 65 29  ache_g.nMinPage)
4620: 0a 20 20 20 20 20 20 20 20 20 20 20 7c 7c 20 70  .           || p
4630: 43 61 63 68 65 2d 3e 6e 50 69 6e 6e 65 64 3e 3d  Cache->nPinned>=
4640: 70 43 61 63 68 65 2d 3e 6e 4d 61 78 29 0a 20 20  pCache->nMax).  
4650: 29 7b 0a 20 20 20 20 50 67 48 64 72 20 2a 70 50  ){.    PgHdr *pP
4660: 67 3b 0a 20 20 20 20 61 73 73 65 72 74 28 70 43  g;.    assert(pC
4670: 61 63 68 65 2d 3e 70 44 69 72 74 79 54 61 69 6c  ache->pDirtyTail
4680: 29 3b 0a 0a 20 20 20 20 66 6f 72 28 70 50 67 3d  );..    for(pPg=
4690: 70 43 61 63 68 65 2d 3e 70 53 79 6e 63 65 64 3b  pCache->pSynced;
46a0: 20 0a 20 20 20 20 20 20 20 20 70 50 67 20 26 26   .        pPg &&
46b0: 20 28 70 50 67 2d 3e 6e 52 65 66 20 7c 7c 20 28   (pPg->nRef || (
46c0: 70 50 67 2d 3e 66 6c 61 67 73 26 50 47 48 44 52  pPg->flags&PGHDR
46d0: 5f 4e 45 45 44 5f 53 59 4e 43 29 29 3b 20 0a 20  _NEED_SYNC)); . 
46e0: 20 20 20 20 20 20 20 70 50 67 3d 70 50 67 2d 3e         pPg=pPg->
46f0: 70 50 72 65 76 0a 20 20 20 20 29 3b 0a 20 20 20  pPrev.    );.   
4700: 20 69 66 28 20 21 70 50 67 20 29 7b 0a 20 20 20   if( !pPg ){.   
4710: 20 20 20 66 6f 72 28 70 50 67 3d 70 43 61 63 68     for(pPg=pCach
4720: 65 2d 3e 70 44 69 72 74 79 54 61 69 6c 3b 20 70  e->pDirtyTail; p
4730: 50 67 20 26 26 20 70 50 67 2d 3e 6e 52 65 66 3b  Pg && pPg->nRef;
4740: 20 70 50 67 3d 70 50 67 2d 3e 70 50 72 65 76 29   pPg=pPg->pPrev)
4750: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20  ;.    }.    if( 
4760: 70 50 67 20 29 7b 0a 20 20 20 20 20 20 69 6e 74  pPg ){.      int
4770: 20 72 63 3b 0a 20 20 20 20 20 20 70 63 61 63 68   rc;.      pcach
4780: 65 45 78 69 74 4d 75 74 65 78 28 29 3b 0a 20 20  eExitMutex();.  
4790: 20 20 20 20 72 63 20 3d 20 70 43 61 63 68 65 2d      rc = pCache-
47a0: 3e 78 53 74 72 65 73 73 28 70 43 61 63 68 65 2d  >xStress(pCache-
47b0: 3e 70 53 74 72 65 73 73 2c 20 70 50 67 29 3b 0a  >pStress, pPg);.
47c0: 20 20 20 20 20 20 70 63 61 63 68 65 45 6e 74 65        pcacheEnte
47d0: 72 4d 75 74 65 78 28 29 3b 0a 20 20 20 20 20 20  rMutex();.      
47e0: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
47f0: 4b 20 26 26 20 72 63 21 3d 53 51 4c 49 54 45 5f  K && rc!=SQLITE_
4800: 42 55 53 59 20 29 7b 0a 20 20 20 20 20 20 20 20  BUSY ){.        
4810: 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 20  return rc;.     
4820: 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20   }.    }.  }..  
4830: 2f 2a 20 49 66 20 65 69 74 68 65 72 20 74 68 65  /* If either the
4840: 20 6c 6f 63 61 6c 20 6f 72 20 74 68 65 20 67 6c   local or the gl
4850: 6f 62 61 6c 20 70 61 67 65 20 6c 69 6d 69 74 20  obal page limit 
4860: 68 61 73 20 62 65 65 6e 20 72 65 61 63 68 65 64  has been reached
4870: 2c 20 0a 20 20 2a 2a 20 74 72 79 20 74 6f 20 72  , .  ** try to r
4880: 65 63 79 63 6c 65 20 61 20 70 61 67 65 2e 20 0a  ecycle a page. .
4890: 20 20 2a 2f 0a 20 20 69 66 28 20 70 43 61 63 68    */.  if( pCach
48a0: 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 26 26  e->bPurgeable &&
48b0: 20 28 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 3e   (pCache->nPage>
48c0: 3d 70 43 61 63 68 65 2d 3e 6e 4d 61 78 2d 31 20  =pCache->nMax-1 
48d0: 7c 7c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ||.             
48e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
48f0: 70 63 61 63 68 65 5f 67 2e 6e 43 75 72 72 65 6e  pcache_g.nCurren
4900: 74 50 61 67 65 3e 3d 70 63 61 63 68 65 5f 67 2e  tPage>=pcache_g.
4910: 6e 4d 61 78 50 61 67 65 29 20 29 7b 0a 20 20 20  nMaxPage) ){.   
4920: 20 70 20 3d 20 70 63 61 63 68 65 52 65 63 79 63   p = pcacheRecyc
4930: 6c 65 50 61 67 65 28 29 3b 0a 20 20 7d 0a 0a 20  lePage();.  }.. 
4940: 20 2f 2a 20 49 66 20 61 20 70 61 67 65 20 68 61   /* If a page ha
4950: 73 20 62 65 65 6e 20 72 65 63 79 63 6c 65 64 20  s been recycled 
4960: 62 75 74 20 69 74 20 69 73 20 74 68 65 20 77 72  but it is the wr
4970: 6f 6e 67 20 73 69 7a 65 2c 20 66 72 65 65 20 69  ong size, free i
4980: 74 2e 20 2a 2f 0a 20 20 69 66 28 20 70 20 26 26  t. */.  if( p &&
4990: 20 28 70 2d 3e 70 43 61 63 68 65 2d 3e 73 7a 50   (p->pCache->szP
49a0: 61 67 65 21 3d 73 7a 50 61 67 65 20 7c 7c 20 70  age!=szPage || p
49b0: 2d 3e 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65  ->pCache->szPage
49c0: 21 3d 73 7a 45 78 74 72 61 29 20 29 7b 0a 20 20  !=szExtra) ){.  
49d0: 20 20 70 63 61 63 68 65 50 61 67 65 46 72 65 65    pcachePageFree
49e0: 28 70 29 3b 0a 20 20 20 20 70 20 3d 20 30 3b 0a  (p);.    p = 0;.
49f0: 20 20 7d 0a 0a 20 20 69 66 28 20 21 70 20 29 7b    }..  if( !p ){
4a00: 0a 20 20 20 20 70 20 3d 20 70 63 61 63 68 65 50  .    p = pcacheP
4a10: 61 67 65 41 6c 6c 6f 63 28 70 43 61 63 68 65 29  ageAlloc(pCache)
4a20: 3b 0a 20 20 7d 0a 0a 20 20 2a 70 70 50 61 67 65  ;.  }..  *ppPage
4a30: 20 3d 20 70 3b 0a 20 20 72 65 74 75 72 6e 20 28   = p;.  return (
4a40: 70 3f 53 51 4c 49 54 45 5f 4f 4b 3a 53 51 4c 49  p?SQLITE_OK:SQLI
4a50: 54 45 5f 4e 4f 4d 45 4d 29 3b 0a 7d 0a 0a 2f 2a  TE_NOMEM);.}../*
4a60: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4a70: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4a80: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4a90: 2a 2a 20 47 65 6e 65 72 61 6c 20 49 6e 74 65 72  ** General Inter
4aa0: 66 61 63 65 73 20 2a 2a 2a 2a 2a 2a 0a 2a 2a 0a  faces ******.**.
4ab0: 2a 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 61 6e  ** Initialize an
4ac0: 64 20 73 68 75 74 64 6f 77 6e 20 74 68 65 20 70  d shutdown the p
4ad0: 61 67 65 20 63 61 63 68 65 20 73 75 62 73 79 73  age cache subsys
4ae0: 74 65 6d 2e 20 4e 65 69 74 68 65 72 20 6f 66 20  tem. Neither of 
4af0: 74 68 65 73 65 20 0a 2a 2a 20 66 75 6e 63 74 69  these .** functi
4b00: 6f 6e 73 20 61 72 65 20 74 68 72 65 61 64 73 61  ons are threadsa
4b10: 66 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  fe..*/.int sqlit
4b20: 65 33 50 63 61 63 68 65 49 6e 69 74 69 61 6c 69  e3PcacheInitiali
4b30: 7a 65 28 76 6f 69 64 29 7b 0a 20 20 61 73 73 65  ze(void){.  asse
4b40: 72 74 28 20 70 63 61 63 68 65 5f 67 2e 69 73 49  rt( pcache_g.isI
4b50: 6e 69 74 3d 3d 30 20 29 3b 0a 20 20 6d 65 6d 73  nit==0 );.  mems
4b60: 65 74 28 26 70 63 61 63 68 65 5f 67 2c 20 30 2c  et(&pcache_g, 0,
4b70: 20 73 69 7a 65 6f 66 28 70 63 61 63 68 65 29 29   sizeof(pcache))
4b80: 3b 0a 20 20 69 66 28 20 73 71 6c 69 74 65 33 47  ;.  if( sqlite3G
4b90: 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 62 43 6f 72  lobalConfig.bCor
4ba0: 65 4d 75 74 65 78 20 29 7b 0a 20 20 20 20 2f 2a  eMutex ){.    /*
4bb0: 20 4e 6f 20 6e 65 65 64 20 74 6f 20 63 68 65 63   No need to chec
4bc0: 6b 20 74 68 65 20 72 65 74 75 72 6e 20 76 61 6c  k the return val
4bd0: 75 65 20 6f 66 20 73 71 6c 69 74 65 33 5f 6d 75  ue of sqlite3_mu
4be0: 74 65 78 5f 61 6c 6c 6f 63 28 29 2e 20 0a 20 20  tex_alloc(). .  
4bf0: 20 20 2a 2a 20 41 6c 6c 6f 63 61 74 69 6e 67 20    ** Allocating 
4c00: 61 20 73 74 61 74 69 63 20 6d 75 74 65 78 20 63  a static mutex c
4c10: 61 6e 6e 6f 74 20 66 61 69 6c 2e 0a 20 20 20 20  annot fail..    
4c20: 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 5f 67 2e  */.    pcache_g.
4c30: 6d 75 74 65 78 20 3d 20 73 71 6c 69 74 65 33 5f  mutex = sqlite3_
4c40: 6d 75 74 65 78 5f 61 6c 6c 6f 63 28 53 51 4c 49  mutex_alloc(SQLI
4c50: 54 45 5f 4d 55 54 45 58 5f 53 54 41 54 49 43 5f  TE_MUTEX_STATIC_
4c60: 4c 52 55 29 3b 0a 20 20 7d 0a 20 20 70 63 61 63  LRU);.  }.  pcac
4c70: 68 65 5f 67 2e 69 73 49 6e 69 74 20 3d 20 31 3b  he_g.isInit = 1;
4c80: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
4c90: 5f 4f 4b 3b 0a 7d 0a 76 6f 69 64 20 73 71 6c 69  _OK;.}.void sqli
4ca0: 74 65 33 50 63 61 63 68 65 53 68 75 74 64 6f 77  te3PcacheShutdow
4cb0: 6e 28 76 6f 69 64 29 7b 0a 20 20 6d 65 6d 73 65  n(void){.  memse
4cc0: 74 28 26 70 63 61 63 68 65 5f 67 2c 20 30 2c 20  t(&pcache_g, 0, 
4cd0: 73 69 7a 65 6f 66 28 70 63 61 63 68 65 29 29 3b  sizeof(pcache));
4ce0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e  .}../*.** Return
4cf0: 20 74 68 65 20 73 69 7a 65 20 69 6e 20 62 79 74   the size in byt
4d00: 65 73 20 6f 66 20 61 20 50 43 61 63 68 65 20 6f  es of a PCache o
4d10: 62 6a 65 63 74 2e 0a 2a 2f 0a 69 6e 74 20 73 71  bject..*/.int sq
4d20: 6c 69 74 65 33 50 63 61 63 68 65 53 69 7a 65 28  lite3PcacheSize(
4d30: 76 6f 69 64 29 7b 20 72 65 74 75 72 6e 20 73 69  void){ return si
4d40: 7a 65 6f 66 28 50 43 61 63 68 65 29 3b 20 7d 0a  zeof(PCache); }.
4d50: 0a 2f 2a 0a 2a 2a 20 43 72 65 61 74 65 20 61 20  ./*.** Create a 
4d60: 6e 65 77 20 50 43 61 63 68 65 20 6f 62 6a 65 63  new PCache objec
4d70: 74 2e 20 20 53 74 6f 72 61 67 65 20 73 70 61 63  t.  Storage spac
4d80: 65 20 74 6f 20 68 6f 6c 64 20 74 68 65 20 6f 62  e to hold the ob
4d90: 6a 65 63 74 0a 2a 2a 20 68 61 73 20 61 6c 72 65  ject.** has alre
4da0: 61 64 79 20 62 65 65 6e 20 61 6c 6c 6f 63 61 74  ady been allocat
4db0: 65 64 20 61 6e 64 20 69 73 20 70 61 73 73 65 64  ed and is passed
4dc0: 20 69 6e 20 61 73 20 74 68 65 20 70 20 70 6f 69   in as the p poi
4dd0: 6e 74 65 72 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71  nter..*/.void sq
4de0: 6c 69 74 65 33 50 63 61 63 68 65 4f 70 65 6e 28  lite3PcacheOpen(
4df0: 0a 20 20 69 6e 74 20 73 7a 50 61 67 65 2c 20 20  .  int szPage,  
4e00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4e10: 2f 2a 20 53 69 7a 65 20 6f 66 20 65 76 65 72 79  /* Size of every
4e20: 20 70 61 67 65 20 2a 2f 0a 20 20 69 6e 74 20 73   page */.  int s
4e30: 7a 45 78 74 72 61 2c 20 20 20 20 20 20 20 20 20  zExtra,         
4e40: 20 20 20 20 20 20 20 20 2f 2a 20 45 78 74 72 61          /* Extra
4e50: 20 73 70 61 63 65 20 61 73 73 6f 63 69 61 74 65   space associate
4e60: 64 20 77 69 74 68 20 65 61 63 68 20 70 61 67 65  d with each page
4e70: 20 2a 2f 0a 20 20 69 6e 74 20 62 50 75 72 67 65   */.  int bPurge
4e80: 61 62 6c 65 2c 20 20 20 20 20 20 20 20 20 20 20  able,           
4e90: 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 70 61     /* True if pa
4ea0: 67 65 73 20 61 72 65 20 6f 6e 20 62 61 63 6b 69  ges are on backi
4eb0: 6e 67 20 73 74 6f 72 65 20 2a 2f 0a 20 20 69 6e  ng store */.  in
4ec0: 74 20 28 2a 78 53 74 72 65 73 73 29 28 76 6f 69  t (*xStress)(voi
4ed0: 64 2a 2c 50 67 48 64 72 2a 29 2c 2f 2a 20 43 61  d*,PgHdr*),/* Ca
4ee0: 6c 6c 20 74 6f 20 74 72 79 20 74 6f 20 6d 61 6b  ll to try to mak
4ef0: 65 20 70 61 67 65 73 20 63 6c 65 61 6e 20 2a 2f  e pages clean */
4f00: 0a 20 20 76 6f 69 64 20 2a 70 53 74 72 65 73 73  .  void *pStress
4f10: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
4f20: 2f 2a 20 41 72 67 75 6d 65 6e 74 20 74 6f 20 78  /* Argument to x
4f30: 53 74 72 65 73 73 20 2a 2f 0a 20 20 50 43 61 63  Stress */.  PCac
4f40: 68 65 20 2a 70 20 20 20 20 20 20 20 20 20 20 20  he *p           
4f50: 20 20 20 20 20 20 20 20 20 2f 2a 20 50 72 65 61           /* Prea
4f60: 6c 6c 6f 63 61 74 65 64 20 73 70 61 63 65 20 66  llocated space f
4f70: 6f 72 20 74 68 65 20 50 43 61 63 68 65 20 2a 2f  or the PCache */
4f80: 0a 29 7b 0a 20 20 61 73 73 65 72 74 28 20 70 63  .){.  assert( pc
4f90: 61 63 68 65 5f 67 2e 69 73 49 6e 69 74 20 29 3b  ache_g.isInit );
4fa0: 0a 20 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20  .  memset(p, 0, 
4fb0: 73 69 7a 65 6f 66 28 50 43 61 63 68 65 29 29 3b  sizeof(PCache));
4fc0: 0a 20 20 70 2d 3e 73 7a 50 61 67 65 20 3d 20 73  .  p->szPage = s
4fd0: 7a 50 61 67 65 3b 0a 20 20 70 2d 3e 73 7a 45 78  zPage;.  p->szEx
4fe0: 74 72 61 20 3d 20 73 7a 45 78 74 72 61 3b 0a 20  tra = szExtra;. 
4ff0: 20 70 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 3d   p->bPurgeable =
5000: 20 62 50 75 72 67 65 61 62 6c 65 3b 0a 20 20 70   bPurgeable;.  p
5010: 2d 3e 78 53 74 72 65 73 73 20 3d 20 78 53 74 72  ->xStress = xStr
5020: 65 73 73 3b 0a 20 20 70 2d 3e 70 53 74 72 65 73  ess;.  p->pStres
5030: 73 20 3d 20 70 53 74 72 65 73 73 3b 0a 20 20 70  s = pStress;.  p
5040: 2d 3e 6e 4d 61 78 20 3d 20 31 30 30 3b 0a 20 20  ->nMax = 100;.  
5050: 70 2d 3e 6e 4d 69 6e 20 3d 20 31 30 3b 0a 0a 20  p->nMin = 10;.. 
5060: 20 70 63 61 63 68 65 45 6e 74 65 72 4d 75 74 65   pcacheEnterMute
5070: 78 28 29 3b 0a 20 20 69 66 28 20 62 50 75 72 67  x();.  if( bPurg
5080: 65 61 62 6c 65 20 29 7b 0a 20 20 20 20 70 63 61  eable ){.    pca
5090: 63 68 65 5f 67 2e 6e 4d 61 78 50 61 67 65 20 2b  che_g.nMaxPage +
50a0: 3d 20 70 2d 3e 6e 4d 61 78 3b 0a 20 20 20 20 70  = p->nMax;.    p
50b0: 63 61 63 68 65 5f 67 2e 6e 4d 69 6e 50 61 67 65  cache_g.nMinPage
50c0: 20 2b 3d 20 70 2d 3e 6e 4d 69 6e 3b 0a 20 20 7d   += p->nMin;.  }
50d0: 0a 0a 20 20 70 63 61 63 68 65 45 78 69 74 4d 75  ..  pcacheExitMu
50e0: 74 65 78 28 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  tex();.}../*.** 
50f0: 43 68 61 6e 67 65 20 74 68 65 20 70 61 67 65 20  Change the page 
5100: 73 69 7a 65 20 66 6f 72 20 50 43 61 63 68 65 20  size for PCache 
5110: 6f 62 6a 65 63 74 2e 20 20 54 68 69 73 20 63 61  object.  This ca
5120: 6e 20 6f 6e 6c 79 20 68 61 70 70 65 6e 0a 2a 2a  n only happen.**
5130: 20 77 68 65 6e 20 74 68 65 20 63 61 63 68 65 20   when the cache 
5140: 69 73 20 65 6d 70 74 79 2e 0a 2a 2f 0a 76 6f 69  is empty..*/.voi
5150: 64 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 53  d sqlite3PcacheS
5160: 65 74 50 61 67 65 53 69 7a 65 28 50 43 61 63 68  etPageSize(PCach
5170: 65 20 2a 70 43 61 63 68 65 2c 20 69 6e 74 20 73  e *pCache, int s
5180: 7a 50 61 67 65 29 7b 0a 20 20 61 73 73 65 72 74  zPage){.  assert
5190: 28 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 3d 3d  (pCache->nPage==
51a0: 30 29 3b 0a 20 20 70 43 61 63 68 65 2d 3e 73 7a  0);.  pCache->sz
51b0: 50 61 67 65 20 3d 20 73 7a 50 61 67 65 3b 0a 7d  Page = szPage;.}
51c0: 0a 0a 2f 2a 0a 2a 2a 20 54 72 79 20 74 6f 20 6f  ../*.** Try to o
51d0: 62 74 61 69 6e 20 61 20 70 61 67 65 20 66 72 6f  btain a page fro
51e0: 6d 20 74 68 65 20 63 61 63 68 65 2e 0a 2a 2f 0a  m the cache..*/.
51f0: 69 6e 74 20 73 71 6c 69 74 65 33 50 63 61 63 68  int sqlite3Pcach
5200: 65 46 65 74 63 68 28 0a 20 20 50 43 61 63 68 65  eFetch(.  PCache
5210: 20 2a 70 43 61 63 68 65 2c 20 20 20 20 20 20 20   *pCache,       
5220: 2f 2a 20 4f 62 74 61 69 6e 20 74 68 65 20 70 61  /* Obtain the pa
5230: 67 65 20 66 72 6f 6d 20 74 68 69 73 20 63 61 63  ge from this cac
5240: 68 65 20 2a 2f 0a 20 20 50 67 6e 6f 20 70 67 6e  he */.  Pgno pgn
5250: 6f 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  o,            /*
5260: 20 50 61 67 65 20 6e 75 6d 62 65 72 20 74 6f 20   Page number to 
5270: 6f 62 74 61 69 6e 20 2a 2f 0a 20 20 69 6e 74 20  obtain */.  int 
5280: 63 72 65 61 74 65 46 6c 61 67 2c 20 20 20 20 20  createFlag,     
5290: 20 20 2f 2a 20 49 66 20 74 72 75 65 2c 20 63 72    /* If true, cr
52a0: 65 61 74 65 20 70 61 67 65 20 69 66 20 69 74 20  eate page if it 
52b0: 64 6f 65 73 20 6e 6f 74 20 65 78 69 73 74 20 61  does not exist a
52c0: 6c 72 65 61 64 79 20 2a 2f 0a 20 20 50 67 48 64  lready */.  PgHd
52d0: 72 20 2a 2a 70 70 50 61 67 65 20 20 20 20 20 20  r **ppPage      
52e0: 20 20 2f 2a 20 57 72 69 74 65 20 74 68 65 20 70    /* Write the p
52f0: 61 67 65 20 68 65 72 65 20 2a 2f 0a 29 7b 0a 20  age here */.){. 
5300: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
5310: 5f 4f 4b 3b 0a 20 20 50 67 48 64 72 20 2a 70 50  _OK;.  PgHdr *pP
5320: 61 67 65 20 3d 20 30 3b 0a 0a 20 20 61 73 73 65  age = 0;..  asse
5330: 72 74 28 20 70 63 61 63 68 65 5f 67 2e 69 73 49  rt( pcache_g.isI
5340: 6e 69 74 20 29 3b 0a 20 20 61 73 73 65 72 74 28  nit );.  assert(
5350: 20 70 43 61 63 68 65 21 3d 30 20 29 3b 0a 20 20   pCache!=0 );.  
5360: 61 73 73 65 72 74 28 20 70 67 6e 6f 3e 30 20 29  assert( pgno>0 )
5370: 3b 0a 20 20 65 78 70 65 6e 73 69 76 65 5f 61 73  ;.  expensive_as
5380: 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e 6e 50  sert( pCache->nP
5390: 69 6e 6e 65 64 3d 3d 70 63 61 63 68 65 50 69 6e  inned==pcachePin
53a0: 6e 65 64 43 6f 75 6e 74 28 70 43 61 63 68 65 29  nedCount(pCache)
53b0: 20 29 3b 0a 0a 20 20 70 63 61 63 68 65 45 6e 74   );..  pcacheEnt
53c0: 65 72 4d 75 74 65 78 28 29 3b 0a 0a 20 20 2f 2a  erMutex();..  /*
53d0: 20 53 65 61 72 63 68 20 74 68 65 20 68 61 73 68   Search the hash
53e0: 20 74 61 62 6c 65 20 66 6f 72 20 74 68 65 20 72   table for the r
53f0: 65 71 75 65 73 74 65 64 20 70 61 67 65 2e 20 45  equested page. E
5400: 78 69 74 20 65 61 72 6c 79 20 69 66 20 69 74 20  xit early if it 
5410: 69 73 20 66 6f 75 6e 64 2e 20 2a 2f 0a 20 20 69  is found. */.  i
5420: 66 28 20 70 43 61 63 68 65 2d 3e 61 70 48 61 73  f( pCache->apHas
5430: 68 20 29 7b 0a 20 20 20 20 75 33 32 20 68 20 3d  h ){.    u32 h =
5440: 20 70 67 6e 6f 20 25 20 70 43 61 63 68 65 2d 3e   pgno % pCache->
5450: 6e 48 61 73 68 3b 0a 20 20 20 20 66 6f 72 28 70  nHash;.    for(p
5460: 50 61 67 65 3d 70 43 61 63 68 65 2d 3e 61 70 48  Page=pCache->apH
5470: 61 73 68 5b 68 5d 3b 20 70 50 61 67 65 3b 20 70  ash[h]; pPage; p
5480: 50 61 67 65 3d 70 50 61 67 65 2d 3e 70 4e 65 78  Page=pPage->pNex
5490: 74 48 61 73 68 29 7b 0a 20 20 20 20 20 20 69 66  tHash){.      if
54a0: 28 20 70 50 61 67 65 2d 3e 70 67 6e 6f 3d 3d 70  ( pPage->pgno==p
54b0: 67 6e 6f 20 29 7b 0a 20 20 20 20 20 20 20 20 69  gno ){.        i
54c0: 66 28 20 70 50 61 67 65 2d 3e 6e 52 65 66 3d 3d  f( pPage->nRef==
54d0: 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69  0 ){.          i
54e0: 66 28 20 30 3d 3d 28 70 50 61 67 65 2d 3e 66 6c  f( 0==(pPage->fl
54f0: 61 67 73 26 50 47 48 44 52 5f 44 49 52 54 59 29  ags&PGHDR_DIRTY)
5500: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20   ){.            
5510: 70 63 61 63 68 65 52 65 6d 6f 76 65 46 72 6f 6d  pcacheRemoveFrom
5520: 4c 72 75 4c 69 73 74 28 70 50 61 67 65 29 3b 0a  LruList(pPage);.
5530: 20 20 20 20 20 20 20 20 20 20 20 20 70 43 61 63              pCac
5540: 68 65 2d 3e 6e 50 69 6e 6e 65 64 2b 2b 3b 0a 20  he->nPinned++;. 
5550: 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20           }.     
5560: 20 20 20 20 20 70 43 61 63 68 65 2d 3e 6e 52 65       pCache->nRe
5570: 66 2b 2b 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  f++;.        }. 
5580: 20 20 20 20 20 20 20 70 50 61 67 65 2d 3e 6e 52         pPage->nR
5590: 65 66 2b 2b 3b 0a 20 20 20 20 20 20 20 20 62 72  ef++;.        br
55a0: 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  eak;.      }.   
55b0: 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 21 70   }.  }..  if( !p
55c0: 50 61 67 65 20 26 26 20 63 72 65 61 74 65 46 6c  Page && createFl
55d0: 61 67 20 29 7b 0a 20 20 20 20 69 66 28 20 70 43  ag ){.    if( pC
55e0: 61 63 68 65 2d 3e 6e 48 61 73 68 3c 3d 70 43 61  ache->nHash<=pCa
55f0: 63 68 65 2d 3e 6e 50 61 67 65 20 29 7b 0a 20 20  che->nPage ){.  
5600: 20 20 20 20 72 63 20 3d 20 70 63 61 63 68 65 52      rc = pcacheR
5610: 65 73 69 7a 65 48 61 73 68 28 70 43 61 63 68 65  esizeHash(pCache
5620: 2c 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3c  , pCache->nHash<
5630: 32 35 36 20 3f 20 32 35 36 20 3a 20 70 43 61 63  256 ? 256 : pCac
5640: 68 65 2d 3e 6e 48 61 73 68 2a 32 29 3b 0a 20 20  he->nHash*2);.  
5650: 20 20 7d 0a 20 20 20 20 69 66 28 20 72 63 3d 3d    }.    if( rc==
5660: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
5670: 20 20 20 72 63 20 3d 20 70 63 61 63 68 65 52 65     rc = pcacheRe
5680: 63 79 63 6c 65 4f 72 41 6c 6c 6f 63 28 70 43 61  cycleOrAlloc(pCa
5690: 63 68 65 2c 20 26 70 50 61 67 65 29 3b 0a 20 20  che, &pPage);.  
56a0: 20 20 7d 0a 20 20 20 20 69 66 28 20 72 63 3d 3d    }.    if( rc==
56b0: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
56c0: 20 20 20 70 50 61 67 65 2d 3e 70 50 61 67 65 72     pPage->pPager
56d0: 20 3d 20 30 3b 0a 20 20 20 20 20 20 70 50 61 67   = 0;.      pPag
56e0: 65 2d 3e 66 6c 61 67 73 20 3d 20 30 3b 0a 20 20  e->flags = 0;.  
56f0: 20 20 20 20 70 50 61 67 65 2d 3e 70 44 69 72 74      pPage->pDirt
5700: 79 20 3d 20 30 3b 0a 20 20 20 20 20 20 70 50 61  y = 0;.      pPa
5710: 67 65 2d 3e 70 67 6e 6f 20 3d 20 70 67 6e 6f 3b  ge->pgno = pgno;
5720: 0a 20 20 20 20 20 20 70 50 61 67 65 2d 3e 70 43  .      pPage->pC
5730: 61 63 68 65 20 3d 20 70 43 61 63 68 65 3b 0a 20  ache = pCache;. 
5740: 20 20 20 20 20 70 50 61 67 65 2d 3e 6e 52 65 66       pPage->nRef
5750: 20 3d 20 31 3b 0a 20 20 20 20 20 20 70 43 61 63   = 1;.      pCac
5760: 68 65 2d 3e 6e 52 65 66 2b 2b 3b 0a 20 20 20 20  he->nRef++;.    
5770: 20 20 70 43 61 63 68 65 2d 3e 6e 50 69 6e 6e 65    pCache->nPinne
5780: 64 2b 2b 3b 0a 20 20 20 20 20 20 70 63 61 63 68  d++;.      pcach
5790: 65 41 64 64 54 6f 4c 69 73 74 28 26 70 43 61 63  eAddToList(&pCac
57a0: 68 65 2d 3e 70 43 6c 65 61 6e 2c 20 70 50 61 67  he->pClean, pPag
57b0: 65 29 3b 0a 20 20 20 20 20 20 70 63 61 63 68 65  e);.      pcache
57c0: 41 64 64 54 6f 48 61 73 68 28 70 50 61 67 65 29  AddToHash(pPage)
57d0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 70  ;.    }.  }..  p
57e0: 63 61 63 68 65 45 78 69 74 4d 75 74 65 78 28 29  cacheExitMutex()
57f0: 3b 0a 0a 20 20 2a 70 70 50 61 67 65 20 3d 20 70  ;..  *ppPage = p
5800: 50 61 67 65 3b 0a 20 20 65 78 70 65 6e 73 69 76  Page;.  expensiv
5810: 65 5f 61 73 73 65 72 74 28 20 70 43 61 63 68 65  e_assert( pCache
5820: 2d 3e 6e 50 69 6e 6e 65 64 3d 3d 70 63 61 63 68  ->nPinned==pcach
5830: 65 50 69 6e 6e 65 64 43 6f 75 6e 74 28 70 43 61  ePinnedCount(pCa
5840: 63 68 65 29 20 29 3b 0a 20 20 61 73 73 65 72 74  che) );.  assert
5850: 28 20 70 50 61 67 65 20 7c 7c 20 21 63 72 65 61  ( pPage || !crea
5860: 74 65 46 6c 61 67 20 7c 7c 20 72 63 21 3d 53 51  teFlag || rc!=SQ
5870: 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 72 65 74  LITE_OK );.  ret
5880: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
5890: 20 44 65 72 65 66 65 72 65 6e 63 65 20 61 20 70   Dereference a p
58a0: 61 67 65 2e 20 20 57 68 65 6e 20 74 68 65 20 72  age.  When the r
58b0: 65 66 65 72 65 6e 63 65 20 63 6f 75 6e 74 20 72  eference count r
58c0: 65 61 63 68 65 73 20 7a 65 72 6f 2c 0a 2a 2a 20  eaches zero,.** 
58d0: 6d 6f 76 65 20 74 68 65 20 70 61 67 65 20 74 6f  move the page to
58e0: 20 74 68 65 20 4c 52 55 20 6c 69 73 74 20 69 66   the LRU list if
58f0: 20 69 74 20 69 73 20 63 6c 65 61 6e 2e 0a 2a 2f   it is clean..*/
5900: 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63 61  .void sqlite3Pca
5910: 63 68 65 52 65 6c 65 61 73 65 28 50 67 48 64 72  cheRelease(PgHdr
5920: 20 2a 70 29 7b 0a 20 20 61 73 73 65 72 74 28 20   *p){.  assert( 
5930: 70 2d 3e 6e 52 65 66 3e 30 20 29 3b 0a 20 20 70  p->nRef>0 );.  p
5940: 2d 3e 6e 52 65 66 2d 2d 3b 0a 20 20 69 66 28 20  ->nRef--;.  if( 
5950: 70 2d 3e 6e 52 65 66 3d 3d 30 20 29 7b 0a 20 20  p->nRef==0 ){.  
5960: 20 20 50 43 61 63 68 65 20 2a 70 43 61 63 68 65    PCache *pCache
5970: 20 3d 20 70 2d 3e 70 43 61 63 68 65 3b 0a 20 20   = p->pCache;.  
5980: 20 20 70 43 61 63 68 65 2d 3e 6e 52 65 66 2d 2d    pCache->nRef--
5990: 3b 0a 20 20 20 20 69 66 28 20 28 70 2d 3e 66 6c  ;.    if( (p->fl
59a0: 61 67 73 26 50 47 48 44 52 5f 44 49 52 54 59 29  ags&PGHDR_DIRTY)
59b0: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 70 43 61  ==0 ){.      pCa
59c0: 63 68 65 2d 3e 6e 50 69 6e 6e 65 64 2d 2d 3b 0a  che->nPinned--;.
59d0: 20 20 20 20 20 20 70 63 61 63 68 65 45 6e 74 65        pcacheEnte
59e0: 72 4d 75 74 65 78 28 29 3b 0a 20 20 20 20 20 20  rMutex();.      
59f0: 69 66 28 20 70 63 61 63 68 65 5f 67 2e 6e 43 75  if( pcache_g.nCu
5a00: 72 72 65 6e 74 50 61 67 65 3e 70 63 61 63 68 65  rrentPage>pcache
5a10: 5f 67 2e 6e 4d 61 78 50 61 67 65 20 29 7b 0a 20  _g.nMaxPage ){. 
5a20: 20 20 20 20 20 20 20 70 63 61 63 68 65 52 65 6d         pcacheRem
5a30: 6f 76 65 46 72 6f 6d 4c 69 73 74 28 26 70 43 61  oveFromList(&pCa
5a40: 63 68 65 2d 3e 70 43 6c 65 61 6e 2c 20 70 29 3b  che->pClean, p);
5a50: 0a 20 20 20 20 20 20 20 20 70 63 61 63 68 65 52  .        pcacheR
5a60: 65 6d 6f 76 65 46 72 6f 6d 48 61 73 68 28 70 29  emoveFromHash(p)
5a70: 3b 0a 20 20 20 20 20 20 20 20 70 63 61 63 68 65  ;.        pcache
5a80: 50 61 67 65 46 72 65 65 28 70 29 3b 0a 20 20 20  PageFree(p);.   
5a90: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
5aa0: 20 20 70 63 61 63 68 65 41 64 64 54 6f 4c 72 75    pcacheAddToLru
5ab0: 4c 69 73 74 28 70 29 3b 0a 20 20 20 20 20 20 7d  List(p);.      }
5ac0: 0a 20 20 20 20 20 20 70 63 61 63 68 65 45 78 69  .      pcacheExi
5ad0: 74 4d 75 74 65 78 28 29 3b 0a 20 20 20 20 7d 65  tMutex();.    }e
5ae0: 6c 73 65 7b 0a 20 20 20 20 20 20 2f 2a 20 4d 6f  lse{.      /* Mo
5af0: 76 65 20 74 68 65 20 70 61 67 65 20 74 6f 20 74  ve the page to t
5b00: 68 65 20 68 65 61 64 20 6f 66 20 74 68 65 20 63  he head of the c
5b10: 61 63 68 65 73 20 64 69 72 74 79 20 6c 69 73 74  aches dirty list
5b20: 2e 20 2a 2f 0a 20 20 20 20 20 20 70 63 61 63 68  . */.      pcach
5b30: 65 52 65 6d 6f 76 65 46 72 6f 6d 4c 69 73 74 28  eRemoveFromList(
5b40: 26 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 2c  &pCache->pDirty,
5b50: 20 70 29 3b 0a 20 20 20 20 20 20 70 63 61 63 68   p);.      pcach
5b60: 65 41 64 64 54 6f 4c 69 73 74 28 26 70 43 61 63  eAddToList(&pCac
5b70: 68 65 2d 3e 70 44 69 72 74 79 2c 20 70 29 3b 0a  he->pDirty, p);.
5b80: 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 76 6f 69      }.  }.}..voi
5b90: 64 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 52  d sqlite3PcacheR
5ba0: 65 66 28 50 67 48 64 72 20 2a 70 29 7b 0a 20 20  ef(PgHdr *p){.  
5bb0: 61 73 73 65 72 74 28 70 2d 3e 6e 52 65 66 3e 30  assert(p->nRef>0
5bc0: 29 3b 0a 20 20 70 2d 3e 6e 52 65 66 2b 2b 3b 0a  );.  p->nRef++;.
5bd0: 7d 0a 0a 2f 2a 0a 2a 2a 20 44 72 6f 70 20 61 20  }../*.** Drop a 
5be0: 70 61 67 65 20 66 72 6f 6d 20 74 68 65 20 63 61  page from the ca
5bf0: 63 68 65 2e 20 54 68 65 72 65 20 6d 75 73 74 20  che. There must 
5c00: 62 65 20 65 78 61 63 74 6c 79 20 6f 6e 65 20 72  be exactly one r
5c10: 65 66 65 72 65 6e 63 65 20 74 6f 20 74 68 65 0a  eference to the.
5c20: 2a 2a 20 70 61 67 65 2e 20 54 68 69 73 20 66 75  ** page. This fu
5c30: 6e 63 74 69 6f 6e 20 64 65 6c 65 74 65 73 20 74  nction deletes t
5c40: 68 61 74 20 72 65 66 65 72 65 6e 63 65 2c 20 73  hat reference, s
5c50: 6f 20 61 66 74 65 72 20 69 74 20 72 65 74 75 72  o after it retur
5c60: 6e 73 20 74 68 65 0a 2a 2a 20 70 61 67 65 20 70  ns the.** page p
5c70: 6f 69 6e 74 65 64 20 74 6f 20 62 79 20 70 20 69  ointed to by p i
5c80: 73 20 69 6e 76 61 6c 69 64 2e 0a 2a 2f 0a 76 6f  s invalid..*/.vo
5c90: 69 64 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  id sqlite3Pcache
5ca0: 44 72 6f 70 28 50 67 48 64 72 20 2a 70 29 7b 0a  Drop(PgHdr *p){.
5cb0: 20 20 50 43 61 63 68 65 20 2a 70 43 61 63 68 65    PCache *pCache
5cc0: 3b 0a 20 20 61 73 73 65 72 74 28 20 70 2d 3e 6e  ;.  assert( p->n
5cd0: 52 65 66 3d 3d 31 20 29 3b 0a 20 20 61 73 73 65  Ref==1 );.  asse
5ce0: 72 74 28 20 30 3d 3d 28 70 2d 3e 66 6c 61 67 73  rt( 0==(p->flags
5cf0: 26 50 47 48 44 52 5f 44 49 52 54 59 29 20 29 3b  &PGHDR_DIRTY) );
5d00: 0a 20 20 70 43 61 63 68 65 20 3d 20 70 2d 3e 70  .  pCache = p->p
5d10: 43 61 63 68 65 3b 0a 20 20 70 43 61 63 68 65 2d  Cache;.  pCache-
5d20: 3e 6e 52 65 66 2d 2d 3b 0a 20 20 70 43 61 63 68  >nRef--;.  pCach
5d30: 65 2d 3e 6e 50 69 6e 6e 65 64 2d 2d 3b 0a 20 20  e->nPinned--;.  
5d40: 70 63 61 63 68 65 45 6e 74 65 72 4d 75 74 65 78  pcacheEnterMutex
5d50: 28 29 3b 0a 20 20 70 63 61 63 68 65 52 65 6d 6f  ();.  pcacheRemo
5d60: 76 65 46 72 6f 6d 4c 69 73 74 28 26 70 43 61 63  veFromList(&pCac
5d70: 68 65 2d 3e 70 43 6c 65 61 6e 2c 20 70 29 3b 0a  he->pClean, p);.
5d80: 20 20 70 63 61 63 68 65 52 65 6d 6f 76 65 46 72    pcacheRemoveFr
5d90: 6f 6d 48 61 73 68 28 70 29 3b 0a 20 20 70 63 61  omHash(p);.  pca
5da0: 63 68 65 50 61 67 65 46 72 65 65 28 70 29 3b 0a  chePageFree(p);.
5db0: 20 20 70 63 61 63 68 65 45 78 69 74 4d 75 74 65    pcacheExitMute
5dc0: 78 28 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61  x();.}../*.** Ma
5dd0: 6b 65 20 73 75 72 65 20 74 68 65 20 70 61 67 65  ke sure the page
5de0: 20 69 73 20 6d 61 72 6b 65 64 20 61 73 20 64 69   is marked as di
5df0: 72 74 79 2e 20 20 49 66 20 69 74 20 69 73 6e 27  rty.  If it isn'
5e00: 74 20 64 69 72 74 79 20 61 6c 72 65 61 64 79 2c  t dirty already,
5e10: 0a 2a 2a 20 6d 61 6b 65 20 69 74 20 73 6f 2e 0a  .** make it so..
5e20: 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50  */.void sqlite3P
5e30: 63 61 63 68 65 4d 61 6b 65 44 69 72 74 79 28 50  cacheMakeDirty(P
5e40: 67 48 64 72 20 2a 70 29 7b 0a 20 20 50 43 61 63  gHdr *p){.  PCac
5e50: 68 65 20 2a 70 43 61 63 68 65 3b 0a 20 20 70 2d  he *pCache;.  p-
5e60: 3e 66 6c 61 67 73 20 26 3d 20 7e 50 47 48 44 52  >flags &= ~PGHDR
5e70: 5f 44 4f 4e 54 5f 57 52 49 54 45 3b 0a 20 20 69  _DONT_WRITE;.  i
5e80: 66 28 20 70 2d 3e 66 6c 61 67 73 20 26 20 50 47  f( p->flags & PG
5e90: 48 44 52 5f 44 49 52 54 59 20 29 20 72 65 74 75  HDR_DIRTY ) retu
5ea0: 72 6e 3b 0a 20 20 61 73 73 65 72 74 28 20 28 70  rn;.  assert( (p
5eb0: 2d 3e 66 6c 61 67 73 20 26 20 50 47 48 44 52 5f  ->flags & PGHDR_
5ec0: 44 49 52 54 59 29 3d 3d 30 20 29 3b 0a 20 20 61  DIRTY)==0 );.  a
5ed0: 73 73 65 72 74 28 20 70 2d 3e 6e 52 65 66 3e 30  ssert( p->nRef>0
5ee0: 20 29 3b 0a 20 20 70 43 61 63 68 65 20 3d 20 70   );.  pCache = p
5ef0: 2d 3e 70 43 61 63 68 65 3b 0a 20 20 70 63 61 63  ->pCache;.  pcac
5f00: 68 65 45 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a  heEnterMutex();.
5f10: 20 20 70 63 61 63 68 65 52 65 6d 6f 76 65 46 72    pcacheRemoveFr
5f20: 6f 6d 4c 69 73 74 28 26 70 43 61 63 68 65 2d 3e  omList(&pCache->
5f30: 70 43 6c 65 61 6e 2c 20 70 29 3b 0a 20 20 70 63  pClean, p);.  pc
5f40: 61 63 68 65 41 64 64 54 6f 4c 69 73 74 28 26 70  acheAddToList(&p
5f50: 43 61 63 68 65 2d 3e 70 44 69 72 74 79 2c 20 70  Cache->pDirty, p
5f60: 29 3b 0a 20 20 70 63 61 63 68 65 45 78 69 74 4d  );.  pcacheExitM
5f70: 75 74 65 78 28 29 3b 0a 20 20 70 2d 3e 66 6c 61  utex();.  p->fla
5f80: 67 73 20 7c 3d 20 50 47 48 44 52 5f 44 49 52 54  gs |= PGHDR_DIRT
5f90: 59 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69  Y;.}..static voi
5fa0: 64 20 70 63 61 63 68 65 4d 61 6b 65 43 6c 65 61  d pcacheMakeClea
5fb0: 6e 28 50 67 48 64 72 20 2a 70 29 7b 0a 20 20 50  n(PgHdr *p){.  P
5fc0: 43 61 63 68 65 20 2a 70 43 61 63 68 65 20 3d 20  Cache *pCache = 
5fd0: 70 2d 3e 70 43 61 63 68 65 3b 0a 20 20 61 73 73  p->pCache;.  ass
5fe0: 65 72 74 28 20 70 2d 3e 66 6c 61 67 73 20 26 20  ert( p->flags & 
5ff0: 50 47 48 44 52 5f 44 49 52 54 59 20 29 3b 0a 20  PGHDR_DIRTY );. 
6000: 20 70 63 61 63 68 65 52 65 6d 6f 76 65 46 72 6f   pcacheRemoveFro
6010: 6d 4c 69 73 74 28 26 70 43 61 63 68 65 2d 3e 70  mList(&pCache->p
6020: 44 69 72 74 79 2c 20 70 29 3b 0a 20 20 70 63 61  Dirty, p);.  pca
6030: 63 68 65 41 64 64 54 6f 4c 69 73 74 28 26 70 43  cheAddToList(&pC
6040: 61 63 68 65 2d 3e 70 43 6c 65 61 6e 2c 20 70 29  ache->pClean, p)
6050: 3b 0a 20 20 70 2d 3e 66 6c 61 67 73 20 26 3d 20  ;.  p->flags &= 
6060: 7e 50 47 48 44 52 5f 44 49 52 54 59 3b 0a 20 20  ~PGHDR_DIRTY;.  
6070: 69 66 28 20 70 2d 3e 6e 52 65 66 3d 3d 30 20 29  if( p->nRef==0 )
6080: 7b 0a 20 20 20 20 70 63 61 63 68 65 41 64 64 54  {.    pcacheAddT
6090: 6f 4c 72 75 4c 69 73 74 28 70 29 3b 0a 20 20 20  oLruList(p);.   
60a0: 20 70 43 61 63 68 65 2d 3e 6e 50 69 6e 6e 65 64   pCache->nPinned
60b0: 2d 2d 3b 0a 20 20 7d 0a 20 20 65 78 70 65 6e 73  --;.  }.  expens
60c0: 69 76 65 5f 61 73 73 65 72 74 28 20 70 43 61 63  ive_assert( pCac
60d0: 68 65 2d 3e 6e 50 69 6e 6e 65 64 3d 3d 70 63 61  he->nPinned==pca
60e0: 63 68 65 50 69 6e 6e 65 64 43 6f 75 6e 74 28 70  chePinnedCount(p
60f0: 43 61 63 68 65 29 20 29 3b 0a 7d 0a 0a 2f 2a 0a  Cache) );.}../*.
6100: 2a 2a 20 4d 61 6b 65 20 73 75 72 65 20 74 68 65  ** Make sure the
6110: 20 70 61 67 65 20 69 73 20 6d 61 72 6b 65 64 20   page is marked 
6120: 61 73 20 63 6c 65 61 6e 2e 20 20 49 66 20 69 74  as clean.  If it
6130: 20 69 73 6e 27 74 20 63 6c 65 61 6e 20 61 6c 72   isn't clean alr
6140: 65 61 64 79 2c 0a 2a 2a 20 6d 61 6b 65 20 69 74  eady,.** make it
6150: 20 73 6f 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c   so..*/.void sql
6160: 69 74 65 33 50 63 61 63 68 65 4d 61 6b 65 43 6c  ite3PcacheMakeCl
6170: 65 61 6e 28 50 67 48 64 72 20 2a 70 29 7b 0a 20  ean(PgHdr *p){. 
6180: 20 69 66 28 20 28 70 2d 3e 66 6c 61 67 73 20 26   if( (p->flags &
6190: 20 50 47 48 44 52 5f 44 49 52 54 59 29 20 29 7b   PGHDR_DIRTY) ){
61a0: 0a 20 20 20 20 70 63 61 63 68 65 45 6e 74 65 72  .    pcacheEnter
61b0: 4d 75 74 65 78 28 29 3b 0a 20 20 20 20 70 63 61  Mutex();.    pca
61c0: 63 68 65 4d 61 6b 65 43 6c 65 61 6e 28 70 29 3b  cheMakeClean(p);
61d0: 0a 20 20 20 20 70 63 61 63 68 65 45 78 69 74 4d  .    pcacheExitM
61e0: 75 74 65 78 28 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f  utex();.  }.}../
61f0: 2a 0a 2a 2a 20 4d 61 6b 65 20 65 76 65 72 79 20  *.** Make every 
6200: 70 61 67 65 20 69 6e 20 74 68 65 20 63 61 63 68  page in the cach
6210: 65 20 63 6c 65 61 6e 2e 0a 2a 2f 0a 76 6f 69 64  e clean..*/.void
6220: 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 43 6c   sqlite3PcacheCl
6230: 65 61 6e 41 6c 6c 28 50 43 61 63 68 65 20 2a 70  eanAll(PCache *p
6240: 43 61 63 68 65 29 7b 0a 20 20 50 67 48 64 72 20  Cache){.  PgHdr 
6250: 2a 70 3b 0a 20 20 70 63 61 63 68 65 45 6e 74 65  *p;.  pcacheEnte
6260: 72 4d 75 74 65 78 28 29 3b 0a 20 20 77 68 69 6c  rMutex();.  whil
6270: 65 28 20 28 70 20 3d 20 70 43 61 63 68 65 2d 3e  e( (p = pCache->
6280: 70 44 69 72 74 79 29 21 3d 30 20 29 7b 0a 20 20  pDirty)!=0 ){.  
6290: 20 20 70 63 61 63 68 65 52 65 6d 6f 76 65 46 72    pcacheRemoveFr
62a0: 6f 6d 4c 69 73 74 28 26 70 43 61 63 68 65 2d 3e  omList(&pCache->
62b0: 70 44 69 72 74 79 2c 20 70 29 3b 0a 20 20 20 20  pDirty, p);.    
62c0: 70 2d 3e 66 6c 61 67 73 20 26 3d 20 7e 50 47 48  p->flags &= ~PGH
62d0: 44 52 5f 44 49 52 54 59 3b 0a 20 20 20 20 70 63  DR_DIRTY;.    pc
62e0: 61 63 68 65 41 64 64 54 6f 4c 69 73 74 28 26 70  acheAddToList(&p
62f0: 43 61 63 68 65 2d 3e 70 43 6c 65 61 6e 2c 20 70  Cache->pClean, p
6300: 29 3b 0a 20 20 20 20 69 66 28 20 70 2d 3e 6e 52  );.    if( p->nR
6310: 65 66 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 70  ef==0 ){.      p
6320: 63 61 63 68 65 41 64 64 54 6f 4c 72 75 4c 69 73  cacheAddToLruLis
6330: 74 28 70 29 3b 0a 20 20 20 20 20 20 70 43 61 63  t(p);.      pCac
6340: 68 65 2d 3e 6e 50 69 6e 6e 65 64 2d 2d 3b 0a 20  he->nPinned--;. 
6350: 20 20 20 7d 0a 20 20 7d 0a 20 20 73 71 6c 69 74     }.  }.  sqlit
6360: 65 33 50 63 61 63 68 65 41 73 73 65 72 74 46 6c  e3PcacheAssertFl
6370: 61 67 73 28 70 43 61 63 68 65 2c 20 30 2c 20 50  ags(pCache, 0, P
6380: 47 48 44 52 5f 44 49 52 54 59 29 3b 0a 20 20 65  GHDR_DIRTY);.  e
6390: 78 70 65 6e 73 69 76 65 5f 61 73 73 65 72 74 28  xpensive_assert(
63a0: 20 70 43 61 63 68 65 2d 3e 6e 50 69 6e 6e 65 64   pCache->nPinned
63b0: 3d 3d 70 63 61 63 68 65 50 69 6e 6e 65 64 43 6f  ==pcachePinnedCo
63c0: 75 6e 74 28 70 43 61 63 68 65 29 20 29 3b 0a 20  unt(pCache) );. 
63d0: 20 70 63 61 63 68 65 45 78 69 74 4d 75 74 65 78   pcacheExitMutex
63e0: 28 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 68 61  ();.}../*.** Cha
63f0: 6e 67 65 20 74 68 65 20 70 61 67 65 20 6e 75 6d  nge the page num
6400: 62 65 72 20 6f 66 20 70 61 67 65 20 70 20 74 6f  ber of page p to
6410: 20 6e 65 77 50 67 6e 6f 2e 20 49 66 20 6e 65 77   newPgno. If new
6420: 50 67 6e 6f 20 69 73 20 30 2c 20 74 68 65 6e 20  Pgno is 0, then 
6430: 74 68 65 0a 2a 2a 20 70 61 67 65 20 6f 62 6a 65  the.** page obje
6440: 63 74 20 69 73 20 61 64 64 65 64 20 74 6f 20 74  ct is added to t
6450: 68 65 20 63 6c 65 61 6e 2d 6c 69 73 74 20 61 6e  he clean-list an
6460: 64 20 74 68 65 20 50 47 48 44 52 5f 52 45 55 53  d the PGHDR_REUS
6470: 45 5f 55 4e 4c 49 4b 45 4c 59 20 0a 2a 2a 20 66  E_UNLIKELY .** f
6480: 6c 61 67 20 73 65 74 2e 0a 2a 2f 0a 76 6f 69 64  lag set..*/.void
6490: 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 4d 6f   sqlite3PcacheMo
64a0: 76 65 28 50 67 48 64 72 20 2a 70 2c 20 50 67 6e  ve(PgHdr *p, Pgn
64b0: 6f 20 6e 65 77 50 67 6e 6f 29 7b 0a 20 20 61 73  o newPgno){.  as
64c0: 73 65 72 74 28 20 70 2d 3e 6e 52 65 66 3e 30 20  sert( p->nRef>0 
64d0: 29 3b 0a 20 20 70 63 61 63 68 65 45 6e 74 65 72  );.  pcacheEnter
64e0: 4d 75 74 65 78 28 29 3b 0a 20 20 70 63 61 63 68  Mutex();.  pcach
64f0: 65 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73 68 28  eRemoveFromHash(
6500: 70 29 3b 0a 20 20 70 2d 3e 70 67 6e 6f 20 3d 20  p);.  p->pgno = 
6510: 6e 65 77 50 67 6e 6f 3b 0a 20 20 69 66 28 20 6e  newPgno;.  if( n
6520: 65 77 50 67 6e 6f 3d 3d 30 20 29 7b 0a 20 20 20  ewPgno==0 ){.   
6530: 20 69 66 28 20 28 70 2d 3e 66 6c 61 67 73 20 26   if( (p->flags &
6540: 20 50 47 48 44 52 5f 44 49 52 54 59 29 20 29 7b   PGHDR_DIRTY) ){
6550: 0a 20 20 20 20 20 20 70 63 61 63 68 65 4d 61 6b  .      pcacheMak
6560: 65 43 6c 65 61 6e 28 70 29 3b 0a 20 20 20 20 7d  eClean(p);.    }
6570: 0a 20 20 20 20 70 2d 3e 66 6c 61 67 73 20 3d 20  .    p->flags = 
6580: 50 47 48 44 52 5f 52 45 55 53 45 5f 55 4e 4c 49  PGHDR_REUSE_UNLI
6590: 4b 45 4c 59 3b 0a 20 20 7d 0a 20 20 70 63 61 63  KELY;.  }.  pcac
65a0: 68 65 41 64 64 54 6f 48 61 73 68 28 70 29 3b 0a  heAddToHash(p);.
65b0: 20 20 70 63 61 63 68 65 45 78 69 74 4d 75 74 65    pcacheExitMute
65c0: 78 28 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65  x();.}../*.** Re
65d0: 6d 6f 76 65 20 61 6c 6c 20 63 6f 6e 74 65 6e 74  move all content
65e0: 20 66 72 6f 6d 20 61 20 70 61 67 65 20 63 61 63   from a page cac
65f0: 68 65 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  he.*/.static voi
6600: 64 20 70 63 61 63 68 65 43 6c 65 61 72 28 50 43  d pcacheClear(PC
6610: 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b 0a 20  ache *pCache){. 
6620: 20 50 67 48 64 72 20 2a 70 2c 20 2a 70 4e 65 78   PgHdr *p, *pNex
6630: 74 3b 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c  t;.  assert( sql
6640: 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28  ite3_mutex_held(
6650: 70 63 61 63 68 65 5f 67 2e 6d 75 74 65 78 29 20  pcache_g.mutex) 
6660: 29 3b 0a 20 20 66 6f 72 28 70 3d 70 43 61 63 68  );.  for(p=pCach
6670: 65 2d 3e 70 43 6c 65 61 6e 3b 20 70 3b 20 70 3d  e->pClean; p; p=
6680: 70 4e 65 78 74 29 7b 0a 20 20 20 20 70 4e 65 78  pNext){.    pNex
6690: 74 20 3d 20 70 2d 3e 70 4e 65 78 74 3b 0a 20 20  t = p->pNext;.  
66a0: 20 20 70 63 61 63 68 65 52 65 6d 6f 76 65 46 72    pcacheRemoveFr
66b0: 6f 6d 4c 72 75 4c 69 73 74 28 70 29 3b 0a 20 20  omLruList(p);.  
66c0: 20 20 70 63 61 63 68 65 50 61 67 65 46 72 65 65    pcachePageFree
66d0: 28 70 29 3b 0a 20 20 7d 0a 20 20 66 6f 72 28 70  (p);.  }.  for(p
66e0: 3d 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 3b  =pCache->pDirty;
66f0: 20 70 3b 20 70 3d 70 4e 65 78 74 29 7b 0a 20 20   p; p=pNext){.  
6700: 20 20 70 4e 65 78 74 20 3d 20 70 2d 3e 70 4e 65    pNext = p->pNe
6710: 78 74 3b 0a 20 20 20 20 70 63 61 63 68 65 50 61  xt;.    pcachePa
6720: 67 65 46 72 65 65 28 70 29 3b 0a 20 20 7d 0a 20  geFree(p);.  }. 
6730: 20 70 43 61 63 68 65 2d 3e 70 43 6c 65 61 6e 20   pCache->pClean 
6740: 3d 20 30 3b 0a 20 20 70 43 61 63 68 65 2d 3e 70  = 0;.  pCache->p
6750: 44 69 72 74 79 20 3d 20 30 3b 0a 20 20 70 43 61  Dirty = 0;.  pCa
6760: 63 68 65 2d 3e 70 44 69 72 74 79 54 61 69 6c 20  che->pDirtyTail 
6770: 3d 20 30 3b 0a 20 20 70 43 61 63 68 65 2d 3e 6e  = 0;.  pCache->n
6780: 50 61 67 65 20 3d 20 30 3b 0a 20 20 70 43 61 63  Page = 0;.  pCac
6790: 68 65 2d 3e 6e 50 69 6e 6e 65 64 20 3d 20 30 3b  he->nPinned = 0;
67a0: 0a 20 20 6d 65 6d 73 65 74 28 70 43 61 63 68 65  .  memset(pCache
67b0: 2d 3e 61 70 48 61 73 68 2c 20 30 2c 20 70 43 61  ->apHash, 0, pCa
67c0: 63 68 65 2d 3e 6e 48 61 73 68 2a 73 69 7a 65 6f  che->nHash*sizeo
67d0: 66 28 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68  f(pCache->apHash
67e0: 5b 30 5d 29 29 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a  [0]));.}.../*.**
67f0: 20 44 72 6f 70 20 65 76 65 72 79 20 63 61 63 68   Drop every cach
6800: 65 20 65 6e 74 72 79 20 77 68 6f 73 65 20 70 61  e entry whose pa
6810: 67 65 20 6e 75 6d 62 65 72 20 69 73 20 67 72 65  ge number is gre
6820: 61 74 65 72 20 74 68 61 6e 20 22 70 67 6e 6f 22  ater than "pgno"
6830: 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
6840: 33 50 63 61 63 68 65 54 72 75 6e 63 61 74 65 28  3PcacheTruncate(
6850: 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 2c 20  PCache *pCache, 
6860: 50 67 6e 6f 20 70 67 6e 6f 29 7b 0a 20 20 50 67  Pgno pgno){.  Pg
6870: 48 64 72 20 2a 70 2c 20 2a 70 4e 65 78 74 3b 0a  Hdr *p, *pNext;.
6880: 20 20 50 67 48 64 72 20 2a 70 44 69 72 74 79 20    PgHdr *pDirty 
6890: 3d 20 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79  = pCache->pDirty
68a0: 3b 0a 20 20 70 63 61 63 68 65 45 6e 74 65 72 4d  ;.  pcacheEnterM
68b0: 75 74 65 78 28 29 3b 0a 20 20 66 6f 72 28 70 3d  utex();.  for(p=
68c0: 70 43 61 63 68 65 2d 3e 70 43 6c 65 61 6e 3b 20  pCache->pClean; 
68d0: 70 7c 7c 70 44 69 72 74 79 3b 20 70 3d 70 4e 65  p||pDirty; p=pNe
68e0: 78 74 29 7b 0a 20 20 20 20 69 66 28 20 21 70 20  xt){.    if( !p 
68f0: 29 7b 0a 20 20 20 20 20 20 70 20 3d 20 70 44 69  ){.      p = pDi
6900: 72 74 79 3b 0a 20 20 20 20 20 20 70 44 69 72 74  rty;.      pDirt
6910: 79 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20 20  y = 0;.    }.   
6920: 20 70 4e 65 78 74 20 3d 20 70 2d 3e 70 4e 65 78   pNext = p->pNex
6930: 74 3b 0a 20 20 20 20 69 66 28 20 70 2d 3e 70 67  t;.    if( p->pg
6940: 6e 6f 3e 70 67 6e 6f 20 29 7b 0a 20 20 20 20 20  no>pgno ){.     
6950: 20 69 66 28 20 70 2d 3e 6e 52 65 66 3d 3d 30 20   if( p->nRef==0 
6960: 29 7b 0a 20 20 20 20 20 20 20 20 70 63 61 63 68  ){.        pcach
6970: 65 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73 68 28  eRemoveFromHash(
6980: 70 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20  p);.        if( 
6990: 70 2d 3e 66 6c 61 67 73 26 50 47 48 44 52 5f 44  p->flags&PGHDR_D
69a0: 49 52 54 59 20 29 7b 0a 20 20 20 20 20 20 20 20  IRTY ){.        
69b0: 20 20 70 63 61 63 68 65 52 65 6d 6f 76 65 46 72    pcacheRemoveFr
69c0: 6f 6d 4c 69 73 74 28 26 70 43 61 63 68 65 2d 3e  omList(&pCache->
69d0: 70 44 69 72 74 79 2c 20 70 29 3b 0a 20 20 20 20  pDirty, p);.    
69e0: 20 20 20 20 20 20 70 43 61 63 68 65 2d 3e 6e 50        pCache->nP
69f0: 69 6e 6e 65 64 2d 2d 3b 0a 20 20 20 20 20 20 20  inned--;.       
6a00: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
6a10: 20 20 70 63 61 63 68 65 52 65 6d 6f 76 65 46 72    pcacheRemoveFr
6a20: 6f 6d 4c 69 73 74 28 26 70 43 61 63 68 65 2d 3e  omList(&pCache->
6a30: 70 43 6c 65 61 6e 2c 20 70 29 3b 0a 20 20 20 20  pClean, p);.    
6a40: 20 20 20 20 20 20 70 63 61 63 68 65 52 65 6d 6f        pcacheRemo
6a50: 76 65 46 72 6f 6d 4c 72 75 4c 69 73 74 28 70 29  veFromLruList(p)
6a60: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
6a70: 20 20 20 20 70 63 61 63 68 65 50 61 67 65 46 72      pcachePageFr
6a80: 65 65 28 70 29 3b 0a 20 20 20 20 20 20 7d 65 6c  ee(p);.      }el
6a90: 73 65 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 49  se{.        /* I
6aa0: 66 20 74 68 65 72 65 20 61 72 65 20 72 65 66 65  f there are refe
6ab0: 72 65 6e 63 65 73 20 74 6f 20 74 68 65 20 70 61  rences to the pa
6ac0: 67 65 2c 20 69 74 20 63 61 6e 6e 6f 74 20 62 65  ge, it cannot be
6ad0: 20 66 72 65 65 64 2e 20 49 6e 20 74 68 69 73 0a   freed. In this.
6ae0: 20 20 20 20 20 20 20 20 2a 2a 20 63 61 73 65 2c          ** case,
6af0: 20 7a 65 72 6f 20 74 68 65 20 70 61 67 65 20 63   zero the page c
6b00: 6f 6e 74 65 6e 74 20 69 6e 73 74 65 61 64 2e 0a  ontent instead..
6b10: 20 20 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20          */.     
6b20: 20 20 20 6d 65 6d 73 65 74 28 70 2d 3e 70 44 61     memset(p->pDa
6b30: 74 61 2c 20 30 2c 20 70 43 61 63 68 65 2d 3e 73  ta, 0, pCache->s
6b40: 7a 50 61 67 65 29 3b 0a 20 20 20 20 20 20 7d 0a  zPage);.      }.
6b50: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 70 63 61 63      }.  }.  pcac
6b60: 68 65 45 78 69 74 4d 75 74 65 78 28 29 3b 0a 7d  heExitMutex();.}
6b70: 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 74 68 65 72 65  ../*.** If there
6b80: 20 61 72 65 20 63 75 72 72 65 6e 74 6c 79 20 6d   are currently m
6b90: 6f 72 65 20 74 68 61 6e 20 70 63 61 63 68 65 2e  ore than pcache.
6ba0: 6e 4d 61 78 50 61 67 65 20 70 61 67 65 73 20 61  nMaxPage pages a
6bb0: 6c 6c 6f 63 61 74 65 64 2c 20 74 72 79 0a 2a 2a  llocated, try.**
6bc0: 20 74 6f 20 72 65 63 79 63 6c 65 20 70 61 67 65   to recycle page
6bd0: 73 20 74 6f 20 72 65 64 75 63 65 20 74 68 65 20  s to reduce the 
6be0: 6e 75 6d 62 65 72 20 61 6c 6c 6f 63 61 74 65 64  number allocated
6bf0: 20 74 6f 20 70 63 61 63 68 65 2e 6e 4d 61 78 50   to pcache.nMaxP
6c00: 61 67 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  age..*/.static v
6c10: 6f 69 64 20 70 63 61 63 68 65 45 6e 66 6f 72 63  oid pcacheEnforc
6c20: 65 4d 61 78 50 61 67 65 28 76 6f 69 64 29 7b 0a  eMaxPage(void){.
6c30: 20 20 50 67 48 64 72 20 2a 70 3b 0a 20 20 61 73    PgHdr *p;.  as
6c40: 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75  sert( sqlite3_mu
6c50: 74 65 78 5f 68 65 6c 64 28 70 63 61 63 68 65 5f  tex_held(pcache_
6c60: 67 2e 6d 75 74 65 78 29 20 29 3b 0a 20 20 77 68  g.mutex) );.  wh
6c70: 69 6c 65 28 20 70 63 61 63 68 65 5f 67 2e 6e 43  ile( pcache_g.nC
6c80: 75 72 72 65 6e 74 50 61 67 65 3e 70 63 61 63 68  urrentPage>pcach
6c90: 65 5f 67 2e 6e 4d 61 78 50 61 67 65 20 26 26 20  e_g.nMaxPage && 
6ca0: 28 70 20 3d 20 70 63 61 63 68 65 52 65 63 79 63  (p = pcacheRecyc
6cb0: 6c 65 50 61 67 65 28 29 29 20 29 7b 0a 20 20 20  lePage()) ){.   
6cc0: 20 70 63 61 63 68 65 50 61 67 65 46 72 65 65 28   pcachePageFree(
6cd0: 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a  p);.  }.}../*.**
6ce0: 20 43 6c 6f 73 65 20 61 20 63 61 63 68 65 2e 0a   Close a cache..
6cf0: 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50  */.void sqlite3P
6d00: 63 61 63 68 65 43 6c 6f 73 65 28 50 43 61 63 68  cacheClose(PCach
6d10: 65 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 70 63  e *pCache){.  pc
6d20: 61 63 68 65 45 6e 74 65 72 4d 75 74 65 78 28 29  acheEnterMutex()
6d30: 3b 0a 0a 20 20 2f 2a 20 46 72 65 65 20 61 6c 6c  ;..  /* Free all
6d40: 20 74 68 65 20 70 61 67 65 73 20 75 73 65 64 20   the pages used 
6d50: 62 79 20 74 68 69 73 20 70 61 67 65 72 20 61 6e  by this pager an
6d60: 64 20 72 65 6d 6f 76 65 20 74 68 65 6d 20 66 72  d remove them fr
6d70: 6f 6d 20 74 68 65 20 4c 52 55 20 6c 69 73 74 2e  om the LRU list.
6d80: 20 2a 2f 0a 20 20 70 63 61 63 68 65 43 6c 65 61   */.  pcacheClea
6d90: 72 28 70 43 61 63 68 65 29 3b 0a 20 20 69 66 28  r(pCache);.  if(
6da0: 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61   pCache->bPurgea
6db0: 62 6c 65 20 29 7b 0a 20 20 20 20 70 63 61 63 68  ble ){.    pcach
6dc0: 65 5f 67 2e 6e 4d 61 78 50 61 67 65 20 2d 3d 20  e_g.nMaxPage -= 
6dd0: 70 43 61 63 68 65 2d 3e 6e 4d 61 78 3b 0a 20 20  pCache->nMax;.  
6de0: 20 20 70 63 61 63 68 65 5f 67 2e 6e 4d 69 6e 50    pcache_g.nMinP
6df0: 61 67 65 20 2d 3d 20 70 43 61 63 68 65 2d 3e 6e  age -= pCache->n
6e00: 4d 69 6e 3b 0a 20 20 20 20 70 63 61 63 68 65 45  Min;.    pcacheE
6e10: 6e 66 6f 72 63 65 4d 61 78 50 61 67 65 28 29 3b  nforceMaxPage();
6e20: 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f 66  .  }.  sqlite3_f
6e30: 72 65 65 28 70 43 61 63 68 65 2d 3e 61 70 48 61  ree(pCache->apHa
6e40: 73 68 29 3b 0a 20 20 70 63 61 63 68 65 45 78 69  sh);.  pcacheExi
6e50: 74 4d 75 74 65 78 28 29 3b 0a 7d 0a 0a 0a 23 69  tMutex();.}...#i
6e60: 66 6e 64 65 66 20 4e 44 45 42 55 47 0a 2f 2a 20  fndef NDEBUG./* 
6e70: 0a 2a 2a 20 41 73 73 65 72 74 20 66 6c 61 67 73  .** Assert flags
6e80: 20 73 65 74 74 69 6e 67 73 20 6f 6e 20 61 6c 6c   settings on all
6e90: 20 70 61 67 65 73 2e 20 20 44 65 62 75 67 67 69   pages.  Debuggi
6ea0: 6e 67 20 6f 6e 6c 79 2e 0a 2a 2f 0a 76 6f 69 64  ng only..*/.void
6eb0: 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 41 73   sqlite3PcacheAs
6ec0: 73 65 72 74 46 6c 61 67 73 28 50 43 61 63 68 65  sertFlags(PCache
6ed0: 20 2a 70 43 61 63 68 65 2c 20 69 6e 74 20 74 72   *pCache, int tr
6ee0: 75 65 4d 61 73 6b 2c 20 69 6e 74 20 66 61 6c 73  ueMask, int fals
6ef0: 65 4d 61 73 6b 29 7b 0a 20 20 50 67 48 64 72 20  eMask){.  PgHdr 
6f00: 2a 70 3b 0a 20 20 66 6f 72 28 70 3d 70 43 61 63  *p;.  for(p=pCac
6f10: 68 65 2d 3e 70 44 69 72 74 79 3b 20 70 3b 20 70  he->pDirty; p; p
6f20: 3d 70 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20  =p->pNext){.    
6f30: 61 73 73 65 72 74 28 20 28 70 2d 3e 66 6c 61 67  assert( (p->flag
6f40: 73 26 74 72 75 65 4d 61 73 6b 29 3d 3d 74 72 75  s&trueMask)==tru
6f50: 65 4d 61 73 6b 20 29 3b 0a 20 20 20 20 61 73 73  eMask );.    ass
6f60: 65 72 74 28 20 28 70 2d 3e 66 6c 61 67 73 26 66  ert( (p->flags&f
6f70: 61 6c 73 65 4d 61 73 6b 29 3d 3d 30 20 29 3b 0a  alseMask)==0 );.
6f80: 20 20 7d 0a 20 20 66 6f 72 28 70 3d 70 43 61 63    }.  for(p=pCac
6f90: 68 65 2d 3e 70 43 6c 65 61 6e 3b 20 70 3b 20 70  he->pClean; p; p
6fa0: 3d 70 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20  =p->pNext){.    
6fb0: 61 73 73 65 72 74 28 20 28 70 2d 3e 66 6c 61 67  assert( (p->flag
6fc0: 73 26 74 72 75 65 4d 61 73 6b 29 3d 3d 74 72 75  s&trueMask)==tru
6fd0: 65 4d 61 73 6b 20 29 3b 0a 20 20 20 20 61 73 73  eMask );.    ass
6fe0: 65 72 74 28 20 28 70 2d 3e 66 6c 61 67 73 26 66  ert( (p->flags&f
6ff0: 61 6c 73 65 4d 61 73 6b 29 3d 3d 30 20 29 3b 0a  alseMask)==0 );.
7000: 20 20 7d 0a 7d 0a 23 65 6e 64 69 66 0a 0a 2f 2a    }.}.#endif../*
7010: 20 0a 2a 2a 20 44 69 73 63 61 72 64 20 74 68 65   .** Discard the
7020: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65   contents of the
7030: 20 63 61 63 68 65 2e 0a 2a 2f 0a 69 6e 74 20 73   cache..*/.int s
7040: 71 6c 69 74 65 33 50 63 61 63 68 65 43 6c 65 61  qlite3PcacheClea
7050: 72 28 50 43 61 63 68 65 20 2a 70 43 61 63 68 65  r(PCache *pCache
7060: 29 7b 0a 20 20 61 73 73 65 72 74 28 70 43 61 63  ){.  assert(pCac
7070: 68 65 2d 3e 6e 52 65 66 3d 3d 30 29 3b 0a 20 20  he->nRef==0);.  
7080: 70 63 61 63 68 65 45 6e 74 65 72 4d 75 74 65 78  pcacheEnterMutex
7090: 28 29 3b 0a 20 20 70 63 61 63 68 65 43 6c 65 61  ();.  pcacheClea
70a0: 72 28 70 43 61 63 68 65 29 3b 0a 20 20 70 63 61  r(pCache);.  pca
70b0: 63 68 65 45 78 69 74 4d 75 74 65 78 28 29 3b 0a  cheExitMutex();.
70c0: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
70d0: 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 65 72  OK;.}../*.** Mer
70e0: 67 65 20 74 77 6f 20 6c 69 73 74 73 20 6f 66 20  ge two lists of 
70f0: 70 61 67 65 73 20 63 6f 6e 6e 65 63 74 65 64 20  pages connected 
7100: 62 79 20 70 44 69 72 74 79 20 61 6e 64 20 69 6e  by pDirty and in
7110: 20 70 67 6e 6f 20 6f 72 64 65 72 2e 0a 2a 2a 20   pgno order..** 
7120: 44 6f 20 6e 6f 74 20 62 6f 74 68 20 66 69 78 69  Do not both fixi
7130: 6e 67 20 74 68 65 20 70 50 72 65 76 44 69 72 74  ng the pPrevDirt
7140: 79 20 70 6f 69 6e 74 65 72 73 2e 0a 2a 2f 0a 73  y pointers..*/.s
7150: 74 61 74 69 63 20 50 67 48 64 72 20 2a 70 63 61  tatic PgHdr *pca
7160: 63 68 65 4d 65 72 67 65 44 69 72 74 79 4c 69 73  cheMergeDirtyLis
7170: 74 28 50 67 48 64 72 20 2a 70 41 2c 20 50 67 48  t(PgHdr *pA, PgH
7180: 64 72 20 2a 70 42 29 7b 0a 20 20 50 67 48 64 72  dr *pB){.  PgHdr
7190: 20 72 65 73 75 6c 74 2c 20 2a 70 54 61 69 6c 3b   result, *pTail;
71a0: 0a 20 20 70 54 61 69 6c 20 3d 20 26 72 65 73 75  .  pTail = &resu
71b0: 6c 74 3b 0a 20 20 77 68 69 6c 65 28 20 70 41 20  lt;.  while( pA 
71c0: 26 26 20 70 42 20 29 7b 0a 20 20 20 20 69 66 28  && pB ){.    if(
71d0: 20 70 41 2d 3e 70 67 6e 6f 3c 70 42 2d 3e 70 67   pA->pgno<pB->pg
71e0: 6e 6f 20 29 7b 0a 20 20 20 20 20 20 70 54 61 69  no ){.      pTai
71f0: 6c 2d 3e 70 44 69 72 74 79 20 3d 20 70 41 3b 0a  l->pDirty = pA;.
7200: 20 20 20 20 20 20 70 54 61 69 6c 20 3d 20 70 41        pTail = pA
7210: 3b 0a 20 20 20 20 20 20 70 41 20 3d 20 70 41 2d  ;.      pA = pA-
7220: 3e 70 44 69 72 74 79 3b 0a 20 20 20 20 7d 65 6c  >pDirty;.    }el
7230: 73 65 7b 0a 20 20 20 20 20 20 70 54 61 69 6c 2d  se{.      pTail-
7240: 3e 70 44 69 72 74 79 20 3d 20 70 42 3b 0a 20 20  >pDirty = pB;.  
7250: 20 20 20 20 70 54 61 69 6c 20 3d 20 70 42 3b 0a      pTail = pB;.
7260: 20 20 20 20 20 20 70 42 20 3d 20 70 42 2d 3e 70        pB = pB->p
7270: 44 69 72 74 79 3b 0a 20 20 20 20 7d 0a 20 20 7d  Dirty;.    }.  }
7280: 0a 20 20 69 66 28 20 70 41 20 29 7b 0a 20 20 20  .  if( pA ){.   
7290: 20 70 54 61 69 6c 2d 3e 70 44 69 72 74 79 20 3d   pTail->pDirty =
72a0: 20 70 41 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28   pA;.  }else if(
72b0: 20 70 42 20 29 7b 0a 20 20 20 20 70 54 61 69 6c   pB ){.    pTail
72c0: 2d 3e 70 44 69 72 74 79 20 3d 20 70 42 3b 0a 20  ->pDirty = pB;. 
72d0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70 54 61 69   }else{.    pTai
72e0: 6c 2d 3e 70 44 69 72 74 79 20 3d 20 30 3b 0a 20  l->pDirty = 0;. 
72f0: 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 65 73 75   }.  return resu
7300: 6c 74 2e 70 44 69 72 74 79 3b 0a 7d 0a 0a 2f 2a  lt.pDirty;.}../*
7310: 0a 2a 2a 20 53 6f 72 74 20 74 68 65 20 6c 69 73  .** Sort the lis
7320: 74 20 6f 66 20 70 61 67 65 73 20 69 6e 20 61 63  t of pages in ac
7330: 63 65 6e 64 69 6e 67 20 6f 72 64 65 72 20 62 79  cending order by
7340: 20 70 67 6e 6f 2e 20 20 50 61 67 65 73 20 61 72   pgno.  Pages ar
7350: 65 0a 2a 2a 20 63 6f 6e 6e 65 63 74 65 64 20 62  e.** connected b
7360: 79 20 70 44 69 72 74 79 20 70 6f 69 6e 74 65 72  y pDirty pointer
7370: 73 2e 20 20 54 68 65 20 70 50 72 65 76 44 69 72  s.  The pPrevDir
7380: 74 79 20 70 6f 69 6e 74 65 72 73 20 61 72 65 0a  ty pointers are.
7390: 2a 2a 20 63 6f 72 72 75 70 74 65 64 20 62 79 20  ** corrupted by 
73a0: 74 68 69 73 20 73 6f 72 74 2e 0a 2a 2f 0a 23 64  this sort..*/.#d
73b0: 65 66 69 6e 65 20 4e 5f 53 4f 52 54 5f 42 55 43  efine N_SORT_BUC
73c0: 4b 45 54 5f 41 4c 4c 4f 43 20 32 35 0a 23 64 65  KET_ALLOC 25.#de
73d0: 66 69 6e 65 20 4e 5f 53 4f 52 54 5f 42 55 43 4b  fine N_SORT_BUCK
73e0: 45 54 20 20 20 20 20 20 20 32 35 0a 23 69 66 64  ET       25.#ifd
73f0: 65 66 20 53 51 4c 49 54 45 5f 54 45 53 54 0a 20  ef SQLITE_TEST. 
7400: 20 69 6e 74 20 73 71 6c 69 74 65 33 5f 70 61 67   int sqlite3_pag
7410: 65 72 5f 6e 5f 73 6f 72 74 5f 62 75 63 6b 65 74  er_n_sort_bucket
7420: 20 3d 20 30 3b 0a 20 20 23 75 6e 64 65 66 20 4e   = 0;.  #undef N
7430: 5f 53 4f 52 54 5f 42 55 43 4b 45 54 0a 20 20 23  _SORT_BUCKET.  #
7440: 64 65 66 69 6e 65 20 4e 5f 53 4f 52 54 5f 42 55  define N_SORT_BU
7450: 43 4b 45 54 20 5c 0a 20 20 20 28 73 71 6c 69 74  CKET \.   (sqlit
7460: 65 33 5f 70 61 67 65 72 5f 6e 5f 73 6f 72 74 5f  e3_pager_n_sort_
7470: 62 75 63 6b 65 74 3f 73 71 6c 69 74 65 33 5f 70  bucket?sqlite3_p
7480: 61 67 65 72 5f 6e 5f 73 6f 72 74 5f 62 75 63 6b  ager_n_sort_buck
7490: 65 74 3a 4e 5f 53 4f 52 54 5f 42 55 43 4b 45 54  et:N_SORT_BUCKET
74a0: 5f 41 4c 4c 4f 43 29 0a 23 65 6e 64 69 66 0a 73  _ALLOC).#endif.s
74b0: 74 61 74 69 63 20 50 67 48 64 72 20 2a 70 63 61  tatic PgHdr *pca
74c0: 63 68 65 53 6f 72 74 44 69 72 74 79 4c 69 73 74  cheSortDirtyList
74d0: 28 50 67 48 64 72 20 2a 70 49 6e 29 7b 0a 20 20  (PgHdr *pIn){.  
74e0: 50 67 48 64 72 20 2a 61 5b 4e 5f 53 4f 52 54 5f  PgHdr *a[N_SORT_
74f0: 42 55 43 4b 45 54 5f 41 4c 4c 4f 43 5d 2c 20 2a  BUCKET_ALLOC], *
7500: 70 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 6d 65  p;.  int i;.  me
7510: 6d 73 65 74 28 61 2c 20 30 2c 20 73 69 7a 65 6f  mset(a, 0, sizeo
7520: 66 28 61 29 29 3b 0a 20 20 77 68 69 6c 65 28 20  f(a));.  while( 
7530: 70 49 6e 20 29 7b 0a 20 20 20 20 70 20 3d 20 70  pIn ){.    p = p
7540: 49 6e 3b 0a 20 20 20 20 70 49 6e 20 3d 20 70 2d  In;.    pIn = p-
7550: 3e 70 44 69 72 74 79 3b 0a 20 20 20 20 70 2d 3e  >pDirty;.    p->
7560: 70 44 69 72 74 79 20 3d 20 30 3b 0a 20 20 20 20  pDirty = 0;.    
7570: 66 6f 72 28 69 3d 30 3b 20 69 3c 4e 5f 53 4f 52  for(i=0; i<N_SOR
7580: 54 5f 42 55 43 4b 45 54 2d 31 3b 20 69 2b 2b 29  T_BUCKET-1; i++)
7590: 7b 0a 20 20 20 20 20 20 69 66 28 20 61 5b 69 5d  {.      if( a[i]
75a0: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 61  ==0 ){.        a
75b0: 5b 69 5d 20 3d 20 70 3b 0a 20 20 20 20 20 20 20  [i] = p;.       
75c0: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 65   break;.      }e
75d0: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 70 20 3d  lse{.        p =
75e0: 20 70 63 61 63 68 65 4d 65 72 67 65 44 69 72 74   pcacheMergeDirt
75f0: 79 4c 69 73 74 28 61 5b 69 5d 2c 20 70 29 3b 0a  yList(a[i], p);.
7600: 20 20 20 20 20 20 20 20 61 5b 69 5d 20 3d 20 30          a[i] = 0
7610: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
7620: 20 20 20 20 69 66 28 20 69 3d 3d 4e 5f 53 4f 52      if( i==N_SOR
7630: 54 5f 42 55 43 4b 45 54 2d 31 20 29 7b 0a 20 20  T_BUCKET-1 ){.  
7640: 20 20 20 20 2f 2a 20 43 6f 76 65 72 61 67 65 3a      /* Coverage:
7650: 20 54 6f 20 67 65 74 20 68 65 72 65 2c 20 74 68   To get here, th
7660: 65 72 65 20 6e 65 65 64 20 74 6f 20 62 65 20 32  ere need to be 2
7670: 5e 28 4e 5f 53 4f 52 54 5f 42 55 43 4b 45 54 29  ^(N_SORT_BUCKET)
7680: 20 0a 20 20 20 20 20 20 2a 2a 20 65 6c 65 6d 65   .      ** eleme
7690: 6e 74 73 20 69 6e 20 74 68 65 20 69 6e 70 75 74  nts in the input
76a0: 20 6c 69 73 74 2e 20 54 68 69 73 20 69 73 20 70   list. This is p
76b0: 6f 73 73 69 62 6c 65 2c 20 62 75 74 20 69 6d 70  ossible, but imp
76c0: 72 61 63 74 69 63 61 6c 2e 0a 20 20 20 20 20 20  ractical..      
76d0: 2a 2a 20 54 65 73 74 69 6e 67 20 74 68 69 73 20  ** Testing this 
76e0: 6c 69 6e 65 20 69 73 20 74 68 65 20 70 6f 69 6e  line is the poin
76f0: 74 20 6f 66 20 67 6c 6f 62 61 6c 20 76 61 72 69  t of global vari
7700: 61 62 6c 65 0a 20 20 20 20 20 20 2a 2a 20 73 71  able.      ** sq
7710: 6c 69 74 65 33 5f 70 61 67 65 72 5f 6e 5f 73 6f  lite3_pager_n_so
7720: 72 74 5f 62 75 63 6b 65 74 2e 0a 20 20 20 20 20  rt_bucket..     
7730: 20 2a 2f 0a 20 20 20 20 20 20 61 5b 69 5d 20 3d   */.      a[i] =
7740: 20 70 63 61 63 68 65 4d 65 72 67 65 44 69 72 74   pcacheMergeDirt
7750: 79 4c 69 73 74 28 61 5b 69 5d 2c 20 70 29 3b 0a  yList(a[i], p);.
7760: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 70 20 3d 20      }.  }.  p = 
7770: 61 5b 30 5d 3b 0a 20 20 66 6f 72 28 69 3d 31 3b  a[0];.  for(i=1;
7780: 20 69 3c 4e 5f 53 4f 52 54 5f 42 55 43 4b 45 54   i<N_SORT_BUCKET
7790: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 70 20 3d 20  ; i++){.    p = 
77a0: 70 63 61 63 68 65 4d 65 72 67 65 44 69 72 74 79  pcacheMergeDirty
77b0: 4c 69 73 74 28 70 2c 20 61 5b 69 5d 29 3b 0a 20  List(p, a[i]);. 
77c0: 20 7d 0a 20 20 72 65 74 75 72 6e 20 70 3b 0a 7d   }.  return p;.}
77d0: 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61  ../*.** Return a
77e0: 20 6c 69 73 74 20 6f 66 20 61 6c 6c 20 64 69 72   list of all dir
77f0: 74 79 20 70 61 67 65 73 20 69 6e 20 74 68 65 20  ty pages in the 
7800: 63 61 63 68 65 2c 20 73 6f 72 74 65 64 20 62 79  cache, sorted by
7810: 20 70 61 67 65 20 6e 75 6d 62 65 72 2e 0a 2a 2f   page number..*/
7820: 0a 50 67 48 64 72 20 2a 73 71 6c 69 74 65 33 50  .PgHdr *sqlite3P
7830: 63 61 63 68 65 44 69 72 74 79 4c 69 73 74 28 50  cacheDirtyList(P
7840: 43 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b 0a  Cache *pCache){.
7850: 20 20 50 67 48 64 72 20 2a 70 3b 0a 20 20 66 6f    PgHdr *p;.  fo
7860: 72 28 70 3d 70 43 61 63 68 65 2d 3e 70 44 69 72  r(p=pCache->pDir
7870: 74 79 3b 20 70 3b 20 70 3d 70 2d 3e 70 4e 65 78  ty; p; p=p->pNex
7880: 74 29 7b 0a 20 20 20 20 70 2d 3e 70 44 69 72 74  t){.    p->pDirt
7890: 79 20 3d 20 70 2d 3e 70 4e 65 78 74 3b 0a 20 20  y = p->pNext;.  
78a0: 7d 0a 20 20 72 65 74 75 72 6e 20 70 63 61 63 68  }.  return pcach
78b0: 65 53 6f 72 74 44 69 72 74 79 4c 69 73 74 28 70  eSortDirtyList(p
78c0: 43 61 63 68 65 2d 3e 70 44 69 72 74 79 29 3b 0a  Cache->pDirty);.
78d0: 7d 0a 0a 2f 2a 20 0a 2a 2a 20 52 65 74 75 72 6e  }../* .** Return
78e0: 20 74 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65   the total numbe
78f0: 72 20 6f 66 20 6f 75 74 73 74 61 6e 64 69 6e 67  r of outstanding
7900: 20 70 61 67 65 20 72 65 66 65 72 65 6e 63 65 73   page references
7910: 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33  ..*/.int sqlite3
7920: 50 63 61 63 68 65 52 65 66 43 6f 75 6e 74 28 50  PcacheRefCount(P
7930: 43 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b 0a  Cache *pCache){.
7940: 20 20 72 65 74 75 72 6e 20 70 43 61 63 68 65 2d    return pCache-
7950: 3e 6e 52 65 66 3b 0a 7d 0a 0a 69 6e 74 20 73 71  >nRef;.}..int sq
7960: 6c 69 74 65 33 50 63 61 63 68 65 50 61 67 65 52  lite3PcachePageR
7970: 65 66 63 6f 75 6e 74 28 50 67 48 64 72 20 2a 70  efcount(PgHdr *p
7980: 29 7b 0a 20 20 72 65 74 75 72 6e 20 70 2d 3e 6e  ){.  return p->n
7990: 52 65 66 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 52  Ref;.}../* .** R
79a0: 65 74 75 72 6e 20 74 68 65 20 74 6f 74 61 6c 20  eturn the total 
79b0: 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20  number of pages 
79c0: 69 6e 20 74 68 65 20 63 61 63 68 65 2e 0a 2a 2f  in the cache..*/
79d0: 0a 69 6e 74 20 73 71 6c 69 74 65 33 50 63 61 63  .int sqlite3Pcac
79e0: 68 65 50 61 67 65 63 6f 75 6e 74 28 50 43 61 63  hePagecount(PCac
79f0: 68 65 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 61  he *pCache){.  a
7a00: 73 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e 6e  ssert( pCache->n
7a10: 50 61 67 65 3e 3d 30 20 29 3b 0a 20 20 72 65 74  Page>=0 );.  ret
7a20: 75 72 6e 20 70 43 61 63 68 65 2d 3e 6e 50 61 67  urn pCache->nPag
7a30: 65 3b 0a 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c  e;.}..#ifdef SQL
7a40: 49 54 45 5f 43 48 45 43 4b 5f 50 41 47 45 53 0a  ITE_CHECK_PAGES.
7a50: 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  /*.** This funct
7a60: 69 6f 6e 20 69 73 20 75 73 65 64 20 62 79 20 74  ion is used by t
7a70: 68 65 20 70 61 67 65 72 2e 63 20 6d 6f 64 75 6c  he pager.c modul
7a80: 65 20 74 6f 20 69 74 65 72 61 74 65 20 74 68 72  e to iterate thr
7a90: 6f 75 67 68 20 61 6c 6c 20 0a 2a 2a 20 70 61 67  ough all .** pag
7aa0: 65 73 20 69 6e 20 74 68 65 20 63 61 63 68 65 2e  es in the cache.
7ab0: 20 41 74 20 70 72 65 73 65 6e 74 2c 20 74 68 69   At present, thi
7ac0: 73 20 69 73 20 6f 6e 6c 79 20 72 65 71 75 69 72  s is only requir
7ad0: 65 64 20 69 66 20 74 68 65 0a 2a 2a 20 53 51 4c  ed if the.** SQL
7ae0: 49 54 45 5f 43 48 45 43 4b 5f 50 41 47 45 53 20  ITE_CHECK_PAGES 
7af0: 6d 61 63 72 6f 20 28 75 73 65 64 20 66 6f 72 20  macro (used for 
7b00: 64 65 62 75 67 67 69 6e 67 29 20 69 73 20 73 70  debugging) is sp
7b10: 65 63 69 66 69 65 64 2e 0a 2a 2f 0a 76 6f 69 64  ecified..*/.void
7b20: 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 49 74   sqlite3PcacheIt
7b30: 65 72 61 74 65 28 50 43 61 63 68 65 20 2a 70 43  erate(PCache *pC
7b40: 61 63 68 65 2c 20 76 6f 69 64 20 28 2a 78 49 74  ache, void (*xIt
7b50: 65 72 29 28 50 67 48 64 72 20 2a 29 29 7b 0a 20  er)(PgHdr *)){. 
7b60: 20 50 67 48 64 72 20 2a 70 3b 0a 20 20 66 6f 72   PgHdr *p;.  for
7b70: 28 70 3d 70 43 61 63 68 65 2d 3e 70 43 6c 65 61  (p=pCache->pClea
7b80: 6e 3b 20 70 3b 20 70 3d 70 2d 3e 70 4e 65 78 74  n; p; p=p->pNext
7b90: 29 7b 0a 20 20 20 20 78 49 74 65 72 28 70 29 3b  ){.    xIter(p);
7ba0: 0a 20 20 7d 0a 20 20 66 6f 72 28 70 3d 70 43 61  .  }.  for(p=pCa
7bb0: 63 68 65 2d 3e 70 44 69 72 74 79 3b 20 70 3b 20  che->pDirty; p; 
7bc0: 70 3d 70 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20  p=p->pNext){.   
7bd0: 20 78 49 74 65 72 28 70 29 3b 0a 20 20 7d 0a 7d   xIter(p);.  }.}
7be0: 0a 23 65 6e 64 69 66 0a 0a 2f 2a 20 0a 2a 2a 20  .#endif../* .** 
7bf0: 53 65 74 20 66 6c 61 67 73 20 6f 6e 20 61 6c 6c  Set flags on all
7c00: 20 70 61 67 65 73 20 69 6e 20 74 68 65 20 70 61   pages in the pa
7c10: 67 65 20 63 61 63 68 65 20 0a 2a 2f 0a 76 6f 69  ge cache .*/.voi
7c20: 64 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 43  d sqlite3PcacheC
7c30: 6c 65 61 72 46 6c 61 67 73 28 50 43 61 63 68 65  learFlags(PCache
7c40: 20 2a 70 43 61 63 68 65 2c 20 69 6e 74 20 6d 61   *pCache, int ma
7c50: 73 6b 29 7b 0a 20 20 50 67 48 64 72 20 2a 70 3b  sk){.  PgHdr *p;
7c60: 0a 0a 20 20 2f 2a 20 4f 62 74 61 69 6e 20 74 68  ..  /* Obtain th
7c70: 65 20 67 6c 6f 62 61 6c 20 6d 75 74 65 78 20 62  e global mutex b
7c80: 65 66 6f 72 65 20 6d 6f 64 69 66 79 69 6e 67 20  efore modifying 
7c90: 61 6e 79 20 50 67 48 64 72 2e 66 6c 61 67 73 20  any PgHdr.flags 
7ca0: 76 61 72 69 61 62 6c 65 73 20 0a 20 20 2a 2a 20  variables .  ** 
7cb0: 6f 72 20 74 72 61 76 65 72 73 69 6e 67 20 74 68  or traversing th
7cc0: 65 20 4c 52 55 20 6c 69 73 74 2e 0a 20 20 2a 2f  e LRU list..  */
7cd0: 20 0a 20 20 70 63 61 63 68 65 45 6e 74 65 72 4d   .  pcacheEnterM
7ce0: 75 74 65 78 28 29 3b 0a 0a 20 20 6d 61 73 6b 20  utex();..  mask 
7cf0: 3d 20 7e 6d 61 73 6b 3b 0a 20 20 66 6f 72 28 70  = ~mask;.  for(p
7d00: 3d 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 3b  =pCache->pDirty;
7d10: 20 70 3b 20 70 3d 70 2d 3e 70 4e 65 78 74 29 7b   p; p=p->pNext){
7d20: 0a 20 20 20 20 70 2d 3e 66 6c 61 67 73 20 26 3d  .    p->flags &=
7d30: 20 6d 61 73 6b 3b 0a 20 20 7d 0a 20 20 66 6f 72   mask;.  }.  for
7d40: 28 70 3d 70 43 61 63 68 65 2d 3e 70 43 6c 65 61  (p=pCache->pClea
7d50: 6e 3b 20 70 3b 20 70 3d 70 2d 3e 70 4e 65 78 74  n; p; p=p->pNext
7d60: 29 7b 0a 20 20 20 20 70 2d 3e 66 6c 61 67 73 20  ){.    p->flags 
7d70: 26 3d 20 6d 61 73 6b 3b 0a 20 20 7d 0a 0a 20 20  &= mask;.  }..  
7d80: 69 66 28 20 30 3d 3d 28 6d 61 73 6b 26 50 47 48  if( 0==(mask&PGH
7d90: 44 52 5f 4e 45 45 44 5f 53 59 4e 43 29 20 29 7b  DR_NEED_SYNC) ){
7da0: 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 70 53 79  .    pCache->pSy
7db0: 6e 63 65 64 20 3d 20 70 43 61 63 68 65 2d 3e 70  nced = pCache->p
7dc0: 44 69 72 74 79 54 61 69 6c 3b 0a 20 20 20 20 61  DirtyTail;.    a
7dd0: 73 73 65 72 74 28 20 21 70 43 61 63 68 65 2d 3e  ssert( !pCache->
7de0: 70 53 79 6e 63 65 64 20 7c 7c 20 28 70 43 61 63  pSynced || (pCac
7df0: 68 65 2d 3e 70 53 79 6e 63 65 64 2d 3e 66 6c 61  he->pSynced->fla
7e00: 67 73 26 50 47 48 44 52 5f 4e 45 45 44 5f 53 59  gs&PGHDR_NEED_SY
7e10: 4e 43 29 3d 3d 30 20 29 3b 0a 20 20 7d 0a 0a 20  NC)==0 );.  }.. 
7e20: 20 70 63 61 63 68 65 45 78 69 74 4d 75 74 65 78   pcacheExitMutex
7e30: 28 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 74  ();.}../*.** Set
7e40: 20 74 68 65 20 73 75 67 67 65 73 74 65 64 20 63   the suggested c
7e50: 61 63 68 65 2d 73 69 7a 65 20 76 61 6c 75 65 2e  ache-size value.
7e60: 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 50  .*/.int sqlite3P
7e70: 63 61 63 68 65 47 65 74 43 61 63 68 65 73 69 7a  cacheGetCachesiz
7e80: 65 28 50 43 61 63 68 65 20 2a 70 43 61 63 68 65  e(PCache *pCache
7e90: 29 7b 0a 20 20 72 65 74 75 72 6e 20 70 43 61 63  ){.  return pCac
7ea0: 68 65 2d 3e 6e 4d 61 78 3b 0a 7d 0a 0a 2f 2a 0a  he->nMax;.}../*.
7eb0: 2a 2a 20 53 65 74 20 74 68 65 20 73 75 67 67 65  ** Set the sugge
7ec0: 73 74 65 64 20 63 61 63 68 65 2d 73 69 7a 65 20  sted cache-size 
7ed0: 76 61 6c 75 65 2e 0a 2a 2f 0a 76 6f 69 64 20 73  value..*/.void s
7ee0: 71 6c 69 74 65 33 50 63 61 63 68 65 53 65 74 43  qlite3PcacheSetC
7ef0: 61 63 68 65 73 69 7a 65 28 50 43 61 63 68 65 20  achesize(PCache 
7f00: 2a 70 43 61 63 68 65 2c 20 69 6e 74 20 6d 78 50  *pCache, int mxP
7f10: 61 67 65 29 7b 0a 20 20 69 66 28 20 6d 78 50 61  age){.  if( mxPa
7f20: 67 65 3c 31 30 20 29 7b 0a 20 20 20 20 6d 78 50  ge<10 ){.    mxP
7f30: 61 67 65 20 3d 20 31 30 3b 0a 20 20 7d 0a 20 20  age = 10;.  }.  
7f40: 69 66 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72  if( pCache->bPur
7f50: 67 65 61 62 6c 65 20 29 7b 0a 20 20 20 20 70 63  geable ){.    pc
7f60: 61 63 68 65 45 6e 74 65 72 4d 75 74 65 78 28 29  acheEnterMutex()
7f70: 3b 0a 20 20 20 20 70 63 61 63 68 65 5f 67 2e 6e  ;.    pcache_g.n
7f80: 4d 61 78 50 61 67 65 20 2d 3d 20 70 43 61 63 68  MaxPage -= pCach
7f90: 65 2d 3e 6e 4d 61 78 3b 0a 20 20 20 20 70 63 61  e->nMax;.    pca
7fa0: 63 68 65 5f 67 2e 6e 4d 61 78 50 61 67 65 20 2b  che_g.nMaxPage +
7fb0: 3d 20 6d 78 50 61 67 65 3b 0a 20 20 20 20 70 63  = mxPage;.    pc
7fc0: 61 63 68 65 45 6e 66 6f 72 63 65 4d 61 78 50 61  acheEnforceMaxPa
7fd0: 67 65 28 29 3b 0a 20 20 20 20 70 63 61 63 68 65  ge();.    pcache
7fe0: 45 78 69 74 4d 75 74 65 78 28 29 3b 0a 20 20 7d  ExitMutex();.  }
7ff0: 0a 20 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 20  .  pCache->nMax 
8000: 3d 20 6d 78 50 61 67 65 3b 0a 7d 0a 0a 23 69 66  = mxPage;.}..#if
8010: 64 65 66 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c  def SQLITE_ENABL
8020: 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d  E_MEMORY_MANAGEM
8030: 45 4e 54 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66  ENT./*.** This f
8040: 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65  unction is calle
8050: 64 20 74 6f 20 66 72 65 65 20 73 75 70 65 72 66  d to free superf
8060: 6c 75 6f 75 73 20 64 79 6e 61 6d 69 63 61 6c 6c  luous dynamicall
8070: 79 20 61 6c 6c 6f 63 61 74 65 64 20 6d 65 6d 6f  y allocated memo
8080: 72 79 0a 2a 2a 20 68 65 6c 64 20 62 79 20 74 68  ry.** held by th
8090: 65 20 70 61 67 65 72 20 73 79 73 74 65 6d 2e 20  e pager system. 
80a0: 4d 65 6d 6f 72 79 20 69 6e 20 75 73 65 20 62 79  Memory in use by
80b0: 20 61 6e 79 20 53 51 4c 69 74 65 20 70 61 67 65   any SQLite page
80c0: 72 20 61 6c 6c 6f 63 61 74 65 64 0a 2a 2a 20 62  r allocated.** b
80d0: 79 20 74 68 65 20 63 75 72 72 65 6e 74 20 74 68  y the current th
80e0: 72 65 61 64 20 6d 61 79 20 62 65 20 73 71 6c 69  read may be sqli
80f0: 74 65 33 5f 66 72 65 65 28 29 65 64 2e 0a 2a 2a  te3_free()ed..**
8100: 0a 2a 2a 20 6e 52 65 71 20 69 73 20 74 68 65 20  .** nReq is the 
8110: 6e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20  number of bytes 
8120: 6f 66 20 6d 65 6d 6f 72 79 20 72 65 71 75 69 72  of memory requir
8130: 65 64 2e 20 4f 6e 63 65 20 74 68 69 73 20 6d 75  ed. Once this mu
8140: 63 68 20 68 61 73 0a 2a 2a 20 62 65 65 6e 20 72  ch has.** been r
8150: 65 6c 65 61 73 65 64 2c 20 74 68 65 20 66 75 6e  eleased, the fun
8160: 63 74 69 6f 6e 20 72 65 74 75 72 6e 73 2e 20 54  ction returns. T
8170: 68 65 20 72 65 74 75 72 6e 20 76 61 6c 75 65 20  he return value 
8180: 69 73 20 74 68 65 20 74 6f 74 61 6c 20 6e 75 6d  is the total num
8190: 62 65 72 20 0a 2a 2a 20 6f 66 20 62 79 74 65 73  ber .** of bytes
81a0: 20 6f 66 20 6d 65 6d 6f 72 79 20 72 65 6c 65 61   of memory relea
81b0: 73 65 64 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  sed..*/.int sqli
81c0: 74 65 33 50 63 61 63 68 65 52 65 6c 65 61 73 65  te3PcacheRelease
81d0: 4d 65 6d 6f 72 79 28 69 6e 74 20 6e 52 65 71 29  Memory(int nReq)
81e0: 7b 0a 20 20 69 6e 74 20 6e 46 72 65 65 20 3d 20  {.  int nFree = 
81f0: 30 3b 0a 20 20 69 66 28 20 70 63 61 63 68 65 5f  0;.  if( pcache_
8200: 67 2e 70 53 74 61 72 74 3d 3d 30 20 29 7b 0a 20  g.pStart==0 ){. 
8210: 20 20 20 50 67 48 64 72 20 2a 70 3b 0a 20 20 20     PgHdr *p;.   
8220: 20 70 63 61 63 68 65 45 6e 74 65 72 4d 75 74 65   pcacheEnterMute
8230: 78 28 29 3b 0a 20 20 20 20 77 68 69 6c 65 28 20  x();.    while( 
8240: 28 6e 52 65 71 3c 30 20 7c 7c 20 6e 46 72 65 65  (nReq<0 || nFree
8250: 3c 6e 52 65 71 29 20 26 26 20 28 70 3d 70 63 61  <nReq) && (p=pca
8260: 63 68 65 52 65 63 79 63 6c 65 50 61 67 65 28 29  cheRecyclePage()
8270: 29 20 29 7b 0a 20 20 20 20 20 20 6e 46 72 65 65  ) ){.      nFree
8280: 20 2b 3d 20 70 63 61 63 68 65 50 61 67 65 53 69   += pcachePageSi
8290: 7a 65 28 70 29 3b 0a 20 20 20 20 20 20 70 63 61  ze(p);.      pca
82a0: 63 68 65 50 61 67 65 46 72 65 65 28 70 29 3b 0a  chePageFree(p);.
82b0: 20 20 20 20 7d 0a 20 20 20 20 70 63 61 63 68 65      }.    pcache
82c0: 45 78 69 74 4d 75 74 65 78 28 29 3b 0a 20 20 7d  ExitMutex();.  }
82d0: 0a 20 20 72 65 74 75 72 6e 20 6e 46 72 65 65 3b  .  return nFree;
82e0: 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51 4c  .}.#endif /* SQL
82f0: 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52  ITE_ENABLE_MEMOR
8300: 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 20 2a 2f 0a  Y_MANAGEMENT */.
8310: 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 54  .#ifdef SQLITE_T
8320: 45 53 54 0a 76 6f 69 64 20 73 71 6c 69 74 65 33  EST.void sqlite3
8330: 50 63 61 63 68 65 53 74 61 74 73 28 0a 20 20 69  PcacheStats(.  i
8340: 6e 74 20 2a 70 6e 43 75 72 72 65 6e 74 2c 0a 20  nt *pnCurrent,. 
8350: 20 69 6e 74 20 2a 70 6e 4d 61 78 2c 0a 20 20 69   int *pnMax,.  i
8360: 6e 74 20 2a 70 6e 4d 69 6e 2c 0a 20 20 69 6e 74  nt *pnMin,.  int
8370: 20 2a 70 6e 52 65 63 79 63 6c 61 62 6c 65 0a 29   *pnRecyclable.)
8380: 7b 0a 20 20 50 67 48 64 72 20 2a 70 3b 0a 20 20  {.  PgHdr *p;.  
8390: 69 6e 74 20 6e 52 65 63 79 63 6c 61 62 6c 65 20  int nRecyclable 
83a0: 3d 20 30 3b 0a 20 20 66 6f 72 28 70 3d 70 63 61  = 0;.  for(p=pca
83b0: 63 68 65 5f 67 2e 70 4c 72 75 48 65 61 64 3b 20  che_g.pLruHead; 
83c0: 70 3b 20 70 3d 70 2d 3e 70 4e 65 78 74 4c 72 75  p; p=p->pNextLru
83d0: 29 7b 0a 20 20 20 20 6e 52 65 63 79 63 6c 61 62  ){.    nRecyclab
83e0: 6c 65 2b 2b 3b 0a 20 20 7d 0a 0a 20 20 2a 70 6e  le++;.  }..  *pn
83f0: 43 75 72 72 65 6e 74 20 3d 20 70 63 61 63 68 65  Current = pcache
8400: 5f 67 2e 6e 43 75 72 72 65 6e 74 50 61 67 65 3b  _g.nCurrentPage;
8410: 0a 20 20 2a 70 6e 4d 61 78 20 3d 20 70 63 61 63  .  *pnMax = pcac
8420: 68 65 5f 67 2e 6e 4d 61 78 50 61 67 65 3b 0a 20  he_g.nMaxPage;. 
8430: 20 2a 70 6e 4d 69 6e 20 3d 20 70 63 61 63 68 65   *pnMin = pcache
8440: 5f 67 2e 6e 4d 69 6e 50 61 67 65 3b 0a 20 20 2a  _g.nMinPage;.  *
8450: 70 6e 52 65 63 79 63 6c 61 62 6c 65 20 3d 20 6e  pnRecyclable = n
8460: 52 65 63 79 63 6c 61 62 6c 65 3b 0a 7d 0a 23 65  Recyclable;.}.#e
8470: 6e 64 69 66 0a                                   ndif.