/ Hex Artifact Content
Login

Artifact e1aaa3bc9bbfd8b0bc391ca731f5f8185467375d:


0000: 2f 2a 0a 2a 2a 20 32 30 30 38 20 4e 6f 76 65 6d  /*.** 2008 Novem
0010: 62 65 72 20 30 35 0a 2a 2a 0a 2a 2a 20 54 68 65  ber 05.**.** The
0020: 20 61 75 74 68 6f 72 20 64 69 73 63 6c 61 69 6d   author disclaim
0030: 73 20 63 6f 70 79 72 69 67 68 74 20 74 6f 20 74  s copyright to t
0040: 68 69 73 20 73 6f 75 72 63 65 20 63 6f 64 65 2e  his source code.
0050: 20 20 49 6e 20 70 6c 61 63 65 20 6f 66 0a 2a 2a    In place of.**
0060: 20 61 20 6c 65 67 61 6c 20 6e 6f 74 69 63 65 2c   a legal notice,
0070: 20 68 65 72 65 20 69 73 20 61 20 62 6c 65 73 73   here is a bless
0080: 69 6e 67 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 4d 61  ing:.**.**    Ma
0090: 79 20 79 6f 75 20 64 6f 20 67 6f 6f 64 20 61 6e  y you do good an
00a0: 64 20 6e 6f 74 20 65 76 69 6c 2e 0a 2a 2a 20 20  d not evil..**  
00b0: 20 20 4d 61 79 20 79 6f 75 20 66 69 6e 64 20 66    May you find f
00c0: 6f 72 67 69 76 65 6e 65 73 73 20 66 6f 72 20 79  orgiveness for y
00d0: 6f 75 72 73 65 6c 66 20 61 6e 64 20 66 6f 72 67  ourself and forg
00e0: 69 76 65 20 6f 74 68 65 72 73 2e 0a 2a 2a 20 20  ive others..**  
00f0: 20 20 4d 61 79 20 79 6f 75 20 73 68 61 72 65 20    May you share 
0100: 66 72 65 65 6c 79 2c 20 6e 65 76 65 72 20 74 61  freely, never ta
0110: 6b 69 6e 67 20 6d 6f 72 65 20 74 68 61 6e 20 79  king more than y
0120: 6f 75 20 67 69 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a  ou give..**.****
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 2a 2a 2a 2a 2a 0a 2a 2a 0a 2a 2a 20 54 68 69 73  *****.**.** This
0180: 20 66 69 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 73   file implements
0190: 20 74 68 65 20 64 65 66 61 75 6c 74 20 70 61 67   the default pag
01a0: 65 20 63 61 63 68 65 20 69 6d 70 6c 65 6d 65 6e  e cache implemen
01b0: 74 61 74 69 6f 6e 20 28 74 68 65 0a 2a 2a 20 73  tation (the.** s
01c0: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 69 6e  qlite3_pcache in
01d0: 74 65 72 66 61 63 65 29 2e 20 49 74 20 61 6c 73  terface). It als
01e0: 6f 20 63 6f 6e 74 61 69 6e 73 20 70 61 72 74 20  o contains part 
01f0: 6f 66 20 74 68 65 20 69 6d 70 6c 65 6d 65 6e 74  of the implement
0200: 61 74 69 6f 6e 0a 2a 2a 20 6f 66 20 74 68 65 20  ation.** of the 
0210: 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41  SQLITE_CONFIG_PA
0220: 47 45 43 41 43 48 45 20 61 6e 64 20 73 71 6c 69  GECACHE and sqli
0230: 74 65 33 5f 72 65 6c 65 61 73 65 5f 6d 65 6d 6f  te3_release_memo
0240: 72 79 28 29 20 66 65 61 74 75 72 65 73 2e 0a 2a  ry() features..*
0250: 2a 20 49 66 20 74 68 65 20 64 65 66 61 75 6c 74  * If the default
0260: 20 70 61 67 65 20 63 61 63 68 65 20 69 6d 70 6c   page cache impl
0270: 65 6d 65 6e 74 61 74 69 6f 6e 20 69 73 20 6f 76  ementation is ov
0280: 65 72 72 69 64 65 6e 2c 20 74 68 65 6e 20 6e 65  erriden, then ne
0290: 69 74 68 65 72 20 6f 66 0a 2a 2a 20 74 68 65 73  ither of.** thes
02a0: 65 20 74 77 6f 20 66 65 61 74 75 72 65 73 20 61  e two features a
02b0: 72 65 20 61 76 61 69 6c 61 62 6c 65 2e 0a 2a 2f  re available..*/
02c0: 0a 0a 23 69 6e 63 6c 75 64 65 20 22 73 71 6c 69  ..#include "sqli
02d0: 74 65 49 6e 74 2e 68 22 0a 0a 74 79 70 65 64 65  teInt.h"..typede
02e0: 66 20 73 74 72 75 63 74 20 50 43 61 63 68 65 31  f struct PCache1
02f0: 20 50 43 61 63 68 65 31 3b 0a 74 79 70 65 64 65   PCache1;.typede
0300: 66 20 73 74 72 75 63 74 20 50 67 48 64 72 31 20  f struct PgHdr1 
0310: 50 67 48 64 72 31 3b 0a 74 79 70 65 64 65 66 20  PgHdr1;.typedef 
0320: 73 74 72 75 63 74 20 50 67 46 72 65 65 73 6c 6f  struct PgFreeslo
0330: 74 20 50 67 46 72 65 65 73 6c 6f 74 3b 0a 74 79  t PgFreeslot;.ty
0340: 70 65 64 65 66 20 73 74 72 75 63 74 20 50 47 72  pedef struct PGr
0350: 6f 75 70 20 50 47 72 6f 75 70 3b 0a 0a 2f 2a 20  oup PGroup;../* 
0360: 45 61 63 68 20 70 61 67 65 20 63 61 63 68 65 20  Each page cache 
0370: 28 6f 72 20 50 43 61 63 68 65 29 20 62 65 6c 6f  (or PCache) belo
0380: 6e 67 73 20 74 6f 20 61 20 50 47 72 6f 75 70 2e  ngs to a PGroup.
0390: 20 20 41 20 50 47 72 6f 75 70 20 69 73 20 61 20    A PGroup is a 
03a0: 73 65 74 20 0a 2a 2a 20 6f 66 20 6f 6e 65 20 6f  set .** of one o
03b0: 72 20 6d 6f 72 65 20 50 43 61 63 68 65 73 20 74  r more PCaches t
03c0: 68 61 74 20 61 72 65 20 61 62 6c 65 20 74 6f 20  hat are able to 
03d0: 72 65 63 79 63 6c 65 20 65 61 63 68 20 6f 74 68  recycle each oth
03e0: 65 72 73 20 75 6e 70 69 6e 6e 65 64 0a 2a 2a 20  ers unpinned.** 
03f0: 70 61 67 65 73 20 77 68 65 6e 20 74 68 65 79 20  pages when they 
0400: 61 72 65 20 75 6e 64 65 72 20 6d 65 6d 6f 72 79  are under memory
0410: 20 70 72 65 73 73 75 72 65 2e 20 20 41 20 50 47   pressure.  A PG
0420: 72 6f 75 70 20 69 73 20 61 6e 20 69 6e 73 74 61  roup is an insta
0430: 6e 63 65 20 6f 66 0a 2a 2a 20 74 68 65 20 66 6f  nce of.** the fo
0440: 6c 6c 6f 77 69 6e 67 20 6f 62 6a 65 63 74 2e 0a  llowing object..
0450: 2a 2a 0a 2a 2a 20 54 68 69 73 20 70 61 67 65 20  **.** This page 
0460: 63 61 63 68 65 20 69 6d 70 6c 65 6d 65 6e 74 61  cache implementa
0470: 74 69 6f 6e 20 77 6f 72 6b 73 20 69 6e 20 6f 6e  tion works in on
0480: 65 20 6f 66 20 74 77 6f 20 6d 6f 64 65 73 3a 0a  e of two modes:.
0490: 2a 2a 0a 2a 2a 20 20 20 28 31 29 20 20 45 76 65  **.**   (1)  Eve
04a0: 72 79 20 50 43 61 63 68 65 20 69 73 20 74 68 65  ry PCache is the
04b0: 20 73 6f 6c 65 20 6d 65 6d 62 65 72 20 6f 66 20   sole member of 
04c0: 69 74 73 20 6f 77 6e 20 50 47 72 6f 75 70 2e 20  its own PGroup. 
04d0: 20 54 68 65 72 65 20 69 73 0a 2a 2a 20 20 20 20   There is.**    
04e0: 20 20 20 20 6f 6e 65 20 50 47 72 6f 75 70 20 70      one PGroup p
04f0: 65 72 20 50 43 61 63 68 65 2e 0a 2a 2a 0a 2a 2a  er PCache..**.**
0500: 20 20 20 28 32 29 20 20 54 68 65 72 65 20 69 73     (2)  There is
0510: 20 61 20 73 69 6e 67 6c 65 20 67 6c 6f 62 61 6c   a single global
0520: 20 50 47 72 6f 75 70 20 74 68 61 74 20 61 6c 6c   PGroup that all
0530: 20 50 43 61 63 68 65 73 20 61 72 65 20 61 20 6d   PCaches are a m
0540: 65 6d 62 65 72 0a 2a 2a 20 20 20 20 20 20 20 20  ember.**        
0550: 6f 66 2e 0a 2a 2a 0a 2a 2a 20 4d 6f 64 65 20 31  of..**.** Mode 1
0560: 20 75 73 65 73 20 6d 6f 72 65 20 6d 65 6d 6f 72   uses more memor
0570: 79 20 28 73 69 6e 63 65 20 50 43 61 63 68 65 20  y (since PCache 
0580: 69 6e 73 74 61 6e 63 65 73 20 61 72 65 20 6e 6f  instances are no
0590: 74 20 61 62 6c 65 20 74 6f 20 72 6f 62 0a 2a 2a  t able to rob.**
05a0: 20 75 6e 75 73 65 64 20 70 61 67 65 73 20 66 72   unused pages fr
05b0: 6f 6d 20 6f 74 68 65 72 20 50 43 61 63 68 65 73  om other PCaches
05c0: 29 20 62 75 74 20 69 74 20 61 6c 73 6f 20 6f 70  ) but it also op
05d0: 65 72 61 74 65 73 20 77 69 74 68 6f 75 74 20 61  erates without a
05e0: 20 6d 75 74 65 78 2c 0a 2a 2a 20 61 6e 64 20 69   mutex,.** and i
05f0: 73 20 74 68 65 72 65 66 6f 72 65 20 6f 66 74 65  s therefore ofte
0600: 6e 20 66 61 73 74 65 72 2e 20 20 4d 6f 64 65 20  n faster.  Mode 
0610: 32 20 72 65 71 75 69 72 65 73 20 61 20 6d 75 74  2 requires a mut
0620: 65 78 20 69 6e 20 6f 72 64 65 72 20 74 6f 20 62  ex in order to b
0630: 65 0a 2a 2a 20 74 68 72 65 61 64 73 61 66 65 2c  e.** threadsafe,
0640: 20 62 75 74 20 69 73 20 61 62 6c 65 20 72 65 63   but is able rec
0650: 79 63 6c 65 20 70 61 67 65 73 20 6d 6f 72 65 20  ycle pages more 
0660: 65 66 66 69 63 69 65 6e 74 2e 0a 2a 2a 0a 2a 2a  efficient..**.**
0670: 20 46 6f 72 20 6d 6f 64 65 20 28 31 29 2c 20 50   For mode (1), P
0680: 47 72 6f 75 70 2e 6d 75 74 65 78 20 69 73 20 4e  Group.mutex is N
0690: 55 4c 4c 2e 20 20 46 6f 72 20 6d 6f 64 65 20 28  ULL.  For mode (
06a0: 32 29 20 74 68 65 72 65 20 69 73 20 6f 6e 6c 79  2) there is only
06b0: 20 61 20 73 69 6e 67 6c 65 0a 2a 2a 20 50 47 72   a single.** PGr
06c0: 6f 75 70 20 77 68 69 63 68 20 69 73 20 74 68 65  oup which is the
06d0: 20 70 63 61 63 68 65 31 2e 67 72 70 20 67 6c 6f   pcache1.grp glo
06e0: 62 61 6c 20 76 61 72 69 61 62 6c 65 20 61 6e 64  bal variable and
06f0: 20 69 74 73 20 6d 75 74 65 78 20 69 73 0a 2a 2a   its mutex is.**
0700: 20 53 51 4c 49 54 45 5f 4d 55 54 45 58 5f 53 54   SQLITE_MUTEX_ST
0710: 41 54 49 43 5f 4c 52 55 2e 0a 2a 2f 0a 73 74 72  ATIC_LRU..*/.str
0720: 75 63 74 20 50 47 72 6f 75 70 20 7b 0a 20 20 73  uct PGroup {.  s
0730: 71 6c 69 74 65 33 5f 6d 75 74 65 78 20 2a 6d 75  qlite3_mutex *mu
0740: 74 65 78 3b 20 20 20 20 20 20 20 20 20 20 2f 2a  tex;          /*
0750: 20 4d 55 54 45 58 5f 53 54 41 54 49 43 5f 4c 52   MUTEX_STATIC_LR
0760: 55 20 6f 72 20 4e 55 4c 4c 20 2a 2f 0a 20 20 75  U or NULL */.  u
0770: 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 4d 61 78  nsigned int nMax
0780: 50 61 67 65 3b 20 20 20 20 20 20 20 20 20 2f 2a  Page;         /*
0790: 20 53 75 6d 20 6f 66 20 6e 4d 61 78 20 66 6f 72   Sum of nMax for
07a0: 20 70 75 72 67 65 61 62 6c 65 20 63 61 63 68 65   purgeable cache
07b0: 73 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20  s */.  unsigned 
07c0: 69 6e 74 20 6e 4d 69 6e 50 61 67 65 3b 20 20 20  int nMinPage;   
07d0: 20 20 20 20 20 20 2f 2a 20 53 75 6d 20 6f 66 20        /* Sum of 
07e0: 6e 4d 69 6e 20 66 6f 72 20 70 75 72 67 65 61 62  nMin for purgeab
07f0: 6c 65 20 63 61 63 68 65 73 20 2a 2f 0a 20 20 75  le caches */.  u
0800: 6e 73 69 67 6e 65 64 20 69 6e 74 20 6d 78 50 69  nsigned int mxPi
0810: 6e 6e 65 64 3b 20 20 20 20 20 20 20 20 20 2f 2a  nned;         /*
0820: 20 6e 4d 61 78 70 61 67 65 20 2b 20 31 30 20 2d   nMaxpage + 10 -
0830: 20 6e 4d 69 6e 50 61 67 65 20 2a 2f 0a 20 20 75   nMinPage */.  u
0840: 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 43 75 72  nsigned int nCur
0850: 72 65 6e 74 50 61 67 65 3b 20 20 20 20 20 2f 2a  rentPage;     /*
0860: 20 4e 75 6d 62 65 72 20 6f 66 20 70 75 72 67 65   Number of purge
0870: 61 62 6c 65 20 70 61 67 65 73 20 61 6c 6c 6f 63  able pages alloc
0880: 61 74 65 64 20 2a 2f 0a 20 20 50 67 48 64 72 31  ated */.  PgHdr1
0890: 20 2a 70 4c 72 75 48 65 61 64 2c 20 2a 70 4c 72   *pLruHead, *pLr
08a0: 75 54 61 69 6c 3b 20 20 20 2f 2a 20 4c 52 55 20  uTail;   /* LRU 
08b0: 6c 69 73 74 20 6f 66 20 75 6e 70 69 6e 6e 65 64  list of unpinned
08c0: 20 70 61 67 65 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a   pages */.};../*
08d0: 20 45 61 63 68 20 70 61 67 65 20 63 61 63 68 65   Each page cache
08e0: 20 69 73 20 61 6e 20 69 6e 73 74 61 6e 63 65 20   is an instance 
08f0: 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  of the following
0900: 20 6f 62 6a 65 63 74 2e 20 20 45 76 65 72 79 0a   object.  Every.
0910: 2a 2a 20 6f 70 65 6e 20 64 61 74 61 62 61 73 65  ** open database
0920: 20 66 69 6c 65 20 28 69 6e 63 6c 75 64 69 6e 67   file (including
0930: 20 65 61 63 68 20 69 6e 2d 6d 65 6d 6f 72 79 20   each in-memory 
0940: 64 61 74 61 62 61 73 65 20 61 6e 64 20 65 61 63  database and eac
0950: 68 0a 2a 2a 20 74 65 6d 70 6f 72 61 72 79 20 6f  h.** temporary o
0960: 72 20 74 72 61 6e 73 69 65 6e 74 20 64 61 74 61  r transient data
0970: 62 61 73 65 29 20 68 61 73 20 61 20 73 69 6e 67  base) has a sing
0980: 6c 65 20 70 61 67 65 20 63 61 63 68 65 20 77 68  le page cache wh
0990: 69 63 68 0a 2a 2a 20 69 73 20 61 6e 20 69 6e 73  ich.** is an ins
09a0: 74 61 6e 63 65 20 6f 66 20 74 68 69 73 20 6f 62  tance of this ob
09b0: 6a 65 63 74 2e 0a 2a 2a 0a 2a 2a 20 50 6f 69 6e  ject..**.** Poin
09c0: 74 65 72 73 20 74 6f 20 73 74 72 75 63 74 75 72  ters to structur
09d0: 65 73 20 6f 66 20 74 68 69 73 20 74 79 70 65 20  es of this type 
09e0: 61 72 65 20 63 61 73 74 20 61 6e 64 20 72 65 74  are cast and ret
09f0: 75 72 6e 65 64 20 61 73 20 0a 2a 2a 20 6f 70 61  urned as .** opa
0a00: 71 75 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63  que sqlite3_pcac
0a10: 68 65 2a 20 68 61 6e 64 6c 65 73 2e 0a 2a 2f 0a  he* handles..*/.
0a20: 73 74 72 75 63 74 20 50 43 61 63 68 65 31 20 7b  struct PCache1 {
0a30: 0a 20 20 2f 2a 20 43 61 63 68 65 20 63 6f 6e 66  .  /* Cache conf
0a40: 69 67 75 72 61 74 69 6f 6e 20 70 61 72 61 6d 65  iguration parame
0a50: 74 65 72 73 2e 20 50 61 67 65 20 73 69 7a 65 20  ters. Page size 
0a60: 28 73 7a 50 61 67 65 29 20 61 6e 64 20 74 68 65  (szPage) and the
0a70: 20 70 75 72 67 65 61 62 6c 65 0a 20 20 2a 2a 20   purgeable.  ** 
0a80: 66 6c 61 67 20 28 62 50 75 72 67 65 61 62 6c 65  flag (bPurgeable
0a90: 29 20 61 72 65 20 73 65 74 20 77 68 65 6e 20 74  ) are set when t
0aa0: 68 65 20 63 61 63 68 65 20 69 73 20 63 72 65 61  he cache is crea
0ab0: 74 65 64 2e 20 6e 4d 61 78 20 6d 61 79 20 62 65  ted. nMax may be
0ac0: 20 0a 20 20 2a 2a 20 6d 6f 64 69 66 69 65 64 20   .  ** modified 
0ad0: 61 74 20 61 6e 79 20 74 69 6d 65 20 62 79 20 61  at any time by a
0ae0: 20 63 61 6c 6c 20 74 6f 20 74 68 65 20 70 63 61   call to the pca
0af0: 63 68 65 31 43 61 63 68 65 53 69 7a 65 28 29 20  che1CacheSize() 
0b00: 6d 65 74 68 6f 64 2e 0a 20 20 2a 2a 20 54 68 65  method..  ** The
0b10: 20 50 47 72 6f 75 70 20 6d 75 74 65 78 20 6d 75   PGroup mutex mu
0b20: 73 74 20 62 65 20 68 65 6c 64 20 77 68 65 6e 20  st be held when 
0b30: 61 63 63 65 73 73 69 6e 67 20 6e 4d 61 78 2e 0a  accessing nMax..
0b40: 20 20 2a 2f 0a 20 20 50 47 72 6f 75 70 20 2a 70    */.  PGroup *p
0b50: 47 72 6f 75 70 3b 20 20 20 20 20 20 20 20 20 20  Group;          
0b60: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 47             /* PG
0b70: 72 6f 75 70 20 74 68 69 73 20 63 61 63 68 65 20  roup this cache 
0b80: 62 65 6c 6f 6e 67 73 20 74 6f 20 2a 2f 0a 20 20  belongs to */.  
0b90: 69 6e 74 20 73 7a 50 61 67 65 3b 20 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 2f 2a 20 53 69 7a 65 20 6f 66 20 61      /* Size of a
0bc0: 6c 6c 6f 63 61 74 65 64 20 70 61 67 65 73 20 69  llocated pages i
0bd0: 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 69 6e 74  n bytes */.  int
0be0: 20 73 7a 45 78 74 72 61 3b 20 20 20 20 20 20 20   szExtra;       
0bf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c00: 20 2f 2a 20 53 69 7a 65 20 6f 66 20 65 78 74 72   /* Size of extr
0c10: 61 20 73 70 61 63 65 20 69 6e 20 62 79 74 65 73  a space in bytes
0c20: 20 2a 2f 0a 20 20 69 6e 74 20 62 50 75 72 67 65   */.  int bPurge
0c30: 61 62 6c 65 3b 20 20 20 20 20 20 20 20 20 20 20  able;           
0c40: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75            /* Tru
0c50: 65 20 69 66 20 63 61 63 68 65 20 69 73 20 70 75  e if cache is pu
0c60: 72 67 65 61 62 6c 65 20 2a 2f 0a 20 20 75 6e 73  rgeable */.  uns
0c70: 69 67 6e 65 64 20 69 6e 74 20 6e 4d 69 6e 3b 20  igned int nMin; 
0c80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c90: 20 2f 2a 20 4d 69 6e 69 6d 75 6d 20 6e 75 6d 62   /* Minimum numb
0ca0: 65 72 20 6f 66 20 70 61 67 65 73 20 72 65 73 65  er of pages rese
0cb0: 72 76 65 64 20 2a 2f 0a 20 20 75 6e 73 69 67 6e  rved */.  unsign
0cc0: 65 64 20 69 6e 74 20 6e 4d 61 78 3b 20 20 20 20  ed int nMax;    
0cd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0ce0: 20 43 6f 6e 66 69 67 75 72 65 64 20 22 63 61 63   Configured "cac
0cf0: 68 65 5f 73 69 7a 65 22 20 76 61 6c 75 65 20 2a  he_size" value *
0d00: 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74  /.  unsigned int
0d10: 20 6e 39 30 70 63 74 3b 20 20 20 20 20 20 20 20   n90pct;        
0d20: 20 20 20 20 20 20 20 20 2f 2a 20 6e 4d 61 78 2a          /* nMax*
0d30: 39 2f 31 30 20 2a 2f 0a 0a 20 20 2f 2a 20 48 61  9/10 */..  /* Ha
0d40: 73 68 20 74 61 62 6c 65 20 6f 66 20 61 6c 6c 20  sh table of all 
0d50: 70 61 67 65 73 2e 20 54 68 65 20 66 6f 6c 6c 6f  pages. The follo
0d60: 77 69 6e 67 20 76 61 72 69 61 62 6c 65 73 20 6d  wing variables m
0d70: 61 79 20 6f 6e 6c 79 20 62 65 20 61 63 63 65 73  ay only be acces
0d80: 73 65 64 0a 20 20 2a 2a 20 77 68 65 6e 20 74 68  sed.  ** when th
0d90: 65 20 61 63 63 65 73 73 6f 72 20 69 73 20 68 6f  e accessor is ho
0da0: 6c 64 69 6e 67 20 74 68 65 20 50 47 72 6f 75 70  lding the PGroup
0db0: 20 6d 75 74 65 78 2e 0a 20 20 2a 2f 0a 20 20 75   mutex..  */.  u
0dc0: 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 52 65 63  nsigned int nRec
0dd0: 79 63 6c 61 62 6c 65 3b 20 20 20 20 20 20 20 20  yclable;        
0de0: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
0df0: 70 61 67 65 73 20 69 6e 20 74 68 65 20 4c 52 55  pages in the LRU
0e00: 20 6c 69 73 74 20 2a 2f 0a 20 20 75 6e 73 69 67   list */.  unsig
0e10: 6e 65 64 20 69 6e 74 20 6e 50 61 67 65 3b 20 20  ned int nPage;  
0e20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0e30: 2a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f  * Total number o
0e40: 66 20 70 61 67 65 73 20 69 6e 20 61 70 48 61 73  f pages in apHas
0e50: 68 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20  h */.  unsigned 
0e60: 69 6e 74 20 6e 48 61 73 68 3b 20 20 20 20 20 20  int nHash;      
0e70: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
0e80: 6d 62 65 72 20 6f 66 20 73 6c 6f 74 73 20 69 6e  mber of slots in
0e90: 20 61 70 48 61 73 68 5b 5d 20 2a 2f 0a 20 20 50   apHash[] */.  P
0ea0: 67 48 64 72 31 20 2a 2a 61 70 48 61 73 68 3b 20  gHdr1 **apHash; 
0eb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ec0: 20 20 20 2f 2a 20 48 61 73 68 20 74 61 62 6c 65     /* Hash table
0ed0: 20 66 6f 72 20 66 61 73 74 20 6c 6f 6f 6b 75 70   for fast lookup
0ee0: 20 62 79 20 6b 65 79 20 2a 2f 0a 0a 20 20 75 6e   by key */..  un
0ef0: 73 69 67 6e 65 64 20 69 6e 74 20 69 4d 61 78 4b  signed int iMaxK
0f00: 65 79 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ey;             
0f10: 20 20 2f 2a 20 4c 61 72 67 65 73 74 20 6b 65 79    /* Largest key
0f20: 20 73 65 65 6e 20 73 69 6e 63 65 20 78 54 72 75   seen since xTru
0f30: 6e 63 61 74 65 28 29 20 2a 2f 0a 7d 3b 0a 0a 2f  ncate() */.};../
0f40: 2a 0a 2a 2a 20 45 61 63 68 20 63 61 63 68 65 20  *.** Each cache 
0f50: 65 6e 74 72 79 20 69 73 20 72 65 70 72 65 73 65  entry is represe
0f60: 6e 74 65 64 20 62 79 20 61 6e 20 69 6e 73 74 61  nted by an insta
0f70: 6e 63 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f  nce of the follo
0f80: 77 69 6e 67 20 0a 2a 2a 20 73 74 72 75 63 74 75  wing .** structu
0f90: 72 65 2e 20 55 6e 6c 65 73 73 20 53 51 4c 49 54  re. Unless SQLIT
0fa0: 45 5f 50 43 41 43 48 45 5f 53 45 50 41 52 41 54  E_PCACHE_SEPARAT
0fb0: 45 5f 48 45 41 44 45 52 20 69 73 20 64 65 66 69  E_HEADER is defi
0fc0: 6e 65 64 2c 20 61 20 62 75 66 66 65 72 20 6f 66  ned, a buffer of
0fd0: 0a 2a 2a 20 50 67 48 64 72 31 2e 70 43 61 63 68  .** PgHdr1.pCach
0fe0: 65 2d 3e 73 7a 50 61 67 65 20 62 79 74 65 73 20  e->szPage bytes 
0ff0: 69 73 20 61 6c 6c 6f 63 61 74 65 64 20 64 69 72  is allocated dir
1000: 65 63 74 6c 79 20 62 65 66 6f 72 65 20 74 68 69  ectly before thi
1010: 73 20 73 74 72 75 63 74 75 72 65 20 0a 2a 2a 20  s structure .** 
1020: 69 6e 20 6d 65 6d 6f 72 79 2e 0a 2a 2f 0a 73 74  in memory..*/.st
1030: 72 75 63 74 20 50 67 48 64 72 31 20 7b 0a 20 20  ruct PgHdr1 {.  
1040: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 5f 70  sqlite3_pcache_p
1050: 61 67 65 20 70 61 67 65 3b 0a 20 20 75 6e 73 69  age page;.  unsi
1060: 67 6e 65 64 20 69 6e 74 20 69 4b 65 79 3b 20 20  gned int iKey;  
1070: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4b 65             /* Ke
1080: 79 20 76 61 6c 75 65 20 28 70 61 67 65 20 6e 75  y value (page nu
1090: 6d 62 65 72 29 20 2a 2f 0a 20 20 50 67 48 64 72  mber) */.  PgHdr
10a0: 31 20 2a 70 4e 65 78 74 3b 20 20 20 20 20 20 20  1 *pNext;       
10b0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78            /* Nex
10c0: 74 20 69 6e 20 68 61 73 68 20 74 61 62 6c 65 20  t in hash table 
10d0: 63 68 61 69 6e 20 2a 2f 0a 20 20 50 43 61 63 68  chain */.  PCach
10e0: 65 31 20 2a 70 43 61 63 68 65 3b 20 20 20 20 20  e1 *pCache;     
10f0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 61 63            /* Cac
1100: 68 65 20 74 68 61 74 20 63 75 72 72 65 6e 74 6c  he that currentl
1110: 79 20 6f 77 6e 73 20 74 68 69 73 20 70 61 67 65  y owns this page
1120: 20 2a 2f 0a 20 20 50 67 48 64 72 31 20 2a 70 4c   */.  PgHdr1 *pL
1130: 72 75 4e 65 78 74 3b 20 20 20 20 20 20 20 20 20  ruNext;         
1140: 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 69 6e 20       /* Next in 
1150: 4c 52 55 20 6c 69 73 74 20 6f 66 20 75 6e 70 69  LRU list of unpi
1160: 6e 6e 65 64 20 70 61 67 65 73 20 2a 2f 0a 20 20  nned pages */.  
1170: 50 67 48 64 72 31 20 2a 70 4c 72 75 50 72 65 76  PgHdr1 *pLruPrev
1180: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ;              /
1190: 2a 20 50 72 65 76 69 6f 75 73 20 69 6e 20 4c 52  * Previous in LR
11a0: 55 20 6c 69 73 74 20 6f 66 20 75 6e 70 69 6e 6e  U list of unpinn
11b0: 65 64 20 70 61 67 65 73 20 2a 2f 0a 7d 3b 0a 0a  ed pages */.};..
11c0: 2f 2a 0a 2a 2a 20 46 72 65 65 20 73 6c 6f 74 73  /*.** Free slots
11d0: 20 69 6e 20 74 68 65 20 61 6c 6c 6f 63 61 74 6f   in the allocato
11e0: 72 20 75 73 65 64 20 74 6f 20 64 69 76 69 64 65  r used to divide
11f0: 20 75 70 20 74 68 65 20 62 75 66 66 65 72 20 70   up the buffer p
1200: 72 6f 76 69 64 65 64 20 75 73 69 6e 67 0a 2a 2a  rovided using.**
1210: 20 74 68 65 20 53 51 4c 49 54 45 5f 43 4f 4e 46   the SQLITE_CONF
1220: 49 47 5f 50 41 47 45 43 41 43 48 45 20 6d 65 63  IG_PAGECACHE mec
1230: 68 61 6e 69 73 6d 2e 0a 2a 2f 0a 73 74 72 75 63  hanism..*/.struc
1240: 74 20 50 67 46 72 65 65 73 6c 6f 74 20 7b 0a 20  t PgFreeslot {. 
1250: 20 50 67 46 72 65 65 73 6c 6f 74 20 2a 70 4e 65   PgFreeslot *pNe
1260: 78 74 3b 20 20 2f 2a 20 4e 65 78 74 20 66 72 65  xt;  /* Next fre
1270: 65 20 73 6c 6f 74 20 2a 2f 0a 7d 3b 0a 0a 2f 2a  e slot */.};../*
1280: 0a 2a 2a 20 47 6c 6f 62 61 6c 20 64 61 74 61 20  .** Global data 
1290: 75 73 65 64 20 62 79 20 74 68 69 73 20 63 61 63  used by this cac
12a0: 68 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 53 51  he..*/.static SQ
12b0: 4c 49 54 45 5f 57 53 44 20 73 74 72 75 63 74 20  LITE_WSD struct 
12c0: 50 43 61 63 68 65 47 6c 6f 62 61 6c 20 7b 0a 20  PCacheGlobal {. 
12d0: 20 50 47 72 6f 75 70 20 67 72 70 3b 20 20 20 20   PGroup grp;    
12e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12f0: 2f 2a 20 54 68 65 20 67 6c 6f 62 61 6c 20 50 47  /* The global PG
1300: 72 6f 75 70 20 66 6f 72 20 6d 6f 64 65 20 28 32  roup for mode (2
1310: 29 20 2a 2f 0a 0a 20 20 2f 2a 20 56 61 72 69 61  ) */..  /* Varia
1320: 62 6c 65 73 20 72 65 6c 61 74 65 64 20 74 6f 20  bles related to 
1330: 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41  SQLITE_CONFIG_PA
1340: 47 45 43 41 43 48 45 20 73 65 74 74 69 6e 67 73  GECACHE settings
1350: 2e 20 20 54 68 65 0a 20 20 2a 2a 20 73 7a 53 6c  .  The.  ** szSl
1360: 6f 74 2c 20 6e 53 6c 6f 74 2c 20 70 53 74 61 72  ot, nSlot, pStar
1370: 74 2c 20 70 45 6e 64 2c 20 6e 52 65 73 65 72 76  t, pEnd, nReserv
1380: 65 2c 20 61 6e 64 20 69 73 49 6e 69 74 20 76 61  e, and isInit va
1390: 6c 75 65 73 20 61 72 65 20 61 6c 6c 0a 20 20 2a  lues are all.  *
13a0: 2a 20 66 69 78 65 64 20 61 74 20 73 71 6c 69 74  * fixed at sqlit
13b0: 65 33 5f 69 6e 69 74 69 61 6c 69 7a 65 28 29 20  e3_initialize() 
13c0: 74 69 6d 65 20 61 6e 64 20 64 6f 20 6e 6f 74 20  time and do not 
13d0: 72 65 71 75 69 72 65 20 6d 75 74 65 78 20 70 72  require mutex pr
13e0: 6f 74 65 63 74 69 6f 6e 2e 0a 20 20 2a 2a 20 54  otection..  ** T
13f0: 68 65 20 6e 46 72 65 65 53 6c 6f 74 20 61 6e 64  he nFreeSlot and
1400: 20 70 46 72 65 65 20 76 61 6c 75 65 73 20 64 6f   pFree values do
1410: 20 72 65 71 75 69 72 65 20 6d 75 74 65 78 20 70   require mutex p
1420: 72 6f 74 65 63 74 69 6f 6e 2e 0a 20 20 2a 2f 0a  rotection..  */.
1430: 20 20 69 6e 74 20 69 73 49 6e 69 74 3b 20 20 20    int isInit;   
1440: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1450: 20 2f 2a 20 54 72 75 65 20 69 66 20 69 6e 69 74   /* True if init
1460: 69 61 6c 69 7a 65 64 20 2a 2f 0a 20 20 69 6e 74  ialized */.  int
1470: 20 73 7a 53 6c 6f 74 3b 20 20 20 20 20 20 20 20   szSlot;        
1480: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
1490: 69 7a 65 20 6f 66 20 65 61 63 68 20 66 72 65 65  ize of each free
14a0: 20 73 6c 6f 74 20 2a 2f 0a 20 20 69 6e 74 20 6e   slot */.  int n
14b0: 53 6c 6f 74 3b 20 20 20 20 20 20 20 20 20 20 20  Slot;           
14c0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65            /* The
14d0: 20 6e 75 6d 62 65 72 20 6f 66 20 70 63 61 63 68   number of pcach
14e0: 65 20 73 6c 6f 74 73 20 2a 2f 0a 20 20 69 6e 74  e slots */.  int
14f0: 20 6e 52 65 73 65 72 76 65 3b 20 20 20 20 20 20   nReserve;      
1500: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
1510: 72 79 20 74 6f 20 6b 65 65 70 20 6e 46 72 65 65  ry to keep nFree
1520: 53 6c 6f 74 20 61 62 6f 76 65 20 74 68 69 73 20  Slot above this 
1530: 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 53 74 61 72  */.  void *pStar
1540: 74 2c 20 2a 70 45 6e 64 3b 20 20 20 20 20 20 20  t, *pEnd;       
1550: 20 20 20 20 2f 2a 20 42 6f 75 6e 64 73 20 6f 66      /* Bounds of
1560: 20 70 61 67 65 63 61 63 68 65 20 6d 61 6c 6c 6f   pagecache mallo
1570: 63 20 72 61 6e 67 65 20 2a 2f 0a 20 20 2f 2a 20  c range */.  /* 
1580: 41 62 6f 76 65 20 72 65 71 75 69 72 65 73 20 6e  Above requires n
1590: 6f 20 6d 75 74 65 78 2e 20 20 55 73 65 20 6d 75  o mutex.  Use mu
15a0: 74 65 78 20 62 65 6c 6f 77 20 66 6f 72 20 76 61  tex below for va
15b0: 72 69 61 62 6c 65 20 74 68 61 74 20 66 6f 6c 6c  riable that foll
15c0: 6f 77 2e 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  ow. */.  sqlite3
15d0: 5f 6d 75 74 65 78 20 2a 6d 75 74 65 78 3b 20 20  _mutex *mutex;  
15e0: 20 20 20 20 20 20 20 20 2f 2a 20 4d 75 74 65 78          /* Mutex
15f0: 20 66 6f 72 20 61 63 63 65 73 73 69 6e 67 20 74   for accessing t
1600: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 3a 20 2a 2f  he following: */
1610: 0a 20 20 69 6e 74 20 6e 46 72 65 65 53 6c 6f 74  .  int nFreeSlot
1620: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1630: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 75    /* Number of u
1640: 6e 75 73 65 64 20 70 63 61 63 68 65 20 73 6c 6f  nused pcache slo
1650: 74 73 20 2a 2f 0a 20 20 50 67 46 72 65 65 73 6c  ts */.  PgFreesl
1660: 6f 74 20 2a 70 46 72 65 65 3b 20 20 20 20 20 20  ot *pFree;      
1670: 20 20 20 20 20 20 20 2f 2a 20 46 72 65 65 20 70         /* Free p
1680: 61 67 65 20 62 6c 6f 63 6b 73 20 2a 2f 0a 20 20  age blocks */.  
1690: 2f 2a 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  /* The following
16a0: 20 76 61 6c 75 65 20 72 65 71 75 69 72 65 73 20   value requires 
16b0: 61 20 6d 75 74 65 78 20 74 6f 20 63 68 61 6e 67  a mutex to chang
16c0: 65 2e 20 20 57 65 20 73 6b 69 70 20 74 68 65 20  e.  We skip the 
16d0: 6d 75 74 65 78 20 6f 6e 0a 20 20 2a 2a 20 72 65  mutex on.  ** re
16e0: 61 64 69 6e 67 20 62 65 63 61 75 73 65 20 28 31  ading because (1
16f0: 29 20 6d 6f 73 74 20 70 6c 61 74 66 6f 72 6d 73  ) most platforms
1700: 20 72 65 61 64 20 61 20 33 32 2d 62 69 74 20 69   read a 32-bit i
1710: 6e 74 65 67 65 72 20 61 74 6f 6d 69 63 61 6c 6c  nteger atomicall
1720: 79 20 61 6e 64 0a 20 20 2a 2a 20 28 32 29 20 65  y and.  ** (2) e
1730: 76 65 6e 20 69 66 20 61 6e 20 69 6e 63 6f 72 72  ven if an incorr
1740: 65 63 74 20 76 61 6c 75 65 20 69 73 20 72 65 61  ect value is rea
1750: 64 2c 20 6e 6f 20 67 72 65 61 74 20 68 61 72 6d  d, no great harm
1760: 20 69 73 20 64 6f 6e 65 20 73 69 6e 63 65 20 74   is done since t
1770: 68 69 73 0a 20 20 2a 2a 20 69 73 20 72 65 61 6c  his.  ** is real
1780: 6c 79 20 6a 75 73 74 20 61 6e 20 6f 70 74 69 6d  ly just an optim
1790: 69 7a 61 74 69 6f 6e 2e 20 2a 2f 0a 20 20 69 6e  ization. */.  in
17a0: 74 20 62 55 6e 64 65 72 50 72 65 73 73 75 72 65  t bUnderPressure
17b0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ;            /* 
17c0: 54 72 75 65 20 69 66 20 6c 6f 77 20 6f 6e 20 50  True if low on P
17d0: 41 47 45 43 41 43 48 45 20 6d 65 6d 6f 72 79 20  AGECACHE memory 
17e0: 2a 2f 0a 7d 20 70 63 61 63 68 65 31 5f 67 3b 0a  */.} pcache1_g;.
17f0: 0a 2f 2a 0a 2a 2a 20 41 6c 6c 20 63 6f 64 65 20  ./*.** All code 
1800: 69 6e 20 74 68 69 73 20 66 69 6c 65 20 73 68 6f  in this file sho
1810: 75 6c 64 20 61 63 63 65 73 73 20 74 68 65 20 67  uld access the g
1820: 6c 6f 62 61 6c 20 73 74 72 75 63 74 75 72 65 20  lobal structure 
1830: 61 62 6f 76 65 20 76 69 61 20 74 68 65 0a 2a 2a  above via the.**
1840: 20 61 6c 69 61 73 20 22 70 63 61 63 68 65 31 22   alias "pcache1"
1850: 2e 20 54 68 69 73 20 65 6e 73 75 72 65 73 20 74  . This ensures t
1860: 68 61 74 20 74 68 65 20 57 53 44 20 65 6d 75 6c  hat the WSD emul
1870: 61 74 69 6f 6e 20 69 73 20 75 73 65 64 20 77 68  ation is used wh
1880: 65 6e 0a 2a 2a 20 63 6f 6d 70 69 6c 69 6e 67 20  en.** compiling 
1890: 66 6f 72 20 73 79 73 74 65 6d 73 20 74 68 61 74  for systems that
18a0: 20 64 6f 20 6e 6f 74 20 73 75 70 70 6f 72 74 20   do not support 
18b0: 72 65 61 6c 20 57 53 44 2e 0a 2a 2f 0a 23 64 65  real WSD..*/.#de
18c0: 66 69 6e 65 20 70 63 61 63 68 65 31 20 28 47 4c  fine pcache1 (GL
18d0: 4f 42 41 4c 28 73 74 72 75 63 74 20 50 43 61 63  OBAL(struct PCac
18e0: 68 65 47 6c 6f 62 61 6c 2c 20 70 63 61 63 68 65  heGlobal, pcache
18f0: 31 5f 67 29 29 0a 0a 2f 2a 0a 2a 2a 20 4d 61 63  1_g))../*.** Mac
1900: 72 6f 73 20 74 6f 20 65 6e 74 65 72 20 61 6e 64  ros to enter and
1910: 20 6c 65 61 76 65 20 74 68 65 20 50 43 61 63 68   leave the PCach
1920: 65 20 4c 52 55 20 6d 75 74 65 78 2e 0a 2a 2f 0a  e LRU mutex..*/.
1930: 23 64 65 66 69 6e 65 20 70 63 61 63 68 65 31 45  #define pcache1E
1940: 6e 74 65 72 4d 75 74 65 78 28 58 29 20 73 71 6c  nterMutex(X) sql
1950: 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e 74 65 72  ite3_mutex_enter
1960: 28 28 58 29 2d 3e 6d 75 74 65 78 29 0a 23 64 65  ((X)->mutex).#de
1970: 66 69 6e 65 20 70 63 61 63 68 65 31 4c 65 61 76  fine pcache1Leav
1980: 65 4d 75 74 65 78 28 58 29 20 73 71 6c 69 74 65  eMutex(X) sqlite
1990: 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 28 58  3_mutex_leave((X
19a0: 29 2d 3e 6d 75 74 65 78 29 0a 0a 2f 2a 2a 2a 2a  )->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 2f 0a 2f 2a 2a 2a  **********/./***
1a00: 2a 2a 2a 2a 2a 20 50 61 67 65 20 41 6c 6c 6f 63  ***** Page Alloc
1a10: 61 74 69 6f 6e 2f 53 51 4c 49 54 45 5f 43 4f 4e  ation/SQLITE_CON
1a20: 46 49 47 5f 50 43 41 43 48 45 20 52 65 6c 61 74  FIG_PCACHE Relat
1a30: 65 64 20 46 75 6e 63 74 69 6f 6e 73 20 2a 2a 2a  ed Functions ***
1a40: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f 2a  ***********/../*
1a50: 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
1a60: 6e 20 69 73 20 63 61 6c 6c 65 64 20 64 75 72 69  n is called duri
1a70: 6e 67 20 69 6e 69 74 69 61 6c 69 7a 61 74 69 6f  ng initializatio
1a80: 6e 20 69 66 20 61 20 73 74 61 74 69 63 20 62 75  n if a static bu
1a90: 66 66 65 72 20 69 73 20 0a 2a 2a 20 73 75 70 70  ffer is .** supp
1aa0: 6c 69 65 64 20 74 6f 20 75 73 65 20 66 6f 72 20  lied to use for 
1ab0: 74 68 65 20 70 61 67 65 2d 63 61 63 68 65 20 62  the page-cache b
1ac0: 79 20 70 61 73 73 69 6e 67 20 74 68 65 20 53 51  y passing the SQ
1ad0: 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47 45  LITE_CONFIG_PAGE
1ae0: 43 41 43 48 45 0a 2a 2a 20 76 65 72 62 20 74 6f  CACHE.** verb to
1af0: 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67 28   sqlite3_config(
1b00: 29 2e 20 50 61 72 61 6d 65 74 65 72 20 70 42 75  ). Parameter pBu
1b10: 66 20 70 6f 69 6e 74 73 20 74 6f 20 61 6e 20 61  f points to an a
1b20: 6c 6c 6f 63 61 74 69 6f 6e 20 6c 61 72 67 65 0a  llocation large.
1b30: 2a 2a 20 65 6e 6f 75 67 68 20 74 6f 20 63 6f 6e  ** enough to con
1b40: 74 61 69 6e 20 27 6e 27 20 62 75 66 66 65 72 73  tain 'n' buffers
1b50: 20 6f 66 20 27 73 7a 27 20 62 79 74 65 73 20 65   of 'sz' bytes e
1b60: 61 63 68 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  ach..**.** This 
1b70: 72 6f 75 74 69 6e 65 20 69 73 20 63 61 6c 6c 65  routine is calle
1b80: 64 20 66 72 6f 6d 20 73 71 6c 69 74 65 33 5f 69  d from sqlite3_i
1b90: 6e 69 74 69 61 6c 69 7a 65 28 29 20 61 6e 64 20  nitialize() and 
1ba0: 73 6f 20 69 74 20 69 73 20 67 75 61 72 61 6e 74  so it is guarant
1bb0: 65 65 64 0a 2a 2a 20 74 6f 20 62 65 20 73 65 72  eed.** to be ser
1bc0: 69 61 6c 69 7a 65 64 20 61 6c 72 65 61 64 79 2e  ialized already.
1bd0: 20 20 54 68 65 72 65 20 69 73 20 6e 6f 20 6e 65    There is no ne
1be0: 65 64 20 66 6f 72 20 66 75 72 74 68 65 72 20 6d  ed for further m
1bf0: 75 74 65 78 69 6e 67 2e 0a 2a 2f 0a 76 6f 69 64  utexing..*/.void
1c00: 20 73 71 6c 69 74 65 33 50 43 61 63 68 65 42 75   sqlite3PCacheBu
1c10: 66 66 65 72 53 65 74 75 70 28 76 6f 69 64 20 2a  fferSetup(void *
1c20: 70 42 75 66 2c 20 69 6e 74 20 73 7a 2c 20 69 6e  pBuf, int sz, in
1c30: 74 20 6e 29 7b 0a 20 20 69 66 28 20 70 63 61 63  t n){.  if( pcac
1c40: 68 65 31 2e 69 73 49 6e 69 74 20 29 7b 0a 20 20  he1.isInit ){.  
1c50: 20 20 50 67 46 72 65 65 73 6c 6f 74 20 2a 70 3b    PgFreeslot *p;
1c60: 0a 20 20 20 20 73 7a 20 3d 20 52 4f 55 4e 44 44  .    sz = ROUNDD
1c70: 4f 57 4e 38 28 73 7a 29 3b 0a 20 20 20 20 70 63  OWN8(sz);.    pc
1c80: 61 63 68 65 31 2e 73 7a 53 6c 6f 74 20 3d 20 73  ache1.szSlot = s
1c90: 7a 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 6e  z;.    pcache1.n
1ca0: 53 6c 6f 74 20 3d 20 70 63 61 63 68 65 31 2e 6e  Slot = pcache1.n
1cb0: 46 72 65 65 53 6c 6f 74 20 3d 20 6e 3b 0a 20 20  FreeSlot = n;.  
1cc0: 20 20 70 63 61 63 68 65 31 2e 6e 52 65 73 65 72    pcache1.nReser
1cd0: 76 65 20 3d 20 6e 3e 39 30 20 3f 20 31 30 20 3a  ve = n>90 ? 10 :
1ce0: 20 28 6e 2f 31 30 20 2b 20 31 29 3b 0a 20 20 20   (n/10 + 1);.   
1cf0: 20 70 63 61 63 68 65 31 2e 70 53 74 61 72 74 20   pcache1.pStart 
1d00: 3d 20 70 42 75 66 3b 0a 20 20 20 20 70 63 61 63  = pBuf;.    pcac
1d10: 68 65 31 2e 70 46 72 65 65 20 3d 20 30 3b 0a 20  he1.pFree = 0;. 
1d20: 20 20 20 70 63 61 63 68 65 31 2e 62 55 6e 64 65     pcache1.bUnde
1d30: 72 50 72 65 73 73 75 72 65 20 3d 20 30 3b 0a 20  rPressure = 0;. 
1d40: 20 20 20 77 68 69 6c 65 28 20 6e 2d 2d 20 29 7b     while( n-- ){
1d50: 0a 20 20 20 20 20 20 70 20 3d 20 28 50 67 46 72  .      p = (PgFr
1d60: 65 65 73 6c 6f 74 2a 29 70 42 75 66 3b 0a 20 20  eeslot*)pBuf;.  
1d70: 20 20 20 20 70 2d 3e 70 4e 65 78 74 20 3d 20 70      p->pNext = p
1d80: 63 61 63 68 65 31 2e 70 46 72 65 65 3b 0a 20 20  cache1.pFree;.  
1d90: 20 20 20 20 70 63 61 63 68 65 31 2e 70 46 72 65      pcache1.pFre
1da0: 65 20 3d 20 70 3b 0a 20 20 20 20 20 20 70 42 75  e = p;.      pBu
1db0: 66 20 3d 20 28 76 6f 69 64 2a 29 26 28 28 63 68  f = (void*)&((ch
1dc0: 61 72 2a 29 70 42 75 66 29 5b 73 7a 5d 3b 0a 20  ar*)pBuf)[sz];. 
1dd0: 20 20 20 7d 0a 20 20 20 20 70 63 61 63 68 65 31     }.    pcache1
1de0: 2e 70 45 6e 64 20 3d 20 70 42 75 66 3b 0a 20 20  .pEnd = pBuf;.  
1df0: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6c 6c 6f  }.}../*.** Mallo
1e00: 63 20 66 75 6e 63 74 69 6f 6e 20 75 73 65 64 20  c function used 
1e10: 77 69 74 68 69 6e 20 74 68 69 73 20 66 69 6c 65  within this file
1e20: 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 73 70 61   to allocate spa
1e30: 63 65 20 66 72 6f 6d 20 74 68 65 20 62 75 66 66  ce from the buff
1e40: 65 72 0a 2a 2a 20 63 6f 6e 66 69 67 75 72 65 64  er.** configured
1e50: 20 75 73 69 6e 67 20 73 71 6c 69 74 65 33 5f 63   using sqlite3_c
1e60: 6f 6e 66 69 67 28 53 51 4c 49 54 45 5f 43 4f 4e  onfig(SQLITE_CON
1e70: 46 49 47 5f 50 41 47 45 43 41 43 48 45 29 20 6f  FIG_PAGECACHE) o
1e80: 70 74 69 6f 6e 2e 20 49 66 20 6e 6f 20 0a 2a 2a  ption. If no .**
1e90: 20 73 75 63 68 20 62 75 66 66 65 72 20 65 78 69   such buffer exi
1ea0: 73 74 73 20 6f 72 20 74 68 65 72 65 20 69 73 20  sts or there is 
1eb0: 6e 6f 20 73 70 61 63 65 20 6c 65 66 74 20 69 6e  no space left in
1ec0: 20 69 74 2c 20 74 68 69 73 20 66 75 6e 63 74 69   it, this functi
1ed0: 6f 6e 20 66 61 6c 6c 73 20 0a 2a 2a 20 62 61 63  on falls .** bac
1ee0: 6b 20 74 6f 20 73 71 6c 69 74 65 33 4d 61 6c 6c  k to sqlite3Mall
1ef0: 6f 63 28 29 2e 0a 2a 2a 0a 2a 2a 20 4d 75 6c 74  oc()..**.** Mult
1f00: 69 70 6c 65 20 74 68 72 65 61 64 73 20 63 61 6e  iple threads can
1f10: 20 72 75 6e 20 74 68 69 73 20 72 6f 75 74 69 6e   run this routin
1f20: 65 20 61 74 20 74 68 65 20 73 61 6d 65 20 74 69  e at the same ti
1f30: 6d 65 2e 20 20 47 6c 6f 62 61 6c 20 76 61 72 69  me.  Global vari
1f40: 61 62 6c 65 73 0a 2a 2a 20 69 6e 20 70 63 61 63  ables.** in pcac
1f50: 68 65 31 20 6e 65 65 64 20 74 6f 20 62 65 20 70  he1 need to be p
1f60: 72 6f 74 65 63 74 65 64 20 76 69 61 20 6d 75 74  rotected via mut
1f70: 65 78 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ex..*/.static vo
1f80: 69 64 20 2a 70 63 61 63 68 65 31 41 6c 6c 6f 63  id *pcache1Alloc
1f90: 28 69 6e 74 20 6e 42 79 74 65 29 7b 0a 20 20 76  (int nByte){.  v
1fa0: 6f 69 64 20 2a 70 20 3d 20 30 3b 0a 20 20 61 73  oid *p = 0;.  as
1fb0: 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75  sert( sqlite3_mu
1fc0: 74 65 78 5f 6e 6f 74 68 65 6c 64 28 70 63 61 63  tex_notheld(pcac
1fd0: 68 65 31 2e 67 72 70 2e 6d 75 74 65 78 29 20 29  he1.grp.mutex) )
1fe0: 3b 0a 20 20 73 71 6c 69 74 65 33 53 74 61 74 75  ;.  sqlite3Statu
1ff0: 73 53 65 74 28 53 51 4c 49 54 45 5f 53 54 41 54  sSet(SQLITE_STAT
2000: 55 53 5f 50 41 47 45 43 41 43 48 45 5f 53 49 5a  US_PAGECACHE_SIZ
2010: 45 2c 20 6e 42 79 74 65 29 3b 0a 20 20 69 66 28  E, nByte);.  if(
2020: 20 6e 42 79 74 65 3c 3d 70 63 61 63 68 65 31 2e   nByte<=pcache1.
2030: 73 7a 53 6c 6f 74 20 29 7b 0a 20 20 20 20 73 71  szSlot ){.    sq
2040: 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e 74 65  lite3_mutex_ente
2050: 72 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29  r(pcache1.mutex)
2060: 3b 0a 20 20 20 20 70 20 3d 20 28 50 67 48 64 72  ;.    p = (PgHdr
2070: 31 20 2a 29 70 63 61 63 68 65 31 2e 70 46 72 65  1 *)pcache1.pFre
2080: 65 3b 0a 20 20 20 20 69 66 28 20 70 20 29 7b 0a  e;.    if( p ){.
2090: 20 20 20 20 20 20 70 63 61 63 68 65 31 2e 70 46        pcache1.pF
20a0: 72 65 65 20 3d 20 70 63 61 63 68 65 31 2e 70 46  ree = pcache1.pF
20b0: 72 65 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20  ree->pNext;.    
20c0: 20 20 70 63 61 63 68 65 31 2e 6e 46 72 65 65 53    pcache1.nFreeS
20d0: 6c 6f 74 2d 2d 3b 0a 20 20 20 20 20 20 70 63 61  lot--;.      pca
20e0: 63 68 65 31 2e 62 55 6e 64 65 72 50 72 65 73 73  che1.bUnderPress
20f0: 75 72 65 20 3d 20 70 63 61 63 68 65 31 2e 6e 46  ure = pcache1.nF
2100: 72 65 65 53 6c 6f 74 3c 70 63 61 63 68 65 31 2e  reeSlot<pcache1.
2110: 6e 52 65 73 65 72 76 65 3b 0a 20 20 20 20 20 20  nReserve;.      
2120: 61 73 73 65 72 74 28 20 70 63 61 63 68 65 31 2e  assert( pcache1.
2130: 6e 46 72 65 65 53 6c 6f 74 3e 3d 30 20 29 3b 0a  nFreeSlot>=0 );.
2140: 20 20 20 20 20 20 73 71 6c 69 74 65 33 53 74 61        sqlite3Sta
2150: 74 75 73 41 64 64 28 53 51 4c 49 54 45 5f 53 54  tusAdd(SQLITE_ST
2160: 41 54 55 53 5f 50 41 47 45 43 41 43 48 45 5f 55  ATUS_PAGECACHE_U
2170: 53 45 44 2c 20 31 29 3b 0a 20 20 20 20 7d 0a 20  SED, 1);.    }. 
2180: 20 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78     sqlite3_mutex
2190: 5f 6c 65 61 76 65 28 70 63 61 63 68 65 31 2e 6d  _leave(pcache1.m
21a0: 75 74 65 78 29 3b 0a 20 20 7d 0a 20 20 69 66 28  utex);.  }.  if(
21b0: 20 70 3d 3d 30 20 29 7b 0a 20 20 20 20 2f 2a 20   p==0 ){.    /* 
21c0: 4d 65 6d 6f 72 79 20 69 73 20 6e 6f 74 20 61 76  Memory is not av
21d0: 61 69 6c 61 62 6c 65 20 69 6e 20 74 68 65 20 53  ailable in the S
21e0: 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47  QLITE_CONFIG_PAG
21f0: 45 43 41 43 48 45 20 70 6f 6f 6c 2e 20 20 47 65  ECACHE pool.  Ge
2200: 74 0a 20 20 20 20 2a 2a 20 69 74 20 66 72 6f 6d  t.    ** it from
2210: 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 20 69   sqlite3Malloc i
2220: 6e 73 74 65 61 64 2e 0a 20 20 20 20 2a 2f 0a 20  nstead..    */. 
2230: 20 20 20 70 20 3d 20 73 71 6c 69 74 65 33 4d 61     p = sqlite3Ma
2240: 6c 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20 20  lloc(nByte);.   
2250: 20 69 66 28 20 70 20 29 7b 0a 20 20 20 20 20 20   if( p ){.      
2260: 69 6e 74 20 73 7a 20 3d 20 73 71 6c 69 74 65 33  int sz = sqlite3
2270: 4d 61 6c 6c 6f 63 53 69 7a 65 28 70 29 3b 0a 20  MallocSize(p);. 
2280: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 75 74       sqlite3_mut
2290: 65 78 5f 65 6e 74 65 72 28 70 63 61 63 68 65 31  ex_enter(pcache1
22a0: 2e 6d 75 74 65 78 29 3b 0a 20 20 20 20 20 20 73  .mutex);.      s
22b0: 71 6c 69 74 65 33 53 74 61 74 75 73 41 64 64 28  qlite3StatusAdd(
22c0: 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41  SQLITE_STATUS_PA
22d0: 47 45 43 41 43 48 45 5f 4f 56 45 52 46 4c 4f 57  GECACHE_OVERFLOW
22e0: 2c 20 73 7a 29 3b 0a 20 20 20 20 20 20 73 71 6c  , sz);.      sql
22f0: 69 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65  ite3_mutex_leave
2300: 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29 3b  (pcache1.mutex);
2310: 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 6c 69 74  .    }.    sqlit
2320: 65 33 4d 65 6d 64 65 62 75 67 53 65 74 54 79 70  e3MemdebugSetTyp
2330: 65 28 70 2c 20 4d 45 4d 54 59 50 45 5f 50 43 41  e(p, MEMTYPE_PCA
2340: 43 48 45 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75  CHE);.  }.  retu
2350: 72 6e 20 70 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46  rn p;.}../*.** F
2360: 72 65 65 20 61 6e 20 61 6c 6c 6f 63 61 74 65 64  ree an allocated
2370: 20 62 75 66 66 65 72 20 6f 62 74 61 69 6e 65 64   buffer obtained
2380: 20 66 72 6f 6d 20 70 63 61 63 68 65 31 41 6c 6c   from pcache1All
2390: 6f 63 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  oc()..*/.static 
23a0: 69 6e 74 20 70 63 61 63 68 65 31 46 72 65 65 28  int pcache1Free(
23b0: 76 6f 69 64 20 2a 70 29 7b 0a 20 20 69 6e 74 20  void *p){.  int 
23c0: 6e 46 72 65 65 64 20 3d 20 30 3b 0a 20 20 69 66  nFreed = 0;.  if
23d0: 28 20 70 3d 3d 30 20 29 20 72 65 74 75 72 6e 20  ( p==0 ) return 
23e0: 30 3b 0a 20 20 69 66 28 20 70 3e 3d 70 63 61 63  0;.  if( p>=pcac
23f0: 68 65 31 2e 70 53 74 61 72 74 20 26 26 20 70 3c  he1.pStart && p<
2400: 70 63 61 63 68 65 31 2e 70 45 6e 64 20 29 7b 0a  pcache1.pEnd ){.
2410: 20 20 20 20 50 67 46 72 65 65 73 6c 6f 74 20 2a      PgFreeslot *
2420: 70 53 6c 6f 74 3b 0a 20 20 20 20 73 71 6c 69 74  pSlot;.    sqlit
2430: 65 33 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28 70  e3_mutex_enter(p
2440: 63 61 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a 20  cache1.mutex);. 
2450: 20 20 20 73 71 6c 69 74 65 33 53 74 61 74 75 73     sqlite3Status
2460: 41 64 64 28 53 51 4c 49 54 45 5f 53 54 41 54 55  Add(SQLITE_STATU
2470: 53 5f 50 41 47 45 43 41 43 48 45 5f 55 53 45 44  S_PAGECACHE_USED
2480: 2c 20 2d 31 29 3b 0a 20 20 20 20 70 53 6c 6f 74  , -1);.    pSlot
2490: 20 3d 20 28 50 67 46 72 65 65 73 6c 6f 74 2a 29   = (PgFreeslot*)
24a0: 70 3b 0a 20 20 20 20 70 53 6c 6f 74 2d 3e 70 4e  p;.    pSlot->pN
24b0: 65 78 74 20 3d 20 70 63 61 63 68 65 31 2e 70 46  ext = pcache1.pF
24c0: 72 65 65 3b 0a 20 20 20 20 70 63 61 63 68 65 31  ree;.    pcache1
24d0: 2e 70 46 72 65 65 20 3d 20 70 53 6c 6f 74 3b 0a  .pFree = pSlot;.
24e0: 20 20 20 20 70 63 61 63 68 65 31 2e 6e 46 72 65      pcache1.nFre
24f0: 65 53 6c 6f 74 2b 2b 3b 0a 20 20 20 20 70 63 61  eSlot++;.    pca
2500: 63 68 65 31 2e 62 55 6e 64 65 72 50 72 65 73 73  che1.bUnderPress
2510: 75 72 65 20 3d 20 70 63 61 63 68 65 31 2e 6e 46  ure = pcache1.nF
2520: 72 65 65 53 6c 6f 74 3c 70 63 61 63 68 65 31 2e  reeSlot<pcache1.
2530: 6e 52 65 73 65 72 76 65 3b 0a 20 20 20 20 61 73  nReserve;.    as
2540: 73 65 72 74 28 20 70 63 61 63 68 65 31 2e 6e 46  sert( pcache1.nF
2550: 72 65 65 53 6c 6f 74 3c 3d 70 63 61 63 68 65 31  reeSlot<=pcache1
2560: 2e 6e 53 6c 6f 74 20 29 3b 0a 20 20 20 20 73 71  .nSlot );.    sq
2570: 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76  lite3_mutex_leav
2580: 65 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29  e(pcache1.mutex)
2590: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 61  ;.  }else{.    a
25a0: 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 4d 65  ssert( sqlite3Me
25b0: 6d 64 65 62 75 67 48 61 73 54 79 70 65 28 70 2c  mdebugHasType(p,
25c0: 20 4d 45 4d 54 59 50 45 5f 50 43 41 43 48 45 29   MEMTYPE_PCACHE)
25d0: 20 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 4d   );.    sqlite3M
25e0: 65 6d 64 65 62 75 67 53 65 74 54 79 70 65 28 70  emdebugSetType(p
25f0: 2c 20 4d 45 4d 54 59 50 45 5f 48 45 41 50 29 3b  , MEMTYPE_HEAP);
2600: 0a 20 20 20 20 6e 46 72 65 65 64 20 3d 20 73 71  .    nFreed = sq
2610: 6c 69 74 65 33 4d 61 6c 6c 6f 63 53 69 7a 65 28  lite3MallocSize(
2620: 70 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  p);.    sqlite3_
2630: 6d 75 74 65 78 5f 65 6e 74 65 72 28 70 63 61 63  mutex_enter(pcac
2640: 68 65 31 2e 6d 75 74 65 78 29 3b 0a 20 20 20 20  he1.mutex);.    
2650: 73 71 6c 69 74 65 33 53 74 61 74 75 73 41 64 64  sqlite3StatusAdd
2660: 28 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50  (SQLITE_STATUS_P
2670: 41 47 45 43 41 43 48 45 5f 4f 56 45 52 46 4c 4f  AGECACHE_OVERFLO
2680: 57 2c 20 2d 6e 46 72 65 65 64 29 3b 0a 20 20 20  W, -nFreed);.   
2690: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6c   sqlite3_mutex_l
26a0: 65 61 76 65 28 70 63 61 63 68 65 31 2e 6d 75 74  eave(pcache1.mut
26b0: 65 78 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  ex);.    sqlite3
26c0: 5f 66 72 65 65 28 70 29 3b 0a 20 20 7d 0a 20 20  _free(p);.  }.  
26d0: 72 65 74 75 72 6e 20 6e 46 72 65 65 64 3b 0a 7d  return nFreed;.}
26e0: 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f  ..#ifdef SQLITE_
26f0: 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41  ENABLE_MEMORY_MA
2700: 4e 41 47 45 4d 45 4e 54 0a 2f 2a 0a 2a 2a 20 52  NAGEMENT./*.** R
2710: 65 74 75 72 6e 20 74 68 65 20 73 69 7a 65 20 6f  eturn the size o
2720: 66 20 61 20 70 63 61 63 68 65 20 61 6c 6c 6f 63  f a pcache alloc
2730: 61 74 69 6f 6e 0a 2a 2f 0a 73 74 61 74 69 63 20  ation.*/.static 
2740: 69 6e 74 20 70 63 61 63 68 65 31 4d 65 6d 53 69  int pcache1MemSi
2750: 7a 65 28 76 6f 69 64 20 2a 70 29 7b 0a 20 20 69  ze(void *p){.  i
2760: 66 28 20 70 3e 3d 70 63 61 63 68 65 31 2e 70 53  f( p>=pcache1.pS
2770: 74 61 72 74 20 26 26 20 70 3c 70 63 61 63 68 65  tart && p<pcache
2780: 31 2e 70 45 6e 64 20 29 7b 0a 20 20 20 20 72 65  1.pEnd ){.    re
2790: 74 75 72 6e 20 70 63 61 63 68 65 31 2e 73 7a 53  turn pcache1.szS
27a0: 6c 6f 74 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  lot;.  }else{.  
27b0: 20 20 69 6e 74 20 69 53 69 7a 65 3b 0a 20 20 20    int iSize;.   
27c0: 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33   assert( sqlite3
27d0: 4d 65 6d 64 65 62 75 67 48 61 73 54 79 70 65 28  MemdebugHasType(
27e0: 70 2c 20 4d 45 4d 54 59 50 45 5f 50 43 41 43 48  p, MEMTYPE_PCACH
27f0: 45 29 20 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  E) );.    sqlite
2800: 33 4d 65 6d 64 65 62 75 67 53 65 74 54 79 70 65  3MemdebugSetType
2810: 28 70 2c 20 4d 45 4d 54 59 50 45 5f 48 45 41 50  (p, MEMTYPE_HEAP
2820: 29 3b 0a 20 20 20 20 69 53 69 7a 65 20 3d 20 73  );.    iSize = s
2830: 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 53 69 7a 65  qlite3MallocSize
2840: 28 70 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  (p);.    sqlite3
2850: 4d 65 6d 64 65 62 75 67 53 65 74 54 79 70 65 28  MemdebugSetType(
2860: 70 2c 20 4d 45 4d 54 59 50 45 5f 50 43 41 43 48  p, MEMTYPE_PCACH
2870: 45 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 69  E);.    return i
2880: 53 69 7a 65 3b 0a 20 20 7d 0a 7d 0a 23 65 6e 64  Size;.  }.}.#end
2890: 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f 45 4e 41  if /* SQLITE_ENA
28a0: 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47  BLE_MEMORY_MANAG
28b0: 45 4d 45 4e 54 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20  EMENT */../*.** 
28c0: 41 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 70  Allocate a new p
28d0: 61 67 65 20 6f 62 6a 65 63 74 20 69 6e 69 74 69  age object initi
28e0: 61 6c 6c 79 20 61 73 73 6f 63 69 61 74 65 64 20  ally associated 
28f0: 77 69 74 68 20 63 61 63 68 65 20 70 43 61 63 68  with cache pCach
2900: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 50 67 48  e..*/.static PgH
2910: 64 72 31 20 2a 70 63 61 63 68 65 31 41 6c 6c 6f  dr1 *pcache1Allo
2920: 63 50 61 67 65 28 50 43 61 63 68 65 31 20 2a 70  cPage(PCache1 *p
2930: 43 61 63 68 65 29 7b 0a 20 20 50 67 48 64 72 31  Cache){.  PgHdr1
2940: 20 2a 70 20 3d 20 30 3b 0a 20 20 76 6f 69 64 20   *p = 0;.  void 
2950: 2a 70 50 67 3b 0a 0a 20 20 2f 2a 20 54 68 65 20  *pPg;..  /* The 
2960: 67 72 6f 75 70 20 6d 75 74 65 78 20 6d 75 73 74  group mutex must
2970: 20 62 65 20 72 65 6c 65 61 73 65 64 20 62 65 66   be released bef
2980: 6f 72 65 20 70 63 61 63 68 65 31 41 6c 6c 6f 63  ore pcache1Alloc
2990: 28 29 20 69 73 20 63 61 6c 6c 65 64 2e 20 54 68  () is called. Th
29a0: 69 73 0a 20 20 2a 2a 20 69 73 20 62 65 63 61 75  is.  ** is becau
29b0: 73 65 20 69 74 20 6d 61 79 20 63 61 6c 6c 20 73  se it may call s
29c0: 71 6c 69 74 65 33 5f 72 65 6c 65 61 73 65 5f 6d  qlite3_release_m
29d0: 65 6d 6f 72 79 28 29 2c 20 77 68 69 63 68 20 61  emory(), which a
29e0: 73 73 75 6d 65 73 20 74 68 61 74 20 0a 20 20 2a  ssumes that .  *
29f0: 2a 20 74 68 69 73 20 6d 75 74 65 78 20 69 73 20  * this mutex is 
2a00: 6e 6f 74 20 68 65 6c 64 2e 20 2a 2f 0a 20 20 61  not held. */.  a
2a10: 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d  ssert( sqlite3_m
2a20: 75 74 65 78 5f 68 65 6c 64 28 70 43 61 63 68 65  utex_held(pCache
2a30: 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78 29  ->pGroup->mutex)
2a40: 20 29 3b 0a 20 20 70 63 61 63 68 65 31 4c 65 61   );.  pcache1Lea
2a50: 76 65 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e  veMutex(pCache->
2a60: 70 47 72 6f 75 70 29 3b 0a 23 69 66 64 65 66 20  pGroup);.#ifdef 
2a70: 53 51 4c 49 54 45 5f 50 43 41 43 48 45 5f 53 45  SQLITE_PCACHE_SE
2a80: 50 41 52 41 54 45 5f 48 45 41 44 45 52 0a 20 20  PARATE_HEADER.  
2a90: 70 50 67 20 3d 20 70 63 61 63 68 65 31 41 6c 6c  pPg = pcache1All
2aa0: 6f 63 28 70 43 61 63 68 65 2d 3e 73 7a 50 61 67  oc(pCache->szPag
2ab0: 65 29 3b 0a 20 20 70 20 3d 20 73 71 6c 69 74 65  e);.  p = sqlite
2ac0: 33 4d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 50  3Malloc(sizeof(P
2ad0: 67 48 64 72 31 29 20 2b 20 70 43 61 63 68 65 2d  gHdr1) + pCache-
2ae0: 3e 73 7a 45 78 74 72 61 29 3b 0a 20 20 69 66 28  >szExtra);.  if(
2af0: 20 21 70 50 67 20 7c 7c 20 21 70 20 29 7b 0a 20   !pPg || !p ){. 
2b00: 20 20 20 70 63 61 63 68 65 31 46 72 65 65 28 70     pcache1Free(p
2b10: 50 67 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  Pg);.    sqlite3
2b20: 5f 66 72 65 65 28 70 29 3b 0a 20 20 20 20 70 50  _free(p);.    pP
2b30: 67 20 3d 20 30 3b 0a 20 20 7d 0a 23 65 6c 73 65  g = 0;.  }.#else
2b40: 0a 20 20 70 50 67 20 3d 20 70 63 61 63 68 65 31  .  pPg = pcache1
2b50: 41 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 50 67 48  Alloc(sizeof(PgH
2b60: 64 72 31 29 20 2b 20 70 43 61 63 68 65 2d 3e 73  dr1) + pCache->s
2b70: 7a 50 61 67 65 20 2b 20 70 43 61 63 68 65 2d 3e  zPage + pCache->
2b80: 73 7a 45 78 74 72 61 29 3b 0a 20 20 70 20 3d 20  szExtra);.  p = 
2b90: 28 50 67 48 64 72 31 20 2a 29 26 28 28 75 38 20  (PgHdr1 *)&((u8 
2ba0: 2a 29 70 50 67 29 5b 70 43 61 63 68 65 2d 3e 73  *)pPg)[pCache->s
2bb0: 7a 50 61 67 65 5d 3b 0a 23 65 6e 64 69 66 0a 20  zPage];.#endif. 
2bc0: 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74   pcache1EnterMut
2bd0: 65 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75  ex(pCache->pGrou
2be0: 70 29 3b 0a 0a 20 20 69 66 28 20 70 50 67 20 29  p);..  if( pPg )
2bf0: 7b 0a 20 20 20 20 70 2d 3e 70 61 67 65 2e 70 42  {.    p->page.pB
2c00: 75 66 20 3d 20 70 50 67 3b 0a 20 20 20 20 70 2d  uf = pPg;.    p-
2c10: 3e 70 61 67 65 2e 70 45 78 74 72 61 20 3d 20 26  >page.pExtra = &
2c20: 70 5b 31 5d 3b 0a 20 20 20 20 69 66 28 20 70 43  p[1];.    if( pC
2c30: 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65  ache->bPurgeable
2c40: 20 29 7b 0a 20 20 20 20 20 20 70 43 61 63 68 65   ){.      pCache
2c50: 2d 3e 70 47 72 6f 75 70 2d 3e 6e 43 75 72 72 65  ->pGroup->nCurre
2c60: 6e 74 50 61 67 65 2b 2b 3b 0a 20 20 20 20 7d 0a  ntPage++;.    }.
2c70: 20 20 20 20 72 65 74 75 72 6e 20 70 3b 0a 20 20      return p;.  
2c80: 7d 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a  }.  return 0;.}.
2c90: 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61 20 70 61  ./*.** Free a pa
2ca0: 67 65 20 6f 62 6a 65 63 74 20 61 6c 6c 6f 63 61  ge object alloca
2cb0: 74 65 64 20 62 79 20 70 63 61 63 68 65 31 41 6c  ted by pcache1Al
2cc0: 6c 6f 63 50 61 67 65 28 29 2e 0a 2a 2a 0a 2a 2a  locPage()..**.**
2cd0: 20 54 68 65 20 70 6f 69 6e 74 65 72 20 69 73 20   The pointer is 
2ce0: 61 6c 6c 6f 77 65 64 20 74 6f 20 62 65 20 4e 55  allowed to be NU
2cf0: 4c 4c 2c 20 77 68 69 63 68 20 69 73 20 70 72 75  LL, which is pru
2d00: 64 65 6e 74 2e 20 20 42 75 74 20 69 74 20 74 75  dent.  But it tu
2d10: 72 6e 73 20 6f 75 74 0a 2a 2a 20 74 68 61 74 20  rns out.** that 
2d20: 74 68 65 20 63 75 72 72 65 6e 74 20 69 6d 70 6c  the current impl
2d30: 65 6d 65 6e 74 61 74 69 6f 6e 20 68 61 70 70 65  ementation happe
2d40: 6e 73 20 74 6f 20 6e 65 76 65 72 20 63 61 6c 6c  ns to never call
2d50: 20 74 68 69 73 20 72 6f 75 74 69 6e 65 0a 2a 2a   this routine.**
2d60: 20 77 69 74 68 20 61 20 4e 55 4c 4c 20 70 6f 69   with a NULL poi
2d70: 6e 74 65 72 2c 20 73 6f 20 77 65 20 6d 61 72 6b  nter, so we mark
2d80: 20 74 68 65 20 4e 55 4c 4c 20 74 65 73 74 20 77   the NULL test w
2d90: 69 74 68 20 41 4c 57 41 59 53 28 29 2e 0a 2a 2f  ith ALWAYS()..*/
2da0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61  .static void pca
2db0: 63 68 65 31 46 72 65 65 50 61 67 65 28 50 67 48  che1FreePage(PgH
2dc0: 64 72 31 20 2a 70 29 7b 0a 20 20 69 66 28 20 41  dr1 *p){.  if( A
2dd0: 4c 57 41 59 53 28 70 29 20 29 7b 0a 20 20 20 20  LWAYS(p) ){.    
2de0: 50 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 20  PCache1 *pCache 
2df0: 3d 20 70 2d 3e 70 43 61 63 68 65 3b 0a 20 20 20  = p->pCache;.   
2e00: 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33   assert( sqlite3
2e10: 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 2d 3e 70  _mutex_held(p->p
2e20: 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 2d 3e 6d  Cache->pGroup->m
2e30: 75 74 65 78 29 20 29 3b 0a 20 20 20 20 70 63 61  utex) );.    pca
2e40: 63 68 65 31 46 72 65 65 28 70 2d 3e 70 61 67 65  che1Free(p->page
2e50: 2e 70 42 75 66 29 3b 0a 23 69 66 64 65 66 20 53  .pBuf);.#ifdef S
2e60: 51 4c 49 54 45 5f 50 43 41 43 48 45 5f 53 45 50  QLITE_PCACHE_SEP
2e70: 41 52 41 54 45 5f 48 45 41 44 45 52 0a 20 20 20  ARATE_HEADER.   
2e80: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 29   sqlite3_free(p)
2e90: 3b 0a 23 65 6e 64 69 66 0a 20 20 20 20 69 66 28  ;.#endif.    if(
2ea0: 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61   pCache->bPurgea
2eb0: 62 6c 65 20 29 7b 0a 20 20 20 20 20 20 70 43 61  ble ){.      pCa
2ec0: 63 68 65 2d 3e 70 47 72 6f 75 70 2d 3e 6e 43 75  che->pGroup->nCu
2ed0: 72 72 65 6e 74 50 61 67 65 2d 2d 3b 0a 20 20 20  rrentPage--;.   
2ee0: 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20   }.  }.}../*.** 
2ef0: 4d 61 6c 6c 6f 63 20 66 75 6e 63 74 69 6f 6e 20  Malloc function 
2f00: 75 73 65 64 20 62 79 20 53 51 4c 69 74 65 20 74  used by SQLite t
2f10: 6f 20 6f 62 74 61 69 6e 20 73 70 61 63 65 20 66  o obtain space f
2f20: 72 6f 6d 20 74 68 65 20 62 75 66 66 65 72 20 63  rom the buffer c
2f30: 6f 6e 66 69 67 75 72 65 64 0a 2a 2a 20 75 73 69  onfigured.** usi
2f40: 6e 67 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69  ng sqlite3_confi
2f50: 67 28 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f  g(SQLITE_CONFIG_
2f60: 50 41 47 45 43 41 43 48 45 29 20 6f 70 74 69 6f  PAGECACHE) optio
2f70: 6e 2e 20 49 66 20 6e 6f 20 73 75 63 68 20 62 75  n. If no such bu
2f80: 66 66 65 72 0a 2a 2a 20 65 78 69 73 74 73 2c 20  ffer.** exists, 
2f90: 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 66 61  this function fa
2fa0: 6c 6c 73 20 62 61 63 6b 20 74 6f 20 73 71 6c 69  lls back to sqli
2fb0: 74 65 33 4d 61 6c 6c 6f 63 28 29 2e 0a 2a 2f 0a  te3Malloc()..*/.
2fc0: 76 6f 69 64 20 2a 73 71 6c 69 74 65 33 50 61 67  void *sqlite3Pag
2fd0: 65 4d 61 6c 6c 6f 63 28 69 6e 74 20 73 7a 29 7b  eMalloc(int sz){
2fe0: 0a 20 20 72 65 74 75 72 6e 20 70 63 61 63 68 65  .  return pcache
2ff0: 31 41 6c 6c 6f 63 28 73 7a 29 3b 0a 7d 0a 0a 2f  1Alloc(sz);.}../
3000: 2a 0a 2a 2a 20 46 72 65 65 20 61 6e 20 61 6c 6c  *.** Free an all
3010: 6f 63 61 74 65 64 20 62 75 66 66 65 72 20 6f 62  ocated buffer ob
3020: 74 61 69 6e 65 64 20 66 72 6f 6d 20 73 71 6c 69  tained from sqli
3030: 74 65 33 50 61 67 65 4d 61 6c 6c 6f 63 28 29 2e  te3PageMalloc().
3040: 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33  .*/.void sqlite3
3050: 50 61 67 65 46 72 65 65 28 76 6f 69 64 20 2a 70  PageFree(void *p
3060: 29 7b 0a 20 20 70 63 61 63 68 65 31 46 72 65 65  ){.  pcache1Free
3070: 28 70 29 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 52  (p);.}.../*.** R
3080: 65 74 75 72 6e 20 74 72 75 65 20 69 66 20 69 74  eturn true if it
3090: 20 64 65 73 69 72 61 62 6c 65 20 74 6f 20 61 76   desirable to av
30a0: 6f 69 64 20 61 6c 6c 6f 63 61 74 69 6e 67 20 61  oid allocating a
30b0: 20 6e 65 77 20 70 61 67 65 20 63 61 63 68 65 0a   new page cache.
30c0: 2a 2a 20 65 6e 74 72 79 2e 0a 2a 2a 0a 2a 2a 20  ** entry..**.** 
30d0: 49 66 20 6d 65 6d 6f 72 79 20 77 61 73 20 61 6c  If memory was al
30e0: 6c 6f 63 61 74 65 64 20 73 70 65 63 69 66 69 63  located specific
30f0: 61 6c 6c 79 20 74 6f 20 74 68 65 20 70 61 67 65  ally to the page
3100: 20 63 61 63 68 65 20 75 73 69 6e 67 0a 2a 2a 20   cache using.** 
3110: 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41  SQLITE_CONFIG_PA
3120: 47 45 43 41 43 48 45 20 62 75 74 20 74 68 61 74  GECACHE but that
3130: 20 6d 65 6d 6f 72 79 20 68 61 73 20 61 6c 6c 20   memory has all 
3140: 62 65 65 6e 20 75 73 65 64 2c 20 74 68 65 6e 0a  been used, then.
3150: 2a 2a 20 69 74 20 69 73 20 64 65 73 69 72 61 62  ** it is desirab
3160: 6c 65 20 74 6f 20 61 76 6f 69 64 20 61 6c 6c 6f  le to avoid allo
3170: 63 61 74 69 6e 67 20 61 20 6e 65 77 20 70 61 67  cating a new pag
3180: 65 20 63 61 63 68 65 20 65 6e 74 72 79 20 62 65  e cache entry be
3190: 63 61 75 73 65 0a 2a 2a 20 70 72 65 73 75 6d 61  cause.** presuma
31a0: 62 6c 79 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49  bly SQLITE_CONFI
31b0: 47 5f 50 41 47 45 43 41 43 48 45 20 77 61 73 20  G_PAGECACHE was 
31c0: 73 75 70 70 6f 73 65 20 74 6f 20 62 65 20 73 75  suppose to be su
31d0: 66 66 69 63 69 65 6e 74 0a 2a 2a 20 66 6f 72 20  fficient.** for 
31e0: 61 6c 6c 20 70 61 67 65 20 63 61 63 68 65 20 6e  all page cache n
31f0: 65 65 64 73 20 61 6e 64 20 77 65 20 73 68 6f 75  eeds and we shou
3200: 6c 64 20 6e 6f 74 20 6e 65 65 64 20 74 6f 20 73  ld not need to s
3210: 70 69 6c 6c 20 74 68 65 0a 2a 2a 20 61 6c 6c 6f  pill the.** allo
3220: 63 61 74 69 6f 6e 20 6f 6e 74 6f 20 74 68 65 20  cation onto the 
3230: 68 65 61 70 2e 0a 2a 2a 0a 2a 2a 20 4f 72 2c 20  heap..**.** Or, 
3240: 74 68 65 20 68 65 61 70 20 69 73 20 75 73 65 64  the heap is used
3250: 20 66 6f 72 20 61 6c 6c 20 70 61 67 65 20 63 61   for all page ca
3260: 63 68 65 20 6d 65 6d 6f 72 79 20 70 75 74 20 74  che memory put t
3270: 68 65 20 68 65 61 70 20 69 73 0a 2a 2a 20 75 6e  he heap is.** un
3280: 64 65 72 20 6d 65 6d 6f 72 79 20 70 72 65 73 73  der memory press
3290: 75 72 65 2c 20 74 68 65 6e 20 61 67 61 69 6e 20  ure, then again 
32a0: 69 74 20 69 73 20 64 65 73 69 72 61 62 6c 65 20  it is desirable 
32b0: 74 6f 20 61 76 6f 69 64 0a 2a 2a 20 61 6c 6c 6f  to avoid.** allo
32c0: 63 61 74 69 6e 67 20 61 20 6e 65 77 20 70 61 67  cating a new pag
32d0: 65 20 63 61 63 68 65 20 65 6e 74 72 79 20 69 6e  e cache entry in
32e0: 20 6f 72 64 65 72 20 74 6f 20 61 76 6f 69 64 20   order to avoid 
32f0: 73 74 72 65 73 73 69 6e 67 0a 2a 2a 20 74 68 65  stressing.** the
3300: 20 68 65 61 70 20 65 76 65 6e 20 66 75 72 74 68   heap even furth
3310: 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  er..*/.static in
3320: 74 20 70 63 61 63 68 65 31 55 6e 64 65 72 4d 65  t pcache1UnderMe
3330: 6d 6f 72 79 50 72 65 73 73 75 72 65 28 50 43 61  moryPressure(PCa
3340: 63 68 65 31 20 2a 70 43 61 63 68 65 29 7b 0a 20  che1 *pCache){. 
3350: 20 69 66 28 20 70 63 61 63 68 65 31 2e 6e 53 6c   if( pcache1.nSl
3360: 6f 74 20 26 26 20 28 70 43 61 63 68 65 2d 3e 73  ot && (pCache->s
3370: 7a 50 61 67 65 2b 70 43 61 63 68 65 2d 3e 73 7a  zPage+pCache->sz
3380: 45 78 74 72 61 29 3c 3d 70 63 61 63 68 65 31 2e  Extra)<=pcache1.
3390: 73 7a 53 6c 6f 74 20 29 7b 0a 20 20 20 20 72 65  szSlot ){.    re
33a0: 74 75 72 6e 20 70 63 61 63 68 65 31 2e 62 55 6e  turn pcache1.bUn
33b0: 64 65 72 50 72 65 73 73 75 72 65 3b 0a 20 20 7d  derPressure;.  }
33c0: 65 6c 73 65 7b 0a 20 20 20 20 72 65 74 75 72 6e  else{.    return
33d0: 20 73 71 6c 69 74 65 33 48 65 61 70 4e 65 61 72   sqlite3HeapNear
33e0: 6c 79 46 75 6c 6c 28 29 3b 0a 20 20 7d 0a 7d 0a  lyFull();.  }.}.
33f0: 0a 2f 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 2a 2a 2a 2a 2a 2a  ****************
3430: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3440: 2f 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 20 47 65 6e 65  /./******** Gene
3450: 72 61 6c 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69  ral Implementati
3460: 6f 6e 20 46 75 6e 63 74 69 6f 6e 73 20 2a 2a 2a  on Functions ***
3470: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3480: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3490: 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66  */../*.** This f
34a0: 75 6e 63 74 69 6f 6e 20 69 73 20 75 73 65 64 20  unction is used 
34b0: 74 6f 20 72 65 73 69 7a 65 20 74 68 65 20 68 61  to resize the ha
34c0: 73 68 20 74 61 62 6c 65 20 75 73 65 64 20 62 79  sh table used by
34d0: 20 74 68 65 20 63 61 63 68 65 20 70 61 73 73 65   the cache passe
34e0: 64 0a 2a 2a 20 61 73 20 74 68 65 20 66 69 72 73  d.** as the firs
34f0: 74 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2a 0a 2a  t argument..**.*
3500: 2a 20 54 68 65 20 50 43 61 63 68 65 20 6d 75 74  * The PCache mut
3510: 65 78 20 6d 75 73 74 20 62 65 20 68 65 6c 64 20  ex must be held 
3520: 77 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69  when this functi
3530: 6f 6e 20 69 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f  on is called..*/
3540: 0a 73 74 61 74 69 63 20 69 6e 74 20 70 63 61 63  .static int pcac
3550: 68 65 31 52 65 73 69 7a 65 48 61 73 68 28 50 43  he1ResizeHash(PC
3560: 61 63 68 65 31 20 2a 70 29 7b 0a 20 20 50 67 48  ache1 *p){.  PgH
3570: 64 72 31 20 2a 2a 61 70 4e 65 77 3b 0a 20 20 75  dr1 **apNew;.  u
3580: 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 4e 65 77  nsigned int nNew
3590: 3b 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74  ;.  unsigned int
35a0: 20 69 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 73   i;..  assert( s
35b0: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c  qlite3_mutex_hel
35c0: 64 28 70 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75 74  d(p->pGroup->mut
35d0: 65 78 29 20 29 3b 0a 0a 20 20 6e 4e 65 77 20 3d  ex) );..  nNew =
35e0: 20 70 2d 3e 6e 48 61 73 68 2a 32 3b 0a 20 20 69   p->nHash*2;.  i
35f0: 66 28 20 6e 4e 65 77 3c 32 35 36 20 29 7b 0a 20  f( nNew<256 ){. 
3600: 20 20 20 6e 4e 65 77 20 3d 20 32 35 36 3b 0a 20     nNew = 256;. 
3610: 20 7d 0a 0a 20 20 70 63 61 63 68 65 31 4c 65 61   }..  pcache1Lea
3620: 76 65 4d 75 74 65 78 28 70 2d 3e 70 47 72 6f 75  veMutex(p->pGrou
3630: 70 29 3b 0a 20 20 69 66 28 20 70 2d 3e 6e 48 61  p);.  if( p->nHa
3640: 73 68 20 29 7b 20 73 71 6c 69 74 65 33 42 65 67  sh ){ sqlite3Beg
3650: 69 6e 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29  inBenignMalloc()
3660: 3b 20 7d 0a 20 20 61 70 4e 65 77 20 3d 20 28 50  ; }.  apNew = (P
3670: 67 48 64 72 31 20 2a 2a 29 73 71 6c 69 74 65 33  gHdr1 **)sqlite3
3680: 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 50  _malloc(sizeof(P
3690: 67 48 64 72 31 20 2a 29 2a 6e 4e 65 77 29 3b 0a  gHdr1 *)*nNew);.
36a0: 20 20 69 66 28 20 70 2d 3e 6e 48 61 73 68 20 29    if( p->nHash )
36b0: 7b 20 73 71 6c 69 74 65 33 45 6e 64 42 65 6e 69  { sqlite3EndBeni
36c0: 67 6e 4d 61 6c 6c 6f 63 28 29 3b 20 7d 0a 20 20  gnMalloc(); }.  
36d0: 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65  pcache1EnterMute
36e0: 78 28 70 2d 3e 70 47 72 6f 75 70 29 3b 0a 20 20  x(p->pGroup);.  
36f0: 69 66 28 20 61 70 4e 65 77 20 29 7b 0a 20 20 20  if( apNew ){.   
3700: 20 6d 65 6d 73 65 74 28 61 70 4e 65 77 2c 20 30   memset(apNew, 0
3710: 2c 20 73 69 7a 65 6f 66 28 50 67 48 64 72 31 20  , sizeof(PgHdr1 
3720: 2a 29 2a 6e 4e 65 77 29 3b 0a 20 20 20 20 66 6f  *)*nNew);.    fo
3730: 72 28 69 3d 30 3b 20 69 3c 70 2d 3e 6e 48 61 73  r(i=0; i<p->nHas
3740: 68 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 50  h; i++){.      P
3750: 67 48 64 72 31 20 2a 70 50 61 67 65 3b 0a 20 20  gHdr1 *pPage;.  
3760: 20 20 20 20 50 67 48 64 72 31 20 2a 70 4e 65 78      PgHdr1 *pNex
3770: 74 20 3d 20 70 2d 3e 61 70 48 61 73 68 5b 69 5d  t = p->apHash[i]
3780: 3b 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20 28  ;.      while( (
3790: 70 50 61 67 65 20 3d 20 70 4e 65 78 74 29 21 3d  pPage = pNext)!=
37a0: 30 20 29 7b 0a 20 20 20 20 20 20 20 20 75 6e 73  0 ){.        uns
37b0: 69 67 6e 65 64 20 69 6e 74 20 68 20 3d 20 70 50  igned int h = pP
37c0: 61 67 65 2d 3e 69 4b 65 79 20 25 20 6e 4e 65 77  age->iKey % nNew
37d0: 3b 0a 20 20 20 20 20 20 20 20 70 4e 65 78 74 20  ;.        pNext 
37e0: 3d 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 3b 0a  = pPage->pNext;.
37f0: 20 20 20 20 20 20 20 20 70 50 61 67 65 2d 3e 70          pPage->p
3800: 4e 65 78 74 20 3d 20 61 70 4e 65 77 5b 68 5d 3b  Next = apNew[h];
3810: 0a 20 20 20 20 20 20 20 20 61 70 4e 65 77 5b 68  .        apNew[h
3820: 5d 20 3d 20 70 50 61 67 65 3b 0a 20 20 20 20 20  ] = pPage;.     
3830: 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 6c   }.    }.    sql
3840: 69 74 65 33 5f 66 72 65 65 28 70 2d 3e 61 70 48  ite3_free(p->apH
3850: 61 73 68 29 3b 0a 20 20 20 20 70 2d 3e 61 70 48  ash);.    p->apH
3860: 61 73 68 20 3d 20 61 70 4e 65 77 3b 0a 20 20 20  ash = apNew;.   
3870: 20 70 2d 3e 6e 48 61 73 68 20 3d 20 6e 4e 65 77   p->nHash = nNew
3880: 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  ;.  }..  return 
3890: 28 70 2d 3e 61 70 48 61 73 68 20 3f 20 53 51 4c  (p->apHash ? SQL
38a0: 49 54 45 5f 4f 4b 20 3a 20 53 51 4c 49 54 45 5f  ITE_OK : SQLITE_
38b0: 4e 4f 4d 45 4d 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  NOMEM);.}../*.**
38c0: 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   This function i
38d0: 73 20 75 73 65 64 20 69 6e 74 65 72 6e 61 6c 6c  s used internall
38e0: 79 20 74 6f 20 72 65 6d 6f 76 65 20 74 68 65 20  y to remove the 
38f0: 70 61 67 65 20 70 50 61 67 65 20 66 72 6f 6d 20  page pPage from 
3900: 74 68 65 20 0a 2a 2a 20 50 47 72 6f 75 70 20 4c  the .** PGroup L
3910: 52 55 20 6c 69 73 74 2c 20 69 66 20 69 73 20 70  RU list, if is p
3920: 61 72 74 20 6f 66 20 69 74 2e 20 49 66 20 70 50  art of it. If pP
3930: 61 67 65 20 69 73 20 6e 6f 74 20 70 61 72 74 20  age is not part 
3940: 6f 66 20 74 68 65 20 50 47 72 6f 75 70 0a 2a 2a  of the PGroup.**
3950: 20 4c 52 55 20 6c 69 73 74 2c 20 74 68 65 6e 20   LRU list, then 
3960: 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73  this function is
3970: 20 61 20 6e 6f 2d 6f 70 2e 0a 2a 2a 0a 2a 2a 20   a no-op..**.** 
3980: 54 68 65 20 50 47 72 6f 75 70 20 6d 75 74 65 78  The PGroup mutex
3990: 20 6d 75 73 74 20 62 65 20 68 65 6c 64 20 77 68   must be held wh
39a0: 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  en this function
39b0: 20 69 73 20 63 61 6c 6c 65 64 2e 0a 2a 2a 0a 2a   is called..**.*
39c0: 2a 20 49 66 20 70 50 61 67 65 20 69 73 20 4e 55  * If pPage is NU
39d0: 4c 4c 20 74 68 65 6e 20 74 68 69 73 20 72 6f 75  LL then this rou
39e0: 74 69 6e 65 20 69 73 20 61 20 6e 6f 2d 6f 70 2e  tine is a no-op.
39f0: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
3a00: 70 63 61 63 68 65 31 50 69 6e 50 61 67 65 28 50  pcache1PinPage(P
3a10: 67 48 64 72 31 20 2a 70 50 61 67 65 29 7b 0a 20  gHdr1 *pPage){. 
3a20: 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68 65   PCache1 *pCache
3a30: 3b 0a 20 20 50 47 72 6f 75 70 20 2a 70 47 72 6f  ;.  PGroup *pGro
3a40: 75 70 3b 0a 0a 20 20 69 66 28 20 70 50 61 67 65  up;..  if( pPage
3a50: 3d 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a 20 20  ==0 ) return;.  
3a60: 70 43 61 63 68 65 20 3d 20 70 50 61 67 65 2d 3e  pCache = pPage->
3a70: 70 43 61 63 68 65 3b 0a 20 20 70 47 72 6f 75 70  pCache;.  pGroup
3a80: 20 3d 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75   = pCache->pGrou
3a90: 70 3b 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c  p;.  assert( sql
3aa0: 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28  ite3_mutex_held(
3ab0: 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78 29 20 29  pGroup->mutex) )
3ac0: 3b 0a 20 20 69 66 28 20 70 50 61 67 65 2d 3e 70  ;.  if( pPage->p
3ad0: 4c 72 75 4e 65 78 74 20 7c 7c 20 70 50 61 67 65  LruNext || pPage
3ae0: 3d 3d 70 47 72 6f 75 70 2d 3e 70 4c 72 75 54 61  ==pGroup->pLruTa
3af0: 69 6c 20 29 7b 0a 20 20 20 20 69 66 28 20 70 50  il ){.    if( pP
3b00: 61 67 65 2d 3e 70 4c 72 75 50 72 65 76 20 29 7b  age->pLruPrev ){
3b10: 0a 20 20 20 20 20 20 70 50 61 67 65 2d 3e 70 4c  .      pPage->pL
3b20: 72 75 50 72 65 76 2d 3e 70 4c 72 75 4e 65 78 74  ruPrev->pLruNext
3b30: 20 3d 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65   = pPage->pLruNe
3b40: 78 74 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66  xt;.    }.    if
3b50: 28 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78  ( pPage->pLruNex
3b60: 74 20 29 7b 0a 20 20 20 20 20 20 70 50 61 67 65  t ){.      pPage
3b70: 2d 3e 70 4c 72 75 4e 65 78 74 2d 3e 70 4c 72 75  ->pLruNext->pLru
3b80: 50 72 65 76 20 3d 20 70 50 61 67 65 2d 3e 70 4c  Prev = pPage->pL
3b90: 72 75 50 72 65 76 3b 0a 20 20 20 20 7d 0a 20 20  ruPrev;.    }.  
3ba0: 20 20 69 66 28 20 70 47 72 6f 75 70 2d 3e 70 4c    if( pGroup->pL
3bb0: 72 75 48 65 61 64 3d 3d 70 50 61 67 65 20 29 7b  ruHead==pPage ){
3bc0: 0a 20 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 70  .      pGroup->p
3bd0: 4c 72 75 48 65 61 64 20 3d 20 70 50 61 67 65 2d  LruHead = pPage-
3be0: 3e 70 4c 72 75 4e 65 78 74 3b 0a 20 20 20 20 7d  >pLruNext;.    }
3bf0: 0a 20 20 20 20 69 66 28 20 70 47 72 6f 75 70 2d  .    if( pGroup-
3c00: 3e 70 4c 72 75 54 61 69 6c 3d 3d 70 50 61 67 65  >pLruTail==pPage
3c10: 20 29 7b 0a 20 20 20 20 20 20 70 47 72 6f 75 70   ){.      pGroup
3c20: 2d 3e 70 4c 72 75 54 61 69 6c 20 3d 20 70 50 61  ->pLruTail = pPa
3c30: 67 65 2d 3e 70 4c 72 75 50 72 65 76 3b 0a 20 20  ge->pLruPrev;.  
3c40: 20 20 7d 0a 20 20 20 20 70 50 61 67 65 2d 3e 70    }.    pPage->p
3c50: 4c 72 75 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20  LruNext = 0;.   
3c60: 20 70 50 61 67 65 2d 3e 70 4c 72 75 50 72 65 76   pPage->pLruPrev
3c70: 20 3d 20 30 3b 0a 20 20 20 20 70 50 61 67 65 2d   = 0;.    pPage-
3c80: 3e 70 43 61 63 68 65 2d 3e 6e 52 65 63 79 63 6c  >pCache->nRecycl
3c90: 61 62 6c 65 2d 2d 3b 0a 20 20 7d 0a 7d 0a 0a 0a  able--;.  }.}...
3ca0: 2f 2a 0a 2a 2a 20 52 65 6d 6f 76 65 20 74 68 65  /*.** Remove the
3cb0: 20 70 61 67 65 20 73 75 70 70 6c 69 65 64 20 61   page supplied a
3cc0: 73 20 61 6e 20 61 72 67 75 6d 65 6e 74 20 66 72  s an argument fr
3cd0: 6f 6d 20 74 68 65 20 68 61 73 68 20 74 61 62 6c  om the hash tabl
3ce0: 65 20 0a 2a 2a 20 28 50 43 61 63 68 65 31 2e 61  e .** (PCache1.a
3cf0: 70 48 61 73 68 20 73 74 72 75 63 74 75 72 65 29  pHash structure)
3d00: 20 74 68 61 74 20 69 74 20 69 73 20 63 75 72 72   that it is curr
3d10: 65 6e 74 6c 79 20 73 74 6f 72 65 64 20 69 6e 2e  ently stored in.
3d20: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 50 47 72 6f 75  .**.** The PGrou
3d30: 70 20 6d 75 74 65 78 20 6d 75 73 74 20 62 65 20  p mutex must be 
3d40: 68 65 6c 64 20 77 68 65 6e 20 74 68 69 73 20 66  held when this f
3d50: 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65  unction is calle
3d60: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  d..*/.static voi
3d70: 64 20 70 63 61 63 68 65 31 52 65 6d 6f 76 65 46  d pcache1RemoveF
3d80: 72 6f 6d 48 61 73 68 28 50 67 48 64 72 31 20 2a  romHash(PgHdr1 *
3d90: 70 50 61 67 65 29 7b 0a 20 20 75 6e 73 69 67 6e  pPage){.  unsign
3da0: 65 64 20 69 6e 74 20 68 3b 0a 20 20 50 43 61 63  ed int h;.  PCac
3db0: 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20 70 50  he1 *pCache = pP
3dc0: 61 67 65 2d 3e 70 43 61 63 68 65 3b 0a 20 20 50  age->pCache;.  P
3dd0: 67 48 64 72 31 20 2a 2a 70 70 3b 0a 0a 20 20 61  gHdr1 **pp;..  a
3de0: 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d  ssert( sqlite3_m
3df0: 75 74 65 78 5f 68 65 6c 64 28 70 43 61 63 68 65  utex_held(pCache
3e00: 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78 29  ->pGroup->mutex)
3e10: 20 29 3b 0a 20 20 68 20 3d 20 70 50 61 67 65 2d   );.  h = pPage-
3e20: 3e 69 4b 65 79 20 25 20 70 43 61 63 68 65 2d 3e  >iKey % pCache->
3e30: 6e 48 61 73 68 3b 0a 20 20 66 6f 72 28 70 70 3d  nHash;.  for(pp=
3e40: 26 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b  &pCache->apHash[
3e50: 68 5d 3b 20 28 2a 70 70 29 21 3d 70 50 61 67 65  h]; (*pp)!=pPage
3e60: 3b 20 70 70 3d 26 28 2a 70 70 29 2d 3e 70 4e 65  ; pp=&(*pp)->pNe
3e70: 78 74 29 3b 0a 20 20 2a 70 70 20 3d 20 28 2a 70  xt);.  *pp = (*p
3e80: 70 29 2d 3e 70 4e 65 78 74 3b 0a 0a 20 20 70 43  p)->pNext;..  pC
3e90: 61 63 68 65 2d 3e 6e 50 61 67 65 2d 2d 3b 0a 7d  ache->nPage--;.}
3ea0: 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 74 68 65 72 65  ../*.** If there
3eb0: 20 61 72 65 20 63 75 72 72 65 6e 74 6c 79 20 6d   are currently m
3ec0: 6f 72 65 20 74 68 61 6e 20 6e 4d 61 78 50 61 67  ore than nMaxPag
3ed0: 65 20 70 61 67 65 73 20 61 6c 6c 6f 63 61 74 65  e pages allocate
3ee0: 64 2c 20 74 72 79 0a 2a 2a 20 74 6f 20 72 65 63  d, try.** to rec
3ef0: 79 63 6c 65 20 70 61 67 65 73 20 74 6f 20 72 65  ycle pages to re
3f00: 64 75 63 65 20 74 68 65 20 6e 75 6d 62 65 72 20  duce the number 
3f10: 61 6c 6c 6f 63 61 74 65 64 20 74 6f 20 6e 4d 61  allocated to nMa
3f20: 78 50 61 67 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  xPage..*/.static
3f30: 20 76 6f 69 64 20 70 63 61 63 68 65 31 45 6e 66   void pcache1Enf
3f40: 6f 72 63 65 4d 61 78 50 61 67 65 28 50 47 72 6f  orceMaxPage(PGro
3f50: 75 70 20 2a 70 47 72 6f 75 70 29 7b 0a 20 20 61  up *pGroup){.  a
3f60: 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d  ssert( sqlite3_m
3f70: 75 74 65 78 5f 68 65 6c 64 28 70 47 72 6f 75 70  utex_held(pGroup
3f80: 2d 3e 6d 75 74 65 78 29 20 29 3b 0a 20 20 77 68  ->mutex) );.  wh
3f90: 69 6c 65 28 20 70 47 72 6f 75 70 2d 3e 6e 43 75  ile( pGroup->nCu
3fa0: 72 72 65 6e 74 50 61 67 65 3e 70 47 72 6f 75 70  rrentPage>pGroup
3fb0: 2d 3e 6e 4d 61 78 50 61 67 65 20 26 26 20 70 47  ->nMaxPage && pG
3fc0: 72 6f 75 70 2d 3e 70 4c 72 75 54 61 69 6c 20 29  roup->pLruTail )
3fd0: 7b 0a 20 20 20 20 50 67 48 64 72 31 20 2a 70 20  {.    PgHdr1 *p 
3fe0: 3d 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 54 61  = pGroup->pLruTa
3ff0: 69 6c 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20  il;.    assert( 
4000: 70 2d 3e 70 43 61 63 68 65 2d 3e 70 47 72 6f 75  p->pCache->pGrou
4010: 70 3d 3d 70 47 72 6f 75 70 20 29 3b 0a 20 20 20  p==pGroup );.   
4020: 20 70 63 61 63 68 65 31 50 69 6e 50 61 67 65 28   pcache1PinPage(
4030: 70 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31 52  p);.    pcache1R
4040: 65 6d 6f 76 65 46 72 6f 6d 48 61 73 68 28 70 29  emoveFromHash(p)
4050: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 46 72 65  ;.    pcache1Fre
4060: 65 50 61 67 65 28 70 29 3b 0a 20 20 7d 0a 7d 0a  ePage(p);.  }.}.
4070: 0a 2f 2a 0a 2a 2a 20 44 69 73 63 61 72 64 20 61  ./*.** Discard a
4080: 6c 6c 20 70 61 67 65 73 20 66 72 6f 6d 20 63 61  ll pages from ca
4090: 63 68 65 20 70 43 61 63 68 65 20 77 69 74 68 20  che pCache with 
40a0: 61 20 70 61 67 65 20 6e 75 6d 62 65 72 20 28 6b  a page number (k
40b0: 65 79 20 76 61 6c 75 65 29 20 0a 2a 2a 20 67 72  ey value) .** gr
40c0: 65 61 74 65 72 20 74 68 61 6e 20 6f 72 20 65 71  eater than or eq
40d0: 75 61 6c 20 74 6f 20 69 4c 69 6d 69 74 2e 20 41  ual to iLimit. A
40e0: 6e 79 20 70 69 6e 6e 65 64 20 70 61 67 65 73 20  ny pinned pages 
40f0: 74 68 61 74 20 6d 65 65 74 20 74 68 69 73 20 0a  that meet this .
4100: 2a 2a 20 63 72 69 74 65 72 69 61 20 61 72 65 20  ** criteria are 
4110: 75 6e 70 69 6e 6e 65 64 20 62 65 66 6f 72 65 20  unpinned before 
4120: 74 68 65 79 20 61 72 65 20 64 69 73 63 61 72 64  they are discard
4130: 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 50 43  ed..**.** The PC
4140: 61 63 68 65 20 6d 75 74 65 78 20 6d 75 73 74 20  ache mutex must 
4150: 62 65 20 68 65 6c 64 20 77 68 65 6e 20 74 68 69  be held when thi
4160: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61  s function is ca
4170: 6c 6c 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  lled..*/.static 
4180: 76 6f 69 64 20 70 63 61 63 68 65 31 54 72 75 6e  void pcache1Trun
4190: 63 61 74 65 55 6e 73 61 66 65 28 0a 20 20 50 43  cateUnsafe(.  PC
41a0: 61 63 68 65 31 20 2a 70 43 61 63 68 65 2c 20 20  ache1 *pCache,  
41b0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68             /* Th
41c0: 65 20 63 61 63 68 65 20 74 6f 20 74 72 75 6e 63  e cache to trunc
41d0: 61 74 65 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65  ate */.  unsigne
41e0: 64 20 69 6e 74 20 69 4c 69 6d 69 74 20 20 20 20  d int iLimit    
41f0: 20 20 20 20 20 20 2f 2a 20 44 72 6f 70 20 70 61        /* Drop pa
4200: 67 65 73 20 77 69 74 68 20 74 68 69 73 20 70 67  ges with this pg
4210: 6e 6f 20 6f 72 20 6c 61 72 67 65 72 20 2a 2f 0a  no or larger */.
4220: 29 7b 0a 20 20 54 45 53 54 4f 4e 4c 59 28 20 75  ){.  TESTONLY( u
4230: 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 50 61 67  nsigned int nPag
4240: 65 20 3d 20 30 3b 20 29 20 20 2f 2a 20 54 6f 20  e = 0; )  /* To 
4250: 61 73 73 65 72 74 20 70 43 61 63 68 65 2d 3e 6e  assert pCache->n
4260: 50 61 67 65 20 69 73 20 63 6f 72 72 65 63 74 20  Page is correct 
4270: 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e  */.  unsigned in
4280: 74 20 68 3b 0a 20 20 61 73 73 65 72 74 28 20 73  t h;.  assert( s
4290: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c  qlite3_mutex_hel
42a0: 64 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70  d(pCache->pGroup
42b0: 2d 3e 6d 75 74 65 78 29 20 29 3b 0a 20 20 66 6f  ->mutex) );.  fo
42c0: 72 28 68 3d 30 3b 20 68 3c 70 43 61 63 68 65 2d  r(h=0; h<pCache-
42d0: 3e 6e 48 61 73 68 3b 20 68 2b 2b 29 7b 0a 20 20  >nHash; h++){.  
42e0: 20 20 50 67 48 64 72 31 20 2a 2a 70 70 20 3d 20    PgHdr1 **pp = 
42f0: 26 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b  &pCache->apHash[
4300: 68 5d 3b 20 0a 20 20 20 20 50 67 48 64 72 31 20  h]; .    PgHdr1 
4310: 2a 70 50 61 67 65 3b 0a 20 20 20 20 77 68 69 6c  *pPage;.    whil
4320: 65 28 20 28 70 50 61 67 65 20 3d 20 2a 70 70 29  e( (pPage = *pp)
4330: 21 3d 30 20 29 7b 0a 20 20 20 20 20 20 69 66 28  !=0 ){.      if(
4340: 20 70 50 61 67 65 2d 3e 69 4b 65 79 3e 3d 69 4c   pPage->iKey>=iL
4350: 69 6d 69 74 20 29 7b 0a 20 20 20 20 20 20 20 20  imit ){.        
4360: 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 2d 2d 3b  pCache->nPage--;
4370: 0a 20 20 20 20 20 20 20 20 2a 70 70 20 3d 20 70  .        *pp = p
4380: 50 61 67 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20  Page->pNext;.   
4390: 20 20 20 20 20 70 63 61 63 68 65 31 50 69 6e 50       pcache1PinP
43a0: 61 67 65 28 70 50 61 67 65 29 3b 0a 20 20 20 20  age(pPage);.    
43b0: 20 20 20 20 70 63 61 63 68 65 31 46 72 65 65 50      pcache1FreeP
43c0: 61 67 65 28 70 50 61 67 65 29 3b 0a 20 20 20 20  age(pPage);.    
43d0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20    }else{.       
43e0: 20 70 70 20 3d 20 26 70 50 61 67 65 2d 3e 70 4e   pp = &pPage->pN
43f0: 65 78 74 3b 0a 20 20 20 20 20 20 20 20 54 45 53  ext;.        TES
4400: 54 4f 4e 4c 59 28 20 6e 50 61 67 65 2b 2b 3b 20  TONLY( nPage++; 
4410: 29 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ).      }.    }.
4420: 20 20 7d 0a 20 20 61 73 73 65 72 74 28 20 70 43    }.  assert( pC
4430: 61 63 68 65 2d 3e 6e 50 61 67 65 3d 3d 6e 50 61  ache->nPage==nPa
4440: 67 65 20 29 3b 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a  ge );.}../******
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 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4490: 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 2a 2a 2a 2a  ********/./*****
44a0: 2a 2a 2a 20 73 71 6c 69 74 65 33 5f 70 63 61 63  *** sqlite3_pcac
44b0: 68 65 20 4d 65 74 68 6f 64 73 20 2a 2a 2a 2a 2a  he Methods *****
44c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
44d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
44e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f 2a 0a 2a  *********/../*.*
44f0: 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  * Implementation
4500: 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f   of the sqlite3_
4510: 70 63 61 63 68 65 2e 78 49 6e 69 74 20 6d 65 74  pcache.xInit met
4520: 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  hod..*/.static i
4530: 6e 74 20 70 63 61 63 68 65 31 49 6e 69 74 28 76  nt pcache1Init(v
4540: 6f 69 64 20 2a 4e 6f 74 55 73 65 64 29 7b 0a 20  oid *NotUsed){. 
4550: 20 55 4e 55 53 45 44 5f 50 41 52 41 4d 45 54 45   UNUSED_PARAMETE
4560: 52 28 4e 6f 74 55 73 65 64 29 3b 0a 20 20 61 73  R(NotUsed);.  as
4570: 73 65 72 74 28 20 70 63 61 63 68 65 31 2e 69 73  sert( pcache1.is
4580: 49 6e 69 74 3d 3d 30 20 29 3b 0a 20 20 6d 65 6d  Init==0 );.  mem
4590: 73 65 74 28 26 70 63 61 63 68 65 31 2c 20 30 2c  set(&pcache1, 0,
45a0: 20 73 69 7a 65 6f 66 28 70 63 61 63 68 65 31 29   sizeof(pcache1)
45b0: 29 3b 0a 20 20 69 66 28 20 73 71 6c 69 74 65 33  );.  if( sqlite3
45c0: 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 62 43 6f  GlobalConfig.bCo
45d0: 72 65 4d 75 74 65 78 20 29 7b 0a 20 20 20 20 70  reMutex ){.    p
45e0: 63 61 63 68 65 31 2e 67 72 70 2e 6d 75 74 65 78  cache1.grp.mutex
45f0: 20 3d 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78   = sqlite3_mutex
4600: 5f 61 6c 6c 6f 63 28 53 51 4c 49 54 45 5f 4d 55  _alloc(SQLITE_MU
4610: 54 45 58 5f 53 54 41 54 49 43 5f 4c 52 55 29 3b  TEX_STATIC_LRU);
4620: 0a 20 20 20 20 70 63 61 63 68 65 31 2e 6d 75 74  .    pcache1.mut
4630: 65 78 20 3d 20 73 71 6c 69 74 65 33 5f 6d 75 74  ex = sqlite3_mut
4640: 65 78 5f 61 6c 6c 6f 63 28 53 51 4c 49 54 45 5f  ex_alloc(SQLITE_
4650: 4d 55 54 45 58 5f 53 54 41 54 49 43 5f 50 4d 45  MUTEX_STATIC_PME
4660: 4d 29 3b 0a 20 20 7d 0a 20 20 70 63 61 63 68 65  M);.  }.  pcache
4670: 31 2e 67 72 70 2e 6d 78 50 69 6e 6e 65 64 20 3d  1.grp.mxPinned =
4680: 20 31 30 3b 0a 20 20 70 63 61 63 68 65 31 2e 69   10;.  pcache1.i
4690: 73 49 6e 69 74 20 3d 20 31 3b 0a 20 20 72 65 74  sInit = 1;.  ret
46a0: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
46b0: 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e  ../*.** Implemen
46c0: 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71  tation of the sq
46d0: 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78 53 68  lite3_pcache.xSh
46e0: 75 74 64 6f 77 6e 20 6d 65 74 68 6f 64 2e 0a 2a  utdown method..*
46f0: 2a 20 4e 6f 74 65 20 74 68 61 74 20 74 68 65 20  * Note that the 
4700: 73 74 61 74 69 63 20 6d 75 74 65 78 20 61 6c 6c  static mutex all
4710: 6f 63 61 74 65 64 20 69 6e 20 78 49 6e 69 74 20  ocated in xInit 
4720: 64 6f 65 73 20 0a 2a 2a 20 6e 6f 74 20 6e 65 65  does .** not nee
4730: 64 20 74 6f 20 62 65 20 66 72 65 65 64 2e 0a 2a  d to be freed..*
4740: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63  /.static void pc
4750: 61 63 68 65 31 53 68 75 74 64 6f 77 6e 28 76 6f  ache1Shutdown(vo
4760: 69 64 20 2a 4e 6f 74 55 73 65 64 29 7b 0a 20 20  id *NotUsed){.  
4770: 55 4e 55 53 45 44 5f 50 41 52 41 4d 45 54 45 52  UNUSED_PARAMETER
4780: 28 4e 6f 74 55 73 65 64 29 3b 0a 20 20 61 73 73  (NotUsed);.  ass
4790: 65 72 74 28 20 70 63 61 63 68 65 31 2e 69 73 49  ert( pcache1.isI
47a0: 6e 69 74 21 3d 30 20 29 3b 0a 20 20 6d 65 6d 73  nit!=0 );.  mems
47b0: 65 74 28 26 70 63 61 63 68 65 31 2c 20 30 2c 20  et(&pcache1, 0, 
47c0: 73 69 7a 65 6f 66 28 70 63 61 63 68 65 31 29 29  sizeof(pcache1))
47d0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65  ;.}../*.** Imple
47e0: 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65  mentation of the
47f0: 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e   sqlite3_pcache.
4800: 78 43 72 65 61 74 65 20 6d 65 74 68 6f 64 2e 0a  xCreate method..
4810: 2a 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65 20 61  **.** Allocate a
4820: 20 6e 65 77 20 63 61 63 68 65 2e 0a 2a 2f 0a 73   new cache..*/.s
4830: 74 61 74 69 63 20 73 71 6c 69 74 65 33 5f 70 63  tatic sqlite3_pc
4840: 61 63 68 65 20 2a 70 63 61 63 68 65 31 43 72 65  ache *pcache1Cre
4850: 61 74 65 28 69 6e 74 20 73 7a 50 61 67 65 2c 20  ate(int szPage, 
4860: 69 6e 74 20 73 7a 45 78 74 72 61 2c 20 69 6e 74  int szExtra, int
4870: 20 62 50 75 72 67 65 61 62 6c 65 29 7b 0a 20 20   bPurgeable){.  
4880: 50 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 3b  PCache1 *pCache;
4890: 20 20 20 20 20 20 2f 2a 20 54 68 65 20 6e 65 77        /* The new
48a0: 6c 79 20 63 72 65 61 74 65 64 20 70 61 67 65 20  ly created page 
48b0: 63 61 63 68 65 20 2a 2f 0a 20 20 50 47 72 6f 75  cache */.  PGrou
48c0: 70 20 2a 70 47 72 6f 75 70 3b 20 20 20 20 20 20  p *pGroup;      
48d0: 20 2f 2a 20 54 68 65 20 67 72 6f 75 70 20 74 68   /* The group th
48e0: 65 20 6e 65 77 20 70 61 67 65 20 63 61 63 68 65  e new page cache
48f0: 20 77 69 6c 6c 20 62 65 6c 6f 6e 67 20 74 6f 20   will belong to 
4900: 2a 2f 0a 20 20 69 6e 74 20 73 7a 3b 20 20 20 20  */.  int sz;    
4910: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79             /* By
4920: 74 65 73 20 6f 66 20 6d 65 6d 6f 72 79 20 72 65  tes of memory re
4930: 71 75 69 72 65 64 20 74 6f 20 61 6c 6c 6f 63 61  quired to alloca
4940: 74 65 20 74 68 65 20 6e 65 77 20 63 61 63 68 65  te the new cache
4950: 20 2a 2f 0a 0a 20 20 2f 2a 0a 20 20 2a 2a 20 54   */..  /*.  ** T
4960: 68 65 20 73 65 70 65 72 61 74 65 43 61 63 68 65  he seperateCache
4970: 20 76 61 72 69 61 62 6c 65 20 69 73 20 74 72 75   variable is tru
4980: 65 20 69 66 20 65 61 63 68 20 50 43 61 63 68 65  e if each PCache
4990: 20 68 61 73 20 69 74 73 20 6f 77 6e 20 70 72 69   has its own pri
49a0: 76 61 74 65 0a 20 20 2a 2a 20 50 47 72 6f 75 70  vate.  ** PGroup
49b0: 2e 20 20 49 6e 20 6f 74 68 65 72 20 77 6f 72 64  .  In other word
49c0: 73 2c 20 73 65 70 61 72 61 74 65 43 61 63 68 65  s, separateCache
49d0: 20 69 73 20 74 72 75 65 20 66 6f 72 20 6d 6f 64   is true for mod
49e0: 65 20 28 31 29 20 77 68 65 72 65 20 6e 6f 0a 20  e (1) where no. 
49f0: 20 2a 2a 20 6d 75 74 65 78 69 6e 67 20 69 73 20   ** mutexing is 
4a00: 72 65 71 75 69 72 65 64 2e 0a 20 20 2a 2a 0a 20  required..  **. 
4a10: 20 2a 2a 20 20 20 2a 20 20 41 6c 77 61 79 73 20   **   *  Always 
4a20: 75 73 65 20 61 20 75 6e 69 66 69 65 64 20 63 61  use a unified ca
4a30: 63 68 65 20 28 6d 6f 64 65 2d 32 29 20 69 66 20  che (mode-2) if 
4a40: 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41  ENABLE_MEMORY_MA
4a50: 4e 41 47 45 4d 45 4e 54 0a 20 20 2a 2a 0a 20 20  NAGEMENT.  **.  
4a60: 2a 2a 20 20 20 2a 20 20 41 6c 77 61 79 73 20 75  **   *  Always u
4a70: 73 65 20 61 20 75 6e 69 66 69 65 64 20 63 61 63  se a unified cac
4a80: 68 65 20 69 6e 20 73 69 6e 67 6c 65 2d 74 68 72  he in single-thr
4a90: 65 61 64 65 64 20 61 70 70 6c 69 63 61 74 69 6f  eaded applicatio
4aa0: 6e 73 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 2a  ns.  **.  **   *
4ab0: 20 20 4f 74 68 65 72 77 69 73 65 20 28 69 66 20    Otherwise (if 
4ac0: 6d 75 6c 74 69 2d 74 68 72 65 61 64 65 64 20 61  multi-threaded a
4ad0: 6e 64 20 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59  nd ENABLE_MEMORY
4ae0: 5f 4d 41 4e 41 47 45 4d 45 4e 54 20 69 73 20 6f  _MANAGEMENT is o
4af0: 66 66 29 0a 20 20 2a 2a 20 20 20 20 20 20 75 73  ff).  **      us
4b00: 65 20 73 65 70 61 72 61 74 65 20 63 61 63 68 65  e separate cache
4b10: 73 20 28 6d 6f 64 65 2d 31 29 0a 20 20 2a 2f 0a  s (mode-1).  */.
4b20: 23 69 66 20 64 65 66 69 6e 65 64 28 53 51 4c 49  #if defined(SQLI
4b30: 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59  TE_ENABLE_MEMORY
4b40: 5f 4d 41 4e 41 47 45 4d 45 4e 54 29 20 7c 7c 20  _MANAGEMENT) || 
4b50: 53 51 4c 49 54 45 5f 54 48 52 45 41 44 53 41 46  SQLITE_THREADSAF
4b60: 45 3d 3d 30 0a 20 20 63 6f 6e 73 74 20 69 6e 74  E==0.  const int
4b70: 20 73 65 70 61 72 61 74 65 43 61 63 68 65 20 3d   separateCache =
4b80: 20 30 3b 0a 23 65 6c 73 65 0a 20 20 69 6e 74 20   0;.#else.  int 
4b90: 73 65 70 61 72 61 74 65 43 61 63 68 65 20 3d 20  separateCache = 
4ba0: 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e  sqlite3GlobalCon
4bb0: 66 69 67 2e 62 43 6f 72 65 4d 75 74 65 78 3e 30  fig.bCoreMutex>0
4bc0: 3b 0a 23 65 6e 64 69 66 0a 0a 20 20 61 73 73 65  ;.#endif..  asse
4bd0: 72 74 28 20 28 73 7a 50 61 67 65 20 26 20 28 73  rt( (szPage & (s
4be0: 7a 50 61 67 65 2d 31 29 29 3d 3d 30 20 26 26 20  zPage-1))==0 && 
4bf0: 73 7a 50 61 67 65 3e 3d 35 31 32 20 26 26 20 73  szPage>=512 && s
4c00: 7a 50 61 67 65 3c 3d 36 35 35 33 36 20 29 3b 0a  zPage<=65536 );.
4c10: 20 20 61 73 73 65 72 74 28 20 73 7a 45 78 74 72    assert( szExtr
4c20: 61 20 3c 20 33 30 30 20 29 3b 0a 0a 20 20 73 7a  a < 300 );..  sz
4c30: 20 3d 20 73 69 7a 65 6f 66 28 50 43 61 63 68 65   = sizeof(PCache
4c40: 31 29 20 2b 20 73 69 7a 65 6f 66 28 50 47 72 6f  1) + sizeof(PGro
4c50: 75 70 29 2a 73 65 70 61 72 61 74 65 43 61 63 68  up)*separateCach
4c60: 65 3b 0a 20 20 70 43 61 63 68 65 20 3d 20 28 50  e;.  pCache = (P
4c70: 43 61 63 68 65 31 20 2a 29 73 71 6c 69 74 65 33  Cache1 *)sqlite3
4c80: 5f 6d 61 6c 6c 6f 63 28 73 7a 29 3b 0a 20 20 69  _malloc(sz);.  i
4c90: 66 28 20 70 43 61 63 68 65 20 29 7b 0a 20 20 20  f( pCache ){.   
4ca0: 20 6d 65 6d 73 65 74 28 70 43 61 63 68 65 2c 20   memset(pCache, 
4cb0: 30 2c 20 73 7a 29 3b 0a 20 20 20 20 69 66 28 20  0, sz);.    if( 
4cc0: 73 65 70 61 72 61 74 65 43 61 63 68 65 20 29 7b  separateCache ){
4cd0: 0a 20 20 20 20 20 20 70 47 72 6f 75 70 20 3d 20  .      pGroup = 
4ce0: 28 50 47 72 6f 75 70 2a 29 26 70 43 61 63 68 65  (PGroup*)&pCache
4cf0: 5b 31 5d 3b 0a 20 20 20 20 20 20 70 47 72 6f 75  [1];.      pGrou
4d00: 70 2d 3e 6d 78 50 69 6e 6e 65 64 20 3d 20 31 30  p->mxPinned = 10
4d10: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
4d20: 20 20 20 70 47 72 6f 75 70 20 3d 20 26 70 63 61     pGroup = &pca
4d30: 63 68 65 31 2e 67 72 70 3b 0a 20 20 20 20 7d 0a  che1.grp;.    }.
4d40: 20 20 20 20 70 43 61 63 68 65 2d 3e 70 47 72 6f      pCache->pGro
4d50: 75 70 20 3d 20 70 47 72 6f 75 70 3b 0a 20 20 20  up = pGroup;.   
4d60: 20 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 20   pCache->szPage 
4d70: 3d 20 73 7a 50 61 67 65 3b 0a 20 20 20 20 70 43  = szPage;.    pC
4d80: 61 63 68 65 2d 3e 73 7a 45 78 74 72 61 20 3d 20  ache->szExtra = 
4d90: 73 7a 45 78 74 72 61 3b 0a 20 20 20 20 70 43 61  szExtra;.    pCa
4da0: 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20  che->bPurgeable 
4db0: 3d 20 28 62 50 75 72 67 65 61 62 6c 65 20 3f 20  = (bPurgeable ? 
4dc0: 31 20 3a 20 30 29 3b 0a 20 20 20 20 69 66 28 20  1 : 0);.    if( 
4dd0: 62 50 75 72 67 65 61 62 6c 65 20 29 7b 0a 20 20  bPurgeable ){.  
4de0: 20 20 20 20 70 43 61 63 68 65 2d 3e 6e 4d 69 6e      pCache->nMin
4df0: 20 3d 20 31 30 3b 0a 20 20 20 20 20 20 70 63 61   = 10;.      pca
4e00: 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70  che1EnterMutex(p
4e10: 47 72 6f 75 70 29 3b 0a 20 20 20 20 20 20 70 47  Group);.      pG
4e20: 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67 65 20 2b  roup->nMinPage +
4e30: 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 3b 0a  = pCache->nMin;.
4e40: 20 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 6d 78        pGroup->mx
4e50: 50 69 6e 6e 65 64 20 3d 20 70 47 72 6f 75 70 2d  Pinned = pGroup-
4e60: 3e 6e 4d 61 78 50 61 67 65 20 2b 20 31 30 20 2d  >nMaxPage + 10 -
4e70: 20 70 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67   pGroup->nMinPag
4e80: 65 3b 0a 20 20 20 20 20 20 70 63 61 63 68 65 31  e;.      pcache1
4e90: 4c 65 61 76 65 4d 75 74 65 78 28 70 47 72 6f 75  LeaveMutex(pGrou
4ea0: 70 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20  p);.    }.  }.  
4eb0: 72 65 74 75 72 6e 20 28 73 71 6c 69 74 65 33 5f  return (sqlite3_
4ec0: 70 63 61 63 68 65 20 2a 29 70 43 61 63 68 65 3b  pcache *)pCache;
4ed0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d  .}../*.** Implem
4ee0: 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20  entation of the 
4ef0: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78  sqlite3_pcache.x
4f00: 43 61 63 68 65 73 69 7a 65 20 6d 65 74 68 6f 64  Cachesize method
4f10: 2e 20 0a 2a 2a 0a 2a 2a 20 43 6f 6e 66 69 67 75  . .**.** Configu
4f20: 72 65 20 74 68 65 20 63 61 63 68 65 5f 73 69 7a  re the cache_siz
4f30: 65 20 6c 69 6d 69 74 20 66 6f 72 20 61 20 63 61  e limit for a ca
4f40: 63 68 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  che..*/.static v
4f50: 6f 69 64 20 70 63 61 63 68 65 31 43 61 63 68 65  oid pcache1Cache
4f60: 73 69 7a 65 28 73 71 6c 69 74 65 33 5f 70 63 61  size(sqlite3_pca
4f70: 63 68 65 20 2a 70 2c 20 69 6e 74 20 6e 4d 61 78  che *p, int nMax
4f80: 29 7b 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43  ){.  PCache1 *pC
4f90: 61 63 68 65 20 3d 20 28 50 43 61 63 68 65 31 20  ache = (PCache1 
4fa0: 2a 29 70 3b 0a 20 20 69 66 28 20 70 43 61 63 68  *)p;.  if( pCach
4fb0: 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 29 7b  e->bPurgeable ){
4fc0: 0a 20 20 20 20 50 47 72 6f 75 70 20 2a 70 47 72  .    PGroup *pGr
4fd0: 6f 75 70 20 3d 20 70 43 61 63 68 65 2d 3e 70 47  oup = pCache->pG
4fe0: 72 6f 75 70 3b 0a 20 20 20 20 70 63 61 63 68 65  roup;.    pcache
4ff0: 31 45 6e 74 65 72 4d 75 74 65 78 28 70 47 72 6f  1EnterMutex(pGro
5000: 75 70 29 3b 0a 20 20 20 20 70 47 72 6f 75 70 2d  up);.    pGroup-
5010: 3e 6e 4d 61 78 50 61 67 65 20 2b 3d 20 28 6e 4d  >nMaxPage += (nM
5020: 61 78 20 2d 20 70 43 61 63 68 65 2d 3e 6e 4d 61  ax - pCache->nMa
5030: 78 29 3b 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e  x);.    pGroup->
5040: 6d 78 50 69 6e 6e 65 64 20 3d 20 70 47 72 6f 75  mxPinned = pGrou
5050: 70 2d 3e 6e 4d 61 78 50 61 67 65 20 2b 20 31 30  p->nMaxPage + 10
5060: 20 2d 20 70 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50   - pGroup->nMinP
5070: 61 67 65 3b 0a 20 20 20 20 70 43 61 63 68 65 2d  age;.    pCache-
5080: 3e 6e 4d 61 78 20 3d 20 6e 4d 61 78 3b 0a 20 20  >nMax = nMax;.  
5090: 20 20 70 43 61 63 68 65 2d 3e 6e 39 30 70 63 74    pCache->n90pct
50a0: 20 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 2a   = pCache->nMax*
50b0: 39 2f 31 30 3b 0a 20 20 20 20 70 63 61 63 68 65  9/10;.    pcache
50c0: 31 45 6e 66 6f 72 63 65 4d 61 78 50 61 67 65 28  1EnforceMaxPage(
50d0: 70 47 72 6f 75 70 29 3b 0a 20 20 20 20 70 63 61  pGroup);.    pca
50e0: 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 70  che1LeaveMutex(p
50f0: 47 72 6f 75 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f  Group);.  }.}../
5100: 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74  *.** Implementat
5110: 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74  ion of the sqlit
5120: 65 33 5f 70 63 61 63 68 65 2e 78 53 68 72 69 6e  e3_pcache.xShrin
5130: 6b 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a  k method. .**.**
5140: 20 46 72 65 65 20 75 70 20 61 73 20 6d 75 63 68   Free up as much
5150: 20 6d 65 6d 6f 72 79 20 61 73 20 70 6f 73 73 69   memory as possi
5160: 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ble..*/.static v
5170: 6f 69 64 20 70 63 61 63 68 65 31 53 68 72 69 6e  oid pcache1Shrin
5180: 6b 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  k(sqlite3_pcache
5190: 20 2a 70 29 7b 0a 20 20 50 43 61 63 68 65 31 20   *p){.  PCache1 
51a0: 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61 63 68  *pCache = (PCach
51b0: 65 31 2a 29 70 3b 0a 20 20 69 66 28 20 70 43 61  e1*)p;.  if( pCa
51c0: 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20  che->bPurgeable 
51d0: 29 7b 0a 20 20 20 20 50 47 72 6f 75 70 20 2a 70  ){.    PGroup *p
51e0: 47 72 6f 75 70 20 3d 20 70 43 61 63 68 65 2d 3e  Group = pCache->
51f0: 70 47 72 6f 75 70 3b 0a 20 20 20 20 69 6e 74 20  pGroup;.    int 
5200: 73 61 76 65 64 4d 61 78 50 61 67 65 3b 0a 20 20  savedMaxPage;.  
5210: 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75    pcache1EnterMu
5220: 74 65 78 28 70 47 72 6f 75 70 29 3b 0a 20 20 20  tex(pGroup);.   
5230: 20 73 61 76 65 64 4d 61 78 50 61 67 65 20 3d 20   savedMaxPage = 
5240: 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65  pGroup->nMaxPage
5250: 3b 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e 6e 4d  ;.    pGroup->nM
5260: 61 78 50 61 67 65 20 3d 20 30 3b 0a 20 20 20 20  axPage = 0;.    
5270: 70 63 61 63 68 65 31 45 6e 66 6f 72 63 65 4d 61  pcache1EnforceMa
5280: 78 50 61 67 65 28 70 47 72 6f 75 70 29 3b 0a 20  xPage(pGroup);. 
5290: 20 20 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50     pGroup->nMaxP
52a0: 61 67 65 20 3d 20 73 61 76 65 64 4d 61 78 50 61  age = savedMaxPa
52b0: 67 65 3b 0a 20 20 20 20 70 63 61 63 68 65 31 4c  ge;.    pcache1L
52c0: 65 61 76 65 4d 75 74 65 78 28 70 47 72 6f 75 70  eaveMutex(pGroup
52d0: 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  );.  }.}../*.** 
52e0: 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  Implementation o
52f0: 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63  f the sqlite3_pc
5300: 61 63 68 65 2e 78 50 61 67 65 63 6f 75 6e 74 20  ache.xPagecount 
5310: 6d 65 74 68 6f 64 2e 20 0a 2a 2f 0a 73 74 61 74  method. .*/.stat
5320: 69 63 20 69 6e 74 20 70 63 61 63 68 65 31 50 61  ic int pcache1Pa
5330: 67 65 63 6f 75 6e 74 28 73 71 6c 69 74 65 33 5f  gecount(sqlite3_
5340: 70 63 61 63 68 65 20 2a 70 29 7b 0a 20 20 69 6e  pcache *p){.  in
5350: 74 20 6e 3b 0a 20 20 50 43 61 63 68 65 31 20 2a  t n;.  PCache1 *
5360: 70 43 61 63 68 65 20 3d 20 28 50 43 61 63 68 65  pCache = (PCache
5370: 31 2a 29 70 3b 0a 20 20 70 63 61 63 68 65 31 45  1*)p;.  pcache1E
5380: 6e 74 65 72 4d 75 74 65 78 28 70 43 61 63 68 65  nterMutex(pCache
5390: 2d 3e 70 47 72 6f 75 70 29 3b 0a 20 20 6e 20 3d  ->pGroup);.  n =
53a0: 20 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 3b 0a   pCache->nPage;.
53b0: 20 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75    pcache1LeaveMu
53c0: 74 65 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f  tex(pCache->pGro
53d0: 75 70 29 3b 0a 20 20 72 65 74 75 72 6e 20 6e 3b  up);.  return n;
53e0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d  .}../*.** Implem
53f0: 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20  entation of the 
5400: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78  sqlite3_pcache.x
5410: 46 65 74 63 68 20 6d 65 74 68 6f 64 2e 20 0a 2a  Fetch method. .*
5420: 2a 0a 2a 2a 20 46 65 74 63 68 20 61 20 70 61 67  *.** Fetch a pag
5430: 65 20 62 79 20 6b 65 79 20 76 61 6c 75 65 2e 0a  e by key value..
5440: 2a 2a 0a 2a 2a 20 57 68 65 74 68 65 72 20 6f 72  **.** Whether or
5450: 20 6e 6f 74 20 61 20 6e 65 77 20 70 61 67 65 20   not a new page 
5460: 6d 61 79 20 62 65 20 61 6c 6c 6f 63 61 74 65 64  may be allocated
5470: 20 62 79 20 74 68 69 73 20 66 75 6e 63 74 69 6f   by this functio
5480: 6e 20 64 65 70 65 6e 64 73 20 6f 6e 0a 2a 2a 20  n depends on.** 
5490: 74 68 65 20 76 61 6c 75 65 20 6f 66 20 74 68 65  the value of the
54a0: 20 63 72 65 61 74 65 46 6c 61 67 20 61 72 67 75   createFlag argu
54b0: 6d 65 6e 74 2e 20 20 30 20 6d 65 61 6e 73 20 64  ment.  0 means d
54c0: 6f 20 6e 6f 74 20 61 6c 6c 6f 63 61 74 65 20 61  o not allocate a
54d0: 20 6e 65 77 0a 2a 2a 20 70 61 67 65 2e 20 20 31   new.** page.  1
54e0: 20 6d 65 61 6e 73 20 61 6c 6c 6f 63 61 74 65 20   means allocate 
54f0: 61 20 6e 65 77 20 70 61 67 65 20 69 66 20 73 70  a new page if sp
5500: 61 63 65 20 69 73 20 65 61 73 69 6c 79 20 61 76  ace is easily av
5510: 61 69 6c 61 62 6c 65 2e 20 20 32 20 0a 2a 2a 20  ailable.  2 .** 
5520: 6d 65 61 6e 73 20 74 6f 20 74 72 79 20 72 65 61  means to try rea
5530: 6c 6c 79 20 68 61 72 64 20 74 6f 20 61 6c 6c 6f  lly hard to allo
5540: 63 61 74 65 20 61 20 6e 65 77 20 70 61 67 65 2e  cate a new page.
5550: 0a 2a 2a 0a 2a 2a 20 46 6f 72 20 61 20 6e 6f 6e  .**.** For a non
5560: 2d 70 75 72 67 65 61 62 6c 65 20 63 61 63 68 65  -purgeable cache
5570: 20 28 61 20 63 61 63 68 65 20 75 73 65 64 20 61   (a cache used a
5580: 73 20 74 68 65 20 73 74 6f 72 61 67 65 20 66 6f  s the storage fo
5590: 72 20 61 6e 20 69 6e 2d 6d 65 6d 6f 72 79 0a 2a  r an in-memory.*
55a0: 2a 20 64 61 74 61 62 61 73 65 29 20 74 68 65 72  * database) ther
55b0: 65 20 69 73 20 72 65 61 6c 6c 79 20 6e 6f 20 64  e is really no d
55c0: 69 66 66 65 72 65 6e 63 65 20 62 65 74 77 65 65  ifference betwee
55d0: 6e 20 63 72 65 61 74 65 46 6c 61 67 20 31 20 61  n createFlag 1 a
55e0: 6e 64 20 32 2e 20 20 53 6f 0a 2a 2a 20 74 68 65  nd 2.  So.** the
55f0: 20 63 61 6c 6c 69 6e 67 20 66 75 6e 63 74 69 6f   calling functio
5600: 6e 20 28 70 63 61 63 68 65 2e 63 29 20 77 69 6c  n (pcache.c) wil
5610: 6c 20 6e 65 76 65 72 20 68 61 76 65 20 61 20 63  l never have a c
5620: 72 65 61 74 65 46 6c 61 67 20 6f 66 20 31 20 6f  reateFlag of 1 o
5630: 6e 0a 2a 2a 20 61 20 6e 6f 6e 2d 70 75 72 67 61  n.** a non-purga
5640: 62 6c 65 20 63 61 63 68 65 2e 0a 2a 2a 0a 2a 2a  ble cache..**.**
5650: 20 54 68 65 72 65 20 61 72 65 20 74 68 72 65 65   There are three
5660: 20 64 69 66 66 65 72 65 6e 74 20 61 70 70 72 6f   different appro
5670: 61 63 68 65 73 20 74 6f 20 6f 62 74 61 69 6e 69  aches to obtaini
5680: 6e 67 20 73 70 61 63 65 20 66 6f 72 20 61 20 70  ng space for a p
5690: 61 67 65 2c 0a 2a 2a 20 64 65 70 65 6e 64 69 6e  age,.** dependin
56a0: 67 20 6f 6e 20 74 68 65 20 76 61 6c 75 65 20 6f  g on the value o
56b0: 66 20 70 61 72 61 6d 65 74 65 72 20 63 72 65 61  f parameter crea
56c0: 74 65 46 6c 61 67 20 28 77 68 69 63 68 20 6d 61  teFlag (which ma
56d0: 79 20 62 65 20 30 2c 20 31 20 6f 72 20 32 29 2e  y be 0, 1 or 2).
56e0: 0a 2a 2a 0a 2a 2a 20 20 20 31 2e 20 52 65 67 61  .**.**   1. Rega
56f0: 72 64 6c 65 73 73 20 6f 66 20 74 68 65 20 76 61  rdless of the va
5700: 6c 75 65 20 6f 66 20 63 72 65 61 74 65 46 6c 61  lue of createFla
5710: 67 2c 20 74 68 65 20 63 61 63 68 65 20 69 73 20  g, the cache is 
5720: 73 65 61 72 63 68 65 64 20 66 6f 72 20 61 20 0a  searched for a .
5730: 2a 2a 20 20 20 20 20 20 63 6f 70 79 20 6f 66 20  **      copy of 
5740: 74 68 65 20 72 65 71 75 65 73 74 65 64 20 70 61  the requested pa
5750: 67 65 2e 20 49 66 20 6f 6e 65 20 69 73 20 66 6f  ge. If one is fo
5760: 75 6e 64 2c 20 69 74 20 69 73 20 72 65 74 75 72  und, it is retur
5770: 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 32 2e 20  ned..**.**   2. 
5780: 49 66 20 63 72 65 61 74 65 46 6c 61 67 3d 3d 30  If createFlag==0
5790: 20 61 6e 64 20 74 68 65 20 70 61 67 65 20 69 73   and the page is
57a0: 20 6e 6f 74 20 61 6c 72 65 61 64 79 20 69 6e 20   not already in 
57b0: 74 68 65 20 63 61 63 68 65 2c 20 4e 55 4c 4c 20  the cache, NULL 
57c0: 69 73 0a 2a 2a 20 20 20 20 20 20 72 65 74 75 72  is.**      retur
57d0: 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 33 2e 20  ned..**.**   3. 
57e0: 49 66 20 63 72 65 61 74 65 46 6c 61 67 20 69 73  If createFlag is
57f0: 20 31 2c 20 61 6e 64 20 74 68 65 20 70 61 67 65   1, and the page
5800: 20 69 73 20 6e 6f 74 20 61 6c 72 65 61 64 79 20   is not already 
5810: 69 6e 20 74 68 65 20 63 61 63 68 65 2c 20 74 68  in the cache, th
5820: 65 6e 0a 2a 2a 20 20 20 20 20 20 72 65 74 75 72  en.**      retur
5830: 6e 20 4e 55 4c 4c 20 28 64 6f 20 6e 6f 74 20 61  n NULL (do not a
5840: 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 70 61  llocate a new pa
5850: 67 65 29 20 69 66 20 61 6e 79 20 6f 66 20 74 68  ge) if any of th
5860: 65 20 66 6f 6c 6c 6f 77 69 6e 67 0a 2a 2a 20 20  e following.**  
5870: 20 20 20 20 63 6f 6e 64 69 74 69 6f 6e 73 20 61      conditions a
5880: 72 65 20 74 72 75 65 3a 0a 2a 2a 0a 2a 2a 20 20  re true:.**.**  
5890: 20 20 20 20 20 28 61 29 20 74 68 65 20 6e 75 6d       (a) the num
58a0: 62 65 72 20 6f 66 20 70 61 67 65 73 20 70 69 6e  ber of pages pin
58b0: 6e 65 64 20 62 79 20 74 68 65 20 63 61 63 68 65  ned by the cache
58c0: 20 69 73 20 67 72 65 61 74 65 72 20 74 68 61 6e   is greater than
58d0: 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 50 43  .**           PC
58e0: 61 63 68 65 31 2e 6e 4d 61 78 2c 20 6f 72 0a 2a  ache1.nMax, or.*
58f0: 2a 0a 2a 2a 20 20 20 20 20 20 20 28 62 29 20 74  *.**       (b) t
5900: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67  he number of pag
5910: 65 73 20 70 69 6e 6e 65 64 20 62 79 20 74 68 65  es pinned by the
5920: 20 63 61 63 68 65 20 69 73 20 67 72 65 61 74 65   cache is greate
5930: 72 20 74 68 61 6e 0a 2a 2a 20 20 20 20 20 20 20  r than.**       
5940: 20 20 20 20 74 68 65 20 73 75 6d 20 6f 66 20 6e      the sum of n
5950: 4d 61 78 20 66 6f 72 20 61 6c 6c 20 70 75 72 67  Max for all purg
5960: 65 61 62 6c 65 20 63 61 63 68 65 73 2c 20 6c 65  eable caches, le
5970: 73 73 20 74 68 65 20 73 75 6d 20 6f 66 20 0a 2a  ss the sum of .*
5980: 2a 20 20 20 20 20 20 20 20 20 20 20 6e 4d 69 6e  *           nMin
5990: 20 66 6f 72 20 61 6c 6c 20 6f 74 68 65 72 20 70   for all other p
59a0: 75 72 67 65 61 62 6c 65 20 63 61 63 68 65 73 2c  urgeable caches,
59b0: 20 6f 72 0a 2a 2a 0a 2a 2a 20 20 20 34 2e 20 49   or.**.**   4. I
59c0: 66 20 6e 6f 6e 65 20 6f 66 20 74 68 65 20 66 69  f none of the fi
59d0: 72 73 74 20 74 68 72 65 65 20 63 6f 6e 64 69 74  rst three condit
59e0: 69 6f 6e 73 20 61 70 70 6c 79 20 61 6e 64 20 74  ions apply and t
59f0: 68 65 20 63 61 63 68 65 20 69 73 20 6d 61 72 6b  he cache is mark
5a00: 65 64 0a 2a 2a 20 20 20 20 20 20 61 73 20 70 75  ed.**      as pu
5a10: 72 67 65 61 62 6c 65 2c 20 61 6e 64 20 69 66 20  rgeable, and if 
5a20: 6f 6e 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f  one of the follo
5a30: 77 69 6e 67 20 69 73 20 74 72 75 65 3a 0a 2a 2a  wing is true:.**
5a40: 0a 2a 2a 20 20 20 20 20 20 20 28 61 29 20 54 68  .**       (a) Th
5a50: 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65  e number of page
5a60: 73 20 61 6c 6c 6f 63 61 74 65 64 20 66 6f 72 20  s allocated for 
5a70: 74 68 65 20 63 61 63 68 65 20 69 73 20 61 6c 72  the cache is alr
5a80: 65 61 64 79 20 0a 2a 2a 20 20 20 20 20 20 20 20  eady .**        
5a90: 20 20 20 50 43 61 63 68 65 31 2e 6e 4d 61 78 2c     PCache1.nMax,
5aa0: 20 6f 72 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20   or.**.**       
5ab0: 28 62 29 20 54 68 65 20 6e 75 6d 62 65 72 20 6f  (b) The number o
5ac0: 66 20 70 61 67 65 73 20 61 6c 6c 6f 63 61 74 65  f pages allocate
5ad0: 64 20 66 6f 72 20 61 6c 6c 20 70 75 72 67 65 61  d for all purgea
5ae0: 62 6c 65 20 63 61 63 68 65 73 20 69 73 0a 2a 2a  ble caches is.**
5af0: 20 20 20 20 20 20 20 20 20 20 20 61 6c 72 65 61             alrea
5b00: 64 79 20 65 71 75 61 6c 20 74 6f 20 6f 72 20 67  dy equal to or g
5b10: 72 65 61 74 65 72 20 74 68 61 6e 20 74 68 65 20  reater than the 
5b20: 73 75 6d 20 6f 66 20 6e 4d 61 78 20 66 6f 72 20  sum of nMax for 
5b30: 61 6c 6c 0a 2a 2a 20 20 20 20 20 20 20 20 20 20  all.**          
5b40: 20 70 75 72 67 65 61 62 6c 65 20 63 61 63 68 65   purgeable cache
5b50: 73 2c 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 28  s,.**.**       (
5b60: 63 29 20 54 68 65 20 73 79 73 74 65 6d 20 69 73  c) The system is
5b70: 20 75 6e 64 65 72 20 6d 65 6d 6f 72 79 20 70 72   under memory pr
5b80: 65 73 73 75 72 65 20 61 6e 64 20 77 61 6e 74 73  essure and wants
5b90: 20 74 6f 20 61 76 6f 69 64 0a 2a 2a 20 20 20 20   to avoid.**    
5ba0: 20 20 20 20 20 20 20 75 6e 6e 65 63 65 73 73 61         unnecessa
5bb0: 72 79 20 70 61 67 65 73 20 63 61 63 68 65 20 65  ry pages cache e
5bc0: 6e 74 72 79 20 61 6c 6c 6f 63 61 74 69 6f 6e 73  ntry allocations
5bd0: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 74 68 65 6e  .**.**      then
5be0: 20 61 74 74 65 6d 70 74 20 74 6f 20 72 65 63 79   attempt to recy
5bf0: 63 6c 65 20 61 20 70 61 67 65 20 66 72 6f 6d 20  cle a page from 
5c00: 74 68 65 20 4c 52 55 20 6c 69 73 74 2e 20 49 66  the LRU list. If
5c10: 20 69 74 20 69 73 20 74 68 65 20 72 69 67 68 74   it is the right
5c20: 0a 2a 2a 20 20 20 20 20 20 73 69 7a 65 2c 20 72  .**      size, r
5c30: 65 74 75 72 6e 20 74 68 65 20 72 65 63 79 63 6c  eturn the recycl
5c40: 65 64 20 62 75 66 66 65 72 2e 20 4f 74 68 65 72  ed buffer. Other
5c50: 77 69 73 65 2c 20 66 72 65 65 20 74 68 65 20 62  wise, free the b
5c60: 75 66 66 65 72 20 61 6e 64 0a 2a 2a 20 20 20 20  uffer and.**    
5c70: 20 20 70 72 6f 63 65 65 64 20 74 6f 20 73 74 65    proceed to ste
5c80: 70 20 35 2e 20 0a 2a 2a 0a 2a 2a 20 20 20 35 2e  p 5. .**.**   5.
5c90: 20 4f 74 68 65 72 77 69 73 65 2c 20 61 6c 6c 6f   Otherwise, allo
5ca0: 63 61 74 65 20 61 6e 64 20 72 65 74 75 72 6e 20  cate and return 
5cb0: 61 20 6e 65 77 20 70 61 67 65 20 62 75 66 66 65  a new page buffe
5cc0: 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 73 71 6c  r..*/.static sql
5cd0: 69 74 65 33 5f 70 63 61 63 68 65 5f 70 61 67 65  ite3_pcache_page
5ce0: 20 2a 70 63 61 63 68 65 31 46 65 74 63 68 28 0a   *pcache1Fetch(.
5cf0: 20 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65    sqlite3_pcache
5d00: 20 2a 70 2c 20 0a 20 20 75 6e 73 69 67 6e 65 64   *p, .  unsigned
5d10: 20 69 6e 74 20 69 4b 65 79 2c 20 0a 20 20 69 6e   int iKey, .  in
5d20: 74 20 63 72 65 61 74 65 46 6c 61 67 0a 29 7b 0a  t createFlag.){.
5d30: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e    unsigned int n
5d40: 50 69 6e 6e 65 64 3b 0a 20 20 50 43 61 63 68 65  Pinned;.  PCache
5d50: 31 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61  1 *pCache = (PCa
5d60: 63 68 65 31 20 2a 29 70 3b 0a 20 20 50 47 72 6f  che1 *)p;.  PGro
5d70: 75 70 20 2a 70 47 72 6f 75 70 3b 0a 20 20 50 67  up *pGroup;.  Pg
5d80: 48 64 72 31 20 2a 70 50 61 67 65 20 3d 20 30 3b  Hdr1 *pPage = 0;
5d90: 0a 0a 20 20 61 73 73 65 72 74 28 20 70 43 61 63  ..  assert( pCac
5da0: 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 7c  he->bPurgeable |
5db0: 7c 20 63 72 65 61 74 65 46 6c 61 67 21 3d 31 20  | createFlag!=1 
5dc0: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 43 61  );.  assert( pCa
5dd0: 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20  che->bPurgeable 
5de0: 7c 7c 20 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 3d  || pCache->nMin=
5df0: 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  =0 );.  assert( 
5e00: 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62  pCache->bPurgeab
5e10: 6c 65 3d 3d 30 20 7c 7c 20 70 43 61 63 68 65 2d  le==0 || pCache-
5e20: 3e 6e 4d 69 6e 3d 3d 31 30 20 29 3b 0a 20 20 61  >nMin==10 );.  a
5e30: 73 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e 6e  ssert( pCache->n
5e40: 4d 69 6e 3d 3d 30 20 7c 7c 20 70 43 61 63 68 65  Min==0 || pCache
5e50: 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 29 3b 0a  ->bPurgeable );.
5e60: 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75    pcache1EnterMu
5e70: 74 65 78 28 70 47 72 6f 75 70 20 3d 20 70 43 61  tex(pGroup = pCa
5e80: 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 0a 20  che->pGroup);.. 
5e90: 20 2f 2a 20 53 74 65 70 20 31 3a 20 53 65 61 72   /* Step 1: Sear
5ea0: 63 68 20 74 68 65 20 68 61 73 68 20 74 61 62 6c  ch the hash tabl
5eb0: 65 20 66 6f 72 20 61 6e 20 65 78 69 73 74 69 6e  e for an existin
5ec0: 67 20 65 6e 74 72 79 2e 20 2a 2f 0a 20 20 69 66  g entry. */.  if
5ed0: 28 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3e  ( pCache->nHash>
5ee0: 30 20 29 7b 0a 20 20 20 20 75 6e 73 69 67 6e 65  0 ){.    unsigne
5ef0: 64 20 69 6e 74 20 68 20 3d 20 69 4b 65 79 20 25  d int h = iKey %
5f00: 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3b 0a   pCache->nHash;.
5f10: 20 20 20 20 66 6f 72 28 70 50 61 67 65 3d 70 43      for(pPage=pC
5f20: 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b  ache->apHash[h];
5f30: 20 70 50 61 67 65 26 26 70 50 61 67 65 2d 3e 69   pPage&&pPage->i
5f40: 4b 65 79 21 3d 69 4b 65 79 3b 20 70 50 61 67 65  Key!=iKey; pPage
5f50: 3d 70 50 61 67 65 2d 3e 70 4e 65 78 74 29 3b 0a  =pPage->pNext);.
5f60: 20 20 7d 0a 0a 20 20 2f 2a 20 53 74 65 70 20 32    }..  /* Step 2
5f70: 3a 20 41 62 6f 72 74 20 69 66 20 6e 6f 20 65 78  : Abort if no ex
5f80: 69 73 74 69 6e 67 20 70 61 67 65 20 69 73 20 66  isting page is f
5f90: 6f 75 6e 64 20 61 6e 64 20 63 72 65 61 74 65 46  ound and createF
5fa0: 6c 61 67 20 69 73 20 30 20 2a 2f 0a 20 20 69 66  lag is 0 */.  if
5fb0: 28 20 70 50 61 67 65 20 7c 7c 20 63 72 65 61 74  ( pPage || creat
5fc0: 65 46 6c 61 67 3d 3d 30 20 29 7b 0a 20 20 20 20  eFlag==0 ){.    
5fd0: 70 63 61 63 68 65 31 50 69 6e 50 61 67 65 28 70  pcache1PinPage(p
5fe0: 50 61 67 65 29 3b 0a 20 20 20 20 67 6f 74 6f 20  Page);.    goto 
5ff0: 66 65 74 63 68 5f 6f 75 74 3b 0a 20 20 7d 0a 0a  fetch_out;.  }..
6000: 20 20 2f 2a 20 54 68 65 20 70 47 72 6f 75 70 20    /* The pGroup 
6010: 6c 6f 63 61 6c 20 76 61 72 69 61 62 6c 65 20 77  local variable w
6020: 69 6c 6c 20 6e 6f 72 6d 61 6c 6c 79 20 62 65 20  ill normally be 
6030: 69 6e 69 74 69 61 6c 69 7a 65 64 20 62 79 20 74  initialized by t
6040: 68 65 0a 20 20 2a 2a 20 70 63 61 63 68 65 31 45  he.  ** pcache1E
6050: 6e 74 65 72 4d 75 74 65 78 28 29 20 6d 61 63 72  nterMutex() macr
6060: 6f 20 61 62 6f 76 65 2e 20 20 42 75 74 20 69 66  o above.  But if
6070: 20 53 51 4c 49 54 45 5f 4d 55 54 45 58 5f 4f 4d   SQLITE_MUTEX_OM
6080: 49 54 20 69 73 20 64 65 66 69 6e 65 64 2c 0a 20  IT is defined,. 
6090: 20 2a 2a 20 74 68 65 6e 20 70 63 61 63 68 65 31   ** then pcache1
60a0: 45 6e 74 65 72 4d 75 74 65 78 28 29 20 69 73 20  EnterMutex() is 
60b0: 61 20 6e 6f 2d 6f 70 2c 20 73 6f 20 77 65 20 68  a no-op, so we h
60c0: 61 76 65 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a  ave to initializ
60d0: 65 20 74 68 65 0a 20 20 2a 2a 20 6c 6f 63 61 6c  e the.  ** local
60e0: 20 76 61 72 69 61 62 6c 65 20 68 65 72 65 2e 20   variable here. 
60f0: 20 44 65 6c 61 79 69 6e 67 20 74 68 65 20 69 6e   Delaying the in
6100: 69 74 69 61 6c 69 7a 61 74 69 6f 6e 20 6f 66 20  itialization of 
6110: 70 47 72 6f 75 70 20 69 73 20 61 6e 0a 20 20 2a  pGroup is an.  *
6120: 2a 20 6f 70 74 69 6d 69 7a 61 74 69 6f 6e 3a 20  * optimization: 
6130: 20 54 68 65 20 63 6f 6d 6d 6f 6e 20 63 61 73 65   The common case
6140: 20 69 73 20 74 6f 20 65 78 69 74 20 74 68 65 20   is to exit the 
6150: 6d 6f 64 75 6c 65 20 62 65 66 6f 72 65 20 72 65  module before re
6160: 61 63 68 69 6e 67 0a 20 20 2a 2a 20 74 68 69 73  aching.  ** this
6170: 20 70 6f 69 6e 74 2e 0a 20 20 2a 2f 0a 23 69 66   point..  */.#if
6180: 64 65 66 20 53 51 4c 49 54 45 5f 4d 55 54 45 58  def SQLITE_MUTEX
6190: 5f 4f 4d 49 54 0a 20 20 70 47 72 6f 75 70 20 3d  _OMIT.  pGroup =
61a0: 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b   pCache->pGroup;
61b0: 0a 23 65 6e 64 69 66 0a 0a 20 20 2f 2a 20 53 74  .#endif..  /* St
61c0: 65 70 20 33 3a 20 41 62 6f 72 74 20 69 66 20 63  ep 3: Abort if c
61d0: 72 65 61 74 65 46 6c 61 67 20 69 73 20 31 20 62  reateFlag is 1 b
61e0: 75 74 20 74 68 65 20 63 61 63 68 65 20 69 73 20  ut the cache is 
61f0: 6e 65 61 72 6c 79 20 66 75 6c 6c 20 2a 2f 0a 20  nearly full */. 
6200: 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65 2d   assert( pCache-
6210: 3e 6e 50 61 67 65 20 3e 3d 20 70 43 61 63 68 65  >nPage >= pCache
6220: 2d 3e 6e 52 65 63 79 63 6c 61 62 6c 65 20 29 3b  ->nRecyclable );
6230: 0a 20 20 6e 50 69 6e 6e 65 64 20 3d 20 70 43 61  .  nPinned = pCa
6240: 63 68 65 2d 3e 6e 50 61 67 65 20 2d 20 70 43 61  che->nPage - pCa
6250: 63 68 65 2d 3e 6e 52 65 63 79 63 6c 61 62 6c 65  che->nRecyclable
6260: 3b 0a 20 20 61 73 73 65 72 74 28 20 70 47 72 6f  ;.  assert( pGro
6270: 75 70 2d 3e 6d 78 50 69 6e 6e 65 64 20 3d 3d 20  up->mxPinned == 
6280: 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65  pGroup->nMaxPage
6290: 20 2b 20 31 30 20 2d 20 70 47 72 6f 75 70 2d 3e   + 10 - pGroup->
62a0: 6e 4d 69 6e 50 61 67 65 20 29 3b 0a 20 20 61 73  nMinPage );.  as
62b0: 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e 6e 39  sert( pCache->n9
62c0: 30 70 63 74 20 3d 3d 20 70 43 61 63 68 65 2d 3e  0pct == pCache->
62d0: 6e 4d 61 78 2a 39 2f 31 30 20 29 3b 0a 20 20 69  nMax*9/10 );.  i
62e0: 66 28 20 63 72 65 61 74 65 46 6c 61 67 3d 3d 31  f( createFlag==1
62f0: 20 26 26 20 28 0a 20 20 20 20 20 20 20 20 6e 50   && (.        nP
6300: 69 6e 6e 65 64 3e 3d 70 47 72 6f 75 70 2d 3e 6d  inned>=pGroup->m
6310: 78 50 69 6e 6e 65 64 0a 20 20 20 20 20 7c 7c 20  xPinned.     || 
6320: 6e 50 69 6e 6e 65 64 3e 3d 70 43 61 63 68 65 2d  nPinned>=pCache-
6330: 3e 6e 39 30 70 63 74 0a 20 20 20 20 20 7c 7c 20  >n90pct.     || 
6340: 70 63 61 63 68 65 31 55 6e 64 65 72 4d 65 6d 6f  pcache1UnderMemo
6350: 72 79 50 72 65 73 73 75 72 65 28 70 43 61 63 68  ryPressure(pCach
6360: 65 29 0a 20 20 29 29 7b 0a 20 20 20 20 67 6f 74  e).  )){.    got
6370: 6f 20 66 65 74 63 68 5f 6f 75 74 3b 0a 20 20 7d  o fetch_out;.  }
6380: 0a 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e  ..  if( pCache->
6390: 6e 50 61 67 65 3e 3d 70 43 61 63 68 65 2d 3e 6e  nPage>=pCache->n
63a0: 48 61 73 68 20 26 26 20 70 63 61 63 68 65 31 52  Hash && pcache1R
63b0: 65 73 69 7a 65 48 61 73 68 28 70 43 61 63 68 65  esizeHash(pCache
63c0: 29 20 29 7b 0a 20 20 20 20 67 6f 74 6f 20 66 65  ) ){.    goto fe
63d0: 74 63 68 5f 6f 75 74 3b 0a 20 20 7d 0a 0a 20 20  tch_out;.  }..  
63e0: 2f 2a 20 53 74 65 70 20 34 2e 20 54 72 79 20 74  /* Step 4. Try t
63f0: 6f 20 72 65 63 79 63 6c 65 20 61 20 70 61 67 65  o recycle a page
6400: 2e 20 2a 2f 0a 20 20 69 66 28 20 70 43 61 63 68  . */.  if( pCach
6410: 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 26 26  e->bPurgeable &&
6420: 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 54 61 69   pGroup->pLruTai
6430: 6c 20 26 26 20 28 0a 20 20 20 20 20 20 20 20 20  l && (.         
6440: 28 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 2b 31  (pCache->nPage+1
6450: 3e 3d 70 43 61 63 68 65 2d 3e 6e 4d 61 78 29 0a  >=pCache->nMax).
6460: 20 20 20 20 20 20 7c 7c 20 70 47 72 6f 75 70 2d        || pGroup-
6470: 3e 6e 43 75 72 72 65 6e 74 50 61 67 65 3e 3d 70  >nCurrentPage>=p
6480: 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65 0a  Group->nMaxPage.
6490: 20 20 20 20 20 20 7c 7c 20 70 63 61 63 68 65 31        || pcache1
64a0: 55 6e 64 65 72 4d 65 6d 6f 72 79 50 72 65 73 73  UnderMemoryPress
64b0: 75 72 65 28 70 43 61 63 68 65 29 0a 20 20 29 29  ure(pCache).  ))
64c0: 7b 0a 20 20 20 20 50 43 61 63 68 65 31 20 2a 70  {.    PCache1 *p
64d0: 4f 74 68 65 72 3b 0a 20 20 20 20 70 50 61 67 65  Other;.    pPage
64e0: 20 3d 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 54   = pGroup->pLruT
64f0: 61 69 6c 3b 0a 20 20 20 20 70 63 61 63 68 65 31  ail;.    pcache1
6500: 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73 68 28 70  RemoveFromHash(p
6510: 50 61 67 65 29 3b 0a 20 20 20 20 70 63 61 63 68  Page);.    pcach
6520: 65 31 50 69 6e 50 61 67 65 28 70 50 61 67 65 29  e1PinPage(pPage)
6530: 3b 0a 20 20 20 20 70 4f 74 68 65 72 20 3d 20 70  ;.    pOther = p
6540: 50 61 67 65 2d 3e 70 43 61 63 68 65 3b 0a 0a 20  Page->pCache;.. 
6550: 20 20 20 2f 2a 20 57 65 20 77 61 6e 74 20 74 6f     /* We want to
6560: 20 76 65 72 69 66 79 20 74 68 61 74 20 73 7a 50   verify that szP
6570: 61 67 65 20 61 6e 64 20 73 7a 45 78 74 72 61 20  age and szExtra 
6580: 61 72 65 20 74 68 65 20 73 61 6d 65 20 66 6f 72  are the same for
6590: 20 70 4f 74 68 65 72 0a 20 20 20 20 2a 2a 20 61   pOther.    ** a
65a0: 6e 64 20 70 43 61 63 68 65 2e 20 20 41 73 73 65  nd pCache.  Asse
65b0: 72 74 20 74 68 61 74 20 77 65 20 63 61 6e 20 76  rt that we can v
65c0: 65 72 69 66 79 20 74 68 69 73 20 62 79 20 63 6f  erify this by co
65d0: 6d 70 61 72 69 6e 67 20 73 75 6d 73 2e 20 2a 2f  mparing sums. */
65e0: 0a 20 20 20 20 61 73 73 65 72 74 28 20 28 70 43  .    assert( (pC
65f0: 61 63 68 65 2d 3e 73 7a 50 61 67 65 20 26 20 28  ache->szPage & (
6600: 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 2d 31  pCache->szPage-1
6610: 29 29 3d 3d 30 20 26 26 20 70 43 61 63 68 65 2d  ))==0 && pCache-
6620: 3e 73 7a 50 61 67 65 3e 3d 35 31 32 20 29 3b 0a  >szPage>=512 );.
6630: 20 20 20 20 61 73 73 65 72 74 28 20 70 43 61 63      assert( pCac
6640: 68 65 2d 3e 73 7a 45 78 74 72 61 3c 35 31 32 20  he->szExtra<512 
6650: 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 28  );.    assert( (
6660: 70 4f 74 68 65 72 2d 3e 73 7a 50 61 67 65 20 26  pOther->szPage &
6670: 20 28 70 4f 74 68 65 72 2d 3e 73 7a 50 61 67 65   (pOther->szPage
6680: 2d 31 29 29 3d 3d 30 20 26 26 20 70 4f 74 68 65  -1))==0 && pOthe
6690: 72 2d 3e 73 7a 50 61 67 65 3e 3d 35 31 32 20 29  r->szPage>=512 )
66a0: 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 4f  ;.    assert( pO
66b0: 74 68 65 72 2d 3e 73 7a 45 78 74 72 61 3c 35 31  ther->szExtra<51
66c0: 32 20 29 3b 0a 0a 20 20 20 20 69 66 28 20 70 4f  2 );..    if( pO
66d0: 74 68 65 72 2d 3e 73 7a 50 61 67 65 2b 70 4f 74  ther->szPage+pOt
66e0: 68 65 72 2d 3e 73 7a 45 78 74 72 61 20 21 3d 20  her->szExtra != 
66f0: 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 2b 70  pCache->szPage+p
6700: 43 61 63 68 65 2d 3e 73 7a 45 78 74 72 61 20 29  Cache->szExtra )
6710: 7b 0a 20 20 20 20 20 20 70 63 61 63 68 65 31 46  {.      pcache1F
6720: 72 65 65 50 61 67 65 28 70 50 61 67 65 29 3b 0a  reePage(pPage);.
6730: 20 20 20 20 20 20 70 50 61 67 65 20 3d 20 30 3b        pPage = 0;
6740: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
6750: 20 20 70 47 72 6f 75 70 2d 3e 6e 43 75 72 72 65    pGroup->nCurre
6760: 6e 74 50 61 67 65 20 2d 3d 20 28 70 4f 74 68 65  ntPage -= (pOthe
6770: 72 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 2d 20  r->bPurgeable - 
6780: 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62  pCache->bPurgeab
6790: 6c 65 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  le);.    }.  }..
67a0: 20 20 2f 2a 20 53 74 65 70 20 35 2e 20 49 66 20    /* Step 5. If 
67b0: 61 20 75 73 61 62 6c 65 20 70 61 67 65 20 62 75  a usable page bu
67c0: 66 66 65 72 20 68 61 73 20 73 74 69 6c 6c 20 6e  ffer has still n
67d0: 6f 74 20 62 65 65 6e 20 66 6f 75 6e 64 2c 20 0a  ot been found, .
67e0: 20 20 2a 2a 20 61 74 74 65 6d 70 74 20 74 6f 20    ** attempt to 
67f0: 61 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 6f  allocate a new o
6800: 6e 65 2e 20 0a 20 20 2a 2f 0a 20 20 69 66 28 20  ne. .  */.  if( 
6810: 21 70 50 61 67 65 20 29 7b 0a 20 20 20 20 69 66  !pPage ){.    if
6820: 28 20 63 72 65 61 74 65 46 6c 61 67 3d 3d 31 20  ( createFlag==1 
6830: 29 20 73 71 6c 69 74 65 33 42 65 67 69 6e 42 65  ) sqlite3BeginBe
6840: 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 0a 20 20  nignMalloc();.  
6850: 20 20 70 50 61 67 65 20 3d 20 70 63 61 63 68 65    pPage = pcache
6860: 31 41 6c 6c 6f 63 50 61 67 65 28 70 43 61 63 68  1AllocPage(pCach
6870: 65 29 3b 0a 20 20 20 20 69 66 28 20 63 72 65 61  e);.    if( crea
6880: 74 65 46 6c 61 67 3d 3d 31 20 29 20 73 71 6c 69  teFlag==1 ) sqli
6890: 74 65 33 45 6e 64 42 65 6e 69 67 6e 4d 61 6c 6c  te3EndBenignMall
68a0: 6f 63 28 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28  oc();.  }..  if(
68b0: 20 70 50 61 67 65 20 29 7b 0a 20 20 20 20 75 6e   pPage ){.    un
68c0: 73 69 67 6e 65 64 20 69 6e 74 20 68 20 3d 20 69  signed int h = i
68d0: 4b 65 79 20 25 20 70 43 61 63 68 65 2d 3e 6e 48  Key % pCache->nH
68e0: 61 73 68 3b 0a 20 20 20 20 70 43 61 63 68 65 2d  ash;.    pCache-
68f0: 3e 6e 50 61 67 65 2b 2b 3b 0a 20 20 20 20 70 50  >nPage++;.    pP
6900: 61 67 65 2d 3e 69 4b 65 79 20 3d 20 69 4b 65 79  age->iKey = iKey
6910: 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 4e 65  ;.    pPage->pNe
6920: 78 74 20 3d 20 70 43 61 63 68 65 2d 3e 61 70 48  xt = pCache->apH
6930: 61 73 68 5b 68 5d 3b 0a 20 20 20 20 70 50 61 67  ash[h];.    pPag
6940: 65 2d 3e 70 43 61 63 68 65 20 3d 20 70 43 61 63  e->pCache = pCac
6950: 68 65 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 70  he;.    pPage->p
6960: 4c 72 75 50 72 65 76 20 3d 20 30 3b 0a 20 20 20  LruPrev = 0;.   
6970: 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74   pPage->pLruNext
6980: 20 3d 20 30 3b 0a 20 20 20 20 2a 28 76 6f 69 64   = 0;.    *(void
6990: 20 2a 2a 29 70 50 61 67 65 2d 3e 70 61 67 65 2e   **)pPage->page.
69a0: 70 45 78 74 72 61 20 3d 20 30 3b 0a 20 20 20 20  pExtra = 0;.    
69b0: 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68  pCache->apHash[h
69c0: 5d 20 3d 20 70 50 61 67 65 3b 0a 20 20 7d 0a 0a  ] = pPage;.  }..
69d0: 66 65 74 63 68 5f 6f 75 74 3a 0a 20 20 69 66 28  fetch_out:.  if(
69e0: 20 70 50 61 67 65 20 26 26 20 69 4b 65 79 3e 70   pPage && iKey>p
69f0: 43 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 29  Cache->iMaxKey )
6a00: 7b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 69 4d  {.    pCache->iM
6a10: 61 78 4b 65 79 20 3d 20 69 4b 65 79 3b 0a 20 20  axKey = iKey;.  
6a20: 7d 0a 20 20 70 63 61 63 68 65 31 4c 65 61 76 65  }.  pcache1Leave
6a30: 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b 0a 20  Mutex(pGroup);. 
6a40: 20 72 65 74 75 72 6e 20 26 70 50 61 67 65 2d 3e   return &pPage->
6a50: 70 61 67 65 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20  page;.}.../*.** 
6a60: 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  Implementation o
6a70: 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63  f the sqlite3_pc
6a80: 61 63 68 65 2e 78 55 6e 70 69 6e 20 6d 65 74 68  ache.xUnpin meth
6a90: 6f 64 2e 0a 2a 2a 0a 2a 2a 20 4d 61 72 6b 20 61  od..**.** Mark a
6aa0: 20 70 61 67 65 20 61 73 20 75 6e 70 69 6e 6e 65   page as unpinne
6ab0: 64 20 28 65 6c 69 67 69 62 6c 65 20 66 6f 72 20  d (eligible for 
6ac0: 61 73 79 6e 63 68 72 6f 6e 6f 75 73 20 72 65 63  asynchronous rec
6ad0: 79 63 6c 69 6e 67 29 2e 0a 2a 2f 0a 73 74 61 74  ycling)..*/.stat
6ae0: 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 31 55  ic void pcache1U
6af0: 6e 70 69 6e 28 0a 20 20 73 71 6c 69 74 65 33 5f  npin(.  sqlite3_
6b00: 70 63 61 63 68 65 20 2a 70 2c 20 0a 20 20 73 71  pcache *p, .  sq
6b10: 6c 69 74 65 33 5f 70 63 61 63 68 65 5f 70 61 67  lite3_pcache_pag
6b20: 65 20 2a 70 50 67 2c 20 0a 20 20 69 6e 74 20 72  e *pPg, .  int r
6b30: 65 75 73 65 55 6e 6c 69 6b 65 6c 79 0a 29 7b 0a  euseUnlikely.){.
6b40: 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68    PCache1 *pCach
6b50: 65 20 3d 20 28 50 43 61 63 68 65 31 20 2a 29 70  e = (PCache1 *)p
6b60: 3b 0a 20 20 50 67 48 64 72 31 20 2a 70 50 61 67  ;.  PgHdr1 *pPag
6b70: 65 20 3d 20 28 50 67 48 64 72 31 20 2a 29 70 50  e = (PgHdr1 *)pP
6b80: 67 3b 0a 20 20 50 47 72 6f 75 70 20 2a 70 47 72  g;.  PGroup *pGr
6b90: 6f 75 70 20 3d 20 70 43 61 63 68 65 2d 3e 70 47  oup = pCache->pG
6ba0: 72 6f 75 70 3b 0a 20 0a 20 20 61 73 73 65 72 74  roup;. .  assert
6bb0: 28 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65 3d  ( pPage->pCache=
6bc0: 3d 70 43 61 63 68 65 20 29 3b 0a 20 20 70 63 61  =pCache );.  pca
6bd0: 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70  che1EnterMutex(p
6be0: 47 72 6f 75 70 29 3b 0a 0a 20 20 2f 2a 20 49 74  Group);..  /* It
6bf0: 20 69 73 20 61 6e 20 65 72 72 6f 72 20 74 6f 20   is an error to 
6c00: 63 61 6c 6c 20 74 68 69 73 20 66 75 6e 63 74 69  call this functi
6c10: 6f 6e 20 69 66 20 74 68 65 20 70 61 67 65 20 69  on if the page i
6c20: 73 20 61 6c 72 65 61 64 79 20 0a 20 20 2a 2a 20  s already .  ** 
6c30: 70 61 72 74 20 6f 66 20 74 68 65 20 50 47 72 6f  part of the PGro
6c40: 75 70 20 4c 52 55 20 6c 69 73 74 2e 0a 20 20 2a  up LRU list..  *
6c50: 2f 0a 20 20 61 73 73 65 72 74 28 20 70 50 61 67  /.  assert( pPag
6c60: 65 2d 3e 70 4c 72 75 50 72 65 76 3d 3d 30 20 26  e->pLruPrev==0 &
6c70: 26 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78  & pPage->pLruNex
6c80: 74 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74  t==0 );.  assert
6c90: 28 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 48 65  ( pGroup->pLruHe
6ca0: 61 64 21 3d 70 50 61 67 65 20 26 26 20 70 47 72  ad!=pPage && pGr
6cb0: 6f 75 70 2d 3e 70 4c 72 75 54 61 69 6c 21 3d 70  oup->pLruTail!=p
6cc0: 50 61 67 65 20 29 3b 0a 0a 20 20 69 66 28 20 72  Page );..  if( r
6cd0: 65 75 73 65 55 6e 6c 69 6b 65 6c 79 20 7c 7c 20  euseUnlikely || 
6ce0: 70 47 72 6f 75 70 2d 3e 6e 43 75 72 72 65 6e 74  pGroup->nCurrent
6cf0: 50 61 67 65 3e 70 47 72 6f 75 70 2d 3e 6e 4d 61  Page>pGroup->nMa
6d00: 78 50 61 67 65 20 29 7b 0a 20 20 20 20 70 63 61  xPage ){.    pca
6d10: 63 68 65 31 52 65 6d 6f 76 65 46 72 6f 6d 48 61  che1RemoveFromHa
6d20: 73 68 28 70 50 61 67 65 29 3b 0a 20 20 20 20 70  sh(pPage);.    p
6d30: 63 61 63 68 65 31 46 72 65 65 50 61 67 65 28 70  cache1FreePage(p
6d40: 50 61 67 65 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a  Page);.  }else{.
6d50: 20 20 20 20 2f 2a 20 41 64 64 20 74 68 65 20 70      /* Add the p
6d60: 61 67 65 20 74 6f 20 74 68 65 20 50 47 72 6f 75  age to the PGrou
6d70: 70 20 4c 52 55 20 6c 69 73 74 2e 20 2a 2f 0a 20  p LRU list. */. 
6d80: 20 20 20 69 66 28 20 70 47 72 6f 75 70 2d 3e 70     if( pGroup->p
6d90: 4c 72 75 48 65 61 64 20 29 7b 0a 20 20 20 20 20  LruHead ){.     
6da0: 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 48 65 61   pGroup->pLruHea
6db0: 64 2d 3e 70 4c 72 75 50 72 65 76 20 3d 20 70 50  d->pLruPrev = pP
6dc0: 61 67 65 3b 0a 20 20 20 20 20 20 70 50 61 67 65  age;.      pPage
6dd0: 2d 3e 70 4c 72 75 4e 65 78 74 20 3d 20 70 47 72  ->pLruNext = pGr
6de0: 6f 75 70 2d 3e 70 4c 72 75 48 65 61 64 3b 0a 20  oup->pLruHead;. 
6df0: 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 70 4c 72       pGroup->pLr
6e00: 75 48 65 61 64 20 3d 20 70 50 61 67 65 3b 0a 20  uHead = pPage;. 
6e10: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
6e20: 70 47 72 6f 75 70 2d 3e 70 4c 72 75 54 61 69 6c  pGroup->pLruTail
6e30: 20 3d 20 70 50 61 67 65 3b 0a 20 20 20 20 20 20   = pPage;.      
6e40: 70 47 72 6f 75 70 2d 3e 70 4c 72 75 48 65 61 64  pGroup->pLruHead
6e50: 20 3d 20 70 50 61 67 65 3b 0a 20 20 20 20 7d 0a   = pPage;.    }.
6e60: 20 20 20 20 70 43 61 63 68 65 2d 3e 6e 52 65 63      pCache->nRec
6e70: 79 63 6c 61 62 6c 65 2b 2b 3b 0a 20 20 7d 0a 0a  yclable++;.  }..
6e80: 20 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75    pcache1LeaveMu
6e90: 74 65 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f  tex(pCache->pGro
6ea0: 75 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d  up);.}../*.** Im
6eb0: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20  plementation of 
6ec0: 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63  the sqlite3_pcac
6ed0: 68 65 2e 78 52 65 6b 65 79 20 6d 65 74 68 6f 64  he.xRekey method
6ee0: 2e 20 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  . .*/.static voi
6ef0: 64 20 70 63 61 63 68 65 31 52 65 6b 65 79 28 0a  d pcache1Rekey(.
6f00: 20 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65    sqlite3_pcache
6f10: 20 2a 70 2c 0a 20 20 73 71 6c 69 74 65 33 5f 70   *p,.  sqlite3_p
6f20: 63 61 63 68 65 5f 70 61 67 65 20 2a 70 50 67 2c  cache_page *pPg,
6f30: 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  .  unsigned int 
6f40: 69 4f 6c 64 2c 0a 20 20 75 6e 73 69 67 6e 65 64  iOld,.  unsigned
6f50: 20 69 6e 74 20 69 4e 65 77 0a 29 7b 0a 20 20 50   int iNew.){.  P
6f60: 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d  Cache1 *pCache =
6f70: 20 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20   (PCache1 *)p;. 
6f80: 20 50 67 48 64 72 31 20 2a 70 50 61 67 65 20 3d   PgHdr1 *pPage =
6f90: 20 28 50 67 48 64 72 31 20 2a 29 70 50 67 3b 0a   (PgHdr1 *)pPg;.
6fa0: 20 20 50 67 48 64 72 31 20 2a 2a 70 70 3b 0a 20    PgHdr1 **pp;. 
6fb0: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 3b   unsigned int h;
6fc0: 20 0a 20 20 61 73 73 65 72 74 28 20 70 50 61 67   .  assert( pPag
6fd0: 65 2d 3e 69 4b 65 79 3d 3d 69 4f 6c 64 20 29 3b  e->iKey==iOld );
6fe0: 0a 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65  .  assert( pPage
6ff0: 2d 3e 70 43 61 63 68 65 3d 3d 70 43 61 63 68 65  ->pCache==pCache
7000: 20 29 3b 0a 0a 20 20 70 63 61 63 68 65 31 45 6e   );..  pcache1En
7010: 74 65 72 4d 75 74 65 78 28 70 43 61 63 68 65 2d  terMutex(pCache-
7020: 3e 70 47 72 6f 75 70 29 3b 0a 0a 20 20 68 20 3d  >pGroup);..  h =
7030: 20 69 4f 6c 64 25 70 43 61 63 68 65 2d 3e 6e 48   iOld%pCache->nH
7040: 61 73 68 3b 0a 20 20 70 70 20 3d 20 26 70 43 61  ash;.  pp = &pCa
7050: 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 0a  che->apHash[h];.
7060: 20 20 77 68 69 6c 65 28 20 28 2a 70 70 29 21 3d    while( (*pp)!=
7070: 70 50 61 67 65 20 29 7b 0a 20 20 20 20 70 70 20  pPage ){.    pp 
7080: 3d 20 26 28 2a 70 70 29 2d 3e 70 4e 65 78 74 3b  = &(*pp)->pNext;
7090: 0a 20 20 7d 0a 20 20 2a 70 70 20 3d 20 70 50 61  .  }.  *pp = pPa
70a0: 67 65 2d 3e 70 4e 65 78 74 3b 0a 0a 20 20 68 20  ge->pNext;..  h 
70b0: 3d 20 69 4e 65 77 25 70 43 61 63 68 65 2d 3e 6e  = iNew%pCache->n
70c0: 48 61 73 68 3b 0a 20 20 70 50 61 67 65 2d 3e 69  Hash;.  pPage->i
70d0: 4b 65 79 20 3d 20 69 4e 65 77 3b 0a 20 20 70 50  Key = iNew;.  pP
70e0: 61 67 65 2d 3e 70 4e 65 78 74 20 3d 20 70 43 61  age->pNext = pCa
70f0: 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 0a  che->apHash[h];.
7100: 20 20 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68    pCache->apHash
7110: 5b 68 5d 20 3d 20 70 50 61 67 65 3b 0a 20 20 69  [h] = pPage;.  i
7120: 66 28 20 69 4e 65 77 3e 70 43 61 63 68 65 2d 3e  f( iNew>pCache->
7130: 69 4d 61 78 4b 65 79 20 29 7b 0a 20 20 20 20 70  iMaxKey ){.    p
7140: 43 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 3d  Cache->iMaxKey =
7150: 20 69 4e 65 77 3b 0a 20 20 7d 0a 0a 20 20 70 63   iNew;.  }..  pc
7160: 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28  ache1LeaveMutex(
7170: 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b  pCache->pGroup);
7180: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d  .}../*.** Implem
7190: 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20  entation of the 
71a0: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78  sqlite3_pcache.x
71b0: 54 72 75 6e 63 61 74 65 20 6d 65 74 68 6f 64 2e  Truncate method.
71c0: 20 0a 2a 2a 0a 2a 2a 20 44 69 73 63 61 72 64 20   .**.** Discard 
71d0: 61 6c 6c 20 75 6e 70 69 6e 6e 65 64 20 70 61 67  all unpinned pag
71e0: 65 73 20 69 6e 20 74 68 65 20 63 61 63 68 65 20  es in the cache 
71f0: 77 69 74 68 20 61 20 70 61 67 65 20 6e 75 6d 62  with a page numb
7200: 65 72 20 65 71 75 61 6c 20 74 6f 0a 2a 2a 20 6f  er equal to.** o
7210: 72 20 67 72 65 61 74 65 72 20 74 68 61 6e 20 70  r greater than p
7220: 61 72 61 6d 65 74 65 72 20 69 4c 69 6d 69 74 2e  arameter iLimit.
7230: 20 41 6e 79 20 70 69 6e 6e 65 64 20 70 61 67 65   Any pinned page
7240: 73 20 77 69 74 68 20 61 20 70 61 67 65 20 6e 75  s with a page nu
7250: 6d 62 65 72 0a 2a 2a 20 65 71 75 61 6c 20 74 6f  mber.** equal to
7260: 20 6f 72 20 67 72 65 61 74 65 72 20 74 68 61 6e   or greater than
7270: 20 69 4c 69 6d 69 74 20 61 72 65 20 69 6d 70 6c   iLimit are impl
7280: 69 63 69 74 6c 79 20 75 6e 70 69 6e 6e 65 64 2e  icitly unpinned.
7290: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
72a0: 70 63 61 63 68 65 31 54 72 75 6e 63 61 74 65 28  pcache1Truncate(
72b0: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a  sqlite3_pcache *
72c0: 70 2c 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  p, unsigned int 
72d0: 69 4c 69 6d 69 74 29 7b 0a 20 20 50 43 61 63 68  iLimit){.  PCach
72e0: 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43  e1 *pCache = (PC
72f0: 61 63 68 65 31 20 2a 29 70 3b 0a 20 20 70 63 61  ache1 *)p;.  pca
7300: 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70  che1EnterMutex(p
7310: 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a  Cache->pGroup);.
7320: 20 20 69 66 28 20 69 4c 69 6d 69 74 3c 3d 70 43    if( iLimit<=pC
7330: 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 29 7b  ache->iMaxKey ){
7340: 0a 20 20 20 20 70 63 61 63 68 65 31 54 72 75 6e  .    pcache1Trun
7350: 63 61 74 65 55 6e 73 61 66 65 28 70 43 61 63 68  cateUnsafe(pCach
7360: 65 2c 20 69 4c 69 6d 69 74 29 3b 0a 20 20 20 20  e, iLimit);.    
7370: 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20  pCache->iMaxKey 
7380: 3d 20 69 4c 69 6d 69 74 2d 31 3b 0a 20 20 7d 0a  = iLimit-1;.  }.
7390: 20 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75    pcache1LeaveMu
73a0: 74 65 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f  tex(pCache->pGro
73b0: 75 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d  up);.}../*.** Im
73c0: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20  plementation of 
73d0: 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63  the sqlite3_pcac
73e0: 68 65 2e 78 44 65 73 74 72 6f 79 20 6d 65 74 68  he.xDestroy meth
73f0: 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20 44 65 73 74 72  od. .**.** Destr
7400: 6f 79 20 61 20 63 61 63 68 65 20 61 6c 6c 6f 63  oy a cache alloc
7410: 61 74 65 64 20 75 73 69 6e 67 20 70 63 61 63 68  ated using pcach
7420: 65 31 43 72 65 61 74 65 28 29 2e 0a 2a 2f 0a 73  e1Create()..*/.s
7430: 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68  tatic void pcach
7440: 65 31 44 65 73 74 72 6f 79 28 73 71 6c 69 74 65  e1Destroy(sqlite
7450: 33 5f 70 63 61 63 68 65 20 2a 70 29 7b 0a 20 20  3_pcache *p){.  
7460: 50 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 20  PCache1 *pCache 
7470: 3d 20 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a  = (PCache1 *)p;.
7480: 20 20 50 47 72 6f 75 70 20 2a 70 47 72 6f 75 70    PGroup *pGroup
7490: 20 3d 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75   = pCache->pGrou
74a0: 70 3b 0a 20 20 61 73 73 65 72 74 28 20 70 43 61  p;.  assert( pCa
74b0: 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20  che->bPurgeable 
74c0: 7c 7c 20 28 70 43 61 63 68 65 2d 3e 6e 4d 61 78  || (pCache->nMax
74d0: 3d 3d 30 20 26 26 20 70 43 61 63 68 65 2d 3e 6e  ==0 && pCache->n
74e0: 4d 69 6e 3d 3d 30 29 20 29 3b 0a 20 20 70 63 61  Min==0) );.  pca
74f0: 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70  che1EnterMutex(p
7500: 47 72 6f 75 70 29 3b 0a 20 20 70 63 61 63 68 65  Group);.  pcache
7510: 31 54 72 75 6e 63 61 74 65 55 6e 73 61 66 65 28  1TruncateUnsafe(
7520: 70 43 61 63 68 65 2c 20 30 29 3b 0a 20 20 61 73  pCache, 0);.  as
7530: 73 65 72 74 28 20 70 47 72 6f 75 70 2d 3e 6e 4d  sert( pGroup->nM
7540: 61 78 50 61 67 65 20 3e 3d 20 70 43 61 63 68 65  axPage >= pCache
7550: 2d 3e 6e 4d 61 78 20 29 3b 0a 20 20 70 47 72 6f  ->nMax );.  pGro
7560: 75 70 2d 3e 6e 4d 61 78 50 61 67 65 20 2d 3d 20  up->nMaxPage -= 
7570: 70 43 61 63 68 65 2d 3e 6e 4d 61 78 3b 0a 20 20  pCache->nMax;.  
7580: 61 73 73 65 72 74 28 20 70 47 72 6f 75 70 2d 3e  assert( pGroup->
7590: 6e 4d 69 6e 50 61 67 65 20 3e 3d 20 70 43 61 63  nMinPage >= pCac
75a0: 68 65 2d 3e 6e 4d 69 6e 20 29 3b 0a 20 20 70 47  he->nMin );.  pG
75b0: 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67 65 20 2d  roup->nMinPage -
75c0: 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 3b 0a  = pCache->nMin;.
75d0: 20 20 70 47 72 6f 75 70 2d 3e 6d 78 50 69 6e 6e    pGroup->mxPinn
75e0: 65 64 20 3d 20 70 47 72 6f 75 70 2d 3e 6e 4d 61  ed = pGroup->nMa
75f0: 78 50 61 67 65 20 2b 20 31 30 20 2d 20 70 47 72  xPage + 10 - pGr
7600: 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67 65 3b 0a 20  oup->nMinPage;. 
7610: 20 70 63 61 63 68 65 31 45 6e 66 6f 72 63 65 4d   pcache1EnforceM
7620: 61 78 50 61 67 65 28 70 47 72 6f 75 70 29 3b 0a  axPage(pGroup);.
7630: 20 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75    pcache1LeaveMu
7640: 74 65 78 28 70 47 72 6f 75 70 29 3b 0a 20 20 73  tex(pGroup);.  s
7650: 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43 61 63  qlite3_free(pCac
7660: 68 65 2d 3e 61 70 48 61 73 68 29 3b 0a 20 20 73  he->apHash);.  s
7670: 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43 61 63  qlite3_free(pCac
7680: 68 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68  he);.}../*.** Th
7690: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63  is function is c
76a0: 61 6c 6c 65 64 20 64 75 72 69 6e 67 20 69 6e 69  alled during ini
76b0: 74 69 61 6c 69 7a 61 74 69 6f 6e 20 28 73 71 6c  tialization (sql
76c0: 69 74 65 33 5f 69 6e 69 74 69 61 6c 69 7a 65 28  ite3_initialize(
76d0: 29 29 20 74 6f 0a 2a 2a 20 69 6e 73 74 61 6c 6c  )) to.** install
76e0: 20 74 68 65 20 64 65 66 61 75 6c 74 20 70 6c 75   the default plu
76f0: 67 67 61 62 6c 65 20 63 61 63 68 65 20 6d 6f 64  ggable cache mod
7700: 75 6c 65 2c 20 61 73 73 75 6d 69 6e 67 20 74 68  ule, assuming th
7710: 65 20 75 73 65 72 20 68 61 73 20 6e 6f 74 0a 2a  e user has not.*
7720: 2a 20 61 6c 72 65 61 64 79 20 70 72 6f 76 69 64  * already provid
7730: 65 64 20 61 6e 20 61 6c 74 65 72 6e 61 74 69 76  ed an alternativ
7740: 65 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74  e..*/.void sqlit
7750: 65 33 50 43 61 63 68 65 53 65 74 44 65 66 61 75  e3PCacheSetDefau
7760: 6c 74 28 76 6f 69 64 29 7b 0a 20 20 73 74 61 74  lt(void){.  stat
7770: 69 63 20 63 6f 6e 73 74 20 73 71 6c 69 74 65 33  ic const sqlite3
7780: 5f 70 63 61 63 68 65 5f 6d 65 74 68 6f 64 73 32  _pcache_methods2
7790: 20 64 65 66 61 75 6c 74 4d 65 74 68 6f 64 73 20   defaultMethods 
77a0: 3d 20 7b 0a 20 20 20 20 31 2c 20 20 20 20 20 20  = {.    1,      
77b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
77c0: 20 2f 2a 20 69 56 65 72 73 69 6f 6e 20 2a 2f 0a   /* iVersion */.
77d0: 20 20 20 20 30 2c 20 20 20 20 20 20 20 20 20 20      0,          
77e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
77f0: 70 41 72 67 20 2a 2f 0a 20 20 20 20 70 63 61 63  pArg */.    pcac
7800: 68 65 31 49 6e 69 74 2c 20 20 20 20 20 20 20 20  he1Init,        
7810: 20 20 20 20 20 2f 2a 20 78 49 6e 69 74 20 2a 2f       /* xInit */
7820: 0a 20 20 20 20 70 63 61 63 68 65 31 53 68 75 74  .    pcache1Shut
7830: 64 6f 77 6e 2c 20 20 20 20 20 20 20 20 20 2f 2a  down,         /*
7840: 20 78 53 68 75 74 64 6f 77 6e 20 2a 2f 0a 20 20   xShutdown */.  
7850: 20 20 70 63 61 63 68 65 31 43 72 65 61 74 65 2c    pcache1Create,
7860: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43             /* xC
7870: 72 65 61 74 65 20 2a 2f 0a 20 20 20 20 70 63 61  reate */.    pca
7880: 63 68 65 31 43 61 63 68 65 73 69 7a 65 2c 20 20  che1Cachesize,  
7890: 20 20 20 20 20 20 2f 2a 20 78 43 61 63 68 65 73        /* xCaches
78a0: 69 7a 65 20 2a 2f 0a 20 20 20 20 70 63 61 63 68  ize */.    pcach
78b0: 65 31 50 61 67 65 63 6f 75 6e 74 2c 20 20 20 20  e1Pagecount,    
78c0: 20 20 20 20 2f 2a 20 78 50 61 67 65 63 6f 75 6e      /* xPagecoun
78d0: 74 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31  t */.    pcache1
78e0: 46 65 74 63 68 2c 20 20 20 20 20 20 20 20 20 20  Fetch,          
78f0: 20 20 2f 2a 20 78 46 65 74 63 68 20 2a 2f 0a 20    /* xFetch */. 
7900: 20 20 20 70 63 61 63 68 65 31 55 6e 70 69 6e 2c     pcache1Unpin,
7910: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
7920: 55 6e 70 69 6e 20 2a 2f 0a 20 20 20 20 70 63 61  Unpin */.    pca
7930: 63 68 65 31 52 65 6b 65 79 2c 20 20 20 20 20 20  che1Rekey,      
7940: 20 20 20 20 20 20 2f 2a 20 78 52 65 6b 65 79 20        /* xRekey 
7950: 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31 54 72  */.    pcache1Tr
7960: 75 6e 63 61 74 65 2c 20 20 20 20 20 20 20 20 20  uncate,         
7970: 2f 2a 20 78 54 72 75 6e 63 61 74 65 20 2a 2f 0a  /* xTruncate */.
7980: 20 20 20 20 70 63 61 63 68 65 31 44 65 73 74 72      pcache1Destr
7990: 6f 79 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20  oy,          /* 
79a0: 78 44 65 73 74 72 6f 79 20 2a 2f 0a 20 20 20 20  xDestroy */.    
79b0: 70 63 61 63 68 65 31 53 68 72 69 6e 6b 20 20 20  pcache1Shrink   
79c0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 53 68 72           /* xShr
79d0: 69 6e 6b 20 2a 2f 0a 20 20 7d 3b 0a 20 20 73 71  ink */.  };.  sq
79e0: 6c 69 74 65 33 5f 63 6f 6e 66 69 67 28 53 51 4c  lite3_config(SQL
79f0: 49 54 45 5f 43 4f 4e 46 49 47 5f 50 43 41 43 48  ITE_CONFIG_PCACH
7a00: 45 32 2c 20 26 64 65 66 61 75 6c 74 4d 65 74 68  E2, &defaultMeth
7a10: 6f 64 73 29 3b 0a 7d 0a 0a 23 69 66 64 65 66 20  ods);.}..#ifdef 
7a20: 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45  SQLITE_ENABLE_ME
7a30: 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 0a  MORY_MANAGEMENT.
7a40: 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  /*.** This funct
7a50: 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 74 6f  ion is called to
7a60: 20 66 72 65 65 20 73 75 70 65 72 66 6c 75 6f 75   free superfluou
7a70: 73 20 64 79 6e 61 6d 69 63 61 6c 6c 79 20 61 6c  s dynamically al
7a80: 6c 6f 63 61 74 65 64 20 6d 65 6d 6f 72 79 0a 2a  located memory.*
7a90: 2a 20 68 65 6c 64 20 62 79 20 74 68 65 20 70 61  * held by the pa
7aa0: 67 65 72 20 73 79 73 74 65 6d 2e 20 4d 65 6d 6f  ger system. Memo
7ab0: 72 79 20 69 6e 20 75 73 65 20 62 79 20 61 6e 79  ry in use by any
7ac0: 20 53 51 4c 69 74 65 20 70 61 67 65 72 20 61 6c   SQLite pager al
7ad0: 6c 6f 63 61 74 65 64 0a 2a 2a 20 62 79 20 74 68  located.** by th
7ae0: 65 20 63 75 72 72 65 6e 74 20 74 68 72 65 61 64  e current thread
7af0: 20 6d 61 79 20 62 65 20 73 71 6c 69 74 65 33 5f   may be sqlite3_
7b00: 66 72 65 65 28 29 65 64 2e 0a 2a 2a 0a 2a 2a 20  free()ed..**.** 
7b10: 6e 52 65 71 20 69 73 20 74 68 65 20 6e 75 6d 62  nReq is the numb
7b20: 65 72 20 6f 66 20 62 79 74 65 73 20 6f 66 20 6d  er of bytes of m
7b30: 65 6d 6f 72 79 20 72 65 71 75 69 72 65 64 2e 20  emory required. 
7b40: 4f 6e 63 65 20 74 68 69 73 20 6d 75 63 68 20 68  Once this much h
7b50: 61 73 0a 2a 2a 20 62 65 65 6e 20 72 65 6c 65 61  as.** been relea
7b60: 73 65 64 2c 20 74 68 65 20 66 75 6e 63 74 69 6f  sed, the functio
7b70: 6e 20 72 65 74 75 72 6e 73 2e 20 54 68 65 20 72  n returns. The r
7b80: 65 74 75 72 6e 20 76 61 6c 75 65 20 69 73 20 74  eturn value is t
7b90: 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20  he total number 
7ba0: 0a 2a 2a 20 6f 66 20 62 79 74 65 73 20 6f 66 20  .** of bytes of 
7bb0: 6d 65 6d 6f 72 79 20 72 65 6c 65 61 73 65 64 2e  memory released.
7bc0: 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 50  .*/.int sqlite3P
7bd0: 63 61 63 68 65 52 65 6c 65 61 73 65 4d 65 6d 6f  cacheReleaseMemo
7be0: 72 79 28 69 6e 74 20 6e 52 65 71 29 7b 0a 20 20  ry(int nReq){.  
7bf0: 69 6e 74 20 6e 46 72 65 65 20 3d 20 30 3b 0a 20  int nFree = 0;. 
7c00: 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33   assert( sqlite3
7c10: 5f 6d 75 74 65 78 5f 6e 6f 74 68 65 6c 64 28 70  _mutex_notheld(p
7c20: 63 61 63 68 65 31 2e 67 72 70 2e 6d 75 74 65 78  cache1.grp.mutex
7c30: 29 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 73  ) );.  assert( s
7c40: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6e 6f 74  qlite3_mutex_not
7c50: 68 65 6c 64 28 70 63 61 63 68 65 31 2e 6d 75 74  held(pcache1.mut
7c60: 65 78 29 20 29 3b 0a 20 20 69 66 28 20 70 63 61  ex) );.  if( pca
7c70: 63 68 65 31 2e 70 53 74 61 72 74 3d 3d 30 20 29  che1.pStart==0 )
7c80: 7b 0a 20 20 20 20 50 67 48 64 72 31 20 2a 70 3b  {.    PgHdr1 *p;
7c90: 0a 20 20 20 20 70 63 61 63 68 65 31 45 6e 74 65  .    pcache1Ente
7ca0: 72 4d 75 74 65 78 28 26 70 63 61 63 68 65 31 2e  rMutex(&pcache1.
7cb0: 67 72 70 29 3b 0a 20 20 20 20 77 68 69 6c 65 28  grp);.    while(
7cc0: 20 28 6e 52 65 71 3c 30 20 7c 7c 20 6e 46 72 65   (nReq<0 || nFre
7cd0: 65 3c 6e 52 65 71 29 20 26 26 20 28 28 70 3d 70  e<nReq) && ((p=p
7ce0: 63 61 63 68 65 31 2e 67 72 70 2e 70 4c 72 75 54  cache1.grp.pLruT
7cf0: 61 69 6c 29 21 3d 30 29 20 29 7b 0a 20 20 20 20  ail)!=0) ){.    
7d00: 20 20 6e 46 72 65 65 20 2b 3d 20 70 63 61 63 68    nFree += pcach
7d10: 65 31 4d 65 6d 53 69 7a 65 28 70 2d 3e 70 61 67  e1MemSize(p->pag
7d20: 65 2e 70 42 75 66 29 3b 0a 23 69 66 64 65 66 20  e.pBuf);.#ifdef 
7d30: 53 51 4c 49 54 45 5f 50 43 41 43 48 45 5f 53 45  SQLITE_PCACHE_SE
7d40: 50 41 52 41 54 45 5f 48 45 41 44 45 52 0a 20 20  PARATE_HEADER.  
7d50: 20 20 20 20 6e 46 72 65 65 20 2b 3d 20 73 71 6c      nFree += sql
7d60: 69 74 65 33 4d 65 6d 53 69 7a 65 28 70 29 3b 0a  ite3MemSize(p);.
7d70: 23 65 6e 64 69 66 0a 20 20 20 20 20 20 70 63 61  #endif.      pca
7d80: 63 68 65 31 50 69 6e 50 61 67 65 28 70 29 3b 0a  che1PinPage(p);.
7d90: 20 20 20 20 20 20 70 63 61 63 68 65 31 52 65 6d        pcache1Rem
7da0: 6f 76 65 46 72 6f 6d 48 61 73 68 28 70 29 3b 0a  oveFromHash(p);.
7db0: 20 20 20 20 20 20 70 63 61 63 68 65 31 46 72 65        pcache1Fre
7dc0: 65 50 61 67 65 28 70 29 3b 0a 20 20 20 20 7d 0a  ePage(p);.    }.
7dd0: 20 20 20 20 70 63 61 63 68 65 31 4c 65 61 76 65      pcache1Leave
7de0: 4d 75 74 65 78 28 26 70 63 61 63 68 65 31 2e 67  Mutex(&pcache1.g
7df0: 72 70 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  rp);.  }.  retur
7e00: 6e 20 6e 46 72 65 65 3b 0a 7d 0a 23 65 6e 64 69  n nFree;.}.#endi
7e10: 66 20 2f 2a 20 53 51 4c 49 54 45 5f 45 4e 41 42  f /* SQLITE_ENAB
7e20: 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47 45  LE_MEMORY_MANAGE
7e30: 4d 45 4e 54 20 2a 2f 0a 0a 23 69 66 64 65 66 20  MENT */..#ifdef 
7e40: 53 51 4c 49 54 45 5f 54 45 53 54 0a 2f 2a 0a 2a  SQLITE_TEST./*.*
7e50: 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  * This function 
7e60: 69 73 20 75 73 65 64 20 62 79 20 74 65 73 74 20  is used by test 
7e70: 70 72 6f 63 65 64 75 72 65 73 20 74 6f 20 69 6e  procedures to in
7e80: 73 70 65 63 74 20 74 68 65 20 69 6e 74 65 72 6e  spect the intern
7e90: 61 6c 20 73 74 61 74 65 0a 2a 2a 20 6f 66 20 74  al state.** of t
7ea0: 68 65 20 67 6c 6f 62 61 6c 20 63 61 63 68 65 2e  he global cache.
7eb0: 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33  .*/.void sqlite3
7ec0: 50 63 61 63 68 65 53 74 61 74 73 28 0a 20 20 69  PcacheStats(.  i
7ed0: 6e 74 20 2a 70 6e 43 75 72 72 65 6e 74 2c 20 20  nt *pnCurrent,  
7ee0: 20 20 20 20 2f 2a 20 4f 55 54 3a 20 54 6f 74 61      /* OUT: Tota
7ef0: 6c 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65  l number of page
7f00: 73 20 63 61 63 68 65 64 20 2a 2f 0a 20 20 69 6e  s cached */.  in
7f10: 74 20 2a 70 6e 4d 61 78 2c 20 20 20 20 20 20 20  t *pnMax,       
7f20: 20 20 20 2f 2a 20 4f 55 54 3a 20 47 6c 6f 62 61     /* OUT: Globa
7f30: 6c 20 6d 61 78 69 6d 75 6d 20 63 61 63 68 65 20  l maximum cache 
7f40: 73 69 7a 65 20 2a 2f 0a 20 20 69 6e 74 20 2a 70  size */.  int *p
7f50: 6e 4d 69 6e 2c 20 20 20 20 20 20 20 20 20 20 2f  nMin,          /
7f60: 2a 20 4f 55 54 3a 20 53 75 6d 20 6f 66 20 50 43  * OUT: Sum of PC
7f70: 61 63 68 65 31 2e 6e 4d 69 6e 20 66 6f 72 20 70  ache1.nMin for p
7f80: 75 72 67 65 61 62 6c 65 20 63 61 63 68 65 73 20  urgeable caches 
7f90: 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 52 65 63 79  */.  int *pnRecy
7fa0: 63 6c 61 62 6c 65 20 20 20 20 2f 2a 20 4f 55 54  clable    /* OUT
7fb0: 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f  : Total number o
7fc0: 66 20 70 61 67 65 73 20 61 76 61 69 6c 61 62 6c  f pages availabl
7fd0: 65 20 66 6f 72 20 72 65 63 79 63 6c 69 6e 67 20  e for recycling 
7fe0: 2a 2f 0a 29 7b 0a 20 20 50 67 48 64 72 31 20 2a  */.){.  PgHdr1 *
7ff0: 70 3b 0a 20 20 69 6e 74 20 6e 52 65 63 79 63 6c  p;.  int nRecycl
8000: 61 62 6c 65 20 3d 20 30 3b 0a 20 20 66 6f 72 28  able = 0;.  for(
8010: 70 3d 70 63 61 63 68 65 31 2e 67 72 70 2e 70 4c  p=pcache1.grp.pL
8020: 72 75 48 65 61 64 3b 20 70 3b 20 70 3d 70 2d 3e  ruHead; p; p=p->
8030: 70 4c 72 75 4e 65 78 74 29 7b 0a 20 20 20 20 6e  pLruNext){.    n
8040: 52 65 63 79 63 6c 61 62 6c 65 2b 2b 3b 0a 20 20  Recyclable++;.  
8050: 7d 0a 20 20 2a 70 6e 43 75 72 72 65 6e 74 20 3d  }.  *pnCurrent =
8060: 20 70 63 61 63 68 65 31 2e 67 72 70 2e 6e 43 75   pcache1.grp.nCu
8070: 72 72 65 6e 74 50 61 67 65 3b 0a 20 20 2a 70 6e  rrentPage;.  *pn
8080: 4d 61 78 20 3d 20 28 69 6e 74 29 70 63 61 63 68  Max = (int)pcach
8090: 65 31 2e 67 72 70 2e 6e 4d 61 78 50 61 67 65 3b  e1.grp.nMaxPage;
80a0: 0a 20 20 2a 70 6e 4d 69 6e 20 3d 20 28 69 6e 74  .  *pnMin = (int
80b0: 29 70 63 61 63 68 65 31 2e 67 72 70 2e 6e 4d 69  )pcache1.grp.nMi
80c0: 6e 50 61 67 65 3b 0a 20 20 2a 70 6e 52 65 63 79  nPage;.  *pnRecy
80d0: 63 6c 61 62 6c 65 20 3d 20 6e 52 65 63 79 63 6c  clable = nRecycl
80e0: 61 62 6c 65 3b 0a 7d 0a 23 65 6e 64 69 66 0a     able;.}.#endif.