/ Hex Artifact Content
Login

Artifact 3d547c392145113336d44b901e048b86ee6a4774:


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 36 20 32 30 30  che.c,v 1.36 200
01c0: 38 2f 31 31 2f 31 31 20 31 38 3a 34 33 3a 30 30  8/11/11 18:43:00
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 20 26 26 20 70 2d 3e 70 43 61 63 68 65 20   p && p->pCache 
3f00: 29 3b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69  );.  return sqli
3f10: 74 65 33 4d 61 6c 6c 6f 63 53 69 7a 65 28 70 29  te3MallocSize(p)
3f20: 3b 0a 7d 0a 23 65 6e 64 69 66 0a 0a 2f 2a 0a 2a  ;.}.#endif../*.*
3f30: 2a 20 41 74 74 65 6d 70 74 20 74 6f 20 27 72 65  * Attempt to 're
3f40: 63 79 63 6c 65 27 20 61 20 70 61 67 65 20 66 72  cycle' a page fr
3f50: 6f 6d 20 74 68 65 20 67 6c 6f 62 61 6c 20 4c 52  om the global LR
3f60: 55 20 6c 69 73 74 2e 20 4f 6e 6c 79 20 63 6c 65  U list. Only cle
3f70: 61 6e 2c 0a 2a 2a 20 75 6e 72 65 66 65 72 65 6e  an,.** unreferen
3f80: 63 65 64 20 70 61 67 65 73 20 66 72 6f 6d 20 70  ced pages from p
3f90: 75 72 67 65 61 62 6c 65 20 63 61 63 68 65 73 20  urgeable caches 
3fa0: 61 72 65 20 65 6c 69 67 69 62 6c 65 20 66 6f 72  are eligible for
3fb0: 20 72 65 63 79 63 6c 69 6e 67 2e 0a 2a 2a 0a 2a   recycling..**.*
3fc0: 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  * This function 
3fd0: 72 65 6d 6f 76 65 73 20 70 61 67 65 20 70 63 61  removes page pca
3fe0: 63 68 65 2e 70 4c 72 75 54 61 69 6c 20 66 72 6f  che.pLruTail fro
3ff0: 6d 20 74 68 65 20 67 6c 6f 62 61 6c 20 4c 52 55  m the global LRU
4000: 20 6c 69 73 74 2c 0a 2a 2a 20 61 6e 64 20 66 72   list,.** and fr
4010: 6f 6d 20 74 68 65 20 68 61 73 68 2d 74 61 62 6c  om the hash-tabl
4020: 65 20 61 6e 64 20 50 43 61 63 68 65 2e 70 43 6c  e and PCache.pCl
4030: 65 61 6e 20 6c 69 73 74 20 6f 66 20 74 68 65 20  ean list of the 
4040: 6f 77 6e 65 72 20 70 63 61 63 68 65 2e 0a 2a 2a  owner pcache..**
4050: 20 54 68 65 72 65 20 73 68 6f 75 6c 64 20 62 65   There should be
4060: 20 6e 6f 20 6f 74 68 65 72 20 72 65 66 65 72 65   no other refere
4070: 6e 63 65 73 20 74 6f 20 74 68 65 20 70 61 67 65  nces to the page
4080: 2e 0a 2a 2a 0a 2a 2a 20 41 20 70 6f 69 6e 74 65  ..**.** A pointe
4090: 72 20 74 6f 20 74 68 65 20 72 65 63 79 63 6c 65  r to the recycle
40a0: 64 20 70 61 67 65 20 69 73 20 72 65 74 75 72 6e  d page is return
40b0: 65 64 2c 20 6f 72 20 4e 55 4c 4c 20 69 66 20 6e  ed, or NULL if n
40c0: 6f 20 70 61 67 65 20 69 73 0a 2a 2a 20 65 6c 69  o page is.** eli
40d0: 67 69 62 6c 65 20 66 6f 72 20 72 65 63 79 63 6c  gible for recycl
40e0: 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 50  ing..*/.static P
40f0: 67 48 64 72 20 2a 70 63 61 63 68 65 52 65 63 79  gHdr *pcacheRecy
4100: 63 6c 65 50 61 67 65 28 76 6f 69 64 29 7b 0a 20  clePage(void){. 
4110: 20 50 67 48 64 72 20 2a 70 20 3d 20 30 3b 0a 20   PgHdr *p = 0;. 
4120: 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33   assert( sqlite3
4130: 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 63 61 63  _mutex_held(pcac
4140: 68 65 5f 67 2e 6d 75 74 65 78 29 20 29 3b 0a 0a  he_g.mutex) );..
4150: 20 20 69 66 28 20 28 70 3d 70 63 61 63 68 65 5f    if( (p=pcache_
4160: 67 2e 70 4c 72 75 54 61 69 6c 29 21 3d 30 20 29  g.pLruTail)!=0 )
4170: 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20 28 70  {.    assert( (p
4180: 2d 3e 66 6c 61 67 73 26 50 47 48 44 52 5f 44 49  ->flags&PGHDR_DI
4190: 52 54 59 29 3d 3d 30 20 29 3b 0a 20 20 20 20 70  RTY)==0 );.    p
41a0: 63 61 63 68 65 52 65 6d 6f 76 65 46 72 6f 6d 4c  cacheRemoveFromL
41b0: 72 75 4c 69 73 74 28 70 29 3b 0a 20 20 20 20 70  ruList(p);.    p
41c0: 63 61 63 68 65 52 65 6d 6f 76 65 46 72 6f 6d 48  cacheRemoveFromH
41d0: 61 73 68 28 70 29 3b 0a 20 20 20 20 70 63 61 63  ash(p);.    pcac
41e0: 68 65 52 65 6d 6f 76 65 46 72 6f 6d 4c 69 73 74  heRemoveFromList
41f0: 28 26 70 2d 3e 70 43 61 63 68 65 2d 3e 70 43 6c  (&p->pCache->pCl
4200: 65 61 6e 2c 20 70 29 3b 0a 20 20 7d 0a 0a 20 20  ean, p);.  }..  
4210: 72 65 74 75 72 6e 20 70 3b 0a 7d 0a 0a 2f 2a 0a  return p;.}../*.
4220: 2a 2a 20 4f 62 74 61 69 6e 20 73 70 61 63 65 20  ** Obtain space 
4230: 66 6f 72 20 61 20 70 61 67 65 2e 20 54 72 79 20  for a page. Try 
4240: 74 6f 20 72 65 63 79 63 6c 65 20 61 6e 20 6f 6c  to recycle an ol
4250: 64 20 70 61 67 65 20 69 66 20 74 68 65 20 6c 69  d page if the li
4260: 6d 69 74 20 6f 6e 20 74 68 65 20 0a 2a 2a 20 6e  mit on the .** n
4270: 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 68  umber of pages h
4280: 61 73 20 62 65 65 6e 20 72 65 61 63 68 65 64 2e  as been reached.
4290: 20 49 66 20 74 68 65 20 6c 69 6d 69 74 20 68 61   If the limit ha
42a0: 73 20 6e 6f 74 20 62 65 65 6e 20 72 65 61 63 68  s not been reach
42b0: 65 64 20 6f 72 0a 2a 2a 20 74 68 65 72 65 20 61  ed or.** there a
42c0: 72 65 20 6e 6f 20 70 61 67 65 73 20 65 6c 69 67  re no pages elig
42d0: 69 62 6c 65 20 66 6f 72 20 72 65 63 79 63 6c 69  ible for recycli
42e0: 6e 67 2c 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e  ng, allocate a n
42f0: 65 77 20 70 61 67 65 2e 0a 2a 2a 0a 2a 2a 20 52  ew page..**.** R
4300: 65 74 75 72 6e 20 61 20 70 6f 69 6e 74 65 72 20  eturn a pointer 
4310: 74 6f 20 74 68 65 20 6e 65 77 20 70 61 67 65 2c  to the new page,
4320: 20 6f 72 20 4e 55 4c 4c 20 69 66 20 61 6e 20 4f   or NULL if an O
4330: 4f 4d 20 63 6f 6e 64 69 74 69 6f 6e 20 6f 63 63  OM condition occ
4340: 75 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  urs..*/.static i
4350: 6e 74 20 70 63 61 63 68 65 52 65 63 79 63 6c 65  nt pcacheRecycle
4360: 4f 72 41 6c 6c 6f 63 28 50 43 61 63 68 65 20 2a  OrAlloc(PCache *
4370: 70 43 61 63 68 65 2c 20 50 67 48 64 72 20 2a 2a  pCache, PgHdr **
4380: 70 70 50 61 67 65 29 7b 0a 20 20 50 67 48 64 72  ppPage){.  PgHdr
4390: 20 2a 70 20 3d 20 30 3b 0a 0a 20 20 69 6e 74 20   *p = 0;..  int 
43a0: 73 7a 50 61 67 65 20 3d 20 70 43 61 63 68 65 2d  szPage = pCache-
43b0: 3e 73 7a 50 61 67 65 3b 0a 20 20 69 6e 74 20 73  >szPage;.  int s
43c0: 7a 45 78 74 72 61 20 3d 20 70 43 61 63 68 65 2d  zExtra = pCache-
43d0: 3e 73 7a 45 78 74 72 61 3b 0a 0a 20 20 61 73 73  >szExtra;..  ass
43e0: 65 72 74 28 20 70 63 61 63 68 65 5f 67 2e 69 73  ert( pcache_g.is
43f0: 49 6e 69 74 20 29 3b 0a 20 20 61 73 73 65 72 74  Init );.  assert
4400: 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f  ( sqlite3_mutex_
4410: 68 65 6c 64 28 70 63 61 63 68 65 5f 67 2e 6d 75  held(pcache_g.mu
4420: 74 65 78 29 20 29 3b 0a 0a 20 20 2a 70 70 50 61  tex) );..  *ppPa
4430: 67 65 20 3d 20 30 3b 0a 0a 20 20 2f 2a 20 49 66  ge = 0;..  /* If
4440: 20 77 65 20 68 61 76 65 20 72 65 61 63 68 65 64   we have reached
4450: 20 65 69 74 68 65 72 20 74 68 65 20 67 6c 6f 62   either the glob
4460: 61 6c 20 6f 72 20 74 68 65 20 6c 6f 63 61 6c 20  al or the local 
4470: 6c 69 6d 69 74 20 66 6f 72 20 0a 20 20 2a 2a 20  limit for .  ** 
4480: 70 69 6e 6e 65 64 2b 64 69 72 74 79 20 70 61 67  pinned+dirty pag
4490: 65 73 2c 20 61 6e 64 20 74 68 65 72 65 20 69 73  es, and there is
44a0: 20 61 74 20 6c 65 61 73 74 20 6f 6e 65 20 64 69   at least one di
44b0: 72 74 79 20 70 61 67 65 2c 0a 20 20 2a 2a 20 69  rty page,.  ** i
44c0: 6e 76 6f 6b 65 20 74 68 65 20 78 53 74 72 65 73  nvoke the xStres
44d0: 73 20 63 61 6c 6c 62 61 63 6b 20 74 6f 20 63 61  s callback to ca
44e0: 75 73 65 20 61 20 70 61 67 65 20 74 6f 20 62 65  use a page to be
44f0: 63 6f 6d 65 20 63 6c 65 61 6e 2e 0a 20 20 2a 2f  come clean..  */
4500: 0a 20 20 65 78 70 65 6e 73 69 76 65 5f 61 73 73  .  expensive_ass
4510: 65 72 74 28 20 70 43 61 63 68 65 2d 3e 6e 50 69  ert( pCache->nPi
4520: 6e 6e 65 64 3d 3d 70 63 61 63 68 65 50 69 6e 6e  nned==pcachePinn
4530: 65 64 43 6f 75 6e 74 28 70 43 61 63 68 65 29 20  edCount(pCache) 
4540: 29 3b 0a 20 20 65 78 70 65 6e 73 69 76 65 5f 61  );.  expensive_a
4550: 73 73 65 72 74 28 20 70 63 61 63 68 65 43 68 65  ssert( pcacheChe
4560: 63 6b 53 79 6e 63 65 64 28 70 43 61 63 68 65 29  ckSynced(pCache)
4570: 20 29 3b 0a 20 20 69 66 28 20 70 43 61 63 68 65   );.  if( pCache
4580: 2d 3e 78 53 74 72 65 73 73 0a 20 20 20 26 26 20  ->xStress.   && 
4590: 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 0a 20  pCache->pDirty. 
45a0: 20 20 26 26 20 28 70 43 61 63 68 65 2d 3e 6e 50    && (pCache->nP
45b0: 69 6e 6e 65 64 3e 3d 28 70 63 61 63 68 65 5f 67  inned>=(pcache_g
45c0: 2e 6e 4d 61 78 50 61 67 65 2b 70 43 61 63 68 65  .nMaxPage+pCache
45d0: 2d 3e 6e 4d 69 6e 2d 70 63 61 63 68 65 5f 67 2e  ->nMin-pcache_g.
45e0: 6e 4d 69 6e 50 61 67 65 29 0a 20 20 20 20 20 20  nMinPage).      
45f0: 20 20 20 20 20 7c 7c 20 70 43 61 63 68 65 2d 3e       || pCache->
4600: 6e 50 69 6e 6e 65 64 3e 3d 70 43 61 63 68 65 2d  nPinned>=pCache-
4610: 3e 6e 4d 61 78 29 0a 20 20 29 7b 0a 20 20 20 20  >nMax).  ){.    
4620: 50 67 48 64 72 20 2a 70 50 67 3b 0a 20 20 20 20  PgHdr *pPg;.    
4630: 61 73 73 65 72 74 28 70 43 61 63 68 65 2d 3e 70  assert(pCache->p
4640: 44 69 72 74 79 54 61 69 6c 29 3b 0a 0a 20 20 20  DirtyTail);..   
4650: 20 66 6f 72 28 70 50 67 3d 70 43 61 63 68 65 2d   for(pPg=pCache-
4660: 3e 70 53 79 6e 63 65 64 3b 20 0a 20 20 20 20 20  >pSynced; .     
4670: 20 20 20 70 50 67 20 26 26 20 28 70 50 67 2d 3e     pPg && (pPg->
4680: 6e 52 65 66 20 7c 7c 20 28 70 50 67 2d 3e 66 6c  nRef || (pPg->fl
4690: 61 67 73 26 50 47 48 44 52 5f 4e 45 45 44 5f 53  ags&PGHDR_NEED_S
46a0: 59 4e 43 29 29 3b 20 0a 20 20 20 20 20 20 20 20  YNC)); .        
46b0: 70 50 67 3d 70 50 67 2d 3e 70 50 72 65 76 0a 20  pPg=pPg->pPrev. 
46c0: 20 20 20 29 3b 0a 20 20 20 20 69 66 28 20 21 70     );.    if( !p
46d0: 50 67 20 29 7b 0a 20 20 20 20 20 20 66 6f 72 28  Pg ){.      for(
46e0: 70 50 67 3d 70 43 61 63 68 65 2d 3e 70 44 69 72  pPg=pCache->pDir
46f0: 74 79 54 61 69 6c 3b 20 70 50 67 20 26 26 20 70  tyTail; pPg && p
4700: 50 67 2d 3e 6e 52 65 66 3b 20 70 50 67 3d 70 50  Pg->nRef; pPg=pP
4710: 67 2d 3e 70 50 72 65 76 29 3b 0a 20 20 20 20 7d  g->pPrev);.    }
4720: 0a 20 20 20 20 69 66 28 20 70 50 67 20 29 7b 0a  .    if( pPg ){.
4730: 20 20 20 20 20 20 69 6e 74 20 72 63 3b 0a 20 20        int rc;.  
4740: 20 20 20 20 70 63 61 63 68 65 45 78 69 74 4d 75      pcacheExitMu
4750: 74 65 78 28 29 3b 0a 20 20 20 20 20 20 72 63 20  tex();.      rc 
4760: 3d 20 70 43 61 63 68 65 2d 3e 78 53 74 72 65 73  = pCache->xStres
4770: 73 28 70 43 61 63 68 65 2d 3e 70 53 74 72 65 73  s(pCache->pStres
4780: 73 2c 20 70 50 67 29 3b 0a 20 20 20 20 20 20 70  s, pPg);.      p
4790: 63 61 63 68 65 45 6e 74 65 72 4d 75 74 65 78 28  cacheEnterMutex(
47a0: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 21  );.      if( rc!
47b0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 72 63  =SQLITE_OK && rc
47c0: 21 3d 53 51 4c 49 54 45 5f 42 55 53 59 20 29 7b  !=SQLITE_BUSY ){
47d0: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
47e0: 72 63 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  rc;.      }.    
47f0: 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 65  }.  }..  /* If e
4800: 69 74 68 65 72 20 74 68 65 20 6c 6f 63 61 6c 20  ither the local 
4810: 6f 72 20 74 68 65 20 67 6c 6f 62 61 6c 20 70 61  or the global pa
4820: 67 65 20 6c 69 6d 69 74 20 68 61 73 20 62 65 65  ge limit has bee
4830: 6e 20 72 65 61 63 68 65 64 2c 20 0a 20 20 2a 2a  n reached, .  **
4840: 20 74 72 79 20 74 6f 20 72 65 63 79 63 6c 65 20   try to recycle 
4850: 61 20 70 61 67 65 2e 20 0a 20 20 2a 2f 0a 20 20  a page. .  */.  
4860: 69 66 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72  if( pCache->bPur
4870: 67 65 61 62 6c 65 20 26 26 20 28 70 43 61 63 68  geable && (pCach
4880: 65 2d 3e 6e 50 61 67 65 3e 3d 70 43 61 63 68 65  e->nPage>=pCache
4890: 2d 3e 6e 4d 61 78 2d 31 20 7c 7c 0a 20 20 20 20  ->nMax-1 ||.    
48a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
48b0: 20 20 20 20 20 20 20 20 20 70 63 61 63 68 65 5f           pcache_
48c0: 67 2e 6e 43 75 72 72 65 6e 74 50 61 67 65 3e 3d  g.nCurrentPage>=
48d0: 70 63 61 63 68 65 5f 67 2e 6e 4d 61 78 50 61 67  pcache_g.nMaxPag
48e0: 65 29 20 29 7b 0a 20 20 20 20 70 20 3d 20 70 63  e) ){.    p = pc
48f0: 61 63 68 65 52 65 63 79 63 6c 65 50 61 67 65 28  acheRecyclePage(
4900: 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20  );.  }..  /* If 
4910: 61 20 70 61 67 65 20 68 61 73 20 62 65 65 6e 20  a page has been 
4920: 72 65 63 79 63 6c 65 64 20 62 75 74 20 69 74 20  recycled but it 
4930: 69 73 20 74 68 65 20 77 72 6f 6e 67 20 73 69 7a  is the wrong siz
4940: 65 2c 20 66 72 65 65 20 69 74 2e 20 2a 2f 0a 20  e, free it. */. 
4950: 20 69 66 28 20 70 20 26 26 20 28 70 2d 3e 70 43   if( p && (p->pC
4960: 61 63 68 65 2d 3e 73 7a 50 61 67 65 21 3d 73 7a  ache->szPage!=sz
4970: 50 61 67 65 20 7c 7c 20 70 2d 3e 70 43 61 63 68  Page || p->pCach
4980: 65 2d 3e 73 7a 50 61 67 65 21 3d 73 7a 45 78 74  e->szPage!=szExt
4990: 72 61 29 20 29 7b 0a 20 20 20 20 70 63 61 63 68  ra) ){.    pcach
49a0: 65 50 61 67 65 46 72 65 65 28 70 29 3b 0a 20 20  ePageFree(p);.  
49b0: 20 20 70 20 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20    p = 0;.  }..  
49c0: 69 66 28 20 21 70 20 29 7b 0a 20 20 20 20 70 20  if( !p ){.    p 
49d0: 3d 20 70 63 61 63 68 65 50 61 67 65 41 6c 6c 6f  = pcachePageAllo
49e0: 63 28 70 43 61 63 68 65 29 3b 0a 20 20 7d 0a 0a  c(pCache);.  }..
49f0: 20 20 2a 70 70 50 61 67 65 20 3d 20 70 3b 0a 20    *ppPage = p;. 
4a00: 20 72 65 74 75 72 6e 20 28 70 3f 53 51 4c 49 54   return (p?SQLIT
4a10: 45 5f 4f 4b 3a 53 51 4c 49 54 45 5f 4e 4f 4d 45  E_OK:SQLITE_NOME
4a20: 4d 29 3b 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a  M);.}../********
4a30: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4a40: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4a50: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 47 65 6e 65  *********** Gene
4a60: 72 61 6c 20 49 6e 74 65 72 66 61 63 65 73 20 2a  ral Interfaces *
4a70: 2a 2a 2a 2a 2a 0a 2a 2a 0a 2a 2a 20 49 6e 69 74  *****.**.** Init
4a80: 69 61 6c 69 7a 65 20 61 6e 64 20 73 68 75 74 64  ialize and shutd
4a90: 6f 77 6e 20 74 68 65 20 70 61 67 65 20 63 61 63  own the page cac
4aa0: 68 65 20 73 75 62 73 79 73 74 65 6d 2e 20 4e 65  he subsystem. Ne
4ab0: 69 74 68 65 72 20 6f 66 20 74 68 65 73 65 20 0a  ither of these .
4ac0: 2a 2a 20 66 75 6e 63 74 69 6f 6e 73 20 61 72 65  ** functions are
4ad0: 20 74 68 72 65 61 64 73 61 66 65 2e 0a 2a 2f 0a   threadsafe..*/.
4ae0: 69 6e 74 20 73 71 6c 69 74 65 33 50 63 61 63 68  int sqlite3Pcach
4af0: 65 49 6e 69 74 69 61 6c 69 7a 65 28 76 6f 69 64  eInitialize(void
4b00: 29 7b 0a 20 20 61 73 73 65 72 74 28 20 70 63 61  ){.  assert( pca
4b10: 63 68 65 5f 67 2e 69 73 49 6e 69 74 3d 3d 30 20  che_g.isInit==0 
4b20: 29 3b 0a 20 20 6d 65 6d 73 65 74 28 26 70 63 61  );.  memset(&pca
4b30: 63 68 65 5f 67 2c 20 30 2c 20 73 69 7a 65 6f 66  che_g, 0, sizeof
4b40: 28 70 63 61 63 68 65 29 29 3b 0a 20 20 69 66 28  (pcache));.  if(
4b50: 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f   sqlite3GlobalCo
4b60: 6e 66 69 67 2e 62 43 6f 72 65 4d 75 74 65 78 20  nfig.bCoreMutex 
4b70: 29 7b 0a 20 20 20 20 2f 2a 20 4e 6f 20 6e 65 65  ){.    /* No nee
4b80: 64 20 74 6f 20 63 68 65 63 6b 20 74 68 65 20 72  d to check the r
4b90: 65 74 75 72 6e 20 76 61 6c 75 65 20 6f 66 20 73  eturn value of s
4ba0: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 61 6c 6c  qlite3_mutex_all
4bb0: 6f 63 28 29 2e 20 0a 20 20 20 20 2a 2a 20 41 6c  oc(). .    ** Al
4bc0: 6c 6f 63 61 74 69 6e 67 20 61 20 73 74 61 74 69  locating a stati
4bd0: 63 20 6d 75 74 65 78 20 63 61 6e 6e 6f 74 20 66  c mutex cannot f
4be0: 61 69 6c 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20  ail..    */.    
4bf0: 70 63 61 63 68 65 5f 67 2e 6d 75 74 65 78 20 3d  pcache_g.mutex =
4c00: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 61   sqlite3_mutex_a
4c10: 6c 6c 6f 63 28 53 51 4c 49 54 45 5f 4d 55 54 45  lloc(SQLITE_MUTE
4c20: 58 5f 53 54 41 54 49 43 5f 4c 52 55 29 3b 0a 20  X_STATIC_LRU);. 
4c30: 20 7d 0a 20 20 70 63 61 63 68 65 5f 67 2e 69 73   }.  pcache_g.is
4c40: 49 6e 69 74 20 3d 20 31 3b 0a 20 20 72 65 74 75  Init = 1;.  retu
4c50: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a  rn SQLITE_OK;.}.
4c60: 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63 61 63  void sqlite3Pcac
4c70: 68 65 53 68 75 74 64 6f 77 6e 28 76 6f 69 64 29  heShutdown(void)
4c80: 7b 0a 20 20 6d 65 6d 73 65 74 28 26 70 63 61 63  {.  memset(&pcac
4c90: 68 65 5f 67 2c 20 30 2c 20 73 69 7a 65 6f 66 28  he_g, 0, sizeof(
4ca0: 70 63 61 63 68 65 29 29 3b 0a 7d 0a 0a 2f 2a 0a  pcache));.}../*.
4cb0: 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 73 69  ** Return the si
4cc0: 7a 65 20 69 6e 20 62 79 74 65 73 20 6f 66 20 61  ze in bytes of a
4cd0: 20 50 43 61 63 68 65 20 6f 62 6a 65 63 74 2e 0a   PCache object..
4ce0: 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 50 63  */.int sqlite3Pc
4cf0: 61 63 68 65 53 69 7a 65 28 76 6f 69 64 29 7b 20  acheSize(void){ 
4d00: 72 65 74 75 72 6e 20 73 69 7a 65 6f 66 28 50 43  return sizeof(PC
4d10: 61 63 68 65 29 3b 20 7d 0a 0a 2f 2a 0a 2a 2a 20  ache); }../*.** 
4d20: 43 72 65 61 74 65 20 61 20 6e 65 77 20 50 43 61  Create a new PCa
4d30: 63 68 65 20 6f 62 6a 65 63 74 2e 20 20 53 74 6f  che object.  Sto
4d40: 72 61 67 65 20 73 70 61 63 65 20 74 6f 20 68 6f  rage space to ho
4d50: 6c 64 20 74 68 65 20 6f 62 6a 65 63 74 0a 2a 2a  ld the object.**
4d60: 20 68 61 73 20 61 6c 72 65 61 64 79 20 62 65 65   has already bee
4d70: 6e 20 61 6c 6c 6f 63 61 74 65 64 20 61 6e 64 20  n allocated and 
4d80: 69 73 20 70 61 73 73 65 64 20 69 6e 20 61 73 20  is passed in as 
4d90: 74 68 65 20 70 20 70 6f 69 6e 74 65 72 2e 0a 2a  the p pointer..*
4da0: 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63  /.void sqlite3Pc
4db0: 61 63 68 65 4f 70 65 6e 28 0a 20 20 69 6e 74 20  acheOpen(.  int 
4dc0: 73 7a 50 61 67 65 2c 20 20 20 20 20 20 20 20 20  szPage,         
4dd0: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65           /* Size
4de0: 20 6f 66 20 65 76 65 72 79 20 70 61 67 65 20 2a   of every page *
4df0: 2f 0a 20 20 69 6e 74 20 73 7a 45 78 74 72 61 2c  /.  int szExtra,
4e00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4e10: 20 2f 2a 20 45 78 74 72 61 20 73 70 61 63 65 20   /* Extra space 
4e20: 61 73 73 6f 63 69 61 74 65 64 20 77 69 74 68 20  associated with 
4e30: 65 61 63 68 20 70 61 67 65 20 2a 2f 0a 20 20 69  each page */.  i
4e40: 6e 74 20 62 50 75 72 67 65 61 62 6c 65 2c 20 20  nt bPurgeable,  
4e50: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
4e60: 72 75 65 20 69 66 20 70 61 67 65 73 20 61 72 65  rue if pages are
4e70: 20 6f 6e 20 62 61 63 6b 69 6e 67 20 73 74 6f 72   on backing stor
4e80: 65 20 2a 2f 0a 20 20 69 6e 74 20 28 2a 78 53 74  e */.  int (*xSt
4e90: 72 65 73 73 29 28 76 6f 69 64 2a 2c 50 67 48 64  ress)(void*,PgHd
4ea0: 72 2a 29 2c 2f 2a 20 43 61 6c 6c 20 74 6f 20 74  r*),/* Call to t
4eb0: 72 79 20 74 6f 20 6d 61 6b 65 20 70 61 67 65 73  ry to make pages
4ec0: 20 63 6c 65 61 6e 20 2a 2f 0a 20 20 76 6f 69 64   clean */.  void
4ed0: 20 2a 70 53 74 72 65 73 73 2c 20 20 20 20 20 20   *pStress,      
4ee0: 20 20 20 20 20 20 20 20 20 2f 2a 20 41 72 67 75           /* Argu
4ef0: 6d 65 6e 74 20 74 6f 20 78 53 74 72 65 73 73 20  ment to xStress 
4f00: 2a 2f 0a 20 20 50 43 61 63 68 65 20 2a 70 20 20  */.  PCache *p  
4f10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4f20: 20 20 2f 2a 20 50 72 65 61 6c 6c 6f 63 61 74 65    /* Preallocate
4f30: 64 20 73 70 61 63 65 20 66 6f 72 20 74 68 65 20  d space for the 
4f40: 50 43 61 63 68 65 20 2a 2f 0a 29 7b 0a 20 20 61  PCache */.){.  a
4f50: 73 73 65 72 74 28 20 70 63 61 63 68 65 5f 67 2e  ssert( pcache_g.
4f60: 69 73 49 6e 69 74 20 29 3b 0a 20 20 6d 65 6d 73  isInit );.  mems
4f70: 65 74 28 70 2c 20 30 2c 20 73 69 7a 65 6f 66 28  et(p, 0, sizeof(
4f80: 50 43 61 63 68 65 29 29 3b 0a 20 20 70 2d 3e 73  PCache));.  p->s
4f90: 7a 50 61 67 65 20 3d 20 73 7a 50 61 67 65 3b 0a  zPage = szPage;.
4fa0: 20 20 70 2d 3e 73 7a 45 78 74 72 61 20 3d 20 73    p->szExtra = s
4fb0: 7a 45 78 74 72 61 3b 0a 20 20 70 2d 3e 62 50 75  zExtra;.  p->bPu
4fc0: 72 67 65 61 62 6c 65 20 3d 20 62 50 75 72 67 65  rgeable = bPurge
4fd0: 61 62 6c 65 3b 0a 20 20 70 2d 3e 78 53 74 72 65  able;.  p->xStre
4fe0: 73 73 20 3d 20 78 53 74 72 65 73 73 3b 0a 20 20  ss = xStress;.  
4ff0: 70 2d 3e 70 53 74 72 65 73 73 20 3d 20 70 53 74  p->pStress = pSt
5000: 72 65 73 73 3b 0a 20 20 70 2d 3e 6e 4d 61 78 20  ress;.  p->nMax 
5010: 3d 20 31 30 30 3b 0a 20 20 70 2d 3e 6e 4d 69 6e  = 100;.  p->nMin
5020: 20 3d 20 31 30 3b 0a 0a 20 20 70 63 61 63 68 65   = 10;..  pcache
5030: 45 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a 20 20  EnterMutex();.  
5040: 69 66 28 20 62 50 75 72 67 65 61 62 6c 65 20 29  if( bPurgeable )
5050: 7b 0a 20 20 20 20 70 63 61 63 68 65 5f 67 2e 6e  {.    pcache_g.n
5060: 4d 61 78 50 61 67 65 20 2b 3d 20 70 2d 3e 6e 4d  MaxPage += p->nM
5070: 61 78 3b 0a 20 20 20 20 70 63 61 63 68 65 5f 67  ax;.    pcache_g
5080: 2e 6e 4d 69 6e 50 61 67 65 20 2b 3d 20 70 2d 3e  .nMinPage += p->
5090: 6e 4d 69 6e 3b 0a 20 20 7d 0a 0a 20 20 70 63 61  nMin;.  }..  pca
50a0: 63 68 65 45 78 69 74 4d 75 74 65 78 28 29 3b 0a  cheExitMutex();.
50b0: 7d 0a 0a 2f 2a 0a 2a 2a 20 43 68 61 6e 67 65 20  }../*.** Change 
50c0: 74 68 65 20 70 61 67 65 20 73 69 7a 65 20 66 6f  the page size fo
50d0: 72 20 50 43 61 63 68 65 20 6f 62 6a 65 63 74 2e  r PCache object.
50e0: 20 20 54 68 69 73 20 63 61 6e 20 6f 6e 6c 79 20    This can only 
50f0: 68 61 70 70 65 6e 0a 2a 2a 20 77 68 65 6e 20 74  happen.** when t
5100: 68 65 20 63 61 63 68 65 20 69 73 20 65 6d 70 74  he cache is empt
5110: 79 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74  y..*/.void sqlit
5120: 65 33 50 63 61 63 68 65 53 65 74 50 61 67 65 53  e3PcacheSetPageS
5130: 69 7a 65 28 50 43 61 63 68 65 20 2a 70 43 61 63  ize(PCache *pCac
5140: 68 65 2c 20 69 6e 74 20 73 7a 50 61 67 65 29 7b  he, int szPage){
5150: 0a 20 20 61 73 73 65 72 74 28 70 43 61 63 68 65  .  assert(pCache
5160: 2d 3e 6e 50 61 67 65 3d 3d 30 29 3b 0a 20 20 70  ->nPage==0);.  p
5170: 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 20 3d 20  Cache->szPage = 
5180: 73 7a 50 61 67 65 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  szPage;.}../*.**
5190: 20 54 72 79 20 74 6f 20 6f 62 74 61 69 6e 20 61   Try to obtain a
51a0: 20 70 61 67 65 20 66 72 6f 6d 20 74 68 65 20 63   page from the c
51b0: 61 63 68 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c  ache..*/.int sql
51c0: 69 74 65 33 50 63 61 63 68 65 46 65 74 63 68 28  ite3PcacheFetch(
51d0: 0a 20 20 50 43 61 63 68 65 20 2a 70 43 61 63 68  .  PCache *pCach
51e0: 65 2c 20 20 20 20 20 20 20 2f 2a 20 4f 62 74 61  e,       /* Obta
51f0: 69 6e 20 74 68 65 20 70 61 67 65 20 66 72 6f 6d  in the page from
5200: 20 74 68 69 73 20 63 61 63 68 65 20 2a 2f 0a 20   this cache */. 
5210: 20 50 67 6e 6f 20 70 67 6e 6f 2c 20 20 20 20 20   Pgno pgno,     
5220: 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65 20 6e         /* Page n
5230: 75 6d 62 65 72 20 74 6f 20 6f 62 74 61 69 6e 20  umber to obtain 
5240: 2a 2f 0a 20 20 69 6e 74 20 63 72 65 61 74 65 46  */.  int createF
5250: 6c 61 67 2c 20 20 20 20 20 20 20 2f 2a 20 49 66  lag,       /* If
5260: 20 74 72 75 65 2c 20 63 72 65 61 74 65 20 70 61   true, create pa
5270: 67 65 20 69 66 20 69 74 20 64 6f 65 73 20 6e 6f  ge if it does no
5280: 74 20 65 78 69 73 74 20 61 6c 72 65 61 64 79 20  t exist already 
5290: 2a 2f 0a 20 20 50 67 48 64 72 20 2a 2a 70 70 50  */.  PgHdr **ppP
52a0: 61 67 65 20 20 20 20 20 20 20 20 2f 2a 20 57 72  age        /* Wr
52b0: 69 74 65 20 74 68 65 20 70 61 67 65 20 68 65 72  ite the page her
52c0: 65 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63  e */.){.  int rc
52d0: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
52e0: 50 67 48 64 72 20 2a 70 50 61 67 65 20 3d 20 30  PgHdr *pPage = 0
52f0: 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70 63 61  ;..  assert( pca
5300: 63 68 65 5f 67 2e 69 73 49 6e 69 74 20 29 3b 0a  che_g.isInit );.
5310: 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65    assert( pCache
5320: 21 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28  !=0 );.  assert(
5330: 20 70 67 6e 6f 3e 30 20 29 3b 0a 20 20 65 78 70   pgno>0 );.  exp
5340: 65 6e 73 69 76 65 5f 61 73 73 65 72 74 28 20 70  ensive_assert( p
5350: 43 61 63 68 65 2d 3e 6e 50 69 6e 6e 65 64 3d 3d  Cache->nPinned==
5360: 70 63 61 63 68 65 50 69 6e 6e 65 64 43 6f 75 6e  pcachePinnedCoun
5370: 74 28 70 43 61 63 68 65 29 20 29 3b 0a 0a 20 20  t(pCache) );..  
5380: 70 63 61 63 68 65 45 6e 74 65 72 4d 75 74 65 78  pcacheEnterMutex
5390: 28 29 3b 0a 0a 20 20 2f 2a 20 53 65 61 72 63 68  ();..  /* Search
53a0: 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 20   the hash table 
53b0: 66 6f 72 20 74 68 65 20 72 65 71 75 65 73 74 65  for the requeste
53c0: 64 20 70 61 67 65 2e 20 45 78 69 74 20 65 61 72  d page. Exit ear
53d0: 6c 79 20 69 66 20 69 74 20 69 73 20 66 6f 75 6e  ly if it is foun
53e0: 64 2e 20 2a 2f 0a 20 20 69 66 28 20 70 43 61 63  d. */.  if( pCac
53f0: 68 65 2d 3e 61 70 48 61 73 68 20 29 7b 0a 20 20  he->apHash ){.  
5400: 20 20 75 33 32 20 68 20 3d 20 70 67 6e 6f 20 25    u32 h = pgno %
5410: 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3b 0a   pCache->nHash;.
5420: 20 20 20 20 66 6f 72 28 70 50 61 67 65 3d 70 43      for(pPage=pC
5430: 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b  ache->apHash[h];
5440: 20 70 50 61 67 65 3b 20 70 50 61 67 65 3d 70 50   pPage; pPage=pP
5450: 61 67 65 2d 3e 70 4e 65 78 74 48 61 73 68 29 7b  age->pNextHash){
5460: 0a 20 20 20 20 20 20 69 66 28 20 70 50 61 67 65  .      if( pPage
5470: 2d 3e 70 67 6e 6f 3d 3d 70 67 6e 6f 20 29 7b 0a  ->pgno==pgno ){.
5480: 20 20 20 20 20 20 20 20 69 66 28 20 70 50 61 67          if( pPag
5490: 65 2d 3e 6e 52 65 66 3d 3d 30 20 29 7b 0a 20 20  e->nRef==0 ){.  
54a0: 20 20 20 20 20 20 20 20 69 66 28 20 30 3d 3d 28          if( 0==(
54b0: 70 50 61 67 65 2d 3e 66 6c 61 67 73 26 50 47 48  pPage->flags&PGH
54c0: 44 52 5f 44 49 52 54 59 29 20 29 7b 0a 20 20 20  DR_DIRTY) ){.   
54d0: 20 20 20 20 20 20 20 20 20 70 63 61 63 68 65 52           pcacheR
54e0: 65 6d 6f 76 65 46 72 6f 6d 4c 72 75 4c 69 73 74  emoveFromLruList
54f0: 28 70 50 61 67 65 29 3b 0a 20 20 20 20 20 20 20  (pPage);.       
5500: 20 20 20 20 20 70 43 61 63 68 65 2d 3e 6e 50 69       pCache->nPi
5510: 6e 6e 65 64 2b 2b 3b 0a 20 20 20 20 20 20 20 20  nned++;.        
5520: 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 70 43    }.          pC
5530: 61 63 68 65 2d 3e 6e 52 65 66 2b 2b 3b 0a 20 20  ache->nRef++;.  
5540: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
5550: 70 50 61 67 65 2d 3e 6e 52 65 66 2b 2b 3b 0a 20  pPage->nRef++;. 
5560: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
5570: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a      }.    }.  }.
5580: 0a 20 20 69 66 28 20 21 70 50 61 67 65 20 26 26  .  if( !pPage &&
5590: 20 63 72 65 61 74 65 46 6c 61 67 20 29 7b 0a 20   createFlag ){. 
55a0: 20 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 6e     if( pCache->n
55b0: 48 61 73 68 3c 3d 70 43 61 63 68 65 2d 3e 6e 50  Hash<=pCache->nP
55c0: 61 67 65 20 29 7b 0a 20 20 20 20 20 20 72 63 20  age ){.      rc 
55d0: 3d 20 70 63 61 63 68 65 52 65 73 69 7a 65 48 61  = pcacheResizeHa
55e0: 73 68 28 70 43 61 63 68 65 2c 20 70 43 61 63 68  sh(pCache, pCach
55f0: 65 2d 3e 6e 48 61 73 68 3c 32 35 36 20 3f 20 32  e->nHash<256 ? 2
5600: 35 36 20 3a 20 70 43 61 63 68 65 2d 3e 6e 48 61  56 : pCache->nHa
5610: 73 68 2a 32 29 3b 0a 20 20 20 20 7d 0a 20 20 20  sh*2);.    }.   
5620: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
5630: 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d  OK ){.      rc =
5640: 20 70 63 61 63 68 65 52 65 63 79 63 6c 65 4f 72   pcacheRecycleOr
5650: 41 6c 6c 6f 63 28 70 43 61 63 68 65 2c 20 26 70  Alloc(pCache, &p
5660: 50 61 67 65 29 3b 0a 20 20 20 20 7d 0a 20 20 20  Page);.    }.   
5670: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
5680: 4f 4b 20 29 7b 0a 20 20 20 20 20 20 70 50 61 67  OK ){.      pPag
5690: 65 2d 3e 70 50 61 67 65 72 20 3d 20 30 3b 0a 20  e->pPager = 0;. 
56a0: 20 20 20 20 20 70 50 61 67 65 2d 3e 66 6c 61 67       pPage->flag
56b0: 73 20 3d 20 30 3b 0a 20 20 20 20 20 20 70 50 61  s = 0;.      pPa
56c0: 67 65 2d 3e 70 44 69 72 74 79 20 3d 20 30 3b 0a  ge->pDirty = 0;.
56d0: 20 20 20 20 20 20 70 50 61 67 65 2d 3e 70 67 6e        pPage->pgn
56e0: 6f 20 3d 20 70 67 6e 6f 3b 0a 20 20 20 20 20 20  o = pgno;.      
56f0: 70 50 61 67 65 2d 3e 70 43 61 63 68 65 20 3d 20  pPage->pCache = 
5700: 70 43 61 63 68 65 3b 0a 20 20 20 20 20 20 70 50  pCache;.      pP
5710: 61 67 65 2d 3e 6e 52 65 66 20 3d 20 31 3b 0a 20  age->nRef = 1;. 
5720: 20 20 20 20 20 70 43 61 63 68 65 2d 3e 6e 52 65       pCache->nRe
5730: 66 2b 2b 3b 0a 20 20 20 20 20 20 70 43 61 63 68  f++;.      pCach
5740: 65 2d 3e 6e 50 69 6e 6e 65 64 2b 2b 3b 0a 20 20  e->nPinned++;.  
5750: 20 20 20 20 70 63 61 63 68 65 41 64 64 54 6f 4c      pcacheAddToL
5760: 69 73 74 28 26 70 43 61 63 68 65 2d 3e 70 43 6c  ist(&pCache->pCl
5770: 65 61 6e 2c 20 70 50 61 67 65 29 3b 0a 20 20 20  ean, pPage);.   
5780: 20 20 20 70 63 61 63 68 65 41 64 64 54 6f 48 61     pcacheAddToHa
5790: 73 68 28 70 50 61 67 65 29 3b 0a 20 20 20 20 7d  sh(pPage);.    }
57a0: 0a 20 20 7d 0a 0a 20 20 70 63 61 63 68 65 45 78  .  }..  pcacheEx
57b0: 69 74 4d 75 74 65 78 28 29 3b 0a 0a 20 20 2a 70  itMutex();..  *p
57c0: 70 50 61 67 65 20 3d 20 70 50 61 67 65 3b 0a 20  pPage = pPage;. 
57d0: 20 65 78 70 65 6e 73 69 76 65 5f 61 73 73 65 72   expensive_asser
57e0: 74 28 20 70 43 61 63 68 65 2d 3e 6e 50 69 6e 6e  t( pCache->nPinn
57f0: 65 64 3d 3d 70 63 61 63 68 65 50 69 6e 6e 65 64  ed==pcachePinned
5800: 43 6f 75 6e 74 28 70 43 61 63 68 65 29 20 29 3b  Count(pCache) );
5810: 0a 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65  .  assert( pPage
5820: 20 7c 7c 20 21 63 72 65 61 74 65 46 6c 61 67 20   || !createFlag 
5830: 7c 7c 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  || rc!=SQLITE_OK
5840: 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   );.  return rc;
5850: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65 72 65 66 65  .}../*.** Derefe
5860: 72 65 6e 63 65 20 61 20 70 61 67 65 2e 20 20 57  rence a page.  W
5870: 68 65 6e 20 74 68 65 20 72 65 66 65 72 65 6e 63  hen the referenc
5880: 65 20 63 6f 75 6e 74 20 72 65 61 63 68 65 73 20  e count reaches 
5890: 7a 65 72 6f 2c 0a 2a 2a 20 6d 6f 76 65 20 74 68  zero,.** move th
58a0: 65 20 70 61 67 65 20 74 6f 20 74 68 65 20 4c 52  e page to the LR
58b0: 55 20 6c 69 73 74 20 69 66 20 69 74 20 69 73 20  U list if it is 
58c0: 63 6c 65 61 6e 2e 0a 2a 2f 0a 76 6f 69 64 20 73  clean..*/.void s
58d0: 71 6c 69 74 65 33 50 63 61 63 68 65 52 65 6c 65  qlite3PcacheRele
58e0: 61 73 65 28 50 67 48 64 72 20 2a 70 29 7b 0a 20  ase(PgHdr *p){. 
58f0: 20 61 73 73 65 72 74 28 20 70 2d 3e 6e 52 65 66   assert( p->nRef
5900: 3e 30 20 29 3b 0a 20 20 70 2d 3e 6e 52 65 66 2d  >0 );.  p->nRef-
5910: 2d 3b 0a 20 20 69 66 28 20 70 2d 3e 6e 52 65 66  -;.  if( p->nRef
5920: 3d 3d 30 20 29 7b 0a 20 20 20 20 50 43 61 63 68  ==0 ){.    PCach
5930: 65 20 2a 70 43 61 63 68 65 20 3d 20 70 2d 3e 70  e *pCache = p->p
5940: 43 61 63 68 65 3b 0a 20 20 20 20 70 43 61 63 68  Cache;.    pCach
5950: 65 2d 3e 6e 52 65 66 2d 2d 3b 0a 20 20 20 20 69  e->nRef--;.    i
5960: 66 28 20 28 70 2d 3e 66 6c 61 67 73 26 50 47 48  f( (p->flags&PGH
5970: 44 52 5f 44 49 52 54 59 29 3d 3d 30 20 29 7b 0a  DR_DIRTY)==0 ){.
5980: 20 20 20 20 20 20 70 43 61 63 68 65 2d 3e 6e 50        pCache->nP
5990: 69 6e 6e 65 64 2d 2d 3b 0a 20 20 20 20 20 20 70  inned--;.      p
59a0: 63 61 63 68 65 45 6e 74 65 72 4d 75 74 65 78 28  cacheEnterMutex(
59b0: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70 63 61  );.      if( pca
59c0: 63 68 65 5f 67 2e 6e 43 75 72 72 65 6e 74 50 61  che_g.nCurrentPa
59d0: 67 65 3e 70 63 61 63 68 65 5f 67 2e 6e 4d 61 78  ge>pcache_g.nMax
59e0: 50 61 67 65 20 29 7b 0a 20 20 20 20 20 20 20 20  Page ){.        
59f0: 70 63 61 63 68 65 52 65 6d 6f 76 65 46 72 6f 6d  pcacheRemoveFrom
5a00: 4c 69 73 74 28 26 70 43 61 63 68 65 2d 3e 70 43  List(&pCache->pC
5a10: 6c 65 61 6e 2c 20 70 29 3b 0a 20 20 20 20 20 20  lean, p);.      
5a20: 20 20 70 63 61 63 68 65 52 65 6d 6f 76 65 46 72    pcacheRemoveFr
5a30: 6f 6d 48 61 73 68 28 70 29 3b 0a 20 20 20 20 20  omHash(p);.     
5a40: 20 20 20 70 63 61 63 68 65 50 61 67 65 46 72 65     pcachePageFre
5a50: 65 28 70 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73  e(p);.      }els
5a60: 65 7b 0a 20 20 20 20 20 20 20 20 70 63 61 63 68  e{.        pcach
5a70: 65 41 64 64 54 6f 4c 72 75 4c 69 73 74 28 70 29  eAddToLruList(p)
5a80: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
5a90: 70 63 61 63 68 65 45 78 69 74 4d 75 74 65 78 28  pcacheExitMutex(
5aa0: 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  );.    }else{.  
5ab0: 20 20 20 20 2f 2a 20 4d 6f 76 65 20 74 68 65 20      /* Move the 
5ac0: 70 61 67 65 20 74 6f 20 74 68 65 20 68 65 61 64  page to the head
5ad0: 20 6f 66 20 74 68 65 20 63 61 63 68 65 73 20 64   of the caches d
5ae0: 69 72 74 79 20 6c 69 73 74 2e 20 2a 2f 0a 20 20  irty list. */.  
5af0: 20 20 20 20 70 63 61 63 68 65 52 65 6d 6f 76 65      pcacheRemove
5b00: 46 72 6f 6d 4c 69 73 74 28 26 70 43 61 63 68 65  FromList(&pCache
5b10: 2d 3e 70 44 69 72 74 79 2c 20 70 29 3b 0a 20 20  ->pDirty, p);.  
5b20: 20 20 20 20 70 63 61 63 68 65 41 64 64 54 6f 4c      pcacheAddToL
5b30: 69 73 74 28 26 70 43 61 63 68 65 2d 3e 70 44 69  ist(&pCache->pDi
5b40: 72 74 79 2c 20 70 29 3b 0a 20 20 20 20 7d 0a 20  rty, p);.    }. 
5b50: 20 7d 0a 7d 0a 0a 76 6f 69 64 20 73 71 6c 69 74   }.}..void sqlit
5b60: 65 33 50 63 61 63 68 65 52 65 66 28 50 67 48 64  e3PcacheRef(PgHd
5b70: 72 20 2a 70 29 7b 0a 20 20 61 73 73 65 72 74 28  r *p){.  assert(
5b80: 70 2d 3e 6e 52 65 66 3e 30 29 3b 0a 20 20 70 2d  p->nRef>0);.  p-
5b90: 3e 6e 52 65 66 2b 2b 3b 0a 7d 0a 0a 2f 2a 0a 2a  >nRef++;.}../*.*
5ba0: 2a 20 44 72 6f 70 20 61 20 70 61 67 65 20 66 72  * Drop a page fr
5bb0: 6f 6d 20 74 68 65 20 63 61 63 68 65 2e 20 54 68  om the cache. Th
5bc0: 65 72 65 20 6d 75 73 74 20 62 65 20 65 78 61 63  ere must be exac
5bd0: 74 6c 79 20 6f 6e 65 20 72 65 66 65 72 65 6e 63  tly one referenc
5be0: 65 20 74 6f 20 74 68 65 0a 2a 2a 20 70 61 67 65  e to the.** page
5bf0: 2e 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  . This function 
5c00: 64 65 6c 65 74 65 73 20 74 68 61 74 20 72 65 66  deletes that ref
5c10: 65 72 65 6e 63 65 2c 20 73 6f 20 61 66 74 65 72  erence, so after
5c20: 20 69 74 20 72 65 74 75 72 6e 73 20 74 68 65 0a   it returns the.
5c30: 2a 2a 20 70 61 67 65 20 70 6f 69 6e 74 65 64 20  ** page pointed 
5c40: 74 6f 20 62 79 20 70 20 69 73 20 69 6e 76 61 6c  to by p is inval
5c50: 69 64 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69  id..*/.void sqli
5c60: 74 65 33 50 63 61 63 68 65 44 72 6f 70 28 50 67  te3PcacheDrop(Pg
5c70: 48 64 72 20 2a 70 29 7b 0a 20 20 50 43 61 63 68  Hdr *p){.  PCach
5c80: 65 20 2a 70 43 61 63 68 65 3b 0a 20 20 61 73 73  e *pCache;.  ass
5c90: 65 72 74 28 20 70 2d 3e 6e 52 65 66 3d 3d 31 20  ert( p->nRef==1 
5ca0: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 30 3d 3d  );.  assert( 0==
5cb0: 28 70 2d 3e 66 6c 61 67 73 26 50 47 48 44 52 5f  (p->flags&PGHDR_
5cc0: 44 49 52 54 59 29 20 29 3b 0a 20 20 70 43 61 63  DIRTY) );.  pCac
5cd0: 68 65 20 3d 20 70 2d 3e 70 43 61 63 68 65 3b 0a  he = p->pCache;.
5ce0: 20 20 70 43 61 63 68 65 2d 3e 6e 52 65 66 2d 2d    pCache->nRef--
5cf0: 3b 0a 20 20 70 43 61 63 68 65 2d 3e 6e 50 69 6e  ;.  pCache->nPin
5d00: 6e 65 64 2d 2d 3b 0a 20 20 70 63 61 63 68 65 45  ned--;.  pcacheE
5d10: 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a 20 20 70  nterMutex();.  p
5d20: 63 61 63 68 65 52 65 6d 6f 76 65 46 72 6f 6d 4c  cacheRemoveFromL
5d30: 69 73 74 28 26 70 43 61 63 68 65 2d 3e 70 43 6c  ist(&pCache->pCl
5d40: 65 61 6e 2c 20 70 29 3b 0a 20 20 70 63 61 63 68  ean, p);.  pcach
5d50: 65 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73 68 28  eRemoveFromHash(
5d60: 70 29 3b 0a 20 20 70 63 61 63 68 65 50 61 67 65  p);.  pcachePage
5d70: 46 72 65 65 28 70 29 3b 0a 20 20 70 63 61 63 68  Free(p);.  pcach
5d80: 65 45 78 69 74 4d 75 74 65 78 28 29 3b 0a 7d 0a  eExitMutex();.}.
5d90: 0a 2f 2a 0a 2a 2a 20 4d 61 6b 65 20 73 75 72 65  ./*.** Make sure
5da0: 20 74 68 65 20 70 61 67 65 20 69 73 20 6d 61 72   the page is mar
5db0: 6b 65 64 20 61 73 20 64 69 72 74 79 2e 20 20 49  ked as dirty.  I
5dc0: 66 20 69 74 20 69 73 6e 27 74 20 64 69 72 74 79  f it isn't dirty
5dd0: 20 61 6c 72 65 61 64 79 2c 0a 2a 2a 20 6d 61 6b   already,.** mak
5de0: 65 20 69 74 20 73 6f 2e 0a 2a 2f 0a 76 6f 69 64  e it so..*/.void
5df0: 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 4d 61   sqlite3PcacheMa
5e00: 6b 65 44 69 72 74 79 28 50 67 48 64 72 20 2a 70  keDirty(PgHdr *p
5e10: 29 7b 0a 20 20 50 43 61 63 68 65 20 2a 70 43 61  ){.  PCache *pCa
5e20: 63 68 65 3b 0a 20 20 70 2d 3e 66 6c 61 67 73 20  che;.  p->flags 
5e30: 26 3d 20 7e 50 47 48 44 52 5f 44 4f 4e 54 5f 57  &= ~PGHDR_DONT_W
5e40: 52 49 54 45 3b 0a 20 20 69 66 28 20 70 2d 3e 66  RITE;.  if( p->f
5e50: 6c 61 67 73 20 26 20 50 47 48 44 52 5f 44 49 52  lags & PGHDR_DIR
5e60: 54 59 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 61  TY ) return;.  a
5e70: 73 73 65 72 74 28 20 28 70 2d 3e 66 6c 61 67 73  ssert( (p->flags
5e80: 20 26 20 50 47 48 44 52 5f 44 49 52 54 59 29 3d   & PGHDR_DIRTY)=
5e90: 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  =0 );.  assert( 
5ea0: 70 2d 3e 6e 52 65 66 3e 30 20 29 3b 0a 20 20 70  p->nRef>0 );.  p
5eb0: 43 61 63 68 65 20 3d 20 70 2d 3e 70 43 61 63 68  Cache = p->pCach
5ec0: 65 3b 0a 20 20 70 63 61 63 68 65 45 6e 74 65 72  e;.  pcacheEnter
5ed0: 4d 75 74 65 78 28 29 3b 0a 20 20 70 63 61 63 68  Mutex();.  pcach
5ee0: 65 52 65 6d 6f 76 65 46 72 6f 6d 4c 69 73 74 28  eRemoveFromList(
5ef0: 26 70 43 61 63 68 65 2d 3e 70 43 6c 65 61 6e 2c  &pCache->pClean,
5f00: 20 70 29 3b 0a 20 20 70 63 61 63 68 65 41 64 64   p);.  pcacheAdd
5f10: 54 6f 4c 69 73 74 28 26 70 43 61 63 68 65 2d 3e  ToList(&pCache->
5f20: 70 44 69 72 74 79 2c 20 70 29 3b 0a 20 20 70 63  pDirty, p);.  pc
5f30: 61 63 68 65 45 78 69 74 4d 75 74 65 78 28 29 3b  acheExitMutex();
5f40: 0a 20 20 70 2d 3e 66 6c 61 67 73 20 7c 3d 20 50  .  p->flags |= P
5f50: 47 48 44 52 5f 44 49 52 54 59 3b 0a 7d 0a 0a 73  GHDR_DIRTY;.}..s
5f60: 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68  tatic void pcach
5f70: 65 4d 61 6b 65 43 6c 65 61 6e 28 50 67 48 64 72  eMakeClean(PgHdr
5f80: 20 2a 70 29 7b 0a 20 20 50 43 61 63 68 65 20 2a   *p){.  PCache *
5f90: 70 43 61 63 68 65 20 3d 20 70 2d 3e 70 43 61 63  pCache = p->pCac
5fa0: 68 65 3b 0a 20 20 61 73 73 65 72 74 28 20 70 2d  he;.  assert( p-
5fb0: 3e 66 6c 61 67 73 20 26 20 50 47 48 44 52 5f 44  >flags & PGHDR_D
5fc0: 49 52 54 59 20 29 3b 0a 20 20 70 63 61 63 68 65  IRTY );.  pcache
5fd0: 52 65 6d 6f 76 65 46 72 6f 6d 4c 69 73 74 28 26  RemoveFromList(&
5fe0: 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 2c 20  pCache->pDirty, 
5ff0: 70 29 3b 0a 20 20 70 63 61 63 68 65 41 64 64 54  p);.  pcacheAddT
6000: 6f 4c 69 73 74 28 26 70 43 61 63 68 65 2d 3e 70  oList(&pCache->p
6010: 43 6c 65 61 6e 2c 20 70 29 3b 0a 20 20 70 2d 3e  Clean, p);.  p->
6020: 66 6c 61 67 73 20 26 3d 20 7e 50 47 48 44 52 5f  flags &= ~PGHDR_
6030: 44 49 52 54 59 3b 0a 20 20 69 66 28 20 70 2d 3e  DIRTY;.  if( p->
6040: 6e 52 65 66 3d 3d 30 20 29 7b 0a 20 20 20 20 70  nRef==0 ){.    p
6050: 63 61 63 68 65 41 64 64 54 6f 4c 72 75 4c 69 73  cacheAddToLruLis
6060: 74 28 70 29 3b 0a 20 20 20 20 70 43 61 63 68 65  t(p);.    pCache
6070: 2d 3e 6e 50 69 6e 6e 65 64 2d 2d 3b 0a 20 20 7d  ->nPinned--;.  }
6080: 0a 20 20 65 78 70 65 6e 73 69 76 65 5f 61 73 73  .  expensive_ass
6090: 65 72 74 28 20 70 43 61 63 68 65 2d 3e 6e 50 69  ert( pCache->nPi
60a0: 6e 6e 65 64 3d 3d 70 63 61 63 68 65 50 69 6e 6e  nned==pcachePinn
60b0: 65 64 43 6f 75 6e 74 28 70 43 61 63 68 65 29 20  edCount(pCache) 
60c0: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6b 65  );.}../*.** Make
60d0: 20 73 75 72 65 20 74 68 65 20 70 61 67 65 20 69   sure the page i
60e0: 73 20 6d 61 72 6b 65 64 20 61 73 20 63 6c 65 61  s marked as clea
60f0: 6e 2e 20 20 49 66 20 69 74 20 69 73 6e 27 74 20  n.  If it isn't 
6100: 63 6c 65 61 6e 20 61 6c 72 65 61 64 79 2c 0a 2a  clean already,.*
6110: 2a 20 6d 61 6b 65 20 69 74 20 73 6f 2e 0a 2a 2f  * make it so..*/
6120: 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63 61  .void sqlite3Pca
6130: 63 68 65 4d 61 6b 65 43 6c 65 61 6e 28 50 67 48  cheMakeClean(PgH
6140: 64 72 20 2a 70 29 7b 0a 20 20 69 66 28 20 28 70  dr *p){.  if( (p
6150: 2d 3e 66 6c 61 67 73 20 26 20 50 47 48 44 52 5f  ->flags & PGHDR_
6160: 44 49 52 54 59 29 20 29 7b 0a 20 20 20 20 70 63  DIRTY) ){.    pc
6170: 61 63 68 65 45 6e 74 65 72 4d 75 74 65 78 28 29  acheEnterMutex()
6180: 3b 0a 20 20 20 20 70 63 61 63 68 65 4d 61 6b 65  ;.    pcacheMake
6190: 43 6c 65 61 6e 28 70 29 3b 0a 20 20 20 20 70 63  Clean(p);.    pc
61a0: 61 63 68 65 45 78 69 74 4d 75 74 65 78 28 29 3b  acheExitMutex();
61b0: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61  .  }.}../*.** Ma
61c0: 6b 65 20 65 76 65 72 79 20 70 61 67 65 20 69 6e  ke every page in
61d0: 20 74 68 65 20 63 61 63 68 65 20 63 6c 65 61 6e   the cache clean
61e0: 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
61f0: 33 50 63 61 63 68 65 43 6c 65 61 6e 41 6c 6c 28  3PcacheCleanAll(
6200: 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b  PCache *pCache){
6210: 0a 20 20 50 67 48 64 72 20 2a 70 3b 0a 20 20 70  .  PgHdr *p;.  p
6220: 63 61 63 68 65 45 6e 74 65 72 4d 75 74 65 78 28  cacheEnterMutex(
6230: 29 3b 0a 20 20 77 68 69 6c 65 28 20 28 70 20 3d  );.  while( (p =
6240: 20 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 29   pCache->pDirty)
6250: 21 3d 30 20 29 7b 0a 20 20 20 20 70 63 61 63 68  !=0 ){.    pcach
6260: 65 52 65 6d 6f 76 65 46 72 6f 6d 4c 69 73 74 28  eRemoveFromList(
6270: 26 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 2c  &pCache->pDirty,
6280: 20 70 29 3b 0a 20 20 20 20 70 2d 3e 66 6c 61 67   p);.    p->flag
6290: 73 20 26 3d 20 7e 50 47 48 44 52 5f 44 49 52 54  s &= ~PGHDR_DIRT
62a0: 59 3b 0a 20 20 20 20 70 63 61 63 68 65 41 64 64  Y;.    pcacheAdd
62b0: 54 6f 4c 69 73 74 28 26 70 43 61 63 68 65 2d 3e  ToList(&pCache->
62c0: 70 43 6c 65 61 6e 2c 20 70 29 3b 0a 20 20 20 20  pClean, p);.    
62d0: 69 66 28 20 70 2d 3e 6e 52 65 66 3d 3d 30 20 29  if( p->nRef==0 )
62e0: 7b 0a 20 20 20 20 20 20 70 63 61 63 68 65 41 64  {.      pcacheAd
62f0: 64 54 6f 4c 72 75 4c 69 73 74 28 70 29 3b 0a 20  dToLruList(p);. 
6300: 20 20 20 20 20 70 43 61 63 68 65 2d 3e 6e 50 69       pCache->nPi
6310: 6e 6e 65 64 2d 2d 3b 0a 20 20 20 20 7d 0a 20 20  nned--;.    }.  
6320: 7d 0a 20 20 73 71 6c 69 74 65 33 50 63 61 63 68  }.  sqlite3Pcach
6330: 65 41 73 73 65 72 74 46 6c 61 67 73 28 70 43 61  eAssertFlags(pCa
6340: 63 68 65 2c 20 30 2c 20 50 47 48 44 52 5f 44 49  che, 0, PGHDR_DI
6350: 52 54 59 29 3b 0a 20 20 65 78 70 65 6e 73 69 76  RTY);.  expensiv
6360: 65 5f 61 73 73 65 72 74 28 20 70 43 61 63 68 65  e_assert( pCache
6370: 2d 3e 6e 50 69 6e 6e 65 64 3d 3d 70 63 61 63 68  ->nPinned==pcach
6380: 65 50 69 6e 6e 65 64 43 6f 75 6e 74 28 70 43 61  ePinnedCount(pCa
6390: 63 68 65 29 20 29 3b 0a 20 20 70 63 61 63 68 65  che) );.  pcache
63a0: 45 78 69 74 4d 75 74 65 78 28 29 3b 0a 7d 0a 0a  ExitMutex();.}..
63b0: 2f 2a 0a 2a 2a 20 43 68 61 6e 67 65 20 74 68 65  /*.** Change the
63c0: 20 70 61 67 65 20 6e 75 6d 62 65 72 20 6f 66 20   page number of 
63d0: 70 61 67 65 20 70 20 74 6f 20 6e 65 77 50 67 6e  page p to newPgn
63e0: 6f 2e 20 49 66 20 6e 65 77 50 67 6e 6f 20 69 73  o. If newPgno is
63f0: 20 30 2c 20 74 68 65 6e 20 74 68 65 0a 2a 2a 20   0, then the.** 
6400: 70 61 67 65 20 6f 62 6a 65 63 74 20 69 73 20 61  page object is a
6410: 64 64 65 64 20 74 6f 20 74 68 65 20 63 6c 65 61  dded to the clea
6420: 6e 2d 6c 69 73 74 20 61 6e 64 20 74 68 65 20 50  n-list and the P
6430: 47 48 44 52 5f 52 45 55 53 45 5f 55 4e 4c 49 4b  GHDR_REUSE_UNLIK
6440: 45 4c 59 20 0a 2a 2a 20 66 6c 61 67 20 73 65 74  ELY .** flag set
6450: 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
6460: 33 50 63 61 63 68 65 4d 6f 76 65 28 50 67 48 64  3PcacheMove(PgHd
6470: 72 20 2a 70 2c 20 50 67 6e 6f 20 6e 65 77 50 67  r *p, Pgno newPg
6480: 6e 6f 29 7b 0a 20 20 61 73 73 65 72 74 28 20 70  no){.  assert( p
6490: 2d 3e 6e 52 65 66 3e 30 20 29 3b 0a 20 20 70 63  ->nRef>0 );.  pc
64a0: 61 63 68 65 45 6e 74 65 72 4d 75 74 65 78 28 29  acheEnterMutex()
64b0: 3b 0a 20 20 70 63 61 63 68 65 52 65 6d 6f 76 65  ;.  pcacheRemove
64c0: 46 72 6f 6d 48 61 73 68 28 70 29 3b 0a 20 20 70  FromHash(p);.  p
64d0: 2d 3e 70 67 6e 6f 20 3d 20 6e 65 77 50 67 6e 6f  ->pgno = newPgno
64e0: 3b 0a 20 20 69 66 28 20 6e 65 77 50 67 6e 6f 3d  ;.  if( newPgno=
64f0: 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20 28 70  =0 ){.    if( (p
6500: 2d 3e 66 6c 61 67 73 20 26 20 50 47 48 44 52 5f  ->flags & PGHDR_
6510: 44 49 52 54 59 29 20 29 7b 0a 20 20 20 20 20 20  DIRTY) ){.      
6520: 70 63 61 63 68 65 4d 61 6b 65 43 6c 65 61 6e 28  pcacheMakeClean(
6530: 70 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 2d  p);.    }.    p-
6540: 3e 66 6c 61 67 73 20 3d 20 50 47 48 44 52 5f 52  >flags = PGHDR_R
6550: 45 55 53 45 5f 55 4e 4c 49 4b 45 4c 59 3b 0a 20  EUSE_UNLIKELY;. 
6560: 20 7d 0a 20 20 70 63 61 63 68 65 41 64 64 54 6f   }.  pcacheAddTo
6570: 48 61 73 68 28 70 29 3b 0a 20 20 70 63 61 63 68  Hash(p);.  pcach
6580: 65 45 78 69 74 4d 75 74 65 78 28 29 3b 0a 7d 0a  eExitMutex();.}.
6590: 0a 2f 2a 0a 2a 2a 20 52 65 6d 6f 76 65 20 61 6c  ./*.** Remove al
65a0: 6c 20 63 6f 6e 74 65 6e 74 20 66 72 6f 6d 20 61  l content from a
65b0: 20 70 61 67 65 20 63 61 63 68 65 0a 2a 2f 0a 73   page cache.*/.s
65c0: 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68  tatic void pcach
65d0: 65 43 6c 65 61 72 28 50 43 61 63 68 65 20 2a 70  eClear(PCache *p
65e0: 43 61 63 68 65 29 7b 0a 20 20 50 67 48 64 72 20  Cache){.  PgHdr 
65f0: 2a 70 2c 20 2a 70 4e 65 78 74 3b 0a 20 20 61 73  *p, *pNext;.  as
6600: 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75  sert( sqlite3_mu
6610: 74 65 78 5f 68 65 6c 64 28 70 63 61 63 68 65 5f  tex_held(pcache_
6620: 67 2e 6d 75 74 65 78 29 20 29 3b 0a 20 20 66 6f  g.mutex) );.  fo
6630: 72 28 70 3d 70 43 61 63 68 65 2d 3e 70 43 6c 65  r(p=pCache->pCle
6640: 61 6e 3b 20 70 3b 20 70 3d 70 4e 65 78 74 29 7b  an; p; p=pNext){
6650: 0a 20 20 20 20 70 4e 65 78 74 20 3d 20 70 2d 3e  .    pNext = p->
6660: 70 4e 65 78 74 3b 0a 20 20 20 20 70 63 61 63 68  pNext;.    pcach
6670: 65 52 65 6d 6f 76 65 46 72 6f 6d 4c 72 75 4c 69  eRemoveFromLruLi
6680: 73 74 28 70 29 3b 0a 20 20 20 20 70 63 61 63 68  st(p);.    pcach
6690: 65 50 61 67 65 46 72 65 65 28 70 29 3b 0a 20 20  ePageFree(p);.  
66a0: 7d 0a 20 20 66 6f 72 28 70 3d 70 43 61 63 68 65  }.  for(p=pCache
66b0: 2d 3e 70 44 69 72 74 79 3b 20 70 3b 20 70 3d 70  ->pDirty; p; p=p
66c0: 4e 65 78 74 29 7b 0a 20 20 20 20 70 4e 65 78 74  Next){.    pNext
66d0: 20 3d 20 70 2d 3e 70 4e 65 78 74 3b 0a 20 20 20   = p->pNext;.   
66e0: 20 70 63 61 63 68 65 50 61 67 65 46 72 65 65 28   pcachePageFree(
66f0: 70 29 3b 0a 20 20 7d 0a 20 20 70 43 61 63 68 65  p);.  }.  pCache
6700: 2d 3e 70 43 6c 65 61 6e 20 3d 20 30 3b 0a 20 20  ->pClean = 0;.  
6710: 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 20 3d  pCache->pDirty =
6720: 20 30 3b 0a 20 20 70 43 61 63 68 65 2d 3e 70 44   0;.  pCache->pD
6730: 69 72 74 79 54 61 69 6c 20 3d 20 30 3b 0a 20 20  irtyTail = 0;.  
6740: 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 20 3d 20  pCache->nPage = 
6750: 30 3b 0a 20 20 70 43 61 63 68 65 2d 3e 6e 50 69  0;.  pCache->nPi
6760: 6e 6e 65 64 20 3d 20 30 3b 0a 20 20 6d 65 6d 73  nned = 0;.  mems
6770: 65 74 28 70 43 61 63 68 65 2d 3e 61 70 48 61 73  et(pCache->apHas
6780: 68 2c 20 30 2c 20 70 43 61 63 68 65 2d 3e 6e 48  h, 0, pCache->nH
6790: 61 73 68 2a 73 69 7a 65 6f 66 28 70 43 61 63 68  ash*sizeof(pCach
67a0: 65 2d 3e 61 70 48 61 73 68 5b 30 5d 29 29 3b 0a  e->apHash[0]));.
67b0: 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 44 72 6f 70 20 65  }.../*.** Drop e
67c0: 76 65 72 79 20 63 61 63 68 65 20 65 6e 74 72 79  very cache entry
67d0: 20 77 68 6f 73 65 20 70 61 67 65 20 6e 75 6d 62   whose page numb
67e0: 65 72 20 69 73 20 67 72 65 61 74 65 72 20 74 68  er is greater th
67f0: 61 6e 20 22 70 67 6e 6f 22 2e 0a 2a 2f 0a 76 6f  an "pgno"..*/.vo
6800: 69 64 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  id sqlite3Pcache
6810: 54 72 75 6e 63 61 74 65 28 50 43 61 63 68 65 20  Truncate(PCache 
6820: 2a 70 43 61 63 68 65 2c 20 50 67 6e 6f 20 70 67  *pCache, Pgno pg
6830: 6e 6f 29 7b 0a 20 20 50 67 48 64 72 20 2a 70 2c  no){.  PgHdr *p,
6840: 20 2a 70 4e 65 78 74 3b 0a 20 20 50 67 48 64 72   *pNext;.  PgHdr
6850: 20 2a 70 44 69 72 74 79 20 3d 20 70 43 61 63 68   *pDirty = pCach
6860: 65 2d 3e 70 44 69 72 74 79 3b 0a 20 20 70 63 61  e->pDirty;.  pca
6870: 63 68 65 45 6e 74 65 72 4d 75 74 65 78 28 29 3b  cheEnterMutex();
6880: 0a 20 20 66 6f 72 28 70 3d 70 43 61 63 68 65 2d  .  for(p=pCache-
6890: 3e 70 43 6c 65 61 6e 3b 20 70 7c 7c 70 44 69 72  >pClean; p||pDir
68a0: 74 79 3b 20 70 3d 70 4e 65 78 74 29 7b 0a 20 20  ty; p=pNext){.  
68b0: 20 20 69 66 28 20 21 70 20 29 7b 0a 20 20 20 20    if( !p ){.    
68c0: 20 20 70 20 3d 20 70 44 69 72 74 79 3b 0a 20 20    p = pDirty;.  
68d0: 20 20 20 20 70 44 69 72 74 79 20 3d 20 30 3b 0a      pDirty = 0;.
68e0: 20 20 20 20 7d 0a 20 20 20 20 70 4e 65 78 74 20      }.    pNext 
68f0: 3d 20 70 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20  = p->pNext;.    
6900: 69 66 28 20 70 2d 3e 70 67 6e 6f 3e 70 67 6e 6f  if( p->pgno>pgno
6910: 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 70 2d   ){.      if( p-
6920: 3e 6e 52 65 66 3d 3d 30 20 29 7b 0a 20 20 20 20  >nRef==0 ){.    
6930: 20 20 20 20 70 63 61 63 68 65 52 65 6d 6f 76 65      pcacheRemove
6940: 46 72 6f 6d 48 61 73 68 28 70 29 3b 0a 20 20 20  FromHash(p);.   
6950: 20 20 20 20 20 69 66 28 20 70 2d 3e 66 6c 61 67       if( p->flag
6960: 73 26 50 47 48 44 52 5f 44 49 52 54 59 20 29 7b  s&PGHDR_DIRTY ){
6970: 0a 20 20 20 20 20 20 20 20 20 20 70 63 61 63 68  .          pcach
6980: 65 52 65 6d 6f 76 65 46 72 6f 6d 4c 69 73 74 28  eRemoveFromList(
6990: 26 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 2c  &pCache->pDirty,
69a0: 20 70 29 3b 0a 20 20 20 20 20 20 20 20 20 20 70   p);.          p
69b0: 43 61 63 68 65 2d 3e 6e 50 69 6e 6e 65 64 2d 2d  Cache->nPinned--
69c0: 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b  ;.        }else{
69d0: 0a 20 20 20 20 20 20 20 20 20 20 70 63 61 63 68  .          pcach
69e0: 65 52 65 6d 6f 76 65 46 72 6f 6d 4c 69 73 74 28  eRemoveFromList(
69f0: 26 70 43 61 63 68 65 2d 3e 70 43 6c 65 61 6e 2c  &pCache->pClean,
6a00: 20 70 29 3b 0a 20 20 20 20 20 20 20 20 20 20 70   p);.          p
6a10: 63 61 63 68 65 52 65 6d 6f 76 65 46 72 6f 6d 4c  cacheRemoveFromL
6a20: 72 75 4c 69 73 74 28 70 29 3b 0a 20 20 20 20 20  ruList(p);.     
6a30: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 70 63 61     }.        pca
6a40: 63 68 65 50 61 67 65 46 72 65 65 28 70 29 3b 0a  chePageFree(p);.
6a50: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
6a60: 20 20 20 20 20 2f 2a 20 49 66 20 74 68 65 72 65       /* If there
6a70: 20 61 72 65 20 72 65 66 65 72 65 6e 63 65 73 20   are references 
6a80: 74 6f 20 74 68 65 20 70 61 67 65 2c 20 69 74 20  to the page, it 
6a90: 63 61 6e 6e 6f 74 20 62 65 20 66 72 65 65 64 2e  cannot be freed.
6aa0: 20 49 6e 20 74 68 69 73 0a 20 20 20 20 20 20 20   In this.       
6ab0: 20 2a 2a 20 63 61 73 65 2c 20 7a 65 72 6f 20 74   ** case, zero t
6ac0: 68 65 20 70 61 67 65 20 63 6f 6e 74 65 6e 74 20  he page content 
6ad0: 69 6e 73 74 65 61 64 2e 0a 20 20 20 20 20 20 20  instead..       
6ae0: 20 2a 2f 0a 20 20 20 20 20 20 20 20 6d 65 6d 73   */.        mems
6af0: 65 74 28 70 2d 3e 70 44 61 74 61 2c 20 30 2c 20  et(p->pData, 0, 
6b00: 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 29 3b  pCache->szPage);
6b10: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
6b20: 20 7d 0a 20 20 70 63 61 63 68 65 45 78 69 74 4d   }.  pcacheExitM
6b30: 75 74 65 78 28 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  utex();.}../*.**
6b40: 20 49 66 20 74 68 65 72 65 20 61 72 65 20 63 75   If there are cu
6b50: 72 72 65 6e 74 6c 79 20 6d 6f 72 65 20 74 68 61  rrently more tha
6b60: 6e 20 70 63 61 63 68 65 2e 6e 4d 61 78 50 61 67  n pcache.nMaxPag
6b70: 65 20 70 61 67 65 73 20 61 6c 6c 6f 63 61 74 65  e pages allocate
6b80: 64 2c 20 74 72 79 0a 2a 2a 20 74 6f 20 72 65 63  d, try.** to rec
6b90: 79 63 6c 65 20 70 61 67 65 73 20 74 6f 20 72 65  ycle pages to re
6ba0: 64 75 63 65 20 74 68 65 20 6e 75 6d 62 65 72 20  duce the number 
6bb0: 61 6c 6c 6f 63 61 74 65 64 20 74 6f 20 70 63 61  allocated to pca
6bc0: 63 68 65 2e 6e 4d 61 78 50 61 67 65 2e 0a 2a 2f  che.nMaxPage..*/
6bd0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61  .static void pca
6be0: 63 68 65 45 6e 66 6f 72 63 65 4d 61 78 50 61 67  cheEnforceMaxPag
6bf0: 65 28 76 6f 69 64 29 7b 0a 20 20 50 67 48 64 72  e(void){.  PgHdr
6c00: 20 2a 70 3b 0a 20 20 61 73 73 65 72 74 28 20 73   *p;.  assert( s
6c10: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c  qlite3_mutex_hel
6c20: 64 28 70 63 61 63 68 65 5f 67 2e 6d 75 74 65 78  d(pcache_g.mutex
6c30: 29 20 29 3b 0a 20 20 77 68 69 6c 65 28 20 70 63  ) );.  while( pc
6c40: 61 63 68 65 5f 67 2e 6e 43 75 72 72 65 6e 74 50  ache_g.nCurrentP
6c50: 61 67 65 3e 70 63 61 63 68 65 5f 67 2e 6e 4d 61  age>pcache_g.nMa
6c60: 78 50 61 67 65 0a 20 20 20 20 20 20 20 20 20 20  xPage.          
6c70: 20 20 20 26 26 20 28 70 20 3d 20 70 63 61 63 68     && (p = pcach
6c80: 65 52 65 63 79 63 6c 65 50 61 67 65 28 29 29 21  eRecyclePage())!
6c90: 3d 30 20 29 7b 0a 20 20 20 20 70 63 61 63 68 65  =0 ){.    pcache
6ca0: 50 61 67 65 46 72 65 65 28 70 29 3b 0a 20 20 7d  PageFree(p);.  }
6cb0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20  .}../*.** Close 
6cc0: 61 20 63 61 63 68 65 2e 0a 2a 2f 0a 76 6f 69 64  a cache..*/.void
6cd0: 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 43 6c   sqlite3PcacheCl
6ce0: 6f 73 65 28 50 43 61 63 68 65 20 2a 70 43 61 63  ose(PCache *pCac
6cf0: 68 65 29 7b 0a 20 20 70 63 61 63 68 65 45 6e 74  he){.  pcacheEnt
6d00: 65 72 4d 75 74 65 78 28 29 3b 0a 0a 20 20 2f 2a  erMutex();..  /*
6d10: 20 46 72 65 65 20 61 6c 6c 20 74 68 65 20 70 61   Free all the pa
6d20: 67 65 73 20 75 73 65 64 20 62 79 20 74 68 69 73  ges used by this
6d30: 20 70 61 67 65 72 20 61 6e 64 20 72 65 6d 6f 76   pager and remov
6d40: 65 20 74 68 65 6d 20 66 72 6f 6d 20 74 68 65 20  e them from the 
6d50: 4c 52 55 20 6c 69 73 74 2e 20 2a 2f 0a 20 20 70  LRU list. */.  p
6d60: 63 61 63 68 65 43 6c 65 61 72 28 70 43 61 63 68  cacheClear(pCach
6d70: 65 29 3b 0a 20 20 69 66 28 20 70 43 61 63 68 65  e);.  if( pCache
6d80: 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 29 7b 0a  ->bPurgeable ){.
6d90: 20 20 20 20 70 63 61 63 68 65 5f 67 2e 6e 4d 61      pcache_g.nMa
6da0: 78 50 61 67 65 20 2d 3d 20 70 43 61 63 68 65 2d  xPage -= pCache-
6db0: 3e 6e 4d 61 78 3b 0a 20 20 20 20 70 63 61 63 68  >nMax;.    pcach
6dc0: 65 5f 67 2e 6e 4d 69 6e 50 61 67 65 20 2d 3d 20  e_g.nMinPage -= 
6dd0: 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 3b 0a 20 20  pCache->nMin;.  
6de0: 20 20 70 63 61 63 68 65 45 6e 66 6f 72 63 65 4d    pcacheEnforceM
6df0: 61 78 50 61 67 65 28 29 3b 0a 20 20 7d 0a 20 20  axPage();.  }.  
6e00: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43 61  sqlite3_free(pCa
6e10: 63 68 65 2d 3e 61 70 48 61 73 68 29 3b 0a 20 20  che->apHash);.  
6e20: 70 63 61 63 68 65 45 78 69 74 4d 75 74 65 78 28  pcacheExitMutex(
6e30: 29 3b 0a 7d 0a 0a 0a 23 69 66 6e 64 65 66 20 4e  );.}...#ifndef N
6e40: 44 45 42 55 47 0a 2f 2a 20 0a 2a 2a 20 41 73 73  DEBUG./* .** Ass
6e50: 65 72 74 20 66 6c 61 67 73 20 73 65 74 74 69 6e  ert flags settin
6e60: 67 73 20 6f 6e 20 61 6c 6c 20 70 61 67 65 73 2e  gs on all pages.
6e70: 20 20 44 65 62 75 67 67 69 6e 67 20 6f 6e 6c 79    Debugging only
6e80: 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
6e90: 33 50 63 61 63 68 65 41 73 73 65 72 74 46 6c 61  3PcacheAssertFla
6ea0: 67 73 28 50 43 61 63 68 65 20 2a 70 43 61 63 68  gs(PCache *pCach
6eb0: 65 2c 20 69 6e 74 20 74 72 75 65 4d 61 73 6b 2c  e, int trueMask,
6ec0: 20 69 6e 74 20 66 61 6c 73 65 4d 61 73 6b 29 7b   int falseMask){
6ed0: 0a 20 20 50 67 48 64 72 20 2a 70 3b 0a 20 20 66  .  PgHdr *p;.  f
6ee0: 6f 72 28 70 3d 70 43 61 63 68 65 2d 3e 70 44 69  or(p=pCache->pDi
6ef0: 72 74 79 3b 20 70 3b 20 70 3d 70 2d 3e 70 4e 65  rty; p; p=p->pNe
6f00: 78 74 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28  xt){.    assert(
6f10: 20 28 70 2d 3e 66 6c 61 67 73 26 74 72 75 65 4d   (p->flags&trueM
6f20: 61 73 6b 29 3d 3d 74 72 75 65 4d 61 73 6b 20 29  ask)==trueMask )
6f30: 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 28 70  ;.    assert( (p
6f40: 2d 3e 66 6c 61 67 73 26 66 61 6c 73 65 4d 61 73  ->flags&falseMas
6f50: 6b 29 3d 3d 30 20 29 3b 0a 20 20 7d 0a 20 20 66  k)==0 );.  }.  f
6f60: 6f 72 28 70 3d 70 43 61 63 68 65 2d 3e 70 43 6c  or(p=pCache->pCl
6f70: 65 61 6e 3b 20 70 3b 20 70 3d 70 2d 3e 70 4e 65  ean; p; p=p->pNe
6f80: 78 74 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28  xt){.    assert(
6f90: 20 28 70 2d 3e 66 6c 61 67 73 26 74 72 75 65 4d   (p->flags&trueM
6fa0: 61 73 6b 29 3d 3d 74 72 75 65 4d 61 73 6b 20 29  ask)==trueMask )
6fb0: 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 28 70  ;.    assert( (p
6fc0: 2d 3e 66 6c 61 67 73 26 66 61 6c 73 65 4d 61 73  ->flags&falseMas
6fd0: 6b 29 3d 3d 30 20 29 3b 0a 20 20 7d 0a 7d 0a 23  k)==0 );.  }.}.#
6fe0: 65 6e 64 69 66 0a 0a 2f 2a 20 0a 2a 2a 20 44 69  endif../* .** Di
6ff0: 73 63 61 72 64 20 74 68 65 20 63 6f 6e 74 65 6e  scard the conten
7000: 74 73 20 6f 66 20 74 68 65 20 63 61 63 68 65 2e  ts of the cache.
7010: 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 50  .*/.int sqlite3P
7020: 63 61 63 68 65 43 6c 65 61 72 28 50 43 61 63 68  cacheClear(PCach
7030: 65 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 61 73  e *pCache){.  as
7040: 73 65 72 74 28 70 43 61 63 68 65 2d 3e 6e 52 65  sert(pCache->nRe
7050: 66 3d 3d 30 29 3b 0a 20 20 70 63 61 63 68 65 45  f==0);.  pcacheE
7060: 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a 20 20 70  nterMutex();.  p
7070: 63 61 63 68 65 43 6c 65 61 72 28 70 43 61 63 68  cacheClear(pCach
7080: 65 29 3b 0a 20 20 70 63 61 63 68 65 45 78 69 74  e);.  pcacheExit
7090: 4d 75 74 65 78 28 29 3b 0a 20 20 72 65 74 75 72  Mutex();.  retur
70a0: 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a  n SQLITE_OK;.}..
70b0: 2f 2a 0a 2a 2a 20 4d 65 72 67 65 20 74 77 6f 20  /*.** Merge two 
70c0: 6c 69 73 74 73 20 6f 66 20 70 61 67 65 73 20 63  lists of pages c
70d0: 6f 6e 6e 65 63 74 65 64 20 62 79 20 70 44 69 72  onnected by pDir
70e0: 74 79 20 61 6e 64 20 69 6e 20 70 67 6e 6f 20 6f  ty and in pgno o
70f0: 72 64 65 72 2e 0a 2a 2a 20 44 6f 20 6e 6f 74 20  rder..** Do not 
7100: 62 6f 74 68 20 66 69 78 69 6e 67 20 74 68 65 20  both fixing the 
7110: 70 50 72 65 76 44 69 72 74 79 20 70 6f 69 6e 74  pPrevDirty point
7120: 65 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 50  ers..*/.static P
7130: 67 48 64 72 20 2a 70 63 61 63 68 65 4d 65 72 67  gHdr *pcacheMerg
7140: 65 44 69 72 74 79 4c 69 73 74 28 50 67 48 64 72  eDirtyList(PgHdr
7150: 20 2a 70 41 2c 20 50 67 48 64 72 20 2a 70 42 29   *pA, PgHdr *pB)
7160: 7b 0a 20 20 50 67 48 64 72 20 72 65 73 75 6c 74  {.  PgHdr result
7170: 2c 20 2a 70 54 61 69 6c 3b 0a 20 20 70 54 61 69  , *pTail;.  pTai
7180: 6c 20 3d 20 26 72 65 73 75 6c 74 3b 0a 20 20 77  l = &result;.  w
7190: 68 69 6c 65 28 20 70 41 20 26 26 20 70 42 20 29  hile( pA && pB )
71a0: 7b 0a 20 20 20 20 69 66 28 20 70 41 2d 3e 70 67  {.    if( pA->pg
71b0: 6e 6f 3c 70 42 2d 3e 70 67 6e 6f 20 29 7b 0a 20  no<pB->pgno ){. 
71c0: 20 20 20 20 20 70 54 61 69 6c 2d 3e 70 44 69 72       pTail->pDir
71d0: 74 79 20 3d 20 70 41 3b 0a 20 20 20 20 20 20 70  ty = pA;.      p
71e0: 54 61 69 6c 20 3d 20 70 41 3b 0a 20 20 20 20 20  Tail = pA;.     
71f0: 20 70 41 20 3d 20 70 41 2d 3e 70 44 69 72 74 79   pA = pA->pDirty
7200: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
7210: 20 20 20 70 54 61 69 6c 2d 3e 70 44 69 72 74 79     pTail->pDirty
7220: 20 3d 20 70 42 3b 0a 20 20 20 20 20 20 70 54 61   = pB;.      pTa
7230: 69 6c 20 3d 20 70 42 3b 0a 20 20 20 20 20 20 70  il = pB;.      p
7240: 42 20 3d 20 70 42 2d 3e 70 44 69 72 74 79 3b 0a  B = pB->pDirty;.
7250: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20      }.  }.  if( 
7260: 70 41 20 29 7b 0a 20 20 20 20 70 54 61 69 6c 2d  pA ){.    pTail-
7270: 3e 70 44 69 72 74 79 20 3d 20 70 41 3b 0a 20 20  >pDirty = pA;.  
7280: 7d 65 6c 73 65 20 69 66 28 20 70 42 20 29 7b 0a  }else if( pB ){.
7290: 20 20 20 20 70 54 61 69 6c 2d 3e 70 44 69 72 74      pTail->pDirt
72a0: 79 20 3d 20 70 42 3b 0a 20 20 7d 65 6c 73 65 7b  y = pB;.  }else{
72b0: 0a 20 20 20 20 70 54 61 69 6c 2d 3e 70 44 69 72  .    pTail->pDir
72c0: 74 79 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 72 65  ty = 0;.  }.  re
72d0: 74 75 72 6e 20 72 65 73 75 6c 74 2e 70 44 69 72  turn result.pDir
72e0: 74 79 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 6f 72  ty;.}../*.** Sor
72f0: 74 20 74 68 65 20 6c 69 73 74 20 6f 66 20 70 61  t the list of pa
7300: 67 65 73 20 69 6e 20 61 63 63 65 6e 64 69 6e 67  ges in accending
7310: 20 6f 72 64 65 72 20 62 79 20 70 67 6e 6f 2e 20   order by pgno. 
7320: 20 50 61 67 65 73 20 61 72 65 0a 2a 2a 20 63 6f   Pages are.** co
7330: 6e 6e 65 63 74 65 64 20 62 79 20 70 44 69 72 74  nnected by pDirt
7340: 79 20 70 6f 69 6e 74 65 72 73 2e 20 20 54 68 65  y pointers.  The
7350: 20 70 50 72 65 76 44 69 72 74 79 20 70 6f 69 6e   pPrevDirty poin
7360: 74 65 72 73 20 61 72 65 0a 2a 2a 20 63 6f 72 72  ters are.** corr
7370: 75 70 74 65 64 20 62 79 20 74 68 69 73 20 73 6f  upted by this so
7380: 72 74 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 4e  rt..*/.#define N
7390: 5f 53 4f 52 54 5f 42 55 43 4b 45 54 5f 41 4c 4c  _SORT_BUCKET_ALL
73a0: 4f 43 20 32 35 0a 23 64 65 66 69 6e 65 20 4e 5f  OC 25.#define N_
73b0: 53 4f 52 54 5f 42 55 43 4b 45 54 20 20 20 20 20  SORT_BUCKET     
73c0: 20 20 32 35 0a 23 69 66 64 65 66 20 53 51 4c 49    25.#ifdef SQLI
73d0: 54 45 5f 54 45 53 54 0a 20 20 69 6e 74 20 73 71  TE_TEST.  int sq
73e0: 6c 69 74 65 33 5f 70 61 67 65 72 5f 6e 5f 73 6f  lite3_pager_n_so
73f0: 72 74 5f 62 75 63 6b 65 74 20 3d 20 30 3b 0a 20  rt_bucket = 0;. 
7400: 20 23 75 6e 64 65 66 20 4e 5f 53 4f 52 54 5f 42   #undef N_SORT_B
7410: 55 43 4b 45 54 0a 20 20 23 64 65 66 69 6e 65 20  UCKET.  #define 
7420: 4e 5f 53 4f 52 54 5f 42 55 43 4b 45 54 20 5c 0a  N_SORT_BUCKET \.
7430: 20 20 20 28 73 71 6c 69 74 65 33 5f 70 61 67 65     (sqlite3_page
7440: 72 5f 6e 5f 73 6f 72 74 5f 62 75 63 6b 65 74 3f  r_n_sort_bucket?
7450: 73 71 6c 69 74 65 33 5f 70 61 67 65 72 5f 6e 5f  sqlite3_pager_n_
7460: 73 6f 72 74 5f 62 75 63 6b 65 74 3a 4e 5f 53 4f  sort_bucket:N_SO
7470: 52 54 5f 42 55 43 4b 45 54 5f 41 4c 4c 4f 43 29  RT_BUCKET_ALLOC)
7480: 0a 23 65 6e 64 69 66 0a 73 74 61 74 69 63 20 50  .#endif.static P
7490: 67 48 64 72 20 2a 70 63 61 63 68 65 53 6f 72 74  gHdr *pcacheSort
74a0: 44 69 72 74 79 4c 69 73 74 28 50 67 48 64 72 20  DirtyList(PgHdr 
74b0: 2a 70 49 6e 29 7b 0a 20 20 50 67 48 64 72 20 2a  *pIn){.  PgHdr *
74c0: 61 5b 4e 5f 53 4f 52 54 5f 42 55 43 4b 45 54 5f  a[N_SORT_BUCKET_
74d0: 41 4c 4c 4f 43 5d 2c 20 2a 70 3b 0a 20 20 69 6e  ALLOC], *p;.  in
74e0: 74 20 69 3b 0a 20 20 6d 65 6d 73 65 74 28 61 2c  t i;.  memset(a,
74f0: 20 30 2c 20 73 69 7a 65 6f 66 28 61 29 29 3b 0a   0, sizeof(a));.
7500: 20 20 77 68 69 6c 65 28 20 70 49 6e 20 29 7b 0a    while( pIn ){.
7510: 20 20 20 20 70 20 3d 20 70 49 6e 3b 0a 20 20 20      p = pIn;.   
7520: 20 70 49 6e 20 3d 20 70 2d 3e 70 44 69 72 74 79   pIn = p->pDirty
7530: 3b 0a 20 20 20 20 70 2d 3e 70 44 69 72 74 79 20  ;.    p->pDirty 
7540: 3d 20 30 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30  = 0;.    for(i=0
7550: 3b 20 69 3c 4e 5f 53 4f 52 54 5f 42 55 43 4b 45  ; i<N_SORT_BUCKE
7560: 54 2d 31 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20  T-1; i++){.     
7570: 20 69 66 28 20 61 5b 69 5d 3d 3d 30 20 29 7b 0a   if( a[i]==0 ){.
7580: 20 20 20 20 20 20 20 20 61 5b 69 5d 20 3d 20 70          a[i] = p
7590: 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b  ;.        break;
75a0: 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  .      }else{.  
75b0: 20 20 20 20 20 20 70 20 3d 20 70 63 61 63 68 65        p = pcache
75c0: 4d 65 72 67 65 44 69 72 74 79 4c 69 73 74 28 61  MergeDirtyList(a
75d0: 5b 69 5d 2c 20 70 29 3b 0a 20 20 20 20 20 20 20  [i], p);.       
75e0: 20 61 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20 20   a[i] = 0;.     
75f0: 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28   }.    }.    if(
7600: 20 69 3d 3d 4e 5f 53 4f 52 54 5f 42 55 43 4b 45   i==N_SORT_BUCKE
7610: 54 2d 31 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20  T-1 ){.      /* 
7620: 43 6f 76 65 72 61 67 65 3a 20 54 6f 20 67 65 74  Coverage: To get
7630: 20 68 65 72 65 2c 20 74 68 65 72 65 20 6e 65 65   here, there nee
7640: 64 20 74 6f 20 62 65 20 32 5e 28 4e 5f 53 4f 52  d to be 2^(N_SOR
7650: 54 5f 42 55 43 4b 45 54 29 20 0a 20 20 20 20 20  T_BUCKET) .     
7660: 20 2a 2a 20 65 6c 65 6d 65 6e 74 73 20 69 6e 20   ** elements in 
7670: 74 68 65 20 69 6e 70 75 74 20 6c 69 73 74 2e 20  the input list. 
7680: 54 68 69 73 20 69 73 20 70 6f 73 73 69 62 6c 65  This is possible
7690: 2c 20 62 75 74 20 69 6d 70 72 61 63 74 69 63 61  , but impractica
76a0: 6c 2e 0a 20 20 20 20 20 20 2a 2a 20 54 65 73 74  l..      ** Test
76b0: 69 6e 67 20 74 68 69 73 20 6c 69 6e 65 20 69 73  ing this line is
76c0: 20 74 68 65 20 70 6f 69 6e 74 20 6f 66 20 67 6c   the point of gl
76d0: 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 0a 20 20  obal variable.  
76e0: 20 20 20 20 2a 2a 20 73 71 6c 69 74 65 33 5f 70      ** sqlite3_p
76f0: 61 67 65 72 5f 6e 5f 73 6f 72 74 5f 62 75 63 6b  ager_n_sort_buck
7700: 65 74 2e 0a 20 20 20 20 20 20 2a 2f 0a 20 20 20  et..      */.   
7710: 20 20 20 61 5b 69 5d 20 3d 20 70 63 61 63 68 65     a[i] = pcache
7720: 4d 65 72 67 65 44 69 72 74 79 4c 69 73 74 28 61  MergeDirtyList(a
7730: 5b 69 5d 2c 20 70 29 3b 0a 20 20 20 20 7d 0a 20  [i], p);.    }. 
7740: 20 7d 0a 20 20 70 20 3d 20 61 5b 30 5d 3b 0a 20   }.  p = a[0];. 
7750: 20 66 6f 72 28 69 3d 31 3b 20 69 3c 4e 5f 53 4f   for(i=1; i<N_SO
7760: 52 54 5f 42 55 43 4b 45 54 3b 20 69 2b 2b 29 7b  RT_BUCKET; i++){
7770: 0a 20 20 20 20 70 20 3d 20 70 63 61 63 68 65 4d  .    p = pcacheM
7780: 65 72 67 65 44 69 72 74 79 4c 69 73 74 28 70 2c  ergeDirtyList(p,
7790: 20 61 5b 69 5d 29 3b 0a 20 20 7d 0a 20 20 72 65   a[i]);.  }.  re
77a0: 74 75 72 6e 20 70 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  turn p;.}../*.**
77b0: 20 52 65 74 75 72 6e 20 61 20 6c 69 73 74 20 6f   Return a list o
77c0: 66 20 61 6c 6c 20 64 69 72 74 79 20 70 61 67 65  f all dirty page
77d0: 73 20 69 6e 20 74 68 65 20 63 61 63 68 65 2c 20  s in the cache, 
77e0: 73 6f 72 74 65 64 20 62 79 20 70 61 67 65 20 6e  sorted by page n
77f0: 75 6d 62 65 72 2e 0a 2a 2f 0a 50 67 48 64 72 20  umber..*/.PgHdr 
7800: 2a 73 71 6c 69 74 65 33 50 63 61 63 68 65 44 69  *sqlite3PcacheDi
7810: 72 74 79 4c 69 73 74 28 50 43 61 63 68 65 20 2a  rtyList(PCache *
7820: 70 43 61 63 68 65 29 7b 0a 20 20 50 67 48 64 72  pCache){.  PgHdr
7830: 20 2a 70 3b 0a 20 20 66 6f 72 28 70 3d 70 43 61   *p;.  for(p=pCa
7840: 63 68 65 2d 3e 70 44 69 72 74 79 3b 20 70 3b 20  che->pDirty; p; 
7850: 70 3d 70 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20  p=p->pNext){.   
7860: 20 70 2d 3e 70 44 69 72 74 79 20 3d 20 70 2d 3e   p->pDirty = p->
7870: 70 4e 65 78 74 3b 0a 20 20 7d 0a 20 20 72 65 74  pNext;.  }.  ret
7880: 75 72 6e 20 70 63 61 63 68 65 53 6f 72 74 44 69  urn pcacheSortDi
7890: 72 74 79 4c 69 73 74 28 70 43 61 63 68 65 2d 3e  rtyList(pCache->
78a0: 70 44 69 72 74 79 29 3b 0a 7d 0a 0a 2f 2a 20 0a  pDirty);.}../* .
78b0: 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 74 6f  ** Return the to
78c0: 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 6f 75  tal number of ou
78d0: 74 73 74 61 6e 64 69 6e 67 20 70 61 67 65 20 72  tstanding page r
78e0: 65 66 65 72 65 6e 63 65 73 2e 0a 2a 2f 0a 69 6e  eferences..*/.in
78f0: 74 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 52  t sqlite3PcacheR
7900: 65 66 43 6f 75 6e 74 28 50 43 61 63 68 65 20 2a  efCount(PCache *
7910: 70 43 61 63 68 65 29 7b 0a 20 20 72 65 74 75 72  pCache){.  retur
7920: 6e 20 70 43 61 63 68 65 2d 3e 6e 52 65 66 3b 0a  n pCache->nRef;.
7930: 7d 0a 0a 69 6e 74 20 73 71 6c 69 74 65 33 50 63  }..int sqlite3Pc
7940: 61 63 68 65 50 61 67 65 52 65 66 63 6f 75 6e 74  achePageRefcount
7950: 28 50 67 48 64 72 20 2a 70 29 7b 0a 20 20 72 65  (PgHdr *p){.  re
7960: 74 75 72 6e 20 70 2d 3e 6e 52 65 66 3b 0a 7d 0a  turn p->nRef;.}.
7970: 0a 2f 2a 20 0a 2a 2a 20 52 65 74 75 72 6e 20 74  ./* .** Return t
7980: 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20  he total number 
7990: 6f 66 20 70 61 67 65 73 20 69 6e 20 74 68 65 20  of pages in the 
79a0: 63 61 63 68 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71  cache..*/.int sq
79b0: 6c 69 74 65 33 50 63 61 63 68 65 50 61 67 65 63  lite3PcachePagec
79c0: 6f 75 6e 74 28 50 43 61 63 68 65 20 2a 70 43 61  ount(PCache *pCa
79d0: 63 68 65 29 7b 0a 20 20 61 73 73 65 72 74 28 20  che){.  assert( 
79e0: 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 3e 3d 30  pCache->nPage>=0
79f0: 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 70 43 61   );.  return pCa
7a00: 63 68 65 2d 3e 6e 50 61 67 65 3b 0a 7d 0a 0a 23  che->nPage;.}..#
7a10: 69 66 64 65 66 20 53 51 4c 49 54 45 5f 43 48 45  ifdef SQLITE_CHE
7a20: 43 4b 5f 50 41 47 45 53 0a 2f 2a 0a 2a 2a 20 54  CK_PAGES./*.** T
7a30: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
7a40: 75 73 65 64 20 62 79 20 74 68 65 20 70 61 67 65  used by the page
7a50: 72 2e 63 20 6d 6f 64 75 6c 65 20 74 6f 20 69 74  r.c module to it
7a60: 65 72 61 74 65 20 74 68 72 6f 75 67 68 20 61 6c  erate through al
7a70: 6c 20 0a 2a 2a 20 70 61 67 65 73 20 69 6e 20 74  l .** pages in t
7a80: 68 65 20 63 61 63 68 65 2e 20 41 74 20 70 72 65  he cache. At pre
7a90: 73 65 6e 74 2c 20 74 68 69 73 20 69 73 20 6f 6e  sent, this is on
7aa0: 6c 79 20 72 65 71 75 69 72 65 64 20 69 66 20 74  ly required if t
7ab0: 68 65 0a 2a 2a 20 53 51 4c 49 54 45 5f 43 48 45  he.** SQLITE_CHE
7ac0: 43 4b 5f 50 41 47 45 53 20 6d 61 63 72 6f 20 28  CK_PAGES macro (
7ad0: 75 73 65 64 20 66 6f 72 20 64 65 62 75 67 67 69  used for debuggi
7ae0: 6e 67 29 20 69 73 20 73 70 65 63 69 66 69 65 64  ng) is specified
7af0: 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
7b00: 33 50 63 61 63 68 65 49 74 65 72 61 74 65 28 50  3PcacheIterate(P
7b10: 43 61 63 68 65 20 2a 70 43 61 63 68 65 2c 20 76  Cache *pCache, v
7b20: 6f 69 64 20 28 2a 78 49 74 65 72 29 28 50 67 48  oid (*xIter)(PgH
7b30: 64 72 20 2a 29 29 7b 0a 20 20 50 67 48 64 72 20  dr *)){.  PgHdr 
7b40: 2a 70 3b 0a 20 20 66 6f 72 28 70 3d 70 43 61 63  *p;.  for(p=pCac
7b50: 68 65 2d 3e 70 43 6c 65 61 6e 3b 20 70 3b 20 70  he->pClean; p; p
7b60: 3d 70 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20  =p->pNext){.    
7b70: 78 49 74 65 72 28 70 29 3b 0a 20 20 7d 0a 20 20  xIter(p);.  }.  
7b80: 66 6f 72 28 70 3d 70 43 61 63 68 65 2d 3e 70 44  for(p=pCache->pD
7b90: 69 72 74 79 3b 20 70 3b 20 70 3d 70 2d 3e 70 4e  irty; p; p=p->pN
7ba0: 65 78 74 29 7b 0a 20 20 20 20 78 49 74 65 72 28  ext){.    xIter(
7bb0: 70 29 3b 0a 20 20 7d 0a 7d 0a 23 65 6e 64 69 66  p);.  }.}.#endif
7bc0: 0a 0a 2f 2a 20 0a 2a 2a 20 53 65 74 20 66 6c 61  ../* .** Set fla
7bd0: 67 73 20 6f 6e 20 61 6c 6c 20 70 61 67 65 73 20  gs on all pages 
7be0: 69 6e 20 74 68 65 20 70 61 67 65 20 63 61 63 68  in the page cach
7bf0: 65 20 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74  e .*/.void sqlit
7c00: 65 33 50 63 61 63 68 65 43 6c 65 61 72 46 6c 61  e3PcacheClearFla
7c10: 67 73 28 50 43 61 63 68 65 20 2a 70 43 61 63 68  gs(PCache *pCach
7c20: 65 2c 20 69 6e 74 20 6d 61 73 6b 29 7b 0a 20 20  e, int mask){.  
7c30: 50 67 48 64 72 20 2a 70 3b 0a 0a 20 20 2f 2a 20  PgHdr *p;..  /* 
7c40: 4f 62 74 61 69 6e 20 74 68 65 20 67 6c 6f 62 61  Obtain the globa
7c50: 6c 20 6d 75 74 65 78 20 62 65 66 6f 72 65 20 6d  l mutex before m
7c60: 6f 64 69 66 79 69 6e 67 20 61 6e 79 20 50 67 48  odifying any PgH
7c70: 64 72 2e 66 6c 61 67 73 20 76 61 72 69 61 62 6c  dr.flags variabl
7c80: 65 73 20 0a 20 20 2a 2a 20 6f 72 20 74 72 61 76  es .  ** or trav
7c90: 65 72 73 69 6e 67 20 74 68 65 20 4c 52 55 20 6c  ersing the LRU l
7ca0: 69 73 74 2e 0a 20 20 2a 2f 20 0a 20 20 70 63 61  ist..  */ .  pca
7cb0: 63 68 65 45 6e 74 65 72 4d 75 74 65 78 28 29 3b  cheEnterMutex();
7cc0: 0a 0a 20 20 6d 61 73 6b 20 3d 20 7e 6d 61 73 6b  ..  mask = ~mask
7cd0: 3b 0a 20 20 66 6f 72 28 70 3d 70 43 61 63 68 65  ;.  for(p=pCache
7ce0: 2d 3e 70 44 69 72 74 79 3b 20 70 3b 20 70 3d 70  ->pDirty; p; p=p
7cf0: 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 70 2d  ->pNext){.    p-
7d00: 3e 66 6c 61 67 73 20 26 3d 20 6d 61 73 6b 3b 0a  >flags &= mask;.
7d10: 20 20 7d 0a 20 20 66 6f 72 28 70 3d 70 43 61 63    }.  for(p=pCac
7d20: 68 65 2d 3e 70 43 6c 65 61 6e 3b 20 70 3b 20 70  he->pClean; p; p
7d30: 3d 70 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20  =p->pNext){.    
7d40: 70 2d 3e 66 6c 61 67 73 20 26 3d 20 6d 61 73 6b  p->flags &= mask
7d50: 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 30 3d 3d  ;.  }..  if( 0==
7d60: 28 6d 61 73 6b 26 50 47 48 44 52 5f 4e 45 45 44  (mask&PGHDR_NEED
7d70: 5f 53 59 4e 43 29 20 29 7b 0a 20 20 20 20 70 43  _SYNC) ){.    pC
7d80: 61 63 68 65 2d 3e 70 53 79 6e 63 65 64 20 3d 20  ache->pSynced = 
7d90: 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 54 61  pCache->pDirtyTa
7da0: 69 6c 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20  il;.    assert( 
7db0: 21 70 43 61 63 68 65 2d 3e 70 53 79 6e 63 65 64  !pCache->pSynced
7dc0: 20 7c 7c 20 28 70 43 61 63 68 65 2d 3e 70 53 79   || (pCache->pSy
7dd0: 6e 63 65 64 2d 3e 66 6c 61 67 73 26 50 47 48 44  nced->flags&PGHD
7de0: 52 5f 4e 45 45 44 5f 53 59 4e 43 29 3d 3d 30 20  R_NEED_SYNC)==0 
7df0: 29 3b 0a 20 20 7d 0a 0a 20 20 70 63 61 63 68 65  );.  }..  pcache
7e00: 45 78 69 74 4d 75 74 65 78 28 29 3b 0a 7d 0a 0a  ExitMutex();.}..
7e10: 2f 2a 0a 2a 2a 20 53 65 74 20 74 68 65 20 73 75  /*.** Set the su
7e20: 67 67 65 73 74 65 64 20 63 61 63 68 65 2d 73 69  ggested cache-si
7e30: 7a 65 20 76 61 6c 75 65 2e 0a 2a 2f 0a 69 6e 74  ze value..*/.int
7e40: 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 47 65   sqlite3PcacheGe
7e50: 74 43 61 63 68 65 73 69 7a 65 28 50 43 61 63 68  tCachesize(PCach
7e60: 65 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 72 65  e *pCache){.  re
7e70: 74 75 72 6e 20 70 43 61 63 68 65 2d 3e 6e 4d 61  turn pCache->nMa
7e80: 78 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20  x;.}../*.** Set 
7e90: 74 68 65 20 73 75 67 67 65 73 74 65 64 20 63 61  the suggested ca
7ea0: 63 68 65 2d 73 69 7a 65 20 76 61 6c 75 65 2e 0a  che-size value..
7eb0: 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50  */.void sqlite3P
7ec0: 63 61 63 68 65 53 65 74 43 61 63 68 65 73 69 7a  cacheSetCachesiz
7ed0: 65 28 50 43 61 63 68 65 20 2a 70 43 61 63 68 65  e(PCache *pCache
7ee0: 2c 20 69 6e 74 20 6d 78 50 61 67 65 29 7b 0a 20  , int mxPage){. 
7ef0: 20 69 66 28 20 6d 78 50 61 67 65 3c 31 30 20 29   if( mxPage<10 )
7f00: 7b 0a 20 20 20 20 6d 78 50 61 67 65 20 3d 20 31  {.    mxPage = 1
7f10: 30 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 43 61  0;.  }.  if( pCa
7f20: 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20  che->bPurgeable 
7f30: 29 7b 0a 20 20 20 20 70 63 61 63 68 65 45 6e 74  ){.    pcacheEnt
7f40: 65 72 4d 75 74 65 78 28 29 3b 0a 20 20 20 20 70  erMutex();.    p
7f50: 63 61 63 68 65 5f 67 2e 6e 4d 61 78 50 61 67 65  cache_g.nMaxPage
7f60: 20 2d 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78   -= pCache->nMax
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 2b 3d 20 6d 78 50 61 67  MaxPage += mxPag
7f90: 65 3b 0a 20 20 20 20 70 63 61 63 68 65 45 6e 66  e;.    pcacheEnf
7fa0: 6f 72 63 65 4d 61 78 50 61 67 65 28 29 3b 0a 20  orceMaxPage();. 
7fb0: 20 20 20 70 63 61 63 68 65 45 78 69 74 4d 75 74     pcacheExitMut
7fc0: 65 78 28 29 3b 0a 20 20 7d 0a 20 20 70 43 61 63  ex();.  }.  pCac
7fd0: 68 65 2d 3e 6e 4d 61 78 20 3d 20 6d 78 50 61 67  he->nMax = mxPag
7fe0: 65 3b 0a 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c  e;.}..#ifdef SQL
7ff0: 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52  ITE_ENABLE_MEMOR
8000: 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 0a 2f 2a 0a  Y_MANAGEMENT./*.
8010: 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
8020: 20 69 73 20 63 61 6c 6c 65 64 20 74 6f 20 66 72   is called to fr
8030: 65 65 20 73 75 70 65 72 66 6c 75 6f 75 73 20 64  ee superfluous d
8040: 79 6e 61 6d 69 63 61 6c 6c 79 20 61 6c 6c 6f 63  ynamically alloc
8050: 61 74 65 64 20 6d 65 6d 6f 72 79 0a 2a 2a 20 68  ated memory.** h
8060: 65 6c 64 20 62 79 20 74 68 65 20 70 61 67 65 72  eld by the pager
8070: 20 73 79 73 74 65 6d 2e 20 4d 65 6d 6f 72 79 20   system. Memory 
8080: 69 6e 20 75 73 65 20 62 79 20 61 6e 79 20 53 51  in use by any SQ
8090: 4c 69 74 65 20 70 61 67 65 72 20 61 6c 6c 6f 63  Lite pager alloc
80a0: 61 74 65 64 0a 2a 2a 20 62 79 20 74 68 65 20 63  ated.** by the c
80b0: 75 72 72 65 6e 74 20 74 68 72 65 61 64 20 6d 61  urrent thread ma
80c0: 79 20 62 65 20 73 71 6c 69 74 65 33 5f 66 72 65  y be sqlite3_fre
80d0: 65 28 29 65 64 2e 0a 2a 2a 0a 2a 2a 20 6e 52 65  e()ed..**.** nRe
80e0: 71 20 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20  q is the number 
80f0: 6f 66 20 62 79 74 65 73 20 6f 66 20 6d 65 6d 6f  of bytes of memo
8100: 72 79 20 72 65 71 75 69 72 65 64 2e 20 4f 6e 63  ry required. Onc
8110: 65 20 74 68 69 73 20 6d 75 63 68 20 68 61 73 0a  e this much has.
8120: 2a 2a 20 62 65 65 6e 20 72 65 6c 65 61 73 65 64  ** been released
8130: 2c 20 74 68 65 20 66 75 6e 63 74 69 6f 6e 20 72  , the function r
8140: 65 74 75 72 6e 73 2e 20 54 68 65 20 72 65 74 75  eturns. The retu
8150: 72 6e 20 76 61 6c 75 65 20 69 73 20 74 68 65 20  rn value is the 
8160: 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 0a 2a 2a  total number .**
8170: 20 6f 66 20 62 79 74 65 73 20 6f 66 20 6d 65 6d   of bytes of mem
8180: 6f 72 79 20 72 65 6c 65 61 73 65 64 2e 0a 2a 2f  ory released..*/
8190: 0a 69 6e 74 20 73 71 6c 69 74 65 33 50 63 61 63  .int sqlite3Pcac
81a0: 68 65 52 65 6c 65 61 73 65 4d 65 6d 6f 72 79 28  heReleaseMemory(
81b0: 69 6e 74 20 6e 52 65 71 29 7b 0a 20 20 69 6e 74  int nReq){.  int
81c0: 20 6e 46 72 65 65 20 3d 20 30 3b 0a 20 20 69 66   nFree = 0;.  if
81d0: 28 20 70 63 61 63 68 65 5f 67 2e 70 53 74 61 72  ( pcache_g.pStar
81e0: 74 3d 3d 30 20 29 7b 0a 20 20 20 20 50 67 48 64  t==0 ){.    PgHd
81f0: 72 20 2a 70 3b 0a 20 20 20 20 70 63 61 63 68 65  r *p;.    pcache
8200: 45 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a 20 20  EnterMutex();.  
8210: 20 20 77 68 69 6c 65 28 20 28 6e 52 65 71 3c 30    while( (nReq<0
8220: 20 7c 7c 20 6e 46 72 65 65 3c 6e 52 65 71 29 20   || nFree<nReq) 
8230: 26 26 20 28 70 3d 70 63 61 63 68 65 52 65 63 79  && (p=pcacheRecy
8240: 63 6c 65 50 61 67 65 28 29 29 20 29 7b 0a 20 20  clePage()) ){.  
8250: 20 20 20 20 6e 46 72 65 65 20 2b 3d 20 70 63 61      nFree += pca
8260: 63 68 65 50 61 67 65 53 69 7a 65 28 70 29 3b 0a  chePageSize(p);.
8270: 20 20 20 20 20 20 70 63 61 63 68 65 50 61 67 65        pcachePage
8280: 46 72 65 65 28 70 29 3b 0a 20 20 20 20 7d 0a 20  Free(p);.    }. 
8290: 20 20 20 70 63 61 63 68 65 45 78 69 74 4d 75 74     pcacheExitMut
82a0: 65 78 28 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75  ex();.  }.  retu
82b0: 72 6e 20 6e 46 72 65 65 3b 0a 7d 0a 23 65 6e 64  rn nFree;.}.#end
82c0: 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f 45 4e 41  if /* SQLITE_ENA
82d0: 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47  BLE_MEMORY_MANAG
82e0: 45 4d 45 4e 54 20 2a 2f 0a 0a 23 69 66 64 65 66  EMENT */..#ifdef
82f0: 20 53 51 4c 49 54 45 5f 54 45 53 54 0a 76 6f 69   SQLITE_TEST.voi
8300: 64 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 53  d sqlite3PcacheS
8310: 74 61 74 73 28 0a 20 20 69 6e 74 20 2a 70 6e 43  tats(.  int *pnC
8320: 75 72 72 65 6e 74 2c 0a 20 20 69 6e 74 20 2a 70  urrent,.  int *p
8330: 6e 4d 61 78 2c 0a 20 20 69 6e 74 20 2a 70 6e 4d  nMax,.  int *pnM
8340: 69 6e 2c 0a 20 20 69 6e 74 20 2a 70 6e 52 65 63  in,.  int *pnRec
8350: 79 63 6c 61 62 6c 65 0a 29 7b 0a 20 20 50 67 48  yclable.){.  PgH
8360: 64 72 20 2a 70 3b 0a 20 20 69 6e 74 20 6e 52 65  dr *p;.  int nRe
8370: 63 79 63 6c 61 62 6c 65 20 3d 20 30 3b 0a 20 20  cyclable = 0;.  
8380: 66 6f 72 28 70 3d 70 63 61 63 68 65 5f 67 2e 70  for(p=pcache_g.p
8390: 4c 72 75 48 65 61 64 3b 20 70 3b 20 70 3d 70 2d  LruHead; p; p=p-
83a0: 3e 70 4e 65 78 74 4c 72 75 29 7b 0a 20 20 20 20  >pNextLru){.    
83b0: 6e 52 65 63 79 63 6c 61 62 6c 65 2b 2b 3b 0a 20  nRecyclable++;. 
83c0: 20 7d 0a 0a 20 20 2a 70 6e 43 75 72 72 65 6e 74   }..  *pnCurrent
83d0: 20 3d 20 70 63 61 63 68 65 5f 67 2e 6e 43 75 72   = pcache_g.nCur
83e0: 72 65 6e 74 50 61 67 65 3b 0a 20 20 2a 70 6e 4d  rentPage;.  *pnM
83f0: 61 78 20 3d 20 70 63 61 63 68 65 5f 67 2e 6e 4d  ax = pcache_g.nM
8400: 61 78 50 61 67 65 3b 0a 20 20 2a 70 6e 4d 69 6e  axPage;.  *pnMin
8410: 20 3d 20 70 63 61 63 68 65 5f 67 2e 6e 4d 69 6e   = pcache_g.nMin
8420: 50 61 67 65 3b 0a 20 20 2a 70 6e 52 65 63 79 63  Page;.  *pnRecyc
8430: 6c 61 62 6c 65 20 3d 20 6e 52 65 63 79 63 6c 61  lable = nRecycla
8440: 62 6c 65 3b 0a 7d 0a 23 65 6e 64 69 66 0a        ble;.}.#endif.