/ Hex Artifact Content
Login

Artifact e9578a3beac26f229ee558a4e16c863f2498185f:


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 2f  re available..*/
02c0: 0a 0a 23 69 6e 63 6c 75 64 65 20 22 73 71 6c 69  ..#include "sqli
02d0: 74 65 49 6e 74 2e 68 22 0a 0a 74 79 70 65 64 65  teInt.h"..typede
02e0: 66 20 73 74 72 75 63 74 20 50 43 61 63 68 65 31  f struct PCache1
02f0: 20 50 43 61 63 68 65 31 3b 0a 74 79 70 65 64 65   PCache1;.typede
0300: 66 20 73 74 72 75 63 74 20 50 67 48 64 72 31 20  f struct PgHdr1 
0310: 50 67 48 64 72 31 3b 0a 74 79 70 65 64 65 66 20  PgHdr1;.typedef 
0320: 73 74 72 75 63 74 20 50 67 46 72 65 65 73 6c 6f  struct PgFreeslo
0330: 74 20 50 67 46 72 65 65 73 6c 6f 74 3b 0a 0a 2f  t PgFreeslot;../
0340: 2a 20 45 61 63 68 20 70 61 67 65 20 63 61 63 68  * Each page cach
0350: 65 20 69 73 20 61 6e 20 69 6e 73 74 61 6e 63 65  e is an instance
0360: 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e   of the followin
0370: 67 20 6f 62 6a 65 63 74 2e 20 20 45 76 65 72 79  g object.  Every
0380: 0a 2a 2a 20 6f 70 65 6e 20 64 61 74 61 62 61 73  .** open databas
0390: 65 20 66 69 6c 65 20 28 69 6e 63 6c 75 64 69 6e  e file (includin
03a0: 67 20 65 61 63 68 20 69 6e 2d 6d 65 6d 6f 72 79  g each in-memory
03b0: 20 64 61 74 61 62 61 73 65 20 61 6e 64 20 65 61   database and ea
03c0: 63 68 0a 2a 2a 20 74 65 6d 70 6f 72 61 72 79 20  ch.** temporary 
03d0: 6f 72 20 74 72 61 6e 73 69 65 6e 74 20 64 61 74  or transient dat
03e0: 61 62 61 73 65 29 20 68 61 73 20 61 20 73 69 6e  abase) has a sin
03f0: 67 6c 65 20 70 61 67 65 20 63 61 63 68 65 20 77  gle page cache w
0400: 68 69 63 68 0a 2a 2a 20 69 73 20 61 6e 20 69 6e  hich.** is an in
0410: 73 74 61 6e 63 65 20 6f 66 20 74 68 69 73 20 6f  stance of this o
0420: 62 6a 65 63 74 2e 0a 2a 2a 0a 2a 2a 20 50 6f 69  bject..**.** Poi
0430: 6e 74 65 72 73 20 74 6f 20 73 74 72 75 63 74 75  nters to structu
0440: 72 65 73 20 6f 66 20 74 68 69 73 20 74 79 70 65  res of this type
0450: 20 61 72 65 20 63 61 73 74 20 61 6e 64 20 72 65   are cast and re
0460: 74 75 72 6e 65 64 20 61 73 20 0a 2a 2a 20 6f 70  turned as .** op
0470: 61 71 75 65 20 73 71 6c 69 74 65 33 5f 70 63 61  aque sqlite3_pca
0480: 63 68 65 2a 20 68 61 6e 64 6c 65 73 2e 0a 2a 2f  che* handles..*/
0490: 0a 73 74 72 75 63 74 20 50 43 61 63 68 65 31 20  .struct PCache1 
04a0: 7b 0a 20 20 2f 2a 20 43 61 63 68 65 20 63 6f 6e  {.  /* Cache con
04b0: 66 69 67 75 72 61 74 69 6f 6e 20 70 61 72 61 6d  figuration param
04c0: 65 74 65 72 73 2e 20 50 61 67 65 20 73 69 7a 65  eters. Page size
04d0: 20 28 73 7a 50 61 67 65 29 20 61 6e 64 20 74 68   (szPage) and th
04e0: 65 20 70 75 72 67 65 61 62 6c 65 0a 20 20 2a 2a  e purgeable.  **
04f0: 20 66 6c 61 67 20 28 62 50 75 72 67 65 61 62 6c   flag (bPurgeabl
0500: 65 29 20 61 72 65 20 73 65 74 20 77 68 65 6e 20  e) are set when 
0510: 74 68 65 20 63 61 63 68 65 20 69 73 20 63 72 65  the cache is cre
0520: 61 74 65 64 2e 20 6e 4d 61 78 20 6d 61 79 20 62  ated. nMax may b
0530: 65 20 0a 20 20 2a 2a 20 6d 6f 64 69 66 69 65 64  e .  ** modified
0540: 20 61 74 20 61 6e 79 20 74 69 6d 65 20 62 79 20   at any time by 
0550: 61 20 63 61 6c 6c 20 74 6f 20 74 68 65 20 70 63  a call to the pc
0560: 61 63 68 65 31 43 61 63 68 65 53 69 7a 65 28 29  ache1CacheSize()
0570: 20 6d 65 74 68 6f 64 2e 0a 20 20 2a 2a 20 54 68   method..  ** Th
0580: 65 20 67 6c 6f 62 61 6c 20 6d 75 74 65 78 20 6d  e global mutex m
0590: 75 73 74 20 62 65 20 68 65 6c 64 20 77 68 65 6e  ust be held when
05a0: 20 61 63 63 65 73 73 69 6e 67 20 6e 4d 61 78 2e   accessing nMax.
05b0: 0a 20 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 50 61  .  */.  int szPa
05c0: 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ge;             
05d0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
05e0: 69 7a 65 20 6f 66 20 61 6c 6c 6f 63 61 74 65 64  ize of allocated
05f0: 20 70 61 67 65 73 20 69 6e 20 62 79 74 65 73 20   pages in bytes 
0600: 2a 2f 0a 20 20 69 6e 74 20 62 50 75 72 67 65 61  */.  int bPurgea
0610: 62 6c 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  ble;            
0620: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
0630: 20 69 66 20 63 61 63 68 65 20 69 73 20 70 75 72   if cache is pur
0640: 67 65 61 62 6c 65 20 2a 2f 0a 20 20 75 6e 73 69  geable */.  unsi
0650: 67 6e 65 64 20 69 6e 74 20 6e 4d 69 6e 3b 20 20  gned int nMin;  
0660: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0670: 2f 2a 20 4d 69 6e 69 6d 75 6d 20 6e 75 6d 62 65  /* Minimum numbe
0680: 72 20 6f 66 20 70 61 67 65 73 20 72 65 73 65 72  r of pages reser
0690: 76 65 64 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65  ved */.  unsigne
06a0: 64 20 69 6e 74 20 6e 4d 61 78 3b 20 20 20 20 20  d int nMax;     
06b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
06c0: 43 6f 6e 66 69 67 75 72 65 64 20 22 63 61 63 68  Configured "cach
06d0: 65 5f 73 69 7a 65 22 20 76 61 6c 75 65 20 2a 2f  e_size" value */
06e0: 0a 0a 20 20 2f 2a 20 48 61 73 68 20 74 61 62 6c  ..  /* Hash tabl
06f0: 65 20 6f 66 20 61 6c 6c 20 70 61 67 65 73 2e 20  e of all pages. 
0700: 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 76 61  The following va
0710: 72 69 61 62 6c 65 73 20 6d 61 79 20 6f 6e 6c 79  riables may only
0720: 20 62 65 20 61 63 63 65 73 73 65 64 0a 20 20 2a   be accessed.  *
0730: 2a 20 77 68 65 6e 20 74 68 65 20 61 63 63 65 73  * when the acces
0740: 73 6f 72 20 69 73 20 68 6f 6c 64 69 6e 67 20 74  sor is holding t
0750: 68 65 20 67 6c 6f 62 61 6c 20 6d 75 74 65 78 20  he global mutex 
0760: 28 73 65 65 20 70 63 61 63 68 65 31 45 6e 74 65  (see pcache1Ente
0770: 72 4d 75 74 65 78 28 29 20 0a 20 20 2a 2a 20 61  rMutex() .  ** a
0780: 6e 64 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d  nd pcache1LeaveM
0790: 75 74 65 78 28 29 29 2e 0a 20 20 2a 2f 0a 20 20  utex())..  */.  
07a0: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 52 65  unsigned int nRe
07b0: 63 79 63 6c 61 62 6c 65 3b 20 20 20 20 20 20 20  cyclable;       
07c0: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
07d0: 20 70 61 67 65 73 20 69 6e 20 74 68 65 20 4c 52   pages in the LR
07e0: 55 20 6c 69 73 74 20 2a 2f 0a 20 20 75 6e 73 69  U list */.  unsi
07f0: 67 6e 65 64 20 69 6e 74 20 6e 50 61 67 65 3b 20  gned int nPage; 
0800: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0810: 2f 2a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20  /* Total number 
0820: 6f 66 20 70 61 67 65 73 20 69 6e 20 61 70 48 61  of pages in apHa
0830: 73 68 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64  sh */.  unsigned
0840: 20 69 6e 74 20 6e 48 61 73 68 3b 20 20 20 20 20   int nHash;     
0850: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
0860: 75 6d 62 65 72 20 6f 66 20 73 6c 6f 74 73 20 69  umber of slots i
0870: 6e 20 61 70 48 61 73 68 5b 5d 20 2a 2f 0a 20 20  n apHash[] */.  
0880: 50 67 48 64 72 31 20 2a 2a 61 70 48 61 73 68 3b  PgHdr1 **apHash;
0890: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
08a0: 20 20 20 20 2f 2a 20 48 61 73 68 20 74 61 62 6c      /* Hash tabl
08b0: 65 20 66 6f 72 20 66 61 73 74 20 6c 6f 6f 6b 75  e for fast looku
08c0: 70 20 62 79 20 6b 65 79 20 2a 2f 0a 0a 20 20 75  p by key */..  u
08d0: 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4d 61 78  nsigned int iMax
08e0: 4b 65 79 3b 20 20 20 20 20 20 20 20 20 20 20 20  Key;            
08f0: 20 20 20 2f 2a 20 4c 61 72 67 65 73 74 20 6b 65     /* Largest ke
0900: 79 20 73 65 65 6e 20 73 69 6e 63 65 20 78 54 72  y seen since xTr
0910: 75 6e 63 61 74 65 28 29 20 2a 2f 0a 7d 3b 0a 0a  uncate() */.};..
0920: 2f 2a 0a 2a 2a 20 45 61 63 68 20 63 61 63 68 65  /*.** Each cache
0930: 20 65 6e 74 72 79 20 69 73 20 72 65 70 72 65 73   entry is repres
0940: 65 6e 74 65 64 20 62 79 20 61 6e 20 69 6e 73 74  ented by an inst
0950: 61 6e 63 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c  ance of the foll
0960: 6f 77 69 6e 67 20 0a 2a 2a 20 73 74 72 75 63 74  owing .** struct
0970: 75 72 65 2e 20 41 20 62 75 66 66 65 72 20 6f 66  ure. A buffer of
0980: 20 50 67 48 64 72 31 2e 70 43 61 63 68 65 2d 3e   PgHdr1.pCache->
0990: 73 7a 50 61 67 65 20 62 79 74 65 73 20 69 73 20  szPage bytes is 
09a0: 61 6c 6c 6f 63 61 74 65 64 20 0a 2a 2a 20 64 69  allocated .** di
09b0: 72 65 63 74 6c 79 20 62 65 66 6f 72 65 20 74 68  rectly before th
09c0: 69 73 20 73 74 72 75 63 74 75 72 65 20 69 6e 20  is structure in 
09d0: 6d 65 6d 6f 72 79 20 28 73 65 65 20 74 68 65 20  memory (see the 
09e0: 50 47 48 44 52 31 5f 54 4f 5f 50 41 47 45 28 29  PGHDR1_TO_PAGE()
09f0: 20 0a 2a 2a 20 6d 61 63 72 6f 20 62 65 6c 6f 77   .** macro below
0a00: 29 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 50 67 48  )..*/.struct PgH
0a10: 64 72 31 20 7b 0a 20 20 75 6e 73 69 67 6e 65 64  dr1 {.  unsigned
0a20: 20 69 6e 74 20 69 4b 65 79 3b 20 20 20 20 20 20   int iKey;      
0a30: 20 20 20 20 20 20 20 2f 2a 20 4b 65 79 20 76 61         /* Key va
0a40: 6c 75 65 20 28 70 61 67 65 20 6e 75 6d 62 65 72  lue (page number
0a50: 29 20 2a 2f 0a 20 20 50 67 48 64 72 31 20 2a 70  ) */.  PgHdr1 *p
0a60: 4e 65 78 74 3b 20 20 20 20 20 20 20 20 20 20 20  Next;           
0a70: 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 69 6e        /* Next in
0a80: 20 68 61 73 68 20 74 61 62 6c 65 20 63 68 61 69   hash table chai
0a90: 6e 20 2a 2f 0a 20 20 50 43 61 63 68 65 31 20 2a  n */.  PCache1 *
0aa0: 70 43 61 63 68 65 3b 20 20 20 20 20 20 20 20 20  pCache;         
0ab0: 20 20 20 20 20 20 2f 2a 20 43 61 63 68 65 20 74        /* Cache t
0ac0: 68 61 74 20 63 75 72 72 65 6e 74 6c 79 20 6f 77  hat currently ow
0ad0: 6e 73 20 74 68 69 73 20 70 61 67 65 20 2a 2f 0a  ns this page */.
0ae0: 20 20 50 67 48 64 72 31 20 2a 70 4c 72 75 4e 65    PgHdr1 *pLruNe
0af0: 78 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  xt;             
0b00: 20 2f 2a 20 4e 65 78 74 20 69 6e 20 4c 52 55 20   /* Next in LRU 
0b10: 6c 69 73 74 20 6f 66 20 75 6e 70 69 6e 6e 65 64  list of unpinned
0b20: 20 70 61 67 65 73 20 2a 2f 0a 20 20 50 67 48 64   pages */.  PgHd
0b30: 72 31 20 2a 70 4c 72 75 50 72 65 76 3b 20 20 20  r1 *pLruPrev;   
0b40: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 72             /* Pr
0b50: 65 76 69 6f 75 73 20 69 6e 20 4c 52 55 20 6c 69  evious in LRU li
0b60: 73 74 20 6f 66 20 75 6e 70 69 6e 6e 65 64 20 70  st of unpinned p
0b70: 61 67 65 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a  ages */.};../*.*
0b80: 2a 20 46 72 65 65 20 73 6c 6f 74 73 20 69 6e 20  * Free slots in 
0b90: 74 68 65 20 61 6c 6c 6f 63 61 74 6f 72 20 75 73  the allocator us
0ba0: 65 64 20 74 6f 20 64 69 76 69 64 65 20 75 70 20  ed to divide up 
0bb0: 74 68 65 20 62 75 66 66 65 72 20 70 72 6f 76 69  the buffer provi
0bc0: 64 65 64 20 75 73 69 6e 67 0a 2a 2a 20 74 68 65  ded using.** the
0bd0: 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50   SQLITE_CONFIG_P
0be0: 41 47 45 43 41 43 48 45 20 6d 65 63 68 61 6e 69  AGECACHE mechani
0bf0: 73 6d 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 50 67  sm..*/.struct Pg
0c00: 46 72 65 65 73 6c 6f 74 20 7b 0a 20 20 50 67 46  Freeslot {.  PgF
0c10: 72 65 65 73 6c 6f 74 20 2a 70 4e 65 78 74 3b 20  reeslot *pNext; 
0c20: 20 2f 2a 20 4e 65 78 74 20 66 72 65 65 20 73 6c   /* Next free sl
0c30: 6f 74 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20  ot */.};../*.** 
0c40: 47 6c 6f 62 61 6c 20 64 61 74 61 20 75 73 65 64  Global data used
0c50: 20 62 79 20 74 68 69 73 20 63 61 63 68 65 2e 0a   by this cache..
0c60: 2a 2f 0a 73 74 61 74 69 63 20 53 51 4c 49 54 45  */.static SQLITE
0c70: 5f 57 53 44 20 73 74 72 75 63 74 20 50 43 61 63  _WSD struct PCac
0c80: 68 65 47 6c 6f 62 61 6c 20 7b 0a 20 20 73 71 6c  heGlobal {.  sql
0c90: 69 74 65 33 5f 6d 75 74 65 78 20 2a 6d 75 74 65  ite3_mutex *mute
0ca0: 78 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  x;              
0cb0: 20 2f 2a 20 73 74 61 74 69 63 20 6d 75 74 65 78   /* static mutex
0cc0: 20 4d 55 54 45 58 5f 53 54 41 54 49 43 5f 4c 52   MUTEX_STATIC_LR
0cd0: 55 20 2a 2f 0a 0a 20 20 69 6e 74 20 6e 4d 61 78  U */..  int nMax
0ce0: 50 61 67 65 3b 20 20 20 20 20 20 20 20 20 20 20  Page;           
0cf0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
0d00: 75 6d 20 6f 66 20 6e 4d 61 78 50 61 67 65 20 66  um of nMaxPage f
0d10: 6f 72 20 70 75 72 67 65 61 62 6c 65 20 63 61 63  or purgeable cac
0d20: 68 65 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 4d 69  hes */.  int nMi
0d30: 6e 50 61 67 65 3b 20 20 20 20 20 20 20 20 20 20  nPage;          
0d40: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0d50: 53 75 6d 20 6f 66 20 6e 4d 69 6e 50 61 67 65 20  Sum of nMinPage 
0d60: 66 6f 72 20 70 75 72 67 65 61 62 6c 65 20 63 61  for purgeable ca
0d70: 63 68 65 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 43  ches */.  int nC
0d80: 75 72 72 65 6e 74 50 61 67 65 3b 20 20 20 20 20  urrentPage;     
0d90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0da0: 20 4e 75 6d 62 65 72 20 6f 66 20 70 75 72 67 65   Number of purge
0db0: 61 62 6c 65 20 70 61 67 65 73 20 61 6c 6c 6f 63  able pages alloc
0dc0: 61 74 65 64 20 2a 2f 0a 20 20 50 67 48 64 72 31  ated */.  PgHdr1
0dd0: 20 2a 70 4c 72 75 48 65 61 64 2c 20 2a 70 4c 72   *pLruHead, *pLr
0de0: 75 54 61 69 6c 3b 20 20 20 20 20 20 20 20 2f 2a  uTail;        /*
0df0: 20 4c 52 55 20 6c 69 73 74 20 6f 66 20 75 6e 70   LRU list of unp
0e00: 69 6e 6e 65 64 20 70 61 67 65 73 20 2a 2f 0a 0a  inned pages */..
0e10: 20 20 2f 2a 20 56 61 72 69 61 62 6c 65 73 20 72    /* Variables r
0e20: 65 6c 61 74 65 64 20 74 6f 20 53 51 4c 49 54 45  elated to SQLITE
0e30: 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48  _CONFIG_PAGECACH
0e40: 45 20 73 65 74 74 69 6e 67 73 2e 20 2a 2f 0a 20  E settings. */. 
0e50: 20 69 6e 74 20 73 7a 53 6c 6f 74 3b 20 20 20 20   int szSlot;    
0e60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e70: 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
0e80: 65 61 63 68 20 66 72 65 65 20 73 6c 6f 74 20 2a  each free slot *
0e90: 2f 0a 20 20 69 6e 74 20 6e 53 6c 6f 74 3b 20 20  /.  int nSlot;  
0ea0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0eb0: 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 6e          /* The n
0ec0: 75 6d 62 65 72 20 6f 66 20 70 63 61 63 68 65 20  umber of pcache 
0ed0: 73 6c 6f 74 73 20 2a 2f 0a 20 20 69 6e 74 20 6e  slots */.  int n
0ee0: 46 72 65 65 53 6c 6f 74 3b 20 20 20 20 20 20 20  FreeSlot;       
0ef0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0f00: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 75 6e 75 73  * Number of unus
0f10: 65 64 20 70 63 61 63 68 65 20 73 6c 6f 74 73 20  ed pcache slots 
0f20: 2a 2f 0a 20 20 69 6e 74 20 6e 52 65 73 65 72 76  */.  int nReserv
0f30: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
0f40: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 79 20           /* Try 
0f50: 74 6f 20 6b 65 65 70 20 6e 46 72 65 65 53 6c 6f  to keep nFreeSlo
0f60: 74 20 61 62 6f 76 65 20 74 68 69 73 20 2a 2f 0a  t above this */.
0f70: 20 20 76 6f 69 64 20 2a 70 53 74 61 72 74 2c 20    void *pStart, 
0f80: 2a 70 45 6e 64 3b 20 20 20 20 20 20 20 20 20 20  *pEnd;          
0f90: 20 20 20 20 20 20 2f 2a 20 42 6f 75 6e 64 73 20        /* Bounds 
0fa0: 6f 66 20 70 61 67 65 63 61 63 68 65 20 6d 61 6c  of pagecache mal
0fb0: 6c 6f 63 20 72 61 6e 67 65 20 2a 2f 0a 20 20 50  loc range */.  P
0fc0: 67 46 72 65 65 73 6c 6f 74 20 2a 70 46 72 65 65  gFreeslot *pFree
0fd0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
0fe0: 20 20 20 2f 2a 20 46 72 65 65 20 70 61 67 65 20     /* Free page 
0ff0: 62 6c 6f 63 6b 73 20 2a 2f 0a 20 20 69 6e 74 20  blocks */.  int 
1000: 69 73 49 6e 69 74 3b 20 20 20 20 20 20 20 20 20  isInit;         
1010: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1020: 2f 2a 20 54 72 75 65 20 69 66 20 69 6e 69 74 69  /* True if initi
1030: 61 6c 69 7a 65 64 20 2a 2f 0a 7d 20 70 63 61 63  alized */.} pcac
1040: 68 65 31 5f 67 3b 0a 0a 2f 2a 0a 2a 2a 20 41 6c  he1_g;../*.** Al
1050: 6c 20 63 6f 64 65 20 69 6e 20 74 68 69 73 20 66  l code in this f
1060: 69 6c 65 20 73 68 6f 75 6c 64 20 61 63 63 65 73  ile should acces
1070: 73 20 74 68 65 20 67 6c 6f 62 61 6c 20 73 74 72  s the global str
1080: 75 63 74 75 72 65 20 61 62 6f 76 65 20 76 69 61  ucture above via
1090: 20 74 68 65 0a 2a 2a 20 61 6c 69 61 73 20 22 70   the.** alias "p
10a0: 63 61 63 68 65 31 22 2e 20 54 68 69 73 20 65 6e  cache1". This en
10b0: 73 75 72 65 73 20 74 68 61 74 20 74 68 65 20 57  sures that the W
10c0: 53 44 20 65 6d 75 6c 61 74 69 6f 6e 20 69 73 20  SD emulation is 
10d0: 75 73 65 64 20 77 68 65 6e 0a 2a 2a 20 63 6f 6d  used when.** com
10e0: 70 69 6c 69 6e 67 20 66 6f 72 20 73 79 73 74 65  piling for syste
10f0: 6d 73 20 74 68 61 74 20 64 6f 20 6e 6f 74 20 73  ms that do not s
1100: 75 70 70 6f 72 74 20 72 65 61 6c 20 57 53 44 2e  upport real WSD.
1110: 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 70 63 61 63  .*/.#define pcac
1120: 68 65 31 20 28 47 4c 4f 42 41 4c 28 73 74 72 75  he1 (GLOBAL(stru
1130: 63 74 20 50 43 61 63 68 65 47 6c 6f 62 61 6c 2c  ct PCacheGlobal,
1140: 20 70 63 61 63 68 65 31 5f 67 29 29 0a 0a 2f 2a   pcache1_g))../*
1150: 0a 2a 2a 20 57 68 65 6e 20 61 20 50 67 48 64 72  .** When a PgHdr
1160: 31 20 73 74 72 75 63 74 75 72 65 20 69 73 20 61  1 structure is a
1170: 6c 6c 6f 63 61 74 65 64 2c 20 74 68 65 20 61 73  llocated, the as
1180: 73 6f 63 69 61 74 65 64 20 50 43 61 63 68 65 31  sociated PCache1
1190: 2e 73 7a 50 61 67 65 0a 2a 2a 20 62 79 74 65 73  .szPage.** bytes
11a0: 20 6f 66 20 64 61 74 61 20 61 72 65 20 6c 6f 63   of data are loc
11b0: 61 74 65 64 20 64 69 72 65 63 74 6c 79 20 62 65  ated directly be
11c0: 66 6f 72 65 20 69 74 20 69 6e 20 6d 65 6d 6f 72  fore it in memor
11d0: 79 20 28 69 2e 65 2e 20 74 68 65 20 74 6f 74 61  y (i.e. the tota
11e0: 6c 0a 2a 2a 20 73 69 7a 65 20 6f 66 20 74 68 65  l.** size of the
11f0: 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 69 73 20 73   allocation is s
1200: 69 7a 65 6f 66 28 50 67 48 64 72 31 29 2b 50 43  izeof(PgHdr1)+PC
1210: 61 63 68 65 31 2e 73 7a 50 61 67 65 20 62 79 74  ache1.szPage byt
1220: 65 29 2e 20 54 68 65 0a 2a 2a 20 50 47 48 44 52  e). The.** PGHDR
1230: 31 5f 54 4f 5f 50 41 47 45 28 29 20 6d 61 63 72  1_TO_PAGE() macr
1240: 6f 20 74 61 6b 65 73 20 61 20 70 6f 69 6e 74 65  o takes a pointe
1250: 72 20 74 6f 20 61 20 50 67 48 64 72 31 20 73 74  r to a PgHdr1 st
1260: 72 75 63 74 75 72 65 20 61 73 0a 2a 2a 20 61 6e  ructure as.** an
1270: 20 61 72 67 75 6d 65 6e 74 20 61 6e 64 20 72 65   argument and re
1280: 74 75 72 6e 73 20 61 20 70 6f 69 6e 74 65 72 20  turns a pointer 
1290: 74 6f 20 74 68 65 20 61 73 73 6f 63 69 61 74 65  to the associate
12a0: 64 20 62 6c 6f 63 6b 20 6f 66 20 73 7a 50 61 67  d block of szPag
12b0: 65 0a 2a 2a 20 62 79 74 65 73 2e 20 54 68 65 20  e.** bytes. The 
12c0: 50 41 47 45 5f 54 4f 5f 50 47 48 44 52 31 28 29  PAGE_TO_PGHDR1()
12d0: 20 6d 61 63 72 6f 20 64 6f 65 73 20 74 68 65 20   macro does the 
12e0: 6f 70 70 6f 73 69 74 65 3a 20 69 74 73 20 61 72  opposite: its ar
12f0: 67 75 6d 65 6e 74 20 69 73 0a 2a 2a 20 61 20 70  gument is.** a p
1300: 6f 69 6e 74 65 72 20 74 6f 20 61 20 62 6c 6f 63  ointer to a bloc
1310: 6b 20 6f 66 20 73 7a 50 61 67 65 20 62 79 74 65  k of szPage byte
1320: 73 20 6f 66 20 64 61 74 61 20 61 6e 64 20 74 68  s of data and th
1330: 65 20 72 65 74 75 72 6e 20 76 61 6c 75 65 20 69  e return value i
1340: 73 0a 2a 2a 20 61 20 70 6f 69 6e 74 65 72 20 74  s.** a pointer t
1350: 6f 20 74 68 65 20 61 73 73 6f 63 69 61 74 65 64  o the associated
1360: 20 50 67 48 64 72 31 20 73 74 72 75 63 74 75 72   PgHdr1 structur
1370: 65 2e 0a 2a 2a 0a 2a 2a 20 20 20 61 73 73 65 72  e..**.**   asser
1380: 74 28 20 50 47 48 44 52 31 5f 54 4f 5f 50 41 47  t( PGHDR1_TO_PAG
1390: 45 28 50 41 47 45 5f 54 4f 5f 50 47 48 44 52 31  E(PAGE_TO_PGHDR1
13a0: 28 70 43 61 63 68 65 2c 20 58 29 29 3d 3d 58 20  (pCache, X))==X 
13b0: 29 3b 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 50 47  );.*/.#define PG
13c0: 48 44 52 31 5f 54 4f 5f 50 41 47 45 28 70 29 20  HDR1_TO_PAGE(p) 
13d0: 20 20 20 28 76 6f 69 64 2a 29 28 28 28 63 68 61     (void*)(((cha
13e0: 72 2a 29 70 29 20 2d 20 70 2d 3e 70 43 61 63 68  r*)p) - p->pCach
13f0: 65 2d 3e 73 7a 50 61 67 65 29 0a 23 64 65 66 69  e->szPage).#defi
1400: 6e 65 20 50 41 47 45 5f 54 4f 5f 50 47 48 44 52  ne PAGE_TO_PGHDR
1410: 31 28 63 2c 20 70 29 20 28 50 67 48 64 72 31 2a  1(c, p) (PgHdr1*
1420: 29 28 28 28 63 68 61 72 2a 29 70 29 20 2b 20 63  )(((char*)p) + c
1430: 2d 3e 73 7a 50 61 67 65 29 0a 0a 2f 2a 0a 2a 2a  ->szPage)../*.**
1440: 20 4d 61 63 72 6f 73 20 74 6f 20 65 6e 74 65 72   Macros to enter
1450: 20 61 6e 64 20 6c 65 61 76 65 20 74 68 65 20 67   and leave the g
1460: 6c 6f 62 61 6c 20 4c 52 55 20 6d 75 74 65 78 2e  lobal LRU mutex.
1470: 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 70 63 61 63  .*/.#define pcac
1480: 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 29 20  he1EnterMutex() 
1490: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e  sqlite3_mutex_en
14a0: 74 65 72 28 70 63 61 63 68 65 31 2e 6d 75 74 65  ter(pcache1.mute
14b0: 78 29 0a 23 64 65 66 69 6e 65 20 70 63 61 63 68  x).#define pcach
14c0: 65 31 4c 65 61 76 65 4d 75 74 65 78 28 29 20 73  e1LeaveMutex() s
14d0: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61  qlite3_mutex_lea
14e0: 76 65 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78  ve(pcache1.mutex
14f0: 29 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  )../************
1500: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1510: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1520: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1530: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1540: 2a 2a 2f 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 20 50 61  **/./******** Pa
1550: 67 65 20 41 6c 6c 6f 63 61 74 69 6f 6e 2f 53 51  ge Allocation/SQ
1560: 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 43 41 43  LITE_CONFIG_PCAC
1570: 48 45 20 52 65 6c 61 74 65 64 20 46 75 6e 63 74  HE Related Funct
1580: 69 6f 6e 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ions ***********
1590: 2a 2a 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  ***/../*.** This
15a0: 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c   function is cal
15b0: 6c 65 64 20 64 75 72 69 6e 67 20 69 6e 69 74 69  led during initi
15c0: 61 6c 69 7a 61 74 69 6f 6e 20 69 66 20 61 20 73  alization if a s
15d0: 74 61 74 69 63 20 62 75 66 66 65 72 20 69 73 20  tatic buffer is 
15e0: 0a 2a 2a 20 73 75 70 70 6c 69 65 64 20 74 6f 20  .** supplied to 
15f0: 75 73 65 20 66 6f 72 20 74 68 65 20 70 61 67 65  use for the page
1600: 2d 63 61 63 68 65 20 62 79 20 70 61 73 73 69 6e  -cache by passin
1610: 67 20 74 68 65 20 53 51 4c 49 54 45 5f 43 4f 4e  g the SQLITE_CON
1620: 46 49 47 5f 50 41 47 45 43 41 43 48 45 0a 2a 2a  FIG_PAGECACHE.**
1630: 20 76 65 72 62 20 74 6f 20 73 71 6c 69 74 65 33   verb to sqlite3
1640: 5f 63 6f 6e 66 69 67 28 29 2e 20 50 61 72 61 6d  _config(). Param
1650: 65 74 65 72 20 70 42 75 66 20 70 6f 69 6e 74 73  eter pBuf points
1660: 20 74 6f 20 61 6e 20 61 6c 6c 6f 63 61 74 69 6f   to an allocatio
1670: 6e 20 6c 61 72 67 65 0a 2a 2a 20 65 6e 6f 75 67  n large.** enoug
1680: 68 20 74 6f 20 63 6f 6e 74 61 69 6e 20 27 6e 27  h to contain 'n'
1690: 20 62 75 66 66 65 72 73 20 6f 66 20 27 73 7a 27   buffers of 'sz'
16a0: 20 62 79 74 65 73 20 65 61 63 68 2e 0a 2a 2f 0a   bytes each..*/.
16b0: 76 6f 69 64 20 73 71 6c 69 74 65 33 50 43 61 63  void sqlite3PCac
16c0: 68 65 42 75 66 66 65 72 53 65 74 75 70 28 76 6f  heBufferSetup(vo
16d0: 69 64 20 2a 70 42 75 66 2c 20 69 6e 74 20 73 7a  id *pBuf, int sz
16e0: 2c 20 69 6e 74 20 6e 29 7b 0a 20 20 69 66 28 20  , int n){.  if( 
16f0: 70 63 61 63 68 65 31 2e 69 73 49 6e 69 74 20 29  pcache1.isInit )
1700: 7b 0a 20 20 20 20 50 67 46 72 65 65 73 6c 6f 74  {.    PgFreeslot
1710: 20 2a 70 3b 0a 20 20 20 20 73 7a 20 3d 20 52 4f   *p;.    sz = RO
1720: 55 4e 44 44 4f 57 4e 38 28 73 7a 29 3b 0a 20 20  UNDDOWN8(sz);.  
1730: 20 20 70 63 61 63 68 65 31 2e 73 7a 53 6c 6f 74    pcache1.szSlot
1740: 20 3d 20 73 7a 3b 0a 20 20 20 20 70 63 61 63 68   = sz;.    pcach
1750: 65 31 2e 6e 53 6c 6f 74 20 3d 20 70 63 61 63 68  e1.nSlot = pcach
1760: 65 31 2e 6e 46 72 65 65 53 6c 6f 74 20 3d 20 6e  e1.nFreeSlot = n
1770: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 6e 52  ;.    pcache1.nR
1780: 65 73 65 72 76 65 20 3d 20 6e 3e 39 30 20 3f 20  eserve = n>90 ? 
1790: 31 30 20 3a 20 28 6e 2f 31 30 20 2b 20 31 29 3b  10 : (n/10 + 1);
17a0: 0a 20 20 20 20 70 63 61 63 68 65 31 2e 70 53 74  .    pcache1.pSt
17b0: 61 72 74 20 3d 20 70 42 75 66 3b 0a 20 20 20 20  art = pBuf;.    
17c0: 70 63 61 63 68 65 31 2e 70 46 72 65 65 20 3d 20  pcache1.pFree = 
17d0: 30 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 6e 2d  0;.    while( n-
17e0: 2d 20 29 7b 0a 20 20 20 20 20 20 70 20 3d 20 28  - ){.      p = (
17f0: 50 67 46 72 65 65 73 6c 6f 74 2a 29 70 42 75 66  PgFreeslot*)pBuf
1800: 3b 0a 20 20 20 20 20 20 70 2d 3e 70 4e 65 78 74  ;.      p->pNext
1810: 20 3d 20 70 63 61 63 68 65 31 2e 70 46 72 65 65   = pcache1.pFree
1820: 3b 0a 20 20 20 20 20 20 70 63 61 63 68 65 31 2e  ;.      pcache1.
1830: 70 46 72 65 65 20 3d 20 70 3b 0a 20 20 20 20 20  pFree = p;.     
1840: 20 70 42 75 66 20 3d 20 28 76 6f 69 64 2a 29 26   pBuf = (void*)&
1850: 28 28 63 68 61 72 2a 29 70 42 75 66 29 5b 73 7a  ((char*)pBuf)[sz
1860: 5d 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 63 61  ];.    }.    pca
1870: 63 68 65 31 2e 70 45 6e 64 20 3d 20 70 42 75 66  che1.pEnd = pBuf
1880: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d  ;.  }.}../*.** M
1890: 61 6c 6c 6f 63 20 66 75 6e 63 74 69 6f 6e 20 75  alloc function u
18a0: 73 65 64 20 77 69 74 68 69 6e 20 74 68 69 73 20  sed within this 
18b0: 66 69 6c 65 20 74 6f 20 61 6c 6c 6f 63 61 74 65  file to allocate
18c0: 20 73 70 61 63 65 20 66 72 6f 6d 20 74 68 65 20   space from the 
18d0: 62 75 66 66 65 72 0a 2a 2a 20 63 6f 6e 66 69 67  buffer.** config
18e0: 75 72 65 64 20 75 73 69 6e 67 20 73 71 6c 69 74  ured using sqlit
18f0: 65 33 5f 63 6f 6e 66 69 67 28 53 51 4c 49 54 45  e3_config(SQLITE
1900: 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48  _CONFIG_PAGECACH
1910: 45 29 20 6f 70 74 69 6f 6e 2e 20 49 66 20 6e 6f  E) option. If no
1920: 20 0a 2a 2a 20 73 75 63 68 20 62 75 66 66 65 72   .** such buffer
1930: 20 65 78 69 73 74 73 20 6f 72 20 74 68 65 72 65   exists or there
1940: 20 69 73 20 6e 6f 20 73 70 61 63 65 20 6c 65 66   is no space lef
1950: 74 20 69 6e 20 69 74 2c 20 74 68 69 73 20 66 75  t in it, this fu
1960: 6e 63 74 69 6f 6e 20 66 61 6c 6c 73 20 0a 2a 2a  nction falls .**
1970: 20 62 61 63 6b 20 74 6f 20 73 71 6c 69 74 65 33   back to sqlite3
1980: 4d 61 6c 6c 6f 63 28 29 2e 0a 2a 2f 0a 73 74 61  Malloc()..*/.sta
1990: 74 69 63 20 76 6f 69 64 20 2a 70 63 61 63 68 65  tic void *pcache
19a0: 31 41 6c 6c 6f 63 28 69 6e 74 20 6e 42 79 74 65  1Alloc(int nByte
19b0: 29 7b 0a 20 20 76 6f 69 64 20 2a 70 3b 0a 20 20  ){.  void *p;.  
19c0: 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f  assert( sqlite3_
19d0: 6d 75 74 65 78 5f 68 65 6c 64 28 70 63 61 63 68  mutex_held(pcach
19e0: 65 31 2e 6d 75 74 65 78 29 20 29 3b 0a 20 20 73  e1.mutex) );.  s
19f0: 71 6c 69 74 65 33 53 74 61 74 75 73 53 65 74 28  qlite3StatusSet(
1a00: 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41  SQLITE_STATUS_PA
1a10: 47 45 43 41 43 48 45 5f 53 49 5a 45 2c 20 6e 42  GECACHE_SIZE, nB
1a20: 79 74 65 29 3b 0a 20 20 69 66 28 20 6e 42 79 74  yte);.  if( nByt
1a30: 65 3c 3d 70 63 61 63 68 65 31 2e 73 7a 53 6c 6f  e<=pcache1.szSlo
1a40: 74 20 26 26 20 70 63 61 63 68 65 31 2e 70 46 72  t && pcache1.pFr
1a50: 65 65 20 29 7b 0a 20 20 20 20 61 73 73 65 72 74  ee ){.    assert
1a60: 28 20 70 63 61 63 68 65 31 2e 69 73 49 6e 69 74  ( pcache1.isInit
1a70: 20 29 3b 0a 20 20 20 20 70 20 3d 20 28 50 67 48   );.    p = (PgH
1a80: 64 72 31 20 2a 29 70 63 61 63 68 65 31 2e 70 46  dr1 *)pcache1.pF
1a90: 72 65 65 3b 0a 20 20 20 20 70 63 61 63 68 65 31  ree;.    pcache1
1aa0: 2e 70 46 72 65 65 20 3d 20 70 63 61 63 68 65 31  .pFree = pcache1
1ab0: 2e 70 46 72 65 65 2d 3e 70 4e 65 78 74 3b 0a 20  .pFree->pNext;. 
1ac0: 20 20 20 70 63 61 63 68 65 31 2e 6e 46 72 65 65     pcache1.nFree
1ad0: 53 6c 6f 74 2d 2d 3b 0a 20 20 20 20 61 73 73 65  Slot--;.    asse
1ae0: 72 74 28 20 70 63 61 63 68 65 31 2e 6e 46 72 65  rt( pcache1.nFre
1af0: 65 53 6c 6f 74 3e 3d 30 20 29 3b 0a 20 20 20 20  eSlot>=0 );.    
1b00: 73 71 6c 69 74 65 33 53 74 61 74 75 73 41 64 64  sqlite3StatusAdd
1b10: 28 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50  (SQLITE_STATUS_P
1b20: 41 47 45 43 41 43 48 45 5f 55 53 45 44 2c 20 31  AGECACHE_USED, 1
1b30: 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 0a 20 20 20  );.  }else{..   
1b40: 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 61 20 6e   /* Allocate a n
1b50: 65 77 20 62 75 66 66 65 72 20 75 73 69 6e 67 20  ew buffer using 
1b60: 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 2e 20 42  sqlite3Malloc. B
1b70: 65 66 6f 72 65 20 64 6f 69 6e 67 20 73 6f 2c 20  efore doing so, 
1b80: 65 78 69 74 20 74 68 65 0a 20 20 20 20 2a 2a 20  exit the.    ** 
1b90: 67 6c 6f 62 61 6c 20 70 63 61 63 68 65 20 6d 75  global pcache mu
1ba0: 74 65 78 20 61 6e 64 20 75 6e 6c 6f 63 6b 20 74  tex and unlock t
1bb0: 68 65 20 70 61 67 65 72 2d 63 61 63 68 65 20 6f  he pager-cache o
1bc0: 62 6a 65 63 74 20 70 43 61 63 68 65 2e 20 54 68  bject pCache. Th
1bd0: 69 73 20 69 73 20 0a 20 20 20 20 2a 2a 20 73 6f  is is .    ** so
1be0: 20 74 68 61 74 20 69 66 20 74 68 65 20 61 74 74   that if the att
1bf0: 65 6d 70 74 20 74 6f 20 61 6c 6c 6f 63 61 74 65  empt to allocate
1c00: 20 61 20 6e 65 77 20 62 75 66 66 65 72 20 63 61   a new buffer ca
1c10: 75 73 65 73 20 74 68 65 20 74 68 65 20 0a 20 20  uses the the .  
1c20: 20 20 2a 2a 20 63 6f 6e 66 69 67 75 72 65 64 20    ** configured 
1c30: 73 6f 66 74 2d 68 65 61 70 2d 6c 69 6d 69 74 20  soft-heap-limit 
1c40: 74 6f 20 62 65 20 62 72 65 61 63 68 65 64 2c 20  to be breached, 
1c50: 69 74 20 77 69 6c 6c 20 62 65 20 70 6f 73 73 69  it will be possi
1c60: 62 6c 65 20 74 6f 0a 20 20 20 20 2a 2a 20 72 65  ble to.    ** re
1c70: 63 6c 61 69 6d 20 6d 65 6d 6f 72 79 20 66 72 6f  claim memory fro
1c80: 6d 20 74 68 69 73 20 70 61 67 65 72 2d 63 61 63  m this pager-cac
1c90: 68 65 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 70  he..    */.    p
1ca0: 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78  cache1LeaveMutex
1cb0: 28 29 3b 0a 20 20 20 20 70 20 3d 20 73 71 6c 69  ();.    p = sqli
1cc0: 74 65 33 4d 61 6c 6c 6f 63 28 6e 42 79 74 65 29  te3Malloc(nByte)
1cd0: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 45 6e 74  ;.    pcache1Ent
1ce0: 65 72 4d 75 74 65 78 28 29 3b 0a 20 20 20 20 69  erMutex();.    i
1cf0: 66 28 20 70 20 29 7b 0a 20 20 20 20 20 20 69 6e  f( p ){.      in
1d00: 74 20 73 7a 20 3d 20 73 71 6c 69 74 65 33 4d 61  t sz = sqlite3Ma
1d10: 6c 6c 6f 63 53 69 7a 65 28 70 29 3b 0a 20 20 20  llocSize(p);.   
1d20: 20 20 20 73 71 6c 69 74 65 33 53 74 61 74 75 73     sqlite3Status
1d30: 41 64 64 28 53 51 4c 49 54 45 5f 53 54 41 54 55  Add(SQLITE_STATU
1d40: 53 5f 50 41 47 45 43 41 43 48 45 5f 4f 56 45 52  S_PAGECACHE_OVER
1d50: 46 4c 4f 57 2c 20 73 7a 29 3b 0a 20 20 20 20 7d  FLOW, sz);.    }
1d60: 0a 20 20 20 20 73 71 6c 69 74 65 33 4d 65 6d 64  .    sqlite3Memd
1d70: 65 62 75 67 53 65 74 54 79 70 65 28 70 2c 20 4d  ebugSetType(p, M
1d80: 45 4d 54 59 50 45 5f 50 43 41 43 48 45 29 3b 0a  EMTYPE_PCACHE);.
1d90: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 70 3b 0a    }.  return p;.
1da0: 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61 6e  }../*.** Free an
1db0: 20 61 6c 6c 6f 63 61 74 65 64 20 62 75 66 66 65   allocated buffe
1dc0: 72 20 6f 62 74 61 69 6e 65 64 20 66 72 6f 6d 20  r obtained from 
1dd0: 70 63 61 63 68 65 31 41 6c 6c 6f 63 28 29 2e 0a  pcache1Alloc()..
1de0: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70  */.static void p
1df0: 63 61 63 68 65 31 46 72 65 65 28 76 6f 69 64 20  cache1Free(void 
1e00: 2a 70 29 7b 0a 20 20 61 73 73 65 72 74 28 20 73  *p){.  assert( s
1e10: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c  qlite3_mutex_hel
1e20: 64 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29  d(pcache1.mutex)
1e30: 20 29 3b 0a 20 20 69 66 28 20 70 3d 3d 30 20 29   );.  if( p==0 )
1e40: 20 72 65 74 75 72 6e 3b 0a 20 20 69 66 28 20 70   return;.  if( p
1e50: 3e 3d 70 63 61 63 68 65 31 2e 70 53 74 61 72 74  >=pcache1.pStart
1e60: 20 26 26 20 70 3c 70 63 61 63 68 65 31 2e 70 45   && p<pcache1.pE
1e70: 6e 64 20 29 7b 0a 20 20 20 20 50 67 46 72 65 65  nd ){.    PgFree
1e80: 73 6c 6f 74 20 2a 70 53 6c 6f 74 3b 0a 20 20 20  slot *pSlot;.   
1e90: 20 73 71 6c 69 74 65 33 53 74 61 74 75 73 41 64   sqlite3StatusAd
1ea0: 64 28 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f  d(SQLITE_STATUS_
1eb0: 50 41 47 45 43 41 43 48 45 5f 55 53 45 44 2c 20  PAGECACHE_USED, 
1ec0: 2d 31 29 3b 0a 20 20 20 20 70 53 6c 6f 74 20 3d  -1);.    pSlot =
1ed0: 20 28 50 67 46 72 65 65 73 6c 6f 74 2a 29 70 3b   (PgFreeslot*)p;
1ee0: 0a 20 20 20 20 70 53 6c 6f 74 2d 3e 70 4e 65 78  .    pSlot->pNex
1ef0: 74 20 3d 20 70 63 61 63 68 65 31 2e 70 46 72 65  t = pcache1.pFre
1f00: 65 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 70  e;.    pcache1.p
1f10: 46 72 65 65 20 3d 20 70 53 6c 6f 74 3b 0a 20 20  Free = pSlot;.  
1f20: 20 20 70 63 61 63 68 65 31 2e 6e 46 72 65 65 53    pcache1.nFreeS
1f30: 6c 6f 74 2b 2b 3b 0a 20 20 20 20 61 73 73 65 72  lot++;.    asser
1f40: 74 28 20 70 63 61 63 68 65 31 2e 6e 46 72 65 65  t( pcache1.nFree
1f50: 53 6c 6f 74 3c 3d 70 63 61 63 68 65 31 2e 6e 53  Slot<=pcache1.nS
1f60: 6c 6f 74 20 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a  lot );.  }else{.
1f70: 20 20 20 20 69 6e 74 20 69 53 69 7a 65 3b 0a 20      int iSize;. 
1f80: 20 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74     assert( sqlit
1f90: 65 33 4d 65 6d 64 65 62 75 67 48 61 73 54 79 70  e3MemdebugHasTyp
1fa0: 65 28 70 2c 20 4d 45 4d 54 59 50 45 5f 50 43 41  e(p, MEMTYPE_PCA
1fb0: 43 48 45 29 20 29 3b 0a 20 20 20 20 73 71 6c 69  CHE) );.    sqli
1fc0: 74 65 33 4d 65 6d 64 65 62 75 67 53 65 74 54 79  te3MemdebugSetTy
1fd0: 70 65 28 70 2c 20 4d 45 4d 54 59 50 45 5f 48 45  pe(p, MEMTYPE_HE
1fe0: 41 50 29 3b 0a 20 20 20 20 69 53 69 7a 65 20 3d  AP);.    iSize =
1ff0: 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 53 69   sqlite3MallocSi
2000: 7a 65 28 70 29 3b 0a 20 20 20 20 73 71 6c 69 74  ze(p);.    sqlit
2010: 65 33 53 74 61 74 75 73 41 64 64 28 53 51 4c 49  e3StatusAdd(SQLI
2020: 54 45 5f 53 54 41 54 55 53 5f 50 41 47 45 43 41  TE_STATUS_PAGECA
2030: 43 48 45 5f 4f 56 45 52 46 4c 4f 57 2c 20 2d 69  CHE_OVERFLOW, -i
2040: 53 69 7a 65 29 3b 0a 20 20 20 20 73 71 6c 69 74  Size);.    sqlit
2050: 65 33 5f 66 72 65 65 28 70 29 3b 0a 20 20 7d 0a  e3_free(p);.  }.
2060: 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45  }..#ifdef SQLITE
2070: 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d  _ENABLE_MEMORY_M
2080: 41 4e 41 47 45 4d 45 4e 54 0a 2f 2a 0a 2a 2a 20  ANAGEMENT./*.** 
2090: 52 65 74 75 72 6e 20 74 68 65 20 73 69 7a 65 20  Return the size 
20a0: 6f 66 20 61 20 70 63 61 63 68 65 20 61 6c 6c 6f  of a pcache allo
20b0: 63 61 74 69 6f 6e 0a 2a 2f 0a 73 74 61 74 69 63  cation.*/.static
20c0: 20 69 6e 74 20 70 63 61 63 68 65 31 4d 65 6d 53   int pcache1MemS
20d0: 69 7a 65 28 76 6f 69 64 20 2a 70 29 7b 0a 20 20  ize(void *p){.  
20e0: 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f  assert( sqlite3_
20f0: 6d 75 74 65 78 5f 68 65 6c 64 28 70 63 61 63 68  mutex_held(pcach
2100: 65 31 2e 6d 75 74 65 78 29 20 29 3b 0a 20 20 69  e1.mutex) );.  i
2110: 66 28 20 70 3e 3d 70 63 61 63 68 65 31 2e 70 53  f( p>=pcache1.pS
2120: 74 61 72 74 20 26 26 20 70 3c 70 63 61 63 68 65  tart && p<pcache
2130: 31 2e 70 45 6e 64 20 29 7b 0a 20 20 20 20 72 65  1.pEnd ){.    re
2140: 74 75 72 6e 20 70 63 61 63 68 65 31 2e 73 7a 53  turn pcache1.szS
2150: 6c 6f 74 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  lot;.  }else{.  
2160: 20 20 69 6e 74 20 69 53 69 7a 65 3b 0a 20 20 20    int iSize;.   
2170: 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33   assert( sqlite3
2180: 4d 65 6d 64 65 62 75 67 48 61 73 54 79 70 65 28  MemdebugHasType(
2190: 70 2c 20 4d 45 4d 54 59 50 45 5f 50 43 41 43 48  p, MEMTYPE_PCACH
21a0: 45 29 20 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  E) );.    sqlite
21b0: 33 4d 65 6d 64 65 62 75 67 53 65 74 54 79 70 65  3MemdebugSetType
21c0: 28 70 2c 20 4d 45 4d 54 59 50 45 5f 48 45 41 50  (p, MEMTYPE_HEAP
21d0: 29 3b 0a 20 20 20 20 69 53 69 7a 65 20 3d 20 73  );.    iSize = s
21e0: 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 53 69 7a 65  qlite3MallocSize
21f0: 28 70 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  (p);.    sqlite3
2200: 4d 65 6d 64 65 62 75 67 53 65 74 54 79 70 65 28  MemdebugSetType(
2210: 70 2c 20 4d 45 4d 54 59 50 45 5f 50 43 41 43 48  p, MEMTYPE_PCACH
2220: 45 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 69  E);.    return i
2230: 53 69 7a 65 3b 0a 20 20 7d 0a 7d 0a 23 65 6e 64  Size;.  }.}.#end
2240: 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f 45 4e 41  if /* SQLITE_ENA
2250: 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47  BLE_MEMORY_MANAG
2260: 45 4d 45 4e 54 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20  EMENT */../*.** 
2270: 41 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 70  Allocate a new p
2280: 61 67 65 20 6f 62 6a 65 63 74 20 69 6e 69 74 69  age object initi
2290: 61 6c 6c 79 20 61 73 73 6f 63 69 61 74 65 64 20  ally associated 
22a0: 77 69 74 68 20 63 61 63 68 65 20 70 43 61 63 68  with cache pCach
22b0: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 50 67 48  e..*/.static PgH
22c0: 64 72 31 20 2a 70 63 61 63 68 65 31 41 6c 6c 6f  dr1 *pcache1Allo
22d0: 63 50 61 67 65 28 50 43 61 63 68 65 31 20 2a 70  cPage(PCache1 *p
22e0: 43 61 63 68 65 29 7b 0a 20 20 69 6e 74 20 6e 42  Cache){.  int nB
22f0: 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 50 67 48  yte = sizeof(PgH
2300: 64 72 31 29 20 2b 20 70 43 61 63 68 65 2d 3e 73  dr1) + pCache->s
2310: 7a 50 61 67 65 3b 0a 20 20 76 6f 69 64 20 2a 70  zPage;.  void *p
2320: 50 67 20 3d 20 70 63 61 63 68 65 31 41 6c 6c 6f  Pg = pcache1Allo
2330: 63 28 6e 42 79 74 65 29 3b 0a 20 20 50 67 48 64  c(nByte);.  PgHd
2340: 72 31 20 2a 70 3b 0a 20 20 69 66 28 20 70 50 67  r1 *p;.  if( pPg
2350: 20 29 7b 0a 20 20 20 20 70 20 3d 20 50 41 47 45   ){.    p = PAGE
2360: 5f 54 4f 5f 50 47 48 44 52 31 28 70 43 61 63 68  _TO_PGHDR1(pCach
2370: 65 2c 20 70 50 67 29 3b 0a 20 20 20 20 69 66 28  e, pPg);.    if(
2380: 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61   pCache->bPurgea
2390: 62 6c 65 20 29 7b 0a 20 20 20 20 20 20 70 63 61  ble ){.      pca
23a0: 63 68 65 31 2e 6e 43 75 72 72 65 6e 74 50 61 67  che1.nCurrentPag
23b0: 65 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 7d 65 6c  e++;.    }.  }el
23c0: 73 65 7b 0a 20 20 20 20 70 20 3d 20 30 3b 0a 20  se{.    p = 0;. 
23d0: 20 7d 0a 20 20 72 65 74 75 72 6e 20 70 3b 0a 7d   }.  return p;.}
23e0: 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61 20 70  ../*.** Free a p
23f0: 61 67 65 20 6f 62 6a 65 63 74 20 61 6c 6c 6f 63  age object alloc
2400: 61 74 65 64 20 62 79 20 70 63 61 63 68 65 31 41  ated by pcache1A
2410: 6c 6c 6f 63 50 61 67 65 28 29 2e 0a 2a 2a 0a 2a  llocPage()..**.*
2420: 2a 20 54 68 65 20 70 6f 69 6e 74 65 72 20 69 73  * The pointer is
2430: 20 61 6c 6c 6f 77 65 64 20 74 6f 20 62 65 20 4e   allowed to be N
2440: 55 4c 4c 2c 20 77 68 69 63 68 20 69 73 20 70 72  ULL, which is pr
2450: 75 64 65 6e 74 2e 20 20 42 75 74 20 69 74 20 74  udent.  But it t
2460: 75 72 6e 73 20 6f 75 74 0a 2a 2a 20 74 68 61 74  urns out.** that
2470: 20 74 68 65 20 63 75 72 72 65 6e 74 20 69 6d 70   the current imp
2480: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 68 61 70 70  lementation happ
2490: 65 6e 73 20 74 6f 20 6e 65 76 65 72 20 63 61 6c  ens to never cal
24a0: 6c 20 74 68 69 73 20 72 6f 75 74 69 6e 65 0a 2a  l this routine.*
24b0: 2a 20 77 69 74 68 20 61 20 4e 55 4c 4c 20 70 6f  * with a NULL po
24c0: 69 6e 74 65 72 2c 20 73 6f 20 77 65 20 6d 61 72  inter, so we mar
24d0: 6b 20 74 68 65 20 4e 55 4c 4c 20 74 65 73 74 20  k the NULL test 
24e0: 77 69 74 68 20 41 4c 57 41 59 53 28 29 2e 0a 2a  with ALWAYS()..*
24f0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63  /.static void pc
2500: 61 63 68 65 31 46 72 65 65 50 61 67 65 28 50 67  ache1FreePage(Pg
2510: 48 64 72 31 20 2a 70 29 7b 0a 20 20 69 66 28 20  Hdr1 *p){.  if( 
2520: 41 4c 57 41 59 53 28 70 29 20 29 7b 0a 20 20 20  ALWAYS(p) ){.   
2530: 20 69 66 28 20 70 2d 3e 70 43 61 63 68 65 2d 3e   if( p->pCache->
2540: 62 50 75 72 67 65 61 62 6c 65 20 29 7b 0a 20 20  bPurgeable ){.  
2550: 20 20 20 20 70 63 61 63 68 65 31 2e 6e 43 75 72      pcache1.nCur
2560: 72 65 6e 74 50 61 67 65 2d 2d 3b 0a 20 20 20 20  rentPage--;.    
2570: 7d 0a 20 20 20 20 70 63 61 63 68 65 31 46 72 65  }.    pcache1Fre
2580: 65 28 50 47 48 44 52 31 5f 54 4f 5f 50 41 47 45  e(PGHDR1_TO_PAGE
2590: 28 70 29 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a  (p));.  }.}../*.
25a0: 2a 2a 20 4d 61 6c 6c 6f 63 20 66 75 6e 63 74 69  ** Malloc functi
25b0: 6f 6e 20 75 73 65 64 20 62 79 20 53 51 4c 69 74  on used by SQLit
25c0: 65 20 74 6f 20 6f 62 74 61 69 6e 20 73 70 61 63  e to obtain spac
25d0: 65 20 66 72 6f 6d 20 74 68 65 20 62 75 66 66 65  e from the buffe
25e0: 72 20 63 6f 6e 66 69 67 75 72 65 64 0a 2a 2a 20  r configured.** 
25f0: 75 73 69 6e 67 20 73 71 6c 69 74 65 33 5f 63 6f  using sqlite3_co
2600: 6e 66 69 67 28 53 51 4c 49 54 45 5f 43 4f 4e 46  nfig(SQLITE_CONF
2610: 49 47 5f 50 41 47 45 43 41 43 48 45 29 20 6f 70  IG_PAGECACHE) op
2620: 74 69 6f 6e 2e 20 49 66 20 6e 6f 20 73 75 63 68  tion. If no such
2630: 20 62 75 66 66 65 72 0a 2a 2a 20 65 78 69 73 74   buffer.** exist
2640: 73 2c 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  s, this function
2650: 20 66 61 6c 6c 73 20 62 61 63 6b 20 74 6f 20 73   falls back to s
2660: 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 29 2e 0a  qlite3Malloc()..
2670: 2a 2f 0a 76 6f 69 64 20 2a 73 71 6c 69 74 65 33  */.void *sqlite3
2680: 50 61 67 65 4d 61 6c 6c 6f 63 28 69 6e 74 20 73  PageMalloc(int s
2690: 7a 29 7b 0a 20 20 76 6f 69 64 20 2a 70 3b 0a 20  z){.  void *p;. 
26a0: 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74   pcache1EnterMut
26b0: 65 78 28 29 3b 0a 20 20 70 20 3d 20 70 63 61 63  ex();.  p = pcac
26c0: 68 65 31 41 6c 6c 6f 63 28 73 7a 29 3b 0a 20 20  he1Alloc(sz);.  
26d0: 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65  pcache1LeaveMute
26e0: 78 28 29 3b 0a 20 20 72 65 74 75 72 6e 20 70 3b  x();.  return p;
26f0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61  .}../*.** Free a
2700: 6e 20 61 6c 6c 6f 63 61 74 65 64 20 62 75 66 66  n allocated buff
2710: 65 72 20 6f 62 74 61 69 6e 65 64 20 66 72 6f 6d  er obtained from
2720: 20 73 71 6c 69 74 65 33 50 61 67 65 4d 61 6c 6c   sqlite3PageMall
2730: 6f 63 28 29 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71  oc()..*/.void sq
2740: 6c 69 74 65 33 50 61 67 65 46 72 65 65 28 76 6f  lite3PageFree(vo
2750: 69 64 20 2a 70 29 7b 0a 20 20 70 63 61 63 68 65  id *p){.  pcache
2760: 31 45 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a 20  1EnterMutex();. 
2770: 20 70 63 61 63 68 65 31 46 72 65 65 28 70 29 3b   pcache1Free(p);
2780: 0a 20 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d  .  pcache1LeaveM
2790: 75 74 65 78 28 29 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a  utex();.}.../*.*
27a0: 2a 20 52 65 74 75 72 6e 20 74 72 75 65 20 69 66  * Return true if
27b0: 20 69 74 20 64 65 73 69 72 61 62 6c 65 20 74 6f   it desirable to
27c0: 20 61 76 6f 69 64 20 61 6c 6c 6f 63 61 74 69 6e   avoid allocatin
27d0: 67 20 61 20 6e 65 77 20 70 61 67 65 20 63 61 63  g a new page cac
27e0: 68 65 0a 2a 2a 20 65 6e 74 72 79 2e 0a 2a 2a 0a  he.** entry..**.
27f0: 2a 2a 20 49 66 20 6d 65 6d 6f 72 79 20 77 61 73  ** If memory was
2800: 20 61 6c 6c 6f 63 61 74 65 64 20 73 70 65 63 69   allocated speci
2810: 66 69 63 61 6c 6c 79 20 74 6f 20 74 68 65 20 70  fically to the p
2820: 61 67 65 20 63 61 63 68 65 20 75 73 69 6e 67 0a  age cache using.
2830: 2a 2a 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47  ** SQLITE_CONFIG
2840: 5f 50 41 47 45 43 41 43 48 45 20 62 75 74 20 74  _PAGECACHE but t
2850: 68 61 74 20 6d 65 6d 6f 72 79 20 68 61 73 20 61  hat memory has a
2860: 6c 6c 20 62 65 65 6e 20 75 73 65 64 2c 20 74 68  ll been used, th
2870: 65 6e 0a 2a 2a 20 69 74 20 69 73 20 64 65 73 69  en.** it is desi
2880: 72 61 62 6c 65 20 74 6f 20 61 76 6f 69 64 20 61  rable to avoid a
2890: 6c 6c 6f 63 61 74 69 6e 67 20 61 20 6e 65 77 20  llocating a new 
28a0: 70 61 67 65 20 63 61 63 68 65 20 65 6e 74 72 79  page cache entry
28b0: 20 62 65 63 61 75 73 65 0a 2a 2a 20 70 72 65 73   because.** pres
28c0: 75 6d 61 62 6c 79 20 53 51 4c 49 54 45 5f 43 4f  umably SQLITE_CO
28d0: 4e 46 49 47 5f 50 41 47 45 43 41 43 48 45 20 77  NFIG_PAGECACHE w
28e0: 61 73 20 73 75 70 70 6f 73 65 20 74 6f 20 62 65  as suppose to be
28f0: 20 73 75 66 66 69 63 69 65 6e 74 0a 2a 2a 20 66   sufficient.** f
2900: 6f 72 20 61 6c 6c 20 70 61 67 65 20 63 61 63 68  or all page cach
2910: 65 20 6e 65 65 64 73 20 61 6e 64 20 77 65 20 73  e needs and we s
2920: 68 6f 75 6c 64 20 6e 6f 74 20 6e 65 65 64 20 74  hould not need t
2930: 6f 20 73 70 69 6c 6c 20 74 68 65 0a 2a 2a 20 61  o spill the.** a
2940: 6c 6c 6f 63 61 74 69 6f 6e 20 6f 6e 74 6f 20 74  llocation onto t
2950: 68 65 20 68 65 61 70 2e 0a 2a 2a 0a 2a 2a 20 4f  he heap..**.** O
2960: 72 2c 20 74 68 65 20 68 65 61 70 20 69 73 20 75  r, the heap is u
2970: 73 65 64 20 66 6f 72 20 61 6c 6c 20 70 61 67 65  sed for all page
2980: 20 63 61 63 68 65 20 6d 65 6d 6f 72 79 20 70 75   cache memory pu
2990: 74 20 74 68 65 20 68 65 61 70 20 69 73 0a 2a 2a  t the heap is.**
29a0: 20 75 6e 64 65 72 20 6d 65 6d 6f 72 79 20 70 72   under memory pr
29b0: 65 73 73 75 72 65 2c 20 74 68 65 6e 20 61 67 61  essure, then aga
29c0: 69 6e 20 69 74 20 69 73 20 64 65 73 69 72 61 62  in it is desirab
29d0: 6c 65 20 74 6f 20 61 76 6f 69 64 0a 2a 2a 20 61  le to avoid.** a
29e0: 6c 6c 6f 63 61 74 69 6e 67 20 61 20 6e 65 77 20  llocating a new 
29f0: 70 61 67 65 20 63 61 63 68 65 20 65 6e 74 72 79  page cache entry
2a00: 20 69 6e 20 6f 72 64 65 72 20 74 6f 20 61 76 6f   in order to avo
2a10: 69 64 20 73 74 72 65 73 73 69 6e 67 0a 2a 2a 20  id stressing.** 
2a20: 74 68 65 20 68 65 61 70 20 65 76 65 6e 20 66 75  the heap even fu
2a30: 72 74 68 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63  rther..*/.static
2a40: 20 69 6e 74 20 70 63 61 63 68 65 31 55 6e 64 65   int pcache1Unde
2a50: 72 4d 65 6d 6f 72 79 50 72 65 73 73 75 72 65 28  rMemoryPressure(
2a60: 50 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 29  PCache1 *pCache)
2a70: 7b 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c 69  {.  assert( sqli
2a80: 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70  te3_mutex_held(p
2a90: 63 61 63 68 65 31 2e 6d 75 74 65 78 29 20 29 3b  cache1.mutex) );
2aa0: 0a 20 20 69 66 28 20 70 63 61 63 68 65 31 2e 6e  .  if( pcache1.n
2ab0: 53 6c 6f 74 20 26 26 20 70 43 61 63 68 65 2d 3e  Slot && pCache->
2ac0: 73 7a 50 61 67 65 3c 3d 70 63 61 63 68 65 31 2e  szPage<=pcache1.
2ad0: 73 7a 53 6c 6f 74 20 29 7b 0a 20 20 20 20 72 65  szSlot ){.    re
2ae0: 74 75 72 6e 20 70 63 61 63 68 65 31 2e 6e 46 72  turn pcache1.nFr
2af0: 65 65 53 6c 6f 74 3c 70 63 61 63 68 65 31 2e 6e  eeSlot<pcache1.n
2b00: 52 65 73 65 72 76 65 3b 0a 20 20 7d 65 6c 73 65  Reserve;.  }else
2b10: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 73 71 6c  {.    return sql
2b20: 69 74 65 33 48 65 61 70 4e 65 61 72 6c 79 46 75  ite3HeapNearlyFu
2b30: 6c 6c 28 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 2a  ll();.  }.}../**
2b40: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2b50: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2b60: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2b70: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2b80: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a  ************/./*
2b90: 2a 2a 2a 2a 2a 2a 2a 20 47 65 6e 65 72 61 6c 20  ******* General 
2ba0: 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 46  Implementation F
2bb0: 75 6e 63 74 69 6f 6e 73 20 2a 2a 2a 2a 2a 2a 2a  unctions *******
2bc0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2bd0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a  *************/..
2be0: 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  /*.** This funct
2bf0: 69 6f 6e 20 69 73 20 75 73 65 64 20 74 6f 20 72  ion is used to r
2c00: 65 73 69 7a 65 20 74 68 65 20 68 61 73 68 20 74  esize the hash t
2c10: 61 62 6c 65 20 75 73 65 64 20 62 79 20 74 68 65  able used by the
2c20: 20 63 61 63 68 65 20 70 61 73 73 65 64 0a 2a 2a   cache passed.**
2c30: 20 61 73 20 74 68 65 20 66 69 72 73 74 20 61 72   as the first ar
2c40: 67 75 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 54 68  gument..**.** Th
2c50: 65 20 67 6c 6f 62 61 6c 20 6d 75 74 65 78 20 6d  e global mutex m
2c60: 75 73 74 20 62 65 20 68 65 6c 64 20 77 68 65 6e  ust be held when
2c70: 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   this function i
2c80: 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f 0a 73 74 61  s called..*/.sta
2c90: 74 69 63 20 69 6e 74 20 70 63 61 63 68 65 31 52  tic int pcache1R
2ca0: 65 73 69 7a 65 48 61 73 68 28 50 43 61 63 68 65  esizeHash(PCache
2cb0: 31 20 2a 70 29 7b 0a 20 20 50 67 48 64 72 31 20  1 *p){.  PgHdr1 
2cc0: 2a 2a 61 70 4e 65 77 3b 0a 20 20 75 6e 73 69 67  **apNew;.  unsig
2cd0: 6e 65 64 20 69 6e 74 20 6e 4e 65 77 3b 0a 20 20  ned int nNew;.  
2ce0: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 3b 0a  unsigned int i;.
2cf0: 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74  .  assert( sqlit
2d00: 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 63  e3_mutex_held(pc
2d10: 61 63 68 65 31 2e 6d 75 74 65 78 29 20 29 3b 0a  ache1.mutex) );.
2d20: 0a 20 20 6e 4e 65 77 20 3d 20 70 2d 3e 6e 48 61  .  nNew = p->nHa
2d30: 73 68 2a 32 3b 0a 20 20 69 66 28 20 6e 4e 65 77  sh*2;.  if( nNew
2d40: 3c 32 35 36 20 29 7b 0a 20 20 20 20 6e 4e 65 77  <256 ){.    nNew
2d50: 20 3d 20 32 35 36 3b 0a 20 20 7d 0a 0a 20 20 70   = 256;.  }..  p
2d60: 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78  cache1LeaveMutex
2d70: 28 29 3b 0a 20 20 69 66 28 20 70 2d 3e 6e 48 61  ();.  if( p->nHa
2d80: 73 68 20 29 7b 20 73 71 6c 69 74 65 33 42 65 67  sh ){ sqlite3Beg
2d90: 69 6e 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29  inBenignMalloc()
2da0: 3b 20 7d 0a 20 20 61 70 4e 65 77 20 3d 20 28 50  ; }.  apNew = (P
2db0: 67 48 64 72 31 20 2a 2a 29 73 71 6c 69 74 65 33  gHdr1 **)sqlite3
2dc0: 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 50  _malloc(sizeof(P
2dd0: 67 48 64 72 31 20 2a 29 2a 6e 4e 65 77 29 3b 0a  gHdr1 *)*nNew);.
2de0: 20 20 69 66 28 20 70 2d 3e 6e 48 61 73 68 20 29    if( p->nHash )
2df0: 7b 20 73 71 6c 69 74 65 33 45 6e 64 42 65 6e 69  { sqlite3EndBeni
2e00: 67 6e 4d 61 6c 6c 6f 63 28 29 3b 20 7d 0a 20 20  gnMalloc(); }.  
2e10: 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65  pcache1EnterMute
2e20: 78 28 29 3b 0a 20 20 69 66 28 20 61 70 4e 65 77  x();.  if( apNew
2e30: 20 29 7b 0a 20 20 20 20 6d 65 6d 73 65 74 28 61   ){.    memset(a
2e40: 70 4e 65 77 2c 20 30 2c 20 73 69 7a 65 6f 66 28  pNew, 0, sizeof(
2e50: 50 67 48 64 72 31 20 2a 29 2a 6e 4e 65 77 29 3b  PgHdr1 *)*nNew);
2e60: 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  .    for(i=0; i<
2e70: 70 2d 3e 6e 48 61 73 68 3b 20 69 2b 2b 29 7b 0a  p->nHash; i++){.
2e80: 20 20 20 20 20 20 50 67 48 64 72 31 20 2a 70 50        PgHdr1 *pP
2e90: 61 67 65 3b 0a 20 20 20 20 20 20 50 67 48 64 72  age;.      PgHdr
2ea0: 31 20 2a 70 4e 65 78 74 20 3d 20 70 2d 3e 61 70  1 *pNext = p->ap
2eb0: 48 61 73 68 5b 69 5d 3b 0a 20 20 20 20 20 20 77  Hash[i];.      w
2ec0: 68 69 6c 65 28 20 28 70 50 61 67 65 20 3d 20 70  hile( (pPage = p
2ed0: 4e 65 78 74 29 21 3d 30 20 29 7b 0a 20 20 20 20  Next)!=0 ){.    
2ee0: 20 20 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74      unsigned int
2ef0: 20 68 20 3d 20 70 50 61 67 65 2d 3e 69 4b 65 79   h = pPage->iKey
2f00: 20 25 20 6e 4e 65 77 3b 0a 20 20 20 20 20 20 20   % nNew;.       
2f10: 20 70 4e 65 78 74 20 3d 20 70 50 61 67 65 2d 3e   pNext = pPage->
2f20: 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 20 20 70  pNext;.        p
2f30: 50 61 67 65 2d 3e 70 4e 65 78 74 20 3d 20 61 70  Page->pNext = ap
2f40: 4e 65 77 5b 68 5d 3b 0a 20 20 20 20 20 20 20 20  New[h];.        
2f50: 61 70 4e 65 77 5b 68 5d 20 3d 20 70 50 61 67 65  apNew[h] = pPage
2f60: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
2f70: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
2f80: 28 70 2d 3e 61 70 48 61 73 68 29 3b 0a 20 20 20  (p->apHash);.   
2f90: 20 70 2d 3e 61 70 48 61 73 68 20 3d 20 61 70 4e   p->apHash = apN
2fa0: 65 77 3b 0a 20 20 20 20 70 2d 3e 6e 48 61 73 68  ew;.    p->nHash
2fb0: 20 3d 20 6e 4e 65 77 3b 0a 20 20 7d 0a 0a 20 20   = nNew;.  }..  
2fc0: 72 65 74 75 72 6e 20 28 70 2d 3e 61 70 48 61 73  return (p->apHas
2fd0: 68 20 3f 20 53 51 4c 49 54 45 5f 4f 4b 20 3a 20  h ? SQLITE_OK : 
2fe0: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 29 3b 0a 7d  SQLITE_NOMEM);.}
2ff0: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e  ../*.** This fun
3000: 63 74 69 6f 6e 20 69 73 20 75 73 65 64 20 69 6e  ction is used in
3010: 74 65 72 6e 61 6c 6c 79 20 74 6f 20 72 65 6d 6f  ternally to remo
3020: 76 65 20 74 68 65 20 70 61 67 65 20 70 50 61 67  ve the page pPag
3030: 65 20 66 72 6f 6d 20 74 68 65 20 0a 2a 2a 20 67  e from the .** g
3040: 6c 6f 62 61 6c 20 4c 52 55 20 6c 69 73 74 2c 20  lobal LRU list, 
3050: 69 66 20 69 73 20 70 61 72 74 20 6f 66 20 69 74  if is part of it
3060: 2e 20 49 66 20 70 50 61 67 65 20 69 73 20 6e 6f  . If pPage is no
3070: 74 20 70 61 72 74 20 6f 66 20 74 68 65 20 67 6c  t part of the gl
3080: 6f 62 61 6c 0a 2a 2a 20 4c 52 55 20 6c 69 73 74  obal.** LRU list
3090: 2c 20 74 68 65 6e 20 74 68 69 73 20 66 75 6e 63  , then this func
30a0: 74 69 6f 6e 20 69 73 20 61 20 6e 6f 2d 6f 70 2e  tion is a no-op.
30b0: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 67 6c 6f 62 61  .**.** The globa
30c0: 6c 20 6d 75 74 65 78 20 6d 75 73 74 20 62 65 20  l mutex must be 
30d0: 68 65 6c 64 20 77 68 65 6e 20 74 68 69 73 20 66  held when this f
30e0: 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65  unction is calle
30f0: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  d..*/.static voi
3100: 64 20 70 63 61 63 68 65 31 50 69 6e 50 61 67 65  d pcache1PinPage
3110: 28 50 67 48 64 72 31 20 2a 70 50 61 67 65 29 7b  (PgHdr1 *pPage){
3120: 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74  .  assert( sqlit
3130: 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 63  e3_mutex_held(pc
3140: 61 63 68 65 31 2e 6d 75 74 65 78 29 20 29 3b 0a  ache1.mutex) );.
3150: 20 20 69 66 28 20 70 50 61 67 65 20 26 26 20 28    if( pPage && (
3160: 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 20  pPage->pLruNext 
3170: 7c 7c 20 70 50 61 67 65 3d 3d 70 63 61 63 68 65  || pPage==pcache
3180: 31 2e 70 4c 72 75 54 61 69 6c 29 20 29 7b 0a 20  1.pLruTail) ){. 
3190: 20 20 20 69 66 28 20 70 50 61 67 65 2d 3e 70 4c     if( pPage->pL
31a0: 72 75 50 72 65 76 20 29 7b 0a 20 20 20 20 20 20  ruPrev ){.      
31b0: 70 50 61 67 65 2d 3e 70 4c 72 75 50 72 65 76 2d  pPage->pLruPrev-
31c0: 3e 70 4c 72 75 4e 65 78 74 20 3d 20 70 50 61 67  >pLruNext = pPag
31d0: 65 2d 3e 70 4c 72 75 4e 65 78 74 3b 0a 20 20 20  e->pLruNext;.   
31e0: 20 7d 0a 20 20 20 20 69 66 28 20 70 50 61 67 65   }.    if( pPage
31f0: 2d 3e 70 4c 72 75 4e 65 78 74 20 29 7b 0a 20 20  ->pLruNext ){.  
3200: 20 20 20 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e      pPage->pLruN
3210: 65 78 74 2d 3e 70 4c 72 75 50 72 65 76 20 3d 20  ext->pLruPrev = 
3220: 70 50 61 67 65 2d 3e 70 4c 72 75 50 72 65 76 3b  pPage->pLruPrev;
3230: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70  .    }.    if( p
3240: 63 61 63 68 65 31 2e 70 4c 72 75 48 65 61 64 3d  cache1.pLruHead=
3250: 3d 70 50 61 67 65 20 29 7b 0a 20 20 20 20 20 20  =pPage ){.      
3260: 70 63 61 63 68 65 31 2e 70 4c 72 75 48 65 61 64  pcache1.pLruHead
3270: 20 3d 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65   = pPage->pLruNe
3280: 78 74 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66  xt;.    }.    if
3290: 28 20 70 63 61 63 68 65 31 2e 70 4c 72 75 54 61  ( pcache1.pLruTa
32a0: 69 6c 3d 3d 70 50 61 67 65 20 29 7b 0a 20 20 20  il==pPage ){.   
32b0: 20 20 20 70 63 61 63 68 65 31 2e 70 4c 72 75 54     pcache1.pLruT
32c0: 61 69 6c 20 3d 20 70 50 61 67 65 2d 3e 70 4c 72  ail = pPage->pLr
32d0: 75 50 72 65 76 3b 0a 20 20 20 20 7d 0a 20 20 20  uPrev;.    }.   
32e0: 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74   pPage->pLruNext
32f0: 20 3d 20 30 3b 0a 20 20 20 20 70 50 61 67 65 2d   = 0;.    pPage-
3300: 3e 70 4c 72 75 50 72 65 76 20 3d 20 30 3b 0a 20  >pLruPrev = 0;. 
3310: 20 20 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65     pPage->pCache
3320: 2d 3e 6e 52 65 63 79 63 6c 61 62 6c 65 2d 2d 3b  ->nRecyclable--;
3330: 0a 20 20 7d 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 52  .  }.}.../*.** R
3340: 65 6d 6f 76 65 20 74 68 65 20 70 61 67 65 20 73  emove the page s
3350: 75 70 70 6c 69 65 64 20 61 73 20 61 6e 20 61 72  upplied as an ar
3360: 67 75 6d 65 6e 74 20 66 72 6f 6d 20 74 68 65 20  gument from the 
3370: 68 61 73 68 20 74 61 62 6c 65 20 0a 2a 2a 20 28  hash table .** (
3380: 50 43 61 63 68 65 31 2e 61 70 48 61 73 68 20 73  PCache1.apHash s
3390: 74 72 75 63 74 75 72 65 29 20 74 68 61 74 20 69  tructure) that i
33a0: 74 20 69 73 20 63 75 72 72 65 6e 74 6c 79 20 73  t is currently s
33b0: 74 6f 72 65 64 20 69 6e 2e 0a 2a 2a 0a 2a 2a 20  tored in..**.** 
33c0: 54 68 65 20 67 6c 6f 62 61 6c 20 6d 75 74 65 78  The global mutex
33d0: 20 6d 75 73 74 20 62 65 20 68 65 6c 64 20 77 68   must be held wh
33e0: 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  en this function
33f0: 20 69 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f 0a 73   is called..*/.s
3400: 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68  tatic void pcach
3410: 65 31 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73 68  e1RemoveFromHash
3420: 28 50 67 48 64 72 31 20 2a 70 50 61 67 65 29 7b  (PgHdr1 *pPage){
3430: 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  .  unsigned int 
3440: 68 3b 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43  h;.  PCache1 *pC
3450: 61 63 68 65 20 3d 20 70 50 61 67 65 2d 3e 70 43  ache = pPage->pC
3460: 61 63 68 65 3b 0a 20 20 50 67 48 64 72 31 20 2a  ache;.  PgHdr1 *
3470: 2a 70 70 3b 0a 0a 20 20 68 20 3d 20 70 50 61 67  *pp;..  h = pPag
3480: 65 2d 3e 69 4b 65 79 20 25 20 70 43 61 63 68 65  e->iKey % pCache
3490: 2d 3e 6e 48 61 73 68 3b 0a 20 20 66 6f 72 28 70  ->nHash;.  for(p
34a0: 70 3d 26 70 43 61 63 68 65 2d 3e 61 70 48 61 73  p=&pCache->apHas
34b0: 68 5b 68 5d 3b 20 28 2a 70 70 29 21 3d 70 50 61  h[h]; (*pp)!=pPa
34c0: 67 65 3b 20 70 70 3d 26 28 2a 70 70 29 2d 3e 70  ge; pp=&(*pp)->p
34d0: 4e 65 78 74 29 3b 0a 20 20 2a 70 70 20 3d 20 28  Next);.  *pp = (
34e0: 2a 70 70 29 2d 3e 70 4e 65 78 74 3b 0a 0a 20 20  *pp)->pNext;..  
34f0: 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 2d 2d 3b  pCache->nPage--;
3500: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 74 68 65  .}../*.** If the
3510: 72 65 20 61 72 65 20 63 75 72 72 65 6e 74 6c 79  re are currently
3520: 20 6d 6f 72 65 20 74 68 61 6e 20 70 63 61 63 68   more than pcach
3530: 65 2e 6e 4d 61 78 50 61 67 65 20 70 61 67 65 73  e.nMaxPage pages
3540: 20 61 6c 6c 6f 63 61 74 65 64 2c 20 74 72 79 0a   allocated, try.
3550: 2a 2a 20 74 6f 20 72 65 63 79 63 6c 65 20 70 61  ** to recycle pa
3560: 67 65 73 20 74 6f 20 72 65 64 75 63 65 20 74 68  ges to reduce th
3570: 65 20 6e 75 6d 62 65 72 20 61 6c 6c 6f 63 61 74  e number allocat
3580: 65 64 20 74 6f 20 70 63 61 63 68 65 2e 6e 4d 61  ed to pcache.nMa
3590: 78 50 61 67 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  xPage..*/.static
35a0: 20 76 6f 69 64 20 70 63 61 63 68 65 31 45 6e 66   void pcache1Enf
35b0: 6f 72 63 65 4d 61 78 50 61 67 65 28 76 6f 69 64  orceMaxPage(void
35c0: 29 7b 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c  ){.  assert( sql
35d0: 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28  ite3_mutex_held(
35e0: 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29 20 29  pcache1.mutex) )
35f0: 3b 0a 20 20 77 68 69 6c 65 28 20 70 63 61 63 68  ;.  while( pcach
3600: 65 31 2e 6e 43 75 72 72 65 6e 74 50 61 67 65 3e  e1.nCurrentPage>
3610: 70 63 61 63 68 65 31 2e 6e 4d 61 78 50 61 67 65  pcache1.nMaxPage
3620: 20 26 26 20 70 63 61 63 68 65 31 2e 70 4c 72 75   && pcache1.pLru
3630: 54 61 69 6c 20 29 7b 0a 20 20 20 20 50 67 48 64  Tail ){.    PgHd
3640: 72 31 20 2a 70 20 3d 20 70 63 61 63 68 65 31 2e  r1 *p = pcache1.
3650: 70 4c 72 75 54 61 69 6c 3b 0a 20 20 20 20 70 63  pLruTail;.    pc
3660: 61 63 68 65 31 50 69 6e 50 61 67 65 28 70 29 3b  ache1PinPage(p);
3670: 0a 20 20 20 20 70 63 61 63 68 65 31 52 65 6d 6f  .    pcache1Remo
3680: 76 65 46 72 6f 6d 48 61 73 68 28 70 29 3b 0a 20  veFromHash(p);. 
3690: 20 20 20 70 63 61 63 68 65 31 46 72 65 65 50 61     pcache1FreePa
36a0: 67 65 28 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a  ge(p);.  }.}../*
36b0: 0a 2a 2a 20 44 69 73 63 61 72 64 20 61 6c 6c 20  .** Discard all 
36c0: 70 61 67 65 73 20 66 72 6f 6d 20 63 61 63 68 65  pages from cache
36d0: 20 70 43 61 63 68 65 20 77 69 74 68 20 61 20 70   pCache with a p
36e0: 61 67 65 20 6e 75 6d 62 65 72 20 28 6b 65 79 20  age number (key 
36f0: 76 61 6c 75 65 29 20 0a 2a 2a 20 67 72 65 61 74  value) .** great
3700: 65 72 20 74 68 61 6e 20 6f 72 20 65 71 75 61 6c  er than or equal
3710: 20 74 6f 20 69 4c 69 6d 69 74 2e 20 41 6e 79 20   to iLimit. Any 
3720: 70 69 6e 6e 65 64 20 70 61 67 65 73 20 74 68 61  pinned pages tha
3730: 74 20 6d 65 65 74 20 74 68 69 73 20 0a 2a 2a 20  t meet this .** 
3740: 63 72 69 74 65 72 69 61 20 61 72 65 20 75 6e 70  criteria are unp
3750: 69 6e 6e 65 64 20 62 65 66 6f 72 65 20 74 68 65  inned before the
3760: 79 20 61 72 65 20 64 69 73 63 61 72 64 65 64 2e  y are discarded.
3770: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 67 6c 6f 62 61  .**.** The globa
3780: 6c 20 6d 75 74 65 78 20 6d 75 73 74 20 62 65 20  l mutex must be 
3790: 68 65 6c 64 20 77 68 65 6e 20 74 68 69 73 20 66  held when this f
37a0: 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65  unction is calle
37b0: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  d..*/.static voi
37c0: 64 20 70 63 61 63 68 65 31 54 72 75 6e 63 61 74  d pcache1Truncat
37d0: 65 55 6e 73 61 66 65 28 0a 20 20 50 43 61 63 68  eUnsafe(.  PCach
37e0: 65 31 20 2a 70 43 61 63 68 65 2c 20 0a 20 20 75  e1 *pCache, .  u
37f0: 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4c 69 6d  nsigned int iLim
3800: 69 74 20 0a 29 7b 0a 20 20 54 45 53 54 4f 4e 4c  it .){.  TESTONL
3810: 59 28 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  Y( unsigned int 
3820: 6e 50 61 67 65 20 3d 20 30 3b 20 29 20 20 20 20  nPage = 0; )    
3830: 20 20 2f 2a 20 55 73 65 64 20 74 6f 20 61 73 73    /* Used to ass
3840: 65 72 74 20 70 43 61 63 68 65 2d 3e 6e 50 61 67  ert pCache->nPag
3850: 65 20 69 73 20 63 6f 72 72 65 63 74 20 2a 2f 0a  e is correct */.
3860: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68    unsigned int h
3870: 3b 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c 69  ;.  assert( sqli
3880: 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70  te3_mutex_held(p
3890: 63 61 63 68 65 31 2e 6d 75 74 65 78 29 20 29 3b  cache1.mutex) );
38a0: 0a 20 20 66 6f 72 28 68 3d 30 3b 20 68 3c 70 43  .  for(h=0; h<pC
38b0: 61 63 68 65 2d 3e 6e 48 61 73 68 3b 20 68 2b 2b  ache->nHash; h++
38c0: 29 7b 0a 20 20 20 20 50 67 48 64 72 31 20 2a 2a  ){.    PgHdr1 **
38d0: 70 70 20 3d 20 26 70 43 61 63 68 65 2d 3e 61 70  pp = &pCache->ap
38e0: 48 61 73 68 5b 68 5d 3b 20 0a 20 20 20 20 50 67  Hash[h]; .    Pg
38f0: 48 64 72 31 20 2a 70 50 61 67 65 3b 0a 20 20 20  Hdr1 *pPage;.   
3900: 20 77 68 69 6c 65 28 20 28 70 50 61 67 65 20 3d   while( (pPage =
3910: 20 2a 70 70 29 21 3d 30 20 29 7b 0a 20 20 20 20   *pp)!=0 ){.    
3920: 20 20 69 66 28 20 70 50 61 67 65 2d 3e 69 4b 65    if( pPage->iKe
3930: 79 3e 3d 69 4c 69 6d 69 74 20 29 7b 0a 20 20 20  y>=iLimit ){.   
3940: 20 20 20 20 20 70 43 61 63 68 65 2d 3e 6e 50 61       pCache->nPa
3950: 67 65 2d 2d 3b 0a 20 20 20 20 20 20 20 20 2a 70  ge--;.        *p
3960: 70 20 3d 20 70 50 61 67 65 2d 3e 70 4e 65 78 74  p = pPage->pNext
3970: 3b 0a 20 20 20 20 20 20 20 20 70 63 61 63 68 65  ;.        pcache
3980: 31 50 69 6e 50 61 67 65 28 70 50 61 67 65 29 3b  1PinPage(pPage);
3990: 0a 20 20 20 20 20 20 20 20 70 63 61 63 68 65 31  .        pcache1
39a0: 46 72 65 65 50 61 67 65 28 70 50 61 67 65 29 3b  FreePage(pPage);
39b0: 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  .      }else{.  
39c0: 20 20 20 20 20 20 70 70 20 3d 20 26 70 50 61 67        pp = &pPag
39d0: 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20  e->pNext;.      
39e0: 20 20 54 45 53 54 4f 4e 4c 59 28 20 6e 50 61 67    TESTONLY( nPag
39f0: 65 2b 2b 3b 20 29 0a 20 20 20 20 20 20 7d 0a 20  e++; ).      }. 
3a00: 20 20 20 7d 0a 20 20 7d 0a 20 20 61 73 73 65 72     }.  }.  asser
3a10: 74 28 20 70 43 61 63 68 65 2d 3e 6e 50 61 67 65  t( pCache->nPage
3a20: 3d 3d 6e 50 61 67 65 20 29 3b 0a 7d 0a 0a 2f 2a  ==nPage );.}../*
3a30: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3a40: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3a50: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3a60: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3a70: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f  *************/./
3a80: 2a 2a 2a 2a 2a 2a 2a 2a 20 73 71 6c 69 74 65 33  ******** sqlite3
3a90: 5f 70 63 61 63 68 65 20 4d 65 74 68 6f 64 73 20  _pcache Methods 
3aa0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3ab0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3ac0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a  **************/.
3ad0: 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74  ./*.** Implement
3ae0: 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c  ation of the sql
3af0: 69 74 65 33 5f 70 63 61 63 68 65 2e 78 49 6e 69  ite3_pcache.xIni
3b00: 74 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61  t method..*/.sta
3b10: 74 69 63 20 69 6e 74 20 70 63 61 63 68 65 31 49  tic int pcache1I
3b20: 6e 69 74 28 76 6f 69 64 20 2a 4e 6f 74 55 73 65  nit(void *NotUse
3b30: 64 29 7b 0a 20 20 55 4e 55 53 45 44 5f 50 41 52  d){.  UNUSED_PAR
3b40: 41 4d 45 54 45 52 28 4e 6f 74 55 73 65 64 29 3b  AMETER(NotUsed);
3b50: 0a 20 20 61 73 73 65 72 74 28 20 70 63 61 63 68  .  assert( pcach
3b60: 65 31 2e 69 73 49 6e 69 74 3d 3d 30 20 29 3b 0a  e1.isInit==0 );.
3b70: 20 20 6d 65 6d 73 65 74 28 26 70 63 61 63 68 65    memset(&pcache
3b80: 31 2c 20 30 2c 20 73 69 7a 65 6f 66 28 70 63 61  1, 0, sizeof(pca
3b90: 63 68 65 31 29 29 3b 0a 20 20 69 66 28 20 73 71  che1));.  if( sq
3ba0: 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69  lite3GlobalConfi
3bb0: 67 2e 62 43 6f 72 65 4d 75 74 65 78 20 29 7b 0a  g.bCoreMutex ){.
3bc0: 20 20 20 20 70 63 61 63 68 65 31 2e 6d 75 74 65      pcache1.mute
3bd0: 78 20 3d 20 73 71 6c 69 74 65 33 5f 6d 75 74 65  x = sqlite3_mute
3be0: 78 5f 61 6c 6c 6f 63 28 53 51 4c 49 54 45 5f 4d  x_alloc(SQLITE_M
3bf0: 55 54 45 58 5f 53 54 41 54 49 43 5f 4c 52 55 29  UTEX_STATIC_LRU)
3c00: 3b 0a 20 20 7d 0a 20 20 70 63 61 63 68 65 31 2e  ;.  }.  pcache1.
3c10: 69 73 49 6e 69 74 20 3d 20 31 3b 0a 20 20 72 65  isInit = 1;.  re
3c20: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
3c30: 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65  }../*.** Impleme
3c40: 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73  ntation of the s
3c50: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78 53  qlite3_pcache.xS
3c60: 68 75 74 64 6f 77 6e 20 6d 65 74 68 6f 64 2e 0a  hutdown method..
3c70: 2a 2a 20 4e 6f 74 65 20 74 68 61 74 20 74 68 65  ** Note that the
3c80: 20 73 74 61 74 69 63 20 6d 75 74 65 78 20 61 6c   static mutex al
3c90: 6c 6f 63 61 74 65 64 20 69 6e 20 78 49 6e 69 74  located in xInit
3ca0: 20 64 6f 65 73 20 0a 2a 2a 20 6e 6f 74 20 6e 65   does .** not ne
3cb0: 65 64 20 74 6f 20 62 65 20 66 72 65 65 64 2e 0a  ed to be freed..
3cc0: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70  */.static void p
3cd0: 63 61 63 68 65 31 53 68 75 74 64 6f 77 6e 28 76  cache1Shutdown(v
3ce0: 6f 69 64 20 2a 4e 6f 74 55 73 65 64 29 7b 0a 20  oid *NotUsed){. 
3cf0: 20 55 4e 55 53 45 44 5f 50 41 52 41 4d 45 54 45   UNUSED_PARAMETE
3d00: 52 28 4e 6f 74 55 73 65 64 29 3b 0a 20 20 61 73  R(NotUsed);.  as
3d10: 73 65 72 74 28 20 70 63 61 63 68 65 31 2e 69 73  sert( pcache1.is
3d20: 49 6e 69 74 21 3d 30 20 29 3b 0a 20 20 6d 65 6d  Init!=0 );.  mem
3d30: 73 65 74 28 26 70 63 61 63 68 65 31 2c 20 30 2c  set(&pcache1, 0,
3d40: 20 73 69 7a 65 6f 66 28 70 63 61 63 68 65 31 29   sizeof(pcache1)
3d50: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c  );.}../*.** Impl
3d60: 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68  ementation of th
3d70: 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  e sqlite3_pcache
3d80: 2e 78 43 72 65 61 74 65 20 6d 65 74 68 6f 64 2e  .xCreate method.
3d90: 0a 2a 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65 20  .**.** Allocate 
3da0: 61 20 6e 65 77 20 63 61 63 68 65 2e 0a 2a 2f 0a  a new cache..*/.
3db0: 73 74 61 74 69 63 20 73 71 6c 69 74 65 33 5f 70  static sqlite3_p
3dc0: 63 61 63 68 65 20 2a 70 63 61 63 68 65 31 43 72  cache *pcache1Cr
3dd0: 65 61 74 65 28 69 6e 74 20 73 7a 50 61 67 65 2c  eate(int szPage,
3de0: 20 69 6e 74 20 62 50 75 72 67 65 61 62 6c 65 29   int bPurgeable)
3df0: 7b 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43 61  {.  PCache1 *pCa
3e00: 63 68 65 3b 0a 0a 20 20 70 43 61 63 68 65 20 3d  che;..  pCache =
3e10: 20 28 50 43 61 63 68 65 31 20 2a 29 73 71 6c 69   (PCache1 *)sqli
3e20: 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f  te3_malloc(sizeo
3e30: 66 28 50 43 61 63 68 65 31 29 29 3b 0a 20 20 69  f(PCache1));.  i
3e40: 66 28 20 70 43 61 63 68 65 20 29 7b 0a 20 20 20  f( pCache ){.   
3e50: 20 6d 65 6d 73 65 74 28 70 43 61 63 68 65 2c 20   memset(pCache, 
3e60: 30 2c 20 73 69 7a 65 6f 66 28 50 43 61 63 68 65  0, sizeof(PCache
3e70: 31 29 29 3b 0a 20 20 20 20 70 43 61 63 68 65 2d  1));.    pCache-
3e80: 3e 73 7a 50 61 67 65 20 3d 20 73 7a 50 61 67 65  >szPage = szPage
3e90: 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 62 50  ;.    pCache->bP
3ea0: 75 72 67 65 61 62 6c 65 20 3d 20 28 62 50 75 72  urgeable = (bPur
3eb0: 67 65 61 62 6c 65 20 3f 20 31 20 3a 20 30 29 3b  geable ? 1 : 0);
3ec0: 0a 20 20 20 20 69 66 28 20 62 50 75 72 67 65 61  .    if( bPurgea
3ed0: 62 6c 65 20 29 7b 0a 20 20 20 20 20 20 70 43 61  ble ){.      pCa
3ee0: 63 68 65 2d 3e 6e 4d 69 6e 20 3d 20 31 30 3b 0a  che->nMin = 10;.
3ef0: 20 20 20 20 20 20 70 63 61 63 68 65 31 45 6e 74        pcache1Ent
3f00: 65 72 4d 75 74 65 78 28 29 3b 0a 20 20 20 20 20  erMutex();.     
3f10: 20 70 63 61 63 68 65 31 2e 6e 4d 69 6e 50 61 67   pcache1.nMinPag
3f20: 65 20 2b 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 69  e += pCache->nMi
3f30: 6e 3b 0a 20 20 20 20 20 20 70 63 61 63 68 65 31  n;.      pcache1
3f40: 4c 65 61 76 65 4d 75 74 65 78 28 29 3b 0a 20 20  LeaveMutex();.  
3f50: 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e    }.  }.  return
3f60: 20 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65   (sqlite3_pcache
3f70: 20 2a 29 70 43 61 63 68 65 3b 0a 7d 0a 0a 2f 2a   *)pCache;.}../*
3f80: 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69  .** Implementati
3f90: 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65  on of the sqlite
3fa0: 33 5f 70 63 61 63 68 65 2e 78 43 61 63 68 65 73  3_pcache.xCaches
3fb0: 69 7a 65 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a  ize method. .**.
3fc0: 2a 2a 20 43 6f 6e 66 69 67 75 72 65 20 74 68 65  ** Configure the
3fd0: 20 63 61 63 68 65 5f 73 69 7a 65 20 6c 69 6d 69   cache_size limi
3fe0: 74 20 66 6f 72 20 61 20 63 61 63 68 65 2e 0a 2a  t for a cache..*
3ff0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63  /.static void pc
4000: 61 63 68 65 31 43 61 63 68 65 73 69 7a 65 28 73  ache1Cachesize(s
4010: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70  qlite3_pcache *p
4020: 2c 20 69 6e 74 20 6e 4d 61 78 29 7b 0a 20 20 50  , int nMax){.  P
4030: 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d  Cache1 *pCache =
4040: 20 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20   (PCache1 *)p;. 
4050: 20 69 66 28 20 70 43 61 63 68 65 2d 3e 62 50 75   if( pCache->bPu
4060: 72 67 65 61 62 6c 65 20 29 7b 0a 20 20 20 20 70  rgeable ){.    p
4070: 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78  cache1EnterMutex
4080: 28 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e  ();.    pcache1.
4090: 6e 4d 61 78 50 61 67 65 20 2b 3d 20 28 6e 4d 61  nMaxPage += (nMa
40a0: 78 20 2d 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78  x - pCache->nMax
40b0: 29 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 6e  );.    pCache->n
40c0: 4d 61 78 20 3d 20 6e 4d 61 78 3b 0a 20 20 20 20  Max = nMax;.    
40d0: 70 63 61 63 68 65 31 45 6e 66 6f 72 63 65 4d 61  pcache1EnforceMa
40e0: 78 50 61 67 65 28 29 3b 0a 20 20 20 20 70 63 61  xPage();.    pca
40f0: 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 29  che1LeaveMutex()
4100: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49  ;.  }.}../*.** I
4110: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66  mplementation of
4120: 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61   the sqlite3_pca
4130: 63 68 65 2e 78 50 61 67 65 63 6f 75 6e 74 20 6d  che.xPagecount m
4140: 65 74 68 6f 64 2e 20 0a 2a 2f 0a 73 74 61 74 69  ethod. .*/.stati
4150: 63 20 69 6e 74 20 70 63 61 63 68 65 31 50 61 67  c int pcache1Pag
4160: 65 63 6f 75 6e 74 28 73 71 6c 69 74 65 33 5f 70  ecount(sqlite3_p
4170: 63 61 63 68 65 20 2a 70 29 7b 0a 20 20 69 6e 74  cache *p){.  int
4180: 20 6e 3b 0a 20 20 70 63 61 63 68 65 31 45 6e 74   n;.  pcache1Ent
4190: 65 72 4d 75 74 65 78 28 29 3b 0a 20 20 6e 20 3d  erMutex();.  n =
41a0: 20 28 28 50 43 61 63 68 65 31 20 2a 29 70 29 2d   ((PCache1 *)p)-
41b0: 3e 6e 50 61 67 65 3b 0a 20 20 70 63 61 63 68 65  >nPage;.  pcache
41c0: 31 4c 65 61 76 65 4d 75 74 65 78 28 29 3b 0a 20  1LeaveMutex();. 
41d0: 20 72 65 74 75 72 6e 20 6e 3b 0a 7d 0a 0a 2f 2a   return n;.}../*
41e0: 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69  .** Implementati
41f0: 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65  on of the sqlite
4200: 33 5f 70 63 61 63 68 65 2e 78 46 65 74 63 68 20  3_pcache.xFetch 
4210: 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20 46  method. .**.** F
4220: 65 74 63 68 20 61 20 70 61 67 65 20 62 79 20 6b  etch a page by k
4230: 65 79 20 76 61 6c 75 65 2e 0a 2a 2a 0a 2a 2a 20  ey value..**.** 
4240: 57 68 65 74 68 65 72 20 6f 72 20 6e 6f 74 20 61  Whether or not a
4250: 20 6e 65 77 20 70 61 67 65 20 6d 61 79 20 62 65   new page may be
4260: 20 61 6c 6c 6f 63 61 74 65 64 20 62 79 20 74 68   allocated by th
4270: 69 73 20 66 75 6e 63 74 69 6f 6e 20 64 65 70 65  is function depe
4280: 6e 64 73 20 6f 6e 0a 2a 2a 20 74 68 65 20 76 61  nds on.** the va
4290: 6c 75 65 20 6f 66 20 74 68 65 20 63 72 65 61 74  lue of the creat
42a0: 65 46 6c 61 67 20 61 72 67 75 6d 65 6e 74 2e 20  eFlag argument. 
42b0: 20 30 20 6d 65 61 6e 73 20 64 6f 20 6e 6f 74 20   0 means do not 
42c0: 61 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 0a 2a  allocate a new.*
42d0: 2a 20 70 61 67 65 2e 20 20 31 20 6d 65 61 6e 73  * page.  1 means
42e0: 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20   allocate a new 
42f0: 70 61 67 65 20 69 66 20 73 70 61 63 65 20 69 73  page if space is
4300: 20 65 61 73 69 6c 79 20 61 76 61 69 6c 61 62 6c   easily availabl
4310: 65 2e 20 20 32 20 0a 2a 2a 20 6d 65 61 6e 73 20  e.  2 .** means 
4320: 74 6f 20 74 72 79 20 72 65 61 6c 6c 79 20 68 61  to try really ha
4330: 72 64 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 61  rd to allocate a
4340: 20 6e 65 77 20 70 61 67 65 2e 0a 2a 2a 0a 2a 2a   new page..**.**
4350: 20 46 6f 72 20 61 20 6e 6f 6e 2d 70 75 72 67 65   For a non-purge
4360: 61 62 6c 65 20 63 61 63 68 65 20 28 61 20 63 61  able cache (a ca
4370: 63 68 65 20 75 73 65 64 20 61 73 20 74 68 65 20  che used as the 
4380: 73 74 6f 72 61 67 65 20 66 6f 72 20 61 6e 20 69  storage for an i
4390: 6e 2d 6d 65 6d 6f 72 79 0a 2a 2a 20 64 61 74 61  n-memory.** data
43a0: 62 61 73 65 29 20 74 68 65 72 65 20 69 73 20 72  base) there is r
43b0: 65 61 6c 6c 79 20 6e 6f 20 64 69 66 66 65 72 65  eally no differe
43c0: 6e 63 65 20 62 65 74 77 65 65 6e 20 63 72 65 61  nce between crea
43d0: 74 65 46 6c 61 67 20 31 20 61 6e 64 20 32 2e 20  teFlag 1 and 2. 
43e0: 20 53 6f 0a 2a 2a 20 74 68 65 20 63 61 6c 6c 69   So.** the calli
43f0: 6e 67 20 66 75 6e 63 74 69 6f 6e 20 28 70 63 61  ng function (pca
4400: 63 68 65 2e 63 29 20 77 69 6c 6c 20 6e 65 76 65  che.c) will neve
4410: 72 20 68 61 76 65 20 61 20 63 72 65 61 74 65 46  r have a createF
4420: 6c 61 67 20 6f 66 20 31 20 6f 6e 0a 2a 2a 20 61  lag of 1 on.** a
4430: 20 6e 6f 6e 2d 70 75 72 67 61 62 6c 65 20 63 61   non-purgable ca
4440: 63 68 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 72 65  che..**.** There
4450: 20 61 72 65 20 74 68 72 65 65 20 64 69 66 66 65   are three diffe
4460: 72 65 6e 74 20 61 70 70 72 6f 61 63 68 65 73 20  rent approaches 
4470: 74 6f 20 6f 62 74 61 69 6e 69 6e 67 20 73 70 61  to obtaining spa
4480: 63 65 20 66 6f 72 20 61 20 70 61 67 65 2c 0a 2a  ce for a page,.*
4490: 2a 20 64 65 70 65 6e 64 69 6e 67 20 6f 6e 20 74  * depending on t
44a0: 68 65 20 76 61 6c 75 65 20 6f 66 20 70 61 72 61  he value of para
44b0: 6d 65 74 65 72 20 63 72 65 61 74 65 46 6c 61 67  meter createFlag
44c0: 20 28 77 68 69 63 68 20 6d 61 79 20 62 65 20 30   (which may be 0
44d0: 2c 20 31 20 6f 72 20 32 29 2e 0a 2a 2a 0a 2a 2a  , 1 or 2)..**.**
44e0: 20 20 20 31 2e 20 52 65 67 61 72 64 6c 65 73 73     1. Regardless
44f0: 20 6f 66 20 74 68 65 20 76 61 6c 75 65 20 6f 66   of the value of
4500: 20 63 72 65 61 74 65 46 6c 61 67 2c 20 74 68 65   createFlag, the
4510: 20 63 61 63 68 65 20 69 73 20 73 65 61 72 63 68   cache is search
4520: 65 64 20 66 6f 72 20 61 20 0a 2a 2a 20 20 20 20  ed for a .**    
4530: 20 20 63 6f 70 79 20 6f 66 20 74 68 65 20 72 65    copy of the re
4540: 71 75 65 73 74 65 64 20 70 61 67 65 2e 20 49 66  quested page. If
4550: 20 6f 6e 65 20 69 73 20 66 6f 75 6e 64 2c 20 69   one is found, i
4560: 74 20 69 73 20 72 65 74 75 72 6e 65 64 2e 0a 2a  t is returned..*
4570: 2a 0a 2a 2a 20 20 20 32 2e 20 49 66 20 63 72 65  *.**   2. If cre
4580: 61 74 65 46 6c 61 67 3d 3d 30 20 61 6e 64 20 74  ateFlag==0 and t
4590: 68 65 20 70 61 67 65 20 69 73 20 6e 6f 74 20 61  he page is not a
45a0: 6c 72 65 61 64 79 20 69 6e 20 74 68 65 20 63 61  lready in the ca
45b0: 63 68 65 2c 20 4e 55 4c 4c 20 69 73 0a 2a 2a 20  che, NULL is.** 
45c0: 20 20 20 20 20 72 65 74 75 72 6e 65 64 2e 0a 2a       returned..*
45d0: 2a 0a 2a 2a 20 20 20 33 2e 20 49 66 20 63 72 65  *.**   3. If cre
45e0: 61 74 65 46 6c 61 67 20 69 73 20 31 2c 20 61 6e  ateFlag is 1, an
45f0: 64 20 74 68 65 20 70 61 67 65 20 69 73 20 6e 6f  d the page is no
4600: 74 20 61 6c 72 65 61 64 79 20 69 6e 20 74 68 65  t already in the
4610: 20 63 61 63 68 65 2c 20 74 68 65 6e 0a 2a 2a 20   cache, then.** 
4620: 20 20 20 20 20 72 65 74 75 72 6e 20 4e 55 4c 4c       return NULL
4630: 20 28 64 6f 20 6e 6f 74 20 61 6c 6c 6f 63 61 74   (do not allocat
4640: 65 20 61 20 6e 65 77 20 70 61 67 65 29 20 69 66  e a new page) if
4650: 20 61 6e 79 20 6f 66 20 74 68 65 20 66 6f 6c 6c   any of the foll
4660: 6f 77 69 6e 67 0a 2a 2a 20 20 20 20 20 20 63 6f  owing.**      co
4670: 6e 64 69 74 69 6f 6e 73 20 61 72 65 20 74 72 75  nditions are tru
4680: 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 28  e:.**.**       (
4690: 61 29 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  a) the number of
46a0: 20 70 61 67 65 73 20 70 69 6e 6e 65 64 20 62 79   pages pinned by
46b0: 20 74 68 65 20 63 61 63 68 65 20 69 73 20 67 72   the cache is gr
46c0: 65 61 74 65 72 20 74 68 61 6e 0a 2a 2a 20 20 20  eater than.**   
46d0: 20 20 20 20 20 20 20 20 50 43 61 63 68 65 31 2e          PCache1.
46e0: 6e 4d 61 78 2c 20 6f 72 0a 2a 2a 0a 2a 2a 20 20  nMax, or.**.**  
46f0: 20 20 20 20 20 28 62 29 20 74 68 65 20 6e 75 6d       (b) the num
4700: 62 65 72 20 6f 66 20 70 61 67 65 73 20 70 69 6e  ber of pages pin
4710: 6e 65 64 20 62 79 20 74 68 65 20 63 61 63 68 65  ned by the cache
4720: 20 69 73 20 67 72 65 61 74 65 72 20 74 68 61 6e   is greater than
4730: 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 74 68  .**           th
4740: 65 20 73 75 6d 20 6f 66 20 6e 4d 61 78 20 66 6f  e sum of nMax fo
4750: 72 20 61 6c 6c 20 70 75 72 67 65 61 62 6c 65 20  r all purgeable 
4760: 63 61 63 68 65 73 2c 20 6c 65 73 73 20 74 68 65  caches, less the
4770: 20 73 75 6d 20 6f 66 20 0a 2a 2a 20 20 20 20 20   sum of .**     
4780: 20 20 20 20 20 20 6e 4d 69 6e 20 66 6f 72 20 61        nMin for a
4790: 6c 6c 20 6f 74 68 65 72 20 70 75 72 67 65 61 62  ll other purgeab
47a0: 6c 65 20 63 61 63 68 65 73 2c 20 6f 72 0a 2a 2a  le caches, or.**
47b0: 0a 2a 2a 20 20 20 34 2e 20 49 66 20 6e 6f 6e 65  .**   4. If none
47c0: 20 6f 66 20 74 68 65 20 66 69 72 73 74 20 74 68   of the first th
47d0: 72 65 65 20 63 6f 6e 64 69 74 69 6f 6e 73 20 61  ree conditions a
47e0: 70 70 6c 79 20 61 6e 64 20 74 68 65 20 63 61 63  pply and the cac
47f0: 68 65 20 69 73 20 6d 61 72 6b 65 64 0a 2a 2a 20  he is marked.** 
4800: 20 20 20 20 20 61 73 20 70 75 72 67 65 61 62 6c       as purgeabl
4810: 65 2c 20 61 6e 64 20 69 66 20 6f 6e 65 20 6f 66  e, and if one of
4820: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 69   the following i
4830: 73 20 74 72 75 65 3a 0a 2a 2a 0a 2a 2a 20 20 20  s true:.**.**   
4840: 20 20 20 20 28 61 29 20 54 68 65 20 6e 75 6d 62      (a) The numb
4850: 65 72 20 6f 66 20 70 61 67 65 73 20 61 6c 6c 6f  er of pages allo
4860: 63 61 74 65 64 20 66 6f 72 20 74 68 65 20 63 61  cated for the ca
4870: 63 68 65 20 69 73 20 61 6c 72 65 61 64 79 20 0a  che is already .
4880: 2a 2a 20 20 20 20 20 20 20 20 20 20 20 50 43 61  **           PCa
4890: 63 68 65 31 2e 6e 4d 61 78 2c 20 6f 72 0a 2a 2a  che1.nMax, or.**
48a0: 0a 2a 2a 20 20 20 20 20 20 20 28 62 29 20 54 68  .**       (b) Th
48b0: 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65  e number of page
48c0: 73 20 61 6c 6c 6f 63 61 74 65 64 20 66 6f 72 20  s allocated for 
48d0: 61 6c 6c 20 70 75 72 67 65 61 62 6c 65 20 63 61  all purgeable ca
48e0: 63 68 65 73 20 69 73 0a 2a 2a 20 20 20 20 20 20  ches is.**      
48f0: 20 20 20 20 20 61 6c 72 65 61 64 79 20 65 71 75       already equ
4900: 61 6c 20 74 6f 20 6f 72 20 67 72 65 61 74 65 72  al to or greater
4910: 20 74 68 61 6e 20 74 68 65 20 73 75 6d 20 6f 66   than the sum of
4920: 20 6e 4d 61 78 20 66 6f 72 20 61 6c 6c 0a 2a 2a   nMax for all.**
4930: 20 20 20 20 20 20 20 20 20 20 20 70 75 72 67 65             purge
4940: 61 62 6c 65 20 63 61 63 68 65 73 2c 0a 2a 2a 0a  able caches,.**.
4950: 2a 2a 20 20 20 20 20 20 20 28 63 29 20 54 68 65  **       (c) The
4960: 20 73 79 73 74 65 6d 20 69 73 20 75 6e 64 65 72   system is under
4970: 20 6d 65 6d 6f 72 79 20 70 72 65 73 73 75 72 65   memory pressure
4980: 20 61 6e 64 20 77 61 6e 74 73 20 74 6f 20 61 76   and wants to av
4990: 6f 69 64 0a 2a 2a 20 20 20 20 20 20 20 20 20 20  oid.**          
49a0: 20 75 6e 6e 65 63 65 73 73 61 72 79 20 70 61 67   unnecessary pag
49b0: 65 73 20 63 61 63 68 65 20 65 6e 74 72 79 20 61  es cache entry a
49c0: 6c 6c 6f 63 61 74 69 6f 6e 73 0a 2a 2a 0a 2a 2a  llocations.**.**
49d0: 20 20 20 20 20 20 74 68 65 6e 20 61 74 74 65 6d        then attem
49e0: 70 74 20 74 6f 20 72 65 63 79 63 6c 65 20 61 20  pt to recycle a 
49f0: 70 61 67 65 20 66 72 6f 6d 20 74 68 65 20 4c 52  page from the LR
4a00: 55 20 6c 69 73 74 2e 20 49 66 20 69 74 20 69 73  U list. If it is
4a10: 20 74 68 65 20 72 69 67 68 74 0a 2a 2a 20 20 20   the right.**   
4a20: 20 20 20 73 69 7a 65 2c 20 72 65 74 75 72 6e 20     size, return 
4a30: 74 68 65 20 72 65 63 79 63 6c 65 64 20 62 75 66  the recycled buf
4a40: 66 65 72 2e 20 4f 74 68 65 72 77 69 73 65 2c 20  fer. Otherwise, 
4a50: 66 72 65 65 20 74 68 65 20 62 75 66 66 65 72 20  free the buffer 
4a60: 61 6e 64 0a 2a 2a 20 20 20 20 20 20 70 72 6f 63  and.**      proc
4a70: 65 65 64 20 74 6f 20 73 74 65 70 20 35 2e 20 0a  eed to step 5. .
4a80: 2a 2a 0a 2a 2a 20 20 20 35 2e 20 4f 74 68 65 72  **.**   5. Other
4a90: 77 69 73 65 2c 20 61 6c 6c 6f 63 61 74 65 20 61  wise, allocate a
4aa0: 6e 64 20 72 65 74 75 72 6e 20 61 20 6e 65 77 20  nd return a new 
4ab0: 70 61 67 65 20 62 75 66 66 65 72 2e 0a 2a 2f 0a  page buffer..*/.
4ac0: 73 74 61 74 69 63 20 76 6f 69 64 20 2a 70 63 61  static void *pca
4ad0: 63 68 65 31 46 65 74 63 68 28 73 71 6c 69 74 65  che1Fetch(sqlite
4ae0: 33 5f 70 63 61 63 68 65 20 2a 70 2c 20 75 6e 73  3_pcache *p, uns
4af0: 69 67 6e 65 64 20 69 6e 74 20 69 4b 65 79 2c 20  igned int iKey, 
4b00: 69 6e 74 20 63 72 65 61 74 65 46 6c 61 67 29 7b  int createFlag){
4b10: 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  .  unsigned int 
4b20: 6e 50 69 6e 6e 65 64 3b 0a 20 20 50 43 61 63 68  nPinned;.  PCach
4b30: 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43  e1 *pCache = (PC
4b40: 61 63 68 65 31 20 2a 29 70 3b 0a 20 20 50 67 48  ache1 *)p;.  PgH
4b50: 64 72 31 20 2a 70 50 61 67 65 20 3d 20 30 3b 0a  dr1 *pPage = 0;.
4b60: 0a 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68  .  assert( pCach
4b70: 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 7c 7c  e->bPurgeable ||
4b80: 20 63 72 65 61 74 65 46 6c 61 67 21 3d 31 20 29   createFlag!=1 )
4b90: 3b 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65 72  ;.  pcache1Enter
4ba0: 4d 75 74 65 78 28 29 3b 0a 20 20 69 66 28 20 63  Mutex();.  if( c
4bb0: 72 65 61 74 65 46 6c 61 67 3d 3d 31 20 29 20 73  reateFlag==1 ) s
4bc0: 71 6c 69 74 65 33 42 65 67 69 6e 42 65 6e 69 67  qlite3BeginBenig
4bd0: 6e 4d 61 6c 6c 6f 63 28 29 3b 0a 0a 20 20 2f 2a  nMalloc();..  /*
4be0: 20 53 65 61 72 63 68 20 74 68 65 20 68 61 73 68   Search the hash
4bf0: 20 74 61 62 6c 65 20 66 6f 72 20 61 6e 20 65 78   table for an ex
4c00: 69 73 74 69 6e 67 20 65 6e 74 72 79 2e 20 2a 2f  isting entry. */
4c10: 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 6e  .  if( pCache->n
4c20: 48 61 73 68 3e 30 20 29 7b 0a 20 20 20 20 75 6e  Hash>0 ){.    un
4c30: 73 69 67 6e 65 64 20 69 6e 74 20 68 20 3d 20 69  signed int h = i
4c40: 4b 65 79 20 25 20 70 43 61 63 68 65 2d 3e 6e 48  Key % pCache->nH
4c50: 61 73 68 3b 0a 20 20 20 20 66 6f 72 28 70 50 61  ash;.    for(pPa
4c60: 67 65 3d 70 43 61 63 68 65 2d 3e 61 70 48 61 73  ge=pCache->apHas
4c70: 68 5b 68 5d 3b 20 70 50 61 67 65 26 26 70 50 61  h[h]; pPage&&pPa
4c80: 67 65 2d 3e 69 4b 65 79 21 3d 69 4b 65 79 3b 20  ge->iKey!=iKey; 
4c90: 70 50 61 67 65 3d 70 50 61 67 65 2d 3e 70 4e 65  pPage=pPage->pNe
4ca0: 78 74 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20  xt);.  }..  if( 
4cb0: 70 50 61 67 65 20 7c 7c 20 63 72 65 61 74 65 46  pPage || createF
4cc0: 6c 61 67 3d 3d 30 20 29 7b 0a 20 20 20 20 70 63  lag==0 ){.    pc
4cd0: 61 63 68 65 31 50 69 6e 50 61 67 65 28 70 50 61  ache1PinPage(pPa
4ce0: 67 65 29 3b 0a 20 20 20 20 67 6f 74 6f 20 66 65  ge);.    goto fe
4cf0: 74 63 68 5f 6f 75 74 3b 0a 20 20 7d 0a 0a 20 20  tch_out;.  }..  
4d00: 2f 2a 20 53 74 65 70 20 33 20 6f 66 20 68 65 61  /* Step 3 of hea
4d10: 64 65 72 20 63 6f 6d 6d 65 6e 74 2e 20 2a 2f 0a  der comment. */.
4d20: 20 20 6e 50 69 6e 6e 65 64 20 3d 20 70 43 61 63    nPinned = pCac
4d30: 68 65 2d 3e 6e 50 61 67 65 20 2d 20 70 43 61 63  he->nPage - pCac
4d40: 68 65 2d 3e 6e 52 65 63 79 63 6c 61 62 6c 65 3b  he->nRecyclable;
4d50: 0a 20 20 69 66 28 20 63 72 65 61 74 65 46 6c 61  .  if( createFla
4d60: 67 3d 3d 31 20 26 26 20 28 0a 20 20 20 20 20 20  g==1 && (.      
4d70: 20 20 6e 50 69 6e 6e 65 64 3e 3d 28 70 63 61 63    nPinned>=(pcac
4d80: 68 65 31 2e 6e 4d 61 78 50 61 67 65 2b 70 43 61  he1.nMaxPage+pCa
4d90: 63 68 65 2d 3e 6e 4d 69 6e 2d 70 63 61 63 68 65  che->nMin-pcache
4da0: 31 2e 6e 4d 69 6e 50 61 67 65 29 0a 20 20 20 20  1.nMinPage).    
4db0: 20 7c 7c 20 6e 50 69 6e 6e 65 64 3e 3d 28 70 43   || nPinned>=(pC
4dc0: 61 63 68 65 2d 3e 6e 4d 61 78 20 2a 20 39 20 2f  ache->nMax * 9 /
4dd0: 20 31 30 29 0a 20 20 20 20 20 7c 7c 20 70 63 61   10).     || pca
4de0: 63 68 65 31 55 6e 64 65 72 4d 65 6d 6f 72 79 50  che1UnderMemoryP
4df0: 72 65 73 73 75 72 65 28 70 43 61 63 68 65 29 0a  ressure(pCache).
4e00: 20 20 29 29 7b 0a 20 20 20 20 67 6f 74 6f 20 66    )){.    goto f
4e10: 65 74 63 68 5f 6f 75 74 3b 0a 20 20 7d 0a 0a 20  etch_out;.  }.. 
4e20: 20 69 66 28 20 70 43 61 63 68 65 2d 3e 6e 50 61   if( pCache->nPa
4e30: 67 65 3e 3d 70 43 61 63 68 65 2d 3e 6e 48 61 73  ge>=pCache->nHas
4e40: 68 20 26 26 20 70 63 61 63 68 65 31 52 65 73 69  h && pcache1Resi
4e50: 7a 65 48 61 73 68 28 70 43 61 63 68 65 29 20 29  zeHash(pCache) )
4e60: 7b 0a 20 20 20 20 67 6f 74 6f 20 66 65 74 63 68  {.    goto fetch
4e70: 5f 6f 75 74 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  _out;.  }..  /* 
4e80: 53 74 65 70 20 34 2e 20 54 72 79 20 74 6f 20 72  Step 4. Try to r
4e90: 65 63 79 63 6c 65 20 61 20 70 61 67 65 20 62 75  ecycle a page bu
4ea0: 66 66 65 72 20 69 66 20 61 70 70 72 6f 70 72 69  ffer if appropri
4eb0: 61 74 65 2e 20 2a 2f 0a 20 20 69 66 28 20 70 43  ate. */.  if( pC
4ec0: 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65  ache->bPurgeable
4ed0: 20 26 26 20 70 63 61 63 68 65 31 2e 70 4c 72 75   && pcache1.pLru
4ee0: 54 61 69 6c 20 26 26 20 28 0a 20 20 20 20 20 20  Tail && (.      
4ef0: 20 20 20 28 70 43 61 63 68 65 2d 3e 6e 50 61 67     (pCache->nPag
4f00: 65 2b 31 3e 3d 70 43 61 63 68 65 2d 3e 6e 4d 61  e+1>=pCache->nMa
4f10: 78 29 0a 20 20 20 20 20 20 7c 7c 20 70 63 61 63  x).      || pcac
4f20: 68 65 31 2e 6e 43 75 72 72 65 6e 74 50 61 67 65  he1.nCurrentPage
4f30: 3e 3d 70 63 61 63 68 65 31 2e 6e 4d 61 78 50 61  >=pcache1.nMaxPa
4f40: 67 65 0a 20 20 20 20 20 20 7c 7c 20 70 63 61 63  ge.      || pcac
4f50: 68 65 31 55 6e 64 65 72 4d 65 6d 6f 72 79 50 72  he1UnderMemoryPr
4f60: 65 73 73 75 72 65 28 70 43 61 63 68 65 29 0a 20  essure(pCache). 
4f70: 20 29 29 7b 0a 20 20 20 20 70 50 61 67 65 20 3d   )){.    pPage =
4f80: 20 70 63 61 63 68 65 31 2e 70 4c 72 75 54 61 69   pcache1.pLruTai
4f90: 6c 3b 0a 20 20 20 20 70 63 61 63 68 65 31 52 65  l;.    pcache1Re
4fa0: 6d 6f 76 65 46 72 6f 6d 48 61 73 68 28 70 50 61  moveFromHash(pPa
4fb0: 67 65 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31  ge);.    pcache1
4fc0: 50 69 6e 50 61 67 65 28 70 50 61 67 65 29 3b 0a  PinPage(pPage);.
4fd0: 20 20 20 20 69 66 28 20 70 50 61 67 65 2d 3e 70      if( pPage->p
4fe0: 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 21 3d 70  Cache->szPage!=p
4ff0: 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 20 29 7b  Cache->szPage ){
5000: 0a 20 20 20 20 20 20 70 63 61 63 68 65 31 46 72  .      pcache1Fr
5010: 65 65 50 61 67 65 28 70 50 61 67 65 29 3b 0a 20  eePage(pPage);. 
5020: 20 20 20 20 20 70 50 61 67 65 20 3d 20 30 3b 0a       pPage = 0;.
5030: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
5040: 20 70 63 61 63 68 65 31 2e 6e 43 75 72 72 65 6e   pcache1.nCurren
5050: 74 50 61 67 65 20 2d 3d 20 28 70 50 61 67 65 2d  tPage -= (pPage-
5060: 3e 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61  >pCache->bPurgea
5070: 62 6c 65 20 2d 20 70 43 61 63 68 65 2d 3e 62 50  ble - pCache->bP
5080: 75 72 67 65 61 62 6c 65 29 3b 0a 20 20 20 20 7d  urgeable);.    }
5090: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53 74 65 70 20  .  }..  /* Step 
50a0: 35 2e 20 49 66 20 61 20 75 73 61 62 6c 65 20 70  5. If a usable p
50b0: 61 67 65 20 62 75 66 66 65 72 20 68 61 73 20 73  age buffer has s
50c0: 74 69 6c 6c 20 6e 6f 74 20 62 65 65 6e 20 66 6f  till not been fo
50d0: 75 6e 64 2c 20 0a 20 20 2a 2a 20 61 74 74 65 6d  und, .  ** attem
50e0: 70 74 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 61  pt to allocate a
50f0: 20 6e 65 77 20 6f 6e 65 2e 20 0a 20 20 2a 2f 0a   new one. .  */.
5100: 20 20 69 66 28 20 21 70 50 61 67 65 20 29 7b 0a    if( !pPage ){.
5110: 20 20 20 20 70 50 61 67 65 20 3d 20 70 63 61 63      pPage = pcac
5120: 68 65 31 41 6c 6c 6f 63 50 61 67 65 28 70 43 61  he1AllocPage(pCa
5130: 63 68 65 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28  che);.  }..  if(
5140: 20 70 50 61 67 65 20 29 7b 0a 20 20 20 20 75 6e   pPage ){.    un
5150: 73 69 67 6e 65 64 20 69 6e 74 20 68 20 3d 20 69  signed int h = i
5160: 4b 65 79 20 25 20 70 43 61 63 68 65 2d 3e 6e 48  Key % pCache->nH
5170: 61 73 68 3b 0a 20 20 20 20 70 43 61 63 68 65 2d  ash;.    pCache-
5180: 3e 6e 50 61 67 65 2b 2b 3b 0a 20 20 20 20 70 50  >nPage++;.    pP
5190: 61 67 65 2d 3e 69 4b 65 79 20 3d 20 69 4b 65 79  age->iKey = iKey
51a0: 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 4e 65  ;.    pPage->pNe
51b0: 78 74 20 3d 20 70 43 61 63 68 65 2d 3e 61 70 48  xt = pCache->apH
51c0: 61 73 68 5b 68 5d 3b 0a 20 20 20 20 70 50 61 67  ash[h];.    pPag
51d0: 65 2d 3e 70 43 61 63 68 65 20 3d 20 70 43 61 63  e->pCache = pCac
51e0: 68 65 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 70  he;.    pPage->p
51f0: 4c 72 75 50 72 65 76 20 3d 20 30 3b 0a 20 20 20  LruPrev = 0;.   
5200: 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74   pPage->pLruNext
5210: 20 3d 20 30 3b 0a 20 20 20 20 2a 28 76 6f 69 64   = 0;.    *(void
5220: 20 2a 2a 29 28 50 47 48 44 52 31 5f 54 4f 5f 50   **)(PGHDR1_TO_P
5230: 41 47 45 28 70 50 61 67 65 29 29 20 3d 20 30 3b  AGE(pPage)) = 0;
5240: 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 61 70 48  .    pCache->apH
5250: 61 73 68 5b 68 5d 20 3d 20 70 50 61 67 65 3b 0a  ash[h] = pPage;.
5260: 20 20 7d 0a 0a 66 65 74 63 68 5f 6f 75 74 3a 0a    }..fetch_out:.
5270: 20 20 69 66 28 20 70 50 61 67 65 20 26 26 20 69    if( pPage && i
5280: 4b 65 79 3e 70 43 61 63 68 65 2d 3e 69 4d 61 78  Key>pCache->iMax
5290: 4b 65 79 20 29 7b 0a 20 20 20 20 70 43 61 63 68  Key ){.    pCach
52a0: 65 2d 3e 69 4d 61 78 4b 65 79 20 3d 20 69 4b 65  e->iMaxKey = iKe
52b0: 79 3b 0a 20 20 7d 0a 20 20 69 66 28 20 63 72 65  y;.  }.  if( cre
52c0: 61 74 65 46 6c 61 67 3d 3d 31 20 29 20 73 71 6c  ateFlag==1 ) sql
52d0: 69 74 65 33 45 6e 64 42 65 6e 69 67 6e 4d 61 6c  ite3EndBenignMal
52e0: 6c 6f 63 28 29 3b 0a 20 20 70 63 61 63 68 65 31  loc();.  pcache1
52f0: 4c 65 61 76 65 4d 75 74 65 78 28 29 3b 0a 20 20  LeaveMutex();.  
5300: 72 65 74 75 72 6e 20 28 70 50 61 67 65 20 3f 20  return (pPage ? 
5310: 50 47 48 44 52 31 5f 54 4f 5f 50 41 47 45 28 70  PGHDR1_TO_PAGE(p
5320: 50 61 67 65 29 20 3a 20 30 29 3b 0a 7d 0a 0a 0a  Page) : 0);.}...
5330: 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61  /*.** Implementa
5340: 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69  tion of the sqli
5350: 74 65 33 5f 70 63 61 63 68 65 2e 78 55 6e 70 69  te3_pcache.xUnpi
5360: 6e 20 6d 65 74 68 6f 64 2e 0a 2a 2a 0a 2a 2a 20  n method..**.** 
5370: 4d 61 72 6b 20 61 20 70 61 67 65 20 61 73 20 75  Mark a page as u
5380: 6e 70 69 6e 6e 65 64 20 28 65 6c 69 67 69 62 6c  npinned (eligibl
5390: 65 20 66 6f 72 20 61 73 79 6e 63 68 72 6f 6e 6f  e for asynchrono
53a0: 75 73 20 72 65 63 79 63 6c 69 6e 67 29 2e 0a 2a  us recycling)..*
53b0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63  /.static void pc
53c0: 61 63 68 65 31 55 6e 70 69 6e 28 73 71 6c 69 74  ache1Unpin(sqlit
53d0: 65 33 5f 70 63 61 63 68 65 20 2a 70 2c 20 76 6f  e3_pcache *p, vo
53e0: 69 64 20 2a 70 50 67 2c 20 69 6e 74 20 72 65 75  id *pPg, int reu
53f0: 73 65 55 6e 6c 69 6b 65 6c 79 29 7b 0a 20 20 50  seUnlikely){.  P
5400: 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d  Cache1 *pCache =
5410: 20 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20   (PCache1 *)p;. 
5420: 20 50 67 48 64 72 31 20 2a 70 50 61 67 65 20 3d   PgHdr1 *pPage =
5430: 20 50 41 47 45 5f 54 4f 5f 50 47 48 44 52 31 28   PAGE_TO_PGHDR1(
5440: 70 43 61 63 68 65 2c 20 70 50 67 29 3b 0a 20 0a  pCache, pPg);. .
5450: 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65 2d    assert( pPage-
5460: 3e 70 43 61 63 68 65 3d 3d 70 43 61 63 68 65 20  >pCache==pCache 
5470: 29 3b 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65  );.  pcache1Ente
5480: 72 4d 75 74 65 78 28 29 3b 0a 0a 20 20 2f 2a 20  rMutex();..  /* 
5490: 49 74 20 69 73 20 61 6e 20 65 72 72 6f 72 20 74  It is an error t
54a0: 6f 20 63 61 6c 6c 20 74 68 69 73 20 66 75 6e 63  o call this func
54b0: 74 69 6f 6e 20 69 66 20 74 68 65 20 70 61 67 65  tion if the page
54c0: 20 69 73 20 61 6c 72 65 61 64 79 20 0a 20 20 2a   is already .  *
54d0: 2a 20 70 61 72 74 20 6f 66 20 74 68 65 20 67 6c  * part of the gl
54e0: 6f 62 61 6c 20 4c 52 55 20 6c 69 73 74 2e 0a 20  obal LRU list.. 
54f0: 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 50   */.  assert( pP
5500: 61 67 65 2d 3e 70 4c 72 75 50 72 65 76 3d 3d 30  age->pLruPrev==0
5510: 20 26 26 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e   && pPage->pLruN
5520: 65 78 74 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65  ext==0 );.  asse
5530: 72 74 28 20 70 63 61 63 68 65 31 2e 70 4c 72 75  rt( pcache1.pLru
5540: 48 65 61 64 21 3d 70 50 61 67 65 20 26 26 20 70  Head!=pPage && p
5550: 63 61 63 68 65 31 2e 70 4c 72 75 54 61 69 6c 21  cache1.pLruTail!
5560: 3d 70 50 61 67 65 20 29 3b 0a 0a 20 20 69 66 28  =pPage );..  if(
5570: 20 72 65 75 73 65 55 6e 6c 69 6b 65 6c 79 20 7c   reuseUnlikely |
5580: 7c 20 70 63 61 63 68 65 31 2e 6e 43 75 72 72 65  | pcache1.nCurre
5590: 6e 74 50 61 67 65 3e 70 63 61 63 68 65 31 2e 6e  ntPage>pcache1.n
55a0: 4d 61 78 50 61 67 65 20 29 7b 0a 20 20 20 20 70  MaxPage ){.    p
55b0: 63 61 63 68 65 31 52 65 6d 6f 76 65 46 72 6f 6d  cache1RemoveFrom
55c0: 48 61 73 68 28 70 50 61 67 65 29 3b 0a 20 20 20  Hash(pPage);.   
55d0: 20 70 63 61 63 68 65 31 46 72 65 65 50 61 67 65   pcache1FreePage
55e0: 28 70 50 61 67 65 29 3b 0a 20 20 7d 65 6c 73 65  (pPage);.  }else
55f0: 7b 0a 20 20 20 20 2f 2a 20 41 64 64 20 74 68 65  {.    /* Add the
5600: 20 70 61 67 65 20 74 6f 20 74 68 65 20 67 6c 6f   page to the glo
5610: 62 61 6c 20 4c 52 55 20 6c 69 73 74 2e 20 4e 6f  bal LRU list. No
5620: 72 6d 61 6c 6c 79 2c 20 74 68 65 20 70 61 67 65  rmally, the page
5630: 20 69 73 20 61 64 64 65 64 20 74 6f 0a 20 20 20   is added to.   
5640: 20 2a 2a 20 74 68 65 20 68 65 61 64 20 6f 66 20   ** the head of 
5650: 74 68 65 20 6c 69 73 74 20 28 6c 61 73 74 20 70  the list (last p
5660: 61 67 65 20 74 6f 20 62 65 20 72 65 63 79 63 6c  age to be recycl
5670: 65 64 29 2e 20 48 6f 77 65 76 65 72 2c 20 69 66  ed). However, if
5680: 20 74 68 65 20 0a 20 20 20 20 2a 2a 20 72 65 75   the .    ** reu
5690: 73 65 55 6e 6c 69 6b 65 6c 79 20 66 6c 61 67 20  seUnlikely flag 
56a0: 70 61 73 73 65 64 20 74 6f 20 74 68 69 73 20 66  passed to this f
56b0: 75 6e 63 74 69 6f 6e 20 69 73 20 74 72 75 65 2c  unction is true,
56c0: 20 74 68 65 20 70 61 67 65 20 69 73 20 61 64 64   the page is add
56d0: 65 64 0a 20 20 20 20 2a 2a 20 74 6f 20 74 68 65  ed.    ** to the
56e0: 20 74 61 69 6c 20 6f 66 20 74 68 65 20 6c 69 73   tail of the lis
56f0: 74 20 28 66 69 72 73 74 20 70 61 67 65 20 74 6f  t (first page to
5700: 20 62 65 20 72 65 63 79 63 6c 65 64 29 2e 0a 20   be recycled).. 
5710: 20 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 70 63     */.    if( pc
5720: 61 63 68 65 31 2e 70 4c 72 75 48 65 61 64 20 29  ache1.pLruHead )
5730: 7b 0a 20 20 20 20 20 20 70 63 61 63 68 65 31 2e  {.      pcache1.
5740: 70 4c 72 75 48 65 61 64 2d 3e 70 4c 72 75 50 72  pLruHead->pLruPr
5750: 65 76 20 3d 20 70 50 61 67 65 3b 0a 20 20 20 20  ev = pPage;.    
5760: 20 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78    pPage->pLruNex
5770: 74 20 3d 20 70 63 61 63 68 65 31 2e 70 4c 72 75  t = pcache1.pLru
5780: 48 65 61 64 3b 0a 20 20 20 20 20 20 70 63 61 63  Head;.      pcac
5790: 68 65 31 2e 70 4c 72 75 48 65 61 64 20 3d 20 70  he1.pLruHead = p
57a0: 50 61 67 65 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  Page;.    }else{
57b0: 0a 20 20 20 20 20 20 70 63 61 63 68 65 31 2e 70  .      pcache1.p
57c0: 4c 72 75 54 61 69 6c 20 3d 20 70 50 61 67 65 3b  LruTail = pPage;
57d0: 0a 20 20 20 20 20 20 70 63 61 63 68 65 31 2e 70  .      pcache1.p
57e0: 4c 72 75 48 65 61 64 20 3d 20 70 50 61 67 65 3b  LruHead = pPage;
57f0: 0a 20 20 20 20 7d 0a 20 20 20 20 70 43 61 63 68  .    }.    pCach
5800: 65 2d 3e 6e 52 65 63 79 63 6c 61 62 6c 65 2b 2b  e->nRecyclable++
5810: 3b 0a 20 20 7d 0a 0a 20 20 70 63 61 63 68 65 31  ;.  }..  pcache1
5820: 4c 65 61 76 65 4d 75 74 65 78 28 29 3b 0a 7d 0a  LeaveMutex();.}.
5830: 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74  ./*.** Implement
5840: 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c  ation of the sql
5850: 69 74 65 33 5f 70 63 61 63 68 65 2e 78 52 65 6b  ite3_pcache.xRek
5860: 65 79 20 6d 65 74 68 6f 64 2e 20 0a 2a 2f 0a 73  ey method. .*/.s
5870: 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68  tatic void pcach
5880: 65 31 52 65 6b 65 79 28 0a 20 20 73 71 6c 69 74  e1Rekey(.  sqlit
5890: 65 33 5f 70 63 61 63 68 65 20 2a 70 2c 0a 20 20  e3_pcache *p,.  
58a0: 76 6f 69 64 20 2a 70 50 67 2c 0a 20 20 75 6e 73  void *pPg,.  uns
58b0: 69 67 6e 65 64 20 69 6e 74 20 69 4f 6c 64 2c 0a  igned int iOld,.
58c0: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69    unsigned int i
58d0: 4e 65 77 0a 29 7b 0a 20 20 50 43 61 63 68 65 31  New.){.  PCache1
58e0: 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61 63   *pCache = (PCac
58f0: 68 65 31 20 2a 29 70 3b 0a 20 20 50 67 48 64 72  he1 *)p;.  PgHdr
5900: 31 20 2a 70 50 61 67 65 20 3d 20 50 41 47 45 5f  1 *pPage = PAGE_
5910: 54 4f 5f 50 47 48 44 52 31 28 70 43 61 63 68 65  TO_PGHDR1(pCache
5920: 2c 20 70 50 67 29 3b 0a 20 20 50 67 48 64 72 31  , pPg);.  PgHdr1
5930: 20 2a 2a 70 70 3b 0a 20 20 75 6e 73 69 67 6e 65   **pp;.  unsigne
5940: 64 20 69 6e 74 20 68 3b 20 0a 20 20 61 73 73 65  d int h; .  asse
5950: 72 74 28 20 70 50 61 67 65 2d 3e 69 4b 65 79 3d  rt( pPage->iKey=
5960: 3d 69 4f 6c 64 20 29 3b 0a 20 20 61 73 73 65 72  =iOld );.  asser
5970: 74 28 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65  t( pPage->pCache
5980: 3d 3d 70 43 61 63 68 65 20 29 3b 0a 0a 20 20 70  ==pCache );..  p
5990: 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78  cache1EnterMutex
59a0: 28 29 3b 0a 0a 20 20 68 20 3d 20 69 4f 6c 64 25  ();..  h = iOld%
59b0: 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20  pCache->nHash;. 
59c0: 20 70 70 20 3d 20 26 70 43 61 63 68 65 2d 3e 61   pp = &pCache->a
59d0: 70 48 61 73 68 5b 68 5d 3b 0a 20 20 77 68 69 6c  pHash[h];.  whil
59e0: 65 28 20 28 2a 70 70 29 21 3d 70 50 61 67 65 20  e( (*pp)!=pPage 
59f0: 29 7b 0a 20 20 20 20 70 70 20 3d 20 26 28 2a 70  ){.    pp = &(*p
5a00: 70 29 2d 3e 70 4e 65 78 74 3b 0a 20 20 7d 0a 20  p)->pNext;.  }. 
5a10: 20 2a 70 70 20 3d 20 70 50 61 67 65 2d 3e 70 4e   *pp = pPage->pN
5a20: 65 78 74 3b 0a 0a 20 20 68 20 3d 20 69 4e 65 77  ext;..  h = iNew
5a30: 25 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3b 0a  %pCache->nHash;.
5a40: 20 20 70 50 61 67 65 2d 3e 69 4b 65 79 20 3d 20    pPage->iKey = 
5a50: 69 4e 65 77 3b 0a 20 20 70 50 61 67 65 2d 3e 70  iNew;.  pPage->p
5a60: 4e 65 78 74 20 3d 20 70 43 61 63 68 65 2d 3e 61  Next = pCache->a
5a70: 70 48 61 73 68 5b 68 5d 3b 0a 20 20 70 43 61 63  pHash[h];.  pCac
5a80: 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 20 3d 20  he->apHash[h] = 
5a90: 70 50 61 67 65 3b 0a 20 20 69 66 28 20 69 4e 65  pPage;.  if( iNe
5aa0: 77 3e 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b 65  w>pCache->iMaxKe
5ab0: 79 20 29 7b 0a 20 20 20 20 70 43 61 63 68 65 2d  y ){.    pCache-
5ac0: 3e 69 4d 61 78 4b 65 79 20 3d 20 69 4e 65 77 3b  >iMaxKey = iNew;
5ad0: 0a 20 20 7d 0a 0a 20 20 70 63 61 63 68 65 31 4c  .  }..  pcache1L
5ae0: 65 61 76 65 4d 75 74 65 78 28 29 3b 0a 7d 0a 0a  eaveMutex();.}..
5af0: 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61  /*.** Implementa
5b00: 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69  tion of the sqli
5b10: 74 65 33 5f 70 63 61 63 68 65 2e 78 54 72 75 6e  te3_pcache.xTrun
5b20: 63 61 74 65 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a  cate method. .**
5b30: 0a 2a 2a 20 44 69 73 63 61 72 64 20 61 6c 6c 20  .** Discard all 
5b40: 75 6e 70 69 6e 6e 65 64 20 70 61 67 65 73 20 69  unpinned pages i
5b50: 6e 20 74 68 65 20 63 61 63 68 65 20 77 69 74 68  n the cache with
5b60: 20 61 20 70 61 67 65 20 6e 75 6d 62 65 72 20 65   a page number e
5b70: 71 75 61 6c 20 74 6f 0a 2a 2a 20 6f 72 20 67 72  qual to.** or gr
5b80: 65 61 74 65 72 20 74 68 61 6e 20 70 61 72 61 6d  eater than param
5b90: 65 74 65 72 20 69 4c 69 6d 69 74 2e 20 41 6e 79  eter iLimit. Any
5ba0: 20 70 69 6e 6e 65 64 20 70 61 67 65 73 20 77 69   pinned pages wi
5bb0: 74 68 20 61 20 70 61 67 65 20 6e 75 6d 62 65 72  th a page number
5bc0: 0a 2a 2a 20 65 71 75 61 6c 20 74 6f 20 6f 72 20  .** equal to or 
5bd0: 67 72 65 61 74 65 72 20 74 68 61 6e 20 69 4c 69  greater than iLi
5be0: 6d 69 74 20 61 72 65 20 69 6d 70 6c 69 63 69 74  mit are implicit
5bf0: 6c 79 20 75 6e 70 69 6e 6e 65 64 2e 0a 2a 2f 0a  ly unpinned..*/.
5c00: 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63  static void pcac
5c10: 68 65 31 54 72 75 6e 63 61 74 65 28 73 71 6c 69  he1Truncate(sqli
5c20: 74 65 33 5f 70 63 61 63 68 65 20 2a 70 2c 20 75  te3_pcache *p, u
5c30: 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4c 69 6d  nsigned int iLim
5c40: 69 74 29 7b 0a 20 20 50 43 61 63 68 65 31 20 2a  it){.  PCache1 *
5c50: 70 43 61 63 68 65 20 3d 20 28 50 43 61 63 68 65  pCache = (PCache
5c60: 31 20 2a 29 70 3b 0a 20 20 70 63 61 63 68 65 31  1 *)p;.  pcache1
5c70: 45 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a 20 20  EnterMutex();.  
5c80: 69 66 28 20 69 4c 69 6d 69 74 3c 3d 70 43 61 63  if( iLimit<=pCac
5c90: 68 65 2d 3e 69 4d 61 78 4b 65 79 20 29 7b 0a 20  he->iMaxKey ){. 
5ca0: 20 20 20 70 63 61 63 68 65 31 54 72 75 6e 63 61     pcache1Trunca
5cb0: 74 65 55 6e 73 61 66 65 28 70 43 61 63 68 65 2c  teUnsafe(pCache,
5cc0: 20 69 4c 69 6d 69 74 29 3b 0a 20 20 20 20 70 43   iLimit);.    pC
5cd0: 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 3d 20  ache->iMaxKey = 
5ce0: 69 4c 69 6d 69 74 2d 31 3b 0a 20 20 7d 0a 20 20  iLimit-1;.  }.  
5cf0: 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65  pcache1LeaveMute
5d00: 78 28 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d  x();.}../*.** Im
5d10: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20  plementation of 
5d20: 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63  the sqlite3_pcac
5d30: 68 65 2e 78 44 65 73 74 72 6f 79 20 6d 65 74 68  he.xDestroy meth
5d40: 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20 44 65 73 74 72  od. .**.** Destr
5d50: 6f 79 20 61 20 63 61 63 68 65 20 61 6c 6c 6f 63  oy a cache alloc
5d60: 61 74 65 64 20 75 73 69 6e 67 20 70 63 61 63 68  ated using pcach
5d70: 65 31 43 72 65 61 74 65 28 29 2e 0a 2a 2f 0a 73  e1Create()..*/.s
5d80: 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68  tatic void pcach
5d90: 65 31 44 65 73 74 72 6f 79 28 73 71 6c 69 74 65  e1Destroy(sqlite
5da0: 33 5f 70 63 61 63 68 65 20 2a 70 29 7b 0a 20 20  3_pcache *p){.  
5db0: 50 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 20  PCache1 *pCache 
5dc0: 3d 20 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a  = (PCache1 *)p;.
5dd0: 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65    assert( pCache
5de0: 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 7c 7c 20  ->bPurgeable || 
5df0: 28 70 43 61 63 68 65 2d 3e 6e 4d 61 78 3d 3d 30  (pCache->nMax==0
5e00: 20 26 26 20 70 43 61 63 68 65 2d 3e 6e 4d 69 6e   && pCache->nMin
5e10: 3d 3d 30 29 20 29 3b 0a 20 20 70 63 61 63 68 65  ==0) );.  pcache
5e20: 31 45 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a 20  1EnterMutex();. 
5e30: 20 70 63 61 63 68 65 31 54 72 75 6e 63 61 74 65   pcache1Truncate
5e40: 55 6e 73 61 66 65 28 70 43 61 63 68 65 2c 20 30  Unsafe(pCache, 0
5e50: 29 3b 0a 20 20 70 63 61 63 68 65 31 2e 6e 4d 61  );.  pcache1.nMa
5e60: 78 50 61 67 65 20 2d 3d 20 70 43 61 63 68 65 2d  xPage -= pCache-
5e70: 3e 6e 4d 61 78 3b 0a 20 20 70 63 61 63 68 65 31  >nMax;.  pcache1
5e80: 2e 6e 4d 69 6e 50 61 67 65 20 2d 3d 20 70 43 61  .nMinPage -= pCa
5e90: 63 68 65 2d 3e 6e 4d 69 6e 3b 0a 20 20 70 63 61  che->nMin;.  pca
5ea0: 63 68 65 31 45 6e 66 6f 72 63 65 4d 61 78 50 61  che1EnforceMaxPa
5eb0: 67 65 28 29 3b 0a 20 20 70 63 61 63 68 65 31 4c  ge();.  pcache1L
5ec0: 65 61 76 65 4d 75 74 65 78 28 29 3b 0a 20 20 73  eaveMutex();.  s
5ed0: 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43 61 63  qlite3_free(pCac
5ee0: 68 65 2d 3e 61 70 48 61 73 68 29 3b 0a 20 20 73  he->apHash);.  s
5ef0: 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43 61 63  qlite3_free(pCac
5f00: 68 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68  he);.}../*.** Th
5f10: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63  is function is c
5f20: 61 6c 6c 65 64 20 64 75 72 69 6e 67 20 69 6e 69  alled during ini
5f30: 74 69 61 6c 69 7a 61 74 69 6f 6e 20 28 73 71 6c  tialization (sql
5f40: 69 74 65 33 5f 69 6e 69 74 69 61 6c 69 7a 65 28  ite3_initialize(
5f50: 29 29 20 74 6f 0a 2a 2a 20 69 6e 73 74 61 6c 6c  )) to.** install
5f60: 20 74 68 65 20 64 65 66 61 75 6c 74 20 70 6c 75   the default plu
5f70: 67 67 61 62 6c 65 20 63 61 63 68 65 20 6d 6f 64  ggable cache mod
5f80: 75 6c 65 2c 20 61 73 73 75 6d 69 6e 67 20 74 68  ule, assuming th
5f90: 65 20 75 73 65 72 20 68 61 73 20 6e 6f 74 0a 2a  e user has not.*
5fa0: 2a 20 61 6c 72 65 61 64 79 20 70 72 6f 76 69 64  * already provid
5fb0: 65 64 20 61 6e 20 61 6c 74 65 72 6e 61 74 69 76  ed an alternativ
5fc0: 65 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74  e..*/.void sqlit
5fd0: 65 33 50 43 61 63 68 65 53 65 74 44 65 66 61 75  e3PCacheSetDefau
5fe0: 6c 74 28 76 6f 69 64 29 7b 0a 20 20 73 74 61 74  lt(void){.  stat
5ff0: 69 63 20 63 6f 6e 73 74 20 73 71 6c 69 74 65 33  ic const sqlite3
6000: 5f 70 63 61 63 68 65 5f 6d 65 74 68 6f 64 73 20  _pcache_methods 
6010: 64 65 66 61 75 6c 74 4d 65 74 68 6f 64 73 20 3d  defaultMethods =
6020: 20 7b 0a 20 20 20 20 30 2c 20 20 20 20 20 20 20   {.    0,       
6030: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6040: 2f 2a 20 70 41 72 67 20 2a 2f 0a 20 20 20 20 70  /* pArg */.    p
6050: 63 61 63 68 65 31 49 6e 69 74 2c 20 20 20 20 20  cache1Init,     
6060: 20 20 20 20 20 20 20 20 2f 2a 20 78 49 6e 69 74          /* xInit
6070: 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31 53   */.    pcache1S
6080: 68 75 74 64 6f 77 6e 2c 20 20 20 20 20 20 20 20  hutdown,        
6090: 20 2f 2a 20 78 53 68 75 74 64 6f 77 6e 20 2a 2f   /* xShutdown */
60a0: 0a 20 20 20 20 70 63 61 63 68 65 31 43 72 65 61  .    pcache1Crea
60b0: 74 65 2c 20 20 20 20 20 20 20 20 20 20 20 2f 2a  te,           /*
60c0: 20 78 43 72 65 61 74 65 20 2a 2f 0a 20 20 20 20   xCreate */.    
60d0: 70 63 61 63 68 65 31 43 61 63 68 65 73 69 7a 65  pcache1Cachesize
60e0: 2c 20 20 20 20 20 20 20 20 2f 2a 20 78 43 61 63  ,        /* xCac
60f0: 68 65 73 69 7a 65 20 2a 2f 0a 20 20 20 20 70 63  hesize */.    pc
6100: 61 63 68 65 31 50 61 67 65 63 6f 75 6e 74 2c 20  ache1Pagecount, 
6110: 20 20 20 20 20 20 20 2f 2a 20 78 50 61 67 65 63         /* xPagec
6120: 6f 75 6e 74 20 2a 2f 0a 20 20 20 20 70 63 61 63  ount */.    pcac
6130: 68 65 31 46 65 74 63 68 2c 20 20 20 20 20 20 20  he1Fetch,       
6140: 20 20 20 20 20 2f 2a 20 78 46 65 74 63 68 20 2a       /* xFetch *
6150: 2f 0a 20 20 20 20 70 63 61 63 68 65 31 55 6e 70  /.    pcache1Unp
6160: 69 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f  in,            /
6170: 2a 20 78 55 6e 70 69 6e 20 2a 2f 0a 20 20 20 20  * xUnpin */.    
6180: 70 63 61 63 68 65 31 52 65 6b 65 79 2c 20 20 20  pcache1Rekey,   
6190: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 52 65 6b           /* xRek
61a0: 65 79 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65  ey */.    pcache
61b0: 31 54 72 75 6e 63 61 74 65 2c 20 20 20 20 20 20  1Truncate,      
61c0: 20 20 20 2f 2a 20 78 54 72 75 6e 63 61 74 65 20     /* xTruncate 
61d0: 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31 44 65  */.    pcache1De
61e0: 73 74 72 6f 79 20 20 20 20 20 20 20 20 20 20 20  stroy           
61f0: 2f 2a 20 78 44 65 73 74 72 6f 79 20 2a 2f 0a 20  /* xDestroy */. 
6200: 20 7d 3b 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f   };.  sqlite3_co
6210: 6e 66 69 67 28 53 51 4c 49 54 45 5f 43 4f 4e 46  nfig(SQLITE_CONF
6220: 49 47 5f 50 43 41 43 48 45 2c 20 26 64 65 66 61  IG_PCACHE, &defa
6230: 75 6c 74 4d 65 74 68 6f 64 73 29 3b 0a 7d 0a 0a  ultMethods);.}..
6240: 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 45 4e  #ifdef SQLITE_EN
6250: 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41  ABLE_MEMORY_MANA
6260: 47 45 4d 45 4e 54 0a 2f 2a 0a 2a 2a 20 54 68 69  GEMENT./*.** Thi
6270: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61  s function is ca
6280: 6c 6c 65 64 20 74 6f 20 66 72 65 65 20 73 75 70  lled to free sup
6290: 65 72 66 6c 75 6f 75 73 20 64 79 6e 61 6d 69 63  erfluous dynamic
62a0: 61 6c 6c 79 20 61 6c 6c 6f 63 61 74 65 64 20 6d  ally allocated m
62b0: 65 6d 6f 72 79 0a 2a 2a 20 68 65 6c 64 20 62 79  emory.** held by
62c0: 20 74 68 65 20 70 61 67 65 72 20 73 79 73 74 65   the pager syste
62d0: 6d 2e 20 4d 65 6d 6f 72 79 20 69 6e 20 75 73 65  m. Memory in use
62e0: 20 62 79 20 61 6e 79 20 53 51 4c 69 74 65 20 70   by any SQLite p
62f0: 61 67 65 72 20 61 6c 6c 6f 63 61 74 65 64 0a 2a  ager allocated.*
6300: 2a 20 62 79 20 74 68 65 20 63 75 72 72 65 6e 74  * by the current
6310: 20 74 68 72 65 61 64 20 6d 61 79 20 62 65 20 73   thread may be s
6320: 71 6c 69 74 65 33 5f 66 72 65 65 28 29 65 64 2e  qlite3_free()ed.
6330: 0a 2a 2a 0a 2a 2a 20 6e 52 65 71 20 69 73 20 74  .**.** nReq is t
6340: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 62 79 74  he number of byt
6350: 65 73 20 6f 66 20 6d 65 6d 6f 72 79 20 72 65 71  es of memory req
6360: 75 69 72 65 64 2e 20 4f 6e 63 65 20 74 68 69 73  uired. Once this
6370: 20 6d 75 63 68 20 68 61 73 0a 2a 2a 20 62 65 65   much has.** bee
6380: 6e 20 72 65 6c 65 61 73 65 64 2c 20 74 68 65 20  n released, the 
6390: 66 75 6e 63 74 69 6f 6e 20 72 65 74 75 72 6e 73  function returns
63a0: 2e 20 54 68 65 20 72 65 74 75 72 6e 20 76 61 6c  . The return val
63b0: 75 65 20 69 73 20 74 68 65 20 74 6f 74 61 6c 20  ue is the total 
63c0: 6e 75 6d 62 65 72 20 0a 2a 2a 20 6f 66 20 62 79  number .** of by
63d0: 74 65 73 20 6f 66 20 6d 65 6d 6f 72 79 20 72 65  tes of memory re
63e0: 6c 65 61 73 65 64 2e 0a 2a 2f 0a 69 6e 74 20 73  leased..*/.int s
63f0: 71 6c 69 74 65 33 50 63 61 63 68 65 52 65 6c 65  qlite3PcacheRele
6400: 61 73 65 4d 65 6d 6f 72 79 28 69 6e 74 20 6e 52  aseMemory(int nR
6410: 65 71 29 7b 0a 20 20 69 6e 74 20 6e 46 72 65 65  eq){.  int nFree
6420: 20 3d 20 30 3b 0a 20 20 69 66 28 20 70 63 61 63   = 0;.  if( pcac
6430: 68 65 31 2e 70 53 74 61 72 74 3d 3d 30 20 29 7b  he1.pStart==0 ){
6440: 0a 20 20 20 20 50 67 48 64 72 31 20 2a 70 3b 0a  .    PgHdr1 *p;.
6450: 20 20 20 20 70 63 61 63 68 65 31 45 6e 74 65 72      pcache1Enter
6460: 4d 75 74 65 78 28 29 3b 0a 20 20 20 20 77 68 69  Mutex();.    whi
6470: 6c 65 28 20 28 6e 52 65 71 3c 30 20 7c 7c 20 6e  le( (nReq<0 || n
6480: 46 72 65 65 3c 6e 52 65 71 29 20 26 26 20 28 28  Free<nReq) && ((
6490: 70 3d 70 63 61 63 68 65 31 2e 70 4c 72 75 54 61  p=pcache1.pLruTa
64a0: 69 6c 29 21 3d 30 29 20 29 7b 0a 20 20 20 20 20  il)!=0) ){.     
64b0: 20 6e 46 72 65 65 20 2b 3d 20 70 63 61 63 68 65   nFree += pcache
64c0: 31 4d 65 6d 53 69 7a 65 28 50 47 48 44 52 31 5f  1MemSize(PGHDR1_
64d0: 54 4f 5f 50 41 47 45 28 70 29 29 3b 0a 20 20 20  TO_PAGE(p));.   
64e0: 20 20 20 70 63 61 63 68 65 31 50 69 6e 50 61 67     pcache1PinPag
64f0: 65 28 70 29 3b 0a 20 20 20 20 20 20 70 63 61 63  e(p);.      pcac
6500: 68 65 31 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73  he1RemoveFromHas
6510: 68 28 70 29 3b 0a 20 20 20 20 20 20 70 63 61 63  h(p);.      pcac
6520: 68 65 31 46 72 65 65 50 61 67 65 28 70 29 3b 0a  he1FreePage(p);.
6530: 20 20 20 20 7d 0a 20 20 20 20 70 63 61 63 68 65      }.    pcache
6540: 31 4c 65 61 76 65 4d 75 74 65 78 28 29 3b 0a 20  1LeaveMutex();. 
6550: 20 7d 0a 20 20 72 65 74 75 72 6e 20 6e 46 72 65   }.  return nFre
6560: 65 3b 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a 20 53  e;.}.#endif /* S
6570: 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d  QLITE_ENABLE_MEM
6580: 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 20 2a  ORY_MANAGEMENT *
6590: 2f 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45  /..#ifdef SQLITE
65a0: 5f 54 45 53 54 0a 2f 2a 0a 2a 2a 20 54 68 69 73  _TEST./*.** This
65b0: 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 75 73 65   function is use
65c0: 64 20 62 79 20 74 65 73 74 20 70 72 6f 63 65 64  d by test proced
65d0: 75 72 65 73 20 74 6f 20 69 6e 73 70 65 63 74 20  ures to inspect 
65e0: 74 68 65 20 69 6e 74 65 72 6e 61 6c 20 73 74 61  the internal sta
65f0: 74 65 0a 2a 2a 20 6f 66 20 74 68 65 20 67 6c 6f  te.** of the glo
6600: 62 61 6c 20 63 61 63 68 65 2e 0a 2a 2f 0a 76 6f  bal cache..*/.vo
6610: 69 64 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  id sqlite3Pcache
6620: 53 74 61 74 73 28 0a 20 20 69 6e 74 20 2a 70 6e  Stats(.  int *pn
6630: 43 75 72 72 65 6e 74 2c 20 20 20 20 20 20 2f 2a  Current,      /*
6640: 20 4f 55 54 3a 20 54 6f 74 61 6c 20 6e 75 6d 62   OUT: Total numb
6650: 65 72 20 6f 66 20 70 61 67 65 73 20 63 61 63 68  er of pages cach
6660: 65 64 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 4d  ed */.  int *pnM
6670: 61 78 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ax,          /* 
6680: 4f 55 54 3a 20 47 6c 6f 62 61 6c 20 6d 61 78 69  OUT: Global maxi
6690: 6d 75 6d 20 63 61 63 68 65 20 73 69 7a 65 20 2a  mum cache size *
66a0: 2f 0a 20 20 69 6e 74 20 2a 70 6e 4d 69 6e 2c 20  /.  int *pnMin, 
66b0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
66c0: 20 53 75 6d 20 6f 66 20 50 43 61 63 68 65 31 2e   Sum of PCache1.
66d0: 6e 4d 69 6e 20 66 6f 72 20 70 75 72 67 65 61 62  nMin for purgeab
66e0: 6c 65 20 63 61 63 68 65 73 20 2a 2f 0a 20 20 69  le caches */.  i
66f0: 6e 74 20 2a 70 6e 52 65 63 79 63 6c 61 62 6c 65  nt *pnRecyclable
6700: 20 20 20 20 2f 2a 20 4f 55 54 3a 20 54 6f 74 61      /* OUT: Tota
6710: 6c 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65  l number of page
6720: 73 20 61 76 61 69 6c 61 62 6c 65 20 66 6f 72 20  s available for 
6730: 72 65 63 79 63 6c 69 6e 67 20 2a 2f 0a 29 7b 0a  recycling */.){.
6740: 20 20 50 67 48 64 72 31 20 2a 70 3b 0a 20 20 69    PgHdr1 *p;.  i
6750: 6e 74 20 6e 52 65 63 79 63 6c 61 62 6c 65 20 3d  nt nRecyclable =
6760: 20 30 3b 0a 20 20 66 6f 72 28 70 3d 70 63 61 63   0;.  for(p=pcac
6770: 68 65 31 2e 70 4c 72 75 48 65 61 64 3b 20 70 3b  he1.pLruHead; p;
6780: 20 70 3d 70 2d 3e 70 4c 72 75 4e 65 78 74 29 7b   p=p->pLruNext){
6790: 0a 20 20 20 20 6e 52 65 63 79 63 6c 61 62 6c 65  .    nRecyclable
67a0: 2b 2b 3b 0a 20 20 7d 0a 20 20 2a 70 6e 43 75 72  ++;.  }.  *pnCur
67b0: 72 65 6e 74 20 3d 20 70 63 61 63 68 65 31 2e 6e  rent = pcache1.n
67c0: 43 75 72 72 65 6e 74 50 61 67 65 3b 0a 20 20 2a  CurrentPage;.  *
67d0: 70 6e 4d 61 78 20 3d 20 70 63 61 63 68 65 31 2e  pnMax = pcache1.
67e0: 6e 4d 61 78 50 61 67 65 3b 0a 20 20 2a 70 6e 4d  nMaxPage;.  *pnM
67f0: 69 6e 20 3d 20 70 63 61 63 68 65 31 2e 6e 4d 69  in = pcache1.nMi
6800: 6e 50 61 67 65 3b 0a 20 20 2a 70 6e 52 65 63 79  nPage;.  *pnRecy
6810: 63 6c 61 62 6c 65 20 3d 20 6e 52 65 63 79 63 6c  clable = nRecycl
6820: 61 62 6c 65 3b 0a 7d 0a 23 65 6e 64 69 66 0a     able;.}.#endif.