/ Hex Artifact Content
Login

Artifact 211295a9ff6a5b30f1ca50516731a5cf3e9bf82c:


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 39 20 32  ache1.c,v 1.19 2
02e0: 30 30 39 2f 30 37 2f 31 37 20 31 31 3a 34 34 3a  009/07/17 11:44:
02f0: 30 37 20 64 72 68 20 45 78 70 20 24 0a 2a 2f 0a  07 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 2a 0a 2a  llocPage()..**.*
1f10: 2a 20 54 68 65 20 70 6f 69 6e 74 65 72 20 69 73  * The pointer is
1f20: 20 61 6c 6c 6f 77 65 64 20 74 6f 20 62 65 20 4e   allowed to be N
1f30: 55 4c 4c 2c 20 77 68 69 63 68 20 69 73 20 70 72  ULL, which is pr
1f40: 75 64 65 6e 74 2e 20 20 42 75 74 20 69 74 20 74  udent.  But it t
1f50: 75 72 6e 73 20 6f 75 74 0a 2a 2a 20 74 68 61 74  urns out.** that
1f60: 20 74 68 65 20 63 75 72 72 65 6e 74 20 69 6d 70   the current imp
1f70: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 68 61 70 70  lementation happ
1f80: 65 6e 73 20 74 6f 20 6e 65 76 65 72 20 63 61 6c  ens to never cal
1f90: 6c 20 74 68 69 73 20 72 6f 75 74 69 6e 65 0a 2a  l this routine.*
1fa0: 2a 20 77 69 74 68 20 61 20 4e 55 4c 4c 20 70 6f  * with a NULL po
1fb0: 69 6e 74 65 72 2c 20 73 6f 20 77 65 20 6d 61 72  inter, so we mar
1fc0: 6b 20 74 68 65 20 4e 55 4c 4c 20 74 65 73 74 20  k the NULL test 
1fd0: 77 69 74 68 20 41 4c 57 41 59 53 28 29 2e 0a 2a  with ALWAYS()..*
1fe0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63  /.static void pc
1ff0: 61 63 68 65 31 46 72 65 65 50 61 67 65 28 50 67  ache1FreePage(Pg
2000: 48 64 72 31 20 2a 70 29 7b 0a 20 20 69 66 28 20  Hdr1 *p){.  if( 
2010: 41 4c 57 41 59 53 28 70 29 20 29 7b 0a 20 20 20  ALWAYS(p) ){.   
2020: 20 69 66 28 20 70 2d 3e 70 43 61 63 68 65 2d 3e   if( p->pCache->
2030: 62 50 75 72 67 65 61 62 6c 65 20 29 7b 0a 20 20  bPurgeable ){.  
2040: 20 20 20 20 70 63 61 63 68 65 31 2e 6e 43 75 72      pcache1.nCur
2050: 72 65 6e 74 50 61 67 65 2d 2d 3b 0a 20 20 20 20  rentPage--;.    
2060: 7d 0a 20 20 20 20 70 63 61 63 68 65 31 46 72 65  }.    pcache1Fre
2070: 65 28 50 47 48 44 52 31 5f 54 4f 5f 50 41 47 45  e(PGHDR1_TO_PAGE
2080: 28 70 29 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a  (p));.  }.}../*.
2090: 2a 2a 20 4d 61 6c 6c 6f 63 20 66 75 6e 63 74 69  ** Malloc functi
20a0: 6f 6e 20 75 73 65 64 20 62 79 20 53 51 4c 69 74  on used by SQLit
20b0: 65 20 74 6f 20 6f 62 74 61 69 6e 20 73 70 61 63  e to obtain spac
20c0: 65 20 66 72 6f 6d 20 74 68 65 20 62 75 66 66 65  e from the buffe
20d0: 72 20 63 6f 6e 66 69 67 75 72 65 64 0a 2a 2a 20  r configured.** 
20e0: 75 73 69 6e 67 20 73 71 6c 69 74 65 33 5f 63 6f  using sqlite3_co
20f0: 6e 66 69 67 28 53 51 4c 49 54 45 5f 43 4f 4e 46  nfig(SQLITE_CONF
2100: 49 47 5f 50 41 47 45 43 41 43 48 45 29 20 6f 70  IG_PAGECACHE) op
2110: 74 69 6f 6e 2e 20 49 66 20 6e 6f 20 73 75 63 68  tion. If no such
2120: 20 62 75 66 66 65 72 0a 2a 2a 20 65 78 69 73 74   buffer.** exist
2130: 73 2c 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  s, this function
2140: 20 66 61 6c 6c 73 20 62 61 63 6b 20 74 6f 20 73   falls back to s
2150: 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 29 2e 0a  qlite3Malloc()..
2160: 2a 2f 0a 76 6f 69 64 20 2a 73 71 6c 69 74 65 33  */.void *sqlite3
2170: 50 61 67 65 4d 61 6c 6c 6f 63 28 69 6e 74 20 73  PageMalloc(int s
2180: 7a 29 7b 0a 20 20 76 6f 69 64 20 2a 70 3b 0a 20  z){.  void *p;. 
2190: 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74   pcache1EnterMut
21a0: 65 78 28 29 3b 0a 20 20 70 20 3d 20 70 63 61 63  ex();.  p = pcac
21b0: 68 65 31 41 6c 6c 6f 63 28 73 7a 29 3b 0a 20 20  he1Alloc(sz);.  
21c0: 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65  pcache1LeaveMute
21d0: 78 28 29 3b 0a 20 20 72 65 74 75 72 6e 20 70 3b  x();.  return p;
21e0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61  .}../*.** Free a
21f0: 6e 20 61 6c 6c 6f 63 61 74 65 64 20 62 75 66 66  n allocated buff
2200: 65 72 20 6f 62 74 61 69 6e 65 64 20 66 72 6f 6d  er obtained from
2210: 20 73 71 6c 69 74 65 33 50 61 67 65 4d 61 6c 6c   sqlite3PageMall
2220: 6f 63 28 29 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71  oc()..*/.void sq
2230: 6c 69 74 65 33 50 61 67 65 46 72 65 65 28 76 6f  lite3PageFree(vo
2240: 69 64 20 2a 70 29 7b 0a 20 20 70 63 61 63 68 65  id *p){.  pcache
2250: 31 45 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a 20  1EnterMutex();. 
2260: 20 70 63 61 63 68 65 31 46 72 65 65 28 70 29 3b   pcache1Free(p);
2270: 0a 20 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d  .  pcache1LeaveM
2280: 75 74 65 78 28 29 3b 0a 7d 0a 0a 2f 2a 2a 2a 2a  utex();.}../****
2290: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
22a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
22b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
22c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
22d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 2a 2a  **********/./***
22e0: 2a 2a 2a 2a 2a 20 47 65 6e 65 72 61 6c 20 49 6d  ***** General Im
22f0: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 46 75 6e  plementation Fun
2300: 63 74 69 6f 6e 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a  ctions *********
2310: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2320: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f 2a  ***********/../*
2330: 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
2340: 6e 20 69 73 20 75 73 65 64 20 74 6f 20 72 65 73  n is used to res
2350: 69 7a 65 20 74 68 65 20 68 61 73 68 20 74 61 62  ize the hash tab
2360: 6c 65 20 75 73 65 64 20 62 79 20 74 68 65 20 63  le used by the c
2370: 61 63 68 65 20 70 61 73 73 65 64 0a 2a 2a 20 61  ache passed.** a
2380: 73 20 74 68 65 20 66 69 72 73 74 20 61 72 67 75  s the first argu
2390: 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  ment..**.** The 
23a0: 67 6c 6f 62 61 6c 20 6d 75 74 65 78 20 6d 75 73  global mutex mus
23b0: 74 20 62 65 20 68 65 6c 64 20 77 68 65 6e 20 74  t be held when t
23c0: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
23d0: 63 61 6c 6c 65 64 2e 0a 2a 2f 0a 73 74 61 74 69  called..*/.stati
23e0: 63 20 69 6e 74 20 70 63 61 63 68 65 31 52 65 73  c int pcache1Res
23f0: 69 7a 65 48 61 73 68 28 50 43 61 63 68 65 31 20  izeHash(PCache1 
2400: 2a 70 29 7b 0a 20 20 50 67 48 64 72 31 20 2a 2a  *p){.  PgHdr1 **
2410: 61 70 4e 65 77 3b 0a 20 20 75 6e 73 69 67 6e 65  apNew;.  unsigne
2420: 64 20 69 6e 74 20 6e 4e 65 77 3b 0a 20 20 75 6e  d int nNew;.  un
2430: 73 69 67 6e 65 64 20 69 6e 74 20 69 3b 0a 0a 20  signed int i;.. 
2440: 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33   assert( sqlite3
2450: 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 63 61 63  _mutex_held(pcac
2460: 68 65 31 2e 6d 75 74 65 78 29 20 29 3b 0a 0a 20  he1.mutex) );.. 
2470: 20 6e 4e 65 77 20 3d 20 70 2d 3e 6e 48 61 73 68   nNew = p->nHash
2480: 2a 32 3b 0a 20 20 69 66 28 20 6e 4e 65 77 3c 32  *2;.  if( nNew<2
2490: 35 36 20 29 7b 0a 20 20 20 20 6e 4e 65 77 20 3d  56 ){.    nNew =
24a0: 20 32 35 36 3b 0a 20 20 7d 0a 0a 20 20 70 63 61   256;.  }..  pca
24b0: 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 29  che1LeaveMutex()
24c0: 3b 0a 20 20 69 66 28 20 70 2d 3e 6e 48 61 73 68  ;.  if( p->nHash
24d0: 20 29 7b 20 73 71 6c 69 74 65 33 42 65 67 69 6e   ){ sqlite3Begin
24e0: 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 20  BenignMalloc(); 
24f0: 7d 0a 20 20 61 70 4e 65 77 20 3d 20 28 50 67 48  }.  apNew = (PgH
2500: 64 72 31 20 2a 2a 29 73 71 6c 69 74 65 33 5f 6d  dr1 **)sqlite3_m
2510: 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 50 67 48  alloc(sizeof(PgH
2520: 64 72 31 20 2a 29 2a 6e 4e 65 77 29 3b 0a 20 20  dr1 *)*nNew);.  
2530: 69 66 28 20 70 2d 3e 6e 48 61 73 68 20 29 7b 20  if( p->nHash ){ 
2540: 73 71 6c 69 74 65 33 45 6e 64 42 65 6e 69 67 6e  sqlite3EndBenign
2550: 4d 61 6c 6c 6f 63 28 29 3b 20 7d 0a 20 20 70 63  Malloc(); }.  pc
2560: 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28  ache1EnterMutex(
2570: 29 3b 0a 20 20 69 66 28 20 61 70 4e 65 77 20 29  );.  if( apNew )
2580: 7b 0a 20 20 20 20 6d 65 6d 73 65 74 28 61 70 4e  {.    memset(apN
2590: 65 77 2c 20 30 2c 20 73 69 7a 65 6f 66 28 50 67  ew, 0, sizeof(Pg
25a0: 48 64 72 31 20 2a 29 2a 6e 4e 65 77 29 3b 0a 20  Hdr1 *)*nNew);. 
25b0: 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 2d     for(i=0; i<p-
25c0: 3e 6e 48 61 73 68 3b 20 69 2b 2b 29 7b 0a 20 20  >nHash; i++){.  
25d0: 20 20 20 20 50 67 48 64 72 31 20 2a 70 50 61 67      PgHdr1 *pPag
25e0: 65 3b 0a 20 20 20 20 20 20 50 67 48 64 72 31 20  e;.      PgHdr1 
25f0: 2a 70 4e 65 78 74 20 3d 20 70 2d 3e 61 70 48 61  *pNext = p->apHa
2600: 73 68 5b 69 5d 3b 0a 20 20 20 20 20 20 77 68 69  sh[i];.      whi
2610: 6c 65 28 20 28 70 50 61 67 65 20 3d 20 70 4e 65  le( (pPage = pNe
2620: 78 74 29 21 3d 30 20 29 7b 0a 20 20 20 20 20 20  xt)!=0 ){.      
2630: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68    unsigned int h
2640: 20 3d 20 70 50 61 67 65 2d 3e 69 4b 65 79 20 25   = pPage->iKey %
2650: 20 6e 4e 65 77 3b 0a 20 20 20 20 20 20 20 20 70   nNew;.        p
2660: 4e 65 78 74 20 3d 20 70 50 61 67 65 2d 3e 70 4e  Next = pPage->pN
2670: 65 78 74 3b 0a 20 20 20 20 20 20 20 20 70 50 61  ext;.        pPa
2680: 67 65 2d 3e 70 4e 65 78 74 20 3d 20 61 70 4e 65  ge->pNext = apNe
2690: 77 5b 68 5d 3b 0a 20 20 20 20 20 20 20 20 61 70  w[h];.        ap
26a0: 4e 65 77 5b 68 5d 20 3d 20 70 50 61 67 65 3b 0a  New[h] = pPage;.
26b0: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
26c0: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
26d0: 2d 3e 61 70 48 61 73 68 29 3b 0a 20 20 20 20 70  ->apHash);.    p
26e0: 2d 3e 61 70 48 61 73 68 20 3d 20 61 70 4e 65 77  ->apHash = apNew
26f0: 3b 0a 20 20 20 20 70 2d 3e 6e 48 61 73 68 20 3d  ;.    p->nHash =
2700: 20 6e 4e 65 77 3b 0a 20 20 7d 0a 0a 20 20 72 65   nNew;.  }..  re
2710: 74 75 72 6e 20 28 70 2d 3e 61 70 48 61 73 68 20  turn (p->apHash 
2720: 3f 20 53 51 4c 49 54 45 5f 4f 4b 20 3a 20 53 51  ? SQLITE_OK : SQ
2730: 4c 49 54 45 5f 4e 4f 4d 45 4d 29 3b 0a 7d 0a 0a  LITE_NOMEM);.}..
2740: 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  /*.** This funct
2750: 69 6f 6e 20 69 73 20 75 73 65 64 20 69 6e 74 65  ion is used inte
2760: 72 6e 61 6c 6c 79 20 74 6f 20 72 65 6d 6f 76 65  rnally to remove
2770: 20 74 68 65 20 70 61 67 65 20 70 50 61 67 65 20   the page pPage 
2780: 66 72 6f 6d 20 74 68 65 20 0a 2a 2a 20 67 6c 6f  from the .** glo
2790: 62 61 6c 20 4c 52 55 20 6c 69 73 74 2c 20 69 66  bal LRU list, if
27a0: 20 69 73 20 70 61 72 74 20 6f 66 20 69 74 2e 20   is part of it. 
27b0: 49 66 20 70 50 61 67 65 20 69 73 20 6e 6f 74 20  If pPage is not 
27c0: 70 61 72 74 20 6f 66 20 74 68 65 20 67 6c 6f 62  part of the glob
27d0: 61 6c 0a 2a 2a 20 4c 52 55 20 6c 69 73 74 2c 20  al.** LRU list, 
27e0: 74 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69  then this functi
27f0: 6f 6e 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a 2a  on is a no-op..*
2800: 2a 0a 2a 2a 20 54 68 65 20 67 6c 6f 62 61 6c 20  *.** The global 
2810: 6d 75 74 65 78 20 6d 75 73 74 20 62 65 20 68 65  mutex must be he
2820: 6c 64 20 77 68 65 6e 20 74 68 69 73 20 66 75 6e  ld when this fun
2830: 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 2e  ction is called.
2840: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
2850: 70 63 61 63 68 65 31 50 69 6e 50 61 67 65 28 50  pcache1PinPage(P
2860: 67 48 64 72 31 20 2a 70 50 61 67 65 29 7b 0a 20  gHdr1 *pPage){. 
2870: 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33   assert( sqlite3
2880: 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 63 61 63  _mutex_held(pcac
2890: 68 65 31 2e 6d 75 74 65 78 29 20 29 3b 0a 20 20  he1.mutex) );.  
28a0: 69 66 28 20 70 50 61 67 65 20 26 26 20 28 70 50  if( pPage && (pP
28b0: 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 20 7c 7c  age->pLruNext ||
28c0: 20 70 50 61 67 65 3d 3d 70 63 61 63 68 65 31 2e   pPage==pcache1.
28d0: 70 4c 72 75 54 61 69 6c 29 20 29 7b 0a 20 20 20  pLruTail) ){.   
28e0: 20 69 66 28 20 70 50 61 67 65 2d 3e 70 4c 72 75   if( pPage->pLru
28f0: 50 72 65 76 20 29 7b 0a 20 20 20 20 20 20 70 50  Prev ){.      pP
2900: 61 67 65 2d 3e 70 4c 72 75 50 72 65 76 2d 3e 70  age->pLruPrev->p
2910: 4c 72 75 4e 65 78 74 20 3d 20 70 50 61 67 65 2d  LruNext = pPage-
2920: 3e 70 4c 72 75 4e 65 78 74 3b 0a 20 20 20 20 7d  >pLruNext;.    }
2930: 0a 20 20 20 20 69 66 28 20 70 50 61 67 65 2d 3e  .    if( pPage->
2940: 70 4c 72 75 4e 65 78 74 20 29 7b 0a 20 20 20 20  pLruNext ){.    
2950: 20 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78    pPage->pLruNex
2960: 74 2d 3e 70 4c 72 75 50 72 65 76 20 3d 20 70 50  t->pLruPrev = pP
2970: 61 67 65 2d 3e 70 4c 72 75 50 72 65 76 3b 0a 20  age->pLruPrev;. 
2980: 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70 63 61     }.    if( pca
2990: 63 68 65 31 2e 70 4c 72 75 48 65 61 64 3d 3d 70  che1.pLruHead==p
29a0: 50 61 67 65 20 29 7b 0a 20 20 20 20 20 20 70 63  Page ){.      pc
29b0: 61 63 68 65 31 2e 70 4c 72 75 48 65 61 64 20 3d  ache1.pLruHead =
29c0: 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74   pPage->pLruNext
29d0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20  ;.    }.    if( 
29e0: 70 63 61 63 68 65 31 2e 70 4c 72 75 54 61 69 6c  pcache1.pLruTail
29f0: 3d 3d 70 50 61 67 65 20 29 7b 0a 20 20 20 20 20  ==pPage ){.     
2a00: 20 70 63 61 63 68 65 31 2e 70 4c 72 75 54 61 69   pcache1.pLruTai
2a10: 6c 20 3d 20 70 50 61 67 65 2d 3e 70 4c 72 75 50  l = pPage->pLruP
2a20: 72 65 76 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70  rev;.    }.    p
2a30: 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 20 3d  Page->pLruNext =
2a40: 20 30 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 70   0;.    pPage->p
2a50: 4c 72 75 50 72 65 76 20 3d 20 30 3b 0a 20 20 20  LruPrev = 0;.   
2a60: 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65 2d 3e   pPage->pCache->
2a70: 6e 52 65 63 79 63 6c 61 62 6c 65 2d 2d 3b 0a 20  nRecyclable--;. 
2a80: 20 7d 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 52 65 6d   }.}.../*.** Rem
2a90: 6f 76 65 20 74 68 65 20 70 61 67 65 20 73 75 70  ove the page sup
2aa0: 70 6c 69 65 64 20 61 73 20 61 6e 20 61 72 67 75  plied as an argu
2ab0: 6d 65 6e 74 20 66 72 6f 6d 20 74 68 65 20 68 61  ment from the ha
2ac0: 73 68 20 74 61 62 6c 65 20 0a 2a 2a 20 28 50 43  sh table .** (PC
2ad0: 61 63 68 65 31 2e 61 70 48 61 73 68 20 73 74 72  ache1.apHash str
2ae0: 75 63 74 75 72 65 29 20 74 68 61 74 20 69 74 20  ucture) that it 
2af0: 69 73 20 63 75 72 72 65 6e 74 6c 79 20 73 74 6f  is currently sto
2b00: 72 65 64 20 69 6e 2e 0a 2a 2a 0a 2a 2a 20 54 68  red in..**.** Th
2b10: 65 20 67 6c 6f 62 61 6c 20 6d 75 74 65 78 20 6d  e global mutex m
2b20: 75 73 74 20 62 65 20 68 65 6c 64 20 77 68 65 6e  ust be held when
2b30: 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   this function i
2b40: 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f 0a 73 74 61  s called..*/.sta
2b50: 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 31  tic void pcache1
2b60: 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73 68 28 50  RemoveFromHash(P
2b70: 67 48 64 72 31 20 2a 70 50 61 67 65 29 7b 0a 20  gHdr1 *pPage){. 
2b80: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 3b   unsigned int h;
2b90: 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63  .  PCache1 *pCac
2ba0: 68 65 20 3d 20 70 50 61 67 65 2d 3e 70 43 61 63  he = pPage->pCac
2bb0: 68 65 3b 0a 20 20 50 67 48 64 72 31 20 2a 2a 70  he;.  PgHdr1 **p
2bc0: 70 3b 0a 0a 20 20 68 20 3d 20 70 50 61 67 65 2d  p;..  h = pPage-
2bd0: 3e 69 4b 65 79 20 25 20 70 43 61 63 68 65 2d 3e  >iKey % pCache->
2be0: 6e 48 61 73 68 3b 0a 20 20 66 6f 72 28 70 70 3d  nHash;.  for(pp=
2bf0: 26 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b  &pCache->apHash[
2c00: 68 5d 3b 20 28 2a 70 70 29 21 3d 70 50 61 67 65  h]; (*pp)!=pPage
2c10: 3b 20 70 70 3d 26 28 2a 70 70 29 2d 3e 70 4e 65  ; pp=&(*pp)->pNe
2c20: 78 74 29 3b 0a 20 20 2a 70 70 20 3d 20 28 2a 70  xt);.  *pp = (*p
2c30: 70 29 2d 3e 70 4e 65 78 74 3b 0a 0a 20 20 70 43  p)->pNext;..  pC
2c40: 61 63 68 65 2d 3e 6e 50 61 67 65 2d 2d 3b 0a 7d  ache->nPage--;.}
2c50: 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 74 68 65 72 65  ../*.** If there
2c60: 20 61 72 65 20 63 75 72 72 65 6e 74 6c 79 20 6d   are currently m
2c70: 6f 72 65 20 74 68 61 6e 20 70 63 61 63 68 65 2e  ore than pcache.
2c80: 6e 4d 61 78 50 61 67 65 20 70 61 67 65 73 20 61  nMaxPage pages a
2c90: 6c 6c 6f 63 61 74 65 64 2c 20 74 72 79 0a 2a 2a  llocated, try.**
2ca0: 20 74 6f 20 72 65 63 79 63 6c 65 20 70 61 67 65   to recycle page
2cb0: 73 20 74 6f 20 72 65 64 75 63 65 20 74 68 65 20  s to reduce the 
2cc0: 6e 75 6d 62 65 72 20 61 6c 6c 6f 63 61 74 65 64  number allocated
2cd0: 20 74 6f 20 70 63 61 63 68 65 2e 6e 4d 61 78 50   to pcache.nMaxP
2ce0: 61 67 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  age..*/.static v
2cf0: 6f 69 64 20 70 63 61 63 68 65 31 45 6e 66 6f 72  oid pcache1Enfor
2d00: 63 65 4d 61 78 50 61 67 65 28 76 6f 69 64 29 7b  ceMaxPage(void){
2d10: 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74  .  assert( sqlit
2d20: 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 63  e3_mutex_held(pc
2d30: 61 63 68 65 31 2e 6d 75 74 65 78 29 20 29 3b 0a  ache1.mutex) );.
2d40: 20 20 77 68 69 6c 65 28 20 70 63 61 63 68 65 31    while( pcache1
2d50: 2e 6e 43 75 72 72 65 6e 74 50 61 67 65 3e 70 63  .nCurrentPage>pc
2d60: 61 63 68 65 31 2e 6e 4d 61 78 50 61 67 65 20 26  ache1.nMaxPage &
2d70: 26 20 70 63 61 63 68 65 31 2e 70 4c 72 75 54 61  & pcache1.pLruTa
2d80: 69 6c 20 29 7b 0a 20 20 20 20 50 67 48 64 72 31  il ){.    PgHdr1
2d90: 20 2a 70 20 3d 20 70 63 61 63 68 65 31 2e 70 4c   *p = pcache1.pL
2da0: 72 75 54 61 69 6c 3b 0a 20 20 20 20 70 63 61 63  ruTail;.    pcac
2db0: 68 65 31 50 69 6e 50 61 67 65 28 70 29 3b 0a 20  he1PinPage(p);. 
2dc0: 20 20 20 70 63 61 63 68 65 31 52 65 6d 6f 76 65     pcache1Remove
2dd0: 46 72 6f 6d 48 61 73 68 28 70 29 3b 0a 20 20 20  FromHash(p);.   
2de0: 20 70 63 61 63 68 65 31 46 72 65 65 50 61 67 65   pcache1FreePage
2df0: 28 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a  (p);.  }.}../*.*
2e00: 2a 20 44 69 73 63 61 72 64 20 61 6c 6c 20 70 61  * Discard all pa
2e10: 67 65 73 20 66 72 6f 6d 20 63 61 63 68 65 20 70  ges from cache p
2e20: 43 61 63 68 65 20 77 69 74 68 20 61 20 70 61 67  Cache with a pag
2e30: 65 20 6e 75 6d 62 65 72 20 28 6b 65 79 20 76 61  e number (key va
2e40: 6c 75 65 29 20 0a 2a 2a 20 67 72 65 61 74 65 72  lue) .** greater
2e50: 20 74 68 61 6e 20 6f 72 20 65 71 75 61 6c 20 74   than or equal t
2e60: 6f 20 69 4c 69 6d 69 74 2e 20 41 6e 79 20 70 69  o iLimit. Any pi
2e70: 6e 6e 65 64 20 70 61 67 65 73 20 74 68 61 74 20  nned pages that 
2e80: 6d 65 65 74 20 74 68 69 73 20 0a 2a 2a 20 63 72  meet this .** cr
2e90: 69 74 65 72 69 61 20 61 72 65 20 75 6e 70 69 6e  iteria are unpin
2ea0: 6e 65 64 20 62 65 66 6f 72 65 20 74 68 65 79 20  ned before they 
2eb0: 61 72 65 20 64 69 73 63 61 72 64 65 64 2e 0a 2a  are discarded..*
2ec0: 2a 0a 2a 2a 20 54 68 65 20 67 6c 6f 62 61 6c 20  *.** The global 
2ed0: 6d 75 74 65 78 20 6d 75 73 74 20 62 65 20 68 65  mutex must be he
2ee0: 6c 64 20 77 68 65 6e 20 74 68 69 73 20 66 75 6e  ld when this fun
2ef0: 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 2e  ction is called.
2f00: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
2f10: 70 63 61 63 68 65 31 54 72 75 6e 63 61 74 65 55  pcache1TruncateU
2f20: 6e 73 61 66 65 28 0a 20 20 50 43 61 63 68 65 31  nsafe(.  PCache1
2f30: 20 2a 70 43 61 63 68 65 2c 20 0a 20 20 75 6e 73   *pCache, .  uns
2f40: 69 67 6e 65 64 20 69 6e 74 20 69 4c 69 6d 69 74  igned int iLimit
2f50: 20 0a 29 7b 0a 20 20 54 45 53 54 4f 4e 4c 59 28   .){.  TESTONLY(
2f60: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 50   unsigned int nP
2f70: 61 67 65 20 3d 20 30 3b 20 29 20 20 20 20 20 20  age = 0; )      
2f80: 2f 2a 20 55 73 65 64 20 74 6f 20 61 73 73 65 72  /* Used to asser
2f90: 74 20 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 20  t pCache->nPage 
2fa0: 69 73 20 63 6f 72 72 65 63 74 20 2a 2f 0a 20 20  is correct */.  
2fb0: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 3b 0a  unsigned int h;.
2fc0: 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65    assert( sqlite
2fd0: 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 63 61  3_mutex_held(pca
2fe0: 63 68 65 31 2e 6d 75 74 65 78 29 20 29 3b 0a 20  che1.mutex) );. 
2ff0: 20 66 6f 72 28 68 3d 30 3b 20 68 3c 70 43 61 63   for(h=0; h<pCac
3000: 68 65 2d 3e 6e 48 61 73 68 3b 20 68 2b 2b 29 7b  he->nHash; h++){
3010: 0a 20 20 20 20 50 67 48 64 72 31 20 2a 2a 70 70  .    PgHdr1 **pp
3020: 20 3d 20 26 70 43 61 63 68 65 2d 3e 61 70 48 61   = &pCache->apHa
3030: 73 68 5b 68 5d 3b 20 0a 20 20 20 20 50 67 48 64  sh[h]; .    PgHd
3040: 72 31 20 2a 70 50 61 67 65 3b 0a 20 20 20 20 77  r1 *pPage;.    w
3050: 68 69 6c 65 28 20 28 70 50 61 67 65 20 3d 20 2a  hile( (pPage = *
3060: 70 70 29 21 3d 30 20 29 7b 0a 20 20 20 20 20 20  pp)!=0 ){.      
3070: 69 66 28 20 70 50 61 67 65 2d 3e 69 4b 65 79 3e  if( pPage->iKey>
3080: 3d 69 4c 69 6d 69 74 20 29 7b 0a 20 20 20 20 20  =iLimit ){.     
3090: 20 20 20 70 43 61 63 68 65 2d 3e 6e 50 61 67 65     pCache->nPage
30a0: 2d 2d 3b 0a 20 20 20 20 20 20 20 20 2a 70 70 20  --;.        *pp 
30b0: 3d 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 3b 0a  = pPage->pNext;.
30c0: 20 20 20 20 20 20 20 20 70 63 61 63 68 65 31 50          pcache1P
30d0: 69 6e 50 61 67 65 28 70 50 61 67 65 29 3b 0a 20  inPage(pPage);. 
30e0: 20 20 20 20 20 20 20 70 63 61 63 68 65 31 46 72         pcache1Fr
30f0: 65 65 50 61 67 65 28 70 50 61 67 65 29 3b 0a 20  eePage(pPage);. 
3100: 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
3110: 20 20 20 20 70 70 20 3d 20 26 70 50 61 67 65 2d      pp = &pPage-
3120: 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 20 20  >pNext;.        
3130: 54 45 53 54 4f 4e 4c 59 28 20 6e 50 61 67 65 2b  TESTONLY( nPage+
3140: 2b 3b 20 29 0a 20 20 20 20 20 20 7d 0a 20 20 20  +; ).      }.   
3150: 20 7d 0a 20 20 7d 0a 20 20 61 73 73 65 72 74 28   }.  }.  assert(
3160: 20 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 3d 3d   pCache->nPage==
3170: 6e 50 61 67 65 20 29 3b 0a 7d 0a 0a 2f 2a 2a 2a  nPage );.}../***
3180: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3190: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
31a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
31b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
31c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 2a  ***********/./**
31d0: 2a 2a 2a 2a 2a 2a 20 73 71 6c 69 74 65 33 5f 70  ****** sqlite3_p
31e0: 63 61 63 68 65 20 4d 65 74 68 6f 64 73 20 2a 2a  cache Methods **
31f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3200: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3210: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f  ************/../
3220: 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74  *.** Implementat
3230: 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74  ion of the sqlit
3240: 65 33 5f 70 63 61 63 68 65 2e 78 49 6e 69 74 20  e3_pcache.xInit 
3250: 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69  method..*/.stati
3260: 63 20 69 6e 74 20 70 63 61 63 68 65 31 49 6e 69  c int pcache1Ini
3270: 74 28 76 6f 69 64 20 2a 4e 6f 74 55 73 65 64 29  t(void *NotUsed)
3280: 7b 0a 20 20 55 4e 55 53 45 44 5f 50 41 52 41 4d  {.  UNUSED_PARAM
3290: 45 54 45 52 28 4e 6f 74 55 73 65 64 29 3b 0a 20  ETER(NotUsed);. 
32a0: 20 61 73 73 65 72 74 28 20 70 63 61 63 68 65 31   assert( pcache1
32b0: 2e 69 73 49 6e 69 74 3d 3d 30 20 29 3b 0a 20 20  .isInit==0 );.  
32c0: 6d 65 6d 73 65 74 28 26 70 63 61 63 68 65 31 2c  memset(&pcache1,
32d0: 20 30 2c 20 73 69 7a 65 6f 66 28 70 63 61 63 68   0, sizeof(pcach
32e0: 65 31 29 29 3b 0a 20 20 69 66 28 20 73 71 6c 69  e1));.  if( sqli
32f0: 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e  te3GlobalConfig.
3300: 62 43 6f 72 65 4d 75 74 65 78 20 29 7b 0a 20 20  bCoreMutex ){.  
3310: 20 20 70 63 61 63 68 65 31 2e 6d 75 74 65 78 20    pcache1.mutex 
3320: 3d 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f  = sqlite3_mutex_
3330: 61 6c 6c 6f 63 28 53 51 4c 49 54 45 5f 4d 55 54  alloc(SQLITE_MUT
3340: 45 58 5f 53 54 41 54 49 43 5f 4c 52 55 29 3b 0a  EX_STATIC_LRU);.
3350: 20 20 7d 0a 20 20 70 63 61 63 68 65 31 2e 69 73    }.  pcache1.is
3360: 49 6e 69 74 20 3d 20 31 3b 0a 20 20 72 65 74 75  Init = 1;.  retu
3370: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a  rn SQLITE_OK;.}.
3380: 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74  ./*.** Implement
3390: 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c  ation of the sql
33a0: 69 74 65 33 5f 70 63 61 63 68 65 2e 78 53 68 75  ite3_pcache.xShu
33b0: 74 64 6f 77 6e 20 6d 65 74 68 6f 64 2e 0a 2a 2a  tdown method..**
33c0: 20 4e 6f 74 65 20 74 68 61 74 20 74 68 65 20 73   Note that the s
33d0: 74 61 74 69 63 20 6d 75 74 65 78 20 61 6c 6c 6f  tatic mutex allo
33e0: 63 61 74 65 64 20 69 6e 20 78 49 6e 69 74 20 64  cated in xInit d
33f0: 6f 65 73 20 0a 2a 2a 20 6e 6f 74 20 6e 65 65 64  oes .** not need
3400: 20 74 6f 20 62 65 20 66 72 65 65 64 2e 0a 2a 2f   to be freed..*/
3410: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61  .static void pca
3420: 63 68 65 31 53 68 75 74 64 6f 77 6e 28 76 6f 69  che1Shutdown(voi
3430: 64 20 2a 4e 6f 74 55 73 65 64 29 7b 0a 20 20 55  d *NotUsed){.  U
3440: 4e 55 53 45 44 5f 50 41 52 41 4d 45 54 45 52 28  NUSED_PARAMETER(
3450: 4e 6f 74 55 73 65 64 29 3b 0a 20 20 61 73 73 65  NotUsed);.  asse
3460: 72 74 28 20 70 63 61 63 68 65 31 2e 69 73 49 6e  rt( pcache1.isIn
3470: 69 74 21 3d 30 20 29 3b 0a 20 20 6d 65 6d 73 65  it!=0 );.  memse
3480: 74 28 26 70 63 61 63 68 65 31 2c 20 30 2c 20 73  t(&pcache1, 0, s
3490: 69 7a 65 6f 66 28 70 63 61 63 68 65 31 29 29 3b  izeof(pcache1));
34a0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d  .}../*.** Implem
34b0: 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20  entation of the 
34c0: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78  sqlite3_pcache.x
34d0: 43 72 65 61 74 65 20 6d 65 74 68 6f 64 2e 0a 2a  Create method..*
34e0: 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65 20 61 20  *.** Allocate a 
34f0: 6e 65 77 20 63 61 63 68 65 2e 0a 2a 2f 0a 73 74  new cache..*/.st
3500: 61 74 69 63 20 73 71 6c 69 74 65 33 5f 70 63 61  atic sqlite3_pca
3510: 63 68 65 20 2a 70 63 61 63 68 65 31 43 72 65 61  che *pcache1Crea
3520: 74 65 28 69 6e 74 20 73 7a 50 61 67 65 2c 20 69  te(int szPage, i
3530: 6e 74 20 62 50 75 72 67 65 61 62 6c 65 29 7b 0a  nt bPurgeable){.
3540: 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68    PCache1 *pCach
3550: 65 3b 0a 0a 20 20 70 43 61 63 68 65 20 3d 20 28  e;..  pCache = (
3560: 50 43 61 63 68 65 31 20 2a 29 73 71 6c 69 74 65  PCache1 *)sqlite
3570: 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28  3_malloc(sizeof(
3580: 50 43 61 63 68 65 31 29 29 3b 0a 20 20 69 66 28  PCache1));.  if(
3590: 20 70 43 61 63 68 65 20 29 7b 0a 20 20 20 20 6d   pCache ){.    m
35a0: 65 6d 73 65 74 28 70 43 61 63 68 65 2c 20 30 2c  emset(pCache, 0,
35b0: 20 73 69 7a 65 6f 66 28 50 43 61 63 68 65 31 29   sizeof(PCache1)
35c0: 29 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 73  );.    pCache->s
35d0: 7a 50 61 67 65 20 3d 20 73 7a 50 61 67 65 3b 0a  zPage = szPage;.
35e0: 20 20 20 20 70 43 61 63 68 65 2d 3e 62 50 75 72      pCache->bPur
35f0: 67 65 61 62 6c 65 20 3d 20 28 62 50 75 72 67 65  geable = (bPurge
3600: 61 62 6c 65 20 3f 20 31 20 3a 20 30 29 3b 0a 20  able ? 1 : 0);. 
3610: 20 20 20 69 66 28 20 62 50 75 72 67 65 61 62 6c     if( bPurgeabl
3620: 65 20 29 7b 0a 20 20 20 20 20 20 70 43 61 63 68  e ){.      pCach
3630: 65 2d 3e 6e 4d 69 6e 20 3d 20 31 30 3b 0a 20 20  e->nMin = 10;.  
3640: 20 20 20 20 70 63 61 63 68 65 31 45 6e 74 65 72      pcache1Enter
3650: 4d 75 74 65 78 28 29 3b 0a 20 20 20 20 20 20 70  Mutex();.      p
3660: 63 61 63 68 65 31 2e 6e 4d 69 6e 50 61 67 65 20  cache1.nMinPage 
3670: 2b 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 3b  += pCache->nMin;
3680: 0a 20 20 20 20 20 20 70 63 61 63 68 65 31 4c 65  .      pcache1Le
3690: 61 76 65 4d 75 74 65 78 28 29 3b 0a 20 20 20 20  aveMutex();.    
36a0: 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 28  }.  }.  return (
36b0: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a  sqlite3_pcache *
36c0: 29 70 43 61 63 68 65 3b 0a 7d 0a 0a 2f 2a 0a 2a  )pCache;.}../*.*
36d0: 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  * Implementation
36e0: 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f   of the sqlite3_
36f0: 70 63 61 63 68 65 2e 78 43 61 63 68 65 73 69 7a  pcache.xCachesiz
3700: 65 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a  e method. .**.**
3710: 20 43 6f 6e 66 69 67 75 72 65 20 74 68 65 20 63   Configure the c
3720: 61 63 68 65 5f 73 69 7a 65 20 6c 69 6d 69 74 20  ache_size limit 
3730: 66 6f 72 20 61 20 63 61 63 68 65 2e 0a 2a 2f 0a  for a cache..*/.
3740: 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63  static void pcac
3750: 68 65 31 43 61 63 68 65 73 69 7a 65 28 73 71 6c  he1Cachesize(sql
3760: 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70 2c 20  ite3_pcache *p, 
3770: 69 6e 74 20 6e 4d 61 78 29 7b 0a 20 20 50 43 61  int nMax){.  PCa
3780: 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28  che1 *pCache = (
3790: 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20 20 69  PCache1 *)p;.  i
37a0: 66 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67  f( pCache->bPurg
37b0: 65 61 62 6c 65 20 29 7b 0a 20 20 20 20 70 63 61  eable ){.    pca
37c0: 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 29  che1EnterMutex()
37d0: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 6e 4d  ;.    pcache1.nM
37e0: 61 78 50 61 67 65 20 2b 3d 20 28 6e 4d 61 78 20  axPage += (nMax 
37f0: 2d 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 29 3b  - pCache->nMax);
3800: 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 6e 4d 61  .    pCache->nMa
3810: 78 20 3d 20 6e 4d 61 78 3b 0a 20 20 20 20 70 63  x = nMax;.    pc
3820: 61 63 68 65 31 45 6e 66 6f 72 63 65 4d 61 78 50  ache1EnforceMaxP
3830: 61 67 65 28 29 3b 0a 20 20 20 20 70 63 61 63 68  age();.    pcach
3840: 65 31 4c 65 61 76 65 4d 75 74 65 78 28 29 3b 0a  e1LeaveMutex();.
3850: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70    }.}../*.** Imp
3860: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74  lementation of t
3870: 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68  he sqlite3_pcach
3880: 65 2e 78 50 61 67 65 63 6f 75 6e 74 20 6d 65 74  e.xPagecount met
3890: 68 6f 64 2e 20 0a 2a 2f 0a 73 74 61 74 69 63 20  hod. .*/.static 
38a0: 69 6e 74 20 70 63 61 63 68 65 31 50 61 67 65 63  int pcache1Pagec
38b0: 6f 75 6e 74 28 73 71 6c 69 74 65 33 5f 70 63 61  ount(sqlite3_pca
38c0: 63 68 65 20 2a 70 29 7b 0a 20 20 69 6e 74 20 6e  che *p){.  int n
38d0: 3b 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65 72  ;.  pcache1Enter
38e0: 4d 75 74 65 78 28 29 3b 0a 20 20 6e 20 3d 20 28  Mutex();.  n = (
38f0: 28 50 43 61 63 68 65 31 20 2a 29 70 29 2d 3e 6e  (PCache1 *)p)->n
3900: 50 61 67 65 3b 0a 20 20 70 63 61 63 68 65 31 4c  Page;.  pcache1L
3910: 65 61 76 65 4d 75 74 65 78 28 29 3b 0a 20 20 72  eaveMutex();.  r
3920: 65 74 75 72 6e 20 6e 3b 0a 7d 0a 0a 2f 2a 0a 2a  eturn n;.}../*.*
3930: 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  * Implementation
3940: 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f   of the sqlite3_
3950: 70 63 61 63 68 65 2e 78 46 65 74 63 68 20 6d 65  pcache.xFetch me
3960: 74 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20 46 65 74  thod. .**.** Fet
3970: 63 68 20 61 20 70 61 67 65 20 62 79 20 6b 65 79  ch a page by key
3980: 20 76 61 6c 75 65 2e 0a 2a 2a 0a 2a 2a 20 57 68   value..**.** Wh
3990: 65 74 68 65 72 20 6f 72 20 6e 6f 74 20 61 20 6e  ether or not a n
39a0: 65 77 20 70 61 67 65 20 6d 61 79 20 62 65 20 61  ew page may be a
39b0: 6c 6c 6f 63 61 74 65 64 20 62 79 20 74 68 69 73  llocated by this
39c0: 20 66 75 6e 63 74 69 6f 6e 20 64 65 70 65 6e 64   function depend
39d0: 73 20 6f 6e 0a 2a 2a 20 74 68 65 20 76 61 6c 75  s on.** the valu
39e0: 65 20 6f 66 20 74 68 65 20 63 72 65 61 74 65 46  e of the createF
39f0: 6c 61 67 20 61 72 67 75 6d 65 6e 74 2e 20 20 30  lag argument.  0
3a00: 20 6d 65 61 6e 73 20 64 6f 20 6e 6f 74 20 61 6c   means do not al
3a10: 6c 6f 63 61 74 65 20 61 20 6e 65 77 0a 2a 2a 20  locate a new.** 
3a20: 70 61 67 65 2e 20 20 31 20 6d 65 61 6e 73 20 61  page.  1 means a
3a30: 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 70 61  llocate a new pa
3a40: 67 65 20 69 66 20 73 70 61 63 65 20 69 73 20 65  ge if space is e
3a50: 61 73 69 6c 79 20 61 76 61 69 6c 61 62 6c 65 2e  asily available.
3a60: 20 20 32 20 0a 2a 2a 20 6d 65 61 6e 73 20 74 6f    2 .** means to
3a70: 20 74 72 79 20 72 65 61 6c 6c 79 20 68 61 72 64   try really hard
3a80: 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e   to allocate a n
3a90: 65 77 20 70 61 67 65 2e 0a 2a 2a 0a 2a 2a 20 46  ew page..**.** F
3aa0: 6f 72 20 61 20 6e 6f 6e 2d 70 75 72 67 65 61 62  or a non-purgeab
3ab0: 6c 65 20 63 61 63 68 65 20 28 61 20 63 61 63 68  le cache (a cach
3ac0: 65 20 75 73 65 64 20 61 73 20 74 68 65 20 73 74  e used as the st
3ad0: 6f 72 61 67 65 20 66 6f 72 20 61 6e 20 69 6e 2d  orage for an in-
3ae0: 6d 65 6d 6f 72 79 0a 2a 2a 20 64 61 74 61 62 61  memory.** databa
3af0: 73 65 29 20 74 68 65 72 65 20 69 73 20 72 65 61  se) there is rea
3b00: 6c 6c 79 20 6e 6f 20 64 69 66 66 65 72 65 6e 63  lly no differenc
3b10: 65 20 62 65 74 77 65 65 6e 20 63 72 65 61 74 65  e between create
3b20: 46 6c 61 67 20 31 20 61 6e 64 20 32 2e 20 20 53  Flag 1 and 2.  S
3b30: 6f 0a 2a 2a 20 74 68 65 20 63 61 6c 6c 69 6e 67  o.** the calling
3b40: 20 66 75 6e 63 74 69 6f 6e 20 28 70 63 61 63 68   function (pcach
3b50: 65 2e 63 29 20 77 69 6c 6c 20 6e 65 76 65 72 20  e.c) will never 
3b60: 68 61 76 65 20 61 20 63 72 65 61 74 65 46 6c 61  have a createFla
3b70: 67 20 6f 66 20 31 20 6f 6e 0a 2a 2a 20 61 20 6e  g of 1 on.** a n
3b80: 6f 6e 2d 70 75 72 67 61 62 6c 65 20 63 61 63 68  on-purgable cach
3b90: 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 72 65 20 61  e..**.** There a
3ba0: 72 65 20 74 68 72 65 65 20 64 69 66 66 65 72 65  re three differe
3bb0: 6e 74 20 61 70 70 72 6f 61 63 68 65 73 20 74 6f  nt approaches to
3bc0: 20 6f 62 74 61 69 6e 69 6e 67 20 73 70 61 63 65   obtaining space
3bd0: 20 66 6f 72 20 61 20 70 61 67 65 2c 0a 2a 2a 20   for a page,.** 
3be0: 64 65 70 65 6e 64 69 6e 67 20 6f 6e 20 74 68 65  depending on the
3bf0: 20 76 61 6c 75 65 20 6f 66 20 70 61 72 61 6d 65   value of parame
3c00: 74 65 72 20 63 72 65 61 74 65 46 6c 61 67 20 28  ter createFlag (
3c10: 77 68 69 63 68 20 6d 61 79 20 62 65 20 30 2c 20  which may be 0, 
3c20: 31 20 6f 72 20 32 29 2e 0a 2a 2a 0a 2a 2a 20 20  1 or 2)..**.**  
3c30: 20 31 2e 20 52 65 67 61 72 64 6c 65 73 73 20 6f   1. Regardless o
3c40: 66 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20 63  f the value of c
3c50: 72 65 61 74 65 46 6c 61 67 2c 20 74 68 65 20 63  reateFlag, the c
3c60: 61 63 68 65 20 69 73 20 73 65 61 72 63 68 65 64  ache is searched
3c70: 20 66 6f 72 20 61 20 0a 2a 2a 20 20 20 20 20 20   for a .**      
3c80: 63 6f 70 79 20 6f 66 20 74 68 65 20 72 65 71 75  copy of the requ
3c90: 65 73 74 65 64 20 70 61 67 65 2e 20 49 66 20 6f  ested page. If o
3ca0: 6e 65 20 69 73 20 66 6f 75 6e 64 2c 20 69 74 20  ne is found, it 
3cb0: 69 73 20 72 65 74 75 72 6e 65 64 2e 0a 2a 2a 0a  is returned..**.
3cc0: 2a 2a 20 20 20 32 2e 20 49 66 20 63 72 65 61 74  **   2. If creat
3cd0: 65 46 6c 61 67 3d 3d 30 20 61 6e 64 20 74 68 65  eFlag==0 and the
3ce0: 20 70 61 67 65 20 69 73 20 6e 6f 74 20 61 6c 72   page is not alr
3cf0: 65 61 64 79 20 69 6e 20 74 68 65 20 63 61 63 68  eady in the cach
3d00: 65 2c 20 4e 55 4c 4c 20 69 73 0a 2a 2a 20 20 20  e, NULL is.**   
3d10: 20 20 20 72 65 74 75 72 6e 65 64 2e 0a 2a 2a 0a     returned..**.
3d20: 2a 2a 20 20 20 33 2e 20 49 66 20 63 72 65 61 74  **   3. If creat
3d30: 65 46 6c 61 67 20 69 73 20 31 2c 20 61 6e 64 20  eFlag is 1, and 
3d40: 74 68 65 20 70 61 67 65 20 69 73 20 6e 6f 74 20  the page is not 
3d50: 61 6c 72 65 61 64 79 20 69 6e 20 74 68 65 20 63  already in the c
3d60: 61 63 68 65 2c 0a 2a 2a 20 20 20 20 20 20 61 6e  ache,.**      an
3d70: 64 20 69 66 20 65 69 74 68 65 72 20 6f 66 20 74  d if either of t
3d80: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 61 72 65  he following are
3d90: 20 74 72 75 65 2c 20 72 65 74 75 72 6e 20 4e 55   true, return NU
3da0: 4c 4c 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20  LL:.**.**       
3db0: 28 61 29 20 74 68 65 20 6e 75 6d 62 65 72 20 6f  (a) the number o
3dc0: 66 20 70 61 67 65 73 20 70 69 6e 6e 65 64 20 62  f pages pinned b
3dd0: 79 20 74 68 65 20 63 61 63 68 65 20 69 73 20 67  y the cache is g
3de0: 72 65 61 74 65 72 20 74 68 61 6e 0a 2a 2a 20 20  reater than.**  
3df0: 20 20 20 20 20 20 20 20 20 50 43 61 63 68 65 31           PCache1
3e00: 2e 6e 4d 61 78 2c 20 6f 72 0a 2a 2a 20 20 20 20  .nMax, or.**    
3e10: 20 20 20 28 62 29 20 74 68 65 20 6e 75 6d 62 65     (b) the numbe
3e20: 72 20 6f 66 20 70 61 67 65 73 20 70 69 6e 6e 65  r of pages pinne
3e30: 64 20 62 79 20 74 68 65 20 63 61 63 68 65 20 69  d by the cache i
3e40: 73 20 67 72 65 61 74 65 72 20 74 68 61 6e 0a 2a  s greater than.*
3e50: 2a 20 20 20 20 20 20 20 20 20 20 20 74 68 65 20  *           the 
3e60: 73 75 6d 20 6f 66 20 6e 4d 61 78 20 66 6f 72 20  sum of nMax for 
3e70: 61 6c 6c 20 70 75 72 67 65 61 62 6c 65 20 63 61  all purgeable ca
3e80: 63 68 65 73 2c 20 6c 65 73 73 20 74 68 65 20 73  ches, less the s
3e90: 75 6d 20 6f 66 20 0a 2a 2a 20 20 20 20 20 20 20  um of .**       
3ea0: 20 20 20 20 6e 4d 69 6e 20 66 6f 72 20 61 6c 6c      nMin for all
3eb0: 20 6f 74 68 65 72 20 70 75 72 67 65 61 62 6c 65   other purgeable
3ec0: 20 63 61 63 68 65 73 2e 20 0a 2a 2a 0a 2a 2a 20   caches. .**.** 
3ed0: 20 20 34 2e 20 49 66 20 6e 6f 6e 65 20 6f 66 20    4. If none of 
3ee0: 74 68 65 20 66 69 72 73 74 20 74 68 72 65 65 20  the first three 
3ef0: 63 6f 6e 64 69 74 69 6f 6e 73 20 61 70 70 6c 79  conditions apply
3f00: 20 61 6e 64 20 74 68 65 20 63 61 63 68 65 20 69   and the cache i
3f10: 73 20 6d 61 72 6b 65 64 0a 2a 2a 20 20 20 20 20  s marked.**     
3f20: 20 61 73 20 70 75 72 67 65 61 62 6c 65 2c 20 61   as purgeable, a
3f30: 6e 64 20 69 66 20 6f 6e 65 20 6f 66 20 74 68 65  nd if one of the
3f40: 20 66 6f 6c 6c 6f 77 69 6e 67 20 69 73 20 74 72   following is tr
3f50: 75 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20  ue:.**.**       
3f60: 28 61 29 20 54 68 65 20 6e 75 6d 62 65 72 20 6f  (a) The number o
3f70: 66 20 70 61 67 65 73 20 61 6c 6c 6f 63 61 74 65  f pages allocate
3f80: 64 20 66 6f 72 20 74 68 65 20 63 61 63 68 65 20  d for the cache 
3f90: 69 73 20 61 6c 72 65 61 64 79 20 0a 2a 2a 20 20  is already .**  
3fa0: 20 20 20 20 20 20 20 20 20 50 43 61 63 68 65 31           PCache1
3fb0: 2e 6e 4d 61 78 2c 20 6f 72 0a 2a 2a 0a 2a 2a 20  .nMax, or.**.** 
3fc0: 20 20 20 20 20 20 28 62 29 20 54 68 65 20 6e 75        (b) The nu
3fd0: 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 61 6c  mber of pages al
3fe0: 6c 6f 63 61 74 65 64 20 66 6f 72 20 61 6c 6c 20  located for all 
3ff0: 70 75 72 67 65 61 62 6c 65 20 63 61 63 68 65 73  purgeable caches
4000: 20 69 73 0a 2a 2a 20 20 20 20 20 20 20 20 20 20   is.**          
4010: 20 61 6c 72 65 61 64 79 20 65 71 75 61 6c 20 74   already equal t
4020: 6f 20 6f 72 20 67 72 65 61 74 65 72 20 74 68 61  o or greater tha
4030: 6e 20 74 68 65 20 73 75 6d 20 6f 66 20 6e 4d 61  n the sum of nMa
4040: 78 20 66 6f 72 20 61 6c 6c 0a 2a 2a 20 20 20 20  x for all.**    
4050: 20 20 20 20 20 20 20 70 75 72 67 65 61 62 6c 65         purgeable
4060: 20 63 61 63 68 65 73 2c 0a 2a 2a 0a 2a 2a 20 20   caches,.**.**  
4070: 20 20 20 20 74 68 65 6e 20 61 74 74 65 6d 70 74      then attempt
4080: 20 74 6f 20 72 65 63 79 63 6c 65 20 61 20 70 61   to recycle a pa
4090: 67 65 20 66 72 6f 6d 20 74 68 65 20 4c 52 55 20  ge from the LRU 
40a0: 6c 69 73 74 2e 20 49 66 20 69 74 20 69 73 20 74  list. If it is t
40b0: 68 65 20 72 69 67 68 74 0a 2a 2a 20 20 20 20 20  he right.**     
40c0: 20 73 69 7a 65 2c 20 72 65 74 75 72 6e 20 74 68   size, return th
40d0: 65 20 72 65 63 79 63 6c 65 64 20 62 75 66 66 65  e recycled buffe
40e0: 72 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 66 72  r. Otherwise, fr
40f0: 65 65 20 74 68 65 20 62 75 66 66 65 72 20 61 6e  ee the buffer an
4100: 64 0a 2a 2a 20 20 20 20 20 20 70 72 6f 63 65 65  d.**      procee
4110: 64 20 74 6f 20 73 74 65 70 20 35 2e 20 0a 2a 2a  d to step 5. .**
4120: 0a 2a 2a 20 20 20 35 2e 20 4f 74 68 65 72 77 69  .**   5. Otherwi
4130: 73 65 2c 20 61 6c 6c 6f 63 61 74 65 20 61 6e 64  se, allocate and
4140: 20 72 65 74 75 72 6e 20 61 20 6e 65 77 20 70 61   return a new pa
4150: 67 65 20 62 75 66 66 65 72 2e 0a 2a 2f 0a 73 74  ge buffer..*/.st
4160: 61 74 69 63 20 76 6f 69 64 20 2a 70 63 61 63 68  atic void *pcach
4170: 65 31 46 65 74 63 68 28 73 71 6c 69 74 65 33 5f  e1Fetch(sqlite3_
4180: 70 63 61 63 68 65 20 2a 70 2c 20 75 6e 73 69 67  pcache *p, unsig
4190: 6e 65 64 20 69 6e 74 20 69 4b 65 79 2c 20 69 6e  ned int iKey, in
41a0: 74 20 63 72 65 61 74 65 46 6c 61 67 29 7b 0a 20  t createFlag){. 
41b0: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 50   unsigned int nP
41c0: 69 6e 6e 65 64 3b 0a 20 20 50 43 61 63 68 65 31  inned;.  PCache1
41d0: 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61 63   *pCache = (PCac
41e0: 68 65 31 20 2a 29 70 3b 0a 20 20 50 67 48 64 72  he1 *)p;.  PgHdr
41f0: 31 20 2a 70 50 61 67 65 20 3d 20 30 3b 0a 0a 20  1 *pPage = 0;.. 
4200: 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65 2d   assert( pCache-
4210: 3e 62 50 75 72 67 65 61 62 6c 65 20 7c 7c 20 63  >bPurgeable || c
4220: 72 65 61 74 65 46 6c 61 67 21 3d 31 20 29 3b 0a  reateFlag!=1 );.
4230: 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75    pcache1EnterMu
4240: 74 65 78 28 29 3b 0a 20 20 69 66 28 20 63 72 65  tex();.  if( cre
4250: 61 74 65 46 6c 61 67 3d 3d 31 20 29 20 73 71 6c  ateFlag==1 ) sql
4260: 69 74 65 33 42 65 67 69 6e 42 65 6e 69 67 6e 4d  ite3BeginBenignM
4270: 61 6c 6c 6f 63 28 29 3b 0a 0a 20 20 2f 2a 20 53  alloc();..  /* S
4280: 65 61 72 63 68 20 74 68 65 20 68 61 73 68 20 74  earch the hash t
4290: 61 62 6c 65 20 66 6f 72 20 61 6e 20 65 78 69 73  able for an exis
42a0: 74 69 6e 67 20 65 6e 74 72 79 2e 20 2a 2f 0a 20  ting entry. */. 
42b0: 20 69 66 28 20 70 43 61 63 68 65 2d 3e 6e 48 61   if( pCache->nHa
42c0: 73 68 3e 30 20 29 7b 0a 20 20 20 20 75 6e 73 69  sh>0 ){.    unsi
42d0: 67 6e 65 64 20 69 6e 74 20 68 20 3d 20 69 4b 65  gned int h = iKe
42e0: 79 20 25 20 70 43 61 63 68 65 2d 3e 6e 48 61 73  y % pCache->nHas
42f0: 68 3b 0a 20 20 20 20 66 6f 72 28 70 50 61 67 65  h;.    for(pPage
4300: 3d 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b  =pCache->apHash[
4310: 68 5d 3b 20 70 50 61 67 65 26 26 70 50 61 67 65  h]; pPage&&pPage
4320: 2d 3e 69 4b 65 79 21 3d 69 4b 65 79 3b 20 70 50  ->iKey!=iKey; pP
4330: 61 67 65 3d 70 50 61 67 65 2d 3e 70 4e 65 78 74  age=pPage->pNext
4340: 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 50  );.  }..  if( pP
4350: 61 67 65 20 7c 7c 20 63 72 65 61 74 65 46 6c 61  age || createFla
4360: 67 3d 3d 30 20 29 7b 0a 20 20 20 20 70 63 61 63  g==0 ){.    pcac
4370: 68 65 31 50 69 6e 50 61 67 65 28 70 50 61 67 65  he1PinPage(pPage
4380: 29 3b 0a 20 20 20 20 67 6f 74 6f 20 66 65 74 63  );.    goto fetc
4390: 68 5f 6f 75 74 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  h_out;.  }..  /*
43a0: 20 53 74 65 70 20 33 20 6f 66 20 68 65 61 64 65   Step 3 of heade
43b0: 72 20 63 6f 6d 6d 65 6e 74 2e 20 2a 2f 0a 20 20  r comment. */.  
43c0: 6e 50 69 6e 6e 65 64 20 3d 20 70 43 61 63 68 65  nPinned = pCache
43d0: 2d 3e 6e 50 61 67 65 20 2d 20 70 43 61 63 68 65  ->nPage - pCache
43e0: 2d 3e 6e 52 65 63 79 63 6c 61 62 6c 65 3b 0a 20  ->nRecyclable;. 
43f0: 20 69 66 28 20 63 72 65 61 74 65 46 6c 61 67 3d   if( createFlag=
4400: 3d 31 20 26 26 20 28 0a 20 20 20 20 20 20 20 20  =1 && (.        
4410: 6e 50 69 6e 6e 65 64 3e 3d 28 70 63 61 63 68 65  nPinned>=(pcache
4420: 31 2e 6e 4d 61 78 50 61 67 65 2b 70 43 61 63 68  1.nMaxPage+pCach
4430: 65 2d 3e 6e 4d 69 6e 2d 70 63 61 63 68 65 31 2e  e->nMin-pcache1.
4440: 6e 4d 69 6e 50 61 67 65 29 0a 20 20 20 20 20 7c  nMinPage).     |
4450: 7c 20 6e 50 69 6e 6e 65 64 3e 3d 28 70 43 61 63  | nPinned>=(pCac
4460: 68 65 2d 3e 6e 4d 61 78 20 2a 20 39 20 2f 20 31  he->nMax * 9 / 1
4470: 30 29 0a 20 20 29 29 7b 0a 20 20 20 20 67 6f 74  0).  )){.    got
4480: 6f 20 66 65 74 63 68 5f 6f 75 74 3b 0a 20 20 7d  o fetch_out;.  }
4490: 0a 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e  ..  if( pCache->
44a0: 6e 50 61 67 65 3e 3d 70 43 61 63 68 65 2d 3e 6e  nPage>=pCache->n
44b0: 48 61 73 68 20 26 26 20 70 63 61 63 68 65 31 52  Hash && pcache1R
44c0: 65 73 69 7a 65 48 61 73 68 28 70 43 61 63 68 65  esizeHash(pCache
44d0: 29 20 29 7b 0a 20 20 20 20 67 6f 74 6f 20 66 65  ) ){.    goto fe
44e0: 74 63 68 5f 6f 75 74 3b 0a 20 20 7d 0a 0a 20 20  tch_out;.  }..  
44f0: 2f 2a 20 53 74 65 70 20 34 2e 20 54 72 79 20 74  /* Step 4. Try t
4500: 6f 20 72 65 63 79 63 6c 65 20 61 20 70 61 67 65  o recycle a page
4510: 20 62 75 66 66 65 72 20 69 66 20 61 70 70 72 6f   buffer if appro
4520: 70 72 69 61 74 65 2e 20 2a 2f 0a 20 20 69 66 28  priate. */.  if(
4530: 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61   pCache->bPurgea
4540: 62 6c 65 20 26 26 20 70 63 61 63 68 65 31 2e 70  ble && pcache1.p
4550: 4c 72 75 54 61 69 6c 20 26 26 20 28 0a 20 20 20  LruTail && (.   
4560: 20 20 28 70 43 61 63 68 65 2d 3e 6e 50 61 67 65    (pCache->nPage
4570: 2b 31 3e 3d 70 43 61 63 68 65 2d 3e 6e 4d 61 78  +1>=pCache->nMax
4580: 29 20 7c 7c 20 70 63 61 63 68 65 31 2e 6e 43 75  ) || pcache1.nCu
4590: 72 72 65 6e 74 50 61 67 65 3e 3d 70 63 61 63 68  rrentPage>=pcach
45a0: 65 31 2e 6e 4d 61 78 50 61 67 65 0a 20 20 29 29  e1.nMaxPage.  ))
45b0: 7b 0a 20 20 20 20 70 50 61 67 65 20 3d 20 70 63  {.    pPage = pc
45c0: 61 63 68 65 31 2e 70 4c 72 75 54 61 69 6c 3b 0a  ache1.pLruTail;.
45d0: 20 20 20 20 70 63 61 63 68 65 31 52 65 6d 6f 76      pcache1Remov
45e0: 65 46 72 6f 6d 48 61 73 68 28 70 50 61 67 65 29  eFromHash(pPage)
45f0: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 50 69 6e  ;.    pcache1Pin
4600: 50 61 67 65 28 70 50 61 67 65 29 3b 0a 20 20 20  Page(pPage);.   
4610: 20 69 66 28 20 70 50 61 67 65 2d 3e 70 43 61 63   if( pPage->pCac
4620: 68 65 2d 3e 73 7a 50 61 67 65 21 3d 70 43 61 63  he->szPage!=pCac
4630: 68 65 2d 3e 73 7a 50 61 67 65 20 29 7b 0a 20 20  he->szPage ){.  
4640: 20 20 20 20 70 63 61 63 68 65 31 46 72 65 65 50      pcache1FreeP
4650: 61 67 65 28 70 50 61 67 65 29 3b 0a 20 20 20 20  age(pPage);.    
4660: 20 20 70 50 61 67 65 20 3d 20 30 3b 0a 20 20 20    pPage = 0;.   
4670: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 63   }else{.      pc
4680: 61 63 68 65 31 2e 6e 43 75 72 72 65 6e 74 50 61  ache1.nCurrentPa
4690: 67 65 20 2d 3d 20 28 70 50 61 67 65 2d 3e 70 43  ge -= (pPage->pC
46a0: 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65  ache->bPurgeable
46b0: 20 2d 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67   - pCache->bPurg
46c0: 65 61 62 6c 65 29 3b 0a 20 20 20 20 7d 0a 20 20  eable);.    }.  
46d0: 7d 0a 0a 20 20 2f 2a 20 53 74 65 70 20 35 2e 20  }..  /* Step 5. 
46e0: 49 66 20 61 20 75 73 61 62 6c 65 20 70 61 67 65  If a usable page
46f0: 20 62 75 66 66 65 72 20 68 61 73 20 73 74 69 6c   buffer has stil
4700: 6c 20 6e 6f 74 20 62 65 65 6e 20 66 6f 75 6e 64  l not been found
4710: 2c 20 0a 20 20 2a 2a 20 61 74 74 65 6d 70 74 20  , .  ** attempt 
4720: 74 6f 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e 65  to allocate a ne
4730: 77 20 6f 6e 65 2e 20 0a 20 20 2a 2f 0a 20 20 69  w one. .  */.  i
4740: 66 28 20 21 70 50 61 67 65 20 29 7b 0a 20 20 20  f( !pPage ){.   
4750: 20 70 50 61 67 65 20 3d 20 70 63 61 63 68 65 31   pPage = pcache1
4760: 41 6c 6c 6f 63 50 61 67 65 28 70 43 61 63 68 65  AllocPage(pCache
4770: 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 50  );.  }..  if( pP
4780: 61 67 65 20 29 7b 0a 20 20 20 20 75 6e 73 69 67  age ){.    unsig
4790: 6e 65 64 20 69 6e 74 20 68 20 3d 20 69 4b 65 79  ned int h = iKey
47a0: 20 25 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68   % pCache->nHash
47b0: 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 6e 50  ;.    pCache->nP
47c0: 61 67 65 2b 2b 3b 0a 20 20 20 20 70 50 61 67 65  age++;.    pPage
47d0: 2d 3e 69 4b 65 79 20 3d 20 69 4b 65 79 3b 0a 20  ->iKey = iKey;. 
47e0: 20 20 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 20     pPage->pNext 
47f0: 3d 20 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68  = pCache->apHash
4800: 5b 68 5d 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e  [h];.    pPage->
4810: 70 43 61 63 68 65 20 3d 20 70 43 61 63 68 65 3b  pCache = pCache;
4820: 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 4c 72 75  .    pPage->pLru
4830: 50 72 65 76 20 3d 20 30 3b 0a 20 20 20 20 70 50  Prev = 0;.    pP
4840: 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 20 3d 20  age->pLruNext = 
4850: 30 3b 0a 20 20 20 20 2a 28 76 6f 69 64 20 2a 2a  0;.    *(void **
4860: 29 28 50 47 48 44 52 31 5f 54 4f 5f 50 41 47 45  )(PGHDR1_TO_PAGE
4870: 28 70 50 61 67 65 29 29 20 3d 20 30 3b 0a 20 20  (pPage)) = 0;.  
4880: 20 20 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68    pCache->apHash
4890: 5b 68 5d 20 3d 20 70 50 61 67 65 3b 0a 20 20 7d  [h] = pPage;.  }
48a0: 0a 0a 66 65 74 63 68 5f 6f 75 74 3a 0a 20 20 69  ..fetch_out:.  i
48b0: 66 28 20 70 50 61 67 65 20 26 26 20 69 4b 65 79  f( pPage && iKey
48c0: 3e 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79  >pCache->iMaxKey
48d0: 20 29 7b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e   ){.    pCache->
48e0: 69 4d 61 78 4b 65 79 20 3d 20 69 4b 65 79 3b 0a  iMaxKey = iKey;.
48f0: 20 20 7d 0a 20 20 69 66 28 20 63 72 65 61 74 65    }.  if( create
4900: 46 6c 61 67 3d 3d 31 20 29 20 73 71 6c 69 74 65  Flag==1 ) sqlite
4910: 33 45 6e 64 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63  3EndBenignMalloc
4920: 28 29 3b 0a 20 20 70 63 61 63 68 65 31 4c 65 61  ();.  pcache1Lea
4930: 76 65 4d 75 74 65 78 28 29 3b 0a 20 20 72 65 74  veMutex();.  ret
4940: 75 72 6e 20 28 70 50 61 67 65 20 3f 20 50 47 48  urn (pPage ? PGH
4950: 44 52 31 5f 54 4f 5f 50 41 47 45 28 70 50 61 67  DR1_TO_PAGE(pPag
4960: 65 29 20 3a 20 30 29 3b 0a 7d 0a 0a 0a 2f 2a 0a  e) : 0);.}.../*.
4970: 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  ** Implementatio
4980: 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33  n of the sqlite3
4990: 5f 70 63 61 63 68 65 2e 78 55 6e 70 69 6e 20 6d  _pcache.xUnpin m
49a0: 65 74 68 6f 64 2e 0a 2a 2a 0a 2a 2a 20 4d 61 72  ethod..**.** Mar
49b0: 6b 20 61 20 70 61 67 65 20 61 73 20 75 6e 70 69  k a page as unpi
49c0: 6e 6e 65 64 20 28 65 6c 69 67 69 62 6c 65 20 66  nned (eligible f
49d0: 6f 72 20 61 73 79 6e 63 68 72 6f 6e 6f 75 73 20  or asynchronous 
49e0: 72 65 63 79 63 6c 69 6e 67 29 2e 0a 2a 2f 0a 73  recycling)..*/.s
49f0: 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68  tatic void pcach
4a00: 65 31 55 6e 70 69 6e 28 73 71 6c 69 74 65 33 5f  e1Unpin(sqlite3_
4a10: 70 63 61 63 68 65 20 2a 70 2c 20 76 6f 69 64 20  pcache *p, void 
4a20: 2a 70 50 67 2c 20 69 6e 74 20 72 65 75 73 65 55  *pPg, int reuseU
4a30: 6e 6c 69 6b 65 6c 79 29 7b 0a 20 20 50 43 61 63  nlikely){.  PCac
4a40: 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28 50  he1 *pCache = (P
4a50: 43 61 63 68 65 31 20 2a 29 70 3b 0a 20 20 50 67  Cache1 *)p;.  Pg
4a60: 48 64 72 31 20 2a 70 50 61 67 65 20 3d 20 50 41  Hdr1 *pPage = PA
4a70: 47 45 5f 54 4f 5f 50 47 48 44 52 31 28 70 43 61  GE_TO_PGHDR1(pCa
4a80: 63 68 65 2c 20 70 50 67 29 3b 0a 20 0a 20 20 61  che, pPg);. .  a
4a90: 73 73 65 72 74 28 20 70 50 61 67 65 2d 3e 70 43  ssert( pPage->pC
4aa0: 61 63 68 65 3d 3d 70 43 61 63 68 65 20 29 3b 0a  ache==pCache );.
4ab0: 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75    pcache1EnterMu
4ac0: 74 65 78 28 29 3b 0a 0a 20 20 2f 2a 20 49 74 20  tex();..  /* It 
4ad0: 69 73 20 61 6e 20 65 72 72 6f 72 20 74 6f 20 63  is an error to c
4ae0: 61 6c 6c 20 74 68 69 73 20 66 75 6e 63 74 69 6f  all this functio
4af0: 6e 20 69 66 20 74 68 65 20 70 61 67 65 20 69 73  n if the page is
4b00: 20 61 6c 72 65 61 64 79 20 0a 20 20 2a 2a 20 70   already .  ** p
4b10: 61 72 74 20 6f 66 20 74 68 65 20 67 6c 6f 62 61  art of the globa
4b20: 6c 20 4c 52 55 20 6c 69 73 74 2e 0a 20 20 2a 2f  l LRU list..  */
4b30: 0a 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65  .  assert( pPage
4b40: 2d 3e 70 4c 72 75 50 72 65 76 3d 3d 30 20 26 26  ->pLruPrev==0 &&
4b50: 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74   pPage->pLruNext
4b60: 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28  ==0 );.  assert(
4b70: 20 70 63 61 63 68 65 31 2e 70 4c 72 75 48 65 61   pcache1.pLruHea
4b80: 64 21 3d 70 50 61 67 65 20 26 26 20 70 63 61 63  d!=pPage && pcac
4b90: 68 65 31 2e 70 4c 72 75 54 61 69 6c 21 3d 70 50  he1.pLruTail!=pP
4ba0: 61 67 65 20 29 3b 0a 0a 20 20 69 66 28 20 72 65  age );..  if( re
4bb0: 75 73 65 55 6e 6c 69 6b 65 6c 79 20 7c 7c 20 70  useUnlikely || p
4bc0: 63 61 63 68 65 31 2e 6e 43 75 72 72 65 6e 74 50  cache1.nCurrentP
4bd0: 61 67 65 3e 70 63 61 63 68 65 31 2e 6e 4d 61 78  age>pcache1.nMax
4be0: 50 61 67 65 20 29 7b 0a 20 20 20 20 70 63 61 63  Page ){.    pcac
4bf0: 68 65 31 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73  he1RemoveFromHas
4c00: 68 28 70 50 61 67 65 29 3b 0a 20 20 20 20 70 63  h(pPage);.    pc
4c10: 61 63 68 65 31 46 72 65 65 50 61 67 65 28 70 50  ache1FreePage(pP
4c20: 61 67 65 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  age);.  }else{. 
4c30: 20 20 20 2f 2a 20 41 64 64 20 74 68 65 20 70 61     /* Add the pa
4c40: 67 65 20 74 6f 20 74 68 65 20 67 6c 6f 62 61 6c  ge to the global
4c50: 20 4c 52 55 20 6c 69 73 74 2e 20 4e 6f 72 6d 61   LRU list. Norma
4c60: 6c 6c 79 2c 20 74 68 65 20 70 61 67 65 20 69 73  lly, the page is
4c70: 20 61 64 64 65 64 20 74 6f 0a 20 20 20 20 2a 2a   added to.    **
4c80: 20 74 68 65 20 68 65 61 64 20 6f 66 20 74 68 65   the head of the
4c90: 20 6c 69 73 74 20 28 6c 61 73 74 20 70 61 67 65   list (last page
4ca0: 20 74 6f 20 62 65 20 72 65 63 79 63 6c 65 64 29   to be recycled)
4cb0: 2e 20 48 6f 77 65 76 65 72 2c 20 69 66 20 74 68  . However, if th
4cc0: 65 20 0a 20 20 20 20 2a 2a 20 72 65 75 73 65 55  e .    ** reuseU
4cd0: 6e 6c 69 6b 65 6c 79 20 66 6c 61 67 20 70 61 73  nlikely flag pas
4ce0: 73 65 64 20 74 6f 20 74 68 69 73 20 66 75 6e 63  sed to this func
4cf0: 74 69 6f 6e 20 69 73 20 74 72 75 65 2c 20 74 68  tion is true, th
4d00: 65 20 70 61 67 65 20 69 73 20 61 64 64 65 64 0a  e page is added.
4d10: 20 20 20 20 2a 2a 20 74 6f 20 74 68 65 20 74 61      ** to the ta
4d20: 69 6c 20 6f 66 20 74 68 65 20 6c 69 73 74 20 28  il of the list (
4d30: 66 69 72 73 74 20 70 61 67 65 20 74 6f 20 62 65  first page to be
4d40: 20 72 65 63 79 63 6c 65 64 29 2e 0a 20 20 20 20   recycled)..    
4d50: 2a 2f 0a 20 20 20 20 69 66 28 20 70 63 61 63 68  */.    if( pcach
4d60: 65 31 2e 70 4c 72 75 48 65 61 64 20 29 7b 0a 20  e1.pLruHead ){. 
4d70: 20 20 20 20 20 70 63 61 63 68 65 31 2e 70 4c 72       pcache1.pLr
4d80: 75 48 65 61 64 2d 3e 70 4c 72 75 50 72 65 76 20  uHead->pLruPrev 
4d90: 3d 20 70 50 61 67 65 3b 0a 20 20 20 20 20 20 70  = pPage;.      p
4da0: 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 20 3d  Page->pLruNext =
4db0: 20 70 63 61 63 68 65 31 2e 70 4c 72 75 48 65 61   pcache1.pLruHea
4dc0: 64 3b 0a 20 20 20 20 20 20 70 63 61 63 68 65 31  d;.      pcache1
4dd0: 2e 70 4c 72 75 48 65 61 64 20 3d 20 70 50 61 67  .pLruHead = pPag
4de0: 65 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  e;.    }else{.  
4df0: 20 20 20 20 70 63 61 63 68 65 31 2e 70 4c 72 75      pcache1.pLru
4e00: 54 61 69 6c 20 3d 20 70 50 61 67 65 3b 0a 20 20  Tail = pPage;.  
4e10: 20 20 20 20 70 63 61 63 68 65 31 2e 70 4c 72 75      pcache1.pLru
4e20: 48 65 61 64 20 3d 20 70 50 61 67 65 3b 0a 20 20  Head = pPage;.  
4e30: 20 20 7d 0a 20 20 20 20 70 43 61 63 68 65 2d 3e    }.    pCache->
4e40: 6e 52 65 63 79 63 6c 61 62 6c 65 2b 2b 3b 0a 20  nRecyclable++;. 
4e50: 20 7d 0a 0a 20 20 70 63 61 63 68 65 31 4c 65 61   }..  pcache1Lea
4e60: 76 65 4d 75 74 65 78 28 29 3b 0a 7d 0a 0a 2f 2a  veMutex();.}../*
4e70: 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69  .** Implementati
4e80: 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65  on of the sqlite
4e90: 33 5f 70 63 61 63 68 65 2e 78 52 65 6b 65 79 20  3_pcache.xRekey 
4ea0: 6d 65 74 68 6f 64 2e 20 0a 2a 2f 0a 73 74 61 74  method. .*/.stat
4eb0: 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 31 52  ic void pcache1R
4ec0: 65 6b 65 79 28 0a 20 20 73 71 6c 69 74 65 33 5f  ekey(.  sqlite3_
4ed0: 70 63 61 63 68 65 20 2a 70 2c 0a 20 20 76 6f 69  pcache *p,.  voi
4ee0: 64 20 2a 70 50 67 2c 0a 20 20 75 6e 73 69 67 6e  d *pPg,.  unsign
4ef0: 65 64 20 69 6e 74 20 69 4f 6c 64 2c 0a 20 20 75  ed int iOld,.  u
4f00: 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4e 65 77  nsigned int iNew
4f10: 0a 29 7b 0a 20 20 50 43 61 63 68 65 31 20 2a 70  .){.  PCache1 *p
4f20: 43 61 63 68 65 20 3d 20 28 50 43 61 63 68 65 31  Cache = (PCache1
4f30: 20 2a 29 70 3b 0a 20 20 50 67 48 64 72 31 20 2a   *)p;.  PgHdr1 *
4f40: 70 50 61 67 65 20 3d 20 50 41 47 45 5f 54 4f 5f  pPage = PAGE_TO_
4f50: 50 47 48 44 52 31 28 70 43 61 63 68 65 2c 20 70  PGHDR1(pCache, p
4f60: 50 67 29 3b 0a 20 20 50 67 48 64 72 31 20 2a 2a  Pg);.  PgHdr1 **
4f70: 70 70 3b 0a 20 20 75 6e 73 69 67 6e 65 64 20 69  pp;.  unsigned i
4f80: 6e 74 20 68 3b 20 0a 20 20 61 73 73 65 72 74 28  nt h; .  assert(
4f90: 20 70 50 61 67 65 2d 3e 69 4b 65 79 3d 3d 69 4f   pPage->iKey==iO
4fa0: 6c 64 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  ld );.  assert( 
4fb0: 70 50 61 67 65 2d 3e 70 43 61 63 68 65 3d 3d 70  pPage->pCache==p
4fc0: 43 61 63 68 65 20 29 3b 0a 0a 20 20 70 63 61 63  Cache );..  pcac
4fd0: 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 29 3b  he1EnterMutex();
4fe0: 0a 0a 20 20 68 20 3d 20 69 4f 6c 64 25 70 43 61  ..  h = iOld%pCa
4ff0: 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 70 70  che->nHash;.  pp
5000: 20 3d 20 26 70 43 61 63 68 65 2d 3e 61 70 48 61   = &pCache->apHa
5010: 73 68 5b 68 5d 3b 0a 20 20 77 68 69 6c 65 28 20  sh[h];.  while( 
5020: 28 2a 70 70 29 21 3d 70 50 61 67 65 20 29 7b 0a  (*pp)!=pPage ){.
5030: 20 20 20 20 70 70 20 3d 20 26 28 2a 70 70 29 2d      pp = &(*pp)-
5040: 3e 70 4e 65 78 74 3b 0a 20 20 7d 0a 20 20 2a 70  >pNext;.  }.  *p
5050: 70 20 3d 20 70 50 61 67 65 2d 3e 70 4e 65 78 74  p = pPage->pNext
5060: 3b 0a 0a 20 20 68 20 3d 20 69 4e 65 77 25 70 43  ;..  h = iNew%pC
5070: 61 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 70  ache->nHash;.  p
5080: 50 61 67 65 2d 3e 69 4b 65 79 20 3d 20 69 4e 65  Page->iKey = iNe
5090: 77 3b 0a 20 20 70 50 61 67 65 2d 3e 70 4e 65 78  w;.  pPage->pNex
50a0: 74 20 3d 20 70 43 61 63 68 65 2d 3e 61 70 48 61  t = pCache->apHa
50b0: 73 68 5b 68 5d 3b 0a 20 20 70 43 61 63 68 65 2d  sh[h];.  pCache-
50c0: 3e 61 70 48 61 73 68 5b 68 5d 20 3d 20 70 50 61  >apHash[h] = pPa
50d0: 67 65 3b 0a 0a 20 20 2f 2a 20 54 68 65 20 78 52  ge;..  /* The xR
50e0: 65 6b 65 79 28 29 20 69 6e 74 65 72 66 61 63 65  ekey() interface
50f0: 20 69 73 20 6f 6e 6c 79 20 75 73 65 64 20 74 6f   is only used to
5100: 20 6d 6f 76 65 20 70 61 67 65 73 20 65 61 72 6c   move pages earl
5110: 69 65 72 20 69 6e 20 74 68 65 0a 20 20 2a 2a 20  ier in the.  ** 
5120: 64 61 74 61 62 61 73 65 20 66 69 6c 65 20 28 69  database file (i
5130: 6e 20 6f 72 64 65 72 20 74 6f 20 6d 6f 76 65 20  n order to move 
5140: 61 6c 6c 20 66 72 65 65 20 70 61 67 65 73 20 74  all free pages t
5150: 6f 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68 65  o the end of the
5160: 0a 20 20 2a 2a 20 66 69 6c 65 20 77 68 65 72 65  .  ** file where
5170: 20 74 68 65 79 20 63 61 6e 20 62 65 20 74 72 75   they can be tru
5180: 6e 63 61 74 65 64 20 6f 66 66 2e 29 20 20 48 65  ncated off.)  He
5190: 6e 63 65 2c 20 69 74 20 69 73 20 6e 6f 74 20 70  nce, it is not p
51a0: 6f 73 73 69 62 6c 65 0a 20 20 2a 2a 20 66 6f 72  ossible.  ** for
51b0: 20 74 68 65 20 6e 65 77 20 70 61 67 65 20 6e 75   the new page nu
51c0: 6d 62 65 72 20 74 6f 20 62 65 20 67 72 65 61 74  mber to be great
51d0: 65 72 20 74 68 61 6e 20 74 68 65 20 6c 61 72 67  er than the larg
51e0: 65 73 74 20 70 72 65 76 69 6f 75 73 6c 79 0a 20  est previously. 
51f0: 20 2a 2a 20 66 65 74 63 68 65 64 20 70 61 67 65   ** fetched page
5200: 2e 20 20 42 75 74 20 77 65 20 72 65 74 61 69 6e  .  But we retain
5210: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 74   the following t
5220: 65 73 74 20 69 6e 20 63 61 73 65 20 78 52 65 6b  est in case xRek
5230: 65 79 28 29 0a 20 20 2a 2a 20 62 65 67 69 6e 73  ey().  ** begins
5240: 20 74 6f 20 62 65 20 75 73 65 64 20 69 6e 20 64   to be used in d
5250: 69 66 66 65 72 65 6e 74 20 77 61 79 73 20 69 6e  ifferent ways in
5260: 20 74 68 65 20 66 75 74 75 72 65 2e 0a 20 20 2a   the future..  *
5270: 2f 0a 20 20 69 66 28 20 4e 45 56 45 52 28 69 4e  /.  if( NEVER(iN
5280: 65 77 3e 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b  ew>pCache->iMaxK
5290: 65 79 29 20 29 7b 0a 20 20 20 20 70 43 61 63 68  ey) ){.    pCach
52a0: 65 2d 3e 69 4d 61 78 4b 65 79 20 3d 20 69 4e 65  e->iMaxKey = iNe
52b0: 77 3b 0a 20 20 7d 0a 0a 20 20 70 63 61 63 68 65  w;.  }..  pcache
52c0: 31 4c 65 61 76 65 4d 75 74 65 78 28 29 3b 0a 7d  1LeaveMutex();.}
52d0: 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e  ../*.** Implemen
52e0: 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71  tation of the sq
52f0: 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78 54 72  lite3_pcache.xTr
5300: 75 6e 63 61 74 65 20 6d 65 74 68 6f 64 2e 20 0a  uncate method. .
5310: 2a 2a 0a 2a 2a 20 44 69 73 63 61 72 64 20 61 6c  **.** Discard al
5320: 6c 20 75 6e 70 69 6e 6e 65 64 20 70 61 67 65 73  l unpinned pages
5330: 20 69 6e 20 74 68 65 20 63 61 63 68 65 20 77 69   in the cache wi
5340: 74 68 20 61 20 70 61 67 65 20 6e 75 6d 62 65 72  th a page number
5350: 20 65 71 75 61 6c 20 74 6f 0a 2a 2a 20 6f 72 20   equal to.** or 
5360: 67 72 65 61 74 65 72 20 74 68 61 6e 20 70 61 72  greater than par
5370: 61 6d 65 74 65 72 20 69 4c 69 6d 69 74 2e 20 41  ameter iLimit. A
5380: 6e 79 20 70 69 6e 6e 65 64 20 70 61 67 65 73 20  ny pinned pages 
5390: 77 69 74 68 20 61 20 70 61 67 65 20 6e 75 6d 62  with a page numb
53a0: 65 72 0a 2a 2a 20 65 71 75 61 6c 20 74 6f 20 6f  er.** equal to o
53b0: 72 20 67 72 65 61 74 65 72 20 74 68 61 6e 20 69  r greater than i
53c0: 4c 69 6d 69 74 20 61 72 65 20 69 6d 70 6c 69 63  Limit are implic
53d0: 69 74 6c 79 20 75 6e 70 69 6e 6e 65 64 2e 0a 2a  itly unpinned..*
53e0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63  /.static void pc
53f0: 61 63 68 65 31 54 72 75 6e 63 61 74 65 28 73 71  ache1Truncate(sq
5400: 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70 2c  lite3_pcache *p,
5410: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4c   unsigned int iL
5420: 69 6d 69 74 29 7b 0a 20 20 50 43 61 63 68 65 31  imit){.  PCache1
5430: 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61 63   *pCache = (PCac
5440: 68 65 31 20 2a 29 70 3b 0a 20 20 70 63 61 63 68  he1 *)p;.  pcach
5450: 65 31 45 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a  e1EnterMutex();.
5460: 20 20 69 66 28 20 69 4c 69 6d 69 74 3c 3d 70 43    if( iLimit<=pC
5470: 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 29 7b  ache->iMaxKey ){
5480: 0a 20 20 20 20 70 63 61 63 68 65 31 54 72 75 6e  .    pcache1Trun
5490: 63 61 74 65 55 6e 73 61 66 65 28 70 43 61 63 68  cateUnsafe(pCach
54a0: 65 2c 20 69 4c 69 6d 69 74 29 3b 0a 20 20 20 20  e, iLimit);.    
54b0: 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20  pCache->iMaxKey 
54c0: 3d 20 69 4c 69 6d 69 74 2d 31 3b 0a 20 20 7d 0a  = iLimit-1;.  }.
54d0: 20 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75    pcache1LeaveMu
54e0: 74 65 78 28 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  tex();.}../*.** 
54f0: 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  Implementation o
5500: 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63  f the sqlite3_pc
5510: 61 63 68 65 2e 78 44 65 73 74 72 6f 79 20 6d 65  ache.xDestroy me
5520: 74 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20 44 65 73  thod. .**.** Des
5530: 74 72 6f 79 20 61 20 63 61 63 68 65 20 61 6c 6c  troy a cache all
5540: 6f 63 61 74 65 64 20 75 73 69 6e 67 20 70 63 61  ocated using pca
5550: 63 68 65 31 43 72 65 61 74 65 28 29 2e 0a 2a 2f  che1Create()..*/
5560: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61  .static void pca
5570: 63 68 65 31 44 65 73 74 72 6f 79 28 73 71 6c 69  che1Destroy(sqli
5580: 74 65 33 5f 70 63 61 63 68 65 20 2a 70 29 7b 0a  te3_pcache *p){.
5590: 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68    PCache1 *pCach
55a0: 65 20 3d 20 28 50 43 61 63 68 65 31 20 2a 29 70  e = (PCache1 *)p
55b0: 3b 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65 72  ;.  pcache1Enter
55c0: 4d 75 74 65 78 28 29 3b 0a 20 20 70 63 61 63 68  Mutex();.  pcach
55d0: 65 31 54 72 75 6e 63 61 74 65 55 6e 73 61 66 65  e1TruncateUnsafe
55e0: 28 70 43 61 63 68 65 2c 20 30 29 3b 0a 20 20 70  (pCache, 0);.  p
55f0: 63 61 63 68 65 31 2e 6e 4d 61 78 50 61 67 65 20  cache1.nMaxPage 
5600: 2d 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 3b  -= pCache->nMax;
5610: 0a 20 20 70 63 61 63 68 65 31 2e 6e 4d 69 6e 50  .  pcache1.nMinP
5620: 61 67 65 20 2d 3d 20 70 43 61 63 68 65 2d 3e 6e  age -= pCache->n
5630: 4d 69 6e 3b 0a 20 20 70 63 61 63 68 65 31 45 6e  Min;.  pcache1En
5640: 66 6f 72 63 65 4d 61 78 50 61 67 65 28 29 3b 0a  forceMaxPage();.
5650: 20 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75    pcache1LeaveMu
5660: 74 65 78 28 29 3b 0a 20 20 73 71 6c 69 74 65 33  tex();.  sqlite3
5670: 5f 66 72 65 65 28 70 43 61 63 68 65 2d 3e 61 70  _free(pCache->ap
5680: 48 61 73 68 29 3b 0a 20 20 73 71 6c 69 74 65 33  Hash);.  sqlite3
5690: 5f 66 72 65 65 28 70 43 61 63 68 65 29 3b 0a 7d  _free(pCache);.}
56a0: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e  ../*.** This fun
56b0: 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20  ction is called 
56c0: 64 75 72 69 6e 67 20 69 6e 69 74 69 61 6c 69 7a  during initializ
56d0: 61 74 69 6f 6e 20 28 73 71 6c 69 74 65 33 5f 69  ation (sqlite3_i
56e0: 6e 69 74 69 61 6c 69 7a 65 28 29 29 20 74 6f 0a  nitialize()) to.
56f0: 2a 2a 20 69 6e 73 74 61 6c 6c 20 74 68 65 20 64  ** install the d
5700: 65 66 61 75 6c 74 20 70 6c 75 67 67 61 62 6c 65  efault pluggable
5710: 20 63 61 63 68 65 20 6d 6f 64 75 6c 65 2c 20 61   cache module, a
5720: 73 73 75 6d 69 6e 67 20 74 68 65 20 75 73 65 72  ssuming the user
5730: 20 68 61 73 20 6e 6f 74 0a 2a 2a 20 61 6c 72 65   has not.** alre
5740: 61 64 79 20 70 72 6f 76 69 64 65 64 20 61 6e 20  ady provided an 
5750: 61 6c 74 65 72 6e 61 74 69 76 65 2e 0a 2a 2f 0a  alternative..*/.
5760: 76 6f 69 64 20 73 71 6c 69 74 65 33 50 43 61 63  void sqlite3PCac
5770: 68 65 53 65 74 44 65 66 61 75 6c 74 28 76 6f 69  heSetDefault(voi
5780: 64 29 7b 0a 20 20 73 74 61 74 69 63 20 73 71 6c  d){.  static sql
5790: 69 74 65 33 5f 70 63 61 63 68 65 5f 6d 65 74 68  ite3_pcache_meth
57a0: 6f 64 73 20 64 65 66 61 75 6c 74 4d 65 74 68 6f  ods defaultMetho
57b0: 64 73 20 3d 20 7b 0a 20 20 20 20 30 2c 20 20 20  ds = {.    0,   
57c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
57d0: 20 20 20 20 2f 2a 20 70 41 72 67 20 2a 2f 0a 20      /* pArg */. 
57e0: 20 20 20 70 63 61 63 68 65 31 49 6e 69 74 2c 20     pcache1Init, 
57f0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
5800: 49 6e 69 74 20 2a 2f 0a 20 20 20 20 70 63 61 63  Init */.    pcac
5810: 68 65 31 53 68 75 74 64 6f 77 6e 2c 20 20 20 20  he1Shutdown,    
5820: 20 20 20 20 20 2f 2a 20 78 53 68 75 74 64 6f 77       /* xShutdow
5830: 6e 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31  n */.    pcache1
5840: 43 72 65 61 74 65 2c 20 20 20 20 20 20 20 20 20  Create,         
5850: 20 20 2f 2a 20 78 43 72 65 61 74 65 20 2a 2f 0a    /* xCreate */.
5860: 20 20 20 20 70 63 61 63 68 65 31 43 61 63 68 65      pcache1Cache
5870: 73 69 7a 65 2c 20 20 20 20 20 20 20 20 2f 2a 20  size,        /* 
5880: 78 43 61 63 68 65 73 69 7a 65 20 2a 2f 0a 20 20  xCachesize */.  
5890: 20 20 70 63 61 63 68 65 31 50 61 67 65 63 6f 75    pcache1Pagecou
58a0: 6e 74 2c 20 20 20 20 20 20 20 20 2f 2a 20 78 50  nt,        /* xP
58b0: 61 67 65 63 6f 75 6e 74 20 2a 2f 0a 20 20 20 20  agecount */.    
58c0: 70 63 61 63 68 65 31 46 65 74 63 68 2c 20 20 20  pcache1Fetch,   
58d0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 46 65 74           /* xFet
58e0: 63 68 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65  ch */.    pcache
58f0: 31 55 6e 70 69 6e 2c 20 20 20 20 20 20 20 20 20  1Unpin,         
5900: 20 20 20 2f 2a 20 78 55 6e 70 69 6e 20 2a 2f 0a     /* xUnpin */.
5910: 20 20 20 20 70 63 61 63 68 65 31 52 65 6b 65 79      pcache1Rekey
5920: 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ,            /* 
5930: 78 52 65 6b 65 79 20 2a 2f 0a 20 20 20 20 70 63  xRekey */.    pc
5940: 61 63 68 65 31 54 72 75 6e 63 61 74 65 2c 20 20  ache1Truncate,  
5950: 20 20 20 20 20 20 20 2f 2a 20 78 54 72 75 6e 63         /* xTrunc
5960: 61 74 65 20 2a 2f 0a 20 20 20 20 70 63 61 63 68  ate */.    pcach
5970: 65 31 44 65 73 74 72 6f 79 20 20 20 20 20 20 20  e1Destroy       
5980: 20 20 20 20 2f 2a 20 78 44 65 73 74 72 6f 79 20      /* xDestroy 
5990: 2a 2f 0a 20 20 7d 3b 0a 20 20 73 71 6c 69 74 65  */.  };.  sqlite
59a0: 33 5f 63 6f 6e 66 69 67 28 53 51 4c 49 54 45 5f  3_config(SQLITE_
59b0: 43 4f 4e 46 49 47 5f 50 43 41 43 48 45 2c 20 26  CONFIG_PCACHE, &
59c0: 64 65 66 61 75 6c 74 4d 65 74 68 6f 64 73 29 3b  defaultMethods);
59d0: 0a 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54  .}..#ifdef SQLIT
59e0: 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f  E_ENABLE_MEMORY_
59f0: 4d 41 4e 41 47 45 4d 45 4e 54 0a 2f 2a 0a 2a 2a  MANAGEMENT./*.**
5a00: 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   This function i
5a10: 73 20 63 61 6c 6c 65 64 20 74 6f 20 66 72 65 65  s called to free
5a20: 20 73 75 70 65 72 66 6c 75 6f 75 73 20 64 79 6e   superfluous dyn
5a30: 61 6d 69 63 61 6c 6c 79 20 61 6c 6c 6f 63 61 74  amically allocat
5a40: 65 64 20 6d 65 6d 6f 72 79 0a 2a 2a 20 68 65 6c  ed memory.** hel
5a50: 64 20 62 79 20 74 68 65 20 70 61 67 65 72 20 73  d by the pager s
5a60: 79 73 74 65 6d 2e 20 4d 65 6d 6f 72 79 20 69 6e  ystem. Memory in
5a70: 20 75 73 65 20 62 79 20 61 6e 79 20 53 51 4c 69   use by any SQLi
5a80: 74 65 20 70 61 67 65 72 20 61 6c 6c 6f 63 61 74  te pager allocat
5a90: 65 64 0a 2a 2a 20 62 79 20 74 68 65 20 63 75 72  ed.** by the cur
5aa0: 72 65 6e 74 20 74 68 72 65 61 64 20 6d 61 79 20  rent thread may 
5ab0: 62 65 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  be sqlite3_free(
5ac0: 29 65 64 2e 0a 2a 2a 0a 2a 2a 20 6e 52 65 71 20  )ed..**.** nReq 
5ad0: 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  is the number of
5ae0: 20 62 79 74 65 73 20 6f 66 20 6d 65 6d 6f 72 79   bytes of memory
5af0: 20 72 65 71 75 69 72 65 64 2e 20 4f 6e 63 65 20   required. Once 
5b00: 74 68 69 73 20 6d 75 63 68 20 68 61 73 0a 2a 2a  this much has.**
5b10: 20 62 65 65 6e 20 72 65 6c 65 61 73 65 64 2c 20   been released, 
5b20: 74 68 65 20 66 75 6e 63 74 69 6f 6e 20 72 65 74  the function ret
5b30: 75 72 6e 73 2e 20 54 68 65 20 72 65 74 75 72 6e  urns. The return
5b40: 20 76 61 6c 75 65 20 69 73 20 74 68 65 20 74 6f   value is the to
5b50: 74 61 6c 20 6e 75 6d 62 65 72 20 0a 2a 2a 20 6f  tal number .** o
5b60: 66 20 62 79 74 65 73 20 6f 66 20 6d 65 6d 6f 72  f bytes of memor
5b70: 79 20 72 65 6c 65 61 73 65 64 2e 0a 2a 2f 0a 69  y released..*/.i
5b80: 6e 74 20 73 71 6c 69 74 65 33 50 63 61 63 68 65  nt sqlite3Pcache
5b90: 52 65 6c 65 61 73 65 4d 65 6d 6f 72 79 28 69 6e  ReleaseMemory(in
5ba0: 74 20 6e 52 65 71 29 7b 0a 20 20 69 6e 74 20 6e  t nReq){.  int n
5bb0: 46 72 65 65 20 3d 20 30 3b 0a 20 20 69 66 28 20  Free = 0;.  if( 
5bc0: 70 63 61 63 68 65 31 2e 70 53 74 61 72 74 3d 3d  pcache1.pStart==
5bd0: 30 20 29 7b 0a 20 20 20 20 50 67 48 64 72 31 20  0 ){.    PgHdr1 
5be0: 2a 70 3b 0a 20 20 20 20 70 63 61 63 68 65 31 45  *p;.    pcache1E
5bf0: 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a 20 20 20  nterMutex();.   
5c00: 20 77 68 69 6c 65 28 20 28 6e 52 65 71 3c 30 20   while( (nReq<0 
5c10: 7c 7c 20 6e 46 72 65 65 3c 6e 52 65 71 29 20 26  || nFree<nReq) &
5c20: 26 20 28 70 3d 70 63 61 63 68 65 31 2e 70 4c 72  & (p=pcache1.pLr
5c30: 75 54 61 69 6c 29 20 29 7b 0a 20 20 20 20 20 20  uTail) ){.      
5c40: 6e 46 72 65 65 20 2b 3d 20 73 71 6c 69 74 65 33  nFree += sqlite3
5c50: 4d 61 6c 6c 6f 63 53 69 7a 65 28 50 47 48 44 52  MallocSize(PGHDR
5c60: 31 5f 54 4f 5f 50 41 47 45 28 70 29 29 3b 0a 20  1_TO_PAGE(p));. 
5c70: 20 20 20 20 20 70 63 61 63 68 65 31 50 69 6e 50       pcache1PinP
5c80: 61 67 65 28 70 29 3b 0a 20 20 20 20 20 20 70 63  age(p);.      pc
5c90: 61 63 68 65 31 52 65 6d 6f 76 65 46 72 6f 6d 48  ache1RemoveFromH
5ca0: 61 73 68 28 70 29 3b 0a 20 20 20 20 20 20 70 63  ash(p);.      pc
5cb0: 61 63 68 65 31 46 72 65 65 50 61 67 65 28 70 29  ache1FreePage(p)
5cc0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 63 61 63  ;.    }.    pcac
5cd0: 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 29 3b  he1LeaveMutex();
5ce0: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 6e 46  .  }.  return nF
5cf0: 72 65 65 3b 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a  ree;.}.#endif /*
5d00: 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d   SQLITE_ENABLE_M
5d10: 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54  EMORY_MANAGEMENT
5d20: 20 2a 2f 0a 0a 23 69 66 64 65 66 20 53 51 4c 49   */..#ifdef SQLI
5d30: 54 45 5f 54 45 53 54 0a 2f 2a 0a 2a 2a 20 54 68  TE_TEST./*.** Th
5d40: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 75  is function is u
5d50: 73 65 64 20 62 79 20 74 65 73 74 20 70 72 6f 63  sed by test proc
5d60: 65 64 75 72 65 73 20 74 6f 20 69 6e 73 70 65 63  edures to inspec
5d70: 74 20 74 68 65 20 69 6e 74 65 72 6e 61 6c 20 73  t the internal s
5d80: 74 61 74 65 0a 2a 2a 20 6f 66 20 74 68 65 20 67  tate.** of the g
5d90: 6c 6f 62 61 6c 20 63 61 63 68 65 2e 0a 2a 2f 0a  lobal cache..*/.
5da0: 76 6f 69 64 20 73 71 6c 69 74 65 33 50 63 61 63  void sqlite3Pcac
5db0: 68 65 53 74 61 74 73 28 0a 20 20 69 6e 74 20 2a  heStats(.  int *
5dc0: 70 6e 43 75 72 72 65 6e 74 2c 20 20 20 20 20 20  pnCurrent,      
5dd0: 2f 2a 20 4f 55 54 3a 20 54 6f 74 61 6c 20 6e 75  /* OUT: Total nu
5de0: 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 63 61  mber of pages ca
5df0: 63 68 65 64 20 2a 2f 0a 20 20 69 6e 74 20 2a 70  ched */.  int *p
5e00: 6e 4d 61 78 2c 20 20 20 20 20 20 20 20 20 20 2f  nMax,          /
5e10: 2a 20 4f 55 54 3a 20 47 6c 6f 62 61 6c 20 6d 61  * OUT: Global ma
5e20: 78 69 6d 75 6d 20 63 61 63 68 65 20 73 69 7a 65  ximum cache size
5e30: 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 4d 69 6e   */.  int *pnMin
5e40: 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55  ,          /* OU
5e50: 54 3a 20 53 75 6d 20 6f 66 20 50 43 61 63 68 65  T: Sum of PCache
5e60: 31 2e 6e 4d 69 6e 20 66 6f 72 20 70 75 72 67 65  1.nMin for purge
5e70: 61 62 6c 65 20 63 61 63 68 65 73 20 2a 2f 0a 20  able caches */. 
5e80: 20 69 6e 74 20 2a 70 6e 52 65 63 79 63 6c 61 62   int *pnRecyclab
5e90: 6c 65 20 20 20 20 2f 2a 20 4f 55 54 3a 20 54 6f  le    /* OUT: To
5ea0: 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 70 61  tal number of pa
5eb0: 67 65 73 20 61 76 61 69 6c 61 62 6c 65 20 66 6f  ges available fo
5ec0: 72 20 72 65 63 79 63 6c 69 6e 67 20 2a 2f 0a 29  r recycling */.)
5ed0: 7b 0a 20 20 50 67 48 64 72 31 20 2a 70 3b 0a 20  {.  PgHdr1 *p;. 
5ee0: 20 69 6e 74 20 6e 52 65 63 79 63 6c 61 62 6c 65   int nRecyclable
5ef0: 20 3d 20 30 3b 0a 20 20 66 6f 72 28 70 3d 70 63   = 0;.  for(p=pc
5f00: 61 63 68 65 31 2e 70 4c 72 75 48 65 61 64 3b 20  ache1.pLruHead; 
5f10: 70 3b 20 70 3d 70 2d 3e 70 4c 72 75 4e 65 78 74  p; p=p->pLruNext
5f20: 29 7b 0a 20 20 20 20 6e 52 65 63 79 63 6c 61 62  ){.    nRecyclab
5f30: 6c 65 2b 2b 3b 0a 20 20 7d 0a 20 20 2a 70 6e 43  le++;.  }.  *pnC
5f40: 75 72 72 65 6e 74 20 3d 20 70 63 61 63 68 65 31  urrent = pcache1
5f50: 2e 6e 43 75 72 72 65 6e 74 50 61 67 65 3b 0a 20  .nCurrentPage;. 
5f60: 20 2a 70 6e 4d 61 78 20 3d 20 70 63 61 63 68 65   *pnMax = pcache
5f70: 31 2e 6e 4d 61 78 50 61 67 65 3b 0a 20 20 2a 70  1.nMaxPage;.  *p
5f80: 6e 4d 69 6e 20 3d 20 70 63 61 63 68 65 31 2e 6e  nMin = pcache1.n
5f90: 4d 69 6e 50 61 67 65 3b 0a 20 20 2a 70 6e 52 65  MinPage;.  *pnRe
5fa0: 63 79 63 6c 61 62 6c 65 20 3d 20 6e 52 65 63 79  cyclable = nRecy
5fb0: 63 6c 61 62 6c 65 3b 0a 7d 0a 23 65 6e 64 69 66  clable;.}.#endif
5fc0: 0a                                               .