/ Hex Artifact Content
Login

Artifact daa2a58a42a3891a5fc1003fad0a704f465eb3b8:


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 2a  re available..**
02c0: 0a 2a 2a 20 40 28 23 29 20 24 49 64 3a 20 70 63  .** @(#) $Id: pc
02d0: 61 63 68 65 31 2e 63 2c 76 20 31 2e 31 38 20 32  ache1.c,v 1.18 2
02e0: 30 30 39 2f 30 37 2f 31 36 20 31 38 3a 32 31 3a  009/07/16 18:21:
02f0: 31 38 20 64 72 68 20 45 78 70 20 24 0a 2a 2f 0a  18 drh Exp $.*/.
0300: 0a 23 69 6e 63 6c 75 64 65 20 22 73 71 6c 69 74  .#include "sqlit
0310: 65 49 6e 74 2e 68 22 0a 0a 74 79 70 65 64 65 66  eInt.h"..typedef
0320: 20 73 74 72 75 63 74 20 50 43 61 63 68 65 31 20   struct PCache1 
0330: 50 43 61 63 68 65 31 3b 0a 74 79 70 65 64 65 66  PCache1;.typedef
0340: 20 73 74 72 75 63 74 20 50 67 48 64 72 31 20 50   struct PgHdr1 P
0350: 67 48 64 72 31 3b 0a 74 79 70 65 64 65 66 20 73  gHdr1;.typedef s
0360: 74 72 75 63 74 20 50 67 46 72 65 65 73 6c 6f 74  truct PgFreeslot
0370: 20 50 67 46 72 65 65 73 6c 6f 74 3b 0a 0a 2f 2a   PgFreeslot;../*
0380: 20 50 6f 69 6e 74 65 72 73 20 74 6f 20 73 74 72   Pointers to str
0390: 75 63 74 75 72 65 73 20 6f 66 20 74 68 69 73 20  uctures of this 
03a0: 74 79 70 65 20 61 72 65 20 63 61 73 74 20 61 6e  type are cast an
03b0: 64 20 72 65 74 75 72 6e 65 64 20 61 73 20 0a 2a  d returned as .*
03c0: 2a 20 6f 70 61 71 75 65 20 73 71 6c 69 74 65 33  * opaque sqlite3
03d0: 5f 70 63 61 63 68 65 2a 20 68 61 6e 64 6c 65 73  _pcache* handles
03e0: 0a 2a 2f 0a 73 74 72 75 63 74 20 50 43 61 63 68  .*/.struct PCach
03f0: 65 31 20 7b 0a 20 20 2f 2a 20 43 61 63 68 65 20  e1 {.  /* Cache 
0400: 63 6f 6e 66 69 67 75 72 61 74 69 6f 6e 20 70 61  configuration pa
0410: 72 61 6d 65 74 65 72 73 2e 20 50 61 67 65 20 73  rameters. Page s
0420: 69 7a 65 20 28 73 7a 50 61 67 65 29 20 61 6e 64  ize (szPage) and
0430: 20 74 68 65 20 70 75 72 67 65 61 62 6c 65 0a 20   the purgeable. 
0440: 20 2a 2a 20 66 6c 61 67 20 28 62 50 75 72 67 65   ** flag (bPurge
0450: 61 62 6c 65 29 20 61 72 65 20 73 65 74 20 77 68  able) are set wh
0460: 65 6e 20 74 68 65 20 63 61 63 68 65 20 69 73 20  en the cache is 
0470: 63 72 65 61 74 65 64 2e 20 6e 4d 61 78 20 6d 61  created. nMax ma
0480: 79 20 62 65 20 0a 20 20 2a 2a 20 6d 6f 64 69 66  y be .  ** modif
0490: 69 65 64 20 61 74 20 61 6e 79 20 74 69 6d 65 20  ied at any time 
04a0: 62 79 20 61 20 63 61 6c 6c 20 74 6f 20 74 68 65  by a call to the
04b0: 20 70 63 61 63 68 65 31 43 61 63 68 65 53 69 7a   pcache1CacheSiz
04c0: 65 28 29 20 6d 65 74 68 6f 64 2e 0a 20 20 2a 2a  e() method..  **
04d0: 20 54 68 65 20 67 6c 6f 62 61 6c 20 6d 75 74 65   The global mute
04e0: 78 20 6d 75 73 74 20 62 65 20 68 65 6c 64 20 77  x must be held w
04f0: 68 65 6e 20 61 63 63 65 73 73 69 6e 67 20 6e 4d  hen accessing nM
0500: 61 78 2e 0a 20 20 2a 2f 0a 20 20 69 6e 74 20 73  ax..  */.  int s
0510: 7a 50 61 67 65 3b 20 20 20 20 20 20 20 20 20 20  zPage;          
0520: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0530: 2a 20 53 69 7a 65 20 6f 66 20 61 6c 6c 6f 63 61  * Size of alloca
0540: 74 65 64 20 70 61 67 65 73 20 69 6e 20 62 79 74  ted pages in byt
0550: 65 73 20 2a 2f 0a 20 20 69 6e 74 20 62 50 75 72  es */.  int bPur
0560: 67 65 61 62 6c 65 3b 20 20 20 20 20 20 20 20 20  geable;         
0570: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
0580: 72 75 65 20 69 66 20 63 61 63 68 65 20 69 73 20  rue if cache is 
0590: 70 75 72 67 65 61 62 6c 65 20 2a 2f 0a 20 20 75  purgeable */.  u
05a0: 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 4d 69 6e  nsigned int nMin
05b0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
05c0: 20 20 20 2f 2a 20 4d 69 6e 69 6d 75 6d 20 6e 75     /* Minimum nu
05d0: 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 72 65  mber of pages re
05e0: 73 65 72 76 65 64 20 2a 2f 0a 20 20 75 6e 73 69  served */.  unsi
05f0: 67 6e 65 64 20 69 6e 74 20 6e 4d 61 78 3b 20 20  gned int nMax;  
0600: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0610: 2f 2a 20 43 6f 6e 66 69 67 75 72 65 64 20 22 63  /* Configured "c
0620: 61 63 68 65 5f 73 69 7a 65 22 20 76 61 6c 75 65  ache_size" value
0630: 20 2a 2f 0a 0a 20 20 2f 2a 20 48 61 73 68 20 74   */..  /* Hash t
0640: 61 62 6c 65 20 6f 66 20 61 6c 6c 20 70 61 67 65  able of all page
0650: 73 2e 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  s. The following
0660: 20 76 61 72 69 61 62 6c 65 73 20 6d 61 79 20 6f   variables may o
0670: 6e 6c 79 20 62 65 20 61 63 63 65 73 73 65 64 0a  nly be accessed.
0680: 20 20 2a 2a 20 77 68 65 6e 20 74 68 65 20 61 63    ** when the ac
0690: 63 65 73 73 6f 72 20 69 73 20 68 6f 6c 64 69 6e  cessor is holdin
06a0: 67 20 74 68 65 20 67 6c 6f 62 61 6c 20 6d 75 74  g the global mut
06b0: 65 78 20 28 73 65 65 20 70 63 61 63 68 65 31 45  ex (see pcache1E
06c0: 6e 74 65 72 4d 75 74 65 78 28 29 20 0a 20 20 2a  nterMutex() .  *
06d0: 2a 20 61 6e 64 20 70 63 61 63 68 65 31 4c 65 61  * and pcache1Lea
06e0: 76 65 4d 75 74 65 78 28 29 29 2e 0a 20 20 2a 2f  veMutex())..  */
06f0: 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  .  unsigned int 
0700: 6e 52 65 63 79 63 6c 61 62 6c 65 3b 20 20 20 20  nRecyclable;    
0710: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
0720: 20 6f 66 20 70 61 67 65 73 20 69 6e 20 74 68 65   of pages in the
0730: 20 4c 52 55 20 6c 69 73 74 20 2a 2f 0a 20 20 75   LRU list */.  u
0740: 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 50 61 67  nsigned int nPag
0750: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
0760: 20 20 20 2f 2a 20 54 6f 74 61 6c 20 6e 75 6d 62     /* Total numb
0770: 65 72 20 6f 66 20 70 61 67 65 73 20 69 6e 20 61  er of pages in a
0780: 70 48 61 73 68 20 2a 2f 0a 20 20 75 6e 73 69 67  pHash */.  unsig
0790: 6e 65 64 20 69 6e 74 20 6e 48 61 73 68 3b 20 20  ned int nHash;  
07a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
07b0: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 73 6c 6f 74  * Number of slot
07c0: 73 20 69 6e 20 61 70 48 61 73 68 5b 5d 20 2a 2f  s in apHash[] */
07d0: 0a 20 20 50 67 48 64 72 31 20 2a 2a 61 70 48 61  .  PgHdr1 **apHa
07e0: 73 68 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  sh;             
07f0: 20 20 20 20 20 20 20 2f 2a 20 48 61 73 68 20 74         /* Hash t
0800: 61 62 6c 65 20 66 6f 72 20 66 61 73 74 20 6c 6f  able for fast lo
0810: 6f 6b 75 70 20 62 79 20 6b 65 79 20 2a 2f 0a 0a  okup by key */..
0820: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69    unsigned int i
0830: 4d 61 78 4b 65 79 3b 20 20 20 20 20 20 20 20 20  MaxKey;         
0840: 20 20 20 20 20 20 2f 2a 20 4c 61 72 67 65 73 74        /* Largest
0850: 20 6b 65 79 20 73 65 65 6e 20 73 69 6e 63 65 20   key seen since 
0860: 78 54 72 75 6e 63 61 74 65 28 29 20 2a 2f 0a 7d  xTruncate() */.}
0870: 3b 0a 0a 2f 2a 0a 2a 2a 20 45 61 63 68 20 63 61  ;../*.** Each ca
0880: 63 68 65 20 65 6e 74 72 79 20 69 73 20 72 65 70  che entry is rep
0890: 72 65 73 65 6e 74 65 64 20 62 79 20 61 6e 20 69  resented by an i
08a0: 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 65 20 66  nstance of the f
08b0: 6f 6c 6c 6f 77 69 6e 67 20 0a 2a 2a 20 73 74 72  ollowing .** str
08c0: 75 63 74 75 72 65 2e 20 41 20 62 75 66 66 65 72  ucture. A buffer
08d0: 20 6f 66 20 50 67 48 64 72 31 2e 70 43 61 63 68   of PgHdr1.pCach
08e0: 65 2d 3e 73 7a 50 61 67 65 20 62 79 74 65 73 20  e->szPage bytes 
08f0: 69 73 20 61 6c 6c 6f 63 61 74 65 64 20 0a 2a 2a  is allocated .**
0900: 20 64 69 72 65 63 74 6c 79 20 62 65 66 6f 72 65   directly before
0910: 20 74 68 69 73 20 73 74 72 75 63 74 75 72 65 20   this structure 
0920: 69 6e 20 6d 65 6d 6f 72 79 20 28 73 65 65 20 74  in memory (see t
0930: 68 65 20 50 47 48 44 52 31 5f 54 4f 5f 50 41 47  he PGHDR1_TO_PAG
0940: 45 28 29 20 0a 2a 2a 20 6d 61 63 72 6f 20 62 65  E() .** macro be
0950: 6c 6f 77 29 2e 0a 2a 2f 0a 73 74 72 75 63 74 20  low)..*/.struct 
0960: 50 67 48 64 72 31 20 7b 0a 20 20 75 6e 73 69 67  PgHdr1 {.  unsig
0970: 6e 65 64 20 69 6e 74 20 69 4b 65 79 3b 20 20 20  ned int iKey;   
0980: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4b 65 79            /* Key
0990: 20 76 61 6c 75 65 20 28 70 61 67 65 20 6e 75 6d   value (page num
09a0: 62 65 72 29 20 2a 2f 0a 20 20 50 67 48 64 72 31  ber) */.  PgHdr1
09b0: 20 2a 70 4e 65 78 74 3b 20 20 20 20 20 20 20 20   *pNext;        
09c0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74           /* Next
09d0: 20 69 6e 20 68 61 73 68 20 74 61 62 6c 65 20 63   in hash table c
09e0: 68 61 69 6e 20 2a 2f 0a 20 20 50 43 61 63 68 65  hain */.  PCache
09f0: 31 20 2a 70 43 61 63 68 65 3b 20 20 20 20 20 20  1 *pCache;      
0a00: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 61 63 68           /* Cach
0a10: 65 20 74 68 61 74 20 63 75 72 72 65 6e 74 6c 79  e that currently
0a20: 20 6f 77 6e 73 20 74 68 69 73 20 70 61 67 65 20   owns this page 
0a30: 2a 2f 0a 20 20 50 67 48 64 72 31 20 2a 70 4c 72  */.  PgHdr1 *pLr
0a40: 75 4e 65 78 74 3b 20 20 20 20 20 20 20 20 20 20  uNext;          
0a50: 20 20 20 20 2f 2a 20 4e 65 78 74 20 69 6e 20 4c      /* Next in L
0a60: 52 55 20 6c 69 73 74 20 6f 66 20 75 6e 70 69 6e  RU list of unpin
0a70: 6e 65 64 20 70 61 67 65 73 20 2a 2f 0a 20 20 50  ned pages */.  P
0a80: 67 48 64 72 31 20 2a 70 4c 72 75 50 72 65 76 3b  gHdr1 *pLruPrev;
0a90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0aa0: 20 50 72 65 76 69 6f 75 73 20 69 6e 20 4c 52 55   Previous in LRU
0ab0: 20 6c 69 73 74 20 6f 66 20 75 6e 70 69 6e 6e 65   list of unpinne
0ac0: 64 20 70 61 67 65 73 20 2a 2f 0a 7d 3b 0a 0a 2f  d pages */.};../
0ad0: 2a 0a 2a 2a 20 46 72 65 65 20 73 6c 6f 74 73 20  *.** Free slots 
0ae0: 69 6e 20 74 68 65 20 61 6c 6c 6f 63 61 74 6f 72  in the allocator
0af0: 20 75 73 65 64 20 74 6f 20 64 69 76 69 64 65 20   used to divide 
0b00: 75 70 20 74 68 65 20 62 75 66 66 65 72 20 70 72  up the buffer pr
0b10: 6f 76 69 64 65 64 20 75 73 69 6e 67 0a 2a 2a 20  ovided using.** 
0b20: 74 68 65 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49  the SQLITE_CONFI
0b30: 47 5f 50 41 47 45 43 41 43 48 45 20 6d 65 63 68  G_PAGECACHE mech
0b40: 61 6e 69 73 6d 2e 0a 2a 2f 0a 73 74 72 75 63 74  anism..*/.struct
0b50: 20 50 67 46 72 65 65 73 6c 6f 74 20 7b 0a 20 20   PgFreeslot {.  
0b60: 50 67 46 72 65 65 73 6c 6f 74 20 2a 70 4e 65 78  PgFreeslot *pNex
0b70: 74 3b 20 20 2f 2a 20 4e 65 78 74 20 66 72 65 65  t;  /* Next free
0b80: 20 73 6c 6f 74 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a   slot */.};../*.
0b90: 2a 2a 20 47 6c 6f 62 61 6c 20 64 61 74 61 20 75  ** Global data u
0ba0: 73 65 64 20 62 79 20 74 68 69 73 20 63 61 63 68  sed by this cach
0bb0: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 53 51 4c  e..*/.static SQL
0bc0: 49 54 45 5f 57 53 44 20 73 74 72 75 63 74 20 50  ITE_WSD struct P
0bd0: 43 61 63 68 65 47 6c 6f 62 61 6c 20 7b 0a 20 20  CacheGlobal {.  
0be0: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 20 2a 6d  sqlite3_mutex *m
0bf0: 75 74 65 78 3b 20 20 20 20 20 20 20 20 20 20 20  utex;           
0c00: 20 20 20 20 2f 2a 20 73 74 61 74 69 63 20 6d 75      /* static mu
0c10: 74 65 78 20 4d 55 54 45 58 5f 53 54 41 54 49 43  tex MUTEX_STATIC
0c20: 5f 4c 52 55 20 2a 2f 0a 0a 20 20 69 6e 74 20 6e  _LRU */..  int n
0c30: 4d 61 78 50 61 67 65 3b 20 20 20 20 20 20 20 20  MaxPage;        
0c40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0c50: 2a 20 53 75 6d 20 6f 66 20 6e 4d 61 78 50 61 67  * Sum of nMaxPag
0c60: 65 20 66 6f 72 20 70 75 72 67 65 61 62 6c 65 20  e for purgeable 
0c70: 63 61 63 68 65 73 20 2a 2f 0a 20 20 69 6e 74 20  caches */.  int 
0c80: 6e 4d 69 6e 50 61 67 65 3b 20 20 20 20 20 20 20  nMinPage;       
0c90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ca0: 2f 2a 20 53 75 6d 20 6f 66 20 6e 4d 69 6e 50 61  /* Sum of nMinPa
0cb0: 67 65 20 66 6f 72 20 70 75 72 67 65 61 62 6c 65  ge for purgeable
0cc0: 20 63 61 63 68 65 73 20 2a 2f 0a 20 20 69 6e 74   caches */.  int
0cd0: 20 6e 43 75 72 72 65 6e 74 50 61 67 65 3b 20 20   nCurrentPage;  
0ce0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0cf0: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 70 75   /* Number of pu
0d00: 72 67 65 61 62 6c 65 20 70 61 67 65 73 20 61 6c  rgeable pages al
0d10: 6c 6f 63 61 74 65 64 20 2a 2f 0a 20 20 50 67 48  located */.  PgH
0d20: 64 72 31 20 2a 70 4c 72 75 48 65 61 64 2c 20 2a  dr1 *pLruHead, *
0d30: 70 4c 72 75 54 61 69 6c 3b 20 20 20 20 20 20 20  pLruTail;       
0d40: 20 2f 2a 20 4c 52 55 20 6c 69 73 74 20 6f 66 20   /* LRU list of 
0d50: 75 6e 70 69 6e 6e 65 64 20 70 61 67 65 73 20 2a  unpinned pages *
0d60: 2f 0a 0a 20 20 2f 2a 20 56 61 72 69 61 62 6c 65  /..  /* Variable
0d70: 73 20 72 65 6c 61 74 65 64 20 74 6f 20 53 51 4c  s related to SQL
0d80: 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43  ITE_CONFIG_PAGEC
0d90: 41 43 48 45 20 73 65 74 74 69 6e 67 73 2e 20 2a  ACHE settings. *
0da0: 2f 0a 20 20 69 6e 74 20 73 7a 53 6c 6f 74 3b 20  /.  int szSlot; 
0db0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0dc0: 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
0dd0: 6f 66 20 65 61 63 68 20 66 72 65 65 20 73 6c 6f  of each free slo
0de0: 74 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 53 74  t */.  void *pSt
0df0: 61 72 74 2c 20 2a 70 45 6e 64 3b 20 20 20 20 20  art, *pEnd;     
0e00: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 6f             /* Bo
0e10: 75 6e 64 73 20 6f 66 20 70 61 67 65 63 61 63 68  unds of pagecach
0e20: 65 20 6d 61 6c 6c 6f 63 20 72 61 6e 67 65 20 2a  e malloc range *
0e30: 2f 0a 20 20 50 67 46 72 65 65 73 6c 6f 74 20 2a  /.  PgFreeslot *
0e40: 70 46 72 65 65 3b 20 20 20 20 20 20 20 20 20 20  pFree;          
0e50: 20 20 20 20 20 20 20 20 2f 2a 20 46 72 65 65 20          /* Free 
0e60: 70 61 67 65 20 62 6c 6f 63 6b 73 20 2a 2f 0a 20  page blocks */. 
0e70: 20 69 6e 74 20 69 73 49 6e 69 74 3b 20 20 20 20   int isInit;    
0e80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e90: 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20       /* True if 
0ea0: 69 6e 69 74 69 61 6c 69 7a 65 64 20 2a 2f 0a 7d  initialized */.}
0eb0: 20 70 63 61 63 68 65 31 5f 67 3b 0a 0a 2f 2a 0a   pcache1_g;../*.
0ec0: 2a 2a 20 41 6c 6c 20 63 6f 64 65 20 69 6e 20 74  ** All code in t
0ed0: 68 69 73 20 66 69 6c 65 20 73 68 6f 75 6c 64 20  his file should 
0ee0: 61 63 63 65 73 73 20 74 68 65 20 67 6c 6f 62 61  access the globa
0ef0: 6c 20 73 74 72 75 63 74 75 72 65 20 61 62 6f 76  l structure abov
0f00: 65 20 76 69 61 20 74 68 65 0a 2a 2a 20 61 6c 69  e via the.** ali
0f10: 61 73 20 22 70 63 61 63 68 65 31 22 2e 20 54 68  as "pcache1". Th
0f20: 69 73 20 65 6e 73 75 72 65 73 20 74 68 61 74 20  is ensures that 
0f30: 74 68 65 20 57 53 44 20 65 6d 75 6c 61 74 69 6f  the WSD emulatio
0f40: 6e 20 69 73 20 75 73 65 64 20 77 68 65 6e 0a 2a  n is used when.*
0f50: 2a 20 63 6f 6d 70 69 6c 69 6e 67 20 66 6f 72 20  * compiling for 
0f60: 73 79 73 74 65 6d 73 20 74 68 61 74 20 64 6f 20  systems that do 
0f70: 6e 6f 74 20 73 75 70 70 6f 72 74 20 72 65 61 6c  not support real
0f80: 20 57 53 44 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65   WSD..*/.#define
0f90: 20 70 63 61 63 68 65 31 20 28 47 4c 4f 42 41 4c   pcache1 (GLOBAL
0fa0: 28 73 74 72 75 63 74 20 50 43 61 63 68 65 47 6c  (struct PCacheGl
0fb0: 6f 62 61 6c 2c 20 70 63 61 63 68 65 31 5f 67 29  obal, pcache1_g)
0fc0: 29 0a 0a 2f 2a 0a 2a 2a 20 57 68 65 6e 20 61 20  )../*.** When a 
0fd0: 50 67 48 64 72 31 20 73 74 72 75 63 74 75 72 65  PgHdr1 structure
0fe0: 20 69 73 20 61 6c 6c 6f 63 61 74 65 64 2c 20 74   is allocated, t
0ff0: 68 65 20 61 73 73 6f 63 69 61 74 65 64 20 50 43  he associated PC
1000: 61 63 68 65 31 2e 73 7a 50 61 67 65 0a 2a 2a 20  ache1.szPage.** 
1010: 62 79 74 65 73 20 6f 66 20 64 61 74 61 20 61 72  bytes of data ar
1020: 65 20 6c 6f 63 61 74 65 64 20 64 69 72 65 63 74  e located direct
1030: 6c 79 20 62 65 66 6f 72 65 20 69 74 20 69 6e 20  ly before it in 
1040: 6d 65 6d 6f 72 79 20 28 69 2e 65 2e 20 74 68 65  memory (i.e. the
1050: 20 74 6f 74 61 6c 0a 2a 2a 20 73 69 7a 65 20 6f   total.** size o
1060: 66 20 74 68 65 20 61 6c 6c 6f 63 61 74 69 6f 6e  f the allocation
1070: 20 69 73 20 73 69 7a 65 6f 66 28 50 67 48 64 72   is sizeof(PgHdr
1080: 31 29 2b 50 43 61 63 68 65 31 2e 73 7a 50 61 67  1)+PCache1.szPag
1090: 65 20 62 79 74 65 29 2e 20 54 68 65 0a 2a 2a 20  e byte). The.** 
10a0: 50 47 48 44 52 31 5f 54 4f 5f 50 41 47 45 28 29  PGHDR1_TO_PAGE()
10b0: 20 6d 61 63 72 6f 20 74 61 6b 65 73 20 61 20 70   macro takes a p
10c0: 6f 69 6e 74 65 72 20 74 6f 20 61 20 50 67 48 64  ointer to a PgHd
10d0: 72 31 20 73 74 72 75 63 74 75 72 65 20 61 73 0a  r1 structure as.
10e0: 2a 2a 20 61 6e 20 61 72 67 75 6d 65 6e 74 20 61  ** an argument a
10f0: 6e 64 20 72 65 74 75 72 6e 73 20 61 20 70 6f 69  nd returns a poi
1100: 6e 74 65 72 20 74 6f 20 74 68 65 20 61 73 73 6f  nter to the asso
1110: 63 69 61 74 65 64 20 62 6c 6f 63 6b 20 6f 66 20  ciated block of 
1120: 73 7a 50 61 67 65 0a 2a 2a 20 62 79 74 65 73 2e  szPage.** bytes.
1130: 20 54 68 65 20 50 41 47 45 5f 54 4f 5f 50 47 48   The PAGE_TO_PGH
1140: 44 52 31 28 29 20 6d 61 63 72 6f 20 64 6f 65 73  DR1() macro does
1150: 20 74 68 65 20 6f 70 70 6f 73 69 74 65 3a 20 69   the opposite: i
1160: 74 73 20 61 72 67 75 6d 65 6e 74 20 69 73 0a 2a  ts argument is.*
1170: 2a 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 61  * a pointer to a
1180: 20 62 6c 6f 63 6b 20 6f 66 20 73 7a 50 61 67 65   block of szPage
1190: 20 62 79 74 65 73 20 6f 66 20 64 61 74 61 20 61   bytes of data a
11a0: 6e 64 20 74 68 65 20 72 65 74 75 72 6e 20 76 61  nd the return va
11b0: 6c 75 65 20 69 73 0a 2a 2a 20 61 20 70 6f 69 6e  lue is.** a poin
11c0: 74 65 72 20 74 6f 20 74 68 65 20 61 73 73 6f 63  ter to the assoc
11d0: 69 61 74 65 64 20 50 67 48 64 72 31 20 73 74 72  iated PgHdr1 str
11e0: 75 63 74 75 72 65 2e 0a 2a 2a 0a 2a 2a 20 20 20  ucture..**.**   
11f0: 61 73 73 65 72 74 28 20 50 47 48 44 52 31 5f 54  assert( PGHDR1_T
1200: 4f 5f 50 41 47 45 28 50 41 47 45 5f 54 4f 5f 50  O_PAGE(PAGE_TO_P
1210: 47 48 44 52 31 28 70 43 61 63 68 65 2c 20 58 29  GHDR1(pCache, X)
1220: 29 3d 3d 58 20 29 3b 0a 2a 2f 0a 23 64 65 66 69  )==X );.*/.#defi
1230: 6e 65 20 50 47 48 44 52 31 5f 54 4f 5f 50 41 47  ne PGHDR1_TO_PAG
1240: 45 28 70 29 20 20 20 20 28 76 6f 69 64 2a 29 28  E(p)    (void*)(
1250: 28 28 63 68 61 72 2a 29 70 29 20 2d 20 70 2d 3e  ((char*)p) - p->
1260: 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 29 0a  pCache->szPage).
1270: 23 64 65 66 69 6e 65 20 50 41 47 45 5f 54 4f 5f  #define PAGE_TO_
1280: 50 47 48 44 52 31 28 63 2c 20 70 29 20 28 50 67  PGHDR1(c, p) (Pg
1290: 48 64 72 31 2a 29 28 28 28 63 68 61 72 2a 29 70  Hdr1*)(((char*)p
12a0: 29 20 2b 20 63 2d 3e 73 7a 50 61 67 65 29 0a 0a  ) + c->szPage)..
12b0: 2f 2a 0a 2a 2a 20 4d 61 63 72 6f 73 20 74 6f 20  /*.** Macros to 
12c0: 65 6e 74 65 72 20 61 6e 64 20 6c 65 61 76 65 20  enter and leave 
12d0: 74 68 65 20 67 6c 6f 62 61 6c 20 4c 52 55 20 6d  the global LRU m
12e0: 75 74 65 78 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65  utex..*/.#define
12f0: 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74   pcache1EnterMut
1300: 65 78 28 29 20 73 71 6c 69 74 65 33 5f 6d 75 74  ex() sqlite3_mut
1310: 65 78 5f 65 6e 74 65 72 28 70 63 61 63 68 65 31  ex_enter(pcache1
1320: 2e 6d 75 74 65 78 29 0a 23 64 65 66 69 6e 65 20  .mutex).#define 
1330: 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65  pcache1LeaveMute
1340: 78 28 29 20 73 71 6c 69 74 65 33 5f 6d 75 74 65  x() sqlite3_mute
1350: 78 5f 6c 65 61 76 65 28 70 63 61 63 68 65 31 2e  x_leave(pcache1.
1360: 6d 75 74 65 78 29 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a  mutex)../*******
1370: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1380: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1390: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
13a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
13b0: 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 2a 2a 2a 2a 2a  *******/./******
13c0: 2a 2a 20 50 61 67 65 20 41 6c 6c 6f 63 61 74 69  ** Page Allocati
13d0: 6f 6e 2f 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47  on/SQLITE_CONFIG
13e0: 5f 50 43 41 43 48 45 20 52 65 6c 61 74 65 64 20  _PCACHE Related 
13f0: 46 75 6e 63 74 69 6f 6e 73 20 2a 2a 2a 2a 2a 2a  Functions ******
1400: 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f 2a 0a 2a 2a  ********/../*.**
1410: 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   This function i
1420: 73 20 63 61 6c 6c 65 64 20 64 75 72 69 6e 67 20  s called during 
1430: 69 6e 69 74 69 61 6c 69 7a 61 74 69 6f 6e 20 69  initialization i
1440: 66 20 61 20 73 74 61 74 69 63 20 62 75 66 66 65  f a static buffe
1450: 72 20 69 73 20 0a 2a 2a 20 73 75 70 70 6c 69 65  r is .** supplie
1460: 64 20 74 6f 20 75 73 65 20 66 6f 72 20 74 68 65  d to use for the
1470: 20 70 61 67 65 2d 63 61 63 68 65 20 62 79 20 70   page-cache by p
1480: 61 73 73 69 6e 67 20 74 68 65 20 53 51 4c 49 54  assing the SQLIT
1490: 45 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41 43  E_CONFIG_PAGECAC
14a0: 48 45 0a 2a 2a 20 76 65 72 62 20 74 6f 20 73 71  HE.** verb to sq
14b0: 6c 69 74 65 33 5f 63 6f 6e 66 69 67 28 29 2e 20  lite3_config(). 
14c0: 50 61 72 61 6d 65 74 65 72 20 70 42 75 66 20 70  Parameter pBuf p
14d0: 6f 69 6e 74 73 20 74 6f 20 61 6e 20 61 6c 6c 6f  oints to an allo
14e0: 63 61 74 69 6f 6e 20 6c 61 72 67 65 0a 2a 2a 20  cation large.** 
14f0: 65 6e 6f 75 67 68 20 74 6f 20 63 6f 6e 74 61 69  enough to contai
1500: 6e 20 27 6e 27 20 62 75 66 66 65 72 73 20 6f 66  n 'n' buffers of
1510: 20 27 73 7a 27 20 62 79 74 65 73 20 65 61 63 68   'sz' bytes each
1520: 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
1530: 33 50 43 61 63 68 65 42 75 66 66 65 72 53 65 74  3PCacheBufferSet
1540: 75 70 28 76 6f 69 64 20 2a 70 42 75 66 2c 20 69  up(void *pBuf, i
1550: 6e 74 20 73 7a 2c 20 69 6e 74 20 6e 29 7b 0a 20  nt sz, int n){. 
1560: 20 69 66 28 20 70 63 61 63 68 65 31 2e 69 73 49   if( pcache1.isI
1570: 6e 69 74 20 29 7b 0a 20 20 20 20 50 67 46 72 65  nit ){.    PgFre
1580: 65 73 6c 6f 74 20 2a 70 3b 0a 20 20 20 20 73 7a  eslot *p;.    sz
1590: 20 3d 20 52 4f 55 4e 44 44 4f 57 4e 38 28 73 7a   = ROUNDDOWN8(sz
15a0: 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 73  );.    pcache1.s
15b0: 7a 53 6c 6f 74 20 3d 20 73 7a 3b 0a 20 20 20 20  zSlot = sz;.    
15c0: 70 63 61 63 68 65 31 2e 70 53 74 61 72 74 20 3d  pcache1.pStart =
15d0: 20 70 42 75 66 3b 0a 20 20 20 20 70 63 61 63 68   pBuf;.    pcach
15e0: 65 31 2e 70 46 72 65 65 20 3d 20 30 3b 0a 20 20  e1.pFree = 0;.  
15f0: 20 20 77 68 69 6c 65 28 20 6e 2d 2d 20 29 7b 0a    while( n-- ){.
1600: 20 20 20 20 20 20 70 20 3d 20 28 50 67 46 72 65        p = (PgFre
1610: 65 73 6c 6f 74 2a 29 70 42 75 66 3b 0a 20 20 20  eslot*)pBuf;.   
1620: 20 20 20 70 2d 3e 70 4e 65 78 74 20 3d 20 70 63     p->pNext = pc
1630: 61 63 68 65 31 2e 70 46 72 65 65 3b 0a 20 20 20  ache1.pFree;.   
1640: 20 20 20 70 63 61 63 68 65 31 2e 70 46 72 65 65     pcache1.pFree
1650: 20 3d 20 70 3b 0a 20 20 20 20 20 20 70 42 75 66   = p;.      pBuf
1660: 20 3d 20 28 76 6f 69 64 2a 29 26 28 28 63 68 61   = (void*)&((cha
1670: 72 2a 29 70 42 75 66 29 5b 73 7a 5d 3b 0a 20 20  r*)pBuf)[sz];.  
1680: 20 20 7d 0a 20 20 20 20 70 63 61 63 68 65 31 2e    }.    pcache1.
1690: 70 45 6e 64 20 3d 20 70 42 75 66 3b 0a 20 20 7d  pEnd = pBuf;.  }
16a0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6c 6c 6f 63  .}../*.** Malloc
16b0: 20 66 75 6e 63 74 69 6f 6e 20 75 73 65 64 20 77   function used w
16c0: 69 74 68 69 6e 20 74 68 69 73 20 66 69 6c 65 20  ithin this file 
16d0: 74 6f 20 61 6c 6c 6f 63 61 74 65 20 73 70 61 63  to allocate spac
16e0: 65 20 66 72 6f 6d 20 74 68 65 20 62 75 66 66 65  e from the buffe
16f0: 72 0a 2a 2a 20 63 6f 6e 66 69 67 75 72 65 64 20  r.** configured 
1700: 75 73 69 6e 67 20 73 71 6c 69 74 65 33 5f 63 6f  using sqlite3_co
1710: 6e 66 69 67 28 53 51 4c 49 54 45 5f 43 4f 4e 46  nfig(SQLITE_CONF
1720: 49 47 5f 50 41 47 45 43 41 43 48 45 29 20 6f 70  IG_PAGECACHE) op
1730: 74 69 6f 6e 2e 20 49 66 20 6e 6f 20 0a 2a 2a 20  tion. If no .** 
1740: 73 75 63 68 20 62 75 66 66 65 72 20 65 78 69 73  such buffer exis
1750: 74 73 20 6f 72 20 74 68 65 72 65 20 69 73 20 6e  ts or there is n
1760: 6f 20 73 70 61 63 65 20 6c 65 66 74 20 69 6e 20  o space left in 
1770: 69 74 2c 20 74 68 69 73 20 66 75 6e 63 74 69 6f  it, this functio
1780: 6e 20 66 61 6c 6c 73 20 0a 2a 2a 20 62 61 63 6b  n falls .** back
1790: 20 74 6f 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f   to sqlite3Mallo
17a0: 63 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  c()..*/.static v
17b0: 6f 69 64 20 2a 70 63 61 63 68 65 31 41 6c 6c 6f  oid *pcache1Allo
17c0: 63 28 69 6e 74 20 6e 42 79 74 65 29 7b 0a 20 20  c(int nByte){.  
17d0: 76 6f 69 64 20 2a 70 3b 0a 20 20 61 73 73 65 72  void *p;.  asser
17e0: 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78  t( sqlite3_mutex
17f0: 5f 68 65 6c 64 28 70 63 61 63 68 65 31 2e 6d 75  _held(pcache1.mu
1800: 74 65 78 29 20 29 3b 0a 20 20 69 66 28 20 6e 42  tex) );.  if( nB
1810: 79 74 65 3c 3d 70 63 61 63 68 65 31 2e 73 7a 53  yte<=pcache1.szS
1820: 6c 6f 74 20 26 26 20 70 63 61 63 68 65 31 2e 70  lot && pcache1.p
1830: 46 72 65 65 20 29 7b 0a 20 20 20 20 61 73 73 65  Free ){.    asse
1840: 72 74 28 20 70 63 61 63 68 65 31 2e 69 73 49 6e  rt( pcache1.isIn
1850: 69 74 20 29 3b 0a 20 20 20 20 70 20 3d 20 28 50  it );.    p = (P
1860: 67 48 64 72 31 20 2a 29 70 63 61 63 68 65 31 2e  gHdr1 *)pcache1.
1870: 70 46 72 65 65 3b 0a 20 20 20 20 70 63 61 63 68  pFree;.    pcach
1880: 65 31 2e 70 46 72 65 65 20 3d 20 70 63 61 63 68  e1.pFree = pcach
1890: 65 31 2e 70 46 72 65 65 2d 3e 70 4e 65 78 74 3b  e1.pFree->pNext;
18a0: 0a 20 20 20 20 73 71 6c 69 74 65 33 53 74 61 74  .    sqlite3Stat
18b0: 75 73 53 65 74 28 53 51 4c 49 54 45 5f 53 54 41  usSet(SQLITE_STA
18c0: 54 55 53 5f 50 41 47 45 43 41 43 48 45 5f 53 49  TUS_PAGECACHE_SI
18d0: 5a 45 2c 20 6e 42 79 74 65 29 3b 0a 20 20 20 20  ZE, nByte);.    
18e0: 73 71 6c 69 74 65 33 53 74 61 74 75 73 41 64 64  sqlite3StatusAdd
18f0: 28 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50  (SQLITE_STATUS_P
1900: 41 47 45 43 41 43 48 45 5f 55 53 45 44 2c 20 31  AGECACHE_USED, 1
1910: 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 0a 20 20 20  );.  }else{..   
1920: 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 61 20 6e   /* Allocate a n
1930: 65 77 20 62 75 66 66 65 72 20 75 73 69 6e 67 20  ew buffer using 
1940: 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 2e 20 42  sqlite3Malloc. B
1950: 65 66 6f 72 65 20 64 6f 69 6e 67 20 73 6f 2c 20  efore doing so, 
1960: 65 78 69 74 20 74 68 65 0a 20 20 20 20 2a 2a 20  exit the.    ** 
1970: 67 6c 6f 62 61 6c 20 70 63 61 63 68 65 20 6d 75  global pcache mu
1980: 74 65 78 20 61 6e 64 20 75 6e 6c 6f 63 6b 20 74  tex and unlock t
1990: 68 65 20 70 61 67 65 72 2d 63 61 63 68 65 20 6f  he pager-cache o
19a0: 62 6a 65 63 74 20 70 43 61 63 68 65 2e 20 54 68  bject pCache. Th
19b0: 69 73 20 69 73 20 0a 20 20 20 20 2a 2a 20 73 6f  is is .    ** so
19c0: 20 74 68 61 74 20 69 66 20 74 68 65 20 61 74 74   that if the att
19d0: 65 6d 70 74 20 74 6f 20 61 6c 6c 6f 63 61 74 65  empt to allocate
19e0: 20 61 20 6e 65 77 20 62 75 66 66 65 72 20 63 61   a new buffer ca
19f0: 75 73 65 73 20 74 68 65 20 74 68 65 20 0a 20 20  uses the the .  
1a00: 20 20 2a 2a 20 63 6f 6e 66 69 67 75 72 65 64 20    ** configured 
1a10: 73 6f 66 74 2d 68 65 61 70 2d 6c 69 6d 69 74 20  soft-heap-limit 
1a20: 74 6f 20 62 65 20 62 72 65 61 63 68 65 64 2c 20  to be breached, 
1a30: 69 74 20 77 69 6c 6c 20 62 65 20 70 6f 73 73 69  it will be possi
1a40: 62 6c 65 20 74 6f 0a 20 20 20 20 2a 2a 20 72 65  ble to.    ** re
1a50: 63 6c 61 69 6d 20 6d 65 6d 6f 72 79 20 66 72 6f  claim memory fro
1a60: 6d 20 74 68 69 73 20 70 61 67 65 72 2d 63 61 63  m this pager-cac
1a70: 68 65 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 70  he..    */.    p
1a80: 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78  cache1LeaveMutex
1a90: 28 29 3b 0a 20 20 20 20 70 20 3d 20 73 71 6c 69  ();.    p = sqli
1aa0: 74 65 33 4d 61 6c 6c 6f 63 28 6e 42 79 74 65 29  te3Malloc(nByte)
1ab0: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 45 6e 74  ;.    pcache1Ent
1ac0: 65 72 4d 75 74 65 78 28 29 3b 0a 20 20 20 20 69  erMutex();.    i
1ad0: 66 28 20 70 20 29 7b 0a 20 20 20 20 20 20 69 6e  f( p ){.      in
1ae0: 74 20 73 7a 20 3d 20 73 71 6c 69 74 65 33 4d 61  t sz = sqlite3Ma
1af0: 6c 6c 6f 63 53 69 7a 65 28 70 29 3b 0a 20 20 20  llocSize(p);.   
1b00: 20 20 20 73 71 6c 69 74 65 33 53 74 61 74 75 73     sqlite3Status
1b10: 41 64 64 28 53 51 4c 49 54 45 5f 53 54 41 54 55  Add(SQLITE_STATU
1b20: 53 5f 50 41 47 45 43 41 43 48 45 5f 4f 56 45 52  S_PAGECACHE_OVER
1b30: 46 4c 4f 57 2c 20 73 7a 29 3b 0a 20 20 20 20 7d  FLOW, sz);.    }
1b40: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 70 3b  .  }.  return p;
1b50: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61  .}../*.** Free a
1b60: 6e 20 61 6c 6c 6f 63 61 74 65 64 20 62 75 66 66  n allocated buff
1b70: 65 72 20 6f 62 74 61 69 6e 65 64 20 66 72 6f 6d  er obtained from
1b80: 20 70 63 61 63 68 65 31 41 6c 6c 6f 63 28 29 2e   pcache1Alloc().
1b90: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
1ba0: 70 63 61 63 68 65 31 46 72 65 65 28 76 6f 69 64  pcache1Free(void
1bb0: 20 2a 70 29 7b 0a 20 20 61 73 73 65 72 74 28 20   *p){.  assert( 
1bc0: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65  sqlite3_mutex_he
1bd0: 6c 64 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78  ld(pcache1.mutex
1be0: 29 20 29 3b 0a 20 20 69 66 28 20 70 3d 3d 30 20  ) );.  if( p==0 
1bf0: 29 20 72 65 74 75 72 6e 3b 0a 20 20 69 66 28 20  ) return;.  if( 
1c00: 70 3e 3d 70 63 61 63 68 65 31 2e 70 53 74 61 72  p>=pcache1.pStar
1c10: 74 20 26 26 20 70 3c 70 63 61 63 68 65 31 2e 70  t && p<pcache1.p
1c20: 45 6e 64 20 29 7b 0a 20 20 20 20 50 67 46 72 65  End ){.    PgFre
1c30: 65 73 6c 6f 74 20 2a 70 53 6c 6f 74 3b 0a 20 20  eslot *pSlot;.  
1c40: 20 20 73 71 6c 69 74 65 33 53 74 61 74 75 73 41    sqlite3StatusA
1c50: 64 64 28 53 51 4c 49 54 45 5f 53 54 41 54 55 53  dd(SQLITE_STATUS
1c60: 5f 50 41 47 45 43 41 43 48 45 5f 55 53 45 44 2c  _PAGECACHE_USED,
1c70: 20 2d 31 29 3b 0a 20 20 20 20 70 53 6c 6f 74 20   -1);.    pSlot 
1c80: 3d 20 28 50 67 46 72 65 65 73 6c 6f 74 2a 29 70  = (PgFreeslot*)p
1c90: 3b 0a 20 20 20 20 70 53 6c 6f 74 2d 3e 70 4e 65  ;.    pSlot->pNe
1ca0: 78 74 20 3d 20 70 63 61 63 68 65 31 2e 70 46 72  xt = pcache1.pFr
1cb0: 65 65 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e  ee;.    pcache1.
1cc0: 70 46 72 65 65 20 3d 20 70 53 6c 6f 74 3b 0a 20  pFree = pSlot;. 
1cd0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 6e 74 20   }else{.    int 
1ce0: 69 53 69 7a 65 20 3d 20 73 71 6c 69 74 65 33 4d  iSize = sqlite3M
1cf0: 61 6c 6c 6f 63 53 69 7a 65 28 70 29 3b 0a 20 20  allocSize(p);.  
1d00: 20 20 73 71 6c 69 74 65 33 53 74 61 74 75 73 41    sqlite3StatusA
1d10: 64 64 28 53 51 4c 49 54 45 5f 53 54 41 54 55 53  dd(SQLITE_STATUS
1d20: 5f 50 41 47 45 43 41 43 48 45 5f 4f 56 45 52 46  _PAGECACHE_OVERF
1d30: 4c 4f 57 2c 20 2d 69 53 69 7a 65 29 3b 0a 20 20  LOW, -iSize);.  
1d40: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
1d50: 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  );.  }.}../*.** 
1d60: 41 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 70  Allocate a new p
1d70: 61 67 65 20 6f 62 6a 65 63 74 20 69 6e 69 74 69  age object initi
1d80: 61 6c 6c 79 20 61 73 73 6f 63 69 61 74 65 64 20  ally associated 
1d90: 77 69 74 68 20 63 61 63 68 65 20 70 43 61 63 68  with cache pCach
1da0: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 50 67 48  e..*/.static PgH
1db0: 64 72 31 20 2a 70 63 61 63 68 65 31 41 6c 6c 6f  dr1 *pcache1Allo
1dc0: 63 50 61 67 65 28 50 43 61 63 68 65 31 20 2a 70  cPage(PCache1 *p
1dd0: 43 61 63 68 65 29 7b 0a 20 20 69 6e 74 20 6e 42  Cache){.  int nB
1de0: 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 50 67 48  yte = sizeof(PgH
1df0: 64 72 31 29 20 2b 20 70 43 61 63 68 65 2d 3e 73  dr1) + pCache->s
1e00: 7a 50 61 67 65 3b 0a 20 20 76 6f 69 64 20 2a 70  zPage;.  void *p
1e10: 50 67 20 3d 20 70 63 61 63 68 65 31 41 6c 6c 6f  Pg = pcache1Allo
1e20: 63 28 6e 42 79 74 65 29 3b 0a 20 20 50 67 48 64  c(nByte);.  PgHd
1e30: 72 31 20 2a 70 3b 0a 20 20 69 66 28 20 70 50 67  r1 *p;.  if( pPg
1e40: 20 29 7b 0a 20 20 20 20 70 20 3d 20 50 41 47 45   ){.    p = PAGE
1e50: 5f 54 4f 5f 50 47 48 44 52 31 28 70 43 61 63 68  _TO_PGHDR1(pCach
1e60: 65 2c 20 70 50 67 29 3b 0a 20 20 20 20 69 66 28  e, pPg);.    if(
1e70: 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61   pCache->bPurgea
1e80: 62 6c 65 20 29 7b 0a 20 20 20 20 20 20 70 63 61  ble ){.      pca
1e90: 63 68 65 31 2e 6e 43 75 72 72 65 6e 74 50 61 67  che1.nCurrentPag
1ea0: 65 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 7d 65 6c  e++;.    }.  }el
1eb0: 73 65 7b 0a 20 20 20 20 70 20 3d 20 30 3b 0a 20  se{.    p = 0;. 
1ec0: 20 7d 0a 20 20 72 65 74 75 72 6e 20 70 3b 0a 7d   }.  return p;.}
1ed0: 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61 20 70  ../*.** Free a p
1ee0: 61 67 65 20 6f 62 6a 65 63 74 20 61 6c 6c 6f 63  age object alloc
1ef0: 61 74 65 64 20 62 79 20 70 63 61 63 68 65 31 41  ated by pcache1A
1f00: 6c 6c 6f 63 50 61 67 65 28 29 2e 0a 2a 2f 0a 73  llocPage()..*/.s
1f10: 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68  tatic void pcach
1f20: 65 31 46 72 65 65 50 61 67 65 28 50 67 48 64 72  e1FreePage(PgHdr
1f30: 31 20 2a 70 29 7b 0a 20 20 69 66 28 20 70 20 29  1 *p){.  if( p )
1f40: 7b 0a 20 20 20 20 69 66 28 20 70 2d 3e 70 43 61  {.    if( p->pCa
1f50: 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20  che->bPurgeable 
1f60: 29 7b 0a 20 20 20 20 20 20 70 63 61 63 68 65 31  ){.      pcache1
1f70: 2e 6e 43 75 72 72 65 6e 74 50 61 67 65 2d 2d 3b  .nCurrentPage--;
1f80: 0a 20 20 20 20 7d 0a 20 20 20 20 70 63 61 63 68  .    }.    pcach
1f90: 65 31 46 72 65 65 28 50 47 48 44 52 31 5f 54 4f  e1Free(PGHDR1_TO
1fa0: 5f 50 41 47 45 28 70 29 29 3b 0a 20 20 7d 0a 7d  _PAGE(p));.  }.}
1fb0: 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6c 6c 6f 63 20 66  ../*.** Malloc f
1fc0: 75 6e 63 74 69 6f 6e 20 75 73 65 64 20 62 79 20  unction used by 
1fd0: 53 51 4c 69 74 65 20 74 6f 20 6f 62 74 61 69 6e  SQLite to obtain
1fe0: 20 73 70 61 63 65 20 66 72 6f 6d 20 74 68 65 20   space from the 
1ff0: 62 75 66 66 65 72 20 63 6f 6e 66 69 67 75 72 65  buffer configure
2000: 64 0a 2a 2a 20 75 73 69 6e 67 20 73 71 6c 69 74  d.** using sqlit
2010: 65 33 5f 63 6f 6e 66 69 67 28 53 51 4c 49 54 45  e3_config(SQLITE
2020: 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48  _CONFIG_PAGECACH
2030: 45 29 20 6f 70 74 69 6f 6e 2e 20 49 66 20 6e 6f  E) option. If no
2040: 20 73 75 63 68 20 62 75 66 66 65 72 0a 2a 2a 20   such buffer.** 
2050: 65 78 69 73 74 73 2c 20 74 68 69 73 20 66 75 6e  exists, this fun
2060: 63 74 69 6f 6e 20 66 61 6c 6c 73 20 62 61 63 6b  ction falls back
2070: 20 74 6f 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f   to sqlite3Mallo
2080: 63 28 29 2e 0a 2a 2f 0a 76 6f 69 64 20 2a 73 71  c()..*/.void *sq
2090: 6c 69 74 65 33 50 61 67 65 4d 61 6c 6c 6f 63 28  lite3PageMalloc(
20a0: 69 6e 74 20 73 7a 29 7b 0a 20 20 76 6f 69 64 20  int sz){.  void 
20b0: 2a 70 3b 0a 20 20 70 63 61 63 68 65 31 45 6e 74  *p;.  pcache1Ent
20c0: 65 72 4d 75 74 65 78 28 29 3b 0a 20 20 70 20 3d  erMutex();.  p =
20d0: 20 70 63 61 63 68 65 31 41 6c 6c 6f 63 28 73 7a   pcache1Alloc(sz
20e0: 29 3b 0a 20 20 70 63 61 63 68 65 31 4c 65 61 76  );.  pcache1Leav
20f0: 65 4d 75 74 65 78 28 29 3b 0a 20 20 72 65 74 75  eMutex();.  retu
2100: 72 6e 20 70 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46  rn p;.}../*.** F
2110: 72 65 65 20 61 6e 20 61 6c 6c 6f 63 61 74 65 64  ree an allocated
2120: 20 62 75 66 66 65 72 20 6f 62 74 61 69 6e 65 64   buffer obtained
2130: 20 66 72 6f 6d 20 73 71 6c 69 74 65 33 50 61 67   from sqlite3Pag
2140: 65 4d 61 6c 6c 6f 63 28 29 2e 0a 2a 2f 0a 76 6f  eMalloc()..*/.vo
2150: 69 64 20 73 71 6c 69 74 65 33 50 61 67 65 46 72  id sqlite3PageFr
2160: 65 65 28 76 6f 69 64 20 2a 70 29 7b 0a 20 20 70  ee(void *p){.  p
2170: 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78  cache1EnterMutex
2180: 28 29 3b 0a 20 20 70 63 61 63 68 65 31 46 72 65  ();.  pcache1Fre
2190: 65 28 70 29 3b 0a 20 20 70 63 61 63 68 65 31 4c  e(p);.  pcache1L
21a0: 65 61 76 65 4d 75 74 65 78 28 29 3b 0a 7d 0a 0a  eaveMutex();.}..
21b0: 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  /***************
21c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
21d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
21e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
21f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f  ***************/
2200: 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 20 47 65 6e 65 72  ./******** Gener
2210: 61 6c 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  al Implementatio
2220: 6e 20 46 75 6e 63 74 69 6f 6e 73 20 2a 2a 2a 2a  n Functions ****
2230: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2240: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2250: 2f 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75  /../*.** This fu
2260: 6e 63 74 69 6f 6e 20 69 73 20 75 73 65 64 20 74  nction is used t
2270: 6f 20 72 65 73 69 7a 65 20 74 68 65 20 68 61 73  o resize the has
2280: 68 20 74 61 62 6c 65 20 75 73 65 64 20 62 79 20  h table used by 
2290: 74 68 65 20 63 61 63 68 65 20 70 61 73 73 65 64  the cache passed
22a0: 0a 2a 2a 20 61 73 20 74 68 65 20 66 69 72 73 74  .** as the first
22b0: 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a   argument..**.**
22c0: 20 54 68 65 20 67 6c 6f 62 61 6c 20 6d 75 74 65   The global mute
22d0: 78 20 6d 75 73 74 20 62 65 20 68 65 6c 64 20 77  x must be held w
22e0: 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f  hen this functio
22f0: 6e 20 69 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f 0a  n is called..*/.
2300: 73 74 61 74 69 63 20 69 6e 74 20 70 63 61 63 68  static int pcach
2310: 65 31 52 65 73 69 7a 65 48 61 73 68 28 50 43 61  e1ResizeHash(PCa
2320: 63 68 65 31 20 2a 70 29 7b 0a 20 20 50 67 48 64  che1 *p){.  PgHd
2330: 72 31 20 2a 2a 61 70 4e 65 77 3b 0a 20 20 75 6e  r1 **apNew;.  un
2340: 73 69 67 6e 65 64 20 69 6e 74 20 6e 4e 65 77 3b  signed int nNew;
2350: 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  .  unsigned int 
2360: 69 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 73 71  i;..  assert( sq
2370: 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64  lite3_mutex_held
2380: 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29 20  (pcache1.mutex) 
2390: 29 3b 0a 0a 20 20 6e 4e 65 77 20 3d 20 70 2d 3e  );..  nNew = p->
23a0: 6e 48 61 73 68 2a 32 3b 0a 20 20 69 66 28 20 6e  nHash*2;.  if( n
23b0: 4e 65 77 3c 32 35 36 20 29 7b 0a 20 20 20 20 6e  New<256 ){.    n
23c0: 4e 65 77 20 3d 20 32 35 36 3b 0a 20 20 7d 0a 0a  New = 256;.  }..
23d0: 20 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75    pcache1LeaveMu
23e0: 74 65 78 28 29 3b 0a 20 20 69 66 28 20 70 2d 3e  tex();.  if( p->
23f0: 6e 48 61 73 68 20 29 7b 20 73 71 6c 69 74 65 33  nHash ){ sqlite3
2400: 42 65 67 69 6e 42 65 6e 69 67 6e 4d 61 6c 6c 6f  BeginBenignMallo
2410: 63 28 29 3b 20 7d 0a 20 20 61 70 4e 65 77 20 3d  c(); }.  apNew =
2420: 20 28 50 67 48 64 72 31 20 2a 2a 29 73 71 6c 69   (PgHdr1 **)sqli
2430: 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f  te3_malloc(sizeo
2440: 66 28 50 67 48 64 72 31 20 2a 29 2a 6e 4e 65 77  f(PgHdr1 *)*nNew
2450: 29 3b 0a 20 20 69 66 28 20 70 2d 3e 6e 48 61 73  );.  if( p->nHas
2460: 68 20 29 7b 20 73 71 6c 69 74 65 33 45 6e 64 42  h ){ sqlite3EndB
2470: 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 20 7d  enignMalloc(); }
2480: 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d  .  pcache1EnterM
2490: 75 74 65 78 28 29 3b 0a 20 20 69 66 28 20 61 70  utex();.  if( ap
24a0: 4e 65 77 20 29 7b 0a 20 20 20 20 6d 65 6d 73 65  New ){.    memse
24b0: 74 28 61 70 4e 65 77 2c 20 30 2c 20 73 69 7a 65  t(apNew, 0, size
24c0: 6f 66 28 50 67 48 64 72 31 20 2a 29 2a 6e 4e 65  of(PgHdr1 *)*nNe
24d0: 77 29 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b  w);.    for(i=0;
24e0: 20 69 3c 70 2d 3e 6e 48 61 73 68 3b 20 69 2b 2b   i<p->nHash; i++
24f0: 29 7b 0a 20 20 20 20 20 20 50 67 48 64 72 31 20  ){.      PgHdr1 
2500: 2a 70 50 61 67 65 3b 0a 20 20 20 20 20 20 50 67  *pPage;.      Pg
2510: 48 64 72 31 20 2a 70 4e 65 78 74 20 3d 20 70 2d  Hdr1 *pNext = p-
2520: 3e 61 70 48 61 73 68 5b 69 5d 3b 0a 20 20 20 20  >apHash[i];.    
2530: 20 20 77 68 69 6c 65 28 20 28 70 50 61 67 65 20    while( (pPage 
2540: 3d 20 70 4e 65 78 74 29 21 3d 30 20 29 7b 0a 20  = pNext)!=0 ){. 
2550: 20 20 20 20 20 20 20 75 6e 73 69 67 6e 65 64 20         unsigned 
2560: 69 6e 74 20 68 20 3d 20 70 50 61 67 65 2d 3e 69  int h = pPage->i
2570: 4b 65 79 20 25 20 6e 4e 65 77 3b 0a 20 20 20 20  Key % nNew;.    
2580: 20 20 20 20 70 4e 65 78 74 20 3d 20 70 50 61 67      pNext = pPag
2590: 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20  e->pNext;.      
25a0: 20 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 20 3d    pPage->pNext =
25b0: 20 61 70 4e 65 77 5b 68 5d 3b 0a 20 20 20 20 20   apNew[h];.     
25c0: 20 20 20 61 70 4e 65 77 5b 68 5d 20 3d 20 70 50     apNew[h] = pP
25d0: 61 67 65 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  age;.      }.   
25e0: 20 7d 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66   }.    sqlite3_f
25f0: 72 65 65 28 70 2d 3e 61 70 48 61 73 68 29 3b 0a  ree(p->apHash);.
2600: 20 20 20 20 70 2d 3e 61 70 48 61 73 68 20 3d 20      p->apHash = 
2610: 61 70 4e 65 77 3b 0a 20 20 20 20 70 2d 3e 6e 48  apNew;.    p->nH
2620: 61 73 68 20 3d 20 6e 4e 65 77 3b 0a 20 20 7d 0a  ash = nNew;.  }.
2630: 0a 20 20 72 65 74 75 72 6e 20 28 70 2d 3e 61 70  .  return (p->ap
2640: 48 61 73 68 20 3f 20 53 51 4c 49 54 45 5f 4f 4b  Hash ? SQLITE_OK
2650: 20 3a 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 29   : SQLITE_NOMEM)
2660: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  ;.}../*.** This 
2670: 66 75 6e 63 74 69 6f 6e 20 69 73 20 75 73 65 64  function is used
2680: 20 69 6e 74 65 72 6e 61 6c 6c 79 20 74 6f 20 72   internally to r
2690: 65 6d 6f 76 65 20 74 68 65 20 70 61 67 65 20 70  emove the page p
26a0: 50 61 67 65 20 66 72 6f 6d 20 74 68 65 20 0a 2a  Page from the .*
26b0: 2a 20 67 6c 6f 62 61 6c 20 4c 52 55 20 6c 69 73  * global LRU lis
26c0: 74 2c 20 69 66 20 69 73 20 70 61 72 74 20 6f 66  t, if is part of
26d0: 20 69 74 2e 20 49 66 20 70 50 61 67 65 20 69 73   it. If pPage is
26e0: 20 6e 6f 74 20 70 61 72 74 20 6f 66 20 74 68 65   not part of the
26f0: 20 67 6c 6f 62 61 6c 0a 2a 2a 20 4c 52 55 20 6c   global.** LRU l
2700: 69 73 74 2c 20 74 68 65 6e 20 74 68 69 73 20 66  ist, then this f
2710: 75 6e 63 74 69 6f 6e 20 69 73 20 61 20 6e 6f 2d  unction is a no-
2720: 6f 70 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 67 6c  op..**.** The gl
2730: 6f 62 61 6c 20 6d 75 74 65 78 20 6d 75 73 74 20  obal mutex must 
2740: 62 65 20 68 65 6c 64 20 77 68 65 6e 20 74 68 69  be held when thi
2750: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61  s function is ca
2760: 6c 6c 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  lled..*/.static 
2770: 76 6f 69 64 20 70 63 61 63 68 65 31 50 69 6e 50  void pcache1PinP
2780: 61 67 65 28 50 67 48 64 72 31 20 2a 70 50 61 67  age(PgHdr1 *pPag
2790: 65 29 7b 0a 20 20 61 73 73 65 72 74 28 20 73 71  e){.  assert( sq
27a0: 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64  lite3_mutex_held
27b0: 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29 20  (pcache1.mutex) 
27c0: 29 3b 0a 20 20 69 66 28 20 70 50 61 67 65 20 26  );.  if( pPage &
27d0: 26 20 28 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65  & (pPage->pLruNe
27e0: 78 74 20 7c 7c 20 70 50 61 67 65 3d 3d 70 63 61  xt || pPage==pca
27f0: 63 68 65 31 2e 70 4c 72 75 54 61 69 6c 29 20 29  che1.pLruTail) )
2800: 7b 0a 20 20 20 20 69 66 28 20 70 50 61 67 65 2d  {.    if( pPage-
2810: 3e 70 4c 72 75 50 72 65 76 20 29 7b 0a 20 20 20  >pLruPrev ){.   
2820: 20 20 20 70 50 61 67 65 2d 3e 70 4c 72 75 50 72     pPage->pLruPr
2830: 65 76 2d 3e 70 4c 72 75 4e 65 78 74 20 3d 20 70  ev->pLruNext = p
2840: 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 3b 0a  Page->pLruNext;.
2850: 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70 50      }.    if( pP
2860: 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 20 29 7b  age->pLruNext ){
2870: 0a 20 20 20 20 20 20 70 50 61 67 65 2d 3e 70 4c  .      pPage->pL
2880: 72 75 4e 65 78 74 2d 3e 70 4c 72 75 50 72 65 76  ruNext->pLruPrev
2890: 20 3d 20 70 50 61 67 65 2d 3e 70 4c 72 75 50 72   = pPage->pLruPr
28a0: 65 76 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66  ev;.    }.    if
28b0: 28 20 70 63 61 63 68 65 31 2e 70 4c 72 75 48 65  ( pcache1.pLruHe
28c0: 61 64 3d 3d 70 50 61 67 65 20 29 7b 0a 20 20 20  ad==pPage ){.   
28d0: 20 20 20 70 63 61 63 68 65 31 2e 70 4c 72 75 48     pcache1.pLruH
28e0: 65 61 64 20 3d 20 70 50 61 67 65 2d 3e 70 4c 72  ead = pPage->pLr
28f0: 75 4e 65 78 74 3b 0a 20 20 20 20 7d 0a 20 20 20  uNext;.    }.   
2900: 20 69 66 28 20 70 63 61 63 68 65 31 2e 70 4c 72   if( pcache1.pLr
2910: 75 54 61 69 6c 3d 3d 70 50 61 67 65 20 29 7b 0a  uTail==pPage ){.
2920: 20 20 20 20 20 20 70 63 61 63 68 65 31 2e 70 4c        pcache1.pL
2930: 72 75 54 61 69 6c 20 3d 20 70 50 61 67 65 2d 3e  ruTail = pPage->
2940: 70 4c 72 75 50 72 65 76 3b 0a 20 20 20 20 7d 0a  pLruPrev;.    }.
2950: 20 20 20 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e      pPage->pLruN
2960: 65 78 74 20 3d 20 30 3b 0a 20 20 20 20 70 50 61  ext = 0;.    pPa
2970: 67 65 2d 3e 70 4c 72 75 50 72 65 76 20 3d 20 30  ge->pLruPrev = 0
2980: 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 43 61  ;.    pPage->pCa
2990: 63 68 65 2d 3e 6e 52 65 63 79 63 6c 61 62 6c 65  che->nRecyclable
29a0: 2d 2d 3b 0a 20 20 7d 0a 7d 0a 0a 0a 2f 2a 0a 2a  --;.  }.}.../*.*
29b0: 2a 20 52 65 6d 6f 76 65 20 74 68 65 20 70 61 67  * Remove the pag
29c0: 65 20 73 75 70 70 6c 69 65 64 20 61 73 20 61 6e  e supplied as an
29d0: 20 61 72 67 75 6d 65 6e 74 20 66 72 6f 6d 20 74   argument from t
29e0: 68 65 20 68 61 73 68 20 74 61 62 6c 65 20 0a 2a  he hash table .*
29f0: 2a 20 28 50 43 61 63 68 65 31 2e 61 70 48 61 73  * (PCache1.apHas
2a00: 68 20 73 74 72 75 63 74 75 72 65 29 20 74 68 61  h structure) tha
2a10: 74 20 69 74 20 69 73 20 63 75 72 72 65 6e 74 6c  t it is currentl
2a20: 79 20 73 74 6f 72 65 64 20 69 6e 2e 0a 2a 2a 0a  y stored in..**.
2a30: 2a 2a 20 54 68 65 20 67 6c 6f 62 61 6c 20 6d 75  ** The global mu
2a40: 74 65 78 20 6d 75 73 74 20 62 65 20 68 65 6c 64  tex must be held
2a50: 20 77 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74   when this funct
2a60: 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 2e 0a 2a  ion is called..*
2a70: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63  /.static void pc
2a80: 61 63 68 65 31 52 65 6d 6f 76 65 46 72 6f 6d 48  ache1RemoveFromH
2a90: 61 73 68 28 50 67 48 64 72 31 20 2a 70 50 61 67  ash(PgHdr1 *pPag
2aa0: 65 29 7b 0a 20 20 75 6e 73 69 67 6e 65 64 20 69  e){.  unsigned i
2ab0: 6e 74 20 68 3b 0a 20 20 50 43 61 63 68 65 31 20  nt h;.  PCache1 
2ac0: 2a 70 43 61 63 68 65 20 3d 20 70 50 61 67 65 2d  *pCache = pPage-
2ad0: 3e 70 43 61 63 68 65 3b 0a 20 20 50 67 48 64 72  >pCache;.  PgHdr
2ae0: 31 20 2a 2a 70 70 3b 0a 0a 20 20 68 20 3d 20 70  1 **pp;..  h = p
2af0: 50 61 67 65 2d 3e 69 4b 65 79 20 25 20 70 43 61  Page->iKey % pCa
2b00: 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 66 6f  che->nHash;.  fo
2b10: 72 28 70 70 3d 26 70 43 61 63 68 65 2d 3e 61 70  r(pp=&pCache->ap
2b20: 48 61 73 68 5b 68 5d 3b 20 28 2a 70 70 29 21 3d  Hash[h]; (*pp)!=
2b30: 70 50 61 67 65 3b 20 70 70 3d 26 28 2a 70 70 29  pPage; pp=&(*pp)
2b40: 2d 3e 70 4e 65 78 74 29 3b 0a 20 20 2a 70 70 20  ->pNext);.  *pp 
2b50: 3d 20 28 2a 70 70 29 2d 3e 70 4e 65 78 74 3b 0a  = (*pp)->pNext;.
2b60: 0a 20 20 70 43 61 63 68 65 2d 3e 6e 50 61 67 65  .  pCache->nPage
2b70: 2d 2d 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20  --;.}../*.** If 
2b80: 74 68 65 72 65 20 61 72 65 20 63 75 72 72 65 6e  there are curren
2b90: 74 6c 79 20 6d 6f 72 65 20 74 68 61 6e 20 70 63  tly more than pc
2ba0: 61 63 68 65 2e 6e 4d 61 78 50 61 67 65 20 70 61  ache.nMaxPage pa
2bb0: 67 65 73 20 61 6c 6c 6f 63 61 74 65 64 2c 20 74  ges allocated, t
2bc0: 72 79 0a 2a 2a 20 74 6f 20 72 65 63 79 63 6c 65  ry.** to recycle
2bd0: 20 70 61 67 65 73 20 74 6f 20 72 65 64 75 63 65   pages to reduce
2be0: 20 74 68 65 20 6e 75 6d 62 65 72 20 61 6c 6c 6f   the number allo
2bf0: 63 61 74 65 64 20 74 6f 20 70 63 61 63 68 65 2e  cated to pcache.
2c00: 6e 4d 61 78 50 61 67 65 2e 0a 2a 2f 0a 73 74 61  nMaxPage..*/.sta
2c10: 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 31  tic void pcache1
2c20: 45 6e 66 6f 72 63 65 4d 61 78 50 61 67 65 28 76  EnforceMaxPage(v
2c30: 6f 69 64 29 7b 0a 20 20 61 73 73 65 72 74 28 20  oid){.  assert( 
2c40: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65  sqlite3_mutex_he
2c50: 6c 64 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78  ld(pcache1.mutex
2c60: 29 20 29 3b 0a 20 20 77 68 69 6c 65 28 20 70 63  ) );.  while( pc
2c70: 61 63 68 65 31 2e 6e 43 75 72 72 65 6e 74 50 61  ache1.nCurrentPa
2c80: 67 65 3e 70 63 61 63 68 65 31 2e 6e 4d 61 78 50  ge>pcache1.nMaxP
2c90: 61 67 65 20 26 26 20 70 63 61 63 68 65 31 2e 70  age && pcache1.p
2ca0: 4c 72 75 54 61 69 6c 20 29 7b 0a 20 20 20 20 50  LruTail ){.    P
2cb0: 67 48 64 72 31 20 2a 70 20 3d 20 70 63 61 63 68  gHdr1 *p = pcach
2cc0: 65 31 2e 70 4c 72 75 54 61 69 6c 3b 0a 20 20 20  e1.pLruTail;.   
2cd0: 20 70 63 61 63 68 65 31 50 69 6e 50 61 67 65 28   pcache1PinPage(
2ce0: 70 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31 52  p);.    pcache1R
2cf0: 65 6d 6f 76 65 46 72 6f 6d 48 61 73 68 28 70 29  emoveFromHash(p)
2d00: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 46 72 65  ;.    pcache1Fre
2d10: 65 50 61 67 65 28 70 29 3b 0a 20 20 7d 0a 7d 0a  ePage(p);.  }.}.
2d20: 0a 2f 2a 0a 2a 2a 20 44 69 73 63 61 72 64 20 61  ./*.** Discard a
2d30: 6c 6c 20 70 61 67 65 73 20 66 72 6f 6d 20 63 61  ll pages from ca
2d40: 63 68 65 20 70 43 61 63 68 65 20 77 69 74 68 20  che pCache with 
2d50: 61 20 70 61 67 65 20 6e 75 6d 62 65 72 20 28 6b  a page number (k
2d60: 65 79 20 76 61 6c 75 65 29 20 0a 2a 2a 20 67 72  ey value) .** gr
2d70: 65 61 74 65 72 20 74 68 61 6e 20 6f 72 20 65 71  eater than or eq
2d80: 75 61 6c 20 74 6f 20 69 4c 69 6d 69 74 2e 20 41  ual to iLimit. A
2d90: 6e 79 20 70 69 6e 6e 65 64 20 70 61 67 65 73 20  ny pinned pages 
2da0: 74 68 61 74 20 6d 65 65 74 20 74 68 69 73 20 0a  that meet this .
2db0: 2a 2a 20 63 72 69 74 65 72 69 61 20 61 72 65 20  ** criteria are 
2dc0: 75 6e 70 69 6e 6e 65 64 20 62 65 66 6f 72 65 20  unpinned before 
2dd0: 74 68 65 79 20 61 72 65 20 64 69 73 63 61 72 64  they are discard
2de0: 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 67 6c  ed..**.** The gl
2df0: 6f 62 61 6c 20 6d 75 74 65 78 20 6d 75 73 74 20  obal mutex must 
2e00: 62 65 20 68 65 6c 64 20 77 68 65 6e 20 74 68 69  be held when thi
2e10: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61  s function is ca
2e20: 6c 6c 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  lled..*/.static 
2e30: 76 6f 69 64 20 70 63 61 63 68 65 31 54 72 75 6e  void pcache1Trun
2e40: 63 61 74 65 55 6e 73 61 66 65 28 0a 20 20 50 43  cateUnsafe(.  PC
2e50: 61 63 68 65 31 20 2a 70 43 61 63 68 65 2c 20 0a  ache1 *pCache, .
2e60: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69    unsigned int i
2e70: 4c 69 6d 69 74 20 0a 29 7b 0a 20 20 54 45 53 54  Limit .){.  TEST
2e80: 4f 4e 4c 59 28 20 75 6e 73 69 67 6e 65 64 20 69  ONLY( unsigned i
2e90: 6e 74 20 6e 50 61 67 65 20 3d 20 30 3b 20 29 20  nt nPage = 0; ) 
2ea0: 20 20 20 20 20 2f 2a 20 55 73 65 64 20 74 6f 20       /* Used to 
2eb0: 61 73 73 65 72 74 20 70 43 61 63 68 65 2d 3e 6e  assert pCache->n
2ec0: 50 61 67 65 20 69 73 20 63 6f 72 72 65 63 74 20  Page is correct 
2ed0: 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e  */.  unsigned in
2ee0: 74 20 68 3b 0a 20 20 61 73 73 65 72 74 28 20 73  t h;.  assert( s
2ef0: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c  qlite3_mutex_hel
2f00: 64 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29  d(pcache1.mutex)
2f10: 20 29 3b 0a 20 20 66 6f 72 28 68 3d 30 3b 20 68   );.  for(h=0; h
2f20: 3c 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3b 20  <pCache->nHash; 
2f30: 68 2b 2b 29 7b 0a 20 20 20 20 50 67 48 64 72 31  h++){.    PgHdr1
2f40: 20 2a 2a 70 70 20 3d 20 26 70 43 61 63 68 65 2d   **pp = &pCache-
2f50: 3e 61 70 48 61 73 68 5b 68 5d 3b 20 0a 20 20 20  >apHash[h]; .   
2f60: 20 50 67 48 64 72 31 20 2a 70 50 61 67 65 3b 0a   PgHdr1 *pPage;.
2f70: 20 20 20 20 77 68 69 6c 65 28 20 28 70 50 61 67      while( (pPag
2f80: 65 20 3d 20 2a 70 70 29 21 3d 30 20 29 7b 0a 20  e = *pp)!=0 ){. 
2f90: 20 20 20 20 20 69 66 28 20 70 50 61 67 65 2d 3e       if( pPage->
2fa0: 69 4b 65 79 3e 3d 69 4c 69 6d 69 74 20 29 7b 0a  iKey>=iLimit ){.
2fb0: 20 20 20 20 20 20 20 20 70 43 61 63 68 65 2d 3e          pCache->
2fc0: 6e 50 61 67 65 2d 2d 3b 0a 20 20 20 20 20 20 20  nPage--;.       
2fd0: 20 2a 70 70 20 3d 20 70 50 61 67 65 2d 3e 70 4e   *pp = pPage->pN
2fe0: 65 78 74 3b 0a 20 20 20 20 20 20 20 20 70 63 61  ext;.        pca
2ff0: 63 68 65 31 50 69 6e 50 61 67 65 28 70 50 61 67  che1PinPage(pPag
3000: 65 29 3b 0a 20 20 20 20 20 20 20 20 70 63 61 63  e);.        pcac
3010: 68 65 31 46 72 65 65 50 61 67 65 28 70 50 61 67  he1FreePage(pPag
3020: 65 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b  e);.      }else{
3030: 0a 20 20 20 20 20 20 20 20 70 70 20 3d 20 26 70  .        pp = &p
3040: 50 61 67 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20  Page->pNext;.   
3050: 20 20 20 20 20 54 45 53 54 4f 4e 4c 59 28 20 6e       TESTONLY( n
3060: 50 61 67 65 2b 2b 3b 20 29 0a 20 20 20 20 20 20  Page++; ).      
3070: 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 61 73  }.    }.  }.  as
3080: 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e 6e 50  sert( pCache->nP
3090: 61 67 65 3d 3d 6e 50 61 67 65 20 29 3b 0a 7d 0a  age==nPage );.}.
30a0: 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ./**************
30b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
30c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
30d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
30e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
30f0: 2f 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 20 73 71 6c 69  /./******** sqli
3100: 74 65 33 5f 70 63 61 63 68 65 20 4d 65 74 68 6f  te3_pcache Metho
3110: 64 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ds *************
3120: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3140: 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d  */../*.** Implem
3150: 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20  entation of the 
3160: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78  sqlite3_pcache.x
3170: 49 6e 69 74 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a  Init method..*/.
3180: 73 74 61 74 69 63 20 69 6e 74 20 70 63 61 63 68  static int pcach
3190: 65 31 49 6e 69 74 28 76 6f 69 64 20 2a 4e 6f 74  e1Init(void *Not
31a0: 55 73 65 64 29 7b 0a 20 20 55 4e 55 53 45 44 5f  Used){.  UNUSED_
31b0: 50 41 52 41 4d 45 54 45 52 28 4e 6f 74 55 73 65  PARAMETER(NotUse
31c0: 64 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 63  d);.  assert( pc
31d0: 61 63 68 65 31 2e 69 73 49 6e 69 74 3d 3d 30 20  ache1.isInit==0 
31e0: 29 3b 0a 20 20 6d 65 6d 73 65 74 28 26 70 63 61  );.  memset(&pca
31f0: 63 68 65 31 2c 20 30 2c 20 73 69 7a 65 6f 66 28  che1, 0, sizeof(
3200: 70 63 61 63 68 65 31 29 29 3b 0a 20 20 69 66 28  pcache1));.  if(
3210: 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f   sqlite3GlobalCo
3220: 6e 66 69 67 2e 62 43 6f 72 65 4d 75 74 65 78 20  nfig.bCoreMutex 
3230: 29 7b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 6d  ){.    pcache1.m
3240: 75 74 65 78 20 3d 20 73 71 6c 69 74 65 33 5f 6d  utex = sqlite3_m
3250: 75 74 65 78 5f 61 6c 6c 6f 63 28 53 51 4c 49 54  utex_alloc(SQLIT
3260: 45 5f 4d 55 54 45 58 5f 53 54 41 54 49 43 5f 4c  E_MUTEX_STATIC_L
3270: 52 55 29 3b 0a 20 20 7d 0a 20 20 70 63 61 63 68  RU);.  }.  pcach
3280: 65 31 2e 69 73 49 6e 69 74 20 3d 20 31 3b 0a 20  e1.isInit = 1;. 
3290: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
32a0: 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c  K;.}../*.** Impl
32b0: 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68  ementation of th
32c0: 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  e sqlite3_pcache
32d0: 2e 78 53 68 75 74 64 6f 77 6e 20 6d 65 74 68 6f  .xShutdown metho
32e0: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  d..*/.static voi
32f0: 64 20 70 63 61 63 68 65 31 53 68 75 74 64 6f 77  d pcache1Shutdow
3300: 6e 28 76 6f 69 64 20 2a 4e 6f 74 55 73 65 64 29  n(void *NotUsed)
3310: 7b 0a 20 20 55 4e 55 53 45 44 5f 50 41 52 41 4d  {.  UNUSED_PARAM
3320: 45 54 45 52 28 4e 6f 74 55 73 65 64 29 3b 0a 20  ETER(NotUsed);. 
3330: 20 61 73 73 65 72 74 28 20 70 63 61 63 68 65 31   assert( pcache1
3340: 2e 69 73 49 6e 69 74 21 3d 30 20 29 3b 0a 20 20  .isInit!=0 );.  
3350: 6d 65 6d 73 65 74 28 26 70 63 61 63 68 65 31 2c  memset(&pcache1,
3360: 20 30 2c 20 73 69 7a 65 6f 66 28 70 63 61 63 68   0, sizeof(pcach
3370: 65 31 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49  e1));.}../*.** I
3380: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66  mplementation of
3390: 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61   the sqlite3_pca
33a0: 63 68 65 2e 78 43 72 65 61 74 65 20 6d 65 74 68  che.xCreate meth
33b0: 6f 64 2e 0a 2a 2a 0a 2a 2a 20 41 6c 6c 6f 63 61  od..**.** Alloca
33c0: 74 65 20 61 20 6e 65 77 20 63 61 63 68 65 2e 0a  te a new cache..
33d0: 2a 2f 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65  */.static sqlite
33e0: 33 5f 70 63 61 63 68 65 20 2a 70 63 61 63 68 65  3_pcache *pcache
33f0: 31 43 72 65 61 74 65 28 69 6e 74 20 73 7a 50 61  1Create(int szPa
3400: 67 65 2c 20 69 6e 74 20 62 50 75 72 67 65 61 62  ge, int bPurgeab
3410: 6c 65 29 7b 0a 20 20 50 43 61 63 68 65 31 20 2a  le){.  PCache1 *
3420: 70 43 61 63 68 65 3b 0a 0a 20 20 70 43 61 63 68  pCache;..  pCach
3430: 65 20 3d 20 28 50 43 61 63 68 65 31 20 2a 29 73  e = (PCache1 *)s
3440: 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69  qlite3_malloc(si
3450: 7a 65 6f 66 28 50 43 61 63 68 65 31 29 29 3b 0a  zeof(PCache1));.
3460: 20 20 69 66 28 20 70 43 61 63 68 65 20 29 7b 0a    if( pCache ){.
3470: 20 20 20 20 6d 65 6d 73 65 74 28 70 43 61 63 68      memset(pCach
3480: 65 2c 20 30 2c 20 73 69 7a 65 6f 66 28 50 43 61  e, 0, sizeof(PCa
3490: 63 68 65 31 29 29 3b 0a 20 20 20 20 70 43 61 63  che1));.    pCac
34a0: 68 65 2d 3e 73 7a 50 61 67 65 20 3d 20 73 7a 50  he->szPage = szP
34b0: 61 67 65 3b 0a 20 20 20 20 70 43 61 63 68 65 2d  age;.    pCache-
34c0: 3e 62 50 75 72 67 65 61 62 6c 65 20 3d 20 28 62  >bPurgeable = (b
34d0: 50 75 72 67 65 61 62 6c 65 20 3f 20 31 20 3a 20  Purgeable ? 1 : 
34e0: 30 29 3b 0a 20 20 20 20 69 66 28 20 62 50 75 72  0);.    if( bPur
34f0: 67 65 61 62 6c 65 20 29 7b 0a 20 20 20 20 20 20  geable ){.      
3500: 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 20 3d 20 31  pCache->nMin = 1
3510: 30 3b 0a 20 20 20 20 20 20 70 63 61 63 68 65 31  0;.      pcache1
3520: 45 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a 20 20  EnterMutex();.  
3530: 20 20 20 20 70 63 61 63 68 65 31 2e 6e 4d 69 6e      pcache1.nMin
3540: 50 61 67 65 20 2b 3d 20 70 43 61 63 68 65 2d 3e  Page += pCache->
3550: 6e 4d 69 6e 3b 0a 20 20 20 20 20 20 70 63 61 63  nMin;.      pcac
3560: 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 29 3b  he1LeaveMutex();
3570: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74  .    }.  }.  ret
3580: 75 72 6e 20 28 73 71 6c 69 74 65 33 5f 70 63 61  urn (sqlite3_pca
3590: 63 68 65 20 2a 29 70 43 61 63 68 65 3b 0a 7d 0a  che *)pCache;.}.
35a0: 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74  ./*.** Implement
35b0: 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c  ation of the sql
35c0: 69 74 65 33 5f 70 63 61 63 68 65 2e 78 43 61 63  ite3_pcache.xCac
35d0: 68 65 73 69 7a 65 20 6d 65 74 68 6f 64 2e 20 0a  hesize method. .
35e0: 2a 2a 0a 2a 2a 20 43 6f 6e 66 69 67 75 72 65 20  **.** Configure 
35f0: 74 68 65 20 63 61 63 68 65 5f 73 69 7a 65 20 6c  the cache_size l
3600: 69 6d 69 74 20 66 6f 72 20 61 20 63 61 63 68 65  imit for a cache
3610: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
3620: 20 70 63 61 63 68 65 31 43 61 63 68 65 73 69 7a   pcache1Cachesiz
3630: 65 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  e(sqlite3_pcache
3640: 20 2a 70 2c 20 69 6e 74 20 6e 4d 61 78 29 7b 0a   *p, int nMax){.
3650: 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68    PCache1 *pCach
3660: 65 20 3d 20 28 50 43 61 63 68 65 31 20 2a 29 70  e = (PCache1 *)p
3670: 3b 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e  ;.  if( pCache->
3680: 62 50 75 72 67 65 61 62 6c 65 20 29 7b 0a 20 20  bPurgeable ){.  
3690: 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75    pcache1EnterMu
36a0: 74 65 78 28 29 3b 0a 20 20 20 20 70 63 61 63 68  tex();.    pcach
36b0: 65 31 2e 6e 4d 61 78 50 61 67 65 20 2b 3d 20 28  e1.nMaxPage += (
36c0: 6e 4d 61 78 20 2d 20 70 43 61 63 68 65 2d 3e 6e  nMax - pCache->n
36d0: 4d 61 78 29 3b 0a 20 20 20 20 70 43 61 63 68 65  Max);.    pCache
36e0: 2d 3e 6e 4d 61 78 20 3d 20 6e 4d 61 78 3b 0a 20  ->nMax = nMax;. 
36f0: 20 20 20 70 63 61 63 68 65 31 45 6e 66 6f 72 63     pcache1Enforc
3700: 65 4d 61 78 50 61 67 65 28 29 3b 0a 20 20 20 20  eMaxPage();.    
3710: 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65  pcache1LeaveMute
3720: 78 28 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a  x();.  }.}../*.*
3730: 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  * Implementation
3740: 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f   of the sqlite3_
3750: 70 63 61 63 68 65 2e 78 50 61 67 65 63 6f 75 6e  pcache.xPagecoun
3760: 74 20 6d 65 74 68 6f 64 2e 20 0a 2a 2f 0a 73 74  t method. .*/.st
3770: 61 74 69 63 20 69 6e 74 20 70 63 61 63 68 65 31  atic int pcache1
3780: 50 61 67 65 63 6f 75 6e 74 28 73 71 6c 69 74 65  Pagecount(sqlite
3790: 33 5f 70 63 61 63 68 65 20 2a 70 29 7b 0a 20 20  3_pcache *p){.  
37a0: 69 6e 74 20 6e 3b 0a 20 20 70 63 61 63 68 65 31  int n;.  pcache1
37b0: 45 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a 20 20  EnterMutex();.  
37c0: 6e 20 3d 20 28 28 50 43 61 63 68 65 31 20 2a 29  n = ((PCache1 *)
37d0: 70 29 2d 3e 6e 50 61 67 65 3b 0a 20 20 70 63 61  p)->nPage;.  pca
37e0: 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 29  che1LeaveMutex()
37f0: 3b 0a 20 20 72 65 74 75 72 6e 20 6e 3b 0a 7d 0a  ;.  return n;.}.
3800: 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74  ./*.** Implement
3810: 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c  ation of the sql
3820: 69 74 65 33 5f 70 63 61 63 68 65 2e 78 46 65 74  ite3_pcache.xFet
3830: 63 68 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a  ch method. .**.*
3840: 2a 20 46 65 74 63 68 20 61 20 70 61 67 65 20 62  * Fetch a page b
3850: 79 20 6b 65 79 20 76 61 6c 75 65 2e 0a 2a 2a 0a  y key value..**.
3860: 2a 2a 20 57 68 65 74 68 65 72 20 6f 72 20 6e 6f  ** Whether or no
3870: 74 20 61 20 6e 65 77 20 70 61 67 65 20 6d 61 79  t a new page may
3880: 20 62 65 20 61 6c 6c 6f 63 61 74 65 64 20 62 79   be allocated by
3890: 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 64   this function d
38a0: 65 70 65 6e 64 73 20 6f 6e 0a 2a 2a 20 74 68 65  epends on.** the
38b0: 20 76 61 6c 75 65 20 6f 66 20 74 68 65 20 63 72   value of the cr
38c0: 65 61 74 65 46 6c 61 67 20 61 72 67 75 6d 65 6e  eateFlag argumen
38d0: 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 72 65 20 61  t..**.** There a
38e0: 72 65 20 74 68 72 65 65 20 64 69 66 66 65 72 65  re three differe
38f0: 6e 74 20 61 70 70 72 6f 61 63 68 65 73 20 74 6f  nt approaches to
3900: 20 6f 62 74 61 69 6e 69 6e 67 20 73 70 61 63 65   obtaining space
3910: 20 66 6f 72 20 61 20 70 61 67 65 2c 0a 2a 2a 20   for a page,.** 
3920: 64 65 70 65 6e 64 69 6e 67 20 6f 6e 20 74 68 65  depending on the
3930: 20 76 61 6c 75 65 20 6f 66 20 70 61 72 61 6d 65   value of parame
3940: 74 65 72 20 63 72 65 61 74 65 46 6c 61 67 20 28  ter createFlag (
3950: 77 68 69 63 68 20 6d 61 79 20 62 65 20 30 2c 20  which may be 0, 
3960: 31 20 6f 72 20 32 29 2e 0a 2a 2a 0a 2a 2a 20 20  1 or 2)..**.**  
3970: 20 31 2e 20 52 65 67 61 72 64 6c 65 73 73 20 6f   1. Regardless o
3980: 66 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20 63  f the value of c
3990: 72 65 61 74 65 46 6c 61 67 2c 20 74 68 65 20 63  reateFlag, the c
39a0: 61 63 68 65 20 69 73 20 73 65 61 72 63 68 65 64  ache is searched
39b0: 20 66 6f 72 20 61 20 0a 2a 2a 20 20 20 20 20 20   for a .**      
39c0: 63 6f 70 79 20 6f 66 20 74 68 65 20 72 65 71 75  copy of the requ
39d0: 65 73 74 65 64 20 70 61 67 65 2e 20 49 66 20 6f  ested page. If o
39e0: 6e 65 20 69 73 20 66 6f 75 6e 64 2c 20 69 74 20  ne is found, it 
39f0: 69 73 20 72 65 74 75 72 6e 65 64 2e 0a 2a 2a 0a  is returned..**.
3a00: 2a 2a 20 20 20 32 2e 20 49 66 20 63 72 65 61 74  **   2. If creat
3a10: 65 46 6c 61 67 3d 3d 30 20 61 6e 64 20 74 68 65  eFlag==0 and the
3a20: 20 70 61 67 65 20 69 73 20 6e 6f 74 20 61 6c 72   page is not alr
3a30: 65 61 64 79 20 69 6e 20 74 68 65 20 63 61 63 68  eady in the cach
3a40: 65 2c 20 4e 55 4c 4c 20 69 73 0a 2a 2a 20 20 20  e, NULL is.**   
3a50: 20 20 20 72 65 74 75 72 6e 65 64 2e 0a 2a 2a 0a     returned..**.
3a60: 2a 2a 20 20 20 33 2e 20 49 66 20 63 72 65 61 74  **   3. If creat
3a70: 65 46 6c 61 67 20 69 73 20 31 2c 20 74 68 65 20  eFlag is 1, the 
3a80: 63 61 63 68 65 20 69 73 20 6d 61 72 6b 65 64 20  cache is marked 
3a90: 61 73 20 70 75 72 67 65 61 62 6c 65 20 61 6e 64  as purgeable and
3aa0: 20 74 68 65 20 70 61 67 65 20 69 73 20 0a 2a 2a   the page is .**
3ab0: 20 20 20 20 20 20 6e 6f 74 20 61 6c 72 65 61 64        not alread
3ac0: 79 20 69 6e 20 74 68 65 20 63 61 63 68 65 2c 20  y in the cache, 
3ad0: 61 6e 64 20 69 66 20 65 69 74 68 65 72 20 6f 66  and if either of
3ae0: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 61   the following a
3af0: 72 65 20 74 72 75 65 2c 20 0a 2a 2a 20 20 20 20  re true, .**    
3b00: 20 20 72 65 74 75 72 6e 20 4e 55 4c 4c 3a 0a 2a    return NULL:.*
3b10: 2a 0a 2a 2a 20 20 20 20 20 20 20 28 61 29 20 74  *.**       (a) t
3b20: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67  he number of pag
3b30: 65 73 20 70 69 6e 6e 65 64 20 62 79 20 74 68 65  es pinned by the
3b40: 20 63 61 63 68 65 20 69 73 20 67 72 65 61 74 65   cache is greate
3b50: 72 20 74 68 61 6e 0a 2a 2a 20 20 20 20 20 20 20  r than.**       
3b60: 20 20 20 20 50 43 61 63 68 65 31 2e 6e 4d 61 78      PCache1.nMax
3b70: 2c 20 6f 72 0a 2a 2a 20 20 20 20 20 20 20 28 62  , or.**       (b
3b80: 29 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  ) the number of 
3b90: 70 61 67 65 73 20 70 69 6e 6e 65 64 20 62 79 20  pages pinned by 
3ba0: 74 68 65 20 63 61 63 68 65 20 69 73 20 67 72 65  the cache is gre
3bb0: 61 74 65 72 20 74 68 61 6e 0a 2a 2a 20 20 20 20  ater than.**    
3bc0: 20 20 20 20 20 20 20 74 68 65 20 73 75 6d 20 6f         the sum o
3bd0: 66 20 6e 4d 61 78 20 66 6f 72 20 61 6c 6c 20 70  f nMax for all p
3be0: 75 72 67 65 61 62 6c 65 20 63 61 63 68 65 73 2c  urgeable caches,
3bf0: 20 6c 65 73 73 20 74 68 65 20 73 75 6d 20 6f 66   less the sum of
3c00: 20 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 6e   .**           n
3c10: 4d 69 6e 20 66 6f 72 20 61 6c 6c 20 6f 74 68 65  Min for all othe
3c20: 72 20 70 75 72 67 65 61 62 6c 65 20 63 61 63 68  r purgeable cach
3c30: 65 73 2e 20 0a 2a 2a 0a 2a 2a 20 20 20 34 2e 20  es. .**.**   4. 
3c40: 49 66 20 6e 6f 6e 65 20 6f 66 20 74 68 65 20 66  If none of the f
3c50: 69 72 73 74 20 74 68 72 65 65 20 63 6f 6e 64 69  irst three condi
3c60: 74 69 6f 6e 73 20 61 70 70 6c 79 20 61 6e 64 20  tions apply and 
3c70: 74 68 65 20 63 61 63 68 65 20 69 73 20 6d 61 72  the cache is mar
3c80: 6b 65 64 0a 2a 2a 20 20 20 20 20 20 61 73 20 70  ked.**      as p
3c90: 75 72 67 65 61 62 6c 65 2c 20 61 6e 64 20 69 66  urgeable, and if
3ca0: 20 6f 6e 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c   one of the foll
3cb0: 6f 77 69 6e 67 20 69 73 20 74 72 75 65 3a 0a 2a  owing is true:.*
3cc0: 2a 0a 2a 2a 20 20 20 20 20 20 20 28 61 29 20 54  *.**       (a) T
3cd0: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67  he number of pag
3ce0: 65 73 20 61 6c 6c 6f 63 61 74 65 64 20 66 6f 72  es allocated for
3cf0: 20 74 68 65 20 63 61 63 68 65 20 69 73 20 61 6c   the cache is al
3d00: 72 65 61 64 79 20 0a 2a 2a 20 20 20 20 20 20 20  ready .**       
3d10: 20 20 20 20 50 43 61 63 68 65 31 2e 6e 4d 61 78      PCache1.nMax
3d20: 2c 20 6f 72 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20  , or.**.**      
3d30: 20 28 62 29 20 54 68 65 20 6e 75 6d 62 65 72 20   (b) The number 
3d40: 6f 66 20 70 61 67 65 73 20 61 6c 6c 6f 63 61 74  of pages allocat
3d50: 65 64 20 66 6f 72 20 61 6c 6c 20 70 75 72 67 65  ed for all purge
3d60: 61 62 6c 65 20 63 61 63 68 65 73 20 69 73 0a 2a  able caches is.*
3d70: 2a 20 20 20 20 20 20 20 20 20 20 20 61 6c 72 65  *           alre
3d80: 61 64 79 20 65 71 75 61 6c 20 74 6f 20 6f 72 20  ady equal to or 
3d90: 67 72 65 61 74 65 72 20 74 68 61 6e 20 74 68 65  greater than the
3da0: 20 73 75 6d 20 6f 66 20 6e 4d 61 78 20 66 6f 72   sum of nMax for
3db0: 20 61 6c 6c 0a 2a 2a 20 20 20 20 20 20 20 20 20   all.**         
3dc0: 20 20 70 75 72 67 65 61 62 6c 65 20 63 61 63 68    purgeable cach
3dd0: 65 73 2c 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 74  es,.**.**      t
3de0: 68 65 6e 20 61 74 74 65 6d 70 74 20 74 6f 20 72  hen attempt to r
3df0: 65 63 79 63 6c 65 20 61 20 70 61 67 65 20 66 72  ecycle a page fr
3e00: 6f 6d 20 74 68 65 20 4c 52 55 20 6c 69 73 74 2e  om the LRU list.
3e10: 20 49 66 20 69 74 20 69 73 20 74 68 65 20 72 69   If it is the ri
3e20: 67 68 74 0a 2a 2a 20 20 20 20 20 20 73 69 7a 65  ght.**      size
3e30: 2c 20 72 65 74 75 72 6e 20 74 68 65 20 72 65 63  , return the rec
3e40: 79 63 6c 65 64 20 62 75 66 66 65 72 2e 20 4f 74  ycled buffer. Ot
3e50: 68 65 72 77 69 73 65 2c 20 66 72 65 65 20 74 68  herwise, free th
3e60: 65 20 62 75 66 66 65 72 20 61 6e 64 0a 2a 2a 20  e buffer and.** 
3e70: 20 20 20 20 20 70 72 6f 63 65 65 64 20 74 6f 20       proceed to 
3e80: 73 74 65 70 20 35 2e 20 0a 2a 2a 0a 2a 2a 20 20  step 5. .**.**  
3e90: 20 35 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 61   5. Otherwise, a
3ea0: 6c 6c 6f 63 61 74 65 20 61 6e 64 20 72 65 74 75  llocate and retu
3eb0: 72 6e 20 61 20 6e 65 77 20 70 61 67 65 20 62 75  rn a new page bu
3ec0: 66 66 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ffer..*/.static 
3ed0: 76 6f 69 64 20 2a 70 63 61 63 68 65 31 46 65 74  void *pcache1Fet
3ee0: 63 68 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68  ch(sqlite3_pcach
3ef0: 65 20 2a 70 2c 20 75 6e 73 69 67 6e 65 64 20 69  e *p, unsigned i
3f00: 6e 74 20 69 4b 65 79 2c 20 69 6e 74 20 63 72 65  nt iKey, int cre
3f10: 61 74 65 46 6c 61 67 29 7b 0a 20 20 75 6e 73 69  ateFlag){.  unsi
3f20: 67 6e 65 64 20 69 6e 74 20 6e 50 69 6e 6e 65 64  gned int nPinned
3f30: 3b 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43 61  ;.  PCache1 *pCa
3f40: 63 68 65 20 3d 20 28 50 43 61 63 68 65 31 20 2a  che = (PCache1 *
3f50: 29 70 3b 0a 20 20 50 67 48 64 72 31 20 2a 70 50  )p;.  PgHdr1 *pP
3f60: 61 67 65 20 3d 20 30 3b 0a 0a 20 20 70 63 61 63  age = 0;..  pcac
3f70: 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 29 3b  he1EnterMutex();
3f80: 0a 20 20 69 66 28 20 63 72 65 61 74 65 46 6c 61  .  if( createFla
3f90: 67 3d 3d 31 20 29 20 73 71 6c 69 74 65 33 42 65  g==1 ) sqlite3Be
3fa0: 67 69 6e 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28  ginBenignMalloc(
3fb0: 29 3b 0a 0a 20 20 2f 2a 20 53 65 61 72 63 68 20  );..  /* Search 
3fc0: 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 20 66  the hash table f
3fd0: 6f 72 20 61 6e 20 65 78 69 73 74 69 6e 67 20 65  or an existing e
3fe0: 6e 74 72 79 2e 20 2a 2f 0a 20 20 69 66 28 20 70  ntry. */.  if( p
3ff0: 43 61 63 68 65 2d 3e 6e 48 61 73 68 3e 30 20 29  Cache->nHash>0 )
4000: 7b 0a 20 20 20 20 75 6e 73 69 67 6e 65 64 20 69  {.    unsigned i
4010: 6e 74 20 68 20 3d 20 69 4b 65 79 20 25 20 70 43  nt h = iKey % pC
4020: 61 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 20  ache->nHash;.   
4030: 20 66 6f 72 28 70 50 61 67 65 3d 70 43 61 63 68   for(pPage=pCach
4040: 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 20 70 50  e->apHash[h]; pP
4050: 61 67 65 26 26 70 50 61 67 65 2d 3e 69 4b 65 79  age&&pPage->iKey
4060: 21 3d 69 4b 65 79 3b 20 70 50 61 67 65 3d 70 50  !=iKey; pPage=pP
4070: 61 67 65 2d 3e 70 4e 65 78 74 29 3b 0a 20 20 7d  age->pNext);.  }
4080: 0a 0a 20 20 69 66 28 20 70 50 61 67 65 20 7c 7c  ..  if( pPage ||
4090: 20 63 72 65 61 74 65 46 6c 61 67 3d 3d 30 20 29   createFlag==0 )
40a0: 7b 0a 20 20 20 20 70 63 61 63 68 65 31 50 69 6e  {.    pcache1Pin
40b0: 50 61 67 65 28 70 50 61 67 65 29 3b 0a 20 20 20  Page(pPage);.   
40c0: 20 67 6f 74 6f 20 66 65 74 63 68 5f 6f 75 74 3b   goto fetch_out;
40d0: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53 74 65 70 20  .  }..  /* Step 
40e0: 33 20 6f 66 20 68 65 61 64 65 72 20 63 6f 6d 6d  3 of header comm
40f0: 65 6e 74 2e 20 2a 2f 0a 20 20 6e 50 69 6e 6e 65  ent. */.  nPinne
4100: 64 20 3d 20 70 43 61 63 68 65 2d 3e 6e 50 61 67  d = pCache->nPag
4110: 65 20 2d 20 70 43 61 63 68 65 2d 3e 6e 52 65 63  e - pCache->nRec
4120: 79 63 6c 61 62 6c 65 3b 0a 20 20 69 66 28 20 63  yclable;.  if( c
4130: 72 65 61 74 65 46 6c 61 67 3d 3d 31 20 26 26 20  reateFlag==1 && 
4140: 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62  pCache->bPurgeab
4150: 6c 65 20 26 26 20 28 0a 20 20 20 20 20 20 20 20  le && (.        
4160: 6e 50 69 6e 6e 65 64 3e 3d 28 70 63 61 63 68 65  nPinned>=(pcache
4170: 31 2e 6e 4d 61 78 50 61 67 65 2b 70 43 61 63 68  1.nMaxPage+pCach
4180: 65 2d 3e 6e 4d 69 6e 2d 70 63 61 63 68 65 31 2e  e->nMin-pcache1.
4190: 6e 4d 69 6e 50 61 67 65 29 0a 20 20 20 20 20 7c  nMinPage).     |
41a0: 7c 20 6e 50 69 6e 6e 65 64 3e 3d 28 70 43 61 63  | nPinned>=(pCac
41b0: 68 65 2d 3e 6e 4d 61 78 20 2a 20 39 20 2f 20 31  he->nMax * 9 / 1
41c0: 30 29 0a 20 20 29 29 7b 0a 20 20 20 20 67 6f 74  0).  )){.    got
41d0: 6f 20 66 65 74 63 68 5f 6f 75 74 3b 0a 20 20 7d  o fetch_out;.  }
41e0: 0a 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e  ..  if( pCache->
41f0: 6e 50 61 67 65 3e 3d 70 43 61 63 68 65 2d 3e 6e  nPage>=pCache->n
4200: 48 61 73 68 20 26 26 20 70 63 61 63 68 65 31 52  Hash && pcache1R
4210: 65 73 69 7a 65 48 61 73 68 28 70 43 61 63 68 65  esizeHash(pCache
4220: 29 20 29 7b 0a 20 20 20 20 67 6f 74 6f 20 66 65  ) ){.    goto fe
4230: 74 63 68 5f 6f 75 74 3b 0a 20 20 7d 0a 0a 20 20  tch_out;.  }..  
4240: 2f 2a 20 53 74 65 70 20 34 2e 20 54 72 79 20 74  /* Step 4. Try t
4250: 6f 20 72 65 63 79 63 6c 65 20 61 20 70 61 67 65  o recycle a page
4260: 20 62 75 66 66 65 72 20 69 66 20 61 70 70 72 6f   buffer if appro
4270: 70 72 69 61 74 65 2e 20 2a 2f 0a 20 20 69 66 28  priate. */.  if(
4280: 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61   pCache->bPurgea
4290: 62 6c 65 20 26 26 20 70 63 61 63 68 65 31 2e 70  ble && pcache1.p
42a0: 4c 72 75 54 61 69 6c 20 26 26 20 28 0a 20 20 20  LruTail && (.   
42b0: 20 20 28 70 43 61 63 68 65 2d 3e 6e 50 61 67 65    (pCache->nPage
42c0: 2b 31 3e 3d 70 43 61 63 68 65 2d 3e 6e 4d 61 78  +1>=pCache->nMax
42d0: 29 20 7c 7c 20 70 63 61 63 68 65 31 2e 6e 43 75  ) || pcache1.nCu
42e0: 72 72 65 6e 74 50 61 67 65 3e 3d 70 63 61 63 68  rrentPage>=pcach
42f0: 65 31 2e 6e 4d 61 78 50 61 67 65 0a 20 20 29 29  e1.nMaxPage.  ))
4300: 7b 0a 20 20 20 20 70 50 61 67 65 20 3d 20 70 63  {.    pPage = pc
4310: 61 63 68 65 31 2e 70 4c 72 75 54 61 69 6c 3b 0a  ache1.pLruTail;.
4320: 20 20 20 20 70 63 61 63 68 65 31 52 65 6d 6f 76      pcache1Remov
4330: 65 46 72 6f 6d 48 61 73 68 28 70 50 61 67 65 29  eFromHash(pPage)
4340: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 50 69 6e  ;.    pcache1Pin
4350: 50 61 67 65 28 70 50 61 67 65 29 3b 0a 20 20 20  Page(pPage);.   
4360: 20 69 66 28 20 70 50 61 67 65 2d 3e 70 43 61 63   if( pPage->pCac
4370: 68 65 2d 3e 73 7a 50 61 67 65 21 3d 70 43 61 63  he->szPage!=pCac
4380: 68 65 2d 3e 73 7a 50 61 67 65 20 29 7b 0a 20 20  he->szPage ){.  
4390: 20 20 20 20 70 63 61 63 68 65 31 46 72 65 65 50      pcache1FreeP
43a0: 61 67 65 28 70 50 61 67 65 29 3b 0a 20 20 20 20  age(pPage);.    
43b0: 20 20 70 50 61 67 65 20 3d 20 30 3b 0a 20 20 20    pPage = 0;.   
43c0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 63   }else{.      pc
43d0: 61 63 68 65 31 2e 6e 43 75 72 72 65 6e 74 50 61  ache1.nCurrentPa
43e0: 67 65 20 2d 3d 20 28 70 50 61 67 65 2d 3e 70 43  ge -= (pPage->pC
43f0: 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65  ache->bPurgeable
4400: 20 2d 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67   - pCache->bPurg
4410: 65 61 62 6c 65 29 3b 0a 20 20 20 20 7d 0a 20 20  eable);.    }.  
4420: 7d 0a 0a 20 20 2f 2a 20 53 74 65 70 20 35 2e 20  }..  /* Step 5. 
4430: 49 66 20 61 20 75 73 61 62 6c 65 20 70 61 67 65  If a usable page
4440: 20 62 75 66 66 65 72 20 68 61 73 20 73 74 69 6c   buffer has stil
4450: 6c 20 6e 6f 74 20 62 65 65 6e 20 66 6f 75 6e 64  l not been found
4460: 2c 20 0a 20 20 2a 2a 20 61 74 74 65 6d 70 74 20  , .  ** attempt 
4470: 74 6f 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e 65  to allocate a ne
4480: 77 20 6f 6e 65 2e 20 0a 20 20 2a 2f 0a 20 20 69  w one. .  */.  i
4490: 66 28 20 21 70 50 61 67 65 20 29 7b 0a 20 20 20  f( !pPage ){.   
44a0: 20 70 50 61 67 65 20 3d 20 70 63 61 63 68 65 31   pPage = pcache1
44b0: 41 6c 6c 6f 63 50 61 67 65 28 70 43 61 63 68 65  AllocPage(pCache
44c0: 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 50  );.  }..  if( pP
44d0: 61 67 65 20 29 7b 0a 20 20 20 20 75 6e 73 69 67  age ){.    unsig
44e0: 6e 65 64 20 69 6e 74 20 68 20 3d 20 69 4b 65 79  ned int h = iKey
44f0: 20 25 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68   % pCache->nHash
4500: 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 6e 50  ;.    pCache->nP
4510: 61 67 65 2b 2b 3b 0a 20 20 20 20 70 50 61 67 65  age++;.    pPage
4520: 2d 3e 69 4b 65 79 20 3d 20 69 4b 65 79 3b 0a 20  ->iKey = iKey;. 
4530: 20 20 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 20     pPage->pNext 
4540: 3d 20 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68  = pCache->apHash
4550: 5b 68 5d 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e  [h];.    pPage->
4560: 70 43 61 63 68 65 20 3d 20 70 43 61 63 68 65 3b  pCache = pCache;
4570: 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 4c 72 75  .    pPage->pLru
4580: 50 72 65 76 20 3d 20 30 3b 0a 20 20 20 20 70 50  Prev = 0;.    pP
4590: 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 20 3d 20  age->pLruNext = 
45a0: 30 3b 0a 20 20 20 20 2a 28 76 6f 69 64 20 2a 2a  0;.    *(void **
45b0: 29 28 50 47 48 44 52 31 5f 54 4f 5f 50 41 47 45  )(PGHDR1_TO_PAGE
45c0: 28 70 50 61 67 65 29 29 20 3d 20 30 3b 0a 20 20  (pPage)) = 0;.  
45d0: 20 20 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68    pCache->apHash
45e0: 5b 68 5d 20 3d 20 70 50 61 67 65 3b 0a 20 20 7d  [h] = pPage;.  }
45f0: 0a 0a 66 65 74 63 68 5f 6f 75 74 3a 0a 20 20 69  ..fetch_out:.  i
4600: 66 28 20 70 50 61 67 65 20 26 26 20 69 4b 65 79  f( pPage && iKey
4610: 3e 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79  >pCache->iMaxKey
4620: 20 29 7b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e   ){.    pCache->
4630: 69 4d 61 78 4b 65 79 20 3d 20 69 4b 65 79 3b 0a  iMaxKey = iKey;.
4640: 20 20 7d 0a 20 20 69 66 28 20 63 72 65 61 74 65    }.  if( create
4650: 46 6c 61 67 3d 3d 31 20 29 20 73 71 6c 69 74 65  Flag==1 ) sqlite
4660: 33 45 6e 64 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63  3EndBenignMalloc
4670: 28 29 3b 0a 20 20 70 63 61 63 68 65 31 4c 65 61  ();.  pcache1Lea
4680: 76 65 4d 75 74 65 78 28 29 3b 0a 20 20 72 65 74  veMutex();.  ret
4690: 75 72 6e 20 28 70 50 61 67 65 20 3f 20 50 47 48  urn (pPage ? PGH
46a0: 44 52 31 5f 54 4f 5f 50 41 47 45 28 70 50 61 67  DR1_TO_PAGE(pPag
46b0: 65 29 20 3a 20 30 29 3b 0a 7d 0a 0a 0a 2f 2a 0a  e) : 0);.}.../*.
46c0: 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  ** Implementatio
46d0: 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33  n of the sqlite3
46e0: 5f 70 63 61 63 68 65 2e 78 55 6e 70 69 6e 20 6d  _pcache.xUnpin m
46f0: 65 74 68 6f 64 2e 0a 2a 2a 0a 2a 2a 20 4d 61 72  ethod..**.** Mar
4700: 6b 20 61 20 70 61 67 65 20 61 73 20 75 6e 70 69  k a page as unpi
4710: 6e 6e 65 64 20 28 65 6c 69 67 69 62 6c 65 20 66  nned (eligible f
4720: 6f 72 20 61 73 79 6e 63 68 72 6f 6e 6f 75 73 20  or asynchronous 
4730: 72 65 63 79 63 6c 69 6e 67 29 2e 0a 2a 2f 0a 73  recycling)..*/.s
4740: 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68  tatic void pcach
4750: 65 31 55 6e 70 69 6e 28 73 71 6c 69 74 65 33 5f  e1Unpin(sqlite3_
4760: 70 63 61 63 68 65 20 2a 70 2c 20 76 6f 69 64 20  pcache *p, void 
4770: 2a 70 50 67 2c 20 69 6e 74 20 72 65 75 73 65 55  *pPg, int reuseU
4780: 6e 6c 69 6b 65 6c 79 29 7b 0a 20 20 50 43 61 63  nlikely){.  PCac
4790: 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28 50  he1 *pCache = (P
47a0: 43 61 63 68 65 31 20 2a 29 70 3b 0a 20 20 50 67  Cache1 *)p;.  Pg
47b0: 48 64 72 31 20 2a 70 50 61 67 65 20 3d 20 50 41  Hdr1 *pPage = PA
47c0: 47 45 5f 54 4f 5f 50 47 48 44 52 31 28 70 43 61  GE_TO_PGHDR1(pCa
47d0: 63 68 65 2c 20 70 50 67 29 3b 0a 20 0a 20 20 61  che, pPg);. .  a
47e0: 73 73 65 72 74 28 20 70 50 61 67 65 2d 3e 70 43  ssert( pPage->pC
47f0: 61 63 68 65 3d 3d 70 43 61 63 68 65 20 29 3b 0a  ache==pCache );.
4800: 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75    pcache1EnterMu
4810: 74 65 78 28 29 3b 0a 0a 20 20 2f 2a 20 49 74 20  tex();..  /* It 
4820: 69 73 20 61 6e 20 65 72 72 6f 72 20 74 6f 20 63  is an error to c
4830: 61 6c 6c 20 74 68 69 73 20 66 75 6e 63 74 69 6f  all this functio
4840: 6e 20 69 66 20 74 68 65 20 70 61 67 65 20 69 73  n if the page is
4850: 20 61 6c 72 65 61 64 79 20 0a 20 20 2a 2a 20 70   already .  ** p
4860: 61 72 74 20 6f 66 20 74 68 65 20 67 6c 6f 62 61  art of the globa
4870: 6c 20 4c 52 55 20 6c 69 73 74 2e 0a 20 20 2a 2f  l LRU list..  */
4880: 0a 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65  .  assert( pPage
4890: 2d 3e 70 4c 72 75 50 72 65 76 3d 3d 30 20 26 26  ->pLruPrev==0 &&
48a0: 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74   pPage->pLruNext
48b0: 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28  ==0 );.  assert(
48c0: 20 70 63 61 63 68 65 31 2e 70 4c 72 75 48 65 61   pcache1.pLruHea
48d0: 64 21 3d 70 50 61 67 65 20 26 26 20 70 63 61 63  d!=pPage && pcac
48e0: 68 65 31 2e 70 4c 72 75 54 61 69 6c 21 3d 70 50  he1.pLruTail!=pP
48f0: 61 67 65 20 29 3b 0a 0a 20 20 69 66 28 20 72 65  age );..  if( re
4900: 75 73 65 55 6e 6c 69 6b 65 6c 79 20 7c 7c 20 70  useUnlikely || p
4910: 63 61 63 68 65 31 2e 6e 43 75 72 72 65 6e 74 50  cache1.nCurrentP
4920: 61 67 65 3e 70 63 61 63 68 65 31 2e 6e 4d 61 78  age>pcache1.nMax
4930: 50 61 67 65 20 29 7b 0a 20 20 20 20 70 63 61 63  Page ){.    pcac
4940: 68 65 31 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73  he1RemoveFromHas
4950: 68 28 70 50 61 67 65 29 3b 0a 20 20 20 20 70 63  h(pPage);.    pc
4960: 61 63 68 65 31 46 72 65 65 50 61 67 65 28 70 50  ache1FreePage(pP
4970: 61 67 65 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  age);.  }else{. 
4980: 20 20 20 2f 2a 20 41 64 64 20 74 68 65 20 70 61     /* Add the pa
4990: 67 65 20 74 6f 20 74 68 65 20 67 6c 6f 62 61 6c  ge to the global
49a0: 20 4c 52 55 20 6c 69 73 74 2e 20 4e 6f 72 6d 61   LRU list. Norma
49b0: 6c 6c 79 2c 20 74 68 65 20 70 61 67 65 20 69 73  lly, the page is
49c0: 20 61 64 64 65 64 20 74 6f 0a 20 20 20 20 2a 2a   added to.    **
49d0: 20 74 68 65 20 68 65 61 64 20 6f 66 20 74 68 65   the head of the
49e0: 20 6c 69 73 74 20 28 6c 61 73 74 20 70 61 67 65   list (last page
49f0: 20 74 6f 20 62 65 20 72 65 63 79 63 6c 65 64 29   to be recycled)
4a00: 2e 20 48 6f 77 65 76 65 72 2c 20 69 66 20 74 68  . However, if th
4a10: 65 20 0a 20 20 20 20 2a 2a 20 72 65 75 73 65 55  e .    ** reuseU
4a20: 6e 6c 69 6b 65 6c 79 20 66 6c 61 67 20 70 61 73  nlikely flag pas
4a30: 73 65 64 20 74 6f 20 74 68 69 73 20 66 75 6e 63  sed to this func
4a40: 74 69 6f 6e 20 69 73 20 74 72 75 65 2c 20 74 68  tion is true, th
4a50: 65 20 70 61 67 65 20 69 73 20 61 64 64 65 64 0a  e page is added.
4a60: 20 20 20 20 2a 2a 20 74 6f 20 74 68 65 20 74 61      ** to the ta
4a70: 69 6c 20 6f 66 20 74 68 65 20 6c 69 73 74 20 28  il of the list (
4a80: 66 69 72 73 74 20 70 61 67 65 20 74 6f 20 62 65  first page to be
4a90: 20 72 65 63 79 63 6c 65 64 29 2e 0a 20 20 20 20   recycled)..    
4aa0: 2a 2f 0a 20 20 20 20 69 66 28 20 70 63 61 63 68  */.    if( pcach
4ab0: 65 31 2e 70 4c 72 75 48 65 61 64 20 29 7b 0a 20  e1.pLruHead ){. 
4ac0: 20 20 20 20 20 70 63 61 63 68 65 31 2e 70 4c 72       pcache1.pLr
4ad0: 75 48 65 61 64 2d 3e 70 4c 72 75 50 72 65 76 20  uHead->pLruPrev 
4ae0: 3d 20 70 50 61 67 65 3b 0a 20 20 20 20 20 20 70  = pPage;.      p
4af0: 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 20 3d  Page->pLruNext =
4b00: 20 70 63 61 63 68 65 31 2e 70 4c 72 75 48 65 61   pcache1.pLruHea
4b10: 64 3b 0a 20 20 20 20 20 20 70 63 61 63 68 65 31  d;.      pcache1
4b20: 2e 70 4c 72 75 48 65 61 64 20 3d 20 70 50 61 67  .pLruHead = pPag
4b30: 65 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  e;.    }else{.  
4b40: 20 20 20 20 70 63 61 63 68 65 31 2e 70 4c 72 75      pcache1.pLru
4b50: 54 61 69 6c 20 3d 20 70 50 61 67 65 3b 0a 20 20  Tail = pPage;.  
4b60: 20 20 20 20 70 63 61 63 68 65 31 2e 70 4c 72 75      pcache1.pLru
4b70: 48 65 61 64 20 3d 20 70 50 61 67 65 3b 0a 20 20  Head = pPage;.  
4b80: 20 20 7d 0a 20 20 20 20 70 43 61 63 68 65 2d 3e    }.    pCache->
4b90: 6e 52 65 63 79 63 6c 61 62 6c 65 2b 2b 3b 0a 20  nRecyclable++;. 
4ba0: 20 7d 0a 0a 20 20 70 63 61 63 68 65 31 4c 65 61   }..  pcache1Lea
4bb0: 76 65 4d 75 74 65 78 28 29 3b 0a 7d 0a 0a 2f 2a  veMutex();.}../*
4bc0: 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69  .** Implementati
4bd0: 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65  on of the sqlite
4be0: 33 5f 70 63 61 63 68 65 2e 78 52 65 6b 65 79 20  3_pcache.xRekey 
4bf0: 6d 65 74 68 6f 64 2e 20 0a 2a 2f 0a 73 74 61 74  method. .*/.stat
4c00: 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 31 52  ic void pcache1R
4c10: 65 6b 65 79 28 0a 20 20 73 71 6c 69 74 65 33 5f  ekey(.  sqlite3_
4c20: 70 63 61 63 68 65 20 2a 70 2c 0a 20 20 76 6f 69  pcache *p,.  voi
4c30: 64 20 2a 70 50 67 2c 0a 20 20 75 6e 73 69 67 6e  d *pPg,.  unsign
4c40: 65 64 20 69 6e 74 20 69 4f 6c 64 2c 0a 20 20 75  ed int iOld,.  u
4c50: 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4e 65 77  nsigned int iNew
4c60: 0a 29 7b 0a 20 20 50 43 61 63 68 65 31 20 2a 70  .){.  PCache1 *p
4c70: 43 61 63 68 65 20 3d 20 28 50 43 61 63 68 65 31  Cache = (PCache1
4c80: 20 2a 29 70 3b 0a 20 20 50 67 48 64 72 31 20 2a   *)p;.  PgHdr1 *
4c90: 70 50 61 67 65 20 3d 20 50 41 47 45 5f 54 4f 5f  pPage = PAGE_TO_
4ca0: 50 47 48 44 52 31 28 70 43 61 63 68 65 2c 20 70  PGHDR1(pCache, p
4cb0: 50 67 29 3b 0a 20 20 50 67 48 64 72 31 20 2a 2a  Pg);.  PgHdr1 **
4cc0: 70 70 3b 0a 20 20 75 6e 73 69 67 6e 65 64 20 69  pp;.  unsigned i
4cd0: 6e 74 20 68 3b 20 0a 20 20 61 73 73 65 72 74 28  nt h; .  assert(
4ce0: 20 70 50 61 67 65 2d 3e 69 4b 65 79 3d 3d 69 4f   pPage->iKey==iO
4cf0: 6c 64 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  ld );.  assert( 
4d00: 70 50 61 67 65 2d 3e 70 43 61 63 68 65 3d 3d 70  pPage->pCache==p
4d10: 43 61 63 68 65 20 29 3b 0a 0a 20 20 70 63 61 63  Cache );..  pcac
4d20: 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 29 3b  he1EnterMutex();
4d30: 0a 0a 20 20 68 20 3d 20 69 4f 6c 64 25 70 43 61  ..  h = iOld%pCa
4d40: 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 70 70  che->nHash;.  pp
4d50: 20 3d 20 26 70 43 61 63 68 65 2d 3e 61 70 48 61   = &pCache->apHa
4d60: 73 68 5b 68 5d 3b 0a 20 20 77 68 69 6c 65 28 20  sh[h];.  while( 
4d70: 28 2a 70 70 29 21 3d 70 50 61 67 65 20 29 7b 0a  (*pp)!=pPage ){.
4d80: 20 20 20 20 70 70 20 3d 20 26 28 2a 70 70 29 2d      pp = &(*pp)-
4d90: 3e 70 4e 65 78 74 3b 0a 20 20 7d 0a 20 20 2a 70  >pNext;.  }.  *p
4da0: 70 20 3d 20 70 50 61 67 65 2d 3e 70 4e 65 78 74  p = pPage->pNext
4db0: 3b 0a 0a 20 20 68 20 3d 20 69 4e 65 77 25 70 43  ;..  h = iNew%pC
4dc0: 61 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 70  ache->nHash;.  p
4dd0: 50 61 67 65 2d 3e 69 4b 65 79 20 3d 20 69 4e 65  Page->iKey = iNe
4de0: 77 3b 0a 20 20 70 50 61 67 65 2d 3e 70 4e 65 78  w;.  pPage->pNex
4df0: 74 20 3d 20 70 43 61 63 68 65 2d 3e 61 70 48 61  t = pCache->apHa
4e00: 73 68 5b 68 5d 3b 0a 20 20 70 43 61 63 68 65 2d  sh[h];.  pCache-
4e10: 3e 61 70 48 61 73 68 5b 68 5d 20 3d 20 70 50 61  >apHash[h] = pPa
4e20: 67 65 3b 0a 0a 20 20 2f 2a 20 54 68 65 20 78 52  ge;..  /* The xR
4e30: 65 6b 65 79 28 29 20 69 6e 74 65 72 66 61 63 65  ekey() interface
4e40: 20 69 73 20 6f 6e 6c 79 20 75 73 65 64 20 74 6f   is only used to
4e50: 20 6d 6f 76 65 20 70 61 67 65 73 20 65 61 72 6c   move pages earl
4e60: 69 65 72 20 69 6e 20 74 68 65 0a 20 20 2a 2a 20  ier in the.  ** 
4e70: 64 61 74 61 62 61 73 65 20 66 69 6c 65 20 28 69  database file (i
4e80: 6e 20 6f 72 64 65 72 20 74 6f 20 6d 6f 76 65 20  n order to move 
4e90: 61 6c 6c 20 66 72 65 65 20 70 61 67 65 73 20 74  all free pages t
4ea0: 6f 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68 65  o the end of the
4eb0: 0a 20 20 2a 2a 20 66 69 6c 65 20 77 68 65 72 65  .  ** file where
4ec0: 20 74 68 65 79 20 63 61 6e 20 62 65 20 74 72 75   they can be tru
4ed0: 6e 63 61 74 65 64 20 6f 66 66 2e 29 20 20 48 65  ncated off.)  He
4ee0: 6e 63 65 2c 20 69 74 20 69 73 20 6e 6f 74 20 70  nce, it is not p
4ef0: 6f 73 73 69 62 6c 65 0a 20 20 2a 2a 20 66 6f 72  ossible.  ** for
4f00: 20 74 68 65 20 6e 65 77 20 70 61 67 65 20 6e 75   the new page nu
4f10: 6d 62 65 72 20 74 6f 20 62 65 20 67 72 65 61 74  mber to be great
4f20: 65 72 20 74 68 61 6e 20 74 68 65 20 6c 61 72 67  er than the larg
4f30: 65 73 74 20 70 72 65 76 69 6f 75 73 6c 79 0a 20  est previously. 
4f40: 20 2a 2a 20 66 65 74 63 68 65 64 20 70 61 67 65   ** fetched page
4f50: 2e 20 20 42 75 74 20 77 65 20 72 65 74 61 69 6e  .  But we retain
4f60: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 74   the following t
4f70: 65 73 74 20 69 6e 20 63 61 73 65 20 78 52 65 6b  est in case xRek
4f80: 65 79 28 29 0a 20 20 2a 2a 20 62 65 67 69 6e 73  ey().  ** begins
4f90: 20 74 6f 20 62 65 20 75 73 65 64 20 69 6e 20 64   to be used in d
4fa0: 69 66 66 65 72 65 6e 74 20 77 61 79 73 20 69 6e  ifferent ways in
4fb0: 20 74 68 65 20 66 75 74 75 72 65 2e 0a 20 20 2a   the future..  *
4fc0: 2f 0a 20 20 69 66 28 20 4e 45 56 45 52 28 69 4e  /.  if( NEVER(iN
4fd0: 65 77 3e 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b  ew>pCache->iMaxK
4fe0: 65 79 29 20 29 7b 0a 20 20 20 20 70 43 61 63 68  ey) ){.    pCach
4ff0: 65 2d 3e 69 4d 61 78 4b 65 79 20 3d 20 69 4e 65  e->iMaxKey = iNe
5000: 77 3b 0a 20 20 7d 0a 0a 20 20 70 63 61 63 68 65  w;.  }..  pcache
5010: 31 4c 65 61 76 65 4d 75 74 65 78 28 29 3b 0a 7d  1LeaveMutex();.}
5020: 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e  ../*.** Implemen
5030: 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71  tation of the sq
5040: 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78 54 72  lite3_pcache.xTr
5050: 75 6e 63 61 74 65 20 6d 65 74 68 6f 64 2e 20 0a  uncate method. .
5060: 2a 2a 0a 2a 2a 20 44 69 73 63 61 72 64 20 61 6c  **.** Discard al
5070: 6c 20 75 6e 70 69 6e 6e 65 64 20 70 61 67 65 73  l unpinned pages
5080: 20 69 6e 20 74 68 65 20 63 61 63 68 65 20 77 69   in the cache wi
5090: 74 68 20 61 20 70 61 67 65 20 6e 75 6d 62 65 72  th a page number
50a0: 20 65 71 75 61 6c 20 74 6f 0a 2a 2a 20 6f 72 20   equal to.** or 
50b0: 67 72 65 61 74 65 72 20 74 68 61 6e 20 70 61 72  greater than par
50c0: 61 6d 65 74 65 72 20 69 4c 69 6d 69 74 2e 20 41  ameter iLimit. A
50d0: 6e 79 20 70 69 6e 6e 65 64 20 70 61 67 65 73 20  ny pinned pages 
50e0: 77 69 74 68 20 61 20 70 61 67 65 20 6e 75 6d 62  with a page numb
50f0: 65 72 0a 2a 2a 20 65 71 75 61 6c 20 74 6f 20 6f  er.** equal to o
5100: 72 20 67 72 65 61 74 65 72 20 74 68 61 6e 20 69  r greater than i
5110: 4c 69 6d 69 74 20 61 72 65 20 69 6d 70 6c 69 63  Limit are implic
5120: 69 74 6c 79 20 75 6e 70 69 6e 6e 65 64 2e 0a 2a  itly unpinned..*
5130: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63  /.static void pc
5140: 61 63 68 65 31 54 72 75 6e 63 61 74 65 28 73 71  ache1Truncate(sq
5150: 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70 2c  lite3_pcache *p,
5160: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4c   unsigned int iL
5170: 69 6d 69 74 29 7b 0a 20 20 50 43 61 63 68 65 31  imit){.  PCache1
5180: 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61 63   *pCache = (PCac
5190: 68 65 31 20 2a 29 70 3b 0a 20 20 70 63 61 63 68  he1 *)p;.  pcach
51a0: 65 31 45 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a  e1EnterMutex();.
51b0: 20 20 69 66 28 20 69 4c 69 6d 69 74 3c 3d 70 43    if( iLimit<=pC
51c0: 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 29 7b  ache->iMaxKey ){
51d0: 0a 20 20 20 20 70 63 61 63 68 65 31 54 72 75 6e  .    pcache1Trun
51e0: 63 61 74 65 55 6e 73 61 66 65 28 70 43 61 63 68  cateUnsafe(pCach
51f0: 65 2c 20 69 4c 69 6d 69 74 29 3b 0a 20 20 20 20  e, iLimit);.    
5200: 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20  pCache->iMaxKey 
5210: 3d 20 69 4c 69 6d 69 74 2d 31 3b 0a 20 20 7d 0a  = iLimit-1;.  }.
5220: 20 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75    pcache1LeaveMu
5230: 74 65 78 28 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  tex();.}../*.** 
5240: 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  Implementation o
5250: 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63  f the sqlite3_pc
5260: 61 63 68 65 2e 78 44 65 73 74 72 6f 79 20 6d 65  ache.xDestroy me
5270: 74 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20 44 65 73  thod. .**.** Des
5280: 74 72 6f 79 20 61 20 63 61 63 68 65 20 61 6c 6c  troy a cache all
5290: 6f 63 61 74 65 64 20 75 73 69 6e 67 20 70 63 61  ocated using pca
52a0: 63 68 65 31 43 72 65 61 74 65 28 29 2e 0a 2a 2f  che1Create()..*/
52b0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61  .static void pca
52c0: 63 68 65 31 44 65 73 74 72 6f 79 28 73 71 6c 69  che1Destroy(sqli
52d0: 74 65 33 5f 70 63 61 63 68 65 20 2a 70 29 7b 0a  te3_pcache *p){.
52e0: 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68    PCache1 *pCach
52f0: 65 20 3d 20 28 50 43 61 63 68 65 31 20 2a 29 70  e = (PCache1 *)p
5300: 3b 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65 72  ;.  pcache1Enter
5310: 4d 75 74 65 78 28 29 3b 0a 20 20 70 63 61 63 68  Mutex();.  pcach
5320: 65 31 54 72 75 6e 63 61 74 65 55 6e 73 61 66 65  e1TruncateUnsafe
5330: 28 70 43 61 63 68 65 2c 20 30 29 3b 0a 20 20 70  (pCache, 0);.  p
5340: 63 61 63 68 65 31 2e 6e 4d 61 78 50 61 67 65 20  cache1.nMaxPage 
5350: 2d 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 3b  -= pCache->nMax;
5360: 0a 20 20 70 63 61 63 68 65 31 2e 6e 4d 69 6e 50  .  pcache1.nMinP
5370: 61 67 65 20 2d 3d 20 70 43 61 63 68 65 2d 3e 6e  age -= pCache->n
5380: 4d 69 6e 3b 0a 20 20 70 63 61 63 68 65 31 45 6e  Min;.  pcache1En
5390: 66 6f 72 63 65 4d 61 78 50 61 67 65 28 29 3b 0a  forceMaxPage();.
53a0: 20 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75    pcache1LeaveMu
53b0: 74 65 78 28 29 3b 0a 20 20 73 71 6c 69 74 65 33  tex();.  sqlite3
53c0: 5f 66 72 65 65 28 70 43 61 63 68 65 2d 3e 61 70  _free(pCache->ap
53d0: 48 61 73 68 29 3b 0a 20 20 73 71 6c 69 74 65 33  Hash);.  sqlite3
53e0: 5f 66 72 65 65 28 70 43 61 63 68 65 29 3b 0a 7d  _free(pCache);.}
53f0: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e  ../*.** This fun
5400: 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20  ction is called 
5410: 64 75 72 69 6e 67 20 69 6e 69 74 69 61 6c 69 7a  during initializ
5420: 61 74 69 6f 6e 20 28 73 71 6c 69 74 65 33 5f 69  ation (sqlite3_i
5430: 6e 69 74 69 61 6c 69 7a 65 28 29 29 20 74 6f 0a  nitialize()) to.
5440: 2a 2a 20 69 6e 73 74 61 6c 6c 20 74 68 65 20 64  ** install the d
5450: 65 66 61 75 6c 74 20 70 6c 75 67 67 61 62 6c 65  efault pluggable
5460: 20 63 61 63 68 65 20 6d 6f 64 75 6c 65 2c 20 61   cache module, a
5470: 73 73 75 6d 69 6e 67 20 74 68 65 20 75 73 65 72  ssuming the user
5480: 20 68 61 73 20 6e 6f 74 0a 2a 2a 20 61 6c 72 65   has not.** alre
5490: 61 64 79 20 70 72 6f 76 69 64 65 64 20 61 6e 20  ady provided an 
54a0: 61 6c 74 65 72 6e 61 74 69 76 65 2e 0a 2a 2f 0a  alternative..*/.
54b0: 76 6f 69 64 20 73 71 6c 69 74 65 33 50 43 61 63  void sqlite3PCac
54c0: 68 65 53 65 74 44 65 66 61 75 6c 74 28 76 6f 69  heSetDefault(voi
54d0: 64 29 7b 0a 20 20 73 74 61 74 69 63 20 73 71 6c  d){.  static sql
54e0: 69 74 65 33 5f 70 63 61 63 68 65 5f 6d 65 74 68  ite3_pcache_meth
54f0: 6f 64 73 20 64 65 66 61 75 6c 74 4d 65 74 68 6f  ods defaultMetho
5500: 64 73 20 3d 20 7b 0a 20 20 20 20 30 2c 20 20 20  ds = {.    0,   
5510: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5520: 20 20 20 20 2f 2a 20 70 41 72 67 20 2a 2f 0a 20      /* pArg */. 
5530: 20 20 20 70 63 61 63 68 65 31 49 6e 69 74 2c 20     pcache1Init, 
5540: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
5550: 49 6e 69 74 20 2a 2f 0a 20 20 20 20 70 63 61 63  Init */.    pcac
5560: 68 65 31 53 68 75 74 64 6f 77 6e 2c 20 20 20 20  he1Shutdown,    
5570: 20 20 20 20 20 2f 2a 20 78 53 68 75 74 64 6f 77       /* xShutdow
5580: 6e 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31  n */.    pcache1
5590: 43 72 65 61 74 65 2c 20 20 20 20 20 20 20 20 20  Create,         
55a0: 20 20 2f 2a 20 78 43 72 65 61 74 65 20 2a 2f 0a    /* xCreate */.
55b0: 20 20 20 20 70 63 61 63 68 65 31 43 61 63 68 65      pcache1Cache
55c0: 73 69 7a 65 2c 20 20 20 20 20 20 20 20 2f 2a 20  size,        /* 
55d0: 78 43 61 63 68 65 73 69 7a 65 20 2a 2f 0a 20 20  xCachesize */.  
55e0: 20 20 70 63 61 63 68 65 31 50 61 67 65 63 6f 75    pcache1Pagecou
55f0: 6e 74 2c 20 20 20 20 20 20 20 20 2f 2a 20 78 50  nt,        /* xP
5600: 61 67 65 63 6f 75 6e 74 20 2a 2f 0a 20 20 20 20  agecount */.    
5610: 70 63 61 63 68 65 31 46 65 74 63 68 2c 20 20 20  pcache1Fetch,   
5620: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 46 65 74           /* xFet
5630: 63 68 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65  ch */.    pcache
5640: 31 55 6e 70 69 6e 2c 20 20 20 20 20 20 20 20 20  1Unpin,         
5650: 20 20 20 2f 2a 20 78 55 6e 70 69 6e 20 2a 2f 0a     /* xUnpin */.
5660: 20 20 20 20 70 63 61 63 68 65 31 52 65 6b 65 79      pcache1Rekey
5670: 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ,            /* 
5680: 78 52 65 6b 65 79 20 2a 2f 0a 20 20 20 20 70 63  xRekey */.    pc
5690: 61 63 68 65 31 54 72 75 6e 63 61 74 65 2c 20 20  ache1Truncate,  
56a0: 20 20 20 20 20 20 20 2f 2a 20 78 54 72 75 6e 63         /* xTrunc
56b0: 61 74 65 20 2a 2f 0a 20 20 20 20 70 63 61 63 68  ate */.    pcach
56c0: 65 31 44 65 73 74 72 6f 79 20 20 20 20 20 20 20  e1Destroy       
56d0: 20 20 20 20 2f 2a 20 78 44 65 73 74 72 6f 79 20      /* xDestroy 
56e0: 2a 2f 0a 20 20 7d 3b 0a 20 20 73 71 6c 69 74 65  */.  };.  sqlite
56f0: 33 5f 63 6f 6e 66 69 67 28 53 51 4c 49 54 45 5f  3_config(SQLITE_
5700: 43 4f 4e 46 49 47 5f 50 43 41 43 48 45 2c 20 26  CONFIG_PCACHE, &
5710: 64 65 66 61 75 6c 74 4d 65 74 68 6f 64 73 29 3b  defaultMethods);
5720: 0a 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54  .}..#ifdef SQLIT
5730: 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f  E_ENABLE_MEMORY_
5740: 4d 41 4e 41 47 45 4d 45 4e 54 0a 2f 2a 0a 2a 2a  MANAGEMENT./*.**
5750: 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   This function i
5760: 73 20 63 61 6c 6c 65 64 20 74 6f 20 66 72 65 65  s called to free
5770: 20 73 75 70 65 72 66 6c 75 6f 75 73 20 64 79 6e   superfluous dyn
5780: 61 6d 69 63 61 6c 6c 79 20 61 6c 6c 6f 63 61 74  amically allocat
5790: 65 64 20 6d 65 6d 6f 72 79 0a 2a 2a 20 68 65 6c  ed memory.** hel
57a0: 64 20 62 79 20 74 68 65 20 70 61 67 65 72 20 73  d by the pager s
57b0: 79 73 74 65 6d 2e 20 4d 65 6d 6f 72 79 20 69 6e  ystem. Memory in
57c0: 20 75 73 65 20 62 79 20 61 6e 79 20 53 51 4c 69   use by any SQLi
57d0: 74 65 20 70 61 67 65 72 20 61 6c 6c 6f 63 61 74  te pager allocat
57e0: 65 64 0a 2a 2a 20 62 79 20 74 68 65 20 63 75 72  ed.** by the cur
57f0: 72 65 6e 74 20 74 68 72 65 61 64 20 6d 61 79 20  rent thread may 
5800: 62 65 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  be sqlite3_free(
5810: 29 65 64 2e 0a 2a 2a 0a 2a 2a 20 6e 52 65 71 20  )ed..**.** nReq 
5820: 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  is the number of
5830: 20 62 79 74 65 73 20 6f 66 20 6d 65 6d 6f 72 79   bytes of memory
5840: 20 72 65 71 75 69 72 65 64 2e 20 4f 6e 63 65 20   required. Once 
5850: 74 68 69 73 20 6d 75 63 68 20 68 61 73 0a 2a 2a  this much has.**
5860: 20 62 65 65 6e 20 72 65 6c 65 61 73 65 64 2c 20   been released, 
5870: 74 68 65 20 66 75 6e 63 74 69 6f 6e 20 72 65 74  the function ret
5880: 75 72 6e 73 2e 20 54 68 65 20 72 65 74 75 72 6e  urns. The return
5890: 20 76 61 6c 75 65 20 69 73 20 74 68 65 20 74 6f   value is the to
58a0: 74 61 6c 20 6e 75 6d 62 65 72 20 0a 2a 2a 20 6f  tal number .** o
58b0: 66 20 62 79 74 65 73 20 6f 66 20 6d 65 6d 6f 72  f bytes of memor
58c0: 79 20 72 65 6c 65 61 73 65 64 2e 0a 2a 2f 0a 69  y released..*/.i
58d0: 6e 74 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  nt sqlite3Pcache
58e0: 52 65 6c 65 61 73 65 4d 65 6d 6f 72 79 28 69 6e  ReleaseMemory(in
58f0: 74 20 6e 52 65 71 29 7b 0a 20 20 69 6e 74 20 6e  t nReq){.  int n
5900: 46 72 65 65 20 3d 20 30 3b 0a 20 20 69 66 28 20  Free = 0;.  if( 
5910: 70 63 61 63 68 65 31 2e 70 53 74 61 72 74 3d 3d  pcache1.pStart==
5920: 30 20 29 7b 0a 20 20 20 20 50 67 48 64 72 31 20  0 ){.    PgHdr1 
5930: 2a 70 3b 0a 20 20 20 20 70 63 61 63 68 65 31 45  *p;.    pcache1E
5940: 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a 20 20 20  nterMutex();.   
5950: 20 77 68 69 6c 65 28 20 28 6e 52 65 71 3c 30 20   while( (nReq<0 
5960: 7c 7c 20 6e 46 72 65 65 3c 6e 52 65 71 29 20 26  || nFree<nReq) &
5970: 26 20 28 70 3d 70 63 61 63 68 65 31 2e 70 4c 72  & (p=pcache1.pLr
5980: 75 54 61 69 6c 29 20 29 7b 0a 20 20 20 20 20 20  uTail) ){.      
5990: 6e 46 72 65 65 20 2b 3d 20 73 71 6c 69 74 65 33  nFree += sqlite3
59a0: 4d 61 6c 6c 6f 63 53 69 7a 65 28 50 47 48 44 52  MallocSize(PGHDR
59b0: 31 5f 54 4f 5f 50 41 47 45 28 70 29 29 3b 0a 20  1_TO_PAGE(p));. 
59c0: 20 20 20 20 20 70 63 61 63 68 65 31 50 69 6e 50       pcache1PinP
59d0: 61 67 65 28 70 29 3b 0a 20 20 20 20 20 20 70 63  age(p);.      pc
59e0: 61 63 68 65 31 52 65 6d 6f 76 65 46 72 6f 6d 48  ache1RemoveFromH
59f0: 61 73 68 28 70 29 3b 0a 20 20 20 20 20 20 70 63  ash(p);.      pc
5a00: 61 63 68 65 31 46 72 65 65 50 61 67 65 28 70 29  ache1FreePage(p)
5a10: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 63 61 63  ;.    }.    pcac
5a20: 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 29 3b  he1LeaveMutex();
5a30: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 6e 46  .  }.  return nF
5a40: 72 65 65 3b 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a  ree;.}.#endif /*
5a50: 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d   SQLITE_ENABLE_M
5a60: 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54  EMORY_MANAGEMENT
5a70: 20 2a 2f 0a 0a 23 69 66 64 65 66 20 53 51 4c 49   */..#ifdef SQLI
5a80: 54 45 5f 54 45 53 54 0a 2f 2a 0a 2a 2a 20 54 68  TE_TEST./*.** Th
5a90: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 75  is function is u
5aa0: 73 65 64 20 62 79 20 74 65 73 74 20 70 72 6f 63  sed by test proc
5ab0: 65 64 75 72 65 73 20 74 6f 20 69 6e 73 70 65 63  edures to inspec
5ac0: 74 20 74 68 65 20 69 6e 74 65 72 6e 61 6c 20 73  t the internal s
5ad0: 74 61 74 65 0a 2a 2a 20 6f 66 20 74 68 65 20 67  tate.** of the g
5ae0: 6c 6f 62 61 6c 20 63 61 63 68 65 2e 0a 2a 2f 0a  lobal cache..*/.
5af0: 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63 61 63  void sqlite3Pcac
5b00: 68 65 53 74 61 74 73 28 0a 20 20 69 6e 74 20 2a  heStats(.  int *
5b10: 70 6e 43 75 72 72 65 6e 74 2c 20 20 20 20 20 20  pnCurrent,      
5b20: 2f 2a 20 4f 55 54 3a 20 54 6f 74 61 6c 20 6e 75  /* OUT: Total nu
5b30: 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 63 61  mber of pages ca
5b40: 63 68 65 64 20 2a 2f 0a 20 20 69 6e 74 20 2a 70  ched */.  int *p
5b50: 6e 4d 61 78 2c 20 20 20 20 20 20 20 20 20 20 2f  nMax,          /
5b60: 2a 20 4f 55 54 3a 20 47 6c 6f 62 61 6c 20 6d 61  * OUT: Global ma
5b70: 78 69 6d 75 6d 20 63 61 63 68 65 20 73 69 7a 65  ximum cache size
5b80: 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 4d 69 6e   */.  int *pnMin
5b90: 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55  ,          /* OU
5ba0: 54 3a 20 53 75 6d 20 6f 66 20 50 43 61 63 68 65  T: Sum of PCache
5bb0: 31 2e 6e 4d 69 6e 20 66 6f 72 20 70 75 72 67 65  1.nMin for purge
5bc0: 61 62 6c 65 20 63 61 63 68 65 73 20 2a 2f 0a 20  able caches */. 
5bd0: 20 69 6e 74 20 2a 70 6e 52 65 63 79 63 6c 61 62   int *pnRecyclab
5be0: 6c 65 20 20 20 20 2f 2a 20 4f 55 54 3a 20 54 6f  le    /* OUT: To
5bf0: 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 70 61  tal number of pa
5c00: 67 65 73 20 61 76 61 69 6c 61 62 6c 65 20 66 6f  ges available fo
5c10: 72 20 72 65 63 79 63 6c 69 6e 67 20 2a 2f 0a 29  r recycling */.)
5c20: 7b 0a 20 20 50 67 48 64 72 31 20 2a 70 3b 0a 20  {.  PgHdr1 *p;. 
5c30: 20 69 6e 74 20 6e 52 65 63 79 63 6c 61 62 6c 65   int nRecyclable
5c40: 20 3d 20 30 3b 0a 20 20 66 6f 72 28 70 3d 70 63   = 0;.  for(p=pc
5c50: 61 63 68 65 31 2e 70 4c 72 75 48 65 61 64 3b 20  ache1.pLruHead; 
5c60: 70 3b 20 70 3d 70 2d 3e 70 4c 72 75 4e 65 78 74  p; p=p->pLruNext
5c70: 29 7b 0a 20 20 20 20 6e 52 65 63 79 63 6c 61 62  ){.    nRecyclab
5c80: 6c 65 2b 2b 3b 0a 20 20 7d 0a 20 20 2a 70 6e 43  le++;.  }.  *pnC
5c90: 75 72 72 65 6e 74 20 3d 20 70 63 61 63 68 65 31  urrent = pcache1
5ca0: 2e 6e 43 75 72 72 65 6e 74 50 61 67 65 3b 0a 20  .nCurrentPage;. 
5cb0: 20 2a 70 6e 4d 61 78 20 3d 20 70 63 61 63 68 65   *pnMax = pcache
5cc0: 31 2e 6e 4d 61 78 50 61 67 65 3b 0a 20 20 2a 70  1.nMaxPage;.  *p
5cd0: 6e 4d 69 6e 20 3d 20 70 63 61 63 68 65 31 2e 6e  nMin = pcache1.n
5ce0: 4d 69 6e 50 61 67 65 3b 0a 20 20 2a 70 6e 52 65  MinPage;.  *pnRe
5cf0: 63 79 63 6c 61 62 6c 65 20 3d 20 6e 52 65 63 79  cyclable = nRecy
5d00: 63 6c 61 62 6c 65 3b 0a 7d 0a 23 65 6e 64 69 66  clable;.}.#endif
5d10: 0a                                               .