/ Hex Artifact Content
Login

Artifact 2610bcebf127df5ff82730c0c130cb35d4d6debe:


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 69  U or NULL */.  i
0770: 6e 74 20 6e 4d 61 78 50 61 67 65 3b 20 20 20 20  nt nMaxPage;    
0780: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
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 69 6e 74 20 6e 4d 69 6e 50  s */.  int nMinP
07c0: 61 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  age;            
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 69  le caches */.  i
0800: 6e 74 20 6e 43 75 72 72 65 6e 74 50 61 67 65 3b  nt nCurrentPage;
0810: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0820: 20 4e 75 6d 62 65 72 20 6f 66 20 70 75 72 67 65   Number of purge
0830: 61 62 6c 65 20 70 61 67 65 73 20 61 6c 6c 6f 63  able pages alloc
0840: 61 74 65 64 20 2a 2f 0a 20 20 50 67 48 64 72 31  ated */.  PgHdr1
0850: 20 2a 70 4c 72 75 48 65 61 64 2c 20 2a 70 4c 72   *pLruHead, *pLr
0860: 75 54 61 69 6c 3b 20 20 20 2f 2a 20 4c 52 55 20  uTail;   /* LRU 
0870: 6c 69 73 74 20 6f 66 20 75 6e 70 69 6e 6e 65 64  list of unpinned
0880: 20 70 61 67 65 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a   pages */.};../*
0890: 20 45 61 63 68 20 70 61 67 65 20 63 61 63 68 65   Each page cache
08a0: 20 69 73 20 61 6e 20 69 6e 73 74 61 6e 63 65 20   is an instance 
08b0: 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  of the following
08c0: 20 6f 62 6a 65 63 74 2e 20 20 45 76 65 72 79 0a   object.  Every.
08d0: 2a 2a 20 6f 70 65 6e 20 64 61 74 61 62 61 73 65  ** open database
08e0: 20 66 69 6c 65 20 28 69 6e 63 6c 75 64 69 6e 67   file (including
08f0: 20 65 61 63 68 20 69 6e 2d 6d 65 6d 6f 72 79 20   each in-memory 
0900: 64 61 74 61 62 61 73 65 20 61 6e 64 20 65 61 63  database and eac
0910: 68 0a 2a 2a 20 74 65 6d 70 6f 72 61 72 79 20 6f  h.** temporary o
0920: 72 20 74 72 61 6e 73 69 65 6e 74 20 64 61 74 61  r transient data
0930: 62 61 73 65 29 20 68 61 73 20 61 20 73 69 6e 67  base) has a sing
0940: 6c 65 20 70 61 67 65 20 63 61 63 68 65 20 77 68  le page cache wh
0950: 69 63 68 0a 2a 2a 20 69 73 20 61 6e 20 69 6e 73  ich.** is an ins
0960: 74 61 6e 63 65 20 6f 66 20 74 68 69 73 20 6f 62  tance of this ob
0970: 6a 65 63 74 2e 0a 2a 2a 0a 2a 2a 20 50 6f 69 6e  ject..**.** Poin
0980: 74 65 72 73 20 74 6f 20 73 74 72 75 63 74 75 72  ters to structur
0990: 65 73 20 6f 66 20 74 68 69 73 20 74 79 70 65 20  es of this type 
09a0: 61 72 65 20 63 61 73 74 20 61 6e 64 20 72 65 74  are cast and ret
09b0: 75 72 6e 65 64 20 61 73 20 0a 2a 2a 20 6f 70 61  urned as .** opa
09c0: 71 75 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63  que sqlite3_pcac
09d0: 68 65 2a 20 68 61 6e 64 6c 65 73 2e 0a 2a 2f 0a  he* handles..*/.
09e0: 73 74 72 75 63 74 20 50 43 61 63 68 65 31 20 7b  struct PCache1 {
09f0: 0a 20 20 2f 2a 20 43 61 63 68 65 20 63 6f 6e 66  .  /* Cache conf
0a00: 69 67 75 72 61 74 69 6f 6e 20 70 61 72 61 6d 65  iguration parame
0a10: 74 65 72 73 2e 20 50 61 67 65 20 73 69 7a 65 20  ters. Page size 
0a20: 28 73 7a 50 61 67 65 29 20 61 6e 64 20 74 68 65  (szPage) and the
0a30: 20 70 75 72 67 65 61 62 6c 65 0a 20 20 2a 2a 20   purgeable.  ** 
0a40: 66 6c 61 67 20 28 62 50 75 72 67 65 61 62 6c 65  flag (bPurgeable
0a50: 29 20 61 72 65 20 73 65 74 20 77 68 65 6e 20 74  ) are set when t
0a60: 68 65 20 63 61 63 68 65 20 69 73 20 63 72 65 61  he cache is crea
0a70: 74 65 64 2e 20 6e 4d 61 78 20 6d 61 79 20 62 65  ted. nMax may be
0a80: 20 0a 20 20 2a 2a 20 6d 6f 64 69 66 69 65 64 20   .  ** modified 
0a90: 61 74 20 61 6e 79 20 74 69 6d 65 20 62 79 20 61  at any time by a
0aa0: 20 63 61 6c 6c 20 74 6f 20 74 68 65 20 70 63 61   call to the pca
0ab0: 63 68 65 31 43 61 63 68 65 53 69 7a 65 28 29 20  che1CacheSize() 
0ac0: 6d 65 74 68 6f 64 2e 0a 20 20 2a 2a 20 54 68 65  method..  ** The
0ad0: 20 50 47 72 6f 75 70 20 6d 75 74 65 78 20 6d 75   PGroup mutex mu
0ae0: 73 74 20 62 65 20 68 65 6c 64 20 77 68 65 6e 20  st be held when 
0af0: 61 63 63 65 73 73 69 6e 67 20 6e 4d 61 78 2e 0a  accessing nMax..
0b00: 20 20 2a 2f 0a 20 20 50 47 72 6f 75 70 20 2a 70    */.  PGroup *p
0b10: 47 72 6f 75 70 3b 20 20 20 20 20 20 20 20 20 20  Group;          
0b20: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 47             /* PG
0b30: 72 6f 75 70 20 74 68 69 73 20 63 61 63 68 65 20  roup this cache 
0b40: 62 65 6c 6f 6e 67 73 20 74 6f 20 2a 2f 0a 20 20  belongs to */.  
0b50: 69 6e 74 20 73 7a 50 61 67 65 3b 20 20 20 20 20  int szPage;     
0b60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0b70: 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 61      /* Size of a
0b80: 6c 6c 6f 63 61 74 65 64 20 70 61 67 65 73 20 69  llocated pages i
0b90: 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 69 6e 74  n bytes */.  int
0ba0: 20 62 50 75 72 67 65 61 62 6c 65 3b 20 20 20 20   bPurgeable;    
0bb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0bc0: 20 2f 2a 20 54 72 75 65 20 69 66 20 63 61 63 68   /* True if cach
0bd0: 65 20 69 73 20 70 75 72 67 65 61 62 6c 65 20 2a  e is purgeable *
0be0: 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74  /.  unsigned int
0bf0: 20 6e 4d 69 6e 3b 20 20 20 20 20 20 20 20 20 20   nMin;          
0c00: 20 20 20 20 20 20 20 20 2f 2a 20 4d 69 6e 69 6d          /* Minim
0c10: 75 6d 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67  um number of pag
0c20: 65 73 20 72 65 73 65 72 76 65 64 20 2a 2f 0a 20  es reserved */. 
0c30: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 4d   unsigned int nM
0c40: 61 78 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ax;             
0c50: 20 20 20 20 20 2f 2a 20 43 6f 6e 66 69 67 75 72       /* Configur
0c60: 65 64 20 22 63 61 63 68 65 5f 73 69 7a 65 22 20  ed "cache_size" 
0c70: 76 61 6c 75 65 20 2a 2f 0a 0a 20 20 2f 2a 20 48  value */..  /* H
0c80: 61 73 68 20 74 61 62 6c 65 20 6f 66 20 61 6c 6c  ash table of all
0c90: 20 70 61 67 65 73 2e 20 54 68 65 20 66 6f 6c 6c   pages. The foll
0ca0: 6f 77 69 6e 67 20 76 61 72 69 61 62 6c 65 73 20  owing variables 
0cb0: 6d 61 79 20 6f 6e 6c 79 20 62 65 20 61 63 63 65  may only be acce
0cc0: 73 73 65 64 0a 20 20 2a 2a 20 77 68 65 6e 20 74  ssed.  ** when t
0cd0: 68 65 20 61 63 63 65 73 73 6f 72 20 69 73 20 68  he accessor is h
0ce0: 6f 6c 64 69 6e 67 20 74 68 65 20 50 47 72 6f 75  olding the PGrou
0cf0: 70 20 6d 75 74 65 78 2e 0a 20 20 2a 2f 0a 20 20  p mutex..  */.  
0d00: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 52 65  unsigned int nRe
0d10: 63 79 63 6c 61 62 6c 65 3b 20 20 20 20 20 20 20  cyclable;       
0d20: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
0d30: 20 70 61 67 65 73 20 69 6e 20 74 68 65 20 4c 52   pages in the LR
0d40: 55 20 6c 69 73 74 20 2a 2f 0a 20 20 75 6e 73 69  U list */.  unsi
0d50: 67 6e 65 64 20 69 6e 74 20 6e 50 61 67 65 3b 20  gned int nPage; 
0d60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0d70: 2f 2a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20  /* Total number 
0d80: 6f 66 20 70 61 67 65 73 20 69 6e 20 61 70 48 61  of pages in apHa
0d90: 73 68 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64  sh */.  unsigned
0da0: 20 69 6e 74 20 6e 48 61 73 68 3b 20 20 20 20 20   int nHash;     
0db0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
0dc0: 75 6d 62 65 72 20 6f 66 20 73 6c 6f 74 73 20 69  umber of slots i
0dd0: 6e 20 61 70 48 61 73 68 5b 5d 20 2a 2f 0a 20 20  n apHash[] */.  
0de0: 50 67 48 64 72 31 20 2a 2a 61 70 48 61 73 68 3b  PgHdr1 **apHash;
0df0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e00: 20 20 20 20 2f 2a 20 48 61 73 68 20 74 61 62 6c      /* Hash tabl
0e10: 65 20 66 6f 72 20 66 61 73 74 20 6c 6f 6f 6b 75  e for fast looku
0e20: 70 20 62 79 20 6b 65 79 20 2a 2f 0a 0a 20 20 75  p by key */..  u
0e30: 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4d 61 78  nsigned int iMax
0e40: 4b 65 79 3b 20 20 20 20 20 20 20 20 20 20 20 20  Key;            
0e50: 20 20 20 2f 2a 20 4c 61 72 67 65 73 74 20 6b 65     /* Largest ke
0e60: 79 20 73 65 65 6e 20 73 69 6e 63 65 20 78 54 72  y seen since xTr
0e70: 75 6e 63 61 74 65 28 29 20 2a 2f 0a 7d 3b 0a 0a  uncate() */.};..
0e80: 2f 2a 0a 2a 2a 20 45 61 63 68 20 63 61 63 68 65  /*.** Each cache
0e90: 20 65 6e 74 72 79 20 69 73 20 72 65 70 72 65 73   entry is repres
0ea0: 65 6e 74 65 64 20 62 79 20 61 6e 20 69 6e 73 74  ented by an inst
0eb0: 61 6e 63 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c  ance of the foll
0ec0: 6f 77 69 6e 67 20 0a 2a 2a 20 73 74 72 75 63 74  owing .** struct
0ed0: 75 72 65 2e 20 41 20 62 75 66 66 65 72 20 6f 66  ure. A buffer of
0ee0: 20 50 67 48 64 72 31 2e 70 43 61 63 68 65 2d 3e   PgHdr1.pCache->
0ef0: 73 7a 50 61 67 65 20 62 79 74 65 73 20 69 73 20  szPage bytes is 
0f00: 61 6c 6c 6f 63 61 74 65 64 20 0a 2a 2a 20 64 69  allocated .** di
0f10: 72 65 63 74 6c 79 20 62 65 66 6f 72 65 20 74 68  rectly before th
0f20: 69 73 20 73 74 72 75 63 74 75 72 65 20 69 6e 20  is structure in 
0f30: 6d 65 6d 6f 72 79 20 28 73 65 65 20 74 68 65 20  memory (see the 
0f40: 50 47 48 44 52 31 5f 54 4f 5f 50 41 47 45 28 29  PGHDR1_TO_PAGE()
0f50: 20 0a 2a 2a 20 6d 61 63 72 6f 20 62 65 6c 6f 77   .** macro below
0f60: 29 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 50 67 48  )..*/.struct PgH
0f70: 64 72 31 20 7b 0a 20 20 75 6e 73 69 67 6e 65 64  dr1 {.  unsigned
0f80: 20 69 6e 74 20 69 4b 65 79 3b 20 20 20 20 20 20   int iKey;      
0f90: 20 20 20 20 20 20 20 2f 2a 20 4b 65 79 20 76 61         /* Key va
0fa0: 6c 75 65 20 28 70 61 67 65 20 6e 75 6d 62 65 72  lue (page number
0fb0: 29 20 2a 2f 0a 20 20 50 67 48 64 72 31 20 2a 70  ) */.  PgHdr1 *p
0fc0: 4e 65 78 74 3b 20 20 20 20 20 20 20 20 20 20 20  Next;           
0fd0: 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 69 6e        /* Next in
0fe0: 20 68 61 73 68 20 74 61 62 6c 65 20 63 68 61 69   hash table chai
0ff0: 6e 20 2a 2f 0a 20 20 50 43 61 63 68 65 31 20 2a  n */.  PCache1 *
1000: 70 43 61 63 68 65 3b 20 20 20 20 20 20 20 20 20  pCache;         
1010: 20 20 20 20 20 20 2f 2a 20 43 61 63 68 65 20 74        /* Cache t
1020: 68 61 74 20 63 75 72 72 65 6e 74 6c 79 20 6f 77  hat currently ow
1030: 6e 73 20 74 68 69 73 20 70 61 67 65 20 2a 2f 0a  ns this page */.
1040: 20 20 50 67 48 64 72 31 20 2a 70 4c 72 75 4e 65    PgHdr1 *pLruNe
1050: 78 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  xt;             
1060: 20 2f 2a 20 4e 65 78 74 20 69 6e 20 4c 52 55 20   /* Next in LRU 
1070: 6c 69 73 74 20 6f 66 20 75 6e 70 69 6e 6e 65 64  list of unpinned
1080: 20 70 61 67 65 73 20 2a 2f 0a 20 20 50 67 48 64   pages */.  PgHd
1090: 72 31 20 2a 70 4c 72 75 50 72 65 76 3b 20 20 20  r1 *pLruPrev;   
10a0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 72             /* Pr
10b0: 65 76 69 6f 75 73 20 69 6e 20 4c 52 55 20 6c 69  evious in LRU li
10c0: 73 74 20 6f 66 20 75 6e 70 69 6e 6e 65 64 20 70  st of unpinned p
10d0: 61 67 65 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a  ages */.};../*.*
10e0: 2a 20 46 72 65 65 20 73 6c 6f 74 73 20 69 6e 20  * Free slots in 
10f0: 74 68 65 20 61 6c 6c 6f 63 61 74 6f 72 20 75 73  the allocator us
1100: 65 64 20 74 6f 20 64 69 76 69 64 65 20 75 70 20  ed to divide up 
1110: 74 68 65 20 62 75 66 66 65 72 20 70 72 6f 76 69  the buffer provi
1120: 64 65 64 20 75 73 69 6e 67 0a 2a 2a 20 74 68 65  ded using.** the
1130: 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50   SQLITE_CONFIG_P
1140: 41 47 45 43 41 43 48 45 20 6d 65 63 68 61 6e 69  AGECACHE mechani
1150: 73 6d 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 50 67  sm..*/.struct Pg
1160: 46 72 65 65 73 6c 6f 74 20 7b 0a 20 20 50 67 46  Freeslot {.  PgF
1170: 72 65 65 73 6c 6f 74 20 2a 70 4e 65 78 74 3b 20  reeslot *pNext; 
1180: 20 2f 2a 20 4e 65 78 74 20 66 72 65 65 20 73 6c   /* Next free sl
1190: 6f 74 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20  ot */.};../*.** 
11a0: 47 6c 6f 62 61 6c 20 64 61 74 61 20 75 73 65 64  Global data used
11b0: 20 62 79 20 74 68 69 73 20 63 61 63 68 65 2e 0a   by this cache..
11c0: 2a 2f 0a 73 74 61 74 69 63 20 53 51 4c 49 54 45  */.static SQLITE
11d0: 5f 57 53 44 20 73 74 72 75 63 74 20 50 43 61 63  _WSD struct PCac
11e0: 68 65 47 6c 6f 62 61 6c 20 7b 0a 20 20 50 47 72  heGlobal {.  PGr
11f0: 6f 75 70 20 67 72 70 3b 20 20 20 20 20 20 20 20  oup grp;        
1200: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
1210: 68 65 20 67 6c 6f 62 61 6c 20 50 47 72 6f 75 70  he global PGroup
1220: 20 66 6f 72 20 6d 6f 64 65 20 28 32 29 20 2a 2f   for mode (2) */
1230: 0a 0a 20 20 2f 2a 20 56 61 72 69 61 62 6c 65 73  ..  /* Variables
1240: 20 72 65 6c 61 74 65 64 20 74 6f 20 53 51 4c 49   related to SQLI
1250: 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41  TE_CONFIG_PAGECA
1260: 43 48 45 20 73 65 74 74 69 6e 67 73 2e 20 20 54  CHE settings.  T
1270: 68 65 0a 20 20 2a 2a 20 73 7a 53 6c 6f 74 2c 20  he.  ** szSlot, 
1280: 6e 53 6c 6f 74 2c 20 70 53 74 61 72 74 2c 20 70  nSlot, pStart, p
1290: 45 6e 64 2c 20 6e 52 65 73 65 72 76 65 2c 20 61  End, nReserve, a
12a0: 6e 64 20 69 73 49 6e 69 74 20 76 61 6c 75 65 73  nd isInit values
12b0: 20 61 72 65 20 61 6c 6c 0a 20 20 2a 2a 20 66 69   are all.  ** fi
12c0: 78 65 64 20 61 74 20 73 71 6c 69 74 65 33 5f 69  xed at sqlite3_i
12d0: 6e 69 74 69 61 6c 69 7a 65 28 29 20 74 69 6d 65  nitialize() time
12e0: 20 61 6e 64 20 64 6f 20 6e 6f 74 20 72 65 71 75   and do not requ
12f0: 69 72 65 20 6d 75 74 65 78 20 70 72 6f 74 65 63  ire mutex protec
1300: 74 69 6f 6e 2e 0a 20 20 2a 2a 20 54 68 65 20 6e  tion..  ** The n
1310: 46 72 65 65 53 6c 6f 74 20 61 6e 64 20 70 46 72  FreeSlot and pFr
1320: 65 65 20 76 61 6c 75 65 73 20 64 6f 20 72 65 71  ee values do req
1330: 75 69 72 65 20 6d 75 74 65 78 20 70 72 6f 74 65  uire mutex prote
1340: 63 74 69 6f 6e 2e 0a 20 20 2a 2f 0a 20 20 69 6e  ction..  */.  in
1350: 74 20 69 73 49 6e 69 74 3b 20 20 20 20 20 20 20  t isInit;       
1360: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1370: 54 72 75 65 20 69 66 20 69 6e 69 74 69 61 6c 69  True if initiali
1380: 7a 65 64 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 53  zed */.  int szS
1390: 6c 6f 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  lot;            
13a0: 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
13b0: 6f 66 20 65 61 63 68 20 66 72 65 65 20 73 6c 6f  of each free slo
13c0: 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 53 6c 6f 74  t */.  int nSlot
13d0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
13e0: 20 20 20 20 20 20 2f 2a 20 54 68 65 20 6e 75 6d        /* The num
13f0: 62 65 72 20 6f 66 20 70 63 61 63 68 65 20 73 6c  ber of pcache sl
1400: 6f 74 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 52 65  ots */.  int nRe
1410: 73 65 72 76 65 3b 20 20 20 20 20 20 20 20 20 20  serve;          
1420: 20 20 20 20 20 20 20 20 2f 2a 20 54 72 79 20 74          /* Try t
1430: 6f 20 6b 65 65 70 20 6e 46 72 65 65 53 6c 6f 74  o keep nFreeSlot
1440: 20 61 62 6f 76 65 20 74 68 69 73 20 2a 2f 0a 20   above this */. 
1450: 20 76 6f 69 64 20 2a 70 53 74 61 72 74 2c 20 2a   void *pStart, *
1460: 70 45 6e 64 3b 20 20 20 20 20 20 20 20 20 20 20  pEnd;           
1470: 2f 2a 20 42 6f 75 6e 64 73 20 6f 66 20 70 61 67  /* Bounds of pag
1480: 65 63 61 63 68 65 20 6d 61 6c 6c 6f 63 20 72 61  ecache malloc ra
1490: 6e 67 65 20 2a 2f 0a 20 20 2f 2a 20 41 62 6f 76  nge */.  /* Abov
14a0: 65 20 72 65 71 75 69 72 65 73 20 6e 6f 20 6d 75  e requires no mu
14b0: 74 65 78 2e 20 20 55 73 65 20 6d 75 74 65 78 20  tex.  Use mutex 
14c0: 62 65 6c 6f 77 20 66 6f 72 20 76 61 72 69 61 62  below for variab
14d0: 6c 65 20 74 68 61 74 20 66 6f 6c 6c 6f 77 2e 20  le that follow. 
14e0: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 6d 75 74  */.  sqlite3_mut
14f0: 65 78 20 2a 6d 75 74 65 78 3b 20 20 20 20 20 20  ex *mutex;      
1500: 20 20 20 20 2f 2a 20 4d 75 74 65 78 20 66 6f 72      /* Mutex for
1510: 20 61 63 63 65 73 73 69 6e 67 20 74 68 65 20 66   accessing the f
1520: 6f 6c 6c 6f 77 69 6e 67 3a 20 2a 2f 0a 20 20 69  ollowing: */.  i
1530: 6e 74 20 6e 46 72 65 65 53 6c 6f 74 3b 20 20 20  nt nFreeSlot;   
1540: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1550: 20 4e 75 6d 62 65 72 20 6f 66 20 75 6e 75 73 65   Number of unuse
1560: 64 20 70 63 61 63 68 65 20 73 6c 6f 74 73 20 2a  d pcache slots *
1570: 2f 0a 20 20 50 67 46 72 65 65 73 6c 6f 74 20 2a  /.  PgFreeslot *
1580: 70 46 72 65 65 3b 20 20 20 20 20 20 20 20 20 20  pFree;          
1590: 20 20 20 2f 2a 20 46 72 65 65 20 70 61 67 65 20     /* Free page 
15a0: 62 6c 6f 63 6b 73 20 2a 2f 0a 20 20 2f 2a 20 54  blocks */.  /* T
15b0: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 76 61 6c  he following val
15c0: 75 65 20 72 65 71 75 69 72 65 73 20 61 20 6d 75  ue requires a mu
15d0: 74 65 78 20 74 6f 20 63 68 61 6e 67 65 2e 20 20  tex to change.  
15e0: 57 65 20 73 6b 69 70 20 74 68 65 20 6d 75 74 65  We skip the mute
15f0: 78 20 6f 6e 0a 20 20 2a 2a 20 72 65 61 64 69 6e  x on.  ** readin
1600: 67 20 62 65 63 61 75 73 65 20 28 31 29 20 6d 6f  g because (1) mo
1610: 73 74 20 70 6c 61 74 66 6f 72 6d 73 20 72 65 61  st platforms rea
1620: 64 20 61 20 33 32 2d 62 69 74 20 69 6e 74 65 67  d a 32-bit integ
1630: 65 72 20 61 74 6f 6d 69 63 61 6c 6c 79 20 61 6e  er atomically an
1640: 64 0a 20 20 2a 2a 20 28 32 29 20 65 76 65 6e 20  d.  ** (2) even 
1650: 69 66 20 61 6e 20 69 6e 63 6f 72 72 65 63 74 20  if an incorrect 
1660: 76 61 6c 75 65 20 69 73 20 72 65 61 64 2c 20 6e  value is read, n
1670: 6f 20 67 72 65 61 74 20 68 61 72 6d 20 69 73 20  o great harm is 
1680: 64 6f 6e 65 20 73 69 6e 63 65 20 74 68 69 73 0a  done since this.
1690: 20 20 2a 2a 20 69 73 20 72 65 61 6c 6c 79 20 6a    ** is really j
16a0: 75 73 74 20 61 6e 20 6f 70 74 69 6d 69 7a 61 74  ust an optimizat
16b0: 69 6f 6e 2e 20 2a 2f 0a 20 20 69 6e 74 20 62 55  ion. */.  int bU
16c0: 6e 64 65 72 50 72 65 73 73 75 72 65 3b 20 20 20  nderPressure;   
16d0: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
16e0: 20 69 66 20 6c 6f 77 20 6f 6e 20 50 41 47 45 43   if low on PAGEC
16f0: 41 43 48 45 20 6d 65 6d 6f 72 79 20 2a 2f 0a 7d  ACHE memory */.}
1700: 20 70 63 61 63 68 65 31 5f 67 3b 0a 0a 2f 2a 0a   pcache1_g;../*.
1710: 2a 2a 20 41 6c 6c 20 63 6f 64 65 20 69 6e 20 74  ** All code in t
1720: 68 69 73 20 66 69 6c 65 20 73 68 6f 75 6c 64 20  his file should 
1730: 61 63 63 65 73 73 20 74 68 65 20 67 6c 6f 62 61  access the globa
1740: 6c 20 73 74 72 75 63 74 75 72 65 20 61 62 6f 76  l structure abov
1750: 65 20 76 69 61 20 74 68 65 0a 2a 2a 20 61 6c 69  e via the.** ali
1760: 61 73 20 22 70 63 61 63 68 65 31 22 2e 20 54 68  as "pcache1". Th
1770: 69 73 20 65 6e 73 75 72 65 73 20 74 68 61 74 20  is ensures that 
1780: 74 68 65 20 57 53 44 20 65 6d 75 6c 61 74 69 6f  the WSD emulatio
1790: 6e 20 69 73 20 75 73 65 64 20 77 68 65 6e 0a 2a  n is used when.*
17a0: 2a 20 63 6f 6d 70 69 6c 69 6e 67 20 66 6f 72 20  * compiling for 
17b0: 73 79 73 74 65 6d 73 20 74 68 61 74 20 64 6f 20  systems that do 
17c0: 6e 6f 74 20 73 75 70 70 6f 72 74 20 72 65 61 6c  not support real
17d0: 20 57 53 44 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65   WSD..*/.#define
17e0: 20 70 63 61 63 68 65 31 20 28 47 4c 4f 42 41 4c   pcache1 (GLOBAL
17f0: 28 73 74 72 75 63 74 20 50 43 61 63 68 65 47 6c  (struct PCacheGl
1800: 6f 62 61 6c 2c 20 70 63 61 63 68 65 31 5f 67 29  obal, pcache1_g)
1810: 29 0a 0a 2f 2a 0a 2a 2a 20 57 68 65 6e 20 61 20  )../*.** When a 
1820: 50 67 48 64 72 31 20 73 74 72 75 63 74 75 72 65  PgHdr1 structure
1830: 20 69 73 20 61 6c 6c 6f 63 61 74 65 64 2c 20 74   is allocated, t
1840: 68 65 20 61 73 73 6f 63 69 61 74 65 64 20 50 43  he associated PC
1850: 61 63 68 65 31 2e 73 7a 50 61 67 65 0a 2a 2a 20  ache1.szPage.** 
1860: 62 79 74 65 73 20 6f 66 20 64 61 74 61 20 61 72  bytes of data ar
1870: 65 20 6c 6f 63 61 74 65 64 20 64 69 72 65 63 74  e located direct
1880: 6c 79 20 62 65 66 6f 72 65 20 69 74 20 69 6e 20  ly before it in 
1890: 6d 65 6d 6f 72 79 20 28 69 2e 65 2e 20 74 68 65  memory (i.e. the
18a0: 20 74 6f 74 61 6c 0a 2a 2a 20 73 69 7a 65 20 6f   total.** size o
18b0: 66 20 74 68 65 20 61 6c 6c 6f 63 61 74 69 6f 6e  f the allocation
18c0: 20 69 73 20 73 69 7a 65 6f 66 28 50 67 48 64 72   is sizeof(PgHdr
18d0: 31 29 2b 50 43 61 63 68 65 31 2e 73 7a 50 61 67  1)+PCache1.szPag
18e0: 65 20 62 79 74 65 29 2e 20 54 68 65 0a 2a 2a 20  e byte). The.** 
18f0: 50 47 48 44 52 31 5f 54 4f 5f 50 41 47 45 28 29  PGHDR1_TO_PAGE()
1900: 20 6d 61 63 72 6f 20 74 61 6b 65 73 20 61 20 70   macro takes a p
1910: 6f 69 6e 74 65 72 20 74 6f 20 61 20 50 67 48 64  ointer to a PgHd
1920: 72 31 20 73 74 72 75 63 74 75 72 65 20 61 73 0a  r1 structure as.
1930: 2a 2a 20 61 6e 20 61 72 67 75 6d 65 6e 74 20 61  ** an argument a
1940: 6e 64 20 72 65 74 75 72 6e 73 20 61 20 70 6f 69  nd returns a poi
1950: 6e 74 65 72 20 74 6f 20 74 68 65 20 61 73 73 6f  nter to the asso
1960: 63 69 61 74 65 64 20 62 6c 6f 63 6b 20 6f 66 20  ciated block of 
1970: 73 7a 50 61 67 65 0a 2a 2a 20 62 79 74 65 73 2e  szPage.** bytes.
1980: 20 54 68 65 20 50 41 47 45 5f 54 4f 5f 50 47 48   The PAGE_TO_PGH
1990: 44 52 31 28 29 20 6d 61 63 72 6f 20 64 6f 65 73  DR1() macro does
19a0: 20 74 68 65 20 6f 70 70 6f 73 69 74 65 3a 20 69   the opposite: i
19b0: 74 73 20 61 72 67 75 6d 65 6e 74 20 69 73 0a 2a  ts argument is.*
19c0: 2a 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 61  * a pointer to a
19d0: 20 62 6c 6f 63 6b 20 6f 66 20 73 7a 50 61 67 65   block of szPage
19e0: 20 62 79 74 65 73 20 6f 66 20 64 61 74 61 20 61   bytes of data a
19f0: 6e 64 20 74 68 65 20 72 65 74 75 72 6e 20 76 61  nd the return va
1a00: 6c 75 65 20 69 73 0a 2a 2a 20 61 20 70 6f 69 6e  lue is.** a poin
1a10: 74 65 72 20 74 6f 20 74 68 65 20 61 73 73 6f 63  ter to the assoc
1a20: 69 61 74 65 64 20 50 67 48 64 72 31 20 73 74 72  iated PgHdr1 str
1a30: 75 63 74 75 72 65 2e 0a 2a 2a 0a 2a 2a 20 20 20  ucture..**.**   
1a40: 61 73 73 65 72 74 28 20 50 47 48 44 52 31 5f 54  assert( PGHDR1_T
1a50: 4f 5f 50 41 47 45 28 50 41 47 45 5f 54 4f 5f 50  O_PAGE(PAGE_TO_P
1a60: 47 48 44 52 31 28 70 43 61 63 68 65 2c 20 58 29  GHDR1(pCache, X)
1a70: 29 3d 3d 58 20 29 3b 0a 2a 2f 0a 23 64 65 66 69  )==X );.*/.#defi
1a80: 6e 65 20 50 47 48 44 52 31 5f 54 4f 5f 50 41 47  ne PGHDR1_TO_PAG
1a90: 45 28 70 29 20 20 20 20 28 76 6f 69 64 2a 29 28  E(p)    (void*)(
1aa0: 28 28 63 68 61 72 2a 29 70 29 20 2d 20 70 2d 3e  ((char*)p) - p->
1ab0: 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 29 0a  pCache->szPage).
1ac0: 23 64 65 66 69 6e 65 20 50 41 47 45 5f 54 4f 5f  #define PAGE_TO_
1ad0: 50 47 48 44 52 31 28 63 2c 20 70 29 20 28 50 67  PGHDR1(c, p) (Pg
1ae0: 48 64 72 31 2a 29 28 28 28 63 68 61 72 2a 29 70  Hdr1*)(((char*)p
1af0: 29 20 2b 20 63 2d 3e 73 7a 50 61 67 65 29 0a 0a  ) + c->szPage)..
1b00: 2f 2a 0a 2a 2a 20 4d 61 63 72 6f 73 20 74 6f 20  /*.** Macros to 
1b10: 65 6e 74 65 72 20 61 6e 64 20 6c 65 61 76 65 20  enter and leave 
1b20: 74 68 65 20 50 43 61 63 68 65 20 4c 52 55 20 6d  the PCache LRU m
1b30: 75 74 65 78 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65  utex..*/.#define
1b40: 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74   pcache1EnterMut
1b50: 65 78 28 58 29 20 73 71 6c 69 74 65 33 5f 6d 75  ex(X) sqlite3_mu
1b60: 74 65 78 5f 65 6e 74 65 72 28 28 58 29 2d 3e 6d  tex_enter((X)->m
1b70: 75 74 65 78 29 0a 23 64 65 66 69 6e 65 20 70 63  utex).#define pc
1b80: 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28  ache1LeaveMutex(
1b90: 58 29 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78  X) sqlite3_mutex
1ba0: 5f 6c 65 61 76 65 28 28 58 29 2d 3e 6d 75 74 65  _leave((X)->mute
1bb0: 78 29 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  x)../***********
1bc0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1bd0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1be0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1bf0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1c00: 2a 2a 2a 2f 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 20 50  ***/./******** P
1c10: 61 67 65 20 41 6c 6c 6f 63 61 74 69 6f 6e 2f 53  age Allocation/S
1c20: 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 43 41  QLITE_CONFIG_PCA
1c30: 43 48 45 20 52 65 6c 61 74 65 64 20 46 75 6e 63  CHE Related Func
1c40: 74 69 6f 6e 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  tions **********
1c50: 2a 2a 2a 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 54 68 69  ****/../*.** Thi
1c60: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61  s function is ca
1c70: 6c 6c 65 64 20 64 75 72 69 6e 67 20 69 6e 69 74  lled during init
1c80: 69 61 6c 69 7a 61 74 69 6f 6e 20 69 66 20 61 20  ialization if a 
1c90: 73 74 61 74 69 63 20 62 75 66 66 65 72 20 69 73  static buffer is
1ca0: 20 0a 2a 2a 20 73 75 70 70 6c 69 65 64 20 74 6f   .** supplied to
1cb0: 20 75 73 65 20 66 6f 72 20 74 68 65 20 70 61 67   use for the pag
1cc0: 65 2d 63 61 63 68 65 20 62 79 20 70 61 73 73 69  e-cache by passi
1cd0: 6e 67 20 74 68 65 20 53 51 4c 49 54 45 5f 43 4f  ng the SQLITE_CO
1ce0: 4e 46 49 47 5f 50 41 47 45 43 41 43 48 45 0a 2a  NFIG_PAGECACHE.*
1cf0: 2a 20 76 65 72 62 20 74 6f 20 73 71 6c 69 74 65  * verb to sqlite
1d00: 33 5f 63 6f 6e 66 69 67 28 29 2e 20 50 61 72 61  3_config(). Para
1d10: 6d 65 74 65 72 20 70 42 75 66 20 70 6f 69 6e 74  meter pBuf point
1d20: 73 20 74 6f 20 61 6e 20 61 6c 6c 6f 63 61 74 69  s to an allocati
1d30: 6f 6e 20 6c 61 72 67 65 0a 2a 2a 20 65 6e 6f 75  on large.** enou
1d40: 67 68 20 74 6f 20 63 6f 6e 74 61 69 6e 20 27 6e  gh to contain 'n
1d50: 27 20 62 75 66 66 65 72 73 20 6f 66 20 27 73 7a  ' buffers of 'sz
1d60: 27 20 62 79 74 65 73 20 65 61 63 68 2e 0a 2a 2a  ' bytes each..**
1d70: 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65  .** This routine
1d80: 20 69 73 20 63 61 6c 6c 65 64 20 66 72 6f 6d 20   is called from 
1d90: 73 71 6c 69 74 65 33 5f 69 6e 69 74 69 61 6c 69  sqlite3_initiali
1da0: 7a 65 28 29 20 61 6e 64 20 73 6f 20 69 74 20 69  ze() and so it i
1db0: 73 20 67 75 61 72 61 6e 74 65 65 64 0a 2a 2a 20  s guaranteed.** 
1dc0: 74 6f 20 62 65 20 73 65 72 69 61 6c 69 7a 65 64  to be serialized
1dd0: 20 61 6c 72 65 61 64 79 2e 20 20 54 68 65 72 65   already.  There
1de0: 20 69 73 20 6e 6f 20 6e 65 65 64 20 66 6f 72 20   is no need for 
1df0: 66 75 72 74 68 65 72 20 6d 75 74 65 78 69 6e 67  further mutexing
1e00: 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
1e10: 33 50 43 61 63 68 65 42 75 66 66 65 72 53 65 74  3PCacheBufferSet
1e20: 75 70 28 76 6f 69 64 20 2a 70 42 75 66 2c 20 69  up(void *pBuf, i
1e30: 6e 74 20 73 7a 2c 20 69 6e 74 20 6e 29 7b 0a 20  nt sz, int n){. 
1e40: 20 69 66 28 20 70 63 61 63 68 65 31 2e 69 73 49   if( pcache1.isI
1e50: 6e 69 74 20 29 7b 0a 20 20 20 20 50 67 46 72 65  nit ){.    PgFre
1e60: 65 73 6c 6f 74 20 2a 70 3b 0a 20 20 20 20 73 7a  eslot *p;.    sz
1e70: 20 3d 20 52 4f 55 4e 44 44 4f 57 4e 38 28 73 7a   = ROUNDDOWN8(sz
1e80: 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 73  );.    pcache1.s
1e90: 7a 53 6c 6f 74 20 3d 20 73 7a 3b 0a 20 20 20 20  zSlot = sz;.    
1ea0: 70 63 61 63 68 65 31 2e 6e 53 6c 6f 74 20 3d 20  pcache1.nSlot = 
1eb0: 70 63 61 63 68 65 31 2e 6e 46 72 65 65 53 6c 6f  pcache1.nFreeSlo
1ec0: 74 20 3d 20 6e 3b 0a 20 20 20 20 70 63 61 63 68  t = n;.    pcach
1ed0: 65 31 2e 6e 52 65 73 65 72 76 65 20 3d 20 6e 3e  e1.nReserve = n>
1ee0: 39 30 20 3f 20 31 30 20 3a 20 28 6e 2f 31 30 20  90 ? 10 : (n/10 
1ef0: 2b 20 31 29 3b 0a 20 20 20 20 70 63 61 63 68 65  + 1);.    pcache
1f00: 31 2e 70 53 74 61 72 74 20 3d 20 70 42 75 66 3b  1.pStart = pBuf;
1f10: 0a 20 20 20 20 70 63 61 63 68 65 31 2e 70 46 72  .    pcache1.pFr
1f20: 65 65 20 3d 20 30 3b 0a 20 20 20 20 70 63 61 63  ee = 0;.    pcac
1f30: 68 65 31 2e 62 55 6e 64 65 72 50 72 65 73 73 75  he1.bUnderPressu
1f40: 72 65 20 3d 20 30 3b 0a 20 20 20 20 77 68 69 6c  re = 0;.    whil
1f50: 65 28 20 6e 2d 2d 20 29 7b 0a 20 20 20 20 20 20  e( n-- ){.      
1f60: 70 20 3d 20 28 50 67 46 72 65 65 73 6c 6f 74 2a  p = (PgFreeslot*
1f70: 29 70 42 75 66 3b 0a 20 20 20 20 20 20 70 2d 3e  )pBuf;.      p->
1f80: 70 4e 65 78 74 20 3d 20 70 63 61 63 68 65 31 2e  pNext = pcache1.
1f90: 70 46 72 65 65 3b 0a 20 20 20 20 20 20 70 63 61  pFree;.      pca
1fa0: 63 68 65 31 2e 70 46 72 65 65 20 3d 20 70 3b 0a  che1.pFree = p;.
1fb0: 20 20 20 20 20 20 70 42 75 66 20 3d 20 28 76 6f        pBuf = (vo
1fc0: 69 64 2a 29 26 28 28 63 68 61 72 2a 29 70 42 75  id*)&((char*)pBu
1fd0: 66 29 5b 73 7a 5d 3b 0a 20 20 20 20 7d 0a 20 20  f)[sz];.    }.  
1fe0: 20 20 70 63 61 63 68 65 31 2e 70 45 6e 64 20 3d    pcache1.pEnd =
1ff0: 20 70 42 75 66 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a   pBuf;.  }.}../*
2000: 0a 2a 2a 20 4d 61 6c 6c 6f 63 20 66 75 6e 63 74  .** Malloc funct
2010: 69 6f 6e 20 75 73 65 64 20 77 69 74 68 69 6e 20  ion used within 
2020: 74 68 69 73 20 66 69 6c 65 20 74 6f 20 61 6c 6c  this file to all
2030: 6f 63 61 74 65 20 73 70 61 63 65 20 66 72 6f 6d  ocate space from
2040: 20 74 68 65 20 62 75 66 66 65 72 0a 2a 2a 20 63   the buffer.** c
2050: 6f 6e 66 69 67 75 72 65 64 20 75 73 69 6e 67 20  onfigured using 
2060: 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67 28 53  sqlite3_config(S
2070: 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47  QLITE_CONFIG_PAG
2080: 45 43 41 43 48 45 29 20 6f 70 74 69 6f 6e 2e 20  ECACHE) option. 
2090: 49 66 20 6e 6f 20 0a 2a 2a 20 73 75 63 68 20 62  If no .** such b
20a0: 75 66 66 65 72 20 65 78 69 73 74 73 20 6f 72 20  uffer exists or 
20b0: 74 68 65 72 65 20 69 73 20 6e 6f 20 73 70 61 63  there is no spac
20c0: 65 20 6c 65 66 74 20 69 6e 20 69 74 2c 20 74 68  e left in it, th
20d0: 69 73 20 66 75 6e 63 74 69 6f 6e 20 66 61 6c 6c  is function fall
20e0: 73 20 0a 2a 2a 20 62 61 63 6b 20 74 6f 20 73 71  s .** back to sq
20f0: 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 29 2e 0a 2a  lite3Malloc()..*
2100: 2a 0a 2a 2a 20 4d 75 6c 74 69 70 6c 65 20 74 68  *.** Multiple th
2110: 72 65 61 64 73 20 63 61 6e 20 72 75 6e 20 74 68  reads can run th
2120: 69 73 20 72 6f 75 74 69 6e 65 20 61 74 20 74 68  is routine at th
2130: 65 20 73 61 6d 65 20 74 69 6d 65 2e 20 20 47 6c  e same time.  Gl
2140: 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73 0a 2a  obal variables.*
2150: 2a 20 69 6e 20 70 63 61 63 68 65 31 20 6e 65 65  * in pcache1 nee
2160: 64 20 74 6f 20 62 65 20 70 72 6f 74 65 63 74 65  d to be protecte
2170: 64 20 76 69 61 20 6d 75 74 65 78 2e 0a 2a 2f 0a  d via mutex..*/.
2180: 73 74 61 74 69 63 20 76 6f 69 64 20 2a 70 63 61  static void *pca
2190: 63 68 65 31 41 6c 6c 6f 63 28 69 6e 74 20 6e 42  che1Alloc(int nB
21a0: 79 74 65 29 7b 0a 20 20 76 6f 69 64 20 2a 70 20  yte){.  void *p 
21b0: 3d 20 30 3b 0a 20 20 61 73 73 65 72 74 28 20 73  = 0;.  assert( s
21c0: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6e 6f 74  qlite3_mutex_not
21d0: 68 65 6c 64 28 70 63 61 63 68 65 31 2e 67 72 70  held(pcache1.grp
21e0: 2e 6d 75 74 65 78 29 20 29 3b 0a 20 20 73 71 6c  .mutex) );.  sql
21f0: 69 74 65 33 53 74 61 74 75 73 53 65 74 28 53 51  ite3StatusSet(SQ
2200: 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41 47 45  LITE_STATUS_PAGE
2210: 43 41 43 48 45 5f 53 49 5a 45 2c 20 6e 42 79 74  CACHE_SIZE, nByt
2220: 65 29 3b 0a 20 20 69 66 28 20 6e 42 79 74 65 3c  e);.  if( nByte<
2230: 3d 70 63 61 63 68 65 31 2e 73 7a 53 6c 6f 74 20  =pcache1.szSlot 
2240: 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 6d  ){.    sqlite3_m
2250: 75 74 65 78 5f 65 6e 74 65 72 28 70 63 61 63 68  utex_enter(pcach
2260: 65 31 2e 6d 75 74 65 78 29 3b 0a 20 20 20 20 70  e1.mutex);.    p
2270: 20 3d 20 28 50 67 48 64 72 31 20 2a 29 70 63 61   = (PgHdr1 *)pca
2280: 63 68 65 31 2e 70 46 72 65 65 3b 0a 20 20 20 20  che1.pFree;.    
2290: 69 66 28 20 70 20 29 7b 0a 20 20 20 20 20 20 70  if( p ){.      p
22a0: 63 61 63 68 65 31 2e 70 46 72 65 65 20 3d 20 70  cache1.pFree = p
22b0: 63 61 63 68 65 31 2e 70 46 72 65 65 2d 3e 70 4e  cache1.pFree->pN
22c0: 65 78 74 3b 0a 20 20 20 20 20 20 70 63 61 63 68  ext;.      pcach
22d0: 65 31 2e 6e 46 72 65 65 53 6c 6f 74 2d 2d 3b 0a  e1.nFreeSlot--;.
22e0: 20 20 20 20 20 20 70 63 61 63 68 65 31 2e 62 55        pcache1.bU
22f0: 6e 64 65 72 50 72 65 73 73 75 72 65 20 3d 20 70  nderPressure = p
2300: 63 61 63 68 65 31 2e 6e 46 72 65 65 53 6c 6f 74  cache1.nFreeSlot
2310: 3c 70 63 61 63 68 65 31 2e 6e 52 65 73 65 72 76  <pcache1.nReserv
2320: 65 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28  e;.      assert(
2330: 20 70 63 61 63 68 65 31 2e 6e 46 72 65 65 53 6c   pcache1.nFreeSl
2340: 6f 74 3e 3d 30 20 29 3b 0a 20 20 20 20 20 20 73  ot>=0 );.      s
2350: 71 6c 69 74 65 33 53 74 61 74 75 73 41 64 64 28  qlite3StatusAdd(
2360: 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41  SQLITE_STATUS_PA
2370: 47 45 43 41 43 48 45 5f 55 53 45 44 2c 20 31 29  GECACHE_USED, 1)
2380: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 6c 69  ;.    }.    sqli
2390: 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28  te3_mutex_leave(
23a0: 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a  pcache1.mutex);.
23b0: 20 20 7d 0a 20 20 69 66 28 20 70 3d 3d 30 20 29    }.  if( p==0 )
23c0: 7b 0a 20 20 20 20 2f 2a 20 4d 65 6d 6f 72 79 20  {.    /* Memory 
23d0: 69 73 20 6e 6f 74 20 61 76 61 69 6c 61 62 6c 65  is not available
23e0: 20 69 6e 20 74 68 65 20 53 51 4c 49 54 45 5f 43   in the SQLITE_C
23f0: 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48 45 20  ONFIG_PAGECACHE 
2400: 70 6f 6f 6c 2e 20 20 47 65 74 0a 20 20 20 20 2a  pool.  Get.    *
2410: 2a 20 69 74 20 66 72 6f 6d 20 73 71 6c 69 74 65  * it from sqlite
2420: 33 4d 61 6c 6c 6f 63 20 69 6e 73 74 65 61 64 2e  3Malloc instead.
2430: 0a 20 20 20 20 2a 2f 0a 20 20 20 20 70 20 3d 20  .    */.    p = 
2440: 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 6e 42  sqlite3Malloc(nB
2450: 79 74 65 29 3b 0a 20 20 20 20 69 66 28 20 70 20  yte);.    if( p 
2460: 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 73 7a 20  ){.      int sz 
2470: 3d 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 53  = sqlite3MallocS
2480: 69 7a 65 28 70 29 3b 0a 20 20 20 20 20 20 73 71  ize(p);.      sq
2490: 6c 69 74 65 33 53 74 61 74 75 73 41 64 64 28 53  lite3StatusAdd(S
24a0: 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41 47  QLITE_STATUS_PAG
24b0: 45 43 41 43 48 45 5f 4f 56 45 52 46 4c 4f 57 2c  ECACHE_OVERFLOW,
24c0: 20 73 7a 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20   sz);.    }.    
24d0: 73 71 6c 69 74 65 33 4d 65 6d 64 65 62 75 67 53  sqlite3MemdebugS
24e0: 65 74 54 79 70 65 28 70 2c 20 4d 45 4d 54 59 50  etType(p, MEMTYP
24f0: 45 5f 50 43 41 43 48 45 29 3b 0a 20 20 7d 0a 20  E_PCACHE);.  }. 
2500: 20 72 65 74 75 72 6e 20 70 3b 0a 7d 0a 0a 2f 2a   return p;.}../*
2510: 0a 2a 2a 20 46 72 65 65 20 61 6e 20 61 6c 6c 6f  .** Free an allo
2520: 63 61 74 65 64 20 62 75 66 66 65 72 20 6f 62 74  cated buffer obt
2530: 61 69 6e 65 64 20 66 72 6f 6d 20 70 63 61 63 68  ained from pcach
2540: 65 31 41 6c 6c 6f 63 28 29 2e 0a 2a 2f 0a 73 74  e1Alloc()..*/.st
2550: 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65  atic void pcache
2560: 31 46 72 65 65 28 76 6f 69 64 20 2a 70 29 7b 0a  1Free(void *p){.
2570: 20 20 69 66 28 20 70 3d 3d 30 20 29 20 72 65 74    if( p==0 ) ret
2580: 75 72 6e 3b 0a 20 20 69 66 28 20 70 3e 3d 70 63  urn;.  if( p>=pc
2590: 61 63 68 65 31 2e 70 53 74 61 72 74 20 26 26 20  ache1.pStart && 
25a0: 70 3c 70 63 61 63 68 65 31 2e 70 45 6e 64 20 29  p<pcache1.pEnd )
25b0: 7b 0a 20 20 20 20 50 67 46 72 65 65 73 6c 6f 74  {.    PgFreeslot
25c0: 20 2a 70 53 6c 6f 74 3b 0a 20 20 20 20 73 71 6c   *pSlot;.    sql
25d0: 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e 74 65 72  ite3_mutex_enter
25e0: 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29 3b  (pcache1.mutex);
25f0: 0a 20 20 20 20 73 71 6c 69 74 65 33 53 74 61 74  .    sqlite3Stat
2600: 75 73 41 64 64 28 53 51 4c 49 54 45 5f 53 54 41  usAdd(SQLITE_STA
2610: 54 55 53 5f 50 41 47 45 43 41 43 48 45 5f 55 53  TUS_PAGECACHE_US
2620: 45 44 2c 20 2d 31 29 3b 0a 20 20 20 20 70 53 6c  ED, -1);.    pSl
2630: 6f 74 20 3d 20 28 50 67 46 72 65 65 73 6c 6f 74  ot = (PgFreeslot
2640: 2a 29 70 3b 0a 20 20 20 20 70 53 6c 6f 74 2d 3e  *)p;.    pSlot->
2650: 70 4e 65 78 74 20 3d 20 70 63 61 63 68 65 31 2e  pNext = pcache1.
2660: 70 46 72 65 65 3b 0a 20 20 20 20 70 63 61 63 68  pFree;.    pcach
2670: 65 31 2e 70 46 72 65 65 20 3d 20 70 53 6c 6f 74  e1.pFree = pSlot
2680: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 6e 46  ;.    pcache1.nF
2690: 72 65 65 53 6c 6f 74 2b 2b 3b 0a 20 20 20 20 70  reeSlot++;.    p
26a0: 63 61 63 68 65 31 2e 62 55 6e 64 65 72 50 72 65  cache1.bUnderPre
26b0: 73 73 75 72 65 20 3d 20 70 63 61 63 68 65 31 2e  ssure = pcache1.
26c0: 6e 46 72 65 65 53 6c 6f 74 3c 70 63 61 63 68 65  nFreeSlot<pcache
26d0: 31 2e 6e 52 65 73 65 72 76 65 3b 0a 20 20 20 20  1.nReserve;.    
26e0: 61 73 73 65 72 74 28 20 70 63 61 63 68 65 31 2e  assert( pcache1.
26f0: 6e 46 72 65 65 53 6c 6f 74 3c 3d 70 63 61 63 68  nFreeSlot<=pcach
2700: 65 31 2e 6e 53 6c 6f 74 20 29 3b 0a 20 20 20 20  e1.nSlot );.    
2710: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6c 65  sqlite3_mutex_le
2720: 61 76 65 28 70 63 61 63 68 65 31 2e 6d 75 74 65  ave(pcache1.mute
2730: 78 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  x);.  }else{.   
2740: 20 69 6e 74 20 69 53 69 7a 65 3b 0a 20 20 20 20   int iSize;.    
2750: 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 4d  assert( sqlite3M
2760: 65 6d 64 65 62 75 67 48 61 73 54 79 70 65 28 70  emdebugHasType(p
2770: 2c 20 4d 45 4d 54 59 50 45 5f 50 43 41 43 48 45  , MEMTYPE_PCACHE
2780: 29 20 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  ) );.    sqlite3
2790: 4d 65 6d 64 65 62 75 67 53 65 74 54 79 70 65 28  MemdebugSetType(
27a0: 70 2c 20 4d 45 4d 54 59 50 45 5f 48 45 41 50 29  p, MEMTYPE_HEAP)
27b0: 3b 0a 20 20 20 20 69 53 69 7a 65 20 3d 20 73 71  ;.    iSize = sq
27c0: 6c 69 74 65 33 4d 61 6c 6c 6f 63 53 69 7a 65 28  lite3MallocSize(
27d0: 70 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 53  p);.    sqlite3S
27e0: 74 61 74 75 73 41 64 64 28 53 51 4c 49 54 45 5f  tatusAdd(SQLITE_
27f0: 53 54 41 54 55 53 5f 50 41 47 45 43 41 43 48 45  STATUS_PAGECACHE
2800: 5f 4f 56 45 52 46 4c 4f 57 2c 20 2d 69 53 69 7a  _OVERFLOW, -iSiz
2810: 65 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  e);.    sqlite3_
2820: 66 72 65 65 28 70 29 3b 0a 20 20 7d 0a 7d 0a 0a  free(p);.  }.}..
2830: 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 45 4e  #ifdef SQLITE_EN
2840: 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41  ABLE_MEMORY_MANA
2850: 47 45 4d 45 4e 54 0a 2f 2a 0a 2a 2a 20 52 65 74  GEMENT./*.** Ret
2860: 75 72 6e 20 74 68 65 20 73 69 7a 65 20 6f 66 20  urn the size of 
2870: 61 20 70 63 61 63 68 65 20 61 6c 6c 6f 63 61 74  a pcache allocat
2880: 69 6f 6e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ion.*/.static in
2890: 74 20 70 63 61 63 68 65 31 4d 65 6d 53 69 7a 65  t pcache1MemSize
28a0: 28 76 6f 69 64 20 2a 70 29 7b 0a 20 20 69 66 28  (void *p){.  if(
28b0: 20 70 3e 3d 70 63 61 63 68 65 31 2e 70 53 74 61   p>=pcache1.pSta
28c0: 72 74 20 26 26 20 70 3c 70 63 61 63 68 65 31 2e  rt && p<pcache1.
28d0: 70 45 6e 64 20 29 7b 0a 20 20 20 20 72 65 74 75  pEnd ){.    retu
28e0: 72 6e 20 70 63 61 63 68 65 31 2e 73 7a 53 6c 6f  rn pcache1.szSlo
28f0: 74 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  t;.  }else{.    
2900: 69 6e 74 20 69 53 69 7a 65 3b 0a 20 20 20 20 61  int iSize;.    a
2910: 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 4d 65  ssert( sqlite3Me
2920: 6d 64 65 62 75 67 48 61 73 54 79 70 65 28 70 2c  mdebugHasType(p,
2930: 20 4d 45 4d 54 59 50 45 5f 50 43 41 43 48 45 29   MEMTYPE_PCACHE)
2940: 20 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 4d   );.    sqlite3M
2950: 65 6d 64 65 62 75 67 53 65 74 54 79 70 65 28 70  emdebugSetType(p
2960: 2c 20 4d 45 4d 54 59 50 45 5f 48 45 41 50 29 3b  , MEMTYPE_HEAP);
2970: 0a 20 20 20 20 69 53 69 7a 65 20 3d 20 73 71 6c  .    iSize = sql
2980: 69 74 65 33 4d 61 6c 6c 6f 63 53 69 7a 65 28 70  ite3MallocSize(p
2990: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 4d 65  );.    sqlite3Me
29a0: 6d 64 65 62 75 67 53 65 74 54 79 70 65 28 70 2c  mdebugSetType(p,
29b0: 20 4d 45 4d 54 59 50 45 5f 50 43 41 43 48 45 29   MEMTYPE_PCACHE)
29c0: 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 69 53 69  ;.    return iSi
29d0: 7a 65 3b 0a 20 20 7d 0a 7d 0a 23 65 6e 64 69 66  ze;.  }.}.#endif
29e0: 20 2f 2a 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c   /* SQLITE_ENABL
29f0: 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d  E_MEMORY_MANAGEM
2a00: 45 4e 54 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 41 6c  ENT */../*.** Al
2a10: 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 70 61 67  locate a new pag
2a20: 65 20 6f 62 6a 65 63 74 20 69 6e 69 74 69 61 6c  e object initial
2a30: 6c 79 20 61 73 73 6f 63 69 61 74 65 64 20 77 69  ly associated wi
2a40: 74 68 20 63 61 63 68 65 20 70 43 61 63 68 65 2e  th cache pCache.
2a50: 0a 2a 2f 0a 73 74 61 74 69 63 20 50 67 48 64 72  .*/.static PgHdr
2a60: 31 20 2a 70 63 61 63 68 65 31 41 6c 6c 6f 63 50  1 *pcache1AllocP
2a70: 61 67 65 28 50 43 61 63 68 65 31 20 2a 70 43 61  age(PCache1 *pCa
2a80: 63 68 65 29 7b 0a 20 20 69 6e 74 20 6e 42 79 74  che){.  int nByt
2a90: 65 20 3d 20 73 69 7a 65 6f 66 28 50 67 48 64 72  e = sizeof(PgHdr
2aa0: 31 29 20 2b 20 70 43 61 63 68 65 2d 3e 73 7a 50  1) + pCache->szP
2ab0: 61 67 65 3b 0a 20 20 76 6f 69 64 20 2a 70 50 67  age;.  void *pPg
2ac0: 20 3d 20 70 63 61 63 68 65 31 41 6c 6c 6f 63 28   = pcache1Alloc(
2ad0: 6e 42 79 74 65 29 3b 0a 20 20 50 67 48 64 72 31  nByte);.  PgHdr1
2ae0: 20 2a 70 3b 0a 20 20 69 66 28 20 70 50 67 20 29   *p;.  if( pPg )
2af0: 7b 0a 20 20 20 20 70 20 3d 20 50 41 47 45 5f 54  {.    p = PAGE_T
2b00: 4f 5f 50 47 48 44 52 31 28 70 43 61 63 68 65 2c  O_PGHDR1(pCache,
2b10: 20 70 50 67 29 3b 0a 20 20 20 20 69 66 28 20 70   pPg);.    if( p
2b20: 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c  Cache->bPurgeabl
2b30: 65 20 29 7b 0a 20 20 20 20 20 20 70 43 61 63 68  e ){.      pCach
2b40: 65 2d 3e 70 47 72 6f 75 70 2d 3e 6e 43 75 72 72  e->pGroup->nCurr
2b50: 65 6e 74 50 61 67 65 2b 2b 3b 0a 20 20 20 20 7d  entPage++;.    }
2b60: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70 20  .  }else{.    p 
2b70: 3d 20 30 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  = 0;.  }.  retur
2b80: 6e 20 70 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72  n p;.}../*.** Fr
2b90: 65 65 20 61 20 70 61 67 65 20 6f 62 6a 65 63 74  ee a page object
2ba0: 20 61 6c 6c 6f 63 61 74 65 64 20 62 79 20 70 63   allocated by pc
2bb0: 61 63 68 65 31 41 6c 6c 6f 63 50 61 67 65 28 29  ache1AllocPage()
2bc0: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 70 6f 69 6e  ..**.** The poin
2bd0: 74 65 72 20 69 73 20 61 6c 6c 6f 77 65 64 20 74  ter is allowed t
2be0: 6f 20 62 65 20 4e 55 4c 4c 2c 20 77 68 69 63 68  o be NULL, which
2bf0: 20 69 73 20 70 72 75 64 65 6e 74 2e 20 20 42 75   is prudent.  Bu
2c00: 74 20 69 74 20 74 75 72 6e 73 20 6f 75 74 0a 2a  t it turns out.*
2c10: 2a 20 74 68 61 74 20 74 68 65 20 63 75 72 72 65  * that the curre
2c20: 6e 74 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  nt implementatio
2c30: 6e 20 68 61 70 70 65 6e 73 20 74 6f 20 6e 65 76  n happens to nev
2c40: 65 72 20 63 61 6c 6c 20 74 68 69 73 20 72 6f 75  er call this rou
2c50: 74 69 6e 65 0a 2a 2a 20 77 69 74 68 20 61 20 4e  tine.** with a N
2c60: 55 4c 4c 20 70 6f 69 6e 74 65 72 2c 20 73 6f 20  ULL pointer, so 
2c70: 77 65 20 6d 61 72 6b 20 74 68 65 20 4e 55 4c 4c  we mark the NULL
2c80: 20 74 65 73 74 20 77 69 74 68 20 41 4c 57 41 59   test with ALWAY
2c90: 53 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  S()..*/.static v
2ca0: 6f 69 64 20 70 63 61 63 68 65 31 46 72 65 65 50  oid pcache1FreeP
2cb0: 61 67 65 28 50 67 48 64 72 31 20 2a 70 29 7b 0a  age(PgHdr1 *p){.
2cc0: 20 20 69 66 28 20 41 4c 57 41 59 53 28 70 29 20    if( ALWAYS(p) 
2cd0: 29 7b 0a 20 20 20 20 50 43 61 63 68 65 31 20 2a  ){.    PCache1 *
2ce0: 70 43 61 63 68 65 20 3d 20 70 2d 3e 70 43 61 63  pCache = p->pCac
2cf0: 68 65 3b 0a 20 20 20 20 69 66 28 20 70 43 61 63  he;.    if( pCac
2d00: 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 29  he->bPurgeable )
2d10: 7b 0a 20 20 20 20 20 20 70 43 61 63 68 65 2d 3e  {.      pCache->
2d20: 70 47 72 6f 75 70 2d 3e 6e 43 75 72 72 65 6e 74  pGroup->nCurrent
2d30: 50 61 67 65 2d 2d 3b 0a 20 20 20 20 7d 0a 20 20  Page--;.    }.  
2d40: 20 20 70 63 61 63 68 65 31 46 72 65 65 28 50 47    pcache1Free(PG
2d50: 48 44 52 31 5f 54 4f 5f 50 41 47 45 28 70 29 29  HDR1_TO_PAGE(p))
2d60: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d  ;.  }.}../*.** M
2d70: 61 6c 6c 6f 63 20 66 75 6e 63 74 69 6f 6e 20 75  alloc function u
2d80: 73 65 64 20 62 79 20 53 51 4c 69 74 65 20 74 6f  sed by SQLite to
2d90: 20 6f 62 74 61 69 6e 20 73 70 61 63 65 20 66 72   obtain space fr
2da0: 6f 6d 20 74 68 65 20 62 75 66 66 65 72 20 63 6f  om the buffer co
2db0: 6e 66 69 67 75 72 65 64 0a 2a 2a 20 75 73 69 6e  nfigured.** usin
2dc0: 67 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67  g sqlite3_config
2dd0: 28 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50  (SQLITE_CONFIG_P
2de0: 41 47 45 43 41 43 48 45 29 20 6f 70 74 69 6f 6e  AGECACHE) option
2df0: 2e 20 49 66 20 6e 6f 20 73 75 63 68 20 62 75 66  . If no such buf
2e00: 66 65 72 0a 2a 2a 20 65 78 69 73 74 73 2c 20 74  fer.** exists, t
2e10: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 66 61 6c  his function fal
2e20: 6c 73 20 62 61 63 6b 20 74 6f 20 73 71 6c 69 74  ls back to sqlit
2e30: 65 33 4d 61 6c 6c 6f 63 28 29 2e 0a 2a 2f 0a 76  e3Malloc()..*/.v
2e40: 6f 69 64 20 2a 73 71 6c 69 74 65 33 50 61 67 65  oid *sqlite3Page
2e50: 4d 61 6c 6c 6f 63 28 69 6e 74 20 73 7a 29 7b 0a  Malloc(int sz){.
2e60: 20 20 72 65 74 75 72 6e 20 70 63 61 63 68 65 31    return pcache1
2e70: 41 6c 6c 6f 63 28 73 7a 29 3b 0a 7d 0a 0a 2f 2a  Alloc(sz);.}../*
2e80: 0a 2a 2a 20 46 72 65 65 20 61 6e 20 61 6c 6c 6f  .** Free an allo
2e90: 63 61 74 65 64 20 62 75 66 66 65 72 20 6f 62 74  cated buffer obt
2ea0: 61 69 6e 65 64 20 66 72 6f 6d 20 73 71 6c 69 74  ained from sqlit
2eb0: 65 33 50 61 67 65 4d 61 6c 6c 6f 63 28 29 2e 0a  e3PageMalloc()..
2ec0: 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50  */.void sqlite3P
2ed0: 61 67 65 46 72 65 65 28 76 6f 69 64 20 2a 70 29  ageFree(void *p)
2ee0: 7b 0a 20 20 70 63 61 63 68 65 31 46 72 65 65 28  {.  pcache1Free(
2ef0: 70 29 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 52 65  p);.}.../*.** Re
2f00: 74 75 72 6e 20 74 72 75 65 20 69 66 20 69 74 20  turn true if it 
2f10: 64 65 73 69 72 61 62 6c 65 20 74 6f 20 61 76 6f  desirable to avo
2f20: 69 64 20 61 6c 6c 6f 63 61 74 69 6e 67 20 61 20  id allocating a 
2f30: 6e 65 77 20 70 61 67 65 20 63 61 63 68 65 0a 2a  new page cache.*
2f40: 2a 20 65 6e 74 72 79 2e 0a 2a 2a 0a 2a 2a 20 49  * entry..**.** I
2f50: 66 20 6d 65 6d 6f 72 79 20 77 61 73 20 61 6c 6c  f memory was all
2f60: 6f 63 61 74 65 64 20 73 70 65 63 69 66 69 63 61  ocated specifica
2f70: 6c 6c 79 20 74 6f 20 74 68 65 20 70 61 67 65 20  lly to the page 
2f80: 63 61 63 68 65 20 75 73 69 6e 67 0a 2a 2a 20 53  cache using.** S
2f90: 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47  QLITE_CONFIG_PAG
2fa0: 45 43 41 43 48 45 20 62 75 74 20 74 68 61 74 20  ECACHE but that 
2fb0: 6d 65 6d 6f 72 79 20 68 61 73 20 61 6c 6c 20 62  memory has all b
2fc0: 65 65 6e 20 75 73 65 64 2c 20 74 68 65 6e 0a 2a  een used, then.*
2fd0: 2a 20 69 74 20 69 73 20 64 65 73 69 72 61 62 6c  * it is desirabl
2fe0: 65 20 74 6f 20 61 76 6f 69 64 20 61 6c 6c 6f 63  e to avoid alloc
2ff0: 61 74 69 6e 67 20 61 20 6e 65 77 20 70 61 67 65  ating a new page
3000: 20 63 61 63 68 65 20 65 6e 74 72 79 20 62 65 63   cache entry bec
3010: 61 75 73 65 0a 2a 2a 20 70 72 65 73 75 6d 61 62  ause.** presumab
3020: 6c 79 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47  ly SQLITE_CONFIG
3030: 5f 50 41 47 45 43 41 43 48 45 20 77 61 73 20 73  _PAGECACHE was s
3040: 75 70 70 6f 73 65 20 74 6f 20 62 65 20 73 75 66  uppose to be suf
3050: 66 69 63 69 65 6e 74 0a 2a 2a 20 66 6f 72 20 61  ficient.** for a
3060: 6c 6c 20 70 61 67 65 20 63 61 63 68 65 20 6e 65  ll page cache ne
3070: 65 64 73 20 61 6e 64 20 77 65 20 73 68 6f 75 6c  eds and we shoul
3080: 64 20 6e 6f 74 20 6e 65 65 64 20 74 6f 20 73 70  d not need to sp
3090: 69 6c 6c 20 74 68 65 0a 2a 2a 20 61 6c 6c 6f 63  ill the.** alloc
30a0: 61 74 69 6f 6e 20 6f 6e 74 6f 20 74 68 65 20 68  ation onto the h
30b0: 65 61 70 2e 0a 2a 2a 0a 2a 2a 20 4f 72 2c 20 74  eap..**.** Or, t
30c0: 68 65 20 68 65 61 70 20 69 73 20 75 73 65 64 20  he heap is used 
30d0: 66 6f 72 20 61 6c 6c 20 70 61 67 65 20 63 61 63  for all page cac
30e0: 68 65 20 6d 65 6d 6f 72 79 20 70 75 74 20 74 68  he memory put th
30f0: 65 20 68 65 61 70 20 69 73 0a 2a 2a 20 75 6e 64  e heap is.** und
3100: 65 72 20 6d 65 6d 6f 72 79 20 70 72 65 73 73 75  er memory pressu
3110: 72 65 2c 20 74 68 65 6e 20 61 67 61 69 6e 20 69  re, then again i
3120: 74 20 69 73 20 64 65 73 69 72 61 62 6c 65 20 74  t is desirable t
3130: 6f 20 61 76 6f 69 64 0a 2a 2a 20 61 6c 6c 6f 63  o avoid.** alloc
3140: 61 74 69 6e 67 20 61 20 6e 65 77 20 70 61 67 65  ating a new page
3150: 20 63 61 63 68 65 20 65 6e 74 72 79 20 69 6e 20   cache entry in 
3160: 6f 72 64 65 72 20 74 6f 20 61 76 6f 69 64 20 73  order to avoid s
3170: 74 72 65 73 73 69 6e 67 0a 2a 2a 20 74 68 65 20  tressing.** the 
3180: 68 65 61 70 20 65 76 65 6e 20 66 75 72 74 68 65  heap even furthe
3190: 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  r..*/.static int
31a0: 20 70 63 61 63 68 65 31 55 6e 64 65 72 4d 65 6d   pcache1UnderMem
31b0: 6f 72 79 50 72 65 73 73 75 72 65 28 50 43 61 63  oryPressure(PCac
31c0: 68 65 31 20 2a 70 43 61 63 68 65 29 7b 0a 20 20  he1 *pCache){.  
31d0: 69 66 28 20 70 63 61 63 68 65 31 2e 6e 53 6c 6f  if( pcache1.nSlo
31e0: 74 20 26 26 20 70 43 61 63 68 65 2d 3e 73 7a 50  t && pCache->szP
31f0: 61 67 65 3c 3d 70 63 61 63 68 65 31 2e 73 7a 53  age<=pcache1.szS
3200: 6c 6f 74 20 29 7b 0a 20 20 20 20 72 65 74 75 72  lot ){.    retur
3210: 6e 20 70 63 61 63 68 65 31 2e 62 55 6e 64 65 72  n pcache1.bUnder
3220: 50 72 65 73 73 75 72 65 3b 0a 20 20 7d 65 6c 73  Pressure;.  }els
3230: 65 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 73 71  e{.    return sq
3240: 6c 69 74 65 33 48 65 61 70 4e 65 61 72 6c 79 46  lite3HeapNearlyF
3250: 75 6c 6c 28 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a  ull();.  }.}../*
3260: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3270: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3280: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3290: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
32a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f  *************/./
32b0: 2a 2a 2a 2a 2a 2a 2a 2a 20 47 65 6e 65 72 61 6c  ******** General
32c0: 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20   Implementation 
32d0: 46 75 6e 63 74 69 6f 6e 73 20 2a 2a 2a 2a 2a 2a  Functions ******
32e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
32f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a  **************/.
3300: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  ./*.** This func
3310: 74 69 6f 6e 20 69 73 20 75 73 65 64 20 74 6f 20  tion is used to 
3320: 72 65 73 69 7a 65 20 74 68 65 20 68 61 73 68 20  resize the hash 
3330: 74 61 62 6c 65 20 75 73 65 64 20 62 79 20 74 68  table used by th
3340: 65 20 63 61 63 68 65 20 70 61 73 73 65 64 0a 2a  e cache passed.*
3350: 2a 20 61 73 20 74 68 65 20 66 69 72 73 74 20 61  * as the first a
3360: 72 67 75 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 54  rgument..**.** T
3370: 68 65 20 50 43 61 63 68 65 20 6d 75 74 65 78 20  he PCache mutex 
3380: 6d 75 73 74 20 62 65 20 68 65 6c 64 20 77 68 65  must be held whe
3390: 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  n this function 
33a0: 69 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f 0a 73 74  is called..*/.st
33b0: 61 74 69 63 20 69 6e 74 20 70 63 61 63 68 65 31  atic int pcache1
33c0: 52 65 73 69 7a 65 48 61 73 68 28 50 43 61 63 68  ResizeHash(PCach
33d0: 65 31 20 2a 70 29 7b 0a 20 20 50 67 48 64 72 31  e1 *p){.  PgHdr1
33e0: 20 2a 2a 61 70 4e 65 77 3b 0a 20 20 75 6e 73 69   **apNew;.  unsi
33f0: 67 6e 65 64 20 69 6e 74 20 6e 4e 65 77 3b 0a 20  gned int nNew;. 
3400: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 3b   unsigned int i;
3410: 0a 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c 69  ..  assert( sqli
3420: 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70  te3_mutex_held(p
3430: 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78 29  ->pGroup->mutex)
3440: 20 29 3b 0a 0a 20 20 6e 4e 65 77 20 3d 20 70 2d   );..  nNew = p-
3450: 3e 6e 48 61 73 68 2a 32 3b 0a 20 20 69 66 28 20  >nHash*2;.  if( 
3460: 6e 4e 65 77 3c 32 35 36 20 29 7b 0a 20 20 20 20  nNew<256 ){.    
3470: 6e 4e 65 77 20 3d 20 32 35 36 3b 0a 20 20 7d 0a  nNew = 256;.  }.
3480: 0a 20 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d  .  pcache1LeaveM
3490: 75 74 65 78 28 70 2d 3e 70 47 72 6f 75 70 29 3b  utex(p->pGroup);
34a0: 0a 20 20 69 66 28 20 70 2d 3e 6e 48 61 73 68 20  .  if( p->nHash 
34b0: 29 7b 20 73 71 6c 69 74 65 33 42 65 67 69 6e 42  ){ sqlite3BeginB
34c0: 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 20 7d  enignMalloc(); }
34d0: 0a 20 20 61 70 4e 65 77 20 3d 20 28 50 67 48 64  .  apNew = (PgHd
34e0: 72 31 20 2a 2a 29 73 71 6c 69 74 65 33 5f 6d 61  r1 **)sqlite3_ma
34f0: 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 50 67 48 64  lloc(sizeof(PgHd
3500: 72 31 20 2a 29 2a 6e 4e 65 77 29 3b 0a 20 20 69  r1 *)*nNew);.  i
3510: 66 28 20 70 2d 3e 6e 48 61 73 68 20 29 7b 20 73  f( p->nHash ){ s
3520: 71 6c 69 74 65 33 45 6e 64 42 65 6e 69 67 6e 4d  qlite3EndBenignM
3530: 61 6c 6c 6f 63 28 29 3b 20 7d 0a 20 20 70 63 61  alloc(); }.  pca
3540: 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70  che1EnterMutex(p
3550: 2d 3e 70 47 72 6f 75 70 29 3b 0a 20 20 69 66 28  ->pGroup);.  if(
3560: 20 61 70 4e 65 77 20 29 7b 0a 20 20 20 20 6d 65   apNew ){.    me
3570: 6d 73 65 74 28 61 70 4e 65 77 2c 20 30 2c 20 73  mset(apNew, 0, s
3580: 69 7a 65 6f 66 28 50 67 48 64 72 31 20 2a 29 2a  izeof(PgHdr1 *)*
3590: 6e 4e 65 77 29 3b 0a 20 20 20 20 66 6f 72 28 69  nNew);.    for(i
35a0: 3d 30 3b 20 69 3c 70 2d 3e 6e 48 61 73 68 3b 20  =0; i<p->nHash; 
35b0: 69 2b 2b 29 7b 0a 20 20 20 20 20 20 50 67 48 64  i++){.      PgHd
35c0: 72 31 20 2a 70 50 61 67 65 3b 0a 20 20 20 20 20  r1 *pPage;.     
35d0: 20 50 67 48 64 72 31 20 2a 70 4e 65 78 74 20 3d   PgHdr1 *pNext =
35e0: 20 70 2d 3e 61 70 48 61 73 68 5b 69 5d 3b 0a 20   p->apHash[i];. 
35f0: 20 20 20 20 20 77 68 69 6c 65 28 20 28 70 50 61       while( (pPa
3600: 67 65 20 3d 20 70 4e 65 78 74 29 21 3d 30 20 29  ge = pNext)!=0 )
3610: 7b 0a 20 20 20 20 20 20 20 20 75 6e 73 69 67 6e  {.        unsign
3620: 65 64 20 69 6e 74 20 68 20 3d 20 70 50 61 67 65  ed int h = pPage
3630: 2d 3e 69 4b 65 79 20 25 20 6e 4e 65 77 3b 0a 20  ->iKey % nNew;. 
3640: 20 20 20 20 20 20 20 70 4e 65 78 74 20 3d 20 70         pNext = p
3650: 50 61 67 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20  Page->pNext;.   
3660: 20 20 20 20 20 70 50 61 67 65 2d 3e 70 4e 65 78       pPage->pNex
3670: 74 20 3d 20 61 70 4e 65 77 5b 68 5d 3b 0a 20 20  t = apNew[h];.  
3680: 20 20 20 20 20 20 61 70 4e 65 77 5b 68 5d 20 3d        apNew[h] =
3690: 20 70 50 61 67 65 3b 0a 20 20 20 20 20 20 7d 0a   pPage;.      }.
36a0: 20 20 20 20 7d 0a 20 20 20 20 73 71 6c 69 74 65      }.    sqlite
36b0: 33 5f 66 72 65 65 28 70 2d 3e 61 70 48 61 73 68  3_free(p->apHash
36c0: 29 3b 0a 20 20 20 20 70 2d 3e 61 70 48 61 73 68  );.    p->apHash
36d0: 20 3d 20 61 70 4e 65 77 3b 0a 20 20 20 20 70 2d   = apNew;.    p-
36e0: 3e 6e 48 61 73 68 20 3d 20 6e 4e 65 77 3b 0a 20  >nHash = nNew;. 
36f0: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 28 70 2d   }..  return (p-
3700: 3e 61 70 48 61 73 68 20 3f 20 53 51 4c 49 54 45  >apHash ? SQLITE
3710: 5f 4f 4b 20 3a 20 53 51 4c 49 54 45 5f 4e 4f 4d  _OK : SQLITE_NOM
3720: 45 4d 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68  EM);.}../*.** Th
3730: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 75  is function is u
3740: 73 65 64 20 69 6e 74 65 72 6e 61 6c 6c 79 20 74  sed internally t
3750: 6f 20 72 65 6d 6f 76 65 20 74 68 65 20 70 61 67  o remove the pag
3760: 65 20 70 50 61 67 65 20 66 72 6f 6d 20 74 68 65  e pPage from the
3770: 20 0a 2a 2a 20 50 47 72 6f 75 70 20 4c 52 55 20   .** PGroup LRU 
3780: 6c 69 73 74 2c 20 69 66 20 69 73 20 70 61 72 74  list, if is part
3790: 20 6f 66 20 69 74 2e 20 49 66 20 70 50 61 67 65   of it. If pPage
37a0: 20 69 73 20 6e 6f 74 20 70 61 72 74 20 6f 66 20   is not part of 
37b0: 74 68 65 20 50 47 72 6f 75 70 0a 2a 2a 20 4c 52  the PGroup.** LR
37c0: 55 20 6c 69 73 74 2c 20 74 68 65 6e 20 74 68 69  U list, then thi
37d0: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 61 20  s function is a 
37e0: 6e 6f 2d 6f 70 2e 0a 2a 2a 0a 2a 2a 20 54 68 65  no-op..**.** The
37f0: 20 50 47 72 6f 75 70 20 6d 75 74 65 78 20 6d 75   PGroup mutex mu
3800: 73 74 20 62 65 20 68 65 6c 64 20 77 68 65 6e 20  st be held when 
3810: 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73  this function is
3820: 20 63 61 6c 6c 65 64 2e 0a 2a 2a 0a 2a 2a 20 49   called..**.** I
3830: 66 20 70 50 61 67 65 20 69 73 20 4e 55 4c 4c 20  f pPage is NULL 
3840: 74 68 65 6e 20 74 68 69 73 20 72 6f 75 74 69 6e  then this routin
3850: 65 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a 2a 2f  e is a no-op..*/
3860: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61  .static void pca
3870: 63 68 65 31 50 69 6e 50 61 67 65 28 50 67 48 64  che1PinPage(PgHd
3880: 72 31 20 2a 70 50 61 67 65 29 7b 0a 20 20 50 43  r1 *pPage){.  PC
3890: 61 63 68 65 31 20 2a 70 43 61 63 68 65 3b 0a 20  ache1 *pCache;. 
38a0: 20 50 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 3b   PGroup *pGroup;
38b0: 0a 0a 20 20 69 66 28 20 70 50 61 67 65 3d 3d 30  ..  if( pPage==0
38c0: 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 70 43 61   ) return;.  pCa
38d0: 63 68 65 20 3d 20 70 50 61 67 65 2d 3e 70 43 61  che = pPage->pCa
38e0: 63 68 65 3b 0a 20 20 70 47 72 6f 75 70 20 3d 20  che;.  pGroup = 
38f0: 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b 0a  pCache->pGroup;.
3900: 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65    assert( sqlite
3910: 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 47 72  3_mutex_held(pGr
3920: 6f 75 70 2d 3e 6d 75 74 65 78 29 20 29 3b 0a 20  oup->mutex) );. 
3930: 20 69 66 28 20 70 50 61 67 65 2d 3e 70 4c 72 75   if( pPage->pLru
3940: 4e 65 78 74 20 7c 7c 20 70 50 61 67 65 3d 3d 70  Next || pPage==p
3950: 47 72 6f 75 70 2d 3e 70 4c 72 75 54 61 69 6c 20  Group->pLruTail 
3960: 29 7b 0a 20 20 20 20 69 66 28 20 70 50 61 67 65  ){.    if( pPage
3970: 2d 3e 70 4c 72 75 50 72 65 76 20 29 7b 0a 20 20  ->pLruPrev ){.  
3980: 20 20 20 20 70 50 61 67 65 2d 3e 70 4c 72 75 50      pPage->pLruP
3990: 72 65 76 2d 3e 70 4c 72 75 4e 65 78 74 20 3d 20  rev->pLruNext = 
39a0: 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 3b  pPage->pLruNext;
39b0: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70  .    }.    if( p
39c0: 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 20 29  Page->pLruNext )
39d0: 7b 0a 20 20 20 20 20 20 70 50 61 67 65 2d 3e 70  {.      pPage->p
39e0: 4c 72 75 4e 65 78 74 2d 3e 70 4c 72 75 50 72 65  LruNext->pLruPre
39f0: 76 20 3d 20 70 50 61 67 65 2d 3e 70 4c 72 75 50  v = pPage->pLruP
3a00: 72 65 76 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69  rev;.    }.    i
3a10: 66 28 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 48  f( pGroup->pLruH
3a20: 65 61 64 3d 3d 70 50 61 67 65 20 29 7b 0a 20 20  ead==pPage ){.  
3a30: 20 20 20 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75      pGroup->pLru
3a40: 48 65 61 64 20 3d 20 70 50 61 67 65 2d 3e 70 4c  Head = pPage->pL
3a50: 72 75 4e 65 78 74 3b 0a 20 20 20 20 7d 0a 20 20  ruNext;.    }.  
3a60: 20 20 69 66 28 20 70 47 72 6f 75 70 2d 3e 70 4c    if( pGroup->pL
3a70: 72 75 54 61 69 6c 3d 3d 70 50 61 67 65 20 29 7b  ruTail==pPage ){
3a80: 0a 20 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 70  .      pGroup->p
3a90: 4c 72 75 54 61 69 6c 20 3d 20 70 50 61 67 65 2d  LruTail = pPage-
3aa0: 3e 70 4c 72 75 50 72 65 76 3b 0a 20 20 20 20 7d  >pLruPrev;.    }
3ab0: 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 4c 72 75  .    pPage->pLru
3ac0: 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20 20 70 50  Next = 0;.    pP
3ad0: 61 67 65 2d 3e 70 4c 72 75 50 72 65 76 20 3d 20  age->pLruPrev = 
3ae0: 30 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 43  0;.    pPage->pC
3af0: 61 63 68 65 2d 3e 6e 52 65 63 79 63 6c 61 62 6c  ache->nRecyclabl
3b00: 65 2d 2d 3b 0a 20 20 7d 0a 7d 0a 0a 0a 2f 2a 0a  e--;.  }.}.../*.
3b10: 2a 2a 20 52 65 6d 6f 76 65 20 74 68 65 20 70 61  ** Remove the pa
3b20: 67 65 20 73 75 70 70 6c 69 65 64 20 61 73 20 61  ge supplied as a
3b30: 6e 20 61 72 67 75 6d 65 6e 74 20 66 72 6f 6d 20  n argument from 
3b40: 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 20 0a  the hash table .
3b50: 2a 2a 20 28 50 43 61 63 68 65 31 2e 61 70 48 61  ** (PCache1.apHa
3b60: 73 68 20 73 74 72 75 63 74 75 72 65 29 20 74 68  sh structure) th
3b70: 61 74 20 69 74 20 69 73 20 63 75 72 72 65 6e 74  at it is current
3b80: 6c 79 20 73 74 6f 72 65 64 20 69 6e 2e 0a 2a 2a  ly stored in..**
3b90: 0a 2a 2a 20 54 68 65 20 50 47 72 6f 75 70 20 6d  .** The PGroup m
3ba0: 75 74 65 78 20 6d 75 73 74 20 62 65 20 68 65 6c  utex must be hel
3bb0: 64 20 77 68 65 6e 20 74 68 69 73 20 66 75 6e 63  d when this func
3bc0: 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 2e 0a  tion is called..
3bd0: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70  */.static void p
3be0: 63 61 63 68 65 31 52 65 6d 6f 76 65 46 72 6f 6d  cache1RemoveFrom
3bf0: 48 61 73 68 28 50 67 48 64 72 31 20 2a 70 50 61  Hash(PgHdr1 *pPa
3c00: 67 65 29 7b 0a 20 20 75 6e 73 69 67 6e 65 64 20  ge){.  unsigned 
3c10: 69 6e 74 20 68 3b 0a 20 20 50 43 61 63 68 65 31  int h;.  PCache1
3c20: 20 2a 70 43 61 63 68 65 20 3d 20 70 50 61 67 65   *pCache = pPage
3c30: 2d 3e 70 43 61 63 68 65 3b 0a 20 20 50 67 48 64  ->pCache;.  PgHd
3c40: 72 31 20 2a 2a 70 70 3b 0a 0a 20 20 61 73 73 65  r1 **pp;..  asse
3c50: 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65  rt( sqlite3_mute
3c60: 78 5f 68 65 6c 64 28 70 43 61 63 68 65 2d 3e 70  x_held(pCache->p
3c70: 47 72 6f 75 70 2d 3e 6d 75 74 65 78 29 20 29 3b  Group->mutex) );
3c80: 0a 20 20 68 20 3d 20 70 50 61 67 65 2d 3e 69 4b  .  h = pPage->iK
3c90: 65 79 20 25 20 70 43 61 63 68 65 2d 3e 6e 48 61  ey % pCache->nHa
3ca0: 73 68 3b 0a 20 20 66 6f 72 28 70 70 3d 26 70 43  sh;.  for(pp=&pC
3cb0: 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b  ache->apHash[h];
3cc0: 20 28 2a 70 70 29 21 3d 70 50 61 67 65 3b 20 70   (*pp)!=pPage; p
3cd0: 70 3d 26 28 2a 70 70 29 2d 3e 70 4e 65 78 74 29  p=&(*pp)->pNext)
3ce0: 3b 0a 20 20 2a 70 70 20 3d 20 28 2a 70 70 29 2d  ;.  *pp = (*pp)-
3cf0: 3e 70 4e 65 78 74 3b 0a 0a 20 20 70 43 61 63 68  >pNext;..  pCach
3d00: 65 2d 3e 6e 50 61 67 65 2d 2d 3b 0a 7d 0a 0a 2f  e->nPage--;.}../
3d10: 2a 0a 2a 2a 20 49 66 20 74 68 65 72 65 20 61 72  *.** If there ar
3d20: 65 20 63 75 72 72 65 6e 74 6c 79 20 6d 6f 72 65  e currently more
3d30: 20 74 68 61 6e 20 6e 4d 61 78 50 61 67 65 20 70   than nMaxPage p
3d40: 61 67 65 73 20 61 6c 6c 6f 63 61 74 65 64 2c 20  ages allocated, 
3d50: 74 72 79 0a 2a 2a 20 74 6f 20 72 65 63 79 63 6c  try.** to recycl
3d60: 65 20 70 61 67 65 73 20 74 6f 20 72 65 64 75 63  e pages to reduc
3d70: 65 20 74 68 65 20 6e 75 6d 62 65 72 20 61 6c 6c  e the number all
3d80: 6f 63 61 74 65 64 20 74 6f 20 6e 4d 61 78 50 61  ocated to nMaxPa
3d90: 67 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ge..*/.static vo
3da0: 69 64 20 70 63 61 63 68 65 31 45 6e 66 6f 72 63  id pcache1Enforc
3db0: 65 4d 61 78 50 61 67 65 28 50 47 72 6f 75 70 20  eMaxPage(PGroup 
3dc0: 2a 70 47 72 6f 75 70 29 7b 0a 20 20 61 73 73 65  *pGroup){.  asse
3dd0: 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65  rt( sqlite3_mute
3de0: 78 5f 68 65 6c 64 28 70 47 72 6f 75 70 2d 3e 6d  x_held(pGroup->m
3df0: 75 74 65 78 29 20 29 3b 0a 20 20 77 68 69 6c 65  utex) );.  while
3e00: 28 20 70 47 72 6f 75 70 2d 3e 6e 43 75 72 72 65  ( pGroup->nCurre
3e10: 6e 74 50 61 67 65 3e 70 47 72 6f 75 70 2d 3e 6e  ntPage>pGroup->n
3e20: 4d 61 78 50 61 67 65 20 26 26 20 70 47 72 6f 75  MaxPage && pGrou
3e30: 70 2d 3e 70 4c 72 75 54 61 69 6c 20 29 7b 0a 20  p->pLruTail ){. 
3e40: 20 20 20 50 67 48 64 72 31 20 2a 70 20 3d 20 70     PgHdr1 *p = p
3e50: 47 72 6f 75 70 2d 3e 70 4c 72 75 54 61 69 6c 3b  Group->pLruTail;
3e60: 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e  .    assert( p->
3e70: 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3d 3d  pCache->pGroup==
3e80: 70 47 72 6f 75 70 20 29 3b 0a 20 20 20 20 70 63  pGroup );.    pc
3e90: 61 63 68 65 31 50 69 6e 50 61 67 65 28 70 29 3b  ache1PinPage(p);
3ea0: 0a 20 20 20 20 70 63 61 63 68 65 31 52 65 6d 6f  .    pcache1Remo
3eb0: 76 65 46 72 6f 6d 48 61 73 68 28 70 29 3b 0a 20  veFromHash(p);. 
3ec0: 20 20 20 70 63 61 63 68 65 31 46 72 65 65 50 61     pcache1FreePa
3ed0: 67 65 28 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a  ge(p);.  }.}../*
3ee0: 0a 2a 2a 20 44 69 73 63 61 72 64 20 61 6c 6c 20  .** Discard all 
3ef0: 70 61 67 65 73 20 66 72 6f 6d 20 63 61 63 68 65  pages from cache
3f00: 20 70 43 61 63 68 65 20 77 69 74 68 20 61 20 70   pCache with a p
3f10: 61 67 65 20 6e 75 6d 62 65 72 20 28 6b 65 79 20  age number (key 
3f20: 76 61 6c 75 65 29 20 0a 2a 2a 20 67 72 65 61 74  value) .** great
3f30: 65 72 20 74 68 61 6e 20 6f 72 20 65 71 75 61 6c  er than or equal
3f40: 20 74 6f 20 69 4c 69 6d 69 74 2e 20 41 6e 79 20   to iLimit. Any 
3f50: 70 69 6e 6e 65 64 20 70 61 67 65 73 20 74 68 61  pinned pages tha
3f60: 74 20 6d 65 65 74 20 74 68 69 73 20 0a 2a 2a 20  t meet this .** 
3f70: 63 72 69 74 65 72 69 61 20 61 72 65 20 75 6e 70  criteria are unp
3f80: 69 6e 6e 65 64 20 62 65 66 6f 72 65 20 74 68 65  inned before the
3f90: 79 20 61 72 65 20 64 69 73 63 61 72 64 65 64 2e  y are discarded.
3fa0: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 50 43 61 63 68  .**.** The PCach
3fb0: 65 20 6d 75 74 65 78 20 6d 75 73 74 20 62 65 20  e mutex must be 
3fc0: 68 65 6c 64 20 77 68 65 6e 20 74 68 69 73 20 66  held when this f
3fd0: 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65  unction is calle
3fe0: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  d..*/.static voi
3ff0: 64 20 70 63 61 63 68 65 31 54 72 75 6e 63 61 74  d pcache1Truncat
4000: 65 55 6e 73 61 66 65 28 0a 20 20 50 43 61 63 68  eUnsafe(.  PCach
4010: 65 31 20 2a 70 43 61 63 68 65 2c 20 20 20 20 20  e1 *pCache,     
4020: 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 63          /* The c
4030: 61 63 68 65 20 74 6f 20 74 72 75 6e 63 61 74 65  ache to truncate
4040: 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69   */.  unsigned i
4050: 6e 74 20 69 4c 69 6d 69 74 20 20 20 20 20 20 20  nt iLimit       
4060: 20 20 20 2f 2a 20 44 72 6f 70 20 70 61 67 65 73     /* Drop pages
4070: 20 77 69 74 68 20 74 68 69 73 20 70 67 6e 6f 20   with this pgno 
4080: 6f 72 20 6c 61 72 67 65 72 20 2a 2f 0a 29 7b 0a  or larger */.){.
4090: 20 20 54 45 53 54 4f 4e 4c 59 28 20 75 6e 73 69    TESTONLY( unsi
40a0: 67 6e 65 64 20 69 6e 74 20 6e 50 61 67 65 20 3d  gned int nPage =
40b0: 20 30 3b 20 29 20 20 2f 2a 20 54 6f 20 61 73 73   0; )  /* To ass
40c0: 65 72 74 20 70 43 61 63 68 65 2d 3e 6e 50 61 67  ert pCache->nPag
40d0: 65 20 69 73 20 63 6f 72 72 65 63 74 20 2a 2f 0a  e is correct */.
40e0: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68    unsigned int h
40f0: 3b 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c 69  ;.  assert( sqli
4100: 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70  te3_mutex_held(p
4110: 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 2d 3e 6d  Cache->pGroup->m
4120: 75 74 65 78 29 20 29 3b 0a 20 20 66 6f 72 28 68  utex) );.  for(h
4130: 3d 30 3b 20 68 3c 70 43 61 63 68 65 2d 3e 6e 48  =0; h<pCache->nH
4140: 61 73 68 3b 20 68 2b 2b 29 7b 0a 20 20 20 20 50  ash; h++){.    P
4150: 67 48 64 72 31 20 2a 2a 70 70 20 3d 20 26 70 43  gHdr1 **pp = &pC
4160: 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b  ache->apHash[h];
4170: 20 0a 20 20 20 20 50 67 48 64 72 31 20 2a 70 50   .    PgHdr1 *pP
4180: 61 67 65 3b 0a 20 20 20 20 77 68 69 6c 65 28 20  age;.    while( 
4190: 28 70 50 61 67 65 20 3d 20 2a 70 70 29 21 3d 30  (pPage = *pp)!=0
41a0: 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 70 50   ){.      if( pP
41b0: 61 67 65 2d 3e 69 4b 65 79 3e 3d 69 4c 69 6d 69  age->iKey>=iLimi
41c0: 74 20 29 7b 0a 20 20 20 20 20 20 20 20 70 43 61  t ){.        pCa
41d0: 63 68 65 2d 3e 6e 50 61 67 65 2d 2d 3b 0a 20 20  che->nPage--;.  
41e0: 20 20 20 20 20 20 2a 70 70 20 3d 20 70 50 61 67        *pp = pPag
41f0: 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20  e->pNext;.      
4200: 20 20 70 63 61 63 68 65 31 50 69 6e 50 61 67 65    pcache1PinPage
4210: 28 70 50 61 67 65 29 3b 0a 20 20 20 20 20 20 20  (pPage);.       
4220: 20 70 63 61 63 68 65 31 46 72 65 65 50 61 67 65   pcache1FreePage
4230: 28 70 50 61 67 65 29 3b 0a 20 20 20 20 20 20 7d  (pPage);.      }
4240: 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 70 70  else{.        pp
4250: 20 3d 20 26 70 50 61 67 65 2d 3e 70 4e 65 78 74   = &pPage->pNext
4260: 3b 0a 20 20 20 20 20 20 20 20 54 45 53 54 4f 4e  ;.        TESTON
4270: 4c 59 28 20 6e 50 61 67 65 2b 2b 3b 20 29 0a 20  LY( nPage++; ). 
4280: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d       }.    }.  }
4290: 0a 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68  .  assert( pCach
42a0: 65 2d 3e 6e 50 61 67 65 3d 3d 6e 50 61 67 65 20  e->nPage==nPage 
42b0: 29 3b 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a  );.}../*********
42c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
42d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
42e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
42f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4300: 2a 2a 2a 2a 2a 2f 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a  *****/./********
4310: 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20   sqlite3_pcache 
4320: 4d 65 74 68 6f 64 73 20 2a 2a 2a 2a 2a 2a 2a 2a  Methods ********
4330: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4340: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4350: 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 49  ******/../*.** I
4360: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66  mplementation of
4370: 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61   the sqlite3_pca
4380: 63 68 65 2e 78 49 6e 69 74 20 6d 65 74 68 6f 64  che.xInit method
4390: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
43a0: 70 63 61 63 68 65 31 49 6e 69 74 28 76 6f 69 64  pcache1Init(void
43b0: 20 2a 4e 6f 74 55 73 65 64 29 7b 0a 20 20 55 4e   *NotUsed){.  UN
43c0: 55 53 45 44 5f 50 41 52 41 4d 45 54 45 52 28 4e  USED_PARAMETER(N
43d0: 6f 74 55 73 65 64 29 3b 0a 20 20 61 73 73 65 72  otUsed);.  asser
43e0: 74 28 20 70 63 61 63 68 65 31 2e 69 73 49 6e 69  t( pcache1.isIni
43f0: 74 3d 3d 30 20 29 3b 0a 20 20 6d 65 6d 73 65 74  t==0 );.  memset
4400: 28 26 70 63 61 63 68 65 31 2c 20 30 2c 20 73 69  (&pcache1, 0, si
4410: 7a 65 6f 66 28 70 63 61 63 68 65 31 29 29 3b 0a  zeof(pcache1));.
4420: 20 20 69 66 28 20 73 71 6c 69 74 65 33 47 6c 6f    if( sqlite3Glo
4430: 62 61 6c 43 6f 6e 66 69 67 2e 62 43 6f 72 65 4d  balConfig.bCoreM
4440: 75 74 65 78 20 29 7b 0a 20 20 20 20 70 63 61 63  utex ){.    pcac
4450: 68 65 31 2e 67 72 70 2e 6d 75 74 65 78 20 3d 20  he1.grp.mutex = 
4460: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 61 6c  sqlite3_mutex_al
4470: 6c 6f 63 28 53 51 4c 49 54 45 5f 4d 55 54 45 58  loc(SQLITE_MUTEX
4480: 5f 53 54 41 54 49 43 5f 4c 52 55 29 3b 0a 20 20  _STATIC_LRU);.  
4490: 20 20 70 63 61 63 68 65 31 2e 6d 75 74 65 78 20    pcache1.mutex 
44a0: 3d 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f  = sqlite3_mutex_
44b0: 61 6c 6c 6f 63 28 53 51 4c 49 54 45 5f 4d 55 54  alloc(SQLITE_MUT
44c0: 45 58 5f 53 54 41 54 49 43 5f 50 4d 45 4d 29 3b  EX_STATIC_PMEM);
44d0: 0a 20 20 7d 0a 20 20 70 63 61 63 68 65 31 2e 69  .  }.  pcache1.i
44e0: 73 49 6e 69 74 20 3d 20 31 3b 0a 20 20 72 65 74  sInit = 1;.  ret
44f0: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
4500: 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e  ../*.** Implemen
4510: 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71  tation of the sq
4520: 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78 53 68  lite3_pcache.xSh
4530: 75 74 64 6f 77 6e 20 6d 65 74 68 6f 64 2e 0a 2a  utdown method..*
4540: 2a 20 4e 6f 74 65 20 74 68 61 74 20 74 68 65 20  * Note that the 
4550: 73 74 61 74 69 63 20 6d 75 74 65 78 20 61 6c 6c  static mutex all
4560: 6f 63 61 74 65 64 20 69 6e 20 78 49 6e 69 74 20  ocated in xInit 
4570: 64 6f 65 73 20 0a 2a 2a 20 6e 6f 74 20 6e 65 65  does .** not nee
4580: 64 20 74 6f 20 62 65 20 66 72 65 65 64 2e 0a 2a  d to be freed..*
4590: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63  /.static void pc
45a0: 61 63 68 65 31 53 68 75 74 64 6f 77 6e 28 76 6f  ache1Shutdown(vo
45b0: 69 64 20 2a 4e 6f 74 55 73 65 64 29 7b 0a 20 20  id *NotUsed){.  
45c0: 55 4e 55 53 45 44 5f 50 41 52 41 4d 45 54 45 52  UNUSED_PARAMETER
45d0: 28 4e 6f 74 55 73 65 64 29 3b 0a 20 20 61 73 73  (NotUsed);.  ass
45e0: 65 72 74 28 20 70 63 61 63 68 65 31 2e 69 73 49  ert( pcache1.isI
45f0: 6e 69 74 21 3d 30 20 29 3b 0a 20 20 6d 65 6d 73  nit!=0 );.  mems
4600: 65 74 28 26 70 63 61 63 68 65 31 2c 20 30 2c 20  et(&pcache1, 0, 
4610: 73 69 7a 65 6f 66 28 70 63 61 63 68 65 31 29 29  sizeof(pcache1))
4620: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65  ;.}../*.** Imple
4630: 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65  mentation of the
4640: 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e   sqlite3_pcache.
4650: 78 43 72 65 61 74 65 20 6d 65 74 68 6f 64 2e 0a  xCreate method..
4660: 2a 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65 20 61  **.** Allocate a
4670: 20 6e 65 77 20 63 61 63 68 65 2e 0a 2a 2f 0a 73   new cache..*/.s
4680: 74 61 74 69 63 20 73 71 6c 69 74 65 33 5f 70 63  tatic sqlite3_pc
4690: 61 63 68 65 20 2a 70 63 61 63 68 65 31 43 72 65  ache *pcache1Cre
46a0: 61 74 65 28 69 6e 74 20 73 7a 50 61 67 65 2c 20  ate(int szPage, 
46b0: 69 6e 74 20 62 50 75 72 67 65 61 62 6c 65 29 7b  int bPurgeable){
46c0: 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63  .  PCache1 *pCac
46d0: 68 65 3b 20 20 20 20 20 20 2f 2a 20 54 68 65 20  he;      /* The 
46e0: 6e 65 77 6c 79 20 63 72 65 61 74 65 64 20 70 61  newly created pa
46f0: 67 65 20 63 61 63 68 65 20 2a 2f 0a 20 20 50 47  ge cache */.  PG
4700: 72 6f 75 70 20 2a 70 47 72 6f 75 70 3b 20 20 20  roup *pGroup;   
4710: 20 20 20 20 2f 2a 20 54 68 65 20 67 72 6f 75 70      /* The group
4720: 20 74 68 65 20 6e 65 77 20 70 61 67 65 20 63 61   the new page ca
4730: 63 68 65 20 77 69 6c 6c 20 62 65 6c 6f 6e 67 20  che will belong 
4740: 74 6f 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 3b 20  to */.  int sz; 
4750: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
4760: 20 42 79 74 65 73 20 6f 66 20 6d 65 6d 6f 72 79   Bytes of memory
4770: 20 72 65 71 75 69 72 65 64 20 74 6f 20 61 6c 6c   required to all
4780: 6f 63 61 74 65 20 74 68 65 20 6e 65 77 20 63 61  ocate the new ca
4790: 63 68 65 20 2a 2f 0a 0a 20 20 2f 2a 0a 20 20 2a  che */..  /*.  *
47a0: 2a 20 54 68 65 20 73 65 70 65 72 61 74 65 43 61  * The seperateCa
47b0: 63 68 65 20 76 61 72 69 61 62 6c 65 20 69 73 20  che variable is 
47c0: 74 72 75 65 20 69 66 20 65 61 63 68 20 50 43 61  true if each PCa
47d0: 63 68 65 20 68 61 73 20 69 74 73 20 6f 77 6e 20  che has its own 
47e0: 70 72 69 76 61 74 65 0a 20 20 2a 2a 20 50 47 72  private.  ** PGr
47f0: 6f 75 70 2e 20 20 49 6e 20 6f 74 68 65 72 20 77  oup.  In other w
4800: 6f 72 64 73 2c 20 73 65 70 61 72 61 74 65 43 61  ords, separateCa
4810: 63 68 65 20 69 73 20 74 72 75 65 20 66 6f 72 20  che is true for 
4820: 6d 6f 64 65 20 28 31 29 20 77 68 65 72 65 20 6e  mode (1) where n
4830: 6f 0a 20 20 2a 2a 20 6d 75 74 65 78 69 6e 67 20  o.  ** mutexing 
4840: 69 73 20 72 65 71 75 69 72 65 64 2e 0a 20 20 2a  is required..  *
4850: 2a 0a 20 20 2a 2a 20 20 20 2a 20 20 41 6c 77 61  *.  **   *  Alwa
4860: 79 73 20 75 73 65 20 61 20 75 6e 69 66 69 65 64  ys use a unified
4870: 20 63 61 63 68 65 20 28 6d 6f 64 65 2d 32 29 20   cache (mode-2) 
4880: 69 66 20 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59  if ENABLE_MEMORY
4890: 5f 4d 41 4e 41 47 45 4d 45 4e 54 0a 20 20 2a 2a  _MANAGEMENT.  **
48a0: 0a 20 20 2a 2a 20 20 20 2a 20 20 41 6c 77 61 79  .  **   *  Alway
48b0: 73 20 75 73 65 20 61 20 75 6e 69 66 69 65 64 20  s use a unified 
48c0: 63 61 63 68 65 20 69 6e 20 73 69 6e 67 6c 65 2d  cache in single-
48d0: 74 68 72 65 61 64 65 64 20 61 70 70 6c 69 63 61  threaded applica
48e0: 74 69 6f 6e 73 0a 20 20 2a 2a 0a 20 20 2a 2a 20  tions.  **.  ** 
48f0: 20 20 2a 20 20 4f 74 68 65 72 77 69 73 65 20 28    *  Otherwise (
4900: 69 66 20 6d 75 6c 74 69 2d 74 68 72 65 61 64 65  if multi-threade
4910: 64 20 61 6e 64 20 45 4e 41 42 4c 45 5f 4d 45 4d  d and ENABLE_MEM
4920: 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 20 69  ORY_MANAGEMENT i
4930: 73 20 6f 66 66 29 0a 20 20 2a 2a 20 20 20 20 20  s off).  **     
4940: 20 75 73 65 20 73 65 70 61 72 61 74 65 20 63 61   use separate ca
4950: 63 68 65 73 20 28 6d 6f 64 65 2d 31 29 0a 20 20  ches (mode-1).  
4960: 2a 2f 0a 23 69 66 20 64 65 66 69 6e 65 64 28 53  */.#if defined(S
4970: 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d  QLITE_ENABLE_MEM
4980: 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 29 20  ORY_MANAGEMENT) 
4990: 7c 7c 20 53 51 4c 49 54 45 5f 54 48 52 45 41 44  || SQLITE_THREAD
49a0: 53 41 46 45 3d 3d 30 0a 20 20 63 6f 6e 73 74 20  SAFE==0.  const 
49b0: 69 6e 74 20 73 65 70 61 72 61 74 65 43 61 63 68  int separateCach
49c0: 65 20 3d 20 30 3b 0a 23 65 6c 73 65 0a 20 20 69  e = 0;.#else.  i
49d0: 6e 74 20 73 65 70 61 72 61 74 65 43 61 63 68 65  nt separateCache
49e0: 20 3d 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c   = sqlite3Global
49f0: 43 6f 6e 66 69 67 2e 62 43 6f 72 65 4d 75 74 65  Config.bCoreMute
4a00: 78 3e 30 3b 0a 23 65 6e 64 69 66 0a 0a 20 20 73  x>0;.#endif..  s
4a10: 7a 20 3d 20 73 69 7a 65 6f 66 28 50 43 61 63 68  z = sizeof(PCach
4a20: 65 31 29 20 2b 20 73 69 7a 65 6f 66 28 50 47 72  e1) + sizeof(PGr
4a30: 6f 75 70 29 2a 73 65 70 61 72 61 74 65 43 61 63  oup)*separateCac
4a40: 68 65 3b 0a 20 20 70 43 61 63 68 65 20 3d 20 28  he;.  pCache = (
4a50: 50 43 61 63 68 65 31 20 2a 29 73 71 6c 69 74 65  PCache1 *)sqlite
4a60: 33 5f 6d 61 6c 6c 6f 63 28 73 7a 29 3b 0a 20 20  3_malloc(sz);.  
4a70: 69 66 28 20 70 43 61 63 68 65 20 29 7b 0a 20 20  if( pCache ){.  
4a80: 20 20 6d 65 6d 73 65 74 28 70 43 61 63 68 65 2c    memset(pCache,
4a90: 20 30 2c 20 73 7a 29 3b 0a 20 20 20 20 69 66 28   0, sz);.    if(
4aa0: 20 73 65 70 61 72 61 74 65 43 61 63 68 65 20 29   separateCache )
4ab0: 7b 0a 20 20 20 20 20 20 70 47 72 6f 75 70 20 3d  {.      pGroup =
4ac0: 20 28 50 47 72 6f 75 70 2a 29 26 70 43 61 63 68   (PGroup*)&pCach
4ad0: 65 5b 31 5d 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  e[1];.    }else{
4ae0: 0a 20 20 20 20 20 20 70 47 72 6f 75 70 20 3d 20  .      pGroup = 
4af0: 26 70 63 61 63 68 65 31 5f 67 2e 67 72 70 3b 0a  &pcache1_g.grp;.
4b00: 20 20 20 20 7d 0a 20 20 20 20 70 43 61 63 68 65      }.    pCache
4b10: 2d 3e 70 47 72 6f 75 70 20 3d 20 70 47 72 6f 75  ->pGroup = pGrou
4b20: 70 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 73  p;.    pCache->s
4b30: 7a 50 61 67 65 20 3d 20 73 7a 50 61 67 65 3b 0a  zPage = szPage;.
4b40: 20 20 20 20 70 43 61 63 68 65 2d 3e 62 50 75 72      pCache->bPur
4b50: 67 65 61 62 6c 65 20 3d 20 28 62 50 75 72 67 65  geable = (bPurge
4b60: 61 62 6c 65 20 3f 20 31 20 3a 20 30 29 3b 0a 20  able ? 1 : 0);. 
4b70: 20 20 20 69 66 28 20 62 50 75 72 67 65 61 62 6c     if( bPurgeabl
4b80: 65 20 29 7b 0a 20 20 20 20 20 20 70 43 61 63 68  e ){.      pCach
4b90: 65 2d 3e 6e 4d 69 6e 20 3d 20 31 30 3b 0a 20 20  e->nMin = 10;.  
4ba0: 20 20 20 20 70 63 61 63 68 65 31 45 6e 74 65 72      pcache1Enter
4bb0: 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b 0a 20  Mutex(pGroup);. 
4bc0: 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 6e 4d 69       pGroup->nMi
4bd0: 6e 50 61 67 65 20 2b 3d 20 70 43 61 63 68 65 2d  nPage += pCache-
4be0: 3e 6e 4d 69 6e 3b 0a 20 20 20 20 20 20 70 63 61  >nMin;.      pca
4bf0: 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 70  che1LeaveMutex(p
4c00: 47 72 6f 75 70 29 3b 0a 20 20 20 20 7d 0a 20 20  Group);.    }.  
4c10: 7d 0a 20 20 72 65 74 75 72 6e 20 28 73 71 6c 69  }.  return (sqli
4c20: 74 65 33 5f 70 63 61 63 68 65 20 2a 29 70 43 61  te3_pcache *)pCa
4c30: 63 68 65 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d  che;.}../*.** Im
4c40: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20  plementation of 
4c50: 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63  the sqlite3_pcac
4c60: 68 65 2e 78 43 61 63 68 65 73 69 7a 65 20 6d 65  he.xCachesize me
4c70: 74 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20 43 6f 6e  thod. .**.** Con
4c80: 66 69 67 75 72 65 20 74 68 65 20 63 61 63 68 65  figure the cache
4c90: 5f 73 69 7a 65 20 6c 69 6d 69 74 20 66 6f 72 20  _size limit for 
4ca0: 61 20 63 61 63 68 65 2e 0a 2a 2f 0a 73 74 61 74  a cache..*/.stat
4cb0: 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 31 43  ic void pcache1C
4cc0: 61 63 68 65 73 69 7a 65 28 73 71 6c 69 74 65 33  achesize(sqlite3
4cd0: 5f 70 63 61 63 68 65 20 2a 70 2c 20 69 6e 74 20  _pcache *p, int 
4ce0: 6e 4d 61 78 29 7b 0a 20 20 50 43 61 63 68 65 31  nMax){.  PCache1
4cf0: 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61 63   *pCache = (PCac
4d00: 68 65 31 20 2a 29 70 3b 0a 20 20 69 66 28 20 70  he1 *)p;.  if( p
4d10: 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c  Cache->bPurgeabl
4d20: 65 20 29 7b 0a 20 20 20 20 50 47 72 6f 75 70 20  e ){.    PGroup 
4d30: 2a 70 47 72 6f 75 70 20 3d 20 70 43 61 63 68 65  *pGroup = pCache
4d40: 2d 3e 70 47 72 6f 75 70 3b 0a 20 20 20 20 70 63  ->pGroup;.    pc
4d50: 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28  ache1EnterMutex(
4d60: 70 47 72 6f 75 70 29 3b 0a 20 20 20 20 70 47 72  pGroup);.    pGr
4d70: 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65 20 2b 3d  oup->nMaxPage +=
4d80: 20 28 6e 4d 61 78 20 2d 20 70 43 61 63 68 65 2d   (nMax - pCache-
4d90: 3e 6e 4d 61 78 29 3b 0a 20 20 20 20 70 43 61 63  >nMax);.    pCac
4da0: 68 65 2d 3e 6e 4d 61 78 20 3d 20 6e 4d 61 78 3b  he->nMax = nMax;
4db0: 0a 20 20 20 20 70 63 61 63 68 65 31 45 6e 66 6f  .    pcache1Enfo
4dc0: 72 63 65 4d 61 78 50 61 67 65 28 70 47 72 6f 75  rceMaxPage(pGrou
4dd0: 70 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31 4c  p);.    pcache1L
4de0: 65 61 76 65 4d 75 74 65 78 28 70 47 72 6f 75 70  eaveMutex(pGroup
4df0: 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  );.  }.}../*.** 
4e00: 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  Implementation o
4e10: 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63  f the sqlite3_pc
4e20: 61 63 68 65 2e 78 50 61 67 65 63 6f 75 6e 74 20  ache.xPagecount 
4e30: 6d 65 74 68 6f 64 2e 20 0a 2a 2f 0a 73 74 61 74  method. .*/.stat
4e40: 69 63 20 69 6e 74 20 70 63 61 63 68 65 31 50 61  ic int pcache1Pa
4e50: 67 65 63 6f 75 6e 74 28 73 71 6c 69 74 65 33 5f  gecount(sqlite3_
4e60: 70 63 61 63 68 65 20 2a 70 29 7b 0a 20 20 69 6e  pcache *p){.  in
4e70: 74 20 6e 3b 0a 20 20 50 43 61 63 68 65 31 20 2a  t n;.  PCache1 *
4e80: 70 43 61 63 68 65 20 3d 20 28 50 43 61 63 68 65  pCache = (PCache
4e90: 31 2a 29 70 3b 0a 20 20 70 63 61 63 68 65 31 45  1*)p;.  pcache1E
4ea0: 6e 74 65 72 4d 75 74 65 78 28 70 43 61 63 68 65  nterMutex(pCache
4eb0: 2d 3e 70 47 72 6f 75 70 29 3b 0a 20 20 6e 20 3d  ->pGroup);.  n =
4ec0: 20 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 3b 0a   pCache->nPage;.
4ed0: 20 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75    pcache1LeaveMu
4ee0: 74 65 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f  tex(pCache->pGro
4ef0: 75 70 29 3b 0a 20 20 72 65 74 75 72 6e 20 6e 3b  up);.  return n;
4f00: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d  .}../*.** Implem
4f10: 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20  entation of the 
4f20: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78  sqlite3_pcache.x
4f30: 46 65 74 63 68 20 6d 65 74 68 6f 64 2e 20 0a 2a  Fetch method. .*
4f40: 2a 0a 2a 2a 20 46 65 74 63 68 20 61 20 70 61 67  *.** Fetch a pag
4f50: 65 20 62 79 20 6b 65 79 20 76 61 6c 75 65 2e 0a  e by key value..
4f60: 2a 2a 0a 2a 2a 20 57 68 65 74 68 65 72 20 6f 72  **.** Whether or
4f70: 20 6e 6f 74 20 61 20 6e 65 77 20 70 61 67 65 20   not a new page 
4f80: 6d 61 79 20 62 65 20 61 6c 6c 6f 63 61 74 65 64  may be allocated
4f90: 20 62 79 20 74 68 69 73 20 66 75 6e 63 74 69 6f   by this functio
4fa0: 6e 20 64 65 70 65 6e 64 73 20 6f 6e 0a 2a 2a 20  n depends on.** 
4fb0: 74 68 65 20 76 61 6c 75 65 20 6f 66 20 74 68 65  the value of the
4fc0: 20 63 72 65 61 74 65 46 6c 61 67 20 61 72 67 75   createFlag argu
4fd0: 6d 65 6e 74 2e 20 20 30 20 6d 65 61 6e 73 20 64  ment.  0 means d
4fe0: 6f 20 6e 6f 74 20 61 6c 6c 6f 63 61 74 65 20 61  o not allocate a
4ff0: 20 6e 65 77 0a 2a 2a 20 70 61 67 65 2e 20 20 31   new.** page.  1
5000: 20 6d 65 61 6e 73 20 61 6c 6c 6f 63 61 74 65 20   means allocate 
5010: 61 20 6e 65 77 20 70 61 67 65 20 69 66 20 73 70  a new page if sp
5020: 61 63 65 20 69 73 20 65 61 73 69 6c 79 20 61 76  ace is easily av
5030: 61 69 6c 61 62 6c 65 2e 20 20 32 20 0a 2a 2a 20  ailable.  2 .** 
5040: 6d 65 61 6e 73 20 74 6f 20 74 72 79 20 72 65 61  means to try rea
5050: 6c 6c 79 20 68 61 72 64 20 74 6f 20 61 6c 6c 6f  lly hard to allo
5060: 63 61 74 65 20 61 20 6e 65 77 20 70 61 67 65 2e  cate a new page.
5070: 0a 2a 2a 0a 2a 2a 20 46 6f 72 20 61 20 6e 6f 6e  .**.** For a non
5080: 2d 70 75 72 67 65 61 62 6c 65 20 63 61 63 68 65  -purgeable cache
5090: 20 28 61 20 63 61 63 68 65 20 75 73 65 64 20 61   (a cache used a
50a0: 73 20 74 68 65 20 73 74 6f 72 61 67 65 20 66 6f  s the storage fo
50b0: 72 20 61 6e 20 69 6e 2d 6d 65 6d 6f 72 79 0a 2a  r an in-memory.*
50c0: 2a 20 64 61 74 61 62 61 73 65 29 20 74 68 65 72  * database) ther
50d0: 65 20 69 73 20 72 65 61 6c 6c 79 20 6e 6f 20 64  e is really no d
50e0: 69 66 66 65 72 65 6e 63 65 20 62 65 74 77 65 65  ifference betwee
50f0: 6e 20 63 72 65 61 74 65 46 6c 61 67 20 31 20 61  n createFlag 1 a
5100: 6e 64 20 32 2e 20 20 53 6f 0a 2a 2a 20 74 68 65  nd 2.  So.** the
5110: 20 63 61 6c 6c 69 6e 67 20 66 75 6e 63 74 69 6f   calling functio
5120: 6e 20 28 70 63 61 63 68 65 2e 63 29 20 77 69 6c  n (pcache.c) wil
5130: 6c 20 6e 65 76 65 72 20 68 61 76 65 20 61 20 63  l never have a c
5140: 72 65 61 74 65 46 6c 61 67 20 6f 66 20 31 20 6f  reateFlag of 1 o
5150: 6e 0a 2a 2a 20 61 20 6e 6f 6e 2d 70 75 72 67 61  n.** a non-purga
5160: 62 6c 65 20 63 61 63 68 65 2e 0a 2a 2a 0a 2a 2a  ble cache..**.**
5170: 20 54 68 65 72 65 20 61 72 65 20 74 68 72 65 65   There are three
5180: 20 64 69 66 66 65 72 65 6e 74 20 61 70 70 72 6f   different appro
5190: 61 63 68 65 73 20 74 6f 20 6f 62 74 61 69 6e 69  aches to obtaini
51a0: 6e 67 20 73 70 61 63 65 20 66 6f 72 20 61 20 70  ng space for a p
51b0: 61 67 65 2c 0a 2a 2a 20 64 65 70 65 6e 64 69 6e  age,.** dependin
51c0: 67 20 6f 6e 20 74 68 65 20 76 61 6c 75 65 20 6f  g on the value o
51d0: 66 20 70 61 72 61 6d 65 74 65 72 20 63 72 65 61  f parameter crea
51e0: 74 65 46 6c 61 67 20 28 77 68 69 63 68 20 6d 61  teFlag (which ma
51f0: 79 20 62 65 20 30 2c 20 31 20 6f 72 20 32 29 2e  y be 0, 1 or 2).
5200: 0a 2a 2a 0a 2a 2a 20 20 20 31 2e 20 52 65 67 61  .**.**   1. Rega
5210: 72 64 6c 65 73 73 20 6f 66 20 74 68 65 20 76 61  rdless of the va
5220: 6c 75 65 20 6f 66 20 63 72 65 61 74 65 46 6c 61  lue of createFla
5230: 67 2c 20 74 68 65 20 63 61 63 68 65 20 69 73 20  g, the cache is 
5240: 73 65 61 72 63 68 65 64 20 66 6f 72 20 61 20 0a  searched for a .
5250: 2a 2a 20 20 20 20 20 20 63 6f 70 79 20 6f 66 20  **      copy of 
5260: 74 68 65 20 72 65 71 75 65 73 74 65 64 20 70 61  the requested pa
5270: 67 65 2e 20 49 66 20 6f 6e 65 20 69 73 20 66 6f  ge. If one is fo
5280: 75 6e 64 2c 20 69 74 20 69 73 20 72 65 74 75 72  und, it is retur
5290: 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 32 2e 20  ned..**.**   2. 
52a0: 49 66 20 63 72 65 61 74 65 46 6c 61 67 3d 3d 30  If createFlag==0
52b0: 20 61 6e 64 20 74 68 65 20 70 61 67 65 20 69 73   and the page is
52c0: 20 6e 6f 74 20 61 6c 72 65 61 64 79 20 69 6e 20   not already in 
52d0: 74 68 65 20 63 61 63 68 65 2c 20 4e 55 4c 4c 20  the cache, NULL 
52e0: 69 73 0a 2a 2a 20 20 20 20 20 20 72 65 74 75 72  is.**      retur
52f0: 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 33 2e 20  ned..**.**   3. 
5300: 49 66 20 63 72 65 61 74 65 46 6c 61 67 20 69 73  If createFlag is
5310: 20 31 2c 20 61 6e 64 20 74 68 65 20 70 61 67 65   1, and the page
5320: 20 69 73 20 6e 6f 74 20 61 6c 72 65 61 64 79 20   is not already 
5330: 69 6e 20 74 68 65 20 63 61 63 68 65 2c 20 74 68  in the cache, th
5340: 65 6e 0a 2a 2a 20 20 20 20 20 20 72 65 74 75 72  en.**      retur
5350: 6e 20 4e 55 4c 4c 20 28 64 6f 20 6e 6f 74 20 61  n NULL (do not a
5360: 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 70 61  llocate a new pa
5370: 67 65 29 20 69 66 20 61 6e 79 20 6f 66 20 74 68  ge) if any of th
5380: 65 20 66 6f 6c 6c 6f 77 69 6e 67 0a 2a 2a 20 20  e following.**  
5390: 20 20 20 20 63 6f 6e 64 69 74 69 6f 6e 73 20 61      conditions a
53a0: 72 65 20 74 72 75 65 3a 0a 2a 2a 0a 2a 2a 20 20  re true:.**.**  
53b0: 20 20 20 20 20 28 61 29 20 74 68 65 20 6e 75 6d       (a) the num
53c0: 62 65 72 20 6f 66 20 70 61 67 65 73 20 70 69 6e  ber of pages pin
53d0: 6e 65 64 20 62 79 20 74 68 65 20 63 61 63 68 65  ned by the cache
53e0: 20 69 73 20 67 72 65 61 74 65 72 20 74 68 61 6e   is greater than
53f0: 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 50 43  .**           PC
5400: 61 63 68 65 31 2e 6e 4d 61 78 2c 20 6f 72 0a 2a  ache1.nMax, or.*
5410: 2a 0a 2a 2a 20 20 20 20 20 20 20 28 62 29 20 74  *.**       (b) t
5420: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67  he number of pag
5430: 65 73 20 70 69 6e 6e 65 64 20 62 79 20 74 68 65  es pinned by the
5440: 20 63 61 63 68 65 20 69 73 20 67 72 65 61 74 65   cache is greate
5450: 72 20 74 68 61 6e 0a 2a 2a 20 20 20 20 20 20 20  r than.**       
5460: 20 20 20 20 74 68 65 20 73 75 6d 20 6f 66 20 6e      the sum of n
5470: 4d 61 78 20 66 6f 72 20 61 6c 6c 20 70 75 72 67  Max for all purg
5480: 65 61 62 6c 65 20 63 61 63 68 65 73 2c 20 6c 65  eable caches, le
5490: 73 73 20 74 68 65 20 73 75 6d 20 6f 66 20 0a 2a  ss the sum of .*
54a0: 2a 20 20 20 20 20 20 20 20 20 20 20 6e 4d 69 6e  *           nMin
54b0: 20 66 6f 72 20 61 6c 6c 20 6f 74 68 65 72 20 70   for all other p
54c0: 75 72 67 65 61 62 6c 65 20 63 61 63 68 65 73 2c  urgeable caches,
54d0: 20 6f 72 0a 2a 2a 0a 2a 2a 20 20 20 34 2e 20 49   or.**.**   4. I
54e0: 66 20 6e 6f 6e 65 20 6f 66 20 74 68 65 20 66 69  f none of the fi
54f0: 72 73 74 20 74 68 72 65 65 20 63 6f 6e 64 69 74  rst three condit
5500: 69 6f 6e 73 20 61 70 70 6c 79 20 61 6e 64 20 74  ions apply and t
5510: 68 65 20 63 61 63 68 65 20 69 73 20 6d 61 72 6b  he cache is mark
5520: 65 64 0a 2a 2a 20 20 20 20 20 20 61 73 20 70 75  ed.**      as pu
5530: 72 67 65 61 62 6c 65 2c 20 61 6e 64 20 69 66 20  rgeable, and if 
5540: 6f 6e 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f  one of the follo
5550: 77 69 6e 67 20 69 73 20 74 72 75 65 3a 0a 2a 2a  wing is true:.**
5560: 0a 2a 2a 20 20 20 20 20 20 20 28 61 29 20 54 68  .**       (a) Th
5570: 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65  e number of page
5580: 73 20 61 6c 6c 6f 63 61 74 65 64 20 66 6f 72 20  s allocated for 
5590: 74 68 65 20 63 61 63 68 65 20 69 73 20 61 6c 72  the cache is alr
55a0: 65 61 64 79 20 0a 2a 2a 20 20 20 20 20 20 20 20  eady .**        
55b0: 20 20 20 50 43 61 63 68 65 31 2e 6e 4d 61 78 2c     PCache1.nMax,
55c0: 20 6f 72 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20   or.**.**       
55d0: 28 62 29 20 54 68 65 20 6e 75 6d 62 65 72 20 6f  (b) The number o
55e0: 66 20 70 61 67 65 73 20 61 6c 6c 6f 63 61 74 65  f pages allocate
55f0: 64 20 66 6f 72 20 61 6c 6c 20 70 75 72 67 65 61  d for all purgea
5600: 62 6c 65 20 63 61 63 68 65 73 20 69 73 0a 2a 2a  ble caches is.**
5610: 20 20 20 20 20 20 20 20 20 20 20 61 6c 72 65 61             alrea
5620: 64 79 20 65 71 75 61 6c 20 74 6f 20 6f 72 20 67  dy equal to or g
5630: 72 65 61 74 65 72 20 74 68 61 6e 20 74 68 65 20  reater than the 
5640: 73 75 6d 20 6f 66 20 6e 4d 61 78 20 66 6f 72 20  sum of nMax for 
5650: 61 6c 6c 0a 2a 2a 20 20 20 20 20 20 20 20 20 20  all.**          
5660: 20 70 75 72 67 65 61 62 6c 65 20 63 61 63 68 65   purgeable cache
5670: 73 2c 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 28  s,.**.**       (
5680: 63 29 20 54 68 65 20 73 79 73 74 65 6d 20 69 73  c) The system is
5690: 20 75 6e 64 65 72 20 6d 65 6d 6f 72 79 20 70 72   under memory pr
56a0: 65 73 73 75 72 65 20 61 6e 64 20 77 61 6e 74 73  essure and wants
56b0: 20 74 6f 20 61 76 6f 69 64 0a 2a 2a 20 20 20 20   to avoid.**    
56c0: 20 20 20 20 20 20 20 75 6e 6e 65 63 65 73 73 61         unnecessa
56d0: 72 79 20 70 61 67 65 73 20 63 61 63 68 65 20 65  ry pages cache e
56e0: 6e 74 72 79 20 61 6c 6c 6f 63 61 74 69 6f 6e 73  ntry allocations
56f0: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 74 68 65 6e  .**.**      then
5700: 20 61 74 74 65 6d 70 74 20 74 6f 20 72 65 63 79   attempt to recy
5710: 63 6c 65 20 61 20 70 61 67 65 20 66 72 6f 6d 20  cle a page from 
5720: 74 68 65 20 4c 52 55 20 6c 69 73 74 2e 20 49 66  the LRU list. If
5730: 20 69 74 20 69 73 20 74 68 65 20 72 69 67 68 74   it is the right
5740: 0a 2a 2a 20 20 20 20 20 20 73 69 7a 65 2c 20 72  .**      size, r
5750: 65 74 75 72 6e 20 74 68 65 20 72 65 63 79 63 6c  eturn the recycl
5760: 65 64 20 62 75 66 66 65 72 2e 20 4f 74 68 65 72  ed buffer. Other
5770: 77 69 73 65 2c 20 66 72 65 65 20 74 68 65 20 62  wise, free the b
5780: 75 66 66 65 72 20 61 6e 64 0a 2a 2a 20 20 20 20  uffer and.**    
5790: 20 20 70 72 6f 63 65 65 64 20 74 6f 20 73 74 65    proceed to ste
57a0: 70 20 35 2e 20 0a 2a 2a 0a 2a 2a 20 20 20 35 2e  p 5. .**.**   5.
57b0: 20 4f 74 68 65 72 77 69 73 65 2c 20 61 6c 6c 6f   Otherwise, allo
57c0: 63 61 74 65 20 61 6e 64 20 72 65 74 75 72 6e 20  cate and return 
57d0: 61 20 6e 65 77 20 70 61 67 65 20 62 75 66 66 65  a new page buffe
57e0: 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  r..*/.static voi
57f0: 64 20 2a 70 63 61 63 68 65 31 46 65 74 63 68 28  d *pcache1Fetch(
5800: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a  sqlite3_pcache *
5810: 70 2c 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  p, unsigned int 
5820: 69 4b 65 79 2c 20 69 6e 74 20 63 72 65 61 74 65  iKey, int create
5830: 46 6c 61 67 29 7b 0a 20 20 75 6e 73 69 67 6e 65  Flag){.  unsigne
5840: 64 20 69 6e 74 20 6e 50 69 6e 6e 65 64 3b 0a 20  d int nPinned;. 
5850: 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68 65   PCache1 *pCache
5860: 20 3d 20 28 50 43 61 63 68 65 31 20 2a 29 70 3b   = (PCache1 *)p;
5870: 0a 20 20 50 47 72 6f 75 70 20 2a 70 47 72 6f 75  .  PGroup *pGrou
5880: 70 20 3d 20 70 43 61 63 68 65 2d 3e 70 47 72 6f  p = pCache->pGro
5890: 75 70 3b 0a 20 20 50 67 48 64 72 31 20 2a 70 50  up;.  PgHdr1 *pP
58a0: 61 67 65 20 3d 20 30 3b 0a 0a 20 20 61 73 73 65  age = 0;..  asse
58b0: 72 74 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72  rt( pCache->bPur
58c0: 67 65 61 62 6c 65 20 7c 7c 20 63 72 65 61 74 65  geable || create
58d0: 46 6c 61 67 21 3d 31 20 29 3b 0a 20 20 70 63 61  Flag!=1 );.  pca
58e0: 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70  che1EnterMutex(p
58f0: 47 72 6f 75 70 29 3b 0a 20 20 69 66 28 20 63 72  Group);.  if( cr
5900: 65 61 74 65 46 6c 61 67 3d 3d 31 20 29 20 73 71  eateFlag==1 ) sq
5910: 6c 69 74 65 33 42 65 67 69 6e 42 65 6e 69 67 6e  lite3BeginBenign
5920: 4d 61 6c 6c 6f 63 28 29 3b 0a 0a 20 20 2f 2a 20  Malloc();..  /* 
5930: 53 74 65 70 20 31 3a 20 53 65 61 72 63 68 20 74  Step 1: Search t
5940: 68 65 20 68 61 73 68 20 74 61 62 6c 65 20 66 6f  he hash table fo
5950: 72 20 61 6e 20 65 78 69 73 74 69 6e 67 20 65 6e  r an existing en
5960: 74 72 79 2e 20 2a 2f 0a 20 20 69 66 28 20 70 43  try. */.  if( pC
5970: 61 63 68 65 2d 3e 6e 48 61 73 68 3e 30 20 29 7b  ache->nHash>0 ){
5980: 0a 20 20 20 20 75 6e 73 69 67 6e 65 64 20 69 6e  .    unsigned in
5990: 74 20 68 20 3d 20 69 4b 65 79 20 25 20 70 43 61  t h = iKey % pCa
59a0: 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 20 20  che->nHash;.    
59b0: 66 6f 72 28 70 50 61 67 65 3d 70 43 61 63 68 65  for(pPage=pCache
59c0: 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 20 70 50 61  ->apHash[h]; pPa
59d0: 67 65 26 26 70 50 61 67 65 2d 3e 69 4b 65 79 21  ge&&pPage->iKey!
59e0: 3d 69 4b 65 79 3b 20 70 50 61 67 65 3d 70 50 61  =iKey; pPage=pPa
59f0: 67 65 2d 3e 70 4e 65 78 74 29 3b 0a 20 20 7d 0a  ge->pNext);.  }.
5a00: 0a 20 20 2f 2a 20 53 74 65 70 20 32 3a 20 41 62  .  /* Step 2: Ab
5a10: 6f 72 74 20 69 66 20 6e 6f 20 65 78 69 73 74 69  ort if no existi
5a20: 6e 67 20 70 61 67 65 20 69 73 20 66 6f 75 6e 64  ng page is found
5a30: 20 61 6e 64 20 63 72 65 61 74 65 46 6c 61 67 20   and createFlag 
5a40: 69 73 20 30 20 2a 2f 0a 20 20 69 66 28 20 70 50  is 0 */.  if( pP
5a50: 61 67 65 20 7c 7c 20 63 72 65 61 74 65 46 6c 61  age || createFla
5a60: 67 3d 3d 30 20 29 7b 0a 20 20 20 20 70 63 61 63  g==0 ){.    pcac
5a70: 68 65 31 50 69 6e 50 61 67 65 28 70 50 61 67 65  he1PinPage(pPage
5a80: 29 3b 0a 20 20 20 20 67 6f 74 6f 20 66 65 74 63  );.    goto fetc
5a90: 68 5f 6f 75 74 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  h_out;.  }..  /*
5aa0: 20 53 74 65 70 20 33 3a 20 41 62 6f 72 74 20 69   Step 3: Abort i
5ab0: 66 20 63 72 65 61 74 65 46 6c 61 67 20 69 73 20  f createFlag is 
5ac0: 31 20 62 75 74 20 74 68 65 20 63 61 63 68 65 20  1 but the cache 
5ad0: 69 73 20 6e 65 61 72 6c 79 20 66 75 6c 6c 20 2a  is nearly full *
5ae0: 2f 0a 20 20 6e 50 69 6e 6e 65 64 20 3d 20 70 43  /.  nPinned = pC
5af0: 61 63 68 65 2d 3e 6e 50 61 67 65 20 2d 20 70 43  ache->nPage - pC
5b00: 61 63 68 65 2d 3e 6e 52 65 63 79 63 6c 61 62 6c  ache->nRecyclabl
5b10: 65 3b 0a 20 20 69 66 28 20 63 72 65 61 74 65 46  e;.  if( createF
5b20: 6c 61 67 3d 3d 31 20 26 26 20 28 0a 20 20 20 20  lag==1 && (.    
5b30: 20 20 20 20 6e 50 69 6e 6e 65 64 3e 3d 28 70 47      nPinned>=(pG
5b40: 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65 2b 70  roup->nMaxPage+p
5b50: 43 61 63 68 65 2d 3e 6e 4d 69 6e 2d 70 47 72 6f  Cache->nMin-pGro
5b60: 75 70 2d 3e 6e 4d 69 6e 50 61 67 65 29 0a 20 20  up->nMinPage).  
5b70: 20 20 20 7c 7c 20 6e 50 69 6e 6e 65 64 3e 3d 28     || nPinned>=(
5b80: 70 43 61 63 68 65 2d 3e 6e 4d 61 78 20 2a 20 39  pCache->nMax * 9
5b90: 20 2f 20 31 30 29 0a 20 20 20 20 20 7c 7c 20 70   / 10).     || p
5ba0: 63 61 63 68 65 31 55 6e 64 65 72 4d 65 6d 6f 72  cache1UnderMemor
5bb0: 79 50 72 65 73 73 75 72 65 28 70 43 61 63 68 65  yPressure(pCache
5bc0: 29 0a 20 20 29 29 7b 0a 20 20 20 20 67 6f 74 6f  ).  )){.    goto
5bd0: 20 66 65 74 63 68 5f 6f 75 74 3b 0a 20 20 7d 0a   fetch_out;.  }.
5be0: 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 6e  .  if( pCache->n
5bf0: 50 61 67 65 3e 3d 70 43 61 63 68 65 2d 3e 6e 48  Page>=pCache->nH
5c00: 61 73 68 20 26 26 20 70 63 61 63 68 65 31 52 65  ash && pcache1Re
5c10: 73 69 7a 65 48 61 73 68 28 70 43 61 63 68 65 29  sizeHash(pCache)
5c20: 20 29 7b 0a 20 20 20 20 67 6f 74 6f 20 66 65 74   ){.    goto fet
5c30: 63 68 5f 6f 75 74 3b 0a 20 20 7d 0a 0a 20 20 2f  ch_out;.  }..  /
5c40: 2a 20 53 74 65 70 20 34 2e 20 54 72 79 20 74 6f  * Step 4. Try to
5c50: 20 72 65 63 79 63 6c 65 20 61 20 70 61 67 65 2e   recycle a page.
5c60: 20 2a 2f 0a 20 20 69 66 28 20 70 43 61 63 68 65   */.  if( pCache
5c70: 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 26 26 20  ->bPurgeable && 
5c80: 70 47 72 6f 75 70 2d 3e 70 4c 72 75 54 61 69 6c  pGroup->pLruTail
5c90: 20 26 26 20 28 0a 20 20 20 20 20 20 20 20 20 28   && (.         (
5ca0: 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 2b 31 3e  pCache->nPage+1>
5cb0: 3d 70 43 61 63 68 65 2d 3e 6e 4d 61 78 29 0a 20  =pCache->nMax). 
5cc0: 20 20 20 20 20 7c 7c 20 70 47 72 6f 75 70 2d 3e       || pGroup->
5cd0: 6e 43 75 72 72 65 6e 74 50 61 67 65 3e 3d 70 47  nCurrentPage>=pG
5ce0: 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65 0a 20  roup->nMaxPage. 
5cf0: 20 20 20 20 20 7c 7c 20 70 63 61 63 68 65 31 55       || pcache1U
5d00: 6e 64 65 72 4d 65 6d 6f 72 79 50 72 65 73 73 75  nderMemoryPressu
5d10: 72 65 28 70 43 61 63 68 65 29 0a 20 20 29 29 7b  re(pCache).  )){
5d20: 0a 20 20 20 20 70 50 61 67 65 20 3d 20 70 47 72  .    pPage = pGr
5d30: 6f 75 70 2d 3e 70 4c 72 75 54 61 69 6c 3b 0a 20  oup->pLruTail;. 
5d40: 20 20 20 70 63 61 63 68 65 31 52 65 6d 6f 76 65     pcache1Remove
5d50: 46 72 6f 6d 48 61 73 68 28 70 50 61 67 65 29 3b  FromHash(pPage);
5d60: 0a 20 20 20 20 70 63 61 63 68 65 31 50 69 6e 50  .    pcache1PinP
5d70: 61 67 65 28 70 50 61 67 65 29 3b 0a 20 20 20 20  age(pPage);.    
5d80: 69 66 28 20 70 50 61 67 65 2d 3e 70 43 61 63 68  if( pPage->pCach
5d90: 65 2d 3e 73 7a 50 61 67 65 21 3d 70 43 61 63 68  e->szPage!=pCach
5da0: 65 2d 3e 73 7a 50 61 67 65 20 29 7b 0a 20 20 20  e->szPage ){.   
5db0: 20 20 20 70 63 61 63 68 65 31 46 72 65 65 50 61     pcache1FreePa
5dc0: 67 65 28 70 50 61 67 65 29 3b 0a 20 20 20 20 20  ge(pPage);.     
5dd0: 20 70 50 61 67 65 20 3d 20 30 3b 0a 20 20 20 20   pPage = 0;.    
5de0: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 47 72  }else{.      pGr
5df0: 6f 75 70 2d 3e 6e 43 75 72 72 65 6e 74 50 61 67  oup->nCurrentPag
5e00: 65 20 2d 3d 20 0a 20 20 20 20 20 20 20 20 20 20  e -= .          
5e10: 20 20 20 20 20 28 70 50 61 67 65 2d 3e 70 43 61       (pPage->pCa
5e20: 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20  che->bPurgeable 
5e30: 2d 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65  - pCache->bPurge
5e40: 61 62 6c 65 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  able);.    }.  }
5e50: 0a 0a 20 20 2f 2a 20 53 74 65 70 20 35 2e 20 49  ..  /* Step 5. I
5e60: 66 20 61 20 75 73 61 62 6c 65 20 70 61 67 65 20  f a usable page 
5e70: 62 75 66 66 65 72 20 68 61 73 20 73 74 69 6c 6c  buffer has still
5e80: 20 6e 6f 74 20 62 65 65 6e 20 66 6f 75 6e 64 2c   not been found,
5e90: 20 0a 20 20 2a 2a 20 61 74 74 65 6d 70 74 20 74   .  ** attempt t
5ea0: 6f 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77  o allocate a new
5eb0: 20 6f 6e 65 2e 20 0a 20 20 2a 2f 0a 20 20 69 66   one. .  */.  if
5ec0: 28 20 21 70 50 61 67 65 20 29 7b 0a 20 20 20 20  ( !pPage ){.    
5ed0: 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65  pcache1LeaveMute
5ee0: 78 28 70 47 72 6f 75 70 29 3b 0a 20 20 20 20 70  x(pGroup);.    p
5ef0: 50 61 67 65 20 3d 20 70 63 61 63 68 65 31 41 6c  Page = pcache1Al
5f00: 6c 6f 63 50 61 67 65 28 70 43 61 63 68 65 29 3b  locPage(pCache);
5f10: 0a 20 20 20 20 70 63 61 63 68 65 31 45 6e 74 65  .    pcache1Ente
5f20: 72 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b 0a  rMutex(pGroup);.
5f30: 20 20 7d 0a 0a 20 20 69 66 28 20 70 50 61 67 65    }..  if( pPage
5f40: 20 29 7b 0a 20 20 20 20 75 6e 73 69 67 6e 65 64   ){.    unsigned
5f50: 20 69 6e 74 20 68 20 3d 20 69 4b 65 79 20 25 20   int h = iKey % 
5f60: 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20  pCache->nHash;. 
5f70: 20 20 20 70 43 61 63 68 65 2d 3e 6e 50 61 67 65     pCache->nPage
5f80: 2b 2b 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 69  ++;.    pPage->i
5f90: 4b 65 79 20 3d 20 69 4b 65 79 3b 0a 20 20 20 20  Key = iKey;.    
5fa0: 70 50 61 67 65 2d 3e 70 4e 65 78 74 20 3d 20 70  pPage->pNext = p
5fb0: 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d  Cache->apHash[h]
5fc0: 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 43 61  ;.    pPage->pCa
5fd0: 63 68 65 20 3d 20 70 43 61 63 68 65 3b 0a 20 20  che = pCache;.  
5fe0: 20 20 70 50 61 67 65 2d 3e 70 4c 72 75 50 72 65    pPage->pLruPre
5ff0: 76 20 3d 20 30 3b 0a 20 20 20 20 70 50 61 67 65  v = 0;.    pPage
6000: 2d 3e 70 4c 72 75 4e 65 78 74 20 3d 20 30 3b 0a  ->pLruNext = 0;.
6010: 20 20 20 20 2a 28 76 6f 69 64 20 2a 2a 29 28 50      *(void **)(P
6020: 47 48 44 52 31 5f 54 4f 5f 50 41 47 45 28 70 50  GHDR1_TO_PAGE(pP
6030: 61 67 65 29 29 20 3d 20 30 3b 0a 20 20 20 20 70  age)) = 0;.    p
6040: 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d  Cache->apHash[h]
6050: 20 3d 20 70 50 61 67 65 3b 0a 20 20 7d 0a 0a 66   = pPage;.  }..f
6060: 65 74 63 68 5f 6f 75 74 3a 0a 20 20 69 66 28 20  etch_out:.  if( 
6070: 70 50 61 67 65 20 26 26 20 69 4b 65 79 3e 70 43  pPage && iKey>pC
6080: 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 29 7b  ache->iMaxKey ){
6090: 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 69 4d 61  .    pCache->iMa
60a0: 78 4b 65 79 20 3d 20 69 4b 65 79 3b 0a 20 20 7d  xKey = iKey;.  }
60b0: 0a 20 20 69 66 28 20 63 72 65 61 74 65 46 6c 61  .  if( createFla
60c0: 67 3d 3d 31 20 29 20 73 71 6c 69 74 65 33 45 6e  g==1 ) sqlite3En
60d0: 64 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b  dBenignMalloc();
60e0: 0a 20 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d  .  pcache1LeaveM
60f0: 75 74 65 78 28 70 47 72 6f 75 70 29 3b 0a 20 20  utex(pGroup);.  
6100: 72 65 74 75 72 6e 20 28 70 50 61 67 65 20 3f 20  return (pPage ? 
6110: 50 47 48 44 52 31 5f 54 4f 5f 50 41 47 45 28 70  PGHDR1_TO_PAGE(p
6120: 50 61 67 65 29 20 3a 20 30 29 3b 0a 7d 0a 0a 0a  Page) : 0);.}...
6130: 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61  /*.** Implementa
6140: 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69  tion of the sqli
6150: 74 65 33 5f 70 63 61 63 68 65 2e 78 55 6e 70 69  te3_pcache.xUnpi
6160: 6e 20 6d 65 74 68 6f 64 2e 0a 2a 2a 0a 2a 2a 20  n method..**.** 
6170: 4d 61 72 6b 20 61 20 70 61 67 65 20 61 73 20 75  Mark a page as u
6180: 6e 70 69 6e 6e 65 64 20 28 65 6c 69 67 69 62 6c  npinned (eligibl
6190: 65 20 66 6f 72 20 61 73 79 6e 63 68 72 6f 6e 6f  e for asynchrono
61a0: 75 73 20 72 65 63 79 63 6c 69 6e 67 29 2e 0a 2a  us recycling)..*
61b0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63  /.static void pc
61c0: 61 63 68 65 31 55 6e 70 69 6e 28 73 71 6c 69 74  ache1Unpin(sqlit
61d0: 65 33 5f 70 63 61 63 68 65 20 2a 70 2c 20 76 6f  e3_pcache *p, vo
61e0: 69 64 20 2a 70 50 67 2c 20 69 6e 74 20 72 65 75  id *pPg, int reu
61f0: 73 65 55 6e 6c 69 6b 65 6c 79 29 7b 0a 20 20 50  seUnlikely){.  P
6200: 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d  Cache1 *pCache =
6210: 20 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20   (PCache1 *)p;. 
6220: 20 50 67 48 64 72 31 20 2a 70 50 61 67 65 20 3d   PgHdr1 *pPage =
6230: 20 50 41 47 45 5f 54 4f 5f 50 47 48 44 52 31 28   PAGE_TO_PGHDR1(
6240: 70 43 61 63 68 65 2c 20 70 50 67 29 3b 0a 20 20  pCache, pPg);.  
6250: 50 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 20 3d  PGroup *pGroup =
6260: 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b   pCache->pGroup;
6270: 0a 20 0a 20 20 61 73 73 65 72 74 28 20 70 50 61  . .  assert( pPa
6280: 67 65 2d 3e 70 43 61 63 68 65 3d 3d 70 43 61 63  ge->pCache==pCac
6290: 68 65 20 29 3b 0a 20 20 70 63 61 63 68 65 31 45  he );.  pcache1E
62a0: 6e 74 65 72 4d 75 74 65 78 28 70 47 72 6f 75 70  nterMutex(pGroup
62b0: 29 3b 0a 0a 20 20 2f 2a 20 49 74 20 69 73 20 61  );..  /* It is a
62c0: 6e 20 65 72 72 6f 72 20 74 6f 20 63 61 6c 6c 20  n error to call 
62d0: 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 66  this function if
62e0: 20 74 68 65 20 70 61 67 65 20 69 73 20 61 6c 72   the page is alr
62f0: 65 61 64 79 20 0a 20 20 2a 2a 20 70 61 72 74 20  eady .  ** part 
6300: 6f 66 20 74 68 65 20 50 47 72 6f 75 70 20 4c 52  of the PGroup LR
6310: 55 20 6c 69 73 74 2e 0a 20 20 2a 2f 0a 20 20 61  U list..  */.  a
6320: 73 73 65 72 74 28 20 70 50 61 67 65 2d 3e 70 4c  ssert( pPage->pL
6330: 72 75 50 72 65 76 3d 3d 30 20 26 26 20 70 50 61  ruPrev==0 && pPa
6340: 67 65 2d 3e 70 4c 72 75 4e 65 78 74 3d 3d 30 20  ge->pLruNext==0 
6350: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 47 72  );.  assert( pGr
6360: 6f 75 70 2d 3e 70 4c 72 75 48 65 61 64 21 3d 70  oup->pLruHead!=p
6370: 50 61 67 65 20 26 26 20 70 47 72 6f 75 70 2d 3e  Page && pGroup->
6380: 70 4c 72 75 54 61 69 6c 21 3d 70 50 61 67 65 20  pLruTail!=pPage 
6390: 29 3b 0a 0a 20 20 69 66 28 20 72 65 75 73 65 55  );..  if( reuseU
63a0: 6e 6c 69 6b 65 6c 79 20 7c 7c 20 70 47 72 6f 75  nlikely || pGrou
63b0: 70 2d 3e 6e 43 75 72 72 65 6e 74 50 61 67 65 3e  p->nCurrentPage>
63c0: 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65  pGroup->nMaxPage
63d0: 20 29 7b 0a 20 20 20 20 70 63 61 63 68 65 31 52   ){.    pcache1R
63e0: 65 6d 6f 76 65 46 72 6f 6d 48 61 73 68 28 70 50  emoveFromHash(pP
63f0: 61 67 65 29 3b 0a 20 20 20 20 70 63 61 63 68 65  age);.    pcache
6400: 31 46 72 65 65 50 61 67 65 28 70 50 61 67 65 29  1FreePage(pPage)
6410: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 2f  ;.  }else{.    /
6420: 2a 20 41 64 64 20 74 68 65 20 70 61 67 65 20 74  * Add the page t
6430: 6f 20 74 68 65 20 50 47 72 6f 75 70 20 4c 52 55  o the PGroup LRU
6440: 20 6c 69 73 74 2e 20 2a 2f 0a 20 20 20 20 69 66   list. */.    if
6450: 28 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 48 65  ( pGroup->pLruHe
6460: 61 64 20 29 7b 0a 20 20 20 20 20 20 70 47 72 6f  ad ){.      pGro
6470: 75 70 2d 3e 70 4c 72 75 48 65 61 64 2d 3e 70 4c  up->pLruHead->pL
6480: 72 75 50 72 65 76 20 3d 20 70 50 61 67 65 3b 0a  ruPrev = pPage;.
6490: 20 20 20 20 20 20 70 50 61 67 65 2d 3e 70 4c 72        pPage->pLr
64a0: 75 4e 65 78 74 20 3d 20 70 47 72 6f 75 70 2d 3e  uNext = pGroup->
64b0: 70 4c 72 75 48 65 61 64 3b 0a 20 20 20 20 20 20  pLruHead;.      
64c0: 70 47 72 6f 75 70 2d 3e 70 4c 72 75 48 65 61 64  pGroup->pLruHead
64d0: 20 3d 20 70 50 61 67 65 3b 0a 20 20 20 20 7d 65   = pPage;.    }e
64e0: 6c 73 65 7b 0a 20 20 20 20 20 20 70 47 72 6f 75  lse{.      pGrou
64f0: 70 2d 3e 70 4c 72 75 54 61 69 6c 20 3d 20 70 50  p->pLruTail = pP
6500: 61 67 65 3b 0a 20 20 20 20 20 20 70 47 72 6f 75  age;.      pGrou
6510: 70 2d 3e 70 4c 72 75 48 65 61 64 20 3d 20 70 50  p->pLruHead = pP
6520: 61 67 65 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70  age;.    }.    p
6530: 43 61 63 68 65 2d 3e 6e 52 65 63 79 63 6c 61 62  Cache->nRecyclab
6540: 6c 65 2b 2b 3b 0a 20 20 7d 0a 0a 20 20 70 63 61  le++;.  }..  pca
6550: 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 70  che1LeaveMutex(p
6560: 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a  Cache->pGroup);.
6570: 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65  }../*.** Impleme
6580: 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73  ntation of the s
6590: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78 52  qlite3_pcache.xR
65a0: 65 6b 65 79 20 6d 65 74 68 6f 64 2e 20 0a 2a 2f  ekey method. .*/
65b0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61  .static void pca
65c0: 63 68 65 31 52 65 6b 65 79 28 0a 20 20 73 71 6c  che1Rekey(.  sql
65d0: 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70 2c 0a  ite3_pcache *p,.
65e0: 20 20 76 6f 69 64 20 2a 70 50 67 2c 0a 20 20 75    void *pPg,.  u
65f0: 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4f 6c 64  nsigned int iOld
6600: 2c 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74  ,.  unsigned int
6610: 20 69 4e 65 77 0a 29 7b 0a 20 20 50 43 61 63 68   iNew.){.  PCach
6620: 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43  e1 *pCache = (PC
6630: 61 63 68 65 31 20 2a 29 70 3b 0a 20 20 50 67 48  ache1 *)p;.  PgH
6640: 64 72 31 20 2a 70 50 61 67 65 20 3d 20 50 41 47  dr1 *pPage = PAG
6650: 45 5f 54 4f 5f 50 47 48 44 52 31 28 70 43 61 63  E_TO_PGHDR1(pCac
6660: 68 65 2c 20 70 50 67 29 3b 0a 20 20 50 67 48 64  he, pPg);.  PgHd
6670: 72 31 20 2a 2a 70 70 3b 0a 20 20 75 6e 73 69 67  r1 **pp;.  unsig
6680: 6e 65 64 20 69 6e 74 20 68 3b 20 0a 20 20 61 73  ned int h; .  as
6690: 73 65 72 74 28 20 70 50 61 67 65 2d 3e 69 4b 65  sert( pPage->iKe
66a0: 79 3d 3d 69 4f 6c 64 20 29 3b 0a 20 20 61 73 73  y==iOld );.  ass
66b0: 65 72 74 28 20 70 50 61 67 65 2d 3e 70 43 61 63  ert( pPage->pCac
66c0: 68 65 3d 3d 70 43 61 63 68 65 20 29 3b 0a 0a 20  he==pCache );.. 
66d0: 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74   pcache1EnterMut
66e0: 65 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75  ex(pCache->pGrou
66f0: 70 29 3b 0a 0a 20 20 68 20 3d 20 69 4f 6c 64 25  p);..  h = iOld%
6700: 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20  pCache->nHash;. 
6710: 20 70 70 20 3d 20 26 70 43 61 63 68 65 2d 3e 61   pp = &pCache->a
6720: 70 48 61 73 68 5b 68 5d 3b 0a 20 20 77 68 69 6c  pHash[h];.  whil
6730: 65 28 20 28 2a 70 70 29 21 3d 70 50 61 67 65 20  e( (*pp)!=pPage 
6740: 29 7b 0a 20 20 20 20 70 70 20 3d 20 26 28 2a 70  ){.    pp = &(*p
6750: 70 29 2d 3e 70 4e 65 78 74 3b 0a 20 20 7d 0a 20  p)->pNext;.  }. 
6760: 20 2a 70 70 20 3d 20 70 50 61 67 65 2d 3e 70 4e   *pp = pPage->pN
6770: 65 78 74 3b 0a 0a 20 20 68 20 3d 20 69 4e 65 77  ext;..  h = iNew
6780: 25 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3b 0a  %pCache->nHash;.
6790: 20 20 70 50 61 67 65 2d 3e 69 4b 65 79 20 3d 20    pPage->iKey = 
67a0: 69 4e 65 77 3b 0a 20 20 70 50 61 67 65 2d 3e 70  iNew;.  pPage->p
67b0: 4e 65 78 74 20 3d 20 70 43 61 63 68 65 2d 3e 61  Next = pCache->a
67c0: 70 48 61 73 68 5b 68 5d 3b 0a 20 20 70 43 61 63  pHash[h];.  pCac
67d0: 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 20 3d 20  he->apHash[h] = 
67e0: 70 50 61 67 65 3b 0a 20 20 69 66 28 20 69 4e 65  pPage;.  if( iNe
67f0: 77 3e 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b 65  w>pCache->iMaxKe
6800: 79 20 29 7b 0a 20 20 20 20 70 43 61 63 68 65 2d  y ){.    pCache-
6810: 3e 69 4d 61 78 4b 65 79 20 3d 20 69 4e 65 77 3b  >iMaxKey = iNew;
6820: 0a 20 20 7d 0a 0a 20 20 70 63 61 63 68 65 31 4c  .  }..  pcache1L
6830: 65 61 76 65 4d 75 74 65 78 28 70 43 61 63 68 65  eaveMutex(pCache
6840: 2d 3e 70 47 72 6f 75 70 29 3b 0a 7d 0a 0a 2f 2a  ->pGroup);.}../*
6850: 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69  .** Implementati
6860: 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65  on of the sqlite
6870: 33 5f 70 63 61 63 68 65 2e 78 54 72 75 6e 63 61  3_pcache.xTrunca
6880: 74 65 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a  te method. .**.*
6890: 2a 20 44 69 73 63 61 72 64 20 61 6c 6c 20 75 6e  * Discard all un
68a0: 70 69 6e 6e 65 64 20 70 61 67 65 73 20 69 6e 20  pinned pages in 
68b0: 74 68 65 20 63 61 63 68 65 20 77 69 74 68 20 61  the cache with a
68c0: 20 70 61 67 65 20 6e 75 6d 62 65 72 20 65 71 75   page number equ
68d0: 61 6c 20 74 6f 0a 2a 2a 20 6f 72 20 67 72 65 61  al to.** or grea
68e0: 74 65 72 20 74 68 61 6e 20 70 61 72 61 6d 65 74  ter than paramet
68f0: 65 72 20 69 4c 69 6d 69 74 2e 20 41 6e 79 20 70  er iLimit. Any p
6900: 69 6e 6e 65 64 20 70 61 67 65 73 20 77 69 74 68  inned pages with
6910: 20 61 20 70 61 67 65 20 6e 75 6d 62 65 72 0a 2a   a page number.*
6920: 2a 20 65 71 75 61 6c 20 74 6f 20 6f 72 20 67 72  * equal to or gr
6930: 65 61 74 65 72 20 74 68 61 6e 20 69 4c 69 6d 69  eater than iLimi
6940: 74 20 61 72 65 20 69 6d 70 6c 69 63 69 74 6c 79  t are implicitly
6950: 20 75 6e 70 69 6e 6e 65 64 2e 0a 2a 2f 0a 73 74   unpinned..*/.st
6960: 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65  atic void pcache
6970: 31 54 72 75 6e 63 61 74 65 28 73 71 6c 69 74 65  1Truncate(sqlite
6980: 33 5f 70 63 61 63 68 65 20 2a 70 2c 20 75 6e 73  3_pcache *p, uns
6990: 69 67 6e 65 64 20 69 6e 74 20 69 4c 69 6d 69 74  igned int iLimit
69a0: 29 7b 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43  ){.  PCache1 *pC
69b0: 61 63 68 65 20 3d 20 28 50 43 61 63 68 65 31 20  ache = (PCache1 
69c0: 2a 29 70 3b 0a 20 20 70 63 61 63 68 65 31 45 6e  *)p;.  pcache1En
69d0: 74 65 72 4d 75 74 65 78 28 70 43 61 63 68 65 2d  terMutex(pCache-
69e0: 3e 70 47 72 6f 75 70 29 3b 0a 20 20 69 66 28 20  >pGroup);.  if( 
69f0: 69 4c 69 6d 69 74 3c 3d 70 43 61 63 68 65 2d 3e  iLimit<=pCache->
6a00: 69 4d 61 78 4b 65 79 20 29 7b 0a 20 20 20 20 70  iMaxKey ){.    p
6a10: 63 61 63 68 65 31 54 72 75 6e 63 61 74 65 55 6e  cache1TruncateUn
6a20: 73 61 66 65 28 70 43 61 63 68 65 2c 20 69 4c 69  safe(pCache, iLi
6a30: 6d 69 74 29 3b 0a 20 20 20 20 70 43 61 63 68 65  mit);.    pCache
6a40: 2d 3e 69 4d 61 78 4b 65 79 20 3d 20 69 4c 69 6d  ->iMaxKey = iLim
6a50: 69 74 2d 31 3b 0a 20 20 7d 0a 20 20 70 63 61 63  it-1;.  }.  pcac
6a60: 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 70 43  he1LeaveMutex(pC
6a70: 61 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 7d  ache->pGroup);.}
6a80: 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e  ../*.** Implemen
6a90: 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71  tation of the sq
6aa0: 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78 44 65  lite3_pcache.xDe
6ab0: 73 74 72 6f 79 20 6d 65 74 68 6f 64 2e 20 0a 2a  stroy method. .*
6ac0: 2a 0a 2a 2a 20 44 65 73 74 72 6f 79 20 61 20 63  *.** Destroy a c
6ad0: 61 63 68 65 20 61 6c 6c 6f 63 61 74 65 64 20 75  ache allocated u
6ae0: 73 69 6e 67 20 70 63 61 63 68 65 31 43 72 65 61  sing pcache1Crea
6af0: 74 65 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  te()..*/.static 
6b00: 76 6f 69 64 20 70 63 61 63 68 65 31 44 65 73 74  void pcache1Dest
6b10: 72 6f 79 28 73 71 6c 69 74 65 33 5f 70 63 61 63  roy(sqlite3_pcac
6b20: 68 65 20 2a 70 29 7b 0a 20 20 50 43 61 63 68 65  he *p){.  PCache
6b30: 31 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61  1 *pCache = (PCa
6b40: 63 68 65 31 20 2a 29 70 3b 0a 20 20 50 47 72 6f  che1 *)p;.  PGro
6b50: 75 70 20 2a 70 47 72 6f 75 70 20 3d 20 70 43 61  up *pGroup = pCa
6b60: 63 68 65 2d 3e 70 47 72 6f 75 70 3b 0a 20 20 61  che->pGroup;.  a
6b70: 73 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e 62  ssert( pCache->b
6b80: 50 75 72 67 65 61 62 6c 65 20 7c 7c 20 28 70 43  Purgeable || (pC
6b90: 61 63 68 65 2d 3e 6e 4d 61 78 3d 3d 30 20 26 26  ache->nMax==0 &&
6ba0: 20 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 3d 3d 30   pCache->nMin==0
6bb0: 29 20 29 3b 0a 20 20 70 63 61 63 68 65 31 45 6e  ) );.  pcache1En
6bc0: 74 65 72 4d 75 74 65 78 28 70 47 72 6f 75 70 29  terMutex(pGroup)
6bd0: 3b 0a 20 20 70 63 61 63 68 65 31 54 72 75 6e 63  ;.  pcache1Trunc
6be0: 61 74 65 55 6e 73 61 66 65 28 70 43 61 63 68 65  ateUnsafe(pCache
6bf0: 2c 20 30 29 3b 0a 20 20 70 47 72 6f 75 70 2d 3e  , 0);.  pGroup->
6c00: 6e 4d 61 78 50 61 67 65 20 2d 3d 20 70 43 61 63  nMaxPage -= pCac
6c10: 68 65 2d 3e 6e 4d 61 78 3b 0a 20 20 70 47 72 6f  he->nMax;.  pGro
6c20: 75 70 2d 3e 6e 4d 69 6e 50 61 67 65 20 2d 3d 20  up->nMinPage -= 
6c30: 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 3b 0a 20 20  pCache->nMin;.  
6c40: 70 63 61 63 68 65 31 45 6e 66 6f 72 63 65 4d 61  pcache1EnforceMa
6c50: 78 50 61 67 65 28 70 47 72 6f 75 70 29 3b 0a 20  xPage(pGroup);. 
6c60: 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74   pcache1LeaveMut
6c70: 65 78 28 70 47 72 6f 75 70 29 3b 0a 20 20 73 71  ex(pGroup);.  sq
6c80: 6c 69 74 65 33 5f 66 72 65 65 28 70 43 61 63 68  lite3_free(pCach
6c90: 65 2d 3e 61 70 48 61 73 68 29 3b 0a 20 20 73 71  e->apHash);.  sq
6ca0: 6c 69 74 65 33 5f 66 72 65 65 28 70 43 61 63 68  lite3_free(pCach
6cb0: 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69  e);.}../*.** Thi
6cc0: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61  s function is ca
6cd0: 6c 6c 65 64 20 64 75 72 69 6e 67 20 69 6e 69 74  lled during init
6ce0: 69 61 6c 69 7a 61 74 69 6f 6e 20 28 73 71 6c 69  ialization (sqli
6cf0: 74 65 33 5f 69 6e 69 74 69 61 6c 69 7a 65 28 29  te3_initialize()
6d00: 29 20 74 6f 0a 2a 2a 20 69 6e 73 74 61 6c 6c 20  ) to.** install 
6d10: 74 68 65 20 64 65 66 61 75 6c 74 20 70 6c 75 67  the default plug
6d20: 67 61 62 6c 65 20 63 61 63 68 65 20 6d 6f 64 75  gable cache modu
6d30: 6c 65 2c 20 61 73 73 75 6d 69 6e 67 20 74 68 65  le, assuming the
6d40: 20 75 73 65 72 20 68 61 73 20 6e 6f 74 0a 2a 2a   user has not.**
6d50: 20 61 6c 72 65 61 64 79 20 70 72 6f 76 69 64 65   already provide
6d60: 64 20 61 6e 20 61 6c 74 65 72 6e 61 74 69 76 65  d an alternative
6d70: 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
6d80: 33 50 43 61 63 68 65 53 65 74 44 65 66 61 75 6c  3PCacheSetDefaul
6d90: 74 28 76 6f 69 64 29 7b 0a 20 20 73 74 61 74 69  t(void){.  stati
6da0: 63 20 63 6f 6e 73 74 20 73 71 6c 69 74 65 33 5f  c const sqlite3_
6db0: 70 63 61 63 68 65 5f 6d 65 74 68 6f 64 73 20 64  pcache_methods d
6dc0: 65 66 61 75 6c 74 4d 65 74 68 6f 64 73 20 3d 20  efaultMethods = 
6dd0: 7b 0a 20 20 20 20 30 2c 20 20 20 20 20 20 20 20  {.    0,        
6de0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
6df0: 2a 20 70 41 72 67 20 2a 2f 0a 20 20 20 20 70 63  * pArg */.    pc
6e00: 61 63 68 65 31 49 6e 69 74 2c 20 20 20 20 20 20  ache1Init,      
6e10: 20 20 20 20 20 20 20 2f 2a 20 78 49 6e 69 74 20         /* xInit 
6e20: 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31 53 68  */.    pcache1Sh
6e30: 75 74 64 6f 77 6e 2c 20 20 20 20 20 20 20 20 20  utdown,         
6e40: 2f 2a 20 78 53 68 75 74 64 6f 77 6e 20 2a 2f 0a  /* xShutdown */.
6e50: 20 20 20 20 70 63 61 63 68 65 31 43 72 65 61 74      pcache1Creat
6e60: 65 2c 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  e,           /* 
6e70: 78 43 72 65 61 74 65 20 2a 2f 0a 20 20 20 20 70  xCreate */.    p
6e80: 63 61 63 68 65 31 43 61 63 68 65 73 69 7a 65 2c  cache1Cachesize,
6e90: 20 20 20 20 20 20 20 20 2f 2a 20 78 43 61 63 68          /* xCach
6ea0: 65 73 69 7a 65 20 2a 2f 0a 20 20 20 20 70 63 61  esize */.    pca
6eb0: 63 68 65 31 50 61 67 65 63 6f 75 6e 74 2c 20 20  che1Pagecount,  
6ec0: 20 20 20 20 20 20 2f 2a 20 78 50 61 67 65 63 6f        /* xPageco
6ed0: 75 6e 74 20 2a 2f 0a 20 20 20 20 70 63 61 63 68  unt */.    pcach
6ee0: 65 31 46 65 74 63 68 2c 20 20 20 20 20 20 20 20  e1Fetch,        
6ef0: 20 20 20 20 2f 2a 20 78 46 65 74 63 68 20 2a 2f      /* xFetch */
6f00: 0a 20 20 20 20 70 63 61 63 68 65 31 55 6e 70 69  .    pcache1Unpi
6f10: 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  n,            /*
6f20: 20 78 55 6e 70 69 6e 20 2a 2f 0a 20 20 20 20 70   xUnpin */.    p
6f30: 63 61 63 68 65 31 52 65 6b 65 79 2c 20 20 20 20  cache1Rekey,    
6f40: 20 20 20 20 20 20 20 20 2f 2a 20 78 52 65 6b 65          /* xReke
6f50: 79 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31  y */.    pcache1
6f60: 54 72 75 6e 63 61 74 65 2c 20 20 20 20 20 20 20  Truncate,       
6f70: 20 20 2f 2a 20 78 54 72 75 6e 63 61 74 65 20 2a    /* xTruncate *
6f80: 2f 0a 20 20 20 20 70 63 61 63 68 65 31 44 65 73  /.    pcache1Des
6f90: 74 72 6f 79 20 20 20 20 20 20 20 20 20 20 20 2f  troy           /
6fa0: 2a 20 78 44 65 73 74 72 6f 79 20 2a 2f 0a 20 20  * xDestroy */.  
6fb0: 7d 3b 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e  };.  sqlite3_con
6fc0: 66 69 67 28 53 51 4c 49 54 45 5f 43 4f 4e 46 49  fig(SQLITE_CONFI
6fd0: 47 5f 50 43 41 43 48 45 2c 20 26 64 65 66 61 75  G_PCACHE, &defau
6fe0: 6c 74 4d 65 74 68 6f 64 73 29 3b 0a 7d 0a 0a 23  ltMethods);.}..#
6ff0: 69 66 64 65 66 20 53 51 4c 49 54 45 5f 45 4e 41  ifdef SQLITE_ENA
7000: 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47  BLE_MEMORY_MANAG
7010: 45 4d 45 4e 54 0a 2f 2a 0a 2a 2a 20 54 68 69 73  EMENT./*.** This
7020: 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c   function is cal
7030: 6c 65 64 20 74 6f 20 66 72 65 65 20 73 75 70 65  led to free supe
7040: 72 66 6c 75 6f 75 73 20 64 79 6e 61 6d 69 63 61  rfluous dynamica
7050: 6c 6c 79 20 61 6c 6c 6f 63 61 74 65 64 20 6d 65  lly allocated me
7060: 6d 6f 72 79 0a 2a 2a 20 68 65 6c 64 20 62 79 20  mory.** held by 
7070: 74 68 65 20 70 61 67 65 72 20 73 79 73 74 65 6d  the pager system
7080: 2e 20 4d 65 6d 6f 72 79 20 69 6e 20 75 73 65 20  . Memory in use 
7090: 62 79 20 61 6e 79 20 53 51 4c 69 74 65 20 70 61  by any SQLite pa
70a0: 67 65 72 20 61 6c 6c 6f 63 61 74 65 64 0a 2a 2a  ger allocated.**
70b0: 20 62 79 20 74 68 65 20 63 75 72 72 65 6e 74 20   by the current 
70c0: 74 68 72 65 61 64 20 6d 61 79 20 62 65 20 73 71  thread may be sq
70d0: 6c 69 74 65 33 5f 66 72 65 65 28 29 65 64 2e 0a  lite3_free()ed..
70e0: 2a 2a 0a 2a 2a 20 6e 52 65 71 20 69 73 20 74 68  **.** nReq is th
70f0: 65 20 6e 75 6d 62 65 72 20 6f 66 20 62 79 74 65  e number of byte
7100: 73 20 6f 66 20 6d 65 6d 6f 72 79 20 72 65 71 75  s of memory requ
7110: 69 72 65 64 2e 20 4f 6e 63 65 20 74 68 69 73 20  ired. Once this 
7120: 6d 75 63 68 20 68 61 73 0a 2a 2a 20 62 65 65 6e  much has.** been
7130: 20 72 65 6c 65 61 73 65 64 2c 20 74 68 65 20 66   released, the f
7140: 75 6e 63 74 69 6f 6e 20 72 65 74 75 72 6e 73 2e  unction returns.
7150: 20 54 68 65 20 72 65 74 75 72 6e 20 76 61 6c 75   The return valu
7160: 65 20 69 73 20 74 68 65 20 74 6f 74 61 6c 20 6e  e is the total n
7170: 75 6d 62 65 72 20 0a 2a 2a 20 6f 66 20 62 79 74  umber .** of byt
7180: 65 73 20 6f 66 20 6d 65 6d 6f 72 79 20 72 65 6c  es of memory rel
7190: 65 61 73 65 64 2e 0a 2a 2f 0a 69 6e 74 20 73 71  eased..*/.int sq
71a0: 6c 69 74 65 33 50 63 61 63 68 65 52 65 6c 65 61  lite3PcacheRelea
71b0: 73 65 4d 65 6d 6f 72 79 28 69 6e 74 20 6e 52 65  seMemory(int nRe
71c0: 71 29 7b 0a 20 20 69 6e 74 20 6e 46 72 65 65 20  q){.  int nFree 
71d0: 3d 20 30 3b 0a 20 20 61 73 73 65 72 74 28 20 73  = 0;.  assert( s
71e0: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6e 6f 74  qlite3_mutex_not
71f0: 68 65 6c 64 28 70 63 61 63 68 65 31 2e 67 72 70  held(pcache1.grp
7200: 2e 6d 75 74 65 78 29 20 29 3b 0a 20 20 61 73 73  .mutex) );.  ass
7210: 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74  ert( sqlite3_mut
7220: 65 78 5f 6e 6f 74 68 65 6c 64 28 70 63 61 63 68  ex_notheld(pcach
7230: 65 31 2e 6d 75 74 65 78 29 20 29 3b 0a 20 20 69  e1.mutex) );.  i
7240: 66 28 20 70 63 61 63 68 65 31 2e 70 53 74 61 72  f( pcache1.pStar
7250: 74 3d 3d 30 20 29 7b 0a 20 20 20 20 50 67 48 64  t==0 ){.    PgHd
7260: 72 31 20 2a 70 3b 0a 20 20 20 20 70 63 61 63 68  r1 *p;.    pcach
7270: 65 31 45 6e 74 65 72 4d 75 74 65 78 28 26 70 63  e1EnterMutex(&pc
7280: 61 63 68 65 31 2e 67 72 70 29 3b 0a 20 20 20 20  ache1.grp);.    
7290: 77 68 69 6c 65 28 20 28 6e 52 65 71 3c 30 20 7c  while( (nReq<0 |
72a0: 7c 20 6e 46 72 65 65 3c 6e 52 65 71 29 20 26 26  | nFree<nReq) &&
72b0: 20 28 28 70 3d 70 63 61 63 68 65 31 2e 67 72 70   ((p=pcache1.grp
72c0: 2e 70 4c 72 75 54 61 69 6c 29 21 3d 30 29 20 29  .pLruTail)!=0) )
72d0: 7b 0a 20 20 20 20 20 20 6e 46 72 65 65 20 2b 3d  {.      nFree +=
72e0: 20 70 63 61 63 68 65 31 4d 65 6d 53 69 7a 65 28   pcache1MemSize(
72f0: 50 47 48 44 52 31 5f 54 4f 5f 50 41 47 45 28 70  PGHDR1_TO_PAGE(p
7300: 29 29 3b 0a 20 20 20 20 20 20 70 63 61 63 68 65  ));.      pcache
7310: 31 50 69 6e 50 61 67 65 28 70 29 3b 0a 20 20 20  1PinPage(p);.   
7320: 20 20 20 70 63 61 63 68 65 31 52 65 6d 6f 76 65     pcache1Remove
7330: 46 72 6f 6d 48 61 73 68 28 70 29 3b 0a 20 20 20  FromHash(p);.   
7340: 20 20 20 70 63 61 63 68 65 31 46 72 65 65 50 61     pcache1FreePa
7350: 67 65 28 70 29 3b 0a 20 20 20 20 7d 0a 20 20 20  ge(p);.    }.   
7360: 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74   pcache1LeaveMut
7370: 65 78 28 26 70 63 61 63 68 65 31 2e 67 72 70 29  ex(&pcache1.grp)
7380: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 6e  ;.  }.  return n
7390: 46 72 65 65 3b 0a 7d 0a 23 65 6e 64 69 66 20 2f  Free;.}.#endif /
73a0: 2a 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f  * SQLITE_ENABLE_
73b0: 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e  MEMORY_MANAGEMEN
73c0: 54 20 2a 2f 0a 0a 23 69 66 64 65 66 20 53 51 4c  T */..#ifdef SQL
73d0: 49 54 45 5f 54 45 53 54 0a 2f 2a 0a 2a 2a 20 54  ITE_TEST./*.** T
73e0: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
73f0: 75 73 65 64 20 62 79 20 74 65 73 74 20 70 72 6f  used by test pro
7400: 63 65 64 75 72 65 73 20 74 6f 20 69 6e 73 70 65  cedures to inspe
7410: 63 74 20 74 68 65 20 69 6e 74 65 72 6e 61 6c 20  ct the internal 
7420: 73 74 61 74 65 0a 2a 2a 20 6f 66 20 74 68 65 20  state.** of the 
7430: 67 6c 6f 62 61 6c 20 63 61 63 68 65 2e 0a 2a 2f  global cache..*/
7440: 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63 61  .void sqlite3Pca
7450: 63 68 65 53 74 61 74 73 28 0a 20 20 69 6e 74 20  cheStats(.  int 
7460: 2a 70 6e 43 75 72 72 65 6e 74 2c 20 20 20 20 20  *pnCurrent,     
7470: 20 2f 2a 20 4f 55 54 3a 20 54 6f 74 61 6c 20 6e   /* OUT: Total n
7480: 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 63  umber of pages c
7490: 61 63 68 65 64 20 2a 2f 0a 20 20 69 6e 74 20 2a  ached */.  int *
74a0: 70 6e 4d 61 78 2c 20 20 20 20 20 20 20 20 20 20  pnMax,          
74b0: 2f 2a 20 4f 55 54 3a 20 47 6c 6f 62 61 6c 20 6d  /* OUT: Global m
74c0: 61 78 69 6d 75 6d 20 63 61 63 68 65 20 73 69 7a  aximum cache siz
74d0: 65 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 4d 69  e */.  int *pnMi
74e0: 6e 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f  n,          /* O
74f0: 55 54 3a 20 53 75 6d 20 6f 66 20 50 43 61 63 68  UT: Sum of PCach
7500: 65 31 2e 6e 4d 69 6e 20 66 6f 72 20 70 75 72 67  e1.nMin for purg
7510: 65 61 62 6c 65 20 63 61 63 68 65 73 20 2a 2f 0a  eable caches */.
7520: 20 20 69 6e 74 20 2a 70 6e 52 65 63 79 63 6c 61    int *pnRecycla
7530: 62 6c 65 20 20 20 20 2f 2a 20 4f 55 54 3a 20 54  ble    /* OUT: T
7540: 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 70  otal number of p
7550: 61 67 65 73 20 61 76 61 69 6c 61 62 6c 65 20 66  ages available f
7560: 6f 72 20 72 65 63 79 63 6c 69 6e 67 20 2a 2f 0a  or recycling */.
7570: 29 7b 0a 20 20 50 67 48 64 72 31 20 2a 70 3b 0a  ){.  PgHdr1 *p;.
7580: 20 20 69 6e 74 20 6e 52 65 63 79 63 6c 61 62 6c    int nRecyclabl
7590: 65 20 3d 20 30 3b 0a 20 20 66 6f 72 28 70 3d 70  e = 0;.  for(p=p
75a0: 63 61 63 68 65 31 2e 67 72 70 2e 70 4c 72 75 48  cache1.grp.pLruH
75b0: 65 61 64 3b 20 70 3b 20 70 3d 70 2d 3e 70 4c 72  ead; p; p=p->pLr
75c0: 75 4e 65 78 74 29 7b 0a 20 20 20 20 6e 52 65 63  uNext){.    nRec
75d0: 79 63 6c 61 62 6c 65 2b 2b 3b 0a 20 20 7d 0a 20  yclable++;.  }. 
75e0: 20 2a 70 6e 43 75 72 72 65 6e 74 20 3d 20 70 63   *pnCurrent = pc
75f0: 61 63 68 65 31 2e 67 72 70 2e 6e 43 75 72 72 65  ache1.grp.nCurre
7600: 6e 74 50 61 67 65 3b 0a 20 20 2a 70 6e 4d 61 78  ntPage;.  *pnMax
7610: 20 3d 20 70 63 61 63 68 65 31 2e 67 72 70 2e 6e   = pcache1.grp.n
7620: 4d 61 78 50 61 67 65 3b 0a 20 20 2a 70 6e 4d 69  MaxPage;.  *pnMi
7630: 6e 20 3d 20 70 63 61 63 68 65 31 2e 67 72 70 2e  n = pcache1.grp.
7640: 6e 4d 69 6e 50 61 67 65 3b 0a 20 20 2a 70 6e 52  nMinPage;.  *pnR
7650: 65 63 79 63 6c 61 62 6c 65 20 3d 20 6e 52 65 63  ecyclable = nRec
7660: 79 63 6c 61 62 6c 65 3b 0a 7d 0a 23 65 6e 64 69  yclable;.}.#endi
7670: 66 0a                                            f.