/ Hex Artifact Content
Login

Artifact 8a2d92fb12ede40cfc8532f062763f353ba2868a:


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 32 30 20 32 30 30  che.c,v 1.20 200
01c0: 38 2f 30 38 2f 32 38 20 30 38 3a 33 31 3a 34 38  8/08/28 08:31:48
01d0: 20 64 61 6e 69 65 6c 6b 31 39 37 37 20 45 78 70   danielk1977 Exp
01e0: 20 24 0a 2a 2f 0a 23 69 6e 63 6c 75 64 65 20 22   $.*/.#include "
01f0: 73 71 6c 69 74 65 49 6e 74 2e 68 22 0a 0a 2f 2a  sqliteInt.h"../*
0200: 0a 2a 2a 20 41 20 63 6f 6d 70 6c 65 74 65 20 70  .** A complete p
0210: 61 67 65 20 63 61 63 68 65 20 69 73 20 61 6e 20  age cache is an 
0220: 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 69 73  instance of this
0230: 20 73 74 72 75 63 74 75 72 65 2e 0a 2a 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 76 6f 69 64 20 28 2a 78 44 65   */.  void (*xDe
0840: 73 74 72 6f 79 29 28 50 67 48 64 72 2a 29 3b 20  stroy)(PgHdr*); 
0850: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 61 6c            /* Cal
0860: 6c 65 64 20 77 68 65 6e 20 72 65 66 63 6e 74 20  led when refcnt 
0870: 67 6f 65 73 20 31 2d 3e 30 20 2a 2f 0a 20 20 69  goes 1->0 */.  i
0880: 6e 74 20 28 2a 78 53 74 72 65 73 73 29 28 76 6f  nt (*xStress)(vo
0890: 69 64 2a 2c 50 67 48 64 72 2a 29 3b 20 20 20 20  id*,PgHdr*);    
08a0: 20 20 20 2f 2a 20 43 61 6c 6c 20 74 6f 20 74 72     /* Call to tr
08b0: 79 20 6d 61 6b 65 20 61 20 70 61 67 65 20 63 6c  y make a page cl
08c0: 65 61 6e 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70  ean */.  void *p
08d0: 53 74 72 65 73 73 3b 20 20 20 20 20 20 20 20 20  Stress;         
08e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
08f0: 41 72 67 75 6d 65 6e 74 20 74 6f 20 78 53 74 72  Argument to xStr
0900: 65 73 73 20 2a 2f 0a 20 20 2f 2a 2a 2a 2a 2a 2a  ess */.  /******
0910: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0920: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0930: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0940: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0950: 0a 20 20 2a 2a 20 54 68 65 20 66 69 6e 61 6c 20  .  ** The final 
0960: 67 72 6f 75 70 20 6f 66 20 65 6c 65 6d 65 6e 74  group of element
0970: 73 20 63 61 6e 20 6f 6e 6c 79 20 62 65 20 61 63  s can only be ac
0980: 63 65 73 73 65 64 20 77 68 69 6c 65 20 68 6f 6c  cessed while hol
0990: 64 69 6e 67 20 74 68 65 0a 20 20 2a 2a 20 6d 75  ding the.  ** mu
09a0: 74 65 78 2e 20 20 42 6f 74 68 20 74 68 65 20 63  tex.  Both the c
09b0: 61 63 68 65 20 6f 77 6e 65 72 20 61 6e 64 20 61  ache owner and a
09c0: 6e 79 20 6f 74 68 65 72 20 74 68 72 65 61 64 20  ny other thread 
09d0: 6d 75 73 74 20 68 6f 6c 64 20 74 68 65 20 6d 75  must hold the mu
09e0: 74 65 78 0a 20 20 2a 2a 20 74 6f 20 72 65 61 64  tex.  ** to read
09f0: 20 6f 72 20 77 72 69 74 65 20 61 6e 79 20 6f 66   or write any of
0a00: 20 74 68 65 73 65 20 65 6c 65 6d 65 6e 74 73 2e   these elements.
0a10: 0a 20 20 2a 2f 0a 20 20 69 6e 74 20 6e 50 61 67  .  */.  int nPag
0a20: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
0a30: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
0a40: 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 70  otal number of p
0a50: 61 67 65 73 20 69 6e 20 61 70 48 61 73 68 20 2a  ages in apHash *
0a60: 2f 0a 20 20 69 6e 74 20 6e 48 61 73 68 3b 20 20  /.  int nHash;  
0a70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0a80: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
0a90: 72 20 6f 66 20 73 6c 6f 74 73 20 69 6e 20 61 70  r of slots in ap
0aa0: 48 61 73 68 5b 5d 20 2a 2f 0a 20 20 50 67 48 64  Hash[] */.  PgHd
0ab0: 72 20 2a 2a 61 70 48 61 73 68 3b 20 20 20 20 20  r **apHash;     
0ac0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ad0: 2f 2a 20 48 61 73 68 20 74 61 62 6c 65 20 66 6f  /* Hash table fo
0ae0: 72 20 66 61 73 74 20 6c 6f 6f 6b 75 70 20 62 79  r fast lookup by
0af0: 20 70 67 6e 6f 20 2a 2f 0a 20 20 50 67 48 64 72   pgno */.  PgHdr
0b00: 20 2a 70 43 6c 65 61 6e 3b 20 20 20 20 20 20 20   *pClean;       
0b10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0b20: 2a 20 4c 69 73 74 20 6f 66 20 63 6c 65 61 6e 20  * List of clean 
0b30: 70 61 67 65 73 20 69 6e 20 75 73 65 20 2a 2f 0a  pages in use */.
0b40: 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 73  };../*.** Free s
0b50: 6c 6f 74 73 20 69 6e 20 74 68 65 20 70 61 67 65  lots in the page
0b60: 20 62 6c 6f 63 6b 20 61 6c 6c 6f 63 61 74 6f 72   block allocator
0b70: 0a 2a 2f 0a 74 79 70 65 64 65 66 20 73 74 72 75  .*/.typedef stru
0b80: 63 74 20 50 67 46 72 65 65 73 6c 6f 74 20 50 67  ct PgFreeslot Pg
0b90: 46 72 65 65 73 6c 6f 74 3b 0a 73 74 72 75 63 74  Freeslot;.struct
0ba0: 20 50 67 46 72 65 65 73 6c 6f 74 20 7b 0a 20 20   PgFreeslot {.  
0bb0: 50 67 46 72 65 65 73 6c 6f 74 20 2a 70 4e 65 78  PgFreeslot *pNex
0bc0: 74 3b 20 20 2f 2a 20 4e 65 78 74 20 66 72 65 65  t;  /* Next free
0bd0: 20 73 6c 6f 74 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a   slot */.};../*.
0be0: 2a 2a 20 47 6c 6f 62 61 6c 20 64 61 74 61 20 66  ** Global data f
0bf0: 6f 72 20 74 68 65 20 70 61 67 65 20 63 61 63 68  or the page cach
0c00: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 73 74 72  e..*/.static str
0c10: 75 63 74 20 50 43 61 63 68 65 47 6c 6f 62 61 6c  uct PCacheGlobal
0c20: 20 7b 0a 20 20 69 6e 74 20 69 73 49 6e 69 74 3b   {.  int isInit;
0c30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c40: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
0c50: 20 77 68 65 6e 20 69 6e 69 74 69 61 6c 69 7a 65   when initialize
0c60: 64 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 6d  d */.  sqlite3_m
0c70: 75 74 65 78 20 2a 6d 75 74 65 78 3b 20 20 20 20  utex *mutex;    
0c80: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 73 74             /* st
0c90: 61 74 69 63 20 6d 75 74 65 78 20 4d 55 54 45 58  atic mutex MUTEX
0ca0: 5f 53 54 41 54 49 43 5f 4c 52 55 20 2a 2f 0a 0a  _STATIC_LRU */..
0cb0: 20 20 69 6e 74 20 6e 4d 61 78 50 61 67 65 3b 20    int nMaxPage; 
0cc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0cd0: 20 20 20 20 20 20 2f 2a 20 53 75 6d 20 6f 66 20        /* Sum of 
0ce0: 6e 4d 61 78 50 61 67 65 20 66 6f 72 20 70 75 72  nMaxPage for pur
0cf0: 67 65 61 62 6c 65 20 63 61 63 68 65 73 20 2a 2f  geable caches */
0d00: 0a 20 20 69 6e 74 20 6e 4d 69 6e 50 61 67 65 3b  .  int nMinPage;
0d10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0d20: 20 20 20 20 20 20 20 2f 2a 20 53 75 6d 20 6f 66         /* Sum of
0d30: 20 6e 4d 69 6e 50 61 67 65 20 66 6f 72 20 70 75   nMinPage for pu
0d40: 72 67 65 61 62 6c 65 20 63 61 63 68 65 73 20 2a  rgeable caches *
0d50: 2f 0a 20 20 69 6e 74 20 6e 43 75 72 72 65 6e 74  /.  int nCurrent
0d60: 50 61 67 65 3b 20 20 20 20 20 20 20 20 20 20 20  Page;           
0d70: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
0d80: 72 20 6f 66 20 70 75 72 67 65 61 62 6c 65 20 70  r of purgeable p
0d90: 61 67 65 73 20 61 6c 6c 6f 63 61 74 65 64 20 2a  ages allocated *
0da0: 2f 0a 20 20 50 67 48 64 72 20 2a 70 4c 72 75 48  /.  PgHdr *pLruH
0db0: 65 61 64 2c 20 2a 70 4c 72 75 54 61 69 6c 3b 20  ead, *pLruTail; 
0dc0: 20 20 20 20 20 20 20 20 2f 2a 20 4c 52 55 20 6c          /* LRU l
0dd0: 69 73 74 20 6f 66 20 75 6e 75 73 65 64 20 63 6c  ist of unused cl
0de0: 65 61 6e 20 70 67 73 20 2a 2f 0a 0a 20 20 2f 2a  ean pgs */..  /*
0df0: 20 56 61 72 69 61 62 6c 65 73 20 72 65 6c 61 74   Variables relat
0e00: 65 64 20 74 6f 20 53 51 4c 49 54 45 5f 43 4f 4e  ed to SQLITE_CON
0e10: 46 49 47 5f 50 41 47 45 43 41 43 48 45 20 73 65  FIG_PAGECACHE se
0e20: 74 74 69 6e 67 73 2e 20 2a 2f 0a 20 20 69 6e 74  ttings. */.  int
0e30: 20 73 7a 53 6c 6f 74 3b 20 20 20 20 20 20 20 20   szSlot;        
0e40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e50: 20 2f 2a 20 53 69 7a 65 20 6f 66 20 65 61 63 68   /* Size of each
0e60: 20 66 72 65 65 20 73 6c 6f 74 20 2a 2f 0a 20 20   free slot */.  
0e70: 76 6f 69 64 20 2a 70 53 74 61 72 74 2c 20 2a 70  void *pStart, *p
0e80: 45 6e 64 3b 20 20 20 20 20 20 20 20 20 20 20 20  End;            
0e90: 20 20 20 20 2f 2a 20 42 6f 75 6e 64 73 20 6f 66      /* Bounds of
0ea0: 20 70 61 67 65 63 61 63 68 65 20 6d 61 6c 6c 6f   pagecache mallo
0eb0: 63 20 72 61 6e 67 65 20 2a 2f 0a 20 20 50 67 46  c range */.  PgF
0ec0: 72 65 65 73 6c 6f 74 20 2a 70 46 72 65 65 3b 20  reeslot *pFree; 
0ed0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ee0: 20 2f 2a 20 46 72 65 65 20 70 61 67 65 20 62 6c   /* Free page bl
0ef0: 6f 63 6b 73 20 2a 2f 0a 7d 20 70 63 61 63 68 65  ocks */.} pcache
0f00: 20 3d 20 7b 30 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41   = {0};../*.** A
0f10: 6c 6c 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62  ll global variab
0f20: 6c 65 73 20 75 73 65 64 20 62 79 20 74 68 69 73  les used by this
0f30: 20 6d 6f 64 75 6c 65 20 28 61 6c 6c 20 6f 66 20   module (all of 
0f40: 77 68 69 63 68 20 61 72 65 20 67 72 6f 75 70 65  which are groupe
0f50: 64 20 0a 2a 2a 20 74 6f 67 65 74 68 65 72 20 69  d .** together i
0f60: 6e 20 67 6c 6f 62 61 6c 20 73 74 72 75 63 74 75  n global structu
0f70: 72 65 20 22 70 63 61 63 68 65 22 20 61 62 6f 76  re "pcache" abov
0f80: 65 29 20 61 72 65 20 70 72 6f 74 65 63 74 65 64  e) are protected
0f90: 20 62 79 20 74 68 65 20 73 74 61 74 69 63 20 0a   by the static .
0fa0: 2a 2a 20 53 51 4c 49 54 45 5f 4d 55 54 45 58 5f  ** SQLITE_MUTEX_
0fb0: 53 54 41 54 49 43 5f 4c 52 55 20 6d 75 74 65 78  STATIC_LRU mutex
0fc0: 2e 20 41 20 70 6f 69 6e 74 65 72 20 74 6f 20 74  . A pointer to t
0fd0: 68 69 73 20 6d 75 74 65 78 20 69 73 20 73 74 6f  his mutex is sto
0fe0: 72 65 64 20 69 6e 0a 2a 2a 20 76 61 72 69 61 62  red in.** variab
0ff0: 6c 65 20 22 70 63 61 63 68 65 2e 6d 75 74 65 78  le "pcache.mutex
1000: 22 2e 0a 2a 2a 0a 2a 2a 20 53 6f 6d 65 20 65 6c  "..**.** Some el
1010: 65 6d 65 6e 74 73 20 6f 66 20 74 68 65 20 50 43  ements of the PC
1020: 61 63 68 65 20 61 6e 64 20 50 67 48 64 72 20 73  ache and PgHdr s
1030: 74 72 75 63 74 75 72 65 73 20 61 72 65 20 70 72  tructures are pr
1040: 6f 74 65 63 74 65 64 20 62 79 20 74 68 65 20 0a  otected by the .
1050: 2a 2a 20 53 51 4c 49 54 45 5f 4d 55 54 45 58 5f  ** SQLITE_MUTEX_
1060: 53 54 41 54 55 53 5f 4c 52 55 20 6d 75 74 65 78  STATUS_LRU mutex
1070: 20 61 6e 64 20 6f 74 68 65 72 20 61 72 65 20 6e   and other are n
1080: 6f 74 2e 20 20 54 68 65 20 70 72 6f 74 65 63 74  ot.  The protect
1090: 65 64 0a 2a 2a 20 65 6c 65 6d 65 6e 74 73 20 61  ed.** elements a
10a0: 72 65 20 67 72 6f 75 70 65 64 20 61 74 20 74 68  re grouped at th
10b0: 65 20 65 6e 64 20 6f 66 20 74 68 65 20 73 74 72  e end of the str
10c0: 75 63 74 75 72 65 73 20 61 6e 64 20 61 72 65 20  uctures and are 
10d0: 63 6c 65 61 72 6c 79 0a 2a 2a 20 6d 61 72 6b 65  clearly.** marke
10e0: 64 2e 0a 2a 2a 0a 2a 2a 20 55 73 65 20 74 68 65  d..**.** Use the
10f0: 20 66 6f 6c 6c 6f 77 69 6e 67 20 6d 61 63 72 6f   following macro
1100: 73 20 6d 75 73 74 20 73 75 72 72 6f 75 6e 64 20  s must surround 
1110: 61 6c 6c 20 61 63 63 65 73 73 20 28 72 65 61 64  all access (read
1120: 20 6f 72 20 77 72 69 74 65 29 0a 2a 2a 20 6f 66   or write).** of
1130: 20 70 72 6f 74 65 63 74 65 64 20 65 6c 65 6d 65   protected eleme
1140: 6e 74 73 2e 20 20 54 68 65 20 6d 75 74 65 78 20  nts.  The mutex 
1150: 69 73 20 6e 6f 74 20 72 65 63 75 72 73 69 76 65  is not recursive
1160: 20 61 6e 64 20 6d 61 79 20 6e 6f 74 20 62 65 0a   and may not be.
1170: 2a 2a 20 65 6e 74 65 72 65 64 20 6d 6f 72 65 20  ** entered more 
1180: 74 68 61 6e 20 6f 6e 63 65 2e 20 20 54 68 65 20  than once.  The 
1190: 70 63 61 63 68 65 4d 75 74 65 78 48 65 6c 64 28  pcacheMutexHeld(
11a0: 29 20 6d 61 63 72 6f 20 73 68 6f 75 6c 64 20 6f  ) macro should o
11b0: 6e 6c 79 20 62 65 0a 2a 2a 20 75 73 65 64 20 77  nly be.** used w
11c0: 69 74 68 69 6e 20 61 6e 20 61 73 73 65 72 74 28  ithin an assert(
11d0: 29 20 74 6f 20 76 65 72 69 66 79 20 74 68 61 74  ) to verify that
11e0: 20 74 68 65 20 6d 75 74 65 78 20 69 73 20 62 65   the mutex is be
11f0: 69 6e 67 20 68 65 6c 64 2e 0a 2a 2f 0a 23 64 65  ing held..*/.#de
1200: 66 69 6e 65 20 70 63 61 63 68 65 45 6e 74 65 72  fine pcacheEnter
1210: 4d 75 74 65 78 28 29 20 73 71 6c 69 74 65 33 5f  Mutex() sqlite3_
1220: 6d 75 74 65 78 5f 65 6e 74 65 72 28 70 63 61 63  mutex_enter(pcac
1230: 68 65 2e 6d 75 74 65 78 29 0a 23 64 65 66 69 6e  he.mutex).#defin
1240: 65 20 70 63 61 63 68 65 45 78 69 74 4d 75 74 65  e pcacheExitMute
1250: 78 28 29 20 20 73 71 6c 69 74 65 33 5f 6d 75 74  x()  sqlite3_mut
1260: 65 78 5f 6c 65 61 76 65 28 70 63 61 63 68 65 2e  ex_leave(pcache.
1270: 6d 75 74 65 78 29 0a 23 64 65 66 69 6e 65 20 70  mutex).#define p
1280: 63 61 63 68 65 4d 75 74 65 78 48 65 6c 64 28 29  cacheMutexHeld()
1290: 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f    sqlite3_mutex_
12a0: 68 65 6c 64 28 70 63 61 63 68 65 2e 6d 75 74 65  held(pcache.mute
12b0: 78 29 0a 0a 2f 2a 0a 2a 2a 20 53 6f 6d 65 20 6f  x)../*.** Some o
12c0: 66 20 74 68 65 20 61 73 73 65 72 74 28 29 20 6d  f the assert() m
12d0: 61 63 72 6f 73 20 69 6e 20 74 68 69 73 20 63 6f  acros in this co
12e0: 64 65 20 61 72 65 20 74 6f 6f 20 65 78 70 65 6e  de are too expen
12f0: 73 69 76 65 20 74 6f 20 72 75 6e 0a 2a 2a 20 65  sive to run.** e
1300: 76 65 6e 20 64 75 72 69 6e 67 20 6e 6f 72 6d 61  ven during norma
1310: 6c 20 64 65 62 75 67 67 69 6e 67 2e 20 20 55 73  l debugging.  Us
1320: 65 20 74 68 65 6d 20 6f 6e 6c 79 20 72 61 72 65  e them only rare
1330: 6c 79 20 6f 6e 20 6c 6f 6e 67 2d 72 75 6e 6e 69  ly on long-runni
1340: 6e 67 0a 2a 2a 20 74 65 73 74 73 2e 20 20 45 6e  ng.** tests.  En
1350: 61 62 6c 65 20 74 68 65 20 65 78 70 65 6e 73 69  able the expensi
1360: 76 65 20 61 73 73 65 72 74 73 20 75 73 69 6e 67  ve asserts using
1370: 20 74 68 65 0a 2a 2a 20 2d 44 53 51 4c 49 54 45   the.** -DSQLITE
1380: 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49 56  _ENABLE_EXPENSIV
1390: 45 5f 41 53 53 45 52 54 3d 31 20 63 6f 6d 70 69  E_ASSERT=1 compi
13a0: 6c 65 2d 74 69 6d 65 20 6f 70 74 69 6f 6e 2e 0a  le-time option..
13b0: 2a 2f 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45  */.#ifdef SQLITE
13c0: 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49 56  _ENABLE_EXPENSIV
13d0: 45 5f 41 53 53 45 52 54 0a 23 20 64 65 66 69 6e  E_ASSERT.# defin
13e0: 65 20 65 78 70 65 6e 73 69 76 65 5f 61 73 73 65  e expensive_asse
13f0: 72 74 28 58 29 20 20 61 73 73 65 72 74 28 58 29  rt(X)  assert(X)
1400: 0a 23 65 6c 73 65 0a 23 20 64 65 66 69 6e 65 20  .#else.# define 
1410: 65 78 70 65 6e 73 69 76 65 5f 61 73 73 65 72 74  expensive_assert
1420: 28 58 29 0a 23 65 6e 64 69 66 0a 0a 2f 2a 2a 2a  (X).#endif../***
1430: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1440: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 20  *************** 
1450: 4c 69 6e 6b 65 64 20 4c 69 73 74 20 4d 61 6e 61  Linked List Mana
1460: 67 65 6d 65 6e 74 20 2a 2a 2a 2a 2a 2a 2a 2a 2a  gement *********
1470: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 23 69  ***********/..#i
1480: 66 20 21 64 65 66 69 6e 65 64 28 4e 44 45 42 55  f !defined(NDEBU
1490: 47 29 20 26 26 20 64 65 66 69 6e 65 64 28 53 51  G) && defined(SQ
14a0: 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45  LITE_ENABLE_EXPE
14b0: 4e 53 49 56 45 5f 41 53 53 45 52 54 29 0a 2f 2a  NSIVE_ASSERT)./*
14c0: 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65  .** This routine
14d0: 20 76 65 72 69 66 69 65 73 20 74 68 61 74 20 74   verifies that t
14e0: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 65 6e 74  he number of ent
14f0: 72 69 65 73 20 69 6e 20 74 68 65 20 68 61 73 68  ries in the hash
1500: 20 74 61 62 6c 65 0a 2a 2a 20 69 73 20 70 43 61   table.** is pCa
1510: 63 68 65 2d 3e 6e 50 61 67 65 2e 20 20 54 68 69  che->nPage.  Thi
1520: 73 20 72 6f 75 74 69 6e 65 20 69 73 20 75 73 65  s routine is use
1530: 64 20 77 69 74 68 69 6e 20 61 73 73 65 72 74 28  d within assert(
1540: 29 20 73 74 61 74 65 6d 65 6e 74 73 0a 2a 2a 20  ) statements.** 
1550: 6f 6e 6c 79 20 61 6e 64 20 69 73 20 74 68 65 72  only and is ther
1560: 65 66 6f 72 65 20 64 69 73 61 62 6c 65 64 20 64  efore disabled d
1570: 75 72 69 6e 67 20 70 72 6f 64 75 63 74 69 6f 6e  uring production
1580: 20 62 75 69 6c 64 73 2e 0a 2a 2f 0a 73 74 61 74   builds..*/.stat
1590: 69 63 20 69 6e 74 20 70 63 61 63 68 65 43 68 65  ic int pcacheChe
15a0: 63 6b 48 61 73 68 43 6f 75 6e 74 28 50 43 61 63  ckHashCount(PCac
15b0: 68 65 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 69  he *pCache){.  i
15c0: 6e 74 20 69 3b 0a 20 20 69 6e 74 20 6e 50 61 67  nt i;.  int nPag
15d0: 65 20 3d 20 30 3b 0a 20 20 66 6f 72 28 69 3d 30  e = 0;.  for(i=0
15e0: 3b 20 69 3c 70 43 61 63 68 65 2d 3e 6e 48 61 73  ; i<pCache->nHas
15f0: 68 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 50 67 48  h; i++){.    PgH
1600: 64 72 20 2a 70 3b 0a 20 20 20 20 66 6f 72 28 70  dr *p;.    for(p
1610: 3d 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b  =pCache->apHash[
1620: 69 5d 3b 20 70 3b 20 70 3d 70 2d 3e 70 4e 65 78  i]; p; p=p->pNex
1630: 74 48 61 73 68 29 7b 0a 20 20 20 20 20 20 6e 50  tHash){.      nP
1640: 61 67 65 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 7d  age++;.    }.  }
1650: 0a 20 20 61 73 73 65 72 74 28 20 6e 50 61 67 65  .  assert( nPage
1660: 3d 3d 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 20  ==pCache->nPage 
1670: 29 3b 0a 20 20 72 65 74 75 72 6e 20 31 3b 0a 7d  );.  return 1;.}
1680: 0a 23 65 6e 64 69 66 20 2f 2a 20 21 4e 44 45 42  .#endif /* !NDEB
1690: 55 47 20 26 26 20 53 51 4c 49 54 45 5f 45 4e 41  UG && SQLITE_ENA
16a0: 42 4c 45 5f 45 58 50 45 4e 53 49 56 45 5f 41 53  BLE_EXPENSIVE_AS
16b0: 53 45 52 54 20 2a 2f 0a 0a 0a 23 69 66 20 21 64  SERT */...#if !d
16c0: 65 66 69 6e 65 64 28 4e 44 45 42 55 47 29 20 26  efined(NDEBUG) &
16d0: 26 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45  & defined(SQLITE
16e0: 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49 56  _ENABLE_EXPENSIV
16f0: 45 5f 41 53 53 45 52 54 29 0a 2f 2a 0a 2a 2a 20  E_ASSERT)./*.** 
1700: 42 61 73 65 64 20 6f 6e 20 74 68 65 20 63 75 72  Based on the cur
1710: 72 65 6e 74 20 76 61 6c 75 65 20 6f 66 20 50 43  rent value of PC
1720: 61 63 68 65 2e 6e 52 65 66 20 61 6e 64 20 74 68  ache.nRef and th
1730: 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68  e contents of th
1740: 65 0a 2a 2a 20 50 43 61 63 68 65 2e 70 44 69 72  e.** PCache.pDir
1750: 74 79 20 6c 69 73 74 2c 20 72 65 74 75 72 6e 20  ty list, return 
1760: 74 68 65 20 65 78 70 65 63 74 65 64 20 76 61 6c  the expected val
1770: 75 65 20 6f 66 20 74 68 65 20 50 43 61 63 68 65  ue of the PCache
1780: 2e 6e 50 69 6e 6e 65 64 0a 2a 2a 20 63 6f 75 6e  .nPinned.** coun
1790: 74 65 72 2e 20 54 68 69 73 20 69 73 20 6f 6e 6c  ter. This is onl
17a0: 79 20 75 73 65 64 20 69 6e 20 64 65 62 75 67 67  y used in debugg
17b0: 69 6e 67 20 62 75 69 6c 64 73 2c 20 61 73 20 66  ing builds, as f
17c0: 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 20 20  ollows:.**.**   
17d0: 65 78 70 65 6e 73 69 76 65 5f 61 73 73 65 72 74  expensive_assert
17e0: 28 20 70 43 61 63 68 65 2d 3e 6e 50 69 6e 6e 65  ( pCache->nPinne
17f0: 64 3d 3d 70 63 61 63 68 65 50 69 6e 6e 65 64 43  d==pcachePinnedC
1800: 6f 75 6e 74 28 70 43 61 63 68 65 29 20 29 3b 0a  ount(pCache) );.
1810: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 70 63  */.static int pc
1820: 61 63 68 65 50 69 6e 6e 65 64 43 6f 75 6e 74 28  achePinnedCount(
1830: 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 29 7b  PCache *pCache){
1840: 0a 20 20 50 67 48 64 72 20 2a 70 3b 0a 20 20 69  .  PgHdr *p;.  i
1850: 6e 74 20 6e 50 69 6e 6e 65 64 20 3d 20 70 43 61  nt nPinned = pCa
1860: 63 68 65 2d 3e 6e 52 65 66 3b 0a 20 20 66 6f 72  che->nRef;.  for
1870: 28 70 3d 70 43 61 63 68 65 2d 3e 70 44 69 72 74  (p=pCache->pDirt
1880: 79 3b 20 70 3b 20 70 3d 70 2d 3e 70 4e 65 78 74  y; p; p=p->pNext
1890: 29 7b 0a 20 20 20 20 69 66 28 20 70 2d 3e 6e 52  ){.    if( p->nR
18a0: 65 66 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 6e  ef==0 ){.      n
18b0: 50 69 6e 6e 65 64 2b 2b 3b 0a 20 20 20 20 7d 0a  Pinned++;.    }.
18c0: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 6e 50 69    }.  return nPi
18d0: 6e 6e 65 64 3b 0a 7d 0a 23 65 6e 64 69 66 20 2f  nned;.}.#endif /
18e0: 2a 20 21 4e 44 45 42 55 47 20 26 26 20 53 51 4c  * !NDEBUG && SQL
18f0: 49 54 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e  ITE_ENABLE_EXPEN
1900: 53 49 56 45 5f 41 53 53 45 52 54 20 2a 2f 0a 0a  SIVE_ASSERT */..
1910: 0a 23 69 66 20 21 64 65 66 69 6e 65 64 28 4e 44  .#if !defined(ND
1920: 45 42 55 47 29 20 26 26 20 64 65 66 69 6e 65 64  EBUG) && defined
1930: 28 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 45  (SQLITE_ENABLE_E
1940: 58 50 45 4e 53 49 56 45 5f 41 53 53 45 52 54 29  XPENSIVE_ASSERT)
1950: 0a 2f 2a 0a 2a 2a 20 43 68 65 63 6b 20 74 68 61  ./*.** Check tha
1960: 74 20 74 68 65 20 70 43 61 63 68 65 2d 3e 70 53  t the pCache->pS
1970: 79 6e 63 65 64 20 76 61 72 69 61 62 6c 65 20 69  ynced variable i
1980: 73 20 73 65 74 20 63 6f 72 72 65 63 74 6c 79 2e  s set correctly.
1990: 20 49 66 20 69 74 0a 2a 2a 20 69 73 20 6e 6f 74   If it.** is not
19a0: 2c 20 65 69 74 68 65 72 20 66 61 69 6c 20 61 6e  , either fail an
19b0: 20 61 73 73 65 72 74 20 6f 72 20 72 65 74 75 72   assert or retur
19c0: 6e 20 7a 65 72 6f 2e 20 4f 74 68 65 72 77 69 73  n zero. Otherwis
19d0: 65 2c 20 72 65 74 75 72 6e 0a 2a 2a 20 6e 6f 6e  e, return.** non
19e0: 2d 7a 65 72 6f 2e 20 54 68 69 73 20 69 73 20 6f  -zero. This is o
19f0: 6e 6c 79 20 75 73 65 64 20 69 6e 20 64 65 62 75  nly used in debu
1a00: 67 67 69 6e 67 20 62 75 69 6c 64 73 2c 20 61 73  gging builds, as
1a10: 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20   follows:.**.** 
1a20: 20 20 65 78 70 65 6e 73 69 76 65 5f 61 73 73 65    expensive_asse
1a30: 72 74 28 20 70 63 61 63 68 65 43 68 65 63 6b 53  rt( pcacheCheckS
1a40: 79 6e 63 65 64 28 70 43 61 63 68 65 29 20 29 3b  ynced(pCache) );
1a50: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 70  .*/.static int p
1a60: 63 61 63 68 65 43 68 65 63 6b 53 79 6e 63 65 64  cacheCheckSynced
1a70: 28 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 29  (PCache *pCache)
1a80: 7b 0a 20 20 50 67 48 64 72 20 2a 70 20 3d 20 70  {.  PgHdr *p = p
1a90: 43 61 63 68 65 2d 3e 70 44 69 72 74 79 54 61 69  Cache->pDirtyTai
1aa0: 6c 3b 0a 20 20 66 6f 72 28 70 3d 70 43 61 63 68  l;.  for(p=pCach
1ab0: 65 2d 3e 70 44 69 72 74 79 54 61 69 6c 3b 20 70  e->pDirtyTail; p
1ac0: 21 3d 70 43 61 63 68 65 2d 3e 70 53 79 6e 63 65  !=pCache->pSynce
1ad0: 64 3b 20 70 3d 70 2d 3e 70 50 72 65 76 29 7b 0a  d; p=p->pPrev){.
1ae0: 20 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e 6e      assert( p->n
1af0: 52 65 66 20 7c 7c 20 28 70 2d 3e 66 6c 61 67 73  Ref || (p->flags
1b00: 26 50 47 48 44 52 5f 4e 45 45 44 5f 53 59 4e 43  &PGHDR_NEED_SYNC
1b10: 29 20 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  ) );.  }.  retur
1b20: 6e 20 28 70 3d 3d 30 20 7c 7c 20 70 2d 3e 6e 52  n (p==0 || p->nR
1b30: 65 66 20 7c 7c 20 28 70 2d 3e 66 6c 61 67 73 26  ef || (p->flags&
1b40: 50 47 48 44 52 5f 4e 45 45 44 5f 53 59 4e 43 29  PGHDR_NEED_SYNC)
1b50: 3d 3d 30 29 3b 0a 20 20 72 65 74 75 72 6e 20 31  ==0);.  return 1
1b60: 3b 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a 20 21 4e  ;.}.#endif /* !N
1b70: 44 45 42 55 47 20 26 26 20 53 51 4c 49 54 45 5f  DEBUG && SQLITE_
1b80: 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49 56 45  ENABLE_EXPENSIVE
1b90: 5f 41 53 53 45 52 54 20 2a 2f 0a 0a 0a 0a 2f 2a  _ASSERT */..../*
1ba0: 0a 2a 2a 20 52 65 6d 6f 76 65 20 61 20 70 61 67  .** Remove a pag
1bb0: 65 20 66 72 6f 6d 20 69 74 73 20 68 61 73 68 20  e from its hash 
1bc0: 74 61 62 6c 65 20 28 50 43 61 63 68 65 2e 61 70  table (PCache.ap
1bd0: 48 61 73 68 5b 5d 29 2e 0a 2a 2f 0a 73 74 61 74  Hash[])..*/.stat
1be0: 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 52 65  ic void pcacheRe
1bf0: 6d 6f 76 65 46 72 6f 6d 48 61 73 68 28 50 67 48  moveFromHash(PgH
1c00: 64 72 20 2a 70 50 61 67 65 29 7b 0a 20 20 2f 2a  dr *pPage){.  /*
1c10: 20 61 73 73 65 72 74 28 20 70 63 61 63 68 65 4d   assert( pcacheM
1c20: 75 74 65 78 48 65 6c 64 28 29 20 29 3b 20 2a 2a  utexHeld() ); **
1c30: 2a 20 46 49 58 4d 45 20 2a 2a 2a 2a 2f 0a 20 20  * FIXME ****/.  
1c40: 69 66 28 20 70 50 61 67 65 2d 3e 70 50 72 65 76  if( pPage->pPrev
1c50: 48 61 73 68 20 29 7b 0a 20 20 20 20 70 50 61 67  Hash ){.    pPag
1c60: 65 2d 3e 70 50 72 65 76 48 61 73 68 2d 3e 70 4e  e->pPrevHash->pN
1c70: 65 78 74 48 61 73 68 20 3d 20 70 50 61 67 65 2d  extHash = pPage-
1c80: 3e 70 4e 65 78 74 48 61 73 68 3b 0a 20 20 7d 65  >pNextHash;.  }e
1c90: 6c 73 65 7b 0a 20 20 20 20 50 43 61 63 68 65 20  lse{.    PCache 
1ca0: 2a 70 43 61 63 68 65 20 3d 20 70 50 61 67 65 2d  *pCache = pPage-
1cb0: 3e 70 43 61 63 68 65 3b 0a 20 20 20 20 75 33 32  >pCache;.    u32
1cc0: 20 68 20 3d 20 70 50 61 67 65 2d 3e 70 67 6e 6f   h = pPage->pgno
1cd0: 20 25 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68   % pCache->nHash
1ce0: 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 43  ;.    assert( pC
1cf0: 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3d  ache->apHash[h]=
1d00: 3d 70 50 61 67 65 20 29 3b 0a 20 20 20 20 70 43  =pPage );.    pC
1d10: 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 20  ache->apHash[h] 
1d20: 3d 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 48 61  = pPage->pNextHa
1d30: 73 68 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 50  sh;.  }.  if( pP
1d40: 61 67 65 2d 3e 70 4e 65 78 74 48 61 73 68 20 29  age->pNextHash )
1d50: 7b 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 4e 65  {.    pPage->pNe
1d60: 78 74 48 61 73 68 2d 3e 70 50 72 65 76 48 61 73  xtHash->pPrevHas
1d70: 68 20 3d 20 70 50 61 67 65 2d 3e 70 50 72 65 76  h = pPage->pPrev
1d80: 48 61 73 68 3b 0a 20 20 7d 0a 20 20 70 50 61 67  Hash;.  }.  pPag
1d90: 65 2d 3e 70 43 61 63 68 65 2d 3e 6e 50 61 67 65  e->pCache->nPage
1da0: 2d 2d 3b 0a 20 20 65 78 70 65 6e 73 69 76 65 5f  --;.  expensive_
1db0: 61 73 73 65 72 74 28 20 70 63 61 63 68 65 43 68  assert( pcacheCh
1dc0: 65 63 6b 48 61 73 68 43 6f 75 6e 74 28 70 50 61  eckHashCount(pPa
1dd0: 67 65 2d 3e 70 43 61 63 68 65 29 20 29 3b 0a 7d  ge->pCache) );.}
1de0: 0a 0a 2f 2a 0a 2a 2a 20 49 6e 73 65 72 74 20 61  ../*.** Insert a
1df0: 20 70 61 67 65 20 69 6e 74 6f 20 74 68 65 20 68   page into the h
1e00: 61 73 68 20 74 61 62 6c 65 0a 2a 2a 0a 2a 2a 20  ash table.**.** 
1e10: 54 68 65 20 6d 75 74 65 78 20 6d 75 73 74 20 62  The mutex must b
1e20: 65 20 68 65 6c 64 20 62 79 20 74 68 65 20 63 61  e held by the ca
1e30: 6c 6c 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ller..*/.static 
1e40: 76 6f 69 64 20 70 63 61 63 68 65 41 64 64 54 6f  void pcacheAddTo
1e50: 48 61 73 68 28 50 67 48 64 72 20 2a 70 50 61 67  Hash(PgHdr *pPag
1e60: 65 29 7b 0a 20 20 50 43 61 63 68 65 20 2a 70 43  e){.  PCache *pC
1e70: 61 63 68 65 20 3d 20 70 50 61 67 65 2d 3e 70 43  ache = pPage->pC
1e80: 61 63 68 65 3b 0a 20 20 75 33 32 20 68 20 3d 20  ache;.  u32 h = 
1e90: 70 50 61 67 65 2d 3e 70 67 6e 6f 20 25 20 70 43  pPage->pgno % pC
1ea0: 61 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 2f  ache->nHash;.  /
1eb0: 2a 20 61 73 73 65 72 74 28 20 70 63 61 63 68 65  * assert( pcache
1ec0: 4d 75 74 65 78 48 65 6c 64 28 29 20 29 3b 20 2a  MutexHeld() ); *
1ed0: 2a 2a 20 46 49 58 4d 45 20 2a 2a 2a 2a 2a 2f 0a  ** FIXME *****/.
1ee0: 20 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 48 61    pPage->pNextHa
1ef0: 73 68 20 3d 20 70 43 61 63 68 65 2d 3e 61 70 48  sh = pCache->apH
1f00: 61 73 68 5b 68 5d 3b 0a 20 20 70 50 61 67 65 2d  ash[h];.  pPage-
1f10: 3e 70 50 72 65 76 48 61 73 68 20 3d 20 30 3b 0a  >pPrevHash = 0;.
1f20: 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 61 70    if( pCache->ap
1f30: 48 61 73 68 5b 68 5d 20 29 7b 0a 20 20 20 20 70  Hash[h] ){.    p
1f40: 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d  Cache->apHash[h]
1f50: 2d 3e 70 50 72 65 76 48 61 73 68 20 3d 20 70 50  ->pPrevHash = pP
1f60: 61 67 65 3b 0a 20 20 7d 0a 20 20 70 43 61 63 68  age;.  }.  pCach
1f70: 65 2d 3e 61 70 48 61 73 68 5b 68 5d 20 3d 20 70  e->apHash[h] = p
1f80: 50 61 67 65 3b 0a 20 20 70 43 61 63 68 65 2d 3e  Page;.  pCache->
1f90: 6e 50 61 67 65 2b 2b 3b 0a 20 20 65 78 70 65 6e  nPage++;.  expen
1fa0: 73 69 76 65 5f 61 73 73 65 72 74 28 20 70 63 61  sive_assert( pca
1fb0: 63 68 65 43 68 65 63 6b 48 61 73 68 43 6f 75 6e  cheCheckHashCoun
1fc0: 74 28 70 43 61 63 68 65 29 20 29 3b 0a 7d 0a 0a  t(pCache) );.}..
1fd0: 2f 2a 0a 2a 2a 20 41 74 74 65 6d 70 74 20 74 6f  /*.** Attempt to
1fe0: 20 69 6e 63 72 65 61 73 65 20 74 68 65 20 73 69   increase the si
1ff0: 7a 65 20 74 68 65 20 68 61 73 68 20 74 61 62 6c  ze the hash tabl
2000: 65 20 74 6f 20 63 6f 6e 74 61 69 6e 0a 2a 2a 20  e to contain.** 
2010: 61 74 20 6c 65 61 73 74 20 6e 48 61 73 68 20 62  at least nHash b
2020: 75 63 6b 65 74 73 2e 0a 2a 2f 0a 73 74 61 74 69  uckets..*/.stati
2030: 63 20 69 6e 74 20 70 63 61 63 68 65 52 65 73 69  c int pcacheResi
2040: 7a 65 48 61 73 68 28 50 43 61 63 68 65 20 2a 70  zeHash(PCache *p
2050: 43 61 63 68 65 2c 20 69 6e 74 20 6e 48 61 73 68  Cache, int nHash
2060: 29 7b 0a 20 20 50 67 48 64 72 20 2a 70 3b 0a 20  ){.  PgHdr *p;. 
2070: 20 50 67 48 64 72 20 2a 2a 70 4e 65 77 3b 0a 20   PgHdr **pNew;. 
2080: 20 2f 2a 20 61 73 73 65 72 74 28 20 70 63 61 63   /* assert( pcac
2090: 68 65 4d 75 74 65 78 48 65 6c 64 28 29 20 29 3b  heMutexHeld() );
20a0: 20 2a 2a 2a 2a 20 46 49 58 4d 45 20 2a 2a 2a 2a   **** FIXME ****
20b0: 2a 2f 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45  */.#ifdef SQLITE
20c0: 5f 4d 41 4c 4c 4f 43 5f 53 4f 46 54 5f 4c 49 4d  _MALLOC_SOFT_LIM
20d0: 49 54 0a 20 20 69 66 28 20 6e 48 61 73 68 2a 73  IT.  if( nHash*s
20e0: 69 7a 65 6f 66 28 50 67 48 64 72 2a 29 3e 53 51  izeof(PgHdr*)>SQ
20f0: 4c 49 54 45 5f 4d 41 4c 4c 4f 43 5f 53 4f 46 54  LITE_MALLOC_SOFT
2100: 5f 4c 49 4d 49 54 20 29 7b 0a 20 20 20 20 6e 48  _LIMIT ){.    nH
2110: 61 73 68 20 3d 20 53 51 4c 49 54 45 5f 4d 41 4c  ash = SQLITE_MAL
2120: 4c 4f 43 5f 53 4f 46 54 5f 4c 49 4d 49 54 2f 73  LOC_SOFT_LIMIT/s
2130: 69 7a 65 6f 66 28 50 67 48 64 72 20 2a 29 3b 0a  izeof(PgHdr *);.
2140: 20 20 7d 0a 23 65 6e 64 69 66 0a 20 20 70 4e 65    }.#endif.  pNe
2150: 77 20 3d 20 28 50 67 48 64 72 20 2a 2a 29 73 71  w = (PgHdr **)sq
2160: 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a  lite3_malloc(siz
2170: 65 6f 66 28 50 67 48 64 72 2a 29 2a 6e 48 61 73  eof(PgHdr*)*nHas
2180: 68 29 3b 0a 20 20 69 66 28 20 21 70 4e 65 77 20  h);.  if( !pNew 
2190: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51  ){.    return SQ
21a0: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a  LITE_NOMEM;.  }.
21b0: 20 20 6d 65 6d 73 65 74 28 70 4e 65 77 2c 20 30    memset(pNew, 0
21c0: 2c 20 73 69 7a 65 6f 66 28 50 67 48 64 72 20 2a  , sizeof(PgHdr *
21d0: 29 2a 6e 48 61 73 68 29 3b 0a 20 20 73 71 6c 69  )*nHash);.  sqli
21e0: 74 65 33 5f 66 72 65 65 28 70 43 61 63 68 65 2d  te3_free(pCache-
21f0: 3e 61 70 48 61 73 68 29 3b 0a 20 20 70 43 61 63  >apHash);.  pCac
2200: 68 65 2d 3e 61 70 48 61 73 68 20 3d 20 70 4e 65  he->apHash = pNe
2210: 77 3b 0a 20 20 70 43 61 63 68 65 2d 3e 6e 48 61  w;.  pCache->nHa
2220: 73 68 20 3d 20 6e 48 61 73 68 3b 0a 20 20 70 43  sh = nHash;.  pC
2230: 61 63 68 65 2d 3e 6e 50 61 67 65 20 3d 20 30 3b  ache->nPage = 0;
2240: 0a 20 0a 20 20 66 6f 72 28 70 3d 70 43 61 63 68  . .  for(p=pCach
2250: 65 2d 3e 70 43 6c 65 61 6e 3b 20 70 3b 20 70 3d  e->pClean; p; p=
2260: 70 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 70  p->pNext){.    p
2270: 63 61 63 68 65 41 64 64 54 6f 48 61 73 68 28 70  cacheAddToHash(p
2280: 29 3b 0a 20 20 7d 0a 20 20 66 6f 72 28 70 3d 70  );.  }.  for(p=p
2290: 43 61 63 68 65 2d 3e 70 44 69 72 74 79 3b 20 70  Cache->pDirty; p
22a0: 3b 20 70 3d 70 2d 3e 70 4e 65 78 74 29 7b 0a 20  ; p=p->pNext){. 
22b0: 20 20 20 70 63 61 63 68 65 41 64 64 54 6f 48 61     pcacheAddToHa
22c0: 73 68 28 70 29 3b 0a 20 20 7d 0a 20 20 72 65 74  sh(p);.  }.  ret
22d0: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
22e0: 0a 0a 2f 2a 0a 2a 2a 20 52 65 6d 6f 76 65 20 61  ../*.** Remove a
22f0: 20 70 61 67 65 20 66 72 6f 6d 20 61 20 6c 69 6e   page from a lin
2300: 6b 65 64 20 6c 69 73 74 20 74 68 61 74 20 69 73  ked list that is
2310: 20 68 65 61 64 65 64 20 62 79 20 2a 70 70 48 65   headed by *ppHe
2320: 61 64 2e 0a 2a 2a 20 2a 70 70 48 65 61 64 20 69  ad..** *ppHead i
2330: 73 20 65 69 74 68 65 72 20 50 43 61 63 68 65 2e  s either PCache.
2340: 70 43 6c 65 61 6e 20 6f 72 20 50 43 61 63 68 65  pClean or PCache
2350: 2e 70 44 69 72 74 79 2e 0a 2a 2f 0a 73 74 61 74  .pDirty..*/.stat
2360: 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 52 65  ic void pcacheRe
2370: 6d 6f 76 65 46 72 6f 6d 4c 69 73 74 28 50 67 48  moveFromList(PgH
2380: 64 72 20 2a 2a 70 70 48 65 61 64 2c 20 50 67 48  dr **ppHead, PgH
2390: 64 72 20 2a 70 50 61 67 65 29 7b 0a 20 20 69 6e  dr *pPage){.  in
23a0: 74 20 69 73 44 69 72 74 79 4c 69 73 74 20 3d 20  t isDirtyList = 
23b0: 28 70 70 48 65 61 64 3d 3d 26 70 50 61 67 65 2d  (ppHead==&pPage-
23c0: 3e 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 29  >pCache->pDirty)
23d0: 3b 0a 20 20 61 73 73 65 72 74 28 20 70 70 48 65  ;.  assert( ppHe
23e0: 61 64 3d 3d 26 70 50 61 67 65 2d 3e 70 43 61 63  ad==&pPage->pCac
23f0: 68 65 2d 3e 70 43 6c 65 61 6e 20 7c 7c 20 70 70  he->pClean || pp
2400: 48 65 61 64 3d 3d 26 70 50 61 67 65 2d 3e 70 43  Head==&pPage->pC
2410: 61 63 68 65 2d 3e 70 44 69 72 74 79 20 29 3b 0a  ache->pDirty );.
2420: 20 20 2f 2a 20 61 73 73 65 72 74 28 20 70 63 61    /* assert( pca
2430: 63 68 65 4d 75 74 65 78 48 65 6c 64 28 29 20 7c  cheMutexHeld() |
2440: 7c 20 70 70 48 65 61 64 21 3d 26 70 50 61 67 65  | ppHead!=&pPage
2450: 2d 3e 70 43 61 63 68 65 2d 3e 70 43 6c 65 61 6e  ->pCache->pClean
2460: 20 29 3b 20 2a 2a 2a 20 46 49 58 4d 45 20 2a 2f   ); *** FIXME */
2470: 0a 0a 20 20 69 66 28 20 70 50 61 67 65 2d 3e 70  ..  if( pPage->p
2480: 50 72 65 76 20 29 7b 0a 20 20 20 20 70 50 61 67  Prev ){.    pPag
2490: 65 2d 3e 70 50 72 65 76 2d 3e 70 4e 65 78 74 20  e->pPrev->pNext 
24a0: 3d 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 3b 0a  = pPage->pNext;.
24b0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 61 73 73    }else{.    ass
24c0: 65 72 74 28 20 2a 70 70 48 65 61 64 3d 3d 70 50  ert( *ppHead==pP
24d0: 61 67 65 20 29 3b 0a 20 20 20 20 2a 70 70 48 65  age );.    *ppHe
24e0: 61 64 20 3d 20 70 50 61 67 65 2d 3e 70 4e 65 78  ad = pPage->pNex
24f0: 74 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 50 61  t;.  }.  if( pPa
2500: 67 65 2d 3e 70 4e 65 78 74 20 29 7b 0a 20 20 20  ge->pNext ){.   
2510: 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 2d 3e 70   pPage->pNext->p
2520: 50 72 65 76 20 3d 20 70 50 61 67 65 2d 3e 70 50  Prev = pPage->pP
2530: 72 65 76 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20  rev;.  }..  if( 
2540: 69 73 44 69 72 74 79 4c 69 73 74 20 29 7b 0a 20  isDirtyList ){. 
2550: 20 20 20 50 43 61 63 68 65 20 2a 70 43 61 63 68     PCache *pCach
2560: 65 20 3d 20 70 50 61 67 65 2d 3e 70 43 61 63 68  e = pPage->pCach
2570: 65 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70  e;.    assert( p
2580: 50 61 67 65 2d 3e 70 4e 65 78 74 20 7c 7c 20 70  Page->pNext || p
2590: 43 61 63 68 65 2d 3e 70 44 69 72 74 79 54 61 69  Cache->pDirtyTai
25a0: 6c 3d 3d 70 50 61 67 65 20 29 3b 0a 20 20 20 20  l==pPage );.    
25b0: 69 66 28 20 21 70 50 61 67 65 2d 3e 70 4e 65 78  if( !pPage->pNex
25c0: 74 20 29 7b 0a 20 20 20 20 20 20 70 43 61 63 68  t ){.      pCach
25d0: 65 2d 3e 70 44 69 72 74 79 54 61 69 6c 20 3d 20  e->pDirtyTail = 
25e0: 70 50 61 67 65 2d 3e 70 50 72 65 76 3b 0a 20 20  pPage->pPrev;.  
25f0: 20 20 7d 0a 20 20 20 20 69 66 28 20 70 43 61 63    }.    if( pCac
2600: 68 65 2d 3e 70 53 79 6e 63 65 64 3d 3d 70 50 61  he->pSynced==pPa
2610: 67 65 20 29 7b 0a 20 20 20 20 20 20 50 67 48 64  ge ){.      PgHd
2620: 72 20 2a 70 53 79 6e 63 65 64 20 3d 20 70 50 61  r *pSynced = pPa
2630: 67 65 2d 3e 70 50 72 65 76 3b 0a 20 20 20 20 20  ge->pPrev;.     
2640: 20 77 68 69 6c 65 28 20 70 53 79 6e 63 65 64 20   while( pSynced 
2650: 26 26 20 28 70 53 79 6e 63 65 64 2d 3e 66 6c 61  && (pSynced->fla
2660: 67 73 26 50 47 48 44 52 5f 4e 45 45 44 5f 53 59  gs&PGHDR_NEED_SY
2670: 4e 43 29 20 29 7b 0a 20 20 20 20 20 20 20 20 70  NC) ){.        p
2680: 53 79 6e 63 65 64 20 3d 20 70 53 79 6e 63 65 64  Synced = pSynced
2690: 2d 3e 70 50 72 65 76 3b 0a 20 20 20 20 20 20 7d  ->pPrev;.      }
26a0: 0a 20 20 20 20 20 20 70 43 61 63 68 65 2d 3e 70  .      pCache->p
26b0: 53 79 6e 63 65 64 20 3d 20 70 53 79 6e 63 65 64  Synced = pSynced
26c0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f  ;.    }.  }.}../
26d0: 2a 0a 2a 2a 20 41 64 64 20 61 20 70 61 67 65 20  *.** Add a page 
26e0: 66 72 6f 6d 20 61 20 6c 69 6e 6b 65 64 20 6c 69  from a linked li
26f0: 73 74 20 74 68 61 74 20 69 73 20 68 65 61 64 65  st that is heade
2700: 64 20 62 79 20 2a 70 70 48 65 61 64 2e 0a 2a 2a  d by *ppHead..**
2710: 20 2a 70 70 48 65 61 64 20 69 73 20 65 69 74 68   *ppHead is eith
2720: 65 72 20 50 43 61 63 68 65 2e 70 43 6c 65 61 6e  er PCache.pClean
2730: 20 6f 72 20 50 43 61 63 68 65 2e 70 44 69 72 74   or PCache.pDirt
2740: 79 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  y..*/.static voi
2750: 64 20 70 63 61 63 68 65 41 64 64 54 6f 4c 69 73  d pcacheAddToLis
2760: 74 28 50 67 48 64 72 20 2a 2a 70 70 48 65 61 64  t(PgHdr **ppHead
2770: 2c 20 50 67 48 64 72 20 2a 70 50 61 67 65 29 7b  , PgHdr *pPage){
2780: 0a 20 20 69 6e 74 20 69 73 44 69 72 74 79 4c 69  .  int isDirtyLi
2790: 73 74 20 3d 20 28 70 70 48 65 61 64 3d 3d 26 70  st = (ppHead==&p
27a0: 50 61 67 65 2d 3e 70 43 61 63 68 65 2d 3e 70 44  Page->pCache->pD
27b0: 69 72 74 79 29 3b 0a 20 20 61 73 73 65 72 74 28  irty);.  assert(
27c0: 20 70 70 48 65 61 64 3d 3d 26 70 50 61 67 65 2d   ppHead==&pPage-
27d0: 3e 70 43 61 63 68 65 2d 3e 70 43 6c 65 61 6e 20  >pCache->pClean 
27e0: 7c 7c 20 70 70 48 65 61 64 3d 3d 26 70 50 61 67  || ppHead==&pPag
27f0: 65 2d 3e 70 43 61 63 68 65 2d 3e 70 44 69 72 74  e->pCache->pDirt
2800: 79 20 29 3b 0a 0a 20 20 69 66 28 20 28 2a 70 70  y );..  if( (*pp
2810: 48 65 61 64 29 20 29 7b 0a 20 20 20 20 28 2a 70  Head) ){.    (*p
2820: 70 48 65 61 64 29 2d 3e 70 50 72 65 76 20 3d 20  pHead)->pPrev = 
2830: 70 50 61 67 65 3b 0a 20 20 7d 0a 20 20 70 50 61  pPage;.  }.  pPa
2840: 67 65 2d 3e 70 4e 65 78 74 20 3d 20 2a 70 70 48  ge->pNext = *ppH
2850: 65 61 64 3b 0a 20 20 70 50 61 67 65 2d 3e 70 50  ead;.  pPage->pP
2860: 72 65 76 20 3d 20 30 3b 0a 20 20 2a 70 70 48 65  rev = 0;.  *ppHe
2870: 61 64 20 3d 20 70 50 61 67 65 3b 0a 0a 20 20 69  ad = pPage;..  i
2880: 66 28 20 69 73 44 69 72 74 79 4c 69 73 74 20 29  f( isDirtyList )
2890: 7b 0a 20 20 20 20 50 43 61 63 68 65 20 2a 70 43  {.    PCache *pC
28a0: 61 63 68 65 20 3d 20 70 50 61 67 65 2d 3e 70 43  ache = pPage->pC
28b0: 61 63 68 65 3b 0a 20 20 20 20 69 66 28 20 21 70  ache;.    if( !p
28c0: 43 61 63 68 65 2d 3e 70 44 69 72 74 79 54 61 69  Cache->pDirtyTai
28d0: 6c 20 29 7b 0a 20 20 20 20 20 20 61 73 73 65 72  l ){.      asser
28e0: 74 28 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 3d  t( pPage->pNext=
28f0: 3d 30 20 29 3b 0a 20 20 20 20 20 20 70 43 61 63  =0 );.      pCac
2900: 68 65 2d 3e 70 44 69 72 74 79 54 61 69 6c 20 3d  he->pDirtyTail =
2910: 20 70 50 61 67 65 3b 0a 20 20 20 20 7d 0a 20 20   pPage;.    }.  
2920: 20 20 69 66 28 20 21 70 43 61 63 68 65 2d 3e 70    if( !pCache->p
2930: 53 79 6e 63 65 64 20 26 26 20 30 3d 3d 28 70 50  Synced && 0==(pP
2940: 61 67 65 2d 3e 66 6c 61 67 73 26 50 47 48 44 52  age->flags&PGHDR
2950: 5f 4e 45 45 44 5f 53 59 4e 43 29 20 29 7b 0a 20  _NEED_SYNC) ){. 
2960: 20 20 20 20 20 70 43 61 63 68 65 2d 3e 70 53 79       pCache->pSy
2970: 6e 63 65 64 20 3d 20 70 50 61 67 65 3b 0a 20 20  nced = pPage;.  
2980: 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a    }.  }.}../*.**
2990: 20 52 65 6d 6f 76 65 20 61 20 70 61 67 65 20 66   Remove a page f
29a0: 72 6f 6d 20 74 68 65 20 67 6c 6f 62 61 6c 20 4c  rom the global L
29b0: 52 55 20 6c 69 73 74 0a 2a 2f 0a 73 74 61 74 69  RU list.*/.stati
29c0: 63 20 76 6f 69 64 20 70 63 61 63 68 65 52 65 6d  c void pcacheRem
29d0: 6f 76 65 46 72 6f 6d 4c 72 75 4c 69 73 74 28 50  oveFromLruList(P
29e0: 67 48 64 72 20 2a 70 50 61 67 65 29 7b 0a 20 20  gHdr *pPage){.  
29f0: 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f  assert( sqlite3_
2a00: 6d 75 74 65 78 5f 68 65 6c 64 28 70 63 61 63 68  mutex_held(pcach
2a10: 65 2e 6d 75 74 65 78 29 20 29 3b 0a 20 20 61 73  e.mutex) );.  as
2a20: 73 65 72 74 28 20 28 70 50 61 67 65 2d 3e 66 6c  sert( (pPage->fl
2a30: 61 67 73 26 50 47 48 44 52 5f 44 49 52 54 59 29  ags&PGHDR_DIRTY)
2a40: 3d 3d 30 20 29 3b 0a 20 20 69 66 28 20 70 50 61  ==0 );.  if( pPa
2a50: 67 65 2d 3e 70 43 61 63 68 65 2d 3e 62 50 75 72  ge->pCache->bPur
2a60: 67 65 61 62 6c 65 3d 3d 30 20 29 20 72 65 74 75  geable==0 ) retu
2a70: 72 6e 3b 0a 20 20 69 66 28 20 70 50 61 67 65 2d  rn;.  if( pPage-
2a80: 3e 70 4e 65 78 74 4c 72 75 20 29 7b 0a 20 20 20  >pNextLru ){.   
2a90: 20 61 73 73 65 72 74 28 20 70 63 61 63 68 65 2e   assert( pcache.
2aa0: 70 4c 72 75 54 61 69 6c 21 3d 70 50 61 67 65 20  pLruTail!=pPage 
2ab0: 29 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 4e  );.    pPage->pN
2ac0: 65 78 74 4c 72 75 2d 3e 70 50 72 65 76 4c 72 75  extLru->pPrevLru
2ad0: 20 3d 20 70 50 61 67 65 2d 3e 70 50 72 65 76 4c   = pPage->pPrevL
2ae0: 72 75 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ru;.  }else{.   
2af0: 20 61 73 73 65 72 74 28 20 70 63 61 63 68 65 2e   assert( pcache.
2b00: 70 4c 72 75 54 61 69 6c 3d 3d 70 50 61 67 65 20  pLruTail==pPage 
2b10: 29 3b 0a 20 20 20 20 70 63 61 63 68 65 2e 70 4c  );.    pcache.pL
2b20: 72 75 54 61 69 6c 20 3d 20 70 50 61 67 65 2d 3e  ruTail = pPage->
2b30: 70 50 72 65 76 4c 72 75 3b 0a 20 20 7d 0a 20 20  pPrevLru;.  }.  
2b40: 69 66 28 20 70 50 61 67 65 2d 3e 70 50 72 65 76  if( pPage->pPrev
2b50: 4c 72 75 20 29 7b 0a 20 20 20 20 61 73 73 65 72  Lru ){.    asser
2b60: 74 28 20 70 63 61 63 68 65 2e 70 4c 72 75 48 65  t( pcache.pLruHe
2b70: 61 64 21 3d 70 50 61 67 65 20 29 3b 0a 20 20 20  ad!=pPage );.   
2b80: 20 70 50 61 67 65 2d 3e 70 50 72 65 76 4c 72 75   pPage->pPrevLru
2b90: 2d 3e 70 4e 65 78 74 4c 72 75 20 3d 20 70 50 61  ->pNextLru = pPa
2ba0: 67 65 2d 3e 70 4e 65 78 74 4c 72 75 3b 0a 20 20  ge->pNextLru;.  
2bb0: 7d 65 6c 73 65 7b 0a 20 20 20 20 61 73 73 65 72  }else{.    asser
2bc0: 74 28 20 70 63 61 63 68 65 2e 70 4c 72 75 48 65  t( pcache.pLruHe
2bd0: 61 64 3d 3d 70 50 61 67 65 20 29 3b 0a 20 20 20  ad==pPage );.   
2be0: 20 70 63 61 63 68 65 2e 70 4c 72 75 48 65 61 64   pcache.pLruHead
2bf0: 20 3d 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 4c   = pPage->pNextL
2c00: 72 75 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a  ru;.  }.}../*.**
2c10: 20 41 64 64 20 61 20 70 61 67 65 20 74 6f 20 74   Add a page to t
2c20: 68 65 20 67 6c 6f 62 61 6c 20 4c 52 55 20 6c 69  he global LRU li
2c30: 73 74 2e 20 20 54 68 65 20 70 61 67 65 20 69 73  st.  The page is
2c40: 20 6e 6f 72 6d 61 6c 6c 79 20 61 64 64 65 64 0a   normally added.
2c50: 2a 2a 20 74 6f 20 74 68 65 20 66 72 6f 6e 74 20  ** to the front 
2c60: 6f 66 20 74 68 65 20 6c 69 73 74 20 73 6f 20 74  of the list so t
2c70: 68 61 74 20 69 74 20 77 69 6c 6c 20 62 65 20 74  hat it will be t
2c80: 68 65 20 6c 61 73 74 20 70 61 67 65 20 72 65 63  he last page rec
2c90: 79 63 6c 65 64 2e 0a 2a 2a 20 48 6f 77 65 76 65  ycled..** Howeve
2ca0: 72 2c 20 69 66 20 74 68 65 20 50 47 48 44 52 5f  r, if the PGHDR_
2cb0: 52 45 55 53 45 5f 55 4e 4c 49 4b 45 4c 59 20 62  REUSE_UNLIKELY b
2cc0: 69 74 20 69 73 20 73 65 74 2c 20 74 68 65 20 70  it is set, the p
2cd0: 61 67 65 20 69 73 20 61 64 64 65 64 0a 2a 2a 20  age is added.** 
2ce0: 74 6f 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68  to the end of th
2cf0: 65 20 4c 52 55 20 6c 69 73 74 20 73 6f 20 74 68  e LRU list so th
2d00: 61 74 20 69 74 20 77 69 6c 6c 20 62 65 20 74 68  at it will be th
2d10: 65 20 6e 65 78 74 20 74 6f 20 62 65 20 72 65 63  e next to be rec
2d20: 79 63 6c 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63  ycled..*/.static
2d30: 20 76 6f 69 64 20 70 63 61 63 68 65 41 64 64 54   void pcacheAddT
2d40: 6f 4c 72 75 4c 69 73 74 28 50 67 48 64 72 20 2a  oLruList(PgHdr *
2d50: 70 50 61 67 65 29 7b 0a 20 20 61 73 73 65 72 74  pPage){.  assert
2d60: 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f  ( sqlite3_mutex_
2d70: 68 65 6c 64 28 70 63 61 63 68 65 2e 6d 75 74 65  held(pcache.mute
2d80: 78 29 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  x) );.  assert( 
2d90: 28 70 50 61 67 65 2d 3e 66 6c 61 67 73 26 50 47  (pPage->flags&PG
2da0: 48 44 52 5f 44 49 52 54 59 29 3d 3d 30 20 29 3b  HDR_DIRTY)==0 );
2db0: 0a 20 20 69 66 28 20 70 50 61 67 65 2d 3e 70 43  .  if( pPage->pC
2dc0: 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65  ache->bPurgeable
2dd0: 3d 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a 20 20  ==0 ) return;.  
2de0: 69 66 28 20 70 63 61 63 68 65 2e 70 4c 72 75 54  if( pcache.pLruT
2df0: 61 69 6c 20 26 26 20 28 70 50 61 67 65 2d 3e 66  ail && (pPage->f
2e00: 6c 61 67 73 20 26 20 50 47 48 44 52 5f 52 45 55  lags & PGHDR_REU
2e10: 53 45 5f 55 4e 4c 49 4b 45 4c 59 29 21 3d 30 20  SE_UNLIKELY)!=0 
2e20: 29 7b 0a 20 20 20 20 2f 2a 20 49 66 20 72 65 75  ){.    /* If reu
2e30: 73 65 20 69 73 20 75 6e 6c 69 6b 65 6c 79 2e 20  se is unlikely. 
2e40: 20 50 75 74 20 74 68 65 20 70 61 67 65 20 61 74   Put the page at
2e50: 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68 65 20   the end of the 
2e60: 4c 52 55 20 6c 69 73 74 0a 20 20 20 20 2a 2a 20  LRU list.    ** 
2e70: 77 68 65 72 65 20 69 74 20 77 69 6c 6c 20 62 65  where it will be
2e80: 20 72 65 63 79 63 6c 65 64 20 73 6f 6f 6e 65 72   recycled sooner
2e90: 20 72 61 74 68 65 72 20 74 68 61 6e 20 6c 61 74   rather than lat
2ea0: 65 72 2e 20 0a 20 20 20 20 2a 2f 0a 20 20 20 20  er. .    */.    
2eb0: 61 73 73 65 72 74 28 20 70 63 61 63 68 65 2e 70  assert( pcache.p
2ec0: 4c 72 75 48 65 61 64 20 29 3b 0a 20 20 20 20 70  LruHead );.    p
2ed0: 50 61 67 65 2d 3e 70 4e 65 78 74 4c 72 75 20 3d  Page->pNextLru =
2ee0: 20 30 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 70   0;.    pPage->p
2ef0: 50 72 65 76 4c 72 75 20 3d 20 70 63 61 63 68 65  PrevLru = pcache
2f00: 2e 70 4c 72 75 54 61 69 6c 3b 0a 20 20 20 20 70  .pLruTail;.    p
2f10: 63 61 63 68 65 2e 70 4c 72 75 54 61 69 6c 2d 3e  cache.pLruTail->
2f20: 70 4e 65 78 74 4c 72 75 20 3d 20 70 50 61 67 65  pNextLru = pPage
2f30: 3b 0a 20 20 20 20 70 63 61 63 68 65 2e 70 4c 72  ;.    pcache.pLr
2f40: 75 54 61 69 6c 20 3d 20 70 50 61 67 65 3b 0a 20  uTail = pPage;. 
2f50: 20 20 20 70 50 61 67 65 2d 3e 66 6c 61 67 73 20     pPage->flags 
2f60: 26 3d 20 7e 50 47 48 44 52 5f 52 45 55 53 45 5f  &= ~PGHDR_REUSE_
2f70: 55 4e 4c 49 4b 45 4c 59 3b 0a 20 20 7d 65 6c 73  UNLIKELY;.  }els
2f80: 65 7b 0a 20 20 20 20 2f 2a 20 49 66 20 72 65 75  e{.    /* If reu
2f90: 73 65 20 69 73 20 70 6f 73 73 69 62 6c 65 2e 20  se is possible. 
2fa0: 74 68 65 20 70 61 67 65 20 67 6f 65 73 20 61 74  the page goes at
2fb0: 20 74 68 65 20 62 65 67 69 6e 6e 69 6e 67 20 6f   the beginning o
2fc0: 66 20 74 68 65 20 4c 52 55 0a 20 20 20 20 2a 2a  f the LRU.    **
2fd0: 20 6c 69 73 74 20 73 6f 20 74 68 61 74 20 69 74   list so that it
2fe0: 20 77 69 6c 6c 20 62 65 20 74 68 65 20 6c 61 73   will be the las
2ff0: 74 20 74 6f 20 62 65 20 72 65 63 79 63 6c 65 64  t to be recycled
3000: 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 69 66 28  ..    */.    if(
3010: 20 70 63 61 63 68 65 2e 70 4c 72 75 48 65 61 64   pcache.pLruHead
3020: 20 29 7b 0a 20 20 20 20 20 20 70 63 61 63 68 65   ){.      pcache
3030: 2e 70 4c 72 75 48 65 61 64 2d 3e 70 50 72 65 76  .pLruHead->pPrev
3040: 4c 72 75 20 3d 20 70 50 61 67 65 3b 0a 20 20 20  Lru = pPage;.   
3050: 20 7d 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 4e   }.    pPage->pN
3060: 65 78 74 4c 72 75 20 3d 20 70 63 61 63 68 65 2e  extLru = pcache.
3070: 70 4c 72 75 48 65 61 64 3b 0a 20 20 20 20 70 63  pLruHead;.    pc
3080: 61 63 68 65 2e 70 4c 72 75 48 65 61 64 20 3d 20  ache.pLruHead = 
3090: 70 50 61 67 65 3b 0a 20 20 20 20 70 50 61 67 65  pPage;.    pPage
30a0: 2d 3e 70 50 72 65 76 4c 72 75 20 3d 20 30 3b 0a  ->pPrevLru = 0;.
30b0: 20 20 20 20 69 66 28 20 70 63 61 63 68 65 2e 70      if( pcache.p
30c0: 4c 72 75 54 61 69 6c 3d 3d 30 20 29 7b 0a 20 20  LruTail==0 ){.  
30d0: 20 20 20 20 70 63 61 63 68 65 2e 70 4c 72 75 54      pcache.pLruT
30e0: 61 69 6c 20 3d 20 70 50 61 67 65 3b 0a 20 20 20  ail = pPage;.   
30f0: 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a   }.  }.}../*****
3100: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3110: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3120: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 4d 65 6d 6f 72  ********** Memor
3130: 79 20 41 6c 6c 6f 63 61 74 69 6f 6e 20 2a 2a 2a  y Allocation ***
3140: 2a 2a 2a 2a 2a 2a 2a 2a 0a 2a 2a 0a 2a 2a 20 49  ********.**.** I
3150: 6e 69 74 69 61 6c 69 7a 65 20 74 68 65 20 70 61  nitialize the pa
3160: 67 65 20 63 61 63 68 65 20 6d 65 6d 6f 72 79 20  ge cache memory 
3170: 70 6f 6f 6c 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73  pool..**.** This
3180: 20 6d 75 73 74 20 62 65 20 63 61 6c 6c 65 64 20   must be called 
3190: 61 74 20 73 74 61 72 74 2d 74 69 6d 65 20 77 68  at start-time wh
31a0: 65 6e 20 6e 6f 20 70 61 67 65 20 63 61 63 68 65  en no page cache
31b0: 20 6c 69 6e 65 73 20 61 72 65 0a 2a 2a 20 63 68   lines are.** ch
31c0: 65 63 6b 65 64 20 6f 75 74 2e 20 54 68 69 73 20  ecked out. This 
31d0: 66 75 6e 63 74 69 6f 6e 20 69 73 20 6e 6f 74 20  function is not 
31e0: 74 68 72 65 61 64 73 61 66 65 2e 0a 2a 2f 0a 76  threadsafe..*/.v
31f0: 6f 69 64 20 73 71 6c 69 74 65 33 50 43 61 63 68  oid sqlite3PCach
3200: 65 42 75 66 66 65 72 53 65 74 75 70 28 76 6f 69  eBufferSetup(voi
3210: 64 20 2a 70 42 75 66 2c 20 69 6e 74 20 73 7a 2c  d *pBuf, int sz,
3220: 20 69 6e 74 20 6e 29 7b 0a 20 20 50 67 46 72 65   int n){.  PgFre
3230: 65 73 6c 6f 74 20 2a 70 3b 0a 20 20 73 7a 20 26  eslot *p;.  sz &
3240: 3d 20 7e 37 3b 0a 20 20 70 63 61 63 68 65 2e 73  = ~7;.  pcache.s
3250: 7a 53 6c 6f 74 20 3d 20 73 7a 3b 0a 20 20 70 63  zSlot = sz;.  pc
3260: 61 63 68 65 2e 70 53 74 61 72 74 20 3d 20 70 42  ache.pStart = pB
3270: 75 66 3b 0a 20 20 70 63 61 63 68 65 2e 70 46 72  uf;.  pcache.pFr
3280: 65 65 20 3d 20 30 3b 0a 20 20 77 68 69 6c 65 28  ee = 0;.  while(
3290: 20 6e 2d 2d 20 29 7b 0a 20 20 20 20 70 20 3d 20   n-- ){.    p = 
32a0: 28 50 67 46 72 65 65 73 6c 6f 74 2a 29 70 42 75  (PgFreeslot*)pBu
32b0: 66 3b 0a 20 20 20 20 70 2d 3e 70 4e 65 78 74 20  f;.    p->pNext 
32c0: 3d 20 70 63 61 63 68 65 2e 70 46 72 65 65 3b 0a  = pcache.pFree;.
32d0: 20 20 20 20 70 63 61 63 68 65 2e 70 46 72 65 65      pcache.pFree
32e0: 20 3d 20 70 3b 0a 20 20 20 20 70 42 75 66 20 3d   = p;.    pBuf =
32f0: 20 28 76 6f 69 64 2a 29 26 28 28 63 68 61 72 2a   (void*)&((char*
3300: 29 70 42 75 66 29 5b 73 7a 5d 3b 0a 20 20 7d 0a  )pBuf)[sz];.  }.
3310: 20 20 70 63 61 63 68 65 2e 70 45 6e 64 20 3d 20    pcache.pEnd = 
3320: 70 42 75 66 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41  pBuf;.}../*.** A
3330: 6c 6c 6f 63 61 74 65 20 61 20 70 61 67 65 20 63  llocate a page c
3340: 61 63 68 65 20 6c 69 6e 65 2e 20 20 4c 6f 6f 6b  ache line.  Look
3350: 20 69 6e 20 74 68 65 20 70 61 67 65 20 63 61 63   in the page cac
3360: 68 65 20 6d 65 6d 6f 72 79 20 70 6f 6f 6c 20 66  he memory pool f
3370: 69 72 73 74 0a 2a 2a 20 61 6e 64 20 75 73 65 20  irst.** and use 
3380: 61 6e 20 65 6c 65 6d 65 6e 74 20 66 72 6f 6d 20  an element from 
3390: 69 74 20 66 69 72 73 74 20 69 66 20 61 76 61 69  it first if avai
33a0: 6c 61 62 6c 65 2e 20 20 49 66 20 6e 6f 74 68 69  lable.  If nothi
33b0: 6e 67 20 69 73 20 61 76 61 69 6c 61 62 6c 65 0a  ng is available.
33c0: 2a 2a 20 69 6e 20 74 68 65 20 70 61 67 65 20 63  ** in the page c
33d0: 61 63 68 65 20 6d 65 6d 6f 72 79 20 70 6f 6f 6c  ache memory pool
33e0: 2c 20 67 6f 20 74 6f 20 74 68 65 20 67 65 6e 65  , go to the gene
33f0: 72 61 6c 20 70 75 72 70 6f 73 65 20 6d 65 6d 6f  ral purpose memo
3400: 72 79 20 61 6c 6c 6f 63 61 74 6f 72 2e 0a 2a 2f  ry allocator..*/
3410: 0a 76 6f 69 64 20 2a 70 63 61 63 68 65 4d 61 6c  .void *pcacheMal
3420: 6c 6f 63 28 69 6e 74 20 73 7a 2c 20 50 43 61 63  loc(int sz, PCac
3430: 68 65 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 61  he *pCache){.  a
3440: 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d  ssert( sqlite3_m
3450: 75 74 65 78 5f 68 65 6c 64 28 70 63 61 63 68 65  utex_held(pcache
3460: 2e 6d 75 74 65 78 29 20 29 3b 0a 20 20 69 66 28  .mutex) );.  if(
3470: 20 73 7a 3c 3d 70 63 61 63 68 65 2e 73 7a 53 6c   sz<=pcache.szSl
3480: 6f 74 20 26 26 20 70 63 61 63 68 65 2e 70 46 72  ot && pcache.pFr
3490: 65 65 20 29 7b 0a 20 20 20 20 50 67 46 72 65 65  ee ){.    PgFree
34a0: 73 6c 6f 74 20 2a 70 20 3d 20 70 63 61 63 68 65  slot *p = pcache
34b0: 2e 70 46 72 65 65 3b 0a 20 20 20 20 70 63 61 63  .pFree;.    pcac
34c0: 68 65 2e 70 46 72 65 65 20 3d 20 70 2d 3e 70 4e  he.pFree = p->pN
34d0: 65 78 74 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  ext;.    sqlite3
34e0: 53 74 61 74 75 73 53 65 74 28 53 51 4c 49 54 45  StatusSet(SQLITE
34f0: 5f 53 54 41 54 55 53 5f 50 41 47 45 43 41 43 48  _STATUS_PAGECACH
3500: 45 5f 53 49 5a 45 2c 20 73 7a 29 3b 0a 20 20 20  E_SIZE, sz);.   
3510: 20 73 71 6c 69 74 65 33 53 74 61 74 75 73 41 64   sqlite3StatusAd
3520: 64 28 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f  d(SQLITE_STATUS_
3530: 50 41 47 45 43 41 43 48 45 5f 55 53 45 44 2c 20  PAGECACHE_USED, 
3540: 31 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 28  1);.    return (
3550: 76 6f 69 64 2a 29 70 3b 0a 20 20 7d 65 6c 73 65  void*)p;.  }else
3560: 7b 0a 20 20 20 20 76 6f 69 64 20 2a 70 3b 0a 0a  {.    void *p;..
3570: 20 20 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20      /* Allocate 
3580: 61 20 6e 65 77 20 62 75 66 66 65 72 20 75 73 69  a new buffer usi
3590: 6e 67 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63  ng sqlite3Malloc
35a0: 2e 20 42 65 66 6f 72 65 20 64 6f 69 6e 67 20 73  . Before doing s
35b0: 6f 2c 20 65 78 69 74 20 74 68 65 0a 20 20 20 20  o, exit the.    
35c0: 2a 2a 20 67 6c 6f 62 61 6c 20 70 63 61 63 68 65  ** global pcache
35d0: 20 6d 75 74 65 78 20 61 6e 64 20 75 6e 6c 6f 63   mutex and unloc
35e0: 6b 20 74 68 65 20 70 61 67 65 72 2d 63 61 63 68  k the pager-cach
35f0: 65 20 6f 62 6a 65 63 74 20 70 43 61 63 68 65 2e  e object pCache.
3600: 20 54 68 69 73 20 69 73 20 0a 20 20 20 20 2a 2a   This is .    **
3610: 20 73 6f 20 74 68 61 74 20 69 66 20 74 68 65 20   so that if the 
3620: 61 74 74 65 6d 70 74 20 74 6f 20 61 6c 6c 6f 63  attempt to alloc
3630: 61 74 65 20 61 20 6e 65 77 20 62 75 66 66 65 72  ate a new buffer
3640: 20 63 61 75 73 65 73 20 74 68 65 20 74 68 65 20   causes the the 
3650: 0a 20 20 20 20 2a 2a 20 63 6f 6e 66 69 67 75 72  .    ** configur
3660: 65 64 20 73 6f 66 74 2d 68 65 61 70 2d 6c 69 6d  ed soft-heap-lim
3670: 69 74 20 74 6f 20 62 65 20 62 72 65 61 63 68 65  it to be breache
3680: 64 2c 20 69 74 20 77 69 6c 6c 20 62 65 20 70 6f  d, it will be po
3690: 73 73 69 62 6c 65 20 74 6f 0a 20 20 20 20 2a 2a  ssible to.    **
36a0: 20 72 65 63 6c 61 69 6d 20 6d 65 6d 6f 72 79 20   reclaim memory 
36b0: 66 72 6f 6d 20 74 68 69 73 20 70 61 67 65 72 2d  from this pager-
36c0: 63 61 63 68 65 2e 0a 20 20 20 20 2a 2f 0a 20 20  cache..    */.  
36d0: 20 20 70 63 61 63 68 65 45 78 69 74 4d 75 74 65    pcacheExitMute
36e0: 78 28 29 3b 0a 20 20 20 20 70 20 3d 20 73 71 6c  x();.    p = sql
36f0: 69 74 65 33 4d 61 6c 6c 6f 63 28 73 7a 29 3b 0a  ite3Malloc(sz);.
3700: 20 20 20 20 70 63 61 63 68 65 45 6e 74 65 72 4d      pcacheEnterM
3710: 75 74 65 78 28 29 3b 0a 0a 20 20 20 20 69 66 28  utex();..    if(
3720: 20 70 20 29 7b 0a 20 20 20 20 20 20 73 7a 20 3d   p ){.      sz =
3730: 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 53 69   sqlite3MallocSi
3740: 7a 65 28 70 29 3b 0a 20 20 20 20 20 20 73 71 6c  ze(p);.      sql
3750: 69 74 65 33 53 74 61 74 75 73 41 64 64 28 53 51  ite3StatusAdd(SQ
3760: 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41 47 45  LITE_STATUS_PAGE
3770: 43 41 43 48 45 5f 4f 56 45 52 46 4c 4f 57 2c 20  CACHE_OVERFLOW, 
3780: 73 7a 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72  sz);.    }.    r
3790: 65 74 75 72 6e 20 70 3b 0a 20 20 7d 0a 7d 0a 76  eturn p;.  }.}.v
37a0: 6f 69 64 20 2a 73 71 6c 69 74 65 33 50 61 67 65  oid *sqlite3Page
37b0: 4d 61 6c 6c 6f 63 28 73 7a 29 7b 0a 20 20 76 6f  Malloc(sz){.  vo
37c0: 69 64 20 2a 70 3b 0a 20 20 70 63 61 63 68 65 45  id *p;.  pcacheE
37d0: 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a 20 20 70  nterMutex();.  p
37e0: 20 3d 20 70 63 61 63 68 65 4d 61 6c 6c 6f 63 28   = pcacheMalloc(
37f0: 73 7a 2c 20 30 29 3b 0a 20 20 70 63 61 63 68 65  sz, 0);.  pcache
3800: 45 78 69 74 4d 75 74 65 78 28 29 3b 0a 20 20 72  ExitMutex();.  r
3810: 65 74 75 72 6e 20 70 3b 0a 7d 0a 0a 2f 2a 0a 2a  eturn p;.}../*.*
3820: 2a 20 52 65 6c 65 61 73 65 20 61 20 70 61 67 65  * Release a page
3830: 72 20 6d 65 6d 6f 72 79 20 61 6c 6c 6f 63 61 74  r memory allocat
3840: 69 6f 6e 0a 2a 2f 0a 76 6f 69 64 20 70 63 61 63  ion.*/.void pcac
3850: 68 65 46 72 65 65 28 76 6f 69 64 20 2a 70 29 7b  heFree(void *p){
3860: 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74  .  assert( sqlit
3870: 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 63  e3_mutex_held(pc
3880: 61 63 68 65 2e 6d 75 74 65 78 29 20 29 3b 0a 20  ache.mutex) );. 
3890: 20 69 66 28 20 70 3d 3d 30 20 29 20 72 65 74 75   if( p==0 ) retu
38a0: 72 6e 3b 0a 20 20 69 66 28 20 70 3e 3d 70 63 61  rn;.  if( p>=pca
38b0: 63 68 65 2e 70 53 74 61 72 74 20 26 26 20 70 3c  che.pStart && p<
38c0: 70 63 61 63 68 65 2e 70 45 6e 64 20 29 7b 0a 20  pcache.pEnd ){. 
38d0: 20 20 20 50 67 46 72 65 65 73 6c 6f 74 20 2a 70     PgFreeslot *p
38e0: 53 6c 6f 74 3b 0a 20 20 20 20 73 71 6c 69 74 65  Slot;.    sqlite
38f0: 33 53 74 61 74 75 73 41 64 64 28 53 51 4c 49 54  3StatusAdd(SQLIT
3900: 45 5f 53 54 41 54 55 53 5f 50 41 47 45 43 41 43  E_STATUS_PAGECAC
3910: 48 45 5f 55 53 45 44 2c 20 2d 31 29 3b 0a 20 20  HE_USED, -1);.  
3920: 20 20 70 53 6c 6f 74 20 3d 20 28 50 67 46 72 65    pSlot = (PgFre
3930: 65 73 6c 6f 74 2a 29 70 3b 0a 20 20 20 20 70 53  eslot*)p;.    pS
3940: 6c 6f 74 2d 3e 70 4e 65 78 74 20 3d 20 70 63 61  lot->pNext = pca
3950: 63 68 65 2e 70 46 72 65 65 3b 0a 20 20 20 20 70  che.pFree;.    p
3960: 63 61 63 68 65 2e 70 46 72 65 65 20 3d 20 70 53  cache.pFree = pS
3970: 6c 6f 74 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  lot;.  }else{.  
3980: 20 20 69 6e 74 20 69 53 69 7a 65 20 3d 20 73 71    int iSize = sq
3990: 6c 69 74 65 33 4d 61 6c 6c 6f 63 53 69 7a 65 28  lite3MallocSize(
39a0: 70 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 53  p);.    sqlite3S
39b0: 74 61 74 75 73 41 64 64 28 53 51 4c 49 54 45 5f  tatusAdd(SQLITE_
39c0: 53 54 41 54 55 53 5f 50 41 47 45 43 41 43 48 45  STATUS_PAGECACHE
39d0: 5f 4f 56 45 52 46 4c 4f 57 2c 20 2d 69 53 69 7a  _OVERFLOW, -iSiz
39e0: 65 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  e);.    sqlite3_
39f0: 66 72 65 65 28 70 29 3b 0a 20 20 7d 0a 7d 0a 76  free(p);.  }.}.v
3a00: 6f 69 64 20 73 71 6c 69 74 65 33 50 61 67 65 46  oid sqlite3PageF
3a10: 72 65 65 28 76 6f 69 64 20 2a 70 29 7b 0a 20 20  ree(void *p){.  
3a20: 70 63 61 63 68 65 45 6e 74 65 72 4d 75 74 65 78  pcacheEnterMutex
3a30: 28 29 3b 0a 20 20 70 63 61 63 68 65 46 72 65 65  ();.  pcacheFree
3a40: 28 70 29 3b 0a 20 20 70 63 61 63 68 65 45 78 69  (p);.  pcacheExi
3a50: 74 4d 75 74 65 78 28 29 3b 0a 7d 0a 0a 2f 2a 0a  tMutex();.}../*.
3a60: 2a 2a 20 41 6c 6c 6f 63 61 74 65 20 61 20 6e 65  ** Allocate a ne
3a70: 77 20 70 61 67 65 2e 0a 2a 2f 0a 73 74 61 74 69  w page..*/.stati
3a80: 63 20 50 67 48 64 72 20 2a 70 63 61 63 68 65 50  c PgHdr *pcacheP
3a90: 61 67 65 41 6c 6c 6f 63 28 50 43 61 63 68 65 20  ageAlloc(PCache 
3aa0: 2a 70 43 61 63 68 65 29 7b 0a 20 20 50 67 48 64  *pCache){.  PgHd
3ab0: 72 20 2a 70 3b 0a 20 20 69 6e 74 20 73 7a 20 3d  r *p;.  int sz =
3ac0: 20 73 69 7a 65 6f 66 28 2a 70 29 20 2b 20 70 43   sizeof(*p) + pC
3ad0: 61 63 68 65 2d 3e 73 7a 50 61 67 65 20 2b 20 70  ache->szPage + p
3ae0: 43 61 63 68 65 2d 3e 73 7a 45 78 74 72 61 3b 0a  Cache->szExtra;.
3af0: 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65    assert( sqlite
3b00: 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 63 61  3_mutex_held(pca
3b10: 63 68 65 2e 6d 75 74 65 78 29 20 29 3b 0a 20 20  che.mutex) );.  
3b20: 70 20 3d 20 70 63 61 63 68 65 4d 61 6c 6c 6f 63  p = pcacheMalloc
3b30: 28 73 7a 2c 20 70 43 61 63 68 65 29 3b 0a 20 20  (sz, pCache);.  
3b40: 69 66 28 20 70 3d 3d 30 20 29 20 72 65 74 75 72  if( p==0 ) retur
3b50: 6e 20 30 3b 0a 20 20 6d 65 6d 73 65 74 28 70 2c  n 0;.  memset(p,
3b60: 20 30 2c 20 73 69 7a 65 6f 66 28 50 67 48 64 72   0, sizeof(PgHdr
3b70: 29 29 3b 0a 20 20 70 2d 3e 70 44 61 74 61 20 3d  ));.  p->pData =
3b80: 20 28 76 6f 69 64 2a 29 26 70 5b 31 5d 3b 0a 20   (void*)&p[1];. 
3b90: 20 70 2d 3e 70 45 78 74 72 61 20 3d 20 28 76 6f   p->pExtra = (vo
3ba0: 69 64 2a 29 26 28 28 63 68 61 72 2a 29 70 2d 3e  id*)&((char*)p->
3bb0: 70 44 61 74 61 29 5b 70 43 61 63 68 65 2d 3e 73  pData)[pCache->s
3bc0: 7a 50 61 67 65 5d 3b 0a 20 20 69 66 28 20 70 43  zPage];.  if( pC
3bd0: 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65  ache->bPurgeable
3be0: 20 29 7b 0a 20 20 20 20 70 63 61 63 68 65 2e 6e   ){.    pcache.n
3bf0: 43 75 72 72 65 6e 74 50 61 67 65 2b 2b 3b 0a 20  CurrentPage++;. 
3c00: 20 7d 0a 20 20 72 65 74 75 72 6e 20 70 3b 0a 7d   }.  return p;.}
3c10: 0a 0a 2f 2a 0a 2a 2a 20 44 65 61 6c 6c 6f 63 61  ../*.** Dealloca
3c20: 74 65 20 61 20 70 61 67 65 0a 2a 2f 0a 73 74 61  te a page.*/.sta
3c30: 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 50  tic void pcacheP
3c40: 61 67 65 46 72 65 65 28 50 67 48 64 72 20 2a 70  ageFree(PgHdr *p
3c50: 29 7b 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c  ){.  assert( sql
3c60: 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28  ite3_mutex_held(
3c70: 70 63 61 63 68 65 2e 6d 75 74 65 78 29 20 29 3b  pcache.mutex) );
3c80: 0a 20 20 69 66 28 20 70 2d 3e 70 43 61 63 68 65  .  if( p->pCache
3c90: 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 29 7b 0a  ->bPurgeable ){.
3ca0: 20 20 20 20 70 63 61 63 68 65 2e 6e 43 75 72 72      pcache.nCurr
3cb0: 65 6e 74 50 61 67 65 2d 2d 3b 0a 20 20 7d 0a 20  entPage--;.  }. 
3cc0: 20 70 63 61 63 68 65 46 72 65 65 28 70 2d 3e 61   pcacheFree(p->a
3cd0: 70 53 61 76 65 5b 30 5d 29 3b 0a 20 20 70 63 61  pSave[0]);.  pca
3ce0: 63 68 65 46 72 65 65 28 70 2d 3e 61 70 53 61 76  cheFree(p->apSav
3cf0: 65 5b 31 5d 29 3b 0a 20 20 70 63 61 63 68 65 46  e[1]);.  pcacheF
3d00: 72 65 65 28 70 29 3b 0a 7d 0a 0a 23 69 66 64 65  ree(p);.}..#ifde
3d10: 66 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f  f SQLITE_ENABLE_
3d20: 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e  MEMORY_MANAGEMEN
3d30: 54 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74  T./*.** Return t
3d40: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 62 79 74  he number of byt
3d50: 65 73 20 74 68 61 74 20 77 69 6c 6c 20 62 65 20  es that will be 
3d60: 72 65 74 75 72 6e 65 64 20 74 6f 20 74 68 65 20  returned to the 
3d70: 68 65 61 70 20 77 68 65 6e 0a 2a 2a 20 74 68 65  heap when.** the
3d80: 20 61 72 67 75 6d 65 6e 74 20 69 73 20 70 61 73   argument is pas
3d90: 73 65 64 20 74 6f 20 70 63 61 63 68 65 50 61 67  sed to pcachePag
3da0: 65 46 72 65 65 28 29 2e 0a 2a 2f 0a 73 74 61 74  eFree()..*/.stat
3db0: 69 63 20 69 6e 74 20 70 63 61 63 68 65 50 61 67  ic int pcachePag
3dc0: 65 53 69 7a 65 28 50 67 48 64 72 20 2a 70 29 7b  eSize(PgHdr *p){
3dd0: 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74  .  assert( sqlit
3de0: 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 63  e3_mutex_held(pc
3df0: 61 63 68 65 2e 6d 75 74 65 78 29 20 29 3b 0a 20  ache.mutex) );. 
3e00: 20 61 73 73 65 72 74 28 20 21 70 63 61 63 68 65   assert( !pcache
3e10: 2e 70 53 74 61 72 74 20 29 3b 0a 20 20 61 73 73  .pStart );.  ass
3e20: 65 72 74 28 20 70 2d 3e 61 70 53 61 76 65 5b 30  ert( p->apSave[0
3e30: 5d 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74  ]==0 );.  assert
3e40: 28 20 70 2d 3e 61 70 53 61 76 65 5b 31 5d 3d 3d  ( p->apSave[1]==
3e50: 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70  0 );.  assert( p
3e60: 20 26 26 20 70 2d 3e 70 43 61 63 68 65 20 29 3b   && p->pCache );
3e70: 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65  .  return sqlite
3e80: 33 4d 61 6c 6c 6f 63 53 69 7a 65 28 70 29 3b 0a  3MallocSize(p);.
3e90: 7d 0a 23 65 6e 64 69 66 0a 0a 2f 2a 0a 2a 2a 20  }.#endif../*.** 
3ea0: 41 74 74 65 6d 70 74 20 74 6f 20 27 72 65 63 79  Attempt to 'recy
3eb0: 63 6c 65 27 20 61 20 70 61 67 65 20 66 72 6f 6d  cle' a page from
3ec0: 20 74 68 65 20 67 6c 6f 62 61 6c 20 4c 52 55 20   the global LRU 
3ed0: 6c 69 73 74 2e 20 4f 6e 6c 79 20 63 6c 65 61 6e  list. Only clean
3ee0: 2c 0a 2a 2a 20 75 6e 72 65 66 65 72 65 6e 63 65  ,.** unreference
3ef0: 64 20 70 61 67 65 73 20 66 72 6f 6d 20 70 75 72  d pages from pur
3f00: 67 65 61 62 6c 65 20 63 61 63 68 65 73 20 61 72  geable caches ar
3f10: 65 20 65 6c 69 67 69 62 6c 65 20 66 6f 72 20 72  e eligible for r
3f20: 65 63 79 63 6c 69 6e 67 2e 0a 2a 2a 0a 2a 2a 20  ecycling..**.** 
3f30: 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 72 65  This function re
3f40: 6d 6f 76 65 73 20 70 61 67 65 20 70 63 61 63 68  moves page pcach
3f50: 65 2e 70 4c 72 75 54 61 69 6c 20 66 72 6f 6d 20  e.pLruTail from 
3f60: 74 68 65 20 67 6c 6f 62 61 6c 20 4c 52 55 20 6c  the global LRU l
3f70: 69 73 74 2c 0a 2a 2a 20 61 6e 64 20 66 72 6f 6d  ist,.** and from
3f80: 20 74 68 65 20 68 61 73 68 2d 74 61 62 6c 65 20   the hash-table 
3f90: 61 6e 64 20 50 43 61 63 68 65 2e 70 43 6c 65 61  and PCache.pClea
3fa0: 6e 20 6c 69 73 74 20 6f 66 20 74 68 65 20 6f 77  n list of the ow
3fb0: 6e 65 72 20 70 63 61 63 68 65 2e 0a 2a 2a 20 54  ner pcache..** T
3fc0: 68 65 72 65 20 73 68 6f 75 6c 64 20 62 65 20 6e  here should be n
3fd0: 6f 20 6f 74 68 65 72 20 72 65 66 65 72 65 6e 63  o other referenc
3fe0: 65 73 20 74 6f 20 74 68 65 20 70 61 67 65 2e 0a  es to the page..
3ff0: 2a 2a 0a 2a 2a 20 41 20 70 6f 69 6e 74 65 72 20  **.** A pointer 
4000: 74 6f 20 74 68 65 20 72 65 63 79 63 6c 65 64 20  to the recycled 
4010: 70 61 67 65 20 69 73 20 72 65 74 75 72 6e 65 64  page is returned
4020: 2c 20 6f 72 20 4e 55 4c 4c 20 69 66 20 6e 6f 20  , or NULL if no 
4030: 70 61 67 65 20 69 73 0a 2a 2a 20 65 6c 69 67 69  page is.** eligi
4040: 62 6c 65 20 66 6f 72 20 72 65 63 79 63 6c 69 6e  ble for recyclin
4050: 67 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 50 67 48  g..*/.static PgH
4060: 64 72 20 2a 70 63 61 63 68 65 52 65 63 79 63 6c  dr *pcacheRecycl
4070: 65 50 61 67 65 28 29 7b 0a 20 20 50 67 48 64 72  ePage(){.  PgHdr
4080: 20 2a 70 20 3d 20 30 3b 0a 20 20 61 73 73 65 72   *p = 0;.  asser
4090: 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78  t( sqlite3_mutex
40a0: 5f 68 65 6c 64 28 70 63 61 63 68 65 2e 6d 75 74  _held(pcache.mut
40b0: 65 78 29 20 29 3b 0a 0a 20 20 69 66 28 20 28 70  ex) );..  if( (p
40c0: 3d 70 63 61 63 68 65 2e 70 4c 72 75 54 61 69 6c  =pcache.pLruTail
40d0: 29 20 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28  ) ){.    assert(
40e0: 20 28 70 2d 3e 66 6c 61 67 73 26 50 47 48 44 52   (p->flags&PGHDR
40f0: 5f 44 49 52 54 59 29 3d 3d 30 20 29 3b 0a 20 20  _DIRTY)==0 );.  
4100: 20 20 70 63 61 63 68 65 52 65 6d 6f 76 65 46 72    pcacheRemoveFr
4110: 6f 6d 4c 72 75 4c 69 73 74 28 70 29 3b 0a 20 20  omLruList(p);.  
4120: 20 20 70 63 61 63 68 65 52 65 6d 6f 76 65 46 72    pcacheRemoveFr
4130: 6f 6d 48 61 73 68 28 70 29 3b 0a 20 20 20 20 70  omHash(p);.    p
4140: 63 61 63 68 65 52 65 6d 6f 76 65 46 72 6f 6d 4c  cacheRemoveFromL
4150: 69 73 74 28 26 70 2d 3e 70 43 61 63 68 65 2d 3e  ist(&p->pCache->
4160: 70 43 6c 65 61 6e 2c 20 70 29 3b 0a 20 20 7d 0a  pClean, p);.  }.
4170: 0a 20 20 72 65 74 75 72 6e 20 70 3b 0a 7d 0a 0a  .  return p;.}..
4180: 2f 2a 0a 2a 2a 20 4f 62 74 61 69 6e 20 73 70 61  /*.** Obtain spa
4190: 63 65 20 66 6f 72 20 61 20 70 61 67 65 2e 20 54  ce for a page. T
41a0: 72 79 20 74 6f 20 72 65 63 79 63 6c 65 20 61 6e  ry to recycle an
41b0: 20 6f 6c 64 20 70 61 67 65 20 69 66 20 74 68 65   old page if the
41c0: 20 6c 69 6d 69 74 20 6f 6e 20 74 68 65 20 0a 2a   limit on the .*
41d0: 2a 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65  * number of page
41e0: 73 20 68 61 73 20 62 65 65 6e 20 72 65 61 63 68  s has been reach
41f0: 65 64 2e 20 49 66 20 74 68 65 20 6c 69 6d 69 74  ed. If the limit
4200: 20 68 61 73 20 6e 6f 74 20 62 65 65 6e 20 72 65   has not been re
4210: 61 63 68 65 64 20 6f 72 0a 2a 2a 20 74 68 65 72  ached or.** ther
4220: 65 20 61 72 65 20 6e 6f 20 70 61 67 65 73 20 65  e are no pages e
4230: 6c 69 67 69 62 6c 65 20 66 6f 72 20 72 65 63 79  ligible for recy
4240: 63 6c 69 6e 67 2c 20 61 6c 6c 6f 63 61 74 65 20  cling, allocate 
4250: 61 20 6e 65 77 20 70 61 67 65 2e 0a 2a 2a 0a 2a  a new page..**.*
4260: 2a 20 52 65 74 75 72 6e 20 61 20 70 6f 69 6e 74  * Return a point
4270: 65 72 20 74 6f 20 74 68 65 20 6e 65 77 20 70 61  er to the new pa
4280: 67 65 2c 20 6f 72 20 4e 55 4c 4c 20 69 66 20 61  ge, or NULL if a
4290: 6e 20 4f 4f 4d 20 63 6f 6e 64 69 74 69 6f 6e 20  n OOM condition 
42a0: 6f 63 63 75 72 73 2e 0a 2a 2f 0a 73 74 61 74 69  occurs..*/.stati
42b0: 63 20 69 6e 74 20 70 63 61 63 68 65 52 65 63 79  c int pcacheRecy
42c0: 63 6c 65 4f 72 41 6c 6c 6f 63 28 50 43 61 63 68  cleOrAlloc(PCach
42d0: 65 20 2a 70 43 61 63 68 65 2c 20 50 67 48 64 72  e *pCache, PgHdr
42e0: 20 2a 2a 70 70 50 61 67 65 29 7b 0a 20 20 50 67   **ppPage){.  Pg
42f0: 48 64 72 20 2a 70 20 3d 20 30 3b 0a 0a 20 20 69  Hdr *p = 0;..  i
4300: 6e 74 20 73 7a 50 61 67 65 20 3d 20 70 43 61 63  nt szPage = pCac
4310: 68 65 2d 3e 73 7a 50 61 67 65 3b 0a 20 20 69 6e  he->szPage;.  in
4320: 74 20 73 7a 45 78 74 72 61 20 3d 20 70 43 61 63  t szExtra = pCac
4330: 68 65 2d 3e 73 7a 45 78 74 72 61 3b 0a 0a 20 20  he->szExtra;..  
4340: 61 73 73 65 72 74 28 20 70 63 61 63 68 65 2e 69  assert( pcache.i
4350: 73 49 6e 69 74 20 29 3b 0a 20 20 61 73 73 65 72  sInit );.  asser
4360: 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78  t( sqlite3_mutex
4370: 5f 6e 6f 74 68 65 6c 64 28 70 63 61 63 68 65 2e  _notheld(pcache.
4380: 6d 75 74 65 78 29 20 29 3b 0a 0a 20 20 2a 70 70  mutex) );..  *pp
4390: 50 61 67 65 20 3d 20 30 3b 0a 20 20 70 63 61 63  Page = 0;.  pcac
43a0: 68 65 45 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a  heEnterMutex();.
43b0: 0a 20 20 2f 2a 20 49 66 20 77 65 20 68 61 76 65  .  /* If we have
43c0: 20 72 65 61 63 68 65 64 20 74 68 65 20 6c 69 6d   reached the lim
43d0: 69 74 20 66 6f 72 20 70 69 6e 6e 65 64 2f 64 69  it for pinned/di
43e0: 72 74 79 20 70 61 67 65 73 2c 20 61 6e 64 20 74  rty pages, and t
43f0: 68 65 72 65 20 69 73 20 61 74 0a 20 20 2a 2a 20  here is at.  ** 
4400: 6c 65 61 73 74 20 6f 6e 65 20 64 69 72 74 79 20  least one dirty 
4410: 70 61 67 65 2c 20 69 6e 76 6f 6b 65 20 74 68 65  page, invoke the
4420: 20 78 53 74 72 65 73 73 20 63 61 6c 6c 62 61 63   xStress callbac
4430: 6b 20 74 6f 20 63 61 75 73 65 20 61 20 70 61 67  k to cause a pag
4440: 65 20 74 6f 0a 20 20 2a 2a 20 62 65 63 6f 6d 65  e to.  ** become
4450: 20 63 6c 65 61 6e 2e 0a 20 20 2a 2f 0a 20 20 65   clean..  */.  e
4460: 78 70 65 6e 73 69 76 65 5f 61 73 73 65 72 74 28  xpensive_assert(
4470: 20 70 43 61 63 68 65 2d 3e 6e 50 69 6e 6e 65 64   pCache->nPinned
4480: 3d 3d 70 63 61 63 68 65 50 69 6e 6e 65 64 43 6f  ==pcachePinnedCo
4490: 75 6e 74 28 70 43 61 63 68 65 29 20 29 3b 0a 20  unt(pCache) );. 
44a0: 20 65 78 70 65 6e 73 69 76 65 5f 61 73 73 65 72   expensive_asser
44b0: 74 28 20 70 63 61 63 68 65 43 68 65 63 6b 53 79  t( pcacheCheckSy
44c0: 6e 63 65 64 28 70 43 61 63 68 65 29 20 29 3b 0a  nced(pCache) );.
44d0: 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 78 53    if( pCache->xS
44e0: 74 72 65 73 73 0a 20 20 20 26 26 20 70 43 61 63  tress.   && pCac
44f0: 68 65 2d 3e 70 44 69 72 74 79 0a 20 20 20 26 26  he->pDirty.   &&
4500: 20 70 43 61 63 68 65 2d 3e 6e 50 69 6e 6e 65 64   pCache->nPinned
4510: 3e 3d 28 70 63 61 63 68 65 2e 6e 4d 61 78 50 61  >=(pcache.nMaxPa
4520: 67 65 2b 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 2d  ge+pCache->nMin-
4530: 70 63 61 63 68 65 2e 6e 4d 69 6e 50 61 67 65 29  pcache.nMinPage)
4540: 0a 20 20 29 7b 0a 20 20 20 20 50 67 48 64 72 20  .  ){.    PgHdr 
4550: 2a 70 50 67 3b 0a 20 20 20 20 61 73 73 65 72 74  *pPg;.    assert
4560: 28 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 54  (pCache->pDirtyT
4570: 61 69 6c 29 3b 0a 0a 20 20 20 20 66 6f 72 28 70  ail);..    for(p
4580: 50 67 3d 70 43 61 63 68 65 2d 3e 70 53 79 6e 63  Pg=pCache->pSync
4590: 65 64 3b 20 0a 20 20 20 20 20 20 20 20 70 50 67  ed; .        pPg
45a0: 20 26 26 20 28 70 50 67 2d 3e 6e 52 65 66 20 7c   && (pPg->nRef |
45b0: 7c 20 28 70 50 67 2d 3e 66 6c 61 67 73 26 50 47  | (pPg->flags&PG
45c0: 48 44 52 5f 4e 45 45 44 5f 53 59 4e 43 29 29 3b  HDR_NEED_SYNC));
45d0: 20 0a 20 20 20 20 20 20 20 20 70 50 67 3d 70 50   .        pPg=pP
45e0: 67 2d 3e 70 50 72 65 76 0a 20 20 20 20 29 3b 0a  g->pPrev.    );.
45f0: 20 20 20 20 69 66 28 20 21 70 50 67 20 29 7b 0a      if( !pPg ){.
4600: 20 20 20 20 20 20 66 6f 72 28 70 50 67 3d 70 43        for(pPg=pC
4610: 61 63 68 65 2d 3e 70 44 69 72 74 79 54 61 69 6c  ache->pDirtyTail
4620: 3b 20 70 50 67 20 26 26 20 70 50 67 2d 3e 6e 52  ; pPg && pPg->nR
4630: 65 66 3b 20 70 50 67 3d 70 50 67 2d 3e 70 50 72  ef; pPg=pPg->pPr
4640: 65 76 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69  ev);.    }.    i
4650: 66 28 20 70 50 67 20 29 7b 0a 20 20 20 20 20 20  f( pPg ){.      
4660: 69 6e 74 20 72 63 3b 0a 20 20 20 20 20 20 70 63  int rc;.      pc
4670: 61 63 68 65 45 78 69 74 4d 75 74 65 78 28 29 3b  acheExitMutex();
4680: 0a 20 20 20 20 20 20 72 63 20 3d 20 70 43 61 63  .      rc = pCac
4690: 68 65 2d 3e 78 53 74 72 65 73 73 28 70 43 61 63  he->xStress(pCac
46a0: 68 65 2d 3e 70 53 74 72 65 73 73 2c 20 70 50 67  he->pStress, pPg
46b0: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 21  );.      if( rc!
46c0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
46d0: 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b        return rc;
46e0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 70  .      }.      p
46f0: 63 61 63 68 65 45 6e 74 65 72 4d 75 74 65 78 28  cacheEnterMutex(
4700: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  );.    }.  }..  
4710: 2f 2a 20 49 66 20 74 68 65 20 67 6c 6f 62 61 6c  /* If the global
4720: 20 70 61 67 65 20 6c 69 6d 69 74 20 68 61 73 20   page limit has 
4730: 62 65 65 6e 20 72 65 61 63 68 65 64 2c 20 74 72  been reached, tr
4740: 79 20 74 6f 20 72 65 63 79 63 6c 65 20 61 20 70  y to recycle a p
4750: 61 67 65 2e 20 2a 2f 0a 20 20 69 66 28 20 70 43  age. */.  if( pC
4760: 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65  ache->bPurgeable
4770: 20 26 26 20 70 63 61 63 68 65 2e 6e 43 75 72 72   && pcache.nCurr
4780: 65 6e 74 50 61 67 65 3e 3d 70 63 61 63 68 65 2e  entPage>=pcache.
4790: 6e 4d 61 78 50 61 67 65 20 29 7b 0a 20 20 20 20  nMaxPage ){.    
47a0: 70 20 3d 20 70 63 61 63 68 65 52 65 63 79 63 6c  p = pcacheRecycl
47b0: 65 50 61 67 65 28 29 3b 0a 20 20 7d 0a 0a 20 20  ePage();.  }..  
47c0: 2f 2a 20 49 66 20 61 20 70 61 67 65 20 68 61 73  /* If a page has
47d0: 20 62 65 65 6e 20 72 65 63 79 63 6c 65 64 20 62   been recycled b
47e0: 75 74 20 69 74 20 69 73 20 74 68 65 20 77 72 6f  ut it is the wro
47f0: 6e 67 20 73 69 7a 65 2c 20 66 72 65 65 20 69 74  ng size, free it
4800: 2e 20 2a 2f 0a 20 20 69 66 28 20 70 20 26 26 20  . */.  if( p && 
4810: 28 70 2d 3e 70 43 61 63 68 65 2d 3e 73 7a 50 61  (p->pCache->szPa
4820: 67 65 21 3d 73 7a 50 61 67 65 20 7c 7c 20 70 2d  ge!=szPage || p-
4830: 3e 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 21  >pCache->szPage!
4840: 3d 73 7a 45 78 74 72 61 29 20 29 7b 0a 20 20 20  =szExtra) ){.   
4850: 20 70 63 61 63 68 65 50 61 67 65 46 72 65 65 28   pcachePageFree(
4860: 70 29 3b 0a 20 20 20 20 70 20 3d 20 30 3b 0a 20  p);.    p = 0;. 
4870: 20 7d 0a 0a 20 20 69 66 28 20 21 70 20 29 7b 0a   }..  if( !p ){.
4880: 20 20 20 20 70 20 3d 20 70 63 61 63 68 65 50 61      p = pcachePa
4890: 67 65 41 6c 6c 6f 63 28 70 43 61 63 68 65 29 3b  geAlloc(pCache);
48a0: 0a 20 20 7d 0a 0a 20 20 70 63 61 63 68 65 45 78  .  }..  pcacheEx
48b0: 69 74 4d 75 74 65 78 28 29 3b 0a 20 20 2a 70 70  itMutex();.  *pp
48c0: 50 61 67 65 20 3d 20 70 3b 0a 20 20 72 65 74 75  Page = p;.  retu
48d0: 72 6e 20 28 70 3f 53 51 4c 49 54 45 5f 4f 4b 3a  rn (p?SQLITE_OK:
48e0: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 29 3b 0a 7d  SQLITE_NOMEM);.}
48f0: 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ../*************
4900: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4910: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4920: 2a 2a 2a 2a 2a 2a 20 47 65 6e 65 72 61 6c 20 49  ****** General I
4930: 6e 74 65 72 66 61 63 65 73 20 2a 2a 2a 2a 2a 2a  nterfaces ******
4940: 0a 2a 2a 0a 2a 2a 20 49 6e 69 74 69 61 6c 69 7a  .**.** Initializ
4950: 65 20 61 6e 64 20 73 68 75 74 64 6f 77 6e 20 74  e and shutdown t
4960: 68 65 20 70 61 67 65 20 63 61 63 68 65 20 73 75  he page cache su
4970: 62 73 79 73 74 65 6d 2e 20 4e 65 69 74 68 65 72  bsystem. Neither
4980: 20 6f 66 20 74 68 65 73 65 20 0a 2a 2a 20 66 75   of these .** fu
4990: 6e 63 74 69 6f 6e 73 20 61 72 65 20 74 68 72 65  nctions are thre
49a0: 61 64 73 61 66 65 2e 0a 2a 2f 0a 69 6e 74 20 73  adsafe..*/.int s
49b0: 71 6c 69 74 65 33 50 63 61 63 68 65 49 6e 69 74  qlite3PcacheInit
49c0: 69 61 6c 69 7a 65 28 76 6f 69 64 29 7b 0a 20 20  ialize(void){.  
49d0: 61 73 73 65 72 74 28 20 70 63 61 63 68 65 2e 69  assert( pcache.i
49e0: 73 49 6e 69 74 3d 3d 30 20 29 3b 0a 20 20 6d 65  sInit==0 );.  me
49f0: 6d 73 65 74 28 26 70 63 61 63 68 65 2c 20 30 2c  mset(&pcache, 0,
4a00: 20 73 69 7a 65 6f 66 28 70 63 61 63 68 65 29 29   sizeof(pcache))
4a10: 3b 0a 20 20 69 66 28 20 73 71 6c 69 74 65 33 43  ;.  if( sqlite3C
4a20: 6f 6e 66 69 67 2e 62 43 6f 72 65 4d 75 74 65 78  onfig.bCoreMutex
4a30: 20 29 7b 0a 20 20 20 20 2f 2a 20 4e 6f 20 6e 65   ){.    /* No ne
4a40: 65 64 20 74 6f 20 63 68 65 63 6b 20 74 68 65 20  ed to check the 
4a50: 72 65 74 75 72 6e 20 76 61 6c 75 65 20 6f 66 20  return value of 
4a60: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 61 6c  sqlite3_mutex_al
4a70: 6c 6f 63 28 29 2e 20 0a 20 20 20 20 2a 2a 20 41  loc(). .    ** A
4a80: 6c 6c 6f 63 61 74 69 6e 67 20 61 20 73 74 61 74  llocating a stat
4a90: 69 63 20 6d 75 74 65 78 20 63 61 6e 6e 6f 74 20  ic mutex cannot 
4aa0: 66 61 69 6c 2e 0a 20 20 20 20 2a 2f 0a 20 20 20  fail..    */.   
4ab0: 20 70 63 61 63 68 65 2e 6d 75 74 65 78 20 3d 20   pcache.mutex = 
4ac0: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 61 6c  sqlite3_mutex_al
4ad0: 6c 6f 63 28 53 51 4c 49 54 45 5f 4d 55 54 45 58  loc(SQLITE_MUTEX
4ae0: 5f 53 54 41 54 49 43 5f 4c 52 55 29 3b 0a 20 20  _STATIC_LRU);.  
4af0: 7d 0a 20 20 70 63 61 63 68 65 2e 69 73 49 6e 69  }.  pcache.isIni
4b00: 74 20 3d 20 31 3b 0a 20 20 72 65 74 75 72 6e 20  t = 1;.  return 
4b10: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 76 6f 69  SQLITE_OK;.}.voi
4b20: 64 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 53  d sqlite3PcacheS
4b30: 68 75 74 64 6f 77 6e 28 76 6f 69 64 29 7b 0a 20  hutdown(void){. 
4b40: 20 6d 65 6d 73 65 74 28 26 70 63 61 63 68 65 2c   memset(&pcache,
4b50: 20 30 2c 20 73 69 7a 65 6f 66 28 70 63 61 63 68   0, sizeof(pcach
4b60: 65 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65  e));.}../*.** Re
4b70: 74 75 72 6e 20 74 68 65 20 73 69 7a 65 20 69 6e  turn the size in
4b80: 20 62 79 74 65 73 20 6f 66 20 61 20 50 43 61 63   bytes of a PCac
4b90: 68 65 20 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 69 6e  he object..*/.in
4ba0: 74 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 53  t sqlite3PcacheS
4bb0: 69 7a 65 28 76 6f 69 64 29 7b 20 72 65 74 75 72  ize(void){ retur
4bc0: 6e 20 73 69 7a 65 6f 66 28 50 43 61 63 68 65 29  n sizeof(PCache)
4bd0: 3b 20 7d 0a 0a 2f 2a 0a 2a 2a 20 43 72 65 61 74  ; }../*.** Creat
4be0: 65 20 61 20 6e 65 77 20 50 43 61 63 68 65 20 6f  e a new PCache o
4bf0: 62 6a 65 63 74 2e 20 20 53 74 6f 72 61 67 65 20  bject.  Storage 
4c00: 73 70 61 63 65 20 74 6f 20 68 6f 6c 64 20 74 68  space to hold th
4c10: 65 20 6f 62 6a 65 63 74 0a 2a 2a 20 68 61 73 20  e object.** has 
4c20: 61 6c 72 65 61 64 79 20 62 65 65 6e 20 61 6c 6c  already been all
4c30: 6f 63 61 74 65 64 20 61 6e 64 20 69 73 20 70 61  ocated and is pa
4c40: 73 73 65 64 20 69 6e 20 61 73 20 74 68 65 20 70  ssed in as the p
4c50: 20 70 6f 69 6e 74 65 72 2e 0a 2a 2f 0a 76 6f 69   pointer..*/.voi
4c60: 64 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 4f  d sqlite3PcacheO
4c70: 70 65 6e 28 0a 20 20 69 6e 74 20 73 7a 50 61 67  pen(.  int szPag
4c80: 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e,              
4c90: 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 65      /* Size of e
4ca0: 76 65 72 79 20 70 61 67 65 20 2a 2f 0a 20 20 69  very page */.  i
4cb0: 6e 74 20 73 7a 45 78 74 72 61 2c 20 20 20 20 20  nt szExtra,     
4cc0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 45              /* E
4cd0: 78 74 72 61 20 73 70 61 63 65 20 61 73 73 6f 63  xtra space assoc
4ce0: 69 61 74 65 64 20 77 69 74 68 20 65 61 63 68 20  iated with each 
4cf0: 70 61 67 65 20 2a 2f 0a 20 20 69 6e 74 20 62 50  page */.  int bP
4d00: 75 72 67 65 61 62 6c 65 2c 20 20 20 20 20 20 20  urgeable,       
4d10: 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69         /* True i
4d20: 66 20 70 61 67 65 73 20 61 72 65 20 6f 6e 20 62  f pages are on b
4d30: 61 63 6b 69 6e 67 20 73 74 6f 72 65 20 2a 2f 0a  acking store */.
4d40: 20 20 76 6f 69 64 20 28 2a 78 44 65 73 74 72 6f    void (*xDestro
4d50: 79 29 28 50 67 48 64 72 2a 29 2c 20 20 20 20 2f  y)(PgHdr*),    /
4d60: 2a 20 43 61 6c 6c 65 64 20 74 6f 20 64 65 73 74  * Called to dest
4d70: 72 6f 79 20 61 20 70 61 67 65 20 2a 2f 0a 20 20  roy a page */.  
4d80: 69 6e 74 20 28 2a 78 53 74 72 65 73 73 29 28 76  int (*xStress)(v
4d90: 6f 69 64 2a 2c 50 67 48 64 72 2a 29 2c 2f 2a 20  oid*,PgHdr*),/* 
4da0: 43 61 6c 6c 20 74 6f 20 74 72 79 20 74 6f 20 6d  Call to try to m
4db0: 61 6b 65 20 70 61 67 65 73 20 63 6c 65 61 6e 20  ake pages clean 
4dc0: 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 53 74 72 65  */.  void *pStre
4dd0: 73 73 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ss,             
4de0: 20 20 2f 2a 20 41 72 67 75 6d 65 6e 74 20 74 6f    /* Argument to
4df0: 20 78 53 74 72 65 73 73 20 2a 2f 0a 20 20 50 43   xStress */.  PC
4e00: 61 63 68 65 20 2a 70 20 20 20 20 20 20 20 20 20  ache *p         
4e10: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 72             /* Pr
4e20: 65 61 6c 6c 6f 63 61 74 65 64 20 73 70 61 63 65  eallocated space
4e30: 20 66 6f 72 20 74 68 65 20 50 43 61 63 68 65 20   for the PCache 
4e40: 2a 2f 0a 29 7b 0a 20 20 61 73 73 65 72 74 28 20  */.){.  assert( 
4e50: 70 63 61 63 68 65 2e 69 73 49 6e 69 74 20 29 3b  pcache.isInit );
4e60: 0a 20 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20  .  memset(p, 0, 
4e70: 73 69 7a 65 6f 66 28 50 43 61 63 68 65 29 29 3b  sizeof(PCache));
4e80: 0a 20 20 70 2d 3e 73 7a 50 61 67 65 20 3d 20 73  .  p->szPage = s
4e90: 7a 50 61 67 65 3b 0a 20 20 70 2d 3e 73 7a 45 78  zPage;.  p->szEx
4ea0: 74 72 61 20 3d 20 73 7a 45 78 74 72 61 3b 0a 20  tra = szExtra;. 
4eb0: 20 70 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 3d   p->bPurgeable =
4ec0: 20 62 50 75 72 67 65 61 62 6c 65 3b 0a 20 20 70   bPurgeable;.  p
4ed0: 2d 3e 78 44 65 73 74 72 6f 79 20 3d 20 78 44 65  ->xDestroy = xDe
4ee0: 73 74 72 6f 79 3b 0a 20 20 70 2d 3e 78 53 74 72  stroy;.  p->xStr
4ef0: 65 73 73 20 3d 20 78 53 74 72 65 73 73 3b 0a 20  ess = xStress;. 
4f00: 20 70 2d 3e 70 53 74 72 65 73 73 20 3d 20 70 53   p->pStress = pS
4f10: 74 72 65 73 73 3b 0a 20 20 70 2d 3e 6e 4d 61 78  tress;.  p->nMax
4f20: 20 3d 20 31 30 30 3b 0a 20 20 70 2d 3e 6e 4d 69   = 100;.  p->nMi
4f30: 6e 20 3d 20 31 30 3b 0a 0a 20 20 70 63 61 63 68  n = 10;..  pcach
4f40: 65 45 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a 20  eEnterMutex();. 
4f50: 20 69 66 28 20 62 50 75 72 67 65 61 62 6c 65 20   if( bPurgeable 
4f60: 29 7b 0a 20 20 20 20 70 63 61 63 68 65 2e 6e 4d  ){.    pcache.nM
4f70: 61 78 50 61 67 65 20 2b 3d 20 70 2d 3e 6e 4d 61  axPage += p->nMa
4f80: 78 3b 0a 20 20 20 20 70 63 61 63 68 65 2e 6e 4d  x;.    pcache.nM
4f90: 69 6e 50 61 67 65 20 2b 3d 20 70 2d 3e 6e 4d 69  inPage += p->nMi
4fa0: 6e 3b 0a 20 20 7d 0a 0a 20 20 70 63 61 63 68 65  n;.  }..  pcache
4fb0: 45 78 69 74 4d 75 74 65 78 28 29 3b 0a 7d 0a 0a  ExitMutex();.}..
4fc0: 2f 2a 0a 2a 2a 20 43 68 61 6e 67 65 20 74 68 65  /*.** Change the
4fd0: 20 70 61 67 65 20 73 69 7a 65 20 66 6f 72 20 50   page size for P
4fe0: 43 61 63 68 65 20 6f 62 6a 65 63 74 2e 20 20 54  Cache object.  T
4ff0: 68 69 73 20 63 61 6e 20 6f 6e 6c 79 20 68 61 70  his can only hap
5000: 70 65 6e 0a 2a 2a 20 77 68 65 6e 20 74 68 65 20  pen.** when the 
5010: 63 61 63 68 65 20 69 73 20 65 6d 70 74 79 2e 0a  cache is empty..
5020: 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50  */.void sqlite3P
5030: 63 61 63 68 65 53 65 74 50 61 67 65 53 69 7a 65  cacheSetPageSize
5040: 28 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 2c  (PCache *pCache,
5050: 20 69 6e 74 20 73 7a 50 61 67 65 29 7b 0a 20 20   int szPage){.  
5060: 61 73 73 65 72 74 28 70 43 61 63 68 65 2d 3e 6e  assert(pCache->n
5070: 50 61 67 65 3d 3d 30 29 3b 0a 20 20 70 43 61 63  Page==0);.  pCac
5080: 68 65 2d 3e 73 7a 50 61 67 65 20 3d 20 73 7a 50  he->szPage = szP
5090: 61 67 65 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 72  age;.}../*.** Tr
50a0: 79 20 74 6f 20 6f 62 74 61 69 6e 20 61 20 70 61  y to obtain a pa
50b0: 67 65 20 66 72 6f 6d 20 74 68 65 20 63 61 63 68  ge from the cach
50c0: 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  e..*/.int sqlite
50d0: 33 50 63 61 63 68 65 46 65 74 63 68 28 0a 20 20  3PcacheFetch(.  
50e0: 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 2c 20  PCache *pCache, 
50f0: 20 20 20 20 20 20 2f 2a 20 4f 62 74 61 69 6e 20        /* Obtain 
5100: 74 68 65 20 70 61 67 65 20 66 72 6f 6d 20 74 68  the page from th
5110: 69 73 20 63 61 63 68 65 20 2a 2f 0a 20 20 50 67  is cache */.  Pg
5120: 6e 6f 20 70 67 6e 6f 2c 20 20 20 20 20 20 20 20  no pgno,        
5130: 20 20 20 20 2f 2a 20 50 61 67 65 20 6e 75 6d 62      /* Page numb
5140: 65 72 20 74 6f 20 6f 62 74 61 69 6e 20 2a 2f 0a  er to obtain */.
5150: 20 20 69 6e 74 20 63 72 65 61 74 65 46 6c 61 67    int createFlag
5160: 2c 20 20 20 20 20 20 20 2f 2a 20 49 66 20 74 72  ,       /* If tr
5170: 75 65 2c 20 63 72 65 61 74 65 20 70 61 67 65 20  ue, create page 
5180: 69 66 20 69 74 20 64 6f 65 73 20 6e 6f 74 20 65  if it does not e
5190: 78 69 73 74 20 61 6c 72 65 61 64 79 20 2a 2f 0a  xist already */.
51a0: 20 20 50 67 48 64 72 20 2a 2a 70 70 50 61 67 65    PgHdr **ppPage
51b0: 20 20 20 20 20 20 20 20 2f 2a 20 57 72 69 74 65          /* Write
51c0: 20 74 68 65 20 70 61 67 65 20 68 65 72 65 20 2a   the page here *
51d0: 2f 0a 29 7b 0a 20 20 50 67 48 64 72 20 2a 70 50  /.){.  PgHdr *pP
51e0: 61 67 65 3b 0a 20 20 61 73 73 65 72 74 28 20 70  age;.  assert( p
51f0: 63 61 63 68 65 2e 69 73 49 6e 69 74 20 29 3b 0a  cache.isInit );.
5200: 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65    assert( pCache
5210: 21 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28  !=0 );.  assert(
5220: 20 70 67 6e 6f 3e 30 20 29 3b 0a 20 20 65 78 70   pgno>0 );.  exp
5230: 65 6e 73 69 76 65 5f 61 73 73 65 72 74 28 20 70  ensive_assert( p
5240: 43 61 63 68 65 2d 3e 6e 50 69 6e 6e 65 64 3d 3d  Cache->nPinned==
5250: 70 63 61 63 68 65 50 69 6e 6e 65 64 43 6f 75 6e  pcachePinnedCoun
5260: 74 28 70 43 61 63 68 65 29 20 29 3b 0a 0a 20 20  t(pCache) );..  
5270: 2f 2a 20 53 65 61 72 63 68 20 74 68 65 20 68 61  /* Search the ha
5280: 73 68 20 74 61 62 6c 65 20 66 6f 72 20 74 68 65  sh table for the
5290: 20 72 65 71 75 65 73 74 65 64 20 70 61 67 65 2e   requested page.
52a0: 20 45 78 69 74 20 65 61 72 6c 79 20 69 66 20 69   Exit early if i
52b0: 74 20 69 73 20 66 6f 75 6e 64 2e 20 2a 2f 0a 20  t is found. */. 
52c0: 20 69 66 28 20 70 43 61 63 68 65 2d 3e 61 70 48   if( pCache->apH
52d0: 61 73 68 20 29 7b 0a 20 20 20 20 75 33 32 20 68  ash ){.    u32 h
52e0: 20 3d 20 70 67 6e 6f 20 25 20 70 43 61 63 68 65   = pgno % pCache
52f0: 2d 3e 6e 48 61 73 68 3b 0a 20 20 20 20 70 63 61  ->nHash;.    pca
5300: 63 68 65 45 6e 74 65 72 4d 75 74 65 78 28 29 3b  cheEnterMutex();
5310: 0a 20 20 20 20 66 6f 72 28 70 50 61 67 65 3d 70  .    for(pPage=p
5320: 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d  Cache->apHash[h]
5330: 3b 20 70 50 61 67 65 3b 20 70 50 61 67 65 3d 70  ; pPage; pPage=p
5340: 50 61 67 65 2d 3e 70 4e 65 78 74 48 61 73 68 29  Page->pNextHash)
5350: 7b 0a 20 20 20 20 20 20 69 66 28 20 70 50 61 67  {.      if( pPag
5360: 65 2d 3e 70 67 6e 6f 3d 3d 70 67 6e 6f 20 29 7b  e->pgno==pgno ){
5370: 0a 20 20 20 20 20 20 20 20 69 66 28 20 70 50 61  .        if( pPa
5380: 67 65 2d 3e 6e 52 65 66 3d 3d 30 20 29 7b 0a 20  ge->nRef==0 ){. 
5390: 20 20 20 20 20 20 20 20 20 69 66 28 20 30 3d 3d           if( 0==
53a0: 28 70 50 61 67 65 2d 3e 66 6c 61 67 73 26 50 47  (pPage->flags&PG
53b0: 48 44 52 5f 44 49 52 54 59 29 20 29 7b 0a 20 20  HDR_DIRTY) ){.  
53c0: 20 20 20 20 20 20 20 20 20 20 70 63 61 63 68 65            pcache
53d0: 52 65 6d 6f 76 65 46 72 6f 6d 4c 72 75 4c 69 73  RemoveFromLruLis
53e0: 74 28 70 50 61 67 65 29 3b 0a 20 20 20 20 20 20  t(pPage);.      
53f0: 20 20 20 20 20 20 70 43 61 63 68 65 2d 3e 6e 50        pCache->nP
5400: 69 6e 6e 65 64 2b 2b 3b 0a 20 20 20 20 20 20 20  inned++;.       
5410: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 70     }.          p
5420: 43 61 63 68 65 2d 3e 6e 52 65 66 2b 2b 3b 0a 20  Cache->nRef++;. 
5430: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
5440: 20 70 50 61 67 65 2d 3e 6e 52 65 66 2b 2b 3b 0a   pPage->nRef++;.
5450: 20 20 20 20 20 20 20 20 2a 70 70 50 61 67 65 20          *ppPage 
5460: 3d 20 70 50 61 67 65 3b 0a 20 20 20 20 20 20 20  = pPage;.       
5470: 20 70 63 61 63 68 65 45 78 69 74 4d 75 74 65 78   pcacheExitMutex
5480: 28 29 3b 0a 20 20 20 20 20 20 20 20 72 65 74 75  ();.        retu
5490: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20  rn SQLITE_OK;.  
54a0: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20      }.    }.    
54b0: 70 63 61 63 68 65 45 78 69 74 4d 75 74 65 78 28  pcacheExitMutex(
54c0: 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 63 72  );.  }..  if( cr
54d0: 65 61 74 65 46 6c 61 67 20 29 7b 0a 20 20 20 20  eateFlag ){.    
54e0: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
54f0: 4f 4b 3b 0a 20 20 20 20 69 66 28 20 70 43 61 63  OK;.    if( pCac
5500: 68 65 2d 3e 6e 48 61 73 68 3c 3d 70 43 61 63 68  he->nHash<=pCach
5510: 65 2d 3e 6e 50 61 67 65 20 29 7b 0a 20 20 20 20  e->nPage ){.    
5520: 20 20 72 63 20 3d 20 70 63 61 63 68 65 52 65 73    rc = pcacheRes
5530: 69 7a 65 48 61 73 68 28 70 43 61 63 68 65 2c 20  izeHash(pCache, 
5540: 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3c 32 35  pCache->nHash<25
5550: 36 20 3f 20 32 35 36 20 3a 20 70 43 61 63 68 65  6 ? 256 : pCache
5560: 2d 3e 6e 48 61 73 68 2a 32 29 3b 0a 20 20 20 20  ->nHash*2);.    
5570: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
5580: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 72  _OK ){.        r
5590: 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 20 20  eturn rc;.      
55a0: 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 72 63 20  }.    }..    rc 
55b0: 3d 20 70 63 61 63 68 65 52 65 63 79 63 6c 65 4f  = pcacheRecycleO
55c0: 72 41 6c 6c 6f 63 28 70 43 61 63 68 65 2c 20 70  rAlloc(pCache, p
55d0: 70 50 61 67 65 29 3b 0a 20 20 20 20 69 66 28 20  pPage);.    if( 
55e0: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc!=SQLITE_OK ){
55f0: 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63  .      return rc
5600: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 50 61 67  ;.    }.    pPag
5610: 65 20 3d 20 2a 70 70 50 61 67 65 3b 0a 20 20 20  e = *ppPage;.   
5620: 20 70 50 61 67 65 2d 3e 70 50 61 67 65 72 20 3d   pPage->pPager =
5630: 20 30 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 66   0;.    pPage->f
5640: 6c 61 67 73 20 3d 20 30 3b 0a 20 20 20 20 70 50  lags = 0;.    pP
5650: 61 67 65 2d 3e 70 44 69 72 74 79 20 3d 20 30 3b  age->pDirty = 0;
5660: 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 67 6e 6f  .    pPage->pgno
5670: 20 3d 20 70 67 6e 6f 3b 0a 20 20 20 20 70 50 61   = pgno;.    pPa
5680: 67 65 2d 3e 70 43 61 63 68 65 20 3d 20 70 43 61  ge->pCache = pCa
5690: 63 68 65 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e  che;.    pPage->
56a0: 6e 52 65 66 20 3d 20 31 3b 0a 20 20 20 20 70 43  nRef = 1;.    pC
56b0: 61 63 68 65 2d 3e 6e 52 65 66 2b 2b 3b 0a 20 20  ache->nRef++;.  
56c0: 20 20 70 43 61 63 68 65 2d 3e 6e 50 69 6e 6e 65    pCache->nPinne
56d0: 64 2b 2b 3b 0a 20 20 20 20 70 63 61 63 68 65 41  d++;.    pcacheA
56e0: 64 64 54 6f 4c 69 73 74 28 26 70 43 61 63 68 65  ddToList(&pCache
56f0: 2d 3e 70 43 6c 65 61 6e 2c 20 70 50 61 67 65 29  ->pClean, pPage)
5700: 3b 0a 20 20 20 20 70 63 61 63 68 65 41 64 64 54  ;.    pcacheAddT
5710: 6f 48 61 73 68 28 70 50 61 67 65 29 3b 0a 20 20  oHash(pPage);.  
5720: 7d 65 6c 73 65 7b 0a 20 20 20 20 2a 70 70 50 61  }else{.    *ppPa
5730: 67 65 20 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20 65  ge = 0;.  }..  e
5740: 78 70 65 6e 73 69 76 65 5f 61 73 73 65 72 74 28  xpensive_assert(
5750: 20 70 43 61 63 68 65 2d 3e 6e 50 69 6e 6e 65 64   pCache->nPinned
5760: 3d 3d 70 63 61 63 68 65 50 69 6e 6e 65 64 43 6f  ==pcachePinnedCo
5770: 75 6e 74 28 70 43 61 63 68 65 29 20 29 3b 0a 20  unt(pCache) );. 
5780: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
5790: 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65 72 65  K;.}../*.** Dere
57a0: 66 65 72 65 6e 63 65 20 61 20 70 61 67 65 2e 20  ference a page. 
57b0: 20 57 68 65 6e 20 74 68 65 20 72 65 66 65 72 65   When the refere
57c0: 6e 63 65 20 63 6f 75 6e 74 20 72 65 61 63 68 65  nce count reache
57d0: 73 20 7a 65 72 6f 2c 0a 2a 2a 20 6d 6f 76 65 20  s zero,.** move 
57e0: 74 68 65 20 70 61 67 65 20 74 6f 20 74 68 65 20  the page to the 
57f0: 4c 52 55 20 6c 69 73 74 20 69 66 20 69 74 20 69  LRU list if it i
5800: 73 20 63 6c 65 61 6e 2e 0a 2a 2f 0a 76 6f 69 64  s clean..*/.void
5810: 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 52 65   sqlite3PcacheRe
5820: 6c 65 61 73 65 28 50 67 48 64 72 20 2a 70 29 7b  lease(PgHdr *p){
5830: 0a 20 20 61 73 73 65 72 74 28 20 70 2d 3e 6e 52  .  assert( p->nR
5840: 65 66 3e 30 20 29 3b 0a 20 20 70 2d 3e 6e 52 65  ef>0 );.  p->nRe
5850: 66 2d 2d 3b 0a 20 20 69 66 28 20 70 2d 3e 6e 52  f--;.  if( p->nR
5860: 65 66 3d 3d 30 20 29 7b 0a 20 20 20 20 50 43 61  ef==0 ){.    PCa
5870: 63 68 65 20 2a 70 43 61 63 68 65 20 3d 20 70 2d  che *pCache = p-
5880: 3e 70 43 61 63 68 65 3b 0a 20 20 20 20 69 66 28  >pCache;.    if(
5890: 20 70 2d 3e 70 43 61 63 68 65 2d 3e 78 44 65 73   p->pCache->xDes
58a0: 74 72 6f 79 20 29 7b 0a 20 20 20 20 20 20 70 2d  troy ){.      p-
58b0: 3e 70 43 61 63 68 65 2d 3e 78 44 65 73 74 72 6f  >pCache->xDestro
58c0: 79 28 70 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20  y(p);.    }.    
58d0: 70 43 61 63 68 65 2d 3e 6e 52 65 66 2d 2d 3b 0a  pCache->nRef--;.
58e0: 20 20 20 20 69 66 28 20 28 70 2d 3e 66 6c 61 67      if( (p->flag
58f0: 73 26 50 47 48 44 52 5f 44 49 52 54 59 29 3d 3d  s&PGHDR_DIRTY)==
5900: 30 20 29 7b 0a 20 20 20 20 20 20 70 43 61 63 68  0 ){.      pCach
5910: 65 2d 3e 6e 50 69 6e 6e 65 64 2d 2d 3b 0a 20 20  e->nPinned--;.  
5920: 20 20 20 20 70 63 61 63 68 65 45 6e 74 65 72 4d      pcacheEnterM
5930: 75 74 65 78 28 29 3b 0a 20 20 20 20 20 20 70 63  utex();.      pc
5940: 61 63 68 65 41 64 64 54 6f 4c 72 75 4c 69 73 74  acheAddToLruList
5950: 28 70 29 3b 0a 20 20 20 20 20 20 70 63 61 63 68  (p);.      pcach
5960: 65 45 78 69 74 4d 75 74 65 78 28 29 3b 0a 20 20  eExitMutex();.  
5970: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 2f    }else{.      /
5980: 2a 20 4d 6f 76 65 20 74 68 65 20 70 61 67 65 20  * Move the page 
5990: 74 6f 20 74 68 65 20 68 65 61 64 20 6f 66 20 74  to the head of t
59a0: 68 65 20 63 61 63 68 65 73 20 64 69 72 74 79 20  he caches dirty 
59b0: 6c 69 73 74 2e 20 2a 2f 0a 20 20 20 20 20 20 70  list. */.      p
59c0: 63 61 63 68 65 52 65 6d 6f 76 65 46 72 6f 6d 4c  cacheRemoveFromL
59d0: 69 73 74 28 26 70 43 61 63 68 65 2d 3e 70 44 69  ist(&pCache->pDi
59e0: 72 74 79 2c 20 70 29 3b 0a 20 20 20 20 20 20 70  rty, p);.      p
59f0: 63 61 63 68 65 41 64 64 54 6f 4c 69 73 74 28 26  cacheAddToList(&
5a00: 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 2c 20  pCache->pDirty, 
5a10: 70 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a  p);.    }.  }.}.
5a20: 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63 61  .void sqlite3Pca
5a30: 63 68 65 52 65 66 28 50 67 48 64 72 20 2a 70 29  cheRef(PgHdr *p)
5a40: 7b 0a 20 20 61 73 73 65 72 74 28 70 2d 3e 6e 52  {.  assert(p->nR
5a50: 65 66 3e 30 29 3b 0a 20 20 70 2d 3e 6e 52 65 66  ef>0);.  p->nRef
5a60: 2b 2b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 72 6f  ++;.}../*.** Dro
5a70: 70 20 61 20 70 61 67 65 20 66 72 6f 6d 20 74 68  p a page from th
5a80: 65 20 63 61 63 68 65 2e 20 54 68 65 72 65 20 6d  e cache. There m
5a90: 75 73 74 20 62 65 20 65 78 61 63 74 6c 79 20 6f  ust be exactly o
5aa0: 6e 65 20 72 65 66 65 72 65 6e 63 65 20 74 6f 20  ne reference to 
5ab0: 74 68 65 0a 2a 2a 20 70 61 67 65 2e 20 54 68 69  the.** page. Thi
5ac0: 73 20 66 75 6e 63 74 69 6f 6e 20 64 65 6c 65 74  s function delet
5ad0: 65 73 20 74 68 61 74 20 72 65 66 65 72 65 6e 63  es that referenc
5ae0: 65 2c 20 73 6f 20 61 66 74 65 72 20 69 74 20 72  e, so after it r
5af0: 65 74 75 72 6e 73 20 74 68 65 0a 2a 2a 20 70 61  eturns the.** pa
5b00: 67 65 20 70 6f 69 6e 74 65 64 20 74 6f 20 62 79  ge pointed to by
5b10: 20 70 20 69 73 20 69 6e 76 61 6c 69 64 2e 0a 2a   p is invalid..*
5b20: 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63  /.void sqlite3Pc
5b30: 61 63 68 65 44 72 6f 70 28 50 67 48 64 72 20 2a  acheDrop(PgHdr *
5b40: 70 29 7b 0a 20 20 50 43 61 63 68 65 20 2a 70 43  p){.  PCache *pC
5b50: 61 63 68 65 3b 0a 20 20 61 73 73 65 72 74 28 20  ache;.  assert( 
5b60: 70 2d 3e 6e 52 65 66 3d 3d 31 20 29 3b 0a 20 20  p->nRef==1 );.  
5b70: 61 73 73 65 72 74 28 20 30 3d 3d 28 70 2d 3e 66  assert( 0==(p->f
5b80: 6c 61 67 73 26 50 47 48 44 52 5f 44 49 52 54 59  lags&PGHDR_DIRTY
5b90: 29 20 29 3b 0a 20 20 70 43 61 63 68 65 20 3d 20  ) );.  pCache = 
5ba0: 70 2d 3e 70 43 61 63 68 65 3b 0a 20 20 70 43 61  p->pCache;.  pCa
5bb0: 63 68 65 2d 3e 6e 52 65 66 2d 2d 3b 0a 20 20 70  che->nRef--;.  p
5bc0: 43 61 63 68 65 2d 3e 6e 50 69 6e 6e 65 64 2d 2d  Cache->nPinned--
5bd0: 3b 0a 20 20 70 63 61 63 68 65 52 65 6d 6f 76 65  ;.  pcacheRemove
5be0: 46 72 6f 6d 4c 69 73 74 28 26 70 43 61 63 68 65  FromList(&pCache
5bf0: 2d 3e 70 43 6c 65 61 6e 2c 20 70 29 3b 0a 20 20  ->pClean, p);.  
5c00: 70 63 61 63 68 65 52 65 6d 6f 76 65 46 72 6f 6d  pcacheRemoveFrom
5c10: 48 61 73 68 28 70 29 3b 0a 20 20 70 63 61 63 68  Hash(p);.  pcach
5c20: 65 45 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a 20  eEnterMutex();. 
5c30: 20 70 63 61 63 68 65 50 61 67 65 46 72 65 65 28   pcachePageFree(
5c40: 70 29 3b 0a 20 20 70 63 61 63 68 65 45 78 69 74  p);.  pcacheExit
5c50: 4d 75 74 65 78 28 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  Mutex();.}../*.*
5c60: 2a 20 4d 61 6b 65 20 73 75 72 65 20 74 68 65 20  * Make sure the 
5c70: 70 61 67 65 20 69 73 20 6d 61 72 6b 65 64 20 61  page is marked a
5c80: 73 20 64 69 72 74 79 2e 20 20 49 66 20 69 74 20  s dirty.  If it 
5c90: 69 73 6e 27 74 20 64 69 72 74 79 20 61 6c 72 65  isn't dirty alre
5ca0: 61 64 79 2c 0a 2a 2a 20 6d 61 6b 65 20 69 74 20  ady,.** make it 
5cb0: 73 6f 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69  so..*/.void sqli
5cc0: 74 65 33 50 63 61 63 68 65 4d 61 6b 65 44 69 72  te3PcacheMakeDir
5cd0: 74 79 28 50 67 48 64 72 20 2a 70 29 7b 0a 20 20  ty(PgHdr *p){.  
5ce0: 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 3b 0a  PCache *pCache;.
5cf0: 20 20 70 2d 3e 66 6c 61 67 73 20 26 3d 20 7e 50    p->flags &= ~P
5d00: 47 48 44 52 5f 44 4f 4e 54 5f 57 52 49 54 45 3b  GHDR_DONT_WRITE;
5d10: 0a 20 20 69 66 28 20 70 2d 3e 66 6c 61 67 73 20  .  if( p->flags 
5d20: 26 20 50 47 48 44 52 5f 44 49 52 54 59 20 29 20  & PGHDR_DIRTY ) 
5d30: 72 65 74 75 72 6e 3b 0a 20 20 61 73 73 65 72 74  return;.  assert
5d40: 28 20 28 70 2d 3e 66 6c 61 67 73 20 26 20 50 47  ( (p->flags & PG
5d50: 48 44 52 5f 44 49 52 54 59 29 3d 3d 30 20 29 3b  HDR_DIRTY)==0 );
5d60: 0a 20 20 61 73 73 65 72 74 28 20 70 2d 3e 6e 52  .  assert( p->nR
5d70: 65 66 3e 30 20 29 3b 0a 20 20 70 43 61 63 68 65  ef>0 );.  pCache
5d80: 20 3d 20 70 2d 3e 70 43 61 63 68 65 3b 0a 20 20   = p->pCache;.  
5d90: 70 63 61 63 68 65 52 65 6d 6f 76 65 46 72 6f 6d  pcacheRemoveFrom
5da0: 4c 69 73 74 28 26 70 43 61 63 68 65 2d 3e 70 43  List(&pCache->pC
5db0: 6c 65 61 6e 2c 20 70 29 3b 0a 20 20 70 63 61 63  lean, p);.  pcac
5dc0: 68 65 41 64 64 54 6f 4c 69 73 74 28 26 70 43 61  heAddToList(&pCa
5dd0: 63 68 65 2d 3e 70 44 69 72 74 79 2c 20 70 29 3b  che->pDirty, p);
5de0: 0a 20 20 70 2d 3e 66 6c 61 67 73 20 7c 3d 20 50  .  p->flags |= P
5df0: 47 48 44 52 5f 44 49 52 54 59 3b 0a 7d 0a 0a 2f  GHDR_DIRTY;.}../
5e00: 2a 0a 2a 2a 20 4d 61 6b 65 20 73 75 72 65 20 74  *.** Make sure t
5e10: 68 65 20 70 61 67 65 20 69 73 20 6d 61 72 6b 65  he page is marke
5e20: 64 20 61 73 20 63 6c 65 61 6e 2e 20 20 49 66 20  d as clean.  If 
5e30: 69 74 20 69 73 6e 27 74 20 63 6c 65 61 6e 20 61  it isn't clean a
5e40: 6c 72 65 61 64 79 2c 0a 2a 2a 20 6d 61 6b 65 20  lready,.** make 
5e50: 69 74 20 73 6f 2e 0a 2a 2f 0a 76 6f 69 64 20 73  it so..*/.void s
5e60: 71 6c 69 74 65 33 50 63 61 63 68 65 4d 61 6b 65  qlite3PcacheMake
5e70: 43 6c 65 61 6e 28 50 67 48 64 72 20 2a 70 29 7b  Clean(PgHdr *p){
5e80: 0a 20 20 50 43 61 63 68 65 20 2a 70 43 61 63 68  .  PCache *pCach
5e90: 65 3b 0a 20 20 69 66 28 20 28 70 2d 3e 66 6c 61  e;.  if( (p->fla
5ea0: 67 73 20 26 20 50 47 48 44 52 5f 44 49 52 54 59  gs & PGHDR_DIRTY
5eb0: 29 3d 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a 20  )==0 ) return;. 
5ec0: 20 61 73 73 65 72 74 28 20 70 2d 3e 61 70 53 61   assert( p->apSa
5ed0: 76 65 5b 30 5d 3d 3d 30 20 26 26 20 70 2d 3e 61  ve[0]==0 && p->a
5ee0: 70 53 61 76 65 5b 31 5d 3d 3d 30 20 29 3b 0a 20  pSave[1]==0 );. 
5ef0: 20 61 73 73 65 72 74 28 20 70 2d 3e 66 6c 61 67   assert( p->flag
5f00: 73 20 26 20 50 47 48 44 52 5f 44 49 52 54 59 20  s & PGHDR_DIRTY 
5f10: 29 3b 0a 20 20 70 43 61 63 68 65 20 3d 20 70 2d  );.  pCache = p-
5f20: 3e 70 43 61 63 68 65 3b 0a 20 20 70 63 61 63 68  >pCache;.  pcach
5f30: 65 52 65 6d 6f 76 65 46 72 6f 6d 4c 69 73 74 28  eRemoveFromList(
5f40: 26 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 2c  &pCache->pDirty,
5f50: 20 70 29 3b 0a 20 20 70 63 61 63 68 65 45 6e 74   p);.  pcacheEnt
5f60: 65 72 4d 75 74 65 78 28 29 3b 0a 20 20 70 63 61  erMutex();.  pca
5f70: 63 68 65 41 64 64 54 6f 4c 69 73 74 28 26 70 43  cheAddToList(&pC
5f80: 61 63 68 65 2d 3e 70 43 6c 65 61 6e 2c 20 70 29  ache->pClean, p)
5f90: 3b 0a 20 20 70 2d 3e 66 6c 61 67 73 20 26 3d 20  ;.  p->flags &= 
5fa0: 7e 50 47 48 44 52 5f 44 49 52 54 59 3b 0a 20 20  ~PGHDR_DIRTY;.  
5fb0: 69 66 28 20 70 2d 3e 6e 52 65 66 3d 3d 30 20 29  if( p->nRef==0 )
5fc0: 7b 0a 20 20 20 20 70 63 61 63 68 65 41 64 64 54  {.    pcacheAddT
5fd0: 6f 4c 72 75 4c 69 73 74 28 70 29 3b 0a 20 20 20  oLruList(p);.   
5fe0: 20 70 43 61 63 68 65 2d 3e 6e 50 69 6e 6e 65 64   pCache->nPinned
5ff0: 2d 2d 3b 0a 20 20 7d 0a 20 20 65 78 70 65 6e 73  --;.  }.  expens
6000: 69 76 65 5f 61 73 73 65 72 74 28 20 70 43 61 63  ive_assert( pCac
6010: 68 65 2d 3e 6e 50 69 6e 6e 65 64 3d 3d 70 63 61  he->nPinned==pca
6020: 63 68 65 50 69 6e 6e 65 64 43 6f 75 6e 74 28 70  chePinnedCount(p
6030: 43 61 63 68 65 29 20 29 3b 0a 20 20 70 63 61 63  Cache) );.  pcac
6040: 68 65 45 78 69 74 4d 75 74 65 78 28 29 3b 0a 7d  heExitMutex();.}
6050: 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6b 65 20 65 76 65  ../*.** Make eve
6060: 72 79 20 70 61 67 65 20 69 6e 20 74 68 65 20 63  ry page in the c
6070: 61 63 68 65 20 63 6c 65 61 6e 2e 0a 2a 2f 0a 76  ache clean..*/.v
6080: 6f 69 64 20 73 71 6c 69 74 65 33 50 63 61 63 68  oid sqlite3Pcach
6090: 65 43 6c 65 61 6e 41 6c 6c 28 50 43 61 63 68 65  eCleanAll(PCache
60a0: 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 50 67 48   *pCache){.  PgH
60b0: 64 72 20 2a 70 3b 0a 20 20 70 63 61 63 68 65 45  dr *p;.  pcacheE
60c0: 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a 20 20 77  nterMutex();.  w
60d0: 68 69 6c 65 28 20 28 70 20 3d 20 70 43 61 63 68  hile( (p = pCach
60e0: 65 2d 3e 70 44 69 72 74 79 29 21 3d 30 20 29 7b  e->pDirty)!=0 ){
60f0: 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e  .    assert( p->
6100: 61 70 53 61 76 65 5b 30 5d 3d 3d 30 20 26 26 20  apSave[0]==0 && 
6110: 70 2d 3e 61 70 53 61 76 65 5b 31 5d 3d 3d 30 20  p->apSave[1]==0 
6120: 29 3b 0a 20 20 20 20 70 63 61 63 68 65 52 65 6d  );.    pcacheRem
6130: 6f 76 65 46 72 6f 6d 4c 69 73 74 28 26 70 43 61  oveFromList(&pCa
6140: 63 68 65 2d 3e 70 44 69 72 74 79 2c 20 70 29 3b  che->pDirty, p);
6150: 0a 20 20 20 20 70 2d 3e 66 6c 61 67 73 20 26 3d  .    p->flags &=
6160: 20 7e 50 47 48 44 52 5f 44 49 52 54 59 3b 0a 20   ~PGHDR_DIRTY;. 
6170: 20 20 20 70 63 61 63 68 65 41 64 64 54 6f 4c 69     pcacheAddToLi
6180: 73 74 28 26 70 43 61 63 68 65 2d 3e 70 43 6c 65  st(&pCache->pCle
6190: 61 6e 2c 20 70 29 3b 0a 20 20 20 20 69 66 28 20  an, p);.    if( 
61a0: 70 2d 3e 6e 52 65 66 3d 3d 30 20 29 7b 0a 20 20  p->nRef==0 ){.  
61b0: 20 20 20 20 70 63 61 63 68 65 41 64 64 54 6f 4c      pcacheAddToL
61c0: 72 75 4c 69 73 74 28 70 29 3b 0a 20 20 20 20 20  ruList(p);.     
61d0: 20 70 43 61 63 68 65 2d 3e 6e 50 69 6e 6e 65 64   pCache->nPinned
61e0: 2d 2d 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20  --;.    }.  }.  
61f0: 73 71 6c 69 74 65 33 50 63 61 63 68 65 41 73 73  sqlite3PcacheAss
6200: 65 72 74 46 6c 61 67 73 28 70 43 61 63 68 65 2c  ertFlags(pCache,
6210: 20 30 2c 20 50 47 48 44 52 5f 44 49 52 54 59 29   0, PGHDR_DIRTY)
6220: 3b 0a 20 20 65 78 70 65 6e 73 69 76 65 5f 61 73  ;.  expensive_as
6230: 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e 6e 50  sert( pCache->nP
6240: 69 6e 6e 65 64 3d 3d 70 63 61 63 68 65 50 69 6e  inned==pcachePin
6250: 6e 65 64 43 6f 75 6e 74 28 70 43 61 63 68 65 29  nedCount(pCache)
6260: 20 29 3b 0a 20 20 70 63 61 63 68 65 45 78 69 74   );.  pcacheExit
6270: 4d 75 74 65 78 28 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  Mutex();.}../*.*
6280: 2a 20 43 68 61 6e 67 65 20 74 68 65 20 70 61 67  * Change the pag
6290: 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65  e number of page
62a0: 20 70 20 74 6f 20 6e 65 77 50 67 6e 6f 2e 20 49   p to newPgno. I
62b0: 66 20 6e 65 77 50 67 6e 6f 20 69 73 20 30 2c 20  f newPgno is 0, 
62c0: 74 68 65 6e 20 74 68 65 0a 2a 2a 20 70 61 67 65  then the.** page
62d0: 20 6f 62 6a 65 63 74 20 69 73 20 61 64 64 65 64   object is added
62e0: 20 74 6f 20 74 68 65 20 63 6c 65 61 6e 2d 6c 69   to the clean-li
62f0: 73 74 20 61 6e 64 20 74 68 65 20 50 47 48 44 52  st and the PGHDR
6300: 5f 52 45 55 53 45 5f 55 4e 4c 49 4b 45 4c 59 20  _REUSE_UNLIKELY 
6310: 0a 2a 2a 20 66 6c 61 67 20 73 65 74 2e 0a 2a 2f  .** flag set..*/
6320: 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63 61  .void sqlite3Pca
6330: 63 68 65 4d 6f 76 65 28 50 67 48 64 72 20 2a 70  cheMove(PgHdr *p
6340: 2c 20 50 67 6e 6f 20 6e 65 77 50 67 6e 6f 29 7b  , Pgno newPgno){
6350: 0a 20 20 61 73 73 65 72 74 28 20 70 2d 3e 6e 52  .  assert( p->nR
6360: 65 66 3e 30 20 29 3b 0a 20 20 70 63 61 63 68 65  ef>0 );.  pcache
6370: 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73 68 28 70  RemoveFromHash(p
6380: 29 3b 0a 20 20 70 2d 3e 70 67 6e 6f 20 3d 20 6e  );.  p->pgno = n
6390: 65 77 50 67 6e 6f 3b 0a 20 20 69 66 28 20 6e 65  ewPgno;.  if( ne
63a0: 77 50 67 6e 6f 3d 3d 30 20 29 7b 0a 20 20 20 20  wPgno==0 ){.    
63b0: 70 2d 3e 66 6c 61 67 73 20 7c 3d 20 50 47 48 44  p->flags |= PGHD
63c0: 52 5f 52 45 55 53 45 5f 55 4e 4c 49 4b 45 4c 59  R_REUSE_UNLIKELY
63d0: 3b 0a 20 20 20 20 70 63 61 63 68 65 45 6e 74 65  ;.    pcacheEnte
63e0: 72 4d 75 74 65 78 28 29 3b 0a 20 20 20 20 70 63  rMutex();.    pc
63f0: 61 63 68 65 46 72 65 65 28 70 2d 3e 61 70 53 61  acheFree(p->apSa
6400: 76 65 5b 30 5d 29 3b 0a 20 20 20 20 70 63 61 63  ve[0]);.    pcac
6410: 68 65 46 72 65 65 28 70 2d 3e 61 70 53 61 76 65  heFree(p->apSave
6420: 5b 31 5d 29 3b 0a 20 20 20 20 70 63 61 63 68 65  [1]);.    pcache
6430: 45 78 69 74 4d 75 74 65 78 28 29 3b 0a 20 20 20  ExitMutex();.   
6440: 20 70 2d 3e 61 70 53 61 76 65 5b 30 5d 20 3d 20   p->apSave[0] = 
6450: 30 3b 0a 20 20 20 20 70 2d 3e 61 70 53 61 76 65  0;.    p->apSave
6460: 5b 31 5d 20 3d 20 30 3b 0a 20 20 20 20 73 71 6c  [1] = 0;.    sql
6470: 69 74 65 33 50 63 61 63 68 65 4d 61 6b 65 43 6c  ite3PcacheMakeCl
6480: 65 61 6e 28 70 29 3b 0a 20 20 7d 0a 20 20 70 63  ean(p);.  }.  pc
6490: 61 63 68 65 41 64 64 54 6f 48 61 73 68 28 70 29  acheAddToHash(p)
64a0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 6d 6f 76  ;.}../*.** Remov
64b0: 65 20 61 6c 6c 20 63 6f 6e 74 65 6e 74 20 66 72  e all content fr
64c0: 6f 6d 20 61 20 70 61 67 65 20 63 61 63 68 65 0a  om a page cache.
64d0: 2a 2f 0a 76 6f 69 64 20 70 63 61 63 68 65 43 6c  */.void pcacheCl
64e0: 65 61 72 28 50 43 61 63 68 65 20 2a 70 43 61 63  ear(PCache *pCac
64f0: 68 65 29 7b 0a 20 20 50 67 48 64 72 20 2a 70 2c  he){.  PgHdr *p,
6500: 20 2a 70 4e 65 78 74 3b 0a 20 20 61 73 73 65 72   *pNext;.  asser
6510: 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78  t( sqlite3_mutex
6520: 5f 68 65 6c 64 28 70 63 61 63 68 65 2e 6d 75 74  _held(pcache.mut
6530: 65 78 29 20 29 3b 0a 20 20 66 6f 72 28 70 3d 70  ex) );.  for(p=p
6540: 43 61 63 68 65 2d 3e 70 43 6c 65 61 6e 3b 20 70  Cache->pClean; p
6550: 3b 20 70 3d 70 4e 65 78 74 29 7b 0a 20 20 20 20  ; p=pNext){.    
6560: 70 4e 65 78 74 20 3d 20 70 2d 3e 70 4e 65 78 74  pNext = p->pNext
6570: 3b 0a 20 20 20 20 70 63 61 63 68 65 52 65 6d 6f  ;.    pcacheRemo
6580: 76 65 46 72 6f 6d 4c 72 75 4c 69 73 74 28 70 29  veFromLruList(p)
6590: 3b 0a 20 20 20 20 70 63 61 63 68 65 50 61 67 65  ;.    pcachePage
65a0: 46 72 65 65 28 70 29 3b 0a 20 20 7d 0a 20 20 66  Free(p);.  }.  f
65b0: 6f 72 28 70 3d 70 43 61 63 68 65 2d 3e 70 44 69  or(p=pCache->pDi
65c0: 72 74 79 3b 20 70 3b 20 70 3d 70 4e 65 78 74 29  rty; p; p=pNext)
65d0: 7b 0a 20 20 20 20 70 4e 65 78 74 20 3d 20 70 2d  {.    pNext = p-
65e0: 3e 70 4e 65 78 74 3b 0a 20 20 20 20 70 63 61 63  >pNext;.    pcac
65f0: 68 65 50 61 67 65 46 72 65 65 28 70 29 3b 0a 20  hePageFree(p);. 
6600: 20 7d 0a 20 20 70 43 61 63 68 65 2d 3e 70 43 6c   }.  pCache->pCl
6610: 65 61 6e 20 3d 20 30 3b 0a 20 20 70 43 61 63 68  ean = 0;.  pCach
6620: 65 2d 3e 70 44 69 72 74 79 20 3d 20 30 3b 0a 20  e->pDirty = 0;. 
6630: 20 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 54   pCache->pDirtyT
6640: 61 69 6c 20 3d 20 30 3b 0a 20 20 70 43 61 63 68  ail = 0;.  pCach
6650: 65 2d 3e 6e 50 61 67 65 20 3d 20 30 3b 0a 20 20  e->nPage = 0;.  
6660: 70 43 61 63 68 65 2d 3e 6e 50 69 6e 6e 65 64 20  pCache->nPinned 
6670: 3d 20 30 3b 0a 20 20 6d 65 6d 73 65 74 28 70 43  = 0;.  memset(pC
6680: 61 63 68 65 2d 3e 61 70 48 61 73 68 2c 20 30 2c  ache->apHash, 0,
6690: 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 2a 73   pCache->nHash*s
66a0: 69 7a 65 6f 66 28 70 43 61 63 68 65 2d 3e 61 70  izeof(pCache->ap
66b0: 48 61 73 68 5b 30 5d 29 29 3b 0a 7d 0a 0a 0a 2f  Hash[0]));.}.../
66c0: 2a 0a 2a 2a 20 44 72 6f 70 20 65 76 65 72 79 20  *.** Drop every 
66d0: 63 61 63 68 65 20 65 6e 74 72 79 20 77 68 6f 73  cache entry whos
66e0: 65 20 70 61 67 65 20 6e 75 6d 62 65 72 20 69 73  e page number is
66f0: 20 67 72 65 61 74 65 72 20 74 68 61 6e 20 22 70   greater than "p
6700: 67 6e 6f 22 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71  gno"..*/.void sq
6710: 6c 69 74 65 33 50 63 61 63 68 65 54 72 75 6e 63  lite3PcacheTrunc
6720: 61 74 65 28 50 43 61 63 68 65 20 2a 70 43 61 63  ate(PCache *pCac
6730: 68 65 2c 20 50 67 6e 6f 20 70 67 6e 6f 29 7b 0a  he, Pgno pgno){.
6740: 20 20 50 67 48 64 72 20 2a 70 2c 20 2a 70 4e 65    PgHdr *p, *pNe
6750: 78 74 3b 0a 20 20 50 67 48 64 72 20 2a 70 44 69  xt;.  PgHdr *pDi
6760: 72 74 79 20 3d 20 70 43 61 63 68 65 2d 3e 70 44  rty = pCache->pD
6770: 69 72 74 79 3b 0a 20 20 70 63 61 63 68 65 45 6e  irty;.  pcacheEn
6780: 74 65 72 4d 75 74 65 78 28 29 3b 0a 20 20 66 6f  terMutex();.  fo
6790: 72 28 70 3d 70 43 61 63 68 65 2d 3e 70 43 6c 65  r(p=pCache->pCle
67a0: 61 6e 3b 20 70 7c 7c 70 44 69 72 74 79 3b 20 70  an; p||pDirty; p
67b0: 3d 70 4e 65 78 74 29 7b 0a 20 20 20 20 69 66 28  =pNext){.    if(
67c0: 20 21 70 20 29 7b 0a 20 20 20 20 20 20 70 20 3d   !p ){.      p =
67d0: 20 70 44 69 72 74 79 3b 0a 20 20 20 20 20 20 70   pDirty;.      p
67e0: 44 69 72 74 79 20 3d 20 30 3b 0a 20 20 20 20 7d  Dirty = 0;.    }
67f0: 0a 20 20 20 20 70 4e 65 78 74 20 3d 20 70 2d 3e  .    pNext = p->
6800: 70 4e 65 78 74 3b 0a 20 20 20 20 69 66 28 20 70  pNext;.    if( p
6810: 2d 3e 70 67 6e 6f 3e 70 67 6e 6f 20 29 7b 0a 20  ->pgno>pgno ){. 
6820: 20 20 20 20 20 69 66 28 20 70 2d 3e 6e 52 65 66       if( p->nRef
6830: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 70  ==0 ){.        p
6840: 63 61 63 68 65 52 65 6d 6f 76 65 46 72 6f 6d 48  cacheRemoveFromH
6850: 61 73 68 28 70 29 3b 0a 20 20 20 20 20 20 20 20  ash(p);.        
6860: 69 66 28 20 70 2d 3e 66 6c 61 67 73 26 50 47 48  if( p->flags&PGH
6870: 44 52 5f 44 49 52 54 59 20 29 7b 0a 20 20 20 20  DR_DIRTY ){.    
6880: 20 20 20 20 20 20 70 63 61 63 68 65 52 65 6d 6f        pcacheRemo
6890: 76 65 46 72 6f 6d 4c 69 73 74 28 26 70 43 61 63  veFromList(&pCac
68a0: 68 65 2d 3e 70 44 69 72 74 79 2c 20 70 29 3b 0a  he->pDirty, p);.
68b0: 20 20 20 20 20 20 20 20 20 20 70 43 61 63 68 65            pCache
68c0: 2d 3e 6e 50 69 6e 6e 65 64 2d 2d 3b 0a 20 20 20  ->nPinned--;.   
68d0: 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
68e0: 20 20 20 20 20 20 70 63 61 63 68 65 52 65 6d 6f        pcacheRemo
68f0: 76 65 46 72 6f 6d 4c 69 73 74 28 26 70 43 61 63  veFromList(&pCac
6900: 68 65 2d 3e 70 43 6c 65 61 6e 2c 20 70 29 3b 0a  he->pClean, p);.
6910: 20 20 20 20 20 20 20 20 20 20 70 63 61 63 68 65            pcache
6920: 52 65 6d 6f 76 65 46 72 6f 6d 4c 72 75 4c 69 73  RemoveFromLruLis
6930: 74 28 70 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a  t(p);.        }.
6940: 20 20 20 20 20 20 20 20 70 63 61 63 68 65 50 61          pcachePa
6950: 67 65 46 72 65 65 28 70 29 3b 0a 20 20 20 20 20  geFree(p);.     
6960: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
6970: 2f 2a 20 49 66 20 74 68 65 72 65 20 61 72 65 20  /* If there are 
6980: 72 65 66 65 72 65 6e 63 65 73 20 74 6f 20 74 68  references to th
6990: 65 20 70 61 67 65 2c 20 69 74 20 63 61 6e 6e 6f  e page, it canno
69a0: 74 20 62 65 20 66 72 65 65 64 2e 20 49 6e 20 74  t be freed. In t
69b0: 68 69 73 0a 20 20 20 20 20 20 20 20 2a 2a 20 63  his.        ** c
69c0: 61 73 65 2c 20 7a 65 72 6f 20 74 68 65 20 70 61  ase, zero the pa
69d0: 67 65 20 63 6f 6e 74 65 6e 74 20 69 6e 73 74 65  ge content inste
69e0: 61 64 2e 0a 20 20 20 20 20 20 20 20 2a 2f 0a 20  ad..        */. 
69f0: 20 20 20 20 20 20 20 6d 65 6d 73 65 74 28 70 2d         memset(p-
6a00: 3e 70 44 61 74 61 2c 20 30 2c 20 70 43 61 63 68  >pData, 0, pCach
6a10: 65 2d 3e 73 7a 50 61 67 65 29 3b 0a 20 20 20 20  e->szPage);.    
6a20: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20    }.    }.  }.  
6a30: 70 63 61 63 68 65 45 78 69 74 4d 75 74 65 78 28  pcacheExitMutex(
6a40: 29 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f  );.}.../*.** Clo
6a50: 73 65 20 61 20 63 61 63 68 65 2e 0a 2a 2f 0a 76  se a cache..*/.v
6a60: 6f 69 64 20 73 71 6c 69 74 65 33 50 63 61 63 68  oid sqlite3Pcach
6a70: 65 43 6c 6f 73 65 28 50 43 61 63 68 65 20 2a 70  eClose(PCache *p
6a80: 43 61 63 68 65 29 7b 0a 20 20 70 63 61 63 68 65  Cache){.  pcache
6a90: 45 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a 0a 20  EnterMutex();.. 
6aa0: 20 2f 2a 20 46 72 65 65 20 61 6c 6c 20 74 68 65   /* Free all the
6ab0: 20 70 61 67 65 73 20 75 73 65 64 20 62 79 20 74   pages used by t
6ac0: 68 69 73 20 70 61 67 65 72 20 61 6e 64 20 72 65  his pager and re
6ad0: 6d 6f 76 65 20 74 68 65 6d 20 66 72 6f 6d 20 74  move them from t
6ae0: 68 65 20 4c 52 55 20 6c 69 73 74 2e 20 2a 2f 0a  he LRU list. */.
6af0: 20 20 70 63 61 63 68 65 43 6c 65 61 72 28 70 43    pcacheClear(pC
6b00: 61 63 68 65 29 3b 0a 20 20 69 66 28 20 70 43 61  ache);.  if( pCa
6b10: 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20  che->bPurgeable 
6b20: 29 7b 0a 20 20 20 20 70 63 61 63 68 65 2e 6e 4d  ){.    pcache.nM
6b30: 61 78 50 61 67 65 20 2d 3d 20 70 43 61 63 68 65  axPage -= pCache
6b40: 2d 3e 6e 4d 61 78 3b 0a 20 20 20 20 70 63 61 63  ->nMax;.    pcac
6b50: 68 65 2e 6e 4d 69 6e 50 61 67 65 20 2d 3d 20 70  he.nMinPage -= p
6b60: 43 61 63 68 65 2d 3e 6e 4d 69 6e 3b 0a 20 20 7d  Cache->nMin;.  }
6b70: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
6b80: 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 29 3b  pCache->apHash);
6b90: 0a 0a 20 20 70 63 61 63 68 65 45 78 69 74 4d 75  ..  pcacheExitMu
6ba0: 74 65 78 28 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  tex();.}../*.** 
6bb0: 50 72 65 73 65 72 76 65 20 74 68 65 20 63 6f 6e  Preserve the con
6bc0: 74 65 6e 74 20 6f 66 20 74 68 65 20 70 61 67 65  tent of the page
6bd0: 2e 20 20 49 74 20 69 73 20 61 73 73 75 6d 65 64  .  It is assumed
6be0: 20 74 68 61 74 20 74 68 65 20 63 6f 6e 74 65 6e   that the conten
6bf0: 74 0a 2a 2a 20 68 61 73 20 6e 6f 74 20 62 65 65  t.** has not bee
6c00: 6e 20 70 72 65 73 65 72 76 65 64 20 61 6c 72 65  n preserved alre
6c10: 61 64 79 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 69 64  ady..**.** If id
6c20: 4a 6f 75 72 6e 61 6c 3d 3d 30 20 74 68 65 6e 20  Journal==0 then 
6c30: 74 68 69 73 20 69 73 20 66 6f 72 20 74 68 65 20  this is for the 
6c40: 6f 76 65 72 61 6c 6c 20 74 72 61 6e 73 61 63 74  overall transact
6c50: 69 6f 6e 2e 0a 2a 2a 20 49 66 20 69 64 4a 6f 75  ion..** If idJou
6c60: 72 6e 61 6c 3d 3d 31 20 74 68 65 6e 20 74 68 69  rnal==1 then thi
6c70: 73 20 69 73 20 66 6f 72 20 74 68 65 20 73 74 61  s is for the sta
6c80: 74 65 6d 65 6e 74 20 6a 6f 75 72 6e 61 6c 2e 0a  tement journal..
6c90: 2a 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69  **.** This routi
6ca0: 6e 65 20 69 73 20 75 73 65 64 20 66 6f 72 20 69  ne is used for i
6cb0: 6e 2d 6d 65 6d 6f 72 79 20 64 61 74 61 62 61 73  n-memory databas
6cc0: 65 73 20 6f 6e 6c 79 2e 0a 2a 2a 0a 2a 2a 20 52  es only..**.** R
6cd0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 20  eturn SQLITE_OK 
6ce0: 6f 72 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 20  or SQLITE_NOMEM 
6cf0: 69 66 20 61 20 6d 65 6d 6f 72 79 20 61 6c 6c 6f  if a memory allo
6d00: 63 61 74 69 6f 6e 20 66 61 69 6c 73 2e 0a 2a 2f  cation fails..*/
6d10: 0a 69 6e 74 20 73 71 6c 69 74 65 33 50 63 61 63  .int sqlite3Pcac
6d20: 68 65 50 72 65 73 65 72 76 65 28 50 67 48 64 72  hePreserve(PgHdr
6d30: 20 2a 70 2c 20 69 6e 74 20 69 64 4a 6f 75 72 6e   *p, int idJourn
6d40: 61 6c 29 7b 0a 20 20 76 6f 69 64 20 2a 78 3b 0a  al){.  void *x;.
6d50: 20 20 69 6e 74 20 73 7a 3b 0a 20 20 61 73 73 65    int sz;.  asse
6d60: 72 74 28 20 70 2d 3e 70 43 61 63 68 65 2d 3e 62  rt( p->pCache->b
6d70: 50 75 72 67 65 61 62 6c 65 3d 3d 30 20 29 3b 0a  Purgeable==0 );.
6d80: 20 20 61 73 73 65 72 74 28 20 70 2d 3e 61 70 53    assert( p->apS
6d90: 61 76 65 5b 69 64 4a 6f 75 72 6e 61 6c 5d 3d 3d  ave[idJournal]==
6da0: 30 20 29 3b 0a 20 20 73 7a 20 3d 20 70 2d 3e 70  0 );.  sz = p->p
6db0: 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 3b 0a 20  Cache->szPage;. 
6dc0: 20 70 2d 3e 61 70 53 61 76 65 5b 69 64 4a 6f 75   p->apSave[idJou
6dd0: 72 6e 61 6c 5d 20 3d 20 78 20 3d 20 73 71 6c 69  rnal] = x = sqli
6de0: 74 65 33 50 61 67 65 4d 61 6c 6c 6f 63 28 20 73  te3PageMalloc( s
6df0: 7a 20 29 3b 0a 20 20 69 66 28 20 78 3d 3d 30 20  z );.  if( x==0 
6e00: 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  ) return SQLITE_
6e10: 4e 4f 4d 45 4d 3b 0a 20 20 6d 65 6d 63 70 79 28  NOMEM;.  memcpy(
6e20: 78 2c 20 70 2d 3e 70 44 61 74 61 2c 20 73 7a 29  x, p->pData, sz)
6e30: 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ;.  return SQLIT
6e40: 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43  E_OK;.}../*.** C
6e50: 6f 6d 6d 69 74 20 61 20 63 68 61 6e 67 65 20 70  ommit a change p
6e60: 72 65 76 69 6f 75 73 6c 79 20 70 72 65 73 65 72  reviously preser
6e70: 76 65 64 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c  ved..*/.void sql
6e80: 69 74 65 33 50 63 61 63 68 65 43 6f 6d 6d 69 74  ite3PcacheCommit
6e90: 28 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 2c  (PCache *pCache,
6ea0: 20 69 6e 74 20 69 64 4a 6f 75 72 6e 61 6c 29 7b   int idJournal){
6eb0: 0a 20 20 50 67 48 64 72 20 2a 70 3b 0a 20 20 70  .  PgHdr *p;.  p
6ec0: 63 61 63 68 65 45 6e 74 65 72 4d 75 74 65 78 28  cacheEnterMutex(
6ed0: 29 3b 20 20 20 20 20 2f 2a 20 4d 75 74 65 78 20  );     /* Mutex 
6ee0: 69 73 20 72 65 71 75 69 72 65 64 20 74 6f 20 63  is required to c
6ef0: 61 6c 6c 20 70 63 61 63 68 65 46 72 65 65 28 29  all pcacheFree()
6f00: 20 2a 2f 0a 20 20 66 6f 72 28 70 3d 70 43 61 63   */.  for(p=pCac
6f10: 68 65 2d 3e 70 44 69 72 74 79 3b 20 70 3b 20 70  he->pDirty; p; p
6f20: 3d 70 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20  =p->pNext){.    
6f30: 69 66 28 20 70 2d 3e 61 70 53 61 76 65 5b 69 64  if( p->apSave[id
6f40: 4a 6f 75 72 6e 61 6c 5d 20 29 7b 0a 20 20 20 20  Journal] ){.    
6f50: 20 20 70 63 61 63 68 65 46 72 65 65 28 70 2d 3e    pcacheFree(p->
6f60: 61 70 53 61 76 65 5b 69 64 4a 6f 75 72 6e 61 6c  apSave[idJournal
6f70: 5d 29 3b 0a 20 20 20 20 20 20 70 2d 3e 61 70 53  ]);.      p->apS
6f80: 61 76 65 5b 69 64 4a 6f 75 72 6e 61 6c 5d 20 3d  ave[idJournal] =
6f90: 20 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20   0;.    }.  }.  
6fa0: 70 63 61 63 68 65 45 78 69 74 4d 75 74 65 78 28  pcacheExitMutex(
6fb0: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 6f 6c 6c  );.}../*.** Roll
6fc0: 62 61 63 6b 20 61 20 63 68 61 6e 67 65 20 70 72  back a change pr
6fd0: 65 76 69 6f 75 73 6c 79 20 70 72 65 73 65 72 76  eviously preserv
6fe0: 65 64 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69  ed..*/.void sqli
6ff0: 74 65 33 50 63 61 63 68 65 52 6f 6c 6c 62 61 63  te3PcacheRollbac
7000: 6b 28 50 43 61 63 68 65 20 2a 70 43 61 63 68 65  k(PCache *pCache
7010: 2c 20 69 6e 74 20 69 64 4a 6f 75 72 6e 61 6c 29  , int idJournal)
7020: 7b 0a 20 20 50 67 48 64 72 20 2a 70 3b 0a 20 20  {.  PgHdr *p;.  
7030: 69 6e 74 20 73 7a 3b 0a 20 20 70 63 61 63 68 65  int sz;.  pcache
7040: 45 6e 74 65 72 4d 75 74 65 78 28 29 3b 20 20 20  EnterMutex();   
7050: 20 20 2f 2a 20 4d 75 74 65 78 20 69 73 20 72 65    /* Mutex is re
7060: 71 75 69 72 65 64 20 74 6f 20 63 61 6c 6c 20 70  quired to call p
7070: 63 61 63 68 65 46 72 65 65 28 29 20 2a 2f 0a 20  cacheFree() */. 
7080: 20 73 7a 20 3d 20 70 43 61 63 68 65 2d 3e 73 7a   sz = pCache->sz
7090: 50 61 67 65 3b 0a 20 20 66 6f 72 28 70 3d 70 43  Page;.  for(p=pC
70a0: 61 63 68 65 2d 3e 70 44 69 72 74 79 3b 20 70 3b  ache->pDirty; p;
70b0: 20 70 3d 70 2d 3e 70 4e 65 78 74 29 7b 0a 20 20   p=p->pNext){.  
70c0: 20 20 69 66 28 20 70 2d 3e 61 70 53 61 76 65 5b    if( p->apSave[
70d0: 69 64 4a 6f 75 72 6e 61 6c 5d 20 29 7b 0a 20 20  idJournal] ){.  
70e0: 20 20 20 20 6d 65 6d 63 70 79 28 70 2d 3e 70 44      memcpy(p->pD
70f0: 61 74 61 2c 20 70 2d 3e 61 70 53 61 76 65 5b 69  ata, p->apSave[i
7100: 64 4a 6f 75 72 6e 61 6c 5d 2c 20 73 7a 29 3b 0a  dJournal], sz);.
7110: 20 20 20 20 20 20 70 63 61 63 68 65 46 72 65 65        pcacheFree
7120: 28 70 2d 3e 61 70 53 61 76 65 5b 69 64 4a 6f 75  (p->apSave[idJou
7130: 72 6e 61 6c 5d 29 3b 0a 20 20 20 20 20 20 70 2d  rnal]);.      p-
7140: 3e 61 70 53 61 76 65 5b 69 64 4a 6f 75 72 6e 61  >apSave[idJourna
7150: 6c 5d 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20  l] = 0;.    }.  
7160: 7d 0a 20 20 70 63 61 63 68 65 45 78 69 74 4d 75  }.  pcacheExitMu
7170: 74 65 78 28 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a  tex();.}../* .**
7180: 20 41 73 73 65 72 74 20 66 6c 61 67 73 20 73 65   Assert flags se
7190: 74 74 69 6e 67 73 20 6f 6e 20 61 6c 6c 20 70 61  ttings on all pa
71a0: 67 65 73 2e 20 20 44 65 62 75 67 67 69 6e 67 20  ges.  Debugging 
71b0: 6f 6e 6c 79 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71  only..*/.void sq
71c0: 6c 69 74 65 33 50 63 61 63 68 65 41 73 73 65 72  lite3PcacheAsser
71d0: 74 46 6c 61 67 73 28 50 43 61 63 68 65 20 2a 70  tFlags(PCache *p
71e0: 43 61 63 68 65 2c 20 69 6e 74 20 74 72 75 65 4d  Cache, int trueM
71f0: 61 73 6b 2c 20 69 6e 74 20 66 61 6c 73 65 4d 61  ask, int falseMa
7200: 73 6b 29 7b 0a 20 20 50 67 48 64 72 20 2a 70 3b  sk){.  PgHdr *p;
7210: 0a 20 20 66 6f 72 28 70 3d 70 43 61 63 68 65 2d  .  for(p=pCache-
7220: 3e 70 44 69 72 74 79 3b 20 70 3b 20 70 3d 70 2d  >pDirty; p; p=p-
7230: 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 61 73 73  >pNext){.    ass
7240: 65 72 74 28 20 28 70 2d 3e 66 6c 61 67 73 26 74  ert( (p->flags&t
7250: 72 75 65 4d 61 73 6b 29 3d 3d 74 72 75 65 4d 61  rueMask)==trueMa
7260: 73 6b 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74  sk );.    assert
7270: 28 20 28 70 2d 3e 66 6c 61 67 73 26 66 61 6c 73  ( (p->flags&fals
7280: 65 4d 61 73 6b 29 3d 3d 30 20 29 3b 0a 20 20 7d  eMask)==0 );.  }
7290: 0a 20 20 66 6f 72 28 70 3d 70 43 61 63 68 65 2d  .  for(p=pCache-
72a0: 3e 70 43 6c 65 61 6e 3b 20 70 3b 20 70 3d 70 2d  >pClean; p; p=p-
72b0: 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 61 73 73  >pNext){.    ass
72c0: 65 72 74 28 20 28 70 2d 3e 66 6c 61 67 73 26 74  ert( (p->flags&t
72d0: 72 75 65 4d 61 73 6b 29 3d 3d 74 72 75 65 4d 61  rueMask)==trueMa
72e0: 73 6b 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74  sk );.    assert
72f0: 28 20 28 70 2d 3e 66 6c 61 67 73 26 66 61 6c 73  ( (p->flags&fals
7300: 65 4d 61 73 6b 29 3d 3d 30 20 29 3b 0a 20 20 7d  eMask)==0 );.  }
7310: 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 44 69 73 63 61  .}../* .** Disca
7320: 72 64 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20  rd the contents 
7330: 6f 66 20 74 68 65 20 63 61 63 68 65 2e 0a 2a 2f  of the cache..*/
7340: 0a 69 6e 74 20 73 71 6c 69 74 65 33 50 63 61 63  .int sqlite3Pcac
7350: 68 65 43 6c 65 61 72 28 50 43 61 63 68 65 20 2a  heClear(PCache *
7360: 70 43 61 63 68 65 29 7b 0a 20 20 61 73 73 65 72  pCache){.  asser
7370: 74 28 70 43 61 63 68 65 2d 3e 6e 52 65 66 3d 3d  t(pCache->nRef==
7380: 30 29 3b 0a 20 20 70 63 61 63 68 65 45 6e 74 65  0);.  pcacheEnte
7390: 72 4d 75 74 65 78 28 29 3b 0a 20 20 70 63 61 63  rMutex();.  pcac
73a0: 68 65 43 6c 65 61 72 28 70 43 61 63 68 65 29 3b  heClear(pCache);
73b0: 0a 20 20 70 63 61 63 68 65 45 78 69 74 4d 75 74  .  pcacheExitMut
73c0: 65 78 28 29 3b 0a 20 20 72 65 74 75 72 6e 20 53  ex();.  return S
73d0: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  QLITE_OK;.}../*.
73e0: 2a 2a 20 4d 65 72 67 65 20 74 77 6f 20 6c 69 73  ** Merge two lis
73f0: 74 73 20 6f 66 20 70 61 67 65 73 20 63 6f 6e 6e  ts of pages conn
7400: 65 63 74 65 64 20 62 79 20 70 44 69 72 74 79 20  ected by pDirty 
7410: 61 6e 64 20 69 6e 20 70 67 6e 6f 20 6f 72 64 65  and in pgno orde
7420: 72 2e 0a 2a 2a 20 44 6f 20 6e 6f 74 20 62 6f 74  r..** Do not bot
7430: 68 20 66 69 78 69 6e 67 20 74 68 65 20 70 50 72  h fixing the pPr
7440: 65 76 44 69 72 74 79 20 70 6f 69 6e 74 65 72 73  evDirty pointers
7450: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 50 67 48 64  ..*/.static PgHd
7460: 72 20 2a 70 63 61 63 68 65 4d 65 72 67 65 44 69  r *pcacheMergeDi
7470: 72 74 79 4c 69 73 74 28 50 67 48 64 72 20 2a 70  rtyList(PgHdr *p
7480: 41 2c 20 50 67 48 64 72 20 2a 70 42 29 7b 0a 20  A, PgHdr *pB){. 
7490: 20 50 67 48 64 72 20 72 65 73 75 6c 74 2c 20 2a   PgHdr result, *
74a0: 70 54 61 69 6c 3b 0a 20 20 70 54 61 69 6c 20 3d  pTail;.  pTail =
74b0: 20 26 72 65 73 75 6c 74 3b 0a 20 20 77 68 69 6c   &result;.  whil
74c0: 65 28 20 70 41 20 26 26 20 70 42 20 29 7b 0a 20  e( pA && pB ){. 
74d0: 20 20 20 69 66 28 20 70 41 2d 3e 70 67 6e 6f 3c     if( pA->pgno<
74e0: 70 42 2d 3e 70 67 6e 6f 20 29 7b 0a 20 20 20 20  pB->pgno ){.    
74f0: 20 20 70 54 61 69 6c 2d 3e 70 44 69 72 74 79 20    pTail->pDirty 
7500: 3d 20 70 41 3b 0a 20 20 20 20 20 20 70 54 61 69  = pA;.      pTai
7510: 6c 20 3d 20 70 41 3b 0a 20 20 20 20 20 20 70 41  l = pA;.      pA
7520: 20 3d 20 70 41 2d 3e 70 44 69 72 74 79 3b 0a 20   = pA->pDirty;. 
7530: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
7540: 70 54 61 69 6c 2d 3e 70 44 69 72 74 79 20 3d 20  pTail->pDirty = 
7550: 70 42 3b 0a 20 20 20 20 20 20 70 54 61 69 6c 20  pB;.      pTail 
7560: 3d 20 70 42 3b 0a 20 20 20 20 20 20 70 42 20 3d  = pB;.      pB =
7570: 20 70 42 2d 3e 70 44 69 72 74 79 3b 0a 20 20 20   pB->pDirty;.   
7580: 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20 70 41 20   }.  }.  if( pA 
7590: 29 7b 0a 20 20 20 20 70 54 61 69 6c 2d 3e 70 44  ){.    pTail->pD
75a0: 69 72 74 79 20 3d 20 70 41 3b 0a 20 20 7d 65 6c  irty = pA;.  }el
75b0: 73 65 20 69 66 28 20 70 42 20 29 7b 0a 20 20 20  se if( pB ){.   
75c0: 20 70 54 61 69 6c 2d 3e 70 44 69 72 74 79 20 3d   pTail->pDirty =
75d0: 20 70 42 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20   pB;.  }else{.  
75e0: 20 20 70 54 61 69 6c 2d 3e 70 44 69 72 74 79 20    pTail->pDirty 
75f0: 3d 20 30 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  = 0;.  }.  retur
7600: 6e 20 72 65 73 75 6c 74 2e 70 44 69 72 74 79 3b  n result.pDirty;
7610: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 6f 72 74 20 74  .}../*.** Sort t
7620: 68 65 20 6c 69 73 74 20 6f 66 20 70 61 67 65 73  he list of pages
7630: 20 69 6e 20 61 63 63 65 6e 64 69 6e 67 20 6f 72   in accending or
7640: 64 65 72 20 62 79 20 70 67 6e 6f 2e 20 20 50 61  der by pgno.  Pa
7650: 67 65 73 20 61 72 65 0a 2a 2a 20 63 6f 6e 6e 65  ges are.** conne
7660: 63 74 65 64 20 62 79 20 70 44 69 72 74 79 20 70  cted by pDirty p
7670: 6f 69 6e 74 65 72 73 2e 20 20 54 68 65 20 70 50  ointers.  The pP
7680: 72 65 76 44 69 72 74 79 20 70 6f 69 6e 74 65 72  revDirty pointer
7690: 73 20 61 72 65 0a 2a 2a 20 63 6f 72 72 75 70 74  s are.** corrupt
76a0: 65 64 20 62 79 20 74 68 69 73 20 73 6f 72 74 2e  ed by this sort.
76b0: 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 4e 5f 53 4f  .*/.#define N_SO
76c0: 52 54 5f 42 55 43 4b 45 54 5f 41 4c 4c 4f 43 20  RT_BUCKET_ALLOC 
76d0: 32 35 0a 23 64 65 66 69 6e 65 20 4e 5f 53 4f 52  25.#define N_SOR
76e0: 54 5f 42 55 43 4b 45 54 20 20 20 20 20 20 20 32  T_BUCKET       2
76f0: 35 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f  5.#ifdef SQLITE_
7700: 54 45 53 54 0a 20 20 69 6e 74 20 73 71 6c 69 74  TEST.  int sqlit
7710: 65 33 5f 70 61 67 65 72 5f 6e 5f 73 6f 72 74 5f  e3_pager_n_sort_
7720: 62 75 63 6b 65 74 20 3d 20 30 3b 0a 20 20 23 75  bucket = 0;.  #u
7730: 6e 64 65 66 20 4e 5f 53 4f 52 54 5f 42 55 43 4b  ndef N_SORT_BUCK
7740: 45 54 0a 20 20 23 64 65 66 69 6e 65 20 4e 5f 53  ET.  #define N_S
7750: 4f 52 54 5f 42 55 43 4b 45 54 20 5c 0a 20 20 20  ORT_BUCKET \.   
7760: 28 73 71 6c 69 74 65 33 5f 70 61 67 65 72 5f 6e  (sqlite3_pager_n
7770: 5f 73 6f 72 74 5f 62 75 63 6b 65 74 3f 73 71 6c  _sort_bucket?sql
7780: 69 74 65 33 5f 70 61 67 65 72 5f 6e 5f 73 6f 72  ite3_pager_n_sor
7790: 74 5f 62 75 63 6b 65 74 3a 4e 5f 53 4f 52 54 5f  t_bucket:N_SORT_
77a0: 42 55 43 4b 45 54 5f 41 4c 4c 4f 43 29 0a 23 65  BUCKET_ALLOC).#e
77b0: 6e 64 69 66 0a 73 74 61 74 69 63 20 50 67 48 64  ndif.static PgHd
77c0: 72 20 2a 70 63 61 63 68 65 53 6f 72 74 44 69 72  r *pcacheSortDir
77d0: 74 79 4c 69 73 74 28 50 67 48 64 72 20 2a 70 49  tyList(PgHdr *pI
77e0: 6e 29 7b 0a 20 20 50 67 48 64 72 20 2a 61 5b 4e  n){.  PgHdr *a[N
77f0: 5f 53 4f 52 54 5f 42 55 43 4b 45 54 5f 41 4c 4c  _SORT_BUCKET_ALL
7800: 4f 43 5d 2c 20 2a 70 3b 0a 20 20 69 6e 74 20 69  OC], *p;.  int i
7810: 3b 0a 20 20 6d 65 6d 73 65 74 28 61 2c 20 30 2c  ;.  memset(a, 0,
7820: 20 73 69 7a 65 6f 66 28 61 29 29 3b 0a 20 20 77   sizeof(a));.  w
7830: 68 69 6c 65 28 20 70 49 6e 20 29 7b 0a 20 20 20  hile( pIn ){.   
7840: 20 70 20 3d 20 70 49 6e 3b 0a 20 20 20 20 70 49   p = pIn;.    pI
7850: 6e 20 3d 20 70 2d 3e 70 44 69 72 74 79 3b 0a 20  n = p->pDirty;. 
7860: 20 20 20 70 2d 3e 70 44 69 72 74 79 20 3d 20 30     p->pDirty = 0
7870: 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69  ;.    for(i=0; i
7880: 3c 4e 5f 53 4f 52 54 5f 42 55 43 4b 45 54 2d 31  <N_SORT_BUCKET-1
7890: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 69 66  ; i++){.      if
78a0: 28 20 61 5b 69 5d 3d 3d 30 20 29 7b 0a 20 20 20  ( a[i]==0 ){.   
78b0: 20 20 20 20 20 61 5b 69 5d 20 3d 20 70 3b 0a 20       a[i] = p;. 
78c0: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
78d0: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
78e0: 20 20 20 70 20 3d 20 70 63 61 63 68 65 4d 65 72     p = pcacheMer
78f0: 67 65 44 69 72 74 79 4c 69 73 74 28 61 5b 69 5d  geDirtyList(a[i]
7900: 2c 20 70 29 3b 0a 20 20 20 20 20 20 20 20 61 5b  , p);.        a[
7910: 69 5d 20 3d 20 30 3b 0a 20 20 20 20 20 20 7d 0a  i] = 0;.      }.
7920: 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 69 3d      }.    if( i=
7930: 3d 4e 5f 53 4f 52 54 5f 42 55 43 4b 45 54 2d 31  =N_SORT_BUCKET-1
7940: 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 43 6f 76   ){.      /* Cov
7950: 65 72 61 67 65 3a 20 54 6f 20 67 65 74 20 68 65  erage: To get he
7960: 72 65 2c 20 74 68 65 72 65 20 6e 65 65 64 20 74  re, there need t
7970: 6f 20 62 65 20 32 5e 28 4e 5f 53 4f 52 54 5f 42  o be 2^(N_SORT_B
7980: 55 43 4b 45 54 29 20 0a 20 20 20 20 20 20 2a 2a  UCKET) .      **
7990: 20 65 6c 65 6d 65 6e 74 73 20 69 6e 20 74 68 65   elements in the
79a0: 20 69 6e 70 75 74 20 6c 69 73 74 2e 20 54 68 69   input list. Thi
79b0: 73 20 69 73 20 70 6f 73 73 69 62 6c 65 2c 20 62  s is possible, b
79c0: 75 74 20 69 6d 70 72 61 63 74 69 63 61 6c 2e 0a  ut impractical..
79d0: 20 20 20 20 20 20 2a 2a 20 54 65 73 74 69 6e 67        ** Testing
79e0: 20 74 68 69 73 20 6c 69 6e 65 20 69 73 20 74 68   this line is th
79f0: 65 20 70 6f 69 6e 74 20 6f 66 20 67 6c 6f 62 61  e point of globa
7a00: 6c 20 76 61 72 69 61 62 6c 65 0a 20 20 20 20 20  l variable.     
7a10: 20 2a 2a 20 73 71 6c 69 74 65 33 5f 70 61 67 65   ** sqlite3_page
7a20: 72 5f 6e 5f 73 6f 72 74 5f 62 75 63 6b 65 74 2e  r_n_sort_bucket.
7a30: 0a 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 20  .      */.      
7a40: 61 5b 69 5d 20 3d 20 70 63 61 63 68 65 4d 65 72  a[i] = pcacheMer
7a50: 67 65 44 69 72 74 79 4c 69 73 74 28 61 5b 69 5d  geDirtyList(a[i]
7a60: 2c 20 70 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  , p);.    }.  }.
7a70: 20 20 70 20 3d 20 61 5b 30 5d 3b 0a 20 20 66 6f    p = a[0];.  fo
7a80: 72 28 69 3d 31 3b 20 69 3c 4e 5f 53 4f 52 54 5f  r(i=1; i<N_SORT_
7a90: 42 55 43 4b 45 54 3b 20 69 2b 2b 29 7b 0a 20 20  BUCKET; i++){.  
7aa0: 20 20 70 20 3d 20 70 63 61 63 68 65 4d 65 72 67    p = pcacheMerg
7ab0: 65 44 69 72 74 79 4c 69 73 74 28 70 2c 20 61 5b  eDirtyList(p, a[
7ac0: 69 5d 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  i]);.  }.  retur
7ad0: 6e 20 70 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65  n p;.}../*.** Re
7ae0: 74 75 72 6e 20 61 20 6c 69 73 74 20 6f 66 20 61  turn a list of a
7af0: 6c 6c 20 64 69 72 74 79 20 70 61 67 65 73 20 69  ll dirty pages i
7b00: 6e 20 74 68 65 20 63 61 63 68 65 2c 20 73 6f 72  n the cache, sor
7b10: 74 65 64 20 62 79 20 70 61 67 65 20 6e 75 6d 62  ted by page numb
7b20: 65 72 2e 0a 2a 2f 0a 50 67 48 64 72 20 2a 73 71  er..*/.PgHdr *sq
7b30: 6c 69 74 65 33 50 63 61 63 68 65 44 69 72 74 79  lite3PcacheDirty
7b40: 4c 69 73 74 28 50 43 61 63 68 65 20 2a 70 43 61  List(PCache *pCa
7b50: 63 68 65 29 7b 0a 20 20 50 67 48 64 72 20 2a 70  che){.  PgHdr *p
7b60: 3b 0a 20 20 66 6f 72 28 70 3d 70 43 61 63 68 65  ;.  for(p=pCache
7b70: 2d 3e 70 44 69 72 74 79 3b 20 70 3b 20 70 3d 70  ->pDirty; p; p=p
7b80: 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 70 2d  ->pNext){.    p-
7b90: 3e 70 44 69 72 74 79 20 3d 20 70 2d 3e 70 4e 65  >pDirty = p->pNe
7ba0: 78 74 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  xt;.  }.  return
7bb0: 20 70 63 61 63 68 65 53 6f 72 74 44 69 72 74 79   pcacheSortDirty
7bc0: 4c 69 73 74 28 70 43 61 63 68 65 2d 3e 70 44 69  List(pCache->pDi
7bd0: 72 74 79 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20  rty);.}../* .** 
7be0: 52 65 74 75 72 6e 20 74 68 65 20 74 6f 74 61 6c  Return the total
7bf0: 20 6e 75 6d 62 65 72 20 6f 66 20 6f 75 74 73 74   number of outst
7c00: 61 6e 64 69 6e 67 20 70 61 67 65 20 72 65 66 65  anding page refe
7c10: 72 65 6e 63 65 73 2e 0a 2a 2f 0a 69 6e 74 20 73  rences..*/.int s
7c20: 71 6c 69 74 65 33 50 63 61 63 68 65 52 65 66 43  qlite3PcacheRefC
7c30: 6f 75 6e 74 28 50 43 61 63 68 65 20 2a 70 43 61  ount(PCache *pCa
7c40: 63 68 65 29 7b 0a 20 20 72 65 74 75 72 6e 20 70  che){.  return p
7c50: 43 61 63 68 65 2d 3e 6e 52 65 66 3b 0a 7d 0a 0a  Cache->nRef;.}..
7c60: 2f 2a 20 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68  /* .** Return th
7c70: 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f  e total number o
7c80: 66 20 70 61 67 65 73 20 69 6e 20 74 68 65 20 63  f pages in the c
7c90: 61 63 68 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c  ache..*/.int sql
7ca0: 69 74 65 33 50 63 61 63 68 65 50 61 67 65 63 6f  ite3PcachePageco
7cb0: 75 6e 74 28 50 43 61 63 68 65 20 2a 70 43 61 63  unt(PCache *pCac
7cc0: 68 65 29 7b 0a 20 20 61 73 73 65 72 74 28 20 70  he){.  assert( p
7cd0: 43 61 63 68 65 2d 3e 6e 50 61 67 65 3e 3d 30 20  Cache->nPage>=0 
7ce0: 29 3b 0a 20 20 72 65 74 75 72 6e 20 70 43 61 63  );.  return pCac
7cf0: 68 65 2d 3e 6e 50 61 67 65 3b 0a 7d 0a 0a 23 69  he->nPage;.}..#i
7d00: 66 64 65 66 20 53 51 4c 49 54 45 5f 43 48 45 43  fdef SQLITE_CHEC
7d10: 4b 5f 50 41 47 45 53 0a 2f 2a 0a 2a 2a 20 54 68  K_PAGES./*.** Th
7d20: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 75  is function is u
7d30: 73 65 64 20 62 79 20 74 68 65 20 70 61 67 65 72  sed by the pager
7d40: 2e 63 20 6d 6f 64 75 6c 65 20 74 6f 20 69 74 65  .c module to ite
7d50: 72 61 74 65 20 74 68 72 6f 75 67 68 20 61 6c 6c  rate through all
7d60: 20 0a 2a 2a 20 70 61 67 65 73 20 69 6e 20 74 68   .** pages in th
7d70: 65 20 63 61 63 68 65 2e 20 41 74 20 70 72 65 73  e cache. At pres
7d80: 65 6e 74 2c 20 74 68 69 73 20 69 73 20 6f 6e 6c  ent, this is onl
7d90: 79 20 72 65 71 75 69 72 65 64 20 69 66 20 74 68  y required if th
7da0: 65 0a 2a 2a 20 53 51 4c 49 54 45 5f 43 48 45 43  e.** SQLITE_CHEC
7db0: 4b 5f 50 41 47 45 53 20 6d 61 63 72 6f 20 28 75  K_PAGES macro (u
7dc0: 73 65 64 20 66 6f 72 20 64 65 62 75 67 67 69 6e  sed for debuggin
7dd0: 67 29 20 69 73 20 73 70 65 63 69 66 69 65 64 2e  g) is specified.
7de0: 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33  .*/.void sqlite3
7df0: 50 63 61 63 68 65 49 74 65 72 61 74 65 28 50 43  PcacheIterate(PC
7e00: 61 63 68 65 20 2a 70 43 61 63 68 65 2c 20 76 6f  ache *pCache, vo
7e10: 69 64 20 28 2a 78 49 74 65 72 29 28 50 67 48 64  id (*xIter)(PgHd
7e20: 72 20 2a 29 29 7b 0a 20 20 50 67 48 64 72 20 2a  r *)){.  PgHdr *
7e30: 70 3b 0a 20 20 66 6f 72 28 70 3d 70 43 61 63 68  p;.  for(p=pCach
7e40: 65 2d 3e 70 43 6c 65 61 6e 3b 20 70 3b 20 70 3d  e->pClean; p; p=
7e50: 70 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 78  p->pNext){.    x
7e60: 49 74 65 72 28 70 29 3b 0a 20 20 7d 0a 20 20 66  Iter(p);.  }.  f
7e70: 6f 72 28 70 3d 70 43 61 63 68 65 2d 3e 70 44 69  or(p=pCache->pDi
7e80: 72 74 79 3b 20 70 3b 20 70 3d 70 2d 3e 70 4e 65  rty; p; p=p->pNe
7e90: 78 74 29 7b 0a 20 20 20 20 78 49 74 65 72 28 70  xt){.    xIter(p
7ea0: 29 3b 0a 20 20 7d 0a 7d 0a 23 65 6e 64 69 66 0a  );.  }.}.#endif.
7eb0: 0a 2f 2a 20 0a 2a 2a 20 53 65 74 20 66 6c 61 67  ./* .** Set flag
7ec0: 73 20 6f 6e 20 61 6c 6c 20 70 61 67 65 73 20 69  s on all pages i
7ed0: 6e 20 74 68 65 20 70 61 67 65 20 63 61 63 68 65  n the page cache
7ee0: 20 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65   .*/.void sqlite
7ef0: 33 50 63 61 63 68 65 53 65 74 46 6c 61 67 73 28  3PcacheSetFlags(
7f00: 50 43 61 63 68 65 20 2a 70 43 61 63 68 65 2c 20  PCache *pCache, 
7f10: 69 6e 74 20 61 6e 64 4d 61 73 6b 2c 20 69 6e 74  int andMask, int
7f20: 20 6f 72 4d 61 73 6b 29 7b 0a 20 20 50 67 48 64   orMask){.  PgHd
7f30: 72 20 2a 70 3b 0a 0a 20 20 61 73 73 65 72 74 28  r *p;..  assert(
7f40: 20 28 6f 72 4d 61 73 6b 26 50 47 48 44 52 5f 4e   (orMask&PGHDR_N
7f50: 45 45 44 5f 53 59 4e 43 29 3d 3d 30 20 29 3b 0a  EED_SYNC)==0 );.
7f60: 0a 20 20 2f 2a 20 4f 62 74 61 69 6e 20 74 68 65  .  /* Obtain the
7f70: 20 67 6c 6f 62 61 6c 20 6d 75 74 65 78 20 62 65   global mutex be
7f80: 66 6f 72 65 20 6d 6f 64 69 66 79 69 6e 67 20 61  fore modifying a
7f90: 6e 79 20 50 67 48 64 72 2e 66 6c 61 67 73 20 76  ny PgHdr.flags v
7fa0: 61 72 69 61 62 6c 65 73 20 0a 20 20 2a 2a 20 6f  ariables .  ** o
7fb0: 72 20 74 72 61 76 65 72 73 69 6e 67 20 74 68 65  r traversing the
7fc0: 20 4c 52 55 20 6c 69 73 74 2e 0a 20 20 2a 2f 20   LRU list..  */ 
7fd0: 0a 20 20 70 63 61 63 68 65 45 6e 74 65 72 4d 75  .  pcacheEnterMu
7fe0: 74 65 78 28 29 3b 0a 0a 20 20 66 6f 72 28 70 3d  tex();..  for(p=
7ff0: 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 3b 20  pCache->pDirty; 
8000: 70 3b 20 70 3d 70 2d 3e 70 4e 65 78 74 29 7b 0a  p; p=p->pNext){.
8010: 20 20 20 20 70 2d 3e 66 6c 61 67 73 20 3d 20 28      p->flags = (
8020: 70 2d 3e 66 6c 61 67 73 26 61 6e 64 4d 61 73 6b  p->flags&andMask
8030: 29 7c 6f 72 4d 61 73 6b 3b 0a 20 20 7d 0a 20 20  )|orMask;.  }.  
8040: 66 6f 72 28 70 3d 70 43 61 63 68 65 2d 3e 70 43  for(p=pCache->pC
8050: 6c 65 61 6e 3b 20 70 3b 20 70 3d 70 2d 3e 70 4e  lean; p; p=p->pN
8060: 65 78 74 29 7b 0a 20 20 20 20 70 2d 3e 66 6c 61  ext){.    p->fla
8070: 67 73 20 3d 20 28 70 2d 3e 66 6c 61 67 73 26 61  gs = (p->flags&a
8080: 6e 64 4d 61 73 6b 29 7c 6f 72 4d 61 73 6b 3b 0a  ndMask)|orMask;.
8090: 20 20 7d 0a 0a 20 20 69 66 28 20 30 3d 3d 28 61    }..  if( 0==(a
80a0: 6e 64 4d 61 73 6b 26 50 47 48 44 52 5f 4e 45 45  ndMask&PGHDR_NEE
80b0: 44 5f 53 59 4e 43 29 20 29 7b 0a 20 20 20 20 70  D_SYNC) ){.    p
80c0: 43 61 63 68 65 2d 3e 70 53 79 6e 63 65 64 20 3d  Cache->pSynced =
80d0: 20 70 43 61 63 68 65 2d 3e 70 44 69 72 74 79 54   pCache->pDirtyT
80e0: 61 69 6c 3b 0a 20 20 20 20 61 73 73 65 72 74 28  ail;.    assert(
80f0: 20 21 70 43 61 63 68 65 2d 3e 70 53 79 6e 63 65   !pCache->pSynce
8100: 64 20 7c 7c 20 28 70 43 61 63 68 65 2d 3e 70 53  d || (pCache->pS
8110: 79 6e 63 65 64 2d 3e 66 6c 61 67 73 26 50 47 48  ynced->flags&PGH
8120: 44 52 5f 4e 45 45 44 5f 53 59 4e 43 29 3d 3d 30  DR_NEED_SYNC)==0
8130: 20 29 3b 0a 20 20 7d 0a 0a 20 20 70 63 61 63 68   );.  }..  pcach
8140: 65 45 78 69 74 4d 75 74 65 78 28 29 3b 0a 7d 0a  eExitMutex();.}.
8150: 0a 2f 2a 0a 2a 2a 20 53 65 74 20 74 68 65 20 73  ./*.** Set the s
8160: 75 67 67 65 73 74 65 64 20 63 61 63 68 65 2d 73  uggested cache-s
8170: 69 7a 65 20 76 61 6c 75 65 2e 0a 2a 2f 0a 69 6e  ize value..*/.in
8180: 74 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 47  t sqlite3PcacheG
8190: 65 74 43 61 63 68 65 73 69 7a 65 28 50 43 61 63  etCachesize(PCac
81a0: 68 65 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 72  he *pCache){.  r
81b0: 65 74 75 72 6e 20 70 43 61 63 68 65 2d 3e 6e 4d  eturn pCache->nM
81c0: 61 78 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 74  ax;.}../*.** Set
81d0: 20 74 68 65 20 73 75 67 67 65 73 74 65 64 20 63   the suggested c
81e0: 61 63 68 65 2d 73 69 7a 65 20 76 61 6c 75 65 2e  ache-size value.
81f0: 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33  .*/.void sqlite3
8200: 50 63 61 63 68 65 53 65 74 43 61 63 68 65 73 69  PcacheSetCachesi
8210: 7a 65 28 50 43 61 63 68 65 20 2a 70 43 61 63 68  ze(PCache *pCach
8220: 65 2c 20 69 6e 74 20 6d 78 50 61 67 65 29 7b 0a  e, int mxPage){.
8230: 20 20 69 66 28 20 6d 78 50 61 67 65 3c 31 30 20    if( mxPage<10 
8240: 29 7b 0a 20 20 20 20 6d 78 50 61 67 65 20 3d 20  ){.    mxPage = 
8250: 31 30 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 43  10;.  }.  if( pC
8260: 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65  ache->bPurgeable
8270: 20 29 7b 0a 20 20 20 20 70 63 61 63 68 65 45 6e   ){.    pcacheEn
8280: 74 65 72 4d 75 74 65 78 28 29 3b 0a 20 20 20 20  terMutex();.    
8290: 70 63 61 63 68 65 2e 6e 4d 61 78 50 61 67 65 20  pcache.nMaxPage 
82a0: 2d 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 3b  -= pCache->nMax;
82b0: 0a 20 20 20 20 70 63 61 63 68 65 2e 6e 4d 61 78  .    pcache.nMax
82c0: 50 61 67 65 20 2b 3d 20 6d 78 50 61 67 65 3b 0a  Page += mxPage;.
82d0: 20 20 20 20 70 63 61 63 68 65 45 78 69 74 4d 75      pcacheExitMu
82e0: 74 65 78 28 29 3b 0a 20 20 7d 0a 20 20 70 43 61  tex();.  }.  pCa
82f0: 63 68 65 2d 3e 6e 4d 61 78 20 3d 20 6d 78 50 61  che->nMax = mxPa
8300: 67 65 3b 0a 7d 0a 0a 23 69 66 64 65 66 20 53 51  ge;.}..#ifdef SQ
8310: 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f  LITE_ENABLE_MEMO
8320: 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 0a 2f 2a  RY_MANAGEMENT./*
8330: 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
8340: 6e 20 69 73 20 63 61 6c 6c 65 64 20 74 6f 20 66  n is called to f
8350: 72 65 65 20 73 75 70 65 72 66 6c 75 6f 75 73 20  ree superfluous 
8360: 64 79 6e 61 6d 69 63 61 6c 6c 79 20 61 6c 6c 6f  dynamically allo
8370: 63 61 74 65 64 20 6d 65 6d 6f 72 79 0a 2a 2a 20  cated memory.** 
8380: 68 65 6c 64 20 62 79 20 74 68 65 20 70 61 67 65  held by the page
8390: 72 20 73 79 73 74 65 6d 2e 20 4d 65 6d 6f 72 79  r system. Memory
83a0: 20 69 6e 20 75 73 65 20 62 79 20 61 6e 79 20 53   in use by any S
83b0: 51 4c 69 74 65 20 70 61 67 65 72 20 61 6c 6c 6f  QLite pager allo
83c0: 63 61 74 65 64 0a 2a 2a 20 62 79 20 74 68 65 20  cated.** by the 
83d0: 63 75 72 72 65 6e 74 20 74 68 72 65 61 64 20 6d  current thread m
83e0: 61 79 20 62 65 20 73 71 6c 69 74 65 33 5f 66 72  ay be sqlite3_fr
83f0: 65 65 28 29 65 64 2e 0a 2a 2a 0a 2a 2a 20 6e 52  ee()ed..**.** nR
8400: 65 71 20 69 73 20 74 68 65 20 6e 75 6d 62 65 72  eq is the number
8410: 20 6f 66 20 62 79 74 65 73 20 6f 66 20 6d 65 6d   of bytes of mem
8420: 6f 72 79 20 72 65 71 75 69 72 65 64 2e 20 4f 6e  ory required. On
8430: 63 65 20 74 68 69 73 20 6d 75 63 68 20 68 61 73  ce this much has
8440: 0a 2a 2a 20 62 65 65 6e 20 72 65 6c 65 61 73 65  .** been release
8450: 64 2c 20 74 68 65 20 66 75 6e 63 74 69 6f 6e 20  d, the function 
8460: 72 65 74 75 72 6e 73 2e 20 54 68 65 20 72 65 74  returns. The ret
8470: 75 72 6e 20 76 61 6c 75 65 20 69 73 20 74 68 65  urn value is the
8480: 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 0a 2a   total number .*
8490: 2a 20 6f 66 20 62 79 74 65 73 20 6f 66 20 6d 65  * of bytes of me
84a0: 6d 6f 72 79 20 72 65 6c 65 61 73 65 64 2e 0a 2a  mory released..*
84b0: 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 50 63 61  /.int sqlite3Pca
84c0: 63 68 65 52 65 6c 65 61 73 65 4d 65 6d 6f 72 79  cheReleaseMemory
84d0: 28 69 6e 74 20 6e 52 65 71 29 7b 0a 20 20 69 6e  (int nReq){.  in
84e0: 74 20 6e 46 72 65 65 20 3d 20 30 3b 0a 20 20 69  t nFree = 0;.  i
84f0: 66 28 20 70 63 61 63 68 65 2e 70 53 74 61 72 74  f( pcache.pStart
8500: 3d 3d 30 20 29 7b 0a 20 20 20 20 50 67 48 64 72  ==0 ){.    PgHdr
8510: 20 2a 70 3b 0a 20 20 20 20 70 63 61 63 68 65 45   *p;.    pcacheE
8520: 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a 20 20 20  nterMutex();.   
8530: 20 77 68 69 6c 65 28 20 28 6e 52 65 71 3c 30 20   while( (nReq<0 
8540: 7c 7c 20 6e 46 72 65 65 3c 6e 52 65 71 29 20 26  || nFree<nReq) &
8550: 26 20 28 70 3d 70 63 61 63 68 65 52 65 63 79 63  & (p=pcacheRecyc
8560: 6c 65 50 61 67 65 28 29 29 20 29 7b 0a 20 20 20  lePage()) ){.   
8570: 20 20 20 6e 46 72 65 65 20 2b 3d 20 70 63 61 63     nFree += pcac
8580: 68 65 50 61 67 65 53 69 7a 65 28 70 29 3b 0a 20  hePageSize(p);. 
8590: 20 20 20 20 20 70 63 61 63 68 65 50 61 67 65 46       pcachePageF
85a0: 72 65 65 28 70 29 3b 0a 20 20 20 20 7d 0a 20 20  ree(p);.    }.  
85b0: 20 20 70 63 61 63 68 65 45 78 69 74 4d 75 74 65    pcacheExitMute
85c0: 78 28 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  x();.  }.  retur
85d0: 6e 20 6e 46 72 65 65 3b 0a 7d 0a 23 65 6e 64 69  n nFree;.}.#endi
85e0: 66 20 2f 2a 20 53 51 4c 49 54 45 5f 45 4e 41 42  f /* SQLITE_ENAB
85f0: 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47 45  LE_MEMORY_MANAGE
8600: 4d 45 4e 54 20 2a 2f 0a                          MENT */.