/ Hex Artifact Content
Login

Artifact 7a3ce2dca0ef889be94b9cb0a2dfc7917ec83eba:


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 6d 78 50 69 6e 6e 65 64 3b 20 20 20 20  nt mxPinned;    
0810: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0820: 20 6e 4d 61 78 70 61 67 65 20 2b 20 31 30 20 2d   nMaxpage + 10 -
0830: 20 6e 4d 69 6e 50 61 67 65 20 2a 2f 0a 20 20 69   nMinPage */.  i
0840: 6e 74 20 6e 43 75 72 72 65 6e 74 50 61 67 65 3b  nt nCurrentPage;
0850: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0860: 20 4e 75 6d 62 65 72 20 6f 66 20 70 75 72 67 65   Number of purge
0870: 61 62 6c 65 20 70 61 67 65 73 20 61 6c 6c 6f 63  able pages alloc
0880: 61 74 65 64 20 2a 2f 0a 20 20 50 67 48 64 72 31  ated */.  PgHdr1
0890: 20 2a 70 4c 72 75 48 65 61 64 2c 20 2a 70 4c 72   *pLruHead, *pLr
08a0: 75 54 61 69 6c 3b 20 20 20 2f 2a 20 4c 52 55 20  uTail;   /* LRU 
08b0: 6c 69 73 74 20 6f 66 20 75 6e 70 69 6e 6e 65 64  list of unpinned
08c0: 20 70 61 67 65 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a   pages */.};../*
08d0: 20 45 61 63 68 20 70 61 67 65 20 63 61 63 68 65   Each page cache
08e0: 20 69 73 20 61 6e 20 69 6e 73 74 61 6e 63 65 20   is an instance 
08f0: 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  of the following
0900: 20 6f 62 6a 65 63 74 2e 20 20 45 76 65 72 79 0a   object.  Every.
0910: 2a 2a 20 6f 70 65 6e 20 64 61 74 61 62 61 73 65  ** open database
0920: 20 66 69 6c 65 20 28 69 6e 63 6c 75 64 69 6e 67   file (including
0930: 20 65 61 63 68 20 69 6e 2d 6d 65 6d 6f 72 79 20   each in-memory 
0940: 64 61 74 61 62 61 73 65 20 61 6e 64 20 65 61 63  database and eac
0950: 68 0a 2a 2a 20 74 65 6d 70 6f 72 61 72 79 20 6f  h.** temporary o
0960: 72 20 74 72 61 6e 73 69 65 6e 74 20 64 61 74 61  r transient data
0970: 62 61 73 65 29 20 68 61 73 20 61 20 73 69 6e 67  base) has a sing
0980: 6c 65 20 70 61 67 65 20 63 61 63 68 65 20 77 68  le page cache wh
0990: 69 63 68 0a 2a 2a 20 69 73 20 61 6e 20 69 6e 73  ich.** is an ins
09a0: 74 61 6e 63 65 20 6f 66 20 74 68 69 73 20 6f 62  tance of this ob
09b0: 6a 65 63 74 2e 0a 2a 2a 0a 2a 2a 20 50 6f 69 6e  ject..**.** Poin
09c0: 74 65 72 73 20 74 6f 20 73 74 72 75 63 74 75 72  ters to structur
09d0: 65 73 20 6f 66 20 74 68 69 73 20 74 79 70 65 20  es of this type 
09e0: 61 72 65 20 63 61 73 74 20 61 6e 64 20 72 65 74  are cast and ret
09f0: 75 72 6e 65 64 20 61 73 20 0a 2a 2a 20 6f 70 61  urned as .** opa
0a00: 71 75 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63  que sqlite3_pcac
0a10: 68 65 2a 20 68 61 6e 64 6c 65 73 2e 0a 2a 2f 0a  he* handles..*/.
0a20: 73 74 72 75 63 74 20 50 43 61 63 68 65 31 20 7b  struct PCache1 {
0a30: 0a 20 20 2f 2a 20 43 61 63 68 65 20 63 6f 6e 66  .  /* Cache conf
0a40: 69 67 75 72 61 74 69 6f 6e 20 70 61 72 61 6d 65  iguration parame
0a50: 74 65 72 73 2e 20 50 61 67 65 20 73 69 7a 65 20  ters. Page size 
0a60: 28 73 7a 50 61 67 65 29 20 61 6e 64 20 74 68 65  (szPage) and the
0a70: 20 70 75 72 67 65 61 62 6c 65 0a 20 20 2a 2a 20   purgeable.  ** 
0a80: 66 6c 61 67 20 28 62 50 75 72 67 65 61 62 6c 65  flag (bPurgeable
0a90: 29 20 61 72 65 20 73 65 74 20 77 68 65 6e 20 74  ) are set when t
0aa0: 68 65 20 63 61 63 68 65 20 69 73 20 63 72 65 61  he cache is crea
0ab0: 74 65 64 2e 20 6e 4d 61 78 20 6d 61 79 20 62 65  ted. nMax may be
0ac0: 20 0a 20 20 2a 2a 20 6d 6f 64 69 66 69 65 64 20   .  ** modified 
0ad0: 61 74 20 61 6e 79 20 74 69 6d 65 20 62 79 20 61  at any time by a
0ae0: 20 63 61 6c 6c 20 74 6f 20 74 68 65 20 70 63 61   call to the pca
0af0: 63 68 65 31 43 61 63 68 65 53 69 7a 65 28 29 20  che1CacheSize() 
0b00: 6d 65 74 68 6f 64 2e 0a 20 20 2a 2a 20 54 68 65  method..  ** The
0b10: 20 50 47 72 6f 75 70 20 6d 75 74 65 78 20 6d 75   PGroup mutex mu
0b20: 73 74 20 62 65 20 68 65 6c 64 20 77 68 65 6e 20  st be held when 
0b30: 61 63 63 65 73 73 69 6e 67 20 6e 4d 61 78 2e 0a  accessing nMax..
0b40: 20 20 2a 2f 0a 20 20 50 47 72 6f 75 70 20 2a 70    */.  PGroup *p
0b50: 47 72 6f 75 70 3b 20 20 20 20 20 20 20 20 20 20  Group;          
0b60: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 47             /* PG
0b70: 72 6f 75 70 20 74 68 69 73 20 63 61 63 68 65 20  roup this cache 
0b80: 62 65 6c 6f 6e 67 73 20 74 6f 20 2a 2f 0a 20 20  belongs to */.  
0b90: 69 6e 74 20 73 7a 50 61 67 65 3b 20 20 20 20 20  int szPage;     
0ba0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0bb0: 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 61      /* Size of a
0bc0: 6c 6c 6f 63 61 74 65 64 20 70 61 67 65 73 20 69  llocated pages i
0bd0: 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 69 6e 74  n bytes */.  int
0be0: 20 73 7a 45 78 74 72 61 3b 20 20 20 20 20 20 20   szExtra;       
0bf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c00: 20 2f 2a 20 53 69 7a 65 20 6f 66 20 65 78 74 72   /* Size of extr
0c10: 61 20 73 70 61 63 65 20 69 6e 20 62 79 74 65 73  a space in bytes
0c20: 20 2a 2f 0a 20 20 69 6e 74 20 62 50 75 72 67 65   */.  int bPurge
0c30: 61 62 6c 65 3b 20 20 20 20 20 20 20 20 20 20 20  able;           
0c40: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75            /* Tru
0c50: 65 20 69 66 20 63 61 63 68 65 20 69 73 20 70 75  e if cache is pu
0c60: 72 67 65 61 62 6c 65 20 2a 2f 0a 20 20 75 6e 73  rgeable */.  uns
0c70: 69 67 6e 65 64 20 69 6e 74 20 6e 4d 69 6e 3b 20  igned int nMin; 
0c80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c90: 20 2f 2a 20 4d 69 6e 69 6d 75 6d 20 6e 75 6d 62   /* Minimum numb
0ca0: 65 72 20 6f 66 20 70 61 67 65 73 20 72 65 73 65  er of pages rese
0cb0: 72 76 65 64 20 2a 2f 0a 20 20 75 6e 73 69 67 6e  rved */.  unsign
0cc0: 65 64 20 69 6e 74 20 6e 4d 61 78 3b 20 20 20 20  ed int nMax;    
0cd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0ce0: 20 43 6f 6e 66 69 67 75 72 65 64 20 22 63 61 63   Configured "cac
0cf0: 68 65 5f 73 69 7a 65 22 20 76 61 6c 75 65 20 2a  he_size" value *
0d00: 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74  /.  unsigned int
0d10: 20 6e 39 30 70 63 74 3b 20 20 20 20 20 20 20 20   n90pct;        
0d20: 20 20 20 20 20 20 20 20 2f 2a 20 6e 4d 61 78 2a          /* nMax*
0d30: 39 2f 31 30 20 2a 2f 0a 0a 20 20 2f 2a 20 48 61  9/10 */..  /* Ha
0d40: 73 68 20 74 61 62 6c 65 20 6f 66 20 61 6c 6c 20  sh table of all 
0d50: 70 61 67 65 73 2e 20 54 68 65 20 66 6f 6c 6c 6f  pages. The follo
0d60: 77 69 6e 67 20 76 61 72 69 61 62 6c 65 73 20 6d  wing variables m
0d70: 61 79 20 6f 6e 6c 79 20 62 65 20 61 63 63 65 73  ay only be acces
0d80: 73 65 64 0a 20 20 2a 2a 20 77 68 65 6e 20 74 68  sed.  ** when th
0d90: 65 20 61 63 63 65 73 73 6f 72 20 69 73 20 68 6f  e accessor is ho
0da0: 6c 64 69 6e 67 20 74 68 65 20 50 47 72 6f 75 70  lding the PGroup
0db0: 20 6d 75 74 65 78 2e 0a 20 20 2a 2f 0a 20 20 75   mutex..  */.  u
0dc0: 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 52 65 63  nsigned int nRec
0dd0: 79 63 6c 61 62 6c 65 3b 20 20 20 20 20 20 20 20  yclable;        
0de0: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
0df0: 70 61 67 65 73 20 69 6e 20 74 68 65 20 4c 52 55  pages in the LRU
0e00: 20 6c 69 73 74 20 2a 2f 0a 20 20 75 6e 73 69 67   list */.  unsig
0e10: 6e 65 64 20 69 6e 74 20 6e 50 61 67 65 3b 20 20  ned int nPage;  
0e20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0e30: 2a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f  * Total number o
0e40: 66 20 70 61 67 65 73 20 69 6e 20 61 70 48 61 73  f pages in apHas
0e50: 68 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20  h */.  unsigned 
0e60: 69 6e 74 20 6e 48 61 73 68 3b 20 20 20 20 20 20  int nHash;      
0e70: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
0e80: 6d 62 65 72 20 6f 66 20 73 6c 6f 74 73 20 69 6e  mber of slots in
0e90: 20 61 70 48 61 73 68 5b 5d 20 2a 2f 0a 20 20 50   apHash[] */.  P
0ea0: 67 48 64 72 31 20 2a 2a 61 70 48 61 73 68 3b 20  gHdr1 **apHash; 
0eb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ec0: 20 20 20 2f 2a 20 48 61 73 68 20 74 61 62 6c 65     /* Hash table
0ed0: 20 66 6f 72 20 66 61 73 74 20 6c 6f 6f 6b 75 70   for fast lookup
0ee0: 20 62 79 20 6b 65 79 20 2a 2f 0a 0a 20 20 75 6e   by key */..  un
0ef0: 73 69 67 6e 65 64 20 69 6e 74 20 69 4d 61 78 4b  signed int iMaxK
0f00: 65 79 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ey;             
0f10: 20 20 2f 2a 20 4c 61 72 67 65 73 74 20 6b 65 79    /* Largest key
0f20: 20 73 65 65 6e 20 73 69 6e 63 65 20 78 54 72 75   seen since xTru
0f30: 6e 63 61 74 65 28 29 20 2a 2f 0a 7d 3b 0a 0a 2f  ncate() */.};../
0f40: 2a 0a 2a 2a 20 45 61 63 68 20 63 61 63 68 65 20  *.** Each cache 
0f50: 65 6e 74 72 79 20 69 73 20 72 65 70 72 65 73 65  entry is represe
0f60: 6e 74 65 64 20 62 79 20 61 6e 20 69 6e 73 74 61  nted by an insta
0f70: 6e 63 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f  nce of the follo
0f80: 77 69 6e 67 20 0a 2a 2a 20 73 74 72 75 63 74 75  wing .** structu
0f90: 72 65 2e 20 55 6e 6c 65 73 73 20 53 51 4c 49 54  re. Unless SQLIT
0fa0: 45 5f 50 43 41 43 48 45 5f 53 45 50 41 52 41 54  E_PCACHE_SEPARAT
0fb0: 45 5f 48 45 41 44 45 52 20 69 73 20 64 65 66 69  E_HEADER is defi
0fc0: 6e 65 64 2c 20 61 20 62 75 66 66 65 72 20 6f 66  ned, a buffer of
0fd0: 0a 2a 2a 20 50 67 48 64 72 31 2e 70 43 61 63 68  .** PgHdr1.pCach
0fe0: 65 2d 3e 73 7a 50 61 67 65 20 62 79 74 65 73 20  e->szPage bytes 
0ff0: 69 73 20 61 6c 6c 6f 63 61 74 65 64 20 64 69 72  is allocated dir
1000: 65 63 74 6c 79 20 62 65 66 6f 72 65 20 74 68 69  ectly before thi
1010: 73 20 73 74 72 75 63 74 75 72 65 20 0a 2a 2a 20  s structure .** 
1020: 69 6e 20 6d 65 6d 6f 72 79 2e 0a 2a 2f 0a 73 74  in memory..*/.st
1030: 72 75 63 74 20 50 67 48 64 72 31 20 7b 0a 20 20  ruct PgHdr1 {.  
1040: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 5f 70  sqlite3_pcache_p
1050: 61 67 65 20 70 61 67 65 3b 0a 20 20 75 6e 73 69  age page;.  unsi
1060: 67 6e 65 64 20 69 6e 74 20 69 4b 65 79 3b 20 20  gned int iKey;  
1070: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4b 65             /* Ke
1080: 79 20 76 61 6c 75 65 20 28 70 61 67 65 20 6e 75  y value (page nu
1090: 6d 62 65 72 29 20 2a 2f 0a 20 20 50 67 48 64 72  mber) */.  PgHdr
10a0: 31 20 2a 70 4e 65 78 74 3b 20 20 20 20 20 20 20  1 *pNext;       
10b0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78            /* Nex
10c0: 74 20 69 6e 20 68 61 73 68 20 74 61 62 6c 65 20  t in hash table 
10d0: 63 68 61 69 6e 20 2a 2f 0a 20 20 50 43 61 63 68  chain */.  PCach
10e0: 65 31 20 2a 70 43 61 63 68 65 3b 20 20 20 20 20  e1 *pCache;     
10f0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 61 63            /* Cac
1100: 68 65 20 74 68 61 74 20 63 75 72 72 65 6e 74 6c  he that currentl
1110: 79 20 6f 77 6e 73 20 74 68 69 73 20 70 61 67 65  y owns this page
1120: 20 2a 2f 0a 20 20 50 67 48 64 72 31 20 2a 70 4c   */.  PgHdr1 *pL
1130: 72 75 4e 65 78 74 3b 20 20 20 20 20 20 20 20 20  ruNext;         
1140: 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 69 6e 20       /* Next in 
1150: 4c 52 55 20 6c 69 73 74 20 6f 66 20 75 6e 70 69  LRU list of unpi
1160: 6e 6e 65 64 20 70 61 67 65 73 20 2a 2f 0a 20 20  nned pages */.  
1170: 50 67 48 64 72 31 20 2a 70 4c 72 75 50 72 65 76  PgHdr1 *pLruPrev
1180: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ;              /
1190: 2a 20 50 72 65 76 69 6f 75 73 20 69 6e 20 4c 52  * Previous in LR
11a0: 55 20 6c 69 73 74 20 6f 66 20 75 6e 70 69 6e 6e  U list of unpinn
11b0: 65 64 20 70 61 67 65 73 20 2a 2f 0a 7d 3b 0a 0a  ed pages */.};..
11c0: 2f 2a 0a 2a 2a 20 46 72 65 65 20 73 6c 6f 74 73  /*.** Free slots
11d0: 20 69 6e 20 74 68 65 20 61 6c 6c 6f 63 61 74 6f   in the allocato
11e0: 72 20 75 73 65 64 20 74 6f 20 64 69 76 69 64 65  r used to divide
11f0: 20 75 70 20 74 68 65 20 62 75 66 66 65 72 20 70   up the buffer p
1200: 72 6f 76 69 64 65 64 20 75 73 69 6e 67 0a 2a 2a  rovided using.**
1210: 20 74 68 65 20 53 51 4c 49 54 45 5f 43 4f 4e 46   the SQLITE_CONF
1220: 49 47 5f 50 41 47 45 43 41 43 48 45 20 6d 65 63  IG_PAGECACHE mec
1230: 68 61 6e 69 73 6d 2e 0a 2a 2f 0a 73 74 72 75 63  hanism..*/.struc
1240: 74 20 50 67 46 72 65 65 73 6c 6f 74 20 7b 0a 20  t PgFreeslot {. 
1250: 20 50 67 46 72 65 65 73 6c 6f 74 20 2a 70 4e 65   PgFreeslot *pNe
1260: 78 74 3b 20 20 2f 2a 20 4e 65 78 74 20 66 72 65  xt;  /* Next fre
1270: 65 20 73 6c 6f 74 20 2a 2f 0a 7d 3b 0a 0a 2f 2a  e slot */.};../*
1280: 0a 2a 2a 20 47 6c 6f 62 61 6c 20 64 61 74 61 20  .** Global data 
1290: 75 73 65 64 20 62 79 20 74 68 69 73 20 63 61 63  used by this cac
12a0: 68 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 53 51  he..*/.static SQ
12b0: 4c 49 54 45 5f 57 53 44 20 73 74 72 75 63 74 20  LITE_WSD struct 
12c0: 50 43 61 63 68 65 47 6c 6f 62 61 6c 20 7b 0a 20  PCacheGlobal {. 
12d0: 20 50 47 72 6f 75 70 20 67 72 70 3b 20 20 20 20   PGroup grp;    
12e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12f0: 2f 2a 20 54 68 65 20 67 6c 6f 62 61 6c 20 50 47  /* The global PG
1300: 72 6f 75 70 20 66 6f 72 20 6d 6f 64 65 20 28 32  roup for mode (2
1310: 29 20 2a 2f 0a 0a 20 20 2f 2a 20 56 61 72 69 61  ) */..  /* Varia
1320: 62 6c 65 73 20 72 65 6c 61 74 65 64 20 74 6f 20  bles related to 
1330: 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41  SQLITE_CONFIG_PA
1340: 47 45 43 41 43 48 45 20 73 65 74 74 69 6e 67 73  GECACHE settings
1350: 2e 20 20 54 68 65 0a 20 20 2a 2a 20 73 7a 53 6c  .  The.  ** szSl
1360: 6f 74 2c 20 6e 53 6c 6f 74 2c 20 70 53 74 61 72  ot, nSlot, pStar
1370: 74 2c 20 70 45 6e 64 2c 20 6e 52 65 73 65 72 76  t, pEnd, nReserv
1380: 65 2c 20 61 6e 64 20 69 73 49 6e 69 74 20 76 61  e, and isInit va
1390: 6c 75 65 73 20 61 72 65 20 61 6c 6c 0a 20 20 2a  lues are all.  *
13a0: 2a 20 66 69 78 65 64 20 61 74 20 73 71 6c 69 74  * fixed at sqlit
13b0: 65 33 5f 69 6e 69 74 69 61 6c 69 7a 65 28 29 20  e3_initialize() 
13c0: 74 69 6d 65 20 61 6e 64 20 64 6f 20 6e 6f 74 20  time and do not 
13d0: 72 65 71 75 69 72 65 20 6d 75 74 65 78 20 70 72  require mutex pr
13e0: 6f 74 65 63 74 69 6f 6e 2e 0a 20 20 2a 2a 20 54  otection..  ** T
13f0: 68 65 20 6e 46 72 65 65 53 6c 6f 74 20 61 6e 64  he nFreeSlot and
1400: 20 70 46 72 65 65 20 76 61 6c 75 65 73 20 64 6f   pFree values do
1410: 20 72 65 71 75 69 72 65 20 6d 75 74 65 78 20 70   require mutex p
1420: 72 6f 74 65 63 74 69 6f 6e 2e 0a 20 20 2a 2f 0a  rotection..  */.
1430: 20 20 69 6e 74 20 69 73 49 6e 69 74 3b 20 20 20    int isInit;   
1440: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1450: 20 2f 2a 20 54 72 75 65 20 69 66 20 69 6e 69 74   /* True if init
1460: 69 61 6c 69 7a 65 64 20 2a 2f 0a 20 20 69 6e 74  ialized */.  int
1470: 20 73 7a 53 6c 6f 74 3b 20 20 20 20 20 20 20 20   szSlot;        
1480: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
1490: 69 7a 65 20 6f 66 20 65 61 63 68 20 66 72 65 65  ize of each free
14a0: 20 73 6c 6f 74 20 2a 2f 0a 20 20 69 6e 74 20 6e   slot */.  int n
14b0: 53 6c 6f 74 3b 20 20 20 20 20 20 20 20 20 20 20  Slot;           
14c0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65            /* The
14d0: 20 6e 75 6d 62 65 72 20 6f 66 20 70 63 61 63 68   number of pcach
14e0: 65 20 73 6c 6f 74 73 20 2a 2f 0a 20 20 69 6e 74  e slots */.  int
14f0: 20 6e 52 65 73 65 72 76 65 3b 20 20 20 20 20 20   nReserve;      
1500: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
1510: 72 79 20 74 6f 20 6b 65 65 70 20 6e 46 72 65 65  ry to keep nFree
1520: 53 6c 6f 74 20 61 62 6f 76 65 20 74 68 69 73 20  Slot above this 
1530: 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 53 74 61 72  */.  void *pStar
1540: 74 2c 20 2a 70 45 6e 64 3b 20 20 20 20 20 20 20  t, *pEnd;       
1550: 20 20 20 20 2f 2a 20 42 6f 75 6e 64 73 20 6f 66      /* Bounds of
1560: 20 70 61 67 65 63 61 63 68 65 20 6d 61 6c 6c 6f   pagecache mallo
1570: 63 20 72 61 6e 67 65 20 2a 2f 0a 20 20 2f 2a 20  c range */.  /* 
1580: 41 62 6f 76 65 20 72 65 71 75 69 72 65 73 20 6e  Above requires n
1590: 6f 20 6d 75 74 65 78 2e 20 20 55 73 65 20 6d 75  o mutex.  Use mu
15a0: 74 65 78 20 62 65 6c 6f 77 20 66 6f 72 20 76 61  tex below for va
15b0: 72 69 61 62 6c 65 20 74 68 61 74 20 66 6f 6c 6c  riable that foll
15c0: 6f 77 2e 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  ow. */.  sqlite3
15d0: 5f 6d 75 74 65 78 20 2a 6d 75 74 65 78 3b 20 20  _mutex *mutex;  
15e0: 20 20 20 20 20 20 20 20 2f 2a 20 4d 75 74 65 78          /* Mutex
15f0: 20 66 6f 72 20 61 63 63 65 73 73 69 6e 67 20 74   for accessing t
1600: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 3a 20 2a 2f  he following: */
1610: 0a 20 20 69 6e 74 20 6e 46 72 65 65 53 6c 6f 74  .  int nFreeSlot
1620: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1630: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 75    /* Number of u
1640: 6e 75 73 65 64 20 70 63 61 63 68 65 20 73 6c 6f  nused pcache slo
1650: 74 73 20 2a 2f 0a 20 20 50 67 46 72 65 65 73 6c  ts */.  PgFreesl
1660: 6f 74 20 2a 70 46 72 65 65 3b 20 20 20 20 20 20  ot *pFree;      
1670: 20 20 20 20 20 20 20 2f 2a 20 46 72 65 65 20 70         /* Free p
1680: 61 67 65 20 62 6c 6f 63 6b 73 20 2a 2f 0a 20 20  age blocks */.  
1690: 2f 2a 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  /* The following
16a0: 20 76 61 6c 75 65 20 72 65 71 75 69 72 65 73 20   value requires 
16b0: 61 20 6d 75 74 65 78 20 74 6f 20 63 68 61 6e 67  a mutex to chang
16c0: 65 2e 20 20 57 65 20 73 6b 69 70 20 74 68 65 20  e.  We skip the 
16d0: 6d 75 74 65 78 20 6f 6e 0a 20 20 2a 2a 20 72 65  mutex on.  ** re
16e0: 61 64 69 6e 67 20 62 65 63 61 75 73 65 20 28 31  ading because (1
16f0: 29 20 6d 6f 73 74 20 70 6c 61 74 66 6f 72 6d 73  ) most platforms
1700: 20 72 65 61 64 20 61 20 33 32 2d 62 69 74 20 69   read a 32-bit i
1710: 6e 74 65 67 65 72 20 61 74 6f 6d 69 63 61 6c 6c  nteger atomicall
1720: 79 20 61 6e 64 0a 20 20 2a 2a 20 28 32 29 20 65  y and.  ** (2) e
1730: 76 65 6e 20 69 66 20 61 6e 20 69 6e 63 6f 72 72  ven if an incorr
1740: 65 63 74 20 76 61 6c 75 65 20 69 73 20 72 65 61  ect value is rea
1750: 64 2c 20 6e 6f 20 67 72 65 61 74 20 68 61 72 6d  d, no great harm
1760: 20 69 73 20 64 6f 6e 65 20 73 69 6e 63 65 20 74   is done since t
1770: 68 69 73 0a 20 20 2a 2a 20 69 73 20 72 65 61 6c  his.  ** is real
1780: 6c 79 20 6a 75 73 74 20 61 6e 20 6f 70 74 69 6d  ly just an optim
1790: 69 7a 61 74 69 6f 6e 2e 20 2a 2f 0a 20 20 69 6e  ization. */.  in
17a0: 74 20 62 55 6e 64 65 72 50 72 65 73 73 75 72 65  t bUnderPressure
17b0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ;            /* 
17c0: 54 72 75 65 20 69 66 20 6c 6f 77 20 6f 6e 20 50  True if low on P
17d0: 41 47 45 43 41 43 48 45 20 6d 65 6d 6f 72 79 20  AGECACHE memory 
17e0: 2a 2f 0a 7d 20 70 63 61 63 68 65 31 5f 67 3b 0a  */.} pcache1_g;.
17f0: 0a 2f 2a 0a 2a 2a 20 41 6c 6c 20 63 6f 64 65 20  ./*.** All code 
1800: 69 6e 20 74 68 69 73 20 66 69 6c 65 20 73 68 6f  in this file sho
1810: 75 6c 64 20 61 63 63 65 73 73 20 74 68 65 20 67  uld access the g
1820: 6c 6f 62 61 6c 20 73 74 72 75 63 74 75 72 65 20  lobal structure 
1830: 61 62 6f 76 65 20 76 69 61 20 74 68 65 0a 2a 2a  above via the.**
1840: 20 61 6c 69 61 73 20 22 70 63 61 63 68 65 31 22   alias "pcache1"
1850: 2e 20 54 68 69 73 20 65 6e 73 75 72 65 73 20 74  . This ensures t
1860: 68 61 74 20 74 68 65 20 57 53 44 20 65 6d 75 6c  hat the WSD emul
1870: 61 74 69 6f 6e 20 69 73 20 75 73 65 64 20 77 68  ation is used wh
1880: 65 6e 0a 2a 2a 20 63 6f 6d 70 69 6c 69 6e 67 20  en.** compiling 
1890: 66 6f 72 20 73 79 73 74 65 6d 73 20 74 68 61 74  for systems that
18a0: 20 64 6f 20 6e 6f 74 20 73 75 70 70 6f 72 74 20   do not support 
18b0: 72 65 61 6c 20 57 53 44 2e 0a 2a 2f 0a 23 64 65  real WSD..*/.#de
18c0: 66 69 6e 65 20 70 63 61 63 68 65 31 20 28 47 4c  fine pcache1 (GL
18d0: 4f 42 41 4c 28 73 74 72 75 63 74 20 50 43 61 63  OBAL(struct PCac
18e0: 68 65 47 6c 6f 62 61 6c 2c 20 70 63 61 63 68 65  heGlobal, pcache
18f0: 31 5f 67 29 29 0a 0a 2f 2a 0a 2a 2a 20 4d 61 63  1_g))../*.** Mac
1900: 72 6f 73 20 74 6f 20 65 6e 74 65 72 20 61 6e 64  ros to enter and
1910: 20 6c 65 61 76 65 20 74 68 65 20 50 43 61 63 68   leave the PCach
1920: 65 20 4c 52 55 20 6d 75 74 65 78 2e 0a 2a 2f 0a  e LRU mutex..*/.
1930: 23 64 65 66 69 6e 65 20 70 63 61 63 68 65 31 45  #define pcache1E
1940: 6e 74 65 72 4d 75 74 65 78 28 58 29 20 73 71 6c  nterMutex(X) sql
1950: 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e 74 65 72  ite3_mutex_enter
1960: 28 28 58 29 2d 3e 6d 75 74 65 78 29 0a 23 64 65  ((X)->mutex).#de
1970: 66 69 6e 65 20 70 63 61 63 68 65 31 4c 65 61 76  fine pcache1Leav
1980: 65 4d 75 74 65 78 28 58 29 20 73 71 6c 69 74 65  eMutex(X) sqlite
1990: 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 28 58  3_mutex_leave((X
19a0: 29 2d 3e 6d 75 74 65 78 29 0a 0a 2f 2a 2a 2a 2a  )->mutex)../****
19b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
19c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
19d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
19e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
19f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 2a 2a  **********/./***
1a00: 2a 2a 2a 2a 2a 20 50 61 67 65 20 41 6c 6c 6f 63  ***** Page Alloc
1a10: 61 74 69 6f 6e 2f 53 51 4c 49 54 45 5f 43 4f 4e  ation/SQLITE_CON
1a20: 46 49 47 5f 50 43 41 43 48 45 20 52 65 6c 61 74  FIG_PCACHE Relat
1a30: 65 64 20 46 75 6e 63 74 69 6f 6e 73 20 2a 2a 2a  ed Functions ***
1a40: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f 2a  ***********/../*
1a50: 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
1a60: 6e 20 69 73 20 63 61 6c 6c 65 64 20 64 75 72 69  n is called duri
1a70: 6e 67 20 69 6e 69 74 69 61 6c 69 7a 61 74 69 6f  ng initializatio
1a80: 6e 20 69 66 20 61 20 73 74 61 74 69 63 20 62 75  n if a static bu
1a90: 66 66 65 72 20 69 73 20 0a 2a 2a 20 73 75 70 70  ffer is .** supp
1aa0: 6c 69 65 64 20 74 6f 20 75 73 65 20 66 6f 72 20  lied to use for 
1ab0: 74 68 65 20 70 61 67 65 2d 63 61 63 68 65 20 62  the page-cache b
1ac0: 79 20 70 61 73 73 69 6e 67 20 74 68 65 20 53 51  y passing the SQ
1ad0: 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47 45  LITE_CONFIG_PAGE
1ae0: 43 41 43 48 45 0a 2a 2a 20 76 65 72 62 20 74 6f  CACHE.** verb to
1af0: 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67 28   sqlite3_config(
1b00: 29 2e 20 50 61 72 61 6d 65 74 65 72 20 70 42 75  ). Parameter pBu
1b10: 66 20 70 6f 69 6e 74 73 20 74 6f 20 61 6e 20 61  f points to an a
1b20: 6c 6c 6f 63 61 74 69 6f 6e 20 6c 61 72 67 65 0a  llocation large.
1b30: 2a 2a 20 65 6e 6f 75 67 68 20 74 6f 20 63 6f 6e  ** enough to con
1b40: 74 61 69 6e 20 27 6e 27 20 62 75 66 66 65 72 73  tain 'n' buffers
1b50: 20 6f 66 20 27 73 7a 27 20 62 79 74 65 73 20 65   of 'sz' bytes e
1b60: 61 63 68 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  ach..**.** This 
1b70: 72 6f 75 74 69 6e 65 20 69 73 20 63 61 6c 6c 65  routine is calle
1b80: 64 20 66 72 6f 6d 20 73 71 6c 69 74 65 33 5f 69  d from sqlite3_i
1b90: 6e 69 74 69 61 6c 69 7a 65 28 29 20 61 6e 64 20  nitialize() and 
1ba0: 73 6f 20 69 74 20 69 73 20 67 75 61 72 61 6e 74  so it is guarant
1bb0: 65 65 64 0a 2a 2a 20 74 6f 20 62 65 20 73 65 72  eed.** to be ser
1bc0: 69 61 6c 69 7a 65 64 20 61 6c 72 65 61 64 79 2e  ialized already.
1bd0: 20 20 54 68 65 72 65 20 69 73 20 6e 6f 20 6e 65    There is no ne
1be0: 65 64 20 66 6f 72 20 66 75 72 74 68 65 72 20 6d  ed for further m
1bf0: 75 74 65 78 69 6e 67 2e 0a 2a 2f 0a 76 6f 69 64  utexing..*/.void
1c00: 20 73 71 6c 69 74 65 33 50 43 61 63 68 65 42 75   sqlite3PCacheBu
1c10: 66 66 65 72 53 65 74 75 70 28 76 6f 69 64 20 2a  fferSetup(void *
1c20: 70 42 75 66 2c 20 69 6e 74 20 73 7a 2c 20 69 6e  pBuf, int sz, in
1c30: 74 20 6e 29 7b 0a 20 20 69 66 28 20 70 63 61 63  t n){.  if( pcac
1c40: 68 65 31 2e 69 73 49 6e 69 74 20 29 7b 0a 20 20  he1.isInit ){.  
1c50: 20 20 50 67 46 72 65 65 73 6c 6f 74 20 2a 70 3b    PgFreeslot *p;
1c60: 0a 20 20 20 20 73 7a 20 3d 20 52 4f 55 4e 44 44  .    sz = ROUNDD
1c70: 4f 57 4e 38 28 73 7a 29 3b 0a 20 20 20 20 70 63  OWN8(sz);.    pc
1c80: 61 63 68 65 31 2e 73 7a 53 6c 6f 74 20 3d 20 73  ache1.szSlot = s
1c90: 7a 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 6e  z;.    pcache1.n
1ca0: 53 6c 6f 74 20 3d 20 70 63 61 63 68 65 31 2e 6e  Slot = pcache1.n
1cb0: 46 72 65 65 53 6c 6f 74 20 3d 20 6e 3b 0a 20 20  FreeSlot = n;.  
1cc0: 20 20 70 63 61 63 68 65 31 2e 6e 52 65 73 65 72    pcache1.nReser
1cd0: 76 65 20 3d 20 6e 3e 39 30 20 3f 20 31 30 20 3a  ve = n>90 ? 10 :
1ce0: 20 28 6e 2f 31 30 20 2b 20 31 29 3b 0a 20 20 20   (n/10 + 1);.   
1cf0: 20 70 63 61 63 68 65 31 2e 70 53 74 61 72 74 20   pcache1.pStart 
1d00: 3d 20 70 42 75 66 3b 0a 20 20 20 20 70 63 61 63  = pBuf;.    pcac
1d10: 68 65 31 2e 70 46 72 65 65 20 3d 20 30 3b 0a 20  he1.pFree = 0;. 
1d20: 20 20 20 70 63 61 63 68 65 31 2e 62 55 6e 64 65     pcache1.bUnde
1d30: 72 50 72 65 73 73 75 72 65 20 3d 20 30 3b 0a 20  rPressure = 0;. 
1d40: 20 20 20 77 68 69 6c 65 28 20 6e 2d 2d 20 29 7b     while( n-- ){
1d50: 0a 20 20 20 20 20 20 70 20 3d 20 28 50 67 46 72  .      p = (PgFr
1d60: 65 65 73 6c 6f 74 2a 29 70 42 75 66 3b 0a 20 20  eeslot*)pBuf;.  
1d70: 20 20 20 20 70 2d 3e 70 4e 65 78 74 20 3d 20 70      p->pNext = p
1d80: 63 61 63 68 65 31 2e 70 46 72 65 65 3b 0a 20 20  cache1.pFree;.  
1d90: 20 20 20 20 70 63 61 63 68 65 31 2e 70 46 72 65      pcache1.pFre
1da0: 65 20 3d 20 70 3b 0a 20 20 20 20 20 20 70 42 75  e = p;.      pBu
1db0: 66 20 3d 20 28 76 6f 69 64 2a 29 26 28 28 63 68  f = (void*)&((ch
1dc0: 61 72 2a 29 70 42 75 66 29 5b 73 7a 5d 3b 0a 20  ar*)pBuf)[sz];. 
1dd0: 20 20 20 7d 0a 20 20 20 20 70 63 61 63 68 65 31     }.    pcache1
1de0: 2e 70 45 6e 64 20 3d 20 70 42 75 66 3b 0a 20 20  .pEnd = pBuf;.  
1df0: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6c 6c 6f  }.}../*.** Mallo
1e00: 63 20 66 75 6e 63 74 69 6f 6e 20 75 73 65 64 20  c function used 
1e10: 77 69 74 68 69 6e 20 74 68 69 73 20 66 69 6c 65  within this file
1e20: 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 73 70 61   to allocate spa
1e30: 63 65 20 66 72 6f 6d 20 74 68 65 20 62 75 66 66  ce from the buff
1e40: 65 72 0a 2a 2a 20 63 6f 6e 66 69 67 75 72 65 64  er.** configured
1e50: 20 75 73 69 6e 67 20 73 71 6c 69 74 65 33 5f 63   using sqlite3_c
1e60: 6f 6e 66 69 67 28 53 51 4c 49 54 45 5f 43 4f 4e  onfig(SQLITE_CON
1e70: 46 49 47 5f 50 41 47 45 43 41 43 48 45 29 20 6f  FIG_PAGECACHE) o
1e80: 70 74 69 6f 6e 2e 20 49 66 20 6e 6f 20 0a 2a 2a  ption. If no .**
1e90: 20 73 75 63 68 20 62 75 66 66 65 72 20 65 78 69   such buffer exi
1ea0: 73 74 73 20 6f 72 20 74 68 65 72 65 20 69 73 20  sts or there is 
1eb0: 6e 6f 20 73 70 61 63 65 20 6c 65 66 74 20 69 6e  no space left in
1ec0: 20 69 74 2c 20 74 68 69 73 20 66 75 6e 63 74 69   it, this functi
1ed0: 6f 6e 20 66 61 6c 6c 73 20 0a 2a 2a 20 62 61 63  on falls .** bac
1ee0: 6b 20 74 6f 20 73 71 6c 69 74 65 33 4d 61 6c 6c  k to sqlite3Mall
1ef0: 6f 63 28 29 2e 0a 2a 2a 0a 2a 2a 20 4d 75 6c 74  oc()..**.** Mult
1f00: 69 70 6c 65 20 74 68 72 65 61 64 73 20 63 61 6e  iple threads can
1f10: 20 72 75 6e 20 74 68 69 73 20 72 6f 75 74 69 6e   run this routin
1f20: 65 20 61 74 20 74 68 65 20 73 61 6d 65 20 74 69  e at the same ti
1f30: 6d 65 2e 20 20 47 6c 6f 62 61 6c 20 76 61 72 69  me.  Global vari
1f40: 61 62 6c 65 73 0a 2a 2a 20 69 6e 20 70 63 61 63  ables.** in pcac
1f50: 68 65 31 20 6e 65 65 64 20 74 6f 20 62 65 20 70  he1 need to be p
1f60: 72 6f 74 65 63 74 65 64 20 76 69 61 20 6d 75 74  rotected via mut
1f70: 65 78 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ex..*/.static vo
1f80: 69 64 20 2a 70 63 61 63 68 65 31 41 6c 6c 6f 63  id *pcache1Alloc
1f90: 28 69 6e 74 20 6e 42 79 74 65 29 7b 0a 20 20 76  (int nByte){.  v
1fa0: 6f 69 64 20 2a 70 20 3d 20 30 3b 0a 20 20 61 73  oid *p = 0;.  as
1fb0: 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75  sert( sqlite3_mu
1fc0: 74 65 78 5f 6e 6f 74 68 65 6c 64 28 70 63 61 63  tex_notheld(pcac
1fd0: 68 65 31 2e 67 72 70 2e 6d 75 74 65 78 29 20 29  he1.grp.mutex) )
1fe0: 3b 0a 20 20 73 71 6c 69 74 65 33 53 74 61 74 75  ;.  sqlite3Statu
1ff0: 73 53 65 74 28 53 51 4c 49 54 45 5f 53 54 41 54  sSet(SQLITE_STAT
2000: 55 53 5f 50 41 47 45 43 41 43 48 45 5f 53 49 5a  US_PAGECACHE_SIZ
2010: 45 2c 20 6e 42 79 74 65 29 3b 0a 20 20 69 66 28  E, nByte);.  if(
2020: 20 6e 42 79 74 65 3c 3d 70 63 61 63 68 65 31 2e   nByte<=pcache1.
2030: 73 7a 53 6c 6f 74 20 29 7b 0a 20 20 20 20 73 71  szSlot ){.    sq
2040: 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e 74 65  lite3_mutex_ente
2050: 72 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29  r(pcache1.mutex)
2060: 3b 0a 20 20 20 20 70 20 3d 20 28 50 67 48 64 72  ;.    p = (PgHdr
2070: 31 20 2a 29 70 63 61 63 68 65 31 2e 70 46 72 65  1 *)pcache1.pFre
2080: 65 3b 0a 20 20 20 20 69 66 28 20 70 20 29 7b 0a  e;.    if( p ){.
2090: 20 20 20 20 20 20 70 63 61 63 68 65 31 2e 70 46        pcache1.pF
20a0: 72 65 65 20 3d 20 70 63 61 63 68 65 31 2e 70 46  ree = pcache1.pF
20b0: 72 65 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20  ree->pNext;.    
20c0: 20 20 70 63 61 63 68 65 31 2e 6e 46 72 65 65 53    pcache1.nFreeS
20d0: 6c 6f 74 2d 2d 3b 0a 20 20 20 20 20 20 70 63 61  lot--;.      pca
20e0: 63 68 65 31 2e 62 55 6e 64 65 72 50 72 65 73 73  che1.bUnderPress
20f0: 75 72 65 20 3d 20 70 63 61 63 68 65 31 2e 6e 46  ure = pcache1.nF
2100: 72 65 65 53 6c 6f 74 3c 70 63 61 63 68 65 31 2e  reeSlot<pcache1.
2110: 6e 52 65 73 65 72 76 65 3b 0a 20 20 20 20 20 20  nReserve;.      
2120: 61 73 73 65 72 74 28 20 70 63 61 63 68 65 31 2e  assert( pcache1.
2130: 6e 46 72 65 65 53 6c 6f 74 3e 3d 30 20 29 3b 0a  nFreeSlot>=0 );.
2140: 20 20 20 20 20 20 73 71 6c 69 74 65 33 53 74 61        sqlite3Sta
2150: 74 75 73 41 64 64 28 53 51 4c 49 54 45 5f 53 54  tusAdd(SQLITE_ST
2160: 41 54 55 53 5f 50 41 47 45 43 41 43 48 45 5f 55  ATUS_PAGECACHE_U
2170: 53 45 44 2c 20 31 29 3b 0a 20 20 20 20 7d 0a 20  SED, 1);.    }. 
2180: 20 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78     sqlite3_mutex
2190: 5f 6c 65 61 76 65 28 70 63 61 63 68 65 31 2e 6d  _leave(pcache1.m
21a0: 75 74 65 78 29 3b 0a 20 20 7d 0a 20 20 69 66 28  utex);.  }.  if(
21b0: 20 70 3d 3d 30 20 29 7b 0a 20 20 20 20 2f 2a 20   p==0 ){.    /* 
21c0: 4d 65 6d 6f 72 79 20 69 73 20 6e 6f 74 20 61 76  Memory is not av
21d0: 61 69 6c 61 62 6c 65 20 69 6e 20 74 68 65 20 53  ailable in the S
21e0: 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47  QLITE_CONFIG_PAG
21f0: 45 43 41 43 48 45 20 70 6f 6f 6c 2e 20 20 47 65  ECACHE pool.  Ge
2200: 74 0a 20 20 20 20 2a 2a 20 69 74 20 66 72 6f 6d  t.    ** it from
2210: 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 20 69   sqlite3Malloc i
2220: 6e 73 74 65 61 64 2e 0a 20 20 20 20 2a 2f 0a 20  nstead..    */. 
2230: 20 20 20 70 20 3d 20 73 71 6c 69 74 65 33 4d 61     p = sqlite3Ma
2240: 6c 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20 20  lloc(nByte);.   
2250: 20 69 66 28 20 70 20 29 7b 0a 20 20 20 20 20 20   if( p ){.      
2260: 69 6e 74 20 73 7a 20 3d 20 73 71 6c 69 74 65 33  int sz = sqlite3
2270: 4d 61 6c 6c 6f 63 53 69 7a 65 28 70 29 3b 0a 20  MallocSize(p);. 
2280: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 75 74       sqlite3_mut
2290: 65 78 5f 65 6e 74 65 72 28 70 63 61 63 68 65 31  ex_enter(pcache1
22a0: 2e 6d 75 74 65 78 29 3b 0a 20 20 20 20 20 20 73  .mutex);.      s
22b0: 71 6c 69 74 65 33 53 74 61 74 75 73 41 64 64 28  qlite3StatusAdd(
22c0: 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41  SQLITE_STATUS_PA
22d0: 47 45 43 41 43 48 45 5f 4f 56 45 52 46 4c 4f 57  GECACHE_OVERFLOW
22e0: 2c 20 73 7a 29 3b 0a 20 20 20 20 20 20 73 71 6c  , sz);.      sql
22f0: 69 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65  ite3_mutex_leave
2300: 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29 3b  (pcache1.mutex);
2310: 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 6c 69 74  .    }.    sqlit
2320: 65 33 4d 65 6d 64 65 62 75 67 53 65 74 54 79 70  e3MemdebugSetTyp
2330: 65 28 70 2c 20 4d 45 4d 54 59 50 45 5f 50 43 41  e(p, MEMTYPE_PCA
2340: 43 48 45 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75  CHE);.  }.  retu
2350: 72 6e 20 70 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46  rn p;.}../*.** F
2360: 72 65 65 20 61 6e 20 61 6c 6c 6f 63 61 74 65 64  ree an allocated
2370: 20 62 75 66 66 65 72 20 6f 62 74 61 69 6e 65 64   buffer obtained
2380: 20 66 72 6f 6d 20 70 63 61 63 68 65 31 41 6c 6c   from pcache1All
2390: 6f 63 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  oc()..*/.static 
23a0: 76 6f 69 64 20 70 63 61 63 68 65 31 46 72 65 65  void pcache1Free
23b0: 28 76 6f 69 64 20 2a 70 29 7b 0a 20 20 69 66 28  (void *p){.  if(
23c0: 20 70 3d 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a   p==0 ) return;.
23d0: 20 20 69 66 28 20 70 3e 3d 70 63 61 63 68 65 31    if( p>=pcache1
23e0: 2e 70 53 74 61 72 74 20 26 26 20 70 3c 70 63 61  .pStart && p<pca
23f0: 63 68 65 31 2e 70 45 6e 64 20 29 7b 0a 20 20 20  che1.pEnd ){.   
2400: 20 50 67 46 72 65 65 73 6c 6f 74 20 2a 70 53 6c   PgFreeslot *pSl
2410: 6f 74 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  ot;.    sqlite3_
2420: 6d 75 74 65 78 5f 65 6e 74 65 72 28 70 63 61 63  mutex_enter(pcac
2430: 68 65 31 2e 6d 75 74 65 78 29 3b 0a 20 20 20 20  he1.mutex);.    
2440: 73 71 6c 69 74 65 33 53 74 61 74 75 73 41 64 64  sqlite3StatusAdd
2450: 28 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50  (SQLITE_STATUS_P
2460: 41 47 45 43 41 43 48 45 5f 55 53 45 44 2c 20 2d  AGECACHE_USED, -
2470: 31 29 3b 0a 20 20 20 20 70 53 6c 6f 74 20 3d 20  1);.    pSlot = 
2480: 28 50 67 46 72 65 65 73 6c 6f 74 2a 29 70 3b 0a  (PgFreeslot*)p;.
2490: 20 20 20 20 70 53 6c 6f 74 2d 3e 70 4e 65 78 74      pSlot->pNext
24a0: 20 3d 20 70 63 61 63 68 65 31 2e 70 46 72 65 65   = pcache1.pFree
24b0: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 70 46  ;.    pcache1.pF
24c0: 72 65 65 20 3d 20 70 53 6c 6f 74 3b 0a 20 20 20  ree = pSlot;.   
24d0: 20 70 63 61 63 68 65 31 2e 6e 46 72 65 65 53 6c   pcache1.nFreeSl
24e0: 6f 74 2b 2b 3b 0a 20 20 20 20 70 63 61 63 68 65  ot++;.    pcache
24f0: 31 2e 62 55 6e 64 65 72 50 72 65 73 73 75 72 65  1.bUnderPressure
2500: 20 3d 20 70 63 61 63 68 65 31 2e 6e 46 72 65 65   = pcache1.nFree
2510: 53 6c 6f 74 3c 70 63 61 63 68 65 31 2e 6e 52 65  Slot<pcache1.nRe
2520: 73 65 72 76 65 3b 0a 20 20 20 20 61 73 73 65 72  serve;.    asser
2530: 74 28 20 70 63 61 63 68 65 31 2e 6e 46 72 65 65  t( pcache1.nFree
2540: 53 6c 6f 74 3c 3d 70 63 61 63 68 65 31 2e 6e 53  Slot<=pcache1.nS
2550: 6c 6f 74 20 29 3b 0a 20 20 20 20 73 71 6c 69 74  lot );.    sqlit
2560: 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 70  e3_mutex_leave(p
2570: 63 61 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a 20  cache1.mutex);. 
2580: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 6e 74 20   }else{.    int 
2590: 69 53 69 7a 65 3b 0a 20 20 20 20 61 73 73 65 72  iSize;.    asser
25a0: 74 28 20 73 71 6c 69 74 65 33 4d 65 6d 64 65 62  t( sqlite3Memdeb
25b0: 75 67 48 61 73 54 79 70 65 28 70 2c 20 4d 45 4d  ugHasType(p, MEM
25c0: 54 59 50 45 5f 50 43 41 43 48 45 29 20 29 3b 0a  TYPE_PCACHE) );.
25d0: 20 20 20 20 73 71 6c 69 74 65 33 4d 65 6d 64 65      sqlite3Memde
25e0: 62 75 67 53 65 74 54 79 70 65 28 70 2c 20 4d 45  bugSetType(p, ME
25f0: 4d 54 59 50 45 5f 48 45 41 50 29 3b 0a 20 20 20  MTYPE_HEAP);.   
2600: 20 69 53 69 7a 65 20 3d 20 73 71 6c 69 74 65 33   iSize = sqlite3
2610: 4d 61 6c 6c 6f 63 53 69 7a 65 28 70 29 3b 0a 20  MallocSize(p);. 
2620: 20 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78     sqlite3_mutex
2630: 5f 65 6e 74 65 72 28 70 63 61 63 68 65 31 2e 6d  _enter(pcache1.m
2640: 75 74 65 78 29 3b 0a 20 20 20 20 73 71 6c 69 74  utex);.    sqlit
2650: 65 33 53 74 61 74 75 73 41 64 64 28 53 51 4c 49  e3StatusAdd(SQLI
2660: 54 45 5f 53 54 41 54 55 53 5f 50 41 47 45 43 41  TE_STATUS_PAGECA
2670: 43 48 45 5f 4f 56 45 52 46 4c 4f 57 2c 20 2d 69  CHE_OVERFLOW, -i
2680: 53 69 7a 65 29 3b 0a 20 20 20 20 73 71 6c 69 74  Size);.    sqlit
2690: 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 70  e3_mutex_leave(p
26a0: 63 61 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a 20  cache1.mutex);. 
26b0: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
26c0: 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 23 69 66 64 65  p);.  }.}..#ifde
26d0: 66 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f  f SQLITE_ENABLE_
26e0: 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e  MEMORY_MANAGEMEN
26f0: 54 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74  T./*.** Return t
2700: 68 65 20 73 69 7a 65 20 6f 66 20 61 20 70 63 61  he size of a pca
2710: 63 68 65 20 61 6c 6c 6f 63 61 74 69 6f 6e 0a 2a  che allocation.*
2720: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 70 63 61  /.static int pca
2730: 63 68 65 31 4d 65 6d 53 69 7a 65 28 76 6f 69 64  che1MemSize(void
2740: 20 2a 70 29 7b 0a 20 20 69 66 28 20 70 3e 3d 70   *p){.  if( p>=p
2750: 63 61 63 68 65 31 2e 70 53 74 61 72 74 20 26 26  cache1.pStart &&
2760: 20 70 3c 70 63 61 63 68 65 31 2e 70 45 6e 64 20   p<pcache1.pEnd 
2770: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 70 63  ){.    return pc
2780: 61 63 68 65 31 2e 73 7a 53 6c 6f 74 3b 0a 20 20  ache1.szSlot;.  
2790: 7d 65 6c 73 65 7b 0a 20 20 20 20 69 6e 74 20 69  }else{.    int i
27a0: 53 69 7a 65 3b 0a 20 20 20 20 61 73 73 65 72 74  Size;.    assert
27b0: 28 20 73 71 6c 69 74 65 33 4d 65 6d 64 65 62 75  ( sqlite3Memdebu
27c0: 67 48 61 73 54 79 70 65 28 70 2c 20 4d 45 4d 54  gHasType(p, MEMT
27d0: 59 50 45 5f 50 43 41 43 48 45 29 20 29 3b 0a 20  YPE_PCACHE) );. 
27e0: 20 20 20 73 71 6c 69 74 65 33 4d 65 6d 64 65 62     sqlite3Memdeb
27f0: 75 67 53 65 74 54 79 70 65 28 70 2c 20 4d 45 4d  ugSetType(p, MEM
2800: 54 59 50 45 5f 48 45 41 50 29 3b 0a 20 20 20 20  TYPE_HEAP);.    
2810: 69 53 69 7a 65 20 3d 20 73 71 6c 69 74 65 33 4d  iSize = sqlite3M
2820: 61 6c 6c 6f 63 53 69 7a 65 28 70 29 3b 0a 20 20  allocSize(p);.  
2830: 20 20 73 71 6c 69 74 65 33 4d 65 6d 64 65 62 75    sqlite3Memdebu
2840: 67 53 65 74 54 79 70 65 28 70 2c 20 4d 45 4d 54  gSetType(p, MEMT
2850: 59 50 45 5f 50 43 41 43 48 45 29 3b 0a 20 20 20  YPE_PCACHE);.   
2860: 20 72 65 74 75 72 6e 20 69 53 69 7a 65 3b 0a 20   return iSize;. 
2870: 20 7d 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a 20 53   }.}.#endif /* S
2880: 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d  QLITE_ENABLE_MEM
2890: 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 20 2a  ORY_MANAGEMENT *
28a0: 2f 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74  /../*.** Allocat
28b0: 65 20 61 20 6e 65 77 20 70 61 67 65 20 6f 62 6a  e a new page obj
28c0: 65 63 74 20 69 6e 69 74 69 61 6c 6c 79 20 61 73  ect initially as
28d0: 73 6f 63 69 61 74 65 64 20 77 69 74 68 20 63 61  sociated with ca
28e0: 63 68 65 20 70 43 61 63 68 65 2e 0a 2a 2f 0a 73  che pCache..*/.s
28f0: 74 61 74 69 63 20 50 67 48 64 72 31 20 2a 70 63  tatic PgHdr1 *pc
2900: 61 63 68 65 31 41 6c 6c 6f 63 50 61 67 65 28 50  ache1AllocPage(P
2910: 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 29 7b  Cache1 *pCache){
2920: 0a 20 20 50 67 48 64 72 31 20 2a 70 20 3d 20 30  .  PgHdr1 *p = 0
2930: 3b 0a 20 20 76 6f 69 64 20 2a 70 50 67 3b 0a 0a  ;.  void *pPg;..
2940: 20 20 2f 2a 20 54 68 65 20 67 72 6f 75 70 20 6d    /* The group m
2950: 75 74 65 78 20 6d 75 73 74 20 62 65 20 72 65 6c  utex must be rel
2960: 65 61 73 65 64 20 62 65 66 6f 72 65 20 70 63 61  eased before pca
2970: 63 68 65 31 41 6c 6c 6f 63 28 29 20 69 73 20 63  che1Alloc() is c
2980: 61 6c 6c 65 64 2e 20 54 68 69 73 0a 20 20 2a 2a  alled. This.  **
2990: 20 69 73 20 62 65 63 61 75 73 65 20 69 74 20 6d   is because it m
29a0: 61 79 20 63 61 6c 6c 20 73 71 6c 69 74 65 33 5f  ay call sqlite3_
29b0: 72 65 6c 65 61 73 65 5f 6d 65 6d 6f 72 79 28 29  release_memory()
29c0: 2c 20 77 68 69 63 68 20 61 73 73 75 6d 65 73 20  , which assumes 
29d0: 74 68 61 74 20 0a 20 20 2a 2a 20 74 68 69 73 20  that .  ** this 
29e0: 6d 75 74 65 78 20 69 73 20 6e 6f 74 20 68 65 6c  mutex is not hel
29f0: 64 2e 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20  d. */.  assert( 
2a00: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65  sqlite3_mutex_he
2a10: 6c 64 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75  ld(pCache->pGrou
2a20: 70 2d 3e 6d 75 74 65 78 29 20 29 3b 0a 20 20 70  p->mutex) );.  p
2a30: 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78  cache1LeaveMutex
2a40: 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 29  (pCache->pGroup)
2a50: 3b 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f  ;.#ifdef SQLITE_
2a60: 50 43 41 43 48 45 5f 53 45 50 41 52 41 54 45 5f  PCACHE_SEPARATE_
2a70: 48 45 41 44 45 52 0a 20 20 70 50 67 20 3d 20 70  HEADER.  pPg = p
2a80: 63 61 63 68 65 31 41 6c 6c 6f 63 28 70 43 61 63  cache1Alloc(pCac
2a90: 68 65 2d 3e 73 7a 50 61 67 65 29 3b 0a 20 20 70  he->szPage);.  p
2aa0: 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63   = sqlite3Malloc
2ab0: 28 73 69 7a 65 6f 66 28 50 67 48 64 72 31 29 20  (sizeof(PgHdr1) 
2ac0: 2b 20 70 43 61 63 68 65 2d 3e 73 7a 45 78 74 72  + pCache->szExtr
2ad0: 61 29 3b 0a 20 20 69 66 28 20 21 70 50 67 20 7c  a);.  if( !pPg |
2ae0: 7c 20 21 70 20 29 7b 0a 20 20 20 20 70 63 61 63  | !p ){.    pcac
2af0: 68 65 31 46 72 65 65 28 70 50 67 29 3b 0a 20 20  he1Free(pPg);.  
2b00: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
2b10: 29 3b 0a 20 20 20 20 70 50 67 20 3d 20 30 3b 0a  );.    pPg = 0;.
2b20: 20 20 7d 0a 23 65 6c 73 65 0a 20 20 70 50 67 20    }.#else.  pPg 
2b30: 3d 20 70 63 61 63 68 65 31 41 6c 6c 6f 63 28 73  = pcache1Alloc(s
2b40: 69 7a 65 6f 66 28 50 67 48 64 72 31 29 20 2b 20  izeof(PgHdr1) + 
2b50: 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 20 2b  pCache->szPage +
2b60: 20 70 43 61 63 68 65 2d 3e 73 7a 45 78 74 72 61   pCache->szExtra
2b70: 29 3b 0a 20 20 70 20 3d 20 28 50 67 48 64 72 31  );.  p = (PgHdr1
2b80: 20 2a 29 26 28 28 75 38 20 2a 29 70 50 67 29 5b   *)&((u8 *)pPg)[
2b90: 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 5d 3b  pCache->szPage];
2ba0: 0a 23 65 6e 64 69 66 0a 20 20 70 63 61 63 68 65  .#endif.  pcache
2bb0: 31 45 6e 74 65 72 4d 75 74 65 78 28 70 43 61 63  1EnterMutex(pCac
2bc0: 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 0a 20 20  he->pGroup);..  
2bd0: 69 66 28 20 70 50 67 20 29 7b 0a 20 20 20 20 70  if( pPg ){.    p
2be0: 2d 3e 70 61 67 65 2e 70 42 75 66 20 3d 20 70 50  ->page.pBuf = pP
2bf0: 67 3b 0a 20 20 20 20 70 2d 3e 70 61 67 65 2e 70  g;.    p->page.p
2c00: 45 78 74 72 61 20 3d 20 26 70 5b 31 5d 3b 0a 20  Extra = &p[1];. 
2c10: 20 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 62     if( pCache->b
2c20: 50 75 72 67 65 61 62 6c 65 20 29 7b 0a 20 20 20  Purgeable ){.   
2c30: 20 20 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75     pCache->pGrou
2c40: 70 2d 3e 6e 43 75 72 72 65 6e 74 50 61 67 65 2b  p->nCurrentPage+
2c50: 2b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72 65 74  +;.    }.    ret
2c60: 75 72 6e 20 70 3b 0a 20 20 7d 0a 20 20 72 65 74  urn p;.  }.  ret
2c70: 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  urn 0;.}../*.** 
2c80: 46 72 65 65 20 61 20 70 61 67 65 20 6f 62 6a 65  Free a page obje
2c90: 63 74 20 61 6c 6c 6f 63 61 74 65 64 20 62 79 20  ct allocated by 
2ca0: 70 63 61 63 68 65 31 41 6c 6c 6f 63 50 61 67 65  pcache1AllocPage
2cb0: 28 29 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 70 6f  ()..**.** The po
2cc0: 69 6e 74 65 72 20 69 73 20 61 6c 6c 6f 77 65 64  inter is allowed
2cd0: 20 74 6f 20 62 65 20 4e 55 4c 4c 2c 20 77 68 69   to be NULL, whi
2ce0: 63 68 20 69 73 20 70 72 75 64 65 6e 74 2e 20 20  ch is prudent.  
2cf0: 42 75 74 20 69 74 20 74 75 72 6e 73 20 6f 75 74  But it turns out
2d00: 0a 2a 2a 20 74 68 61 74 20 74 68 65 20 63 75 72  .** that the cur
2d10: 72 65 6e 74 20 69 6d 70 6c 65 6d 65 6e 74 61 74  rent implementat
2d20: 69 6f 6e 20 68 61 70 70 65 6e 73 20 74 6f 20 6e  ion happens to n
2d30: 65 76 65 72 20 63 61 6c 6c 20 74 68 69 73 20 72  ever call this r
2d40: 6f 75 74 69 6e 65 0a 2a 2a 20 77 69 74 68 20 61  outine.** with a
2d50: 20 4e 55 4c 4c 20 70 6f 69 6e 74 65 72 2c 20 73   NULL pointer, s
2d60: 6f 20 77 65 20 6d 61 72 6b 20 74 68 65 20 4e 55  o we mark the NU
2d70: 4c 4c 20 74 65 73 74 20 77 69 74 68 20 41 4c 57  LL test with ALW
2d80: 41 59 53 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63  AYS()..*/.static
2d90: 20 76 6f 69 64 20 70 63 61 63 68 65 31 46 72 65   void pcache1Fre
2da0: 65 50 61 67 65 28 50 67 48 64 72 31 20 2a 70 29  ePage(PgHdr1 *p)
2db0: 7b 0a 20 20 69 66 28 20 41 4c 57 41 59 53 28 70  {.  if( ALWAYS(p
2dc0: 29 20 29 7b 0a 20 20 20 20 50 43 61 63 68 65 31  ) ){.    PCache1
2dd0: 20 2a 70 43 61 63 68 65 20 3d 20 70 2d 3e 70 43   *pCache = p->pC
2de0: 61 63 68 65 3b 0a 20 20 20 20 61 73 73 65 72 74  ache;.    assert
2df0: 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f  ( sqlite3_mutex_
2e00: 68 65 6c 64 28 70 2d 3e 70 43 61 63 68 65 2d 3e  held(p->pCache->
2e10: 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78 29 20 29  pGroup->mutex) )
2e20: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 46 72 65  ;.    pcache1Fre
2e30: 65 28 70 2d 3e 70 61 67 65 2e 70 42 75 66 29 3b  e(p->page.pBuf);
2e40: 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 50  .#ifdef SQLITE_P
2e50: 43 41 43 48 45 5f 53 45 50 41 52 41 54 45 5f 48  CACHE_SEPARATE_H
2e60: 45 41 44 45 52 0a 20 20 20 20 73 71 6c 69 74 65  EADER.    sqlite
2e70: 33 5f 66 72 65 65 28 70 29 3b 0a 23 65 6e 64 69  3_free(p);.#endi
2e80: 66 0a 20 20 20 20 69 66 28 20 70 43 61 63 68 65  f.    if( pCache
2e90: 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 29 7b 0a  ->bPurgeable ){.
2ea0: 20 20 20 20 20 20 70 43 61 63 68 65 2d 3e 70 47        pCache->pG
2eb0: 72 6f 75 70 2d 3e 6e 43 75 72 72 65 6e 74 50 61  roup->nCurrentPa
2ec0: 67 65 2d 2d 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  ge--;.    }.  }.
2ed0: 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6c 6c 6f 63 20  }../*.** Malloc 
2ee0: 66 75 6e 63 74 69 6f 6e 20 75 73 65 64 20 62 79  function used by
2ef0: 20 53 51 4c 69 74 65 20 74 6f 20 6f 62 74 61 69   SQLite to obtai
2f00: 6e 20 73 70 61 63 65 20 66 72 6f 6d 20 74 68 65  n space from the
2f10: 20 62 75 66 66 65 72 20 63 6f 6e 66 69 67 75 72   buffer configur
2f20: 65 64 0a 2a 2a 20 75 73 69 6e 67 20 73 71 6c 69  ed.** using sqli
2f30: 74 65 33 5f 63 6f 6e 66 69 67 28 53 51 4c 49 54  te3_config(SQLIT
2f40: 45 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41 43  E_CONFIG_PAGECAC
2f50: 48 45 29 20 6f 70 74 69 6f 6e 2e 20 49 66 20 6e  HE) option. If n
2f60: 6f 20 73 75 63 68 20 62 75 66 66 65 72 0a 2a 2a  o such buffer.**
2f70: 20 65 78 69 73 74 73 2c 20 74 68 69 73 20 66 75   exists, this fu
2f80: 6e 63 74 69 6f 6e 20 66 61 6c 6c 73 20 62 61 63  nction falls bac
2f90: 6b 20 74 6f 20 73 71 6c 69 74 65 33 4d 61 6c 6c  k to sqlite3Mall
2fa0: 6f 63 28 29 2e 0a 2a 2f 0a 76 6f 69 64 20 2a 73  oc()..*/.void *s
2fb0: 71 6c 69 74 65 33 50 61 67 65 4d 61 6c 6c 6f 63  qlite3PageMalloc
2fc0: 28 69 6e 74 20 73 7a 29 7b 0a 20 20 72 65 74 75  (int sz){.  retu
2fd0: 72 6e 20 70 63 61 63 68 65 31 41 6c 6c 6f 63 28  rn pcache1Alloc(
2fe0: 73 7a 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72  sz);.}../*.** Fr
2ff0: 65 65 20 61 6e 20 61 6c 6c 6f 63 61 74 65 64 20  ee an allocated 
3000: 62 75 66 66 65 72 20 6f 62 74 61 69 6e 65 64 20  buffer obtained 
3010: 66 72 6f 6d 20 73 71 6c 69 74 65 33 50 61 67 65  from sqlite3Page
3020: 4d 61 6c 6c 6f 63 28 29 2e 0a 2a 2f 0a 76 6f 69  Malloc()..*/.voi
3030: 64 20 73 71 6c 69 74 65 33 50 61 67 65 46 72 65  d sqlite3PageFre
3040: 65 28 76 6f 69 64 20 2a 70 29 7b 0a 20 20 70 63  e(void *p){.  pc
3050: 61 63 68 65 31 46 72 65 65 28 70 29 3b 0a 7d 0a  ache1Free(p);.}.
3060: 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74  ../*.** Return t
3070: 72 75 65 20 69 66 20 69 74 20 64 65 73 69 72 61  rue if it desira
3080: 62 6c 65 20 74 6f 20 61 76 6f 69 64 20 61 6c 6c  ble to avoid all
3090: 6f 63 61 74 69 6e 67 20 61 20 6e 65 77 20 70 61  ocating a new pa
30a0: 67 65 20 63 61 63 68 65 0a 2a 2a 20 65 6e 74 72  ge cache.** entr
30b0: 79 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 6d 65 6d 6f  y..**.** If memo
30c0: 72 79 20 77 61 73 20 61 6c 6c 6f 63 61 74 65 64  ry was allocated
30d0: 20 73 70 65 63 69 66 69 63 61 6c 6c 79 20 74 6f   specifically to
30e0: 20 74 68 65 20 70 61 67 65 20 63 61 63 68 65 20   the page cache 
30f0: 75 73 69 6e 67 0a 2a 2a 20 53 51 4c 49 54 45 5f  using.** SQLITE_
3100: 43 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48 45  CONFIG_PAGECACHE
3110: 20 62 75 74 20 74 68 61 74 20 6d 65 6d 6f 72 79   but that memory
3120: 20 68 61 73 20 61 6c 6c 20 62 65 65 6e 20 75 73   has all been us
3130: 65 64 2c 20 74 68 65 6e 0a 2a 2a 20 69 74 20 69  ed, then.** it i
3140: 73 20 64 65 73 69 72 61 62 6c 65 20 74 6f 20 61  s desirable to a
3150: 76 6f 69 64 20 61 6c 6c 6f 63 61 74 69 6e 67 20  void allocating 
3160: 61 20 6e 65 77 20 70 61 67 65 20 63 61 63 68 65  a new page cache
3170: 20 65 6e 74 72 79 20 62 65 63 61 75 73 65 0a 2a   entry because.*
3180: 2a 20 70 72 65 73 75 6d 61 62 6c 79 20 53 51 4c  * presumably SQL
3190: 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43  ITE_CONFIG_PAGEC
31a0: 41 43 48 45 20 77 61 73 20 73 75 70 70 6f 73 65  ACHE was suppose
31b0: 20 74 6f 20 62 65 20 73 75 66 66 69 63 69 65 6e   to be sufficien
31c0: 74 0a 2a 2a 20 66 6f 72 20 61 6c 6c 20 70 61 67  t.** for all pag
31d0: 65 20 63 61 63 68 65 20 6e 65 65 64 73 20 61 6e  e cache needs an
31e0: 64 20 77 65 20 73 68 6f 75 6c 64 20 6e 6f 74 20  d we should not 
31f0: 6e 65 65 64 20 74 6f 20 73 70 69 6c 6c 20 74 68  need to spill th
3200: 65 0a 2a 2a 20 61 6c 6c 6f 63 61 74 69 6f 6e 20  e.** allocation 
3210: 6f 6e 74 6f 20 74 68 65 20 68 65 61 70 2e 0a 2a  onto the heap..*
3220: 2a 0a 2a 2a 20 4f 72 2c 20 74 68 65 20 68 65 61  *.** Or, the hea
3230: 70 20 69 73 20 75 73 65 64 20 66 6f 72 20 61 6c  p is used for al
3240: 6c 20 70 61 67 65 20 63 61 63 68 65 20 6d 65 6d  l page cache mem
3250: 6f 72 79 20 70 75 74 20 74 68 65 20 68 65 61 70  ory put the heap
3260: 20 69 73 0a 2a 2a 20 75 6e 64 65 72 20 6d 65 6d   is.** under mem
3270: 6f 72 79 20 70 72 65 73 73 75 72 65 2c 20 74 68  ory pressure, th
3280: 65 6e 20 61 67 61 69 6e 20 69 74 20 69 73 20 64  en again it is d
3290: 65 73 69 72 61 62 6c 65 20 74 6f 20 61 76 6f 69  esirable to avoi
32a0: 64 0a 2a 2a 20 61 6c 6c 6f 63 61 74 69 6e 67 20  d.** allocating 
32b0: 61 20 6e 65 77 20 70 61 67 65 20 63 61 63 68 65  a new page cache
32c0: 20 65 6e 74 72 79 20 69 6e 20 6f 72 64 65 72 20   entry in order 
32d0: 74 6f 20 61 76 6f 69 64 20 73 74 72 65 73 73 69  to avoid stressi
32e0: 6e 67 0a 2a 2a 20 74 68 65 20 68 65 61 70 20 65  ng.** the heap e
32f0: 76 65 6e 20 66 75 72 74 68 65 72 2e 0a 2a 2f 0a  ven further..*/.
3300: 73 74 61 74 69 63 20 69 6e 74 20 70 63 61 63 68  static int pcach
3310: 65 31 55 6e 64 65 72 4d 65 6d 6f 72 79 50 72 65  e1UnderMemoryPre
3320: 73 73 75 72 65 28 50 43 61 63 68 65 31 20 2a 70  ssure(PCache1 *p
3330: 43 61 63 68 65 29 7b 0a 20 20 69 66 28 20 70 63  Cache){.  if( pc
3340: 61 63 68 65 31 2e 6e 53 6c 6f 74 20 26 26 20 28  ache1.nSlot && (
3350: 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 2b 70  pCache->szPage+p
3360: 43 61 63 68 65 2d 3e 73 7a 45 78 74 72 61 29 3c  Cache->szExtra)<
3370: 3d 70 63 61 63 68 65 31 2e 73 7a 53 6c 6f 74 20  =pcache1.szSlot 
3380: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 70 63  ){.    return pc
3390: 61 63 68 65 31 2e 62 55 6e 64 65 72 50 72 65 73  ache1.bUnderPres
33a0: 73 75 72 65 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  sure;.  }else{. 
33b0: 20 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65     return sqlite
33c0: 33 48 65 61 70 4e 65 61 72 6c 79 46 75 6c 6c 28  3HeapNearlyFull(
33d0: 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a  );.  }.}../*****
33e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
33f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3400: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3410: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3420: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 2a 2a 2a  *********/./****
3430: 2a 2a 2a 2a 20 47 65 6e 65 72 61 6c 20 49 6d 70  **** General Imp
3440: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 46 75 6e 63  lementation Func
3450: 74 69 6f 6e 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  tions **********
3460: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3470: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f 2a 0a  **********/../*.
3480: 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
3490: 20 69 73 20 75 73 65 64 20 74 6f 20 72 65 73 69   is used to resi
34a0: 7a 65 20 74 68 65 20 68 61 73 68 20 74 61 62 6c  ze the hash tabl
34b0: 65 20 75 73 65 64 20 62 79 20 74 68 65 20 63 61  e used by the ca
34c0: 63 68 65 20 70 61 73 73 65 64 0a 2a 2a 20 61 73  che passed.** as
34d0: 20 74 68 65 20 66 69 72 73 74 20 61 72 67 75 6d   the first argum
34e0: 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 50  ent..**.** The P
34f0: 43 61 63 68 65 20 6d 75 74 65 78 20 6d 75 73 74  Cache mutex must
3500: 20 62 65 20 68 65 6c 64 20 77 68 65 6e 20 74 68   be held when th
3510: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63  is function is c
3520: 61 6c 6c 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63  alled..*/.static
3530: 20 69 6e 74 20 70 63 61 63 68 65 31 52 65 73 69   int pcache1Resi
3540: 7a 65 48 61 73 68 28 50 43 61 63 68 65 31 20 2a  zeHash(PCache1 *
3550: 70 29 7b 0a 20 20 50 67 48 64 72 31 20 2a 2a 61  p){.  PgHdr1 **a
3560: 70 4e 65 77 3b 0a 20 20 75 6e 73 69 67 6e 65 64  pNew;.  unsigned
3570: 20 69 6e 74 20 6e 4e 65 77 3b 0a 20 20 75 6e 73   int nNew;.  uns
3580: 69 67 6e 65 64 20 69 6e 74 20 69 3b 0a 0a 20 20  igned int i;..  
3590: 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f  assert( sqlite3_
35a0: 6d 75 74 65 78 5f 68 65 6c 64 28 70 2d 3e 70 47  mutex_held(p->pG
35b0: 72 6f 75 70 2d 3e 6d 75 74 65 78 29 20 29 3b 0a  roup->mutex) );.
35c0: 0a 20 20 6e 4e 65 77 20 3d 20 70 2d 3e 6e 48 61  .  nNew = p->nHa
35d0: 73 68 2a 32 3b 0a 20 20 69 66 28 20 6e 4e 65 77  sh*2;.  if( nNew
35e0: 3c 32 35 36 20 29 7b 0a 20 20 20 20 6e 4e 65 77  <256 ){.    nNew
35f0: 20 3d 20 32 35 36 3b 0a 20 20 7d 0a 0a 20 20 70   = 256;.  }..  p
3600: 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78  cache1LeaveMutex
3610: 28 70 2d 3e 70 47 72 6f 75 70 29 3b 0a 20 20 69  (p->pGroup);.  i
3620: 66 28 20 70 2d 3e 6e 48 61 73 68 20 29 7b 20 73  f( p->nHash ){ s
3630: 71 6c 69 74 65 33 42 65 67 69 6e 42 65 6e 69 67  qlite3BeginBenig
3640: 6e 4d 61 6c 6c 6f 63 28 29 3b 20 7d 0a 20 20 61  nMalloc(); }.  a
3650: 70 4e 65 77 20 3d 20 28 50 67 48 64 72 31 20 2a  pNew = (PgHdr1 *
3660: 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63  *)sqlite3_malloc
3670: 28 73 69 7a 65 6f 66 28 50 67 48 64 72 31 20 2a  (sizeof(PgHdr1 *
3680: 29 2a 6e 4e 65 77 29 3b 0a 20 20 69 66 28 20 70  )*nNew);.  if( p
3690: 2d 3e 6e 48 61 73 68 20 29 7b 20 73 71 6c 69 74  ->nHash ){ sqlit
36a0: 65 33 45 6e 64 42 65 6e 69 67 6e 4d 61 6c 6c 6f  e3EndBenignMallo
36b0: 63 28 29 3b 20 7d 0a 20 20 70 63 61 63 68 65 31  c(); }.  pcache1
36c0: 45 6e 74 65 72 4d 75 74 65 78 28 70 2d 3e 70 47  EnterMutex(p->pG
36d0: 72 6f 75 70 29 3b 0a 20 20 69 66 28 20 61 70 4e  roup);.  if( apN
36e0: 65 77 20 29 7b 0a 20 20 20 20 6d 65 6d 73 65 74  ew ){.    memset
36f0: 28 61 70 4e 65 77 2c 20 30 2c 20 73 69 7a 65 6f  (apNew, 0, sizeo
3700: 66 28 50 67 48 64 72 31 20 2a 29 2a 6e 4e 65 77  f(PgHdr1 *)*nNew
3710: 29 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20  );.    for(i=0; 
3720: 69 3c 70 2d 3e 6e 48 61 73 68 3b 20 69 2b 2b 29  i<p->nHash; i++)
3730: 7b 0a 20 20 20 20 20 20 50 67 48 64 72 31 20 2a  {.      PgHdr1 *
3740: 70 50 61 67 65 3b 0a 20 20 20 20 20 20 50 67 48  pPage;.      PgH
3750: 64 72 31 20 2a 70 4e 65 78 74 20 3d 20 70 2d 3e  dr1 *pNext = p->
3760: 61 70 48 61 73 68 5b 69 5d 3b 0a 20 20 20 20 20  apHash[i];.     
3770: 20 77 68 69 6c 65 28 20 28 70 50 61 67 65 20 3d   while( (pPage =
3780: 20 70 4e 65 78 74 29 21 3d 30 20 29 7b 0a 20 20   pNext)!=0 ){.  
3790: 20 20 20 20 20 20 75 6e 73 69 67 6e 65 64 20 69        unsigned i
37a0: 6e 74 20 68 20 3d 20 70 50 61 67 65 2d 3e 69 4b  nt h = pPage->iK
37b0: 65 79 20 25 20 6e 4e 65 77 3b 0a 20 20 20 20 20  ey % nNew;.     
37c0: 20 20 20 70 4e 65 78 74 20 3d 20 70 50 61 67 65     pNext = pPage
37d0: 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 20  ->pNext;.       
37e0: 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 20 3d 20   pPage->pNext = 
37f0: 61 70 4e 65 77 5b 68 5d 3b 0a 20 20 20 20 20 20  apNew[h];.      
3800: 20 20 61 70 4e 65 77 5b 68 5d 20 3d 20 70 50 61    apNew[h] = pPa
3810: 67 65 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  ge;.      }.    
3820: 7d 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72  }.    sqlite3_fr
3830: 65 65 28 70 2d 3e 61 70 48 61 73 68 29 3b 0a 20  ee(p->apHash);. 
3840: 20 20 20 70 2d 3e 61 70 48 61 73 68 20 3d 20 61     p->apHash = a
3850: 70 4e 65 77 3b 0a 20 20 20 20 70 2d 3e 6e 48 61  pNew;.    p->nHa
3860: 73 68 20 3d 20 6e 4e 65 77 3b 0a 20 20 7d 0a 0a  sh = nNew;.  }..
3870: 20 20 72 65 74 75 72 6e 20 28 70 2d 3e 61 70 48    return (p->apH
3880: 61 73 68 20 3f 20 53 51 4c 49 54 45 5f 4f 4b 20  ash ? SQLITE_OK 
3890: 3a 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 29 3b  : SQLITE_NOMEM);
38a0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66  .}../*.** This f
38b0: 75 6e 63 74 69 6f 6e 20 69 73 20 75 73 65 64 20  unction is used 
38c0: 69 6e 74 65 72 6e 61 6c 6c 79 20 74 6f 20 72 65  internally to re
38d0: 6d 6f 76 65 20 74 68 65 20 70 61 67 65 20 70 50  move the page pP
38e0: 61 67 65 20 66 72 6f 6d 20 74 68 65 20 0a 2a 2a  age from the .**
38f0: 20 50 47 72 6f 75 70 20 4c 52 55 20 6c 69 73 74   PGroup LRU list
3900: 2c 20 69 66 20 69 73 20 70 61 72 74 20 6f 66 20  , if is part of 
3910: 69 74 2e 20 49 66 20 70 50 61 67 65 20 69 73 20  it. If pPage is 
3920: 6e 6f 74 20 70 61 72 74 20 6f 66 20 74 68 65 20  not part of the 
3930: 50 47 72 6f 75 70 0a 2a 2a 20 4c 52 55 20 6c 69  PGroup.** LRU li
3940: 73 74 2c 20 74 68 65 6e 20 74 68 69 73 20 66 75  st, then this fu
3950: 6e 63 74 69 6f 6e 20 69 73 20 61 20 6e 6f 2d 6f  nction is a no-o
3960: 70 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 50 47 72  p..**.** The PGr
3970: 6f 75 70 20 6d 75 74 65 78 20 6d 75 73 74 20 62  oup mutex must b
3980: 65 20 68 65 6c 64 20 77 68 65 6e 20 74 68 69 73  e held when this
3990: 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c   function is cal
39a0: 6c 65 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 70 50  led..**.** If pP
39b0: 61 67 65 20 69 73 20 4e 55 4c 4c 20 74 68 65 6e  age is NULL then
39c0: 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 69 73   this routine is
39d0: 20 61 20 6e 6f 2d 6f 70 2e 0a 2a 2f 0a 73 74 61   a no-op..*/.sta
39e0: 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 31  tic void pcache1
39f0: 50 69 6e 50 61 67 65 28 50 67 48 64 72 31 20 2a  PinPage(PgHdr1 *
3a00: 70 50 61 67 65 29 7b 0a 20 20 50 43 61 63 68 65  pPage){.  PCache
3a10: 31 20 2a 70 43 61 63 68 65 3b 0a 20 20 50 47 72  1 *pCache;.  PGr
3a20: 6f 75 70 20 2a 70 47 72 6f 75 70 3b 0a 0a 20 20  oup *pGroup;..  
3a30: 69 66 28 20 70 50 61 67 65 3d 3d 30 20 29 20 72  if( pPage==0 ) r
3a40: 65 74 75 72 6e 3b 0a 20 20 70 43 61 63 68 65 20  eturn;.  pCache 
3a50: 3d 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65 3b  = pPage->pCache;
3a60: 0a 20 20 70 47 72 6f 75 70 20 3d 20 70 43 61 63  .  pGroup = pCac
3a70: 68 65 2d 3e 70 47 72 6f 75 70 3b 0a 20 20 61 73  he->pGroup;.  as
3a80: 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75  sert( sqlite3_mu
3a90: 74 65 78 5f 68 65 6c 64 28 70 47 72 6f 75 70 2d  tex_held(pGroup-
3aa0: 3e 6d 75 74 65 78 29 20 29 3b 0a 20 20 69 66 28  >mutex) );.  if(
3ab0: 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74   pPage->pLruNext
3ac0: 20 7c 7c 20 70 50 61 67 65 3d 3d 70 47 72 6f 75   || pPage==pGrou
3ad0: 70 2d 3e 70 4c 72 75 54 61 69 6c 20 29 7b 0a 20  p->pLruTail ){. 
3ae0: 20 20 20 69 66 28 20 70 50 61 67 65 2d 3e 70 4c     if( pPage->pL
3af0: 72 75 50 72 65 76 20 29 7b 0a 20 20 20 20 20 20  ruPrev ){.      
3b00: 70 50 61 67 65 2d 3e 70 4c 72 75 50 72 65 76 2d  pPage->pLruPrev-
3b10: 3e 70 4c 72 75 4e 65 78 74 20 3d 20 70 50 61 67  >pLruNext = pPag
3b20: 65 2d 3e 70 4c 72 75 4e 65 78 74 3b 0a 20 20 20  e->pLruNext;.   
3b30: 20 7d 0a 20 20 20 20 69 66 28 20 70 50 61 67 65   }.    if( pPage
3b40: 2d 3e 70 4c 72 75 4e 65 78 74 20 29 7b 0a 20 20  ->pLruNext ){.  
3b50: 20 20 20 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e      pPage->pLruN
3b60: 65 78 74 2d 3e 70 4c 72 75 50 72 65 76 20 3d 20  ext->pLruPrev = 
3b70: 70 50 61 67 65 2d 3e 70 4c 72 75 50 72 65 76 3b  pPage->pLruPrev;
3b80: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70  .    }.    if( p
3b90: 47 72 6f 75 70 2d 3e 70 4c 72 75 48 65 61 64 3d  Group->pLruHead=
3ba0: 3d 70 50 61 67 65 20 29 7b 0a 20 20 20 20 20 20  =pPage ){.      
3bb0: 70 47 72 6f 75 70 2d 3e 70 4c 72 75 48 65 61 64  pGroup->pLruHead
3bc0: 20 3d 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65   = pPage->pLruNe
3bd0: 78 74 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66  xt;.    }.    if
3be0: 28 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 54 61  ( pGroup->pLruTa
3bf0: 69 6c 3d 3d 70 50 61 67 65 20 29 7b 0a 20 20 20  il==pPage ){.   
3c00: 20 20 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 54     pGroup->pLruT
3c10: 61 69 6c 20 3d 20 70 50 61 67 65 2d 3e 70 4c 72  ail = pPage->pLr
3c20: 75 50 72 65 76 3b 0a 20 20 20 20 7d 0a 20 20 20  uPrev;.    }.   
3c30: 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74   pPage->pLruNext
3c40: 20 3d 20 30 3b 0a 20 20 20 20 70 50 61 67 65 2d   = 0;.    pPage-
3c50: 3e 70 4c 72 75 50 72 65 76 20 3d 20 30 3b 0a 20  >pLruPrev = 0;. 
3c60: 20 20 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65     pPage->pCache
3c70: 2d 3e 6e 52 65 63 79 63 6c 61 62 6c 65 2d 2d 3b  ->nRecyclable--;
3c80: 0a 20 20 7d 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 52  .  }.}.../*.** R
3c90: 65 6d 6f 76 65 20 74 68 65 20 70 61 67 65 20 73  emove the page s
3ca0: 75 70 70 6c 69 65 64 20 61 73 20 61 6e 20 61 72  upplied as an ar
3cb0: 67 75 6d 65 6e 74 20 66 72 6f 6d 20 74 68 65 20  gument from the 
3cc0: 68 61 73 68 20 74 61 62 6c 65 20 0a 2a 2a 20 28  hash table .** (
3cd0: 50 43 61 63 68 65 31 2e 61 70 48 61 73 68 20 73  PCache1.apHash s
3ce0: 74 72 75 63 74 75 72 65 29 20 74 68 61 74 20 69  tructure) that i
3cf0: 74 20 69 73 20 63 75 72 72 65 6e 74 6c 79 20 73  t is currently s
3d00: 74 6f 72 65 64 20 69 6e 2e 0a 2a 2a 0a 2a 2a 20  tored in..**.** 
3d10: 54 68 65 20 50 47 72 6f 75 70 20 6d 75 74 65 78  The PGroup mutex
3d20: 20 6d 75 73 74 20 62 65 20 68 65 6c 64 20 77 68   must be held wh
3d30: 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  en this function
3d40: 20 69 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f 0a 73   is called..*/.s
3d50: 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68  tatic void pcach
3d60: 65 31 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73 68  e1RemoveFromHash
3d70: 28 50 67 48 64 72 31 20 2a 70 50 61 67 65 29 7b  (PgHdr1 *pPage){
3d80: 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  .  unsigned int 
3d90: 68 3b 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43  h;.  PCache1 *pC
3da0: 61 63 68 65 20 3d 20 70 50 61 67 65 2d 3e 70 43  ache = pPage->pC
3db0: 61 63 68 65 3b 0a 20 20 50 67 48 64 72 31 20 2a  ache;.  PgHdr1 *
3dc0: 2a 70 70 3b 0a 0a 20 20 61 73 73 65 72 74 28 20  *pp;..  assert( 
3dd0: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65  sqlite3_mutex_he
3de0: 6c 64 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75  ld(pCache->pGrou
3df0: 70 2d 3e 6d 75 74 65 78 29 20 29 3b 0a 20 20 68  p->mutex) );.  h
3e00: 20 3d 20 70 50 61 67 65 2d 3e 69 4b 65 79 20 25   = pPage->iKey %
3e10: 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3b 0a   pCache->nHash;.
3e20: 20 20 66 6f 72 28 70 70 3d 26 70 43 61 63 68 65    for(pp=&pCache
3e30: 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 20 28 2a 70  ->apHash[h]; (*p
3e40: 70 29 21 3d 70 50 61 67 65 3b 20 70 70 3d 26 28  p)!=pPage; pp=&(
3e50: 2a 70 70 29 2d 3e 70 4e 65 78 74 29 3b 0a 20 20  *pp)->pNext);.  
3e60: 2a 70 70 20 3d 20 28 2a 70 70 29 2d 3e 70 4e 65  *pp = (*pp)->pNe
3e70: 78 74 3b 0a 0a 20 20 70 43 61 63 68 65 2d 3e 6e  xt;..  pCache->n
3e80: 50 61 67 65 2d 2d 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  Page--;.}../*.**
3e90: 20 49 66 20 74 68 65 72 65 20 61 72 65 20 63 75   If there are cu
3ea0: 72 72 65 6e 74 6c 79 20 6d 6f 72 65 20 74 68 61  rrently more tha
3eb0: 6e 20 6e 4d 61 78 50 61 67 65 20 70 61 67 65 73  n nMaxPage pages
3ec0: 20 61 6c 6c 6f 63 61 74 65 64 2c 20 74 72 79 0a   allocated, try.
3ed0: 2a 2a 20 74 6f 20 72 65 63 79 63 6c 65 20 70 61  ** to recycle pa
3ee0: 67 65 73 20 74 6f 20 72 65 64 75 63 65 20 74 68  ges to reduce th
3ef0: 65 20 6e 75 6d 62 65 72 20 61 6c 6c 6f 63 61 74  e number allocat
3f00: 65 64 20 74 6f 20 6e 4d 61 78 50 61 67 65 2e 0a  ed to nMaxPage..
3f10: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70  */.static void p
3f20: 63 61 63 68 65 31 45 6e 66 6f 72 63 65 4d 61 78  cache1EnforceMax
3f30: 50 61 67 65 28 50 47 72 6f 75 70 20 2a 70 47 72  Page(PGroup *pGr
3f40: 6f 75 70 29 7b 0a 20 20 61 73 73 65 72 74 28 20  oup){.  assert( 
3f50: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65  sqlite3_mutex_he
3f60: 6c 64 28 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78  ld(pGroup->mutex
3f70: 29 20 29 3b 0a 20 20 77 68 69 6c 65 28 20 70 47  ) );.  while( pG
3f80: 72 6f 75 70 2d 3e 6e 43 75 72 72 65 6e 74 50 61  roup->nCurrentPa
3f90: 67 65 3e 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50  ge>pGroup->nMaxP
3fa0: 61 67 65 20 26 26 20 70 47 72 6f 75 70 2d 3e 70  age && pGroup->p
3fb0: 4c 72 75 54 61 69 6c 20 29 7b 0a 20 20 20 20 50  LruTail ){.    P
3fc0: 67 48 64 72 31 20 2a 70 20 3d 20 70 47 72 6f 75  gHdr1 *p = pGrou
3fd0: 70 2d 3e 70 4c 72 75 54 61 69 6c 3b 0a 20 20 20  p->pLruTail;.   
3fe0: 20 61 73 73 65 72 74 28 20 70 2d 3e 70 43 61 63   assert( p->pCac
3ff0: 68 65 2d 3e 70 47 72 6f 75 70 3d 3d 70 47 72 6f  he->pGroup==pGro
4000: 75 70 20 29 3b 0a 20 20 20 20 70 63 61 63 68 65  up );.    pcache
4010: 31 50 69 6e 50 61 67 65 28 70 29 3b 0a 20 20 20  1PinPage(p);.   
4020: 20 70 63 61 63 68 65 31 52 65 6d 6f 76 65 46 72   pcache1RemoveFr
4030: 6f 6d 48 61 73 68 28 70 29 3b 0a 20 20 20 20 70  omHash(p);.    p
4040: 63 61 63 68 65 31 46 72 65 65 50 61 67 65 28 70  cache1FreePage(p
4050: 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  );.  }.}../*.** 
4060: 44 69 73 63 61 72 64 20 61 6c 6c 20 70 61 67 65  Discard all page
4070: 73 20 66 72 6f 6d 20 63 61 63 68 65 20 70 43 61  s from cache pCa
4080: 63 68 65 20 77 69 74 68 20 61 20 70 61 67 65 20  che with a page 
4090: 6e 75 6d 62 65 72 20 28 6b 65 79 20 76 61 6c 75  number (key valu
40a0: 65 29 20 0a 2a 2a 20 67 72 65 61 74 65 72 20 74  e) .** greater t
40b0: 68 61 6e 20 6f 72 20 65 71 75 61 6c 20 74 6f 20  han or equal to 
40c0: 69 4c 69 6d 69 74 2e 20 41 6e 79 20 70 69 6e 6e  iLimit. Any pinn
40d0: 65 64 20 70 61 67 65 73 20 74 68 61 74 20 6d 65  ed pages that me
40e0: 65 74 20 74 68 69 73 20 0a 2a 2a 20 63 72 69 74  et this .** crit
40f0: 65 72 69 61 20 61 72 65 20 75 6e 70 69 6e 6e 65  eria are unpinne
4100: 64 20 62 65 66 6f 72 65 20 74 68 65 79 20 61 72  d before they ar
4110: 65 20 64 69 73 63 61 72 64 65 64 2e 0a 2a 2a 0a  e discarded..**.
4120: 2a 2a 20 54 68 65 20 50 43 61 63 68 65 20 6d 75  ** The PCache mu
4130: 74 65 78 20 6d 75 73 74 20 62 65 20 68 65 6c 64  tex must be held
4140: 20 77 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74   when this funct
4150: 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 2e 0a 2a  ion is called..*
4160: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63  /.static void pc
4170: 61 63 68 65 31 54 72 75 6e 63 61 74 65 55 6e 73  ache1TruncateUns
4180: 61 66 65 28 0a 20 20 50 43 61 63 68 65 31 20 2a  afe(.  PCache1 *
4190: 70 43 61 63 68 65 2c 20 20 20 20 20 20 20 20 20  pCache,         
41a0: 20 20 20 20 2f 2a 20 54 68 65 20 63 61 63 68 65      /* The cache
41b0: 20 74 6f 20 74 72 75 6e 63 61 74 65 20 2a 2f 0a   to truncate */.
41c0: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69    unsigned int i
41d0: 4c 69 6d 69 74 20 20 20 20 20 20 20 20 20 20 2f  Limit          /
41e0: 2a 20 44 72 6f 70 20 70 61 67 65 73 20 77 69 74  * Drop pages wit
41f0: 68 20 74 68 69 73 20 70 67 6e 6f 20 6f 72 20 6c  h this pgno or l
4200: 61 72 67 65 72 20 2a 2f 0a 29 7b 0a 20 20 54 45  arger */.){.  TE
4210: 53 54 4f 4e 4c 59 28 20 75 6e 73 69 67 6e 65 64  STONLY( unsigned
4220: 20 69 6e 74 20 6e 50 61 67 65 20 3d 20 30 3b 20   int nPage = 0; 
4230: 29 20 20 2f 2a 20 54 6f 20 61 73 73 65 72 74 20  )  /* To assert 
4240: 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 20 69 73  pCache->nPage is
4250: 20 63 6f 72 72 65 63 74 20 2a 2f 0a 20 20 75 6e   correct */.  un
4260: 73 69 67 6e 65 64 20 69 6e 74 20 68 3b 0a 20 20  signed int h;.  
4270: 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f  assert( sqlite3_
4280: 6d 75 74 65 78 5f 68 65 6c 64 28 70 43 61 63 68  mutex_held(pCach
4290: 65 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78  e->pGroup->mutex
42a0: 29 20 29 3b 0a 20 20 66 6f 72 28 68 3d 30 3b 20  ) );.  for(h=0; 
42b0: 68 3c 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3b  h<pCache->nHash;
42c0: 20 68 2b 2b 29 7b 0a 20 20 20 20 50 67 48 64 72   h++){.    PgHdr
42d0: 31 20 2a 2a 70 70 20 3d 20 26 70 43 61 63 68 65  1 **pp = &pCache
42e0: 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 20 0a 20 20  ->apHash[h]; .  
42f0: 20 20 50 67 48 64 72 31 20 2a 70 50 61 67 65 3b    PgHdr1 *pPage;
4300: 0a 20 20 20 20 77 68 69 6c 65 28 20 28 70 50 61  .    while( (pPa
4310: 67 65 20 3d 20 2a 70 70 29 21 3d 30 20 29 7b 0a  ge = *pp)!=0 ){.
4320: 20 20 20 20 20 20 69 66 28 20 70 50 61 67 65 2d        if( pPage-
4330: 3e 69 4b 65 79 3e 3d 69 4c 69 6d 69 74 20 29 7b  >iKey>=iLimit ){
4340: 0a 20 20 20 20 20 20 20 20 70 43 61 63 68 65 2d  .        pCache-
4350: 3e 6e 50 61 67 65 2d 2d 3b 0a 20 20 20 20 20 20  >nPage--;.      
4360: 20 20 2a 70 70 20 3d 20 70 50 61 67 65 2d 3e 70    *pp = pPage->p
4370: 4e 65 78 74 3b 0a 20 20 20 20 20 20 20 20 70 63  Next;.        pc
4380: 61 63 68 65 31 50 69 6e 50 61 67 65 28 70 50 61  ache1PinPage(pPa
4390: 67 65 29 3b 0a 20 20 20 20 20 20 20 20 70 63 61  ge);.        pca
43a0: 63 68 65 31 46 72 65 65 50 61 67 65 28 70 50 61  che1FreePage(pPa
43b0: 67 65 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65  ge);.      }else
43c0: 7b 0a 20 20 20 20 20 20 20 20 70 70 20 3d 20 26  {.        pp = &
43d0: 70 50 61 67 65 2d 3e 70 4e 65 78 74 3b 0a 20 20  pPage->pNext;.  
43e0: 20 20 20 20 20 20 54 45 53 54 4f 4e 4c 59 28 20        TESTONLY( 
43f0: 6e 50 61 67 65 2b 2b 3b 20 29 0a 20 20 20 20 20  nPage++; ).     
4400: 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 61   }.    }.  }.  a
4410: 73 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e 6e  ssert( pCache->n
4420: 50 61 67 65 3d 3d 6e 50 61 67 65 20 29 3b 0a 7d  Page==nPage );.}
4430: 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ../*************
4440: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4450: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4460: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4470: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4480: 2a 2f 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 20 73 71 6c  */./******** sql
4490: 69 74 65 33 5f 70 63 61 63 68 65 20 4d 65 74 68  ite3_pcache Meth
44a0: 6f 64 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ods ************
44b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
44c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
44d0: 2a 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65  **/../*.** Imple
44e0: 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65  mentation of the
44f0: 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e   sqlite3_pcache.
4500: 78 49 6e 69 74 20 6d 65 74 68 6f 64 2e 0a 2a 2f  xInit method..*/
4510: 0a 73 74 61 74 69 63 20 69 6e 74 20 70 63 61 63  .static int pcac
4520: 68 65 31 49 6e 69 74 28 76 6f 69 64 20 2a 4e 6f  he1Init(void *No
4530: 74 55 73 65 64 29 7b 0a 20 20 55 4e 55 53 45 44  tUsed){.  UNUSED
4540: 5f 50 41 52 41 4d 45 54 45 52 28 4e 6f 74 55 73  _PARAMETER(NotUs
4550: 65 64 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70  ed);.  assert( p
4560: 63 61 63 68 65 31 2e 69 73 49 6e 69 74 3d 3d 30  cache1.isInit==0
4570: 20 29 3b 0a 20 20 6d 65 6d 73 65 74 28 26 70 63   );.  memset(&pc
4580: 61 63 68 65 31 2c 20 30 2c 20 73 69 7a 65 6f 66  ache1, 0, sizeof
4590: 28 70 63 61 63 68 65 31 29 29 3b 0a 20 20 69 66  (pcache1));.  if
45a0: 28 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43  ( sqlite3GlobalC
45b0: 6f 6e 66 69 67 2e 62 43 6f 72 65 4d 75 74 65 78  onfig.bCoreMutex
45c0: 20 29 7b 0a 20 20 20 20 70 63 61 63 68 65 31 2e   ){.    pcache1.
45d0: 67 72 70 2e 6d 75 74 65 78 20 3d 20 73 71 6c 69  grp.mutex = sqli
45e0: 74 65 33 5f 6d 75 74 65 78 5f 61 6c 6c 6f 63 28  te3_mutex_alloc(
45f0: 53 51 4c 49 54 45 5f 4d 55 54 45 58 5f 53 54 41  SQLITE_MUTEX_STA
4600: 54 49 43 5f 4c 52 55 29 3b 0a 20 20 20 20 70 63  TIC_LRU);.    pc
4610: 61 63 68 65 31 2e 6d 75 74 65 78 20 3d 20 73 71  ache1.mutex = sq
4620: 6c 69 74 65 33 5f 6d 75 74 65 78 5f 61 6c 6c 6f  lite3_mutex_allo
4630: 63 28 53 51 4c 49 54 45 5f 4d 55 54 45 58 5f 53  c(SQLITE_MUTEX_S
4640: 54 41 54 49 43 5f 50 4d 45 4d 29 3b 0a 20 20 7d  TATIC_PMEM);.  }
4650: 0a 20 20 70 63 61 63 68 65 31 2e 67 72 70 2e 6d  .  pcache1.grp.m
4660: 78 50 69 6e 6e 65 64 20 3d 20 31 30 3b 0a 20 20  xPinned = 10;.  
4670: 70 63 61 63 68 65 31 2e 69 73 49 6e 69 74 20 3d  pcache1.isInit =
4680: 20 31 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c   1;.  return SQL
4690: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ITE_OK;.}../*.**
46a0: 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20   Implementation 
46b0: 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70  of the sqlite3_p
46c0: 63 61 63 68 65 2e 78 53 68 75 74 64 6f 77 6e 20  cache.xShutdown 
46d0: 6d 65 74 68 6f 64 2e 0a 2a 2a 20 4e 6f 74 65 20  method..** Note 
46e0: 74 68 61 74 20 74 68 65 20 73 74 61 74 69 63 20  that the static 
46f0: 6d 75 74 65 78 20 61 6c 6c 6f 63 61 74 65 64 20  mutex allocated 
4700: 69 6e 20 78 49 6e 69 74 20 64 6f 65 73 20 0a 2a  in xInit does .*
4710: 2a 20 6e 6f 74 20 6e 65 65 64 20 74 6f 20 62 65  * not need to be
4720: 20 66 72 65 65 64 2e 0a 2a 2f 0a 73 74 61 74 69   freed..*/.stati
4730: 63 20 76 6f 69 64 20 70 63 61 63 68 65 31 53 68  c void pcache1Sh
4740: 75 74 64 6f 77 6e 28 76 6f 69 64 20 2a 4e 6f 74  utdown(void *Not
4750: 55 73 65 64 29 7b 0a 20 20 55 4e 55 53 45 44 5f  Used){.  UNUSED_
4760: 50 41 52 41 4d 45 54 45 52 28 4e 6f 74 55 73 65  PARAMETER(NotUse
4770: 64 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 63  d);.  assert( pc
4780: 61 63 68 65 31 2e 69 73 49 6e 69 74 21 3d 30 20  ache1.isInit!=0 
4790: 29 3b 0a 20 20 6d 65 6d 73 65 74 28 26 70 63 61  );.  memset(&pca
47a0: 63 68 65 31 2c 20 30 2c 20 73 69 7a 65 6f 66 28  che1, 0, sizeof(
47b0: 70 63 61 63 68 65 31 29 29 3b 0a 7d 0a 0a 2f 2a  pcache1));.}../*
47c0: 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69  .** Implementati
47d0: 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65  on of the sqlite
47e0: 33 5f 70 63 61 63 68 65 2e 78 43 72 65 61 74 65  3_pcache.xCreate
47f0: 20 6d 65 74 68 6f 64 2e 0a 2a 2a 0a 2a 2a 20 41   method..**.** A
4800: 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 63 61  llocate a new ca
4810: 63 68 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 73  che..*/.static s
4820: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70  qlite3_pcache *p
4830: 63 61 63 68 65 31 43 72 65 61 74 65 28 69 6e 74  cache1Create(int
4840: 20 73 7a 50 61 67 65 2c 20 69 6e 74 20 73 7a 45   szPage, int szE
4850: 78 74 72 61 2c 20 69 6e 74 20 62 50 75 72 67 65  xtra, int bPurge
4860: 61 62 6c 65 29 7b 0a 20 20 50 43 61 63 68 65 31  able){.  PCache1
4870: 20 2a 70 43 61 63 68 65 3b 20 20 20 20 20 20 2f   *pCache;      /
4880: 2a 20 54 68 65 20 6e 65 77 6c 79 20 63 72 65 61  * The newly crea
4890: 74 65 64 20 70 61 67 65 20 63 61 63 68 65 20 2a  ted page cache *
48a0: 2f 0a 20 20 50 47 72 6f 75 70 20 2a 70 47 72 6f  /.  PGroup *pGro
48b0: 75 70 3b 20 20 20 20 20 20 20 2f 2a 20 54 68 65  up;       /* The
48c0: 20 67 72 6f 75 70 20 74 68 65 20 6e 65 77 20 70   group the new p
48d0: 61 67 65 20 63 61 63 68 65 20 77 69 6c 6c 20 62  age cache will b
48e0: 65 6c 6f 6e 67 20 74 6f 20 2a 2f 0a 20 20 69 6e  elong to */.  in
48f0: 74 20 73 7a 3b 20 20 20 20 20 20 20 20 20 20 20  t sz;           
4900: 20 20 20 20 2f 2a 20 42 79 74 65 73 20 6f 66 20      /* Bytes of 
4910: 6d 65 6d 6f 72 79 20 72 65 71 75 69 72 65 64 20  memory required 
4920: 74 6f 20 61 6c 6c 6f 63 61 74 65 20 74 68 65 20  to allocate the 
4930: 6e 65 77 20 63 61 63 68 65 20 2a 2f 0a 0a 20 20  new cache */..  
4940: 2f 2a 0a 20 20 2a 2a 20 54 68 65 20 73 65 70 65  /*.  ** The sepe
4950: 72 61 74 65 43 61 63 68 65 20 76 61 72 69 61 62  rateCache variab
4960: 6c 65 20 69 73 20 74 72 75 65 20 69 66 20 65 61  le is true if ea
4970: 63 68 20 50 43 61 63 68 65 20 68 61 73 20 69 74  ch PCache has it
4980: 73 20 6f 77 6e 20 70 72 69 76 61 74 65 0a 20 20  s own private.  
4990: 2a 2a 20 50 47 72 6f 75 70 2e 20 20 49 6e 20 6f  ** PGroup.  In o
49a0: 74 68 65 72 20 77 6f 72 64 73 2c 20 73 65 70 61  ther words, sepa
49b0: 72 61 74 65 43 61 63 68 65 20 69 73 20 74 72 75  rateCache is tru
49c0: 65 20 66 6f 72 20 6d 6f 64 65 20 28 31 29 20 77  e for mode (1) w
49d0: 68 65 72 65 20 6e 6f 0a 20 20 2a 2a 20 6d 75 74  here no.  ** mut
49e0: 65 78 69 6e 67 20 69 73 20 72 65 71 75 69 72 65  exing is require
49f0: 64 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 2a  d..  **.  **   *
4a00: 20 20 41 6c 77 61 79 73 20 75 73 65 20 61 20 75    Always use a u
4a10: 6e 69 66 69 65 64 20 63 61 63 68 65 20 28 6d 6f  nified cache (mo
4a20: 64 65 2d 32 29 20 69 66 20 45 4e 41 42 4c 45 5f  de-2) if ENABLE_
4a30: 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e  MEMORY_MANAGEMEN
4a40: 54 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 2a 20  T.  **.  **   * 
4a50: 20 41 6c 77 61 79 73 20 75 73 65 20 61 20 75 6e   Always use a un
4a60: 69 66 69 65 64 20 63 61 63 68 65 20 69 6e 20 73  ified cache in s
4a70: 69 6e 67 6c 65 2d 74 68 72 65 61 64 65 64 20 61  ingle-threaded a
4a80: 70 70 6c 69 63 61 74 69 6f 6e 73 0a 20 20 2a 2a  pplications.  **
4a90: 0a 20 20 2a 2a 20 20 20 2a 20 20 4f 74 68 65 72  .  **   *  Other
4aa0: 77 69 73 65 20 28 69 66 20 6d 75 6c 74 69 2d 74  wise (if multi-t
4ab0: 68 72 65 61 64 65 64 20 61 6e 64 20 45 4e 41 42  hreaded and ENAB
4ac0: 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47 45  LE_MEMORY_MANAGE
4ad0: 4d 45 4e 54 20 69 73 20 6f 66 66 29 0a 20 20 2a  MENT is off).  *
4ae0: 2a 20 20 20 20 20 20 75 73 65 20 73 65 70 61 72  *      use separ
4af0: 61 74 65 20 63 61 63 68 65 73 20 28 6d 6f 64 65  ate caches (mode
4b00: 2d 31 29 0a 20 20 2a 2f 0a 23 69 66 20 64 65 66  -1).  */.#if def
4b10: 69 6e 65 64 28 53 51 4c 49 54 45 5f 45 4e 41 42  ined(SQLITE_ENAB
4b20: 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47 45  LE_MEMORY_MANAGE
4b30: 4d 45 4e 54 29 20 7c 7c 20 53 51 4c 49 54 45 5f  MENT) || SQLITE_
4b40: 54 48 52 45 41 44 53 41 46 45 3d 3d 30 0a 20 20  THREADSAFE==0.  
4b50: 63 6f 6e 73 74 20 69 6e 74 20 73 65 70 61 72 61  const int separa
4b60: 74 65 43 61 63 68 65 20 3d 20 30 3b 0a 23 65 6c  teCache = 0;.#el
4b70: 73 65 0a 20 20 69 6e 74 20 73 65 70 61 72 61 74  se.  int separat
4b80: 65 43 61 63 68 65 20 3d 20 73 71 6c 69 74 65 33  eCache = sqlite3
4b90: 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 62 43 6f  GlobalConfig.bCo
4ba0: 72 65 4d 75 74 65 78 3e 30 3b 0a 23 65 6e 64 69  reMutex>0;.#endi
4bb0: 66 0a 0a 20 20 61 73 73 65 72 74 28 20 28 73 7a  f..  assert( (sz
4bc0: 50 61 67 65 20 26 20 28 73 7a 50 61 67 65 2d 31  Page & (szPage-1
4bd0: 29 29 3d 3d 30 20 26 26 20 73 7a 50 61 67 65 3e  ))==0 && szPage>
4be0: 3d 35 31 32 20 26 26 20 73 7a 50 61 67 65 3c 3d  =512 && szPage<=
4bf0: 36 35 35 33 36 20 29 3b 0a 20 20 61 73 73 65 72  65536 );.  asser
4c00: 74 28 20 73 7a 45 78 74 72 61 20 3c 20 33 30 30  t( szExtra < 300
4c10: 20 29 3b 0a 0a 20 20 73 7a 20 3d 20 73 69 7a 65   );..  sz = size
4c20: 6f 66 28 50 43 61 63 68 65 31 29 20 2b 20 73 69  of(PCache1) + si
4c30: 7a 65 6f 66 28 50 47 72 6f 75 70 29 2a 73 65 70  zeof(PGroup)*sep
4c40: 61 72 61 74 65 43 61 63 68 65 3b 0a 20 20 70 43  arateCache;.  pC
4c50: 61 63 68 65 20 3d 20 28 50 43 61 63 68 65 31 20  ache = (PCache1 
4c60: 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63  *)sqlite3_malloc
4c70: 28 73 7a 29 3b 0a 20 20 69 66 28 20 70 43 61 63  (sz);.  if( pCac
4c80: 68 65 20 29 7b 0a 20 20 20 20 6d 65 6d 73 65 74  he ){.    memset
4c90: 28 70 43 61 63 68 65 2c 20 30 2c 20 73 7a 29 3b  (pCache, 0, sz);
4ca0: 0a 20 20 20 20 69 66 28 20 73 65 70 61 72 61 74  .    if( separat
4cb0: 65 43 61 63 68 65 20 29 7b 0a 20 20 20 20 20 20  eCache ){.      
4cc0: 70 47 72 6f 75 70 20 3d 20 28 50 47 72 6f 75 70  pGroup = (PGroup
4cd0: 2a 29 26 70 43 61 63 68 65 5b 31 5d 3b 0a 20 20  *)&pCache[1];.  
4ce0: 20 20 20 20 70 47 72 6f 75 70 2d 3e 6d 78 50 69      pGroup->mxPi
4cf0: 6e 6e 65 64 20 3d 20 31 30 3b 0a 20 20 20 20 7d  nned = 10;.    }
4d00: 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 47 72 6f  else{.      pGro
4d10: 75 70 20 3d 20 26 70 63 61 63 68 65 31 2e 67 72  up = &pcache1.gr
4d20: 70 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 43 61  p;.    }.    pCa
4d30: 63 68 65 2d 3e 70 47 72 6f 75 70 20 3d 20 70 47  che->pGroup = pG
4d40: 72 6f 75 70 3b 0a 20 20 20 20 70 43 61 63 68 65  roup;.    pCache
4d50: 2d 3e 73 7a 50 61 67 65 20 3d 20 73 7a 50 61 67  ->szPage = szPag
4d60: 65 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 73  e;.    pCache->s
4d70: 7a 45 78 74 72 61 20 3d 20 73 7a 45 78 74 72 61  zExtra = szExtra
4d80: 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 62 50  ;.    pCache->bP
4d90: 75 72 67 65 61 62 6c 65 20 3d 20 28 62 50 75 72  urgeable = (bPur
4da0: 67 65 61 62 6c 65 20 3f 20 31 20 3a 20 30 29 3b  geable ? 1 : 0);
4db0: 0a 20 20 20 20 69 66 28 20 62 50 75 72 67 65 61  .    if( bPurgea
4dc0: 62 6c 65 20 29 7b 0a 20 20 20 20 20 20 70 43 61  ble ){.      pCa
4dd0: 63 68 65 2d 3e 6e 4d 69 6e 20 3d 20 31 30 3b 0a  che->nMin = 10;.
4de0: 20 20 20 20 20 20 70 63 61 63 68 65 31 45 6e 74        pcache1Ent
4df0: 65 72 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b  erMutex(pGroup);
4e00: 0a 20 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 6e  .      pGroup->n
4e10: 4d 69 6e 50 61 67 65 20 2b 3d 20 70 43 61 63 68  MinPage += pCach
4e20: 65 2d 3e 6e 4d 69 6e 3b 0a 20 20 20 20 20 20 70  e->nMin;.      p
4e30: 47 72 6f 75 70 2d 3e 6d 78 50 69 6e 6e 65 64 20  Group->mxPinned 
4e40: 3d 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61  = pGroup->nMaxPa
4e50: 67 65 20 2b 20 31 30 20 2d 20 70 47 72 6f 75 70  ge + 10 - pGroup
4e60: 2d 3e 6e 4d 69 6e 50 61 67 65 3b 0a 20 20 20 20  ->nMinPage;.    
4e70: 20 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75    pcache1LeaveMu
4e80: 74 65 78 28 70 47 72 6f 75 70 29 3b 0a 20 20 20  tex(pGroup);.   
4e90: 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20   }.  }.  return 
4ea0: 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20  (sqlite3_pcache 
4eb0: 2a 29 70 43 61 63 68 65 3b 0a 7d 0a 0a 2f 2a 0a  *)pCache;.}../*.
4ec0: 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  ** Implementatio
4ed0: 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33  n of the sqlite3
4ee0: 5f 70 63 61 63 68 65 2e 78 43 61 63 68 65 73 69  _pcache.xCachesi
4ef0: 7a 65 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a  ze method. .**.*
4f00: 2a 20 43 6f 6e 66 69 67 75 72 65 20 74 68 65 20  * Configure the 
4f10: 63 61 63 68 65 5f 73 69 7a 65 20 6c 69 6d 69 74  cache_size limit
4f20: 20 66 6f 72 20 61 20 63 61 63 68 65 2e 0a 2a 2f   for a cache..*/
4f30: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61  .static void pca
4f40: 63 68 65 31 43 61 63 68 65 73 69 7a 65 28 73 71  che1Cachesize(sq
4f50: 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70 2c  lite3_pcache *p,
4f60: 20 69 6e 74 20 6e 4d 61 78 29 7b 0a 20 20 50 43   int nMax){.  PC
4f70: 61 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20  ache1 *pCache = 
4f80: 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20 20  (PCache1 *)p;.  
4f90: 69 66 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72  if( pCache->bPur
4fa0: 67 65 61 62 6c 65 20 29 7b 0a 20 20 20 20 50 47  geable ){.    PG
4fb0: 72 6f 75 70 20 2a 70 47 72 6f 75 70 20 3d 20 70  roup *pGroup = p
4fc0: 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b 0a 20  Cache->pGroup;. 
4fd0: 20 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d     pcache1EnterM
4fe0: 75 74 65 78 28 70 47 72 6f 75 70 29 3b 0a 20 20  utex(pGroup);.  
4ff0: 20 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61    pGroup->nMaxPa
5000: 67 65 20 2b 3d 20 28 6e 4d 61 78 20 2d 20 70 43  ge += (nMax - pC
5010: 61 63 68 65 2d 3e 6e 4d 61 78 29 3b 0a 20 20 20  ache->nMax);.   
5020: 20 70 47 72 6f 75 70 2d 3e 6d 78 50 69 6e 6e 65   pGroup->mxPinne
5030: 64 20 3d 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78  d = pGroup->nMax
5040: 50 61 67 65 20 2b 20 31 30 20 2d 20 70 47 72 6f  Page + 10 - pGro
5050: 75 70 2d 3e 6e 4d 69 6e 50 61 67 65 3b 0a 20 20  up->nMinPage;.  
5060: 20 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 20 3d    pCache->nMax =
5070: 20 6e 4d 61 78 3b 0a 20 20 20 20 70 43 61 63 68   nMax;.    pCach
5080: 65 2d 3e 6e 39 30 70 63 74 20 3d 20 70 43 61 63  e->n90pct = pCac
5090: 68 65 2d 3e 6e 4d 61 78 2a 39 2f 31 30 3b 0a 20  he->nMax*9/10;. 
50a0: 20 20 20 70 63 61 63 68 65 31 45 6e 66 6f 72 63     pcache1Enforc
50b0: 65 4d 61 78 50 61 67 65 28 70 47 72 6f 75 70 29  eMaxPage(pGroup)
50c0: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 4c 65 61  ;.    pcache1Lea
50d0: 76 65 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b  veMutex(pGroup);
50e0: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d  .  }.}../*.** Im
50f0: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20  plementation of 
5100: 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63  the sqlite3_pcac
5110: 68 65 2e 78 50 61 67 65 63 6f 75 6e 74 20 6d 65  he.xPagecount me
5120: 74 68 6f 64 2e 20 0a 2a 2f 0a 73 74 61 74 69 63  thod. .*/.static
5130: 20 69 6e 74 20 70 63 61 63 68 65 31 50 61 67 65   int pcache1Page
5140: 63 6f 75 6e 74 28 73 71 6c 69 74 65 33 5f 70 63  count(sqlite3_pc
5150: 61 63 68 65 20 2a 70 29 7b 0a 20 20 69 6e 74 20  ache *p){.  int 
5160: 6e 3b 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43  n;.  PCache1 *pC
5170: 61 63 68 65 20 3d 20 28 50 43 61 63 68 65 31 2a  ache = (PCache1*
5180: 29 70 3b 0a 20 20 70 63 61 63 68 65 31 45 6e 74  )p;.  pcache1Ent
5190: 65 72 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e  erMutex(pCache->
51a0: 70 47 72 6f 75 70 29 3b 0a 20 20 6e 20 3d 20 70  pGroup);.  n = p
51b0: 43 61 63 68 65 2d 3e 6e 50 61 67 65 3b 0a 20 20  Cache->nPage;.  
51c0: 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65  pcache1LeaveMute
51d0: 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70  x(pCache->pGroup
51e0: 29 3b 0a 20 20 72 65 74 75 72 6e 20 6e 3b 0a 7d  );.  return n;.}
51f0: 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e  ../*.** Implemen
5200: 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71  tation of the sq
5210: 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78 46 65  lite3_pcache.xFe
5220: 74 63 68 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a  tch method. .**.
5230: 2a 2a 20 46 65 74 63 68 20 61 20 70 61 67 65 20  ** Fetch a page 
5240: 62 79 20 6b 65 79 20 76 61 6c 75 65 2e 0a 2a 2a  by key value..**
5250: 0a 2a 2a 20 57 68 65 74 68 65 72 20 6f 72 20 6e  .** Whether or n
5260: 6f 74 20 61 20 6e 65 77 20 70 61 67 65 20 6d 61  ot a new page ma
5270: 79 20 62 65 20 61 6c 6c 6f 63 61 74 65 64 20 62  y be allocated b
5280: 79 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  y this function 
5290: 64 65 70 65 6e 64 73 20 6f 6e 0a 2a 2a 20 74 68  depends on.** th
52a0: 65 20 76 61 6c 75 65 20 6f 66 20 74 68 65 20 63  e value of the c
52b0: 72 65 61 74 65 46 6c 61 67 20 61 72 67 75 6d 65  reateFlag argume
52c0: 6e 74 2e 20 20 30 20 6d 65 61 6e 73 20 64 6f 20  nt.  0 means do 
52d0: 6e 6f 74 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e  not allocate a n
52e0: 65 77 0a 2a 2a 20 70 61 67 65 2e 20 20 31 20 6d  ew.** page.  1 m
52f0: 65 61 6e 73 20 61 6c 6c 6f 63 61 74 65 20 61 20  eans allocate a 
5300: 6e 65 77 20 70 61 67 65 20 69 66 20 73 70 61 63  new page if spac
5310: 65 20 69 73 20 65 61 73 69 6c 79 20 61 76 61 69  e is easily avai
5320: 6c 61 62 6c 65 2e 20 20 32 20 0a 2a 2a 20 6d 65  lable.  2 .** me
5330: 61 6e 73 20 74 6f 20 74 72 79 20 72 65 61 6c 6c  ans to try reall
5340: 79 20 68 61 72 64 20 74 6f 20 61 6c 6c 6f 63 61  y hard to alloca
5350: 74 65 20 61 20 6e 65 77 20 70 61 67 65 2e 0a 2a  te a new page..*
5360: 2a 0a 2a 2a 20 46 6f 72 20 61 20 6e 6f 6e 2d 70  *.** For a non-p
5370: 75 72 67 65 61 62 6c 65 20 63 61 63 68 65 20 28  urgeable cache (
5380: 61 20 63 61 63 68 65 20 75 73 65 64 20 61 73 20  a cache used as 
5390: 74 68 65 20 73 74 6f 72 61 67 65 20 66 6f 72 20  the storage for 
53a0: 61 6e 20 69 6e 2d 6d 65 6d 6f 72 79 0a 2a 2a 20  an in-memory.** 
53b0: 64 61 74 61 62 61 73 65 29 20 74 68 65 72 65 20  database) there 
53c0: 69 73 20 72 65 61 6c 6c 79 20 6e 6f 20 64 69 66  is really no dif
53d0: 66 65 72 65 6e 63 65 20 62 65 74 77 65 65 6e 20  ference between 
53e0: 63 72 65 61 74 65 46 6c 61 67 20 31 20 61 6e 64  createFlag 1 and
53f0: 20 32 2e 20 20 53 6f 0a 2a 2a 20 74 68 65 20 63   2.  So.** the c
5400: 61 6c 6c 69 6e 67 20 66 75 6e 63 74 69 6f 6e 20  alling function 
5410: 28 70 63 61 63 68 65 2e 63 29 20 77 69 6c 6c 20  (pcache.c) will 
5420: 6e 65 76 65 72 20 68 61 76 65 20 61 20 63 72 65  never have a cre
5430: 61 74 65 46 6c 61 67 20 6f 66 20 31 20 6f 6e 0a  ateFlag of 1 on.
5440: 2a 2a 20 61 20 6e 6f 6e 2d 70 75 72 67 61 62 6c  ** a non-purgabl
5450: 65 20 63 61 63 68 65 2e 0a 2a 2a 0a 2a 2a 20 54  e cache..**.** T
5460: 68 65 72 65 20 61 72 65 20 74 68 72 65 65 20 64  here are three d
5470: 69 66 66 65 72 65 6e 74 20 61 70 70 72 6f 61 63  ifferent approac
5480: 68 65 73 20 74 6f 20 6f 62 74 61 69 6e 69 6e 67  hes to obtaining
5490: 20 73 70 61 63 65 20 66 6f 72 20 61 20 70 61 67   space for a pag
54a0: 65 2c 0a 2a 2a 20 64 65 70 65 6e 64 69 6e 67 20  e,.** depending 
54b0: 6f 6e 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20  on the value of 
54c0: 70 61 72 61 6d 65 74 65 72 20 63 72 65 61 74 65  parameter create
54d0: 46 6c 61 67 20 28 77 68 69 63 68 20 6d 61 79 20  Flag (which may 
54e0: 62 65 20 30 2c 20 31 20 6f 72 20 32 29 2e 0a 2a  be 0, 1 or 2)..*
54f0: 2a 0a 2a 2a 20 20 20 31 2e 20 52 65 67 61 72 64  *.**   1. Regard
5500: 6c 65 73 73 20 6f 66 20 74 68 65 20 76 61 6c 75  less of the valu
5510: 65 20 6f 66 20 63 72 65 61 74 65 46 6c 61 67 2c  e of createFlag,
5520: 20 74 68 65 20 63 61 63 68 65 20 69 73 20 73 65   the cache is se
5530: 61 72 63 68 65 64 20 66 6f 72 20 61 20 0a 2a 2a  arched for a .**
5540: 20 20 20 20 20 20 63 6f 70 79 20 6f 66 20 74 68        copy of th
5550: 65 20 72 65 71 75 65 73 74 65 64 20 70 61 67 65  e requested page
5560: 2e 20 49 66 20 6f 6e 65 20 69 73 20 66 6f 75 6e  . If one is foun
5570: 64 2c 20 69 74 20 69 73 20 72 65 74 75 72 6e 65  d, it is returne
5580: 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 32 2e 20 49 66  d..**.**   2. If
5590: 20 63 72 65 61 74 65 46 6c 61 67 3d 3d 30 20 61   createFlag==0 a
55a0: 6e 64 20 74 68 65 20 70 61 67 65 20 69 73 20 6e  nd the page is n
55b0: 6f 74 20 61 6c 72 65 61 64 79 20 69 6e 20 74 68  ot already in th
55c0: 65 20 63 61 63 68 65 2c 20 4e 55 4c 4c 20 69 73  e cache, NULL is
55d0: 0a 2a 2a 20 20 20 20 20 20 72 65 74 75 72 6e 65  .**      returne
55e0: 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 33 2e 20 49 66  d..**.**   3. If
55f0: 20 63 72 65 61 74 65 46 6c 61 67 20 69 73 20 31   createFlag is 1
5600: 2c 20 61 6e 64 20 74 68 65 20 70 61 67 65 20 69  , and the page i
5610: 73 20 6e 6f 74 20 61 6c 72 65 61 64 79 20 69 6e  s not already in
5620: 20 74 68 65 20 63 61 63 68 65 2c 20 74 68 65 6e   the cache, then
5630: 0a 2a 2a 20 20 20 20 20 20 72 65 74 75 72 6e 20  .**      return 
5640: 4e 55 4c 4c 20 28 64 6f 20 6e 6f 74 20 61 6c 6c  NULL (do not all
5650: 6f 63 61 74 65 20 61 20 6e 65 77 20 70 61 67 65  ocate a new page
5660: 29 20 69 66 20 61 6e 79 20 6f 66 20 74 68 65 20  ) if any of the 
5670: 66 6f 6c 6c 6f 77 69 6e 67 0a 2a 2a 20 20 20 20  following.**    
5680: 20 20 63 6f 6e 64 69 74 69 6f 6e 73 20 61 72 65    conditions are
5690: 20 74 72 75 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20   true:.**.**    
56a0: 20 20 20 28 61 29 20 74 68 65 20 6e 75 6d 62 65     (a) the numbe
56b0: 72 20 6f 66 20 70 61 67 65 73 20 70 69 6e 6e 65  r of pages pinne
56c0: 64 20 62 79 20 74 68 65 20 63 61 63 68 65 20 69  d by the cache i
56d0: 73 20 67 72 65 61 74 65 72 20 74 68 61 6e 0a 2a  s greater than.*
56e0: 2a 20 20 20 20 20 20 20 20 20 20 20 50 43 61 63  *           PCac
56f0: 68 65 31 2e 6e 4d 61 78 2c 20 6f 72 0a 2a 2a 0a  he1.nMax, or.**.
5700: 2a 2a 20 20 20 20 20 20 20 28 62 29 20 74 68 65  **       (b) the
5710: 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73   number of pages
5720: 20 70 69 6e 6e 65 64 20 62 79 20 74 68 65 20 63   pinned by the c
5730: 61 63 68 65 20 69 73 20 67 72 65 61 74 65 72 20  ache is greater 
5740: 74 68 61 6e 0a 2a 2a 20 20 20 20 20 20 20 20 20  than.**         
5750: 20 20 74 68 65 20 73 75 6d 20 6f 66 20 6e 4d 61    the sum of nMa
5760: 78 20 66 6f 72 20 61 6c 6c 20 70 75 72 67 65 61  x for all purgea
5770: 62 6c 65 20 63 61 63 68 65 73 2c 20 6c 65 73 73  ble caches, less
5780: 20 74 68 65 20 73 75 6d 20 6f 66 20 0a 2a 2a 20   the sum of .** 
5790: 20 20 20 20 20 20 20 20 20 20 6e 4d 69 6e 20 66            nMin f
57a0: 6f 72 20 61 6c 6c 20 6f 74 68 65 72 20 70 75 72  or all other pur
57b0: 67 65 61 62 6c 65 20 63 61 63 68 65 73 2c 20 6f  geable caches, o
57c0: 72 0a 2a 2a 0a 2a 2a 20 20 20 34 2e 20 49 66 20  r.**.**   4. If 
57d0: 6e 6f 6e 65 20 6f 66 20 74 68 65 20 66 69 72 73  none of the firs
57e0: 74 20 74 68 72 65 65 20 63 6f 6e 64 69 74 69 6f  t three conditio
57f0: 6e 73 20 61 70 70 6c 79 20 61 6e 64 20 74 68 65  ns apply and the
5800: 20 63 61 63 68 65 20 69 73 20 6d 61 72 6b 65 64   cache is marked
5810: 0a 2a 2a 20 20 20 20 20 20 61 73 20 70 75 72 67  .**      as purg
5820: 65 61 62 6c 65 2c 20 61 6e 64 20 69 66 20 6f 6e  eable, and if on
5830: 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69  e of the followi
5840: 6e 67 20 69 73 20 74 72 75 65 3a 0a 2a 2a 0a 2a  ng is true:.**.*
5850: 2a 20 20 20 20 20 20 20 28 61 29 20 54 68 65 20  *       (a) The 
5860: 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20  number of pages 
5870: 61 6c 6c 6f 63 61 74 65 64 20 66 6f 72 20 74 68  allocated for th
5880: 65 20 63 61 63 68 65 20 69 73 20 61 6c 72 65 61  e cache is alrea
5890: 64 79 20 0a 2a 2a 20 20 20 20 20 20 20 20 20 20  dy .**          
58a0: 20 50 43 61 63 68 65 31 2e 6e 4d 61 78 2c 20 6f   PCache1.nMax, o
58b0: 72 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 28 62  r.**.**       (b
58c0: 29 20 54 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  ) The number of 
58d0: 70 61 67 65 73 20 61 6c 6c 6f 63 61 74 65 64 20  pages allocated 
58e0: 66 6f 72 20 61 6c 6c 20 70 75 72 67 65 61 62 6c  for all purgeabl
58f0: 65 20 63 61 63 68 65 73 20 69 73 0a 2a 2a 20 20  e caches is.**  
5900: 20 20 20 20 20 20 20 20 20 61 6c 72 65 61 64 79           already
5910: 20 65 71 75 61 6c 20 74 6f 20 6f 72 20 67 72 65   equal to or gre
5920: 61 74 65 72 20 74 68 61 6e 20 74 68 65 20 73 75  ater than the su
5930: 6d 20 6f 66 20 6e 4d 61 78 20 66 6f 72 20 61 6c  m of nMax for al
5940: 6c 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 70  l.**           p
5950: 75 72 67 65 61 62 6c 65 20 63 61 63 68 65 73 2c  urgeable caches,
5960: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 28 63 29  .**.**       (c)
5970: 20 54 68 65 20 73 79 73 74 65 6d 20 69 73 20 75   The system is u
5980: 6e 64 65 72 20 6d 65 6d 6f 72 79 20 70 72 65 73  nder memory pres
5990: 73 75 72 65 20 61 6e 64 20 77 61 6e 74 73 20 74  sure and wants t
59a0: 6f 20 61 76 6f 69 64 0a 2a 2a 20 20 20 20 20 20  o avoid.**      
59b0: 20 20 20 20 20 75 6e 6e 65 63 65 73 73 61 72 79       unnecessary
59c0: 20 70 61 67 65 73 20 63 61 63 68 65 20 65 6e 74   pages cache ent
59d0: 72 79 20 61 6c 6c 6f 63 61 74 69 6f 6e 73 0a 2a  ry allocations.*
59e0: 2a 0a 2a 2a 20 20 20 20 20 20 74 68 65 6e 20 61  *.**      then a
59f0: 74 74 65 6d 70 74 20 74 6f 20 72 65 63 79 63 6c  ttempt to recycl
5a00: 65 20 61 20 70 61 67 65 20 66 72 6f 6d 20 74 68  e a page from th
5a10: 65 20 4c 52 55 20 6c 69 73 74 2e 20 49 66 20 69  e LRU list. If i
5a20: 74 20 69 73 20 74 68 65 20 72 69 67 68 74 0a 2a  t is the right.*
5a30: 2a 20 20 20 20 20 20 73 69 7a 65 2c 20 72 65 74  *      size, ret
5a40: 75 72 6e 20 74 68 65 20 72 65 63 79 63 6c 65 64  urn the recycled
5a50: 20 62 75 66 66 65 72 2e 20 4f 74 68 65 72 77 69   buffer. Otherwi
5a60: 73 65 2c 20 66 72 65 65 20 74 68 65 20 62 75 66  se, free the buf
5a70: 66 65 72 20 61 6e 64 0a 2a 2a 20 20 20 20 20 20  fer and.**      
5a80: 70 72 6f 63 65 65 64 20 74 6f 20 73 74 65 70 20  proceed to step 
5a90: 35 2e 20 0a 2a 2a 0a 2a 2a 20 20 20 35 2e 20 4f  5. .**.**   5. O
5aa0: 74 68 65 72 77 69 73 65 2c 20 61 6c 6c 6f 63 61  therwise, alloca
5ab0: 74 65 20 61 6e 64 20 72 65 74 75 72 6e 20 61 20  te and return a 
5ac0: 6e 65 77 20 70 61 67 65 20 62 75 66 66 65 72 2e  new page buffer.
5ad0: 0a 2a 2f 0a 73 74 61 74 69 63 20 73 71 6c 69 74  .*/.static sqlit
5ae0: 65 33 5f 70 63 61 63 68 65 5f 70 61 67 65 20 2a  e3_pcache_page *
5af0: 70 63 61 63 68 65 31 46 65 74 63 68 28 0a 20 20  pcache1Fetch(.  
5b00: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a  sqlite3_pcache *
5b10: 70 2c 20 0a 20 20 75 6e 73 69 67 6e 65 64 20 69  p, .  unsigned i
5b20: 6e 74 20 69 4b 65 79 2c 20 0a 20 20 69 6e 74 20  nt iKey, .  int 
5b30: 63 72 65 61 74 65 46 6c 61 67 0a 29 7b 0a 20 20  createFlag.){.  
5b40: 69 6e 74 20 6e 50 69 6e 6e 65 64 3b 0a 20 20 50  int nPinned;.  P
5b50: 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d  Cache1 *pCache =
5b60: 20 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20   (PCache1 *)p;. 
5b70: 20 50 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 3b   PGroup *pGroup;
5b80: 0a 20 20 50 67 48 64 72 31 20 2a 70 50 61 67 65  .  PgHdr1 *pPage
5b90: 20 3d 20 30 3b 0a 0a 20 20 61 73 73 65 72 74 28   = 0;..  assert(
5ba0: 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61   pCache->bPurgea
5bb0: 62 6c 65 20 7c 7c 20 63 72 65 61 74 65 46 6c 61  ble || createFla
5bc0: 67 21 3d 31 20 29 3b 0a 20 20 61 73 73 65 72 74  g!=1 );.  assert
5bd0: 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65  ( pCache->bPurge
5be0: 61 62 6c 65 20 7c 7c 20 70 43 61 63 68 65 2d 3e  able || pCache->
5bf0: 6e 4d 69 6e 3d 3d 30 20 29 3b 0a 20 20 61 73 73  nMin==0 );.  ass
5c00: 65 72 74 28 20 70 43 61 63 68 65 2d 3e 62 50 75  ert( pCache->bPu
5c10: 72 67 65 61 62 6c 65 3d 3d 30 20 7c 7c 20 70 43  rgeable==0 || pC
5c20: 61 63 68 65 2d 3e 6e 4d 69 6e 3d 3d 31 30 20 29  ache->nMin==10 )
5c30: 3b 0a 20 20 61 73 73 65 72 74 28 20 70 43 61 63  ;.  assert( pCac
5c40: 68 65 2d 3e 6e 4d 69 6e 3d 3d 30 20 7c 7c 20 70  he->nMin==0 || p
5c50: 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c  Cache->bPurgeabl
5c60: 65 20 29 3b 0a 20 20 70 63 61 63 68 65 31 45 6e  e );.  pcache1En
5c70: 74 65 72 4d 75 74 65 78 28 70 47 72 6f 75 70 20  terMutex(pGroup 
5c80: 3d 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70  = pCache->pGroup
5c90: 29 3b 0a 0a 20 20 2f 2a 20 53 74 65 70 20 31 3a  );..  /* Step 1:
5ca0: 20 53 65 61 72 63 68 20 74 68 65 20 68 61 73 68   Search the hash
5cb0: 20 74 61 62 6c 65 20 66 6f 72 20 61 6e 20 65 78   table for an ex
5cc0: 69 73 74 69 6e 67 20 65 6e 74 72 79 2e 20 2a 2f  isting entry. */
5cd0: 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 6e  .  if( pCache->n
5ce0: 48 61 73 68 3e 30 20 29 7b 0a 20 20 20 20 75 6e  Hash>0 ){.    un
5cf0: 73 69 67 6e 65 64 20 69 6e 74 20 68 20 3d 20 69  signed int h = i
5d00: 4b 65 79 20 25 20 70 43 61 63 68 65 2d 3e 6e 48  Key % pCache->nH
5d10: 61 73 68 3b 0a 20 20 20 20 66 6f 72 28 70 50 61  ash;.    for(pPa
5d20: 67 65 3d 70 43 61 63 68 65 2d 3e 61 70 48 61 73  ge=pCache->apHas
5d30: 68 5b 68 5d 3b 20 70 50 61 67 65 26 26 70 50 61  h[h]; pPage&&pPa
5d40: 67 65 2d 3e 69 4b 65 79 21 3d 69 4b 65 79 3b 20  ge->iKey!=iKey; 
5d50: 70 50 61 67 65 3d 70 50 61 67 65 2d 3e 70 4e 65  pPage=pPage->pNe
5d60: 78 74 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53  xt);.  }..  /* S
5d70: 74 65 70 20 32 3a 20 41 62 6f 72 74 20 69 66 20  tep 2: Abort if 
5d80: 6e 6f 20 65 78 69 73 74 69 6e 67 20 70 61 67 65  no existing page
5d90: 20 69 73 20 66 6f 75 6e 64 20 61 6e 64 20 63 72   is found and cr
5da0: 65 61 74 65 46 6c 61 67 20 69 73 20 30 20 2a 2f  eateFlag is 0 */
5db0: 0a 20 20 69 66 28 20 70 50 61 67 65 20 7c 7c 20  .  if( pPage || 
5dc0: 63 72 65 61 74 65 46 6c 61 67 3d 3d 30 20 29 7b  createFlag==0 ){
5dd0: 0a 20 20 20 20 70 63 61 63 68 65 31 50 69 6e 50  .    pcache1PinP
5de0: 61 67 65 28 70 50 61 67 65 29 3b 0a 20 20 20 20  age(pPage);.    
5df0: 67 6f 74 6f 20 66 65 74 63 68 5f 6f 75 74 3b 0a  goto fetch_out;.
5e00: 20 20 7d 0a 0a 20 20 2f 2a 20 54 68 65 20 70 47    }..  /* The pG
5e10: 72 6f 75 70 20 6c 6f 63 61 6c 20 76 61 72 69 61  roup local varia
5e20: 62 6c 65 20 77 69 6c 6c 20 6e 6f 72 6d 61 6c 6c  ble will normall
5e30: 79 20 62 65 20 69 6e 69 74 69 61 6c 69 7a 65 64  y be initialized
5e40: 20 62 79 20 74 68 65 0a 20 20 2a 2a 20 70 63 61   by the.  ** pca
5e50: 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 29  che1EnterMutex()
5e60: 20 6d 61 63 72 6f 20 61 62 6f 76 65 2e 20 20 42   macro above.  B
5e70: 75 74 20 69 66 20 53 51 4c 49 54 45 5f 4d 55 54  ut if SQLITE_MUT
5e80: 45 58 5f 4f 4d 49 54 20 69 73 20 64 65 66 69 6e  EX_OMIT is defin
5e90: 65 64 2c 0a 20 20 2a 2a 20 74 68 65 6e 20 70 63  ed,.  ** then pc
5ea0: 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28  ache1EnterMutex(
5eb0: 29 20 69 73 20 61 20 6e 6f 2d 6f 70 2c 20 73 6f  ) is a no-op, so
5ec0: 20 77 65 20 68 61 76 65 20 74 6f 20 69 6e 69 74   we have to init
5ed0: 69 61 6c 69 7a 65 20 74 68 65 0a 20 20 2a 2a 20  ialize the.  ** 
5ee0: 6c 6f 63 61 6c 20 76 61 72 69 61 62 6c 65 20 68  local variable h
5ef0: 65 72 65 2e 20 20 44 65 6c 61 79 69 6e 67 20 74  ere.  Delaying t
5f00: 68 65 20 69 6e 69 74 69 61 6c 69 7a 61 74 69 6f  he initializatio
5f10: 6e 20 6f 66 20 70 47 72 6f 75 70 20 69 73 20 61  n of pGroup is a
5f20: 6e 0a 20 20 2a 2a 20 6f 70 74 69 6d 69 7a 61 74  n.  ** optimizat
5f30: 69 6f 6e 3a 20 20 54 68 65 20 63 6f 6d 6d 6f 6e  ion:  The common
5f40: 20 63 61 73 65 20 69 73 20 74 6f 20 65 78 69 74   case is to exit
5f50: 20 74 68 65 20 6d 6f 64 75 6c 65 20 62 65 66 6f   the module befo
5f60: 72 65 20 72 65 61 63 68 69 6e 67 0a 20 20 2a 2a  re reaching.  **
5f70: 20 74 68 69 73 20 70 6f 69 6e 74 2e 0a 20 20 2a   this point..  *
5f80: 2f 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f  /.#ifdef SQLITE_
5f90: 4d 55 54 45 58 5f 4f 4d 49 54 0a 20 20 70 47 72  MUTEX_OMIT.  pGr
5fa0: 6f 75 70 20 3d 20 70 43 61 63 68 65 2d 3e 70 47  oup = pCache->pG
5fb0: 72 6f 75 70 3b 0a 23 65 6e 64 69 66 0a 0a 20 20  roup;.#endif..  
5fc0: 2f 2a 20 53 74 65 70 20 33 3a 20 41 62 6f 72 74  /* Step 3: Abort
5fd0: 20 69 66 20 63 72 65 61 74 65 46 6c 61 67 20 69   if createFlag i
5fe0: 73 20 31 20 62 75 74 20 74 68 65 20 63 61 63 68  s 1 but the cach
5ff0: 65 20 69 73 20 6e 65 61 72 6c 79 20 66 75 6c 6c  e is nearly full
6000: 20 2a 2f 0a 20 20 6e 50 69 6e 6e 65 64 20 3d 20   */.  nPinned = 
6010: 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 20 2d 20  pCache->nPage - 
6020: 70 43 61 63 68 65 2d 3e 6e 52 65 63 79 63 6c 61  pCache->nRecycla
6030: 62 6c 65 3b 0a 20 20 61 73 73 65 72 74 28 20 6e  ble;.  assert( n
6040: 50 69 6e 6e 65 64 3e 3d 30 20 29 3b 0a 20 20 61  Pinned>=0 );.  a
6050: 73 73 65 72 74 28 20 70 47 72 6f 75 70 2d 3e 6d  ssert( pGroup->m
6060: 78 50 69 6e 6e 65 64 20 3d 3d 20 70 47 72 6f 75  xPinned == pGrou
6070: 70 2d 3e 6e 4d 61 78 50 61 67 65 20 2b 20 31 30  p->nMaxPage + 10
6080: 20 2d 20 70 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50   - pGroup->nMinP
6090: 61 67 65 20 29 3b 0a 20 20 61 73 73 65 72 74 28  age );.  assert(
60a0: 20 70 43 61 63 68 65 2d 3e 6e 39 30 70 63 74 20   pCache->n90pct 
60b0: 3d 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 2a  == pCache->nMax*
60c0: 39 2f 31 30 20 29 3b 0a 20 20 69 66 28 20 63 72  9/10 );.  if( cr
60d0: 65 61 74 65 46 6c 61 67 3d 3d 31 20 26 26 20 28  eateFlag==1 && (
60e0: 0a 20 20 20 20 20 20 20 20 6e 50 69 6e 6e 65 64  .        nPinned
60f0: 3e 3d 70 47 72 6f 75 70 2d 3e 6d 78 50 69 6e 6e  >=pGroup->mxPinn
6100: 65 64 0a 20 20 20 20 20 7c 7c 20 6e 50 69 6e 6e  ed.     || nPinn
6110: 65 64 3e 3d 28 69 6e 74 29 70 43 61 63 68 65 2d  ed>=(int)pCache-
6120: 3e 6e 39 30 70 63 74 0a 20 20 20 20 20 7c 7c 20  >n90pct.     || 
6130: 70 63 61 63 68 65 31 55 6e 64 65 72 4d 65 6d 6f  pcache1UnderMemo
6140: 72 79 50 72 65 73 73 75 72 65 28 70 43 61 63 68  ryPressure(pCach
6150: 65 29 0a 20 20 29 29 7b 0a 20 20 20 20 67 6f 74  e).  )){.    got
6160: 6f 20 66 65 74 63 68 5f 6f 75 74 3b 0a 20 20 7d  o fetch_out;.  }
6170: 0a 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e  ..  if( pCache->
6180: 6e 50 61 67 65 3e 3d 70 43 61 63 68 65 2d 3e 6e  nPage>=pCache->n
6190: 48 61 73 68 20 26 26 20 70 63 61 63 68 65 31 52  Hash && pcache1R
61a0: 65 73 69 7a 65 48 61 73 68 28 70 43 61 63 68 65  esizeHash(pCache
61b0: 29 20 29 7b 0a 20 20 20 20 67 6f 74 6f 20 66 65  ) ){.    goto fe
61c0: 74 63 68 5f 6f 75 74 3b 0a 20 20 7d 0a 0a 20 20  tch_out;.  }..  
61d0: 2f 2a 20 53 74 65 70 20 34 2e 20 54 72 79 20 74  /* Step 4. Try t
61e0: 6f 20 72 65 63 79 63 6c 65 20 61 20 70 61 67 65  o recycle a page
61f0: 2e 20 2a 2f 0a 20 20 69 66 28 20 70 43 61 63 68  . */.  if( pCach
6200: 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 26 26  e->bPurgeable &&
6210: 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 54 61 69   pGroup->pLruTai
6220: 6c 20 26 26 20 28 0a 20 20 20 20 20 20 20 20 20  l && (.         
6230: 28 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 2b 31  (pCache->nPage+1
6240: 3e 3d 70 43 61 63 68 65 2d 3e 6e 4d 61 78 29 0a  >=pCache->nMax).
6250: 20 20 20 20 20 20 7c 7c 20 70 47 72 6f 75 70 2d        || pGroup-
6260: 3e 6e 43 75 72 72 65 6e 74 50 61 67 65 3e 3d 70  >nCurrentPage>=p
6270: 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65 0a  Group->nMaxPage.
6280: 20 20 20 20 20 20 7c 7c 20 70 63 61 63 68 65 31        || pcache1
6290: 55 6e 64 65 72 4d 65 6d 6f 72 79 50 72 65 73 73  UnderMemoryPress
62a0: 75 72 65 28 70 43 61 63 68 65 29 0a 20 20 29 29  ure(pCache).  ))
62b0: 7b 0a 20 20 20 20 50 43 61 63 68 65 31 20 2a 70  {.    PCache1 *p
62c0: 4f 74 68 65 72 3b 0a 20 20 20 20 70 50 61 67 65  Other;.    pPage
62d0: 20 3d 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 54   = pGroup->pLruT
62e0: 61 69 6c 3b 0a 20 20 20 20 70 63 61 63 68 65 31  ail;.    pcache1
62f0: 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73 68 28 70  RemoveFromHash(p
6300: 50 61 67 65 29 3b 0a 20 20 20 20 70 63 61 63 68  Page);.    pcach
6310: 65 31 50 69 6e 50 61 67 65 28 70 50 61 67 65 29  e1PinPage(pPage)
6320: 3b 0a 20 20 20 20 70 4f 74 68 65 72 20 3d 20 70  ;.    pOther = p
6330: 50 61 67 65 2d 3e 70 43 61 63 68 65 3b 0a 0a 20  Page->pCache;.. 
6340: 20 20 20 2f 2a 20 57 65 20 77 61 6e 74 20 74 6f     /* We want to
6350: 20 76 65 72 69 66 79 20 74 68 61 74 20 73 7a 50   verify that szP
6360: 61 67 65 20 61 6e 64 20 73 7a 45 78 74 72 61 20  age and szExtra 
6370: 61 72 65 20 74 68 65 20 73 61 6d 65 20 66 6f 72  are the same for
6380: 20 70 4f 74 68 65 72 0a 20 20 20 20 2a 2a 20 61   pOther.    ** a
6390: 6e 64 20 70 43 61 63 68 65 2e 20 20 41 73 73 65  nd pCache.  Asse
63a0: 72 74 20 74 68 61 74 20 77 65 20 63 61 6e 20 76  rt that we can v
63b0: 65 72 69 66 79 20 74 68 69 73 20 62 79 20 63 6f  erify this by co
63c0: 6d 70 61 72 69 6e 67 20 73 75 6d 73 2e 20 2a 2f  mparing sums. */
63d0: 0a 20 20 20 20 61 73 73 65 72 74 28 20 28 70 43  .    assert( (pC
63e0: 61 63 68 65 2d 3e 73 7a 50 61 67 65 20 26 20 28  ache->szPage & (
63f0: 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 2d 31  pCache->szPage-1
6400: 29 29 3d 3d 30 20 26 26 20 70 43 61 63 68 65 2d  ))==0 && pCache-
6410: 3e 73 7a 50 61 67 65 3e 3d 35 31 32 20 29 3b 0a  >szPage>=512 );.
6420: 20 20 20 20 61 73 73 65 72 74 28 20 70 43 61 63      assert( pCac
6430: 68 65 2d 3e 73 7a 45 78 74 72 61 3c 35 31 32 20  he->szExtra<512 
6440: 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 28  );.    assert( (
6450: 70 4f 74 68 65 72 2d 3e 73 7a 50 61 67 65 20 26  pOther->szPage &
6460: 20 28 70 4f 74 68 65 72 2d 3e 73 7a 50 61 67 65   (pOther->szPage
6470: 2d 31 29 29 3d 3d 30 20 26 26 20 70 4f 74 68 65  -1))==0 && pOthe
6480: 72 2d 3e 73 7a 50 61 67 65 3e 3d 35 31 32 20 29  r->szPage>=512 )
6490: 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 4f  ;.    assert( pO
64a0: 74 68 65 72 2d 3e 73 7a 45 78 74 72 61 3c 35 31  ther->szExtra<51
64b0: 32 20 29 3b 0a 0a 20 20 20 20 69 66 28 20 70 4f  2 );..    if( pO
64c0: 74 68 65 72 2d 3e 73 7a 50 61 67 65 2b 70 4f 74  ther->szPage+pOt
64d0: 68 65 72 2d 3e 73 7a 45 78 74 72 61 20 21 3d 20  her->szExtra != 
64e0: 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 2b 70  pCache->szPage+p
64f0: 43 61 63 68 65 2d 3e 73 7a 45 78 74 72 61 20 29  Cache->szExtra )
6500: 7b 0a 20 20 20 20 20 20 70 63 61 63 68 65 31 46  {.      pcache1F
6510: 72 65 65 50 61 67 65 28 70 50 61 67 65 29 3b 0a  reePage(pPage);.
6520: 20 20 20 20 20 20 70 50 61 67 65 20 3d 20 30 3b        pPage = 0;
6530: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
6540: 20 20 70 47 72 6f 75 70 2d 3e 6e 43 75 72 72 65    pGroup->nCurre
6550: 6e 74 50 61 67 65 20 2d 3d 20 28 70 4f 74 68 65  ntPage -= (pOthe
6560: 72 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 2d 20  r->bPurgeable - 
6570: 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62  pCache->bPurgeab
6580: 6c 65 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  le);.    }.  }..
6590: 20 20 2f 2a 20 53 74 65 70 20 35 2e 20 49 66 20    /* Step 5. If 
65a0: 61 20 75 73 61 62 6c 65 20 70 61 67 65 20 62 75  a usable page bu
65b0: 66 66 65 72 20 68 61 73 20 73 74 69 6c 6c 20 6e  ffer has still n
65c0: 6f 74 20 62 65 65 6e 20 66 6f 75 6e 64 2c 20 0a  ot been found, .
65d0: 20 20 2a 2a 20 61 74 74 65 6d 70 74 20 74 6f 20    ** attempt to 
65e0: 61 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 6f  allocate a new o
65f0: 6e 65 2e 20 0a 20 20 2a 2f 0a 20 20 69 66 28 20  ne. .  */.  if( 
6600: 21 70 50 61 67 65 20 29 7b 0a 20 20 20 20 69 66  !pPage ){.    if
6610: 28 20 63 72 65 61 74 65 46 6c 61 67 3d 3d 31 20  ( createFlag==1 
6620: 29 20 73 71 6c 69 74 65 33 42 65 67 69 6e 42 65  ) sqlite3BeginBe
6630: 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 0a 20 20  nignMalloc();.  
6640: 20 20 70 50 61 67 65 20 3d 20 70 63 61 63 68 65    pPage = pcache
6650: 31 41 6c 6c 6f 63 50 61 67 65 28 70 43 61 63 68  1AllocPage(pCach
6660: 65 29 3b 0a 20 20 20 20 69 66 28 20 63 72 65 61  e);.    if( crea
6670: 74 65 46 6c 61 67 3d 3d 31 20 29 20 73 71 6c 69  teFlag==1 ) sqli
6680: 74 65 33 45 6e 64 42 65 6e 69 67 6e 4d 61 6c 6c  te3EndBenignMall
6690: 6f 63 28 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28  oc();.  }..  if(
66a0: 20 70 50 61 67 65 20 29 7b 0a 20 20 20 20 75 6e   pPage ){.    un
66b0: 73 69 67 6e 65 64 20 69 6e 74 20 68 20 3d 20 69  signed int h = i
66c0: 4b 65 79 20 25 20 70 43 61 63 68 65 2d 3e 6e 48  Key % pCache->nH
66d0: 61 73 68 3b 0a 20 20 20 20 70 43 61 63 68 65 2d  ash;.    pCache-
66e0: 3e 6e 50 61 67 65 2b 2b 3b 0a 20 20 20 20 70 50  >nPage++;.    pP
66f0: 61 67 65 2d 3e 69 4b 65 79 20 3d 20 69 4b 65 79  age->iKey = iKey
6700: 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 4e 65  ;.    pPage->pNe
6710: 78 74 20 3d 20 70 43 61 63 68 65 2d 3e 61 70 48  xt = pCache->apH
6720: 61 73 68 5b 68 5d 3b 0a 20 20 20 20 70 50 61 67  ash[h];.    pPag
6730: 65 2d 3e 70 43 61 63 68 65 20 3d 20 70 43 61 63  e->pCache = pCac
6740: 68 65 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 70  he;.    pPage->p
6750: 4c 72 75 50 72 65 76 20 3d 20 30 3b 0a 20 20 20  LruPrev = 0;.   
6760: 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74   pPage->pLruNext
6770: 20 3d 20 30 3b 0a 20 20 20 20 2a 28 76 6f 69 64   = 0;.    *(void
6780: 20 2a 2a 29 70 50 61 67 65 2d 3e 70 61 67 65 2e   **)pPage->page.
6790: 70 45 78 74 72 61 20 3d 20 30 3b 0a 20 20 20 20  pExtra = 0;.    
67a0: 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68  pCache->apHash[h
67b0: 5d 20 3d 20 70 50 61 67 65 3b 0a 20 20 7d 0a 0a  ] = pPage;.  }..
67c0: 66 65 74 63 68 5f 6f 75 74 3a 0a 20 20 69 66 28  fetch_out:.  if(
67d0: 20 70 50 61 67 65 20 26 26 20 69 4b 65 79 3e 70   pPage && iKey>p
67e0: 43 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 29  Cache->iMaxKey )
67f0: 7b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 69 4d  {.    pCache->iM
6800: 61 78 4b 65 79 20 3d 20 69 4b 65 79 3b 0a 20 20  axKey = iKey;.  
6810: 7d 0a 20 20 70 63 61 63 68 65 31 4c 65 61 76 65  }.  pcache1Leave
6820: 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b 0a 20  Mutex(pGroup);. 
6830: 20 72 65 74 75 72 6e 20 26 70 50 61 67 65 2d 3e   return &pPage->
6840: 70 61 67 65 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20  page;.}.../*.** 
6850: 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  Implementation o
6860: 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63  f the sqlite3_pc
6870: 61 63 68 65 2e 78 55 6e 70 69 6e 20 6d 65 74 68  ache.xUnpin meth
6880: 6f 64 2e 0a 2a 2a 0a 2a 2a 20 4d 61 72 6b 20 61  od..**.** Mark a
6890: 20 70 61 67 65 20 61 73 20 75 6e 70 69 6e 6e 65   page as unpinne
68a0: 64 20 28 65 6c 69 67 69 62 6c 65 20 66 6f 72 20  d (eligible for 
68b0: 61 73 79 6e 63 68 72 6f 6e 6f 75 73 20 72 65 63  asynchronous rec
68c0: 79 63 6c 69 6e 67 29 2e 0a 2a 2f 0a 73 74 61 74  ycling)..*/.stat
68d0: 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 31 55  ic void pcache1U
68e0: 6e 70 69 6e 28 0a 20 20 73 71 6c 69 74 65 33 5f  npin(.  sqlite3_
68f0: 70 63 61 63 68 65 20 2a 70 2c 20 0a 20 20 73 71  pcache *p, .  sq
6900: 6c 69 74 65 33 5f 70 63 61 63 68 65 5f 70 61 67  lite3_pcache_pag
6910: 65 20 2a 70 50 67 2c 20 0a 20 20 69 6e 74 20 72  e *pPg, .  int r
6920: 65 75 73 65 55 6e 6c 69 6b 65 6c 79 0a 29 7b 0a  euseUnlikely.){.
6930: 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68    PCache1 *pCach
6940: 65 20 3d 20 28 50 43 61 63 68 65 31 20 2a 29 70  e = (PCache1 *)p
6950: 3b 0a 20 20 50 67 48 64 72 31 20 2a 70 50 61 67  ;.  PgHdr1 *pPag
6960: 65 20 3d 20 28 50 67 48 64 72 31 20 2a 29 70 50  e = (PgHdr1 *)pP
6970: 67 3b 0a 20 20 50 47 72 6f 75 70 20 2a 70 47 72  g;.  PGroup *pGr
6980: 6f 75 70 20 3d 20 70 43 61 63 68 65 2d 3e 70 47  oup = pCache->pG
6990: 72 6f 75 70 3b 0a 20 0a 20 20 61 73 73 65 72 74  roup;. .  assert
69a0: 28 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65 3d  ( pPage->pCache=
69b0: 3d 70 43 61 63 68 65 20 29 3b 0a 20 20 70 63 61  =pCache );.  pca
69c0: 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70  che1EnterMutex(p
69d0: 47 72 6f 75 70 29 3b 0a 0a 20 20 2f 2a 20 49 74  Group);..  /* It
69e0: 20 69 73 20 61 6e 20 65 72 72 6f 72 20 74 6f 20   is an error to 
69f0: 63 61 6c 6c 20 74 68 69 73 20 66 75 6e 63 74 69  call this functi
6a00: 6f 6e 20 69 66 20 74 68 65 20 70 61 67 65 20 69  on if the page i
6a10: 73 20 61 6c 72 65 61 64 79 20 0a 20 20 2a 2a 20  s already .  ** 
6a20: 70 61 72 74 20 6f 66 20 74 68 65 20 50 47 72 6f  part of the PGro
6a30: 75 70 20 4c 52 55 20 6c 69 73 74 2e 0a 20 20 2a  up LRU list..  *
6a40: 2f 0a 20 20 61 73 73 65 72 74 28 20 70 50 61 67  /.  assert( pPag
6a50: 65 2d 3e 70 4c 72 75 50 72 65 76 3d 3d 30 20 26  e->pLruPrev==0 &
6a60: 26 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78  & pPage->pLruNex
6a70: 74 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74  t==0 );.  assert
6a80: 28 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 48 65  ( pGroup->pLruHe
6a90: 61 64 21 3d 70 50 61 67 65 20 26 26 20 70 47 72  ad!=pPage && pGr
6aa0: 6f 75 70 2d 3e 70 4c 72 75 54 61 69 6c 21 3d 70  oup->pLruTail!=p
6ab0: 50 61 67 65 20 29 3b 0a 0a 20 20 69 66 28 20 72  Page );..  if( r
6ac0: 65 75 73 65 55 6e 6c 69 6b 65 6c 79 20 7c 7c 20  euseUnlikely || 
6ad0: 70 47 72 6f 75 70 2d 3e 6e 43 75 72 72 65 6e 74  pGroup->nCurrent
6ae0: 50 61 67 65 3e 70 47 72 6f 75 70 2d 3e 6e 4d 61  Page>pGroup->nMa
6af0: 78 50 61 67 65 20 29 7b 0a 20 20 20 20 70 63 61  xPage ){.    pca
6b00: 63 68 65 31 52 65 6d 6f 76 65 46 72 6f 6d 48 61  che1RemoveFromHa
6b10: 73 68 28 70 50 61 67 65 29 3b 0a 20 20 20 20 70  sh(pPage);.    p
6b20: 63 61 63 68 65 31 46 72 65 65 50 61 67 65 28 70  cache1FreePage(p
6b30: 50 61 67 65 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a  Page);.  }else{.
6b40: 20 20 20 20 2f 2a 20 41 64 64 20 74 68 65 20 70      /* Add the p
6b50: 61 67 65 20 74 6f 20 74 68 65 20 50 47 72 6f 75  age to the PGrou
6b60: 70 20 4c 52 55 20 6c 69 73 74 2e 20 2a 2f 0a 20  p LRU list. */. 
6b70: 20 20 20 69 66 28 20 70 47 72 6f 75 70 2d 3e 70     if( pGroup->p
6b80: 4c 72 75 48 65 61 64 20 29 7b 0a 20 20 20 20 20  LruHead ){.     
6b90: 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 48 65 61   pGroup->pLruHea
6ba0: 64 2d 3e 70 4c 72 75 50 72 65 76 20 3d 20 70 50  d->pLruPrev = pP
6bb0: 61 67 65 3b 0a 20 20 20 20 20 20 70 50 61 67 65  age;.      pPage
6bc0: 2d 3e 70 4c 72 75 4e 65 78 74 20 3d 20 70 47 72  ->pLruNext = pGr
6bd0: 6f 75 70 2d 3e 70 4c 72 75 48 65 61 64 3b 0a 20  oup->pLruHead;. 
6be0: 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 70 4c 72       pGroup->pLr
6bf0: 75 48 65 61 64 20 3d 20 70 50 61 67 65 3b 0a 20  uHead = pPage;. 
6c00: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
6c10: 70 47 72 6f 75 70 2d 3e 70 4c 72 75 54 61 69 6c  pGroup->pLruTail
6c20: 20 3d 20 70 50 61 67 65 3b 0a 20 20 20 20 20 20   = pPage;.      
6c30: 70 47 72 6f 75 70 2d 3e 70 4c 72 75 48 65 61 64  pGroup->pLruHead
6c40: 20 3d 20 70 50 61 67 65 3b 0a 20 20 20 20 7d 0a   = pPage;.    }.
6c50: 20 20 20 20 70 43 61 63 68 65 2d 3e 6e 52 65 63      pCache->nRec
6c60: 79 63 6c 61 62 6c 65 2b 2b 3b 0a 20 20 7d 0a 0a  yclable++;.  }..
6c70: 20 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75    pcache1LeaveMu
6c80: 74 65 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f  tex(pCache->pGro
6c90: 75 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d  up);.}../*.** Im
6ca0: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20  plementation of 
6cb0: 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63  the sqlite3_pcac
6cc0: 68 65 2e 78 52 65 6b 65 79 20 6d 65 74 68 6f 64  he.xRekey method
6cd0: 2e 20 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  . .*/.static voi
6ce0: 64 20 70 63 61 63 68 65 31 52 65 6b 65 79 28 0a  d pcache1Rekey(.
6cf0: 20 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65    sqlite3_pcache
6d00: 20 2a 70 2c 0a 20 20 73 71 6c 69 74 65 33 5f 70   *p,.  sqlite3_p
6d10: 63 61 63 68 65 5f 70 61 67 65 20 2a 70 50 67 2c  cache_page *pPg,
6d20: 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  .  unsigned int 
6d30: 69 4f 6c 64 2c 0a 20 20 75 6e 73 69 67 6e 65 64  iOld,.  unsigned
6d40: 20 69 6e 74 20 69 4e 65 77 0a 29 7b 0a 20 20 50   int iNew.){.  P
6d50: 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d  Cache1 *pCache =
6d60: 20 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20   (PCache1 *)p;. 
6d70: 20 50 67 48 64 72 31 20 2a 70 50 61 67 65 20 3d   PgHdr1 *pPage =
6d80: 20 28 50 67 48 64 72 31 20 2a 29 70 50 67 3b 0a   (PgHdr1 *)pPg;.
6d90: 20 20 50 67 48 64 72 31 20 2a 2a 70 70 3b 0a 20    PgHdr1 **pp;. 
6da0: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 3b   unsigned int h;
6db0: 20 0a 20 20 61 73 73 65 72 74 28 20 70 50 61 67   .  assert( pPag
6dc0: 65 2d 3e 69 4b 65 79 3d 3d 69 4f 6c 64 20 29 3b  e->iKey==iOld );
6dd0: 0a 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65  .  assert( pPage
6de0: 2d 3e 70 43 61 63 68 65 3d 3d 70 43 61 63 68 65  ->pCache==pCache
6df0: 20 29 3b 0a 0a 20 20 70 63 61 63 68 65 31 45 6e   );..  pcache1En
6e00: 74 65 72 4d 75 74 65 78 28 70 43 61 63 68 65 2d  terMutex(pCache-
6e10: 3e 70 47 72 6f 75 70 29 3b 0a 0a 20 20 68 20 3d  >pGroup);..  h =
6e20: 20 69 4f 6c 64 25 70 43 61 63 68 65 2d 3e 6e 48   iOld%pCache->nH
6e30: 61 73 68 3b 0a 20 20 70 70 20 3d 20 26 70 43 61  ash;.  pp = &pCa
6e40: 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 0a  che->apHash[h];.
6e50: 20 20 77 68 69 6c 65 28 20 28 2a 70 70 29 21 3d    while( (*pp)!=
6e60: 70 50 61 67 65 20 29 7b 0a 20 20 20 20 70 70 20  pPage ){.    pp 
6e70: 3d 20 26 28 2a 70 70 29 2d 3e 70 4e 65 78 74 3b  = &(*pp)->pNext;
6e80: 0a 20 20 7d 0a 20 20 2a 70 70 20 3d 20 70 50 61  .  }.  *pp = pPa
6e90: 67 65 2d 3e 70 4e 65 78 74 3b 0a 0a 20 20 68 20  ge->pNext;..  h 
6ea0: 3d 20 69 4e 65 77 25 70 43 61 63 68 65 2d 3e 6e  = iNew%pCache->n
6eb0: 48 61 73 68 3b 0a 20 20 70 50 61 67 65 2d 3e 69  Hash;.  pPage->i
6ec0: 4b 65 79 20 3d 20 69 4e 65 77 3b 0a 20 20 70 50  Key = iNew;.  pP
6ed0: 61 67 65 2d 3e 70 4e 65 78 74 20 3d 20 70 43 61  age->pNext = pCa
6ee0: 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 0a  che->apHash[h];.
6ef0: 20 20 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68    pCache->apHash
6f00: 5b 68 5d 20 3d 20 70 50 61 67 65 3b 0a 20 20 69  [h] = pPage;.  i
6f10: 66 28 20 69 4e 65 77 3e 70 43 61 63 68 65 2d 3e  f( iNew>pCache->
6f20: 69 4d 61 78 4b 65 79 20 29 7b 0a 20 20 20 20 70  iMaxKey ){.    p
6f30: 43 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 3d  Cache->iMaxKey =
6f40: 20 69 4e 65 77 3b 0a 20 20 7d 0a 0a 20 20 70 63   iNew;.  }..  pc
6f50: 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28  ache1LeaveMutex(
6f60: 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b  pCache->pGroup);
6f70: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d  .}../*.** Implem
6f80: 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20  entation of the 
6f90: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78  sqlite3_pcache.x
6fa0: 54 72 75 6e 63 61 74 65 20 6d 65 74 68 6f 64 2e  Truncate method.
6fb0: 20 0a 2a 2a 0a 2a 2a 20 44 69 73 63 61 72 64 20   .**.** Discard 
6fc0: 61 6c 6c 20 75 6e 70 69 6e 6e 65 64 20 70 61 67  all unpinned pag
6fd0: 65 73 20 69 6e 20 74 68 65 20 63 61 63 68 65 20  es in the cache 
6fe0: 77 69 74 68 20 61 20 70 61 67 65 20 6e 75 6d 62  with a page numb
6ff0: 65 72 20 65 71 75 61 6c 20 74 6f 0a 2a 2a 20 6f  er equal to.** o
7000: 72 20 67 72 65 61 74 65 72 20 74 68 61 6e 20 70  r greater than p
7010: 61 72 61 6d 65 74 65 72 20 69 4c 69 6d 69 74 2e  arameter iLimit.
7020: 20 41 6e 79 20 70 69 6e 6e 65 64 20 70 61 67 65   Any pinned page
7030: 73 20 77 69 74 68 20 61 20 70 61 67 65 20 6e 75  s with a page nu
7040: 6d 62 65 72 0a 2a 2a 20 65 71 75 61 6c 20 74 6f  mber.** equal to
7050: 20 6f 72 20 67 72 65 61 74 65 72 20 74 68 61 6e   or greater than
7060: 20 69 4c 69 6d 69 74 20 61 72 65 20 69 6d 70 6c   iLimit are impl
7070: 69 63 69 74 6c 79 20 75 6e 70 69 6e 6e 65 64 2e  icitly unpinned.
7080: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
7090: 70 63 61 63 68 65 31 54 72 75 6e 63 61 74 65 28  pcache1Truncate(
70a0: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a  sqlite3_pcache *
70b0: 70 2c 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  p, unsigned int 
70c0: 69 4c 69 6d 69 74 29 7b 0a 20 20 50 43 61 63 68  iLimit){.  PCach
70d0: 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43  e1 *pCache = (PC
70e0: 61 63 68 65 31 20 2a 29 70 3b 0a 20 20 70 63 61  ache1 *)p;.  pca
70f0: 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70  che1EnterMutex(p
7100: 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a  Cache->pGroup);.
7110: 20 20 69 66 28 20 69 4c 69 6d 69 74 3c 3d 70 43    if( iLimit<=pC
7120: 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 29 7b  ache->iMaxKey ){
7130: 0a 20 20 20 20 70 63 61 63 68 65 31 54 72 75 6e  .    pcache1Trun
7140: 63 61 74 65 55 6e 73 61 66 65 28 70 43 61 63 68  cateUnsafe(pCach
7150: 65 2c 20 69 4c 69 6d 69 74 29 3b 0a 20 20 20 20  e, iLimit);.    
7160: 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20  pCache->iMaxKey 
7170: 3d 20 69 4c 69 6d 69 74 2d 31 3b 0a 20 20 7d 0a  = iLimit-1;.  }.
7180: 20 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75    pcache1LeaveMu
7190: 74 65 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f  tex(pCache->pGro
71a0: 75 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d  up);.}../*.** Im
71b0: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20  plementation of 
71c0: 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63  the sqlite3_pcac
71d0: 68 65 2e 78 44 65 73 74 72 6f 79 20 6d 65 74 68  he.xDestroy meth
71e0: 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20 44 65 73 74 72  od. .**.** Destr
71f0: 6f 79 20 61 20 63 61 63 68 65 20 61 6c 6c 6f 63  oy a cache alloc
7200: 61 74 65 64 20 75 73 69 6e 67 20 70 63 61 63 68  ated using pcach
7210: 65 31 43 72 65 61 74 65 28 29 2e 0a 2a 2f 0a 73  e1Create()..*/.s
7220: 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68  tatic void pcach
7230: 65 31 44 65 73 74 72 6f 79 28 73 71 6c 69 74 65  e1Destroy(sqlite
7240: 33 5f 70 63 61 63 68 65 20 2a 70 29 7b 0a 20 20  3_pcache *p){.  
7250: 50 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 20  PCache1 *pCache 
7260: 3d 20 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a  = (PCache1 *)p;.
7270: 20 20 50 47 72 6f 75 70 20 2a 70 47 72 6f 75 70    PGroup *pGroup
7280: 20 3d 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75   = pCache->pGrou
7290: 70 3b 0a 20 20 61 73 73 65 72 74 28 20 70 43 61  p;.  assert( pCa
72a0: 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20  che->bPurgeable 
72b0: 7c 7c 20 28 70 43 61 63 68 65 2d 3e 6e 4d 61 78  || (pCache->nMax
72c0: 3d 3d 30 20 26 26 20 70 43 61 63 68 65 2d 3e 6e  ==0 && pCache->n
72d0: 4d 69 6e 3d 3d 30 29 20 29 3b 0a 20 20 70 63 61  Min==0) );.  pca
72e0: 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70  che1EnterMutex(p
72f0: 47 72 6f 75 70 29 3b 0a 20 20 70 63 61 63 68 65  Group);.  pcache
7300: 31 54 72 75 6e 63 61 74 65 55 6e 73 61 66 65 28  1TruncateUnsafe(
7310: 70 43 61 63 68 65 2c 20 30 29 3b 0a 20 20 70 47  pCache, 0);.  pG
7320: 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65 20 2d  roup->nMaxPage -
7330: 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 3b 0a  = pCache->nMax;.
7340: 20 20 70 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61    pGroup->nMinPa
7350: 67 65 20 2d 3d 20 70 43 61 63 68 65 2d 3e 6e 4d  ge -= pCache->nM
7360: 69 6e 3b 0a 20 20 70 47 72 6f 75 70 2d 3e 6d 78  in;.  pGroup->mx
7370: 50 69 6e 6e 65 64 20 3d 20 70 47 72 6f 75 70 2d  Pinned = pGroup-
7380: 3e 6e 4d 61 78 50 61 67 65 20 2b 20 31 30 20 2d  >nMaxPage + 10 -
7390: 20 70 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67   pGroup->nMinPag
73a0: 65 3b 0a 20 20 70 63 61 63 68 65 31 45 6e 66 6f  e;.  pcache1Enfo
73b0: 72 63 65 4d 61 78 50 61 67 65 28 70 47 72 6f 75  rceMaxPage(pGrou
73c0: 70 29 3b 0a 20 20 70 63 61 63 68 65 31 4c 65 61  p);.  pcache1Lea
73d0: 76 65 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b  veMutex(pGroup);
73e0: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
73f0: 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 29 3b  pCache->apHash);
7400: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
7410: 70 43 61 63 68 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  pCache);.}../*.*
7420: 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  * This function 
7430: 69 73 20 63 61 6c 6c 65 64 20 64 75 72 69 6e 67  is called during
7440: 20 69 6e 69 74 69 61 6c 69 7a 61 74 69 6f 6e 20   initialization 
7450: 28 73 71 6c 69 74 65 33 5f 69 6e 69 74 69 61 6c  (sqlite3_initial
7460: 69 7a 65 28 29 29 20 74 6f 0a 2a 2a 20 69 6e 73  ize()) to.** ins
7470: 74 61 6c 6c 20 74 68 65 20 64 65 66 61 75 6c 74  tall the default
7480: 20 70 6c 75 67 67 61 62 6c 65 20 63 61 63 68 65   pluggable cache
7490: 20 6d 6f 64 75 6c 65 2c 20 61 73 73 75 6d 69 6e   module, assumin
74a0: 67 20 74 68 65 20 75 73 65 72 20 68 61 73 20 6e  g the user has n
74b0: 6f 74 0a 2a 2a 20 61 6c 72 65 61 64 79 20 70 72  ot.** already pr
74c0: 6f 76 69 64 65 64 20 61 6e 20 61 6c 74 65 72 6e  ovided an altern
74d0: 61 74 69 76 65 2e 0a 2a 2f 0a 76 6f 69 64 20 73  ative..*/.void s
74e0: 71 6c 69 74 65 33 50 43 61 63 68 65 53 65 74 44  qlite3PCacheSetD
74f0: 65 66 61 75 6c 74 28 76 6f 69 64 29 7b 0a 20 20  efault(void){.  
7500: 73 74 61 74 69 63 20 63 6f 6e 73 74 20 73 71 6c  static const sql
7510: 69 74 65 33 5f 70 63 61 63 68 65 5f 6d 65 74 68  ite3_pcache_meth
7520: 6f 64 73 32 20 64 65 66 61 75 6c 74 4d 65 74 68  ods2 defaultMeth
7530: 6f 64 73 20 3d 20 7b 0a 20 20 20 20 30 2c 20 20  ods = {.    0,  
7540: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7550: 20 20 20 20 20 2f 2a 20 70 41 72 67 20 2a 2f 0a       /* pArg */.
7560: 20 20 20 20 70 63 61 63 68 65 31 49 6e 69 74 2c      pcache1Init,
7570: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
7580: 78 49 6e 69 74 20 2a 2f 0a 20 20 20 20 70 63 61  xInit */.    pca
7590: 63 68 65 31 53 68 75 74 64 6f 77 6e 2c 20 20 20  che1Shutdown,   
75a0: 20 20 20 20 20 20 2f 2a 20 78 53 68 75 74 64 6f        /* xShutdo
75b0: 77 6e 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65  wn */.    pcache
75c0: 31 43 72 65 61 74 65 2c 20 20 20 20 20 20 20 20  1Create,        
75d0: 20 20 20 2f 2a 20 78 43 72 65 61 74 65 20 2a 2f     /* xCreate */
75e0: 0a 20 20 20 20 70 63 61 63 68 65 31 43 61 63 68  .    pcache1Cach
75f0: 65 73 69 7a 65 2c 20 20 20 20 20 20 20 20 2f 2a  esize,        /*
7600: 20 78 43 61 63 68 65 73 69 7a 65 20 2a 2f 0a 20   xCachesize */. 
7610: 20 20 20 70 63 61 63 68 65 31 50 61 67 65 63 6f     pcache1Pageco
7620: 75 6e 74 2c 20 20 20 20 20 20 20 20 2f 2a 20 78  unt,        /* x
7630: 50 61 67 65 63 6f 75 6e 74 20 2a 2f 0a 20 20 20  Pagecount */.   
7640: 20 70 63 61 63 68 65 31 46 65 74 63 68 2c 20 20   pcache1Fetch,  
7650: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 46 65            /* xFe
7660: 74 63 68 20 2a 2f 0a 20 20 20 20 70 63 61 63 68  tch */.    pcach
7670: 65 31 55 6e 70 69 6e 2c 20 20 20 20 20 20 20 20  e1Unpin,        
7680: 20 20 20 20 2f 2a 20 78 55 6e 70 69 6e 20 2a 2f      /* xUnpin */
7690: 0a 20 20 20 20 70 63 61 63 68 65 31 52 65 6b 65  .    pcache1Reke
76a0: 79 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  y,            /*
76b0: 20 78 52 65 6b 65 79 20 2a 2f 0a 20 20 20 20 70   xRekey */.    p
76c0: 63 61 63 68 65 31 54 72 75 6e 63 61 74 65 2c 20  cache1Truncate, 
76d0: 20 20 20 20 20 20 20 20 2f 2a 20 78 54 72 75 6e          /* xTrun
76e0: 63 61 74 65 20 2a 2f 0a 20 20 20 20 70 63 61 63  cate */.    pcac
76f0: 68 65 31 44 65 73 74 72 6f 79 20 20 20 20 20 20  he1Destroy      
7700: 20 20 20 20 20 2f 2a 20 78 44 65 73 74 72 6f 79       /* xDestroy
7710: 20 2a 2f 0a 20 20 7d 3b 0a 20 20 73 71 6c 69 74   */.  };.  sqlit
7720: 65 33 5f 63 6f 6e 66 69 67 28 53 51 4c 49 54 45  e3_config(SQLITE
7730: 5f 43 4f 4e 46 49 47 5f 50 43 41 43 48 45 32 2c  _CONFIG_PCACHE2,
7740: 20 26 64 65 66 61 75 6c 74 4d 65 74 68 6f 64 73   &defaultMethods
7750: 29 3b 0a 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c  );.}..#ifdef SQL
7760: 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52  ITE_ENABLE_MEMOR
7770: 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 0a 2f 2a 0a  Y_MANAGEMENT./*.
7780: 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
7790: 20 69 73 20 63 61 6c 6c 65 64 20 74 6f 20 66 72   is called to fr
77a0: 65 65 20 73 75 70 65 72 66 6c 75 6f 75 73 20 64  ee superfluous d
77b0: 79 6e 61 6d 69 63 61 6c 6c 79 20 61 6c 6c 6f 63  ynamically alloc
77c0: 61 74 65 64 20 6d 65 6d 6f 72 79 0a 2a 2a 20 68  ated memory.** h
77d0: 65 6c 64 20 62 79 20 74 68 65 20 70 61 67 65 72  eld by the pager
77e0: 20 73 79 73 74 65 6d 2e 20 4d 65 6d 6f 72 79 20   system. Memory 
77f0: 69 6e 20 75 73 65 20 62 79 20 61 6e 79 20 53 51  in use by any SQ
7800: 4c 69 74 65 20 70 61 67 65 72 20 61 6c 6c 6f 63  Lite pager alloc
7810: 61 74 65 64 0a 2a 2a 20 62 79 20 74 68 65 20 63  ated.** by the c
7820: 75 72 72 65 6e 74 20 74 68 72 65 61 64 20 6d 61  urrent thread ma
7830: 79 20 62 65 20 73 71 6c 69 74 65 33 5f 66 72 65  y be sqlite3_fre
7840: 65 28 29 65 64 2e 0a 2a 2a 0a 2a 2a 20 6e 52 65  e()ed..**.** nRe
7850: 71 20 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20  q is the number 
7860: 6f 66 20 62 79 74 65 73 20 6f 66 20 6d 65 6d 6f  of bytes of memo
7870: 72 79 20 72 65 71 75 69 72 65 64 2e 20 4f 6e 63  ry required. Onc
7880: 65 20 74 68 69 73 20 6d 75 63 68 20 68 61 73 0a  e this much has.
7890: 2a 2a 20 62 65 65 6e 20 72 65 6c 65 61 73 65 64  ** been released
78a0: 2c 20 74 68 65 20 66 75 6e 63 74 69 6f 6e 20 72  , the function r
78b0: 65 74 75 72 6e 73 2e 20 54 68 65 20 72 65 74 75  eturns. The retu
78c0: 72 6e 20 76 61 6c 75 65 20 69 73 20 74 68 65 20  rn value is the 
78d0: 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 0a 2a 2a  total number .**
78e0: 20 6f 66 20 62 79 74 65 73 20 6f 66 20 6d 65 6d   of bytes of mem
78f0: 6f 72 79 20 72 65 6c 65 61 73 65 64 2e 0a 2a 2f  ory released..*/
7900: 0a 69 6e 74 20 73 71 6c 69 74 65 33 50 63 61 63  .int sqlite3Pcac
7910: 68 65 52 65 6c 65 61 73 65 4d 65 6d 6f 72 79 28  heReleaseMemory(
7920: 69 6e 74 20 6e 52 65 71 29 7b 0a 20 20 69 6e 74  int nReq){.  int
7930: 20 6e 46 72 65 65 20 3d 20 30 3b 0a 20 20 61 73   nFree = 0;.  as
7940: 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75  sert( sqlite3_mu
7950: 74 65 78 5f 6e 6f 74 68 65 6c 64 28 70 63 61 63  tex_notheld(pcac
7960: 68 65 31 2e 67 72 70 2e 6d 75 74 65 78 29 20 29  he1.grp.mutex) )
7970: 3b 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c 69  ;.  assert( sqli
7980: 74 65 33 5f 6d 75 74 65 78 5f 6e 6f 74 68 65 6c  te3_mutex_nothel
7990: 64 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29  d(pcache1.mutex)
79a0: 20 29 3b 0a 20 20 69 66 28 20 70 63 61 63 68 65   );.  if( pcache
79b0: 31 2e 70 53 74 61 72 74 3d 3d 30 20 29 7b 0a 20  1.pStart==0 ){. 
79c0: 20 20 20 50 67 48 64 72 31 20 2a 70 3b 0a 20 20     PgHdr1 *p;.  
79d0: 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75    pcache1EnterMu
79e0: 74 65 78 28 26 70 63 61 63 68 65 31 2e 67 72 70  tex(&pcache1.grp
79f0: 29 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 28 6e  );.    while( (n
7a00: 52 65 71 3c 30 20 7c 7c 20 6e 46 72 65 65 3c 6e  Req<0 || nFree<n
7a10: 52 65 71 29 20 26 26 20 28 28 70 3d 70 63 61 63  Req) && ((p=pcac
7a20: 68 65 31 2e 67 72 70 2e 70 4c 72 75 54 61 69 6c  he1.grp.pLruTail
7a30: 29 21 3d 30 29 20 29 7b 0a 20 20 20 20 20 20 6e  )!=0) ){.      n
7a40: 46 72 65 65 20 2b 3d 20 70 63 61 63 68 65 31 4d  Free += pcache1M
7a50: 65 6d 53 69 7a 65 28 70 2d 3e 70 61 67 65 2e 70  emSize(p->page.p
7a60: 42 75 66 29 3b 0a 23 69 66 64 65 66 20 53 51 4c  Buf);.#ifdef SQL
7a70: 49 54 45 5f 50 43 41 43 48 45 5f 53 45 50 41 52  ITE_PCACHE_SEPAR
7a80: 41 54 45 5f 48 45 41 44 45 52 0a 20 20 20 20 20  ATE_HEADER.     
7a90: 20 6e 46 72 65 65 20 2b 3d 20 73 71 6c 69 74 65   nFree += sqlite
7aa0: 33 4d 65 6d 53 69 7a 65 28 70 29 3b 0a 23 65 6e  3MemSize(p);.#en
7ab0: 64 69 66 0a 20 20 20 20 20 20 70 63 61 63 68 65  dif.      pcache
7ac0: 31 50 69 6e 50 61 67 65 28 70 29 3b 0a 20 20 20  1PinPage(p);.   
7ad0: 20 20 20 70 63 61 63 68 65 31 52 65 6d 6f 76 65     pcache1Remove
7ae0: 46 72 6f 6d 48 61 73 68 28 70 29 3b 0a 20 20 20  FromHash(p);.   
7af0: 20 20 20 70 63 61 63 68 65 31 46 72 65 65 50 61     pcache1FreePa
7b00: 67 65 28 70 29 3b 0a 20 20 20 20 7d 0a 20 20 20  ge(p);.    }.   
7b10: 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74   pcache1LeaveMut
7b20: 65 78 28 26 70 63 61 63 68 65 31 2e 67 72 70 29  ex(&pcache1.grp)
7b30: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 6e  ;.  }.  return n
7b40: 46 72 65 65 3b 0a 7d 0a 23 65 6e 64 69 66 20 2f  Free;.}.#endif /
7b50: 2a 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f  * SQLITE_ENABLE_
7b60: 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e  MEMORY_MANAGEMEN
7b70: 54 20 2a 2f 0a 0a 23 69 66 64 65 66 20 53 51 4c  T */..#ifdef SQL
7b80: 49 54 45 5f 54 45 53 54 0a 2f 2a 0a 2a 2a 20 54  ITE_TEST./*.** T
7b90: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
7ba0: 75 73 65 64 20 62 79 20 74 65 73 74 20 70 72 6f  used by test pro
7bb0: 63 65 64 75 72 65 73 20 74 6f 20 69 6e 73 70 65  cedures to inspe
7bc0: 63 74 20 74 68 65 20 69 6e 74 65 72 6e 61 6c 20  ct the internal 
7bd0: 73 74 61 74 65 0a 2a 2a 20 6f 66 20 74 68 65 20  state.** of the 
7be0: 67 6c 6f 62 61 6c 20 63 61 63 68 65 2e 0a 2a 2f  global cache..*/
7bf0: 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63 61  .void sqlite3Pca
7c00: 63 68 65 53 74 61 74 73 28 0a 20 20 69 6e 74 20  cheStats(.  int 
7c10: 2a 70 6e 43 75 72 72 65 6e 74 2c 20 20 20 20 20  *pnCurrent,     
7c20: 20 2f 2a 20 4f 55 54 3a 20 54 6f 74 61 6c 20 6e   /* OUT: Total n
7c30: 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 63  umber of pages c
7c40: 61 63 68 65 64 20 2a 2f 0a 20 20 69 6e 74 20 2a  ached */.  int *
7c50: 70 6e 4d 61 78 2c 20 20 20 20 20 20 20 20 20 20  pnMax,          
7c60: 2f 2a 20 4f 55 54 3a 20 47 6c 6f 62 61 6c 20 6d  /* OUT: Global m
7c70: 61 78 69 6d 75 6d 20 63 61 63 68 65 20 73 69 7a  aximum cache siz
7c80: 65 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 4d 69  e */.  int *pnMi
7c90: 6e 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f  n,          /* O
7ca0: 55 54 3a 20 53 75 6d 20 6f 66 20 50 43 61 63 68  UT: Sum of PCach
7cb0: 65 31 2e 6e 4d 69 6e 20 66 6f 72 20 70 75 72 67  e1.nMin for purg
7cc0: 65 61 62 6c 65 20 63 61 63 68 65 73 20 2a 2f 0a  eable caches */.
7cd0: 20 20 69 6e 74 20 2a 70 6e 52 65 63 79 63 6c 61    int *pnRecycla
7ce0: 62 6c 65 20 20 20 20 2f 2a 20 4f 55 54 3a 20 54  ble    /* OUT: T
7cf0: 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 70  otal number of p
7d00: 61 67 65 73 20 61 76 61 69 6c 61 62 6c 65 20 66  ages available f
7d10: 6f 72 20 72 65 63 79 63 6c 69 6e 67 20 2a 2f 0a  or recycling */.
7d20: 29 7b 0a 20 20 50 67 48 64 72 31 20 2a 70 3b 0a  ){.  PgHdr1 *p;.
7d30: 20 20 69 6e 74 20 6e 52 65 63 79 63 6c 61 62 6c    int nRecyclabl
7d40: 65 20 3d 20 30 3b 0a 20 20 66 6f 72 28 70 3d 70  e = 0;.  for(p=p
7d50: 63 61 63 68 65 31 2e 67 72 70 2e 70 4c 72 75 48  cache1.grp.pLruH
7d60: 65 61 64 3b 20 70 3b 20 70 3d 70 2d 3e 70 4c 72  ead; p; p=p->pLr
7d70: 75 4e 65 78 74 29 7b 0a 20 20 20 20 6e 52 65 63  uNext){.    nRec
7d80: 79 63 6c 61 62 6c 65 2b 2b 3b 0a 20 20 7d 0a 20  yclable++;.  }. 
7d90: 20 2a 70 6e 43 75 72 72 65 6e 74 20 3d 20 70 63   *pnCurrent = pc
7da0: 61 63 68 65 31 2e 67 72 70 2e 6e 43 75 72 72 65  ache1.grp.nCurre
7db0: 6e 74 50 61 67 65 3b 0a 20 20 2a 70 6e 4d 61 78  ntPage;.  *pnMax
7dc0: 20 3d 20 70 63 61 63 68 65 31 2e 67 72 70 2e 6e   = pcache1.grp.n
7dd0: 4d 61 78 50 61 67 65 3b 0a 20 20 2a 70 6e 4d 69  MaxPage;.  *pnMi
7de0: 6e 20 3d 20 70 63 61 63 68 65 31 2e 67 72 70 2e  n = pcache1.grp.
7df0: 6e 4d 69 6e 50 61 67 65 3b 0a 20 20 2a 70 6e 52  nMinPage;.  *pnR
7e00: 65 63 79 63 6c 61 62 6c 65 20 3d 20 6e 52 65 63  ecyclable = nRec
7e10: 79 63 6c 61 62 6c 65 3b 0a 7d 0a 23 65 6e 64 69  yclable;.}.#endi
7e20: 66 0a                                            f.