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

Artifact 8e3799b33c41d517d86444d4abefc80d4f02adca:


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 64 65 6e 2c 20 74 68 65 6e 20 6e  erridden, then n
0290: 65 69 74 68 65 72 20 6f 66 0a 2a 2a 20 74 68 65  either of.** the
02a0: 73 65 20 74 77 6f 20 66 65 61 74 75 72 65 73 20  se two features 
02b0: 61 72 65 20 61 76 61 69 6c 61 62 6c 65 2e 0a 2a  are available..*
02c0: 2f 0a 0a 23 69 6e 63 6c 75 64 65 20 22 73 71 6c  /..#include "sql
02d0: 69 74 65 49 6e 74 2e 68 22 0a 0a 74 79 70 65 64  iteInt.h"..typed
02e0: 65 66 20 73 74 72 75 63 74 20 50 43 61 63 68 65  ef struct PCache
02f0: 31 20 50 43 61 63 68 65 31 3b 0a 74 79 70 65 64  1 PCache1;.typed
0300: 65 66 20 73 74 72 75 63 74 20 50 67 48 64 72 31  ef struct PgHdr1
0310: 20 50 67 48 64 72 31 3b 0a 74 79 70 65 64 65 66   PgHdr1;.typedef
0320: 20 73 74 72 75 63 74 20 50 67 46 72 65 65 73 6c   struct PgFreesl
0330: 6f 74 20 50 67 46 72 65 65 73 6c 6f 74 3b 0a 74  ot PgFreeslot;.t
0340: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 50 47  ypedef struct PG
0350: 72 6f 75 70 20 50 47 72 6f 75 70 3b 0a 0a 2f 2a  roup PGroup;../*
0360: 20 45 61 63 68 20 70 61 67 65 20 63 61 63 68 65   Each page cache
0370: 20 28 6f 72 20 50 43 61 63 68 65 29 20 62 65 6c   (or PCache) bel
0380: 6f 6e 67 73 20 74 6f 20 61 20 50 47 72 6f 75 70  ongs to a PGroup
0390: 2e 20 20 41 20 50 47 72 6f 75 70 20 69 73 20 61  .  A PGroup is a
03a0: 20 73 65 74 20 0a 2a 2a 20 6f 66 20 6f 6e 65 20   set .** of one 
03b0: 6f 72 20 6d 6f 72 65 20 50 43 61 63 68 65 73 20  or more PCaches 
03c0: 74 68 61 74 20 61 72 65 20 61 62 6c 65 20 74 6f  that are able to
03d0: 20 72 65 63 79 63 6c 65 20 65 61 63 68 20 6f 74   recycle each ot
03e0: 68 65 72 27 73 20 75 6e 70 69 6e 6e 65 64 0a 2a  her's unpinned.*
03f0: 2a 20 70 61 67 65 73 20 77 68 65 6e 20 74 68 65  * pages when the
0400: 79 20 61 72 65 20 75 6e 64 65 72 20 6d 65 6d 6f  y are under memo
0410: 72 79 20 70 72 65 73 73 75 72 65 2e 20 20 41 20  ry pressure.  A 
0420: 50 47 72 6f 75 70 20 69 73 20 61 6e 20 69 6e 73  PGroup is an ins
0430: 74 61 6e 63 65 20 6f 66 0a 2a 2a 20 74 68 65 20  tance of.** the 
0440: 66 6f 6c 6c 6f 77 69 6e 67 20 6f 62 6a 65 63 74  following object
0450: 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 70 61 67  ..**.** This pag
0460: 65 20 63 61 63 68 65 20 69 6d 70 6c 65 6d 65 6e  e cache implemen
0470: 74 61 74 69 6f 6e 20 77 6f 72 6b 73 20 69 6e 20  tation works in 
0480: 6f 6e 65 20 6f 66 20 74 77 6f 20 6d 6f 64 65 73  one of two modes
0490: 3a 0a 2a 2a 0a 2a 2a 20 20 20 28 31 29 20 20 45  :.**.**   (1)  E
04a0: 76 65 72 79 20 50 43 61 63 68 65 20 69 73 20 74  very PCache is t
04b0: 68 65 20 73 6f 6c 65 20 6d 65 6d 62 65 72 20 6f  he sole member o
04c0: 66 20 69 74 73 20 6f 77 6e 20 50 47 72 6f 75 70  f its own PGroup
04d0: 2e 20 20 54 68 65 72 65 20 69 73 0a 2a 2a 20 20  .  There is.**  
04e0: 20 20 20 20 20 20 6f 6e 65 20 50 47 72 6f 75 70        one PGroup
04f0: 20 70 65 72 20 50 43 61 63 68 65 2e 0a 2a 2a 0a   per PCache..**.
0500: 2a 2a 20 20 20 28 32 29 20 20 54 68 65 72 65 20  **   (2)  There 
0510: 69 73 20 61 20 73 69 6e 67 6c 65 20 67 6c 6f 62  is a single glob
0520: 61 6c 20 50 47 72 6f 75 70 20 74 68 61 74 20 61  al PGroup that a
0530: 6c 6c 20 50 43 61 63 68 65 73 20 61 72 65 20 61  ll PCaches are a
0540: 20 6d 65 6d 62 65 72 0a 2a 2a 20 20 20 20 20 20   member.**      
0550: 20 20 6f 66 2e 0a 2a 2a 0a 2a 2a 20 4d 6f 64 65    of..**.** Mode
0560: 20 31 20 75 73 65 73 20 6d 6f 72 65 20 6d 65 6d   1 uses more mem
0570: 6f 72 79 20 28 73 69 6e 63 65 20 50 43 61 63 68  ory (since PCach
0580: 65 20 69 6e 73 74 61 6e 63 65 73 20 61 72 65 20  e instances are 
0590: 6e 6f 74 20 61 62 6c 65 20 74 6f 20 72 6f 62 0a  not able to rob.
05a0: 2a 2a 20 75 6e 75 73 65 64 20 70 61 67 65 73 20  ** unused pages 
05b0: 66 72 6f 6d 20 6f 74 68 65 72 20 50 43 61 63 68  from other PCach
05c0: 65 73 29 20 62 75 74 20 69 74 20 61 6c 73 6f 20  es) but it also 
05d0: 6f 70 65 72 61 74 65 73 20 77 69 74 68 6f 75 74  operates without
05e0: 20 61 20 6d 75 74 65 78 2c 0a 2a 2a 20 61 6e 64   a mutex,.** and
05f0: 20 69 73 20 74 68 65 72 65 66 6f 72 65 20 6f 66   is therefore of
0600: 74 65 6e 20 66 61 73 74 65 72 2e 20 20 4d 6f 64  ten faster.  Mod
0610: 65 20 32 20 72 65 71 75 69 72 65 73 20 61 20 6d  e 2 requires a m
0620: 75 74 65 78 20 69 6e 20 6f 72 64 65 72 20 74 6f  utex in order to
0630: 20 62 65 0a 2a 2a 20 74 68 72 65 61 64 73 61 66   be.** threadsaf
0640: 65 2c 20 62 75 74 20 72 65 63 79 63 6c 65 73 20  e, but recycles 
0650: 70 61 67 65 73 20 6d 6f 72 65 20 65 66 66 69 63  pages more effic
0660: 69 65 6e 74 6c 79 2e 0a 2a 2a 0a 2a 2a 20 46 6f  iently..**.** Fo
0670: 72 20 6d 6f 64 65 20 28 31 29 2c 20 50 47 72 6f  r mode (1), PGro
0680: 75 70 2e 6d 75 74 65 78 20 69 73 20 4e 55 4c 4c  up.mutex is NULL
0690: 2e 20 20 46 6f 72 20 6d 6f 64 65 20 28 32 29 20  .  For mode (2) 
06a0: 74 68 65 72 65 20 69 73 20 6f 6e 6c 79 20 61 20  there is only a 
06b0: 73 69 6e 67 6c 65 0a 2a 2a 20 50 47 72 6f 75 70  single.** PGroup
06c0: 20 77 68 69 63 68 20 69 73 20 74 68 65 20 70 63   which is the pc
06d0: 61 63 68 65 31 2e 67 72 70 20 67 6c 6f 62 61 6c  ache1.grp global
06e0: 20 76 61 72 69 61 62 6c 65 20 61 6e 64 20 69 74   variable and it
06f0: 73 20 6d 75 74 65 78 20 69 73 0a 2a 2a 20 53 51  s mutex is.** SQ
0700: 4c 49 54 45 5f 4d 55 54 45 58 5f 53 54 41 54 49  LITE_MUTEX_STATI
0710: 43 5f 4c 52 55 2e 0a 2a 2f 0a 73 74 72 75 63 74  C_LRU..*/.struct
0720: 20 50 47 72 6f 75 70 20 7b 0a 20 20 73 71 6c 69   PGroup {.  sqli
0730: 74 65 33 5f 6d 75 74 65 78 20 2a 6d 75 74 65 78  te3_mutex *mutex
0740: 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 55  ;          /* MU
0750: 54 45 58 5f 53 54 41 54 49 43 5f 4c 52 55 20 6f  TEX_STATIC_LRU o
0760: 72 20 4e 55 4c 4c 20 2a 2f 0a 20 20 75 6e 73 69  r NULL */.  unsi
0770: 67 6e 65 64 20 69 6e 74 20 6e 4d 61 78 50 61 67  gned int nMaxPag
0780: 65 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 53 75  e;         /* Su
0790: 6d 20 6f 66 20 6e 4d 61 78 20 66 6f 72 20 70 75  m of nMax for pu
07a0: 72 67 65 61 62 6c 65 20 63 61 63 68 65 73 20 2a  rgeable caches *
07b0: 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74  /.  unsigned int
07c0: 20 6e 4d 69 6e 50 61 67 65 3b 20 20 20 20 20 20   nMinPage;      
07d0: 20 20 20 2f 2a 20 53 75 6d 20 6f 66 20 6e 4d 69     /* Sum of nMi
07e0: 6e 20 66 6f 72 20 70 75 72 67 65 61 62 6c 65 20  n for purgeable 
07f0: 63 61 63 68 65 73 20 2a 2f 0a 20 20 75 6e 73 69  caches */.  unsi
0800: 67 6e 65 64 20 69 6e 74 20 6d 78 50 69 6e 6e 65  gned int mxPinne
0810: 64 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 6e 4d  d;         /* nM
0820: 61 78 70 61 67 65 20 2b 20 31 30 20 2d 20 6e 4d  axpage + 10 - nM
0830: 69 6e 50 61 67 65 20 2a 2f 0a 20 20 75 6e 73 69  inPage */.  unsi
0840: 67 6e 65 64 20 69 6e 74 20 6e 43 75 72 72 65 6e  gned int nCurren
0850: 74 50 61 67 65 3b 20 20 20 20 20 2f 2a 20 4e 75  tPage;     /* Nu
0860: 6d 62 65 72 20 6f 66 20 70 75 72 67 65 61 62 6c  mber of purgeabl
0870: 65 20 70 61 67 65 73 20 61 6c 6c 6f 63 61 74 65  e pages allocate
0880: 64 20 2a 2f 0a 20 20 50 67 48 64 72 31 20 2a 70  d */.  PgHdr1 *p
0890: 4c 72 75 48 65 61 64 2c 20 2a 70 4c 72 75 54 61  LruHead, *pLruTa
08a0: 69 6c 3b 20 20 20 2f 2a 20 4c 52 55 20 6c 69 73  il;   /* LRU lis
08b0: 74 20 6f 66 20 75 6e 70 69 6e 6e 65 64 20 70 61  t of unpinned pa
08c0: 67 65 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 20 45 61  ges */.};../* Ea
08d0: 63 68 20 70 61 67 65 20 63 61 63 68 65 20 69 73  ch page cache is
08e0: 20 61 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66 20   an instance of 
08f0: 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6f 62  the following ob
0900: 6a 65 63 74 2e 20 20 45 76 65 72 79 0a 2a 2a 20  ject.  Every.** 
0910: 6f 70 65 6e 20 64 61 74 61 62 61 73 65 20 66 69  open database fi
0920: 6c 65 20 28 69 6e 63 6c 75 64 69 6e 67 20 65 61  le (including ea
0930: 63 68 20 69 6e 2d 6d 65 6d 6f 72 79 20 64 61 74  ch in-memory dat
0940: 61 62 61 73 65 20 61 6e 64 20 65 61 63 68 0a 2a  abase and each.*
0950: 2a 20 74 65 6d 70 6f 72 61 72 79 20 6f 72 20 74  * temporary or t
0960: 72 61 6e 73 69 65 6e 74 20 64 61 74 61 62 61 73  ransient databas
0970: 65 29 20 68 61 73 20 61 20 73 69 6e 67 6c 65 20  e) has a single 
0980: 70 61 67 65 20 63 61 63 68 65 20 77 68 69 63 68  page cache which
0990: 0a 2a 2a 20 69 73 20 61 6e 20 69 6e 73 74 61 6e  .** is an instan
09a0: 63 65 20 6f 66 20 74 68 69 73 20 6f 62 6a 65 63  ce of this objec
09b0: 74 2e 0a 2a 2a 0a 2a 2a 20 50 6f 69 6e 74 65 72  t..**.** Pointer
09c0: 73 20 74 6f 20 73 74 72 75 63 74 75 72 65 73 20  s to structures 
09d0: 6f 66 20 74 68 69 73 20 74 79 70 65 20 61 72 65  of this type are
09e0: 20 63 61 73 74 20 61 6e 64 20 72 65 74 75 72 6e   cast and return
09f0: 65 64 20 61 73 20 0a 2a 2a 20 6f 70 61 71 75 65  ed as .** opaque
0a00: 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2a   sqlite3_pcache*
0a10: 20 68 61 6e 64 6c 65 73 2e 0a 2a 2f 0a 73 74 72   handles..*/.str
0a20: 75 63 74 20 50 43 61 63 68 65 31 20 7b 0a 20 20  uct PCache1 {.  
0a30: 2f 2a 20 43 61 63 68 65 20 63 6f 6e 66 69 67 75  /* Cache configu
0a40: 72 61 74 69 6f 6e 20 70 61 72 61 6d 65 74 65 72  ration parameter
0a50: 73 2e 20 50 61 67 65 20 73 69 7a 65 20 28 73 7a  s. Page size (sz
0a60: 50 61 67 65 29 20 61 6e 64 20 74 68 65 20 70 75  Page) and the pu
0a70: 72 67 65 61 62 6c 65 0a 20 20 2a 2a 20 66 6c 61  rgeable.  ** fla
0a80: 67 20 28 62 50 75 72 67 65 61 62 6c 65 29 20 61  g (bPurgeable) a
0a90: 72 65 20 73 65 74 20 77 68 65 6e 20 74 68 65 20  re set when the 
0aa0: 63 61 63 68 65 20 69 73 20 63 72 65 61 74 65 64  cache is created
0ab0: 2e 20 6e 4d 61 78 20 6d 61 79 20 62 65 20 0a 20  . nMax may be . 
0ac0: 20 2a 2a 20 6d 6f 64 69 66 69 65 64 20 61 74 20   ** modified at 
0ad0: 61 6e 79 20 74 69 6d 65 20 62 79 20 61 20 63 61  any time by a ca
0ae0: 6c 6c 20 74 6f 20 74 68 65 20 70 63 61 63 68 65  ll to the pcache
0af0: 31 43 61 63 68 65 73 69 7a 65 28 29 20 6d 65 74  1Cachesize() met
0b00: 68 6f 64 2e 0a 20 20 2a 2a 20 54 68 65 20 50 47  hod..  ** The PG
0b10: 72 6f 75 70 20 6d 75 74 65 78 20 6d 75 73 74 20  roup mutex must 
0b20: 62 65 20 68 65 6c 64 20 77 68 65 6e 20 61 63 63  be held when acc
0b30: 65 73 73 69 6e 67 20 6e 4d 61 78 2e 0a 20 20 2a  essing nMax..  *
0b40: 2f 0a 20 20 50 47 72 6f 75 70 20 2a 70 47 72 6f  /.  PGroup *pGro
0b50: 75 70 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  up;             
0b60: 20 20 20 20 20 20 20 20 2f 2a 20 50 47 72 6f 75          /* PGrou
0b70: 70 20 74 68 69 73 20 63 61 63 68 65 20 62 65 6c  p this cache bel
0b80: 6f 6e 67 73 20 74 6f 20 2a 2f 0a 20 20 69 6e 74  ongs to */.  int
0b90: 20 73 7a 50 61 67 65 3b 20 20 20 20 20 20 20 20   szPage;        
0ba0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0bb0: 20 2f 2a 20 53 69 7a 65 20 6f 66 20 61 6c 6c 6f   /* Size of allo
0bc0: 63 61 74 65 64 20 70 61 67 65 73 20 69 6e 20 62  cated pages in b
0bd0: 79 74 65 73 20 2a 2f 0a 20 20 69 6e 74 20 73 7a  ytes */.  int sz
0be0: 45 78 74 72 61 3b 20 20 20 20 20 20 20 20 20 20  Extra;          
0bf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0c00: 20 53 69 7a 65 20 6f 66 20 65 78 74 72 61 20 73   Size of extra s
0c10: 70 61 63 65 20 69 6e 20 62 79 74 65 73 20 2a 2f  pace in bytes */
0c20: 0a 20 20 69 6e 74 20 62 50 75 72 67 65 61 62 6c  .  int bPurgeabl
0c30: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
0c40: 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69         /* True i
0c50: 66 20 63 61 63 68 65 20 69 73 20 70 75 72 67 65  f cache is purge
0c60: 61 62 6c 65 20 2a 2f 0a 20 20 75 6e 73 69 67 6e  able */.  unsign
0c70: 65 64 20 69 6e 74 20 6e 4d 69 6e 3b 20 20 20 20  ed int nMin;    
0c80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0c90: 20 4d 69 6e 69 6d 75 6d 20 6e 75 6d 62 65 72 20   Minimum number 
0ca0: 6f 66 20 70 61 67 65 73 20 72 65 73 65 72 76 65  of pages reserve
0cb0: 64 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20  d */.  unsigned 
0cc0: 69 6e 74 20 6e 4d 61 78 3b 20 20 20 20 20 20 20  int nMax;       
0cd0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f             /* Co
0ce0: 6e 66 69 67 75 72 65 64 20 22 63 61 63 68 65 5f  nfigured "cache_
0cf0: 73 69 7a 65 22 20 76 61 6c 75 65 20 2a 2f 0a 20  size" value */. 
0d00: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 39   unsigned int n9
0d10: 30 70 63 74 3b 20 20 20 20 20 20 20 20 20 20 20  0pct;           
0d20: 20 20 20 20 20 2f 2a 20 6e 4d 61 78 2a 39 2f 31       /* nMax*9/1
0d30: 30 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20  0 */.  unsigned 
0d40: 69 6e 74 20 69 4d 61 78 4b 65 79 3b 20 20 20 20  int iMaxKey;    
0d50: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 61             /* La
0d60: 72 67 65 73 74 20 6b 65 79 20 73 65 65 6e 20 73  rgest key seen s
0d70: 69 6e 63 65 20 78 54 72 75 6e 63 61 74 65 28 29  ince xTruncate()
0d80: 20 2a 2f 0a 0a 20 20 2f 2a 20 48 61 73 68 20 74   */..  /* Hash t
0d90: 61 62 6c 65 20 6f 66 20 61 6c 6c 20 70 61 67 65  able of all page
0da0: 73 2e 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  s. The following
0db0: 20 76 61 72 69 61 62 6c 65 73 20 6d 61 79 20 6f   variables may o
0dc0: 6e 6c 79 20 62 65 20 61 63 63 65 73 73 65 64 0a  nly be accessed.
0dd0: 20 20 2a 2a 20 77 68 65 6e 20 74 68 65 20 61 63    ** when the ac
0de0: 63 65 73 73 6f 72 20 69 73 20 68 6f 6c 64 69 6e  cessor is holdin
0df0: 67 20 74 68 65 20 50 47 72 6f 75 70 20 6d 75 74  g the PGroup mut
0e00: 65 78 2e 0a 20 20 2a 2f 0a 20 20 75 6e 73 69 67  ex..  */.  unsig
0e10: 6e 65 64 20 69 6e 74 20 6e 52 65 63 79 63 6c 61  ned int nRecycla
0e20: 62 6c 65 3b 20 20 20 20 20 20 20 20 20 20 20 2f  ble;           /
0e30: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 70 61 67 65  * Number of page
0e40: 73 20 69 6e 20 74 68 65 20 4c 52 55 20 6c 69 73  s in the LRU lis
0e50: 74 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20  t */.  unsigned 
0e60: 69 6e 74 20 6e 50 61 67 65 3b 20 20 20 20 20 20  int nPage;      
0e70: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 6f             /* To
0e80: 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 70 61  tal number of pa
0e90: 67 65 73 20 69 6e 20 61 70 48 61 73 68 20 2a 2f  ges in apHash */
0ea0: 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  .  unsigned int 
0eb0: 6e 48 61 73 68 3b 20 20 20 20 20 20 20 20 20 20  nHash;          
0ec0: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
0ed0: 20 6f 66 20 73 6c 6f 74 73 20 69 6e 20 61 70 48   of slots in apH
0ee0: 61 73 68 5b 5d 20 2a 2f 0a 20 20 50 67 48 64 72  ash[] */.  PgHdr
0ef0: 31 20 2a 2a 61 70 48 61 73 68 3b 20 20 20 20 20  1 **apHash;     
0f00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0f10: 2a 20 48 61 73 68 20 74 61 62 6c 65 20 66 6f 72  * Hash table for
0f20: 20 66 61 73 74 20 6c 6f 6f 6b 75 70 20 62 79 20   fast lookup by 
0f30: 6b 65 79 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a  key */.};../*.**
0f40: 20 45 61 63 68 20 63 61 63 68 65 20 65 6e 74 72   Each cache entr
0f50: 79 20 69 73 20 72 65 70 72 65 73 65 6e 74 65 64  y is represented
0f60: 20 62 79 20 61 6e 20 69 6e 73 74 61 6e 63 65 20   by an instance 
0f70: 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  of the following
0f80: 20 0a 2a 2a 20 73 74 72 75 63 74 75 72 65 2e 20   .** structure. 
0f90: 55 6e 6c 65 73 73 20 53 51 4c 49 54 45 5f 50 43  Unless SQLITE_PC
0fa0: 41 43 48 45 5f 53 45 50 41 52 41 54 45 5f 48 45  ACHE_SEPARATE_HE
0fb0: 41 44 45 52 20 69 73 20 64 65 66 69 6e 65 64 2c  ADER is defined,
0fc0: 20 61 20 62 75 66 66 65 72 20 6f 66 0a 2a 2a 20   a buffer of.** 
0fd0: 50 67 48 64 72 31 2e 70 43 61 63 68 65 2d 3e 73  PgHdr1.pCache->s
0fe0: 7a 50 61 67 65 20 62 79 74 65 73 20 69 73 20 61  zPage bytes is a
0ff0: 6c 6c 6f 63 61 74 65 64 20 64 69 72 65 63 74 6c  llocated directl
1000: 79 20 62 65 66 6f 72 65 20 74 68 69 73 20 73 74  y before this st
1010: 72 75 63 74 75 72 65 20 0a 2a 2a 20 69 6e 20 6d  ructure .** in m
1020: 65 6d 6f 72 79 2e 0a 2a 2f 0a 73 74 72 75 63 74  emory..*/.struct
1030: 20 50 67 48 64 72 31 20 7b 0a 20 20 73 71 6c 69   PgHdr1 {.  sqli
1040: 74 65 33 5f 70 63 61 63 68 65 5f 70 61 67 65 20  te3_pcache_page 
1050: 70 61 67 65 3b 0a 20 20 75 6e 73 69 67 6e 65 64  page;.  unsigned
1060: 20 69 6e 74 20 69 4b 65 79 3b 20 20 20 20 20 20   int iKey;      
1070: 20 20 20 20 20 20 20 2f 2a 20 4b 65 79 20 76 61         /* Key va
1080: 6c 75 65 20 28 70 61 67 65 20 6e 75 6d 62 65 72  lue (page number
1090: 29 20 2a 2f 0a 20 20 75 38 20 69 73 50 69 6e 6e  ) */.  u8 isPinn
10a0: 65 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ed;             
10b0: 20 20 20 20 20 20 2f 2a 20 50 61 67 65 20 69 6e        /* Page in
10c0: 20 75 73 65 2c 20 6e 6f 74 20 6f 6e 20 74 68 65   use, not on the
10d0: 20 4c 52 55 20 6c 69 73 74 20 2a 2f 0a 20 20 50   LRU list */.  P
10e0: 67 48 64 72 31 20 2a 70 4e 65 78 74 3b 20 20 20  gHdr1 *pNext;   
10f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1100: 20 4e 65 78 74 20 69 6e 20 68 61 73 68 20 74 61   Next in hash ta
1110: 62 6c 65 20 63 68 61 69 6e 20 2a 2f 0a 20 20 50  ble chain */.  P
1120: 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 3b 20  Cache1 *pCache; 
1130: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1140: 20 43 61 63 68 65 20 74 68 61 74 20 63 75 72 72   Cache that curr
1150: 65 6e 74 6c 79 20 6f 77 6e 73 20 74 68 69 73 20  ently owns this 
1160: 70 61 67 65 20 2a 2f 0a 20 20 50 67 48 64 72 31  page */.  PgHdr1
1170: 20 2a 70 4c 72 75 4e 65 78 74 3b 20 20 20 20 20   *pLruNext;     
1180: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74           /* Next
1190: 20 69 6e 20 4c 52 55 20 6c 69 73 74 20 6f 66 20   in LRU list of 
11a0: 75 6e 70 69 6e 6e 65 64 20 70 61 67 65 73 20 2a  unpinned pages *
11b0: 2f 0a 20 20 50 67 48 64 72 31 20 2a 70 4c 72 75  /.  PgHdr1 *pLru
11c0: 50 72 65 76 3b 20 20 20 20 20 20 20 20 20 20 20  Prev;           
11d0: 20 20 20 2f 2a 20 50 72 65 76 69 6f 75 73 20 69     /* Previous i
11e0: 6e 20 4c 52 55 20 6c 69 73 74 20 6f 66 20 75 6e  n LRU list of un
11f0: 70 69 6e 6e 65 64 20 70 61 67 65 73 20 2a 2f 0a  pinned pages */.
1200: 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 73  };../*.** Free s
1210: 6c 6f 74 73 20 69 6e 20 74 68 65 20 61 6c 6c 6f  lots in the allo
1220: 63 61 74 6f 72 20 75 73 65 64 20 74 6f 20 64 69  cator used to di
1230: 76 69 64 65 20 75 70 20 74 68 65 20 62 75 66 66  vide up the buff
1240: 65 72 20 70 72 6f 76 69 64 65 64 20 75 73 69 6e  er provided usin
1250: 67 0a 2a 2a 20 74 68 65 20 53 51 4c 49 54 45 5f  g.** the SQLITE_
1260: 43 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48 45  CONFIG_PAGECACHE
1270: 20 6d 65 63 68 61 6e 69 73 6d 2e 0a 2a 2f 0a 73   mechanism..*/.s
1280: 74 72 75 63 74 20 50 67 46 72 65 65 73 6c 6f 74  truct PgFreeslot
1290: 20 7b 0a 20 20 50 67 46 72 65 65 73 6c 6f 74 20   {.  PgFreeslot 
12a0: 2a 70 4e 65 78 74 3b 20 20 2f 2a 20 4e 65 78 74  *pNext;  /* Next
12b0: 20 66 72 65 65 20 73 6c 6f 74 20 2a 2f 0a 7d 3b   free slot */.};
12c0: 0a 0a 2f 2a 0a 2a 2a 20 47 6c 6f 62 61 6c 20 64  ../*.** Global d
12d0: 61 74 61 20 75 73 65 64 20 62 79 20 74 68 69 73  ata used by this
12e0: 20 63 61 63 68 65 2e 0a 2a 2f 0a 73 74 61 74 69   cache..*/.stati
12f0: 63 20 53 51 4c 49 54 45 5f 57 53 44 20 73 74 72  c SQLITE_WSD str
1300: 75 63 74 20 50 43 61 63 68 65 47 6c 6f 62 61 6c  uct PCacheGlobal
1310: 20 7b 0a 20 20 50 47 72 6f 75 70 20 67 72 70 3b   {.  PGroup grp;
1320: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1330: 20 20 20 20 2f 2a 20 54 68 65 20 67 6c 6f 62 61      /* The globa
1340: 6c 20 50 47 72 6f 75 70 20 66 6f 72 20 6d 6f 64  l PGroup for mod
1350: 65 20 28 32 29 20 2a 2f 0a 0a 20 20 2f 2a 20 56  e (2) */..  /* V
1360: 61 72 69 61 62 6c 65 73 20 72 65 6c 61 74 65 64  ariables related
1370: 20 74 6f 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49   to SQLITE_CONFI
1380: 47 5f 50 41 47 45 43 41 43 48 45 20 73 65 74 74  G_PAGECACHE sett
1390: 69 6e 67 73 2e 20 20 54 68 65 0a 20 20 2a 2a 20  ings.  The.  ** 
13a0: 73 7a 53 6c 6f 74 2c 20 6e 53 6c 6f 74 2c 20 70  szSlot, nSlot, p
13b0: 53 74 61 72 74 2c 20 70 45 6e 64 2c 20 6e 52 65  Start, pEnd, nRe
13c0: 73 65 72 76 65 2c 20 61 6e 64 20 69 73 49 6e 69  serve, and isIni
13d0: 74 20 76 61 6c 75 65 73 20 61 72 65 20 61 6c 6c  t values are all
13e0: 0a 20 20 2a 2a 20 66 69 78 65 64 20 61 74 20 73  .  ** fixed at s
13f0: 71 6c 69 74 65 33 5f 69 6e 69 74 69 61 6c 69 7a  qlite3_initializ
1400: 65 28 29 20 74 69 6d 65 20 61 6e 64 20 64 6f 20  e() time and do 
1410: 6e 6f 74 20 72 65 71 75 69 72 65 20 6d 75 74 65  not require mute
1420: 78 20 70 72 6f 74 65 63 74 69 6f 6e 2e 0a 20 20  x protection..  
1430: 2a 2a 20 54 68 65 20 6e 46 72 65 65 53 6c 6f 74  ** The nFreeSlot
1440: 20 61 6e 64 20 70 46 72 65 65 20 76 61 6c 75 65   and pFree value
1450: 73 20 64 6f 20 72 65 71 75 69 72 65 20 6d 75 74  s do require mut
1460: 65 78 20 70 72 6f 74 65 63 74 69 6f 6e 2e 0a 20  ex protection.. 
1470: 20 2a 2f 0a 20 20 69 6e 74 20 69 73 49 6e 69 74   */.  int isInit
1480: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1490: 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20       /* True if 
14a0: 69 6e 69 74 69 61 6c 69 7a 65 64 20 2a 2f 0a 20  initialized */. 
14b0: 20 69 6e 74 20 73 7a 53 6c 6f 74 3b 20 20 20 20   int szSlot;    
14c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14d0: 2f 2a 20 53 69 7a 65 20 6f 66 20 65 61 63 68 20  /* Size of each 
14e0: 66 72 65 65 20 73 6c 6f 74 20 2a 2f 0a 20 20 69  free slot */.  i
14f0: 6e 74 20 6e 53 6c 6f 74 3b 20 20 20 20 20 20 20  nt nSlot;       
1500: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1510: 20 54 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70   The number of p
1520: 63 61 63 68 65 20 73 6c 6f 74 73 20 2a 2f 0a 20  cache slots */. 
1530: 20 69 6e 74 20 6e 52 65 73 65 72 76 65 3b 20 20   int nReserve;  
1540: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1550: 2f 2a 20 54 72 79 20 74 6f 20 6b 65 65 70 20 6e  /* Try to keep n
1560: 46 72 65 65 53 6c 6f 74 20 61 62 6f 76 65 20 74  FreeSlot above t
1570: 68 69 73 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70  his */.  void *p
1580: 53 74 61 72 74 2c 20 2a 70 45 6e 64 3b 20 20 20  Start, *pEnd;   
1590: 20 20 20 20 20 20 20 20 2f 2a 20 42 6f 75 6e 64          /* Bound
15a0: 73 20 6f 66 20 70 61 67 65 63 61 63 68 65 20 6d  s of pagecache m
15b0: 61 6c 6c 6f 63 20 72 61 6e 67 65 20 2a 2f 0a 20  alloc range */. 
15c0: 20 2f 2a 20 41 62 6f 76 65 20 72 65 71 75 69 72   /* Above requir
15d0: 65 73 20 6e 6f 20 6d 75 74 65 78 2e 20 20 55 73  es no mutex.  Us
15e0: 65 20 6d 75 74 65 78 20 62 65 6c 6f 77 20 66 6f  e mutex below fo
15f0: 72 20 76 61 72 69 61 62 6c 65 20 74 68 61 74 20  r variable that 
1600: 66 6f 6c 6c 6f 77 2e 20 2a 2f 0a 20 20 73 71 6c  follow. */.  sql
1610: 69 74 65 33 5f 6d 75 74 65 78 20 2a 6d 75 74 65  ite3_mutex *mute
1620: 78 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d  x;          /* M
1630: 75 74 65 78 20 66 6f 72 20 61 63 63 65 73 73 69  utex for accessi
1640: 6e 67 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  ng the following
1650: 3a 20 2a 2f 0a 20 20 50 67 46 72 65 65 73 6c 6f  : */.  PgFreeslo
1660: 74 20 2a 70 46 72 65 65 3b 20 20 20 20 20 20 20  t *pFree;       
1670: 20 20 20 20 20 20 2f 2a 20 46 72 65 65 20 70 61        /* Free pa
1680: 67 65 20 62 6c 6f 63 6b 73 20 2a 2f 0a 20 20 69  ge blocks */.  i
1690: 6e 74 20 6e 46 72 65 65 53 6c 6f 74 3b 20 20 20  nt nFreeSlot;   
16a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
16b0: 20 4e 75 6d 62 65 72 20 6f 66 20 75 6e 75 73 65   Number of unuse
16c0: 64 20 70 63 61 63 68 65 20 73 6c 6f 74 73 20 2a  d pcache slots *
16d0: 2f 0a 20 20 2f 2a 20 54 68 65 20 66 6f 6c 6c 6f  /.  /* The follo
16e0: 77 69 6e 67 20 76 61 6c 75 65 20 72 65 71 75 69  wing value requi
16f0: 72 65 73 20 61 20 6d 75 74 65 78 20 74 6f 20 63  res a mutex to c
1700: 68 61 6e 67 65 2e 20 20 57 65 20 73 6b 69 70 20  hange.  We skip 
1710: 74 68 65 20 6d 75 74 65 78 20 6f 6e 0a 20 20 2a  the mutex on.  *
1720: 2a 20 72 65 61 64 69 6e 67 20 62 65 63 61 75 73  * reading becaus
1730: 65 20 28 31 29 20 6d 6f 73 74 20 70 6c 61 74 66  e (1) most platf
1740: 6f 72 6d 73 20 72 65 61 64 20 61 20 33 32 2d 62  orms read a 32-b
1750: 69 74 20 69 6e 74 65 67 65 72 20 61 74 6f 6d 69  it integer atomi
1760: 63 61 6c 6c 79 20 61 6e 64 0a 20 20 2a 2a 20 28  cally and.  ** (
1770: 32 29 20 65 76 65 6e 20 69 66 20 61 6e 20 69 6e  2) even if an in
1780: 63 6f 72 72 65 63 74 20 76 61 6c 75 65 20 69 73  correct value is
1790: 20 72 65 61 64 2c 20 6e 6f 20 67 72 65 61 74 20   read, no great 
17a0: 68 61 72 6d 20 69 73 20 64 6f 6e 65 20 73 69 6e  harm is done sin
17b0: 63 65 20 74 68 69 73 0a 20 20 2a 2a 20 69 73 20  ce this.  ** is 
17c0: 72 65 61 6c 6c 79 20 6a 75 73 74 20 61 6e 20 6f  really just an o
17d0: 70 74 69 6d 69 7a 61 74 69 6f 6e 2e 20 2a 2f 0a  ptimization. */.
17e0: 20 20 69 6e 74 20 62 55 6e 64 65 72 50 72 65 73    int bUnderPres
17f0: 73 75 72 65 3b 20 20 20 20 20 20 20 20 20 20 20  sure;           
1800: 20 2f 2a 20 54 72 75 65 20 69 66 20 6c 6f 77 20   /* True if low 
1810: 6f 6e 20 50 41 47 45 43 41 43 48 45 20 6d 65 6d  on PAGECACHE mem
1820: 6f 72 79 20 2a 2f 0a 7d 20 70 63 61 63 68 65 31  ory */.} pcache1
1830: 5f 67 3b 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c 20 63  _g;../*.** All c
1840: 6f 64 65 20 69 6e 20 74 68 69 73 20 66 69 6c 65  ode in this file
1850: 20 73 68 6f 75 6c 64 20 61 63 63 65 73 73 20 74   should access t
1860: 68 65 20 67 6c 6f 62 61 6c 20 73 74 72 75 63 74  he global struct
1870: 75 72 65 20 61 62 6f 76 65 20 76 69 61 20 74 68  ure above via th
1880: 65 0a 2a 2a 20 61 6c 69 61 73 20 22 70 63 61 63  e.** alias "pcac
1890: 68 65 31 22 2e 20 54 68 69 73 20 65 6e 73 75 72  he1". This ensur
18a0: 65 73 20 74 68 61 74 20 74 68 65 20 57 53 44 20  es that the WSD 
18b0: 65 6d 75 6c 61 74 69 6f 6e 20 69 73 20 75 73 65  emulation is use
18c0: 64 20 77 68 65 6e 0a 2a 2a 20 63 6f 6d 70 69 6c  d when.** compil
18d0: 69 6e 67 20 66 6f 72 20 73 79 73 74 65 6d 73 20  ing for systems 
18e0: 74 68 61 74 20 64 6f 20 6e 6f 74 20 73 75 70 70  that do not supp
18f0: 6f 72 74 20 72 65 61 6c 20 57 53 44 2e 0a 2a 2f  ort real WSD..*/
1900: 0a 23 64 65 66 69 6e 65 20 70 63 61 63 68 65 31  .#define pcache1
1910: 20 28 47 4c 4f 42 41 4c 28 73 74 72 75 63 74 20   (GLOBAL(struct 
1920: 50 43 61 63 68 65 47 6c 6f 62 61 6c 2c 20 70 63  PCacheGlobal, pc
1930: 61 63 68 65 31 5f 67 29 29 0a 0a 2f 2a 0a 2a 2a  ache1_g))../*.**
1940: 20 4d 61 63 72 6f 73 20 74 6f 20 65 6e 74 65 72   Macros to enter
1950: 20 61 6e 64 20 6c 65 61 76 65 20 74 68 65 20 50   and leave the P
1960: 43 61 63 68 65 20 4c 52 55 20 6d 75 74 65 78 2e  Cache LRU mutex.
1970: 0a 2a 2f 0a 23 69 66 20 21 64 65 66 69 6e 65 64  .*/.#if !defined
1980: 28 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d  (SQLITE_ENABLE_M
1990: 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54  EMORY_MANAGEMENT
19a0: 29 20 7c 7c 20 53 51 4c 49 54 45 5f 54 48 52 45  ) || SQLITE_THRE
19b0: 41 44 53 41 46 45 3d 3d 30 0a 23 20 64 65 66 69  ADSAFE==0.# defi
19c0: 6e 65 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d  ne pcache1EnterM
19d0: 75 74 65 78 28 58 29 20 20 61 73 73 65 72 74 28  utex(X)  assert(
19e0: 28 58 29 2d 3e 6d 75 74 65 78 3d 3d 30 29 0a 23  (X)->mutex==0).#
19f0: 20 64 65 66 69 6e 65 20 70 63 61 63 68 65 31 4c   define pcache1L
1a00: 65 61 76 65 4d 75 74 65 78 28 58 29 20 20 61 73  eaveMutex(X)  as
1a10: 73 65 72 74 28 28 58 29 2d 3e 6d 75 74 65 78 3d  sert((X)->mutex=
1a20: 3d 30 29 0a 23 20 64 65 66 69 6e 65 20 50 43 41  =0).# define PCA
1a30: 43 48 45 31 5f 4d 49 47 48 54 5f 55 53 45 5f 47  CHE1_MIGHT_USE_G
1a40: 52 4f 55 50 5f 4d 55 54 45 58 20 30 0a 23 65 6c  ROUP_MUTEX 0.#el
1a50: 73 65 0a 23 20 64 65 66 69 6e 65 20 70 63 61 63  se.# define pcac
1a60: 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 58 29  he1EnterMutex(X)
1a70: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65   sqlite3_mutex_e
1a80: 6e 74 65 72 28 28 58 29 2d 3e 6d 75 74 65 78 29  nter((X)->mutex)
1a90: 0a 23 20 64 65 66 69 6e 65 20 70 63 61 63 68 65  .# define pcache
1aa0: 31 4c 65 61 76 65 4d 75 74 65 78 28 58 29 20 73  1LeaveMutex(X) s
1ab0: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61  qlite3_mutex_lea
1ac0: 76 65 28 28 58 29 2d 3e 6d 75 74 65 78 29 0a 23  ve((X)->mutex).#
1ad0: 20 64 65 66 69 6e 65 20 50 43 41 43 48 45 31 5f   define PCACHE1_
1ae0: 4d 49 47 48 54 5f 55 53 45 5f 47 52 4f 55 50 5f  MIGHT_USE_GROUP_
1af0: 4d 55 54 45 58 20 31 0a 23 65 6e 64 69 66 0a 0a  MUTEX 1.#endif..
1b00: 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  /***************
1b10: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1b20: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1b30: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1b40: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f  ***************/
1b50: 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 20 50 61 67 65 20  ./******** Page 
1b60: 41 6c 6c 6f 63 61 74 69 6f 6e 2f 53 51 4c 49 54  Allocation/SQLIT
1b70: 45 5f 43 4f 4e 46 49 47 5f 50 43 41 43 48 45 20  E_CONFIG_PCACHE 
1b80: 52 65 6c 61 74 65 64 20 46 75 6e 63 74 69 6f 6e  Related Function
1b90: 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  s **************
1ba0: 2f 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75  /../*.** This fu
1bb0: 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64  nction is called
1bc0: 20 64 75 72 69 6e 67 20 69 6e 69 74 69 61 6c 69   during initiali
1bd0: 7a 61 74 69 6f 6e 20 69 66 20 61 20 73 74 61 74  zation if a stat
1be0: 69 63 20 62 75 66 66 65 72 20 69 73 20 0a 2a 2a  ic buffer is .**
1bf0: 20 73 75 70 70 6c 69 65 64 20 74 6f 20 75 73 65   supplied to use
1c00: 20 66 6f 72 20 74 68 65 20 70 61 67 65 2d 63 61   for the page-ca
1c10: 63 68 65 20 62 79 20 70 61 73 73 69 6e 67 20 74  che by passing t
1c20: 68 65 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47  he SQLITE_CONFIG
1c30: 5f 50 41 47 45 43 41 43 48 45 0a 2a 2a 20 76 65  _PAGECACHE.** ve
1c40: 72 62 20 74 6f 20 73 71 6c 69 74 65 33 5f 63 6f  rb to sqlite3_co
1c50: 6e 66 69 67 28 29 2e 20 50 61 72 61 6d 65 74 65  nfig(). Paramete
1c60: 72 20 70 42 75 66 20 70 6f 69 6e 74 73 20 74 6f  r pBuf points to
1c70: 20 61 6e 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 6c   an allocation l
1c80: 61 72 67 65 0a 2a 2a 20 65 6e 6f 75 67 68 20 74  arge.** enough t
1c90: 6f 20 63 6f 6e 74 61 69 6e 20 27 6e 27 20 62 75  o contain 'n' bu
1ca0: 66 66 65 72 73 20 6f 66 20 27 73 7a 27 20 62 79  ffers of 'sz' by
1cb0: 74 65 73 20 65 61 63 68 2e 0a 2a 2a 0a 2a 2a 20  tes each..**.** 
1cc0: 54 68 69 73 20 72 6f 75 74 69 6e 65 20 69 73 20  This routine is 
1cd0: 63 61 6c 6c 65 64 20 66 72 6f 6d 20 73 71 6c 69  called from sqli
1ce0: 74 65 33 5f 69 6e 69 74 69 61 6c 69 7a 65 28 29  te3_initialize()
1cf0: 20 61 6e 64 20 73 6f 20 69 74 20 69 73 20 67 75   and so it is gu
1d00: 61 72 61 6e 74 65 65 64 0a 2a 2a 20 74 6f 20 62  aranteed.** to b
1d10: 65 20 73 65 72 69 61 6c 69 7a 65 64 20 61 6c 72  e serialized alr
1d20: 65 61 64 79 2e 20 20 54 68 65 72 65 20 69 73 20  eady.  There is 
1d30: 6e 6f 20 6e 65 65 64 20 66 6f 72 20 66 75 72 74  no need for furt
1d40: 68 65 72 20 6d 75 74 65 78 69 6e 67 2e 0a 2a 2f  her mutexing..*/
1d50: 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 43 61  .void sqlite3PCa
1d60: 63 68 65 42 75 66 66 65 72 53 65 74 75 70 28 76  cheBufferSetup(v
1d70: 6f 69 64 20 2a 70 42 75 66 2c 20 69 6e 74 20 73  oid *pBuf, int s
1d80: 7a 2c 20 69 6e 74 20 6e 29 7b 0a 20 20 69 66 28  z, int n){.  if(
1d90: 20 70 63 61 63 68 65 31 2e 69 73 49 6e 69 74 20   pcache1.isInit 
1da0: 29 7b 0a 20 20 20 20 50 67 46 72 65 65 73 6c 6f  ){.    PgFreeslo
1db0: 74 20 2a 70 3b 0a 20 20 20 20 73 7a 20 3d 20 52  t *p;.    sz = R
1dc0: 4f 55 4e 44 44 4f 57 4e 38 28 73 7a 29 3b 0a 20  OUNDDOWN8(sz);. 
1dd0: 20 20 20 70 63 61 63 68 65 31 2e 73 7a 53 6c 6f     pcache1.szSlo
1de0: 74 20 3d 20 73 7a 3b 0a 20 20 20 20 70 63 61 63  t = sz;.    pcac
1df0: 68 65 31 2e 6e 53 6c 6f 74 20 3d 20 70 63 61 63  he1.nSlot = pcac
1e00: 68 65 31 2e 6e 46 72 65 65 53 6c 6f 74 20 3d 20  he1.nFreeSlot = 
1e10: 6e 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 6e  n;.    pcache1.n
1e20: 52 65 73 65 72 76 65 20 3d 20 6e 3e 39 30 20 3f  Reserve = n>90 ?
1e30: 20 31 30 20 3a 20 28 6e 2f 31 30 20 2b 20 31 29   10 : (n/10 + 1)
1e40: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 70 53  ;.    pcache1.pS
1e50: 74 61 72 74 20 3d 20 70 42 75 66 3b 0a 20 20 20  tart = pBuf;.   
1e60: 20 70 63 61 63 68 65 31 2e 70 46 72 65 65 20 3d   pcache1.pFree =
1e70: 20 30 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e   0;.    pcache1.
1e80: 62 55 6e 64 65 72 50 72 65 73 73 75 72 65 20 3d  bUnderPressure =
1e90: 20 30 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 6e   0;.    while( n
1ea0: 2d 2d 20 29 7b 0a 20 20 20 20 20 20 70 20 3d 20  -- ){.      p = 
1eb0: 28 50 67 46 72 65 65 73 6c 6f 74 2a 29 70 42 75  (PgFreeslot*)pBu
1ec0: 66 3b 0a 20 20 20 20 20 20 70 2d 3e 70 4e 65 78  f;.      p->pNex
1ed0: 74 20 3d 20 70 63 61 63 68 65 31 2e 70 46 72 65  t = pcache1.pFre
1ee0: 65 3b 0a 20 20 20 20 20 20 70 63 61 63 68 65 31  e;.      pcache1
1ef0: 2e 70 46 72 65 65 20 3d 20 70 3b 0a 20 20 20 20  .pFree = p;.    
1f00: 20 20 70 42 75 66 20 3d 20 28 76 6f 69 64 2a 29    pBuf = (void*)
1f10: 26 28 28 63 68 61 72 2a 29 70 42 75 66 29 5b 73  &((char*)pBuf)[s
1f20: 7a 5d 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 63  z];.    }.    pc
1f30: 61 63 68 65 31 2e 70 45 6e 64 20 3d 20 70 42 75  ache1.pEnd = pBu
1f40: 66 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  f;.  }.}../*.** 
1f50: 4d 61 6c 6c 6f 63 20 66 75 6e 63 74 69 6f 6e 20  Malloc function 
1f60: 75 73 65 64 20 77 69 74 68 69 6e 20 74 68 69 73  used within this
1f70: 20 66 69 6c 65 20 74 6f 20 61 6c 6c 6f 63 61 74   file to allocat
1f80: 65 20 73 70 61 63 65 20 66 72 6f 6d 20 74 68 65  e space from the
1f90: 20 62 75 66 66 65 72 0a 2a 2a 20 63 6f 6e 66 69   buffer.** confi
1fa0: 67 75 72 65 64 20 75 73 69 6e 67 20 73 71 6c 69  gured using sqli
1fb0: 74 65 33 5f 63 6f 6e 66 69 67 28 53 51 4c 49 54  te3_config(SQLIT
1fc0: 45 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41 43  E_CONFIG_PAGECAC
1fd0: 48 45 29 20 6f 70 74 69 6f 6e 2e 20 49 66 20 6e  HE) option. If n
1fe0: 6f 20 0a 2a 2a 20 73 75 63 68 20 62 75 66 66 65  o .** such buffe
1ff0: 72 20 65 78 69 73 74 73 20 6f 72 20 74 68 65 72  r exists or ther
2000: 65 20 69 73 20 6e 6f 20 73 70 61 63 65 20 6c 65  e is no space le
2010: 66 74 20 69 6e 20 69 74 2c 20 74 68 69 73 20 66  ft in it, this f
2020: 75 6e 63 74 69 6f 6e 20 66 61 6c 6c 73 20 0a 2a  unction falls .*
2030: 2a 20 62 61 63 6b 20 74 6f 20 73 71 6c 69 74 65  * back to sqlite
2040: 33 4d 61 6c 6c 6f 63 28 29 2e 0a 2a 2a 0a 2a 2a  3Malloc()..**.**
2050: 20 4d 75 6c 74 69 70 6c 65 20 74 68 72 65 61 64   Multiple thread
2060: 73 20 63 61 6e 20 72 75 6e 20 74 68 69 73 20 72  s can run this r
2070: 6f 75 74 69 6e 65 20 61 74 20 74 68 65 20 73 61  outine at the sa
2080: 6d 65 20 74 69 6d 65 2e 20 20 47 6c 6f 62 61 6c  me time.  Global
2090: 20 76 61 72 69 61 62 6c 65 73 0a 2a 2a 20 69 6e   variables.** in
20a0: 20 70 63 61 63 68 65 31 20 6e 65 65 64 20 74 6f   pcache1 need to
20b0: 20 62 65 20 70 72 6f 74 65 63 74 65 64 20 76 69   be protected vi
20c0: 61 20 6d 75 74 65 78 2e 0a 2a 2f 0a 73 74 61 74  a mutex..*/.stat
20d0: 69 63 20 76 6f 69 64 20 2a 70 63 61 63 68 65 31  ic void *pcache1
20e0: 41 6c 6c 6f 63 28 69 6e 74 20 6e 42 79 74 65 29  Alloc(int nByte)
20f0: 7b 0a 20 20 76 6f 69 64 20 2a 70 20 3d 20 30 3b  {.  void *p = 0;
2100: 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74  .  assert( sqlit
2110: 65 33 5f 6d 75 74 65 78 5f 6e 6f 74 68 65 6c 64  e3_mutex_notheld
2120: 28 70 63 61 63 68 65 31 2e 67 72 70 2e 6d 75 74  (pcache1.grp.mut
2130: 65 78 29 20 29 3b 0a 20 20 69 66 28 20 6e 42 79  ex) );.  if( nBy
2140: 74 65 3c 3d 70 63 61 63 68 65 31 2e 73 7a 53 6c  te<=pcache1.szSl
2150: 6f 74 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  ot ){.    sqlite
2160: 33 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28 70 63  3_mutex_enter(pc
2170: 61 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a 20 20  ache1.mutex);.  
2180: 20 20 70 20 3d 20 28 50 67 48 64 72 31 20 2a 29    p = (PgHdr1 *)
2190: 70 63 61 63 68 65 31 2e 70 46 72 65 65 3b 0a 20  pcache1.pFree;. 
21a0: 20 20 20 69 66 28 20 70 20 29 7b 0a 20 20 20 20     if( p ){.    
21b0: 20 20 70 63 61 63 68 65 31 2e 70 46 72 65 65 20    pcache1.pFree 
21c0: 3d 20 70 63 61 63 68 65 31 2e 70 46 72 65 65 2d  = pcache1.pFree-
21d0: 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 70 63  >pNext;.      pc
21e0: 61 63 68 65 31 2e 6e 46 72 65 65 53 6c 6f 74 2d  ache1.nFreeSlot-
21f0: 2d 3b 0a 20 20 20 20 20 20 70 63 61 63 68 65 31  -;.      pcache1
2200: 2e 62 55 6e 64 65 72 50 72 65 73 73 75 72 65 20  .bUnderPressure 
2210: 3d 20 70 63 61 63 68 65 31 2e 6e 46 72 65 65 53  = pcache1.nFreeS
2220: 6c 6f 74 3c 70 63 61 63 68 65 31 2e 6e 52 65 73  lot<pcache1.nRes
2230: 65 72 76 65 3b 0a 20 20 20 20 20 20 61 73 73 65  erve;.      asse
2240: 72 74 28 20 70 63 61 63 68 65 31 2e 6e 46 72 65  rt( pcache1.nFre
2250: 65 53 6c 6f 74 3e 3d 30 20 29 3b 0a 20 20 20 20  eSlot>=0 );.    
2260: 20 20 73 71 6c 69 74 65 33 53 74 61 74 75 73 53    sqlite3StatusS
2270: 65 74 28 53 51 4c 49 54 45 5f 53 54 41 54 55 53  et(SQLITE_STATUS
2280: 5f 50 41 47 45 43 41 43 48 45 5f 53 49 5a 45 2c  _PAGECACHE_SIZE,
2290: 20 6e 42 79 74 65 29 3b 0a 20 20 20 20 20 20 73   nByte);.      s
22a0: 71 6c 69 74 65 33 53 74 61 74 75 73 55 70 28 53  qlite3StatusUp(S
22b0: 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41 47  QLITE_STATUS_PAG
22c0: 45 43 41 43 48 45 5f 55 53 45 44 2c 20 31 29 3b  ECACHE_USED, 1);
22d0: 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 6c 69 74  .    }.    sqlit
22e0: 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 70  e3_mutex_leave(p
22f0: 63 61 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a 20  cache1.mutex);. 
2300: 20 7d 0a 20 20 69 66 28 20 70 3d 3d 30 20 29 7b   }.  if( p==0 ){
2310: 0a 20 20 20 20 2f 2a 20 4d 65 6d 6f 72 79 20 69  .    /* Memory i
2320: 73 20 6e 6f 74 20 61 76 61 69 6c 61 62 6c 65 20  s not available 
2330: 69 6e 20 74 68 65 20 53 51 4c 49 54 45 5f 43 4f  in the SQLITE_CO
2340: 4e 46 49 47 5f 50 41 47 45 43 41 43 48 45 20 70  NFIG_PAGECACHE p
2350: 6f 6f 6c 2e 20 20 47 65 74 0a 20 20 20 20 2a 2a  ool.  Get.    **
2360: 20 69 74 20 66 72 6f 6d 20 73 71 6c 69 74 65 33   it from sqlite3
2370: 4d 61 6c 6c 6f 63 20 69 6e 73 74 65 61 64 2e 0a  Malloc instead..
2380: 20 20 20 20 2a 2f 0a 20 20 20 20 70 20 3d 20 73      */.    p = s
2390: 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 6e 42 79  qlite3Malloc(nBy
23a0: 74 65 29 3b 0a 23 69 66 6e 64 65 66 20 53 51 4c  te);.#ifndef SQL
23b0: 49 54 45 5f 44 49 53 41 42 4c 45 5f 50 41 47 45  ITE_DISABLE_PAGE
23c0: 43 41 43 48 45 5f 4f 56 45 52 46 4c 4f 57 5f 53  CACHE_OVERFLOW_S
23d0: 54 41 54 53 0a 20 20 20 20 69 66 28 20 70 20 29  TATS.    if( p )
23e0: 7b 0a 20 20 20 20 20 20 69 6e 74 20 73 7a 20 3d  {.      int sz =
23f0: 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 53 69   sqlite3MallocSi
2400: 7a 65 28 70 29 3b 0a 20 20 20 20 20 20 73 71 6c  ze(p);.      sql
2410: 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e 74 65 72  ite3_mutex_enter
2420: 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29 3b  (pcache1.mutex);
2430: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 53 74  .      sqlite3St
2440: 61 74 75 73 53 65 74 28 53 51 4c 49 54 45 5f 53  atusSet(SQLITE_S
2450: 54 41 54 55 53 5f 50 41 47 45 43 41 43 48 45 5f  TATUS_PAGECACHE_
2460: 53 49 5a 45 2c 20 6e 42 79 74 65 29 3b 0a 20 20  SIZE, nByte);.  
2470: 20 20 20 20 73 71 6c 69 74 65 33 53 74 61 74 75      sqlite3Statu
2480: 73 55 70 28 53 51 4c 49 54 45 5f 53 54 41 54 55  sUp(SQLITE_STATU
2490: 53 5f 50 41 47 45 43 41 43 48 45 5f 4f 56 45 52  S_PAGECACHE_OVER
24a0: 46 4c 4f 57 2c 20 73 7a 29 3b 0a 20 20 20 20 20  FLOW, sz);.     
24b0: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6c   sqlite3_mutex_l
24c0: 65 61 76 65 28 70 63 61 63 68 65 31 2e 6d 75 74  eave(pcache1.mut
24d0: 65 78 29 3b 0a 20 20 20 20 7d 0a 23 65 6e 64 69  ex);.    }.#endi
24e0: 66 0a 20 20 20 20 73 71 6c 69 74 65 33 4d 65 6d  f.    sqlite3Mem
24f0: 64 65 62 75 67 53 65 74 54 79 70 65 28 70 2c 20  debugSetType(p, 
2500: 4d 45 4d 54 59 50 45 5f 50 43 41 43 48 45 29 3b  MEMTYPE_PCACHE);
2510: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 70 3b  .  }.  return p;
2520: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61  .}../*.** Free a
2530: 6e 20 61 6c 6c 6f 63 61 74 65 64 20 62 75 66 66  n allocated buff
2540: 65 72 20 6f 62 74 61 69 6e 65 64 20 66 72 6f 6d  er obtained from
2550: 20 70 63 61 63 68 65 31 41 6c 6c 6f 63 28 29 2e   pcache1Alloc().
2560: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 70  .*/.static int p
2570: 63 61 63 68 65 31 46 72 65 65 28 76 6f 69 64 20  cache1Free(void 
2580: 2a 70 29 7b 0a 20 20 69 6e 74 20 6e 46 72 65 65  *p){.  int nFree
2590: 64 20 3d 20 30 3b 0a 20 20 69 66 28 20 70 3d 3d  d = 0;.  if( p==
25a0: 30 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20  0 ) return 0;.  
25b0: 69 66 28 20 70 3e 3d 70 63 61 63 68 65 31 2e 70  if( p>=pcache1.p
25c0: 53 74 61 72 74 20 26 26 20 70 3c 70 63 61 63 68  Start && p<pcach
25d0: 65 31 2e 70 45 6e 64 20 29 7b 0a 20 20 20 20 50  e1.pEnd ){.    P
25e0: 67 46 72 65 65 73 6c 6f 74 20 2a 70 53 6c 6f 74  gFreeslot *pSlot
25f0: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 75  ;.    sqlite3_mu
2600: 74 65 78 5f 65 6e 74 65 72 28 70 63 61 63 68 65  tex_enter(pcache
2610: 31 2e 6d 75 74 65 78 29 3b 0a 20 20 20 20 73 71  1.mutex);.    sq
2620: 6c 69 74 65 33 53 74 61 74 75 73 44 6f 77 6e 28  lite3StatusDown(
2630: 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41  SQLITE_STATUS_PA
2640: 47 45 43 41 43 48 45 5f 55 53 45 44 2c 20 31 29  GECACHE_USED, 1)
2650: 3b 0a 20 20 20 20 70 53 6c 6f 74 20 3d 20 28 50  ;.    pSlot = (P
2660: 67 46 72 65 65 73 6c 6f 74 2a 29 70 3b 0a 20 20  gFreeslot*)p;.  
2670: 20 20 70 53 6c 6f 74 2d 3e 70 4e 65 78 74 20 3d    pSlot->pNext =
2680: 20 70 63 61 63 68 65 31 2e 70 46 72 65 65 3b 0a   pcache1.pFree;.
2690: 20 20 20 20 70 63 61 63 68 65 31 2e 70 46 72 65      pcache1.pFre
26a0: 65 20 3d 20 70 53 6c 6f 74 3b 0a 20 20 20 20 70  e = pSlot;.    p
26b0: 63 61 63 68 65 31 2e 6e 46 72 65 65 53 6c 6f 74  cache1.nFreeSlot
26c0: 2b 2b 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e  ++;.    pcache1.
26d0: 62 55 6e 64 65 72 50 72 65 73 73 75 72 65 20 3d  bUnderPressure =
26e0: 20 70 63 61 63 68 65 31 2e 6e 46 72 65 65 53 6c   pcache1.nFreeSl
26f0: 6f 74 3c 70 63 61 63 68 65 31 2e 6e 52 65 73 65  ot<pcache1.nRese
2700: 72 76 65 3b 0a 20 20 20 20 61 73 73 65 72 74 28  rve;.    assert(
2710: 20 70 63 61 63 68 65 31 2e 6e 46 72 65 65 53 6c   pcache1.nFreeSl
2720: 6f 74 3c 3d 70 63 61 63 68 65 31 2e 6e 53 6c 6f  ot<=pcache1.nSlo
2730: 74 20 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  t );.    sqlite3
2740: 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 70 63 61  _mutex_leave(pca
2750: 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a 20 20 7d  che1.mutex);.  }
2760: 65 6c 73 65 7b 0a 20 20 20 20 61 73 73 65 72 74  else{.    assert
2770: 28 20 73 71 6c 69 74 65 33 4d 65 6d 64 65 62 75  ( sqlite3Memdebu
2780: 67 48 61 73 54 79 70 65 28 70 2c 20 4d 45 4d 54  gHasType(p, MEMT
2790: 59 50 45 5f 50 43 41 43 48 45 29 20 29 3b 0a 20  YPE_PCACHE) );. 
27a0: 20 20 20 73 71 6c 69 74 65 33 4d 65 6d 64 65 62     sqlite3Memdeb
27b0: 75 67 53 65 74 54 79 70 65 28 70 2c 20 4d 45 4d  ugSetType(p, MEM
27c0: 54 59 50 45 5f 48 45 41 50 29 3b 0a 20 20 20 20  TYPE_HEAP);.    
27d0: 6e 46 72 65 65 64 20 3d 20 73 71 6c 69 74 65 33  nFreed = sqlite3
27e0: 4d 61 6c 6c 6f 63 53 69 7a 65 28 70 29 3b 0a 23  MallocSize(p);.#
27f0: 69 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 44 49  ifndef SQLITE_DI
2800: 53 41 42 4c 45 5f 50 41 47 45 43 41 43 48 45 5f  SABLE_PAGECACHE_
2810: 4f 56 45 52 46 4c 4f 57 5f 53 54 41 54 53 0a 20  OVERFLOW_STATS. 
2820: 20 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78     sqlite3_mutex
2830: 5f 65 6e 74 65 72 28 70 63 61 63 68 65 31 2e 6d  _enter(pcache1.m
2840: 75 74 65 78 29 3b 0a 20 20 20 20 73 71 6c 69 74  utex);.    sqlit
2850: 65 33 53 74 61 74 75 73 44 6f 77 6e 28 53 51 4c  e3StatusDown(SQL
2860: 49 54 45 5f 53 54 41 54 55 53 5f 50 41 47 45 43  ITE_STATUS_PAGEC
2870: 41 43 48 45 5f 4f 56 45 52 46 4c 4f 57 2c 20 6e  ACHE_OVERFLOW, n
2880: 46 72 65 65 64 29 3b 0a 20 20 20 20 73 71 6c 69  Freed);.    sqli
2890: 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28  te3_mutex_leave(
28a0: 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a  pcache1.mutex);.
28b0: 23 65 6e 64 69 66 0a 20 20 20 20 73 71 6c 69 74  #endif.    sqlit
28c0: 65 33 5f 66 72 65 65 28 70 29 3b 0a 20 20 7d 0a  e3_free(p);.  }.
28d0: 20 20 72 65 74 75 72 6e 20 6e 46 72 65 65 64 3b    return nFreed;
28e0: 0a 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54  .}..#ifdef SQLIT
28f0: 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f  E_ENABLE_MEMORY_
2900: 4d 41 4e 41 47 45 4d 45 4e 54 0a 2f 2a 0a 2a 2a  MANAGEMENT./*.**
2910: 20 52 65 74 75 72 6e 20 74 68 65 20 73 69 7a 65   Return the size
2920: 20 6f 66 20 61 20 70 63 61 63 68 65 20 61 6c 6c   of a pcache all
2930: 6f 63 61 74 69 6f 6e 0a 2a 2f 0a 73 74 61 74 69  ocation.*/.stati
2940: 63 20 69 6e 74 20 70 63 61 63 68 65 31 4d 65 6d  c int pcache1Mem
2950: 53 69 7a 65 28 76 6f 69 64 20 2a 70 29 7b 0a 20  Size(void *p){. 
2960: 20 69 66 28 20 70 3e 3d 70 63 61 63 68 65 31 2e   if( p>=pcache1.
2970: 70 53 74 61 72 74 20 26 26 20 70 3c 70 63 61 63  pStart && p<pcac
2980: 68 65 31 2e 70 45 6e 64 20 29 7b 0a 20 20 20 20  he1.pEnd ){.    
2990: 72 65 74 75 72 6e 20 70 63 61 63 68 65 31 2e 73  return pcache1.s
29a0: 7a 53 6c 6f 74 3b 0a 20 20 7d 65 6c 73 65 7b 0a  zSlot;.  }else{.
29b0: 20 20 20 20 69 6e 74 20 69 53 69 7a 65 3b 0a 20      int iSize;. 
29c0: 20 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74     assert( sqlit
29d0: 65 33 4d 65 6d 64 65 62 75 67 48 61 73 54 79 70  e3MemdebugHasTyp
29e0: 65 28 70 2c 20 4d 45 4d 54 59 50 45 5f 50 43 41  e(p, MEMTYPE_PCA
29f0: 43 48 45 29 20 29 3b 0a 20 20 20 20 73 71 6c 69  CHE) );.    sqli
2a00: 74 65 33 4d 65 6d 64 65 62 75 67 53 65 74 54 79  te3MemdebugSetTy
2a10: 70 65 28 70 2c 20 4d 45 4d 54 59 50 45 5f 48 45  pe(p, MEMTYPE_HE
2a20: 41 50 29 3b 0a 20 20 20 20 69 53 69 7a 65 20 3d  AP);.    iSize =
2a30: 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 53 69   sqlite3MallocSi
2a40: 7a 65 28 70 29 3b 0a 20 20 20 20 73 71 6c 69 74  ze(p);.    sqlit
2a50: 65 33 4d 65 6d 64 65 62 75 67 53 65 74 54 79 70  e3MemdebugSetTyp
2a60: 65 28 70 2c 20 4d 45 4d 54 59 50 45 5f 50 43 41  e(p, MEMTYPE_PCA
2a70: 43 48 45 29 3b 0a 20 20 20 20 72 65 74 75 72 6e  CHE);.    return
2a80: 20 69 53 69 7a 65 3b 0a 20 20 7d 0a 7d 0a 23 65   iSize;.  }.}.#e
2a90: 6e 64 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f 45  ndif /* SQLITE_E
2aa0: 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e  NABLE_MEMORY_MAN
2ab0: 41 47 45 4d 45 4e 54 20 2a 2f 0a 0a 2f 2a 0a 2a  AGEMENT */../*.*
2ac0: 2a 20 41 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77  * Allocate a new
2ad0: 20 70 61 67 65 20 6f 62 6a 65 63 74 20 69 6e 69   page object ini
2ae0: 74 69 61 6c 6c 79 20 61 73 73 6f 63 69 61 74 65  tially associate
2af0: 64 20 77 69 74 68 20 63 61 63 68 65 20 70 43 61  d with cache pCa
2b00: 63 68 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 50  che..*/.static P
2b10: 67 48 64 72 31 20 2a 70 63 61 63 68 65 31 41 6c  gHdr1 *pcache1Al
2b20: 6c 6f 63 50 61 67 65 28 50 43 61 63 68 65 31 20  locPage(PCache1 
2b30: 2a 70 43 61 63 68 65 29 7b 0a 20 20 50 67 48 64  *pCache){.  PgHd
2b40: 72 31 20 2a 70 20 3d 20 30 3b 0a 20 20 76 6f 69  r1 *p = 0;.  voi
2b50: 64 20 2a 70 50 67 3b 0a 0a 20 20 2f 2a 20 54 68  d *pPg;..  /* Th
2b60: 65 20 67 72 6f 75 70 20 6d 75 74 65 78 20 6d 75  e group mutex mu
2b70: 73 74 20 62 65 20 72 65 6c 65 61 73 65 64 20 62  st be released b
2b80: 65 66 6f 72 65 20 70 63 61 63 68 65 31 41 6c 6c  efore pcache1All
2b90: 6f 63 28 29 20 69 73 20 63 61 6c 6c 65 64 2e 20  oc() is called. 
2ba0: 54 68 69 73 0a 20 20 2a 2a 20 69 73 20 62 65 63  This.  ** is bec
2bb0: 61 75 73 65 20 69 74 20 6d 61 79 20 63 61 6c 6c  ause it may call
2bc0: 20 73 71 6c 69 74 65 33 5f 72 65 6c 65 61 73 65   sqlite3_release
2bd0: 5f 6d 65 6d 6f 72 79 28 29 2c 20 77 68 69 63 68  _memory(), which
2be0: 20 61 73 73 75 6d 65 73 20 74 68 61 74 20 0a 20   assumes that . 
2bf0: 20 2a 2a 20 74 68 69 73 20 6d 75 74 65 78 20 69   ** this mutex i
2c00: 73 20 6e 6f 74 20 68 65 6c 64 2e 20 2a 2f 0a 20  s not held. */. 
2c10: 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33   assert( sqlite3
2c20: 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 43 61 63  _mutex_held(pCac
2c30: 68 65 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75 74 65  he->pGroup->mute
2c40: 78 29 20 29 3b 0a 20 20 70 63 61 63 68 65 31 4c  x) );.  pcache1L
2c50: 65 61 76 65 4d 75 74 65 78 28 70 43 61 63 68 65  eaveMutex(pCache
2c60: 2d 3e 70 47 72 6f 75 70 29 3b 0a 23 69 66 64 65  ->pGroup);.#ifde
2c70: 66 20 53 51 4c 49 54 45 5f 50 43 41 43 48 45 5f  f SQLITE_PCACHE_
2c80: 53 45 50 41 52 41 54 45 5f 48 45 41 44 45 52 0a  SEPARATE_HEADER.
2c90: 20 20 70 50 67 20 3d 20 70 63 61 63 68 65 31 41    pPg = pcache1A
2ca0: 6c 6c 6f 63 28 70 43 61 63 68 65 2d 3e 73 7a 50  lloc(pCache->szP
2cb0: 61 67 65 29 3b 0a 20 20 70 20 3d 20 73 71 6c 69  age);.  p = sqli
2cc0: 74 65 33 4d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66  te3Malloc(sizeof
2cd0: 28 50 67 48 64 72 31 29 20 2b 20 70 43 61 63 68  (PgHdr1) + pCach
2ce0: 65 2d 3e 73 7a 45 78 74 72 61 29 3b 0a 20 20 69  e->szExtra);.  i
2cf0: 66 28 20 21 70 50 67 20 7c 7c 20 21 70 20 29 7b  f( !pPg || !p ){
2d00: 0a 20 20 20 20 70 63 61 63 68 65 31 46 72 65 65  .    pcache1Free
2d10: 28 70 50 67 29 3b 0a 20 20 20 20 73 71 6c 69 74  (pPg);.    sqlit
2d20: 65 33 5f 66 72 65 65 28 70 29 3b 0a 20 20 20 20  e3_free(p);.    
2d30: 70 50 67 20 3d 20 30 3b 0a 20 20 7d 0a 23 65 6c  pPg = 0;.  }.#el
2d40: 73 65 0a 20 20 70 50 67 20 3d 20 70 63 61 63 68  se.  pPg = pcach
2d50: 65 31 41 6c 6c 6f 63 28 52 4f 55 4e 44 38 28 73  e1Alloc(ROUND8(s
2d60: 69 7a 65 6f 66 28 50 67 48 64 72 31 29 29 20 2b  izeof(PgHdr1)) +
2d70: 20 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 20   pCache->szPage 
2d80: 2b 20 70 43 61 63 68 65 2d 3e 73 7a 45 78 74 72  + pCache->szExtr
2d90: 61 29 3b 0a 20 20 70 20 3d 20 28 50 67 48 64 72  a);.  p = (PgHdr
2da0: 31 20 2a 29 26 28 28 75 38 20 2a 29 70 50 67 29  1 *)&((u8 *)pPg)
2db0: 5b 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 5d  [pCache->szPage]
2dc0: 3b 0a 23 65 6e 64 69 66 0a 20 20 70 63 61 63 68  ;.#endif.  pcach
2dd0: 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70 43 61  e1EnterMutex(pCa
2de0: 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 0a 20  che->pGroup);.. 
2df0: 20 69 66 28 20 70 50 67 20 29 7b 0a 20 20 20 20   if( pPg ){.    
2e00: 70 2d 3e 70 61 67 65 2e 70 42 75 66 20 3d 20 70  p->page.pBuf = p
2e10: 50 67 3b 0a 20 20 20 20 70 2d 3e 70 61 67 65 2e  Pg;.    p->page.
2e20: 70 45 78 74 72 61 20 3d 20 26 70 5b 31 5d 3b 0a  pExtra = &p[1];.
2e30: 20 20 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e      if( pCache->
2e40: 62 50 75 72 67 65 61 62 6c 65 20 29 7b 0a 20 20  bPurgeable ){.  
2e50: 20 20 20 20 70 43 61 63 68 65 2d 3e 70 47 72 6f      pCache->pGro
2e60: 75 70 2d 3e 6e 43 75 72 72 65 6e 74 50 61 67 65  up->nCurrentPage
2e70: 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72 65  ++;.    }.    re
2e80: 74 75 72 6e 20 70 3b 0a 20 20 7d 0a 20 20 72 65  turn p;.  }.  re
2e90: 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  turn 0;.}../*.**
2ea0: 20 46 72 65 65 20 61 20 70 61 67 65 20 6f 62 6a   Free a page obj
2eb0: 65 63 74 20 61 6c 6c 6f 63 61 74 65 64 20 62 79  ect allocated by
2ec0: 20 70 63 61 63 68 65 31 41 6c 6c 6f 63 50 61 67   pcache1AllocPag
2ed0: 65 28 29 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 70  e()..**.** The p
2ee0: 6f 69 6e 74 65 72 20 69 73 20 61 6c 6c 6f 77 65  ointer is allowe
2ef0: 64 20 74 6f 20 62 65 20 4e 55 4c 4c 2c 20 77 68  d to be NULL, wh
2f00: 69 63 68 20 69 73 20 70 72 75 64 65 6e 74 2e 20  ich is prudent. 
2f10: 20 42 75 74 20 69 74 20 74 75 72 6e 73 20 6f 75   But it turns ou
2f20: 74 0a 2a 2a 20 74 68 61 74 20 74 68 65 20 63 75  t.** that the cu
2f30: 72 72 65 6e 74 20 69 6d 70 6c 65 6d 65 6e 74 61  rrent implementa
2f40: 74 69 6f 6e 20 68 61 70 70 65 6e 73 20 74 6f 20  tion happens to 
2f50: 6e 65 76 65 72 20 63 61 6c 6c 20 74 68 69 73 20  never call this 
2f60: 72 6f 75 74 69 6e 65 0a 2a 2a 20 77 69 74 68 20  routine.** with 
2f70: 61 20 4e 55 4c 4c 20 70 6f 69 6e 74 65 72 2c 20  a NULL pointer, 
2f80: 73 6f 20 77 65 20 6d 61 72 6b 20 74 68 65 20 4e  so we mark the N
2f90: 55 4c 4c 20 74 65 73 74 20 77 69 74 68 20 41 4c  ULL test with AL
2fa0: 57 41 59 53 28 29 2e 0a 2a 2f 0a 73 74 61 74 69  WAYS()..*/.stati
2fb0: 63 20 76 6f 69 64 20 70 63 61 63 68 65 31 46 72  c void pcache1Fr
2fc0: 65 65 50 61 67 65 28 50 67 48 64 72 31 20 2a 70  eePage(PgHdr1 *p
2fd0: 29 7b 0a 20 20 69 66 28 20 41 4c 57 41 59 53 28  ){.  if( ALWAYS(
2fe0: 70 29 20 29 7b 0a 20 20 20 20 50 43 61 63 68 65  p) ){.    PCache
2ff0: 31 20 2a 70 43 61 63 68 65 20 3d 20 70 2d 3e 70  1 *pCache = p->p
3000: 43 61 63 68 65 3b 0a 20 20 20 20 61 73 73 65 72  Cache;.    asser
3010: 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78  t( sqlite3_mutex
3020: 5f 68 65 6c 64 28 70 2d 3e 70 43 61 63 68 65 2d  _held(p->pCache-
3030: 3e 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78 29 20  >pGroup->mutex) 
3040: 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31 46 72  );.    pcache1Fr
3050: 65 65 28 70 2d 3e 70 61 67 65 2e 70 42 75 66 29  ee(p->page.pBuf)
3060: 3b 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f  ;.#ifdef SQLITE_
3070: 50 43 41 43 48 45 5f 53 45 50 41 52 41 54 45 5f  PCACHE_SEPARATE_
3080: 48 45 41 44 45 52 0a 20 20 20 20 73 71 6c 69 74  HEADER.    sqlit
3090: 65 33 5f 66 72 65 65 28 70 29 3b 0a 23 65 6e 64  e3_free(p);.#end
30a0: 69 66 0a 20 20 20 20 69 66 28 20 70 43 61 63 68  if.    if( pCach
30b0: 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 29 7b  e->bPurgeable ){
30c0: 0a 20 20 20 20 20 20 70 43 61 63 68 65 2d 3e 70  .      pCache->p
30d0: 47 72 6f 75 70 2d 3e 6e 43 75 72 72 65 6e 74 50  Group->nCurrentP
30e0: 61 67 65 2d 2d 3b 0a 20 20 20 20 7d 0a 20 20 7d  age--;.    }.  }
30f0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6c 6c 6f 63  .}../*.** Malloc
3100: 20 66 75 6e 63 74 69 6f 6e 20 75 73 65 64 20 62   function used b
3110: 79 20 53 51 4c 69 74 65 20 74 6f 20 6f 62 74 61  y SQLite to obta
3120: 69 6e 20 73 70 61 63 65 20 66 72 6f 6d 20 74 68  in space from th
3130: 65 20 62 75 66 66 65 72 20 63 6f 6e 66 69 67 75  e buffer configu
3140: 72 65 64 0a 2a 2a 20 75 73 69 6e 67 20 73 71 6c  red.** using sql
3150: 69 74 65 33 5f 63 6f 6e 66 69 67 28 53 51 4c 49  ite3_config(SQLI
3160: 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41  TE_CONFIG_PAGECA
3170: 43 48 45 29 20 6f 70 74 69 6f 6e 2e 20 49 66 20  CHE) option. If 
3180: 6e 6f 20 73 75 63 68 20 62 75 66 66 65 72 0a 2a  no such buffer.*
3190: 2a 20 65 78 69 73 74 73 2c 20 74 68 69 73 20 66  * exists, this f
31a0: 75 6e 63 74 69 6f 6e 20 66 61 6c 6c 73 20 62 61  unction falls ba
31b0: 63 6b 20 74 6f 20 73 71 6c 69 74 65 33 4d 61 6c  ck to sqlite3Mal
31c0: 6c 6f 63 28 29 2e 0a 2a 2f 0a 76 6f 69 64 20 2a  loc()..*/.void *
31d0: 73 71 6c 69 74 65 33 50 61 67 65 4d 61 6c 6c 6f  sqlite3PageMallo
31e0: 63 28 69 6e 74 20 73 7a 29 7b 0a 20 20 72 65 74  c(int sz){.  ret
31f0: 75 72 6e 20 70 63 61 63 68 65 31 41 6c 6c 6f 63  urn pcache1Alloc
3200: 28 73 7a 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46  (sz);.}../*.** F
3210: 72 65 65 20 61 6e 20 61 6c 6c 6f 63 61 74 65 64  ree an allocated
3220: 20 62 75 66 66 65 72 20 6f 62 74 61 69 6e 65 64   buffer obtained
3230: 20 66 72 6f 6d 20 73 71 6c 69 74 65 33 50 61 67   from sqlite3Pag
3240: 65 4d 61 6c 6c 6f 63 28 29 2e 0a 2a 2f 0a 76 6f  eMalloc()..*/.vo
3250: 69 64 20 73 71 6c 69 74 65 33 50 61 67 65 46 72  id sqlite3PageFr
3260: 65 65 28 76 6f 69 64 20 2a 70 29 7b 0a 20 20 70  ee(void *p){.  p
3270: 63 61 63 68 65 31 46 72 65 65 28 70 29 3b 0a 7d  cache1Free(p);.}
3280: 0a 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20  .../*.** Return 
3290: 74 72 75 65 20 69 66 20 69 74 20 64 65 73 69 72  true if it desir
32a0: 61 62 6c 65 20 74 6f 20 61 76 6f 69 64 20 61 6c  able to avoid al
32b0: 6c 6f 63 61 74 69 6e 67 20 61 20 6e 65 77 20 70  locating a new p
32c0: 61 67 65 20 63 61 63 68 65 0a 2a 2a 20 65 6e 74  age cache.** ent
32d0: 72 79 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 6d 65 6d  ry..**.** If mem
32e0: 6f 72 79 20 77 61 73 20 61 6c 6c 6f 63 61 74 65  ory was allocate
32f0: 64 20 73 70 65 63 69 66 69 63 61 6c 6c 79 20 74  d specifically t
3300: 6f 20 74 68 65 20 70 61 67 65 20 63 61 63 68 65  o the page cache
3310: 20 75 73 69 6e 67 0a 2a 2a 20 53 51 4c 49 54 45   using.** SQLITE
3320: 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48  _CONFIG_PAGECACH
3330: 45 20 62 75 74 20 74 68 61 74 20 6d 65 6d 6f 72  E but that memor
3340: 79 20 68 61 73 20 61 6c 6c 20 62 65 65 6e 20 75  y has all been u
3350: 73 65 64 2c 20 74 68 65 6e 0a 2a 2a 20 69 74 20  sed, then.** it 
3360: 69 73 20 64 65 73 69 72 61 62 6c 65 20 74 6f 20  is desirable to 
3370: 61 76 6f 69 64 20 61 6c 6c 6f 63 61 74 69 6e 67  avoid allocating
3380: 20 61 20 6e 65 77 20 70 61 67 65 20 63 61 63 68   a new page cach
3390: 65 20 65 6e 74 72 79 20 62 65 63 61 75 73 65 0a  e entry because.
33a0: 2a 2a 20 70 72 65 73 75 6d 61 62 6c 79 20 53 51  ** presumably SQ
33b0: 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47 45  LITE_CONFIG_PAGE
33c0: 43 41 43 48 45 20 77 61 73 20 73 75 70 70 6f 73  CACHE was suppos
33d0: 65 20 74 6f 20 62 65 20 73 75 66 66 69 63 69 65  e to be sufficie
33e0: 6e 74 0a 2a 2a 20 66 6f 72 20 61 6c 6c 20 70 61  nt.** for all pa
33f0: 67 65 20 63 61 63 68 65 20 6e 65 65 64 73 20 61  ge cache needs a
3400: 6e 64 20 77 65 20 73 68 6f 75 6c 64 20 6e 6f 74  nd we should not
3410: 20 6e 65 65 64 20 74 6f 20 73 70 69 6c 6c 20 74   need to spill t
3420: 68 65 0a 2a 2a 20 61 6c 6c 6f 63 61 74 69 6f 6e  he.** allocation
3430: 20 6f 6e 74 6f 20 74 68 65 20 68 65 61 70 2e 0a   onto the heap..
3440: 2a 2a 0a 2a 2a 20 4f 72 2c 20 74 68 65 20 68 65  **.** Or, the he
3450: 61 70 20 69 73 20 75 73 65 64 20 66 6f 72 20 61  ap is used for a
3460: 6c 6c 20 70 61 67 65 20 63 61 63 68 65 20 6d 65  ll page cache me
3470: 6d 6f 72 79 20 62 75 74 20 74 68 65 20 68 65 61  mory but the hea
3480: 70 20 69 73 0a 2a 2a 20 75 6e 64 65 72 20 6d 65  p is.** under me
3490: 6d 6f 72 79 20 70 72 65 73 73 75 72 65 2c 20 74  mory pressure, t
34a0: 68 65 6e 20 61 67 61 69 6e 20 69 74 20 69 73 20  hen again it is 
34b0: 64 65 73 69 72 61 62 6c 65 20 74 6f 20 61 76 6f  desirable to avo
34c0: 69 64 0a 2a 2a 20 61 6c 6c 6f 63 61 74 69 6e 67  id.** allocating
34d0: 20 61 20 6e 65 77 20 70 61 67 65 20 63 61 63 68   a new page cach
34e0: 65 20 65 6e 74 72 79 20 69 6e 20 6f 72 64 65 72  e entry in order
34f0: 20 74 6f 20 61 76 6f 69 64 20 73 74 72 65 73 73   to avoid stress
3500: 69 6e 67 0a 2a 2a 20 74 68 65 20 68 65 61 70 20  ing.** the heap 
3510: 65 76 65 6e 20 66 75 72 74 68 65 72 2e 0a 2a 2f  even further..*/
3520: 0a 73 74 61 74 69 63 20 69 6e 74 20 70 63 61 63  .static int pcac
3530: 68 65 31 55 6e 64 65 72 4d 65 6d 6f 72 79 50 72  he1UnderMemoryPr
3540: 65 73 73 75 72 65 28 50 43 61 63 68 65 31 20 2a  essure(PCache1 *
3550: 70 43 61 63 68 65 29 7b 0a 20 20 69 66 28 20 70  pCache){.  if( p
3560: 63 61 63 68 65 31 2e 6e 53 6c 6f 74 20 26 26 20  cache1.nSlot && 
3570: 28 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 2b  (pCache->szPage+
3580: 70 43 61 63 68 65 2d 3e 73 7a 45 78 74 72 61 29  pCache->szExtra)
3590: 3c 3d 70 63 61 63 68 65 31 2e 73 7a 53 6c 6f 74  <=pcache1.szSlot
35a0: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 70   ){.    return p
35b0: 63 61 63 68 65 31 2e 62 55 6e 64 65 72 50 72 65  cache1.bUnderPre
35c0: 73 73 75 72 65 3b 0a 20 20 7d 65 6c 73 65 7b 0a  ssure;.  }else{.
35d0: 20 20 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74      return sqlit
35e0: 65 33 48 65 61 70 4e 65 61 72 6c 79 46 75 6c 6c  e3HeapNearlyFull
35f0: 28 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 2a 2a 2a  ();.  }.}../****
3600: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3610: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3620: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3630: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3640: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 2a 2a  **********/./***
3650: 2a 2a 2a 2a 2a 20 47 65 6e 65 72 61 6c 20 49 6d  ***** General Im
3660: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 46 75 6e  plementation Fun
3670: 63 74 69 6f 6e 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a  ctions *********
3680: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3690: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f 2a  ***********/../*
36a0: 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
36b0: 6e 20 69 73 20 75 73 65 64 20 74 6f 20 72 65 73  n is used to res
36c0: 69 7a 65 20 74 68 65 20 68 61 73 68 20 74 61 62  ize the hash tab
36d0: 6c 65 20 75 73 65 64 20 62 79 20 74 68 65 20 63  le used by the c
36e0: 61 63 68 65 20 70 61 73 73 65 64 0a 2a 2a 20 61  ache passed.** a
36f0: 73 20 74 68 65 20 66 69 72 73 74 20 61 72 67 75  s the first argu
3700: 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  ment..**.** The 
3710: 50 43 61 63 68 65 20 6d 75 74 65 78 20 6d 75 73  PCache mutex mus
3720: 74 20 62 65 20 68 65 6c 64 20 77 68 65 6e 20 74  t be held when t
3730: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
3740: 63 61 6c 6c 65 64 2e 0a 2a 2f 0a 73 74 61 74 69  called..*/.stati
3750: 63 20 76 6f 69 64 20 70 63 61 63 68 65 31 52 65  c void pcache1Re
3760: 73 69 7a 65 48 61 73 68 28 50 43 61 63 68 65 31  sizeHash(PCache1
3770: 20 2a 70 29 7b 0a 20 20 50 67 48 64 72 31 20 2a   *p){.  PgHdr1 *
3780: 2a 61 70 4e 65 77 3b 0a 20 20 75 6e 73 69 67 6e  *apNew;.  unsign
3790: 65 64 20 69 6e 74 20 6e 4e 65 77 3b 0a 20 20 75  ed int nNew;.  u
37a0: 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 3b 0a 0a  nsigned int i;..
37b0: 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65    assert( sqlite
37c0: 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 2d 3e  3_mutex_held(p->
37d0: 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78 29 20 29  pGroup->mutex) )
37e0: 3b 0a 0a 20 20 6e 4e 65 77 20 3d 20 70 2d 3e 6e  ;..  nNew = p->n
37f0: 48 61 73 68 2a 32 3b 0a 20 20 69 66 28 20 6e 4e  Hash*2;.  if( nN
3800: 65 77 3c 32 35 36 20 29 7b 0a 20 20 20 20 6e 4e  ew<256 ){.    nN
3810: 65 77 20 3d 20 32 35 36 3b 0a 20 20 7d 0a 0a 20  ew = 256;.  }.. 
3820: 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74   pcache1LeaveMut
3830: 65 78 28 70 2d 3e 70 47 72 6f 75 70 29 3b 0a 20  ex(p->pGroup);. 
3840: 20 69 66 28 20 70 2d 3e 6e 48 61 73 68 20 29 7b   if( p->nHash ){
3850: 20 73 71 6c 69 74 65 33 42 65 67 69 6e 42 65 6e   sqlite3BeginBen
3860: 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 20 7d 0a 20  ignMalloc(); }. 
3870: 20 61 70 4e 65 77 20 3d 20 28 50 67 48 64 72 31   apNew = (PgHdr1
3880: 20 2a 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f   **)sqlite3Mallo
3890: 63 5a 65 72 6f 28 73 69 7a 65 6f 66 28 50 67 48  cZero(sizeof(PgH
38a0: 64 72 31 20 2a 29 2a 6e 4e 65 77 29 3b 0a 20 20  dr1 *)*nNew);.  
38b0: 69 66 28 20 70 2d 3e 6e 48 61 73 68 20 29 7b 20  if( p->nHash ){ 
38c0: 73 71 6c 69 74 65 33 45 6e 64 42 65 6e 69 67 6e  sqlite3EndBenign
38d0: 4d 61 6c 6c 6f 63 28 29 3b 20 7d 0a 20 20 70 63  Malloc(); }.  pc
38e0: 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28  ache1EnterMutex(
38f0: 70 2d 3e 70 47 72 6f 75 70 29 3b 0a 20 20 69 66  p->pGroup);.  if
3900: 28 20 61 70 4e 65 77 20 29 7b 0a 20 20 20 20 66  ( apNew ){.    f
3910: 6f 72 28 69 3d 30 3b 20 69 3c 70 2d 3e 6e 48 61  or(i=0; i<p->nHa
3920: 73 68 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  sh; i++){.      
3930: 50 67 48 64 72 31 20 2a 70 50 61 67 65 3b 0a 20  PgHdr1 *pPage;. 
3940: 20 20 20 20 20 50 67 48 64 72 31 20 2a 70 4e 65       PgHdr1 *pNe
3950: 78 74 20 3d 20 70 2d 3e 61 70 48 61 73 68 5b 69  xt = p->apHash[i
3960: 5d 3b 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20  ];.      while( 
3970: 28 70 50 61 67 65 20 3d 20 70 4e 65 78 74 29 21  (pPage = pNext)!
3980: 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 75 6e  =0 ){.        un
3990: 73 69 67 6e 65 64 20 69 6e 74 20 68 20 3d 20 70  signed int h = p
39a0: 50 61 67 65 2d 3e 69 4b 65 79 20 25 20 6e 4e 65  Page->iKey % nNe
39b0: 77 3b 0a 20 20 20 20 20 20 20 20 70 4e 65 78 74  w;.        pNext
39c0: 20 3d 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 3b   = pPage->pNext;
39d0: 0a 20 20 20 20 20 20 20 20 70 50 61 67 65 2d 3e  .        pPage->
39e0: 70 4e 65 78 74 20 3d 20 61 70 4e 65 77 5b 68 5d  pNext = apNew[h]
39f0: 3b 0a 20 20 20 20 20 20 20 20 61 70 4e 65 77 5b  ;.        apNew[
3a00: 68 5d 20 3d 20 70 50 61 67 65 3b 0a 20 20 20 20  h] = pPage;.    
3a10: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 73 71    }.    }.    sq
3a20: 6c 69 74 65 33 5f 66 72 65 65 28 70 2d 3e 61 70  lite3_free(p->ap
3a30: 48 61 73 68 29 3b 0a 20 20 20 20 70 2d 3e 61 70  Hash);.    p->ap
3a40: 48 61 73 68 20 3d 20 61 70 4e 65 77 3b 0a 20 20  Hash = apNew;.  
3a50: 20 20 70 2d 3e 6e 48 61 73 68 20 3d 20 6e 4e 65    p->nHash = nNe
3a60: 77 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  w;.  }.}../*.** 
3a70: 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73  This function is
3a80: 20 75 73 65 64 20 69 6e 74 65 72 6e 61 6c 6c 79   used internally
3a90: 20 74 6f 20 72 65 6d 6f 76 65 20 74 68 65 20 70   to remove the p
3aa0: 61 67 65 20 70 50 61 67 65 20 66 72 6f 6d 20 74  age pPage from t
3ab0: 68 65 20 0a 2a 2a 20 50 47 72 6f 75 70 20 4c 52  he .** PGroup LR
3ac0: 55 20 6c 69 73 74 2c 20 69 66 20 69 73 20 70 61  U list, if is pa
3ad0: 72 74 20 6f 66 20 69 74 2e 20 49 66 20 70 50 61  rt of it. If pPa
3ae0: 67 65 20 69 73 20 6e 6f 74 20 70 61 72 74 20 6f  ge is not part o
3af0: 66 20 74 68 65 20 50 47 72 6f 75 70 0a 2a 2a 20  f the PGroup.** 
3b00: 4c 52 55 20 6c 69 73 74 2c 20 74 68 65 6e 20 74  LRU list, then t
3b10: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
3b20: 61 20 6e 6f 2d 6f 70 2e 0a 2a 2a 0a 2a 2a 20 54  a no-op..**.** T
3b30: 68 65 20 50 47 72 6f 75 70 20 6d 75 74 65 78 20  he PGroup mutex 
3b40: 6d 75 73 74 20 62 65 20 68 65 6c 64 20 77 68 65  must be held whe
3b50: 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  n this function 
3b60: 69 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f 0a 73 74  is called..*/.st
3b70: 61 74 69 63 20 50 67 48 64 72 31 20 2a 70 63 61  atic PgHdr1 *pca
3b80: 63 68 65 31 50 69 6e 50 61 67 65 28 50 67 48 64  che1PinPage(PgHd
3b90: 72 31 20 2a 70 50 61 67 65 29 7b 0a 20 20 50 43  r1 *pPage){.  PC
3ba0: 61 63 68 65 31 20 2a 70 43 61 63 68 65 3b 0a 0a  ache1 *pCache;..
3bb0: 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65 21    assert( pPage!
3bc0: 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  =0 );.  assert( 
3bd0: 70 50 61 67 65 2d 3e 69 73 50 69 6e 6e 65 64 3d  pPage->isPinned=
3be0: 3d 30 20 29 3b 0a 20 20 70 43 61 63 68 65 20 3d  =0 );.  pCache =
3bf0: 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65 3b 0a   pPage->pCache;.
3c00: 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65 2d    assert( pPage-
3c10: 3e 70 4c 72 75 4e 65 78 74 20 7c 7c 20 70 50 61  >pLruNext || pPa
3c20: 67 65 3d 3d 70 43 61 63 68 65 2d 3e 70 47 72 6f  ge==pCache->pGro
3c30: 75 70 2d 3e 70 4c 72 75 54 61 69 6c 20 29 3b 0a  up->pLruTail );.
3c40: 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65 2d    assert( pPage-
3c50: 3e 70 4c 72 75 50 72 65 76 20 7c 7c 20 70 50 61  >pLruPrev || pPa
3c60: 67 65 3d 3d 70 43 61 63 68 65 2d 3e 70 47 72 6f  ge==pCache->pGro
3c70: 75 70 2d 3e 70 4c 72 75 48 65 61 64 20 29 3b 0a  up->pLruHead );.
3c80: 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65    assert( sqlite
3c90: 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 43 61  3_mutex_held(pCa
3ca0: 63 68 65 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75 74  che->pGroup->mut
3cb0: 65 78 29 20 29 3b 0a 20 20 69 66 28 20 70 50 61  ex) );.  if( pPa
3cc0: 67 65 2d 3e 70 4c 72 75 50 72 65 76 20 29 7b 0a  ge->pLruPrev ){.
3cd0: 20 20 20 20 70 50 61 67 65 2d 3e 70 4c 72 75 50      pPage->pLruP
3ce0: 72 65 76 2d 3e 70 4c 72 75 4e 65 78 74 20 3d 20  rev->pLruNext = 
3cf0: 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 3b  pPage->pLruNext;
3d00: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70 43  .  }else{.    pC
3d10: 61 63 68 65 2d 3e 70 47 72 6f 75 70 2d 3e 70 4c  ache->pGroup->pL
3d20: 72 75 48 65 61 64 20 3d 20 70 50 61 67 65 2d 3e  ruHead = pPage->
3d30: 70 4c 72 75 4e 65 78 74 3b 0a 20 20 7d 0a 20 20  pLruNext;.  }.  
3d40: 69 66 28 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e  if( pPage->pLruN
3d50: 65 78 74 20 29 7b 0a 20 20 20 20 70 50 61 67 65  ext ){.    pPage
3d60: 2d 3e 70 4c 72 75 4e 65 78 74 2d 3e 70 4c 72 75  ->pLruNext->pLru
3d70: 50 72 65 76 20 3d 20 70 50 61 67 65 2d 3e 70 4c  Prev = pPage->pL
3d80: 72 75 50 72 65 76 3b 0a 20 20 7d 65 6c 73 65 7b  ruPrev;.  }else{
3d90: 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 70 47 72  .    pCache->pGr
3da0: 6f 75 70 2d 3e 70 4c 72 75 54 61 69 6c 20 3d 20  oup->pLruTail = 
3db0: 70 50 61 67 65 2d 3e 70 4c 72 75 50 72 65 76 3b  pPage->pLruPrev;
3dc0: 0a 20 20 7d 0a 20 20 70 50 61 67 65 2d 3e 70 4c  .  }.  pPage->pL
3dd0: 72 75 4e 65 78 74 20 3d 20 30 3b 0a 20 20 70 50  ruNext = 0;.  pP
3de0: 61 67 65 2d 3e 70 4c 72 75 50 72 65 76 20 3d 20  age->pLruPrev = 
3df0: 30 3b 0a 20 20 70 50 61 67 65 2d 3e 69 73 50 69  0;.  pPage->isPi
3e00: 6e 6e 65 64 20 3d 20 31 3b 0a 20 20 70 43 61 63  nned = 1;.  pCac
3e10: 68 65 2d 3e 6e 52 65 63 79 63 6c 61 62 6c 65 2d  he->nRecyclable-
3e20: 2d 3b 0a 20 20 72 65 74 75 72 6e 20 70 50 61 67  -;.  return pPag
3e30: 65 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 52 65 6d  e;.}.../*.** Rem
3e40: 6f 76 65 20 74 68 65 20 70 61 67 65 20 73 75 70  ove the page sup
3e50: 70 6c 69 65 64 20 61 73 20 61 6e 20 61 72 67 75  plied as an argu
3e60: 6d 65 6e 74 20 66 72 6f 6d 20 74 68 65 20 68 61  ment from the ha
3e70: 73 68 20 74 61 62 6c 65 20 0a 2a 2a 20 28 50 43  sh table .** (PC
3e80: 61 63 68 65 31 2e 61 70 48 61 73 68 20 73 74 72  ache1.apHash str
3e90: 75 63 74 75 72 65 29 20 74 68 61 74 20 69 74 20  ucture) that it 
3ea0: 69 73 20 63 75 72 72 65 6e 74 6c 79 20 73 74 6f  is currently sto
3eb0: 72 65 64 20 69 6e 2e 0a 2a 2a 0a 2a 2a 20 54 68  red in..**.** Th
3ec0: 65 20 50 47 72 6f 75 70 20 6d 75 74 65 78 20 6d  e PGroup mutex m
3ed0: 75 73 74 20 62 65 20 68 65 6c 64 20 77 68 65 6e  ust be held when
3ee0: 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   this function i
3ef0: 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f 0a 73 74 61  s called..*/.sta
3f00: 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 31  tic void pcache1
3f10: 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73 68 28 50  RemoveFromHash(P
3f20: 67 48 64 72 31 20 2a 70 50 61 67 65 29 7b 0a 20  gHdr1 *pPage){. 
3f30: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 3b   unsigned int h;
3f40: 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63  .  PCache1 *pCac
3f50: 68 65 20 3d 20 70 50 61 67 65 2d 3e 70 43 61 63  he = pPage->pCac
3f60: 68 65 3b 0a 20 20 50 67 48 64 72 31 20 2a 2a 70  he;.  PgHdr1 **p
3f70: 70 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 73 71  p;..  assert( sq
3f80: 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64  lite3_mutex_held
3f90: 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 2d  (pCache->pGroup-
3fa0: 3e 6d 75 74 65 78 29 20 29 3b 0a 20 20 68 20 3d  >mutex) );.  h =
3fb0: 20 70 50 61 67 65 2d 3e 69 4b 65 79 20 25 20 70   pPage->iKey % p
3fc0: 43 61 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20  Cache->nHash;.  
3fd0: 66 6f 72 28 70 70 3d 26 70 43 61 63 68 65 2d 3e  for(pp=&pCache->
3fe0: 61 70 48 61 73 68 5b 68 5d 3b 20 28 2a 70 70 29  apHash[h]; (*pp)
3ff0: 21 3d 70 50 61 67 65 3b 20 70 70 3d 26 28 2a 70  !=pPage; pp=&(*p
4000: 70 29 2d 3e 70 4e 65 78 74 29 3b 0a 20 20 2a 70  p)->pNext);.  *p
4010: 70 20 3d 20 28 2a 70 70 29 2d 3e 70 4e 65 78 74  p = (*pp)->pNext
4020: 3b 0a 0a 20 20 70 43 61 63 68 65 2d 3e 6e 50 61  ;..  pCache->nPa
4030: 67 65 2d 2d 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49  ge--;.}../*.** I
4040: 66 20 74 68 65 72 65 20 61 72 65 20 63 75 72 72  f there are curr
4050: 65 6e 74 6c 79 20 6d 6f 72 65 20 74 68 61 6e 20  ently more than 
4060: 6e 4d 61 78 50 61 67 65 20 70 61 67 65 73 20 61  nMaxPage pages a
4070: 6c 6c 6f 63 61 74 65 64 2c 20 74 72 79 0a 2a 2a  llocated, try.**
4080: 20 74 6f 20 72 65 63 79 63 6c 65 20 70 61 67 65   to recycle page
4090: 73 20 74 6f 20 72 65 64 75 63 65 20 74 68 65 20  s to reduce the 
40a0: 6e 75 6d 62 65 72 20 61 6c 6c 6f 63 61 74 65 64  number allocated
40b0: 20 74 6f 20 6e 4d 61 78 50 61 67 65 2e 0a 2a 2f   to nMaxPage..*/
40c0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61  .static void pca
40d0: 63 68 65 31 45 6e 66 6f 72 63 65 4d 61 78 50 61  che1EnforceMaxPa
40e0: 67 65 28 50 47 72 6f 75 70 20 2a 70 47 72 6f 75  ge(PGroup *pGrou
40f0: 70 29 7b 0a 20 20 61 73 73 65 72 74 28 20 73 71  p){.  assert( sq
4100: 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64  lite3_mutex_held
4110: 28 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78 29 20  (pGroup->mutex) 
4120: 29 3b 0a 20 20 77 68 69 6c 65 28 20 70 47 72 6f  );.  while( pGro
4130: 75 70 2d 3e 6e 43 75 72 72 65 6e 74 50 61 67 65  up->nCurrentPage
4140: 3e 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67  >pGroup->nMaxPag
4150: 65 20 26 26 20 70 47 72 6f 75 70 2d 3e 70 4c 72  e && pGroup->pLr
4160: 75 54 61 69 6c 20 29 7b 0a 20 20 20 20 50 67 48  uTail ){.    PgH
4170: 64 72 31 20 2a 70 20 3d 20 70 47 72 6f 75 70 2d  dr1 *p = pGroup-
4180: 3e 70 4c 72 75 54 61 69 6c 3b 0a 20 20 20 20 61  >pLruTail;.    a
4190: 73 73 65 72 74 28 20 70 2d 3e 70 43 61 63 68 65  ssert( p->pCache
41a0: 2d 3e 70 47 72 6f 75 70 3d 3d 70 47 72 6f 75 70  ->pGroup==pGroup
41b0: 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20   );.    assert( 
41c0: 70 2d 3e 69 73 50 69 6e 6e 65 64 3d 3d 30 20 29  p->isPinned==0 )
41d0: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 50 69 6e  ;.    pcache1Pin
41e0: 50 61 67 65 28 70 29 3b 0a 20 20 20 20 70 63 61  Page(p);.    pca
41f0: 63 68 65 31 52 65 6d 6f 76 65 46 72 6f 6d 48 61  che1RemoveFromHa
4200: 73 68 28 70 29 3b 0a 20 20 20 20 70 63 61 63 68  sh(p);.    pcach
4210: 65 31 46 72 65 65 50 61 67 65 28 70 29 3b 0a 20  e1FreePage(p);. 
4220: 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 69 73 63   }.}../*.** Disc
4230: 61 72 64 20 61 6c 6c 20 70 61 67 65 73 20 66 72  ard all pages fr
4240: 6f 6d 20 63 61 63 68 65 20 70 43 61 63 68 65 20  om cache pCache 
4250: 77 69 74 68 20 61 20 70 61 67 65 20 6e 75 6d 62  with a page numb
4260: 65 72 20 28 6b 65 79 20 76 61 6c 75 65 29 20 0a  er (key value) .
4270: 2a 2a 20 67 72 65 61 74 65 72 20 74 68 61 6e 20  ** greater than 
4280: 6f 72 20 65 71 75 61 6c 20 74 6f 20 69 4c 69 6d  or equal to iLim
4290: 69 74 2e 20 41 6e 79 20 70 69 6e 6e 65 64 20 70  it. Any pinned p
42a0: 61 67 65 73 20 74 68 61 74 20 6d 65 65 74 20 74  ages that meet t
42b0: 68 69 73 20 0a 2a 2a 20 63 72 69 74 65 72 69 61  his .** criteria
42c0: 20 61 72 65 20 75 6e 70 69 6e 6e 65 64 20 62 65   are unpinned be
42d0: 66 6f 72 65 20 74 68 65 79 20 61 72 65 20 64 69  fore they are di
42e0: 73 63 61 72 64 65 64 2e 0a 2a 2a 0a 2a 2a 20 54  scarded..**.** T
42f0: 68 65 20 50 43 61 63 68 65 20 6d 75 74 65 78 20  he PCache mutex 
4300: 6d 75 73 74 20 62 65 20 68 65 6c 64 20 77 68 65  must be held whe
4310: 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  n this function 
4320: 69 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f 0a 73 74  is called..*/.st
4330: 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65  atic void pcache
4340: 31 54 72 75 6e 63 61 74 65 55 6e 73 61 66 65 28  1TruncateUnsafe(
4350: 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63  .  PCache1 *pCac
4360: 68 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  he,             
4370: 2f 2a 20 54 68 65 20 63 61 63 68 65 20 74 6f 20  /* The cache to 
4380: 74 72 75 6e 63 61 74 65 20 2a 2f 0a 20 20 75 6e  truncate */.  un
4390: 73 69 67 6e 65 64 20 69 6e 74 20 69 4c 69 6d 69  signed int iLimi
43a0: 74 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 72  t          /* Dr
43b0: 6f 70 20 70 61 67 65 73 20 77 69 74 68 20 74 68  op pages with th
43c0: 69 73 20 70 67 6e 6f 20 6f 72 20 6c 61 72 67 65  is pgno or large
43d0: 72 20 2a 2f 0a 29 7b 0a 20 20 54 45 53 54 4f 4e  r */.){.  TESTON
43e0: 4c 59 28 20 75 6e 73 69 67 6e 65 64 20 69 6e 74  LY( unsigned int
43f0: 20 6e 50 61 67 65 20 3d 20 30 3b 20 29 20 20 2f   nPage = 0; )  /
4400: 2a 20 54 6f 20 61 73 73 65 72 74 20 70 43 61 63  * To assert pCac
4410: 68 65 2d 3e 6e 50 61 67 65 20 69 73 20 63 6f 72  he->nPage is cor
4420: 72 65 63 74 20 2a 2f 0a 20 20 75 6e 73 69 67 6e  rect */.  unsign
4430: 65 64 20 69 6e 74 20 68 3b 0a 20 20 61 73 73 65  ed int h;.  asse
4440: 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65  rt( sqlite3_mute
4450: 78 5f 68 65 6c 64 28 70 43 61 63 68 65 2d 3e 70  x_held(pCache->p
4460: 47 72 6f 75 70 2d 3e 6d 75 74 65 78 29 20 29 3b  Group->mutex) );
4470: 0a 20 20 66 6f 72 28 68 3d 30 3b 20 68 3c 70 43  .  for(h=0; h<pC
4480: 61 63 68 65 2d 3e 6e 48 61 73 68 3b 20 68 2b 2b  ache->nHash; h++
4490: 29 7b 0a 20 20 20 20 50 67 48 64 72 31 20 2a 2a  ){.    PgHdr1 **
44a0: 70 70 20 3d 20 26 70 43 61 63 68 65 2d 3e 61 70  pp = &pCache->ap
44b0: 48 61 73 68 5b 68 5d 3b 20 0a 20 20 20 20 50 67  Hash[h]; .    Pg
44c0: 48 64 72 31 20 2a 70 50 61 67 65 3b 0a 20 20 20  Hdr1 *pPage;.   
44d0: 20 77 68 69 6c 65 28 20 28 70 50 61 67 65 20 3d   while( (pPage =
44e0: 20 2a 70 70 29 21 3d 30 20 29 7b 0a 20 20 20 20   *pp)!=0 ){.    
44f0: 20 20 69 66 28 20 70 50 61 67 65 2d 3e 69 4b 65    if( pPage->iKe
4500: 79 3e 3d 69 4c 69 6d 69 74 20 29 7b 0a 20 20 20  y>=iLimit ){.   
4510: 20 20 20 20 20 70 43 61 63 68 65 2d 3e 6e 50 61       pCache->nPa
4520: 67 65 2d 2d 3b 0a 20 20 20 20 20 20 20 20 2a 70  ge--;.        *p
4530: 70 20 3d 20 70 50 61 67 65 2d 3e 70 4e 65 78 74  p = pPage->pNext
4540: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 21 70  ;.        if( !p
4550: 50 61 67 65 2d 3e 69 73 50 69 6e 6e 65 64 20 29  Page->isPinned )
4560: 20 70 63 61 63 68 65 31 50 69 6e 50 61 67 65 28   pcache1PinPage(
4570: 70 50 61 67 65 29 3b 0a 20 20 20 20 20 20 20 20  pPage);.        
4580: 70 63 61 63 68 65 31 46 72 65 65 50 61 67 65 28  pcache1FreePage(
4590: 70 50 61 67 65 29 3b 0a 20 20 20 20 20 20 7d 65  pPage);.      }e
45a0: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 70 70 20  lse{.        pp 
45b0: 3d 20 26 70 50 61 67 65 2d 3e 70 4e 65 78 74 3b  = &pPage->pNext;
45c0: 0a 20 20 20 20 20 20 20 20 54 45 53 54 4f 4e 4c  .        TESTONL
45d0: 59 28 20 6e 50 61 67 65 2b 2b 3b 20 29 0a 20 20  Y( nPage++; ).  
45e0: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a      }.    }.  }.
45f0: 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65    assert( pCache
4600: 2d 3e 6e 50 61 67 65 3d 3d 6e 50 61 67 65 20 29  ->nPage==nPage )
4610: 3b 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ;.}../**********
4620: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4630: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4640: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4650: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4660: 2a 2a 2a 2a 2f 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 20  ****/./******** 
4670: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 4d  sqlite3_pcache M
4680: 65 74 68 6f 64 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a  ethods *********
4690: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
46a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
46b0: 2a 2a 2a 2a 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 49 6d  *****/../*.** Im
46c0: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20  plementation of 
46d0: 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63  the sqlite3_pcac
46e0: 68 65 2e 78 49 6e 69 74 20 6d 65 74 68 6f 64 2e  he.xInit method.
46f0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 70  .*/.static int p
4700: 63 61 63 68 65 31 49 6e 69 74 28 76 6f 69 64 20  cache1Init(void 
4710: 2a 4e 6f 74 55 73 65 64 29 7b 0a 20 20 55 4e 55  *NotUsed){.  UNU
4720: 53 45 44 5f 50 41 52 41 4d 45 54 45 52 28 4e 6f  SED_PARAMETER(No
4730: 74 55 73 65 64 29 3b 0a 20 20 61 73 73 65 72 74  tUsed);.  assert
4740: 28 20 70 63 61 63 68 65 31 2e 69 73 49 6e 69 74  ( pcache1.isInit
4750: 3d 3d 30 20 29 3b 0a 20 20 6d 65 6d 73 65 74 28  ==0 );.  memset(
4760: 26 70 63 61 63 68 65 31 2c 20 30 2c 20 73 69 7a  &pcache1, 0, siz
4770: 65 6f 66 28 70 63 61 63 68 65 31 29 29 3b 0a 23  eof(pcache1));.#
4780: 69 66 20 53 51 4c 49 54 45 5f 54 48 52 45 41 44  if SQLITE_THREAD
4790: 53 41 46 45 0a 20 20 69 66 28 20 73 71 6c 69 74  SAFE.  if( sqlit
47a0: 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 62  e3GlobalConfig.b
47b0: 43 6f 72 65 4d 75 74 65 78 20 29 7b 0a 20 20 20  CoreMutex ){.   
47c0: 20 70 63 61 63 68 65 31 2e 67 72 70 2e 6d 75 74   pcache1.grp.mut
47d0: 65 78 20 3d 20 73 71 6c 69 74 65 33 5f 6d 75 74  ex = sqlite3_mut
47e0: 65 78 5f 61 6c 6c 6f 63 28 53 51 4c 49 54 45 5f  ex_alloc(SQLITE_
47f0: 4d 55 54 45 58 5f 53 54 41 54 49 43 5f 4c 52 55  MUTEX_STATIC_LRU
4800: 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 6d  );.    pcache1.m
4810: 75 74 65 78 20 3d 20 73 71 6c 69 74 65 33 5f 6d  utex = sqlite3_m
4820: 75 74 65 78 5f 61 6c 6c 6f 63 28 53 51 4c 49 54  utex_alloc(SQLIT
4830: 45 5f 4d 55 54 45 58 5f 53 54 41 54 49 43 5f 50  E_MUTEX_STATIC_P
4840: 4d 45 4d 29 3b 0a 20 20 7d 0a 23 65 6e 64 69 66  MEM);.  }.#endif
4850: 0a 20 20 70 63 61 63 68 65 31 2e 67 72 70 2e 6d  .  pcache1.grp.m
4860: 78 50 69 6e 6e 65 64 20 3d 20 31 30 3b 0a 20 20  xPinned = 10;.  
4870: 70 63 61 63 68 65 31 2e 69 73 49 6e 69 74 20 3d  pcache1.isInit =
4880: 20 31 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c   1;.  return SQL
4890: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ITE_OK;.}../*.**
48a0: 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20   Implementation 
48b0: 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70  of the sqlite3_p
48c0: 63 61 63 68 65 2e 78 53 68 75 74 64 6f 77 6e 20  cache.xShutdown 
48d0: 6d 65 74 68 6f 64 2e 0a 2a 2a 20 4e 6f 74 65 20  method..** Note 
48e0: 74 68 61 74 20 74 68 65 20 73 74 61 74 69 63 20  that the static 
48f0: 6d 75 74 65 78 20 61 6c 6c 6f 63 61 74 65 64 20  mutex allocated 
4900: 69 6e 20 78 49 6e 69 74 20 64 6f 65 73 20 0a 2a  in xInit does .*
4910: 2a 20 6e 6f 74 20 6e 65 65 64 20 74 6f 20 62 65  * not need to be
4920: 20 66 72 65 65 64 2e 0a 2a 2f 0a 73 74 61 74 69   freed..*/.stati
4930: 63 20 76 6f 69 64 20 70 63 61 63 68 65 31 53 68  c void pcache1Sh
4940: 75 74 64 6f 77 6e 28 76 6f 69 64 20 2a 4e 6f 74  utdown(void *Not
4950: 55 73 65 64 29 7b 0a 20 20 55 4e 55 53 45 44 5f  Used){.  UNUSED_
4960: 50 41 52 41 4d 45 54 45 52 28 4e 6f 74 55 73 65  PARAMETER(NotUse
4970: 64 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 63  d);.  assert( pc
4980: 61 63 68 65 31 2e 69 73 49 6e 69 74 21 3d 30 20  ache1.isInit!=0 
4990: 29 3b 0a 20 20 6d 65 6d 73 65 74 28 26 70 63 61  );.  memset(&pca
49a0: 63 68 65 31 2c 20 30 2c 20 73 69 7a 65 6f 66 28  che1, 0, sizeof(
49b0: 70 63 61 63 68 65 31 29 29 3b 0a 7d 0a 0a 2f 2a  pcache1));.}../*
49c0: 20 66 6f 72 77 61 72 64 20 64 65 63 6c 61 72 61   forward declara
49d0: 74 69 6f 6e 20 2a 2f 0a 73 74 61 74 69 63 20 76  tion */.static v
49e0: 6f 69 64 20 70 63 61 63 68 65 31 44 65 73 74 72  oid pcache1Destr
49f0: 6f 79 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68  oy(sqlite3_pcach
4a00: 65 20 2a 70 29 3b 0a 0a 2f 2a 0a 2a 2a 20 49 6d  e *p);../*.** Im
4a10: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20  plementation of 
4a20: 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63  the sqlite3_pcac
4a30: 68 65 2e 78 43 72 65 61 74 65 20 6d 65 74 68 6f  he.xCreate metho
4a40: 64 2e 0a 2a 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74  d..**.** Allocat
4a50: 65 20 61 20 6e 65 77 20 63 61 63 68 65 2e 0a 2a  e a new cache..*
4a60: 2f 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65 33  /.static sqlite3
4a70: 5f 70 63 61 63 68 65 20 2a 70 63 61 63 68 65 31  _pcache *pcache1
4a80: 43 72 65 61 74 65 28 69 6e 74 20 73 7a 50 61 67  Create(int szPag
4a90: 65 2c 20 69 6e 74 20 73 7a 45 78 74 72 61 2c 20  e, int szExtra, 
4aa0: 69 6e 74 20 62 50 75 72 67 65 61 62 6c 65 29 7b  int bPurgeable){
4ab0: 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63  .  PCache1 *pCac
4ac0: 68 65 3b 20 20 20 20 20 20 2f 2a 20 54 68 65 20  he;      /* The 
4ad0: 6e 65 77 6c 79 20 63 72 65 61 74 65 64 20 70 61  newly created pa
4ae0: 67 65 20 63 61 63 68 65 20 2a 2f 0a 20 20 50 47  ge cache */.  PG
4af0: 72 6f 75 70 20 2a 70 47 72 6f 75 70 3b 20 20 20  roup *pGroup;   
4b00: 20 20 20 20 2f 2a 20 54 68 65 20 67 72 6f 75 70      /* The group
4b10: 20 74 68 65 20 6e 65 77 20 70 61 67 65 20 63 61   the new page ca
4b20: 63 68 65 20 77 69 6c 6c 20 62 65 6c 6f 6e 67 20  che will belong 
4b30: 74 6f 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 3b 20  to */.  int sz; 
4b40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
4b50: 20 42 79 74 65 73 20 6f 66 20 6d 65 6d 6f 72 79   Bytes of memory
4b60: 20 72 65 71 75 69 72 65 64 20 74 6f 20 61 6c 6c   required to all
4b70: 6f 63 61 74 65 20 74 68 65 20 6e 65 77 20 63 61  ocate the new ca
4b80: 63 68 65 20 2a 2f 0a 0a 20 20 2f 2a 0a 20 20 2a  che */..  /*.  *
4b90: 2a 20 54 68 65 20 73 65 70 61 72 61 74 65 43 61  * The separateCa
4ba0: 63 68 65 20 76 61 72 69 61 62 6c 65 20 69 73 20  che variable is 
4bb0: 74 72 75 65 20 69 66 20 65 61 63 68 20 50 43 61  true if each PCa
4bc0: 63 68 65 20 68 61 73 20 69 74 73 20 6f 77 6e 20  che has its own 
4bd0: 70 72 69 76 61 74 65 0a 20 20 2a 2a 20 50 47 72  private.  ** PGr
4be0: 6f 75 70 2e 20 20 49 6e 20 6f 74 68 65 72 20 77  oup.  In other w
4bf0: 6f 72 64 73 2c 20 73 65 70 61 72 61 74 65 43 61  ords, separateCa
4c00: 63 68 65 20 69 73 20 74 72 75 65 20 66 6f 72 20  che is true for 
4c10: 6d 6f 64 65 20 28 31 29 20 77 68 65 72 65 20 6e  mode (1) where n
4c20: 6f 0a 20 20 2a 2a 20 6d 75 74 65 78 69 6e 67 20  o.  ** mutexing 
4c30: 69 73 20 72 65 71 75 69 72 65 64 2e 0a 20 20 2a  is required..  *
4c40: 2a 0a 20 20 2a 2a 20 20 20 2a 20 20 41 6c 77 61  *.  **   *  Alwa
4c50: 79 73 20 75 73 65 20 61 20 75 6e 69 66 69 65 64  ys use a unified
4c60: 20 63 61 63 68 65 20 28 6d 6f 64 65 2d 32 29 20   cache (mode-2) 
4c70: 69 66 20 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59  if ENABLE_MEMORY
4c80: 5f 4d 41 4e 41 47 45 4d 45 4e 54 0a 20 20 2a 2a  _MANAGEMENT.  **
4c90: 0a 20 20 2a 2a 20 20 20 2a 20 20 41 6c 77 61 79  .  **   *  Alway
4ca0: 73 20 75 73 65 20 61 20 75 6e 69 66 69 65 64 20  s use a unified 
4cb0: 63 61 63 68 65 20 69 6e 20 73 69 6e 67 6c 65 2d  cache in single-
4cc0: 74 68 72 65 61 64 65 64 20 61 70 70 6c 69 63 61  threaded applica
4cd0: 74 69 6f 6e 73 0a 20 20 2a 2a 0a 20 20 2a 2a 20  tions.  **.  ** 
4ce0: 20 20 2a 20 20 4f 74 68 65 72 77 69 73 65 20 28    *  Otherwise (
4cf0: 69 66 20 6d 75 6c 74 69 2d 74 68 72 65 61 64 65  if multi-threade
4d00: 64 20 61 6e 64 20 45 4e 41 42 4c 45 5f 4d 45 4d  d and ENABLE_MEM
4d10: 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 20 69  ORY_MANAGEMENT i
4d20: 73 20 6f 66 66 29 0a 20 20 2a 2a 20 20 20 20 20  s off).  **     
4d30: 20 75 73 65 20 73 65 70 61 72 61 74 65 20 63 61   use separate ca
4d40: 63 68 65 73 20 28 6d 6f 64 65 2d 31 29 0a 20 20  ches (mode-1).  
4d50: 2a 2f 0a 23 69 66 20 64 65 66 69 6e 65 64 28 53  */.#if defined(S
4d60: 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d  QLITE_ENABLE_MEM
4d70: 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 29 20  ORY_MANAGEMENT) 
4d80: 7c 7c 20 53 51 4c 49 54 45 5f 54 48 52 45 41 44  || SQLITE_THREAD
4d90: 53 41 46 45 3d 3d 30 0a 20 20 63 6f 6e 73 74 20  SAFE==0.  const 
4da0: 69 6e 74 20 73 65 70 61 72 61 74 65 43 61 63 68  int separateCach
4db0: 65 20 3d 20 30 3b 0a 23 65 6c 73 65 0a 20 20 69  e = 0;.#else.  i
4dc0: 6e 74 20 73 65 70 61 72 61 74 65 43 61 63 68 65  nt separateCache
4dd0: 20 3d 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c   = sqlite3Global
4de0: 43 6f 6e 66 69 67 2e 62 43 6f 72 65 4d 75 74 65  Config.bCoreMute
4df0: 78 3e 30 3b 0a 23 65 6e 64 69 66 0a 0a 20 20 61  x>0;.#endif..  a
4e00: 73 73 65 72 74 28 20 28 73 7a 50 61 67 65 20 26  ssert( (szPage &
4e10: 20 28 73 7a 50 61 67 65 2d 31 29 29 3d 3d 30 20   (szPage-1))==0 
4e20: 26 26 20 73 7a 50 61 67 65 3e 3d 35 31 32 20 26  && szPage>=512 &
4e30: 26 20 73 7a 50 61 67 65 3c 3d 36 35 35 33 36 20  & szPage<=65536 
4e40: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 73 7a 45  );.  assert( szE
4e50: 78 74 72 61 20 3c 20 33 30 30 20 29 3b 0a 0a 20  xtra < 300 );.. 
4e60: 20 73 7a 20 3d 20 73 69 7a 65 6f 66 28 50 43 61   sz = sizeof(PCa
4e70: 63 68 65 31 29 20 2b 20 73 69 7a 65 6f 66 28 50  che1) + sizeof(P
4e80: 47 72 6f 75 70 29 2a 73 65 70 61 72 61 74 65 43  Group)*separateC
4e90: 61 63 68 65 3b 0a 20 20 70 43 61 63 68 65 20 3d  ache;.  pCache =
4ea0: 20 28 50 43 61 63 68 65 31 20 2a 29 73 71 6c 69   (PCache1 *)sqli
4eb0: 74 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28 73 7a  te3MallocZero(sz
4ec0: 29 3b 0a 20 20 69 66 28 20 70 43 61 63 68 65 20  );.  if( pCache 
4ed0: 29 7b 0a 20 20 20 20 69 66 28 20 73 65 70 61 72  ){.    if( separ
4ee0: 61 74 65 43 61 63 68 65 20 29 7b 0a 20 20 20 20  ateCache ){.    
4ef0: 20 20 70 47 72 6f 75 70 20 3d 20 28 50 47 72 6f    pGroup = (PGro
4f00: 75 70 2a 29 26 70 43 61 63 68 65 5b 31 5d 3b 0a  up*)&pCache[1];.
4f10: 20 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 6d 78        pGroup->mx
4f20: 50 69 6e 6e 65 64 20 3d 20 31 30 3b 0a 20 20 20  Pinned = 10;.   
4f30: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 47   }else{.      pG
4f40: 72 6f 75 70 20 3d 20 26 70 63 61 63 68 65 31 2e  roup = &pcache1.
4f50: 67 72 70 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70  grp;.    }.    p
4f60: 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 20 3d 20  Cache->pGroup = 
4f70: 70 47 72 6f 75 70 3b 0a 20 20 20 20 70 43 61 63  pGroup;.    pCac
4f80: 68 65 2d 3e 73 7a 50 61 67 65 20 3d 20 73 7a 50  he->szPage = szP
4f90: 61 67 65 3b 0a 20 20 20 20 70 43 61 63 68 65 2d  age;.    pCache-
4fa0: 3e 73 7a 45 78 74 72 61 20 3d 20 73 7a 45 78 74  >szExtra = szExt
4fb0: 72 61 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e  ra;.    pCache->
4fc0: 62 50 75 72 67 65 61 62 6c 65 20 3d 20 28 62 50  bPurgeable = (bP
4fd0: 75 72 67 65 61 62 6c 65 20 3f 20 31 20 3a 20 30  urgeable ? 1 : 0
4fe0: 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31 45 6e  );.    pcache1En
4ff0: 74 65 72 4d 75 74 65 78 28 70 47 72 6f 75 70 29  terMutex(pGroup)
5000: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 52 65 73  ;.    pcache1Res
5010: 69 7a 65 48 61 73 68 28 70 43 61 63 68 65 29 3b  izeHash(pCache);
5020: 0a 20 20 20 20 69 66 28 20 62 50 75 72 67 65 61  .    if( bPurgea
5030: 62 6c 65 20 29 7b 0a 20 20 20 20 20 20 70 43 61  ble ){.      pCa
5040: 63 68 65 2d 3e 6e 4d 69 6e 20 3d 20 31 30 3b 0a  che->nMin = 10;.
5050: 20 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 6e 4d        pGroup->nM
5060: 69 6e 50 61 67 65 20 2b 3d 20 70 43 61 63 68 65  inPage += pCache
5070: 2d 3e 6e 4d 69 6e 3b 0a 20 20 20 20 20 20 70 47  ->nMin;.      pG
5080: 72 6f 75 70 2d 3e 6d 78 50 69 6e 6e 65 64 20 3d  roup->mxPinned =
5090: 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67   pGroup->nMaxPag
50a0: 65 20 2b 20 31 30 20 2d 20 70 47 72 6f 75 70 2d  e + 10 - pGroup-
50b0: 3e 6e 4d 69 6e 50 61 67 65 3b 0a 20 20 20 20 7d  >nMinPage;.    }
50c0: 0a 20 20 20 20 70 63 61 63 68 65 31 4c 65 61 76  .    pcache1Leav
50d0: 65 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b 0a  eMutex(pGroup);.
50e0: 20 20 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e      if( pCache->
50f0: 6e 48 61 73 68 3d 3d 30 20 29 7b 0a 20 20 20 20  nHash==0 ){.    
5100: 20 20 70 63 61 63 68 65 31 44 65 73 74 72 6f 79    pcache1Destroy
5110: 28 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  ((sqlite3_pcache
5120: 2a 29 70 43 61 63 68 65 29 3b 0a 20 20 20 20 20  *)pCache);.     
5130: 20 70 43 61 63 68 65 20 3d 20 30 3b 0a 20 20 20   pCache = 0;.   
5140: 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20   }.  }.  return 
5150: 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20  (sqlite3_pcache 
5160: 2a 29 70 43 61 63 68 65 3b 0a 7d 0a 0a 2f 2a 0a  *)pCache;.}../*.
5170: 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  ** Implementatio
5180: 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33  n of the sqlite3
5190: 5f 70 63 61 63 68 65 2e 78 43 61 63 68 65 73 69  _pcache.xCachesi
51a0: 7a 65 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a  ze method. .**.*
51b0: 2a 20 43 6f 6e 66 69 67 75 72 65 20 74 68 65 20  * Configure the 
51c0: 63 61 63 68 65 5f 73 69 7a 65 20 6c 69 6d 69 74  cache_size limit
51d0: 20 66 6f 72 20 61 20 63 61 63 68 65 2e 0a 2a 2f   for a cache..*/
51e0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61  .static void pca
51f0: 63 68 65 31 43 61 63 68 65 73 69 7a 65 28 73 71  che1Cachesize(sq
5200: 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70 2c  lite3_pcache *p,
5210: 20 69 6e 74 20 6e 4d 61 78 29 7b 0a 20 20 50 43   int nMax){.  PC
5220: 61 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20  ache1 *pCache = 
5230: 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20 20  (PCache1 *)p;.  
5240: 69 66 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72  if( pCache->bPur
5250: 67 65 61 62 6c 65 20 29 7b 0a 20 20 20 20 50 47  geable ){.    PG
5260: 72 6f 75 70 20 2a 70 47 72 6f 75 70 20 3d 20 70  roup *pGroup = p
5270: 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b 0a 20  Cache->pGroup;. 
5280: 20 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d     pcache1EnterM
5290: 75 74 65 78 28 70 47 72 6f 75 70 29 3b 0a 20 20  utex(pGroup);.  
52a0: 20 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61    pGroup->nMaxPa
52b0: 67 65 20 2b 3d 20 28 6e 4d 61 78 20 2d 20 70 43  ge += (nMax - pC
52c0: 61 63 68 65 2d 3e 6e 4d 61 78 29 3b 0a 20 20 20  ache->nMax);.   
52d0: 20 70 47 72 6f 75 70 2d 3e 6d 78 50 69 6e 6e 65   pGroup->mxPinne
52e0: 64 20 3d 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78  d = pGroup->nMax
52f0: 50 61 67 65 20 2b 20 31 30 20 2d 20 70 47 72 6f  Page + 10 - pGro
5300: 75 70 2d 3e 6e 4d 69 6e 50 61 67 65 3b 0a 20 20  up->nMinPage;.  
5310: 20 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 20 3d    pCache->nMax =
5320: 20 6e 4d 61 78 3b 0a 20 20 20 20 70 43 61 63 68   nMax;.    pCach
5330: 65 2d 3e 6e 39 30 70 63 74 20 3d 20 70 43 61 63  e->n90pct = pCac
5340: 68 65 2d 3e 6e 4d 61 78 2a 39 2f 31 30 3b 0a 20  he->nMax*9/10;. 
5350: 20 20 20 70 63 61 63 68 65 31 45 6e 66 6f 72 63     pcache1Enforc
5360: 65 4d 61 78 50 61 67 65 28 70 47 72 6f 75 70 29  eMaxPage(pGroup)
5370: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 4c 65 61  ;.    pcache1Lea
5380: 76 65 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b  veMutex(pGroup);
5390: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d  .  }.}../*.** Im
53a0: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20  plementation of 
53b0: 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63  the sqlite3_pcac
53c0: 68 65 2e 78 53 68 72 69 6e 6b 20 6d 65 74 68 6f  he.xShrink metho
53d0: 64 2e 20 0a 2a 2a 0a 2a 2a 20 46 72 65 65 20 75  d. .**.** Free u
53e0: 70 20 61 73 20 6d 75 63 68 20 6d 65 6d 6f 72 79  p as much memory
53f0: 20 61 73 20 70 6f 73 73 69 62 6c 65 2e 0a 2a 2f   as possible..*/
5400: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61  .static void pca
5410: 63 68 65 31 53 68 72 69 6e 6b 28 73 71 6c 69 74  che1Shrink(sqlit
5420: 65 33 5f 70 63 61 63 68 65 20 2a 70 29 7b 0a 20  e3_pcache *p){. 
5430: 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68 65   PCache1 *pCache
5440: 20 3d 20 28 50 43 61 63 68 65 31 2a 29 70 3b 0a   = (PCache1*)p;.
5450: 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 62 50    if( pCache->bP
5460: 75 72 67 65 61 62 6c 65 20 29 7b 0a 20 20 20 20  urgeable ){.    
5470: 50 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 20 3d  PGroup *pGroup =
5480: 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b   pCache->pGroup;
5490: 0a 20 20 20 20 69 6e 74 20 73 61 76 65 64 4d 61  .    int savedMa
54a0: 78 50 61 67 65 3b 0a 20 20 20 20 70 63 61 63 68  xPage;.    pcach
54b0: 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70 47 72  e1EnterMutex(pGr
54c0: 6f 75 70 29 3b 0a 20 20 20 20 73 61 76 65 64 4d  oup);.    savedM
54d0: 61 78 50 61 67 65 20 3d 20 70 47 72 6f 75 70 2d  axPage = pGroup-
54e0: 3e 6e 4d 61 78 50 61 67 65 3b 0a 20 20 20 20 70  >nMaxPage;.    p
54f0: 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65 20  Group->nMaxPage 
5500: 3d 20 30 3b 0a 20 20 20 20 70 63 61 63 68 65 31  = 0;.    pcache1
5510: 45 6e 66 6f 72 63 65 4d 61 78 50 61 67 65 28 70  EnforceMaxPage(p
5520: 47 72 6f 75 70 29 3b 0a 20 20 20 20 70 47 72 6f  Group);.    pGro
5530: 75 70 2d 3e 6e 4d 61 78 50 61 67 65 20 3d 20 73  up->nMaxPage = s
5540: 61 76 65 64 4d 61 78 50 61 67 65 3b 0a 20 20 20  avedMaxPage;.   
5550: 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74   pcache1LeaveMut
5560: 65 78 28 70 47 72 6f 75 70 29 3b 0a 20 20 7d 0a  ex(pGroup);.  }.
5570: 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65  }../*.** Impleme
5580: 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73  ntation of the s
5590: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78 50  qlite3_pcache.xP
55a0: 61 67 65 63 6f 75 6e 74 20 6d 65 74 68 6f 64 2e  agecount method.
55b0: 20 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 50 61 67 65 63 6f 75 6e 74  pcache1Pagecount
55d0: 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20  (sqlite3_pcache 
55e0: 2a 70 29 7b 0a 20 20 69 6e 74 20 6e 3b 0a 20 20  *p){.  int n;.  
55f0: 50 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 20  PCache1 *pCache 
5600: 3d 20 28 50 43 61 63 68 65 31 2a 29 70 3b 0a 20  = (PCache1*)p;. 
5610: 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74   pcache1EnterMut
5620: 65 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75  ex(pCache->pGrou
5630: 70 29 3b 0a 20 20 6e 20 3d 20 70 43 61 63 68 65  p);.  n = pCache
5640: 2d 3e 6e 50 61 67 65 3b 0a 20 20 70 63 61 63 68  ->nPage;.  pcach
5650: 65 31 4c 65 61 76 65 4d 75 74 65 78 28 70 43 61  e1LeaveMutex(pCa
5660: 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 20 20  che->pGroup);.  
5670: 72 65 74 75 72 6e 20 6e 3b 0a 7d 0a 0a 0a 2f 2a  return n;.}.../*
5680: 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 20 73 74  .** Implement st
5690: 65 70 73 20 33 2c 20 34 2c 20 61 6e 64 20 35 20  eps 3, 4, and 5 
56a0: 6f 66 20 74 68 65 20 70 63 61 63 68 65 31 46 65  of the pcache1Fe
56b0: 74 63 68 28 29 20 61 6c 67 6f 72 69 74 68 6d 20  tch() algorithm 
56c0: 64 65 73 63 72 69 62 65 64 0a 2a 2a 20 69 6e 20  described.** in 
56d0: 74 68 65 20 68 65 61 64 65 72 20 6f 66 20 74 68  the header of th
56e0: 65 20 70 63 61 63 68 65 31 46 65 74 63 68 28 29  e pcache1Fetch()
56f0: 20 70 72 6f 63 65 64 75 72 65 2e 0a 2a 2a 0a 2a   procedure..**.*
5700: 2a 20 54 68 69 73 20 73 74 65 70 73 20 61 72 65  * This steps are
5710: 20 62 72 6f 6b 65 6e 20 6f 75 74 20 69 6e 74 6f   broken out into
5720: 20 61 20 73 65 70 61 72 61 74 65 20 70 72 6f 63   a separate proc
5730: 65 64 75 72 65 20 62 65 63 61 75 73 65 20 74 68  edure because th
5740: 65 79 20 61 72 65 0a 2a 2a 20 75 73 75 61 6c 6c  ey are.** usuall
5750: 79 20 6e 6f 74 20 6e 65 65 64 65 64 2c 20 61 6e  y not needed, an
5760: 64 20 62 79 20 61 76 6f 69 64 69 6e 67 20 74 68  d by avoiding th
5770: 65 20 73 74 61 63 6b 20 69 6e 69 74 69 61 6c 69  e stack initiali
5780: 7a 61 74 69 6f 6e 20 72 65 71 75 69 72 65 64 0a  zation required.
5790: 2a 2a 20 66 6f 72 20 74 68 65 73 65 20 73 74 65  ** for these ste
57a0: 70 73 2c 20 74 68 65 20 6d 61 69 6e 20 70 63 61  ps, the main pca
57b0: 63 68 65 31 46 65 74 63 68 28 29 20 70 72 6f 63  che1Fetch() proc
57c0: 65 64 75 72 65 20 63 61 6e 20 72 75 6e 20 66 61  edure can run fa
57d0: 73 74 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ster..*/.static 
57e0: 53 51 4c 49 54 45 5f 4e 4f 49 4e 4c 49 4e 45 20  SQLITE_NOINLINE 
57f0: 50 67 48 64 72 31 20 2a 70 63 61 63 68 65 31 46  PgHdr1 *pcache1F
5800: 65 74 63 68 53 74 61 67 65 32 28 0a 20 20 50 43  etchStage2(.  PC
5810: 61 63 68 65 31 20 2a 70 43 61 63 68 65 2c 20 0a  ache1 *pCache, .
5820: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69    unsigned int i
5830: 4b 65 79 2c 20 0a 20 20 69 6e 74 20 63 72 65 61  Key, .  int crea
5840: 74 65 46 6c 61 67 0a 29 7b 0a 20 20 75 6e 73 69  teFlag.){.  unsi
5850: 67 6e 65 64 20 69 6e 74 20 6e 50 69 6e 6e 65 64  gned int nPinned
5860: 3b 0a 20 20 50 47 72 6f 75 70 20 2a 70 47 72 6f  ;.  PGroup *pGro
5870: 75 70 20 3d 20 70 43 61 63 68 65 2d 3e 70 47 72  up = pCache->pGr
5880: 6f 75 70 3b 0a 20 20 50 67 48 64 72 31 20 2a 70  oup;.  PgHdr1 *p
5890: 50 61 67 65 20 3d 20 30 3b 0a 0a 20 20 2f 2a 20  Page = 0;..  /* 
58a0: 53 74 65 70 20 33 3a 20 41 62 6f 72 74 20 69 66  Step 3: Abort if
58b0: 20 63 72 65 61 74 65 46 6c 61 67 20 69 73 20 31   createFlag is 1
58c0: 20 62 75 74 20 74 68 65 20 63 61 63 68 65 20 69   but the cache i
58d0: 73 20 6e 65 61 72 6c 79 20 66 75 6c 6c 20 2a 2f  s nearly full */
58e0: 0a 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68  .  assert( pCach
58f0: 65 2d 3e 6e 50 61 67 65 20 3e 3d 20 70 43 61 63  e->nPage >= pCac
5900: 68 65 2d 3e 6e 52 65 63 79 63 6c 61 62 6c 65 20  he->nRecyclable 
5910: 29 3b 0a 20 20 6e 50 69 6e 6e 65 64 20 3d 20 70  );.  nPinned = p
5920: 43 61 63 68 65 2d 3e 6e 50 61 67 65 20 2d 20 70  Cache->nPage - p
5930: 43 61 63 68 65 2d 3e 6e 52 65 63 79 63 6c 61 62  Cache->nRecyclab
5940: 6c 65 3b 0a 20 20 61 73 73 65 72 74 28 20 70 47  le;.  assert( pG
5950: 72 6f 75 70 2d 3e 6d 78 50 69 6e 6e 65 64 20 3d  roup->mxPinned =
5960: 3d 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61  = pGroup->nMaxPa
5970: 67 65 20 2b 20 31 30 20 2d 20 70 47 72 6f 75 70  ge + 10 - pGroup
5980: 2d 3e 6e 4d 69 6e 50 61 67 65 20 29 3b 0a 20 20  ->nMinPage );.  
5990: 61 73 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e  assert( pCache->
59a0: 6e 39 30 70 63 74 20 3d 3d 20 70 43 61 63 68 65  n90pct == pCache
59b0: 2d 3e 6e 4d 61 78 2a 39 2f 31 30 20 29 3b 0a 20  ->nMax*9/10 );. 
59c0: 20 69 66 28 20 63 72 65 61 74 65 46 6c 61 67 3d   if( createFlag=
59d0: 3d 31 20 26 26 20 28 0a 20 20 20 20 20 20 20 20  =1 && (.        
59e0: 6e 50 69 6e 6e 65 64 3e 3d 70 47 72 6f 75 70 2d  nPinned>=pGroup-
59f0: 3e 6d 78 50 69 6e 6e 65 64 0a 20 20 20 20 20 7c  >mxPinned.     |
5a00: 7c 20 6e 50 69 6e 6e 65 64 3e 3d 70 43 61 63 68  | nPinned>=pCach
5a10: 65 2d 3e 6e 39 30 70 63 74 0a 20 20 20 20 20 7c  e->n90pct.     |
5a20: 7c 20 28 70 63 61 63 68 65 31 55 6e 64 65 72 4d  | (pcache1UnderM
5a30: 65 6d 6f 72 79 50 72 65 73 73 75 72 65 28 70 43  emoryPressure(pC
5a40: 61 63 68 65 29 20 26 26 20 70 43 61 63 68 65 2d  ache) && pCache-
5a50: 3e 6e 52 65 63 79 63 6c 61 62 6c 65 3c 6e 50 69  >nRecyclable<nPi
5a60: 6e 6e 65 64 29 0a 20 20 29 29 7b 0a 20 20 20 20  nned).  )){.    
5a70: 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 0a 20  return 0;.  }.. 
5a80: 20 69 66 28 20 70 43 61 63 68 65 2d 3e 6e 50 61   if( pCache->nPa
5a90: 67 65 3e 3d 70 43 61 63 68 65 2d 3e 6e 48 61 73  ge>=pCache->nHas
5aa0: 68 20 29 20 70 63 61 63 68 65 31 52 65 73 69 7a  h ) pcache1Resiz
5ab0: 65 48 61 73 68 28 70 43 61 63 68 65 29 3b 0a 20  eHash(pCache);. 
5ac0: 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65 2d   assert( pCache-
5ad0: 3e 6e 48 61 73 68 3e 30 20 26 26 20 70 43 61 63  >nHash>0 && pCac
5ae0: 68 65 2d 3e 61 70 48 61 73 68 20 29 3b 0a 0a 20  he->apHash );.. 
5af0: 20 2f 2a 20 53 74 65 70 20 34 2e 20 54 72 79 20   /* Step 4. Try 
5b00: 74 6f 20 72 65 63 79 63 6c 65 20 61 20 70 61 67  to recycle a pag
5b10: 65 2e 20 2a 2f 0a 20 20 69 66 28 20 70 43 61 63  e. */.  if( pCac
5b20: 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 26  he->bPurgeable &
5b30: 26 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 54 61  & pGroup->pLruTa
5b40: 69 6c 20 26 26 20 28 0a 20 20 20 20 20 20 20 20  il && (.        
5b50: 20 28 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 2b   (pCache->nPage+
5b60: 31 3e 3d 70 43 61 63 68 65 2d 3e 6e 4d 61 78 29  1>=pCache->nMax)
5b70: 0a 20 20 20 20 20 20 7c 7c 20 70 47 72 6f 75 70  .      || pGroup
5b80: 2d 3e 6e 43 75 72 72 65 6e 74 50 61 67 65 3e 3d  ->nCurrentPage>=
5b90: 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65  pGroup->nMaxPage
5ba0: 0a 20 20 20 20 20 20 7c 7c 20 70 63 61 63 68 65  .      || pcache
5bb0: 31 55 6e 64 65 72 4d 65 6d 6f 72 79 50 72 65 73  1UnderMemoryPres
5bc0: 73 75 72 65 28 70 43 61 63 68 65 29 0a 20 20 29  sure(pCache).  )
5bd0: 29 7b 0a 20 20 20 20 50 43 61 63 68 65 31 20 2a  ){.    PCache1 *
5be0: 70 4f 74 68 65 72 3b 0a 20 20 20 20 70 50 61 67  pOther;.    pPag
5bf0: 65 20 3d 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75  e = pGroup->pLru
5c00: 54 61 69 6c 3b 0a 20 20 20 20 61 73 73 65 72 74  Tail;.    assert
5c10: 28 20 70 50 61 67 65 2d 3e 69 73 50 69 6e 6e 65  ( pPage->isPinne
5c20: 64 3d 3d 30 20 29 3b 0a 20 20 20 20 70 63 61 63  d==0 );.    pcac
5c30: 68 65 31 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73  he1RemoveFromHas
5c40: 68 28 70 50 61 67 65 29 3b 0a 20 20 20 20 70 63  h(pPage);.    pc
5c50: 61 63 68 65 31 50 69 6e 50 61 67 65 28 70 50 61  ache1PinPage(pPa
5c60: 67 65 29 3b 0a 20 20 20 20 70 4f 74 68 65 72 20  ge);.    pOther 
5c70: 3d 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65 3b  = pPage->pCache;
5c80: 0a 0a 20 20 20 20 2f 2a 20 57 65 20 77 61 6e 74  ..    /* We want
5c90: 20 74 6f 20 76 65 72 69 66 79 20 74 68 61 74 20   to verify that 
5ca0: 73 7a 50 61 67 65 20 61 6e 64 20 73 7a 45 78 74  szPage and szExt
5cb0: 72 61 20 61 72 65 20 74 68 65 20 73 61 6d 65 20  ra are the same 
5cc0: 66 6f 72 20 70 4f 74 68 65 72 0a 20 20 20 20 2a  for pOther.    *
5cd0: 2a 20 61 6e 64 20 70 43 61 63 68 65 2e 20 20 41  * and pCache.  A
5ce0: 73 73 65 72 74 20 74 68 61 74 20 77 65 20 63 61  ssert that we ca
5cf0: 6e 20 76 65 72 69 66 79 20 74 68 69 73 20 62 79  n verify this by
5d00: 20 63 6f 6d 70 61 72 69 6e 67 20 73 75 6d 73 2e   comparing sums.
5d10: 20 2a 2f 0a 20 20 20 20 61 73 73 65 72 74 28 20   */.    assert( 
5d20: 28 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 20  (pCache->szPage 
5d30: 26 20 28 70 43 61 63 68 65 2d 3e 73 7a 50 61 67  & (pCache->szPag
5d40: 65 2d 31 29 29 3d 3d 30 20 26 26 20 70 43 61 63  e-1))==0 && pCac
5d50: 68 65 2d 3e 73 7a 50 61 67 65 3e 3d 35 31 32 20  he->szPage>=512 
5d60: 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70  );.    assert( p
5d70: 43 61 63 68 65 2d 3e 73 7a 45 78 74 72 61 3c 35  Cache->szExtra<5
5d80: 31 32 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74  12 );.    assert
5d90: 28 20 28 70 4f 74 68 65 72 2d 3e 73 7a 50 61 67  ( (pOther->szPag
5da0: 65 20 26 20 28 70 4f 74 68 65 72 2d 3e 73 7a 50  e & (pOther->szP
5db0: 61 67 65 2d 31 29 29 3d 3d 30 20 26 26 20 70 4f  age-1))==0 && pO
5dc0: 74 68 65 72 2d 3e 73 7a 50 61 67 65 3e 3d 35 31  ther->szPage>=51
5dd0: 32 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28  2 );.    assert(
5de0: 20 70 4f 74 68 65 72 2d 3e 73 7a 45 78 74 72 61   pOther->szExtra
5df0: 3c 35 31 32 20 29 3b 0a 0a 20 20 20 20 69 66 28  <512 );..    if(
5e00: 20 70 4f 74 68 65 72 2d 3e 73 7a 50 61 67 65 2b   pOther->szPage+
5e10: 70 4f 74 68 65 72 2d 3e 73 7a 45 78 74 72 61 20  pOther->szExtra 
5e20: 21 3d 20 70 43 61 63 68 65 2d 3e 73 7a 50 61 67  != pCache->szPag
5e30: 65 2b 70 43 61 63 68 65 2d 3e 73 7a 45 78 74 72  e+pCache->szExtr
5e40: 61 20 29 7b 0a 20 20 20 20 20 20 70 63 61 63 68  a ){.      pcach
5e50: 65 31 46 72 65 65 50 61 67 65 28 70 50 61 67 65  e1FreePage(pPage
5e60: 29 3b 0a 20 20 20 20 20 20 70 50 61 67 65 20 3d  );.      pPage =
5e70: 20 30 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20   0;.    }else{. 
5e80: 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 6e 43 75       pGroup->nCu
5e90: 72 72 65 6e 74 50 61 67 65 20 2d 3d 20 28 70 4f  rrentPage -= (pO
5ea0: 74 68 65 72 2d 3e 62 50 75 72 67 65 61 62 6c 65  ther->bPurgeable
5eb0: 20 2d 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67   - pCache->bPurg
5ec0: 65 61 62 6c 65 29 3b 0a 20 20 20 20 7d 0a 20 20  eable);.    }.  
5ed0: 7d 0a 0a 20 20 2f 2a 20 53 74 65 70 20 35 2e 20  }..  /* Step 5. 
5ee0: 49 66 20 61 20 75 73 61 62 6c 65 20 70 61 67 65  If a usable page
5ef0: 20 62 75 66 66 65 72 20 68 61 73 20 73 74 69 6c   buffer has stil
5f00: 6c 20 6e 6f 74 20 62 65 65 6e 20 66 6f 75 6e 64  l not been found
5f10: 2c 20 0a 20 20 2a 2a 20 61 74 74 65 6d 70 74 20  , .  ** attempt 
5f20: 74 6f 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e 65  to allocate a ne
5f30: 77 20 6f 6e 65 2e 20 0a 20 20 2a 2f 0a 20 20 69  w one. .  */.  i
5f40: 66 28 20 21 70 50 61 67 65 20 29 7b 0a 20 20 20  f( !pPage ){.   
5f50: 20 69 66 28 20 63 72 65 61 74 65 46 6c 61 67 3d   if( createFlag=
5f60: 3d 31 20 29 7b 20 73 71 6c 69 74 65 33 42 65 67  =1 ){ sqlite3Beg
5f70: 69 6e 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29  inBenignMalloc()
5f80: 3b 20 7d 0a 20 20 20 20 70 50 61 67 65 20 3d 20  ; }.    pPage = 
5f90: 70 63 61 63 68 65 31 41 6c 6c 6f 63 50 61 67 65  pcache1AllocPage
5fa0: 28 70 43 61 63 68 65 29 3b 0a 20 20 20 20 69 66  (pCache);.    if
5fb0: 28 20 63 72 65 61 74 65 46 6c 61 67 3d 3d 31 20  ( createFlag==1 
5fc0: 29 7b 20 73 71 6c 69 74 65 33 45 6e 64 42 65 6e  ){ sqlite3EndBen
5fd0: 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 20 7d 0a 20  ignMalloc(); }. 
5fe0: 20 7d 0a 0a 20 20 69 66 28 20 70 50 61 67 65 20   }..  if( pPage 
5ff0: 29 7b 0a 20 20 20 20 75 6e 73 69 67 6e 65 64 20  ){.    unsigned 
6000: 69 6e 74 20 68 20 3d 20 69 4b 65 79 20 25 20 70  int h = iKey % p
6010: 43 61 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20  Cache->nHash;.  
6020: 20 20 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 2b    pCache->nPage+
6030: 2b 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 69 4b  +;.    pPage->iK
6040: 65 79 20 3d 20 69 4b 65 79 3b 0a 20 20 20 20 70  ey = iKey;.    p
6050: 50 61 67 65 2d 3e 70 4e 65 78 74 20 3d 20 70 43  Page->pNext = pC
6060: 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b  ache->apHash[h];
6070: 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 43 61 63  .    pPage->pCac
6080: 68 65 20 3d 20 70 43 61 63 68 65 3b 0a 20 20 20  he = pCache;.   
6090: 20 70 50 61 67 65 2d 3e 70 4c 72 75 50 72 65 76   pPage->pLruPrev
60a0: 20 3d 20 30 3b 0a 20 20 20 20 70 50 61 67 65 2d   = 0;.    pPage-
60b0: 3e 70 4c 72 75 4e 65 78 74 20 3d 20 30 3b 0a 20  >pLruNext = 0;. 
60c0: 20 20 20 70 50 61 67 65 2d 3e 69 73 50 69 6e 6e     pPage->isPinn
60d0: 65 64 20 3d 20 31 3b 0a 20 20 20 20 2a 28 76 6f  ed = 1;.    *(vo
60e0: 69 64 20 2a 2a 29 70 50 61 67 65 2d 3e 70 61 67  id **)pPage->pag
60f0: 65 2e 70 45 78 74 72 61 20 3d 20 30 3b 0a 20 20  e.pExtra = 0;.  
6100: 20 20 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68    pCache->apHash
6110: 5b 68 5d 20 3d 20 70 50 61 67 65 3b 0a 20 20 20  [h] = pPage;.   
6120: 20 69 66 28 20 69 4b 65 79 3e 70 43 61 63 68 65   if( iKey>pCache
6130: 2d 3e 69 4d 61 78 4b 65 79 20 29 7b 0a 20 20 20  ->iMaxKey ){.   
6140: 20 20 20 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b     pCache->iMaxK
6150: 65 79 20 3d 20 69 4b 65 79 3b 0a 20 20 20 20 7d  ey = iKey;.    }
6160: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 70 50  .  }.  return pP
6170: 61 67 65 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d  age;.}../*.** Im
6180: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20  plementation of 
6190: 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63  the sqlite3_pcac
61a0: 68 65 2e 78 46 65 74 63 68 20 6d 65 74 68 6f 64  he.xFetch method
61b0: 2e 20 0a 2a 2a 0a 2a 2a 20 46 65 74 63 68 20 61  . .**.** Fetch a
61c0: 20 70 61 67 65 20 62 79 20 6b 65 79 20 76 61 6c   page by key val
61d0: 75 65 2e 0a 2a 2a 0a 2a 2a 20 57 68 65 74 68 65  ue..**.** Whethe
61e0: 72 20 6f 72 20 6e 6f 74 20 61 20 6e 65 77 20 70  r or not a new p
61f0: 61 67 65 20 6d 61 79 20 62 65 20 61 6c 6c 6f 63  age may be alloc
6200: 61 74 65 64 20 62 79 20 74 68 69 73 20 66 75 6e  ated by this fun
6210: 63 74 69 6f 6e 20 64 65 70 65 6e 64 73 20 6f 6e  ction depends on
6220: 0a 2a 2a 20 74 68 65 20 76 61 6c 75 65 20 6f 66  .** the value of
6230: 20 74 68 65 20 63 72 65 61 74 65 46 6c 61 67 20   the createFlag 
6240: 61 72 67 75 6d 65 6e 74 2e 20 20 30 20 6d 65 61  argument.  0 mea
6250: 6e 73 20 64 6f 20 6e 6f 74 20 61 6c 6c 6f 63 61  ns do not alloca
6260: 74 65 20 61 20 6e 65 77 0a 2a 2a 20 70 61 67 65  te a new.** page
6270: 2e 20 20 31 20 6d 65 61 6e 73 20 61 6c 6c 6f 63  .  1 means alloc
6280: 61 74 65 20 61 20 6e 65 77 20 70 61 67 65 20 69  ate a new page i
6290: 66 20 73 70 61 63 65 20 69 73 20 65 61 73 69 6c  f space is easil
62a0: 79 20 61 76 61 69 6c 61 62 6c 65 2e 20 20 32 20  y available.  2 
62b0: 0a 2a 2a 20 6d 65 61 6e 73 20 74 6f 20 74 72 79  .** means to try
62c0: 20 72 65 61 6c 6c 79 20 68 61 72 64 20 74 6f 20   really hard to 
62d0: 61 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 70  allocate a new p
62e0: 61 67 65 2e 0a 2a 2a 0a 2a 2a 20 46 6f 72 20 61  age..**.** For a
62f0: 20 6e 6f 6e 2d 70 75 72 67 65 61 62 6c 65 20 63   non-purgeable c
6300: 61 63 68 65 20 28 61 20 63 61 63 68 65 20 75 73  ache (a cache us
6310: 65 64 20 61 73 20 74 68 65 20 73 74 6f 72 61 67  ed as the storag
6320: 65 20 66 6f 72 20 61 6e 20 69 6e 2d 6d 65 6d 6f  e for an in-memo
6330: 72 79 0a 2a 2a 20 64 61 74 61 62 61 73 65 29 20  ry.** database) 
6340: 74 68 65 72 65 20 69 73 20 72 65 61 6c 6c 79 20  there is really 
6350: 6e 6f 20 64 69 66 66 65 72 65 6e 63 65 20 62 65  no difference be
6360: 74 77 65 65 6e 20 63 72 65 61 74 65 46 6c 61 67  tween createFlag
6370: 20 31 20 61 6e 64 20 32 2e 20 20 53 6f 0a 2a 2a   1 and 2.  So.**
6380: 20 74 68 65 20 63 61 6c 6c 69 6e 67 20 66 75 6e   the calling fun
6390: 63 74 69 6f 6e 20 28 70 63 61 63 68 65 2e 63 29  ction (pcache.c)
63a0: 20 77 69 6c 6c 20 6e 65 76 65 72 20 68 61 76 65   will never have
63b0: 20 61 20 63 72 65 61 74 65 46 6c 61 67 20 6f 66   a createFlag of
63c0: 20 31 20 6f 6e 0a 2a 2a 20 61 20 6e 6f 6e 2d 70   1 on.** a non-p
63d0: 75 72 67 65 61 62 6c 65 20 63 61 63 68 65 2e 0a  urgeable cache..
63e0: 2a 2a 0a 2a 2a 20 54 68 65 72 65 20 61 72 65 20  **.** There are 
63f0: 74 68 72 65 65 20 64 69 66 66 65 72 65 6e 74 20  three different 
6400: 61 70 70 72 6f 61 63 68 65 73 20 74 6f 20 6f 62  approaches to ob
6410: 74 61 69 6e 69 6e 67 20 73 70 61 63 65 20 66 6f  taining space fo
6420: 72 20 61 20 70 61 67 65 2c 0a 2a 2a 20 64 65 70  r a page,.** dep
6430: 65 6e 64 69 6e 67 20 6f 6e 20 74 68 65 20 76 61  ending on the va
6440: 6c 75 65 20 6f 66 20 70 61 72 61 6d 65 74 65 72  lue of parameter
6450: 20 63 72 65 61 74 65 46 6c 61 67 20 28 77 68 69   createFlag (whi
6460: 63 68 20 6d 61 79 20 62 65 20 30 2c 20 31 20 6f  ch may be 0, 1 o
6470: 72 20 32 29 2e 0a 2a 2a 0a 2a 2a 20 20 20 31 2e  r 2)..**.**   1.
6480: 20 52 65 67 61 72 64 6c 65 73 73 20 6f 66 20 74   Regardless of t
6490: 68 65 20 76 61 6c 75 65 20 6f 66 20 63 72 65 61  he value of crea
64a0: 74 65 46 6c 61 67 2c 20 74 68 65 20 63 61 63 68  teFlag, the cach
64b0: 65 20 69 73 20 73 65 61 72 63 68 65 64 20 66 6f  e is searched fo
64c0: 72 20 61 20 0a 2a 2a 20 20 20 20 20 20 63 6f 70  r a .**      cop
64d0: 79 20 6f 66 20 74 68 65 20 72 65 71 75 65 73 74  y of the request
64e0: 65 64 20 70 61 67 65 2e 20 49 66 20 6f 6e 65 20  ed page. If one 
64f0: 69 73 20 66 6f 75 6e 64 2c 20 69 74 20 69 73 20  is found, it is 
6500: 72 65 74 75 72 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20  returned..**.** 
6510: 20 20 32 2e 20 49 66 20 63 72 65 61 74 65 46 6c    2. If createFl
6520: 61 67 3d 3d 30 20 61 6e 64 20 74 68 65 20 70 61  ag==0 and the pa
6530: 67 65 20 69 73 20 6e 6f 74 20 61 6c 72 65 61 64  ge is not alread
6540: 79 20 69 6e 20 74 68 65 20 63 61 63 68 65 2c 20  y in the cache, 
6550: 4e 55 4c 4c 20 69 73 0a 2a 2a 20 20 20 20 20 20  NULL is.**      
6560: 72 65 74 75 72 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20  returned..**.** 
6570: 20 20 33 2e 20 49 66 20 63 72 65 61 74 65 46 6c    3. If createFl
6580: 61 67 20 69 73 20 31 2c 20 61 6e 64 20 74 68 65  ag is 1, and the
6590: 20 70 61 67 65 20 69 73 20 6e 6f 74 20 61 6c 72   page is not alr
65a0: 65 61 64 79 20 69 6e 20 74 68 65 20 63 61 63 68  eady in the cach
65b0: 65 2c 20 74 68 65 6e 0a 2a 2a 20 20 20 20 20 20  e, then.**      
65c0: 72 65 74 75 72 6e 20 4e 55 4c 4c 20 28 64 6f 20  return NULL (do 
65d0: 6e 6f 74 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e  not allocate a n
65e0: 65 77 20 70 61 67 65 29 20 69 66 20 61 6e 79 20  ew page) if any 
65f0: 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  of the following
6600: 0a 2a 2a 20 20 20 20 20 20 63 6f 6e 64 69 74 69  .**      conditi
6610: 6f 6e 73 20 61 72 65 20 74 72 75 65 3a 0a 2a 2a  ons are true:.**
6620: 0a 2a 2a 20 20 20 20 20 20 20 28 61 29 20 74 68  .**       (a) th
6630: 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65  e number of page
6640: 73 20 70 69 6e 6e 65 64 20 62 79 20 74 68 65 20  s pinned by the 
6650: 63 61 63 68 65 20 69 73 20 67 72 65 61 74 65 72  cache is greater
6660: 20 74 68 61 6e 0a 2a 2a 20 20 20 20 20 20 20 20   than.**        
6670: 20 20 20 50 43 61 63 68 65 31 2e 6e 4d 61 78 2c     PCache1.nMax,
6680: 20 6f 72 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20   or.**.**       
6690: 28 62 29 20 74 68 65 20 6e 75 6d 62 65 72 20 6f  (b) the number o
66a0: 66 20 70 61 67 65 73 20 70 69 6e 6e 65 64 20 62  f pages pinned b
66b0: 79 20 74 68 65 20 63 61 63 68 65 20 69 73 20 67  y the cache is g
66c0: 72 65 61 74 65 72 20 74 68 61 6e 0a 2a 2a 20 20  reater than.**  
66d0: 20 20 20 20 20 20 20 20 20 74 68 65 20 73 75 6d           the sum
66e0: 20 6f 66 20 6e 4d 61 78 20 66 6f 72 20 61 6c 6c   of nMax for all
66f0: 20 70 75 72 67 65 61 62 6c 65 20 63 61 63 68 65   purgeable cache
6700: 73 2c 20 6c 65 73 73 20 74 68 65 20 73 75 6d 20  s, less the sum 
6710: 6f 66 20 0a 2a 2a 20 20 20 20 20 20 20 20 20 20  of .**          
6720: 20 6e 4d 69 6e 20 66 6f 72 20 61 6c 6c 20 6f 74   nMin for all ot
6730: 68 65 72 20 70 75 72 67 65 61 62 6c 65 20 63 61  her purgeable ca
6740: 63 68 65 73 2c 20 6f 72 0a 2a 2a 0a 2a 2a 20 20  ches, or.**.**  
6750: 20 34 2e 20 49 66 20 6e 6f 6e 65 20 6f 66 20 74   4. If none of t
6760: 68 65 20 66 69 72 73 74 20 74 68 72 65 65 20 63  he first three c
6770: 6f 6e 64 69 74 69 6f 6e 73 20 61 70 70 6c 79 20  onditions apply 
6780: 61 6e 64 20 74 68 65 20 63 61 63 68 65 20 69 73  and the cache is
6790: 20 6d 61 72 6b 65 64 0a 2a 2a 20 20 20 20 20 20   marked.**      
67a0: 61 73 20 70 75 72 67 65 61 62 6c 65 2c 20 61 6e  as purgeable, an
67b0: 64 20 69 66 20 6f 6e 65 20 6f 66 20 74 68 65 20  d if one of the 
67c0: 66 6f 6c 6c 6f 77 69 6e 67 20 69 73 20 74 72 75  following is tru
67d0: 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 28  e:.**.**       (
67e0: 61 29 20 54 68 65 20 6e 75 6d 62 65 72 20 6f 66  a) The number of
67f0: 20 70 61 67 65 73 20 61 6c 6c 6f 63 61 74 65 64   pages allocated
6800: 20 66 6f 72 20 74 68 65 20 63 61 63 68 65 20 69   for the cache i
6810: 73 20 61 6c 72 65 61 64 79 20 0a 2a 2a 20 20 20  s already .**   
6820: 20 20 20 20 20 20 20 20 50 43 61 63 68 65 31 2e          PCache1.
6830: 6e 4d 61 78 2c 20 6f 72 0a 2a 2a 0a 2a 2a 20 20  nMax, or.**.**  
6840: 20 20 20 20 20 28 62 29 20 54 68 65 20 6e 75 6d       (b) The num
6850: 62 65 72 20 6f 66 20 70 61 67 65 73 20 61 6c 6c  ber of pages all
6860: 6f 63 61 74 65 64 20 66 6f 72 20 61 6c 6c 20 70  ocated for all p
6870: 75 72 67 65 61 62 6c 65 20 63 61 63 68 65 73 20  urgeable caches 
6880: 69 73 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20  is.**           
6890: 61 6c 72 65 61 64 79 20 65 71 75 61 6c 20 74 6f  already equal to
68a0: 20 6f 72 20 67 72 65 61 74 65 72 20 74 68 61 6e   or greater than
68b0: 20 74 68 65 20 73 75 6d 20 6f 66 20 6e 4d 61 78   the sum of nMax
68c0: 20 66 6f 72 20 61 6c 6c 0a 2a 2a 20 20 20 20 20   for all.**     
68d0: 20 20 20 20 20 20 70 75 72 67 65 61 62 6c 65 20        purgeable 
68e0: 63 61 63 68 65 73 2c 0a 2a 2a 0a 2a 2a 20 20 20  caches,.**.**   
68f0: 20 20 20 20 28 63 29 20 54 68 65 20 73 79 73 74      (c) The syst
6900: 65 6d 20 69 73 20 75 6e 64 65 72 20 6d 65 6d 6f  em is under memo
6910: 72 79 20 70 72 65 73 73 75 72 65 20 61 6e 64 20  ry pressure and 
6920: 77 61 6e 74 73 20 74 6f 20 61 76 6f 69 64 0a 2a  wants to avoid.*
6930: 2a 20 20 20 20 20 20 20 20 20 20 20 75 6e 6e 65  *           unne
6940: 63 65 73 73 61 72 79 20 70 61 67 65 73 20 63 61  cessary pages ca
6950: 63 68 65 20 65 6e 74 72 79 20 61 6c 6c 6f 63 61  che entry alloca
6960: 74 69 6f 6e 73 0a 2a 2a 0a 2a 2a 20 20 20 20 20  tions.**.**     
6970: 20 74 68 65 6e 20 61 74 74 65 6d 70 74 20 74 6f   then attempt to
6980: 20 72 65 63 79 63 6c 65 20 61 20 70 61 67 65 20   recycle a page 
6990: 66 72 6f 6d 20 74 68 65 20 4c 52 55 20 6c 69 73  from the LRU lis
69a0: 74 2e 20 49 66 20 69 74 20 69 73 20 74 68 65 20  t. If it is the 
69b0: 72 69 67 68 74 0a 2a 2a 20 20 20 20 20 20 73 69  right.**      si
69c0: 7a 65 2c 20 72 65 74 75 72 6e 20 74 68 65 20 72  ze, return the r
69d0: 65 63 79 63 6c 65 64 20 62 75 66 66 65 72 2e 20  ecycled buffer. 
69e0: 4f 74 68 65 72 77 69 73 65 2c 20 66 72 65 65 20  Otherwise, free 
69f0: 74 68 65 20 62 75 66 66 65 72 20 61 6e 64 0a 2a  the buffer and.*
6a00: 2a 20 20 20 20 20 20 70 72 6f 63 65 65 64 20 74  *      proceed t
6a10: 6f 20 73 74 65 70 20 35 2e 20 0a 2a 2a 0a 2a 2a  o step 5. .**.**
6a20: 20 20 20 35 2e 20 4f 74 68 65 72 77 69 73 65 2c     5. Otherwise,
6a30: 20 61 6c 6c 6f 63 61 74 65 20 61 6e 64 20 72 65   allocate and re
6a40: 74 75 72 6e 20 61 20 6e 65 77 20 70 61 67 65 20  turn a new page 
6a50: 62 75 66 66 65 72 2e 0a 2a 2a 0a 2a 2a 20 54 68  buffer..**.** Th
6a60: 65 72 65 20 61 72 65 20 74 77 6f 20 76 65 72 73  ere are two vers
6a70: 69 6f 6e 73 20 6f 66 20 74 68 69 73 20 72 6f 75  ions of this rou
6a80: 74 69 6e 65 2e 20 20 70 63 61 63 68 65 31 46 65  tine.  pcache1Fe
6a90: 74 63 68 57 69 74 68 4d 75 74 65 78 28 29 20 69  tchWithMutex() i
6aa0: 73 0a 2a 2a 20 74 68 65 20 67 65 6e 65 72 61 6c  s.** the general
6ab0: 20 63 61 73 65 2e 20 20 70 63 61 63 68 65 31 46   case.  pcache1F
6ac0: 65 74 63 68 4e 6f 4d 75 74 65 78 28 29 20 69 73  etchNoMutex() is
6ad0: 20 61 20 66 61 73 74 65 72 20 69 6d 70 6c 65 6d   a faster implem
6ae0: 65 6e 74 61 74 69 6f 6e 20 66 6f 72 0a 2a 2a 20  entation for.** 
6af0: 74 68 65 20 63 6f 6d 6d 6f 6e 20 63 61 73 65 20  the common case 
6b00: 77 68 65 72 65 20 70 47 72 6f 75 70 2d 3e 6d 75  where pGroup->mu
6b10: 74 65 78 20 69 73 20 4e 55 4c 4c 2e 20 20 54 68  tex is NULL.  Th
6b20: 65 20 70 63 61 63 68 65 31 46 65 74 63 68 28 29  e pcache1Fetch()
6b30: 20 77 72 61 70 70 65 72 0a 2a 2a 20 69 6e 76 6f   wrapper.** invo
6b40: 6b 65 73 20 74 68 65 20 61 70 70 72 6f 70 72 69  kes the appropri
6b50: 61 74 65 20 72 6f 75 74 69 6e 65 2e 0a 2a 2f 0a  ate routine..*/.
6b60: 73 74 61 74 69 63 20 50 67 48 64 72 31 20 2a 70  static PgHdr1 *p
6b70: 63 61 63 68 65 31 46 65 74 63 68 4e 6f 4d 75 74  cache1FetchNoMut
6b80: 65 78 28 0a 20 20 73 71 6c 69 74 65 33 5f 70 63  ex(.  sqlite3_pc
6b90: 61 63 68 65 20 2a 70 2c 20 0a 20 20 75 6e 73 69  ache *p, .  unsi
6ba0: 67 6e 65 64 20 69 6e 74 20 69 4b 65 79 2c 20 0a  gned int iKey, .
6bb0: 20 20 69 6e 74 20 63 72 65 61 74 65 46 6c 61 67    int createFlag
6bc0: 0a 29 7b 0a 20 20 50 43 61 63 68 65 31 20 2a 70  .){.  PCache1 *p
6bd0: 43 61 63 68 65 20 3d 20 28 50 43 61 63 68 65 31  Cache = (PCache1
6be0: 20 2a 29 70 3b 0a 20 20 50 67 48 64 72 31 20 2a   *)p;.  PgHdr1 *
6bf0: 70 50 61 67 65 20 3d 20 30 3b 0a 0a 20 20 2f 2a  pPage = 0;..  /*
6c00: 20 53 74 65 70 20 31 3a 20 53 65 61 72 63 68 20   Step 1: Search 
6c10: 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 20 66  the hash table f
6c20: 6f 72 20 61 6e 20 65 78 69 73 74 69 6e 67 20 65  or an existing e
6c30: 6e 74 72 79 2e 20 2a 2f 0a 20 20 70 50 61 67 65  ntry. */.  pPage
6c40: 20 3d 20 70 43 61 63 68 65 2d 3e 61 70 48 61 73   = pCache->apHas
6c50: 68 5b 69 4b 65 79 20 25 20 70 43 61 63 68 65 2d  h[iKey % pCache-
6c60: 3e 6e 48 61 73 68 5d 3b 0a 20 20 77 68 69 6c 65  >nHash];.  while
6c70: 28 20 70 50 61 67 65 20 26 26 20 70 50 61 67 65  ( pPage && pPage
6c80: 2d 3e 69 4b 65 79 21 3d 69 4b 65 79 20 29 7b 20  ->iKey!=iKey ){ 
6c90: 70 50 61 67 65 20 3d 20 70 50 61 67 65 2d 3e 70  pPage = pPage->p
6ca0: 4e 65 78 74 3b 20 7d 0a 0a 20 20 2f 2a 20 53 74  Next; }..  /* St
6cb0: 65 70 20 32 3a 20 41 62 6f 72 74 20 69 66 20 6e  ep 2: Abort if n
6cc0: 6f 20 65 78 69 73 74 69 6e 67 20 70 61 67 65 20  o existing page 
6cd0: 69 73 20 66 6f 75 6e 64 20 61 6e 64 20 63 72 65  is found and cre
6ce0: 61 74 65 46 6c 61 67 20 69 73 20 30 20 2a 2f 0a  ateFlag is 0 */.
6cf0: 20 20 69 66 28 20 70 50 61 67 65 20 29 7b 0a 20    if( pPage ){. 
6d00: 20 20 20 69 66 28 20 21 70 50 61 67 65 2d 3e 69     if( !pPage->i
6d10: 73 50 69 6e 6e 65 64 20 29 7b 0a 20 20 20 20 20  sPinned ){.     
6d20: 20 72 65 74 75 72 6e 20 70 63 61 63 68 65 31 50   return pcache1P
6d30: 69 6e 50 61 67 65 28 70 50 61 67 65 29 3b 0a 20  inPage(pPage);. 
6d40: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
6d50: 72 65 74 75 72 6e 20 70 50 61 67 65 3b 0a 20 20  return pPage;.  
6d60: 20 20 7d 0a 20 20 7d 65 6c 73 65 20 69 66 28 20    }.  }else if( 
6d70: 63 72 65 61 74 65 46 6c 61 67 20 29 7b 0a 20 20  createFlag ){.  
6d80: 20 20 2f 2a 20 53 74 65 70 73 20 33 2c 20 34 2c    /* Steps 3, 4,
6d90: 20 61 6e 64 20 35 20 69 6d 70 6c 65 6d 65 6e 74   and 5 implement
6da0: 65 64 20 62 79 20 74 68 69 73 20 73 75 62 72 6f  ed by this subro
6db0: 75 74 69 6e 65 20 2a 2f 0a 20 20 20 20 72 65 74  utine */.    ret
6dc0: 75 72 6e 20 70 63 61 63 68 65 31 46 65 74 63 68  urn pcache1Fetch
6dd0: 53 74 61 67 65 32 28 70 43 61 63 68 65 2c 20 69  Stage2(pCache, i
6de0: 4b 65 79 2c 20 63 72 65 61 74 65 46 6c 61 67 29  Key, createFlag)
6df0: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 72  ;.  }else{.    r
6e00: 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 7d 0a 23  eturn 0;.  }.}.#
6e10: 69 66 20 50 43 41 43 48 45 31 5f 4d 49 47 48 54  if PCACHE1_MIGHT
6e20: 5f 55 53 45 5f 47 52 4f 55 50 5f 4d 55 54 45 58  _USE_GROUP_MUTEX
6e30: 0a 73 74 61 74 69 63 20 50 67 48 64 72 31 20 2a  .static PgHdr1 *
6e40: 70 63 61 63 68 65 31 46 65 74 63 68 57 69 74 68  pcache1FetchWith
6e50: 4d 75 74 65 78 28 0a 20 20 73 71 6c 69 74 65 33  Mutex(.  sqlite3
6e60: 5f 70 63 61 63 68 65 20 2a 70 2c 20 0a 20 20 75  _pcache *p, .  u
6e70: 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4b 65 79  nsigned int iKey
6e80: 2c 20 0a 20 20 69 6e 74 20 63 72 65 61 74 65 46  , .  int createF
6e90: 6c 61 67 0a 29 7b 0a 20 20 50 43 61 63 68 65 31  lag.){.  PCache1
6ea0: 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61 63   *pCache = (PCac
6eb0: 68 65 31 20 2a 29 70 3b 0a 20 20 50 67 48 64 72  he1 *)p;.  PgHdr
6ec0: 31 20 2a 70 50 61 67 65 3b 0a 0a 20 20 70 63 61  1 *pPage;..  pca
6ed0: 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70  che1EnterMutex(p
6ee0: 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a  Cache->pGroup);.
6ef0: 20 20 70 50 61 67 65 20 3d 20 70 63 61 63 68 65    pPage = pcache
6f00: 31 46 65 74 63 68 4e 6f 4d 75 74 65 78 28 70 2c  1FetchNoMutex(p,
6f10: 20 69 4b 65 79 2c 20 63 72 65 61 74 65 46 6c 61   iKey, createFla
6f20: 67 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 50  g);.  assert( pP
6f30: 61 67 65 3d 3d 30 20 7c 7c 20 70 43 61 63 68 65  age==0 || pCache
6f40: 2d 3e 69 4d 61 78 4b 65 79 3e 3d 69 4b 65 79 20  ->iMaxKey>=iKey 
6f50: 29 3b 0a 20 20 70 63 61 63 68 65 31 4c 65 61 76  );.  pcache1Leav
6f60: 65 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e 70  eMutex(pCache->p
6f70: 47 72 6f 75 70 29 3b 0a 20 20 72 65 74 75 72 6e  Group);.  return
6f80: 20 70 50 61 67 65 3b 0a 7d 0a 23 65 6e 64 69 66   pPage;.}.#endif
6f90: 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65 33 5f  .static sqlite3_
6fa0: 70 63 61 63 68 65 5f 70 61 67 65 20 2a 70 63 61  pcache_page *pca
6fb0: 63 68 65 31 46 65 74 63 68 28 0a 20 20 73 71 6c  che1Fetch(.  sql
6fc0: 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70 2c 20  ite3_pcache *p, 
6fd0: 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  .  unsigned int 
6fe0: 69 4b 65 79 2c 20 0a 20 20 69 6e 74 20 63 72 65  iKey, .  int cre
6ff0: 61 74 65 46 6c 61 67 0a 29 7b 0a 23 69 66 20 50  ateFlag.){.#if P
7000: 43 41 43 48 45 31 5f 4d 49 47 48 54 5f 55 53 45  CACHE1_MIGHT_USE
7010: 5f 47 52 4f 55 50 5f 4d 55 54 45 58 20 7c 7c 20  _GROUP_MUTEX || 
7020: 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 44  defined(SQLITE_D
7030: 45 42 55 47 29 0a 20 20 50 43 61 63 68 65 31 20  EBUG).  PCache1 
7040: 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61 63 68  *pCache = (PCach
7050: 65 31 20 2a 29 70 3b 0a 23 65 6e 64 69 66 0a 0a  e1 *)p;.#endif..
7060: 20 20 61 73 73 65 72 74 28 20 6f 66 66 73 65 74    assert( offset
7070: 6f 66 28 50 67 48 64 72 31 2c 70 61 67 65 29 3d  of(PgHdr1,page)=
7080: 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  =0 );.  assert( 
7090: 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62  pCache->bPurgeab
70a0: 6c 65 20 7c 7c 20 63 72 65 61 74 65 46 6c 61 67  le || createFlag
70b0: 21 3d 31 20 29 3b 0a 20 20 61 73 73 65 72 74 28  !=1 );.  assert(
70c0: 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61   pCache->bPurgea
70d0: 62 6c 65 20 7c 7c 20 70 43 61 63 68 65 2d 3e 6e  ble || pCache->n
70e0: 4d 69 6e 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65  Min==0 );.  asse
70f0: 72 74 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72  rt( pCache->bPur
7100: 67 65 61 62 6c 65 3d 3d 30 20 7c 7c 20 70 43 61  geable==0 || pCa
7110: 63 68 65 2d 3e 6e 4d 69 6e 3d 3d 31 30 20 29 3b  che->nMin==10 );
7120: 0a 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68  .  assert( pCach
7130: 65 2d 3e 6e 4d 69 6e 3d 3d 30 20 7c 7c 20 70 43  e->nMin==0 || pC
7140: 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65  ache->bPurgeable
7150: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 43   );.  assert( pC
7160: 61 63 68 65 2d 3e 6e 48 61 73 68 3e 30 20 29 3b  ache->nHash>0 );
7170: 0a 23 69 66 20 50 43 41 43 48 45 31 5f 4d 49 47  .#if PCACHE1_MIG
7180: 48 54 5f 55 53 45 5f 47 52 4f 55 50 5f 4d 55 54  HT_USE_GROUP_MUT
7190: 45 58 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d  EX.  if( pCache-
71a0: 3e 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78 20 29  >pGroup->mutex )
71b0: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 28 73 71  {.    return (sq
71c0: 6c 69 74 65 33 5f 70 63 61 63 68 65 5f 70 61 67  lite3_pcache_pag
71d0: 65 2a 29 70 63 61 63 68 65 31 46 65 74 63 68 57  e*)pcache1FetchW
71e0: 69 74 68 4d 75 74 65 78 28 70 2c 20 69 4b 65 79  ithMutex(p, iKey
71f0: 2c 20 63 72 65 61 74 65 46 6c 61 67 29 3b 0a 20  , createFlag);. 
7200: 20 7d 65 6c 73 65 0a 23 65 6e 64 69 66 0a 20 20   }else.#endif.  
7210: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 28 73 71  {.    return (sq
7220: 6c 69 74 65 33 5f 70 63 61 63 68 65 5f 70 61 67  lite3_pcache_pag
7230: 65 2a 29 70 63 61 63 68 65 31 46 65 74 63 68 4e  e*)pcache1FetchN
7240: 6f 4d 75 74 65 78 28 70 2c 20 69 4b 65 79 2c 20  oMutex(p, iKey, 
7250: 63 72 65 61 74 65 46 6c 61 67 29 3b 0a 20 20 7d  createFlag);.  }
7260: 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65  .}.../*.** Imple
7270: 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65  mentation of the
7280: 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e   sqlite3_pcache.
7290: 78 55 6e 70 69 6e 20 6d 65 74 68 6f 64 2e 0a 2a  xUnpin method..*
72a0: 2a 0a 2a 2a 20 4d 61 72 6b 20 61 20 70 61 67 65  *.** Mark a page
72b0: 20 61 73 20 75 6e 70 69 6e 6e 65 64 20 28 65 6c   as unpinned (el
72c0: 69 67 69 62 6c 65 20 66 6f 72 20 61 73 79 6e 63  igible for async
72d0: 68 72 6f 6e 6f 75 73 20 72 65 63 79 63 6c 69 6e  hronous recyclin
72e0: 67 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  g)..*/.static vo
72f0: 69 64 20 70 63 61 63 68 65 31 55 6e 70 69 6e 28  id pcache1Unpin(
7300: 0a 20 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68  .  sqlite3_pcach
7310: 65 20 2a 70 2c 20 0a 20 20 73 71 6c 69 74 65 33  e *p, .  sqlite3
7320: 5f 70 63 61 63 68 65 5f 70 61 67 65 20 2a 70 50  _pcache_page *pP
7330: 67 2c 20 0a 20 20 69 6e 74 20 72 65 75 73 65 55  g, .  int reuseU
7340: 6e 6c 69 6b 65 6c 79 0a 29 7b 0a 20 20 50 43 61  nlikely.){.  PCa
7350: 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28  che1 *pCache = (
7360: 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20 20 50  PCache1 *)p;.  P
7370: 67 48 64 72 31 20 2a 70 50 61 67 65 20 3d 20 28  gHdr1 *pPage = (
7380: 50 67 48 64 72 31 20 2a 29 70 50 67 3b 0a 20 20  PgHdr1 *)pPg;.  
7390: 50 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 20 3d  PGroup *pGroup =
73a0: 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b   pCache->pGroup;
73b0: 0a 20 0a 20 20 61 73 73 65 72 74 28 20 70 50 61  . .  assert( pPa
73c0: 67 65 2d 3e 70 43 61 63 68 65 3d 3d 70 43 61 63  ge->pCache==pCac
73d0: 68 65 20 29 3b 0a 20 20 70 63 61 63 68 65 31 45  he );.  pcache1E
73e0: 6e 74 65 72 4d 75 74 65 78 28 70 47 72 6f 75 70  nterMutex(pGroup
73f0: 29 3b 0a 0a 20 20 2f 2a 20 49 74 20 69 73 20 61  );..  /* It is a
7400: 6e 20 65 72 72 6f 72 20 74 6f 20 63 61 6c 6c 20  n error to call 
7410: 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 66  this function if
7420: 20 74 68 65 20 70 61 67 65 20 69 73 20 61 6c 72   the page is alr
7430: 65 61 64 79 20 0a 20 20 2a 2a 20 70 61 72 74 20  eady .  ** part 
7440: 6f 66 20 74 68 65 20 50 47 72 6f 75 70 20 4c 52  of the PGroup LR
7450: 55 20 6c 69 73 74 2e 0a 20 20 2a 2f 0a 20 20 61  U list..  */.  a
7460: 73 73 65 72 74 28 20 70 50 61 67 65 2d 3e 70 4c  ssert( pPage->pL
7470: 72 75 50 72 65 76 3d 3d 30 20 26 26 20 70 50 61  ruPrev==0 && pPa
7480: 67 65 2d 3e 70 4c 72 75 4e 65 78 74 3d 3d 30 20  ge->pLruNext==0 
7490: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 47 72  );.  assert( pGr
74a0: 6f 75 70 2d 3e 70 4c 72 75 48 65 61 64 21 3d 70  oup->pLruHead!=p
74b0: 50 61 67 65 20 26 26 20 70 47 72 6f 75 70 2d 3e  Page && pGroup->
74c0: 70 4c 72 75 54 61 69 6c 21 3d 70 50 61 67 65 20  pLruTail!=pPage 
74d0: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 50 61  );.  assert( pPa
74e0: 67 65 2d 3e 69 73 50 69 6e 6e 65 64 3d 3d 31 20  ge->isPinned==1 
74f0: 29 3b 0a 0a 20 20 69 66 28 20 72 65 75 73 65 55  );..  if( reuseU
7500: 6e 6c 69 6b 65 6c 79 20 7c 7c 20 70 47 72 6f 75  nlikely || pGrou
7510: 70 2d 3e 6e 43 75 72 72 65 6e 74 50 61 67 65 3e  p->nCurrentPage>
7520: 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65  pGroup->nMaxPage
7530: 20 29 7b 0a 20 20 20 20 70 63 61 63 68 65 31 52   ){.    pcache1R
7540: 65 6d 6f 76 65 46 72 6f 6d 48 61 73 68 28 70 50  emoveFromHash(pP
7550: 61 67 65 29 3b 0a 20 20 20 20 70 63 61 63 68 65  age);.    pcache
7560: 31 46 72 65 65 50 61 67 65 28 70 50 61 67 65 29  1FreePage(pPage)
7570: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 2f  ;.  }else{.    /
7580: 2a 20 41 64 64 20 74 68 65 20 70 61 67 65 20 74  * Add the page t
7590: 6f 20 74 68 65 20 50 47 72 6f 75 70 20 4c 52 55  o the PGroup LRU
75a0: 20 6c 69 73 74 2e 20 2a 2f 0a 20 20 20 20 69 66   list. */.    if
75b0: 28 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 48 65  ( pGroup->pLruHe
75c0: 61 64 20 29 7b 0a 20 20 20 20 20 20 70 47 72 6f  ad ){.      pGro
75d0: 75 70 2d 3e 70 4c 72 75 48 65 61 64 2d 3e 70 4c  up->pLruHead->pL
75e0: 72 75 50 72 65 76 20 3d 20 70 50 61 67 65 3b 0a  ruPrev = pPage;.
75f0: 20 20 20 20 20 20 70 50 61 67 65 2d 3e 70 4c 72        pPage->pLr
7600: 75 4e 65 78 74 20 3d 20 70 47 72 6f 75 70 2d 3e  uNext = pGroup->
7610: 70 4c 72 75 48 65 61 64 3b 0a 20 20 20 20 20 20  pLruHead;.      
7620: 70 47 72 6f 75 70 2d 3e 70 4c 72 75 48 65 61 64  pGroup->pLruHead
7630: 20 3d 20 70 50 61 67 65 3b 0a 20 20 20 20 7d 65   = pPage;.    }e
7640: 6c 73 65 7b 0a 20 20 20 20 20 20 70 47 72 6f 75  lse{.      pGrou
7650: 70 2d 3e 70 4c 72 75 54 61 69 6c 20 3d 20 70 50  p->pLruTail = pP
7660: 61 67 65 3b 0a 20 20 20 20 20 20 70 47 72 6f 75  age;.      pGrou
7670: 70 2d 3e 70 4c 72 75 48 65 61 64 20 3d 20 70 50  p->pLruHead = pP
7680: 61 67 65 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70  age;.    }.    p
7690: 43 61 63 68 65 2d 3e 6e 52 65 63 79 63 6c 61 62  Cache->nRecyclab
76a0: 6c 65 2b 2b 3b 0a 20 20 20 20 70 50 61 67 65 2d  le++;.    pPage-
76b0: 3e 69 73 50 69 6e 6e 65 64 20 3d 20 30 3b 0a 20  >isPinned = 0;. 
76c0: 20 7d 0a 0a 20 20 70 63 61 63 68 65 31 4c 65 61   }..  pcache1Lea
76d0: 76 65 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e  veMutex(pCache->
76e0: 70 47 72 6f 75 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  pGroup);.}../*.*
76f0: 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  * Implementation
7700: 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f   of the sqlite3_
7710: 70 63 61 63 68 65 2e 78 52 65 6b 65 79 20 6d 65  pcache.xRekey me
7720: 74 68 6f 64 2e 20 0a 2a 2f 0a 73 74 61 74 69 63  thod. .*/.static
7730: 20 76 6f 69 64 20 70 63 61 63 68 65 31 52 65 6b   void pcache1Rek
7740: 65 79 28 0a 20 20 73 71 6c 69 74 65 33 5f 70 63  ey(.  sqlite3_pc
7750: 61 63 68 65 20 2a 70 2c 0a 20 20 73 71 6c 69 74  ache *p,.  sqlit
7760: 65 33 5f 70 63 61 63 68 65 5f 70 61 67 65 20 2a  e3_pcache_page *
7770: 70 50 67 2c 0a 20 20 75 6e 73 69 67 6e 65 64 20  pPg,.  unsigned 
7780: 69 6e 74 20 69 4f 6c 64 2c 0a 20 20 75 6e 73 69  int iOld,.  unsi
7790: 67 6e 65 64 20 69 6e 74 20 69 4e 65 77 0a 29 7b  gned int iNew.){
77a0: 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63  .  PCache1 *pCac
77b0: 68 65 20 3d 20 28 50 43 61 63 68 65 31 20 2a 29  he = (PCache1 *)
77c0: 70 3b 0a 20 20 50 67 48 64 72 31 20 2a 70 50 61  p;.  PgHdr1 *pPa
77d0: 67 65 20 3d 20 28 50 67 48 64 72 31 20 2a 29 70  ge = (PgHdr1 *)p
77e0: 50 67 3b 0a 20 20 50 67 48 64 72 31 20 2a 2a 70  Pg;.  PgHdr1 **p
77f0: 70 3b 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e  p;.  unsigned in
7800: 74 20 68 3b 20 0a 20 20 61 73 73 65 72 74 28 20  t h; .  assert( 
7810: 70 50 61 67 65 2d 3e 69 4b 65 79 3d 3d 69 4f 6c  pPage->iKey==iOl
7820: 64 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70  d );.  assert( p
7830: 50 61 67 65 2d 3e 70 43 61 63 68 65 3d 3d 70 43  Page->pCache==pC
7840: 61 63 68 65 20 29 3b 0a 0a 20 20 70 63 61 63 68  ache );..  pcach
7850: 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70 43 61  e1EnterMutex(pCa
7860: 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 0a 20  che->pGroup);.. 
7870: 20 68 20 3d 20 69 4f 6c 64 25 70 43 61 63 68 65   h = iOld%pCache
7880: 2d 3e 6e 48 61 73 68 3b 0a 20 20 70 70 20 3d 20  ->nHash;.  pp = 
7890: 26 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b  &pCache->apHash[
78a0: 68 5d 3b 0a 20 20 77 68 69 6c 65 28 20 28 2a 70  h];.  while( (*p
78b0: 70 29 21 3d 70 50 61 67 65 20 29 7b 0a 20 20 20  p)!=pPage ){.   
78c0: 20 70 70 20 3d 20 26 28 2a 70 70 29 2d 3e 70 4e   pp = &(*pp)->pN
78d0: 65 78 74 3b 0a 20 20 7d 0a 20 20 2a 70 70 20 3d  ext;.  }.  *pp =
78e0: 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 3b 0a 0a   pPage->pNext;..
78f0: 20 20 68 20 3d 20 69 4e 65 77 25 70 43 61 63 68    h = iNew%pCach
7900: 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 70 50 61 67  e->nHash;.  pPag
7910: 65 2d 3e 69 4b 65 79 20 3d 20 69 4e 65 77 3b 0a  e->iKey = iNew;.
7920: 20 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 20 3d    pPage->pNext =
7930: 20 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b   pCache->apHash[
7940: 68 5d 3b 0a 20 20 70 43 61 63 68 65 2d 3e 61 70  h];.  pCache->ap
7950: 48 61 73 68 5b 68 5d 20 3d 20 70 50 61 67 65 3b  Hash[h] = pPage;
7960: 0a 20 20 69 66 28 20 69 4e 65 77 3e 70 43 61 63  .  if( iNew>pCac
7970: 68 65 2d 3e 69 4d 61 78 4b 65 79 20 29 7b 0a 20  he->iMaxKey ){. 
7980: 20 20 20 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b     pCache->iMaxK
7990: 65 79 20 3d 20 69 4e 65 77 3b 0a 20 20 7d 0a 0a  ey = iNew;.  }..
79a0: 20 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75    pcache1LeaveMu
79b0: 74 65 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f  tex(pCache->pGro
79c0: 75 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d  up);.}../*.** Im
79d0: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20  plementation of 
79e0: 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63  the sqlite3_pcac
79f0: 68 65 2e 78 54 72 75 6e 63 61 74 65 20 6d 65 74  he.xTruncate met
7a00: 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20 44 69 73 63  hod. .**.** Disc
7a10: 61 72 64 20 61 6c 6c 20 75 6e 70 69 6e 6e 65 64  ard all unpinned
7a20: 20 70 61 67 65 73 20 69 6e 20 74 68 65 20 63 61   pages in the ca
7a30: 63 68 65 20 77 69 74 68 20 61 20 70 61 67 65 20  che with a page 
7a40: 6e 75 6d 62 65 72 20 65 71 75 61 6c 20 74 6f 0a  number equal to.
7a50: 2a 2a 20 6f 72 20 67 72 65 61 74 65 72 20 74 68  ** or greater th
7a60: 61 6e 20 70 61 72 61 6d 65 74 65 72 20 69 4c 69  an parameter iLi
7a70: 6d 69 74 2e 20 41 6e 79 20 70 69 6e 6e 65 64 20  mit. Any pinned 
7a80: 70 61 67 65 73 20 77 69 74 68 20 61 20 70 61 67  pages with a pag
7a90: 65 20 6e 75 6d 62 65 72 0a 2a 2a 20 65 71 75 61  e number.** equa
7aa0: 6c 20 74 6f 20 6f 72 20 67 72 65 61 74 65 72 20  l to or greater 
7ab0: 74 68 61 6e 20 69 4c 69 6d 69 74 20 61 72 65 20  than iLimit are 
7ac0: 69 6d 70 6c 69 63 69 74 6c 79 20 75 6e 70 69 6e  implicitly unpin
7ad0: 6e 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ned..*/.static v
7ae0: 6f 69 64 20 70 63 61 63 68 65 31 54 72 75 6e 63  oid pcache1Trunc
7af0: 61 74 65 28 73 71 6c 69 74 65 33 5f 70 63 61 63  ate(sqlite3_pcac
7b00: 68 65 20 2a 70 2c 20 75 6e 73 69 67 6e 65 64 20  he *p, unsigned 
7b10: 69 6e 74 20 69 4c 69 6d 69 74 29 7b 0a 20 20 50  int iLimit){.  P
7b20: 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d  Cache1 *pCache =
7b30: 20 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20   (PCache1 *)p;. 
7b40: 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74   pcache1EnterMut
7b50: 65 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75  ex(pCache->pGrou
7b60: 70 29 3b 0a 20 20 69 66 28 20 69 4c 69 6d 69 74  p);.  if( iLimit
7b70: 3c 3d 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b 65  <=pCache->iMaxKe
7b80: 79 20 29 7b 0a 20 20 20 20 70 63 61 63 68 65 31  y ){.    pcache1
7b90: 54 72 75 6e 63 61 74 65 55 6e 73 61 66 65 28 70  TruncateUnsafe(p
7ba0: 43 61 63 68 65 2c 20 69 4c 69 6d 69 74 29 3b 0a  Cache, iLimit);.
7bb0: 20 20 20 20 70 43 61 63 68 65 2d 3e 69 4d 61 78      pCache->iMax
7bc0: 4b 65 79 20 3d 20 69 4c 69 6d 69 74 2d 31 3b 0a  Key = iLimit-1;.
7bd0: 20 20 7d 0a 20 20 70 63 61 63 68 65 31 4c 65 61    }.  pcache1Lea
7be0: 76 65 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e  veMutex(pCache->
7bf0: 70 47 72 6f 75 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  pGroup);.}../*.*
7c00: 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  * Implementation
7c10: 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f   of the sqlite3_
7c20: 70 63 61 63 68 65 2e 78 44 65 73 74 72 6f 79 20  pcache.xDestroy 
7c30: 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20 44  method. .**.** D
7c40: 65 73 74 72 6f 79 20 61 20 63 61 63 68 65 20 61  estroy a cache a
7c50: 6c 6c 6f 63 61 74 65 64 20 75 73 69 6e 67 20 70  llocated using p
7c60: 63 61 63 68 65 31 43 72 65 61 74 65 28 29 2e 0a  cache1Create()..
7c70: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70  */.static void p
7c80: 63 61 63 68 65 31 44 65 73 74 72 6f 79 28 73 71  cache1Destroy(sq
7c90: 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70 29  lite3_pcache *p)
7ca0: 7b 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43 61  {.  PCache1 *pCa
7cb0: 63 68 65 20 3d 20 28 50 43 61 63 68 65 31 20 2a  che = (PCache1 *
7cc0: 29 70 3b 0a 20 20 50 47 72 6f 75 70 20 2a 70 47  )p;.  PGroup *pG
7cd0: 72 6f 75 70 20 3d 20 70 43 61 63 68 65 2d 3e 70  roup = pCache->p
7ce0: 47 72 6f 75 70 3b 0a 20 20 61 73 73 65 72 74 28  Group;.  assert(
7cf0: 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61   pCache->bPurgea
7d00: 62 6c 65 20 7c 7c 20 28 70 43 61 63 68 65 2d 3e  ble || (pCache->
7d10: 6e 4d 61 78 3d 3d 30 20 26 26 20 70 43 61 63 68  nMax==0 && pCach
7d20: 65 2d 3e 6e 4d 69 6e 3d 3d 30 29 20 29 3b 0a 20  e->nMin==0) );. 
7d30: 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74   pcache1EnterMut
7d40: 65 78 28 70 47 72 6f 75 70 29 3b 0a 20 20 70 63  ex(pGroup);.  pc
7d50: 61 63 68 65 31 54 72 75 6e 63 61 74 65 55 6e 73  ache1TruncateUns
7d60: 61 66 65 28 70 43 61 63 68 65 2c 20 30 29 3b 0a  afe(pCache, 0);.
7d70: 20 20 61 73 73 65 72 74 28 20 70 47 72 6f 75 70    assert( pGroup
7d80: 2d 3e 6e 4d 61 78 50 61 67 65 20 3e 3d 20 70 43  ->nMaxPage >= pC
7d90: 61 63 68 65 2d 3e 6e 4d 61 78 20 29 3b 0a 20 20  ache->nMax );.  
7da0: 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65  pGroup->nMaxPage
7db0: 20 2d 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78   -= pCache->nMax
7dc0: 3b 0a 20 20 61 73 73 65 72 74 28 20 70 47 72 6f  ;.  assert( pGro
7dd0: 75 70 2d 3e 6e 4d 69 6e 50 61 67 65 20 3e 3d 20  up->nMinPage >= 
7de0: 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 20 29 3b 0a  pCache->nMin );.
7df0: 20 20 70 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61    pGroup->nMinPa
7e00: 67 65 20 2d 3d 20 70 43 61 63 68 65 2d 3e 6e 4d  ge -= pCache->nM
7e10: 69 6e 3b 0a 20 20 70 47 72 6f 75 70 2d 3e 6d 78  in;.  pGroup->mx
7e20: 50 69 6e 6e 65 64 20 3d 20 70 47 72 6f 75 70 2d  Pinned = pGroup-
7e30: 3e 6e 4d 61 78 50 61 67 65 20 2b 20 31 30 20 2d  >nMaxPage + 10 -
7e40: 20 70 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67   pGroup->nMinPag
7e50: 65 3b 0a 20 20 70 63 61 63 68 65 31 45 6e 66 6f  e;.  pcache1Enfo
7e60: 72 63 65 4d 61 78 50 61 67 65 28 70 47 72 6f 75  rceMaxPage(pGrou
7e70: 70 29 3b 0a 20 20 70 63 61 63 68 65 31 4c 65 61  p);.  pcache1Lea
7e80: 76 65 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b  veMutex(pGroup);
7e90: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
7ea0: 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 29 3b  pCache->apHash);
7eb0: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
7ec0: 70 43 61 63 68 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  pCache);.}../*.*
7ed0: 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  * This function 
7ee0: 69 73 20 63 61 6c 6c 65 64 20 64 75 72 69 6e 67  is called during
7ef0: 20 69 6e 69 74 69 61 6c 69 7a 61 74 69 6f 6e 20   initialization 
7f00: 28 73 71 6c 69 74 65 33 5f 69 6e 69 74 69 61 6c  (sqlite3_initial
7f10: 69 7a 65 28 29 29 20 74 6f 0a 2a 2a 20 69 6e 73  ize()) to.** ins
7f20: 74 61 6c 6c 20 74 68 65 20 64 65 66 61 75 6c 74  tall the default
7f30: 20 70 6c 75 67 67 61 62 6c 65 20 63 61 63 68 65   pluggable cache
7f40: 20 6d 6f 64 75 6c 65 2c 20 61 73 73 75 6d 69 6e   module, assumin
7f50: 67 20 74 68 65 20 75 73 65 72 20 68 61 73 20 6e  g the user has n
7f60: 6f 74 0a 2a 2a 20 61 6c 72 65 61 64 79 20 70 72  ot.** already pr
7f70: 6f 76 69 64 65 64 20 61 6e 20 61 6c 74 65 72 6e  ovided an altern
7f80: 61 74 69 76 65 2e 0a 2a 2f 0a 76 6f 69 64 20 73  ative..*/.void s
7f90: 71 6c 69 74 65 33 50 43 61 63 68 65 53 65 74 44  qlite3PCacheSetD
7fa0: 65 66 61 75 6c 74 28 76 6f 69 64 29 7b 0a 20 20  efault(void){.  
7fb0: 73 74 61 74 69 63 20 63 6f 6e 73 74 20 73 71 6c  static const sql
7fc0: 69 74 65 33 5f 70 63 61 63 68 65 5f 6d 65 74 68  ite3_pcache_meth
7fd0: 6f 64 73 32 20 64 65 66 61 75 6c 74 4d 65 74 68  ods2 defaultMeth
7fe0: 6f 64 73 20 3d 20 7b 0a 20 20 20 20 31 2c 20 20  ods = {.    1,  
7ff0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8000: 20 20 20 20 20 2f 2a 20 69 56 65 72 73 69 6f 6e       /* iVersion
8010: 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20 20 20   */.    0,      
8020: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8030: 20 2f 2a 20 70 41 72 67 20 2a 2f 0a 20 20 20 20   /* pArg */.    
8040: 70 63 61 63 68 65 31 49 6e 69 74 2c 20 20 20 20  pcache1Init,    
8050: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 49 6e 69           /* xIni
8060: 74 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31  t */.    pcache1
8070: 53 68 75 74 64 6f 77 6e 2c 20 20 20 20 20 20 20  Shutdown,       
8080: 20 20 2f 2a 20 78 53 68 75 74 64 6f 77 6e 20 2a    /* xShutdown *
8090: 2f 0a 20 20 20 20 70 63 61 63 68 65 31 43 72 65  /.    pcache1Cre
80a0: 61 74 65 2c 20 20 20 20 20 20 20 20 20 20 20 2f  ate,           /
80b0: 2a 20 78 43 72 65 61 74 65 20 2a 2f 0a 20 20 20  * xCreate */.   
80c0: 20 70 63 61 63 68 65 31 43 61 63 68 65 73 69 7a   pcache1Cachesiz
80d0: 65 2c 20 20 20 20 20 20 20 20 2f 2a 20 78 43 61  e,        /* xCa
80e0: 63 68 65 73 69 7a 65 20 2a 2f 0a 20 20 20 20 70  chesize */.    p
80f0: 63 61 63 68 65 31 50 61 67 65 63 6f 75 6e 74 2c  cache1Pagecount,
8100: 20 20 20 20 20 20 20 20 2f 2a 20 78 50 61 67 65          /* xPage
8110: 63 6f 75 6e 74 20 2a 2f 0a 20 20 20 20 70 63 61  count */.    pca
8120: 63 68 65 31 46 65 74 63 68 2c 20 20 20 20 20 20  che1Fetch,      
8130: 20 20 20 20 20 20 2f 2a 20 78 46 65 74 63 68 20        /* xFetch 
8140: 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31 55 6e  */.    pcache1Un
8150: 70 69 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20  pin,            
8160: 2f 2a 20 78 55 6e 70 69 6e 20 2a 2f 0a 20 20 20  /* xUnpin */.   
8170: 20 70 63 61 63 68 65 31 52 65 6b 65 79 2c 20 20   pcache1Rekey,  
8180: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 52 65            /* xRe
8190: 6b 65 79 20 2a 2f 0a 20 20 20 20 70 63 61 63 68  key */.    pcach
81a0: 65 31 54 72 75 6e 63 61 74 65 2c 20 20 20 20 20  e1Truncate,     
81b0: 20 20 20 20 2f 2a 20 78 54 72 75 6e 63 61 74 65      /* xTruncate
81c0: 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31 44   */.    pcache1D
81d0: 65 73 74 72 6f 79 2c 20 20 20 20 20 20 20 20 20  estroy,         
81e0: 20 2f 2a 20 78 44 65 73 74 72 6f 79 20 2a 2f 0a   /* xDestroy */.
81f0: 20 20 20 20 70 63 61 63 68 65 31 53 68 72 69 6e      pcache1Shrin
8200: 6b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  k            /* 
8210: 78 53 68 72 69 6e 6b 20 2a 2f 0a 20 20 7d 3b 0a  xShrink */.  };.
8220: 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67    sqlite3_config
8230: 28 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50  (SQLITE_CONFIG_P
8240: 43 41 43 48 45 32 2c 20 26 64 65 66 61 75 6c 74  CACHE2, &default
8250: 4d 65 74 68 6f 64 73 29 3b 0a 7d 0a 0a 2f 2a 0a  Methods);.}../*.
8260: 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 73 69  ** Return the si
8270: 7a 65 20 6f 66 20 74 68 65 20 68 65 61 64 65 72  ze of the header
8280: 20 6f 6e 20 65 61 63 68 20 70 61 67 65 20 6f 66   on each page of
8290: 20 74 68 69 73 20 50 43 41 43 48 45 20 69 6d 70   this PCACHE imp
82a0: 6c 65 6d 65 6e 74 61 74 69 6f 6e 2e 0a 2a 2f 0a  lementation..*/.
82b0: 69 6e 74 20 73 71 6c 69 74 65 33 48 65 61 64 65  int sqlite3Heade
82c0: 72 53 69 7a 65 50 63 61 63 68 65 31 28 76 6f 69  rSizePcache1(voi
82d0: 64 29 7b 20 72 65 74 75 72 6e 20 52 4f 55 4e 44  d){ return ROUND
82e0: 38 28 73 69 7a 65 6f 66 28 50 67 48 64 72 31 29  8(sizeof(PgHdr1)
82f0: 29 3b 20 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75  ); }../*.** Retu
8300: 72 6e 20 74 68 65 20 67 6c 6f 62 61 6c 20 6d 75  rn the global mu
8310: 74 65 78 20 75 73 65 64 20 62 79 20 74 68 69 73  tex used by this
8320: 20 50 43 41 43 48 45 20 69 6d 70 6c 65 6d 65 6e   PCACHE implemen
8330: 74 61 74 69 6f 6e 2e 20 20 54 68 65 0a 2a 2a 20  tation.  The.** 
8340: 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73 28 29  sqlite3_status()
8350: 20 72 6f 75 74 69 6e 65 20 6e 65 65 64 73 20 61   routine needs a
8360: 63 63 65 73 73 20 74 6f 20 74 68 69 73 20 6d 75  ccess to this mu
8370: 74 65 78 2e 0a 2a 2f 0a 73 71 6c 69 74 65 33 5f  tex..*/.sqlite3_
8380: 6d 75 74 65 78 20 2a 73 71 6c 69 74 65 33 50 63  mutex *sqlite3Pc
8390: 61 63 68 65 31 4d 75 74 65 78 28 76 6f 69 64 29  ache1Mutex(void)
83a0: 7b 0a 20 20 72 65 74 75 72 6e 20 70 63 61 63 68  {.  return pcach
83b0: 65 31 2e 6d 75 74 65 78 3b 0a 7d 0a 0a 23 69 66  e1.mutex;.}..#if
83c0: 64 65 66 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c  def SQLITE_ENABL
83d0: 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d  E_MEMORY_MANAGEM
83e0: 45 4e 54 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66  ENT./*.** This f
83f0: 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65  unction is calle
8400: 64 20 74 6f 20 66 72 65 65 20 73 75 70 65 72 66  d to free superf
8410: 6c 75 6f 75 73 20 64 79 6e 61 6d 69 63 61 6c 6c  luous dynamicall
8420: 79 20 61 6c 6c 6f 63 61 74 65 64 20 6d 65 6d 6f  y allocated memo
8430: 72 79 0a 2a 2a 20 68 65 6c 64 20 62 79 20 74 68  ry.** held by th
8440: 65 20 70 61 67 65 72 20 73 79 73 74 65 6d 2e 20  e pager system. 
8450: 4d 65 6d 6f 72 79 20 69 6e 20 75 73 65 20 62 79  Memory in use by
8460: 20 61 6e 79 20 53 51 4c 69 74 65 20 70 61 67 65   any SQLite page
8470: 72 20 61 6c 6c 6f 63 61 74 65 64 0a 2a 2a 20 62  r allocated.** b
8480: 79 20 74 68 65 20 63 75 72 72 65 6e 74 20 74 68  y the current th
8490: 72 65 61 64 20 6d 61 79 20 62 65 20 73 71 6c 69  read may be sqli
84a0: 74 65 33 5f 66 72 65 65 28 29 65 64 2e 0a 2a 2a  te3_free()ed..**
84b0: 0a 2a 2a 20 6e 52 65 71 20 69 73 20 74 68 65 20  .** nReq is the 
84c0: 6e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20  number of bytes 
84d0: 6f 66 20 6d 65 6d 6f 72 79 20 72 65 71 75 69 72  of memory requir
84e0: 65 64 2e 20 4f 6e 63 65 20 74 68 69 73 20 6d 75  ed. Once this mu
84f0: 63 68 20 68 61 73 0a 2a 2a 20 62 65 65 6e 20 72  ch has.** been r
8500: 65 6c 65 61 73 65 64 2c 20 74 68 65 20 66 75 6e  eleased, the fun
8510: 63 74 69 6f 6e 20 72 65 74 75 72 6e 73 2e 20 54  ction returns. T
8520: 68 65 20 72 65 74 75 72 6e 20 76 61 6c 75 65 20  he return value 
8530: 69 73 20 74 68 65 20 74 6f 74 61 6c 20 6e 75 6d  is the total num
8540: 62 65 72 20 0a 2a 2a 20 6f 66 20 62 79 74 65 73  ber .** of bytes
8550: 20 6f 66 20 6d 65 6d 6f 72 79 20 72 65 6c 65 61   of memory relea
8560: 73 65 64 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  sed..*/.int sqli
8570: 74 65 33 50 63 61 63 68 65 52 65 6c 65 61 73 65  te3PcacheRelease
8580: 4d 65 6d 6f 72 79 28 69 6e 74 20 6e 52 65 71 29  Memory(int nReq)
8590: 7b 0a 20 20 69 6e 74 20 6e 46 72 65 65 20 3d 20  {.  int nFree = 
85a0: 30 3b 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c  0;.  assert( sql
85b0: 69 74 65 33 5f 6d 75 74 65 78 5f 6e 6f 74 68 65  ite3_mutex_nothe
85c0: 6c 64 28 70 63 61 63 68 65 31 2e 67 72 70 2e 6d  ld(pcache1.grp.m
85d0: 75 74 65 78 29 20 29 3b 0a 20 20 61 73 73 65 72  utex) );.  asser
85e0: 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78  t( sqlite3_mutex
85f0: 5f 6e 6f 74 68 65 6c 64 28 70 63 61 63 68 65 31  _notheld(pcache1
8600: 2e 6d 75 74 65 78 29 20 29 3b 0a 20 20 69 66 28  .mutex) );.  if(
8610: 20 70 63 61 63 68 65 31 2e 70 53 74 61 72 74 3d   pcache1.pStart=
8620: 3d 30 20 29 7b 0a 20 20 20 20 50 67 48 64 72 31  =0 ){.    PgHdr1
8630: 20 2a 70 3b 0a 20 20 20 20 70 63 61 63 68 65 31   *p;.    pcache1
8640: 45 6e 74 65 72 4d 75 74 65 78 28 26 70 63 61 63  EnterMutex(&pcac
8650: 68 65 31 2e 67 72 70 29 3b 0a 20 20 20 20 77 68  he1.grp);.    wh
8660: 69 6c 65 28 20 28 6e 52 65 71 3c 30 20 7c 7c 20  ile( (nReq<0 || 
8670: 6e 46 72 65 65 3c 6e 52 65 71 29 20 26 26 20 28  nFree<nReq) && (
8680: 28 70 3d 70 63 61 63 68 65 31 2e 67 72 70 2e 70  (p=pcache1.grp.p
8690: 4c 72 75 54 61 69 6c 29 21 3d 30 29 20 29 7b 0a  LruTail)!=0) ){.
86a0: 20 20 20 20 20 20 6e 46 72 65 65 20 2b 3d 20 70        nFree += p
86b0: 63 61 63 68 65 31 4d 65 6d 53 69 7a 65 28 70 2d  cache1MemSize(p-
86c0: 3e 70 61 67 65 2e 70 42 75 66 29 3b 0a 23 69 66  >page.pBuf);.#if
86d0: 64 65 66 20 53 51 4c 49 54 45 5f 50 43 41 43 48  def SQLITE_PCACH
86e0: 45 5f 53 45 50 41 52 41 54 45 5f 48 45 41 44 45  E_SEPARATE_HEADE
86f0: 52 0a 20 20 20 20 20 20 6e 46 72 65 65 20 2b 3d  R.      nFree +=
8700: 20 73 71 6c 69 74 65 33 4d 65 6d 53 69 7a 65 28   sqlite3MemSize(
8710: 70 29 3b 0a 23 65 6e 64 69 66 0a 20 20 20 20 20  p);.#endif.     
8720: 20 61 73 73 65 72 74 28 20 70 2d 3e 69 73 50 69   assert( p->isPi
8730: 6e 6e 65 64 3d 3d 30 20 29 3b 0a 20 20 20 20 20  nned==0 );.     
8740: 20 70 63 61 63 68 65 31 50 69 6e 50 61 67 65 28   pcache1PinPage(
8750: 70 29 3b 0a 20 20 20 20 20 20 70 63 61 63 68 65  p);.      pcache
8760: 31 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73 68 28  1RemoveFromHash(
8770: 70 29 3b 0a 20 20 20 20 20 20 70 63 61 63 68 65  p);.      pcache
8780: 31 46 72 65 65 50 61 67 65 28 70 29 3b 0a 20 20  1FreePage(p);.  
8790: 20 20 7d 0a 20 20 20 20 70 63 61 63 68 65 31 4c    }.    pcache1L
87a0: 65 61 76 65 4d 75 74 65 78 28 26 70 63 61 63 68  eaveMutex(&pcach
87b0: 65 31 2e 67 72 70 29 3b 0a 20 20 7d 0a 20 20 72  e1.grp);.  }.  r
87c0: 65 74 75 72 6e 20 6e 46 72 65 65 3b 0a 7d 0a 23  eturn nFree;.}.#
87d0: 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f  endif /* SQLITE_
87e0: 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41  ENABLE_MEMORY_MA
87f0: 4e 41 47 45 4d 45 4e 54 20 2a 2f 0a 0a 23 69 66  NAGEMENT */..#if
8800: 64 65 66 20 53 51 4c 49 54 45 5f 54 45 53 54 0a  def SQLITE_TEST.
8810: 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  /*.** This funct
8820: 69 6f 6e 20 69 73 20 75 73 65 64 20 62 79 20 74  ion is used by t
8830: 65 73 74 20 70 72 6f 63 65 64 75 72 65 73 20 74  est procedures t
8840: 6f 20 69 6e 73 70 65 63 74 20 74 68 65 20 69 6e  o inspect the in
8850: 74 65 72 6e 61 6c 20 73 74 61 74 65 0a 2a 2a 20  ternal state.** 
8860: 6f 66 20 74 68 65 20 67 6c 6f 62 61 6c 20 63 61  of the global ca
8870: 63 68 65 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c  che..*/.void sql
8880: 69 74 65 33 50 63 61 63 68 65 53 74 61 74 73 28  ite3PcacheStats(
8890: 0a 20 20 69 6e 74 20 2a 70 6e 43 75 72 72 65 6e  .  int *pnCurren
88a0: 74 2c 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20  t,      /* OUT: 
88b0: 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20  Total number of 
88c0: 70 61 67 65 73 20 63 61 63 68 65 64 20 2a 2f 0a  pages cached */.
88d0: 20 20 69 6e 74 20 2a 70 6e 4d 61 78 2c 20 20 20    int *pnMax,   
88e0: 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 47         /* OUT: G
88f0: 6c 6f 62 61 6c 20 6d 61 78 69 6d 75 6d 20 63 61  lobal maximum ca
8900: 63 68 65 20 73 69 7a 65 20 2a 2f 0a 20 20 69 6e  che size */.  in
8910: 74 20 2a 70 6e 4d 69 6e 2c 20 20 20 20 20 20 20  t *pnMin,       
8920: 20 20 20 2f 2a 20 4f 55 54 3a 20 53 75 6d 20 6f     /* OUT: Sum o
8930: 66 20 50 43 61 63 68 65 31 2e 6e 4d 69 6e 20 66  f PCache1.nMin f
8940: 6f 72 20 70 75 72 67 65 61 62 6c 65 20 63 61 63  or purgeable cac
8950: 68 65 73 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e  hes */.  int *pn
8960: 52 65 63 79 63 6c 61 62 6c 65 20 20 20 20 2f 2a  Recyclable    /*
8970: 20 4f 55 54 3a 20 54 6f 74 61 6c 20 6e 75 6d 62   OUT: Total numb
8980: 65 72 20 6f 66 20 70 61 67 65 73 20 61 76 61 69  er of pages avai
8990: 6c 61 62 6c 65 20 66 6f 72 20 72 65 63 79 63 6c  lable for recycl
89a0: 69 6e 67 20 2a 2f 0a 29 7b 0a 20 20 50 67 48 64  ing */.){.  PgHd
89b0: 72 31 20 2a 70 3b 0a 20 20 69 6e 74 20 6e 52 65  r1 *p;.  int nRe
89c0: 63 79 63 6c 61 62 6c 65 20 3d 20 30 3b 0a 20 20  cyclable = 0;.  
89d0: 66 6f 72 28 70 3d 70 63 61 63 68 65 31 2e 67 72  for(p=pcache1.gr
89e0: 70 2e 70 4c 72 75 48 65 61 64 3b 20 70 3b 20 70  p.pLruHead; p; p
89f0: 3d 70 2d 3e 70 4c 72 75 4e 65 78 74 29 7b 0a 20  =p->pLruNext){. 
8a00: 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e 69 73     assert( p->is
8a10: 50 69 6e 6e 65 64 3d 3d 30 20 29 3b 0a 20 20 20  Pinned==0 );.   
8a20: 20 6e 52 65 63 79 63 6c 61 62 6c 65 2b 2b 3b 0a   nRecyclable++;.
8a30: 20 20 7d 0a 20 20 2a 70 6e 43 75 72 72 65 6e 74    }.  *pnCurrent
8a40: 20 3d 20 70 63 61 63 68 65 31 2e 67 72 70 2e 6e   = pcache1.grp.n
8a50: 43 75 72 72 65 6e 74 50 61 67 65 3b 0a 20 20 2a  CurrentPage;.  *
8a60: 70 6e 4d 61 78 20 3d 20 28 69 6e 74 29 70 63 61  pnMax = (int)pca
8a70: 63 68 65 31 2e 67 72 70 2e 6e 4d 61 78 50 61 67  che1.grp.nMaxPag
8a80: 65 3b 0a 20 20 2a 70 6e 4d 69 6e 20 3d 20 28 69  e;.  *pnMin = (i
8a90: 6e 74 29 70 63 61 63 68 65 31 2e 67 72 70 2e 6e  nt)pcache1.grp.n
8aa0: 4d 69 6e 50 61 67 65 3b 0a 20 20 2a 70 6e 52 65  MinPage;.  *pnRe
8ab0: 63 79 63 6c 61 62 6c 65 20 3d 20 6e 52 65 63 79  cyclable = nRecy
8ac0: 63 6c 61 62 6c 65 3b 0a 7d 0a 23 65 6e 64 69 66  clable;.}.#endif
8ad0: 0a                                               .