/ Hex Artifact Content
Login

Artifact 9fd22671c270b35131ef480bbc00392b8b5f8ab9:


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 74 79  t PgFreeslot;.ty
0340: 70 65 64 65 66 20 73 74 72 75 63 74 20 50 47 72  pedef struct PGr
0350: 6f 75 70 20 50 47 72 6f 75 70 3b 0a 0a 2f 2a 20  oup PGroup;../* 
0360: 45 61 63 68 20 70 61 67 65 20 63 61 63 68 65 20  Each page cache 
0370: 28 6f 72 20 50 43 61 63 68 65 29 20 62 65 6c 6f  (or PCache) belo
0380: 6e 67 73 20 74 6f 20 61 20 50 47 72 6f 75 70 2e  ngs to a PGroup.
0390: 20 20 41 20 50 47 72 6f 75 70 20 69 73 20 61 20    A PGroup is a 
03a0: 73 65 74 20 0a 2a 2a 20 6f 66 20 6f 6e 65 20 6f  set .** of one o
03b0: 72 20 6d 6f 72 65 20 50 43 61 63 68 65 73 20 74  r more PCaches t
03c0: 68 61 74 20 61 72 65 20 61 62 6c 65 20 74 6f 20  hat are able to 
03d0: 72 65 63 79 63 6c 65 20 65 61 63 68 20 6f 74 68  recycle each oth
03e0: 65 72 73 20 75 6e 70 69 6e 6e 65 64 0a 2a 2a 20  ers unpinned.** 
03f0: 70 61 67 65 73 20 77 68 65 6e 20 74 68 65 79 20  pages when they 
0400: 61 72 65 20 75 6e 64 65 72 20 6d 65 6d 6f 72 79  are under memory
0410: 20 70 72 65 73 73 75 72 65 2e 20 20 41 20 50 47   pressure.  A PG
0420: 72 6f 75 70 20 69 73 20 61 6e 20 69 6e 73 74 61  roup is an insta
0430: 6e 63 65 20 6f 66 0a 2a 2a 20 74 68 65 20 66 6f  nce of.** the fo
0440: 6c 6c 6f 77 69 6e 67 20 6f 62 6a 65 63 74 2e 0a  llowing object..
0450: 2a 2a 0a 2a 2a 20 54 68 69 73 20 70 61 67 65 20  **.** This page 
0460: 63 61 63 68 65 20 69 6d 70 6c 65 6d 65 6e 74 61  cache implementa
0470: 74 69 6f 6e 20 77 6f 72 6b 73 20 69 6e 20 6f 6e  tion works in on
0480: 65 20 6f 66 20 74 77 6f 20 6d 6f 64 65 73 3a 0a  e of two modes:.
0490: 2a 2a 0a 2a 2a 20 20 20 28 31 29 20 20 45 76 65  **.**   (1)  Eve
04a0: 72 79 20 50 43 61 63 68 65 20 69 73 20 74 68 65  ry PCache is the
04b0: 20 73 6f 6c 65 20 6d 65 6d 62 65 72 20 6f 66 20   sole member of 
04c0: 69 74 73 20 6f 77 6e 20 50 47 72 6f 75 70 2e 20  its own PGroup. 
04d0: 20 54 68 65 72 65 20 69 73 0a 2a 2a 20 20 20 20   There is.**    
04e0: 20 20 20 20 6f 6e 65 20 50 47 72 6f 75 70 20 70      one PGroup p
04f0: 65 72 20 50 43 61 63 68 65 2e 0a 2a 2a 0a 2a 2a  er PCache..**.**
0500: 20 20 20 28 32 29 20 20 54 68 65 72 65 20 69 73     (2)  There is
0510: 20 61 20 73 69 6e 67 6c 65 20 67 6c 6f 62 61 6c   a single global
0520: 20 50 47 72 6f 75 70 20 74 68 61 74 20 61 6c 6c   PGroup that all
0530: 20 50 43 61 63 68 65 73 20 61 72 65 20 61 20 6d   PCaches are a m
0540: 65 6d 62 65 72 0a 2a 2a 20 20 20 20 20 20 20 20  ember.**        
0550: 6f 66 2e 0a 2a 2a 0a 2a 2a 20 4d 6f 64 65 20 31  of..**.** Mode 1
0560: 20 75 73 65 73 20 6d 6f 72 65 20 6d 65 6d 6f 72   uses more memor
0570: 79 20 28 73 69 6e 63 65 20 50 43 61 63 68 65 20  y (since PCache 
0580: 69 6e 73 74 61 6e 63 65 73 20 61 72 65 20 6e 6f  instances are no
0590: 74 20 61 62 6c 65 20 74 6f 20 72 6f 62 0a 2a 2a  t able to rob.**
05a0: 20 75 6e 75 73 65 64 20 70 61 67 65 73 20 66 72   unused pages fr
05b0: 6f 6d 20 6f 74 68 65 72 20 50 43 61 63 68 65 73  om other PCaches
05c0: 29 20 62 75 74 20 69 74 20 61 6c 73 6f 20 6f 70  ) but it also op
05d0: 65 72 61 74 65 73 20 77 69 74 68 6f 75 74 20 61  erates without a
05e0: 20 6d 75 74 65 78 2c 0a 2a 2a 20 61 6e 64 20 69   mutex,.** and i
05f0: 73 20 74 68 65 72 65 66 6f 72 65 20 6f 66 74 65  s therefore ofte
0600: 6e 20 66 61 73 74 65 72 2e 20 20 4d 6f 64 65 20  n faster.  Mode 
0610: 32 20 72 65 71 75 69 72 65 73 20 61 20 6d 75 74  2 requires a mut
0620: 65 78 20 69 6e 20 6f 72 64 65 72 20 74 6f 20 62  ex in order to b
0630: 65 0a 2a 2a 20 74 68 72 65 61 64 73 61 66 65 2c  e.** threadsafe,
0640: 20 62 75 74 20 72 65 63 79 63 6c 65 73 20 70 61   but recycles pa
0650: 67 65 73 20 6d 6f 72 65 20 65 66 66 69 63 69 65  ges more efficie
0660: 6e 74 6c 79 2e 0a 2a 2a 0a 2a 2a 20 46 6f 72 20  ntly..**.** For 
0670: 6d 6f 64 65 20 28 31 29 2c 20 50 47 72 6f 75 70  mode (1), PGroup
0680: 2e 6d 75 74 65 78 20 69 73 20 4e 55 4c 4c 2e 20  .mutex is NULL. 
0690: 20 46 6f 72 20 6d 6f 64 65 20 28 32 29 20 74 68   For mode (2) th
06a0: 65 72 65 20 69 73 20 6f 6e 6c 79 20 61 20 73 69  ere is only a si
06b0: 6e 67 6c 65 0a 2a 2a 20 50 47 72 6f 75 70 20 77  ngle.** PGroup w
06c0: 68 69 63 68 20 69 73 20 74 68 65 20 70 63 61 63  hich is the pcac
06d0: 68 65 31 2e 67 72 70 20 67 6c 6f 62 61 6c 20 76  he1.grp global v
06e0: 61 72 69 61 62 6c 65 20 61 6e 64 20 69 74 73 20  ariable and its 
06f0: 6d 75 74 65 78 20 69 73 0a 2a 2a 20 53 51 4c 49  mutex is.** SQLI
0700: 54 45 5f 4d 55 54 45 58 5f 53 54 41 54 49 43 5f  TE_MUTEX_STATIC_
0710: 4c 52 55 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 50  LRU..*/.struct P
0720: 47 72 6f 75 70 20 7b 0a 20 20 73 71 6c 69 74 65  Group {.  sqlite
0730: 33 5f 6d 75 74 65 78 20 2a 6d 75 74 65 78 3b 20  3_mutex *mutex; 
0740: 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 55 54 45           /* MUTE
0750: 58 5f 53 54 41 54 49 43 5f 4c 52 55 20 6f 72 20  X_STATIC_LRU or 
0760: 4e 55 4c 4c 20 2a 2f 0a 20 20 75 6e 73 69 67 6e  NULL */.  unsign
0770: 65 64 20 69 6e 74 20 6e 4d 61 78 50 61 67 65 3b  ed int nMaxPage;
0780: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 75 6d 20           /* Sum 
0790: 6f 66 20 6e 4d 61 78 20 66 6f 72 20 70 75 72 67  of nMax for purg
07a0: 65 61 62 6c 65 20 63 61 63 68 65 73 20 2a 2f 0a  eable caches */.
07b0: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e    unsigned int n
07c0: 4d 69 6e 50 61 67 65 3b 20 20 20 20 20 20 20 20  MinPage;        
07d0: 20 2f 2a 20 53 75 6d 20 6f 66 20 6e 4d 69 6e 20   /* Sum of nMin 
07e0: 66 6f 72 20 70 75 72 67 65 61 62 6c 65 20 63 61  for purgeable ca
07f0: 63 68 65 73 20 2a 2f 0a 20 20 75 6e 73 69 67 6e  ches */.  unsign
0800: 65 64 20 69 6e 74 20 6d 78 50 69 6e 6e 65 64 3b  ed int mxPinned;
0810: 20 20 20 20 20 20 20 20 20 2f 2a 20 6e 4d 61 78           /* nMax
0820: 70 61 67 65 20 2b 20 31 30 20 2d 20 6e 4d 69 6e  page + 10 - nMin
0830: 50 61 67 65 20 2a 2f 0a 20 20 75 6e 73 69 67 6e  Page */.  unsign
0840: 65 64 20 69 6e 74 20 6e 43 75 72 72 65 6e 74 50  ed int nCurrentP
0850: 61 67 65 3b 20 20 20 20 20 2f 2a 20 4e 75 6d 62  age;     /* Numb
0860: 65 72 20 6f 66 20 70 75 72 67 65 61 62 6c 65 20  er of purgeable 
0870: 70 61 67 65 73 20 61 6c 6c 6f 63 61 74 65 64 20  pages allocated 
0880: 2a 2f 0a 20 20 50 67 48 64 72 31 20 2a 70 4c 72  */.  PgHdr1 *pLr
0890: 75 48 65 61 64 2c 20 2a 70 4c 72 75 54 61 69 6c  uHead, *pLruTail
08a0: 3b 20 20 20 2f 2a 20 4c 52 55 20 6c 69 73 74 20  ;   /* LRU list 
08b0: 6f 66 20 75 6e 70 69 6e 6e 65 64 20 70 61 67 65  of unpinned page
08c0: 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 20 45 61 63 68  s */.};../* Each
08d0: 20 70 61 67 65 20 63 61 63 68 65 20 69 73 20 61   page cache is a
08e0: 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68  n instance of th
08f0: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6f 62 6a 65  e following obje
0900: 63 74 2e 20 20 45 76 65 72 79 0a 2a 2a 20 6f 70  ct.  Every.** op
0910: 65 6e 20 64 61 74 61 62 61 73 65 20 66 69 6c 65  en database file
0920: 20 28 69 6e 63 6c 75 64 69 6e 67 20 65 61 63 68   (including each
0930: 20 69 6e 2d 6d 65 6d 6f 72 79 20 64 61 74 61 62   in-memory datab
0940: 61 73 65 20 61 6e 64 20 65 61 63 68 0a 2a 2a 20  ase and each.** 
0950: 74 65 6d 70 6f 72 61 72 79 20 6f 72 20 74 72 61  temporary or tra
0960: 6e 73 69 65 6e 74 20 64 61 74 61 62 61 73 65 29  nsient database)
0970: 20 68 61 73 20 61 20 73 69 6e 67 6c 65 20 70 61   has a single pa
0980: 67 65 20 63 61 63 68 65 20 77 68 69 63 68 0a 2a  ge cache which.*
0990: 2a 20 69 73 20 61 6e 20 69 6e 73 74 61 6e 63 65  * is an instance
09a0: 20 6f 66 20 74 68 69 73 20 6f 62 6a 65 63 74 2e   of this object.
09b0: 0a 2a 2a 0a 2a 2a 20 50 6f 69 6e 74 65 72 73 20  .**.** Pointers 
09c0: 74 6f 20 73 74 72 75 63 74 75 72 65 73 20 6f 66  to structures of
09d0: 20 74 68 69 73 20 74 79 70 65 20 61 72 65 20 63   this type are c
09e0: 61 73 74 20 61 6e 64 20 72 65 74 75 72 6e 65 64  ast and returned
09f0: 20 61 73 20 0a 2a 2a 20 6f 70 61 71 75 65 20 73   as .** opaque s
0a00: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2a 20 68  qlite3_pcache* h
0a10: 61 6e 64 6c 65 73 2e 0a 2a 2f 0a 73 74 72 75 63  andles..*/.struc
0a20: 74 20 50 43 61 63 68 65 31 20 7b 0a 20 20 2f 2a  t PCache1 {.  /*
0a30: 20 43 61 63 68 65 20 63 6f 6e 66 69 67 75 72 61   Cache configura
0a40: 74 69 6f 6e 20 70 61 72 61 6d 65 74 65 72 73 2e  tion parameters.
0a50: 20 50 61 67 65 20 73 69 7a 65 20 28 73 7a 50 61   Page size (szPa
0a60: 67 65 29 20 61 6e 64 20 74 68 65 20 70 75 72 67  ge) and the purg
0a70: 65 61 62 6c 65 0a 20 20 2a 2a 20 66 6c 61 67 20  eable.  ** flag 
0a80: 28 62 50 75 72 67 65 61 62 6c 65 29 20 61 72 65  (bPurgeable) are
0a90: 20 73 65 74 20 77 68 65 6e 20 74 68 65 20 63 61   set when the ca
0aa0: 63 68 65 20 69 73 20 63 72 65 61 74 65 64 2e 20  che is created. 
0ab0: 6e 4d 61 78 20 6d 61 79 20 62 65 20 0a 20 20 2a  nMax may be .  *
0ac0: 2a 20 6d 6f 64 69 66 69 65 64 20 61 74 20 61 6e  * modified at an
0ad0: 79 20 74 69 6d 65 20 62 79 20 61 20 63 61 6c 6c  y time by a call
0ae0: 20 74 6f 20 74 68 65 20 70 63 61 63 68 65 31 43   to the pcache1C
0af0: 61 63 68 65 73 69 7a 65 28 29 20 6d 65 74 68 6f  achesize() metho
0b00: 64 2e 0a 20 20 2a 2a 20 54 68 65 20 50 47 72 6f  d..  ** The PGro
0b10: 75 70 20 6d 75 74 65 78 20 6d 75 73 74 20 62 65  up mutex must be
0b20: 20 68 65 6c 64 20 77 68 65 6e 20 61 63 63 65 73   held when acces
0b30: 73 69 6e 67 20 6e 4d 61 78 2e 0a 20 20 2a 2f 0a  sing nMax..  */.
0b40: 20 20 50 47 72 6f 75 70 20 2a 70 47 72 6f 75 70    PGroup *pGroup
0b50: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
0b60: 20 20 20 20 20 20 2f 2a 20 50 47 72 6f 75 70 20        /* PGroup 
0b70: 74 68 69 73 20 63 61 63 68 65 20 62 65 6c 6f 6e  this cache belon
0b80: 67 73 20 74 6f 20 2a 2f 0a 20 20 69 6e 74 20 73  gs to */.  int s
0b90: 7a 50 61 67 65 3b 20 20 20 20 20 20 20 20 20 20  zPage;          
0ba0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0bb0: 2a 20 53 69 7a 65 20 6f 66 20 61 6c 6c 6f 63 61  * Size of alloca
0bc0: 74 65 64 20 70 61 67 65 73 20 69 6e 20 62 79 74  ted pages in byt
0bd0: 65 73 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 45 78  es */.  int szEx
0be0: 74 72 61 3b 20 20 20 20 20 20 20 20 20 20 20 20  tra;            
0bf0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
0c00: 69 7a 65 20 6f 66 20 65 78 74 72 61 20 73 70 61  ize of extra spa
0c10: 63 65 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20  ce in bytes */. 
0c20: 20 69 6e 74 20 62 50 75 72 67 65 61 62 6c 65 3b   int bPurgeable;
0c30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c40: 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20       /* True if 
0c50: 63 61 63 68 65 20 69 73 20 70 75 72 67 65 61 62  cache is purgeab
0c60: 6c 65 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64  le */.  unsigned
0c70: 20 69 6e 74 20 6e 4d 69 6e 3b 20 20 20 20 20 20   int nMin;      
0c80: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d              /* M
0c90: 69 6e 69 6d 75 6d 20 6e 75 6d 62 65 72 20 6f 66  inimum number of
0ca0: 20 70 61 67 65 73 20 72 65 73 65 72 76 65 64 20   pages reserved 
0cb0: 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e  */.  unsigned in
0cc0: 74 20 6e 4d 61 78 3b 20 20 20 20 20 20 20 20 20  t nMax;         
0cd0: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6e 66           /* Conf
0ce0: 69 67 75 72 65 64 20 22 63 61 63 68 65 5f 73 69  igured "cache_si
0cf0: 7a 65 22 20 76 61 6c 75 65 20 2a 2f 0a 20 20 75  ze" value */.  u
0d00: 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 39 30 70  nsigned int n90p
0d10: 63 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ct;             
0d20: 20 20 20 2f 2a 20 6e 4d 61 78 2a 39 2f 31 30 20     /* nMax*9/10 
0d30: 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e  */.  unsigned in
0d40: 74 20 69 4d 61 78 4b 65 79 3b 20 20 20 20 20 20  t iMaxKey;      
0d50: 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 61 72 67           /* Larg
0d60: 65 73 74 20 6b 65 79 20 73 65 65 6e 20 73 69 6e  est key seen sin
0d70: 63 65 20 78 54 72 75 6e 63 61 74 65 28 29 20 2a  ce xTruncate() *
0d80: 2f 0a 0a 20 20 2f 2a 20 48 61 73 68 20 74 61 62  /..  /* Hash tab
0d90: 6c 65 20 6f 66 20 61 6c 6c 20 70 61 67 65 73 2e  le of all pages.
0da0: 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 76   The following v
0db0: 61 72 69 61 62 6c 65 73 20 6d 61 79 20 6f 6e 6c  ariables may onl
0dc0: 79 20 62 65 20 61 63 63 65 73 73 65 64 0a 20 20  y be accessed.  
0dd0: 2a 2a 20 77 68 65 6e 20 74 68 65 20 61 63 63 65  ** when the acce
0de0: 73 73 6f 72 20 69 73 20 68 6f 6c 64 69 6e 67 20  ssor is holding 
0df0: 74 68 65 20 50 47 72 6f 75 70 20 6d 75 74 65 78  the PGroup mutex
0e00: 2e 0a 20 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65  ..  */.  unsigne
0e10: 64 20 69 6e 74 20 6e 52 65 63 79 63 6c 61 62 6c  d int nRecyclabl
0e20: 65 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  e;           /* 
0e30: 4e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20  Number of pages 
0e40: 69 6e 20 74 68 65 20 4c 52 55 20 6c 69 73 74 20  in the LRU list 
0e50: 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e  */.  unsigned in
0e60: 74 20 6e 50 61 67 65 3b 20 20 20 20 20 20 20 20  t nPage;        
0e70: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 6f 74 61           /* Tota
0e80: 6c 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65  l number of page
0e90: 73 20 69 6e 20 61 70 48 61 73 68 20 2a 2f 0a 20  s in apHash */. 
0ea0: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 48   unsigned int nH
0eb0: 61 73 68 3b 20 20 20 20 20 20 20 20 20 20 20 20  ash;            
0ec0: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
0ed0: 66 20 73 6c 6f 74 73 20 69 6e 20 61 70 48 61 73  f slots in apHas
0ee0: 68 5b 5d 20 2a 2f 0a 20 20 50 67 48 64 72 31 20  h[] */.  PgHdr1 
0ef0: 2a 2a 61 70 48 61 73 68 3b 20 20 20 20 20 20 20  **apHash;       
0f00: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0f10: 48 61 73 68 20 74 61 62 6c 65 20 66 6f 72 20 66  Hash table for f
0f20: 61 73 74 20 6c 6f 6f 6b 75 70 20 62 79 20 6b 65  ast lookup by ke
0f30: 79 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 45  y */.};../*.** E
0f40: 61 63 68 20 63 61 63 68 65 20 65 6e 74 72 79 20  ach cache entry 
0f50: 69 73 20 72 65 70 72 65 73 65 6e 74 65 64 20 62  is represented b
0f60: 79 20 61 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66  y an instance of
0f70: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 0a   the following .
0f80: 2a 2a 20 73 74 72 75 63 74 75 72 65 2e 20 55 6e  ** structure. Un
0f90: 6c 65 73 73 20 53 51 4c 49 54 45 5f 50 43 41 43  less SQLITE_PCAC
0fa0: 48 45 5f 53 45 50 41 52 41 54 45 5f 48 45 41 44  HE_SEPARATE_HEAD
0fb0: 45 52 20 69 73 20 64 65 66 69 6e 65 64 2c 20 61  ER is defined, a
0fc0: 20 62 75 66 66 65 72 20 6f 66 0a 2a 2a 20 50 67   buffer of.** Pg
0fd0: 48 64 72 31 2e 70 43 61 63 68 65 2d 3e 73 7a 50  Hdr1.pCache->szP
0fe0: 61 67 65 20 62 79 74 65 73 20 69 73 20 61 6c 6c  age bytes is all
0ff0: 6f 63 61 74 65 64 20 64 69 72 65 63 74 6c 79 20  ocated directly 
1000: 62 65 66 6f 72 65 20 74 68 69 73 20 73 74 72 75  before this stru
1010: 63 74 75 72 65 20 0a 2a 2a 20 69 6e 20 6d 65 6d  cture .** in mem
1020: 6f 72 79 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 50  ory..*/.struct P
1030: 67 48 64 72 31 20 7b 0a 20 20 73 71 6c 69 74 65  gHdr1 {.  sqlite
1040: 33 5f 70 63 61 63 68 65 5f 70 61 67 65 20 70 61  3_pcache_page pa
1050: 67 65 3b 0a 20 20 75 6e 73 69 67 6e 65 64 20 69  ge;.  unsigned i
1060: 6e 74 20 69 4b 65 79 3b 20 20 20 20 20 20 20 20  nt iKey;        
1070: 20 20 20 20 20 2f 2a 20 4b 65 79 20 76 61 6c 75       /* Key valu
1080: 65 20 28 70 61 67 65 20 6e 75 6d 62 65 72 29 20  e (page number) 
1090: 2a 2f 0a 20 20 50 67 48 64 72 31 20 2a 70 4e 65  */.  PgHdr1 *pNe
10a0: 78 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  xt;             
10b0: 20 20 20 20 2f 2a 20 4e 65 78 74 20 69 6e 20 68      /* Next in h
10c0: 61 73 68 20 74 61 62 6c 65 20 63 68 61 69 6e 20  ash table chain 
10d0: 2a 2f 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43  */.  PCache1 *pC
10e0: 61 63 68 65 3b 20 20 20 20 20 20 20 20 20 20 20  ache;           
10f0: 20 20 20 20 2f 2a 20 43 61 63 68 65 20 74 68 61      /* Cache tha
1100: 74 20 63 75 72 72 65 6e 74 6c 79 20 6f 77 6e 73  t currently owns
1110: 20 74 68 69 73 20 70 61 67 65 20 2a 2f 0a 20 20   this page */.  
1120: 50 67 48 64 72 31 20 2a 70 4c 72 75 4e 65 78 74  PgHdr1 *pLruNext
1130: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ;              /
1140: 2a 20 4e 65 78 74 20 69 6e 20 4c 52 55 20 6c 69  * Next in LRU li
1150: 73 74 20 6f 66 20 75 6e 70 69 6e 6e 65 64 20 70  st of unpinned p
1160: 61 67 65 73 20 2a 2f 0a 20 20 50 67 48 64 72 31  ages */.  PgHdr1
1170: 20 2a 70 4c 72 75 50 72 65 76 3b 20 20 20 20 20   *pLruPrev;     
1180: 20 20 20 20 20 20 20 20 20 2f 2a 20 50 72 65 76           /* Prev
1190: 69 6f 75 73 20 69 6e 20 4c 52 55 20 6c 69 73 74  ious in LRU list
11a0: 20 6f 66 20 75 6e 70 69 6e 6e 65 64 20 70 61 67   of unpinned pag
11b0: 65 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20  es */.};../*.** 
11c0: 46 72 65 65 20 73 6c 6f 74 73 20 69 6e 20 74 68  Free slots in th
11d0: 65 20 61 6c 6c 6f 63 61 74 6f 72 20 75 73 65 64  e allocator used
11e0: 20 74 6f 20 64 69 76 69 64 65 20 75 70 20 74 68   to divide up th
11f0: 65 20 62 75 66 66 65 72 20 70 72 6f 76 69 64 65  e buffer provide
1200: 64 20 75 73 69 6e 67 0a 2a 2a 20 74 68 65 20 53  d using.** the S
1210: 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47  QLITE_CONFIG_PAG
1220: 45 43 41 43 48 45 20 6d 65 63 68 61 6e 69 73 6d  ECACHE mechanism
1230: 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 50 67 46 72  ..*/.struct PgFr
1240: 65 65 73 6c 6f 74 20 7b 0a 20 20 50 67 46 72 65  eeslot {.  PgFre
1250: 65 73 6c 6f 74 20 2a 70 4e 65 78 74 3b 20 20 2f  eslot *pNext;  /
1260: 2a 20 4e 65 78 74 20 66 72 65 65 20 73 6c 6f 74  * Next free slot
1270: 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 47 6c   */.};../*.** Gl
1280: 6f 62 61 6c 20 64 61 74 61 20 75 73 65 64 20 62  obal data used b
1290: 79 20 74 68 69 73 20 63 61 63 68 65 2e 0a 2a 2f  y this cache..*/
12a0: 0a 73 74 61 74 69 63 20 53 51 4c 49 54 45 5f 57  .static SQLITE_W
12b0: 53 44 20 73 74 72 75 63 74 20 50 43 61 63 68 65  SD struct PCache
12c0: 47 6c 6f 62 61 6c 20 7b 0a 20 20 50 47 72 6f 75  Global {.  PGrou
12d0: 70 20 67 72 70 3b 20 20 20 20 20 20 20 20 20 20  p grp;          
12e0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65            /* The
12f0: 20 67 6c 6f 62 61 6c 20 50 47 72 6f 75 70 20 66   global PGroup f
1300: 6f 72 20 6d 6f 64 65 20 28 32 29 20 2a 2f 0a 0a  or mode (2) */..
1310: 20 20 2f 2a 20 56 61 72 69 61 62 6c 65 73 20 72    /* Variables r
1320: 65 6c 61 74 65 64 20 74 6f 20 53 51 4c 49 54 45  elated to SQLITE
1330: 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48  _CONFIG_PAGECACH
1340: 45 20 73 65 74 74 69 6e 67 73 2e 20 20 54 68 65  E settings.  The
1350: 0a 20 20 2a 2a 20 73 7a 53 6c 6f 74 2c 20 6e 53  .  ** szSlot, nS
1360: 6c 6f 74 2c 20 70 53 74 61 72 74 2c 20 70 45 6e  lot, pStart, pEn
1370: 64 2c 20 6e 52 65 73 65 72 76 65 2c 20 61 6e 64  d, nReserve, and
1380: 20 69 73 49 6e 69 74 20 76 61 6c 75 65 73 20 61   isInit values a
1390: 72 65 20 61 6c 6c 0a 20 20 2a 2a 20 66 69 78 65  re all.  ** fixe
13a0: 64 20 61 74 20 73 71 6c 69 74 65 33 5f 69 6e 69  d at sqlite3_ini
13b0: 74 69 61 6c 69 7a 65 28 29 20 74 69 6d 65 20 61  tialize() time a
13c0: 6e 64 20 64 6f 20 6e 6f 74 20 72 65 71 75 69 72  nd do not requir
13d0: 65 20 6d 75 74 65 78 20 70 72 6f 74 65 63 74 69  e mutex protecti
13e0: 6f 6e 2e 0a 20 20 2a 2a 20 54 68 65 20 6e 46 72  on..  ** The nFr
13f0: 65 65 53 6c 6f 74 20 61 6e 64 20 70 46 72 65 65  eeSlot and pFree
1400: 20 76 61 6c 75 65 73 20 64 6f 20 72 65 71 75 69   values do requi
1410: 72 65 20 6d 75 74 65 78 20 70 72 6f 74 65 63 74  re mutex protect
1420: 69 6f 6e 2e 0a 20 20 2a 2f 0a 20 20 69 6e 74 20  ion..  */.  int 
1430: 69 73 49 6e 69 74 3b 20 20 20 20 20 20 20 20 20  isInit;         
1440: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72             /* Tr
1450: 75 65 20 69 66 20 69 6e 69 74 69 61 6c 69 7a 65  ue if initialize
1460: 64 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 53 6c 6f  d */.  int szSlo
1470: 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t;              
1480: 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66        /* Size of
1490: 20 65 61 63 68 20 66 72 65 65 20 73 6c 6f 74 20   each free slot 
14a0: 2a 2f 0a 20 20 69 6e 74 20 6e 53 6c 6f 74 3b 20  */.  int nSlot; 
14b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14c0: 20 20 20 20 2f 2a 20 54 68 65 20 6e 75 6d 62 65      /* The numbe
14d0: 72 20 6f 66 20 70 63 61 63 68 65 20 73 6c 6f 74  r of pcache slot
14e0: 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 52 65 73 65  s */.  int nRese
14f0: 72 76 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  rve;            
1500: 20 20 20 20 20 20 2f 2a 20 54 72 79 20 74 6f 20        /* Try to 
1510: 6b 65 65 70 20 6e 46 72 65 65 53 6c 6f 74 20 61  keep nFreeSlot a
1520: 62 6f 76 65 20 74 68 69 73 20 2a 2f 0a 20 20 76  bove this */.  v
1530: 6f 69 64 20 2a 70 53 74 61 72 74 2c 20 2a 70 45  oid *pStart, *pE
1540: 6e 64 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a  nd;           /*
1550: 20 42 6f 75 6e 64 73 20 6f 66 20 70 61 67 65 63   Bounds of pagec
1560: 61 63 68 65 20 6d 61 6c 6c 6f 63 20 72 61 6e 67  ache malloc rang
1570: 65 20 2a 2f 0a 20 20 2f 2a 20 41 62 6f 76 65 20  e */.  /* Above 
1580: 72 65 71 75 69 72 65 73 20 6e 6f 20 6d 75 74 65  requires no mute
1590: 78 2e 20 20 55 73 65 20 6d 75 74 65 78 20 62 65  x.  Use mutex be
15a0: 6c 6f 77 20 66 6f 72 20 76 61 72 69 61 62 6c 65  low for variable
15b0: 20 74 68 61 74 20 66 6f 6c 6c 6f 77 2e 20 2a 2f   that follow. */
15c0: 0a 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78  .  sqlite3_mutex
15d0: 20 2a 6d 75 74 65 78 3b 20 20 20 20 20 20 20 20   *mutex;        
15e0: 20 20 2f 2a 20 4d 75 74 65 78 20 66 6f 72 20 61    /* Mutex for a
15f0: 63 63 65 73 73 69 6e 67 20 74 68 65 20 66 6f 6c  ccessing the fol
1600: 6c 6f 77 69 6e 67 3a 20 2a 2f 0a 20 20 50 67 46  lowing: */.  PgF
1610: 72 65 65 73 6c 6f 74 20 2a 70 46 72 65 65 3b 20  reeslot *pFree; 
1620: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46              /* F
1630: 72 65 65 20 70 61 67 65 20 62 6c 6f 63 6b 73 20  ree page blocks 
1640: 2a 2f 0a 20 20 69 6e 74 20 6e 46 72 65 65 53 6c  */.  int nFreeSl
1650: 6f 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ot;             
1660: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
1670: 20 75 6e 75 73 65 64 20 70 63 61 63 68 65 20 73   unused pcache s
1680: 6c 6f 74 73 20 2a 2f 0a 20 20 2f 2a 20 54 68 65  lots */.  /* The
1690: 20 66 6f 6c 6c 6f 77 69 6e 67 20 76 61 6c 75 65   following value
16a0: 20 72 65 71 75 69 72 65 73 20 61 20 6d 75 74 65   requires a mute
16b0: 78 20 74 6f 20 63 68 61 6e 67 65 2e 20 20 57 65  x to change.  We
16c0: 20 73 6b 69 70 20 74 68 65 20 6d 75 74 65 78 20   skip the mutex 
16d0: 6f 6e 0a 20 20 2a 2a 20 72 65 61 64 69 6e 67 20  on.  ** reading 
16e0: 62 65 63 61 75 73 65 20 28 31 29 20 6d 6f 73 74  because (1) most
16f0: 20 70 6c 61 74 66 6f 72 6d 73 20 72 65 61 64 20   platforms read 
1700: 61 20 33 32 2d 62 69 74 20 69 6e 74 65 67 65 72  a 32-bit integer
1710: 20 61 74 6f 6d 69 63 61 6c 6c 79 20 61 6e 64 0a   atomically and.
1720: 20 20 2a 2a 20 28 32 29 20 65 76 65 6e 20 69 66    ** (2) even if
1730: 20 61 6e 20 69 6e 63 6f 72 72 65 63 74 20 76 61   an incorrect va
1740: 6c 75 65 20 69 73 20 72 65 61 64 2c 20 6e 6f 20  lue is read, no 
1750: 67 72 65 61 74 20 68 61 72 6d 20 69 73 20 64 6f  great harm is do
1760: 6e 65 20 73 69 6e 63 65 20 74 68 69 73 0a 20 20  ne since this.  
1770: 2a 2a 20 69 73 20 72 65 61 6c 6c 79 20 6a 75 73  ** is really jus
1780: 74 20 61 6e 20 6f 70 74 69 6d 69 7a 61 74 69 6f  t an optimizatio
1790: 6e 2e 20 2a 2f 0a 20 20 69 6e 74 20 62 55 6e 64  n. */.  int bUnd
17a0: 65 72 50 72 65 73 73 75 72 65 3b 20 20 20 20 20  erPressure;     
17b0: 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69         /* True i
17c0: 66 20 6c 6f 77 20 6f 6e 20 50 41 47 45 43 41 43  f low on PAGECAC
17d0: 48 45 20 6d 65 6d 6f 72 79 20 2a 2f 0a 7d 20 70  HE memory */.} p
17e0: 63 61 63 68 65 31 5f 67 3b 0a 0a 2f 2a 0a 2a 2a  cache1_g;../*.**
17f0: 20 41 6c 6c 20 63 6f 64 65 20 69 6e 20 74 68 69   All code in thi
1800: 73 20 66 69 6c 65 20 73 68 6f 75 6c 64 20 61 63  s file should ac
1810: 63 65 73 73 20 74 68 65 20 67 6c 6f 62 61 6c 20  cess the global 
1820: 73 74 72 75 63 74 75 72 65 20 61 62 6f 76 65 20  structure above 
1830: 76 69 61 20 74 68 65 0a 2a 2a 20 61 6c 69 61 73  via the.** alias
1840: 20 22 70 63 61 63 68 65 31 22 2e 20 54 68 69 73   "pcache1". This
1850: 20 65 6e 73 75 72 65 73 20 74 68 61 74 20 74 68   ensures that th
1860: 65 20 57 53 44 20 65 6d 75 6c 61 74 69 6f 6e 20  e WSD emulation 
1870: 69 73 20 75 73 65 64 20 77 68 65 6e 0a 2a 2a 20  is used when.** 
1880: 63 6f 6d 70 69 6c 69 6e 67 20 66 6f 72 20 73 79  compiling for sy
1890: 73 74 65 6d 73 20 74 68 61 74 20 64 6f 20 6e 6f  stems that do no
18a0: 74 20 73 75 70 70 6f 72 74 20 72 65 61 6c 20 57  t support real W
18b0: 53 44 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 70  SD..*/.#define p
18c0: 63 61 63 68 65 31 20 28 47 4c 4f 42 41 4c 28 73  cache1 (GLOBAL(s
18d0: 74 72 75 63 74 20 50 43 61 63 68 65 47 6c 6f 62  truct PCacheGlob
18e0: 61 6c 2c 20 70 63 61 63 68 65 31 5f 67 29 29 0a  al, pcache1_g)).
18f0: 0a 2f 2a 0a 2a 2a 20 4d 61 63 72 6f 73 20 74 6f  ./*.** Macros to
1900: 20 65 6e 74 65 72 20 61 6e 64 20 6c 65 61 76 65   enter and leave
1910: 20 74 68 65 20 50 43 61 63 68 65 20 4c 52 55 20   the PCache LRU 
1920: 6d 75 74 65 78 2e 0a 2a 2f 0a 23 64 65 66 69 6e  mutex..*/.#defin
1930: 65 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75  e pcache1EnterMu
1940: 74 65 78 28 58 29 20 73 71 6c 69 74 65 33 5f 6d  tex(X) sqlite3_m
1950: 75 74 65 78 5f 65 6e 74 65 72 28 28 58 29 2d 3e  utex_enter((X)->
1960: 6d 75 74 65 78 29 0a 23 64 65 66 69 6e 65 20 70  mutex).#define p
1970: 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78  cache1LeaveMutex
1980: 28 58 29 20 73 71 6c 69 74 65 33 5f 6d 75 74 65  (X) sqlite3_mute
1990: 78 5f 6c 65 61 76 65 28 28 58 29 2d 3e 6d 75 74  x_leave((X)->mut
19a0: 65 78 29 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ex)../**********
19b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
19c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
19d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
19e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
19f0: 2a 2a 2a 2a 2f 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 20  ****/./******** 
1a00: 50 61 67 65 20 41 6c 6c 6f 63 61 74 69 6f 6e 2f  Page Allocation/
1a10: 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 43  SQLITE_CONFIG_PC
1a20: 41 43 48 45 20 52 65 6c 61 74 65 64 20 46 75 6e  ACHE Related Fun
1a30: 63 74 69 6f 6e 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a  ctions *********
1a40: 2a 2a 2a 2a 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 54 68  *****/../*.** Th
1a50: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63  is function is c
1a60: 61 6c 6c 65 64 20 64 75 72 69 6e 67 20 69 6e 69  alled during ini
1a70: 74 69 61 6c 69 7a 61 74 69 6f 6e 20 69 66 20 61  tialization if a
1a80: 20 73 74 61 74 69 63 20 62 75 66 66 65 72 20 69   static buffer i
1a90: 73 20 0a 2a 2a 20 73 75 70 70 6c 69 65 64 20 74  s .** supplied t
1aa0: 6f 20 75 73 65 20 66 6f 72 20 74 68 65 20 70 61  o use for the pa
1ab0: 67 65 2d 63 61 63 68 65 20 62 79 20 70 61 73 73  ge-cache by pass
1ac0: 69 6e 67 20 74 68 65 20 53 51 4c 49 54 45 5f 43  ing the SQLITE_C
1ad0: 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48 45 0a  ONFIG_PAGECACHE.
1ae0: 2a 2a 20 76 65 72 62 20 74 6f 20 73 71 6c 69 74  ** verb to sqlit
1af0: 65 33 5f 63 6f 6e 66 69 67 28 29 2e 20 50 61 72  e3_config(). Par
1b00: 61 6d 65 74 65 72 20 70 42 75 66 20 70 6f 69 6e  ameter pBuf poin
1b10: 74 73 20 74 6f 20 61 6e 20 61 6c 6c 6f 63 61 74  ts to an allocat
1b20: 69 6f 6e 20 6c 61 72 67 65 0a 2a 2a 20 65 6e 6f  ion large.** eno
1b30: 75 67 68 20 74 6f 20 63 6f 6e 74 61 69 6e 20 27  ugh to contain '
1b40: 6e 27 20 62 75 66 66 65 72 73 20 6f 66 20 27 73  n' buffers of 's
1b50: 7a 27 20 62 79 74 65 73 20 65 61 63 68 2e 0a 2a  z' bytes each..*
1b60: 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e  *.** This routin
1b70: 65 20 69 73 20 63 61 6c 6c 65 64 20 66 72 6f 6d  e is called from
1b80: 20 73 71 6c 69 74 65 33 5f 69 6e 69 74 69 61 6c   sqlite3_initial
1b90: 69 7a 65 28 29 20 61 6e 64 20 73 6f 20 69 74 20  ize() and so it 
1ba0: 69 73 20 67 75 61 72 61 6e 74 65 65 64 0a 2a 2a  is guaranteed.**
1bb0: 20 74 6f 20 62 65 20 73 65 72 69 61 6c 69 7a 65   to be serialize
1bc0: 64 20 61 6c 72 65 61 64 79 2e 20 20 54 68 65 72  d already.  Ther
1bd0: 65 20 69 73 20 6e 6f 20 6e 65 65 64 20 66 6f 72  e is no need for
1be0: 20 66 75 72 74 68 65 72 20 6d 75 74 65 78 69 6e   further mutexin
1bf0: 67 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74  g..*/.void sqlit
1c00: 65 33 50 43 61 63 68 65 42 75 66 66 65 72 53 65  e3PCacheBufferSe
1c10: 74 75 70 28 76 6f 69 64 20 2a 70 42 75 66 2c 20  tup(void *pBuf, 
1c20: 69 6e 74 20 73 7a 2c 20 69 6e 74 20 6e 29 7b 0a  int sz, int n){.
1c30: 20 20 69 66 28 20 70 63 61 63 68 65 31 2e 69 73    if( pcache1.is
1c40: 49 6e 69 74 20 29 7b 0a 20 20 20 20 50 67 46 72  Init ){.    PgFr
1c50: 65 65 73 6c 6f 74 20 2a 70 3b 0a 20 20 20 20 73  eeslot *p;.    s
1c60: 7a 20 3d 20 52 4f 55 4e 44 44 4f 57 4e 38 28 73  z = ROUNDDOWN8(s
1c70: 7a 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e  z);.    pcache1.
1c80: 73 7a 53 6c 6f 74 20 3d 20 73 7a 3b 0a 20 20 20  szSlot = sz;.   
1c90: 20 70 63 61 63 68 65 31 2e 6e 53 6c 6f 74 20 3d   pcache1.nSlot =
1ca0: 20 70 63 61 63 68 65 31 2e 6e 46 72 65 65 53 6c   pcache1.nFreeSl
1cb0: 6f 74 20 3d 20 6e 3b 0a 20 20 20 20 70 63 61 63  ot = n;.    pcac
1cc0: 68 65 31 2e 6e 52 65 73 65 72 76 65 20 3d 20 6e  he1.nReserve = n
1cd0: 3e 39 30 20 3f 20 31 30 20 3a 20 28 6e 2f 31 30  >90 ? 10 : (n/10
1ce0: 20 2b 20 31 29 3b 0a 20 20 20 20 70 63 61 63 68   + 1);.    pcach
1cf0: 65 31 2e 70 53 74 61 72 74 20 3d 20 70 42 75 66  e1.pStart = pBuf
1d00: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 70 46  ;.    pcache1.pF
1d10: 72 65 65 20 3d 20 30 3b 0a 20 20 20 20 70 63 61  ree = 0;.    pca
1d20: 63 68 65 31 2e 62 55 6e 64 65 72 50 72 65 73 73  che1.bUnderPress
1d30: 75 72 65 20 3d 20 30 3b 0a 20 20 20 20 77 68 69  ure = 0;.    whi
1d40: 6c 65 28 20 6e 2d 2d 20 29 7b 0a 20 20 20 20 20  le( n-- ){.     
1d50: 20 70 20 3d 20 28 50 67 46 72 65 65 73 6c 6f 74   p = (PgFreeslot
1d60: 2a 29 70 42 75 66 3b 0a 20 20 20 20 20 20 70 2d  *)pBuf;.      p-
1d70: 3e 70 4e 65 78 74 20 3d 20 70 63 61 63 68 65 31  >pNext = pcache1
1d80: 2e 70 46 72 65 65 3b 0a 20 20 20 20 20 20 70 63  .pFree;.      pc
1d90: 61 63 68 65 31 2e 70 46 72 65 65 20 3d 20 70 3b  ache1.pFree = p;
1da0: 0a 20 20 20 20 20 20 70 42 75 66 20 3d 20 28 76  .      pBuf = (v
1db0: 6f 69 64 2a 29 26 28 28 63 68 61 72 2a 29 70 42  oid*)&((char*)pB
1dc0: 75 66 29 5b 73 7a 5d 3b 0a 20 20 20 20 7d 0a 20  uf)[sz];.    }. 
1dd0: 20 20 20 70 63 61 63 68 65 31 2e 70 45 6e 64 20     pcache1.pEnd 
1de0: 3d 20 70 42 75 66 3b 0a 20 20 7d 0a 7d 0a 0a 2f  = pBuf;.  }.}../
1df0: 2a 0a 2a 2a 20 4d 61 6c 6c 6f 63 20 66 75 6e 63  *.** Malloc func
1e00: 74 69 6f 6e 20 75 73 65 64 20 77 69 74 68 69 6e  tion used within
1e10: 20 74 68 69 73 20 66 69 6c 65 20 74 6f 20 61 6c   this file to al
1e20: 6c 6f 63 61 74 65 20 73 70 61 63 65 20 66 72 6f  locate space fro
1e30: 6d 20 74 68 65 20 62 75 66 66 65 72 0a 2a 2a 20  m the buffer.** 
1e40: 63 6f 6e 66 69 67 75 72 65 64 20 75 73 69 6e 67  configured using
1e50: 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67 28   sqlite3_config(
1e60: 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41  SQLITE_CONFIG_PA
1e70: 47 45 43 41 43 48 45 29 20 6f 70 74 69 6f 6e 2e  GECACHE) option.
1e80: 20 49 66 20 6e 6f 20 0a 2a 2a 20 73 75 63 68 20   If no .** such 
1e90: 62 75 66 66 65 72 20 65 78 69 73 74 73 20 6f 72  buffer exists or
1ea0: 20 74 68 65 72 65 20 69 73 20 6e 6f 20 73 70 61   there is no spa
1eb0: 63 65 20 6c 65 66 74 20 69 6e 20 69 74 2c 20 74  ce left in it, t
1ec0: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 66 61 6c  his function fal
1ed0: 6c 73 20 0a 2a 2a 20 62 61 63 6b 20 74 6f 20 73  ls .** back to s
1ee0: 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 29 2e 0a  qlite3Malloc()..
1ef0: 2a 2a 0a 2a 2a 20 4d 75 6c 74 69 70 6c 65 20 74  **.** Multiple t
1f00: 68 72 65 61 64 73 20 63 61 6e 20 72 75 6e 20 74  hreads can run t
1f10: 68 69 73 20 72 6f 75 74 69 6e 65 20 61 74 20 74  his routine at t
1f20: 68 65 20 73 61 6d 65 20 74 69 6d 65 2e 20 20 47  he same time.  G
1f30: 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73 0a  lobal variables.
1f40: 2a 2a 20 69 6e 20 70 63 61 63 68 65 31 20 6e 65  ** in pcache1 ne
1f50: 65 64 20 74 6f 20 62 65 20 70 72 6f 74 65 63 74  ed to be protect
1f60: 65 64 20 76 69 61 20 6d 75 74 65 78 2e 0a 2a 2f  ed via mutex..*/
1f70: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 2a 70 63  .static void *pc
1f80: 61 63 68 65 31 41 6c 6c 6f 63 28 69 6e 74 20 6e  ache1Alloc(int n
1f90: 42 79 74 65 29 7b 0a 20 20 76 6f 69 64 20 2a 70  Byte){.  void *p
1fa0: 20 3d 20 30 3b 0a 20 20 61 73 73 65 72 74 28 20   = 0;.  assert( 
1fb0: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6e 6f  sqlite3_mutex_no
1fc0: 74 68 65 6c 64 28 70 63 61 63 68 65 31 2e 67 72  theld(pcache1.gr
1fd0: 70 2e 6d 75 74 65 78 29 20 29 3b 0a 20 20 73 71  p.mutex) );.  sq
1fe0: 6c 69 74 65 33 53 74 61 74 75 73 53 65 74 28 53  lite3StatusSet(S
1ff0: 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41 47  QLITE_STATUS_PAG
2000: 45 43 41 43 48 45 5f 53 49 5a 45 2c 20 6e 42 79  ECACHE_SIZE, nBy
2010: 74 65 29 3b 0a 20 20 69 66 28 20 6e 42 79 74 65  te);.  if( nByte
2020: 3c 3d 70 63 61 63 68 65 31 2e 73 7a 53 6c 6f 74  <=pcache1.szSlot
2030: 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f   ){.    sqlite3_
2040: 6d 75 74 65 78 5f 65 6e 74 65 72 28 70 63 61 63  mutex_enter(pcac
2050: 68 65 31 2e 6d 75 74 65 78 29 3b 0a 20 20 20 20  he1.mutex);.    
2060: 70 20 3d 20 28 50 67 48 64 72 31 20 2a 29 70 63  p = (PgHdr1 *)pc
2070: 61 63 68 65 31 2e 70 46 72 65 65 3b 0a 20 20 20  ache1.pFree;.   
2080: 20 69 66 28 20 70 20 29 7b 0a 20 20 20 20 20 20   if( p ){.      
2090: 70 63 61 63 68 65 31 2e 70 46 72 65 65 20 3d 20  pcache1.pFree = 
20a0: 70 63 61 63 68 65 31 2e 70 46 72 65 65 2d 3e 70  pcache1.pFree->p
20b0: 4e 65 78 74 3b 0a 20 20 20 20 20 20 70 63 61 63  Next;.      pcac
20c0: 68 65 31 2e 6e 46 72 65 65 53 6c 6f 74 2d 2d 3b  he1.nFreeSlot--;
20d0: 0a 20 20 20 20 20 20 70 63 61 63 68 65 31 2e 62  .      pcache1.b
20e0: 55 6e 64 65 72 50 72 65 73 73 75 72 65 20 3d 20  UnderPressure = 
20f0: 70 63 61 63 68 65 31 2e 6e 46 72 65 65 53 6c 6f  pcache1.nFreeSlo
2100: 74 3c 70 63 61 63 68 65 31 2e 6e 52 65 73 65 72  t<pcache1.nReser
2110: 76 65 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74  ve;.      assert
2120: 28 20 70 63 61 63 68 65 31 2e 6e 46 72 65 65 53  ( pcache1.nFreeS
2130: 6c 6f 74 3e 3d 30 20 29 3b 0a 20 20 20 20 20 20  lot>=0 );.      
2140: 73 71 6c 69 74 65 33 53 74 61 74 75 73 41 64 64  sqlite3StatusAdd
2150: 28 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50  (SQLITE_STATUS_P
2160: 41 47 45 43 41 43 48 45 5f 55 53 45 44 2c 20 31  AGECACHE_USED, 1
2170: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 6c  );.    }.    sql
2180: 69 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65  ite3_mutex_leave
2190: 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29 3b  (pcache1.mutex);
21a0: 0a 20 20 7d 0a 20 20 69 66 28 20 70 3d 3d 30 20  .  }.  if( p==0 
21b0: 29 7b 0a 20 20 20 20 2f 2a 20 4d 65 6d 6f 72 79  ){.    /* Memory
21c0: 20 69 73 20 6e 6f 74 20 61 76 61 69 6c 61 62 6c   is not availabl
21d0: 65 20 69 6e 20 74 68 65 20 53 51 4c 49 54 45 5f  e in the SQLITE_
21e0: 43 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48 45  CONFIG_PAGECACHE
21f0: 20 70 6f 6f 6c 2e 20 20 47 65 74 0a 20 20 20 20   pool.  Get.    
2200: 2a 2a 20 69 74 20 66 72 6f 6d 20 73 71 6c 69 74  ** it from sqlit
2210: 65 33 4d 61 6c 6c 6f 63 20 69 6e 73 74 65 61 64  e3Malloc instead
2220: 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 70 20 3d  ..    */.    p =
2230: 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 6e   sqlite3Malloc(n
2240: 42 79 74 65 29 3b 0a 23 69 66 6e 64 65 66 20 53  Byte);.#ifndef S
2250: 51 4c 49 54 45 5f 44 49 53 41 42 4c 45 5f 50 41  QLITE_DISABLE_PA
2260: 47 45 43 41 43 48 45 5f 4f 56 45 52 46 4c 4f 57  GECACHE_OVERFLOW
2270: 5f 53 54 41 54 53 0a 20 20 20 20 69 66 28 20 70  _STATS.    if( p
2280: 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 73 7a   ){.      int sz
2290: 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63   = sqlite3Malloc
22a0: 53 69 7a 65 28 70 29 3b 0a 20 20 20 20 20 20 73  Size(p);.      s
22b0: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e 74  qlite3_mutex_ent
22c0: 65 72 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78  er(pcache1.mutex
22d0: 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  );.      sqlite3
22e0: 53 74 61 74 75 73 41 64 64 28 53 51 4c 49 54 45  StatusAdd(SQLITE
22f0: 5f 53 54 41 54 55 53 5f 50 41 47 45 43 41 43 48  _STATUS_PAGECACH
2300: 45 5f 4f 56 45 52 46 4c 4f 57 2c 20 73 7a 29 3b  E_OVERFLOW, sz);
2310: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 6d  .      sqlite3_m
2320: 75 74 65 78 5f 6c 65 61 76 65 28 70 63 61 63 68  utex_leave(pcach
2330: 65 31 2e 6d 75 74 65 78 29 3b 0a 20 20 20 20 7d  e1.mutex);.    }
2340: 0a 23 65 6e 64 69 66 0a 20 20 20 20 73 71 6c 69  .#endif.    sqli
2350: 74 65 33 4d 65 6d 64 65 62 75 67 53 65 74 54 79  te3MemdebugSetTy
2360: 70 65 28 70 2c 20 4d 45 4d 54 59 50 45 5f 50 43  pe(p, MEMTYPE_PC
2370: 41 43 48 45 29 3b 0a 20 20 7d 0a 20 20 72 65 74  ACHE);.  }.  ret
2380: 75 72 6e 20 70 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  urn p;.}../*.** 
2390: 46 72 65 65 20 61 6e 20 61 6c 6c 6f 63 61 74 65  Free an allocate
23a0: 64 20 62 75 66 66 65 72 20 6f 62 74 61 69 6e 65  d buffer obtaine
23b0: 64 20 66 72 6f 6d 20 70 63 61 63 68 65 31 41 6c  d from pcache1Al
23c0: 6c 6f 63 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63  loc()..*/.static
23d0: 20 69 6e 74 20 70 63 61 63 68 65 31 46 72 65 65   int pcache1Free
23e0: 28 76 6f 69 64 20 2a 70 29 7b 0a 20 20 69 6e 74  (void *p){.  int
23f0: 20 6e 46 72 65 65 64 20 3d 20 30 3b 0a 20 20 69   nFreed = 0;.  i
2400: 66 28 20 70 3d 3d 30 20 29 20 72 65 74 75 72 6e  f( p==0 ) return
2410: 20 30 3b 0a 20 20 69 66 28 20 70 3e 3d 70 63 61   0;.  if( p>=pca
2420: 63 68 65 31 2e 70 53 74 61 72 74 20 26 26 20 70  che1.pStart && p
2430: 3c 70 63 61 63 68 65 31 2e 70 45 6e 64 20 29 7b  <pcache1.pEnd ){
2440: 0a 20 20 20 20 50 67 46 72 65 65 73 6c 6f 74 20  .    PgFreeslot 
2450: 2a 70 53 6c 6f 74 3b 0a 20 20 20 20 73 71 6c 69  *pSlot;.    sqli
2460: 74 65 33 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28  te3_mutex_enter(
2470: 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a  pcache1.mutex);.
2480: 20 20 20 20 73 71 6c 69 74 65 33 53 74 61 74 75      sqlite3Statu
2490: 73 41 64 64 28 53 51 4c 49 54 45 5f 53 54 41 54  sAdd(SQLITE_STAT
24a0: 55 53 5f 50 41 47 45 43 41 43 48 45 5f 55 53 45  US_PAGECACHE_USE
24b0: 44 2c 20 2d 31 29 3b 0a 20 20 20 20 70 53 6c 6f  D, -1);.    pSlo
24c0: 74 20 3d 20 28 50 67 46 72 65 65 73 6c 6f 74 2a  t = (PgFreeslot*
24d0: 29 70 3b 0a 20 20 20 20 70 53 6c 6f 74 2d 3e 70  )p;.    pSlot->p
24e0: 4e 65 78 74 20 3d 20 70 63 61 63 68 65 31 2e 70  Next = pcache1.p
24f0: 46 72 65 65 3b 0a 20 20 20 20 70 63 61 63 68 65  Free;.    pcache
2500: 31 2e 70 46 72 65 65 20 3d 20 70 53 6c 6f 74 3b  1.pFree = pSlot;
2510: 0a 20 20 20 20 70 63 61 63 68 65 31 2e 6e 46 72  .    pcache1.nFr
2520: 65 65 53 6c 6f 74 2b 2b 3b 0a 20 20 20 20 70 63  eeSlot++;.    pc
2530: 61 63 68 65 31 2e 62 55 6e 64 65 72 50 72 65 73  ache1.bUnderPres
2540: 73 75 72 65 20 3d 20 70 63 61 63 68 65 31 2e 6e  sure = pcache1.n
2550: 46 72 65 65 53 6c 6f 74 3c 70 63 61 63 68 65 31  FreeSlot<pcache1
2560: 2e 6e 52 65 73 65 72 76 65 3b 0a 20 20 20 20 61  .nReserve;.    a
2570: 73 73 65 72 74 28 20 70 63 61 63 68 65 31 2e 6e  ssert( pcache1.n
2580: 46 72 65 65 53 6c 6f 74 3c 3d 70 63 61 63 68 65  FreeSlot<=pcache
2590: 31 2e 6e 53 6c 6f 74 20 29 3b 0a 20 20 20 20 73  1.nSlot );.    s
25a0: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61  qlite3_mutex_lea
25b0: 76 65 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78  ve(pcache1.mutex
25c0: 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  );.  }else{.    
25d0: 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 4d  assert( sqlite3M
25e0: 65 6d 64 65 62 75 67 48 61 73 54 79 70 65 28 70  emdebugHasType(p
25f0: 2c 20 4d 45 4d 54 59 50 45 5f 50 43 41 43 48 45  , MEMTYPE_PCACHE
2600: 29 20 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  ) );.    sqlite3
2610: 4d 65 6d 64 65 62 75 67 53 65 74 54 79 70 65 28  MemdebugSetType(
2620: 70 2c 20 4d 45 4d 54 59 50 45 5f 48 45 41 50 29  p, MEMTYPE_HEAP)
2630: 3b 0a 20 20 20 20 6e 46 72 65 65 64 20 3d 20 73  ;.    nFreed = s
2640: 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 53 69 7a 65  qlite3MallocSize
2650: 28 70 29 3b 0a 23 69 66 6e 64 65 66 20 53 51 4c  (p);.#ifndef SQL
2660: 49 54 45 5f 44 49 53 41 42 4c 45 5f 50 41 47 45  ITE_DISABLE_PAGE
2670: 43 41 43 48 45 5f 4f 56 45 52 46 4c 4f 57 5f 53  CACHE_OVERFLOW_S
2680: 54 41 54 53 0a 20 20 20 20 73 71 6c 69 74 65 33  TATS.    sqlite3
2690: 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28 70 63 61  _mutex_enter(pca
26a0: 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a 20 20 20  che1.mutex);.   
26b0: 20 73 71 6c 69 74 65 33 53 74 61 74 75 73 41 64   sqlite3StatusAd
26c0: 64 28 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f  d(SQLITE_STATUS_
26d0: 50 41 47 45 43 41 43 48 45 5f 4f 56 45 52 46 4c  PAGECACHE_OVERFL
26e0: 4f 57 2c 20 2d 6e 46 72 65 65 64 29 3b 0a 20 20  OW, -nFreed);.  
26f0: 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f    sqlite3_mutex_
2700: 6c 65 61 76 65 28 70 63 61 63 68 65 31 2e 6d 75  leave(pcache1.mu
2710: 74 65 78 29 3b 0a 23 65 6e 64 69 66 0a 20 20 20  tex);.#endif.   
2720: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 29   sqlite3_free(p)
2730: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 6e  ;.  }.  return n
2740: 46 72 65 65 64 3b 0a 7d 0a 0a 23 69 66 64 65 66  Freed;.}..#ifdef
2750: 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d   SQLITE_ENABLE_M
2760: 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54  EMORY_MANAGEMENT
2770: 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68  ./*.** Return th
2780: 65 20 73 69 7a 65 20 6f 66 20 61 20 70 63 61 63  e size of a pcac
2790: 68 65 20 61 6c 6c 6f 63 61 74 69 6f 6e 0a 2a 2f  he allocation.*/
27a0: 0a 73 74 61 74 69 63 20 69 6e 74 20 70 63 61 63  .static int pcac
27b0: 68 65 31 4d 65 6d 53 69 7a 65 28 76 6f 69 64 20  he1MemSize(void 
27c0: 2a 70 29 7b 0a 20 20 69 66 28 20 70 3e 3d 70 63  *p){.  if( p>=pc
27d0: 61 63 68 65 31 2e 70 53 74 61 72 74 20 26 26 20  ache1.pStart && 
27e0: 70 3c 70 63 61 63 68 65 31 2e 70 45 6e 64 20 29  p<pcache1.pEnd )
27f0: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 70 63 61  {.    return pca
2800: 63 68 65 31 2e 73 7a 53 6c 6f 74 3b 0a 20 20 7d  che1.szSlot;.  }
2810: 65 6c 73 65 7b 0a 20 20 20 20 69 6e 74 20 69 53  else{.    int iS
2820: 69 7a 65 3b 0a 20 20 20 20 61 73 73 65 72 74 28  ize;.    assert(
2830: 20 73 71 6c 69 74 65 33 4d 65 6d 64 65 62 75 67   sqlite3Memdebug
2840: 48 61 73 54 79 70 65 28 70 2c 20 4d 45 4d 54 59  HasType(p, MEMTY
2850: 50 45 5f 50 43 41 43 48 45 29 20 29 3b 0a 20 20  PE_PCACHE) );.  
2860: 20 20 73 71 6c 69 74 65 33 4d 65 6d 64 65 62 75    sqlite3Memdebu
2870: 67 53 65 74 54 79 70 65 28 70 2c 20 4d 45 4d 54  gSetType(p, MEMT
2880: 59 50 45 5f 48 45 41 50 29 3b 0a 20 20 20 20 69  YPE_HEAP);.    i
2890: 53 69 7a 65 20 3d 20 73 71 6c 69 74 65 33 4d 61  Size = sqlite3Ma
28a0: 6c 6c 6f 63 53 69 7a 65 28 70 29 3b 0a 20 20 20  llocSize(p);.   
28b0: 20 73 71 6c 69 74 65 33 4d 65 6d 64 65 62 75 67   sqlite3Memdebug
28c0: 53 65 74 54 79 70 65 28 70 2c 20 4d 45 4d 54 59  SetType(p, MEMTY
28d0: 50 45 5f 50 43 41 43 48 45 29 3b 0a 20 20 20 20  PE_PCACHE);.    
28e0: 72 65 74 75 72 6e 20 69 53 69 7a 65 3b 0a 20 20  return iSize;.  
28f0: 7d 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51  }.}.#endif /* SQ
2900: 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f  LITE_ENABLE_MEMO
2910: 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 20 2a 2f  RY_MANAGEMENT */
2920: 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65  ../*.** Allocate
2930: 20 61 20 6e 65 77 20 70 61 67 65 20 6f 62 6a 65   a new page obje
2940: 63 74 20 69 6e 69 74 69 61 6c 6c 79 20 61 73 73  ct initially ass
2950: 6f 63 69 61 74 65 64 20 77 69 74 68 20 63 61 63  ociated with cac
2960: 68 65 20 70 43 61 63 68 65 2e 0a 2a 2f 0a 73 74  he pCache..*/.st
2970: 61 74 69 63 20 50 67 48 64 72 31 20 2a 70 63 61  atic PgHdr1 *pca
2980: 63 68 65 31 41 6c 6c 6f 63 50 61 67 65 28 50 43  che1AllocPage(PC
2990: 61 63 68 65 31 20 2a 70 43 61 63 68 65 29 7b 0a  ache1 *pCache){.
29a0: 20 20 50 67 48 64 72 31 20 2a 70 20 3d 20 30 3b    PgHdr1 *p = 0;
29b0: 0a 20 20 76 6f 69 64 20 2a 70 50 67 3b 0a 0a 20  .  void *pPg;.. 
29c0: 20 2f 2a 20 54 68 65 20 67 72 6f 75 70 20 6d 75   /* The group mu
29d0: 74 65 78 20 6d 75 73 74 20 62 65 20 72 65 6c 65  tex must be rele
29e0: 61 73 65 64 20 62 65 66 6f 72 65 20 70 63 61 63  ased before pcac
29f0: 68 65 31 41 6c 6c 6f 63 28 29 20 69 73 20 63 61  he1Alloc() is ca
2a00: 6c 6c 65 64 2e 20 54 68 69 73 0a 20 20 2a 2a 20  lled. This.  ** 
2a10: 69 73 20 62 65 63 61 75 73 65 20 69 74 20 6d 61  is because it ma
2a20: 79 20 63 61 6c 6c 20 73 71 6c 69 74 65 33 5f 72  y call sqlite3_r
2a30: 65 6c 65 61 73 65 5f 6d 65 6d 6f 72 79 28 29 2c  elease_memory(),
2a40: 20 77 68 69 63 68 20 61 73 73 75 6d 65 73 20 74   which assumes t
2a50: 68 61 74 20 0a 20 20 2a 2a 20 74 68 69 73 20 6d  hat .  ** this m
2a60: 75 74 65 78 20 69 73 20 6e 6f 74 20 68 65 6c 64  utex is not held
2a70: 2e 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 73  . */.  assert( s
2a80: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c  qlite3_mutex_hel
2a90: 64 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70  d(pCache->pGroup
2aa0: 2d 3e 6d 75 74 65 78 29 20 29 3b 0a 20 20 70 63  ->mutex) );.  pc
2ab0: 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28  ache1LeaveMutex(
2ac0: 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b  pCache->pGroup);
2ad0: 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 50  .#ifdef SQLITE_P
2ae0: 43 41 43 48 45 5f 53 45 50 41 52 41 54 45 5f 48  CACHE_SEPARATE_H
2af0: 45 41 44 45 52 0a 20 20 70 50 67 20 3d 20 70 63  EADER.  pPg = pc
2b00: 61 63 68 65 31 41 6c 6c 6f 63 28 70 43 61 63 68  ache1Alloc(pCach
2b10: 65 2d 3e 73 7a 50 61 67 65 29 3b 0a 20 20 70 20  e->szPage);.  p 
2b20: 3d 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28  = sqlite3Malloc(
2b30: 73 69 7a 65 6f 66 28 50 67 48 64 72 31 29 20 2b  sizeof(PgHdr1) +
2b40: 20 70 43 61 63 68 65 2d 3e 73 7a 45 78 74 72 61   pCache->szExtra
2b50: 29 3b 0a 20 20 69 66 28 20 21 70 50 67 20 7c 7c  );.  if( !pPg ||
2b60: 20 21 70 20 29 7b 0a 20 20 20 20 70 63 61 63 68   !p ){.    pcach
2b70: 65 31 46 72 65 65 28 70 50 67 29 3b 0a 20 20 20  e1Free(pPg);.   
2b80: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 29   sqlite3_free(p)
2b90: 3b 0a 20 20 20 20 70 50 67 20 3d 20 30 3b 0a 20  ;.    pPg = 0;. 
2ba0: 20 7d 0a 23 65 6c 73 65 0a 20 20 70 50 67 20 3d   }.#else.  pPg =
2bb0: 20 70 63 61 63 68 65 31 41 6c 6c 6f 63 28 73 69   pcache1Alloc(si
2bc0: 7a 65 6f 66 28 50 67 48 64 72 31 29 20 2b 20 70  zeof(PgHdr1) + p
2bd0: 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 20 2b 20  Cache->szPage + 
2be0: 70 43 61 63 68 65 2d 3e 73 7a 45 78 74 72 61 29  pCache->szExtra)
2bf0: 3b 0a 20 20 70 20 3d 20 28 50 67 48 64 72 31 20  ;.  p = (PgHdr1 
2c00: 2a 29 26 28 28 75 38 20 2a 29 70 50 67 29 5b 70  *)&((u8 *)pPg)[p
2c10: 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 5d 3b 0a  Cache->szPage];.
2c20: 23 65 6e 64 69 66 0a 20 20 70 63 61 63 68 65 31  #endif.  pcache1
2c30: 45 6e 74 65 72 4d 75 74 65 78 28 70 43 61 63 68  EnterMutex(pCach
2c40: 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 0a 20 20 69  e->pGroup);..  i
2c50: 66 28 20 70 50 67 20 29 7b 0a 20 20 20 20 70 2d  f( pPg ){.    p-
2c60: 3e 70 61 67 65 2e 70 42 75 66 20 3d 20 70 50 67  >page.pBuf = pPg
2c70: 3b 0a 20 20 20 20 70 2d 3e 70 61 67 65 2e 70 45  ;.    p->page.pE
2c80: 78 74 72 61 20 3d 20 26 70 5b 31 5d 3b 0a 20 20  xtra = &p[1];.  
2c90: 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 62 50    if( pCache->bP
2ca0: 75 72 67 65 61 62 6c 65 20 29 7b 0a 20 20 20 20  urgeable ){.    
2cb0: 20 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70    pCache->pGroup
2cc0: 2d 3e 6e 43 75 72 72 65 6e 74 50 61 67 65 2b 2b  ->nCurrentPage++
2cd0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72 65 74 75  ;.    }.    retu
2ce0: 72 6e 20 70 3b 0a 20 20 7d 0a 20 20 72 65 74 75  rn p;.  }.  retu
2cf0: 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46  rn 0;.}../*.** F
2d00: 72 65 65 20 61 20 70 61 67 65 20 6f 62 6a 65 63  ree a page objec
2d10: 74 20 61 6c 6c 6f 63 61 74 65 64 20 62 79 20 70  t allocated by p
2d20: 63 61 63 68 65 31 41 6c 6c 6f 63 50 61 67 65 28  cache1AllocPage(
2d30: 29 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 70 6f 69  )..**.** The poi
2d40: 6e 74 65 72 20 69 73 20 61 6c 6c 6f 77 65 64 20  nter is allowed 
2d50: 74 6f 20 62 65 20 4e 55 4c 4c 2c 20 77 68 69 63  to be NULL, whic
2d60: 68 20 69 73 20 70 72 75 64 65 6e 74 2e 20 20 42  h is prudent.  B
2d70: 75 74 20 69 74 20 74 75 72 6e 73 20 6f 75 74 0a  ut it turns out.
2d80: 2a 2a 20 74 68 61 74 20 74 68 65 20 63 75 72 72  ** that the curr
2d90: 65 6e 74 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69  ent implementati
2da0: 6f 6e 20 68 61 70 70 65 6e 73 20 74 6f 20 6e 65  on happens to ne
2db0: 76 65 72 20 63 61 6c 6c 20 74 68 69 73 20 72 6f  ver call this ro
2dc0: 75 74 69 6e 65 0a 2a 2a 20 77 69 74 68 20 61 20  utine.** with a 
2dd0: 4e 55 4c 4c 20 70 6f 69 6e 74 65 72 2c 20 73 6f  NULL pointer, so
2de0: 20 77 65 20 6d 61 72 6b 20 74 68 65 20 4e 55 4c   we mark the NUL
2df0: 4c 20 74 65 73 74 20 77 69 74 68 20 41 4c 57 41  L test with ALWA
2e00: 59 53 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  YS()..*/.static 
2e10: 76 6f 69 64 20 70 63 61 63 68 65 31 46 72 65 65  void pcache1Free
2e20: 50 61 67 65 28 50 67 48 64 72 31 20 2a 70 29 7b  Page(PgHdr1 *p){
2e30: 0a 20 20 69 66 28 20 41 4c 57 41 59 53 28 70 29  .  if( ALWAYS(p)
2e40: 20 29 7b 0a 20 20 20 20 50 43 61 63 68 65 31 20   ){.    PCache1 
2e50: 2a 70 43 61 63 68 65 20 3d 20 70 2d 3e 70 43 61  *pCache = p->pCa
2e60: 63 68 65 3b 0a 20 20 20 20 61 73 73 65 72 74 28  che;.    assert(
2e70: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68   sqlite3_mutex_h
2e80: 65 6c 64 28 70 2d 3e 70 43 61 63 68 65 2d 3e 70  eld(p->pCache->p
2e90: 47 72 6f 75 70 2d 3e 6d 75 74 65 78 29 20 29 3b  Group->mutex) );
2ea0: 0a 20 20 20 20 70 63 61 63 68 65 31 46 72 65 65  .    pcache1Free
2eb0: 28 70 2d 3e 70 61 67 65 2e 70 42 75 66 29 3b 0a  (p->page.pBuf);.
2ec0: 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 50 43  #ifdef SQLITE_PC
2ed0: 41 43 48 45 5f 53 45 50 41 52 41 54 45 5f 48 45  ACHE_SEPARATE_HE
2ee0: 41 44 45 52 0a 20 20 20 20 73 71 6c 69 74 65 33  ADER.    sqlite3
2ef0: 5f 66 72 65 65 28 70 29 3b 0a 23 65 6e 64 69 66  _free(p);.#endif
2f00: 0a 20 20 20 20 69 66 28 20 70 43 61 63 68 65 2d  .    if( pCache-
2f10: 3e 62 50 75 72 67 65 61 62 6c 65 20 29 7b 0a 20  >bPurgeable ){. 
2f20: 20 20 20 20 20 70 43 61 63 68 65 2d 3e 70 47 72       pCache->pGr
2f30: 6f 75 70 2d 3e 6e 43 75 72 72 65 6e 74 50 61 67  oup->nCurrentPag
2f40: 65 2d 2d 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d  e--;.    }.  }.}
2f50: 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6c 6c 6f 63 20 66  ../*.** Malloc f
2f60: 75 6e 63 74 69 6f 6e 20 75 73 65 64 20 62 79 20  unction used by 
2f70: 53 51 4c 69 74 65 20 74 6f 20 6f 62 74 61 69 6e  SQLite to obtain
2f80: 20 73 70 61 63 65 20 66 72 6f 6d 20 74 68 65 20   space from the 
2f90: 62 75 66 66 65 72 20 63 6f 6e 66 69 67 75 72 65  buffer configure
2fa0: 64 0a 2a 2a 20 75 73 69 6e 67 20 73 71 6c 69 74  d.** using sqlit
2fb0: 65 33 5f 63 6f 6e 66 69 67 28 53 51 4c 49 54 45  e3_config(SQLITE
2fc0: 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48  _CONFIG_PAGECACH
2fd0: 45 29 20 6f 70 74 69 6f 6e 2e 20 49 66 20 6e 6f  E) option. If no
2fe0: 20 73 75 63 68 20 62 75 66 66 65 72 0a 2a 2a 20   such buffer.** 
2ff0: 65 78 69 73 74 73 2c 20 74 68 69 73 20 66 75 6e  exists, this fun
3000: 63 74 69 6f 6e 20 66 61 6c 6c 73 20 62 61 63 6b  ction falls back
3010: 20 74 6f 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f   to sqlite3Mallo
3020: 63 28 29 2e 0a 2a 2f 0a 76 6f 69 64 20 2a 73 71  c()..*/.void *sq
3030: 6c 69 74 65 33 50 61 67 65 4d 61 6c 6c 6f 63 28  lite3PageMalloc(
3040: 69 6e 74 20 73 7a 29 7b 0a 20 20 72 65 74 75 72  int sz){.  retur
3050: 6e 20 70 63 61 63 68 65 31 41 6c 6c 6f 63 28 73  n pcache1Alloc(s
3060: 7a 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65  z);.}../*.** Fre
3070: 65 20 61 6e 20 61 6c 6c 6f 63 61 74 65 64 20 62  e an allocated b
3080: 75 66 66 65 72 20 6f 62 74 61 69 6e 65 64 20 66  uffer obtained f
3090: 72 6f 6d 20 73 71 6c 69 74 65 33 50 61 67 65 4d  rom sqlite3PageM
30a0: 61 6c 6c 6f 63 28 29 2e 0a 2a 2f 0a 76 6f 69 64  alloc()..*/.void
30b0: 20 73 71 6c 69 74 65 33 50 61 67 65 46 72 65 65   sqlite3PageFree
30c0: 28 76 6f 69 64 20 2a 70 29 7b 0a 20 20 70 63 61  (void *p){.  pca
30d0: 63 68 65 31 46 72 65 65 28 70 29 3b 0a 7d 0a 0a  che1Free(p);.}..
30e0: 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 72  ./*.** Return tr
30f0: 75 65 20 69 66 20 69 74 20 64 65 73 69 72 61 62  ue if it desirab
3100: 6c 65 20 74 6f 20 61 76 6f 69 64 20 61 6c 6c 6f  le to avoid allo
3110: 63 61 74 69 6e 67 20 61 20 6e 65 77 20 70 61 67  cating a new pag
3120: 65 20 63 61 63 68 65 0a 2a 2a 20 65 6e 74 72 79  e cache.** entry
3130: 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 6d 65 6d 6f 72  ..**.** If memor
3140: 79 20 77 61 73 20 61 6c 6c 6f 63 61 74 65 64 20  y was allocated 
3150: 73 70 65 63 69 66 69 63 61 6c 6c 79 20 74 6f 20  specifically to 
3160: 74 68 65 20 70 61 67 65 20 63 61 63 68 65 20 75  the page cache u
3170: 73 69 6e 67 0a 2a 2a 20 53 51 4c 49 54 45 5f 43  sing.** SQLITE_C
3180: 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48 45 20  ONFIG_PAGECACHE 
3190: 62 75 74 20 74 68 61 74 20 6d 65 6d 6f 72 79 20  but that memory 
31a0: 68 61 73 20 61 6c 6c 20 62 65 65 6e 20 75 73 65  has all been use
31b0: 64 2c 20 74 68 65 6e 0a 2a 2a 20 69 74 20 69 73  d, then.** it is
31c0: 20 64 65 73 69 72 61 62 6c 65 20 74 6f 20 61 76   desirable to av
31d0: 6f 69 64 20 61 6c 6c 6f 63 61 74 69 6e 67 20 61  oid allocating a
31e0: 20 6e 65 77 20 70 61 67 65 20 63 61 63 68 65 20   new page cache 
31f0: 65 6e 74 72 79 20 62 65 63 61 75 73 65 0a 2a 2a  entry because.**
3200: 20 70 72 65 73 75 6d 61 62 6c 79 20 53 51 4c 49   presumably SQLI
3210: 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41  TE_CONFIG_PAGECA
3220: 43 48 45 20 77 61 73 20 73 75 70 70 6f 73 65 20  CHE was suppose 
3230: 74 6f 20 62 65 20 73 75 66 66 69 63 69 65 6e 74  to be sufficient
3240: 0a 2a 2a 20 66 6f 72 20 61 6c 6c 20 70 61 67 65  .** for all page
3250: 20 63 61 63 68 65 20 6e 65 65 64 73 20 61 6e 64   cache needs and
3260: 20 77 65 20 73 68 6f 75 6c 64 20 6e 6f 74 20 6e   we should not n
3270: 65 65 64 20 74 6f 20 73 70 69 6c 6c 20 74 68 65  eed to spill the
3280: 0a 2a 2a 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 6f  .** allocation o
3290: 6e 74 6f 20 74 68 65 20 68 65 61 70 2e 0a 2a 2a  nto the heap..**
32a0: 0a 2a 2a 20 4f 72 2c 20 74 68 65 20 68 65 61 70  .** Or, the heap
32b0: 20 69 73 20 75 73 65 64 20 66 6f 72 20 61 6c 6c   is used for all
32c0: 20 70 61 67 65 20 63 61 63 68 65 20 6d 65 6d 6f   page cache memo
32d0: 72 79 20 62 75 74 20 74 68 65 20 68 65 61 70 20  ry but the heap 
32e0: 69 73 0a 2a 2a 20 75 6e 64 65 72 20 6d 65 6d 6f  is.** under memo
32f0: 72 79 20 70 72 65 73 73 75 72 65 2c 20 74 68 65  ry pressure, the
3300: 6e 20 61 67 61 69 6e 20 69 74 20 69 73 20 64 65  n again it is de
3310: 73 69 72 61 62 6c 65 20 74 6f 20 61 76 6f 69 64  sirable to avoid
3320: 0a 2a 2a 20 61 6c 6c 6f 63 61 74 69 6e 67 20 61  .** allocating a
3330: 20 6e 65 77 20 70 61 67 65 20 63 61 63 68 65 20   new page cache 
3340: 65 6e 74 72 79 20 69 6e 20 6f 72 64 65 72 20 74  entry in order t
3350: 6f 20 61 76 6f 69 64 20 73 74 72 65 73 73 69 6e  o avoid stressin
3360: 67 0a 2a 2a 20 74 68 65 20 68 65 61 70 20 65 76  g.** the heap ev
3370: 65 6e 20 66 75 72 74 68 65 72 2e 0a 2a 2f 0a 73  en further..*/.s
3380: 74 61 74 69 63 20 69 6e 74 20 70 63 61 63 68 65  tatic int pcache
3390: 31 55 6e 64 65 72 4d 65 6d 6f 72 79 50 72 65 73  1UnderMemoryPres
33a0: 73 75 72 65 28 50 43 61 63 68 65 31 20 2a 70 43  sure(PCache1 *pC
33b0: 61 63 68 65 29 7b 0a 20 20 69 66 28 20 70 63 61  ache){.  if( pca
33c0: 63 68 65 31 2e 6e 53 6c 6f 74 20 26 26 20 28 70  che1.nSlot && (p
33d0: 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 2b 70 43  Cache->szPage+pC
33e0: 61 63 68 65 2d 3e 73 7a 45 78 74 72 61 29 3c 3d  ache->szExtra)<=
33f0: 70 63 61 63 68 65 31 2e 73 7a 53 6c 6f 74 20 29  pcache1.szSlot )
3400: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 70 63 61  {.    return pca
3410: 63 68 65 31 2e 62 55 6e 64 65 72 50 72 65 73 73  che1.bUnderPress
3420: 75 72 65 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  ure;.  }else{.  
3430: 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33    return sqlite3
3440: 48 65 61 70 4e 65 61 72 6c 79 46 75 6c 6c 28 29  HeapNearlyFull()
3450: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a  ;.  }.}../******
3460: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3470: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3480: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3490: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
34a0: 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 2a 2a 2a 2a  ********/./*****
34b0: 2a 2a 2a 20 47 65 6e 65 72 61 6c 20 49 6d 70 6c  *** General Impl
34c0: 65 6d 65 6e 74 61 74 69 6f 6e 20 46 75 6e 63 74  ementation Funct
34d0: 69 6f 6e 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ions ***********
34e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
34f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f 2a 0a 2a  *********/../*.*
3500: 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  * This function 
3510: 69 73 20 75 73 65 64 20 74 6f 20 72 65 73 69 7a  is used to resiz
3520: 65 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65  e the hash table
3530: 20 75 73 65 64 20 62 79 20 74 68 65 20 63 61 63   used by the cac
3540: 68 65 20 70 61 73 73 65 64 0a 2a 2a 20 61 73 20  he passed.** as 
3550: 74 68 65 20 66 69 72 73 74 20 61 72 67 75 6d 65  the first argume
3560: 6e 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 50 43  nt..**.** The PC
3570: 61 63 68 65 20 6d 75 74 65 78 20 6d 75 73 74 20  ache mutex must 
3580: 62 65 20 68 65 6c 64 20 77 68 65 6e 20 74 68 69  be held when thi
3590: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61  s function is ca
35a0: 6c 6c 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  lled..*/.static 
35b0: 69 6e 74 20 70 63 61 63 68 65 31 52 65 73 69 7a  int pcache1Resiz
35c0: 65 48 61 73 68 28 50 43 61 63 68 65 31 20 2a 70  eHash(PCache1 *p
35d0: 29 7b 0a 20 20 50 67 48 64 72 31 20 2a 2a 61 70  ){.  PgHdr1 **ap
35e0: 4e 65 77 3b 0a 20 20 75 6e 73 69 67 6e 65 64 20  New;.  unsigned 
35f0: 69 6e 74 20 6e 4e 65 77 3b 0a 20 20 75 6e 73 69  int nNew;.  unsi
3600: 67 6e 65 64 20 69 6e 74 20 69 3b 0a 0a 20 20 61  gned int i;..  a
3610: 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d  ssert( sqlite3_m
3620: 75 74 65 78 5f 68 65 6c 64 28 70 2d 3e 70 47 72  utex_held(p->pGr
3630: 6f 75 70 2d 3e 6d 75 74 65 78 29 20 29 3b 0a 0a  oup->mutex) );..
3640: 20 20 6e 4e 65 77 20 3d 20 70 2d 3e 6e 48 61 73    nNew = p->nHas
3650: 68 2a 32 3b 0a 20 20 69 66 28 20 6e 4e 65 77 3c  h*2;.  if( nNew<
3660: 32 35 36 20 29 7b 0a 20 20 20 20 6e 4e 65 77 20  256 ){.    nNew 
3670: 3d 20 32 35 36 3b 0a 20 20 7d 0a 0a 20 20 70 63  = 256;.  }..  pc
3680: 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28  ache1LeaveMutex(
3690: 70 2d 3e 70 47 72 6f 75 70 29 3b 0a 20 20 69 66  p->pGroup);.  if
36a0: 28 20 70 2d 3e 6e 48 61 73 68 20 29 7b 20 73 71  ( p->nHash ){ sq
36b0: 6c 69 74 65 33 42 65 67 69 6e 42 65 6e 69 67 6e  lite3BeginBenign
36c0: 4d 61 6c 6c 6f 63 28 29 3b 20 7d 0a 20 20 61 70  Malloc(); }.  ap
36d0: 4e 65 77 20 3d 20 28 50 67 48 64 72 31 20 2a 2a  New = (PgHdr1 **
36e0: 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65  )sqlite3MallocZe
36f0: 72 6f 28 73 69 7a 65 6f 66 28 50 67 48 64 72 31  ro(sizeof(PgHdr1
3700: 20 2a 29 2a 6e 4e 65 77 29 3b 0a 20 20 69 66 28   *)*nNew);.  if(
3710: 20 70 2d 3e 6e 48 61 73 68 20 29 7b 20 73 71 6c   p->nHash ){ sql
3720: 69 74 65 33 45 6e 64 42 65 6e 69 67 6e 4d 61 6c  ite3EndBenignMal
3730: 6c 6f 63 28 29 3b 20 7d 0a 20 20 70 63 61 63 68  loc(); }.  pcach
3740: 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70 2d 3e  e1EnterMutex(p->
3750: 70 47 72 6f 75 70 29 3b 0a 20 20 69 66 28 20 61  pGroup);.  if( a
3760: 70 4e 65 77 20 29 7b 0a 20 20 20 20 66 6f 72 28  pNew ){.    for(
3770: 69 3d 30 3b 20 69 3c 70 2d 3e 6e 48 61 73 68 3b  i=0; i<p->nHash;
3780: 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 50 67 48   i++){.      PgH
3790: 64 72 31 20 2a 70 50 61 67 65 3b 0a 20 20 20 20  dr1 *pPage;.    
37a0: 20 20 50 67 48 64 72 31 20 2a 70 4e 65 78 74 20    PgHdr1 *pNext 
37b0: 3d 20 70 2d 3e 61 70 48 61 73 68 5b 69 5d 3b 0a  = p->apHash[i];.
37c0: 20 20 20 20 20 20 77 68 69 6c 65 28 20 28 70 50        while( (pP
37d0: 61 67 65 20 3d 20 70 4e 65 78 74 29 21 3d 30 20  age = pNext)!=0 
37e0: 29 7b 0a 20 20 20 20 20 20 20 20 75 6e 73 69 67  ){.        unsig
37f0: 6e 65 64 20 69 6e 74 20 68 20 3d 20 70 50 61 67  ned int h = pPag
3800: 65 2d 3e 69 4b 65 79 20 25 20 6e 4e 65 77 3b 0a  e->iKey % nNew;.
3810: 20 20 20 20 20 20 20 20 70 4e 65 78 74 20 3d 20          pNext = 
3820: 70 50 61 67 65 2d 3e 70 4e 65 78 74 3b 0a 20 20  pPage->pNext;.  
3830: 20 20 20 20 20 20 70 50 61 67 65 2d 3e 70 4e 65        pPage->pNe
3840: 78 74 20 3d 20 61 70 4e 65 77 5b 68 5d 3b 0a 20  xt = apNew[h];. 
3850: 20 20 20 20 20 20 20 61 70 4e 65 77 5b 68 5d 20         apNew[h] 
3860: 3d 20 70 50 61 67 65 3b 0a 20 20 20 20 20 20 7d  = pPage;.      }
3870: 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 6c 69 74  .    }.    sqlit
3880: 65 33 5f 66 72 65 65 28 70 2d 3e 61 70 48 61 73  e3_free(p->apHas
3890: 68 29 3b 0a 20 20 20 20 70 2d 3e 61 70 48 61 73  h);.    p->apHas
38a0: 68 20 3d 20 61 70 4e 65 77 3b 0a 20 20 20 20 70  h = apNew;.    p
38b0: 2d 3e 6e 48 61 73 68 20 3d 20 6e 4e 65 77 3b 0a  ->nHash = nNew;.
38c0: 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 28 70    }..  return (p
38d0: 2d 3e 61 70 48 61 73 68 20 3f 20 53 51 4c 49 54  ->apHash ? SQLIT
38e0: 45 5f 4f 4b 20 3a 20 53 51 4c 49 54 45 5f 4e 4f  E_OK : SQLITE_NO
38f0: 4d 45 4d 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  MEM);.}../*.** T
3900: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
3910: 75 73 65 64 20 69 6e 74 65 72 6e 61 6c 6c 79 20  used internally 
3920: 74 6f 20 72 65 6d 6f 76 65 20 74 68 65 20 70 61  to remove the pa
3930: 67 65 20 70 50 61 67 65 20 66 72 6f 6d 20 74 68  ge pPage from th
3940: 65 20 0a 2a 2a 20 50 47 72 6f 75 70 20 4c 52 55  e .** PGroup LRU
3950: 20 6c 69 73 74 2c 20 69 66 20 69 73 20 70 61 72   list, if is par
3960: 74 20 6f 66 20 69 74 2e 20 49 66 20 70 50 61 67  t of it. If pPag
3970: 65 20 69 73 20 6e 6f 74 20 70 61 72 74 20 6f 66  e is not part of
3980: 20 74 68 65 20 50 47 72 6f 75 70 0a 2a 2a 20 4c   the PGroup.** L
3990: 52 55 20 6c 69 73 74 2c 20 74 68 65 6e 20 74 68  RU list, then th
39a0: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 61  is function is a
39b0: 20 6e 6f 2d 6f 70 2e 0a 2a 2a 0a 2a 2a 20 54 68   no-op..**.** Th
39c0: 65 20 50 47 72 6f 75 70 20 6d 75 74 65 78 20 6d  e PGroup mutex m
39d0: 75 73 74 20 62 65 20 68 65 6c 64 20 77 68 65 6e  ust be held when
39e0: 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   this function i
39f0: 73 20 63 61 6c 6c 65 64 2e 0a 2a 2a 0a 2a 2a 20  s called..**.** 
3a00: 49 66 20 70 50 61 67 65 20 69 73 20 4e 55 4c 4c  If pPage is NULL
3a10: 20 74 68 65 6e 20 74 68 69 73 20 72 6f 75 74 69   then this routi
3a20: 6e 65 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a 2a  ne is a no-op..*
3a30: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63  /.static void pc
3a40: 61 63 68 65 31 50 69 6e 50 61 67 65 28 50 67 48  ache1PinPage(PgH
3a50: 64 72 31 20 2a 70 50 61 67 65 29 7b 0a 20 20 50  dr1 *pPage){.  P
3a60: 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 3b 0a  Cache1 *pCache;.
3a70: 20 20 50 47 72 6f 75 70 20 2a 70 47 72 6f 75 70    PGroup *pGroup
3a80: 3b 0a 0a 20 20 69 66 28 20 70 50 61 67 65 3d 3d  ;..  if( pPage==
3a90: 30 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 70 43  0 ) return;.  pC
3aa0: 61 63 68 65 20 3d 20 70 50 61 67 65 2d 3e 70 43  ache = pPage->pC
3ab0: 61 63 68 65 3b 0a 20 20 70 47 72 6f 75 70 20 3d  ache;.  pGroup =
3ac0: 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b   pCache->pGroup;
3ad0: 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74  .  assert( sqlit
3ae0: 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 47  e3_mutex_held(pG
3af0: 72 6f 75 70 2d 3e 6d 75 74 65 78 29 20 29 3b 0a  roup->mutex) );.
3b00: 20 20 69 66 28 20 70 50 61 67 65 2d 3e 70 4c 72    if( pPage->pLr
3b10: 75 4e 65 78 74 20 7c 7c 20 70 50 61 67 65 3d 3d  uNext || pPage==
3b20: 70 47 72 6f 75 70 2d 3e 70 4c 72 75 54 61 69 6c  pGroup->pLruTail
3b30: 20 29 7b 0a 20 20 20 20 69 66 28 20 70 50 61 67   ){.    if( pPag
3b40: 65 2d 3e 70 4c 72 75 50 72 65 76 20 29 7b 0a 20  e->pLruPrev ){. 
3b50: 20 20 20 20 20 70 50 61 67 65 2d 3e 70 4c 72 75       pPage->pLru
3b60: 50 72 65 76 2d 3e 70 4c 72 75 4e 65 78 74 20 3d  Prev->pLruNext =
3b70: 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74   pPage->pLruNext
3b80: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20  ;.    }.    if( 
3b90: 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 20  pPage->pLruNext 
3ba0: 29 7b 0a 20 20 20 20 20 20 70 50 61 67 65 2d 3e  ){.      pPage->
3bb0: 70 4c 72 75 4e 65 78 74 2d 3e 70 4c 72 75 50 72  pLruNext->pLruPr
3bc0: 65 76 20 3d 20 70 50 61 67 65 2d 3e 70 4c 72 75  ev = pPage->pLru
3bd0: 50 72 65 76 3b 0a 20 20 20 20 7d 0a 20 20 20 20  Prev;.    }.    
3be0: 69 66 28 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75  if( pGroup->pLru
3bf0: 48 65 61 64 3d 3d 70 50 61 67 65 20 29 7b 0a 20  Head==pPage ){. 
3c00: 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 70 4c 72       pGroup->pLr
3c10: 75 48 65 61 64 20 3d 20 70 50 61 67 65 2d 3e 70  uHead = pPage->p
3c20: 4c 72 75 4e 65 78 74 3b 0a 20 20 20 20 7d 0a 20  LruNext;.    }. 
3c30: 20 20 20 69 66 28 20 70 47 72 6f 75 70 2d 3e 70     if( pGroup->p
3c40: 4c 72 75 54 61 69 6c 3d 3d 70 50 61 67 65 20 29  LruTail==pPage )
3c50: 7b 0a 20 20 20 20 20 20 70 47 72 6f 75 70 2d 3e  {.      pGroup->
3c60: 70 4c 72 75 54 61 69 6c 20 3d 20 70 50 61 67 65  pLruTail = pPage
3c70: 2d 3e 70 4c 72 75 50 72 65 76 3b 0a 20 20 20 20  ->pLruPrev;.    
3c80: 7d 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 4c 72  }.    pPage->pLr
3c90: 75 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20 20 70  uNext = 0;.    p
3ca0: 50 61 67 65 2d 3e 70 4c 72 75 50 72 65 76 20 3d  Page->pLruPrev =
3cb0: 20 30 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 70   0;.    pPage->p
3cc0: 43 61 63 68 65 2d 3e 6e 52 65 63 79 63 6c 61 62  Cache->nRecyclab
3cd0: 6c 65 2d 2d 3b 0a 20 20 7d 0a 7d 0a 0a 0a 2f 2a  le--;.  }.}.../*
3ce0: 0a 2a 2a 20 52 65 6d 6f 76 65 20 74 68 65 20 70  .** Remove the p
3cf0: 61 67 65 20 73 75 70 70 6c 69 65 64 20 61 73 20  age supplied as 
3d00: 61 6e 20 61 72 67 75 6d 65 6e 74 20 66 72 6f 6d  an argument from
3d10: 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 20   the hash table 
3d20: 0a 2a 2a 20 28 50 43 61 63 68 65 31 2e 61 70 48  .** (PCache1.apH
3d30: 61 73 68 20 73 74 72 75 63 74 75 72 65 29 20 74  ash structure) t
3d40: 68 61 74 20 69 74 20 69 73 20 63 75 72 72 65 6e  hat it is curren
3d50: 74 6c 79 20 73 74 6f 72 65 64 20 69 6e 2e 0a 2a  tly stored in..*
3d60: 2a 0a 2a 2a 20 54 68 65 20 50 47 72 6f 75 70 20  *.** The PGroup 
3d70: 6d 75 74 65 78 20 6d 75 73 74 20 62 65 20 68 65  mutex must be he
3d80: 6c 64 20 77 68 65 6e 20 74 68 69 73 20 66 75 6e  ld when this fun
3d90: 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 2e  ction is called.
3da0: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
3db0: 70 63 61 63 68 65 31 52 65 6d 6f 76 65 46 72 6f  pcache1RemoveFro
3dc0: 6d 48 61 73 68 28 50 67 48 64 72 31 20 2a 70 50  mHash(PgHdr1 *pP
3dd0: 61 67 65 29 7b 0a 20 20 75 6e 73 69 67 6e 65 64  age){.  unsigned
3de0: 20 69 6e 74 20 68 3b 0a 20 20 50 43 61 63 68 65   int h;.  PCache
3df0: 31 20 2a 70 43 61 63 68 65 20 3d 20 70 50 61 67  1 *pCache = pPag
3e00: 65 2d 3e 70 43 61 63 68 65 3b 0a 20 20 50 67 48  e->pCache;.  PgH
3e10: 64 72 31 20 2a 2a 70 70 3b 0a 0a 20 20 61 73 73  dr1 **pp;..  ass
3e20: 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74  ert( sqlite3_mut
3e30: 65 78 5f 68 65 6c 64 28 70 43 61 63 68 65 2d 3e  ex_held(pCache->
3e40: 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78 29 20 29  pGroup->mutex) )
3e50: 3b 0a 20 20 68 20 3d 20 70 50 61 67 65 2d 3e 69  ;.  h = pPage->i
3e60: 4b 65 79 20 25 20 70 43 61 63 68 65 2d 3e 6e 48  Key % pCache->nH
3e70: 61 73 68 3b 0a 20 20 66 6f 72 28 70 70 3d 26 70  ash;.  for(pp=&p
3e80: 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d  Cache->apHash[h]
3e90: 3b 20 28 2a 70 70 29 21 3d 70 50 61 67 65 3b 20  ; (*pp)!=pPage; 
3ea0: 70 70 3d 26 28 2a 70 70 29 2d 3e 70 4e 65 78 74  pp=&(*pp)->pNext
3eb0: 29 3b 0a 20 20 2a 70 70 20 3d 20 28 2a 70 70 29  );.  *pp = (*pp)
3ec0: 2d 3e 70 4e 65 78 74 3b 0a 0a 20 20 70 43 61 63  ->pNext;..  pCac
3ed0: 68 65 2d 3e 6e 50 61 67 65 2d 2d 3b 0a 7d 0a 0a  he->nPage--;.}..
3ee0: 2f 2a 0a 2a 2a 20 49 66 20 74 68 65 72 65 20 61  /*.** If there a
3ef0: 72 65 20 63 75 72 72 65 6e 74 6c 79 20 6d 6f 72  re currently mor
3f00: 65 20 74 68 61 6e 20 6e 4d 61 78 50 61 67 65 20  e than nMaxPage 
3f10: 70 61 67 65 73 20 61 6c 6c 6f 63 61 74 65 64 2c  pages allocated,
3f20: 20 74 72 79 0a 2a 2a 20 74 6f 20 72 65 63 79 63   try.** to recyc
3f30: 6c 65 20 70 61 67 65 73 20 74 6f 20 72 65 64 75  le pages to redu
3f40: 63 65 20 74 68 65 20 6e 75 6d 62 65 72 20 61 6c  ce the number al
3f50: 6c 6f 63 61 74 65 64 20 74 6f 20 6e 4d 61 78 50  located to nMaxP
3f60: 61 67 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  age..*/.static v
3f70: 6f 69 64 20 70 63 61 63 68 65 31 45 6e 66 6f 72  oid pcache1Enfor
3f80: 63 65 4d 61 78 50 61 67 65 28 50 47 72 6f 75 70  ceMaxPage(PGroup
3f90: 20 2a 70 47 72 6f 75 70 29 7b 0a 20 20 61 73 73   *pGroup){.  ass
3fa0: 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74  ert( sqlite3_mut
3fb0: 65 78 5f 68 65 6c 64 28 70 47 72 6f 75 70 2d 3e  ex_held(pGroup->
3fc0: 6d 75 74 65 78 29 20 29 3b 0a 20 20 77 68 69 6c  mutex) );.  whil
3fd0: 65 28 20 70 47 72 6f 75 70 2d 3e 6e 43 75 72 72  e( pGroup->nCurr
3fe0: 65 6e 74 50 61 67 65 3e 70 47 72 6f 75 70 2d 3e  entPage>pGroup->
3ff0: 6e 4d 61 78 50 61 67 65 20 26 26 20 70 47 72 6f  nMaxPage && pGro
4000: 75 70 2d 3e 70 4c 72 75 54 61 69 6c 20 29 7b 0a  up->pLruTail ){.
4010: 20 20 20 20 50 67 48 64 72 31 20 2a 70 20 3d 20      PgHdr1 *p = 
4020: 70 47 72 6f 75 70 2d 3e 70 4c 72 75 54 61 69 6c  pGroup->pLruTail
4030: 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 2d  ;.    assert( p-
4040: 3e 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3d  >pCache->pGroup=
4050: 3d 70 47 72 6f 75 70 20 29 3b 0a 20 20 20 20 70  =pGroup );.    p
4060: 63 61 63 68 65 31 50 69 6e 50 61 67 65 28 70 29  cache1PinPage(p)
4070: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 52 65 6d  ;.    pcache1Rem
4080: 6f 76 65 46 72 6f 6d 48 61 73 68 28 70 29 3b 0a  oveFromHash(p);.
4090: 20 20 20 20 70 63 61 63 68 65 31 46 72 65 65 50      pcache1FreeP
40a0: 61 67 65 28 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f  age(p);.  }.}../
40b0: 2a 0a 2a 2a 20 44 69 73 63 61 72 64 20 61 6c 6c  *.** Discard all
40c0: 20 70 61 67 65 73 20 66 72 6f 6d 20 63 61 63 68   pages from cach
40d0: 65 20 70 43 61 63 68 65 20 77 69 74 68 20 61 20  e pCache with a 
40e0: 70 61 67 65 20 6e 75 6d 62 65 72 20 28 6b 65 79  page number (key
40f0: 20 76 61 6c 75 65 29 20 0a 2a 2a 20 67 72 65 61   value) .** grea
4100: 74 65 72 20 74 68 61 6e 20 6f 72 20 65 71 75 61  ter than or equa
4110: 6c 20 74 6f 20 69 4c 69 6d 69 74 2e 20 41 6e 79  l to iLimit. Any
4120: 20 70 69 6e 6e 65 64 20 70 61 67 65 73 20 74 68   pinned pages th
4130: 61 74 20 6d 65 65 74 20 74 68 69 73 20 0a 2a 2a  at meet this .**
4140: 20 63 72 69 74 65 72 69 61 20 61 72 65 20 75 6e   criteria are un
4150: 70 69 6e 6e 65 64 20 62 65 66 6f 72 65 20 74 68  pinned before th
4160: 65 79 20 61 72 65 20 64 69 73 63 61 72 64 65 64  ey are discarded
4170: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 50 43 61 63  ..**.** The PCac
4180: 68 65 20 6d 75 74 65 78 20 6d 75 73 74 20 62 65  he mutex must be
4190: 20 68 65 6c 64 20 77 68 65 6e 20 74 68 69 73 20   held when this 
41a0: 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c  function is call
41b0: 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ed..*/.static vo
41c0: 69 64 20 70 63 61 63 68 65 31 54 72 75 6e 63 61  id pcache1Trunca
41d0: 74 65 55 6e 73 61 66 65 28 0a 20 20 50 43 61 63  teUnsafe(.  PCac
41e0: 68 65 31 20 2a 70 43 61 63 68 65 2c 20 20 20 20  he1 *pCache,    
41f0: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20           /* The 
4200: 63 61 63 68 65 20 74 6f 20 74 72 75 6e 63 61 74  cache to truncat
4210: 65 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20  e */.  unsigned 
4220: 69 6e 74 20 69 4c 69 6d 69 74 20 20 20 20 20 20  int iLimit      
4230: 20 20 20 20 2f 2a 20 44 72 6f 70 20 70 61 67 65      /* Drop page
4240: 73 20 77 69 74 68 20 74 68 69 73 20 70 67 6e 6f  s with this pgno
4250: 20 6f 72 20 6c 61 72 67 65 72 20 2a 2f 0a 29 7b   or larger */.){
4260: 0a 20 20 54 45 53 54 4f 4e 4c 59 28 20 75 6e 73  .  TESTONLY( uns
4270: 69 67 6e 65 64 20 69 6e 74 20 6e 50 61 67 65 20  igned int nPage 
4280: 3d 20 30 3b 20 29 20 20 2f 2a 20 54 6f 20 61 73  = 0; )  /* To as
4290: 73 65 72 74 20 70 43 61 63 68 65 2d 3e 6e 50 61  sert pCache->nPa
42a0: 67 65 20 69 73 20 63 6f 72 72 65 63 74 20 2a 2f  ge is correct */
42b0: 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  .  unsigned int 
42c0: 68 3b 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c  h;.  assert( sql
42d0: 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28  ite3_mutex_held(
42e0: 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 2d 3e  pCache->pGroup->
42f0: 6d 75 74 65 78 29 20 29 3b 0a 20 20 66 6f 72 28  mutex) );.  for(
4300: 68 3d 30 3b 20 68 3c 70 43 61 63 68 65 2d 3e 6e  h=0; h<pCache->n
4310: 48 61 73 68 3b 20 68 2b 2b 29 7b 0a 20 20 20 20  Hash; h++){.    
4320: 50 67 48 64 72 31 20 2a 2a 70 70 20 3d 20 26 70  PgHdr1 **pp = &p
4330: 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d  Cache->apHash[h]
4340: 3b 20 0a 20 20 20 20 50 67 48 64 72 31 20 2a 70  ; .    PgHdr1 *p
4350: 50 61 67 65 3b 0a 20 20 20 20 77 68 69 6c 65 28  Page;.    while(
4360: 20 28 70 50 61 67 65 20 3d 20 2a 70 70 29 21 3d   (pPage = *pp)!=
4370: 30 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 70  0 ){.      if( p
4380: 50 61 67 65 2d 3e 69 4b 65 79 3e 3d 69 4c 69 6d  Page->iKey>=iLim
4390: 69 74 20 29 7b 0a 20 20 20 20 20 20 20 20 70 43  it ){.        pC
43a0: 61 63 68 65 2d 3e 6e 50 61 67 65 2d 2d 3b 0a 20  ache->nPage--;. 
43b0: 20 20 20 20 20 20 20 2a 70 70 20 3d 20 70 50 61         *pp = pPa
43c0: 67 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20  ge->pNext;.     
43d0: 20 20 20 70 63 61 63 68 65 31 50 69 6e 50 61 67     pcache1PinPag
43e0: 65 28 70 50 61 67 65 29 3b 0a 20 20 20 20 20 20  e(pPage);.      
43f0: 20 20 70 63 61 63 68 65 31 46 72 65 65 50 61 67    pcache1FreePag
4400: 65 28 70 50 61 67 65 29 3b 0a 20 20 20 20 20 20  e(pPage);.      
4410: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 70  }else{.        p
4420: 70 20 3d 20 26 70 50 61 67 65 2d 3e 70 4e 65 78  p = &pPage->pNex
4430: 74 3b 0a 20 20 20 20 20 20 20 20 54 45 53 54 4f  t;.        TESTO
4440: 4e 4c 59 28 20 6e 50 61 67 65 2b 2b 3b 20 29 0a  NLY( nPage++; ).
4450: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
4460: 7d 0a 20 20 61 73 73 65 72 74 28 20 70 43 61 63  }.  assert( pCac
4470: 68 65 2d 3e 6e 50 61 67 65 3d 3d 6e 50 61 67 65  he->nPage==nPage
4480: 20 29 3b 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a   );.}../********
4490: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
44a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
44b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
44c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
44d0: 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 2a 2a 2a 2a 2a 2a  ******/./*******
44e0: 2a 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  * sqlite3_pcache
44f0: 20 4d 65 74 68 6f 64 73 20 2a 2a 2a 2a 2a 2a 2a   Methods *******
4500: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4510: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4520: 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f 2a 0a 2a 2a 20  *******/../*.** 
4530: 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  Implementation o
4540: 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63  f the sqlite3_pc
4550: 61 63 68 65 2e 78 49 6e 69 74 20 6d 65 74 68 6f  ache.xInit metho
4560: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d..*/.static int
4570: 20 70 63 61 63 68 65 31 49 6e 69 74 28 76 6f 69   pcache1Init(voi
4580: 64 20 2a 4e 6f 74 55 73 65 64 29 7b 0a 20 20 55  d *NotUsed){.  U
4590: 4e 55 53 45 44 5f 50 41 52 41 4d 45 54 45 52 28  NUSED_PARAMETER(
45a0: 4e 6f 74 55 73 65 64 29 3b 0a 20 20 61 73 73 65  NotUsed);.  asse
45b0: 72 74 28 20 70 63 61 63 68 65 31 2e 69 73 49 6e  rt( pcache1.isIn
45c0: 69 74 3d 3d 30 20 29 3b 0a 20 20 6d 65 6d 73 65  it==0 );.  memse
45d0: 74 28 26 70 63 61 63 68 65 31 2c 20 30 2c 20 73  t(&pcache1, 0, s
45e0: 69 7a 65 6f 66 28 70 63 61 63 68 65 31 29 29 3b  izeof(pcache1));
45f0: 0a 20 20 69 66 28 20 73 71 6c 69 74 65 33 47 6c  .  if( sqlite3Gl
4600: 6f 62 61 6c 43 6f 6e 66 69 67 2e 62 43 6f 72 65  obalConfig.bCore
4610: 4d 75 74 65 78 20 29 7b 0a 20 20 20 20 70 63 61  Mutex ){.    pca
4620: 63 68 65 31 2e 67 72 70 2e 6d 75 74 65 78 20 3d  che1.grp.mutex =
4630: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 61   sqlite3_mutex_a
4640: 6c 6c 6f 63 28 53 51 4c 49 54 45 5f 4d 55 54 45  lloc(SQLITE_MUTE
4650: 58 5f 53 54 41 54 49 43 5f 4c 52 55 29 3b 0a 20  X_STATIC_LRU);. 
4660: 20 20 20 70 63 61 63 68 65 31 2e 6d 75 74 65 78     pcache1.mutex
4670: 20 3d 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78   = sqlite3_mutex
4680: 5f 61 6c 6c 6f 63 28 53 51 4c 49 54 45 5f 4d 55  _alloc(SQLITE_MU
4690: 54 45 58 5f 53 54 41 54 49 43 5f 50 4d 45 4d 29  TEX_STATIC_PMEM)
46a0: 3b 0a 20 20 7d 0a 20 20 70 63 61 63 68 65 31 2e  ;.  }.  pcache1.
46b0: 67 72 70 2e 6d 78 50 69 6e 6e 65 64 20 3d 20 31  grp.mxPinned = 1
46c0: 30 3b 0a 20 20 70 63 61 63 68 65 31 2e 69 73 49  0;.  pcache1.isI
46d0: 6e 69 74 20 3d 20 31 3b 0a 20 20 72 65 74 75 72  nit = 1;.  retur
46e0: 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a  n SQLITE_OK;.}..
46f0: 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61  /*.** Implementa
4700: 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69  tion of the sqli
4710: 74 65 33 5f 70 63 61 63 68 65 2e 78 53 68 75 74  te3_pcache.xShut
4720: 64 6f 77 6e 20 6d 65 74 68 6f 64 2e 0a 2a 2a 20  down method..** 
4730: 4e 6f 74 65 20 74 68 61 74 20 74 68 65 20 73 74  Note that the st
4740: 61 74 69 63 20 6d 75 74 65 78 20 61 6c 6c 6f 63  atic mutex alloc
4750: 61 74 65 64 20 69 6e 20 78 49 6e 69 74 20 64 6f  ated in xInit do
4760: 65 73 20 0a 2a 2a 20 6e 6f 74 20 6e 65 65 64 20  es .** not need 
4770: 74 6f 20 62 65 20 66 72 65 65 64 2e 0a 2a 2f 0a  to be freed..*/.
4780: 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63  static void pcac
4790: 68 65 31 53 68 75 74 64 6f 77 6e 28 76 6f 69 64  he1Shutdown(void
47a0: 20 2a 4e 6f 74 55 73 65 64 29 7b 0a 20 20 55 4e   *NotUsed){.  UN
47b0: 55 53 45 44 5f 50 41 52 41 4d 45 54 45 52 28 4e  USED_PARAMETER(N
47c0: 6f 74 55 73 65 64 29 3b 0a 20 20 61 73 73 65 72  otUsed);.  asser
47d0: 74 28 20 70 63 61 63 68 65 31 2e 69 73 49 6e 69  t( pcache1.isIni
47e0: 74 21 3d 30 20 29 3b 0a 20 20 6d 65 6d 73 65 74  t!=0 );.  memset
47f0: 28 26 70 63 61 63 68 65 31 2c 20 30 2c 20 73 69  (&pcache1, 0, si
4800: 7a 65 6f 66 28 70 63 61 63 68 65 31 29 29 3b 0a  zeof(pcache1));.
4810: 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65  }../*.** Impleme
4820: 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73  ntation of the s
4830: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78 43  qlite3_pcache.xC
4840: 72 65 61 74 65 20 6d 65 74 68 6f 64 2e 0a 2a 2a  reate method..**
4850: 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65 20 61 20 6e  .** Allocate a n
4860: 65 77 20 63 61 63 68 65 2e 0a 2a 2f 0a 73 74 61  ew cache..*/.sta
4870: 74 69 63 20 73 71 6c 69 74 65 33 5f 70 63 61 63  tic sqlite3_pcac
4880: 68 65 20 2a 70 63 61 63 68 65 31 43 72 65 61 74  he *pcache1Creat
4890: 65 28 69 6e 74 20 73 7a 50 61 67 65 2c 20 69 6e  e(int szPage, in
48a0: 74 20 73 7a 45 78 74 72 61 2c 20 69 6e 74 20 62  t szExtra, int b
48b0: 50 75 72 67 65 61 62 6c 65 29 7b 0a 20 20 50 43  Purgeable){.  PC
48c0: 61 63 68 65 31 20 2a 70 43 61 63 68 65 3b 20 20  ache1 *pCache;  
48d0: 20 20 20 20 2f 2a 20 54 68 65 20 6e 65 77 6c 79      /* The newly
48e0: 20 63 72 65 61 74 65 64 20 70 61 67 65 20 63 61   created page ca
48f0: 63 68 65 20 2a 2f 0a 20 20 50 47 72 6f 75 70 20  che */.  PGroup 
4900: 2a 70 47 72 6f 75 70 3b 20 20 20 20 20 20 20 2f  *pGroup;       /
4910: 2a 20 54 68 65 20 67 72 6f 75 70 20 74 68 65 20  * The group the 
4920: 6e 65 77 20 70 61 67 65 20 63 61 63 68 65 20 77  new page cache w
4930: 69 6c 6c 20 62 65 6c 6f 6e 67 20 74 6f 20 2a 2f  ill belong to */
4940: 0a 20 20 69 6e 74 20 73 7a 3b 20 20 20 20 20 20  .  int sz;      
4950: 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65           /* Byte
4960: 73 20 6f 66 20 6d 65 6d 6f 72 79 20 72 65 71 75  s of memory requ
4970: 69 72 65 64 20 74 6f 20 61 6c 6c 6f 63 61 74 65  ired to allocate
4980: 20 74 68 65 20 6e 65 77 20 63 61 63 68 65 20 2a   the new cache *
4990: 2f 0a 0a 20 20 2f 2a 0a 20 20 2a 2a 20 54 68 65  /..  /*.  ** The
49a0: 20 73 65 70 65 72 61 74 65 43 61 63 68 65 20 76   seperateCache v
49b0: 61 72 69 61 62 6c 65 20 69 73 20 74 72 75 65 20  ariable is true 
49c0: 69 66 20 65 61 63 68 20 50 43 61 63 68 65 20 68  if each PCache h
49d0: 61 73 20 69 74 73 20 6f 77 6e 20 70 72 69 76 61  as its own priva
49e0: 74 65 0a 20 20 2a 2a 20 50 47 72 6f 75 70 2e 20  te.  ** PGroup. 
49f0: 20 49 6e 20 6f 74 68 65 72 20 77 6f 72 64 73 2c   In other words,
4a00: 20 73 65 70 61 72 61 74 65 43 61 63 68 65 20 69   separateCache i
4a10: 73 20 74 72 75 65 20 66 6f 72 20 6d 6f 64 65 20  s true for mode 
4a20: 28 31 29 20 77 68 65 72 65 20 6e 6f 0a 20 20 2a  (1) where no.  *
4a30: 2a 20 6d 75 74 65 78 69 6e 67 20 69 73 20 72 65  * mutexing is re
4a40: 71 75 69 72 65 64 2e 0a 20 20 2a 2a 0a 20 20 2a  quired..  **.  *
4a50: 2a 20 20 20 2a 20 20 41 6c 77 61 79 73 20 75 73  *   *  Always us
4a60: 65 20 61 20 75 6e 69 66 69 65 64 20 63 61 63 68  e a unified cach
4a70: 65 20 28 6d 6f 64 65 2d 32 29 20 69 66 20 45 4e  e (mode-2) if EN
4a80: 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41  ABLE_MEMORY_MANA
4a90: 47 45 4d 45 4e 54 0a 20 20 2a 2a 0a 20 20 2a 2a  GEMENT.  **.  **
4aa0: 20 20 20 2a 20 20 41 6c 77 61 79 73 20 75 73 65     *  Always use
4ab0: 20 61 20 75 6e 69 66 69 65 64 20 63 61 63 68 65   a unified cache
4ac0: 20 69 6e 20 73 69 6e 67 6c 65 2d 74 68 72 65 61   in single-threa
4ad0: 64 65 64 20 61 70 70 6c 69 63 61 74 69 6f 6e 73  ded applications
4ae0: 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 2a 20 20  .  **.  **   *  
4af0: 4f 74 68 65 72 77 69 73 65 20 28 69 66 20 6d 75  Otherwise (if mu
4b00: 6c 74 69 2d 74 68 72 65 61 64 65 64 20 61 6e 64  lti-threaded and
4b10: 20 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d   ENABLE_MEMORY_M
4b20: 41 4e 41 47 45 4d 45 4e 54 20 69 73 20 6f 66 66  ANAGEMENT is off
4b30: 29 0a 20 20 2a 2a 20 20 20 20 20 20 75 73 65 20  ).  **      use 
4b40: 73 65 70 61 72 61 74 65 20 63 61 63 68 65 73 20  separate caches 
4b50: 28 6d 6f 64 65 2d 31 29 0a 20 20 2a 2f 0a 23 69  (mode-1).  */.#i
4b60: 66 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45  f defined(SQLITE
4b70: 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d  _ENABLE_MEMORY_M
4b80: 41 4e 41 47 45 4d 45 4e 54 29 20 7c 7c 20 53 51  ANAGEMENT) || SQ
4b90: 4c 49 54 45 5f 54 48 52 45 41 44 53 41 46 45 3d  LITE_THREADSAFE=
4ba0: 3d 30 0a 20 20 63 6f 6e 73 74 20 69 6e 74 20 73  =0.  const int s
4bb0: 65 70 61 72 61 74 65 43 61 63 68 65 20 3d 20 30  eparateCache = 0
4bc0: 3b 0a 23 65 6c 73 65 0a 20 20 69 6e 74 20 73 65  ;.#else.  int se
4bd0: 70 61 72 61 74 65 43 61 63 68 65 20 3d 20 73 71  parateCache = sq
4be0: 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69  lite3GlobalConfi
4bf0: 67 2e 62 43 6f 72 65 4d 75 74 65 78 3e 30 3b 0a  g.bCoreMutex>0;.
4c00: 23 65 6e 64 69 66 0a 0a 20 20 61 73 73 65 72 74  #endif..  assert
4c10: 28 20 28 73 7a 50 61 67 65 20 26 20 28 73 7a 50  ( (szPage & (szP
4c20: 61 67 65 2d 31 29 29 3d 3d 30 20 26 26 20 73 7a  age-1))==0 && sz
4c30: 50 61 67 65 3e 3d 35 31 32 20 26 26 20 73 7a 50  Page>=512 && szP
4c40: 61 67 65 3c 3d 36 35 35 33 36 20 29 3b 0a 20 20  age<=65536 );.  
4c50: 61 73 73 65 72 74 28 20 73 7a 45 78 74 72 61 20  assert( szExtra 
4c60: 3c 20 33 30 30 20 29 3b 0a 0a 20 20 73 7a 20 3d  < 300 );..  sz =
4c70: 20 73 69 7a 65 6f 66 28 50 43 61 63 68 65 31 29   sizeof(PCache1)
4c80: 20 2b 20 73 69 7a 65 6f 66 28 50 47 72 6f 75 70   + sizeof(PGroup
4c90: 29 2a 73 65 70 61 72 61 74 65 43 61 63 68 65 3b  )*separateCache;
4ca0: 0a 20 20 70 43 61 63 68 65 20 3d 20 28 50 43 61  .  pCache = (PCa
4cb0: 63 68 65 31 20 2a 29 73 71 6c 69 74 65 33 4d 61  che1 *)sqlite3Ma
4cc0: 6c 6c 6f 63 5a 65 72 6f 28 73 7a 29 3b 0a 20 20  llocZero(sz);.  
4cd0: 69 66 28 20 70 43 61 63 68 65 20 29 7b 0a 20 20  if( pCache ){.  
4ce0: 20 20 69 66 28 20 73 65 70 61 72 61 74 65 43 61    if( separateCa
4cf0: 63 68 65 20 29 7b 0a 20 20 20 20 20 20 70 47 72  che ){.      pGr
4d00: 6f 75 70 20 3d 20 28 50 47 72 6f 75 70 2a 29 26  oup = (PGroup*)&
4d10: 70 43 61 63 68 65 5b 31 5d 3b 0a 20 20 20 20 20  pCache[1];.     
4d20: 20 70 47 72 6f 75 70 2d 3e 6d 78 50 69 6e 6e 65   pGroup->mxPinne
4d30: 64 20 3d 20 31 30 3b 0a 20 20 20 20 7d 65 6c 73  d = 10;.    }els
4d40: 65 7b 0a 20 20 20 20 20 20 70 47 72 6f 75 70 20  e{.      pGroup 
4d50: 3d 20 26 70 63 61 63 68 65 31 2e 67 72 70 3b 0a  = &pcache1.grp;.
4d60: 20 20 20 20 7d 0a 20 20 20 20 70 43 61 63 68 65      }.    pCache
4d70: 2d 3e 70 47 72 6f 75 70 20 3d 20 70 47 72 6f 75  ->pGroup = pGrou
4d80: 70 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 73  p;.    pCache->s
4d90: 7a 50 61 67 65 20 3d 20 73 7a 50 61 67 65 3b 0a  zPage = szPage;.
4da0: 20 20 20 20 70 43 61 63 68 65 2d 3e 73 7a 45 78      pCache->szEx
4db0: 74 72 61 20 3d 20 73 7a 45 78 74 72 61 3b 0a 20  tra = szExtra;. 
4dc0: 20 20 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67     pCache->bPurg
4dd0: 65 61 62 6c 65 20 3d 20 28 62 50 75 72 67 65 61  eable = (bPurgea
4de0: 62 6c 65 20 3f 20 31 20 3a 20 30 29 3b 0a 20 20  ble ? 1 : 0);.  
4df0: 20 20 69 66 28 20 62 50 75 72 67 65 61 62 6c 65    if( bPurgeable
4e00: 20 29 7b 0a 20 20 20 20 20 20 70 43 61 63 68 65   ){.      pCache
4e10: 2d 3e 6e 4d 69 6e 20 3d 20 31 30 3b 0a 20 20 20  ->nMin = 10;.   
4e20: 20 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d     pcache1EnterM
4e30: 75 74 65 78 28 70 47 72 6f 75 70 29 3b 0a 20 20  utex(pGroup);.  
4e40: 20 20 20 20 70 47 72 6f 75 70 2d 3e 6e 4d 69 6e      pGroup->nMin
4e50: 50 61 67 65 20 2b 3d 20 70 43 61 63 68 65 2d 3e  Page += pCache->
4e60: 6e 4d 69 6e 3b 0a 20 20 20 20 20 20 70 47 72 6f  nMin;.      pGro
4e70: 75 70 2d 3e 6d 78 50 69 6e 6e 65 64 20 3d 20 70  up->mxPinned = p
4e80: 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65 20  Group->nMaxPage 
4e90: 2b 20 31 30 20 2d 20 70 47 72 6f 75 70 2d 3e 6e  + 10 - pGroup->n
4ea0: 4d 69 6e 50 61 67 65 3b 0a 20 20 20 20 20 20 70  MinPage;.      p
4eb0: 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78  cache1LeaveMutex
4ec0: 28 70 47 72 6f 75 70 29 3b 0a 20 20 20 20 7d 0a  (pGroup);.    }.
4ed0: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 28 73 71    }.  return (sq
4ee0: 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 29 70  lite3_pcache *)p
4ef0: 43 61 63 68 65 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  Cache;.}../*.** 
4f00: 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  Implementation o
4f10: 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63  f the sqlite3_pc
4f20: 61 63 68 65 2e 78 43 61 63 68 65 73 69 7a 65 20  ache.xCachesize 
4f30: 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20 43  method. .**.** C
4f40: 6f 6e 66 69 67 75 72 65 20 74 68 65 20 63 61 63  onfigure the cac
4f50: 68 65 5f 73 69 7a 65 20 6c 69 6d 69 74 20 66 6f  he_size limit fo
4f60: 72 20 61 20 63 61 63 68 65 2e 0a 2a 2f 0a 73 74  r a cache..*/.st
4f70: 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65  atic void pcache
4f80: 31 43 61 63 68 65 73 69 7a 65 28 73 71 6c 69 74  1Cachesize(sqlit
4f90: 65 33 5f 70 63 61 63 68 65 20 2a 70 2c 20 69 6e  e3_pcache *p, in
4fa0: 74 20 6e 4d 61 78 29 7b 0a 20 20 50 43 61 63 68  t nMax){.  PCach
4fb0: 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43  e1 *pCache = (PC
4fc0: 61 63 68 65 31 20 2a 29 70 3b 0a 20 20 69 66 28  ache1 *)p;.  if(
4fd0: 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61   pCache->bPurgea
4fe0: 62 6c 65 20 29 7b 0a 20 20 20 20 50 47 72 6f 75  ble ){.    PGrou
4ff0: 70 20 2a 70 47 72 6f 75 70 20 3d 20 70 43 61 63  p *pGroup = pCac
5000: 68 65 2d 3e 70 47 72 6f 75 70 3b 0a 20 20 20 20  he->pGroup;.    
5010: 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65  pcache1EnterMute
5020: 78 28 70 47 72 6f 75 70 29 3b 0a 20 20 20 20 70  x(pGroup);.    p
5030: 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65 20  Group->nMaxPage 
5040: 2b 3d 20 28 6e 4d 61 78 20 2d 20 70 43 61 63 68  += (nMax - pCach
5050: 65 2d 3e 6e 4d 61 78 29 3b 0a 20 20 20 20 70 47  e->nMax);.    pG
5060: 72 6f 75 70 2d 3e 6d 78 50 69 6e 6e 65 64 20 3d  roup->mxPinned =
5070: 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67   pGroup->nMaxPag
5080: 65 20 2b 20 31 30 20 2d 20 70 47 72 6f 75 70 2d  e + 10 - pGroup-
5090: 3e 6e 4d 69 6e 50 61 67 65 3b 0a 20 20 20 20 70  >nMinPage;.    p
50a0: 43 61 63 68 65 2d 3e 6e 4d 61 78 20 3d 20 6e 4d  Cache->nMax = nM
50b0: 61 78 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e  ax;.    pCache->
50c0: 6e 39 30 70 63 74 20 3d 20 70 43 61 63 68 65 2d  n90pct = pCache-
50d0: 3e 6e 4d 61 78 2a 39 2f 31 30 3b 0a 20 20 20 20  >nMax*9/10;.    
50e0: 70 63 61 63 68 65 31 45 6e 66 6f 72 63 65 4d 61  pcache1EnforceMa
50f0: 78 50 61 67 65 28 70 47 72 6f 75 70 29 3b 0a 20  xPage(pGroup);. 
5100: 20 20 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d     pcache1LeaveM
5110: 75 74 65 78 28 70 47 72 6f 75 70 29 3b 0a 20 20  utex(pGroup);.  
5120: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65  }.}../*.** Imple
5130: 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65  mentation of the
5140: 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e   sqlite3_pcache.
5150: 78 53 68 72 69 6e 6b 20 6d 65 74 68 6f 64 2e 20  xShrink method. 
5160: 0a 2a 2a 0a 2a 2a 20 46 72 65 65 20 75 70 20 61  .**.** Free up a
5170: 73 20 6d 75 63 68 20 6d 65 6d 6f 72 79 20 61 73  s much memory as
5180: 20 70 6f 73 73 69 62 6c 65 2e 0a 2a 2f 0a 73 74   possible..*/.st
5190: 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65  atic void pcache
51a0: 31 53 68 72 69 6e 6b 28 73 71 6c 69 74 65 33 5f  1Shrink(sqlite3_
51b0: 70 63 61 63 68 65 20 2a 70 29 7b 0a 20 20 50 43  pcache *p){.  PC
51c0: 61 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20  ache1 *pCache = 
51d0: 28 50 43 61 63 68 65 31 2a 29 70 3b 0a 20 20 69  (PCache1*)p;.  i
51e0: 66 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67  f( pCache->bPurg
51f0: 65 61 62 6c 65 20 29 7b 0a 20 20 20 20 50 47 72  eable ){.    PGr
5200: 6f 75 70 20 2a 70 47 72 6f 75 70 20 3d 20 70 43  oup *pGroup = pC
5210: 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b 0a 20 20  ache->pGroup;.  
5220: 20 20 69 6e 74 20 73 61 76 65 64 4d 61 78 50 61    int savedMaxPa
5230: 67 65 3b 0a 20 20 20 20 70 63 61 63 68 65 31 45  ge;.    pcache1E
5240: 6e 74 65 72 4d 75 74 65 78 28 70 47 72 6f 75 70  nterMutex(pGroup
5250: 29 3b 0a 20 20 20 20 73 61 76 65 64 4d 61 78 50  );.    savedMaxP
5260: 61 67 65 20 3d 20 70 47 72 6f 75 70 2d 3e 6e 4d  age = pGroup->nM
5270: 61 78 50 61 67 65 3b 0a 20 20 20 20 70 47 72 6f  axPage;.    pGro
5280: 75 70 2d 3e 6e 4d 61 78 50 61 67 65 20 3d 20 30  up->nMaxPage = 0
5290: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 45 6e 66  ;.    pcache1Enf
52a0: 6f 72 63 65 4d 61 78 50 61 67 65 28 70 47 72 6f  orceMaxPage(pGro
52b0: 75 70 29 3b 0a 20 20 20 20 70 47 72 6f 75 70 2d  up);.    pGroup-
52c0: 3e 6e 4d 61 78 50 61 67 65 20 3d 20 73 61 76 65  >nMaxPage = save
52d0: 64 4d 61 78 50 61 67 65 3b 0a 20 20 20 20 70 63  dMaxPage;.    pc
52e0: 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28  ache1LeaveMutex(
52f0: 70 47 72 6f 75 70 29 3b 0a 20 20 7d 0a 7d 0a 0a  pGroup);.  }.}..
5300: 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61  /*.** Implementa
5310: 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69  tion of the sqli
5320: 74 65 33 5f 70 63 61 63 68 65 2e 78 50 61 67 65  te3_pcache.xPage
5330: 63 6f 75 6e 74 20 6d 65 74 68 6f 64 2e 20 0a 2a  count method. .*
5340: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 70 63 61  /.static int pca
5350: 63 68 65 31 50 61 67 65 63 6f 75 6e 74 28 73 71  che1Pagecount(sq
5360: 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70 29  lite3_pcache *p)
5370: 7b 0a 20 20 69 6e 74 20 6e 3b 0a 20 20 50 43 61  {.  int n;.  PCa
5380: 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28  che1 *pCache = (
5390: 50 43 61 63 68 65 31 2a 29 70 3b 0a 20 20 70 63  PCache1*)p;.  pc
53a0: 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28  ache1EnterMutex(
53b0: 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b  pCache->pGroup);
53c0: 0a 20 20 6e 20 3d 20 70 43 61 63 68 65 2d 3e 6e  .  n = pCache->n
53d0: 50 61 67 65 3b 0a 20 20 70 63 61 63 68 65 31 4c  Page;.  pcache1L
53e0: 65 61 76 65 4d 75 74 65 78 28 70 43 61 63 68 65  eaveMutex(pCache
53f0: 2d 3e 70 47 72 6f 75 70 29 3b 0a 20 20 72 65 74  ->pGroup);.  ret
5400: 75 72 6e 20 6e 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  urn n;.}../*.** 
5410: 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  Implementation o
5420: 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63  f the sqlite3_pc
5430: 61 63 68 65 2e 78 46 65 74 63 68 20 6d 65 74 68  ache.xFetch meth
5440: 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20 46 65 74 63 68  od. .**.** Fetch
5450: 20 61 20 70 61 67 65 20 62 79 20 6b 65 79 20 76   a page by key v
5460: 61 6c 75 65 2e 0a 2a 2a 0a 2a 2a 20 57 68 65 74  alue..**.** Whet
5470: 68 65 72 20 6f 72 20 6e 6f 74 20 61 20 6e 65 77  her or not a new
5480: 20 70 61 67 65 20 6d 61 79 20 62 65 20 61 6c 6c   page may be all
5490: 6f 63 61 74 65 64 20 62 79 20 74 68 69 73 20 66  ocated by this f
54a0: 75 6e 63 74 69 6f 6e 20 64 65 70 65 6e 64 73 20  unction depends 
54b0: 6f 6e 0a 2a 2a 20 74 68 65 20 76 61 6c 75 65 20  on.** the value 
54c0: 6f 66 20 74 68 65 20 63 72 65 61 74 65 46 6c 61  of the createFla
54d0: 67 20 61 72 67 75 6d 65 6e 74 2e 20 20 30 20 6d  g argument.  0 m
54e0: 65 61 6e 73 20 64 6f 20 6e 6f 74 20 61 6c 6c 6f  eans do not allo
54f0: 63 61 74 65 20 61 20 6e 65 77 0a 2a 2a 20 70 61  cate a new.** pa
5500: 67 65 2e 20 20 31 20 6d 65 61 6e 73 20 61 6c 6c  ge.  1 means all
5510: 6f 63 61 74 65 20 61 20 6e 65 77 20 70 61 67 65  ocate a new page
5520: 20 69 66 20 73 70 61 63 65 20 69 73 20 65 61 73   if space is eas
5530: 69 6c 79 20 61 76 61 69 6c 61 62 6c 65 2e 20 20  ily available.  
5540: 32 20 0a 2a 2a 20 6d 65 61 6e 73 20 74 6f 20 74  2 .** means to t
5550: 72 79 20 72 65 61 6c 6c 79 20 68 61 72 64 20 74  ry really hard t
5560: 6f 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77  o allocate a new
5570: 20 70 61 67 65 2e 0a 2a 2a 0a 2a 2a 20 46 6f 72   page..**.** For
5580: 20 61 20 6e 6f 6e 2d 70 75 72 67 65 61 62 6c 65   a non-purgeable
5590: 20 63 61 63 68 65 20 28 61 20 63 61 63 68 65 20   cache (a cache 
55a0: 75 73 65 64 20 61 73 20 74 68 65 20 73 74 6f 72  used as the stor
55b0: 61 67 65 20 66 6f 72 20 61 6e 20 69 6e 2d 6d 65  age for an in-me
55c0: 6d 6f 72 79 0a 2a 2a 20 64 61 74 61 62 61 73 65  mory.** database
55d0: 29 20 74 68 65 72 65 20 69 73 20 72 65 61 6c 6c  ) there is reall
55e0: 79 20 6e 6f 20 64 69 66 66 65 72 65 6e 63 65 20  y no difference 
55f0: 62 65 74 77 65 65 6e 20 63 72 65 61 74 65 46 6c  between createFl
5600: 61 67 20 31 20 61 6e 64 20 32 2e 20 20 53 6f 0a  ag 1 and 2.  So.
5610: 2a 2a 20 74 68 65 20 63 61 6c 6c 69 6e 67 20 66  ** the calling f
5620: 75 6e 63 74 69 6f 6e 20 28 70 63 61 63 68 65 2e  unction (pcache.
5630: 63 29 20 77 69 6c 6c 20 6e 65 76 65 72 20 68 61  c) will never ha
5640: 76 65 20 61 20 63 72 65 61 74 65 46 6c 61 67 20  ve a createFlag 
5650: 6f 66 20 31 20 6f 6e 0a 2a 2a 20 61 20 6e 6f 6e  of 1 on.** a non
5660: 2d 70 75 72 67 65 61 62 6c 65 20 63 61 63 68 65  -purgeable cache
5670: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 72 65 20 61 72  ..**.** There ar
5680: 65 20 74 68 72 65 65 20 64 69 66 66 65 72 65 6e  e three differen
5690: 74 20 61 70 70 72 6f 61 63 68 65 73 20 74 6f 20  t approaches to 
56a0: 6f 62 74 61 69 6e 69 6e 67 20 73 70 61 63 65 20  obtaining space 
56b0: 66 6f 72 20 61 20 70 61 67 65 2c 0a 2a 2a 20 64  for a page,.** d
56c0: 65 70 65 6e 64 69 6e 67 20 6f 6e 20 74 68 65 20  epending on the 
56d0: 76 61 6c 75 65 20 6f 66 20 70 61 72 61 6d 65 74  value of paramet
56e0: 65 72 20 63 72 65 61 74 65 46 6c 61 67 20 28 77  er createFlag (w
56f0: 68 69 63 68 20 6d 61 79 20 62 65 20 30 2c 20 31  hich may be 0, 1
5700: 20 6f 72 20 32 29 2e 0a 2a 2a 0a 2a 2a 20 20 20   or 2)..**.**   
5710: 31 2e 20 52 65 67 61 72 64 6c 65 73 73 20 6f 66  1. Regardless of
5720: 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20 63 72   the value of cr
5730: 65 61 74 65 46 6c 61 67 2c 20 74 68 65 20 63 61  eateFlag, the ca
5740: 63 68 65 20 69 73 20 73 65 61 72 63 68 65 64 20  che is searched 
5750: 66 6f 72 20 61 20 0a 2a 2a 20 20 20 20 20 20 63  for a .**      c
5760: 6f 70 79 20 6f 66 20 74 68 65 20 72 65 71 75 65  opy of the reque
5770: 73 74 65 64 20 70 61 67 65 2e 20 49 66 20 6f 6e  sted page. If on
5780: 65 20 69 73 20 66 6f 75 6e 64 2c 20 69 74 20 69  e is found, it i
5790: 73 20 72 65 74 75 72 6e 65 64 2e 0a 2a 2a 0a 2a  s returned..**.*
57a0: 2a 20 20 20 32 2e 20 49 66 20 63 72 65 61 74 65  *   2. If create
57b0: 46 6c 61 67 3d 3d 30 20 61 6e 64 20 74 68 65 20  Flag==0 and the 
57c0: 70 61 67 65 20 69 73 20 6e 6f 74 20 61 6c 72 65  page is not alre
57d0: 61 64 79 20 69 6e 20 74 68 65 20 63 61 63 68 65  ady in the cache
57e0: 2c 20 4e 55 4c 4c 20 69 73 0a 2a 2a 20 20 20 20  , NULL is.**    
57f0: 20 20 72 65 74 75 72 6e 65 64 2e 0a 2a 2a 0a 2a    returned..**.*
5800: 2a 20 20 20 33 2e 20 49 66 20 63 72 65 61 74 65  *   3. If create
5810: 46 6c 61 67 20 69 73 20 31 2c 20 61 6e 64 20 74  Flag is 1, and t
5820: 68 65 20 70 61 67 65 20 69 73 20 6e 6f 74 20 61  he page is not a
5830: 6c 72 65 61 64 79 20 69 6e 20 74 68 65 20 63 61  lready in the ca
5840: 63 68 65 2c 20 74 68 65 6e 0a 2a 2a 20 20 20 20  che, then.**    
5850: 20 20 72 65 74 75 72 6e 20 4e 55 4c 4c 20 28 64    return NULL (d
5860: 6f 20 6e 6f 74 20 61 6c 6c 6f 63 61 74 65 20 61  o not allocate a
5870: 20 6e 65 77 20 70 61 67 65 29 20 69 66 20 61 6e   new page) if an
5880: 79 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69  y of the followi
5890: 6e 67 0a 2a 2a 20 20 20 20 20 20 63 6f 6e 64 69  ng.**      condi
58a0: 74 69 6f 6e 73 20 61 72 65 20 74 72 75 65 3a 0a  tions are true:.
58b0: 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 28 61 29 20  **.**       (a) 
58c0: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 61  the number of pa
58d0: 67 65 73 20 70 69 6e 6e 65 64 20 62 79 20 74 68  ges pinned by th
58e0: 65 20 63 61 63 68 65 20 69 73 20 67 72 65 61 74  e cache is great
58f0: 65 72 20 74 68 61 6e 0a 2a 2a 20 20 20 20 20 20  er than.**      
5900: 20 20 20 20 20 50 43 61 63 68 65 31 2e 6e 4d 61       PCache1.nMa
5910: 78 2c 20 6f 72 0a 2a 2a 0a 2a 2a 20 20 20 20 20  x, or.**.**     
5920: 20 20 28 62 29 20 74 68 65 20 6e 75 6d 62 65 72    (b) the number
5930: 20 6f 66 20 70 61 67 65 73 20 70 69 6e 6e 65 64   of pages pinned
5940: 20 62 79 20 74 68 65 20 63 61 63 68 65 20 69 73   by the cache is
5950: 20 67 72 65 61 74 65 72 20 74 68 61 6e 0a 2a 2a   greater than.**
5960: 20 20 20 20 20 20 20 20 20 20 20 74 68 65 20 73             the s
5970: 75 6d 20 6f 66 20 6e 4d 61 78 20 66 6f 72 20 61  um of nMax for a
5980: 6c 6c 20 70 75 72 67 65 61 62 6c 65 20 63 61 63  ll purgeable cac
5990: 68 65 73 2c 20 6c 65 73 73 20 74 68 65 20 73 75  hes, less the su
59a0: 6d 20 6f 66 20 0a 2a 2a 20 20 20 20 20 20 20 20  m of .**        
59b0: 20 20 20 6e 4d 69 6e 20 66 6f 72 20 61 6c 6c 20     nMin for all 
59c0: 6f 74 68 65 72 20 70 75 72 67 65 61 62 6c 65 20  other purgeable 
59d0: 63 61 63 68 65 73 2c 20 6f 72 0a 2a 2a 0a 2a 2a  caches, or.**.**
59e0: 20 20 20 34 2e 20 49 66 20 6e 6f 6e 65 20 6f 66     4. If none of
59f0: 20 74 68 65 20 66 69 72 73 74 20 74 68 72 65 65   the first three
5a00: 20 63 6f 6e 64 69 74 69 6f 6e 73 20 61 70 70 6c   conditions appl
5a10: 79 20 61 6e 64 20 74 68 65 20 63 61 63 68 65 20  y and the cache 
5a20: 69 73 20 6d 61 72 6b 65 64 0a 2a 2a 20 20 20 20  is marked.**    
5a30: 20 20 61 73 20 70 75 72 67 65 61 62 6c 65 2c 20    as purgeable, 
5a40: 61 6e 64 20 69 66 20 6f 6e 65 20 6f 66 20 74 68  and if one of th
5a50: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 69 73 20 74  e following is t
5a60: 72 75 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20  rue:.**.**      
5a70: 20 28 61 29 20 54 68 65 20 6e 75 6d 62 65 72 20   (a) The number 
5a80: 6f 66 20 70 61 67 65 73 20 61 6c 6c 6f 63 61 74  of pages allocat
5a90: 65 64 20 66 6f 72 20 74 68 65 20 63 61 63 68 65  ed for the cache
5aa0: 20 69 73 20 61 6c 72 65 61 64 79 20 0a 2a 2a 20   is already .** 
5ab0: 20 20 20 20 20 20 20 20 20 20 50 43 61 63 68 65            PCache
5ac0: 31 2e 6e 4d 61 78 2c 20 6f 72 0a 2a 2a 0a 2a 2a  1.nMax, or.**.**
5ad0: 20 20 20 20 20 20 20 28 62 29 20 54 68 65 20 6e         (b) The n
5ae0: 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 61  umber of pages a
5af0: 6c 6c 6f 63 61 74 65 64 20 66 6f 72 20 61 6c 6c  llocated for all
5b00: 20 70 75 72 67 65 61 62 6c 65 20 63 61 63 68 65   purgeable cache
5b10: 73 20 69 73 0a 2a 2a 20 20 20 20 20 20 20 20 20  s is.**         
5b20: 20 20 61 6c 72 65 61 64 79 20 65 71 75 61 6c 20    already equal 
5b30: 74 6f 20 6f 72 20 67 72 65 61 74 65 72 20 74 68  to or greater th
5b40: 61 6e 20 74 68 65 20 73 75 6d 20 6f 66 20 6e 4d  an the sum of nM
5b50: 61 78 20 66 6f 72 20 61 6c 6c 0a 2a 2a 20 20 20  ax for all.**   
5b60: 20 20 20 20 20 20 20 20 70 75 72 67 65 61 62 6c          purgeabl
5b70: 65 20 63 61 63 68 65 73 2c 0a 2a 2a 0a 2a 2a 20  e caches,.**.** 
5b80: 20 20 20 20 20 20 28 63 29 20 54 68 65 20 73 79        (c) The sy
5b90: 73 74 65 6d 20 69 73 20 75 6e 64 65 72 20 6d 65  stem is under me
5ba0: 6d 6f 72 79 20 70 72 65 73 73 75 72 65 20 61 6e  mory pressure an
5bb0: 64 20 77 61 6e 74 73 20 74 6f 20 61 76 6f 69 64  d wants to avoid
5bc0: 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 75 6e  .**           un
5bd0: 6e 65 63 65 73 73 61 72 79 20 70 61 67 65 73 20  necessary pages 
5be0: 63 61 63 68 65 20 65 6e 74 72 79 20 61 6c 6c 6f  cache entry allo
5bf0: 63 61 74 69 6f 6e 73 0a 2a 2a 0a 2a 2a 20 20 20  cations.**.**   
5c00: 20 20 20 74 68 65 6e 20 61 74 74 65 6d 70 74 20     then attempt 
5c10: 74 6f 20 72 65 63 79 63 6c 65 20 61 20 70 61 67  to recycle a pag
5c20: 65 20 66 72 6f 6d 20 74 68 65 20 4c 52 55 20 6c  e from the LRU l
5c30: 69 73 74 2e 20 49 66 20 69 74 20 69 73 20 74 68  ist. If it is th
5c40: 65 20 72 69 67 68 74 0a 2a 2a 20 20 20 20 20 20  e right.**      
5c50: 73 69 7a 65 2c 20 72 65 74 75 72 6e 20 74 68 65  size, return the
5c60: 20 72 65 63 79 63 6c 65 64 20 62 75 66 66 65 72   recycled buffer
5c70: 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 66 72 65  . Otherwise, fre
5c80: 65 20 74 68 65 20 62 75 66 66 65 72 20 61 6e 64  e the buffer and
5c90: 0a 2a 2a 20 20 20 20 20 20 70 72 6f 63 65 65 64  .**      proceed
5ca0: 20 74 6f 20 73 74 65 70 20 35 2e 20 0a 2a 2a 0a   to step 5. .**.
5cb0: 2a 2a 20 20 20 35 2e 20 4f 74 68 65 72 77 69 73  **   5. Otherwis
5cc0: 65 2c 20 61 6c 6c 6f 63 61 74 65 20 61 6e 64 20  e, allocate and 
5cd0: 72 65 74 75 72 6e 20 61 20 6e 65 77 20 70 61 67  return a new pag
5ce0: 65 20 62 75 66 66 65 72 2e 0a 2a 2f 0a 73 74 61  e buffer..*/.sta
5cf0: 74 69 63 20 73 71 6c 69 74 65 33 5f 70 63 61 63  tic sqlite3_pcac
5d00: 68 65 5f 70 61 67 65 20 2a 70 63 61 63 68 65 31  he_page *pcache1
5d10: 46 65 74 63 68 28 0a 20 20 73 71 6c 69 74 65 33  Fetch(.  sqlite3
5d20: 5f 70 63 61 63 68 65 20 2a 70 2c 20 0a 20 20 75  _pcache *p, .  u
5d30: 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4b 65 79  nsigned int iKey
5d40: 2c 20 0a 20 20 69 6e 74 20 63 72 65 61 74 65 46  , .  int createF
5d50: 6c 61 67 0a 29 7b 0a 20 20 75 6e 73 69 67 6e 65  lag.){.  unsigne
5d60: 64 20 69 6e 74 20 6e 50 69 6e 6e 65 64 3b 0a 20  d int nPinned;. 
5d70: 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68 65   PCache1 *pCache
5d80: 20 3d 20 28 50 43 61 63 68 65 31 20 2a 29 70 3b   = (PCache1 *)p;
5d90: 0a 20 20 50 47 72 6f 75 70 20 2a 70 47 72 6f 75  .  PGroup *pGrou
5da0: 70 3b 0a 20 20 50 67 48 64 72 31 20 2a 70 50 61  p;.  PgHdr1 *pPa
5db0: 67 65 20 3d 20 30 3b 0a 0a 20 20 61 73 73 65 72  ge = 0;..  asser
5dc0: 74 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67  t( pCache->bPurg
5dd0: 65 61 62 6c 65 20 7c 7c 20 63 72 65 61 74 65 46  eable || createF
5de0: 6c 61 67 21 3d 31 20 29 3b 0a 20 20 61 73 73 65  lag!=1 );.  asse
5df0: 72 74 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72  rt( pCache->bPur
5e00: 67 65 61 62 6c 65 20 7c 7c 20 70 43 61 63 68 65  geable || pCache
5e10: 2d 3e 6e 4d 69 6e 3d 3d 30 20 29 3b 0a 20 20 61  ->nMin==0 );.  a
5e20: 73 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e 62  ssert( pCache->b
5e30: 50 75 72 67 65 61 62 6c 65 3d 3d 30 20 7c 7c 20  Purgeable==0 || 
5e40: 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 3d 3d 31 30  pCache->nMin==10
5e50: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 43   );.  assert( pC
5e60: 61 63 68 65 2d 3e 6e 4d 69 6e 3d 3d 30 20 7c 7c  ache->nMin==0 ||
5e70: 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61   pCache->bPurgea
5e80: 62 6c 65 20 29 3b 0a 20 20 70 63 61 63 68 65 31  ble );.  pcache1
5e90: 45 6e 74 65 72 4d 75 74 65 78 28 70 47 72 6f 75  EnterMutex(pGrou
5ea0: 70 20 3d 20 70 43 61 63 68 65 2d 3e 70 47 72 6f  p = pCache->pGro
5eb0: 75 70 29 3b 0a 0a 20 20 2f 2a 20 53 74 65 70 20  up);..  /* Step 
5ec0: 31 3a 20 53 65 61 72 63 68 20 74 68 65 20 68 61  1: Search the ha
5ed0: 73 68 20 74 61 62 6c 65 20 66 6f 72 20 61 6e 20  sh table for an 
5ee0: 65 78 69 73 74 69 6e 67 20 65 6e 74 72 79 2e 20  existing entry. 
5ef0: 2a 2f 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d  */.  if( pCache-
5f00: 3e 6e 48 61 73 68 3e 30 20 29 7b 0a 20 20 20 20  >nHash>0 ){.    
5f10: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 20 3d  unsigned int h =
5f20: 20 69 4b 65 79 20 25 20 70 43 61 63 68 65 2d 3e   iKey % pCache->
5f30: 6e 48 61 73 68 3b 0a 20 20 20 20 66 6f 72 28 70  nHash;.    for(p
5f40: 50 61 67 65 3d 70 43 61 63 68 65 2d 3e 61 70 48  Page=pCache->apH
5f50: 61 73 68 5b 68 5d 3b 20 70 50 61 67 65 26 26 70  ash[h]; pPage&&p
5f60: 50 61 67 65 2d 3e 69 4b 65 79 21 3d 69 4b 65 79  Page->iKey!=iKey
5f70: 3b 20 70 50 61 67 65 3d 70 50 61 67 65 2d 3e 70  ; pPage=pPage->p
5f80: 4e 65 78 74 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  Next);.  }..  /*
5f90: 20 53 74 65 70 20 32 3a 20 41 62 6f 72 74 20 69   Step 2: Abort i
5fa0: 66 20 6e 6f 20 65 78 69 73 74 69 6e 67 20 70 61  f no existing pa
5fb0: 67 65 20 69 73 20 66 6f 75 6e 64 20 61 6e 64 20  ge is found and 
5fc0: 63 72 65 61 74 65 46 6c 61 67 20 69 73 20 30 20  createFlag is 0 
5fd0: 2a 2f 0a 20 20 69 66 28 20 70 50 61 67 65 20 7c  */.  if( pPage |
5fe0: 7c 20 63 72 65 61 74 65 46 6c 61 67 3d 3d 30 20  | createFlag==0 
5ff0: 29 7b 0a 20 20 20 20 70 63 61 63 68 65 31 50 69  ){.    pcache1Pi
6000: 6e 50 61 67 65 28 70 50 61 67 65 29 3b 0a 20 20  nPage(pPage);.  
6010: 20 20 67 6f 74 6f 20 66 65 74 63 68 5f 6f 75 74    goto fetch_out
6020: 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 54 68 65 20  ;.  }..  /* The 
6030: 70 47 72 6f 75 70 20 6c 6f 63 61 6c 20 76 61 72  pGroup local var
6040: 69 61 62 6c 65 20 77 69 6c 6c 20 6e 6f 72 6d 61  iable will norma
6050: 6c 6c 79 20 62 65 20 69 6e 69 74 69 61 6c 69 7a  lly be initializ
6060: 65 64 20 62 79 20 74 68 65 0a 20 20 2a 2a 20 70  ed by the.  ** p
6070: 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78  cache1EnterMutex
6080: 28 29 20 6d 61 63 72 6f 20 61 62 6f 76 65 2e 20  () macro above. 
6090: 20 42 75 74 20 69 66 20 53 51 4c 49 54 45 5f 4d   But if SQLITE_M
60a0: 55 54 45 58 5f 4f 4d 49 54 20 69 73 20 64 65 66  UTEX_OMIT is def
60b0: 69 6e 65 64 2c 0a 20 20 2a 2a 20 74 68 65 6e 20  ined,.  ** then 
60c0: 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65  pcache1EnterMute
60d0: 78 28 29 20 69 73 20 61 20 6e 6f 2d 6f 70 2c 20  x() is a no-op, 
60e0: 73 6f 20 77 65 20 68 61 76 65 20 74 6f 20 69 6e  so we have to in
60f0: 69 74 69 61 6c 69 7a 65 20 74 68 65 0a 20 20 2a  itialize the.  *
6100: 2a 20 6c 6f 63 61 6c 20 76 61 72 69 61 62 6c 65  * local variable
6110: 20 68 65 72 65 2e 20 20 44 65 6c 61 79 69 6e 67   here.  Delaying
6120: 20 74 68 65 20 69 6e 69 74 69 61 6c 69 7a 61 74   the initializat
6130: 69 6f 6e 20 6f 66 20 70 47 72 6f 75 70 20 69 73  ion of pGroup is
6140: 20 61 6e 0a 20 20 2a 2a 20 6f 70 74 69 6d 69 7a   an.  ** optimiz
6150: 61 74 69 6f 6e 3a 20 20 54 68 65 20 63 6f 6d 6d  ation:  The comm
6160: 6f 6e 20 63 61 73 65 20 69 73 20 74 6f 20 65 78  on case is to ex
6170: 69 74 20 74 68 65 20 6d 6f 64 75 6c 65 20 62 65  it the module be
6180: 66 6f 72 65 20 72 65 61 63 68 69 6e 67 0a 20 20  fore reaching.  
6190: 2a 2a 20 74 68 69 73 20 70 6f 69 6e 74 2e 0a 20  ** this point.. 
61a0: 20 2a 2f 0a 23 69 66 64 65 66 20 53 51 4c 49 54   */.#ifdef SQLIT
61b0: 45 5f 4d 55 54 45 58 5f 4f 4d 49 54 0a 20 20 70  E_MUTEX_OMIT.  p
61c0: 47 72 6f 75 70 20 3d 20 70 43 61 63 68 65 2d 3e  Group = pCache->
61d0: 70 47 72 6f 75 70 3b 0a 23 65 6e 64 69 66 0a 0a  pGroup;.#endif..
61e0: 20 20 2f 2a 20 53 74 65 70 20 33 3a 20 41 62 6f    /* Step 3: Abo
61f0: 72 74 20 69 66 20 63 72 65 61 74 65 46 6c 61 67  rt if createFlag
6200: 20 69 73 20 31 20 62 75 74 20 74 68 65 20 63 61   is 1 but the ca
6210: 63 68 65 20 69 73 20 6e 65 61 72 6c 79 20 66 75  che is nearly fu
6220: 6c 6c 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20  ll */.  assert( 
6230: 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 20 3e 3d  pCache->nPage >=
6240: 20 70 43 61 63 68 65 2d 3e 6e 52 65 63 79 63 6c   pCache->nRecycl
6250: 61 62 6c 65 20 29 3b 0a 20 20 6e 50 69 6e 6e 65  able );.  nPinne
6260: 64 20 3d 20 70 43 61 63 68 65 2d 3e 6e 50 61 67  d = pCache->nPag
6270: 65 20 2d 20 70 43 61 63 68 65 2d 3e 6e 52 65 63  e - pCache->nRec
6280: 79 63 6c 61 62 6c 65 3b 0a 20 20 61 73 73 65 72  yclable;.  asser
6290: 74 28 20 70 47 72 6f 75 70 2d 3e 6d 78 50 69 6e  t( pGroup->mxPin
62a0: 6e 65 64 20 3d 3d 20 70 47 72 6f 75 70 2d 3e 6e  ned == pGroup->n
62b0: 4d 61 78 50 61 67 65 20 2b 20 31 30 20 2d 20 70  MaxPage + 10 - p
62c0: 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67 65 20  Group->nMinPage 
62d0: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 43 61  );.  assert( pCa
62e0: 63 68 65 2d 3e 6e 39 30 70 63 74 20 3d 3d 20 70  che->n90pct == p
62f0: 43 61 63 68 65 2d 3e 6e 4d 61 78 2a 39 2f 31 30  Cache->nMax*9/10
6300: 20 29 3b 0a 20 20 69 66 28 20 63 72 65 61 74 65   );.  if( create
6310: 46 6c 61 67 3d 3d 31 20 26 26 20 28 0a 20 20 20  Flag==1 && (.   
6320: 20 20 20 20 20 6e 50 69 6e 6e 65 64 3e 3d 70 47       nPinned>=pG
6330: 72 6f 75 70 2d 3e 6d 78 50 69 6e 6e 65 64 0a 20  roup->mxPinned. 
6340: 20 20 20 20 7c 7c 20 6e 50 69 6e 6e 65 64 3e 3d      || nPinned>=
6350: 70 43 61 63 68 65 2d 3e 6e 39 30 70 63 74 0a 20  pCache->n90pct. 
6360: 20 20 20 20 7c 7c 20 70 63 61 63 68 65 31 55 6e      || pcache1Un
6370: 64 65 72 4d 65 6d 6f 72 79 50 72 65 73 73 75 72  derMemoryPressur
6380: 65 28 70 43 61 63 68 65 29 0a 20 20 29 29 7b 0a  e(pCache).  )){.
6390: 20 20 20 20 67 6f 74 6f 20 66 65 74 63 68 5f 6f      goto fetch_o
63a0: 75 74 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70  ut;.  }..  if( p
63b0: 43 61 63 68 65 2d 3e 6e 50 61 67 65 3e 3d 70 43  Cache->nPage>=pC
63c0: 61 63 68 65 2d 3e 6e 48 61 73 68 20 26 26 20 70  ache->nHash && p
63d0: 63 61 63 68 65 31 52 65 73 69 7a 65 48 61 73 68  cache1ResizeHash
63e0: 28 70 43 61 63 68 65 29 20 29 7b 0a 20 20 20 20  (pCache) ){.    
63f0: 67 6f 74 6f 20 66 65 74 63 68 5f 6f 75 74 3b 0a  goto fetch_out;.
6400: 20 20 7d 0a 0a 20 20 2f 2a 20 53 74 65 70 20 34    }..  /* Step 4
6410: 2e 20 54 72 79 20 74 6f 20 72 65 63 79 63 6c 65  . Try to recycle
6420: 20 61 20 70 61 67 65 2e 20 2a 2f 0a 20 20 69 66   a page. */.  if
6430: 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65  ( pCache->bPurge
6440: 61 62 6c 65 20 26 26 20 70 47 72 6f 75 70 2d 3e  able && pGroup->
6450: 70 4c 72 75 54 61 69 6c 20 26 26 20 28 0a 20 20  pLruTail && (.  
6460: 20 20 20 20 20 20 20 28 70 43 61 63 68 65 2d 3e         (pCache->
6470: 6e 50 61 67 65 2b 31 3e 3d 70 43 61 63 68 65 2d  nPage+1>=pCache-
6480: 3e 6e 4d 61 78 29 0a 20 20 20 20 20 20 7c 7c 20  >nMax).      || 
6490: 70 47 72 6f 75 70 2d 3e 6e 43 75 72 72 65 6e 74  pGroup->nCurrent
64a0: 50 61 67 65 3e 3d 70 47 72 6f 75 70 2d 3e 6e 4d  Page>=pGroup->nM
64b0: 61 78 50 61 67 65 0a 20 20 20 20 20 20 7c 7c 20  axPage.      || 
64c0: 70 63 61 63 68 65 31 55 6e 64 65 72 4d 65 6d 6f  pcache1UnderMemo
64d0: 72 79 50 72 65 73 73 75 72 65 28 70 43 61 63 68  ryPressure(pCach
64e0: 65 29 0a 20 20 29 29 7b 0a 20 20 20 20 50 43 61  e).  )){.    PCa
64f0: 63 68 65 31 20 2a 70 4f 74 68 65 72 3b 0a 20 20  che1 *pOther;.  
6500: 20 20 70 50 61 67 65 20 3d 20 70 47 72 6f 75 70    pPage = pGroup
6510: 2d 3e 70 4c 72 75 54 61 69 6c 3b 0a 20 20 20 20  ->pLruTail;.    
6520: 70 63 61 63 68 65 31 52 65 6d 6f 76 65 46 72 6f  pcache1RemoveFro
6530: 6d 48 61 73 68 28 70 50 61 67 65 29 3b 0a 20 20  mHash(pPage);.  
6540: 20 20 70 63 61 63 68 65 31 50 69 6e 50 61 67 65    pcache1PinPage
6550: 28 70 50 61 67 65 29 3b 0a 20 20 20 20 70 4f 74  (pPage);.    pOt
6560: 68 65 72 20 3d 20 70 50 61 67 65 2d 3e 70 43 61  her = pPage->pCa
6570: 63 68 65 3b 0a 0a 20 20 20 20 2f 2a 20 57 65 20  che;..    /* We 
6580: 77 61 6e 74 20 74 6f 20 76 65 72 69 66 79 20 74  want to verify t
6590: 68 61 74 20 73 7a 50 61 67 65 20 61 6e 64 20 73  hat szPage and s
65a0: 7a 45 78 74 72 61 20 61 72 65 20 74 68 65 20 73  zExtra are the s
65b0: 61 6d 65 20 66 6f 72 20 70 4f 74 68 65 72 0a 20  ame for pOther. 
65c0: 20 20 20 2a 2a 20 61 6e 64 20 70 43 61 63 68 65     ** and pCache
65d0: 2e 20 20 41 73 73 65 72 74 20 74 68 61 74 20 77  .  Assert that w
65e0: 65 20 63 61 6e 20 76 65 72 69 66 79 20 74 68 69  e can verify thi
65f0: 73 20 62 79 20 63 6f 6d 70 61 72 69 6e 67 20 73  s by comparing s
6600: 75 6d 73 2e 20 2a 2f 0a 20 20 20 20 61 73 73 65  ums. */.    asse
6610: 72 74 28 20 28 70 43 61 63 68 65 2d 3e 73 7a 50  rt( (pCache->szP
6620: 61 67 65 20 26 20 28 70 43 61 63 68 65 2d 3e 73  age & (pCache->s
6630: 7a 50 61 67 65 2d 31 29 29 3d 3d 30 20 26 26 20  zPage-1))==0 && 
6640: 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 3e 3d  pCache->szPage>=
6650: 35 31 32 20 29 3b 0a 20 20 20 20 61 73 73 65 72  512 );.    asser
6660: 74 28 20 70 43 61 63 68 65 2d 3e 73 7a 45 78 74  t( pCache->szExt
6670: 72 61 3c 35 31 32 20 29 3b 0a 20 20 20 20 61 73  ra<512 );.    as
6680: 73 65 72 74 28 20 28 70 4f 74 68 65 72 2d 3e 73  sert( (pOther->s
6690: 7a 50 61 67 65 20 26 20 28 70 4f 74 68 65 72 2d  zPage & (pOther-
66a0: 3e 73 7a 50 61 67 65 2d 31 29 29 3d 3d 30 20 26  >szPage-1))==0 &
66b0: 26 20 70 4f 74 68 65 72 2d 3e 73 7a 50 61 67 65  & pOther->szPage
66c0: 3e 3d 35 31 32 20 29 3b 0a 20 20 20 20 61 73 73  >=512 );.    ass
66d0: 65 72 74 28 20 70 4f 74 68 65 72 2d 3e 73 7a 45  ert( pOther->szE
66e0: 78 74 72 61 3c 35 31 32 20 29 3b 0a 0a 20 20 20  xtra<512 );..   
66f0: 20 69 66 28 20 70 4f 74 68 65 72 2d 3e 73 7a 50   if( pOther->szP
6700: 61 67 65 2b 70 4f 74 68 65 72 2d 3e 73 7a 45 78  age+pOther->szEx
6710: 74 72 61 20 21 3d 20 70 43 61 63 68 65 2d 3e 73  tra != pCache->s
6720: 7a 50 61 67 65 2b 70 43 61 63 68 65 2d 3e 73 7a  zPage+pCache->sz
6730: 45 78 74 72 61 20 29 7b 0a 20 20 20 20 20 20 70  Extra ){.      p
6740: 63 61 63 68 65 31 46 72 65 65 50 61 67 65 28 70  cache1FreePage(p
6750: 50 61 67 65 29 3b 0a 20 20 20 20 20 20 70 50 61  Page);.      pPa
6760: 67 65 20 3d 20 30 3b 0a 20 20 20 20 7d 65 6c 73  ge = 0;.    }els
6770: 65 7b 0a 20 20 20 20 20 20 70 47 72 6f 75 70 2d  e{.      pGroup-
6780: 3e 6e 43 75 72 72 65 6e 74 50 61 67 65 20 2d 3d  >nCurrentPage -=
6790: 20 28 70 4f 74 68 65 72 2d 3e 62 50 75 72 67 65   (pOther->bPurge
67a0: 61 62 6c 65 20 2d 20 70 43 61 63 68 65 2d 3e 62  able - pCache->b
67b0: 50 75 72 67 65 61 62 6c 65 29 3b 0a 20 20 20 20  Purgeable);.    
67c0: 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53 74 65 70  }.  }..  /* Step
67d0: 20 35 2e 20 49 66 20 61 20 75 73 61 62 6c 65 20   5. If a usable 
67e0: 70 61 67 65 20 62 75 66 66 65 72 20 68 61 73 20  page buffer has 
67f0: 73 74 69 6c 6c 20 6e 6f 74 20 62 65 65 6e 20 66  still not been f
6800: 6f 75 6e 64 2c 20 0a 20 20 2a 2a 20 61 74 74 65  ound, .  ** atte
6810: 6d 70 74 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20  mpt to allocate 
6820: 61 20 6e 65 77 20 6f 6e 65 2e 20 0a 20 20 2a 2f  a new one. .  */
6830: 0a 20 20 69 66 28 20 21 70 50 61 67 65 20 29 7b  .  if( !pPage ){
6840: 0a 20 20 20 20 69 66 28 20 63 72 65 61 74 65 46  .    if( createF
6850: 6c 61 67 3d 3d 31 20 29 20 73 71 6c 69 74 65 33  lag==1 ) sqlite3
6860: 42 65 67 69 6e 42 65 6e 69 67 6e 4d 61 6c 6c 6f  BeginBenignMallo
6870: 63 28 29 3b 0a 20 20 20 20 70 50 61 67 65 20 3d  c();.    pPage =
6880: 20 70 63 61 63 68 65 31 41 6c 6c 6f 63 50 61 67   pcache1AllocPag
6890: 65 28 70 43 61 63 68 65 29 3b 0a 20 20 20 20 69  e(pCache);.    i
68a0: 66 28 20 63 72 65 61 74 65 46 6c 61 67 3d 3d 31  f( createFlag==1
68b0: 20 29 20 73 71 6c 69 74 65 33 45 6e 64 42 65 6e   ) sqlite3EndBen
68c0: 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 0a 20 20 7d  ignMalloc();.  }
68d0: 0a 0a 20 20 69 66 28 20 70 50 61 67 65 20 29 7b  ..  if( pPage ){
68e0: 0a 20 20 20 20 75 6e 73 69 67 6e 65 64 20 69 6e  .    unsigned in
68f0: 74 20 68 20 3d 20 69 4b 65 79 20 25 20 70 43 61  t h = iKey % pCa
6900: 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 20 20  che->nHash;.    
6910: 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 2b 2b 3b  pCache->nPage++;
6920: 0a 20 20 20 20 70 50 61 67 65 2d 3e 69 4b 65 79  .    pPage->iKey
6930: 20 3d 20 69 4b 65 79 3b 0a 20 20 20 20 70 50 61   = iKey;.    pPa
6940: 67 65 2d 3e 70 4e 65 78 74 20 3d 20 70 43 61 63  ge->pNext = pCac
6950: 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 0a 20  he->apHash[h];. 
6960: 20 20 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65     pPage->pCache
6970: 20 3d 20 70 43 61 63 68 65 3b 0a 20 20 20 20 70   = pCache;.    p
6980: 50 61 67 65 2d 3e 70 4c 72 75 50 72 65 76 20 3d  Page->pLruPrev =
6990: 20 30 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 70   0;.    pPage->p
69a0: 4c 72 75 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20  LruNext = 0;.   
69b0: 20 2a 28 76 6f 69 64 20 2a 2a 29 70 50 61 67 65   *(void **)pPage
69c0: 2d 3e 70 61 67 65 2e 70 45 78 74 72 61 20 3d 20  ->page.pExtra = 
69d0: 30 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 61  0;.    pCache->a
69e0: 70 48 61 73 68 5b 68 5d 20 3d 20 70 50 61 67 65  pHash[h] = pPage
69f0: 3b 0a 20 20 7d 0a 0a 66 65 74 63 68 5f 6f 75 74  ;.  }..fetch_out
6a00: 3a 0a 20 20 69 66 28 20 70 50 61 67 65 20 26 26  :.  if( pPage &&
6a10: 20 69 4b 65 79 3e 70 43 61 63 68 65 2d 3e 69 4d   iKey>pCache->iM
6a20: 61 78 4b 65 79 20 29 7b 0a 20 20 20 20 70 43 61  axKey ){.    pCa
6a30: 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 3d 20 69  che->iMaxKey = i
6a40: 4b 65 79 3b 0a 20 20 7d 0a 20 20 70 63 61 63 68  Key;.  }.  pcach
6a50: 65 31 4c 65 61 76 65 4d 75 74 65 78 28 70 47 72  e1LeaveMutex(pGr
6a60: 6f 75 70 29 3b 0a 20 20 72 65 74 75 72 6e 20 26  oup);.  return &
6a70: 70 50 61 67 65 2d 3e 70 61 67 65 3b 0a 7d 0a 0a  pPage->page;.}..
6a80: 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74  ./*.** Implement
6a90: 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c  ation of the sql
6aa0: 69 74 65 33 5f 70 63 61 63 68 65 2e 78 55 6e 70  ite3_pcache.xUnp
6ab0: 69 6e 20 6d 65 74 68 6f 64 2e 0a 2a 2a 0a 2a 2a  in method..**.**
6ac0: 20 4d 61 72 6b 20 61 20 70 61 67 65 20 61 73 20   Mark a page as 
6ad0: 75 6e 70 69 6e 6e 65 64 20 28 65 6c 69 67 69 62  unpinned (eligib
6ae0: 6c 65 20 66 6f 72 20 61 73 79 6e 63 68 72 6f 6e  le for asynchron
6af0: 6f 75 73 20 72 65 63 79 63 6c 69 6e 67 29 2e 0a  ous recycling)..
6b00: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70  */.static void p
6b10: 63 61 63 68 65 31 55 6e 70 69 6e 28 0a 20 20 73  cache1Unpin(.  s
6b20: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70  qlite3_pcache *p
6b30: 2c 20 0a 20 20 73 71 6c 69 74 65 33 5f 70 63 61  , .  sqlite3_pca
6b40: 63 68 65 5f 70 61 67 65 20 2a 70 50 67 2c 20 0a  che_page *pPg, .
6b50: 20 20 69 6e 74 20 72 65 75 73 65 55 6e 6c 69 6b    int reuseUnlik
6b60: 65 6c 79 0a 29 7b 0a 20 20 50 43 61 63 68 65 31  ely.){.  PCache1
6b70: 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61 63   *pCache = (PCac
6b80: 68 65 31 20 2a 29 70 3b 0a 20 20 50 67 48 64 72  he1 *)p;.  PgHdr
6b90: 31 20 2a 70 50 61 67 65 20 3d 20 28 50 67 48 64  1 *pPage = (PgHd
6ba0: 72 31 20 2a 29 70 50 67 3b 0a 20 20 50 47 72 6f  r1 *)pPg;.  PGro
6bb0: 75 70 20 2a 70 47 72 6f 75 70 20 3d 20 70 43 61  up *pGroup = pCa
6bc0: 63 68 65 2d 3e 70 47 72 6f 75 70 3b 0a 20 0a 20  che->pGroup;. . 
6bd0: 20 61 73 73 65 72 74 28 20 70 50 61 67 65 2d 3e   assert( pPage->
6be0: 70 43 61 63 68 65 3d 3d 70 43 61 63 68 65 20 29  pCache==pCache )
6bf0: 3b 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65 72  ;.  pcache1Enter
6c00: 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b 0a 0a  Mutex(pGroup);..
6c10: 20 20 2f 2a 20 49 74 20 69 73 20 61 6e 20 65 72    /* It is an er
6c20: 72 6f 72 20 74 6f 20 63 61 6c 6c 20 74 68 69 73  ror to call this
6c30: 20 66 75 6e 63 74 69 6f 6e 20 69 66 20 74 68 65   function if the
6c40: 20 70 61 67 65 20 69 73 20 61 6c 72 65 61 64 79   page is already
6c50: 20 0a 20 20 2a 2a 20 70 61 72 74 20 6f 66 20 74   .  ** part of t
6c60: 68 65 20 50 47 72 6f 75 70 20 4c 52 55 20 6c 69  he PGroup LRU li
6c70: 73 74 2e 0a 20 20 2a 2f 0a 20 20 61 73 73 65 72  st..  */.  asser
6c80: 74 28 20 70 50 61 67 65 2d 3e 70 4c 72 75 50 72  t( pPage->pLruPr
6c90: 65 76 3d 3d 30 20 26 26 20 70 50 61 67 65 2d 3e  ev==0 && pPage->
6ca0: 70 4c 72 75 4e 65 78 74 3d 3d 30 20 29 3b 0a 20  pLruNext==0 );. 
6cb0: 20 61 73 73 65 72 74 28 20 70 47 72 6f 75 70 2d   assert( pGroup-
6cc0: 3e 70 4c 72 75 48 65 61 64 21 3d 70 50 61 67 65  >pLruHead!=pPage
6cd0: 20 26 26 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75   && pGroup->pLru
6ce0: 54 61 69 6c 21 3d 70 50 61 67 65 20 29 3b 0a 0a  Tail!=pPage );..
6cf0: 20 20 69 66 28 20 72 65 75 73 65 55 6e 6c 69 6b    if( reuseUnlik
6d00: 65 6c 79 20 7c 7c 20 70 47 72 6f 75 70 2d 3e 6e  ely || pGroup->n
6d10: 43 75 72 72 65 6e 74 50 61 67 65 3e 70 47 72 6f  CurrentPage>pGro
6d20: 75 70 2d 3e 6e 4d 61 78 50 61 67 65 20 29 7b 0a  up->nMaxPage ){.
6d30: 20 20 20 20 70 63 61 63 68 65 31 52 65 6d 6f 76      pcache1Remov
6d40: 65 46 72 6f 6d 48 61 73 68 28 70 50 61 67 65 29  eFromHash(pPage)
6d50: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 46 72 65  ;.    pcache1Fre
6d60: 65 50 61 67 65 28 70 50 61 67 65 29 3b 0a 20 20  ePage(pPage);.  
6d70: 7d 65 6c 73 65 7b 0a 20 20 20 20 2f 2a 20 41 64  }else{.    /* Ad
6d80: 64 20 74 68 65 20 70 61 67 65 20 74 6f 20 74 68  d the page to th
6d90: 65 20 50 47 72 6f 75 70 20 4c 52 55 20 6c 69 73  e PGroup LRU lis
6da0: 74 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 70 47  t. */.    if( pG
6db0: 72 6f 75 70 2d 3e 70 4c 72 75 48 65 61 64 20 29  roup->pLruHead )
6dc0: 7b 0a 20 20 20 20 20 20 70 47 72 6f 75 70 2d 3e  {.      pGroup->
6dd0: 70 4c 72 75 48 65 61 64 2d 3e 70 4c 72 75 50 72  pLruHead->pLruPr
6de0: 65 76 20 3d 20 70 50 61 67 65 3b 0a 20 20 20 20  ev = pPage;.    
6df0: 20 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78    pPage->pLruNex
6e00: 74 20 3d 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75  t = pGroup->pLru
6e10: 48 65 61 64 3b 0a 20 20 20 20 20 20 70 47 72 6f  Head;.      pGro
6e20: 75 70 2d 3e 70 4c 72 75 48 65 61 64 20 3d 20 70  up->pLruHead = p
6e30: 50 61 67 65 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  Page;.    }else{
6e40: 0a 20 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 70  .      pGroup->p
6e50: 4c 72 75 54 61 69 6c 20 3d 20 70 50 61 67 65 3b  LruTail = pPage;
6e60: 0a 20 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 70  .      pGroup->p
6e70: 4c 72 75 48 65 61 64 20 3d 20 70 50 61 67 65 3b  LruHead = pPage;
6e80: 0a 20 20 20 20 7d 0a 20 20 20 20 70 43 61 63 68  .    }.    pCach
6e90: 65 2d 3e 6e 52 65 63 79 63 6c 61 62 6c 65 2b 2b  e->nRecyclable++
6ea0: 3b 0a 20 20 7d 0a 0a 20 20 70 63 61 63 68 65 31  ;.  }..  pcache1
6eb0: 4c 65 61 76 65 4d 75 74 65 78 28 70 43 61 63 68  LeaveMutex(pCach
6ec0: 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 7d 0a 0a 2f  e->pGroup);.}../
6ed0: 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74  *.** Implementat
6ee0: 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74  ion of the sqlit
6ef0: 65 33 5f 70 63 61 63 68 65 2e 78 52 65 6b 65 79  e3_pcache.xRekey
6f00: 20 6d 65 74 68 6f 64 2e 20 0a 2a 2f 0a 73 74 61   method. .*/.sta
6f10: 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 31  tic void pcache1
6f20: 52 65 6b 65 79 28 0a 20 20 73 71 6c 69 74 65 33  Rekey(.  sqlite3
6f30: 5f 70 63 61 63 68 65 20 2a 70 2c 0a 20 20 73 71  _pcache *p,.  sq
6f40: 6c 69 74 65 33 5f 70 63 61 63 68 65 5f 70 61 67  lite3_pcache_pag
6f50: 65 20 2a 70 50 67 2c 0a 20 20 75 6e 73 69 67 6e  e *pPg,.  unsign
6f60: 65 64 20 69 6e 74 20 69 4f 6c 64 2c 0a 20 20 75  ed int iOld,.  u
6f70: 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4e 65 77  nsigned int iNew
6f80: 0a 29 7b 0a 20 20 50 43 61 63 68 65 31 20 2a 70  .){.  PCache1 *p
6f90: 43 61 63 68 65 20 3d 20 28 50 43 61 63 68 65 31  Cache = (PCache1
6fa0: 20 2a 29 70 3b 0a 20 20 50 67 48 64 72 31 20 2a   *)p;.  PgHdr1 *
6fb0: 70 50 61 67 65 20 3d 20 28 50 67 48 64 72 31 20  pPage = (PgHdr1 
6fc0: 2a 29 70 50 67 3b 0a 20 20 50 67 48 64 72 31 20  *)pPg;.  PgHdr1 
6fd0: 2a 2a 70 70 3b 0a 20 20 75 6e 73 69 67 6e 65 64  **pp;.  unsigned
6fe0: 20 69 6e 74 20 68 3b 20 0a 20 20 61 73 73 65 72   int h; .  asser
6ff0: 74 28 20 70 50 61 67 65 2d 3e 69 4b 65 79 3d 3d  t( pPage->iKey==
7000: 69 4f 6c 64 20 29 3b 0a 20 20 61 73 73 65 72 74  iOld );.  assert
7010: 28 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65 3d  ( pPage->pCache=
7020: 3d 70 43 61 63 68 65 20 29 3b 0a 0a 20 20 70 63  =pCache );..  pc
7030: 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28  ache1EnterMutex(
7040: 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b  pCache->pGroup);
7050: 0a 0a 20 20 68 20 3d 20 69 4f 6c 64 25 70 43 61  ..  h = iOld%pCa
7060: 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 70 70  che->nHash;.  pp
7070: 20 3d 20 26 70 43 61 63 68 65 2d 3e 61 70 48 61   = &pCache->apHa
7080: 73 68 5b 68 5d 3b 0a 20 20 77 68 69 6c 65 28 20  sh[h];.  while( 
7090: 28 2a 70 70 29 21 3d 70 50 61 67 65 20 29 7b 0a  (*pp)!=pPage ){.
70a0: 20 20 20 20 70 70 20 3d 20 26 28 2a 70 70 29 2d      pp = &(*pp)-
70b0: 3e 70 4e 65 78 74 3b 0a 20 20 7d 0a 20 20 2a 70  >pNext;.  }.  *p
70c0: 70 20 3d 20 70 50 61 67 65 2d 3e 70 4e 65 78 74  p = pPage->pNext
70d0: 3b 0a 0a 20 20 68 20 3d 20 69 4e 65 77 25 70 43  ;..  h = iNew%pC
70e0: 61 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 70  ache->nHash;.  p
70f0: 50 61 67 65 2d 3e 69 4b 65 79 20 3d 20 69 4e 65  Page->iKey = iNe
7100: 77 3b 0a 20 20 70 50 61 67 65 2d 3e 70 4e 65 78  w;.  pPage->pNex
7110: 74 20 3d 20 70 43 61 63 68 65 2d 3e 61 70 48 61  t = pCache->apHa
7120: 73 68 5b 68 5d 3b 0a 20 20 70 43 61 63 68 65 2d  sh[h];.  pCache-
7130: 3e 61 70 48 61 73 68 5b 68 5d 20 3d 20 70 50 61  >apHash[h] = pPa
7140: 67 65 3b 0a 20 20 69 66 28 20 69 4e 65 77 3e 70  ge;.  if( iNew>p
7150: 43 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 29  Cache->iMaxKey )
7160: 7b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 69 4d  {.    pCache->iM
7170: 61 78 4b 65 79 20 3d 20 69 4e 65 77 3b 0a 20 20  axKey = iNew;.  
7180: 7d 0a 0a 20 20 70 63 61 63 68 65 31 4c 65 61 76  }..  pcache1Leav
7190: 65 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e 70  eMutex(pCache->p
71a0: 47 72 6f 75 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  Group);.}../*.**
71b0: 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20   Implementation 
71c0: 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70  of the sqlite3_p
71d0: 63 61 63 68 65 2e 78 54 72 75 6e 63 61 74 65 20  cache.xTruncate 
71e0: 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20 44  method. .**.** D
71f0: 69 73 63 61 72 64 20 61 6c 6c 20 75 6e 70 69 6e  iscard all unpin
7200: 6e 65 64 20 70 61 67 65 73 20 69 6e 20 74 68 65  ned pages in the
7210: 20 63 61 63 68 65 20 77 69 74 68 20 61 20 70 61   cache with a pa
7220: 67 65 20 6e 75 6d 62 65 72 20 65 71 75 61 6c 20  ge number equal 
7230: 74 6f 0a 2a 2a 20 6f 72 20 67 72 65 61 74 65 72  to.** or greater
7240: 20 74 68 61 6e 20 70 61 72 61 6d 65 74 65 72 20   than parameter 
7250: 69 4c 69 6d 69 74 2e 20 41 6e 79 20 70 69 6e 6e  iLimit. Any pinn
7260: 65 64 20 70 61 67 65 73 20 77 69 74 68 20 61 20  ed pages with a 
7270: 70 61 67 65 20 6e 75 6d 62 65 72 0a 2a 2a 20 65  page number.** e
7280: 71 75 61 6c 20 74 6f 20 6f 72 20 67 72 65 61 74  qual to or great
7290: 65 72 20 74 68 61 6e 20 69 4c 69 6d 69 74 20 61  er than iLimit a
72a0: 72 65 20 69 6d 70 6c 69 63 69 74 6c 79 20 75 6e  re implicitly un
72b0: 70 69 6e 6e 65 64 2e 0a 2a 2f 0a 73 74 61 74 69  pinned..*/.stati
72c0: 63 20 76 6f 69 64 20 70 63 61 63 68 65 31 54 72  c void pcache1Tr
72d0: 75 6e 63 61 74 65 28 73 71 6c 69 74 65 33 5f 70  uncate(sqlite3_p
72e0: 63 61 63 68 65 20 2a 70 2c 20 75 6e 73 69 67 6e  cache *p, unsign
72f0: 65 64 20 69 6e 74 20 69 4c 69 6d 69 74 29 7b 0a  ed int iLimit){.
7300: 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68    PCache1 *pCach
7310: 65 20 3d 20 28 50 43 61 63 68 65 31 20 2a 29 70  e = (PCache1 *)p
7320: 3b 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65 72  ;.  pcache1Enter
7330: 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e 70 47  Mutex(pCache->pG
7340: 72 6f 75 70 29 3b 0a 20 20 69 66 28 20 69 4c 69  roup);.  if( iLi
7350: 6d 69 74 3c 3d 70 43 61 63 68 65 2d 3e 69 4d 61  mit<=pCache->iMa
7360: 78 4b 65 79 20 29 7b 0a 20 20 20 20 70 63 61 63  xKey ){.    pcac
7370: 68 65 31 54 72 75 6e 63 61 74 65 55 6e 73 61 66  he1TruncateUnsaf
7380: 65 28 70 43 61 63 68 65 2c 20 69 4c 69 6d 69 74  e(pCache, iLimit
7390: 29 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 69  );.    pCache->i
73a0: 4d 61 78 4b 65 79 20 3d 20 69 4c 69 6d 69 74 2d  MaxKey = iLimit-
73b0: 31 3b 0a 20 20 7d 0a 20 20 70 63 61 63 68 65 31  1;.  }.  pcache1
73c0: 4c 65 61 76 65 4d 75 74 65 78 28 70 43 61 63 68  LeaveMutex(pCach
73d0: 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 7d 0a 0a 2f  e->pGroup);.}../
73e0: 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74  *.** Implementat
73f0: 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74  ion of the sqlit
7400: 65 33 5f 70 63 61 63 68 65 2e 78 44 65 73 74 72  e3_pcache.xDestr
7410: 6f 79 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a  oy method. .**.*
7420: 2a 20 44 65 73 74 72 6f 79 20 61 20 63 61 63 68  * Destroy a cach
7430: 65 20 61 6c 6c 6f 63 61 74 65 64 20 75 73 69 6e  e allocated usin
7440: 67 20 70 63 61 63 68 65 31 43 72 65 61 74 65 28  g pcache1Create(
7450: 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  )..*/.static voi
7460: 64 20 70 63 61 63 68 65 31 44 65 73 74 72 6f 79  d pcache1Destroy
7470: 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20  (sqlite3_pcache 
7480: 2a 70 29 7b 0a 20 20 50 43 61 63 68 65 31 20 2a  *p){.  PCache1 *
7490: 70 43 61 63 68 65 20 3d 20 28 50 43 61 63 68 65  pCache = (PCache
74a0: 31 20 2a 29 70 3b 0a 20 20 50 47 72 6f 75 70 20  1 *)p;.  PGroup 
74b0: 2a 70 47 72 6f 75 70 20 3d 20 70 43 61 63 68 65  *pGroup = pCache
74c0: 2d 3e 70 47 72 6f 75 70 3b 0a 20 20 61 73 73 65  ->pGroup;.  asse
74d0: 72 74 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72  rt( pCache->bPur
74e0: 67 65 61 62 6c 65 20 7c 7c 20 28 70 43 61 63 68  geable || (pCach
74f0: 65 2d 3e 6e 4d 61 78 3d 3d 30 20 26 26 20 70 43  e->nMax==0 && pC
7500: 61 63 68 65 2d 3e 6e 4d 69 6e 3d 3d 30 29 20 29  ache->nMin==0) )
7510: 3b 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65 72  ;.  pcache1Enter
7520: 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b 0a 20  Mutex(pGroup);. 
7530: 20 70 63 61 63 68 65 31 54 72 75 6e 63 61 74 65   pcache1Truncate
7540: 55 6e 73 61 66 65 28 70 43 61 63 68 65 2c 20 30  Unsafe(pCache, 0
7550: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 47 72  );.  assert( pGr
7560: 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65 20 3e 3d  oup->nMaxPage >=
7570: 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 20 29 3b   pCache->nMax );
7580: 0a 20 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50  .  pGroup->nMaxP
7590: 61 67 65 20 2d 3d 20 70 43 61 63 68 65 2d 3e 6e  age -= pCache->n
75a0: 4d 61 78 3b 0a 20 20 61 73 73 65 72 74 28 20 70  Max;.  assert( p
75b0: 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67 65 20  Group->nMinPage 
75c0: 3e 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 20  >= pCache->nMin 
75d0: 29 3b 0a 20 20 70 47 72 6f 75 70 2d 3e 6e 4d 69  );.  pGroup->nMi
75e0: 6e 50 61 67 65 20 2d 3d 20 70 43 61 63 68 65 2d  nPage -= pCache-
75f0: 3e 6e 4d 69 6e 3b 0a 20 20 70 47 72 6f 75 70 2d  >nMin;.  pGroup-
7600: 3e 6d 78 50 69 6e 6e 65 64 20 3d 20 70 47 72 6f  >mxPinned = pGro
7610: 75 70 2d 3e 6e 4d 61 78 50 61 67 65 20 2b 20 31  up->nMaxPage + 1
7620: 30 20 2d 20 70 47 72 6f 75 70 2d 3e 6e 4d 69 6e  0 - pGroup->nMin
7630: 50 61 67 65 3b 0a 20 20 70 63 61 63 68 65 31 45  Page;.  pcache1E
7640: 6e 66 6f 72 63 65 4d 61 78 50 61 67 65 28 70 47  nforceMaxPage(pG
7650: 72 6f 75 70 29 3b 0a 20 20 70 63 61 63 68 65 31  roup);.  pcache1
7660: 4c 65 61 76 65 4d 75 74 65 78 28 70 47 72 6f 75  LeaveMutex(pGrou
7670: 70 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72  p);.  sqlite3_fr
7680: 65 65 28 70 43 61 63 68 65 2d 3e 61 70 48 61 73  ee(pCache->apHas
7690: 68 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72  h);.  sqlite3_fr
76a0: 65 65 28 70 43 61 63 68 65 29 3b 0a 7d 0a 0a 2f  ee(pCache);.}../
76b0: 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69  *.** This functi
76c0: 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 64 75 72  on is called dur
76d0: 69 6e 67 20 69 6e 69 74 69 61 6c 69 7a 61 74 69  ing initializati
76e0: 6f 6e 20 28 73 71 6c 69 74 65 33 5f 69 6e 69 74  on (sqlite3_init
76f0: 69 61 6c 69 7a 65 28 29 29 20 74 6f 0a 2a 2a 20  ialize()) to.** 
7700: 69 6e 73 74 61 6c 6c 20 74 68 65 20 64 65 66 61  install the defa
7710: 75 6c 74 20 70 6c 75 67 67 61 62 6c 65 20 63 61  ult pluggable ca
7720: 63 68 65 20 6d 6f 64 75 6c 65 2c 20 61 73 73 75  che module, assu
7730: 6d 69 6e 67 20 74 68 65 20 75 73 65 72 20 68 61  ming the user ha
7740: 73 20 6e 6f 74 0a 2a 2a 20 61 6c 72 65 61 64 79  s not.** already
7750: 20 70 72 6f 76 69 64 65 64 20 61 6e 20 61 6c 74   provided an alt
7760: 65 72 6e 61 74 69 76 65 2e 0a 2a 2f 0a 76 6f 69  ernative..*/.voi
7770: 64 20 73 71 6c 69 74 65 33 50 43 61 63 68 65 53  d sqlite3PCacheS
7780: 65 74 44 65 66 61 75 6c 74 28 76 6f 69 64 29 7b  etDefault(void){
7790: 0a 20 20 73 74 61 74 69 63 20 63 6f 6e 73 74 20  .  static const 
77a0: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 5f 6d  sqlite3_pcache_m
77b0: 65 74 68 6f 64 73 32 20 64 65 66 61 75 6c 74 4d  ethods2 defaultM
77c0: 65 74 68 6f 64 73 20 3d 20 7b 0a 20 20 20 20 31  ethods = {.    1
77d0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
77e0: 20 20 20 20 20 20 20 20 2f 2a 20 69 56 65 72 73          /* iVers
77f0: 69 6f 6e 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20  ion */.    0,   
7800: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7810: 20 20 20 20 2f 2a 20 70 41 72 67 20 2a 2f 0a 20      /* pArg */. 
7820: 20 20 20 70 63 61 63 68 65 31 49 6e 69 74 2c 20     pcache1Init, 
7830: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
7840: 49 6e 69 74 20 2a 2f 0a 20 20 20 20 70 63 61 63  Init */.    pcac
7850: 68 65 31 53 68 75 74 64 6f 77 6e 2c 20 20 20 20  he1Shutdown,    
7860: 20 20 20 20 20 2f 2a 20 78 53 68 75 74 64 6f 77       /* xShutdow
7870: 6e 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31  n */.    pcache1
7880: 43 72 65 61 74 65 2c 20 20 20 20 20 20 20 20 20  Create,         
7890: 20 20 2f 2a 20 78 43 72 65 61 74 65 20 2a 2f 0a    /* xCreate */.
78a0: 20 20 20 20 70 63 61 63 68 65 31 43 61 63 68 65      pcache1Cache
78b0: 73 69 7a 65 2c 20 20 20 20 20 20 20 20 2f 2a 20  size,        /* 
78c0: 78 43 61 63 68 65 73 69 7a 65 20 2a 2f 0a 20 20  xCachesize */.  
78d0: 20 20 70 63 61 63 68 65 31 50 61 67 65 63 6f 75    pcache1Pagecou
78e0: 6e 74 2c 20 20 20 20 20 20 20 20 2f 2a 20 78 50  nt,        /* xP
78f0: 61 67 65 63 6f 75 6e 74 20 2a 2f 0a 20 20 20 20  agecount */.    
7900: 70 63 61 63 68 65 31 46 65 74 63 68 2c 20 20 20  pcache1Fetch,   
7910: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 46 65 74           /* xFet
7920: 63 68 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65  ch */.    pcache
7930: 31 55 6e 70 69 6e 2c 20 20 20 20 20 20 20 20 20  1Unpin,         
7940: 20 20 20 2f 2a 20 78 55 6e 70 69 6e 20 2a 2f 0a     /* xUnpin */.
7950: 20 20 20 20 70 63 61 63 68 65 31 52 65 6b 65 79      pcache1Rekey
7960: 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ,            /* 
7970: 78 52 65 6b 65 79 20 2a 2f 0a 20 20 20 20 70 63  xRekey */.    pc
7980: 61 63 68 65 31 54 72 75 6e 63 61 74 65 2c 20 20  ache1Truncate,  
7990: 20 20 20 20 20 20 20 2f 2a 20 78 54 72 75 6e 63         /* xTrunc
79a0: 61 74 65 20 2a 2f 0a 20 20 20 20 70 63 61 63 68  ate */.    pcach
79b0: 65 31 44 65 73 74 72 6f 79 2c 20 20 20 20 20 20  e1Destroy,      
79c0: 20 20 20 20 2f 2a 20 78 44 65 73 74 72 6f 79 20      /* xDestroy 
79d0: 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31 53 68  */.    pcache1Sh
79e0: 72 69 6e 6b 20 20 20 20 20 20 20 20 20 20 20 20  rink            
79f0: 2f 2a 20 78 53 68 72 69 6e 6b 20 2a 2f 0a 20 20  /* xShrink */.  
7a00: 7d 3b 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e  };.  sqlite3_con
7a10: 66 69 67 28 53 51 4c 49 54 45 5f 43 4f 4e 46 49  fig(SQLITE_CONFI
7a20: 47 5f 50 43 41 43 48 45 32 2c 20 26 64 65 66 61  G_PCACHE2, &defa
7a30: 75 6c 74 4d 65 74 68 6f 64 73 29 3b 0a 7d 0a 0a  ultMethods);.}..
7a40: 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 45 4e  #ifdef SQLITE_EN
7a50: 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41  ABLE_MEMORY_MANA
7a60: 47 45 4d 45 4e 54 0a 2f 2a 0a 2a 2a 20 54 68 69  GEMENT./*.** Thi
7a70: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61  s function is ca
7a80: 6c 6c 65 64 20 74 6f 20 66 72 65 65 20 73 75 70  lled to free sup
7a90: 65 72 66 6c 75 6f 75 73 20 64 79 6e 61 6d 69 63  erfluous dynamic
7aa0: 61 6c 6c 79 20 61 6c 6c 6f 63 61 74 65 64 20 6d  ally allocated m
7ab0: 65 6d 6f 72 79 0a 2a 2a 20 68 65 6c 64 20 62 79  emory.** held by
7ac0: 20 74 68 65 20 70 61 67 65 72 20 73 79 73 74 65   the pager syste
7ad0: 6d 2e 20 4d 65 6d 6f 72 79 20 69 6e 20 75 73 65  m. Memory in use
7ae0: 20 62 79 20 61 6e 79 20 53 51 4c 69 74 65 20 70   by any SQLite p
7af0: 61 67 65 72 20 61 6c 6c 6f 63 61 74 65 64 0a 2a  ager allocated.*
7b00: 2a 20 62 79 20 74 68 65 20 63 75 72 72 65 6e 74  * by the current
7b10: 20 74 68 72 65 61 64 20 6d 61 79 20 62 65 20 73   thread may be s
7b20: 71 6c 69 74 65 33 5f 66 72 65 65 28 29 65 64 2e  qlite3_free()ed.
7b30: 0a 2a 2a 0a 2a 2a 20 6e 52 65 71 20 69 73 20 74  .**.** nReq is t
7b40: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 62 79 74  he number of byt
7b50: 65 73 20 6f 66 20 6d 65 6d 6f 72 79 20 72 65 71  es of memory req
7b60: 75 69 72 65 64 2e 20 4f 6e 63 65 20 74 68 69 73  uired. Once this
7b70: 20 6d 75 63 68 20 68 61 73 0a 2a 2a 20 62 65 65   much has.** bee
7b80: 6e 20 72 65 6c 65 61 73 65 64 2c 20 74 68 65 20  n released, the 
7b90: 66 75 6e 63 74 69 6f 6e 20 72 65 74 75 72 6e 73  function returns
7ba0: 2e 20 54 68 65 20 72 65 74 75 72 6e 20 76 61 6c  . The return val
7bb0: 75 65 20 69 73 20 74 68 65 20 74 6f 74 61 6c 20  ue is the total 
7bc0: 6e 75 6d 62 65 72 20 0a 2a 2a 20 6f 66 20 62 79  number .** of by
7bd0: 74 65 73 20 6f 66 20 6d 65 6d 6f 72 79 20 72 65  tes of memory re
7be0: 6c 65 61 73 65 64 2e 0a 2a 2f 0a 69 6e 74 20 73  leased..*/.int s
7bf0: 71 6c 69 74 65 33 50 63 61 63 68 65 52 65 6c 65  qlite3PcacheRele
7c00: 61 73 65 4d 65 6d 6f 72 79 28 69 6e 74 20 6e 52  aseMemory(int nR
7c10: 65 71 29 7b 0a 20 20 69 6e 74 20 6e 46 72 65 65  eq){.  int nFree
7c20: 20 3d 20 30 3b 0a 20 20 61 73 73 65 72 74 28 20   = 0;.  assert( 
7c30: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6e 6f  sqlite3_mutex_no
7c40: 74 68 65 6c 64 28 70 63 61 63 68 65 31 2e 67 72  theld(pcache1.gr
7c50: 70 2e 6d 75 74 65 78 29 20 29 3b 0a 20 20 61 73  p.mutex) );.  as
7c60: 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75  sert( sqlite3_mu
7c70: 74 65 78 5f 6e 6f 74 68 65 6c 64 28 70 63 61 63  tex_notheld(pcac
7c80: 68 65 31 2e 6d 75 74 65 78 29 20 29 3b 0a 20 20  he1.mutex) );.  
7c90: 69 66 28 20 70 63 61 63 68 65 31 2e 70 53 74 61  if( pcache1.pSta
7ca0: 72 74 3d 3d 30 20 29 7b 0a 20 20 20 20 50 67 48  rt==0 ){.    PgH
7cb0: 64 72 31 20 2a 70 3b 0a 20 20 20 20 70 63 61 63  dr1 *p;.    pcac
7cc0: 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 26 70  he1EnterMutex(&p
7cd0: 63 61 63 68 65 31 2e 67 72 70 29 3b 0a 20 20 20  cache1.grp);.   
7ce0: 20 77 68 69 6c 65 28 20 28 6e 52 65 71 3c 30 20   while( (nReq<0 
7cf0: 7c 7c 20 6e 46 72 65 65 3c 6e 52 65 71 29 20 26  || nFree<nReq) &
7d00: 26 20 28 28 70 3d 70 63 61 63 68 65 31 2e 67 72  & ((p=pcache1.gr
7d10: 70 2e 70 4c 72 75 54 61 69 6c 29 21 3d 30 29 20  p.pLruTail)!=0) 
7d20: 29 7b 0a 20 20 20 20 20 20 6e 46 72 65 65 20 2b  ){.      nFree +
7d30: 3d 20 70 63 61 63 68 65 31 4d 65 6d 53 69 7a 65  = pcache1MemSize
7d40: 28 70 2d 3e 70 61 67 65 2e 70 42 75 66 29 3b 0a  (p->page.pBuf);.
7d50: 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 50 43  #ifdef SQLITE_PC
7d60: 41 43 48 45 5f 53 45 50 41 52 41 54 45 5f 48 45  ACHE_SEPARATE_HE
7d70: 41 44 45 52 0a 20 20 20 20 20 20 6e 46 72 65 65  ADER.      nFree
7d80: 20 2b 3d 20 73 71 6c 69 74 65 33 4d 65 6d 53 69   += sqlite3MemSi
7d90: 7a 65 28 70 29 3b 0a 23 65 6e 64 69 66 0a 20 20  ze(p);.#endif.  
7da0: 20 20 20 20 70 63 61 63 68 65 31 50 69 6e 50 61      pcache1PinPa
7db0: 67 65 28 70 29 3b 0a 20 20 20 20 20 20 70 63 61  ge(p);.      pca
7dc0: 63 68 65 31 52 65 6d 6f 76 65 46 72 6f 6d 48 61  che1RemoveFromHa
7dd0: 73 68 28 70 29 3b 0a 20 20 20 20 20 20 70 63 61  sh(p);.      pca
7de0: 63 68 65 31 46 72 65 65 50 61 67 65 28 70 29 3b  che1FreePage(p);
7df0: 0a 20 20 20 20 7d 0a 20 20 20 20 70 63 61 63 68  .    }.    pcach
7e00: 65 31 4c 65 61 76 65 4d 75 74 65 78 28 26 70 63  e1LeaveMutex(&pc
7e10: 61 63 68 65 31 2e 67 72 70 29 3b 0a 20 20 7d 0a  ache1.grp);.  }.
7e20: 20 20 72 65 74 75 72 6e 20 6e 46 72 65 65 3b 0a    return nFree;.
7e30: 7d 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49  }.#endif /* SQLI
7e40: 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59  TE_ENABLE_MEMORY
7e50: 5f 4d 41 4e 41 47 45 4d 45 4e 54 20 2a 2f 0a 0a  _MANAGEMENT */..
7e60: 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 54 45  #ifdef SQLITE_TE
7e70: 53 54 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75  ST./*.** This fu
7e80: 6e 63 74 69 6f 6e 20 69 73 20 75 73 65 64 20 62  nction is used b
7e90: 79 20 74 65 73 74 20 70 72 6f 63 65 64 75 72 65  y test procedure
7ea0: 73 20 74 6f 20 69 6e 73 70 65 63 74 20 74 68 65  s to inspect the
7eb0: 20 69 6e 74 65 72 6e 61 6c 20 73 74 61 74 65 0a   internal state.
7ec0: 2a 2a 20 6f 66 20 74 68 65 20 67 6c 6f 62 61 6c  ** of the global
7ed0: 20 63 61 63 68 65 2e 0a 2a 2f 0a 76 6f 69 64 20   cache..*/.void 
7ee0: 73 71 6c 69 74 65 33 50 63 61 63 68 65 53 74 61  sqlite3PcacheSta
7ef0: 74 73 28 0a 20 20 69 6e 74 20 2a 70 6e 43 75 72  ts(.  int *pnCur
7f00: 72 65 6e 74 2c 20 20 20 20 20 20 2f 2a 20 4f 55  rent,      /* OU
7f10: 54 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20  T: Total number 
7f20: 6f 66 20 70 61 67 65 73 20 63 61 63 68 65 64 20  of pages cached 
7f30: 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 4d 61 78 2c  */.  int *pnMax,
7f40: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
7f50: 3a 20 47 6c 6f 62 61 6c 20 6d 61 78 69 6d 75 6d  : Global maximum
7f60: 20 63 61 63 68 65 20 73 69 7a 65 20 2a 2f 0a 20   cache size */. 
7f70: 20 69 6e 74 20 2a 70 6e 4d 69 6e 2c 20 20 20 20   int *pnMin,    
7f80: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 53 75        /* OUT: Su
7f90: 6d 20 6f 66 20 50 43 61 63 68 65 31 2e 6e 4d 69  m of PCache1.nMi
7fa0: 6e 20 66 6f 72 20 70 75 72 67 65 61 62 6c 65 20  n for purgeable 
7fb0: 63 61 63 68 65 73 20 2a 2f 0a 20 20 69 6e 74 20  caches */.  int 
7fc0: 2a 70 6e 52 65 63 79 63 6c 61 62 6c 65 20 20 20  *pnRecyclable   
7fd0: 20 2f 2a 20 4f 55 54 3a 20 54 6f 74 61 6c 20 6e   /* OUT: Total n
7fe0: 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 61  umber of pages a
7ff0: 76 61 69 6c 61 62 6c 65 20 66 6f 72 20 72 65 63  vailable for rec
8000: 79 63 6c 69 6e 67 20 2a 2f 0a 29 7b 0a 20 20 50  ycling */.){.  P
8010: 67 48 64 72 31 20 2a 70 3b 0a 20 20 69 6e 74 20  gHdr1 *p;.  int 
8020: 6e 52 65 63 79 63 6c 61 62 6c 65 20 3d 20 30 3b  nRecyclable = 0;
8030: 0a 20 20 66 6f 72 28 70 3d 70 63 61 63 68 65 31  .  for(p=pcache1
8040: 2e 67 72 70 2e 70 4c 72 75 48 65 61 64 3b 20 70  .grp.pLruHead; p
8050: 3b 20 70 3d 70 2d 3e 70 4c 72 75 4e 65 78 74 29  ; p=p->pLruNext)
8060: 7b 0a 20 20 20 20 6e 52 65 63 79 63 6c 61 62 6c  {.    nRecyclabl
8070: 65 2b 2b 3b 0a 20 20 7d 0a 20 20 2a 70 6e 43 75  e++;.  }.  *pnCu
8080: 72 72 65 6e 74 20 3d 20 70 63 61 63 68 65 31 2e  rrent = pcache1.
8090: 67 72 70 2e 6e 43 75 72 72 65 6e 74 50 61 67 65  grp.nCurrentPage
80a0: 3b 0a 20 20 2a 70 6e 4d 61 78 20 3d 20 28 69 6e  ;.  *pnMax = (in
80b0: 74 29 70 63 61 63 68 65 31 2e 67 72 70 2e 6e 4d  t)pcache1.grp.nM
80c0: 61 78 50 61 67 65 3b 0a 20 20 2a 70 6e 4d 69 6e  axPage;.  *pnMin
80d0: 20 3d 20 28 69 6e 74 29 70 63 61 63 68 65 31 2e   = (int)pcache1.
80e0: 67 72 70 2e 6e 4d 69 6e 50 61 67 65 3b 0a 20 20  grp.nMinPage;.  
80f0: 2a 70 6e 52 65 63 79 63 6c 61 62 6c 65 20 3d 20  *pnRecyclable = 
8100: 6e 52 65 63 79 63 6c 61 62 6c 65 3b 0a 7d 0a 23  nRecyclable;.}.#
8110: 65 6e 64 69 66 0a                                endif.