/ Hex Artifact Content
Login

Artifact 102e6f5a2fbc646154463eb856d1fd716867b64c:


0000: 2f 2a 0a 2a 2a 20 32 30 30 38 20 4e 6f 76 65 6d  /*.** 2008 Novem
0010: 62 65 72 20 30 35 0a 2a 2a 0a 2a 2a 20 54 68 65  ber 05.**.** The
0020: 20 61 75 74 68 6f 72 20 64 69 73 63 6c 61 69 6d   author disclaim
0030: 73 20 63 6f 70 79 72 69 67 68 74 20 74 6f 20 74  s copyright to t
0040: 68 69 73 20 73 6f 75 72 63 65 20 63 6f 64 65 2e  his source code.
0050: 20 20 49 6e 20 70 6c 61 63 65 20 6f 66 0a 2a 2a    In place of.**
0060: 20 61 20 6c 65 67 61 6c 20 6e 6f 74 69 63 65 2c   a legal notice,
0070: 20 68 65 72 65 20 69 73 20 61 20 62 6c 65 73 73   here is a bless
0080: 69 6e 67 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 4d 61  ing:.**.**    Ma
0090: 79 20 79 6f 75 20 64 6f 20 67 6f 6f 64 20 61 6e  y you do good an
00a0: 64 20 6e 6f 74 20 65 76 69 6c 2e 0a 2a 2a 20 20  d not evil..**  
00b0: 20 20 4d 61 79 20 79 6f 75 20 66 69 6e 64 20 66    May you find f
00c0: 6f 72 67 69 76 65 6e 65 73 73 20 66 6f 72 20 79  orgiveness for y
00d0: 6f 75 72 73 65 6c 66 20 61 6e 64 20 66 6f 72 67  ourself and forg
00e0: 69 76 65 20 6f 74 68 65 72 73 2e 0a 2a 2a 20 20  ive others..**  
00f0: 20 20 4d 61 79 20 79 6f 75 20 73 68 61 72 65 20    May you share 
0100: 66 72 65 65 6c 79 2c 20 6e 65 76 65 72 20 74 61  freely, never ta
0110: 6b 69 6e 67 20 6d 6f 72 65 20 74 68 61 6e 20 79  king more than y
0120: 6f 75 20 67 69 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a  ou give..**.****
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 2a 2a 2a 2a 2a 0a 2a 2a 0a 2a 2a 20 54 68 69 73  *****.**.** This
0180: 20 66 69 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 73   file implements
0190: 20 74 68 65 20 64 65 66 61 75 6c 74 20 70 61 67   the default pag
01a0: 65 20 63 61 63 68 65 20 69 6d 70 6c 65 6d 65 6e  e cache implemen
01b0: 74 61 74 69 6f 6e 20 28 74 68 65 0a 2a 2a 20 73  tation (the.** s
01c0: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 69 6e  qlite3_pcache in
01d0: 74 65 72 66 61 63 65 29 2e 20 49 74 20 61 6c 73  terface). It als
01e0: 6f 20 63 6f 6e 74 61 69 6e 73 20 70 61 72 74 20  o contains part 
01f0: 6f 66 20 74 68 65 20 69 6d 70 6c 65 6d 65 6e 74  of the implement
0200: 61 74 69 6f 6e 0a 2a 2a 20 6f 66 20 74 68 65 20  ation.** of the 
0210: 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41  SQLITE_CONFIG_PA
0220: 47 45 43 41 43 48 45 20 61 6e 64 20 73 71 6c 69  GECACHE and sqli
0230: 74 65 33 5f 72 65 6c 65 61 73 65 5f 6d 65 6d 6f  te3_release_memo
0240: 72 79 28 29 20 66 65 61 74 75 72 65 73 2e 0a 2a  ry() features..*
0250: 2a 20 49 66 20 74 68 65 20 64 65 66 61 75 6c 74  * If the default
0260: 20 70 61 67 65 20 63 61 63 68 65 20 69 6d 70 6c   page cache impl
0270: 65 6d 65 6e 74 61 74 69 6f 6e 20 69 73 20 6f 76  ementation is ov
0280: 65 72 72 69 64 65 6e 2c 20 74 68 65 6e 20 6e 65  erriden, then ne
0290: 69 74 68 65 72 20 6f 66 0a 2a 2a 20 74 68 65 73  ither of.** thes
02a0: 65 20 74 77 6f 20 66 65 61 74 75 72 65 73 20 61  e two features a
02b0: 72 65 20 61 76 61 69 6c 61 62 6c 65 2e 0a 2a 2f  re available..*/
02c0: 0a 0a 23 69 6e 63 6c 75 64 65 20 22 73 71 6c 69  ..#include "sqli
02d0: 74 65 49 6e 74 2e 68 22 0a 0a 74 79 70 65 64 65  teInt.h"..typede
02e0: 66 20 73 74 72 75 63 74 20 50 43 61 63 68 65 31  f struct PCache1
02f0: 20 50 43 61 63 68 65 31 3b 0a 74 79 70 65 64 65   PCache1;.typede
0300: 66 20 73 74 72 75 63 74 20 50 67 48 64 72 31 20  f struct PgHdr1 
0310: 50 67 48 64 72 31 3b 0a 74 79 70 65 64 65 66 20  PgHdr1;.typedef 
0320: 73 74 72 75 63 74 20 50 67 46 72 65 65 73 6c 6f  struct PgFreeslo
0330: 74 20 50 67 46 72 65 65 73 6c 6f 74 3b 0a 74 79  t PgFreeslot;.ty
0340: 70 65 64 65 66 20 73 74 72 75 63 74 20 50 47 72  pedef struct PGr
0350: 6f 75 70 20 50 47 72 6f 75 70 3b 0a 0a 2f 2a 20  oup PGroup;../* 
0360: 45 61 63 68 20 70 61 67 65 20 63 61 63 68 65 20  Each page cache 
0370: 28 6f 72 20 50 43 61 63 68 65 29 20 62 65 6c 6f  (or PCache) belo
0380: 6e 67 73 20 74 6f 20 61 20 50 47 72 6f 75 70 2e  ngs to a PGroup.
0390: 20 20 41 20 50 47 72 6f 75 70 20 69 73 20 61 20    A PGroup is a 
03a0: 73 65 74 20 0a 2a 2a 20 6f 66 20 6f 6e 65 20 6f  set .** of one o
03b0: 72 20 6d 6f 72 65 20 50 43 61 63 68 65 73 20 74  r more PCaches t
03c0: 68 61 74 20 61 72 65 20 61 62 6c 65 20 74 6f 20  hat are able to 
03d0: 72 65 63 79 63 6c 65 20 65 61 63 68 20 6f 74 68  recycle each oth
03e0: 65 72 73 20 75 6e 70 69 6e 6e 65 64 0a 2a 2a 20  ers unpinned.** 
03f0: 70 61 67 65 73 20 77 68 65 6e 20 74 68 65 79 20  pages when they 
0400: 61 72 65 20 75 6e 64 65 72 20 6d 65 6d 6f 72 79  are under memory
0410: 20 70 72 65 73 73 75 72 65 2e 20 20 41 20 50 47   pressure.  A PG
0420: 72 6f 75 70 20 69 73 20 61 6e 20 69 6e 73 74 61  roup is an insta
0430: 6e 63 65 20 6f 66 0a 2a 2a 20 74 68 65 20 66 6f  nce of.** the fo
0440: 6c 6c 6f 77 69 6e 67 20 6f 62 6a 65 63 74 2e 0a  llowing object..
0450: 2a 2a 0a 2a 2a 20 54 68 69 73 20 70 61 67 65 20  **.** This page 
0460: 63 61 63 68 65 20 69 6d 70 6c 65 6d 65 6e 74 61  cache implementa
0470: 74 69 6f 6e 20 77 6f 72 6b 73 20 69 6e 20 6f 6e  tion works in on
0480: 65 20 6f 66 20 74 77 6f 20 6d 6f 64 65 73 3a 0a  e of two modes:.
0490: 2a 2a 0a 2a 2a 20 20 20 28 31 29 20 20 45 76 65  **.**   (1)  Eve
04a0: 72 79 20 50 43 61 63 68 65 20 69 73 20 74 68 65  ry PCache is the
04b0: 20 73 6f 6c 65 20 6d 65 6d 62 65 72 20 6f 66 20   sole member of 
04c0: 69 74 73 20 6f 77 6e 20 50 47 72 6f 75 70 2e 20  its own PGroup. 
04d0: 20 54 68 65 72 65 20 69 73 0a 2a 2a 20 20 20 20   There is.**    
04e0: 20 20 20 20 6f 6e 65 20 50 47 72 6f 75 70 20 70      one PGroup p
04f0: 65 72 20 50 43 61 63 68 65 2e 0a 2a 2a 0a 2a 2a  er PCache..**.**
0500: 20 20 20 28 32 29 20 20 54 68 65 72 65 20 69 73     (2)  There is
0510: 20 61 20 73 69 6e 67 6c 65 20 67 6c 6f 62 61 6c   a single global
0520: 20 50 47 72 6f 75 70 20 74 68 61 74 20 61 6c 6c   PGroup that all
0530: 20 50 43 61 63 68 65 73 20 61 72 65 20 61 20 6d   PCaches are a m
0540: 65 6d 62 65 72 0a 2a 2a 20 20 20 20 20 20 20 20  ember.**        
0550: 6f 66 2e 0a 2a 2a 0a 2a 2a 20 4d 6f 64 65 20 31  of..**.** Mode 1
0560: 20 75 73 65 73 20 6d 6f 72 65 20 6d 65 6d 6f 72   uses more memor
0570: 79 20 28 73 69 6e 63 65 20 50 43 61 63 68 65 20  y (since PCache 
0580: 69 6e 73 74 61 6e 63 65 73 20 61 72 65 20 6e 6f  instances are no
0590: 74 20 61 62 6c 65 20 74 6f 20 72 6f 62 0a 2a 2a  t able to rob.**
05a0: 20 75 6e 75 73 65 64 20 70 61 67 65 73 20 66 72   unused pages fr
05b0: 6f 6d 20 6f 74 68 65 72 20 50 43 61 63 68 65 73  om other PCaches
05c0: 29 20 62 75 74 20 69 74 20 61 6c 73 6f 20 6f 70  ) but it also op
05d0: 65 72 61 74 65 73 20 77 69 74 68 6f 75 74 20 61  erates without a
05e0: 20 6d 75 74 65 78 2c 0a 2a 2a 20 61 6e 64 20 69   mutex,.** and i
05f0: 73 20 74 68 65 72 65 66 6f 72 65 20 6f 66 74 65  s therefore ofte
0600: 6e 20 66 61 73 74 65 72 2e 20 20 4d 6f 64 65 20  n faster.  Mode 
0610: 32 20 72 65 71 75 69 72 65 73 20 61 20 6d 75 74  2 requires a mut
0620: 65 78 20 69 6e 20 6f 72 64 65 72 20 74 6f 20 62  ex in order to b
0630: 65 0a 2a 2a 20 74 68 72 65 61 64 73 61 66 65 2c  e.** threadsafe,
0640: 20 62 75 74 20 72 65 63 79 63 6c 65 73 20 70 61   but recycles pa
0650: 67 65 73 20 6d 6f 72 65 20 65 66 66 69 63 69 65  ges more efficie
0660: 6e 74 6c 79 2e 0a 2a 2a 0a 2a 2a 20 46 6f 72 20  ntly..**.** For 
0670: 6d 6f 64 65 20 28 31 29 2c 20 50 47 72 6f 75 70  mode (1), PGroup
0680: 2e 6d 75 74 65 78 20 69 73 20 4e 55 4c 4c 2e 20  .mutex is NULL. 
0690: 20 46 6f 72 20 6d 6f 64 65 20 28 32 29 20 74 68   For mode (2) th
06a0: 65 72 65 20 69 73 20 6f 6e 6c 79 20 61 20 73 69  ere is only a si
06b0: 6e 67 6c 65 0a 2a 2a 20 50 47 72 6f 75 70 20 77  ngle.** PGroup w
06c0: 68 69 63 68 20 69 73 20 74 68 65 20 70 63 61 63  hich is the pcac
06d0: 68 65 31 2e 67 72 70 20 67 6c 6f 62 61 6c 20 76  he1.grp global v
06e0: 61 72 69 61 62 6c 65 20 61 6e 64 20 69 74 73 20  ariable and its 
06f0: 6d 75 74 65 78 20 69 73 0a 2a 2a 20 53 51 4c 49  mutex is.** SQLI
0700: 54 45 5f 4d 55 54 45 58 5f 53 54 41 54 49 43 5f  TE_MUTEX_STATIC_
0710: 4c 52 55 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 50  LRU..*/.struct P
0720: 47 72 6f 75 70 20 7b 0a 20 20 73 71 6c 69 74 65  Group {.  sqlite
0730: 33 5f 6d 75 74 65 78 20 2a 6d 75 74 65 78 3b 20  3_mutex *mutex; 
0740: 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 55 54 45           /* MUTE
0750: 58 5f 53 54 41 54 49 43 5f 4c 52 55 20 6f 72 20  X_STATIC_LRU or 
0760: 4e 55 4c 4c 20 2a 2f 0a 20 20 75 6e 73 69 67 6e  NULL */.  unsign
0770: 65 64 20 69 6e 74 20 6e 4d 61 78 50 61 67 65 3b  ed int nMaxPage;
0780: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 75 6d 20           /* Sum 
0790: 6f 66 20 6e 4d 61 78 20 66 6f 72 20 70 75 72 67  of nMax for purg
07a0: 65 61 62 6c 65 20 63 61 63 68 65 73 20 2a 2f 0a  eable caches */.
07b0: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e    unsigned int n
07c0: 4d 69 6e 50 61 67 65 3b 20 20 20 20 20 20 20 20  MinPage;        
07d0: 20 2f 2a 20 53 75 6d 20 6f 66 20 6e 4d 69 6e 20   /* Sum of nMin 
07e0: 66 6f 72 20 70 75 72 67 65 61 62 6c 65 20 63 61  for purgeable ca
07f0: 63 68 65 73 20 2a 2f 0a 20 20 75 6e 73 69 67 6e  ches */.  unsign
0800: 65 64 20 69 6e 74 20 6d 78 50 69 6e 6e 65 64 3b  ed int mxPinned;
0810: 20 20 20 20 20 20 20 20 20 2f 2a 20 6e 4d 61 78           /* nMax
0820: 70 61 67 65 20 2b 20 31 30 20 2d 20 6e 4d 69 6e  page + 10 - nMin
0830: 50 61 67 65 20 2a 2f 0a 20 20 75 6e 73 69 67 6e  Page */.  unsign
0840: 65 64 20 69 6e 74 20 6e 43 75 72 72 65 6e 74 50  ed int nCurrentP
0850: 61 67 65 3b 20 20 20 20 20 2f 2a 20 4e 75 6d 62  age;     /* Numb
0860: 65 72 20 6f 66 20 70 75 72 67 65 61 62 6c 65 20  er of purgeable 
0870: 70 61 67 65 73 20 61 6c 6c 6f 63 61 74 65 64 20  pages allocated 
0880: 2a 2f 0a 20 20 50 67 48 64 72 31 20 2a 70 4c 72  */.  PgHdr1 *pLr
0890: 75 48 65 61 64 2c 20 2a 70 4c 72 75 54 61 69 6c  uHead, *pLruTail
08a0: 3b 20 20 20 2f 2a 20 4c 52 55 20 6c 69 73 74 20  ;   /* LRU list 
08b0: 6f 66 20 75 6e 70 69 6e 6e 65 64 20 70 61 67 65  of unpinned page
08c0: 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 20 45 61 63 68  s */.};../* Each
08d0: 20 70 61 67 65 20 63 61 63 68 65 20 69 73 20 61   page cache is a
08e0: 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68  n instance of th
08f0: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6f 62 6a 65  e following obje
0900: 63 74 2e 20 20 45 76 65 72 79 0a 2a 2a 20 6f 70  ct.  Every.** op
0910: 65 6e 20 64 61 74 61 62 61 73 65 20 66 69 6c 65  en database file
0920: 20 28 69 6e 63 6c 75 64 69 6e 67 20 65 61 63 68   (including each
0930: 20 69 6e 2d 6d 65 6d 6f 72 79 20 64 61 74 61 62   in-memory datab
0940: 61 73 65 20 61 6e 64 20 65 61 63 68 0a 2a 2a 20  ase and each.** 
0950: 74 65 6d 70 6f 72 61 72 79 20 6f 72 20 74 72 61  temporary or tra
0960: 6e 73 69 65 6e 74 20 64 61 74 61 62 61 73 65 29  nsient database)
0970: 20 68 61 73 20 61 20 73 69 6e 67 6c 65 20 70 61   has a single pa
0980: 67 65 20 63 61 63 68 65 20 77 68 69 63 68 0a 2a  ge cache which.*
0990: 2a 20 69 73 20 61 6e 20 69 6e 73 74 61 6e 63 65  * is an instance
09a0: 20 6f 66 20 74 68 69 73 20 6f 62 6a 65 63 74 2e   of this object.
09b0: 0a 2a 2a 0a 2a 2a 20 50 6f 69 6e 74 65 72 73 20  .**.** Pointers 
09c0: 74 6f 20 73 74 72 75 63 74 75 72 65 73 20 6f 66  to structures of
09d0: 20 74 68 69 73 20 74 79 70 65 20 61 72 65 20 63   this type are c
09e0: 61 73 74 20 61 6e 64 20 72 65 74 75 72 6e 65 64  ast and returned
09f0: 20 61 73 20 0a 2a 2a 20 6f 70 61 71 75 65 20 73   as .** opaque s
0a00: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2a 20 68  qlite3_pcache* h
0a10: 61 6e 64 6c 65 73 2e 0a 2a 2f 0a 73 74 72 75 63  andles..*/.struc
0a20: 74 20 50 43 61 63 68 65 31 20 7b 0a 20 20 2f 2a  t PCache1 {.  /*
0a30: 20 43 61 63 68 65 20 63 6f 6e 66 69 67 75 72 61   Cache configura
0a40: 74 69 6f 6e 20 70 61 72 61 6d 65 74 65 72 73 2e  tion parameters.
0a50: 20 50 61 67 65 20 73 69 7a 65 20 28 73 7a 50 61   Page size (szPa
0a60: 67 65 29 20 61 6e 64 20 74 68 65 20 70 75 72 67  ge) and the purg
0a70: 65 61 62 6c 65 0a 20 20 2a 2a 20 66 6c 61 67 20  eable.  ** flag 
0a80: 28 62 50 75 72 67 65 61 62 6c 65 29 20 61 72 65  (bPurgeable) are
0a90: 20 73 65 74 20 77 68 65 6e 20 74 68 65 20 63 61   set when the ca
0aa0: 63 68 65 20 69 73 20 63 72 65 61 74 65 64 2e 20  che is created. 
0ab0: 6e 4d 61 78 20 6d 61 79 20 62 65 20 0a 20 20 2a  nMax may be .  *
0ac0: 2a 20 6d 6f 64 69 66 69 65 64 20 61 74 20 61 6e  * modified at an
0ad0: 79 20 74 69 6d 65 20 62 79 20 61 20 63 61 6c 6c  y time by a call
0ae0: 20 74 6f 20 74 68 65 20 70 63 61 63 68 65 31 43   to the pcache1C
0af0: 61 63 68 65 73 69 7a 65 28 29 20 6d 65 74 68 6f  achesize() metho
0b00: 64 2e 0a 20 20 2a 2a 20 54 68 65 20 50 47 72 6f  d..  ** The PGro
0b10: 75 70 20 6d 75 74 65 78 20 6d 75 73 74 20 62 65  up mutex must be
0b20: 20 68 65 6c 64 20 77 68 65 6e 20 61 63 63 65 73   held when acces
0b30: 73 69 6e 67 20 6e 4d 61 78 2e 0a 20 20 2a 2f 0a  sing nMax..  */.
0b40: 20 20 50 47 72 6f 75 70 20 2a 70 47 72 6f 75 70    PGroup *pGroup
0b50: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
0b60: 20 20 20 20 20 20 2f 2a 20 50 47 72 6f 75 70 20        /* PGroup 
0b70: 74 68 69 73 20 63 61 63 68 65 20 62 65 6c 6f 6e  this cache belon
0b80: 67 73 20 74 6f 20 2a 2f 0a 20 20 69 6e 74 20 73  gs to */.  int s
0b90: 7a 50 61 67 65 3b 20 20 20 20 20 20 20 20 20 20  zPage;          
0ba0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0bb0: 2a 20 53 69 7a 65 20 6f 66 20 61 6c 6c 6f 63 61  * Size of alloca
0bc0: 74 65 64 20 70 61 67 65 73 20 69 6e 20 62 79 74  ted pages in byt
0bd0: 65 73 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 45 78  es */.  int szEx
0be0: 74 72 61 3b 20 20 20 20 20 20 20 20 20 20 20 20  tra;            
0bf0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
0c00: 69 7a 65 20 6f 66 20 65 78 74 72 61 20 73 70 61  ize of extra spa
0c10: 63 65 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20  ce in bytes */. 
0c20: 20 69 6e 74 20 62 50 75 72 67 65 61 62 6c 65 3b   int bPurgeable;
0c30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c40: 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20       /* True if 
0c50: 63 61 63 68 65 20 69 73 20 70 75 72 67 65 61 62  cache is purgeab
0c60: 6c 65 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64  le */.  unsigned
0c70: 20 69 6e 74 20 6e 4d 69 6e 3b 20 20 20 20 20 20   int nMin;      
0c80: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d              /* M
0c90: 69 6e 69 6d 75 6d 20 6e 75 6d 62 65 72 20 6f 66  inimum number of
0ca0: 20 70 61 67 65 73 20 72 65 73 65 72 76 65 64 20   pages reserved 
0cb0: 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e  */.  unsigned in
0cc0: 74 20 6e 4d 61 78 3b 20 20 20 20 20 20 20 20 20  t nMax;         
0cd0: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6e 66           /* Conf
0ce0: 69 67 75 72 65 64 20 22 63 61 63 68 65 5f 73 69  igured "cache_si
0cf0: 7a 65 22 20 76 61 6c 75 65 20 2a 2f 0a 20 20 75  ze" value */.  u
0d00: 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 39 30 70  nsigned int n90p
0d10: 63 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ct;             
0d20: 20 20 20 2f 2a 20 6e 4d 61 78 2a 39 2f 31 30 20     /* nMax*9/10 
0d30: 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e  */.  unsigned in
0d40: 74 20 69 4d 61 78 4b 65 79 3b 20 20 20 20 20 20  t iMaxKey;      
0d50: 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 61 72 67           /* Larg
0d60: 65 73 74 20 6b 65 79 20 73 65 65 6e 20 73 69 6e  est key seen sin
0d70: 63 65 20 78 54 72 75 6e 63 61 74 65 28 29 20 2a  ce xTruncate() *
0d80: 2f 0a 0a 20 20 2f 2a 20 48 61 73 68 20 74 61 62  /..  /* Hash tab
0d90: 6c 65 20 6f 66 20 61 6c 6c 20 70 61 67 65 73 2e  le of all pages.
0da0: 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 76   The following v
0db0: 61 72 69 61 62 6c 65 73 20 6d 61 79 20 6f 6e 6c  ariables may onl
0dc0: 79 20 62 65 20 61 63 63 65 73 73 65 64 0a 20 20  y be accessed.  
0dd0: 2a 2a 20 77 68 65 6e 20 74 68 65 20 61 63 63 65  ** when the acce
0de0: 73 73 6f 72 20 69 73 20 68 6f 6c 64 69 6e 67 20  ssor is holding 
0df0: 74 68 65 20 50 47 72 6f 75 70 20 6d 75 74 65 78  the PGroup mutex
0e00: 2e 0a 20 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65  ..  */.  unsigne
0e10: 64 20 69 6e 74 20 6e 52 65 63 79 63 6c 61 62 6c  d int nRecyclabl
0e20: 65 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  e;           /* 
0e30: 4e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20  Number of pages 
0e40: 69 6e 20 74 68 65 20 4c 52 55 20 6c 69 73 74 20  in the LRU list 
0e50: 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e  */.  unsigned in
0e60: 74 20 6e 50 61 67 65 3b 20 20 20 20 20 20 20 20  t nPage;        
0e70: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 6f 74 61           /* Tota
0e80: 6c 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65  l number of page
0e90: 73 20 69 6e 20 61 70 48 61 73 68 20 2a 2f 0a 20  s in apHash */. 
0ea0: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 48   unsigned int nH
0eb0: 61 73 68 3b 20 20 20 20 20 20 20 20 20 20 20 20  ash;            
0ec0: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
0ed0: 66 20 73 6c 6f 74 73 20 69 6e 20 61 70 48 61 73  f slots in apHas
0ee0: 68 5b 5d 20 2a 2f 0a 20 20 50 67 48 64 72 31 20  h[] */.  PgHdr1 
0ef0: 2a 2a 61 70 48 61 73 68 3b 20 20 20 20 20 20 20  **apHash;       
0f00: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0f10: 48 61 73 68 20 74 61 62 6c 65 20 66 6f 72 20 66  Hash table for f
0f20: 61 73 74 20 6c 6f 6f 6b 75 70 20 62 79 20 6b 65  ast lookup by ke
0f30: 79 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 45  y */.};../*.** E
0f40: 61 63 68 20 63 61 63 68 65 20 65 6e 74 72 79 20  ach cache entry 
0f50: 69 73 20 72 65 70 72 65 73 65 6e 74 65 64 20 62  is represented b
0f60: 79 20 61 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66  y an instance of
0f70: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 0a   the following .
0f80: 2a 2a 20 73 74 72 75 63 74 75 72 65 2e 20 55 6e  ** structure. Un
0f90: 6c 65 73 73 20 53 51 4c 49 54 45 5f 50 43 41 43  less SQLITE_PCAC
0fa0: 48 45 5f 53 45 50 41 52 41 54 45 5f 48 45 41 44  HE_SEPARATE_HEAD
0fb0: 45 52 20 69 73 20 64 65 66 69 6e 65 64 2c 20 61  ER is defined, a
0fc0: 20 62 75 66 66 65 72 20 6f 66 0a 2a 2a 20 50 67   buffer of.** Pg
0fd0: 48 64 72 31 2e 70 43 61 63 68 65 2d 3e 73 7a 50  Hdr1.pCache->szP
0fe0: 61 67 65 20 62 79 74 65 73 20 69 73 20 61 6c 6c  age bytes is all
0ff0: 6f 63 61 74 65 64 20 64 69 72 65 63 74 6c 79 20  ocated directly 
1000: 62 65 66 6f 72 65 20 74 68 69 73 20 73 74 72 75  before this stru
1010: 63 74 75 72 65 20 0a 2a 2a 20 69 6e 20 6d 65 6d  cture .** in mem
1020: 6f 72 79 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 50  ory..*/.struct P
1030: 67 48 64 72 31 20 7b 0a 20 20 73 71 6c 69 74 65  gHdr1 {.  sqlite
1040: 33 5f 70 63 61 63 68 65 5f 70 61 67 65 20 70 61  3_pcache_page pa
1050: 67 65 3b 0a 20 20 75 6e 73 69 67 6e 65 64 20 69  ge;.  unsigned i
1060: 6e 74 20 69 4b 65 79 3b 20 20 20 20 20 20 20 20  nt iKey;        
1070: 20 20 20 20 20 2f 2a 20 4b 65 79 20 76 61 6c 75       /* Key valu
1080: 65 20 28 70 61 67 65 20 6e 75 6d 62 65 72 29 20  e (page number) 
1090: 2a 2f 0a 20 20 75 38 20 69 73 50 69 6e 6e 65 64  */.  u8 isPinned
10a0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
10b0: 20 20 20 20 2f 2a 20 50 61 67 65 20 69 6e 20 75      /* Page in u
10c0: 73 65 2c 20 6e 6f 74 20 6f 6e 20 74 68 65 20 4c  se, not on the L
10d0: 52 55 20 6c 69 73 74 20 2a 2f 0a 20 20 50 67 48  RU list */.  PgH
10e0: 64 72 31 20 2a 70 4e 65 78 74 3b 20 20 20 20 20  dr1 *pNext;     
10f0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
1100: 65 78 74 20 69 6e 20 68 61 73 68 20 74 61 62 6c  ext in hash tabl
1110: 65 20 63 68 61 69 6e 20 2a 2f 0a 20 20 50 43 61  e chain */.  PCa
1120: 63 68 65 31 20 2a 70 43 61 63 68 65 3b 20 20 20  che1 *pCache;   
1130: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
1140: 61 63 68 65 20 74 68 61 74 20 63 75 72 72 65 6e  ache that curren
1150: 74 6c 79 20 6f 77 6e 73 20 74 68 69 73 20 70 61  tly owns this pa
1160: 67 65 20 2a 2f 0a 20 20 50 67 48 64 72 31 20 2a  ge */.  PgHdr1 *
1170: 70 4c 72 75 4e 65 78 74 3b 20 20 20 20 20 20 20  pLruNext;       
1180: 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 69         /* Next i
1190: 6e 20 4c 52 55 20 6c 69 73 74 20 6f 66 20 75 6e  n LRU list of un
11a0: 70 69 6e 6e 65 64 20 70 61 67 65 73 20 2a 2f 0a  pinned pages */.
11b0: 20 20 50 67 48 64 72 31 20 2a 70 4c 72 75 50 72    PgHdr1 *pLruPr
11c0: 65 76 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ev;             
11d0: 20 2f 2a 20 50 72 65 76 69 6f 75 73 20 69 6e 20   /* Previous in 
11e0: 4c 52 55 20 6c 69 73 74 20 6f 66 20 75 6e 70 69  LRU list of unpi
11f0: 6e 6e 65 64 20 70 61 67 65 73 20 2a 2f 0a 7d 3b  nned pages */.};
1200: 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 73 6c 6f  ../*.** Free slo
1210: 74 73 20 69 6e 20 74 68 65 20 61 6c 6c 6f 63 61  ts in the alloca
1220: 74 6f 72 20 75 73 65 64 20 74 6f 20 64 69 76 69  tor used to divi
1230: 64 65 20 75 70 20 74 68 65 20 62 75 66 66 65 72  de up the buffer
1240: 20 70 72 6f 76 69 64 65 64 20 75 73 69 6e 67 0a   provided using.
1250: 2a 2a 20 74 68 65 20 53 51 4c 49 54 45 5f 43 4f  ** the SQLITE_CO
1260: 4e 46 49 47 5f 50 41 47 45 43 41 43 48 45 20 6d  NFIG_PAGECACHE m
1270: 65 63 68 61 6e 69 73 6d 2e 0a 2a 2f 0a 73 74 72  echanism..*/.str
1280: 75 63 74 20 50 67 46 72 65 65 73 6c 6f 74 20 7b  uct PgFreeslot {
1290: 0a 20 20 50 67 46 72 65 65 73 6c 6f 74 20 2a 70  .  PgFreeslot *p
12a0: 4e 65 78 74 3b 20 20 2f 2a 20 4e 65 78 74 20 66  Next;  /* Next f
12b0: 72 65 65 20 73 6c 6f 74 20 2a 2f 0a 7d 3b 0a 0a  ree slot */.};..
12c0: 2f 2a 0a 2a 2a 20 47 6c 6f 62 61 6c 20 64 61 74  /*.** Global dat
12d0: 61 20 75 73 65 64 20 62 79 20 74 68 69 73 20 63  a used by this c
12e0: 61 63 68 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ache..*/.static 
12f0: 53 51 4c 49 54 45 5f 57 53 44 20 73 74 72 75 63  SQLITE_WSD struc
1300: 74 20 50 43 61 63 68 65 47 6c 6f 62 61 6c 20 7b  t PCacheGlobal {
1310: 0a 20 20 50 47 72 6f 75 70 20 67 72 70 3b 20 20  .  PGroup grp;  
1320: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1330: 20 20 2f 2a 20 54 68 65 20 67 6c 6f 62 61 6c 20    /* The global 
1340: 50 47 72 6f 75 70 20 66 6f 72 20 6d 6f 64 65 20  PGroup for mode 
1350: 28 32 29 20 2a 2f 0a 0a 20 20 2f 2a 20 56 61 72  (2) */..  /* Var
1360: 69 61 62 6c 65 73 20 72 65 6c 61 74 65 64 20 74  iables related t
1370: 6f 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f  o SQLITE_CONFIG_
1380: 50 41 47 45 43 41 43 48 45 20 73 65 74 74 69 6e  PAGECACHE settin
1390: 67 73 2e 20 20 54 68 65 0a 20 20 2a 2a 20 73 7a  gs.  The.  ** sz
13a0: 53 6c 6f 74 2c 20 6e 53 6c 6f 74 2c 20 70 53 74  Slot, nSlot, pSt
13b0: 61 72 74 2c 20 70 45 6e 64 2c 20 6e 52 65 73 65  art, pEnd, nRese
13c0: 72 76 65 2c 20 61 6e 64 20 69 73 49 6e 69 74 20  rve, and isInit 
13d0: 76 61 6c 75 65 73 20 61 72 65 20 61 6c 6c 0a 20  values are all. 
13e0: 20 2a 2a 20 66 69 78 65 64 20 61 74 20 73 71 6c   ** fixed at sql
13f0: 69 74 65 33 5f 69 6e 69 74 69 61 6c 69 7a 65 28  ite3_initialize(
1400: 29 20 74 69 6d 65 20 61 6e 64 20 64 6f 20 6e 6f  ) time and do no
1410: 74 20 72 65 71 75 69 72 65 20 6d 75 74 65 78 20  t require mutex 
1420: 70 72 6f 74 65 63 74 69 6f 6e 2e 0a 20 20 2a 2a  protection..  **
1430: 20 54 68 65 20 6e 46 72 65 65 53 6c 6f 74 20 61   The nFreeSlot a
1440: 6e 64 20 70 46 72 65 65 20 76 61 6c 75 65 73 20  nd pFree values 
1450: 64 6f 20 72 65 71 75 69 72 65 20 6d 75 74 65 78  do require mutex
1460: 20 70 72 6f 74 65 63 74 69 6f 6e 2e 0a 20 20 2a   protection..  *
1470: 2f 0a 20 20 69 6e 74 20 69 73 49 6e 69 74 3b 20  /.  int isInit; 
1480: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1490: 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 69 6e     /* True if in
14a0: 69 74 69 61 6c 69 7a 65 64 20 2a 2f 0a 20 20 69  itialized */.  i
14b0: 6e 74 20 73 7a 53 6c 6f 74 3b 20 20 20 20 20 20  nt szSlot;      
14c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
14d0: 20 53 69 7a 65 20 6f 66 20 65 61 63 68 20 66 72   Size of each fr
14e0: 65 65 20 73 6c 6f 74 20 2a 2f 0a 20 20 69 6e 74  ee slot */.  int
14f0: 20 6e 53 6c 6f 74 3b 20 20 20 20 20 20 20 20 20   nSlot;         
1500: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
1510: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 63 61  he number of pca
1520: 63 68 65 20 73 6c 6f 74 73 20 2a 2f 0a 20 20 69  che slots */.  i
1530: 6e 74 20 6e 52 65 73 65 72 76 65 3b 20 20 20 20  nt nReserve;    
1540: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1550: 20 54 72 79 20 74 6f 20 6b 65 65 70 20 6e 46 72   Try to keep nFr
1560: 65 65 53 6c 6f 74 20 61 62 6f 76 65 20 74 68 69  eeSlot above thi
1570: 73 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 53 74  s */.  void *pSt
1580: 61 72 74 2c 20 2a 70 45 6e 64 3b 20 20 20 20 20  art, *pEnd;     
1590: 20 20 20 20 20 20 2f 2a 20 42 6f 75 6e 64 73 20        /* Bounds 
15a0: 6f 66 20 70 61 67 65 63 61 63 68 65 20 6d 61 6c  of pagecache mal
15b0: 6c 6f 63 20 72 61 6e 67 65 20 2a 2f 0a 20 20 2f  loc range */.  /
15c0: 2a 20 41 62 6f 76 65 20 72 65 71 75 69 72 65 73  * Above requires
15d0: 20 6e 6f 20 6d 75 74 65 78 2e 20 20 55 73 65 20   no mutex.  Use 
15e0: 6d 75 74 65 78 20 62 65 6c 6f 77 20 66 6f 72 20  mutex below for 
15f0: 76 61 72 69 61 62 6c 65 20 74 68 61 74 20 66 6f  variable that fo
1600: 6c 6c 6f 77 2e 20 2a 2f 0a 20 20 73 71 6c 69 74  llow. */.  sqlit
1610: 65 33 5f 6d 75 74 65 78 20 2a 6d 75 74 65 78 3b  e3_mutex *mutex;
1620: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 75 74            /* Mut
1630: 65 78 20 66 6f 72 20 61 63 63 65 73 73 69 6e 67  ex for accessing
1640: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 3a 20   the following: 
1650: 2a 2f 0a 20 20 50 67 46 72 65 65 73 6c 6f 74 20  */.  PgFreeslot 
1660: 2a 70 46 72 65 65 3b 20 20 20 20 20 20 20 20 20  *pFree;         
1670: 20 20 20 20 2f 2a 20 46 72 65 65 20 70 61 67 65      /* Free page
1680: 20 62 6c 6f 63 6b 73 20 2a 2f 0a 20 20 69 6e 74   blocks */.  int
1690: 20 6e 46 72 65 65 53 6c 6f 74 3b 20 20 20 20 20   nFreeSlot;     
16a0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
16b0: 75 6d 62 65 72 20 6f 66 20 75 6e 75 73 65 64 20  umber of unused 
16c0: 70 63 61 63 68 65 20 73 6c 6f 74 73 20 2a 2f 0a  pcache slots */.
16d0: 20 20 2f 2a 20 54 68 65 20 66 6f 6c 6c 6f 77 69    /* The followi
16e0: 6e 67 20 76 61 6c 75 65 20 72 65 71 75 69 72 65  ng value require
16f0: 73 20 61 20 6d 75 74 65 78 20 74 6f 20 63 68 61  s a mutex to cha
1700: 6e 67 65 2e 20 20 57 65 20 73 6b 69 70 20 74 68  nge.  We skip th
1710: 65 20 6d 75 74 65 78 20 6f 6e 0a 20 20 2a 2a 20  e mutex on.  ** 
1720: 72 65 61 64 69 6e 67 20 62 65 63 61 75 73 65 20  reading because 
1730: 28 31 29 20 6d 6f 73 74 20 70 6c 61 74 66 6f 72  (1) most platfor
1740: 6d 73 20 72 65 61 64 20 61 20 33 32 2d 62 69 74  ms read a 32-bit
1750: 20 69 6e 74 65 67 65 72 20 61 74 6f 6d 69 63 61   integer atomica
1760: 6c 6c 79 20 61 6e 64 0a 20 20 2a 2a 20 28 32 29  lly and.  ** (2)
1770: 20 65 76 65 6e 20 69 66 20 61 6e 20 69 6e 63 6f   even if an inco
1780: 72 72 65 63 74 20 76 61 6c 75 65 20 69 73 20 72  rrect value is r
1790: 65 61 64 2c 20 6e 6f 20 67 72 65 61 74 20 68 61  ead, no great ha
17a0: 72 6d 20 69 73 20 64 6f 6e 65 20 73 69 6e 63 65  rm is done since
17b0: 20 74 68 69 73 0a 20 20 2a 2a 20 69 73 20 72 65   this.  ** is re
17c0: 61 6c 6c 79 20 6a 75 73 74 20 61 6e 20 6f 70 74  ally just an opt
17d0: 69 6d 69 7a 61 74 69 6f 6e 2e 20 2a 2f 0a 20 20  imization. */.  
17e0: 69 6e 74 20 62 55 6e 64 65 72 50 72 65 73 73 75  int bUnderPressu
17f0: 72 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f  re;            /
1800: 2a 20 54 72 75 65 20 69 66 20 6c 6f 77 20 6f 6e  * True if low on
1810: 20 50 41 47 45 43 41 43 48 45 20 6d 65 6d 6f 72   PAGECACHE memor
1820: 79 20 2a 2f 0a 7d 20 70 63 61 63 68 65 31 5f 67  y */.} pcache1_g
1830: 3b 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c 20 63 6f 64  ;../*.** All cod
1840: 65 20 69 6e 20 74 68 69 73 20 66 69 6c 65 20 73  e in this file s
1850: 68 6f 75 6c 64 20 61 63 63 65 73 73 20 74 68 65  hould access the
1860: 20 67 6c 6f 62 61 6c 20 73 74 72 75 63 74 75 72   global structur
1870: 65 20 61 62 6f 76 65 20 76 69 61 20 74 68 65 0a  e above via the.
1880: 2a 2a 20 61 6c 69 61 73 20 22 70 63 61 63 68 65  ** alias "pcache
1890: 31 22 2e 20 54 68 69 73 20 65 6e 73 75 72 65 73  1". This ensures
18a0: 20 74 68 61 74 20 74 68 65 20 57 53 44 20 65 6d   that the WSD em
18b0: 75 6c 61 74 69 6f 6e 20 69 73 20 75 73 65 64 20  ulation is used 
18c0: 77 68 65 6e 0a 2a 2a 20 63 6f 6d 70 69 6c 69 6e  when.** compilin
18d0: 67 20 66 6f 72 20 73 79 73 74 65 6d 73 20 74 68  g for systems th
18e0: 61 74 20 64 6f 20 6e 6f 74 20 73 75 70 70 6f 72  at do not suppor
18f0: 74 20 72 65 61 6c 20 57 53 44 2e 0a 2a 2f 0a 23  t real WSD..*/.#
1900: 64 65 66 69 6e 65 20 70 63 61 63 68 65 31 20 28  define pcache1 (
1910: 47 4c 4f 42 41 4c 28 73 74 72 75 63 74 20 50 43  GLOBAL(struct PC
1920: 61 63 68 65 47 6c 6f 62 61 6c 2c 20 70 63 61 63  acheGlobal, pcac
1930: 68 65 31 5f 67 29 29 0a 0a 2f 2a 0a 2a 2a 20 4d  he1_g))../*.** M
1940: 61 63 72 6f 73 20 74 6f 20 65 6e 74 65 72 20 61  acros to enter a
1950: 6e 64 20 6c 65 61 76 65 20 74 68 65 20 50 43 61  nd leave the PCa
1960: 63 68 65 20 4c 52 55 20 6d 75 74 65 78 2e 0a 2a  che LRU mutex..*
1970: 2f 0a 23 64 65 66 69 6e 65 20 70 63 61 63 68 65  /.#define pcache
1980: 31 45 6e 74 65 72 4d 75 74 65 78 28 58 29 20 73  1EnterMutex(X) s
1990: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e 74  qlite3_mutex_ent
19a0: 65 72 28 28 58 29 2d 3e 6d 75 74 65 78 29 0a 23  er((X)->mutex).#
19b0: 64 65 66 69 6e 65 20 70 63 61 63 68 65 31 4c 65  define pcache1Le
19c0: 61 76 65 4d 75 74 65 78 28 58 29 20 73 71 6c 69  aveMutex(X) sqli
19d0: 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28  te3_mutex_leave(
19e0: 28 58 29 2d 3e 6d 75 74 65 78 29 0a 0a 2f 2a 2a  (X)->mutex)../**
19f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1a00: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1a10: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1a20: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1a30: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a  ************/./*
1a40: 2a 2a 2a 2a 2a 2a 2a 20 50 61 67 65 20 41 6c 6c  ******* Page All
1a50: 6f 63 61 74 69 6f 6e 2f 53 51 4c 49 54 45 5f 43  ocation/SQLITE_C
1a60: 4f 4e 46 49 47 5f 50 43 41 43 48 45 20 52 65 6c  ONFIG_PCACHE Rel
1a70: 61 74 65 64 20 46 75 6e 63 74 69 6f 6e 73 20 2a  ated Functions *
1a80: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a  *************/..
1a90: 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  /*.** This funct
1aa0: 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 64 75  ion is called du
1ab0: 72 69 6e 67 20 69 6e 69 74 69 61 6c 69 7a 61 74  ring initializat
1ac0: 69 6f 6e 20 69 66 20 61 20 73 74 61 74 69 63 20  ion if a static 
1ad0: 62 75 66 66 65 72 20 69 73 20 0a 2a 2a 20 73 75  buffer is .** su
1ae0: 70 70 6c 69 65 64 20 74 6f 20 75 73 65 20 66 6f  pplied to use fo
1af0: 72 20 74 68 65 20 70 61 67 65 2d 63 61 63 68 65  r the page-cache
1b00: 20 62 79 20 70 61 73 73 69 6e 67 20 74 68 65 20   by passing the 
1b10: 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41  SQLITE_CONFIG_PA
1b20: 47 45 43 41 43 48 45 0a 2a 2a 20 76 65 72 62 20  GECACHE.** verb 
1b30: 74 6f 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69  to sqlite3_confi
1b40: 67 28 29 2e 20 50 61 72 61 6d 65 74 65 72 20 70  g(). Parameter p
1b50: 42 75 66 20 70 6f 69 6e 74 73 20 74 6f 20 61 6e  Buf points to an
1b60: 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 6c 61 72 67   allocation larg
1b70: 65 0a 2a 2a 20 65 6e 6f 75 67 68 20 74 6f 20 63  e.** enough to c
1b80: 6f 6e 74 61 69 6e 20 27 6e 27 20 62 75 66 66 65  ontain 'n' buffe
1b90: 72 73 20 6f 66 20 27 73 7a 27 20 62 79 74 65 73  rs of 'sz' bytes
1ba0: 20 65 61 63 68 2e 0a 2a 2a 0a 2a 2a 20 54 68 69   each..**.** Thi
1bb0: 73 20 72 6f 75 74 69 6e 65 20 69 73 20 63 61 6c  s routine is cal
1bc0: 6c 65 64 20 66 72 6f 6d 20 73 71 6c 69 74 65 33  led from sqlite3
1bd0: 5f 69 6e 69 74 69 61 6c 69 7a 65 28 29 20 61 6e  _initialize() an
1be0: 64 20 73 6f 20 69 74 20 69 73 20 67 75 61 72 61  d so it is guara
1bf0: 6e 74 65 65 64 0a 2a 2a 20 74 6f 20 62 65 20 73  nteed.** to be s
1c00: 65 72 69 61 6c 69 7a 65 64 20 61 6c 72 65 61 64  erialized alread
1c10: 79 2e 20 20 54 68 65 72 65 20 69 73 20 6e 6f 20  y.  There is no 
1c20: 6e 65 65 64 20 66 6f 72 20 66 75 72 74 68 65 72  need for further
1c30: 20 6d 75 74 65 78 69 6e 67 2e 0a 2a 2f 0a 76 6f   mutexing..*/.vo
1c40: 69 64 20 73 71 6c 69 74 65 33 50 43 61 63 68 65  id sqlite3PCache
1c50: 42 75 66 66 65 72 53 65 74 75 70 28 76 6f 69 64  BufferSetup(void
1c60: 20 2a 70 42 75 66 2c 20 69 6e 74 20 73 7a 2c 20   *pBuf, int sz, 
1c70: 69 6e 74 20 6e 29 7b 0a 20 20 69 66 28 20 70 63  int n){.  if( pc
1c80: 61 63 68 65 31 2e 69 73 49 6e 69 74 20 29 7b 0a  ache1.isInit ){.
1c90: 20 20 20 20 50 67 46 72 65 65 73 6c 6f 74 20 2a      PgFreeslot *
1ca0: 70 3b 0a 20 20 20 20 73 7a 20 3d 20 52 4f 55 4e  p;.    sz = ROUN
1cb0: 44 44 4f 57 4e 38 28 73 7a 29 3b 0a 20 20 20 20  DDOWN8(sz);.    
1cc0: 70 63 61 63 68 65 31 2e 73 7a 53 6c 6f 74 20 3d  pcache1.szSlot =
1cd0: 20 73 7a 3b 0a 20 20 20 20 70 63 61 63 68 65 31   sz;.    pcache1
1ce0: 2e 6e 53 6c 6f 74 20 3d 20 70 63 61 63 68 65 31  .nSlot = pcache1
1cf0: 2e 6e 46 72 65 65 53 6c 6f 74 20 3d 20 6e 3b 0a  .nFreeSlot = n;.
1d00: 20 20 20 20 70 63 61 63 68 65 31 2e 6e 52 65 73      pcache1.nRes
1d10: 65 72 76 65 20 3d 20 6e 3e 39 30 20 3f 20 31 30  erve = n>90 ? 10
1d20: 20 3a 20 28 6e 2f 31 30 20 2b 20 31 29 3b 0a 20   : (n/10 + 1);. 
1d30: 20 20 20 70 63 61 63 68 65 31 2e 70 53 74 61 72     pcache1.pStar
1d40: 74 20 3d 20 70 42 75 66 3b 0a 20 20 20 20 70 63  t = pBuf;.    pc
1d50: 61 63 68 65 31 2e 70 46 72 65 65 20 3d 20 30 3b  ache1.pFree = 0;
1d60: 0a 20 20 20 20 70 63 61 63 68 65 31 2e 62 55 6e  .    pcache1.bUn
1d70: 64 65 72 50 72 65 73 73 75 72 65 20 3d 20 30 3b  derPressure = 0;
1d80: 0a 20 20 20 20 77 68 69 6c 65 28 20 6e 2d 2d 20  .    while( n-- 
1d90: 29 7b 0a 20 20 20 20 20 20 70 20 3d 20 28 50 67  ){.      p = (Pg
1da0: 46 72 65 65 73 6c 6f 74 2a 29 70 42 75 66 3b 0a  Freeslot*)pBuf;.
1db0: 20 20 20 20 20 20 70 2d 3e 70 4e 65 78 74 20 3d        p->pNext =
1dc0: 20 70 63 61 63 68 65 31 2e 70 46 72 65 65 3b 0a   pcache1.pFree;.
1dd0: 20 20 20 20 20 20 70 63 61 63 68 65 31 2e 70 46        pcache1.pF
1de0: 72 65 65 20 3d 20 70 3b 0a 20 20 20 20 20 20 70  ree = p;.      p
1df0: 42 75 66 20 3d 20 28 76 6f 69 64 2a 29 26 28 28  Buf = (void*)&((
1e00: 63 68 61 72 2a 29 70 42 75 66 29 5b 73 7a 5d 3b  char*)pBuf)[sz];
1e10: 0a 20 20 20 20 7d 0a 20 20 20 20 70 63 61 63 68  .    }.    pcach
1e20: 65 31 2e 70 45 6e 64 20 3d 20 70 42 75 66 3b 0a  e1.pEnd = pBuf;.
1e30: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6c    }.}../*.** Mal
1e40: 6c 6f 63 20 66 75 6e 63 74 69 6f 6e 20 75 73 65  loc function use
1e50: 64 20 77 69 74 68 69 6e 20 74 68 69 73 20 66 69  d within this fi
1e60: 6c 65 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 73  le to allocate s
1e70: 70 61 63 65 20 66 72 6f 6d 20 74 68 65 20 62 75  pace from the bu
1e80: 66 66 65 72 0a 2a 2a 20 63 6f 6e 66 69 67 75 72  ffer.** configur
1e90: 65 64 20 75 73 69 6e 67 20 73 71 6c 69 74 65 33  ed using sqlite3
1ea0: 5f 63 6f 6e 66 69 67 28 53 51 4c 49 54 45 5f 43  _config(SQLITE_C
1eb0: 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48 45 29  ONFIG_PAGECACHE)
1ec0: 20 6f 70 74 69 6f 6e 2e 20 49 66 20 6e 6f 20 0a   option. If no .
1ed0: 2a 2a 20 73 75 63 68 20 62 75 66 66 65 72 20 65  ** such buffer e
1ee0: 78 69 73 74 73 20 6f 72 20 74 68 65 72 65 20 69  xists or there i
1ef0: 73 20 6e 6f 20 73 70 61 63 65 20 6c 65 66 74 20  s no space left 
1f00: 69 6e 20 69 74 2c 20 74 68 69 73 20 66 75 6e 63  in it, this func
1f10: 74 69 6f 6e 20 66 61 6c 6c 73 20 0a 2a 2a 20 62  tion falls .** b
1f20: 61 63 6b 20 74 6f 20 73 71 6c 69 74 65 33 4d 61  ack to sqlite3Ma
1f30: 6c 6c 6f 63 28 29 2e 0a 2a 2a 0a 2a 2a 20 4d 75  lloc()..**.** Mu
1f40: 6c 74 69 70 6c 65 20 74 68 72 65 61 64 73 20 63  ltiple threads c
1f50: 61 6e 20 72 75 6e 20 74 68 69 73 20 72 6f 75 74  an run this rout
1f60: 69 6e 65 20 61 74 20 74 68 65 20 73 61 6d 65 20  ine at the same 
1f70: 74 69 6d 65 2e 20 20 47 6c 6f 62 61 6c 20 76 61  time.  Global va
1f80: 72 69 61 62 6c 65 73 0a 2a 2a 20 69 6e 20 70 63  riables.** in pc
1f90: 61 63 68 65 31 20 6e 65 65 64 20 74 6f 20 62 65  ache1 need to be
1fa0: 20 70 72 6f 74 65 63 74 65 64 20 76 69 61 20 6d   protected via m
1fb0: 75 74 65 78 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  utex..*/.static 
1fc0: 76 6f 69 64 20 2a 70 63 61 63 68 65 31 41 6c 6c  void *pcache1All
1fd0: 6f 63 28 69 6e 74 20 6e 42 79 74 65 29 7b 0a 20  oc(int nByte){. 
1fe0: 20 76 6f 69 64 20 2a 70 20 3d 20 30 3b 0a 20 20   void *p = 0;.  
1ff0: 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f  assert( sqlite3_
2000: 6d 75 74 65 78 5f 6e 6f 74 68 65 6c 64 28 70 63  mutex_notheld(pc
2010: 61 63 68 65 31 2e 67 72 70 2e 6d 75 74 65 78 29  ache1.grp.mutex)
2020: 20 29 3b 0a 20 20 73 71 6c 69 74 65 33 53 74 61   );.  sqlite3Sta
2030: 74 75 73 53 65 74 28 53 51 4c 49 54 45 5f 53 54  tusSet(SQLITE_ST
2040: 41 54 55 53 5f 50 41 47 45 43 41 43 48 45 5f 53  ATUS_PAGECACHE_S
2050: 49 5a 45 2c 20 6e 42 79 74 65 29 3b 0a 20 20 69  IZE, nByte);.  i
2060: 66 28 20 6e 42 79 74 65 3c 3d 70 63 61 63 68 65  f( nByte<=pcache
2070: 31 2e 73 7a 53 6c 6f 74 20 29 7b 0a 20 20 20 20  1.szSlot ){.    
2080: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e  sqlite3_mutex_en
2090: 74 65 72 28 70 63 61 63 68 65 31 2e 6d 75 74 65  ter(pcache1.mute
20a0: 78 29 3b 0a 20 20 20 20 70 20 3d 20 28 50 67 48  x);.    p = (PgH
20b0: 64 72 31 20 2a 29 70 63 61 63 68 65 31 2e 70 46  dr1 *)pcache1.pF
20c0: 72 65 65 3b 0a 20 20 20 20 69 66 28 20 70 20 29  ree;.    if( p )
20d0: 7b 0a 20 20 20 20 20 20 70 63 61 63 68 65 31 2e  {.      pcache1.
20e0: 70 46 72 65 65 20 3d 20 70 63 61 63 68 65 31 2e  pFree = pcache1.
20f0: 70 46 72 65 65 2d 3e 70 4e 65 78 74 3b 0a 20 20  pFree->pNext;.  
2100: 20 20 20 20 70 63 61 63 68 65 31 2e 6e 46 72 65      pcache1.nFre
2110: 65 53 6c 6f 74 2d 2d 3b 0a 20 20 20 20 20 20 70  eSlot--;.      p
2120: 63 61 63 68 65 31 2e 62 55 6e 64 65 72 50 72 65  cache1.bUnderPre
2130: 73 73 75 72 65 20 3d 20 70 63 61 63 68 65 31 2e  ssure = pcache1.
2140: 6e 46 72 65 65 53 6c 6f 74 3c 70 63 61 63 68 65  nFreeSlot<pcache
2150: 31 2e 6e 52 65 73 65 72 76 65 3b 0a 20 20 20 20  1.nReserve;.    
2160: 20 20 61 73 73 65 72 74 28 20 70 63 61 63 68 65    assert( pcache
2170: 31 2e 6e 46 72 65 65 53 6c 6f 74 3e 3d 30 20 29  1.nFreeSlot>=0 )
2180: 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 53  ;.      sqlite3S
2190: 74 61 74 75 73 41 64 64 28 53 51 4c 49 54 45 5f  tatusAdd(SQLITE_
21a0: 53 54 41 54 55 53 5f 50 41 47 45 43 41 43 48 45  STATUS_PAGECACHE
21b0: 5f 55 53 45 44 2c 20 31 29 3b 0a 20 20 20 20 7d  _USED, 1);.    }
21c0: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 75 74  .    sqlite3_mut
21d0: 65 78 5f 6c 65 61 76 65 28 70 63 61 63 68 65 31  ex_leave(pcache1
21e0: 2e 6d 75 74 65 78 29 3b 0a 20 20 7d 0a 20 20 69  .mutex);.  }.  i
21f0: 66 28 20 70 3d 3d 30 20 29 7b 0a 20 20 20 20 2f  f( p==0 ){.    /
2200: 2a 20 4d 65 6d 6f 72 79 20 69 73 20 6e 6f 74 20  * Memory is not 
2210: 61 76 61 69 6c 61 62 6c 65 20 69 6e 20 74 68 65  available in the
2220: 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50   SQLITE_CONFIG_P
2230: 41 47 45 43 41 43 48 45 20 70 6f 6f 6c 2e 20 20  AGECACHE pool.  
2240: 47 65 74 0a 20 20 20 20 2a 2a 20 69 74 20 66 72  Get.    ** it fr
2250: 6f 6d 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63  om sqlite3Malloc
2260: 20 69 6e 73 74 65 61 64 2e 0a 20 20 20 20 2a 2f   instead..    */
2270: 0a 20 20 20 20 70 20 3d 20 73 71 6c 69 74 65 33  .    p = sqlite3
2280: 4d 61 6c 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 23  Malloc(nByte);.#
2290: 69 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 44 49  ifndef SQLITE_DI
22a0: 53 41 42 4c 45 5f 50 41 47 45 43 41 43 48 45 5f  SABLE_PAGECACHE_
22b0: 4f 56 45 52 46 4c 4f 57 5f 53 54 41 54 53 0a 20  OVERFLOW_STATS. 
22c0: 20 20 20 69 66 28 20 70 20 29 7b 0a 20 20 20 20     if( p ){.    
22d0: 20 20 69 6e 74 20 73 7a 20 3d 20 73 71 6c 69 74    int sz = sqlit
22e0: 65 33 4d 61 6c 6c 6f 63 53 69 7a 65 28 70 29 3b  e3MallocSize(p);
22f0: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 6d  .      sqlite3_m
2300: 75 74 65 78 5f 65 6e 74 65 72 28 70 63 61 63 68  utex_enter(pcach
2310: 65 31 2e 6d 75 74 65 78 29 3b 0a 20 20 20 20 20  e1.mutex);.     
2320: 20 73 71 6c 69 74 65 33 53 74 61 74 75 73 41 64   sqlite3StatusAd
2330: 64 28 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f  d(SQLITE_STATUS_
2340: 50 41 47 45 43 41 43 48 45 5f 4f 56 45 52 46 4c  PAGECACHE_OVERFL
2350: 4f 57 2c 20 73 7a 29 3b 0a 20 20 20 20 20 20 73  OW, sz);.      s
2360: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61  qlite3_mutex_lea
2370: 76 65 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78  ve(pcache1.mutex
2380: 29 3b 0a 20 20 20 20 7d 0a 23 65 6e 64 69 66 0a  );.    }.#endif.
2390: 20 20 20 20 73 71 6c 69 74 65 33 4d 65 6d 64 65      sqlite3Memde
23a0: 62 75 67 53 65 74 54 79 70 65 28 70 2c 20 4d 45  bugSetType(p, ME
23b0: 4d 54 59 50 45 5f 50 43 41 43 48 45 29 3b 0a 20  MTYPE_PCACHE);. 
23c0: 20 7d 0a 20 20 72 65 74 75 72 6e 20 70 3b 0a 7d   }.  return p;.}
23d0: 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61 6e 20  ../*.** Free an 
23e0: 61 6c 6c 6f 63 61 74 65 64 20 62 75 66 66 65 72  allocated buffer
23f0: 20 6f 62 74 61 69 6e 65 64 20 66 72 6f 6d 20 70   obtained from p
2400: 63 61 63 68 65 31 41 6c 6c 6f 63 28 29 2e 0a 2a  cache1Alloc()..*
2410: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 70 63 61  /.static int pca
2420: 63 68 65 31 46 72 65 65 28 76 6f 69 64 20 2a 70  che1Free(void *p
2430: 29 7b 0a 20 20 69 6e 74 20 6e 46 72 65 65 64 20  ){.  int nFreed 
2440: 3d 20 30 3b 0a 20 20 69 66 28 20 70 3d 3d 30 20  = 0;.  if( p==0 
2450: 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 69 66  ) return 0;.  if
2460: 28 20 70 3e 3d 70 63 61 63 68 65 31 2e 70 53 74  ( p>=pcache1.pSt
2470: 61 72 74 20 26 26 20 70 3c 70 63 61 63 68 65 31  art && p<pcache1
2480: 2e 70 45 6e 64 20 29 7b 0a 20 20 20 20 50 67 46  .pEnd ){.    PgF
2490: 72 65 65 73 6c 6f 74 20 2a 70 53 6c 6f 74 3b 0a  reeslot *pSlot;.
24a0: 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65      sqlite3_mute
24b0: 78 5f 65 6e 74 65 72 28 70 63 61 63 68 65 31 2e  x_enter(pcache1.
24c0: 6d 75 74 65 78 29 3b 0a 20 20 20 20 73 71 6c 69  mutex);.    sqli
24d0: 74 65 33 53 74 61 74 75 73 41 64 64 28 53 51 4c  te3StatusAdd(SQL
24e0: 49 54 45 5f 53 54 41 54 55 53 5f 50 41 47 45 43  ITE_STATUS_PAGEC
24f0: 41 43 48 45 5f 55 53 45 44 2c 20 2d 31 29 3b 0a  ACHE_USED, -1);.
2500: 20 20 20 20 70 53 6c 6f 74 20 3d 20 28 50 67 46      pSlot = (PgF
2510: 72 65 65 73 6c 6f 74 2a 29 70 3b 0a 20 20 20 20  reeslot*)p;.    
2520: 70 53 6c 6f 74 2d 3e 70 4e 65 78 74 20 3d 20 70  pSlot->pNext = p
2530: 63 61 63 68 65 31 2e 70 46 72 65 65 3b 0a 20 20  cache1.pFree;.  
2540: 20 20 70 63 61 63 68 65 31 2e 70 46 72 65 65 20    pcache1.pFree 
2550: 3d 20 70 53 6c 6f 74 3b 0a 20 20 20 20 70 63 61  = pSlot;.    pca
2560: 63 68 65 31 2e 6e 46 72 65 65 53 6c 6f 74 2b 2b  che1.nFreeSlot++
2570: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 62 55  ;.    pcache1.bU
2580: 6e 64 65 72 50 72 65 73 73 75 72 65 20 3d 20 70  nderPressure = p
2590: 63 61 63 68 65 31 2e 6e 46 72 65 65 53 6c 6f 74  cache1.nFreeSlot
25a0: 3c 70 63 61 63 68 65 31 2e 6e 52 65 73 65 72 76  <pcache1.nReserv
25b0: 65 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70  e;.    assert( p
25c0: 63 61 63 68 65 31 2e 6e 46 72 65 65 53 6c 6f 74  cache1.nFreeSlot
25d0: 3c 3d 70 63 61 63 68 65 31 2e 6e 53 6c 6f 74 20  <=pcache1.nSlot 
25e0: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 6d  );.    sqlite3_m
25f0: 75 74 65 78 5f 6c 65 61 76 65 28 70 63 61 63 68  utex_leave(pcach
2600: 65 31 2e 6d 75 74 65 78 29 3b 0a 20 20 7d 65 6c  e1.mutex);.  }el
2610: 73 65 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20  se{.    assert( 
2620: 73 71 6c 69 74 65 33 4d 65 6d 64 65 62 75 67 48  sqlite3MemdebugH
2630: 61 73 54 79 70 65 28 70 2c 20 4d 45 4d 54 59 50  asType(p, MEMTYP
2640: 45 5f 50 43 41 43 48 45 29 20 29 3b 0a 20 20 20  E_PCACHE) );.   
2650: 20 73 71 6c 69 74 65 33 4d 65 6d 64 65 62 75 67   sqlite3Memdebug
2660: 53 65 74 54 79 70 65 28 70 2c 20 4d 45 4d 54 59  SetType(p, MEMTY
2670: 50 45 5f 48 45 41 50 29 3b 0a 20 20 20 20 6e 46  PE_HEAP);.    nF
2680: 72 65 65 64 20 3d 20 73 71 6c 69 74 65 33 4d 61  reed = sqlite3Ma
2690: 6c 6c 6f 63 53 69 7a 65 28 70 29 3b 0a 23 69 66  llocSize(p);.#if
26a0: 6e 64 65 66 20 53 51 4c 49 54 45 5f 44 49 53 41  ndef SQLITE_DISA
26b0: 42 4c 45 5f 50 41 47 45 43 41 43 48 45 5f 4f 56  BLE_PAGECACHE_OV
26c0: 45 52 46 4c 4f 57 5f 53 54 41 54 53 0a 20 20 20  ERFLOW_STATS.   
26d0: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65   sqlite3_mutex_e
26e0: 6e 74 65 72 28 70 63 61 63 68 65 31 2e 6d 75 74  nter(pcache1.mut
26f0: 65 78 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  ex);.    sqlite3
2700: 53 74 61 74 75 73 41 64 64 28 53 51 4c 49 54 45  StatusAdd(SQLITE
2710: 5f 53 54 41 54 55 53 5f 50 41 47 45 43 41 43 48  _STATUS_PAGECACH
2720: 45 5f 4f 56 45 52 46 4c 4f 57 2c 20 2d 6e 46 72  E_OVERFLOW, -nFr
2730: 65 65 64 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  eed);.    sqlite
2740: 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 70 63  3_mutex_leave(pc
2750: 61 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a 23 65  ache1.mutex);.#e
2760: 6e 64 69 66 0a 20 20 20 20 73 71 6c 69 74 65 33  ndif.    sqlite3
2770: 5f 66 72 65 65 28 70 29 3b 0a 20 20 7d 0a 20 20  _free(p);.  }.  
2780: 72 65 74 75 72 6e 20 6e 46 72 65 65 64 3b 0a 7d  return nFreed;.}
2790: 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f  ..#ifdef SQLITE_
27a0: 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41  ENABLE_MEMORY_MA
27b0: 4e 41 47 45 4d 45 4e 54 0a 2f 2a 0a 2a 2a 20 52  NAGEMENT./*.** R
27c0: 65 74 75 72 6e 20 74 68 65 20 73 69 7a 65 20 6f  eturn the size o
27d0: 66 20 61 20 70 63 61 63 68 65 20 61 6c 6c 6f 63  f a pcache alloc
27e0: 61 74 69 6f 6e 0a 2a 2f 0a 73 74 61 74 69 63 20  ation.*/.static 
27f0: 69 6e 74 20 70 63 61 63 68 65 31 4d 65 6d 53 69  int pcache1MemSi
2800: 7a 65 28 76 6f 69 64 20 2a 70 29 7b 0a 20 20 69  ze(void *p){.  i
2810: 66 28 20 70 3e 3d 70 63 61 63 68 65 31 2e 70 53  f( p>=pcache1.pS
2820: 74 61 72 74 20 26 26 20 70 3c 70 63 61 63 68 65  tart && p<pcache
2830: 31 2e 70 45 6e 64 20 29 7b 0a 20 20 20 20 72 65  1.pEnd ){.    re
2840: 74 75 72 6e 20 70 63 61 63 68 65 31 2e 73 7a 53  turn pcache1.szS
2850: 6c 6f 74 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  lot;.  }else{.  
2860: 20 20 69 6e 74 20 69 53 69 7a 65 3b 0a 20 20 20    int iSize;.   
2870: 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33   assert( sqlite3
2880: 4d 65 6d 64 65 62 75 67 48 61 73 54 79 70 65 28  MemdebugHasType(
2890: 70 2c 20 4d 45 4d 54 59 50 45 5f 50 43 41 43 48  p, MEMTYPE_PCACH
28a0: 45 29 20 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  E) );.    sqlite
28b0: 33 4d 65 6d 64 65 62 75 67 53 65 74 54 79 70 65  3MemdebugSetType
28c0: 28 70 2c 20 4d 45 4d 54 59 50 45 5f 48 45 41 50  (p, MEMTYPE_HEAP
28d0: 29 3b 0a 20 20 20 20 69 53 69 7a 65 20 3d 20 73  );.    iSize = s
28e0: 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 53 69 7a 65  qlite3MallocSize
28f0: 28 70 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  (p);.    sqlite3
2900: 4d 65 6d 64 65 62 75 67 53 65 74 54 79 70 65 28  MemdebugSetType(
2910: 70 2c 20 4d 45 4d 54 59 50 45 5f 50 43 41 43 48  p, MEMTYPE_PCACH
2920: 45 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 69  E);.    return i
2930: 53 69 7a 65 3b 0a 20 20 7d 0a 7d 0a 23 65 6e 64  Size;.  }.}.#end
2940: 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f 45 4e 41  if /* SQLITE_ENA
2950: 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47  BLE_MEMORY_MANAG
2960: 45 4d 45 4e 54 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20  EMENT */../*.** 
2970: 41 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 70  Allocate a new p
2980: 61 67 65 20 6f 62 6a 65 63 74 20 69 6e 69 74 69  age object initi
2990: 61 6c 6c 79 20 61 73 73 6f 63 69 61 74 65 64 20  ally associated 
29a0: 77 69 74 68 20 63 61 63 68 65 20 70 43 61 63 68  with cache pCach
29b0: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 50 67 48  e..*/.static PgH
29c0: 64 72 31 20 2a 70 63 61 63 68 65 31 41 6c 6c 6f  dr1 *pcache1Allo
29d0: 63 50 61 67 65 28 50 43 61 63 68 65 31 20 2a 70  cPage(PCache1 *p
29e0: 43 61 63 68 65 29 7b 0a 20 20 50 67 48 64 72 31  Cache){.  PgHdr1
29f0: 20 2a 70 20 3d 20 30 3b 0a 20 20 76 6f 69 64 20   *p = 0;.  void 
2a00: 2a 70 50 67 3b 0a 0a 20 20 2f 2a 20 54 68 65 20  *pPg;..  /* The 
2a10: 67 72 6f 75 70 20 6d 75 74 65 78 20 6d 75 73 74  group mutex must
2a20: 20 62 65 20 72 65 6c 65 61 73 65 64 20 62 65 66   be released bef
2a30: 6f 72 65 20 70 63 61 63 68 65 31 41 6c 6c 6f 63  ore pcache1Alloc
2a40: 28 29 20 69 73 20 63 61 6c 6c 65 64 2e 20 54 68  () is called. Th
2a50: 69 73 0a 20 20 2a 2a 20 69 73 20 62 65 63 61 75  is.  ** is becau
2a60: 73 65 20 69 74 20 6d 61 79 20 63 61 6c 6c 20 73  se it may call s
2a70: 71 6c 69 74 65 33 5f 72 65 6c 65 61 73 65 5f 6d  qlite3_release_m
2a80: 65 6d 6f 72 79 28 29 2c 20 77 68 69 63 68 20 61  emory(), which a
2a90: 73 73 75 6d 65 73 20 74 68 61 74 20 0a 20 20 2a  ssumes that .  *
2aa0: 2a 20 74 68 69 73 20 6d 75 74 65 78 20 69 73 20  * this mutex is 
2ab0: 6e 6f 74 20 68 65 6c 64 2e 20 2a 2f 0a 20 20 61  not held. */.  a
2ac0: 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d  ssert( sqlite3_m
2ad0: 75 74 65 78 5f 68 65 6c 64 28 70 43 61 63 68 65  utex_held(pCache
2ae0: 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78 29  ->pGroup->mutex)
2af0: 20 29 3b 0a 20 20 70 63 61 63 68 65 31 4c 65 61   );.  pcache1Lea
2b00: 76 65 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e  veMutex(pCache->
2b10: 70 47 72 6f 75 70 29 3b 0a 23 69 66 64 65 66 20  pGroup);.#ifdef 
2b20: 53 51 4c 49 54 45 5f 50 43 41 43 48 45 5f 53 45  SQLITE_PCACHE_SE
2b30: 50 41 52 41 54 45 5f 48 45 41 44 45 52 0a 20 20  PARATE_HEADER.  
2b40: 70 50 67 20 3d 20 70 63 61 63 68 65 31 41 6c 6c  pPg = pcache1All
2b50: 6f 63 28 70 43 61 63 68 65 2d 3e 73 7a 50 61 67  oc(pCache->szPag
2b60: 65 29 3b 0a 20 20 70 20 3d 20 73 71 6c 69 74 65  e);.  p = sqlite
2b70: 33 4d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 50  3Malloc(sizeof(P
2b80: 67 48 64 72 31 29 20 2b 20 70 43 61 63 68 65 2d  gHdr1) + pCache-
2b90: 3e 73 7a 45 78 74 72 61 29 3b 0a 20 20 69 66 28  >szExtra);.  if(
2ba0: 20 21 70 50 67 20 7c 7c 20 21 70 20 29 7b 0a 20   !pPg || !p ){. 
2bb0: 20 20 20 70 63 61 63 68 65 31 46 72 65 65 28 70     pcache1Free(p
2bc0: 50 67 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  Pg);.    sqlite3
2bd0: 5f 66 72 65 65 28 70 29 3b 0a 20 20 20 20 70 50  _free(p);.    pP
2be0: 67 20 3d 20 30 3b 0a 20 20 7d 0a 23 65 6c 73 65  g = 0;.  }.#else
2bf0: 0a 20 20 70 50 67 20 3d 20 70 63 61 63 68 65 31  .  pPg = pcache1
2c00: 41 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 50 67 48  Alloc(sizeof(PgH
2c10: 64 72 31 29 20 2b 20 70 43 61 63 68 65 2d 3e 73  dr1) + pCache->s
2c20: 7a 50 61 67 65 20 2b 20 70 43 61 63 68 65 2d 3e  zPage + pCache->
2c30: 73 7a 45 78 74 72 61 29 3b 0a 20 20 70 20 3d 20  szExtra);.  p = 
2c40: 28 50 67 48 64 72 31 20 2a 29 26 28 28 75 38 20  (PgHdr1 *)&((u8 
2c50: 2a 29 70 50 67 29 5b 70 43 61 63 68 65 2d 3e 73  *)pPg)[pCache->s
2c60: 7a 50 61 67 65 5d 3b 0a 23 65 6e 64 69 66 0a 20  zPage];.#endif. 
2c70: 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74   pcache1EnterMut
2c80: 65 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75  ex(pCache->pGrou
2c90: 70 29 3b 0a 0a 20 20 69 66 28 20 70 50 67 20 29  p);..  if( pPg )
2ca0: 7b 0a 20 20 20 20 70 2d 3e 70 61 67 65 2e 70 42  {.    p->page.pB
2cb0: 75 66 20 3d 20 70 50 67 3b 0a 20 20 20 20 70 2d  uf = pPg;.    p-
2cc0: 3e 70 61 67 65 2e 70 45 78 74 72 61 20 3d 20 26  >page.pExtra = &
2cd0: 70 5b 31 5d 3b 0a 20 20 20 20 69 66 28 20 70 43  p[1];.    if( pC
2ce0: 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65  ache->bPurgeable
2cf0: 20 29 7b 0a 20 20 20 20 20 20 70 43 61 63 68 65   ){.      pCache
2d00: 2d 3e 70 47 72 6f 75 70 2d 3e 6e 43 75 72 72 65  ->pGroup->nCurre
2d10: 6e 74 50 61 67 65 2b 2b 3b 0a 20 20 20 20 7d 0a  ntPage++;.    }.
2d20: 20 20 20 20 72 65 74 75 72 6e 20 70 3b 0a 20 20      return p;.  
2d30: 7d 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a  }.  return 0;.}.
2d40: 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61 20 70 61  ./*.** Free a pa
2d50: 67 65 20 6f 62 6a 65 63 74 20 61 6c 6c 6f 63 61  ge object alloca
2d60: 74 65 64 20 62 79 20 70 63 61 63 68 65 31 41 6c  ted by pcache1Al
2d70: 6c 6f 63 50 61 67 65 28 29 2e 0a 2a 2a 0a 2a 2a  locPage()..**.**
2d80: 20 54 68 65 20 70 6f 69 6e 74 65 72 20 69 73 20   The pointer is 
2d90: 61 6c 6c 6f 77 65 64 20 74 6f 20 62 65 20 4e 55  allowed to be NU
2da0: 4c 4c 2c 20 77 68 69 63 68 20 69 73 20 70 72 75  LL, which is pru
2db0: 64 65 6e 74 2e 20 20 42 75 74 20 69 74 20 74 75  dent.  But it tu
2dc0: 72 6e 73 20 6f 75 74 0a 2a 2a 20 74 68 61 74 20  rns out.** that 
2dd0: 74 68 65 20 63 75 72 72 65 6e 74 20 69 6d 70 6c  the current impl
2de0: 65 6d 65 6e 74 61 74 69 6f 6e 20 68 61 70 70 65  ementation happe
2df0: 6e 73 20 74 6f 20 6e 65 76 65 72 20 63 61 6c 6c  ns to never call
2e00: 20 74 68 69 73 20 72 6f 75 74 69 6e 65 0a 2a 2a   this routine.**
2e10: 20 77 69 74 68 20 61 20 4e 55 4c 4c 20 70 6f 69   with a NULL poi
2e20: 6e 74 65 72 2c 20 73 6f 20 77 65 20 6d 61 72 6b  nter, so we mark
2e30: 20 74 68 65 20 4e 55 4c 4c 20 74 65 73 74 20 77   the NULL test w
2e40: 69 74 68 20 41 4c 57 41 59 53 28 29 2e 0a 2a 2f  ith ALWAYS()..*/
2e50: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61  .static void pca
2e60: 63 68 65 31 46 72 65 65 50 61 67 65 28 50 67 48  che1FreePage(PgH
2e70: 64 72 31 20 2a 70 29 7b 0a 20 20 69 66 28 20 41  dr1 *p){.  if( A
2e80: 4c 57 41 59 53 28 70 29 20 29 7b 0a 20 20 20 20  LWAYS(p) ){.    
2e90: 50 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 20  PCache1 *pCache 
2ea0: 3d 20 70 2d 3e 70 43 61 63 68 65 3b 0a 20 20 20  = p->pCache;.   
2eb0: 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33   assert( sqlite3
2ec0: 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 2d 3e 70  _mutex_held(p->p
2ed0: 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 2d 3e 6d  Cache->pGroup->m
2ee0: 75 74 65 78 29 20 29 3b 0a 20 20 20 20 70 63 61  utex) );.    pca
2ef0: 63 68 65 31 46 72 65 65 28 70 2d 3e 70 61 67 65  che1Free(p->page
2f00: 2e 70 42 75 66 29 3b 0a 23 69 66 64 65 66 20 53  .pBuf);.#ifdef S
2f10: 51 4c 49 54 45 5f 50 43 41 43 48 45 5f 53 45 50  QLITE_PCACHE_SEP
2f20: 41 52 41 54 45 5f 48 45 41 44 45 52 0a 20 20 20  ARATE_HEADER.   
2f30: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 29   sqlite3_free(p)
2f40: 3b 0a 23 65 6e 64 69 66 0a 20 20 20 20 69 66 28  ;.#endif.    if(
2f50: 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61   pCache->bPurgea
2f60: 62 6c 65 20 29 7b 0a 20 20 20 20 20 20 70 43 61  ble ){.      pCa
2f70: 63 68 65 2d 3e 70 47 72 6f 75 70 2d 3e 6e 43 75  che->pGroup->nCu
2f80: 72 72 65 6e 74 50 61 67 65 2d 2d 3b 0a 20 20 20  rrentPage--;.   
2f90: 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20   }.  }.}../*.** 
2fa0: 4d 61 6c 6c 6f 63 20 66 75 6e 63 74 69 6f 6e 20  Malloc function 
2fb0: 75 73 65 64 20 62 79 20 53 51 4c 69 74 65 20 74  used by SQLite t
2fc0: 6f 20 6f 62 74 61 69 6e 20 73 70 61 63 65 20 66  o obtain space f
2fd0: 72 6f 6d 20 74 68 65 20 62 75 66 66 65 72 20 63  rom the buffer c
2fe0: 6f 6e 66 69 67 75 72 65 64 0a 2a 2a 20 75 73 69  onfigured.** usi
2ff0: 6e 67 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69  ng sqlite3_confi
3000: 67 28 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f  g(SQLITE_CONFIG_
3010: 50 41 47 45 43 41 43 48 45 29 20 6f 70 74 69 6f  PAGECACHE) optio
3020: 6e 2e 20 49 66 20 6e 6f 20 73 75 63 68 20 62 75  n. If no such bu
3030: 66 66 65 72 0a 2a 2a 20 65 78 69 73 74 73 2c 20  ffer.** exists, 
3040: 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 66 61  this function fa
3050: 6c 6c 73 20 62 61 63 6b 20 74 6f 20 73 71 6c 69  lls back to sqli
3060: 74 65 33 4d 61 6c 6c 6f 63 28 29 2e 0a 2a 2f 0a  te3Malloc()..*/.
3070: 76 6f 69 64 20 2a 73 71 6c 69 74 65 33 50 61 67  void *sqlite3Pag
3080: 65 4d 61 6c 6c 6f 63 28 69 6e 74 20 73 7a 29 7b  eMalloc(int sz){
3090: 0a 20 20 72 65 74 75 72 6e 20 70 63 61 63 68 65  .  return pcache
30a0: 31 41 6c 6c 6f 63 28 73 7a 29 3b 0a 7d 0a 0a 2f  1Alloc(sz);.}../
30b0: 2a 0a 2a 2a 20 46 72 65 65 20 61 6e 20 61 6c 6c  *.** Free an all
30c0: 6f 63 61 74 65 64 20 62 75 66 66 65 72 20 6f 62  ocated buffer ob
30d0: 74 61 69 6e 65 64 20 66 72 6f 6d 20 73 71 6c 69  tained from sqli
30e0: 74 65 33 50 61 67 65 4d 61 6c 6c 6f 63 28 29 2e  te3PageMalloc().
30f0: 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33  .*/.void sqlite3
3100: 50 61 67 65 46 72 65 65 28 76 6f 69 64 20 2a 70  PageFree(void *p
3110: 29 7b 0a 20 20 70 63 61 63 68 65 31 46 72 65 65  ){.  pcache1Free
3120: 28 70 29 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 52  (p);.}.../*.** R
3130: 65 74 75 72 6e 20 74 72 75 65 20 69 66 20 69 74  eturn true if it
3140: 20 64 65 73 69 72 61 62 6c 65 20 74 6f 20 61 76   desirable to av
3150: 6f 69 64 20 61 6c 6c 6f 63 61 74 69 6e 67 20 61  oid allocating a
3160: 20 6e 65 77 20 70 61 67 65 20 63 61 63 68 65 0a   new page cache.
3170: 2a 2a 20 65 6e 74 72 79 2e 0a 2a 2a 0a 2a 2a 20  ** entry..**.** 
3180: 49 66 20 6d 65 6d 6f 72 79 20 77 61 73 20 61 6c  If memory was al
3190: 6c 6f 63 61 74 65 64 20 73 70 65 63 69 66 69 63  located specific
31a0: 61 6c 6c 79 20 74 6f 20 74 68 65 20 70 61 67 65  ally to the page
31b0: 20 63 61 63 68 65 20 75 73 69 6e 67 0a 2a 2a 20   cache using.** 
31c0: 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41  SQLITE_CONFIG_PA
31d0: 47 45 43 41 43 48 45 20 62 75 74 20 74 68 61 74  GECACHE but that
31e0: 20 6d 65 6d 6f 72 79 20 68 61 73 20 61 6c 6c 20   memory has all 
31f0: 62 65 65 6e 20 75 73 65 64 2c 20 74 68 65 6e 0a  been used, then.
3200: 2a 2a 20 69 74 20 69 73 20 64 65 73 69 72 61 62  ** it is desirab
3210: 6c 65 20 74 6f 20 61 76 6f 69 64 20 61 6c 6c 6f  le to avoid allo
3220: 63 61 74 69 6e 67 20 61 20 6e 65 77 20 70 61 67  cating a new pag
3230: 65 20 63 61 63 68 65 20 65 6e 74 72 79 20 62 65  e cache entry be
3240: 63 61 75 73 65 0a 2a 2a 20 70 72 65 73 75 6d 61  cause.** presuma
3250: 62 6c 79 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49  bly SQLITE_CONFI
3260: 47 5f 50 41 47 45 43 41 43 48 45 20 77 61 73 20  G_PAGECACHE was 
3270: 73 75 70 70 6f 73 65 20 74 6f 20 62 65 20 73 75  suppose to be su
3280: 66 66 69 63 69 65 6e 74 0a 2a 2a 20 66 6f 72 20  fficient.** for 
3290: 61 6c 6c 20 70 61 67 65 20 63 61 63 68 65 20 6e  all page cache n
32a0: 65 65 64 73 20 61 6e 64 20 77 65 20 73 68 6f 75  eeds and we shou
32b0: 6c 64 20 6e 6f 74 20 6e 65 65 64 20 74 6f 20 73  ld not need to s
32c0: 70 69 6c 6c 20 74 68 65 0a 2a 2a 20 61 6c 6c 6f  pill the.** allo
32d0: 63 61 74 69 6f 6e 20 6f 6e 74 6f 20 74 68 65 20  cation onto the 
32e0: 68 65 61 70 2e 0a 2a 2a 0a 2a 2a 20 4f 72 2c 20  heap..**.** Or, 
32f0: 74 68 65 20 68 65 61 70 20 69 73 20 75 73 65 64  the heap is used
3300: 20 66 6f 72 20 61 6c 6c 20 70 61 67 65 20 63 61   for all page ca
3310: 63 68 65 20 6d 65 6d 6f 72 79 20 62 75 74 20 74  che memory but t
3320: 68 65 20 68 65 61 70 20 69 73 0a 2a 2a 20 75 6e  he heap is.** un
3330: 64 65 72 20 6d 65 6d 6f 72 79 20 70 72 65 73 73  der memory press
3340: 75 72 65 2c 20 74 68 65 6e 20 61 67 61 69 6e 20  ure, then again 
3350: 69 74 20 69 73 20 64 65 73 69 72 61 62 6c 65 20  it is desirable 
3360: 74 6f 20 61 76 6f 69 64 0a 2a 2a 20 61 6c 6c 6f  to avoid.** allo
3370: 63 61 74 69 6e 67 20 61 20 6e 65 77 20 70 61 67  cating a new pag
3380: 65 20 63 61 63 68 65 20 65 6e 74 72 79 20 69 6e  e cache entry in
3390: 20 6f 72 64 65 72 20 74 6f 20 61 76 6f 69 64 20   order to avoid 
33a0: 73 74 72 65 73 73 69 6e 67 0a 2a 2a 20 74 68 65  stressing.** the
33b0: 20 68 65 61 70 20 65 76 65 6e 20 66 75 72 74 68   heap even furth
33c0: 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  er..*/.static in
33d0: 74 20 70 63 61 63 68 65 31 55 6e 64 65 72 4d 65  t pcache1UnderMe
33e0: 6d 6f 72 79 50 72 65 73 73 75 72 65 28 50 43 61  moryPressure(PCa
33f0: 63 68 65 31 20 2a 70 43 61 63 68 65 29 7b 0a 20  che1 *pCache){. 
3400: 20 69 66 28 20 70 63 61 63 68 65 31 2e 6e 53 6c   if( pcache1.nSl
3410: 6f 74 20 26 26 20 28 70 43 61 63 68 65 2d 3e 73  ot && (pCache->s
3420: 7a 50 61 67 65 2b 70 43 61 63 68 65 2d 3e 73 7a  zPage+pCache->sz
3430: 45 78 74 72 61 29 3c 3d 70 63 61 63 68 65 31 2e  Extra)<=pcache1.
3440: 73 7a 53 6c 6f 74 20 29 7b 0a 20 20 20 20 72 65  szSlot ){.    re
3450: 74 75 72 6e 20 70 63 61 63 68 65 31 2e 62 55 6e  turn pcache1.bUn
3460: 64 65 72 50 72 65 73 73 75 72 65 3b 0a 20 20 7d  derPressure;.  }
3470: 65 6c 73 65 7b 0a 20 20 20 20 72 65 74 75 72 6e  else{.    return
3480: 20 73 71 6c 69 74 65 33 48 65 61 70 4e 65 61 72   sqlite3HeapNear
3490: 6c 79 46 75 6c 6c 28 29 3b 0a 20 20 7d 0a 7d 0a  lyFull();.  }.}.
34a0: 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ./**************
34b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
34c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
34d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
34e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
34f0: 2f 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 20 47 65 6e 65  /./******** Gene
3500: 72 61 6c 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69  ral Implementati
3510: 6f 6e 20 46 75 6e 63 74 69 6f 6e 73 20 2a 2a 2a  on Functions ***
3520: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3530: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3540: 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66  */../*.** This f
3550: 75 6e 63 74 69 6f 6e 20 69 73 20 75 73 65 64 20  unction is used 
3560: 74 6f 20 72 65 73 69 7a 65 20 74 68 65 20 68 61  to resize the ha
3570: 73 68 20 74 61 62 6c 65 20 75 73 65 64 20 62 79  sh table used by
3580: 20 74 68 65 20 63 61 63 68 65 20 70 61 73 73 65   the cache passe
3590: 64 0a 2a 2a 20 61 73 20 74 68 65 20 66 69 72 73  d.** as the firs
35a0: 74 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2a 0a 2a  t argument..**.*
35b0: 2a 20 54 68 65 20 50 43 61 63 68 65 20 6d 75 74  * The PCache mut
35c0: 65 78 20 6d 75 73 74 20 62 65 20 68 65 6c 64 20  ex must be held 
35d0: 77 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69  when this functi
35e0: 6f 6e 20 69 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f  on is called..*/
35f0: 0a 73 74 61 74 69 63 20 69 6e 74 20 70 63 61 63  .static int pcac
3600: 68 65 31 52 65 73 69 7a 65 48 61 73 68 28 50 43  he1ResizeHash(PC
3610: 61 63 68 65 31 20 2a 70 29 7b 0a 20 20 50 67 48  ache1 *p){.  PgH
3620: 64 72 31 20 2a 2a 61 70 4e 65 77 3b 0a 20 20 75  dr1 **apNew;.  u
3630: 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 4e 65 77  nsigned int nNew
3640: 3b 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74  ;.  unsigned int
3650: 20 69 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 73   i;..  assert( s
3660: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c  qlite3_mutex_hel
3670: 64 28 70 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75 74  d(p->pGroup->mut
3680: 65 78 29 20 29 3b 0a 0a 20 20 6e 4e 65 77 20 3d  ex) );..  nNew =
3690: 20 70 2d 3e 6e 48 61 73 68 2a 32 3b 0a 20 20 69   p->nHash*2;.  i
36a0: 66 28 20 6e 4e 65 77 3c 32 35 36 20 29 7b 0a 20  f( nNew<256 ){. 
36b0: 20 20 20 6e 4e 65 77 20 3d 20 32 35 36 3b 0a 20     nNew = 256;. 
36c0: 20 7d 0a 0a 20 20 70 63 61 63 68 65 31 4c 65 61   }..  pcache1Lea
36d0: 76 65 4d 75 74 65 78 28 70 2d 3e 70 47 72 6f 75  veMutex(p->pGrou
36e0: 70 29 3b 0a 20 20 69 66 28 20 70 2d 3e 6e 48 61  p);.  if( p->nHa
36f0: 73 68 20 29 7b 20 73 71 6c 69 74 65 33 42 65 67  sh ){ sqlite3Beg
3700: 69 6e 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29  inBenignMalloc()
3710: 3b 20 7d 0a 20 20 61 70 4e 65 77 20 3d 20 28 50  ; }.  apNew = (P
3720: 67 48 64 72 31 20 2a 2a 29 73 71 6c 69 74 65 33  gHdr1 **)sqlite3
3730: 4d 61 6c 6c 6f 63 5a 65 72 6f 28 73 69 7a 65 6f  MallocZero(sizeo
3740: 66 28 50 67 48 64 72 31 20 2a 29 2a 6e 4e 65 77  f(PgHdr1 *)*nNew
3750: 29 3b 0a 20 20 69 66 28 20 70 2d 3e 6e 48 61 73  );.  if( p->nHas
3760: 68 20 29 7b 20 73 71 6c 69 74 65 33 45 6e 64 42  h ){ sqlite3EndB
3770: 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 20 7d  enignMalloc(); }
3780: 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d  .  pcache1EnterM
3790: 75 74 65 78 28 70 2d 3e 70 47 72 6f 75 70 29 3b  utex(p->pGroup);
37a0: 0a 20 20 69 66 28 20 61 70 4e 65 77 20 29 7b 0a  .  if( apNew ){.
37b0: 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70      for(i=0; i<p
37c0: 2d 3e 6e 48 61 73 68 3b 20 69 2b 2b 29 7b 0a 20  ->nHash; i++){. 
37d0: 20 20 20 20 20 50 67 48 64 72 31 20 2a 70 50 61       PgHdr1 *pPa
37e0: 67 65 3b 0a 20 20 20 20 20 20 50 67 48 64 72 31  ge;.      PgHdr1
37f0: 20 2a 70 4e 65 78 74 20 3d 20 70 2d 3e 61 70 48   *pNext = p->apH
3800: 61 73 68 5b 69 5d 3b 0a 20 20 20 20 20 20 77 68  ash[i];.      wh
3810: 69 6c 65 28 20 28 70 50 61 67 65 20 3d 20 70 4e  ile( (pPage = pN
3820: 65 78 74 29 21 3d 30 20 29 7b 0a 20 20 20 20 20  ext)!=0 ){.     
3830: 20 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20     unsigned int 
3840: 68 20 3d 20 70 50 61 67 65 2d 3e 69 4b 65 79 20  h = pPage->iKey 
3850: 25 20 6e 4e 65 77 3b 0a 20 20 20 20 20 20 20 20  % nNew;.        
3860: 70 4e 65 78 74 20 3d 20 70 50 61 67 65 2d 3e 70  pNext = pPage->p
3870: 4e 65 78 74 3b 0a 20 20 20 20 20 20 20 20 70 50  Next;.        pP
3880: 61 67 65 2d 3e 70 4e 65 78 74 20 3d 20 61 70 4e  age->pNext = apN
3890: 65 77 5b 68 5d 3b 0a 20 20 20 20 20 20 20 20 61  ew[h];.        a
38a0: 70 4e 65 77 5b 68 5d 20 3d 20 70 50 61 67 65 3b  pNew[h] = pPage;
38b0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
38c0: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
38d0: 70 2d 3e 61 70 48 61 73 68 29 3b 0a 20 20 20 20  p->apHash);.    
38e0: 70 2d 3e 61 70 48 61 73 68 20 3d 20 61 70 4e 65  p->apHash = apNe
38f0: 77 3b 0a 20 20 20 20 70 2d 3e 6e 48 61 73 68 20  w;.    p->nHash 
3900: 3d 20 6e 4e 65 77 3b 0a 20 20 7d 0a 0a 20 20 72  = nNew;.  }..  r
3910: 65 74 75 72 6e 20 28 70 2d 3e 61 70 48 61 73 68  eturn (p->apHash
3920: 20 3f 20 53 51 4c 49 54 45 5f 4f 4b 20 3a 20 53   ? SQLITE_OK : S
3930: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 29 3b 0a 7d 0a  QLITE_NOMEM);.}.
3940: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  ./*.** This func
3950: 74 69 6f 6e 20 69 73 20 75 73 65 64 20 69 6e 74  tion is used int
3960: 65 72 6e 61 6c 6c 79 20 74 6f 20 72 65 6d 6f 76  ernally to remov
3970: 65 20 74 68 65 20 70 61 67 65 20 70 50 61 67 65  e the page pPage
3980: 20 66 72 6f 6d 20 74 68 65 20 0a 2a 2a 20 50 47   from the .** PG
3990: 72 6f 75 70 20 4c 52 55 20 6c 69 73 74 2c 20 69  roup LRU list, i
39a0: 66 20 69 73 20 70 61 72 74 20 6f 66 20 69 74 2e  f is part of it.
39b0: 20 49 66 20 70 50 61 67 65 20 69 73 20 6e 6f 74   If pPage is not
39c0: 20 70 61 72 74 20 6f 66 20 74 68 65 20 50 47 72   part of the PGr
39d0: 6f 75 70 0a 2a 2a 20 4c 52 55 20 6c 69 73 74 2c  oup.** LRU list,
39e0: 20 74 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74   then this funct
39f0: 69 6f 6e 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a  ion is a no-op..
3a00: 2a 2a 0a 2a 2a 20 54 68 65 20 50 47 72 6f 75 70  **.** The PGroup
3a10: 20 6d 75 74 65 78 20 6d 75 73 74 20 62 65 20 68   mutex must be h
3a20: 65 6c 64 20 77 68 65 6e 20 74 68 69 73 20 66 75  eld when this fu
3a30: 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64  nction is called
3a40: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
3a50: 20 70 63 61 63 68 65 31 50 69 6e 50 61 67 65 28   pcache1PinPage(
3a60: 50 67 48 64 72 31 20 2a 70 50 61 67 65 29 7b 0a  PgHdr1 *pPage){.
3a70: 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68    PCache1 *pCach
3a80: 65 3b 0a 20 20 50 47 72 6f 75 70 20 2a 70 47 72  e;.  PGroup *pGr
3a90: 6f 75 70 3b 0a 0a 20 20 61 73 73 65 72 74 28 20  oup;..  assert( 
3aa0: 70 50 61 67 65 21 3d 30 20 29 3b 0a 20 20 61 73  pPage!=0 );.  as
3ab0: 73 65 72 74 28 20 70 50 61 67 65 2d 3e 69 73 50  sert( pPage->isP
3ac0: 69 6e 6e 65 64 3d 3d 30 20 29 3b 0a 20 20 70 43  inned==0 );.  pC
3ad0: 61 63 68 65 20 3d 20 70 50 61 67 65 2d 3e 70 43  ache = pPage->pC
3ae0: 61 63 68 65 3b 0a 20 20 70 47 72 6f 75 70 20 3d  ache;.  pGroup =
3af0: 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b   pCache->pGroup;
3b00: 0a 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65  .  assert( pPage
3b10: 2d 3e 70 4c 72 75 4e 65 78 74 20 7c 7c 20 70 50  ->pLruNext || pP
3b20: 61 67 65 3d 3d 70 47 72 6f 75 70 2d 3e 70 4c 72  age==pGroup->pLr
3b30: 75 54 61 69 6c 20 29 3b 0a 20 20 61 73 73 65 72  uTail );.  asser
3b40: 74 28 20 70 50 61 67 65 2d 3e 70 4c 72 75 50 72  t( pPage->pLruPr
3b50: 65 76 20 7c 7c 20 70 50 61 67 65 3d 3d 70 47 72  ev || pPage==pGr
3b60: 6f 75 70 2d 3e 70 4c 72 75 48 65 61 64 20 29 3b  oup->pLruHead );
3b70: 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74  .  assert( sqlit
3b80: 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 47  e3_mutex_held(pG
3b90: 72 6f 75 70 2d 3e 6d 75 74 65 78 29 20 29 3b 0a  roup->mutex) );.
3ba0: 20 20 69 66 28 20 70 50 61 67 65 2d 3e 70 4c 72    if( pPage->pLr
3bb0: 75 50 72 65 76 20 29 7b 0a 20 20 20 20 70 50 61  uPrev ){.    pPa
3bc0: 67 65 2d 3e 70 4c 72 75 50 72 65 76 2d 3e 70 4c  ge->pLruPrev->pL
3bd0: 72 75 4e 65 78 74 20 3d 20 70 50 61 67 65 2d 3e  ruNext = pPage->
3be0: 70 4c 72 75 4e 65 78 74 3b 0a 20 20 7d 65 6c 73  pLruNext;.  }els
3bf0: 65 7b 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e 70  e{.    pGroup->p
3c00: 4c 72 75 48 65 61 64 20 3d 20 70 50 61 67 65 2d  LruHead = pPage-
3c10: 3e 70 4c 72 75 4e 65 78 74 3b 0a 20 20 7d 0a 20  >pLruNext;.  }. 
3c20: 20 69 66 28 20 70 50 61 67 65 2d 3e 70 4c 72 75   if( pPage->pLru
3c30: 4e 65 78 74 20 29 7b 0a 20 20 20 20 70 50 61 67  Next ){.    pPag
3c40: 65 2d 3e 70 4c 72 75 4e 65 78 74 2d 3e 70 4c 72  e->pLruNext->pLr
3c50: 75 50 72 65 76 20 3d 20 70 50 61 67 65 2d 3e 70  uPrev = pPage->p
3c60: 4c 72 75 50 72 65 76 3b 0a 20 20 7d 65 6c 73 65  LruPrev;.  }else
3c70: 7b 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e 70 4c  {.    pGroup->pL
3c80: 72 75 54 61 69 6c 20 3d 20 70 50 61 67 65 2d 3e  ruTail = pPage->
3c90: 70 4c 72 75 50 72 65 76 3b 0a 20 20 7d 0a 20 20  pLruPrev;.  }.  
3ca0: 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 20  pPage->pLruNext 
3cb0: 3d 20 30 3b 0a 20 20 70 50 61 67 65 2d 3e 70 4c  = 0;.  pPage->pL
3cc0: 72 75 50 72 65 76 20 3d 20 30 3b 0a 20 20 70 50  ruPrev = 0;.  pP
3cd0: 61 67 65 2d 3e 69 73 50 69 6e 6e 65 64 20 3d 20  age->isPinned = 
3ce0: 31 3b 0a 20 20 70 43 61 63 68 65 2d 3e 6e 52 65  1;.  pCache->nRe
3cf0: 63 79 63 6c 61 62 6c 65 2d 2d 3b 0a 7d 0a 0a 0a  cyclable--;.}...
3d00: 2f 2a 0a 2a 2a 20 52 65 6d 6f 76 65 20 74 68 65  /*.** Remove the
3d10: 20 70 61 67 65 20 73 75 70 70 6c 69 65 64 20 61   page supplied a
3d20: 73 20 61 6e 20 61 72 67 75 6d 65 6e 74 20 66 72  s an argument fr
3d30: 6f 6d 20 74 68 65 20 68 61 73 68 20 74 61 62 6c  om the hash tabl
3d40: 65 20 0a 2a 2a 20 28 50 43 61 63 68 65 31 2e 61  e .** (PCache1.a
3d50: 70 48 61 73 68 20 73 74 72 75 63 74 75 72 65 29  pHash structure)
3d60: 20 74 68 61 74 20 69 74 20 69 73 20 63 75 72 72   that it is curr
3d70: 65 6e 74 6c 79 20 73 74 6f 72 65 64 20 69 6e 2e  ently stored in.
3d80: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 50 47 72 6f 75  .**.** The PGrou
3d90: 70 20 6d 75 74 65 78 20 6d 75 73 74 20 62 65 20  p mutex must be 
3da0: 68 65 6c 64 20 77 68 65 6e 20 74 68 69 73 20 66  held when this f
3db0: 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65  unction is calle
3dc0: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  d..*/.static voi
3dd0: 64 20 70 63 61 63 68 65 31 52 65 6d 6f 76 65 46  d pcache1RemoveF
3de0: 72 6f 6d 48 61 73 68 28 50 67 48 64 72 31 20 2a  romHash(PgHdr1 *
3df0: 70 50 61 67 65 29 7b 0a 20 20 75 6e 73 69 67 6e  pPage){.  unsign
3e00: 65 64 20 69 6e 74 20 68 3b 0a 20 20 50 43 61 63  ed int h;.  PCac
3e10: 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20 70 50  he1 *pCache = pP
3e20: 61 67 65 2d 3e 70 43 61 63 68 65 3b 0a 20 20 50  age->pCache;.  P
3e30: 67 48 64 72 31 20 2a 2a 70 70 3b 0a 0a 20 20 61  gHdr1 **pp;..  a
3e40: 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d  ssert( sqlite3_m
3e50: 75 74 65 78 5f 68 65 6c 64 28 70 43 61 63 68 65  utex_held(pCache
3e60: 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78 29  ->pGroup->mutex)
3e70: 20 29 3b 0a 20 20 68 20 3d 20 70 50 61 67 65 2d   );.  h = pPage-
3e80: 3e 69 4b 65 79 20 25 20 70 43 61 63 68 65 2d 3e  >iKey % pCache->
3e90: 6e 48 61 73 68 3b 0a 20 20 66 6f 72 28 70 70 3d  nHash;.  for(pp=
3ea0: 26 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b  &pCache->apHash[
3eb0: 68 5d 3b 20 28 2a 70 70 29 21 3d 70 50 61 67 65  h]; (*pp)!=pPage
3ec0: 3b 20 70 70 3d 26 28 2a 70 70 29 2d 3e 70 4e 65  ; pp=&(*pp)->pNe
3ed0: 78 74 29 3b 0a 20 20 2a 70 70 20 3d 20 28 2a 70  xt);.  *pp = (*p
3ee0: 70 29 2d 3e 70 4e 65 78 74 3b 0a 0a 20 20 70 43  p)->pNext;..  pC
3ef0: 61 63 68 65 2d 3e 6e 50 61 67 65 2d 2d 3b 0a 7d  ache->nPage--;.}
3f00: 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 74 68 65 72 65  ../*.** If there
3f10: 20 61 72 65 20 63 75 72 72 65 6e 74 6c 79 20 6d   are currently m
3f20: 6f 72 65 20 74 68 61 6e 20 6e 4d 61 78 50 61 67  ore than nMaxPag
3f30: 65 20 70 61 67 65 73 20 61 6c 6c 6f 63 61 74 65  e pages allocate
3f40: 64 2c 20 74 72 79 0a 2a 2a 20 74 6f 20 72 65 63  d, try.** to rec
3f50: 79 63 6c 65 20 70 61 67 65 73 20 74 6f 20 72 65  ycle pages to re
3f60: 64 75 63 65 20 74 68 65 20 6e 75 6d 62 65 72 20  duce the number 
3f70: 61 6c 6c 6f 63 61 74 65 64 20 74 6f 20 6e 4d 61  allocated to nMa
3f80: 78 50 61 67 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  xPage..*/.static
3f90: 20 76 6f 69 64 20 70 63 61 63 68 65 31 45 6e 66   void pcache1Enf
3fa0: 6f 72 63 65 4d 61 78 50 61 67 65 28 50 47 72 6f  orceMaxPage(PGro
3fb0: 75 70 20 2a 70 47 72 6f 75 70 29 7b 0a 20 20 61  up *pGroup){.  a
3fc0: 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d  ssert( sqlite3_m
3fd0: 75 74 65 78 5f 68 65 6c 64 28 70 47 72 6f 75 70  utex_held(pGroup
3fe0: 2d 3e 6d 75 74 65 78 29 20 29 3b 0a 20 20 77 68  ->mutex) );.  wh
3ff0: 69 6c 65 28 20 70 47 72 6f 75 70 2d 3e 6e 43 75  ile( pGroup->nCu
4000: 72 72 65 6e 74 50 61 67 65 3e 70 47 72 6f 75 70  rrentPage>pGroup
4010: 2d 3e 6e 4d 61 78 50 61 67 65 20 26 26 20 70 47  ->nMaxPage && pG
4020: 72 6f 75 70 2d 3e 70 4c 72 75 54 61 69 6c 20 29  roup->pLruTail )
4030: 7b 0a 20 20 20 20 50 67 48 64 72 31 20 2a 70 20  {.    PgHdr1 *p 
4040: 3d 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 54 61  = pGroup->pLruTa
4050: 69 6c 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20  il;.    assert( 
4060: 70 2d 3e 70 43 61 63 68 65 2d 3e 70 47 72 6f 75  p->pCache->pGrou
4070: 70 3d 3d 70 47 72 6f 75 70 20 29 3b 0a 20 20 20  p==pGroup );.   
4080: 20 61 73 73 65 72 74 28 20 70 2d 3e 69 73 50 69   assert( p->isPi
4090: 6e 6e 65 64 3d 3d 30 20 29 3b 0a 20 20 20 20 70  nned==0 );.    p
40a0: 63 61 63 68 65 31 50 69 6e 50 61 67 65 28 70 29  cache1PinPage(p)
40b0: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 52 65 6d  ;.    pcache1Rem
40c0: 6f 76 65 46 72 6f 6d 48 61 73 68 28 70 29 3b 0a  oveFromHash(p);.
40d0: 20 20 20 20 70 63 61 63 68 65 31 46 72 65 65 50      pcache1FreeP
40e0: 61 67 65 28 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f  age(p);.  }.}../
40f0: 2a 0a 2a 2a 20 44 69 73 63 61 72 64 20 61 6c 6c  *.** Discard all
4100: 20 70 61 67 65 73 20 66 72 6f 6d 20 63 61 63 68   pages from cach
4110: 65 20 70 43 61 63 68 65 20 77 69 74 68 20 61 20  e pCache with a 
4120: 70 61 67 65 20 6e 75 6d 62 65 72 20 28 6b 65 79  page number (key
4130: 20 76 61 6c 75 65 29 20 0a 2a 2a 20 67 72 65 61   value) .** grea
4140: 74 65 72 20 74 68 61 6e 20 6f 72 20 65 71 75 61  ter than or equa
4150: 6c 20 74 6f 20 69 4c 69 6d 69 74 2e 20 41 6e 79  l to iLimit. Any
4160: 20 70 69 6e 6e 65 64 20 70 61 67 65 73 20 74 68   pinned pages th
4170: 61 74 20 6d 65 65 74 20 74 68 69 73 20 0a 2a 2a  at meet this .**
4180: 20 63 72 69 74 65 72 69 61 20 61 72 65 20 75 6e   criteria are un
4190: 70 69 6e 6e 65 64 20 62 65 66 6f 72 65 20 74 68  pinned before th
41a0: 65 79 20 61 72 65 20 64 69 73 63 61 72 64 65 64  ey are discarded
41b0: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 50 43 61 63  ..**.** The PCac
41c0: 68 65 20 6d 75 74 65 78 20 6d 75 73 74 20 62 65  he mutex must be
41d0: 20 68 65 6c 64 20 77 68 65 6e 20 74 68 69 73 20   held when this 
41e0: 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c  function is call
41f0: 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ed..*/.static vo
4200: 69 64 20 70 63 61 63 68 65 31 54 72 75 6e 63 61  id pcache1Trunca
4210: 74 65 55 6e 73 61 66 65 28 0a 20 20 50 43 61 63  teUnsafe(.  PCac
4220: 68 65 31 20 2a 70 43 61 63 68 65 2c 20 20 20 20  he1 *pCache,    
4230: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20           /* The 
4240: 63 61 63 68 65 20 74 6f 20 74 72 75 6e 63 61 74  cache to truncat
4250: 65 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20  e */.  unsigned 
4260: 69 6e 74 20 69 4c 69 6d 69 74 20 20 20 20 20 20  int iLimit      
4270: 20 20 20 20 2f 2a 20 44 72 6f 70 20 70 61 67 65      /* Drop page
4280: 73 20 77 69 74 68 20 74 68 69 73 20 70 67 6e 6f  s with this pgno
4290: 20 6f 72 20 6c 61 72 67 65 72 20 2a 2f 0a 29 7b   or larger */.){
42a0: 0a 20 20 54 45 53 54 4f 4e 4c 59 28 20 75 6e 73  .  TESTONLY( uns
42b0: 69 67 6e 65 64 20 69 6e 74 20 6e 50 61 67 65 20  igned int nPage 
42c0: 3d 20 30 3b 20 29 20 20 2f 2a 20 54 6f 20 61 73  = 0; )  /* To as
42d0: 73 65 72 74 20 70 43 61 63 68 65 2d 3e 6e 50 61  sert pCache->nPa
42e0: 67 65 20 69 73 20 63 6f 72 72 65 63 74 20 2a 2f  ge is correct */
42f0: 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  .  unsigned int 
4300: 68 3b 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c  h;.  assert( sql
4310: 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28  ite3_mutex_held(
4320: 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 2d 3e  pCache->pGroup->
4330: 6d 75 74 65 78 29 20 29 3b 0a 20 20 66 6f 72 28  mutex) );.  for(
4340: 68 3d 30 3b 20 68 3c 70 43 61 63 68 65 2d 3e 6e  h=0; h<pCache->n
4350: 48 61 73 68 3b 20 68 2b 2b 29 7b 0a 20 20 20 20  Hash; h++){.    
4360: 50 67 48 64 72 31 20 2a 2a 70 70 20 3d 20 26 70  PgHdr1 **pp = &p
4370: 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d  Cache->apHash[h]
4380: 3b 20 0a 20 20 20 20 50 67 48 64 72 31 20 2a 70  ; .    PgHdr1 *p
4390: 50 61 67 65 3b 0a 20 20 20 20 77 68 69 6c 65 28  Page;.    while(
43a0: 20 28 70 50 61 67 65 20 3d 20 2a 70 70 29 21 3d   (pPage = *pp)!=
43b0: 30 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 70  0 ){.      if( p
43c0: 50 61 67 65 2d 3e 69 4b 65 79 3e 3d 69 4c 69 6d  Page->iKey>=iLim
43d0: 69 74 20 29 7b 0a 20 20 20 20 20 20 20 20 70 43  it ){.        pC
43e0: 61 63 68 65 2d 3e 6e 50 61 67 65 2d 2d 3b 0a 20  ache->nPage--;. 
43f0: 20 20 20 20 20 20 20 2a 70 70 20 3d 20 70 50 61         *pp = pPa
4400: 67 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20  ge->pNext;.     
4410: 20 20 20 69 66 28 20 21 70 50 61 67 65 2d 3e 69     if( !pPage->i
4420: 73 50 69 6e 6e 65 64 20 29 20 70 63 61 63 68 65  sPinned ) pcache
4430: 31 50 69 6e 50 61 67 65 28 70 50 61 67 65 29 3b  1PinPage(pPage);
4440: 0a 20 20 20 20 20 20 20 20 70 63 61 63 68 65 31  .        pcache1
4450: 46 72 65 65 50 61 67 65 28 70 50 61 67 65 29 3b  FreePage(pPage);
4460: 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  .      }else{.  
4470: 20 20 20 20 20 20 70 70 20 3d 20 26 70 50 61 67        pp = &pPag
4480: 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20  e->pNext;.      
4490: 20 20 54 45 53 54 4f 4e 4c 59 28 20 6e 50 61 67    TESTONLY( nPag
44a0: 65 2b 2b 3b 20 29 0a 20 20 20 20 20 20 7d 0a 20  e++; ).      }. 
44b0: 20 20 20 7d 0a 20 20 7d 0a 20 20 61 73 73 65 72     }.  }.  asser
44c0: 74 28 20 70 43 61 63 68 65 2d 3e 6e 50 61 67 65  t( pCache->nPage
44d0: 3d 3d 6e 50 61 67 65 20 29 3b 0a 7d 0a 0a 2f 2a  ==nPage );.}../*
44e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
44f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4500: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4510: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4520: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f  *************/./
4530: 2a 2a 2a 2a 2a 2a 2a 2a 20 73 71 6c 69 74 65 33  ******** sqlite3
4540: 5f 70 63 61 63 68 65 20 4d 65 74 68 6f 64 73 20  _pcache Methods 
4550: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4560: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4570: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a  **************/.
4580: 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74  ./*.** Implement
4590: 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c  ation of the sql
45a0: 69 74 65 33 5f 70 63 61 63 68 65 2e 78 49 6e 69  ite3_pcache.xIni
45b0: 74 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61  t method..*/.sta
45c0: 74 69 63 20 69 6e 74 20 70 63 61 63 68 65 31 49  tic int pcache1I
45d0: 6e 69 74 28 76 6f 69 64 20 2a 4e 6f 74 55 73 65  nit(void *NotUse
45e0: 64 29 7b 0a 20 20 55 4e 55 53 45 44 5f 50 41 52  d){.  UNUSED_PAR
45f0: 41 4d 45 54 45 52 28 4e 6f 74 55 73 65 64 29 3b  AMETER(NotUsed);
4600: 0a 20 20 61 73 73 65 72 74 28 20 70 63 61 63 68  .  assert( pcach
4610: 65 31 2e 69 73 49 6e 69 74 3d 3d 30 20 29 3b 0a  e1.isInit==0 );.
4620: 20 20 6d 65 6d 73 65 74 28 26 70 63 61 63 68 65    memset(&pcache
4630: 31 2c 20 30 2c 20 73 69 7a 65 6f 66 28 70 63 61  1, 0, sizeof(pca
4640: 63 68 65 31 29 29 3b 0a 20 20 69 66 28 20 73 71  che1));.  if( sq
4650: 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69  lite3GlobalConfi
4660: 67 2e 62 43 6f 72 65 4d 75 74 65 78 20 29 7b 0a  g.bCoreMutex ){.
4670: 20 20 20 20 70 63 61 63 68 65 31 2e 67 72 70 2e      pcache1.grp.
4680: 6d 75 74 65 78 20 3d 20 73 71 6c 69 74 65 33 5f  mutex = sqlite3_
4690: 6d 75 74 65 78 5f 61 6c 6c 6f 63 28 53 51 4c 49  mutex_alloc(SQLI
46a0: 54 45 5f 4d 55 54 45 58 5f 53 54 41 54 49 43 5f  TE_MUTEX_STATIC_
46b0: 4c 52 55 29 3b 0a 20 20 20 20 70 63 61 63 68 65  LRU);.    pcache
46c0: 31 2e 6d 75 74 65 78 20 3d 20 73 71 6c 69 74 65  1.mutex = sqlite
46d0: 33 5f 6d 75 74 65 78 5f 61 6c 6c 6f 63 28 53 51  3_mutex_alloc(SQ
46e0: 4c 49 54 45 5f 4d 55 54 45 58 5f 53 54 41 54 49  LITE_MUTEX_STATI
46f0: 43 5f 50 4d 45 4d 29 3b 0a 20 20 7d 0a 20 20 70  C_PMEM);.  }.  p
4700: 63 61 63 68 65 31 2e 67 72 70 2e 6d 78 50 69 6e  cache1.grp.mxPin
4710: 6e 65 64 20 3d 20 31 30 3b 0a 20 20 70 63 61 63  ned = 10;.  pcac
4720: 68 65 31 2e 69 73 49 6e 69 74 20 3d 20 31 3b 0a  he1.isInit = 1;.
4730: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
4740: 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70  OK;.}../*.** Imp
4750: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74  lementation of t
4760: 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68  he sqlite3_pcach
4770: 65 2e 78 53 68 75 74 64 6f 77 6e 20 6d 65 74 68  e.xShutdown meth
4780: 6f 64 2e 0a 2a 2a 20 4e 6f 74 65 20 74 68 61 74  od..** Note that
4790: 20 74 68 65 20 73 74 61 74 69 63 20 6d 75 74 65   the static mute
47a0: 78 20 61 6c 6c 6f 63 61 74 65 64 20 69 6e 20 78  x allocated in x
47b0: 49 6e 69 74 20 64 6f 65 73 20 0a 2a 2a 20 6e 6f  Init does .** no
47c0: 74 20 6e 65 65 64 20 74 6f 20 62 65 20 66 72 65  t need to be fre
47d0: 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ed..*/.static vo
47e0: 69 64 20 70 63 61 63 68 65 31 53 68 75 74 64 6f  id pcache1Shutdo
47f0: 77 6e 28 76 6f 69 64 20 2a 4e 6f 74 55 73 65 64  wn(void *NotUsed
4800: 29 7b 0a 20 20 55 4e 55 53 45 44 5f 50 41 52 41  ){.  UNUSED_PARA
4810: 4d 45 54 45 52 28 4e 6f 74 55 73 65 64 29 3b 0a  METER(NotUsed);.
4820: 20 20 61 73 73 65 72 74 28 20 70 63 61 63 68 65    assert( pcache
4830: 31 2e 69 73 49 6e 69 74 21 3d 30 20 29 3b 0a 20  1.isInit!=0 );. 
4840: 20 6d 65 6d 73 65 74 28 26 70 63 61 63 68 65 31   memset(&pcache1
4850: 2c 20 30 2c 20 73 69 7a 65 6f 66 28 70 63 61 63  , 0, sizeof(pcac
4860: 68 65 31 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  he1));.}../*.** 
4870: 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  Implementation o
4880: 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63  f the sqlite3_pc
4890: 61 63 68 65 2e 78 43 72 65 61 74 65 20 6d 65 74  ache.xCreate met
48a0: 68 6f 64 2e 0a 2a 2a 0a 2a 2a 20 41 6c 6c 6f 63  hod..**.** Alloc
48b0: 61 74 65 20 61 20 6e 65 77 20 63 61 63 68 65 2e  ate a new cache.
48c0: 0a 2a 2f 0a 73 74 61 74 69 63 20 73 71 6c 69 74  .*/.static sqlit
48d0: 65 33 5f 70 63 61 63 68 65 20 2a 70 63 61 63 68  e3_pcache *pcach
48e0: 65 31 43 72 65 61 74 65 28 69 6e 74 20 73 7a 50  e1Create(int szP
48f0: 61 67 65 2c 20 69 6e 74 20 73 7a 45 78 74 72 61  age, int szExtra
4900: 2c 20 69 6e 74 20 62 50 75 72 67 65 61 62 6c 65  , int bPurgeable
4910: 29 7b 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43  ){.  PCache1 *pC
4920: 61 63 68 65 3b 20 20 20 20 20 20 2f 2a 20 54 68  ache;      /* Th
4930: 65 20 6e 65 77 6c 79 20 63 72 65 61 74 65 64 20  e newly created 
4940: 70 61 67 65 20 63 61 63 68 65 20 2a 2f 0a 20 20  page cache */.  
4950: 50 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 3b 20  PGroup *pGroup; 
4960: 20 20 20 20 20 20 2f 2a 20 54 68 65 20 67 72 6f        /* The gro
4970: 75 70 20 74 68 65 20 6e 65 77 20 70 61 67 65 20  up the new page 
4980: 63 61 63 68 65 20 77 69 6c 6c 20 62 65 6c 6f 6e  cache will belon
4990: 67 20 74 6f 20 2a 2f 0a 20 20 69 6e 74 20 73 7a  g to */.  int sz
49a0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
49b0: 2f 2a 20 42 79 74 65 73 20 6f 66 20 6d 65 6d 6f  /* Bytes of memo
49c0: 72 79 20 72 65 71 75 69 72 65 64 20 74 6f 20 61  ry required to a
49d0: 6c 6c 6f 63 61 74 65 20 74 68 65 20 6e 65 77 20  llocate the new 
49e0: 63 61 63 68 65 20 2a 2f 0a 0a 20 20 2f 2a 0a 20  cache */..  /*. 
49f0: 20 2a 2a 20 54 68 65 20 73 65 70 61 72 61 74 65   ** The separate
4a00: 43 61 63 68 65 20 76 61 72 69 61 62 6c 65 20 69  Cache variable i
4a10: 73 20 74 72 75 65 20 69 66 20 65 61 63 68 20 50  s true if each P
4a20: 43 61 63 68 65 20 68 61 73 20 69 74 73 20 6f 77  Cache has its ow
4a30: 6e 20 70 72 69 76 61 74 65 0a 20 20 2a 2a 20 50  n private.  ** P
4a40: 47 72 6f 75 70 2e 20 20 49 6e 20 6f 74 68 65 72  Group.  In other
4a50: 20 77 6f 72 64 73 2c 20 73 65 70 61 72 61 74 65   words, separate
4a60: 43 61 63 68 65 20 69 73 20 74 72 75 65 20 66 6f  Cache is true fo
4a70: 72 20 6d 6f 64 65 20 28 31 29 20 77 68 65 72 65  r mode (1) where
4a80: 20 6e 6f 0a 20 20 2a 2a 20 6d 75 74 65 78 69 6e   no.  ** mutexin
4a90: 67 20 69 73 20 72 65 71 75 69 72 65 64 2e 0a 20  g is required.. 
4aa0: 20 2a 2a 0a 20 20 2a 2a 20 20 20 2a 20 20 41 6c   **.  **   *  Al
4ab0: 77 61 79 73 20 75 73 65 20 61 20 75 6e 69 66 69  ways use a unifi
4ac0: 65 64 20 63 61 63 68 65 20 28 6d 6f 64 65 2d 32  ed cache (mode-2
4ad0: 29 20 69 66 20 45 4e 41 42 4c 45 5f 4d 45 4d 4f  ) if ENABLE_MEMO
4ae0: 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 0a 20 20  RY_MANAGEMENT.  
4af0: 2a 2a 0a 20 20 2a 2a 20 20 20 2a 20 20 41 6c 77  **.  **   *  Alw
4b00: 61 79 73 20 75 73 65 20 61 20 75 6e 69 66 69 65  ays use a unifie
4b10: 64 20 63 61 63 68 65 20 69 6e 20 73 69 6e 67 6c  d cache in singl
4b20: 65 2d 74 68 72 65 61 64 65 64 20 61 70 70 6c 69  e-threaded appli
4b30: 63 61 74 69 6f 6e 73 0a 20 20 2a 2a 0a 20 20 2a  cations.  **.  *
4b40: 2a 20 20 20 2a 20 20 4f 74 68 65 72 77 69 73 65  *   *  Otherwise
4b50: 20 28 69 66 20 6d 75 6c 74 69 2d 74 68 72 65 61   (if multi-threa
4b60: 64 65 64 20 61 6e 64 20 45 4e 41 42 4c 45 5f 4d  ded and ENABLE_M
4b70: 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54  EMORY_MANAGEMENT
4b80: 20 69 73 20 6f 66 66 29 0a 20 20 2a 2a 20 20 20   is off).  **   
4b90: 20 20 20 75 73 65 20 73 65 70 61 72 61 74 65 20     use separate 
4ba0: 63 61 63 68 65 73 20 28 6d 6f 64 65 2d 31 29 0a  caches (mode-1).
4bb0: 20 20 2a 2f 0a 23 69 66 20 64 65 66 69 6e 65 64    */.#if defined
4bc0: 28 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d  (SQLITE_ENABLE_M
4bd0: 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54  EMORY_MANAGEMENT
4be0: 29 20 7c 7c 20 53 51 4c 49 54 45 5f 54 48 52 45  ) || SQLITE_THRE
4bf0: 41 44 53 41 46 45 3d 3d 30 0a 20 20 63 6f 6e 73  ADSAFE==0.  cons
4c00: 74 20 69 6e 74 20 73 65 70 61 72 61 74 65 43 61  t int separateCa
4c10: 63 68 65 20 3d 20 30 3b 0a 23 65 6c 73 65 0a 20  che = 0;.#else. 
4c20: 20 69 6e 74 20 73 65 70 61 72 61 74 65 43 61 63   int separateCac
4c30: 68 65 20 3d 20 73 71 6c 69 74 65 33 47 6c 6f 62  he = sqlite3Glob
4c40: 61 6c 43 6f 6e 66 69 67 2e 62 43 6f 72 65 4d 75  alConfig.bCoreMu
4c50: 74 65 78 3e 30 3b 0a 23 65 6e 64 69 66 0a 0a 20  tex>0;.#endif.. 
4c60: 20 61 73 73 65 72 74 28 20 28 73 7a 50 61 67 65   assert( (szPage
4c70: 20 26 20 28 73 7a 50 61 67 65 2d 31 29 29 3d 3d   & (szPage-1))==
4c80: 30 20 26 26 20 73 7a 50 61 67 65 3e 3d 35 31 32  0 && szPage>=512
4c90: 20 26 26 20 73 7a 50 61 67 65 3c 3d 36 35 35 33   && szPage<=6553
4ca0: 36 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 73  6 );.  assert( s
4cb0: 7a 45 78 74 72 61 20 3c 20 33 30 30 20 29 3b 0a  zExtra < 300 );.
4cc0: 0a 20 20 73 7a 20 3d 20 73 69 7a 65 6f 66 28 50  .  sz = sizeof(P
4cd0: 43 61 63 68 65 31 29 20 2b 20 73 69 7a 65 6f 66  Cache1) + sizeof
4ce0: 28 50 47 72 6f 75 70 29 2a 73 65 70 61 72 61 74  (PGroup)*separat
4cf0: 65 43 61 63 68 65 3b 0a 20 20 70 43 61 63 68 65  eCache;.  pCache
4d00: 20 3d 20 28 50 43 61 63 68 65 31 20 2a 29 73 71   = (PCache1 *)sq
4d10: 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28  lite3MallocZero(
4d20: 73 7a 29 3b 0a 20 20 69 66 28 20 70 43 61 63 68  sz);.  if( pCach
4d30: 65 20 29 7b 0a 20 20 20 20 69 66 28 20 73 65 70  e ){.    if( sep
4d40: 61 72 61 74 65 43 61 63 68 65 20 29 7b 0a 20 20  arateCache ){.  
4d50: 20 20 20 20 70 47 72 6f 75 70 20 3d 20 28 50 47      pGroup = (PG
4d60: 72 6f 75 70 2a 29 26 70 43 61 63 68 65 5b 31 5d  roup*)&pCache[1]
4d70: 3b 0a 20 20 20 20 20 20 70 47 72 6f 75 70 2d 3e  ;.      pGroup->
4d80: 6d 78 50 69 6e 6e 65 64 20 3d 20 31 30 3b 0a 20  mxPinned = 10;. 
4d90: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
4da0: 70 47 72 6f 75 70 20 3d 20 26 70 63 61 63 68 65  pGroup = &pcache
4db0: 31 2e 67 72 70 3b 0a 20 20 20 20 7d 0a 20 20 20  1.grp;.    }.   
4dc0: 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 20   pCache->pGroup 
4dd0: 3d 20 70 47 72 6f 75 70 3b 0a 20 20 20 20 70 43  = pGroup;.    pC
4de0: 61 63 68 65 2d 3e 73 7a 50 61 67 65 20 3d 20 73  ache->szPage = s
4df0: 7a 50 61 67 65 3b 0a 20 20 20 20 70 43 61 63 68  zPage;.    pCach
4e00: 65 2d 3e 73 7a 45 78 74 72 61 20 3d 20 73 7a 45  e->szExtra = szE
4e10: 78 74 72 61 3b 0a 20 20 20 20 70 43 61 63 68 65  xtra;.    pCache
4e20: 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 3d 20 28  ->bPurgeable = (
4e30: 62 50 75 72 67 65 61 62 6c 65 20 3f 20 31 20 3a  bPurgeable ? 1 :
4e40: 20 30 29 3b 0a 20 20 20 20 69 66 28 20 62 50 75   0);.    if( bPu
4e50: 72 67 65 61 62 6c 65 20 29 7b 0a 20 20 20 20 20  rgeable ){.     
4e60: 20 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 20 3d 20   pCache->nMin = 
4e70: 31 30 3b 0a 20 20 20 20 20 20 70 63 61 63 68 65  10;.      pcache
4e80: 31 45 6e 74 65 72 4d 75 74 65 78 28 70 47 72 6f  1EnterMutex(pGro
4e90: 75 70 29 3b 0a 20 20 20 20 20 20 70 47 72 6f 75  up);.      pGrou
4ea0: 70 2d 3e 6e 4d 69 6e 50 61 67 65 20 2b 3d 20 70  p->nMinPage += p
4eb0: 43 61 63 68 65 2d 3e 6e 4d 69 6e 3b 0a 20 20 20  Cache->nMin;.   
4ec0: 20 20 20 70 47 72 6f 75 70 2d 3e 6d 78 50 69 6e     pGroup->mxPin
4ed0: 6e 65 64 20 3d 20 70 47 72 6f 75 70 2d 3e 6e 4d  ned = pGroup->nM
4ee0: 61 78 50 61 67 65 20 2b 20 31 30 20 2d 20 70 47  axPage + 10 - pG
4ef0: 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67 65 3b 0a  roup->nMinPage;.
4f00: 20 20 20 20 20 20 70 63 61 63 68 65 31 4c 65 61        pcache1Lea
4f10: 76 65 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b  veMutex(pGroup);
4f20: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74  .    }.  }.  ret
4f30: 75 72 6e 20 28 73 71 6c 69 74 65 33 5f 70 63 61  urn (sqlite3_pca
4f40: 63 68 65 20 2a 29 70 43 61 63 68 65 3b 0a 7d 0a  che *)pCache;.}.
4f50: 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74  ./*.** Implement
4f60: 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c  ation of the sql
4f70: 69 74 65 33 5f 70 63 61 63 68 65 2e 78 43 61 63  ite3_pcache.xCac
4f80: 68 65 73 69 7a 65 20 6d 65 74 68 6f 64 2e 20 0a  hesize method. .
4f90: 2a 2a 0a 2a 2a 20 43 6f 6e 66 69 67 75 72 65 20  **.** Configure 
4fa0: 74 68 65 20 63 61 63 68 65 5f 73 69 7a 65 20 6c  the cache_size l
4fb0: 69 6d 69 74 20 66 6f 72 20 61 20 63 61 63 68 65  imit for a cache
4fc0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
4fd0: 20 70 63 61 63 68 65 31 43 61 63 68 65 73 69 7a   pcache1Cachesiz
4fe0: 65 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  e(sqlite3_pcache
4ff0: 20 2a 70 2c 20 69 6e 74 20 6e 4d 61 78 29 7b 0a   *p, int nMax){.
5000: 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68    PCache1 *pCach
5010: 65 20 3d 20 28 50 43 61 63 68 65 31 20 2a 29 70  e = (PCache1 *)p
5020: 3b 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e  ;.  if( pCache->
5030: 62 50 75 72 67 65 61 62 6c 65 20 29 7b 0a 20 20  bPurgeable ){.  
5040: 20 20 50 47 72 6f 75 70 20 2a 70 47 72 6f 75 70    PGroup *pGroup
5050: 20 3d 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75   = pCache->pGrou
5060: 70 3b 0a 20 20 20 20 70 63 61 63 68 65 31 45 6e  p;.    pcache1En
5070: 74 65 72 4d 75 74 65 78 28 70 47 72 6f 75 70 29  terMutex(pGroup)
5080: 3b 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e 6e 4d  ;.    pGroup->nM
5090: 61 78 50 61 67 65 20 2b 3d 20 28 6e 4d 61 78 20  axPage += (nMax 
50a0: 2d 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 29 3b  - pCache->nMax);
50b0: 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e 6d 78 50  .    pGroup->mxP
50c0: 69 6e 6e 65 64 20 3d 20 70 47 72 6f 75 70 2d 3e  inned = pGroup->
50d0: 6e 4d 61 78 50 61 67 65 20 2b 20 31 30 20 2d 20  nMaxPage + 10 - 
50e0: 70 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67 65  pGroup->nMinPage
50f0: 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 6e 4d  ;.    pCache->nM
5100: 61 78 20 3d 20 6e 4d 61 78 3b 0a 20 20 20 20 70  ax = nMax;.    p
5110: 43 61 63 68 65 2d 3e 6e 39 30 70 63 74 20 3d 20  Cache->n90pct = 
5120: 70 43 61 63 68 65 2d 3e 6e 4d 61 78 2a 39 2f 31  pCache->nMax*9/1
5130: 30 3b 0a 20 20 20 20 70 63 61 63 68 65 31 45 6e  0;.    pcache1En
5140: 66 6f 72 63 65 4d 61 78 50 61 67 65 28 70 47 72  forceMaxPage(pGr
5150: 6f 75 70 29 3b 0a 20 20 20 20 70 63 61 63 68 65  oup);.    pcache
5160: 31 4c 65 61 76 65 4d 75 74 65 78 28 70 47 72 6f  1LeaveMutex(pGro
5170: 75 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a  up);.  }.}../*.*
5180: 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  * Implementation
5190: 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f   of the sqlite3_
51a0: 70 63 61 63 68 65 2e 78 53 68 72 69 6e 6b 20 6d  pcache.xShrink m
51b0: 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20 46 72  ethod. .**.** Fr
51c0: 65 65 20 75 70 20 61 73 20 6d 75 63 68 20 6d 65  ee up as much me
51d0: 6d 6f 72 79 20 61 73 20 70 6f 73 73 69 62 6c 65  mory as possible
51e0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
51f0: 20 70 63 61 63 68 65 31 53 68 72 69 6e 6b 28 73   pcache1Shrink(s
5200: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70  qlite3_pcache *p
5210: 29 7b 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43  ){.  PCache1 *pC
5220: 61 63 68 65 20 3d 20 28 50 43 61 63 68 65 31 2a  ache = (PCache1*
5230: 29 70 3b 0a 20 20 69 66 28 20 70 43 61 63 68 65  )p;.  if( pCache
5240: 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 29 7b 0a  ->bPurgeable ){.
5250: 20 20 20 20 50 47 72 6f 75 70 20 2a 70 47 72 6f      PGroup *pGro
5260: 75 70 20 3d 20 70 43 61 63 68 65 2d 3e 70 47 72  up = pCache->pGr
5270: 6f 75 70 3b 0a 20 20 20 20 69 6e 74 20 73 61 76  oup;.    int sav
5280: 65 64 4d 61 78 50 61 67 65 3b 0a 20 20 20 20 70  edMaxPage;.    p
5290: 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78  cache1EnterMutex
52a0: 28 70 47 72 6f 75 70 29 3b 0a 20 20 20 20 73 61  (pGroup);.    sa
52b0: 76 65 64 4d 61 78 50 61 67 65 20 3d 20 70 47 72  vedMaxPage = pGr
52c0: 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65 3b 0a 20  oup->nMaxPage;. 
52d0: 20 20 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50     pGroup->nMaxP
52e0: 61 67 65 20 3d 20 30 3b 0a 20 20 20 20 70 63 61  age = 0;.    pca
52f0: 63 68 65 31 45 6e 66 6f 72 63 65 4d 61 78 50 61  che1EnforceMaxPa
5300: 67 65 28 70 47 72 6f 75 70 29 3b 0a 20 20 20 20  ge(pGroup);.    
5310: 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65  pGroup->nMaxPage
5320: 20 3d 20 73 61 76 65 64 4d 61 78 50 61 67 65 3b   = savedMaxPage;
5330: 0a 20 20 20 20 70 63 61 63 68 65 31 4c 65 61 76  .    pcache1Leav
5340: 65 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b 0a  eMutex(pGroup);.
5350: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70    }.}../*.** Imp
5360: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74  lementation of t
5370: 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68  he sqlite3_pcach
5380: 65 2e 78 50 61 67 65 63 6f 75 6e 74 20 6d 65 74  e.xPagecount met
5390: 68 6f 64 2e 20 0a 2a 2f 0a 73 74 61 74 69 63 20  hod. .*/.static 
53a0: 69 6e 74 20 70 63 61 63 68 65 31 50 61 67 65 63  int pcache1Pagec
53b0: 6f 75 6e 74 28 73 71 6c 69 74 65 33 5f 70 63 61  ount(sqlite3_pca
53c0: 63 68 65 20 2a 70 29 7b 0a 20 20 69 6e 74 20 6e  che *p){.  int n
53d0: 3b 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43 61  ;.  PCache1 *pCa
53e0: 63 68 65 20 3d 20 28 50 43 61 63 68 65 31 2a 29  che = (PCache1*)
53f0: 70 3b 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65  p;.  pcache1Ente
5400: 72 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e 70  rMutex(pCache->p
5410: 47 72 6f 75 70 29 3b 0a 20 20 6e 20 3d 20 70 43  Group);.  n = pC
5420: 61 63 68 65 2d 3e 6e 50 61 67 65 3b 0a 20 20 70  ache->nPage;.  p
5430: 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78  cache1LeaveMutex
5440: 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 29  (pCache->pGroup)
5450: 3b 0a 20 20 72 65 74 75 72 6e 20 6e 3b 0a 7d 0a  ;.  return n;.}.
5460: 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74  ./*.** Implement
5470: 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c  ation of the sql
5480: 69 74 65 33 5f 70 63 61 63 68 65 2e 78 46 65 74  ite3_pcache.xFet
5490: 63 68 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a  ch method. .**.*
54a0: 2a 20 46 65 74 63 68 20 61 20 70 61 67 65 20 62  * Fetch a page b
54b0: 79 20 6b 65 79 20 76 61 6c 75 65 2e 0a 2a 2a 0a  y key value..**.
54c0: 2a 2a 20 57 68 65 74 68 65 72 20 6f 72 20 6e 6f  ** Whether or no
54d0: 74 20 61 20 6e 65 77 20 70 61 67 65 20 6d 61 79  t a new page may
54e0: 20 62 65 20 61 6c 6c 6f 63 61 74 65 64 20 62 79   be allocated by
54f0: 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 64   this function d
5500: 65 70 65 6e 64 73 20 6f 6e 0a 2a 2a 20 74 68 65  epends on.** the
5510: 20 76 61 6c 75 65 20 6f 66 20 74 68 65 20 63 72   value of the cr
5520: 65 61 74 65 46 6c 61 67 20 61 72 67 75 6d 65 6e  eateFlag argumen
5530: 74 2e 20 20 30 20 6d 65 61 6e 73 20 64 6f 20 6e  t.  0 means do n
5540: 6f 74 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e 65  ot allocate a ne
5550: 77 0a 2a 2a 20 70 61 67 65 2e 20 20 31 20 6d 65  w.** page.  1 me
5560: 61 6e 73 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e  ans allocate a n
5570: 65 77 20 70 61 67 65 20 69 66 20 73 70 61 63 65  ew page if space
5580: 20 69 73 20 65 61 73 69 6c 79 20 61 76 61 69 6c   is easily avail
5590: 61 62 6c 65 2e 20 20 32 20 0a 2a 2a 20 6d 65 61  able.  2 .** mea
55a0: 6e 73 20 74 6f 20 74 72 79 20 72 65 61 6c 6c 79  ns to try really
55b0: 20 68 61 72 64 20 74 6f 20 61 6c 6c 6f 63 61 74   hard to allocat
55c0: 65 20 61 20 6e 65 77 20 70 61 67 65 2e 0a 2a 2a  e a new page..**
55d0: 0a 2a 2a 20 46 6f 72 20 61 20 6e 6f 6e 2d 70 75  .** For a non-pu
55e0: 72 67 65 61 62 6c 65 20 63 61 63 68 65 20 28 61  rgeable cache (a
55f0: 20 63 61 63 68 65 20 75 73 65 64 20 61 73 20 74   cache used as t
5600: 68 65 20 73 74 6f 72 61 67 65 20 66 6f 72 20 61  he storage for a
5610: 6e 20 69 6e 2d 6d 65 6d 6f 72 79 0a 2a 2a 20 64  n in-memory.** d
5620: 61 74 61 62 61 73 65 29 20 74 68 65 72 65 20 69  atabase) there i
5630: 73 20 72 65 61 6c 6c 79 20 6e 6f 20 64 69 66 66  s really no diff
5640: 65 72 65 6e 63 65 20 62 65 74 77 65 65 6e 20 63  erence between c
5650: 72 65 61 74 65 46 6c 61 67 20 31 20 61 6e 64 20  reateFlag 1 and 
5660: 32 2e 20 20 53 6f 0a 2a 2a 20 74 68 65 20 63 61  2.  So.** the ca
5670: 6c 6c 69 6e 67 20 66 75 6e 63 74 69 6f 6e 20 28  lling function (
5680: 70 63 61 63 68 65 2e 63 29 20 77 69 6c 6c 20 6e  pcache.c) will n
5690: 65 76 65 72 20 68 61 76 65 20 61 20 63 72 65 61  ever have a crea
56a0: 74 65 46 6c 61 67 20 6f 66 20 31 20 6f 6e 0a 2a  teFlag of 1 on.*
56b0: 2a 20 61 20 6e 6f 6e 2d 70 75 72 67 65 61 62 6c  * a non-purgeabl
56c0: 65 20 63 61 63 68 65 2e 0a 2a 2a 0a 2a 2a 20 54  e cache..**.** T
56d0: 68 65 72 65 20 61 72 65 20 74 68 72 65 65 20 64  here are three d
56e0: 69 66 66 65 72 65 6e 74 20 61 70 70 72 6f 61 63  ifferent approac
56f0: 68 65 73 20 74 6f 20 6f 62 74 61 69 6e 69 6e 67  hes to obtaining
5700: 20 73 70 61 63 65 20 66 6f 72 20 61 20 70 61 67   space for a pag
5710: 65 2c 0a 2a 2a 20 64 65 70 65 6e 64 69 6e 67 20  e,.** depending 
5720: 6f 6e 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20  on the value of 
5730: 70 61 72 61 6d 65 74 65 72 20 63 72 65 61 74 65  parameter create
5740: 46 6c 61 67 20 28 77 68 69 63 68 20 6d 61 79 20  Flag (which may 
5750: 62 65 20 30 2c 20 31 20 6f 72 20 32 29 2e 0a 2a  be 0, 1 or 2)..*
5760: 2a 0a 2a 2a 20 20 20 31 2e 20 52 65 67 61 72 64  *.**   1. Regard
5770: 6c 65 73 73 20 6f 66 20 74 68 65 20 76 61 6c 75  less of the valu
5780: 65 20 6f 66 20 63 72 65 61 74 65 46 6c 61 67 2c  e of createFlag,
5790: 20 74 68 65 20 63 61 63 68 65 20 69 73 20 73 65   the cache is se
57a0: 61 72 63 68 65 64 20 66 6f 72 20 61 20 0a 2a 2a  arched for a .**
57b0: 20 20 20 20 20 20 63 6f 70 79 20 6f 66 20 74 68        copy of th
57c0: 65 20 72 65 71 75 65 73 74 65 64 20 70 61 67 65  e requested page
57d0: 2e 20 49 66 20 6f 6e 65 20 69 73 20 66 6f 75 6e  . If one is foun
57e0: 64 2c 20 69 74 20 69 73 20 72 65 74 75 72 6e 65  d, it is returne
57f0: 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 32 2e 20 49 66  d..**.**   2. If
5800: 20 63 72 65 61 74 65 46 6c 61 67 3d 3d 30 20 61   createFlag==0 a
5810: 6e 64 20 74 68 65 20 70 61 67 65 20 69 73 20 6e  nd the page is n
5820: 6f 74 20 61 6c 72 65 61 64 79 20 69 6e 20 74 68  ot already in th
5830: 65 20 63 61 63 68 65 2c 20 4e 55 4c 4c 20 69 73  e cache, NULL is
5840: 0a 2a 2a 20 20 20 20 20 20 72 65 74 75 72 6e 65  .**      returne
5850: 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 33 2e 20 49 66  d..**.**   3. If
5860: 20 63 72 65 61 74 65 46 6c 61 67 20 69 73 20 31   createFlag is 1
5870: 2c 20 61 6e 64 20 74 68 65 20 70 61 67 65 20 69  , and the page i
5880: 73 20 6e 6f 74 20 61 6c 72 65 61 64 79 20 69 6e  s not already in
5890: 20 74 68 65 20 63 61 63 68 65 2c 20 74 68 65 6e   the cache, then
58a0: 0a 2a 2a 20 20 20 20 20 20 72 65 74 75 72 6e 20  .**      return 
58b0: 4e 55 4c 4c 20 28 64 6f 20 6e 6f 74 20 61 6c 6c  NULL (do not all
58c0: 6f 63 61 74 65 20 61 20 6e 65 77 20 70 61 67 65  ocate a new page
58d0: 29 20 69 66 20 61 6e 79 20 6f 66 20 74 68 65 20  ) if any of the 
58e0: 66 6f 6c 6c 6f 77 69 6e 67 0a 2a 2a 20 20 20 20  following.**    
58f0: 20 20 63 6f 6e 64 69 74 69 6f 6e 73 20 61 72 65    conditions are
5900: 20 74 72 75 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20   true:.**.**    
5910: 20 20 20 28 61 29 20 74 68 65 20 6e 75 6d 62 65     (a) the numbe
5920: 72 20 6f 66 20 70 61 67 65 73 20 70 69 6e 6e 65  r of pages pinne
5930: 64 20 62 79 20 74 68 65 20 63 61 63 68 65 20 69  d by the cache i
5940: 73 20 67 72 65 61 74 65 72 20 74 68 61 6e 0a 2a  s greater than.*
5950: 2a 20 20 20 20 20 20 20 20 20 20 20 50 43 61 63  *           PCac
5960: 68 65 31 2e 6e 4d 61 78 2c 20 6f 72 0a 2a 2a 0a  he1.nMax, or.**.
5970: 2a 2a 20 20 20 20 20 20 20 28 62 29 20 74 68 65  **       (b) the
5980: 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73   number of pages
5990: 20 70 69 6e 6e 65 64 20 62 79 20 74 68 65 20 63   pinned by the c
59a0: 61 63 68 65 20 69 73 20 67 72 65 61 74 65 72 20  ache is greater 
59b0: 74 68 61 6e 0a 2a 2a 20 20 20 20 20 20 20 20 20  than.**         
59c0: 20 20 74 68 65 20 73 75 6d 20 6f 66 20 6e 4d 61    the sum of nMa
59d0: 78 20 66 6f 72 20 61 6c 6c 20 70 75 72 67 65 61  x for all purgea
59e0: 62 6c 65 20 63 61 63 68 65 73 2c 20 6c 65 73 73  ble caches, less
59f0: 20 74 68 65 20 73 75 6d 20 6f 66 20 0a 2a 2a 20   the sum of .** 
5a00: 20 20 20 20 20 20 20 20 20 20 6e 4d 69 6e 20 66            nMin f
5a10: 6f 72 20 61 6c 6c 20 6f 74 68 65 72 20 70 75 72  or all other pur
5a20: 67 65 61 62 6c 65 20 63 61 63 68 65 73 2c 20 6f  geable caches, o
5a30: 72 0a 2a 2a 0a 2a 2a 20 20 20 34 2e 20 49 66 20  r.**.**   4. If 
5a40: 6e 6f 6e 65 20 6f 66 20 74 68 65 20 66 69 72 73  none of the firs
5a50: 74 20 74 68 72 65 65 20 63 6f 6e 64 69 74 69 6f  t three conditio
5a60: 6e 73 20 61 70 70 6c 79 20 61 6e 64 20 74 68 65  ns apply and the
5a70: 20 63 61 63 68 65 20 69 73 20 6d 61 72 6b 65 64   cache is marked
5a80: 0a 2a 2a 20 20 20 20 20 20 61 73 20 70 75 72 67  .**      as purg
5a90: 65 61 62 6c 65 2c 20 61 6e 64 20 69 66 20 6f 6e  eable, and if on
5aa0: 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69  e of the followi
5ab0: 6e 67 20 69 73 20 74 72 75 65 3a 0a 2a 2a 0a 2a  ng is true:.**.*
5ac0: 2a 20 20 20 20 20 20 20 28 61 29 20 54 68 65 20  *       (a) The 
5ad0: 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20  number of pages 
5ae0: 61 6c 6c 6f 63 61 74 65 64 20 66 6f 72 20 74 68  allocated for th
5af0: 65 20 63 61 63 68 65 20 69 73 20 61 6c 72 65 61  e cache is alrea
5b00: 64 79 20 0a 2a 2a 20 20 20 20 20 20 20 20 20 20  dy .**          
5b10: 20 50 43 61 63 68 65 31 2e 6e 4d 61 78 2c 20 6f   PCache1.nMax, o
5b20: 72 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 28 62  r.**.**       (b
5b30: 29 20 54 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  ) The number of 
5b40: 70 61 67 65 73 20 61 6c 6c 6f 63 61 74 65 64 20  pages allocated 
5b50: 66 6f 72 20 61 6c 6c 20 70 75 72 67 65 61 62 6c  for all purgeabl
5b60: 65 20 63 61 63 68 65 73 20 69 73 0a 2a 2a 20 20  e caches is.**  
5b70: 20 20 20 20 20 20 20 20 20 61 6c 72 65 61 64 79           already
5b80: 20 65 71 75 61 6c 20 74 6f 20 6f 72 20 67 72 65   equal to or gre
5b90: 61 74 65 72 20 74 68 61 6e 20 74 68 65 20 73 75  ater than the su
5ba0: 6d 20 6f 66 20 6e 4d 61 78 20 66 6f 72 20 61 6c  m of nMax for al
5bb0: 6c 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 70  l.**           p
5bc0: 75 72 67 65 61 62 6c 65 20 63 61 63 68 65 73 2c  urgeable caches,
5bd0: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 28 63 29  .**.**       (c)
5be0: 20 54 68 65 20 73 79 73 74 65 6d 20 69 73 20 75   The system is u
5bf0: 6e 64 65 72 20 6d 65 6d 6f 72 79 20 70 72 65 73  nder memory pres
5c00: 73 75 72 65 20 61 6e 64 20 77 61 6e 74 73 20 74  sure and wants t
5c10: 6f 20 61 76 6f 69 64 0a 2a 2a 20 20 20 20 20 20  o avoid.**      
5c20: 20 20 20 20 20 75 6e 6e 65 63 65 73 73 61 72 79       unnecessary
5c30: 20 70 61 67 65 73 20 63 61 63 68 65 20 65 6e 74   pages cache ent
5c40: 72 79 20 61 6c 6c 6f 63 61 74 69 6f 6e 73 0a 2a  ry allocations.*
5c50: 2a 0a 2a 2a 20 20 20 20 20 20 74 68 65 6e 20 61  *.**      then a
5c60: 74 74 65 6d 70 74 20 74 6f 20 72 65 63 79 63 6c  ttempt to recycl
5c70: 65 20 61 20 70 61 67 65 20 66 72 6f 6d 20 74 68  e a page from th
5c80: 65 20 4c 52 55 20 6c 69 73 74 2e 20 49 66 20 69  e LRU list. If i
5c90: 74 20 69 73 20 74 68 65 20 72 69 67 68 74 0a 2a  t is the right.*
5ca0: 2a 20 20 20 20 20 20 73 69 7a 65 2c 20 72 65 74  *      size, ret
5cb0: 75 72 6e 20 74 68 65 20 72 65 63 79 63 6c 65 64  urn the recycled
5cc0: 20 62 75 66 66 65 72 2e 20 4f 74 68 65 72 77 69   buffer. Otherwi
5cd0: 73 65 2c 20 66 72 65 65 20 74 68 65 20 62 75 66  se, free the buf
5ce0: 66 65 72 20 61 6e 64 0a 2a 2a 20 20 20 20 20 20  fer and.**      
5cf0: 70 72 6f 63 65 65 64 20 74 6f 20 73 74 65 70 20  proceed to step 
5d00: 35 2e 20 0a 2a 2a 0a 2a 2a 20 20 20 35 2e 20 4f  5. .**.**   5. O
5d10: 74 68 65 72 77 69 73 65 2c 20 61 6c 6c 6f 63 61  therwise, alloca
5d20: 74 65 20 61 6e 64 20 72 65 74 75 72 6e 20 61 20  te and return a 
5d30: 6e 65 77 20 70 61 67 65 20 62 75 66 66 65 72 2e  new page buffer.
5d40: 0a 2a 2f 0a 73 74 61 74 69 63 20 73 71 6c 69 74  .*/.static sqlit
5d50: 65 33 5f 70 63 61 63 68 65 5f 70 61 67 65 20 2a  e3_pcache_page *
5d60: 70 63 61 63 68 65 31 46 65 74 63 68 28 0a 20 20  pcache1Fetch(.  
5d70: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a  sqlite3_pcache *
5d80: 70 2c 20 0a 20 20 75 6e 73 69 67 6e 65 64 20 69  p, .  unsigned i
5d90: 6e 74 20 69 4b 65 79 2c 20 0a 20 20 69 6e 74 20  nt iKey, .  int 
5da0: 63 72 65 61 74 65 46 6c 61 67 0a 29 7b 0a 20 20  createFlag.){.  
5db0: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 50 69  unsigned int nPi
5dc0: 6e 6e 65 64 3b 0a 20 20 50 43 61 63 68 65 31 20  nned;.  PCache1 
5dd0: 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61 63 68  *pCache = (PCach
5de0: 65 31 20 2a 29 70 3b 0a 20 20 50 47 72 6f 75 70  e1 *)p;.  PGroup
5df0: 20 2a 70 47 72 6f 75 70 3b 0a 20 20 50 67 48 64   *pGroup;.  PgHd
5e00: 72 31 20 2a 70 50 61 67 65 20 3d 20 30 3b 0a 0a  r1 *pPage = 0;..
5e10: 20 20 61 73 73 65 72 74 28 20 6f 66 66 73 65 74    assert( offset
5e20: 6f 66 28 50 67 48 64 72 31 2c 70 61 67 65 29 3d  of(PgHdr1,page)=
5e30: 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  =0 );.  assert( 
5e40: 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62  pCache->bPurgeab
5e50: 6c 65 20 7c 7c 20 63 72 65 61 74 65 46 6c 61 67  le || createFlag
5e60: 21 3d 31 20 29 3b 0a 20 20 61 73 73 65 72 74 28  !=1 );.  assert(
5e70: 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61   pCache->bPurgea
5e80: 62 6c 65 20 7c 7c 20 70 43 61 63 68 65 2d 3e 6e  ble || pCache->n
5e90: 4d 69 6e 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65  Min==0 );.  asse
5ea0: 72 74 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72  rt( pCache->bPur
5eb0: 67 65 61 62 6c 65 3d 3d 30 20 7c 7c 20 70 43 61  geable==0 || pCa
5ec0: 63 68 65 2d 3e 6e 4d 69 6e 3d 3d 31 30 20 29 3b  che->nMin==10 );
5ed0: 0a 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68  .  assert( pCach
5ee0: 65 2d 3e 6e 4d 69 6e 3d 3d 30 20 7c 7c 20 70 43  e->nMin==0 || pC
5ef0: 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65  ache->bPurgeable
5f00: 20 29 3b 0a 20 20 70 63 61 63 68 65 31 45 6e 74   );.  pcache1Ent
5f10: 65 72 4d 75 74 65 78 28 70 47 72 6f 75 70 20 3d  erMutex(pGroup =
5f20: 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 29   pCache->pGroup)
5f30: 3b 0a 0a 20 20 2f 2a 20 53 74 65 70 20 31 3a 20  ;..  /* Step 1: 
5f40: 53 65 61 72 63 68 20 74 68 65 20 68 61 73 68 20  Search the hash 
5f50: 74 61 62 6c 65 20 66 6f 72 20 61 6e 20 65 78 69  table for an exi
5f60: 73 74 69 6e 67 20 65 6e 74 72 79 2e 20 2a 2f 0a  sting entry. */.
5f70: 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 6e 48    if( pCache->nH
5f80: 61 73 68 3e 30 20 29 7b 0a 20 20 20 20 75 6e 73  ash>0 ){.    uns
5f90: 69 67 6e 65 64 20 69 6e 74 20 68 20 3d 20 69 4b  igned int h = iK
5fa0: 65 79 20 25 20 70 43 61 63 68 65 2d 3e 6e 48 61  ey % pCache->nHa
5fb0: 73 68 3b 0a 20 20 20 20 66 6f 72 28 70 50 61 67  sh;.    for(pPag
5fc0: 65 3d 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68  e=pCache->apHash
5fd0: 5b 68 5d 3b 20 70 50 61 67 65 26 26 70 50 61 67  [h]; pPage&&pPag
5fe0: 65 2d 3e 69 4b 65 79 21 3d 69 4b 65 79 3b 20 70  e->iKey!=iKey; p
5ff0: 50 61 67 65 3d 70 50 61 67 65 2d 3e 70 4e 65 78  Page=pPage->pNex
6000: 74 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53 74  t);.  }..  /* St
6010: 65 70 20 32 3a 20 41 62 6f 72 74 20 69 66 20 6e  ep 2: Abort if n
6020: 6f 20 65 78 69 73 74 69 6e 67 20 70 61 67 65 20  o existing page 
6030: 69 73 20 66 6f 75 6e 64 20 61 6e 64 20 63 72 65  is found and cre
6040: 61 74 65 46 6c 61 67 20 69 73 20 30 20 2a 2f 0a  ateFlag is 0 */.
6050: 20 20 69 66 28 20 70 50 61 67 65 20 29 7b 0a 20    if( pPage ){. 
6060: 20 20 20 69 66 28 20 21 70 50 61 67 65 2d 3e 69     if( !pPage->i
6070: 73 50 69 6e 6e 65 64 20 29 20 70 63 61 63 68 65  sPinned ) pcache
6080: 31 50 69 6e 50 61 67 65 28 70 50 61 67 65 29 3b  1PinPage(pPage);
6090: 0a 20 20 20 20 67 6f 74 6f 20 66 65 74 63 68 5f  .    goto fetch_
60a0: 6f 75 74 3b 0a 20 20 7d 0a 20 20 69 66 28 20 63  out;.  }.  if( c
60b0: 72 65 61 74 65 46 6c 61 67 3d 3d 30 20 29 7b 0a  reateFlag==0 ){.
60c0: 20 20 20 20 67 6f 74 6f 20 66 65 74 63 68 5f 6f      goto fetch_o
60d0: 75 74 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 54 68  ut;.  }..  /* Th
60e0: 65 20 70 47 72 6f 75 70 20 6c 6f 63 61 6c 20 76  e pGroup local v
60f0: 61 72 69 61 62 6c 65 20 77 69 6c 6c 20 6e 6f 72  ariable will nor
6100: 6d 61 6c 6c 79 20 62 65 20 69 6e 69 74 69 61 6c  mally be initial
6110: 69 7a 65 64 20 62 79 20 74 68 65 0a 20 20 2a 2a  ized by the.  **
6120: 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74   pcache1EnterMut
6130: 65 78 28 29 20 6d 61 63 72 6f 20 61 62 6f 76 65  ex() macro above
6140: 2e 20 20 42 75 74 20 69 66 20 53 51 4c 49 54 45  .  But if SQLITE
6150: 5f 4d 55 54 45 58 5f 4f 4d 49 54 20 69 73 20 64  _MUTEX_OMIT is d
6160: 65 66 69 6e 65 64 2c 0a 20 20 2a 2a 20 74 68 65  efined,.  ** the
6170: 6e 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75  n pcache1EnterMu
6180: 74 65 78 28 29 20 69 73 20 61 20 6e 6f 2d 6f 70  tex() is a no-op
6190: 2c 20 73 6f 20 77 65 20 68 61 76 65 20 74 6f 20  , so we have to 
61a0: 69 6e 69 74 69 61 6c 69 7a 65 20 74 68 65 0a 20  initialize the. 
61b0: 20 2a 2a 20 6c 6f 63 61 6c 20 76 61 72 69 61 62   ** local variab
61c0: 6c 65 20 68 65 72 65 2e 20 20 44 65 6c 61 79 69  le here.  Delayi
61d0: 6e 67 20 74 68 65 20 69 6e 69 74 69 61 6c 69 7a  ng the initializ
61e0: 61 74 69 6f 6e 20 6f 66 20 70 47 72 6f 75 70 20  ation of pGroup 
61f0: 69 73 20 61 6e 0a 20 20 2a 2a 20 6f 70 74 69 6d  is an.  ** optim
6200: 69 7a 61 74 69 6f 6e 3a 20 20 54 68 65 20 63 6f  ization:  The co
6210: 6d 6d 6f 6e 20 63 61 73 65 20 69 73 20 74 6f 20  mmon case is to 
6220: 65 78 69 74 20 74 68 65 20 6d 6f 64 75 6c 65 20  exit the module 
6230: 62 65 66 6f 72 65 20 72 65 61 63 68 69 6e 67 0a  before reaching.
6240: 20 20 2a 2a 20 74 68 69 73 20 70 6f 69 6e 74 2e    ** this point.
6250: 0a 20 20 2a 2f 0a 23 69 66 64 65 66 20 53 51 4c  .  */.#ifdef SQL
6260: 49 54 45 5f 4d 55 54 45 58 5f 4f 4d 49 54 0a 20  ITE_MUTEX_OMIT. 
6270: 20 70 47 72 6f 75 70 20 3d 20 70 43 61 63 68 65   pGroup = pCache
6280: 2d 3e 70 47 72 6f 75 70 3b 0a 23 65 6e 64 69 66  ->pGroup;.#endif
6290: 0a 0a 20 20 2f 2a 20 53 74 65 70 20 33 3a 20 41  ..  /* Step 3: A
62a0: 62 6f 72 74 20 69 66 20 63 72 65 61 74 65 46 6c  bort if createFl
62b0: 61 67 20 69 73 20 31 20 62 75 74 20 74 68 65 20  ag is 1 but the 
62c0: 63 61 63 68 65 20 69 73 20 6e 65 61 72 6c 79 20  cache is nearly 
62d0: 66 75 6c 6c 20 2a 2f 0a 20 20 61 73 73 65 72 74  full */.  assert
62e0: 28 20 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 20  ( pCache->nPage 
62f0: 3e 3d 20 70 43 61 63 68 65 2d 3e 6e 52 65 63 79  >= pCache->nRecy
6300: 63 6c 61 62 6c 65 20 29 3b 0a 20 20 6e 50 69 6e  clable );.  nPin
6310: 6e 65 64 20 3d 20 70 43 61 63 68 65 2d 3e 6e 50  ned = pCache->nP
6320: 61 67 65 20 2d 20 70 43 61 63 68 65 2d 3e 6e 52  age - pCache->nR
6330: 65 63 79 63 6c 61 62 6c 65 3b 0a 20 20 61 73 73  ecyclable;.  ass
6340: 65 72 74 28 20 70 47 72 6f 75 70 2d 3e 6d 78 50  ert( pGroup->mxP
6350: 69 6e 6e 65 64 20 3d 3d 20 70 47 72 6f 75 70 2d  inned == pGroup-
6360: 3e 6e 4d 61 78 50 61 67 65 20 2b 20 31 30 20 2d  >nMaxPage + 10 -
6370: 20 70 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67   pGroup->nMinPag
6380: 65 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70  e );.  assert( p
6390: 43 61 63 68 65 2d 3e 6e 39 30 70 63 74 20 3d 3d  Cache->n90pct ==
63a0: 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 2a 39 2f   pCache->nMax*9/
63b0: 31 30 20 29 3b 0a 20 20 69 66 28 20 63 72 65 61  10 );.  if( crea
63c0: 74 65 46 6c 61 67 3d 3d 31 20 26 26 20 28 0a 20  teFlag==1 && (. 
63d0: 20 20 20 20 20 20 20 6e 50 69 6e 6e 65 64 3e 3d         nPinned>=
63e0: 70 47 72 6f 75 70 2d 3e 6d 78 50 69 6e 6e 65 64  pGroup->mxPinned
63f0: 0a 20 20 20 20 20 7c 7c 20 6e 50 69 6e 6e 65 64  .     || nPinned
6400: 3e 3d 70 43 61 63 68 65 2d 3e 6e 39 30 70 63 74  >=pCache->n90pct
6410: 0a 20 20 20 20 20 7c 7c 20 70 63 61 63 68 65 31  .     || pcache1
6420: 55 6e 64 65 72 4d 65 6d 6f 72 79 50 72 65 73 73  UnderMemoryPress
6430: 75 72 65 28 70 43 61 63 68 65 29 0a 20 20 29 29  ure(pCache).  ))
6440: 7b 0a 20 20 20 20 67 6f 74 6f 20 66 65 74 63 68  {.    goto fetch
6450: 5f 6f 75 74 3b 0a 20 20 7d 0a 0a 20 20 69 66 28  _out;.  }..  if(
6460: 20 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 3e 3d   pCache->nPage>=
6470: 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 20 26 26  pCache->nHash &&
6480: 20 70 63 61 63 68 65 31 52 65 73 69 7a 65 48 61   pcache1ResizeHa
6490: 73 68 28 70 43 61 63 68 65 29 20 29 7b 0a 20 20  sh(pCache) ){.  
64a0: 20 20 67 6f 74 6f 20 66 65 74 63 68 5f 6f 75 74    goto fetch_out
64b0: 3b 0a 20 20 7d 0a 20 20 61 73 73 65 72 74 28 20  ;.  }.  assert( 
64c0: 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3e 30 20  pCache->nHash>0 
64d0: 26 26 20 70 43 61 63 68 65 2d 3e 61 70 48 61 73  && pCache->apHas
64e0: 68 20 29 3b 0a 0a 20 20 2f 2a 20 53 74 65 70 20  h );..  /* Step 
64f0: 34 2e 20 54 72 79 20 74 6f 20 72 65 63 79 63 6c  4. Try to recycl
6500: 65 20 61 20 70 61 67 65 2e 20 2a 2f 0a 20 20 69  e a page. */.  i
6510: 66 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67  f( pCache->bPurg
6520: 65 61 62 6c 65 20 26 26 20 70 47 72 6f 75 70 2d  eable && pGroup-
6530: 3e 70 4c 72 75 54 61 69 6c 20 26 26 20 28 0a 20  >pLruTail && (. 
6540: 20 20 20 20 20 20 20 20 28 70 43 61 63 68 65 2d          (pCache-
6550: 3e 6e 50 61 67 65 2b 31 3e 3d 70 43 61 63 68 65  >nPage+1>=pCache
6560: 2d 3e 6e 4d 61 78 29 0a 20 20 20 20 20 20 7c 7c  ->nMax).      ||
6570: 20 70 47 72 6f 75 70 2d 3e 6e 43 75 72 72 65 6e   pGroup->nCurren
6580: 74 50 61 67 65 3e 3d 70 47 72 6f 75 70 2d 3e 6e  tPage>=pGroup->n
6590: 4d 61 78 50 61 67 65 0a 20 20 20 20 20 20 7c 7c  MaxPage.      ||
65a0: 20 70 63 61 63 68 65 31 55 6e 64 65 72 4d 65 6d   pcache1UnderMem
65b0: 6f 72 79 50 72 65 73 73 75 72 65 28 70 43 61 63  oryPressure(pCac
65c0: 68 65 29 0a 20 20 29 29 7b 0a 20 20 20 20 50 43  he).  )){.    PC
65d0: 61 63 68 65 31 20 2a 70 4f 74 68 65 72 3b 0a 20  ache1 *pOther;. 
65e0: 20 20 20 70 50 61 67 65 20 3d 20 70 47 72 6f 75     pPage = pGrou
65f0: 70 2d 3e 70 4c 72 75 54 61 69 6c 3b 0a 20 20 20  p->pLruTail;.   
6600: 20 61 73 73 65 72 74 28 20 70 50 61 67 65 2d 3e   assert( pPage->
6610: 69 73 50 69 6e 6e 65 64 3d 3d 30 20 29 3b 0a 20  isPinned==0 );. 
6620: 20 20 20 70 63 61 63 68 65 31 52 65 6d 6f 76 65     pcache1Remove
6630: 46 72 6f 6d 48 61 73 68 28 70 50 61 67 65 29 3b  FromHash(pPage);
6640: 0a 20 20 20 20 70 63 61 63 68 65 31 50 69 6e 50  .    pcache1PinP
6650: 61 67 65 28 70 50 61 67 65 29 3b 0a 20 20 20 20  age(pPage);.    
6660: 70 4f 74 68 65 72 20 3d 20 70 50 61 67 65 2d 3e  pOther = pPage->
6670: 70 43 61 63 68 65 3b 0a 0a 20 20 20 20 2f 2a 20  pCache;..    /* 
6680: 57 65 20 77 61 6e 74 20 74 6f 20 76 65 72 69 66  We want to verif
6690: 79 20 74 68 61 74 20 73 7a 50 61 67 65 20 61 6e  y that szPage an
66a0: 64 20 73 7a 45 78 74 72 61 20 61 72 65 20 74 68  d szExtra are th
66b0: 65 20 73 61 6d 65 20 66 6f 72 20 70 4f 74 68 65  e same for pOthe
66c0: 72 0a 20 20 20 20 2a 2a 20 61 6e 64 20 70 43 61  r.    ** and pCa
66d0: 63 68 65 2e 20 20 41 73 73 65 72 74 20 74 68 61  che.  Assert tha
66e0: 74 20 77 65 20 63 61 6e 20 76 65 72 69 66 79 20  t we can verify 
66f0: 74 68 69 73 20 62 79 20 63 6f 6d 70 61 72 69 6e  this by comparin
6700: 67 20 73 75 6d 73 2e 20 2a 2f 0a 20 20 20 20 61  g sums. */.    a
6710: 73 73 65 72 74 28 20 28 70 43 61 63 68 65 2d 3e  ssert( (pCache->
6720: 73 7a 50 61 67 65 20 26 20 28 70 43 61 63 68 65  szPage & (pCache
6730: 2d 3e 73 7a 50 61 67 65 2d 31 29 29 3d 3d 30 20  ->szPage-1))==0 
6740: 26 26 20 70 43 61 63 68 65 2d 3e 73 7a 50 61 67  && pCache->szPag
6750: 65 3e 3d 35 31 32 20 29 3b 0a 20 20 20 20 61 73  e>=512 );.    as
6760: 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e 73 7a  sert( pCache->sz
6770: 45 78 74 72 61 3c 35 31 32 20 29 3b 0a 20 20 20  Extra<512 );.   
6780: 20 61 73 73 65 72 74 28 20 28 70 4f 74 68 65 72   assert( (pOther
6790: 2d 3e 73 7a 50 61 67 65 20 26 20 28 70 4f 74 68  ->szPage & (pOth
67a0: 65 72 2d 3e 73 7a 50 61 67 65 2d 31 29 29 3d 3d  er->szPage-1))==
67b0: 30 20 26 26 20 70 4f 74 68 65 72 2d 3e 73 7a 50  0 && pOther->szP
67c0: 61 67 65 3e 3d 35 31 32 20 29 3b 0a 20 20 20 20  age>=512 );.    
67d0: 61 73 73 65 72 74 28 20 70 4f 74 68 65 72 2d 3e  assert( pOther->
67e0: 73 7a 45 78 74 72 61 3c 35 31 32 20 29 3b 0a 0a  szExtra<512 );..
67f0: 20 20 20 20 69 66 28 20 70 4f 74 68 65 72 2d 3e      if( pOther->
6800: 73 7a 50 61 67 65 2b 70 4f 74 68 65 72 2d 3e 73  szPage+pOther->s
6810: 7a 45 78 74 72 61 20 21 3d 20 70 43 61 63 68 65  zExtra != pCache
6820: 2d 3e 73 7a 50 61 67 65 2b 70 43 61 63 68 65 2d  ->szPage+pCache-
6830: 3e 73 7a 45 78 74 72 61 20 29 7b 0a 20 20 20 20  >szExtra ){.    
6840: 20 20 70 63 61 63 68 65 31 46 72 65 65 50 61 67    pcache1FreePag
6850: 65 28 70 50 61 67 65 29 3b 0a 20 20 20 20 20 20  e(pPage);.      
6860: 70 50 61 67 65 20 3d 20 30 3b 0a 20 20 20 20 7d  pPage = 0;.    }
6870: 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 47 72 6f  else{.      pGro
6880: 75 70 2d 3e 6e 43 75 72 72 65 6e 74 50 61 67 65  up->nCurrentPage
6890: 20 2d 3d 20 28 70 4f 74 68 65 72 2d 3e 62 50 75   -= (pOther->bPu
68a0: 72 67 65 61 62 6c 65 20 2d 20 70 43 61 63 68 65  rgeable - pCache
68b0: 2d 3e 62 50 75 72 67 65 61 62 6c 65 29 3b 0a 20  ->bPurgeable);. 
68c0: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53     }.  }..  /* S
68d0: 74 65 70 20 35 2e 20 49 66 20 61 20 75 73 61 62  tep 5. If a usab
68e0: 6c 65 20 70 61 67 65 20 62 75 66 66 65 72 20 68  le page buffer h
68f0: 61 73 20 73 74 69 6c 6c 20 6e 6f 74 20 62 65 65  as still not bee
6900: 6e 20 66 6f 75 6e 64 2c 20 0a 20 20 2a 2a 20 61  n found, .  ** a
6910: 74 74 65 6d 70 74 20 74 6f 20 61 6c 6c 6f 63 61  ttempt to alloca
6920: 74 65 20 61 20 6e 65 77 20 6f 6e 65 2e 20 0a 20  te a new one. . 
6930: 20 2a 2f 0a 20 20 69 66 28 20 21 70 50 61 67 65   */.  if( !pPage
6940: 20 29 7b 0a 20 20 20 20 69 66 28 20 63 72 65 61   ){.    if( crea
6950: 74 65 46 6c 61 67 3d 3d 31 20 29 20 73 71 6c 69  teFlag==1 ) sqli
6960: 74 65 33 42 65 67 69 6e 42 65 6e 69 67 6e 4d 61  te3BeginBenignMa
6970: 6c 6c 6f 63 28 29 3b 0a 20 20 20 20 70 50 61 67  lloc();.    pPag
6980: 65 20 3d 20 70 63 61 63 68 65 31 41 6c 6c 6f 63  e = pcache1Alloc
6990: 50 61 67 65 28 70 43 61 63 68 65 29 3b 0a 20 20  Page(pCache);.  
69a0: 20 20 69 66 28 20 63 72 65 61 74 65 46 6c 61 67    if( createFlag
69b0: 3d 3d 31 20 29 20 73 71 6c 69 74 65 33 45 6e 64  ==1 ) sqlite3End
69c0: 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 0a  BenignMalloc();.
69d0: 20 20 7d 0a 0a 20 20 69 66 28 20 70 50 61 67 65    }..  if( pPage
69e0: 20 29 7b 0a 20 20 20 20 75 6e 73 69 67 6e 65 64   ){.    unsigned
69f0: 20 69 6e 74 20 68 20 3d 20 69 4b 65 79 20 25 20   int h = iKey % 
6a00: 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20  pCache->nHash;. 
6a10: 20 20 20 70 43 61 63 68 65 2d 3e 6e 50 61 67 65     pCache->nPage
6a20: 2b 2b 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 69  ++;.    pPage->i
6a30: 4b 65 79 20 3d 20 69 4b 65 79 3b 0a 20 20 20 20  Key = iKey;.    
6a40: 70 50 61 67 65 2d 3e 70 4e 65 78 74 20 3d 20 70  pPage->pNext = p
6a50: 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d  Cache->apHash[h]
6a60: 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 43 61  ;.    pPage->pCa
6a70: 63 68 65 20 3d 20 70 43 61 63 68 65 3b 0a 20 20  che = pCache;.  
6a80: 20 20 70 50 61 67 65 2d 3e 70 4c 72 75 50 72 65    pPage->pLruPre
6a90: 76 20 3d 20 30 3b 0a 20 20 20 20 70 50 61 67 65  v = 0;.    pPage
6aa0: 2d 3e 70 4c 72 75 4e 65 78 74 20 3d 20 30 3b 0a  ->pLruNext = 0;.
6ab0: 20 20 20 20 70 50 61 67 65 2d 3e 69 73 50 69 6e      pPage->isPin
6ac0: 6e 65 64 20 3d 20 31 3b 0a 20 20 20 20 2a 28 76  ned = 1;.    *(v
6ad0: 6f 69 64 20 2a 2a 29 70 50 61 67 65 2d 3e 70 61  oid **)pPage->pa
6ae0: 67 65 2e 70 45 78 74 72 61 20 3d 20 30 3b 0a 20  ge.pExtra = 0;. 
6af0: 20 20 20 70 43 61 63 68 65 2d 3e 61 70 48 61 73     pCache->apHas
6b00: 68 5b 68 5d 20 3d 20 70 50 61 67 65 3b 0a 20 20  h[h] = pPage;.  
6b10: 7d 0a 0a 66 65 74 63 68 5f 6f 75 74 3a 0a 20 20  }..fetch_out:.  
6b20: 69 66 28 20 70 50 61 67 65 20 26 26 20 69 4b 65  if( pPage && iKe
6b30: 79 3e 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b 65  y>pCache->iMaxKe
6b40: 79 20 29 7b 0a 20 20 20 20 70 43 61 63 68 65 2d  y ){.    pCache-
6b50: 3e 69 4d 61 78 4b 65 79 20 3d 20 69 4b 65 79 3b  >iMaxKey = iKey;
6b60: 0a 20 20 7d 0a 20 20 70 63 61 63 68 65 31 4c 65  .  }.  pcache1Le
6b70: 61 76 65 4d 75 74 65 78 28 70 47 72 6f 75 70 29  aveMutex(pGroup)
6b80: 3b 0a 20 20 72 65 74 75 72 6e 20 28 73 71 6c 69  ;.  return (sqli
6b90: 74 65 33 5f 70 63 61 63 68 65 5f 70 61 67 65 2a  te3_pcache_page*
6ba0: 29 70 50 61 67 65 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a  )pPage;.}.../*.*
6bb0: 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  * Implementation
6bc0: 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f   of the sqlite3_
6bd0: 70 63 61 63 68 65 2e 78 55 6e 70 69 6e 20 6d 65  pcache.xUnpin me
6be0: 74 68 6f 64 2e 0a 2a 2a 0a 2a 2a 20 4d 61 72 6b  thod..**.** Mark
6bf0: 20 61 20 70 61 67 65 20 61 73 20 75 6e 70 69 6e   a page as unpin
6c00: 6e 65 64 20 28 65 6c 69 67 69 62 6c 65 20 66 6f  ned (eligible fo
6c10: 72 20 61 73 79 6e 63 68 72 6f 6e 6f 75 73 20 72  r asynchronous r
6c20: 65 63 79 63 6c 69 6e 67 29 2e 0a 2a 2f 0a 73 74  ecycling)..*/.st
6c30: 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65  atic void pcache
6c40: 31 55 6e 70 69 6e 28 0a 20 20 73 71 6c 69 74 65  1Unpin(.  sqlite
6c50: 33 5f 70 63 61 63 68 65 20 2a 70 2c 20 0a 20 20  3_pcache *p, .  
6c60: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 5f 70  sqlite3_pcache_p
6c70: 61 67 65 20 2a 70 50 67 2c 20 0a 20 20 69 6e 74  age *pPg, .  int
6c80: 20 72 65 75 73 65 55 6e 6c 69 6b 65 6c 79 0a 29   reuseUnlikely.)
6c90: 7b 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43 61  {.  PCache1 *pCa
6ca0: 63 68 65 20 3d 20 28 50 43 61 63 68 65 31 20 2a  che = (PCache1 *
6cb0: 29 70 3b 0a 20 20 50 67 48 64 72 31 20 2a 70 50  )p;.  PgHdr1 *pP
6cc0: 61 67 65 20 3d 20 28 50 67 48 64 72 31 20 2a 29  age = (PgHdr1 *)
6cd0: 70 50 67 3b 0a 20 20 50 47 72 6f 75 70 20 2a 70  pPg;.  PGroup *p
6ce0: 47 72 6f 75 70 20 3d 20 70 43 61 63 68 65 2d 3e  Group = pCache->
6cf0: 70 47 72 6f 75 70 3b 0a 20 0a 20 20 61 73 73 65  pGroup;. .  asse
6d00: 72 74 28 20 70 50 61 67 65 2d 3e 70 43 61 63 68  rt( pPage->pCach
6d10: 65 3d 3d 70 43 61 63 68 65 20 29 3b 0a 20 20 70  e==pCache );.  p
6d20: 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78  cache1EnterMutex
6d30: 28 70 47 72 6f 75 70 29 3b 0a 0a 20 20 2f 2a 20  (pGroup);..  /* 
6d40: 49 74 20 69 73 20 61 6e 20 65 72 72 6f 72 20 74  It is an error t
6d50: 6f 20 63 61 6c 6c 20 74 68 69 73 20 66 75 6e 63  o call this func
6d60: 74 69 6f 6e 20 69 66 20 74 68 65 20 70 61 67 65  tion if the page
6d70: 20 69 73 20 61 6c 72 65 61 64 79 20 0a 20 20 2a   is already .  *
6d80: 2a 20 70 61 72 74 20 6f 66 20 74 68 65 20 50 47  * part of the PG
6d90: 72 6f 75 70 20 4c 52 55 20 6c 69 73 74 2e 0a 20  roup LRU list.. 
6da0: 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 50   */.  assert( pP
6db0: 61 67 65 2d 3e 70 4c 72 75 50 72 65 76 3d 3d 30  age->pLruPrev==0
6dc0: 20 26 26 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e   && pPage->pLruN
6dd0: 65 78 74 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65  ext==0 );.  asse
6de0: 72 74 28 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75  rt( pGroup->pLru
6df0: 48 65 61 64 21 3d 70 50 61 67 65 20 26 26 20 70  Head!=pPage && p
6e00: 47 72 6f 75 70 2d 3e 70 4c 72 75 54 61 69 6c 21  Group->pLruTail!
6e10: 3d 70 50 61 67 65 20 29 3b 0a 20 20 61 73 73 65  =pPage );.  asse
6e20: 72 74 28 20 70 50 61 67 65 2d 3e 69 73 50 69 6e  rt( pPage->isPin
6e30: 6e 65 64 3d 3d 31 20 29 3b 0a 0a 20 20 69 66 28  ned==1 );..  if(
6e40: 20 72 65 75 73 65 55 6e 6c 69 6b 65 6c 79 20 7c   reuseUnlikely |
6e50: 7c 20 70 47 72 6f 75 70 2d 3e 6e 43 75 72 72 65  | pGroup->nCurre
6e60: 6e 74 50 61 67 65 3e 70 47 72 6f 75 70 2d 3e 6e  ntPage>pGroup->n
6e70: 4d 61 78 50 61 67 65 20 29 7b 0a 20 20 20 20 70  MaxPage ){.    p
6e80: 63 61 63 68 65 31 52 65 6d 6f 76 65 46 72 6f 6d  cache1RemoveFrom
6e90: 48 61 73 68 28 70 50 61 67 65 29 3b 0a 20 20 20  Hash(pPage);.   
6ea0: 20 70 63 61 63 68 65 31 46 72 65 65 50 61 67 65   pcache1FreePage
6eb0: 28 70 50 61 67 65 29 3b 0a 20 20 7d 65 6c 73 65  (pPage);.  }else
6ec0: 7b 0a 20 20 20 20 2f 2a 20 41 64 64 20 74 68 65  {.    /* Add the
6ed0: 20 70 61 67 65 20 74 6f 20 74 68 65 20 50 47 72   page to the PGr
6ee0: 6f 75 70 20 4c 52 55 20 6c 69 73 74 2e 20 2a 2f  oup LRU list. */
6ef0: 0a 20 20 20 20 69 66 28 20 70 47 72 6f 75 70 2d  .    if( pGroup-
6f00: 3e 70 4c 72 75 48 65 61 64 20 29 7b 0a 20 20 20  >pLruHead ){.   
6f10: 20 20 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 48     pGroup->pLruH
6f20: 65 61 64 2d 3e 70 4c 72 75 50 72 65 76 20 3d 20  ead->pLruPrev = 
6f30: 70 50 61 67 65 3b 0a 20 20 20 20 20 20 70 50 61  pPage;.      pPa
6f40: 67 65 2d 3e 70 4c 72 75 4e 65 78 74 20 3d 20 70  ge->pLruNext = p
6f50: 47 72 6f 75 70 2d 3e 70 4c 72 75 48 65 61 64 3b  Group->pLruHead;
6f60: 0a 20 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 70  .      pGroup->p
6f70: 4c 72 75 48 65 61 64 20 3d 20 70 50 61 67 65 3b  LruHead = pPage;
6f80: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
6f90: 20 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 54 61    pGroup->pLruTa
6fa0: 69 6c 20 3d 20 70 50 61 67 65 3b 0a 20 20 20 20  il = pPage;.    
6fb0: 20 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 48 65    pGroup->pLruHe
6fc0: 61 64 20 3d 20 70 50 61 67 65 3b 0a 20 20 20 20  ad = pPage;.    
6fd0: 7d 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 6e 52  }.    pCache->nR
6fe0: 65 63 79 63 6c 61 62 6c 65 2b 2b 3b 0a 20 20 20  ecyclable++;.   
6ff0: 20 70 50 61 67 65 2d 3e 69 73 50 69 6e 6e 65 64   pPage->isPinned
7000: 20 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20 70 63 61   = 0;.  }..  pca
7010: 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 70  che1LeaveMutex(p
7020: 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a  Cache->pGroup);.
7030: 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65  }../*.** Impleme
7040: 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73  ntation of the s
7050: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78 52  qlite3_pcache.xR
7060: 65 6b 65 79 20 6d 65 74 68 6f 64 2e 20 0a 2a 2f  ekey method. .*/
7070: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61  .static void pca
7080: 63 68 65 31 52 65 6b 65 79 28 0a 20 20 73 71 6c  che1Rekey(.  sql
7090: 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70 2c 0a  ite3_pcache *p,.
70a0: 20 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65    sqlite3_pcache
70b0: 5f 70 61 67 65 20 2a 70 50 67 2c 0a 20 20 75 6e  _page *pPg,.  un
70c0: 73 69 67 6e 65 64 20 69 6e 74 20 69 4f 6c 64 2c  signed int iOld,
70d0: 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  .  unsigned int 
70e0: 69 4e 65 77 0a 29 7b 0a 20 20 50 43 61 63 68 65  iNew.){.  PCache
70f0: 31 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61  1 *pCache = (PCa
7100: 63 68 65 31 20 2a 29 70 3b 0a 20 20 50 67 48 64  che1 *)p;.  PgHd
7110: 72 31 20 2a 70 50 61 67 65 20 3d 20 28 50 67 48  r1 *pPage = (PgH
7120: 64 72 31 20 2a 29 70 50 67 3b 0a 20 20 50 67 48  dr1 *)pPg;.  PgH
7130: 64 72 31 20 2a 2a 70 70 3b 0a 20 20 75 6e 73 69  dr1 **pp;.  unsi
7140: 67 6e 65 64 20 69 6e 74 20 68 3b 20 0a 20 20 61  gned int h; .  a
7150: 73 73 65 72 74 28 20 70 50 61 67 65 2d 3e 69 4b  ssert( pPage->iK
7160: 65 79 3d 3d 69 4f 6c 64 20 29 3b 0a 20 20 61 73  ey==iOld );.  as
7170: 73 65 72 74 28 20 70 50 61 67 65 2d 3e 70 43 61  sert( pPage->pCa
7180: 63 68 65 3d 3d 70 43 61 63 68 65 20 29 3b 0a 0a  che==pCache );..
7190: 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75    pcache1EnterMu
71a0: 74 65 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f  tex(pCache->pGro
71b0: 75 70 29 3b 0a 0a 20 20 68 20 3d 20 69 4f 6c 64  up);..  h = iOld
71c0: 25 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3b 0a  %pCache->nHash;.
71d0: 20 20 70 70 20 3d 20 26 70 43 61 63 68 65 2d 3e    pp = &pCache->
71e0: 61 70 48 61 73 68 5b 68 5d 3b 0a 20 20 77 68 69  apHash[h];.  whi
71f0: 6c 65 28 20 28 2a 70 70 29 21 3d 70 50 61 67 65  le( (*pp)!=pPage
7200: 20 29 7b 0a 20 20 20 20 70 70 20 3d 20 26 28 2a   ){.    pp = &(*
7210: 70 70 29 2d 3e 70 4e 65 78 74 3b 0a 20 20 7d 0a  pp)->pNext;.  }.
7220: 20 20 2a 70 70 20 3d 20 70 50 61 67 65 2d 3e 70    *pp = pPage->p
7230: 4e 65 78 74 3b 0a 0a 20 20 68 20 3d 20 69 4e 65  Next;..  h = iNe
7240: 77 25 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3b  w%pCache->nHash;
7250: 0a 20 20 70 50 61 67 65 2d 3e 69 4b 65 79 20 3d  .  pPage->iKey =
7260: 20 69 4e 65 77 3b 0a 20 20 70 50 61 67 65 2d 3e   iNew;.  pPage->
7270: 70 4e 65 78 74 20 3d 20 70 43 61 63 68 65 2d 3e  pNext = pCache->
7280: 61 70 48 61 73 68 5b 68 5d 3b 0a 20 20 70 43 61  apHash[h];.  pCa
7290: 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 20 3d  che->apHash[h] =
72a0: 20 70 50 61 67 65 3b 0a 20 20 69 66 28 20 69 4e   pPage;.  if( iN
72b0: 65 77 3e 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b  ew>pCache->iMaxK
72c0: 65 79 20 29 7b 0a 20 20 20 20 70 43 61 63 68 65  ey ){.    pCache
72d0: 2d 3e 69 4d 61 78 4b 65 79 20 3d 20 69 4e 65 77  ->iMaxKey = iNew
72e0: 3b 0a 20 20 7d 0a 0a 20 20 70 63 61 63 68 65 31  ;.  }..  pcache1
72f0: 4c 65 61 76 65 4d 75 74 65 78 28 70 43 61 63 68  LeaveMutex(pCach
7300: 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 7d 0a 0a 2f  e->pGroup);.}../
7310: 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74  *.** Implementat
7320: 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74  ion of the sqlit
7330: 65 33 5f 70 63 61 63 68 65 2e 78 54 72 75 6e 63  e3_pcache.xTrunc
7340: 61 74 65 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a  ate method. .**.
7350: 2a 2a 20 44 69 73 63 61 72 64 20 61 6c 6c 20 75  ** Discard all u
7360: 6e 70 69 6e 6e 65 64 20 70 61 67 65 73 20 69 6e  npinned pages in
7370: 20 74 68 65 20 63 61 63 68 65 20 77 69 74 68 20   the cache with 
7380: 61 20 70 61 67 65 20 6e 75 6d 62 65 72 20 65 71  a page number eq
7390: 75 61 6c 20 74 6f 0a 2a 2a 20 6f 72 20 67 72 65  ual to.** or gre
73a0: 61 74 65 72 20 74 68 61 6e 20 70 61 72 61 6d 65  ater than parame
73b0: 74 65 72 20 69 4c 69 6d 69 74 2e 20 41 6e 79 20  ter iLimit. Any 
73c0: 70 69 6e 6e 65 64 20 70 61 67 65 73 20 77 69 74  pinned pages wit
73d0: 68 20 61 20 70 61 67 65 20 6e 75 6d 62 65 72 0a  h a page number.
73e0: 2a 2a 20 65 71 75 61 6c 20 74 6f 20 6f 72 20 67  ** equal to or g
73f0: 72 65 61 74 65 72 20 74 68 61 6e 20 69 4c 69 6d  reater than iLim
7400: 69 74 20 61 72 65 20 69 6d 70 6c 69 63 69 74 6c  it are implicitl
7410: 79 20 75 6e 70 69 6e 6e 65 64 2e 0a 2a 2f 0a 73  y unpinned..*/.s
7420: 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68  tatic void pcach
7430: 65 31 54 72 75 6e 63 61 74 65 28 73 71 6c 69 74  e1Truncate(sqlit
7440: 65 33 5f 70 63 61 63 68 65 20 2a 70 2c 20 75 6e  e3_pcache *p, un
7450: 73 69 67 6e 65 64 20 69 6e 74 20 69 4c 69 6d 69  signed int iLimi
7460: 74 29 7b 0a 20 20 50 43 61 63 68 65 31 20 2a 70  t){.  PCache1 *p
7470: 43 61 63 68 65 20 3d 20 28 50 43 61 63 68 65 31  Cache = (PCache1
7480: 20 2a 29 70 3b 0a 20 20 70 63 61 63 68 65 31 45   *)p;.  pcache1E
7490: 6e 74 65 72 4d 75 74 65 78 28 70 43 61 63 68 65  nterMutex(pCache
74a0: 2d 3e 70 47 72 6f 75 70 29 3b 0a 20 20 69 66 28  ->pGroup);.  if(
74b0: 20 69 4c 69 6d 69 74 3c 3d 70 43 61 63 68 65 2d   iLimit<=pCache-
74c0: 3e 69 4d 61 78 4b 65 79 20 29 7b 0a 20 20 20 20  >iMaxKey ){.    
74d0: 70 63 61 63 68 65 31 54 72 75 6e 63 61 74 65 55  pcache1TruncateU
74e0: 6e 73 61 66 65 28 70 43 61 63 68 65 2c 20 69 4c  nsafe(pCache, iL
74f0: 69 6d 69 74 29 3b 0a 20 20 20 20 70 43 61 63 68  imit);.    pCach
7500: 65 2d 3e 69 4d 61 78 4b 65 79 20 3d 20 69 4c 69  e->iMaxKey = iLi
7510: 6d 69 74 2d 31 3b 0a 20 20 7d 0a 20 20 70 63 61  mit-1;.  }.  pca
7520: 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 70  che1LeaveMutex(p
7530: 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a  Cache->pGroup);.
7540: 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65  }../*.** Impleme
7550: 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73  ntation of the s
7560: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78 44  qlite3_pcache.xD
7570: 65 73 74 72 6f 79 20 6d 65 74 68 6f 64 2e 20 0a  estroy method. .
7580: 2a 2a 0a 2a 2a 20 44 65 73 74 72 6f 79 20 61 20  **.** Destroy a 
7590: 63 61 63 68 65 20 61 6c 6c 6f 63 61 74 65 64 20  cache allocated 
75a0: 75 73 69 6e 67 20 70 63 61 63 68 65 31 43 72 65  using pcache1Cre
75b0: 61 74 65 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63  ate()..*/.static
75c0: 20 76 6f 69 64 20 70 63 61 63 68 65 31 44 65 73   void pcache1Des
75d0: 74 72 6f 79 28 73 71 6c 69 74 65 33 5f 70 63 61  troy(sqlite3_pca
75e0: 63 68 65 20 2a 70 29 7b 0a 20 20 50 43 61 63 68  che *p){.  PCach
75f0: 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43  e1 *pCache = (PC
7600: 61 63 68 65 31 20 2a 29 70 3b 0a 20 20 50 47 72  ache1 *)p;.  PGr
7610: 6f 75 70 20 2a 70 47 72 6f 75 70 20 3d 20 70 43  oup *pGroup = pC
7620: 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b 0a 20 20  ache->pGroup;.  
7630: 61 73 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e  assert( pCache->
7640: 62 50 75 72 67 65 61 62 6c 65 20 7c 7c 20 28 70  bPurgeable || (p
7650: 43 61 63 68 65 2d 3e 6e 4d 61 78 3d 3d 30 20 26  Cache->nMax==0 &
7660: 26 20 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 3d 3d  & pCache->nMin==
7670: 30 29 20 29 3b 0a 20 20 70 63 61 63 68 65 31 45  0) );.  pcache1E
7680: 6e 74 65 72 4d 75 74 65 78 28 70 47 72 6f 75 70  nterMutex(pGroup
7690: 29 3b 0a 20 20 70 63 61 63 68 65 31 54 72 75 6e  );.  pcache1Trun
76a0: 63 61 74 65 55 6e 73 61 66 65 28 70 43 61 63 68  cateUnsafe(pCach
76b0: 65 2c 20 30 29 3b 0a 20 20 61 73 73 65 72 74 28  e, 0);.  assert(
76c0: 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67   pGroup->nMaxPag
76d0: 65 20 3e 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 61  e >= pCache->nMa
76e0: 78 20 29 3b 0a 20 20 70 47 72 6f 75 70 2d 3e 6e  x );.  pGroup->n
76f0: 4d 61 78 50 61 67 65 20 2d 3d 20 70 43 61 63 68  MaxPage -= pCach
7700: 65 2d 3e 6e 4d 61 78 3b 0a 20 20 61 73 73 65 72  e->nMax;.  asser
7710: 74 28 20 70 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50  t( pGroup->nMinP
7720: 61 67 65 20 3e 3d 20 70 43 61 63 68 65 2d 3e 6e  age >= pCache->n
7730: 4d 69 6e 20 29 3b 0a 20 20 70 47 72 6f 75 70 2d  Min );.  pGroup-
7740: 3e 6e 4d 69 6e 50 61 67 65 20 2d 3d 20 70 43 61  >nMinPage -= pCa
7750: 63 68 65 2d 3e 6e 4d 69 6e 3b 0a 20 20 70 47 72  che->nMin;.  pGr
7760: 6f 75 70 2d 3e 6d 78 50 69 6e 6e 65 64 20 3d 20  oup->mxPinned = 
7770: 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65  pGroup->nMaxPage
7780: 20 2b 20 31 30 20 2d 20 70 47 72 6f 75 70 2d 3e   + 10 - pGroup->
7790: 6e 4d 69 6e 50 61 67 65 3b 0a 20 20 70 63 61 63  nMinPage;.  pcac
77a0: 68 65 31 45 6e 66 6f 72 63 65 4d 61 78 50 61 67  he1EnforceMaxPag
77b0: 65 28 70 47 72 6f 75 70 29 3b 0a 20 20 70 63 61  e(pGroup);.  pca
77c0: 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 70  che1LeaveMutex(p
77d0: 47 72 6f 75 70 29 3b 0a 20 20 73 71 6c 69 74 65  Group);.  sqlite
77e0: 33 5f 66 72 65 65 28 70 43 61 63 68 65 2d 3e 61  3_free(pCache->a
77f0: 70 48 61 73 68 29 3b 0a 20 20 73 71 6c 69 74 65  pHash);.  sqlite
7800: 33 5f 66 72 65 65 28 70 43 61 63 68 65 29 3b 0a  3_free(pCache);.
7810: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75  }../*.** This fu
7820: 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64  nction is called
7830: 20 64 75 72 69 6e 67 20 69 6e 69 74 69 61 6c 69   during initiali
7840: 7a 61 74 69 6f 6e 20 28 73 71 6c 69 74 65 33 5f  zation (sqlite3_
7850: 69 6e 69 74 69 61 6c 69 7a 65 28 29 29 20 74 6f  initialize()) to
7860: 0a 2a 2a 20 69 6e 73 74 61 6c 6c 20 74 68 65 20  .** install the 
7870: 64 65 66 61 75 6c 74 20 70 6c 75 67 67 61 62 6c  default pluggabl
7880: 65 20 63 61 63 68 65 20 6d 6f 64 75 6c 65 2c 20  e cache module, 
7890: 61 73 73 75 6d 69 6e 67 20 74 68 65 20 75 73 65  assuming the use
78a0: 72 20 68 61 73 20 6e 6f 74 0a 2a 2a 20 61 6c 72  r has not.** alr
78b0: 65 61 64 79 20 70 72 6f 76 69 64 65 64 20 61 6e  eady provided an
78c0: 20 61 6c 74 65 72 6e 61 74 69 76 65 2e 0a 2a 2f   alternative..*/
78d0: 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 43 61  .void sqlite3PCa
78e0: 63 68 65 53 65 74 44 65 66 61 75 6c 74 28 76 6f  cheSetDefault(vo
78f0: 69 64 29 7b 0a 20 20 73 74 61 74 69 63 20 63 6f  id){.  static co
7900: 6e 73 74 20 73 71 6c 69 74 65 33 5f 70 63 61 63  nst sqlite3_pcac
7910: 68 65 5f 6d 65 74 68 6f 64 73 32 20 64 65 66 61  he_methods2 defa
7920: 75 6c 74 4d 65 74 68 6f 64 73 20 3d 20 7b 0a 20  ultMethods = {. 
7930: 20 20 20 31 2c 20 20 20 20 20 20 20 20 20 20 20     1,           
7940: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 69              /* i
7950: 56 65 72 73 69 6f 6e 20 2a 2f 0a 20 20 20 20 30  Version */.    0
7960: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
7970: 20 20 20 20 20 20 20 20 2f 2a 20 70 41 72 67 20          /* pArg 
7980: 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31 49 6e  */.    pcache1In
7990: 69 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  it,             
79a0: 2f 2a 20 78 49 6e 69 74 20 2a 2f 0a 20 20 20 20  /* xInit */.    
79b0: 70 63 61 63 68 65 31 53 68 75 74 64 6f 77 6e 2c  pcache1Shutdown,
79c0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 53 68 75           /* xShu
79d0: 74 64 6f 77 6e 20 2a 2f 0a 20 20 20 20 70 63 61  tdown */.    pca
79e0: 63 68 65 31 43 72 65 61 74 65 2c 20 20 20 20 20  che1Create,     
79f0: 20 20 20 20 20 20 2f 2a 20 78 43 72 65 61 74 65        /* xCreate
7a00: 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31 43   */.    pcache1C
7a10: 61 63 68 65 73 69 7a 65 2c 20 20 20 20 20 20 20  achesize,       
7a20: 20 2f 2a 20 78 43 61 63 68 65 73 69 7a 65 20 2a   /* xCachesize *
7a30: 2f 0a 20 20 20 20 70 63 61 63 68 65 31 50 61 67  /.    pcache1Pag
7a40: 65 63 6f 75 6e 74 2c 20 20 20 20 20 20 20 20 2f  ecount,        /
7a50: 2a 20 78 50 61 67 65 63 6f 75 6e 74 20 2a 2f 0a  * xPagecount */.
7a60: 20 20 20 20 70 63 61 63 68 65 31 46 65 74 63 68      pcache1Fetch
7a70: 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ,            /* 
7a80: 78 46 65 74 63 68 20 2a 2f 0a 20 20 20 20 70 63  xFetch */.    pc
7a90: 61 63 68 65 31 55 6e 70 69 6e 2c 20 20 20 20 20  ache1Unpin,     
7aa0: 20 20 20 20 20 20 20 2f 2a 20 78 55 6e 70 69 6e         /* xUnpin
7ab0: 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31 52   */.    pcache1R
7ac0: 65 6b 65 79 2c 20 20 20 20 20 20 20 20 20 20 20  ekey,           
7ad0: 20 2f 2a 20 78 52 65 6b 65 79 20 2a 2f 0a 20 20   /* xRekey */.  
7ae0: 20 20 70 63 61 63 68 65 31 54 72 75 6e 63 61 74    pcache1Truncat
7af0: 65 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 78 54  e,         /* xT
7b00: 72 75 6e 63 61 74 65 20 2a 2f 0a 20 20 20 20 70  runcate */.    p
7b10: 63 61 63 68 65 31 44 65 73 74 72 6f 79 2c 20 20  cache1Destroy,  
7b20: 20 20 20 20 20 20 20 20 2f 2a 20 78 44 65 73 74          /* xDest
7b30: 72 6f 79 20 2a 2f 0a 20 20 20 20 70 63 61 63 68  roy */.    pcach
7b40: 65 31 53 68 72 69 6e 6b 20 20 20 20 20 20 20 20  e1Shrink        
7b50: 20 20 20 20 2f 2a 20 78 53 68 72 69 6e 6b 20 2a      /* xShrink *
7b60: 2f 0a 20 20 7d 3b 0a 20 20 73 71 6c 69 74 65 33  /.  };.  sqlite3
7b70: 5f 63 6f 6e 66 69 67 28 53 51 4c 49 54 45 5f 43  _config(SQLITE_C
7b80: 4f 4e 46 49 47 5f 50 43 41 43 48 45 32 2c 20 26  ONFIG_PCACHE2, &
7b90: 64 65 66 61 75 6c 74 4d 65 74 68 6f 64 73 29 3b  defaultMethods);
7ba0: 0a 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54  .}..#ifdef SQLIT
7bb0: 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f  E_ENABLE_MEMORY_
7bc0: 4d 41 4e 41 47 45 4d 45 4e 54 0a 2f 2a 0a 2a 2a  MANAGEMENT./*.**
7bd0: 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   This function i
7be0: 73 20 63 61 6c 6c 65 64 20 74 6f 20 66 72 65 65  s called to free
7bf0: 20 73 75 70 65 72 66 6c 75 6f 75 73 20 64 79 6e   superfluous dyn
7c00: 61 6d 69 63 61 6c 6c 79 20 61 6c 6c 6f 63 61 74  amically allocat
7c10: 65 64 20 6d 65 6d 6f 72 79 0a 2a 2a 20 68 65 6c  ed memory.** hel
7c20: 64 20 62 79 20 74 68 65 20 70 61 67 65 72 20 73  d by the pager s
7c30: 79 73 74 65 6d 2e 20 4d 65 6d 6f 72 79 20 69 6e  ystem. Memory in
7c40: 20 75 73 65 20 62 79 20 61 6e 79 20 53 51 4c 69   use by any SQLi
7c50: 74 65 20 70 61 67 65 72 20 61 6c 6c 6f 63 61 74  te pager allocat
7c60: 65 64 0a 2a 2a 20 62 79 20 74 68 65 20 63 75 72  ed.** by the cur
7c70: 72 65 6e 74 20 74 68 72 65 61 64 20 6d 61 79 20  rent thread may 
7c80: 62 65 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  be sqlite3_free(
7c90: 29 65 64 2e 0a 2a 2a 0a 2a 2a 20 6e 52 65 71 20  )ed..**.** nReq 
7ca0: 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  is the number of
7cb0: 20 62 79 74 65 73 20 6f 66 20 6d 65 6d 6f 72 79   bytes of memory
7cc0: 20 72 65 71 75 69 72 65 64 2e 20 4f 6e 63 65 20   required. Once 
7cd0: 74 68 69 73 20 6d 75 63 68 20 68 61 73 0a 2a 2a  this much has.**
7ce0: 20 62 65 65 6e 20 72 65 6c 65 61 73 65 64 2c 20   been released, 
7cf0: 74 68 65 20 66 75 6e 63 74 69 6f 6e 20 72 65 74  the function ret
7d00: 75 72 6e 73 2e 20 54 68 65 20 72 65 74 75 72 6e  urns. The return
7d10: 20 76 61 6c 75 65 20 69 73 20 74 68 65 20 74 6f   value is the to
7d20: 74 61 6c 20 6e 75 6d 62 65 72 20 0a 2a 2a 20 6f  tal number .** o
7d30: 66 20 62 79 74 65 73 20 6f 66 20 6d 65 6d 6f 72  f bytes of memor
7d40: 79 20 72 65 6c 65 61 73 65 64 2e 0a 2a 2f 0a 69  y released..*/.i
7d50: 6e 74 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  nt sqlite3Pcache
7d60: 52 65 6c 65 61 73 65 4d 65 6d 6f 72 79 28 69 6e  ReleaseMemory(in
7d70: 74 20 6e 52 65 71 29 7b 0a 20 20 69 6e 74 20 6e  t nReq){.  int n
7d80: 46 72 65 65 20 3d 20 30 3b 0a 20 20 61 73 73 65  Free = 0;.  asse
7d90: 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65  rt( sqlite3_mute
7da0: 78 5f 6e 6f 74 68 65 6c 64 28 70 63 61 63 68 65  x_notheld(pcache
7db0: 31 2e 67 72 70 2e 6d 75 74 65 78 29 20 29 3b 0a  1.grp.mutex) );.
7dc0: 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65    assert( sqlite
7dd0: 33 5f 6d 75 74 65 78 5f 6e 6f 74 68 65 6c 64 28  3_mutex_notheld(
7de0: 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29 20 29  pcache1.mutex) )
7df0: 3b 0a 20 20 69 66 28 20 70 63 61 63 68 65 31 2e  ;.  if( pcache1.
7e00: 70 53 74 61 72 74 3d 3d 30 20 29 7b 0a 20 20 20  pStart==0 ){.   
7e10: 20 50 67 48 64 72 31 20 2a 70 3b 0a 20 20 20 20   PgHdr1 *p;.    
7e20: 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65  pcache1EnterMute
7e30: 78 28 26 70 63 61 63 68 65 31 2e 67 72 70 29 3b  x(&pcache1.grp);
7e40: 0a 20 20 20 20 77 68 69 6c 65 28 20 28 6e 52 65  .    while( (nRe
7e50: 71 3c 30 20 7c 7c 20 6e 46 72 65 65 3c 6e 52 65  q<0 || nFree<nRe
7e60: 71 29 20 26 26 20 28 28 70 3d 70 63 61 63 68 65  q) && ((p=pcache
7e70: 31 2e 67 72 70 2e 70 4c 72 75 54 61 69 6c 29 21  1.grp.pLruTail)!
7e80: 3d 30 29 20 29 7b 0a 20 20 20 20 20 20 6e 46 72  =0) ){.      nFr
7e90: 65 65 20 2b 3d 20 70 63 61 63 68 65 31 4d 65 6d  ee += pcache1Mem
7ea0: 53 69 7a 65 28 70 2d 3e 70 61 67 65 2e 70 42 75  Size(p->page.pBu
7eb0: 66 29 3b 0a 23 69 66 64 65 66 20 53 51 4c 49 54  f);.#ifdef SQLIT
7ec0: 45 5f 50 43 41 43 48 45 5f 53 45 50 41 52 41 54  E_PCACHE_SEPARAT
7ed0: 45 5f 48 45 41 44 45 52 0a 20 20 20 20 20 20 6e  E_HEADER.      n
7ee0: 46 72 65 65 20 2b 3d 20 73 71 6c 69 74 65 33 4d  Free += sqlite3M
7ef0: 65 6d 53 69 7a 65 28 70 29 3b 0a 23 65 6e 64 69  emSize(p);.#endi
7f00: 66 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20  f.      assert( 
7f10: 70 2d 3e 69 73 50 69 6e 6e 65 64 3d 3d 30 20 29  p->isPinned==0 )
7f20: 3b 0a 20 20 20 20 20 20 70 63 61 63 68 65 31 50  ;.      pcache1P
7f30: 69 6e 50 61 67 65 28 70 29 3b 0a 20 20 20 20 20  inPage(p);.     
7f40: 20 70 63 61 63 68 65 31 52 65 6d 6f 76 65 46 72   pcache1RemoveFr
7f50: 6f 6d 48 61 73 68 28 70 29 3b 0a 20 20 20 20 20  omHash(p);.     
7f60: 20 70 63 61 63 68 65 31 46 72 65 65 50 61 67 65   pcache1FreePage
7f70: 28 70 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70  (p);.    }.    p
7f80: 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78  cache1LeaveMutex
7f90: 28 26 70 63 61 63 68 65 31 2e 67 72 70 29 3b 0a  (&pcache1.grp);.
7fa0: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 6e 46 72    }.  return nFr
7fb0: 65 65 3b 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a 20  ee;.}.#endif /* 
7fc0: 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45  SQLITE_ENABLE_ME
7fd0: 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 20  MORY_MANAGEMENT 
7fe0: 2a 2f 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54  */..#ifdef SQLIT
7ff0: 45 5f 54 45 53 54 0a 2f 2a 0a 2a 2a 20 54 68 69  E_TEST./*.** Thi
8000: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 75 73  s function is us
8010: 65 64 20 62 79 20 74 65 73 74 20 70 72 6f 63 65  ed by test proce
8020: 64 75 72 65 73 20 74 6f 20 69 6e 73 70 65 63 74  dures to inspect
8030: 20 74 68 65 20 69 6e 74 65 72 6e 61 6c 20 73 74   the internal st
8040: 61 74 65 0a 2a 2a 20 6f 66 20 74 68 65 20 67 6c  ate.** of the gl
8050: 6f 62 61 6c 20 63 61 63 68 65 2e 0a 2a 2f 0a 76  obal cache..*/.v
8060: 6f 69 64 20 73 71 6c 69 74 65 33 50 63 61 63 68  oid sqlite3Pcach
8070: 65 53 74 61 74 73 28 0a 20 20 69 6e 74 20 2a 70  eStats(.  int *p
8080: 6e 43 75 72 72 65 6e 74 2c 20 20 20 20 20 20 2f  nCurrent,      /
8090: 2a 20 4f 55 54 3a 20 54 6f 74 61 6c 20 6e 75 6d  * OUT: Total num
80a0: 62 65 72 20 6f 66 20 70 61 67 65 73 20 63 61 63  ber of pages cac
80b0: 68 65 64 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e  hed */.  int *pn
80c0: 4d 61 78 2c 20 20 20 20 20 20 20 20 20 20 2f 2a  Max,          /*
80d0: 20 4f 55 54 3a 20 47 6c 6f 62 61 6c 20 6d 61 78   OUT: Global max
80e0: 69 6d 75 6d 20 63 61 63 68 65 20 73 69 7a 65 20  imum cache size 
80f0: 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 4d 69 6e 2c  */.  int *pnMin,
8100: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
8110: 3a 20 53 75 6d 20 6f 66 20 50 43 61 63 68 65 31  : Sum of PCache1
8120: 2e 6e 4d 69 6e 20 66 6f 72 20 70 75 72 67 65 61  .nMin for purgea
8130: 62 6c 65 20 63 61 63 68 65 73 20 2a 2f 0a 20 20  ble caches */.  
8140: 69 6e 74 20 2a 70 6e 52 65 63 79 63 6c 61 62 6c  int *pnRecyclabl
8150: 65 20 20 20 20 2f 2a 20 4f 55 54 3a 20 54 6f 74  e    /* OUT: Tot
8160: 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67  al number of pag
8170: 65 73 20 61 76 61 69 6c 61 62 6c 65 20 66 6f 72  es available for
8180: 20 72 65 63 79 63 6c 69 6e 67 20 2a 2f 0a 29 7b   recycling */.){
8190: 0a 20 20 50 67 48 64 72 31 20 2a 70 3b 0a 20 20  .  PgHdr1 *p;.  
81a0: 69 6e 74 20 6e 52 65 63 79 63 6c 61 62 6c 65 20  int nRecyclable 
81b0: 3d 20 30 3b 0a 20 20 66 6f 72 28 70 3d 70 63 61  = 0;.  for(p=pca
81c0: 63 68 65 31 2e 67 72 70 2e 70 4c 72 75 48 65 61  che1.grp.pLruHea
81d0: 64 3b 20 70 3b 20 70 3d 70 2d 3e 70 4c 72 75 4e  d; p; p=p->pLruN
81e0: 65 78 74 29 7b 0a 20 20 20 20 61 73 73 65 72 74  ext){.    assert
81f0: 28 20 70 2d 3e 69 73 50 69 6e 6e 65 64 3d 3d 30  ( p->isPinned==0
8200: 20 29 3b 0a 20 20 20 20 6e 52 65 63 79 63 6c 61   );.    nRecycla
8210: 62 6c 65 2b 2b 3b 0a 20 20 7d 0a 20 20 2a 70 6e  ble++;.  }.  *pn
8220: 43 75 72 72 65 6e 74 20 3d 20 70 63 61 63 68 65  Current = pcache
8230: 31 2e 67 72 70 2e 6e 43 75 72 72 65 6e 74 50 61  1.grp.nCurrentPa
8240: 67 65 3b 0a 20 20 2a 70 6e 4d 61 78 20 3d 20 28  ge;.  *pnMax = (
8250: 69 6e 74 29 70 63 61 63 68 65 31 2e 67 72 70 2e  int)pcache1.grp.
8260: 6e 4d 61 78 50 61 67 65 3b 0a 20 20 2a 70 6e 4d  nMaxPage;.  *pnM
8270: 69 6e 20 3d 20 28 69 6e 74 29 70 63 61 63 68 65  in = (int)pcache
8280: 31 2e 67 72 70 2e 6e 4d 69 6e 50 61 67 65 3b 0a  1.grp.nMinPage;.
8290: 20 20 2a 70 6e 52 65 63 79 63 6c 61 62 6c 65 20    *pnRecyclable 
82a0: 3d 20 6e 52 65 63 79 63 6c 61 62 6c 65 3b 0a 7d  = nRecyclable;.}
82b0: 0a 23 65 6e 64 69 66 0a                          .#endif.