/ Hex Artifact Content
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Artifact a1d860753eee0a46165afaad3962a88463fb32a8:


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 74 79 70  oup PGroup;..typ
0360: 65 64 65 66 20 73 74 72 75 63 74 20 50 47 72 6f  edef struct PGro
0370: 75 70 42 6c 6f 63 6b 20 50 47 72 6f 75 70 42 6c  upBlock PGroupBl
0380: 6f 63 6b 3b 0a 74 79 70 65 64 65 66 20 73 74 72  ock;.typedef str
0390: 75 63 74 20 50 47 72 6f 75 70 42 6c 6f 63 6b 4c  uct PGroupBlockL
03a0: 69 73 74 20 50 47 72 6f 75 70 42 6c 6f 63 6b 4c  ist PGroupBlockL
03b0: 69 73 74 3b 0a 0a 2f 2a 20 45 61 63 68 20 70 61  ist;../* Each pa
03c0: 67 65 20 63 61 63 68 65 20 28 6f 72 20 50 43 61  ge cache (or PCa
03d0: 63 68 65 29 20 62 65 6c 6f 6e 67 73 20 74 6f 20  che) belongs to 
03e0: 61 20 50 47 72 6f 75 70 2e 20 20 41 20 50 47 72  a PGroup.  A PGr
03f0: 6f 75 70 20 69 73 20 61 20 73 65 74 20 0a 2a 2a  oup is a set .**
0400: 20 6f 66 20 6f 6e 65 20 6f 72 20 6d 6f 72 65 20   of one or more 
0410: 50 43 61 63 68 65 73 20 74 68 61 74 20 61 72 65  PCaches that are
0420: 20 61 62 6c 65 20 74 6f 20 72 65 63 79 63 6c 65   able to recycle
0430: 20 65 61 63 68 20 6f 74 68 65 72 73 20 75 6e 70   each others unp
0440: 69 6e 6e 65 64 0a 2a 2a 20 70 61 67 65 73 20 77  inned.** pages w
0450: 68 65 6e 20 74 68 65 79 20 61 72 65 20 75 6e 64  hen they are und
0460: 65 72 20 6d 65 6d 6f 72 79 20 70 72 65 73 73 75  er memory pressu
0470: 72 65 2e 20 20 41 20 50 47 72 6f 75 70 20 69 73  re.  A PGroup is
0480: 20 61 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66 0a   an instance of.
0490: 2a 2a 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  ** the following
04a0: 20 6f 62 6a 65 63 74 2e 0a 2a 2a 0a 2a 2a 20 54   object..**.** T
04b0: 68 69 73 20 70 61 67 65 20 63 61 63 68 65 20 69  his page cache i
04c0: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 77 6f  mplementation wo
04d0: 72 6b 73 20 69 6e 20 6f 6e 65 20 6f 66 20 74 77  rks in one of tw
04e0: 6f 20 6d 6f 64 65 73 3a 0a 2a 2a 0a 2a 2a 20 20  o modes:.**.**  
04f0: 20 28 31 29 20 20 45 76 65 72 79 20 50 43 61 63   (1)  Every PCac
0500: 68 65 20 69 73 20 74 68 65 20 73 6f 6c 65 20 6d  he is the sole m
0510: 65 6d 62 65 72 20 6f 66 20 69 74 73 20 6f 77 6e  ember of its own
0520: 20 50 47 72 6f 75 70 2e 20 20 54 68 65 72 65 20   PGroup.  There 
0530: 69 73 0a 2a 2a 20 20 20 20 20 20 20 20 6f 6e 65  is.**        one
0540: 20 50 47 72 6f 75 70 20 70 65 72 20 50 43 61 63   PGroup per PCac
0550: 68 65 2e 0a 2a 2a 0a 2a 2a 20 20 20 28 32 29 20  he..**.**   (2) 
0560: 20 54 68 65 72 65 20 69 73 20 61 20 73 69 6e 67   There is a sing
0570: 6c 65 20 67 6c 6f 62 61 6c 20 50 47 72 6f 75 70  le global PGroup
0580: 20 74 68 61 74 20 61 6c 6c 20 50 43 61 63 68 65   that all PCache
0590: 73 20 61 72 65 20 61 20 6d 65 6d 62 65 72 0a 2a  s are a member.*
05a0: 2a 20 20 20 20 20 20 20 20 6f 66 2e 0a 2a 2a 0a  *        of..**.
05b0: 2a 2a 20 4d 6f 64 65 20 31 20 75 73 65 73 20 6d  ** Mode 1 uses m
05c0: 6f 72 65 20 6d 65 6d 6f 72 79 20 28 73 69 6e 63  ore memory (sinc
05d0: 65 20 50 43 61 63 68 65 20 69 6e 73 74 61 6e 63  e PCache instanc
05e0: 65 73 20 61 72 65 20 6e 6f 74 20 61 62 6c 65 20  es are not able 
05f0: 74 6f 20 72 6f 62 0a 2a 2a 20 75 6e 75 73 65 64  to rob.** unused
0600: 20 70 61 67 65 73 20 66 72 6f 6d 20 6f 74 68 65   pages from othe
0610: 72 20 50 43 61 63 68 65 73 29 20 62 75 74 20 69  r PCaches) but i
0620: 74 20 61 6c 73 6f 20 6f 70 65 72 61 74 65 73 20  t also operates 
0630: 77 69 74 68 6f 75 74 20 61 20 6d 75 74 65 78 2c  without a mutex,
0640: 0a 2a 2a 20 61 6e 64 20 69 73 20 74 68 65 72 65  .** and is there
0650: 66 6f 72 65 20 6f 66 74 65 6e 20 66 61 73 74 65  fore often faste
0660: 72 2e 20 20 4d 6f 64 65 20 32 20 72 65 71 75 69  r.  Mode 2 requi
0670: 72 65 73 20 61 20 6d 75 74 65 78 20 69 6e 20 6f  res a mutex in o
0680: 72 64 65 72 20 74 6f 20 62 65 0a 2a 2a 20 74 68  rder to be.** th
0690: 72 65 61 64 73 61 66 65 2c 20 62 75 74 20 69 73  readsafe, but is
06a0: 20 61 62 6c 65 20 72 65 63 79 63 6c 65 20 70 61   able recycle pa
06b0: 67 65 73 20 6d 6f 72 65 20 65 66 66 69 63 69 65  ges more efficie
06c0: 6e 74 2e 0a 2a 2a 0a 2a 2a 20 46 6f 72 20 6d 6f  nt..**.** For mo
06d0: 64 65 20 28 31 29 2c 20 50 47 72 6f 75 70 2e 6d  de (1), PGroup.m
06e0: 75 74 65 78 20 69 73 20 4e 55 4c 4c 2e 20 20 46  utex is NULL.  F
06f0: 6f 72 20 6d 6f 64 65 20 28 32 29 20 74 68 65 72  or mode (2) ther
0700: 65 20 69 73 20 6f 6e 6c 79 20 61 20 73 69 6e 67  e is only a sing
0710: 6c 65 0a 2a 2a 20 50 47 72 6f 75 70 20 77 68 69  le.** PGroup whi
0720: 63 68 20 69 73 20 74 68 65 20 70 63 61 63 68 65  ch is the pcache
0730: 31 2e 67 72 70 20 67 6c 6f 62 61 6c 20 76 61 72  1.grp global var
0740: 69 61 62 6c 65 20 61 6e 64 20 69 74 73 20 6d 75  iable and its mu
0750: 74 65 78 20 69 73 0a 2a 2a 20 53 51 4c 49 54 45  tex is.** SQLITE
0760: 5f 4d 55 54 45 58 5f 53 54 41 54 49 43 5f 4c 52  _MUTEX_STATIC_LR
0770: 55 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 50 47 72  U..*/.struct PGr
0780: 6f 75 70 20 7b 0a 20 20 73 71 6c 69 74 65 33 5f  oup {.  sqlite3_
0790: 6d 75 74 65 78 20 2a 6d 75 74 65 78 3b 20 20 20  mutex *mutex;   
07a0: 20 20 20 20 20 20 20 2f 2a 20 4d 55 54 45 58 5f         /* MUTEX_
07b0: 53 54 41 54 49 43 5f 4c 52 55 20 6f 72 20 4e 55  STATIC_LRU or NU
07c0: 4c 4c 20 2a 2f 0a 20 20 69 6e 74 20 6e 4d 61 78  LL */.  int nMax
07d0: 50 61 67 65 3b 20 20 20 20 20 20 20 20 20 20 20  Page;           
07e0: 20 20 20 20 20 20 20 2f 2a 20 53 75 6d 20 6f 66         /* Sum of
07f0: 20 6e 4d 61 78 20 66 6f 72 20 70 75 72 67 65 61   nMax for purgea
0800: 62 6c 65 20 63 61 63 68 65 73 20 2a 2f 0a 20 20  ble caches */.  
0810: 69 6e 74 20 6e 4d 69 6e 50 61 67 65 3b 20 20 20  int nMinPage;   
0820: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0830: 2a 20 53 75 6d 20 6f 66 20 6e 4d 69 6e 20 66 6f  * Sum of nMin fo
0840: 72 20 70 75 72 67 65 61 62 6c 65 20 63 61 63 68  r purgeable cach
0850: 65 73 20 2a 2f 0a 20 20 69 6e 74 20 6d 78 50 69  es */.  int mxPi
0860: 6e 6e 65 64 3b 20 20 20 20 20 20 20 20 20 20 20  nned;           
0870: 20 20 20 20 20 20 20 2f 2a 20 6e 4d 61 78 70 61         /* nMaxpa
0880: 67 65 20 2b 20 31 30 20 2d 20 6e 4d 69 6e 50 61  ge + 10 - nMinPa
0890: 67 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 43 75 72  ge */.  int nCur
08a0: 72 65 6e 74 50 61 67 65 3b 20 20 20 20 20 20 20  rentPage;       
08b0: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
08c0: 20 6f 66 20 70 75 72 67 65 61 62 6c 65 20 70 61   of purgeable pa
08d0: 67 65 73 20 61 6c 6c 6f 63 61 74 65 64 20 2a 2f  ges allocated */
08e0: 0a 20 20 50 67 48 64 72 31 20 2a 70 4c 72 75 48  .  PgHdr1 *pLruH
08f0: 65 61 64 2c 20 2a 70 4c 72 75 54 61 69 6c 3b 20  ead, *pLruTail; 
0900: 20 20 2f 2a 20 4c 52 55 20 6c 69 73 74 20 6f 66    /* LRU list of
0910: 20 75 6e 70 69 6e 6e 65 64 20 70 61 67 65 73 20   unpinned pages 
0920: 2a 2f 0a 20 20 50 47 72 6f 75 70 42 6c 6f 63 6b  */.  PGroupBlock
0930: 4c 69 73 74 20 2a 70 42 6c 6f 63 6b 4c 69 73 74  List *pBlockList
0940: 3b 20 20 20 2f 2a 20 4c 69 73 74 20 6f 66 20 62  ;   /* List of b
0950: 6c 6f 63 6b 2d 6c 69 73 74 73 20 66 6f 72 20 74  lock-lists for t
0960: 68 69 73 20 67 72 6f 75 70 20 2a 2f 0a 7d 3b 0a  his group */.};.
0970: 0a 2f 2a 0a 2a 2a 20 49 66 20 53 51 4c 49 54 45  ./*.** If SQLITE
0980: 5f 50 41 47 45 43 41 43 48 45 5f 42 4c 4f 43 4b  _PAGECACHE_BLOCK
0990: 41 4c 4c 4f 43 20 69 73 20 64 65 66 69 6e 65 64  ALLOC is defined
09a0: 20 77 68 65 6e 20 74 68 65 20 6c 69 62 72 61 72   when the librar
09b0: 79 20 69 73 20 62 75 69 6c 74 2c 0a 2a 2a 20 65  y is built,.** e
09c0: 61 63 68 20 50 47 72 6f 75 70 20 73 74 72 75 63  ach PGroup struc
09d0: 74 75 72 65 20 68 61 73 20 61 20 6c 69 6e 6b 65  ture has a linke
09e0: 64 20 6c 69 73 74 20 6f 66 20 74 68 65 20 74 68  d list of the th
09f0: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 73 74 61 72  e following star
0a00: 74 69 6e 67 0a 2a 2a 20 61 74 20 50 47 72 6f 75  ting.** at PGrou
0a10: 70 2e 70 42 6c 6f 63 6b 4c 69 73 74 2e 20 54 68  p.pBlockList. Th
0a20: 65 72 65 20 69 73 20 6f 6e 65 20 65 6e 74 72 79  ere is one entry
0a30: 20 66 6f 72 20 65 61 63 68 20 64 69 73 74 69 6e   for each distin
0a40: 63 74 20 70 61 67 65 2d 73 69 7a 65 20 0a 2a 2a  ct page-size .**
0a50: 20 63 75 72 72 65 6e 74 6c 79 20 75 73 65 64 20   currently used 
0a60: 62 79 20 6d 65 6d 62 65 72 73 20 6f 66 20 74 68  by members of th
0a70: 65 20 50 47 72 6f 75 70 20 28 69 2e 65 2e 20 31  e PGroup (i.e. 1
0a80: 30 32 34 20 62 79 74 65 73 2c 20 34 30 39 36 20  024 bytes, 4096 
0a90: 62 79 74 65 73 0a 2a 2a 20 65 74 63 2e 29 2e 20  bytes.** etc.). 
0aa0: 56 61 72 69 61 62 6c 65 20 50 47 72 6f 75 70 42  Variable PGroupB
0ab0: 6c 6f 63 6b 4c 69 73 74 2e 6e 42 79 74 65 20 69  lockList.nByte i
0ac0: 73 20 73 65 74 20 74 6f 20 74 68 65 20 61 63 74  s set to the act
0ad0: 75 61 6c 20 61 6c 6c 6f 63 61 74 69 6f 6e 0a 2a  ual allocation.*
0ae0: 2a 20 73 69 7a 65 20 72 65 71 75 65 73 74 65 64  * size requested
0af0: 20 62 79 20 65 61 63 68 20 70 63 61 63 68 65 2c   by each pcache,
0b00: 20 77 68 69 63 68 20 69 73 20 74 68 65 20 64 61   which is the da
0b10: 74 61 62 61 73 65 20 70 61 67 65 2d 73 69 7a 65  tabase page-size
0b20: 20 70 6c 75 73 0a 2a 2a 20 74 68 65 20 76 61 72   plus.** the var
0b30: 69 6f 75 73 20 68 65 61 64 65 72 20 73 74 72 75  ious header stru
0b40: 63 74 75 72 65 73 20 75 73 65 64 20 62 79 20 74  ctures used by t
0b50: 68 65 20 70 63 61 63 68 65 2c 20 70 61 67 65 72  he pcache, pager
0b60: 20 61 6e 64 20 62 74 72 65 65 20 6c 61 79 65 72   and btree layer
0b70: 73 2e 0a 2a 2a 20 55 73 75 61 6c 6c 79 20 61 72  s..** Usually ar
0b80: 6f 75 6e 64 20 28 70 67 73 7a 2b 32 30 30 29 20  ound (pgsz+200) 
0b90: 62 79 74 65 73 2e 0a 2a 2a 0a 2a 2a 20 54 68 69  bytes..**.** Thi
0ba0: 73 20 73 69 7a 65 20 28 70 67 73 7a 2b 32 30 30  s size (pgsz+200
0bb0: 29 20 62 79 74 65 73 20 69 73 20 6e 6f 74 20 61  ) bytes is not a
0bc0: 6c 6c 6f 63 61 74 65 64 20 65 66 66 69 63 69 65  llocated efficie
0bd0: 6e 74 6c 79 20 62 79 20 73 6f 6d 65 0a 2a 2a 20  ntly by some.** 
0be0: 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 73 20  implementations 
0bf0: 6f 66 20 6d 61 6c 6c 6f 63 2e 20 49 6e 20 70 61  of malloc. In pa
0c00: 72 74 69 63 75 6c 61 72 2c 20 73 6f 6d 65 20 69  rticular, some i
0c10: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 73 20 61  mplementations a
0c20: 72 65 20 6f 6e 6c 79 0a 2a 2a 20 61 62 6c 65 20  re only.** able 
0c30: 74 6f 20 61 6c 6c 6f 63 61 74 65 20 62 6c 6f 63  to allocate bloc
0c40: 6b 73 20 6f 66 20 6d 65 6d 6f 72 79 20 63 68 75  ks of memory chu
0c50: 6e 6b 73 20 6f 66 20 32 5e 4e 20 62 79 74 65 73  nks of 2^N bytes
0c60: 2c 20 77 68 65 72 65 20 4e 20 69 73 20 73 6f 6d  , where N is som
0c70: 65 0a 2a 2a 20 69 6e 74 65 67 65 72 20 76 61 6c  e.** integer val
0c80: 75 65 2e 20 53 69 6e 63 65 20 74 68 65 20 70 61  ue. Since the pa
0c90: 67 65 2d 73 69 7a 65 20 69 73 20 61 20 70 6f 77  ge-size is a pow
0ca0: 65 72 20 6f 66 20 32 2c 20 74 68 69 73 20 6d 65  er of 2, this me
0cb0: 61 6e 73 20 77 65 0a 2a 2a 20 65 6e 64 20 75 70  ans we.** end up
0cc0: 20 77 61 73 74 69 6e 67 20 28 70 67 73 7a 2d 32   wasting (pgsz-2
0cd0: 30 30 29 20 62 79 74 65 73 20 69 6e 20 65 61 63  00) bytes in eac
0ce0: 68 20 61 6c 6c 6f 63 61 74 69 6f 6e 2e 0a 2a 2a  h allocation..**
0cf0: 0a 2a 2a 20 49 66 20 53 51 4c 49 54 45 5f 50 41  .** If SQLITE_PA
0d00: 47 45 43 41 43 48 45 5f 42 4c 4f 43 4b 41 4c 4c  GECACHE_BLOCKALL
0d10: 4f 43 20 69 73 20 64 65 66 69 6e 65 64 2c 20 74  OC is defined, t
0d20: 68 65 20 28 70 67 73 7a 2b 32 30 30 29 20 62 79  he (pgsz+200) by
0d30: 74 65 20 62 6c 6f 63 6b 73 0a 2a 2a 20 61 72 65  te blocks.** are
0d40: 20 6e 6f 74 20 61 6c 6c 6f 63 61 74 65 64 20 64   not allocated d
0d50: 69 72 65 63 74 6c 79 2e 20 49 6e 73 74 65 61 64  irectly. Instead
0d60: 2c 20 62 6c 6f 63 6b 73 20 6f 66 20 72 6f 75 67  , blocks of roug
0d70: 68 6c 79 20 4d 2a 28 70 67 73 7a 2b 32 30 30 29  hly M*(pgsz+200)
0d80: 20 62 79 74 65 73 20 0a 2a 2a 20 61 72 65 20 72   bytes .** are r
0d90: 65 71 75 65 73 74 65 64 20 66 72 6f 6d 20 6d 61  equested from ma
0da0: 6c 6c 6f 63 20 61 6c 6c 6f 63 61 74 6f 72 2e 20  lloc allocator. 
0db0: 41 66 74 65 72 20 61 20 62 6c 6f 63 6b 20 69 73  After a block is
0dc0: 20 72 65 74 75 72 6e 65 64 2c 0a 2a 2a 20 73 71   returned,.** sq
0dd0: 6c 69 74 65 33 4d 61 6c 6c 6f 63 53 69 7a 65 28  lite3MallocSize(
0de0: 29 20 69 73 20 75 73 65 64 20 74 6f 20 64 65 74  ) is used to det
0df0: 65 72 6d 69 6e 65 20 68 6f 77 20 6d 61 6e 79 20  ermine how many 
0e00: 28 70 67 73 7a 2b 32 30 30 29 20 62 79 74 65 0a  (pgsz+200) byte.
0e10: 2a 2a 20 61 6c 6c 6f 63 61 74 69 6f 6e 73 20 63  ** allocations c
0e20: 61 6e 20 66 69 74 20 69 6e 20 74 68 65 20 73 70  an fit in the sp
0e30: 61 63 65 20 72 65 74 75 72 6e 65 64 20 62 79 20  ace returned by 
0e40: 6d 61 6c 6c 6f 63 28 29 2e 20 54 68 69 73 20 76  malloc(). This v
0e50: 61 6c 75 65 20 6d 61 79 0a 2a 2a 20 62 65 20 6d  alue may.** be m
0e60: 6f 72 65 20 74 68 61 6e 20 4d 2e 0a 2a 2a 0a 2a  ore than M..**.*
0e70: 2a 20 54 68 65 20 62 6c 6f 63 6b 73 20 61 72 65  * The blocks are
0e80: 20 73 74 6f 72 65 64 20 69 6e 20 61 20 64 6f 75   stored in a dou
0e90: 62 6c 79 2d 6c 69 6e 6b 65 64 20 6c 69 73 74 2e  bly-linked list.
0ea0: 20 56 61 72 69 61 62 6c 65 20 50 47 72 6f 75 70   Variable PGroup
0eb0: 42 6c 6f 63 6b 2e 6e 45 6e 74 72 79 0a 2a 2a 20  Block.nEntry.** 
0ec0: 63 6f 6e 74 61 69 6e 73 20 74 68 65 20 6e 75 6d  contains the num
0ed0: 62 65 72 20 6f 66 20 61 6c 6c 6f 63 61 74 69 6f  ber of allocatio
0ee0: 6e 73 20 74 68 61 74 20 77 69 6c 6c 20 66 69 74  ns that will fit
0ef0: 20 69 6e 20 74 68 65 20 61 44 61 74 61 5b 5d 20   in the aData[] 
0f00: 73 70 61 63 65 2e 0a 2a 2a 20 6e 45 6e 74 72 79  space..** nEntry
0f10: 20 69 73 20 6c 69 6d 69 74 65 64 20 74 6f 20 74   is limited to t
0f20: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 62 69 74  he number of bit
0f30: 73 20 69 6e 20 62 69 74 6d 61 73 6b 20 6d 55 73  s in bitmask mUs
0f40: 65 64 2e 20 49 66 20 61 20 73 6c 6f 74 0a 2a 2a  ed. If a slot.**
0f50: 20 77 69 74 68 69 6e 20 61 44 61 74 61 20 69 73   within aData is
0f60: 20 69 6e 20 75 73 65 2c 20 74 68 65 20 63 6f 72   in use, the cor
0f70: 72 65 73 70 6f 6e 64 69 6e 67 20 62 69 74 20 69  responding bit i
0f80: 6e 20 6d 55 73 65 64 20 69 73 20 73 65 74 2e 20  n mUsed is set. 
0f90: 54 68 75 73 0a 2a 2a 20 77 68 65 6e 20 28 6d 55  Thus.** when (mU
0fa0: 73 65 64 2b 31 3d 3d 28 31 20 3c 3c 20 6e 45 6e  sed+1==(1 << nEn
0fb0: 74 72 79 29 29 20 74 68 65 20 62 6c 6f 63 6b 20  try)) the block 
0fc0: 69 73 20 63 6f 6d 70 6c 65 74 65 6c 79 20 66 75  is completely fu
0fd0: 6c 6c 2e 0a 2a 2a 0a 2a 2a 20 45 61 63 68 20 74  ll..**.** Each t
0fe0: 69 6d 65 20 61 20 73 6c 6f 74 20 77 69 74 68 69  ime a slot withi
0ff0: 6e 20 61 20 62 6c 6f 63 6b 20 69 73 20 66 72 65  n a block is fre
1000: 65 64 2c 20 74 68 65 20 62 6c 6f 63 6b 20 69 73  ed, the block is
1010: 20 6d 6f 76 65 64 20 74 6f 20 74 68 65 20 73 74   moved to the st
1020: 61 72 74 0a 2a 2a 20 6f 66 20 74 68 65 20 6c 69  art.** of the li
1030: 6e 6b 65 64 2d 6c 69 73 74 2e 20 41 6e 64 20 69  nked-list. And i
1040: 66 20 61 20 62 6c 6f 63 6b 20 62 65 63 6f 6d 65  f a block become
1050: 73 20 63 6f 6d 70 6c 65 74 65 6c 79 20 66 75 6c  s completely ful
1060: 6c 2c 20 74 68 65 6e 20 69 74 20 69 73 0a 2a 2a  l, then it is.**
1070: 20 6d 6f 76 65 64 20 74 6f 20 74 68 65 20 65 6e   moved to the en
1080: 64 20 6f 66 20 74 68 65 20 6c 69 73 74 2e 20 41  d of the list. A
1090: 73 20 61 20 72 65 73 75 6c 74 2c 20 77 68 65 6e  s a result, when
10a0: 20 73 65 61 72 63 68 69 6e 67 20 66 6f 72 20 61   searching for a
10b0: 20 66 72 65 65 0a 2a 2a 20 73 6c 6f 74 2c 20 6f   free.** slot, o
10c0: 6e 6c 79 20 74 68 65 20 66 69 72 73 74 20 62 6c  nly the first bl
10d0: 6f 63 6b 20 69 6e 20 74 68 65 20 6c 69 73 74 20  ock in the list 
10e0: 6e 65 65 64 20 62 65 20 65 78 61 6d 69 6e 65 64  need be examined
10f0: 2e 20 49 66 20 69 74 20 69 73 20 66 75 6c 6c 2c  . If it is full,
1100: 0a 2a 2a 20 74 68 65 6e 20 69 74 20 69 73 20 67  .** then it is g
1110: 75 61 72 61 6e 74 65 65 64 20 74 68 61 74 20 61  uaranteed that a
1120: 6c 6c 20 62 6c 6f 63 6b 73 20 61 72 65 20 66 75  ll blocks are fu
1130: 6c 6c 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 50 47  ll..*/.struct PG
1140: 72 6f 75 70 42 6c 6f 63 6b 4c 69 73 74 20 7b 0a  roupBlockList {.
1150: 20 20 69 6e 74 20 6e 42 79 74 65 3b 20 20 20 20    int nByte;    
1160: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1170: 20 2f 2a 20 53 69 7a 65 20 6f 66 20 65 61 63 68   /* Size of each
1180: 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 69 6e 20 62   allocation in b
1190: 79 74 65 73 20 2a 2f 0a 20 20 50 47 72 6f 75 70  ytes */.  PGroup
11a0: 42 6c 6f 63 6b 20 2a 70 46 69 72 73 74 3b 20 20  Block *pFirst;  
11b0: 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69 72 73           /* Firs
11c0: 74 20 50 47 72 6f 75 70 42 6c 6f 63 6b 20 69 6e  t PGroupBlock in
11d0: 20 6c 69 73 74 20 2a 2f 0a 20 20 50 47 72 6f 75   list */.  PGrou
11e0: 70 42 6c 6f 63 6b 20 2a 70 4c 61 73 74 3b 20 20  pBlock *pLast;  
11f0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 61 73            /* Las
1200: 74 20 50 47 72 6f 75 70 42 6c 6f 63 6b 20 69 6e  t PGroupBlock in
1210: 20 6c 69 73 74 20 2a 2f 0a 20 20 50 47 72 6f 75   list */.  PGrou
1220: 70 42 6c 6f 63 6b 4c 69 73 74 20 2a 70 4e 65 78  pBlockList *pNex
1230: 74 3b 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78  t;        /* Nex
1240: 74 20 62 6c 6f 63 6b 2d 6c 69 73 74 20 61 74 74  t block-list att
1250: 61 63 68 65 64 20 74 6f 20 67 72 6f 75 70 20 2a  ached to group *
1260: 2f 0a 7d 3b 0a 0a 73 74 72 75 63 74 20 50 47 72  /.};..struct PGr
1270: 6f 75 70 42 6c 6f 63 6b 20 7b 0a 20 20 42 69 74  oupBlock {.  Bit
1280: 6d 61 73 6b 20 6d 55 73 65 64 3b 20 20 20 20 20  mask mUsed;     
1290: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d              /* M
12a0: 61 73 6b 20 6f 66 20 75 73 65 64 20 73 6c 6f 74  ask of used slot
12b0: 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 45 6e 74 72  s */.  int nEntr
12c0: 79 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  y;              
12d0: 20 20 20 20 20 20 2f 2a 20 4d 61 78 69 6d 75 6d        /* Maximum
12e0: 20 6e 75 6d 62 65 72 20 6f 66 20 61 6c 6c 6f 63   number of alloc
12f0: 61 74 69 6f 6e 73 20 69 6e 20 61 44 61 74 61 5b  ations in aData[
1300: 5d 20 2a 2f 0a 20 20 75 38 20 2a 61 44 61 74 61  ] */.  u8 *aData
1310: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1320: 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72        /* Pointer
1330: 20 74 6f 20 64 61 74 61 20 62 6c 6f 63 6b 20 2a   to data block *
1340: 2f 0a 20 20 50 47 72 6f 75 70 42 6c 6f 63 6b 20  /.  PGroupBlock 
1350: 2a 70 4e 65 78 74 3b 20 20 20 20 20 20 20 20 20  *pNext;         
1360: 20 20 20 2f 2a 20 4e 65 78 74 20 50 47 72 6f 75     /* Next PGrou
1370: 70 42 6c 6f 63 6b 20 69 6e 20 6c 69 73 74 20 2a  pBlock in list *
1380: 2f 0a 20 20 50 47 72 6f 75 70 42 6c 6f 63 6b 20  /.  PGroupBlock 
1390: 2a 70 50 72 65 76 3b 20 20 20 20 20 20 20 20 20  *pPrev;         
13a0: 20 20 20 2f 2a 20 50 72 65 76 69 6f 75 73 20 50     /* Previous P
13b0: 47 72 6f 75 70 42 6c 6f 63 6b 20 69 6e 20 6c 69  GroupBlock in li
13c0: 73 74 20 2a 2f 0a 20 20 50 47 72 6f 75 70 42 6c  st */.  PGroupBl
13d0: 6f 63 6b 4c 69 73 74 20 2a 70 4c 69 73 74 3b 20  ockList *pList; 
13e0: 20 20 20 20 20 20 20 2f 2a 20 4f 77 6e 65 72 20         /* Owner 
13f0: 6c 69 73 74 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 20 4d  list */.};../* M
1400: 69 6e 69 6d 75 6d 20 76 61 6c 75 65 20 66 6f 72  inimum value for
1410: 20 50 47 72 6f 75 70 42 6c 6f 63 6b 2e 6e 45 6e   PGroupBlock.nEn
1420: 74 72 79 20 2a 2f 0a 23 64 65 66 69 6e 65 20 50  try */.#define P
1430: 41 47 45 43 41 43 48 45 5f 42 4c 4f 43 4b 41 4c  AGECACHE_BLOCKAL
1440: 4c 4f 43 5f 4d 49 4e 45 4e 54 52 59 20 31 35 0a  LOC_MINENTRY 15.
1450: 0a 2f 2a 20 45 61 63 68 20 70 61 67 65 20 63 61  ./* Each page ca
1460: 63 68 65 20 69 73 20 61 6e 20 69 6e 73 74 61 6e  che is an instan
1470: 63 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77  ce of the follow
1480: 69 6e 67 20 6f 62 6a 65 63 74 2e 20 20 45 76 65  ing object.  Eve
1490: 72 79 0a 2a 2a 20 6f 70 65 6e 20 64 61 74 61 62  ry.** open datab
14a0: 61 73 65 20 66 69 6c 65 20 28 69 6e 63 6c 75 64  ase file (includ
14b0: 69 6e 67 20 65 61 63 68 20 69 6e 2d 6d 65 6d 6f  ing each in-memo
14c0: 72 79 20 64 61 74 61 62 61 73 65 20 61 6e 64 20  ry database and 
14d0: 65 61 63 68 0a 2a 2a 20 74 65 6d 70 6f 72 61 72  each.** temporar
14e0: 79 20 6f 72 20 74 72 61 6e 73 69 65 6e 74 20 64  y or transient d
14f0: 61 74 61 62 61 73 65 29 20 68 61 73 20 61 20 73  atabase) has a s
1500: 69 6e 67 6c 65 20 70 61 67 65 20 63 61 63 68 65  ingle page cache
1510: 20 77 68 69 63 68 0a 2a 2a 20 69 73 20 61 6e 20   which.** is an 
1520: 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 69 73  instance of this
1530: 20 6f 62 6a 65 63 74 2e 0a 2a 2a 0a 2a 2a 20 50   object..**.** P
1540: 6f 69 6e 74 65 72 73 20 74 6f 20 73 74 72 75 63  ointers to struc
1550: 74 75 72 65 73 20 6f 66 20 74 68 69 73 20 74 79  tures of this ty
1560: 70 65 20 61 72 65 20 63 61 73 74 20 61 6e 64 20  pe are cast and 
1570: 72 65 74 75 72 6e 65 64 20 61 73 20 0a 2a 2a 20  returned as .** 
1580: 6f 70 61 71 75 65 20 73 71 6c 69 74 65 33 5f 70  opaque sqlite3_p
1590: 63 61 63 68 65 2a 20 68 61 6e 64 6c 65 73 2e 0a  cache* handles..
15a0: 2a 2f 0a 73 74 72 75 63 74 20 50 43 61 63 68 65  */.struct PCache
15b0: 31 20 7b 0a 20 20 2f 2a 20 43 61 63 68 65 20 63  1 {.  /* Cache c
15c0: 6f 6e 66 69 67 75 72 61 74 69 6f 6e 20 70 61 72  onfiguration par
15d0: 61 6d 65 74 65 72 73 2e 20 50 61 67 65 20 73 69  ameters. Page si
15e0: 7a 65 20 28 73 7a 50 61 67 65 29 20 61 6e 64 20  ze (szPage) and 
15f0: 74 68 65 20 70 75 72 67 65 61 62 6c 65 0a 20 20  the purgeable.  
1600: 2a 2a 20 66 6c 61 67 20 28 62 50 75 72 67 65 61  ** flag (bPurgea
1610: 62 6c 65 29 20 61 72 65 20 73 65 74 20 77 68 65  ble) are set whe
1620: 6e 20 74 68 65 20 63 61 63 68 65 20 69 73 20 63  n the cache is c
1630: 72 65 61 74 65 64 2e 20 6e 4d 61 78 20 6d 61 79  reated. nMax may
1640: 20 62 65 20 0a 20 20 2a 2a 20 6d 6f 64 69 66 69   be .  ** modifi
1650: 65 64 20 61 74 20 61 6e 79 20 74 69 6d 65 20 62  ed at any time b
1660: 79 20 61 20 63 61 6c 6c 20 74 6f 20 74 68 65 20  y a call to the 
1670: 70 63 61 63 68 65 31 43 61 63 68 65 53 69 7a 65  pcache1CacheSize
1680: 28 29 20 6d 65 74 68 6f 64 2e 0a 20 20 2a 2a 20  () method..  ** 
1690: 54 68 65 20 50 47 72 6f 75 70 20 6d 75 74 65 78  The PGroup mutex
16a0: 20 6d 75 73 74 20 62 65 20 68 65 6c 64 20 77 68   must be held wh
16b0: 65 6e 20 61 63 63 65 73 73 69 6e 67 20 6e 4d 61  en accessing nMa
16c0: 78 2e 0a 20 20 2a 2f 0a 20 20 50 47 72 6f 75 70  x..  */.  PGroup
16d0: 20 2a 70 47 72 6f 75 70 3b 20 20 20 20 20 20 20   *pGroup;       
16e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
16f0: 20 50 47 72 6f 75 70 20 74 68 69 73 20 63 61 63   PGroup this cac
1700: 68 65 20 62 65 6c 6f 6e 67 73 20 74 6f 20 2a 2f  he belongs to */
1710: 0a 20 20 69 6e 74 20 73 7a 50 61 67 65 3b 20 20  .  int szPage;  
1720: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1730: 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
1740: 66 20 61 6c 6c 6f 63 61 74 65 64 20 70 61 67 65  f allocated page
1750: 73 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20  s in bytes */.  
1760: 69 6e 74 20 62 50 75 72 67 65 61 62 6c 65 3b 20  int bPurgeable; 
1770: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1780: 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 63      /* True if c
1790: 61 63 68 65 20 69 73 20 70 75 72 67 65 61 62 6c  ache is purgeabl
17a0: 65 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20  e */.  unsigned 
17b0: 69 6e 74 20 6e 4d 69 6e 3b 20 20 20 20 20 20 20  int nMin;       
17c0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 69             /* Mi
17d0: 6e 69 6d 75 6d 20 6e 75 6d 62 65 72 20 6f 66 20  nimum number of 
17e0: 70 61 67 65 73 20 72 65 73 65 72 76 65 64 20 2a  pages reserved *
17f0: 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74  /.  unsigned int
1800: 20 6e 4d 61 78 3b 20 20 20 20 20 20 20 20 20 20   nMax;          
1810: 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6e 66 69          /* Confi
1820: 67 75 72 65 64 20 22 63 61 63 68 65 5f 73 69 7a  gured "cache_siz
1830: 65 22 20 76 61 6c 75 65 20 2a 2f 0a 20 20 75 6e  e" value */.  un
1840: 73 69 67 6e 65 64 20 69 6e 74 20 6e 39 30 70 63  signed int n90pc
1850: 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t;              
1860: 20 20 2f 2a 20 6e 4d 61 78 2a 39 2f 31 30 20 2a    /* nMax*9/10 *
1870: 2f 0a 0a 20 20 2f 2a 20 48 61 73 68 20 74 61 62  /..  /* Hash tab
1880: 6c 65 20 6f 66 20 61 6c 6c 20 70 61 67 65 73 2e  le of all pages.
1890: 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 76   The following v
18a0: 61 72 69 61 62 6c 65 73 20 6d 61 79 20 6f 6e 6c  ariables may onl
18b0: 79 20 62 65 20 61 63 63 65 73 73 65 64 0a 20 20  y be accessed.  
18c0: 2a 2a 20 77 68 65 6e 20 74 68 65 20 61 63 63 65  ** when the acce
18d0: 73 73 6f 72 20 69 73 20 68 6f 6c 64 69 6e 67 20  ssor is holding 
18e0: 74 68 65 20 50 47 72 6f 75 70 20 6d 75 74 65 78  the PGroup mutex
18f0: 2e 0a 20 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65  ..  */.  unsigne
1900: 64 20 69 6e 74 20 6e 52 65 63 79 63 6c 61 62 6c  d int nRecyclabl
1910: 65 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  e;           /* 
1920: 4e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20  Number of pages 
1930: 69 6e 20 74 68 65 20 4c 52 55 20 6c 69 73 74 20  in the LRU list 
1940: 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e  */.  unsigned in
1950: 74 20 6e 50 61 67 65 3b 20 20 20 20 20 20 20 20  t nPage;        
1960: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 6f 74 61           /* Tota
1970: 6c 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65  l number of page
1980: 73 20 69 6e 20 61 70 48 61 73 68 20 2a 2f 0a 20  s in apHash */. 
1990: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 48   unsigned int nH
19a0: 61 73 68 3b 20 20 20 20 20 20 20 20 20 20 20 20  ash;            
19b0: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
19c0: 66 20 73 6c 6f 74 73 20 69 6e 20 61 70 48 61 73  f slots in apHas
19d0: 68 5b 5d 20 2a 2f 0a 20 20 50 67 48 64 72 31 20  h[] */.  PgHdr1 
19e0: 2a 2a 61 70 48 61 73 68 3b 20 20 20 20 20 20 20  **apHash;       
19f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1a00: 48 61 73 68 20 74 61 62 6c 65 20 66 6f 72 20 66  Hash table for f
1a10: 61 73 74 20 6c 6f 6f 6b 75 70 20 62 79 20 6b 65  ast lookup by ke
1a20: 79 20 2a 2f 0a 0a 20 20 75 6e 73 69 67 6e 65 64  y */..  unsigned
1a30: 20 69 6e 74 20 69 4d 61 78 4b 65 79 3b 20 20 20   int iMaxKey;   
1a40: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c              /* L
1a50: 61 72 67 65 73 74 20 6b 65 79 20 73 65 65 6e 20  argest key seen 
1a60: 73 69 6e 63 65 20 78 54 72 75 6e 63 61 74 65 28  since xTruncate(
1a70: 29 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 45  ) */.};../*.** E
1a80: 61 63 68 20 63 61 63 68 65 20 65 6e 74 72 79 20  ach cache entry 
1a90: 69 73 20 72 65 70 72 65 73 65 6e 74 65 64 20 62  is represented b
1aa0: 79 20 61 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66  y an instance of
1ab0: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 0a   the following .
1ac0: 2a 2a 20 73 74 72 75 63 74 75 72 65 2e 20 41 20  ** structure. A 
1ad0: 62 75 66 66 65 72 20 6f 66 20 50 67 48 64 72 31  buffer of PgHdr1
1ae0: 2e 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 20  .pCache->szPage 
1af0: 62 79 74 65 73 20 69 73 20 61 6c 6c 6f 63 61 74  bytes is allocat
1b00: 65 64 20 0a 2a 2a 20 64 69 72 65 63 74 6c 79 20  ed .** directly 
1b10: 62 65 66 6f 72 65 20 74 68 69 73 20 73 74 72 75  before this stru
1b20: 63 74 75 72 65 20 69 6e 20 6d 65 6d 6f 72 79 20  cture in memory 
1b30: 28 73 65 65 20 74 68 65 20 50 47 48 44 52 31 5f  (see the PGHDR1_
1b40: 54 4f 5f 50 41 47 45 28 29 20 0a 2a 2a 20 6d 61  TO_PAGE() .** ma
1b50: 63 72 6f 20 62 65 6c 6f 77 29 2e 0a 2a 2f 0a 73  cro below)..*/.s
1b60: 74 72 75 63 74 20 50 67 48 64 72 31 20 7b 0a 20  truct PgHdr1 {. 
1b70: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4b   unsigned int iK
1b80: 65 79 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ey;             
1b90: 2f 2a 20 4b 65 79 20 76 61 6c 75 65 20 28 70 61  /* Key value (pa
1ba0: 67 65 20 6e 75 6d 62 65 72 29 20 2a 2f 0a 20 20  ge number) */.  
1bb0: 50 67 48 64 72 31 20 2a 70 4e 65 78 74 3b 20 20  PgHdr1 *pNext;  
1bc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1bd0: 2a 20 4e 65 78 74 20 69 6e 20 68 61 73 68 20 74  * Next in hash t
1be0: 61 62 6c 65 20 63 68 61 69 6e 20 2a 2f 0a 20 20  able chain */.  
1bf0: 50 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 3b  PCache1 *pCache;
1c00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1c10: 2a 20 43 61 63 68 65 20 74 68 61 74 20 63 75 72  * Cache that cur
1c20: 72 65 6e 74 6c 79 20 6f 77 6e 73 20 74 68 69 73  rently owns this
1c30: 20 70 61 67 65 20 2a 2f 0a 20 20 50 67 48 64 72   page */.  PgHdr
1c40: 31 20 2a 70 4c 72 75 4e 65 78 74 3b 20 20 20 20  1 *pLruNext;    
1c50: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78            /* Nex
1c60: 74 20 69 6e 20 4c 52 55 20 6c 69 73 74 20 6f 66  t in LRU list of
1c70: 20 75 6e 70 69 6e 6e 65 64 20 70 61 67 65 73 20   unpinned pages 
1c80: 2a 2f 0a 20 20 50 67 48 64 72 31 20 2a 70 4c 72  */.  PgHdr1 *pLr
1c90: 75 50 72 65 76 3b 20 20 20 20 20 20 20 20 20 20  uPrev;          
1ca0: 20 20 20 20 2f 2a 20 50 72 65 76 69 6f 75 73 20      /* Previous 
1cb0: 69 6e 20 4c 52 55 20 6c 69 73 74 20 6f 66 20 75  in LRU list of u
1cc0: 6e 70 69 6e 6e 65 64 20 70 61 67 65 73 20 2a 2f  npinned pages */
1cd0: 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20  .};../*.** Free 
1ce0: 73 6c 6f 74 73 20 69 6e 20 74 68 65 20 61 6c 6c  slots in the all
1cf0: 6f 63 61 74 6f 72 20 75 73 65 64 20 74 6f 20 64  ocator used to d
1d00: 69 76 69 64 65 20 75 70 20 74 68 65 20 62 75 66  ivide up the buf
1d10: 66 65 72 20 70 72 6f 76 69 64 65 64 20 75 73 69  fer provided usi
1d20: 6e 67 0a 2a 2a 20 74 68 65 20 53 51 4c 49 54 45  ng.** the SQLITE
1d30: 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48  _CONFIG_PAGECACH
1d40: 45 20 6d 65 63 68 61 6e 69 73 6d 2e 0a 2a 2f 0a  E mechanism..*/.
1d50: 73 74 72 75 63 74 20 50 67 46 72 65 65 73 6c 6f  struct PgFreeslo
1d60: 74 20 7b 0a 20 20 50 67 46 72 65 65 73 6c 6f 74  t {.  PgFreeslot
1d70: 20 2a 70 4e 65 78 74 3b 20 20 2f 2a 20 4e 65 78   *pNext;  /* Nex
1d80: 74 20 66 72 65 65 20 73 6c 6f 74 20 2a 2f 0a 7d  t free slot */.}
1d90: 3b 0a 0a 2f 2a 0a 2a 2a 20 47 6c 6f 62 61 6c 20  ;../*.** Global 
1da0: 64 61 74 61 20 75 73 65 64 20 62 79 20 74 68 69  data used by thi
1db0: 73 20 63 61 63 68 65 2e 0a 2a 2f 0a 73 74 61 74  s cache..*/.stat
1dc0: 69 63 20 53 51 4c 49 54 45 5f 57 53 44 20 73 74  ic SQLITE_WSD st
1dd0: 72 75 63 74 20 50 43 61 63 68 65 47 6c 6f 62 61  ruct PCacheGloba
1de0: 6c 20 7b 0a 20 20 50 47 72 6f 75 70 20 67 72 70  l {.  PGroup grp
1df0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1e00: 20 20 20 20 20 2f 2a 20 54 68 65 20 67 6c 6f 62       /* The glob
1e10: 61 6c 20 50 47 72 6f 75 70 20 66 6f 72 20 6d 6f  al PGroup for mo
1e20: 64 65 20 28 32 29 20 2a 2f 0a 0a 20 20 2f 2a 20  de (2) */..  /* 
1e30: 56 61 72 69 61 62 6c 65 73 20 72 65 6c 61 74 65  Variables relate
1e40: 64 20 74 6f 20 53 51 4c 49 54 45 5f 43 4f 4e 46  d to SQLITE_CONF
1e50: 49 47 5f 50 41 47 45 43 41 43 48 45 20 73 65 74  IG_PAGECACHE set
1e60: 74 69 6e 67 73 2e 20 20 54 68 65 0a 20 20 2a 2a  tings.  The.  **
1e70: 20 73 7a 53 6c 6f 74 2c 20 6e 53 6c 6f 74 2c 20   szSlot, nSlot, 
1e80: 70 53 74 61 72 74 2c 20 70 45 6e 64 2c 20 6e 52  pStart, pEnd, nR
1e90: 65 73 65 72 76 65 2c 20 61 6e 64 20 69 73 49 6e  eserve, and isIn
1ea0: 69 74 20 76 61 6c 75 65 73 20 61 72 65 20 61 6c  it values are al
1eb0: 6c 0a 20 20 2a 2a 20 66 69 78 65 64 20 61 74 20  l.  ** fixed at 
1ec0: 73 71 6c 69 74 65 33 5f 69 6e 69 74 69 61 6c 69  sqlite3_initiali
1ed0: 7a 65 28 29 20 74 69 6d 65 20 61 6e 64 20 64 6f  ze() time and do
1ee0: 20 6e 6f 74 20 72 65 71 75 69 72 65 20 6d 75 74   not require mut
1ef0: 65 78 20 70 72 6f 74 65 63 74 69 6f 6e 2e 0a 20  ex protection.. 
1f00: 20 2a 2a 20 54 68 65 20 6e 46 72 65 65 53 6c 6f   ** The nFreeSlo
1f10: 74 20 61 6e 64 20 70 46 72 65 65 20 76 61 6c 75  t and pFree valu
1f20: 65 73 20 64 6f 20 72 65 71 75 69 72 65 20 6d 75  es do require mu
1f30: 74 65 78 20 70 72 6f 74 65 63 74 69 6f 6e 2e 0a  tex protection..
1f40: 20 20 2a 2f 0a 20 20 69 6e 74 20 69 73 49 6e 69    */.  int isIni
1f50: 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t;              
1f60: 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66        /* True if
1f70: 20 69 6e 69 74 69 61 6c 69 7a 65 64 20 2a 2f 0a   initialized */.
1f80: 20 20 69 6e 74 20 73 7a 53 6c 6f 74 3b 20 20 20    int szSlot;   
1f90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1fa0: 20 2f 2a 20 53 69 7a 65 20 6f 66 20 65 61 63 68   /* Size of each
1fb0: 20 66 72 65 65 20 73 6c 6f 74 20 2a 2f 0a 20 20   free slot */.  
1fc0: 69 6e 74 20 6e 53 6c 6f 74 3b 20 20 20 20 20 20  int nSlot;      
1fd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1fe0: 2a 20 54 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  * The number of 
1ff0: 70 63 61 63 68 65 20 73 6c 6f 74 73 20 2a 2f 0a  pcache slots */.
2000: 20 20 69 6e 74 20 6e 52 65 73 65 72 76 65 3b 20    int nReserve; 
2010: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2020: 20 2f 2a 20 54 72 79 20 74 6f 20 6b 65 65 70 20   /* Try to keep 
2030: 6e 46 72 65 65 53 6c 6f 74 20 61 62 6f 76 65 20  nFreeSlot above 
2040: 74 68 69 73 20 2a 2f 0a 20 20 76 6f 69 64 20 2a  this */.  void *
2050: 70 53 74 61 72 74 2c 20 2a 70 45 6e 64 3b 20 20  pStart, *pEnd;  
2060: 20 20 20 20 20 20 20 20 20 2f 2a 20 42 6f 75 6e           /* Boun
2070: 64 73 20 6f 66 20 70 61 67 65 63 61 63 68 65 20  ds of pagecache 
2080: 6d 61 6c 6c 6f 63 20 72 61 6e 67 65 20 2a 2f 0a  malloc range */.
2090: 20 20 2f 2a 20 41 62 6f 76 65 20 72 65 71 75 69    /* Above requi
20a0: 72 65 73 20 6e 6f 20 6d 75 74 65 78 2e 20 20 55  res no mutex.  U
20b0: 73 65 20 6d 75 74 65 78 20 62 65 6c 6f 77 20 66  se mutex below f
20c0: 6f 72 20 76 61 72 69 61 62 6c 65 20 74 68 61 74  or variable that
20d0: 20 66 6f 6c 6c 6f 77 2e 20 2a 2f 0a 20 20 73 71   follow. */.  sq
20e0: 6c 69 74 65 33 5f 6d 75 74 65 78 20 2a 6d 75 74  lite3_mutex *mut
20f0: 65 78 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ex;          /* 
2100: 4d 75 74 65 78 20 66 6f 72 20 61 63 63 65 73 73  Mutex for access
2110: 69 6e 67 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e  ing the followin
2120: 67 3a 20 2a 2f 0a 20 20 69 6e 74 20 6e 46 72 65  g: */.  int nFre
2130: 65 53 6c 6f 74 3b 20 20 20 20 20 20 20 20 20 20  eSlot;          
2140: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
2150: 20 6f 66 20 75 6e 75 73 65 64 20 70 63 61 63 68   of unused pcach
2160: 65 20 73 6c 6f 74 73 20 2a 2f 0a 20 20 50 67 46  e slots */.  PgF
2170: 72 65 65 73 6c 6f 74 20 2a 70 46 72 65 65 3b 20  reeslot *pFree; 
2180: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46              /* F
2190: 72 65 65 20 70 61 67 65 20 62 6c 6f 63 6b 73 20  ree page blocks 
21a0: 2a 2f 0a 20 20 2f 2a 20 54 68 65 20 66 6f 6c 6c  */.  /* The foll
21b0: 6f 77 69 6e 67 20 76 61 6c 75 65 20 72 65 71 75  owing value requ
21c0: 69 72 65 73 20 61 20 6d 75 74 65 78 20 74 6f 20  ires a mutex to 
21d0: 63 68 61 6e 67 65 2e 20 20 57 65 20 73 6b 69 70  change.  We skip
21e0: 20 74 68 65 20 6d 75 74 65 78 20 6f 6e 0a 20 20   the mutex on.  
21f0: 2a 2a 20 72 65 61 64 69 6e 67 20 62 65 63 61 75  ** reading becau
2200: 73 65 20 28 31 29 20 6d 6f 73 74 20 70 6c 61 74  se (1) most plat
2210: 66 6f 72 6d 73 20 72 65 61 64 20 61 20 33 32 2d  forms read a 32-
2220: 62 69 74 20 69 6e 74 65 67 65 72 20 61 74 6f 6d  bit integer atom
2230: 69 63 61 6c 6c 79 20 61 6e 64 0a 20 20 2a 2a 20  ically and.  ** 
2240: 28 32 29 20 65 76 65 6e 20 69 66 20 61 6e 20 69  (2) even if an i
2250: 6e 63 6f 72 72 65 63 74 20 76 61 6c 75 65 20 69  ncorrect value i
2260: 73 20 72 65 61 64 2c 20 6e 6f 20 67 72 65 61 74  s read, no great
2270: 20 68 61 72 6d 20 69 73 20 64 6f 6e 65 20 73 69   harm is done si
2280: 6e 63 65 20 74 68 69 73 0a 20 20 2a 2a 20 69 73  nce this.  ** is
2290: 20 72 65 61 6c 6c 79 20 6a 75 73 74 20 61 6e 20   really just an 
22a0: 6f 70 74 69 6d 69 7a 61 74 69 6f 6e 2e 20 2a 2f  optimization. */
22b0: 0a 20 20 69 6e 74 20 62 55 6e 64 65 72 50 72 65  .  int bUnderPre
22c0: 73 73 75 72 65 3b 20 20 20 20 20 20 20 20 20 20  ssure;          
22d0: 20 20 2f 2a 20 54 72 75 65 20 69 66 20 6c 6f 77    /* True if low
22e0: 20 6f 6e 20 50 41 47 45 43 41 43 48 45 20 6d 65   on PAGECACHE me
22f0: 6d 6f 72 79 20 2a 2f 0a 7d 20 70 63 61 63 68 65  mory */.} pcache
2300: 31 5f 67 3b 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c 20  1_g;../*.** All 
2310: 63 6f 64 65 20 69 6e 20 74 68 69 73 20 66 69 6c  code in this fil
2320: 65 20 73 68 6f 75 6c 64 20 61 63 63 65 73 73 20  e should access 
2330: 74 68 65 20 67 6c 6f 62 61 6c 20 73 74 72 75 63  the global struc
2340: 74 75 72 65 20 61 62 6f 76 65 20 76 69 61 20 74  ture above via t
2350: 68 65 0a 2a 2a 20 61 6c 69 61 73 20 22 70 63 61  he.** alias "pca
2360: 63 68 65 31 22 2e 20 54 68 69 73 20 65 6e 73 75  che1". This ensu
2370: 72 65 73 20 74 68 61 74 20 74 68 65 20 57 53 44  res that the WSD
2380: 20 65 6d 75 6c 61 74 69 6f 6e 20 69 73 20 75 73   emulation is us
2390: 65 64 20 77 68 65 6e 0a 2a 2a 20 63 6f 6d 70 69  ed when.** compi
23a0: 6c 69 6e 67 20 66 6f 72 20 73 79 73 74 65 6d 73  ling for systems
23b0: 20 74 68 61 74 20 64 6f 20 6e 6f 74 20 73 75 70   that do not sup
23c0: 70 6f 72 74 20 72 65 61 6c 20 57 53 44 2e 0a 2a  port real WSD..*
23d0: 2f 0a 23 64 65 66 69 6e 65 20 70 63 61 63 68 65  /.#define pcache
23e0: 31 20 28 47 4c 4f 42 41 4c 28 73 74 72 75 63 74  1 (GLOBAL(struct
23f0: 20 50 43 61 63 68 65 47 6c 6f 62 61 6c 2c 20 70   PCacheGlobal, p
2400: 63 61 63 68 65 31 5f 67 29 29 0a 0a 2f 2a 0a 2a  cache1_g))../*.*
2410: 2a 20 57 68 65 6e 20 61 20 50 67 48 64 72 31 20  * When a PgHdr1 
2420: 73 74 72 75 63 74 75 72 65 20 69 73 20 61 6c 6c  structure is all
2430: 6f 63 61 74 65 64 2c 20 74 68 65 20 61 73 73 6f  ocated, the asso
2440: 63 69 61 74 65 64 20 50 43 61 63 68 65 31 2e 73  ciated PCache1.s
2450: 7a 50 61 67 65 0a 2a 2a 20 62 79 74 65 73 20 6f  zPage.** bytes o
2460: 66 20 64 61 74 61 20 61 72 65 20 6c 6f 63 61 74  f data are locat
2470: 65 64 20 64 69 72 65 63 74 6c 79 20 62 65 66 6f  ed directly befo
2480: 72 65 20 69 74 20 69 6e 20 6d 65 6d 6f 72 79 20  re it in memory 
2490: 28 69 2e 65 2e 20 74 68 65 20 74 6f 74 61 6c 0a  (i.e. the total.
24a0: 2a 2a 20 73 69 7a 65 20 6f 66 20 74 68 65 20 61  ** size of the a
24b0: 6c 6c 6f 63 61 74 69 6f 6e 20 69 73 20 73 69 7a  llocation is siz
24c0: 65 6f 66 28 50 67 48 64 72 31 29 2b 50 43 61 63  eof(PgHdr1)+PCac
24d0: 68 65 31 2e 73 7a 50 61 67 65 20 62 79 74 65 29  he1.szPage byte)
24e0: 2e 20 54 68 65 0a 2a 2a 20 50 47 48 44 52 31 5f  . The.** PGHDR1_
24f0: 54 4f 5f 50 41 47 45 28 29 20 6d 61 63 72 6f 20  TO_PAGE() macro 
2500: 74 61 6b 65 73 20 61 20 70 6f 69 6e 74 65 72 20  takes a pointer 
2510: 74 6f 20 61 20 50 67 48 64 72 31 20 73 74 72 75  to a PgHdr1 stru
2520: 63 74 75 72 65 20 61 73 0a 2a 2a 20 61 6e 20 61  cture as.** an a
2530: 72 67 75 6d 65 6e 74 20 61 6e 64 20 72 65 74 75  rgument and retu
2540: 72 6e 73 20 61 20 70 6f 69 6e 74 65 72 20 74 6f  rns a pointer to
2550: 20 74 68 65 20 61 73 73 6f 63 69 61 74 65 64 20   the associated 
2560: 62 6c 6f 63 6b 20 6f 66 20 73 7a 50 61 67 65 0a  block of szPage.
2570: 2a 2a 20 62 79 74 65 73 2e 20 54 68 65 20 50 41  ** bytes. The PA
2580: 47 45 5f 54 4f 5f 50 47 48 44 52 31 28 29 20 6d  GE_TO_PGHDR1() m
2590: 61 63 72 6f 20 64 6f 65 73 20 74 68 65 20 6f 70  acro does the op
25a0: 70 6f 73 69 74 65 3a 20 69 74 73 20 61 72 67 75  posite: its argu
25b0: 6d 65 6e 74 20 69 73 0a 2a 2a 20 61 20 70 6f 69  ment is.** a poi
25c0: 6e 74 65 72 20 74 6f 20 61 20 62 6c 6f 63 6b 20  nter to a block 
25d0: 6f 66 20 73 7a 50 61 67 65 20 62 79 74 65 73 20  of szPage bytes 
25e0: 6f 66 20 64 61 74 61 20 61 6e 64 20 74 68 65 20  of data and the 
25f0: 72 65 74 75 72 6e 20 76 61 6c 75 65 20 69 73 0a  return value is.
2600: 2a 2a 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20  ** a pointer to 
2610: 74 68 65 20 61 73 73 6f 63 69 61 74 65 64 20 50  the associated P
2620: 67 48 64 72 31 20 73 74 72 75 63 74 75 72 65 2e  gHdr1 structure.
2630: 0a 2a 2a 0a 2a 2a 20 20 20 61 73 73 65 72 74 28  .**.**   assert(
2640: 20 50 47 48 44 52 31 5f 54 4f 5f 50 41 47 45 28   PGHDR1_TO_PAGE(
2650: 50 41 47 45 5f 54 4f 5f 50 47 48 44 52 31 28 70  PAGE_TO_PGHDR1(p
2660: 43 61 63 68 65 2c 20 58 29 29 3d 3d 58 20 29 3b  Cache, X))==X );
2670: 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 50 47 48 44  .*/.#define PGHD
2680: 52 31 5f 54 4f 5f 50 41 47 45 28 70 29 20 20 20  R1_TO_PAGE(p)   
2690: 20 28 76 6f 69 64 2a 29 28 28 28 63 68 61 72 2a   (void*)(((char*
26a0: 29 70 29 20 2d 20 70 2d 3e 70 43 61 63 68 65 2d  )p) - p->pCache-
26b0: 3e 73 7a 50 61 67 65 29 0a 23 64 65 66 69 6e 65  >szPage).#define
26c0: 20 50 41 47 45 5f 54 4f 5f 50 47 48 44 52 31 28   PAGE_TO_PGHDR1(
26d0: 63 2c 20 70 29 20 28 50 67 48 64 72 31 2a 29 28  c, p) (PgHdr1*)(
26e0: 28 28 63 68 61 72 2a 29 70 29 20 2b 20 63 2d 3e  ((char*)p) + c->
26f0: 73 7a 50 61 67 65 29 0a 0a 2f 2a 0a 2a 2a 20 42  szPage)../*.** B
2700: 6c 6f 63 6b 73 20 75 73 65 64 20 62 79 20 74 68  locks used by th
2710: 65 20 53 51 4c 49 54 45 5f 50 41 47 45 43 41 43  e SQLITE_PAGECAC
2720: 48 45 5f 42 4c 4f 43 4b 41 4c 4c 4f 43 20 62 6c  HE_BLOCKALLOC bl
2730: 6f 63 6b 73 20 74 6f 20 73 74 6f 72 65 2f 72 65  ocks to store/re
2740: 74 72 69 65 76 65 20 0a 2a 2a 20 61 20 50 47 72  trieve .** a PGr
2750: 6f 75 70 42 6c 6f 63 6b 20 70 6f 69 6e 74 65 72  oupBlock pointer
2760: 20 62 61 73 65 64 20 6f 6e 20 61 20 70 6f 69 6e   based on a poin
2770: 74 65 72 20 74 6f 20 61 20 70 61 67 65 20 62 75  ter to a page bu
2780: 66 66 65 72 2e 20 0a 2a 2f 0a 23 64 65 66 69 6e  ffer. .*/.#defin
2790: 65 20 50 41 47 45 5f 53 45 54 5f 42 4c 4f 43 4b  e PAGE_SET_BLOCK
27a0: 50 54 52 28 70 43 61 63 68 65 2c 20 70 50 67 2c  PTR(pCache, pPg,
27b0: 20 70 42 6c 6f 63 6b 29 20 5c 0a 20 20 28 20 2a   pBlock) \.  ( *
27c0: 28 50 47 72 6f 75 70 42 6c 6f 63 6b 20 2a 2a 29  (PGroupBlock **)
27d0: 26 28 28 28 75 38 2a 29 70 50 67 29 5b 73 69 7a  &(((u8*)pPg)[siz
27e0: 65 6f 66 28 50 67 48 64 72 31 29 20 2b 20 70 43  eof(PgHdr1) + pC
27f0: 61 63 68 65 2d 3e 73 7a 50 61 67 65 5d 29 20 3d  ache->szPage]) =
2800: 20 70 42 6c 6f 63 6b 20 29 0a 0a 23 64 65 66 69   pBlock )..#defi
2810: 6e 65 20 50 41 47 45 5f 47 45 54 5f 42 4c 4f 43  ne PAGE_GET_BLOC
2820: 4b 50 54 52 28 70 43 61 63 68 65 2c 20 70 50 67  KPTR(pCache, pPg
2830: 29 20 5c 0a 20 20 28 20 2a 28 50 47 72 6f 75 70  ) \.  ( *(PGroup
2840: 42 6c 6f 63 6b 20 2a 2a 29 26 28 28 28 75 38 2a  Block **)&(((u8*
2850: 29 70 50 67 29 5b 73 69 7a 65 6f 66 28 50 67 48  )pPg)[sizeof(PgH
2860: 64 72 31 29 20 2b 20 70 43 61 63 68 65 2d 3e 73  dr1) + pCache->s
2870: 7a 50 61 67 65 5d 29 20 29 0a 0a 0a 2f 2a 0a 2a  zPage]) ).../*.*
2880: 2a 20 4d 61 63 72 6f 73 20 74 6f 20 65 6e 74 65  * Macros to ente
2890: 72 20 61 6e 64 20 6c 65 61 76 65 20 74 68 65 20  r and leave the 
28a0: 50 43 61 63 68 65 20 4c 52 55 20 6d 75 74 65 78  PCache LRU mutex
28b0: 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 70 63 61  ..*/.#define pca
28c0: 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 58  che1EnterMutex(X
28d0: 29 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f  ) sqlite3_mutex_
28e0: 65 6e 74 65 72 28 28 58 29 2d 3e 6d 75 74 65 78  enter((X)->mutex
28f0: 29 0a 23 64 65 66 69 6e 65 20 70 63 61 63 68 65  ).#define pcache
2900: 31 4c 65 61 76 65 4d 75 74 65 78 28 58 29 20 73  1LeaveMutex(X) s
2910: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61  qlite3_mutex_lea
2920: 76 65 28 28 58 29 2d 3e 6d 75 74 65 78 29 0a 0a  ve((X)->mutex)..
2930: 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  /***************
2940: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2950: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2960: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2970: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f  ***************/
2980: 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 20 50 61 67 65 20  ./******** Page 
2990: 41 6c 6c 6f 63 61 74 69 6f 6e 2f 53 51 4c 49 54  Allocation/SQLIT
29a0: 45 5f 43 4f 4e 46 49 47 5f 50 43 41 43 48 45 20  E_CONFIG_PCACHE 
29b0: 52 65 6c 61 74 65 64 20 46 75 6e 63 74 69 6f 6e  Related Function
29c0: 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  s **************
29d0: 2f 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75  /../*.** This fu
29e0: 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64  nction is called
29f0: 20 64 75 72 69 6e 67 20 69 6e 69 74 69 61 6c 69   during initiali
2a00: 7a 61 74 69 6f 6e 20 69 66 20 61 20 73 74 61 74  zation if a stat
2a10: 69 63 20 62 75 66 66 65 72 20 69 73 20 0a 2a 2a  ic buffer is .**
2a20: 20 73 75 70 70 6c 69 65 64 20 74 6f 20 75 73 65   supplied to use
2a30: 20 66 6f 72 20 74 68 65 20 70 61 67 65 2d 63 61   for the page-ca
2a40: 63 68 65 20 62 79 20 70 61 73 73 69 6e 67 20 74  che by passing t
2a50: 68 65 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47  he SQLITE_CONFIG
2a60: 5f 50 41 47 45 43 41 43 48 45 0a 2a 2a 20 76 65  _PAGECACHE.** ve
2a70: 72 62 20 74 6f 20 73 71 6c 69 74 65 33 5f 63 6f  rb to sqlite3_co
2a80: 6e 66 69 67 28 29 2e 20 50 61 72 61 6d 65 74 65  nfig(). Paramete
2a90: 72 20 70 42 75 66 20 70 6f 69 6e 74 73 20 74 6f  r pBuf points to
2aa0: 20 61 6e 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 6c   an allocation l
2ab0: 61 72 67 65 0a 2a 2a 20 65 6e 6f 75 67 68 20 74  arge.** enough t
2ac0: 6f 20 63 6f 6e 74 61 69 6e 20 27 6e 27 20 62 75  o contain 'n' bu
2ad0: 66 66 65 72 73 20 6f 66 20 27 73 7a 27 20 62 79  ffers of 'sz' by
2ae0: 74 65 73 20 65 61 63 68 2e 0a 2a 2a 0a 2a 2a 20  tes each..**.** 
2af0: 54 68 69 73 20 72 6f 75 74 69 6e 65 20 69 73 20  This routine is 
2b00: 63 61 6c 6c 65 64 20 66 72 6f 6d 20 73 71 6c 69  called from sqli
2b10: 74 65 33 5f 69 6e 69 74 69 61 6c 69 7a 65 28 29  te3_initialize()
2b20: 20 61 6e 64 20 73 6f 20 69 74 20 69 73 20 67 75   and so it is gu
2b30: 61 72 61 6e 74 65 65 64 0a 2a 2a 20 74 6f 20 62  aranteed.** to b
2b40: 65 20 73 65 72 69 61 6c 69 7a 65 64 20 61 6c 72  e serialized alr
2b50: 65 61 64 79 2e 20 20 54 68 65 72 65 20 69 73 20  eady.  There is 
2b60: 6e 6f 20 6e 65 65 64 20 66 6f 72 20 66 75 72 74  no need for furt
2b70: 68 65 72 20 6d 75 74 65 78 69 6e 67 2e 0a 2a 2f  her mutexing..*/
2b80: 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 43 61  .void sqlite3PCa
2b90: 63 68 65 42 75 66 66 65 72 53 65 74 75 70 28 76  cheBufferSetup(v
2ba0: 6f 69 64 20 2a 70 42 75 66 2c 20 69 6e 74 20 73  oid *pBuf, int s
2bb0: 7a 2c 20 69 6e 74 20 6e 29 7b 0a 20 20 69 66 28  z, int n){.  if(
2bc0: 20 70 63 61 63 68 65 31 2e 69 73 49 6e 69 74 20   pcache1.isInit 
2bd0: 29 7b 0a 20 20 20 20 50 67 46 72 65 65 73 6c 6f  ){.    PgFreeslo
2be0: 74 20 2a 70 3b 0a 20 20 20 20 73 7a 20 3d 20 52  t *p;.    sz = R
2bf0: 4f 55 4e 44 44 4f 57 4e 38 28 73 7a 29 3b 0a 20  OUNDDOWN8(sz);. 
2c00: 20 20 20 70 63 61 63 68 65 31 2e 73 7a 53 6c 6f     pcache1.szSlo
2c10: 74 20 3d 20 73 7a 3b 0a 20 20 20 20 70 63 61 63  t = sz;.    pcac
2c20: 68 65 31 2e 6e 53 6c 6f 74 20 3d 20 70 63 61 63  he1.nSlot = pcac
2c30: 68 65 31 2e 6e 46 72 65 65 53 6c 6f 74 20 3d 20  he1.nFreeSlot = 
2c40: 6e 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 6e  n;.    pcache1.n
2c50: 52 65 73 65 72 76 65 20 3d 20 6e 3e 39 30 20 3f  Reserve = n>90 ?
2c60: 20 31 30 20 3a 20 28 6e 2f 31 30 20 2b 20 31 29   10 : (n/10 + 1)
2c70: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 70 53  ;.    pcache1.pS
2c80: 74 61 72 74 20 3d 20 70 42 75 66 3b 0a 20 20 20  tart = pBuf;.   
2c90: 20 70 63 61 63 68 65 31 2e 70 46 72 65 65 20 3d   pcache1.pFree =
2ca0: 20 30 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e   0;.    pcache1.
2cb0: 62 55 6e 64 65 72 50 72 65 73 73 75 72 65 20 3d  bUnderPressure =
2cc0: 20 30 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 6e   0;.    while( n
2cd0: 2d 2d 20 29 7b 0a 20 20 20 20 20 20 70 20 3d 20  -- ){.      p = 
2ce0: 28 50 67 46 72 65 65 73 6c 6f 74 2a 29 70 42 75  (PgFreeslot*)pBu
2cf0: 66 3b 0a 20 20 20 20 20 20 70 2d 3e 70 4e 65 78  f;.      p->pNex
2d00: 74 20 3d 20 70 63 61 63 68 65 31 2e 70 46 72 65  t = pcache1.pFre
2d10: 65 3b 0a 20 20 20 20 20 20 70 63 61 63 68 65 31  e;.      pcache1
2d20: 2e 70 46 72 65 65 20 3d 20 70 3b 0a 20 20 20 20  .pFree = p;.    
2d30: 20 20 70 42 75 66 20 3d 20 28 76 6f 69 64 2a 29    pBuf = (void*)
2d40: 26 28 28 63 68 61 72 2a 29 70 42 75 66 29 5b 73  &((char*)pBuf)[s
2d50: 7a 5d 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 63  z];.    }.    pc
2d60: 61 63 68 65 31 2e 70 45 6e 64 20 3d 20 70 42 75  ache1.pEnd = pBu
2d70: 66 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  f;.  }.}../*.** 
2d80: 4d 61 6c 6c 6f 63 20 66 75 6e 63 74 69 6f 6e 20  Malloc function 
2d90: 75 73 65 64 20 77 69 74 68 69 6e 20 74 68 69 73  used within this
2da0: 20 66 69 6c 65 20 74 6f 20 61 6c 6c 6f 63 61 74   file to allocat
2db0: 65 20 73 70 61 63 65 20 66 72 6f 6d 20 74 68 65  e space from the
2dc0: 20 62 75 66 66 65 72 0a 2a 2a 20 63 6f 6e 66 69   buffer.** confi
2dd0: 67 75 72 65 64 20 75 73 69 6e 67 20 73 71 6c 69  gured using sqli
2de0: 74 65 33 5f 63 6f 6e 66 69 67 28 53 51 4c 49 54  te3_config(SQLIT
2df0: 45 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41 43  E_CONFIG_PAGECAC
2e00: 48 45 29 20 6f 70 74 69 6f 6e 2e 20 49 66 20 6e  HE) option. If n
2e10: 6f 20 0a 2a 2a 20 73 75 63 68 20 62 75 66 66 65  o .** such buffe
2e20: 72 20 65 78 69 73 74 73 20 6f 72 20 74 68 65 72  r exists or ther
2e30: 65 20 69 73 20 6e 6f 20 73 70 61 63 65 20 6c 65  e is no space le
2e40: 66 74 20 69 6e 20 69 74 2c 20 74 68 69 73 20 66  ft in it, this f
2e50: 75 6e 63 74 69 6f 6e 20 66 61 6c 6c 73 20 0a 2a  unction falls .*
2e60: 2a 20 62 61 63 6b 20 74 6f 20 73 71 6c 69 74 65  * back to sqlite
2e70: 33 4d 61 6c 6c 6f 63 28 29 2e 0a 2a 2a 0a 2a 2a  3Malloc()..**.**
2e80: 20 4d 75 6c 74 69 70 6c 65 20 74 68 72 65 61 64   Multiple thread
2e90: 73 20 63 61 6e 20 72 75 6e 20 74 68 69 73 20 72  s can run this r
2ea0: 6f 75 74 69 6e 65 20 61 74 20 74 68 65 20 73 61  outine at the sa
2eb0: 6d 65 20 74 69 6d 65 2e 20 20 47 6c 6f 62 61 6c  me time.  Global
2ec0: 20 76 61 72 69 61 62 6c 65 73 0a 2a 2a 20 69 6e   variables.** in
2ed0: 20 70 63 61 63 68 65 31 20 6e 65 65 64 20 74 6f   pcache1 need to
2ee0: 20 62 65 20 70 72 6f 74 65 63 74 65 64 20 76 69   be protected vi
2ef0: 61 20 6d 75 74 65 78 2e 0a 2a 2f 0a 73 74 61 74  a mutex..*/.stat
2f00: 69 63 20 76 6f 69 64 20 2a 70 63 61 63 68 65 31  ic void *pcache1
2f10: 41 6c 6c 6f 63 28 69 6e 74 20 6e 42 79 74 65 29  Alloc(int nByte)
2f20: 7b 0a 20 20 76 6f 69 64 20 2a 70 20 3d 20 30 3b  {.  void *p = 0;
2f30: 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74  .  assert( sqlit
2f40: 65 33 5f 6d 75 74 65 78 5f 6e 6f 74 68 65 6c 64  e3_mutex_notheld
2f50: 28 70 63 61 63 68 65 31 2e 67 72 70 2e 6d 75 74  (pcache1.grp.mut
2f60: 65 78 29 20 29 3b 0a 20 20 73 71 6c 69 74 65 33  ex) );.  sqlite3
2f70: 53 74 61 74 75 73 53 65 74 28 53 51 4c 49 54 45  StatusSet(SQLITE
2f80: 5f 53 54 41 54 55 53 5f 50 41 47 45 43 41 43 48  _STATUS_PAGECACH
2f90: 45 5f 53 49 5a 45 2c 20 6e 42 79 74 65 29 3b 0a  E_SIZE, nByte);.
2fa0: 20 20 69 66 28 20 6e 42 79 74 65 3c 3d 70 63 61    if( nByte<=pca
2fb0: 63 68 65 31 2e 73 7a 53 6c 6f 74 20 29 7b 0a 20  che1.szSlot ){. 
2fc0: 20 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78     sqlite3_mutex
2fd0: 5f 65 6e 74 65 72 28 70 63 61 63 68 65 31 2e 6d  _enter(pcache1.m
2fe0: 75 74 65 78 29 3b 0a 20 20 20 20 70 20 3d 20 28  utex);.    p = (
2ff0: 50 67 48 64 72 31 20 2a 29 70 63 61 63 68 65 31  PgHdr1 *)pcache1
3000: 2e 70 46 72 65 65 3b 0a 20 20 20 20 69 66 28 20  .pFree;.    if( 
3010: 70 20 29 7b 0a 20 20 20 20 20 20 70 63 61 63 68  p ){.      pcach
3020: 65 31 2e 70 46 72 65 65 20 3d 20 70 63 61 63 68  e1.pFree = pcach
3030: 65 31 2e 70 46 72 65 65 2d 3e 70 4e 65 78 74 3b  e1.pFree->pNext;
3040: 0a 20 20 20 20 20 20 70 63 61 63 68 65 31 2e 6e  .      pcache1.n
3050: 46 72 65 65 53 6c 6f 74 2d 2d 3b 0a 20 20 20 20  FreeSlot--;.    
3060: 20 20 70 63 61 63 68 65 31 2e 62 55 6e 64 65 72    pcache1.bUnder
3070: 50 72 65 73 73 75 72 65 20 3d 20 70 63 61 63 68  Pressure = pcach
3080: 65 31 2e 6e 46 72 65 65 53 6c 6f 74 3c 70 63 61  e1.nFreeSlot<pca
3090: 63 68 65 31 2e 6e 52 65 73 65 72 76 65 3b 0a 20  che1.nReserve;. 
30a0: 20 20 20 20 20 61 73 73 65 72 74 28 20 70 63 61       assert( pca
30b0: 63 68 65 31 2e 6e 46 72 65 65 53 6c 6f 74 3e 3d  che1.nFreeSlot>=
30c0: 30 20 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74  0 );.      sqlit
30d0: 65 33 53 74 61 74 75 73 41 64 64 28 53 51 4c 49  e3StatusAdd(SQLI
30e0: 54 45 5f 53 54 41 54 55 53 5f 50 41 47 45 43 41  TE_STATUS_PAGECA
30f0: 43 48 45 5f 55 53 45 44 2c 20 31 29 3b 0a 20 20  CHE_USED, 1);.  
3100: 20 20 7d 0a 20 20 20 20 73 71 6c 69 74 65 33 5f    }.    sqlite3_
3110: 6d 75 74 65 78 5f 6c 65 61 76 65 28 70 63 61 63  mutex_leave(pcac
3120: 68 65 31 2e 6d 75 74 65 78 29 3b 0a 20 20 7d 0a  he1.mutex);.  }.
3130: 20 20 69 66 28 20 70 3d 3d 30 20 29 7b 0a 20 20    if( p==0 ){.  
3140: 20 20 2f 2a 20 4d 65 6d 6f 72 79 20 69 73 20 6e    /* Memory is n
3150: 6f 74 20 61 76 61 69 6c 61 62 6c 65 20 69 6e 20  ot available in 
3160: 74 68 65 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49  the SQLITE_CONFI
3170: 47 5f 50 41 47 45 43 41 43 48 45 20 70 6f 6f 6c  G_PAGECACHE pool
3180: 2e 20 20 47 65 74 0a 20 20 20 20 2a 2a 20 69 74  .  Get.    ** it
3190: 20 66 72 6f 6d 20 73 71 6c 69 74 65 33 4d 61 6c   from sqlite3Mal
31a0: 6c 6f 63 20 69 6e 73 74 65 61 64 2e 0a 20 20 20  loc instead..   
31b0: 20 2a 2f 0a 20 20 20 20 70 20 3d 20 73 71 6c 69   */.    p = sqli
31c0: 74 65 33 4d 61 6c 6c 6f 63 28 6e 42 79 74 65 29  te3Malloc(nByte)
31d0: 3b 0a 20 20 20 20 69 66 28 20 70 20 29 7b 0a 20  ;.    if( p ){. 
31e0: 20 20 20 20 20 69 6e 74 20 73 7a 20 3d 20 73 71       int sz = sq
31f0: 6c 69 74 65 33 4d 61 6c 6c 6f 63 53 69 7a 65 28  lite3MallocSize(
3200: 70 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65  p);.      sqlite
3210: 33 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28 70 63  3_mutex_enter(pc
3220: 61 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a 20 20  ache1.mutex);.  
3230: 20 20 20 20 73 71 6c 69 74 65 33 53 74 61 74 75      sqlite3Statu
3240: 73 41 64 64 28 53 51 4c 49 54 45 5f 53 54 41 54  sAdd(SQLITE_STAT
3250: 55 53 5f 50 41 47 45 43 41 43 48 45 5f 4f 56 45  US_PAGECACHE_OVE
3260: 52 46 4c 4f 57 2c 20 73 7a 29 3b 0a 20 20 20 20  RFLOW, sz);.    
3270: 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f    sqlite3_mutex_
3280: 6c 65 61 76 65 28 70 63 61 63 68 65 31 2e 6d 75  leave(pcache1.mu
3290: 74 65 78 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20  tex);.    }.    
32a0: 73 71 6c 69 74 65 33 4d 65 6d 64 65 62 75 67 53  sqlite3MemdebugS
32b0: 65 74 54 79 70 65 28 70 2c 20 4d 45 4d 54 59 50  etType(p, MEMTYP
32c0: 45 5f 50 43 41 43 48 45 29 3b 0a 20 20 7d 0a 20  E_PCACHE);.  }. 
32d0: 20 72 65 74 75 72 6e 20 70 3b 0a 7d 0a 0a 2f 2a   return p;.}../*
32e0: 0a 2a 2a 20 46 72 65 65 20 61 6e 20 61 6c 6c 6f  .** Free an allo
32f0: 63 61 74 65 64 20 62 75 66 66 65 72 20 6f 62 74  cated buffer obt
3300: 61 69 6e 65 64 20 66 72 6f 6d 20 70 63 61 63 68  ained from pcach
3310: 65 31 41 6c 6c 6f 63 28 29 2e 0a 2a 2f 0a 73 74  e1Alloc()..*/.st
3320: 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65  atic void pcache
3330: 31 46 72 65 65 28 76 6f 69 64 20 2a 70 29 7b 0a  1Free(void *p){.
3340: 20 20 69 66 28 20 70 3d 3d 30 20 29 20 72 65 74    if( p==0 ) ret
3350: 75 72 6e 3b 0a 20 20 69 66 28 20 70 3e 3d 70 63  urn;.  if( p>=pc
3360: 61 63 68 65 31 2e 70 53 74 61 72 74 20 26 26 20  ache1.pStart && 
3370: 70 3c 70 63 61 63 68 65 31 2e 70 45 6e 64 20 29  p<pcache1.pEnd )
3380: 7b 0a 20 20 20 20 50 67 46 72 65 65 73 6c 6f 74  {.    PgFreeslot
3390: 20 2a 70 53 6c 6f 74 3b 0a 20 20 20 20 73 71 6c   *pSlot;.    sql
33a0: 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e 74 65 72  ite3_mutex_enter
33b0: 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29 3b  (pcache1.mutex);
33c0: 0a 20 20 20 20 73 71 6c 69 74 65 33 53 74 61 74  .    sqlite3Stat
33d0: 75 73 41 64 64 28 53 51 4c 49 54 45 5f 53 54 41  usAdd(SQLITE_STA
33e0: 54 55 53 5f 50 41 47 45 43 41 43 48 45 5f 55 53  TUS_PAGECACHE_US
33f0: 45 44 2c 20 2d 31 29 3b 0a 20 20 20 20 70 53 6c  ED, -1);.    pSl
3400: 6f 74 20 3d 20 28 50 67 46 72 65 65 73 6c 6f 74  ot = (PgFreeslot
3410: 2a 29 70 3b 0a 20 20 20 20 70 53 6c 6f 74 2d 3e  *)p;.    pSlot->
3420: 70 4e 65 78 74 20 3d 20 70 63 61 63 68 65 31 2e  pNext = pcache1.
3430: 70 46 72 65 65 3b 0a 20 20 20 20 70 63 61 63 68  pFree;.    pcach
3440: 65 31 2e 70 46 72 65 65 20 3d 20 70 53 6c 6f 74  e1.pFree = pSlot
3450: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 6e 46  ;.    pcache1.nF
3460: 72 65 65 53 6c 6f 74 2b 2b 3b 0a 20 20 20 20 70  reeSlot++;.    p
3470: 63 61 63 68 65 31 2e 62 55 6e 64 65 72 50 72 65  cache1.bUnderPre
3480: 73 73 75 72 65 20 3d 20 70 63 61 63 68 65 31 2e  ssure = pcache1.
3490: 6e 46 72 65 65 53 6c 6f 74 3c 70 63 61 63 68 65  nFreeSlot<pcache
34a0: 31 2e 6e 52 65 73 65 72 76 65 3b 0a 20 20 20 20  1.nReserve;.    
34b0: 61 73 73 65 72 74 28 20 70 63 61 63 68 65 31 2e  assert( pcache1.
34c0: 6e 46 72 65 65 53 6c 6f 74 3c 3d 70 63 61 63 68  nFreeSlot<=pcach
34d0: 65 31 2e 6e 53 6c 6f 74 20 29 3b 0a 20 20 20 20  e1.nSlot );.    
34e0: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6c 65  sqlite3_mutex_le
34f0: 61 76 65 28 70 63 61 63 68 65 31 2e 6d 75 74 65  ave(pcache1.mute
3500: 78 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  x);.  }else{.   
3510: 20 69 6e 74 20 69 53 69 7a 65 3b 0a 20 20 20 20   int iSize;.    
3520: 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 4d  assert( sqlite3M
3530: 65 6d 64 65 62 75 67 48 61 73 54 79 70 65 28 70  emdebugHasType(p
3540: 2c 20 4d 45 4d 54 59 50 45 5f 50 43 41 43 48 45  , MEMTYPE_PCACHE
3550: 29 20 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  ) );.    sqlite3
3560: 4d 65 6d 64 65 62 75 67 53 65 74 54 79 70 65 28  MemdebugSetType(
3570: 70 2c 20 4d 45 4d 54 59 50 45 5f 48 45 41 50 29  p, MEMTYPE_HEAP)
3580: 3b 0a 20 20 20 20 69 53 69 7a 65 20 3d 20 73 71  ;.    iSize = sq
3590: 6c 69 74 65 33 4d 61 6c 6c 6f 63 53 69 7a 65 28  lite3MallocSize(
35a0: 70 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  p);.    sqlite3_
35b0: 6d 75 74 65 78 5f 65 6e 74 65 72 28 70 63 61 63  mutex_enter(pcac
35c0: 68 65 31 2e 6d 75 74 65 78 29 3b 0a 20 20 20 20  he1.mutex);.    
35d0: 73 71 6c 69 74 65 33 53 74 61 74 75 73 41 64 64  sqlite3StatusAdd
35e0: 28 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50  (SQLITE_STATUS_P
35f0: 41 47 45 43 41 43 48 45 5f 4f 56 45 52 46 4c 4f  AGECACHE_OVERFLO
3600: 57 2c 20 2d 69 53 69 7a 65 29 3b 0a 20 20 20 20  W, -iSize);.    
3610: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6c 65  sqlite3_mutex_le
3620: 61 76 65 28 70 63 61 63 68 65 31 2e 6d 75 74 65  ave(pcache1.mute
3630: 78 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  x);.    sqlite3_
3640: 66 72 65 65 28 70 29 3b 0a 20 20 7d 0a 7d 0a 0a  free(p);.  }.}..
3650: 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 45 4e  #ifdef SQLITE_EN
3660: 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41  ABLE_MEMORY_MANA
3670: 47 45 4d 45 4e 54 0a 2f 2a 0a 2a 2a 20 52 65 74  GEMENT./*.** Ret
3680: 75 72 6e 20 74 68 65 20 73 69 7a 65 20 6f 66 20  urn the size of 
3690: 61 20 70 63 61 63 68 65 20 61 6c 6c 6f 63 61 74  a pcache allocat
36a0: 69 6f 6e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ion.*/.static in
36b0: 74 20 70 63 61 63 68 65 31 4d 65 6d 53 69 7a 65  t pcache1MemSize
36c0: 28 76 6f 69 64 20 2a 70 29 7b 0a 20 20 69 66 28  (void *p){.  if(
36d0: 20 70 3e 3d 70 63 61 63 68 65 31 2e 70 53 74 61   p>=pcache1.pSta
36e0: 72 74 20 26 26 20 70 3c 70 63 61 63 68 65 31 2e  rt && p<pcache1.
36f0: 70 45 6e 64 20 29 7b 0a 20 20 20 20 72 65 74 75  pEnd ){.    retu
3700: 72 6e 20 70 63 61 63 68 65 31 2e 73 7a 53 6c 6f  rn pcache1.szSlo
3710: 74 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  t;.  }else{.    
3720: 69 6e 74 20 69 53 69 7a 65 3b 0a 20 20 20 20 61  int iSize;.    a
3730: 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 4d 65  ssert( sqlite3Me
3740: 6d 64 65 62 75 67 48 61 73 54 79 70 65 28 70 2c  mdebugHasType(p,
3750: 20 4d 45 4d 54 59 50 45 5f 50 43 41 43 48 45 29   MEMTYPE_PCACHE)
3760: 20 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 4d   );.    sqlite3M
3770: 65 6d 64 65 62 75 67 53 65 74 54 79 70 65 28 70  emdebugSetType(p
3780: 2c 20 4d 45 4d 54 59 50 45 5f 48 45 41 50 29 3b  , MEMTYPE_HEAP);
3790: 0a 20 20 20 20 69 53 69 7a 65 20 3d 20 73 71 6c  .    iSize = sql
37a0: 69 74 65 33 4d 61 6c 6c 6f 63 53 69 7a 65 28 70  ite3MallocSize(p
37b0: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 4d 65  );.    sqlite3Me
37c0: 6d 64 65 62 75 67 53 65 74 54 79 70 65 28 70 2c  mdebugSetType(p,
37d0: 20 4d 45 4d 54 59 50 45 5f 50 43 41 43 48 45 29   MEMTYPE_PCACHE)
37e0: 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 69 53 69  ;.    return iSi
37f0: 7a 65 3b 0a 20 20 7d 0a 7d 0a 23 65 6e 64 69 66  ze;.  }.}.#endif
3800: 20 2f 2a 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c   /* SQLITE_ENABL
3810: 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d  E_MEMORY_MANAGEM
3820: 45 4e 54 20 2a 2f 0a 0a 23 69 66 64 65 66 20 53  ENT */..#ifdef S
3830: 51 4c 49 54 45 5f 50 41 47 45 43 41 43 48 45 5f  QLITE_PAGECACHE_
3840: 42 4c 4f 43 4b 41 4c 4c 4f 43 0a 2f 2a 0a 2a 2a  BLOCKALLOC./*.**
3850: 20 54 68 65 20 62 6c 6f 63 6b 20 70 42 6c 6f 63   The block pBloc
3860: 6b 20 62 65 6c 6f 6e 67 73 20 74 6f 20 6c 69 73  k belongs to lis
3870: 74 20 70 4c 69 73 74 20 62 75 74 20 69 73 20 6e  t pList but is n
3880: 6f 74 20 63 75 72 72 65 6e 74 6c 79 20 6c 69 6e  ot currently lin
3890: 6b 65 64 20 69 6e 2e 0a 2a 2a 20 49 6e 73 65 72  ked in..** Inser
38a0: 74 20 69 74 20 69 6e 74 6f 20 74 68 65 20 73 74  t it into the st
38b0: 61 72 74 20 6f 66 20 74 68 65 20 6c 69 73 74 2e  art of the list.
38c0: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
38d0: 61 64 64 42 6c 6f 63 6b 54 6f 4c 69 73 74 28 50  addBlockToList(P
38e0: 47 72 6f 75 70 42 6c 6f 63 6b 4c 69 73 74 20 2a  GroupBlockList *
38f0: 70 4c 69 73 74 2c 20 50 47 72 6f 75 70 42 6c 6f  pList, PGroupBlo
3900: 63 6b 20 2a 70 42 6c 6f 63 6b 29 7b 0a 20 20 70  ck *pBlock){.  p
3910: 42 6c 6f 63 6b 2d 3e 70 50 72 65 76 20 3d 20 30  Block->pPrev = 0
3920: 3b 0a 20 20 70 42 6c 6f 63 6b 2d 3e 70 4e 65 78  ;.  pBlock->pNex
3930: 74 20 3d 20 70 4c 69 73 74 2d 3e 70 46 69 72 73  t = pList->pFirs
3940: 74 3b 0a 20 20 70 4c 69 73 74 2d 3e 70 46 69 72  t;.  pList->pFir
3950: 73 74 20 3d 20 70 42 6c 6f 63 6b 3b 0a 20 20 69  st = pBlock;.  i
3960: 66 28 20 70 42 6c 6f 63 6b 2d 3e 70 4e 65 78 74  f( pBlock->pNext
3970: 20 29 7b 0a 20 20 20 20 70 42 6c 6f 63 6b 2d 3e   ){.    pBlock->
3980: 70 4e 65 78 74 2d 3e 70 50 72 65 76 20 3d 20 70  pNext->pPrev = p
3990: 42 6c 6f 63 6b 3b 0a 20 20 7d 65 6c 73 65 7b 0a  Block;.  }else{.
39a0: 20 20 20 20 61 73 73 65 72 74 28 20 70 4c 69 73      assert( pLis
39b0: 74 2d 3e 70 4c 61 73 74 3d 3d 30 20 29 3b 0a 20  t->pLast==0 );. 
39c0: 20 20 20 70 4c 69 73 74 2d 3e 70 4c 61 73 74 20     pList->pLast 
39d0: 3d 20 70 42 6c 6f 63 6b 3b 0a 20 20 7d 0a 7d 0a  = pBlock;.  }.}.
39e0: 0a 2f 2a 0a 2a 2a 20 49 66 20 74 68 65 72 65 20  ./*.** If there 
39f0: 61 72 65 20 6e 6f 20 62 6c 6f 63 6b 73 20 69 6e  are no blocks in
3a00: 20 74 68 65 20 6c 69 73 74 20 68 65 61 64 65 64   the list headed
3a10: 20 62 79 20 70 4c 69 73 74 2c 20 72 65 6d 6f 76   by pList, remov
3a20: 65 20 70 4c 69 73 74 0a 2a 2a 20 66 72 6f 6d 20  e pList.** from 
3a30: 74 68 65 20 70 47 72 6f 75 70 2d 3e 70 42 6c 6f  the pGroup->pBlo
3a40: 63 6b 4c 69 73 74 20 6c 69 73 74 20 61 6e 64 20  ckList list and 
3a50: 66 72 65 65 20 69 74 20 77 69 74 68 20 73 71 6c  free it with sql
3a60: 69 74 65 33 5f 66 72 65 65 28 29 2e 0a 2a 2f 0a  ite3_free()..*/.
3a70: 73 74 61 74 69 63 20 76 6f 69 64 20 66 72 65 65  static void free
3a80: 4c 69 73 74 49 66 45 6d 70 74 79 28 50 47 72 6f  ListIfEmpty(PGro
3a90: 75 70 20 2a 70 47 72 6f 75 70 2c 20 50 47 72 6f  up *pGroup, PGro
3aa0: 75 70 42 6c 6f 63 6b 4c 69 73 74 20 2a 70 4c 69  upBlockList *pLi
3ab0: 73 74 29 7b 0a 20 20 61 73 73 65 72 74 28 20 73  st){.  assert( s
3ac0: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c  qlite3_mutex_hel
3ad0: 64 28 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78 29  d(pGroup->mutex)
3ae0: 20 29 3b 0a 20 20 69 66 28 20 70 4c 69 73 74 2d   );.  if( pList-
3af0: 3e 70 46 69 72 73 74 3d 3d 30 20 29 7b 0a 20 20  >pFirst==0 ){.  
3b00: 20 20 50 47 72 6f 75 70 42 6c 6f 63 6b 4c 69 73    PGroupBlockLis
3b10: 74 20 2a 2a 70 70 3b 0a 20 20 20 20 66 6f 72 28  t **pp;.    for(
3b20: 70 70 3d 26 70 47 72 6f 75 70 2d 3e 70 42 6c 6f  pp=&pGroup->pBlo
3b30: 63 6b 4c 69 73 74 3b 20 2a 70 70 21 3d 70 4c 69  ckList; *pp!=pLi
3b40: 73 74 3b 20 70 70 3d 26 28 2a 70 70 29 2d 3e 70  st; pp=&(*pp)->p
3b50: 4e 65 78 74 29 3b 0a 20 20 20 20 2a 70 70 20 3d  Next);.    *pp =
3b60: 20 28 2a 70 70 29 2d 3e 70 4e 65 78 74 3b 0a 20   (*pp)->pNext;. 
3b70: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
3b80: 70 4c 69 73 74 29 3b 0a 20 20 7d 0a 7d 0a 23 65  pList);.  }.}.#e
3b90: 6e 64 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f 50  ndif /* SQLITE_P
3ba0: 41 47 45 43 41 43 48 45 5f 42 4c 4f 43 4b 41 4c  AGECACHE_BLOCKAL
3bb0: 4c 4f 43 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 41 6c  LOC */../*.** Al
3bc0: 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 70 61 67  locate a new pag
3bd0: 65 20 6f 62 6a 65 63 74 20 69 6e 69 74 69 61 6c  e object initial
3be0: 6c 79 20 61 73 73 6f 63 69 61 74 65 64 20 77 69  ly associated wi
3bf0: 74 68 20 63 61 63 68 65 20 70 43 61 63 68 65 2e  th cache pCache.
3c00: 0a 2a 2f 0a 73 74 61 74 69 63 20 50 67 48 64 72  .*/.static PgHdr
3c10: 31 20 2a 70 63 61 63 68 65 31 41 6c 6c 6f 63 50  1 *pcache1AllocP
3c20: 61 67 65 28 50 43 61 63 68 65 31 20 2a 70 43 61  age(PCache1 *pCa
3c30: 63 68 65 29 7b 0a 20 20 69 6e 74 20 6e 42 79 74  che){.  int nByt
3c40: 65 20 3d 20 73 69 7a 65 6f 66 28 50 67 48 64 72  e = sizeof(PgHdr
3c50: 31 29 20 2b 20 70 43 61 63 68 65 2d 3e 73 7a 50  1) + pCache->szP
3c60: 61 67 65 3b 0a 20 20 76 6f 69 64 20 2a 70 50 67  age;.  void *pPg
3c70: 20 3d 20 30 3b 0a 20 20 50 67 48 64 72 31 20 2a   = 0;.  PgHdr1 *
3c80: 70 3b 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54  p;..#ifdef SQLIT
3c90: 45 5f 50 41 47 45 43 41 43 48 45 5f 42 4c 4f 43  E_PAGECACHE_BLOC
3ca0: 4b 41 4c 4c 4f 43 0a 20 20 50 47 72 6f 75 70 20  KALLOC.  PGroup 
3cb0: 2a 70 47 72 6f 75 70 20 3d 20 70 43 61 63 68 65  *pGroup = pCache
3cc0: 2d 3e 70 47 72 6f 75 70 3b 0a 20 20 50 47 72 6f  ->pGroup;.  PGro
3cd0: 75 70 42 6c 6f 63 6b 4c 69 73 74 20 2a 70 4c 69  upBlockList *pLi
3ce0: 73 74 3b 0a 20 20 50 47 72 6f 75 70 42 6c 6f 63  st;.  PGroupBloc
3cf0: 6b 20 2a 70 42 6c 6f 63 6b 3b 0a 20 20 69 6e 74  k *pBlock;.  int
3d00: 20 69 3b 0a 0a 20 20 6e 42 79 74 65 20 2b 3d 20   i;..  nByte += 
3d10: 73 69 7a 65 6f 66 28 50 47 72 6f 75 70 42 6c 6f  sizeof(PGroupBlo
3d20: 63 6b 4c 69 73 74 20 2a 29 3b 0a 20 20 6e 42 79  ckList *);.  nBy
3d30: 74 65 20 3d 20 52 4f 55 4e 44 38 28 6e 42 79 74  te = ROUND8(nByt
3d40: 65 29 3b 0a 0a 20 20 64 6f 7b 0a 20 20 20 20 66  e);..  do{.    f
3d50: 6f 72 28 70 4c 69 73 74 3d 70 47 72 6f 75 70 2d  or(pList=pGroup-
3d60: 3e 70 42 6c 6f 63 6b 4c 69 73 74 3b 20 70 4c 69  >pBlockList; pLi
3d70: 73 74 3b 20 70 4c 69 73 74 3d 70 4c 69 73 74 2d  st; pList=pList-
3d80: 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 20 20 69  >pNext){.      i
3d90: 66 28 20 70 4c 69 73 74 2d 3e 6e 42 79 74 65 3d  f( pList->nByte=
3da0: 3d 6e 42 79 74 65 20 29 20 62 72 65 61 6b 3b 0a  =nByte ) break;.
3db0: 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70 4c      }.    if( pL
3dc0: 69 73 74 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  ist==0 ){.      
3dd0: 50 47 72 6f 75 70 42 6c 6f 63 6b 4c 69 73 74 20  PGroupBlockList 
3de0: 2a 70 4e 65 77 3b 0a 20 20 20 20 20 20 70 63 61  *pNew;.      pca
3df0: 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 70  che1LeaveMutex(p
3e00: 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a  Cache->pGroup);.
3e10: 20 20 20 20 20 20 70 4e 65 77 20 3d 20 28 50 47        pNew = (PG
3e20: 72 6f 75 70 42 6c 6f 63 6b 4c 69 73 74 20 2a 29  roupBlockList *)
3e30: 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65 72  sqlite3MallocZer
3e40: 6f 28 73 69 7a 65 6f 66 28 50 47 72 6f 75 70 42  o(sizeof(PGroupB
3e50: 6c 6f 63 6b 4c 69 73 74 29 29 3b 0a 20 20 20 20  lockList));.    
3e60: 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75    pcache1EnterMu
3e70: 74 65 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f  tex(pCache->pGro
3e80: 75 70 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70  up);.      if( p
3e90: 4e 65 77 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  New==0 ){.      
3ea0: 20 20 2f 2a 20 6d 61 6c 6c 6f 63 28 29 20 66 61    /* malloc() fa
3eb0: 69 6c 75 72 65 2e 20 52 65 74 75 72 6e 20 65 61  ilure. Return ea
3ec0: 72 6c 79 2e 20 2a 2f 0a 20 20 20 20 20 20 20 20  rly. */.        
3ed0: 72 65 74 75 72 6e 20 30 3b 0a 20 20 20 20 20 20  return 0;.      
3ee0: 7d 0a 20 20 20 20 20 20 66 6f 72 28 70 4c 69 73  }.      for(pLis
3ef0: 74 3d 70 47 72 6f 75 70 2d 3e 70 42 6c 6f 63 6b  t=pGroup->pBlock
3f00: 4c 69 73 74 3b 20 70 4c 69 73 74 3b 20 70 4c 69  List; pList; pLi
3f10: 73 74 3d 70 4c 69 73 74 2d 3e 70 4e 65 78 74 29  st=pList->pNext)
3f20: 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 70 4c  {.        if( pL
3f30: 69 73 74 2d 3e 6e 42 79 74 65 3d 3d 6e 42 79 74  ist->nByte==nByt
3f40: 65 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20  e ) break;.     
3f50: 20 7d 0a 20 20 20 20 20 20 69 66 28 20 70 4c 69   }.      if( pLi
3f60: 73 74 20 29 7b 0a 20 20 20 20 20 20 20 20 73 71  st ){.        sq
3f70: 6c 69 74 65 33 5f 66 72 65 65 28 70 4e 65 77 29  lite3_free(pNew)
3f80: 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20  ;.      }else{. 
3f90: 20 20 20 20 20 20 20 70 4e 65 77 2d 3e 6e 42 79         pNew->nBy
3fa0: 74 65 20 3d 20 6e 42 79 74 65 3b 0a 20 20 20 20  te = nByte;.    
3fb0: 20 20 20 20 70 4e 65 77 2d 3e 70 4e 65 78 74 20      pNew->pNext 
3fc0: 3d 20 70 47 72 6f 75 70 2d 3e 70 42 6c 6f 63 6b  = pGroup->pBlock
3fd0: 4c 69 73 74 3b 0a 20 20 20 20 20 20 20 20 70 47  List;.        pG
3fe0: 72 6f 75 70 2d 3e 70 42 6c 6f 63 6b 4c 69 73 74  roup->pBlockList
3ff0: 20 3d 20 70 4e 65 77 3b 0a 20 20 20 20 20 20 20   = pNew;.       
4000: 20 70 4c 69 73 74 20 3d 20 70 4e 65 77 3b 0a 20   pList = pNew;. 
4010: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d       }.    }.  }
4020: 77 68 69 6c 65 28 20 70 4c 69 73 74 3d 3d 30 20  while( pList==0 
4030: 29 3b 0a 0a 20 20 70 42 6c 6f 63 6b 20 3d 20 70  );..  pBlock = p
4040: 4c 69 73 74 2d 3e 70 46 69 72 73 74 3b 0a 20 20  List->pFirst;.  
4050: 69 66 28 20 70 42 6c 6f 63 6b 3d 3d 30 20 7c 7c  if( pBlock==0 ||
4060: 20 70 42 6c 6f 63 6b 2d 3e 6d 55 73 65 64 3d 3d   pBlock->mUsed==
4070: 28 28 28 42 69 74 6d 61 73 6b 29 31 3c 3c 70 42  (((Bitmask)1<<pB
4080: 6c 6f 63 6b 2d 3e 6e 45 6e 74 72 79 29 2d 31 29  lock->nEntry)-1)
4090: 20 29 7b 0a 20 20 20 20 69 6e 74 20 73 7a 3b 0a   ){.    int sz;.
40a0: 0a 20 20 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65  .    /* Allocate
40b0: 20 61 20 6e 65 77 20 62 6c 6f 63 6b 2e 20 54 72   a new block. Tr
40c0: 79 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 65 6e  y to allocate en
40d0: 6f 75 67 68 20 73 70 61 63 65 20 66 6f 72 20 74  ough space for t
40e0: 68 65 20 50 47 72 6f 75 70 42 6c 6f 63 6b 0a 20  he PGroupBlock. 
40f0: 20 20 20 2a 2a 20 73 74 72 75 63 74 75 72 65 20     ** structure 
4100: 61 6e 64 20 4d 49 4e 45 4e 54 52 59 20 61 6c 6c  and MINENTRY all
4110: 6f 63 61 74 69 6f 6e 73 20 6f 66 20 6e 42 79 74  ocations of nByt
4120: 65 20 62 79 74 65 73 20 65 61 63 68 2e 20 49 66  e bytes each. If
4130: 20 74 68 65 20 0a 20 20 20 20 2a 2a 20 61 6c 6c   the .    ** all
4140: 6f 63 61 74 6f 72 20 72 65 74 75 72 6e 73 20 6d  ocator returns m
4150: 6f 72 65 20 6d 65 6d 6f 72 79 20 74 68 61 6e 20  ore memory than 
4160: 72 65 71 75 65 73 74 65 64 2c 20 74 68 65 6e 20  requested, then 
4170: 6d 6f 72 65 20 74 68 61 6e 20 4d 49 4e 45 4e 54  more than MINENT
4180: 52 59 20 0a 20 20 20 20 2a 2a 20 61 6c 6c 6f 63  RY .    ** alloc
4190: 61 74 69 6f 6e 73 20 6d 61 79 20 66 69 74 20 69  ations may fit i
41a0: 6e 20 69 74 2e 20 2a 2f 0a 20 20 20 20 70 63 61  n it. */.    pca
41b0: 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 70  che1LeaveMutex(p
41c0: 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a  Cache->pGroup);.
41d0: 20 20 20 20 73 7a 20 3d 20 73 69 7a 65 6f 66 28      sz = sizeof(
41e0: 50 47 72 6f 75 70 42 6c 6f 63 6b 29 20 2b 20 50  PGroupBlock) + P
41f0: 41 47 45 43 41 43 48 45 5f 42 4c 4f 43 4b 41 4c  AGECACHE_BLOCKAL
4200: 4c 4f 43 5f 4d 49 4e 45 4e 54 52 59 20 2a 20 6e  LOC_MINENTRY * n
4210: 42 79 74 65 3b 0a 20 20 20 20 70 42 6c 6f 63 6b  Byte;.    pBlock
4220: 20 3d 20 28 50 47 72 6f 75 70 42 6c 6f 63 6b 20   = (PGroupBlock 
4230: 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28  *)sqlite3Malloc(
4240: 73 7a 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31  sz);.    pcache1
4250: 45 6e 74 65 72 4d 75 74 65 78 28 70 43 61 63 68  EnterMutex(pCach
4260: 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 0a 20 20 20  e->pGroup);..   
4270: 20 69 66 28 20 21 70 42 6c 6f 63 6b 20 29 7b 0a   if( !pBlock ){.
4280: 20 20 20 20 20 20 66 72 65 65 4c 69 73 74 49 66        freeListIf
4290: 45 6d 70 74 79 28 70 47 72 6f 75 70 2c 20 70 4c  Empty(pGroup, pL
42a0: 69 73 74 29 3b 0a 20 20 20 20 20 20 72 65 74 75  ist);.      retu
42b0: 72 6e 20 30 3b 0a 20 20 20 20 7d 0a 20 20 20 20  rn 0;.    }.    
42c0: 70 42 6c 6f 63 6b 2d 3e 6e 45 6e 74 72 79 20 3d  pBlock->nEntry =
42d0: 20 28 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 53   (sqlite3MallocS
42e0: 69 7a 65 28 70 42 6c 6f 63 6b 29 20 2d 20 73 69  ize(pBlock) - si
42f0: 7a 65 6f 66 28 50 47 72 6f 75 70 42 6c 6f 63 6b  zeof(PGroupBlock
4300: 29 29 20 2f 20 6e 42 79 74 65 3b 0a 20 20 20 20  )) / nByte;.    
4310: 69 66 28 20 70 42 6c 6f 63 6b 2d 3e 6e 45 6e 74  if( pBlock->nEnt
4320: 72 79 3e 3d 42 4d 53 20 29 7b 0a 20 20 20 20 20  ry>=BMS ){.     
4330: 20 70 42 6c 6f 63 6b 2d 3e 6e 45 6e 74 72 79 20   pBlock->nEntry 
4340: 3d 20 42 4d 53 2d 31 3b 0a 20 20 20 20 7d 0a 20  = BMS-1;.    }. 
4350: 20 20 20 70 42 6c 6f 63 6b 2d 3e 70 4c 69 73 74     pBlock->pList
4360: 20 3d 20 70 4c 69 73 74 3b 0a 20 20 20 20 70 42   = pList;.    pB
4370: 6c 6f 63 6b 2d 3e 6d 55 73 65 64 20 3d 20 30 3b  lock->mUsed = 0;
4380: 0a 20 20 20 20 70 42 6c 6f 63 6b 2d 3e 61 44 61  .    pBlock->aDa
4390: 74 61 20 3d 20 28 75 38 20 2a 29 26 70 42 6c 6f  ta = (u8 *)&pBlo
43a0: 63 6b 5b 31 5d 3b 0a 20 20 20 20 61 64 64 42 6c  ck[1];.    addBl
43b0: 6f 63 6b 54 6f 4c 69 73 74 28 70 4c 69 73 74 2c  ockToList(pList,
43c0: 20 70 42 6c 6f 63 6b 29 3b 0a 0a 20 20 20 20 73   pBlock);..    s
43d0: 7a 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f  z = sqlite3Mallo
43e0: 63 53 69 7a 65 28 70 42 6c 6f 63 6b 29 3b 0a 20  cSize(pBlock);. 
43f0: 20 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78     sqlite3_mutex
4400: 5f 65 6e 74 65 72 28 70 63 61 63 68 65 31 2e 6d  _enter(pcache1.m
4410: 75 74 65 78 29 3b 0a 20 20 20 20 73 71 6c 69 74  utex);.    sqlit
4420: 65 33 53 74 61 74 75 73 41 64 64 28 53 51 4c 49  e3StatusAdd(SQLI
4430: 54 45 5f 53 54 41 54 55 53 5f 50 41 47 45 43 41  TE_STATUS_PAGECA
4440: 43 48 45 5f 4f 56 45 52 46 4c 4f 57 2c 20 73 7a  CHE_OVERFLOW, sz
4450: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 6d  );.    sqlite3_m
4460: 75 74 65 78 5f 6c 65 61 76 65 28 70 63 61 63 68  utex_leave(pcach
4470: 65 31 2e 6d 75 74 65 78 29 3b 0a 20 20 7d 0a 0a  e1.mutex);.  }..
4480: 20 20 66 6f 72 28 69 3d 30 3b 20 70 50 67 3d 3d    for(i=0; pPg==
4490: 30 20 26 26 20 41 4c 57 41 59 53 28 69 3c 70 42  0 && ALWAYS(i<pB
44a0: 6c 6f 63 6b 2d 3e 6e 45 6e 74 72 79 29 3b 20 69  lock->nEntry); i
44b0: 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 30 3d 3d  ++){.    if( 0==
44c0: 28 70 42 6c 6f 63 6b 2d 3e 6d 55 73 65 64 20 26  (pBlock->mUsed &
44d0: 20 28 28 42 69 74 6d 61 73 6b 29 31 3c 3c 69 29   ((Bitmask)1<<i)
44e0: 29 20 29 7b 0a 20 20 20 20 20 20 70 42 6c 6f 63  ) ){.      pBloc
44f0: 6b 2d 3e 6d 55 73 65 64 20 7c 3d 20 28 28 42 69  k->mUsed |= ((Bi
4500: 74 6d 61 73 6b 29 31 3c 3c 69 29 3b 0a 20 20 20  tmask)1<<i);.   
4510: 20 20 20 70 50 67 20 3d 20 28 76 6f 69 64 20 2a     pPg = (void *
4520: 29 26 70 42 6c 6f 63 6b 2d 3e 61 44 61 74 61 5b  )&pBlock->aData[
4530: 70 4c 69 73 74 2d 3e 6e 42 79 74 65 20 2a 20 69  pList->nByte * i
4540: 5d 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 61  ];.    }.  }.  a
4550: 73 73 65 72 74 28 20 70 50 67 20 29 3b 0a 20 20  ssert( pPg );.  
4560: 50 41 47 45 5f 53 45 54 5f 42 4c 4f 43 4b 50 54  PAGE_SET_BLOCKPT
4570: 52 28 70 43 61 63 68 65 2c 20 70 50 67 2c 20 70  R(pCache, pPg, p
4580: 42 6c 6f 63 6b 29 3b 0a 0a 20 20 2f 2a 20 49 66  Block);..  /* If
4590: 20 74 68 65 20 62 6c 6f 63 6b 20 69 73 20 6e 6f   the block is no
45a0: 77 20 66 75 6c 6c 2c 20 73 68 69 66 74 20 69 74  w full, shift it
45b0: 20 74 6f 20 74 68 65 20 65 6e 64 20 6f 66 20 74   to the end of t
45c0: 68 65 20 6c 69 73 74 20 2a 2f 0a 20 20 69 66 28  he list */.  if(
45d0: 20 70 42 6c 6f 63 6b 2d 3e 6d 55 73 65 64 3d 3d   pBlock->mUsed==
45e0: 28 28 28 42 69 74 6d 61 73 6b 29 31 3c 3c 70 42  (((Bitmask)1<<pB
45f0: 6c 6f 63 6b 2d 3e 6e 45 6e 74 72 79 29 2d 31 29  lock->nEntry)-1)
4600: 20 26 26 20 70 4c 69 73 74 2d 3e 70 4c 61 73 74   && pList->pLast
4610: 21 3d 70 42 6c 6f 63 6b 20 29 7b 0a 20 20 20 20  !=pBlock ){.    
4620: 61 73 73 65 72 74 28 20 70 4c 69 73 74 2d 3e 70  assert( pList->p
4630: 46 69 72 73 74 3d 3d 70 42 6c 6f 63 6b 20 29 3b  First==pBlock );
4640: 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 42 6c  .    assert( pBl
4650: 6f 63 6b 2d 3e 70 50 72 65 76 3d 3d 30 20 29 3b  ock->pPrev==0 );
4660: 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 4c 69  .    assert( pLi
4670: 73 74 2d 3e 70 4c 61 73 74 2d 3e 70 4e 65 78 74  st->pLast->pNext
4680: 3d 3d 30 20 29 3b 0a 20 20 20 20 70 4c 69 73 74  ==0 );.    pList
4690: 2d 3e 70 46 69 72 73 74 20 3d 20 70 42 6c 6f 63  ->pFirst = pBloc
46a0: 6b 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 70 4c  k->pNext;.    pL
46b0: 69 73 74 2d 3e 70 46 69 72 73 74 2d 3e 70 50 72  ist->pFirst->pPr
46c0: 65 76 20 3d 20 30 3b 0a 20 20 20 20 70 42 6c 6f  ev = 0;.    pBlo
46d0: 63 6b 2d 3e 70 50 72 65 76 20 3d 20 70 4c 69 73  ck->pPrev = pLis
46e0: 74 2d 3e 70 4c 61 73 74 3b 0a 20 20 20 20 70 42  t->pLast;.    pB
46f0: 6c 6f 63 6b 2d 3e 70 4e 65 78 74 20 3d 20 30 3b  lock->pNext = 0;
4700: 0a 20 20 20 20 70 4c 69 73 74 2d 3e 70 4c 61 73  .    pList->pLas
4710: 74 2d 3e 70 4e 65 78 74 20 3d 20 70 42 6c 6f 63  t->pNext = pBloc
4720: 6b 3b 0a 20 20 20 20 70 4c 69 73 74 2d 3e 70 4c  k;.    pList->pL
4730: 61 73 74 20 3d 20 70 42 6c 6f 63 6b 3b 0a 20 20  ast = pBlock;.  
4740: 7d 0a 23 65 6c 73 65 0a 20 20 2f 2a 20 54 68 65  }.#else.  /* The
4750: 20 67 72 6f 75 70 20 6d 75 74 65 78 20 6d 75 73   group mutex mus
4760: 74 20 62 65 20 72 65 6c 65 61 73 65 64 20 62 65  t be released be
4770: 66 6f 72 65 20 70 63 61 63 68 65 31 41 6c 6c 6f  fore pcache1Allo
4780: 63 28 29 20 69 73 20 63 61 6c 6c 65 64 2e 20 54  c() is called. T
4790: 68 69 73 0a 20 20 2a 2a 20 69 73 20 62 65 63 61  his.  ** is beca
47a0: 75 73 65 20 69 74 20 6d 61 79 20 63 61 6c 6c 20  use it may call 
47b0: 73 71 6c 69 74 65 33 5f 72 65 6c 65 61 73 65 5f  sqlite3_release_
47c0: 6d 65 6d 6f 72 79 28 29 2c 20 77 68 69 63 68 20  memory(), which 
47d0: 61 73 73 75 6d 65 73 20 74 68 61 74 20 0a 20 20  assumes that .  
47e0: 2a 2a 20 74 68 69 73 20 6d 75 74 65 78 20 69 73  ** this mutex is
47f0: 20 6e 6f 74 20 68 65 6c 64 2e 20 2a 2f 0a 20 20   not held. */.  
4800: 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f  assert( sqlite3_
4810: 6d 75 74 65 78 5f 68 65 6c 64 28 70 43 61 63 68  mutex_held(pCach
4820: 65 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78  e->pGroup->mutex
4830: 29 20 29 3b 0a 20 20 70 63 61 63 68 65 31 4c 65  ) );.  pcache1Le
4840: 61 76 65 4d 75 74 65 78 28 70 43 61 63 68 65 2d  aveMutex(pCache-
4850: 3e 70 47 72 6f 75 70 29 3b 0a 20 20 70 50 67 20  >pGroup);.  pPg 
4860: 3d 20 70 63 61 63 68 65 31 41 6c 6c 6f 63 28 6e  = pcache1Alloc(n
4870: 42 79 74 65 29 3b 0a 20 20 70 63 61 63 68 65 31  Byte);.  pcache1
4880: 45 6e 74 65 72 4d 75 74 65 78 28 70 43 61 63 68  EnterMutex(pCach
4890: 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 23 65 6e 64  e->pGroup);.#end
48a0: 69 66 0a 0a 20 20 69 66 28 20 70 50 67 20 29 7b  if..  if( pPg ){
48b0: 0a 20 20 20 20 70 20 3d 20 50 41 47 45 5f 54 4f  .    p = PAGE_TO
48c0: 5f 50 47 48 44 52 31 28 70 43 61 63 68 65 2c 20  _PGHDR1(pCache, 
48d0: 70 50 67 29 3b 0a 20 20 20 20 69 66 28 20 70 43  pPg);.    if( pC
48e0: 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65  ache->bPurgeable
48f0: 20 29 7b 0a 20 20 20 20 20 20 70 43 61 63 68 65   ){.      pCache
4900: 2d 3e 70 47 72 6f 75 70 2d 3e 6e 43 75 72 72 65  ->pGroup->nCurre
4910: 6e 74 50 61 67 65 2b 2b 3b 0a 20 20 20 20 7d 0a  ntPage++;.    }.
4920: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70 20 3d    }else{.    p =
4930: 20 30 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e   0;.  }.  return
4940: 20 70 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65   p;.}../*.** Fre
4950: 65 20 61 20 70 61 67 65 20 6f 62 6a 65 63 74 20  e a page object 
4960: 61 6c 6c 6f 63 61 74 65 64 20 62 79 20 70 63 61  allocated by pca
4970: 63 68 65 31 41 6c 6c 6f 63 50 61 67 65 28 29 2e  che1AllocPage().
4980: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 70 6f 69 6e 74  .**.** The point
4990: 65 72 20 69 73 20 61 6c 6c 6f 77 65 64 20 74 6f  er is allowed to
49a0: 20 62 65 20 4e 55 4c 4c 2c 20 77 68 69 63 68 20   be NULL, which 
49b0: 69 73 20 70 72 75 64 65 6e 74 2e 20 20 42 75 74  is prudent.  But
49c0: 20 69 74 20 74 75 72 6e 73 20 6f 75 74 0a 2a 2a   it turns out.**
49d0: 20 74 68 61 74 20 74 68 65 20 63 75 72 72 65 6e   that the curren
49e0: 74 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  t implementation
49f0: 20 68 61 70 70 65 6e 73 20 74 6f 20 6e 65 76 65   happens to neve
4a00: 72 20 63 61 6c 6c 20 74 68 69 73 20 72 6f 75 74  r call this rout
4a10: 69 6e 65 0a 2a 2a 20 77 69 74 68 20 61 20 4e 55  ine.** with a NU
4a20: 4c 4c 20 70 6f 69 6e 74 65 72 2c 20 73 6f 20 77  LL pointer, so w
4a30: 65 20 6d 61 72 6b 20 74 68 65 20 4e 55 4c 4c 20  e mark the NULL 
4a40: 74 65 73 74 20 77 69 74 68 20 41 4c 57 41 59 53  test with ALWAYS
4a50: 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ()..*/.static vo
4a60: 69 64 20 70 63 61 63 68 65 31 46 72 65 65 50 61  id pcache1FreePa
4a70: 67 65 28 50 67 48 64 72 31 20 2a 70 29 7b 0a 20  ge(PgHdr1 *p){. 
4a80: 20 69 66 28 20 41 4c 57 41 59 53 28 70 29 20 29   if( ALWAYS(p) )
4a90: 7b 0a 20 20 20 20 50 43 61 63 68 65 31 20 2a 70  {.    PCache1 *p
4aa0: 43 61 63 68 65 20 3d 20 70 2d 3e 70 43 61 63 68  Cache = p->pCach
4ab0: 65 3b 0a 20 20 20 20 76 6f 69 64 20 2a 70 50 67  e;.    void *pPg
4ac0: 20 3d 20 50 47 48 44 52 31 5f 54 4f 5f 50 41 47   = PGHDR1_TO_PAG
4ad0: 45 28 70 29 3b 0a 0a 23 69 66 64 65 66 20 53 51  E(p);..#ifdef SQ
4ae0: 4c 49 54 45 5f 50 41 47 45 43 41 43 48 45 5f 42  LITE_PAGECACHE_B
4af0: 4c 4f 43 4b 41 4c 4c 4f 43 0a 20 20 20 20 50 47  LOCKALLOC.    PG
4b00: 72 6f 75 70 42 6c 6f 63 6b 20 2a 70 42 6c 6f 63  roupBlock *pBloc
4b10: 6b 20 3d 20 50 41 47 45 5f 47 45 54 5f 42 4c 4f  k = PAGE_GET_BLO
4b20: 43 4b 50 54 52 28 70 43 61 63 68 65 2c 20 70 50  CKPTR(pCache, pP
4b30: 67 29 3b 0a 20 20 20 20 50 47 72 6f 75 70 42 6c  g);.    PGroupBl
4b40: 6f 63 6b 4c 69 73 74 20 2a 70 4c 69 73 74 20 3d  ockList *pList =
4b50: 20 70 42 6c 6f 63 6b 2d 3e 70 4c 69 73 74 3b 0a   pBlock->pList;.
4b60: 20 20 20 20 69 6e 74 20 69 20 3d 20 28 28 75 38      int i = ((u8
4b70: 20 2a 29 70 50 67 20 2d 20 70 42 6c 6f 63 6b 2d   *)pPg - pBlock-
4b80: 3e 61 44 61 74 61 29 20 2f 20 70 4c 69 73 74 2d  >aData) / pList-
4b90: 3e 6e 42 79 74 65 3b 0a 0a 20 20 20 20 61 73 73  >nByte;..    ass
4ba0: 65 72 74 28 20 70 50 67 3d 3d 28 76 6f 69 64 20  ert( pPg==(void 
4bb0: 2a 29 26 70 42 6c 6f 63 6b 2d 3e 61 44 61 74 61  *)&pBlock->aData
4bc0: 5b 69 2a 70 4c 69 73 74 2d 3e 6e 42 79 74 65 5d  [i*pList->nByte]
4bd0: 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20   );.    assert( 
4be0: 70 42 6c 6f 63 6b 2d 3e 6d 55 73 65 64 20 26 20  pBlock->mUsed & 
4bf0: 28 28 42 69 74 6d 61 73 6b 29 31 3c 3c 69 29 20  ((Bitmask)1<<i) 
4c00: 29 3b 0a 20 20 20 20 70 42 6c 6f 63 6b 2d 3e 6d  );.    pBlock->m
4c10: 55 73 65 64 20 26 3d 20 7e 28 28 42 69 74 6d 61  Used &= ~((Bitma
4c20: 73 6b 29 31 3c 3c 69 29 3b 0a 0a 20 20 20 20 2f  sk)1<<i);..    /
4c30: 2a 20 52 65 6d 6f 76 65 20 74 68 65 20 62 6c 6f  * Remove the blo
4c40: 63 6b 20 66 72 6f 6d 20 74 68 65 20 6c 69 73 74  ck from the list
4c50: 2e 20 49 66 20 69 74 20 69 73 20 63 6f 6d 70 6c  . If it is compl
4c60: 65 74 65 6c 79 20 65 6d 70 74 79 2c 20 66 72 65  etely empty, fre
4c70: 65 20 69 74 2e 0a 20 20 20 20 2a 2a 20 4f 72 20  e it..    ** Or 
4c80: 69 66 20 69 74 20 69 73 20 6e 6f 74 20 63 6f 6d  if it is not com
4c90: 70 6c 65 74 65 6c 79 20 65 6d 70 74 79 2c 20 72  pletely empty, r
4ca0: 65 2d 69 6e 73 65 72 74 20 69 74 20 61 74 20 74  e-insert it at t
4cb0: 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 65 0a  he start of the.
4cc0: 20 20 20 20 2a 2a 20 6c 69 73 74 2e 20 2a 2f 0a      ** list. */.
4cd0: 20 20 20 20 69 66 28 20 70 4c 69 73 74 2d 3e 70      if( pList->p
4ce0: 46 69 72 73 74 3d 3d 70 42 6c 6f 63 6b 20 29 7b  First==pBlock ){
4cf0: 0a 20 20 20 20 20 20 70 4c 69 73 74 2d 3e 70 46  .      pList->pF
4d00: 69 72 73 74 20 3d 20 70 42 6c 6f 63 6b 2d 3e 70  irst = pBlock->p
4d10: 4e 65 78 74 3b 0a 20 20 20 20 20 20 69 66 28 20  Next;.      if( 
4d20: 70 4c 69 73 74 2d 3e 70 46 69 72 73 74 20 29 20  pList->pFirst ) 
4d30: 70 4c 69 73 74 2d 3e 70 46 69 72 73 74 2d 3e 70  pList->pFirst->p
4d40: 50 72 65 76 20 3d 20 30 3b 0a 20 20 20 20 7d 65  Prev = 0;.    }e
4d50: 6c 73 65 7b 0a 20 20 20 20 20 20 70 42 6c 6f 63  lse{.      pBloc
4d60: 6b 2d 3e 70 50 72 65 76 2d 3e 70 4e 65 78 74 20  k->pPrev->pNext 
4d70: 3d 20 70 42 6c 6f 63 6b 2d 3e 70 4e 65 78 74 3b  = pBlock->pNext;
4d80: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70  .    }.    if( p
4d90: 4c 69 73 74 2d 3e 70 4c 61 73 74 3d 3d 70 42 6c  List->pLast==pBl
4da0: 6f 63 6b 20 29 7b 0a 20 20 20 20 20 20 70 4c 69  ock ){.      pLi
4db0: 73 74 2d 3e 70 4c 61 73 74 20 3d 20 70 42 6c 6f  st->pLast = pBlo
4dc0: 63 6b 2d 3e 70 50 72 65 76 3b 0a 20 20 20 20 20  ck->pPrev;.     
4dd0: 20 69 66 28 20 70 4c 69 73 74 2d 3e 70 4c 61 73   if( pList->pLas
4de0: 74 20 29 20 70 4c 69 73 74 2d 3e 70 4c 61 73 74  t ) pList->pLast
4df0: 2d 3e 70 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20  ->pNext = 0;.   
4e00: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 42   }else{.      pB
4e10: 6c 6f 63 6b 2d 3e 70 4e 65 78 74 2d 3e 70 50 72  lock->pNext->pPr
4e20: 65 76 20 3d 20 70 42 6c 6f 63 6b 2d 3e 70 50 72  ev = pBlock->pPr
4e30: 65 76 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69  ev;.    }..    i
4e40: 66 28 20 70 42 6c 6f 63 6b 2d 3e 6d 55 73 65 64  f( pBlock->mUsed
4e50: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 50 47 72  ==0 ){.      PGr
4e60: 6f 75 70 20 2a 70 47 72 6f 75 70 20 3d 20 70 2d  oup *pGroup = p-
4e70: 3e 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b  >pCache->pGroup;
4e80: 0a 0a 20 20 20 20 20 20 69 6e 74 20 73 7a 20 3d  ..      int sz =
4e90: 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 53 69   sqlite3MallocSi
4ea0: 7a 65 28 70 42 6c 6f 63 6b 29 3b 0a 20 20 20 20  ze(pBlock);.    
4eb0: 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f    sqlite3_mutex_
4ec0: 65 6e 74 65 72 28 70 63 61 63 68 65 31 2e 6d 75  enter(pcache1.mu
4ed0: 74 65 78 29 3b 0a 20 20 20 20 20 20 73 71 6c 69  tex);.      sqli
4ee0: 74 65 33 53 74 61 74 75 73 41 64 64 28 53 51 4c  te3StatusAdd(SQL
4ef0: 49 54 45 5f 53 54 41 54 55 53 5f 50 41 47 45 43  ITE_STATUS_PAGEC
4f00: 41 43 48 45 5f 4f 56 45 52 46 4c 4f 57 2c 20 2d  ACHE_OVERFLOW, -
4f10: 73 7a 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74  sz);.      sqlit
4f20: 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 70  e3_mutex_leave(p
4f30: 63 61 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a 20  cache1.mutex);. 
4f40: 20 20 20 20 20 66 72 65 65 4c 69 73 74 49 66 45       freeListIfE
4f50: 6d 70 74 79 28 70 47 72 6f 75 70 2c 20 70 4c 69  mpty(pGroup, pLi
4f60: 73 74 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74  st);.      sqlit
4f70: 65 33 5f 66 72 65 65 28 70 42 6c 6f 63 6b 29 3b  e3_free(pBlock);
4f80: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
4f90: 20 20 61 64 64 42 6c 6f 63 6b 54 6f 4c 69 73 74    addBlockToList
4fa0: 28 70 4c 69 73 74 2c 20 70 42 6c 6f 63 6b 29 3b  (pList, pBlock);
4fb0: 0a 20 20 20 20 7d 0a 23 65 6c 73 65 0a 20 20 20  .    }.#else.   
4fc0: 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33   assert( sqlite3
4fd0: 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 2d 3e 70  _mutex_held(p->p
4fe0: 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 2d 3e 6d  Cache->pGroup->m
4ff0: 75 74 65 78 29 20 29 3b 0a 20 20 20 20 70 63 61  utex) );.    pca
5000: 63 68 65 31 46 72 65 65 28 70 50 67 29 3b 0a 23  che1Free(pPg);.#
5010: 65 6e 64 69 66 0a 20 20 20 20 69 66 28 20 70 43  endif.    if( pC
5020: 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65  ache->bPurgeable
5030: 20 29 7b 0a 20 20 20 20 20 20 70 43 61 63 68 65   ){.      pCache
5040: 2d 3e 70 47 72 6f 75 70 2d 3e 6e 43 75 72 72 65  ->pGroup->nCurre
5050: 6e 74 50 61 67 65 2d 2d 3b 0a 20 20 20 20 7d 0a  ntPage--;.    }.
5060: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6c    }.}../*.** Mal
5070: 6c 6f 63 20 66 75 6e 63 74 69 6f 6e 20 75 73 65  loc function use
5080: 64 20 62 79 20 53 51 4c 69 74 65 20 74 6f 20 6f  d by SQLite to o
5090: 62 74 61 69 6e 20 73 70 61 63 65 20 66 72 6f 6d  btain space from
50a0: 20 74 68 65 20 62 75 66 66 65 72 20 63 6f 6e 66   the buffer conf
50b0: 69 67 75 72 65 64 0a 2a 2a 20 75 73 69 6e 67 20  igured.** using 
50c0: 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67 28 53  sqlite3_config(S
50d0: 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47  QLITE_CONFIG_PAG
50e0: 45 43 41 43 48 45 29 20 6f 70 74 69 6f 6e 2e 20  ECACHE) option. 
50f0: 49 66 20 6e 6f 20 73 75 63 68 20 62 75 66 66 65  If no such buffe
5100: 72 0a 2a 2a 20 65 78 69 73 74 73 2c 20 74 68 69  r.** exists, thi
5110: 73 20 66 75 6e 63 74 69 6f 6e 20 66 61 6c 6c 73  s function falls
5120: 20 62 61 63 6b 20 74 6f 20 73 71 6c 69 74 65 33   back to sqlite3
5130: 4d 61 6c 6c 6f 63 28 29 2e 0a 2a 2f 0a 76 6f 69  Malloc()..*/.voi
5140: 64 20 2a 73 71 6c 69 74 65 33 50 61 67 65 4d 61  d *sqlite3PageMa
5150: 6c 6c 6f 63 28 69 6e 74 20 73 7a 29 7b 0a 20 20  lloc(int sz){.  
5160: 72 65 74 75 72 6e 20 70 63 61 63 68 65 31 41 6c  return pcache1Al
5170: 6c 6f 63 28 73 7a 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  loc(sz);.}../*.*
5180: 2a 20 46 72 65 65 20 61 6e 20 61 6c 6c 6f 63 61  * Free an alloca
5190: 74 65 64 20 62 75 66 66 65 72 20 6f 62 74 61 69  ted buffer obtai
51a0: 6e 65 64 20 66 72 6f 6d 20 73 71 6c 69 74 65 33  ned from sqlite3
51b0: 50 61 67 65 4d 61 6c 6c 6f 63 28 29 2e 0a 2a 2f  PageMalloc()..*/
51c0: 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 61 67  .void sqlite3Pag
51d0: 65 46 72 65 65 28 76 6f 69 64 20 2a 70 29 7b 0a  eFree(void *p){.
51e0: 20 20 70 63 61 63 68 65 31 46 72 65 65 28 70 29    pcache1Free(p)
51f0: 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75  ;.}.../*.** Retu
5200: 72 6e 20 74 72 75 65 20 69 66 20 69 74 20 64 65  rn true if it de
5210: 73 69 72 61 62 6c 65 20 74 6f 20 61 76 6f 69 64  sirable to avoid
5220: 20 61 6c 6c 6f 63 61 74 69 6e 67 20 61 20 6e 65   allocating a ne
5230: 77 20 70 61 67 65 20 63 61 63 68 65 0a 2a 2a 20  w page cache.** 
5240: 65 6e 74 72 79 2e 0a 2a 2a 0a 2a 2a 20 49 66 20  entry..**.** If 
5250: 6d 65 6d 6f 72 79 20 77 61 73 20 61 6c 6c 6f 63  memory was alloc
5260: 61 74 65 64 20 73 70 65 63 69 66 69 63 61 6c 6c  ated specificall
5270: 79 20 74 6f 20 74 68 65 20 70 61 67 65 20 63 61  y to the page ca
5280: 63 68 65 20 75 73 69 6e 67 0a 2a 2a 20 53 51 4c  che using.** SQL
5290: 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43  ITE_CONFIG_PAGEC
52a0: 41 43 48 45 20 62 75 74 20 74 68 61 74 20 6d 65  ACHE but that me
52b0: 6d 6f 72 79 20 68 61 73 20 61 6c 6c 20 62 65 65  mory has all bee
52c0: 6e 20 75 73 65 64 2c 20 74 68 65 6e 0a 2a 2a 20  n used, then.** 
52d0: 69 74 20 69 73 20 64 65 73 69 72 61 62 6c 65 20  it is desirable 
52e0: 74 6f 20 61 76 6f 69 64 20 61 6c 6c 6f 63 61 74  to avoid allocat
52f0: 69 6e 67 20 61 20 6e 65 77 20 70 61 67 65 20 63  ing a new page c
5300: 61 63 68 65 20 65 6e 74 72 79 20 62 65 63 61 75  ache entry becau
5310: 73 65 0a 2a 2a 20 70 72 65 73 75 6d 61 62 6c 79  se.** presumably
5320: 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50   SQLITE_CONFIG_P
5330: 41 47 45 43 41 43 48 45 20 77 61 73 20 73 75 70  AGECACHE was sup
5340: 70 6f 73 65 20 74 6f 20 62 65 20 73 75 66 66 69  pose to be suffi
5350: 63 69 65 6e 74 0a 2a 2a 20 66 6f 72 20 61 6c 6c  cient.** for all
5360: 20 70 61 67 65 20 63 61 63 68 65 20 6e 65 65 64   page cache need
5370: 73 20 61 6e 64 20 77 65 20 73 68 6f 75 6c 64 20  s and we should 
5380: 6e 6f 74 20 6e 65 65 64 20 74 6f 20 73 70 69 6c  not need to spil
5390: 6c 20 74 68 65 0a 2a 2a 20 61 6c 6c 6f 63 61 74  l the.** allocat
53a0: 69 6f 6e 20 6f 6e 74 6f 20 74 68 65 20 68 65 61  ion onto the hea
53b0: 70 2e 0a 2a 2a 0a 2a 2a 20 4f 72 2c 20 74 68 65  p..**.** Or, the
53c0: 20 68 65 61 70 20 69 73 20 75 73 65 64 20 66 6f   heap is used fo
53d0: 72 20 61 6c 6c 20 70 61 67 65 20 63 61 63 68 65  r all page cache
53e0: 20 6d 65 6d 6f 72 79 20 70 75 74 20 74 68 65 20   memory put the 
53f0: 68 65 61 70 20 69 73 0a 2a 2a 20 75 6e 64 65 72  heap is.** under
5400: 20 6d 65 6d 6f 72 79 20 70 72 65 73 73 75 72 65   memory pressure
5410: 2c 20 74 68 65 6e 20 61 67 61 69 6e 20 69 74 20  , then again it 
5420: 69 73 20 64 65 73 69 72 61 62 6c 65 20 74 6f 20  is desirable to 
5430: 61 76 6f 69 64 0a 2a 2a 20 61 6c 6c 6f 63 61 74  avoid.** allocat
5440: 69 6e 67 20 61 20 6e 65 77 20 70 61 67 65 20 63  ing a new page c
5450: 61 63 68 65 20 65 6e 74 72 79 20 69 6e 20 6f 72  ache entry in or
5460: 64 65 72 20 74 6f 20 61 76 6f 69 64 20 73 74 72  der to avoid str
5470: 65 73 73 69 6e 67 0a 2a 2a 20 74 68 65 20 68 65  essing.** the he
5480: 61 70 20 65 76 65 6e 20 66 75 72 74 68 65 72 2e  ap even further.
5490: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 70  .*/.static int p
54a0: 63 61 63 68 65 31 55 6e 64 65 72 4d 65 6d 6f 72  cache1UnderMemor
54b0: 79 50 72 65 73 73 75 72 65 28 50 43 61 63 68 65  yPressure(PCache
54c0: 31 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 69 66  1 *pCache){.  if
54d0: 28 20 70 63 61 63 68 65 31 2e 6e 53 6c 6f 74 20  ( pcache1.nSlot 
54e0: 26 26 20 70 43 61 63 68 65 2d 3e 73 7a 50 61 67  && pCache->szPag
54f0: 65 3c 3d 70 63 61 63 68 65 31 2e 73 7a 53 6c 6f  e<=pcache1.szSlo
5500: 74 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  t ){.    return 
5510: 70 63 61 63 68 65 31 2e 62 55 6e 64 65 72 50 72  pcache1.bUnderPr
5520: 65 73 73 75 72 65 3b 0a 20 20 7d 65 6c 73 65 7b  essure;.  }else{
5530: 0a 20 20 20 20 72 65 74 75 72 6e 20 73 71 6c 69  .    return sqli
5540: 74 65 33 48 65 61 70 4e 65 61 72 6c 79 46 75 6c  te3HeapNearlyFul
5550: 6c 28 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 2a 2a  l();.  }.}../***
5560: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5570: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5580: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5590: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
55a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 2a  ***********/./**
55b0: 2a 2a 2a 2a 2a 2a 20 47 65 6e 65 72 61 6c 20 49  ****** General I
55c0: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 46 75  mplementation Fu
55d0: 6e 63 74 69 6f 6e 73 20 2a 2a 2a 2a 2a 2a 2a 2a  nctions ********
55e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
55f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f  ************/../
5600: 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69  *.** This functi
5610: 6f 6e 20 69 73 20 75 73 65 64 20 74 6f 20 72 65  on is used to re
5620: 73 69 7a 65 20 74 68 65 20 68 61 73 68 20 74 61  size the hash ta
5630: 62 6c 65 20 75 73 65 64 20 62 79 20 74 68 65 20  ble used by the 
5640: 63 61 63 68 65 20 70 61 73 73 65 64 0a 2a 2a 20  cache passed.** 
5650: 61 73 20 74 68 65 20 66 69 72 73 74 20 61 72 67  as the first arg
5660: 75 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65  ument..**.** The
5670: 20 50 43 61 63 68 65 20 6d 75 74 65 78 20 6d 75   PCache mutex mu
5680: 73 74 20 62 65 20 68 65 6c 64 20 77 68 65 6e 20  st be held when 
5690: 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73  this function is
56a0: 20 63 61 6c 6c 65 64 2e 0a 2a 2f 0a 73 74 61 74   called..*/.stat
56b0: 69 63 20 69 6e 74 20 70 63 61 63 68 65 31 52 65  ic int pcache1Re
56c0: 73 69 7a 65 48 61 73 68 28 50 43 61 63 68 65 31  sizeHash(PCache1
56d0: 20 2a 70 29 7b 0a 20 20 50 67 48 64 72 31 20 2a   *p){.  PgHdr1 *
56e0: 2a 61 70 4e 65 77 3b 0a 20 20 75 6e 73 69 67 6e  *apNew;.  unsign
56f0: 65 64 20 69 6e 74 20 6e 4e 65 77 3b 0a 20 20 75  ed int nNew;.  u
5700: 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 3b 0a 0a  nsigned int i;..
5710: 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65    assert( sqlite
5720: 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 2d 3e  3_mutex_held(p->
5730: 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78 29 20 29  pGroup->mutex) )
5740: 3b 0a 0a 20 20 6e 4e 65 77 20 3d 20 70 2d 3e 6e  ;..  nNew = p->n
5750: 48 61 73 68 2a 32 3b 0a 20 20 69 66 28 20 6e 4e  Hash*2;.  if( nN
5760: 65 77 3c 32 35 36 20 29 7b 0a 20 20 20 20 6e 4e  ew<256 ){.    nN
5770: 65 77 20 3d 20 32 35 36 3b 0a 20 20 7d 0a 0a 20  ew = 256;.  }.. 
5780: 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74   pcache1LeaveMut
5790: 65 78 28 70 2d 3e 70 47 72 6f 75 70 29 3b 0a 20  ex(p->pGroup);. 
57a0: 20 69 66 28 20 70 2d 3e 6e 48 61 73 68 20 29 7b   if( p->nHash ){
57b0: 20 73 71 6c 69 74 65 33 42 65 67 69 6e 42 65 6e   sqlite3BeginBen
57c0: 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 20 7d 0a 20  ignMalloc(); }. 
57d0: 20 61 70 4e 65 77 20 3d 20 28 50 67 48 64 72 31   apNew = (PgHdr1
57e0: 20 2a 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c   **)sqlite3_mall
57f0: 6f 63 28 73 69 7a 65 6f 66 28 50 67 48 64 72 31  oc(sizeof(PgHdr1
5800: 20 2a 29 2a 6e 4e 65 77 29 3b 0a 20 20 69 66 28   *)*nNew);.  if(
5810: 20 70 2d 3e 6e 48 61 73 68 20 29 7b 20 73 71 6c   p->nHash ){ sql
5820: 69 74 65 33 45 6e 64 42 65 6e 69 67 6e 4d 61 6c  ite3EndBenignMal
5830: 6c 6f 63 28 29 3b 20 7d 0a 20 20 70 63 61 63 68  loc(); }.  pcach
5840: 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70 2d 3e  e1EnterMutex(p->
5850: 70 47 72 6f 75 70 29 3b 0a 20 20 69 66 28 20 61  pGroup);.  if( a
5860: 70 4e 65 77 20 29 7b 0a 20 20 20 20 6d 65 6d 73  pNew ){.    mems
5870: 65 74 28 61 70 4e 65 77 2c 20 30 2c 20 73 69 7a  et(apNew, 0, siz
5880: 65 6f 66 28 50 67 48 64 72 31 20 2a 29 2a 6e 4e  eof(PgHdr1 *)*nN
5890: 65 77 29 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30  ew);.    for(i=0
58a0: 3b 20 69 3c 70 2d 3e 6e 48 61 73 68 3b 20 69 2b  ; i<p->nHash; i+
58b0: 2b 29 7b 0a 20 20 20 20 20 20 50 67 48 64 72 31  +){.      PgHdr1
58c0: 20 2a 70 50 61 67 65 3b 0a 20 20 20 20 20 20 50   *pPage;.      P
58d0: 67 48 64 72 31 20 2a 70 4e 65 78 74 20 3d 20 70  gHdr1 *pNext = p
58e0: 2d 3e 61 70 48 61 73 68 5b 69 5d 3b 0a 20 20 20  ->apHash[i];.   
58f0: 20 20 20 77 68 69 6c 65 28 20 28 70 50 61 67 65     while( (pPage
5900: 20 3d 20 70 4e 65 78 74 29 21 3d 30 20 29 7b 0a   = pNext)!=0 ){.
5910: 20 20 20 20 20 20 20 20 75 6e 73 69 67 6e 65 64          unsigned
5920: 20 69 6e 74 20 68 20 3d 20 70 50 61 67 65 2d 3e   int h = pPage->
5930: 69 4b 65 79 20 25 20 6e 4e 65 77 3b 0a 20 20 20  iKey % nNew;.   
5940: 20 20 20 20 20 70 4e 65 78 74 20 3d 20 70 50 61       pNext = pPa
5950: 67 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20  ge->pNext;.     
5960: 20 20 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 20     pPage->pNext 
5970: 3d 20 61 70 4e 65 77 5b 68 5d 3b 0a 20 20 20 20  = apNew[h];.    
5980: 20 20 20 20 61 70 4e 65 77 5b 68 5d 20 3d 20 70      apNew[h] = p
5990: 50 61 67 65 3b 0a 20 20 20 20 20 20 7d 0a 20 20  Page;.      }.  
59a0: 20 20 7d 0a 20 20 20 20 73 71 6c 69 74 65 33 5f    }.    sqlite3_
59b0: 66 72 65 65 28 70 2d 3e 61 70 48 61 73 68 29 3b  free(p->apHash);
59c0: 0a 20 20 20 20 70 2d 3e 61 70 48 61 73 68 20 3d  .    p->apHash =
59d0: 20 61 70 4e 65 77 3b 0a 20 20 20 20 70 2d 3e 6e   apNew;.    p->n
59e0: 48 61 73 68 20 3d 20 6e 4e 65 77 3b 0a 20 20 7d  Hash = nNew;.  }
59f0: 0a 0a 20 20 72 65 74 75 72 6e 20 28 70 2d 3e 61  ..  return (p->a
5a00: 70 48 61 73 68 20 3f 20 53 51 4c 49 54 45 5f 4f  pHash ? SQLITE_O
5a10: 4b 20 3a 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  K : SQLITE_NOMEM
5a20: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  );.}../*.** This
5a30: 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 75 73 65   function is use
5a40: 64 20 69 6e 74 65 72 6e 61 6c 6c 79 20 74 6f 20  d internally to 
5a50: 72 65 6d 6f 76 65 20 74 68 65 20 70 61 67 65 20  remove the page 
5a60: 70 50 61 67 65 20 66 72 6f 6d 20 74 68 65 20 0a  pPage from the .
5a70: 2a 2a 20 50 47 72 6f 75 70 20 4c 52 55 20 6c 69  ** PGroup LRU li
5a80: 73 74 2c 20 69 66 20 69 73 20 70 61 72 74 20 6f  st, if is part o
5a90: 66 20 69 74 2e 20 49 66 20 70 50 61 67 65 20 69  f it. If pPage i
5aa0: 73 20 6e 6f 74 20 70 61 72 74 20 6f 66 20 74 68  s not part of th
5ab0: 65 20 50 47 72 6f 75 70 0a 2a 2a 20 4c 52 55 20  e PGroup.** LRU 
5ac0: 6c 69 73 74 2c 20 74 68 65 6e 20 74 68 69 73 20  list, then this 
5ad0: 66 75 6e 63 74 69 6f 6e 20 69 73 20 61 20 6e 6f  function is a no
5ae0: 2d 6f 70 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 50  -op..**.** The P
5af0: 47 72 6f 75 70 20 6d 75 74 65 78 20 6d 75 73 74  Group mutex must
5b00: 20 62 65 20 68 65 6c 64 20 77 68 65 6e 20 74 68   be held when th
5b10: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63  is function is c
5b20: 61 6c 6c 65 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20  alled..**.** If 
5b30: 70 50 61 67 65 20 69 73 20 4e 55 4c 4c 20 74 68  pPage is NULL th
5b40: 65 6e 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20  en this routine 
5b50: 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a 2a 2f 0a 73  is a no-op..*/.s
5b60: 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68  tatic void pcach
5b70: 65 31 50 69 6e 50 61 67 65 28 50 67 48 64 72 31  e1PinPage(PgHdr1
5b80: 20 2a 70 50 61 67 65 29 7b 0a 20 20 50 43 61 63   *pPage){.  PCac
5b90: 68 65 31 20 2a 70 43 61 63 68 65 3b 0a 20 20 50  he1 *pCache;.  P
5ba0: 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 3b 0a 0a  Group *pGroup;..
5bb0: 20 20 69 66 28 20 70 50 61 67 65 3d 3d 30 20 29    if( pPage==0 )
5bc0: 20 72 65 74 75 72 6e 3b 0a 20 20 70 43 61 63 68   return;.  pCach
5bd0: 65 20 3d 20 70 50 61 67 65 2d 3e 70 43 61 63 68  e = pPage->pCach
5be0: 65 3b 0a 20 20 70 47 72 6f 75 70 20 3d 20 70 43  e;.  pGroup = pC
5bf0: 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b 0a 20 20  ache->pGroup;.  
5c00: 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f  assert( sqlite3_
5c10: 6d 75 74 65 78 5f 68 65 6c 64 28 70 47 72 6f 75  mutex_held(pGrou
5c20: 70 2d 3e 6d 75 74 65 78 29 20 29 3b 0a 20 20 69  p->mutex) );.  i
5c30: 66 28 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65  f( pPage->pLruNe
5c40: 78 74 20 7c 7c 20 70 50 61 67 65 3d 3d 70 47 72  xt || pPage==pGr
5c50: 6f 75 70 2d 3e 70 4c 72 75 54 61 69 6c 20 29 7b  oup->pLruTail ){
5c60: 0a 20 20 20 20 69 66 28 20 70 50 61 67 65 2d 3e  .    if( pPage->
5c70: 70 4c 72 75 50 72 65 76 20 29 7b 0a 20 20 20 20  pLruPrev ){.    
5c80: 20 20 70 50 61 67 65 2d 3e 70 4c 72 75 50 72 65    pPage->pLruPre
5c90: 76 2d 3e 70 4c 72 75 4e 65 78 74 20 3d 20 70 50  v->pLruNext = pP
5ca0: 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 3b 0a 20  age->pLruNext;. 
5cb0: 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70 50 61     }.    if( pPa
5cc0: 67 65 2d 3e 70 4c 72 75 4e 65 78 74 20 29 7b 0a  ge->pLruNext ){.
5cd0: 20 20 20 20 20 20 70 50 61 67 65 2d 3e 70 4c 72        pPage->pLr
5ce0: 75 4e 65 78 74 2d 3e 70 4c 72 75 50 72 65 76 20  uNext->pLruPrev 
5cf0: 3d 20 70 50 61 67 65 2d 3e 70 4c 72 75 50 72 65  = pPage->pLruPre
5d00: 76 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28  v;.    }.    if(
5d10: 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 48 65 61   pGroup->pLruHea
5d20: 64 3d 3d 70 50 61 67 65 20 29 7b 0a 20 20 20 20  d==pPage ){.    
5d30: 20 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 48 65    pGroup->pLruHe
5d40: 61 64 20 3d 20 70 50 61 67 65 2d 3e 70 4c 72 75  ad = pPage->pLru
5d50: 4e 65 78 74 3b 0a 20 20 20 20 7d 0a 20 20 20 20  Next;.    }.    
5d60: 69 66 28 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75  if( pGroup->pLru
5d70: 54 61 69 6c 3d 3d 70 50 61 67 65 20 29 7b 0a 20  Tail==pPage ){. 
5d80: 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 70 4c 72       pGroup->pLr
5d90: 75 54 61 69 6c 20 3d 20 70 50 61 67 65 2d 3e 70  uTail = pPage->p
5da0: 4c 72 75 50 72 65 76 3b 0a 20 20 20 20 7d 0a 20  LruPrev;.    }. 
5db0: 20 20 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65     pPage->pLruNe
5dc0: 78 74 20 3d 20 30 3b 0a 20 20 20 20 70 50 61 67  xt = 0;.    pPag
5dd0: 65 2d 3e 70 4c 72 75 50 72 65 76 20 3d 20 30 3b  e->pLruPrev = 0;
5de0: 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 43 61 63  .    pPage->pCac
5df0: 68 65 2d 3e 6e 52 65 63 79 63 6c 61 62 6c 65 2d  he->nRecyclable-
5e00: 2d 3b 0a 20 20 7d 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a  -;.  }.}.../*.**
5e10: 20 52 65 6d 6f 76 65 20 74 68 65 20 70 61 67 65   Remove the page
5e20: 20 73 75 70 70 6c 69 65 64 20 61 73 20 61 6e 20   supplied as an 
5e30: 61 72 67 75 6d 65 6e 74 20 66 72 6f 6d 20 74 68  argument from th
5e40: 65 20 68 61 73 68 20 74 61 62 6c 65 20 0a 2a 2a  e hash table .**
5e50: 20 28 50 43 61 63 68 65 31 2e 61 70 48 61 73 68   (PCache1.apHash
5e60: 20 73 74 72 75 63 74 75 72 65 29 20 74 68 61 74   structure) that
5e70: 20 69 74 20 69 73 20 63 75 72 72 65 6e 74 6c 79   it is currently
5e80: 20 73 74 6f 72 65 64 20 69 6e 2e 0a 2a 2a 0a 2a   stored in..**.*
5e90: 2a 20 54 68 65 20 50 47 72 6f 75 70 20 6d 75 74  * The PGroup mut
5ea0: 65 78 20 6d 75 73 74 20 62 65 20 68 65 6c 64 20  ex must be held 
5eb0: 77 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69  when this functi
5ec0: 6f 6e 20 69 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f  on is called..*/
5ed0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61  .static void pca
5ee0: 63 68 65 31 52 65 6d 6f 76 65 46 72 6f 6d 48 61  che1RemoveFromHa
5ef0: 73 68 28 50 67 48 64 72 31 20 2a 70 50 61 67 65  sh(PgHdr1 *pPage
5f00: 29 7b 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e  ){.  unsigned in
5f10: 74 20 68 3b 0a 20 20 50 43 61 63 68 65 31 20 2a  t h;.  PCache1 *
5f20: 70 43 61 63 68 65 20 3d 20 70 50 61 67 65 2d 3e  pCache = pPage->
5f30: 70 43 61 63 68 65 3b 0a 20 20 50 67 48 64 72 31  pCache;.  PgHdr1
5f40: 20 2a 2a 70 70 3b 0a 0a 20 20 61 73 73 65 72 74   **pp;..  assert
5f50: 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f  ( sqlite3_mutex_
5f60: 68 65 6c 64 28 70 43 61 63 68 65 2d 3e 70 47 72  held(pCache->pGr
5f70: 6f 75 70 2d 3e 6d 75 74 65 78 29 20 29 3b 0a 20  oup->mutex) );. 
5f80: 20 68 20 3d 20 70 50 61 67 65 2d 3e 69 4b 65 79   h = pPage->iKey
5f90: 20 25 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68   % pCache->nHash
5fa0: 3b 0a 20 20 66 6f 72 28 70 70 3d 26 70 43 61 63  ;.  for(pp=&pCac
5fb0: 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 20 28  he->apHash[h]; (
5fc0: 2a 70 70 29 21 3d 70 50 61 67 65 3b 20 70 70 3d  *pp)!=pPage; pp=
5fd0: 26 28 2a 70 70 29 2d 3e 70 4e 65 78 74 29 3b 0a  &(*pp)->pNext);.
5fe0: 20 20 2a 70 70 20 3d 20 28 2a 70 70 29 2d 3e 70    *pp = (*pp)->p
5ff0: 4e 65 78 74 3b 0a 0a 20 20 70 43 61 63 68 65 2d  Next;..  pCache-
6000: 3e 6e 50 61 67 65 2d 2d 3b 0a 7d 0a 0a 2f 2a 0a  >nPage--;.}../*.
6010: 2a 2a 20 49 66 20 74 68 65 72 65 20 61 72 65 20  ** If there are 
6020: 63 75 72 72 65 6e 74 6c 79 20 6d 6f 72 65 20 74  currently more t
6030: 68 61 6e 20 6e 4d 61 78 50 61 67 65 20 70 61 67  han nMaxPage pag
6040: 65 73 20 61 6c 6c 6f 63 61 74 65 64 2c 20 74 72  es allocated, tr
6050: 79 0a 2a 2a 20 74 6f 20 72 65 63 79 63 6c 65 20  y.** to recycle 
6060: 70 61 67 65 73 20 74 6f 20 72 65 64 75 63 65 20  pages to reduce 
6070: 74 68 65 20 6e 75 6d 62 65 72 20 61 6c 6c 6f 63  the number alloc
6080: 61 74 65 64 20 74 6f 20 6e 4d 61 78 50 61 67 65  ated to nMaxPage
6090: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
60a0: 20 70 63 61 63 68 65 31 45 6e 66 6f 72 63 65 4d   pcache1EnforceM
60b0: 61 78 50 61 67 65 28 50 47 72 6f 75 70 20 2a 70  axPage(PGroup *p
60c0: 47 72 6f 75 70 29 7b 0a 20 20 61 73 73 65 72 74  Group){.  assert
60d0: 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f  ( sqlite3_mutex_
60e0: 68 65 6c 64 28 70 47 72 6f 75 70 2d 3e 6d 75 74  held(pGroup->mut
60f0: 65 78 29 20 29 3b 0a 20 20 77 68 69 6c 65 28 20  ex) );.  while( 
6100: 70 47 72 6f 75 70 2d 3e 6e 43 75 72 72 65 6e 74  pGroup->nCurrent
6110: 50 61 67 65 3e 70 47 72 6f 75 70 2d 3e 6e 4d 61  Page>pGroup->nMa
6120: 78 50 61 67 65 20 26 26 20 70 47 72 6f 75 70 2d  xPage && pGroup-
6130: 3e 70 4c 72 75 54 61 69 6c 20 29 7b 0a 20 20 20  >pLruTail ){.   
6140: 20 50 67 48 64 72 31 20 2a 70 20 3d 20 70 47 72   PgHdr1 *p = pGr
6150: 6f 75 70 2d 3e 70 4c 72 75 54 61 69 6c 3b 0a 20  oup->pLruTail;. 
6160: 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e 70 43     assert( p->pC
6170: 61 63 68 65 2d 3e 70 47 72 6f 75 70 3d 3d 70 47  ache->pGroup==pG
6180: 72 6f 75 70 20 29 3b 0a 20 20 20 20 70 63 61 63  roup );.    pcac
6190: 68 65 31 50 69 6e 50 61 67 65 28 70 29 3b 0a 20  he1PinPage(p);. 
61a0: 20 20 20 70 63 61 63 68 65 31 52 65 6d 6f 76 65     pcache1Remove
61b0: 46 72 6f 6d 48 61 73 68 28 70 29 3b 0a 20 20 20  FromHash(p);.   
61c0: 20 70 63 61 63 68 65 31 46 72 65 65 50 61 67 65   pcache1FreePage
61d0: 28 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a  (p);.  }.}../*.*
61e0: 2a 20 44 69 73 63 61 72 64 20 61 6c 6c 20 70 61  * Discard all pa
61f0: 67 65 73 20 66 72 6f 6d 20 63 61 63 68 65 20 70  ges from cache p
6200: 43 61 63 68 65 20 77 69 74 68 20 61 20 70 61 67  Cache with a pag
6210: 65 20 6e 75 6d 62 65 72 20 28 6b 65 79 20 76 61  e number (key va
6220: 6c 75 65 29 20 0a 2a 2a 20 67 72 65 61 74 65 72  lue) .** greater
6230: 20 74 68 61 6e 20 6f 72 20 65 71 75 61 6c 20 74   than or equal t
6240: 6f 20 69 4c 69 6d 69 74 2e 20 41 6e 79 20 70 69  o iLimit. Any pi
6250: 6e 6e 65 64 20 70 61 67 65 73 20 74 68 61 74 20  nned pages that 
6260: 6d 65 65 74 20 74 68 69 73 20 0a 2a 2a 20 63 72  meet this .** cr
6270: 69 74 65 72 69 61 20 61 72 65 20 75 6e 70 69 6e  iteria are unpin
6280: 6e 65 64 20 62 65 66 6f 72 65 20 74 68 65 79 20  ned before they 
6290: 61 72 65 20 64 69 73 63 61 72 64 65 64 2e 0a 2a  are discarded..*
62a0: 2a 0a 2a 2a 20 54 68 65 20 50 43 61 63 68 65 20  *.** The PCache 
62b0: 6d 75 74 65 78 20 6d 75 73 74 20 62 65 20 68 65  mutex must be he
62c0: 6c 64 20 77 68 65 6e 20 74 68 69 73 20 66 75 6e  ld when this fun
62d0: 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 2e  ction is called.
62e0: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
62f0: 70 63 61 63 68 65 31 54 72 75 6e 63 61 74 65 55  pcache1TruncateU
6300: 6e 73 61 66 65 28 0a 20 20 50 43 61 63 68 65 31  nsafe(.  PCache1
6310: 20 2a 70 43 61 63 68 65 2c 20 20 20 20 20 20 20   *pCache,       
6320: 20 20 20 20 20 20 2f 2a 20 54 68 65 20 63 61 63        /* The cac
6330: 68 65 20 74 6f 20 74 72 75 6e 63 61 74 65 20 2a  he to truncate *
6340: 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74  /.  unsigned int
6350: 20 69 4c 69 6d 69 74 20 20 20 20 20 20 20 20 20   iLimit         
6360: 20 2f 2a 20 44 72 6f 70 20 70 61 67 65 73 20 77   /* Drop pages w
6370: 69 74 68 20 74 68 69 73 20 70 67 6e 6f 20 6f 72  ith this pgno or
6380: 20 6c 61 72 67 65 72 20 2a 2f 0a 29 7b 0a 20 20   larger */.){.  
6390: 54 45 53 54 4f 4e 4c 59 28 20 75 6e 73 69 67 6e  TESTONLY( unsign
63a0: 65 64 20 69 6e 74 20 6e 50 61 67 65 20 3d 20 30  ed int nPage = 0
63b0: 3b 20 29 20 20 2f 2a 20 54 6f 20 61 73 73 65 72  ; )  /* To asser
63c0: 74 20 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 20  t pCache->nPage 
63d0: 69 73 20 63 6f 72 72 65 63 74 20 2a 2f 0a 20 20  is correct */.  
63e0: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 3b 0a  unsigned int h;.
63f0: 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65    assert( sqlite
6400: 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 43 61  3_mutex_held(pCa
6410: 63 68 65 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75 74  che->pGroup->mut
6420: 65 78 29 20 29 3b 0a 20 20 66 6f 72 28 68 3d 30  ex) );.  for(h=0
6430: 3b 20 68 3c 70 43 61 63 68 65 2d 3e 6e 48 61 73  ; h<pCache->nHas
6440: 68 3b 20 68 2b 2b 29 7b 0a 20 20 20 20 50 67 48  h; h++){.    PgH
6450: 64 72 31 20 2a 2a 70 70 20 3d 20 26 70 43 61 63  dr1 **pp = &pCac
6460: 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 20 0a  he->apHash[h]; .
6470: 20 20 20 20 50 67 48 64 72 31 20 2a 70 50 61 67      PgHdr1 *pPag
6480: 65 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 28 70  e;.    while( (p
6490: 50 61 67 65 20 3d 20 2a 70 70 29 21 3d 30 20 29  Page = *pp)!=0 )
64a0: 7b 0a 20 20 20 20 20 20 69 66 28 20 70 50 61 67  {.      if( pPag
64b0: 65 2d 3e 69 4b 65 79 3e 3d 69 4c 69 6d 69 74 20  e->iKey>=iLimit 
64c0: 29 7b 0a 20 20 20 20 20 20 20 20 70 43 61 63 68  ){.        pCach
64d0: 65 2d 3e 6e 50 61 67 65 2d 2d 3b 0a 20 20 20 20  e->nPage--;.    
64e0: 20 20 20 20 2a 70 70 20 3d 20 70 50 61 67 65 2d      *pp = pPage-
64f0: 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 20 20  >pNext;.        
6500: 70 63 61 63 68 65 31 50 69 6e 50 61 67 65 28 70  pcache1PinPage(p
6510: 50 61 67 65 29 3b 0a 20 20 20 20 20 20 20 20 70  Page);.        p
6520: 63 61 63 68 65 31 46 72 65 65 50 61 67 65 28 70  cache1FreePage(p
6530: 50 61 67 65 29 3b 0a 20 20 20 20 20 20 7d 65 6c  Page);.      }el
6540: 73 65 7b 0a 20 20 20 20 20 20 20 20 70 70 20 3d  se{.        pp =
6550: 20 26 70 50 61 67 65 2d 3e 70 4e 65 78 74 3b 0a   &pPage->pNext;.
6560: 20 20 20 20 20 20 20 20 54 45 53 54 4f 4e 4c 59          TESTONLY
6570: 28 20 6e 50 61 67 65 2b 2b 3b 20 29 0a 20 20 20  ( nPage++; ).   
6580: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20     }.    }.  }. 
6590: 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65 2d   assert( pCache-
65a0: 3e 6e 50 61 67 65 3d 3d 6e 50 61 67 65 20 29 3b  >nPage==nPage );
65b0: 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  .}../***********
65c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
65d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
65e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
65f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
6600: 2a 2a 2a 2f 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 20 73  ***/./******** s
6610: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 4d 65  qlite3_pcache Me
6620: 74 68 6f 64 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  thods **********
6630: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
6640: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
6650: 2a 2a 2a 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70  ****/../*.** Imp
6660: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74  lementation of t
6670: 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68  he sqlite3_pcach
6680: 65 2e 78 49 6e 69 74 20 6d 65 74 68 6f 64 2e 0a  e.xInit method..
6690: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 70 63  */.static int pc
66a0: 61 63 68 65 31 49 6e 69 74 28 76 6f 69 64 20 2a  ache1Init(void *
66b0: 4e 6f 74 55 73 65 64 29 7b 0a 20 20 55 4e 55 53  NotUsed){.  UNUS
66c0: 45 44 5f 50 41 52 41 4d 45 54 45 52 28 4e 6f 74  ED_PARAMETER(Not
66d0: 55 73 65 64 29 3b 0a 20 20 61 73 73 65 72 74 28  Used);.  assert(
66e0: 20 70 63 61 63 68 65 31 2e 69 73 49 6e 69 74 3d   pcache1.isInit=
66f0: 3d 30 20 29 3b 0a 20 20 6d 65 6d 73 65 74 28 26  =0 );.  memset(&
6700: 70 63 61 63 68 65 31 2c 20 30 2c 20 73 69 7a 65  pcache1, 0, size
6710: 6f 66 28 70 63 61 63 68 65 31 29 29 3b 0a 20 20  of(pcache1));.  
6720: 69 66 28 20 73 71 6c 69 74 65 33 47 6c 6f 62 61  if( sqlite3Globa
6730: 6c 43 6f 6e 66 69 67 2e 62 43 6f 72 65 4d 75 74  lConfig.bCoreMut
6740: 65 78 20 29 7b 0a 20 20 20 20 70 63 61 63 68 65  ex ){.    pcache
6750: 31 2e 67 72 70 2e 6d 75 74 65 78 20 3d 20 73 71  1.grp.mutex = sq
6760: 6c 69 74 65 33 5f 6d 75 74 65 78 5f 61 6c 6c 6f  lite3_mutex_allo
6770: 63 28 53 51 4c 49 54 45 5f 4d 55 54 45 58 5f 53  c(SQLITE_MUTEX_S
6780: 54 41 54 49 43 5f 4c 52 55 29 3b 0a 20 20 20 20  TATIC_LRU);.    
6790: 70 63 61 63 68 65 31 2e 6d 75 74 65 78 20 3d 20  pcache1.mutex = 
67a0: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 61 6c  sqlite3_mutex_al
67b0: 6c 6f 63 28 53 51 4c 49 54 45 5f 4d 55 54 45 58  loc(SQLITE_MUTEX
67c0: 5f 53 54 41 54 49 43 5f 50 4d 45 4d 29 3b 0a 20  _STATIC_PMEM);. 
67d0: 20 7d 0a 20 20 70 63 61 63 68 65 31 2e 67 72 70   }.  pcache1.grp
67e0: 2e 6d 78 50 69 6e 6e 65 64 20 3d 20 31 30 3b 0a  .mxPinned = 10;.
67f0: 20 20 70 63 61 63 68 65 31 2e 69 73 49 6e 69 74    pcache1.isInit
6800: 20 3d 20 31 3b 0a 20 20 72 65 74 75 72 6e 20 53   = 1;.  return S
6810: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  QLITE_OK;.}../*.
6820: 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  ** Implementatio
6830: 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33  n of the sqlite3
6840: 5f 70 63 61 63 68 65 2e 78 53 68 75 74 64 6f 77  _pcache.xShutdow
6850: 6e 20 6d 65 74 68 6f 64 2e 0a 2a 2a 20 4e 6f 74  n method..** Not
6860: 65 20 74 68 61 74 20 74 68 65 20 73 74 61 74 69  e that the stati
6870: 63 20 6d 75 74 65 78 20 61 6c 6c 6f 63 61 74 65  c mutex allocate
6880: 64 20 69 6e 20 78 49 6e 69 74 20 64 6f 65 73 20  d in xInit does 
6890: 0a 2a 2a 20 6e 6f 74 20 6e 65 65 64 20 74 6f 20  .** not need to 
68a0: 62 65 20 66 72 65 65 64 2e 0a 2a 2f 0a 73 74 61  be freed..*/.sta
68b0: 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 31  tic void pcache1
68c0: 53 68 75 74 64 6f 77 6e 28 76 6f 69 64 20 2a 4e  Shutdown(void *N
68d0: 6f 74 55 73 65 64 29 7b 0a 20 20 55 4e 55 53 45  otUsed){.  UNUSE
68e0: 44 5f 50 41 52 41 4d 45 54 45 52 28 4e 6f 74 55  D_PARAMETER(NotU
68f0: 73 65 64 29 3b 0a 20 20 61 73 73 65 72 74 28 20  sed);.  assert( 
6900: 70 63 61 63 68 65 31 2e 69 73 49 6e 69 74 21 3d  pcache1.isInit!=
6910: 30 20 29 3b 0a 20 20 6d 65 6d 73 65 74 28 26 70  0 );.  memset(&p
6920: 63 61 63 68 65 31 2c 20 30 2c 20 73 69 7a 65 6f  cache1, 0, sizeo
6930: 66 28 70 63 61 63 68 65 31 29 29 3b 0a 7d 0a 0a  f(pcache1));.}..
6940: 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61  /*.** Implementa
6950: 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69  tion of the sqli
6960: 74 65 33 5f 70 63 61 63 68 65 2e 78 43 72 65 61  te3_pcache.xCrea
6970: 74 65 20 6d 65 74 68 6f 64 2e 0a 2a 2a 0a 2a 2a  te method..**.**
6980: 20 41 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20   Allocate a new 
6990: 63 61 63 68 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  cache..*/.static
69a0: 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20   sqlite3_pcache 
69b0: 2a 70 63 61 63 68 65 31 43 72 65 61 74 65 28 69  *pcache1Create(i
69c0: 6e 74 20 73 7a 50 61 67 65 2c 20 69 6e 74 20 62  nt szPage, int b
69d0: 50 75 72 67 65 61 62 6c 65 29 7b 0a 20 20 50 43  Purgeable){.  PC
69e0: 61 63 68 65 31 20 2a 70 43 61 63 68 65 3b 20 20  ache1 *pCache;  
69f0: 20 20 20 20 2f 2a 20 54 68 65 20 6e 65 77 6c 79      /* The newly
6a00: 20 63 72 65 61 74 65 64 20 70 61 67 65 20 63 61   created page ca
6a10: 63 68 65 20 2a 2f 0a 20 20 50 47 72 6f 75 70 20  che */.  PGroup 
6a20: 2a 70 47 72 6f 75 70 3b 20 20 20 20 20 20 20 2f  *pGroup;       /
6a30: 2a 20 54 68 65 20 67 72 6f 75 70 20 74 68 65 20  * The group the 
6a40: 6e 65 77 20 70 61 67 65 20 63 61 63 68 65 20 77  new page cache w
6a50: 69 6c 6c 20 62 65 6c 6f 6e 67 20 74 6f 20 2a 2f  ill belong to */
6a60: 0a 20 20 69 6e 74 20 73 7a 3b 20 20 20 20 20 20  .  int sz;      
6a70: 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65           /* Byte
6a80: 73 20 6f 66 20 6d 65 6d 6f 72 79 20 72 65 71 75  s of memory requ
6a90: 69 72 65 64 20 74 6f 20 61 6c 6c 6f 63 61 74 65  ired to allocate
6aa0: 20 74 68 65 20 6e 65 77 20 63 61 63 68 65 20 2a   the new cache *
6ab0: 2f 0a 0a 20 20 2f 2a 0a 20 20 2a 2a 20 54 68 65  /..  /*.  ** The
6ac0: 20 73 65 70 65 72 61 74 65 43 61 63 68 65 20 76   seperateCache v
6ad0: 61 72 69 61 62 6c 65 20 69 73 20 74 72 75 65 20  ariable is true 
6ae0: 69 66 20 65 61 63 68 20 50 43 61 63 68 65 20 68  if each PCache h
6af0: 61 73 20 69 74 73 20 6f 77 6e 20 70 72 69 76 61  as its own priva
6b00: 74 65 0a 20 20 2a 2a 20 50 47 72 6f 75 70 2e 20  te.  ** PGroup. 
6b10: 20 49 6e 20 6f 74 68 65 72 20 77 6f 72 64 73 2c   In other words,
6b20: 20 73 65 70 61 72 61 74 65 43 61 63 68 65 20 69   separateCache i
6b30: 73 20 74 72 75 65 20 66 6f 72 20 6d 6f 64 65 20  s true for mode 
6b40: 28 31 29 20 77 68 65 72 65 20 6e 6f 0a 20 20 2a  (1) where no.  *
6b50: 2a 20 6d 75 74 65 78 69 6e 67 20 69 73 20 72 65  * mutexing is re
6b60: 71 75 69 72 65 64 2e 0a 20 20 2a 2a 0a 20 20 2a  quired..  **.  *
6b70: 2a 20 20 20 2a 20 20 41 6c 77 61 79 73 20 75 73  *   *  Always us
6b80: 65 20 61 20 75 6e 69 66 69 65 64 20 63 61 63 68  e a unified cach
6b90: 65 20 28 6d 6f 64 65 2d 32 29 20 69 66 20 45 4e  e (mode-2) if EN
6ba0: 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41  ABLE_MEMORY_MANA
6bb0: 47 45 4d 45 4e 54 0a 20 20 2a 2a 0a 20 20 2a 2a  GEMENT.  **.  **
6bc0: 20 20 20 2a 20 20 41 6c 77 61 79 73 20 75 73 65     *  Always use
6bd0: 20 61 20 75 6e 69 66 69 65 64 20 63 61 63 68 65   a unified cache
6be0: 20 69 6e 20 73 69 6e 67 6c 65 2d 74 68 72 65 61   in single-threa
6bf0: 64 65 64 20 61 70 70 6c 69 63 61 74 69 6f 6e 73  ded applications
6c00: 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 2a 20 20  .  **.  **   *  
6c10: 4f 74 68 65 72 77 69 73 65 20 28 69 66 20 6d 75  Otherwise (if mu
6c20: 6c 74 69 2d 74 68 72 65 61 64 65 64 20 61 6e 64  lti-threaded and
6c30: 20 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d   ENABLE_MEMORY_M
6c40: 41 4e 41 47 45 4d 45 4e 54 20 69 73 20 6f 66 66  ANAGEMENT is off
6c50: 29 0a 20 20 2a 2a 20 20 20 20 20 20 75 73 65 20  ).  **      use 
6c60: 73 65 70 61 72 61 74 65 20 63 61 63 68 65 73 20  separate caches 
6c70: 28 6d 6f 64 65 2d 31 29 0a 20 20 2a 2f 0a 23 69  (mode-1).  */.#i
6c80: 66 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45  f defined(SQLITE
6c90: 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d  _ENABLE_MEMORY_M
6ca0: 41 4e 41 47 45 4d 45 4e 54 29 20 7c 7c 20 53 51  ANAGEMENT) || SQ
6cb0: 4c 49 54 45 5f 54 48 52 45 41 44 53 41 46 45 3d  LITE_THREADSAFE=
6cc0: 3d 30 0a 20 20 63 6f 6e 73 74 20 69 6e 74 20 73  =0.  const int s
6cd0: 65 70 61 72 61 74 65 43 61 63 68 65 20 3d 20 30  eparateCache = 0
6ce0: 3b 0a 23 65 6c 73 65 0a 20 20 69 6e 74 20 73 65  ;.#else.  int se
6cf0: 70 61 72 61 74 65 43 61 63 68 65 20 3d 20 73 71  parateCache = sq
6d00: 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69  lite3GlobalConfi
6d10: 67 2e 62 43 6f 72 65 4d 75 74 65 78 3e 30 3b 0a  g.bCoreMutex>0;.
6d20: 23 65 6e 64 69 66 0a 0a 20 20 73 7a 20 3d 20 73  #endif..  sz = s
6d30: 69 7a 65 6f 66 28 50 43 61 63 68 65 31 29 20 2b  izeof(PCache1) +
6d40: 20 73 69 7a 65 6f 66 28 50 47 72 6f 75 70 29 2a   sizeof(PGroup)*
6d50: 73 65 70 61 72 61 74 65 43 61 63 68 65 3b 0a 20  separateCache;. 
6d60: 20 70 43 61 63 68 65 20 3d 20 28 50 43 61 63 68   pCache = (PCach
6d70: 65 31 20 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c  e1 *)sqlite3_mal
6d80: 6c 6f 63 28 73 7a 29 3b 0a 20 20 69 66 28 20 70  loc(sz);.  if( p
6d90: 43 61 63 68 65 20 29 7b 0a 20 20 20 20 6d 65 6d  Cache ){.    mem
6da0: 73 65 74 28 70 43 61 63 68 65 2c 20 30 2c 20 73  set(pCache, 0, s
6db0: 7a 29 3b 0a 20 20 20 20 69 66 28 20 73 65 70 61  z);.    if( sepa
6dc0: 72 61 74 65 43 61 63 68 65 20 29 7b 0a 20 20 20  rateCache ){.   
6dd0: 20 20 20 70 47 72 6f 75 70 20 3d 20 28 50 47 72     pGroup = (PGr
6de0: 6f 75 70 2a 29 26 70 43 61 63 68 65 5b 31 5d 3b  oup*)&pCache[1];
6df0: 0a 20 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 6d  .      pGroup->m
6e00: 78 50 69 6e 6e 65 64 20 3d 20 31 30 3b 0a 20 20  xPinned = 10;.  
6e10: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70    }else{.      p
6e20: 47 72 6f 75 70 20 3d 20 26 70 63 61 63 68 65 31  Group = &pcache1
6e30: 2e 67 72 70 3b 0a 20 20 20 20 7d 0a 20 20 20 20  .grp;.    }.    
6e40: 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 20 3d  pCache->pGroup =
6e50: 20 70 47 72 6f 75 70 3b 0a 20 20 20 20 70 43 61   pGroup;.    pCa
6e60: 63 68 65 2d 3e 73 7a 50 61 67 65 20 3d 20 73 7a  che->szPage = sz
6e70: 50 61 67 65 3b 0a 20 20 20 20 70 43 61 63 68 65  Page;.    pCache
6e80: 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 3d 20 28  ->bPurgeable = (
6e90: 62 50 75 72 67 65 61 62 6c 65 20 3f 20 31 20 3a  bPurgeable ? 1 :
6ea0: 20 30 29 3b 0a 20 20 20 20 69 66 28 20 62 50 75   0);.    if( bPu
6eb0: 72 67 65 61 62 6c 65 20 29 7b 0a 20 20 20 20 20  rgeable ){.     
6ec0: 20 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 20 3d 20   pCache->nMin = 
6ed0: 31 30 3b 0a 20 20 20 20 20 20 70 63 61 63 68 65  10;.      pcache
6ee0: 31 45 6e 74 65 72 4d 75 74 65 78 28 70 47 72 6f  1EnterMutex(pGro
6ef0: 75 70 29 3b 0a 20 20 20 20 20 20 70 47 72 6f 75  up);.      pGrou
6f00: 70 2d 3e 6e 4d 69 6e 50 61 67 65 20 2b 3d 20 70  p->nMinPage += p
6f10: 43 61 63 68 65 2d 3e 6e 4d 69 6e 3b 0a 20 20 20  Cache->nMin;.   
6f20: 20 20 20 70 47 72 6f 75 70 2d 3e 6d 78 50 69 6e     pGroup->mxPin
6f30: 6e 65 64 20 3d 20 70 47 72 6f 75 70 2d 3e 6e 4d  ned = pGroup->nM
6f40: 61 78 50 61 67 65 20 2b 20 31 30 20 2d 20 70 47  axPage + 10 - pG
6f50: 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67 65 3b 0a  roup->nMinPage;.
6f60: 20 20 20 20 20 20 70 63 61 63 68 65 31 4c 65 61        pcache1Lea
6f70: 76 65 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b  veMutex(pGroup);
6f80: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74  .    }.  }.  ret
6f90: 75 72 6e 20 28 73 71 6c 69 74 65 33 5f 70 63 61  urn (sqlite3_pca
6fa0: 63 68 65 20 2a 29 70 43 61 63 68 65 3b 0a 7d 0a  che *)pCache;.}.
6fb0: 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74  ./*.** Implement
6fc0: 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c  ation of the sql
6fd0: 69 74 65 33 5f 70 63 61 63 68 65 2e 78 43 61 63  ite3_pcache.xCac
6fe0: 68 65 73 69 7a 65 20 6d 65 74 68 6f 64 2e 20 0a  hesize method. .
6ff0: 2a 2a 0a 2a 2a 20 43 6f 6e 66 69 67 75 72 65 20  **.** Configure 
7000: 74 68 65 20 63 61 63 68 65 5f 73 69 7a 65 20 6c  the cache_size l
7010: 69 6d 69 74 20 66 6f 72 20 61 20 63 61 63 68 65  imit for a cache
7020: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
7030: 20 70 63 61 63 68 65 31 43 61 63 68 65 73 69 7a   pcache1Cachesiz
7040: 65 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  e(sqlite3_pcache
7050: 20 2a 70 2c 20 69 6e 74 20 6e 4d 61 78 29 7b 0a   *p, int nMax){.
7060: 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68    PCache1 *pCach
7070: 65 20 3d 20 28 50 43 61 63 68 65 31 20 2a 29 70  e = (PCache1 *)p
7080: 3b 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e  ;.  if( pCache->
7090: 62 50 75 72 67 65 61 62 6c 65 20 29 7b 0a 20 20  bPurgeable ){.  
70a0: 20 20 50 47 72 6f 75 70 20 2a 70 47 72 6f 75 70    PGroup *pGroup
70b0: 20 3d 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75   = pCache->pGrou
70c0: 70 3b 0a 20 20 20 20 70 63 61 63 68 65 31 45 6e  p;.    pcache1En
70d0: 74 65 72 4d 75 74 65 78 28 70 47 72 6f 75 70 29  terMutex(pGroup)
70e0: 3b 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e 6e 4d  ;.    pGroup->nM
70f0: 61 78 50 61 67 65 20 2b 3d 20 28 6e 4d 61 78 20  axPage += (nMax 
7100: 2d 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 29 3b  - pCache->nMax);
7110: 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e 6d 78 50  .    pGroup->mxP
7120: 69 6e 6e 65 64 20 3d 20 70 47 72 6f 75 70 2d 3e  inned = pGroup->
7130: 6e 4d 61 78 50 61 67 65 20 2b 20 31 30 20 2d 20  nMaxPage + 10 - 
7140: 70 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67 65  pGroup->nMinPage
7150: 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 6e 4d  ;.    pCache->nM
7160: 61 78 20 3d 20 6e 4d 61 78 3b 0a 20 20 20 20 70  ax = nMax;.    p
7170: 43 61 63 68 65 2d 3e 6e 39 30 70 63 74 20 3d 20  Cache->n90pct = 
7180: 70 43 61 63 68 65 2d 3e 6e 4d 61 78 2a 39 2f 31  pCache->nMax*9/1
7190: 30 3b 0a 20 20 20 20 70 63 61 63 68 65 31 45 6e  0;.    pcache1En
71a0: 66 6f 72 63 65 4d 61 78 50 61 67 65 28 70 47 72  forceMaxPage(pGr
71b0: 6f 75 70 29 3b 0a 20 20 20 20 70 63 61 63 68 65  oup);.    pcache
71c0: 31 4c 65 61 76 65 4d 75 74 65 78 28 70 47 72 6f  1LeaveMutex(pGro
71d0: 75 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a  up);.  }.}../*.*
71e0: 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  * Implementation
71f0: 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f   of the sqlite3_
7200: 70 63 61 63 68 65 2e 78 50 61 67 65 63 6f 75 6e  pcache.xPagecoun
7210: 74 20 6d 65 74 68 6f 64 2e 20 0a 2a 2f 0a 73 74  t method. .*/.st
7220: 61 74 69 63 20 69 6e 74 20 70 63 61 63 68 65 31  atic int pcache1
7230: 50 61 67 65 63 6f 75 6e 74 28 73 71 6c 69 74 65  Pagecount(sqlite
7240: 33 5f 70 63 61 63 68 65 20 2a 70 29 7b 0a 20 20  3_pcache *p){.  
7250: 69 6e 74 20 6e 3b 0a 20 20 50 43 61 63 68 65 31  int n;.  PCache1
7260: 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61 63   *pCache = (PCac
7270: 68 65 31 2a 29 70 3b 0a 20 20 70 63 61 63 68 65  he1*)p;.  pcache
7280: 31 45 6e 74 65 72 4d 75 74 65 78 28 70 43 61 63  1EnterMutex(pCac
7290: 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 20 20 6e  he->pGroup);.  n
72a0: 20 3d 20 70 43 61 63 68 65 2d 3e 6e 50 61 67 65   = pCache->nPage
72b0: 3b 0a 20 20 70 63 61 63 68 65 31 4c 65 61 76 65  ;.  pcache1Leave
72c0: 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e 70 47  Mutex(pCache->pG
72d0: 72 6f 75 70 29 3b 0a 20 20 72 65 74 75 72 6e 20  roup);.  return 
72e0: 6e 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c  n;.}../*.** Impl
72f0: 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68  ementation of th
7300: 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  e sqlite3_pcache
7310: 2e 78 46 65 74 63 68 20 6d 65 74 68 6f 64 2e 20  .xFetch method. 
7320: 0a 2a 2a 0a 2a 2a 20 46 65 74 63 68 20 61 20 70  .**.** Fetch a p
7330: 61 67 65 20 62 79 20 6b 65 79 20 76 61 6c 75 65  age by key value
7340: 2e 0a 2a 2a 0a 2a 2a 20 57 68 65 74 68 65 72 20  ..**.** Whether 
7350: 6f 72 20 6e 6f 74 20 61 20 6e 65 77 20 70 61 67  or not a new pag
7360: 65 20 6d 61 79 20 62 65 20 61 6c 6c 6f 63 61 74  e may be allocat
7370: 65 64 20 62 79 20 74 68 69 73 20 66 75 6e 63 74  ed by this funct
7380: 69 6f 6e 20 64 65 70 65 6e 64 73 20 6f 6e 0a 2a  ion depends on.*
7390: 2a 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20 74  * the value of t
73a0: 68 65 20 63 72 65 61 74 65 46 6c 61 67 20 61 72  he createFlag ar
73b0: 67 75 6d 65 6e 74 2e 20 20 30 20 6d 65 61 6e 73  gument.  0 means
73c0: 20 64 6f 20 6e 6f 74 20 61 6c 6c 6f 63 61 74 65   do not allocate
73d0: 20 61 20 6e 65 77 0a 2a 2a 20 70 61 67 65 2e 20   a new.** page. 
73e0: 20 31 20 6d 65 61 6e 73 20 61 6c 6c 6f 63 61 74   1 means allocat
73f0: 65 20 61 20 6e 65 77 20 70 61 67 65 20 69 66 20  e a new page if 
7400: 73 70 61 63 65 20 69 73 20 65 61 73 69 6c 79 20  space is easily 
7410: 61 76 61 69 6c 61 62 6c 65 2e 20 20 32 20 0a 2a  available.  2 .*
7420: 2a 20 6d 65 61 6e 73 20 74 6f 20 74 72 79 20 72  * means to try r
7430: 65 61 6c 6c 79 20 68 61 72 64 20 74 6f 20 61 6c  eally hard to al
7440: 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 70 61 67  locate a new pag
7450: 65 2e 0a 2a 2a 0a 2a 2a 20 46 6f 72 20 61 20 6e  e..**.** For a n
7460: 6f 6e 2d 70 75 72 67 65 61 62 6c 65 20 63 61 63  on-purgeable cac
7470: 68 65 20 28 61 20 63 61 63 68 65 20 75 73 65 64  he (a cache used
7480: 20 61 73 20 74 68 65 20 73 74 6f 72 61 67 65 20   as the storage 
7490: 66 6f 72 20 61 6e 20 69 6e 2d 6d 65 6d 6f 72 79  for an in-memory
74a0: 0a 2a 2a 20 64 61 74 61 62 61 73 65 29 20 74 68  .** database) th
74b0: 65 72 65 20 69 73 20 72 65 61 6c 6c 79 20 6e 6f  ere is really no
74c0: 20 64 69 66 66 65 72 65 6e 63 65 20 62 65 74 77   difference betw
74d0: 65 65 6e 20 63 72 65 61 74 65 46 6c 61 67 20 31  een createFlag 1
74e0: 20 61 6e 64 20 32 2e 20 20 53 6f 0a 2a 2a 20 74   and 2.  So.** t
74f0: 68 65 20 63 61 6c 6c 69 6e 67 20 66 75 6e 63 74  he calling funct
7500: 69 6f 6e 20 28 70 63 61 63 68 65 2e 63 29 20 77  ion (pcache.c) w
7510: 69 6c 6c 20 6e 65 76 65 72 20 68 61 76 65 20 61  ill never have a
7520: 20 63 72 65 61 74 65 46 6c 61 67 20 6f 66 20 31   createFlag of 1
7530: 20 6f 6e 0a 2a 2a 20 61 20 6e 6f 6e 2d 70 75 72   on.** a non-pur
7540: 67 61 62 6c 65 20 63 61 63 68 65 2e 0a 2a 2a 0a  gable cache..**.
7550: 2a 2a 20 54 68 65 72 65 20 61 72 65 20 74 68 72  ** There are thr
7560: 65 65 20 64 69 66 66 65 72 65 6e 74 20 61 70 70  ee different app
7570: 72 6f 61 63 68 65 73 20 74 6f 20 6f 62 74 61 69  roaches to obtai
7580: 6e 69 6e 67 20 73 70 61 63 65 20 66 6f 72 20 61  ning space for a
7590: 20 70 61 67 65 2c 0a 2a 2a 20 64 65 70 65 6e 64   page,.** depend
75a0: 69 6e 67 20 6f 6e 20 74 68 65 20 76 61 6c 75 65  ing on the value
75b0: 20 6f 66 20 70 61 72 61 6d 65 74 65 72 20 63 72   of parameter cr
75c0: 65 61 74 65 46 6c 61 67 20 28 77 68 69 63 68 20  eateFlag (which 
75d0: 6d 61 79 20 62 65 20 30 2c 20 31 20 6f 72 20 32  may be 0, 1 or 2
75e0: 29 2e 0a 2a 2a 0a 2a 2a 20 20 20 31 2e 20 52 65  )..**.**   1. Re
75f0: 67 61 72 64 6c 65 73 73 20 6f 66 20 74 68 65 20  gardless of the 
7600: 76 61 6c 75 65 20 6f 66 20 63 72 65 61 74 65 46  value of createF
7610: 6c 61 67 2c 20 74 68 65 20 63 61 63 68 65 20 69  lag, the cache i
7620: 73 20 73 65 61 72 63 68 65 64 20 66 6f 72 20 61  s searched for a
7630: 20 0a 2a 2a 20 20 20 20 20 20 63 6f 70 79 20 6f   .**      copy o
7640: 66 20 74 68 65 20 72 65 71 75 65 73 74 65 64 20  f the requested 
7650: 70 61 67 65 2e 20 49 66 20 6f 6e 65 20 69 73 20  page. If one is 
7660: 66 6f 75 6e 64 2c 20 69 74 20 69 73 20 72 65 74  found, it is ret
7670: 75 72 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 32  urned..**.**   2
7680: 2e 20 49 66 20 63 72 65 61 74 65 46 6c 61 67 3d  . If createFlag=
7690: 3d 30 20 61 6e 64 20 74 68 65 20 70 61 67 65 20  =0 and the page 
76a0: 69 73 20 6e 6f 74 20 61 6c 72 65 61 64 79 20 69  is not already i
76b0: 6e 20 74 68 65 20 63 61 63 68 65 2c 20 4e 55 4c  n the cache, NUL
76c0: 4c 20 69 73 0a 2a 2a 20 20 20 20 20 20 72 65 74  L is.**      ret
76d0: 75 72 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 33  urned..**.**   3
76e0: 2e 20 49 66 20 63 72 65 61 74 65 46 6c 61 67 20  . If createFlag 
76f0: 69 73 20 31 2c 20 61 6e 64 20 74 68 65 20 70 61  is 1, and the pa
7700: 67 65 20 69 73 20 6e 6f 74 20 61 6c 72 65 61 64  ge is not alread
7710: 79 20 69 6e 20 74 68 65 20 63 61 63 68 65 2c 20  y in the cache, 
7720: 74 68 65 6e 0a 2a 2a 20 20 20 20 20 20 72 65 74  then.**      ret
7730: 75 72 6e 20 4e 55 4c 4c 20 28 64 6f 20 6e 6f 74  urn NULL (do not
7740: 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20   allocate a new 
7750: 70 61 67 65 29 20 69 66 20 61 6e 79 20 6f 66 20  page) if any of 
7760: 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 0a 2a 2a  the following.**
7770: 20 20 20 20 20 20 63 6f 6e 64 69 74 69 6f 6e 73        conditions
7780: 20 61 72 65 20 74 72 75 65 3a 0a 2a 2a 0a 2a 2a   are true:.**.**
7790: 20 20 20 20 20 20 20 28 61 29 20 74 68 65 20 6e         (a) the n
77a0: 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 70  umber of pages p
77b0: 69 6e 6e 65 64 20 62 79 20 74 68 65 20 63 61 63  inned by the cac
77c0: 68 65 20 69 73 20 67 72 65 61 74 65 72 20 74 68  he is greater th
77d0: 61 6e 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20  an.**           
77e0: 50 43 61 63 68 65 31 2e 6e 4d 61 78 2c 20 6f 72  PCache1.nMax, or
77f0: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 28 62 29  .**.**       (b)
7800: 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70   the number of p
7810: 61 67 65 73 20 70 69 6e 6e 65 64 20 62 79 20 74  ages pinned by t
7820: 68 65 20 63 61 63 68 65 20 69 73 20 67 72 65 61  he cache is grea
7830: 74 65 72 20 74 68 61 6e 0a 2a 2a 20 20 20 20 20  ter than.**     
7840: 20 20 20 20 20 20 74 68 65 20 73 75 6d 20 6f 66        the sum of
7850: 20 6e 4d 61 78 20 66 6f 72 20 61 6c 6c 20 70 75   nMax for all pu
7860: 72 67 65 61 62 6c 65 20 63 61 63 68 65 73 2c 20  rgeable caches, 
7870: 6c 65 73 73 20 74 68 65 20 73 75 6d 20 6f 66 20  less the sum of 
7880: 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 6e 4d  .**           nM
7890: 69 6e 20 66 6f 72 20 61 6c 6c 20 6f 74 68 65 72  in for all other
78a0: 20 70 75 72 67 65 61 62 6c 65 20 63 61 63 68 65   purgeable cache
78b0: 73 2c 20 6f 72 0a 2a 2a 0a 2a 2a 20 20 20 34 2e  s, or.**.**   4.
78c0: 20 49 66 20 6e 6f 6e 65 20 6f 66 20 74 68 65 20   If none of the 
78d0: 66 69 72 73 74 20 74 68 72 65 65 20 63 6f 6e 64  first three cond
78e0: 69 74 69 6f 6e 73 20 61 70 70 6c 79 20 61 6e 64  itions apply and
78f0: 20 74 68 65 20 63 61 63 68 65 20 69 73 20 6d 61   the cache is ma
7900: 72 6b 65 64 0a 2a 2a 20 20 20 20 20 20 61 73 20  rked.**      as 
7910: 70 75 72 67 65 61 62 6c 65 2c 20 61 6e 64 20 69  purgeable, and i
7920: 66 20 6f 6e 65 20 6f 66 20 74 68 65 20 66 6f 6c  f one of the fol
7930: 6c 6f 77 69 6e 67 20 69 73 20 74 72 75 65 3a 0a  lowing is true:.
7940: 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 28 61 29 20  **.**       (a) 
7950: 54 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 61  The number of pa
7960: 67 65 73 20 61 6c 6c 6f 63 61 74 65 64 20 66 6f  ges allocated fo
7970: 72 20 74 68 65 20 63 61 63 68 65 20 69 73 20 61  r the cache is a
7980: 6c 72 65 61 64 79 20 0a 2a 2a 20 20 20 20 20 20  lready .**      
7990: 20 20 20 20 20 50 43 61 63 68 65 31 2e 6e 4d 61       PCache1.nMa
79a0: 78 2c 20 6f 72 0a 2a 2a 0a 2a 2a 20 20 20 20 20  x, or.**.**     
79b0: 20 20 28 62 29 20 54 68 65 20 6e 75 6d 62 65 72    (b) The number
79c0: 20 6f 66 20 70 61 67 65 73 20 61 6c 6c 6f 63 61   of pages alloca
79d0: 74 65 64 20 66 6f 72 20 61 6c 6c 20 70 75 72 67  ted for all purg
79e0: 65 61 62 6c 65 20 63 61 63 68 65 73 20 69 73 0a  eable caches is.
79f0: 2a 2a 20 20 20 20 20 20 20 20 20 20 20 61 6c 72  **           alr
7a00: 65 61 64 79 20 65 71 75 61 6c 20 74 6f 20 6f 72  eady equal to or
7a10: 20 67 72 65 61 74 65 72 20 74 68 61 6e 20 74 68   greater than th
7a20: 65 20 73 75 6d 20 6f 66 20 6e 4d 61 78 20 66 6f  e sum of nMax fo
7a30: 72 20 61 6c 6c 0a 2a 2a 20 20 20 20 20 20 20 20  r all.**        
7a40: 20 20 20 70 75 72 67 65 61 62 6c 65 20 63 61 63     purgeable cac
7a50: 68 65 73 2c 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20  hes,.**.**      
7a60: 20 28 63 29 20 54 68 65 20 73 79 73 74 65 6d 20   (c) The system 
7a70: 69 73 20 75 6e 64 65 72 20 6d 65 6d 6f 72 79 20  is under memory 
7a80: 70 72 65 73 73 75 72 65 20 61 6e 64 20 77 61 6e  pressure and wan
7a90: 74 73 20 74 6f 20 61 76 6f 69 64 0a 2a 2a 20 20  ts to avoid.**  
7aa0: 20 20 20 20 20 20 20 20 20 75 6e 6e 65 63 65 73           unneces
7ab0: 73 61 72 79 20 70 61 67 65 73 20 63 61 63 68 65  sary pages cache
7ac0: 20 65 6e 74 72 79 20 61 6c 6c 6f 63 61 74 69 6f   entry allocatio
7ad0: 6e 73 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 74 68  ns.**.**      th
7ae0: 65 6e 20 61 74 74 65 6d 70 74 20 74 6f 20 72 65  en attempt to re
7af0: 63 79 63 6c 65 20 61 20 70 61 67 65 20 66 72 6f  cycle a page fro
7b00: 6d 20 74 68 65 20 4c 52 55 20 6c 69 73 74 2e 20  m the LRU list. 
7b10: 49 66 20 69 74 20 69 73 20 74 68 65 20 72 69 67  If it is the rig
7b20: 68 74 0a 2a 2a 20 20 20 20 20 20 73 69 7a 65 2c  ht.**      size,
7b30: 20 72 65 74 75 72 6e 20 74 68 65 20 72 65 63 79   return the recy
7b40: 63 6c 65 64 20 62 75 66 66 65 72 2e 20 4f 74 68  cled buffer. Oth
7b50: 65 72 77 69 73 65 2c 20 66 72 65 65 20 74 68 65  erwise, free the
7b60: 20 62 75 66 66 65 72 20 61 6e 64 0a 2a 2a 20 20   buffer and.**  
7b70: 20 20 20 20 70 72 6f 63 65 65 64 20 74 6f 20 73      proceed to s
7b80: 74 65 70 20 35 2e 20 0a 2a 2a 0a 2a 2a 20 20 20  tep 5. .**.**   
7b90: 35 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 61 6c  5. Otherwise, al
7ba0: 6c 6f 63 61 74 65 20 61 6e 64 20 72 65 74 75 72  locate and retur
7bb0: 6e 20 61 20 6e 65 77 20 70 61 67 65 20 62 75 66  n a new page buf
7bc0: 66 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  fer..*/.static v
7bd0: 6f 69 64 20 2a 70 63 61 63 68 65 31 46 65 74 63  oid *pcache1Fetc
7be0: 68 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  h(sqlite3_pcache
7bf0: 20 2a 70 2c 20 75 6e 73 69 67 6e 65 64 20 69 6e   *p, unsigned in
7c00: 74 20 69 4b 65 79 2c 20 69 6e 74 20 63 72 65 61  t iKey, int crea
7c10: 74 65 46 6c 61 67 29 7b 0a 20 20 69 6e 74 20 6e  teFlag){.  int n
7c20: 50 69 6e 6e 65 64 3b 0a 20 20 50 43 61 63 68 65  Pinned;.  PCache
7c30: 31 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61  1 *pCache = (PCa
7c40: 63 68 65 31 20 2a 29 70 3b 0a 20 20 50 47 72 6f  che1 *)p;.  PGro
7c50: 75 70 20 2a 70 47 72 6f 75 70 3b 0a 20 20 50 67  up *pGroup;.  Pg
7c60: 48 64 72 31 20 2a 70 50 61 67 65 20 3d 20 30 3b  Hdr1 *pPage = 0;
7c70: 0a 0a 20 20 61 73 73 65 72 74 28 20 70 43 61 63  ..  assert( pCac
7c80: 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 7c  he->bPurgeable |
7c90: 7c 20 63 72 65 61 74 65 46 6c 61 67 21 3d 31 20  | createFlag!=1 
7ca0: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 43 61  );.  assert( pCa
7cb0: 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20  che->bPurgeable 
7cc0: 7c 7c 20 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 3d  || pCache->nMin=
7cd0: 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  =0 );.  assert( 
7ce0: 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62  pCache->bPurgeab
7cf0: 6c 65 3d 3d 30 20 7c 7c 20 70 43 61 63 68 65 2d  le==0 || pCache-
7d00: 3e 6e 4d 69 6e 3d 3d 31 30 20 29 3b 0a 20 20 61  >nMin==10 );.  a
7d10: 73 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e 6e  ssert( pCache->n
7d20: 4d 69 6e 3d 3d 30 20 7c 7c 20 70 43 61 63 68 65  Min==0 || pCache
7d30: 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 29 3b 0a  ->bPurgeable );.
7d40: 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75    pcache1EnterMu
7d50: 74 65 78 28 70 47 72 6f 75 70 20 3d 20 70 43 61  tex(pGroup = pCa
7d60: 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 0a 20  che->pGroup);.. 
7d70: 20 2f 2a 20 53 74 65 70 20 31 3a 20 53 65 61 72   /* Step 1: Sear
7d80: 63 68 20 74 68 65 20 68 61 73 68 20 74 61 62 6c  ch the hash tabl
7d90: 65 20 66 6f 72 20 61 6e 20 65 78 69 73 74 69 6e  e for an existin
7da0: 67 20 65 6e 74 72 79 2e 20 2a 2f 0a 20 20 69 66  g entry. */.  if
7db0: 28 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3e  ( pCache->nHash>
7dc0: 30 20 29 7b 0a 20 20 20 20 75 6e 73 69 67 6e 65  0 ){.    unsigne
7dd0: 64 20 69 6e 74 20 68 20 3d 20 69 4b 65 79 20 25  d int h = iKey %
7de0: 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3b 0a   pCache->nHash;.
7df0: 20 20 20 20 66 6f 72 28 70 50 61 67 65 3d 70 43      for(pPage=pC
7e00: 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b  ache->apHash[h];
7e10: 20 70 50 61 67 65 26 26 70 50 61 67 65 2d 3e 69   pPage&&pPage->i
7e20: 4b 65 79 21 3d 69 4b 65 79 3b 20 70 50 61 67 65  Key!=iKey; pPage
7e30: 3d 70 50 61 67 65 2d 3e 70 4e 65 78 74 29 3b 0a  =pPage->pNext);.
7e40: 20 20 7d 0a 0a 20 20 2f 2a 20 53 74 65 70 20 32    }..  /* Step 2
7e50: 3a 20 41 62 6f 72 74 20 69 66 20 6e 6f 20 65 78  : Abort if no ex
7e60: 69 73 74 69 6e 67 20 70 61 67 65 20 69 73 20 66  isting page is f
7e70: 6f 75 6e 64 20 61 6e 64 20 63 72 65 61 74 65 46  ound and createF
7e80: 6c 61 67 20 69 73 20 30 20 2a 2f 0a 20 20 69 66  lag is 0 */.  if
7e90: 28 20 70 50 61 67 65 20 7c 7c 20 63 72 65 61 74  ( pPage || creat
7ea0: 65 46 6c 61 67 3d 3d 30 20 29 7b 0a 20 20 20 20  eFlag==0 ){.    
7eb0: 70 63 61 63 68 65 31 50 69 6e 50 61 67 65 28 70  pcache1PinPage(p
7ec0: 50 61 67 65 29 3b 0a 20 20 20 20 67 6f 74 6f 20  Page);.    goto 
7ed0: 66 65 74 63 68 5f 6f 75 74 3b 0a 20 20 7d 0a 0a  fetch_out;.  }..
7ee0: 20 20 2f 2a 20 54 68 65 20 70 47 72 6f 75 70 20    /* The pGroup 
7ef0: 6c 6f 63 61 6c 20 76 61 72 69 61 62 6c 65 20 77  local variable w
7f00: 69 6c 6c 20 6e 6f 72 6d 61 6c 6c 79 20 62 65 20  ill normally be 
7f10: 69 6e 69 74 69 61 6c 69 7a 65 64 20 62 79 20 74  initialized by t
7f20: 68 65 0a 20 20 2a 2a 20 70 63 61 63 68 65 31 45  he.  ** pcache1E
7f30: 6e 74 65 72 4d 75 74 65 78 28 29 20 6d 61 63 72  nterMutex() macr
7f40: 6f 20 61 62 6f 76 65 2e 20 20 42 75 74 20 69 66  o above.  But if
7f50: 20 53 51 4c 49 54 45 5f 4d 55 54 45 58 5f 4f 4d   SQLITE_MUTEX_OM
7f60: 49 54 20 69 73 20 64 65 66 69 6e 65 64 2c 0a 20  IT is defined,. 
7f70: 20 2a 2a 20 74 68 65 6e 20 70 63 61 63 68 65 31   ** then pcache1
7f80: 45 6e 74 65 72 4d 75 74 65 78 28 29 20 69 73 20  EnterMutex() is 
7f90: 61 20 6e 6f 2d 6f 70 2c 20 73 6f 20 77 65 20 68  a no-op, so we h
7fa0: 61 76 65 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a  ave to initializ
7fb0: 65 20 74 68 65 0a 20 20 2a 2a 20 6c 6f 63 61 6c  e the.  ** local
7fc0: 20 76 61 72 69 61 62 6c 65 20 68 65 72 65 2e 20   variable here. 
7fd0: 20 44 65 6c 61 79 69 6e 67 20 74 68 65 20 69 6e   Delaying the in
7fe0: 69 74 69 61 6c 69 7a 61 74 69 6f 6e 20 6f 66 20  itialization of 
7ff0: 70 47 72 6f 75 70 20 69 73 20 61 6e 0a 20 20 2a  pGroup is an.  *
8000: 2a 20 6f 70 74 69 6d 69 7a 61 74 69 6f 6e 3a 20  * optimization: 
8010: 20 54 68 65 20 63 6f 6d 6d 6f 6e 20 63 61 73 65   The common case
8020: 20 69 73 20 74 6f 20 65 78 69 74 20 74 68 65 20   is to exit the 
8030: 6d 6f 64 75 6c 65 20 62 65 66 6f 72 65 20 72 65  module before re
8040: 61 63 68 69 6e 67 0a 20 20 2a 2a 20 74 68 69 73  aching.  ** this
8050: 20 70 6f 69 6e 74 2e 0a 20 20 2a 2f 0a 23 69 66   point..  */.#if
8060: 64 65 66 20 53 51 4c 49 54 45 5f 4d 55 54 45 58  def SQLITE_MUTEX
8070: 5f 4f 4d 49 54 0a 20 20 70 47 72 6f 75 70 20 3d  _OMIT.  pGroup =
8080: 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b   pCache->pGroup;
8090: 0a 23 65 6e 64 69 66 0a 0a 0a 20 20 2f 2a 20 53  .#endif...  /* S
80a0: 74 65 70 20 33 3a 20 41 62 6f 72 74 20 69 66 20  tep 3: Abort if 
80b0: 63 72 65 61 74 65 46 6c 61 67 20 69 73 20 31 20  createFlag is 1 
80c0: 62 75 74 20 74 68 65 20 63 61 63 68 65 20 69 73  but the cache is
80d0: 20 6e 65 61 72 6c 79 20 66 75 6c 6c 20 2a 2f 0a   nearly full */.
80e0: 20 20 6e 50 69 6e 6e 65 64 20 3d 20 70 43 61 63    nPinned = pCac
80f0: 68 65 2d 3e 6e 50 61 67 65 20 2d 20 70 43 61 63  he->nPage - pCac
8100: 68 65 2d 3e 6e 52 65 63 79 63 6c 61 62 6c 65 3b  he->nRecyclable;
8110: 0a 20 20 61 73 73 65 72 74 28 20 6e 50 69 6e 6e  .  assert( nPinn
8120: 65 64 3e 3d 30 20 29 3b 0a 20 20 61 73 73 65 72  ed>=0 );.  asser
8130: 74 28 20 70 47 72 6f 75 70 2d 3e 6d 78 50 69 6e  t( pGroup->mxPin
8140: 6e 65 64 20 3d 3d 20 70 47 72 6f 75 70 2d 3e 6e  ned == pGroup->n
8150: 4d 61 78 50 61 67 65 20 2b 20 31 30 20 2d 20 70  MaxPage + 10 - p
8160: 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67 65 20  Group->nMinPage 
8170: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 43 61  );.  assert( pCa
8180: 63 68 65 2d 3e 6e 39 30 70 63 74 20 3d 3d 20 70  che->n90pct == p
8190: 43 61 63 68 65 2d 3e 6e 4d 61 78 2a 39 2f 31 30  Cache->nMax*9/10
81a0: 20 29 3b 0a 20 20 69 66 28 20 63 72 65 61 74 65   );.  if( create
81b0: 46 6c 61 67 3d 3d 31 20 26 26 20 28 0a 20 20 20  Flag==1 && (.   
81c0: 20 20 20 20 20 6e 50 69 6e 6e 65 64 3e 3d 70 47       nPinned>=pG
81d0: 72 6f 75 70 2d 3e 6d 78 50 69 6e 6e 65 64 0a 20  roup->mxPinned. 
81e0: 20 20 20 20 7c 7c 20 6e 50 69 6e 6e 65 64 3e 3d      || nPinned>=
81f0: 28 69 6e 74 29 70 43 61 63 68 65 2d 3e 6e 39 30  (int)pCache->n90
8200: 70 63 74 0a 20 20 20 20 20 7c 7c 20 70 63 61 63  pct.     || pcac
8210: 68 65 31 55 6e 64 65 72 4d 65 6d 6f 72 79 50 72  he1UnderMemoryPr
8220: 65 73 73 75 72 65 28 70 43 61 63 68 65 29 0a 20  essure(pCache). 
8230: 20 29 29 7b 0a 20 20 20 20 67 6f 74 6f 20 66 65   )){.    goto fe
8240: 74 63 68 5f 6f 75 74 3b 0a 20 20 7d 0a 0a 20 20  tch_out;.  }..  
8250: 69 66 28 20 70 43 61 63 68 65 2d 3e 6e 50 61 67  if( pCache->nPag
8260: 65 3e 3d 70 43 61 63 68 65 2d 3e 6e 48 61 73 68  e>=pCache->nHash
8270: 20 26 26 20 70 63 61 63 68 65 31 52 65 73 69 7a   && pcache1Resiz
8280: 65 48 61 73 68 28 70 43 61 63 68 65 29 20 29 7b  eHash(pCache) ){
8290: 0a 20 20 20 20 67 6f 74 6f 20 66 65 74 63 68 5f  .    goto fetch_
82a0: 6f 75 74 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53  out;.  }..  /* S
82b0: 74 65 70 20 34 2e 20 54 72 79 20 74 6f 20 72 65  tep 4. Try to re
82c0: 63 79 63 6c 65 20 61 20 70 61 67 65 2e 20 2a 2f  cycle a page. */
82d0: 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 62  .  if( pCache->b
82e0: 50 75 72 67 65 61 62 6c 65 20 26 26 20 70 47 72  Purgeable && pGr
82f0: 6f 75 70 2d 3e 70 4c 72 75 54 61 69 6c 20 26 26  oup->pLruTail &&
8300: 20 28 0a 20 20 20 20 20 20 20 20 20 28 70 43 61   (.         (pCa
8310: 63 68 65 2d 3e 6e 50 61 67 65 2b 31 3e 3d 70 43  che->nPage+1>=pC
8320: 61 63 68 65 2d 3e 6e 4d 61 78 29 0a 20 20 20 20  ache->nMax).    
8330: 20 20 7c 7c 20 70 47 72 6f 75 70 2d 3e 6e 43 75    || pGroup->nCu
8340: 72 72 65 6e 74 50 61 67 65 3e 3d 70 47 72 6f 75  rrentPage>=pGrou
8350: 70 2d 3e 6e 4d 61 78 50 61 67 65 0a 20 20 20 20  p->nMaxPage.    
8360: 20 20 7c 7c 20 70 63 61 63 68 65 31 55 6e 64 65    || pcache1Unde
8370: 72 4d 65 6d 6f 72 79 50 72 65 73 73 75 72 65 28  rMemoryPressure(
8380: 70 43 61 63 68 65 29 0a 20 20 29 29 7b 0a 20 20  pCache).  )){.  
8390: 20 20 50 43 61 63 68 65 31 20 2a 70 4f 74 68 65    PCache1 *pOthe
83a0: 72 43 61 63 68 65 3b 0a 20 20 20 20 70 50 61 67  rCache;.    pPag
83b0: 65 20 3d 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75  e = pGroup->pLru
83c0: 54 61 69 6c 3b 0a 20 20 20 20 70 63 61 63 68 65  Tail;.    pcache
83d0: 31 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73 68 28  1RemoveFromHash(
83e0: 70 50 61 67 65 29 3b 0a 20 20 20 20 70 63 61 63  pPage);.    pcac
83f0: 68 65 31 50 69 6e 50 61 67 65 28 70 50 61 67 65  he1PinPage(pPage
8400: 29 3b 0a 20 20 20 20 69 66 28 20 28 70 4f 74 68  );.    if( (pOth
8410: 65 72 43 61 63 68 65 20 3d 20 70 50 61 67 65 2d  erCache = pPage-
8420: 3e 70 43 61 63 68 65 29 2d 3e 73 7a 50 61 67 65  >pCache)->szPage
8430: 21 3d 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65  !=pCache->szPage
8440: 20 29 7b 0a 20 20 20 20 20 20 70 63 61 63 68 65   ){.      pcache
8450: 31 46 72 65 65 50 61 67 65 28 70 50 61 67 65 29  1FreePage(pPage)
8460: 3b 0a 20 20 20 20 20 20 70 50 61 67 65 20 3d 20  ;.      pPage = 
8470: 30 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  0;.    }else{.  
8480: 20 20 20 20 70 47 72 6f 75 70 2d 3e 6e 43 75 72      pGroup->nCur
8490: 72 65 6e 74 50 61 67 65 20 2d 3d 20 0a 20 20 20  rentPage -= .   
84a0: 20 20 20 20 20 20 20 20 20 20 20 20 28 70 4f 74              (pOt
84b0: 68 65 72 43 61 63 68 65 2d 3e 62 50 75 72 67 65  herCache->bPurge
84c0: 61 62 6c 65 20 2d 20 70 43 61 63 68 65 2d 3e 62  able - pCache->b
84d0: 50 75 72 67 65 61 62 6c 65 29 3b 0a 20 20 20 20  Purgeable);.    
84e0: 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53 74 65 70  }.  }..  /* Step
84f0: 20 35 2e 20 49 66 20 61 20 75 73 61 62 6c 65 20   5. If a usable 
8500: 70 61 67 65 20 62 75 66 66 65 72 20 68 61 73 20  page buffer has 
8510: 73 74 69 6c 6c 20 6e 6f 74 20 62 65 65 6e 20 66  still not been f
8520: 6f 75 6e 64 2c 20 0a 20 20 2a 2a 20 61 74 74 65  ound, .  ** atte
8530: 6d 70 74 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20  mpt to allocate 
8540: 61 20 6e 65 77 20 6f 6e 65 2e 20 0a 20 20 2a 2f  a new one. .  */
8550: 0a 20 20 69 66 28 20 21 70 50 61 67 65 20 29 7b  .  if( !pPage ){
8560: 0a 20 20 20 20 69 66 28 20 63 72 65 61 74 65 46  .    if( createF
8570: 6c 61 67 3d 3d 31 20 29 20 73 71 6c 69 74 65 33  lag==1 ) sqlite3
8580: 42 65 67 69 6e 42 65 6e 69 67 6e 4d 61 6c 6c 6f  BeginBenignMallo
8590: 63 28 29 3b 0a 20 20 20 20 70 50 61 67 65 20 3d  c();.    pPage =
85a0: 20 70 63 61 63 68 65 31 41 6c 6c 6f 63 50 61 67   pcache1AllocPag
85b0: 65 28 70 43 61 63 68 65 29 3b 0a 20 20 20 20 69  e(pCache);.    i
85c0: 66 28 20 63 72 65 61 74 65 46 6c 61 67 3d 3d 31  f( createFlag==1
85d0: 20 29 20 73 71 6c 69 74 65 33 45 6e 64 42 65 6e   ) sqlite3EndBen
85e0: 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 0a 20 20 7d  ignMalloc();.  }
85f0: 0a 0a 20 20 69 66 28 20 70 50 61 67 65 20 29 7b  ..  if( pPage ){
8600: 0a 20 20 20 20 75 6e 73 69 67 6e 65 64 20 69 6e  .    unsigned in
8610: 74 20 68 20 3d 20 69 4b 65 79 20 25 20 70 43 61  t h = iKey % pCa
8620: 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 20 20  che->nHash;.    
8630: 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 2b 2b 3b  pCache->nPage++;
8640: 0a 20 20 20 20 70 50 61 67 65 2d 3e 69 4b 65 79  .    pPage->iKey
8650: 20 3d 20 69 4b 65 79 3b 0a 20 20 20 20 70 50 61   = iKey;.    pPa
8660: 67 65 2d 3e 70 4e 65 78 74 20 3d 20 70 43 61 63  ge->pNext = pCac
8670: 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 0a 20  he->apHash[h];. 
8680: 20 20 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65     pPage->pCache
8690: 20 3d 20 70 43 61 63 68 65 3b 0a 20 20 20 20 70   = pCache;.    p
86a0: 50 61 67 65 2d 3e 70 4c 72 75 50 72 65 76 20 3d  Page->pLruPrev =
86b0: 20 30 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 70   0;.    pPage->p
86c0: 4c 72 75 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20  LruNext = 0;.   
86d0: 20 2a 28 76 6f 69 64 20 2a 2a 29 28 50 47 48 44   *(void **)(PGHD
86e0: 52 31 5f 54 4f 5f 50 41 47 45 28 70 50 61 67 65  R1_TO_PAGE(pPage
86f0: 29 29 20 3d 20 30 3b 0a 20 20 20 20 70 43 61 63  )) = 0;.    pCac
8700: 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 20 3d 20  he->apHash[h] = 
8710: 70 50 61 67 65 3b 0a 20 20 7d 0a 0a 66 65 74 63  pPage;.  }..fetc
8720: 68 5f 6f 75 74 3a 0a 20 20 69 66 28 20 70 50 61  h_out:.  if( pPa
8730: 67 65 20 26 26 20 69 4b 65 79 3e 70 43 61 63 68  ge && iKey>pCach
8740: 65 2d 3e 69 4d 61 78 4b 65 79 20 29 7b 0a 20 20  e->iMaxKey ){.  
8750: 20 20 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b 65    pCache->iMaxKe
8760: 79 20 3d 20 69 4b 65 79 3b 0a 20 20 7d 0a 20 20  y = iKey;.  }.  
8770: 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65  pcache1LeaveMute
8780: 78 28 70 47 72 6f 75 70 29 3b 0a 20 20 72 65 74  x(pGroup);.  ret
8790: 75 72 6e 20 28 70 50 61 67 65 20 3f 20 50 47 48  urn (pPage ? PGH
87a0: 44 52 31 5f 54 4f 5f 50 41 47 45 28 70 50 61 67  DR1_TO_PAGE(pPag
87b0: 65 29 20 3a 20 30 29 3b 0a 7d 0a 0a 0a 2f 2a 0a  e) : 0);.}.../*.
87c0: 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  ** Implementatio
87d0: 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33  n of the sqlite3
87e0: 5f 70 63 61 63 68 65 2e 78 55 6e 70 69 6e 20 6d  _pcache.xUnpin m
87f0: 65 74 68 6f 64 2e 0a 2a 2a 0a 2a 2a 20 4d 61 72  ethod..**.** Mar
8800: 6b 20 61 20 70 61 67 65 20 61 73 20 75 6e 70 69  k a page as unpi
8810: 6e 6e 65 64 20 28 65 6c 69 67 69 62 6c 65 20 66  nned (eligible f
8820: 6f 72 20 61 73 79 6e 63 68 72 6f 6e 6f 75 73 20  or asynchronous 
8830: 72 65 63 79 63 6c 69 6e 67 29 2e 0a 2a 2f 0a 73  recycling)..*/.s
8840: 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68  tatic void pcach
8850: 65 31 55 6e 70 69 6e 28 73 71 6c 69 74 65 33 5f  e1Unpin(sqlite3_
8860: 70 63 61 63 68 65 20 2a 70 2c 20 76 6f 69 64 20  pcache *p, void 
8870: 2a 70 50 67 2c 20 69 6e 74 20 72 65 75 73 65 55  *pPg, int reuseU
8880: 6e 6c 69 6b 65 6c 79 29 7b 0a 20 20 50 43 61 63  nlikely){.  PCac
8890: 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28 50  he1 *pCache = (P
88a0: 43 61 63 68 65 31 20 2a 29 70 3b 0a 20 20 50 67  Cache1 *)p;.  Pg
88b0: 48 64 72 31 20 2a 70 50 61 67 65 20 3d 20 50 41  Hdr1 *pPage = PA
88c0: 47 45 5f 54 4f 5f 50 47 48 44 52 31 28 70 43 61  GE_TO_PGHDR1(pCa
88d0: 63 68 65 2c 20 70 50 67 29 3b 0a 20 20 50 47 72  che, pPg);.  PGr
88e0: 6f 75 70 20 2a 70 47 72 6f 75 70 20 3d 20 70 43  oup *pGroup = pC
88f0: 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b 0a 20 0a  ache->pGroup;. .
8900: 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65 2d    assert( pPage-
8910: 3e 70 43 61 63 68 65 3d 3d 70 43 61 63 68 65 20  >pCache==pCache 
8920: 29 3b 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65  );.  pcache1Ente
8930: 72 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b 0a  rMutex(pGroup);.
8940: 0a 20 20 2f 2a 20 49 74 20 69 73 20 61 6e 20 65  .  /* It is an e
8950: 72 72 6f 72 20 74 6f 20 63 61 6c 6c 20 74 68 69  rror to call thi
8960: 73 20 66 75 6e 63 74 69 6f 6e 20 69 66 20 74 68  s function if th
8970: 65 20 70 61 67 65 20 69 73 20 61 6c 72 65 61 64  e page is alread
8980: 79 20 0a 20 20 2a 2a 20 70 61 72 74 20 6f 66 20  y .  ** part of 
8990: 74 68 65 20 50 47 72 6f 75 70 20 4c 52 55 20 6c  the PGroup LRU l
89a0: 69 73 74 2e 0a 20 20 2a 2f 0a 20 20 61 73 73 65  ist..  */.  asse
89b0: 72 74 28 20 70 50 61 67 65 2d 3e 70 4c 72 75 50  rt( pPage->pLruP
89c0: 72 65 76 3d 3d 30 20 26 26 20 70 50 61 67 65 2d  rev==0 && pPage-
89d0: 3e 70 4c 72 75 4e 65 78 74 3d 3d 30 20 29 3b 0a  >pLruNext==0 );.
89e0: 20 20 61 73 73 65 72 74 28 20 70 47 72 6f 75 70    assert( pGroup
89f0: 2d 3e 70 4c 72 75 48 65 61 64 21 3d 70 50 61 67  ->pLruHead!=pPag
8a00: 65 20 26 26 20 70 47 72 6f 75 70 2d 3e 70 4c 72  e && pGroup->pLr
8a10: 75 54 61 69 6c 21 3d 70 50 61 67 65 20 29 3b 0a  uTail!=pPage );.
8a20: 0a 20 20 69 66 28 20 72 65 75 73 65 55 6e 6c 69  .  if( reuseUnli
8a30: 6b 65 6c 79 20 7c 7c 20 70 47 72 6f 75 70 2d 3e  kely || pGroup->
8a40: 6e 43 75 72 72 65 6e 74 50 61 67 65 3e 70 47 72  nCurrentPage>pGr
8a50: 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65 20 29 7b  oup->nMaxPage ){
8a60: 0a 20 20 20 20 70 63 61 63 68 65 31 52 65 6d 6f  .    pcache1Remo
8a70: 76 65 46 72 6f 6d 48 61 73 68 28 70 50 61 67 65  veFromHash(pPage
8a80: 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31 46 72  );.    pcache1Fr
8a90: 65 65 50 61 67 65 28 70 50 61 67 65 29 3b 0a 20  eePage(pPage);. 
8aa0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 2f 2a 20 41   }else{.    /* A
8ab0: 64 64 20 74 68 65 20 70 61 67 65 20 74 6f 20 74  dd the page to t
8ac0: 68 65 20 50 47 72 6f 75 70 20 4c 52 55 20 6c 69  he PGroup LRU li
8ad0: 73 74 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 70  st. */.    if( p
8ae0: 47 72 6f 75 70 2d 3e 70 4c 72 75 48 65 61 64 20  Group->pLruHead 
8af0: 29 7b 0a 20 20 20 20 20 20 70 47 72 6f 75 70 2d  ){.      pGroup-
8b00: 3e 70 4c 72 75 48 65 61 64 2d 3e 70 4c 72 75 50  >pLruHead->pLruP
8b10: 72 65 76 20 3d 20 70 50 61 67 65 3b 0a 20 20 20  rev = pPage;.   
8b20: 20 20 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65     pPage->pLruNe
8b30: 78 74 20 3d 20 70 47 72 6f 75 70 2d 3e 70 4c 72  xt = pGroup->pLr
8b40: 75 48 65 61 64 3b 0a 20 20 20 20 20 20 70 47 72  uHead;.      pGr
8b50: 6f 75 70 2d 3e 70 4c 72 75 48 65 61 64 20 3d 20  oup->pLruHead = 
8b60: 70 50 61 67 65 3b 0a 20 20 20 20 7d 65 6c 73 65  pPage;.    }else
8b70: 7b 0a 20 20 20 20 20 20 70 47 72 6f 75 70 2d 3e  {.      pGroup->
8b80: 70 4c 72 75 54 61 69 6c 20 3d 20 70 50 61 67 65  pLruTail = pPage
8b90: 3b 0a 20 20 20 20 20 20 70 47 72 6f 75 70 2d 3e  ;.      pGroup->
8ba0: 70 4c 72 75 48 65 61 64 20 3d 20 70 50 61 67 65  pLruHead = pPage
8bb0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 43 61 63  ;.    }.    pCac
8bc0: 68 65 2d 3e 6e 52 65 63 79 63 6c 61 62 6c 65 2b  he->nRecyclable+
8bd0: 2b 3b 0a 20 20 7d 0a 0a 20 20 70 63 61 63 68 65  +;.  }..  pcache
8be0: 31 4c 65 61 76 65 4d 75 74 65 78 28 70 43 61 63  1LeaveMutex(pCac
8bf0: 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 7d 0a 0a  he->pGroup);.}..
8c00: 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61  /*.** Implementa
8c10: 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69  tion of the sqli
8c20: 74 65 33 5f 70 63 61 63 68 65 2e 78 52 65 6b 65  te3_pcache.xReke
8c30: 79 20 6d 65 74 68 6f 64 2e 20 0a 2a 2f 0a 73 74  y method. .*/.st
8c40: 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65  atic void pcache
8c50: 31 52 65 6b 65 79 28 0a 20 20 73 71 6c 69 74 65  1Rekey(.  sqlite
8c60: 33 5f 70 63 61 63 68 65 20 2a 70 2c 0a 20 20 76  3_pcache *p,.  v
8c70: 6f 69 64 20 2a 70 50 67 2c 0a 20 20 75 6e 73 69  oid *pPg,.  unsi
8c80: 67 6e 65 64 20 69 6e 74 20 69 4f 6c 64 2c 0a 20  gned int iOld,. 
8c90: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4e   unsigned int iN
8ca0: 65 77 0a 29 7b 0a 20 20 50 43 61 63 68 65 31 20  ew.){.  PCache1 
8cb0: 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61 63 68  *pCache = (PCach
8cc0: 65 31 20 2a 29 70 3b 0a 20 20 50 67 48 64 72 31  e1 *)p;.  PgHdr1
8cd0: 20 2a 70 50 61 67 65 20 3d 20 50 41 47 45 5f 54   *pPage = PAGE_T
8ce0: 4f 5f 50 47 48 44 52 31 28 70 43 61 63 68 65 2c  O_PGHDR1(pCache,
8cf0: 20 70 50 67 29 3b 0a 20 20 50 67 48 64 72 31 20   pPg);.  PgHdr1 
8d00: 2a 2a 70 70 3b 0a 20 20 75 6e 73 69 67 6e 65 64  **pp;.  unsigned
8d10: 20 69 6e 74 20 68 3b 20 0a 20 20 61 73 73 65 72   int h; .  asser
8d20: 74 28 20 70 50 61 67 65 2d 3e 69 4b 65 79 3d 3d  t( pPage->iKey==
8d30: 69 4f 6c 64 20 29 3b 0a 20 20 61 73 73 65 72 74  iOld );.  assert
8d40: 28 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65 3d  ( pPage->pCache=
8d50: 3d 70 43 61 63 68 65 20 29 3b 0a 0a 20 20 70 63  =pCache );..  pc
8d60: 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28  ache1EnterMutex(
8d70: 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b  pCache->pGroup);
8d80: 0a 0a 20 20 68 20 3d 20 69 4f 6c 64 25 70 43 61  ..  h = iOld%pCa
8d90: 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 70 70  che->nHash;.  pp
8da0: 20 3d 20 26 70 43 61 63 68 65 2d 3e 61 70 48 61   = &pCache->apHa
8db0: 73 68 5b 68 5d 3b 0a 20 20 77 68 69 6c 65 28 20  sh[h];.  while( 
8dc0: 28 2a 70 70 29 21 3d 70 50 61 67 65 20 29 7b 0a  (*pp)!=pPage ){.
8dd0: 20 20 20 20 70 70 20 3d 20 26 28 2a 70 70 29 2d      pp = &(*pp)-
8de0: 3e 70 4e 65 78 74 3b 0a 20 20 7d 0a 20 20 2a 70  >pNext;.  }.  *p
8df0: 70 20 3d 20 70 50 61 67 65 2d 3e 70 4e 65 78 74  p = pPage->pNext
8e00: 3b 0a 0a 20 20 68 20 3d 20 69 4e 65 77 25 70 43  ;..  h = iNew%pC
8e10: 61 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 70  ache->nHash;.  p
8e20: 50 61 67 65 2d 3e 69 4b 65 79 20 3d 20 69 4e 65  Page->iKey = iNe
8e30: 77 3b 0a 20 20 70 50 61 67 65 2d 3e 70 4e 65 78  w;.  pPage->pNex
8e40: 74 20 3d 20 70 43 61 63 68 65 2d 3e 61 70 48 61  t = pCache->apHa
8e50: 73 68 5b 68 5d 3b 0a 20 20 70 43 61 63 68 65 2d  sh[h];.  pCache-
8e60: 3e 61 70 48 61 73 68 5b 68 5d 20 3d 20 70 50 61  >apHash[h] = pPa
8e70: 67 65 3b 0a 20 20 69 66 28 20 69 4e 65 77 3e 70  ge;.  if( iNew>p
8e80: 43 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 29  Cache->iMaxKey )
8e90: 7b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 69 4d  {.    pCache->iM
8ea0: 61 78 4b 65 79 20 3d 20 69 4e 65 77 3b 0a 20 20  axKey = iNew;.  
8eb0: 7d 0a 0a 20 20 70 63 61 63 68 65 31 4c 65 61 76  }..  pcache1Leav
8ec0: 65 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e 70  eMutex(pCache->p
8ed0: 47 72 6f 75 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  Group);.}../*.**
8ee0: 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20   Implementation 
8ef0: 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70  of the sqlite3_p
8f00: 63 61 63 68 65 2e 78 54 72 75 6e 63 61 74 65 20  cache.xTruncate 
8f10: 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20 44  method. .**.** D
8f20: 69 73 63 61 72 64 20 61 6c 6c 20 75 6e 70 69 6e  iscard all unpin
8f30: 6e 65 64 20 70 61 67 65 73 20 69 6e 20 74 68 65  ned pages in the
8f40: 20 63 61 63 68 65 20 77 69 74 68 20 61 20 70 61   cache with a pa
8f50: 67 65 20 6e 75 6d 62 65 72 20 65 71 75 61 6c 20  ge number equal 
8f60: 74 6f 0a 2a 2a 20 6f 72 20 67 72 65 61 74 65 72  to.** or greater
8f70: 20 74 68 61 6e 20 70 61 72 61 6d 65 74 65 72 20   than parameter 
8f80: 69 4c 69 6d 69 74 2e 20 41 6e 79 20 70 69 6e 6e  iLimit. Any pinn
8f90: 65 64 20 70 61 67 65 73 20 77 69 74 68 20 61 20  ed pages with a 
8fa0: 70 61 67 65 20 6e 75 6d 62 65 72 0a 2a 2a 20 65  page number.** e
8fb0: 71 75 61 6c 20 74 6f 20 6f 72 20 67 72 65 61 74  qual to or great
8fc0: 65 72 20 74 68 61 6e 20 69 4c 69 6d 69 74 20 61  er than iLimit a
8fd0: 72 65 20 69 6d 70 6c 69 63 69 74 6c 79 20 75 6e  re implicitly un
8fe0: 70 69 6e 6e 65 64 2e 0a 2a 2f 0a 73 74 61 74 69  pinned..*/.stati
8ff0: 63 20 76 6f 69 64 20 70 63 61 63 68 65 31 54 72  c void pcache1Tr
9000: 75 6e 63 61 74 65 28 73 71 6c 69 74 65 33 5f 70  uncate(sqlite3_p
9010: 63 61 63 68 65 20 2a 70 2c 20 75 6e 73 69 67 6e  cache *p, unsign
9020: 65 64 20 69 6e 74 20 69 4c 69 6d 69 74 29 7b 0a  ed int iLimit){.
9030: 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68    PCache1 *pCach
9040: 65 20 3d 20 28 50 43 61 63 68 65 31 20 2a 29 70  e = (PCache1 *)p
9050: 3b 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65 72  ;.  pcache1Enter
9060: 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e 70 47  Mutex(pCache->pG
9070: 72 6f 75 70 29 3b 0a 20 20 69 66 28 20 69 4c 69  roup);.  if( iLi
9080: 6d 69 74 3c 3d 70 43 61 63 68 65 2d 3e 69 4d 61  mit<=pCache->iMa
9090: 78 4b 65 79 20 29 7b 0a 20 20 20 20 70 63 61 63  xKey ){.    pcac
90a0: 68 65 31 54 72 75 6e 63 61 74 65 55 6e 73 61 66  he1TruncateUnsaf
90b0: 65 28 70 43 61 63 68 65 2c 20 69 4c 69 6d 69 74  e(pCache, iLimit
90c0: 29 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 69  );.    pCache->i
90d0: 4d 61 78 4b 65 79 20 3d 20 69 4c 69 6d 69 74 2d  MaxKey = iLimit-
90e0: 31 3b 0a 20 20 7d 0a 20 20 70 63 61 63 68 65 31  1;.  }.  pcache1
90f0: 4c 65 61 76 65 4d 75 74 65 78 28 70 43 61 63 68  LeaveMutex(pCach
9100: 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 7d 0a 0a 2f  e->pGroup);.}../
9110: 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74  *.** Implementat
9120: 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74  ion of the sqlit
9130: 65 33 5f 70 63 61 63 68 65 2e 78 44 65 73 74 72  e3_pcache.xDestr
9140: 6f 79 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a  oy method. .**.*
9150: 2a 20 44 65 73 74 72 6f 79 20 61 20 63 61 63 68  * Destroy a cach
9160: 65 20 61 6c 6c 6f 63 61 74 65 64 20 75 73 69 6e  e allocated usin
9170: 67 20 70 63 61 63 68 65 31 43 72 65 61 74 65 28  g pcache1Create(
9180: 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  )..*/.static voi
9190: 64 20 70 63 61 63 68 65 31 44 65 73 74 72 6f 79  d pcache1Destroy
91a0: 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20  (sqlite3_pcache 
91b0: 2a 70 29 7b 0a 20 20 50 43 61 63 68 65 31 20 2a  *p){.  PCache1 *
91c0: 70 43 61 63 68 65 20 3d 20 28 50 43 61 63 68 65  pCache = (PCache
91d0: 31 20 2a 29 70 3b 0a 20 20 50 47 72 6f 75 70 20  1 *)p;.  PGroup 
91e0: 2a 70 47 72 6f 75 70 20 3d 20 70 43 61 63 68 65  *pGroup = pCache
91f0: 2d 3e 70 47 72 6f 75 70 3b 0a 20 20 61 73 73 65  ->pGroup;.  asse
9200: 72 74 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72  rt( pCache->bPur
9210: 67 65 61 62 6c 65 20 7c 7c 20 28 70 43 61 63 68  geable || (pCach
9220: 65 2d 3e 6e 4d 61 78 3d 3d 30 20 26 26 20 70 43  e->nMax==0 && pC
9230: 61 63 68 65 2d 3e 6e 4d 69 6e 3d 3d 30 29 20 29  ache->nMin==0) )
9240: 3b 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65 72  ;.  pcache1Enter
9250: 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b 0a 20  Mutex(pGroup);. 
9260: 20 70 63 61 63 68 65 31 54 72 75 6e 63 61 74 65   pcache1Truncate
9270: 55 6e 73 61 66 65 28 70 43 61 63 68 65 2c 20 30  Unsafe(pCache, 0
9280: 29 3b 0a 20 20 70 47 72 6f 75 70 2d 3e 6e 4d 61  );.  pGroup->nMa
9290: 78 50 61 67 65 20 2d 3d 20 70 43 61 63 68 65 2d  xPage -= pCache-
92a0: 3e 6e 4d 61 78 3b 0a 20 20 70 47 72 6f 75 70 2d  >nMax;.  pGroup-
92b0: 3e 6e 4d 69 6e 50 61 67 65 20 2d 3d 20 70 43 61  >nMinPage -= pCa
92c0: 63 68 65 2d 3e 6e 4d 69 6e 3b 0a 20 20 70 47 72  che->nMin;.  pGr
92d0: 6f 75 70 2d 3e 6d 78 50 69 6e 6e 65 64 20 3d 20  oup->mxPinned = 
92e0: 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65  pGroup->nMaxPage
92f0: 20 2b 20 31 30 20 2d 20 70 47 72 6f 75 70 2d 3e   + 10 - pGroup->
9300: 6e 4d 69 6e 50 61 67 65 3b 0a 20 20 70 63 61 63  nMinPage;.  pcac
9310: 68 65 31 45 6e 66 6f 72 63 65 4d 61 78 50 61 67  he1EnforceMaxPag
9320: 65 28 70 47 72 6f 75 70 29 3b 0a 20 20 70 63 61  e(pGroup);.  pca
9330: 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 70  che1LeaveMutex(p
9340: 47 72 6f 75 70 29 3b 0a 20 20 73 71 6c 69 74 65  Group);.  sqlite
9350: 33 5f 66 72 65 65 28 70 43 61 63 68 65 2d 3e 61  3_free(pCache->a
9360: 70 48 61 73 68 29 3b 0a 20 20 73 71 6c 69 74 65  pHash);.  sqlite
9370: 33 5f 66 72 65 65 28 70 43 61 63 68 65 29 3b 0a  3_free(pCache);.
9380: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75  }../*.** This fu
9390: 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64  nction is called
93a0: 20 64 75 72 69 6e 67 20 69 6e 69 74 69 61 6c 69   during initiali
93b0: 7a 61 74 69 6f 6e 20 28 73 71 6c 69 74 65 33 5f  zation (sqlite3_
93c0: 69 6e 69 74 69 61 6c 69 7a 65 28 29 29 20 74 6f  initialize()) to
93d0: 0a 2a 2a 20 69 6e 73 74 61 6c 6c 20 74 68 65 20  .** install the 
93e0: 64 65 66 61 75 6c 74 20 70 6c 75 67 67 61 62 6c  default pluggabl
93f0: 65 20 63 61 63 68 65 20 6d 6f 64 75 6c 65 2c 20  e cache module, 
9400: 61 73 73 75 6d 69 6e 67 20 74 68 65 20 75 73 65  assuming the use
9410: 72 20 68 61 73 20 6e 6f 74 0a 2a 2a 20 61 6c 72  r has not.** alr
9420: 65 61 64 79 20 70 72 6f 76 69 64 65 64 20 61 6e  eady provided an
9430: 20 61 6c 74 65 72 6e 61 74 69 76 65 2e 0a 2a 2f   alternative..*/
9440: 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 43 61  .void sqlite3PCa
9450: 63 68 65 53 65 74 44 65 66 61 75 6c 74 28 76 6f  cheSetDefault(vo
9460: 69 64 29 7b 0a 20 20 73 74 61 74 69 63 20 63 6f  id){.  static co
9470: 6e 73 74 20 73 71 6c 69 74 65 33 5f 70 63 61 63  nst sqlite3_pcac
9480: 68 65 5f 6d 65 74 68 6f 64 73 20 64 65 66 61 75  he_methods defau
9490: 6c 74 4d 65 74 68 6f 64 73 20 3d 20 7b 0a 20 20  ltMethods = {.  
94a0: 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20    0,            
94b0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 70 41             /* pA
94c0: 72 67 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65  rg */.    pcache
94d0: 31 49 6e 69 74 2c 20 20 20 20 20 20 20 20 20 20  1Init,          
94e0: 20 20 20 2f 2a 20 78 49 6e 69 74 20 2a 2f 0a 20     /* xInit */. 
94f0: 20 20 20 70 63 61 63 68 65 31 53 68 75 74 64 6f     pcache1Shutdo
9500: 77 6e 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 78  wn,         /* x
9510: 53 68 75 74 64 6f 77 6e 20 2a 2f 0a 20 20 20 20  Shutdown */.    
9520: 70 63 61 63 68 65 31 43 72 65 61 74 65 2c 20 20  pcache1Create,  
9530: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43 72 65           /* xCre
9540: 61 74 65 20 2a 2f 0a 20 20 20 20 70 63 61 63 68  ate */.    pcach
9550: 65 31 43 61 63 68 65 73 69 7a 65 2c 20 20 20 20  e1Cachesize,    
9560: 20 20 20 20 2f 2a 20 78 43 61 63 68 65 73 69 7a      /* xCachesiz
9570: 65 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31  e */.    pcache1
9580: 50 61 67 65 63 6f 75 6e 74 2c 20 20 20 20 20 20  Pagecount,      
9590: 20 20 2f 2a 20 78 50 61 67 65 63 6f 75 6e 74 20    /* xPagecount 
95a0: 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31 46 65  */.    pcache1Fe
95b0: 74 63 68 2c 20 20 20 20 20 20 20 20 20 20 20 20  tch,            
95c0: 2f 2a 20 78 46 65 74 63 68 20 2a 2f 0a 20 20 20  /* xFetch */.   
95d0: 20 70 63 61 63 68 65 31 55 6e 70 69 6e 2c 20 20   pcache1Unpin,  
95e0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 55 6e            /* xUn
95f0: 70 69 6e 20 2a 2f 0a 20 20 20 20 70 63 61 63 68  pin */.    pcach
9600: 65 31 52 65 6b 65 79 2c 20 20 20 20 20 20 20 20  e1Rekey,        
9610: 20 20 20 20 2f 2a 20 78 52 65 6b 65 79 20 2a 2f      /* xRekey */
9620: 0a 20 20 20 20 70 63 61 63 68 65 31 54 72 75 6e  .    pcache1Trun
9630: 63 61 74 65 2c 20 20 20 20 20 20 20 20 20 2f 2a  cate,         /*
9640: 20 78 54 72 75 6e 63 61 74 65 20 2a 2f 0a 20 20   xTruncate */.  
9650: 20 20 70 63 61 63 68 65 31 44 65 73 74 72 6f 79    pcache1Destroy
9660: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44             /* xD
9670: 65 73 74 72 6f 79 20 2a 2f 0a 20 20 7d 3b 0a 20  estroy */.  };. 
9680: 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67 28   sqlite3_config(
9690: 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 43  SQLITE_CONFIG_PC
96a0: 41 43 48 45 2c 20 26 64 65 66 61 75 6c 74 4d 65  ACHE, &defaultMe
96b0: 74 68 6f 64 73 29 3b 0a 7d 0a 0a 23 69 66 64 65  thods);.}..#ifde
96c0: 66 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f  f SQLITE_ENABLE_
96d0: 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e  MEMORY_MANAGEMEN
96e0: 54 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e  T./*.** This fun
96f0: 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20  ction is called 
9700: 74 6f 20 66 72 65 65 20 73 75 70 65 72 66 6c 75  to free superflu
9710: 6f 75 73 20 64 79 6e 61 6d 69 63 61 6c 6c 79 20  ous dynamically 
9720: 61 6c 6c 6f 63 61 74 65 64 20 6d 65 6d 6f 72 79  allocated memory
9730: 0a 2a 2a 20 68 65 6c 64 20 62 79 20 74 68 65 20  .** held by the 
9740: 70 61 67 65 72 20 73 79 73 74 65 6d 2e 20 4d 65  pager system. Me
9750: 6d 6f 72 79 20 69 6e 20 75 73 65 20 62 79 20 61  mory in use by a
9760: 6e 79 20 53 51 4c 69 74 65 20 70 61 67 65 72 20  ny SQLite pager 
9770: 61 6c 6c 6f 63 61 74 65 64 0a 2a 2a 20 62 79 20  allocated.** by 
9780: 74 68 65 20 63 75 72 72 65 6e 74 20 74 68 72 65  the current thre
9790: 61 64 20 6d 61 79 20 62 65 20 73 71 6c 69 74 65  ad may be sqlite
97a0: 33 5f 66 72 65 65 28 29 65 64 2e 0a 2a 2a 0a 2a  3_free()ed..**.*
97b0: 2a 20 6e 52 65 71 20 69 73 20 74 68 65 20 6e 75  * nReq is the nu
97c0: 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 6f 66  mber of bytes of
97d0: 20 6d 65 6d 6f 72 79 20 72 65 71 75 69 72 65 64   memory required
97e0: 2e 20 4f 6e 63 65 20 74 68 69 73 20 6d 75 63 68  . Once this much
97f0: 20 68 61 73 0a 2a 2a 20 62 65 65 6e 20 72 65 6c   has.** been rel
9800: 65 61 73 65 64 2c 20 74 68 65 20 66 75 6e 63 74  eased, the funct
9810: 69 6f 6e 20 72 65 74 75 72 6e 73 2e 20 54 68 65  ion returns. The
9820: 20 72 65 74 75 72 6e 20 76 61 6c 75 65 20 69 73   return value is
9830: 20 74 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65   the total numbe
9840: 72 20 0a 2a 2a 20 6f 66 20 62 79 74 65 73 20 6f  r .** of bytes o
9850: 66 20 6d 65 6d 6f 72 79 20 72 65 6c 65 61 73 65  f memory release
9860: 64 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  d..*/.int sqlite
9870: 33 50 63 61 63 68 65 52 65 6c 65 61 73 65 4d 65  3PcacheReleaseMe
9880: 6d 6f 72 79 28 69 6e 74 20 6e 52 65 71 29 7b 0a  mory(int nReq){.
9890: 20 20 69 6e 74 20 6e 46 72 65 65 20 3d 20 30 3b    int nFree = 0;
98a0: 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74  .  assert( sqlit
98b0: 65 33 5f 6d 75 74 65 78 5f 6e 6f 74 68 65 6c 64  e3_mutex_notheld
98c0: 28 70 63 61 63 68 65 31 2e 67 72 70 2e 6d 75 74  (pcache1.grp.mut
98d0: 65 78 29 20 29 3b 0a 20 20 61 73 73 65 72 74 28  ex) );.  assert(
98e0: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6e   sqlite3_mutex_n
98f0: 6f 74 68 65 6c 64 28 70 63 61 63 68 65 31 2e 6d  otheld(pcache1.m
9900: 75 74 65 78 29 20 29 3b 0a 20 20 69 66 28 20 70  utex) );.  if( p
9910: 63 61 63 68 65 31 2e 70 53 74 61 72 74 3d 3d 30  cache1.pStart==0
9920: 20 29 7b 0a 20 20 20 20 50 67 48 64 72 31 20 2a   ){.    PgHdr1 *
9930: 70 3b 0a 20 20 20 20 70 63 61 63 68 65 31 45 6e  p;.    pcache1En
9940: 74 65 72 4d 75 74 65 78 28 26 70 63 61 63 68 65  terMutex(&pcache
9950: 31 2e 67 72 70 29 3b 0a 20 20 20 20 77 68 69 6c  1.grp);.    whil
9960: 65 28 20 28 6e 52 65 71 3c 30 20 7c 7c 20 6e 46  e( (nReq<0 || nF
9970: 72 65 65 3c 6e 52 65 71 29 20 26 26 20 28 28 70  ree<nReq) && ((p
9980: 3d 70 63 61 63 68 65 31 2e 67 72 70 2e 70 4c 72  =pcache1.grp.pLr
9990: 75 54 61 69 6c 29 21 3d 30 29 20 29 7b 0a 20 20  uTail)!=0) ){.  
99a0: 20 20 20 20 6e 46 72 65 65 20 2b 3d 20 70 63 61      nFree += pca
99b0: 63 68 65 31 4d 65 6d 53 69 7a 65 28 50 47 48 44  che1MemSize(PGHD
99c0: 52 31 5f 54 4f 5f 50 41 47 45 28 70 29 29 3b 0a  R1_TO_PAGE(p));.
99d0: 20 20 20 20 20 20 70 63 61 63 68 65 31 50 69 6e        pcache1Pin
99e0: 50 61 67 65 28 70 29 3b 0a 20 20 20 20 20 20 70  Page(p);.      p
99f0: 63 61 63 68 65 31 52 65 6d 6f 76 65 46 72 6f 6d  cache1RemoveFrom
9a00: 48 61 73 68 28 70 29 3b 0a 20 20 20 20 20 20 70  Hash(p);.      p
9a10: 63 61 63 68 65 31 46 72 65 65 50 61 67 65 28 70  cache1FreePage(p
9a20: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 63 61  );.    }.    pca
9a30: 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 26  che1LeaveMutex(&
9a40: 70 63 61 63 68 65 31 2e 67 72 70 29 3b 0a 20 20  pcache1.grp);.  
9a50: 7d 0a 20 20 72 65 74 75 72 6e 20 6e 46 72 65 65  }.  return nFree
9a60: 3b 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51  ;.}.#endif /* SQ
9a70: 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f  LITE_ENABLE_MEMO
9a80: 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 20 2a 2f  RY_MANAGEMENT */
9a90: 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f  ..#ifdef SQLITE_
9aa0: 54 45 53 54 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  TEST./*.** This 
9ab0: 66 75 6e 63 74 69 6f 6e 20 69 73 20 75 73 65 64  function is used
9ac0: 20 62 79 20 74 65 73 74 20 70 72 6f 63 65 64 75   by test procedu
9ad0: 72 65 73 20 74 6f 20 69 6e 73 70 65 63 74 20 74  res to inspect t
9ae0: 68 65 20 69 6e 74 65 72 6e 61 6c 20 73 74 61 74  he internal stat
9af0: 65 0a 2a 2a 20 6f 66 20 74 68 65 20 67 6c 6f 62  e.** of the glob
9b00: 61 6c 20 63 61 63 68 65 2e 0a 2a 2f 0a 76 6f 69  al cache..*/.voi
9b10: 64 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 53  d sqlite3PcacheS
9b20: 74 61 74 73 28 0a 20 20 69 6e 74 20 2a 70 6e 43  tats(.  int *pnC
9b30: 75 72 72 65 6e 74 2c 20 20 20 20 20 20 2f 2a 20  urrent,      /* 
9b40: 4f 55 54 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65  OUT: Total numbe
9b50: 72 20 6f 66 20 70 61 67 65 73 20 63 61 63 68 65  r of pages cache
9b60: 64 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 4d 61  d */.  int *pnMa
9b70: 78 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f  x,          /* O
9b80: 55 54 3a 20 47 6c 6f 62 61 6c 20 6d 61 78 69 6d  UT: Global maxim
9b90: 75 6d 20 63 61 63 68 65 20 73 69 7a 65 20 2a 2f  um cache size */
9ba0: 0a 20 20 69 6e 74 20 2a 70 6e 4d 69 6e 2c 20 20  .  int *pnMin,  
9bb0: 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
9bc0: 53 75 6d 20 6f 66 20 50 43 61 63 68 65 31 2e 6e  Sum of PCache1.n
9bd0: 4d 69 6e 20 66 6f 72 20 70 75 72 67 65 61 62 6c  Min for purgeabl
9be0: 65 20 63 61 63 68 65 73 20 2a 2f 0a 20 20 69 6e  e caches */.  in
9bf0: 74 20 2a 70 6e 52 65 63 79 63 6c 61 62 6c 65 20  t *pnRecyclable 
9c00: 20 20 20 2f 2a 20 4f 55 54 3a 20 54 6f 74 61 6c     /* OUT: Total
9c10: 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73   number of pages
9c20: 20 61 76 61 69 6c 61 62 6c 65 20 66 6f 72 20 72   available for r
9c30: 65 63 79 63 6c 69 6e 67 20 2a 2f 0a 29 7b 0a 20  ecycling */.){. 
9c40: 20 50 67 48 64 72 31 20 2a 70 3b 0a 20 20 69 6e   PgHdr1 *p;.  in
9c50: 74 20 6e 52 65 63 79 63 6c 61 62 6c 65 20 3d 20  t nRecyclable = 
9c60: 30 3b 0a 20 20 66 6f 72 28 70 3d 70 63 61 63 68  0;.  for(p=pcach
9c70: 65 31 2e 67 72 70 2e 70 4c 72 75 48 65 61 64 3b  e1.grp.pLruHead;
9c80: 20 70 3b 20 70 3d 70 2d 3e 70 4c 72 75 4e 65 78   p; p=p->pLruNex
9c90: 74 29 7b 0a 20 20 20 20 6e 52 65 63 79 63 6c 61  t){.    nRecycla
9ca0: 62 6c 65 2b 2b 3b 0a 20 20 7d 0a 20 20 2a 70 6e  ble++;.  }.  *pn
9cb0: 43 75 72 72 65 6e 74 20 3d 20 70 63 61 63 68 65  Current = pcache
9cc0: 31 2e 67 72 70 2e 6e 43 75 72 72 65 6e 74 50 61  1.grp.nCurrentPa
9cd0: 67 65 3b 0a 20 20 2a 70 6e 4d 61 78 20 3d 20 70  ge;.  *pnMax = p
9ce0: 63 61 63 68 65 31 2e 67 72 70 2e 6e 4d 61 78 50  cache1.grp.nMaxP
9cf0: 61 67 65 3b 0a 20 20 2a 70 6e 4d 69 6e 20 3d 20  age;.  *pnMin = 
9d00: 70 63 61 63 68 65 31 2e 67 72 70 2e 6e 4d 69 6e  pcache1.grp.nMin
9d10: 50 61 67 65 3b 0a 20 20 2a 70 6e 52 65 63 79 63  Page;.  *pnRecyc
9d20: 6c 61 62 6c 65 20 3d 20 6e 52 65 63 79 63 6c 61  lable = nRecycla
9d30: 62 6c 65 3b 0a 7d 0a 23 65 6e 64 69 66 0a        ble;.}.#endif.