/ Hex Artifact Content
Login

Artifact 3de4feb556a11a62febe172ca98655dff68a0df3:


0000: 2f 2a 0a 2a 2a 20 32 30 30 38 20 4e 6f 76 65 6d  /*.** 2008 Novem
0010: 62 65 72 20 30 35 0a 2a 2a 0a 2a 2a 20 54 68 65  ber 05.**.** The
0020: 20 61 75 74 68 6f 72 20 64 69 73 63 6c 61 69 6d   author disclaim
0030: 73 20 63 6f 70 79 72 69 67 68 74 20 74 6f 20 74  s copyright to t
0040: 68 69 73 20 73 6f 75 72 63 65 20 63 6f 64 65 2e  his source code.
0050: 20 20 49 6e 20 70 6c 61 63 65 20 6f 66 0a 2a 2a    In place of.**
0060: 20 61 20 6c 65 67 61 6c 20 6e 6f 74 69 63 65 2c   a legal notice,
0070: 20 68 65 72 65 20 69 73 20 61 20 62 6c 65 73 73   here is a bless
0080: 69 6e 67 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 4d 61  ing:.**.**    Ma
0090: 79 20 79 6f 75 20 64 6f 20 67 6f 6f 64 20 61 6e  y you do good an
00a0: 64 20 6e 6f 74 20 65 76 69 6c 2e 0a 2a 2a 20 20  d not evil..**  
00b0: 20 20 4d 61 79 20 79 6f 75 20 66 69 6e 64 20 66    May you find f
00c0: 6f 72 67 69 76 65 6e 65 73 73 20 66 6f 72 20 79  orgiveness for y
00d0: 6f 75 72 73 65 6c 66 20 61 6e 64 20 66 6f 72 67  ourself and forg
00e0: 69 76 65 20 6f 74 68 65 72 73 2e 0a 2a 2a 20 20  ive others..**  
00f0: 20 20 4d 61 79 20 79 6f 75 20 73 68 61 72 65 20    May you share 
0100: 66 72 65 65 6c 79 2c 20 6e 65 76 65 72 20 74 61  freely, never ta
0110: 6b 69 6e 67 20 6d 6f 72 65 20 74 68 61 6e 20 79  king more than y
0120: 6f 75 20 67 69 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a  ou 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 2a 2a 0a 2a 2a 0a 2a 2a 20 54 68 69 73  *****.**.** This
0180: 20 66 69 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 73   file implements
0190: 20 74 68 65 20 64 65 66 61 75 6c 74 20 70 61 67   the default pag
01a0: 65 20 63 61 63 68 65 20 69 6d 70 6c 65 6d 65 6e  e cache implemen
01b0: 74 61 74 69 6f 6e 20 28 74 68 65 0a 2a 2a 20 73  tation (the.** s
01c0: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 69 6e  qlite3_pcache in
01d0: 74 65 72 66 61 63 65 29 2e 20 49 74 20 61 6c 73  terface). It als
01e0: 6f 20 63 6f 6e 74 61 69 6e 73 20 70 61 72 74 20  o contains part 
01f0: 6f 66 20 74 68 65 20 69 6d 70 6c 65 6d 65 6e 74  of the implement
0200: 61 74 69 6f 6e 0a 2a 2a 20 6f 66 20 74 68 65 20  ation.** of the 
0210: 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41  SQLITE_CONFIG_PA
0220: 47 45 43 41 43 48 45 20 61 6e 64 20 73 71 6c 69  GECACHE and sqli
0230: 74 65 33 5f 72 65 6c 65 61 73 65 5f 6d 65 6d 6f  te3_release_memo
0240: 72 79 28 29 20 66 65 61 74 75 72 65 73 2e 0a 2a  ry() features..*
0250: 2a 20 49 66 20 74 68 65 20 64 65 66 61 75 6c 74  * If the default
0260: 20 70 61 67 65 20 63 61 63 68 65 20 69 6d 70 6c   page cache impl
0270: 65 6d 65 6e 74 61 74 69 6f 6e 20 69 73 20 6f 76  ementation is ov
0280: 65 72 72 69 64 65 6e 2c 20 74 68 65 6e 20 6e 65  erriden, then ne
0290: 69 74 68 65 72 20 6f 66 0a 2a 2a 20 74 68 65 73  ither of.** thes
02a0: 65 20 74 77 6f 20 66 65 61 74 75 72 65 73 20 61  e two features a
02b0: 72 65 20 61 76 61 69 6c 61 62 6c 65 2e 0a 2a 2a  re available..**
02c0: 0a 2a 2a 20 40 28 23 29 20 24 49 64 3a 20 70 63  .** @(#) $Id: pc
02d0: 61 63 68 65 31 2e 63 2c 76 20 31 2e 31 36 20 32  ache1.c,v 1.16 2
02e0: 30 30 39 2f 30 36 2f 30 33 20 32 31 3a 30 34 3a  009/06/03 21:04:
02f0: 33 36 20 64 72 68 20 45 78 70 20 24 0a 2a 2f 0a  36 drh Exp $.*/.
0300: 0a 23 69 6e 63 6c 75 64 65 20 22 73 71 6c 69 74  .#include "sqlit
0310: 65 49 6e 74 2e 68 22 0a 0a 74 79 70 65 64 65 66  eInt.h"..typedef
0320: 20 73 74 72 75 63 74 20 50 43 61 63 68 65 31 20   struct PCache1 
0330: 50 43 61 63 68 65 31 3b 0a 74 79 70 65 64 65 66  PCache1;.typedef
0340: 20 73 74 72 75 63 74 20 50 67 48 64 72 31 20 50   struct PgHdr1 P
0350: 67 48 64 72 31 3b 0a 74 79 70 65 64 65 66 20 73  gHdr1;.typedef s
0360: 74 72 75 63 74 20 50 67 46 72 65 65 73 6c 6f 74  truct PgFreeslot
0370: 20 50 67 46 72 65 65 73 6c 6f 74 3b 0a 0a 2f 2a   PgFreeslot;../*
0380: 20 50 6f 69 6e 74 65 72 73 20 74 6f 20 73 74 72   Pointers to str
0390: 75 63 74 75 72 65 73 20 6f 66 20 74 68 69 73 20  uctures of this 
03a0: 74 79 70 65 20 61 72 65 20 63 61 73 74 20 61 6e  type are cast an
03b0: 64 20 72 65 74 75 72 6e 65 64 20 61 73 20 0a 2a  d returned as .*
03c0: 2a 20 6f 70 61 71 75 65 20 73 71 6c 69 74 65 33  * opaque sqlite3
03d0: 5f 70 63 61 63 68 65 2a 20 68 61 6e 64 6c 65 73  _pcache* handles
03e0: 0a 2a 2f 0a 73 74 72 75 63 74 20 50 43 61 63 68  .*/.struct PCach
03f0: 65 31 20 7b 0a 20 20 2f 2a 20 43 61 63 68 65 20  e1 {.  /* Cache 
0400: 63 6f 6e 66 69 67 75 72 61 74 69 6f 6e 20 70 61  configuration pa
0410: 72 61 6d 65 74 65 72 73 2e 20 50 61 67 65 20 73  rameters. Page s
0420: 69 7a 65 20 28 73 7a 50 61 67 65 29 20 61 6e 64  ize (szPage) and
0430: 20 74 68 65 20 70 75 72 67 65 61 62 6c 65 0a 20   the purgeable. 
0440: 20 2a 2a 20 66 6c 61 67 20 28 62 50 75 72 67 65   ** flag (bPurge
0450: 61 62 6c 65 29 20 61 72 65 20 73 65 74 20 77 68  able) are set wh
0460: 65 6e 20 74 68 65 20 63 61 63 68 65 20 69 73 20  en the cache is 
0470: 63 72 65 61 74 65 64 2e 20 6e 4d 61 78 20 6d 61  created. nMax ma
0480: 79 20 62 65 20 0a 20 20 2a 2a 20 6d 6f 64 69 66  y be .  ** modif
0490: 69 65 64 20 61 74 20 61 6e 79 20 74 69 6d 65 20  ied at any time 
04a0: 62 79 20 61 20 63 61 6c 6c 20 74 6f 20 74 68 65  by a call to the
04b0: 20 70 63 61 63 68 65 31 43 61 63 68 65 53 69 7a   pcache1CacheSiz
04c0: 65 28 29 20 6d 65 74 68 6f 64 2e 0a 20 20 2a 2a  e() method..  **
04d0: 20 54 68 65 20 67 6c 6f 62 61 6c 20 6d 75 74 65   The global mute
04e0: 78 20 6d 75 73 74 20 62 65 20 68 65 6c 64 20 77  x must be held w
04f0: 68 65 6e 20 61 63 63 65 73 73 69 6e 67 20 6e 4d  hen accessing nM
0500: 61 78 2e 0a 20 20 2a 2f 0a 20 20 69 6e 74 20 73  ax..  */.  int s
0510: 7a 50 61 67 65 3b 20 20 20 20 20 20 20 20 20 20  zPage;          
0520: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0530: 2a 20 53 69 7a 65 20 6f 66 20 61 6c 6c 6f 63 61  * Size of alloca
0540: 74 65 64 20 70 61 67 65 73 20 69 6e 20 62 79 74  ted pages in byt
0550: 65 73 20 2a 2f 0a 20 20 69 6e 74 20 62 50 75 72  es */.  int bPur
0560: 67 65 61 62 6c 65 3b 20 20 20 20 20 20 20 20 20  geable;         
0570: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
0580: 72 75 65 20 69 66 20 63 61 63 68 65 20 69 73 20  rue if cache is 
0590: 70 75 72 67 65 61 62 6c 65 20 2a 2f 0a 20 20 75  purgeable */.  u
05a0: 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 4d 69 6e  nsigned int nMin
05b0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
05c0: 20 20 20 2f 2a 20 4d 69 6e 69 6d 75 6d 20 6e 75     /* Minimum nu
05d0: 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 72 65  mber of pages re
05e0: 73 65 72 76 65 64 20 2a 2f 0a 20 20 75 6e 73 69  served */.  unsi
05f0: 67 6e 65 64 20 69 6e 74 20 6e 4d 61 78 3b 20 20  gned int nMax;  
0600: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0610: 2f 2a 20 43 6f 6e 66 69 67 75 72 65 64 20 22 63  /* Configured "c
0620: 61 63 68 65 5f 73 69 7a 65 22 20 76 61 6c 75 65  ache_size" value
0630: 20 2a 2f 0a 0a 20 20 2f 2a 20 48 61 73 68 20 74   */..  /* Hash t
0640: 61 62 6c 65 20 6f 66 20 61 6c 6c 20 70 61 67 65  able of all page
0650: 73 2e 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  s. The following
0660: 20 76 61 72 69 61 62 6c 65 73 20 6d 61 79 20 6f   variables may o
0670: 6e 6c 79 20 62 65 20 61 63 63 65 73 73 65 64 0a  nly be accessed.
0680: 20 20 2a 2a 20 77 68 65 6e 20 74 68 65 20 61 63    ** when the ac
0690: 63 65 73 73 6f 72 20 69 73 20 68 6f 6c 64 69 6e  cessor is holdin
06a0: 67 20 74 68 65 20 67 6c 6f 62 61 6c 20 6d 75 74  g the global mut
06b0: 65 78 20 28 73 65 65 20 70 63 61 63 68 65 31 45  ex (see pcache1E
06c0: 6e 74 65 72 4d 75 74 65 78 28 29 20 0a 20 20 2a  nterMutex() .  *
06d0: 2a 20 61 6e 64 20 70 63 61 63 68 65 31 4c 65 61  * and pcache1Lea
06e0: 76 65 4d 75 74 65 78 28 29 29 2e 0a 20 20 2a 2f  veMutex())..  */
06f0: 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  .  unsigned int 
0700: 6e 52 65 63 79 63 6c 61 62 6c 65 3b 20 20 20 20  nRecyclable;    
0710: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
0720: 20 6f 66 20 70 61 67 65 73 20 69 6e 20 74 68 65   of pages in the
0730: 20 4c 52 55 20 6c 69 73 74 20 2a 2f 0a 20 20 75   LRU list */.  u
0740: 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 50 61 67  nsigned int nPag
0750: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
0760: 20 20 20 2f 2a 20 54 6f 74 61 6c 20 6e 75 6d 62     /* Total numb
0770: 65 72 20 6f 66 20 70 61 67 65 73 20 69 6e 20 61  er of pages in a
0780: 70 48 61 73 68 20 2a 2f 0a 20 20 75 6e 73 69 67  pHash */.  unsig
0790: 6e 65 64 20 69 6e 74 20 6e 48 61 73 68 3b 20 20  ned int nHash;  
07a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
07b0: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 73 6c 6f 74  * Number of slot
07c0: 73 20 69 6e 20 61 70 48 61 73 68 5b 5d 20 2a 2f  s in apHash[] */
07d0: 0a 20 20 50 67 48 64 72 31 20 2a 2a 61 70 48 61  .  PgHdr1 **apHa
07e0: 73 68 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  sh;             
07f0: 20 20 20 20 20 20 20 2f 2a 20 48 61 73 68 20 74         /* Hash t
0800: 61 62 6c 65 20 66 6f 72 20 66 61 73 74 20 6c 6f  able for fast lo
0810: 6f 6b 75 70 20 62 79 20 6b 65 79 20 2a 2f 0a 0a  okup by key */..
0820: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69    unsigned int i
0830: 4d 61 78 4b 65 79 3b 20 20 20 20 20 20 20 20 20  MaxKey;         
0840: 20 20 20 20 20 20 2f 2a 20 4c 61 72 67 65 73 74        /* Largest
0850: 20 6b 65 79 20 73 65 65 6e 20 73 69 6e 63 65 20   key seen since 
0860: 78 54 72 75 6e 63 61 74 65 28 29 20 2a 2f 0a 7d  xTruncate() */.}
0870: 3b 0a 0a 2f 2a 0a 2a 2a 20 45 61 63 68 20 63 61  ;../*.** Each ca
0880: 63 68 65 20 65 6e 74 72 79 20 69 73 20 72 65 70  che entry is rep
0890: 72 65 73 65 6e 74 65 64 20 62 79 20 61 6e 20 69  resented by an i
08a0: 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 65 20 66  nstance of the f
08b0: 6f 6c 6c 6f 77 69 6e 67 20 0a 2a 2a 20 73 74 72  ollowing .** str
08c0: 75 63 74 75 72 65 2e 20 41 20 62 75 66 66 65 72  ucture. A buffer
08d0: 20 6f 66 20 50 67 48 64 72 31 2e 70 43 61 63 68   of PgHdr1.pCach
08e0: 65 2d 3e 73 7a 50 61 67 65 20 62 79 74 65 73 20  e->szPage bytes 
08f0: 69 73 20 61 6c 6c 6f 63 61 74 65 64 20 0a 2a 2a  is allocated .**
0900: 20 64 69 72 65 63 74 6c 79 20 62 65 66 6f 72 65   directly before
0910: 20 74 68 69 73 20 73 74 72 75 63 74 75 72 65 20   this structure 
0920: 69 6e 20 6d 65 6d 6f 72 79 20 28 73 65 65 20 74  in memory (see t
0930: 68 65 20 50 47 48 44 52 31 5f 54 4f 5f 50 41 47  he PGHDR1_TO_PAG
0940: 45 28 29 20 0a 2a 2a 20 6d 61 63 72 6f 20 62 65  E() .** macro be
0950: 6c 6f 77 29 2e 0a 2a 2f 0a 73 74 72 75 63 74 20  low)..*/.struct 
0960: 50 67 48 64 72 31 20 7b 0a 20 20 75 6e 73 69 67  PgHdr1 {.  unsig
0970: 6e 65 64 20 69 6e 74 20 69 4b 65 79 3b 20 20 20  ned int iKey;   
0980: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4b 65 79            /* Key
0990: 20 76 61 6c 75 65 20 28 70 61 67 65 20 6e 75 6d   value (page num
09a0: 62 65 72 29 20 2a 2f 0a 20 20 50 67 48 64 72 31  ber) */.  PgHdr1
09b0: 20 2a 70 4e 65 78 74 3b 20 20 20 20 20 20 20 20   *pNext;        
09c0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74           /* Next
09d0: 20 69 6e 20 68 61 73 68 20 74 61 62 6c 65 20 63   in hash table c
09e0: 68 61 69 6e 20 2a 2f 0a 20 20 50 43 61 63 68 65  hain */.  PCache
09f0: 31 20 2a 70 43 61 63 68 65 3b 20 20 20 20 20 20  1 *pCache;      
0a00: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 61 63 68           /* Cach
0a10: 65 20 74 68 61 74 20 63 75 72 72 65 6e 74 6c 79  e that currently
0a20: 20 6f 77 6e 73 20 74 68 69 73 20 70 61 67 65 20   owns this page 
0a30: 2a 2f 0a 20 20 50 67 48 64 72 31 20 2a 70 4c 72  */.  PgHdr1 *pLr
0a40: 75 4e 65 78 74 3b 20 20 20 20 20 20 20 20 20 20  uNext;          
0a50: 20 20 20 20 2f 2a 20 4e 65 78 74 20 69 6e 20 4c      /* Next in L
0a60: 52 55 20 6c 69 73 74 20 6f 66 20 75 6e 70 69 6e  RU list of unpin
0a70: 6e 65 64 20 70 61 67 65 73 20 2a 2f 0a 20 20 50  ned pages */.  P
0a80: 67 48 64 72 31 20 2a 70 4c 72 75 50 72 65 76 3b  gHdr1 *pLruPrev;
0a90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0aa0: 20 50 72 65 76 69 6f 75 73 20 69 6e 20 4c 52 55   Previous in LRU
0ab0: 20 6c 69 73 74 20 6f 66 20 75 6e 70 69 6e 6e 65   list of unpinne
0ac0: 64 20 70 61 67 65 73 20 2a 2f 0a 7d 3b 0a 0a 2f  d pages */.};../
0ad0: 2a 0a 2a 2a 20 46 72 65 65 20 73 6c 6f 74 73 20  *.** Free slots 
0ae0: 69 6e 20 74 68 65 20 61 6c 6c 6f 63 61 74 6f 72  in the allocator
0af0: 20 75 73 65 64 20 74 6f 20 64 69 76 69 64 65 20   used to divide 
0b00: 75 70 20 74 68 65 20 62 75 66 66 65 72 20 70 72  up the buffer pr
0b10: 6f 76 69 64 65 64 20 75 73 69 6e 67 0a 2a 2a 20  ovided using.** 
0b20: 74 68 65 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49  the SQLITE_CONFI
0b30: 47 5f 50 41 47 45 43 41 43 48 45 20 6d 65 63 68  G_PAGECACHE mech
0b40: 61 6e 69 73 6d 2e 0a 2a 2f 0a 73 74 72 75 63 74  anism..*/.struct
0b50: 20 50 67 46 72 65 65 73 6c 6f 74 20 7b 0a 20 20   PgFreeslot {.  
0b60: 50 67 46 72 65 65 73 6c 6f 74 20 2a 70 4e 65 78  PgFreeslot *pNex
0b70: 74 3b 20 20 2f 2a 20 4e 65 78 74 20 66 72 65 65  t;  /* Next free
0b80: 20 73 6c 6f 74 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a   slot */.};../*.
0b90: 2a 2a 20 47 6c 6f 62 61 6c 20 64 61 74 61 20 75  ** Global data u
0ba0: 73 65 64 20 62 79 20 74 68 69 73 20 63 61 63 68  sed by this cach
0bb0: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 53 51 4c  e..*/.static SQL
0bc0: 49 54 45 5f 57 53 44 20 73 74 72 75 63 74 20 50  ITE_WSD struct P
0bd0: 43 61 63 68 65 47 6c 6f 62 61 6c 20 7b 0a 20 20  CacheGlobal {.  
0be0: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 20 2a 6d  sqlite3_mutex *m
0bf0: 75 74 65 78 3b 20 20 20 20 20 20 20 20 20 20 20  utex;           
0c00: 20 20 20 20 2f 2a 20 73 74 61 74 69 63 20 6d 75      /* static mu
0c10: 74 65 78 20 4d 55 54 45 58 5f 53 54 41 54 49 43  tex MUTEX_STATIC
0c20: 5f 4c 52 55 20 2a 2f 0a 0a 20 20 69 6e 74 20 6e  _LRU */..  int n
0c30: 4d 61 78 50 61 67 65 3b 20 20 20 20 20 20 20 20  MaxPage;        
0c40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0c50: 2a 20 53 75 6d 20 6f 66 20 6e 4d 61 78 50 61 67  * Sum of nMaxPag
0c60: 65 20 66 6f 72 20 70 75 72 67 65 61 62 6c 65 20  e for purgeable 
0c70: 63 61 63 68 65 73 20 2a 2f 0a 20 20 69 6e 74 20  caches */.  int 
0c80: 6e 4d 69 6e 50 61 67 65 3b 20 20 20 20 20 20 20  nMinPage;       
0c90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ca0: 2f 2a 20 53 75 6d 20 6f 66 20 6e 4d 69 6e 50 61  /* Sum of nMinPa
0cb0: 67 65 20 66 6f 72 20 70 75 72 67 65 61 62 6c 65  ge for purgeable
0cc0: 20 63 61 63 68 65 73 20 2a 2f 0a 20 20 69 6e 74   caches */.  int
0cd0: 20 6e 43 75 72 72 65 6e 74 50 61 67 65 3b 20 20   nCurrentPage;  
0ce0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0cf0: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 70 75   /* Number of pu
0d00: 72 67 65 61 62 6c 65 20 70 61 67 65 73 20 61 6c  rgeable pages al
0d10: 6c 6f 63 61 74 65 64 20 2a 2f 0a 20 20 50 67 48  located */.  PgH
0d20: 64 72 31 20 2a 70 4c 72 75 48 65 61 64 2c 20 2a  dr1 *pLruHead, *
0d30: 70 4c 72 75 54 61 69 6c 3b 20 20 20 20 20 20 20  pLruTail;       
0d40: 20 2f 2a 20 4c 52 55 20 6c 69 73 74 20 6f 66 20   /* LRU list of 
0d50: 75 6e 70 69 6e 6e 65 64 20 70 61 67 65 73 20 2a  unpinned pages *
0d60: 2f 0a 0a 20 20 2f 2a 20 56 61 72 69 61 62 6c 65  /..  /* Variable
0d70: 73 20 72 65 6c 61 74 65 64 20 74 6f 20 53 51 4c  s related to SQL
0d80: 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43  ITE_CONFIG_PAGEC
0d90: 41 43 48 45 20 73 65 74 74 69 6e 67 73 2e 20 2a  ACHE settings. *
0da0: 2f 0a 20 20 69 6e 74 20 73 7a 53 6c 6f 74 3b 20  /.  int szSlot; 
0db0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0dc0: 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
0dd0: 6f 66 20 65 61 63 68 20 66 72 65 65 20 73 6c 6f  of each free slo
0de0: 74 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 53 74  t */.  void *pSt
0df0: 61 72 74 2c 20 2a 70 45 6e 64 3b 20 20 20 20 20  art, *pEnd;     
0e00: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 6f             /* Bo
0e10: 75 6e 64 73 20 6f 66 20 70 61 67 65 63 61 63 68  unds of pagecach
0e20: 65 20 6d 61 6c 6c 6f 63 20 72 61 6e 67 65 20 2a  e malloc range *
0e30: 2f 0a 20 20 50 67 46 72 65 65 73 6c 6f 74 20 2a  /.  PgFreeslot *
0e40: 70 46 72 65 65 3b 20 20 20 20 20 20 20 20 20 20  pFree;          
0e50: 20 20 20 20 20 20 20 20 2f 2a 20 46 72 65 65 20          /* Free 
0e60: 70 61 67 65 20 62 6c 6f 63 6b 73 20 2a 2f 0a 20  page blocks */. 
0e70: 20 69 6e 74 20 69 73 49 6e 69 74 3b 20 20 20 20   int isInit;    
0e80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e90: 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20       /* True if 
0ea0: 69 6e 69 74 69 61 6c 69 7a 65 64 20 2a 2f 0a 7d  initialized */.}
0eb0: 20 70 63 61 63 68 65 31 5f 67 3b 0a 0a 2f 2a 0a   pcache1_g;../*.
0ec0: 2a 2a 20 41 6c 6c 20 63 6f 64 65 20 69 6e 20 74  ** All code in t
0ed0: 68 69 73 20 66 69 6c 65 20 73 68 6f 75 6c 64 20  his file should 
0ee0: 61 63 63 65 73 73 20 74 68 65 20 67 6c 6f 62 61  access the globa
0ef0: 6c 20 73 74 72 75 63 74 75 72 65 20 61 62 6f 76  l structure abov
0f00: 65 20 76 69 61 20 74 68 65 0a 2a 2a 20 61 6c 69  e via the.** ali
0f10: 61 73 20 22 70 63 61 63 68 65 31 22 2e 20 54 68  as "pcache1". Th
0f20: 69 73 20 65 6e 73 75 72 65 73 20 74 68 61 74 20  is ensures that 
0f30: 74 68 65 20 57 53 44 20 65 6d 75 6c 61 74 69 6f  the WSD emulatio
0f40: 6e 20 69 73 20 75 73 65 64 20 77 68 65 6e 0a 2a  n is used when.*
0f50: 2a 20 63 6f 6d 70 69 6c 69 6e 67 20 66 6f 72 20  * compiling for 
0f60: 73 79 73 74 65 6d 73 20 74 68 61 74 20 64 6f 20  systems that do 
0f70: 6e 6f 74 20 73 75 70 70 6f 72 74 20 72 65 61 6c  not support real
0f80: 20 57 53 44 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65   WSD..*/.#define
0f90: 20 70 63 61 63 68 65 31 20 28 47 4c 4f 42 41 4c   pcache1 (GLOBAL
0fa0: 28 73 74 72 75 63 74 20 50 43 61 63 68 65 47 6c  (struct PCacheGl
0fb0: 6f 62 61 6c 2c 20 70 63 61 63 68 65 31 5f 67 29  obal, pcache1_g)
0fc0: 29 0a 0a 2f 2a 0a 2a 2a 20 57 68 65 6e 20 61 20  )../*.** When a 
0fd0: 50 67 48 64 72 31 20 73 74 72 75 63 74 75 72 65  PgHdr1 structure
0fe0: 20 69 73 20 61 6c 6c 6f 63 61 74 65 64 2c 20 74   is allocated, t
0ff0: 68 65 20 61 73 73 6f 63 69 61 74 65 64 20 50 43  he associated PC
1000: 61 63 68 65 31 2e 73 7a 50 61 67 65 0a 2a 2a 20  ache1.szPage.** 
1010: 62 79 74 65 73 20 6f 66 20 64 61 74 61 20 61 72  bytes of data ar
1020: 65 20 6c 6f 63 61 74 65 64 20 64 69 72 65 63 74  e located direct
1030: 6c 79 20 62 65 66 6f 72 65 20 69 74 20 69 6e 20  ly before it in 
1040: 6d 65 6d 6f 72 79 20 28 69 2e 65 2e 20 74 68 65  memory (i.e. the
1050: 20 74 6f 74 61 6c 0a 2a 2a 20 73 69 7a 65 20 6f   total.** size o
1060: 66 20 74 68 65 20 61 6c 6c 6f 63 61 74 69 6f 6e  f the allocation
1070: 20 69 73 20 73 69 7a 65 6f 66 28 50 67 48 64 72   is sizeof(PgHdr
1080: 31 29 2b 50 43 61 63 68 65 31 2e 73 7a 50 61 67  1)+PCache1.szPag
1090: 65 20 62 79 74 65 29 2e 20 54 68 65 0a 2a 2a 20  e byte). The.** 
10a0: 50 47 48 44 52 31 5f 54 4f 5f 50 41 47 45 28 29  PGHDR1_TO_PAGE()
10b0: 20 6d 61 63 72 6f 20 74 61 6b 65 73 20 61 20 70   macro takes a p
10c0: 6f 69 6e 74 65 72 20 74 6f 20 61 20 50 67 48 64  ointer to a PgHd
10d0: 72 31 20 73 74 72 75 63 74 75 72 65 20 61 73 0a  r1 structure as.
10e0: 2a 2a 20 61 6e 20 61 72 67 75 6d 65 6e 74 20 61  ** an argument a
10f0: 6e 64 20 72 65 74 75 72 6e 73 20 61 20 70 6f 69  nd returns a poi
1100: 6e 74 65 72 20 74 6f 20 74 68 65 20 61 73 73 6f  nter to the asso
1110: 63 69 61 74 65 64 20 62 6c 6f 63 6b 20 6f 66 20  ciated block of 
1120: 73 7a 50 61 67 65 0a 2a 2a 20 62 79 74 65 73 2e  szPage.** bytes.
1130: 20 54 68 65 20 50 41 47 45 5f 54 4f 5f 50 47 48   The PAGE_TO_PGH
1140: 44 52 31 28 29 20 6d 61 63 72 6f 20 64 6f 65 73  DR1() macro does
1150: 20 74 68 65 20 6f 70 70 6f 73 69 74 65 3a 20 69   the opposite: i
1160: 74 73 20 61 72 67 75 6d 65 6e 74 20 69 73 0a 2a  ts argument is.*
1170: 2a 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 61  * a pointer to a
1180: 20 62 6c 6f 63 6b 20 6f 66 20 73 7a 50 61 67 65   block of szPage
1190: 20 62 79 74 65 73 20 6f 66 20 64 61 74 61 20 61   bytes of data a
11a0: 6e 64 20 74 68 65 20 72 65 74 75 72 6e 20 76 61  nd the return va
11b0: 6c 75 65 20 69 73 0a 2a 2a 20 61 20 70 6f 69 6e  lue is.** a poin
11c0: 74 65 72 20 74 6f 20 74 68 65 20 61 73 73 6f 63  ter to the assoc
11d0: 69 61 74 65 64 20 50 67 48 64 72 31 20 73 74 72  iated PgHdr1 str
11e0: 75 63 74 75 72 65 2e 0a 2a 2a 0a 2a 2a 20 20 20  ucture..**.**   
11f0: 61 73 73 65 72 74 28 20 50 47 48 44 52 31 5f 54  assert( PGHDR1_T
1200: 4f 5f 50 41 47 45 28 50 41 47 45 5f 54 4f 5f 50  O_PAGE(PAGE_TO_P
1210: 47 48 44 52 31 28 70 43 61 63 68 65 2c 20 58 29  GHDR1(pCache, X)
1220: 29 3d 3d 58 20 29 3b 0a 2a 2f 0a 23 64 65 66 69  )==X );.*/.#defi
1230: 6e 65 20 50 47 48 44 52 31 5f 54 4f 5f 50 41 47  ne PGHDR1_TO_PAG
1240: 45 28 70 29 20 20 20 20 28 76 6f 69 64 2a 29 28  E(p)    (void*)(
1250: 28 28 63 68 61 72 2a 29 70 29 20 2d 20 70 2d 3e  ((char*)p) - p->
1260: 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 29 0a  pCache->szPage).
1270: 23 64 65 66 69 6e 65 20 50 41 47 45 5f 54 4f 5f  #define PAGE_TO_
1280: 50 47 48 44 52 31 28 63 2c 20 70 29 20 28 50 67  PGHDR1(c, p) (Pg
1290: 48 64 72 31 2a 29 28 28 28 63 68 61 72 2a 29 70  Hdr1*)(((char*)p
12a0: 29 20 2b 20 63 2d 3e 73 7a 50 61 67 65 29 0a 0a  ) + c->szPage)..
12b0: 2f 2a 0a 2a 2a 20 4d 61 63 72 6f 73 20 74 6f 20  /*.** Macros to 
12c0: 65 6e 74 65 72 20 61 6e 64 20 6c 65 61 76 65 20  enter and leave 
12d0: 74 68 65 20 67 6c 6f 62 61 6c 20 4c 52 55 20 6d  the global LRU m
12e0: 75 74 65 78 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65  utex..*/.#define
12f0: 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74   pcache1EnterMut
1300: 65 78 28 29 20 73 71 6c 69 74 65 33 5f 6d 75 74  ex() sqlite3_mut
1310: 65 78 5f 65 6e 74 65 72 28 70 63 61 63 68 65 31  ex_enter(pcache1
1320: 2e 6d 75 74 65 78 29 0a 23 64 65 66 69 6e 65 20  .mutex).#define 
1330: 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65  pcache1LeaveMute
1340: 78 28 29 20 73 71 6c 69 74 65 33 5f 6d 75 74 65  x() sqlite3_mute
1350: 78 5f 6c 65 61 76 65 28 70 63 61 63 68 65 31 2e  x_leave(pcache1.
1360: 6d 75 74 65 78 29 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a  mutex)../*******
1370: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1380: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1390: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
13a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
13b0: 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 2a 2a 2a 2a 2a  *******/./******
13c0: 2a 2a 20 50 61 67 65 20 41 6c 6c 6f 63 61 74 69  ** Page Allocati
13d0: 6f 6e 2f 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47  on/SQLITE_CONFIG
13e0: 5f 50 43 41 43 48 45 20 52 65 6c 61 74 65 64 20  _PCACHE Related 
13f0: 46 75 6e 63 74 69 6f 6e 73 20 2a 2a 2a 2a 2a 2a  Functions ******
1400: 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f 2a 0a 2a 2a  ********/../*.**
1410: 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   This function i
1420: 73 20 63 61 6c 6c 65 64 20 64 75 72 69 6e 67 20  s called during 
1430: 69 6e 69 74 69 61 6c 69 7a 61 74 69 6f 6e 20 69  initialization i
1440: 66 20 61 20 73 74 61 74 69 63 20 62 75 66 66 65  f a static buffe
1450: 72 20 69 73 20 0a 2a 2a 20 73 75 70 70 6c 69 65  r is .** supplie
1460: 64 20 74 6f 20 75 73 65 20 66 6f 72 20 74 68 65  d to use for the
1470: 20 70 61 67 65 2d 63 61 63 68 65 20 62 79 20 70   page-cache by p
1480: 61 73 73 69 6e 67 20 74 68 65 20 53 51 4c 49 54  assing the SQLIT
1490: 45 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41 43  E_CONFIG_PAGECAC
14a0: 48 45 0a 2a 2a 20 76 65 72 62 20 74 6f 20 73 71  HE.** verb to sq
14b0: 6c 69 74 65 33 5f 63 6f 6e 66 69 67 28 29 2e 20  lite3_config(). 
14c0: 50 61 72 61 6d 65 74 65 72 20 70 42 75 66 20 70  Parameter pBuf p
14d0: 6f 69 6e 74 73 20 74 6f 20 61 6e 20 61 6c 6c 6f  oints to an allo
14e0: 63 61 74 69 6f 6e 20 6c 61 72 67 65 0a 2a 2a 20  cation large.** 
14f0: 65 6e 6f 75 67 68 20 74 6f 20 63 6f 6e 74 61 69  enough to contai
1500: 6e 20 27 6e 27 20 62 75 66 66 65 72 73 20 6f 66  n 'n' buffers of
1510: 20 27 73 7a 27 20 62 79 74 65 73 20 65 61 63 68   'sz' bytes each
1520: 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
1530: 33 50 43 61 63 68 65 42 75 66 66 65 72 53 65 74  3PCacheBufferSet
1540: 75 70 28 76 6f 69 64 20 2a 70 42 75 66 2c 20 69  up(void *pBuf, i
1550: 6e 74 20 73 7a 2c 20 69 6e 74 20 6e 29 7b 0a 20  nt sz, int n){. 
1560: 20 69 66 28 20 70 63 61 63 68 65 31 2e 69 73 49   if( pcache1.isI
1570: 6e 69 74 20 29 7b 0a 20 20 20 20 50 67 46 72 65  nit ){.    PgFre
1580: 65 73 6c 6f 74 20 2a 70 3b 0a 20 20 20 20 73 7a  eslot *p;.    sz
1590: 20 3d 20 52 4f 55 4e 44 44 4f 57 4e 38 28 73 7a   = ROUNDDOWN8(sz
15a0: 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 73  );.    pcache1.s
15b0: 7a 53 6c 6f 74 20 3d 20 73 7a 3b 0a 20 20 20 20  zSlot = sz;.    
15c0: 70 63 61 63 68 65 31 2e 70 53 74 61 72 74 20 3d  pcache1.pStart =
15d0: 20 70 42 75 66 3b 0a 20 20 20 20 70 63 61 63 68   pBuf;.    pcach
15e0: 65 31 2e 70 46 72 65 65 20 3d 20 30 3b 0a 20 20  e1.pFree = 0;.  
15f0: 20 20 77 68 69 6c 65 28 20 6e 2d 2d 20 29 7b 0a    while( n-- ){.
1600: 20 20 20 20 20 20 70 20 3d 20 28 50 67 46 72 65        p = (PgFre
1610: 65 73 6c 6f 74 2a 29 70 42 75 66 3b 0a 20 20 20  eslot*)pBuf;.   
1620: 20 20 20 70 2d 3e 70 4e 65 78 74 20 3d 20 70 63     p->pNext = pc
1630: 61 63 68 65 31 2e 70 46 72 65 65 3b 0a 20 20 20  ache1.pFree;.   
1640: 20 20 20 70 63 61 63 68 65 31 2e 70 46 72 65 65     pcache1.pFree
1650: 20 3d 20 70 3b 0a 20 20 20 20 20 20 70 42 75 66   = p;.      pBuf
1660: 20 3d 20 28 76 6f 69 64 2a 29 26 28 28 63 68 61   = (void*)&((cha
1670: 72 2a 29 70 42 75 66 29 5b 73 7a 5d 3b 0a 20 20  r*)pBuf)[sz];.  
1680: 20 20 7d 0a 20 20 20 20 70 63 61 63 68 65 31 2e    }.    pcache1.
1690: 70 45 6e 64 20 3d 20 70 42 75 66 3b 0a 20 20 7d  pEnd = pBuf;.  }
16a0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6c 6c 6f 63  .}../*.** Malloc
16b0: 20 66 75 6e 63 74 69 6f 6e 20 75 73 65 64 20 77   function used w
16c0: 69 74 68 69 6e 20 74 68 69 73 20 66 69 6c 65 20  ithin this file 
16d0: 74 6f 20 61 6c 6c 6f 63 61 74 65 20 73 70 61 63  to allocate spac
16e0: 65 20 66 72 6f 6d 20 74 68 65 20 62 75 66 66 65  e from the buffe
16f0: 72 0a 2a 2a 20 63 6f 6e 66 69 67 75 72 65 64 20  r.** configured 
1700: 75 73 69 6e 67 20 73 71 6c 69 74 65 33 5f 63 6f  using sqlite3_co
1710: 6e 66 69 67 28 53 51 4c 49 54 45 5f 43 4f 4e 46  nfig(SQLITE_CONF
1720: 49 47 5f 50 41 47 45 43 41 43 48 45 29 20 6f 70  IG_PAGECACHE) op
1730: 74 69 6f 6e 2e 20 49 66 20 6e 6f 20 0a 2a 2a 20  tion. If no .** 
1740: 73 75 63 68 20 62 75 66 66 65 72 20 65 78 69 73  such buffer exis
1750: 74 73 20 6f 72 20 74 68 65 72 65 20 69 73 20 6e  ts or there is n
1760: 6f 20 73 70 61 63 65 20 6c 65 66 74 20 69 6e 20  o space left in 
1770: 69 74 2c 20 74 68 69 73 20 66 75 6e 63 74 69 6f  it, this functio
1780: 6e 20 66 61 6c 6c 73 20 0a 2a 2a 20 62 61 63 6b  n falls .** back
1790: 20 74 6f 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f   to sqlite3Mallo
17a0: 63 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  c()..*/.static v
17b0: 6f 69 64 20 2a 70 63 61 63 68 65 31 41 6c 6c 6f  oid *pcache1Allo
17c0: 63 28 69 6e 74 20 6e 42 79 74 65 29 7b 0a 20 20  c(int nByte){.  
17d0: 76 6f 69 64 20 2a 70 3b 0a 20 20 61 73 73 65 72  void *p;.  asser
17e0: 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78  t( sqlite3_mutex
17f0: 5f 68 65 6c 64 28 70 63 61 63 68 65 31 2e 6d 75  _held(pcache1.mu
1800: 74 65 78 29 20 29 3b 0a 20 20 69 66 28 20 6e 42  tex) );.  if( nB
1810: 79 74 65 3c 3d 70 63 61 63 68 65 31 2e 73 7a 53  yte<=pcache1.szS
1820: 6c 6f 74 20 26 26 20 70 63 61 63 68 65 31 2e 70  lot && pcache1.p
1830: 46 72 65 65 20 29 7b 0a 20 20 20 20 61 73 73 65  Free ){.    asse
1840: 72 74 28 20 70 63 61 63 68 65 31 2e 69 73 49 6e  rt( pcache1.isIn
1850: 69 74 20 29 3b 0a 20 20 20 20 70 20 3d 20 28 50  it );.    p = (P
1860: 67 48 64 72 31 20 2a 29 70 63 61 63 68 65 31 2e  gHdr1 *)pcache1.
1870: 70 46 72 65 65 3b 0a 20 20 20 20 70 63 61 63 68  pFree;.    pcach
1880: 65 31 2e 70 46 72 65 65 20 3d 20 70 63 61 63 68  e1.pFree = pcach
1890: 65 31 2e 70 46 72 65 65 2d 3e 70 4e 65 78 74 3b  e1.pFree->pNext;
18a0: 0a 20 20 20 20 73 71 6c 69 74 65 33 53 74 61 74  .    sqlite3Stat
18b0: 75 73 53 65 74 28 53 51 4c 49 54 45 5f 53 54 41  usSet(SQLITE_STA
18c0: 54 55 53 5f 50 41 47 45 43 41 43 48 45 5f 53 49  TUS_PAGECACHE_SI
18d0: 5a 45 2c 20 6e 42 79 74 65 29 3b 0a 20 20 20 20  ZE, nByte);.    
18e0: 73 71 6c 69 74 65 33 53 74 61 74 75 73 41 64 64  sqlite3StatusAdd
18f0: 28 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50  (SQLITE_STATUS_P
1900: 41 47 45 43 41 43 48 45 5f 55 53 45 44 2c 20 31  AGECACHE_USED, 1
1910: 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 0a 20 20 20  );.  }else{..   
1920: 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 61 20 6e   /* Allocate a n
1930: 65 77 20 62 75 66 66 65 72 20 75 73 69 6e 67 20  ew buffer using 
1940: 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 2e 20 42  sqlite3Malloc. B
1950: 65 66 6f 72 65 20 64 6f 69 6e 67 20 73 6f 2c 20  efore doing so, 
1960: 65 78 69 74 20 74 68 65 0a 20 20 20 20 2a 2a 20  exit the.    ** 
1970: 67 6c 6f 62 61 6c 20 70 63 61 63 68 65 20 6d 75  global pcache mu
1980: 74 65 78 20 61 6e 64 20 75 6e 6c 6f 63 6b 20 74  tex and unlock t
1990: 68 65 20 70 61 67 65 72 2d 63 61 63 68 65 20 6f  he pager-cache o
19a0: 62 6a 65 63 74 20 70 43 61 63 68 65 2e 20 54 68  bject pCache. Th
19b0: 69 73 20 69 73 20 0a 20 20 20 20 2a 2a 20 73 6f  is is .    ** so
19c0: 20 74 68 61 74 20 69 66 20 74 68 65 20 61 74 74   that if the att
19d0: 65 6d 70 74 20 74 6f 20 61 6c 6c 6f 63 61 74 65  empt to allocate
19e0: 20 61 20 6e 65 77 20 62 75 66 66 65 72 20 63 61   a new buffer ca
19f0: 75 73 65 73 20 74 68 65 20 74 68 65 20 0a 20 20  uses the the .  
1a00: 20 20 2a 2a 20 63 6f 6e 66 69 67 75 72 65 64 20    ** configured 
1a10: 73 6f 66 74 2d 68 65 61 70 2d 6c 69 6d 69 74 20  soft-heap-limit 
1a20: 74 6f 20 62 65 20 62 72 65 61 63 68 65 64 2c 20  to be breached, 
1a30: 69 74 20 77 69 6c 6c 20 62 65 20 70 6f 73 73 69  it will be possi
1a40: 62 6c 65 20 74 6f 0a 20 20 20 20 2a 2a 20 72 65  ble to.    ** re
1a50: 63 6c 61 69 6d 20 6d 65 6d 6f 72 79 20 66 72 6f  claim memory fro
1a60: 6d 20 74 68 69 73 20 70 61 67 65 72 2d 63 61 63  m this pager-cac
1a70: 68 65 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 70  he..    */.    p
1a80: 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78  cache1LeaveMutex
1a90: 28 29 3b 0a 20 20 20 20 70 20 3d 20 73 71 6c 69  ();.    p = sqli
1aa0: 74 65 33 4d 61 6c 6c 6f 63 28 6e 42 79 74 65 29  te3Malloc(nByte)
1ab0: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 45 6e 74  ;.    pcache1Ent
1ac0: 65 72 4d 75 74 65 78 28 29 3b 0a 20 20 20 20 69  erMutex();.    i
1ad0: 66 28 20 70 20 29 7b 0a 20 20 20 20 20 20 69 6e  f( p ){.      in
1ae0: 74 20 73 7a 20 3d 20 73 71 6c 69 74 65 33 4d 61  t sz = sqlite3Ma
1af0: 6c 6c 6f 63 53 69 7a 65 28 70 29 3b 0a 20 20 20  llocSize(p);.   
1b00: 20 20 20 73 71 6c 69 74 65 33 53 74 61 74 75 73     sqlite3Status
1b10: 41 64 64 28 53 51 4c 49 54 45 5f 53 54 41 54 55  Add(SQLITE_STATU
1b20: 53 5f 50 41 47 45 43 41 43 48 45 5f 4f 56 45 52  S_PAGECACHE_OVER
1b30: 46 4c 4f 57 2c 20 73 7a 29 3b 0a 20 20 20 20 7d  FLOW, sz);.    }
1b40: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 70 3b  .  }.  return p;
1b50: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61  .}../*.** Free a
1b60: 6e 20 61 6c 6c 6f 63 61 74 65 64 20 62 75 66 66  n allocated buff
1b70: 65 72 20 6f 62 74 61 69 6e 65 64 20 66 72 6f 6d  er obtained from
1b80: 20 70 63 61 63 68 65 31 41 6c 6c 6f 63 28 29 2e   pcache1Alloc().
1b90: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
1ba0: 70 63 61 63 68 65 31 46 72 65 65 28 76 6f 69 64  pcache1Free(void
1bb0: 20 2a 70 29 7b 0a 20 20 61 73 73 65 72 74 28 20   *p){.  assert( 
1bc0: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65  sqlite3_mutex_he
1bd0: 6c 64 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78  ld(pcache1.mutex
1be0: 29 20 29 3b 0a 20 20 69 66 28 20 70 3d 3d 30 20  ) );.  if( p==0 
1bf0: 29 20 72 65 74 75 72 6e 3b 0a 20 20 69 66 28 20  ) return;.  if( 
1c00: 70 3e 3d 70 63 61 63 68 65 31 2e 70 53 74 61 72  p>=pcache1.pStar
1c10: 74 20 26 26 20 70 3c 70 63 61 63 68 65 31 2e 70  t && p<pcache1.p
1c20: 45 6e 64 20 29 7b 0a 20 20 20 20 50 67 46 72 65  End ){.    PgFre
1c30: 65 73 6c 6f 74 20 2a 70 53 6c 6f 74 3b 0a 20 20  eslot *pSlot;.  
1c40: 20 20 73 71 6c 69 74 65 33 53 74 61 74 75 73 41    sqlite3StatusA
1c50: 64 64 28 53 51 4c 49 54 45 5f 53 54 41 54 55 53  dd(SQLITE_STATUS
1c60: 5f 50 41 47 45 43 41 43 48 45 5f 55 53 45 44 2c  _PAGECACHE_USED,
1c70: 20 2d 31 29 3b 0a 20 20 20 20 70 53 6c 6f 74 20   -1);.    pSlot 
1c80: 3d 20 28 50 67 46 72 65 65 73 6c 6f 74 2a 29 70  = (PgFreeslot*)p
1c90: 3b 0a 20 20 20 20 70 53 6c 6f 74 2d 3e 70 4e 65  ;.    pSlot->pNe
1ca0: 78 74 20 3d 20 70 63 61 63 68 65 31 2e 70 46 72  xt = pcache1.pFr
1cb0: 65 65 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e  ee;.    pcache1.
1cc0: 70 46 72 65 65 20 3d 20 70 53 6c 6f 74 3b 0a 20  pFree = pSlot;. 
1cd0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 6e 74 20   }else{.    int 
1ce0: 69 53 69 7a 65 20 3d 20 73 71 6c 69 74 65 33 4d  iSize = sqlite3M
1cf0: 61 6c 6c 6f 63 53 69 7a 65 28 70 29 3b 0a 20 20  allocSize(p);.  
1d00: 20 20 73 71 6c 69 74 65 33 53 74 61 74 75 73 41    sqlite3StatusA
1d10: 64 64 28 53 51 4c 49 54 45 5f 53 54 41 54 55 53  dd(SQLITE_STATUS
1d20: 5f 50 41 47 45 43 41 43 48 45 5f 4f 56 45 52 46  _PAGECACHE_OVERF
1d30: 4c 4f 57 2c 20 2d 69 53 69 7a 65 29 3b 0a 20 20  LOW, -iSize);.  
1d40: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
1d50: 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  );.  }.}../*.** 
1d60: 41 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 70  Allocate a new p
1d70: 61 67 65 20 6f 62 6a 65 63 74 20 69 6e 69 74 69  age object initi
1d80: 61 6c 6c 79 20 61 73 73 6f 63 69 61 74 65 64 20  ally associated 
1d90: 77 69 74 68 20 63 61 63 68 65 20 70 43 61 63 68  with cache pCach
1da0: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 50 67 48  e..*/.static PgH
1db0: 64 72 31 20 2a 70 63 61 63 68 65 31 41 6c 6c 6f  dr1 *pcache1Allo
1dc0: 63 50 61 67 65 28 50 43 61 63 68 65 31 20 2a 70  cPage(PCache1 *p
1dd0: 43 61 63 68 65 29 7b 0a 20 20 69 6e 74 20 6e 42  Cache){.  int nB
1de0: 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 50 67 48  yte = sizeof(PgH
1df0: 64 72 31 29 20 2b 20 70 43 61 63 68 65 2d 3e 73  dr1) + pCache->s
1e00: 7a 50 61 67 65 3b 0a 20 20 76 6f 69 64 20 2a 70  zPage;.  void *p
1e10: 50 67 20 3d 20 70 63 61 63 68 65 31 41 6c 6c 6f  Pg = pcache1Allo
1e20: 63 28 6e 42 79 74 65 29 3b 0a 20 20 50 67 48 64  c(nByte);.  PgHd
1e30: 72 31 20 2a 70 3b 0a 20 20 69 66 28 20 70 50 67  r1 *p;.  if( pPg
1e40: 20 29 7b 0a 20 20 20 20 70 20 3d 20 50 41 47 45   ){.    p = PAGE
1e50: 5f 54 4f 5f 50 47 48 44 52 31 28 70 43 61 63 68  _TO_PGHDR1(pCach
1e60: 65 2c 20 70 50 67 29 3b 0a 20 20 20 20 69 66 28  e, pPg);.    if(
1e70: 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61   pCache->bPurgea
1e80: 62 6c 65 20 29 7b 0a 20 20 20 20 20 20 70 63 61  ble ){.      pca
1e90: 63 68 65 31 2e 6e 43 75 72 72 65 6e 74 50 61 67  che1.nCurrentPag
1ea0: 65 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 7d 65 6c  e++;.    }.  }el
1eb0: 73 65 7b 0a 20 20 20 20 70 20 3d 20 30 3b 0a 20  se{.    p = 0;. 
1ec0: 20 7d 0a 20 20 72 65 74 75 72 6e 20 70 3b 0a 7d   }.  return p;.}
1ed0: 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61 20 70  ../*.** Free a p
1ee0: 61 67 65 20 6f 62 6a 65 63 74 20 61 6c 6c 6f 63  age object alloc
1ef0: 61 74 65 64 20 62 79 20 70 63 61 63 68 65 31 41  ated by pcache1A
1f00: 6c 6c 6f 63 50 61 67 65 28 29 2e 0a 2a 2f 0a 73  llocPage()..*/.s
1f10: 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68  tatic void pcach
1f20: 65 31 46 72 65 65 50 61 67 65 28 50 67 48 64 72  e1FreePage(PgHdr
1f30: 31 20 2a 70 29 7b 0a 20 20 69 66 28 20 70 20 29  1 *p){.  if( p )
1f40: 7b 0a 20 20 20 20 69 66 28 20 70 2d 3e 70 43 61  {.    if( p->pCa
1f50: 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20  che->bPurgeable 
1f60: 29 7b 0a 20 20 20 20 20 20 70 63 61 63 68 65 31  ){.      pcache1
1f70: 2e 6e 43 75 72 72 65 6e 74 50 61 67 65 2d 2d 3b  .nCurrentPage--;
1f80: 0a 20 20 20 20 7d 0a 20 20 20 20 70 63 61 63 68  .    }.    pcach
1f90: 65 31 46 72 65 65 28 50 47 48 44 52 31 5f 54 4f  e1Free(PGHDR1_TO
1fa0: 5f 50 41 47 45 28 70 29 29 3b 0a 20 20 7d 0a 7d  _PAGE(p));.  }.}
1fb0: 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6c 6c 6f 63 20 66  ../*.** Malloc f
1fc0: 75 6e 63 74 69 6f 6e 20 75 73 65 64 20 62 79 20  unction used by 
1fd0: 53 51 4c 69 74 65 20 74 6f 20 6f 62 74 61 69 6e  SQLite to obtain
1fe0: 20 73 70 61 63 65 20 66 72 6f 6d 20 74 68 65 20   space from the 
1ff0: 62 75 66 66 65 72 20 63 6f 6e 66 69 67 75 72 65  buffer configure
2000: 64 0a 2a 2a 20 75 73 69 6e 67 20 73 71 6c 69 74  d.** using sqlit
2010: 65 33 5f 63 6f 6e 66 69 67 28 53 51 4c 49 54 45  e3_config(SQLITE
2020: 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48  _CONFIG_PAGECACH
2030: 45 29 20 6f 70 74 69 6f 6e 2e 20 49 66 20 6e 6f  E) option. If no
2040: 20 73 75 63 68 20 62 75 66 66 65 72 0a 2a 2a 20   such buffer.** 
2050: 65 78 69 73 74 73 2c 20 74 68 69 73 20 66 75 6e  exists, this fun
2060: 63 74 69 6f 6e 20 66 61 6c 6c 73 20 62 61 63 6b  ction falls back
2070: 20 74 6f 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f   to sqlite3Mallo
2080: 63 28 29 2e 0a 2a 2f 0a 76 6f 69 64 20 2a 73 71  c()..*/.void *sq
2090: 6c 69 74 65 33 50 61 67 65 4d 61 6c 6c 6f 63 28  lite3PageMalloc(
20a0: 69 6e 74 20 73 7a 29 7b 0a 20 20 76 6f 69 64 20  int sz){.  void 
20b0: 2a 70 3b 0a 20 20 70 63 61 63 68 65 31 45 6e 74  *p;.  pcache1Ent
20c0: 65 72 4d 75 74 65 78 28 29 3b 0a 20 20 70 20 3d  erMutex();.  p =
20d0: 20 70 63 61 63 68 65 31 41 6c 6c 6f 63 28 73 7a   pcache1Alloc(sz
20e0: 29 3b 0a 20 20 70 63 61 63 68 65 31 4c 65 61 76  );.  pcache1Leav
20f0: 65 4d 75 74 65 78 28 29 3b 0a 20 20 72 65 74 75  eMutex();.  retu
2100: 72 6e 20 70 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46  rn p;.}../*.** F
2110: 72 65 65 20 61 6e 20 61 6c 6c 6f 63 61 74 65 64  ree an allocated
2120: 20 62 75 66 66 65 72 20 6f 62 74 61 69 6e 65 64   buffer obtained
2130: 20 66 72 6f 6d 20 73 71 6c 69 74 65 33 50 61 67   from sqlite3Pag
2140: 65 4d 61 6c 6c 6f 63 28 29 2e 0a 2a 2f 0a 76 6f  eMalloc()..*/.vo
2150: 69 64 20 73 71 6c 69 74 65 33 50 61 67 65 46 72  id sqlite3PageFr
2160: 65 65 28 76 6f 69 64 20 2a 70 29 7b 0a 20 20 70  ee(void *p){.  p
2170: 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78  cache1EnterMutex
2180: 28 29 3b 0a 20 20 70 63 61 63 68 65 31 46 72 65  ();.  pcache1Fre
2190: 65 28 70 29 3b 0a 20 20 70 63 61 63 68 65 31 4c  e(p);.  pcache1L
21a0: 65 61 76 65 4d 75 74 65 78 28 29 3b 0a 7d 0a 0a  eaveMutex();.}..
21b0: 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  /***************
21c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
21d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
21e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
21f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f  ***************/
2200: 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 20 47 65 6e 65 72  ./******** Gener
2210: 61 6c 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  al Implementatio
2220: 6e 20 46 75 6e 63 74 69 6f 6e 73 20 2a 2a 2a 2a  n Functions ****
2230: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2240: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2250: 2f 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75  /../*.** This fu
2260: 6e 63 74 69 6f 6e 20 69 73 20 75 73 65 64 20 74  nction is used t
2270: 6f 20 72 65 73 69 7a 65 20 74 68 65 20 68 61 73  o resize the has
2280: 68 20 74 61 62 6c 65 20 75 73 65 64 20 62 79 20  h table used by 
2290: 74 68 65 20 63 61 63 68 65 20 70 61 73 73 65 64  the cache passed
22a0: 0a 2a 2a 20 61 73 20 74 68 65 20 66 69 72 73 74  .** as the first
22b0: 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a   argument..**.**
22c0: 20 54 68 65 20 67 6c 6f 62 61 6c 20 6d 75 74 65   The global mute
22d0: 78 20 6d 75 73 74 20 62 65 20 68 65 6c 64 20 77  x must be held w
22e0: 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f  hen this functio
22f0: 6e 20 69 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f 0a  n is called..*/.
2300: 73 74 61 74 69 63 20 69 6e 74 20 70 63 61 63 68  static int pcach
2310: 65 31 52 65 73 69 7a 65 48 61 73 68 28 50 43 61  e1ResizeHash(PCa
2320: 63 68 65 31 20 2a 70 29 7b 0a 20 20 50 67 48 64  che1 *p){.  PgHd
2330: 72 31 20 2a 2a 61 70 4e 65 77 3b 0a 20 20 75 6e  r1 **apNew;.  un
2340: 73 69 67 6e 65 64 20 69 6e 74 20 6e 4e 65 77 3b  signed int nNew;
2350: 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  .  unsigned int 
2360: 69 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 73 71  i;..  assert( sq
2370: 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64  lite3_mutex_held
2380: 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29 20  (pcache1.mutex) 
2390: 29 3b 0a 0a 20 20 6e 4e 65 77 20 3d 20 70 2d 3e  );..  nNew = p->
23a0: 6e 48 61 73 68 2a 32 3b 0a 20 20 69 66 28 20 6e  nHash*2;.  if( n
23b0: 4e 65 77 3c 32 35 36 20 29 7b 0a 20 20 20 20 6e  New<256 ){.    n
23c0: 4e 65 77 20 3d 20 32 35 36 3b 0a 20 20 7d 0a 0a  New = 256;.  }..
23d0: 20 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75    pcache1LeaveMu
23e0: 74 65 78 28 29 3b 0a 20 20 69 66 28 20 70 2d 3e  tex();.  if( p->
23f0: 6e 48 61 73 68 20 29 7b 20 73 71 6c 69 74 65 33  nHash ){ sqlite3
2400: 42 65 67 69 6e 42 65 6e 69 67 6e 4d 61 6c 6c 6f  BeginBenignMallo
2410: 63 28 29 3b 20 7d 0a 20 20 61 70 4e 65 77 20 3d  c(); }.  apNew =
2420: 20 28 50 67 48 64 72 31 20 2a 2a 29 73 71 6c 69   (PgHdr1 **)sqli
2430: 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f  te3_malloc(sizeo
2440: 66 28 50 67 48 64 72 31 20 2a 29 2a 6e 4e 65 77  f(PgHdr1 *)*nNew
2450: 29 3b 0a 20 20 69 66 28 20 70 2d 3e 6e 48 61 73  );.  if( p->nHas
2460: 68 20 29 7b 20 73 71 6c 69 74 65 33 45 6e 64 42  h ){ sqlite3EndB
2470: 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 20 7d  enignMalloc(); }
2480: 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d  .  pcache1EnterM
2490: 75 74 65 78 28 29 3b 0a 20 20 69 66 28 20 61 70  utex();.  if( ap
24a0: 4e 65 77 20 29 7b 0a 20 20 20 20 6d 65 6d 73 65  New ){.    memse
24b0: 74 28 61 70 4e 65 77 2c 20 30 2c 20 73 69 7a 65  t(apNew, 0, size
24c0: 6f 66 28 50 67 48 64 72 31 20 2a 29 2a 6e 4e 65  of(PgHdr1 *)*nNe
24d0: 77 29 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b  w);.    for(i=0;
24e0: 20 69 3c 70 2d 3e 6e 48 61 73 68 3b 20 69 2b 2b   i<p->nHash; i++
24f0: 29 7b 0a 20 20 20 20 20 20 50 67 48 64 72 31 20  ){.      PgHdr1 
2500: 2a 70 50 61 67 65 3b 0a 20 20 20 20 20 20 50 67  *pPage;.      Pg
2510: 48 64 72 31 20 2a 70 4e 65 78 74 20 3d 20 70 2d  Hdr1 *pNext = p-
2520: 3e 61 70 48 61 73 68 5b 69 5d 3b 0a 20 20 20 20  >apHash[i];.    
2530: 20 20 77 68 69 6c 65 28 20 28 70 50 61 67 65 20    while( (pPage 
2540: 3d 20 70 4e 65 78 74 29 21 3d 30 20 29 7b 0a 20  = pNext)!=0 ){. 
2550: 20 20 20 20 20 20 20 75 6e 73 69 67 6e 65 64 20         unsigned 
2560: 69 6e 74 20 68 20 3d 20 70 50 61 67 65 2d 3e 69  int h = pPage->i
2570: 4b 65 79 20 25 20 6e 4e 65 77 3b 0a 20 20 20 20  Key % nNew;.    
2580: 20 20 20 20 70 4e 65 78 74 20 3d 20 70 50 61 67      pNext = pPag
2590: 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20  e->pNext;.      
25a0: 20 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 20 3d    pPage->pNext =
25b0: 20 61 70 4e 65 77 5b 68 5d 3b 0a 20 20 20 20 20   apNew[h];.     
25c0: 20 20 20 61 70 4e 65 77 5b 68 5d 20 3d 20 70 50     apNew[h] = pP
25d0: 61 67 65 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  age;.      }.   
25e0: 20 7d 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66   }.    sqlite3_f
25f0: 72 65 65 28 70 2d 3e 61 70 48 61 73 68 29 3b 0a  ree(p->apHash);.
2600: 20 20 20 20 70 2d 3e 61 70 48 61 73 68 20 3d 20      p->apHash = 
2610: 61 70 4e 65 77 3b 0a 20 20 20 20 70 2d 3e 6e 48  apNew;.    p->nH
2620: 61 73 68 20 3d 20 6e 4e 65 77 3b 0a 20 20 7d 0a  ash = nNew;.  }.
2630: 0a 20 20 72 65 74 75 72 6e 20 28 70 2d 3e 61 70  .  return (p->ap
2640: 48 61 73 68 20 3f 20 53 51 4c 49 54 45 5f 4f 4b  Hash ? SQLITE_OK
2650: 20 3a 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 29   : SQLITE_NOMEM)
2660: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  ;.}../*.** This 
2670: 66 75 6e 63 74 69 6f 6e 20 69 73 20 75 73 65 64  function is used
2680: 20 69 6e 74 65 72 6e 61 6c 6c 79 20 74 6f 20 72   internally to r
2690: 65 6d 6f 76 65 20 74 68 65 20 70 61 67 65 20 70  emove the page p
26a0: 50 61 67 65 20 66 72 6f 6d 20 74 68 65 20 0a 2a  Page from the .*
26b0: 2a 20 67 6c 6f 62 61 6c 20 4c 52 55 20 6c 69 73  * global LRU lis
26c0: 74 2c 20 69 66 20 69 73 20 70 61 72 74 20 6f 66  t, if is part of
26d0: 20 69 74 2e 20 49 66 20 70 50 61 67 65 20 69 73   it. If pPage is
26e0: 20 6e 6f 74 20 70 61 72 74 20 6f 66 20 74 68 65   not part of the
26f0: 20 67 6c 6f 62 61 6c 0a 2a 2a 20 4c 52 55 20 6c   global.** LRU l
2700: 69 73 74 2c 20 74 68 65 6e 20 74 68 69 73 20 66  ist, then this f
2710: 75 6e 63 74 69 6f 6e 20 69 73 20 61 20 6e 6f 2d  unction is a no-
2720: 6f 70 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 67 6c  op..**.** The gl
2730: 6f 62 61 6c 20 6d 75 74 65 78 20 6d 75 73 74 20  obal mutex must 
2740: 62 65 20 68 65 6c 64 20 77 68 65 6e 20 74 68 69  be held when thi
2750: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61  s function is ca
2760: 6c 6c 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  lled..*/.static 
2770: 76 6f 69 64 20 70 63 61 63 68 65 31 50 69 6e 50  void pcache1PinP
2780: 61 67 65 28 50 67 48 64 72 31 20 2a 70 50 61 67  age(PgHdr1 *pPag
2790: 65 29 7b 0a 20 20 61 73 73 65 72 74 28 20 73 71  e){.  assert( sq
27a0: 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64  lite3_mutex_held
27b0: 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29 20  (pcache1.mutex) 
27c0: 29 3b 0a 20 20 69 66 28 20 70 50 61 67 65 20 26  );.  if( pPage &
27d0: 26 20 28 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65  & (pPage->pLruNe
27e0: 78 74 20 7c 7c 20 70 50 61 67 65 3d 3d 70 63 61  xt || pPage==pca
27f0: 63 68 65 31 2e 70 4c 72 75 54 61 69 6c 29 20 29  che1.pLruTail) )
2800: 7b 0a 20 20 20 20 69 66 28 20 70 50 61 67 65 2d  {.    if( pPage-
2810: 3e 70 4c 72 75 50 72 65 76 20 29 7b 0a 20 20 20  >pLruPrev ){.   
2820: 20 20 20 70 50 61 67 65 2d 3e 70 4c 72 75 50 72     pPage->pLruPr
2830: 65 76 2d 3e 70 4c 72 75 4e 65 78 74 20 3d 20 70  ev->pLruNext = p
2840: 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 3b 0a  Page->pLruNext;.
2850: 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70 50      }.    if( pP
2860: 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 20 29 7b  age->pLruNext ){
2870: 0a 20 20 20 20 20 20 70 50 61 67 65 2d 3e 70 4c  .      pPage->pL
2880: 72 75 4e 65 78 74 2d 3e 70 4c 72 75 50 72 65 76  ruNext->pLruPrev
2890: 20 3d 20 70 50 61 67 65 2d 3e 70 4c 72 75 50 72   = pPage->pLruPr
28a0: 65 76 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66  ev;.    }.    if
28b0: 28 20 70 63 61 63 68 65 31 2e 70 4c 72 75 48 65  ( pcache1.pLruHe
28c0: 61 64 3d 3d 70 50 61 67 65 20 29 7b 0a 20 20 20  ad==pPage ){.   
28d0: 20 20 20 70 63 61 63 68 65 31 2e 70 4c 72 75 48     pcache1.pLruH
28e0: 65 61 64 20 3d 20 70 50 61 67 65 2d 3e 70 4c 72  ead = pPage->pLr
28f0: 75 4e 65 78 74 3b 0a 20 20 20 20 7d 0a 20 20 20  uNext;.    }.   
2900: 20 69 66 28 20 70 63 61 63 68 65 31 2e 70 4c 72   if( pcache1.pLr
2910: 75 54 61 69 6c 3d 3d 70 50 61 67 65 20 29 7b 0a  uTail==pPage ){.
2920: 20 20 20 20 20 20 70 63 61 63 68 65 31 2e 70 4c        pcache1.pL
2930: 72 75 54 61 69 6c 20 3d 20 70 50 61 67 65 2d 3e  ruTail = pPage->
2940: 70 4c 72 75 50 72 65 76 3b 0a 20 20 20 20 7d 0a  pLruPrev;.    }.
2950: 20 20 20 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e      pPage->pLruN
2960: 65 78 74 20 3d 20 30 3b 0a 20 20 20 20 70 50 61  ext = 0;.    pPa
2970: 67 65 2d 3e 70 4c 72 75 50 72 65 76 20 3d 20 30  ge->pLruPrev = 0
2980: 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 43 61  ;.    pPage->pCa
2990: 63 68 65 2d 3e 6e 52 65 63 79 63 6c 61 62 6c 65  che->nRecyclable
29a0: 2d 2d 3b 0a 20 20 7d 0a 7d 0a 0a 0a 2f 2a 0a 2a  --;.  }.}.../*.*
29b0: 2a 20 52 65 6d 6f 76 65 20 74 68 65 20 70 61 67  * Remove the pag
29c0: 65 20 73 75 70 70 6c 69 65 64 20 61 73 20 61 6e  e supplied as an
29d0: 20 61 72 67 75 6d 65 6e 74 20 66 72 6f 6d 20 74   argument from t
29e0: 68 65 20 68 61 73 68 20 74 61 62 6c 65 20 0a 2a  he hash table .*
29f0: 2a 20 28 50 43 61 63 68 65 31 2e 61 70 48 61 73  * (PCache1.apHas
2a00: 68 20 73 74 72 75 63 74 75 72 65 29 20 74 68 61  h structure) tha
2a10: 74 20 69 74 20 69 73 20 63 75 72 72 65 6e 74 6c  t it is currentl
2a20: 79 20 73 74 6f 72 65 64 20 69 6e 2e 0a 2a 2a 0a  y stored in..**.
2a30: 2a 2a 20 54 68 65 20 67 6c 6f 62 61 6c 20 6d 75  ** The global mu
2a40: 74 65 78 20 6d 75 73 74 20 62 65 20 68 65 6c 64  tex must be held
2a50: 20 77 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74   when this funct
2a60: 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 2e 0a 2a  ion is called..*
2a70: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63  /.static void pc
2a80: 61 63 68 65 31 52 65 6d 6f 76 65 46 72 6f 6d 48  ache1RemoveFromH
2a90: 61 73 68 28 50 67 48 64 72 31 20 2a 70 50 61 67  ash(PgHdr1 *pPag
2aa0: 65 29 7b 0a 20 20 75 6e 73 69 67 6e 65 64 20 69  e){.  unsigned i
2ab0: 6e 74 20 68 3b 0a 20 20 50 43 61 63 68 65 31 20  nt h;.  PCache1 
2ac0: 2a 70 43 61 63 68 65 20 3d 20 70 50 61 67 65 2d  *pCache = pPage-
2ad0: 3e 70 43 61 63 68 65 3b 0a 20 20 50 67 48 64 72  >pCache;.  PgHdr
2ae0: 31 20 2a 2a 70 70 3b 0a 0a 20 20 68 20 3d 20 70  1 **pp;..  h = p
2af0: 50 61 67 65 2d 3e 69 4b 65 79 20 25 20 70 43 61  Page->iKey % pCa
2b00: 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 66 6f  che->nHash;.  fo
2b10: 72 28 70 70 3d 26 70 43 61 63 68 65 2d 3e 61 70  r(pp=&pCache->ap
2b20: 48 61 73 68 5b 68 5d 3b 20 28 2a 70 70 29 21 3d  Hash[h]; (*pp)!=
2b30: 70 50 61 67 65 3b 20 70 70 3d 26 28 2a 70 70 29  pPage; pp=&(*pp)
2b40: 2d 3e 70 4e 65 78 74 29 3b 0a 20 20 2a 70 70 20  ->pNext);.  *pp 
2b50: 3d 20 28 2a 70 70 29 2d 3e 70 4e 65 78 74 3b 0a  = (*pp)->pNext;.
2b60: 0a 20 20 70 43 61 63 68 65 2d 3e 6e 50 61 67 65  .  pCache->nPage
2b70: 2d 2d 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20  --;.}../*.** If 
2b80: 74 68 65 72 65 20 61 72 65 20 63 75 72 72 65 6e  there are curren
2b90: 74 6c 79 20 6d 6f 72 65 20 74 68 61 6e 20 70 63  tly more than pc
2ba0: 61 63 68 65 2e 6e 4d 61 78 50 61 67 65 20 70 61  ache.nMaxPage pa
2bb0: 67 65 73 20 61 6c 6c 6f 63 61 74 65 64 2c 20 74  ges allocated, t
2bc0: 72 79 0a 2a 2a 20 74 6f 20 72 65 63 79 63 6c 65  ry.** to recycle
2bd0: 20 70 61 67 65 73 20 74 6f 20 72 65 64 75 63 65   pages to reduce
2be0: 20 74 68 65 20 6e 75 6d 62 65 72 20 61 6c 6c 6f   the number allo
2bf0: 63 61 74 65 64 20 74 6f 20 70 63 61 63 68 65 2e  cated to pcache.
2c00: 6e 4d 61 78 50 61 67 65 2e 0a 2a 2f 0a 73 74 61  nMaxPage..*/.sta
2c10: 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 31  tic void pcache1
2c20: 45 6e 66 6f 72 63 65 4d 61 78 50 61 67 65 28 76  EnforceMaxPage(v
2c30: 6f 69 64 29 7b 0a 20 20 61 73 73 65 72 74 28 20  oid){.  assert( 
2c40: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65  sqlite3_mutex_he
2c50: 6c 64 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78  ld(pcache1.mutex
2c60: 29 20 29 3b 0a 20 20 77 68 69 6c 65 28 20 70 63  ) );.  while( pc
2c70: 61 63 68 65 31 2e 6e 43 75 72 72 65 6e 74 50 61  ache1.nCurrentPa
2c80: 67 65 3e 70 63 61 63 68 65 31 2e 6e 4d 61 78 50  ge>pcache1.nMaxP
2c90: 61 67 65 20 26 26 20 70 63 61 63 68 65 31 2e 70  age && pcache1.p
2ca0: 4c 72 75 54 61 69 6c 20 29 7b 0a 20 20 20 20 50  LruTail ){.    P
2cb0: 67 48 64 72 31 20 2a 70 20 3d 20 70 63 61 63 68  gHdr1 *p = pcach
2cc0: 65 31 2e 70 4c 72 75 54 61 69 6c 3b 0a 20 20 20  e1.pLruTail;.   
2cd0: 20 70 63 61 63 68 65 31 50 69 6e 50 61 67 65 28   pcache1PinPage(
2ce0: 70 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31 52  p);.    pcache1R
2cf0: 65 6d 6f 76 65 46 72 6f 6d 48 61 73 68 28 70 29  emoveFromHash(p)
2d00: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 46 72 65  ;.    pcache1Fre
2d10: 65 50 61 67 65 28 70 29 3b 0a 20 20 7d 0a 7d 0a  ePage(p);.  }.}.
2d20: 0a 2f 2a 0a 2a 2a 20 44 69 73 63 61 72 64 20 61  ./*.** Discard a
2d30: 6c 6c 20 70 61 67 65 73 20 66 72 6f 6d 20 63 61  ll pages from ca
2d40: 63 68 65 20 70 43 61 63 68 65 20 77 69 74 68 20  che pCache with 
2d50: 61 20 70 61 67 65 20 6e 75 6d 62 65 72 20 28 6b  a page number (k
2d60: 65 79 20 76 61 6c 75 65 29 20 0a 2a 2a 20 67 72  ey value) .** gr
2d70: 65 61 74 65 72 20 74 68 61 6e 20 6f 72 20 65 71  eater than or eq
2d80: 75 61 6c 20 74 6f 20 69 4c 69 6d 69 74 2e 20 41  ual to iLimit. A
2d90: 6e 79 20 70 69 6e 6e 65 64 20 70 61 67 65 73 20  ny pinned pages 
2da0: 74 68 61 74 20 6d 65 65 74 20 74 68 69 73 20 0a  that meet this .
2db0: 2a 2a 20 63 72 69 74 65 72 69 61 20 61 72 65 20  ** criteria are 
2dc0: 75 6e 70 69 6e 6e 65 64 20 62 65 66 6f 72 65 20  unpinned before 
2dd0: 74 68 65 79 20 61 72 65 20 64 69 73 63 61 72 64  they are discard
2de0: 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 67 6c  ed..**.** The gl
2df0: 6f 62 61 6c 20 6d 75 74 65 78 20 6d 75 73 74 20  obal mutex must 
2e00: 62 65 20 68 65 6c 64 20 77 68 65 6e 20 74 68 69  be held when thi
2e10: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61  s function is ca
2e20: 6c 6c 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  lled..*/.static 
2e30: 76 6f 69 64 20 70 63 61 63 68 65 31 54 72 75 6e  void pcache1Trun
2e40: 63 61 74 65 55 6e 73 61 66 65 28 0a 20 20 50 43  cateUnsafe(.  PC
2e50: 61 63 68 65 31 20 2a 70 43 61 63 68 65 2c 20 0a  ache1 *pCache, .
2e60: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69    unsigned int i
2e70: 4c 69 6d 69 74 20 0a 29 7b 0a 20 20 54 45 53 54  Limit .){.  TEST
2e80: 4f 4e 4c 59 28 20 69 6e 74 20 6e 50 61 67 65 20  ONLY( int nPage 
2e90: 3d 20 30 3b 20 29 20 20 20 20 20 20 2f 2a 20 55  = 0; )      /* U
2ea0: 73 65 64 20 74 6f 20 61 73 73 65 72 74 20 70 43  sed to assert pC
2eb0: 61 63 68 65 2d 3e 6e 50 61 67 65 20 69 73 20 63  ache->nPage is c
2ec0: 6f 72 72 65 63 74 20 2a 2f 0a 20 20 75 6e 73 69  orrect */.  unsi
2ed0: 67 6e 65 64 20 69 6e 74 20 68 3b 0a 20 20 61 73  gned int h;.  as
2ee0: 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75  sert( sqlite3_mu
2ef0: 74 65 78 5f 68 65 6c 64 28 70 63 61 63 68 65 31  tex_held(pcache1
2f00: 2e 6d 75 74 65 78 29 20 29 3b 0a 20 20 66 6f 72  .mutex) );.  for
2f10: 28 68 3d 30 3b 20 68 3c 70 43 61 63 68 65 2d 3e  (h=0; h<pCache->
2f20: 6e 48 61 73 68 3b 20 68 2b 2b 29 7b 0a 20 20 20  nHash; h++){.   
2f30: 20 50 67 48 64 72 31 20 2a 2a 70 70 20 3d 20 26   PgHdr1 **pp = &
2f40: 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68  pCache->apHash[h
2f50: 5d 3b 20 0a 20 20 20 20 50 67 48 64 72 31 20 2a  ]; .    PgHdr1 *
2f60: 70 50 61 67 65 3b 0a 20 20 20 20 77 68 69 6c 65  pPage;.    while
2f70: 28 20 28 70 50 61 67 65 20 3d 20 2a 70 70 29 21  ( (pPage = *pp)!
2f80: 3d 30 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20  =0 ){.      if( 
2f90: 70 50 61 67 65 2d 3e 69 4b 65 79 3e 3d 69 4c 69  pPage->iKey>=iLi
2fa0: 6d 69 74 20 29 7b 0a 20 20 20 20 20 20 20 20 70  mit ){.        p
2fb0: 43 61 63 68 65 2d 3e 6e 50 61 67 65 2d 2d 3b 0a  Cache->nPage--;.
2fc0: 20 20 20 20 20 20 20 20 2a 70 70 20 3d 20 70 50          *pp = pP
2fd0: 61 67 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20  age->pNext;.    
2fe0: 20 20 20 20 70 63 61 63 68 65 31 50 69 6e 50 61      pcache1PinPa
2ff0: 67 65 28 70 50 61 67 65 29 3b 0a 20 20 20 20 20  ge(pPage);.     
3000: 20 20 20 70 63 61 63 68 65 31 46 72 65 65 50 61     pcache1FreePa
3010: 67 65 28 70 50 61 67 65 29 3b 0a 20 20 20 20 20  ge(pPage);.     
3020: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
3030: 70 70 20 3d 20 26 70 50 61 67 65 2d 3e 70 4e 65  pp = &pPage->pNe
3040: 78 74 3b 0a 20 20 20 20 20 20 20 20 54 45 53 54  xt;.        TEST
3050: 4f 4e 4c 59 28 20 6e 50 61 67 65 2b 2b 3b 20 29  ONLY( nPage++; )
3060: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
3070: 20 7d 0a 20 20 61 73 73 65 72 74 28 20 70 43 61   }.  assert( pCa
3080: 63 68 65 2d 3e 6e 50 61 67 65 3d 3d 6e 50 61 67  che->nPage==nPag
3090: 65 20 29 3b 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a  e );.}../*******
30a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
30b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
30c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
30d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
30e0: 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 2a 2a 2a 2a 2a  *******/./******
30f0: 2a 2a 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68  ** sqlite3_pcach
3100: 65 20 4d 65 74 68 6f 64 73 20 2a 2a 2a 2a 2a 2a  e Methods ******
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 2a 2a 2a 2a 2a 2a  ****************
3130: 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f 2a 0a 2a 2a  ********/../*.**
3140: 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20   Implementation 
3150: 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70  of the sqlite3_p
3160: 63 61 63 68 65 2e 78 49 6e 69 74 20 6d 65 74 68  cache.xInit meth
3170: 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  od..*/.static in
3180: 74 20 70 63 61 63 68 65 31 49 6e 69 74 28 76 6f  t pcache1Init(vo
3190: 69 64 20 2a 4e 6f 74 55 73 65 64 29 7b 0a 20 20  id *NotUsed){.  
31a0: 55 4e 55 53 45 44 5f 50 41 52 41 4d 45 54 45 52  UNUSED_PARAMETER
31b0: 28 4e 6f 74 55 73 65 64 29 3b 0a 20 20 61 73 73  (NotUsed);.  ass
31c0: 65 72 74 28 20 70 63 61 63 68 65 31 2e 69 73 49  ert( pcache1.isI
31d0: 6e 69 74 3d 3d 30 20 29 3b 0a 20 20 6d 65 6d 73  nit==0 );.  mems
31e0: 65 74 28 26 70 63 61 63 68 65 31 2c 20 30 2c 20  et(&pcache1, 0, 
31f0: 73 69 7a 65 6f 66 28 70 63 61 63 68 65 31 29 29  sizeof(pcache1))
3200: 3b 0a 20 20 69 66 28 20 73 71 6c 69 74 65 33 47  ;.  if( sqlite3G
3210: 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 62 43 6f 72  lobalConfig.bCor
3220: 65 4d 75 74 65 78 20 29 7b 0a 20 20 20 20 70 63  eMutex ){.    pc
3230: 61 63 68 65 31 2e 6d 75 74 65 78 20 3d 20 73 71  ache1.mutex = sq
3240: 6c 69 74 65 33 5f 6d 75 74 65 78 5f 61 6c 6c 6f  lite3_mutex_allo
3250: 63 28 53 51 4c 49 54 45 5f 4d 55 54 45 58 5f 53  c(SQLITE_MUTEX_S
3260: 54 41 54 49 43 5f 4c 52 55 29 3b 0a 20 20 7d 0a  TATIC_LRU);.  }.
3270: 20 20 70 63 61 63 68 65 31 2e 69 73 49 6e 69 74    pcache1.isInit
3280: 20 3d 20 31 3b 0a 20 20 72 65 74 75 72 6e 20 53   = 1;.  return S
3290: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  QLITE_OK;.}../*.
32a0: 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  ** Implementatio
32b0: 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33  n of the sqlite3
32c0: 5f 70 63 61 63 68 65 2e 78 53 68 75 74 64 6f 77  _pcache.xShutdow
32d0: 6e 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61  n method..*/.sta
32e0: 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 31  tic void pcache1
32f0: 53 68 75 74 64 6f 77 6e 28 76 6f 69 64 20 2a 4e  Shutdown(void *N
3300: 6f 74 55 73 65 64 29 7b 0a 20 20 55 4e 55 53 45  otUsed){.  UNUSE
3310: 44 5f 50 41 52 41 4d 45 54 45 52 28 4e 6f 74 55  D_PARAMETER(NotU
3320: 73 65 64 29 3b 0a 20 20 61 73 73 65 72 74 28 20  sed);.  assert( 
3330: 70 63 61 63 68 65 31 2e 69 73 49 6e 69 74 21 3d  pcache1.isInit!=
3340: 30 20 29 3b 0a 20 20 6d 65 6d 73 65 74 28 26 70  0 );.  memset(&p
3350: 63 61 63 68 65 31 2c 20 30 2c 20 73 69 7a 65 6f  cache1, 0, sizeo
3360: 66 28 70 63 61 63 68 65 31 29 29 3b 0a 7d 0a 0a  f(pcache1));.}..
3370: 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61  /*.** Implementa
3380: 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69  tion of the sqli
3390: 74 65 33 5f 70 63 61 63 68 65 2e 78 43 72 65 61  te3_pcache.xCrea
33a0: 74 65 20 6d 65 74 68 6f 64 2e 0a 2a 2a 0a 2a 2a  te method..**.**
33b0: 20 41 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20   Allocate a new 
33c0: 63 61 63 68 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  cache..*/.static
33d0: 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20   sqlite3_pcache 
33e0: 2a 70 63 61 63 68 65 31 43 72 65 61 74 65 28 69  *pcache1Create(i
33f0: 6e 74 20 73 7a 50 61 67 65 2c 20 69 6e 74 20 62  nt szPage, int b
3400: 50 75 72 67 65 61 62 6c 65 29 7b 0a 20 20 50 43  Purgeable){.  PC
3410: 61 63 68 65 31 20 2a 70 43 61 63 68 65 3b 0a 0a  ache1 *pCache;..
3420: 20 20 70 43 61 63 68 65 20 3d 20 28 50 43 61 63    pCache = (PCac
3430: 68 65 31 20 2a 29 73 71 6c 69 74 65 33 5f 6d 61  he1 *)sqlite3_ma
3440: 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 50 43 61 63  lloc(sizeof(PCac
3450: 68 65 31 29 29 3b 0a 20 20 69 66 28 20 70 43 61  he1));.  if( pCa
3460: 63 68 65 20 29 7b 0a 20 20 20 20 6d 65 6d 73 65  che ){.    memse
3470: 74 28 70 43 61 63 68 65 2c 20 30 2c 20 73 69 7a  t(pCache, 0, siz
3480: 65 6f 66 28 50 43 61 63 68 65 31 29 29 3b 0a 20  eof(PCache1));. 
3490: 20 20 20 70 43 61 63 68 65 2d 3e 73 7a 50 61 67     pCache->szPag
34a0: 65 20 3d 20 73 7a 50 61 67 65 3b 0a 20 20 20 20  e = szPage;.    
34b0: 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62  pCache->bPurgeab
34c0: 6c 65 20 3d 20 28 62 50 75 72 67 65 61 62 6c 65  le = (bPurgeable
34d0: 20 3f 20 31 20 3a 20 30 29 3b 0a 20 20 20 20 69   ? 1 : 0);.    i
34e0: 66 28 20 62 50 75 72 67 65 61 62 6c 65 20 29 7b  f( bPurgeable ){
34f0: 0a 20 20 20 20 20 20 70 43 61 63 68 65 2d 3e 6e  .      pCache->n
3500: 4d 69 6e 20 3d 20 31 30 3b 0a 20 20 20 20 20 20  Min = 10;.      
3510: 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65  pcache1EnterMute
3520: 78 28 29 3b 0a 20 20 20 20 20 20 70 63 61 63 68  x();.      pcach
3530: 65 31 2e 6e 4d 69 6e 50 61 67 65 20 2b 3d 20 70  e1.nMinPage += p
3540: 43 61 63 68 65 2d 3e 6e 4d 69 6e 3b 0a 20 20 20  Cache->nMin;.   
3550: 20 20 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d     pcache1LeaveM
3560: 75 74 65 78 28 29 3b 0a 20 20 20 20 7d 0a 20 20  utex();.    }.  
3570: 7d 0a 20 20 72 65 74 75 72 6e 20 28 73 71 6c 69  }.  return (sqli
3580: 74 65 33 5f 70 63 61 63 68 65 20 2a 29 70 43 61  te3_pcache *)pCa
3590: 63 68 65 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d  che;.}../*.** Im
35a0: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20  plementation of 
35b0: 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63  the sqlite3_pcac
35c0: 68 65 2e 78 43 61 63 68 65 73 69 7a 65 20 6d 65  he.xCachesize me
35d0: 74 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20 43 6f 6e  thod. .**.** Con
35e0: 66 69 67 75 72 65 20 74 68 65 20 63 61 63 68 65  figure the cache
35f0: 5f 73 69 7a 65 20 6c 69 6d 69 74 20 66 6f 72 20  _size limit for 
3600: 61 20 63 61 63 68 65 2e 0a 2a 2f 0a 73 74 61 74  a cache..*/.stat
3610: 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 31 43  ic void pcache1C
3620: 61 63 68 65 73 69 7a 65 28 73 71 6c 69 74 65 33  achesize(sqlite3
3630: 5f 70 63 61 63 68 65 20 2a 70 2c 20 69 6e 74 20  _pcache *p, int 
3640: 6e 4d 61 78 29 7b 0a 20 20 50 43 61 63 68 65 31  nMax){.  PCache1
3650: 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61 63   *pCache = (PCac
3660: 68 65 31 20 2a 29 70 3b 0a 20 20 69 66 28 20 70  he1 *)p;.  if( p
3670: 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c  Cache->bPurgeabl
3680: 65 20 29 7b 0a 20 20 20 20 70 63 61 63 68 65 31  e ){.    pcache1
3690: 45 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a 20 20  EnterMutex();.  
36a0: 20 20 70 63 61 63 68 65 31 2e 6e 4d 61 78 50 61    pcache1.nMaxPa
36b0: 67 65 20 2b 3d 20 28 6e 4d 61 78 20 2d 20 70 43  ge += (nMax - pC
36c0: 61 63 68 65 2d 3e 6e 4d 61 78 29 3b 0a 20 20 20  ache->nMax);.   
36d0: 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 20 3d 20   pCache->nMax = 
36e0: 6e 4d 61 78 3b 0a 20 20 20 20 70 63 61 63 68 65  nMax;.    pcache
36f0: 31 45 6e 66 6f 72 63 65 4d 61 78 50 61 67 65 28  1EnforceMaxPage(
3700: 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31 4c 65  );.    pcache1Le
3710: 61 76 65 4d 75 74 65 78 28 29 3b 0a 20 20 7d 0a  aveMutex();.  }.
3720: 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65  }../*.** Impleme
3730: 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73  ntation of the s
3740: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78 50  qlite3_pcache.xP
3750: 61 67 65 63 6f 75 6e 74 20 6d 65 74 68 6f 64 2e  agecount method.
3760: 20 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20   .*/.static int 
3770: 70 63 61 63 68 65 31 50 61 67 65 63 6f 75 6e 74  pcache1Pagecount
3780: 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20  (sqlite3_pcache 
3790: 2a 70 29 7b 0a 20 20 69 6e 74 20 6e 3b 0a 20 20  *p){.  int n;.  
37a0: 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65  pcache1EnterMute
37b0: 78 28 29 3b 0a 20 20 6e 20 3d 20 28 28 50 43 61  x();.  n = ((PCa
37c0: 63 68 65 31 20 2a 29 70 29 2d 3e 6e 50 61 67 65  che1 *)p)->nPage
37d0: 3b 0a 20 20 70 63 61 63 68 65 31 4c 65 61 76 65  ;.  pcache1Leave
37e0: 4d 75 74 65 78 28 29 3b 0a 20 20 72 65 74 75 72  Mutex();.  retur
37f0: 6e 20 6e 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d  n n;.}../*.** Im
3800: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20  plementation of 
3810: 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63  the sqlite3_pcac
3820: 68 65 2e 78 46 65 74 63 68 20 6d 65 74 68 6f 64  he.xFetch method
3830: 2e 20 0a 2a 2a 0a 2a 2a 20 46 65 74 63 68 20 61  . .**.** Fetch a
3840: 20 70 61 67 65 20 62 79 20 6b 65 79 20 76 61 6c   page by key val
3850: 75 65 2e 0a 2a 2a 0a 2a 2a 20 57 68 65 74 68 65  ue..**.** Whethe
3860: 72 20 6f 72 20 6e 6f 74 20 61 20 6e 65 77 20 70  r or not a new p
3870: 61 67 65 20 6d 61 79 20 62 65 20 61 6c 6c 6f 63  age may be alloc
3880: 61 74 65 64 20 62 79 20 74 68 69 73 20 66 75 6e  ated by this fun
3890: 63 74 69 6f 6e 20 64 65 70 65 6e 64 73 20 6f 6e  ction depends on
38a0: 0a 2a 2a 20 74 68 65 20 76 61 6c 75 65 20 6f 66  .** the value of
38b0: 20 74 68 65 20 63 72 65 61 74 65 46 6c 61 67 20   the createFlag 
38c0: 61 72 67 75 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20  argument..**.** 
38d0: 54 68 65 72 65 20 61 72 65 20 74 68 72 65 65 20  There are three 
38e0: 64 69 66 66 65 72 65 6e 74 20 61 70 70 72 6f 61  different approa
38f0: 63 68 65 73 20 74 6f 20 6f 62 74 61 69 6e 69 6e  ches to obtainin
3900: 67 20 73 70 61 63 65 20 66 6f 72 20 61 20 70 61  g space for a pa
3910: 67 65 2c 0a 2a 2a 20 64 65 70 65 6e 64 69 6e 67  ge,.** depending
3920: 20 6f 6e 20 74 68 65 20 76 61 6c 75 65 20 6f 66   on the value of
3930: 20 70 61 72 61 6d 65 74 65 72 20 63 72 65 61 74   parameter creat
3940: 65 46 6c 61 67 20 28 77 68 69 63 68 20 6d 61 79  eFlag (which may
3950: 20 62 65 20 30 2c 20 31 20 6f 72 20 32 29 2e 0a   be 0, 1 or 2)..
3960: 2a 2a 0a 2a 2a 20 20 20 31 2e 20 52 65 67 61 72  **.**   1. Regar
3970: 64 6c 65 73 73 20 6f 66 20 74 68 65 20 76 61 6c  dless of the val
3980: 75 65 20 6f 66 20 63 72 65 61 74 65 46 6c 61 67  ue of createFlag
3990: 2c 20 74 68 65 20 63 61 63 68 65 20 69 73 20 73  , the cache is s
39a0: 65 61 72 63 68 65 64 20 66 6f 72 20 61 20 0a 2a  earched for a .*
39b0: 2a 20 20 20 20 20 20 63 6f 70 79 20 6f 66 20 74  *      copy of t
39c0: 68 65 20 72 65 71 75 65 73 74 65 64 20 70 61 67  he requested pag
39d0: 65 2e 20 49 66 20 6f 6e 65 20 69 73 20 66 6f 75  e. If one is fou
39e0: 6e 64 2c 20 69 74 20 69 73 20 72 65 74 75 72 6e  nd, it is return
39f0: 65 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 32 2e 20 49  ed..**.**   2. I
3a00: 66 20 63 72 65 61 74 65 46 6c 61 67 3d 3d 30 20  f createFlag==0 
3a10: 61 6e 64 20 74 68 65 20 70 61 67 65 20 69 73 20  and the page is 
3a20: 6e 6f 74 20 61 6c 72 65 61 64 79 20 69 6e 20 74  not already in t
3a30: 68 65 20 63 61 63 68 65 2c 20 4e 55 4c 4c 20 69  he cache, NULL i
3a40: 73 0a 2a 2a 20 20 20 20 20 20 72 65 74 75 72 6e  s.**      return
3a50: 65 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 33 2e 20 49  ed..**.**   3. I
3a60: 66 20 63 72 65 61 74 65 46 6c 61 67 20 69 73 20  f createFlag is 
3a70: 31 2c 20 74 68 65 20 63 61 63 68 65 20 69 73 20  1, the cache is 
3a80: 6d 61 72 6b 65 64 20 61 73 20 70 75 72 67 65 61  marked as purgea
3a90: 62 6c 65 20 61 6e 64 20 74 68 65 20 70 61 67 65  ble and the page
3aa0: 20 69 73 20 0a 2a 2a 20 20 20 20 20 20 6e 6f 74   is .**      not
3ab0: 20 61 6c 72 65 61 64 79 20 69 6e 20 74 68 65 20   already in the 
3ac0: 63 61 63 68 65 2c 20 61 6e 64 20 69 66 20 65 69  cache, and if ei
3ad0: 74 68 65 72 20 6f 66 20 74 68 65 20 66 6f 6c 6c  ther of the foll
3ae0: 6f 77 69 6e 67 20 61 72 65 20 74 72 75 65 2c 20  owing are true, 
3af0: 0a 2a 2a 20 20 20 20 20 20 72 65 74 75 72 6e 20  .**      return 
3b00: 4e 55 4c 4c 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20  NULL:.**.**     
3b10: 20 20 28 61 29 20 74 68 65 20 6e 75 6d 62 65 72    (a) the number
3b20: 20 6f 66 20 70 61 67 65 73 20 70 69 6e 6e 65 64   of pages pinned
3b30: 20 62 79 20 74 68 65 20 63 61 63 68 65 20 69 73   by the cache is
3b40: 20 67 72 65 61 74 65 72 20 74 68 61 6e 0a 2a 2a   greater than.**
3b50: 20 20 20 20 20 20 20 20 20 20 20 50 43 61 63 68             PCach
3b60: 65 31 2e 6e 4d 61 78 2c 20 6f 72 0a 2a 2a 20 20  e1.nMax, or.**  
3b70: 20 20 20 20 20 28 62 29 20 74 68 65 20 6e 75 6d       (b) the num
3b80: 62 65 72 20 6f 66 20 70 61 67 65 73 20 70 69 6e  ber of pages pin
3b90: 6e 65 64 20 62 79 20 74 68 65 20 63 61 63 68 65  ned by the cache
3ba0: 20 69 73 20 67 72 65 61 74 65 72 20 74 68 61 6e   is greater than
3bb0: 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 74 68  .**           th
3bc0: 65 20 73 75 6d 20 6f 66 20 6e 4d 61 78 20 66 6f  e sum of nMax fo
3bd0: 72 20 61 6c 6c 20 70 75 72 67 65 61 62 6c 65 20  r all purgeable 
3be0: 63 61 63 68 65 73 2c 20 6c 65 73 73 20 74 68 65  caches, less the
3bf0: 20 73 75 6d 20 6f 66 20 0a 2a 2a 20 20 20 20 20   sum of .**     
3c00: 20 20 20 20 20 20 6e 4d 69 6e 20 66 6f 72 20 61        nMin for a
3c10: 6c 6c 20 6f 74 68 65 72 20 70 75 72 67 65 61 62  ll other purgeab
3c20: 6c 65 20 63 61 63 68 65 73 2e 20 0a 2a 2a 0a 2a  le caches. .**.*
3c30: 2a 20 20 20 34 2e 20 49 66 20 6e 6f 6e 65 20 6f  *   4. If none o
3c40: 66 20 74 68 65 20 66 69 72 73 74 20 74 68 72 65  f the first thre
3c50: 65 20 63 6f 6e 64 69 74 69 6f 6e 73 20 61 70 70  e conditions app
3c60: 6c 79 20 61 6e 64 20 74 68 65 20 63 61 63 68 65  ly and the cache
3c70: 20 69 73 20 6d 61 72 6b 65 64 0a 2a 2a 20 20 20   is marked.**   
3c80: 20 20 20 61 73 20 70 75 72 67 65 61 62 6c 65 2c     as purgeable,
3c90: 20 61 6e 64 20 69 66 20 6f 6e 65 20 6f 66 20 74   and if one of t
3ca0: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 69 73 20  he following is 
3cb0: 74 72 75 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20  true:.**.**     
3cc0: 20 20 28 61 29 20 54 68 65 20 6e 75 6d 62 65 72    (a) The number
3cd0: 20 6f 66 20 70 61 67 65 73 20 61 6c 6c 6f 63 61   of pages alloca
3ce0: 74 65 64 20 66 6f 72 20 74 68 65 20 63 61 63 68  ted for the cach
3cf0: 65 20 69 73 20 61 6c 72 65 61 64 79 20 0a 2a 2a  e is already .**
3d00: 20 20 20 20 20 20 20 20 20 20 20 50 43 61 63 68             PCach
3d10: 65 31 2e 6e 4d 61 78 2c 20 6f 72 0a 2a 2a 0a 2a  e1.nMax, or.**.*
3d20: 2a 20 20 20 20 20 20 20 28 62 29 20 54 68 65 20  *       (b) The 
3d30: 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20  number of pages 
3d40: 61 6c 6c 6f 63 61 74 65 64 20 66 6f 72 20 61 6c  allocated for al
3d50: 6c 20 70 75 72 67 65 61 62 6c 65 20 63 61 63 68  l purgeable cach
3d60: 65 73 20 69 73 0a 2a 2a 20 20 20 20 20 20 20 20  es is.**        
3d70: 20 20 20 61 6c 72 65 61 64 79 20 65 71 75 61 6c     already equal
3d80: 20 74 6f 20 6f 72 20 67 72 65 61 74 65 72 20 74   to or greater t
3d90: 68 61 6e 20 74 68 65 20 73 75 6d 20 6f 66 20 6e  han the sum of n
3da0: 4d 61 78 20 66 6f 72 20 61 6c 6c 0a 2a 2a 20 20  Max for all.**  
3db0: 20 20 20 20 20 20 20 20 20 70 75 72 67 65 61 62           purgeab
3dc0: 6c 65 20 63 61 63 68 65 73 2c 0a 2a 2a 0a 2a 2a  le caches,.**.**
3dd0: 20 20 20 20 20 20 74 68 65 6e 20 61 74 74 65 6d        then attem
3de0: 70 74 20 74 6f 20 72 65 63 79 63 6c 65 20 61 20  pt to recycle a 
3df0: 70 61 67 65 20 66 72 6f 6d 20 74 68 65 20 4c 52  page from the LR
3e00: 55 20 6c 69 73 74 2e 20 49 66 20 69 74 20 69 73  U list. If it is
3e10: 20 74 68 65 20 72 69 67 68 74 0a 2a 2a 20 20 20   the right.**   
3e20: 20 20 20 73 69 7a 65 2c 20 72 65 74 75 72 6e 20     size, return 
3e30: 74 68 65 20 72 65 63 79 63 6c 65 64 20 62 75 66  the recycled buf
3e40: 66 65 72 2e 20 4f 74 68 65 72 77 69 73 65 2c 20  fer. Otherwise, 
3e50: 66 72 65 65 20 74 68 65 20 62 75 66 66 65 72 20  free the buffer 
3e60: 61 6e 64 0a 2a 2a 20 20 20 20 20 20 70 72 6f 63  and.**      proc
3e70: 65 65 64 20 74 6f 20 73 74 65 70 20 35 2e 20 0a  eed to step 5. .
3e80: 2a 2a 0a 2a 2a 20 20 20 35 2e 20 4f 74 68 65 72  **.**   5. Other
3e90: 77 69 73 65 2c 20 61 6c 6c 6f 63 61 74 65 20 61  wise, allocate a
3ea0: 6e 64 20 72 65 74 75 72 6e 20 61 20 6e 65 77 20  nd return a new 
3eb0: 70 61 67 65 20 62 75 66 66 65 72 2e 0a 2a 2f 0a  page buffer..*/.
3ec0: 73 74 61 74 69 63 20 76 6f 69 64 20 2a 70 63 61  static void *pca
3ed0: 63 68 65 31 46 65 74 63 68 28 73 71 6c 69 74 65  che1Fetch(sqlite
3ee0: 33 5f 70 63 61 63 68 65 20 2a 70 2c 20 75 6e 73  3_pcache *p, uns
3ef0: 69 67 6e 65 64 20 69 6e 74 20 69 4b 65 79 2c 20  igned int iKey, 
3f00: 69 6e 74 20 63 72 65 61 74 65 46 6c 61 67 29 7b  int createFlag){
3f10: 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  .  unsigned int 
3f20: 6e 50 69 6e 6e 65 64 3b 0a 20 20 50 43 61 63 68  nPinned;.  PCach
3f30: 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43  e1 *pCache = (PC
3f40: 61 63 68 65 31 20 2a 29 70 3b 0a 20 20 50 67 48  ache1 *)p;.  PgH
3f50: 64 72 31 20 2a 70 50 61 67 65 20 3d 20 30 3b 0a  dr1 *pPage = 0;.
3f60: 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d  .  pcache1EnterM
3f70: 75 74 65 78 28 29 3b 0a 20 20 69 66 28 20 63 72  utex();.  if( cr
3f80: 65 61 74 65 46 6c 61 67 3d 3d 31 20 29 20 73 71  eateFlag==1 ) sq
3f90: 6c 69 74 65 33 42 65 67 69 6e 42 65 6e 69 67 6e  lite3BeginBenign
3fa0: 4d 61 6c 6c 6f 63 28 29 3b 0a 0a 20 20 2f 2a 20  Malloc();..  /* 
3fb0: 53 65 61 72 63 68 20 74 68 65 20 68 61 73 68 20  Search the hash 
3fc0: 74 61 62 6c 65 20 66 6f 72 20 61 6e 20 65 78 69  table for an exi
3fd0: 73 74 69 6e 67 20 65 6e 74 72 79 2e 20 2a 2f 0a  sting entry. */.
3fe0: 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 6e 48    if( pCache->nH
3ff0: 61 73 68 3e 30 20 29 7b 0a 20 20 20 20 75 6e 73  ash>0 ){.    uns
4000: 69 67 6e 65 64 20 69 6e 74 20 68 20 3d 20 69 4b  igned int h = iK
4010: 65 79 20 25 20 70 43 61 63 68 65 2d 3e 6e 48 61  ey % pCache->nHa
4020: 73 68 3b 0a 20 20 20 20 66 6f 72 28 70 50 61 67  sh;.    for(pPag
4030: 65 3d 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68  e=pCache->apHash
4040: 5b 68 5d 3b 20 70 50 61 67 65 26 26 70 50 61 67  [h]; pPage&&pPag
4050: 65 2d 3e 69 4b 65 79 21 3d 69 4b 65 79 3b 20 70  e->iKey!=iKey; p
4060: 50 61 67 65 3d 70 50 61 67 65 2d 3e 70 4e 65 78  Page=pPage->pNex
4070: 74 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70  t);.  }..  if( p
4080: 50 61 67 65 20 7c 7c 20 63 72 65 61 74 65 46 6c  Page || createFl
4090: 61 67 3d 3d 30 20 29 7b 0a 20 20 20 20 70 63 61  ag==0 ){.    pca
40a0: 63 68 65 31 50 69 6e 50 61 67 65 28 70 50 61 67  che1PinPage(pPag
40b0: 65 29 3b 0a 20 20 20 20 67 6f 74 6f 20 66 65 74  e);.    goto fet
40c0: 63 68 5f 6f 75 74 3b 0a 20 20 7d 0a 0a 20 20 2f  ch_out;.  }..  /
40d0: 2a 20 53 74 65 70 20 33 20 6f 66 20 68 65 61 64  * Step 3 of head
40e0: 65 72 20 63 6f 6d 6d 65 6e 74 2e 20 2a 2f 0a 20  er comment. */. 
40f0: 20 6e 50 69 6e 6e 65 64 20 3d 20 70 43 61 63 68   nPinned = pCach
4100: 65 2d 3e 6e 50 61 67 65 20 2d 20 70 43 61 63 68  e->nPage - pCach
4110: 65 2d 3e 6e 52 65 63 79 63 6c 61 62 6c 65 3b 0a  e->nRecyclable;.
4120: 20 20 69 66 28 20 63 72 65 61 74 65 46 6c 61 67    if( createFlag
4130: 3d 3d 31 20 26 26 20 70 43 61 63 68 65 2d 3e 62  ==1 && pCache->b
4140: 50 75 72 67 65 61 62 6c 65 20 26 26 20 28 0a 20  Purgeable && (. 
4150: 20 20 20 20 20 20 20 6e 50 69 6e 6e 65 64 3e 3d         nPinned>=
4160: 28 70 63 61 63 68 65 31 2e 6e 4d 61 78 50 61 67  (pcache1.nMaxPag
4170: 65 2b 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 2d 70  e+pCache->nMin-p
4180: 63 61 63 68 65 31 2e 6e 4d 69 6e 50 61 67 65 29  cache1.nMinPage)
4190: 0a 20 20 20 20 20 7c 7c 20 6e 50 69 6e 6e 65 64  .     || nPinned
41a0: 3e 3d 28 70 43 61 63 68 65 2d 3e 6e 4d 61 78 20  >=(pCache->nMax 
41b0: 2a 20 39 20 2f 20 31 30 29 0a 20 20 29 29 7b 0a  * 9 / 10).  )){.
41c0: 20 20 20 20 67 6f 74 6f 20 66 65 74 63 68 5f 6f      goto fetch_o
41d0: 75 74 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70  ut;.  }..  if( p
41e0: 43 61 63 68 65 2d 3e 6e 50 61 67 65 3e 3d 70 43  Cache->nPage>=pC
41f0: 61 63 68 65 2d 3e 6e 48 61 73 68 20 26 26 20 70  ache->nHash && p
4200: 63 61 63 68 65 31 52 65 73 69 7a 65 48 61 73 68  cache1ResizeHash
4210: 28 70 43 61 63 68 65 29 20 29 7b 0a 20 20 20 20  (pCache) ){.    
4220: 67 6f 74 6f 20 66 65 74 63 68 5f 6f 75 74 3b 0a  goto fetch_out;.
4230: 20 20 7d 0a 0a 20 20 2f 2a 20 53 74 65 70 20 34    }..  /* Step 4
4240: 2e 20 54 72 79 20 74 6f 20 72 65 63 79 63 6c 65  . Try to recycle
4250: 20 61 20 70 61 67 65 20 62 75 66 66 65 72 20 69   a page buffer i
4260: 66 20 61 70 70 72 6f 70 72 69 61 74 65 2e 20 2a  f appropriate. *
4270: 2f 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e  /.  if( pCache->
4280: 62 50 75 72 67 65 61 62 6c 65 20 26 26 20 70 63  bPurgeable && pc
4290: 61 63 68 65 31 2e 70 4c 72 75 54 61 69 6c 20 26  ache1.pLruTail &
42a0: 26 20 28 0a 20 20 20 20 20 28 70 43 61 63 68 65  & (.     (pCache
42b0: 2d 3e 6e 50 61 67 65 2b 31 3e 3d 70 43 61 63 68  ->nPage+1>=pCach
42c0: 65 2d 3e 6e 4d 61 78 29 20 7c 7c 20 70 63 61 63  e->nMax) || pcac
42d0: 68 65 31 2e 6e 43 75 72 72 65 6e 74 50 61 67 65  he1.nCurrentPage
42e0: 3e 3d 70 63 61 63 68 65 31 2e 6e 4d 61 78 50 61  >=pcache1.nMaxPa
42f0: 67 65 0a 20 20 29 29 7b 0a 20 20 20 20 70 50 61  ge.  )){.    pPa
4300: 67 65 20 3d 20 70 63 61 63 68 65 31 2e 70 4c 72  ge = pcache1.pLr
4310: 75 54 61 69 6c 3b 0a 20 20 20 20 70 63 61 63 68  uTail;.    pcach
4320: 65 31 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73 68  e1RemoveFromHash
4330: 28 70 50 61 67 65 29 3b 0a 20 20 20 20 70 63 61  (pPage);.    pca
4340: 63 68 65 31 50 69 6e 50 61 67 65 28 70 50 61 67  che1PinPage(pPag
4350: 65 29 3b 0a 20 20 20 20 69 66 28 20 70 50 61 67  e);.    if( pPag
4360: 65 2d 3e 70 43 61 63 68 65 2d 3e 73 7a 50 61 67  e->pCache->szPag
4370: 65 21 3d 70 43 61 63 68 65 2d 3e 73 7a 50 61 67  e!=pCache->szPag
4380: 65 20 29 7b 0a 20 20 20 20 20 20 70 63 61 63 68  e ){.      pcach
4390: 65 31 46 72 65 65 50 61 67 65 28 70 50 61 67 65  e1FreePage(pPage
43a0: 29 3b 0a 20 20 20 20 20 20 70 50 61 67 65 20 3d  );.      pPage =
43b0: 20 30 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20   0;.    }else{. 
43c0: 20 20 20 20 20 70 63 61 63 68 65 31 2e 6e 43 75       pcache1.nCu
43d0: 72 72 65 6e 74 50 61 67 65 20 2d 3d 20 28 70 50  rrentPage -= (pP
43e0: 61 67 65 2d 3e 70 43 61 63 68 65 2d 3e 62 50 75  age->pCache->bPu
43f0: 72 67 65 61 62 6c 65 20 2d 20 70 43 61 63 68 65  rgeable - pCache
4400: 2d 3e 62 50 75 72 67 65 61 62 6c 65 29 3b 0a 20  ->bPurgeable);. 
4410: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53     }.  }..  /* S
4420: 74 65 70 20 35 2e 20 49 66 20 61 20 75 73 61 62  tep 5. If a usab
4430: 6c 65 20 70 61 67 65 20 62 75 66 66 65 72 20 68  le page buffer h
4440: 61 73 20 73 74 69 6c 6c 20 6e 6f 74 20 62 65 65  as still not bee
4450: 6e 20 66 6f 75 6e 64 2c 20 0a 20 20 2a 2a 20 61  n found, .  ** a
4460: 74 74 65 6d 70 74 20 74 6f 20 61 6c 6c 6f 63 61  ttempt to alloca
4470: 74 65 20 61 20 6e 65 77 20 6f 6e 65 2e 20 0a 20  te a new one. . 
4480: 20 2a 2f 0a 20 20 69 66 28 20 21 70 50 61 67 65   */.  if( !pPage
4490: 20 29 7b 0a 20 20 20 20 70 50 61 67 65 20 3d 20   ){.    pPage = 
44a0: 70 63 61 63 68 65 31 41 6c 6c 6f 63 50 61 67 65  pcache1AllocPage
44b0: 28 70 43 61 63 68 65 29 3b 0a 20 20 7d 0a 0a 20  (pCache);.  }.. 
44c0: 20 69 66 28 20 70 50 61 67 65 20 29 7b 0a 20 20   if( pPage ){.  
44d0: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68    unsigned int h
44e0: 20 3d 20 69 4b 65 79 20 25 20 70 43 61 63 68 65   = iKey % pCache
44f0: 2d 3e 6e 48 61 73 68 3b 0a 20 20 20 20 70 43 61  ->nHash;.    pCa
4500: 63 68 65 2d 3e 6e 50 61 67 65 2b 2b 3b 0a 20 20  che->nPage++;.  
4510: 20 20 70 50 61 67 65 2d 3e 69 4b 65 79 20 3d 20    pPage->iKey = 
4520: 69 4b 65 79 3b 0a 20 20 20 20 70 50 61 67 65 2d  iKey;.    pPage-
4530: 3e 70 4e 65 78 74 20 3d 20 70 43 61 63 68 65 2d  >pNext = pCache-
4540: 3e 61 70 48 61 73 68 5b 68 5d 3b 0a 20 20 20 20  >apHash[h];.    
4550: 70 50 61 67 65 2d 3e 70 43 61 63 68 65 20 3d 20  pPage->pCache = 
4560: 70 43 61 63 68 65 3b 0a 20 20 20 20 70 50 61 67  pCache;.    pPag
4570: 65 2d 3e 70 4c 72 75 50 72 65 76 20 3d 20 30 3b  e->pLruPrev = 0;
4580: 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 4c 72 75  .    pPage->pLru
4590: 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20 20 2a 28  Next = 0;.    *(
45a0: 76 6f 69 64 20 2a 2a 29 28 50 47 48 44 52 31 5f  void **)(PGHDR1_
45b0: 54 4f 5f 50 41 47 45 28 70 50 61 67 65 29 29 20  TO_PAGE(pPage)) 
45c0: 3d 20 30 3b 0a 20 20 20 20 70 43 61 63 68 65 2d  = 0;.    pCache-
45d0: 3e 61 70 48 61 73 68 5b 68 5d 20 3d 20 70 50 61  >apHash[h] = pPa
45e0: 67 65 3b 0a 20 20 7d 0a 0a 66 65 74 63 68 5f 6f  ge;.  }..fetch_o
45f0: 75 74 3a 0a 20 20 69 66 28 20 70 50 61 67 65 20  ut:.  if( pPage 
4600: 26 26 20 69 4b 65 79 3e 70 43 61 63 68 65 2d 3e  && iKey>pCache->
4610: 69 4d 61 78 4b 65 79 20 29 7b 0a 20 20 20 20 70  iMaxKey ){.    p
4620: 43 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 3d  Cache->iMaxKey =
4630: 20 69 4b 65 79 3b 0a 20 20 7d 0a 20 20 69 66 28   iKey;.  }.  if(
4640: 20 63 72 65 61 74 65 46 6c 61 67 3d 3d 31 20 29   createFlag==1 )
4650: 20 73 71 6c 69 74 65 33 45 6e 64 42 65 6e 69 67   sqlite3EndBenig
4660: 6e 4d 61 6c 6c 6f 63 28 29 3b 0a 20 20 70 63 61  nMalloc();.  pca
4670: 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 29  che1LeaveMutex()
4680: 3b 0a 20 20 72 65 74 75 72 6e 20 28 70 50 61 67  ;.  return (pPag
4690: 65 20 3f 20 50 47 48 44 52 31 5f 54 4f 5f 50 41  e ? PGHDR1_TO_PA
46a0: 47 45 28 70 50 61 67 65 29 20 3a 20 30 29 3b 0a  GE(pPage) : 0);.
46b0: 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d  }.../*.** Implem
46c0: 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20  entation of the 
46d0: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78  sqlite3_pcache.x
46e0: 55 6e 70 69 6e 20 6d 65 74 68 6f 64 2e 0a 2a 2a  Unpin method..**
46f0: 0a 2a 2a 20 4d 61 72 6b 20 61 20 70 61 67 65 20  .** Mark a page 
4700: 61 73 20 75 6e 70 69 6e 6e 65 64 20 28 65 6c 69  as unpinned (eli
4710: 67 69 62 6c 65 20 66 6f 72 20 61 73 79 6e 63 68  gible for asynch
4720: 72 6f 6e 6f 75 73 20 72 65 63 79 63 6c 69 6e 67  ronous recycling
4730: 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  )..*/.static voi
4740: 64 20 70 63 61 63 68 65 31 55 6e 70 69 6e 28 73  d pcache1Unpin(s
4750: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70  qlite3_pcache *p
4760: 2c 20 76 6f 69 64 20 2a 70 50 67 2c 20 69 6e 74  , void *pPg, int
4770: 20 72 65 75 73 65 55 6e 6c 69 6b 65 6c 79 29 7b   reuseUnlikely){
4780: 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63  .  PCache1 *pCac
4790: 68 65 20 3d 20 28 50 43 61 63 68 65 31 20 2a 29  he = (PCache1 *)
47a0: 70 3b 0a 20 20 50 67 48 64 72 31 20 2a 70 50 61  p;.  PgHdr1 *pPa
47b0: 67 65 20 3d 20 50 41 47 45 5f 54 4f 5f 50 47 48  ge = PAGE_TO_PGH
47c0: 44 52 31 28 70 43 61 63 68 65 2c 20 70 50 67 29  DR1(pCache, pPg)
47d0: 3b 0a 20 0a 20 20 61 73 73 65 72 74 28 20 70 50  ;. .  assert( pP
47e0: 61 67 65 2d 3e 70 43 61 63 68 65 3d 3d 70 43 61  age->pCache==pCa
47f0: 63 68 65 20 29 3b 0a 20 20 70 63 61 63 68 65 31  che );.  pcache1
4800: 45 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a 0a 20  EnterMutex();.. 
4810: 20 2f 2a 20 49 74 20 69 73 20 61 6e 20 65 72 72   /* It is an err
4820: 6f 72 20 74 6f 20 63 61 6c 6c 20 74 68 69 73 20  or to call this 
4830: 66 75 6e 63 74 69 6f 6e 20 69 66 20 74 68 65 20  function if the 
4840: 70 61 67 65 20 69 73 20 61 6c 72 65 61 64 79 20  page is already 
4850: 0a 20 20 2a 2a 20 70 61 72 74 20 6f 66 20 74 68  .  ** part of th
4860: 65 20 67 6c 6f 62 61 6c 20 4c 52 55 20 6c 69 73  e global LRU lis
4870: 74 2e 0a 20 20 2a 2f 0a 20 20 61 73 73 65 72 74  t..  */.  assert
4880: 28 20 70 50 61 67 65 2d 3e 70 4c 72 75 50 72 65  ( pPage->pLruPre
4890: 76 3d 3d 30 20 26 26 20 70 50 61 67 65 2d 3e 70  v==0 && pPage->p
48a0: 4c 72 75 4e 65 78 74 3d 3d 30 20 29 3b 0a 20 20  LruNext==0 );.  
48b0: 61 73 73 65 72 74 28 20 70 63 61 63 68 65 31 2e  assert( pcache1.
48c0: 70 4c 72 75 48 65 61 64 21 3d 70 50 61 67 65 20  pLruHead!=pPage 
48d0: 26 26 20 70 63 61 63 68 65 31 2e 70 4c 72 75 54  && pcache1.pLruT
48e0: 61 69 6c 21 3d 70 50 61 67 65 20 29 3b 0a 0a 20  ail!=pPage );.. 
48f0: 20 69 66 28 20 72 65 75 73 65 55 6e 6c 69 6b 65   if( reuseUnlike
4900: 6c 79 20 7c 7c 20 70 63 61 63 68 65 31 2e 6e 43  ly || pcache1.nC
4910: 75 72 72 65 6e 74 50 61 67 65 3e 70 63 61 63 68  urrentPage>pcach
4920: 65 31 2e 6e 4d 61 78 50 61 67 65 20 29 7b 0a 20  e1.nMaxPage ){. 
4930: 20 20 20 70 63 61 63 68 65 31 52 65 6d 6f 76 65     pcache1Remove
4940: 46 72 6f 6d 48 61 73 68 28 70 50 61 67 65 29 3b  FromHash(pPage);
4950: 0a 20 20 20 20 70 63 61 63 68 65 31 46 72 65 65  .    pcache1Free
4960: 50 61 67 65 28 70 50 61 67 65 29 3b 0a 20 20 7d  Page(pPage);.  }
4970: 65 6c 73 65 7b 0a 20 20 20 20 2f 2a 20 41 64 64  else{.    /* Add
4980: 20 74 68 65 20 70 61 67 65 20 74 6f 20 74 68 65   the page to the
4990: 20 67 6c 6f 62 61 6c 20 4c 52 55 20 6c 69 73 74   global LRU list
49a0: 2e 20 4e 6f 72 6d 61 6c 6c 79 2c 20 74 68 65 20  . Normally, the 
49b0: 70 61 67 65 20 69 73 20 61 64 64 65 64 20 74 6f  page is added to
49c0: 0a 20 20 20 20 2a 2a 20 74 68 65 20 68 65 61 64  .    ** the head
49d0: 20 6f 66 20 74 68 65 20 6c 69 73 74 20 28 6c 61   of the list (la
49e0: 73 74 20 70 61 67 65 20 74 6f 20 62 65 20 72 65  st page to be re
49f0: 63 79 63 6c 65 64 29 2e 20 48 6f 77 65 76 65 72  cycled). However
4a00: 2c 20 69 66 20 74 68 65 20 0a 20 20 20 20 2a 2a  , if the .    **
4a10: 20 72 65 75 73 65 55 6e 6c 69 6b 65 6c 79 20 66   reuseUnlikely f
4a20: 6c 61 67 20 70 61 73 73 65 64 20 74 6f 20 74 68  lag passed to th
4a30: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 74  is function is t
4a40: 72 75 65 2c 20 74 68 65 20 70 61 67 65 20 69 73  rue, the page is
4a50: 20 61 64 64 65 64 0a 20 20 20 20 2a 2a 20 74 6f   added.    ** to
4a60: 20 74 68 65 20 74 61 69 6c 20 6f 66 20 74 68 65   the tail of the
4a70: 20 6c 69 73 74 20 28 66 69 72 73 74 20 70 61 67   list (first pag
4a80: 65 20 74 6f 20 62 65 20 72 65 63 79 63 6c 65 64  e to be recycled
4a90: 29 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 69 66  )..    */.    if
4aa0: 28 20 70 63 61 63 68 65 31 2e 70 4c 72 75 48 65  ( pcache1.pLruHe
4ab0: 61 64 20 29 7b 0a 20 20 20 20 20 20 70 63 61 63  ad ){.      pcac
4ac0: 68 65 31 2e 70 4c 72 75 48 65 61 64 2d 3e 70 4c  he1.pLruHead->pL
4ad0: 72 75 50 72 65 76 20 3d 20 70 50 61 67 65 3b 0a  ruPrev = pPage;.
4ae0: 20 20 20 20 20 20 70 50 61 67 65 2d 3e 70 4c 72        pPage->pLr
4af0: 75 4e 65 78 74 20 3d 20 70 63 61 63 68 65 31 2e  uNext = pcache1.
4b00: 70 4c 72 75 48 65 61 64 3b 0a 20 20 20 20 20 20  pLruHead;.      
4b10: 70 63 61 63 68 65 31 2e 70 4c 72 75 48 65 61 64  pcache1.pLruHead
4b20: 20 3d 20 70 50 61 67 65 3b 0a 20 20 20 20 7d 65   = pPage;.    }e
4b30: 6c 73 65 7b 0a 20 20 20 20 20 20 70 63 61 63 68  lse{.      pcach
4b40: 65 31 2e 70 4c 72 75 54 61 69 6c 20 3d 20 70 50  e1.pLruTail = pP
4b50: 61 67 65 3b 0a 20 20 20 20 20 20 70 63 61 63 68  age;.      pcach
4b60: 65 31 2e 70 4c 72 75 48 65 61 64 20 3d 20 70 50  e1.pLruHead = pP
4b70: 61 67 65 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70  age;.    }.    p
4b80: 43 61 63 68 65 2d 3e 6e 52 65 63 79 63 6c 61 62  Cache->nRecyclab
4b90: 6c 65 2b 2b 3b 0a 20 20 7d 0a 0a 20 20 70 63 61  le++;.  }..  pca
4ba0: 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 29  che1LeaveMutex()
4bb0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65  ;.}../*.** Imple
4bc0: 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65  mentation of the
4bd0: 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e   sqlite3_pcache.
4be0: 78 52 65 6b 65 79 20 6d 65 74 68 6f 64 2e 20 0a  xRekey method. .
4bf0: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70  */.static void p
4c00: 63 61 63 68 65 31 52 65 6b 65 79 28 0a 20 20 73  cache1Rekey(.  s
4c10: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70  qlite3_pcache *p
4c20: 2c 0a 20 20 76 6f 69 64 20 2a 70 50 67 2c 0a 20  ,.  void *pPg,. 
4c30: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4f   unsigned int iO
4c40: 6c 64 2c 0a 20 20 75 6e 73 69 67 6e 65 64 20 69  ld,.  unsigned i
4c50: 6e 74 20 69 4e 65 77 0a 29 7b 0a 20 20 50 43 61  nt iNew.){.  PCa
4c60: 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28  che1 *pCache = (
4c70: 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20 20 50  PCache1 *)p;.  P
4c80: 67 48 64 72 31 20 2a 70 50 61 67 65 20 3d 20 50  gHdr1 *pPage = P
4c90: 41 47 45 5f 54 4f 5f 50 47 48 44 52 31 28 70 43  AGE_TO_PGHDR1(pC
4ca0: 61 63 68 65 2c 20 70 50 67 29 3b 0a 20 20 50 67  ache, pPg);.  Pg
4cb0: 48 64 72 31 20 2a 2a 70 70 3b 0a 20 20 75 6e 73  Hdr1 **pp;.  uns
4cc0: 69 67 6e 65 64 20 69 6e 74 20 68 3b 20 0a 20 20  igned int h; .  
4cd0: 61 73 73 65 72 74 28 20 70 50 61 67 65 2d 3e 69  assert( pPage->i
4ce0: 4b 65 79 3d 3d 69 4f 6c 64 20 29 3b 0a 20 20 61  Key==iOld );.  a
4cf0: 73 73 65 72 74 28 20 70 50 61 67 65 2d 3e 70 43  ssert( pPage->pC
4d00: 61 63 68 65 3d 3d 70 43 61 63 68 65 20 29 3b 0a  ache==pCache );.
4d10: 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d  .  pcache1EnterM
4d20: 75 74 65 78 28 29 3b 0a 0a 20 20 68 20 3d 20 69  utex();..  h = i
4d30: 4f 6c 64 25 70 43 61 63 68 65 2d 3e 6e 48 61 73  Old%pCache->nHas
4d40: 68 3b 0a 20 20 70 70 20 3d 20 26 70 43 61 63 68  h;.  pp = &pCach
4d50: 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 0a 20 20  e->apHash[h];.  
4d60: 77 68 69 6c 65 28 20 28 2a 70 70 29 21 3d 70 50  while( (*pp)!=pP
4d70: 61 67 65 20 29 7b 0a 20 20 20 20 70 70 20 3d 20  age ){.    pp = 
4d80: 26 28 2a 70 70 29 2d 3e 70 4e 65 78 74 3b 0a 20  &(*pp)->pNext;. 
4d90: 20 7d 0a 20 20 2a 70 70 20 3d 20 70 50 61 67 65   }.  *pp = pPage
4da0: 2d 3e 70 4e 65 78 74 3b 0a 0a 20 20 68 20 3d 20  ->pNext;..  h = 
4db0: 69 4e 65 77 25 70 43 61 63 68 65 2d 3e 6e 48 61  iNew%pCache->nHa
4dc0: 73 68 3b 0a 20 20 70 50 61 67 65 2d 3e 69 4b 65  sh;.  pPage->iKe
4dd0: 79 20 3d 20 69 4e 65 77 3b 0a 20 20 70 50 61 67  y = iNew;.  pPag
4de0: 65 2d 3e 70 4e 65 78 74 20 3d 20 70 43 61 63 68  e->pNext = pCach
4df0: 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 0a 20 20  e->apHash[h];.  
4e00: 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68  pCache->apHash[h
4e10: 5d 20 3d 20 70 50 61 67 65 3b 0a 0a 20 20 69 66  ] = pPage;..  if
4e20: 28 20 69 4e 65 77 3e 70 43 61 63 68 65 2d 3e 69  ( iNew>pCache->i
4e30: 4d 61 78 4b 65 79 20 29 7b 0a 20 20 20 20 70 43  MaxKey ){.    pC
4e40: 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 3d 20  ache->iMaxKey = 
4e50: 69 4e 65 77 3b 0a 20 20 7d 0a 0a 20 20 70 63 61  iNew;.  }..  pca
4e60: 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 29  che1LeaveMutex()
4e70: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65  ;.}../*.** Imple
4e80: 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65  mentation of the
4e90: 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e   sqlite3_pcache.
4ea0: 78 54 72 75 6e 63 61 74 65 20 6d 65 74 68 6f 64  xTruncate method
4eb0: 2e 20 0a 2a 2a 0a 2a 2a 20 44 69 73 63 61 72 64  . .**.** Discard
4ec0: 20 61 6c 6c 20 75 6e 70 69 6e 6e 65 64 20 70 61   all unpinned pa
4ed0: 67 65 73 20 69 6e 20 74 68 65 20 63 61 63 68 65  ges in the cache
4ee0: 20 77 69 74 68 20 61 20 70 61 67 65 20 6e 75 6d   with a page num
4ef0: 62 65 72 20 65 71 75 61 6c 20 74 6f 0a 2a 2a 20  ber equal to.** 
4f00: 6f 72 20 67 72 65 61 74 65 72 20 74 68 61 6e 20  or greater than 
4f10: 70 61 72 61 6d 65 74 65 72 20 69 4c 69 6d 69 74  parameter iLimit
4f20: 2e 20 41 6e 79 20 70 69 6e 6e 65 64 20 70 61 67  . Any pinned pag
4f30: 65 73 20 77 69 74 68 20 61 20 70 61 67 65 20 6e  es with a page n
4f40: 75 6d 62 65 72 0a 2a 2a 20 65 71 75 61 6c 20 74  umber.** equal t
4f50: 6f 20 6f 72 20 67 72 65 61 74 65 72 20 74 68 61  o or greater tha
4f60: 6e 20 69 4c 69 6d 69 74 20 61 72 65 20 69 6d 70  n iLimit are imp
4f70: 6c 69 63 69 74 6c 79 20 75 6e 70 69 6e 6e 65 64  licitly unpinned
4f80: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
4f90: 20 70 63 61 63 68 65 31 54 72 75 6e 63 61 74 65   pcache1Truncate
4fa0: 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20  (sqlite3_pcache 
4fb0: 2a 70 2c 20 75 6e 73 69 67 6e 65 64 20 69 6e 74  *p, unsigned int
4fc0: 20 69 4c 69 6d 69 74 29 7b 0a 20 20 50 43 61 63   iLimit){.  PCac
4fd0: 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28 50  he1 *pCache = (P
4fe0: 43 61 63 68 65 31 20 2a 29 70 3b 0a 20 20 70 63  Cache1 *)p;.  pc
4ff0: 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28  ache1EnterMutex(
5000: 29 3b 0a 20 20 69 66 28 20 69 4c 69 6d 69 74 3c  );.  if( iLimit<
5010: 3d 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79  =pCache->iMaxKey
5020: 20 29 7b 0a 20 20 20 20 70 63 61 63 68 65 31 54   ){.    pcache1T
5030: 72 75 6e 63 61 74 65 55 6e 73 61 66 65 28 70 43  runcateUnsafe(pC
5040: 61 63 68 65 2c 20 69 4c 69 6d 69 74 29 3b 0a 20  ache, iLimit);. 
5050: 20 20 20 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b     pCache->iMaxK
5060: 65 79 20 3d 20 69 4c 69 6d 69 74 2d 31 3b 0a 20  ey = iLimit-1;. 
5070: 20 7d 0a 20 20 70 63 61 63 68 65 31 4c 65 61 76   }.  pcache1Leav
5080: 65 4d 75 74 65 78 28 29 3b 0a 7d 0a 0a 2f 2a 0a  eMutex();.}../*.
5090: 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  ** Implementatio
50a0: 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33  n of the sqlite3
50b0: 5f 70 63 61 63 68 65 2e 78 44 65 73 74 72 6f 79  _pcache.xDestroy
50c0: 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20   method. .**.** 
50d0: 44 65 73 74 72 6f 79 20 61 20 63 61 63 68 65 20  Destroy a cache 
50e0: 61 6c 6c 6f 63 61 74 65 64 20 75 73 69 6e 67 20  allocated using 
50f0: 70 63 61 63 68 65 31 43 72 65 61 74 65 28 29 2e  pcache1Create().
5100: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
5110: 70 63 61 63 68 65 31 44 65 73 74 72 6f 79 28 73  pcache1Destroy(s
5120: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70  qlite3_pcache *p
5130: 29 7b 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43  ){.  PCache1 *pC
5140: 61 63 68 65 20 3d 20 28 50 43 61 63 68 65 31 20  ache = (PCache1 
5150: 2a 29 70 3b 0a 20 20 70 63 61 63 68 65 31 45 6e  *)p;.  pcache1En
5160: 74 65 72 4d 75 74 65 78 28 29 3b 0a 20 20 70 63  terMutex();.  pc
5170: 61 63 68 65 31 54 72 75 6e 63 61 74 65 55 6e 73  ache1TruncateUns
5180: 61 66 65 28 70 43 61 63 68 65 2c 20 30 29 3b 0a  afe(pCache, 0);.
5190: 20 20 70 63 61 63 68 65 31 2e 6e 4d 61 78 50 61    pcache1.nMaxPa
51a0: 67 65 20 2d 3d 20 70 43 61 63 68 65 2d 3e 6e 4d  ge -= pCache->nM
51b0: 61 78 3b 0a 20 20 70 63 61 63 68 65 31 2e 6e 4d  ax;.  pcache1.nM
51c0: 69 6e 50 61 67 65 20 2d 3d 20 70 43 61 63 68 65  inPage -= pCache
51d0: 2d 3e 6e 4d 69 6e 3b 0a 20 20 70 63 61 63 68 65  ->nMin;.  pcache
51e0: 31 45 6e 66 6f 72 63 65 4d 61 78 50 61 67 65 28  1EnforceMaxPage(
51f0: 29 3b 0a 20 20 70 63 61 63 68 65 31 4c 65 61 76  );.  pcache1Leav
5200: 65 4d 75 74 65 78 28 29 3b 0a 20 20 73 71 6c 69  eMutex();.  sqli
5210: 74 65 33 5f 66 72 65 65 28 70 43 61 63 68 65 2d  te3_free(pCache-
5220: 3e 61 70 48 61 73 68 29 3b 0a 20 20 73 71 6c 69  >apHash);.  sqli
5230: 74 65 33 5f 66 72 65 65 28 70 43 61 63 68 65 29  te3_free(pCache)
5240: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  ;.}../*.** This 
5250: 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c  function is call
5260: 65 64 20 64 75 72 69 6e 67 20 69 6e 69 74 69 61  ed during initia
5270: 6c 69 7a 61 74 69 6f 6e 20 28 73 71 6c 69 74 65  lization (sqlite
5280: 33 5f 69 6e 69 74 69 61 6c 69 7a 65 28 29 29 20  3_initialize()) 
5290: 74 6f 0a 2a 2a 20 69 6e 73 74 61 6c 6c 20 74 68  to.** install th
52a0: 65 20 64 65 66 61 75 6c 74 20 70 6c 75 67 67 61  e default plugga
52b0: 62 6c 65 20 63 61 63 68 65 20 6d 6f 64 75 6c 65  ble cache module
52c0: 2c 20 61 73 73 75 6d 69 6e 67 20 74 68 65 20 75  , assuming the u
52d0: 73 65 72 20 68 61 73 20 6e 6f 74 0a 2a 2a 20 61  ser has not.** a
52e0: 6c 72 65 61 64 79 20 70 72 6f 76 69 64 65 64 20  lready provided 
52f0: 61 6e 20 61 6c 74 65 72 6e 61 74 69 76 65 2e 0a  an alternative..
5300: 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50  */.void sqlite3P
5310: 43 61 63 68 65 53 65 74 44 65 66 61 75 6c 74 28  CacheSetDefault(
5320: 76 6f 69 64 29 7b 0a 20 20 73 74 61 74 69 63 20  void){.  static 
5330: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 5f 6d  sqlite3_pcache_m
5340: 65 74 68 6f 64 73 20 64 65 66 61 75 6c 74 4d 65  ethods defaultMe
5350: 74 68 6f 64 73 20 3d 20 7b 0a 20 20 20 20 30 2c  thods = {.    0,
5360: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5370: 20 20 20 20 20 20 20 2f 2a 20 70 41 72 67 20 2a         /* pArg *
5380: 2f 0a 20 20 20 20 70 63 61 63 68 65 31 49 6e 69  /.    pcache1Ini
5390: 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  t,             /
53a0: 2a 20 78 49 6e 69 74 20 2a 2f 0a 20 20 20 20 70  * xInit */.    p
53b0: 63 61 63 68 65 31 53 68 75 74 64 6f 77 6e 2c 20  cache1Shutdown, 
53c0: 20 20 20 20 20 20 20 20 2f 2a 20 78 53 68 75 74          /* xShut
53d0: 64 6f 77 6e 20 2a 2f 0a 20 20 20 20 70 63 61 63  down */.    pcac
53e0: 68 65 31 43 72 65 61 74 65 2c 20 20 20 20 20 20  he1Create,      
53f0: 20 20 20 20 20 2f 2a 20 78 43 72 65 61 74 65 20       /* xCreate 
5400: 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31 43 61  */.    pcache1Ca
5410: 63 68 65 73 69 7a 65 2c 20 20 20 20 20 20 20 20  chesize,        
5420: 2f 2a 20 78 43 61 63 68 65 73 69 7a 65 20 2a 2f  /* xCachesize */
5430: 0a 20 20 20 20 70 63 61 63 68 65 31 50 61 67 65  .    pcache1Page
5440: 63 6f 75 6e 74 2c 20 20 20 20 20 20 20 20 2f 2a  count,        /*
5450: 20 78 50 61 67 65 63 6f 75 6e 74 20 2a 2f 0a 20   xPagecount */. 
5460: 20 20 20 70 63 61 63 68 65 31 46 65 74 63 68 2c     pcache1Fetch,
5470: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
5480: 46 65 74 63 68 20 2a 2f 0a 20 20 20 20 70 63 61  Fetch */.    pca
5490: 63 68 65 31 55 6e 70 69 6e 2c 20 20 20 20 20 20  che1Unpin,      
54a0: 20 20 20 20 20 20 2f 2a 20 78 55 6e 70 69 6e 20        /* xUnpin 
54b0: 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31 52 65  */.    pcache1Re
54c0: 6b 65 79 2c 20 20 20 20 20 20 20 20 20 20 20 20  key,            
54d0: 2f 2a 20 78 52 65 6b 65 79 20 2a 2f 0a 20 20 20  /* xRekey */.   
54e0: 20 70 63 61 63 68 65 31 54 72 75 6e 63 61 74 65   pcache1Truncate
54f0: 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 78 54 72  ,         /* xTr
5500: 75 6e 63 61 74 65 20 2a 2f 0a 20 20 20 20 70 63  uncate */.    pc
5510: 61 63 68 65 31 44 65 73 74 72 6f 79 20 20 20 20  ache1Destroy    
5520: 20 20 20 20 20 20 20 2f 2a 20 78 44 65 73 74 72         /* xDestr
5530: 6f 79 20 2a 2f 0a 20 20 7d 3b 0a 20 20 73 71 6c  oy */.  };.  sql
5540: 69 74 65 33 5f 63 6f 6e 66 69 67 28 53 51 4c 49  ite3_config(SQLI
5550: 54 45 5f 43 4f 4e 46 49 47 5f 50 43 41 43 48 45  TE_CONFIG_PCACHE
5560: 2c 20 26 64 65 66 61 75 6c 74 4d 65 74 68 6f 64  , &defaultMethod
5570: 73 29 3b 0a 7d 0a 0a 23 69 66 64 65 66 20 53 51  s);.}..#ifdef SQ
5580: 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f  LITE_ENABLE_MEMO
5590: 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 0a 2f 2a  RY_MANAGEMENT./*
55a0: 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
55b0: 6e 20 69 73 20 63 61 6c 6c 65 64 20 74 6f 20 66  n is called to f
55c0: 72 65 65 20 73 75 70 65 72 66 6c 75 6f 75 73 20  ree superfluous 
55d0: 64 79 6e 61 6d 69 63 61 6c 6c 79 20 61 6c 6c 6f  dynamically allo
55e0: 63 61 74 65 64 20 6d 65 6d 6f 72 79 0a 2a 2a 20  cated memory.** 
55f0: 68 65 6c 64 20 62 79 20 74 68 65 20 70 61 67 65  held by the page
5600: 72 20 73 79 73 74 65 6d 2e 20 4d 65 6d 6f 72 79  r system. Memory
5610: 20 69 6e 20 75 73 65 20 62 79 20 61 6e 79 20 53   in use by any S
5620: 51 4c 69 74 65 20 70 61 67 65 72 20 61 6c 6c 6f  QLite pager allo
5630: 63 61 74 65 64 0a 2a 2a 20 62 79 20 74 68 65 20  cated.** by the 
5640: 63 75 72 72 65 6e 74 20 74 68 72 65 61 64 20 6d  current thread m
5650: 61 79 20 62 65 20 73 71 6c 69 74 65 33 5f 66 72  ay be sqlite3_fr
5660: 65 65 28 29 65 64 2e 0a 2a 2a 0a 2a 2a 20 6e 52  ee()ed..**.** nR
5670: 65 71 20 69 73 20 74 68 65 20 6e 75 6d 62 65 72  eq is the number
5680: 20 6f 66 20 62 79 74 65 73 20 6f 66 20 6d 65 6d   of bytes of mem
5690: 6f 72 79 20 72 65 71 75 69 72 65 64 2e 20 4f 6e  ory required. On
56a0: 63 65 20 74 68 69 73 20 6d 75 63 68 20 68 61 73  ce this much has
56b0: 0a 2a 2a 20 62 65 65 6e 20 72 65 6c 65 61 73 65  .** been release
56c0: 64 2c 20 74 68 65 20 66 75 6e 63 74 69 6f 6e 20  d, the function 
56d0: 72 65 74 75 72 6e 73 2e 20 54 68 65 20 72 65 74  returns. The ret
56e0: 75 72 6e 20 76 61 6c 75 65 20 69 73 20 74 68 65  urn value is the
56f0: 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 0a 2a   total number .*
5700: 2a 20 6f 66 20 62 79 74 65 73 20 6f 66 20 6d 65  * of bytes of me
5710: 6d 6f 72 79 20 72 65 6c 65 61 73 65 64 2e 0a 2a  mory released..*
5720: 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 50 63 61  /.int sqlite3Pca
5730: 63 68 65 52 65 6c 65 61 73 65 4d 65 6d 6f 72 79  cheReleaseMemory
5740: 28 69 6e 74 20 6e 52 65 71 29 7b 0a 20 20 69 6e  (int nReq){.  in
5750: 74 20 6e 46 72 65 65 20 3d 20 30 3b 0a 20 20 69  t nFree = 0;.  i
5760: 66 28 20 70 63 61 63 68 65 31 2e 70 53 74 61 72  f( pcache1.pStar
5770: 74 3d 3d 30 20 29 7b 0a 20 20 20 20 50 67 48 64  t==0 ){.    PgHd
5780: 72 31 20 2a 70 3b 0a 20 20 20 20 70 63 61 63 68  r1 *p;.    pcach
5790: 65 31 45 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a  e1EnterMutex();.
57a0: 20 20 20 20 77 68 69 6c 65 28 20 28 6e 52 65 71      while( (nReq
57b0: 3c 30 20 7c 7c 20 6e 46 72 65 65 3c 6e 52 65 71  <0 || nFree<nReq
57c0: 29 20 26 26 20 28 70 3d 70 63 61 63 68 65 31 2e  ) && (p=pcache1.
57d0: 70 4c 72 75 54 61 69 6c 29 20 29 7b 0a 20 20 20  pLruTail) ){.   
57e0: 20 20 20 6e 46 72 65 65 20 2b 3d 20 73 71 6c 69     nFree += sqli
57f0: 74 65 33 4d 61 6c 6c 6f 63 53 69 7a 65 28 50 47  te3MallocSize(PG
5800: 48 44 52 31 5f 54 4f 5f 50 41 47 45 28 70 29 29  HDR1_TO_PAGE(p))
5810: 3b 0a 20 20 20 20 20 20 70 63 61 63 68 65 31 50  ;.      pcache1P
5820: 69 6e 50 61 67 65 28 70 29 3b 0a 20 20 20 20 20  inPage(p);.     
5830: 20 70 63 61 63 68 65 31 52 65 6d 6f 76 65 46 72   pcache1RemoveFr
5840: 6f 6d 48 61 73 68 28 70 29 3b 0a 20 20 20 20 20  omHash(p);.     
5850: 20 70 63 61 63 68 65 31 46 72 65 65 50 61 67 65   pcache1FreePage
5860: 28 70 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70  (p);.    }.    p
5870: 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78  cache1LeaveMutex
5880: 28 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  ();.  }.  return
5890: 20 6e 46 72 65 65 3b 0a 7d 0a 23 65 6e 64 69 66   nFree;.}.#endif
58a0: 20 2f 2a 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c   /* SQLITE_ENABL
58b0: 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d  E_MEMORY_MANAGEM
58c0: 45 4e 54 20 2a 2f 0a 0a 23 69 66 64 65 66 20 53  ENT */..#ifdef S
58d0: 51 4c 49 54 45 5f 54 45 53 54 0a 2f 2a 0a 2a 2a  QLITE_TEST./*.**
58e0: 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   This function i
58f0: 73 20 75 73 65 64 20 62 79 20 74 65 73 74 20 70  s used by test p
5900: 72 6f 63 65 64 75 72 65 73 20 74 6f 20 69 6e 73  rocedures to ins
5910: 70 65 63 74 20 74 68 65 20 69 6e 74 65 72 6e 61  pect the interna
5920: 6c 20 73 74 61 74 65 0a 2a 2a 20 6f 66 20 74 68  l state.** of th
5930: 65 20 67 6c 6f 62 61 6c 20 63 61 63 68 65 2e 0a  e global cache..
5940: 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50  */.void sqlite3P
5950: 63 61 63 68 65 53 74 61 74 73 28 0a 20 20 69 6e  cacheStats(.  in
5960: 74 20 2a 70 6e 43 75 72 72 65 6e 74 2c 20 20 20  t *pnCurrent,   
5970: 20 20 20 2f 2a 20 4f 55 54 3a 20 54 6f 74 61 6c     /* OUT: Total
5980: 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73   number of pages
5990: 20 63 61 63 68 65 64 20 2a 2f 0a 20 20 69 6e 74   cached */.  int
59a0: 20 2a 70 6e 4d 61 78 2c 20 20 20 20 20 20 20 20   *pnMax,        
59b0: 20 20 2f 2a 20 4f 55 54 3a 20 47 6c 6f 62 61 6c    /* OUT: Global
59c0: 20 6d 61 78 69 6d 75 6d 20 63 61 63 68 65 20 73   maximum cache s
59d0: 69 7a 65 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e  ize */.  int *pn
59e0: 4d 69 6e 2c 20 20 20 20 20 20 20 20 20 20 2f 2a  Min,          /*
59f0: 20 4f 55 54 3a 20 53 75 6d 20 6f 66 20 50 43 61   OUT: Sum of PCa
5a00: 63 68 65 31 2e 6e 4d 69 6e 20 66 6f 72 20 70 75  che1.nMin for pu
5a10: 72 67 65 61 62 6c 65 20 63 61 63 68 65 73 20 2a  rgeable caches *
5a20: 2f 0a 20 20 69 6e 74 20 2a 70 6e 52 65 63 79 63  /.  int *pnRecyc
5a30: 6c 61 62 6c 65 20 20 20 20 2f 2a 20 4f 55 54 3a  lable    /* OUT:
5a40: 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66   Total number of
5a50: 20 70 61 67 65 73 20 61 76 61 69 6c 61 62 6c 65   pages available
5a60: 20 66 6f 72 20 72 65 63 79 63 6c 69 6e 67 20 2a   for recycling *
5a70: 2f 0a 29 7b 0a 20 20 50 67 48 64 72 31 20 2a 70  /.){.  PgHdr1 *p
5a80: 3b 0a 20 20 69 6e 74 20 6e 52 65 63 79 63 6c 61  ;.  int nRecycla
5a90: 62 6c 65 20 3d 20 30 3b 0a 20 20 66 6f 72 28 70  ble = 0;.  for(p
5aa0: 3d 70 63 61 63 68 65 31 2e 70 4c 72 75 48 65 61  =pcache1.pLruHea
5ab0: 64 3b 20 70 3b 20 70 3d 70 2d 3e 70 4c 72 75 4e  d; p; p=p->pLruN
5ac0: 65 78 74 29 7b 0a 20 20 20 20 6e 52 65 63 79 63  ext){.    nRecyc
5ad0: 6c 61 62 6c 65 2b 2b 3b 0a 20 20 7d 0a 20 20 2a  lable++;.  }.  *
5ae0: 70 6e 43 75 72 72 65 6e 74 20 3d 20 70 63 61 63  pnCurrent = pcac
5af0: 68 65 31 2e 6e 43 75 72 72 65 6e 74 50 61 67 65  he1.nCurrentPage
5b00: 3b 0a 20 20 2a 70 6e 4d 61 78 20 3d 20 70 63 61  ;.  *pnMax = pca
5b10: 63 68 65 31 2e 6e 4d 61 78 50 61 67 65 3b 0a 20  che1.nMaxPage;. 
5b20: 20 2a 70 6e 4d 69 6e 20 3d 20 70 63 61 63 68 65   *pnMin = pcache
5b30: 31 2e 6e 4d 69 6e 50 61 67 65 3b 0a 20 20 2a 70  1.nMinPage;.  *p
5b40: 6e 52 65 63 79 63 6c 61 62 6c 65 20 3d 20 6e 52  nRecyclable = nR
5b50: 65 63 79 63 6c 61 62 6c 65 3b 0a 7d 0a 23 65 6e  ecyclable;.}.#en
5b60: 64 69 66 0a                                      dif.