/ Hex Artifact Content
Login

Artifact c5af6403a55178c9d1c09e4f77b0f9c88822762c:


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 76 6f 69 64 20 70 63 61  .static void pca
3600: 63 68 65 31 52 65 73 69 7a 65 48 61 73 68 28 50  che1ResizeHash(P
3610: 43 61 63 68 65 31 20 2a 70 29 7b 0a 20 20 50 67  Cache1 *p){.  Pg
3620: 48 64 72 31 20 2a 2a 61 70 4e 65 77 3b 0a 20 20  Hdr1 **apNew;.  
3630: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 4e 65  unsigned int nNe
3640: 77 3b 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e  w;.  unsigned in
3650: 74 20 69 3b 0a 0a 20 20 61 73 73 65 72 74 28 20  t i;..  assert( 
3660: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65  sqlite3_mutex_he
3670: 6c 64 28 70 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75  ld(p->pGroup->mu
3680: 74 65 78 29 20 29 3b 0a 0a 20 20 6e 4e 65 77 20  tex) );..  nNew 
3690: 3d 20 70 2d 3e 6e 48 61 73 68 2a 32 3b 0a 20 20  = p->nHash*2;.  
36a0: 69 66 28 20 6e 4e 65 77 3c 32 35 36 20 29 7b 0a  if( nNew<256 ){.
36b0: 20 20 20 20 6e 4e 65 77 20 3d 20 32 35 36 3b 0a      nNew = 256;.
36c0: 20 20 7d 0a 0a 20 20 70 63 61 63 68 65 31 4c 65    }..  pcache1Le
36d0: 61 76 65 4d 75 74 65 78 28 70 2d 3e 70 47 72 6f  aveMutex(p->pGro
36e0: 75 70 29 3b 0a 20 20 69 66 28 20 70 2d 3e 6e 48  up);.  if( p->nH
36f0: 61 73 68 20 29 7b 20 73 71 6c 69 74 65 33 42 65  ash ){ sqlite3Be
3700: 67 69 6e 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28  ginBenignMalloc(
3710: 29 3b 20 7d 0a 20 20 61 70 4e 65 77 20 3d 20 28  ); }.  apNew = (
3720: 50 67 48 64 72 31 20 2a 2a 29 73 71 6c 69 74 65  PgHdr1 **)sqlite
3730: 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28 73 69 7a 65  3MallocZero(size
3740: 6f 66 28 50 67 48 64 72 31 20 2a 29 2a 6e 4e 65  of(PgHdr1 *)*nNe
3750: 77 29 3b 0a 20 20 69 66 28 20 70 2d 3e 6e 48 61  w);.  if( p->nHa
3760: 73 68 20 29 7b 20 73 71 6c 69 74 65 33 45 6e 64  sh ){ sqlite3End
3770: 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 20  BenignMalloc(); 
3780: 7d 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65 72  }.  pcache1Enter
3790: 4d 75 74 65 78 28 70 2d 3e 70 47 72 6f 75 70 29  Mutex(p->pGroup)
37a0: 3b 0a 20 20 69 66 28 20 61 70 4e 65 77 20 29 7b  ;.  if( apNew ){
37b0: 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  .    for(i=0; i<
37c0: 70 2d 3e 6e 48 61 73 68 3b 20 69 2b 2b 29 7b 0a  p->nHash; i++){.
37d0: 20 20 20 20 20 20 50 67 48 64 72 31 20 2a 70 50        PgHdr1 *pP
37e0: 61 67 65 3b 0a 20 20 20 20 20 20 50 67 48 64 72  age;.      PgHdr
37f0: 31 20 2a 70 4e 65 78 74 20 3d 20 70 2d 3e 61 70  1 *pNext = p->ap
3800: 48 61 73 68 5b 69 5d 3b 0a 20 20 20 20 20 20 77  Hash[i];.      w
3810: 68 69 6c 65 28 20 28 70 50 61 67 65 20 3d 20 70  hile( (pPage = p
3820: 4e 65 78 74 29 21 3d 30 20 29 7b 0a 20 20 20 20  Next)!=0 ){.    
3830: 20 20 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74      unsigned int
3840: 20 68 20 3d 20 70 50 61 67 65 2d 3e 69 4b 65 79   h = pPage->iKey
3850: 20 25 20 6e 4e 65 77 3b 0a 20 20 20 20 20 20 20   % nNew;.       
3860: 20 70 4e 65 78 74 20 3d 20 70 50 61 67 65 2d 3e   pNext = pPage->
3870: 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 20 20 70  pNext;.        p
3880: 50 61 67 65 2d 3e 70 4e 65 78 74 20 3d 20 61 70  Page->pNext = ap
3890: 4e 65 77 5b 68 5d 3b 0a 20 20 20 20 20 20 20 20  New[h];.        
38a0: 61 70 4e 65 77 5b 68 5d 20 3d 20 70 50 61 67 65  apNew[h] = pPage
38b0: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
38c0: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
38d0: 28 70 2d 3e 61 70 48 61 73 68 29 3b 0a 20 20 20  (p->apHash);.   
38e0: 20 70 2d 3e 61 70 48 61 73 68 20 3d 20 61 70 4e   p->apHash = apN
38f0: 65 77 3b 0a 20 20 20 20 70 2d 3e 6e 48 61 73 68  ew;.    p->nHash
3900: 20 3d 20 6e 4e 65 77 3b 0a 20 20 7d 0a 7d 0a 0a   = nNew;.  }.}..
3910: 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  /*.** This funct
3920: 69 6f 6e 20 69 73 20 75 73 65 64 20 69 6e 74 65  ion is used inte
3930: 72 6e 61 6c 6c 79 20 74 6f 20 72 65 6d 6f 76 65  rnally to remove
3940: 20 74 68 65 20 70 61 67 65 20 70 50 61 67 65 20   the page pPage 
3950: 66 72 6f 6d 20 74 68 65 20 0a 2a 2a 20 50 47 72  from the .** PGr
3960: 6f 75 70 20 4c 52 55 20 6c 69 73 74 2c 20 69 66  oup LRU list, if
3970: 20 69 73 20 70 61 72 74 20 6f 66 20 69 74 2e 20   is part of it. 
3980: 49 66 20 70 50 61 67 65 20 69 73 20 6e 6f 74 20  If pPage is not 
3990: 70 61 72 74 20 6f 66 20 74 68 65 20 50 47 72 6f  part of the PGro
39a0: 75 70 0a 2a 2a 20 4c 52 55 20 6c 69 73 74 2c 20  up.** LRU list, 
39b0: 74 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69  then this functi
39c0: 6f 6e 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a 2a  on is a no-op..*
39d0: 2a 0a 2a 2a 20 54 68 65 20 50 47 72 6f 75 70 20  *.** The PGroup 
39e0: 6d 75 74 65 78 20 6d 75 73 74 20 62 65 20 68 65  mutex must be he
39f0: 6c 64 20 77 68 65 6e 20 74 68 69 73 20 66 75 6e  ld when this fun
3a00: 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 2e  ction is called.
3a10: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
3a20: 70 63 61 63 68 65 31 50 69 6e 50 61 67 65 28 50  pcache1PinPage(P
3a30: 67 48 64 72 31 20 2a 70 50 61 67 65 29 7b 0a 20  gHdr1 *pPage){. 
3a40: 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68 65   PCache1 *pCache
3a50: 3b 0a 20 20 50 47 72 6f 75 70 20 2a 70 47 72 6f  ;.  PGroup *pGro
3a60: 75 70 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70  up;..  assert( p
3a70: 50 61 67 65 21 3d 30 20 29 3b 0a 20 20 61 73 73  Page!=0 );.  ass
3a80: 65 72 74 28 20 70 50 61 67 65 2d 3e 69 73 50 69  ert( pPage->isPi
3a90: 6e 6e 65 64 3d 3d 30 20 29 3b 0a 20 20 70 43 61  nned==0 );.  pCa
3aa0: 63 68 65 20 3d 20 70 50 61 67 65 2d 3e 70 43 61  che = pPage->pCa
3ab0: 63 68 65 3b 0a 20 20 70 47 72 6f 75 70 20 3d 20  che;.  pGroup = 
3ac0: 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b 0a  pCache->pGroup;.
3ad0: 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65 2d    assert( pPage-
3ae0: 3e 70 4c 72 75 4e 65 78 74 20 7c 7c 20 70 50 61  >pLruNext || pPa
3af0: 67 65 3d 3d 70 47 72 6f 75 70 2d 3e 70 4c 72 75  ge==pGroup->pLru
3b00: 54 61 69 6c 20 29 3b 0a 20 20 61 73 73 65 72 74  Tail );.  assert
3b10: 28 20 70 50 61 67 65 2d 3e 70 4c 72 75 50 72 65  ( pPage->pLruPre
3b20: 76 20 7c 7c 20 70 50 61 67 65 3d 3d 70 47 72 6f  v || pPage==pGro
3b30: 75 70 2d 3e 70 4c 72 75 48 65 61 64 20 29 3b 0a  up->pLruHead );.
3b40: 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65    assert( sqlite
3b50: 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 47 72  3_mutex_held(pGr
3b60: 6f 75 70 2d 3e 6d 75 74 65 78 29 20 29 3b 0a 20  oup->mutex) );. 
3b70: 20 69 66 28 20 70 50 61 67 65 2d 3e 70 4c 72 75   if( pPage->pLru
3b80: 50 72 65 76 20 29 7b 0a 20 20 20 20 70 50 61 67  Prev ){.    pPag
3b90: 65 2d 3e 70 4c 72 75 50 72 65 76 2d 3e 70 4c 72  e->pLruPrev->pLr
3ba0: 75 4e 65 78 74 20 3d 20 70 50 61 67 65 2d 3e 70  uNext = pPage->p
3bb0: 4c 72 75 4e 65 78 74 3b 0a 20 20 7d 65 6c 73 65  LruNext;.  }else
3bc0: 7b 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e 70 4c  {.    pGroup->pL
3bd0: 72 75 48 65 61 64 20 3d 20 70 50 61 67 65 2d 3e  ruHead = pPage->
3be0: 70 4c 72 75 4e 65 78 74 3b 0a 20 20 7d 0a 20 20  pLruNext;.  }.  
3bf0: 69 66 28 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e  if( pPage->pLruN
3c00: 65 78 74 20 29 7b 0a 20 20 20 20 70 50 61 67 65  ext ){.    pPage
3c10: 2d 3e 70 4c 72 75 4e 65 78 74 2d 3e 70 4c 72 75  ->pLruNext->pLru
3c20: 50 72 65 76 20 3d 20 70 50 61 67 65 2d 3e 70 4c  Prev = pPage->pL
3c30: 72 75 50 72 65 76 3b 0a 20 20 7d 65 6c 73 65 7b  ruPrev;.  }else{
3c40: 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e 70 4c 72  .    pGroup->pLr
3c50: 75 54 61 69 6c 20 3d 20 70 50 61 67 65 2d 3e 70  uTail = pPage->p
3c60: 4c 72 75 50 72 65 76 3b 0a 20 20 7d 0a 20 20 70  LruPrev;.  }.  p
3c70: 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 20 3d  Page->pLruNext =
3c80: 20 30 3b 0a 20 20 70 50 61 67 65 2d 3e 70 4c 72   0;.  pPage->pLr
3c90: 75 50 72 65 76 20 3d 20 30 3b 0a 20 20 70 50 61  uPrev = 0;.  pPa
3ca0: 67 65 2d 3e 69 73 50 69 6e 6e 65 64 20 3d 20 31  ge->isPinned = 1
3cb0: 3b 0a 20 20 70 43 61 63 68 65 2d 3e 6e 52 65 63  ;.  pCache->nRec
3cc0: 79 63 6c 61 62 6c 65 2d 2d 3b 0a 7d 0a 0a 0a 2f  yclable--;.}.../
3cd0: 2a 0a 2a 2a 20 52 65 6d 6f 76 65 20 74 68 65 20  *.** Remove the 
3ce0: 70 61 67 65 20 73 75 70 70 6c 69 65 64 20 61 73  page supplied as
3cf0: 20 61 6e 20 61 72 67 75 6d 65 6e 74 20 66 72 6f   an argument fro
3d00: 6d 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65  m the hash table
3d10: 20 0a 2a 2a 20 28 50 43 61 63 68 65 31 2e 61 70   .** (PCache1.ap
3d20: 48 61 73 68 20 73 74 72 75 63 74 75 72 65 29 20  Hash structure) 
3d30: 74 68 61 74 20 69 74 20 69 73 20 63 75 72 72 65  that it is curre
3d40: 6e 74 6c 79 20 73 74 6f 72 65 64 20 69 6e 2e 0a  ntly stored in..
3d50: 2a 2a 0a 2a 2a 20 54 68 65 20 50 47 72 6f 75 70  **.** The PGroup
3d60: 20 6d 75 74 65 78 20 6d 75 73 74 20 62 65 20 68   mutex must be h
3d70: 65 6c 64 20 77 68 65 6e 20 74 68 69 73 20 66 75  eld when this fu
3d80: 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64  nction is called
3d90: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
3da0: 20 70 63 61 63 68 65 31 52 65 6d 6f 76 65 46 72   pcache1RemoveFr
3db0: 6f 6d 48 61 73 68 28 50 67 48 64 72 31 20 2a 70  omHash(PgHdr1 *p
3dc0: 50 61 67 65 29 7b 0a 20 20 75 6e 73 69 67 6e 65  Page){.  unsigne
3dd0: 64 20 69 6e 74 20 68 3b 0a 20 20 50 43 61 63 68  d int h;.  PCach
3de0: 65 31 20 2a 70 43 61 63 68 65 20 3d 20 70 50 61  e1 *pCache = pPa
3df0: 67 65 2d 3e 70 43 61 63 68 65 3b 0a 20 20 50 67  ge->pCache;.  Pg
3e00: 48 64 72 31 20 2a 2a 70 70 3b 0a 0a 20 20 61 73  Hdr1 **pp;..  as
3e10: 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75  sert( sqlite3_mu
3e20: 74 65 78 5f 68 65 6c 64 28 70 43 61 63 68 65 2d  tex_held(pCache-
3e30: 3e 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78 29 20  >pGroup->mutex) 
3e40: 29 3b 0a 20 20 68 20 3d 20 70 50 61 67 65 2d 3e  );.  h = pPage->
3e50: 69 4b 65 79 20 25 20 70 43 61 63 68 65 2d 3e 6e  iKey % pCache->n
3e60: 48 61 73 68 3b 0a 20 20 66 6f 72 28 70 70 3d 26  Hash;.  for(pp=&
3e70: 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68  pCache->apHash[h
3e80: 5d 3b 20 28 2a 70 70 29 21 3d 70 50 61 67 65 3b  ]; (*pp)!=pPage;
3e90: 20 70 70 3d 26 28 2a 70 70 29 2d 3e 70 4e 65 78   pp=&(*pp)->pNex
3ea0: 74 29 3b 0a 20 20 2a 70 70 20 3d 20 28 2a 70 70  t);.  *pp = (*pp
3eb0: 29 2d 3e 70 4e 65 78 74 3b 0a 0a 20 20 70 43 61  )->pNext;..  pCa
3ec0: 63 68 65 2d 3e 6e 50 61 67 65 2d 2d 3b 0a 7d 0a  che->nPage--;.}.
3ed0: 0a 2f 2a 0a 2a 2a 20 49 66 20 74 68 65 72 65 20  ./*.** If there 
3ee0: 61 72 65 20 63 75 72 72 65 6e 74 6c 79 20 6d 6f  are currently mo
3ef0: 72 65 20 74 68 61 6e 20 6e 4d 61 78 50 61 67 65  re than nMaxPage
3f00: 20 70 61 67 65 73 20 61 6c 6c 6f 63 61 74 65 64   pages allocated
3f10: 2c 20 74 72 79 0a 2a 2a 20 74 6f 20 72 65 63 79  , try.** to recy
3f20: 63 6c 65 20 70 61 67 65 73 20 74 6f 20 72 65 64  cle pages to red
3f30: 75 63 65 20 74 68 65 20 6e 75 6d 62 65 72 20 61  uce the number a
3f40: 6c 6c 6f 63 61 74 65 64 20 74 6f 20 6e 4d 61 78  llocated to nMax
3f50: 50 61 67 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  Page..*/.static 
3f60: 76 6f 69 64 20 70 63 61 63 68 65 31 45 6e 66 6f  void pcache1Enfo
3f70: 72 63 65 4d 61 78 50 61 67 65 28 50 47 72 6f 75  rceMaxPage(PGrou
3f80: 70 20 2a 70 47 72 6f 75 70 29 7b 0a 20 20 61 73  p *pGroup){.  as
3f90: 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75  sert( sqlite3_mu
3fa0: 74 65 78 5f 68 65 6c 64 28 70 47 72 6f 75 70 2d  tex_held(pGroup-
3fb0: 3e 6d 75 74 65 78 29 20 29 3b 0a 20 20 77 68 69  >mutex) );.  whi
3fc0: 6c 65 28 20 70 47 72 6f 75 70 2d 3e 6e 43 75 72  le( pGroup->nCur
3fd0: 72 65 6e 74 50 61 67 65 3e 70 47 72 6f 75 70 2d  rentPage>pGroup-
3fe0: 3e 6e 4d 61 78 50 61 67 65 20 26 26 20 70 47 72  >nMaxPage && pGr
3ff0: 6f 75 70 2d 3e 70 4c 72 75 54 61 69 6c 20 29 7b  oup->pLruTail ){
4000: 0a 20 20 20 20 50 67 48 64 72 31 20 2a 70 20 3d  .    PgHdr1 *p =
4010: 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 54 61 69   pGroup->pLruTai
4020: 6c 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70  l;.    assert( p
4030: 2d 3e 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70  ->pCache->pGroup
4040: 3d 3d 70 47 72 6f 75 70 20 29 3b 0a 20 20 20 20  ==pGroup );.    
4050: 61 73 73 65 72 74 28 20 70 2d 3e 69 73 50 69 6e  assert( p->isPin
4060: 6e 65 64 3d 3d 30 20 29 3b 0a 20 20 20 20 70 63  ned==0 );.    pc
4070: 61 63 68 65 31 50 69 6e 50 61 67 65 28 70 29 3b  ache1PinPage(p);
4080: 0a 20 20 20 20 70 63 61 63 68 65 31 52 65 6d 6f  .    pcache1Remo
4090: 76 65 46 72 6f 6d 48 61 73 68 28 70 29 3b 0a 20  veFromHash(p);. 
40a0: 20 20 20 70 63 61 63 68 65 31 46 72 65 65 50 61     pcache1FreePa
40b0: 67 65 28 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a  ge(p);.  }.}../*
40c0: 0a 2a 2a 20 44 69 73 63 61 72 64 20 61 6c 6c 20  .** Discard all 
40d0: 70 61 67 65 73 20 66 72 6f 6d 20 63 61 63 68 65  pages from cache
40e0: 20 70 43 61 63 68 65 20 77 69 74 68 20 61 20 70   pCache with a p
40f0: 61 67 65 20 6e 75 6d 62 65 72 20 28 6b 65 79 20  age number (key 
4100: 76 61 6c 75 65 29 20 0a 2a 2a 20 67 72 65 61 74  value) .** great
4110: 65 72 20 74 68 61 6e 20 6f 72 20 65 71 75 61 6c  er than or equal
4120: 20 74 6f 20 69 4c 69 6d 69 74 2e 20 41 6e 79 20   to iLimit. Any 
4130: 70 69 6e 6e 65 64 20 70 61 67 65 73 20 74 68 61  pinned pages tha
4140: 74 20 6d 65 65 74 20 74 68 69 73 20 0a 2a 2a 20  t meet this .** 
4150: 63 72 69 74 65 72 69 61 20 61 72 65 20 75 6e 70  criteria are unp
4160: 69 6e 6e 65 64 20 62 65 66 6f 72 65 20 74 68 65  inned before the
4170: 79 20 61 72 65 20 64 69 73 63 61 72 64 65 64 2e  y are discarded.
4180: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 50 43 61 63 68  .**.** The PCach
4190: 65 20 6d 75 74 65 78 20 6d 75 73 74 20 62 65 20  e mutex must be 
41a0: 68 65 6c 64 20 77 68 65 6e 20 74 68 69 73 20 66  held when this f
41b0: 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65  unction is calle
41c0: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  d..*/.static voi
41d0: 64 20 70 63 61 63 68 65 31 54 72 75 6e 63 61 74  d pcache1Truncat
41e0: 65 55 6e 73 61 66 65 28 0a 20 20 50 43 61 63 68  eUnsafe(.  PCach
41f0: 65 31 20 2a 70 43 61 63 68 65 2c 20 20 20 20 20  e1 *pCache,     
4200: 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 63          /* The c
4210: 61 63 68 65 20 74 6f 20 74 72 75 6e 63 61 74 65  ache to truncate
4220: 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69   */.  unsigned i
4230: 6e 74 20 69 4c 69 6d 69 74 20 20 20 20 20 20 20  nt iLimit       
4240: 20 20 20 2f 2a 20 44 72 6f 70 20 70 61 67 65 73     /* Drop pages
4250: 20 77 69 74 68 20 74 68 69 73 20 70 67 6e 6f 20   with this pgno 
4260: 6f 72 20 6c 61 72 67 65 72 20 2a 2f 0a 29 7b 0a  or larger */.){.
4270: 20 20 54 45 53 54 4f 4e 4c 59 28 20 75 6e 73 69    TESTONLY( unsi
4280: 67 6e 65 64 20 69 6e 74 20 6e 50 61 67 65 20 3d  gned int nPage =
4290: 20 30 3b 20 29 20 20 2f 2a 20 54 6f 20 61 73 73   0; )  /* To ass
42a0: 65 72 74 20 70 43 61 63 68 65 2d 3e 6e 50 61 67  ert pCache->nPag
42b0: 65 20 69 73 20 63 6f 72 72 65 63 74 20 2a 2f 0a  e is correct */.
42c0: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68    unsigned int h
42d0: 3b 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c 69  ;.  assert( sqli
42e0: 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70  te3_mutex_held(p
42f0: 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 2d 3e 6d  Cache->pGroup->m
4300: 75 74 65 78 29 20 29 3b 0a 20 20 66 6f 72 28 68  utex) );.  for(h
4310: 3d 30 3b 20 68 3c 70 43 61 63 68 65 2d 3e 6e 48  =0; h<pCache->nH
4320: 61 73 68 3b 20 68 2b 2b 29 7b 0a 20 20 20 20 50  ash; h++){.    P
4330: 67 48 64 72 31 20 2a 2a 70 70 20 3d 20 26 70 43  gHdr1 **pp = &pC
4340: 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b  ache->apHash[h];
4350: 20 0a 20 20 20 20 50 67 48 64 72 31 20 2a 70 50   .    PgHdr1 *pP
4360: 61 67 65 3b 0a 20 20 20 20 77 68 69 6c 65 28 20  age;.    while( 
4370: 28 70 50 61 67 65 20 3d 20 2a 70 70 29 21 3d 30  (pPage = *pp)!=0
4380: 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 70 50   ){.      if( pP
4390: 61 67 65 2d 3e 69 4b 65 79 3e 3d 69 4c 69 6d 69  age->iKey>=iLimi
43a0: 74 20 29 7b 0a 20 20 20 20 20 20 20 20 70 43 61  t ){.        pCa
43b0: 63 68 65 2d 3e 6e 50 61 67 65 2d 2d 3b 0a 20 20  che->nPage--;.  
43c0: 20 20 20 20 20 20 2a 70 70 20 3d 20 70 50 61 67        *pp = pPag
43d0: 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20  e->pNext;.      
43e0: 20 20 69 66 28 20 21 70 50 61 67 65 2d 3e 69 73    if( !pPage->is
43f0: 50 69 6e 6e 65 64 20 29 20 70 63 61 63 68 65 31  Pinned ) pcache1
4400: 50 69 6e 50 61 67 65 28 70 50 61 67 65 29 3b 0a  PinPage(pPage);.
4410: 20 20 20 20 20 20 20 20 70 63 61 63 68 65 31 46          pcache1F
4420: 72 65 65 50 61 67 65 28 70 50 61 67 65 29 3b 0a  reePage(pPage);.
4430: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
4440: 20 20 20 20 20 70 70 20 3d 20 26 70 50 61 67 65       pp = &pPage
4450: 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 20  ->pNext;.       
4460: 20 54 45 53 54 4f 4e 4c 59 28 20 6e 50 61 67 65   TESTONLY( nPage
4470: 2b 2b 3b 20 29 0a 20 20 20 20 20 20 7d 0a 20 20  ++; ).      }.  
4480: 20 20 7d 0a 20 20 7d 0a 20 20 61 73 73 65 72 74    }.  }.  assert
4490: 28 20 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 3d  ( pCache->nPage=
44a0: 3d 6e 50 61 67 65 20 29 3b 0a 7d 0a 0a 2f 2a 2a  =nPage );.}../**
44b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
44c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
44d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
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 2f 0a 2f 2a  ************/./*
4500: 2a 2a 2a 2a 2a 2a 2a 20 73 71 6c 69 74 65 33 5f  ******* sqlite3_
4510: 70 63 61 63 68 65 20 4d 65 74 68 6f 64 73 20 2a  pcache Methods *
4520: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4530: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4540: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a  *************/..
4550: 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61  /*.** Implementa
4560: 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69  tion of the sqli
4570: 74 65 33 5f 70 63 61 63 68 65 2e 78 49 6e 69 74  te3_pcache.xInit
4580: 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74   method..*/.stat
4590: 69 63 20 69 6e 74 20 70 63 61 63 68 65 31 49 6e  ic int pcache1In
45a0: 69 74 28 76 6f 69 64 20 2a 4e 6f 74 55 73 65 64  it(void *NotUsed
45b0: 29 7b 0a 20 20 55 4e 55 53 45 44 5f 50 41 52 41  ){.  UNUSED_PARA
45c0: 4d 45 54 45 52 28 4e 6f 74 55 73 65 64 29 3b 0a  METER(NotUsed);.
45d0: 20 20 61 73 73 65 72 74 28 20 70 63 61 63 68 65    assert( pcache
45e0: 31 2e 69 73 49 6e 69 74 3d 3d 30 20 29 3b 0a 20  1.isInit==0 );. 
45f0: 20 6d 65 6d 73 65 74 28 26 70 63 61 63 68 65 31   memset(&pcache1
4600: 2c 20 30 2c 20 73 69 7a 65 6f 66 28 70 63 61 63  , 0, sizeof(pcac
4610: 68 65 31 29 29 3b 0a 20 20 69 66 28 20 73 71 6c  he1));.  if( sql
4620: 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67  ite3GlobalConfig
4630: 2e 62 43 6f 72 65 4d 75 74 65 78 20 29 7b 0a 20  .bCoreMutex ){. 
4640: 20 20 20 70 63 61 63 68 65 31 2e 67 72 70 2e 6d     pcache1.grp.m
4650: 75 74 65 78 20 3d 20 73 71 6c 69 74 65 33 5f 6d  utex = sqlite3_m
4660: 75 74 65 78 5f 61 6c 6c 6f 63 28 53 51 4c 49 54  utex_alloc(SQLIT
4670: 45 5f 4d 55 54 45 58 5f 53 54 41 54 49 43 5f 4c  E_MUTEX_STATIC_L
4680: 52 55 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31  RU);.    pcache1
4690: 2e 6d 75 74 65 78 20 3d 20 73 71 6c 69 74 65 33  .mutex = sqlite3
46a0: 5f 6d 75 74 65 78 5f 61 6c 6c 6f 63 28 53 51 4c  _mutex_alloc(SQL
46b0: 49 54 45 5f 4d 55 54 45 58 5f 53 54 41 54 49 43  ITE_MUTEX_STATIC
46c0: 5f 50 4d 45 4d 29 3b 0a 20 20 7d 0a 20 20 70 63  _PMEM);.  }.  pc
46d0: 61 63 68 65 31 2e 67 72 70 2e 6d 78 50 69 6e 6e  ache1.grp.mxPinn
46e0: 65 64 20 3d 20 31 30 3b 0a 20 20 70 63 61 63 68  ed = 10;.  pcach
46f0: 65 31 2e 69 73 49 6e 69 74 20 3d 20 31 3b 0a 20  e1.isInit = 1;. 
4700: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
4710: 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c  K;.}../*.** Impl
4720: 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68  ementation of th
4730: 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  e sqlite3_pcache
4740: 2e 78 53 68 75 74 64 6f 77 6e 20 6d 65 74 68 6f  .xShutdown metho
4750: 64 2e 0a 2a 2a 20 4e 6f 74 65 20 74 68 61 74 20  d..** Note that 
4760: 74 68 65 20 73 74 61 74 69 63 20 6d 75 74 65 78  the static mutex
4770: 20 61 6c 6c 6f 63 61 74 65 64 20 69 6e 20 78 49   allocated in xI
4780: 6e 69 74 20 64 6f 65 73 20 0a 2a 2a 20 6e 6f 74  nit does .** not
4790: 20 6e 65 65 64 20 74 6f 20 62 65 20 66 72 65 65   need to be free
47a0: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  d..*/.static voi
47b0: 64 20 70 63 61 63 68 65 31 53 68 75 74 64 6f 77  d pcache1Shutdow
47c0: 6e 28 76 6f 69 64 20 2a 4e 6f 74 55 73 65 64 29  n(void *NotUsed)
47d0: 7b 0a 20 20 55 4e 55 53 45 44 5f 50 41 52 41 4d  {.  UNUSED_PARAM
47e0: 45 54 45 52 28 4e 6f 74 55 73 65 64 29 3b 0a 20  ETER(NotUsed);. 
47f0: 20 61 73 73 65 72 74 28 20 70 63 61 63 68 65 31   assert( pcache1
4800: 2e 69 73 49 6e 69 74 21 3d 30 20 29 3b 0a 20 20  .isInit!=0 );.  
4810: 6d 65 6d 73 65 74 28 26 70 63 61 63 68 65 31 2c  memset(&pcache1,
4820: 20 30 2c 20 73 69 7a 65 6f 66 28 70 63 61 63 68   0, sizeof(pcach
4830: 65 31 29 29 3b 0a 7d 0a 0a 2f 2a 20 66 6f 72 77  e1));.}../* forw
4840: 61 72 64 20 64 65 63 6c 61 72 61 74 69 6f 6e 20  ard declaration 
4850: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70  */.static void p
4860: 63 61 63 68 65 31 44 65 73 74 72 6f 79 28 73 71  cache1Destroy(sq
4870: 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70 29  lite3_pcache *p)
4880: 3b 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65  ;../*.** Impleme
4890: 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73  ntation of the s
48a0: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78 43  qlite3_pcache.xC
48b0: 72 65 61 74 65 20 6d 65 74 68 6f 64 2e 0a 2a 2a  reate method..**
48c0: 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65 20 61 20 6e  .** Allocate a n
48d0: 65 77 20 63 61 63 68 65 2e 0a 2a 2f 0a 73 74 61  ew cache..*/.sta
48e0: 74 69 63 20 73 71 6c 69 74 65 33 5f 70 63 61 63  tic sqlite3_pcac
48f0: 68 65 20 2a 70 63 61 63 68 65 31 43 72 65 61 74  he *pcache1Creat
4900: 65 28 69 6e 74 20 73 7a 50 61 67 65 2c 20 69 6e  e(int szPage, in
4910: 74 20 73 7a 45 78 74 72 61 2c 20 69 6e 74 20 62  t szExtra, int b
4920: 50 75 72 67 65 61 62 6c 65 29 7b 0a 20 20 50 43  Purgeable){.  PC
4930: 61 63 68 65 31 20 2a 70 43 61 63 68 65 3b 20 20  ache1 *pCache;  
4940: 20 20 20 20 2f 2a 20 54 68 65 20 6e 65 77 6c 79      /* The newly
4950: 20 63 72 65 61 74 65 64 20 70 61 67 65 20 63 61   created page ca
4960: 63 68 65 20 2a 2f 0a 20 20 50 47 72 6f 75 70 20  che */.  PGroup 
4970: 2a 70 47 72 6f 75 70 3b 20 20 20 20 20 20 20 2f  *pGroup;       /
4980: 2a 20 54 68 65 20 67 72 6f 75 70 20 74 68 65 20  * The group the 
4990: 6e 65 77 20 70 61 67 65 20 63 61 63 68 65 20 77  new page cache w
49a0: 69 6c 6c 20 62 65 6c 6f 6e 67 20 74 6f 20 2a 2f  ill belong to */
49b0: 0a 20 20 69 6e 74 20 73 7a 3b 20 20 20 20 20 20  .  int sz;      
49c0: 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65           /* Byte
49d0: 73 20 6f 66 20 6d 65 6d 6f 72 79 20 72 65 71 75  s of memory requ
49e0: 69 72 65 64 20 74 6f 20 61 6c 6c 6f 63 61 74 65  ired to allocate
49f0: 20 74 68 65 20 6e 65 77 20 63 61 63 68 65 20 2a   the new cache *
4a00: 2f 0a 0a 20 20 2f 2a 0a 20 20 2a 2a 20 54 68 65  /..  /*.  ** The
4a10: 20 73 65 70 61 72 61 74 65 43 61 63 68 65 20 76   separateCache v
4a20: 61 72 69 61 62 6c 65 20 69 73 20 74 72 75 65 20  ariable is true 
4a30: 69 66 20 65 61 63 68 20 50 43 61 63 68 65 20 68  if each PCache h
4a40: 61 73 20 69 74 73 20 6f 77 6e 20 70 72 69 76 61  as its own priva
4a50: 74 65 0a 20 20 2a 2a 20 50 47 72 6f 75 70 2e 20  te.  ** PGroup. 
4a60: 20 49 6e 20 6f 74 68 65 72 20 77 6f 72 64 73 2c   In other words,
4a70: 20 73 65 70 61 72 61 74 65 43 61 63 68 65 20 69   separateCache i
4a80: 73 20 74 72 75 65 20 66 6f 72 20 6d 6f 64 65 20  s true for mode 
4a90: 28 31 29 20 77 68 65 72 65 20 6e 6f 0a 20 20 2a  (1) where no.  *
4aa0: 2a 20 6d 75 74 65 78 69 6e 67 20 69 73 20 72 65  * mutexing is re
4ab0: 71 75 69 72 65 64 2e 0a 20 20 2a 2a 0a 20 20 2a  quired..  **.  *
4ac0: 2a 20 20 20 2a 20 20 41 6c 77 61 79 73 20 75 73  *   *  Always us
4ad0: 65 20 61 20 75 6e 69 66 69 65 64 20 63 61 63 68  e a unified cach
4ae0: 65 20 28 6d 6f 64 65 2d 32 29 20 69 66 20 45 4e  e (mode-2) if EN
4af0: 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41  ABLE_MEMORY_MANA
4b00: 47 45 4d 45 4e 54 0a 20 20 2a 2a 0a 20 20 2a 2a  GEMENT.  **.  **
4b10: 20 20 20 2a 20 20 41 6c 77 61 79 73 20 75 73 65     *  Always use
4b20: 20 61 20 75 6e 69 66 69 65 64 20 63 61 63 68 65   a unified cache
4b30: 20 69 6e 20 73 69 6e 67 6c 65 2d 74 68 72 65 61   in single-threa
4b40: 64 65 64 20 61 70 70 6c 69 63 61 74 69 6f 6e 73  ded applications
4b50: 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 2a 20 20  .  **.  **   *  
4b60: 4f 74 68 65 72 77 69 73 65 20 28 69 66 20 6d 75  Otherwise (if mu
4b70: 6c 74 69 2d 74 68 72 65 61 64 65 64 20 61 6e 64  lti-threaded and
4b80: 20 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d   ENABLE_MEMORY_M
4b90: 41 4e 41 47 45 4d 45 4e 54 20 69 73 20 6f 66 66  ANAGEMENT is off
4ba0: 29 0a 20 20 2a 2a 20 20 20 20 20 20 75 73 65 20  ).  **      use 
4bb0: 73 65 70 61 72 61 74 65 20 63 61 63 68 65 73 20  separate caches 
4bc0: 28 6d 6f 64 65 2d 31 29 0a 20 20 2a 2f 0a 23 69  (mode-1).  */.#i
4bd0: 66 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45  f defined(SQLITE
4be0: 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d  _ENABLE_MEMORY_M
4bf0: 41 4e 41 47 45 4d 45 4e 54 29 20 7c 7c 20 53 51  ANAGEMENT) || SQ
4c00: 4c 49 54 45 5f 54 48 52 45 41 44 53 41 46 45 3d  LITE_THREADSAFE=
4c10: 3d 30 0a 20 20 63 6f 6e 73 74 20 69 6e 74 20 73  =0.  const int s
4c20: 65 70 61 72 61 74 65 43 61 63 68 65 20 3d 20 30  eparateCache = 0
4c30: 3b 0a 23 65 6c 73 65 0a 20 20 69 6e 74 20 73 65  ;.#else.  int se
4c40: 70 61 72 61 74 65 43 61 63 68 65 20 3d 20 73 71  parateCache = sq
4c50: 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69  lite3GlobalConfi
4c60: 67 2e 62 43 6f 72 65 4d 75 74 65 78 3e 30 3b 0a  g.bCoreMutex>0;.
4c70: 23 65 6e 64 69 66 0a 0a 20 20 61 73 73 65 72 74  #endif..  assert
4c80: 28 20 28 73 7a 50 61 67 65 20 26 20 28 73 7a 50  ( (szPage & (szP
4c90: 61 67 65 2d 31 29 29 3d 3d 30 20 26 26 20 73 7a  age-1))==0 && sz
4ca0: 50 61 67 65 3e 3d 35 31 32 20 26 26 20 73 7a 50  Page>=512 && szP
4cb0: 61 67 65 3c 3d 36 35 35 33 36 20 29 3b 0a 20 20  age<=65536 );.  
4cc0: 61 73 73 65 72 74 28 20 73 7a 45 78 74 72 61 20  assert( szExtra 
4cd0: 3c 20 33 30 30 20 29 3b 0a 0a 20 20 73 7a 20 3d  < 300 );..  sz =
4ce0: 20 73 69 7a 65 6f 66 28 50 43 61 63 68 65 31 29   sizeof(PCache1)
4cf0: 20 2b 20 73 69 7a 65 6f 66 28 50 47 72 6f 75 70   + sizeof(PGroup
4d00: 29 2a 73 65 70 61 72 61 74 65 43 61 63 68 65 3b  )*separateCache;
4d10: 0a 20 20 70 43 61 63 68 65 20 3d 20 28 50 43 61  .  pCache = (PCa
4d20: 63 68 65 31 20 2a 29 73 71 6c 69 74 65 33 4d 61  che1 *)sqlite3Ma
4d30: 6c 6c 6f 63 5a 65 72 6f 28 73 7a 29 3b 0a 20 20  llocZero(sz);.  
4d40: 69 66 28 20 70 43 61 63 68 65 20 29 7b 0a 20 20  if( pCache ){.  
4d50: 20 20 69 66 28 20 73 65 70 61 72 61 74 65 43 61    if( separateCa
4d60: 63 68 65 20 29 7b 0a 20 20 20 20 20 20 70 47 72  che ){.      pGr
4d70: 6f 75 70 20 3d 20 28 50 47 72 6f 75 70 2a 29 26  oup = (PGroup*)&
4d80: 70 43 61 63 68 65 5b 31 5d 3b 0a 20 20 20 20 20  pCache[1];.     
4d90: 20 70 47 72 6f 75 70 2d 3e 6d 78 50 69 6e 6e 65   pGroup->mxPinne
4da0: 64 20 3d 20 31 30 3b 0a 20 20 20 20 7d 65 6c 73  d = 10;.    }els
4db0: 65 7b 0a 20 20 20 20 20 20 70 47 72 6f 75 70 20  e{.      pGroup 
4dc0: 3d 20 26 70 63 61 63 68 65 31 2e 67 72 70 3b 0a  = &pcache1.grp;.
4dd0: 20 20 20 20 7d 0a 20 20 20 20 70 43 61 63 68 65      }.    pCache
4de0: 2d 3e 70 47 72 6f 75 70 20 3d 20 70 47 72 6f 75  ->pGroup = pGrou
4df0: 70 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 73  p;.    pCache->s
4e00: 7a 50 61 67 65 20 3d 20 73 7a 50 61 67 65 3b 0a  zPage = szPage;.
4e10: 20 20 20 20 70 43 61 63 68 65 2d 3e 73 7a 45 78      pCache->szEx
4e20: 74 72 61 20 3d 20 73 7a 45 78 74 72 61 3b 0a 20  tra = szExtra;. 
4e30: 20 20 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67     pCache->bPurg
4e40: 65 61 62 6c 65 20 3d 20 28 62 50 75 72 67 65 61  eable = (bPurgea
4e50: 62 6c 65 20 3f 20 31 20 3a 20 30 29 3b 0a 20 20  ble ? 1 : 0);.  
4e60: 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75    pcache1EnterMu
4e70: 74 65 78 28 70 47 72 6f 75 70 29 3b 0a 20 20 20  tex(pGroup);.   
4e80: 20 70 63 61 63 68 65 31 52 65 73 69 7a 65 48 61   pcache1ResizeHa
4e90: 73 68 28 70 43 61 63 68 65 29 3b 0a 20 20 20 20  sh(pCache);.    
4ea0: 69 66 28 20 62 50 75 72 67 65 61 62 6c 65 20 29  if( bPurgeable )
4eb0: 7b 0a 20 20 20 20 20 20 70 43 61 63 68 65 2d 3e  {.      pCache->
4ec0: 6e 4d 69 6e 20 3d 20 31 30 3b 0a 20 20 20 20 20  nMin = 10;.     
4ed0: 20 70 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67   pGroup->nMinPag
4ee0: 65 20 2b 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 69  e += pCache->nMi
4ef0: 6e 3b 0a 20 20 20 20 20 20 70 47 72 6f 75 70 2d  n;.      pGroup-
4f00: 3e 6d 78 50 69 6e 6e 65 64 20 3d 20 70 47 72 6f  >mxPinned = pGro
4f10: 75 70 2d 3e 6e 4d 61 78 50 61 67 65 20 2b 20 31  up->nMaxPage + 1
4f20: 30 20 2d 20 70 47 72 6f 75 70 2d 3e 6e 4d 69 6e  0 - pGroup->nMin
4f30: 50 61 67 65 3b 0a 20 20 20 20 7d 0a 20 20 20 20  Page;.    }.    
4f40: 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65  pcache1LeaveMute
4f50: 78 28 70 47 72 6f 75 70 29 3b 0a 20 20 20 20 69  x(pGroup);.    i
4f60: 66 28 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68  f( pCache->nHash
4f70: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 70 63 61  ==0 ){.      pca
4f80: 63 68 65 31 44 65 73 74 72 6f 79 28 28 73 71 6c  che1Destroy((sql
4f90: 69 74 65 33 5f 70 63 61 63 68 65 2a 29 70 43 61  ite3_pcache*)pCa
4fa0: 63 68 65 29 3b 0a 20 20 20 20 20 20 70 43 61 63  che);.      pCac
4fb0: 68 65 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20  he = 0;.    }.  
4fc0: 7d 0a 20 20 72 65 74 75 72 6e 20 28 73 71 6c 69  }.  return (sqli
4fd0: 74 65 33 5f 70 63 61 63 68 65 20 2a 29 70 43 61  te3_pcache *)pCa
4fe0: 63 68 65 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d  che;.}../*.** Im
4ff0: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20  plementation of 
5000: 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63  the sqlite3_pcac
5010: 68 65 2e 78 43 61 63 68 65 73 69 7a 65 20 6d 65  he.xCachesize me
5020: 74 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20 43 6f 6e  thod. .**.** Con
5030: 66 69 67 75 72 65 20 74 68 65 20 63 61 63 68 65  figure the cache
5040: 5f 73 69 7a 65 20 6c 69 6d 69 74 20 66 6f 72 20  _size limit for 
5050: 61 20 63 61 63 68 65 2e 0a 2a 2f 0a 73 74 61 74  a cache..*/.stat
5060: 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 31 43  ic void pcache1C
5070: 61 63 68 65 73 69 7a 65 28 73 71 6c 69 74 65 33  achesize(sqlite3
5080: 5f 70 63 61 63 68 65 20 2a 70 2c 20 69 6e 74 20  _pcache *p, int 
5090: 6e 4d 61 78 29 7b 0a 20 20 50 43 61 63 68 65 31  nMax){.  PCache1
50a0: 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61 63   *pCache = (PCac
50b0: 68 65 31 20 2a 29 70 3b 0a 20 20 69 66 28 20 70  he1 *)p;.  if( p
50c0: 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c  Cache->bPurgeabl
50d0: 65 20 29 7b 0a 20 20 20 20 50 47 72 6f 75 70 20  e ){.    PGroup 
50e0: 2a 70 47 72 6f 75 70 20 3d 20 70 43 61 63 68 65  *pGroup = pCache
50f0: 2d 3e 70 47 72 6f 75 70 3b 0a 20 20 20 20 70 63  ->pGroup;.    pc
5100: 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28  ache1EnterMutex(
5110: 70 47 72 6f 75 70 29 3b 0a 20 20 20 20 70 47 72  pGroup);.    pGr
5120: 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65 20 2b 3d  oup->nMaxPage +=
5130: 20 28 6e 4d 61 78 20 2d 20 70 43 61 63 68 65 2d   (nMax - pCache-
5140: 3e 6e 4d 61 78 29 3b 0a 20 20 20 20 70 47 72 6f  >nMax);.    pGro
5150: 75 70 2d 3e 6d 78 50 69 6e 6e 65 64 20 3d 20 70  up->mxPinned = p
5160: 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65 20  Group->nMaxPage 
5170: 2b 20 31 30 20 2d 20 70 47 72 6f 75 70 2d 3e 6e  + 10 - pGroup->n
5180: 4d 69 6e 50 61 67 65 3b 0a 20 20 20 20 70 43 61  MinPage;.    pCa
5190: 63 68 65 2d 3e 6e 4d 61 78 20 3d 20 6e 4d 61 78  che->nMax = nMax
51a0: 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 6e 39  ;.    pCache->n9
51b0: 30 70 63 74 20 3d 20 70 43 61 63 68 65 2d 3e 6e  0pct = pCache->n
51c0: 4d 61 78 2a 39 2f 31 30 3b 0a 20 20 20 20 70 63  Max*9/10;.    pc
51d0: 61 63 68 65 31 45 6e 66 6f 72 63 65 4d 61 78 50  ache1EnforceMaxP
51e0: 61 67 65 28 70 47 72 6f 75 70 29 3b 0a 20 20 20  age(pGroup);.   
51f0: 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74   pcache1LeaveMut
5200: 65 78 28 70 47 72 6f 75 70 29 3b 0a 20 20 7d 0a  ex(pGroup);.  }.
5210: 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65  }../*.** Impleme
5220: 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73  ntation of the s
5230: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78 53  qlite3_pcache.xS
5240: 68 72 69 6e 6b 20 6d 65 74 68 6f 64 2e 20 0a 2a  hrink method. .*
5250: 2a 0a 2a 2a 20 46 72 65 65 20 75 70 20 61 73 20  *.** Free up as 
5260: 6d 75 63 68 20 6d 65 6d 6f 72 79 20 61 73 20 70  much memory as p
5270: 6f 73 73 69 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74  ossible..*/.stat
5280: 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 31 53  ic void pcache1S
5290: 68 72 69 6e 6b 28 73 71 6c 69 74 65 33 5f 70 63  hrink(sqlite3_pc
52a0: 61 63 68 65 20 2a 70 29 7b 0a 20 20 50 43 61 63  ache *p){.  PCac
52b0: 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28 50  he1 *pCache = (P
52c0: 43 61 63 68 65 31 2a 29 70 3b 0a 20 20 69 66 28  Cache1*)p;.  if(
52d0: 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61   pCache->bPurgea
52e0: 62 6c 65 20 29 7b 0a 20 20 20 20 50 47 72 6f 75  ble ){.    PGrou
52f0: 70 20 2a 70 47 72 6f 75 70 20 3d 20 70 43 61 63  p *pGroup = pCac
5300: 68 65 2d 3e 70 47 72 6f 75 70 3b 0a 20 20 20 20  he->pGroup;.    
5310: 69 6e 74 20 73 61 76 65 64 4d 61 78 50 61 67 65  int savedMaxPage
5320: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 45 6e 74  ;.    pcache1Ent
5330: 65 72 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b  erMutex(pGroup);
5340: 0a 20 20 20 20 73 61 76 65 64 4d 61 78 50 61 67  .    savedMaxPag
5350: 65 20 3d 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78  e = pGroup->nMax
5360: 50 61 67 65 3b 0a 20 20 20 20 70 47 72 6f 75 70  Page;.    pGroup
5370: 2d 3e 6e 4d 61 78 50 61 67 65 20 3d 20 30 3b 0a  ->nMaxPage = 0;.
5380: 20 20 20 20 70 63 61 63 68 65 31 45 6e 66 6f 72      pcache1Enfor
5390: 63 65 4d 61 78 50 61 67 65 28 70 47 72 6f 75 70  ceMaxPage(pGroup
53a0: 29 3b 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e 6e  );.    pGroup->n
53b0: 4d 61 78 50 61 67 65 20 3d 20 73 61 76 65 64 4d  MaxPage = savedM
53c0: 61 78 50 61 67 65 3b 0a 20 20 20 20 70 63 61 63  axPage;.    pcac
53d0: 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 70 47  he1LeaveMutex(pG
53e0: 72 6f 75 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a  roup);.  }.}../*
53f0: 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69  .** Implementati
5400: 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65  on of the sqlite
5410: 33 5f 70 63 61 63 68 65 2e 78 50 61 67 65 63 6f  3_pcache.xPageco
5420: 75 6e 74 20 6d 65 74 68 6f 64 2e 20 0a 2a 2f 0a  unt method. .*/.
5430: 73 74 61 74 69 63 20 69 6e 74 20 70 63 61 63 68  static int pcach
5440: 65 31 50 61 67 65 63 6f 75 6e 74 28 73 71 6c 69  e1Pagecount(sqli
5450: 74 65 33 5f 70 63 61 63 68 65 20 2a 70 29 7b 0a  te3_pcache *p){.
5460: 20 20 69 6e 74 20 6e 3b 0a 20 20 50 43 61 63 68    int n;.  PCach
5470: 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43  e1 *pCache = (PC
5480: 61 63 68 65 31 2a 29 70 3b 0a 20 20 70 63 61 63  ache1*)p;.  pcac
5490: 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70 43  he1EnterMutex(pC
54a0: 61 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 20  ache->pGroup);. 
54b0: 20 6e 20 3d 20 70 43 61 63 68 65 2d 3e 6e 50 61   n = pCache->nPa
54c0: 67 65 3b 0a 20 20 70 63 61 63 68 65 31 4c 65 61  ge;.  pcache1Lea
54d0: 76 65 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e  veMutex(pCache->
54e0: 70 47 72 6f 75 70 29 3b 0a 20 20 72 65 74 75 72  pGroup);.  retur
54f0: 6e 20 6e 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 49  n n;.}.../*.** I
5500: 6d 70 6c 65 6d 65 6e 74 20 73 74 65 70 73 20 33  mplement steps 3
5510: 2c 20 34 2c 20 61 6e 64 20 35 20 6f 66 20 74 68  , 4, and 5 of th
5520: 65 20 70 63 61 63 68 65 31 46 65 74 63 68 28 29  e pcache1Fetch()
5530: 20 61 6c 67 6f 72 69 74 68 6d 20 64 65 73 63 72   algorithm descr
5540: 69 62 65 64 0a 2a 2a 20 69 6e 20 74 68 65 20 68  ibed.** in the h
5550: 65 61 64 65 72 20 6f 66 20 74 68 65 20 70 63 61  eader of the pca
5560: 63 68 65 31 46 65 74 63 68 28 29 20 70 72 6f 63  che1Fetch() proc
5570: 65 64 75 72 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 69  edure..**.** Thi
5580: 73 20 73 74 65 70 73 20 61 72 65 20 62 72 6f 6b  s steps are brok
5590: 65 6e 20 6f 75 74 20 69 6e 74 6f 20 61 20 73 65  en out into a se
55a0: 70 61 72 61 74 65 20 70 72 6f 63 65 64 75 72 65  parate procedure
55b0: 20 62 65 63 61 75 73 65 20 74 68 65 79 20 61 72   because they ar
55c0: 65 0a 2a 2a 20 75 73 75 61 6c 6c 79 20 6e 6f 74  e.** usually not
55d0: 20 6e 65 65 64 65 64 2c 20 61 6e 64 20 62 79 20   needed, and by 
55e0: 61 76 6f 69 64 69 6e 67 20 74 68 65 20 73 74 61  avoiding the sta
55f0: 63 6b 20 69 6e 69 74 69 61 6c 69 7a 61 74 69 6f  ck initializatio
5600: 6e 20 72 65 71 75 69 72 65 64 0a 2a 2a 20 66 6f  n required.** fo
5610: 72 20 74 68 65 73 65 20 73 74 65 70 73 2c 20 74  r these steps, t
5620: 68 65 20 6d 61 69 6e 20 70 63 61 63 68 65 31 46  he main pcache1F
5630: 65 74 63 68 28 29 20 70 72 6f 63 65 64 75 72 65  etch() procedure
5640: 20 63 61 6e 20 72 75 6e 20 66 61 73 74 65 72 2e   can run faster.
5650: 0a 2a 2f 0a 73 74 61 74 69 63 20 53 51 4c 49 54  .*/.static SQLIT
5660: 45 5f 4e 4f 49 4e 4c 49 4e 45 20 50 67 48 64 72  E_NOINLINE PgHdr
5670: 31 20 2a 70 63 61 63 68 65 31 46 65 74 63 68 53  1 *pcache1FetchS
5680: 74 61 67 65 32 28 0a 20 20 50 43 61 63 68 65 31  tage2(.  PCache1
5690: 20 2a 70 43 61 63 68 65 2c 20 0a 20 20 75 6e 73   *pCache, .  uns
56a0: 69 67 6e 65 64 20 69 6e 74 20 69 4b 65 79 2c 20  igned int iKey, 
56b0: 0a 20 20 69 6e 74 20 63 72 65 61 74 65 46 6c 61  .  int createFla
56c0: 67 0a 29 7b 0a 20 20 75 6e 73 69 67 6e 65 64 20  g.){.  unsigned 
56d0: 69 6e 74 20 6e 50 69 6e 6e 65 64 3b 0a 20 20 50  int nPinned;.  P
56e0: 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 20 3d 20  Group *pGroup = 
56f0: 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b 0a  pCache->pGroup;.
5700: 20 20 50 67 48 64 72 31 20 2a 70 50 61 67 65 20    PgHdr1 *pPage 
5710: 3d 20 30 3b 0a 0a 20 20 2f 2a 20 53 74 65 70 20  = 0;..  /* Step 
5720: 33 3a 20 41 62 6f 72 74 20 69 66 20 63 72 65 61  3: Abort if crea
5730: 74 65 46 6c 61 67 20 69 73 20 31 20 62 75 74 20  teFlag is 1 but 
5740: 74 68 65 20 63 61 63 68 65 20 69 73 20 6e 65 61  the cache is nea
5750: 72 6c 79 20 66 75 6c 6c 20 2a 2f 0a 20 20 61 73  rly full */.  as
5760: 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e 6e 50  sert( pCache->nP
5770: 61 67 65 20 3e 3d 20 70 43 61 63 68 65 2d 3e 6e  age >= pCache->n
5780: 52 65 63 79 63 6c 61 62 6c 65 20 29 3b 0a 20 20  Recyclable );.  
5790: 6e 50 69 6e 6e 65 64 20 3d 20 70 43 61 63 68 65  nPinned = pCache
57a0: 2d 3e 6e 50 61 67 65 20 2d 20 70 43 61 63 68 65  ->nPage - pCache
57b0: 2d 3e 6e 52 65 63 79 63 6c 61 62 6c 65 3b 0a 20  ->nRecyclable;. 
57c0: 20 61 73 73 65 72 74 28 20 70 47 72 6f 75 70 2d   assert( pGroup-
57d0: 3e 6d 78 50 69 6e 6e 65 64 20 3d 3d 20 70 47 72  >mxPinned == pGr
57e0: 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65 20 2b 20  oup->nMaxPage + 
57f0: 31 30 20 2d 20 70 47 72 6f 75 70 2d 3e 6e 4d 69  10 - pGroup->nMi
5800: 6e 50 61 67 65 20 29 3b 0a 20 20 61 73 73 65 72  nPage );.  asser
5810: 74 28 20 70 43 61 63 68 65 2d 3e 6e 39 30 70 63  t( pCache->n90pc
5820: 74 20 3d 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 61  t == pCache->nMa
5830: 78 2a 39 2f 31 30 20 29 3b 0a 20 20 69 66 28 20  x*9/10 );.  if( 
5840: 63 72 65 61 74 65 46 6c 61 67 3d 3d 31 20 26 26  createFlag==1 &&
5850: 20 28 0a 20 20 20 20 20 20 20 20 6e 50 69 6e 6e   (.        nPinn
5860: 65 64 3e 3d 70 47 72 6f 75 70 2d 3e 6d 78 50 69  ed>=pGroup->mxPi
5870: 6e 6e 65 64 0a 20 20 20 20 20 7c 7c 20 6e 50 69  nned.     || nPi
5880: 6e 6e 65 64 3e 3d 70 43 61 63 68 65 2d 3e 6e 39  nned>=pCache->n9
5890: 30 70 63 74 0a 20 20 20 20 20 7c 7c 20 70 63 61  0pct.     || pca
58a0: 63 68 65 31 55 6e 64 65 72 4d 65 6d 6f 72 79 50  che1UnderMemoryP
58b0: 72 65 73 73 75 72 65 28 70 43 61 63 68 65 29 0a  ressure(pCache).
58c0: 20 20 29 29 7b 0a 20 20 20 20 72 65 74 75 72 6e    )){.    return
58d0: 20 30 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70   0;.  }..  if( p
58e0: 43 61 63 68 65 2d 3e 6e 50 61 67 65 3e 3d 70 43  Cache->nPage>=pC
58f0: 61 63 68 65 2d 3e 6e 48 61 73 68 20 29 20 70 63  ache->nHash ) pc
5900: 61 63 68 65 31 52 65 73 69 7a 65 48 61 73 68 28  ache1ResizeHash(
5910: 70 43 61 63 68 65 29 3b 0a 20 20 61 73 73 65 72  pCache);.  asser
5920: 74 28 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68  t( pCache->nHash
5930: 3e 30 20 26 26 20 70 43 61 63 68 65 2d 3e 61 70  >0 && pCache->ap
5940: 48 61 73 68 20 29 3b 0a 0a 20 20 2f 2a 20 53 74  Hash );..  /* St
5950: 65 70 20 34 2e 20 54 72 79 20 74 6f 20 72 65 63  ep 4. Try to rec
5960: 79 63 6c 65 20 61 20 70 61 67 65 2e 20 2a 2f 0a  ycle a page. */.
5970: 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 62 50    if( pCache->bP
5980: 75 72 67 65 61 62 6c 65 20 26 26 20 70 47 72 6f  urgeable && pGro
5990: 75 70 2d 3e 70 4c 72 75 54 61 69 6c 20 26 26 20  up->pLruTail && 
59a0: 28 0a 20 20 20 20 20 20 20 20 20 28 70 43 61 63  (.         (pCac
59b0: 68 65 2d 3e 6e 50 61 67 65 2b 31 3e 3d 70 43 61  he->nPage+1>=pCa
59c0: 63 68 65 2d 3e 6e 4d 61 78 29 0a 20 20 20 20 20  che->nMax).     
59d0: 20 7c 7c 20 70 47 72 6f 75 70 2d 3e 6e 43 75 72   || pGroup->nCur
59e0: 72 65 6e 74 50 61 67 65 3e 3d 70 47 72 6f 75 70  rentPage>=pGroup
59f0: 2d 3e 6e 4d 61 78 50 61 67 65 0a 20 20 20 20 20  ->nMaxPage.     
5a00: 20 7c 7c 20 70 63 61 63 68 65 31 55 6e 64 65 72   || pcache1Under
5a10: 4d 65 6d 6f 72 79 50 72 65 73 73 75 72 65 28 70  MemoryPressure(p
5a20: 43 61 63 68 65 29 0a 20 20 29 29 7b 0a 20 20 20  Cache).  )){.   
5a30: 20 50 43 61 63 68 65 31 20 2a 70 4f 74 68 65 72   PCache1 *pOther
5a40: 3b 0a 20 20 20 20 70 50 61 67 65 20 3d 20 70 47  ;.    pPage = pG
5a50: 72 6f 75 70 2d 3e 70 4c 72 75 54 61 69 6c 3b 0a  roup->pLruTail;.
5a60: 20 20 20 20 61 73 73 65 72 74 28 20 70 50 61 67      assert( pPag
5a70: 65 2d 3e 69 73 50 69 6e 6e 65 64 3d 3d 30 20 29  e->isPinned==0 )
5a80: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 52 65 6d  ;.    pcache1Rem
5a90: 6f 76 65 46 72 6f 6d 48 61 73 68 28 70 50 61 67  oveFromHash(pPag
5aa0: 65 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31 50  e);.    pcache1P
5ab0: 69 6e 50 61 67 65 28 70 50 61 67 65 29 3b 0a 20  inPage(pPage);. 
5ac0: 20 20 20 70 4f 74 68 65 72 20 3d 20 70 50 61 67     pOther = pPag
5ad0: 65 2d 3e 70 43 61 63 68 65 3b 0a 0a 20 20 20 20  e->pCache;..    
5ae0: 2f 2a 20 57 65 20 77 61 6e 74 20 74 6f 20 76 65  /* We want to ve
5af0: 72 69 66 79 20 74 68 61 74 20 73 7a 50 61 67 65  rify that szPage
5b00: 20 61 6e 64 20 73 7a 45 78 74 72 61 20 61 72 65   and szExtra are
5b10: 20 74 68 65 20 73 61 6d 65 20 66 6f 72 20 70 4f   the same for pO
5b20: 74 68 65 72 0a 20 20 20 20 2a 2a 20 61 6e 64 20  ther.    ** and 
5b30: 70 43 61 63 68 65 2e 20 20 41 73 73 65 72 74 20  pCache.  Assert 
5b40: 74 68 61 74 20 77 65 20 63 61 6e 20 76 65 72 69  that we can veri
5b50: 66 79 20 74 68 69 73 20 62 79 20 63 6f 6d 70 61  fy this by compa
5b60: 72 69 6e 67 20 73 75 6d 73 2e 20 2a 2f 0a 20 20  ring sums. */.  
5b70: 20 20 61 73 73 65 72 74 28 20 28 70 43 61 63 68    assert( (pCach
5b80: 65 2d 3e 73 7a 50 61 67 65 20 26 20 28 70 43 61  e->szPage & (pCa
5b90: 63 68 65 2d 3e 73 7a 50 61 67 65 2d 31 29 29 3d  che->szPage-1))=
5ba0: 3d 30 20 26 26 20 70 43 61 63 68 65 2d 3e 73 7a  =0 && pCache->sz
5bb0: 50 61 67 65 3e 3d 35 31 32 20 29 3b 0a 20 20 20  Page>=512 );.   
5bc0: 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65 2d   assert( pCache-
5bd0: 3e 73 7a 45 78 74 72 61 3c 35 31 32 20 29 3b 0a  >szExtra<512 );.
5be0: 20 20 20 20 61 73 73 65 72 74 28 20 28 70 4f 74      assert( (pOt
5bf0: 68 65 72 2d 3e 73 7a 50 61 67 65 20 26 20 28 70  her->szPage & (p
5c00: 4f 74 68 65 72 2d 3e 73 7a 50 61 67 65 2d 31 29  Other->szPage-1)
5c10: 29 3d 3d 30 20 26 26 20 70 4f 74 68 65 72 2d 3e  )==0 && pOther->
5c20: 73 7a 50 61 67 65 3e 3d 35 31 32 20 29 3b 0a 20  szPage>=512 );. 
5c30: 20 20 20 61 73 73 65 72 74 28 20 70 4f 74 68 65     assert( pOthe
5c40: 72 2d 3e 73 7a 45 78 74 72 61 3c 35 31 32 20 29  r->szExtra<512 )
5c50: 3b 0a 0a 20 20 20 20 69 66 28 20 70 4f 74 68 65  ;..    if( pOthe
5c60: 72 2d 3e 73 7a 50 61 67 65 2b 70 4f 74 68 65 72  r->szPage+pOther
5c70: 2d 3e 73 7a 45 78 74 72 61 20 21 3d 20 70 43 61  ->szExtra != pCa
5c80: 63 68 65 2d 3e 73 7a 50 61 67 65 2b 70 43 61 63  che->szPage+pCac
5c90: 68 65 2d 3e 73 7a 45 78 74 72 61 20 29 7b 0a 20  he->szExtra ){. 
5ca0: 20 20 20 20 20 70 63 61 63 68 65 31 46 72 65 65       pcache1Free
5cb0: 50 61 67 65 28 70 50 61 67 65 29 3b 0a 20 20 20  Page(pPage);.   
5cc0: 20 20 20 70 50 61 67 65 20 3d 20 30 3b 0a 20 20     pPage = 0;.  
5cd0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70    }else{.      p
5ce0: 47 72 6f 75 70 2d 3e 6e 43 75 72 72 65 6e 74 50  Group->nCurrentP
5cf0: 61 67 65 20 2d 3d 20 28 70 4f 74 68 65 72 2d 3e  age -= (pOther->
5d00: 62 50 75 72 67 65 61 62 6c 65 20 2d 20 70 43 61  bPurgeable - pCa
5d10: 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 29  che->bPurgeable)
5d20: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f  ;.    }.  }..  /
5d30: 2a 20 53 74 65 70 20 35 2e 20 49 66 20 61 20 75  * Step 5. If a u
5d40: 73 61 62 6c 65 20 70 61 67 65 20 62 75 66 66 65  sable page buffe
5d50: 72 20 68 61 73 20 73 74 69 6c 6c 20 6e 6f 74 20  r has still not 
5d60: 62 65 65 6e 20 66 6f 75 6e 64 2c 20 0a 20 20 2a  been found, .  *
5d70: 2a 20 61 74 74 65 6d 70 74 20 74 6f 20 61 6c 6c  * attempt to all
5d80: 6f 63 61 74 65 20 61 20 6e 65 77 20 6f 6e 65 2e  ocate a new one.
5d90: 20 0a 20 20 2a 2f 0a 20 20 69 66 28 20 21 70 50   .  */.  if( !pP
5da0: 61 67 65 20 29 7b 0a 20 20 20 20 69 66 28 20 63  age ){.    if( c
5db0: 72 65 61 74 65 46 6c 61 67 3d 3d 31 20 29 20 73  reateFlag==1 ) s
5dc0: 71 6c 69 74 65 33 42 65 67 69 6e 42 65 6e 69 67  qlite3BeginBenig
5dd0: 6e 4d 61 6c 6c 6f 63 28 29 3b 0a 20 20 20 20 70  nMalloc();.    p
5de0: 50 61 67 65 20 3d 20 70 63 61 63 68 65 31 41 6c  Page = pcache1Al
5df0: 6c 6f 63 50 61 67 65 28 70 43 61 63 68 65 29 3b  locPage(pCache);
5e00: 0a 20 20 20 20 69 66 28 20 63 72 65 61 74 65 46  .    if( createF
5e10: 6c 61 67 3d 3d 31 20 29 20 73 71 6c 69 74 65 33  lag==1 ) sqlite3
5e20: 45 6e 64 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28  EndBenignMalloc(
5e30: 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 50  );.  }..  if( pP
5e40: 61 67 65 20 29 7b 0a 20 20 20 20 75 6e 73 69 67  age ){.    unsig
5e50: 6e 65 64 20 69 6e 74 20 68 20 3d 20 69 4b 65 79  ned int h = iKey
5e60: 20 25 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68   % pCache->nHash
5e70: 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 6e 50  ;.    pCache->nP
5e80: 61 67 65 2b 2b 3b 0a 20 20 20 20 70 50 61 67 65  age++;.    pPage
5e90: 2d 3e 69 4b 65 79 20 3d 20 69 4b 65 79 3b 0a 20  ->iKey = iKey;. 
5ea0: 20 20 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 20     pPage->pNext 
5eb0: 3d 20 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68  = pCache->apHash
5ec0: 5b 68 5d 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e  [h];.    pPage->
5ed0: 70 43 61 63 68 65 20 3d 20 70 43 61 63 68 65 3b  pCache = pCache;
5ee0: 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 4c 72 75  .    pPage->pLru
5ef0: 50 72 65 76 20 3d 20 30 3b 0a 20 20 20 20 70 50  Prev = 0;.    pP
5f00: 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 20 3d 20  age->pLruNext = 
5f10: 30 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 69 73  0;.    pPage->is
5f20: 50 69 6e 6e 65 64 20 3d 20 31 3b 0a 20 20 20 20  Pinned = 1;.    
5f30: 2a 28 76 6f 69 64 20 2a 2a 29 70 50 61 67 65 2d  *(void **)pPage-
5f40: 3e 70 61 67 65 2e 70 45 78 74 72 61 20 3d 20 30  >page.pExtra = 0
5f50: 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 61 70  ;.    pCache->ap
5f60: 48 61 73 68 5b 68 5d 20 3d 20 70 50 61 67 65 3b  Hash[h] = pPage;
5f70: 0a 20 20 20 20 69 66 28 20 69 4b 65 79 3e 70 43  .    if( iKey>pC
5f80: 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 29 7b  ache->iMaxKey ){
5f90: 0a 20 20 20 20 20 20 70 43 61 63 68 65 2d 3e 69  .      pCache->i
5fa0: 4d 61 78 4b 65 79 20 3d 20 69 4b 65 79 3b 0a 20  MaxKey = iKey;. 
5fb0: 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72     }.  }.  retur
5fc0: 6e 20 70 50 61 67 65 3b 0a 7d 0a 0a 2f 2a 0a 2a  n pPage;.}../*.*
5fd0: 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  * Implementation
5fe0: 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f   of the sqlite3_
5ff0: 70 63 61 63 68 65 2e 78 46 65 74 63 68 20 6d 65  pcache.xFetch me
6000: 74 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20 46 65 74  thod. .**.** Fet
6010: 63 68 20 61 20 70 61 67 65 20 62 79 20 6b 65 79  ch a page by key
6020: 20 76 61 6c 75 65 2e 0a 2a 2a 0a 2a 2a 20 57 68   value..**.** Wh
6030: 65 74 68 65 72 20 6f 72 20 6e 6f 74 20 61 20 6e  ether or not a n
6040: 65 77 20 70 61 67 65 20 6d 61 79 20 62 65 20 61  ew page may be a
6050: 6c 6c 6f 63 61 74 65 64 20 62 79 20 74 68 69 73  llocated by this
6060: 20 66 75 6e 63 74 69 6f 6e 20 64 65 70 65 6e 64   function depend
6070: 73 20 6f 6e 0a 2a 2a 20 74 68 65 20 76 61 6c 75  s on.** the valu
6080: 65 20 6f 66 20 74 68 65 20 63 72 65 61 74 65 46  e of the createF
6090: 6c 61 67 20 61 72 67 75 6d 65 6e 74 2e 20 20 30  lag argument.  0
60a0: 20 6d 65 61 6e 73 20 64 6f 20 6e 6f 74 20 61 6c   means do not al
60b0: 6c 6f 63 61 74 65 20 61 20 6e 65 77 0a 2a 2a 20  locate a new.** 
60c0: 70 61 67 65 2e 20 20 31 20 6d 65 61 6e 73 20 61  page.  1 means a
60d0: 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 70 61  llocate a new pa
60e0: 67 65 20 69 66 20 73 70 61 63 65 20 69 73 20 65  ge if space is e
60f0: 61 73 69 6c 79 20 61 76 61 69 6c 61 62 6c 65 2e  asily available.
6100: 20 20 32 20 0a 2a 2a 20 6d 65 61 6e 73 20 74 6f    2 .** means to
6110: 20 74 72 79 20 72 65 61 6c 6c 79 20 68 61 72 64   try really hard
6120: 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e   to allocate a n
6130: 65 77 20 70 61 67 65 2e 0a 2a 2a 0a 2a 2a 20 46  ew page..**.** F
6140: 6f 72 20 61 20 6e 6f 6e 2d 70 75 72 67 65 61 62  or a non-purgeab
6150: 6c 65 20 63 61 63 68 65 20 28 61 20 63 61 63 68  le cache (a cach
6160: 65 20 75 73 65 64 20 61 73 20 74 68 65 20 73 74  e used as the st
6170: 6f 72 61 67 65 20 66 6f 72 20 61 6e 20 69 6e 2d  orage for an in-
6180: 6d 65 6d 6f 72 79 0a 2a 2a 20 64 61 74 61 62 61  memory.** databa
6190: 73 65 29 20 74 68 65 72 65 20 69 73 20 72 65 61  se) there is rea
61a0: 6c 6c 79 20 6e 6f 20 64 69 66 66 65 72 65 6e 63  lly no differenc
61b0: 65 20 62 65 74 77 65 65 6e 20 63 72 65 61 74 65  e between create
61c0: 46 6c 61 67 20 31 20 61 6e 64 20 32 2e 20 20 53  Flag 1 and 2.  S
61d0: 6f 0a 2a 2a 20 74 68 65 20 63 61 6c 6c 69 6e 67  o.** the calling
61e0: 20 66 75 6e 63 74 69 6f 6e 20 28 70 63 61 63 68   function (pcach
61f0: 65 2e 63 29 20 77 69 6c 6c 20 6e 65 76 65 72 20  e.c) will never 
6200: 68 61 76 65 20 61 20 63 72 65 61 74 65 46 6c 61  have a createFla
6210: 67 20 6f 66 20 31 20 6f 6e 0a 2a 2a 20 61 20 6e  g of 1 on.** a n
6220: 6f 6e 2d 70 75 72 67 65 61 62 6c 65 20 63 61 63  on-purgeable cac
6230: 68 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 72 65 20  he..**.** There 
6240: 61 72 65 20 74 68 72 65 65 20 64 69 66 66 65 72  are three differ
6250: 65 6e 74 20 61 70 70 72 6f 61 63 68 65 73 20 74  ent approaches t
6260: 6f 20 6f 62 74 61 69 6e 69 6e 67 20 73 70 61 63  o obtaining spac
6270: 65 20 66 6f 72 20 61 20 70 61 67 65 2c 0a 2a 2a  e for a page,.**
6280: 20 64 65 70 65 6e 64 69 6e 67 20 6f 6e 20 74 68   depending on th
6290: 65 20 76 61 6c 75 65 20 6f 66 20 70 61 72 61 6d  e value of param
62a0: 65 74 65 72 20 63 72 65 61 74 65 46 6c 61 67 20  eter createFlag 
62b0: 28 77 68 69 63 68 20 6d 61 79 20 62 65 20 30 2c  (which may be 0,
62c0: 20 31 20 6f 72 20 32 29 2e 0a 2a 2a 0a 2a 2a 20   1 or 2)..**.** 
62d0: 20 20 31 2e 20 52 65 67 61 72 64 6c 65 73 73 20    1. Regardless 
62e0: 6f 66 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20  of the value of 
62f0: 63 72 65 61 74 65 46 6c 61 67 2c 20 74 68 65 20  createFlag, the 
6300: 63 61 63 68 65 20 69 73 20 73 65 61 72 63 68 65  cache is searche
6310: 64 20 66 6f 72 20 61 20 0a 2a 2a 20 20 20 20 20  d for a .**     
6320: 20 63 6f 70 79 20 6f 66 20 74 68 65 20 72 65 71   copy of the req
6330: 75 65 73 74 65 64 20 70 61 67 65 2e 20 49 66 20  uested page. If 
6340: 6f 6e 65 20 69 73 20 66 6f 75 6e 64 2c 20 69 74  one is found, it
6350: 20 69 73 20 72 65 74 75 72 6e 65 64 2e 0a 2a 2a   is returned..**
6360: 0a 2a 2a 20 20 20 32 2e 20 49 66 20 63 72 65 61  .**   2. If crea
6370: 74 65 46 6c 61 67 3d 3d 30 20 61 6e 64 20 74 68  teFlag==0 and th
6380: 65 20 70 61 67 65 20 69 73 20 6e 6f 74 20 61 6c  e page is not al
6390: 72 65 61 64 79 20 69 6e 20 74 68 65 20 63 61 63  ready in the cac
63a0: 68 65 2c 20 4e 55 4c 4c 20 69 73 0a 2a 2a 20 20  he, NULL is.**  
63b0: 20 20 20 20 72 65 74 75 72 6e 65 64 2e 0a 2a 2a      returned..**
63c0: 0a 2a 2a 20 20 20 33 2e 20 49 66 20 63 72 65 61  .**   3. If crea
63d0: 74 65 46 6c 61 67 20 69 73 20 31 2c 20 61 6e 64  teFlag is 1, and
63e0: 20 74 68 65 20 70 61 67 65 20 69 73 20 6e 6f 74   the page is not
63f0: 20 61 6c 72 65 61 64 79 20 69 6e 20 74 68 65 20   already in the 
6400: 63 61 63 68 65 2c 20 74 68 65 6e 0a 2a 2a 20 20  cache, then.**  
6410: 20 20 20 20 72 65 74 75 72 6e 20 4e 55 4c 4c 20      return NULL 
6420: 28 64 6f 20 6e 6f 74 20 61 6c 6c 6f 63 61 74 65  (do not allocate
6430: 20 61 20 6e 65 77 20 70 61 67 65 29 20 69 66 20   a new page) if 
6440: 61 6e 79 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f  any of the follo
6450: 77 69 6e 67 0a 2a 2a 20 20 20 20 20 20 63 6f 6e  wing.**      con
6460: 64 69 74 69 6f 6e 73 20 61 72 65 20 74 72 75 65  ditions are true
6470: 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 28 61  :.**.**       (a
6480: 29 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  ) the number of 
6490: 70 61 67 65 73 20 70 69 6e 6e 65 64 20 62 79 20  pages pinned by 
64a0: 74 68 65 20 63 61 63 68 65 20 69 73 20 67 72 65  the cache is gre
64b0: 61 74 65 72 20 74 68 61 6e 0a 2a 2a 20 20 20 20  ater than.**    
64c0: 20 20 20 20 20 20 20 50 43 61 63 68 65 31 2e 6e         PCache1.n
64d0: 4d 61 78 2c 20 6f 72 0a 2a 2a 0a 2a 2a 20 20 20  Max, or.**.**   
64e0: 20 20 20 20 28 62 29 20 74 68 65 20 6e 75 6d 62      (b) the numb
64f0: 65 72 20 6f 66 20 70 61 67 65 73 20 70 69 6e 6e  er of pages pinn
6500: 65 64 20 62 79 20 74 68 65 20 63 61 63 68 65 20  ed by the cache 
6510: 69 73 20 67 72 65 61 74 65 72 20 74 68 61 6e 0a  is greater than.
6520: 2a 2a 20 20 20 20 20 20 20 20 20 20 20 74 68 65  **           the
6530: 20 73 75 6d 20 6f 66 20 6e 4d 61 78 20 66 6f 72   sum of nMax for
6540: 20 61 6c 6c 20 70 75 72 67 65 61 62 6c 65 20 63   all purgeable c
6550: 61 63 68 65 73 2c 20 6c 65 73 73 20 74 68 65 20  aches, less the 
6560: 73 75 6d 20 6f 66 20 0a 2a 2a 20 20 20 20 20 20  sum of .**      
6570: 20 20 20 20 20 6e 4d 69 6e 20 66 6f 72 20 61 6c       nMin for al
6580: 6c 20 6f 74 68 65 72 20 70 75 72 67 65 61 62 6c  l other purgeabl
6590: 65 20 63 61 63 68 65 73 2c 20 6f 72 0a 2a 2a 0a  e caches, or.**.
65a0: 2a 2a 20 20 20 34 2e 20 49 66 20 6e 6f 6e 65 20  **   4. If none 
65b0: 6f 66 20 74 68 65 20 66 69 72 73 74 20 74 68 72  of the first thr
65c0: 65 65 20 63 6f 6e 64 69 74 69 6f 6e 73 20 61 70  ee conditions ap
65d0: 70 6c 79 20 61 6e 64 20 74 68 65 20 63 61 63 68  ply and the cach
65e0: 65 20 69 73 20 6d 61 72 6b 65 64 0a 2a 2a 20 20  e is marked.**  
65f0: 20 20 20 20 61 73 20 70 75 72 67 65 61 62 6c 65      as purgeable
6600: 2c 20 61 6e 64 20 69 66 20 6f 6e 65 20 6f 66 20  , and if one of 
6610: 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 69 73  the following is
6620: 20 74 72 75 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20   true:.**.**    
6630: 20 20 20 28 61 29 20 54 68 65 20 6e 75 6d 62 65     (a) The numbe
6640: 72 20 6f 66 20 70 61 67 65 73 20 61 6c 6c 6f 63  r of pages alloc
6650: 61 74 65 64 20 66 6f 72 20 74 68 65 20 63 61 63  ated for the cac
6660: 68 65 20 69 73 20 61 6c 72 65 61 64 79 20 0a 2a  he is already .*
6670: 2a 20 20 20 20 20 20 20 20 20 20 20 50 43 61 63  *           PCac
6680: 68 65 31 2e 6e 4d 61 78 2c 20 6f 72 0a 2a 2a 0a  he1.nMax, or.**.
6690: 2a 2a 20 20 20 20 20 20 20 28 62 29 20 54 68 65  **       (b) The
66a0: 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73   number of pages
66b0: 20 61 6c 6c 6f 63 61 74 65 64 20 66 6f 72 20 61   allocated for a
66c0: 6c 6c 20 70 75 72 67 65 61 62 6c 65 20 63 61 63  ll purgeable cac
66d0: 68 65 73 20 69 73 0a 2a 2a 20 20 20 20 20 20 20  hes is.**       
66e0: 20 20 20 20 61 6c 72 65 61 64 79 20 65 71 75 61      already equa
66f0: 6c 20 74 6f 20 6f 72 20 67 72 65 61 74 65 72 20  l to or greater 
6700: 74 68 61 6e 20 74 68 65 20 73 75 6d 20 6f 66 20  than the sum of 
6710: 6e 4d 61 78 20 66 6f 72 20 61 6c 6c 0a 2a 2a 20  nMax for all.** 
6720: 20 20 20 20 20 20 20 20 20 20 70 75 72 67 65 61            purgea
6730: 62 6c 65 20 63 61 63 68 65 73 2c 0a 2a 2a 0a 2a  ble caches,.**.*
6740: 2a 20 20 20 20 20 20 20 28 63 29 20 54 68 65 20  *       (c) The 
6750: 73 79 73 74 65 6d 20 69 73 20 75 6e 64 65 72 20  system is under 
6760: 6d 65 6d 6f 72 79 20 70 72 65 73 73 75 72 65 20  memory pressure 
6770: 61 6e 64 20 77 61 6e 74 73 20 74 6f 20 61 76 6f  and wants to avo
6780: 69 64 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20  id.**           
6790: 75 6e 6e 65 63 65 73 73 61 72 79 20 70 61 67 65  unnecessary page
67a0: 73 20 63 61 63 68 65 20 65 6e 74 72 79 20 61 6c  s cache entry al
67b0: 6c 6f 63 61 74 69 6f 6e 73 0a 2a 2a 0a 2a 2a 20  locations.**.** 
67c0: 20 20 20 20 20 74 68 65 6e 20 61 74 74 65 6d 70       then attemp
67d0: 74 20 74 6f 20 72 65 63 79 63 6c 65 20 61 20 70  t to recycle a p
67e0: 61 67 65 20 66 72 6f 6d 20 74 68 65 20 4c 52 55  age from the LRU
67f0: 20 6c 69 73 74 2e 20 49 66 20 69 74 20 69 73 20   list. If it is 
6800: 74 68 65 20 72 69 67 68 74 0a 2a 2a 20 20 20 20  the right.**    
6810: 20 20 73 69 7a 65 2c 20 72 65 74 75 72 6e 20 74    size, return t
6820: 68 65 20 72 65 63 79 63 6c 65 64 20 62 75 66 66  he recycled buff
6830: 65 72 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 66  er. Otherwise, f
6840: 72 65 65 20 74 68 65 20 62 75 66 66 65 72 20 61  ree the buffer a
6850: 6e 64 0a 2a 2a 20 20 20 20 20 20 70 72 6f 63 65  nd.**      proce
6860: 65 64 20 74 6f 20 73 74 65 70 20 35 2e 20 0a 2a  ed to step 5. .*
6870: 2a 0a 2a 2a 20 20 20 35 2e 20 4f 74 68 65 72 77  *.**   5. Otherw
6880: 69 73 65 2c 20 61 6c 6c 6f 63 61 74 65 20 61 6e  ise, allocate an
6890: 64 20 72 65 74 75 72 6e 20 61 20 6e 65 77 20 70  d return a new p
68a0: 61 67 65 20 62 75 66 66 65 72 2e 0a 2a 2f 0a 73  age buffer..*/.s
68b0: 74 61 74 69 63 20 73 71 6c 69 74 65 33 5f 70 63  tatic sqlite3_pc
68c0: 61 63 68 65 5f 70 61 67 65 20 2a 70 63 61 63 68  ache_page *pcach
68d0: 65 31 46 65 74 63 68 28 0a 20 20 73 71 6c 69 74  e1Fetch(.  sqlit
68e0: 65 33 5f 70 63 61 63 68 65 20 2a 70 2c 20 0a 20  e3_pcache *p, . 
68f0: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4b   unsigned int iK
6900: 65 79 2c 20 0a 20 20 69 6e 74 20 63 72 65 61 74  ey, .  int creat
6910: 65 46 6c 61 67 0a 29 7b 0a 20 20 50 43 61 63 68  eFlag.){.  PCach
6920: 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43  e1 *pCache = (PC
6930: 61 63 68 65 31 20 2a 29 70 3b 0a 20 20 50 67 48  ache1 *)p;.  PgH
6940: 64 72 31 20 2a 70 50 61 67 65 20 3d 20 30 3b 0a  dr1 *pPage = 0;.
6950: 0a 20 20 61 73 73 65 72 74 28 20 6f 66 66 73 65  .  assert( offse
6960: 74 6f 66 28 50 67 48 64 72 31 2c 70 61 67 65 29  tof(PgHdr1,page)
6970: 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28  ==0 );.  assert(
6980: 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61   pCache->bPurgea
6990: 62 6c 65 20 7c 7c 20 63 72 65 61 74 65 46 6c 61  ble || createFla
69a0: 67 21 3d 31 20 29 3b 0a 20 20 61 73 73 65 72 74  g!=1 );.  assert
69b0: 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65  ( pCache->bPurge
69c0: 61 62 6c 65 20 7c 7c 20 70 43 61 63 68 65 2d 3e  able || pCache->
69d0: 6e 4d 69 6e 3d 3d 30 20 29 3b 0a 20 20 61 73 73  nMin==0 );.  ass
69e0: 65 72 74 28 20 70 43 61 63 68 65 2d 3e 62 50 75  ert( pCache->bPu
69f0: 72 67 65 61 62 6c 65 3d 3d 30 20 7c 7c 20 70 43  rgeable==0 || pC
6a00: 61 63 68 65 2d 3e 6e 4d 69 6e 3d 3d 31 30 20 29  ache->nMin==10 )
6a10: 3b 0a 20 20 61 73 73 65 72 74 28 20 70 43 61 63  ;.  assert( pCac
6a20: 68 65 2d 3e 6e 4d 69 6e 3d 3d 30 20 7c 7c 20 70  he->nMin==0 || p
6a30: 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c  Cache->bPurgeabl
6a40: 65 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70  e );.  assert( p
6a50: 43 61 63 68 65 2d 3e 6e 48 61 73 68 3e 30 20 29  Cache->nHash>0 )
6a60: 3b 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65 72  ;.  pcache1Enter
6a70: 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e 70 47  Mutex(pCache->pG
6a80: 72 6f 75 70 29 3b 0a 0a 20 20 2f 2a 20 53 74 65  roup);..  /* Ste
6a90: 70 20 31 3a 20 53 65 61 72 63 68 20 74 68 65 20  p 1: Search the 
6aa0: 68 61 73 68 20 74 61 62 6c 65 20 66 6f 72 20 61  hash table for a
6ab0: 6e 20 65 78 69 73 74 69 6e 67 20 65 6e 74 72 79  n existing entry
6ac0: 2e 20 2a 2f 0a 20 20 70 50 61 67 65 20 3d 20 70  . */.  pPage = p
6ad0: 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 69 4b  Cache->apHash[iK
6ae0: 65 79 20 25 20 70 43 61 63 68 65 2d 3e 6e 48 61  ey % pCache->nHa
6af0: 73 68 5d 3b 0a 20 20 77 68 69 6c 65 28 20 70 50  sh];.  while( pP
6b00: 61 67 65 20 26 26 20 70 50 61 67 65 2d 3e 69 4b  age && pPage->iK
6b10: 65 79 21 3d 69 4b 65 79 20 29 7b 20 70 50 61 67  ey!=iKey ){ pPag
6b20: 65 20 3d 20 70 50 61 67 65 2d 3e 70 4e 65 78 74  e = pPage->pNext
6b30: 3b 20 7d 0a 0a 20 20 2f 2a 20 53 74 65 70 20 32  ; }..  /* Step 2
6b40: 3a 20 41 62 6f 72 74 20 69 66 20 6e 6f 20 65 78  : Abort if no ex
6b50: 69 73 74 69 6e 67 20 70 61 67 65 20 69 73 20 66  isting page is f
6b60: 6f 75 6e 64 20 61 6e 64 20 63 72 65 61 74 65 46  ound and createF
6b70: 6c 61 67 20 69 73 20 30 20 2a 2f 0a 20 20 69 66  lag is 0 */.  if
6b80: 28 20 70 50 61 67 65 20 29 7b 0a 20 20 20 20 69  ( pPage ){.    i
6b90: 66 28 20 21 70 50 61 67 65 2d 3e 69 73 50 69 6e  f( !pPage->isPin
6ba0: 6e 65 64 20 29 20 70 63 61 63 68 65 31 50 69 6e  ned ) pcache1Pin
6bb0: 50 61 67 65 28 70 50 61 67 65 29 3b 0a 20 20 7d  Page(pPage);.  }
6bc0: 65 6c 73 65 20 69 66 28 20 63 72 65 61 74 65 46  else if( createF
6bd0: 6c 61 67 20 29 7b 0a 20 20 20 20 2f 2a 20 53 74  lag ){.    /* St
6be0: 65 70 73 20 33 2c 20 34 2c 20 61 6e 64 20 35 20  eps 3, 4, and 5 
6bf0: 69 6d 70 6c 65 6d 65 6e 74 65 64 20 62 79 20 74  implemented by t
6c00: 68 69 73 20 73 75 62 72 6f 75 74 69 6e 65 20 2a  his subroutine *
6c10: 2f 0a 20 20 20 20 70 50 61 67 65 20 3d 20 70 63  /.    pPage = pc
6c20: 61 63 68 65 31 46 65 74 63 68 53 74 61 67 65 32  ache1FetchStage2
6c30: 28 70 43 61 63 68 65 2c 20 69 4b 65 79 2c 20 63  (pCache, iKey, c
6c40: 72 65 61 74 65 46 6c 61 67 29 3b 0a 20 20 7d 0a  reateFlag);.  }.
6c50: 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65 3d    assert( pPage=
6c60: 3d 30 20 7c 7c 20 70 43 61 63 68 65 2d 3e 69 4d  =0 || pCache->iM
6c70: 61 78 4b 65 79 3e 3d 69 4b 65 79 20 29 3b 0a 20  axKey>=iKey );. 
6c80: 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74   pcache1LeaveMut
6c90: 65 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75  ex(pCache->pGrou
6ca0: 70 29 3b 0a 20 20 72 65 74 75 72 6e 20 28 73 71  p);.  return (sq
6cb0: 6c 69 74 65 33 5f 70 63 61 63 68 65 5f 70 61 67  lite3_pcache_pag
6cc0: 65 2a 29 70 50 61 67 65 3b 0a 7d 0a 0a 0a 2f 2a  e*)pPage;.}.../*
6cd0: 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69  .** Implementati
6ce0: 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65  on of the sqlite
6cf0: 33 5f 70 63 61 63 68 65 2e 78 55 6e 70 69 6e 20  3_pcache.xUnpin 
6d00: 6d 65 74 68 6f 64 2e 0a 2a 2a 0a 2a 2a 20 4d 61  method..**.** Ma
6d10: 72 6b 20 61 20 70 61 67 65 20 61 73 20 75 6e 70  rk a page as unp
6d20: 69 6e 6e 65 64 20 28 65 6c 69 67 69 62 6c 65 20  inned (eligible 
6d30: 66 6f 72 20 61 73 79 6e 63 68 72 6f 6e 6f 75 73  for asynchronous
6d40: 20 72 65 63 79 63 6c 69 6e 67 29 2e 0a 2a 2f 0a   recycling)..*/.
6d50: 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63  static void pcac
6d60: 68 65 31 55 6e 70 69 6e 28 0a 20 20 73 71 6c 69  he1Unpin(.  sqli
6d70: 74 65 33 5f 70 63 61 63 68 65 20 2a 70 2c 20 0a  te3_pcache *p, .
6d80: 20 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65    sqlite3_pcache
6d90: 5f 70 61 67 65 20 2a 70 50 67 2c 20 0a 20 20 69  _page *pPg, .  i
6da0: 6e 74 20 72 65 75 73 65 55 6e 6c 69 6b 65 6c 79  nt reuseUnlikely
6db0: 0a 29 7b 0a 20 20 50 43 61 63 68 65 31 20 2a 70  .){.  PCache1 *p
6dc0: 43 61 63 68 65 20 3d 20 28 50 43 61 63 68 65 31  Cache = (PCache1
6dd0: 20 2a 29 70 3b 0a 20 20 50 67 48 64 72 31 20 2a   *)p;.  PgHdr1 *
6de0: 70 50 61 67 65 20 3d 20 28 50 67 48 64 72 31 20  pPage = (PgHdr1 
6df0: 2a 29 70 50 67 3b 0a 20 20 50 47 72 6f 75 70 20  *)pPg;.  PGroup 
6e00: 2a 70 47 72 6f 75 70 20 3d 20 70 43 61 63 68 65  *pGroup = pCache
6e10: 2d 3e 70 47 72 6f 75 70 3b 0a 20 0a 20 20 61 73  ->pGroup;. .  as
6e20: 73 65 72 74 28 20 70 50 61 67 65 2d 3e 70 43 61  sert( pPage->pCa
6e30: 63 68 65 3d 3d 70 43 61 63 68 65 20 29 3b 0a 20  che==pCache );. 
6e40: 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74   pcache1EnterMut
6e50: 65 78 28 70 47 72 6f 75 70 29 3b 0a 0a 20 20 2f  ex(pGroup);..  /
6e60: 2a 20 49 74 20 69 73 20 61 6e 20 65 72 72 6f 72  * It is an error
6e70: 20 74 6f 20 63 61 6c 6c 20 74 68 69 73 20 66 75   to call this fu
6e80: 6e 63 74 69 6f 6e 20 69 66 20 74 68 65 20 70 61  nction if the pa
6e90: 67 65 20 69 73 20 61 6c 72 65 61 64 79 20 0a 20  ge is already . 
6ea0: 20 2a 2a 20 70 61 72 74 20 6f 66 20 74 68 65 20   ** part of the 
6eb0: 50 47 72 6f 75 70 20 4c 52 55 20 6c 69 73 74 2e  PGroup LRU list.
6ec0: 0a 20 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20  .  */.  assert( 
6ed0: 70 50 61 67 65 2d 3e 70 4c 72 75 50 72 65 76 3d  pPage->pLruPrev=
6ee0: 3d 30 20 26 26 20 70 50 61 67 65 2d 3e 70 4c 72  =0 && pPage->pLr
6ef0: 75 4e 65 78 74 3d 3d 30 20 29 3b 0a 20 20 61 73  uNext==0 );.  as
6f00: 73 65 72 74 28 20 70 47 72 6f 75 70 2d 3e 70 4c  sert( pGroup->pL
6f10: 72 75 48 65 61 64 21 3d 70 50 61 67 65 20 26 26  ruHead!=pPage &&
6f20: 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 54 61 69   pGroup->pLruTai
6f30: 6c 21 3d 70 50 61 67 65 20 29 3b 0a 20 20 61 73  l!=pPage );.  as
6f40: 73 65 72 74 28 20 70 50 61 67 65 2d 3e 69 73 50  sert( pPage->isP
6f50: 69 6e 6e 65 64 3d 3d 31 20 29 3b 0a 0a 20 20 69  inned==1 );..  i
6f60: 66 28 20 72 65 75 73 65 55 6e 6c 69 6b 65 6c 79  f( reuseUnlikely
6f70: 20 7c 7c 20 70 47 72 6f 75 70 2d 3e 6e 43 75 72   || pGroup->nCur
6f80: 72 65 6e 74 50 61 67 65 3e 70 47 72 6f 75 70 2d  rentPage>pGroup-
6f90: 3e 6e 4d 61 78 50 61 67 65 20 29 7b 0a 20 20 20  >nMaxPage ){.   
6fa0: 20 70 63 61 63 68 65 31 52 65 6d 6f 76 65 46 72   pcache1RemoveFr
6fb0: 6f 6d 48 61 73 68 28 70 50 61 67 65 29 3b 0a 20  omHash(pPage);. 
6fc0: 20 20 20 70 63 61 63 68 65 31 46 72 65 65 50 61     pcache1FreePa
6fd0: 67 65 28 70 50 61 67 65 29 3b 0a 20 20 7d 65 6c  ge(pPage);.  }el
6fe0: 73 65 7b 0a 20 20 20 20 2f 2a 20 41 64 64 20 74  se{.    /* Add t
6ff0: 68 65 20 70 61 67 65 20 74 6f 20 74 68 65 20 50  he page to the P
7000: 47 72 6f 75 70 20 4c 52 55 20 6c 69 73 74 2e 20  Group LRU list. 
7010: 2a 2f 0a 20 20 20 20 69 66 28 20 70 47 72 6f 75  */.    if( pGrou
7020: 70 2d 3e 70 4c 72 75 48 65 61 64 20 29 7b 0a 20  p->pLruHead ){. 
7030: 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 70 4c 72       pGroup->pLr
7040: 75 48 65 61 64 2d 3e 70 4c 72 75 50 72 65 76 20  uHead->pLruPrev 
7050: 3d 20 70 50 61 67 65 3b 0a 20 20 20 20 20 20 70  = pPage;.      p
7060: 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 20 3d  Page->pLruNext =
7070: 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 48 65 61   pGroup->pLruHea
7080: 64 3b 0a 20 20 20 20 20 20 70 47 72 6f 75 70 2d  d;.      pGroup-
7090: 3e 70 4c 72 75 48 65 61 64 20 3d 20 70 50 61 67  >pLruHead = pPag
70a0: 65 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  e;.    }else{.  
70b0: 20 20 20 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75      pGroup->pLru
70c0: 54 61 69 6c 20 3d 20 70 50 61 67 65 3b 0a 20 20  Tail = pPage;.  
70d0: 20 20 20 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75      pGroup->pLru
70e0: 48 65 61 64 20 3d 20 70 50 61 67 65 3b 0a 20 20  Head = pPage;.  
70f0: 20 20 7d 0a 20 20 20 20 70 43 61 63 68 65 2d 3e    }.    pCache->
7100: 6e 52 65 63 79 63 6c 61 62 6c 65 2b 2b 3b 0a 20  nRecyclable++;. 
7110: 20 20 20 70 50 61 67 65 2d 3e 69 73 50 69 6e 6e     pPage->isPinn
7120: 65 64 20 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20 70  ed = 0;.  }..  p
7130: 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78  cache1LeaveMutex
7140: 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 29  (pCache->pGroup)
7150: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65  ;.}../*.** Imple
7160: 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65  mentation of the
7170: 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e   sqlite3_pcache.
7180: 78 52 65 6b 65 79 20 6d 65 74 68 6f 64 2e 20 0a  xRekey method. .
7190: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70  */.static void p
71a0: 63 61 63 68 65 31 52 65 6b 65 79 28 0a 20 20 73  cache1Rekey(.  s
71b0: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70  qlite3_pcache *p
71c0: 2c 0a 20 20 73 71 6c 69 74 65 33 5f 70 63 61 63  ,.  sqlite3_pcac
71d0: 68 65 5f 70 61 67 65 20 2a 70 50 67 2c 0a 20 20  he_page *pPg,.  
71e0: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4f 6c  unsigned int iOl
71f0: 64 2c 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e  d,.  unsigned in
7200: 74 20 69 4e 65 77 0a 29 7b 0a 20 20 50 43 61 63  t iNew.){.  PCac
7210: 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28 50  he1 *pCache = (P
7220: 43 61 63 68 65 31 20 2a 29 70 3b 0a 20 20 50 67  Cache1 *)p;.  Pg
7230: 48 64 72 31 20 2a 70 50 61 67 65 20 3d 20 28 50  Hdr1 *pPage = (P
7240: 67 48 64 72 31 20 2a 29 70 50 67 3b 0a 20 20 50  gHdr1 *)pPg;.  P
7250: 67 48 64 72 31 20 2a 2a 70 70 3b 0a 20 20 75 6e  gHdr1 **pp;.  un
7260: 73 69 67 6e 65 64 20 69 6e 74 20 68 3b 20 0a 20  signed int h; . 
7270: 20 61 73 73 65 72 74 28 20 70 50 61 67 65 2d 3e   assert( pPage->
7280: 69 4b 65 79 3d 3d 69 4f 6c 64 20 29 3b 0a 20 20  iKey==iOld );.  
7290: 61 73 73 65 72 74 28 20 70 50 61 67 65 2d 3e 70  assert( pPage->p
72a0: 43 61 63 68 65 3d 3d 70 43 61 63 68 65 20 29 3b  Cache==pCache );
72b0: 0a 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65 72  ..  pcache1Enter
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 0a 20 20 68 20 3d 20 69 4f  roup);..  h = iO
72e0: 6c 64 25 70 43 61 63 68 65 2d 3e 6e 48 61 73 68  ld%pCache->nHash
72f0: 3b 0a 20 20 70 70 20 3d 20 26 70 43 61 63 68 65  ;.  pp = &pCache
7300: 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 0a 20 20 77  ->apHash[h];.  w
7310: 68 69 6c 65 28 20 28 2a 70 70 29 21 3d 70 50 61  hile( (*pp)!=pPa
7320: 67 65 20 29 7b 0a 20 20 20 20 70 70 20 3d 20 26  ge ){.    pp = &
7330: 28 2a 70 70 29 2d 3e 70 4e 65 78 74 3b 0a 20 20  (*pp)->pNext;.  
7340: 7d 0a 20 20 2a 70 70 20 3d 20 70 50 61 67 65 2d  }.  *pp = pPage-
7350: 3e 70 4e 65 78 74 3b 0a 0a 20 20 68 20 3d 20 69  >pNext;..  h = i
7360: 4e 65 77 25 70 43 61 63 68 65 2d 3e 6e 48 61 73  New%pCache->nHas
7370: 68 3b 0a 20 20 70 50 61 67 65 2d 3e 69 4b 65 79  h;.  pPage->iKey
7380: 20 3d 20 69 4e 65 77 3b 0a 20 20 70 50 61 67 65   = iNew;.  pPage
7390: 2d 3e 70 4e 65 78 74 20 3d 20 70 43 61 63 68 65  ->pNext = pCache
73a0: 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 0a 20 20 70  ->apHash[h];.  p
73b0: 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d  Cache->apHash[h]
73c0: 20 3d 20 70 50 61 67 65 3b 0a 20 20 69 66 28 20   = pPage;.  if( 
73d0: 69 4e 65 77 3e 70 43 61 63 68 65 2d 3e 69 4d 61  iNew>pCache->iMa
73e0: 78 4b 65 79 20 29 7b 0a 20 20 20 20 70 43 61 63  xKey ){.    pCac
73f0: 68 65 2d 3e 69 4d 61 78 4b 65 79 20 3d 20 69 4e  he->iMaxKey = iN
7400: 65 77 3b 0a 20 20 7d 0a 0a 20 20 70 63 61 63 68  ew;.  }..  pcach
7410: 65 31 4c 65 61 76 65 4d 75 74 65 78 28 70 43 61  e1LeaveMutex(pCa
7420: 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 7d 0a  che->pGroup);.}.
7430: 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74  ./*.** Implement
7440: 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c  ation of the sql
7450: 69 74 65 33 5f 70 63 61 63 68 65 2e 78 54 72 75  ite3_pcache.xTru
7460: 6e 63 61 74 65 20 6d 65 74 68 6f 64 2e 20 0a 2a  ncate method. .*
7470: 2a 0a 2a 2a 20 44 69 73 63 61 72 64 20 61 6c 6c  *.** Discard all
7480: 20 75 6e 70 69 6e 6e 65 64 20 70 61 67 65 73 20   unpinned pages 
7490: 69 6e 20 74 68 65 20 63 61 63 68 65 20 77 69 74  in the cache wit
74a0: 68 20 61 20 70 61 67 65 20 6e 75 6d 62 65 72 20  h a page number 
74b0: 65 71 75 61 6c 20 74 6f 0a 2a 2a 20 6f 72 20 67  equal to.** or g
74c0: 72 65 61 74 65 72 20 74 68 61 6e 20 70 61 72 61  reater than para
74d0: 6d 65 74 65 72 20 69 4c 69 6d 69 74 2e 20 41 6e  meter iLimit. An
74e0: 79 20 70 69 6e 6e 65 64 20 70 61 67 65 73 20 77  y pinned pages w
74f0: 69 74 68 20 61 20 70 61 67 65 20 6e 75 6d 62 65  ith a page numbe
7500: 72 0a 2a 2a 20 65 71 75 61 6c 20 74 6f 20 6f 72  r.** equal to or
7510: 20 67 72 65 61 74 65 72 20 74 68 61 6e 20 69 4c   greater than iL
7520: 69 6d 69 74 20 61 72 65 20 69 6d 70 6c 69 63 69  imit are implici
7530: 74 6c 79 20 75 6e 70 69 6e 6e 65 64 2e 0a 2a 2f  tly unpinned..*/
7540: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61  .static void pca
7550: 63 68 65 31 54 72 75 6e 63 61 74 65 28 73 71 6c  che1Truncate(sql
7560: 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70 2c 20  ite3_pcache *p, 
7570: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4c 69  unsigned int iLi
7580: 6d 69 74 29 7b 0a 20 20 50 43 61 63 68 65 31 20  mit){.  PCache1 
7590: 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61 63 68  *pCache = (PCach
75a0: 65 31 20 2a 29 70 3b 0a 20 20 70 63 61 63 68 65  e1 *)p;.  pcache
75b0: 31 45 6e 74 65 72 4d 75 74 65 78 28 70 43 61 63  1EnterMutex(pCac
75c0: 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 20 20 69  he->pGroup);.  i
75d0: 66 28 20 69 4c 69 6d 69 74 3c 3d 70 43 61 63 68  f( iLimit<=pCach
75e0: 65 2d 3e 69 4d 61 78 4b 65 79 20 29 7b 0a 20 20  e->iMaxKey ){.  
75f0: 20 20 70 63 61 63 68 65 31 54 72 75 6e 63 61 74    pcache1Truncat
7600: 65 55 6e 73 61 66 65 28 70 43 61 63 68 65 2c 20  eUnsafe(pCache, 
7610: 69 4c 69 6d 69 74 29 3b 0a 20 20 20 20 70 43 61  iLimit);.    pCa
7620: 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 3d 20 69  che->iMaxKey = i
7630: 4c 69 6d 69 74 2d 31 3b 0a 20 20 7d 0a 20 20 70  Limit-1;.  }.  p
7640: 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78  cache1LeaveMutex
7650: 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 29  (pCache->pGroup)
7660: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65  ;.}../*.** Imple
7670: 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65  mentation of the
7680: 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e   sqlite3_pcache.
7690: 78 44 65 73 74 72 6f 79 20 6d 65 74 68 6f 64 2e  xDestroy method.
76a0: 20 0a 2a 2a 0a 2a 2a 20 44 65 73 74 72 6f 79 20   .**.** Destroy 
76b0: 61 20 63 61 63 68 65 20 61 6c 6c 6f 63 61 74 65  a cache allocate
76c0: 64 20 75 73 69 6e 67 20 70 63 61 63 68 65 31 43  d using pcache1C
76d0: 72 65 61 74 65 28 29 2e 0a 2a 2f 0a 73 74 61 74  reate()..*/.stat
76e0: 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 31 44  ic void pcache1D
76f0: 65 73 74 72 6f 79 28 73 71 6c 69 74 65 33 5f 70  estroy(sqlite3_p
7700: 63 61 63 68 65 20 2a 70 29 7b 0a 20 20 50 43 61  cache *p){.  PCa
7710: 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28  che1 *pCache = (
7720: 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20 20 50  PCache1 *)p;.  P
7730: 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 20 3d 20  Group *pGroup = 
7740: 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b 0a  pCache->pGroup;.
7750: 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65    assert( pCache
7760: 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 7c 7c 20  ->bPurgeable || 
7770: 28 70 43 61 63 68 65 2d 3e 6e 4d 61 78 3d 3d 30  (pCache->nMax==0
7780: 20 26 26 20 70 43 61 63 68 65 2d 3e 6e 4d 69 6e   && pCache->nMin
7790: 3d 3d 30 29 20 29 3b 0a 20 20 70 63 61 63 68 65  ==0) );.  pcache
77a0: 31 45 6e 74 65 72 4d 75 74 65 78 28 70 47 72 6f  1EnterMutex(pGro
77b0: 75 70 29 3b 0a 20 20 70 63 61 63 68 65 31 54 72  up);.  pcache1Tr
77c0: 75 6e 63 61 74 65 55 6e 73 61 66 65 28 70 43 61  uncateUnsafe(pCa
77d0: 63 68 65 2c 20 30 29 3b 0a 20 20 61 73 73 65 72  che, 0);.  asser
77e0: 74 28 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50  t( pGroup->nMaxP
77f0: 61 67 65 20 3e 3d 20 70 43 61 63 68 65 2d 3e 6e  age >= pCache->n
7800: 4d 61 78 20 29 3b 0a 20 20 70 47 72 6f 75 70 2d  Max );.  pGroup-
7810: 3e 6e 4d 61 78 50 61 67 65 20 2d 3d 20 70 43 61  >nMaxPage -= pCa
7820: 63 68 65 2d 3e 6e 4d 61 78 3b 0a 20 20 61 73 73  che->nMax;.  ass
7830: 65 72 74 28 20 70 47 72 6f 75 70 2d 3e 6e 4d 69  ert( pGroup->nMi
7840: 6e 50 61 67 65 20 3e 3d 20 70 43 61 63 68 65 2d  nPage >= pCache-
7850: 3e 6e 4d 69 6e 20 29 3b 0a 20 20 70 47 72 6f 75  >nMin );.  pGrou
7860: 70 2d 3e 6e 4d 69 6e 50 61 67 65 20 2d 3d 20 70  p->nMinPage -= p
7870: 43 61 63 68 65 2d 3e 6e 4d 69 6e 3b 0a 20 20 70  Cache->nMin;.  p
7880: 47 72 6f 75 70 2d 3e 6d 78 50 69 6e 6e 65 64 20  Group->mxPinned 
7890: 3d 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61  = pGroup->nMaxPa
78a0: 67 65 20 2b 20 31 30 20 2d 20 70 47 72 6f 75 70  ge + 10 - pGroup
78b0: 2d 3e 6e 4d 69 6e 50 61 67 65 3b 0a 20 20 70 63  ->nMinPage;.  pc
78c0: 61 63 68 65 31 45 6e 66 6f 72 63 65 4d 61 78 50  ache1EnforceMaxP
78d0: 61 67 65 28 70 47 72 6f 75 70 29 3b 0a 20 20 70  age(pGroup);.  p
78e0: 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78  cache1LeaveMutex
78f0: 28 70 47 72 6f 75 70 29 3b 0a 20 20 73 71 6c 69  (pGroup);.  sqli
7900: 74 65 33 5f 66 72 65 65 28 70 43 61 63 68 65 2d  te3_free(pCache-
7910: 3e 61 70 48 61 73 68 29 3b 0a 20 20 73 71 6c 69  >apHash);.  sqli
7920: 74 65 33 5f 66 72 65 65 28 70 43 61 63 68 65 29  te3_free(pCache)
7930: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  ;.}../*.** This 
7940: 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c  function is call
7950: 65 64 20 64 75 72 69 6e 67 20 69 6e 69 74 69 61  ed during initia
7960: 6c 69 7a 61 74 69 6f 6e 20 28 73 71 6c 69 74 65  lization (sqlite
7970: 33 5f 69 6e 69 74 69 61 6c 69 7a 65 28 29 29 20  3_initialize()) 
7980: 74 6f 0a 2a 2a 20 69 6e 73 74 61 6c 6c 20 74 68  to.** install th
7990: 65 20 64 65 66 61 75 6c 74 20 70 6c 75 67 67 61  e default plugga
79a0: 62 6c 65 20 63 61 63 68 65 20 6d 6f 64 75 6c 65  ble cache module
79b0: 2c 20 61 73 73 75 6d 69 6e 67 20 74 68 65 20 75  , assuming the u
79c0: 73 65 72 20 68 61 73 20 6e 6f 74 0a 2a 2a 20 61  ser has not.** a
79d0: 6c 72 65 61 64 79 20 70 72 6f 76 69 64 65 64 20  lready provided 
79e0: 61 6e 20 61 6c 74 65 72 6e 61 74 69 76 65 2e 0a  an alternative..
79f0: 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50  */.void sqlite3P
7a00: 43 61 63 68 65 53 65 74 44 65 66 61 75 6c 74 28  CacheSetDefault(
7a10: 76 6f 69 64 29 7b 0a 20 20 73 74 61 74 69 63 20  void){.  static 
7a20: 63 6f 6e 73 74 20 73 71 6c 69 74 65 33 5f 70 63  const sqlite3_pc
7a30: 61 63 68 65 5f 6d 65 74 68 6f 64 73 32 20 64 65  ache_methods2 de
7a40: 66 61 75 6c 74 4d 65 74 68 6f 64 73 20 3d 20 7b  faultMethods = {
7a50: 0a 20 20 20 20 31 2c 20 20 20 20 20 20 20 20 20  .    1,         
7a60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
7a70: 20 69 56 65 72 73 69 6f 6e 20 2a 2f 0a 20 20 20   iVersion */.   
7a80: 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20   0,             
7a90: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 70 41 72            /* pAr
7aa0: 67 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31  g */.    pcache1
7ab0: 49 6e 69 74 2c 20 20 20 20 20 20 20 20 20 20 20  Init,           
7ac0: 20 20 2f 2a 20 78 49 6e 69 74 20 2a 2f 0a 20 20    /* xInit */.  
7ad0: 20 20 70 63 61 63 68 65 31 53 68 75 74 64 6f 77    pcache1Shutdow
7ae0: 6e 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 78 53  n,         /* xS
7af0: 68 75 74 64 6f 77 6e 20 2a 2f 0a 20 20 20 20 70  hutdown */.    p
7b00: 63 61 63 68 65 31 43 72 65 61 74 65 2c 20 20 20  cache1Create,   
7b10: 20 20 20 20 20 20 20 20 2f 2a 20 78 43 72 65 61          /* xCrea
7b20: 74 65 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65  te */.    pcache
7b30: 31 43 61 63 68 65 73 69 7a 65 2c 20 20 20 20 20  1Cachesize,     
7b40: 20 20 20 2f 2a 20 78 43 61 63 68 65 73 69 7a 65     /* xCachesize
7b50: 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31 50   */.    pcache1P
7b60: 61 67 65 63 6f 75 6e 74 2c 20 20 20 20 20 20 20  agecount,       
7b70: 20 2f 2a 20 78 50 61 67 65 63 6f 75 6e 74 20 2a   /* xPagecount *
7b80: 2f 0a 20 20 20 20 70 63 61 63 68 65 31 46 65 74  /.    pcache1Fet
7b90: 63 68 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f  ch,            /
7ba0: 2a 20 78 46 65 74 63 68 20 2a 2f 0a 20 20 20 20  * xFetch */.    
7bb0: 70 63 61 63 68 65 31 55 6e 70 69 6e 2c 20 20 20  pcache1Unpin,   
7bc0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 55 6e 70           /* xUnp
7bd0: 69 6e 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65  in */.    pcache
7be0: 31 52 65 6b 65 79 2c 20 20 20 20 20 20 20 20 20  1Rekey,         
7bf0: 20 20 20 2f 2a 20 78 52 65 6b 65 79 20 2a 2f 0a     /* xRekey */.
7c00: 20 20 20 20 70 63 61 63 68 65 31 54 72 75 6e 63      pcache1Trunc
7c10: 61 74 65 2c 20 20 20 20 20 20 20 20 20 2f 2a 20  ate,         /* 
7c20: 78 54 72 75 6e 63 61 74 65 20 2a 2f 0a 20 20 20  xTruncate */.   
7c30: 20 70 63 61 63 68 65 31 44 65 73 74 72 6f 79 2c   pcache1Destroy,
7c40: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 65            /* xDe
7c50: 73 74 72 6f 79 20 2a 2f 0a 20 20 20 20 70 63 61  stroy */.    pca
7c60: 63 68 65 31 53 68 72 69 6e 6b 20 20 20 20 20 20  che1Shrink      
7c70: 20 20 20 20 20 20 2f 2a 20 78 53 68 72 69 6e 6b        /* xShrink
7c80: 20 2a 2f 0a 20 20 7d 3b 0a 20 20 73 71 6c 69 74   */.  };.  sqlit
7c90: 65 33 5f 63 6f 6e 66 69 67 28 53 51 4c 49 54 45  e3_config(SQLITE
7ca0: 5f 43 4f 4e 46 49 47 5f 50 43 41 43 48 45 32 2c  _CONFIG_PCACHE2,
7cb0: 20 26 64 65 66 61 75 6c 74 4d 65 74 68 6f 64 73   &defaultMethods
7cc0: 29 3b 0a 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c  );.}..#ifdef SQL
7cd0: 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52  ITE_ENABLE_MEMOR
7ce0: 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 0a 2f 2a 0a  Y_MANAGEMENT./*.
7cf0: 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
7d00: 20 69 73 20 63 61 6c 6c 65 64 20 74 6f 20 66 72   is called to fr
7d10: 65 65 20 73 75 70 65 72 66 6c 75 6f 75 73 20 64  ee superfluous d
7d20: 79 6e 61 6d 69 63 61 6c 6c 79 20 61 6c 6c 6f 63  ynamically alloc
7d30: 61 74 65 64 20 6d 65 6d 6f 72 79 0a 2a 2a 20 68  ated memory.** h
7d40: 65 6c 64 20 62 79 20 74 68 65 20 70 61 67 65 72  eld by the pager
7d50: 20 73 79 73 74 65 6d 2e 20 4d 65 6d 6f 72 79 20   system. Memory 
7d60: 69 6e 20 75 73 65 20 62 79 20 61 6e 79 20 53 51  in use by any SQ
7d70: 4c 69 74 65 20 70 61 67 65 72 20 61 6c 6c 6f 63  Lite pager alloc
7d80: 61 74 65 64 0a 2a 2a 20 62 79 20 74 68 65 20 63  ated.** by the c
7d90: 75 72 72 65 6e 74 20 74 68 72 65 61 64 20 6d 61  urrent thread ma
7da0: 79 20 62 65 20 73 71 6c 69 74 65 33 5f 66 72 65  y be sqlite3_fre
7db0: 65 28 29 65 64 2e 0a 2a 2a 0a 2a 2a 20 6e 52 65  e()ed..**.** nRe
7dc0: 71 20 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20  q is the number 
7dd0: 6f 66 20 62 79 74 65 73 20 6f 66 20 6d 65 6d 6f  of bytes of memo
7de0: 72 79 20 72 65 71 75 69 72 65 64 2e 20 4f 6e 63  ry required. Onc
7df0: 65 20 74 68 69 73 20 6d 75 63 68 20 68 61 73 0a  e this much has.
7e00: 2a 2a 20 62 65 65 6e 20 72 65 6c 65 61 73 65 64  ** been released
7e10: 2c 20 74 68 65 20 66 75 6e 63 74 69 6f 6e 20 72  , the function r
7e20: 65 74 75 72 6e 73 2e 20 54 68 65 20 72 65 74 75  eturns. The retu
7e30: 72 6e 20 76 61 6c 75 65 20 69 73 20 74 68 65 20  rn value is the 
7e40: 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 0a 2a 2a  total number .**
7e50: 20 6f 66 20 62 79 74 65 73 20 6f 66 20 6d 65 6d   of bytes of mem
7e60: 6f 72 79 20 72 65 6c 65 61 73 65 64 2e 0a 2a 2f  ory released..*/
7e70: 0a 69 6e 74 20 73 71 6c 69 74 65 33 50 63 61 63  .int sqlite3Pcac
7e80: 68 65 52 65 6c 65 61 73 65 4d 65 6d 6f 72 79 28  heReleaseMemory(
7e90: 69 6e 74 20 6e 52 65 71 29 7b 0a 20 20 69 6e 74  int nReq){.  int
7ea0: 20 6e 46 72 65 65 20 3d 20 30 3b 0a 20 20 61 73   nFree = 0;.  as
7eb0: 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75  sert( sqlite3_mu
7ec0: 74 65 78 5f 6e 6f 74 68 65 6c 64 28 70 63 61 63  tex_notheld(pcac
7ed0: 68 65 31 2e 67 72 70 2e 6d 75 74 65 78 29 20 29  he1.grp.mutex) )
7ee0: 3b 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c 69  ;.  assert( sqli
7ef0: 74 65 33 5f 6d 75 74 65 78 5f 6e 6f 74 68 65 6c  te3_mutex_nothel
7f00: 64 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29  d(pcache1.mutex)
7f10: 20 29 3b 0a 20 20 69 66 28 20 70 63 61 63 68 65   );.  if( pcache
7f20: 31 2e 70 53 74 61 72 74 3d 3d 30 20 29 7b 0a 20  1.pStart==0 ){. 
7f30: 20 20 20 50 67 48 64 72 31 20 2a 70 3b 0a 20 20     PgHdr1 *p;.  
7f40: 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75    pcache1EnterMu
7f50: 74 65 78 28 26 70 63 61 63 68 65 31 2e 67 72 70  tex(&pcache1.grp
7f60: 29 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 28 6e  );.    while( (n
7f70: 52 65 71 3c 30 20 7c 7c 20 6e 46 72 65 65 3c 6e  Req<0 || nFree<n
7f80: 52 65 71 29 20 26 26 20 28 28 70 3d 70 63 61 63  Req) && ((p=pcac
7f90: 68 65 31 2e 67 72 70 2e 70 4c 72 75 54 61 69 6c  he1.grp.pLruTail
7fa0: 29 21 3d 30 29 20 29 7b 0a 20 20 20 20 20 20 6e  )!=0) ){.      n
7fb0: 46 72 65 65 20 2b 3d 20 70 63 61 63 68 65 31 4d  Free += pcache1M
7fc0: 65 6d 53 69 7a 65 28 70 2d 3e 70 61 67 65 2e 70  emSize(p->page.p
7fd0: 42 75 66 29 3b 0a 23 69 66 64 65 66 20 53 51 4c  Buf);.#ifdef SQL
7fe0: 49 54 45 5f 50 43 41 43 48 45 5f 53 45 50 41 52  ITE_PCACHE_SEPAR
7ff0: 41 54 45 5f 48 45 41 44 45 52 0a 20 20 20 20 20  ATE_HEADER.     
8000: 20 6e 46 72 65 65 20 2b 3d 20 73 71 6c 69 74 65   nFree += sqlite
8010: 33 4d 65 6d 53 69 7a 65 28 70 29 3b 0a 23 65 6e  3MemSize(p);.#en
8020: 64 69 66 0a 20 20 20 20 20 20 61 73 73 65 72 74  dif.      assert
8030: 28 20 70 2d 3e 69 73 50 69 6e 6e 65 64 3d 3d 30  ( p->isPinned==0
8040: 20 29 3b 0a 20 20 20 20 20 20 70 63 61 63 68 65   );.      pcache
8050: 31 50 69 6e 50 61 67 65 28 70 29 3b 0a 20 20 20  1PinPage(p);.   
8060: 20 20 20 70 63 61 63 68 65 31 52 65 6d 6f 76 65     pcache1Remove
8070: 46 72 6f 6d 48 61 73 68 28 70 29 3b 0a 20 20 20  FromHash(p);.   
8080: 20 20 20 70 63 61 63 68 65 31 46 72 65 65 50 61     pcache1FreePa
8090: 67 65 28 70 29 3b 0a 20 20 20 20 7d 0a 20 20 20  ge(p);.    }.   
80a0: 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74   pcache1LeaveMut
80b0: 65 78 28 26 70 63 61 63 68 65 31 2e 67 72 70 29  ex(&pcache1.grp)
80c0: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 6e  ;.  }.  return n
80d0: 46 72 65 65 3b 0a 7d 0a 23 65 6e 64 69 66 20 2f  Free;.}.#endif /
80e0: 2a 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f  * SQLITE_ENABLE_
80f0: 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e  MEMORY_MANAGEMEN
8100: 54 20 2a 2f 0a 0a 23 69 66 64 65 66 20 53 51 4c  T */..#ifdef SQL
8110: 49 54 45 5f 54 45 53 54 0a 2f 2a 0a 2a 2a 20 54  ITE_TEST./*.** T
8120: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
8130: 75 73 65 64 20 62 79 20 74 65 73 74 20 70 72 6f  used by test pro
8140: 63 65 64 75 72 65 73 20 74 6f 20 69 6e 73 70 65  cedures to inspe
8150: 63 74 20 74 68 65 20 69 6e 74 65 72 6e 61 6c 20  ct the internal 
8160: 73 74 61 74 65 0a 2a 2a 20 6f 66 20 74 68 65 20  state.** of the 
8170: 67 6c 6f 62 61 6c 20 63 61 63 68 65 2e 0a 2a 2f  global cache..*/
8180: 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63 61  .void sqlite3Pca
8190: 63 68 65 53 74 61 74 73 28 0a 20 20 69 6e 74 20  cheStats(.  int 
81a0: 2a 70 6e 43 75 72 72 65 6e 74 2c 20 20 20 20 20  *pnCurrent,     
81b0: 20 2f 2a 20 4f 55 54 3a 20 54 6f 74 61 6c 20 6e   /* OUT: Total n
81c0: 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 63  umber of pages c
81d0: 61 63 68 65 64 20 2a 2f 0a 20 20 69 6e 74 20 2a  ached */.  int *
81e0: 70 6e 4d 61 78 2c 20 20 20 20 20 20 20 20 20 20  pnMax,          
81f0: 2f 2a 20 4f 55 54 3a 20 47 6c 6f 62 61 6c 20 6d  /* OUT: Global m
8200: 61 78 69 6d 75 6d 20 63 61 63 68 65 20 73 69 7a  aximum cache siz
8210: 65 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 4d 69  e */.  int *pnMi
8220: 6e 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f  n,          /* O
8230: 55 54 3a 20 53 75 6d 20 6f 66 20 50 43 61 63 68  UT: Sum of PCach
8240: 65 31 2e 6e 4d 69 6e 20 66 6f 72 20 70 75 72 67  e1.nMin for purg
8250: 65 61 62 6c 65 20 63 61 63 68 65 73 20 2a 2f 0a  eable caches */.
8260: 20 20 69 6e 74 20 2a 70 6e 52 65 63 79 63 6c 61    int *pnRecycla
8270: 62 6c 65 20 20 20 20 2f 2a 20 4f 55 54 3a 20 54  ble    /* OUT: T
8280: 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 70  otal number of p
8290: 61 67 65 73 20 61 76 61 69 6c 61 62 6c 65 20 66  ages available f
82a0: 6f 72 20 72 65 63 79 63 6c 69 6e 67 20 2a 2f 0a  or recycling */.
82b0: 29 7b 0a 20 20 50 67 48 64 72 31 20 2a 70 3b 0a  ){.  PgHdr1 *p;.
82c0: 20 20 69 6e 74 20 6e 52 65 63 79 63 6c 61 62 6c    int nRecyclabl
82d0: 65 20 3d 20 30 3b 0a 20 20 66 6f 72 28 70 3d 70  e = 0;.  for(p=p
82e0: 63 61 63 68 65 31 2e 67 72 70 2e 70 4c 72 75 48  cache1.grp.pLruH
82f0: 65 61 64 3b 20 70 3b 20 70 3d 70 2d 3e 70 4c 72  ead; p; p=p->pLr
8300: 75 4e 65 78 74 29 7b 0a 20 20 20 20 61 73 73 65  uNext){.    asse
8310: 72 74 28 20 70 2d 3e 69 73 50 69 6e 6e 65 64 3d  rt( p->isPinned=
8320: 3d 30 20 29 3b 0a 20 20 20 20 6e 52 65 63 79 63  =0 );.    nRecyc
8330: 6c 61 62 6c 65 2b 2b 3b 0a 20 20 7d 0a 20 20 2a  lable++;.  }.  *
8340: 70 6e 43 75 72 72 65 6e 74 20 3d 20 70 63 61 63  pnCurrent = pcac
8350: 68 65 31 2e 67 72 70 2e 6e 43 75 72 72 65 6e 74  he1.grp.nCurrent
8360: 50 61 67 65 3b 0a 20 20 2a 70 6e 4d 61 78 20 3d  Page;.  *pnMax =
8370: 20 28 69 6e 74 29 70 63 61 63 68 65 31 2e 67 72   (int)pcache1.gr
8380: 70 2e 6e 4d 61 78 50 61 67 65 3b 0a 20 20 2a 70  p.nMaxPage;.  *p
8390: 6e 4d 69 6e 20 3d 20 28 69 6e 74 29 70 63 61 63  nMin = (int)pcac
83a0: 68 65 31 2e 67 72 70 2e 6e 4d 69 6e 50 61 67 65  he1.grp.nMinPage
83b0: 3b 0a 20 20 2a 70 6e 52 65 63 79 63 6c 61 62 6c  ;.  *pnRecyclabl
83c0: 65 20 3d 20 6e 52 65 63 79 63 6c 61 62 6c 65 3b  e = nRecyclable;
83d0: 0a 7d 0a 23 65 6e 64 69 66 0a                    .}.#endif.