/ Hex Artifact Content
Login

Artifact 57fee9a9a617218f5037afbbe49b09da65bde56b:


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 75 38 20 69 73 50 69 6e 6e 65 64  */.  u8 isPinned
10a0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
10b0: 20 20 20 20 2f 2a 20 50 61 67 65 20 69 6e 20 75      /* Page in u
10c0: 73 65 2c 20 6e 6f 74 20 6f 6e 20 74 68 65 20 4c  se, not on the L
10d0: 52 55 20 6c 69 73 74 20 2a 2f 0a 20 20 50 67 48  RU list */.  PgH
10e0: 64 72 31 20 2a 70 4e 65 78 74 3b 20 20 20 20 20  dr1 *pNext;     
10f0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
1100: 65 78 74 20 69 6e 20 68 61 73 68 20 74 61 62 6c  ext in hash tabl
1110: 65 20 63 68 61 69 6e 20 2a 2f 0a 20 20 50 43 61  e chain */.  PCa
1120: 63 68 65 31 20 2a 70 43 61 63 68 65 3b 20 20 20  che1 *pCache;   
1130: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
1140: 61 63 68 65 20 74 68 61 74 20 63 75 72 72 65 6e  ache that curren
1150: 74 6c 79 20 6f 77 6e 73 20 74 68 69 73 20 70 61  tly owns this pa
1160: 67 65 20 2a 2f 0a 20 20 50 67 48 64 72 31 20 2a  ge */.  PgHdr1 *
1170: 70 4c 72 75 4e 65 78 74 3b 20 20 20 20 20 20 20  pLruNext;       
1180: 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 69         /* Next i
1190: 6e 20 4c 52 55 20 6c 69 73 74 20 6f 66 20 75 6e  n LRU list of un
11a0: 70 69 6e 6e 65 64 20 70 61 67 65 73 20 2a 2f 0a  pinned pages */.
11b0: 20 20 50 67 48 64 72 31 20 2a 70 4c 72 75 50 72    PgHdr1 *pLruPr
11c0: 65 76 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ev;             
11d0: 20 2f 2a 20 50 72 65 76 69 6f 75 73 20 69 6e 20   /* Previous in 
11e0: 4c 52 55 20 6c 69 73 74 20 6f 66 20 75 6e 70 69  LRU list of unpi
11f0: 6e 6e 65 64 20 70 61 67 65 73 20 2a 2f 0a 7d 3b  nned pages */.};
1200: 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 73 6c 6f  ../*.** Free slo
1210: 74 73 20 69 6e 20 74 68 65 20 61 6c 6c 6f 63 61  ts in the alloca
1220: 74 6f 72 20 75 73 65 64 20 74 6f 20 64 69 76 69  tor used to divi
1230: 64 65 20 75 70 20 74 68 65 20 62 75 66 66 65 72  de up the buffer
1240: 20 70 72 6f 76 69 64 65 64 20 75 73 69 6e 67 0a   provided using.
1250: 2a 2a 20 74 68 65 20 53 51 4c 49 54 45 5f 43 4f  ** the SQLITE_CO
1260: 4e 46 49 47 5f 50 41 47 45 43 41 43 48 45 20 6d  NFIG_PAGECACHE m
1270: 65 63 68 61 6e 69 73 6d 2e 0a 2a 2f 0a 73 74 72  echanism..*/.str
1280: 75 63 74 20 50 67 46 72 65 65 73 6c 6f 74 20 7b  uct PgFreeslot {
1290: 0a 20 20 50 67 46 72 65 65 73 6c 6f 74 20 2a 70  .  PgFreeslot *p
12a0: 4e 65 78 74 3b 20 20 2f 2a 20 4e 65 78 74 20 66  Next;  /* Next f
12b0: 72 65 65 20 73 6c 6f 74 20 2a 2f 0a 7d 3b 0a 0a  ree slot */.};..
12c0: 2f 2a 0a 2a 2a 20 47 6c 6f 62 61 6c 20 64 61 74  /*.** Global dat
12d0: 61 20 75 73 65 64 20 62 79 20 74 68 69 73 20 63  a used by this c
12e0: 61 63 68 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ache..*/.static 
12f0: 53 51 4c 49 54 45 5f 57 53 44 20 73 74 72 75 63  SQLITE_WSD struc
1300: 74 20 50 43 61 63 68 65 47 6c 6f 62 61 6c 20 7b  t PCacheGlobal {
1310: 0a 20 20 50 47 72 6f 75 70 20 67 72 70 3b 20 20  .  PGroup grp;  
1320: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1330: 20 20 2f 2a 20 54 68 65 20 67 6c 6f 62 61 6c 20    /* The global 
1340: 50 47 72 6f 75 70 20 66 6f 72 20 6d 6f 64 65 20  PGroup for mode 
1350: 28 32 29 20 2a 2f 0a 0a 20 20 2f 2a 20 56 61 72  (2) */..  /* Var
1360: 69 61 62 6c 65 73 20 72 65 6c 61 74 65 64 20 74  iables related t
1370: 6f 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f  o SQLITE_CONFIG_
1380: 50 41 47 45 43 41 43 48 45 20 73 65 74 74 69 6e  PAGECACHE settin
1390: 67 73 2e 20 20 54 68 65 0a 20 20 2a 2a 20 73 7a  gs.  The.  ** sz
13a0: 53 6c 6f 74 2c 20 6e 53 6c 6f 74 2c 20 70 53 74  Slot, nSlot, pSt
13b0: 61 72 74 2c 20 70 45 6e 64 2c 20 6e 52 65 73 65  art, pEnd, nRese
13c0: 72 76 65 2c 20 61 6e 64 20 69 73 49 6e 69 74 20  rve, and isInit 
13d0: 76 61 6c 75 65 73 20 61 72 65 20 61 6c 6c 0a 20  values are all. 
13e0: 20 2a 2a 20 66 69 78 65 64 20 61 74 20 73 71 6c   ** fixed at sql
13f0: 69 74 65 33 5f 69 6e 69 74 69 61 6c 69 7a 65 28  ite3_initialize(
1400: 29 20 74 69 6d 65 20 61 6e 64 20 64 6f 20 6e 6f  ) time and do no
1410: 74 20 72 65 71 75 69 72 65 20 6d 75 74 65 78 20  t require mutex 
1420: 70 72 6f 74 65 63 74 69 6f 6e 2e 0a 20 20 2a 2a  protection..  **
1430: 20 54 68 65 20 6e 46 72 65 65 53 6c 6f 74 20 61   The nFreeSlot a
1440: 6e 64 20 70 46 72 65 65 20 76 61 6c 75 65 73 20  nd pFree values 
1450: 64 6f 20 72 65 71 75 69 72 65 20 6d 75 74 65 78  do require mutex
1460: 20 70 72 6f 74 65 63 74 69 6f 6e 2e 0a 20 20 2a   protection..  *
1470: 2f 0a 20 20 69 6e 74 20 69 73 49 6e 69 74 3b 20  /.  int isInit; 
1480: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1490: 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 69 6e     /* True if in
14a0: 69 74 69 61 6c 69 7a 65 64 20 2a 2f 0a 20 20 69  itialized */.  i
14b0: 6e 74 20 73 7a 53 6c 6f 74 3b 20 20 20 20 20 20  nt szSlot;      
14c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
14d0: 20 53 69 7a 65 20 6f 66 20 65 61 63 68 20 66 72   Size of each fr
14e0: 65 65 20 73 6c 6f 74 20 2a 2f 0a 20 20 69 6e 74  ee slot */.  int
14f0: 20 6e 53 6c 6f 74 3b 20 20 20 20 20 20 20 20 20   nSlot;         
1500: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
1510: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 63 61  he number of pca
1520: 63 68 65 20 73 6c 6f 74 73 20 2a 2f 0a 20 20 69  che slots */.  i
1530: 6e 74 20 6e 52 65 73 65 72 76 65 3b 20 20 20 20  nt nReserve;    
1540: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1550: 20 54 72 79 20 74 6f 20 6b 65 65 70 20 6e 46 72   Try to keep nFr
1560: 65 65 53 6c 6f 74 20 61 62 6f 76 65 20 74 68 69  eeSlot above thi
1570: 73 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 53 74  s */.  void *pSt
1580: 61 72 74 2c 20 2a 70 45 6e 64 3b 20 20 20 20 20  art, *pEnd;     
1590: 20 20 20 20 20 20 2f 2a 20 42 6f 75 6e 64 73 20        /* Bounds 
15a0: 6f 66 20 70 61 67 65 63 61 63 68 65 20 6d 61 6c  of pagecache mal
15b0: 6c 6f 63 20 72 61 6e 67 65 20 2a 2f 0a 20 20 2f  loc range */.  /
15c0: 2a 20 41 62 6f 76 65 20 72 65 71 75 69 72 65 73  * Above requires
15d0: 20 6e 6f 20 6d 75 74 65 78 2e 20 20 55 73 65 20   no mutex.  Use 
15e0: 6d 75 74 65 78 20 62 65 6c 6f 77 20 66 6f 72 20  mutex below for 
15f0: 76 61 72 69 61 62 6c 65 20 74 68 61 74 20 66 6f  variable that fo
1600: 6c 6c 6f 77 2e 20 2a 2f 0a 20 20 73 71 6c 69 74  llow. */.  sqlit
1610: 65 33 5f 6d 75 74 65 78 20 2a 6d 75 74 65 78 3b  e3_mutex *mutex;
1620: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 75 74            /* Mut
1630: 65 78 20 66 6f 72 20 61 63 63 65 73 73 69 6e 67  ex for accessing
1640: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 3a 20   the following: 
1650: 2a 2f 0a 20 20 50 67 46 72 65 65 73 6c 6f 74 20  */.  PgFreeslot 
1660: 2a 70 46 72 65 65 3b 20 20 20 20 20 20 20 20 20  *pFree;         
1670: 20 20 20 20 2f 2a 20 46 72 65 65 20 70 61 67 65      /* Free page
1680: 20 62 6c 6f 63 6b 73 20 2a 2f 0a 20 20 69 6e 74   blocks */.  int
1690: 20 6e 46 72 65 65 53 6c 6f 74 3b 20 20 20 20 20   nFreeSlot;     
16a0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
16b0: 75 6d 62 65 72 20 6f 66 20 75 6e 75 73 65 64 20  umber of unused 
16c0: 70 63 61 63 68 65 20 73 6c 6f 74 73 20 2a 2f 0a  pcache slots */.
16d0: 20 20 2f 2a 20 54 68 65 20 66 6f 6c 6c 6f 77 69    /* The followi
16e0: 6e 67 20 76 61 6c 75 65 20 72 65 71 75 69 72 65  ng value require
16f0: 73 20 61 20 6d 75 74 65 78 20 74 6f 20 63 68 61  s a mutex to cha
1700: 6e 67 65 2e 20 20 57 65 20 73 6b 69 70 20 74 68  nge.  We skip th
1710: 65 20 6d 75 74 65 78 20 6f 6e 0a 20 20 2a 2a 20  e mutex on.  ** 
1720: 72 65 61 64 69 6e 67 20 62 65 63 61 75 73 65 20  reading because 
1730: 28 31 29 20 6d 6f 73 74 20 70 6c 61 74 66 6f 72  (1) most platfor
1740: 6d 73 20 72 65 61 64 20 61 20 33 32 2d 62 69 74  ms read a 32-bit
1750: 20 69 6e 74 65 67 65 72 20 61 74 6f 6d 69 63 61   integer atomica
1760: 6c 6c 79 20 61 6e 64 0a 20 20 2a 2a 20 28 32 29  lly and.  ** (2)
1770: 20 65 76 65 6e 20 69 66 20 61 6e 20 69 6e 63 6f   even if an inco
1780: 72 72 65 63 74 20 76 61 6c 75 65 20 69 73 20 72  rrect value is r
1790: 65 61 64 2c 20 6e 6f 20 67 72 65 61 74 20 68 61  ead, no great ha
17a0: 72 6d 20 69 73 20 64 6f 6e 65 20 73 69 6e 63 65  rm is done since
17b0: 20 74 68 69 73 0a 20 20 2a 2a 20 69 73 20 72 65   this.  ** is re
17c0: 61 6c 6c 79 20 6a 75 73 74 20 61 6e 20 6f 70 74  ally just an opt
17d0: 69 6d 69 7a 61 74 69 6f 6e 2e 20 2a 2f 0a 20 20  imization. */.  
17e0: 69 6e 74 20 62 55 6e 64 65 72 50 72 65 73 73 75  int bUnderPressu
17f0: 72 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f  re;            /
1800: 2a 20 54 72 75 65 20 69 66 20 6c 6f 77 20 6f 6e  * True if low on
1810: 20 50 41 47 45 43 41 43 48 45 20 6d 65 6d 6f 72   PAGECACHE memor
1820: 79 20 2a 2f 0a 7d 20 70 63 61 63 68 65 31 5f 67  y */.} pcache1_g
1830: 3b 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c 20 63 6f 64  ;../*.** All cod
1840: 65 20 69 6e 20 74 68 69 73 20 66 69 6c 65 20 73  e in this file s
1850: 68 6f 75 6c 64 20 61 63 63 65 73 73 20 74 68 65  hould access the
1860: 20 67 6c 6f 62 61 6c 20 73 74 72 75 63 74 75 72   global structur
1870: 65 20 61 62 6f 76 65 20 76 69 61 20 74 68 65 0a  e above via the.
1880: 2a 2a 20 61 6c 69 61 73 20 22 70 63 61 63 68 65  ** alias "pcache
1890: 31 22 2e 20 54 68 69 73 20 65 6e 73 75 72 65 73  1". This ensures
18a0: 20 74 68 61 74 20 74 68 65 20 57 53 44 20 65 6d   that the WSD em
18b0: 75 6c 61 74 69 6f 6e 20 69 73 20 75 73 65 64 20  ulation is used 
18c0: 77 68 65 6e 0a 2a 2a 20 63 6f 6d 70 69 6c 69 6e  when.** compilin
18d0: 67 20 66 6f 72 20 73 79 73 74 65 6d 73 20 74 68  g for systems th
18e0: 61 74 20 64 6f 20 6e 6f 74 20 73 75 70 70 6f 72  at do not suppor
18f0: 74 20 72 65 61 6c 20 57 53 44 2e 0a 2a 2f 0a 23  t real WSD..*/.#
1900: 64 65 66 69 6e 65 20 70 63 61 63 68 65 31 20 28  define pcache1 (
1910: 47 4c 4f 42 41 4c 28 73 74 72 75 63 74 20 50 43  GLOBAL(struct PC
1920: 61 63 68 65 47 6c 6f 62 61 6c 2c 20 70 63 61 63  acheGlobal, pcac
1930: 68 65 31 5f 67 29 29 0a 0a 2f 2a 0a 2a 2a 20 4d  he1_g))../*.** M
1940: 61 63 72 6f 73 20 74 6f 20 65 6e 74 65 72 20 61  acros to enter a
1950: 6e 64 20 6c 65 61 76 65 20 74 68 65 20 50 43 61  nd leave the PCa
1960: 63 68 65 20 4c 52 55 20 6d 75 74 65 78 2e 0a 2a  che LRU mutex..*
1970: 2f 0a 23 64 65 66 69 6e 65 20 70 63 61 63 68 65  /.#define pcache
1980: 31 45 6e 74 65 72 4d 75 74 65 78 28 58 29 20 73  1EnterMutex(X) s
1990: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e 74  qlite3_mutex_ent
19a0: 65 72 28 28 58 29 2d 3e 6d 75 74 65 78 29 0a 23  er((X)->mutex).#
19b0: 64 65 66 69 6e 65 20 70 63 61 63 68 65 31 4c 65  define pcache1Le
19c0: 61 76 65 4d 75 74 65 78 28 58 29 20 73 71 6c 69  aveMutex(X) sqli
19d0: 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28  te3_mutex_leave(
19e0: 28 58 29 2d 3e 6d 75 74 65 78 29 0a 0a 2f 2a 2a  (X)->mutex)../**
19f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1a00: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1a10: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1a20: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1a30: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a  ************/./*
1a40: 2a 2a 2a 2a 2a 2a 2a 20 50 61 67 65 20 41 6c 6c  ******* Page All
1a50: 6f 63 61 74 69 6f 6e 2f 53 51 4c 49 54 45 5f 43  ocation/SQLITE_C
1a60: 4f 4e 46 49 47 5f 50 43 41 43 48 45 20 52 65 6c  ONFIG_PCACHE Rel
1a70: 61 74 65 64 20 46 75 6e 63 74 69 6f 6e 73 20 2a  ated Functions *
1a80: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a  *************/..
1a90: 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  /*.** This funct
1aa0: 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 64 75  ion is called du
1ab0: 72 69 6e 67 20 69 6e 69 74 69 61 6c 69 7a 61 74  ring initializat
1ac0: 69 6f 6e 20 69 66 20 61 20 73 74 61 74 69 63 20  ion if a static 
1ad0: 62 75 66 66 65 72 20 69 73 20 0a 2a 2a 20 73 75  buffer is .** su
1ae0: 70 70 6c 69 65 64 20 74 6f 20 75 73 65 20 66 6f  pplied to use fo
1af0: 72 20 74 68 65 20 70 61 67 65 2d 63 61 63 68 65  r the page-cache
1b00: 20 62 79 20 70 61 73 73 69 6e 67 20 74 68 65 20   by passing the 
1b10: 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41  SQLITE_CONFIG_PA
1b20: 47 45 43 41 43 48 45 0a 2a 2a 20 76 65 72 62 20  GECACHE.** verb 
1b30: 74 6f 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69  to sqlite3_confi
1b40: 67 28 29 2e 20 50 61 72 61 6d 65 74 65 72 20 70  g(). Parameter p
1b50: 42 75 66 20 70 6f 69 6e 74 73 20 74 6f 20 61 6e  Buf points to an
1b60: 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 6c 61 72 67   allocation larg
1b70: 65 0a 2a 2a 20 65 6e 6f 75 67 68 20 74 6f 20 63  e.** enough to c
1b80: 6f 6e 74 61 69 6e 20 27 6e 27 20 62 75 66 66 65  ontain 'n' buffe
1b90: 72 73 20 6f 66 20 27 73 7a 27 20 62 79 74 65 73  rs of 'sz' bytes
1ba0: 20 65 61 63 68 2e 0a 2a 2a 0a 2a 2a 20 54 68 69   each..**.** Thi
1bb0: 73 20 72 6f 75 74 69 6e 65 20 69 73 20 63 61 6c  s routine is cal
1bc0: 6c 65 64 20 66 72 6f 6d 20 73 71 6c 69 74 65 33  led from sqlite3
1bd0: 5f 69 6e 69 74 69 61 6c 69 7a 65 28 29 20 61 6e  _initialize() an
1be0: 64 20 73 6f 20 69 74 20 69 73 20 67 75 61 72 61  d so it is guara
1bf0: 6e 74 65 65 64 0a 2a 2a 20 74 6f 20 62 65 20 73  nteed.** to be s
1c00: 65 72 69 61 6c 69 7a 65 64 20 61 6c 72 65 61 64  erialized alread
1c10: 79 2e 20 20 54 68 65 72 65 20 69 73 20 6e 6f 20  y.  There is no 
1c20: 6e 65 65 64 20 66 6f 72 20 66 75 72 74 68 65 72  need for further
1c30: 20 6d 75 74 65 78 69 6e 67 2e 0a 2a 2f 0a 76 6f   mutexing..*/.vo
1c40: 69 64 20 73 71 6c 69 74 65 33 50 43 61 63 68 65  id sqlite3PCache
1c50: 42 75 66 66 65 72 53 65 74 75 70 28 76 6f 69 64  BufferSetup(void
1c60: 20 2a 70 42 75 66 2c 20 69 6e 74 20 73 7a 2c 20   *pBuf, int sz, 
1c70: 69 6e 74 20 6e 29 7b 0a 20 20 69 66 28 20 70 63  int n){.  if( pc
1c80: 61 63 68 65 31 2e 69 73 49 6e 69 74 20 29 7b 0a  ache1.isInit ){.
1c90: 20 20 20 20 50 67 46 72 65 65 73 6c 6f 74 20 2a      PgFreeslot *
1ca0: 70 3b 0a 20 20 20 20 73 7a 20 3d 20 52 4f 55 4e  p;.    sz = ROUN
1cb0: 44 44 4f 57 4e 38 28 73 7a 29 3b 0a 20 20 20 20  DDOWN8(sz);.    
1cc0: 70 63 61 63 68 65 31 2e 73 7a 53 6c 6f 74 20 3d  pcache1.szSlot =
1cd0: 20 73 7a 3b 0a 20 20 20 20 70 63 61 63 68 65 31   sz;.    pcache1
1ce0: 2e 6e 53 6c 6f 74 20 3d 20 70 63 61 63 68 65 31  .nSlot = pcache1
1cf0: 2e 6e 46 72 65 65 53 6c 6f 74 20 3d 20 6e 3b 0a  .nFreeSlot = n;.
1d00: 20 20 20 20 70 63 61 63 68 65 31 2e 6e 52 65 73      pcache1.nRes
1d10: 65 72 76 65 20 3d 20 6e 3e 39 30 20 3f 20 31 30  erve = n>90 ? 10
1d20: 20 3a 20 28 6e 2f 31 30 20 2b 20 31 29 3b 0a 20   : (n/10 + 1);. 
1d30: 20 20 20 70 63 61 63 68 65 31 2e 70 53 74 61 72     pcache1.pStar
1d40: 74 20 3d 20 70 42 75 66 3b 0a 20 20 20 20 70 63  t = pBuf;.    pc
1d50: 61 63 68 65 31 2e 70 46 72 65 65 20 3d 20 30 3b  ache1.pFree = 0;
1d60: 0a 20 20 20 20 70 63 61 63 68 65 31 2e 62 55 6e  .    pcache1.bUn
1d70: 64 65 72 50 72 65 73 73 75 72 65 20 3d 20 30 3b  derPressure = 0;
1d80: 0a 20 20 20 20 77 68 69 6c 65 28 20 6e 2d 2d 20  .    while( n-- 
1d90: 29 7b 0a 20 20 20 20 20 20 70 20 3d 20 28 50 67  ){.      p = (Pg
1da0: 46 72 65 65 73 6c 6f 74 2a 29 70 42 75 66 3b 0a  Freeslot*)pBuf;.
1db0: 20 20 20 20 20 20 70 2d 3e 70 4e 65 78 74 20 3d        p->pNext =
1dc0: 20 70 63 61 63 68 65 31 2e 70 46 72 65 65 3b 0a   pcache1.pFree;.
1dd0: 20 20 20 20 20 20 70 63 61 63 68 65 31 2e 70 46        pcache1.pF
1de0: 72 65 65 20 3d 20 70 3b 0a 20 20 20 20 20 20 70  ree = p;.      p
1df0: 42 75 66 20 3d 20 28 76 6f 69 64 2a 29 26 28 28  Buf = (void*)&((
1e00: 63 68 61 72 2a 29 70 42 75 66 29 5b 73 7a 5d 3b  char*)pBuf)[sz];
1e10: 0a 20 20 20 20 7d 0a 20 20 20 20 70 63 61 63 68  .    }.    pcach
1e20: 65 31 2e 70 45 6e 64 20 3d 20 70 42 75 66 3b 0a  e1.pEnd = pBuf;.
1e30: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6c    }.}../*.** Mal
1e40: 6c 6f 63 20 66 75 6e 63 74 69 6f 6e 20 75 73 65  loc function use
1e50: 64 20 77 69 74 68 69 6e 20 74 68 69 73 20 66 69  d within this fi
1e60: 6c 65 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 73  le to allocate s
1e70: 70 61 63 65 20 66 72 6f 6d 20 74 68 65 20 62 75  pace from the bu
1e80: 66 66 65 72 0a 2a 2a 20 63 6f 6e 66 69 67 75 72  ffer.** configur
1e90: 65 64 20 75 73 69 6e 67 20 73 71 6c 69 74 65 33  ed using sqlite3
1ea0: 5f 63 6f 6e 66 69 67 28 53 51 4c 49 54 45 5f 43  _config(SQLITE_C
1eb0: 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48 45 29  ONFIG_PAGECACHE)
1ec0: 20 6f 70 74 69 6f 6e 2e 20 49 66 20 6e 6f 20 0a   option. If no .
1ed0: 2a 2a 20 73 75 63 68 20 62 75 66 66 65 72 20 65  ** such buffer e
1ee0: 78 69 73 74 73 20 6f 72 20 74 68 65 72 65 20 69  xists or there i
1ef0: 73 20 6e 6f 20 73 70 61 63 65 20 6c 65 66 74 20  s no space left 
1f00: 69 6e 20 69 74 2c 20 74 68 69 73 20 66 75 6e 63  in it, this func
1f10: 74 69 6f 6e 20 66 61 6c 6c 73 20 0a 2a 2a 20 62  tion falls .** b
1f20: 61 63 6b 20 74 6f 20 73 71 6c 69 74 65 33 4d 61  ack to sqlite3Ma
1f30: 6c 6c 6f 63 28 29 2e 0a 2a 2a 0a 2a 2a 20 4d 75  lloc()..**.** Mu
1f40: 6c 74 69 70 6c 65 20 74 68 72 65 61 64 73 20 63  ltiple threads c
1f50: 61 6e 20 72 75 6e 20 74 68 69 73 20 72 6f 75 74  an run this rout
1f60: 69 6e 65 20 61 74 20 74 68 65 20 73 61 6d 65 20  ine at the same 
1f70: 74 69 6d 65 2e 20 20 47 6c 6f 62 61 6c 20 76 61  time.  Global va
1f80: 72 69 61 62 6c 65 73 0a 2a 2a 20 69 6e 20 70 63  riables.** in pc
1f90: 61 63 68 65 31 20 6e 65 65 64 20 74 6f 20 62 65  ache1 need to be
1fa0: 20 70 72 6f 74 65 63 74 65 64 20 76 69 61 20 6d   protected via m
1fb0: 75 74 65 78 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  utex..*/.static 
1fc0: 76 6f 69 64 20 2a 70 63 61 63 68 65 31 41 6c 6c  void *pcache1All
1fd0: 6f 63 28 69 6e 74 20 6e 42 79 74 65 29 7b 0a 20  oc(int nByte){. 
1fe0: 20 76 6f 69 64 20 2a 70 20 3d 20 30 3b 0a 20 20   void *p = 0;.  
1ff0: 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f  assert( sqlite3_
2000: 6d 75 74 65 78 5f 6e 6f 74 68 65 6c 64 28 70 63  mutex_notheld(pc
2010: 61 63 68 65 31 2e 67 72 70 2e 6d 75 74 65 78 29  ache1.grp.mutex)
2020: 20 29 3b 0a 20 20 73 71 6c 69 74 65 33 53 74 61   );.  sqlite3Sta
2030: 74 75 73 53 65 74 28 53 51 4c 49 54 45 5f 53 54  tusSet(SQLITE_ST
2040: 41 54 55 53 5f 50 41 47 45 43 41 43 48 45 5f 53  ATUS_PAGECACHE_S
2050: 49 5a 45 2c 20 6e 42 79 74 65 29 3b 0a 20 20 69  IZE, nByte);.  i
2060: 66 28 20 6e 42 79 74 65 3c 3d 70 63 61 63 68 65  f( nByte<=pcache
2070: 31 2e 73 7a 53 6c 6f 74 20 29 7b 0a 20 20 20 20  1.szSlot ){.    
2080: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e  sqlite3_mutex_en
2090: 74 65 72 28 70 63 61 63 68 65 31 2e 6d 75 74 65  ter(pcache1.mute
20a0: 78 29 3b 0a 20 20 20 20 70 20 3d 20 28 50 67 48  x);.    p = (PgH
20b0: 64 72 31 20 2a 29 70 63 61 63 68 65 31 2e 70 46  dr1 *)pcache1.pF
20c0: 72 65 65 3b 0a 20 20 20 20 69 66 28 20 70 20 29  ree;.    if( p )
20d0: 7b 0a 20 20 20 20 20 20 70 63 61 63 68 65 31 2e  {.      pcache1.
20e0: 70 46 72 65 65 20 3d 20 70 63 61 63 68 65 31 2e  pFree = pcache1.
20f0: 70 46 72 65 65 2d 3e 70 4e 65 78 74 3b 0a 20 20  pFree->pNext;.  
2100: 20 20 20 20 70 63 61 63 68 65 31 2e 6e 46 72 65      pcache1.nFre
2110: 65 53 6c 6f 74 2d 2d 3b 0a 20 20 20 20 20 20 70  eSlot--;.      p
2120: 63 61 63 68 65 31 2e 62 55 6e 64 65 72 50 72 65  cache1.bUnderPre
2130: 73 73 75 72 65 20 3d 20 70 63 61 63 68 65 31 2e  ssure = pcache1.
2140: 6e 46 72 65 65 53 6c 6f 74 3c 70 63 61 63 68 65  nFreeSlot<pcache
2150: 31 2e 6e 52 65 73 65 72 76 65 3b 0a 20 20 20 20  1.nReserve;.    
2160: 20 20 61 73 73 65 72 74 28 20 70 63 61 63 68 65    assert( pcache
2170: 31 2e 6e 46 72 65 65 53 6c 6f 74 3e 3d 30 20 29  1.nFreeSlot>=0 )
2180: 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 53  ;.      sqlite3S
2190: 74 61 74 75 73 41 64 64 28 53 51 4c 49 54 45 5f  tatusAdd(SQLITE_
21a0: 53 54 41 54 55 53 5f 50 41 47 45 43 41 43 48 45  STATUS_PAGECACHE
21b0: 5f 55 53 45 44 2c 20 31 29 3b 0a 20 20 20 20 7d  _USED, 1);.    }
21c0: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 75 74  .    sqlite3_mut
21d0: 65 78 5f 6c 65 61 76 65 28 70 63 61 63 68 65 31  ex_leave(pcache1
21e0: 2e 6d 75 74 65 78 29 3b 0a 20 20 7d 0a 20 20 69  .mutex);.  }.  i
21f0: 66 28 20 70 3d 3d 30 20 29 7b 0a 20 20 20 20 2f  f( p==0 ){.    /
2200: 2a 20 4d 65 6d 6f 72 79 20 69 73 20 6e 6f 74 20  * Memory is not 
2210: 61 76 61 69 6c 61 62 6c 65 20 69 6e 20 74 68 65  available in the
2220: 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50   SQLITE_CONFIG_P
2230: 41 47 45 43 41 43 48 45 20 70 6f 6f 6c 2e 20 20  AGECACHE pool.  
2240: 47 65 74 0a 20 20 20 20 2a 2a 20 69 74 20 66 72  Get.    ** it fr
2250: 6f 6d 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63  om sqlite3Malloc
2260: 20 69 6e 73 74 65 61 64 2e 0a 20 20 20 20 2a 2f   instead..    */
2270: 0a 20 20 20 20 70 20 3d 20 73 71 6c 69 74 65 33  .    p = sqlite3
2280: 4d 61 6c 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 23  Malloc(nByte);.#
2290: 69 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 44 49  ifndef SQLITE_DI
22a0: 53 41 42 4c 45 5f 50 41 47 45 43 41 43 48 45 5f  SABLE_PAGECACHE_
22b0: 4f 56 45 52 46 4c 4f 57 5f 53 54 41 54 53 0a 20  OVERFLOW_STATS. 
22c0: 20 20 20 69 66 28 20 70 20 29 7b 0a 20 20 20 20     if( p ){.    
22d0: 20 20 69 6e 74 20 73 7a 20 3d 20 73 71 6c 69 74    int sz = sqlit
22e0: 65 33 4d 61 6c 6c 6f 63 53 69 7a 65 28 70 29 3b  e3MallocSize(p);
22f0: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 6d  .      sqlite3_m
2300: 75 74 65 78 5f 65 6e 74 65 72 28 70 63 61 63 68  utex_enter(pcach
2310: 65 31 2e 6d 75 74 65 78 29 3b 0a 20 20 20 20 20  e1.mutex);.     
2320: 20 73 71 6c 69 74 65 33 53 74 61 74 75 73 41 64   sqlite3StatusAd
2330: 64 28 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f  d(SQLITE_STATUS_
2340: 50 41 47 45 43 41 43 48 45 5f 4f 56 45 52 46 4c  PAGECACHE_OVERFL
2350: 4f 57 2c 20 73 7a 29 3b 0a 20 20 20 20 20 20 73  OW, sz);.      s
2360: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61  qlite3_mutex_lea
2370: 76 65 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78  ve(pcache1.mutex
2380: 29 3b 0a 20 20 20 20 7d 0a 23 65 6e 64 69 66 0a  );.    }.#endif.
2390: 20 20 20 20 73 71 6c 69 74 65 33 4d 65 6d 64 65      sqlite3Memde
23a0: 62 75 67 53 65 74 54 79 70 65 28 70 2c 20 4d 45  bugSetType(p, ME
23b0: 4d 54 59 50 45 5f 50 43 41 43 48 45 29 3b 0a 20  MTYPE_PCACHE);. 
23c0: 20 7d 0a 20 20 72 65 74 75 72 6e 20 70 3b 0a 7d   }.  return p;.}
23d0: 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61 6e 20  ../*.** Free an 
23e0: 61 6c 6c 6f 63 61 74 65 64 20 62 75 66 66 65 72  allocated buffer
23f0: 20 6f 62 74 61 69 6e 65 64 20 66 72 6f 6d 20 70   obtained from p
2400: 63 61 63 68 65 31 41 6c 6c 6f 63 28 29 2e 0a 2a  cache1Alloc()..*
2410: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 70 63 61  /.static int pca
2420: 63 68 65 31 46 72 65 65 28 76 6f 69 64 20 2a 70  che1Free(void *p
2430: 29 7b 0a 20 20 69 6e 74 20 6e 46 72 65 65 64 20  ){.  int nFreed 
2440: 3d 20 30 3b 0a 20 20 69 66 28 20 70 3d 3d 30 20  = 0;.  if( p==0 
2450: 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 69 66  ) return 0;.  if
2460: 28 20 70 3e 3d 70 63 61 63 68 65 31 2e 70 53 74  ( p>=pcache1.pSt
2470: 61 72 74 20 26 26 20 70 3c 70 63 61 63 68 65 31  art && p<pcache1
2480: 2e 70 45 6e 64 20 29 7b 0a 20 20 20 20 50 67 46  .pEnd ){.    PgF
2490: 72 65 65 73 6c 6f 74 20 2a 70 53 6c 6f 74 3b 0a  reeslot *pSlot;.
24a0: 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65      sqlite3_mute
24b0: 78 5f 65 6e 74 65 72 28 70 63 61 63 68 65 31 2e  x_enter(pcache1.
24c0: 6d 75 74 65 78 29 3b 0a 20 20 20 20 73 71 6c 69  mutex);.    sqli
24d0: 74 65 33 53 74 61 74 75 73 41 64 64 28 53 51 4c  te3StatusAdd(SQL
24e0: 49 54 45 5f 53 54 41 54 55 53 5f 50 41 47 45 43  ITE_STATUS_PAGEC
24f0: 41 43 48 45 5f 55 53 45 44 2c 20 2d 31 29 3b 0a  ACHE_USED, -1);.
2500: 20 20 20 20 70 53 6c 6f 74 20 3d 20 28 50 67 46      pSlot = (PgF
2510: 72 65 65 73 6c 6f 74 2a 29 70 3b 0a 20 20 20 20  reeslot*)p;.    
2520: 70 53 6c 6f 74 2d 3e 70 4e 65 78 74 20 3d 20 70  pSlot->pNext = p
2530: 63 61 63 68 65 31 2e 70 46 72 65 65 3b 0a 20 20  cache1.pFree;.  
2540: 20 20 70 63 61 63 68 65 31 2e 70 46 72 65 65 20    pcache1.pFree 
2550: 3d 20 70 53 6c 6f 74 3b 0a 20 20 20 20 70 63 61  = pSlot;.    pca
2560: 63 68 65 31 2e 6e 46 72 65 65 53 6c 6f 74 2b 2b  che1.nFreeSlot++
2570: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 62 55  ;.    pcache1.bU
2580: 6e 64 65 72 50 72 65 73 73 75 72 65 20 3d 20 70  nderPressure = p
2590: 63 61 63 68 65 31 2e 6e 46 72 65 65 53 6c 6f 74  cache1.nFreeSlot
25a0: 3c 70 63 61 63 68 65 31 2e 6e 52 65 73 65 72 76  <pcache1.nReserv
25b0: 65 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70  e;.    assert( p
25c0: 63 61 63 68 65 31 2e 6e 46 72 65 65 53 6c 6f 74  cache1.nFreeSlot
25d0: 3c 3d 70 63 61 63 68 65 31 2e 6e 53 6c 6f 74 20  <=pcache1.nSlot 
25e0: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 6d  );.    sqlite3_m
25f0: 75 74 65 78 5f 6c 65 61 76 65 28 70 63 61 63 68  utex_leave(pcach
2600: 65 31 2e 6d 75 74 65 78 29 3b 0a 20 20 7d 65 6c  e1.mutex);.  }el
2610: 73 65 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20  se{.    assert( 
2620: 73 71 6c 69 74 65 33 4d 65 6d 64 65 62 75 67 48  sqlite3MemdebugH
2630: 61 73 54 79 70 65 28 70 2c 20 4d 45 4d 54 59 50  asType(p, MEMTYP
2640: 45 5f 50 43 41 43 48 45 29 20 29 3b 0a 20 20 20  E_PCACHE) );.   
2650: 20 73 71 6c 69 74 65 33 4d 65 6d 64 65 62 75 67   sqlite3Memdebug
2660: 53 65 74 54 79 70 65 28 70 2c 20 4d 45 4d 54 59  SetType(p, MEMTY
2670: 50 45 5f 48 45 41 50 29 3b 0a 20 20 20 20 6e 46  PE_HEAP);.    nF
2680: 72 65 65 64 20 3d 20 73 71 6c 69 74 65 33 4d 61  reed = sqlite3Ma
2690: 6c 6c 6f 63 53 69 7a 65 28 70 29 3b 0a 23 69 66  llocSize(p);.#if
26a0: 6e 64 65 66 20 53 51 4c 49 54 45 5f 44 49 53 41  ndef SQLITE_DISA
26b0: 42 4c 45 5f 50 41 47 45 43 41 43 48 45 5f 4f 56  BLE_PAGECACHE_OV
26c0: 45 52 46 4c 4f 57 5f 53 54 41 54 53 0a 20 20 20  ERFLOW_STATS.   
26d0: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65   sqlite3_mutex_e
26e0: 6e 74 65 72 28 70 63 61 63 68 65 31 2e 6d 75 74  nter(pcache1.mut
26f0: 65 78 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  ex);.    sqlite3
2700: 53 74 61 74 75 73 41 64 64 28 53 51 4c 49 54 45  StatusAdd(SQLITE
2710: 5f 53 54 41 54 55 53 5f 50 41 47 45 43 41 43 48  _STATUS_PAGECACH
2720: 45 5f 4f 56 45 52 46 4c 4f 57 2c 20 2d 6e 46 72  E_OVERFLOW, -nFr
2730: 65 65 64 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  eed);.    sqlite
2740: 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 70 63  3_mutex_leave(pc
2750: 61 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a 23 65  ache1.mutex);.#e
2760: 6e 64 69 66 0a 20 20 20 20 73 71 6c 69 74 65 33  ndif.    sqlite3
2770: 5f 66 72 65 65 28 70 29 3b 0a 20 20 7d 0a 20 20  _free(p);.  }.  
2780: 72 65 74 75 72 6e 20 6e 46 72 65 65 64 3b 0a 7d  return nFreed;.}
2790: 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f  ..#ifdef SQLITE_
27a0: 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41  ENABLE_MEMORY_MA
27b0: 4e 41 47 45 4d 45 4e 54 0a 2f 2a 0a 2a 2a 20 52  NAGEMENT./*.** R
27c0: 65 74 75 72 6e 20 74 68 65 20 73 69 7a 65 20 6f  eturn the size o
27d0: 66 20 61 20 70 63 61 63 68 65 20 61 6c 6c 6f 63  f a pcache alloc
27e0: 61 74 69 6f 6e 0a 2a 2f 0a 73 74 61 74 69 63 20  ation.*/.static 
27f0: 69 6e 74 20 70 63 61 63 68 65 31 4d 65 6d 53 69  int pcache1MemSi
2800: 7a 65 28 76 6f 69 64 20 2a 70 29 7b 0a 20 20 69  ze(void *p){.  i
2810: 66 28 20 70 3e 3d 70 63 61 63 68 65 31 2e 70 53  f( p>=pcache1.pS
2820: 74 61 72 74 20 26 26 20 70 3c 70 63 61 63 68 65  tart && p<pcache
2830: 31 2e 70 45 6e 64 20 29 7b 0a 20 20 20 20 72 65  1.pEnd ){.    re
2840: 74 75 72 6e 20 70 63 61 63 68 65 31 2e 73 7a 53  turn pcache1.szS
2850: 6c 6f 74 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  lot;.  }else{.  
2860: 20 20 69 6e 74 20 69 53 69 7a 65 3b 0a 20 20 20    int iSize;.   
2870: 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33   assert( sqlite3
2880: 4d 65 6d 64 65 62 75 67 48 61 73 54 79 70 65 28  MemdebugHasType(
2890: 70 2c 20 4d 45 4d 54 59 50 45 5f 50 43 41 43 48  p, MEMTYPE_PCACH
28a0: 45 29 20 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  E) );.    sqlite
28b0: 33 4d 65 6d 64 65 62 75 67 53 65 74 54 79 70 65  3MemdebugSetType
28c0: 28 70 2c 20 4d 45 4d 54 59 50 45 5f 48 45 41 50  (p, MEMTYPE_HEAP
28d0: 29 3b 0a 20 20 20 20 69 53 69 7a 65 20 3d 20 73  );.    iSize = s
28e0: 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 53 69 7a 65  qlite3MallocSize
28f0: 28 70 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  (p);.    sqlite3
2900: 4d 65 6d 64 65 62 75 67 53 65 74 54 79 70 65 28  MemdebugSetType(
2910: 70 2c 20 4d 45 4d 54 59 50 45 5f 50 43 41 43 48  p, MEMTYPE_PCACH
2920: 45 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 69  E);.    return i
2930: 53 69 7a 65 3b 0a 20 20 7d 0a 7d 0a 23 65 6e 64  Size;.  }.}.#end
2940: 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f 45 4e 41  if /* SQLITE_ENA
2950: 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47  BLE_MEMORY_MANAG
2960: 45 4d 45 4e 54 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20  EMENT */../*.** 
2970: 41 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 70  Allocate a new p
2980: 61 67 65 20 6f 62 6a 65 63 74 20 69 6e 69 74 69  age object initi
2990: 61 6c 6c 79 20 61 73 73 6f 63 69 61 74 65 64 20  ally associated 
29a0: 77 69 74 68 20 63 61 63 68 65 20 70 43 61 63 68  with cache pCach
29b0: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 50 67 48  e..*/.static PgH
29c0: 64 72 31 20 2a 70 63 61 63 68 65 31 41 6c 6c 6f  dr1 *pcache1Allo
29d0: 63 50 61 67 65 28 50 43 61 63 68 65 31 20 2a 70  cPage(PCache1 *p
29e0: 43 61 63 68 65 29 7b 0a 20 20 50 67 48 64 72 31  Cache){.  PgHdr1
29f0: 20 2a 70 20 3d 20 30 3b 0a 20 20 76 6f 69 64 20   *p = 0;.  void 
2a00: 2a 70 50 67 3b 0a 0a 20 20 2f 2a 20 54 68 65 20  *pPg;..  /* The 
2a10: 67 72 6f 75 70 20 6d 75 74 65 78 20 6d 75 73 74  group mutex must
2a20: 20 62 65 20 72 65 6c 65 61 73 65 64 20 62 65 66   be released bef
2a30: 6f 72 65 20 70 63 61 63 68 65 31 41 6c 6c 6f 63  ore pcache1Alloc
2a40: 28 29 20 69 73 20 63 61 6c 6c 65 64 2e 20 54 68  () is called. Th
2a50: 69 73 0a 20 20 2a 2a 20 69 73 20 62 65 63 61 75  is.  ** is becau
2a60: 73 65 20 69 74 20 6d 61 79 20 63 61 6c 6c 20 73  se it may call s
2a70: 71 6c 69 74 65 33 5f 72 65 6c 65 61 73 65 5f 6d  qlite3_release_m
2a80: 65 6d 6f 72 79 28 29 2c 20 77 68 69 63 68 20 61  emory(), which a
2a90: 73 73 75 6d 65 73 20 74 68 61 74 20 0a 20 20 2a  ssumes that .  *
2aa0: 2a 20 74 68 69 73 20 6d 75 74 65 78 20 69 73 20  * this mutex is 
2ab0: 6e 6f 74 20 68 65 6c 64 2e 20 2a 2f 0a 20 20 61  not held. */.  a
2ac0: 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d  ssert( sqlite3_m
2ad0: 75 74 65 78 5f 68 65 6c 64 28 70 43 61 63 68 65  utex_held(pCache
2ae0: 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78 29  ->pGroup->mutex)
2af0: 20 29 3b 0a 20 20 70 63 61 63 68 65 31 4c 65 61   );.  pcache1Lea
2b00: 76 65 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e  veMutex(pCache->
2b10: 70 47 72 6f 75 70 29 3b 0a 23 69 66 64 65 66 20  pGroup);.#ifdef 
2b20: 53 51 4c 49 54 45 5f 50 43 41 43 48 45 5f 53 45  SQLITE_PCACHE_SE
2b30: 50 41 52 41 54 45 5f 48 45 41 44 45 52 0a 20 20  PARATE_HEADER.  
2b40: 70 50 67 20 3d 20 70 63 61 63 68 65 31 41 6c 6c  pPg = pcache1All
2b50: 6f 63 28 70 43 61 63 68 65 2d 3e 73 7a 50 61 67  oc(pCache->szPag
2b60: 65 29 3b 0a 20 20 70 20 3d 20 73 71 6c 69 74 65  e);.  p = sqlite
2b70: 33 4d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 50  3Malloc(sizeof(P
2b80: 67 48 64 72 31 29 20 2b 20 70 43 61 63 68 65 2d  gHdr1) + pCache-
2b90: 3e 73 7a 45 78 74 72 61 29 3b 0a 20 20 69 66 28  >szExtra);.  if(
2ba0: 20 21 70 50 67 20 7c 7c 20 21 70 20 29 7b 0a 20   !pPg || !p ){. 
2bb0: 20 20 20 70 63 61 63 68 65 31 46 72 65 65 28 70     pcache1Free(p
2bc0: 50 67 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  Pg);.    sqlite3
2bd0: 5f 66 72 65 65 28 70 29 3b 0a 20 20 20 20 70 50  _free(p);.    pP
2be0: 67 20 3d 20 30 3b 0a 20 20 7d 0a 23 65 6c 73 65  g = 0;.  }.#else
2bf0: 0a 20 20 70 50 67 20 3d 20 70 63 61 63 68 65 31  .  pPg = pcache1
2c00: 41 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 50 67 48  Alloc(sizeof(PgH
2c10: 64 72 31 29 20 2b 20 70 43 61 63 68 65 2d 3e 73  dr1) + pCache->s
2c20: 7a 50 61 67 65 20 2b 20 70 43 61 63 68 65 2d 3e  zPage + pCache->
2c30: 73 7a 45 78 74 72 61 29 3b 0a 20 20 70 20 3d 20  szExtra);.  p = 
2c40: 28 50 67 48 64 72 31 20 2a 29 26 28 28 75 38 20  (PgHdr1 *)&((u8 
2c50: 2a 29 70 50 67 29 5b 70 43 61 63 68 65 2d 3e 73  *)pPg)[pCache->s
2c60: 7a 50 61 67 65 5d 3b 0a 23 65 6e 64 69 66 0a 20  zPage];.#endif. 
2c70: 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74   pcache1EnterMut
2c80: 65 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75  ex(pCache->pGrou
2c90: 70 29 3b 0a 0a 20 20 69 66 28 20 70 50 67 20 29  p);..  if( pPg )
2ca0: 7b 0a 20 20 20 20 70 2d 3e 70 61 67 65 2e 70 42  {.    p->page.pB
2cb0: 75 66 20 3d 20 70 50 67 3b 0a 20 20 20 20 70 2d  uf = pPg;.    p-
2cc0: 3e 70 61 67 65 2e 70 45 78 74 72 61 20 3d 20 26  >page.pExtra = &
2cd0: 70 5b 31 5d 3b 0a 20 20 20 20 69 66 28 20 70 43  p[1];.    if( pC
2ce0: 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65  ache->bPurgeable
2cf0: 20 29 7b 0a 20 20 20 20 20 20 70 43 61 63 68 65   ){.      pCache
2d00: 2d 3e 70 47 72 6f 75 70 2d 3e 6e 43 75 72 72 65  ->pGroup->nCurre
2d10: 6e 74 50 61 67 65 2b 2b 3b 0a 20 20 20 20 7d 0a  ntPage++;.    }.
2d20: 20 20 20 20 72 65 74 75 72 6e 20 70 3b 0a 20 20      return p;.  
2d30: 7d 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a  }.  return 0;.}.
2d40: 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61 20 70 61  ./*.** Free a pa
2d50: 67 65 20 6f 62 6a 65 63 74 20 61 6c 6c 6f 63 61  ge object alloca
2d60: 74 65 64 20 62 79 20 70 63 61 63 68 65 31 41 6c  ted by pcache1Al
2d70: 6c 6f 63 50 61 67 65 28 29 2e 0a 2a 2a 0a 2a 2a  locPage()..**.**
2d80: 20 54 68 65 20 70 6f 69 6e 74 65 72 20 69 73 20   The pointer is 
2d90: 61 6c 6c 6f 77 65 64 20 74 6f 20 62 65 20 4e 55  allowed to be NU
2da0: 4c 4c 2c 20 77 68 69 63 68 20 69 73 20 70 72 75  LL, which is pru
2db0: 64 65 6e 74 2e 20 20 42 75 74 20 69 74 20 74 75  dent.  But it tu
2dc0: 72 6e 73 20 6f 75 74 0a 2a 2a 20 74 68 61 74 20  rns out.** that 
2dd0: 74 68 65 20 63 75 72 72 65 6e 74 20 69 6d 70 6c  the current impl
2de0: 65 6d 65 6e 74 61 74 69 6f 6e 20 68 61 70 70 65  ementation happe
2df0: 6e 73 20 74 6f 20 6e 65 76 65 72 20 63 61 6c 6c  ns to never call
2e00: 20 74 68 69 73 20 72 6f 75 74 69 6e 65 0a 2a 2a   this routine.**
2e10: 20 77 69 74 68 20 61 20 4e 55 4c 4c 20 70 6f 69   with a NULL poi
2e20: 6e 74 65 72 2c 20 73 6f 20 77 65 20 6d 61 72 6b  nter, so we mark
2e30: 20 74 68 65 20 4e 55 4c 4c 20 74 65 73 74 20 77   the NULL test w
2e40: 69 74 68 20 41 4c 57 41 59 53 28 29 2e 0a 2a 2f  ith ALWAYS()..*/
2e50: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61  .static void pca
2e60: 63 68 65 31 46 72 65 65 50 61 67 65 28 50 67 48  che1FreePage(PgH
2e70: 64 72 31 20 2a 70 29 7b 0a 20 20 69 66 28 20 41  dr1 *p){.  if( A
2e80: 4c 57 41 59 53 28 70 29 20 29 7b 0a 20 20 20 20  LWAYS(p) ){.    
2e90: 50 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 20  PCache1 *pCache 
2ea0: 3d 20 70 2d 3e 70 43 61 63 68 65 3b 0a 20 20 20  = p->pCache;.   
2eb0: 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33   assert( sqlite3
2ec0: 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 2d 3e 70  _mutex_held(p->p
2ed0: 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 2d 3e 6d  Cache->pGroup->m
2ee0: 75 74 65 78 29 20 29 3b 0a 20 20 20 20 70 63 61  utex) );.    pca
2ef0: 63 68 65 31 46 72 65 65 28 70 2d 3e 70 61 67 65  che1Free(p->page
2f00: 2e 70 42 75 66 29 3b 0a 23 69 66 64 65 66 20 53  .pBuf);.#ifdef S
2f10: 51 4c 49 54 45 5f 50 43 41 43 48 45 5f 53 45 50  QLITE_PCACHE_SEP
2f20: 41 52 41 54 45 5f 48 45 41 44 45 52 0a 20 20 20  ARATE_HEADER.   
2f30: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 29   sqlite3_free(p)
2f40: 3b 0a 23 65 6e 64 69 66 0a 20 20 20 20 69 66 28  ;.#endif.    if(
2f50: 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61   pCache->bPurgea
2f60: 62 6c 65 20 29 7b 0a 20 20 20 20 20 20 70 43 61  ble ){.      pCa
2f70: 63 68 65 2d 3e 70 47 72 6f 75 70 2d 3e 6e 43 75  che->pGroup->nCu
2f80: 72 72 65 6e 74 50 61 67 65 2d 2d 3b 0a 20 20 20  rrentPage--;.   
2f90: 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20   }.  }.}../*.** 
2fa0: 4d 61 6c 6c 6f 63 20 66 75 6e 63 74 69 6f 6e 20  Malloc function 
2fb0: 75 73 65 64 20 62 79 20 53 51 4c 69 74 65 20 74  used by SQLite t
2fc0: 6f 20 6f 62 74 61 69 6e 20 73 70 61 63 65 20 66  o obtain space f
2fd0: 72 6f 6d 20 74 68 65 20 62 75 66 66 65 72 20 63  rom the buffer c
2fe0: 6f 6e 66 69 67 75 72 65 64 0a 2a 2a 20 75 73 69  onfigured.** usi
2ff0: 6e 67 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69  ng sqlite3_confi
3000: 67 28 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f  g(SQLITE_CONFIG_
3010: 50 41 47 45 43 41 43 48 45 29 20 6f 70 74 69 6f  PAGECACHE) optio
3020: 6e 2e 20 49 66 20 6e 6f 20 73 75 63 68 20 62 75  n. If no such bu
3030: 66 66 65 72 0a 2a 2a 20 65 78 69 73 74 73 2c 20  ffer.** exists, 
3040: 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 66 61  this function fa
3050: 6c 6c 73 20 62 61 63 6b 20 74 6f 20 73 71 6c 69  lls back to sqli
3060: 74 65 33 4d 61 6c 6c 6f 63 28 29 2e 0a 2a 2f 0a  te3Malloc()..*/.
3070: 76 6f 69 64 20 2a 73 71 6c 69 74 65 33 50 61 67  void *sqlite3Pag
3080: 65 4d 61 6c 6c 6f 63 28 69 6e 74 20 73 7a 29 7b  eMalloc(int sz){
3090: 0a 20 20 72 65 74 75 72 6e 20 70 63 61 63 68 65  .  return pcache
30a0: 31 41 6c 6c 6f 63 28 73 7a 29 3b 0a 7d 0a 0a 2f  1Alloc(sz);.}../
30b0: 2a 0a 2a 2a 20 46 72 65 65 20 61 6e 20 61 6c 6c  *.** Free an all
30c0: 6f 63 61 74 65 64 20 62 75 66 66 65 72 20 6f 62  ocated buffer ob
30d0: 74 61 69 6e 65 64 20 66 72 6f 6d 20 73 71 6c 69  tained from sqli
30e0: 74 65 33 50 61 67 65 4d 61 6c 6c 6f 63 28 29 2e  te3PageMalloc().
30f0: 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33  .*/.void sqlite3
3100: 50 61 67 65 46 72 65 65 28 76 6f 69 64 20 2a 70  PageFree(void *p
3110: 29 7b 0a 20 20 70 63 61 63 68 65 31 46 72 65 65  ){.  pcache1Free
3120: 28 70 29 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 52  (p);.}.../*.** R
3130: 65 74 75 72 6e 20 74 72 75 65 20 69 66 20 69 74  eturn true if it
3140: 20 64 65 73 69 72 61 62 6c 65 20 74 6f 20 61 76   desirable to av
3150: 6f 69 64 20 61 6c 6c 6f 63 61 74 69 6e 67 20 61  oid allocating a
3160: 20 6e 65 77 20 70 61 67 65 20 63 61 63 68 65 0a   new page cache.
3170: 2a 2a 20 65 6e 74 72 79 2e 0a 2a 2a 0a 2a 2a 20  ** entry..**.** 
3180: 49 66 20 6d 65 6d 6f 72 79 20 77 61 73 20 61 6c  If memory was al
3190: 6c 6f 63 61 74 65 64 20 73 70 65 63 69 66 69 63  located specific
31a0: 61 6c 6c 79 20 74 6f 20 74 68 65 20 70 61 67 65  ally to the page
31b0: 20 63 61 63 68 65 20 75 73 69 6e 67 0a 2a 2a 20   cache using.** 
31c0: 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41  SQLITE_CONFIG_PA
31d0: 47 45 43 41 43 48 45 20 62 75 74 20 74 68 61 74  GECACHE but that
31e0: 20 6d 65 6d 6f 72 79 20 68 61 73 20 61 6c 6c 20   memory has all 
31f0: 62 65 65 6e 20 75 73 65 64 2c 20 74 68 65 6e 0a  been used, then.
3200: 2a 2a 20 69 74 20 69 73 20 64 65 73 69 72 61 62  ** it is desirab
3210: 6c 65 20 74 6f 20 61 76 6f 69 64 20 61 6c 6c 6f  le to avoid allo
3220: 63 61 74 69 6e 67 20 61 20 6e 65 77 20 70 61 67  cating a new pag
3230: 65 20 63 61 63 68 65 20 65 6e 74 72 79 20 62 65  e cache entry be
3240: 63 61 75 73 65 0a 2a 2a 20 70 72 65 73 75 6d 61  cause.** presuma
3250: 62 6c 79 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49  bly SQLITE_CONFI
3260: 47 5f 50 41 47 45 43 41 43 48 45 20 77 61 73 20  G_PAGECACHE was 
3270: 73 75 70 70 6f 73 65 20 74 6f 20 62 65 20 73 75  suppose to be su
3280: 66 66 69 63 69 65 6e 74 0a 2a 2a 20 66 6f 72 20  fficient.** for 
3290: 61 6c 6c 20 70 61 67 65 20 63 61 63 68 65 20 6e  all page cache n
32a0: 65 65 64 73 20 61 6e 64 20 77 65 20 73 68 6f 75  eeds and we shou
32b0: 6c 64 20 6e 6f 74 20 6e 65 65 64 20 74 6f 20 73  ld not need to s
32c0: 70 69 6c 6c 20 74 68 65 0a 2a 2a 20 61 6c 6c 6f  pill the.** allo
32d0: 63 61 74 69 6f 6e 20 6f 6e 74 6f 20 74 68 65 20  cation onto the 
32e0: 68 65 61 70 2e 0a 2a 2a 0a 2a 2a 20 4f 72 2c 20  heap..**.** Or, 
32f0: 74 68 65 20 68 65 61 70 20 69 73 20 75 73 65 64  the heap is used
3300: 20 66 6f 72 20 61 6c 6c 20 70 61 67 65 20 63 61   for all page ca
3310: 63 68 65 20 6d 65 6d 6f 72 79 20 62 75 74 20 74  che memory but t
3320: 68 65 20 68 65 61 70 20 69 73 0a 2a 2a 20 75 6e  he heap is.** un
3330: 64 65 72 20 6d 65 6d 6f 72 79 20 70 72 65 73 73  der memory press
3340: 75 72 65 2c 20 74 68 65 6e 20 61 67 61 69 6e 20  ure, then again 
3350: 69 74 20 69 73 20 64 65 73 69 72 61 62 6c 65 20  it is desirable 
3360: 74 6f 20 61 76 6f 69 64 0a 2a 2a 20 61 6c 6c 6f  to avoid.** allo
3370: 63 61 74 69 6e 67 20 61 20 6e 65 77 20 70 61 67  cating a new pag
3380: 65 20 63 61 63 68 65 20 65 6e 74 72 79 20 69 6e  e cache entry in
3390: 20 6f 72 64 65 72 20 74 6f 20 61 76 6f 69 64 20   order to avoid 
33a0: 73 74 72 65 73 73 69 6e 67 0a 2a 2a 20 74 68 65  stressing.** the
33b0: 20 68 65 61 70 20 65 76 65 6e 20 66 75 72 74 68   heap even furth
33c0: 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  er..*/.static in
33d0: 74 20 70 63 61 63 68 65 31 55 6e 64 65 72 4d 65  t pcache1UnderMe
33e0: 6d 6f 72 79 50 72 65 73 73 75 72 65 28 50 43 61  moryPressure(PCa
33f0: 63 68 65 31 20 2a 70 43 61 63 68 65 29 7b 0a 20  che1 *pCache){. 
3400: 20 69 66 28 20 70 63 61 63 68 65 31 2e 6e 53 6c   if( pcache1.nSl
3410: 6f 74 20 26 26 20 28 70 43 61 63 68 65 2d 3e 73  ot && (pCache->s
3420: 7a 50 61 67 65 2b 70 43 61 63 68 65 2d 3e 73 7a  zPage+pCache->sz
3430: 45 78 74 72 61 29 3c 3d 70 63 61 63 68 65 31 2e  Extra)<=pcache1.
3440: 73 7a 53 6c 6f 74 20 29 7b 0a 20 20 20 20 72 65  szSlot ){.    re
3450: 74 75 72 6e 20 70 63 61 63 68 65 31 2e 62 55 6e  turn pcache1.bUn
3460: 64 65 72 50 72 65 73 73 75 72 65 3b 0a 20 20 7d  derPressure;.  }
3470: 65 6c 73 65 7b 0a 20 20 20 20 72 65 74 75 72 6e  else{.    return
3480: 20 73 71 6c 69 74 65 33 48 65 61 70 4e 65 61 72   sqlite3HeapNear
3490: 6c 79 46 75 6c 6c 28 29 3b 0a 20 20 7d 0a 7d 0a  lyFull();.  }.}.
34a0: 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ./**************
34b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
34c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
34d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
34e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
34f0: 2f 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 20 47 65 6e 65  /./******** Gene
3500: 72 61 6c 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69  ral Implementati
3510: 6f 6e 20 46 75 6e 63 74 69 6f 6e 73 20 2a 2a 2a  on Functions ***
3520: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3530: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3540: 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66  */../*.** This f
3550: 75 6e 63 74 69 6f 6e 20 69 73 20 75 73 65 64 20  unction is used 
3560: 74 6f 20 72 65 73 69 7a 65 20 74 68 65 20 68 61  to resize the ha
3570: 73 68 20 74 61 62 6c 65 20 75 73 65 64 20 62 79  sh table used by
3580: 20 74 68 65 20 63 61 63 68 65 20 70 61 73 73 65   the cache passe
3590: 64 0a 2a 2a 20 61 73 20 74 68 65 20 66 69 72 73  d.** as the firs
35a0: 74 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2a 0a 2a  t argument..**.*
35b0: 2a 20 54 68 65 20 50 43 61 63 68 65 20 6d 75 74  * The PCache mut
35c0: 65 78 20 6d 75 73 74 20 62 65 20 68 65 6c 64 20  ex must be held 
35d0: 77 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69  when this functi
35e0: 6f 6e 20 69 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f  on is called..*/
35f0: 0a 73 74 61 74 69 63 20 69 6e 74 20 70 63 61 63  .static int pcac
3600: 68 65 31 52 65 73 69 7a 65 48 61 73 68 28 50 43  he1ResizeHash(PC
3610: 61 63 68 65 31 20 2a 70 29 7b 0a 20 20 50 67 48  ache1 *p){.  PgH
3620: 64 72 31 20 2a 2a 61 70 4e 65 77 3b 0a 20 20 75  dr1 **apNew;.  u
3630: 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 4e 65 77  nsigned int nNew
3640: 3b 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74  ;.  unsigned int
3650: 20 69 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 73   i;..  assert( s
3660: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c  qlite3_mutex_hel
3670: 64 28 70 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75 74  d(p->pGroup->mut
3680: 65 78 29 20 29 3b 0a 0a 20 20 6e 4e 65 77 20 3d  ex) );..  nNew =
3690: 20 70 2d 3e 6e 48 61 73 68 2a 32 3b 0a 20 20 69   p->nHash*2;.  i
36a0: 66 28 20 6e 4e 65 77 3c 32 35 36 20 29 7b 0a 20  f( nNew<256 ){. 
36b0: 20 20 20 6e 4e 65 77 20 3d 20 32 35 36 3b 0a 20     nNew = 256;. 
36c0: 20 7d 0a 0a 20 20 70 63 61 63 68 65 31 4c 65 61   }..  pcache1Lea
36d0: 76 65 4d 75 74 65 78 28 70 2d 3e 70 47 72 6f 75  veMutex(p->pGrou
36e0: 70 29 3b 0a 20 20 69 66 28 20 70 2d 3e 6e 48 61  p);.  if( p->nHa
36f0: 73 68 20 29 7b 20 73 71 6c 69 74 65 33 42 65 67  sh ){ sqlite3Beg
3700: 69 6e 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29  inBenignMalloc()
3710: 3b 20 7d 0a 20 20 61 70 4e 65 77 20 3d 20 28 50  ; }.  apNew = (P
3720: 67 48 64 72 31 20 2a 2a 29 73 71 6c 69 74 65 33  gHdr1 **)sqlite3
3730: 4d 61 6c 6c 6f 63 5a 65 72 6f 28 73 69 7a 65 6f  MallocZero(sizeo
3740: 66 28 50 67 48 64 72 31 20 2a 29 2a 6e 4e 65 77  f(PgHdr1 *)*nNew
3750: 29 3b 0a 20 20 69 66 28 20 70 2d 3e 6e 48 61 73  );.  if( p->nHas
3760: 68 20 29 7b 20 73 71 6c 69 74 65 33 45 6e 64 42  h ){ sqlite3EndB
3770: 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 20 7d  enignMalloc(); }
3780: 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d  .  pcache1EnterM
3790: 75 74 65 78 28 70 2d 3e 70 47 72 6f 75 70 29 3b  utex(p->pGroup);
37a0: 0a 20 20 69 66 28 20 61 70 4e 65 77 20 29 7b 0a  .  if( apNew ){.
37b0: 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70      for(i=0; i<p
37c0: 2d 3e 6e 48 61 73 68 3b 20 69 2b 2b 29 7b 0a 20  ->nHash; i++){. 
37d0: 20 20 20 20 20 50 67 48 64 72 31 20 2a 70 50 61       PgHdr1 *pPa
37e0: 67 65 3b 0a 20 20 20 20 20 20 50 67 48 64 72 31  ge;.      PgHdr1
37f0: 20 2a 70 4e 65 78 74 20 3d 20 70 2d 3e 61 70 48   *pNext = p->apH
3800: 61 73 68 5b 69 5d 3b 0a 20 20 20 20 20 20 77 68  ash[i];.      wh
3810: 69 6c 65 28 20 28 70 50 61 67 65 20 3d 20 70 4e  ile( (pPage = pN
3820: 65 78 74 29 21 3d 30 20 29 7b 0a 20 20 20 20 20  ext)!=0 ){.     
3830: 20 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20     unsigned int 
3840: 68 20 3d 20 70 50 61 67 65 2d 3e 69 4b 65 79 20  h = pPage->iKey 
3850: 25 20 6e 4e 65 77 3b 0a 20 20 20 20 20 20 20 20  % nNew;.        
3860: 70 4e 65 78 74 20 3d 20 70 50 61 67 65 2d 3e 70  pNext = pPage->p
3870: 4e 65 78 74 3b 0a 20 20 20 20 20 20 20 20 70 50  Next;.        pP
3880: 61 67 65 2d 3e 70 4e 65 78 74 20 3d 20 61 70 4e  age->pNext = apN
3890: 65 77 5b 68 5d 3b 0a 20 20 20 20 20 20 20 20 61  ew[h];.        a
38a0: 70 4e 65 77 5b 68 5d 20 3d 20 70 50 61 67 65 3b  pNew[h] = pPage;
38b0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
38c0: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
38d0: 70 2d 3e 61 70 48 61 73 68 29 3b 0a 20 20 20 20  p->apHash);.    
38e0: 70 2d 3e 61 70 48 61 73 68 20 3d 20 61 70 4e 65  p->apHash = apNe
38f0: 77 3b 0a 20 20 20 20 70 2d 3e 6e 48 61 73 68 20  w;.    p->nHash 
3900: 3d 20 6e 4e 65 77 3b 0a 20 20 7d 0a 0a 20 20 72  = nNew;.  }..  r
3910: 65 74 75 72 6e 20 28 70 2d 3e 61 70 48 61 73 68  eturn (p->apHash
3920: 20 3f 20 53 51 4c 49 54 45 5f 4f 4b 20 3a 20 53   ? SQLITE_OK : S
3930: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 29 3b 0a 7d 0a  QLITE_NOMEM);.}.
3940: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  ./*.** This func
3950: 74 69 6f 6e 20 69 73 20 75 73 65 64 20 69 6e 74  tion is used int
3960: 65 72 6e 61 6c 6c 79 20 74 6f 20 72 65 6d 6f 76  ernally to remov
3970: 65 20 74 68 65 20 70 61 67 65 20 70 50 61 67 65  e the page pPage
3980: 20 66 72 6f 6d 20 74 68 65 20 0a 2a 2a 20 50 47   from the .** PG
3990: 72 6f 75 70 20 4c 52 55 20 6c 69 73 74 2c 20 69  roup LRU list, i
39a0: 66 20 69 73 20 70 61 72 74 20 6f 66 20 69 74 2e  f is part of it.
39b0: 20 49 66 20 70 50 61 67 65 20 69 73 20 6e 6f 74   If pPage is not
39c0: 20 70 61 72 74 20 6f 66 20 74 68 65 20 50 47 72   part of the PGr
39d0: 6f 75 70 0a 2a 2a 20 4c 52 55 20 6c 69 73 74 2c  oup.** LRU list,
39e0: 20 74 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74   then this funct
39f0: 69 6f 6e 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a  ion is a no-op..
3a00: 2a 2a 0a 2a 2a 20 54 68 65 20 50 47 72 6f 75 70  **.** The PGroup
3a10: 20 6d 75 74 65 78 20 6d 75 73 74 20 62 65 20 68   mutex must be h
3a20: 65 6c 64 20 77 68 65 6e 20 74 68 69 73 20 66 75  eld when this fu
3a30: 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64  nction is called
3a40: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
3a50: 20 70 63 61 63 68 65 31 50 69 6e 50 61 67 65 28   pcache1PinPage(
3a60: 50 67 48 64 72 31 20 2a 70 50 61 67 65 29 7b 0a  PgHdr1 *pPage){.
3a70: 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68    PCache1 *pCach
3a80: 65 3b 0a 20 20 50 47 72 6f 75 70 20 2a 70 47 72  e;.  PGroup *pGr
3a90: 6f 75 70 3b 0a 0a 20 20 61 73 73 65 72 74 28 20  oup;..  assert( 
3aa0: 70 50 61 67 65 21 3d 30 20 29 3b 0a 20 20 61 73  pPage!=0 );.  as
3ab0: 73 65 72 74 28 20 70 50 61 67 65 2d 3e 69 73 50  sert( pPage->isP
3ac0: 69 6e 6e 65 64 3d 3d 30 20 29 3b 0a 20 20 70 43  inned==0 );.  pC
3ad0: 61 63 68 65 20 3d 20 70 50 61 67 65 2d 3e 70 43  ache = pPage->pC
3ae0: 61 63 68 65 3b 0a 20 20 70 47 72 6f 75 70 20 3d  ache;.  pGroup =
3af0: 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b   pCache->pGroup;
3b00: 0a 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65  .  assert( pPage
3b10: 2d 3e 70 4c 72 75 4e 65 78 74 20 7c 7c 20 70 50  ->pLruNext || pP
3b20: 61 67 65 3d 3d 70 47 72 6f 75 70 2d 3e 70 4c 72  age==pGroup->pLr
3b30: 75 54 61 69 6c 20 29 3b 0a 20 20 61 73 73 65 72  uTail );.  asser
3b40: 74 28 20 70 50 61 67 65 2d 3e 70 4c 72 75 50 72  t( pPage->pLruPr
3b50: 65 76 20 7c 7c 20 70 50 61 67 65 3d 3d 70 47 72  ev || pPage==pGr
3b60: 6f 75 70 2d 3e 70 4c 72 75 48 65 61 64 20 29 3b  oup->pLruHead );
3b70: 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74  .  assert( sqlit
3b80: 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 47  e3_mutex_held(pG
3b90: 72 6f 75 70 2d 3e 6d 75 74 65 78 29 20 29 3b 0a  roup->mutex) );.
3ba0: 20 20 69 66 28 20 70 50 61 67 65 2d 3e 70 4c 72    if( pPage->pLr
3bb0: 75 50 72 65 76 20 29 7b 0a 20 20 20 20 70 50 61  uPrev ){.    pPa
3bc0: 67 65 2d 3e 70 4c 72 75 50 72 65 76 2d 3e 70 4c  ge->pLruPrev->pL
3bd0: 72 75 4e 65 78 74 20 3d 20 70 50 61 67 65 2d 3e  ruNext = pPage->
3be0: 70 4c 72 75 4e 65 78 74 3b 0a 20 20 7d 65 6c 73  pLruNext;.  }els
3bf0: 65 7b 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e 70  e{.    pGroup->p
3c00: 4c 72 75 48 65 61 64 20 3d 20 70 50 61 67 65 2d  LruHead = pPage-
3c10: 3e 70 4c 72 75 4e 65 78 74 3b 0a 20 20 7d 0a 20  >pLruNext;.  }. 
3c20: 20 69 66 28 20 70 50 61 67 65 2d 3e 70 4c 72 75   if( pPage->pLru
3c30: 4e 65 78 74 20 29 7b 0a 20 20 20 20 70 50 61 67  Next ){.    pPag
3c40: 65 2d 3e 70 4c 72 75 4e 65 78 74 2d 3e 70 4c 72  e->pLruNext->pLr
3c50: 75 50 72 65 76 20 3d 20 70 50 61 67 65 2d 3e 70  uPrev = pPage->p
3c60: 4c 72 75 50 72 65 76 3b 0a 20 20 7d 65 6c 73 65  LruPrev;.  }else
3c70: 7b 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e 70 4c  {.    pGroup->pL
3c80: 72 75 54 61 69 6c 20 3d 20 70 50 61 67 65 2d 3e  ruTail = pPage->
3c90: 70 4c 72 75 50 72 65 76 3b 0a 20 20 7d 0a 20 20  pLruPrev;.  }.  
3ca0: 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 20  pPage->pLruNext 
3cb0: 3d 20 30 3b 0a 20 20 70 50 61 67 65 2d 3e 70 4c  = 0;.  pPage->pL
3cc0: 72 75 50 72 65 76 20 3d 20 30 3b 0a 20 20 70 50  ruPrev = 0;.  pP
3cd0: 61 67 65 2d 3e 69 73 50 69 6e 6e 65 64 20 3d 20  age->isPinned = 
3ce0: 31 3b 0a 20 20 70 43 61 63 68 65 2d 3e 6e 52 65  1;.  pCache->nRe
3cf0: 63 79 63 6c 61 62 6c 65 2d 2d 3b 0a 7d 0a 0a 0a  cyclable--;.}...
3d00: 2f 2a 0a 2a 2a 20 52 65 6d 6f 76 65 20 74 68 65  /*.** Remove the
3d10: 20 70 61 67 65 20 73 75 70 70 6c 69 65 64 20 61   page supplied a
3d20: 73 20 61 6e 20 61 72 67 75 6d 65 6e 74 20 66 72  s an argument fr
3d30: 6f 6d 20 74 68 65 20 68 61 73 68 20 74 61 62 6c  om the hash tabl
3d40: 65 20 0a 2a 2a 20 28 50 43 61 63 68 65 31 2e 61  e .** (PCache1.a
3d50: 70 48 61 73 68 20 73 74 72 75 63 74 75 72 65 29  pHash structure)
3d60: 20 74 68 61 74 20 69 74 20 69 73 20 63 75 72 72   that it is curr
3d70: 65 6e 74 6c 79 20 73 74 6f 72 65 64 20 69 6e 2e  ently stored in.
3d80: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 50 47 72 6f 75  .**.** The PGrou
3d90: 70 20 6d 75 74 65 78 20 6d 75 73 74 20 62 65 20  p mutex must be 
3da0: 68 65 6c 64 20 77 68 65 6e 20 74 68 69 73 20 66  held when this f
3db0: 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65  unction is calle
3dc0: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  d..*/.static voi
3dd0: 64 20 70 63 61 63 68 65 31 52 65 6d 6f 76 65 46  d pcache1RemoveF
3de0: 72 6f 6d 48 61 73 68 28 50 67 48 64 72 31 20 2a  romHash(PgHdr1 *
3df0: 70 50 61 67 65 29 7b 0a 20 20 75 6e 73 69 67 6e  pPage){.  unsign
3e00: 65 64 20 69 6e 74 20 68 3b 0a 20 20 50 43 61 63  ed int h;.  PCac
3e10: 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20 70 50  he1 *pCache = pP
3e20: 61 67 65 2d 3e 70 43 61 63 68 65 3b 0a 20 20 50  age->pCache;.  P
3e30: 67 48 64 72 31 20 2a 2a 70 70 3b 0a 0a 20 20 61  gHdr1 **pp;..  a
3e40: 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d  ssert( sqlite3_m
3e50: 75 74 65 78 5f 68 65 6c 64 28 70 43 61 63 68 65  utex_held(pCache
3e60: 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78 29  ->pGroup->mutex)
3e70: 20 29 3b 0a 20 20 68 20 3d 20 70 50 61 67 65 2d   );.  h = pPage-
3e80: 3e 69 4b 65 79 20 25 20 70 43 61 63 68 65 2d 3e  >iKey % pCache->
3e90: 6e 48 61 73 68 3b 0a 20 20 66 6f 72 28 70 70 3d  nHash;.  for(pp=
3ea0: 26 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b  &pCache->apHash[
3eb0: 68 5d 3b 20 28 2a 70 70 29 21 3d 70 50 61 67 65  h]; (*pp)!=pPage
3ec0: 3b 20 70 70 3d 26 28 2a 70 70 29 2d 3e 70 4e 65  ; pp=&(*pp)->pNe
3ed0: 78 74 29 3b 0a 20 20 2a 70 70 20 3d 20 28 2a 70  xt);.  *pp = (*p
3ee0: 70 29 2d 3e 70 4e 65 78 74 3b 0a 0a 20 20 70 43  p)->pNext;..  pC
3ef0: 61 63 68 65 2d 3e 6e 50 61 67 65 2d 2d 3b 0a 7d  ache->nPage--;.}
3f00: 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 74 68 65 72 65  ../*.** If there
3f10: 20 61 72 65 20 63 75 72 72 65 6e 74 6c 79 20 6d   are currently m
3f20: 6f 72 65 20 74 68 61 6e 20 6e 4d 61 78 50 61 67  ore than nMaxPag
3f30: 65 20 70 61 67 65 73 20 61 6c 6c 6f 63 61 74 65  e pages allocate
3f40: 64 2c 20 74 72 79 0a 2a 2a 20 74 6f 20 72 65 63  d, try.** to rec
3f50: 79 63 6c 65 20 70 61 67 65 73 20 74 6f 20 72 65  ycle pages to re
3f60: 64 75 63 65 20 74 68 65 20 6e 75 6d 62 65 72 20  duce the number 
3f70: 61 6c 6c 6f 63 61 74 65 64 20 74 6f 20 6e 4d 61  allocated to nMa
3f80: 78 50 61 67 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  xPage..*/.static
3f90: 20 76 6f 69 64 20 70 63 61 63 68 65 31 45 6e 66   void pcache1Enf
3fa0: 6f 72 63 65 4d 61 78 50 61 67 65 28 50 47 72 6f  orceMaxPage(PGro
3fb0: 75 70 20 2a 70 47 72 6f 75 70 29 7b 0a 20 20 61  up *pGroup){.  a
3fc0: 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d  ssert( sqlite3_m
3fd0: 75 74 65 78 5f 68 65 6c 64 28 70 47 72 6f 75 70  utex_held(pGroup
3fe0: 2d 3e 6d 75 74 65 78 29 20 29 3b 0a 20 20 77 68  ->mutex) );.  wh
3ff0: 69 6c 65 28 20 70 47 72 6f 75 70 2d 3e 6e 43 75  ile( pGroup->nCu
4000: 72 72 65 6e 74 50 61 67 65 3e 70 47 72 6f 75 70  rrentPage>pGroup
4010: 2d 3e 6e 4d 61 78 50 61 67 65 20 26 26 20 70 47  ->nMaxPage && pG
4020: 72 6f 75 70 2d 3e 70 4c 72 75 54 61 69 6c 20 29  roup->pLruTail )
4030: 7b 0a 20 20 20 20 50 67 48 64 72 31 20 2a 70 20  {.    PgHdr1 *p 
4040: 3d 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 54 61  = pGroup->pLruTa
4050: 69 6c 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20  il;.    assert( 
4060: 70 2d 3e 70 43 61 63 68 65 2d 3e 70 47 72 6f 75  p->pCache->pGrou
4070: 70 3d 3d 70 47 72 6f 75 70 20 29 3b 0a 20 20 20  p==pGroup );.   
4080: 20 61 73 73 65 72 74 28 20 70 2d 3e 69 73 50 69   assert( p->isPi
4090: 6e 6e 65 64 3d 3d 30 20 29 3b 0a 20 20 20 20 70  nned==0 );.    p
40a0: 63 61 63 68 65 31 50 69 6e 50 61 67 65 28 70 29  cache1PinPage(p)
40b0: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 52 65 6d  ;.    pcache1Rem
40c0: 6f 76 65 46 72 6f 6d 48 61 73 68 28 70 29 3b 0a  oveFromHash(p);.
40d0: 20 20 20 20 70 63 61 63 68 65 31 46 72 65 65 50      pcache1FreeP
40e0: 61 67 65 28 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f  age(p);.  }.}../
40f0: 2a 0a 2a 2a 20 44 69 73 63 61 72 64 20 61 6c 6c  *.** Discard all
4100: 20 70 61 67 65 73 20 66 72 6f 6d 20 63 61 63 68   pages from cach
4110: 65 20 70 43 61 63 68 65 20 77 69 74 68 20 61 20  e pCache with a 
4120: 70 61 67 65 20 6e 75 6d 62 65 72 20 28 6b 65 79  page number (key
4130: 20 76 61 6c 75 65 29 20 0a 2a 2a 20 67 72 65 61   value) .** grea
4140: 74 65 72 20 74 68 61 6e 20 6f 72 20 65 71 75 61  ter than or equa
4150: 6c 20 74 6f 20 69 4c 69 6d 69 74 2e 20 41 6e 79  l to iLimit. Any
4160: 20 70 69 6e 6e 65 64 20 70 61 67 65 73 20 74 68   pinned pages th
4170: 61 74 20 6d 65 65 74 20 74 68 69 73 20 0a 2a 2a  at meet this .**
4180: 20 63 72 69 74 65 72 69 61 20 61 72 65 20 75 6e   criteria are un
4190: 70 69 6e 6e 65 64 20 62 65 66 6f 72 65 20 74 68  pinned before th
41a0: 65 79 20 61 72 65 20 64 69 73 63 61 72 64 65 64  ey are discarded
41b0: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 50 43 61 63  ..**.** The PCac
41c0: 68 65 20 6d 75 74 65 78 20 6d 75 73 74 20 62 65  he mutex must be
41d0: 20 68 65 6c 64 20 77 68 65 6e 20 74 68 69 73 20   held when this 
41e0: 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c  function is call
41f0: 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ed..*/.static vo
4200: 69 64 20 70 63 61 63 68 65 31 54 72 75 6e 63 61  id pcache1Trunca
4210: 74 65 55 6e 73 61 66 65 28 0a 20 20 50 43 61 63  teUnsafe(.  PCac
4220: 68 65 31 20 2a 70 43 61 63 68 65 2c 20 20 20 20  he1 *pCache,    
4230: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20           /* The 
4240: 63 61 63 68 65 20 74 6f 20 74 72 75 6e 63 61 74  cache to truncat
4250: 65 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20  e */.  unsigned 
4260: 69 6e 74 20 69 4c 69 6d 69 74 20 20 20 20 20 20  int iLimit      
4270: 20 20 20 20 2f 2a 20 44 72 6f 70 20 70 61 67 65      /* Drop page
4280: 73 20 77 69 74 68 20 74 68 69 73 20 70 67 6e 6f  s with this pgno
4290: 20 6f 72 20 6c 61 72 67 65 72 20 2a 2f 0a 29 7b   or larger */.){
42a0: 0a 20 20 54 45 53 54 4f 4e 4c 59 28 20 75 6e 73  .  TESTONLY( uns
42b0: 69 67 6e 65 64 20 69 6e 74 20 6e 50 61 67 65 20  igned int nPage 
42c0: 3d 20 30 3b 20 29 20 20 2f 2a 20 54 6f 20 61 73  = 0; )  /* To as
42d0: 73 65 72 74 20 70 43 61 63 68 65 2d 3e 6e 50 61  sert pCache->nPa
42e0: 67 65 20 69 73 20 63 6f 72 72 65 63 74 20 2a 2f  ge is correct */
42f0: 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  .  unsigned int 
4300: 68 3b 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c  h;.  assert( sql
4310: 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28  ite3_mutex_held(
4320: 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 2d 3e  pCache->pGroup->
4330: 6d 75 74 65 78 29 20 29 3b 0a 20 20 66 6f 72 28  mutex) );.  for(
4340: 68 3d 30 3b 20 68 3c 70 43 61 63 68 65 2d 3e 6e  h=0; h<pCache->n
4350: 48 61 73 68 3b 20 68 2b 2b 29 7b 0a 20 20 20 20  Hash; h++){.    
4360: 50 67 48 64 72 31 20 2a 2a 70 70 20 3d 20 26 70  PgHdr1 **pp = &p
4370: 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d  Cache->apHash[h]
4380: 3b 20 0a 20 20 20 20 50 67 48 64 72 31 20 2a 70  ; .    PgHdr1 *p
4390: 50 61 67 65 3b 0a 20 20 20 20 77 68 69 6c 65 28  Page;.    while(
43a0: 20 28 70 50 61 67 65 20 3d 20 2a 70 70 29 21 3d   (pPage = *pp)!=
43b0: 30 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 70  0 ){.      if( p
43c0: 50 61 67 65 2d 3e 69 4b 65 79 3e 3d 69 4c 69 6d  Page->iKey>=iLim
43d0: 69 74 20 29 7b 0a 20 20 20 20 20 20 20 20 70 43  it ){.        pC
43e0: 61 63 68 65 2d 3e 6e 50 61 67 65 2d 2d 3b 0a 20  ache->nPage--;. 
43f0: 20 20 20 20 20 20 20 2a 70 70 20 3d 20 70 50 61         *pp = pPa
4400: 67 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20  ge->pNext;.     
4410: 20 20 20 69 66 28 20 21 70 50 61 67 65 2d 3e 69     if( !pPage->i
4420: 73 50 69 6e 6e 65 64 20 29 20 70 63 61 63 68 65  sPinned ) pcache
4430: 31 50 69 6e 50 61 67 65 28 70 50 61 67 65 29 3b  1PinPage(pPage);
4440: 0a 20 20 20 20 20 20 20 20 70 63 61 63 68 65 31  .        pcache1
4450: 46 72 65 65 50 61 67 65 28 70 50 61 67 65 29 3b  FreePage(pPage);
4460: 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  .      }else{.  
4470: 20 20 20 20 20 20 70 70 20 3d 20 26 70 50 61 67        pp = &pPag
4480: 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20  e->pNext;.      
4490: 20 20 54 45 53 54 4f 4e 4c 59 28 20 6e 50 61 67    TESTONLY( nPag
44a0: 65 2b 2b 3b 20 29 0a 20 20 20 20 20 20 7d 0a 20  e++; ).      }. 
44b0: 20 20 20 7d 0a 20 20 7d 0a 20 20 61 73 73 65 72     }.  }.  asser
44c0: 74 28 20 70 43 61 63 68 65 2d 3e 6e 50 61 67 65  t( pCache->nPage
44d0: 3d 3d 6e 50 61 67 65 20 29 3b 0a 7d 0a 0a 2f 2a  ==nPage );.}../*
44e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
44f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
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 2a 2a 2a 2a 2a 2a 2f 0a 2f  *************/./
4530: 2a 2a 2a 2a 2a 2a 2a 2a 20 73 71 6c 69 74 65 33  ******** sqlite3
4540: 5f 70 63 61 63 68 65 20 4d 65 74 68 6f 64 73 20  _pcache Methods 
4550: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4560: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4570: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a  **************/.
4580: 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74  ./*.** Implement
4590: 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c  ation of the sql
45a0: 69 74 65 33 5f 70 63 61 63 68 65 2e 78 49 6e 69  ite3_pcache.xIni
45b0: 74 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61  t method..*/.sta
45c0: 74 69 63 20 69 6e 74 20 70 63 61 63 68 65 31 49  tic int pcache1I
45d0: 6e 69 74 28 76 6f 69 64 20 2a 4e 6f 74 55 73 65  nit(void *NotUse
45e0: 64 29 7b 0a 20 20 55 4e 55 53 45 44 5f 50 41 52  d){.  UNUSED_PAR
45f0: 41 4d 45 54 45 52 28 4e 6f 74 55 73 65 64 29 3b  AMETER(NotUsed);
4600: 0a 20 20 61 73 73 65 72 74 28 20 70 63 61 63 68  .  assert( pcach
4610: 65 31 2e 69 73 49 6e 69 74 3d 3d 30 20 29 3b 0a  e1.isInit==0 );.
4620: 20 20 6d 65 6d 73 65 74 28 26 70 63 61 63 68 65    memset(&pcache
4630: 31 2c 20 30 2c 20 73 69 7a 65 6f 66 28 70 63 61  1, 0, sizeof(pca
4640: 63 68 65 31 29 29 3b 0a 20 20 69 66 28 20 73 71  che1));.  if( sq
4650: 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69  lite3GlobalConfi
4660: 67 2e 62 43 6f 72 65 4d 75 74 65 78 20 29 7b 0a  g.bCoreMutex ){.
4670: 20 20 20 20 70 63 61 63 68 65 31 2e 67 72 70 2e      pcache1.grp.
4680: 6d 75 74 65 78 20 3d 20 73 71 6c 69 74 65 33 5f  mutex = sqlite3_
4690: 6d 75 74 65 78 5f 61 6c 6c 6f 63 28 53 51 4c 49  mutex_alloc(SQLI
46a0: 54 45 5f 4d 55 54 45 58 5f 53 54 41 54 49 43 5f  TE_MUTEX_STATIC_
46b0: 4c 52 55 29 3b 0a 20 20 20 20 70 63 61 63 68 65  LRU);.    pcache
46c0: 31 2e 6d 75 74 65 78 20 3d 20 73 71 6c 69 74 65  1.mutex = sqlite
46d0: 33 5f 6d 75 74 65 78 5f 61 6c 6c 6f 63 28 53 51  3_mutex_alloc(SQ
46e0: 4c 49 54 45 5f 4d 55 54 45 58 5f 53 54 41 54 49  LITE_MUTEX_STATI
46f0: 43 5f 50 4d 45 4d 29 3b 0a 20 20 7d 0a 20 20 70  C_PMEM);.  }.  p
4700: 63 61 63 68 65 31 2e 67 72 70 2e 6d 78 50 69 6e  cache1.grp.mxPin
4710: 6e 65 64 20 3d 20 31 30 3b 0a 20 20 70 63 61 63  ned = 10;.  pcac
4720: 68 65 31 2e 69 73 49 6e 69 74 20 3d 20 31 3b 0a  he1.isInit = 1;.
4730: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
4740: 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70  OK;.}../*.** Imp
4750: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74  lementation of t
4760: 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68  he sqlite3_pcach
4770: 65 2e 78 53 68 75 74 64 6f 77 6e 20 6d 65 74 68  e.xShutdown meth
4780: 6f 64 2e 0a 2a 2a 20 4e 6f 74 65 20 74 68 61 74  od..** Note that
4790: 20 74 68 65 20 73 74 61 74 69 63 20 6d 75 74 65   the static mute
47a0: 78 20 61 6c 6c 6f 63 61 74 65 64 20 69 6e 20 78  x allocated in x
47b0: 49 6e 69 74 20 64 6f 65 73 20 0a 2a 2a 20 6e 6f  Init does .** no
47c0: 74 20 6e 65 65 64 20 74 6f 20 62 65 20 66 72 65  t need to be fre
47d0: 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ed..*/.static vo
47e0: 69 64 20 70 63 61 63 68 65 31 53 68 75 74 64 6f  id pcache1Shutdo
47f0: 77 6e 28 76 6f 69 64 20 2a 4e 6f 74 55 73 65 64  wn(void *NotUsed
4800: 29 7b 0a 20 20 55 4e 55 53 45 44 5f 50 41 52 41  ){.  UNUSED_PARA
4810: 4d 45 54 45 52 28 4e 6f 74 55 73 65 64 29 3b 0a  METER(NotUsed);.
4820: 20 20 61 73 73 65 72 74 28 20 70 63 61 63 68 65    assert( pcache
4830: 31 2e 69 73 49 6e 69 74 21 3d 30 20 29 3b 0a 20  1.isInit!=0 );. 
4840: 20 6d 65 6d 73 65 74 28 26 70 63 61 63 68 65 31   memset(&pcache1
4850: 2c 20 30 2c 20 73 69 7a 65 6f 66 28 70 63 61 63  , 0, sizeof(pcac
4860: 68 65 31 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  he1));.}../*.** 
4870: 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  Implementation o
4880: 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63  f the sqlite3_pc
4890: 61 63 68 65 2e 78 43 72 65 61 74 65 20 6d 65 74  ache.xCreate met
48a0: 68 6f 64 2e 0a 2a 2a 0a 2a 2a 20 41 6c 6c 6f 63  hod..**.** Alloc
48b0: 61 74 65 20 61 20 6e 65 77 20 63 61 63 68 65 2e  ate a new cache.
48c0: 0a 2a 2f 0a 73 74 61 74 69 63 20 73 71 6c 69 74  .*/.static sqlit
48d0: 65 33 5f 70 63 61 63 68 65 20 2a 70 63 61 63 68  e3_pcache *pcach
48e0: 65 31 43 72 65 61 74 65 28 69 6e 74 20 73 7a 50  e1Create(int szP
48f0: 61 67 65 2c 20 69 6e 74 20 73 7a 45 78 74 72 61  age, int szExtra
4900: 2c 20 69 6e 74 20 62 50 75 72 67 65 61 62 6c 65  , int bPurgeable
4910: 29 7b 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43  ){.  PCache1 *pC
4920: 61 63 68 65 3b 20 20 20 20 20 20 2f 2a 20 54 68  ache;      /* Th
4930: 65 20 6e 65 77 6c 79 20 63 72 65 61 74 65 64 20  e newly created 
4940: 70 61 67 65 20 63 61 63 68 65 20 2a 2f 0a 20 20  page cache */.  
4950: 50 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 3b 20  PGroup *pGroup; 
4960: 20 20 20 20 20 20 2f 2a 20 54 68 65 20 67 72 6f        /* The gro
4970: 75 70 20 74 68 65 20 6e 65 77 20 70 61 67 65 20  up the new page 
4980: 63 61 63 68 65 20 77 69 6c 6c 20 62 65 6c 6f 6e  cache will belon
4990: 67 20 74 6f 20 2a 2f 0a 20 20 69 6e 74 20 73 7a  g to */.  int sz
49a0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
49b0: 2f 2a 20 42 79 74 65 73 20 6f 66 20 6d 65 6d 6f  /* Bytes of memo
49c0: 72 79 20 72 65 71 75 69 72 65 64 20 74 6f 20 61  ry required to a
49d0: 6c 6c 6f 63 61 74 65 20 74 68 65 20 6e 65 77 20  llocate the new 
49e0: 63 61 63 68 65 20 2a 2f 0a 0a 20 20 2f 2a 0a 20  cache */..  /*. 
49f0: 20 2a 2a 20 54 68 65 20 73 65 70 61 72 61 74 65   ** The separate
4a00: 43 61 63 68 65 20 76 61 72 69 61 62 6c 65 20 69  Cache variable i
4a10: 73 20 74 72 75 65 20 69 66 20 65 61 63 68 20 50  s true if each P
4a20: 43 61 63 68 65 20 68 61 73 20 69 74 73 20 6f 77  Cache has its ow
4a30: 6e 20 70 72 69 76 61 74 65 0a 20 20 2a 2a 20 50  n private.  ** P
4a40: 47 72 6f 75 70 2e 20 20 49 6e 20 6f 74 68 65 72  Group.  In other
4a50: 20 77 6f 72 64 73 2c 20 73 65 70 61 72 61 74 65   words, separate
4a60: 43 61 63 68 65 20 69 73 20 74 72 75 65 20 66 6f  Cache is true fo
4a70: 72 20 6d 6f 64 65 20 28 31 29 20 77 68 65 72 65  r mode (1) where
4a80: 20 6e 6f 0a 20 20 2a 2a 20 6d 75 74 65 78 69 6e   no.  ** mutexin
4a90: 67 20 69 73 20 72 65 71 75 69 72 65 64 2e 0a 20  g is required.. 
4aa0: 20 2a 2a 0a 20 20 2a 2a 20 20 20 2a 20 20 41 6c   **.  **   *  Al
4ab0: 77 61 79 73 20 75 73 65 20 61 20 75 6e 69 66 69  ways use a unifi
4ac0: 65 64 20 63 61 63 68 65 20 28 6d 6f 64 65 2d 32  ed cache (mode-2
4ad0: 29 20 69 66 20 45 4e 41 42 4c 45 5f 4d 45 4d 4f  ) if ENABLE_MEMO
4ae0: 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 0a 20 20  RY_MANAGEMENT.  
4af0: 2a 2a 0a 20 20 2a 2a 20 20 20 2a 20 20 41 6c 77  **.  **   *  Alw
4b00: 61 79 73 20 75 73 65 20 61 20 75 6e 69 66 69 65  ays use a unifie
4b10: 64 20 63 61 63 68 65 20 69 6e 20 73 69 6e 67 6c  d cache in singl
4b20: 65 2d 74 68 72 65 61 64 65 64 20 61 70 70 6c 69  e-threaded appli
4b30: 63 61 74 69 6f 6e 73 0a 20 20 2a 2a 0a 20 20 2a  cations.  **.  *
4b40: 2a 20 20 20 2a 20 20 4f 74 68 65 72 77 69 73 65  *   *  Otherwise
4b50: 20 28 69 66 20 6d 75 6c 74 69 2d 74 68 72 65 61   (if multi-threa
4b60: 64 65 64 20 61 6e 64 20 45 4e 41 42 4c 45 5f 4d  ded and ENABLE_M
4b70: 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54  EMORY_MANAGEMENT
4b80: 20 69 73 20 6f 66 66 29 0a 20 20 2a 2a 20 20 20   is off).  **   
4b90: 20 20 20 75 73 65 20 73 65 70 61 72 61 74 65 20     use separate 
4ba0: 63 61 63 68 65 73 20 28 6d 6f 64 65 2d 31 29 0a  caches (mode-1).
4bb0: 20 20 2a 2f 0a 23 69 66 20 64 65 66 69 6e 65 64    */.#if defined
4bc0: 28 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d  (SQLITE_ENABLE_M
4bd0: 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54  EMORY_MANAGEMENT
4be0: 29 20 7c 7c 20 53 51 4c 49 54 45 5f 54 48 52 45  ) || SQLITE_THRE
4bf0: 41 44 53 41 46 45 3d 3d 30 0a 20 20 63 6f 6e 73  ADSAFE==0.  cons
4c00: 74 20 69 6e 74 20 73 65 70 61 72 61 74 65 43 61  t int separateCa
4c10: 63 68 65 20 3d 20 30 3b 0a 23 65 6c 73 65 0a 20  che = 0;.#else. 
4c20: 20 69 6e 74 20 73 65 70 61 72 61 74 65 43 61 63   int separateCac
4c30: 68 65 20 3d 20 73 71 6c 69 74 65 33 47 6c 6f 62  he = sqlite3Glob
4c40: 61 6c 43 6f 6e 66 69 67 2e 62 43 6f 72 65 4d 75  alConfig.bCoreMu
4c50: 74 65 78 3e 30 3b 0a 23 65 6e 64 69 66 0a 0a 20  tex>0;.#endif.. 
4c60: 20 61 73 73 65 72 74 28 20 28 73 7a 50 61 67 65   assert( (szPage
4c70: 20 26 20 28 73 7a 50 61 67 65 2d 31 29 29 3d 3d   & (szPage-1))==
4c80: 30 20 26 26 20 73 7a 50 61 67 65 3e 3d 35 31 32  0 && szPage>=512
4c90: 20 26 26 20 73 7a 50 61 67 65 3c 3d 36 35 35 33   && szPage<=6553
4ca0: 36 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 73  6 );.  assert( s
4cb0: 7a 45 78 74 72 61 20 3c 20 33 30 30 20 29 3b 0a  zExtra < 300 );.
4cc0: 0a 20 20 73 7a 20 3d 20 73 69 7a 65 6f 66 28 50  .  sz = sizeof(P
4cd0: 43 61 63 68 65 31 29 20 2b 20 73 69 7a 65 6f 66  Cache1) + sizeof
4ce0: 28 50 47 72 6f 75 70 29 2a 73 65 70 61 72 61 74  (PGroup)*separat
4cf0: 65 43 61 63 68 65 3b 0a 20 20 70 43 61 63 68 65  eCache;.  pCache
4d00: 20 3d 20 28 50 43 61 63 68 65 31 20 2a 29 73 71   = (PCache1 *)sq
4d10: 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28  lite3MallocZero(
4d20: 73 7a 29 3b 0a 20 20 69 66 28 20 70 43 61 63 68  sz);.  if( pCach
4d30: 65 20 29 7b 0a 20 20 20 20 69 66 28 20 73 65 70  e ){.    if( sep
4d40: 61 72 61 74 65 43 61 63 68 65 20 29 7b 0a 20 20  arateCache ){.  
4d50: 20 20 20 20 70 47 72 6f 75 70 20 3d 20 28 50 47      pGroup = (PG
4d60: 72 6f 75 70 2a 29 26 70 43 61 63 68 65 5b 31 5d  roup*)&pCache[1]
4d70: 3b 0a 20 20 20 20 20 20 70 47 72 6f 75 70 2d 3e  ;.      pGroup->
4d80: 6d 78 50 69 6e 6e 65 64 20 3d 20 31 30 3b 0a 20  mxPinned = 10;. 
4d90: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
4da0: 70 47 72 6f 75 70 20 3d 20 26 70 63 61 63 68 65  pGroup = &pcache
4db0: 31 2e 67 72 70 3b 0a 20 20 20 20 7d 0a 20 20 20  1.grp;.    }.   
4dc0: 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 20   pCache->pGroup 
4dd0: 3d 20 70 47 72 6f 75 70 3b 0a 20 20 20 20 70 43  = pGroup;.    pC
4de0: 61 63 68 65 2d 3e 73 7a 50 61 67 65 20 3d 20 73  ache->szPage = s
4df0: 7a 50 61 67 65 3b 0a 20 20 20 20 70 43 61 63 68  zPage;.    pCach
4e00: 65 2d 3e 73 7a 45 78 74 72 61 20 3d 20 73 7a 45  e->szExtra = szE
4e10: 78 74 72 61 3b 0a 20 20 20 20 70 43 61 63 68 65  xtra;.    pCache
4e20: 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 3d 20 28  ->bPurgeable = (
4e30: 62 50 75 72 67 65 61 62 6c 65 20 3f 20 31 20 3a  bPurgeable ? 1 :
4e40: 20 30 29 3b 0a 20 20 20 20 69 66 28 20 62 50 75   0);.    if( bPu
4e50: 72 67 65 61 62 6c 65 20 29 7b 0a 20 20 20 20 20  rgeable ){.     
4e60: 20 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 20 3d 20   pCache->nMin = 
4e70: 31 30 3b 0a 20 20 20 20 20 20 70 63 61 63 68 65  10;.      pcache
4e80: 31 45 6e 74 65 72 4d 75 74 65 78 28 70 47 72 6f  1EnterMutex(pGro
4e90: 75 70 29 3b 0a 20 20 20 20 20 20 70 47 72 6f 75  up);.      pGrou
4ea0: 70 2d 3e 6e 4d 69 6e 50 61 67 65 20 2b 3d 20 70  p->nMinPage += p
4eb0: 43 61 63 68 65 2d 3e 6e 4d 69 6e 3b 0a 20 20 20  Cache->nMin;.   
4ec0: 20 20 20 70 47 72 6f 75 70 2d 3e 6d 78 50 69 6e     pGroup->mxPin
4ed0: 6e 65 64 20 3d 20 70 47 72 6f 75 70 2d 3e 6e 4d  ned = pGroup->nM
4ee0: 61 78 50 61 67 65 20 2b 20 31 30 20 2d 20 70 47  axPage + 10 - pG
4ef0: 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67 65 3b 0a  roup->nMinPage;.
4f00: 20 20 20 20 20 20 70 63 61 63 68 65 31 4c 65 61        pcache1Lea
4f10: 76 65 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b  veMutex(pGroup);
4f20: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74  .    }.  }.  ret
4f30: 75 72 6e 20 28 73 71 6c 69 74 65 33 5f 70 63 61  urn (sqlite3_pca
4f40: 63 68 65 20 2a 29 70 43 61 63 68 65 3b 0a 7d 0a  che *)pCache;.}.
4f50: 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74  ./*.** Implement
4f60: 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c  ation of the sql
4f70: 69 74 65 33 5f 70 63 61 63 68 65 2e 78 43 61 63  ite3_pcache.xCac
4f80: 68 65 73 69 7a 65 20 6d 65 74 68 6f 64 2e 20 0a  hesize method. .
4f90: 2a 2a 0a 2a 2a 20 43 6f 6e 66 69 67 75 72 65 20  **.** Configure 
4fa0: 74 68 65 20 63 61 63 68 65 5f 73 69 7a 65 20 6c  the cache_size l
4fb0: 69 6d 69 74 20 66 6f 72 20 61 20 63 61 63 68 65  imit for a cache
4fc0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
4fd0: 20 70 63 61 63 68 65 31 43 61 63 68 65 73 69 7a   pcache1Cachesiz
4fe0: 65 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  e(sqlite3_pcache
4ff0: 20 2a 70 2c 20 69 6e 74 20 6e 4d 61 78 29 7b 0a   *p, int nMax){.
5000: 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68    PCache1 *pCach
5010: 65 20 3d 20 28 50 43 61 63 68 65 31 20 2a 29 70  e = (PCache1 *)p
5020: 3b 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e  ;.  if( pCache->
5030: 62 50 75 72 67 65 61 62 6c 65 20 29 7b 0a 20 20  bPurgeable ){.  
5040: 20 20 50 47 72 6f 75 70 20 2a 70 47 72 6f 75 70    PGroup *pGroup
5050: 20 3d 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75   = pCache->pGrou
5060: 70 3b 0a 20 20 20 20 70 63 61 63 68 65 31 45 6e  p;.    pcache1En
5070: 74 65 72 4d 75 74 65 78 28 70 47 72 6f 75 70 29  terMutex(pGroup)
5080: 3b 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e 6e 4d  ;.    pGroup->nM
5090: 61 78 50 61 67 65 20 2b 3d 20 28 6e 4d 61 78 20  axPage += (nMax 
50a0: 2d 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 29 3b  - pCache->nMax);
50b0: 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e 6d 78 50  .    pGroup->mxP
50c0: 69 6e 6e 65 64 20 3d 20 70 47 72 6f 75 70 2d 3e  inned = pGroup->
50d0: 6e 4d 61 78 50 61 67 65 20 2b 20 31 30 20 2d 20  nMaxPage + 10 - 
50e0: 70 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67 65  pGroup->nMinPage
50f0: 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 6e 4d  ;.    pCache->nM
5100: 61 78 20 3d 20 6e 4d 61 78 3b 0a 20 20 20 20 70  ax = nMax;.    p
5110: 43 61 63 68 65 2d 3e 6e 39 30 70 63 74 20 3d 20  Cache->n90pct = 
5120: 70 43 61 63 68 65 2d 3e 6e 4d 61 78 2a 39 2f 31  pCache->nMax*9/1
5130: 30 3b 0a 20 20 20 20 70 63 61 63 68 65 31 45 6e  0;.    pcache1En
5140: 66 6f 72 63 65 4d 61 78 50 61 67 65 28 70 47 72  forceMaxPage(pGr
5150: 6f 75 70 29 3b 0a 20 20 20 20 70 63 61 63 68 65  oup);.    pcache
5160: 31 4c 65 61 76 65 4d 75 74 65 78 28 70 47 72 6f  1LeaveMutex(pGro
5170: 75 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a  up);.  }.}../*.*
5180: 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  * Implementation
5190: 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f   of the sqlite3_
51a0: 70 63 61 63 68 65 2e 78 53 68 72 69 6e 6b 20 6d  pcache.xShrink m
51b0: 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20 46 72  ethod. .**.** Fr
51c0: 65 65 20 75 70 20 61 73 20 6d 75 63 68 20 6d 65  ee up as much me
51d0: 6d 6f 72 79 20 61 73 20 70 6f 73 73 69 62 6c 65  mory as possible
51e0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
51f0: 20 70 63 61 63 68 65 31 53 68 72 69 6e 6b 28 73   pcache1Shrink(s
5200: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70  qlite3_pcache *p
5210: 29 7b 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43  ){.  PCache1 *pC
5220: 61 63 68 65 20 3d 20 28 50 43 61 63 68 65 31 2a  ache = (PCache1*
5230: 29 70 3b 0a 20 20 69 66 28 20 70 43 61 63 68 65  )p;.  if( pCache
5240: 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 29 7b 0a  ->bPurgeable ){.
5250: 20 20 20 20 50 47 72 6f 75 70 20 2a 70 47 72 6f      PGroup *pGro
5260: 75 70 20 3d 20 70 43 61 63 68 65 2d 3e 70 47 72  up = pCache->pGr
5270: 6f 75 70 3b 0a 20 20 20 20 69 6e 74 20 73 61 76  oup;.    int sav
5280: 65 64 4d 61 78 50 61 67 65 3b 0a 20 20 20 20 70  edMaxPage;.    p
5290: 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78  cache1EnterMutex
52a0: 28 70 47 72 6f 75 70 29 3b 0a 20 20 20 20 73 61  (pGroup);.    sa
52b0: 76 65 64 4d 61 78 50 61 67 65 20 3d 20 70 47 72  vedMaxPage = pGr
52c0: 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65 3b 0a 20  oup->nMaxPage;. 
52d0: 20 20 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50     pGroup->nMaxP
52e0: 61 67 65 20 3d 20 30 3b 0a 20 20 20 20 70 63 61  age = 0;.    pca
52f0: 63 68 65 31 45 6e 66 6f 72 63 65 4d 61 78 50 61  che1EnforceMaxPa
5300: 67 65 28 70 47 72 6f 75 70 29 3b 0a 20 20 20 20  ge(pGroup);.    
5310: 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65  pGroup->nMaxPage
5320: 20 3d 20 73 61 76 65 64 4d 61 78 50 61 67 65 3b   = savedMaxPage;
5330: 0a 20 20 20 20 70 63 61 63 68 65 31 4c 65 61 76  .    pcache1Leav
5340: 65 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b 0a  eMutex(pGroup);.
5350: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70    }.}../*.** Imp
5360: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74  lementation of t
5370: 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68  he sqlite3_pcach
5380: 65 2e 78 50 61 67 65 63 6f 75 6e 74 20 6d 65 74  e.xPagecount met
5390: 68 6f 64 2e 20 0a 2a 2f 0a 73 74 61 74 69 63 20  hod. .*/.static 
53a0: 69 6e 74 20 70 63 61 63 68 65 31 50 61 67 65 63  int pcache1Pagec
53b0: 6f 75 6e 74 28 73 71 6c 69 74 65 33 5f 70 63 61  ount(sqlite3_pca
53c0: 63 68 65 20 2a 70 29 7b 0a 20 20 69 6e 74 20 6e  che *p){.  int n
53d0: 3b 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43 61  ;.  PCache1 *pCa
53e0: 63 68 65 20 3d 20 28 50 43 61 63 68 65 31 2a 29  che = (PCache1*)
53f0: 70 3b 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65  p;.  pcache1Ente
5400: 72 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e 70  rMutex(pCache->p
5410: 47 72 6f 75 70 29 3b 0a 20 20 6e 20 3d 20 70 43  Group);.  n = pC
5420: 61 63 68 65 2d 3e 6e 50 61 67 65 3b 0a 20 20 70  ache->nPage;.  p
5430: 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78  cache1LeaveMutex
5440: 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 29  (pCache->pGroup)
5450: 3b 0a 20 20 72 65 74 75 72 6e 20 6e 3b 0a 7d 0a  ;.  return n;.}.
5460: 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74  ./*.** Implement
5470: 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c  ation of the sql
5480: 69 74 65 33 5f 70 63 61 63 68 65 2e 78 46 65 74  ite3_pcache.xFet
5490: 63 68 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a  ch method. .**.*
54a0: 2a 20 46 65 74 63 68 20 61 20 70 61 67 65 20 62  * Fetch a page b
54b0: 79 20 6b 65 79 20 76 61 6c 75 65 2e 0a 2a 2a 0a  y key value..**.
54c0: 2a 2a 20 57 68 65 74 68 65 72 20 6f 72 20 6e 6f  ** Whether or no
54d0: 74 20 61 20 6e 65 77 20 70 61 67 65 20 6d 61 79  t a new page may
54e0: 20 62 65 20 61 6c 6c 6f 63 61 74 65 64 20 62 79   be allocated by
54f0: 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 64   this function d
5500: 65 70 65 6e 64 73 20 6f 6e 0a 2a 2a 20 74 68 65  epends on.** the
5510: 20 76 61 6c 75 65 20 6f 66 20 74 68 65 20 63 72   value of the cr
5520: 65 61 74 65 46 6c 61 67 20 61 72 67 75 6d 65 6e  eateFlag argumen
5530: 74 2e 20 20 30 20 6d 65 61 6e 73 20 64 6f 20 6e  t.  0 means do n
5540: 6f 74 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e 65  ot allocate a ne
5550: 77 0a 2a 2a 20 70 61 67 65 2e 20 20 31 20 6d 65  w.** page.  1 me
5560: 61 6e 73 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e  ans allocate a n
5570: 65 77 20 70 61 67 65 20 69 66 20 73 70 61 63 65  ew page if space
5580: 20 69 73 20 65 61 73 69 6c 79 20 61 76 61 69 6c   is easily avail
5590: 61 62 6c 65 2e 20 20 32 20 0a 2a 2a 20 6d 65 61  able.  2 .** mea
55a0: 6e 73 20 74 6f 20 74 72 79 20 72 65 61 6c 6c 79  ns to try really
55b0: 20 68 61 72 64 20 74 6f 20 61 6c 6c 6f 63 61 74   hard to allocat
55c0: 65 20 61 20 6e 65 77 20 70 61 67 65 2e 0a 2a 2a  e a new page..**
55d0: 0a 2a 2a 20 46 6f 72 20 61 20 6e 6f 6e 2d 70 75  .** For a non-pu
55e0: 72 67 65 61 62 6c 65 20 63 61 63 68 65 20 28 61  rgeable cache (a
55f0: 20 63 61 63 68 65 20 75 73 65 64 20 61 73 20 74   cache used as t
5600: 68 65 20 73 74 6f 72 61 67 65 20 66 6f 72 20 61  he storage for a
5610: 6e 20 69 6e 2d 6d 65 6d 6f 72 79 0a 2a 2a 20 64  n in-memory.** d
5620: 61 74 61 62 61 73 65 29 20 74 68 65 72 65 20 69  atabase) there i
5630: 73 20 72 65 61 6c 6c 79 20 6e 6f 20 64 69 66 66  s really no diff
5640: 65 72 65 6e 63 65 20 62 65 74 77 65 65 6e 20 63  erence between c
5650: 72 65 61 74 65 46 6c 61 67 20 31 20 61 6e 64 20  reateFlag 1 and 
5660: 32 2e 20 20 53 6f 0a 2a 2a 20 74 68 65 20 63 61  2.  So.** the ca
5670: 6c 6c 69 6e 67 20 66 75 6e 63 74 69 6f 6e 20 28  lling function (
5680: 70 63 61 63 68 65 2e 63 29 20 77 69 6c 6c 20 6e  pcache.c) will n
5690: 65 76 65 72 20 68 61 76 65 20 61 20 63 72 65 61  ever have a crea
56a0: 74 65 46 6c 61 67 20 6f 66 20 31 20 6f 6e 0a 2a  teFlag of 1 on.*
56b0: 2a 20 61 20 6e 6f 6e 2d 70 75 72 67 65 61 62 6c  * a non-purgeabl
56c0: 65 20 63 61 63 68 65 2e 0a 2a 2a 0a 2a 2a 20 54  e cache..**.** T
56d0: 68 65 72 65 20 61 72 65 20 74 68 72 65 65 20 64  here are three d
56e0: 69 66 66 65 72 65 6e 74 20 61 70 70 72 6f 61 63  ifferent approac
56f0: 68 65 73 20 74 6f 20 6f 62 74 61 69 6e 69 6e 67  hes to obtaining
5700: 20 73 70 61 63 65 20 66 6f 72 20 61 20 70 61 67   space for a pag
5710: 65 2c 0a 2a 2a 20 64 65 70 65 6e 64 69 6e 67 20  e,.** depending 
5720: 6f 6e 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20  on the value of 
5730: 70 61 72 61 6d 65 74 65 72 20 63 72 65 61 74 65  parameter create
5740: 46 6c 61 67 20 28 77 68 69 63 68 20 6d 61 79 20  Flag (which may 
5750: 62 65 20 30 2c 20 31 20 6f 72 20 32 29 2e 0a 2a  be 0, 1 or 2)..*
5760: 2a 0a 2a 2a 20 20 20 31 2e 20 52 65 67 61 72 64  *.**   1. Regard
5770: 6c 65 73 73 20 6f 66 20 74 68 65 20 76 61 6c 75  less of the valu
5780: 65 20 6f 66 20 63 72 65 61 74 65 46 6c 61 67 2c  e of createFlag,
5790: 20 74 68 65 20 63 61 63 68 65 20 69 73 20 73 65   the cache is se
57a0: 61 72 63 68 65 64 20 66 6f 72 20 61 20 0a 2a 2a  arched for a .**
57b0: 20 20 20 20 20 20 63 6f 70 79 20 6f 66 20 74 68        copy of th
57c0: 65 20 72 65 71 75 65 73 74 65 64 20 70 61 67 65  e requested page
57d0: 2e 20 49 66 20 6f 6e 65 20 69 73 20 66 6f 75 6e  . If one is foun
57e0: 64 2c 20 69 74 20 69 73 20 72 65 74 75 72 6e 65  d, it is returne
57f0: 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 32 2e 20 49 66  d..**.**   2. If
5800: 20 63 72 65 61 74 65 46 6c 61 67 3d 3d 30 20 61   createFlag==0 a
5810: 6e 64 20 74 68 65 20 70 61 67 65 20 69 73 20 6e  nd the page is n
5820: 6f 74 20 61 6c 72 65 61 64 79 20 69 6e 20 74 68  ot already in th
5830: 65 20 63 61 63 68 65 2c 20 4e 55 4c 4c 20 69 73  e cache, NULL is
5840: 0a 2a 2a 20 20 20 20 20 20 72 65 74 75 72 6e 65  .**      returne
5850: 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 33 2e 20 49 66  d..**.**   3. If
5860: 20 63 72 65 61 74 65 46 6c 61 67 20 69 73 20 31   createFlag is 1
5870: 2c 20 61 6e 64 20 74 68 65 20 70 61 67 65 20 69  , and the page i
5880: 73 20 6e 6f 74 20 61 6c 72 65 61 64 79 20 69 6e  s not already in
5890: 20 74 68 65 20 63 61 63 68 65 2c 20 74 68 65 6e   the cache, then
58a0: 0a 2a 2a 20 20 20 20 20 20 72 65 74 75 72 6e 20  .**      return 
58b0: 4e 55 4c 4c 20 28 64 6f 20 6e 6f 74 20 61 6c 6c  NULL (do not all
58c0: 6f 63 61 74 65 20 61 20 6e 65 77 20 70 61 67 65  ocate a new page
58d0: 29 20 69 66 20 61 6e 79 20 6f 66 20 74 68 65 20  ) if any of the 
58e0: 66 6f 6c 6c 6f 77 69 6e 67 0a 2a 2a 20 20 20 20  following.**    
58f0: 20 20 63 6f 6e 64 69 74 69 6f 6e 73 20 61 72 65    conditions are
5900: 20 74 72 75 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20   true:.**.**    
5910: 20 20 20 28 61 29 20 74 68 65 20 6e 75 6d 62 65     (a) the numbe
5920: 72 20 6f 66 20 70 61 67 65 73 20 70 69 6e 6e 65  r of pages pinne
5930: 64 20 62 79 20 74 68 65 20 63 61 63 68 65 20 69  d by the cache i
5940: 73 20 67 72 65 61 74 65 72 20 74 68 61 6e 0a 2a  s greater than.*
5950: 2a 20 20 20 20 20 20 20 20 20 20 20 50 43 61 63  *           PCac
5960: 68 65 31 2e 6e 4d 61 78 2c 20 6f 72 0a 2a 2a 0a  he1.nMax, or.**.
5970: 2a 2a 20 20 20 20 20 20 20 28 62 29 20 74 68 65  **       (b) the
5980: 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73   number of pages
5990: 20 70 69 6e 6e 65 64 20 62 79 20 74 68 65 20 63   pinned by the c
59a0: 61 63 68 65 20 69 73 20 67 72 65 61 74 65 72 20  ache is greater 
59b0: 74 68 61 6e 0a 2a 2a 20 20 20 20 20 20 20 20 20  than.**         
59c0: 20 20 74 68 65 20 73 75 6d 20 6f 66 20 6e 4d 61    the sum of nMa
59d0: 78 20 66 6f 72 20 61 6c 6c 20 70 75 72 67 65 61  x for all purgea
59e0: 62 6c 65 20 63 61 63 68 65 73 2c 20 6c 65 73 73  ble caches, less
59f0: 20 74 68 65 20 73 75 6d 20 6f 66 20 0a 2a 2a 20   the sum of .** 
5a00: 20 20 20 20 20 20 20 20 20 20 6e 4d 69 6e 20 66            nMin f
5a10: 6f 72 20 61 6c 6c 20 6f 74 68 65 72 20 70 75 72  or all other pur
5a20: 67 65 61 62 6c 65 20 63 61 63 68 65 73 2c 20 6f  geable caches, o
5a30: 72 0a 2a 2a 0a 2a 2a 20 20 20 34 2e 20 49 66 20  r.**.**   4. If 
5a40: 6e 6f 6e 65 20 6f 66 20 74 68 65 20 66 69 72 73  none of the firs
5a50: 74 20 74 68 72 65 65 20 63 6f 6e 64 69 74 69 6f  t three conditio
5a60: 6e 73 20 61 70 70 6c 79 20 61 6e 64 20 74 68 65  ns apply and the
5a70: 20 63 61 63 68 65 20 69 73 20 6d 61 72 6b 65 64   cache is marked
5a80: 0a 2a 2a 20 20 20 20 20 20 61 73 20 70 75 72 67  .**      as purg
5a90: 65 61 62 6c 65 2c 20 61 6e 64 20 69 66 20 6f 6e  eable, and if on
5aa0: 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69  e of the followi
5ab0: 6e 67 20 69 73 20 74 72 75 65 3a 0a 2a 2a 0a 2a  ng is true:.**.*
5ac0: 2a 20 20 20 20 20 20 20 28 61 29 20 54 68 65 20  *       (a) The 
5ad0: 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20  number of pages 
5ae0: 61 6c 6c 6f 63 61 74 65 64 20 66 6f 72 20 74 68  allocated for th
5af0: 65 20 63 61 63 68 65 20 69 73 20 61 6c 72 65 61  e cache is alrea
5b00: 64 79 20 0a 2a 2a 20 20 20 20 20 20 20 20 20 20  dy .**          
5b10: 20 50 43 61 63 68 65 31 2e 6e 4d 61 78 2c 20 6f   PCache1.nMax, o
5b20: 72 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 28 62  r.**.**       (b
5b30: 29 20 54 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  ) The number of 
5b40: 70 61 67 65 73 20 61 6c 6c 6f 63 61 74 65 64 20  pages allocated 
5b50: 66 6f 72 20 61 6c 6c 20 70 75 72 67 65 61 62 6c  for all purgeabl
5b60: 65 20 63 61 63 68 65 73 20 69 73 0a 2a 2a 20 20  e caches is.**  
5b70: 20 20 20 20 20 20 20 20 20 61 6c 72 65 61 64 79           already
5b80: 20 65 71 75 61 6c 20 74 6f 20 6f 72 20 67 72 65   equal to or gre
5b90: 61 74 65 72 20 74 68 61 6e 20 74 68 65 20 73 75  ater than the su
5ba0: 6d 20 6f 66 20 6e 4d 61 78 20 66 6f 72 20 61 6c  m of nMax for al
5bb0: 6c 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 70  l.**           p
5bc0: 75 72 67 65 61 62 6c 65 20 63 61 63 68 65 73 2c  urgeable caches,
5bd0: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 28 63 29  .**.**       (c)
5be0: 20 54 68 65 20 73 79 73 74 65 6d 20 69 73 20 75   The system is u
5bf0: 6e 64 65 72 20 6d 65 6d 6f 72 79 20 70 72 65 73  nder memory pres
5c00: 73 75 72 65 20 61 6e 64 20 77 61 6e 74 73 20 74  sure and wants t
5c10: 6f 20 61 76 6f 69 64 0a 2a 2a 20 20 20 20 20 20  o avoid.**      
5c20: 20 20 20 20 20 75 6e 6e 65 63 65 73 73 61 72 79       unnecessary
5c30: 20 70 61 67 65 73 20 63 61 63 68 65 20 65 6e 74   pages cache ent
5c40: 72 79 20 61 6c 6c 6f 63 61 74 69 6f 6e 73 0a 2a  ry allocations.*
5c50: 2a 0a 2a 2a 20 20 20 20 20 20 74 68 65 6e 20 61  *.**      then a
5c60: 74 74 65 6d 70 74 20 74 6f 20 72 65 63 79 63 6c  ttempt to recycl
5c70: 65 20 61 20 70 61 67 65 20 66 72 6f 6d 20 74 68  e a page from th
5c80: 65 20 4c 52 55 20 6c 69 73 74 2e 20 49 66 20 69  e LRU list. If i
5c90: 74 20 69 73 20 74 68 65 20 72 69 67 68 74 0a 2a  t is the right.*
5ca0: 2a 20 20 20 20 20 20 73 69 7a 65 2c 20 72 65 74  *      size, ret
5cb0: 75 72 6e 20 74 68 65 20 72 65 63 79 63 6c 65 64  urn the recycled
5cc0: 20 62 75 66 66 65 72 2e 20 4f 74 68 65 72 77 69   buffer. Otherwi
5cd0: 73 65 2c 20 66 72 65 65 20 74 68 65 20 62 75 66  se, free the buf
5ce0: 66 65 72 20 61 6e 64 0a 2a 2a 20 20 20 20 20 20  fer and.**      
5cf0: 70 72 6f 63 65 65 64 20 74 6f 20 73 74 65 70 20  proceed to step 
5d00: 35 2e 20 0a 2a 2a 0a 2a 2a 20 20 20 35 2e 20 4f  5. .**.**   5. O
5d10: 74 68 65 72 77 69 73 65 2c 20 61 6c 6c 6f 63 61  therwise, alloca
5d20: 74 65 20 61 6e 64 20 72 65 74 75 72 6e 20 61 20  te and return a 
5d30: 6e 65 77 20 70 61 67 65 20 62 75 66 66 65 72 2e  new page buffer.
5d40: 0a 2a 2f 0a 73 74 61 74 69 63 20 73 71 6c 69 74  .*/.static sqlit
5d50: 65 33 5f 70 63 61 63 68 65 5f 70 61 67 65 20 2a  e3_pcache_page *
5d60: 70 63 61 63 68 65 31 46 65 74 63 68 28 0a 20 20  pcache1Fetch(.  
5d70: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a  sqlite3_pcache *
5d80: 70 2c 20 0a 20 20 75 6e 73 69 67 6e 65 64 20 69  p, .  unsigned i
5d90: 6e 74 20 69 4b 65 79 2c 20 0a 20 20 69 6e 74 20  nt iKey, .  int 
5da0: 63 72 65 61 74 65 46 6c 61 67 0a 29 7b 0a 20 20  createFlag.){.  
5db0: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 50 69  unsigned int nPi
5dc0: 6e 6e 65 64 3b 0a 20 20 50 43 61 63 68 65 31 20  nned;.  PCache1 
5dd0: 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61 63 68  *pCache = (PCach
5de0: 65 31 20 2a 29 70 3b 0a 20 20 50 47 72 6f 75 70  e1 *)p;.  PGroup
5df0: 20 2a 70 47 72 6f 75 70 3b 0a 20 20 50 67 48 64   *pGroup;.  PgHd
5e00: 72 31 20 2a 70 50 61 67 65 20 3d 20 30 3b 0a 0a  r1 *pPage = 0;..
5e10: 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65    assert( pCache
5e20: 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 7c 7c 20  ->bPurgeable || 
5e30: 63 72 65 61 74 65 46 6c 61 67 21 3d 31 20 29 3b  createFlag!=1 );
5e40: 0a 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68  .  assert( pCach
5e50: 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 7c 7c  e->bPurgeable ||
5e60: 20 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 3d 3d 30   pCache->nMin==0
5e70: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 43   );.  assert( pC
5e80: 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65  ache->bPurgeable
5e90: 3d 3d 30 20 7c 7c 20 70 43 61 63 68 65 2d 3e 6e  ==0 || pCache->n
5ea0: 4d 69 6e 3d 3d 31 30 20 29 3b 0a 20 20 61 73 73  Min==10 );.  ass
5eb0: 65 72 74 28 20 70 43 61 63 68 65 2d 3e 6e 4d 69  ert( pCache->nMi
5ec0: 6e 3d 3d 30 20 7c 7c 20 70 43 61 63 68 65 2d 3e  n==0 || pCache->
5ed0: 62 50 75 72 67 65 61 62 6c 65 20 29 3b 0a 20 20  bPurgeable );.  
5ee0: 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65  pcache1EnterMute
5ef0: 78 28 70 47 72 6f 75 70 20 3d 20 70 43 61 63 68  x(pGroup = pCach
5f00: 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 0a 20 20 2f  e->pGroup);..  /
5f10: 2a 20 53 74 65 70 20 31 3a 20 53 65 61 72 63 68  * Step 1: Search
5f20: 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 20   the hash table 
5f30: 66 6f 72 20 61 6e 20 65 78 69 73 74 69 6e 67 20  for an existing 
5f40: 65 6e 74 72 79 2e 20 2a 2f 0a 20 20 69 66 28 20  entry. */.  if( 
5f50: 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3e 30 20  pCache->nHash>0 
5f60: 29 7b 0a 20 20 20 20 75 6e 73 69 67 6e 65 64 20  ){.    unsigned 
5f70: 69 6e 74 20 68 20 3d 20 69 4b 65 79 20 25 20 70  int h = iKey % p
5f80: 43 61 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20  Cache->nHash;.  
5f90: 20 20 66 6f 72 28 70 50 61 67 65 3d 70 43 61 63    for(pPage=pCac
5fa0: 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 20 70  he->apHash[h]; p
5fb0: 50 61 67 65 26 26 70 50 61 67 65 2d 3e 69 4b 65  Page&&pPage->iKe
5fc0: 79 21 3d 69 4b 65 79 3b 20 70 50 61 67 65 3d 70  y!=iKey; pPage=p
5fd0: 50 61 67 65 2d 3e 70 4e 65 78 74 29 3b 0a 20 20  Page->pNext);.  
5fe0: 7d 0a 0a 20 20 2f 2a 20 53 74 65 70 20 32 3a 20  }..  /* Step 2: 
5ff0: 41 62 6f 72 74 20 69 66 20 6e 6f 20 65 78 69 73  Abort if no exis
6000: 74 69 6e 67 20 70 61 67 65 20 69 73 20 66 6f 75  ting page is fou
6010: 6e 64 20 61 6e 64 20 63 72 65 61 74 65 46 6c 61  nd and createFla
6020: 67 20 69 73 20 30 20 2a 2f 0a 20 20 69 66 28 20  g is 0 */.  if( 
6030: 70 50 61 67 65 20 29 7b 0a 20 20 20 20 69 66 28  pPage ){.    if(
6040: 20 21 70 50 61 67 65 2d 3e 69 73 50 69 6e 6e 65   !pPage->isPinne
6050: 64 20 29 20 70 63 61 63 68 65 31 50 69 6e 50 61  d ) pcache1PinPa
6060: 67 65 28 70 50 61 67 65 29 3b 0a 20 20 20 20 67  ge(pPage);.    g
6070: 6f 74 6f 20 66 65 74 63 68 5f 6f 75 74 3b 0a 20  oto fetch_out;. 
6080: 20 7d 0a 20 20 69 66 28 20 63 72 65 61 74 65 46   }.  if( createF
6090: 6c 61 67 3d 3d 30 20 29 7b 0a 20 20 20 20 67 6f  lag==0 ){.    go
60a0: 74 6f 20 66 65 74 63 68 5f 6f 75 74 3b 0a 20 20  to fetch_out;.  
60b0: 7d 0a 0a 20 20 2f 2a 20 54 68 65 20 70 47 72 6f  }..  /* The pGro
60c0: 75 70 20 6c 6f 63 61 6c 20 76 61 72 69 61 62 6c  up local variabl
60d0: 65 20 77 69 6c 6c 20 6e 6f 72 6d 61 6c 6c 79 20  e will normally 
60e0: 62 65 20 69 6e 69 74 69 61 6c 69 7a 65 64 20 62  be initialized b
60f0: 79 20 74 68 65 0a 20 20 2a 2a 20 70 63 61 63 68  y the.  ** pcach
6100: 65 31 45 6e 74 65 72 4d 75 74 65 78 28 29 20 6d  e1EnterMutex() m
6110: 61 63 72 6f 20 61 62 6f 76 65 2e 20 20 42 75 74  acro above.  But
6120: 20 69 66 20 53 51 4c 49 54 45 5f 4d 55 54 45 58   if SQLITE_MUTEX
6130: 5f 4f 4d 49 54 20 69 73 20 64 65 66 69 6e 65 64  _OMIT is defined
6140: 2c 0a 20 20 2a 2a 20 74 68 65 6e 20 70 63 61 63  ,.  ** then pcac
6150: 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 29 20  he1EnterMutex() 
6160: 69 73 20 61 20 6e 6f 2d 6f 70 2c 20 73 6f 20 77  is a no-op, so w
6170: 65 20 68 61 76 65 20 74 6f 20 69 6e 69 74 69 61  e have to initia
6180: 6c 69 7a 65 20 74 68 65 0a 20 20 2a 2a 20 6c 6f  lize the.  ** lo
6190: 63 61 6c 20 76 61 72 69 61 62 6c 65 20 68 65 72  cal variable her
61a0: 65 2e 20 20 44 65 6c 61 79 69 6e 67 20 74 68 65  e.  Delaying the
61b0: 20 69 6e 69 74 69 61 6c 69 7a 61 74 69 6f 6e 20   initialization 
61c0: 6f 66 20 70 47 72 6f 75 70 20 69 73 20 61 6e 0a  of pGroup is an.
61d0: 20 20 2a 2a 20 6f 70 74 69 6d 69 7a 61 74 69 6f    ** optimizatio
61e0: 6e 3a 20 20 54 68 65 20 63 6f 6d 6d 6f 6e 20 63  n:  The common c
61f0: 61 73 65 20 69 73 20 74 6f 20 65 78 69 74 20 74  ase is to exit t
6200: 68 65 20 6d 6f 64 75 6c 65 20 62 65 66 6f 72 65  he module before
6210: 20 72 65 61 63 68 69 6e 67 0a 20 20 2a 2a 20 74   reaching.  ** t
6220: 68 69 73 20 70 6f 69 6e 74 2e 0a 20 20 2a 2f 0a  his point..  */.
6230: 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 4d 55  #ifdef SQLITE_MU
6240: 54 45 58 5f 4f 4d 49 54 0a 20 20 70 47 72 6f 75  TEX_OMIT.  pGrou
6250: 70 20 3d 20 70 43 61 63 68 65 2d 3e 70 47 72 6f  p = pCache->pGro
6260: 75 70 3b 0a 23 65 6e 64 69 66 0a 0a 20 20 2f 2a  up;.#endif..  /*
6270: 20 53 74 65 70 20 33 3a 20 41 62 6f 72 74 20 69   Step 3: Abort i
6280: 66 20 63 72 65 61 74 65 46 6c 61 67 20 69 73 20  f createFlag is 
6290: 31 20 62 75 74 20 74 68 65 20 63 61 63 68 65 20  1 but the cache 
62a0: 69 73 20 6e 65 61 72 6c 79 20 66 75 6c 6c 20 2a  is nearly full *
62b0: 2f 0a 20 20 61 73 73 65 72 74 28 20 70 43 61 63  /.  assert( pCac
62c0: 68 65 2d 3e 6e 50 61 67 65 20 3e 3d 20 70 43 61  he->nPage >= pCa
62d0: 63 68 65 2d 3e 6e 52 65 63 79 63 6c 61 62 6c 65  che->nRecyclable
62e0: 20 29 3b 0a 20 20 6e 50 69 6e 6e 65 64 20 3d 20   );.  nPinned = 
62f0: 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 20 2d 20  pCache->nPage - 
6300: 70 43 61 63 68 65 2d 3e 6e 52 65 63 79 63 6c 61  pCache->nRecycla
6310: 62 6c 65 3b 0a 20 20 61 73 73 65 72 74 28 20 70  ble;.  assert( p
6320: 47 72 6f 75 70 2d 3e 6d 78 50 69 6e 6e 65 64 20  Group->mxPinned 
6330: 3d 3d 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50  == pGroup->nMaxP
6340: 61 67 65 20 2b 20 31 30 20 2d 20 70 47 72 6f 75  age + 10 - pGrou
6350: 70 2d 3e 6e 4d 69 6e 50 61 67 65 20 29 3b 0a 20  p->nMinPage );. 
6360: 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65 2d   assert( pCache-
6370: 3e 6e 39 30 70 63 74 20 3d 3d 20 70 43 61 63 68  >n90pct == pCach
6380: 65 2d 3e 6e 4d 61 78 2a 39 2f 31 30 20 29 3b 0a  e->nMax*9/10 );.
6390: 20 20 69 66 28 20 63 72 65 61 74 65 46 6c 61 67    if( createFlag
63a0: 3d 3d 31 20 26 26 20 28 0a 20 20 20 20 20 20 20  ==1 && (.       
63b0: 20 6e 50 69 6e 6e 65 64 3e 3d 70 47 72 6f 75 70   nPinned>=pGroup
63c0: 2d 3e 6d 78 50 69 6e 6e 65 64 0a 20 20 20 20 20  ->mxPinned.     
63d0: 7c 7c 20 6e 50 69 6e 6e 65 64 3e 3d 70 43 61 63  || nPinned>=pCac
63e0: 68 65 2d 3e 6e 39 30 70 63 74 0a 20 20 20 20 20  he->n90pct.     
63f0: 7c 7c 20 70 63 61 63 68 65 31 55 6e 64 65 72 4d  || pcache1UnderM
6400: 65 6d 6f 72 79 50 72 65 73 73 75 72 65 28 70 43  emoryPressure(pC
6410: 61 63 68 65 29 0a 20 20 29 29 7b 0a 20 20 20 20  ache).  )){.    
6420: 67 6f 74 6f 20 66 65 74 63 68 5f 6f 75 74 3b 0a  goto fetch_out;.
6430: 20 20 7d 0a 0a 20 20 69 66 28 20 70 43 61 63 68    }..  if( pCach
6440: 65 2d 3e 6e 50 61 67 65 3e 3d 70 43 61 63 68 65  e->nPage>=pCache
6450: 2d 3e 6e 48 61 73 68 20 26 26 20 70 63 61 63 68  ->nHash && pcach
6460: 65 31 52 65 73 69 7a 65 48 61 73 68 28 70 43 61  e1ResizeHash(pCa
6470: 63 68 65 29 20 29 7b 0a 20 20 20 20 67 6f 74 6f  che) ){.    goto
6480: 20 66 65 74 63 68 5f 6f 75 74 3b 0a 20 20 7d 0a   fetch_out;.  }.
6490: 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65    assert( pCache
64a0: 2d 3e 6e 48 61 73 68 3e 30 20 26 26 20 70 43 61  ->nHash>0 && pCa
64b0: 63 68 65 2d 3e 61 70 48 61 73 68 20 29 3b 0a 0a  che->apHash );..
64c0: 20 20 2f 2a 20 53 74 65 70 20 34 2e 20 54 72 79    /* Step 4. Try
64d0: 20 74 6f 20 72 65 63 79 63 6c 65 20 61 20 70 61   to recycle a pa
64e0: 67 65 2e 20 2a 2f 0a 20 20 69 66 28 20 70 43 61  ge. */.  if( pCa
64f0: 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20  che->bPurgeable 
6500: 26 26 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 54  && pGroup->pLruT
6510: 61 69 6c 20 26 26 20 28 0a 20 20 20 20 20 20 20  ail && (.       
6520: 20 20 28 70 43 61 63 68 65 2d 3e 6e 50 61 67 65    (pCache->nPage
6530: 2b 31 3e 3d 70 43 61 63 68 65 2d 3e 6e 4d 61 78  +1>=pCache->nMax
6540: 29 0a 20 20 20 20 20 20 7c 7c 20 70 47 72 6f 75  ).      || pGrou
6550: 70 2d 3e 6e 43 75 72 72 65 6e 74 50 61 67 65 3e  p->nCurrentPage>
6560: 3d 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67  =pGroup->nMaxPag
6570: 65 0a 20 20 20 20 20 20 7c 7c 20 70 63 61 63 68  e.      || pcach
6580: 65 31 55 6e 64 65 72 4d 65 6d 6f 72 79 50 72 65  e1UnderMemoryPre
6590: 73 73 75 72 65 28 70 43 61 63 68 65 29 0a 20 20  ssure(pCache).  
65a0: 29 29 7b 0a 20 20 20 20 50 43 61 63 68 65 31 20  )){.    PCache1 
65b0: 2a 70 4f 74 68 65 72 3b 0a 20 20 20 20 70 50 61  *pOther;.    pPa
65c0: 67 65 20 3d 20 70 47 72 6f 75 70 2d 3e 70 4c 72  ge = pGroup->pLr
65d0: 75 54 61 69 6c 3b 0a 20 20 20 20 61 73 73 65 72  uTail;.    asser
65e0: 74 28 20 70 50 61 67 65 2d 3e 69 73 50 69 6e 6e  t( pPage->isPinn
65f0: 65 64 3d 3d 30 20 29 3b 0a 20 20 20 20 70 63 61  ed==0 );.    pca
6600: 63 68 65 31 52 65 6d 6f 76 65 46 72 6f 6d 48 61  che1RemoveFromHa
6610: 73 68 28 70 50 61 67 65 29 3b 0a 20 20 20 20 70  sh(pPage);.    p
6620: 63 61 63 68 65 31 50 69 6e 50 61 67 65 28 70 50  cache1PinPage(pP
6630: 61 67 65 29 3b 0a 20 20 20 20 70 4f 74 68 65 72  age);.    pOther
6640: 20 3d 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65   = pPage->pCache
6650: 3b 0a 0a 20 20 20 20 2f 2a 20 57 65 20 77 61 6e  ;..    /* We wan
6660: 74 20 74 6f 20 76 65 72 69 66 79 20 74 68 61 74  t to verify that
6670: 20 73 7a 50 61 67 65 20 61 6e 64 20 73 7a 45 78   szPage and szEx
6680: 74 72 61 20 61 72 65 20 74 68 65 20 73 61 6d 65  tra are the same
6690: 20 66 6f 72 20 70 4f 74 68 65 72 0a 20 20 20 20   for pOther.    
66a0: 2a 2a 20 61 6e 64 20 70 43 61 63 68 65 2e 20 20  ** and pCache.  
66b0: 41 73 73 65 72 74 20 74 68 61 74 20 77 65 20 63  Assert that we c
66c0: 61 6e 20 76 65 72 69 66 79 20 74 68 69 73 20 62  an verify this b
66d0: 79 20 63 6f 6d 70 61 72 69 6e 67 20 73 75 6d 73  y comparing sums
66e0: 2e 20 2a 2f 0a 20 20 20 20 61 73 73 65 72 74 28  . */.    assert(
66f0: 20 28 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65   (pCache->szPage
6700: 20 26 20 28 70 43 61 63 68 65 2d 3e 73 7a 50 61   & (pCache->szPa
6710: 67 65 2d 31 29 29 3d 3d 30 20 26 26 20 70 43 61  ge-1))==0 && pCa
6720: 63 68 65 2d 3e 73 7a 50 61 67 65 3e 3d 35 31 32  che->szPage>=512
6730: 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20   );.    assert( 
6740: 70 43 61 63 68 65 2d 3e 73 7a 45 78 74 72 61 3c  pCache->szExtra<
6750: 35 31 32 20 29 3b 0a 20 20 20 20 61 73 73 65 72  512 );.    asser
6760: 74 28 20 28 70 4f 74 68 65 72 2d 3e 73 7a 50 61  t( (pOther->szPa
6770: 67 65 20 26 20 28 70 4f 74 68 65 72 2d 3e 73 7a  ge & (pOther->sz
6780: 50 61 67 65 2d 31 29 29 3d 3d 30 20 26 26 20 70  Page-1))==0 && p
6790: 4f 74 68 65 72 2d 3e 73 7a 50 61 67 65 3e 3d 35  Other->szPage>=5
67a0: 31 32 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74  12 );.    assert
67b0: 28 20 70 4f 74 68 65 72 2d 3e 73 7a 45 78 74 72  ( pOther->szExtr
67c0: 61 3c 35 31 32 20 29 3b 0a 0a 20 20 20 20 69 66  a<512 );..    if
67d0: 28 20 70 4f 74 68 65 72 2d 3e 73 7a 50 61 67 65  ( pOther->szPage
67e0: 2b 70 4f 74 68 65 72 2d 3e 73 7a 45 78 74 72 61  +pOther->szExtra
67f0: 20 21 3d 20 70 43 61 63 68 65 2d 3e 73 7a 50 61   != pCache->szPa
6800: 67 65 2b 70 43 61 63 68 65 2d 3e 73 7a 45 78 74  ge+pCache->szExt
6810: 72 61 20 29 7b 0a 20 20 20 20 20 20 70 63 61 63  ra ){.      pcac
6820: 68 65 31 46 72 65 65 50 61 67 65 28 70 50 61 67  he1FreePage(pPag
6830: 65 29 3b 0a 20 20 20 20 20 20 70 50 61 67 65 20  e);.      pPage 
6840: 3d 20 30 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  = 0;.    }else{.
6850: 20 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 6e 43        pGroup->nC
6860: 75 72 72 65 6e 74 50 61 67 65 20 2d 3d 20 28 70  urrentPage -= (p
6870: 4f 74 68 65 72 2d 3e 62 50 75 72 67 65 61 62 6c  Other->bPurgeabl
6880: 65 20 2d 20 70 43 61 63 68 65 2d 3e 62 50 75 72  e - pCache->bPur
6890: 67 65 61 62 6c 65 29 3b 0a 20 20 20 20 7d 0a 20  geable);.    }. 
68a0: 20 7d 0a 0a 20 20 2f 2a 20 53 74 65 70 20 35 2e   }..  /* Step 5.
68b0: 20 49 66 20 61 20 75 73 61 62 6c 65 20 70 61 67   If a usable pag
68c0: 65 20 62 75 66 66 65 72 20 68 61 73 20 73 74 69  e buffer has sti
68d0: 6c 6c 20 6e 6f 74 20 62 65 65 6e 20 66 6f 75 6e  ll not been foun
68e0: 64 2c 20 0a 20 20 2a 2a 20 61 74 74 65 6d 70 74  d, .  ** attempt
68f0: 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e   to allocate a n
6900: 65 77 20 6f 6e 65 2e 20 0a 20 20 2a 2f 0a 20 20  ew one. .  */.  
6910: 69 66 28 20 21 70 50 61 67 65 20 29 7b 0a 20 20  if( !pPage ){.  
6920: 20 20 69 66 28 20 63 72 65 61 74 65 46 6c 61 67    if( createFlag
6930: 3d 3d 31 20 29 20 73 71 6c 69 74 65 33 42 65 67  ==1 ) sqlite3Beg
6940: 69 6e 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29  inBenignMalloc()
6950: 3b 0a 20 20 20 20 70 50 61 67 65 20 3d 20 70 63  ;.    pPage = pc
6960: 61 63 68 65 31 41 6c 6c 6f 63 50 61 67 65 28 70  ache1AllocPage(p
6970: 43 61 63 68 65 29 3b 0a 20 20 20 20 69 66 28 20  Cache);.    if( 
6980: 63 72 65 61 74 65 46 6c 61 67 3d 3d 31 20 29 20  createFlag==1 ) 
6990: 73 71 6c 69 74 65 33 45 6e 64 42 65 6e 69 67 6e  sqlite3EndBenign
69a0: 4d 61 6c 6c 6f 63 28 29 3b 0a 20 20 7d 0a 0a 20  Malloc();.  }.. 
69b0: 20 69 66 28 20 70 50 61 67 65 20 29 7b 0a 20 20   if( pPage ){.  
69c0: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68    unsigned int h
69d0: 20 3d 20 69 4b 65 79 20 25 20 70 43 61 63 68 65   = iKey % pCache
69e0: 2d 3e 6e 48 61 73 68 3b 0a 20 20 20 20 70 43 61  ->nHash;.    pCa
69f0: 63 68 65 2d 3e 6e 50 61 67 65 2b 2b 3b 0a 20 20  che->nPage++;.  
6a00: 20 20 70 50 61 67 65 2d 3e 69 4b 65 79 20 3d 20    pPage->iKey = 
6a10: 69 4b 65 79 3b 0a 20 20 20 20 70 50 61 67 65 2d  iKey;.    pPage-
6a20: 3e 70 4e 65 78 74 20 3d 20 70 43 61 63 68 65 2d  >pNext = pCache-
6a30: 3e 61 70 48 61 73 68 5b 68 5d 3b 0a 20 20 20 20  >apHash[h];.    
6a40: 70 50 61 67 65 2d 3e 70 43 61 63 68 65 20 3d 20  pPage->pCache = 
6a50: 70 43 61 63 68 65 3b 0a 20 20 20 20 70 50 61 67  pCache;.    pPag
6a60: 65 2d 3e 70 4c 72 75 50 72 65 76 20 3d 20 30 3b  e->pLruPrev = 0;
6a70: 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 4c 72 75  .    pPage->pLru
6a80: 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20 20 70 50  Next = 0;.    pP
6a90: 61 67 65 2d 3e 69 73 50 69 6e 6e 65 64 20 3d 20  age->isPinned = 
6aa0: 31 3b 0a 20 20 20 20 2a 28 76 6f 69 64 20 2a 2a  1;.    *(void **
6ab0: 29 70 50 61 67 65 2d 3e 70 61 67 65 2e 70 45 78  )pPage->page.pEx
6ac0: 74 72 61 20 3d 20 30 3b 0a 20 20 20 20 70 43 61  tra = 0;.    pCa
6ad0: 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 20 3d  che->apHash[h] =
6ae0: 20 70 50 61 67 65 3b 0a 20 20 7d 0a 0a 66 65 74   pPage;.  }..fet
6af0: 63 68 5f 6f 75 74 3a 0a 20 20 69 66 28 20 70 50  ch_out:.  if( pP
6b00: 61 67 65 20 26 26 20 69 4b 65 79 3e 70 43 61 63  age && iKey>pCac
6b10: 68 65 2d 3e 69 4d 61 78 4b 65 79 20 29 7b 0a 20  he->iMaxKey ){. 
6b20: 20 20 20 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b     pCache->iMaxK
6b30: 65 79 20 3d 20 69 4b 65 79 3b 0a 20 20 7d 0a 20  ey = iKey;.  }. 
6b40: 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74   pcache1LeaveMut
6b50: 65 78 28 70 47 72 6f 75 70 29 3b 0a 20 20 72 65  ex(pGroup);.  re
6b60: 74 75 72 6e 20 26 70 50 61 67 65 2d 3e 70 61 67  turn &pPage->pag
6b70: 65 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70  e;.}.../*.** Imp
6b80: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74  lementation of t
6b90: 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68  he sqlite3_pcach
6ba0: 65 2e 78 55 6e 70 69 6e 20 6d 65 74 68 6f 64 2e  e.xUnpin method.
6bb0: 0a 2a 2a 0a 2a 2a 20 4d 61 72 6b 20 61 20 70 61  .**.** Mark a pa
6bc0: 67 65 20 61 73 20 75 6e 70 69 6e 6e 65 64 20 28  ge as unpinned (
6bd0: 65 6c 69 67 69 62 6c 65 20 66 6f 72 20 61 73 79  eligible for asy
6be0: 6e 63 68 72 6f 6e 6f 75 73 20 72 65 63 79 63 6c  nchronous recycl
6bf0: 69 6e 67 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ing)..*/.static 
6c00: 76 6f 69 64 20 70 63 61 63 68 65 31 55 6e 70 69  void pcache1Unpi
6c10: 6e 28 0a 20 20 73 71 6c 69 74 65 33 5f 70 63 61  n(.  sqlite3_pca
6c20: 63 68 65 20 2a 70 2c 20 0a 20 20 73 71 6c 69 74  che *p, .  sqlit
6c30: 65 33 5f 70 63 61 63 68 65 5f 70 61 67 65 20 2a  e3_pcache_page *
6c40: 70 50 67 2c 20 0a 20 20 69 6e 74 20 72 65 75 73  pPg, .  int reus
6c50: 65 55 6e 6c 69 6b 65 6c 79 0a 29 7b 0a 20 20 50  eUnlikely.){.  P
6c60: 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d  Cache1 *pCache =
6c70: 20 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20   (PCache1 *)p;. 
6c80: 20 50 67 48 64 72 31 20 2a 70 50 61 67 65 20 3d   PgHdr1 *pPage =
6c90: 20 28 50 67 48 64 72 31 20 2a 29 70 50 67 3b 0a   (PgHdr1 *)pPg;.
6ca0: 20 20 50 47 72 6f 75 70 20 2a 70 47 72 6f 75 70    PGroup *pGroup
6cb0: 20 3d 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75   = pCache->pGrou
6cc0: 70 3b 0a 20 0a 20 20 61 73 73 65 72 74 28 20 70  p;. .  assert( p
6cd0: 50 61 67 65 2d 3e 70 43 61 63 68 65 3d 3d 70 43  Page->pCache==pC
6ce0: 61 63 68 65 20 29 3b 0a 20 20 70 63 61 63 68 65  ache );.  pcache
6cf0: 31 45 6e 74 65 72 4d 75 74 65 78 28 70 47 72 6f  1EnterMutex(pGro
6d00: 75 70 29 3b 0a 0a 20 20 2f 2a 20 49 74 20 69 73  up);..  /* It is
6d10: 20 61 6e 20 65 72 72 6f 72 20 74 6f 20 63 61 6c   an error to cal
6d20: 6c 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  l this function 
6d30: 69 66 20 74 68 65 20 70 61 67 65 20 69 73 20 61  if the page is a
6d40: 6c 72 65 61 64 79 20 0a 20 20 2a 2a 20 70 61 72  lready .  ** par
6d50: 74 20 6f 66 20 74 68 65 20 50 47 72 6f 75 70 20  t of the PGroup 
6d60: 4c 52 55 20 6c 69 73 74 2e 0a 20 20 2a 2f 0a 20  LRU list..  */. 
6d70: 20 61 73 73 65 72 74 28 20 70 50 61 67 65 2d 3e   assert( pPage->
6d80: 70 4c 72 75 50 72 65 76 3d 3d 30 20 26 26 20 70  pLruPrev==0 && p
6d90: 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 3d 3d  Page->pLruNext==
6da0: 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70  0 );.  assert( p
6db0: 47 72 6f 75 70 2d 3e 70 4c 72 75 48 65 61 64 21  Group->pLruHead!
6dc0: 3d 70 50 61 67 65 20 26 26 20 70 47 72 6f 75 70  =pPage && pGroup
6dd0: 2d 3e 70 4c 72 75 54 61 69 6c 21 3d 70 50 61 67  ->pLruTail!=pPag
6de0: 65 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70  e );.  assert( p
6df0: 50 61 67 65 2d 3e 69 73 50 69 6e 6e 65 64 3d 3d  Page->isPinned==
6e00: 31 20 29 3b 0a 0a 20 20 69 66 28 20 72 65 75 73  1 );..  if( reus
6e10: 65 55 6e 6c 69 6b 65 6c 79 20 7c 7c 20 70 47 72  eUnlikely || pGr
6e20: 6f 75 70 2d 3e 6e 43 75 72 72 65 6e 74 50 61 67  oup->nCurrentPag
6e30: 65 3e 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61  e>pGroup->nMaxPa
6e40: 67 65 20 29 7b 0a 20 20 20 20 70 63 61 63 68 65  ge ){.    pcache
6e50: 31 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73 68 28  1RemoveFromHash(
6e60: 70 50 61 67 65 29 3b 0a 20 20 20 20 70 63 61 63  pPage);.    pcac
6e70: 68 65 31 46 72 65 65 50 61 67 65 28 70 50 61 67  he1FreePage(pPag
6e80: 65 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  e);.  }else{.   
6e90: 20 2f 2a 20 41 64 64 20 74 68 65 20 70 61 67 65   /* Add the page
6ea0: 20 74 6f 20 74 68 65 20 50 47 72 6f 75 70 20 4c   to the PGroup L
6eb0: 52 55 20 6c 69 73 74 2e 20 2a 2f 0a 20 20 20 20  RU list. */.    
6ec0: 69 66 28 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75  if( pGroup->pLru
6ed0: 48 65 61 64 20 29 7b 0a 20 20 20 20 20 20 70 47  Head ){.      pG
6ee0: 72 6f 75 70 2d 3e 70 4c 72 75 48 65 61 64 2d 3e  roup->pLruHead->
6ef0: 70 4c 72 75 50 72 65 76 20 3d 20 70 50 61 67 65  pLruPrev = pPage
6f00: 3b 0a 20 20 20 20 20 20 70 50 61 67 65 2d 3e 70  ;.      pPage->p
6f10: 4c 72 75 4e 65 78 74 20 3d 20 70 47 72 6f 75 70  LruNext = pGroup
6f20: 2d 3e 70 4c 72 75 48 65 61 64 3b 0a 20 20 20 20  ->pLruHead;.    
6f30: 20 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 48 65    pGroup->pLruHe
6f40: 61 64 20 3d 20 70 50 61 67 65 3b 0a 20 20 20 20  ad = pPage;.    
6f50: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 47 72  }else{.      pGr
6f60: 6f 75 70 2d 3e 70 4c 72 75 54 61 69 6c 20 3d 20  oup->pLruTail = 
6f70: 70 50 61 67 65 3b 0a 20 20 20 20 20 20 70 47 72  pPage;.      pGr
6f80: 6f 75 70 2d 3e 70 4c 72 75 48 65 61 64 20 3d 20  oup->pLruHead = 
6f90: 70 50 61 67 65 3b 0a 20 20 20 20 7d 0a 20 20 20  pPage;.    }.   
6fa0: 20 70 43 61 63 68 65 2d 3e 6e 52 65 63 79 63 6c   pCache->nRecycl
6fb0: 61 62 6c 65 2b 2b 3b 0a 20 20 20 20 70 50 61 67  able++;.    pPag
6fc0: 65 2d 3e 69 73 50 69 6e 6e 65 64 20 3d 20 30 3b  e->isPinned = 0;
6fd0: 0a 20 20 7d 0a 0a 20 20 70 63 61 63 68 65 31 4c  .  }..  pcache1L
6fe0: 65 61 76 65 4d 75 74 65 78 28 70 43 61 63 68 65  eaveMutex(pCache
6ff0: 2d 3e 70 47 72 6f 75 70 29 3b 0a 7d 0a 0a 2f 2a  ->pGroup);.}../*
7000: 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69  .** Implementati
7010: 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65  on of the sqlite
7020: 33 5f 70 63 61 63 68 65 2e 78 52 65 6b 65 79 20  3_pcache.xRekey 
7030: 6d 65 74 68 6f 64 2e 20 0a 2a 2f 0a 73 74 61 74  method. .*/.stat
7040: 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 31 52  ic void pcache1R
7050: 65 6b 65 79 28 0a 20 20 73 71 6c 69 74 65 33 5f  ekey(.  sqlite3_
7060: 70 63 61 63 68 65 20 2a 70 2c 0a 20 20 73 71 6c  pcache *p,.  sql
7070: 69 74 65 33 5f 70 63 61 63 68 65 5f 70 61 67 65  ite3_pcache_page
7080: 20 2a 70 50 67 2c 0a 20 20 75 6e 73 69 67 6e 65   *pPg,.  unsigne
7090: 64 20 69 6e 74 20 69 4f 6c 64 2c 0a 20 20 75 6e  d int iOld,.  un
70a0: 73 69 67 6e 65 64 20 69 6e 74 20 69 4e 65 77 0a  signed int iNew.
70b0: 29 7b 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43  ){.  PCache1 *pC
70c0: 61 63 68 65 20 3d 20 28 50 43 61 63 68 65 31 20  ache = (PCache1 
70d0: 2a 29 70 3b 0a 20 20 50 67 48 64 72 31 20 2a 70  *)p;.  PgHdr1 *p
70e0: 50 61 67 65 20 3d 20 28 50 67 48 64 72 31 20 2a  Page = (PgHdr1 *
70f0: 29 70 50 67 3b 0a 20 20 50 67 48 64 72 31 20 2a  )pPg;.  PgHdr1 *
7100: 2a 70 70 3b 0a 20 20 75 6e 73 69 67 6e 65 64 20  *pp;.  unsigned 
7110: 69 6e 74 20 68 3b 20 0a 20 20 61 73 73 65 72 74  int h; .  assert
7120: 28 20 70 50 61 67 65 2d 3e 69 4b 65 79 3d 3d 69  ( pPage->iKey==i
7130: 4f 6c 64 20 29 3b 0a 20 20 61 73 73 65 72 74 28  Old );.  assert(
7140: 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65 3d 3d   pPage->pCache==
7150: 70 43 61 63 68 65 20 29 3b 0a 0a 20 20 70 63 61  pCache );..  pca
7160: 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70  che1EnterMutex(p
7170: 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a  Cache->pGroup);.
7180: 0a 20 20 68 20 3d 20 69 4f 6c 64 25 70 43 61 63  .  h = iOld%pCac
7190: 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 70 70 20  he->nHash;.  pp 
71a0: 3d 20 26 70 43 61 63 68 65 2d 3e 61 70 48 61 73  = &pCache->apHas
71b0: 68 5b 68 5d 3b 0a 20 20 77 68 69 6c 65 28 20 28  h[h];.  while( (
71c0: 2a 70 70 29 21 3d 70 50 61 67 65 20 29 7b 0a 20  *pp)!=pPage ){. 
71d0: 20 20 20 70 70 20 3d 20 26 28 2a 70 70 29 2d 3e     pp = &(*pp)->
71e0: 70 4e 65 78 74 3b 0a 20 20 7d 0a 20 20 2a 70 70  pNext;.  }.  *pp
71f0: 20 3d 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 3b   = pPage->pNext;
7200: 0a 0a 20 20 68 20 3d 20 69 4e 65 77 25 70 43 61  ..  h = iNew%pCa
7210: 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 70 50  che->nHash;.  pP
7220: 61 67 65 2d 3e 69 4b 65 79 20 3d 20 69 4e 65 77  age->iKey = iNew
7230: 3b 0a 20 20 70 50 61 67 65 2d 3e 70 4e 65 78 74  ;.  pPage->pNext
7240: 20 3d 20 70 43 61 63 68 65 2d 3e 61 70 48 61 73   = pCache->apHas
7250: 68 5b 68 5d 3b 0a 20 20 70 43 61 63 68 65 2d 3e  h[h];.  pCache->
7260: 61 70 48 61 73 68 5b 68 5d 20 3d 20 70 50 61 67  apHash[h] = pPag
7270: 65 3b 0a 20 20 69 66 28 20 69 4e 65 77 3e 70 43  e;.  if( iNew>pC
7280: 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 29 7b  ache->iMaxKey ){
7290: 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 69 4d 61  .    pCache->iMa
72a0: 78 4b 65 79 20 3d 20 69 4e 65 77 3b 0a 20 20 7d  xKey = iNew;.  }
72b0: 0a 0a 20 20 70 63 61 63 68 65 31 4c 65 61 76 65  ..  pcache1Leave
72c0: 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e 70 47  Mutex(pCache->pG
72d0: 72 6f 75 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  roup);.}../*.** 
72e0: 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  Implementation o
72f0: 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63  f the sqlite3_pc
7300: 61 63 68 65 2e 78 54 72 75 6e 63 61 74 65 20 6d  ache.xTruncate m
7310: 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20 44 69  ethod. .**.** Di
7320: 73 63 61 72 64 20 61 6c 6c 20 75 6e 70 69 6e 6e  scard all unpinn
7330: 65 64 20 70 61 67 65 73 20 69 6e 20 74 68 65 20  ed pages in the 
7340: 63 61 63 68 65 20 77 69 74 68 20 61 20 70 61 67  cache with a pag
7350: 65 20 6e 75 6d 62 65 72 20 65 71 75 61 6c 20 74  e number equal t
7360: 6f 0a 2a 2a 20 6f 72 20 67 72 65 61 74 65 72 20  o.** or greater 
7370: 74 68 61 6e 20 70 61 72 61 6d 65 74 65 72 20 69  than parameter i
7380: 4c 69 6d 69 74 2e 20 41 6e 79 20 70 69 6e 6e 65  Limit. Any pinne
7390: 64 20 70 61 67 65 73 20 77 69 74 68 20 61 20 70  d pages with a p
73a0: 61 67 65 20 6e 75 6d 62 65 72 0a 2a 2a 20 65 71  age number.** eq
73b0: 75 61 6c 20 74 6f 20 6f 72 20 67 72 65 61 74 65  ual to or greate
73c0: 72 20 74 68 61 6e 20 69 4c 69 6d 69 74 20 61 72  r than iLimit ar
73d0: 65 20 69 6d 70 6c 69 63 69 74 6c 79 20 75 6e 70  e implicitly unp
73e0: 69 6e 6e 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63  inned..*/.static
73f0: 20 76 6f 69 64 20 70 63 61 63 68 65 31 54 72 75   void pcache1Tru
7400: 6e 63 61 74 65 28 73 71 6c 69 74 65 33 5f 70 63  ncate(sqlite3_pc
7410: 61 63 68 65 20 2a 70 2c 20 75 6e 73 69 67 6e 65  ache *p, unsigne
7420: 64 20 69 6e 74 20 69 4c 69 6d 69 74 29 7b 0a 20  d int iLimit){. 
7430: 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68 65   PCache1 *pCache
7440: 20 3d 20 28 50 43 61 63 68 65 31 20 2a 29 70 3b   = (PCache1 *)p;
7450: 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d  .  pcache1EnterM
7460: 75 74 65 78 28 70 43 61 63 68 65 2d 3e 70 47 72  utex(pCache->pGr
7470: 6f 75 70 29 3b 0a 20 20 69 66 28 20 69 4c 69 6d  oup);.  if( iLim
7480: 69 74 3c 3d 70 43 61 63 68 65 2d 3e 69 4d 61 78  it<=pCache->iMax
7490: 4b 65 79 20 29 7b 0a 20 20 20 20 70 63 61 63 68  Key ){.    pcach
74a0: 65 31 54 72 75 6e 63 61 74 65 55 6e 73 61 66 65  e1TruncateUnsafe
74b0: 28 70 43 61 63 68 65 2c 20 69 4c 69 6d 69 74 29  (pCache, iLimit)
74c0: 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 69 4d  ;.    pCache->iM
74d0: 61 78 4b 65 79 20 3d 20 69 4c 69 6d 69 74 2d 31  axKey = iLimit-1
74e0: 3b 0a 20 20 7d 0a 20 20 70 63 61 63 68 65 31 4c  ;.  }.  pcache1L
74f0: 65 61 76 65 4d 75 74 65 78 28 70 43 61 63 68 65  eaveMutex(pCache
7500: 2d 3e 70 47 72 6f 75 70 29 3b 0a 7d 0a 0a 2f 2a  ->pGroup);.}../*
7510: 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69  .** Implementati
7520: 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65  on of the sqlite
7530: 33 5f 70 63 61 63 68 65 2e 78 44 65 73 74 72 6f  3_pcache.xDestro
7540: 79 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a  y method. .**.**
7550: 20 44 65 73 74 72 6f 79 20 61 20 63 61 63 68 65   Destroy a cache
7560: 20 61 6c 6c 6f 63 61 74 65 64 20 75 73 69 6e 67   allocated using
7570: 20 70 63 61 63 68 65 31 43 72 65 61 74 65 28 29   pcache1Create()
7580: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
7590: 20 70 63 61 63 68 65 31 44 65 73 74 72 6f 79 28   pcache1Destroy(
75a0: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a  sqlite3_pcache *
75b0: 70 29 7b 0a 20 20 50 43 61 63 68 65 31 20 2a 70  p){.  PCache1 *p
75c0: 43 61 63 68 65 20 3d 20 28 50 43 61 63 68 65 31  Cache = (PCache1
75d0: 20 2a 29 70 3b 0a 20 20 50 47 72 6f 75 70 20 2a   *)p;.  PGroup *
75e0: 70 47 72 6f 75 70 20 3d 20 70 43 61 63 68 65 2d  pGroup = pCache-
75f0: 3e 70 47 72 6f 75 70 3b 0a 20 20 61 73 73 65 72  >pGroup;.  asser
7600: 74 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67  t( pCache->bPurg
7610: 65 61 62 6c 65 20 7c 7c 20 28 70 43 61 63 68 65  eable || (pCache
7620: 2d 3e 6e 4d 61 78 3d 3d 30 20 26 26 20 70 43 61  ->nMax==0 && pCa
7630: 63 68 65 2d 3e 6e 4d 69 6e 3d 3d 30 29 20 29 3b  che->nMin==0) );
7640: 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d  .  pcache1EnterM
7650: 75 74 65 78 28 70 47 72 6f 75 70 29 3b 0a 20 20  utex(pGroup);.  
7660: 70 63 61 63 68 65 31 54 72 75 6e 63 61 74 65 55  pcache1TruncateU
7670: 6e 73 61 66 65 28 70 43 61 63 68 65 2c 20 30 29  nsafe(pCache, 0)
7680: 3b 0a 20 20 61 73 73 65 72 74 28 20 70 47 72 6f  ;.  assert( pGro
7690: 75 70 2d 3e 6e 4d 61 78 50 61 67 65 20 3e 3d 20  up->nMaxPage >= 
76a0: 70 43 61 63 68 65 2d 3e 6e 4d 61 78 20 29 3b 0a  pCache->nMax );.
76b0: 20 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61    pGroup->nMaxPa
76c0: 67 65 20 2d 3d 20 70 43 61 63 68 65 2d 3e 6e 4d  ge -= pCache->nM
76d0: 61 78 3b 0a 20 20 61 73 73 65 72 74 28 20 70 47  ax;.  assert( pG
76e0: 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67 65 20 3e  roup->nMinPage >
76f0: 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 20 29  = pCache->nMin )
7700: 3b 0a 20 20 70 47 72 6f 75 70 2d 3e 6e 4d 69 6e  ;.  pGroup->nMin
7710: 50 61 67 65 20 2d 3d 20 70 43 61 63 68 65 2d 3e  Page -= pCache->
7720: 6e 4d 69 6e 3b 0a 20 20 70 47 72 6f 75 70 2d 3e  nMin;.  pGroup->
7730: 6d 78 50 69 6e 6e 65 64 20 3d 20 70 47 72 6f 75  mxPinned = pGrou
7740: 70 2d 3e 6e 4d 61 78 50 61 67 65 20 2b 20 31 30  p->nMaxPage + 10
7750: 20 2d 20 70 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50   - pGroup->nMinP
7760: 61 67 65 3b 0a 20 20 70 63 61 63 68 65 31 45 6e  age;.  pcache1En
7770: 66 6f 72 63 65 4d 61 78 50 61 67 65 28 70 47 72  forceMaxPage(pGr
7780: 6f 75 70 29 3b 0a 20 20 70 63 61 63 68 65 31 4c  oup);.  pcache1L
7790: 65 61 76 65 4d 75 74 65 78 28 70 47 72 6f 75 70  eaveMutex(pGroup
77a0: 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65  );.  sqlite3_fre
77b0: 65 28 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68  e(pCache->apHash
77c0: 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65  );.  sqlite3_fre
77d0: 65 28 70 43 61 63 68 65 29 3b 0a 7d 0a 0a 2f 2a  e(pCache);.}../*
77e0: 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
77f0: 6e 20 69 73 20 63 61 6c 6c 65 64 20 64 75 72 69  n is called duri
7800: 6e 67 20 69 6e 69 74 69 61 6c 69 7a 61 74 69 6f  ng initializatio
7810: 6e 20 28 73 71 6c 69 74 65 33 5f 69 6e 69 74 69  n (sqlite3_initi
7820: 61 6c 69 7a 65 28 29 29 20 74 6f 0a 2a 2a 20 69  alize()) to.** i
7830: 6e 73 74 61 6c 6c 20 74 68 65 20 64 65 66 61 75  nstall the defau
7840: 6c 74 20 70 6c 75 67 67 61 62 6c 65 20 63 61 63  lt pluggable cac
7850: 68 65 20 6d 6f 64 75 6c 65 2c 20 61 73 73 75 6d  he module, assum
7860: 69 6e 67 20 74 68 65 20 75 73 65 72 20 68 61 73  ing the user has
7870: 20 6e 6f 74 0a 2a 2a 20 61 6c 72 65 61 64 79 20   not.** already 
7880: 70 72 6f 76 69 64 65 64 20 61 6e 20 61 6c 74 65  provided an alte
7890: 72 6e 61 74 69 76 65 2e 0a 2a 2f 0a 76 6f 69 64  rnative..*/.void
78a0: 20 73 71 6c 69 74 65 33 50 43 61 63 68 65 53 65   sqlite3PCacheSe
78b0: 74 44 65 66 61 75 6c 74 28 76 6f 69 64 29 7b 0a  tDefault(void){.
78c0: 20 20 73 74 61 74 69 63 20 63 6f 6e 73 74 20 73    static const s
78d0: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 5f 6d 65  qlite3_pcache_me
78e0: 74 68 6f 64 73 32 20 64 65 66 61 75 6c 74 4d 65  thods2 defaultMe
78f0: 74 68 6f 64 73 20 3d 20 7b 0a 20 20 20 20 31 2c  thods = {.    1,
7900: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7910: 20 20 20 20 20 20 20 2f 2a 20 69 56 65 72 73 69         /* iVersi
7920: 6f 6e 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20  on */.    0,    
7930: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7940: 20 20 20 2f 2a 20 70 41 72 67 20 2a 2f 0a 20 20     /* pArg */.  
7950: 20 20 70 63 61 63 68 65 31 49 6e 69 74 2c 20 20    pcache1Init,  
7960: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 49             /* xI
7970: 6e 69 74 20 2a 2f 0a 20 20 20 20 70 63 61 63 68  nit */.    pcach
7980: 65 31 53 68 75 74 64 6f 77 6e 2c 20 20 20 20 20  e1Shutdown,     
7990: 20 20 20 20 2f 2a 20 78 53 68 75 74 64 6f 77 6e      /* xShutdown
79a0: 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31 43   */.    pcache1C
79b0: 72 65 61 74 65 2c 20 20 20 20 20 20 20 20 20 20  reate,          
79c0: 20 2f 2a 20 78 43 72 65 61 74 65 20 2a 2f 0a 20   /* xCreate */. 
79d0: 20 20 20 70 63 61 63 68 65 31 43 61 63 68 65 73     pcache1Caches
79e0: 69 7a 65 2c 20 20 20 20 20 20 20 20 2f 2a 20 78  ize,        /* x
79f0: 43 61 63 68 65 73 69 7a 65 20 2a 2f 0a 20 20 20  Cachesize */.   
7a00: 20 70 63 61 63 68 65 31 50 61 67 65 63 6f 75 6e   pcache1Pagecoun
7a10: 74 2c 20 20 20 20 20 20 20 20 2f 2a 20 78 50 61  t,        /* xPa
7a20: 67 65 63 6f 75 6e 74 20 2a 2f 0a 20 20 20 20 70  gecount */.    p
7a30: 63 61 63 68 65 31 46 65 74 63 68 2c 20 20 20 20  cache1Fetch,    
7a40: 20 20 20 20 20 20 20 20 2f 2a 20 78 46 65 74 63          /* xFetc
7a50: 68 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31  h */.    pcache1
7a60: 55 6e 70 69 6e 2c 20 20 20 20 20 20 20 20 20 20  Unpin,          
7a70: 20 20 2f 2a 20 78 55 6e 70 69 6e 20 2a 2f 0a 20    /* xUnpin */. 
7a80: 20 20 20 70 63 61 63 68 65 31 52 65 6b 65 79 2c     pcache1Rekey,
7a90: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
7aa0: 52 65 6b 65 79 20 2a 2f 0a 20 20 20 20 70 63 61  Rekey */.    pca
7ab0: 63 68 65 31 54 72 75 6e 63 61 74 65 2c 20 20 20  che1Truncate,   
7ac0: 20 20 20 20 20 20 2f 2a 20 78 54 72 75 6e 63 61        /* xTrunca
7ad0: 74 65 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65  te */.    pcache
7ae0: 31 44 65 73 74 72 6f 79 2c 20 20 20 20 20 20 20  1Destroy,       
7af0: 20 20 20 2f 2a 20 78 44 65 73 74 72 6f 79 20 2a     /* xDestroy *
7b00: 2f 0a 20 20 20 20 70 63 61 63 68 65 31 53 68 72  /.    pcache1Shr
7b10: 69 6e 6b 20 20 20 20 20 20 20 20 20 20 20 20 2f  ink            /
7b20: 2a 20 78 53 68 72 69 6e 6b 20 2a 2f 0a 20 20 7d  * xShrink */.  }
7b30: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66  ;.  sqlite3_conf
7b40: 69 67 28 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47  ig(SQLITE_CONFIG
7b50: 5f 50 43 41 43 48 45 32 2c 20 26 64 65 66 61 75  _PCACHE2, &defau
7b60: 6c 74 4d 65 74 68 6f 64 73 29 3b 0a 7d 0a 0a 23  ltMethods);.}..#
7b70: 69 66 64 65 66 20 53 51 4c 49 54 45 5f 45 4e 41  ifdef SQLITE_ENA
7b80: 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47  BLE_MEMORY_MANAG
7b90: 45 4d 45 4e 54 0a 2f 2a 0a 2a 2a 20 54 68 69 73  EMENT./*.** This
7ba0: 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c   function is cal
7bb0: 6c 65 64 20 74 6f 20 66 72 65 65 20 73 75 70 65  led to free supe
7bc0: 72 66 6c 75 6f 75 73 20 64 79 6e 61 6d 69 63 61  rfluous dynamica
7bd0: 6c 6c 79 20 61 6c 6c 6f 63 61 74 65 64 20 6d 65  lly allocated me
7be0: 6d 6f 72 79 0a 2a 2a 20 68 65 6c 64 20 62 79 20  mory.** held by 
7bf0: 74 68 65 20 70 61 67 65 72 20 73 79 73 74 65 6d  the pager system
7c00: 2e 20 4d 65 6d 6f 72 79 20 69 6e 20 75 73 65 20  . Memory in use 
7c10: 62 79 20 61 6e 79 20 53 51 4c 69 74 65 20 70 61  by any SQLite pa
7c20: 67 65 72 20 61 6c 6c 6f 63 61 74 65 64 0a 2a 2a  ger allocated.**
7c30: 20 62 79 20 74 68 65 20 63 75 72 72 65 6e 74 20   by the current 
7c40: 74 68 72 65 61 64 20 6d 61 79 20 62 65 20 73 71  thread may be sq
7c50: 6c 69 74 65 33 5f 66 72 65 65 28 29 65 64 2e 0a  lite3_free()ed..
7c60: 2a 2a 0a 2a 2a 20 6e 52 65 71 20 69 73 20 74 68  **.** nReq is th
7c70: 65 20 6e 75 6d 62 65 72 20 6f 66 20 62 79 74 65  e number of byte
7c80: 73 20 6f 66 20 6d 65 6d 6f 72 79 20 72 65 71 75  s of memory requ
7c90: 69 72 65 64 2e 20 4f 6e 63 65 20 74 68 69 73 20  ired. Once this 
7ca0: 6d 75 63 68 20 68 61 73 0a 2a 2a 20 62 65 65 6e  much has.** been
7cb0: 20 72 65 6c 65 61 73 65 64 2c 20 74 68 65 20 66   released, the f
7cc0: 75 6e 63 74 69 6f 6e 20 72 65 74 75 72 6e 73 2e  unction returns.
7cd0: 20 54 68 65 20 72 65 74 75 72 6e 20 76 61 6c 75   The return valu
7ce0: 65 20 69 73 20 74 68 65 20 74 6f 74 61 6c 20 6e  e is the total n
7cf0: 75 6d 62 65 72 20 0a 2a 2a 20 6f 66 20 62 79 74  umber .** of byt
7d00: 65 73 20 6f 66 20 6d 65 6d 6f 72 79 20 72 65 6c  es of memory rel
7d10: 65 61 73 65 64 2e 0a 2a 2f 0a 69 6e 74 20 73 71  eased..*/.int sq
7d20: 6c 69 74 65 33 50 63 61 63 68 65 52 65 6c 65 61  lite3PcacheRelea
7d30: 73 65 4d 65 6d 6f 72 79 28 69 6e 74 20 6e 52 65  seMemory(int nRe
7d40: 71 29 7b 0a 20 20 69 6e 74 20 6e 46 72 65 65 20  q){.  int nFree 
7d50: 3d 20 30 3b 0a 20 20 61 73 73 65 72 74 28 20 73  = 0;.  assert( s
7d60: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6e 6f 74  qlite3_mutex_not
7d70: 68 65 6c 64 28 70 63 61 63 68 65 31 2e 67 72 70  held(pcache1.grp
7d80: 2e 6d 75 74 65 78 29 20 29 3b 0a 20 20 61 73 73  .mutex) );.  ass
7d90: 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74  ert( sqlite3_mut
7da0: 65 78 5f 6e 6f 74 68 65 6c 64 28 70 63 61 63 68  ex_notheld(pcach
7db0: 65 31 2e 6d 75 74 65 78 29 20 29 3b 0a 20 20 69  e1.mutex) );.  i
7dc0: 66 28 20 70 63 61 63 68 65 31 2e 70 53 74 61 72  f( pcache1.pStar
7dd0: 74 3d 3d 30 20 29 7b 0a 20 20 20 20 50 67 48 64  t==0 ){.    PgHd
7de0: 72 31 20 2a 70 3b 0a 20 20 20 20 70 63 61 63 68  r1 *p;.    pcach
7df0: 65 31 45 6e 74 65 72 4d 75 74 65 78 28 26 70 63  e1EnterMutex(&pc
7e00: 61 63 68 65 31 2e 67 72 70 29 3b 0a 20 20 20 20  ache1.grp);.    
7e10: 77 68 69 6c 65 28 20 28 6e 52 65 71 3c 30 20 7c  while( (nReq<0 |
7e20: 7c 20 6e 46 72 65 65 3c 6e 52 65 71 29 20 26 26  | nFree<nReq) &&
7e30: 20 28 28 70 3d 70 63 61 63 68 65 31 2e 67 72 70   ((p=pcache1.grp
7e40: 2e 70 4c 72 75 54 61 69 6c 29 21 3d 30 29 20 29  .pLruTail)!=0) )
7e50: 7b 0a 20 20 20 20 20 20 6e 46 72 65 65 20 2b 3d  {.      nFree +=
7e60: 20 70 63 61 63 68 65 31 4d 65 6d 53 69 7a 65 28   pcache1MemSize(
7e70: 70 2d 3e 70 61 67 65 2e 70 42 75 66 29 3b 0a 23  p->page.pBuf);.#
7e80: 69 66 64 65 66 20 53 51 4c 49 54 45 5f 50 43 41  ifdef SQLITE_PCA
7e90: 43 48 45 5f 53 45 50 41 52 41 54 45 5f 48 45 41  CHE_SEPARATE_HEA
7ea0: 44 45 52 0a 20 20 20 20 20 20 6e 46 72 65 65 20  DER.      nFree 
7eb0: 2b 3d 20 73 71 6c 69 74 65 33 4d 65 6d 53 69 7a  += sqlite3MemSiz
7ec0: 65 28 70 29 3b 0a 23 65 6e 64 69 66 0a 20 20 20  e(p);.#endif.   
7ed0: 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e 69 73     assert( p->is
7ee0: 50 69 6e 6e 65 64 3d 3d 30 20 29 3b 0a 20 20 20  Pinned==0 );.   
7ef0: 20 20 20 70 63 61 63 68 65 31 50 69 6e 50 61 67     pcache1PinPag
7f00: 65 28 70 29 3b 0a 20 20 20 20 20 20 70 63 61 63  e(p);.      pcac
7f10: 68 65 31 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73  he1RemoveFromHas
7f20: 68 28 70 29 3b 0a 20 20 20 20 20 20 70 63 61 63  h(p);.      pcac
7f30: 68 65 31 46 72 65 65 50 61 67 65 28 70 29 3b 0a  he1FreePage(p);.
7f40: 20 20 20 20 7d 0a 20 20 20 20 70 63 61 63 68 65      }.    pcache
7f50: 31 4c 65 61 76 65 4d 75 74 65 78 28 26 70 63 61  1LeaveMutex(&pca
7f60: 63 68 65 31 2e 67 72 70 29 3b 0a 20 20 7d 0a 20  che1.grp);.  }. 
7f70: 20 72 65 74 75 72 6e 20 6e 46 72 65 65 3b 0a 7d   return nFree;.}
7f80: 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49 54  .#endif /* SQLIT
7f90: 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f  E_ENABLE_MEMORY_
7fa0: 4d 41 4e 41 47 45 4d 45 4e 54 20 2a 2f 0a 0a 23  MANAGEMENT */..#
7fb0: 69 66 64 65 66 20 53 51 4c 49 54 45 5f 54 45 53  ifdef SQLITE_TES
7fc0: 54 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e  T./*.** This fun
7fd0: 63 74 69 6f 6e 20 69 73 20 75 73 65 64 20 62 79  ction is used by
7fe0: 20 74 65 73 74 20 70 72 6f 63 65 64 75 72 65 73   test procedures
7ff0: 20 74 6f 20 69 6e 73 70 65 63 74 20 74 68 65 20   to inspect the 
8000: 69 6e 74 65 72 6e 61 6c 20 73 74 61 74 65 0a 2a  internal state.*
8010: 2a 20 6f 66 20 74 68 65 20 67 6c 6f 62 61 6c 20  * of the global 
8020: 63 61 63 68 65 2e 0a 2a 2f 0a 76 6f 69 64 20 73  cache..*/.void s
8030: 71 6c 69 74 65 33 50 63 61 63 68 65 53 74 61 74  qlite3PcacheStat
8040: 73 28 0a 20 20 69 6e 74 20 2a 70 6e 43 75 72 72  s(.  int *pnCurr
8050: 65 6e 74 2c 20 20 20 20 20 20 2f 2a 20 4f 55 54  ent,      /* OUT
8060: 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f  : Total number o
8070: 66 20 70 61 67 65 73 20 63 61 63 68 65 64 20 2a  f pages cached *
8080: 2f 0a 20 20 69 6e 74 20 2a 70 6e 4d 61 78 2c 20  /.  int *pnMax, 
8090: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
80a0: 20 47 6c 6f 62 61 6c 20 6d 61 78 69 6d 75 6d 20   Global maximum 
80b0: 63 61 63 68 65 20 73 69 7a 65 20 2a 2f 0a 20 20  cache size */.  
80c0: 69 6e 74 20 2a 70 6e 4d 69 6e 2c 20 20 20 20 20  int *pnMin,     
80d0: 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 53 75 6d       /* OUT: Sum
80e0: 20 6f 66 20 50 43 61 63 68 65 31 2e 6e 4d 69 6e   of PCache1.nMin
80f0: 20 66 6f 72 20 70 75 72 67 65 61 62 6c 65 20 63   for purgeable c
8100: 61 63 68 65 73 20 2a 2f 0a 20 20 69 6e 74 20 2a  aches */.  int *
8110: 70 6e 52 65 63 79 63 6c 61 62 6c 65 20 20 20 20  pnRecyclable    
8120: 2f 2a 20 4f 55 54 3a 20 54 6f 74 61 6c 20 6e 75  /* OUT: Total nu
8130: 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 61 76  mber of pages av
8140: 61 69 6c 61 62 6c 65 20 66 6f 72 20 72 65 63 79  ailable for recy
8150: 63 6c 69 6e 67 20 2a 2f 0a 29 7b 0a 20 20 50 67  cling */.){.  Pg
8160: 48 64 72 31 20 2a 70 3b 0a 20 20 69 6e 74 20 6e  Hdr1 *p;.  int n
8170: 52 65 63 79 63 6c 61 62 6c 65 20 3d 20 30 3b 0a  Recyclable = 0;.
8180: 20 20 66 6f 72 28 70 3d 70 63 61 63 68 65 31 2e    for(p=pcache1.
8190: 67 72 70 2e 70 4c 72 75 48 65 61 64 3b 20 70 3b  grp.pLruHead; p;
81a0: 20 70 3d 70 2d 3e 70 4c 72 75 4e 65 78 74 29 7b   p=p->pLruNext){
81b0: 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e  .    assert( p->
81c0: 69 73 50 69 6e 6e 65 64 3d 3d 30 20 29 3b 0a 20  isPinned==0 );. 
81d0: 20 20 20 6e 52 65 63 79 63 6c 61 62 6c 65 2b 2b     nRecyclable++
81e0: 3b 0a 20 20 7d 0a 20 20 2a 70 6e 43 75 72 72 65  ;.  }.  *pnCurre
81f0: 6e 74 20 3d 20 70 63 61 63 68 65 31 2e 67 72 70  nt = pcache1.grp
8200: 2e 6e 43 75 72 72 65 6e 74 50 61 67 65 3b 0a 20  .nCurrentPage;. 
8210: 20 2a 70 6e 4d 61 78 20 3d 20 28 69 6e 74 29 70   *pnMax = (int)p
8220: 63 61 63 68 65 31 2e 67 72 70 2e 6e 4d 61 78 50  cache1.grp.nMaxP
8230: 61 67 65 3b 0a 20 20 2a 70 6e 4d 69 6e 20 3d 20  age;.  *pnMin = 
8240: 28 69 6e 74 29 70 63 61 63 68 65 31 2e 67 72 70  (int)pcache1.grp
8250: 2e 6e 4d 69 6e 50 61 67 65 3b 0a 20 20 2a 70 6e  .nMinPage;.  *pn
8260: 52 65 63 79 63 6c 61 62 6c 65 20 3d 20 6e 52 65  Recyclable = nRe
8270: 63 79 63 6c 61 62 6c 65 3b 0a 7d 0a 23 65 6e 64  cyclable;.}.#end
8280: 69 66 0a                                         if.