/ Hex Artifact Content
Login

Artifact 54fc4ed623157b6f706da961c1d3776a40aa131d:


0000: 2f 2a 0a 2a 2a 20 32 30 30 38 20 4e 6f 76 65 6d  /*.** 2008 Novem
0010: 62 65 72 20 30 35 0a 2a 2a 0a 2a 2a 20 54 68 65  ber 05.**.** The
0020: 20 61 75 74 68 6f 72 20 64 69 73 63 6c 61 69 6d   author disclaim
0030: 73 20 63 6f 70 79 72 69 67 68 74 20 74 6f 20 74  s copyright to t
0040: 68 69 73 20 73 6f 75 72 63 65 20 63 6f 64 65 2e  his source code.
0050: 20 20 49 6e 20 70 6c 61 63 65 20 6f 66 0a 2a 2a    In place of.**
0060: 20 61 20 6c 65 67 61 6c 20 6e 6f 74 69 63 65 2c   a legal notice,
0070: 20 68 65 72 65 20 69 73 20 61 20 62 6c 65 73 73   here is a bless
0080: 69 6e 67 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 4d 61  ing:.**.**    Ma
0090: 79 20 79 6f 75 20 64 6f 20 67 6f 6f 64 20 61 6e  y you do good an
00a0: 64 20 6e 6f 74 20 65 76 69 6c 2e 0a 2a 2a 20 20  d not evil..**  
00b0: 20 20 4d 61 79 20 79 6f 75 20 66 69 6e 64 20 66    May you find f
00c0: 6f 72 67 69 76 65 6e 65 73 73 20 66 6f 72 20 79  orgiveness for y
00d0: 6f 75 72 73 65 6c 66 20 61 6e 64 20 66 6f 72 67  ourself and forg
00e0: 69 76 65 20 6f 74 68 65 72 73 2e 0a 2a 2a 20 20  ive others..**  
00f0: 20 20 4d 61 79 20 79 6f 75 20 73 68 61 72 65 20    May you share 
0100: 66 72 65 65 6c 79 2c 20 6e 65 76 65 72 20 74 61  freely, never ta
0110: 6b 69 6e 67 20 6d 6f 72 65 20 74 68 61 6e 20 79  king more than y
0120: 6f 75 20 67 69 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a  ou give..**.****
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 2a 2a 2a 2a 2a 0a 2a 2a 0a 2a 2a 20 54 68 69 73  *****.**.** This
0180: 20 66 69 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 73   file implements
0190: 20 74 68 65 20 64 65 66 61 75 6c 74 20 70 61 67   the default pag
01a0: 65 20 63 61 63 68 65 20 69 6d 70 6c 65 6d 65 6e  e cache implemen
01b0: 74 61 74 69 6f 6e 20 28 74 68 65 0a 2a 2a 20 73  tation (the.** s
01c0: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 69 6e  qlite3_pcache in
01d0: 74 65 72 66 61 63 65 29 2e 20 49 74 20 61 6c 73  terface). It als
01e0: 6f 20 63 6f 6e 74 61 69 6e 73 20 70 61 72 74 20  o contains part 
01f0: 6f 66 20 74 68 65 20 69 6d 70 6c 65 6d 65 6e 74  of the implement
0200: 61 74 69 6f 6e 0a 2a 2a 20 6f 66 20 74 68 65 20  ation.** of the 
0210: 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41  SQLITE_CONFIG_PA
0220: 47 45 43 41 43 48 45 20 61 6e 64 20 73 71 6c 69  GECACHE and sqli
0230: 74 65 33 5f 72 65 6c 65 61 73 65 5f 6d 65 6d 6f  te3_release_memo
0240: 72 79 28 29 20 66 65 61 74 75 72 65 73 2e 0a 2a  ry() features..*
0250: 2a 20 49 66 20 74 68 65 20 64 65 66 61 75 6c 74  * If the default
0260: 20 70 61 67 65 20 63 61 63 68 65 20 69 6d 70 6c   page cache impl
0270: 65 6d 65 6e 74 61 74 69 6f 6e 20 69 73 20 6f 76  ementation is ov
0280: 65 72 72 69 64 65 6e 2c 20 74 68 65 6e 20 6e 65  erriden, then ne
0290: 69 74 68 65 72 20 6f 66 0a 2a 2a 20 74 68 65 73  ither of.** thes
02a0: 65 20 74 77 6f 20 66 65 61 74 75 72 65 73 20 61  e two features a
02b0: 72 65 20 61 76 61 69 6c 61 62 6c 65 2e 0a 2a 2f  re available..*/
02c0: 0a 0a 23 69 6e 63 6c 75 64 65 20 22 73 71 6c 69  ..#include "sqli
02d0: 74 65 49 6e 74 2e 68 22 0a 0a 74 79 70 65 64 65  teInt.h"..typede
02e0: 66 20 73 74 72 75 63 74 20 50 43 61 63 68 65 31  f struct PCache1
02f0: 20 50 43 61 63 68 65 31 3b 0a 74 79 70 65 64 65   PCache1;.typede
0300: 66 20 73 74 72 75 63 74 20 50 67 48 64 72 31 20  f struct PgHdr1 
0310: 50 67 48 64 72 31 3b 0a 74 79 70 65 64 65 66 20  PgHdr1;.typedef 
0320: 73 74 72 75 63 74 20 50 67 46 72 65 65 73 6c 6f  struct PgFreeslo
0330: 74 20 50 67 46 72 65 65 73 6c 6f 74 3b 0a 74 79  t PgFreeslot;.ty
0340: 70 65 64 65 66 20 73 74 72 75 63 74 20 50 47 72  pedef struct PGr
0350: 6f 75 70 20 50 47 72 6f 75 70 3b 0a 0a 0a 2f 2a  oup 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 73 20 75 6e 70 69 6e 6e 65 64 0a 2a 2a  hers unpinned.**
03f0: 20 70 61 67 65 73 20 77 68 65 6e 20 74 68 65 79   pages when they
0400: 20 61 72 65 20 75 6e 64 65 72 20 6d 65 6d 6f 72   are under memor
0410: 79 20 70 72 65 73 73 75 72 65 2e 20 20 41 20 50  y pressure.  A P
0420: 47 72 6f 75 70 20 69 73 20 61 6e 20 69 6e 73 74  Group is an inst
0430: 61 6e 63 65 20 6f 66 0a 2a 2a 20 74 68 65 20 66  ance of.** the f
0440: 6f 6c 6c 6f 77 69 6e 67 20 6f 62 6a 65 63 74 2e  ollowing object.
0450: 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 70 61 67 65  .**.** This page
0460: 20 63 61 63 68 65 20 69 6d 70 6c 65 6d 65 6e 74   cache implement
0470: 61 74 69 6f 6e 20 77 6f 72 6b 73 20 69 6e 20 6f  ation works in o
0480: 6e 65 20 6f 66 20 74 77 6f 20 6d 6f 64 65 73 3a  ne of two modes:
0490: 0a 2a 2a 0a 2a 2a 20 20 20 28 31 29 20 20 45 76  .**.**   (1)  Ev
04a0: 65 72 79 20 50 43 61 63 68 65 20 69 73 20 74 68  ery PCache is th
04b0: 65 20 73 6f 6c 65 20 6d 65 6d 62 65 72 20 6f 66  e sole member of
04c0: 20 69 74 73 20 6f 77 6e 20 50 47 72 6f 75 70 2e   its own PGroup.
04d0: 20 20 54 68 65 72 65 20 69 73 0a 2a 2a 20 20 20    There is.**   
04e0: 20 20 20 20 20 6f 6e 65 20 50 47 72 6f 75 70 20       one PGroup 
04f0: 70 65 72 20 50 43 61 63 68 65 2e 0a 2a 2a 0a 2a  per PCache..**.*
0500: 2a 20 20 20 28 32 29 20 20 54 68 65 72 65 20 69  *   (2)  There i
0510: 73 20 61 20 73 69 6e 67 6c 65 20 67 6c 6f 62 61  s a single globa
0520: 6c 20 50 47 72 6f 75 70 20 74 68 61 74 20 61 6c  l PGroup that al
0530: 6c 20 50 43 61 63 68 65 73 20 61 72 65 20 61 20  l PCaches are a 
0540: 6d 65 6d 62 65 72 0a 2a 2a 20 20 20 20 20 20 20  member.**       
0550: 20 6f 66 2e 0a 2a 2a 0a 2a 2a 20 4d 6f 64 65 20   of..**.** Mode 
0560: 31 20 75 73 65 73 20 6d 6f 72 65 20 6d 65 6d 6f  1 uses more memo
0570: 72 79 20 28 73 69 6e 63 65 20 50 43 61 63 68 65  ry (since PCache
0580: 20 69 6e 73 74 61 6e 63 65 73 20 61 72 65 20 6e   instances are n
0590: 6f 74 20 61 62 6c 65 20 74 6f 20 72 6f 62 0a 2a  ot able to rob.*
05a0: 2a 20 75 6e 75 73 65 64 20 70 61 67 65 73 20 66  * unused pages f
05b0: 72 6f 6d 20 6f 74 68 65 72 20 50 43 61 63 68 65  rom other PCache
05c0: 73 29 20 62 75 74 20 69 74 20 61 6c 73 6f 20 6f  s) but it also o
05d0: 70 65 72 61 74 65 73 20 77 69 74 68 6f 75 74 20  perates without 
05e0: 61 20 6d 75 74 65 78 2c 0a 2a 2a 20 61 6e 64 20  a mutex,.** and 
05f0: 69 73 20 74 68 65 72 65 66 6f 72 65 20 6f 66 74  is therefore oft
0600: 65 6e 20 66 61 73 74 65 72 2e 20 20 4d 6f 64 65  en faster.  Mode
0610: 20 32 20 72 65 71 75 69 72 65 73 20 61 20 6d 75   2 requires a mu
0620: 74 65 78 20 69 6e 20 6f 72 64 65 72 20 74 6f 20  tex in order to 
0630: 62 65 0a 2a 2a 20 74 68 72 65 61 64 73 61 66 65  be.** threadsafe
0640: 2c 20 62 75 74 20 69 73 20 61 62 6c 65 20 72 65  , but is able re
0650: 63 79 63 6c 65 20 70 61 67 65 73 20 6d 6f 72 65  cycle pages more
0660: 20 65 66 66 69 63 69 65 6e 74 2e 0a 2a 2a 0a 2a   efficient..**.*
0670: 2a 20 46 6f 72 20 6d 6f 64 65 20 28 31 29 2c 20  * For mode (1), 
0680: 50 47 72 6f 75 70 2e 6d 75 74 65 78 20 69 73 20  PGroup.mutex is 
0690: 4e 55 4c 4c 2e 20 20 46 6f 72 20 6d 6f 64 65 20  NULL.  For mode 
06a0: 28 32 29 20 74 68 65 72 65 20 69 73 20 6f 6e 6c  (2) there is onl
06b0: 79 20 61 20 73 69 6e 67 6c 65 0a 2a 2a 20 50 47  y a single.** PG
06c0: 72 6f 75 70 20 77 68 69 63 68 20 69 73 20 74 68  roup which is th
06d0: 65 20 70 63 61 63 68 65 31 2e 67 72 70 20 67 6c  e pcache1.grp gl
06e0: 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 20 61 6e  obal variable an
06f0: 64 20 69 74 73 20 6d 75 74 65 78 20 69 73 0a 2a  d its mutex is.*
0700: 2a 20 53 51 4c 49 54 45 5f 4d 55 54 45 58 5f 53  * SQLITE_MUTEX_S
0710: 54 41 54 49 43 5f 4c 52 55 2e 0a 2a 2f 0a 73 74  TATIC_LRU..*/.st
0720: 72 75 63 74 20 50 47 72 6f 75 70 20 7b 0a 20 20  ruct PGroup {.  
0730: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 20 2a 6d  sqlite3_mutex *m
0740: 75 74 65 78 3b 20 20 20 20 20 20 20 20 20 20 2f  utex;          /
0750: 2a 20 4d 55 54 45 58 5f 53 54 41 54 49 43 5f 4c  * MUTEX_STATIC_L
0760: 52 55 20 6f 72 20 4e 55 4c 4c 20 2a 2f 0a 20 20  RU or NULL */.  
0770: 69 6e 74 20 6e 4d 61 78 50 61 67 65 3b 20 20 20  int nMaxPage;   
0780: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0790: 2a 20 53 75 6d 20 6f 66 20 6e 4d 61 78 20 66 6f  * Sum of nMax fo
07a0: 72 20 70 75 72 67 65 61 62 6c 65 20 63 61 63 68  r purgeable cach
07b0: 65 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 4d 69 6e  es */.  int nMin
07c0: 50 61 67 65 3b 20 20 20 20 20 20 20 20 20 20 20  Page;           
07d0: 20 20 20 20 20 20 20 2f 2a 20 53 75 6d 20 6f 66         /* Sum of
07e0: 20 6e 4d 69 6e 20 66 6f 72 20 70 75 72 67 65 61   nMin for purgea
07f0: 62 6c 65 20 63 61 63 68 65 73 20 2a 2f 0a 20 20  ble caches */.  
0800: 69 6e 74 20 6d 78 50 69 6e 6e 65 64 3b 20 20 20  int mxPinned;   
0810: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0820: 2a 20 6e 4d 61 78 70 61 67 65 20 2b 20 31 30 20  * nMaxpage + 10 
0830: 2d 20 6e 4d 69 6e 50 61 67 65 20 2a 2f 0a 20 20  - nMinPage */.  
0840: 69 6e 74 20 6e 43 75 72 72 65 6e 74 50 61 67 65  int nCurrentPage
0850: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ;              /
0860: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 70 75 72 67  * Number of purg
0870: 65 61 62 6c 65 20 70 61 67 65 73 20 61 6c 6c 6f  eable pages allo
0880: 63 61 74 65 64 20 2a 2f 0a 20 20 50 67 48 64 72  cated */.  PgHdr
0890: 31 20 2a 70 4c 72 75 48 65 61 64 2c 20 2a 70 4c  1 *pLruHead, *pL
08a0: 72 75 54 61 69 6c 3b 20 20 20 2f 2a 20 4c 52 55  ruTail;   /* LRU
08b0: 20 6c 69 73 74 20 6f 66 20 75 6e 70 69 6e 6e 65   list of unpinne
08c0: 64 20 70 61 67 65 73 20 2a 2f 0a 7d 3b 0a 0a 2f  d pages */.};../
08d0: 2a 20 45 61 63 68 20 70 61 67 65 20 63 61 63 68  * Each page cach
08e0: 65 20 69 73 20 61 6e 20 69 6e 73 74 61 6e 63 65  e is an instance
08f0: 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e   of the followin
0900: 67 20 6f 62 6a 65 63 74 2e 20 20 45 76 65 72 79  g object.  Every
0910: 0a 2a 2a 20 6f 70 65 6e 20 64 61 74 61 62 61 73  .** open databas
0920: 65 20 66 69 6c 65 20 28 69 6e 63 6c 75 64 69 6e  e file (includin
0930: 67 20 65 61 63 68 20 69 6e 2d 6d 65 6d 6f 72 79  g each in-memory
0940: 20 64 61 74 61 62 61 73 65 20 61 6e 64 20 65 61   database and ea
0950: 63 68 0a 2a 2a 20 74 65 6d 70 6f 72 61 72 79 20  ch.** temporary 
0960: 6f 72 20 74 72 61 6e 73 69 65 6e 74 20 64 61 74  or transient dat
0970: 61 62 61 73 65 29 20 68 61 73 20 61 20 73 69 6e  abase) has a sin
0980: 67 6c 65 20 70 61 67 65 20 63 61 63 68 65 20 77  gle page cache w
0990: 68 69 63 68 0a 2a 2a 20 69 73 20 61 6e 20 69 6e  hich.** is an in
09a0: 73 74 61 6e 63 65 20 6f 66 20 74 68 69 73 20 6f  stance of this o
09b0: 62 6a 65 63 74 2e 0a 2a 2a 0a 2a 2a 20 50 6f 69  bject..**.** Poi
09c0: 6e 74 65 72 73 20 74 6f 20 73 74 72 75 63 74 75  nters to structu
09d0: 72 65 73 20 6f 66 20 74 68 69 73 20 74 79 70 65  res of this type
09e0: 20 61 72 65 20 63 61 73 74 20 61 6e 64 20 72 65   are cast and re
09f0: 74 75 72 6e 65 64 20 61 73 20 0a 2a 2a 20 6f 70  turned as .** op
0a00: 61 71 75 65 20 73 71 6c 69 74 65 33 5f 70 63 61  aque sqlite3_pca
0a10: 63 68 65 2a 20 68 61 6e 64 6c 65 73 2e 0a 2a 2f  che* handles..*/
0a20: 0a 73 74 72 75 63 74 20 50 43 61 63 68 65 31 20  .struct PCache1 
0a30: 7b 0a 20 20 2f 2a 20 43 61 63 68 65 20 63 6f 6e  {.  /* Cache con
0a40: 66 69 67 75 72 61 74 69 6f 6e 20 70 61 72 61 6d  figuration param
0a50: 65 74 65 72 73 2e 20 50 61 67 65 20 73 69 7a 65  eters. Page size
0a60: 20 28 73 7a 50 61 67 65 29 20 61 6e 64 20 74 68   (szPage) and th
0a70: 65 20 70 75 72 67 65 61 62 6c 65 0a 20 20 2a 2a  e purgeable.  **
0a80: 20 66 6c 61 67 20 28 62 50 75 72 67 65 61 62 6c   flag (bPurgeabl
0a90: 65 29 20 61 72 65 20 73 65 74 20 77 68 65 6e 20  e) are set when 
0aa0: 74 68 65 20 63 61 63 68 65 20 69 73 20 63 72 65  the cache is cre
0ab0: 61 74 65 64 2e 20 6e 4d 61 78 20 6d 61 79 20 62  ated. nMax may b
0ac0: 65 20 0a 20 20 2a 2a 20 6d 6f 64 69 66 69 65 64  e .  ** modified
0ad0: 20 61 74 20 61 6e 79 20 74 69 6d 65 20 62 79 20   at any time by 
0ae0: 61 20 63 61 6c 6c 20 74 6f 20 74 68 65 20 70 63  a call to the pc
0af0: 61 63 68 65 31 43 61 63 68 65 53 69 7a 65 28 29  ache1CacheSize()
0b00: 20 6d 65 74 68 6f 64 2e 0a 20 20 2a 2a 20 54 68   method..  ** Th
0b10: 65 20 50 47 72 6f 75 70 20 6d 75 74 65 78 20 6d  e PGroup mutex m
0b20: 75 73 74 20 62 65 20 68 65 6c 64 20 77 68 65 6e  ust be held when
0b30: 20 61 63 63 65 73 73 69 6e 67 20 6e 4d 61 78 2e   accessing nMax.
0b40: 0a 20 20 2a 2f 0a 20 20 50 47 72 6f 75 70 20 2a  .  */.  PGroup *
0b50: 70 47 72 6f 75 70 3b 20 20 20 20 20 20 20 20 20  pGroup;         
0b60: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
0b70: 47 72 6f 75 70 20 74 68 69 73 20 63 61 63 68 65  Group this cache
0b80: 20 62 65 6c 6f 6e 67 73 20 74 6f 20 2a 2f 0a 20   belongs to */. 
0b90: 20 69 6e 74 20 73 7a 50 61 67 65 3b 20 20 20 20   int szPage;    
0ba0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0bb0: 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
0bc0: 61 6c 6c 6f 63 61 74 65 64 20 70 61 67 65 73 20  allocated pages 
0bd0: 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 69 6e  in bytes */.  in
0be0: 74 20 73 7a 45 78 74 72 61 3b 20 20 20 20 20 20  t szExtra;      
0bf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c00: 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 65 78 74    /* Size of ext
0c10: 72 61 20 73 70 61 63 65 20 69 6e 20 62 79 74 65  ra space in byte
0c20: 73 20 2a 2f 0a 20 20 69 6e 74 20 62 50 75 72 67  s */.  int bPurg
0c30: 65 61 62 6c 65 3b 20 20 20 20 20 20 20 20 20 20  eable;          
0c40: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72             /* Tr
0c50: 75 65 20 69 66 20 63 61 63 68 65 20 69 73 20 70  ue if cache is p
0c60: 75 72 67 65 61 62 6c 65 20 2a 2f 0a 20 20 75 6e  urgeable */.  un
0c70: 73 69 67 6e 65 64 20 69 6e 74 20 6e 4d 69 6e 3b  signed int nMin;
0c80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c90: 20 20 2f 2a 20 4d 69 6e 69 6d 75 6d 20 6e 75 6d    /* Minimum num
0ca0: 62 65 72 20 6f 66 20 70 61 67 65 73 20 72 65 73  ber of pages res
0cb0: 65 72 76 65 64 20 2a 2f 0a 20 20 75 6e 73 69 67  erved */.  unsig
0cc0: 6e 65 64 20 69 6e 74 20 6e 4d 61 78 3b 20 20 20  ned int nMax;   
0cd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0ce0: 2a 20 43 6f 6e 66 69 67 75 72 65 64 20 22 63 61  * Configured "ca
0cf0: 63 68 65 5f 73 69 7a 65 22 20 76 61 6c 75 65 20  che_size" value 
0d00: 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e  */.  unsigned in
0d10: 74 20 6e 39 30 70 63 74 3b 20 20 20 20 20 20 20  t n90pct;       
0d20: 20 20 20 20 20 20 20 20 20 2f 2a 20 6e 4d 61 78           /* nMax
0d30: 2a 39 2f 31 30 20 2a 2f 0a 0a 20 20 2f 2a 20 48  *9/10 */..  /* H
0d40: 61 73 68 20 74 61 62 6c 65 20 6f 66 20 61 6c 6c  ash table of all
0d50: 20 70 61 67 65 73 2e 20 54 68 65 20 66 6f 6c 6c   pages. The foll
0d60: 6f 77 69 6e 67 20 76 61 72 69 61 62 6c 65 73 20  owing variables 
0d70: 6d 61 79 20 6f 6e 6c 79 20 62 65 20 61 63 63 65  may only be acce
0d80: 73 73 65 64 0a 20 20 2a 2a 20 77 68 65 6e 20 74  ssed.  ** when t
0d90: 68 65 20 61 63 63 65 73 73 6f 72 20 69 73 20 68  he accessor is h
0da0: 6f 6c 64 69 6e 67 20 74 68 65 20 50 47 72 6f 75  olding the PGrou
0db0: 70 20 6d 75 74 65 78 2e 0a 20 20 2a 2f 0a 20 20  p mutex..  */.  
0dc0: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 52 65  unsigned int nRe
0dd0: 63 79 63 6c 61 62 6c 65 3b 20 20 20 20 20 20 20  cyclable;       
0de0: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
0df0: 20 70 61 67 65 73 20 69 6e 20 74 68 65 20 4c 52   pages in the LR
0e00: 55 20 6c 69 73 74 20 2a 2f 0a 20 20 75 6e 73 69  U list */.  unsi
0e10: 67 6e 65 64 20 69 6e 74 20 6e 50 61 67 65 3b 20  gned int nPage; 
0e20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e30: 2f 2a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20  /* Total number 
0e40: 6f 66 20 70 61 67 65 73 20 69 6e 20 61 70 48 61  of pages in apHa
0e50: 73 68 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64  sh */.  unsigned
0e60: 20 69 6e 74 20 6e 48 61 73 68 3b 20 20 20 20 20   int nHash;     
0e70: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
0e80: 75 6d 62 65 72 20 6f 66 20 73 6c 6f 74 73 20 69  umber of slots i
0e90: 6e 20 61 70 48 61 73 68 5b 5d 20 2a 2f 0a 20 20  n apHash[] */.  
0ea0: 50 67 48 64 72 31 20 2a 2a 61 70 48 61 73 68 3b  PgHdr1 **apHash;
0eb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ec0: 20 20 20 20 2f 2a 20 48 61 73 68 20 74 61 62 6c      /* Hash tabl
0ed0: 65 20 66 6f 72 20 66 61 73 74 20 6c 6f 6f 6b 75  e for fast looku
0ee0: 70 20 62 79 20 6b 65 79 20 2a 2f 0a 0a 20 20 75  p by key */..  u
0ef0: 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4d 61 78  nsigned int iMax
0f00: 4b 65 79 3b 20 20 20 20 20 20 20 20 20 20 20 20  Key;            
0f10: 20 20 20 2f 2a 20 4c 61 72 67 65 73 74 20 6b 65     /* Largest ke
0f20: 79 20 73 65 65 6e 20 73 69 6e 63 65 20 78 54 72  y seen since xTr
0f30: 75 6e 63 61 74 65 28 29 20 2a 2f 0a 7d 3b 0a 0a  uncate() */.};..
0f40: 2f 2a 0a 2a 2a 20 45 61 63 68 20 63 61 63 68 65  /*.** Each cache
0f50: 20 65 6e 74 72 79 20 69 73 20 72 65 70 72 65 73   entry is repres
0f60: 65 6e 74 65 64 20 62 79 20 61 6e 20 69 6e 73 74  ented by an inst
0f70: 61 6e 63 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c  ance of the foll
0f80: 6f 77 69 6e 67 20 0a 2a 2a 20 73 74 72 75 63 74  owing .** struct
0f90: 75 72 65 2e 20 55 6e 6c 65 73 73 20 53 51 4c 49  ure. Unless SQLI
0fa0: 54 45 5f 50 43 41 43 48 45 5f 53 45 50 41 52 41  TE_PCACHE_SEPARA
0fb0: 54 45 5f 48 45 41 44 45 52 20 69 73 20 64 65 66  TE_HEADER is def
0fc0: 69 6e 65 64 2c 20 61 20 62 75 66 66 65 72 20 6f  ined, a buffer o
0fd0: 66 0a 2a 2a 20 50 67 48 64 72 31 2e 70 43 61 63  f.** PgHdr1.pCac
0fe0: 68 65 2d 3e 73 7a 50 61 67 65 20 62 79 74 65 73  he->szPage bytes
0ff0: 20 69 73 20 61 6c 6c 6f 63 61 74 65 64 20 64 69   is allocated di
1000: 72 65 63 74 6c 79 20 62 65 66 6f 72 65 20 74 68  rectly before th
1010: 69 73 20 73 74 72 75 63 74 75 72 65 20 0a 2a 2a  is structure .**
1020: 20 69 6e 20 6d 65 6d 6f 72 79 2e 0a 2a 2f 0a 73   in memory..*/.s
1030: 74 72 75 63 74 20 50 67 48 64 72 31 20 7b 0a 20  truct PgHdr1 {. 
1040: 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 5f   sqlite3_pcache_
1050: 70 61 67 65 20 70 61 67 65 3b 0a 20 20 75 6e 73  page page;.  uns
1060: 69 67 6e 65 64 20 69 6e 74 20 69 4b 65 79 3b 20  igned int iKey; 
1070: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4b              /* K
1080: 65 79 20 76 61 6c 75 65 20 28 70 61 67 65 20 6e  ey value (page n
1090: 75 6d 62 65 72 29 20 2a 2f 0a 20 20 50 67 48 64  umber) */.  PgHd
10a0: 72 31 20 2a 70 4e 65 78 74 3b 20 20 20 20 20 20  r1 *pNext;      
10b0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65             /* Ne
10c0: 78 74 20 69 6e 20 68 61 73 68 20 74 61 62 6c 65  xt in hash table
10d0: 20 63 68 61 69 6e 20 2a 2f 0a 20 20 50 43 61 63   chain */.  PCac
10e0: 68 65 31 20 2a 70 43 61 63 68 65 3b 20 20 20 20  he1 *pCache;    
10f0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 61             /* Ca
1100: 63 68 65 20 74 68 61 74 20 63 75 72 72 65 6e 74  che that current
1110: 6c 79 20 6f 77 6e 73 20 74 68 69 73 20 70 61 67  ly owns this pag
1120: 65 20 2a 2f 0a 20 20 50 67 48 64 72 31 20 2a 70  e */.  PgHdr1 *p
1130: 4c 72 75 4e 65 78 74 3b 20 20 20 20 20 20 20 20  LruNext;        
1140: 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 69 6e        /* Next in
1150: 20 4c 52 55 20 6c 69 73 74 20 6f 66 20 75 6e 70   LRU list of unp
1160: 69 6e 6e 65 64 20 70 61 67 65 73 20 2a 2f 0a 20  inned pages */. 
1170: 20 50 67 48 64 72 31 20 2a 70 4c 72 75 50 72 65   PgHdr1 *pLruPre
1180: 76 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  v;              
1190: 2f 2a 20 50 72 65 76 69 6f 75 73 20 69 6e 20 4c  /* Previous in L
11a0: 52 55 20 6c 69 73 74 20 6f 66 20 75 6e 70 69 6e  RU list of unpin
11b0: 6e 65 64 20 70 61 67 65 73 20 2a 2f 0a 7d 3b 0a  ned pages */.};.
11c0: 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 73 6c 6f 74  ./*.** Free slot
11d0: 73 20 69 6e 20 74 68 65 20 61 6c 6c 6f 63 61 74  s in the allocat
11e0: 6f 72 20 75 73 65 64 20 74 6f 20 64 69 76 69 64  or used to divid
11f0: 65 20 75 70 20 74 68 65 20 62 75 66 66 65 72 20  e up the buffer 
1200: 70 72 6f 76 69 64 65 64 20 75 73 69 6e 67 0a 2a  provided using.*
1210: 2a 20 74 68 65 20 53 51 4c 49 54 45 5f 43 4f 4e  * the SQLITE_CON
1220: 46 49 47 5f 50 41 47 45 43 41 43 48 45 20 6d 65  FIG_PAGECACHE me
1230: 63 68 61 6e 69 73 6d 2e 0a 2a 2f 0a 73 74 72 75  chanism..*/.stru
1240: 63 74 20 50 67 46 72 65 65 73 6c 6f 74 20 7b 0a  ct PgFreeslot {.
1250: 20 20 50 67 46 72 65 65 73 6c 6f 74 20 2a 70 4e    PgFreeslot *pN
1260: 65 78 74 3b 20 20 2f 2a 20 4e 65 78 74 20 66 72  ext;  /* Next fr
1270: 65 65 20 73 6c 6f 74 20 2a 2f 0a 7d 3b 0a 0a 2f  ee slot */.};../
1280: 2a 0a 2a 2a 20 47 6c 6f 62 61 6c 20 64 61 74 61  *.** Global data
1290: 20 75 73 65 64 20 62 79 20 74 68 69 73 20 63 61   used by this ca
12a0: 63 68 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 53  che..*/.static S
12b0: 51 4c 49 54 45 5f 57 53 44 20 73 74 72 75 63 74  QLITE_WSD struct
12c0: 20 50 43 61 63 68 65 47 6c 6f 62 61 6c 20 7b 0a   PCacheGlobal {.
12d0: 20 20 50 47 72 6f 75 70 20 67 72 70 3b 20 20 20    PGroup grp;   
12e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12f0: 20 2f 2a 20 54 68 65 20 67 6c 6f 62 61 6c 20 50   /* The global P
1300: 47 72 6f 75 70 20 66 6f 72 20 6d 6f 64 65 20 28  Group for mode (
1310: 32 29 20 2a 2f 0a 0a 20 20 2f 2a 20 56 61 72 69  2) */..  /* Vari
1320: 61 62 6c 65 73 20 72 65 6c 61 74 65 64 20 74 6f  ables related to
1330: 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50   SQLITE_CONFIG_P
1340: 41 47 45 43 41 43 48 45 20 73 65 74 74 69 6e 67  AGECACHE setting
1350: 73 2e 20 20 54 68 65 0a 20 20 2a 2a 20 73 7a 53  s.  The.  ** szS
1360: 6c 6f 74 2c 20 6e 53 6c 6f 74 2c 20 70 53 74 61  lot, nSlot, pSta
1370: 72 74 2c 20 70 45 6e 64 2c 20 6e 52 65 73 65 72  rt, pEnd, nReser
1380: 76 65 2c 20 61 6e 64 20 69 73 49 6e 69 74 20 76  ve, and isInit v
1390: 61 6c 75 65 73 20 61 72 65 20 61 6c 6c 0a 20 20  alues are all.  
13a0: 2a 2a 20 66 69 78 65 64 20 61 74 20 73 71 6c 69  ** fixed at sqli
13b0: 74 65 33 5f 69 6e 69 74 69 61 6c 69 7a 65 28 29  te3_initialize()
13c0: 20 74 69 6d 65 20 61 6e 64 20 64 6f 20 6e 6f 74   time and do not
13d0: 20 72 65 71 75 69 72 65 20 6d 75 74 65 78 20 70   require mutex p
13e0: 72 6f 74 65 63 74 69 6f 6e 2e 0a 20 20 2a 2a 20  rotection..  ** 
13f0: 54 68 65 20 6e 46 72 65 65 53 6c 6f 74 20 61 6e  The nFreeSlot an
1400: 64 20 70 46 72 65 65 20 76 61 6c 75 65 73 20 64  d pFree values d
1410: 6f 20 72 65 71 75 69 72 65 20 6d 75 74 65 78 20  o require mutex 
1420: 70 72 6f 74 65 63 74 69 6f 6e 2e 0a 20 20 2a 2f  protection..  */
1430: 0a 20 20 69 6e 74 20 69 73 49 6e 69 74 3b 20 20  .  int isInit;  
1440: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1450: 20 20 2f 2a 20 54 72 75 65 20 69 66 20 69 6e 69    /* True if ini
1460: 74 69 61 6c 69 7a 65 64 20 2a 2f 0a 20 20 69 6e  tialized */.  in
1470: 74 20 73 7a 53 6c 6f 74 3b 20 20 20 20 20 20 20  t szSlot;       
1480: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1490: 53 69 7a 65 20 6f 66 20 65 61 63 68 20 66 72 65  Size of each fre
14a0: 65 20 73 6c 6f 74 20 2a 2f 0a 20 20 69 6e 74 20  e slot */.  int 
14b0: 6e 53 6c 6f 74 3b 20 20 20 20 20 20 20 20 20 20  nSlot;          
14c0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68             /* Th
14d0: 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 63 61 63  e number of pcac
14e0: 68 65 20 73 6c 6f 74 73 20 2a 2f 0a 20 20 69 6e  he slots */.  in
14f0: 74 20 6e 52 65 73 65 72 76 65 3b 20 20 20 20 20  t nReserve;     
1500: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1510: 54 72 79 20 74 6f 20 6b 65 65 70 20 6e 46 72 65  Try to keep nFre
1520: 65 53 6c 6f 74 20 61 62 6f 76 65 20 74 68 69 73  eSlot above this
1530: 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 53 74 61   */.  void *pSta
1540: 72 74 2c 20 2a 70 45 6e 64 3b 20 20 20 20 20 20  rt, *pEnd;      
1550: 20 20 20 20 20 2f 2a 20 42 6f 75 6e 64 73 20 6f       /* Bounds o
1560: 66 20 70 61 67 65 63 61 63 68 65 20 6d 61 6c 6c  f pagecache mall
1570: 6f 63 20 72 61 6e 67 65 20 2a 2f 0a 20 20 2f 2a  oc range */.  /*
1580: 20 41 62 6f 76 65 20 72 65 71 75 69 72 65 73 20   Above requires 
1590: 6e 6f 20 6d 75 74 65 78 2e 20 20 55 73 65 20 6d  no mutex.  Use m
15a0: 75 74 65 78 20 62 65 6c 6f 77 20 66 6f 72 20 76  utex below for v
15b0: 61 72 69 61 62 6c 65 20 74 68 61 74 20 66 6f 6c  ariable that fol
15c0: 6c 6f 77 2e 20 2a 2f 0a 20 20 73 71 6c 69 74 65  low. */.  sqlite
15d0: 33 5f 6d 75 74 65 78 20 2a 6d 75 74 65 78 3b 20  3_mutex *mutex; 
15e0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 75 74 65           /* Mute
15f0: 78 20 66 6f 72 20 61 63 63 65 73 73 69 6e 67 20  x for accessing 
1600: 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 3a 20 2a  the following: *
1610: 2f 0a 20 20 69 6e 74 20 6e 46 72 65 65 53 6c 6f  /.  int nFreeSlo
1620: 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t;              
1630: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
1640: 75 6e 75 73 65 64 20 70 63 61 63 68 65 20 73 6c  unused pcache sl
1650: 6f 74 73 20 2a 2f 0a 20 20 50 67 46 72 65 65 73  ots */.  PgFrees
1660: 6c 6f 74 20 2a 70 46 72 65 65 3b 20 20 20 20 20  lot *pFree;     
1670: 20 20 20 20 20 20 20 20 2f 2a 20 46 72 65 65 20          /* Free 
1680: 70 61 67 65 20 62 6c 6f 63 6b 73 20 2a 2f 0a 20  page blocks */. 
1690: 20 2f 2a 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e   /* The followin
16a0: 67 20 76 61 6c 75 65 20 72 65 71 75 69 72 65 73  g value requires
16b0: 20 61 20 6d 75 74 65 78 20 74 6f 20 63 68 61 6e   a mutex to chan
16c0: 67 65 2e 20 20 57 65 20 73 6b 69 70 20 74 68 65  ge.  We skip the
16d0: 20 6d 75 74 65 78 20 6f 6e 0a 20 20 2a 2a 20 72   mutex on.  ** r
16e0: 65 61 64 69 6e 67 20 62 65 63 61 75 73 65 20 28  eading because (
16f0: 31 29 20 6d 6f 73 74 20 70 6c 61 74 66 6f 72 6d  1) most platform
1700: 73 20 72 65 61 64 20 61 20 33 32 2d 62 69 74 20  s read a 32-bit 
1710: 69 6e 74 65 67 65 72 20 61 74 6f 6d 69 63 61 6c  integer atomical
1720: 6c 79 20 61 6e 64 0a 20 20 2a 2a 20 28 32 29 20  ly and.  ** (2) 
1730: 65 76 65 6e 20 69 66 20 61 6e 20 69 6e 63 6f 72  even if an incor
1740: 72 65 63 74 20 76 61 6c 75 65 20 69 73 20 72 65  rect value is re
1750: 61 64 2c 20 6e 6f 20 67 72 65 61 74 20 68 61 72  ad, no great har
1760: 6d 20 69 73 20 64 6f 6e 65 20 73 69 6e 63 65 20  m is done since 
1770: 74 68 69 73 0a 20 20 2a 2a 20 69 73 20 72 65 61  this.  ** is rea
1780: 6c 6c 79 20 6a 75 73 74 20 61 6e 20 6f 70 74 69  lly just an opti
1790: 6d 69 7a 61 74 69 6f 6e 2e 20 2a 2f 0a 20 20 69  mization. */.  i
17a0: 6e 74 20 62 55 6e 64 65 72 50 72 65 73 73 75 72  nt bUnderPressur
17b0: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  e;            /*
17c0: 20 54 72 75 65 20 69 66 20 6c 6f 77 20 6f 6e 20   True if low on 
17d0: 50 41 47 45 43 41 43 48 45 20 6d 65 6d 6f 72 79  PAGECACHE memory
17e0: 20 2a 2f 0a 7d 20 70 63 61 63 68 65 31 5f 67 3b   */.} pcache1_g;
17f0: 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c 20 63 6f 64 65  ../*.** All code
1800: 20 69 6e 20 74 68 69 73 20 66 69 6c 65 20 73 68   in this file sh
1810: 6f 75 6c 64 20 61 63 63 65 73 73 20 74 68 65 20  ould access the 
1820: 67 6c 6f 62 61 6c 20 73 74 72 75 63 74 75 72 65  global structure
1830: 20 61 62 6f 76 65 20 76 69 61 20 74 68 65 0a 2a   above via the.*
1840: 2a 20 61 6c 69 61 73 20 22 70 63 61 63 68 65 31  * alias "pcache1
1850: 22 2e 20 54 68 69 73 20 65 6e 73 75 72 65 73 20  ". This ensures 
1860: 74 68 61 74 20 74 68 65 20 57 53 44 20 65 6d 75  that the WSD emu
1870: 6c 61 74 69 6f 6e 20 69 73 20 75 73 65 64 20 77  lation is used w
1880: 68 65 6e 0a 2a 2a 20 63 6f 6d 70 69 6c 69 6e 67  hen.** compiling
1890: 20 66 6f 72 20 73 79 73 74 65 6d 73 20 74 68 61   for systems tha
18a0: 74 20 64 6f 20 6e 6f 74 20 73 75 70 70 6f 72 74  t do not support
18b0: 20 72 65 61 6c 20 57 53 44 2e 0a 2a 2f 0a 23 64   real WSD..*/.#d
18c0: 65 66 69 6e 65 20 70 63 61 63 68 65 31 20 28 47  efine pcache1 (G
18d0: 4c 4f 42 41 4c 28 73 74 72 75 63 74 20 50 43 61  LOBAL(struct PCa
18e0: 63 68 65 47 6c 6f 62 61 6c 2c 20 70 63 61 63 68  cheGlobal, pcach
18f0: 65 31 5f 67 29 29 0a 0a 2f 2a 0a 2a 2a 20 4d 61  e1_g))../*.** Ma
1900: 63 72 6f 73 20 74 6f 20 65 6e 74 65 72 20 61 6e  cros to enter an
1910: 64 20 6c 65 61 76 65 20 74 68 65 20 50 43 61 63  d leave the PCac
1920: 68 65 20 4c 52 55 20 6d 75 74 65 78 2e 0a 2a 2f  he LRU mutex..*/
1930: 0a 23 64 65 66 69 6e 65 20 70 63 61 63 68 65 31  .#define pcache1
1940: 45 6e 74 65 72 4d 75 74 65 78 28 58 29 20 73 71  EnterMutex(X) sq
1950: 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e 74 65  lite3_mutex_ente
1960: 72 28 28 58 29 2d 3e 6d 75 74 65 78 29 0a 23 64  r((X)->mutex).#d
1970: 65 66 69 6e 65 20 70 63 61 63 68 65 31 4c 65 61  efine pcache1Lea
1980: 76 65 4d 75 74 65 78 28 58 29 20 73 71 6c 69 74  veMutex(X) sqlit
1990: 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 28  e3_mutex_leave((
19a0: 58 29 2d 3e 6d 75 74 65 78 29 0a 0a 2f 2a 2a 2a  X)->mutex)../***
19b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
19c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
19d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
19e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
19f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 2a  ***********/./**
1a00: 2a 2a 2a 2a 2a 2a 20 50 61 67 65 20 41 6c 6c 6f  ****** Page Allo
1a10: 63 61 74 69 6f 6e 2f 53 51 4c 49 54 45 5f 43 4f  cation/SQLITE_CO
1a20: 4e 46 49 47 5f 50 43 41 43 48 45 20 52 65 6c 61  NFIG_PCACHE Rela
1a30: 74 65 64 20 46 75 6e 63 74 69 6f 6e 73 20 2a 2a  ted Functions **
1a40: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f  ************/../
1a50: 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69  *.** This functi
1a60: 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 64 75 72  on is called dur
1a70: 69 6e 67 20 69 6e 69 74 69 61 6c 69 7a 61 74 69  ing initializati
1a80: 6f 6e 20 69 66 20 61 20 73 74 61 74 69 63 20 62  on if a static b
1a90: 75 66 66 65 72 20 69 73 20 0a 2a 2a 20 73 75 70  uffer is .** sup
1aa0: 70 6c 69 65 64 20 74 6f 20 75 73 65 20 66 6f 72  plied to use for
1ab0: 20 74 68 65 20 70 61 67 65 2d 63 61 63 68 65 20   the page-cache 
1ac0: 62 79 20 70 61 73 73 69 6e 67 20 74 68 65 20 53  by passing the S
1ad0: 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47  QLITE_CONFIG_PAG
1ae0: 45 43 41 43 48 45 0a 2a 2a 20 76 65 72 62 20 74  ECACHE.** verb t
1af0: 6f 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67  o sqlite3_config
1b00: 28 29 2e 20 50 61 72 61 6d 65 74 65 72 20 70 42  (). Parameter pB
1b10: 75 66 20 70 6f 69 6e 74 73 20 74 6f 20 61 6e 20  uf points to an 
1b20: 61 6c 6c 6f 63 61 74 69 6f 6e 20 6c 61 72 67 65  allocation large
1b30: 0a 2a 2a 20 65 6e 6f 75 67 68 20 74 6f 20 63 6f  .** enough to co
1b40: 6e 74 61 69 6e 20 27 6e 27 20 62 75 66 66 65 72  ntain 'n' buffer
1b50: 73 20 6f 66 20 27 73 7a 27 20 62 79 74 65 73 20  s of 'sz' bytes 
1b60: 65 61 63 68 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73  each..**.** This
1b70: 20 72 6f 75 74 69 6e 65 20 69 73 20 63 61 6c 6c   routine is call
1b80: 65 64 20 66 72 6f 6d 20 73 71 6c 69 74 65 33 5f  ed from sqlite3_
1b90: 69 6e 69 74 69 61 6c 69 7a 65 28 29 20 61 6e 64  initialize() and
1ba0: 20 73 6f 20 69 74 20 69 73 20 67 75 61 72 61 6e   so it is guaran
1bb0: 74 65 65 64 0a 2a 2a 20 74 6f 20 62 65 20 73 65  teed.** to be se
1bc0: 72 69 61 6c 69 7a 65 64 20 61 6c 72 65 61 64 79  rialized already
1bd0: 2e 20 20 54 68 65 72 65 20 69 73 20 6e 6f 20 6e  .  There is no n
1be0: 65 65 64 20 66 6f 72 20 66 75 72 74 68 65 72 20  eed for further 
1bf0: 6d 75 74 65 78 69 6e 67 2e 0a 2a 2f 0a 76 6f 69  mutexing..*/.voi
1c00: 64 20 73 71 6c 69 74 65 33 50 43 61 63 68 65 42  d sqlite3PCacheB
1c10: 75 66 66 65 72 53 65 74 75 70 28 76 6f 69 64 20  ufferSetup(void 
1c20: 2a 70 42 75 66 2c 20 69 6e 74 20 73 7a 2c 20 69  *pBuf, int sz, i
1c30: 6e 74 20 6e 29 7b 0a 20 20 69 66 28 20 70 63 61  nt n){.  if( pca
1c40: 63 68 65 31 2e 69 73 49 6e 69 74 20 29 7b 0a 20  che1.isInit ){. 
1c50: 20 20 20 50 67 46 72 65 65 73 6c 6f 74 20 2a 70     PgFreeslot *p
1c60: 3b 0a 20 20 20 20 73 7a 20 3d 20 52 4f 55 4e 44  ;.    sz = ROUND
1c70: 44 4f 57 4e 38 28 73 7a 29 3b 0a 20 20 20 20 70  DOWN8(sz);.    p
1c80: 63 61 63 68 65 31 2e 73 7a 53 6c 6f 74 20 3d 20  cache1.szSlot = 
1c90: 73 7a 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e  sz;.    pcache1.
1ca0: 6e 53 6c 6f 74 20 3d 20 70 63 61 63 68 65 31 2e  nSlot = pcache1.
1cb0: 6e 46 72 65 65 53 6c 6f 74 20 3d 20 6e 3b 0a 20  nFreeSlot = n;. 
1cc0: 20 20 20 70 63 61 63 68 65 31 2e 6e 52 65 73 65     pcache1.nRese
1cd0: 72 76 65 20 3d 20 6e 3e 39 30 20 3f 20 31 30 20  rve = n>90 ? 10 
1ce0: 3a 20 28 6e 2f 31 30 20 2b 20 31 29 3b 0a 20 20  : (n/10 + 1);.  
1cf0: 20 20 70 63 61 63 68 65 31 2e 70 53 74 61 72 74    pcache1.pStart
1d00: 20 3d 20 70 42 75 66 3b 0a 20 20 20 20 70 63 61   = pBuf;.    pca
1d10: 63 68 65 31 2e 70 46 72 65 65 20 3d 20 30 3b 0a  che1.pFree = 0;.
1d20: 20 20 20 20 70 63 61 63 68 65 31 2e 62 55 6e 64      pcache1.bUnd
1d30: 65 72 50 72 65 73 73 75 72 65 20 3d 20 30 3b 0a  erPressure = 0;.
1d40: 20 20 20 20 77 68 69 6c 65 28 20 6e 2d 2d 20 29      while( n-- )
1d50: 7b 0a 20 20 20 20 20 20 70 20 3d 20 28 50 67 46  {.      p = (PgF
1d60: 72 65 65 73 6c 6f 74 2a 29 70 42 75 66 3b 0a 20  reeslot*)pBuf;. 
1d70: 20 20 20 20 20 70 2d 3e 70 4e 65 78 74 20 3d 20       p->pNext = 
1d80: 70 63 61 63 68 65 31 2e 70 46 72 65 65 3b 0a 20  pcache1.pFree;. 
1d90: 20 20 20 20 20 70 63 61 63 68 65 31 2e 70 46 72       pcache1.pFr
1da0: 65 65 20 3d 20 70 3b 0a 20 20 20 20 20 20 70 42  ee = p;.      pB
1db0: 75 66 20 3d 20 28 76 6f 69 64 2a 29 26 28 28 63  uf = (void*)&((c
1dc0: 68 61 72 2a 29 70 42 75 66 29 5b 73 7a 5d 3b 0a  har*)pBuf)[sz];.
1dd0: 20 20 20 20 7d 0a 20 20 20 20 70 63 61 63 68 65      }.    pcache
1de0: 31 2e 70 45 6e 64 20 3d 20 70 42 75 66 3b 0a 20  1.pEnd = pBuf;. 
1df0: 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6c 6c   }.}../*.** Mall
1e00: 6f 63 20 66 75 6e 63 74 69 6f 6e 20 75 73 65 64  oc function used
1e10: 20 77 69 74 68 69 6e 20 74 68 69 73 20 66 69 6c   within this fil
1e20: 65 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 73 70  e to allocate sp
1e30: 61 63 65 20 66 72 6f 6d 20 74 68 65 20 62 75 66  ace from the buf
1e40: 66 65 72 0a 2a 2a 20 63 6f 6e 66 69 67 75 72 65  fer.** configure
1e50: 64 20 75 73 69 6e 67 20 73 71 6c 69 74 65 33 5f  d using sqlite3_
1e60: 63 6f 6e 66 69 67 28 53 51 4c 49 54 45 5f 43 4f  config(SQLITE_CO
1e70: 4e 46 49 47 5f 50 41 47 45 43 41 43 48 45 29 20  NFIG_PAGECACHE) 
1e80: 6f 70 74 69 6f 6e 2e 20 49 66 20 6e 6f 20 0a 2a  option. If no .*
1e90: 2a 20 73 75 63 68 20 62 75 66 66 65 72 20 65 78  * such buffer ex
1ea0: 69 73 74 73 20 6f 72 20 74 68 65 72 65 20 69 73  ists or there is
1eb0: 20 6e 6f 20 73 70 61 63 65 20 6c 65 66 74 20 69   no space left i
1ec0: 6e 20 69 74 2c 20 74 68 69 73 20 66 75 6e 63 74  n it, this funct
1ed0: 69 6f 6e 20 66 61 6c 6c 73 20 0a 2a 2a 20 62 61  ion falls .** ba
1ee0: 63 6b 20 74 6f 20 73 71 6c 69 74 65 33 4d 61 6c  ck to sqlite3Mal
1ef0: 6c 6f 63 28 29 2e 0a 2a 2a 0a 2a 2a 20 4d 75 6c  loc()..**.** Mul
1f00: 74 69 70 6c 65 20 74 68 72 65 61 64 73 20 63 61  tiple threads ca
1f10: 6e 20 72 75 6e 20 74 68 69 73 20 72 6f 75 74 69  n run this routi
1f20: 6e 65 20 61 74 20 74 68 65 20 73 61 6d 65 20 74  ne at the same t
1f30: 69 6d 65 2e 20 20 47 6c 6f 62 61 6c 20 76 61 72  ime.  Global var
1f40: 69 61 62 6c 65 73 0a 2a 2a 20 69 6e 20 70 63 61  iables.** in pca
1f50: 63 68 65 31 20 6e 65 65 64 20 74 6f 20 62 65 20  che1 need to be 
1f60: 70 72 6f 74 65 63 74 65 64 20 76 69 61 20 6d 75  protected via mu
1f70: 74 65 78 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  tex..*/.static v
1f80: 6f 69 64 20 2a 70 63 61 63 68 65 31 41 6c 6c 6f  oid *pcache1Allo
1f90: 63 28 69 6e 74 20 6e 42 79 74 65 29 7b 0a 20 20  c(int nByte){.  
1fa0: 76 6f 69 64 20 2a 70 20 3d 20 30 3b 0a 20 20 61  void *p = 0;.  a
1fb0: 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d  ssert( sqlite3_m
1fc0: 75 74 65 78 5f 6e 6f 74 68 65 6c 64 28 70 63 61  utex_notheld(pca
1fd0: 63 68 65 31 2e 67 72 70 2e 6d 75 74 65 78 29 20  che1.grp.mutex) 
1fe0: 29 3b 0a 20 20 73 71 6c 69 74 65 33 53 74 61 74  );.  sqlite3Stat
1ff0: 75 73 53 65 74 28 53 51 4c 49 54 45 5f 53 54 41  usSet(SQLITE_STA
2000: 54 55 53 5f 50 41 47 45 43 41 43 48 45 5f 53 49  TUS_PAGECACHE_SI
2010: 5a 45 2c 20 6e 42 79 74 65 29 3b 0a 20 20 69 66  ZE, nByte);.  if
2020: 28 20 6e 42 79 74 65 3c 3d 70 63 61 63 68 65 31  ( nByte<=pcache1
2030: 2e 73 7a 53 6c 6f 74 20 29 7b 0a 20 20 20 20 73  .szSlot ){.    s
2040: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e 74  qlite3_mutex_ent
2050: 65 72 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78  er(pcache1.mutex
2060: 29 3b 0a 20 20 20 20 70 20 3d 20 28 50 67 48 64  );.    p = (PgHd
2070: 72 31 20 2a 29 70 63 61 63 68 65 31 2e 70 46 72  r1 *)pcache1.pFr
2080: 65 65 3b 0a 20 20 20 20 69 66 28 20 70 20 29 7b  ee;.    if( p ){
2090: 0a 20 20 20 20 20 20 70 63 61 63 68 65 31 2e 70  .      pcache1.p
20a0: 46 72 65 65 20 3d 20 70 63 61 63 68 65 31 2e 70  Free = pcache1.p
20b0: 46 72 65 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20  Free->pNext;.   
20c0: 20 20 20 70 63 61 63 68 65 31 2e 6e 46 72 65 65     pcache1.nFree
20d0: 53 6c 6f 74 2d 2d 3b 0a 20 20 20 20 20 20 70 63  Slot--;.      pc
20e0: 61 63 68 65 31 2e 62 55 6e 64 65 72 50 72 65 73  ache1.bUnderPres
20f0: 73 75 72 65 20 3d 20 70 63 61 63 68 65 31 2e 6e  sure = pcache1.n
2100: 46 72 65 65 53 6c 6f 74 3c 70 63 61 63 68 65 31  FreeSlot<pcache1
2110: 2e 6e 52 65 73 65 72 76 65 3b 0a 20 20 20 20 20  .nReserve;.     
2120: 20 61 73 73 65 72 74 28 20 70 63 61 63 68 65 31   assert( pcache1
2130: 2e 6e 46 72 65 65 53 6c 6f 74 3e 3d 30 20 29 3b  .nFreeSlot>=0 );
2140: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 53 74  .      sqlite3St
2150: 61 74 75 73 41 64 64 28 53 51 4c 49 54 45 5f 53  atusAdd(SQLITE_S
2160: 54 41 54 55 53 5f 50 41 47 45 43 41 43 48 45 5f  TATUS_PAGECACHE_
2170: 55 53 45 44 2c 20 31 29 3b 0a 20 20 20 20 7d 0a  USED, 1);.    }.
2180: 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65      sqlite3_mute
2190: 78 5f 6c 65 61 76 65 28 70 63 61 63 68 65 31 2e  x_leave(pcache1.
21a0: 6d 75 74 65 78 29 3b 0a 20 20 7d 0a 20 20 69 66  mutex);.  }.  if
21b0: 28 20 70 3d 3d 30 20 29 7b 0a 20 20 20 20 2f 2a  ( p==0 ){.    /*
21c0: 20 4d 65 6d 6f 72 79 20 69 73 20 6e 6f 74 20 61   Memory is not a
21d0: 76 61 69 6c 61 62 6c 65 20 69 6e 20 74 68 65 20  vailable in the 
21e0: 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41  SQLITE_CONFIG_PA
21f0: 47 45 43 41 43 48 45 20 70 6f 6f 6c 2e 20 20 47  GECACHE pool.  G
2200: 65 74 0a 20 20 20 20 2a 2a 20 69 74 20 66 72 6f  et.    ** it fro
2210: 6d 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 20  m sqlite3Malloc 
2220: 69 6e 73 74 65 61 64 2e 0a 20 20 20 20 2a 2f 0a  instead..    */.
2230: 20 20 20 20 70 20 3d 20 73 71 6c 69 74 65 33 4d      p = sqlite3M
2240: 61 6c 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20  alloc(nByte);.  
2250: 20 20 69 66 28 20 70 20 29 7b 0a 20 20 20 20 20    if( p ){.     
2260: 20 69 6e 74 20 73 7a 20 3d 20 73 71 6c 69 74 65   int sz = sqlite
2270: 33 4d 61 6c 6c 6f 63 53 69 7a 65 28 70 29 3b 0a  3MallocSize(p);.
2280: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 75        sqlite3_mu
2290: 74 65 78 5f 65 6e 74 65 72 28 70 63 61 63 68 65  tex_enter(pcache
22a0: 31 2e 6d 75 74 65 78 29 3b 0a 20 20 20 20 20 20  1.mutex);.      
22b0: 73 71 6c 69 74 65 33 53 74 61 74 75 73 41 64 64  sqlite3StatusAdd
22c0: 28 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50  (SQLITE_STATUS_P
22d0: 41 47 45 43 41 43 48 45 5f 4f 56 45 52 46 4c 4f  AGECACHE_OVERFLO
22e0: 57 2c 20 73 7a 29 3b 0a 20 20 20 20 20 20 73 71  W, sz);.      sq
22f0: 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76  lite3_mutex_leav
2300: 65 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29  e(pcache1.mutex)
2310: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 6c 69  ;.    }.    sqli
2320: 74 65 33 4d 65 6d 64 65 62 75 67 53 65 74 54 79  te3MemdebugSetTy
2330: 70 65 28 70 2c 20 4d 45 4d 54 59 50 45 5f 50 43  pe(p, MEMTYPE_PC
2340: 41 43 48 45 29 3b 0a 20 20 7d 0a 20 20 72 65 74  ACHE);.  }.  ret
2350: 75 72 6e 20 70 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  urn p;.}../*.** 
2360: 46 72 65 65 20 61 6e 20 61 6c 6c 6f 63 61 74 65  Free an allocate
2370: 64 20 62 75 66 66 65 72 20 6f 62 74 61 69 6e 65  d buffer obtaine
2380: 64 20 66 72 6f 6d 20 70 63 61 63 68 65 31 41 6c  d from pcache1Al
2390: 6c 6f 63 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63  loc()..*/.static
23a0: 20 76 6f 69 64 20 70 63 61 63 68 65 31 46 72 65   void pcache1Fre
23b0: 65 28 76 6f 69 64 20 2a 70 29 7b 0a 20 20 69 66  e(void *p){.  if
23c0: 28 20 70 3d 3d 30 20 29 20 72 65 74 75 72 6e 3b  ( p==0 ) return;
23d0: 0a 20 20 69 66 28 20 70 3e 3d 70 63 61 63 68 65  .  if( p>=pcache
23e0: 31 2e 70 53 74 61 72 74 20 26 26 20 70 3c 70 63  1.pStart && p<pc
23f0: 61 63 68 65 31 2e 70 45 6e 64 20 29 7b 0a 20 20  ache1.pEnd ){.  
2400: 20 20 50 67 46 72 65 65 73 6c 6f 74 20 2a 70 53    PgFreeslot *pS
2410: 6c 6f 74 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  lot;.    sqlite3
2420: 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28 70 63 61  _mutex_enter(pca
2430: 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a 20 20 20  che1.mutex);.   
2440: 20 73 71 6c 69 74 65 33 53 74 61 74 75 73 41 64   sqlite3StatusAd
2450: 64 28 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f  d(SQLITE_STATUS_
2460: 50 41 47 45 43 41 43 48 45 5f 55 53 45 44 2c 20  PAGECACHE_USED, 
2470: 2d 31 29 3b 0a 20 20 20 20 70 53 6c 6f 74 20 3d  -1);.    pSlot =
2480: 20 28 50 67 46 72 65 65 73 6c 6f 74 2a 29 70 3b   (PgFreeslot*)p;
2490: 0a 20 20 20 20 70 53 6c 6f 74 2d 3e 70 4e 65 78  .    pSlot->pNex
24a0: 74 20 3d 20 70 63 61 63 68 65 31 2e 70 46 72 65  t = pcache1.pFre
24b0: 65 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 70  e;.    pcache1.p
24c0: 46 72 65 65 20 3d 20 70 53 6c 6f 74 3b 0a 20 20  Free = pSlot;.  
24d0: 20 20 70 63 61 63 68 65 31 2e 6e 46 72 65 65 53    pcache1.nFreeS
24e0: 6c 6f 74 2b 2b 3b 0a 20 20 20 20 70 63 61 63 68  lot++;.    pcach
24f0: 65 31 2e 62 55 6e 64 65 72 50 72 65 73 73 75 72  e1.bUnderPressur
2500: 65 20 3d 20 70 63 61 63 68 65 31 2e 6e 46 72 65  e = pcache1.nFre
2510: 65 53 6c 6f 74 3c 70 63 61 63 68 65 31 2e 6e 52  eSlot<pcache1.nR
2520: 65 73 65 72 76 65 3b 0a 20 20 20 20 61 73 73 65  eserve;.    asse
2530: 72 74 28 20 70 63 61 63 68 65 31 2e 6e 46 72 65  rt( pcache1.nFre
2540: 65 53 6c 6f 74 3c 3d 70 63 61 63 68 65 31 2e 6e  eSlot<=pcache1.n
2550: 53 6c 6f 74 20 29 3b 0a 20 20 20 20 73 71 6c 69  Slot );.    sqli
2560: 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28  te3_mutex_leave(
2570: 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a  pcache1.mutex);.
2580: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 6e 74    }else{.    int
2590: 20 69 53 69 7a 65 3b 0a 20 20 20 20 61 73 73 65   iSize;.    asse
25a0: 72 74 28 20 73 71 6c 69 74 65 33 4d 65 6d 64 65  rt( sqlite3Memde
25b0: 62 75 67 48 61 73 54 79 70 65 28 70 2c 20 4d 45  bugHasType(p, ME
25c0: 4d 54 59 50 45 5f 50 43 41 43 48 45 29 20 29 3b  MTYPE_PCACHE) );
25d0: 0a 20 20 20 20 73 71 6c 69 74 65 33 4d 65 6d 64  .    sqlite3Memd
25e0: 65 62 75 67 53 65 74 54 79 70 65 28 70 2c 20 4d  ebugSetType(p, M
25f0: 45 4d 54 59 50 45 5f 48 45 41 50 29 3b 0a 20 20  EMTYPE_HEAP);.  
2600: 20 20 69 53 69 7a 65 20 3d 20 73 71 6c 69 74 65    iSize = sqlite
2610: 33 4d 61 6c 6c 6f 63 53 69 7a 65 28 70 29 3b 0a  3MallocSize(p);.
2620: 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65      sqlite3_mute
2630: 78 5f 65 6e 74 65 72 28 70 63 61 63 68 65 31 2e  x_enter(pcache1.
2640: 6d 75 74 65 78 29 3b 0a 20 20 20 20 73 71 6c 69  mutex);.    sqli
2650: 74 65 33 53 74 61 74 75 73 41 64 64 28 53 51 4c  te3StatusAdd(SQL
2660: 49 54 45 5f 53 54 41 54 55 53 5f 50 41 47 45 43  ITE_STATUS_PAGEC
2670: 41 43 48 45 5f 4f 56 45 52 46 4c 4f 57 2c 20 2d  ACHE_OVERFLOW, -
2680: 69 53 69 7a 65 29 3b 0a 20 20 20 20 73 71 6c 69  iSize);.    sqli
2690: 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28  te3_mutex_leave(
26a0: 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a  pcache1.mutex);.
26b0: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
26c0: 28 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 23 69 66 64  (p);.  }.}..#ifd
26d0: 65 66 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45  ef SQLITE_ENABLE
26e0: 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45  _MEMORY_MANAGEME
26f0: 4e 54 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20  NT./*.** Return 
2700: 74 68 65 20 73 69 7a 65 20 6f 66 20 61 20 70 63  the size of a pc
2710: 61 63 68 65 20 61 6c 6c 6f 63 61 74 69 6f 6e 0a  ache allocation.
2720: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 70 63  */.static int pc
2730: 61 63 68 65 31 4d 65 6d 53 69 7a 65 28 76 6f 69  ache1MemSize(voi
2740: 64 20 2a 70 29 7b 0a 20 20 69 66 28 20 70 3e 3d  d *p){.  if( p>=
2750: 70 63 61 63 68 65 31 2e 70 53 74 61 72 74 20 26  pcache1.pStart &
2760: 26 20 70 3c 70 63 61 63 68 65 31 2e 70 45 6e 64  & p<pcache1.pEnd
2770: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 70   ){.    return p
2780: 63 61 63 68 65 31 2e 73 7a 53 6c 6f 74 3b 0a 20  cache1.szSlot;. 
2790: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 6e 74 20   }else{.    int 
27a0: 69 53 69 7a 65 3b 0a 20 20 20 20 61 73 73 65 72  iSize;.    asser
27b0: 74 28 20 73 71 6c 69 74 65 33 4d 65 6d 64 65 62  t( sqlite3Memdeb
27c0: 75 67 48 61 73 54 79 70 65 28 70 2c 20 4d 45 4d  ugHasType(p, MEM
27d0: 54 59 50 45 5f 50 43 41 43 48 45 29 20 29 3b 0a  TYPE_PCACHE) );.
27e0: 20 20 20 20 73 71 6c 69 74 65 33 4d 65 6d 64 65      sqlite3Memde
27f0: 62 75 67 53 65 74 54 79 70 65 28 70 2c 20 4d 45  bugSetType(p, ME
2800: 4d 54 59 50 45 5f 48 45 41 50 29 3b 0a 20 20 20  MTYPE_HEAP);.   
2810: 20 69 53 69 7a 65 20 3d 20 73 71 6c 69 74 65 33   iSize = sqlite3
2820: 4d 61 6c 6c 6f 63 53 69 7a 65 28 70 29 3b 0a 20  MallocSize(p);. 
2830: 20 20 20 73 71 6c 69 74 65 33 4d 65 6d 64 65 62     sqlite3Memdeb
2840: 75 67 53 65 74 54 79 70 65 28 70 2c 20 4d 45 4d  ugSetType(p, MEM
2850: 54 59 50 45 5f 50 43 41 43 48 45 29 3b 0a 20 20  TYPE_PCACHE);.  
2860: 20 20 72 65 74 75 72 6e 20 69 53 69 7a 65 3b 0a    return iSize;.
2870: 20 20 7d 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a 20    }.}.#endif /* 
2880: 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45  SQLITE_ENABLE_ME
2890: 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 20  MORY_MANAGEMENT 
28a0: 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c 6f 63 61  */../*.** Alloca
28b0: 74 65 20 61 20 6e 65 77 20 70 61 67 65 20 6f 62  te a new page ob
28c0: 6a 65 63 74 20 69 6e 69 74 69 61 6c 6c 79 20 61  ject initially a
28d0: 73 73 6f 63 69 61 74 65 64 20 77 69 74 68 20 63  ssociated with c
28e0: 61 63 68 65 20 70 43 61 63 68 65 2e 0a 2a 2f 0a  ache pCache..*/.
28f0: 73 74 61 74 69 63 20 50 67 48 64 72 31 20 2a 70  static PgHdr1 *p
2900: 63 61 63 68 65 31 41 6c 6c 6f 63 50 61 67 65 28  cache1AllocPage(
2910: 50 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 29  PCache1 *pCache)
2920: 7b 0a 20 20 50 67 48 64 72 31 20 2a 70 20 3d 20  {.  PgHdr1 *p = 
2930: 30 3b 0a 20 20 76 6f 69 64 20 2a 70 50 67 3b 0a  0;.  void *pPg;.
2940: 0a 20 20 2f 2a 20 54 68 65 20 67 72 6f 75 70 20  .  /* The group 
2950: 6d 75 74 65 78 20 6d 75 73 74 20 62 65 20 72 65  mutex must be re
2960: 6c 65 61 73 65 64 20 62 65 66 6f 72 65 20 70 63  leased before pc
2970: 61 63 68 65 31 41 6c 6c 6f 63 28 29 20 69 73 20  ache1Alloc() is 
2980: 63 61 6c 6c 65 64 2e 20 54 68 69 73 0a 20 20 2a  called. This.  *
2990: 2a 20 69 73 20 62 65 63 61 75 73 65 20 69 74 20  * is because it 
29a0: 6d 61 79 20 63 61 6c 6c 20 73 71 6c 69 74 65 33  may call sqlite3
29b0: 5f 72 65 6c 65 61 73 65 5f 6d 65 6d 6f 72 79 28  _release_memory(
29c0: 29 2c 20 77 68 69 63 68 20 61 73 73 75 6d 65 73  ), which assumes
29d0: 20 74 68 61 74 20 0a 20 20 2a 2a 20 74 68 69 73   that .  ** this
29e0: 20 6d 75 74 65 78 20 69 73 20 6e 6f 74 20 68 65   mutex is not he
29f0: 6c 64 2e 20 2a 2f 0a 20 20 61 73 73 65 72 74 28  ld. */.  assert(
2a00: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68   sqlite3_mutex_h
2a10: 65 6c 64 28 70 43 61 63 68 65 2d 3e 70 47 72 6f  eld(pCache->pGro
2a20: 75 70 2d 3e 6d 75 74 65 78 29 20 29 3b 0a 20 20  up->mutex) );.  
2a30: 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65  pcache1LeaveMute
2a40: 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70  x(pCache->pGroup
2a50: 29 3b 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45  );.#ifdef SQLITE
2a60: 5f 50 43 41 43 48 45 5f 53 45 50 41 52 41 54 45  _PCACHE_SEPARATE
2a70: 5f 48 45 41 44 45 52 0a 20 20 70 50 67 20 3d 20  _HEADER.  pPg = 
2a80: 70 63 61 63 68 65 31 41 6c 6c 6f 63 28 70 43 61  pcache1Alloc(pCa
2a90: 63 68 65 2d 3e 73 7a 50 61 67 65 29 3b 0a 20 20  che->szPage);.  
2aa0: 70 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f  p = sqlite3Mallo
2ab0: 63 28 73 69 7a 65 6f 66 28 50 67 48 64 72 31 29  c(sizeof(PgHdr1)
2ac0: 20 2b 20 70 43 61 63 68 65 2d 3e 73 7a 45 78 74   + pCache->szExt
2ad0: 72 61 29 3b 0a 20 20 69 66 28 20 21 70 50 67 20  ra);.  if( !pPg 
2ae0: 7c 7c 20 21 70 20 29 7b 0a 20 20 20 20 70 63 61  || !p ){.    pca
2af0: 63 68 65 31 46 72 65 65 28 70 50 67 29 3b 0a 20  che1Free(pPg);. 
2b00: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
2b10: 70 29 3b 0a 20 20 20 20 70 50 67 20 3d 20 30 3b  p);.    pPg = 0;
2b20: 0a 20 20 7d 0a 23 65 6c 73 65 0a 20 20 70 50 67  .  }.#else.  pPg
2b30: 20 3d 20 70 63 61 63 68 65 31 41 6c 6c 6f 63 28   = pcache1Alloc(
2b40: 73 69 7a 65 6f 66 28 50 67 48 64 72 31 29 20 2b  sizeof(PgHdr1) +
2b50: 20 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 20   pCache->szPage 
2b60: 2b 20 70 43 61 63 68 65 2d 3e 73 7a 45 78 74 72  + pCache->szExtr
2b70: 61 29 3b 0a 20 20 70 20 3d 20 28 50 67 48 64 72  a);.  p = (PgHdr
2b80: 31 20 2a 29 26 28 28 75 38 20 2a 29 70 50 67 29  1 *)&((u8 *)pPg)
2b90: 5b 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 5d  [pCache->szPage]
2ba0: 3b 0a 23 65 6e 64 69 66 0a 20 20 70 63 61 63 68  ;.#endif.  pcach
2bb0: 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70 43 61  e1EnterMutex(pCa
2bc0: 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 0a 20  che->pGroup);.. 
2bd0: 20 69 66 28 20 70 50 67 20 29 7b 0a 20 20 20 20   if( pPg ){.    
2be0: 70 2d 3e 70 61 67 65 2e 70 42 75 66 20 3d 20 70  p->page.pBuf = p
2bf0: 50 67 3b 0a 20 20 20 20 70 2d 3e 70 61 67 65 2e  Pg;.    p->page.
2c00: 70 45 78 74 72 61 20 3d 20 26 70 5b 31 5d 3b 0a  pExtra = &p[1];.
2c10: 20 20 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e      if( pCache->
2c20: 62 50 75 72 67 65 61 62 6c 65 20 29 7b 0a 20 20  bPurgeable ){.  
2c30: 20 20 20 20 70 43 61 63 68 65 2d 3e 70 47 72 6f      pCache->pGro
2c40: 75 70 2d 3e 6e 43 75 72 72 65 6e 74 50 61 67 65  up->nCurrentPage
2c50: 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72 65  ++;.    }.    re
2c60: 74 75 72 6e 20 70 3b 0a 20 20 7d 0a 20 20 72 65  turn p;.  }.  re
2c70: 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  turn 0;.}../*.**
2c80: 20 46 72 65 65 20 61 20 70 61 67 65 20 6f 62 6a   Free a page obj
2c90: 65 63 74 20 61 6c 6c 6f 63 61 74 65 64 20 62 79  ect allocated by
2ca0: 20 70 63 61 63 68 65 31 41 6c 6c 6f 63 50 61 67   pcache1AllocPag
2cb0: 65 28 29 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 70  e()..**.** The p
2cc0: 6f 69 6e 74 65 72 20 69 73 20 61 6c 6c 6f 77 65  ointer is allowe
2cd0: 64 20 74 6f 20 62 65 20 4e 55 4c 4c 2c 20 77 68  d to be NULL, wh
2ce0: 69 63 68 20 69 73 20 70 72 75 64 65 6e 74 2e 20  ich is prudent. 
2cf0: 20 42 75 74 20 69 74 20 74 75 72 6e 73 20 6f 75   But it turns ou
2d00: 74 0a 2a 2a 20 74 68 61 74 20 74 68 65 20 63 75  t.** that the cu
2d10: 72 72 65 6e 74 20 69 6d 70 6c 65 6d 65 6e 74 61  rrent implementa
2d20: 74 69 6f 6e 20 68 61 70 70 65 6e 73 20 74 6f 20  tion happens to 
2d30: 6e 65 76 65 72 20 63 61 6c 6c 20 74 68 69 73 20  never call this 
2d40: 72 6f 75 74 69 6e 65 0a 2a 2a 20 77 69 74 68 20  routine.** with 
2d50: 61 20 4e 55 4c 4c 20 70 6f 69 6e 74 65 72 2c 20  a NULL pointer, 
2d60: 73 6f 20 77 65 20 6d 61 72 6b 20 74 68 65 20 4e  so we mark the N
2d70: 55 4c 4c 20 74 65 73 74 20 77 69 74 68 20 41 4c  ULL test with AL
2d80: 57 41 59 53 28 29 2e 0a 2a 2f 0a 73 74 61 74 69  WAYS()..*/.stati
2d90: 63 20 76 6f 69 64 20 70 63 61 63 68 65 31 46 72  c void pcache1Fr
2da0: 65 65 50 61 67 65 28 50 67 48 64 72 31 20 2a 70  eePage(PgHdr1 *p
2db0: 29 7b 0a 20 20 69 66 28 20 41 4c 57 41 59 53 28  ){.  if( ALWAYS(
2dc0: 70 29 20 29 7b 0a 20 20 20 20 50 43 61 63 68 65  p) ){.    PCache
2dd0: 31 20 2a 70 43 61 63 68 65 20 3d 20 70 2d 3e 70  1 *pCache = p->p
2de0: 43 61 63 68 65 3b 0a 20 20 20 20 61 73 73 65 72  Cache;.    asser
2df0: 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78  t( sqlite3_mutex
2e00: 5f 68 65 6c 64 28 70 2d 3e 70 43 61 63 68 65 2d  _held(p->pCache-
2e10: 3e 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78 29 20  >pGroup->mutex) 
2e20: 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31 46 72  );.    pcache1Fr
2e30: 65 65 28 70 2d 3e 70 61 67 65 2e 70 42 75 66 29  ee(p->page.pBuf)
2e40: 3b 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f  ;.#ifdef SQLITE_
2e50: 50 43 41 43 48 45 5f 53 45 50 41 52 41 54 45 5f  PCACHE_SEPARATE_
2e60: 48 45 41 44 45 52 0a 20 20 20 20 73 71 6c 69 74  HEADER.    sqlit
2e70: 65 33 5f 66 72 65 65 28 70 29 3b 0a 23 65 6e 64  e3_free(p);.#end
2e80: 69 66 0a 20 20 20 20 69 66 28 20 70 43 61 63 68  if.    if( pCach
2e90: 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 29 7b  e->bPurgeable ){
2ea0: 0a 20 20 20 20 20 20 70 43 61 63 68 65 2d 3e 70  .      pCache->p
2eb0: 47 72 6f 75 70 2d 3e 6e 43 75 72 72 65 6e 74 50  Group->nCurrentP
2ec0: 61 67 65 2d 2d 3b 0a 20 20 20 20 7d 0a 20 20 7d  age--;.    }.  }
2ed0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6c 6c 6f 63  .}../*.** Malloc
2ee0: 20 66 75 6e 63 74 69 6f 6e 20 75 73 65 64 20 62   function used b
2ef0: 79 20 53 51 4c 69 74 65 20 74 6f 20 6f 62 74 61  y SQLite to obta
2f00: 69 6e 20 73 70 61 63 65 20 66 72 6f 6d 20 74 68  in space from th
2f10: 65 20 62 75 66 66 65 72 20 63 6f 6e 66 69 67 75  e buffer configu
2f20: 72 65 64 0a 2a 2a 20 75 73 69 6e 67 20 73 71 6c  red.** using sql
2f30: 69 74 65 33 5f 63 6f 6e 66 69 67 28 53 51 4c 49  ite3_config(SQLI
2f40: 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41  TE_CONFIG_PAGECA
2f50: 43 48 45 29 20 6f 70 74 69 6f 6e 2e 20 49 66 20  CHE) option. If 
2f60: 6e 6f 20 73 75 63 68 20 62 75 66 66 65 72 0a 2a  no such buffer.*
2f70: 2a 20 65 78 69 73 74 73 2c 20 74 68 69 73 20 66  * exists, this f
2f80: 75 6e 63 74 69 6f 6e 20 66 61 6c 6c 73 20 62 61  unction falls ba
2f90: 63 6b 20 74 6f 20 73 71 6c 69 74 65 33 4d 61 6c  ck to sqlite3Mal
2fa0: 6c 6f 63 28 29 2e 0a 2a 2f 0a 76 6f 69 64 20 2a  loc()..*/.void *
2fb0: 73 71 6c 69 74 65 33 50 61 67 65 4d 61 6c 6c 6f  sqlite3PageMallo
2fc0: 63 28 69 6e 74 20 73 7a 29 7b 0a 20 20 72 65 74  c(int sz){.  ret
2fd0: 75 72 6e 20 70 63 61 63 68 65 31 41 6c 6c 6f 63  urn pcache1Alloc
2fe0: 28 73 7a 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46  (sz);.}../*.** F
2ff0: 72 65 65 20 61 6e 20 61 6c 6c 6f 63 61 74 65 64  ree an allocated
3000: 20 62 75 66 66 65 72 20 6f 62 74 61 69 6e 65 64   buffer obtained
3010: 20 66 72 6f 6d 20 73 71 6c 69 74 65 33 50 61 67   from sqlite3Pag
3020: 65 4d 61 6c 6c 6f 63 28 29 2e 0a 2a 2f 0a 76 6f  eMalloc()..*/.vo
3030: 69 64 20 73 71 6c 69 74 65 33 50 61 67 65 46 72  id sqlite3PageFr
3040: 65 65 28 76 6f 69 64 20 2a 70 29 7b 0a 20 20 70  ee(void *p){.  p
3050: 63 61 63 68 65 31 46 72 65 65 28 70 29 3b 0a 7d  cache1Free(p);.}
3060: 0a 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20  .../*.** Return 
3070: 74 72 75 65 20 69 66 20 69 74 20 64 65 73 69 72  true if it desir
3080: 61 62 6c 65 20 74 6f 20 61 76 6f 69 64 20 61 6c  able to avoid al
3090: 6c 6f 63 61 74 69 6e 67 20 61 20 6e 65 77 20 70  locating a new p
30a0: 61 67 65 20 63 61 63 68 65 0a 2a 2a 20 65 6e 74  age cache.** ent
30b0: 72 79 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 6d 65 6d  ry..**.** If mem
30c0: 6f 72 79 20 77 61 73 20 61 6c 6c 6f 63 61 74 65  ory was allocate
30d0: 64 20 73 70 65 63 69 66 69 63 61 6c 6c 79 20 74  d specifically t
30e0: 6f 20 74 68 65 20 70 61 67 65 20 63 61 63 68 65  o the page cache
30f0: 20 75 73 69 6e 67 0a 2a 2a 20 53 51 4c 49 54 45   using.** SQLITE
3100: 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48  _CONFIG_PAGECACH
3110: 45 20 62 75 74 20 74 68 61 74 20 6d 65 6d 6f 72  E but that memor
3120: 79 20 68 61 73 20 61 6c 6c 20 62 65 65 6e 20 75  y has all been u
3130: 73 65 64 2c 20 74 68 65 6e 0a 2a 2a 20 69 74 20  sed, then.** it 
3140: 69 73 20 64 65 73 69 72 61 62 6c 65 20 74 6f 20  is desirable to 
3150: 61 76 6f 69 64 20 61 6c 6c 6f 63 61 74 69 6e 67  avoid allocating
3160: 20 61 20 6e 65 77 20 70 61 67 65 20 63 61 63 68   a new page cach
3170: 65 20 65 6e 74 72 79 20 62 65 63 61 75 73 65 0a  e entry because.
3180: 2a 2a 20 70 72 65 73 75 6d 61 62 6c 79 20 53 51  ** presumably SQ
3190: 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47 45  LITE_CONFIG_PAGE
31a0: 43 41 43 48 45 20 77 61 73 20 73 75 70 70 6f 73  CACHE was suppos
31b0: 65 20 74 6f 20 62 65 20 73 75 66 66 69 63 69 65  e to be sufficie
31c0: 6e 74 0a 2a 2a 20 66 6f 72 20 61 6c 6c 20 70 61  nt.** for all pa
31d0: 67 65 20 63 61 63 68 65 20 6e 65 65 64 73 20 61  ge cache needs a
31e0: 6e 64 20 77 65 20 73 68 6f 75 6c 64 20 6e 6f 74  nd we should not
31f0: 20 6e 65 65 64 20 74 6f 20 73 70 69 6c 6c 20 74   need to spill t
3200: 68 65 0a 2a 2a 20 61 6c 6c 6f 63 61 74 69 6f 6e  he.** allocation
3210: 20 6f 6e 74 6f 20 74 68 65 20 68 65 61 70 2e 0a   onto the heap..
3220: 2a 2a 0a 2a 2a 20 4f 72 2c 20 74 68 65 20 68 65  **.** Or, the he
3230: 61 70 20 69 73 20 75 73 65 64 20 66 6f 72 20 61  ap is used for a
3240: 6c 6c 20 70 61 67 65 20 63 61 63 68 65 20 6d 65  ll page cache me
3250: 6d 6f 72 79 20 70 75 74 20 74 68 65 20 68 65 61  mory put the hea
3260: 70 20 69 73 0a 2a 2a 20 75 6e 64 65 72 20 6d 65  p is.** under me
3270: 6d 6f 72 79 20 70 72 65 73 73 75 72 65 2c 20 74  mory pressure, t
3280: 68 65 6e 20 61 67 61 69 6e 20 69 74 20 69 73 20  hen again it is 
3290: 64 65 73 69 72 61 62 6c 65 20 74 6f 20 61 76 6f  desirable to avo
32a0: 69 64 0a 2a 2a 20 61 6c 6c 6f 63 61 74 69 6e 67  id.** allocating
32b0: 20 61 20 6e 65 77 20 70 61 67 65 20 63 61 63 68   a new page cach
32c0: 65 20 65 6e 74 72 79 20 69 6e 20 6f 72 64 65 72  e entry in order
32d0: 20 74 6f 20 61 76 6f 69 64 20 73 74 72 65 73 73   to avoid stress
32e0: 69 6e 67 0a 2a 2a 20 74 68 65 20 68 65 61 70 20  ing.** the heap 
32f0: 65 76 65 6e 20 66 75 72 74 68 65 72 2e 0a 2a 2f  even further..*/
3300: 0a 73 74 61 74 69 63 20 69 6e 74 20 70 63 61 63  .static int pcac
3310: 68 65 31 55 6e 64 65 72 4d 65 6d 6f 72 79 50 72  he1UnderMemoryPr
3320: 65 73 73 75 72 65 28 50 43 61 63 68 65 31 20 2a  essure(PCache1 *
3330: 70 43 61 63 68 65 29 7b 0a 20 20 69 66 28 20 70  pCache){.  if( p
3340: 63 61 63 68 65 31 2e 6e 53 6c 6f 74 20 26 26 20  cache1.nSlot && 
3350: 28 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 2b  (pCache->szPage+
3360: 70 43 61 63 68 65 2d 3e 73 7a 45 78 74 72 61 29  pCache->szExtra)
3370: 3c 3d 70 63 61 63 68 65 31 2e 73 7a 53 6c 6f 74  <=pcache1.szSlot
3380: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 70   ){.    return p
3390: 63 61 63 68 65 31 2e 62 55 6e 64 65 72 50 72 65  cache1.bUnderPre
33a0: 73 73 75 72 65 3b 0a 20 20 7d 65 6c 73 65 7b 0a  ssure;.  }else{.
33b0: 20 20 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74      return sqlit
33c0: 65 33 48 65 61 70 4e 65 61 72 6c 79 46 75 6c 6c  e3HeapNearlyFull
33d0: 28 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 2a 2a 2a  ();.  }.}../****
33e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
33f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3400: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3410: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3420: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 2a 2a  **********/./***
3430: 2a 2a 2a 2a 2a 20 47 65 6e 65 72 61 6c 20 49 6d  ***** General Im
3440: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 46 75 6e  plementation Fun
3450: 63 74 69 6f 6e 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a  ctions *********
3460: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3470: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f 2a  ***********/../*
3480: 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
3490: 6e 20 69 73 20 75 73 65 64 20 74 6f 20 72 65 73  n is used to res
34a0: 69 7a 65 20 74 68 65 20 68 61 73 68 20 74 61 62  ize the hash tab
34b0: 6c 65 20 75 73 65 64 20 62 79 20 74 68 65 20 63  le used by the c
34c0: 61 63 68 65 20 70 61 73 73 65 64 0a 2a 2a 20 61  ache passed.** a
34d0: 73 20 74 68 65 20 66 69 72 73 74 20 61 72 67 75  s the first argu
34e0: 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  ment..**.** The 
34f0: 50 43 61 63 68 65 20 6d 75 74 65 78 20 6d 75 73  PCache mutex mus
3500: 74 20 62 65 20 68 65 6c 64 20 77 68 65 6e 20 74  t be held when t
3510: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
3520: 63 61 6c 6c 65 64 2e 0a 2a 2f 0a 73 74 61 74 69  called..*/.stati
3530: 63 20 69 6e 74 20 70 63 61 63 68 65 31 52 65 73  c int pcache1Res
3540: 69 7a 65 48 61 73 68 28 50 43 61 63 68 65 31 20  izeHash(PCache1 
3550: 2a 70 29 7b 0a 20 20 50 67 48 64 72 31 20 2a 2a  *p){.  PgHdr1 **
3560: 61 70 4e 65 77 3b 0a 20 20 75 6e 73 69 67 6e 65  apNew;.  unsigne
3570: 64 20 69 6e 74 20 6e 4e 65 77 3b 0a 20 20 75 6e  d int nNew;.  un
3580: 73 69 67 6e 65 64 20 69 6e 74 20 69 3b 0a 0a 20  signed int i;.. 
3590: 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33   assert( sqlite3
35a0: 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 2d 3e 70  _mutex_held(p->p
35b0: 47 72 6f 75 70 2d 3e 6d 75 74 65 78 29 20 29 3b  Group->mutex) );
35c0: 0a 0a 20 20 6e 4e 65 77 20 3d 20 70 2d 3e 6e 48  ..  nNew = p->nH
35d0: 61 73 68 2a 32 3b 0a 20 20 69 66 28 20 6e 4e 65  ash*2;.  if( nNe
35e0: 77 3c 32 35 36 20 29 7b 0a 20 20 20 20 6e 4e 65  w<256 ){.    nNe
35f0: 77 20 3d 20 32 35 36 3b 0a 20 20 7d 0a 0a 20 20  w = 256;.  }..  
3600: 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65  pcache1LeaveMute
3610: 78 28 70 2d 3e 70 47 72 6f 75 70 29 3b 0a 20 20  x(p->pGroup);.  
3620: 69 66 28 20 70 2d 3e 6e 48 61 73 68 20 29 7b 20  if( p->nHash ){ 
3630: 73 71 6c 69 74 65 33 42 65 67 69 6e 42 65 6e 69  sqlite3BeginBeni
3640: 67 6e 4d 61 6c 6c 6f 63 28 29 3b 20 7d 0a 20 20  gnMalloc(); }.  
3650: 61 70 4e 65 77 20 3d 20 28 50 67 48 64 72 31 20  apNew = (PgHdr1 
3660: 2a 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f  **)sqlite3_mallo
3670: 63 28 73 69 7a 65 6f 66 28 50 67 48 64 72 31 20  c(sizeof(PgHdr1 
3680: 2a 29 2a 6e 4e 65 77 29 3b 0a 20 20 69 66 28 20  *)*nNew);.  if( 
3690: 70 2d 3e 6e 48 61 73 68 20 29 7b 20 73 71 6c 69  p->nHash ){ sqli
36a0: 74 65 33 45 6e 64 42 65 6e 69 67 6e 4d 61 6c 6c  te3EndBenignMall
36b0: 6f 63 28 29 3b 20 7d 0a 20 20 70 63 61 63 68 65  oc(); }.  pcache
36c0: 31 45 6e 74 65 72 4d 75 74 65 78 28 70 2d 3e 70  1EnterMutex(p->p
36d0: 47 72 6f 75 70 29 3b 0a 20 20 69 66 28 20 61 70  Group);.  if( ap
36e0: 4e 65 77 20 29 7b 0a 20 20 20 20 6d 65 6d 73 65  New ){.    memse
36f0: 74 28 61 70 4e 65 77 2c 20 30 2c 20 73 69 7a 65  t(apNew, 0, size
3700: 6f 66 28 50 67 48 64 72 31 20 2a 29 2a 6e 4e 65  of(PgHdr1 *)*nNe
3710: 77 29 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b  w);.    for(i=0;
3720: 20 69 3c 70 2d 3e 6e 48 61 73 68 3b 20 69 2b 2b   i<p->nHash; i++
3730: 29 7b 0a 20 20 20 20 20 20 50 67 48 64 72 31 20  ){.      PgHdr1 
3740: 2a 70 50 61 67 65 3b 0a 20 20 20 20 20 20 50 67  *pPage;.      Pg
3750: 48 64 72 31 20 2a 70 4e 65 78 74 20 3d 20 70 2d  Hdr1 *pNext = p-
3760: 3e 61 70 48 61 73 68 5b 69 5d 3b 0a 20 20 20 20  >apHash[i];.    
3770: 20 20 77 68 69 6c 65 28 20 28 70 50 61 67 65 20    while( (pPage 
3780: 3d 20 70 4e 65 78 74 29 21 3d 30 20 29 7b 0a 20  = pNext)!=0 ){. 
3790: 20 20 20 20 20 20 20 75 6e 73 69 67 6e 65 64 20         unsigned 
37a0: 69 6e 74 20 68 20 3d 20 70 50 61 67 65 2d 3e 69  int h = pPage->i
37b0: 4b 65 79 20 25 20 6e 4e 65 77 3b 0a 20 20 20 20  Key % nNew;.    
37c0: 20 20 20 20 70 4e 65 78 74 20 3d 20 70 50 61 67      pNext = pPag
37d0: 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20  e->pNext;.      
37e0: 20 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 20 3d    pPage->pNext =
37f0: 20 61 70 4e 65 77 5b 68 5d 3b 0a 20 20 20 20 20   apNew[h];.     
3800: 20 20 20 61 70 4e 65 77 5b 68 5d 20 3d 20 70 50     apNew[h] = pP
3810: 61 67 65 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  age;.      }.   
3820: 20 7d 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66   }.    sqlite3_f
3830: 72 65 65 28 70 2d 3e 61 70 48 61 73 68 29 3b 0a  ree(p->apHash);.
3840: 20 20 20 20 70 2d 3e 61 70 48 61 73 68 20 3d 20      p->apHash = 
3850: 61 70 4e 65 77 3b 0a 20 20 20 20 70 2d 3e 6e 48  apNew;.    p->nH
3860: 61 73 68 20 3d 20 6e 4e 65 77 3b 0a 20 20 7d 0a  ash = nNew;.  }.
3870: 0a 20 20 72 65 74 75 72 6e 20 28 70 2d 3e 61 70  .  return (p->ap
3880: 48 61 73 68 20 3f 20 53 51 4c 49 54 45 5f 4f 4b  Hash ? SQLITE_OK
3890: 20 3a 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 29   : SQLITE_NOMEM)
38a0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  ;.}../*.** This 
38b0: 66 75 6e 63 74 69 6f 6e 20 69 73 20 75 73 65 64  function is used
38c0: 20 69 6e 74 65 72 6e 61 6c 6c 79 20 74 6f 20 72   internally to r
38d0: 65 6d 6f 76 65 20 74 68 65 20 70 61 67 65 20 70  emove the page p
38e0: 50 61 67 65 20 66 72 6f 6d 20 74 68 65 20 0a 2a  Page from the .*
38f0: 2a 20 50 47 72 6f 75 70 20 4c 52 55 20 6c 69 73  * PGroup LRU lis
3900: 74 2c 20 69 66 20 69 73 20 70 61 72 74 20 6f 66  t, if is part of
3910: 20 69 74 2e 20 49 66 20 70 50 61 67 65 20 69 73   it. If pPage is
3920: 20 6e 6f 74 20 70 61 72 74 20 6f 66 20 74 68 65   not part of the
3930: 20 50 47 72 6f 75 70 0a 2a 2a 20 4c 52 55 20 6c   PGroup.** LRU l
3940: 69 73 74 2c 20 74 68 65 6e 20 74 68 69 73 20 66  ist, then this f
3950: 75 6e 63 74 69 6f 6e 20 69 73 20 61 20 6e 6f 2d  unction is a no-
3960: 6f 70 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 50 47  op..**.** The PG
3970: 72 6f 75 70 20 6d 75 74 65 78 20 6d 75 73 74 20  roup mutex must 
3980: 62 65 20 68 65 6c 64 20 77 68 65 6e 20 74 68 69  be held when thi
3990: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61  s function is ca
39a0: 6c 6c 65 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 70  lled..**.** If p
39b0: 50 61 67 65 20 69 73 20 4e 55 4c 4c 20 74 68 65  Page is NULL the
39c0: 6e 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 69  n this routine i
39d0: 73 20 61 20 6e 6f 2d 6f 70 2e 0a 2a 2f 0a 73 74  s a no-op..*/.st
39e0: 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65  atic void pcache
39f0: 31 50 69 6e 50 61 67 65 28 50 67 48 64 72 31 20  1PinPage(PgHdr1 
3a00: 2a 70 50 61 67 65 29 7b 0a 20 20 50 43 61 63 68  *pPage){.  PCach
3a10: 65 31 20 2a 70 43 61 63 68 65 3b 0a 20 20 50 47  e1 *pCache;.  PG
3a20: 72 6f 75 70 20 2a 70 47 72 6f 75 70 3b 0a 0a 20  roup *pGroup;.. 
3a30: 20 69 66 28 20 70 50 61 67 65 3d 3d 30 20 29 20   if( pPage==0 ) 
3a40: 72 65 74 75 72 6e 3b 0a 20 20 70 43 61 63 68 65  return;.  pCache
3a50: 20 3d 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65   = pPage->pCache
3a60: 3b 0a 20 20 70 47 72 6f 75 70 20 3d 20 70 43 61  ;.  pGroup = pCa
3a70: 63 68 65 2d 3e 70 47 72 6f 75 70 3b 0a 20 20 61  che->pGroup;.  a
3a80: 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d  ssert( sqlite3_m
3a90: 75 74 65 78 5f 68 65 6c 64 28 70 47 72 6f 75 70  utex_held(pGroup
3aa0: 2d 3e 6d 75 74 65 78 29 20 29 3b 0a 20 20 69 66  ->mutex) );.  if
3ab0: 28 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78  ( pPage->pLruNex
3ac0: 74 20 7c 7c 20 70 50 61 67 65 3d 3d 70 47 72 6f  t || pPage==pGro
3ad0: 75 70 2d 3e 70 4c 72 75 54 61 69 6c 20 29 7b 0a  up->pLruTail ){.
3ae0: 20 20 20 20 69 66 28 20 70 50 61 67 65 2d 3e 70      if( pPage->p
3af0: 4c 72 75 50 72 65 76 20 29 7b 0a 20 20 20 20 20  LruPrev ){.     
3b00: 20 70 50 61 67 65 2d 3e 70 4c 72 75 50 72 65 76   pPage->pLruPrev
3b10: 2d 3e 70 4c 72 75 4e 65 78 74 20 3d 20 70 50 61  ->pLruNext = pPa
3b20: 67 65 2d 3e 70 4c 72 75 4e 65 78 74 3b 0a 20 20  ge->pLruNext;.  
3b30: 20 20 7d 0a 20 20 20 20 69 66 28 20 70 50 61 67    }.    if( pPag
3b40: 65 2d 3e 70 4c 72 75 4e 65 78 74 20 29 7b 0a 20  e->pLruNext ){. 
3b50: 20 20 20 20 20 70 50 61 67 65 2d 3e 70 4c 72 75       pPage->pLru
3b60: 4e 65 78 74 2d 3e 70 4c 72 75 50 72 65 76 20 3d  Next->pLruPrev =
3b70: 20 70 50 61 67 65 2d 3e 70 4c 72 75 50 72 65 76   pPage->pLruPrev
3b80: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20  ;.    }.    if( 
3b90: 70 47 72 6f 75 70 2d 3e 70 4c 72 75 48 65 61 64  pGroup->pLruHead
3ba0: 3d 3d 70 50 61 67 65 20 29 7b 0a 20 20 20 20 20  ==pPage ){.     
3bb0: 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 48 65 61   pGroup->pLruHea
3bc0: 64 20 3d 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e  d = pPage->pLruN
3bd0: 65 78 74 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69  ext;.    }.    i
3be0: 66 28 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 54  f( pGroup->pLruT
3bf0: 61 69 6c 3d 3d 70 50 61 67 65 20 29 7b 0a 20 20  ail==pPage ){.  
3c00: 20 20 20 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75      pGroup->pLru
3c10: 54 61 69 6c 20 3d 20 70 50 61 67 65 2d 3e 70 4c  Tail = pPage->pL
3c20: 72 75 50 72 65 76 3b 0a 20 20 20 20 7d 0a 20 20  ruPrev;.    }.  
3c30: 20 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78    pPage->pLruNex
3c40: 74 20 3d 20 30 3b 0a 20 20 20 20 70 50 61 67 65  t = 0;.    pPage
3c50: 2d 3e 70 4c 72 75 50 72 65 76 20 3d 20 30 3b 0a  ->pLruPrev = 0;.
3c60: 20 20 20 20 70 50 61 67 65 2d 3e 70 43 61 63 68      pPage->pCach
3c70: 65 2d 3e 6e 52 65 63 79 63 6c 61 62 6c 65 2d 2d  e->nRecyclable--
3c80: 3b 0a 20 20 7d 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20  ;.  }.}.../*.** 
3c90: 52 65 6d 6f 76 65 20 74 68 65 20 70 61 67 65 20  Remove the page 
3ca0: 73 75 70 70 6c 69 65 64 20 61 73 20 61 6e 20 61  supplied as an a
3cb0: 72 67 75 6d 65 6e 74 20 66 72 6f 6d 20 74 68 65  rgument from the
3cc0: 20 68 61 73 68 20 74 61 62 6c 65 20 0a 2a 2a 20   hash table .** 
3cd0: 28 50 43 61 63 68 65 31 2e 61 70 48 61 73 68 20  (PCache1.apHash 
3ce0: 73 74 72 75 63 74 75 72 65 29 20 74 68 61 74 20  structure) that 
3cf0: 69 74 20 69 73 20 63 75 72 72 65 6e 74 6c 79 20  it is currently 
3d00: 73 74 6f 72 65 64 20 69 6e 2e 0a 2a 2a 0a 2a 2a  stored in..**.**
3d10: 20 54 68 65 20 50 47 72 6f 75 70 20 6d 75 74 65   The PGroup mute
3d20: 78 20 6d 75 73 74 20 62 65 20 68 65 6c 64 20 77  x must be held w
3d30: 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f  hen this functio
3d40: 6e 20 69 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f 0a  n is called..*/.
3d50: 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63  static void pcac
3d60: 68 65 31 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73  he1RemoveFromHas
3d70: 68 28 50 67 48 64 72 31 20 2a 70 50 61 67 65 29  h(PgHdr1 *pPage)
3d80: 7b 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74  {.  unsigned int
3d90: 20 68 3b 0a 20 20 50 43 61 63 68 65 31 20 2a 70   h;.  PCache1 *p
3da0: 43 61 63 68 65 20 3d 20 70 50 61 67 65 2d 3e 70  Cache = pPage->p
3db0: 43 61 63 68 65 3b 0a 20 20 50 67 48 64 72 31 20  Cache;.  PgHdr1 
3dc0: 2a 2a 70 70 3b 0a 0a 20 20 61 73 73 65 72 74 28  **pp;..  assert(
3dd0: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68   sqlite3_mutex_h
3de0: 65 6c 64 28 70 43 61 63 68 65 2d 3e 70 47 72 6f  eld(pCache->pGro
3df0: 75 70 2d 3e 6d 75 74 65 78 29 20 29 3b 0a 20 20  up->mutex) );.  
3e00: 68 20 3d 20 70 50 61 67 65 2d 3e 69 4b 65 79 20  h = pPage->iKey 
3e10: 25 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3b  % pCache->nHash;
3e20: 0a 20 20 66 6f 72 28 70 70 3d 26 70 43 61 63 68  .  for(pp=&pCach
3e30: 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 20 28 2a  e->apHash[h]; (*
3e40: 70 70 29 21 3d 70 50 61 67 65 3b 20 70 70 3d 26  pp)!=pPage; pp=&
3e50: 28 2a 70 70 29 2d 3e 70 4e 65 78 74 29 3b 0a 20  (*pp)->pNext);. 
3e60: 20 2a 70 70 20 3d 20 28 2a 70 70 29 2d 3e 70 4e   *pp = (*pp)->pN
3e70: 65 78 74 3b 0a 0a 20 20 70 43 61 63 68 65 2d 3e  ext;..  pCache->
3e80: 6e 50 61 67 65 2d 2d 3b 0a 7d 0a 0a 2f 2a 0a 2a  nPage--;.}../*.*
3e90: 2a 20 49 66 20 74 68 65 72 65 20 61 72 65 20 63  * If there are c
3ea0: 75 72 72 65 6e 74 6c 79 20 6d 6f 72 65 20 74 68  urrently more th
3eb0: 61 6e 20 6e 4d 61 78 50 61 67 65 20 70 61 67 65  an nMaxPage page
3ec0: 73 20 61 6c 6c 6f 63 61 74 65 64 2c 20 74 72 79  s allocated, try
3ed0: 0a 2a 2a 20 74 6f 20 72 65 63 79 63 6c 65 20 70  .** to recycle p
3ee0: 61 67 65 73 20 74 6f 20 72 65 64 75 63 65 20 74  ages to reduce t
3ef0: 68 65 20 6e 75 6d 62 65 72 20 61 6c 6c 6f 63 61  he number alloca
3f00: 74 65 64 20 74 6f 20 6e 4d 61 78 50 61 67 65 2e  ted to nMaxPage.
3f10: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
3f20: 70 63 61 63 68 65 31 45 6e 66 6f 72 63 65 4d 61  pcache1EnforceMa
3f30: 78 50 61 67 65 28 50 47 72 6f 75 70 20 2a 70 47  xPage(PGroup *pG
3f40: 72 6f 75 70 29 7b 0a 20 20 61 73 73 65 72 74 28  roup){.  assert(
3f50: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68   sqlite3_mutex_h
3f60: 65 6c 64 28 70 47 72 6f 75 70 2d 3e 6d 75 74 65  eld(pGroup->mute
3f70: 78 29 20 29 3b 0a 20 20 77 68 69 6c 65 28 20 70  x) );.  while( p
3f80: 47 72 6f 75 70 2d 3e 6e 43 75 72 72 65 6e 74 50  Group->nCurrentP
3f90: 61 67 65 3e 70 47 72 6f 75 70 2d 3e 6e 4d 61 78  age>pGroup->nMax
3fa0: 50 61 67 65 20 26 26 20 70 47 72 6f 75 70 2d 3e  Page && pGroup->
3fb0: 70 4c 72 75 54 61 69 6c 20 29 7b 0a 20 20 20 20  pLruTail ){.    
3fc0: 50 67 48 64 72 31 20 2a 70 20 3d 20 70 47 72 6f  PgHdr1 *p = pGro
3fd0: 75 70 2d 3e 70 4c 72 75 54 61 69 6c 3b 0a 20 20  up->pLruTail;.  
3fe0: 20 20 61 73 73 65 72 74 28 20 70 2d 3e 70 43 61    assert( p->pCa
3ff0: 63 68 65 2d 3e 70 47 72 6f 75 70 3d 3d 70 47 72  che->pGroup==pGr
4000: 6f 75 70 20 29 3b 0a 20 20 20 20 70 63 61 63 68  oup );.    pcach
4010: 65 31 50 69 6e 50 61 67 65 28 70 29 3b 0a 20 20  e1PinPage(p);.  
4020: 20 20 70 63 61 63 68 65 31 52 65 6d 6f 76 65 46    pcache1RemoveF
4030: 72 6f 6d 48 61 73 68 28 70 29 3b 0a 20 20 20 20  romHash(p);.    
4040: 70 63 61 63 68 65 31 46 72 65 65 50 61 67 65 28  pcache1FreePage(
4050: 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a  p);.  }.}../*.**
4060: 20 44 69 73 63 61 72 64 20 61 6c 6c 20 70 61 67   Discard all pag
4070: 65 73 20 66 72 6f 6d 20 63 61 63 68 65 20 70 43  es from cache pC
4080: 61 63 68 65 20 77 69 74 68 20 61 20 70 61 67 65  ache with a page
4090: 20 6e 75 6d 62 65 72 20 28 6b 65 79 20 76 61 6c   number (key val
40a0: 75 65 29 20 0a 2a 2a 20 67 72 65 61 74 65 72 20  ue) .** greater 
40b0: 74 68 61 6e 20 6f 72 20 65 71 75 61 6c 20 74 6f  than or equal to
40c0: 20 69 4c 69 6d 69 74 2e 20 41 6e 79 20 70 69 6e   iLimit. Any pin
40d0: 6e 65 64 20 70 61 67 65 73 20 74 68 61 74 20 6d  ned pages that m
40e0: 65 65 74 20 74 68 69 73 20 0a 2a 2a 20 63 72 69  eet this .** cri
40f0: 74 65 72 69 61 20 61 72 65 20 75 6e 70 69 6e 6e  teria are unpinn
4100: 65 64 20 62 65 66 6f 72 65 20 74 68 65 79 20 61  ed before they a
4110: 72 65 20 64 69 73 63 61 72 64 65 64 2e 0a 2a 2a  re discarded..**
4120: 0a 2a 2a 20 54 68 65 20 50 43 61 63 68 65 20 6d  .** The PCache m
4130: 75 74 65 78 20 6d 75 73 74 20 62 65 20 68 65 6c  utex must be hel
4140: 64 20 77 68 65 6e 20 74 68 69 73 20 66 75 6e 63  d when this func
4150: 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 2e 0a  tion is called..
4160: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70  */.static void p
4170: 63 61 63 68 65 31 54 72 75 6e 63 61 74 65 55 6e  cache1TruncateUn
4180: 73 61 66 65 28 0a 20 20 50 43 61 63 68 65 31 20  safe(.  PCache1 
4190: 2a 70 43 61 63 68 65 2c 20 20 20 20 20 20 20 20  *pCache,        
41a0: 20 20 20 20 20 2f 2a 20 54 68 65 20 63 61 63 68       /* The cach
41b0: 65 20 74 6f 20 74 72 75 6e 63 61 74 65 20 2a 2f  e to truncate */
41c0: 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  .  unsigned int 
41d0: 69 4c 69 6d 69 74 20 20 20 20 20 20 20 20 20 20  iLimit          
41e0: 2f 2a 20 44 72 6f 70 20 70 61 67 65 73 20 77 69  /* Drop pages wi
41f0: 74 68 20 74 68 69 73 20 70 67 6e 6f 20 6f 72 20  th this pgno or 
4200: 6c 61 72 67 65 72 20 2a 2f 0a 29 7b 0a 20 20 54  larger */.){.  T
4210: 45 53 54 4f 4e 4c 59 28 20 75 6e 73 69 67 6e 65  ESTONLY( unsigne
4220: 64 20 69 6e 74 20 6e 50 61 67 65 20 3d 20 30 3b  d int nPage = 0;
4230: 20 29 20 20 2f 2a 20 54 6f 20 61 73 73 65 72 74   )  /* To assert
4240: 20 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 20 69   pCache->nPage i
4250: 73 20 63 6f 72 72 65 63 74 20 2a 2f 0a 20 20 75  s correct */.  u
4260: 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 3b 0a 20  nsigned int h;. 
4270: 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33   assert( sqlite3
4280: 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 43 61 63  _mutex_held(pCac
4290: 68 65 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75 74 65  he->pGroup->mute
42a0: 78 29 20 29 3b 0a 20 20 66 6f 72 28 68 3d 30 3b  x) );.  for(h=0;
42b0: 20 68 3c 70 43 61 63 68 65 2d 3e 6e 48 61 73 68   h<pCache->nHash
42c0: 3b 20 68 2b 2b 29 7b 0a 20 20 20 20 50 67 48 64  ; h++){.    PgHd
42d0: 72 31 20 2a 2a 70 70 20 3d 20 26 70 43 61 63 68  r1 **pp = &pCach
42e0: 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 20 0a 20  e->apHash[h]; . 
42f0: 20 20 20 50 67 48 64 72 31 20 2a 70 50 61 67 65     PgHdr1 *pPage
4300: 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 28 70 50  ;.    while( (pP
4310: 61 67 65 20 3d 20 2a 70 70 29 21 3d 30 20 29 7b  age = *pp)!=0 ){
4320: 0a 20 20 20 20 20 20 69 66 28 20 70 50 61 67 65  .      if( pPage
4330: 2d 3e 69 4b 65 79 3e 3d 69 4c 69 6d 69 74 20 29  ->iKey>=iLimit )
4340: 7b 0a 20 20 20 20 20 20 20 20 70 43 61 63 68 65  {.        pCache
4350: 2d 3e 6e 50 61 67 65 2d 2d 3b 0a 20 20 20 20 20  ->nPage--;.     
4360: 20 20 20 2a 70 70 20 3d 20 70 50 61 67 65 2d 3e     *pp = pPage->
4370: 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 20 20 70  pNext;.        p
4380: 63 61 63 68 65 31 50 69 6e 50 61 67 65 28 70 50  cache1PinPage(pP
4390: 61 67 65 29 3b 0a 20 20 20 20 20 20 20 20 70 63  age);.        pc
43a0: 61 63 68 65 31 46 72 65 65 50 61 67 65 28 70 50  ache1FreePage(pP
43b0: 61 67 65 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73  age);.      }els
43c0: 65 7b 0a 20 20 20 20 20 20 20 20 70 70 20 3d 20  e{.        pp = 
43d0: 26 70 50 61 67 65 2d 3e 70 4e 65 78 74 3b 0a 20  &pPage->pNext;. 
43e0: 20 20 20 20 20 20 20 54 45 53 54 4f 4e 4c 59 28         TESTONLY(
43f0: 20 6e 50 61 67 65 2b 2b 3b 20 29 0a 20 20 20 20   nPage++; ).    
4400: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20    }.    }.  }.  
4410: 61 73 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e  assert( pCache->
4420: 6e 50 61 67 65 3d 3d 6e 50 61 67 65 20 29 3b 0a  nPage==nPage );.
4430: 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  }../************
4440: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4450: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4460: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4470: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4480: 2a 2a 2f 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 20 73 71  **/./******** sq
4490: 6c 69 74 65 33 5f 70 63 61 63 68 65 20 4d 65 74  lite3_pcache Met
44a0: 68 6f 64 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  hods ***********
44b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
44c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
44d0: 2a 2a 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c  ***/../*.** Impl
44e0: 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68  ementation of th
44f0: 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  e sqlite3_pcache
4500: 2e 78 49 6e 69 74 20 6d 65 74 68 6f 64 2e 0a 2a  .xInit method..*
4510: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 70 63 61  /.static int pca
4520: 63 68 65 31 49 6e 69 74 28 76 6f 69 64 20 2a 4e  che1Init(void *N
4530: 6f 74 55 73 65 64 29 7b 0a 20 20 55 4e 55 53 45  otUsed){.  UNUSE
4540: 44 5f 50 41 52 41 4d 45 54 45 52 28 4e 6f 74 55  D_PARAMETER(NotU
4550: 73 65 64 29 3b 0a 20 20 61 73 73 65 72 74 28 20  sed);.  assert( 
4560: 70 63 61 63 68 65 31 2e 69 73 49 6e 69 74 3d 3d  pcache1.isInit==
4570: 30 20 29 3b 0a 20 20 6d 65 6d 73 65 74 28 26 70  0 );.  memset(&p
4580: 63 61 63 68 65 31 2c 20 30 2c 20 73 69 7a 65 6f  cache1, 0, sizeo
4590: 66 28 70 63 61 63 68 65 31 29 29 3b 0a 20 20 69  f(pcache1));.  i
45a0: 66 28 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c  f( sqlite3Global
45b0: 43 6f 6e 66 69 67 2e 62 43 6f 72 65 4d 75 74 65  Config.bCoreMute
45c0: 78 20 29 7b 0a 20 20 20 20 70 63 61 63 68 65 31  x ){.    pcache1
45d0: 2e 67 72 70 2e 6d 75 74 65 78 20 3d 20 73 71 6c  .grp.mutex = sql
45e0: 69 74 65 33 5f 6d 75 74 65 78 5f 61 6c 6c 6f 63  ite3_mutex_alloc
45f0: 28 53 51 4c 49 54 45 5f 4d 55 54 45 58 5f 53 54  (SQLITE_MUTEX_ST
4600: 41 54 49 43 5f 4c 52 55 29 3b 0a 20 20 20 20 70  ATIC_LRU);.    p
4610: 63 61 63 68 65 31 2e 6d 75 74 65 78 20 3d 20 73  cache1.mutex = s
4620: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 61 6c 6c  qlite3_mutex_all
4630: 6f 63 28 53 51 4c 49 54 45 5f 4d 55 54 45 58 5f  oc(SQLITE_MUTEX_
4640: 53 54 41 54 49 43 5f 50 4d 45 4d 29 3b 0a 20 20  STATIC_PMEM);.  
4650: 7d 0a 20 20 70 63 61 63 68 65 31 2e 67 72 70 2e  }.  pcache1.grp.
4660: 6d 78 50 69 6e 6e 65 64 20 3d 20 31 30 3b 0a 20  mxPinned = 10;. 
4670: 20 70 63 61 63 68 65 31 2e 69 73 49 6e 69 74 20   pcache1.isInit 
4680: 3d 20 31 3b 0a 20 20 72 65 74 75 72 6e 20 53 51  = 1;.  return SQ
4690: 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a  LITE_OK;.}../*.*
46a0: 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  * Implementation
46b0: 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f   of the sqlite3_
46c0: 70 63 61 63 68 65 2e 78 53 68 75 74 64 6f 77 6e  pcache.xShutdown
46d0: 20 6d 65 74 68 6f 64 2e 0a 2a 2a 20 4e 6f 74 65   method..** Note
46e0: 20 74 68 61 74 20 74 68 65 20 73 74 61 74 69 63   that the static
46f0: 20 6d 75 74 65 78 20 61 6c 6c 6f 63 61 74 65 64   mutex allocated
4700: 20 69 6e 20 78 49 6e 69 74 20 64 6f 65 73 20 0a   in xInit does .
4710: 2a 2a 20 6e 6f 74 20 6e 65 65 64 20 74 6f 20 62  ** not need to b
4720: 65 20 66 72 65 65 64 2e 0a 2a 2f 0a 73 74 61 74  e freed..*/.stat
4730: 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 31 53  ic void pcache1S
4740: 68 75 74 64 6f 77 6e 28 76 6f 69 64 20 2a 4e 6f  hutdown(void *No
4750: 74 55 73 65 64 29 7b 0a 20 20 55 4e 55 53 45 44  tUsed){.  UNUSED
4760: 5f 50 41 52 41 4d 45 54 45 52 28 4e 6f 74 55 73  _PARAMETER(NotUs
4770: 65 64 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70  ed);.  assert( p
4780: 63 61 63 68 65 31 2e 69 73 49 6e 69 74 21 3d 30  cache1.isInit!=0
4790: 20 29 3b 0a 20 20 6d 65 6d 73 65 74 28 26 70 63   );.  memset(&pc
47a0: 61 63 68 65 31 2c 20 30 2c 20 73 69 7a 65 6f 66  ache1, 0, sizeof
47b0: 28 70 63 61 63 68 65 31 29 29 3b 0a 7d 0a 0a 2f  (pcache1));.}../
47c0: 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74  *.** Implementat
47d0: 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74  ion of the sqlit
47e0: 65 33 5f 70 63 61 63 68 65 2e 78 43 72 65 61 74  e3_pcache.xCreat
47f0: 65 20 6d 65 74 68 6f 64 2e 0a 2a 2a 0a 2a 2a 20  e method..**.** 
4800: 41 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 63  Allocate a new c
4810: 61 63 68 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ache..*/.static 
4820: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a  sqlite3_pcache *
4830: 70 63 61 63 68 65 31 43 72 65 61 74 65 28 69 6e  pcache1Create(in
4840: 74 20 73 7a 45 78 74 72 61 2c 20 69 6e 74 20 73  t szExtra, int s
4850: 7a 50 61 67 65 2c 20 69 6e 74 20 62 50 75 72 67  zPage, int bPurg
4860: 65 61 62 6c 65 29 7b 0a 20 20 50 43 61 63 68 65  eable){.  PCache
4870: 31 20 2a 70 43 61 63 68 65 3b 20 20 20 20 20 20  1 *pCache;      
4880: 2f 2a 20 54 68 65 20 6e 65 77 6c 79 20 63 72 65  /* The newly cre
4890: 61 74 65 64 20 70 61 67 65 20 63 61 63 68 65 20  ated page cache 
48a0: 2a 2f 0a 20 20 50 47 72 6f 75 70 20 2a 70 47 72  */.  PGroup *pGr
48b0: 6f 75 70 3b 20 20 20 20 20 20 20 2f 2a 20 54 68  oup;       /* Th
48c0: 65 20 67 72 6f 75 70 20 74 68 65 20 6e 65 77 20  e group the new 
48d0: 70 61 67 65 20 63 61 63 68 65 20 77 69 6c 6c 20  page cache will 
48e0: 62 65 6c 6f 6e 67 20 74 6f 20 2a 2f 0a 20 20 69  belong to */.  i
48f0: 6e 74 20 73 7a 3b 20 20 20 20 20 20 20 20 20 20  nt sz;          
4900: 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20 6f 66       /* Bytes of
4910: 20 6d 65 6d 6f 72 79 20 72 65 71 75 69 72 65 64   memory required
4920: 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 74 68 65   to allocate the
4930: 20 6e 65 77 20 63 61 63 68 65 20 2a 2f 0a 0a 20   new cache */.. 
4940: 20 2f 2a 0a 20 20 2a 2a 20 54 68 65 20 73 65 70   /*.  ** The sep
4950: 65 72 61 74 65 43 61 63 68 65 20 76 61 72 69 61  erateCache varia
4960: 62 6c 65 20 69 73 20 74 72 75 65 20 69 66 20 65  ble is true if e
4970: 61 63 68 20 50 43 61 63 68 65 20 68 61 73 20 69  ach PCache has i
4980: 74 73 20 6f 77 6e 20 70 72 69 76 61 74 65 0a 20  ts own private. 
4990: 20 2a 2a 20 50 47 72 6f 75 70 2e 20 20 49 6e 20   ** PGroup.  In 
49a0: 6f 74 68 65 72 20 77 6f 72 64 73 2c 20 73 65 70  other words, sep
49b0: 61 72 61 74 65 43 61 63 68 65 20 69 73 20 74 72  arateCache is tr
49c0: 75 65 20 66 6f 72 20 6d 6f 64 65 20 28 31 29 20  ue for mode (1) 
49d0: 77 68 65 72 65 20 6e 6f 0a 20 20 2a 2a 20 6d 75  where no.  ** mu
49e0: 74 65 78 69 6e 67 20 69 73 20 72 65 71 75 69 72  texing is requir
49f0: 65 64 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20  ed..  **.  **   
4a00: 2a 20 20 41 6c 77 61 79 73 20 75 73 65 20 61 20  *  Always use a 
4a10: 75 6e 69 66 69 65 64 20 63 61 63 68 65 20 28 6d  unified cache (m
4a20: 6f 64 65 2d 32 29 20 69 66 20 45 4e 41 42 4c 45  ode-2) if ENABLE
4a30: 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45  _MEMORY_MANAGEME
4a40: 4e 54 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 2a  NT.  **.  **   *
4a50: 20 20 41 6c 77 61 79 73 20 75 73 65 20 61 20 75    Always use a u
4a60: 6e 69 66 69 65 64 20 63 61 63 68 65 20 69 6e 20  nified cache in 
4a70: 73 69 6e 67 6c 65 2d 74 68 72 65 61 64 65 64 20  single-threaded 
4a80: 61 70 70 6c 69 63 61 74 69 6f 6e 73 0a 20 20 2a  applications.  *
4a90: 2a 0a 20 20 2a 2a 20 20 20 2a 20 20 4f 74 68 65  *.  **   *  Othe
4aa0: 72 77 69 73 65 20 28 69 66 20 6d 75 6c 74 69 2d  rwise (if multi-
4ab0: 74 68 72 65 61 64 65 64 20 61 6e 64 20 45 4e 41  threaded and ENA
4ac0: 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47  BLE_MEMORY_MANAG
4ad0: 45 4d 45 4e 54 20 69 73 20 6f 66 66 29 0a 20 20  EMENT is off).  
4ae0: 2a 2a 20 20 20 20 20 20 75 73 65 20 73 65 70 61  **      use sepa
4af0: 72 61 74 65 20 63 61 63 68 65 73 20 28 6d 6f 64  rate caches (mod
4b00: 65 2d 31 29 0a 20 20 2a 2f 0a 23 69 66 20 64 65  e-1).  */.#if de
4b10: 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 45 4e 41  fined(SQLITE_ENA
4b20: 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47  BLE_MEMORY_MANAG
4b30: 45 4d 45 4e 54 29 20 7c 7c 20 53 51 4c 49 54 45  EMENT) || SQLITE
4b40: 5f 54 48 52 45 41 44 53 41 46 45 3d 3d 30 0a 20  _THREADSAFE==0. 
4b50: 20 63 6f 6e 73 74 20 69 6e 74 20 73 65 70 61 72   const int separ
4b60: 61 74 65 43 61 63 68 65 20 3d 20 30 3b 0a 23 65  ateCache = 0;.#e
4b70: 6c 73 65 0a 20 20 69 6e 74 20 73 65 70 61 72 61  lse.  int separa
4b80: 74 65 43 61 63 68 65 20 3d 20 73 71 6c 69 74 65  teCache = sqlite
4b90: 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 62 43  3GlobalConfig.bC
4ba0: 6f 72 65 4d 75 74 65 78 3e 30 3b 0a 23 65 6e 64  oreMutex>0;.#end
4bb0: 69 66 0a 0a 20 20 73 7a 20 3d 20 73 69 7a 65 6f  if..  sz = sizeo
4bc0: 66 28 50 43 61 63 68 65 31 29 20 2b 20 73 69 7a  f(PCache1) + siz
4bd0: 65 6f 66 28 50 47 72 6f 75 70 29 2a 73 65 70 61  eof(PGroup)*sepa
4be0: 72 61 74 65 43 61 63 68 65 3b 0a 20 20 70 43 61  rateCache;.  pCa
4bf0: 63 68 65 20 3d 20 28 50 43 61 63 68 65 31 20 2a  che = (PCache1 *
4c00: 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28  )sqlite3_malloc(
4c10: 73 7a 29 3b 0a 20 20 69 66 28 20 70 43 61 63 68  sz);.  if( pCach
4c20: 65 20 29 7b 0a 20 20 20 20 6d 65 6d 73 65 74 28  e ){.    memset(
4c30: 70 43 61 63 68 65 2c 20 30 2c 20 73 7a 29 3b 0a  pCache, 0, sz);.
4c40: 20 20 20 20 69 66 28 20 73 65 70 61 72 61 74 65      if( separate
4c50: 43 61 63 68 65 20 29 7b 0a 20 20 20 20 20 20 70  Cache ){.      p
4c60: 47 72 6f 75 70 20 3d 20 28 50 47 72 6f 75 70 2a  Group = (PGroup*
4c70: 29 26 70 43 61 63 68 65 5b 31 5d 3b 0a 20 20 20  )&pCache[1];.   
4c80: 20 20 20 70 47 72 6f 75 70 2d 3e 6d 78 50 69 6e     pGroup->mxPin
4c90: 6e 65 64 20 3d 20 31 30 3b 0a 20 20 20 20 7d 65  ned = 10;.    }e
4ca0: 6c 73 65 7b 0a 20 20 20 20 20 20 70 47 72 6f 75  lse{.      pGrou
4cb0: 70 20 3d 20 26 70 63 61 63 68 65 31 2e 67 72 70  p = &pcache1.grp
4cc0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 43 61 63  ;.    }.    pCac
4cd0: 68 65 2d 3e 70 47 72 6f 75 70 20 3d 20 70 47 72  he->pGroup = pGr
4ce0: 6f 75 70 3b 0a 20 20 20 20 70 43 61 63 68 65 2d  oup;.    pCache-
4cf0: 3e 73 7a 50 61 67 65 20 3d 20 73 7a 50 61 67 65  >szPage = szPage
4d00: 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 73 7a  ;.    pCache->sz
4d10: 45 78 74 72 61 20 3d 20 73 7a 45 78 74 72 61 3b  Extra = szExtra;
4d20: 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 62 50 75  .    pCache->bPu
4d30: 72 67 65 61 62 6c 65 20 3d 20 28 62 50 75 72 67  rgeable = (bPurg
4d40: 65 61 62 6c 65 20 3f 20 31 20 3a 20 30 29 3b 0a  eable ? 1 : 0);.
4d50: 20 20 20 20 69 66 28 20 62 50 75 72 67 65 61 62      if( bPurgeab
4d60: 6c 65 20 29 7b 0a 20 20 20 20 20 20 70 43 61 63  le ){.      pCac
4d70: 68 65 2d 3e 6e 4d 69 6e 20 3d 20 31 30 3b 0a 20  he->nMin = 10;. 
4d80: 20 20 20 20 20 70 63 61 63 68 65 31 45 6e 74 65       pcache1Ente
4d90: 72 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b 0a  rMutex(pGroup);.
4da0: 20 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 6e 4d        pGroup->nM
4db0: 69 6e 50 61 67 65 20 2b 3d 20 70 43 61 63 68 65  inPage += pCache
4dc0: 2d 3e 6e 4d 69 6e 3b 0a 20 20 20 20 20 20 70 47  ->nMin;.      pG
4dd0: 72 6f 75 70 2d 3e 6d 78 50 69 6e 6e 65 64 20 3d  roup->mxPinned =
4de0: 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67   pGroup->nMaxPag
4df0: 65 20 2b 20 31 30 20 2d 20 70 47 72 6f 75 70 2d  e + 10 - pGroup-
4e00: 3e 6e 4d 69 6e 50 61 67 65 3b 0a 20 20 20 20 20  >nMinPage;.     
4e10: 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74   pcache1LeaveMut
4e20: 65 78 28 70 47 72 6f 75 70 29 3b 0a 20 20 20 20  ex(pGroup);.    
4e30: 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 28  }.  }.  return (
4e40: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a  sqlite3_pcache *
4e50: 29 70 43 61 63 68 65 3b 0a 7d 0a 0a 2f 2a 0a 2a  )pCache;.}../*.*
4e60: 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  * Implementation
4e70: 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f   of the sqlite3_
4e80: 70 63 61 63 68 65 2e 78 43 61 63 68 65 73 69 7a  pcache.xCachesiz
4e90: 65 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a  e method. .**.**
4ea0: 20 43 6f 6e 66 69 67 75 72 65 20 74 68 65 20 63   Configure the c
4eb0: 61 63 68 65 5f 73 69 7a 65 20 6c 69 6d 69 74 20  ache_size limit 
4ec0: 66 6f 72 20 61 20 63 61 63 68 65 2e 0a 2a 2f 0a  for a cache..*/.
4ed0: 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63  static void pcac
4ee0: 68 65 31 43 61 63 68 65 73 69 7a 65 28 73 71 6c  he1Cachesize(sql
4ef0: 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70 2c 20  ite3_pcache *p, 
4f00: 69 6e 74 20 6e 4d 61 78 29 7b 0a 20 20 50 43 61  int nMax){.  PCa
4f10: 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28  che1 *pCache = (
4f20: 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20 20 69  PCache1 *)p;.  i
4f30: 66 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67  f( pCache->bPurg
4f40: 65 61 62 6c 65 20 29 7b 0a 20 20 20 20 50 47 72  eable ){.    PGr
4f50: 6f 75 70 20 2a 70 47 72 6f 75 70 20 3d 20 70 43  oup *pGroup = pC
4f60: 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b 0a 20 20  ache->pGroup;.  
4f70: 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75    pcache1EnterMu
4f80: 74 65 78 28 70 47 72 6f 75 70 29 3b 0a 20 20 20  tex(pGroup);.   
4f90: 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67   pGroup->nMaxPag
4fa0: 65 20 2b 3d 20 28 6e 4d 61 78 20 2d 20 70 43 61  e += (nMax - pCa
4fb0: 63 68 65 2d 3e 6e 4d 61 78 29 3b 0a 20 20 20 20  che->nMax);.    
4fc0: 70 47 72 6f 75 70 2d 3e 6d 78 50 69 6e 6e 65 64  pGroup->mxPinned
4fd0: 20 3d 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50   = pGroup->nMaxP
4fe0: 61 67 65 20 2b 20 31 30 20 2d 20 70 47 72 6f 75  age + 10 - pGrou
4ff0: 70 2d 3e 6e 4d 69 6e 50 61 67 65 3b 0a 20 20 20  p->nMinPage;.   
5000: 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 20 3d 20   pCache->nMax = 
5010: 6e 4d 61 78 3b 0a 20 20 20 20 70 43 61 63 68 65  nMax;.    pCache
5020: 2d 3e 6e 39 30 70 63 74 20 3d 20 70 43 61 63 68  ->n90pct = pCach
5030: 65 2d 3e 6e 4d 61 78 2a 39 2f 31 30 3b 0a 20 20  e->nMax*9/10;.  
5040: 20 20 70 63 61 63 68 65 31 45 6e 66 6f 72 63 65    pcache1Enforce
5050: 4d 61 78 50 61 67 65 28 70 47 72 6f 75 70 29 3b  MaxPage(pGroup);
5060: 0a 20 20 20 20 70 63 61 63 68 65 31 4c 65 61 76  .    pcache1Leav
5070: 65 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b 0a  eMutex(pGroup);.
5080: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70    }.}../*.** Imp
5090: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74  lementation of t
50a0: 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68  he sqlite3_pcach
50b0: 65 2e 78 50 61 67 65 63 6f 75 6e 74 20 6d 65 74  e.xPagecount met
50c0: 68 6f 64 2e 20 0a 2a 2f 0a 73 74 61 74 69 63 20  hod. .*/.static 
50d0: 69 6e 74 20 70 63 61 63 68 65 31 50 61 67 65 63  int pcache1Pagec
50e0: 6f 75 6e 74 28 73 71 6c 69 74 65 33 5f 70 63 61  ount(sqlite3_pca
50f0: 63 68 65 20 2a 70 29 7b 0a 20 20 69 6e 74 20 6e  che *p){.  int n
5100: 3b 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43 61  ;.  PCache1 *pCa
5110: 63 68 65 20 3d 20 28 50 43 61 63 68 65 31 2a 29  che = (PCache1*)
5120: 70 3b 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65  p;.  pcache1Ente
5130: 72 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e 70  rMutex(pCache->p
5140: 47 72 6f 75 70 29 3b 0a 20 20 6e 20 3d 20 70 43  Group);.  n = pC
5150: 61 63 68 65 2d 3e 6e 50 61 67 65 3b 0a 20 20 70  ache->nPage;.  p
5160: 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78  cache1LeaveMutex
5170: 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 29  (pCache->pGroup)
5180: 3b 0a 20 20 72 65 74 75 72 6e 20 6e 3b 0a 7d 0a  ;.  return n;.}.
5190: 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74  ./*.** Implement
51a0: 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c  ation of the sql
51b0: 69 74 65 33 5f 70 63 61 63 68 65 2e 78 46 65 74  ite3_pcache.xFet
51c0: 63 68 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a  ch method. .**.*
51d0: 2a 20 46 65 74 63 68 20 61 20 70 61 67 65 20 62  * Fetch a page b
51e0: 79 20 6b 65 79 20 76 61 6c 75 65 2e 0a 2a 2a 0a  y key value..**.
51f0: 2a 2a 20 57 68 65 74 68 65 72 20 6f 72 20 6e 6f  ** Whether or no
5200: 74 20 61 20 6e 65 77 20 70 61 67 65 20 6d 61 79  t a new page may
5210: 20 62 65 20 61 6c 6c 6f 63 61 74 65 64 20 62 79   be allocated by
5220: 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 64   this function d
5230: 65 70 65 6e 64 73 20 6f 6e 0a 2a 2a 20 74 68 65  epends on.** the
5240: 20 76 61 6c 75 65 20 6f 66 20 74 68 65 20 63 72   value of the cr
5250: 65 61 74 65 46 6c 61 67 20 61 72 67 75 6d 65 6e  eateFlag argumen
5260: 74 2e 20 20 30 20 6d 65 61 6e 73 20 64 6f 20 6e  t.  0 means do n
5270: 6f 74 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e 65  ot allocate a ne
5280: 77 0a 2a 2a 20 70 61 67 65 2e 20 20 31 20 6d 65  w.** page.  1 me
5290: 61 6e 73 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e  ans allocate a n
52a0: 65 77 20 70 61 67 65 20 69 66 20 73 70 61 63 65  ew page if space
52b0: 20 69 73 20 65 61 73 69 6c 79 20 61 76 61 69 6c   is easily avail
52c0: 61 62 6c 65 2e 20 20 32 20 0a 2a 2a 20 6d 65 61  able.  2 .** mea
52d0: 6e 73 20 74 6f 20 74 72 79 20 72 65 61 6c 6c 79  ns to try really
52e0: 20 68 61 72 64 20 74 6f 20 61 6c 6c 6f 63 61 74   hard to allocat
52f0: 65 20 61 20 6e 65 77 20 70 61 67 65 2e 0a 2a 2a  e a new page..**
5300: 0a 2a 2a 20 46 6f 72 20 61 20 6e 6f 6e 2d 70 75  .** For a non-pu
5310: 72 67 65 61 62 6c 65 20 63 61 63 68 65 20 28 61  rgeable cache (a
5320: 20 63 61 63 68 65 20 75 73 65 64 20 61 73 20 74   cache used as t
5330: 68 65 20 73 74 6f 72 61 67 65 20 66 6f 72 20 61  he storage for a
5340: 6e 20 69 6e 2d 6d 65 6d 6f 72 79 0a 2a 2a 20 64  n in-memory.** d
5350: 61 74 61 62 61 73 65 29 20 74 68 65 72 65 20 69  atabase) there i
5360: 73 20 72 65 61 6c 6c 79 20 6e 6f 20 64 69 66 66  s really no diff
5370: 65 72 65 6e 63 65 20 62 65 74 77 65 65 6e 20 63  erence between c
5380: 72 65 61 74 65 46 6c 61 67 20 31 20 61 6e 64 20  reateFlag 1 and 
5390: 32 2e 20 20 53 6f 0a 2a 2a 20 74 68 65 20 63 61  2.  So.** the ca
53a0: 6c 6c 69 6e 67 20 66 75 6e 63 74 69 6f 6e 20 28  lling function (
53b0: 70 63 61 63 68 65 2e 63 29 20 77 69 6c 6c 20 6e  pcache.c) will n
53c0: 65 76 65 72 20 68 61 76 65 20 61 20 63 72 65 61  ever have a crea
53d0: 74 65 46 6c 61 67 20 6f 66 20 31 20 6f 6e 0a 2a  teFlag of 1 on.*
53e0: 2a 20 61 20 6e 6f 6e 2d 70 75 72 67 61 62 6c 65  * a non-purgable
53f0: 20 63 61 63 68 65 2e 0a 2a 2a 0a 2a 2a 20 54 68   cache..**.** Th
5400: 65 72 65 20 61 72 65 20 74 68 72 65 65 20 64 69  ere are three di
5410: 66 66 65 72 65 6e 74 20 61 70 70 72 6f 61 63 68  fferent approach
5420: 65 73 20 74 6f 20 6f 62 74 61 69 6e 69 6e 67 20  es to obtaining 
5430: 73 70 61 63 65 20 66 6f 72 20 61 20 70 61 67 65  space for a page
5440: 2c 0a 2a 2a 20 64 65 70 65 6e 64 69 6e 67 20 6f  ,.** depending o
5450: 6e 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20 70  n the value of p
5460: 61 72 61 6d 65 74 65 72 20 63 72 65 61 74 65 46  arameter createF
5470: 6c 61 67 20 28 77 68 69 63 68 20 6d 61 79 20 62  lag (which may b
5480: 65 20 30 2c 20 31 20 6f 72 20 32 29 2e 0a 2a 2a  e 0, 1 or 2)..**
5490: 0a 2a 2a 20 20 20 31 2e 20 52 65 67 61 72 64 6c  .**   1. Regardl
54a0: 65 73 73 20 6f 66 20 74 68 65 20 76 61 6c 75 65  ess of the value
54b0: 20 6f 66 20 63 72 65 61 74 65 46 6c 61 67 2c 20   of createFlag, 
54c0: 74 68 65 20 63 61 63 68 65 20 69 73 20 73 65 61  the cache is sea
54d0: 72 63 68 65 64 20 66 6f 72 20 61 20 0a 2a 2a 20  rched for a .** 
54e0: 20 20 20 20 20 63 6f 70 79 20 6f 66 20 74 68 65       copy of the
54f0: 20 72 65 71 75 65 73 74 65 64 20 70 61 67 65 2e   requested page.
5500: 20 49 66 20 6f 6e 65 20 69 73 20 66 6f 75 6e 64   If one is found
5510: 2c 20 69 74 20 69 73 20 72 65 74 75 72 6e 65 64  , it is returned
5520: 2e 0a 2a 2a 0a 2a 2a 20 20 20 32 2e 20 49 66 20  ..**.**   2. If 
5530: 63 72 65 61 74 65 46 6c 61 67 3d 3d 30 20 61 6e  createFlag==0 an
5540: 64 20 74 68 65 20 70 61 67 65 20 69 73 20 6e 6f  d the page is no
5550: 74 20 61 6c 72 65 61 64 79 20 69 6e 20 74 68 65  t already in the
5560: 20 63 61 63 68 65 2c 20 4e 55 4c 4c 20 69 73 0a   cache, NULL is.
5570: 2a 2a 20 20 20 20 20 20 72 65 74 75 72 6e 65 64  **      returned
5580: 2e 0a 2a 2a 0a 2a 2a 20 20 20 33 2e 20 49 66 20  ..**.**   3. If 
5590: 63 72 65 61 74 65 46 6c 61 67 20 69 73 20 31 2c  createFlag is 1,
55a0: 20 61 6e 64 20 74 68 65 20 70 61 67 65 20 69 73   and the page is
55b0: 20 6e 6f 74 20 61 6c 72 65 61 64 79 20 69 6e 20   not already in 
55c0: 74 68 65 20 63 61 63 68 65 2c 20 74 68 65 6e 0a  the cache, then.
55d0: 2a 2a 20 20 20 20 20 20 72 65 74 75 72 6e 20 4e  **      return N
55e0: 55 4c 4c 20 28 64 6f 20 6e 6f 74 20 61 6c 6c 6f  ULL (do not allo
55f0: 63 61 74 65 20 61 20 6e 65 77 20 70 61 67 65 29  cate a new page)
5600: 20 69 66 20 61 6e 79 20 6f 66 20 74 68 65 20 66   if any of the f
5610: 6f 6c 6c 6f 77 69 6e 67 0a 2a 2a 20 20 20 20 20  ollowing.**     
5620: 20 63 6f 6e 64 69 74 69 6f 6e 73 20 61 72 65 20   conditions are 
5630: 74 72 75 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20  true:.**.**     
5640: 20 20 28 61 29 20 74 68 65 20 6e 75 6d 62 65 72    (a) the number
5650: 20 6f 66 20 70 61 67 65 73 20 70 69 6e 6e 65 64   of pages pinned
5660: 20 62 79 20 74 68 65 20 63 61 63 68 65 20 69 73   by the cache is
5670: 20 67 72 65 61 74 65 72 20 74 68 61 6e 0a 2a 2a   greater than.**
5680: 20 20 20 20 20 20 20 20 20 20 20 50 43 61 63 68             PCach
5690: 65 31 2e 6e 4d 61 78 2c 20 6f 72 0a 2a 2a 0a 2a  e1.nMax, or.**.*
56a0: 2a 20 20 20 20 20 20 20 28 62 29 20 74 68 65 20  *       (b) the 
56b0: 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20  number of pages 
56c0: 70 69 6e 6e 65 64 20 62 79 20 74 68 65 20 63 61  pinned by the ca
56d0: 63 68 65 20 69 73 20 67 72 65 61 74 65 72 20 74  che is greater t
56e0: 68 61 6e 0a 2a 2a 20 20 20 20 20 20 20 20 20 20  han.**          
56f0: 20 74 68 65 20 73 75 6d 20 6f 66 20 6e 4d 61 78   the sum of nMax
5700: 20 66 6f 72 20 61 6c 6c 20 70 75 72 67 65 61 62   for all purgeab
5710: 6c 65 20 63 61 63 68 65 73 2c 20 6c 65 73 73 20  le caches, less 
5720: 74 68 65 20 73 75 6d 20 6f 66 20 0a 2a 2a 20 20  the sum of .**  
5730: 20 20 20 20 20 20 20 20 20 6e 4d 69 6e 20 66 6f           nMin fo
5740: 72 20 61 6c 6c 20 6f 74 68 65 72 20 70 75 72 67  r all other purg
5750: 65 61 62 6c 65 20 63 61 63 68 65 73 2c 20 6f 72  eable caches, or
5760: 0a 2a 2a 0a 2a 2a 20 20 20 34 2e 20 49 66 20 6e  .**.**   4. If n
5770: 6f 6e 65 20 6f 66 20 74 68 65 20 66 69 72 73 74  one of the first
5780: 20 74 68 72 65 65 20 63 6f 6e 64 69 74 69 6f 6e   three condition
5790: 73 20 61 70 70 6c 79 20 61 6e 64 20 74 68 65 20  s apply and the 
57a0: 63 61 63 68 65 20 69 73 20 6d 61 72 6b 65 64 0a  cache is marked.
57b0: 2a 2a 20 20 20 20 20 20 61 73 20 70 75 72 67 65  **      as purge
57c0: 61 62 6c 65 2c 20 61 6e 64 20 69 66 20 6f 6e 65  able, and if one
57d0: 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e   of the followin
57e0: 67 20 69 73 20 74 72 75 65 3a 0a 2a 2a 0a 2a 2a  g is true:.**.**
57f0: 20 20 20 20 20 20 20 28 61 29 20 54 68 65 20 6e         (a) The n
5800: 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 61  umber of pages a
5810: 6c 6c 6f 63 61 74 65 64 20 66 6f 72 20 74 68 65  llocated for the
5820: 20 63 61 63 68 65 20 69 73 20 61 6c 72 65 61 64   cache is alread
5830: 79 20 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20  y .**           
5840: 50 43 61 63 68 65 31 2e 6e 4d 61 78 2c 20 6f 72  PCache1.nMax, or
5850: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 28 62 29  .**.**       (b)
5860: 20 54 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70   The number of p
5870: 61 67 65 73 20 61 6c 6c 6f 63 61 74 65 64 20 66  ages allocated f
5880: 6f 72 20 61 6c 6c 20 70 75 72 67 65 61 62 6c 65  or all purgeable
5890: 20 63 61 63 68 65 73 20 69 73 0a 2a 2a 20 20 20   caches is.**   
58a0: 20 20 20 20 20 20 20 20 61 6c 72 65 61 64 79 20          already 
58b0: 65 71 75 61 6c 20 74 6f 20 6f 72 20 67 72 65 61  equal to or grea
58c0: 74 65 72 20 74 68 61 6e 20 74 68 65 20 73 75 6d  ter than the sum
58d0: 20 6f 66 20 6e 4d 61 78 20 66 6f 72 20 61 6c 6c   of nMax for all
58e0: 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 70 75  .**           pu
58f0: 72 67 65 61 62 6c 65 20 63 61 63 68 65 73 2c 0a  rgeable caches,.
5900: 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 28 63 29 20  **.**       (c) 
5910: 54 68 65 20 73 79 73 74 65 6d 20 69 73 20 75 6e  The system is un
5920: 64 65 72 20 6d 65 6d 6f 72 79 20 70 72 65 73 73  der memory press
5930: 75 72 65 20 61 6e 64 20 77 61 6e 74 73 20 74 6f  ure and wants to
5940: 20 61 76 6f 69 64 0a 2a 2a 20 20 20 20 20 20 20   avoid.**       
5950: 20 20 20 20 75 6e 6e 65 63 65 73 73 61 72 79 20      unnecessary 
5960: 70 61 67 65 73 20 63 61 63 68 65 20 65 6e 74 72  pages cache entr
5970: 79 20 61 6c 6c 6f 63 61 74 69 6f 6e 73 0a 2a 2a  y allocations.**
5980: 0a 2a 2a 20 20 20 20 20 20 74 68 65 6e 20 61 74  .**      then at
5990: 74 65 6d 70 74 20 74 6f 20 72 65 63 79 63 6c 65  tempt to recycle
59a0: 20 61 20 70 61 67 65 20 66 72 6f 6d 20 74 68 65   a page from the
59b0: 20 4c 52 55 20 6c 69 73 74 2e 20 49 66 20 69 74   LRU list. If it
59c0: 20 69 73 20 74 68 65 20 72 69 67 68 74 0a 2a 2a   is the right.**
59d0: 20 20 20 20 20 20 73 69 7a 65 2c 20 72 65 74 75        size, retu
59e0: 72 6e 20 74 68 65 20 72 65 63 79 63 6c 65 64 20  rn the recycled 
59f0: 62 75 66 66 65 72 2e 20 4f 74 68 65 72 77 69 73  buffer. Otherwis
5a00: 65 2c 20 66 72 65 65 20 74 68 65 20 62 75 66 66  e, free the buff
5a10: 65 72 20 61 6e 64 0a 2a 2a 20 20 20 20 20 20 70  er and.**      p
5a20: 72 6f 63 65 65 64 20 74 6f 20 73 74 65 70 20 35  roceed to step 5
5a30: 2e 20 0a 2a 2a 0a 2a 2a 20 20 20 35 2e 20 4f 74  . .**.**   5. Ot
5a40: 68 65 72 77 69 73 65 2c 20 61 6c 6c 6f 63 61 74  herwise, allocat
5a50: 65 20 61 6e 64 20 72 65 74 75 72 6e 20 61 20 6e  e and return a n
5a60: 65 77 20 70 61 67 65 20 62 75 66 66 65 72 2e 0a  ew page buffer..
5a70: 2a 2f 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65  */.static sqlite
5a80: 33 5f 70 63 61 63 68 65 5f 70 61 67 65 20 2a 70  3_pcache_page *p
5a90: 63 61 63 68 65 31 46 65 74 63 68 28 0a 20 20 73  cache1Fetch(.  s
5aa0: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70  qlite3_pcache *p
5ab0: 2c 20 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e  , .  unsigned in
5ac0: 74 20 69 4b 65 79 2c 20 0a 20 20 69 6e 74 20 63  t iKey, .  int c
5ad0: 72 65 61 74 65 46 6c 61 67 0a 29 7b 0a 20 20 69  reateFlag.){.  i
5ae0: 6e 74 20 6e 50 69 6e 6e 65 64 3b 0a 20 20 50 43  nt nPinned;.  PC
5af0: 61 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20  ache1 *pCache = 
5b00: 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20 20  (PCache1 *)p;.  
5b10: 50 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 3b 0a  PGroup *pGroup;.
5b20: 20 20 50 67 48 64 72 31 20 2a 70 50 61 67 65 20    PgHdr1 *pPage 
5b30: 3d 20 30 3b 0a 0a 20 20 61 73 73 65 72 74 28 20  = 0;..  assert( 
5b40: 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62  pCache->bPurgeab
5b50: 6c 65 20 7c 7c 20 63 72 65 61 74 65 46 6c 61 67  le || createFlag
5b60: 21 3d 31 20 29 3b 0a 20 20 61 73 73 65 72 74 28  !=1 );.  assert(
5b70: 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61   pCache->bPurgea
5b80: 62 6c 65 20 7c 7c 20 70 43 61 63 68 65 2d 3e 6e  ble || pCache->n
5b90: 4d 69 6e 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65  Min==0 );.  asse
5ba0: 72 74 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72  rt( pCache->bPur
5bb0: 67 65 61 62 6c 65 3d 3d 30 20 7c 7c 20 70 43 61  geable==0 || pCa
5bc0: 63 68 65 2d 3e 6e 4d 69 6e 3d 3d 31 30 20 29 3b  che->nMin==10 );
5bd0: 0a 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68  .  assert( pCach
5be0: 65 2d 3e 6e 4d 69 6e 3d 3d 30 20 7c 7c 20 70 43  e->nMin==0 || pC
5bf0: 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65  ache->bPurgeable
5c00: 20 29 3b 0a 20 20 70 63 61 63 68 65 31 45 6e 74   );.  pcache1Ent
5c10: 65 72 4d 75 74 65 78 28 70 47 72 6f 75 70 20 3d  erMutex(pGroup =
5c20: 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 29   pCache->pGroup)
5c30: 3b 0a 0a 20 20 2f 2a 20 53 74 65 70 20 31 3a 20  ;..  /* Step 1: 
5c40: 53 65 61 72 63 68 20 74 68 65 20 68 61 73 68 20  Search the hash 
5c50: 74 61 62 6c 65 20 66 6f 72 20 61 6e 20 65 78 69  table for an exi
5c60: 73 74 69 6e 67 20 65 6e 74 72 79 2e 20 2a 2f 0a  sting entry. */.
5c70: 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 6e 48    if( pCache->nH
5c80: 61 73 68 3e 30 20 29 7b 0a 20 20 20 20 75 6e 73  ash>0 ){.    uns
5c90: 69 67 6e 65 64 20 69 6e 74 20 68 20 3d 20 69 4b  igned int h = iK
5ca0: 65 79 20 25 20 70 43 61 63 68 65 2d 3e 6e 48 61  ey % pCache->nHa
5cb0: 73 68 3b 0a 20 20 20 20 66 6f 72 28 70 50 61 67  sh;.    for(pPag
5cc0: 65 3d 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68  e=pCache->apHash
5cd0: 5b 68 5d 3b 20 70 50 61 67 65 26 26 70 50 61 67  [h]; pPage&&pPag
5ce0: 65 2d 3e 69 4b 65 79 21 3d 69 4b 65 79 3b 20 70  e->iKey!=iKey; p
5cf0: 50 61 67 65 3d 70 50 61 67 65 2d 3e 70 4e 65 78  Page=pPage->pNex
5d00: 74 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53 74  t);.  }..  /* St
5d10: 65 70 20 32 3a 20 41 62 6f 72 74 20 69 66 20 6e  ep 2: Abort if n
5d20: 6f 20 65 78 69 73 74 69 6e 67 20 70 61 67 65 20  o existing page 
5d30: 69 73 20 66 6f 75 6e 64 20 61 6e 64 20 63 72 65  is found and cre
5d40: 61 74 65 46 6c 61 67 20 69 73 20 30 20 2a 2f 0a  ateFlag is 0 */.
5d50: 20 20 69 66 28 20 70 50 61 67 65 20 7c 7c 20 63    if( pPage || c
5d60: 72 65 61 74 65 46 6c 61 67 3d 3d 30 20 29 7b 0a  reateFlag==0 ){.
5d70: 20 20 20 20 70 63 61 63 68 65 31 50 69 6e 50 61      pcache1PinPa
5d80: 67 65 28 70 50 61 67 65 29 3b 0a 20 20 20 20 67  ge(pPage);.    g
5d90: 6f 74 6f 20 66 65 74 63 68 5f 6f 75 74 3b 0a 20  oto fetch_out;. 
5da0: 20 7d 0a 0a 20 20 2f 2a 20 54 68 65 20 70 47 72   }..  /* The pGr
5db0: 6f 75 70 20 6c 6f 63 61 6c 20 76 61 72 69 61 62  oup local variab
5dc0: 6c 65 20 77 69 6c 6c 20 6e 6f 72 6d 61 6c 6c 79  le will normally
5dd0: 20 62 65 20 69 6e 69 74 69 61 6c 69 7a 65 64 20   be initialized 
5de0: 62 79 20 74 68 65 0a 20 20 2a 2a 20 70 63 61 63  by the.  ** pcac
5df0: 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 29 20  he1EnterMutex() 
5e00: 6d 61 63 72 6f 20 61 62 6f 76 65 2e 20 20 42 75  macro above.  Bu
5e10: 74 20 69 66 20 53 51 4c 49 54 45 5f 4d 55 54 45  t if SQLITE_MUTE
5e20: 58 5f 4f 4d 49 54 20 69 73 20 64 65 66 69 6e 65  X_OMIT is define
5e30: 64 2c 0a 20 20 2a 2a 20 74 68 65 6e 20 70 63 61  d,.  ** then pca
5e40: 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 29  che1EnterMutex()
5e50: 20 69 73 20 61 20 6e 6f 2d 6f 70 2c 20 73 6f 20   is a no-op, so 
5e60: 77 65 20 68 61 76 65 20 74 6f 20 69 6e 69 74 69  we have to initi
5e70: 61 6c 69 7a 65 20 74 68 65 0a 20 20 2a 2a 20 6c  alize the.  ** l
5e80: 6f 63 61 6c 20 76 61 72 69 61 62 6c 65 20 68 65  ocal variable he
5e90: 72 65 2e 20 20 44 65 6c 61 79 69 6e 67 20 74 68  re.  Delaying th
5ea0: 65 20 69 6e 69 74 69 61 6c 69 7a 61 74 69 6f 6e  e initialization
5eb0: 20 6f 66 20 70 47 72 6f 75 70 20 69 73 20 61 6e   of pGroup is an
5ec0: 0a 20 20 2a 2a 20 6f 70 74 69 6d 69 7a 61 74 69  .  ** optimizati
5ed0: 6f 6e 3a 20 20 54 68 65 20 63 6f 6d 6d 6f 6e 20  on:  The common 
5ee0: 63 61 73 65 20 69 73 20 74 6f 20 65 78 69 74 20  case is to exit 
5ef0: 74 68 65 20 6d 6f 64 75 6c 65 20 62 65 66 6f 72  the module befor
5f00: 65 20 72 65 61 63 68 69 6e 67 0a 20 20 2a 2a 20  e reaching.  ** 
5f10: 74 68 69 73 20 70 6f 69 6e 74 2e 0a 20 20 2a 2f  this point..  */
5f20: 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 4d  .#ifdef SQLITE_M
5f30: 55 54 45 58 5f 4f 4d 49 54 0a 20 20 70 47 72 6f  UTEX_OMIT.  pGro
5f40: 75 70 20 3d 20 70 43 61 63 68 65 2d 3e 70 47 72  up = pCache->pGr
5f50: 6f 75 70 3b 0a 23 65 6e 64 69 66 0a 0a 20 20 2f  oup;.#endif..  /
5f60: 2a 20 53 74 65 70 20 33 3a 20 41 62 6f 72 74 20  * Step 3: Abort 
5f70: 69 66 20 63 72 65 61 74 65 46 6c 61 67 20 69 73  if createFlag is
5f80: 20 31 20 62 75 74 20 74 68 65 20 63 61 63 68 65   1 but the cache
5f90: 20 69 73 20 6e 65 61 72 6c 79 20 66 75 6c 6c 20   is nearly full 
5fa0: 2a 2f 0a 20 20 6e 50 69 6e 6e 65 64 20 3d 20 70  */.  nPinned = p
5fb0: 43 61 63 68 65 2d 3e 6e 50 61 67 65 20 2d 20 70  Cache->nPage - p
5fc0: 43 61 63 68 65 2d 3e 6e 52 65 63 79 63 6c 61 62  Cache->nRecyclab
5fd0: 6c 65 3b 0a 20 20 61 73 73 65 72 74 28 20 6e 50  le;.  assert( nP
5fe0: 69 6e 6e 65 64 3e 3d 30 20 29 3b 0a 20 20 61 73  inned>=0 );.  as
5ff0: 73 65 72 74 28 20 70 47 72 6f 75 70 2d 3e 6d 78  sert( pGroup->mx
6000: 50 69 6e 6e 65 64 20 3d 3d 20 70 47 72 6f 75 70  Pinned == pGroup
6010: 2d 3e 6e 4d 61 78 50 61 67 65 20 2b 20 31 30 20  ->nMaxPage + 10 
6020: 2d 20 70 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61  - pGroup->nMinPa
6030: 67 65 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  ge );.  assert( 
6040: 70 43 61 63 68 65 2d 3e 6e 39 30 70 63 74 20 3d  pCache->n90pct =
6050: 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 2a 39  = pCache->nMax*9
6060: 2f 31 30 20 29 3b 0a 20 20 69 66 28 20 63 72 65  /10 );.  if( cre
6070: 61 74 65 46 6c 61 67 3d 3d 31 20 26 26 20 28 0a  ateFlag==1 && (.
6080: 20 20 20 20 20 20 20 20 6e 50 69 6e 6e 65 64 3e          nPinned>
6090: 3d 70 47 72 6f 75 70 2d 3e 6d 78 50 69 6e 6e 65  =pGroup->mxPinne
60a0: 64 0a 20 20 20 20 20 7c 7c 20 6e 50 69 6e 6e 65  d.     || nPinne
60b0: 64 3e 3d 28 69 6e 74 29 70 43 61 63 68 65 2d 3e  d>=(int)pCache->
60c0: 6e 39 30 70 63 74 0a 20 20 20 20 20 7c 7c 20 70  n90pct.     || p
60d0: 63 61 63 68 65 31 55 6e 64 65 72 4d 65 6d 6f 72  cache1UnderMemor
60e0: 79 50 72 65 73 73 75 72 65 28 70 43 61 63 68 65  yPressure(pCache
60f0: 29 0a 20 20 29 29 7b 0a 20 20 20 20 67 6f 74 6f  ).  )){.    goto
6100: 20 66 65 74 63 68 5f 6f 75 74 3b 0a 20 20 7d 0a   fetch_out;.  }.
6110: 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 6e  .  if( pCache->n
6120: 50 61 67 65 3e 3d 70 43 61 63 68 65 2d 3e 6e 48  Page>=pCache->nH
6130: 61 73 68 20 26 26 20 70 63 61 63 68 65 31 52 65  ash && pcache1Re
6140: 73 69 7a 65 48 61 73 68 28 70 43 61 63 68 65 29  sizeHash(pCache)
6150: 20 29 7b 0a 20 20 20 20 67 6f 74 6f 20 66 65 74   ){.    goto fet
6160: 63 68 5f 6f 75 74 3b 0a 20 20 7d 0a 0a 20 20 2f  ch_out;.  }..  /
6170: 2a 20 53 74 65 70 20 34 2e 20 54 72 79 20 74 6f  * Step 4. Try to
6180: 20 72 65 63 79 63 6c 65 20 61 20 70 61 67 65 2e   recycle a page.
6190: 20 2a 2f 0a 20 20 69 66 28 20 70 43 61 63 68 65   */.  if( pCache
61a0: 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 26 26 20  ->bPurgeable && 
61b0: 70 47 72 6f 75 70 2d 3e 70 4c 72 75 54 61 69 6c  pGroup->pLruTail
61c0: 20 26 26 20 28 0a 20 20 20 20 20 20 20 20 20 28   && (.         (
61d0: 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 2b 31 3e  pCache->nPage+1>
61e0: 3d 70 43 61 63 68 65 2d 3e 6e 4d 61 78 29 0a 20  =pCache->nMax). 
61f0: 20 20 20 20 20 7c 7c 20 70 47 72 6f 75 70 2d 3e       || pGroup->
6200: 6e 43 75 72 72 65 6e 74 50 61 67 65 3e 3d 70 47  nCurrentPage>=pG
6210: 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65 0a 20  roup->nMaxPage. 
6220: 20 20 20 20 20 7c 7c 20 70 63 61 63 68 65 31 55       || pcache1U
6230: 6e 64 65 72 4d 65 6d 6f 72 79 50 72 65 73 73 75  nderMemoryPressu
6240: 72 65 28 70 43 61 63 68 65 29 0a 20 20 29 29 7b  re(pCache).  )){
6250: 0a 20 20 20 20 50 43 61 63 68 65 31 20 2a 70 4f  .    PCache1 *pO
6260: 74 68 65 72 43 61 63 68 65 3b 0a 20 20 20 20 70  therCache;.    p
6270: 50 61 67 65 20 3d 20 70 47 72 6f 75 70 2d 3e 70  Page = pGroup->p
6280: 4c 72 75 54 61 69 6c 3b 0a 20 20 20 20 70 63 61  LruTail;.    pca
6290: 63 68 65 31 52 65 6d 6f 76 65 46 72 6f 6d 48 61  che1RemoveFromHa
62a0: 73 68 28 70 50 61 67 65 29 3b 0a 20 20 20 20 70  sh(pPage);.    p
62b0: 63 61 63 68 65 31 50 69 6e 50 61 67 65 28 70 50  cache1PinPage(pP
62c0: 61 67 65 29 3b 0a 20 20 20 20 69 66 28 20 28 70  age);.    if( (p
62d0: 4f 74 68 65 72 43 61 63 68 65 20 3d 20 70 50 61  OtherCache = pPa
62e0: 67 65 2d 3e 70 43 61 63 68 65 29 2d 3e 73 7a 50  ge->pCache)->szP
62f0: 61 67 65 21 3d 70 43 61 63 68 65 2d 3e 73 7a 50  age!=pCache->szP
6300: 61 67 65 20 0a 20 20 20 20 20 7c 7c 20 70 4f 74  age .     || pOt
6310: 68 65 72 43 61 63 68 65 2d 3e 73 7a 45 78 74 72  herCache->szExtr
6320: 61 21 3d 70 43 61 63 68 65 2d 3e 73 7a 45 78 74  a!=pCache->szExt
6330: 72 61 20 0a 20 20 20 20 29 7b 0a 20 20 20 20 20  ra .    ){.     
6340: 20 70 63 61 63 68 65 31 46 72 65 65 50 61 67 65   pcache1FreePage
6350: 28 70 50 61 67 65 29 3b 0a 20 20 20 20 20 20 70  (pPage);.      p
6360: 50 61 67 65 20 3d 20 30 3b 0a 20 20 20 20 7d 65  Page = 0;.    }e
6370: 6c 73 65 7b 0a 20 20 20 20 20 20 70 47 72 6f 75  lse{.      pGrou
6380: 70 2d 3e 6e 43 75 72 72 65 6e 74 50 61 67 65 20  p->nCurrentPage 
6390: 2d 3d 20 28 70 4f 74 68 65 72 43 61 63 68 65 2d  -= (pOtherCache-
63a0: 3e 62 50 75 72 67 65 61 62 6c 65 20 2d 20 70 43  >bPurgeable - pC
63b0: 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65  ache->bPurgeable
63c0: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  );.    }.  }..  
63d0: 2f 2a 20 53 74 65 70 20 35 2e 20 49 66 20 61 20  /* Step 5. If a 
63e0: 75 73 61 62 6c 65 20 70 61 67 65 20 62 75 66 66  usable page buff
63f0: 65 72 20 68 61 73 20 73 74 69 6c 6c 20 6e 6f 74  er has still not
6400: 20 62 65 65 6e 20 66 6f 75 6e 64 2c 20 0a 20 20   been found, .  
6410: 2a 2a 20 61 74 74 65 6d 70 74 20 74 6f 20 61 6c  ** attempt to al
6420: 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 6f 6e 65  locate a new one
6430: 2e 20 0a 20 20 2a 2f 0a 20 20 69 66 28 20 21 70  . .  */.  if( !p
6440: 50 61 67 65 20 29 7b 0a 20 20 20 20 69 66 28 20  Page ){.    if( 
6450: 63 72 65 61 74 65 46 6c 61 67 3d 3d 31 20 29 20  createFlag==1 ) 
6460: 73 71 6c 69 74 65 33 42 65 67 69 6e 42 65 6e 69  sqlite3BeginBeni
6470: 67 6e 4d 61 6c 6c 6f 63 28 29 3b 0a 20 20 20 20  gnMalloc();.    
6480: 70 50 61 67 65 20 3d 20 70 63 61 63 68 65 31 41  pPage = pcache1A
6490: 6c 6c 6f 63 50 61 67 65 28 70 43 61 63 68 65 29  llocPage(pCache)
64a0: 3b 0a 20 20 20 20 69 66 28 20 63 72 65 61 74 65  ;.    if( create
64b0: 46 6c 61 67 3d 3d 31 20 29 20 73 71 6c 69 74 65  Flag==1 ) sqlite
64c0: 33 45 6e 64 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63  3EndBenignMalloc
64d0: 28 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70  ();.  }..  if( p
64e0: 50 61 67 65 20 29 7b 0a 20 20 20 20 75 6e 73 69  Page ){.    unsi
64f0: 67 6e 65 64 20 69 6e 74 20 68 20 3d 20 69 4b 65  gned int h = iKe
6500: 79 20 25 20 70 43 61 63 68 65 2d 3e 6e 48 61 73  y % pCache->nHas
6510: 68 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 6e  h;.    pCache->n
6520: 50 61 67 65 2b 2b 3b 0a 20 20 20 20 70 50 61 67  Page++;.    pPag
6530: 65 2d 3e 69 4b 65 79 20 3d 20 69 4b 65 79 3b 0a  e->iKey = iKey;.
6540: 20 20 20 20 70 50 61 67 65 2d 3e 70 4e 65 78 74      pPage->pNext
6550: 20 3d 20 70 43 61 63 68 65 2d 3e 61 70 48 61 73   = pCache->apHas
6560: 68 5b 68 5d 3b 0a 20 20 20 20 70 50 61 67 65 2d  h[h];.    pPage-
6570: 3e 70 43 61 63 68 65 20 3d 20 70 43 61 63 68 65  >pCache = pCache
6580: 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 4c 72  ;.    pPage->pLr
6590: 75 50 72 65 76 20 3d 20 30 3b 0a 20 20 20 20 70  uPrev = 0;.    p
65a0: 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 20 3d  Page->pLruNext =
65b0: 20 30 3b 0a 20 20 20 20 2a 28 76 6f 69 64 20 2a   0;.    *(void *
65c0: 2a 29 70 50 61 67 65 2d 3e 70 61 67 65 2e 70 45  *)pPage->page.pE
65d0: 78 74 72 61 20 3d 20 30 3b 0a 20 20 20 20 70 43  xtra = 0;.    pC
65e0: 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 20  ache->apHash[h] 
65f0: 3d 20 70 50 61 67 65 3b 0a 20 20 7d 0a 0a 66 65  = pPage;.  }..fe
6600: 74 63 68 5f 6f 75 74 3a 0a 20 20 69 66 28 20 70  tch_out:.  if( p
6610: 50 61 67 65 20 26 26 20 69 4b 65 79 3e 70 43 61  Page && iKey>pCa
6620: 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 29 7b 0a  che->iMaxKey ){.
6630: 20 20 20 20 70 43 61 63 68 65 2d 3e 69 4d 61 78      pCache->iMax
6640: 4b 65 79 20 3d 20 69 4b 65 79 3b 0a 20 20 7d 0a  Key = iKey;.  }.
6650: 20 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75    pcache1LeaveMu
6660: 74 65 78 28 70 47 72 6f 75 70 29 3b 0a 20 20 72  tex(pGroup);.  r
6670: 65 74 75 72 6e 20 26 70 50 61 67 65 2d 3e 70 61  eturn &pPage->pa
6680: 67 65 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 49 6d  ge;.}.../*.** Im
6690: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20  plementation of 
66a0: 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63  the sqlite3_pcac
66b0: 68 65 2e 78 55 6e 70 69 6e 20 6d 65 74 68 6f 64  he.xUnpin method
66c0: 2e 0a 2a 2a 0a 2a 2a 20 4d 61 72 6b 20 61 20 70  ..**.** Mark a p
66d0: 61 67 65 20 61 73 20 75 6e 70 69 6e 6e 65 64 20  age as unpinned 
66e0: 28 65 6c 69 67 69 62 6c 65 20 66 6f 72 20 61 73  (eligible for as
66f0: 79 6e 63 68 72 6f 6e 6f 75 73 20 72 65 63 79 63  ynchronous recyc
6700: 6c 69 6e 67 29 2e 0a 2a 2f 0a 73 74 61 74 69 63  ling)..*/.static
6710: 20 76 6f 69 64 20 70 63 61 63 68 65 31 55 6e 70   void pcache1Unp
6720: 69 6e 28 0a 20 20 73 71 6c 69 74 65 33 5f 70 63  in(.  sqlite3_pc
6730: 61 63 68 65 20 2a 70 2c 20 0a 20 20 73 71 6c 69  ache *p, .  sqli
6740: 74 65 33 5f 70 63 61 63 68 65 5f 70 61 67 65 20  te3_pcache_page 
6750: 2a 70 50 67 2c 20 0a 20 20 69 6e 74 20 72 65 75  *pPg, .  int reu
6760: 73 65 55 6e 6c 69 6b 65 6c 79 0a 29 7b 0a 20 20  seUnlikely.){.  
6770: 50 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 20  PCache1 *pCache 
6780: 3d 20 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a  = (PCache1 *)p;.
6790: 20 20 50 67 48 64 72 31 20 2a 70 50 61 67 65 20    PgHdr1 *pPage 
67a0: 3d 20 28 50 67 48 64 72 31 20 2a 29 70 50 67 3b  = (PgHdr1 *)pPg;
67b0: 0a 20 20 50 47 72 6f 75 70 20 2a 70 47 72 6f 75  .  PGroup *pGrou
67c0: 70 20 3d 20 70 43 61 63 68 65 2d 3e 70 47 72 6f  p = pCache->pGro
67d0: 75 70 3b 0a 20 0a 20 20 61 73 73 65 72 74 28 20  up;. .  assert( 
67e0: 70 50 61 67 65 2d 3e 70 43 61 63 68 65 3d 3d 70  pPage->pCache==p
67f0: 43 61 63 68 65 20 29 3b 0a 20 20 70 63 61 63 68  Cache );.  pcach
6800: 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70 47 72  e1EnterMutex(pGr
6810: 6f 75 70 29 3b 0a 0a 20 20 2f 2a 20 49 74 20 69  oup);..  /* It i
6820: 73 20 61 6e 20 65 72 72 6f 72 20 74 6f 20 63 61  s an error to ca
6830: 6c 6c 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  ll this function
6840: 20 69 66 20 74 68 65 20 70 61 67 65 20 69 73 20   if the page is 
6850: 61 6c 72 65 61 64 79 20 0a 20 20 2a 2a 20 70 61  already .  ** pa
6860: 72 74 20 6f 66 20 74 68 65 20 50 47 72 6f 75 70  rt of the PGroup
6870: 20 4c 52 55 20 6c 69 73 74 2e 0a 20 20 2a 2f 0a   LRU list..  */.
6880: 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65 2d    assert( pPage-
6890: 3e 70 4c 72 75 50 72 65 76 3d 3d 30 20 26 26 20  >pLruPrev==0 && 
68a0: 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 3d  pPage->pLruNext=
68b0: 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  =0 );.  assert( 
68c0: 70 47 72 6f 75 70 2d 3e 70 4c 72 75 48 65 61 64  pGroup->pLruHead
68d0: 21 3d 70 50 61 67 65 20 26 26 20 70 47 72 6f 75  !=pPage && pGrou
68e0: 70 2d 3e 70 4c 72 75 54 61 69 6c 21 3d 70 50 61  p->pLruTail!=pPa
68f0: 67 65 20 29 3b 0a 0a 20 20 69 66 28 20 72 65 75  ge );..  if( reu
6900: 73 65 55 6e 6c 69 6b 65 6c 79 20 7c 7c 20 70 47  seUnlikely || pG
6910: 72 6f 75 70 2d 3e 6e 43 75 72 72 65 6e 74 50 61  roup->nCurrentPa
6920: 67 65 3e 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50  ge>pGroup->nMaxP
6930: 61 67 65 20 29 7b 0a 20 20 20 20 70 63 61 63 68  age ){.    pcach
6940: 65 31 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73 68  e1RemoveFromHash
6950: 28 70 50 61 67 65 29 3b 0a 20 20 20 20 70 63 61  (pPage);.    pca
6960: 63 68 65 31 46 72 65 65 50 61 67 65 28 70 50 61  che1FreePage(pPa
6970: 67 65 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  ge);.  }else{.  
6980: 20 20 2f 2a 20 41 64 64 20 74 68 65 20 70 61 67    /* Add the pag
6990: 65 20 74 6f 20 74 68 65 20 50 47 72 6f 75 70 20  e to the PGroup 
69a0: 4c 52 55 20 6c 69 73 74 2e 20 2a 2f 0a 20 20 20  LRU list. */.   
69b0: 20 69 66 28 20 70 47 72 6f 75 70 2d 3e 70 4c 72   if( pGroup->pLr
69c0: 75 48 65 61 64 20 29 7b 0a 20 20 20 20 20 20 70  uHead ){.      p
69d0: 47 72 6f 75 70 2d 3e 70 4c 72 75 48 65 61 64 2d  Group->pLruHead-
69e0: 3e 70 4c 72 75 50 72 65 76 20 3d 20 70 50 61 67  >pLruPrev = pPag
69f0: 65 3b 0a 20 20 20 20 20 20 70 50 61 67 65 2d 3e  e;.      pPage->
6a00: 70 4c 72 75 4e 65 78 74 20 3d 20 70 47 72 6f 75  pLruNext = pGrou
6a10: 70 2d 3e 70 4c 72 75 48 65 61 64 3b 0a 20 20 20  p->pLruHead;.   
6a20: 20 20 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 48     pGroup->pLruH
6a30: 65 61 64 20 3d 20 70 50 61 67 65 3b 0a 20 20 20  ead = pPage;.   
6a40: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 47   }else{.      pG
6a50: 72 6f 75 70 2d 3e 70 4c 72 75 54 61 69 6c 20 3d  roup->pLruTail =
6a60: 20 70 50 61 67 65 3b 0a 20 20 20 20 20 20 70 47   pPage;.      pG
6a70: 72 6f 75 70 2d 3e 70 4c 72 75 48 65 61 64 20 3d  roup->pLruHead =
6a80: 20 70 50 61 67 65 3b 0a 20 20 20 20 7d 0a 20 20   pPage;.    }.  
6a90: 20 20 70 43 61 63 68 65 2d 3e 6e 52 65 63 79 63    pCache->nRecyc
6aa0: 6c 61 62 6c 65 2b 2b 3b 0a 20 20 7d 0a 0a 20 20  lable++;.  }..  
6ab0: 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65  pcache1LeaveMute
6ac0: 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70  x(pCache->pGroup
6ad0: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c  );.}../*.** Impl
6ae0: 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68  ementation of th
6af0: 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  e sqlite3_pcache
6b00: 2e 78 52 65 6b 65 79 20 6d 65 74 68 6f 64 2e 20  .xRekey method. 
6b10: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
6b20: 70 63 61 63 68 65 31 52 65 6b 65 79 28 0a 20 20  pcache1Rekey(.  
6b30: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a  sqlite3_pcache *
6b40: 70 2c 0a 20 20 73 71 6c 69 74 65 33 5f 70 63 61  p,.  sqlite3_pca
6b50: 63 68 65 5f 70 61 67 65 20 2a 70 50 67 2c 0a 20  che_page *pPg,. 
6b60: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4f   unsigned int iO
6b70: 6c 64 2c 0a 20 20 75 6e 73 69 67 6e 65 64 20 69  ld,.  unsigned i
6b80: 6e 74 20 69 4e 65 77 0a 29 7b 0a 20 20 50 43 61  nt iNew.){.  PCa
6b90: 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28  che1 *pCache = (
6ba0: 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20 20 50  PCache1 *)p;.  P
6bb0: 67 48 64 72 31 20 2a 70 50 61 67 65 20 3d 20 28  gHdr1 *pPage = (
6bc0: 50 67 48 64 72 31 20 2a 29 70 50 67 3b 0a 20 20  PgHdr1 *)pPg;.  
6bd0: 50 67 48 64 72 31 20 2a 2a 70 70 3b 0a 20 20 75  PgHdr1 **pp;.  u
6be0: 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 3b 20 0a  nsigned int h; .
6bf0: 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65 2d    assert( pPage-
6c00: 3e 69 4b 65 79 3d 3d 69 4f 6c 64 20 29 3b 0a 20  >iKey==iOld );. 
6c10: 20 61 73 73 65 72 74 28 20 70 50 61 67 65 2d 3e   assert( pPage->
6c20: 70 43 61 63 68 65 3d 3d 70 43 61 63 68 65 20 29  pCache==pCache )
6c30: 3b 0a 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65  ;..  pcache1Ente
6c40: 72 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e 70  rMutex(pCache->p
6c50: 47 72 6f 75 70 29 3b 0a 0a 20 20 68 20 3d 20 69  Group);..  h = i
6c60: 4f 6c 64 25 70 43 61 63 68 65 2d 3e 6e 48 61 73  Old%pCache->nHas
6c70: 68 3b 0a 20 20 70 70 20 3d 20 26 70 43 61 63 68  h;.  pp = &pCach
6c80: 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 0a 20 20  e->apHash[h];.  
6c90: 77 68 69 6c 65 28 20 28 2a 70 70 29 21 3d 70 50  while( (*pp)!=pP
6ca0: 61 67 65 20 29 7b 0a 20 20 20 20 70 70 20 3d 20  age ){.    pp = 
6cb0: 26 28 2a 70 70 29 2d 3e 70 4e 65 78 74 3b 0a 20  &(*pp)->pNext;. 
6cc0: 20 7d 0a 20 20 2a 70 70 20 3d 20 70 50 61 67 65   }.  *pp = pPage
6cd0: 2d 3e 70 4e 65 78 74 3b 0a 0a 20 20 68 20 3d 20  ->pNext;..  h = 
6ce0: 69 4e 65 77 25 70 43 61 63 68 65 2d 3e 6e 48 61  iNew%pCache->nHa
6cf0: 73 68 3b 0a 20 20 70 50 61 67 65 2d 3e 69 4b 65  sh;.  pPage->iKe
6d00: 79 20 3d 20 69 4e 65 77 3b 0a 20 20 70 50 61 67  y = iNew;.  pPag
6d10: 65 2d 3e 70 4e 65 78 74 20 3d 20 70 43 61 63 68  e->pNext = pCach
6d20: 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 0a 20 20  e->apHash[h];.  
6d30: 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68  pCache->apHash[h
6d40: 5d 20 3d 20 70 50 61 67 65 3b 0a 20 20 69 66 28  ] = pPage;.  if(
6d50: 20 69 4e 65 77 3e 70 43 61 63 68 65 2d 3e 69 4d   iNew>pCache->iM
6d60: 61 78 4b 65 79 20 29 7b 0a 20 20 20 20 70 43 61  axKey ){.    pCa
6d70: 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 3d 20 69  che->iMaxKey = i
6d80: 4e 65 77 3b 0a 20 20 7d 0a 0a 20 20 70 63 61 63  New;.  }..  pcac
6d90: 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 70 43  he1LeaveMutex(pC
6da0: 61 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 7d  ache->pGroup);.}
6db0: 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e  ../*.** Implemen
6dc0: 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71  tation of the sq
6dd0: 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78 54 72  lite3_pcache.xTr
6de0: 75 6e 63 61 74 65 20 6d 65 74 68 6f 64 2e 20 0a  uncate method. .
6df0: 2a 2a 0a 2a 2a 20 44 69 73 63 61 72 64 20 61 6c  **.** Discard al
6e00: 6c 20 75 6e 70 69 6e 6e 65 64 20 70 61 67 65 73  l unpinned pages
6e10: 20 69 6e 20 74 68 65 20 63 61 63 68 65 20 77 69   in the cache wi
6e20: 74 68 20 61 20 70 61 67 65 20 6e 75 6d 62 65 72  th a page number
6e30: 20 65 71 75 61 6c 20 74 6f 0a 2a 2a 20 6f 72 20   equal to.** or 
6e40: 67 72 65 61 74 65 72 20 74 68 61 6e 20 70 61 72  greater than par
6e50: 61 6d 65 74 65 72 20 69 4c 69 6d 69 74 2e 20 41  ameter iLimit. A
6e60: 6e 79 20 70 69 6e 6e 65 64 20 70 61 67 65 73 20  ny pinned pages 
6e70: 77 69 74 68 20 61 20 70 61 67 65 20 6e 75 6d 62  with a page numb
6e80: 65 72 0a 2a 2a 20 65 71 75 61 6c 20 74 6f 20 6f  er.** equal to o
6e90: 72 20 67 72 65 61 74 65 72 20 74 68 61 6e 20 69  r greater than i
6ea0: 4c 69 6d 69 74 20 61 72 65 20 69 6d 70 6c 69 63  Limit are implic
6eb0: 69 74 6c 79 20 75 6e 70 69 6e 6e 65 64 2e 0a 2a  itly unpinned..*
6ec0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63  /.static void pc
6ed0: 61 63 68 65 31 54 72 75 6e 63 61 74 65 28 73 71  ache1Truncate(sq
6ee0: 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70 2c  lite3_pcache *p,
6ef0: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4c   unsigned int iL
6f00: 69 6d 69 74 29 7b 0a 20 20 50 43 61 63 68 65 31  imit){.  PCache1
6f10: 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61 63   *pCache = (PCac
6f20: 68 65 31 20 2a 29 70 3b 0a 20 20 70 63 61 63 68  he1 *)p;.  pcach
6f30: 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70 43 61  e1EnterMutex(pCa
6f40: 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 20 20  che->pGroup);.  
6f50: 69 66 28 20 69 4c 69 6d 69 74 3c 3d 70 43 61 63  if( iLimit<=pCac
6f60: 68 65 2d 3e 69 4d 61 78 4b 65 79 20 29 7b 0a 20  he->iMaxKey ){. 
6f70: 20 20 20 70 63 61 63 68 65 31 54 72 75 6e 63 61     pcache1Trunca
6f80: 74 65 55 6e 73 61 66 65 28 70 43 61 63 68 65 2c  teUnsafe(pCache,
6f90: 20 69 4c 69 6d 69 74 29 3b 0a 20 20 20 20 70 43   iLimit);.    pC
6fa0: 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 3d 20  ache->iMaxKey = 
6fb0: 69 4c 69 6d 69 74 2d 31 3b 0a 20 20 7d 0a 20 20  iLimit-1;.  }.  
6fc0: 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65  pcache1LeaveMute
6fd0: 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70  x(pCache->pGroup
6fe0: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c  );.}../*.** Impl
6ff0: 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68  ementation of th
7000: 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  e sqlite3_pcache
7010: 2e 78 44 65 73 74 72 6f 79 20 6d 65 74 68 6f 64  .xDestroy method
7020: 2e 20 0a 2a 2a 0a 2a 2a 20 44 65 73 74 72 6f 79  . .**.** Destroy
7030: 20 61 20 63 61 63 68 65 20 61 6c 6c 6f 63 61 74   a cache allocat
7040: 65 64 20 75 73 69 6e 67 20 70 63 61 63 68 65 31  ed using pcache1
7050: 43 72 65 61 74 65 28 29 2e 0a 2a 2f 0a 73 74 61  Create()..*/.sta
7060: 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 31  tic void pcache1
7070: 44 65 73 74 72 6f 79 28 73 71 6c 69 74 65 33 5f  Destroy(sqlite3_
7080: 70 63 61 63 68 65 20 2a 70 29 7b 0a 20 20 50 43  pcache *p){.  PC
7090: 61 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20  ache1 *pCache = 
70a0: 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20 20  (PCache1 *)p;.  
70b0: 50 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 20 3d  PGroup *pGroup =
70c0: 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b   pCache->pGroup;
70d0: 0a 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68  .  assert( pCach
70e0: 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 7c 7c  e->bPurgeable ||
70f0: 20 28 70 43 61 63 68 65 2d 3e 6e 4d 61 78 3d 3d   (pCache->nMax==
7100: 30 20 26 26 20 70 43 61 63 68 65 2d 3e 6e 4d 69  0 && pCache->nMi
7110: 6e 3d 3d 30 29 20 29 3b 0a 20 20 70 63 61 63 68  n==0) );.  pcach
7120: 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70 47 72  e1EnterMutex(pGr
7130: 6f 75 70 29 3b 0a 20 20 70 63 61 63 68 65 31 54  oup);.  pcache1T
7140: 72 75 6e 63 61 74 65 55 6e 73 61 66 65 28 70 43  runcateUnsafe(pC
7150: 61 63 68 65 2c 20 30 29 3b 0a 20 20 70 47 72 6f  ache, 0);.  pGro
7160: 75 70 2d 3e 6e 4d 61 78 50 61 67 65 20 2d 3d 20  up->nMaxPage -= 
7170: 70 43 61 63 68 65 2d 3e 6e 4d 61 78 3b 0a 20 20  pCache->nMax;.  
7180: 70 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67 65  pGroup->nMinPage
7190: 20 2d 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 69 6e   -= pCache->nMin
71a0: 3b 0a 20 20 70 47 72 6f 75 70 2d 3e 6d 78 50 69  ;.  pGroup->mxPi
71b0: 6e 6e 65 64 20 3d 20 70 47 72 6f 75 70 2d 3e 6e  nned = pGroup->n
71c0: 4d 61 78 50 61 67 65 20 2b 20 31 30 20 2d 20 70  MaxPage + 10 - p
71d0: 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67 65 3b  Group->nMinPage;
71e0: 0a 20 20 70 63 61 63 68 65 31 45 6e 66 6f 72 63  .  pcache1Enforc
71f0: 65 4d 61 78 50 61 67 65 28 70 47 72 6f 75 70 29  eMaxPage(pGroup)
7200: 3b 0a 20 20 70 63 61 63 68 65 31 4c 65 61 76 65  ;.  pcache1Leave
7210: 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b 0a 20  Mutex(pGroup);. 
7220: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43   sqlite3_free(pC
7230: 61 63 68 65 2d 3e 61 70 48 61 73 68 29 3b 0a 20  ache->apHash);. 
7240: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43   sqlite3_free(pC
7250: 61 63 68 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  ache);.}../*.** 
7260: 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73  This function is
7270: 20 63 61 6c 6c 65 64 20 64 75 72 69 6e 67 20 69   called during i
7280: 6e 69 74 69 61 6c 69 7a 61 74 69 6f 6e 20 28 73  nitialization (s
7290: 71 6c 69 74 65 33 5f 69 6e 69 74 69 61 6c 69 7a  qlite3_initializ
72a0: 65 28 29 29 20 74 6f 0a 2a 2a 20 69 6e 73 74 61  e()) to.** insta
72b0: 6c 6c 20 74 68 65 20 64 65 66 61 75 6c 74 20 70  ll the default p
72c0: 6c 75 67 67 61 62 6c 65 20 63 61 63 68 65 20 6d  luggable cache m
72d0: 6f 64 75 6c 65 2c 20 61 73 73 75 6d 69 6e 67 20  odule, assuming 
72e0: 74 68 65 20 75 73 65 72 20 68 61 73 20 6e 6f 74  the user has not
72f0: 0a 2a 2a 20 61 6c 72 65 61 64 79 20 70 72 6f 76  .** already prov
7300: 69 64 65 64 20 61 6e 20 61 6c 74 65 72 6e 61 74  ided an alternat
7310: 69 76 65 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c  ive..*/.void sql
7320: 69 74 65 33 50 43 61 63 68 65 53 65 74 44 65 66  ite3PCacheSetDef
7330: 61 75 6c 74 28 76 6f 69 64 29 7b 0a 20 20 73 74  ault(void){.  st
7340: 61 74 69 63 20 63 6f 6e 73 74 20 73 71 6c 69 74  atic const sqlit
7350: 65 33 5f 70 63 61 63 68 65 5f 6d 65 74 68 6f 64  e3_pcache_method
7360: 73 32 20 64 65 66 61 75 6c 74 4d 65 74 68 6f 64  s2 defaultMethod
7370: 73 20 3d 20 7b 0a 20 20 20 20 30 2c 20 20 20 20  s = {.    0,    
7380: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7390: 20 20 20 2f 2a 20 70 41 72 67 20 2a 2f 0a 20 20     /* pArg */.  
73a0: 20 20 70 63 61 63 68 65 31 49 6e 69 74 2c 20 20    pcache1Init,  
73b0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 49             /* xI
73c0: 6e 69 74 20 2a 2f 0a 20 20 20 20 70 63 61 63 68  nit */.    pcach
73d0: 65 31 53 68 75 74 64 6f 77 6e 2c 20 20 20 20 20  e1Shutdown,     
73e0: 20 20 20 20 2f 2a 20 78 53 68 75 74 64 6f 77 6e      /* xShutdown
73f0: 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31 43   */.    pcache1C
7400: 72 65 61 74 65 2c 20 20 20 20 20 20 20 20 20 20  reate,          
7410: 20 2f 2a 20 78 43 72 65 61 74 65 20 2a 2f 0a 20   /* xCreate */. 
7420: 20 20 20 70 63 61 63 68 65 31 43 61 63 68 65 73     pcache1Caches
7430: 69 7a 65 2c 20 20 20 20 20 20 20 20 2f 2a 20 78  ize,        /* x
7440: 43 61 63 68 65 73 69 7a 65 20 2a 2f 0a 20 20 20  Cachesize */.   
7450: 20 70 63 61 63 68 65 31 50 61 67 65 63 6f 75 6e   pcache1Pagecoun
7460: 74 2c 20 20 20 20 20 20 20 20 2f 2a 20 78 50 61  t,        /* xPa
7470: 67 65 63 6f 75 6e 74 20 2a 2f 0a 20 20 20 20 70  gecount */.    p
7480: 63 61 63 68 65 31 46 65 74 63 68 2c 20 20 20 20  cache1Fetch,    
7490: 20 20 20 20 20 20 20 20 2f 2a 20 78 46 65 74 63          /* xFetc
74a0: 68 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31  h */.    pcache1
74b0: 55 6e 70 69 6e 2c 20 20 20 20 20 20 20 20 20 20  Unpin,          
74c0: 20 20 2f 2a 20 78 55 6e 70 69 6e 20 2a 2f 0a 20    /* xUnpin */. 
74d0: 20 20 20 70 63 61 63 68 65 31 52 65 6b 65 79 2c     pcache1Rekey,
74e0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
74f0: 52 65 6b 65 79 20 2a 2f 0a 20 20 20 20 70 63 61  Rekey */.    pca
7500: 63 68 65 31 54 72 75 6e 63 61 74 65 2c 20 20 20  che1Truncate,   
7510: 20 20 20 20 20 20 2f 2a 20 78 54 72 75 6e 63 61        /* xTrunca
7520: 74 65 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65  te */.    pcache
7530: 31 44 65 73 74 72 6f 79 20 20 20 20 20 20 20 20  1Destroy        
7540: 20 20 20 2f 2a 20 78 44 65 73 74 72 6f 79 20 2a     /* xDestroy *
7550: 2f 0a 20 20 7d 3b 0a 20 20 73 71 6c 69 74 65 33  /.  };.  sqlite3
7560: 5f 63 6f 6e 66 69 67 28 53 51 4c 49 54 45 5f 43  _config(SQLITE_C
7570: 4f 4e 46 49 47 5f 50 43 41 43 48 45 32 2c 20 26  ONFIG_PCACHE2, &
7580: 64 65 66 61 75 6c 74 4d 65 74 68 6f 64 73 29 3b  defaultMethods);
7590: 0a 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54  .}..#ifdef SQLIT
75a0: 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f  E_ENABLE_MEMORY_
75b0: 4d 41 4e 41 47 45 4d 45 4e 54 0a 2f 2a 0a 2a 2a  MANAGEMENT./*.**
75c0: 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   This function i
75d0: 73 20 63 61 6c 6c 65 64 20 74 6f 20 66 72 65 65  s called to free
75e0: 20 73 75 70 65 72 66 6c 75 6f 75 73 20 64 79 6e   superfluous dyn
75f0: 61 6d 69 63 61 6c 6c 79 20 61 6c 6c 6f 63 61 74  amically allocat
7600: 65 64 20 6d 65 6d 6f 72 79 0a 2a 2a 20 68 65 6c  ed memory.** hel
7610: 64 20 62 79 20 74 68 65 20 70 61 67 65 72 20 73  d by the pager s
7620: 79 73 74 65 6d 2e 20 4d 65 6d 6f 72 79 20 69 6e  ystem. Memory in
7630: 20 75 73 65 20 62 79 20 61 6e 79 20 53 51 4c 69   use by any SQLi
7640: 74 65 20 70 61 67 65 72 20 61 6c 6c 6f 63 61 74  te pager allocat
7650: 65 64 0a 2a 2a 20 62 79 20 74 68 65 20 63 75 72  ed.** by the cur
7660: 72 65 6e 74 20 74 68 72 65 61 64 20 6d 61 79 20  rent thread may 
7670: 62 65 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  be sqlite3_free(
7680: 29 65 64 2e 0a 2a 2a 0a 2a 2a 20 6e 52 65 71 20  )ed..**.** nReq 
7690: 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  is the number of
76a0: 20 62 79 74 65 73 20 6f 66 20 6d 65 6d 6f 72 79   bytes of memory
76b0: 20 72 65 71 75 69 72 65 64 2e 20 4f 6e 63 65 20   required. Once 
76c0: 74 68 69 73 20 6d 75 63 68 20 68 61 73 0a 2a 2a  this much has.**
76d0: 20 62 65 65 6e 20 72 65 6c 65 61 73 65 64 2c 20   been released, 
76e0: 74 68 65 20 66 75 6e 63 74 69 6f 6e 20 72 65 74  the function ret
76f0: 75 72 6e 73 2e 20 54 68 65 20 72 65 74 75 72 6e  urns. The return
7700: 20 76 61 6c 75 65 20 69 73 20 74 68 65 20 74 6f   value is the to
7710: 74 61 6c 20 6e 75 6d 62 65 72 20 0a 2a 2a 20 6f  tal number .** o
7720: 66 20 62 79 74 65 73 20 6f 66 20 6d 65 6d 6f 72  f bytes of memor
7730: 79 20 72 65 6c 65 61 73 65 64 2e 0a 2a 2f 0a 69  y released..*/.i
7740: 6e 74 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  nt sqlite3Pcache
7750: 52 65 6c 65 61 73 65 4d 65 6d 6f 72 79 28 69 6e  ReleaseMemory(in
7760: 74 20 6e 52 65 71 29 7b 0a 20 20 69 6e 74 20 6e  t nReq){.  int n
7770: 46 72 65 65 20 3d 20 30 3b 0a 20 20 61 73 73 65  Free = 0;.  asse
7780: 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65  rt( sqlite3_mute
7790: 78 5f 6e 6f 74 68 65 6c 64 28 70 63 61 63 68 65  x_notheld(pcache
77a0: 31 2e 67 72 70 2e 6d 75 74 65 78 29 20 29 3b 0a  1.grp.mutex) );.
77b0: 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65    assert( sqlite
77c0: 33 5f 6d 75 74 65 78 5f 6e 6f 74 68 65 6c 64 28  3_mutex_notheld(
77d0: 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29 20 29  pcache1.mutex) )
77e0: 3b 0a 20 20 69 66 28 20 70 63 61 63 68 65 31 2e  ;.  if( pcache1.
77f0: 70 53 74 61 72 74 3d 3d 30 20 29 7b 0a 20 20 20  pStart==0 ){.   
7800: 20 50 67 48 64 72 31 20 2a 70 3b 0a 20 20 20 20   PgHdr1 *p;.    
7810: 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65  pcache1EnterMute
7820: 78 28 26 70 63 61 63 68 65 31 2e 67 72 70 29 3b  x(&pcache1.grp);
7830: 0a 20 20 20 20 77 68 69 6c 65 28 20 28 6e 52 65  .    while( (nRe
7840: 71 3c 30 20 7c 7c 20 6e 46 72 65 65 3c 6e 52 65  q<0 || nFree<nRe
7850: 71 29 20 26 26 20 28 28 70 3d 70 63 61 63 68 65  q) && ((p=pcache
7860: 31 2e 67 72 70 2e 70 4c 72 75 54 61 69 6c 29 21  1.grp.pLruTail)!
7870: 3d 30 29 20 29 7b 0a 20 20 20 20 20 20 6e 46 72  =0) ){.      nFr
7880: 65 65 20 2b 3d 20 70 63 61 63 68 65 31 4d 65 6d  ee += pcache1Mem
7890: 53 69 7a 65 28 70 2d 3e 70 61 67 65 2e 70 42 75  Size(p->page.pBu
78a0: 66 29 3b 0a 23 69 66 64 65 66 20 53 51 4c 49 54  f);.#ifdef SQLIT
78b0: 45 5f 50 43 41 43 48 45 5f 53 45 50 41 52 41 54  E_PCACHE_SEPARAT
78c0: 45 5f 48 45 41 44 45 52 0a 20 20 20 20 20 20 6e  E_HEADER.      n
78d0: 46 72 65 65 20 2b 3d 20 73 71 6c 69 74 65 33 4d  Free += sqlite3M
78e0: 65 6d 53 69 7a 65 28 70 29 3b 0a 23 65 6e 64 69  emSize(p);.#endi
78f0: 66 0a 20 20 20 20 20 20 70 63 61 63 68 65 31 50  f.      pcache1P
7900: 69 6e 50 61 67 65 28 70 29 3b 0a 20 20 20 20 20  inPage(p);.     
7910: 20 70 63 61 63 68 65 31 52 65 6d 6f 76 65 46 72   pcache1RemoveFr
7920: 6f 6d 48 61 73 68 28 70 29 3b 0a 20 20 20 20 20  omHash(p);.     
7930: 20 70 63 61 63 68 65 31 46 72 65 65 50 61 67 65   pcache1FreePage
7940: 28 70 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70  (p);.    }.    p
7950: 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78  cache1LeaveMutex
7960: 28 26 70 63 61 63 68 65 31 2e 67 72 70 29 3b 0a  (&pcache1.grp);.
7970: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 6e 46 72    }.  return nFr
7980: 65 65 3b 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a 20  ee;.}.#endif /* 
7990: 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45  SQLITE_ENABLE_ME
79a0: 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 20  MORY_MANAGEMENT 
79b0: 2a 2f 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54  */..#ifdef SQLIT
79c0: 45 5f 54 45 53 54 0a 2f 2a 0a 2a 2a 20 54 68 69  E_TEST./*.** Thi
79d0: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 75 73  s function is us
79e0: 65 64 20 62 79 20 74 65 73 74 20 70 72 6f 63 65  ed by test proce
79f0: 64 75 72 65 73 20 74 6f 20 69 6e 73 70 65 63 74  dures to inspect
7a00: 20 74 68 65 20 69 6e 74 65 72 6e 61 6c 20 73 74   the internal st
7a10: 61 74 65 0a 2a 2a 20 6f 66 20 74 68 65 20 67 6c  ate.** of the gl
7a20: 6f 62 61 6c 20 63 61 63 68 65 2e 0a 2a 2f 0a 76  obal cache..*/.v
7a30: 6f 69 64 20 73 71 6c 69 74 65 33 50 63 61 63 68  oid sqlite3Pcach
7a40: 65 53 74 61 74 73 28 0a 20 20 69 6e 74 20 2a 70  eStats(.  int *p
7a50: 6e 43 75 72 72 65 6e 74 2c 20 20 20 20 20 20 2f  nCurrent,      /
7a60: 2a 20 4f 55 54 3a 20 54 6f 74 61 6c 20 6e 75 6d  * OUT: Total num
7a70: 62 65 72 20 6f 66 20 70 61 67 65 73 20 63 61 63  ber of pages cac
7a80: 68 65 64 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e  hed */.  int *pn
7a90: 4d 61 78 2c 20 20 20 20 20 20 20 20 20 20 2f 2a  Max,          /*
7aa0: 20 4f 55 54 3a 20 47 6c 6f 62 61 6c 20 6d 61 78   OUT: Global max
7ab0: 69 6d 75 6d 20 63 61 63 68 65 20 73 69 7a 65 20  imum cache size 
7ac0: 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 4d 69 6e 2c  */.  int *pnMin,
7ad0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
7ae0: 3a 20 53 75 6d 20 6f 66 20 50 43 61 63 68 65 31  : Sum of PCache1
7af0: 2e 6e 4d 69 6e 20 66 6f 72 20 70 75 72 67 65 61  .nMin for purgea
7b00: 62 6c 65 20 63 61 63 68 65 73 20 2a 2f 0a 20 20  ble caches */.  
7b10: 69 6e 74 20 2a 70 6e 52 65 63 79 63 6c 61 62 6c  int *pnRecyclabl
7b20: 65 20 20 20 20 2f 2a 20 4f 55 54 3a 20 54 6f 74  e    /* OUT: Tot
7b30: 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67  al number of pag
7b40: 65 73 20 61 76 61 69 6c 61 62 6c 65 20 66 6f 72  es available for
7b50: 20 72 65 63 79 63 6c 69 6e 67 20 2a 2f 0a 29 7b   recycling */.){
7b60: 0a 20 20 50 67 48 64 72 31 20 2a 70 3b 0a 20 20  .  PgHdr1 *p;.  
7b70: 69 6e 74 20 6e 52 65 63 79 63 6c 61 62 6c 65 20  int nRecyclable 
7b80: 3d 20 30 3b 0a 20 20 66 6f 72 28 70 3d 70 63 61  = 0;.  for(p=pca
7b90: 63 68 65 31 2e 67 72 70 2e 70 4c 72 75 48 65 61  che1.grp.pLruHea
7ba0: 64 3b 20 70 3b 20 70 3d 70 2d 3e 70 4c 72 75 4e  d; p; p=p->pLruN
7bb0: 65 78 74 29 7b 0a 20 20 20 20 6e 52 65 63 79 63  ext){.    nRecyc
7bc0: 6c 61 62 6c 65 2b 2b 3b 0a 20 20 7d 0a 20 20 2a  lable++;.  }.  *
7bd0: 70 6e 43 75 72 72 65 6e 74 20 3d 20 70 63 61 63  pnCurrent = pcac
7be0: 68 65 31 2e 67 72 70 2e 6e 43 75 72 72 65 6e 74  he1.grp.nCurrent
7bf0: 50 61 67 65 3b 0a 20 20 2a 70 6e 4d 61 78 20 3d  Page;.  *pnMax =
7c00: 20 70 63 61 63 68 65 31 2e 67 72 70 2e 6e 4d 61   pcache1.grp.nMa
7c10: 78 50 61 67 65 3b 0a 20 20 2a 70 6e 4d 69 6e 20  xPage;.  *pnMin 
7c20: 3d 20 70 63 61 63 68 65 31 2e 67 72 70 2e 6e 4d  = pcache1.grp.nM
7c30: 69 6e 50 61 67 65 3b 0a 20 20 2a 70 6e 52 65 63  inPage;.  *pnRec
7c40: 79 63 6c 61 62 6c 65 20 3d 20 6e 52 65 63 79 63  yclable = nRecyc
7c50: 6c 61 62 6c 65 3b 0a 7d 0a 23 65 6e 64 69 66 0a  lable;.}.#endif.