/ Hex Artifact Content
Login

Artifact c8982f7048a70b7fd37975a8f6c84d6bc294175a:


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 23 69 66 64 65 66 20 53 51 4c 49 54 45  */.#ifdef SQLITE
0930: 5f 50 41 47 45 43 41 43 48 45 5f 42 4c 4f 43 4b  _PAGECACHE_BLOCK
0940: 41 4c 4c 4f 43 0a 20 20 69 6e 74 20 69 73 42 75  ALLOC.  int isBu
0950: 73 79 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  sy;             
0960: 20 20 20 20 20 20 20 2f 2a 20 44 6f 20 6e 6f 74         /* Do not
0970: 20 72 75 6e 20 52 65 6c 65 61 73 65 4d 65 6d 6f   run ReleaseMemo
0980: 72 79 28 29 20 69 66 20 74 72 75 65 20 2a 2f 0a  ry() if true */.
0990: 20 20 50 47 72 6f 75 70 42 6c 6f 63 6b 4c 69 73    PGroupBlockLis
09a0: 74 20 2a 70 42 6c 6f 63 6b 4c 69 73 74 3b 20 20  t *pBlockList;  
09b0: 20 2f 2a 20 4c 69 73 74 20 6f 66 20 62 6c 6f 63   /* List of bloc
09c0: 6b 2d 6c 69 73 74 73 20 66 6f 72 20 74 68 69 73  k-lists for this
09d0: 20 67 72 6f 75 70 20 2a 2f 0a 23 65 6e 64 69 66   group */.#endif
09e0: 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 53 51  .};../*.** If SQ
09f0: 4c 49 54 45 5f 50 41 47 45 43 41 43 48 45 5f 42  LITE_PAGECACHE_B
0a00: 4c 4f 43 4b 41 4c 4c 4f 43 20 69 73 20 64 65 66  LOCKALLOC is def
0a10: 69 6e 65 64 20 77 68 65 6e 20 74 68 65 20 6c 69  ined when the li
0a20: 62 72 61 72 79 20 69 73 20 62 75 69 6c 74 2c 0a  brary is built,.
0a30: 2a 2a 20 65 61 63 68 20 50 47 72 6f 75 70 20 73  ** each PGroup s
0a40: 74 72 75 63 74 75 72 65 20 68 61 73 20 61 20 6c  tructure has a l
0a50: 69 6e 6b 65 64 20 6c 69 73 74 20 6f 66 20 74 68  inked list of th
0a60: 65 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20  e the following 
0a70: 73 74 61 72 74 69 6e 67 0a 2a 2a 20 61 74 20 50  starting.** at P
0a80: 47 72 6f 75 70 2e 70 42 6c 6f 63 6b 4c 69 73 74  Group.pBlockList
0a90: 2e 20 54 68 65 72 65 20 69 73 20 6f 6e 65 20 65  . There is one e
0aa0: 6e 74 72 79 20 66 6f 72 20 65 61 63 68 20 64 69  ntry for each di
0ab0: 73 74 69 6e 63 74 20 70 61 67 65 2d 73 69 7a 65  stinct page-size
0ac0: 20 0a 2a 2a 20 63 75 72 72 65 6e 74 6c 79 20 75   .** currently u
0ad0: 73 65 64 20 62 79 20 6d 65 6d 62 65 72 73 20 6f  sed by members o
0ae0: 66 20 74 68 65 20 50 47 72 6f 75 70 20 28 69 2e  f the PGroup (i.
0af0: 65 2e 20 31 30 32 34 20 62 79 74 65 73 2c 20 34  e. 1024 bytes, 4
0b00: 30 39 36 20 62 79 74 65 73 0a 2a 2a 20 65 74 63  096 bytes.** etc
0b10: 2e 29 2e 20 56 61 72 69 61 62 6c 65 20 50 47 72  .). Variable PGr
0b20: 6f 75 70 42 6c 6f 63 6b 4c 69 73 74 2e 6e 42 79  oupBlockList.nBy
0b30: 74 65 20 69 73 20 73 65 74 20 74 6f 20 74 68 65  te is set to the
0b40: 20 61 63 74 75 61 6c 20 61 6c 6c 6f 63 61 74 69   actual allocati
0b50: 6f 6e 0a 2a 2a 20 73 69 7a 65 20 72 65 71 75 65  on.** size reque
0b60: 73 74 65 64 20 62 79 20 65 61 63 68 20 70 63 61  sted by each pca
0b70: 63 68 65 2c 20 77 68 69 63 68 20 69 73 20 74 68  che, which is th
0b80: 65 20 64 61 74 61 62 61 73 65 20 70 61 67 65 2d  e database page-
0b90: 73 69 7a 65 20 70 6c 75 73 0a 2a 2a 20 74 68 65  size plus.** the
0ba0: 20 76 61 72 69 6f 75 73 20 68 65 61 64 65 72 20   various header 
0bb0: 73 74 72 75 63 74 75 72 65 73 20 75 73 65 64 20  structures used 
0bc0: 62 79 20 74 68 65 20 70 63 61 63 68 65 2c 20 70  by the pcache, p
0bd0: 61 67 65 72 20 61 6e 64 20 62 74 72 65 65 20 6c  ager and btree l
0be0: 61 79 65 72 73 2e 0a 2a 2a 20 55 73 75 61 6c 6c  ayers..** Usuall
0bf0: 79 20 61 72 6f 75 6e 64 20 28 70 67 73 7a 2b 32  y around (pgsz+2
0c00: 30 30 29 20 62 79 74 65 73 2e 0a 2a 2a 0a 2a 2a  00) bytes..**.**
0c10: 20 54 68 69 73 20 73 69 7a 65 20 28 70 67 73 7a   This size (pgsz
0c20: 2b 32 30 30 29 20 62 79 74 65 73 20 69 73 20 6e  +200) bytes is n
0c30: 6f 74 20 61 6c 6c 6f 63 61 74 65 64 20 65 66 66  ot allocated eff
0c40: 69 63 69 65 6e 74 6c 79 20 62 79 20 73 6f 6d 65  iciently by some
0c50: 0a 2a 2a 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69  .** implementati
0c60: 6f 6e 73 20 6f 66 20 6d 61 6c 6c 6f 63 2e 20 49  ons of malloc. I
0c70: 6e 20 70 61 72 74 69 63 75 6c 61 72 2c 20 73 6f  n particular, so
0c80: 6d 65 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  me implementatio
0c90: 6e 73 20 61 72 65 20 6f 6e 6c 79 0a 2a 2a 20 61  ns are only.** a
0ca0: 62 6c 65 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20  ble to allocate 
0cb0: 62 6c 6f 63 6b 73 20 6f 66 20 6d 65 6d 6f 72 79  blocks of memory
0cc0: 20 63 68 75 6e 6b 73 20 6f 66 20 32 5e 4e 20 62   chunks of 2^N b
0cd0: 79 74 65 73 2c 20 77 68 65 72 65 20 4e 20 69 73  ytes, where N is
0ce0: 20 73 6f 6d 65 0a 2a 2a 20 69 6e 74 65 67 65 72   some.** integer
0cf0: 20 76 61 6c 75 65 2e 20 53 69 6e 63 65 20 74 68   value. Since th
0d00: 65 20 70 61 67 65 2d 73 69 7a 65 20 69 73 20 61  e page-size is a
0d10: 20 70 6f 77 65 72 20 6f 66 20 32 2c 20 74 68 69   power of 2, thi
0d20: 73 20 6d 65 61 6e 73 20 77 65 0a 2a 2a 20 65 6e  s means we.** en
0d30: 64 20 75 70 20 77 61 73 74 69 6e 67 20 28 70 67  d up wasting (pg
0d40: 73 7a 2d 32 30 30 29 20 62 79 74 65 73 20 69 6e  sz-200) bytes in
0d50: 20 65 61 63 68 20 61 6c 6c 6f 63 61 74 69 6f 6e   each allocation
0d60: 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 53 51 4c 49 54  ..**.** If SQLIT
0d70: 45 5f 50 41 47 45 43 41 43 48 45 5f 42 4c 4f 43  E_PAGECACHE_BLOC
0d80: 4b 41 4c 4c 4f 43 20 69 73 20 64 65 66 69 6e 65  KALLOC is define
0d90: 64 2c 20 74 68 65 20 28 70 67 73 7a 2b 32 30 30  d, the (pgsz+200
0da0: 29 20 62 79 74 65 20 62 6c 6f 63 6b 73 0a 2a 2a  ) byte blocks.**
0db0: 20 61 72 65 20 6e 6f 74 20 61 6c 6c 6f 63 61 74   are not allocat
0dc0: 65 64 20 64 69 72 65 63 74 6c 79 2e 20 49 6e 73  ed directly. Ins
0dd0: 74 65 61 64 2c 20 62 6c 6f 63 6b 73 20 6f 66 20  tead, blocks of 
0de0: 72 6f 75 67 68 6c 79 20 4d 2a 28 70 67 73 7a 2b  roughly M*(pgsz+
0df0: 32 30 30 29 20 62 79 74 65 73 20 0a 2a 2a 20 61  200) bytes .** a
0e00: 72 65 20 72 65 71 75 65 73 74 65 64 20 66 72 6f  re requested fro
0e10: 6d 20 6d 61 6c 6c 6f 63 20 61 6c 6c 6f 63 61 74  m malloc allocat
0e20: 6f 72 2e 20 41 66 74 65 72 20 61 20 62 6c 6f 63  or. After a bloc
0e30: 6b 20 69 73 20 72 65 74 75 72 6e 65 64 2c 0a 2a  k is returned,.*
0e40: 2a 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 53  * sqlite3MallocS
0e50: 69 7a 65 28 29 20 69 73 20 75 73 65 64 20 74 6f  ize() is used to
0e60: 20 64 65 74 65 72 6d 69 6e 65 20 68 6f 77 20 6d   determine how m
0e70: 61 6e 79 20 28 70 67 73 7a 2b 32 30 30 29 20 62  any (pgsz+200) b
0e80: 79 74 65 0a 2a 2a 20 61 6c 6c 6f 63 61 74 69 6f  yte.** allocatio
0e90: 6e 73 20 63 61 6e 20 66 69 74 20 69 6e 20 74 68  ns can fit in th
0ea0: 65 20 73 70 61 63 65 20 72 65 74 75 72 6e 65 64  e space returned
0eb0: 20 62 79 20 6d 61 6c 6c 6f 63 28 29 2e 20 54 68   by malloc(). Th
0ec0: 69 73 20 76 61 6c 75 65 20 6d 61 79 0a 2a 2a 20  is value may.** 
0ed0: 62 65 20 6d 6f 72 65 20 74 68 61 6e 20 4d 2e 0a  be more than M..
0ee0: 2a 2a 0a 2a 2a 20 54 68 65 20 62 6c 6f 63 6b 73  **.** The blocks
0ef0: 20 61 72 65 20 73 74 6f 72 65 64 20 69 6e 20 61   are stored in a
0f00: 20 64 6f 75 62 6c 79 2d 6c 69 6e 6b 65 64 20 6c   doubly-linked l
0f10: 69 73 74 2e 20 56 61 72 69 61 62 6c 65 20 50 47  ist. Variable PG
0f20: 72 6f 75 70 42 6c 6f 63 6b 2e 6e 45 6e 74 72 79  roupBlock.nEntry
0f30: 0a 2a 2a 20 63 6f 6e 74 61 69 6e 73 20 74 68 65  .** contains the
0f40: 20 6e 75 6d 62 65 72 20 6f 66 20 61 6c 6c 6f 63   number of alloc
0f50: 61 74 69 6f 6e 73 20 74 68 61 74 20 77 69 6c 6c  ations that will
0f60: 20 66 69 74 20 69 6e 20 74 68 65 20 61 44 61 74   fit in the aDat
0f70: 61 5b 5d 20 73 70 61 63 65 2e 0a 2a 2a 20 6e 45  a[] space..** nE
0f80: 6e 74 72 79 20 69 73 20 6c 69 6d 69 74 65 64 20  ntry is limited 
0f90: 74 6f 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  to the number of
0fa0: 20 62 69 74 73 20 69 6e 20 62 69 74 6d 61 73 6b   bits in bitmask
0fb0: 20 6d 55 73 65 64 2e 20 49 66 20 61 20 73 6c 6f   mUsed. If a slo
0fc0: 74 0a 2a 2a 20 77 69 74 68 69 6e 20 61 44 61 74  t.** within aDat
0fd0: 61 20 69 73 20 69 6e 20 75 73 65 2c 20 74 68 65  a is in use, the
0fe0: 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20 62   corresponding b
0ff0: 69 74 20 69 6e 20 6d 55 73 65 64 20 69 73 20 73  it in mUsed is s
1000: 65 74 2e 20 54 68 75 73 0a 2a 2a 20 77 68 65 6e  et. Thus.** when
1010: 20 28 6d 55 73 65 64 2b 31 3d 3d 28 31 20 3c 3c   (mUsed+1==(1 <<
1020: 20 6e 45 6e 74 72 79 29 29 20 74 68 65 20 62 6c   nEntry)) the bl
1030: 6f 63 6b 20 69 73 20 63 6f 6d 70 6c 65 74 65 6c  ock is completel
1040: 79 20 66 75 6c 6c 2e 0a 2a 2a 0a 2a 2a 20 45 61  y full..**.** Ea
1050: 63 68 20 74 69 6d 65 20 61 20 73 6c 6f 74 20 77  ch time a slot w
1060: 69 74 68 69 6e 20 61 20 62 6c 6f 63 6b 20 69 73  ithin a block is
1070: 20 66 72 65 65 64 2c 20 74 68 65 20 62 6c 6f 63   freed, the bloc
1080: 6b 20 69 73 20 6d 6f 76 65 64 20 74 6f 20 74 68  k is moved to th
1090: 65 20 73 74 61 72 74 0a 2a 2a 20 6f 66 20 74 68  e start.** of th
10a0: 65 20 6c 69 6e 6b 65 64 2d 6c 69 73 74 2e 20 41  e linked-list. A
10b0: 6e 64 20 69 66 20 61 20 62 6c 6f 63 6b 20 62 65  nd if a block be
10c0: 63 6f 6d 65 73 20 63 6f 6d 70 6c 65 74 65 6c 79  comes completely
10d0: 20 66 75 6c 6c 2c 20 74 68 65 6e 20 69 74 20 69   full, then it i
10e0: 73 0a 2a 2a 20 6d 6f 76 65 64 20 74 6f 20 74 68  s.** moved to th
10f0: 65 20 65 6e 64 20 6f 66 20 74 68 65 20 6c 69 73  e end of the lis
1100: 74 2e 20 41 73 20 61 20 72 65 73 75 6c 74 2c 20  t. As a result, 
1110: 77 68 65 6e 20 73 65 61 72 63 68 69 6e 67 20 66  when searching f
1120: 6f 72 20 61 20 66 72 65 65 0a 2a 2a 20 73 6c 6f  or a free.** slo
1130: 74 2c 20 6f 6e 6c 79 20 74 68 65 20 66 69 72 73  t, only the firs
1140: 74 20 62 6c 6f 63 6b 20 69 6e 20 74 68 65 20 6c  t block in the l
1150: 69 73 74 20 6e 65 65 64 20 62 65 20 65 78 61 6d  ist need be exam
1160: 69 6e 65 64 2e 20 49 66 20 69 74 20 69 73 20 66  ined. If it is f
1170: 75 6c 6c 2c 0a 2a 2a 20 74 68 65 6e 20 69 74 20  ull,.** then it 
1180: 69 73 20 67 75 61 72 61 6e 74 65 65 64 20 74 68  is guaranteed th
1190: 61 74 20 61 6c 6c 20 62 6c 6f 63 6b 73 20 61 72  at all blocks ar
11a0: 65 20 66 75 6c 6c 2e 0a 2a 2f 0a 73 74 72 75 63  e full..*/.struc
11b0: 74 20 50 47 72 6f 75 70 42 6c 6f 63 6b 4c 69 73  t PGroupBlockLis
11c0: 74 20 7b 0a 20 20 69 6e 74 20 6e 42 79 74 65 3b  t {.  int nByte;
11d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
11e0: 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
11f0: 65 61 63 68 20 61 6c 6c 6f 63 61 74 69 6f 6e 20  each allocation 
1200: 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 50 47  in bytes */.  PG
1210: 72 6f 75 70 42 6c 6f 63 6b 20 2a 70 46 69 72 73  roupBlock *pFirs
1220: 74 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  t;           /* 
1230: 46 69 72 73 74 20 50 47 72 6f 75 70 42 6c 6f 63  First PGroupBloc
1240: 6b 20 69 6e 20 6c 69 73 74 20 2a 2f 0a 20 20 50  k in list */.  P
1250: 47 72 6f 75 70 42 6c 6f 63 6b 20 2a 70 4c 61 73  GroupBlock *pLas
1260: 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  t;            /*
1270: 20 4c 61 73 74 20 50 47 72 6f 75 70 42 6c 6f 63   Last PGroupBloc
1280: 6b 20 69 6e 20 6c 69 73 74 20 2a 2f 0a 20 20 50  k in list */.  P
1290: 47 72 6f 75 70 42 6c 6f 63 6b 4c 69 73 74 20 2a  GroupBlockList *
12a0: 70 4e 65 78 74 3b 20 20 20 20 20 20 20 20 2f 2a  pNext;        /*
12b0: 20 4e 65 78 74 20 62 6c 6f 63 6b 2d 6c 69 73 74   Next block-list
12c0: 20 61 74 74 61 63 68 65 64 20 74 6f 20 67 72 6f   attached to gro
12d0: 75 70 20 2a 2f 0a 7d 3b 0a 0a 73 74 72 75 63 74  up */.};..struct
12e0: 20 50 47 72 6f 75 70 42 6c 6f 63 6b 20 7b 0a 20   PGroupBlock {. 
12f0: 20 42 69 74 6d 61 73 6b 20 6d 55 73 65 64 3b 20   Bitmask mUsed; 
1300: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1310: 2f 2a 20 4d 61 73 6b 20 6f 66 20 75 73 65 64 20  /* Mask of used 
1320: 73 6c 6f 74 73 20 2a 2f 0a 20 20 69 6e 74 20 6e  slots */.  int n
1330: 45 6e 74 72 79 3b 20 20 20 20 20 20 20 20 20 20  Entry;          
1340: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61 78            /* Max
1350: 69 6d 75 6d 20 6e 75 6d 62 65 72 20 6f 66 20 61  imum number of a
1360: 6c 6c 6f 63 61 74 69 6f 6e 73 20 69 6e 20 61 44  llocations in aD
1370: 61 74 61 5b 5d 20 2a 2f 0a 20 20 75 38 20 2a 61  ata[] */.  u8 *a
1380: 44 61 74 61 3b 20 20 20 20 20 20 20 20 20 20 20  Data;           
1390: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69            /* Poi
13a0: 6e 74 65 72 20 74 6f 20 64 61 74 61 20 62 6c 6f  nter to data blo
13b0: 63 6b 20 2a 2f 0a 20 20 50 47 72 6f 75 70 42 6c  ck */.  PGroupBl
13c0: 6f 63 6b 20 2a 70 4e 65 78 74 3b 20 20 20 20 20  ock *pNext;     
13d0: 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 50         /* Next P
13e0: 47 72 6f 75 70 42 6c 6f 63 6b 20 69 6e 20 6c 69  GroupBlock in li
13f0: 73 74 20 2a 2f 0a 20 20 50 47 72 6f 75 70 42 6c  st */.  PGroupBl
1400: 6f 63 6b 20 2a 70 50 72 65 76 3b 20 20 20 20 20  ock *pPrev;     
1410: 20 20 20 20 20 20 20 2f 2a 20 50 72 65 76 69 6f         /* Previo
1420: 75 73 20 50 47 72 6f 75 70 42 6c 6f 63 6b 20 69  us PGroupBlock i
1430: 6e 20 6c 69 73 74 20 2a 2f 0a 20 20 50 47 72 6f  n list */.  PGro
1440: 75 70 42 6c 6f 63 6b 4c 69 73 74 20 2a 70 4c 69  upBlockList *pLi
1450: 73 74 3b 20 20 20 20 20 20 20 20 2f 2a 20 4f 77  st;        /* Ow
1460: 6e 65 72 20 6c 69 73 74 20 2a 2f 0a 7d 3b 0a 0a  ner list */.};..
1470: 2f 2a 20 4d 69 6e 69 6d 75 6d 20 76 61 6c 75 65  /* Minimum value
1480: 20 66 6f 72 20 50 47 72 6f 75 70 42 6c 6f 63 6b   for PGroupBlock
1490: 2e 6e 45 6e 74 72 79 20 2a 2f 0a 23 64 65 66 69  .nEntry */.#defi
14a0: 6e 65 20 50 41 47 45 43 41 43 48 45 5f 42 4c 4f  ne PAGECACHE_BLO
14b0: 43 4b 41 4c 4c 4f 43 5f 4d 49 4e 45 4e 54 52 59  CKALLOC_MINENTRY
14c0: 20 31 35 0a 0a 2f 2a 20 45 61 63 68 20 70 61 67   15../* Each pag
14d0: 65 20 63 61 63 68 65 20 69 73 20 61 6e 20 69 6e  e cache is an in
14e0: 73 74 61 6e 63 65 20 6f 66 20 74 68 65 20 66 6f  stance of the fo
14f0: 6c 6c 6f 77 69 6e 67 20 6f 62 6a 65 63 74 2e 20  llowing object. 
1500: 20 45 76 65 72 79 0a 2a 2a 20 6f 70 65 6e 20 64   Every.** open d
1510: 61 74 61 62 61 73 65 20 66 69 6c 65 20 28 69 6e  atabase file (in
1520: 63 6c 75 64 69 6e 67 20 65 61 63 68 20 69 6e 2d  cluding each in-
1530: 6d 65 6d 6f 72 79 20 64 61 74 61 62 61 73 65 20  memory database 
1540: 61 6e 64 20 65 61 63 68 0a 2a 2a 20 74 65 6d 70  and each.** temp
1550: 6f 72 61 72 79 20 6f 72 20 74 72 61 6e 73 69 65  orary or transie
1560: 6e 74 20 64 61 74 61 62 61 73 65 29 20 68 61 73  nt database) has
1570: 20 61 20 73 69 6e 67 6c 65 20 70 61 67 65 20 63   a single page c
1580: 61 63 68 65 20 77 68 69 63 68 0a 2a 2a 20 69 73  ache which.** is
1590: 20 61 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66 20   an instance of 
15a0: 74 68 69 73 20 6f 62 6a 65 63 74 2e 0a 2a 2a 0a  this object..**.
15b0: 2a 2a 20 50 6f 69 6e 74 65 72 73 20 74 6f 20 73  ** Pointers to s
15c0: 74 72 75 63 74 75 72 65 73 20 6f 66 20 74 68 69  tructures of thi
15d0: 73 20 74 79 70 65 20 61 72 65 20 63 61 73 74 20  s type are cast 
15e0: 61 6e 64 20 72 65 74 75 72 6e 65 64 20 61 73 20  and returned as 
15f0: 0a 2a 2a 20 6f 70 61 71 75 65 20 73 71 6c 69 74  .** opaque sqlit
1600: 65 33 5f 70 63 61 63 68 65 2a 20 68 61 6e 64 6c  e3_pcache* handl
1610: 65 73 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 50 43  es..*/.struct PC
1620: 61 63 68 65 31 20 7b 0a 20 20 2f 2a 20 43 61 63  ache1 {.  /* Cac
1630: 68 65 20 63 6f 6e 66 69 67 75 72 61 74 69 6f 6e  he configuration
1640: 20 70 61 72 61 6d 65 74 65 72 73 2e 20 50 61 67   parameters. Pag
1650: 65 20 73 69 7a 65 20 28 73 7a 50 61 67 65 29 20  e size (szPage) 
1660: 61 6e 64 20 74 68 65 20 70 75 72 67 65 61 62 6c  and the purgeabl
1670: 65 0a 20 20 2a 2a 20 66 6c 61 67 20 28 62 50 75  e.  ** flag (bPu
1680: 72 67 65 61 62 6c 65 29 20 61 72 65 20 73 65 74  rgeable) are set
1690: 20 77 68 65 6e 20 74 68 65 20 63 61 63 68 65 20   when the cache 
16a0: 69 73 20 63 72 65 61 74 65 64 2e 20 6e 4d 61 78  is created. nMax
16b0: 20 6d 61 79 20 62 65 20 0a 20 20 2a 2a 20 6d 6f   may be .  ** mo
16c0: 64 69 66 69 65 64 20 61 74 20 61 6e 79 20 74 69  dified at any ti
16d0: 6d 65 20 62 79 20 61 20 63 61 6c 6c 20 74 6f 20  me by a call to 
16e0: 74 68 65 20 70 63 61 63 68 65 31 43 61 63 68 65  the pcache1Cache
16f0: 53 69 7a 65 28 29 20 6d 65 74 68 6f 64 2e 0a 20  Size() method.. 
1700: 20 2a 2a 20 54 68 65 20 50 47 72 6f 75 70 20 6d   ** The PGroup m
1710: 75 74 65 78 20 6d 75 73 74 20 62 65 20 68 65 6c  utex must be hel
1720: 64 20 77 68 65 6e 20 61 63 63 65 73 73 69 6e 67  d when accessing
1730: 20 6e 4d 61 78 2e 0a 20 20 2a 2f 0a 20 20 50 47   nMax..  */.  PG
1740: 72 6f 75 70 20 2a 70 47 72 6f 75 70 3b 20 20 20  roup *pGroup;   
1750: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1760: 20 20 2f 2a 20 50 47 72 6f 75 70 20 74 68 69 73    /* PGroup this
1770: 20 63 61 63 68 65 20 62 65 6c 6f 6e 67 73 20 74   cache belongs t
1780: 6f 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 50 61 67  o */.  int szPag
1790: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
17a0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69             /* Si
17b0: 7a 65 20 6f 66 20 61 6c 6c 6f 63 61 74 65 64 20  ze of allocated 
17c0: 70 61 67 65 73 20 69 6e 20 62 79 74 65 73 20 2a  pages in bytes *
17d0: 2f 0a 20 20 69 6e 74 20 62 50 75 72 67 65 61 62  /.  int bPurgeab
17e0: 6c 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  le;             
17f0: 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20          /* True 
1800: 69 66 20 63 61 63 68 65 20 69 73 20 70 75 72 67  if cache is purg
1810: 65 61 62 6c 65 20 2a 2f 0a 20 20 75 6e 73 69 67  eable */.  unsig
1820: 6e 65 64 20 69 6e 74 20 6e 4d 69 6e 3b 20 20 20  ned int nMin;   
1830: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1840: 2a 20 4d 69 6e 69 6d 75 6d 20 6e 75 6d 62 65 72  * Minimum number
1850: 20 6f 66 20 70 61 67 65 73 20 72 65 73 65 72 76   of pages reserv
1860: 65 64 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64  ed */.  unsigned
1870: 20 69 6e 74 20 6e 4d 61 78 3b 20 20 20 20 20 20   int nMax;      
1880: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
1890: 6f 6e 66 69 67 75 72 65 64 20 22 63 61 63 68 65  onfigured "cache
18a0: 5f 73 69 7a 65 22 20 76 61 6c 75 65 20 2a 2f 0a  _size" value */.
18b0: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e    unsigned int n
18c0: 39 30 70 63 74 3b 20 20 20 20 20 20 20 20 20 20  90pct;          
18d0: 20 20 20 20 20 20 2f 2a 20 6e 4d 61 78 2a 39 2f        /* nMax*9/
18e0: 31 30 20 2a 2f 0a 0a 20 20 2f 2a 20 48 61 73 68  10 */..  /* Hash
18f0: 20 74 61 62 6c 65 20 6f 66 20 61 6c 6c 20 70 61   table of all pa
1900: 67 65 73 2e 20 54 68 65 20 66 6f 6c 6c 6f 77 69  ges. The followi
1910: 6e 67 20 76 61 72 69 61 62 6c 65 73 20 6d 61 79  ng variables may
1920: 20 6f 6e 6c 79 20 62 65 20 61 63 63 65 73 73 65   only be accesse
1930: 64 0a 20 20 2a 2a 20 77 68 65 6e 20 74 68 65 20  d.  ** when the 
1940: 61 63 63 65 73 73 6f 72 20 69 73 20 68 6f 6c 64  accessor is hold
1950: 69 6e 67 20 74 68 65 20 50 47 72 6f 75 70 20 6d  ing the PGroup m
1960: 75 74 65 78 2e 0a 20 20 2a 2f 0a 20 20 75 6e 73  utex..  */.  uns
1970: 69 67 6e 65 64 20 69 6e 74 20 6e 52 65 63 79 63  igned int nRecyc
1980: 6c 61 62 6c 65 3b 20 20 20 20 20 20 20 20 20 20  lable;          
1990: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 70 61   /* Number of pa
19a0: 67 65 73 20 69 6e 20 74 68 65 20 4c 52 55 20 6c  ges in the LRU l
19b0: 69 73 74 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65  ist */.  unsigne
19c0: 64 20 69 6e 74 20 6e 50 61 67 65 3b 20 20 20 20  d int nPage;    
19d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
19e0: 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20  Total number of 
19f0: 70 61 67 65 73 20 69 6e 20 61 70 48 61 73 68 20  pages in apHash 
1a00: 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e  */.  unsigned in
1a10: 74 20 6e 48 61 73 68 3b 20 20 20 20 20 20 20 20  t nHash;        
1a20: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
1a30: 65 72 20 6f 66 20 73 6c 6f 74 73 20 69 6e 20 61  er of slots in a
1a40: 70 48 61 73 68 5b 5d 20 2a 2f 0a 20 20 50 67 48  pHash[] */.  PgH
1a50: 64 72 31 20 2a 2a 61 70 48 61 73 68 3b 20 20 20  dr1 **apHash;   
1a60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1a70: 20 2f 2a 20 48 61 73 68 20 74 61 62 6c 65 20 66   /* Hash table f
1a80: 6f 72 20 66 61 73 74 20 6c 6f 6f 6b 75 70 20 62  or fast lookup b
1a90: 79 20 6b 65 79 20 2a 2f 0a 0a 20 20 75 6e 73 69  y key */..  unsi
1aa0: 67 6e 65 64 20 69 6e 74 20 69 4d 61 78 4b 65 79  gned int iMaxKey
1ab0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1ac0: 2f 2a 20 4c 61 72 67 65 73 74 20 6b 65 79 20 73  /* Largest key s
1ad0: 65 65 6e 20 73 69 6e 63 65 20 78 54 72 75 6e 63  een since xTrunc
1ae0: 61 74 65 28 29 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a  ate() */.};../*.
1af0: 2a 2a 20 45 61 63 68 20 63 61 63 68 65 20 65 6e  ** Each cache en
1b00: 74 72 79 20 69 73 20 72 65 70 72 65 73 65 6e 74  try is represent
1b10: 65 64 20 62 79 20 61 6e 20 69 6e 73 74 61 6e 63  ed by an instanc
1b20: 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69  e of the followi
1b30: 6e 67 20 0a 2a 2a 20 73 74 72 75 63 74 75 72 65  ng .** structure
1b40: 2e 20 41 20 62 75 66 66 65 72 20 6f 66 20 50 67  . A buffer of Pg
1b50: 48 64 72 31 2e 70 43 61 63 68 65 2d 3e 73 7a 50  Hdr1.pCache->szP
1b60: 61 67 65 20 62 79 74 65 73 20 69 73 20 61 6c 6c  age bytes is all
1b70: 6f 63 61 74 65 64 20 0a 2a 2a 20 64 69 72 65 63  ocated .** direc
1b80: 74 6c 79 20 62 65 66 6f 72 65 20 74 68 69 73 20  tly before this 
1b90: 73 74 72 75 63 74 75 72 65 20 69 6e 20 6d 65 6d  structure in mem
1ba0: 6f 72 79 20 28 73 65 65 20 74 68 65 20 50 47 48  ory (see the PGH
1bb0: 44 52 31 5f 54 4f 5f 50 41 47 45 28 29 20 0a 2a  DR1_TO_PAGE() .*
1bc0: 2a 20 6d 61 63 72 6f 20 62 65 6c 6f 77 29 2e 0a  * macro below)..
1bd0: 2a 2f 0a 73 74 72 75 63 74 20 50 67 48 64 72 31  */.struct PgHdr1
1be0: 20 7b 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e   {.  unsigned in
1bf0: 74 20 69 4b 65 79 3b 20 20 20 20 20 20 20 20 20  t iKey;         
1c00: 20 20 20 20 2f 2a 20 4b 65 79 20 76 61 6c 75 65      /* Key value
1c10: 20 28 70 61 67 65 20 6e 75 6d 62 65 72 29 20 2a   (page number) *
1c20: 2f 0a 20 20 50 67 48 64 72 31 20 2a 70 4e 65 78  /.  PgHdr1 *pNex
1c30: 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t;              
1c40: 20 20 20 2f 2a 20 4e 65 78 74 20 69 6e 20 68 61     /* Next in ha
1c50: 73 68 20 74 61 62 6c 65 20 63 68 61 69 6e 20 2a  sh table chain *
1c60: 2f 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43 61  /.  PCache1 *pCa
1c70: 63 68 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  che;            
1c80: 20 20 20 2f 2a 20 43 61 63 68 65 20 74 68 61 74     /* Cache that
1c90: 20 63 75 72 72 65 6e 74 6c 79 20 6f 77 6e 73 20   currently owns 
1ca0: 74 68 69 73 20 70 61 67 65 20 2a 2f 0a 20 20 50  this page */.  P
1cb0: 67 48 64 72 31 20 2a 70 4c 72 75 4e 65 78 74 3b  gHdr1 *pLruNext;
1cc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1cd0: 20 4e 65 78 74 20 69 6e 20 4c 52 55 20 6c 69 73   Next in LRU lis
1ce0: 74 20 6f 66 20 75 6e 70 69 6e 6e 65 64 20 70 61  t of unpinned pa
1cf0: 67 65 73 20 2a 2f 0a 20 20 50 67 48 64 72 31 20  ges */.  PgHdr1 
1d00: 2a 70 4c 72 75 50 72 65 76 3b 20 20 20 20 20 20  *pLruPrev;      
1d10: 20 20 20 20 20 20 20 20 2f 2a 20 50 72 65 76 69          /* Previ
1d20: 6f 75 73 20 69 6e 20 4c 52 55 20 6c 69 73 74 20  ous in LRU list 
1d30: 6f 66 20 75 6e 70 69 6e 6e 65 64 20 70 61 67 65  of unpinned page
1d40: 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 46  s */.};../*.** F
1d50: 72 65 65 20 73 6c 6f 74 73 20 69 6e 20 74 68 65  ree slots in the
1d60: 20 61 6c 6c 6f 63 61 74 6f 72 20 75 73 65 64 20   allocator used 
1d70: 74 6f 20 64 69 76 69 64 65 20 75 70 20 74 68 65  to divide up the
1d80: 20 62 75 66 66 65 72 20 70 72 6f 76 69 64 65 64   buffer provided
1d90: 20 75 73 69 6e 67 0a 2a 2a 20 74 68 65 20 53 51   using.** the SQ
1da0: 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47 45  LITE_CONFIG_PAGE
1db0: 43 41 43 48 45 20 6d 65 63 68 61 6e 69 73 6d 2e  CACHE mechanism.
1dc0: 0a 2a 2f 0a 73 74 72 75 63 74 20 50 67 46 72 65  .*/.struct PgFre
1dd0: 65 73 6c 6f 74 20 7b 0a 20 20 50 67 46 72 65 65  eslot {.  PgFree
1de0: 73 6c 6f 74 20 2a 70 4e 65 78 74 3b 20 20 2f 2a  slot *pNext;  /*
1df0: 20 4e 65 78 74 20 66 72 65 65 20 73 6c 6f 74 20   Next free slot 
1e00: 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 47 6c 6f  */.};../*.** Glo
1e10: 62 61 6c 20 64 61 74 61 20 75 73 65 64 20 62 79  bal data used by
1e20: 20 74 68 69 73 20 63 61 63 68 65 2e 0a 2a 2f 0a   this cache..*/.
1e30: 73 74 61 74 69 63 20 53 51 4c 49 54 45 5f 57 53  static SQLITE_WS
1e40: 44 20 73 74 72 75 63 74 20 50 43 61 63 68 65 47  D struct PCacheG
1e50: 6c 6f 62 61 6c 20 7b 0a 20 20 50 47 72 6f 75 70  lobal {.  PGroup
1e60: 20 67 72 70 3b 20 20 20 20 20 20 20 20 20 20 20   grp;           
1e70: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20           /* The 
1e80: 67 6c 6f 62 61 6c 20 50 47 72 6f 75 70 20 66 6f  global PGroup fo
1e90: 72 20 6d 6f 64 65 20 28 32 29 20 2a 2f 0a 0a 20  r mode (2) */.. 
1ea0: 20 2f 2a 20 56 61 72 69 61 62 6c 65 73 20 72 65   /* Variables re
1eb0: 6c 61 74 65 64 20 74 6f 20 53 51 4c 49 54 45 5f  lated to SQLITE_
1ec0: 43 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48 45  CONFIG_PAGECACHE
1ed0: 20 73 65 74 74 69 6e 67 73 2e 20 20 54 68 65 0a   settings.  The.
1ee0: 20 20 2a 2a 20 73 7a 53 6c 6f 74 2c 20 6e 53 6c    ** szSlot, nSl
1ef0: 6f 74 2c 20 70 53 74 61 72 74 2c 20 70 45 6e 64  ot, pStart, pEnd
1f00: 2c 20 6e 52 65 73 65 72 76 65 2c 20 61 6e 64 20  , nReserve, and 
1f10: 69 73 49 6e 69 74 20 76 61 6c 75 65 73 20 61 72  isInit values ar
1f20: 65 20 61 6c 6c 0a 20 20 2a 2a 20 66 69 78 65 64  e all.  ** fixed
1f30: 20 61 74 20 73 71 6c 69 74 65 33 5f 69 6e 69 74   at sqlite3_init
1f40: 69 61 6c 69 7a 65 28 29 20 74 69 6d 65 20 61 6e  ialize() time an
1f50: 64 20 64 6f 20 6e 6f 74 20 72 65 71 75 69 72 65  d do not require
1f60: 20 6d 75 74 65 78 20 70 72 6f 74 65 63 74 69 6f   mutex protectio
1f70: 6e 2e 0a 20 20 2a 2a 20 54 68 65 20 6e 46 72 65  n..  ** The nFre
1f80: 65 53 6c 6f 74 20 61 6e 64 20 70 46 72 65 65 20  eSlot and pFree 
1f90: 76 61 6c 75 65 73 20 64 6f 20 72 65 71 75 69 72  values do requir
1fa0: 65 20 6d 75 74 65 78 20 70 72 6f 74 65 63 74 69  e mutex protecti
1fb0: 6f 6e 2e 0a 20 20 2a 2f 0a 20 20 69 6e 74 20 69  on..  */.  int i
1fc0: 73 49 6e 69 74 3b 20 20 20 20 20 20 20 20 20 20  sInit;          
1fd0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75            /* Tru
1fe0: 65 20 69 66 20 69 6e 69 74 69 61 6c 69 7a 65 64  e if initialized
1ff0: 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 53 6c 6f 74   */.  int szSlot
2000: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
2010: 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
2020: 65 61 63 68 20 66 72 65 65 20 73 6c 6f 74 20 2a  each free slot *
2030: 2f 0a 20 20 69 6e 74 20 6e 53 6c 6f 74 3b 20 20  /.  int nSlot;  
2040: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2050: 20 20 20 2f 2a 20 54 68 65 20 6e 75 6d 62 65 72     /* The number
2060: 20 6f 66 20 70 63 61 63 68 65 20 73 6c 6f 74 73   of pcache slots
2070: 20 2a 2f 0a 20 20 69 6e 74 20 6e 52 65 73 65 72   */.  int nReser
2080: 76 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ve;             
2090: 20 20 20 20 20 2f 2a 20 54 72 79 20 74 6f 20 6b       /* Try to k
20a0: 65 65 70 20 6e 46 72 65 65 53 6c 6f 74 20 61 62  eep nFreeSlot ab
20b0: 6f 76 65 20 74 68 69 73 20 2a 2f 0a 20 20 76 6f  ove this */.  vo
20c0: 69 64 20 2a 70 53 74 61 72 74 2c 20 2a 70 45 6e  id *pStart, *pEn
20d0: 64 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  d;           /* 
20e0: 42 6f 75 6e 64 73 20 6f 66 20 70 61 67 65 63 61  Bounds of pageca
20f0: 63 68 65 20 6d 61 6c 6c 6f 63 20 72 61 6e 67 65  che malloc range
2100: 20 2a 2f 0a 20 20 2f 2a 20 41 62 6f 76 65 20 72   */.  /* Above r
2110: 65 71 75 69 72 65 73 20 6e 6f 20 6d 75 74 65 78  equires no mutex
2120: 2e 20 20 55 73 65 20 6d 75 74 65 78 20 62 65 6c  .  Use mutex bel
2130: 6f 77 20 66 6f 72 20 76 61 72 69 61 62 6c 65 20  ow for variable 
2140: 74 68 61 74 20 66 6f 6c 6c 6f 77 2e 20 2a 2f 0a  that follow. */.
2150: 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 20    sqlite3_mutex 
2160: 2a 6d 75 74 65 78 3b 20 20 20 20 20 20 20 20 20  *mutex;         
2170: 20 2f 2a 20 4d 75 74 65 78 20 66 6f 72 20 61 63   /* Mutex for ac
2180: 63 65 73 73 69 6e 67 20 74 68 65 20 66 6f 6c 6c  cessing the foll
2190: 6f 77 69 6e 67 3a 20 2a 2f 0a 20 20 69 6e 74 20  owing: */.  int 
21a0: 6e 46 72 65 65 53 6c 6f 74 3b 20 20 20 20 20 20  nFreeSlot;      
21b0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
21c0: 6d 62 65 72 20 6f 66 20 75 6e 75 73 65 64 20 70  mber of unused p
21d0: 63 61 63 68 65 20 73 6c 6f 74 73 20 2a 2f 0a 20  cache slots */. 
21e0: 20 50 67 46 72 65 65 73 6c 6f 74 20 2a 70 46 72   PgFreeslot *pFr
21f0: 65 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ee;             
2200: 2f 2a 20 46 72 65 65 20 70 61 67 65 20 62 6c 6f  /* Free page blo
2210: 63 6b 73 20 2a 2f 0a 20 20 2f 2a 20 54 68 65 20  cks */.  /* The 
2220: 66 6f 6c 6c 6f 77 69 6e 67 20 76 61 6c 75 65 20  following value 
2230: 72 65 71 75 69 72 65 73 20 61 20 6d 75 74 65 78  requires a mutex
2240: 20 74 6f 20 63 68 61 6e 67 65 2e 20 20 57 65 20   to change.  We 
2250: 73 6b 69 70 20 74 68 65 20 6d 75 74 65 78 20 6f  skip the mutex o
2260: 6e 0a 20 20 2a 2a 20 72 65 61 64 69 6e 67 20 62  n.  ** reading b
2270: 65 63 61 75 73 65 20 28 31 29 20 6d 6f 73 74 20  ecause (1) most 
2280: 70 6c 61 74 66 6f 72 6d 73 20 72 65 61 64 20 61  platforms read a
2290: 20 33 32 2d 62 69 74 20 69 6e 74 65 67 65 72 20   32-bit integer 
22a0: 61 74 6f 6d 69 63 61 6c 6c 79 20 61 6e 64 0a 20  atomically and. 
22b0: 20 2a 2a 20 28 32 29 20 65 76 65 6e 20 69 66 20   ** (2) even if 
22c0: 61 6e 20 69 6e 63 6f 72 72 65 63 74 20 76 61 6c  an incorrect val
22d0: 75 65 20 69 73 20 72 65 61 64 2c 20 6e 6f 20 67  ue is read, no g
22e0: 72 65 61 74 20 68 61 72 6d 20 69 73 20 64 6f 6e  reat harm is don
22f0: 65 20 73 69 6e 63 65 20 74 68 69 73 0a 20 20 2a  e since this.  *
2300: 2a 20 69 73 20 72 65 61 6c 6c 79 20 6a 75 73 74  * is really just
2310: 20 61 6e 20 6f 70 74 69 6d 69 7a 61 74 69 6f 6e   an optimization
2320: 2e 20 2a 2f 0a 20 20 69 6e 74 20 62 55 6e 64 65  . */.  int bUnde
2330: 72 50 72 65 73 73 75 72 65 3b 20 20 20 20 20 20  rPressure;      
2340: 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66        /* True if
2350: 20 6c 6f 77 20 6f 6e 20 50 41 47 45 43 41 43 48   low on PAGECACH
2360: 45 20 6d 65 6d 6f 72 79 20 2a 2f 0a 7d 20 70 63  E memory */.} pc
2370: 61 63 68 65 31 5f 67 3b 0a 0a 2f 2a 0a 2a 2a 20  ache1_g;../*.** 
2380: 41 6c 6c 20 63 6f 64 65 20 69 6e 20 74 68 69 73  All code in this
2390: 20 66 69 6c 65 20 73 68 6f 75 6c 64 20 61 63 63   file should acc
23a0: 65 73 73 20 74 68 65 20 67 6c 6f 62 61 6c 20 73  ess the global s
23b0: 74 72 75 63 74 75 72 65 20 61 62 6f 76 65 20 76  tructure above v
23c0: 69 61 20 74 68 65 0a 2a 2a 20 61 6c 69 61 73 20  ia the.** alias 
23d0: 22 70 63 61 63 68 65 31 22 2e 20 54 68 69 73 20  "pcache1". This 
23e0: 65 6e 73 75 72 65 73 20 74 68 61 74 20 74 68 65  ensures that the
23f0: 20 57 53 44 20 65 6d 75 6c 61 74 69 6f 6e 20 69   WSD emulation i
2400: 73 20 75 73 65 64 20 77 68 65 6e 0a 2a 2a 20 63  s used when.** c
2410: 6f 6d 70 69 6c 69 6e 67 20 66 6f 72 20 73 79 73  ompiling for sys
2420: 74 65 6d 73 20 74 68 61 74 20 64 6f 20 6e 6f 74  tems that do not
2430: 20 73 75 70 70 6f 72 74 20 72 65 61 6c 20 57 53   support real WS
2440: 44 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 70 63  D..*/.#define pc
2450: 61 63 68 65 31 20 28 47 4c 4f 42 41 4c 28 73 74  ache1 (GLOBAL(st
2460: 72 75 63 74 20 50 43 61 63 68 65 47 6c 6f 62 61  ruct PCacheGloba
2470: 6c 2c 20 70 63 61 63 68 65 31 5f 67 29 29 0a 0a  l, pcache1_g))..
2480: 2f 2a 0a 2a 2a 20 57 68 65 6e 20 61 20 50 67 48  /*.** When a PgH
2490: 64 72 31 20 73 74 72 75 63 74 75 72 65 20 69 73  dr1 structure is
24a0: 20 61 6c 6c 6f 63 61 74 65 64 2c 20 74 68 65 20   allocated, the 
24b0: 61 73 73 6f 63 69 61 74 65 64 20 50 43 61 63 68  associated PCach
24c0: 65 31 2e 73 7a 50 61 67 65 0a 2a 2a 20 62 79 74  e1.szPage.** byt
24d0: 65 73 20 6f 66 20 64 61 74 61 20 61 72 65 20 6c  es of data are l
24e0: 6f 63 61 74 65 64 20 64 69 72 65 63 74 6c 79 20  ocated directly 
24f0: 62 65 66 6f 72 65 20 69 74 20 69 6e 20 6d 65 6d  before it in mem
2500: 6f 72 79 20 28 69 2e 65 2e 20 74 68 65 20 74 6f  ory (i.e. the to
2510: 74 61 6c 0a 2a 2a 20 73 69 7a 65 20 6f 66 20 74  tal.** size of t
2520: 68 65 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 69 73  he allocation is
2530: 20 73 69 7a 65 6f 66 28 50 67 48 64 72 31 29 2b   sizeof(PgHdr1)+
2540: 50 43 61 63 68 65 31 2e 73 7a 50 61 67 65 20 62  PCache1.szPage b
2550: 79 74 65 29 2e 20 54 68 65 0a 2a 2a 20 50 47 48  yte). The.** PGH
2560: 44 52 31 5f 54 4f 5f 50 41 47 45 28 29 20 6d 61  DR1_TO_PAGE() ma
2570: 63 72 6f 20 74 61 6b 65 73 20 61 20 70 6f 69 6e  cro takes a poin
2580: 74 65 72 20 74 6f 20 61 20 50 67 48 64 72 31 20  ter to a PgHdr1 
2590: 73 74 72 75 63 74 75 72 65 20 61 73 0a 2a 2a 20  structure as.** 
25a0: 61 6e 20 61 72 67 75 6d 65 6e 74 20 61 6e 64 20  an argument and 
25b0: 72 65 74 75 72 6e 73 20 61 20 70 6f 69 6e 74 65  returns a pointe
25c0: 72 20 74 6f 20 74 68 65 20 61 73 73 6f 63 69 61  r to the associa
25d0: 74 65 64 20 62 6c 6f 63 6b 20 6f 66 20 73 7a 50  ted block of szP
25e0: 61 67 65 0a 2a 2a 20 62 79 74 65 73 2e 20 54 68  age.** bytes. Th
25f0: 65 20 50 41 47 45 5f 54 4f 5f 50 47 48 44 52 31  e PAGE_TO_PGHDR1
2600: 28 29 20 6d 61 63 72 6f 20 64 6f 65 73 20 74 68  () macro does th
2610: 65 20 6f 70 70 6f 73 69 74 65 3a 20 69 74 73 20  e opposite: its 
2620: 61 72 67 75 6d 65 6e 74 20 69 73 0a 2a 2a 20 61  argument is.** a
2630: 20 70 6f 69 6e 74 65 72 20 74 6f 20 61 20 62 6c   pointer to a bl
2640: 6f 63 6b 20 6f 66 20 73 7a 50 61 67 65 20 62 79  ock of szPage by
2650: 74 65 73 20 6f 66 20 64 61 74 61 20 61 6e 64 20  tes of data and 
2660: 74 68 65 20 72 65 74 75 72 6e 20 76 61 6c 75 65  the return value
2670: 20 69 73 0a 2a 2a 20 61 20 70 6f 69 6e 74 65 72   is.** a pointer
2680: 20 74 6f 20 74 68 65 20 61 73 73 6f 63 69 61 74   to the associat
2690: 65 64 20 50 67 48 64 72 31 20 73 74 72 75 63 74  ed PgHdr1 struct
26a0: 75 72 65 2e 0a 2a 2a 0a 2a 2a 20 20 20 61 73 73  ure..**.**   ass
26b0: 65 72 74 28 20 50 47 48 44 52 31 5f 54 4f 5f 50  ert( PGHDR1_TO_P
26c0: 41 47 45 28 50 41 47 45 5f 54 4f 5f 50 47 48 44  AGE(PAGE_TO_PGHD
26d0: 52 31 28 70 43 61 63 68 65 2c 20 58 29 29 3d 3d  R1(pCache, X))==
26e0: 58 20 29 3b 0a 2a 2f 0a 23 64 65 66 69 6e 65 20  X );.*/.#define 
26f0: 50 47 48 44 52 31 5f 54 4f 5f 50 41 47 45 28 70  PGHDR1_TO_PAGE(p
2700: 29 20 20 20 20 28 76 6f 69 64 2a 29 28 28 28 63  )    (void*)(((c
2710: 68 61 72 2a 29 70 29 20 2d 20 70 2d 3e 70 43 61  har*)p) - p->pCa
2720: 63 68 65 2d 3e 73 7a 50 61 67 65 29 0a 23 64 65  che->szPage).#de
2730: 66 69 6e 65 20 50 41 47 45 5f 54 4f 5f 50 47 48  fine PAGE_TO_PGH
2740: 44 52 31 28 63 2c 20 70 29 20 28 50 67 48 64 72  DR1(c, p) (PgHdr
2750: 31 2a 29 28 28 28 63 68 61 72 2a 29 70 29 20 2b  1*)(((char*)p) +
2760: 20 63 2d 3e 73 7a 50 61 67 65 29 0a 0a 2f 2a 0a   c->szPage)../*.
2770: 2a 2a 20 42 6c 6f 63 6b 73 20 75 73 65 64 20 62  ** Blocks used b
2780: 79 20 74 68 65 20 53 51 4c 49 54 45 5f 50 41 47  y the SQLITE_PAG
2790: 45 43 41 43 48 45 5f 42 4c 4f 43 4b 41 4c 4c 4f  ECACHE_BLOCKALLO
27a0: 43 20 62 6c 6f 63 6b 73 20 74 6f 20 73 74 6f 72  C blocks to stor
27b0: 65 2f 72 65 74 72 69 65 76 65 20 0a 2a 2a 20 61  e/retrieve .** a
27c0: 20 50 47 72 6f 75 70 42 6c 6f 63 6b 20 70 6f 69   PGroupBlock poi
27d0: 6e 74 65 72 20 62 61 73 65 64 20 6f 6e 20 61 20  nter based on a 
27e0: 70 6f 69 6e 74 65 72 20 74 6f 20 61 20 70 61 67  pointer to a pag
27f0: 65 20 62 75 66 66 65 72 2e 20 0a 2a 2f 0a 23 64  e buffer. .*/.#d
2800: 65 66 69 6e 65 20 50 41 47 45 5f 53 45 54 5f 42  efine PAGE_SET_B
2810: 4c 4f 43 4b 50 54 52 28 70 43 61 63 68 65 2c 20  LOCKPTR(pCache, 
2820: 70 50 67 2c 20 70 42 6c 6f 63 6b 29 20 5c 0a 20  pPg, pBlock) \. 
2830: 20 28 20 2a 28 50 47 72 6f 75 70 42 6c 6f 63 6b   ( *(PGroupBlock
2840: 20 2a 2a 29 26 28 28 28 75 38 2a 29 70 50 67 29   **)&(((u8*)pPg)
2850: 5b 73 69 7a 65 6f 66 28 50 67 48 64 72 31 29 20  [sizeof(PgHdr1) 
2860: 2b 20 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65  + pCache->szPage
2870: 5d 29 20 3d 20 70 42 6c 6f 63 6b 20 29 0a 0a 23  ]) = pBlock )..#
2880: 64 65 66 69 6e 65 20 50 41 47 45 5f 47 45 54 5f  define PAGE_GET_
2890: 42 4c 4f 43 4b 50 54 52 28 70 43 61 63 68 65 2c  BLOCKPTR(pCache,
28a0: 20 70 50 67 29 20 5c 0a 20 20 28 20 2a 28 50 47   pPg) \.  ( *(PG
28b0: 72 6f 75 70 42 6c 6f 63 6b 20 2a 2a 29 26 28 28  roupBlock **)&((
28c0: 28 75 38 2a 29 70 50 67 29 5b 73 69 7a 65 6f 66  (u8*)pPg)[sizeof
28d0: 28 50 67 48 64 72 31 29 20 2b 20 70 43 61 63 68  (PgHdr1) + pCach
28e0: 65 2d 3e 73 7a 50 61 67 65 5d 29 20 29 0a 0a 0a  e->szPage]) )...
28f0: 2f 2a 0a 2a 2a 20 4d 61 63 72 6f 73 20 74 6f 20  /*.** Macros to 
2900: 65 6e 74 65 72 20 61 6e 64 20 6c 65 61 76 65 20  enter and leave 
2910: 74 68 65 20 50 43 61 63 68 65 20 4c 52 55 20 6d  the PCache LRU m
2920: 75 74 65 78 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65  utex..*/.#define
2930: 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74   pcache1EnterMut
2940: 65 78 28 58 29 20 73 71 6c 69 74 65 33 5f 6d 75  ex(X) sqlite3_mu
2950: 74 65 78 5f 65 6e 74 65 72 28 28 58 29 2d 3e 6d  tex_enter((X)->m
2960: 75 74 65 78 29 0a 23 64 65 66 69 6e 65 20 70 63  utex).#define pc
2970: 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28  ache1LeaveMutex(
2980: 58 29 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78  X) sqlite3_mutex
2990: 5f 6c 65 61 76 65 28 28 58 29 2d 3e 6d 75 74 65  _leave((X)->mute
29a0: 78 29 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  x)../***********
29b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
29c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
29d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
29e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
29f0: 2a 2a 2a 2f 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 20 50  ***/./******** P
2a00: 61 67 65 20 41 6c 6c 6f 63 61 74 69 6f 6e 2f 53  age Allocation/S
2a10: 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 43 41  QLITE_CONFIG_PCA
2a20: 43 48 45 20 52 65 6c 61 74 65 64 20 46 75 6e 63  CHE Related Func
2a30: 74 69 6f 6e 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  tions **********
2a40: 2a 2a 2a 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 54 68 69  ****/../*.** Thi
2a50: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61  s function is ca
2a60: 6c 6c 65 64 20 64 75 72 69 6e 67 20 69 6e 69 74  lled during init
2a70: 69 61 6c 69 7a 61 74 69 6f 6e 20 69 66 20 61 20  ialization if a 
2a80: 73 74 61 74 69 63 20 62 75 66 66 65 72 20 69 73  static buffer is
2a90: 20 0a 2a 2a 20 73 75 70 70 6c 69 65 64 20 74 6f   .** supplied to
2aa0: 20 75 73 65 20 66 6f 72 20 74 68 65 20 70 61 67   use for the pag
2ab0: 65 2d 63 61 63 68 65 20 62 79 20 70 61 73 73 69  e-cache by passi
2ac0: 6e 67 20 74 68 65 20 53 51 4c 49 54 45 5f 43 4f  ng the SQLITE_CO
2ad0: 4e 46 49 47 5f 50 41 47 45 43 41 43 48 45 0a 2a  NFIG_PAGECACHE.*
2ae0: 2a 20 76 65 72 62 20 74 6f 20 73 71 6c 69 74 65  * verb to sqlite
2af0: 33 5f 63 6f 6e 66 69 67 28 29 2e 20 50 61 72 61  3_config(). Para
2b00: 6d 65 74 65 72 20 70 42 75 66 20 70 6f 69 6e 74  meter pBuf point
2b10: 73 20 74 6f 20 61 6e 20 61 6c 6c 6f 63 61 74 69  s to an allocati
2b20: 6f 6e 20 6c 61 72 67 65 0a 2a 2a 20 65 6e 6f 75  on large.** enou
2b30: 67 68 20 74 6f 20 63 6f 6e 74 61 69 6e 20 27 6e  gh to contain 'n
2b40: 27 20 62 75 66 66 65 72 73 20 6f 66 20 27 73 7a  ' buffers of 'sz
2b50: 27 20 62 79 74 65 73 20 65 61 63 68 2e 0a 2a 2a  ' bytes each..**
2b60: 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65  .** This routine
2b70: 20 69 73 20 63 61 6c 6c 65 64 20 66 72 6f 6d 20   is called from 
2b80: 73 71 6c 69 74 65 33 5f 69 6e 69 74 69 61 6c 69  sqlite3_initiali
2b90: 7a 65 28 29 20 61 6e 64 20 73 6f 20 69 74 20 69  ze() and so it i
2ba0: 73 20 67 75 61 72 61 6e 74 65 65 64 0a 2a 2a 20  s guaranteed.** 
2bb0: 74 6f 20 62 65 20 73 65 72 69 61 6c 69 7a 65 64  to be serialized
2bc0: 20 61 6c 72 65 61 64 79 2e 20 20 54 68 65 72 65   already.  There
2bd0: 20 69 73 20 6e 6f 20 6e 65 65 64 20 66 6f 72 20   is no need for 
2be0: 66 75 72 74 68 65 72 20 6d 75 74 65 78 69 6e 67  further mutexing
2bf0: 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
2c00: 33 50 43 61 63 68 65 42 75 66 66 65 72 53 65 74  3PCacheBufferSet
2c10: 75 70 28 76 6f 69 64 20 2a 70 42 75 66 2c 20 69  up(void *pBuf, i
2c20: 6e 74 20 73 7a 2c 20 69 6e 74 20 6e 29 7b 0a 20  nt sz, int n){. 
2c30: 20 69 66 28 20 70 63 61 63 68 65 31 2e 69 73 49   if( pcache1.isI
2c40: 6e 69 74 20 29 7b 0a 20 20 20 20 50 67 46 72 65  nit ){.    PgFre
2c50: 65 73 6c 6f 74 20 2a 70 3b 0a 20 20 20 20 73 7a  eslot *p;.    sz
2c60: 20 3d 20 52 4f 55 4e 44 44 4f 57 4e 38 28 73 7a   = ROUNDDOWN8(sz
2c70: 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 73  );.    pcache1.s
2c80: 7a 53 6c 6f 74 20 3d 20 73 7a 3b 0a 20 20 20 20  zSlot = sz;.    
2c90: 70 63 61 63 68 65 31 2e 6e 53 6c 6f 74 20 3d 20  pcache1.nSlot = 
2ca0: 70 63 61 63 68 65 31 2e 6e 46 72 65 65 53 6c 6f  pcache1.nFreeSlo
2cb0: 74 20 3d 20 6e 3b 0a 20 20 20 20 70 63 61 63 68  t = n;.    pcach
2cc0: 65 31 2e 6e 52 65 73 65 72 76 65 20 3d 20 6e 3e  e1.nReserve = n>
2cd0: 39 30 20 3f 20 31 30 20 3a 20 28 6e 2f 31 30 20  90 ? 10 : (n/10 
2ce0: 2b 20 31 29 3b 0a 20 20 20 20 70 63 61 63 68 65  + 1);.    pcache
2cf0: 31 2e 70 53 74 61 72 74 20 3d 20 70 42 75 66 3b  1.pStart = pBuf;
2d00: 0a 20 20 20 20 70 63 61 63 68 65 31 2e 70 46 72  .    pcache1.pFr
2d10: 65 65 20 3d 20 30 3b 0a 20 20 20 20 70 63 61 63  ee = 0;.    pcac
2d20: 68 65 31 2e 62 55 6e 64 65 72 50 72 65 73 73 75  he1.bUnderPressu
2d30: 72 65 20 3d 20 30 3b 0a 20 20 20 20 77 68 69 6c  re = 0;.    whil
2d40: 65 28 20 6e 2d 2d 20 29 7b 0a 20 20 20 20 20 20  e( n-- ){.      
2d50: 70 20 3d 20 28 50 67 46 72 65 65 73 6c 6f 74 2a  p = (PgFreeslot*
2d60: 29 70 42 75 66 3b 0a 20 20 20 20 20 20 70 2d 3e  )pBuf;.      p->
2d70: 70 4e 65 78 74 20 3d 20 70 63 61 63 68 65 31 2e  pNext = pcache1.
2d80: 70 46 72 65 65 3b 0a 20 20 20 20 20 20 70 63 61  pFree;.      pca
2d90: 63 68 65 31 2e 70 46 72 65 65 20 3d 20 70 3b 0a  che1.pFree = p;.
2da0: 20 20 20 20 20 20 70 42 75 66 20 3d 20 28 76 6f        pBuf = (vo
2db0: 69 64 2a 29 26 28 28 63 68 61 72 2a 29 70 42 75  id*)&((char*)pBu
2dc0: 66 29 5b 73 7a 5d 3b 0a 20 20 20 20 7d 0a 20 20  f)[sz];.    }.  
2dd0: 20 20 70 63 61 63 68 65 31 2e 70 45 6e 64 20 3d    pcache1.pEnd =
2de0: 20 70 42 75 66 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a   pBuf;.  }.}../*
2df0: 0a 2a 2a 20 4d 61 6c 6c 6f 63 20 66 75 6e 63 74  .** Malloc funct
2e00: 69 6f 6e 20 75 73 65 64 20 77 69 74 68 69 6e 20  ion used within 
2e10: 74 68 69 73 20 66 69 6c 65 20 74 6f 20 61 6c 6c  this file to all
2e20: 6f 63 61 74 65 20 73 70 61 63 65 20 66 72 6f 6d  ocate space from
2e30: 20 74 68 65 20 62 75 66 66 65 72 0a 2a 2a 20 63   the buffer.** c
2e40: 6f 6e 66 69 67 75 72 65 64 20 75 73 69 6e 67 20  onfigured using 
2e50: 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67 28 53  sqlite3_config(S
2e60: 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47  QLITE_CONFIG_PAG
2e70: 45 43 41 43 48 45 29 20 6f 70 74 69 6f 6e 2e 20  ECACHE) option. 
2e80: 49 66 20 6e 6f 20 0a 2a 2a 20 73 75 63 68 20 62  If no .** such b
2e90: 75 66 66 65 72 20 65 78 69 73 74 73 20 6f 72 20  uffer exists or 
2ea0: 74 68 65 72 65 20 69 73 20 6e 6f 20 73 70 61 63  there is no spac
2eb0: 65 20 6c 65 66 74 20 69 6e 20 69 74 2c 20 74 68  e left in it, th
2ec0: 69 73 20 66 75 6e 63 74 69 6f 6e 20 66 61 6c 6c  is function fall
2ed0: 73 20 0a 2a 2a 20 62 61 63 6b 20 74 6f 20 73 71  s .** back to sq
2ee0: 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 29 2e 0a 2a  lite3Malloc()..*
2ef0: 2a 0a 2a 2a 20 4d 75 6c 74 69 70 6c 65 20 74 68  *.** Multiple th
2f00: 72 65 61 64 73 20 63 61 6e 20 72 75 6e 20 74 68  reads can run th
2f10: 69 73 20 72 6f 75 74 69 6e 65 20 61 74 20 74 68  is routine at th
2f20: 65 20 73 61 6d 65 20 74 69 6d 65 2e 20 20 47 6c  e same time.  Gl
2f30: 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73 0a 2a  obal variables.*
2f40: 2a 20 69 6e 20 70 63 61 63 68 65 31 20 6e 65 65  * in pcache1 nee
2f50: 64 20 74 6f 20 62 65 20 70 72 6f 74 65 63 74 65  d to be protecte
2f60: 64 20 76 69 61 20 6d 75 74 65 78 2e 0a 2a 2f 0a  d via mutex..*/.
2f70: 73 74 61 74 69 63 20 76 6f 69 64 20 2a 70 63 61  static void *pca
2f80: 63 68 65 31 41 6c 6c 6f 63 28 69 6e 74 20 6e 42  che1Alloc(int nB
2f90: 79 74 65 29 7b 0a 20 20 76 6f 69 64 20 2a 70 20  yte){.  void *p 
2fa0: 3d 20 30 3b 0a 20 20 61 73 73 65 72 74 28 20 73  = 0;.  assert( s
2fb0: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6e 6f 74  qlite3_mutex_not
2fc0: 68 65 6c 64 28 70 63 61 63 68 65 31 2e 67 72 70  held(pcache1.grp
2fd0: 2e 6d 75 74 65 78 29 20 29 3b 0a 20 20 73 71 6c  .mutex) );.  sql
2fe0: 69 74 65 33 53 74 61 74 75 73 53 65 74 28 53 51  ite3StatusSet(SQ
2ff0: 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41 47 45  LITE_STATUS_PAGE
3000: 43 41 43 48 45 5f 53 49 5a 45 2c 20 6e 42 79 74  CACHE_SIZE, nByt
3010: 65 29 3b 0a 20 20 69 66 28 20 6e 42 79 74 65 3c  e);.  if( nByte<
3020: 3d 70 63 61 63 68 65 31 2e 73 7a 53 6c 6f 74 20  =pcache1.szSlot 
3030: 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 6d  ){.    sqlite3_m
3040: 75 74 65 78 5f 65 6e 74 65 72 28 70 63 61 63 68  utex_enter(pcach
3050: 65 31 2e 6d 75 74 65 78 29 3b 0a 20 20 20 20 70  e1.mutex);.    p
3060: 20 3d 20 28 50 67 48 64 72 31 20 2a 29 70 63 61   = (PgHdr1 *)pca
3070: 63 68 65 31 2e 70 46 72 65 65 3b 0a 20 20 20 20  che1.pFree;.    
3080: 69 66 28 20 70 20 29 7b 0a 20 20 20 20 20 20 70  if( p ){.      p
3090: 63 61 63 68 65 31 2e 70 46 72 65 65 20 3d 20 70  cache1.pFree = p
30a0: 63 61 63 68 65 31 2e 70 46 72 65 65 2d 3e 70 4e  cache1.pFree->pN
30b0: 65 78 74 3b 0a 20 20 20 20 20 20 70 63 61 63 68  ext;.      pcach
30c0: 65 31 2e 6e 46 72 65 65 53 6c 6f 74 2d 2d 3b 0a  e1.nFreeSlot--;.
30d0: 20 20 20 20 20 20 70 63 61 63 68 65 31 2e 62 55        pcache1.bU
30e0: 6e 64 65 72 50 72 65 73 73 75 72 65 20 3d 20 70  nderPressure = p
30f0: 63 61 63 68 65 31 2e 6e 46 72 65 65 53 6c 6f 74  cache1.nFreeSlot
3100: 3c 70 63 61 63 68 65 31 2e 6e 52 65 73 65 72 76  <pcache1.nReserv
3110: 65 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28  e;.      assert(
3120: 20 70 63 61 63 68 65 31 2e 6e 46 72 65 65 53 6c   pcache1.nFreeSl
3130: 6f 74 3e 3d 30 20 29 3b 0a 20 20 20 20 20 20 73  ot>=0 );.      s
3140: 71 6c 69 74 65 33 53 74 61 74 75 73 41 64 64 28  qlite3StatusAdd(
3150: 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41  SQLITE_STATUS_PA
3160: 47 45 43 41 43 48 45 5f 55 53 45 44 2c 20 31 29  GECACHE_USED, 1)
3170: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 6c 69  ;.    }.    sqli
3180: 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28  te3_mutex_leave(
3190: 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a  pcache1.mutex);.
31a0: 20 20 7d 0a 20 20 69 66 28 20 70 3d 3d 30 20 29    }.  if( p==0 )
31b0: 7b 0a 20 20 20 20 2f 2a 20 4d 65 6d 6f 72 79 20  {.    /* Memory 
31c0: 69 73 20 6e 6f 74 20 61 76 61 69 6c 61 62 6c 65  is not available
31d0: 20 69 6e 20 74 68 65 20 53 51 4c 49 54 45 5f 43   in the SQLITE_C
31e0: 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48 45 20  ONFIG_PAGECACHE 
31f0: 70 6f 6f 6c 2e 20 20 47 65 74 0a 20 20 20 20 2a  pool.  Get.    *
3200: 2a 20 69 74 20 66 72 6f 6d 20 73 71 6c 69 74 65  * it from sqlite
3210: 33 4d 61 6c 6c 6f 63 20 69 6e 73 74 65 61 64 2e  3Malloc instead.
3220: 0a 20 20 20 20 2a 2f 0a 20 20 20 20 70 20 3d 20  .    */.    p = 
3230: 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 6e 42  sqlite3Malloc(nB
3240: 79 74 65 29 3b 0a 20 20 20 20 69 66 28 20 70 20  yte);.    if( p 
3250: 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 73 7a 20  ){.      int sz 
3260: 3d 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 53  = sqlite3MallocS
3270: 69 7a 65 28 70 29 3b 0a 20 20 20 20 20 20 73 71  ize(p);.      sq
3280: 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e 74 65  lite3_mutex_ente
3290: 72 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29  r(pcache1.mutex)
32a0: 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 53  ;.      sqlite3S
32b0: 74 61 74 75 73 41 64 64 28 53 51 4c 49 54 45 5f  tatusAdd(SQLITE_
32c0: 53 54 41 54 55 53 5f 50 41 47 45 43 41 43 48 45  STATUS_PAGECACHE
32d0: 5f 4f 56 45 52 46 4c 4f 57 2c 20 73 7a 29 3b 0a  _OVERFLOW, sz);.
32e0: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 75        sqlite3_mu
32f0: 74 65 78 5f 6c 65 61 76 65 28 70 63 61 63 68 65  tex_leave(pcache
3300: 31 2e 6d 75 74 65 78 29 3b 0a 20 20 20 20 7d 0a  1.mutex);.    }.
3310: 20 20 20 20 73 71 6c 69 74 65 33 4d 65 6d 64 65      sqlite3Memde
3320: 62 75 67 53 65 74 54 79 70 65 28 70 2c 20 4d 45  bugSetType(p, ME
3330: 4d 54 59 50 45 5f 50 43 41 43 48 45 29 3b 0a 20  MTYPE_PCACHE);. 
3340: 20 7d 0a 20 20 72 65 74 75 72 6e 20 70 3b 0a 7d   }.  return p;.}
3350: 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61 6e 20  ../*.** Free an 
3360: 61 6c 6c 6f 63 61 74 65 64 20 62 75 66 66 65 72  allocated buffer
3370: 20 6f 62 74 61 69 6e 65 64 20 66 72 6f 6d 20 70   obtained from p
3380: 63 61 63 68 65 31 41 6c 6c 6f 63 28 29 2e 0a 2a  cache1Alloc()..*
3390: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63  /.static void pc
33a0: 61 63 68 65 31 46 72 65 65 28 76 6f 69 64 20 2a  ache1Free(void *
33b0: 70 29 7b 0a 20 20 69 66 28 20 70 3d 3d 30 20 29  p){.  if( p==0 )
33c0: 20 72 65 74 75 72 6e 3b 0a 20 20 69 66 28 20 70   return;.  if( p
33d0: 3e 3d 70 63 61 63 68 65 31 2e 70 53 74 61 72 74  >=pcache1.pStart
33e0: 20 26 26 20 70 3c 70 63 61 63 68 65 31 2e 70 45   && p<pcache1.pE
33f0: 6e 64 20 29 7b 0a 20 20 20 20 50 67 46 72 65 65  nd ){.    PgFree
3400: 73 6c 6f 74 20 2a 70 53 6c 6f 74 3b 0a 20 20 20  slot *pSlot;.   
3410: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65   sqlite3_mutex_e
3420: 6e 74 65 72 28 70 63 61 63 68 65 31 2e 6d 75 74  nter(pcache1.mut
3430: 65 78 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  ex);.    sqlite3
3440: 53 74 61 74 75 73 41 64 64 28 53 51 4c 49 54 45  StatusAdd(SQLITE
3450: 5f 53 54 41 54 55 53 5f 50 41 47 45 43 41 43 48  _STATUS_PAGECACH
3460: 45 5f 55 53 45 44 2c 20 2d 31 29 3b 0a 20 20 20  E_USED, -1);.   
3470: 20 70 53 6c 6f 74 20 3d 20 28 50 67 46 72 65 65   pSlot = (PgFree
3480: 73 6c 6f 74 2a 29 70 3b 0a 20 20 20 20 70 53 6c  slot*)p;.    pSl
3490: 6f 74 2d 3e 70 4e 65 78 74 20 3d 20 70 63 61 63  ot->pNext = pcac
34a0: 68 65 31 2e 70 46 72 65 65 3b 0a 20 20 20 20 70  he1.pFree;.    p
34b0: 63 61 63 68 65 31 2e 70 46 72 65 65 20 3d 20 70  cache1.pFree = p
34c0: 53 6c 6f 74 3b 0a 20 20 20 20 70 63 61 63 68 65  Slot;.    pcache
34d0: 31 2e 6e 46 72 65 65 53 6c 6f 74 2b 2b 3b 0a 20  1.nFreeSlot++;. 
34e0: 20 20 20 70 63 61 63 68 65 31 2e 62 55 6e 64 65     pcache1.bUnde
34f0: 72 50 72 65 73 73 75 72 65 20 3d 20 70 63 61 63  rPressure = pcac
3500: 68 65 31 2e 6e 46 72 65 65 53 6c 6f 74 3c 70 63  he1.nFreeSlot<pc
3510: 61 63 68 65 31 2e 6e 52 65 73 65 72 76 65 3b 0a  ache1.nReserve;.
3520: 20 20 20 20 61 73 73 65 72 74 28 20 70 63 61 63      assert( pcac
3530: 68 65 31 2e 6e 46 72 65 65 53 6c 6f 74 3c 3d 70  he1.nFreeSlot<=p
3540: 63 61 63 68 65 31 2e 6e 53 6c 6f 74 20 29 3b 0a  cache1.nSlot );.
3550: 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65      sqlite3_mute
3560: 78 5f 6c 65 61 76 65 28 70 63 61 63 68 65 31 2e  x_leave(pcache1.
3570: 6d 75 74 65 78 29 3b 0a 20 20 7d 65 6c 73 65 7b  mutex);.  }else{
3580: 0a 20 20 20 20 69 6e 74 20 69 53 69 7a 65 3b 0a  .    int iSize;.
3590: 20 20 20 20 61 73 73 65 72 74 28 20 73 71 6c 69      assert( sqli
35a0: 74 65 33 4d 65 6d 64 65 62 75 67 48 61 73 54 79  te3MemdebugHasTy
35b0: 70 65 28 70 2c 20 4d 45 4d 54 59 50 45 5f 50 43  pe(p, MEMTYPE_PC
35c0: 41 43 48 45 29 20 29 3b 0a 20 20 20 20 73 71 6c  ACHE) );.    sql
35d0: 69 74 65 33 4d 65 6d 64 65 62 75 67 53 65 74 54  ite3MemdebugSetT
35e0: 79 70 65 28 70 2c 20 4d 45 4d 54 59 50 45 5f 48  ype(p, MEMTYPE_H
35f0: 45 41 50 29 3b 0a 20 20 20 20 69 53 69 7a 65 20  EAP);.    iSize 
3600: 3d 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 53  = sqlite3MallocS
3610: 69 7a 65 28 70 29 3b 0a 20 20 20 20 73 71 6c 69  ize(p);.    sqli
3620: 74 65 33 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28  te3_mutex_enter(
3630: 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a  pcache1.mutex);.
3640: 20 20 20 20 73 71 6c 69 74 65 33 53 74 61 74 75      sqlite3Statu
3650: 73 41 64 64 28 53 51 4c 49 54 45 5f 53 54 41 54  sAdd(SQLITE_STAT
3660: 55 53 5f 50 41 47 45 43 41 43 48 45 5f 4f 56 45  US_PAGECACHE_OVE
3670: 52 46 4c 4f 57 2c 20 2d 69 53 69 7a 65 29 3b 0a  RFLOW, -iSize);.
3680: 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65      sqlite3_mute
3690: 78 5f 6c 65 61 76 65 28 70 63 61 63 68 65 31 2e  x_leave(pcache1.
36a0: 6d 75 74 65 78 29 3b 0a 20 20 20 20 73 71 6c 69  mutex);.    sqli
36b0: 74 65 33 5f 66 72 65 65 28 70 29 3b 0a 20 20 7d  te3_free(p);.  }
36c0: 0a 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54  .}..#ifdef SQLIT
36d0: 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f  E_ENABLE_MEMORY_
36e0: 4d 41 4e 41 47 45 4d 45 4e 54 0a 2f 2a 0a 2a 2a  MANAGEMENT./*.**
36f0: 20 52 65 74 75 72 6e 20 74 68 65 20 73 69 7a 65   Return the size
3700: 20 6f 66 20 61 20 70 63 61 63 68 65 20 61 6c 6c   of a pcache all
3710: 6f 63 61 74 69 6f 6e 0a 2a 2f 0a 73 74 61 74 69  ocation.*/.stati
3720: 63 20 69 6e 74 20 70 63 61 63 68 65 31 4d 65 6d  c int pcache1Mem
3730: 53 69 7a 65 28 76 6f 69 64 20 2a 70 29 7b 0a 20  Size(void *p){. 
3740: 20 69 66 28 20 70 3e 3d 70 63 61 63 68 65 31 2e   if( p>=pcache1.
3750: 70 53 74 61 72 74 20 26 26 20 70 3c 70 63 61 63  pStart && p<pcac
3760: 68 65 31 2e 70 45 6e 64 20 29 7b 0a 20 20 20 20  he1.pEnd ){.    
3770: 72 65 74 75 72 6e 20 70 63 61 63 68 65 31 2e 73  return pcache1.s
3780: 7a 53 6c 6f 74 3b 0a 20 20 7d 65 6c 73 65 7b 0a  zSlot;.  }else{.
3790: 20 20 20 20 69 6e 74 20 69 53 69 7a 65 3b 0a 20      int iSize;. 
37a0: 20 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74     assert( sqlit
37b0: 65 33 4d 65 6d 64 65 62 75 67 48 61 73 54 79 70  e3MemdebugHasTyp
37c0: 65 28 70 2c 20 4d 45 4d 54 59 50 45 5f 50 43 41  e(p, MEMTYPE_PCA
37d0: 43 48 45 29 20 29 3b 0a 20 20 20 20 73 71 6c 69  CHE) );.    sqli
37e0: 74 65 33 4d 65 6d 64 65 62 75 67 53 65 74 54 79  te3MemdebugSetTy
37f0: 70 65 28 70 2c 20 4d 45 4d 54 59 50 45 5f 48 45  pe(p, MEMTYPE_HE
3800: 41 50 29 3b 0a 20 20 20 20 69 53 69 7a 65 20 3d  AP);.    iSize =
3810: 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 53 69   sqlite3MallocSi
3820: 7a 65 28 70 29 3b 0a 20 20 20 20 73 71 6c 69 74  ze(p);.    sqlit
3830: 65 33 4d 65 6d 64 65 62 75 67 53 65 74 54 79 70  e3MemdebugSetTyp
3840: 65 28 70 2c 20 4d 45 4d 54 59 50 45 5f 50 43 41  e(p, MEMTYPE_PCA
3850: 43 48 45 29 3b 0a 20 20 20 20 72 65 74 75 72 6e  CHE);.    return
3860: 20 69 53 69 7a 65 3b 0a 20 20 7d 0a 7d 0a 23 65   iSize;.  }.}.#e
3870: 6e 64 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f 45  ndif /* SQLITE_E
3880: 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e  NABLE_MEMORY_MAN
3890: 41 47 45 4d 45 4e 54 20 2a 2f 0a 0a 23 69 66 64  AGEMENT */..#ifd
38a0: 65 66 20 53 51 4c 49 54 45 5f 50 41 47 45 43 41  ef SQLITE_PAGECA
38b0: 43 48 45 5f 42 4c 4f 43 4b 41 4c 4c 4f 43 0a 2f  CHE_BLOCKALLOC./
38c0: 2a 0a 2a 2a 20 54 68 65 20 62 6c 6f 63 6b 20 70  *.** The block p
38d0: 42 6c 6f 63 6b 20 62 65 6c 6f 6e 67 73 20 74 6f  Block belongs to
38e0: 20 6c 69 73 74 20 70 4c 69 73 74 20 62 75 74 20   list pList but 
38f0: 69 73 20 6e 6f 74 20 63 75 72 72 65 6e 74 6c 79  is not currently
3900: 20 6c 69 6e 6b 65 64 20 69 6e 2e 0a 2a 2a 20 49   linked in..** I
3910: 6e 73 65 72 74 20 69 74 20 69 6e 74 6f 20 74 68  nsert it into th
3920: 65 20 73 74 61 72 74 20 6f 66 20 74 68 65 20 6c  e start of the l
3930: 69 73 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ist..*/.static v
3940: 6f 69 64 20 61 64 64 42 6c 6f 63 6b 54 6f 4c 69  oid addBlockToLi
3950: 73 74 28 50 47 72 6f 75 70 42 6c 6f 63 6b 4c 69  st(PGroupBlockLi
3960: 73 74 20 2a 70 4c 69 73 74 2c 20 50 47 72 6f 75  st *pList, PGrou
3970: 70 42 6c 6f 63 6b 20 2a 70 42 6c 6f 63 6b 29 7b  pBlock *pBlock){
3980: 0a 20 20 70 42 6c 6f 63 6b 2d 3e 70 50 72 65 76  .  pBlock->pPrev
3990: 20 3d 20 30 3b 0a 20 20 70 42 6c 6f 63 6b 2d 3e   = 0;.  pBlock->
39a0: 70 4e 65 78 74 20 3d 20 70 4c 69 73 74 2d 3e 70  pNext = pList->p
39b0: 46 69 72 73 74 3b 0a 20 20 70 4c 69 73 74 2d 3e  First;.  pList->
39c0: 70 46 69 72 73 74 20 3d 20 70 42 6c 6f 63 6b 3b  pFirst = pBlock;
39d0: 0a 20 20 69 66 28 20 70 42 6c 6f 63 6b 2d 3e 70  .  if( pBlock->p
39e0: 4e 65 78 74 20 29 7b 0a 20 20 20 20 70 42 6c 6f  Next ){.    pBlo
39f0: 63 6b 2d 3e 70 4e 65 78 74 2d 3e 70 50 72 65 76  ck->pNext->pPrev
3a00: 20 3d 20 70 42 6c 6f 63 6b 3b 0a 20 20 7d 65 6c   = pBlock;.  }el
3a10: 73 65 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20  se{.    assert( 
3a20: 70 4c 69 73 74 2d 3e 70 4c 61 73 74 3d 3d 30 20  pList->pLast==0 
3a30: 29 3b 0a 20 20 20 20 70 4c 69 73 74 2d 3e 70 4c  );.    pList->pL
3a40: 61 73 74 20 3d 20 70 42 6c 6f 63 6b 3b 0a 20 20  ast = pBlock;.  
3a50: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 74 68  }.}../*.** If th
3a60: 65 72 65 20 61 72 65 20 6e 6f 20 62 6c 6f 63 6b  ere are no block
3a70: 73 20 69 6e 20 74 68 65 20 6c 69 73 74 20 68 65  s in the list he
3a80: 61 64 65 64 20 62 79 20 70 4c 69 73 74 2c 20 72  aded by pList, r
3a90: 65 6d 6f 76 65 20 70 4c 69 73 74 0a 2a 2a 20 66  emove pList.** f
3aa0: 72 6f 6d 20 74 68 65 20 70 47 72 6f 75 70 2d 3e  rom the pGroup->
3ab0: 70 42 6c 6f 63 6b 4c 69 73 74 20 6c 69 73 74 20  pBlockList list 
3ac0: 61 6e 64 20 66 72 65 65 20 69 74 20 77 69 74 68  and free it with
3ad0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 29 2e   sqlite3_free().
3ae0: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
3af0: 66 72 65 65 4c 69 73 74 49 66 45 6d 70 74 79 28  freeListIfEmpty(
3b00: 50 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 2c 20  PGroup *pGroup, 
3b10: 50 47 72 6f 75 70 42 6c 6f 63 6b 4c 69 73 74 20  PGroupBlockList 
3b20: 2a 70 4c 69 73 74 29 7b 0a 20 20 61 73 73 65 72  *pList){.  asser
3b30: 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78  t( sqlite3_mutex
3b40: 5f 68 65 6c 64 28 70 47 72 6f 75 70 2d 3e 6d 75  _held(pGroup->mu
3b50: 74 65 78 29 20 29 3b 0a 20 20 69 66 28 20 70 4c  tex) );.  if( pL
3b60: 69 73 74 2d 3e 70 46 69 72 73 74 3d 3d 30 20 29  ist->pFirst==0 )
3b70: 7b 0a 20 20 20 20 50 47 72 6f 75 70 42 6c 6f 63  {.    PGroupBloc
3b80: 6b 4c 69 73 74 20 2a 2a 70 70 3b 0a 20 20 20 20  kList **pp;.    
3b90: 66 6f 72 28 70 70 3d 26 70 47 72 6f 75 70 2d 3e  for(pp=&pGroup->
3ba0: 70 42 6c 6f 63 6b 4c 69 73 74 3b 20 2a 70 70 21  pBlockList; *pp!
3bb0: 3d 70 4c 69 73 74 3b 20 70 70 3d 26 28 2a 70 70  =pList; pp=&(*pp
3bc0: 29 2d 3e 70 4e 65 78 74 29 3b 0a 20 20 20 20 2a  )->pNext);.    *
3bd0: 70 70 20 3d 20 28 2a 70 70 29 2d 3e 70 4e 65 78  pp = (*pp)->pNex
3be0: 74 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66  t;.    sqlite3_f
3bf0: 72 65 65 28 70 4c 69 73 74 29 3b 0a 20 20 7d 0a  ree(pList);.  }.
3c00: 7d 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49  }.#endif /* SQLI
3c10: 54 45 5f 50 41 47 45 43 41 43 48 45 5f 42 4c 4f  TE_PAGECACHE_BLO
3c20: 43 4b 41 4c 4c 4f 43 20 2a 2f 0a 0a 2f 2a 0a 2a  CKALLOC */../*.*
3c30: 2a 20 41 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77  * Allocate a new
3c40: 20 70 61 67 65 20 6f 62 6a 65 63 74 20 69 6e 69   page object ini
3c50: 74 69 61 6c 6c 79 20 61 73 73 6f 63 69 61 74 65  tially associate
3c60: 64 20 77 69 74 68 20 63 61 63 68 65 20 70 43 61  d with cache pCa
3c70: 63 68 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 50  che..*/.static P
3c80: 67 48 64 72 31 20 2a 70 63 61 63 68 65 31 41 6c  gHdr1 *pcache1Al
3c90: 6c 6f 63 50 61 67 65 28 50 43 61 63 68 65 31 20  locPage(PCache1 
3ca0: 2a 70 43 61 63 68 65 29 7b 0a 20 20 69 6e 74 20  *pCache){.  int 
3cb0: 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 50  nByte = sizeof(P
3cc0: 67 48 64 72 31 29 20 2b 20 70 43 61 63 68 65 2d  gHdr1) + pCache-
3cd0: 3e 73 7a 50 61 67 65 3b 0a 20 20 76 6f 69 64 20  >szPage;.  void 
3ce0: 2a 70 50 67 20 3d 20 30 3b 0a 20 20 50 67 48 64  *pPg = 0;.  PgHd
3cf0: 72 31 20 2a 70 3b 0a 0a 23 69 66 64 65 66 20 53  r1 *p;..#ifdef S
3d00: 51 4c 49 54 45 5f 50 41 47 45 43 41 43 48 45 5f  QLITE_PAGECACHE_
3d10: 42 4c 4f 43 4b 41 4c 4c 4f 43 0a 20 20 50 47 72  BLOCKALLOC.  PGr
3d20: 6f 75 70 20 2a 70 47 72 6f 75 70 20 3d 20 70 43  oup *pGroup = pC
3d30: 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b 0a 20 20  ache->pGroup;.  
3d40: 50 47 72 6f 75 70 42 6c 6f 63 6b 4c 69 73 74 20  PGroupBlockList 
3d50: 2a 70 4c 69 73 74 3b 0a 20 20 50 47 72 6f 75 70  *pList;.  PGroup
3d60: 42 6c 6f 63 6b 20 2a 70 42 6c 6f 63 6b 3b 0a 20  Block *pBlock;. 
3d70: 20 69 6e 74 20 69 3b 0a 0a 20 20 6e 42 79 74 65   int i;..  nByte
3d80: 20 2b 3d 20 73 69 7a 65 6f 66 28 50 47 72 6f 75   += sizeof(PGrou
3d90: 70 42 6c 6f 63 6b 4c 69 73 74 20 2a 29 3b 0a 20  pBlockList *);. 
3da0: 20 6e 42 79 74 65 20 3d 20 52 4f 55 4e 44 38 28   nByte = ROUND8(
3db0: 6e 42 79 74 65 29 3b 0a 0a 20 20 66 6f 72 28 70  nByte);..  for(p
3dc0: 4c 69 73 74 3d 70 47 72 6f 75 70 2d 3e 70 42 6c  List=pGroup->pBl
3dd0: 6f 63 6b 4c 69 73 74 3b 20 70 4c 69 73 74 3b 20  ockList; pList; 
3de0: 70 4c 69 73 74 3d 70 4c 69 73 74 2d 3e 70 4e 65  pList=pList->pNe
3df0: 78 74 29 7b 0a 20 20 20 20 69 66 28 20 70 4c 69  xt){.    if( pLi
3e00: 73 74 2d 3e 6e 42 79 74 65 3d 3d 6e 42 79 74 65  st->nByte==nByte
3e10: 20 29 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 20 20   ) break;.  }.  
3e20: 69 66 28 20 70 4c 69 73 74 3d 3d 30 20 29 7b 0a  if( pList==0 ){.
3e30: 20 20 20 20 50 47 72 6f 75 70 42 6c 6f 63 6b 4c      PGroupBlockL
3e40: 69 73 74 20 2a 70 4e 65 77 3b 0a 20 20 20 20 61  ist *pNew;.    a
3e50: 73 73 65 72 74 28 20 70 47 72 6f 75 70 2d 3e 69  ssert( pGroup->i
3e60: 73 42 75 73 79 3d 3d 30 20 29 3b 0a 20 20 20 20  sBusy==0 );.    
3e70: 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f  assert( sqlite3_
3e80: 6d 75 74 65 78 5f 68 65 6c 64 28 70 47 72 6f 75  mutex_held(pGrou
3e90: 70 2d 3e 6d 75 74 65 78 29 20 29 3b 0a 20 20 20  p->mutex) );.   
3ea0: 20 70 47 72 6f 75 70 2d 3e 69 73 42 75 73 79 20   pGroup->isBusy 
3eb0: 3d 20 31 3b 20 20 2f 2a 20 44 69 73 61 62 6c 65  = 1;  /* Disable
3ec0: 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 52 65   sqlite3PcacheRe
3ed0: 6c 65 61 73 65 4d 65 6d 6f 72 79 28 29 20 2a 2f  leaseMemory() */
3ee0: 0a 20 20 20 20 70 4e 65 77 20 3d 20 28 50 47 72  .    pNew = (PGr
3ef0: 6f 75 70 42 6c 6f 63 6b 4c 69 73 74 20 2a 29 73  oupBlockList *)s
3f00: 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f  qlite3MallocZero
3f10: 28 73 69 7a 65 6f 66 28 50 47 72 6f 75 70 42 6c  (sizeof(PGroupBl
3f20: 6f 63 6b 4c 69 73 74 29 29 3b 0a 20 20 20 20 70  ockList));.    p
3f30: 47 72 6f 75 70 2d 3e 69 73 42 75 73 79 20 3d 20  Group->isBusy = 
3f40: 30 3b 20 20 2f 2a 20 52 65 65 6e 61 62 6c 65 20  0;  /* Reenable 
3f50: 73 71 6c 69 74 65 33 50 63 61 63 68 65 52 65 6c  sqlite3PcacheRel
3f60: 65 61 73 65 4d 65 6d 6f 72 79 28 29 20 2a 2f 0a  easeMemory() */.
3f70: 20 20 20 20 69 66 28 20 70 4e 65 77 3d 3d 30 20      if( pNew==0 
3f80: 29 7b 0a 20 20 20 20 20 20 2f 2a 20 6d 61 6c 6c  ){.      /* mall
3f90: 6f 63 28 29 20 66 61 69 6c 75 72 65 2e 20 52 65  oc() failure. Re
3fa0: 74 75 72 6e 20 65 61 72 6c 79 2e 20 2a 2f 0a 20  turn early. */. 
3fb0: 20 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20       return 0;. 
3fc0: 20 20 20 7d 0a 23 69 66 64 65 66 20 53 51 4c 49     }.#ifdef SQLI
3fd0: 54 45 5f 44 45 42 55 47 0a 20 20 20 20 66 6f 72  TE_DEBUG.    for
3fe0: 28 70 4c 69 73 74 3d 70 47 72 6f 75 70 2d 3e 70  (pList=pGroup->p
3ff0: 42 6c 6f 63 6b 4c 69 73 74 3b 20 70 4c 69 73 74  BlockList; pList
4000: 3b 20 70 4c 69 73 74 3d 70 4c 69 73 74 2d 3e 70  ; pList=pList->p
4010: 4e 65 78 74 29 7b 0a 20 20 20 20 20 20 61 73 73  Next){.      ass
4020: 65 72 74 28 20 70 4c 69 73 74 2d 3e 6e 42 79 74  ert( pList->nByt
4030: 65 21 3d 6e 42 79 74 65 20 29 3b 0a 20 20 20 20  e!=nByte );.    
4040: 7d 0a 23 65 6e 64 69 66 0a 20 20 20 20 70 4e 65  }.#endif.    pNe
4050: 77 2d 3e 6e 42 79 74 65 20 3d 20 6e 42 79 74 65  w->nByte = nByte
4060: 3b 0a 20 20 20 20 70 4e 65 77 2d 3e 70 4e 65 78  ;.    pNew->pNex
4070: 74 20 3d 20 70 47 72 6f 75 70 2d 3e 70 42 6c 6f  t = pGroup->pBlo
4080: 63 6b 4c 69 73 74 3b 0a 20 20 20 20 70 47 72 6f  ckList;.    pGro
4090: 75 70 2d 3e 70 42 6c 6f 63 6b 4c 69 73 74 20 3d  up->pBlockList =
40a0: 20 70 4e 65 77 3b 0a 20 20 20 20 70 4c 69 73 74   pNew;.    pList
40b0: 20 3d 20 70 4e 65 77 3b 0a 20 20 7d 0a 0a 20 20   = pNew;.  }..  
40c0: 70 42 6c 6f 63 6b 20 3d 20 70 4c 69 73 74 2d 3e  pBlock = pList->
40d0: 70 46 69 72 73 74 3b 0a 20 20 69 66 28 20 70 42  pFirst;.  if( pB
40e0: 6c 6f 63 6b 3d 3d 30 20 7c 7c 20 70 42 6c 6f 63  lock==0 || pBloc
40f0: 6b 2d 3e 6d 55 73 65 64 3d 3d 28 28 28 42 69 74  k->mUsed==(((Bit
4100: 6d 61 73 6b 29 31 3c 3c 70 42 6c 6f 63 6b 2d 3e  mask)1<<pBlock->
4110: 6e 45 6e 74 72 79 29 2d 31 29 20 29 7b 0a 20 20  nEntry)-1) ){.  
4120: 20 20 69 6e 74 20 73 7a 3b 0a 0a 20 20 20 20 2f    int sz;..    /
4130: 2a 20 41 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77  * Allocate a new
4140: 20 62 6c 6f 63 6b 2e 20 54 72 79 20 74 6f 20 61   block. Try to a
4150: 6c 6c 6f 63 61 74 65 20 65 6e 6f 75 67 68 20 73  llocate enough s
4160: 70 61 63 65 20 66 6f 72 20 74 68 65 20 50 47 72  pace for the PGr
4170: 6f 75 70 42 6c 6f 63 6b 0a 20 20 20 20 2a 2a 20  oupBlock.    ** 
4180: 73 74 72 75 63 74 75 72 65 20 61 6e 64 20 4d 49  structure and MI
4190: 4e 45 4e 54 52 59 20 61 6c 6c 6f 63 61 74 69 6f  NENTRY allocatio
41a0: 6e 73 20 6f 66 20 6e 42 79 74 65 20 62 79 74 65  ns of nByte byte
41b0: 73 20 65 61 63 68 2e 20 49 66 20 74 68 65 20 0a  s each. If the .
41c0: 20 20 20 20 2a 2a 20 61 6c 6c 6f 63 61 74 6f 72      ** allocator
41d0: 20 72 65 74 75 72 6e 73 20 6d 6f 72 65 20 6d 65   returns more me
41e0: 6d 6f 72 79 20 74 68 61 6e 20 72 65 71 75 65 73  mory than reques
41f0: 74 65 64 2c 20 74 68 65 6e 20 6d 6f 72 65 20 74  ted, then more t
4200: 68 61 6e 20 4d 49 4e 45 4e 54 52 59 20 0a 20 20  han MINENTRY .  
4210: 20 20 2a 2a 20 61 6c 6c 6f 63 61 74 69 6f 6e 73    ** allocations
4220: 20 6d 61 79 20 66 69 74 20 69 6e 20 69 74 2e 20   may fit in it. 
4230: 2a 2f 0a 20 20 20 20 61 73 73 65 72 74 28 20 73  */.    assert( s
4240: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c  qlite3_mutex_hel
4250: 64 28 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78 29  d(pGroup->mutex)
4260: 20 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31 4c   );.    pcache1L
4270: 65 61 76 65 4d 75 74 65 78 28 70 43 61 63 68 65  eaveMutex(pCache
4280: 2d 3e 70 47 72 6f 75 70 29 3b 0a 20 20 20 20 73  ->pGroup);.    s
4290: 7a 20 3d 20 73 69 7a 65 6f 66 28 50 47 72 6f 75  z = sizeof(PGrou
42a0: 70 42 6c 6f 63 6b 29 20 2b 20 50 41 47 45 43 41  pBlock) + PAGECA
42b0: 43 48 45 5f 42 4c 4f 43 4b 41 4c 4c 4f 43 5f 4d  CHE_BLOCKALLOC_M
42c0: 49 4e 45 4e 54 52 59 20 2a 20 6e 42 79 74 65 3b  INENTRY * nByte;
42d0: 0a 20 20 20 20 70 42 6c 6f 63 6b 20 3d 20 28 50  .    pBlock = (P
42e0: 47 72 6f 75 70 42 6c 6f 63 6b 20 2a 29 73 71 6c  GroupBlock *)sql
42f0: 69 74 65 33 4d 61 6c 6c 6f 63 28 73 7a 29 3b 0a  ite3Malloc(sz);.
4300: 20 20 20 20 70 63 61 63 68 65 31 45 6e 74 65 72      pcache1Enter
4310: 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e 70 47  Mutex(pCache->pG
4320: 72 6f 75 70 29 3b 0a 0a 20 20 20 20 69 66 28 20  roup);..    if( 
4330: 21 70 42 6c 6f 63 6b 20 29 7b 0a 20 20 20 20 20  !pBlock ){.     
4340: 20 66 72 65 65 4c 69 73 74 49 66 45 6d 70 74 79   freeListIfEmpty
4350: 28 70 47 72 6f 75 70 2c 20 70 4c 69 73 74 29 3b  (pGroup, pList);
4360: 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 30 3b  .      return 0;
4370: 0a 20 20 20 20 7d 0a 20 20 20 20 70 42 6c 6f 63  .    }.    pBloc
4380: 6b 2d 3e 6e 45 6e 74 72 79 20 3d 20 28 73 71 6c  k->nEntry = (sql
4390: 69 74 65 33 4d 61 6c 6c 6f 63 53 69 7a 65 28 70  ite3MallocSize(p
43a0: 42 6c 6f 63 6b 29 20 2d 20 73 69 7a 65 6f 66 28  Block) - sizeof(
43b0: 50 47 72 6f 75 70 42 6c 6f 63 6b 29 29 20 2f 20  PGroupBlock)) / 
43c0: 6e 42 79 74 65 3b 0a 20 20 20 20 69 66 28 20 70  nByte;.    if( p
43d0: 42 6c 6f 63 6b 2d 3e 6e 45 6e 74 72 79 3e 3d 42  Block->nEntry>=B
43e0: 4d 53 20 29 7b 0a 20 20 20 20 20 20 70 42 6c 6f  MS ){.      pBlo
43f0: 63 6b 2d 3e 6e 45 6e 74 72 79 20 3d 20 42 4d 53  ck->nEntry = BMS
4400: 2d 31 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 42  -1;.    }.    pB
4410: 6c 6f 63 6b 2d 3e 70 4c 69 73 74 20 3d 20 70 4c  lock->pList = pL
4420: 69 73 74 3b 0a 20 20 20 20 70 42 6c 6f 63 6b 2d  ist;.    pBlock-
4430: 3e 6d 55 73 65 64 20 3d 20 30 3b 0a 20 20 20 20  >mUsed = 0;.    
4440: 70 42 6c 6f 63 6b 2d 3e 61 44 61 74 61 20 3d 20  pBlock->aData = 
4450: 28 75 38 20 2a 29 26 70 42 6c 6f 63 6b 5b 31 5d  (u8 *)&pBlock[1]
4460: 3b 0a 20 20 20 20 61 64 64 42 6c 6f 63 6b 54 6f  ;.    addBlockTo
4470: 4c 69 73 74 28 70 4c 69 73 74 2c 20 70 42 6c 6f  List(pList, pBlo
4480: 63 6b 29 3b 0a 0a 20 20 20 20 73 7a 20 3d 20 73  ck);..    sz = s
4490: 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 53 69 7a 65  qlite3MallocSize
44a0: 28 70 42 6c 6f 63 6b 29 3b 0a 20 20 20 20 73 71  (pBlock);.    sq
44b0: 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e 74 65  lite3_mutex_ente
44c0: 72 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29  r(pcache1.mutex)
44d0: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 53 74 61  ;.    sqlite3Sta
44e0: 74 75 73 41 64 64 28 53 51 4c 49 54 45 5f 53 54  tusAdd(SQLITE_ST
44f0: 41 54 55 53 5f 50 41 47 45 43 41 43 48 45 5f 4f  ATUS_PAGECACHE_O
4500: 56 45 52 46 4c 4f 57 2c 20 73 7a 29 3b 0a 20 20  VERFLOW, sz);.  
4510: 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f    sqlite3_mutex_
4520: 6c 65 61 76 65 28 70 63 61 63 68 65 31 2e 6d 75  leave(pcache1.mu
4530: 74 65 78 29 3b 0a 20 20 7d 0a 0a 20 20 66 6f 72  tex);.  }..  for
4540: 28 69 3d 30 3b 20 70 50 67 3d 3d 30 20 26 26 20  (i=0; pPg==0 && 
4550: 41 4c 57 41 59 53 28 69 3c 70 42 6c 6f 63 6b 2d  ALWAYS(i<pBlock-
4560: 3e 6e 45 6e 74 72 79 29 3b 20 69 2b 2b 29 7b 0a  >nEntry); i++){.
4570: 20 20 20 20 69 66 28 20 30 3d 3d 28 70 42 6c 6f      if( 0==(pBlo
4580: 63 6b 2d 3e 6d 55 73 65 64 20 26 20 28 28 42 69  ck->mUsed & ((Bi
4590: 74 6d 61 73 6b 29 31 3c 3c 69 29 29 20 29 7b 0a  tmask)1<<i)) ){.
45a0: 20 20 20 20 20 20 70 42 6c 6f 63 6b 2d 3e 6d 55        pBlock->mU
45b0: 73 65 64 20 7c 3d 20 28 28 42 69 74 6d 61 73 6b  sed |= ((Bitmask
45c0: 29 31 3c 3c 69 29 3b 0a 20 20 20 20 20 20 70 50  )1<<i);.      pP
45d0: 67 20 3d 20 28 76 6f 69 64 20 2a 29 26 70 42 6c  g = (void *)&pBl
45e0: 6f 63 6b 2d 3e 61 44 61 74 61 5b 70 4c 69 73 74  ock->aData[pList
45f0: 2d 3e 6e 42 79 74 65 20 2a 20 69 5d 3b 0a 20 20  ->nByte * i];.  
4600: 20 20 7d 0a 20 20 7d 0a 20 20 61 73 73 65 72 74    }.  }.  assert
4610: 28 20 70 50 67 20 29 3b 0a 20 20 50 41 47 45 5f  ( pPg );.  PAGE_
4620: 53 45 54 5f 42 4c 4f 43 4b 50 54 52 28 70 43 61  SET_BLOCKPTR(pCa
4630: 63 68 65 2c 20 70 50 67 2c 20 70 42 6c 6f 63 6b  che, pPg, pBlock
4640: 29 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 20  );..  /* If the 
4650: 62 6c 6f 63 6b 20 69 73 20 6e 6f 77 20 66 75 6c  block is now ful
4660: 6c 2c 20 73 68 69 66 74 20 69 74 20 74 6f 20 74  l, shift it to t
4670: 68 65 20 65 6e 64 20 6f 66 20 74 68 65 20 6c 69  he end of the li
4680: 73 74 20 2a 2f 0a 20 20 69 66 28 20 70 42 6c 6f  st */.  if( pBlo
4690: 63 6b 2d 3e 6d 55 73 65 64 3d 3d 28 28 28 42 69  ck->mUsed==(((Bi
46a0: 74 6d 61 73 6b 29 31 3c 3c 70 42 6c 6f 63 6b 2d  tmask)1<<pBlock-
46b0: 3e 6e 45 6e 74 72 79 29 2d 31 29 20 26 26 20 70  >nEntry)-1) && p
46c0: 4c 69 73 74 2d 3e 70 4c 61 73 74 21 3d 70 42 6c  List->pLast!=pBl
46d0: 6f 63 6b 20 29 7b 0a 20 20 20 20 61 73 73 65 72  ock ){.    asser
46e0: 74 28 20 70 4c 69 73 74 2d 3e 70 46 69 72 73 74  t( pList->pFirst
46f0: 3d 3d 70 42 6c 6f 63 6b 20 29 3b 0a 20 20 20 20  ==pBlock );.    
4700: 61 73 73 65 72 74 28 20 70 42 6c 6f 63 6b 2d 3e  assert( pBlock->
4710: 70 50 72 65 76 3d 3d 30 20 29 3b 0a 20 20 20 20  pPrev==0 );.    
4720: 61 73 73 65 72 74 28 20 70 4c 69 73 74 2d 3e 70  assert( pList->p
4730: 4c 61 73 74 2d 3e 70 4e 65 78 74 3d 3d 30 20 29  Last->pNext==0 )
4740: 3b 0a 20 20 20 20 70 4c 69 73 74 2d 3e 70 46 69  ;.    pList->pFi
4750: 72 73 74 20 3d 20 70 42 6c 6f 63 6b 2d 3e 70 4e  rst = pBlock->pN
4760: 65 78 74 3b 0a 20 20 20 20 70 4c 69 73 74 2d 3e  ext;.    pList->
4770: 70 46 69 72 73 74 2d 3e 70 50 72 65 76 20 3d 20  pFirst->pPrev = 
4780: 30 3b 0a 20 20 20 20 70 42 6c 6f 63 6b 2d 3e 70  0;.    pBlock->p
4790: 50 72 65 76 20 3d 20 70 4c 69 73 74 2d 3e 70 4c  Prev = pList->pL
47a0: 61 73 74 3b 0a 20 20 20 20 70 42 6c 6f 63 6b 2d  ast;.    pBlock-
47b0: 3e 70 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20 20  >pNext = 0;.    
47c0: 70 4c 69 73 74 2d 3e 70 4c 61 73 74 2d 3e 70 4e  pList->pLast->pN
47d0: 65 78 74 20 3d 20 70 42 6c 6f 63 6b 3b 0a 20 20  ext = pBlock;.  
47e0: 20 20 70 4c 69 73 74 2d 3e 70 4c 61 73 74 20 3d    pList->pLast =
47f0: 20 70 42 6c 6f 63 6b 3b 0a 20 20 7d 0a 20 20 70   pBlock;.  }.  p
4800: 20 3d 20 50 41 47 45 5f 54 4f 5f 50 47 48 44 52   = PAGE_TO_PGHDR
4810: 31 28 70 43 61 63 68 65 2c 20 70 50 67 29 3b 0a  1(pCache, pPg);.
4820: 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 62 50    if( pCache->bP
4830: 75 72 67 65 61 62 6c 65 20 29 7b 0a 20 20 20 20  urgeable ){.    
4840: 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 2d 3e  pCache->pGroup->
4850: 6e 43 75 72 72 65 6e 74 50 61 67 65 2b 2b 3b 0a  nCurrentPage++;.
4860: 20 20 7d 0a 23 65 6c 73 65 0a 20 20 2f 2a 20 54    }.#else.  /* T
4870: 68 65 20 67 72 6f 75 70 20 6d 75 74 65 78 20 6d  he group mutex m
4880: 75 73 74 20 62 65 20 72 65 6c 65 61 73 65 64 20  ust be released 
4890: 62 65 66 6f 72 65 20 70 63 61 63 68 65 31 41 6c  before pcache1Al
48a0: 6c 6f 63 28 29 20 69 73 20 63 61 6c 6c 65 64 2e  loc() is called.
48b0: 20 54 68 69 73 0a 20 20 2a 2a 20 69 73 20 62 65   This.  ** is be
48c0: 63 61 75 73 65 20 69 74 20 6d 61 79 20 63 61 6c  cause it may cal
48d0: 6c 20 73 71 6c 69 74 65 33 5f 72 65 6c 65 61 73  l sqlite3_releas
48e0: 65 5f 6d 65 6d 6f 72 79 28 29 2c 20 77 68 69 63  e_memory(), whic
48f0: 68 20 61 73 73 75 6d 65 73 20 74 68 61 74 20 0a  h assumes that .
4900: 20 20 2a 2a 20 74 68 69 73 20 6d 75 74 65 78 20    ** this mutex 
4910: 69 73 20 6e 6f 74 20 68 65 6c 64 2e 20 2a 2f 0a  is not held. */.
4920: 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65    assert( sqlite
4930: 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 43 61  3_mutex_held(pCa
4940: 63 68 65 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75 74  che->pGroup->mut
4950: 65 78 29 20 29 3b 0a 20 20 70 63 61 63 68 65 31  ex) );.  pcache1
4960: 4c 65 61 76 65 4d 75 74 65 78 28 70 43 61 63 68  LeaveMutex(pCach
4970: 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 20 20 70 50  e->pGroup);.  pP
4980: 67 20 3d 20 70 63 61 63 68 65 31 41 6c 6c 6f 63  g = pcache1Alloc
4990: 28 6e 42 79 74 65 29 3b 0a 20 20 70 63 61 63 68  (nByte);.  pcach
49a0: 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70 43 61  e1EnterMutex(pCa
49b0: 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 20 20  che->pGroup);.  
49c0: 69 66 28 20 70 50 67 20 29 7b 0a 20 20 20 20 70  if( pPg ){.    p
49d0: 20 3d 20 50 41 47 45 5f 54 4f 5f 50 47 48 44 52   = PAGE_TO_PGHDR
49e0: 31 28 70 43 61 63 68 65 2c 20 70 50 67 29 3b 0a  1(pCache, pPg);.
49f0: 20 20 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e      if( pCache->
4a00: 62 50 75 72 67 65 61 62 6c 65 20 29 7b 0a 20 20  bPurgeable ){.  
4a10: 20 20 20 20 70 43 61 63 68 65 2d 3e 70 47 72 6f      pCache->pGro
4a20: 75 70 2d 3e 6e 43 75 72 72 65 6e 74 50 61 67 65  up->nCurrentPage
4a30: 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73  ++;.    }.  }els
4a40: 65 7b 0a 20 20 20 20 70 20 3d 20 30 3b 0a 20 20  e{.    p = 0;.  
4a50: 7d 0a 23 65 6e 64 69 66 0a 20 20 72 65 74 75 72  }.#endif.  retur
4a60: 6e 20 70 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72  n p;.}../*.** Fr
4a70: 65 65 20 61 20 70 61 67 65 20 6f 62 6a 65 63 74  ee a page object
4a80: 20 61 6c 6c 6f 63 61 74 65 64 20 62 79 20 70 63   allocated by pc
4a90: 61 63 68 65 31 41 6c 6c 6f 63 50 61 67 65 28 29  ache1AllocPage()
4aa0: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 70 6f 69 6e  ..**.** The poin
4ab0: 74 65 72 20 69 73 20 61 6c 6c 6f 77 65 64 20 74  ter is allowed t
4ac0: 6f 20 62 65 20 4e 55 4c 4c 2c 20 77 68 69 63 68  o be NULL, which
4ad0: 20 69 73 20 70 72 75 64 65 6e 74 2e 20 20 42 75   is prudent.  Bu
4ae0: 74 20 69 74 20 74 75 72 6e 73 20 6f 75 74 0a 2a  t it turns out.*
4af0: 2a 20 74 68 61 74 20 74 68 65 20 63 75 72 72 65  * that the curre
4b00: 6e 74 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  nt implementatio
4b10: 6e 20 68 61 70 70 65 6e 73 20 74 6f 20 6e 65 76  n happens to nev
4b20: 65 72 20 63 61 6c 6c 20 74 68 69 73 20 72 6f 75  er call this rou
4b30: 74 69 6e 65 0a 2a 2a 20 77 69 74 68 20 61 20 4e  tine.** with a N
4b40: 55 4c 4c 20 70 6f 69 6e 74 65 72 2c 20 73 6f 20  ULL pointer, so 
4b50: 77 65 20 6d 61 72 6b 20 74 68 65 20 4e 55 4c 4c  we mark the NULL
4b60: 20 74 65 73 74 20 77 69 74 68 20 41 4c 57 41 59   test with ALWAY
4b70: 53 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  S()..*/.static v
4b80: 6f 69 64 20 70 63 61 63 68 65 31 46 72 65 65 50  oid pcache1FreeP
4b90: 61 67 65 28 50 67 48 64 72 31 20 2a 70 29 7b 0a  age(PgHdr1 *p){.
4ba0: 20 20 69 66 28 20 41 4c 57 41 59 53 28 70 29 20    if( ALWAYS(p) 
4bb0: 29 7b 0a 20 20 20 20 50 43 61 63 68 65 31 20 2a  ){.    PCache1 *
4bc0: 70 43 61 63 68 65 20 3d 20 70 2d 3e 70 43 61 63  pCache = p->pCac
4bd0: 68 65 3b 0a 20 20 20 20 76 6f 69 64 20 2a 70 50  he;.    void *pP
4be0: 67 20 3d 20 50 47 48 44 52 31 5f 54 4f 5f 50 41  g = PGHDR1_TO_PA
4bf0: 47 45 28 70 29 3b 0a 0a 23 69 66 64 65 66 20 53  GE(p);..#ifdef S
4c00: 51 4c 49 54 45 5f 50 41 47 45 43 41 43 48 45 5f  QLITE_PAGECACHE_
4c10: 42 4c 4f 43 4b 41 4c 4c 4f 43 0a 20 20 20 20 50  BLOCKALLOC.    P
4c20: 47 72 6f 75 70 42 6c 6f 63 6b 20 2a 70 42 6c 6f  GroupBlock *pBlo
4c30: 63 6b 20 3d 20 50 41 47 45 5f 47 45 54 5f 42 4c  ck = PAGE_GET_BL
4c40: 4f 43 4b 50 54 52 28 70 43 61 63 68 65 2c 20 70  OCKPTR(pCache, p
4c50: 50 67 29 3b 0a 20 20 20 20 50 47 72 6f 75 70 42  Pg);.    PGroupB
4c60: 6c 6f 63 6b 4c 69 73 74 20 2a 70 4c 69 73 74 20  lockList *pList 
4c70: 3d 20 70 42 6c 6f 63 6b 2d 3e 70 4c 69 73 74 3b  = pBlock->pList;
4c80: 0a 20 20 20 20 69 6e 74 20 69 20 3d 20 28 28 75  .    int i = ((u
4c90: 38 20 2a 29 70 50 67 20 2d 20 70 42 6c 6f 63 6b  8 *)pPg - pBlock
4ca0: 2d 3e 61 44 61 74 61 29 20 2f 20 70 4c 69 73 74  ->aData) / pList
4cb0: 2d 3e 6e 42 79 74 65 3b 0a 0a 20 20 20 20 61 73  ->nByte;..    as
4cc0: 73 65 72 74 28 20 70 50 67 3d 3d 28 76 6f 69 64  sert( pPg==(void
4cd0: 20 2a 29 26 70 42 6c 6f 63 6b 2d 3e 61 44 61 74   *)&pBlock->aDat
4ce0: 61 5b 69 2a 70 4c 69 73 74 2d 3e 6e 42 79 74 65  a[i*pList->nByte
4cf0: 5d 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28  ] );.    assert(
4d00: 20 70 42 6c 6f 63 6b 2d 3e 6d 55 73 65 64 20 26   pBlock->mUsed &
4d10: 20 28 28 42 69 74 6d 61 73 6b 29 31 3c 3c 69 29   ((Bitmask)1<<i)
4d20: 20 29 3b 0a 20 20 20 20 70 42 6c 6f 63 6b 2d 3e   );.    pBlock->
4d30: 6d 55 73 65 64 20 26 3d 20 7e 28 28 42 69 74 6d  mUsed &= ~((Bitm
4d40: 61 73 6b 29 31 3c 3c 69 29 3b 0a 0a 20 20 20 20  ask)1<<i);..    
4d50: 2f 2a 20 52 65 6d 6f 76 65 20 74 68 65 20 62 6c  /* Remove the bl
4d60: 6f 63 6b 20 66 72 6f 6d 20 74 68 65 20 6c 69 73  ock from the lis
4d70: 74 2e 20 49 66 20 69 74 20 69 73 20 63 6f 6d 70  t. If it is comp
4d80: 6c 65 74 65 6c 79 20 65 6d 70 74 79 2c 20 66 72  letely empty, fr
4d90: 65 65 20 69 74 2e 0a 20 20 20 20 2a 2a 20 4f 72  ee it..    ** Or
4da0: 20 69 66 20 69 74 20 69 73 20 6e 6f 74 20 63 6f   if it is not co
4db0: 6d 70 6c 65 74 65 6c 79 20 65 6d 70 74 79 2c 20  mpletely empty, 
4dc0: 72 65 2d 69 6e 73 65 72 74 20 69 74 20 61 74 20  re-insert it at 
4dd0: 74 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 65  the start of the
4de0: 0a 20 20 20 20 2a 2a 20 6c 69 73 74 2e 20 2a 2f  .    ** list. */
4df0: 0a 20 20 20 20 69 66 28 20 70 4c 69 73 74 2d 3e  .    if( pList->
4e00: 70 46 69 72 73 74 3d 3d 70 42 6c 6f 63 6b 20 29  pFirst==pBlock )
4e10: 7b 0a 20 20 20 20 20 20 70 4c 69 73 74 2d 3e 70  {.      pList->p
4e20: 46 69 72 73 74 20 3d 20 70 42 6c 6f 63 6b 2d 3e  First = pBlock->
4e30: 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 69 66 28  pNext;.      if(
4e40: 20 70 4c 69 73 74 2d 3e 70 46 69 72 73 74 20 29   pList->pFirst )
4e50: 20 70 4c 69 73 74 2d 3e 70 46 69 72 73 74 2d 3e   pList->pFirst->
4e60: 70 50 72 65 76 20 3d 20 30 3b 0a 20 20 20 20 7d  pPrev = 0;.    }
4e70: 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 42 6c 6f  else{.      pBlo
4e80: 63 6b 2d 3e 70 50 72 65 76 2d 3e 70 4e 65 78 74  ck->pPrev->pNext
4e90: 20 3d 20 70 42 6c 6f 63 6b 2d 3e 70 4e 65 78 74   = pBlock->pNext
4ea0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20  ;.    }.    if( 
4eb0: 70 4c 69 73 74 2d 3e 70 4c 61 73 74 3d 3d 70 42  pList->pLast==pB
4ec0: 6c 6f 63 6b 20 29 7b 0a 20 20 20 20 20 20 70 4c  lock ){.      pL
4ed0: 69 73 74 2d 3e 70 4c 61 73 74 20 3d 20 70 42 6c  ist->pLast = pBl
4ee0: 6f 63 6b 2d 3e 70 50 72 65 76 3b 0a 20 20 20 20  ock->pPrev;.    
4ef0: 20 20 69 66 28 20 70 4c 69 73 74 2d 3e 70 4c 61    if( pList->pLa
4f00: 73 74 20 29 20 70 4c 69 73 74 2d 3e 70 4c 61 73  st ) pList->pLas
4f10: 74 2d 3e 70 4e 65 78 74 20 3d 20 30 3b 0a 20 20  t->pNext = 0;.  
4f20: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70    }else{.      p
4f30: 42 6c 6f 63 6b 2d 3e 70 4e 65 78 74 2d 3e 70 50  Block->pNext->pP
4f40: 72 65 76 20 3d 20 70 42 6c 6f 63 6b 2d 3e 70 50  rev = pBlock->pP
4f50: 72 65 76 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  rev;.    }..    
4f60: 69 66 28 20 70 42 6c 6f 63 6b 2d 3e 6d 55 73 65  if( pBlock->mUse
4f70: 64 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 50 47  d==0 ){.      PG
4f80: 72 6f 75 70 20 2a 70 47 72 6f 75 70 20 3d 20 70  roup *pGroup = p
4f90: 2d 3e 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70  ->pCache->pGroup
4fa0: 3b 0a 0a 20 20 20 20 20 20 69 6e 74 20 73 7a 20  ;..      int sz 
4fb0: 3d 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 53  = sqlite3MallocS
4fc0: 69 7a 65 28 70 42 6c 6f 63 6b 29 3b 0a 20 20 20  ize(pBlock);.   
4fd0: 20 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78     sqlite3_mutex
4fe0: 5f 65 6e 74 65 72 28 70 63 61 63 68 65 31 2e 6d  _enter(pcache1.m
4ff0: 75 74 65 78 29 3b 0a 20 20 20 20 20 20 73 71 6c  utex);.      sql
5000: 69 74 65 33 53 74 61 74 75 73 41 64 64 28 53 51  ite3StatusAdd(SQ
5010: 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41 47 45  LITE_STATUS_PAGE
5020: 43 41 43 48 45 5f 4f 56 45 52 46 4c 4f 57 2c 20  CACHE_OVERFLOW, 
5030: 2d 73 7a 29 3b 0a 20 20 20 20 20 20 73 71 6c 69  -sz);.      sqli
5040: 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28  te3_mutex_leave(
5050: 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a  pcache1.mutex);.
5060: 20 20 20 20 20 20 66 72 65 65 4c 69 73 74 49 66        freeListIf
5070: 45 6d 70 74 79 28 70 47 72 6f 75 70 2c 20 70 4c  Empty(pGroup, pL
5080: 69 73 74 29 3b 0a 20 20 20 20 20 20 73 71 6c 69  ist);.      sqli
5090: 74 65 33 5f 66 72 65 65 28 70 42 6c 6f 63 6b 29  te3_free(pBlock)
50a0: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
50b0: 20 20 20 61 64 64 42 6c 6f 63 6b 54 6f 4c 69 73     addBlockToLis
50c0: 74 28 70 4c 69 73 74 2c 20 70 42 6c 6f 63 6b 29  t(pList, pBlock)
50d0: 3b 0a 20 20 20 20 7d 0a 23 65 6c 73 65 0a 20 20  ;.    }.#else.  
50e0: 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65    assert( sqlite
50f0: 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 2d 3e  3_mutex_held(p->
5100: 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 2d 3e  pCache->pGroup->
5110: 6d 75 74 65 78 29 20 29 3b 0a 20 20 20 20 70 63  mutex) );.    pc
5120: 61 63 68 65 31 46 72 65 65 28 70 50 67 29 3b 0a  ache1Free(pPg);.
5130: 23 65 6e 64 69 66 0a 20 20 20 20 69 66 28 20 70  #endif.    if( p
5140: 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c  Cache->bPurgeabl
5150: 65 20 29 7b 0a 20 20 20 20 20 20 70 43 61 63 68  e ){.      pCach
5160: 65 2d 3e 70 47 72 6f 75 70 2d 3e 6e 43 75 72 72  e->pGroup->nCurr
5170: 65 6e 74 50 61 67 65 2d 2d 3b 0a 20 20 20 20 7d  entPage--;.    }
5180: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61  .  }.}../*.** Ma
5190: 6c 6c 6f 63 20 66 75 6e 63 74 69 6f 6e 20 75 73  lloc function us
51a0: 65 64 20 62 79 20 53 51 4c 69 74 65 20 74 6f 20  ed by SQLite to 
51b0: 6f 62 74 61 69 6e 20 73 70 61 63 65 20 66 72 6f  obtain space fro
51c0: 6d 20 74 68 65 20 62 75 66 66 65 72 20 63 6f 6e  m the buffer con
51d0: 66 69 67 75 72 65 64 0a 2a 2a 20 75 73 69 6e 67  figured.** using
51e0: 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67 28   sqlite3_config(
51f0: 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41  SQLITE_CONFIG_PA
5200: 47 45 43 41 43 48 45 29 20 6f 70 74 69 6f 6e 2e  GECACHE) option.
5210: 20 49 66 20 6e 6f 20 73 75 63 68 20 62 75 66 66   If no such buff
5220: 65 72 0a 2a 2a 20 65 78 69 73 74 73 2c 20 74 68  er.** exists, th
5230: 69 73 20 66 75 6e 63 74 69 6f 6e 20 66 61 6c 6c  is function fall
5240: 73 20 62 61 63 6b 20 74 6f 20 73 71 6c 69 74 65  s back to sqlite
5250: 33 4d 61 6c 6c 6f 63 28 29 2e 0a 2a 2f 0a 76 6f  3Malloc()..*/.vo
5260: 69 64 20 2a 73 71 6c 69 74 65 33 50 61 67 65 4d  id *sqlite3PageM
5270: 61 6c 6c 6f 63 28 69 6e 74 20 73 7a 29 7b 0a 20  alloc(int sz){. 
5280: 20 72 65 74 75 72 6e 20 70 63 61 63 68 65 31 41   return pcache1A
5290: 6c 6c 6f 63 28 73 7a 29 3b 0a 7d 0a 0a 2f 2a 0a  lloc(sz);.}../*.
52a0: 2a 2a 20 46 72 65 65 20 61 6e 20 61 6c 6c 6f 63  ** Free an alloc
52b0: 61 74 65 64 20 62 75 66 66 65 72 20 6f 62 74 61  ated buffer obta
52c0: 69 6e 65 64 20 66 72 6f 6d 20 73 71 6c 69 74 65  ined from sqlite
52d0: 33 50 61 67 65 4d 61 6c 6c 6f 63 28 29 2e 0a 2a  3PageMalloc()..*
52e0: 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 61  /.void sqlite3Pa
52f0: 67 65 46 72 65 65 28 76 6f 69 64 20 2a 70 29 7b  geFree(void *p){
5300: 0a 20 20 70 63 61 63 68 65 31 46 72 65 65 28 70  .  pcache1Free(p
5310: 29 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 52 65 74  );.}.../*.** Ret
5320: 75 72 6e 20 74 72 75 65 20 69 66 20 69 74 20 64  urn true if it d
5330: 65 73 69 72 61 62 6c 65 20 74 6f 20 61 76 6f 69  esirable to avoi
5340: 64 20 61 6c 6c 6f 63 61 74 69 6e 67 20 61 20 6e  d allocating a n
5350: 65 77 20 70 61 67 65 20 63 61 63 68 65 0a 2a 2a  ew page cache.**
5360: 20 65 6e 74 72 79 2e 0a 2a 2a 0a 2a 2a 20 49 66   entry..**.** If
5370: 20 6d 65 6d 6f 72 79 20 77 61 73 20 61 6c 6c 6f   memory was allo
5380: 63 61 74 65 64 20 73 70 65 63 69 66 69 63 61 6c  cated specifical
5390: 6c 79 20 74 6f 20 74 68 65 20 70 61 67 65 20 63  ly to the page c
53a0: 61 63 68 65 20 75 73 69 6e 67 0a 2a 2a 20 53 51  ache using.** SQ
53b0: 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47 45  LITE_CONFIG_PAGE
53c0: 43 41 43 48 45 20 62 75 74 20 74 68 61 74 20 6d  CACHE but that m
53d0: 65 6d 6f 72 79 20 68 61 73 20 61 6c 6c 20 62 65  emory has all be
53e0: 65 6e 20 75 73 65 64 2c 20 74 68 65 6e 0a 2a 2a  en used, then.**
53f0: 20 69 74 20 69 73 20 64 65 73 69 72 61 62 6c 65   it is desirable
5400: 20 74 6f 20 61 76 6f 69 64 20 61 6c 6c 6f 63 61   to avoid alloca
5410: 74 69 6e 67 20 61 20 6e 65 77 20 70 61 67 65 20  ting a new page 
5420: 63 61 63 68 65 20 65 6e 74 72 79 20 62 65 63 61  cache entry beca
5430: 75 73 65 0a 2a 2a 20 70 72 65 73 75 6d 61 62 6c  use.** presumabl
5440: 79 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f  y SQLITE_CONFIG_
5450: 50 41 47 45 43 41 43 48 45 20 77 61 73 20 73 75  PAGECACHE was su
5460: 70 70 6f 73 65 20 74 6f 20 62 65 20 73 75 66 66  ppose to be suff
5470: 69 63 69 65 6e 74 0a 2a 2a 20 66 6f 72 20 61 6c  icient.** for al
5480: 6c 20 70 61 67 65 20 63 61 63 68 65 20 6e 65 65  l page cache nee
5490: 64 73 20 61 6e 64 20 77 65 20 73 68 6f 75 6c 64  ds and we should
54a0: 20 6e 6f 74 20 6e 65 65 64 20 74 6f 20 73 70 69   not need to spi
54b0: 6c 6c 20 74 68 65 0a 2a 2a 20 61 6c 6c 6f 63 61  ll the.** alloca
54c0: 74 69 6f 6e 20 6f 6e 74 6f 20 74 68 65 20 68 65  tion onto the he
54d0: 61 70 2e 0a 2a 2a 0a 2a 2a 20 4f 72 2c 20 74 68  ap..**.** Or, th
54e0: 65 20 68 65 61 70 20 69 73 20 75 73 65 64 20 66  e heap is used f
54f0: 6f 72 20 61 6c 6c 20 70 61 67 65 20 63 61 63 68  or all page cach
5500: 65 20 6d 65 6d 6f 72 79 20 70 75 74 20 74 68 65  e memory put the
5510: 20 68 65 61 70 20 69 73 0a 2a 2a 20 75 6e 64 65   heap is.** unde
5520: 72 20 6d 65 6d 6f 72 79 20 70 72 65 73 73 75 72  r memory pressur
5530: 65 2c 20 74 68 65 6e 20 61 67 61 69 6e 20 69 74  e, then again it
5540: 20 69 73 20 64 65 73 69 72 61 62 6c 65 20 74 6f   is desirable to
5550: 20 61 76 6f 69 64 0a 2a 2a 20 61 6c 6c 6f 63 61   avoid.** alloca
5560: 74 69 6e 67 20 61 20 6e 65 77 20 70 61 67 65 20  ting a new page 
5570: 63 61 63 68 65 20 65 6e 74 72 79 20 69 6e 20 6f  cache entry in o
5580: 72 64 65 72 20 74 6f 20 61 76 6f 69 64 20 73 74  rder to avoid st
5590: 72 65 73 73 69 6e 67 0a 2a 2a 20 74 68 65 20 68  ressing.** the h
55a0: 65 61 70 20 65 76 65 6e 20 66 75 72 74 68 65 72  eap even further
55b0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
55c0: 70 63 61 63 68 65 31 55 6e 64 65 72 4d 65 6d 6f  pcache1UnderMemo
55d0: 72 79 50 72 65 73 73 75 72 65 28 50 43 61 63 68  ryPressure(PCach
55e0: 65 31 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 69  e1 *pCache){.  i
55f0: 66 28 20 70 63 61 63 68 65 31 2e 6e 53 6c 6f 74  f( pcache1.nSlot
5600: 20 26 26 20 70 43 61 63 68 65 2d 3e 73 7a 50 61   && pCache->szPa
5610: 67 65 3c 3d 70 63 61 63 68 65 31 2e 73 7a 53 6c  ge<=pcache1.szSl
5620: 6f 74 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  ot ){.    return
5630: 20 70 63 61 63 68 65 31 2e 62 55 6e 64 65 72 50   pcache1.bUnderP
5640: 72 65 73 73 75 72 65 3b 0a 20 20 7d 65 6c 73 65  ressure;.  }else
5650: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 73 71 6c  {.    return sql
5660: 69 74 65 33 48 65 61 70 4e 65 61 72 6c 79 46 75  ite3HeapNearlyFu
5670: 6c 6c 28 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 2a  ll();.  }.}../**
5680: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5690: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
56a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
56b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
56c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a  ************/./*
56d0: 2a 2a 2a 2a 2a 2a 2a 20 47 65 6e 65 72 61 6c 20  ******* General 
56e0: 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 46  Implementation F
56f0: 75 6e 63 74 69 6f 6e 73 20 2a 2a 2a 2a 2a 2a 2a  unctions *******
5700: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5710: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a  *************/..
5720: 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  /*.** This funct
5730: 69 6f 6e 20 69 73 20 75 73 65 64 20 74 6f 20 72  ion is used to r
5740: 65 73 69 7a 65 20 74 68 65 20 68 61 73 68 20 74  esize the hash t
5750: 61 62 6c 65 20 75 73 65 64 20 62 79 20 74 68 65  able used by the
5760: 20 63 61 63 68 65 20 70 61 73 73 65 64 0a 2a 2a   cache passed.**
5770: 20 61 73 20 74 68 65 20 66 69 72 73 74 20 61 72   as the first ar
5780: 67 75 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 54 68  gument..**.** Th
5790: 65 20 50 43 61 63 68 65 20 6d 75 74 65 78 20 6d  e PCache mutex m
57a0: 75 73 74 20 62 65 20 68 65 6c 64 20 77 68 65 6e  ust be held when
57b0: 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   this function i
57c0: 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f 0a 73 74 61  s called..*/.sta
57d0: 74 69 63 20 69 6e 74 20 70 63 61 63 68 65 31 52  tic int pcache1R
57e0: 65 73 69 7a 65 48 61 73 68 28 50 43 61 63 68 65  esizeHash(PCache
57f0: 31 20 2a 70 29 7b 0a 20 20 50 67 48 64 72 31 20  1 *p){.  PgHdr1 
5800: 2a 2a 61 70 4e 65 77 3b 0a 20 20 75 6e 73 69 67  **apNew;.  unsig
5810: 6e 65 64 20 69 6e 74 20 6e 4e 65 77 3b 0a 20 20  ned int nNew;.  
5820: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 3b 0a  unsigned int i;.
5830: 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74  .  assert( sqlit
5840: 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 2d  e3_mutex_held(p-
5850: 3e 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78 29 20  >pGroup->mutex) 
5860: 29 3b 0a 0a 20 20 6e 4e 65 77 20 3d 20 70 2d 3e  );..  nNew = p->
5870: 6e 48 61 73 68 2a 32 3b 0a 20 20 69 66 28 20 6e  nHash*2;.  if( n
5880: 4e 65 77 3c 32 35 36 20 29 7b 0a 20 20 20 20 6e  New<256 ){.    n
5890: 4e 65 77 20 3d 20 32 35 36 3b 0a 20 20 7d 0a 0a  New = 256;.  }..
58a0: 20 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75    pcache1LeaveMu
58b0: 74 65 78 28 70 2d 3e 70 47 72 6f 75 70 29 3b 0a  tex(p->pGroup);.
58c0: 20 20 69 66 28 20 70 2d 3e 6e 48 61 73 68 20 29    if( p->nHash )
58d0: 7b 20 73 71 6c 69 74 65 33 42 65 67 69 6e 42 65  { sqlite3BeginBe
58e0: 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 20 7d 0a  nignMalloc(); }.
58f0: 20 20 61 70 4e 65 77 20 3d 20 28 50 67 48 64 72    apNew = (PgHdr
5900: 31 20 2a 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c  1 **)sqlite3_mal
5910: 6c 6f 63 28 73 69 7a 65 6f 66 28 50 67 48 64 72  loc(sizeof(PgHdr
5920: 31 20 2a 29 2a 6e 4e 65 77 29 3b 0a 20 20 69 66  1 *)*nNew);.  if
5930: 28 20 70 2d 3e 6e 48 61 73 68 20 29 7b 20 73 71  ( p->nHash ){ sq
5940: 6c 69 74 65 33 45 6e 64 42 65 6e 69 67 6e 4d 61  lite3EndBenignMa
5950: 6c 6c 6f 63 28 29 3b 20 7d 0a 20 20 70 63 61 63  lloc(); }.  pcac
5960: 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70 2d  he1EnterMutex(p-
5970: 3e 70 47 72 6f 75 70 29 3b 0a 20 20 69 66 28 20  >pGroup);.  if( 
5980: 61 70 4e 65 77 20 29 7b 0a 20 20 20 20 6d 65 6d  apNew ){.    mem
5990: 73 65 74 28 61 70 4e 65 77 2c 20 30 2c 20 73 69  set(apNew, 0, si
59a0: 7a 65 6f 66 28 50 67 48 64 72 31 20 2a 29 2a 6e  zeof(PgHdr1 *)*n
59b0: 4e 65 77 29 3b 0a 20 20 20 20 66 6f 72 28 69 3d  New);.    for(i=
59c0: 30 3b 20 69 3c 70 2d 3e 6e 48 61 73 68 3b 20 69  0; i<p->nHash; i
59d0: 2b 2b 29 7b 0a 20 20 20 20 20 20 50 67 48 64 72  ++){.      PgHdr
59e0: 31 20 2a 70 50 61 67 65 3b 0a 20 20 20 20 20 20  1 *pPage;.      
59f0: 50 67 48 64 72 31 20 2a 70 4e 65 78 74 20 3d 20  PgHdr1 *pNext = 
5a00: 70 2d 3e 61 70 48 61 73 68 5b 69 5d 3b 0a 20 20  p->apHash[i];.  
5a10: 20 20 20 20 77 68 69 6c 65 28 20 28 70 50 61 67      while( (pPag
5a20: 65 20 3d 20 70 4e 65 78 74 29 21 3d 30 20 29 7b  e = pNext)!=0 ){
5a30: 0a 20 20 20 20 20 20 20 20 75 6e 73 69 67 6e 65  .        unsigne
5a40: 64 20 69 6e 74 20 68 20 3d 20 70 50 61 67 65 2d  d int h = pPage-
5a50: 3e 69 4b 65 79 20 25 20 6e 4e 65 77 3b 0a 20 20  >iKey % nNew;.  
5a60: 20 20 20 20 20 20 70 4e 65 78 74 20 3d 20 70 50        pNext = pP
5a70: 61 67 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20  age->pNext;.    
5a80: 20 20 20 20 70 50 61 67 65 2d 3e 70 4e 65 78 74      pPage->pNext
5a90: 20 3d 20 61 70 4e 65 77 5b 68 5d 3b 0a 20 20 20   = apNew[h];.   
5aa0: 20 20 20 20 20 61 70 4e 65 77 5b 68 5d 20 3d 20       apNew[h] = 
5ab0: 70 50 61 67 65 3b 0a 20 20 20 20 20 20 7d 0a 20  pPage;.      }. 
5ac0: 20 20 20 7d 0a 20 20 20 20 73 71 6c 69 74 65 33     }.    sqlite3
5ad0: 5f 66 72 65 65 28 70 2d 3e 61 70 48 61 73 68 29  _free(p->apHash)
5ae0: 3b 0a 20 20 20 20 70 2d 3e 61 70 48 61 73 68 20  ;.    p->apHash 
5af0: 3d 20 61 70 4e 65 77 3b 0a 20 20 20 20 70 2d 3e  = apNew;.    p->
5b00: 6e 48 61 73 68 20 3d 20 6e 4e 65 77 3b 0a 20 20  nHash = nNew;.  
5b10: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 28 70 2d 3e  }..  return (p->
5b20: 61 70 48 61 73 68 20 3f 20 53 51 4c 49 54 45 5f  apHash ? SQLITE_
5b30: 4f 4b 20 3a 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  OK : SQLITE_NOME
5b40: 4d 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69  M);.}../*.** Thi
5b50: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 75 73  s function is us
5b60: 65 64 20 69 6e 74 65 72 6e 61 6c 6c 79 20 74 6f  ed internally to
5b70: 20 72 65 6d 6f 76 65 20 74 68 65 20 70 61 67 65   remove the page
5b80: 20 70 50 61 67 65 20 66 72 6f 6d 20 74 68 65 20   pPage from the 
5b90: 0a 2a 2a 20 50 47 72 6f 75 70 20 4c 52 55 20 6c  .** PGroup LRU l
5ba0: 69 73 74 2c 20 69 66 20 69 73 20 70 61 72 74 20  ist, if is part 
5bb0: 6f 66 20 69 74 2e 20 49 66 20 70 50 61 67 65 20  of it. If pPage 
5bc0: 69 73 20 6e 6f 74 20 70 61 72 74 20 6f 66 20 74  is not part of t
5bd0: 68 65 20 50 47 72 6f 75 70 0a 2a 2a 20 4c 52 55  he PGroup.** LRU
5be0: 20 6c 69 73 74 2c 20 74 68 65 6e 20 74 68 69 73   list, then this
5bf0: 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 61 20 6e   function is a n
5c00: 6f 2d 6f 70 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  o-op..**.** The 
5c10: 50 47 72 6f 75 70 20 6d 75 74 65 78 20 6d 75 73  PGroup mutex mus
5c20: 74 20 62 65 20 68 65 6c 64 20 77 68 65 6e 20 74  t be held when t
5c30: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
5c40: 63 61 6c 6c 65 64 2e 0a 2a 2a 0a 2a 2a 20 49 66  called..**.** If
5c50: 20 70 50 61 67 65 20 69 73 20 4e 55 4c 4c 20 74   pPage is NULL t
5c60: 68 65 6e 20 74 68 69 73 20 72 6f 75 74 69 6e 65  hen this routine
5c70: 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a 2a 2f 0a   is a no-op..*/.
5c80: 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63  static void pcac
5c90: 68 65 31 50 69 6e 50 61 67 65 28 50 67 48 64 72  he1PinPage(PgHdr
5ca0: 31 20 2a 70 50 61 67 65 29 7b 0a 20 20 50 43 61  1 *pPage){.  PCa
5cb0: 63 68 65 31 20 2a 70 43 61 63 68 65 3b 0a 20 20  che1 *pCache;.  
5cc0: 50 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 3b 0a  PGroup *pGroup;.
5cd0: 0a 20 20 69 66 28 20 70 50 61 67 65 3d 3d 30 20  .  if( pPage==0 
5ce0: 29 20 72 65 74 75 72 6e 3b 0a 20 20 70 43 61 63  ) return;.  pCac
5cf0: 68 65 20 3d 20 70 50 61 67 65 2d 3e 70 43 61 63  he = pPage->pCac
5d00: 68 65 3b 0a 20 20 70 47 72 6f 75 70 20 3d 20 70  he;.  pGroup = p
5d10: 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b 0a 20  Cache->pGroup;. 
5d20: 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33   assert( sqlite3
5d30: 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 47 72 6f  _mutex_held(pGro
5d40: 75 70 2d 3e 6d 75 74 65 78 29 20 29 3b 0a 20 20  up->mutex) );.  
5d50: 69 66 28 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e  if( pPage->pLruN
5d60: 65 78 74 20 7c 7c 20 70 50 61 67 65 3d 3d 70 47  ext || pPage==pG
5d70: 72 6f 75 70 2d 3e 70 4c 72 75 54 61 69 6c 20 29  roup->pLruTail )
5d80: 7b 0a 20 20 20 20 69 66 28 20 70 50 61 67 65 2d  {.    if( pPage-
5d90: 3e 70 4c 72 75 50 72 65 76 20 29 7b 0a 20 20 20  >pLruPrev ){.   
5da0: 20 20 20 70 50 61 67 65 2d 3e 70 4c 72 75 50 72     pPage->pLruPr
5db0: 65 76 2d 3e 70 4c 72 75 4e 65 78 74 20 3d 20 70  ev->pLruNext = p
5dc0: 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 3b 0a  Page->pLruNext;.
5dd0: 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70 50      }.    if( pP
5de0: 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 20 29 7b  age->pLruNext ){
5df0: 0a 20 20 20 20 20 20 70 50 61 67 65 2d 3e 70 4c  .      pPage->pL
5e00: 72 75 4e 65 78 74 2d 3e 70 4c 72 75 50 72 65 76  ruNext->pLruPrev
5e10: 20 3d 20 70 50 61 67 65 2d 3e 70 4c 72 75 50 72   = pPage->pLruPr
5e20: 65 76 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66  ev;.    }.    if
5e30: 28 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 48 65  ( pGroup->pLruHe
5e40: 61 64 3d 3d 70 50 61 67 65 20 29 7b 0a 20 20 20  ad==pPage ){.   
5e50: 20 20 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 48     pGroup->pLruH
5e60: 65 61 64 20 3d 20 70 50 61 67 65 2d 3e 70 4c 72  ead = pPage->pLr
5e70: 75 4e 65 78 74 3b 0a 20 20 20 20 7d 0a 20 20 20  uNext;.    }.   
5e80: 20 69 66 28 20 70 47 72 6f 75 70 2d 3e 70 4c 72   if( pGroup->pLr
5e90: 75 54 61 69 6c 3d 3d 70 50 61 67 65 20 29 7b 0a  uTail==pPage ){.
5ea0: 20 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 70 4c        pGroup->pL
5eb0: 72 75 54 61 69 6c 20 3d 20 70 50 61 67 65 2d 3e  ruTail = pPage->
5ec0: 70 4c 72 75 50 72 65 76 3b 0a 20 20 20 20 7d 0a  pLruPrev;.    }.
5ed0: 20 20 20 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e      pPage->pLruN
5ee0: 65 78 74 20 3d 20 30 3b 0a 20 20 20 20 70 50 61  ext = 0;.    pPa
5ef0: 67 65 2d 3e 70 4c 72 75 50 72 65 76 20 3d 20 30  ge->pLruPrev = 0
5f00: 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 43 61  ;.    pPage->pCa
5f10: 63 68 65 2d 3e 6e 52 65 63 79 63 6c 61 62 6c 65  che->nRecyclable
5f20: 2d 2d 3b 0a 20 20 7d 0a 7d 0a 0a 0a 2f 2a 0a 2a  --;.  }.}.../*.*
5f30: 2a 20 52 65 6d 6f 76 65 20 74 68 65 20 70 61 67  * Remove the pag
5f40: 65 20 73 75 70 70 6c 69 65 64 20 61 73 20 61 6e  e supplied as an
5f50: 20 61 72 67 75 6d 65 6e 74 20 66 72 6f 6d 20 74   argument from t
5f60: 68 65 20 68 61 73 68 20 74 61 62 6c 65 20 0a 2a  he hash table .*
5f70: 2a 20 28 50 43 61 63 68 65 31 2e 61 70 48 61 73  * (PCache1.apHas
5f80: 68 20 73 74 72 75 63 74 75 72 65 29 20 74 68 61  h structure) tha
5f90: 74 20 69 74 20 69 73 20 63 75 72 72 65 6e 74 6c  t it is currentl
5fa0: 79 20 73 74 6f 72 65 64 20 69 6e 2e 0a 2a 2a 0a  y stored in..**.
5fb0: 2a 2a 20 54 68 65 20 50 47 72 6f 75 70 20 6d 75  ** The PGroup mu
5fc0: 74 65 78 20 6d 75 73 74 20 62 65 20 68 65 6c 64  tex must be held
5fd0: 20 77 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74   when this funct
5fe0: 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 2e 0a 2a  ion is called..*
5ff0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63  /.static void pc
6000: 61 63 68 65 31 52 65 6d 6f 76 65 46 72 6f 6d 48  ache1RemoveFromH
6010: 61 73 68 28 50 67 48 64 72 31 20 2a 70 50 61 67  ash(PgHdr1 *pPag
6020: 65 29 7b 0a 20 20 75 6e 73 69 67 6e 65 64 20 69  e){.  unsigned i
6030: 6e 74 20 68 3b 0a 20 20 50 43 61 63 68 65 31 20  nt h;.  PCache1 
6040: 2a 70 43 61 63 68 65 20 3d 20 70 50 61 67 65 2d  *pCache = pPage-
6050: 3e 70 43 61 63 68 65 3b 0a 20 20 50 67 48 64 72  >pCache;.  PgHdr
6060: 31 20 2a 2a 70 70 3b 0a 0a 20 20 61 73 73 65 72  1 **pp;..  asser
6070: 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78  t( sqlite3_mutex
6080: 5f 68 65 6c 64 28 70 43 61 63 68 65 2d 3e 70 47  _held(pCache->pG
6090: 72 6f 75 70 2d 3e 6d 75 74 65 78 29 20 29 3b 0a  roup->mutex) );.
60a0: 20 20 68 20 3d 20 70 50 61 67 65 2d 3e 69 4b 65    h = pPage->iKe
60b0: 79 20 25 20 70 43 61 63 68 65 2d 3e 6e 48 61 73  y % pCache->nHas
60c0: 68 3b 0a 20 20 66 6f 72 28 70 70 3d 26 70 43 61  h;.  for(pp=&pCa
60d0: 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 20  che->apHash[h]; 
60e0: 28 2a 70 70 29 21 3d 70 50 61 67 65 3b 20 70 70  (*pp)!=pPage; pp
60f0: 3d 26 28 2a 70 70 29 2d 3e 70 4e 65 78 74 29 3b  =&(*pp)->pNext);
6100: 0a 20 20 2a 70 70 20 3d 20 28 2a 70 70 29 2d 3e  .  *pp = (*pp)->
6110: 70 4e 65 78 74 3b 0a 0a 20 20 70 43 61 63 68 65  pNext;..  pCache
6120: 2d 3e 6e 50 61 67 65 2d 2d 3b 0a 7d 0a 0a 2f 2a  ->nPage--;.}../*
6130: 0a 2a 2a 20 49 66 20 74 68 65 72 65 20 61 72 65  .** If there are
6140: 20 63 75 72 72 65 6e 74 6c 79 20 6d 6f 72 65 20   currently more 
6150: 74 68 61 6e 20 6e 4d 61 78 50 61 67 65 20 70 61  than nMaxPage pa
6160: 67 65 73 20 61 6c 6c 6f 63 61 74 65 64 2c 20 74  ges allocated, t
6170: 72 79 0a 2a 2a 20 74 6f 20 72 65 63 79 63 6c 65  ry.** to recycle
6180: 20 70 61 67 65 73 20 74 6f 20 72 65 64 75 63 65   pages to reduce
6190: 20 74 68 65 20 6e 75 6d 62 65 72 20 61 6c 6c 6f   the number allo
61a0: 63 61 74 65 64 20 74 6f 20 6e 4d 61 78 50 61 67  cated to nMaxPag
61b0: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  e..*/.static voi
61c0: 64 20 70 63 61 63 68 65 31 45 6e 66 6f 72 63 65  d pcache1Enforce
61d0: 4d 61 78 50 61 67 65 28 50 47 72 6f 75 70 20 2a  MaxPage(PGroup *
61e0: 70 47 72 6f 75 70 29 7b 0a 20 20 61 73 73 65 72  pGroup){.  asser
61f0: 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78  t( sqlite3_mutex
6200: 5f 68 65 6c 64 28 70 47 72 6f 75 70 2d 3e 6d 75  _held(pGroup->mu
6210: 74 65 78 29 20 29 3b 0a 20 20 77 68 69 6c 65 28  tex) );.  while(
6220: 20 70 47 72 6f 75 70 2d 3e 6e 43 75 72 72 65 6e   pGroup->nCurren
6230: 74 50 61 67 65 3e 70 47 72 6f 75 70 2d 3e 6e 4d  tPage>pGroup->nM
6240: 61 78 50 61 67 65 20 26 26 20 70 47 72 6f 75 70  axPage && pGroup
6250: 2d 3e 70 4c 72 75 54 61 69 6c 20 29 7b 0a 20 20  ->pLruTail ){.  
6260: 20 20 50 67 48 64 72 31 20 2a 70 20 3d 20 70 47    PgHdr1 *p = pG
6270: 72 6f 75 70 2d 3e 70 4c 72 75 54 61 69 6c 3b 0a  roup->pLruTail;.
6280: 20 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e 70      assert( p->p
6290: 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3d 3d 70  Cache->pGroup==p
62a0: 47 72 6f 75 70 20 29 3b 0a 20 20 20 20 70 63 61  Group );.    pca
62b0: 63 68 65 31 50 69 6e 50 61 67 65 28 70 29 3b 0a  che1PinPage(p);.
62c0: 20 20 20 20 70 63 61 63 68 65 31 52 65 6d 6f 76      pcache1Remov
62d0: 65 46 72 6f 6d 48 61 73 68 28 70 29 3b 0a 20 20  eFromHash(p);.  
62e0: 20 20 70 63 61 63 68 65 31 46 72 65 65 50 61 67    pcache1FreePag
62f0: 65 28 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a  e(p);.  }.}../*.
6300: 2a 2a 20 44 69 73 63 61 72 64 20 61 6c 6c 20 70  ** Discard all p
6310: 61 67 65 73 20 66 72 6f 6d 20 63 61 63 68 65 20  ages from cache 
6320: 70 43 61 63 68 65 20 77 69 74 68 20 61 20 70 61  pCache with a pa
6330: 67 65 20 6e 75 6d 62 65 72 20 28 6b 65 79 20 76  ge number (key v
6340: 61 6c 75 65 29 20 0a 2a 2a 20 67 72 65 61 74 65  alue) .** greate
6350: 72 20 74 68 61 6e 20 6f 72 20 65 71 75 61 6c 20  r than or equal 
6360: 74 6f 20 69 4c 69 6d 69 74 2e 20 41 6e 79 20 70  to iLimit. Any p
6370: 69 6e 6e 65 64 20 70 61 67 65 73 20 74 68 61 74  inned pages that
6380: 20 6d 65 65 74 20 74 68 69 73 20 0a 2a 2a 20 63   meet this .** c
6390: 72 69 74 65 72 69 61 20 61 72 65 20 75 6e 70 69  riteria are unpi
63a0: 6e 6e 65 64 20 62 65 66 6f 72 65 20 74 68 65 79  nned before they
63b0: 20 61 72 65 20 64 69 73 63 61 72 64 65 64 2e 0a   are discarded..
63c0: 2a 2a 0a 2a 2a 20 54 68 65 20 50 43 61 63 68 65  **.** The PCache
63d0: 20 6d 75 74 65 78 20 6d 75 73 74 20 62 65 20 68   mutex must be h
63e0: 65 6c 64 20 77 68 65 6e 20 74 68 69 73 20 66 75  eld when this fu
63f0: 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64  nction is called
6400: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
6410: 20 70 63 61 63 68 65 31 54 72 75 6e 63 61 74 65   pcache1Truncate
6420: 55 6e 73 61 66 65 28 0a 20 20 50 43 61 63 68 65  Unsafe(.  PCache
6430: 31 20 2a 70 43 61 63 68 65 2c 20 20 20 20 20 20  1 *pCache,      
6440: 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 63 61         /* The ca
6450: 63 68 65 20 74 6f 20 74 72 75 6e 63 61 74 65 20  che to truncate 
6460: 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e  */.  unsigned in
6470: 74 20 69 4c 69 6d 69 74 20 20 20 20 20 20 20 20  t iLimit        
6480: 20 20 2f 2a 20 44 72 6f 70 20 70 61 67 65 73 20    /* Drop pages 
6490: 77 69 74 68 20 74 68 69 73 20 70 67 6e 6f 20 6f  with this pgno o
64a0: 72 20 6c 61 72 67 65 72 20 2a 2f 0a 29 7b 0a 20  r larger */.){. 
64b0: 20 54 45 53 54 4f 4e 4c 59 28 20 75 6e 73 69 67   TESTONLY( unsig
64c0: 6e 65 64 20 69 6e 74 20 6e 50 61 67 65 20 3d 20  ned int nPage = 
64d0: 30 3b 20 29 20 20 2f 2a 20 54 6f 20 61 73 73 65  0; )  /* To asse
64e0: 72 74 20 70 43 61 63 68 65 2d 3e 6e 50 61 67 65  rt pCache->nPage
64f0: 20 69 73 20 63 6f 72 72 65 63 74 20 2a 2f 0a 20   is correct */. 
6500: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 3b   unsigned int h;
6510: 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74  .  assert( sqlit
6520: 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 43  e3_mutex_held(pC
6530: 61 63 68 65 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75  ache->pGroup->mu
6540: 74 65 78 29 20 29 3b 0a 20 20 66 6f 72 28 68 3d  tex) );.  for(h=
6550: 30 3b 20 68 3c 70 43 61 63 68 65 2d 3e 6e 48 61  0; h<pCache->nHa
6560: 73 68 3b 20 68 2b 2b 29 7b 0a 20 20 20 20 50 67  sh; h++){.    Pg
6570: 48 64 72 31 20 2a 2a 70 70 20 3d 20 26 70 43 61  Hdr1 **pp = &pCa
6580: 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 20  che->apHash[h]; 
6590: 0a 20 20 20 20 50 67 48 64 72 31 20 2a 70 50 61  .    PgHdr1 *pPa
65a0: 67 65 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 28  ge;.    while( (
65b0: 70 50 61 67 65 20 3d 20 2a 70 70 29 21 3d 30 20  pPage = *pp)!=0 
65c0: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 70 50 61  ){.      if( pPa
65d0: 67 65 2d 3e 69 4b 65 79 3e 3d 69 4c 69 6d 69 74  ge->iKey>=iLimit
65e0: 20 29 7b 0a 20 20 20 20 20 20 20 20 70 43 61 63   ){.        pCac
65f0: 68 65 2d 3e 6e 50 61 67 65 2d 2d 3b 0a 20 20 20  he->nPage--;.   
6600: 20 20 20 20 20 2a 70 70 20 3d 20 70 50 61 67 65       *pp = pPage
6610: 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 20  ->pNext;.       
6620: 20 70 63 61 63 68 65 31 50 69 6e 50 61 67 65 28   pcache1PinPage(
6630: 70 50 61 67 65 29 3b 0a 20 20 20 20 20 20 20 20  pPage);.        
6640: 70 63 61 63 68 65 31 46 72 65 65 50 61 67 65 28  pcache1FreePage(
6650: 70 50 61 67 65 29 3b 0a 20 20 20 20 20 20 7d 65  pPage);.      }e
6660: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 70 70 20  lse{.        pp 
6670: 3d 20 26 70 50 61 67 65 2d 3e 70 4e 65 78 74 3b  = &pPage->pNext;
6680: 0a 20 20 20 20 20 20 20 20 54 45 53 54 4f 4e 4c  .        TESTONL
6690: 59 28 20 6e 50 61 67 65 2b 2b 3b 20 29 0a 20 20  Y( nPage++; ).  
66a0: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a      }.    }.  }.
66b0: 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65    assert( pCache
66c0: 2d 3e 6e 50 61 67 65 3d 3d 6e 50 61 67 65 20 29  ->nPage==nPage )
66d0: 3b 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ;.}../**********
66e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
66f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
6700: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
6710: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
6720: 2a 2a 2a 2a 2f 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 20  ****/./******** 
6730: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 4d  sqlite3_pcache M
6740: 65 74 68 6f 64 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a  ethods *********
6750: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
6760: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
6770: 2a 2a 2a 2a 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 49 6d  *****/../*.** Im
6780: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20  plementation of 
6790: 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63  the sqlite3_pcac
67a0: 68 65 2e 78 49 6e 69 74 20 6d 65 74 68 6f 64 2e  he.xInit method.
67b0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 70  .*/.static int p
67c0: 63 61 63 68 65 31 49 6e 69 74 28 76 6f 69 64 20  cache1Init(void 
67d0: 2a 4e 6f 74 55 73 65 64 29 7b 0a 20 20 55 4e 55  *NotUsed){.  UNU
67e0: 53 45 44 5f 50 41 52 41 4d 45 54 45 52 28 4e 6f  SED_PARAMETER(No
67f0: 74 55 73 65 64 29 3b 0a 20 20 61 73 73 65 72 74  tUsed);.  assert
6800: 28 20 70 63 61 63 68 65 31 2e 69 73 49 6e 69 74  ( pcache1.isInit
6810: 3d 3d 30 20 29 3b 0a 20 20 6d 65 6d 73 65 74 28  ==0 );.  memset(
6820: 26 70 63 61 63 68 65 31 2c 20 30 2c 20 73 69 7a  &pcache1, 0, siz
6830: 65 6f 66 28 70 63 61 63 68 65 31 29 29 3b 0a 20  eof(pcache1));. 
6840: 20 69 66 28 20 73 71 6c 69 74 65 33 47 6c 6f 62   if( sqlite3Glob
6850: 61 6c 43 6f 6e 66 69 67 2e 62 43 6f 72 65 4d 75  alConfig.bCoreMu
6860: 74 65 78 20 29 7b 0a 20 20 20 20 70 63 61 63 68  tex ){.    pcach
6870: 65 31 2e 67 72 70 2e 6d 75 74 65 78 20 3d 20 73  e1.grp.mutex = s
6880: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 61 6c 6c  qlite3_mutex_all
6890: 6f 63 28 53 51 4c 49 54 45 5f 4d 55 54 45 58 5f  oc(SQLITE_MUTEX_
68a0: 53 54 41 54 49 43 5f 4c 52 55 29 3b 0a 20 20 20  STATIC_LRU);.   
68b0: 20 70 63 61 63 68 65 31 2e 6d 75 74 65 78 20 3d   pcache1.mutex =
68c0: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 61   sqlite3_mutex_a
68d0: 6c 6c 6f 63 28 53 51 4c 49 54 45 5f 4d 55 54 45  lloc(SQLITE_MUTE
68e0: 58 5f 53 54 41 54 49 43 5f 50 4d 45 4d 29 3b 0a  X_STATIC_PMEM);.
68f0: 20 20 7d 0a 20 20 70 63 61 63 68 65 31 2e 67 72    }.  pcache1.gr
6900: 70 2e 6d 78 50 69 6e 6e 65 64 20 3d 20 31 30 3b  p.mxPinned = 10;
6910: 0a 20 20 70 63 61 63 68 65 31 2e 69 73 49 6e 69  .  pcache1.isIni
6920: 74 20 3d 20 31 3b 0a 20 20 72 65 74 75 72 6e 20  t = 1;.  return 
6930: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a  SQLITE_OK;.}../*
6940: 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69  .** Implementati
6950: 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65  on of the sqlite
6960: 33 5f 70 63 61 63 68 65 2e 78 53 68 75 74 64 6f  3_pcache.xShutdo
6970: 77 6e 20 6d 65 74 68 6f 64 2e 0a 2a 2a 20 4e 6f  wn method..** No
6980: 74 65 20 74 68 61 74 20 74 68 65 20 73 74 61 74  te that the stat
6990: 69 63 20 6d 75 74 65 78 20 61 6c 6c 6f 63 61 74  ic mutex allocat
69a0: 65 64 20 69 6e 20 78 49 6e 69 74 20 64 6f 65 73  ed in xInit does
69b0: 20 0a 2a 2a 20 6e 6f 74 20 6e 65 65 64 20 74 6f   .** not need to
69c0: 20 62 65 20 66 72 65 65 64 2e 0a 2a 2f 0a 73 74   be freed..*/.st
69d0: 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65  atic void pcache
69e0: 31 53 68 75 74 64 6f 77 6e 28 76 6f 69 64 20 2a  1Shutdown(void *
69f0: 4e 6f 74 55 73 65 64 29 7b 0a 20 20 55 4e 55 53  NotUsed){.  UNUS
6a00: 45 44 5f 50 41 52 41 4d 45 54 45 52 28 4e 6f 74  ED_PARAMETER(Not
6a10: 55 73 65 64 29 3b 0a 20 20 61 73 73 65 72 74 28  Used);.  assert(
6a20: 20 70 63 61 63 68 65 31 2e 69 73 49 6e 69 74 21   pcache1.isInit!
6a30: 3d 30 20 29 3b 0a 20 20 6d 65 6d 73 65 74 28 26  =0 );.  memset(&
6a40: 70 63 61 63 68 65 31 2c 20 30 2c 20 73 69 7a 65  pcache1, 0, size
6a50: 6f 66 28 70 63 61 63 68 65 31 29 29 3b 0a 7d 0a  of(pcache1));.}.
6a60: 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74  ./*.** Implement
6a70: 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c  ation of the sql
6a80: 69 74 65 33 5f 70 63 61 63 68 65 2e 78 43 72 65  ite3_pcache.xCre
6a90: 61 74 65 20 6d 65 74 68 6f 64 2e 0a 2a 2a 0a 2a  ate method..**.*
6aa0: 2a 20 41 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77  * Allocate a new
6ab0: 20 63 61 63 68 65 2e 0a 2a 2f 0a 73 74 61 74 69   cache..*/.stati
6ac0: 63 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  c sqlite3_pcache
6ad0: 20 2a 70 63 61 63 68 65 31 43 72 65 61 74 65 28   *pcache1Create(
6ae0: 69 6e 74 20 73 7a 50 61 67 65 2c 20 69 6e 74 20  int szPage, int 
6af0: 62 50 75 72 67 65 61 62 6c 65 29 7b 0a 20 20 50  bPurgeable){.  P
6b00: 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 3b 20  Cache1 *pCache; 
6b10: 20 20 20 20 20 2f 2a 20 54 68 65 20 6e 65 77 6c       /* The newl
6b20: 79 20 63 72 65 61 74 65 64 20 70 61 67 65 20 63  y created page c
6b30: 61 63 68 65 20 2a 2f 0a 20 20 50 47 72 6f 75 70  ache */.  PGroup
6b40: 20 2a 70 47 72 6f 75 70 3b 20 20 20 20 20 20 20   *pGroup;       
6b50: 2f 2a 20 54 68 65 20 67 72 6f 75 70 20 74 68 65  /* The group the
6b60: 20 6e 65 77 20 70 61 67 65 20 63 61 63 68 65 20   new page cache 
6b70: 77 69 6c 6c 20 62 65 6c 6f 6e 67 20 74 6f 20 2a  will belong to *
6b80: 2f 0a 20 20 69 6e 74 20 73 7a 3b 20 20 20 20 20  /.  int sz;     
6b90: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74            /* Byt
6ba0: 65 73 20 6f 66 20 6d 65 6d 6f 72 79 20 72 65 71  es of memory req
6bb0: 75 69 72 65 64 20 74 6f 20 61 6c 6c 6f 63 61 74  uired to allocat
6bc0: 65 20 74 68 65 20 6e 65 77 20 63 61 63 68 65 20  e the new cache 
6bd0: 2a 2f 0a 0a 20 20 2f 2a 0a 20 20 2a 2a 20 54 68  */..  /*.  ** Th
6be0: 65 20 73 65 70 65 72 61 74 65 43 61 63 68 65 20  e seperateCache 
6bf0: 76 61 72 69 61 62 6c 65 20 69 73 20 74 72 75 65  variable is true
6c00: 20 69 66 20 65 61 63 68 20 50 43 61 63 68 65 20   if each PCache 
6c10: 68 61 73 20 69 74 73 20 6f 77 6e 20 70 72 69 76  has its own priv
6c20: 61 74 65 0a 20 20 2a 2a 20 50 47 72 6f 75 70 2e  ate.  ** PGroup.
6c30: 20 20 49 6e 20 6f 74 68 65 72 20 77 6f 72 64 73    In other words
6c40: 2c 20 73 65 70 61 72 61 74 65 43 61 63 68 65 20  , separateCache 
6c50: 69 73 20 74 72 75 65 20 66 6f 72 20 6d 6f 64 65  is true for mode
6c60: 20 28 31 29 20 77 68 65 72 65 20 6e 6f 0a 20 20   (1) where no.  
6c70: 2a 2a 20 6d 75 74 65 78 69 6e 67 20 69 73 20 72  ** mutexing is r
6c80: 65 71 75 69 72 65 64 2e 0a 20 20 2a 2a 0a 20 20  equired..  **.  
6c90: 2a 2a 20 20 20 2a 20 20 41 6c 77 61 79 73 20 75  **   *  Always u
6ca0: 73 65 20 61 20 75 6e 69 66 69 65 64 20 63 61 63  se a unified cac
6cb0: 68 65 20 28 6d 6f 64 65 2d 32 29 20 69 66 20 45  he (mode-2) if E
6cc0: 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e  NABLE_MEMORY_MAN
6cd0: 41 47 45 4d 45 4e 54 0a 20 20 2a 2a 0a 20 20 2a  AGEMENT.  **.  *
6ce0: 2a 20 20 20 2a 20 20 41 6c 77 61 79 73 20 75 73  *   *  Always us
6cf0: 65 20 61 20 75 6e 69 66 69 65 64 20 63 61 63 68  e a unified cach
6d00: 65 20 69 6e 20 73 69 6e 67 6c 65 2d 74 68 72 65  e in single-thre
6d10: 61 64 65 64 20 61 70 70 6c 69 63 61 74 69 6f 6e  aded application
6d20: 73 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 2a 20  s.  **.  **   * 
6d30: 20 4f 74 68 65 72 77 69 73 65 20 28 69 66 20 6d   Otherwise (if m
6d40: 75 6c 74 69 2d 74 68 72 65 61 64 65 64 20 61 6e  ulti-threaded an
6d50: 64 20 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f  d ENABLE_MEMORY_
6d60: 4d 41 4e 41 47 45 4d 45 4e 54 20 69 73 20 6f 66  MANAGEMENT is of
6d70: 66 29 0a 20 20 2a 2a 20 20 20 20 20 20 75 73 65  f).  **      use
6d80: 20 73 65 70 61 72 61 74 65 20 63 61 63 68 65 73   separate caches
6d90: 20 28 6d 6f 64 65 2d 31 29 0a 20 20 2a 2f 0a 23   (mode-1).  */.#
6da0: 69 66 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54  if defined(SQLIT
6db0: 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f  E_ENABLE_MEMORY_
6dc0: 4d 41 4e 41 47 45 4d 45 4e 54 29 20 7c 7c 20 53  MANAGEMENT) || S
6dd0: 51 4c 49 54 45 5f 54 48 52 45 41 44 53 41 46 45  QLITE_THREADSAFE
6de0: 3d 3d 30 0a 20 20 63 6f 6e 73 74 20 69 6e 74 20  ==0.  const int 
6df0: 73 65 70 61 72 61 74 65 43 61 63 68 65 20 3d 20  separateCache = 
6e00: 30 3b 0a 23 65 6c 73 65 0a 20 20 69 6e 74 20 73  0;.#else.  int s
6e10: 65 70 61 72 61 74 65 43 61 63 68 65 20 3d 20 73  eparateCache = s
6e20: 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66  qlite3GlobalConf
6e30: 69 67 2e 62 43 6f 72 65 4d 75 74 65 78 3e 30 3b  ig.bCoreMutex>0;
6e40: 0a 23 65 6e 64 69 66 0a 0a 20 20 73 7a 20 3d 20  .#endif..  sz = 
6e50: 73 69 7a 65 6f 66 28 50 43 61 63 68 65 31 29 20  sizeof(PCache1) 
6e60: 2b 20 73 69 7a 65 6f 66 28 50 47 72 6f 75 70 29  + sizeof(PGroup)
6e70: 2a 73 65 70 61 72 61 74 65 43 61 63 68 65 3b 0a  *separateCache;.
6e80: 20 20 70 43 61 63 68 65 20 3d 20 28 50 43 61 63    pCache = (PCac
6e90: 68 65 31 20 2a 29 73 71 6c 69 74 65 33 5f 6d 61  he1 *)sqlite3_ma
6ea0: 6c 6c 6f 63 28 73 7a 29 3b 0a 20 20 69 66 28 20  lloc(sz);.  if( 
6eb0: 70 43 61 63 68 65 20 29 7b 0a 20 20 20 20 6d 65  pCache ){.    me
6ec0: 6d 73 65 74 28 70 43 61 63 68 65 2c 20 30 2c 20  mset(pCache, 0, 
6ed0: 73 7a 29 3b 0a 20 20 20 20 69 66 28 20 73 65 70  sz);.    if( sep
6ee0: 61 72 61 74 65 43 61 63 68 65 20 29 7b 0a 20 20  arateCache ){.  
6ef0: 20 20 20 20 70 47 72 6f 75 70 20 3d 20 28 50 47      pGroup = (PG
6f00: 72 6f 75 70 2a 29 26 70 43 61 63 68 65 5b 31 5d  roup*)&pCache[1]
6f10: 3b 0a 20 20 20 20 20 20 70 47 72 6f 75 70 2d 3e  ;.      pGroup->
6f20: 6d 78 50 69 6e 6e 65 64 20 3d 20 31 30 3b 0a 20  mxPinned = 10;. 
6f30: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
6f40: 70 47 72 6f 75 70 20 3d 20 26 70 63 61 63 68 65  pGroup = &pcache
6f50: 31 2e 67 72 70 3b 0a 20 20 20 20 7d 0a 20 20 20  1.grp;.    }.   
6f60: 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 20   pCache->pGroup 
6f70: 3d 20 70 47 72 6f 75 70 3b 0a 20 20 20 20 70 43  = pGroup;.    pC
6f80: 61 63 68 65 2d 3e 73 7a 50 61 67 65 20 3d 20 73  ache->szPage = s
6f90: 7a 50 61 67 65 3b 0a 20 20 20 20 70 43 61 63 68  zPage;.    pCach
6fa0: 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 3d 20  e->bPurgeable = 
6fb0: 28 62 50 75 72 67 65 61 62 6c 65 20 3f 20 31 20  (bPurgeable ? 1 
6fc0: 3a 20 30 29 3b 0a 20 20 20 20 69 66 28 20 62 50  : 0);.    if( bP
6fd0: 75 72 67 65 61 62 6c 65 20 29 7b 0a 20 20 20 20  urgeable ){.    
6fe0: 20 20 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 20 3d    pCache->nMin =
6ff0: 20 31 30 3b 0a 20 20 20 20 20 20 70 63 61 63 68   10;.      pcach
7000: 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70 47 72  e1EnterMutex(pGr
7010: 6f 75 70 29 3b 0a 20 20 20 20 20 20 70 47 72 6f  oup);.      pGro
7020: 75 70 2d 3e 6e 4d 69 6e 50 61 67 65 20 2b 3d 20  up->nMinPage += 
7030: 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 3b 0a 20 20  pCache->nMin;.  
7040: 20 20 20 20 70 47 72 6f 75 70 2d 3e 6d 78 50 69      pGroup->mxPi
7050: 6e 6e 65 64 20 3d 20 70 47 72 6f 75 70 2d 3e 6e  nned = pGroup->n
7060: 4d 61 78 50 61 67 65 20 2b 20 31 30 20 2d 20 70  MaxPage + 10 - p
7070: 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67 65 3b  Group->nMinPage;
7080: 0a 20 20 20 20 20 20 70 63 61 63 68 65 31 4c 65  .      pcache1Le
7090: 61 76 65 4d 75 74 65 78 28 70 47 72 6f 75 70 29  aveMutex(pGroup)
70a0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65  ;.    }.  }.  re
70b0: 74 75 72 6e 20 28 73 71 6c 69 74 65 33 5f 70 63  turn (sqlite3_pc
70c0: 61 63 68 65 20 2a 29 70 43 61 63 68 65 3b 0a 7d  ache *)pCache;.}
70d0: 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e  ../*.** Implemen
70e0: 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71  tation of the sq
70f0: 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78 43 61  lite3_pcache.xCa
7100: 63 68 65 73 69 7a 65 20 6d 65 74 68 6f 64 2e 20  chesize method. 
7110: 0a 2a 2a 0a 2a 2a 20 43 6f 6e 66 69 67 75 72 65  .**.** Configure
7120: 20 74 68 65 20 63 61 63 68 65 5f 73 69 7a 65 20   the cache_size 
7130: 6c 69 6d 69 74 20 66 6f 72 20 61 20 63 61 63 68  limit for a cach
7140: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  e..*/.static voi
7150: 64 20 70 63 61 63 68 65 31 43 61 63 68 65 73 69  d pcache1Cachesi
7160: 7a 65 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68  ze(sqlite3_pcach
7170: 65 20 2a 70 2c 20 69 6e 74 20 6e 4d 61 78 29 7b  e *p, int nMax){
7180: 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63  .  PCache1 *pCac
7190: 68 65 20 3d 20 28 50 43 61 63 68 65 31 20 2a 29  he = (PCache1 *)
71a0: 70 3b 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d  p;.  if( pCache-
71b0: 3e 62 50 75 72 67 65 61 62 6c 65 20 29 7b 0a 20  >bPurgeable ){. 
71c0: 20 20 20 50 47 72 6f 75 70 20 2a 70 47 72 6f 75     PGroup *pGrou
71d0: 70 20 3d 20 70 43 61 63 68 65 2d 3e 70 47 72 6f  p = pCache->pGro
71e0: 75 70 3b 0a 20 20 20 20 70 63 61 63 68 65 31 45  up;.    pcache1E
71f0: 6e 74 65 72 4d 75 74 65 78 28 70 47 72 6f 75 70  nterMutex(pGroup
7200: 29 3b 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e 6e  );.    pGroup->n
7210: 4d 61 78 50 61 67 65 20 2b 3d 20 28 6e 4d 61 78  MaxPage += (nMax
7220: 20 2d 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 29   - pCache->nMax)
7230: 3b 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e 6d 78  ;.    pGroup->mx
7240: 50 69 6e 6e 65 64 20 3d 20 70 47 72 6f 75 70 2d  Pinned = pGroup-
7250: 3e 6e 4d 61 78 50 61 67 65 20 2b 20 31 30 20 2d  >nMaxPage + 10 -
7260: 20 70 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67   pGroup->nMinPag
7270: 65 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 6e  e;.    pCache->n
7280: 4d 61 78 20 3d 20 6e 4d 61 78 3b 0a 20 20 20 20  Max = nMax;.    
7290: 70 43 61 63 68 65 2d 3e 6e 39 30 70 63 74 20 3d  pCache->n90pct =
72a0: 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 2a 39 2f   pCache->nMax*9/
72b0: 31 30 3b 0a 20 20 20 20 70 63 61 63 68 65 31 45  10;.    pcache1E
72c0: 6e 66 6f 72 63 65 4d 61 78 50 61 67 65 28 70 47  nforceMaxPage(pG
72d0: 72 6f 75 70 29 3b 0a 20 20 20 20 70 63 61 63 68  roup);.    pcach
72e0: 65 31 4c 65 61 76 65 4d 75 74 65 78 28 70 47 72  e1LeaveMutex(pGr
72f0: 6f 75 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a  oup);.  }.}../*.
7300: 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  ** Implementatio
7310: 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33  n of the sqlite3
7320: 5f 70 63 61 63 68 65 2e 78 50 61 67 65 63 6f 75  _pcache.xPagecou
7330: 6e 74 20 6d 65 74 68 6f 64 2e 20 0a 2a 2f 0a 73  nt method. .*/.s
7340: 74 61 74 69 63 20 69 6e 74 20 70 63 61 63 68 65  tatic int pcache
7350: 31 50 61 67 65 63 6f 75 6e 74 28 73 71 6c 69 74  1Pagecount(sqlit
7360: 65 33 5f 70 63 61 63 68 65 20 2a 70 29 7b 0a 20  e3_pcache *p){. 
7370: 20 69 6e 74 20 6e 3b 0a 20 20 50 43 61 63 68 65   int n;.  PCache
7380: 31 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61  1 *pCache = (PCa
7390: 63 68 65 31 2a 29 70 3b 0a 20 20 70 63 61 63 68  che1*)p;.  pcach
73a0: 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70 43 61  e1EnterMutex(pCa
73b0: 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 20 20  che->pGroup);.  
73c0: 6e 20 3d 20 70 43 61 63 68 65 2d 3e 6e 50 61 67  n = pCache->nPag
73d0: 65 3b 0a 20 20 70 63 61 63 68 65 31 4c 65 61 76  e;.  pcache1Leav
73e0: 65 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e 70  eMutex(pCache->p
73f0: 47 72 6f 75 70 29 3b 0a 20 20 72 65 74 75 72 6e  Group);.  return
7400: 20 6e 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70   n;.}../*.** Imp
7410: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74  lementation of t
7420: 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68  he sqlite3_pcach
7430: 65 2e 78 46 65 74 63 68 20 6d 65 74 68 6f 64 2e  e.xFetch method.
7440: 20 0a 2a 2a 0a 2a 2a 20 46 65 74 63 68 20 61 20   .**.** Fetch a 
7450: 70 61 67 65 20 62 79 20 6b 65 79 20 76 61 6c 75  page by key valu
7460: 65 2e 0a 2a 2a 0a 2a 2a 20 57 68 65 74 68 65 72  e..**.** Whether
7470: 20 6f 72 20 6e 6f 74 20 61 20 6e 65 77 20 70 61   or not a new pa
7480: 67 65 20 6d 61 79 20 62 65 20 61 6c 6c 6f 63 61  ge may be alloca
7490: 74 65 64 20 62 79 20 74 68 69 73 20 66 75 6e 63  ted by this func
74a0: 74 69 6f 6e 20 64 65 70 65 6e 64 73 20 6f 6e 0a  tion depends on.
74b0: 2a 2a 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20  ** the value of 
74c0: 74 68 65 20 63 72 65 61 74 65 46 6c 61 67 20 61  the createFlag a
74d0: 72 67 75 6d 65 6e 74 2e 20 20 30 20 6d 65 61 6e  rgument.  0 mean
74e0: 73 20 64 6f 20 6e 6f 74 20 61 6c 6c 6f 63 61 74  s do not allocat
74f0: 65 20 61 20 6e 65 77 0a 2a 2a 20 70 61 67 65 2e  e a new.** page.
7500: 20 20 31 20 6d 65 61 6e 73 20 61 6c 6c 6f 63 61    1 means alloca
7510: 74 65 20 61 20 6e 65 77 20 70 61 67 65 20 69 66  te a new page if
7520: 20 73 70 61 63 65 20 69 73 20 65 61 73 69 6c 79   space is easily
7530: 20 61 76 61 69 6c 61 62 6c 65 2e 20 20 32 20 0a   available.  2 .
7540: 2a 2a 20 6d 65 61 6e 73 20 74 6f 20 74 72 79 20  ** means to try 
7550: 72 65 61 6c 6c 79 20 68 61 72 64 20 74 6f 20 61  really hard to a
7560: 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 70 61  llocate a new pa
7570: 67 65 2e 0a 2a 2a 0a 2a 2a 20 46 6f 72 20 61 20  ge..**.** For a 
7580: 6e 6f 6e 2d 70 75 72 67 65 61 62 6c 65 20 63 61  non-purgeable ca
7590: 63 68 65 20 28 61 20 63 61 63 68 65 20 75 73 65  che (a cache use
75a0: 64 20 61 73 20 74 68 65 20 73 74 6f 72 61 67 65  d as the storage
75b0: 20 66 6f 72 20 61 6e 20 69 6e 2d 6d 65 6d 6f 72   for an in-memor
75c0: 79 0a 2a 2a 20 64 61 74 61 62 61 73 65 29 20 74  y.** database) t
75d0: 68 65 72 65 20 69 73 20 72 65 61 6c 6c 79 20 6e  here is really n
75e0: 6f 20 64 69 66 66 65 72 65 6e 63 65 20 62 65 74  o difference bet
75f0: 77 65 65 6e 20 63 72 65 61 74 65 46 6c 61 67 20  ween createFlag 
7600: 31 20 61 6e 64 20 32 2e 20 20 53 6f 0a 2a 2a 20  1 and 2.  So.** 
7610: 74 68 65 20 63 61 6c 6c 69 6e 67 20 66 75 6e 63  the calling func
7620: 74 69 6f 6e 20 28 70 63 61 63 68 65 2e 63 29 20  tion (pcache.c) 
7630: 77 69 6c 6c 20 6e 65 76 65 72 20 68 61 76 65 20  will never have 
7640: 61 20 63 72 65 61 74 65 46 6c 61 67 20 6f 66 20  a createFlag of 
7650: 31 20 6f 6e 0a 2a 2a 20 61 20 6e 6f 6e 2d 70 75  1 on.** a non-pu
7660: 72 67 61 62 6c 65 20 63 61 63 68 65 2e 0a 2a 2a  rgable cache..**
7670: 0a 2a 2a 20 54 68 65 72 65 20 61 72 65 20 74 68  .** There are th
7680: 72 65 65 20 64 69 66 66 65 72 65 6e 74 20 61 70  ree different ap
7690: 70 72 6f 61 63 68 65 73 20 74 6f 20 6f 62 74 61  proaches to obta
76a0: 69 6e 69 6e 67 20 73 70 61 63 65 20 66 6f 72 20  ining space for 
76b0: 61 20 70 61 67 65 2c 0a 2a 2a 20 64 65 70 65 6e  a page,.** depen
76c0: 64 69 6e 67 20 6f 6e 20 74 68 65 20 76 61 6c 75  ding on the valu
76d0: 65 20 6f 66 20 70 61 72 61 6d 65 74 65 72 20 63  e of parameter c
76e0: 72 65 61 74 65 46 6c 61 67 20 28 77 68 69 63 68  reateFlag (which
76f0: 20 6d 61 79 20 62 65 20 30 2c 20 31 20 6f 72 20   may be 0, 1 or 
7700: 32 29 2e 0a 2a 2a 0a 2a 2a 20 20 20 31 2e 20 52  2)..**.**   1. R
7710: 65 67 61 72 64 6c 65 73 73 20 6f 66 20 74 68 65  egardless of the
7720: 20 76 61 6c 75 65 20 6f 66 20 63 72 65 61 74 65   value of create
7730: 46 6c 61 67 2c 20 74 68 65 20 63 61 63 68 65 20  Flag, the cache 
7740: 69 73 20 73 65 61 72 63 68 65 64 20 66 6f 72 20  is searched for 
7750: 61 20 0a 2a 2a 20 20 20 20 20 20 63 6f 70 79 20  a .**      copy 
7760: 6f 66 20 74 68 65 20 72 65 71 75 65 73 74 65 64  of the requested
7770: 20 70 61 67 65 2e 20 49 66 20 6f 6e 65 20 69 73   page. If one is
7780: 20 66 6f 75 6e 64 2c 20 69 74 20 69 73 20 72 65   found, it is re
7790: 74 75 72 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 20 20  turned..**.**   
77a0: 32 2e 20 49 66 20 63 72 65 61 74 65 46 6c 61 67  2. If createFlag
77b0: 3d 3d 30 20 61 6e 64 20 74 68 65 20 70 61 67 65  ==0 and the page
77c0: 20 69 73 20 6e 6f 74 20 61 6c 72 65 61 64 79 20   is not already 
77d0: 69 6e 20 74 68 65 20 63 61 63 68 65 2c 20 4e 55  in the cache, NU
77e0: 4c 4c 20 69 73 0a 2a 2a 20 20 20 20 20 20 72 65  LL is.**      re
77f0: 74 75 72 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 20 20  turned..**.**   
7800: 33 2e 20 49 66 20 63 72 65 61 74 65 46 6c 61 67  3. If createFlag
7810: 20 69 73 20 31 2c 20 61 6e 64 20 74 68 65 20 70   is 1, and the p
7820: 61 67 65 20 69 73 20 6e 6f 74 20 61 6c 72 65 61  age is not alrea
7830: 64 79 20 69 6e 20 74 68 65 20 63 61 63 68 65 2c  dy in the cache,
7840: 20 74 68 65 6e 0a 2a 2a 20 20 20 20 20 20 72 65   then.**      re
7850: 74 75 72 6e 20 4e 55 4c 4c 20 28 64 6f 20 6e 6f  turn NULL (do no
7860: 74 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77  t allocate a new
7870: 20 70 61 67 65 29 20 69 66 20 61 6e 79 20 6f 66   page) if any of
7880: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 0a 2a   the following.*
7890: 2a 20 20 20 20 20 20 63 6f 6e 64 69 74 69 6f 6e  *      condition
78a0: 73 20 61 72 65 20 74 72 75 65 3a 0a 2a 2a 0a 2a  s are true:.**.*
78b0: 2a 20 20 20 20 20 20 20 28 61 29 20 74 68 65 20  *       (a) the 
78c0: 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20  number of pages 
78d0: 70 69 6e 6e 65 64 20 62 79 20 74 68 65 20 63 61  pinned by the ca
78e0: 63 68 65 20 69 73 20 67 72 65 61 74 65 72 20 74  che is greater t
78f0: 68 61 6e 0a 2a 2a 20 20 20 20 20 20 20 20 20 20  han.**          
7900: 20 50 43 61 63 68 65 31 2e 6e 4d 61 78 2c 20 6f   PCache1.nMax, o
7910: 72 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 28 62  r.**.**       (b
7920: 29 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  ) the number of 
7930: 70 61 67 65 73 20 70 69 6e 6e 65 64 20 62 79 20  pages pinned by 
7940: 74 68 65 20 63 61 63 68 65 20 69 73 20 67 72 65  the cache is gre
7950: 61 74 65 72 20 74 68 61 6e 0a 2a 2a 20 20 20 20  ater than.**    
7960: 20 20 20 20 20 20 20 74 68 65 20 73 75 6d 20 6f         the sum o
7970: 66 20 6e 4d 61 78 20 66 6f 72 20 61 6c 6c 20 70  f nMax for all p
7980: 75 72 67 65 61 62 6c 65 20 63 61 63 68 65 73 2c  urgeable caches,
7990: 20 6c 65 73 73 20 74 68 65 20 73 75 6d 20 6f 66   less the sum of
79a0: 20 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 6e   .**           n
79b0: 4d 69 6e 20 66 6f 72 20 61 6c 6c 20 6f 74 68 65  Min for all othe
79c0: 72 20 70 75 72 67 65 61 62 6c 65 20 63 61 63 68  r purgeable cach
79d0: 65 73 2c 20 6f 72 0a 2a 2a 0a 2a 2a 20 20 20 34  es, or.**.**   4
79e0: 2e 20 49 66 20 6e 6f 6e 65 20 6f 66 20 74 68 65  . If none of the
79f0: 20 66 69 72 73 74 20 74 68 72 65 65 20 63 6f 6e   first three con
7a00: 64 69 74 69 6f 6e 73 20 61 70 70 6c 79 20 61 6e  ditions apply an
7a10: 64 20 74 68 65 20 63 61 63 68 65 20 69 73 20 6d  d the cache is m
7a20: 61 72 6b 65 64 0a 2a 2a 20 20 20 20 20 20 61 73  arked.**      as
7a30: 20 70 75 72 67 65 61 62 6c 65 2c 20 61 6e 64 20   purgeable, and 
7a40: 69 66 20 6f 6e 65 20 6f 66 20 74 68 65 20 66 6f  if one of the fo
7a50: 6c 6c 6f 77 69 6e 67 20 69 73 20 74 72 75 65 3a  llowing is true:
7a60: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 28 61 29  .**.**       (a)
7a70: 20 54 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70   The number of p
7a80: 61 67 65 73 20 61 6c 6c 6f 63 61 74 65 64 20 66  ages allocated f
7a90: 6f 72 20 74 68 65 20 63 61 63 68 65 20 69 73 20  or the cache is 
7aa0: 61 6c 72 65 61 64 79 20 0a 2a 2a 20 20 20 20 20  already .**     
7ab0: 20 20 20 20 20 20 50 43 61 63 68 65 31 2e 6e 4d        PCache1.nM
7ac0: 61 78 2c 20 6f 72 0a 2a 2a 0a 2a 2a 20 20 20 20  ax, or.**.**    
7ad0: 20 20 20 28 62 29 20 54 68 65 20 6e 75 6d 62 65     (b) The numbe
7ae0: 72 20 6f 66 20 70 61 67 65 73 20 61 6c 6c 6f 63  r of pages alloc
7af0: 61 74 65 64 20 66 6f 72 20 61 6c 6c 20 70 75 72  ated for all pur
7b00: 67 65 61 62 6c 65 20 63 61 63 68 65 73 20 69 73  geable caches is
7b10: 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 61 6c  .**           al
7b20: 72 65 61 64 79 20 65 71 75 61 6c 20 74 6f 20 6f  ready equal to o
7b30: 72 20 67 72 65 61 74 65 72 20 74 68 61 6e 20 74  r greater than t
7b40: 68 65 20 73 75 6d 20 6f 66 20 6e 4d 61 78 20 66  he sum of nMax f
7b50: 6f 72 20 61 6c 6c 0a 2a 2a 20 20 20 20 20 20 20  or all.**       
7b60: 20 20 20 20 70 75 72 67 65 61 62 6c 65 20 63 61      purgeable ca
7b70: 63 68 65 73 2c 0a 2a 2a 0a 2a 2a 20 20 20 20 20  ches,.**.**     
7b80: 20 20 28 63 29 20 54 68 65 20 73 79 73 74 65 6d    (c) The system
7b90: 20 69 73 20 75 6e 64 65 72 20 6d 65 6d 6f 72 79   is under memory
7ba0: 20 70 72 65 73 73 75 72 65 20 61 6e 64 20 77 61   pressure and wa
7bb0: 6e 74 73 20 74 6f 20 61 76 6f 69 64 0a 2a 2a 20  nts to avoid.** 
7bc0: 20 20 20 20 20 20 20 20 20 20 75 6e 6e 65 63 65            unnece
7bd0: 73 73 61 72 79 20 70 61 67 65 73 20 63 61 63 68  ssary pages cach
7be0: 65 20 65 6e 74 72 79 20 61 6c 6c 6f 63 61 74 69  e entry allocati
7bf0: 6f 6e 73 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 74  ons.**.**      t
7c00: 68 65 6e 20 61 74 74 65 6d 70 74 20 74 6f 20 72  hen attempt to r
7c10: 65 63 79 63 6c 65 20 61 20 70 61 67 65 20 66 72  ecycle a page fr
7c20: 6f 6d 20 74 68 65 20 4c 52 55 20 6c 69 73 74 2e  om the LRU list.
7c30: 20 49 66 20 69 74 20 69 73 20 74 68 65 20 72 69   If it is the ri
7c40: 67 68 74 0a 2a 2a 20 20 20 20 20 20 73 69 7a 65  ght.**      size
7c50: 2c 20 72 65 74 75 72 6e 20 74 68 65 20 72 65 63  , return the rec
7c60: 79 63 6c 65 64 20 62 75 66 66 65 72 2e 20 4f 74  ycled buffer. Ot
7c70: 68 65 72 77 69 73 65 2c 20 66 72 65 65 20 74 68  herwise, free th
7c80: 65 20 62 75 66 66 65 72 20 61 6e 64 0a 2a 2a 20  e buffer and.** 
7c90: 20 20 20 20 20 70 72 6f 63 65 65 64 20 74 6f 20       proceed to 
7ca0: 73 74 65 70 20 35 2e 20 0a 2a 2a 0a 2a 2a 20 20  step 5. .**.**  
7cb0: 20 35 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 61   5. Otherwise, a
7cc0: 6c 6c 6f 63 61 74 65 20 61 6e 64 20 72 65 74 75  llocate and retu
7cd0: 72 6e 20 61 20 6e 65 77 20 70 61 67 65 20 62 75  rn a new page bu
7ce0: 66 66 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ffer..*/.static 
7cf0: 76 6f 69 64 20 2a 70 63 61 63 68 65 31 46 65 74  void *pcache1Fet
7d00: 63 68 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68  ch(sqlite3_pcach
7d10: 65 20 2a 70 2c 20 75 6e 73 69 67 6e 65 64 20 69  e *p, unsigned i
7d20: 6e 74 20 69 4b 65 79 2c 20 69 6e 74 20 63 72 65  nt iKey, int cre
7d30: 61 74 65 46 6c 61 67 29 7b 0a 20 20 69 6e 74 20  ateFlag){.  int 
7d40: 6e 50 69 6e 6e 65 64 3b 0a 20 20 50 43 61 63 68  nPinned;.  PCach
7d50: 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43  e1 *pCache = (PC
7d60: 61 63 68 65 31 20 2a 29 70 3b 0a 20 20 50 47 72  ache1 *)p;.  PGr
7d70: 6f 75 70 20 2a 70 47 72 6f 75 70 3b 0a 20 20 50  oup *pGroup;.  P
7d80: 67 48 64 72 31 20 2a 70 50 61 67 65 20 3d 20 30  gHdr1 *pPage = 0
7d90: 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70 43 61  ;..  assert( pCa
7da0: 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20  che->bPurgeable 
7db0: 7c 7c 20 63 72 65 61 74 65 46 6c 61 67 21 3d 31  || createFlag!=1
7dc0: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 43   );.  assert( pC
7dd0: 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65  ache->bPurgeable
7de0: 20 7c 7c 20 70 43 61 63 68 65 2d 3e 6e 4d 69 6e   || pCache->nMin
7df0: 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28  ==0 );.  assert(
7e00: 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61   pCache->bPurgea
7e10: 62 6c 65 3d 3d 30 20 7c 7c 20 70 43 61 63 68 65  ble==0 || pCache
7e20: 2d 3e 6e 4d 69 6e 3d 3d 31 30 20 29 3b 0a 20 20  ->nMin==10 );.  
7e30: 61 73 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e  assert( pCache->
7e40: 6e 4d 69 6e 3d 3d 30 20 7c 7c 20 70 43 61 63 68  nMin==0 || pCach
7e50: 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 29 3b  e->bPurgeable );
7e60: 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d  .  pcache1EnterM
7e70: 75 74 65 78 28 70 47 72 6f 75 70 20 3d 20 70 43  utex(pGroup = pC
7e80: 61 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 0a  ache->pGroup);..
7e90: 20 20 2f 2a 20 53 74 65 70 20 31 3a 20 53 65 61    /* Step 1: Sea
7ea0: 72 63 68 20 74 68 65 20 68 61 73 68 20 74 61 62  rch the hash tab
7eb0: 6c 65 20 66 6f 72 20 61 6e 20 65 78 69 73 74 69  le for an existi
7ec0: 6e 67 20 65 6e 74 72 79 2e 20 2a 2f 0a 20 20 69  ng entry. */.  i
7ed0: 66 28 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68  f( pCache->nHash
7ee0: 3e 30 20 29 7b 0a 20 20 20 20 75 6e 73 69 67 6e  >0 ){.    unsign
7ef0: 65 64 20 69 6e 74 20 68 20 3d 20 69 4b 65 79 20  ed int h = iKey 
7f00: 25 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3b  % pCache->nHash;
7f10: 0a 20 20 20 20 66 6f 72 28 70 50 61 67 65 3d 70  .    for(pPage=p
7f20: 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d  Cache->apHash[h]
7f30: 3b 20 70 50 61 67 65 26 26 70 50 61 67 65 2d 3e  ; pPage&&pPage->
7f40: 69 4b 65 79 21 3d 69 4b 65 79 3b 20 70 50 61 67  iKey!=iKey; pPag
7f50: 65 3d 70 50 61 67 65 2d 3e 70 4e 65 78 74 29 3b  e=pPage->pNext);
7f60: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53 74 65 70 20  .  }..  /* Step 
7f70: 32 3a 20 41 62 6f 72 74 20 69 66 20 6e 6f 20 65  2: Abort if no e
7f80: 78 69 73 74 69 6e 67 20 70 61 67 65 20 69 73 20  xisting page is 
7f90: 66 6f 75 6e 64 20 61 6e 64 20 63 72 65 61 74 65  found and create
7fa0: 46 6c 61 67 20 69 73 20 30 20 2a 2f 0a 20 20 69  Flag is 0 */.  i
7fb0: 66 28 20 70 50 61 67 65 20 7c 7c 20 63 72 65 61  f( pPage || crea
7fc0: 74 65 46 6c 61 67 3d 3d 30 20 29 7b 0a 20 20 20  teFlag==0 ){.   
7fd0: 20 70 63 61 63 68 65 31 50 69 6e 50 61 67 65 28   pcache1PinPage(
7fe0: 70 50 61 67 65 29 3b 0a 20 20 20 20 67 6f 74 6f  pPage);.    goto
7ff0: 20 66 65 74 63 68 5f 6f 75 74 3b 0a 20 20 7d 0a   fetch_out;.  }.
8000: 0a 20 20 2f 2a 20 54 68 65 20 70 47 72 6f 75 70  .  /* The pGroup
8010: 20 6c 6f 63 61 6c 20 76 61 72 69 61 62 6c 65 20   local variable 
8020: 77 69 6c 6c 20 6e 6f 72 6d 61 6c 6c 79 20 62 65  will normally be
8030: 20 69 6e 69 74 69 61 6c 69 7a 65 64 20 62 79 20   initialized by 
8040: 74 68 65 0a 20 20 2a 2a 20 70 63 61 63 68 65 31  the.  ** pcache1
8050: 45 6e 74 65 72 4d 75 74 65 78 28 29 20 6d 61 63  EnterMutex() mac
8060: 72 6f 20 61 62 6f 76 65 2e 20 20 42 75 74 20 69  ro above.  But i
8070: 66 20 53 51 4c 49 54 45 5f 4d 55 54 45 58 5f 4f  f SQLITE_MUTEX_O
8080: 4d 49 54 20 69 73 20 64 65 66 69 6e 65 64 2c 0a  MIT is defined,.
8090: 20 20 2a 2a 20 74 68 65 6e 20 70 63 61 63 68 65    ** then pcache
80a0: 31 45 6e 74 65 72 4d 75 74 65 78 28 29 20 69 73  1EnterMutex() is
80b0: 20 61 20 6e 6f 2d 6f 70 2c 20 73 6f 20 77 65 20   a no-op, so we 
80c0: 68 61 76 65 20 74 6f 20 69 6e 69 74 69 61 6c 69  have to initiali
80d0: 7a 65 20 74 68 65 0a 20 20 2a 2a 20 6c 6f 63 61  ze the.  ** loca
80e0: 6c 20 76 61 72 69 61 62 6c 65 20 68 65 72 65 2e  l variable here.
80f0: 20 20 44 65 6c 61 79 69 6e 67 20 74 68 65 20 69    Delaying the i
8100: 6e 69 74 69 61 6c 69 7a 61 74 69 6f 6e 20 6f 66  nitialization of
8110: 20 70 47 72 6f 75 70 20 69 73 20 61 6e 0a 20 20   pGroup is an.  
8120: 2a 2a 20 6f 70 74 69 6d 69 7a 61 74 69 6f 6e 3a  ** optimization:
8130: 20 20 54 68 65 20 63 6f 6d 6d 6f 6e 20 63 61 73    The common cas
8140: 65 20 69 73 20 74 6f 20 65 78 69 74 20 74 68 65  e is to exit the
8150: 20 6d 6f 64 75 6c 65 20 62 65 66 6f 72 65 20 72   module before r
8160: 65 61 63 68 69 6e 67 0a 20 20 2a 2a 20 74 68 69  eaching.  ** thi
8170: 73 20 70 6f 69 6e 74 2e 0a 20 20 2a 2f 0a 23 69  s point..  */.#i
8180: 66 64 65 66 20 53 51 4c 49 54 45 5f 4d 55 54 45  fdef SQLITE_MUTE
8190: 58 5f 4f 4d 49 54 0a 20 20 70 47 72 6f 75 70 20  X_OMIT.  pGroup 
81a0: 3d 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70  = pCache->pGroup
81b0: 3b 0a 23 65 6e 64 69 66 0a 0a 0a 20 20 2f 2a 20  ;.#endif...  /* 
81c0: 53 74 65 70 20 33 3a 20 41 62 6f 72 74 20 69 66  Step 3: Abort if
81d0: 20 63 72 65 61 74 65 46 6c 61 67 20 69 73 20 31   createFlag is 1
81e0: 20 62 75 74 20 74 68 65 20 63 61 63 68 65 20 69   but the cache i
81f0: 73 20 6e 65 61 72 6c 79 20 66 75 6c 6c 20 2a 2f  s nearly full */
8200: 0a 20 20 6e 50 69 6e 6e 65 64 20 3d 20 70 43 61  .  nPinned = pCa
8210: 63 68 65 2d 3e 6e 50 61 67 65 20 2d 20 70 43 61  che->nPage - pCa
8220: 63 68 65 2d 3e 6e 52 65 63 79 63 6c 61 62 6c 65  che->nRecyclable
8230: 3b 0a 20 20 61 73 73 65 72 74 28 20 6e 50 69 6e  ;.  assert( nPin
8240: 6e 65 64 3e 3d 30 20 29 3b 0a 20 20 61 73 73 65  ned>=0 );.  asse
8250: 72 74 28 20 70 47 72 6f 75 70 2d 3e 6d 78 50 69  rt( pGroup->mxPi
8260: 6e 6e 65 64 20 3d 3d 20 70 47 72 6f 75 70 2d 3e  nned == pGroup->
8270: 6e 4d 61 78 50 61 67 65 20 2b 20 31 30 20 2d 20  nMaxPage + 10 - 
8280: 70 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67 65  pGroup->nMinPage
8290: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 43   );.  assert( pC
82a0: 61 63 68 65 2d 3e 6e 39 30 70 63 74 20 3d 3d 20  ache->n90pct == 
82b0: 70 43 61 63 68 65 2d 3e 6e 4d 61 78 2a 39 2f 31  pCache->nMax*9/1
82c0: 30 20 29 3b 0a 20 20 69 66 28 20 63 72 65 61 74  0 );.  if( creat
82d0: 65 46 6c 61 67 3d 3d 31 20 26 26 20 28 0a 20 20  eFlag==1 && (.  
82e0: 20 20 20 20 20 20 6e 50 69 6e 6e 65 64 3e 3d 70        nPinned>=p
82f0: 47 72 6f 75 70 2d 3e 6d 78 50 69 6e 6e 65 64 0a  Group->mxPinned.
8300: 20 20 20 20 20 7c 7c 20 6e 50 69 6e 6e 65 64 3e       || nPinned>
8310: 3d 28 69 6e 74 29 70 43 61 63 68 65 2d 3e 6e 39  =(int)pCache->n9
8320: 30 70 63 74 0a 20 20 20 20 20 7c 7c 20 70 63 61  0pct.     || pca
8330: 63 68 65 31 55 6e 64 65 72 4d 65 6d 6f 72 79 50  che1UnderMemoryP
8340: 72 65 73 73 75 72 65 28 70 43 61 63 68 65 29 0a  ressure(pCache).
8350: 20 20 29 29 7b 0a 20 20 20 20 67 6f 74 6f 20 66    )){.    goto f
8360: 65 74 63 68 5f 6f 75 74 3b 0a 20 20 7d 0a 0a 20  etch_out;.  }.. 
8370: 20 69 66 28 20 70 43 61 63 68 65 2d 3e 6e 50 61   if( pCache->nPa
8380: 67 65 3e 3d 70 43 61 63 68 65 2d 3e 6e 48 61 73  ge>=pCache->nHas
8390: 68 20 26 26 20 70 63 61 63 68 65 31 52 65 73 69  h && pcache1Resi
83a0: 7a 65 48 61 73 68 28 70 43 61 63 68 65 29 20 29  zeHash(pCache) )
83b0: 7b 0a 20 20 20 20 67 6f 74 6f 20 66 65 74 63 68  {.    goto fetch
83c0: 5f 6f 75 74 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  _out;.  }..  /* 
83d0: 53 74 65 70 20 34 2e 20 54 72 79 20 74 6f 20 72  Step 4. Try to r
83e0: 65 63 79 63 6c 65 20 61 20 70 61 67 65 2e 20 2a  ecycle a page. *
83f0: 2f 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e  /.  if( pCache->
8400: 62 50 75 72 67 65 61 62 6c 65 20 26 26 20 70 47  bPurgeable && pG
8410: 72 6f 75 70 2d 3e 70 4c 72 75 54 61 69 6c 20 26  roup->pLruTail &
8420: 26 20 28 0a 20 20 20 20 20 20 20 20 20 28 70 43  & (.         (pC
8430: 61 63 68 65 2d 3e 6e 50 61 67 65 2b 31 3e 3d 70  ache->nPage+1>=p
8440: 43 61 63 68 65 2d 3e 6e 4d 61 78 29 0a 20 20 20  Cache->nMax).   
8450: 20 20 20 7c 7c 20 70 47 72 6f 75 70 2d 3e 6e 43     || pGroup->nC
8460: 75 72 72 65 6e 74 50 61 67 65 3e 3d 70 47 72 6f  urrentPage>=pGro
8470: 75 70 2d 3e 6e 4d 61 78 50 61 67 65 0a 20 20 20  up->nMaxPage.   
8480: 20 20 20 7c 7c 20 70 63 61 63 68 65 31 55 6e 64     || pcache1Und
8490: 65 72 4d 65 6d 6f 72 79 50 72 65 73 73 75 72 65  erMemoryPressure
84a0: 28 70 43 61 63 68 65 29 0a 20 20 29 29 7b 0a 20  (pCache).  )){. 
84b0: 20 20 20 50 43 61 63 68 65 31 20 2a 70 4f 74 68     PCache1 *pOth
84c0: 65 72 43 61 63 68 65 3b 0a 20 20 20 20 70 50 61  erCache;.    pPa
84d0: 67 65 20 3d 20 70 47 72 6f 75 70 2d 3e 70 4c 72  ge = pGroup->pLr
84e0: 75 54 61 69 6c 3b 0a 20 20 20 20 70 63 61 63 68  uTail;.    pcach
84f0: 65 31 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73 68  e1RemoveFromHash
8500: 28 70 50 61 67 65 29 3b 0a 20 20 20 20 70 63 61  (pPage);.    pca
8510: 63 68 65 31 50 69 6e 50 61 67 65 28 70 50 61 67  che1PinPage(pPag
8520: 65 29 3b 0a 20 20 20 20 69 66 28 20 28 70 4f 74  e);.    if( (pOt
8530: 68 65 72 43 61 63 68 65 20 3d 20 70 50 61 67 65  herCache = pPage
8540: 2d 3e 70 43 61 63 68 65 29 2d 3e 73 7a 50 61 67  ->pCache)->szPag
8550: 65 21 3d 70 43 61 63 68 65 2d 3e 73 7a 50 61 67  e!=pCache->szPag
8560: 65 20 29 7b 0a 20 20 20 20 20 20 70 63 61 63 68  e ){.      pcach
8570: 65 31 46 72 65 65 50 61 67 65 28 70 50 61 67 65  e1FreePage(pPage
8580: 29 3b 0a 20 20 20 20 20 20 70 50 61 67 65 20 3d  );.      pPage =
8590: 20 30 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20   0;.    }else{. 
85a0: 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 6e 43 75       pGroup->nCu
85b0: 72 72 65 6e 74 50 61 67 65 20 2d 3d 20 0a 20 20  rrentPage -= .  
85c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 28 70 4f               (pO
85d0: 74 68 65 72 43 61 63 68 65 2d 3e 62 50 75 72 67  therCache->bPurg
85e0: 65 61 62 6c 65 20 2d 20 70 43 61 63 68 65 2d 3e  eable - pCache->
85f0: 62 50 75 72 67 65 61 62 6c 65 29 3b 0a 20 20 20  bPurgeable);.   
8600: 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53 74 65   }.  }..  /* Ste
8610: 70 20 35 2e 20 49 66 20 61 20 75 73 61 62 6c 65  p 5. If a usable
8620: 20 70 61 67 65 20 62 75 66 66 65 72 20 68 61 73   page buffer has
8630: 20 73 74 69 6c 6c 20 6e 6f 74 20 62 65 65 6e 20   still not been 
8640: 66 6f 75 6e 64 2c 20 0a 20 20 2a 2a 20 61 74 74  found, .  ** att
8650: 65 6d 70 74 20 74 6f 20 61 6c 6c 6f 63 61 74 65  empt to allocate
8660: 20 61 20 6e 65 77 20 6f 6e 65 2e 20 0a 20 20 2a   a new one. .  *
8670: 2f 0a 20 20 69 66 28 20 21 70 50 61 67 65 20 29  /.  if( !pPage )
8680: 7b 0a 20 20 20 20 69 66 28 20 63 72 65 61 74 65  {.    if( create
8690: 46 6c 61 67 3d 3d 31 20 29 20 73 71 6c 69 74 65  Flag==1 ) sqlite
86a0: 33 42 65 67 69 6e 42 65 6e 69 67 6e 4d 61 6c 6c  3BeginBenignMall
86b0: 6f 63 28 29 3b 0a 20 20 20 20 70 50 61 67 65 20  oc();.    pPage 
86c0: 3d 20 70 63 61 63 68 65 31 41 6c 6c 6f 63 50 61  = pcache1AllocPa
86d0: 67 65 28 70 43 61 63 68 65 29 3b 0a 20 20 20 20  ge(pCache);.    
86e0: 69 66 28 20 63 72 65 61 74 65 46 6c 61 67 3d 3d  if( createFlag==
86f0: 31 20 29 20 73 71 6c 69 74 65 33 45 6e 64 42 65  1 ) sqlite3EndBe
8700: 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 0a 20 20  nignMalloc();.  
8710: 7d 0a 0a 20 20 69 66 28 20 70 50 61 67 65 20 29  }..  if( pPage )
8720: 7b 0a 20 20 20 20 75 6e 73 69 67 6e 65 64 20 69  {.    unsigned i
8730: 6e 74 20 68 20 3d 20 69 4b 65 79 20 25 20 70 43  nt h = iKey % pC
8740: 61 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 20  ache->nHash;.   
8750: 20 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 2b 2b   pCache->nPage++
8760: 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 69 4b 65  ;.    pPage->iKe
8770: 79 20 3d 20 69 4b 65 79 3b 0a 20 20 20 20 70 50  y = iKey;.    pP
8780: 61 67 65 2d 3e 70 4e 65 78 74 20 3d 20 70 43 61  age->pNext = pCa
8790: 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 0a  che->apHash[h];.
87a0: 20 20 20 20 70 50 61 67 65 2d 3e 70 43 61 63 68      pPage->pCach
87b0: 65 20 3d 20 70 43 61 63 68 65 3b 0a 20 20 20 20  e = pCache;.    
87c0: 70 50 61 67 65 2d 3e 70 4c 72 75 50 72 65 76 20  pPage->pLruPrev 
87d0: 3d 20 30 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e  = 0;.    pPage->
87e0: 70 4c 72 75 4e 65 78 74 20 3d 20 30 3b 0a 20 20  pLruNext = 0;.  
87f0: 20 20 2a 28 76 6f 69 64 20 2a 2a 29 28 50 47 48    *(void **)(PGH
8800: 44 52 31 5f 54 4f 5f 50 41 47 45 28 70 50 61 67  DR1_TO_PAGE(pPag
8810: 65 29 29 20 3d 20 30 3b 0a 20 20 20 20 70 43 61  e)) = 0;.    pCa
8820: 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 20 3d  che->apHash[h] =
8830: 20 70 50 61 67 65 3b 0a 20 20 7d 0a 0a 66 65 74   pPage;.  }..fet
8840: 63 68 5f 6f 75 74 3a 0a 20 20 69 66 28 20 70 50  ch_out:.  if( pP
8850: 61 67 65 20 26 26 20 69 4b 65 79 3e 70 43 61 63  age && iKey>pCac
8860: 68 65 2d 3e 69 4d 61 78 4b 65 79 20 29 7b 0a 20  he->iMaxKey ){. 
8870: 20 20 20 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b     pCache->iMaxK
8880: 65 79 20 3d 20 69 4b 65 79 3b 0a 20 20 7d 0a 20  ey = iKey;.  }. 
8890: 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74   pcache1LeaveMut
88a0: 65 78 28 70 47 72 6f 75 70 29 3b 0a 20 20 72 65  ex(pGroup);.  re
88b0: 74 75 72 6e 20 28 70 50 61 67 65 20 3f 20 50 47  turn (pPage ? PG
88c0: 48 44 52 31 5f 54 4f 5f 50 41 47 45 28 70 50 61  HDR1_TO_PAGE(pPa
88d0: 67 65 29 20 3a 20 30 29 3b 0a 7d 0a 0a 0a 2f 2a  ge) : 0);.}.../*
88e0: 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69  .** Implementati
88f0: 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65  on of the sqlite
8900: 33 5f 70 63 61 63 68 65 2e 78 55 6e 70 69 6e 20  3_pcache.xUnpin 
8910: 6d 65 74 68 6f 64 2e 0a 2a 2a 0a 2a 2a 20 4d 61  method..**.** Ma
8920: 72 6b 20 61 20 70 61 67 65 20 61 73 20 75 6e 70  rk a page as unp
8930: 69 6e 6e 65 64 20 28 65 6c 69 67 69 62 6c 65 20  inned (eligible 
8940: 66 6f 72 20 61 73 79 6e 63 68 72 6f 6e 6f 75 73  for asynchronous
8950: 20 72 65 63 79 63 6c 69 6e 67 29 2e 0a 2a 2f 0a   recycling)..*/.
8960: 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63  static void pcac
8970: 68 65 31 55 6e 70 69 6e 28 73 71 6c 69 74 65 33  he1Unpin(sqlite3
8980: 5f 70 63 61 63 68 65 20 2a 70 2c 20 76 6f 69 64  _pcache *p, void
8990: 20 2a 70 50 67 2c 20 69 6e 74 20 72 65 75 73 65   *pPg, int reuse
89a0: 55 6e 6c 69 6b 65 6c 79 29 7b 0a 20 20 50 43 61  Unlikely){.  PCa
89b0: 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28  che1 *pCache = (
89c0: 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20 20 50  PCache1 *)p;.  P
89d0: 67 48 64 72 31 20 2a 70 50 61 67 65 20 3d 20 50  gHdr1 *pPage = P
89e0: 41 47 45 5f 54 4f 5f 50 47 48 44 52 31 28 70 43  AGE_TO_PGHDR1(pC
89f0: 61 63 68 65 2c 20 70 50 67 29 3b 0a 20 20 50 47  ache, pPg);.  PG
8a00: 72 6f 75 70 20 2a 70 47 72 6f 75 70 20 3d 20 70  roup *pGroup = p
8a10: 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b 0a 20  Cache->pGroup;. 
8a20: 0a 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65  .  assert( pPage
8a30: 2d 3e 70 43 61 63 68 65 3d 3d 70 43 61 63 68 65  ->pCache==pCache
8a40: 20 29 3b 0a 20 20 70 63 61 63 68 65 31 45 6e 74   );.  pcache1Ent
8a50: 65 72 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b  erMutex(pGroup);
8a60: 0a 0a 20 20 2f 2a 20 49 74 20 69 73 20 61 6e 20  ..  /* It is an 
8a70: 65 72 72 6f 72 20 74 6f 20 63 61 6c 6c 20 74 68  error to call th
8a80: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 66 20 74  is function if t
8a90: 68 65 20 70 61 67 65 20 69 73 20 61 6c 72 65 61  he page is alrea
8aa0: 64 79 20 0a 20 20 2a 2a 20 70 61 72 74 20 6f 66  dy .  ** part of
8ab0: 20 74 68 65 20 50 47 72 6f 75 70 20 4c 52 55 20   the PGroup LRU 
8ac0: 6c 69 73 74 2e 0a 20 20 2a 2f 0a 20 20 61 73 73  list..  */.  ass
8ad0: 65 72 74 28 20 70 50 61 67 65 2d 3e 70 4c 72 75  ert( pPage->pLru
8ae0: 50 72 65 76 3d 3d 30 20 26 26 20 70 50 61 67 65  Prev==0 && pPage
8af0: 2d 3e 70 4c 72 75 4e 65 78 74 3d 3d 30 20 29 3b  ->pLruNext==0 );
8b00: 0a 20 20 61 73 73 65 72 74 28 20 70 47 72 6f 75  .  assert( pGrou
8b10: 70 2d 3e 70 4c 72 75 48 65 61 64 21 3d 70 50 61  p->pLruHead!=pPa
8b20: 67 65 20 26 26 20 70 47 72 6f 75 70 2d 3e 70 4c  ge && pGroup->pL
8b30: 72 75 54 61 69 6c 21 3d 70 50 61 67 65 20 29 3b  ruTail!=pPage );
8b40: 0a 0a 20 20 69 66 28 20 72 65 75 73 65 55 6e 6c  ..  if( reuseUnl
8b50: 69 6b 65 6c 79 20 7c 7c 20 70 47 72 6f 75 70 2d  ikely || pGroup-
8b60: 3e 6e 43 75 72 72 65 6e 74 50 61 67 65 3e 70 47  >nCurrentPage>pG
8b70: 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65 20 29  roup->nMaxPage )
8b80: 7b 0a 20 20 20 20 70 63 61 63 68 65 31 52 65 6d  {.    pcache1Rem
8b90: 6f 76 65 46 72 6f 6d 48 61 73 68 28 70 50 61 67  oveFromHash(pPag
8ba0: 65 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31 46  e);.    pcache1F
8bb0: 72 65 65 50 61 67 65 28 70 50 61 67 65 29 3b 0a  reePage(pPage);.
8bc0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 2f 2a 20    }else{.    /* 
8bd0: 41 64 64 20 74 68 65 20 70 61 67 65 20 74 6f 20  Add the page to 
8be0: 74 68 65 20 50 47 72 6f 75 70 20 4c 52 55 20 6c  the PGroup LRU l
8bf0: 69 73 74 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20  ist. */.    if( 
8c00: 70 47 72 6f 75 70 2d 3e 70 4c 72 75 48 65 61 64  pGroup->pLruHead
8c10: 20 29 7b 0a 20 20 20 20 20 20 70 47 72 6f 75 70   ){.      pGroup
8c20: 2d 3e 70 4c 72 75 48 65 61 64 2d 3e 70 4c 72 75  ->pLruHead->pLru
8c30: 50 72 65 76 20 3d 20 70 50 61 67 65 3b 0a 20 20  Prev = pPage;.  
8c40: 20 20 20 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e      pPage->pLruN
8c50: 65 78 74 20 3d 20 70 47 72 6f 75 70 2d 3e 70 4c  ext = pGroup->pL
8c60: 72 75 48 65 61 64 3b 0a 20 20 20 20 20 20 70 47  ruHead;.      pG
8c70: 72 6f 75 70 2d 3e 70 4c 72 75 48 65 61 64 20 3d  roup->pLruHead =
8c80: 20 70 50 61 67 65 3b 0a 20 20 20 20 7d 65 6c 73   pPage;.    }els
8c90: 65 7b 0a 20 20 20 20 20 20 70 47 72 6f 75 70 2d  e{.      pGroup-
8ca0: 3e 70 4c 72 75 54 61 69 6c 20 3d 20 70 50 61 67  >pLruTail = pPag
8cb0: 65 3b 0a 20 20 20 20 20 20 70 47 72 6f 75 70 2d  e;.      pGroup-
8cc0: 3e 70 4c 72 75 48 65 61 64 20 3d 20 70 50 61 67  >pLruHead = pPag
8cd0: 65 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 43 61  e;.    }.    pCa
8ce0: 63 68 65 2d 3e 6e 52 65 63 79 63 6c 61 62 6c 65  che->nRecyclable
8cf0: 2b 2b 3b 0a 20 20 7d 0a 0a 20 20 70 63 61 63 68  ++;.  }..  pcach
8d00: 65 31 4c 65 61 76 65 4d 75 74 65 78 28 70 43 61  e1LeaveMutex(pCa
8d10: 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 7d 0a  che->pGroup);.}.
8d20: 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74  ./*.** Implement
8d30: 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c  ation of the sql
8d40: 69 74 65 33 5f 70 63 61 63 68 65 2e 78 52 65 6b  ite3_pcache.xRek
8d50: 65 79 20 6d 65 74 68 6f 64 2e 20 0a 2a 2f 0a 73  ey method. .*/.s
8d60: 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68  tatic void pcach
8d70: 65 31 52 65 6b 65 79 28 0a 20 20 73 71 6c 69 74  e1Rekey(.  sqlit
8d80: 65 33 5f 70 63 61 63 68 65 20 2a 70 2c 0a 20 20  e3_pcache *p,.  
8d90: 76 6f 69 64 20 2a 70 50 67 2c 0a 20 20 75 6e 73  void *pPg,.  uns
8da0: 69 67 6e 65 64 20 69 6e 74 20 69 4f 6c 64 2c 0a  igned int iOld,.
8db0: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69    unsigned int i
8dc0: 4e 65 77 0a 29 7b 0a 20 20 50 43 61 63 68 65 31  New.){.  PCache1
8dd0: 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61 63   *pCache = (PCac
8de0: 68 65 31 20 2a 29 70 3b 0a 20 20 50 67 48 64 72  he1 *)p;.  PgHdr
8df0: 31 20 2a 70 50 61 67 65 20 3d 20 50 41 47 45 5f  1 *pPage = PAGE_
8e00: 54 4f 5f 50 47 48 44 52 31 28 70 43 61 63 68 65  TO_PGHDR1(pCache
8e10: 2c 20 70 50 67 29 3b 0a 20 20 50 67 48 64 72 31  , pPg);.  PgHdr1
8e20: 20 2a 2a 70 70 3b 0a 20 20 75 6e 73 69 67 6e 65   **pp;.  unsigne
8e30: 64 20 69 6e 74 20 68 3b 20 0a 20 20 61 73 73 65  d int h; .  asse
8e40: 72 74 28 20 70 50 61 67 65 2d 3e 69 4b 65 79 3d  rt( pPage->iKey=
8e50: 3d 69 4f 6c 64 20 29 3b 0a 20 20 61 73 73 65 72  =iOld );.  asser
8e60: 74 28 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65  t( pPage->pCache
8e70: 3d 3d 70 43 61 63 68 65 20 29 3b 0a 0a 20 20 70  ==pCache );..  p
8e80: 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78  cache1EnterMutex
8e90: 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 29  (pCache->pGroup)
8ea0: 3b 0a 0a 20 20 68 20 3d 20 69 4f 6c 64 25 70 43  ;..  h = iOld%pC
8eb0: 61 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 70  ache->nHash;.  p
8ec0: 70 20 3d 20 26 70 43 61 63 68 65 2d 3e 61 70 48  p = &pCache->apH
8ed0: 61 73 68 5b 68 5d 3b 0a 20 20 77 68 69 6c 65 28  ash[h];.  while(
8ee0: 20 28 2a 70 70 29 21 3d 70 50 61 67 65 20 29 7b   (*pp)!=pPage ){
8ef0: 0a 20 20 20 20 70 70 20 3d 20 26 28 2a 70 70 29  .    pp = &(*pp)
8f00: 2d 3e 70 4e 65 78 74 3b 0a 20 20 7d 0a 20 20 2a  ->pNext;.  }.  *
8f10: 70 70 20 3d 20 70 50 61 67 65 2d 3e 70 4e 65 78  pp = pPage->pNex
8f20: 74 3b 0a 0a 20 20 68 20 3d 20 69 4e 65 77 25 70  t;..  h = iNew%p
8f30: 43 61 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20  Cache->nHash;.  
8f40: 70 50 61 67 65 2d 3e 69 4b 65 79 20 3d 20 69 4e  pPage->iKey = iN
8f50: 65 77 3b 0a 20 20 70 50 61 67 65 2d 3e 70 4e 65  ew;.  pPage->pNe
8f60: 78 74 20 3d 20 70 43 61 63 68 65 2d 3e 61 70 48  xt = pCache->apH
8f70: 61 73 68 5b 68 5d 3b 0a 20 20 70 43 61 63 68 65  ash[h];.  pCache
8f80: 2d 3e 61 70 48 61 73 68 5b 68 5d 20 3d 20 70 50  ->apHash[h] = pP
8f90: 61 67 65 3b 0a 20 20 69 66 28 20 69 4e 65 77 3e  age;.  if( iNew>
8fa0: 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20  pCache->iMaxKey 
8fb0: 29 7b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 69  ){.    pCache->i
8fc0: 4d 61 78 4b 65 79 20 3d 20 69 4e 65 77 3b 0a 20  MaxKey = iNew;. 
8fd0: 20 7d 0a 0a 20 20 70 63 61 63 68 65 31 4c 65 61   }..  pcache1Lea
8fe0: 76 65 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e  veMutex(pCache->
8ff0: 70 47 72 6f 75 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  pGroup);.}../*.*
9000: 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  * Implementation
9010: 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f   of the sqlite3_
9020: 70 63 61 63 68 65 2e 78 54 72 75 6e 63 61 74 65  pcache.xTruncate
9030: 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20   method. .**.** 
9040: 44 69 73 63 61 72 64 20 61 6c 6c 20 75 6e 70 69  Discard all unpi
9050: 6e 6e 65 64 20 70 61 67 65 73 20 69 6e 20 74 68  nned pages in th
9060: 65 20 63 61 63 68 65 20 77 69 74 68 20 61 20 70  e cache with a p
9070: 61 67 65 20 6e 75 6d 62 65 72 20 65 71 75 61 6c  age number equal
9080: 20 74 6f 0a 2a 2a 20 6f 72 20 67 72 65 61 74 65   to.** or greate
9090: 72 20 74 68 61 6e 20 70 61 72 61 6d 65 74 65 72  r than parameter
90a0: 20 69 4c 69 6d 69 74 2e 20 41 6e 79 20 70 69 6e   iLimit. Any pin
90b0: 6e 65 64 20 70 61 67 65 73 20 77 69 74 68 20 61  ned pages with a
90c0: 20 70 61 67 65 20 6e 75 6d 62 65 72 0a 2a 2a 20   page number.** 
90d0: 65 71 75 61 6c 20 74 6f 20 6f 72 20 67 72 65 61  equal to or grea
90e0: 74 65 72 20 74 68 61 6e 20 69 4c 69 6d 69 74 20  ter than iLimit 
90f0: 61 72 65 20 69 6d 70 6c 69 63 69 74 6c 79 20 75  are implicitly u
9100: 6e 70 69 6e 6e 65 64 2e 0a 2a 2f 0a 73 74 61 74  npinned..*/.stat
9110: 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 31 54  ic void pcache1T
9120: 72 75 6e 63 61 74 65 28 73 71 6c 69 74 65 33 5f  runcate(sqlite3_
9130: 70 63 61 63 68 65 20 2a 70 2c 20 75 6e 73 69 67  pcache *p, unsig
9140: 6e 65 64 20 69 6e 74 20 69 4c 69 6d 69 74 29 7b  ned int iLimit){
9150: 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63  .  PCache1 *pCac
9160: 68 65 20 3d 20 28 50 43 61 63 68 65 31 20 2a 29  he = (PCache1 *)
9170: 70 3b 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65  p;.  pcache1Ente
9180: 72 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e 70  rMutex(pCache->p
9190: 47 72 6f 75 70 29 3b 0a 20 20 69 66 28 20 69 4c  Group);.  if( iL
91a0: 69 6d 69 74 3c 3d 70 43 61 63 68 65 2d 3e 69 4d  imit<=pCache->iM
91b0: 61 78 4b 65 79 20 29 7b 0a 20 20 20 20 70 63 61  axKey ){.    pca
91c0: 63 68 65 31 54 72 75 6e 63 61 74 65 55 6e 73 61  che1TruncateUnsa
91d0: 66 65 28 70 43 61 63 68 65 2c 20 69 4c 69 6d 69  fe(pCache, iLimi
91e0: 74 29 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e  t);.    pCache->
91f0: 69 4d 61 78 4b 65 79 20 3d 20 69 4c 69 6d 69 74  iMaxKey = iLimit
9200: 2d 31 3b 0a 20 20 7d 0a 20 20 70 63 61 63 68 65  -1;.  }.  pcache
9210: 31 4c 65 61 76 65 4d 75 74 65 78 28 70 43 61 63  1LeaveMutex(pCac
9220: 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 7d 0a 0a  he->pGroup);.}..
9230: 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61  /*.** Implementa
9240: 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69  tion of the sqli
9250: 74 65 33 5f 70 63 61 63 68 65 2e 78 44 65 73 74  te3_pcache.xDest
9260: 72 6f 79 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a  roy method. .**.
9270: 2a 2a 20 44 65 73 74 72 6f 79 20 61 20 63 61 63  ** Destroy a cac
9280: 68 65 20 61 6c 6c 6f 63 61 74 65 64 20 75 73 69  he allocated usi
9290: 6e 67 20 70 63 61 63 68 65 31 43 72 65 61 74 65  ng pcache1Create
92a0: 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ()..*/.static vo
92b0: 69 64 20 70 63 61 63 68 65 31 44 65 73 74 72 6f  id pcache1Destro
92c0: 79 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  y(sqlite3_pcache
92d0: 20 2a 70 29 7b 0a 20 20 50 43 61 63 68 65 31 20   *p){.  PCache1 
92e0: 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61 63 68  *pCache = (PCach
92f0: 65 31 20 2a 29 70 3b 0a 20 20 50 47 72 6f 75 70  e1 *)p;.  PGroup
9300: 20 2a 70 47 72 6f 75 70 20 3d 20 70 43 61 63 68   *pGroup = pCach
9310: 65 2d 3e 70 47 72 6f 75 70 3b 0a 20 20 61 73 73  e->pGroup;.  ass
9320: 65 72 74 28 20 70 43 61 63 68 65 2d 3e 62 50 75  ert( pCache->bPu
9330: 72 67 65 61 62 6c 65 20 7c 7c 20 28 70 43 61 63  rgeable || (pCac
9340: 68 65 2d 3e 6e 4d 61 78 3d 3d 30 20 26 26 20 70  he->nMax==0 && p
9350: 43 61 63 68 65 2d 3e 6e 4d 69 6e 3d 3d 30 29 20  Cache->nMin==0) 
9360: 29 3b 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65  );.  pcache1Ente
9370: 72 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b 0a  rMutex(pGroup);.
9380: 20 20 70 63 61 63 68 65 31 54 72 75 6e 63 61 74    pcache1Truncat
9390: 65 55 6e 73 61 66 65 28 70 43 61 63 68 65 2c 20  eUnsafe(pCache, 
93a0: 30 29 3b 0a 20 20 70 47 72 6f 75 70 2d 3e 6e 4d  0);.  pGroup->nM
93b0: 61 78 50 61 67 65 20 2d 3d 20 70 43 61 63 68 65  axPage -= pCache
93c0: 2d 3e 6e 4d 61 78 3b 0a 20 20 70 47 72 6f 75 70  ->nMax;.  pGroup
93d0: 2d 3e 6e 4d 69 6e 50 61 67 65 20 2d 3d 20 70 43  ->nMinPage -= pC
93e0: 61 63 68 65 2d 3e 6e 4d 69 6e 3b 0a 20 20 70 47  ache->nMin;.  pG
93f0: 72 6f 75 70 2d 3e 6d 78 50 69 6e 6e 65 64 20 3d  roup->mxPinned =
9400: 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67   pGroup->nMaxPag
9410: 65 20 2b 20 31 30 20 2d 20 70 47 72 6f 75 70 2d  e + 10 - pGroup-
9420: 3e 6e 4d 69 6e 50 61 67 65 3b 0a 20 20 70 63 61  >nMinPage;.  pca
9430: 63 68 65 31 45 6e 66 6f 72 63 65 4d 61 78 50 61  che1EnforceMaxPa
9440: 67 65 28 70 47 72 6f 75 70 29 3b 0a 20 20 70 63  ge(pGroup);.  pc
9450: 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28  ache1LeaveMutex(
9460: 70 47 72 6f 75 70 29 3b 0a 20 20 73 71 6c 69 74  pGroup);.  sqlit
9470: 65 33 5f 66 72 65 65 28 70 43 61 63 68 65 2d 3e  e3_free(pCache->
9480: 61 70 48 61 73 68 29 3b 0a 20 20 73 71 6c 69 74  apHash);.  sqlit
9490: 65 33 5f 66 72 65 65 28 70 43 61 63 68 65 29 3b  e3_free(pCache);
94a0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66  .}../*.** This f
94b0: 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65  unction is calle
94c0: 64 20 64 75 72 69 6e 67 20 69 6e 69 74 69 61 6c  d during initial
94d0: 69 7a 61 74 69 6f 6e 20 28 73 71 6c 69 74 65 33  ization (sqlite3
94e0: 5f 69 6e 69 74 69 61 6c 69 7a 65 28 29 29 20 74  _initialize()) t
94f0: 6f 0a 2a 2a 20 69 6e 73 74 61 6c 6c 20 74 68 65  o.** install the
9500: 20 64 65 66 61 75 6c 74 20 70 6c 75 67 67 61 62   default pluggab
9510: 6c 65 20 63 61 63 68 65 20 6d 6f 64 75 6c 65 2c  le cache module,
9520: 20 61 73 73 75 6d 69 6e 67 20 74 68 65 20 75 73   assuming the us
9530: 65 72 20 68 61 73 20 6e 6f 74 0a 2a 2a 20 61 6c  er has not.** al
9540: 72 65 61 64 79 20 70 72 6f 76 69 64 65 64 20 61  ready provided a
9550: 6e 20 61 6c 74 65 72 6e 61 74 69 76 65 2e 0a 2a  n alternative..*
9560: 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 43  /.void sqlite3PC
9570: 61 63 68 65 53 65 74 44 65 66 61 75 6c 74 28 76  acheSetDefault(v
9580: 6f 69 64 29 7b 0a 20 20 73 74 61 74 69 63 20 63  oid){.  static c
9590: 6f 6e 73 74 20 73 71 6c 69 74 65 33 5f 70 63 61  onst sqlite3_pca
95a0: 63 68 65 5f 6d 65 74 68 6f 64 73 20 64 65 66 61  che_methods defa
95b0: 75 6c 74 4d 65 74 68 6f 64 73 20 3d 20 7b 0a 20  ultMethods = {. 
95c0: 20 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20     0,           
95d0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 70              /* p
95e0: 41 72 67 20 2a 2f 0a 20 20 20 20 70 63 61 63 68  Arg */.    pcach
95f0: 65 31 49 6e 69 74 2c 20 20 20 20 20 20 20 20 20  e1Init,         
9600: 20 20 20 20 2f 2a 20 78 49 6e 69 74 20 2a 2f 0a      /* xInit */.
9610: 20 20 20 20 70 63 61 63 68 65 31 53 68 75 74 64      pcache1Shutd
9620: 6f 77 6e 2c 20 20 20 20 20 20 20 20 20 2f 2a 20  own,         /* 
9630: 78 53 68 75 74 64 6f 77 6e 20 2a 2f 0a 20 20 20  xShutdown */.   
9640: 20 70 63 61 63 68 65 31 43 72 65 61 74 65 2c 20   pcache1Create, 
9650: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43 72            /* xCr
9660: 65 61 74 65 20 2a 2f 0a 20 20 20 20 70 63 61 63  eate */.    pcac
9670: 68 65 31 43 61 63 68 65 73 69 7a 65 2c 20 20 20  he1Cachesize,   
9680: 20 20 20 20 20 2f 2a 20 78 43 61 63 68 65 73 69       /* xCachesi
9690: 7a 65 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65  ze */.    pcache
96a0: 31 50 61 67 65 63 6f 75 6e 74 2c 20 20 20 20 20  1Pagecount,     
96b0: 20 20 20 2f 2a 20 78 50 61 67 65 63 6f 75 6e 74     /* xPagecount
96c0: 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31 46   */.    pcache1F
96d0: 65 74 63 68 2c 20 20 20 20 20 20 20 20 20 20 20  etch,           
96e0: 20 2f 2a 20 78 46 65 74 63 68 20 2a 2f 0a 20 20   /* xFetch */.  
96f0: 20 20 70 63 61 63 68 65 31 55 6e 70 69 6e 2c 20    pcache1Unpin, 
9700: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 55             /* xU
9710: 6e 70 69 6e 20 2a 2f 0a 20 20 20 20 70 63 61 63  npin */.    pcac
9720: 68 65 31 52 65 6b 65 79 2c 20 20 20 20 20 20 20  he1Rekey,       
9730: 20 20 20 20 20 2f 2a 20 78 52 65 6b 65 79 20 2a       /* xRekey *
9740: 2f 0a 20 20 20 20 70 63 61 63 68 65 31 54 72 75  /.    pcache1Tru
9750: 6e 63 61 74 65 2c 20 20 20 20 20 20 20 20 20 2f  ncate,         /
9760: 2a 20 78 54 72 75 6e 63 61 74 65 20 2a 2f 0a 20  * xTruncate */. 
9770: 20 20 20 70 63 61 63 68 65 31 44 65 73 74 72 6f     pcache1Destro
9780: 79 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78  y           /* x
9790: 44 65 73 74 72 6f 79 20 2a 2f 0a 20 20 7d 3b 0a  Destroy */.  };.
97a0: 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67    sqlite3_config
97b0: 28 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50  (SQLITE_CONFIG_P
97c0: 43 41 43 48 45 2c 20 26 64 65 66 61 75 6c 74 4d  CACHE, &defaultM
97d0: 65 74 68 6f 64 73 29 3b 0a 7d 0a 0a 23 69 66 64  ethods);.}..#ifd
97e0: 65 66 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45  ef SQLITE_ENABLE
97f0: 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45  _MEMORY_MANAGEME
9800: 4e 54 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75  NT./*.** This fu
9810: 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64  nction is called
9820: 20 74 6f 20 66 72 65 65 20 73 75 70 65 72 66 6c   to free superfl
9830: 75 6f 75 73 20 64 79 6e 61 6d 69 63 61 6c 6c 79  uous dynamically
9840: 20 61 6c 6c 6f 63 61 74 65 64 20 6d 65 6d 6f 72   allocated memor
9850: 79 0a 2a 2a 20 68 65 6c 64 20 62 79 20 74 68 65  y.** held by the
9860: 20 70 61 67 65 72 20 73 79 73 74 65 6d 2e 20 4d   pager system. M
9870: 65 6d 6f 72 79 20 69 6e 20 75 73 65 20 62 79 20  emory in use by 
9880: 61 6e 79 20 53 51 4c 69 74 65 20 70 61 67 65 72  any SQLite pager
9890: 20 61 6c 6c 6f 63 61 74 65 64 0a 2a 2a 20 62 79   allocated.** by
98a0: 20 74 68 65 20 63 75 72 72 65 6e 74 20 74 68 72   the current thr
98b0: 65 61 64 20 6d 61 79 20 62 65 20 73 71 6c 69 74  ead may be sqlit
98c0: 65 33 5f 66 72 65 65 28 29 65 64 2e 0a 2a 2a 0a  e3_free()ed..**.
98d0: 2a 2a 20 6e 52 65 71 20 69 73 20 74 68 65 20 6e  ** nReq is the n
98e0: 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 6f  umber of bytes o
98f0: 66 20 6d 65 6d 6f 72 79 20 72 65 71 75 69 72 65  f memory require
9900: 64 2e 20 4f 6e 63 65 20 74 68 69 73 20 6d 75 63  d. Once this muc
9910: 68 20 68 61 73 0a 2a 2a 20 62 65 65 6e 20 72 65  h has.** been re
9920: 6c 65 61 73 65 64 2c 20 74 68 65 20 66 75 6e 63  leased, the func
9930: 74 69 6f 6e 20 72 65 74 75 72 6e 73 2e 20 54 68  tion returns. Th
9940: 65 20 72 65 74 75 72 6e 20 76 61 6c 75 65 20 69  e return value i
9950: 73 20 74 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62  s the total numb
9960: 65 72 20 0a 2a 2a 20 6f 66 20 62 79 74 65 73 20  er .** of bytes 
9970: 6f 66 20 6d 65 6d 6f 72 79 20 72 65 6c 65 61 73  of memory releas
9980: 65 64 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  ed..*/.int sqlit
9990: 65 33 50 63 61 63 68 65 52 65 6c 65 61 73 65 4d  e3PcacheReleaseM
99a0: 65 6d 6f 72 79 28 69 6e 74 20 6e 52 65 71 29 7b  emory(int nReq){
99b0: 0a 20 20 69 6e 74 20 6e 46 72 65 65 20 3d 20 30  .  int nFree = 0
99c0: 3b 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f  ;.#ifdef SQLITE_
99d0: 50 41 47 45 43 41 43 48 45 5f 42 4c 4f 43 4b 41  PAGECACHE_BLOCKA
99e0: 4c 4c 4f 43 0a 20 20 69 66 28 20 70 63 61 63 68  LLOC.  if( pcach
99f0: 65 31 2e 67 72 70 2e 69 73 42 75 73 79 20 29 20  e1.grp.isBusy ) 
9a00: 72 65 74 75 72 6e 20 30 3b 0a 23 65 6e 64 69 66  return 0;.#endif
9a10: 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74  .  assert( sqlit
9a20: 65 33 5f 6d 75 74 65 78 5f 6e 6f 74 68 65 6c 64  e3_mutex_notheld
9a30: 28 70 63 61 63 68 65 31 2e 67 72 70 2e 6d 75 74  (pcache1.grp.mut
9a40: 65 78 29 20 29 3b 0a 20 20 61 73 73 65 72 74 28  ex) );.  assert(
9a50: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6e   sqlite3_mutex_n
9a60: 6f 74 68 65 6c 64 28 70 63 61 63 68 65 31 2e 6d  otheld(pcache1.m
9a70: 75 74 65 78 29 20 29 3b 0a 20 20 69 66 28 20 70  utex) );.  if( p
9a80: 63 61 63 68 65 31 2e 70 53 74 61 72 74 3d 3d 30  cache1.pStart==0
9a90: 20 29 7b 0a 20 20 20 20 50 67 48 64 72 31 20 2a   ){.    PgHdr1 *
9aa0: 70 3b 0a 20 20 20 20 70 63 61 63 68 65 31 45 6e  p;.    pcache1En
9ab0: 74 65 72 4d 75 74 65 78 28 26 70 63 61 63 68 65  terMutex(&pcache
9ac0: 31 2e 67 72 70 29 3b 0a 20 20 20 20 77 68 69 6c  1.grp);.    whil
9ad0: 65 28 20 28 6e 52 65 71 3c 30 20 7c 7c 20 6e 46  e( (nReq<0 || nF
9ae0: 72 65 65 3c 6e 52 65 71 29 20 26 26 20 28 28 70  ree<nReq) && ((p
9af0: 3d 70 63 61 63 68 65 31 2e 67 72 70 2e 70 4c 72  =pcache1.grp.pLr
9b00: 75 54 61 69 6c 29 21 3d 30 29 20 29 7b 0a 20 20  uTail)!=0) ){.  
9b10: 20 20 20 20 6e 46 72 65 65 20 2b 3d 20 70 63 61      nFree += pca
9b20: 63 68 65 31 4d 65 6d 53 69 7a 65 28 50 47 48 44  che1MemSize(PGHD
9b30: 52 31 5f 54 4f 5f 50 41 47 45 28 70 29 29 3b 0a  R1_TO_PAGE(p));.
9b40: 20 20 20 20 20 20 70 63 61 63 68 65 31 50 69 6e        pcache1Pin
9b50: 50 61 67 65 28 70 29 3b 0a 20 20 20 20 20 20 70  Page(p);.      p
9b60: 63 61 63 68 65 31 52 65 6d 6f 76 65 46 72 6f 6d  cache1RemoveFrom
9b70: 48 61 73 68 28 70 29 3b 0a 20 20 20 20 20 20 70  Hash(p);.      p
9b80: 63 61 63 68 65 31 46 72 65 65 50 61 67 65 28 70  cache1FreePage(p
9b90: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 63 61  );.    }.    pca
9ba0: 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 26  che1LeaveMutex(&
9bb0: 70 63 61 63 68 65 31 2e 67 72 70 29 3b 0a 20 20  pcache1.grp);.  
9bc0: 7d 0a 20 20 72 65 74 75 72 6e 20 6e 46 72 65 65  }.  return nFree
9bd0: 3b 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51  ;.}.#endif /* SQ
9be0: 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f  LITE_ENABLE_MEMO
9bf0: 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 20 2a 2f  RY_MANAGEMENT */
9c00: 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f  ..#ifdef SQLITE_
9c10: 54 45 53 54 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  TEST./*.** This 
9c20: 66 75 6e 63 74 69 6f 6e 20 69 73 20 75 73 65 64  function is used
9c30: 20 62 79 20 74 65 73 74 20 70 72 6f 63 65 64 75   by test procedu
9c40: 72 65 73 20 74 6f 20 69 6e 73 70 65 63 74 20 74  res to inspect t
9c50: 68 65 20 69 6e 74 65 72 6e 61 6c 20 73 74 61 74  he internal stat
9c60: 65 0a 2a 2a 20 6f 66 20 74 68 65 20 67 6c 6f 62  e.** of the glob
9c70: 61 6c 20 63 61 63 68 65 2e 0a 2a 2f 0a 76 6f 69  al cache..*/.voi
9c80: 64 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 53  d sqlite3PcacheS
9c90: 74 61 74 73 28 0a 20 20 69 6e 74 20 2a 70 6e 43  tats(.  int *pnC
9ca0: 75 72 72 65 6e 74 2c 20 20 20 20 20 20 2f 2a 20  urrent,      /* 
9cb0: 4f 55 54 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65  OUT: Total numbe
9cc0: 72 20 6f 66 20 70 61 67 65 73 20 63 61 63 68 65  r of pages cache
9cd0: 64 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 4d 61  d */.  int *pnMa
9ce0: 78 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f  x,          /* O
9cf0: 55 54 3a 20 47 6c 6f 62 61 6c 20 6d 61 78 69 6d  UT: Global maxim
9d00: 75 6d 20 63 61 63 68 65 20 73 69 7a 65 20 2a 2f  um cache size */
9d10: 0a 20 20 69 6e 74 20 2a 70 6e 4d 69 6e 2c 20 20  .  int *pnMin,  
9d20: 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
9d30: 53 75 6d 20 6f 66 20 50 43 61 63 68 65 31 2e 6e  Sum of PCache1.n
9d40: 4d 69 6e 20 66 6f 72 20 70 75 72 67 65 61 62 6c  Min for purgeabl
9d50: 65 20 63 61 63 68 65 73 20 2a 2f 0a 20 20 69 6e  e caches */.  in
9d60: 74 20 2a 70 6e 52 65 63 79 63 6c 61 62 6c 65 20  t *pnRecyclable 
9d70: 20 20 20 2f 2a 20 4f 55 54 3a 20 54 6f 74 61 6c     /* OUT: Total
9d80: 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73   number of pages
9d90: 20 61 76 61 69 6c 61 62 6c 65 20 66 6f 72 20 72   available for r
9da0: 65 63 79 63 6c 69 6e 67 20 2a 2f 0a 29 7b 0a 20  ecycling */.){. 
9db0: 20 50 67 48 64 72 31 20 2a 70 3b 0a 20 20 69 6e   PgHdr1 *p;.  in
9dc0: 74 20 6e 52 65 63 79 63 6c 61 62 6c 65 20 3d 20  t nRecyclable = 
9dd0: 30 3b 0a 20 20 66 6f 72 28 70 3d 70 63 61 63 68  0;.  for(p=pcach
9de0: 65 31 2e 67 72 70 2e 70 4c 72 75 48 65 61 64 3b  e1.grp.pLruHead;
9df0: 20 70 3b 20 70 3d 70 2d 3e 70 4c 72 75 4e 65 78   p; p=p->pLruNex
9e00: 74 29 7b 0a 20 20 20 20 6e 52 65 63 79 63 6c 61  t){.    nRecycla
9e10: 62 6c 65 2b 2b 3b 0a 20 20 7d 0a 20 20 2a 70 6e  ble++;.  }.  *pn
9e20: 43 75 72 72 65 6e 74 20 3d 20 70 63 61 63 68 65  Current = pcache
9e30: 31 2e 67 72 70 2e 6e 43 75 72 72 65 6e 74 50 61  1.grp.nCurrentPa
9e40: 67 65 3b 0a 20 20 2a 70 6e 4d 61 78 20 3d 20 70  ge;.  *pnMax = p
9e50: 63 61 63 68 65 31 2e 67 72 70 2e 6e 4d 61 78 50  cache1.grp.nMaxP
9e60: 61 67 65 3b 0a 20 20 2a 70 6e 4d 69 6e 20 3d 20  age;.  *pnMin = 
9e70: 70 63 61 63 68 65 31 2e 67 72 70 2e 6e 4d 69 6e  pcache1.grp.nMin
9e80: 50 61 67 65 3b 0a 20 20 2a 70 6e 52 65 63 79 63  Page;.  *pnRecyc
9e90: 6c 61 62 6c 65 20 3d 20 6e 52 65 63 79 63 6c 61  lable = nRecycla
9ea0: 62 6c 65 3b 0a 7d 0a 23 65 6e 64 69 66 0a        ble;.}.#endif.