/ Hex Artifact Content
Login

Artifact d8d412326cc5123ba3bfaa66e36205ca8c5dbc5e:


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 34 20 32 30  ache1.c,v 1.4 20
02e0: 30 38 2f 31 31 2f 32 34 20 32 30 3a 30 35 3a 33  08/11/24 20:05:3
02f0: 39 20 73 68 61 6e 65 20 45 78 70 20 24 0a 2a 2f  9 shane Exp $.*/
0300: 0a 0a 23 69 6e 63 6c 75 64 65 20 22 73 71 6c 69  ..#include "sqli
0310: 74 65 49 6e 74 2e 68 22 0a 0a 74 79 70 65 64 65  teInt.h"..typede
0320: 66 20 73 74 72 75 63 74 20 50 43 61 63 68 65 31  f struct PCache1
0330: 20 50 43 61 63 68 65 31 3b 0a 74 79 70 65 64 65   PCache1;.typede
0340: 66 20 73 74 72 75 63 74 20 50 67 48 64 72 31 20  f struct PgHdr1 
0350: 50 67 48 64 72 31 3b 0a 74 79 70 65 64 65 66 20  PgHdr1;.typedef 
0360: 73 74 72 75 63 74 20 50 67 46 72 65 65 73 6c 6f  struct PgFreeslo
0370: 74 20 50 67 46 72 65 65 73 6c 6f 74 3b 0a 0a 2f  t PgFreeslot;../
0380: 2a 20 50 6f 69 6e 74 65 72 73 20 74 6f 20 73 74  * Pointers to st
0390: 72 75 63 74 75 72 65 73 20 6f 66 20 74 68 69 73  ructures of this
03a0: 20 74 79 70 65 20 61 72 65 20 63 61 73 74 20 61   type are cast a
03b0: 6e 64 20 72 65 74 75 72 6e 65 64 20 61 73 20 0a  nd returned as .
03c0: 2a 2a 20 6f 70 61 71 75 65 20 73 71 6c 69 74 65  ** opaque sqlite
03d0: 33 5f 70 63 61 63 68 65 2a 20 68 61 6e 64 6c 65  3_pcache* handle
03e0: 73 0a 2a 2f 0a 73 74 72 75 63 74 20 50 43 61 63  s.*/.struct PCac
03f0: 68 65 31 20 7b 0a 20 20 2f 2a 20 43 61 63 68 65  he1 {.  /* Cache
0400: 20 63 6f 6e 66 69 67 75 72 61 74 69 6f 6e 20 70   configuration p
0410: 61 72 61 6d 65 74 65 72 73 2e 20 50 61 67 65 20  arameters. Page 
0420: 73 69 7a 65 20 28 73 7a 50 61 67 65 29 20 61 6e  size (szPage) an
0430: 64 20 74 68 65 20 70 75 72 67 65 61 62 6c 65 0a  d the purgeable.
0440: 20 20 2a 2a 20 66 6c 61 67 20 28 62 50 75 72 67    ** flag (bPurg
0450: 65 61 62 6c 65 29 20 61 72 65 20 73 65 74 20 77  eable) are set w
0460: 68 65 6e 20 74 68 65 20 63 61 63 68 65 20 69 73  hen the cache is
0470: 20 63 72 65 61 74 65 64 2e 20 6e 4d 61 78 20 6d   created. nMax m
0480: 61 79 20 62 65 20 0a 20 20 2a 2a 20 6d 6f 64 69  ay be .  ** modi
0490: 66 69 65 64 20 61 74 20 61 6e 79 20 74 69 6d 65  fied at any time
04a0: 20 62 79 20 61 20 63 61 6c 6c 20 74 6f 20 74 68   by a call to th
04b0: 65 20 70 63 61 63 68 65 31 43 61 63 68 65 53 69  e pcache1CacheSi
04c0: 7a 65 28 29 20 6d 65 74 68 6f 64 2e 0a 20 20 2a  ze() method..  *
04d0: 2a 20 54 68 65 20 67 6c 6f 62 61 6c 20 6d 75 74  * The global mut
04e0: 65 78 20 6d 75 73 74 20 62 65 20 68 65 6c 64 20  ex must be held 
04f0: 77 68 65 6e 20 61 63 63 65 73 73 69 6e 67 20 6e  when accessing n
0500: 4d 61 78 2e 0a 20 20 2a 2f 0a 20 20 69 6e 74 20  Max..  */.  int 
0510: 73 7a 50 61 67 65 3b 20 20 20 20 20 20 20 20 20  szPage;         
0520: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0530: 2f 2a 20 53 69 7a 65 20 6f 66 20 61 6c 6c 6f 63  /* Size of alloc
0540: 61 74 65 64 20 70 61 67 65 73 20 69 6e 20 62 79  ated pages in by
0550: 74 65 73 20 2a 2f 0a 20 20 69 6e 74 20 62 50 75  tes */.  int bPu
0560: 72 67 65 61 62 6c 65 3b 20 20 20 20 20 20 20 20  rgeable;        
0570: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0580: 54 72 75 65 20 69 66 20 63 61 63 68 65 20 69 73  True if cache is
0590: 20 70 75 72 67 65 61 62 6c 65 20 2a 2f 0a 20 20   purgeable */.  
05a0: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 4d 69  unsigned int nMi
05b0: 6e 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  n;              
05c0: 20 20 20 20 2f 2a 20 4d 69 6e 69 6d 75 6d 20 6e      /* Minimum n
05d0: 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 72  umber of pages r
05e0: 65 73 65 72 76 65 64 20 2a 2f 0a 20 20 75 6e 73  eserved */.  uns
05f0: 69 67 6e 65 64 20 69 6e 74 20 6e 4d 61 78 3b 20  igned int nMax; 
0600: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0610: 20 2f 2a 20 43 6f 6e 66 69 67 75 72 65 64 20 22   /* Configured "
0620: 63 61 63 68 65 5f 73 69 7a 65 22 20 76 61 6c 75  cache_size" valu
0630: 65 20 2a 2f 0a 0a 20 20 2f 2a 20 48 61 73 68 20  e */..  /* Hash 
0640: 74 61 62 6c 65 20 6f 66 20 61 6c 6c 20 70 61 67  table of all pag
0650: 65 73 2e 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e  es. The followin
0660: 67 20 76 61 72 69 61 62 6c 65 73 20 6d 61 79 20  g variables may 
0670: 6f 6e 6c 79 20 62 65 20 61 63 63 65 73 73 65 64  only be accessed
0680: 0a 20 20 2a 2a 20 77 68 65 6e 20 74 68 65 20 61  .  ** when the a
0690: 63 63 65 73 73 6f 72 20 69 73 20 68 6f 6c 64 69  ccessor is holdi
06a0: 6e 67 20 74 68 65 20 67 6c 6f 62 61 6c 20 6d 75  ng the global mu
06b0: 74 65 78 20 28 73 65 65 20 70 63 61 63 68 65 31  tex (see pcache1
06c0: 45 6e 74 65 72 4d 75 74 65 78 28 29 20 0a 20 20  EnterMutex() .  
06d0: 2a 2a 20 61 6e 64 20 70 63 61 63 68 65 31 4c 65  ** and pcache1Le
06e0: 61 76 65 4d 75 74 65 78 28 29 29 2e 0a 20 20 2a  aveMutex())..  *
06f0: 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74  /.  unsigned int
0700: 20 6e 52 65 63 79 63 6c 61 62 6c 65 3b 20 20 20   nRecyclable;   
0710: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
0720: 72 20 6f 66 20 70 61 67 65 73 20 69 6e 20 74 68  r of pages in th
0730: 65 20 4c 52 55 20 6c 69 73 74 20 2a 2f 0a 20 20  e LRU list */.  
0740: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 50 61  unsigned int nPa
0750: 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ge;             
0760: 20 20 20 20 2f 2a 20 54 6f 74 61 6c 20 6e 75 6d      /* Total num
0770: 62 65 72 20 6f 66 20 70 61 67 65 73 20 69 6e 20  ber of pages in 
0780: 61 70 48 61 73 68 20 2a 2f 0a 20 20 75 6e 73 69  apHash */.  unsi
0790: 67 6e 65 64 20 69 6e 74 20 6e 48 61 73 68 3b 20  gned int nHash; 
07a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
07b0: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 73 6c 6f  /* Number of slo
07c0: 74 73 20 69 6e 20 61 70 48 61 73 68 5b 5d 20 2a  ts in apHash[] *
07d0: 2f 0a 20 20 50 67 48 64 72 31 20 2a 2a 61 70 48  /.  PgHdr1 **apH
07e0: 61 73 68 3b 20 20 20 20 20 20 20 20 20 20 20 20  ash;            
07f0: 20 20 20 20 20 20 20 20 2f 2a 20 48 61 73 68 20          /* Hash 
0800: 74 61 62 6c 65 20 66 6f 72 20 66 61 73 74 20 6c  table for fast l
0810: 6f 6f 6b 75 70 20 62 79 20 6b 65 79 20 2a 2f 0a  ookup by key */.
0820: 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 45 61 63 68 20 63  };../*.** Each c
0830: 61 63 68 65 20 65 6e 74 72 79 20 69 73 20 72 65  ache entry is re
0840: 70 72 65 73 65 6e 74 65 64 20 62 79 20 61 6e 20  presented by an 
0850: 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 65 20  instance of the 
0860: 66 6f 6c 6c 6f 77 69 6e 67 20 0a 2a 2a 20 73 74  following .** st
0870: 72 75 63 74 75 72 65 2e 20 41 20 62 75 66 66 65  ructure. A buffe
0880: 72 20 6f 66 20 50 67 48 64 72 31 2e 70 43 61 63  r of PgHdr1.pCac
0890: 68 65 2d 3e 73 7a 50 61 67 65 20 62 79 74 65 73  he->szPage bytes
08a0: 20 69 73 20 61 6c 6c 6f 63 61 74 65 64 20 0a 2a   is allocated .*
08b0: 2a 20 64 69 72 65 63 74 6c 79 20 61 66 74 65 72  * directly after
08c0: 20 74 68 65 20 73 74 72 75 63 74 75 72 65 20 69   the structure i
08d0: 6e 20 6d 65 6d 6f 72 79 20 28 73 65 65 20 74 68  n memory (see th
08e0: 65 20 50 47 48 44 52 31 5f 54 4f 5f 50 41 47 45  e PGHDR1_TO_PAGE
08f0: 28 29 20 0a 2a 2a 20 6d 61 63 72 6f 20 62 65 6c  () .** macro bel
0900: 6f 77 29 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 50  ow)..*/.struct P
0910: 67 48 64 72 31 20 7b 0a 20 20 75 6e 73 69 67 6e  gHdr1 {.  unsign
0920: 65 64 20 69 6e 74 20 69 4b 65 79 3b 20 20 20 20  ed int iKey;    
0930: 20 20 20 20 20 20 20 20 20 2f 2a 20 4b 65 79 20           /* Key 
0940: 76 61 6c 75 65 20 28 70 61 67 65 20 6e 75 6d 62  value (page numb
0950: 65 72 29 20 2a 2f 0a 20 20 50 67 48 64 72 31 20  er) */.  PgHdr1 
0960: 2a 70 4e 65 78 74 3b 20 20 20 20 20 20 20 20 20  *pNext;         
0970: 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20          /* Next 
0980: 69 6e 20 68 61 73 68 20 74 61 62 6c 65 20 63 68  in hash table ch
0990: 61 69 6e 20 2a 2f 0a 20 20 50 43 61 63 68 65 31  ain */.  PCache1
09a0: 20 2a 70 43 61 63 68 65 3b 20 20 20 20 20 20 20   *pCache;       
09b0: 20 20 20 20 20 20 20 20 2f 2a 20 43 61 63 68 65          /* Cache
09c0: 20 74 68 61 74 20 63 75 72 72 65 6e 74 6c 79 20   that currently 
09d0: 6f 77 6e 73 20 74 68 69 73 20 70 61 67 65 20 2a  owns this page *
09e0: 2f 0a 20 20 50 67 48 64 72 31 20 2a 70 4c 72 75  /.  PgHdr1 *pLru
09f0: 4e 65 78 74 3b 20 20 20 20 20 20 20 20 20 20 20  Next;           
0a00: 20 20 20 2f 2a 20 4e 65 78 74 20 69 6e 20 4c 52     /* Next in LR
0a10: 55 20 6c 69 73 74 20 6f 66 20 75 6e 70 69 6e 6e  U list of unpinn
0a20: 65 64 20 70 61 67 65 73 20 2a 2f 0a 20 20 50 67  ed pages */.  Pg
0a30: 48 64 72 31 20 2a 70 4c 72 75 50 72 65 76 3b 20  Hdr1 *pLruPrev; 
0a40: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0a50: 50 72 65 76 69 6f 75 73 20 69 6e 20 4c 52 55 20  Previous in LRU 
0a60: 6c 69 73 74 20 6f 66 20 75 6e 70 69 6e 6e 65 64  list of unpinned
0a70: 20 70 61 67 65 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a   pages */.};../*
0a80: 0a 2a 2a 20 46 72 65 65 20 73 6c 6f 74 73 20 69  .** Free slots i
0a90: 6e 20 74 68 65 20 61 6c 6c 6f 63 61 74 6f 72 20  n the allocator 
0aa0: 75 73 65 64 20 74 6f 20 64 69 76 69 64 65 20 75  used to divide u
0ab0: 70 20 74 68 65 20 62 75 66 66 65 72 20 70 72 6f  p the buffer pro
0ac0: 76 69 64 65 64 20 75 73 69 6e 67 0a 2a 2a 20 74  vided using.** t
0ad0: 68 65 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47  he SQLITE_CONFIG
0ae0: 5f 50 41 47 45 43 41 43 48 45 20 6d 65 63 68 61  _PAGECACHE mecha
0af0: 6e 69 73 6d 2e 0a 2a 2f 0a 73 74 72 75 63 74 20  nism..*/.struct 
0b00: 50 67 46 72 65 65 73 6c 6f 74 20 7b 0a 20 20 50  PgFreeslot {.  P
0b10: 67 46 72 65 65 73 6c 6f 74 20 2a 70 4e 65 78 74  gFreeslot *pNext
0b20: 3b 20 20 2f 2a 20 4e 65 78 74 20 66 72 65 65 20  ;  /* Next free 
0b30: 73 6c 6f 74 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a  slot */.};../*.*
0b40: 2a 20 47 6c 6f 62 61 6c 20 64 61 74 61 20 75 73  * Global data us
0b50: 65 64 20 62 79 20 74 68 69 73 20 63 61 63 68 65  ed by this cache
0b60: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 53 51 4c 49  ..*/.static SQLI
0b70: 54 45 5f 57 53 44 20 73 74 72 75 63 74 20 50 43  TE_WSD struct PC
0b80: 61 63 68 65 47 6c 6f 62 61 6c 20 7b 0a 20 20 73  acheGlobal {.  s
0b90: 71 6c 69 74 65 33 5f 6d 75 74 65 78 20 2a 6d 75  qlite3_mutex *mu
0ba0: 74 65 78 3b 20 20 20 20 20 20 20 20 20 20 20 20  tex;            
0bb0: 20 20 20 2f 2a 20 73 74 61 74 69 63 20 6d 75 74     /* static mut
0bc0: 65 78 20 4d 55 54 45 58 5f 53 54 41 54 49 43 5f  ex MUTEX_STATIC_
0bd0: 4c 52 55 20 2a 2f 0a 0a 20 20 69 6e 74 20 6e 4d  LRU */..  int nM
0be0: 61 78 50 61 67 65 3b 20 20 20 20 20 20 20 20 20  axPage;         
0bf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0c00: 20 53 75 6d 20 6f 66 20 6e 4d 61 78 50 61 67 65   Sum of nMaxPage
0c10: 20 66 6f 72 20 70 75 72 67 65 61 62 6c 65 20 63   for purgeable c
0c20: 61 63 68 65 73 20 2a 2f 0a 20 20 69 6e 74 20 6e  aches */.  int n
0c30: 4d 69 6e 50 61 67 65 3b 20 20 20 20 20 20 20 20  MinPage;        
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 69 6e 50 61 67  * Sum of nMinPag
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 43 75 72 72 65 6e 74 50 61 67 65 3b 20 20 20  nCurrentPage;   
0c90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ca0: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 70 75 72  /* Number of pur
0cb0: 67 65 61 62 6c 65 20 70 61 67 65 73 20 61 6c 6c  geable pages all
0cc0: 6f 63 61 74 65 64 20 2a 2f 0a 20 20 50 67 48 64  ocated */.  PgHd
0cd0: 72 31 20 2a 70 4c 72 75 48 65 61 64 2c 20 2a 70  r1 *pLruHead, *p
0ce0: 4c 72 75 54 61 69 6c 3b 20 20 20 20 20 20 20 20  LruTail;        
0cf0: 2f 2a 20 4c 52 55 20 6c 69 73 74 20 6f 66 20 75  /* LRU list of u
0d00: 6e 70 69 6e 6e 65 64 20 70 61 67 65 73 20 2a 2f  npinned pages */
0d10: 0a 0a 20 20 2f 2a 20 56 61 72 69 61 62 6c 65 73  ..  /* Variables
0d20: 20 72 65 6c 61 74 65 64 20 74 6f 20 53 51 4c 49   related to SQLI
0d30: 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41  TE_CONFIG_PAGECA
0d40: 43 48 45 20 73 65 74 74 69 6e 67 73 2e 20 2a 2f  CHE settings. */
0d50: 0a 20 20 69 6e 74 20 73 7a 53 6c 6f 74 3b 20 20  .  int szSlot;  
0d60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0d70: 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
0d80: 66 20 65 61 63 68 20 66 72 65 65 20 73 6c 6f 74  f each free slot
0d90: 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 53 74 61   */.  void *pSta
0da0: 72 74 2c 20 2a 70 45 6e 64 3b 20 20 20 20 20 20  rt, *pEnd;      
0db0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 6f 75            /* Bou
0dc0: 6e 64 73 20 6f 66 20 70 61 67 65 63 61 63 68 65  nds of pagecache
0dd0: 20 6d 61 6c 6c 6f 63 20 72 61 6e 67 65 20 2a 2f   malloc range */
0de0: 0a 20 20 50 67 46 72 65 65 73 6c 6f 74 20 2a 70  .  PgFreeslot *p
0df0: 46 72 65 65 3b 20 20 20 20 20 20 20 20 20 20 20  Free;           
0e00: 20 20 20 20 20 20 20 2f 2a 20 46 72 65 65 20 70         /* Free p
0e10: 61 67 65 20 62 6c 6f 63 6b 73 20 2a 2f 0a 7d 20  age blocks */.} 
0e20: 70 63 61 63 68 65 31 5f 67 3b 0a 0a 2f 2a 0a 2a  pcache1_g;../*.*
0e30: 2a 20 41 6c 6c 20 63 6f 64 65 20 69 6e 20 74 68  * All code in th
0e40: 69 73 20 66 69 6c 65 20 73 68 6f 75 6c 64 20 61  is file should a
0e50: 63 63 65 73 73 20 74 68 65 20 67 6c 6f 62 61 6c  ccess the global
0e60: 20 73 74 72 75 63 74 75 72 65 20 61 62 6f 76 65   structure above
0e70: 20 76 69 61 20 74 68 65 0a 2a 2a 20 61 6c 69 61   via the.** alia
0e80: 73 20 22 70 63 61 63 68 65 31 22 2e 20 54 68 69  s "pcache1". Thi
0e90: 73 20 65 6e 73 75 72 65 73 20 74 68 61 74 20 74  s ensures that t
0ea0: 68 65 20 57 53 44 20 65 6d 75 6c 61 74 69 6f 6e  he WSD emulation
0eb0: 20 69 73 20 75 73 65 64 20 77 68 65 6e 0a 2a 2a   is used when.**
0ec0: 20 63 6f 6d 70 69 6c 69 6e 67 20 66 6f 72 20 73   compiling for s
0ed0: 79 73 74 65 6d 73 20 74 68 61 74 20 64 6f 20 6e  ystems that do n
0ee0: 6f 74 20 73 75 70 70 6f 72 74 20 72 65 61 6c 20  ot support real 
0ef0: 57 53 44 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20  WSD..*/.#define 
0f00: 70 63 61 63 68 65 31 20 28 47 4c 4f 42 41 4c 28  pcache1 (GLOBAL(
0f10: 73 74 72 75 63 74 20 50 43 61 63 68 65 47 6c 6f  struct PCacheGlo
0f20: 62 61 6c 2c 20 70 63 61 63 68 65 31 5f 67 29 29  bal, pcache1_g))
0f30: 0a 0a 2f 2a 0a 2a 2a 20 57 68 65 6e 20 61 20 50  ../*.** When a P
0f40: 67 48 64 72 31 20 73 74 72 75 63 74 75 72 65 20  gHdr1 structure 
0f50: 69 73 20 61 6c 6c 6f 63 61 74 65 64 2c 20 74 68  is allocated, th
0f60: 65 20 61 73 73 6f 63 69 61 74 65 64 20 50 43 61  e associated PCa
0f70: 63 68 65 31 2e 73 7a 50 61 67 65 0a 2a 2a 20 62  che1.szPage.** b
0f80: 79 74 65 73 20 6f 66 20 64 61 74 61 20 61 72 65  ytes of data are
0f90: 20 6c 6f 63 61 74 65 64 20 64 69 72 65 63 74 6c   located directl
0fa0: 79 20 61 66 74 65 72 20 69 74 20 69 6e 20 6d 65  y after it in me
0fb0: 6d 6f 72 79 20 28 69 2e 65 2e 20 74 68 65 20 74  mory (i.e. the t
0fc0: 6f 74 61 6c 0a 2a 2a 20 73 69 7a 65 20 6f 66 20  otal.** size of 
0fd0: 74 68 65 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 69  the allocation i
0fe0: 73 20 73 69 7a 65 6f 66 28 50 67 48 64 72 31 29  s sizeof(PgHdr1)
0ff0: 2b 50 43 61 63 68 65 31 2e 73 7a 50 61 67 65 20  +PCache1.szPage 
1000: 62 79 74 65 29 2e 20 54 68 65 0a 2a 2a 20 50 47  byte). The.** PG
1010: 48 44 52 31 5f 54 4f 5f 50 41 47 45 28 29 20 6d  HDR1_TO_PAGE() m
1020: 61 63 72 6f 20 74 61 6b 65 73 20 61 20 70 6f 69  acro takes a poi
1030: 6e 74 65 72 20 74 6f 20 61 20 50 67 48 64 72 31  nter to a PgHdr1
1040: 20 73 74 72 75 63 74 75 72 65 20 61 73 0a 2a 2a   structure as.**
1050: 20 61 6e 20 61 72 67 75 6d 65 6e 74 20 61 6e 64   an argument and
1060: 20 72 65 74 75 72 6e 73 20 61 20 70 6f 69 6e 74   returns a point
1070: 65 72 20 74 6f 20 74 68 65 20 61 73 73 6f 63 69  er to the associ
1080: 61 74 65 64 20 62 6c 6f 63 6b 20 6f 66 20 73 7a  ated block of sz
1090: 50 61 67 65 0a 2a 2a 20 62 79 74 65 73 2e 20 54  Page.** bytes. T
10a0: 68 65 20 50 41 47 45 5f 54 4f 5f 50 47 48 44 52  he PAGE_TO_PGHDR
10b0: 31 28 29 20 6d 61 63 72 6f 20 64 6f 65 73 20 74  1() macro does t
10c0: 68 65 20 6f 70 70 6f 73 69 74 65 3a 20 69 74 73  he opposite: its
10d0: 20 61 72 67 75 6d 65 6e 74 20 69 73 0a 2a 2a 20   argument is.** 
10e0: 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 61 20 62  a pointer to a b
10f0: 6c 6f 63 6b 20 6f 66 20 73 7a 50 61 67 65 20 62  lock of szPage b
1100: 79 74 65 73 20 6f 66 20 64 61 74 61 20 61 6e 64  ytes of data and
1110: 20 74 68 65 20 72 65 74 75 72 6e 20 76 61 6c 75   the return valu
1120: 65 20 69 73 0a 2a 2a 20 61 20 70 6f 69 6e 74 65  e is.** a pointe
1130: 72 20 74 6f 20 74 68 65 20 61 73 73 6f 63 69 61  r to the associa
1140: 74 65 64 20 50 67 48 64 72 31 20 73 74 72 75 63  ted PgHdr1 struc
1150: 74 75 72 65 2e 0a 2a 2a 0a 2a 2a 20 20 20 61 73  ture..**.**   as
1160: 73 65 72 74 28 20 50 47 48 44 52 31 5f 54 4f 5f  sert( PGHDR1_TO_
1170: 50 41 47 45 28 50 41 47 45 5f 54 4f 5f 50 47 48  PAGE(PAGE_TO_PGH
1180: 44 52 31 28 58 29 29 3d 3d 58 20 29 3b 0a 2a 2f  DR1(X))==X );.*/
1190: 0a 23 64 65 66 69 6e 65 20 50 47 48 44 52 31 5f  .#define PGHDR1_
11a0: 54 4f 5f 50 41 47 45 28 70 29 20 28 76 6f 69 64  TO_PAGE(p) (void
11b0: 20 2a 29 28 26 28 28 75 6e 73 69 67 6e 65 64 20   *)(&((unsigned 
11c0: 63 68 61 72 20 2a 29 70 29 5b 73 69 7a 65 6f 66  char *)p)[sizeof
11d0: 28 50 67 48 64 72 31 29 5d 29 0a 23 64 65 66 69  (PgHdr1)]).#defi
11e0: 6e 65 20 50 41 47 45 5f 54 4f 5f 50 47 48 44 52  ne PAGE_TO_PGHDR
11f0: 31 28 70 29 20 28 50 67 48 64 72 31 20 2a 29 28  1(p) (PgHdr1 *)(
1200: 26 28 28 75 6e 73 69 67 6e 65 64 20 63 68 61 72  &((unsigned char
1210: 20 2a 29 70 29 5b 2d 31 2a 28 69 6e 74 29 73 69   *)p)[-1*(int)si
1220: 7a 65 6f 66 28 50 67 48 64 72 31 29 5d 29 0a 0a  zeof(PgHdr1)])..
1230: 2f 2a 0a 2a 2a 20 4d 61 63 72 6f 73 20 74 6f 20  /*.** Macros to 
1240: 65 6e 74 65 72 20 61 6e 64 20 6c 65 61 76 65 20  enter and leave 
1250: 74 68 65 20 67 6c 6f 62 61 6c 20 4c 52 55 20 6d  the global LRU m
1260: 75 74 65 78 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65  utex..*/.#define
1270: 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74   pcache1EnterMut
1280: 65 78 28 29 20 73 71 6c 69 74 65 33 5f 6d 75 74  ex() sqlite3_mut
1290: 65 78 5f 65 6e 74 65 72 28 70 63 61 63 68 65 31  ex_enter(pcache1
12a0: 2e 6d 75 74 65 78 29 0a 23 64 65 66 69 6e 65 20  .mutex).#define 
12b0: 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65  pcache1LeaveMute
12c0: 78 28 29 20 73 71 6c 69 74 65 33 5f 6d 75 74 65  x() sqlite3_mute
12d0: 78 5f 6c 65 61 76 65 28 70 63 61 63 68 65 31 2e  x_leave(pcache1.
12e0: 6d 75 74 65 78 29 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a  mutex)../*******
12f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1300: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1310: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1320: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1330: 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 2a 2a 2a 2a 2a  *******/./******
1340: 2a 2a 20 50 61 67 65 20 41 6c 6c 6f 63 61 74 69  ** Page Allocati
1350: 6f 6e 2f 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47  on/SQLITE_CONFIG
1360: 5f 50 43 41 43 48 45 20 52 65 6c 61 74 65 64 20  _PCACHE Related 
1370: 46 75 6e 63 74 69 6f 6e 73 20 2a 2a 2a 2a 2a 2a  Functions ******
1380: 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f 2a 0a 2a 2a  ********/../*.**
1390: 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   This function i
13a0: 73 20 63 61 6c 6c 65 64 20 64 75 72 69 6e 67 20  s called during 
13b0: 69 6e 69 74 69 61 6c 69 7a 61 74 69 6f 6e 20 69  initialization i
13c0: 66 20 61 20 73 74 61 74 69 63 20 62 75 66 66 65  f a static buffe
13d0: 72 20 69 73 20 0a 2a 2a 20 73 75 70 70 6c 69 65  r is .** supplie
13e0: 64 20 74 6f 20 75 73 65 20 66 6f 72 20 74 68 65  d to use for the
13f0: 20 70 61 67 65 2d 63 61 63 68 65 20 62 79 20 70   page-cache by p
1400: 61 73 73 69 6e 67 20 74 68 65 20 53 51 4c 49 54  assing the SQLIT
1410: 45 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41 43  E_CONFIG_PAGECAC
1420: 48 45 0a 2a 2a 20 76 65 72 62 20 74 6f 20 73 71  HE.** verb to sq
1430: 6c 69 74 65 33 5f 63 6f 6e 66 69 67 28 29 2e 20  lite3_config(). 
1440: 50 61 72 61 6d 65 74 65 72 20 70 42 75 66 20 70  Parameter pBuf p
1450: 6f 69 6e 74 73 20 74 6f 20 61 6e 20 61 6c 6c 6f  oints to an allo
1460: 63 61 74 69 6f 6e 20 6c 61 72 67 65 0a 2a 2a 20  cation large.** 
1470: 65 6e 6f 75 67 68 20 74 6f 20 63 6f 6e 74 61 69  enough to contai
1480: 6e 20 27 6e 27 20 62 75 66 66 65 72 73 20 6f 66  n 'n' buffers of
1490: 20 27 73 7a 27 20 62 79 74 65 73 20 65 61 63 68   'sz' bytes each
14a0: 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
14b0: 33 50 43 61 63 68 65 42 75 66 66 65 72 53 65 74  3PCacheBufferSet
14c0: 75 70 28 76 6f 69 64 20 2a 70 42 75 66 2c 20 69  up(void *pBuf, i
14d0: 6e 74 20 73 7a 2c 20 69 6e 74 20 6e 29 7b 0a 20  nt sz, int n){. 
14e0: 20 50 67 46 72 65 65 73 6c 6f 74 20 2a 70 3b 0a   PgFreeslot *p;.
14f0: 20 20 73 7a 20 26 3d 20 7e 37 3b 0a 20 20 70 63    sz &= ~7;.  pc
1500: 61 63 68 65 31 2e 73 7a 53 6c 6f 74 20 3d 20 73  ache1.szSlot = s
1510: 7a 3b 0a 20 20 70 63 61 63 68 65 31 2e 70 53 74  z;.  pcache1.pSt
1520: 61 72 74 20 3d 20 70 42 75 66 3b 0a 20 20 70 63  art = pBuf;.  pc
1530: 61 63 68 65 31 2e 70 46 72 65 65 20 3d 20 30 3b  ache1.pFree = 0;
1540: 0a 20 20 77 68 69 6c 65 28 20 6e 2d 2d 20 29 7b  .  while( n-- ){
1550: 0a 20 20 20 20 70 20 3d 20 28 50 67 46 72 65 65  .    p = (PgFree
1560: 73 6c 6f 74 2a 29 70 42 75 66 3b 0a 20 20 20 20  slot*)pBuf;.    
1570: 70 2d 3e 70 4e 65 78 74 20 3d 20 70 63 61 63 68  p->pNext = pcach
1580: 65 31 2e 70 46 72 65 65 3b 0a 20 20 20 20 70 63  e1.pFree;.    pc
1590: 61 63 68 65 31 2e 70 46 72 65 65 20 3d 20 70 3b  ache1.pFree = p;
15a0: 0a 20 20 20 20 70 42 75 66 20 3d 20 28 76 6f 69  .    pBuf = (voi
15b0: 64 2a 29 26 28 28 63 68 61 72 2a 29 70 42 75 66  d*)&((char*)pBuf
15c0: 29 5b 73 7a 5d 3b 0a 20 20 7d 0a 20 20 70 63 61  )[sz];.  }.  pca
15d0: 63 68 65 31 2e 70 45 6e 64 20 3d 20 70 42 75 66  che1.pEnd = pBuf
15e0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6c 6c 6f  ;.}../*.** Mallo
15f0: 63 20 66 75 6e 63 74 69 6f 6e 20 75 73 65 64 20  c function used 
1600: 77 69 74 68 69 6e 20 74 68 69 73 20 66 69 6c 65  within this file
1610: 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 73 70 61   to allocate spa
1620: 63 65 20 66 72 6f 6d 20 74 68 65 20 62 75 66 66  ce from the buff
1630: 65 72 0a 2a 2a 20 63 6f 6e 66 69 67 75 72 65 64  er.** configured
1640: 20 75 73 69 6e 67 20 73 71 6c 69 74 65 33 5f 63   using sqlite3_c
1650: 6f 6e 66 69 67 28 53 51 4c 49 54 45 5f 43 4f 4e  onfig(SQLITE_CON
1660: 46 49 47 5f 50 41 47 45 43 41 43 48 45 29 20 6f  FIG_PAGECACHE) o
1670: 70 74 69 6f 6e 2e 20 49 66 20 6e 6f 20 0a 2a 2a  ption. If no .**
1680: 20 73 75 63 68 20 62 75 66 66 65 72 20 65 78 69   such buffer exi
1690: 73 74 73 20 6f 72 20 74 68 65 72 65 20 69 73 20  sts or there is 
16a0: 6e 6f 20 73 70 61 63 65 20 6c 65 66 74 20 69 6e  no space left in
16b0: 20 69 74 2c 20 74 68 69 73 20 66 75 6e 63 74 69   it, this functi
16c0: 6f 6e 20 66 61 6c 6c 73 20 0a 2a 2a 20 62 61 63  on falls .** bac
16d0: 6b 20 74 6f 20 73 71 6c 69 74 65 33 4d 61 6c 6c  k to sqlite3Mall
16e0: 6f 63 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  oc()..*/.static 
16f0: 76 6f 69 64 20 2a 70 63 61 63 68 65 31 41 6c 6c  void *pcache1All
1700: 6f 63 28 69 6e 74 20 6e 42 79 74 65 29 7b 0a 20  oc(int nByte){. 
1710: 20 76 6f 69 64 20 2a 70 3b 0a 20 20 61 73 73 65   void *p;.  asse
1720: 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65  rt( sqlite3_mute
1730: 78 5f 68 65 6c 64 28 70 63 61 63 68 65 31 2e 6d  x_held(pcache1.m
1740: 75 74 65 78 29 20 29 3b 0a 20 20 69 66 28 20 6e  utex) );.  if( n
1750: 42 79 74 65 3c 3d 70 63 61 63 68 65 31 2e 73 7a  Byte<=pcache1.sz
1760: 53 6c 6f 74 20 26 26 20 70 63 61 63 68 65 31 2e  Slot && pcache1.
1770: 70 46 72 65 65 20 29 7b 0a 20 20 20 20 70 20 3d  pFree ){.    p =
1780: 20 28 50 67 48 64 72 31 20 2a 29 70 63 61 63 68   (PgHdr1 *)pcach
1790: 65 31 2e 70 46 72 65 65 3b 0a 20 20 20 20 70 63  e1.pFree;.    pc
17a0: 61 63 68 65 31 2e 70 46 72 65 65 20 3d 20 70 63  ache1.pFree = pc
17b0: 61 63 68 65 31 2e 70 46 72 65 65 2d 3e 70 4e 65  ache1.pFree->pNe
17c0: 78 74 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 53  xt;.    sqlite3S
17d0: 74 61 74 75 73 53 65 74 28 53 51 4c 49 54 45 5f  tatusSet(SQLITE_
17e0: 53 54 41 54 55 53 5f 50 41 47 45 43 41 43 48 45  STATUS_PAGECACHE
17f0: 5f 53 49 5a 45 2c 20 6e 42 79 74 65 29 3b 0a 20  _SIZE, nByte);. 
1800: 20 20 20 73 71 6c 69 74 65 33 53 74 61 74 75 73     sqlite3Status
1810: 41 64 64 28 53 51 4c 49 54 45 5f 53 54 41 54 55  Add(SQLITE_STATU
1820: 53 5f 50 41 47 45 43 41 43 48 45 5f 55 53 45 44  S_PAGECACHE_USED
1830: 2c 20 31 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 0a  , 1);.  }else{..
1840: 20 20 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20      /* Allocate 
1850: 61 20 6e 65 77 20 62 75 66 66 65 72 20 75 73 69  a new buffer usi
1860: 6e 67 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63  ng sqlite3Malloc
1870: 2e 20 42 65 66 6f 72 65 20 64 6f 69 6e 67 20 73  . Before doing s
1880: 6f 2c 20 65 78 69 74 20 74 68 65 0a 20 20 20 20  o, exit the.    
1890: 2a 2a 20 67 6c 6f 62 61 6c 20 70 63 61 63 68 65  ** global pcache
18a0: 20 6d 75 74 65 78 20 61 6e 64 20 75 6e 6c 6f 63   mutex and unloc
18b0: 6b 20 74 68 65 20 70 61 67 65 72 2d 63 61 63 68  k the pager-cach
18c0: 65 20 6f 62 6a 65 63 74 20 70 43 61 63 68 65 2e  e object pCache.
18d0: 20 54 68 69 73 20 69 73 20 0a 20 20 20 20 2a 2a   This is .    **
18e0: 20 73 6f 20 74 68 61 74 20 69 66 20 74 68 65 20   so that if the 
18f0: 61 74 74 65 6d 70 74 20 74 6f 20 61 6c 6c 6f 63  attempt to alloc
1900: 61 74 65 20 61 20 6e 65 77 20 62 75 66 66 65 72  ate a new buffer
1910: 20 63 61 75 73 65 73 20 74 68 65 20 74 68 65 20   causes the the 
1920: 0a 20 20 20 20 2a 2a 20 63 6f 6e 66 69 67 75 72  .    ** configur
1930: 65 64 20 73 6f 66 74 2d 68 65 61 70 2d 6c 69 6d  ed soft-heap-lim
1940: 69 74 20 74 6f 20 62 65 20 62 72 65 61 63 68 65  it to be breache
1950: 64 2c 20 69 74 20 77 69 6c 6c 20 62 65 20 70 6f  d, it will be po
1960: 73 73 69 62 6c 65 20 74 6f 0a 20 20 20 20 2a 2a  ssible to.    **
1970: 20 72 65 63 6c 61 69 6d 20 6d 65 6d 6f 72 79 20   reclaim memory 
1980: 66 72 6f 6d 20 74 68 69 73 20 70 61 67 65 72 2d  from this pager-
1990: 63 61 63 68 65 2e 0a 20 20 20 20 2a 2f 0a 20 20  cache..    */.  
19a0: 20 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75    pcache1LeaveMu
19b0: 74 65 78 28 29 3b 0a 20 20 20 20 70 20 3d 20 73  tex();.    p = s
19c0: 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 6e 42 79  qlite3Malloc(nBy
19d0: 74 65 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31  te);.    pcache1
19e0: 45 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a 20 20  EnterMutex();.  
19f0: 20 20 69 66 28 20 70 20 29 7b 0a 20 20 20 20 20    if( p ){.     
1a00: 20 69 6e 74 20 73 7a 20 3d 20 73 71 6c 69 74 65   int sz = sqlite
1a10: 33 4d 61 6c 6c 6f 63 53 69 7a 65 28 70 29 3b 0a  3MallocSize(p);.
1a20: 20 20 20 20 20 20 73 71 6c 69 74 65 33 53 74 61        sqlite3Sta
1a30: 74 75 73 41 64 64 28 53 51 4c 49 54 45 5f 53 54  tusAdd(SQLITE_ST
1a40: 41 54 55 53 5f 50 41 47 45 43 41 43 48 45 5f 4f  ATUS_PAGECACHE_O
1a50: 56 45 52 46 4c 4f 57 2c 20 73 7a 29 3b 0a 20 20  VERFLOW, sz);.  
1a60: 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e    }.  }.  return
1a70: 20 70 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65   p;.}../*.** Fre
1a80: 65 20 61 6e 20 61 6c 6c 6f 63 61 74 65 64 20 62  e an allocated b
1a90: 75 66 66 65 72 20 6f 62 74 61 69 6e 65 64 20 66  uffer obtained f
1aa0: 72 6f 6d 20 70 63 61 63 68 65 31 41 6c 6c 6f 63  rom pcache1Alloc
1ab0: 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ()..*/.static vo
1ac0: 69 64 20 70 63 61 63 68 65 31 46 72 65 65 28 76  id pcache1Free(v
1ad0: 6f 69 64 20 2a 70 29 7b 0a 20 20 61 73 73 65 72  oid *p){.  asser
1ae0: 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78  t( sqlite3_mutex
1af0: 5f 68 65 6c 64 28 70 63 61 63 68 65 31 2e 6d 75  _held(pcache1.mu
1b00: 74 65 78 29 20 29 3b 0a 20 20 69 66 28 20 70 3d  tex) );.  if( p=
1b10: 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 69  =0 ) return;.  i
1b20: 66 28 20 70 3e 3d 70 63 61 63 68 65 31 2e 70 53  f( p>=pcache1.pS
1b30: 74 61 72 74 20 26 26 20 70 3c 70 63 61 63 68 65  tart && p<pcache
1b40: 31 2e 70 45 6e 64 20 29 7b 0a 20 20 20 20 50 67  1.pEnd ){.    Pg
1b50: 46 72 65 65 73 6c 6f 74 20 2a 70 53 6c 6f 74 3b  Freeslot *pSlot;
1b60: 0a 20 20 20 20 73 71 6c 69 74 65 33 53 74 61 74  .    sqlite3Stat
1b70: 75 73 41 64 64 28 53 51 4c 49 54 45 5f 53 54 41  usAdd(SQLITE_STA
1b80: 54 55 53 5f 50 41 47 45 43 41 43 48 45 5f 55 53  TUS_PAGECACHE_US
1b90: 45 44 2c 20 2d 31 29 3b 0a 20 20 20 20 70 53 6c  ED, -1);.    pSl
1ba0: 6f 74 20 3d 20 28 50 67 46 72 65 65 73 6c 6f 74  ot = (PgFreeslot
1bb0: 2a 29 70 3b 0a 20 20 20 20 70 53 6c 6f 74 2d 3e  *)p;.    pSlot->
1bc0: 70 4e 65 78 74 20 3d 20 70 63 61 63 68 65 31 2e  pNext = pcache1.
1bd0: 70 46 72 65 65 3b 0a 20 20 20 20 70 63 61 63 68  pFree;.    pcach
1be0: 65 31 2e 70 46 72 65 65 20 3d 20 70 53 6c 6f 74  e1.pFree = pSlot
1bf0: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69  ;.  }else{.    i
1c00: 6e 74 20 69 53 69 7a 65 20 3d 20 73 71 6c 69 74  nt iSize = sqlit
1c10: 65 33 4d 61 6c 6c 6f 63 53 69 7a 65 28 70 29 3b  e3MallocSize(p);
1c20: 0a 20 20 20 20 73 71 6c 69 74 65 33 53 74 61 74  .    sqlite3Stat
1c30: 75 73 41 64 64 28 53 51 4c 49 54 45 5f 53 54 41  usAdd(SQLITE_STA
1c40: 54 55 53 5f 50 41 47 45 43 41 43 48 45 5f 4f 56  TUS_PAGECACHE_OV
1c50: 45 52 46 4c 4f 57 2c 20 2d 69 53 69 7a 65 29 3b  ERFLOW, -iSize);
1c60: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65  .    sqlite3_fre
1c70: 65 28 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a  e(p);.  }.}../*.
1c80: 2a 2a 20 41 6c 6c 6f 63 61 74 65 20 61 20 6e 65  ** Allocate a ne
1c90: 77 20 70 61 67 65 20 6f 62 6a 65 63 74 20 69 6e  w page object in
1ca0: 69 74 69 61 6c 6c 79 20 61 73 73 6f 63 69 61 74  itially associat
1cb0: 65 64 20 77 69 74 68 20 63 61 63 68 65 20 70 43  ed with cache pC
1cc0: 61 63 68 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ache..*/.static 
1cd0: 50 67 48 64 72 31 20 2a 70 63 61 63 68 65 31 41  PgHdr1 *pcache1A
1ce0: 6c 6c 6f 63 50 61 67 65 28 50 43 61 63 68 65 31  llocPage(PCache1
1cf0: 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 69 6e 74   *pCache){.  int
1d00: 20 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28   nByte = sizeof(
1d10: 50 67 48 64 72 31 29 20 2b 20 70 43 61 63 68 65  PgHdr1) + pCache
1d20: 2d 3e 73 7a 50 61 67 65 3b 0a 20 20 50 67 48 64  ->szPage;.  PgHd
1d30: 72 31 20 2a 70 20 3d 20 28 50 67 48 64 72 31 20  r1 *p = (PgHdr1 
1d40: 2a 29 70 63 61 63 68 65 31 41 6c 6c 6f 63 28 6e  *)pcache1Alloc(n
1d50: 42 79 74 65 29 3b 0a 20 20 69 66 28 20 70 20 29  Byte);.  if( p )
1d60: 7b 0a 20 20 20 20 6d 65 6d 73 65 74 28 70 2c 20  {.    memset(p, 
1d70: 30 2c 20 6e 42 79 74 65 29 3b 0a 20 20 20 20 69  0, nByte);.    i
1d80: 66 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67  f( pCache->bPurg
1d90: 65 61 62 6c 65 20 29 7b 0a 20 20 20 20 20 20 70  eable ){.      p
1da0: 63 61 63 68 65 31 2e 6e 43 75 72 72 65 6e 74 50  cache1.nCurrentP
1db0: 61 67 65 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 7d  age++;.    }.  }
1dc0: 0a 20 20 72 65 74 75 72 6e 20 70 3b 0a 7d 0a 0a  .  return p;.}..
1dd0: 2f 2a 0a 2a 2a 20 46 72 65 65 20 61 20 70 61 67  /*.** Free a pag
1de0: 65 20 6f 62 6a 65 63 74 20 61 6c 6c 6f 63 61 74  e object allocat
1df0: 65 64 20 62 79 20 70 63 61 63 68 65 31 41 6c 6c  ed by pcache1All
1e00: 6f 63 50 61 67 65 28 29 2e 0a 2a 2f 0a 73 74 61  ocPage()..*/.sta
1e10: 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 31  tic void pcache1
1e20: 46 72 65 65 50 61 67 65 28 50 67 48 64 72 31 20  FreePage(PgHdr1 
1e30: 2a 70 29 7b 0a 20 20 69 66 28 20 70 20 29 7b 0a  *p){.  if( p ){.
1e40: 20 20 20 20 69 66 28 20 70 2d 3e 70 43 61 63 68      if( p->pCach
1e50: 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 29 7b  e->bPurgeable ){
1e60: 0a 20 20 20 20 20 20 70 63 61 63 68 65 31 2e 6e  .      pcache1.n
1e70: 43 75 72 72 65 6e 74 50 61 67 65 2d 2d 3b 0a 20  CurrentPage--;. 
1e80: 20 20 20 7d 0a 20 20 20 20 70 63 61 63 68 65 31     }.    pcache1
1e90: 46 72 65 65 28 70 29 3b 0a 20 20 7d 0a 7d 0a 0a  Free(p);.  }.}..
1ea0: 2f 2a 0a 2a 2a 20 4d 61 6c 6c 6f 63 20 66 75 6e  /*.** Malloc fun
1eb0: 63 74 69 6f 6e 20 75 73 65 64 20 62 79 20 53 51  ction used by SQ
1ec0: 4c 69 74 65 20 74 6f 20 6f 62 74 61 69 6e 20 73  Lite to obtain s
1ed0: 70 61 63 65 20 66 72 6f 6d 20 74 68 65 20 62 75  pace from the bu
1ee0: 66 66 65 72 20 63 6f 6e 66 69 67 75 72 65 64 0a  ffer configured.
1ef0: 2a 2a 20 75 73 69 6e 67 20 73 71 6c 69 74 65 33  ** using sqlite3
1f00: 5f 63 6f 6e 66 69 67 28 53 51 4c 49 54 45 5f 43  _config(SQLITE_C
1f10: 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48 45 29  ONFIG_PAGECACHE)
1f20: 20 6f 70 74 69 6f 6e 2e 20 49 66 20 6e 6f 20 73   option. If no s
1f30: 75 63 68 20 62 75 66 66 65 72 0a 2a 2a 20 65 78  uch buffer.** ex
1f40: 69 73 74 73 2c 20 74 68 69 73 20 66 75 6e 63 74  ists, this funct
1f50: 69 6f 6e 20 66 61 6c 6c 73 20 62 61 63 6b 20 74  ion falls back t
1f60: 6f 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28  o sqlite3Malloc(
1f70: 29 2e 0a 2a 2f 0a 76 6f 69 64 20 2a 73 71 6c 69  )..*/.void *sqli
1f80: 74 65 33 50 61 67 65 4d 61 6c 6c 6f 63 28 69 6e  te3PageMalloc(in
1f90: 74 20 73 7a 29 7b 0a 20 20 76 6f 69 64 20 2a 70  t sz){.  void *p
1fa0: 3b 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65 72  ;.  pcache1Enter
1fb0: 4d 75 74 65 78 28 29 3b 0a 20 20 70 20 3d 20 70  Mutex();.  p = p
1fc0: 63 61 63 68 65 31 41 6c 6c 6f 63 28 73 7a 29 3b  cache1Alloc(sz);
1fd0: 0a 20 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d  .  pcache1LeaveM
1fe0: 75 74 65 78 28 29 3b 0a 20 20 72 65 74 75 72 6e  utex();.  return
1ff0: 20 70 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65   p;.}../*.** Fre
2000: 65 20 61 6e 20 61 6c 6c 6f 63 61 74 65 64 20 62  e an allocated b
2010: 75 66 66 65 72 20 6f 62 74 61 69 6e 65 64 20 66  uffer obtained f
2020: 72 6f 6d 20 73 71 6c 69 74 65 33 50 61 67 65 4d  rom sqlite3PageM
2030: 61 6c 6c 6f 63 28 29 2e 0a 2a 2f 0a 76 6f 69 64  alloc()..*/.void
2040: 20 73 71 6c 69 74 65 33 50 61 67 65 46 72 65 65   sqlite3PageFree
2050: 28 76 6f 69 64 20 2a 70 29 7b 0a 20 20 70 63 61  (void *p){.  pca
2060: 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 29  che1EnterMutex()
2070: 3b 0a 20 20 70 63 61 63 68 65 31 46 72 65 65 28  ;.  pcache1Free(
2080: 70 29 3b 0a 20 20 70 63 61 63 68 65 31 4c 65 61  p);.  pcache1Lea
2090: 76 65 4d 75 74 65 78 28 29 3b 0a 7d 0a 0a 2f 2a  veMutex();.}../*
20a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
20b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
20c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
20d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
20e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f  *************/./
20f0: 2a 2a 2a 2a 2a 2a 2a 2a 20 47 65 6e 65 72 61 6c  ******** General
2100: 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20   Implementation 
2110: 46 75 6e 63 74 69 6f 6e 73 20 2a 2a 2a 2a 2a 2a  Functions ******
2120: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a  **************/.
2140: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  ./*.** This func
2150: 74 69 6f 6e 20 69 73 20 75 73 65 64 20 74 6f 20  tion is used to 
2160: 72 65 73 69 7a 65 20 74 68 65 20 68 61 73 68 20  resize the hash 
2170: 74 61 62 6c 65 20 75 73 65 64 20 62 79 20 74 68  table used by th
2180: 65 20 63 61 63 68 65 20 70 61 73 73 65 64 0a 2a  e cache passed.*
2190: 2a 20 61 73 20 74 68 65 20 66 69 72 73 74 20 61  * as the first a
21a0: 72 67 75 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 54  rgument..**.** T
21b0: 68 65 20 67 6c 6f 62 61 6c 20 6d 75 74 65 78 20  he global mutex 
21c0: 6d 75 73 74 20 62 65 20 68 65 6c 64 20 77 68 65  must be held whe
21d0: 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  n this function 
21e0: 69 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f 0a 73 74  is called..*/.st
21f0: 61 74 69 63 20 69 6e 74 20 70 63 61 63 68 65 31  atic int pcache1
2200: 52 65 73 69 7a 65 48 61 73 68 28 50 43 61 63 68  ResizeHash(PCach
2210: 65 31 20 2a 70 29 7b 0a 20 20 50 67 48 64 72 31  e1 *p){.  PgHdr1
2220: 20 2a 2a 61 70 4e 65 77 3b 0a 20 20 75 6e 73 69   **apNew;.  unsi
2230: 67 6e 65 64 20 69 6e 74 20 6e 4e 65 77 3b 0a 20  gned int nNew;. 
2240: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 3b   unsigned int i;
2250: 0a 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c 69  ..  assert( sqli
2260: 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70  te3_mutex_held(p
2270: 63 61 63 68 65 31 2e 6d 75 74 65 78 29 20 29 3b  cache1.mutex) );
2280: 0a 0a 20 20 6e 4e 65 77 20 3d 20 70 2d 3e 6e 48  ..  nNew = p->nH
2290: 61 73 68 2a 32 3b 0a 20 20 69 66 28 20 6e 4e 65  ash*2;.  if( nNe
22a0: 77 3c 32 35 36 20 29 7b 0a 20 20 20 20 6e 4e 65  w<256 ){.    nNe
22b0: 77 20 3d 20 32 35 36 3b 0a 20 20 7d 0a 0a 20 20  w = 256;.  }..  
22c0: 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65  pcache1LeaveMute
22d0: 78 28 29 3b 0a 20 20 61 70 4e 65 77 20 3d 20 28  x();.  apNew = (
22e0: 50 67 48 64 72 31 20 2a 2a 29 73 71 6c 69 74 65  PgHdr1 **)sqlite
22f0: 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28  3_malloc(sizeof(
2300: 50 67 48 64 72 31 20 2a 29 2a 6e 4e 65 77 29 3b  PgHdr1 *)*nNew);
2310: 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d  .  pcache1EnterM
2320: 75 74 65 78 28 29 3b 0a 20 20 69 66 28 20 61 70  utex();.  if( ap
2330: 4e 65 77 20 29 7b 0a 20 20 20 20 6d 65 6d 73 65  New ){.    memse
2340: 74 28 61 70 4e 65 77 2c 20 30 2c 20 73 69 7a 65  t(apNew, 0, size
2350: 6f 66 28 50 67 48 64 72 31 20 2a 29 2a 6e 4e 65  of(PgHdr1 *)*nNe
2360: 77 29 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b  w);.    for(i=0;
2370: 20 69 3c 70 2d 3e 6e 48 61 73 68 3b 20 69 2b 2b   i<p->nHash; i++
2380: 29 7b 0a 20 20 20 20 20 20 50 67 48 64 72 31 20  ){.      PgHdr1 
2390: 2a 70 50 61 67 65 3b 0a 20 20 20 20 20 20 50 67  *pPage;.      Pg
23a0: 48 64 72 31 20 2a 70 4e 65 78 74 20 3d 20 70 2d  Hdr1 *pNext = p-
23b0: 3e 61 70 48 61 73 68 5b 69 5d 3b 0a 20 20 20 20  >apHash[i];.    
23c0: 20 20 77 68 69 6c 65 28 20 28 70 50 61 67 65 20    while( (pPage 
23d0: 3d 20 70 4e 65 78 74 29 20 29 7b 0a 20 20 20 20  = pNext) ){.    
23e0: 20 20 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74      unsigned int
23f0: 20 68 20 3d 20 70 50 61 67 65 2d 3e 69 4b 65 79   h = pPage->iKey
2400: 20 25 20 6e 4e 65 77 3b 0a 20 20 20 20 20 20 20   % nNew;.       
2410: 20 70 4e 65 78 74 20 3d 20 70 50 61 67 65 2d 3e   pNext = pPage->
2420: 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 20 20 70  pNext;.        p
2430: 50 61 67 65 2d 3e 70 4e 65 78 74 20 3d 20 61 70  Page->pNext = ap
2440: 4e 65 77 5b 68 5d 3b 0a 20 20 20 20 20 20 20 20  New[h];.        
2450: 61 70 4e 65 77 5b 68 5d 20 3d 20 70 50 61 67 65  apNew[h] = pPage
2460: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
2470: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
2480: 28 70 2d 3e 61 70 48 61 73 68 29 3b 0a 20 20 20  (p->apHash);.   
2490: 20 70 2d 3e 61 70 48 61 73 68 20 3d 20 61 70 4e   p->apHash = apN
24a0: 65 77 3b 0a 20 20 20 20 70 2d 3e 6e 48 61 73 68  ew;.    p->nHash
24b0: 20 3d 20 6e 4e 65 77 3b 0a 20 20 7d 0a 0a 20 20   = nNew;.  }..  
24c0: 72 65 74 75 72 6e 20 28 70 2d 3e 61 70 48 61 73  return (p->apHas
24d0: 68 20 3f 20 53 51 4c 49 54 45 5f 4f 4b 20 3a 20  h ? SQLITE_OK : 
24e0: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 29 3b 0a 7d  SQLITE_NOMEM);.}
24f0: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e  ../*.** This fun
2500: 63 74 69 6f 6e 20 69 73 20 75 73 65 64 20 69 6e  ction is used in
2510: 74 65 72 6e 61 6c 6c 79 20 74 6f 20 72 65 6d 6f  ternally to remo
2520: 76 65 20 74 68 65 20 70 61 67 65 20 70 50 61 67  ve the page pPag
2530: 65 20 66 72 6f 6d 20 74 68 65 20 0a 2a 2a 20 67  e from the .** g
2540: 6c 6f 62 61 6c 20 4c 52 55 20 6c 69 73 74 2c 20  lobal LRU list, 
2550: 69 66 20 69 73 20 70 61 72 74 20 6f 66 20 69 74  if is part of it
2560: 2e 20 49 66 20 70 50 61 67 65 20 69 73 20 6e 6f  . If pPage is no
2570: 74 20 70 61 72 74 20 6f 66 20 74 68 65 20 67 6c  t part of the gl
2580: 6f 62 61 6c 0a 2a 2a 20 4c 52 55 20 6c 69 73 74  obal.** LRU list
2590: 2c 20 74 68 65 6e 20 74 68 69 73 20 66 75 6e 63  , then this func
25a0: 74 69 6f 6e 20 69 73 20 61 20 6e 6f 2d 6f 70 2e  tion is a no-op.
25b0: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 67 6c 6f 62 61  .**.** The globa
25c0: 6c 20 6d 75 74 65 78 20 6d 75 73 74 20 62 65 20  l mutex must be 
25d0: 68 65 6c 64 20 77 68 65 6e 20 74 68 69 73 20 66  held when this f
25e0: 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65  unction is calle
25f0: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  d..*/.static voi
2600: 64 20 70 63 61 63 68 65 31 50 69 6e 50 61 67 65  d pcache1PinPage
2610: 28 50 67 48 64 72 31 20 2a 70 50 61 67 65 29 7b  (PgHdr1 *pPage){
2620: 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74  .  assert( sqlit
2630: 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 63  e3_mutex_held(pc
2640: 61 63 68 65 31 2e 6d 75 74 65 78 29 20 29 3b 0a  ache1.mutex) );.
2650: 20 20 69 66 28 20 70 50 61 67 65 20 26 26 20 28    if( pPage && (
2660: 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 20  pPage->pLruNext 
2670: 7c 7c 20 70 50 61 67 65 3d 3d 70 63 61 63 68 65  || pPage==pcache
2680: 31 2e 70 4c 72 75 54 61 69 6c 29 20 29 7b 0a 20  1.pLruTail) ){. 
2690: 20 20 20 69 66 28 20 70 50 61 67 65 2d 3e 70 4c     if( pPage->pL
26a0: 72 75 50 72 65 76 20 29 7b 0a 20 20 20 20 20 20  ruPrev ){.      
26b0: 70 50 61 67 65 2d 3e 70 4c 72 75 50 72 65 76 2d  pPage->pLruPrev-
26c0: 3e 70 4c 72 75 4e 65 78 74 20 3d 20 70 50 61 67  >pLruNext = pPag
26d0: 65 2d 3e 70 4c 72 75 4e 65 78 74 3b 0a 20 20 20  e->pLruNext;.   
26e0: 20 7d 0a 20 20 20 20 69 66 28 20 70 50 61 67 65   }.    if( pPage
26f0: 2d 3e 70 4c 72 75 4e 65 78 74 20 29 7b 0a 20 20  ->pLruNext ){.  
2700: 20 20 20 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e      pPage->pLruN
2710: 65 78 74 2d 3e 70 4c 72 75 50 72 65 76 20 3d 20  ext->pLruPrev = 
2720: 70 50 61 67 65 2d 3e 70 4c 72 75 50 72 65 76 3b  pPage->pLruPrev;
2730: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70  .    }.    if( p
2740: 63 61 63 68 65 31 2e 70 4c 72 75 48 65 61 64 3d  cache1.pLruHead=
2750: 3d 70 50 61 67 65 20 29 7b 0a 20 20 20 20 20 20  =pPage ){.      
2760: 70 63 61 63 68 65 31 2e 70 4c 72 75 48 65 61 64  pcache1.pLruHead
2770: 20 3d 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65   = pPage->pLruNe
2780: 78 74 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66  xt;.    }.    if
2790: 28 20 70 63 61 63 68 65 31 2e 70 4c 72 75 54 61  ( pcache1.pLruTa
27a0: 69 6c 3d 3d 70 50 61 67 65 20 29 7b 0a 20 20 20  il==pPage ){.   
27b0: 20 20 20 70 63 61 63 68 65 31 2e 70 4c 72 75 54     pcache1.pLruT
27c0: 61 69 6c 20 3d 20 70 50 61 67 65 2d 3e 70 4c 72  ail = pPage->pLr
27d0: 75 50 72 65 76 3b 0a 20 20 20 20 7d 0a 20 20 20  uPrev;.    }.   
27e0: 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74   pPage->pLruNext
27f0: 20 3d 20 30 3b 0a 20 20 20 20 70 50 61 67 65 2d   = 0;.    pPage-
2800: 3e 70 4c 72 75 50 72 65 76 20 3d 20 30 3b 0a 20  >pLruPrev = 0;. 
2810: 20 20 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65     pPage->pCache
2820: 2d 3e 6e 52 65 63 79 63 6c 61 62 6c 65 2d 2d 3b  ->nRecyclable--;
2830: 0a 20 20 7d 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 52  .  }.}.../*.** R
2840: 65 6d 6f 76 65 20 74 68 65 20 70 61 67 65 20 73  emove the page s
2850: 75 70 70 6c 69 65 64 20 61 73 20 61 6e 20 61 72  upplied as an ar
2860: 67 75 6d 65 6e 74 20 66 72 6f 6d 20 74 68 65 20  gument from the 
2870: 68 61 73 68 20 74 61 62 6c 65 20 0a 2a 2a 20 28  hash table .** (
2880: 50 43 61 63 68 65 31 2e 61 70 48 61 73 68 20 73  PCache1.apHash s
2890: 74 72 75 63 74 75 72 65 29 20 74 68 61 74 20 69  tructure) that i
28a0: 74 20 69 73 20 63 75 72 72 65 6e 74 6c 79 20 73  t is currently s
28b0: 74 6f 72 65 64 20 69 6e 2e 0a 2a 2a 0a 2a 2a 20  tored in..**.** 
28c0: 54 68 65 20 67 6c 6f 62 61 6c 20 6d 75 74 65 78  The global mutex
28d0: 20 6d 75 73 74 20 62 65 20 68 65 6c 64 20 77 68   must be held wh
28e0: 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  en this function
28f0: 20 69 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f 0a 73   is called..*/.s
2900: 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68  tatic void pcach
2910: 65 31 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73 68  e1RemoveFromHash
2920: 28 50 67 48 64 72 31 20 2a 70 50 61 67 65 29 7b  (PgHdr1 *pPage){
2930: 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  .  unsigned int 
2940: 68 3b 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43  h;.  PCache1 *pC
2950: 61 63 68 65 20 3d 20 70 50 61 67 65 2d 3e 70 43  ache = pPage->pC
2960: 61 63 68 65 3b 0a 20 20 50 67 48 64 72 31 20 2a  ache;.  PgHdr1 *
2970: 2a 70 70 3b 0a 0a 20 20 68 20 3d 20 70 50 61 67  *pp;..  h = pPag
2980: 65 2d 3e 69 4b 65 79 20 25 20 70 43 61 63 68 65  e->iKey % pCache
2990: 2d 3e 6e 48 61 73 68 3b 0a 20 20 66 6f 72 28 70  ->nHash;.  for(p
29a0: 70 3d 26 70 43 61 63 68 65 2d 3e 61 70 48 61 73  p=&pCache->apHas
29b0: 68 5b 68 5d 3b 20 28 2a 70 70 29 21 3d 70 50 61  h[h]; (*pp)!=pPa
29c0: 67 65 3b 20 70 70 3d 26 28 2a 70 70 29 2d 3e 70  ge; pp=&(*pp)->p
29d0: 4e 65 78 74 29 3b 0a 20 20 2a 70 70 20 3d 20 28  Next);.  *pp = (
29e0: 2a 70 70 29 2d 3e 70 4e 65 78 74 3b 0a 0a 20 20  *pp)->pNext;..  
29f0: 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 2d 2d 3b  pCache->nPage--;
2a00: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 74 68 65  .}../*.** If the
2a10: 72 65 20 61 72 65 20 63 75 72 72 65 6e 74 6c 79  re are currently
2a20: 20 6d 6f 72 65 20 74 68 61 6e 20 70 63 61 63 68   more than pcach
2a30: 65 2e 6e 4d 61 78 50 61 67 65 20 70 61 67 65 73  e.nMaxPage pages
2a40: 20 61 6c 6c 6f 63 61 74 65 64 2c 20 74 72 79 0a   allocated, try.
2a50: 2a 2a 20 74 6f 20 72 65 63 79 63 6c 65 20 70 61  ** to recycle pa
2a60: 67 65 73 20 74 6f 20 72 65 64 75 63 65 20 74 68  ges to reduce th
2a70: 65 20 6e 75 6d 62 65 72 20 61 6c 6c 6f 63 61 74  e number allocat
2a80: 65 64 20 74 6f 20 70 63 61 63 68 65 2e 6e 4d 61  ed to pcache.nMa
2a90: 78 50 61 67 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  xPage..*/.static
2aa0: 20 76 6f 69 64 20 70 63 61 63 68 65 31 45 6e 66   void pcache1Enf
2ab0: 6f 72 63 65 4d 61 78 50 61 67 65 28 76 6f 69 64  orceMaxPage(void
2ac0: 29 7b 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c  ){.  assert( sql
2ad0: 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28  ite3_mutex_held(
2ae0: 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29 20 29  pcache1.mutex) )
2af0: 3b 0a 20 20 77 68 69 6c 65 28 20 70 63 61 63 68  ;.  while( pcach
2b00: 65 31 2e 6e 43 75 72 72 65 6e 74 50 61 67 65 3e  e1.nCurrentPage>
2b10: 70 63 61 63 68 65 31 2e 6e 4d 61 78 50 61 67 65  pcache1.nMaxPage
2b20: 20 26 26 20 70 63 61 63 68 65 31 2e 70 4c 72 75   && pcache1.pLru
2b30: 54 61 69 6c 20 29 7b 0a 20 20 20 20 50 67 48 64  Tail ){.    PgHd
2b40: 72 31 20 2a 70 20 3d 20 70 63 61 63 68 65 31 2e  r1 *p = pcache1.
2b50: 70 4c 72 75 54 61 69 6c 3b 0a 20 20 20 20 70 63  pLruTail;.    pc
2b60: 61 63 68 65 31 50 69 6e 50 61 67 65 28 70 29 3b  ache1PinPage(p);
2b70: 0a 20 20 20 20 70 63 61 63 68 65 31 52 65 6d 6f  .    pcache1Remo
2b80: 76 65 46 72 6f 6d 48 61 73 68 28 70 29 3b 0a 20  veFromHash(p);. 
2b90: 20 20 20 70 63 61 63 68 65 31 46 72 65 65 50 61     pcache1FreePa
2ba0: 67 65 28 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a  ge(p);.  }.}../*
2bb0: 0a 2a 2a 20 44 69 73 63 61 72 64 20 61 6c 6c 20  .** Discard all 
2bc0: 70 61 67 65 73 20 66 72 6f 6d 20 63 61 63 68 65  pages from cache
2bd0: 20 70 43 61 63 68 65 20 77 69 74 68 20 61 20 70   pCache with a p
2be0: 61 67 65 20 6e 75 6d 62 65 72 20 28 6b 65 79 20  age number (key 
2bf0: 76 61 6c 75 65 29 20 0a 2a 2a 20 67 72 65 61 74  value) .** great
2c00: 65 72 20 74 68 61 6e 20 6f 72 20 65 71 75 61 6c  er than or equal
2c10: 20 74 6f 20 69 4c 69 6d 69 74 2e 20 41 6e 79 20   to iLimit. Any 
2c20: 70 69 6e 6e 65 64 20 70 61 67 65 73 20 74 68 61  pinned pages tha
2c30: 74 20 6d 65 65 74 20 74 68 69 73 20 0a 2a 2a 20  t meet this .** 
2c40: 63 72 69 74 65 72 69 61 20 61 72 65 20 75 6e 70  criteria are unp
2c50: 69 6e 6e 65 64 20 62 65 66 6f 72 65 20 74 68 65  inned before the
2c60: 79 20 61 72 65 20 64 69 73 63 61 72 64 65 64 2e  y are discarded.
2c70: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 67 6c 6f 62 61  .**.** The globa
2c80: 6c 20 6d 75 74 65 78 20 6d 75 73 74 20 62 65 20  l mutex must be 
2c90: 68 65 6c 64 20 77 68 65 6e 20 74 68 69 73 20 66  held when this f
2ca0: 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65  unction is calle
2cb0: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  d..*/.static voi
2cc0: 64 20 70 63 61 63 68 65 31 54 72 75 6e 63 61 74  d pcache1Truncat
2cd0: 65 55 6e 73 61 66 65 28 0a 20 20 50 43 61 63 68  eUnsafe(.  PCach
2ce0: 65 31 20 2a 70 43 61 63 68 65 2c 20 0a 20 20 75  e1 *pCache, .  u
2cf0: 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4c 69 6d  nsigned int iLim
2d00: 69 74 20 0a 29 7b 0a 20 20 75 6e 73 69 67 6e 65  it .){.  unsigne
2d10: 64 20 69 6e 74 20 68 3b 0a 20 20 61 73 73 65 72  d int h;.  asser
2d20: 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78  t( sqlite3_mutex
2d30: 5f 68 65 6c 64 28 70 63 61 63 68 65 31 2e 6d 75  _held(pcache1.mu
2d40: 74 65 78 29 20 29 3b 0a 20 20 66 6f 72 28 68 3d  tex) );.  for(h=
2d50: 30 3b 20 68 3c 70 43 61 63 68 65 2d 3e 6e 48 61  0; h<pCache->nHa
2d60: 73 68 3b 20 68 2b 2b 29 7b 0a 20 20 20 20 50 67  sh; h++){.    Pg
2d70: 48 64 72 31 20 2a 2a 70 70 20 3d 20 26 70 43 61  Hdr1 **pp = &pCa
2d80: 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 20  che->apHash[h]; 
2d90: 0a 20 20 20 20 50 67 48 64 72 31 20 2a 70 50 61  .    PgHdr1 *pPa
2da0: 67 65 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 28  ge;.    while( (
2db0: 70 50 61 67 65 20 3d 20 2a 70 70 29 20 29 7b 0a  pPage = *pp) ){.
2dc0: 20 20 20 20 20 20 69 66 28 20 70 50 61 67 65 2d        if( pPage-
2dd0: 3e 69 4b 65 79 3e 3d 69 4c 69 6d 69 74 20 29 7b  >iKey>=iLimit ){
2de0: 0a 20 20 20 20 20 20 20 20 70 63 61 63 68 65 31  .        pcache1
2df0: 50 69 6e 50 61 67 65 28 70 50 61 67 65 29 3b 0a  PinPage(pPage);.
2e00: 20 20 20 20 20 20 20 20 2a 70 70 20 3d 20 70 50          *pp = pP
2e10: 61 67 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20  age->pNext;.    
2e20: 20 20 20 20 70 63 61 63 68 65 31 46 72 65 65 50      pcache1FreeP
2e30: 61 67 65 28 70 50 61 67 65 29 3b 0a 20 20 20 20  age(pPage);.    
2e40: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20    }else{.       
2e50: 20 70 70 20 3d 20 26 70 50 61 67 65 2d 3e 70 4e   pp = &pPage->pN
2e60: 65 78 74 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  ext;.      }.   
2e70: 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a   }.  }.}../*****
2e80: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2e90: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2ea0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2eb0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2ec0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 2a 2a 2a  *********/./****
2ed0: 2a 2a 2a 2a 20 73 71 6c 69 74 65 33 5f 70 63 61  **** sqlite3_pca
2ee0: 63 68 65 20 4d 65 74 68 6f 64 73 20 2a 2a 2a 2a  che Methods ****
2ef0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2f00: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2f10: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f 2a 0a  **********/../*.
2f20: 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  ** Implementatio
2f30: 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33  n of the sqlite3
2f40: 5f 70 63 61 63 68 65 2e 78 49 6e 69 74 20 6d 65  _pcache.xInit me
2f50: 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  thod..*/.static 
2f60: 69 6e 74 20 70 63 61 63 68 65 31 49 6e 69 74 28  int pcache1Init(
2f70: 76 6f 69 64 20 2a 4e 6f 74 55 73 65 64 29 7b 0a  void *NotUsed){.
2f80: 20 20 55 4e 55 53 45 44 5f 50 41 52 41 4d 45 54    UNUSED_PARAMET
2f90: 45 52 28 4e 6f 74 55 73 65 64 29 3b 0a 20 20 6d  ER(NotUsed);.  m
2fa0: 65 6d 73 65 74 28 26 70 63 61 63 68 65 31 2c 20  emset(&pcache1, 
2fb0: 30 2c 20 73 69 7a 65 6f 66 28 70 63 61 63 68 65  0, sizeof(pcache
2fc0: 31 29 29 3b 0a 20 20 69 66 28 20 73 71 6c 69 74  1));.  if( sqlit
2fd0: 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 62  e3GlobalConfig.b
2fe0: 43 6f 72 65 4d 75 74 65 78 20 29 7b 0a 20 20 20  CoreMutex ){.   
2ff0: 20 70 63 61 63 68 65 31 2e 6d 75 74 65 78 20 3d   pcache1.mutex =
3000: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 61   sqlite3_mutex_a
3010: 6c 6c 6f 63 28 53 51 4c 49 54 45 5f 4d 55 54 45  lloc(SQLITE_MUTE
3020: 58 5f 53 54 41 54 49 43 5f 4c 52 55 29 3b 0a 20  X_STATIC_LRU);. 
3030: 20 7d 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49   }.  return SQLI
3040: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  TE_OK;.}../*.** 
3050: 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  Implementation o
3060: 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63  f the sqlite3_pc
3070: 61 63 68 65 2e 78 53 68 75 74 64 6f 77 6e 20 6d  ache.xShutdown m
3080: 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63  ethod..*/.static
3090: 20 76 6f 69 64 20 70 63 61 63 68 65 31 53 68 75   void pcache1Shu
30a0: 74 64 6f 77 6e 28 76 6f 69 64 20 2a 4e 6f 74 55  tdown(void *NotU
30b0: 73 65 64 29 7b 0a 20 20 55 4e 55 53 45 44 5f 50  sed){.  UNUSED_P
30c0: 41 52 41 4d 45 54 45 52 28 4e 6f 74 55 73 65 64  ARAMETER(NotUsed
30d0: 29 3b 0a 20 20 2f 2a 20 6e 6f 2d 6f 70 20 2a 2f  );.  /* no-op */
30e0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d  .}../*.** Implem
30f0: 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20  entation of the 
3100: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78  sqlite3_pcache.x
3110: 43 72 65 61 74 65 20 6d 65 74 68 6f 64 2e 0a 2a  Create method..*
3120: 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65 20 61 20  *.** Allocate a 
3130: 6e 65 77 20 63 61 63 68 65 2e 0a 2a 2f 0a 73 74  new cache..*/.st
3140: 61 74 69 63 20 73 71 6c 69 74 65 33 5f 70 63 61  atic sqlite3_pca
3150: 63 68 65 20 2a 70 63 61 63 68 65 31 43 72 65 61  che *pcache1Crea
3160: 74 65 28 69 6e 74 20 73 7a 50 61 67 65 2c 20 69  te(int szPage, i
3170: 6e 74 20 62 50 75 72 67 65 61 62 6c 65 29 7b 0a  nt bPurgeable){.
3180: 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68    PCache1 *pCach
3190: 65 3b 0a 0a 20 20 70 43 61 63 68 65 20 3d 20 28  e;..  pCache = (
31a0: 50 43 61 63 68 65 31 20 2a 29 73 71 6c 69 74 65  PCache1 *)sqlite
31b0: 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28  3_malloc(sizeof(
31c0: 50 43 61 63 68 65 31 29 29 3b 0a 20 20 69 66 28  PCache1));.  if(
31d0: 20 70 43 61 63 68 65 20 29 7b 0a 20 20 20 20 6d   pCache ){.    m
31e0: 65 6d 73 65 74 28 70 43 61 63 68 65 2c 20 30 2c  emset(pCache, 0,
31f0: 20 73 69 7a 65 6f 66 28 50 43 61 63 68 65 31 29   sizeof(PCache1)
3200: 29 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 73  );.    pCache->s
3210: 7a 50 61 67 65 20 3d 20 73 7a 50 61 67 65 3b 0a  zPage = szPage;.
3220: 20 20 20 20 70 43 61 63 68 65 2d 3e 62 50 75 72      pCache->bPur
3230: 67 65 61 62 6c 65 20 3d 20 28 62 50 75 72 67 65  geable = (bPurge
3240: 61 62 6c 65 20 3f 20 31 20 3a 20 30 29 3b 0a 20  able ? 1 : 0);. 
3250: 20 20 20 69 66 28 20 62 50 75 72 67 65 61 62 6c     if( bPurgeabl
3260: 65 20 29 7b 0a 20 20 20 20 20 20 70 43 61 63 68  e ){.      pCach
3270: 65 2d 3e 6e 4d 69 6e 20 3d 20 31 30 3b 0a 20 20  e->nMin = 10;.  
3280: 20 20 20 20 70 63 61 63 68 65 31 45 6e 74 65 72      pcache1Enter
3290: 4d 75 74 65 78 28 29 3b 0a 20 20 20 20 20 20 70  Mutex();.      p
32a0: 63 61 63 68 65 31 2e 6e 4d 69 6e 50 61 67 65 20  cache1.nMinPage 
32b0: 2b 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 3b  += pCache->nMin;
32c0: 0a 20 20 20 20 20 20 70 63 61 63 68 65 31 4c 65  .      pcache1Le
32d0: 61 76 65 4d 75 74 65 78 28 29 3b 0a 20 20 20 20  aveMutex();.    
32e0: 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 28  }.  }.  return (
32f0: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a  sqlite3_pcache *
3300: 29 70 43 61 63 68 65 3b 0a 7d 0a 0a 2f 2a 0a 2a  )pCache;.}../*.*
3310: 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  * Implementation
3320: 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f   of the sqlite3_
3330: 70 63 61 63 68 65 2e 78 43 61 63 68 65 73 69 7a  pcache.xCachesiz
3340: 65 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a  e method. .**.**
3350: 20 43 6f 6e 66 69 67 75 72 65 20 74 68 65 20 63   Configure the c
3360: 61 63 68 65 5f 73 69 7a 65 20 6c 69 6d 69 74 20  ache_size limit 
3370: 66 6f 72 20 61 20 63 61 63 68 65 2e 0a 2a 2f 0a  for a cache..*/.
3380: 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63  static void pcac
3390: 68 65 31 43 61 63 68 65 73 69 7a 65 28 73 71 6c  he1Cachesize(sql
33a0: 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70 2c 20  ite3_pcache *p, 
33b0: 69 6e 74 20 6e 4d 61 78 29 7b 0a 20 20 50 43 61  int nMax){.  PCa
33c0: 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28  che1 *pCache = (
33d0: 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20 20 69  PCache1 *)p;.  i
33e0: 66 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67  f( pCache->bPurg
33f0: 65 61 62 6c 65 20 29 7b 0a 20 20 20 20 70 63 61  eable ){.    pca
3400: 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 29  che1EnterMutex()
3410: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 6e 4d  ;.    pcache1.nM
3420: 61 78 50 61 67 65 20 2b 3d 20 28 6e 4d 61 78 20  axPage += (nMax 
3430: 2d 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 29 3b  - pCache->nMax);
3440: 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 6e 4d 61  .    pCache->nMa
3450: 78 20 3d 20 6e 4d 61 78 3b 0a 20 20 20 20 70 63  x = nMax;.    pc
3460: 61 63 68 65 31 45 6e 66 6f 72 63 65 4d 61 78 50  ache1EnforceMaxP
3470: 61 67 65 28 29 3b 0a 20 20 20 20 70 63 61 63 68  age();.    pcach
3480: 65 31 4c 65 61 76 65 4d 75 74 65 78 28 29 3b 0a  e1LeaveMutex();.
3490: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70    }.}../*.** Imp
34a0: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74  lementation of t
34b0: 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68  he sqlite3_pcach
34c0: 65 2e 78 50 61 67 65 63 6f 75 6e 74 20 6d 65 74  e.xPagecount met
34d0: 68 6f 64 2e 20 0a 2a 2f 0a 73 74 61 74 69 63 20  hod. .*/.static 
34e0: 69 6e 74 20 70 63 61 63 68 65 31 50 61 67 65 63  int pcache1Pagec
34f0: 6f 75 6e 74 28 73 71 6c 69 74 65 33 5f 70 63 61  ount(sqlite3_pca
3500: 63 68 65 20 2a 70 29 7b 0a 20 20 69 6e 74 20 6e  che *p){.  int n
3510: 3b 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65 72  ;.  pcache1Enter
3520: 4d 75 74 65 78 28 29 3b 0a 20 20 6e 20 3d 20 28  Mutex();.  n = (
3530: 28 50 43 61 63 68 65 31 20 2a 29 70 29 2d 3e 6e  (PCache1 *)p)->n
3540: 50 61 67 65 3b 0a 20 20 70 63 61 63 68 65 31 4c  Page;.  pcache1L
3550: 65 61 76 65 4d 75 74 65 78 28 29 3b 0a 20 20 72  eaveMutex();.  r
3560: 65 74 75 72 6e 20 6e 3b 0a 7d 0a 0a 2f 2a 0a 2a  eturn n;.}../*.*
3570: 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  * Implementation
3580: 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f   of the sqlite3_
3590: 70 63 61 63 68 65 2e 78 46 65 74 63 68 20 6d 65  pcache.xFetch me
35a0: 74 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20 46 65 74  thod. .**.** Fet
35b0: 63 68 20 61 20 70 61 67 65 20 62 79 20 6b 65 79  ch a page by key
35c0: 20 76 61 6c 75 65 2e 0a 2a 2a 0a 2a 2a 20 57 68   value..**.** Wh
35d0: 65 74 68 65 72 20 6f 72 20 6e 6f 74 20 61 20 6e  ether or not a n
35e0: 65 77 20 70 61 67 65 20 6d 61 79 20 62 65 20 61  ew page may be a
35f0: 6c 6c 6f 63 61 74 65 64 20 62 79 20 74 68 69 73  llocated by this
3600: 20 66 75 6e 63 74 69 6f 6e 20 64 65 70 65 6e 64   function depend
3610: 73 20 6f 6e 0a 2a 2a 20 74 68 65 20 76 61 6c 75  s on.** the valu
3620: 65 20 6f 66 20 74 68 65 20 63 72 65 61 74 65 46  e of the createF
3630: 6c 61 67 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2a  lag argument..**
3640: 0a 2a 2a 20 54 68 65 72 65 20 61 72 65 20 74 68  .** There are th
3650: 72 65 65 20 64 69 66 66 65 72 65 6e 74 20 61 70  ree different ap
3660: 70 72 6f 61 63 68 65 73 20 74 6f 20 6f 62 74 61  proaches to obta
3670: 69 6e 69 6e 67 20 73 70 61 63 65 20 66 6f 72 20  ining space for 
3680: 61 20 70 61 67 65 2c 0a 2a 2a 20 64 65 70 65 6e  a page,.** depen
3690: 64 69 6e 67 20 6f 6e 20 74 68 65 20 76 61 6c 75  ding on the valu
36a0: 65 20 6f 66 20 70 61 72 61 6d 65 74 65 72 20 63  e of parameter c
36b0: 72 65 61 74 65 46 6c 61 67 20 28 77 68 69 63 68  reateFlag (which
36c0: 20 6d 61 79 20 62 65 20 30 2c 20 31 20 6f 72 20   may be 0, 1 or 
36d0: 32 29 2e 0a 2a 2a 0a 2a 2a 20 20 20 31 2e 20 52  2)..**.**   1. R
36e0: 65 67 61 72 64 6c 65 73 73 20 6f 66 20 74 68 65  egardless of the
36f0: 20 76 61 6c 75 65 20 6f 66 20 63 72 65 61 74 65   value of create
3700: 46 6c 61 67 2c 20 74 68 65 20 63 61 63 68 65 20  Flag, the cache 
3710: 69 73 20 73 65 61 72 63 68 65 64 20 66 6f 72 20  is searched for 
3720: 61 20 0a 2a 2a 20 20 20 20 20 20 63 6f 70 79 20  a .**      copy 
3730: 6f 66 20 74 68 65 20 72 65 71 75 65 73 74 65 64  of the requested
3740: 20 70 61 67 65 2e 20 49 66 20 6f 6e 65 20 69 73   page. If one is
3750: 20 66 6f 75 6e 64 2c 20 69 74 20 69 73 20 72 65   found, it is re
3760: 74 75 72 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 20 20  turned..**.**   
3770: 32 2e 20 49 66 20 63 72 65 61 74 65 46 6c 61 67  2. If createFlag
3780: 3d 3d 30 20 61 6e 64 20 74 68 65 20 70 61 67 65  ==0 and the page
3790: 20 69 73 20 6e 6f 74 20 61 6c 72 65 61 64 79 20   is not already 
37a0: 69 6e 20 74 68 65 20 63 61 63 68 65 2c 20 4e 55  in the cache, NU
37b0: 4c 4c 20 69 73 0a 2a 2a 20 20 20 20 20 20 72 65  LL is.**      re
37c0: 74 75 72 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 20 20  turned..**.**   
37d0: 33 2e 20 49 66 20 63 72 65 61 74 65 46 6c 61 67  3. If createFlag
37e0: 20 69 73 20 31 2c 20 74 68 65 20 63 61 63 68 65   is 1, the cache
37f0: 20 69 73 20 6d 61 72 6b 65 64 20 61 73 20 70 75   is marked as pu
3800: 72 67 65 61 62 6c 65 20 61 6e 64 20 74 68 65 20  rgeable and the 
3810: 70 61 67 65 20 69 73 20 0a 2a 2a 20 20 20 20 20  page is .**     
3820: 20 6e 6f 74 20 61 6c 72 65 61 64 79 20 69 6e 20   not already in 
3830: 74 68 65 20 63 61 63 68 65 2c 20 61 6e 64 20 69  the cache, and i
3840: 66 20 65 69 74 68 65 72 20 6f 66 20 74 68 65 20  f either of the 
3850: 66 6f 6c 6c 6f 77 69 6e 67 20 61 72 65 20 74 72  following are tr
3860: 75 65 2c 20 0a 2a 2a 20 20 20 20 20 20 72 65 74  ue, .**      ret
3870: 75 72 6e 20 4e 55 4c 4c 3a 0a 2a 2a 0a 2a 2a 20  urn NULL:.**.** 
3880: 20 20 20 20 20 20 28 61 29 20 74 68 65 20 6e 75        (a) the nu
3890: 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 70 69  mber of pages pi
38a0: 6e 6e 65 64 20 62 79 20 74 68 65 20 63 61 63 68  nned by the cach
38b0: 65 20 69 73 20 67 72 65 61 74 65 72 20 74 68 61  e is greater tha
38c0: 6e 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 50  n.**           P
38d0: 43 61 63 68 65 31 2e 6e 4d 61 78 2c 20 6f 72 0a  Cache1.nMax, or.
38e0: 2a 2a 20 20 20 20 20 20 20 28 62 29 20 74 68 65  **       (b) the
38f0: 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73   number of pages
3900: 20 70 69 6e 6e 65 64 20 62 79 20 74 68 65 20 63   pinned by the c
3910: 61 63 68 65 20 69 73 20 67 72 65 61 74 65 72 20  ache is greater 
3920: 74 68 61 6e 0a 2a 2a 20 20 20 20 20 20 20 20 20  than.**         
3930: 20 20 74 68 65 20 73 75 6d 20 6f 66 20 6e 4d 61    the sum of nMa
3940: 78 20 66 6f 72 20 61 6c 6c 20 70 75 72 67 65 61  x for all purgea
3950: 62 6c 65 20 63 61 63 68 65 73 2c 20 6c 65 73 73  ble caches, less
3960: 20 74 68 65 20 73 75 6d 20 6f 66 20 0a 2a 2a 20   the sum of .** 
3970: 20 20 20 20 20 20 20 20 20 20 6e 4d 69 6e 20 66            nMin f
3980: 6f 72 20 61 6c 6c 20 6f 74 68 65 72 20 70 75 72  or all other pur
3990: 67 65 61 62 6c 65 20 63 61 63 68 65 73 2e 20 0a  geable caches. .
39a0: 2a 2a 0a 2a 2a 20 20 20 34 2e 20 49 66 20 6e 6f  **.**   4. If no
39b0: 6e 65 20 6f 66 20 74 68 65 20 66 69 72 73 74 20  ne of the first 
39c0: 74 68 72 65 65 20 63 6f 6e 64 69 74 69 6f 6e 73  three conditions
39d0: 20 61 70 70 6c 79 20 61 6e 64 20 74 68 65 20 63   apply and the c
39e0: 61 63 68 65 20 69 73 20 6d 61 72 6b 65 64 0a 2a  ache is marked.*
39f0: 2a 20 20 20 20 20 20 61 73 20 70 75 72 67 65 61  *      as purgea
3a00: 62 6c 65 2c 20 61 6e 64 20 69 66 20 6f 6e 65 20  ble, and if one 
3a10: 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  of the following
3a20: 20 69 73 20 74 72 75 65 3a 0a 2a 2a 0a 2a 2a 20   is true:.**.** 
3a30: 20 20 20 20 20 20 28 61 29 20 54 68 65 20 6e 75        (a) The nu
3a40: 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 61 6c  mber of pages al
3a50: 6c 6f 63 61 74 65 64 20 66 6f 72 20 74 68 65 20  located for the 
3a60: 63 61 63 68 65 20 69 73 20 61 6c 72 65 61 64 79  cache is already
3a70: 20 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 50   .**           P
3a80: 43 61 63 68 65 31 2e 6e 4d 61 78 2c 20 6f 72 0a  Cache1.nMax, or.
3a90: 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 28 62 29 20  **.**       (b) 
3aa0: 54 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 61  The number of pa
3ab0: 67 65 73 20 61 6c 6c 6f 63 61 74 65 64 20 66 6f  ges allocated fo
3ac0: 72 20 61 6c 6c 20 70 75 72 67 65 61 62 6c 65 20  r all purgeable 
3ad0: 63 61 63 68 65 73 20 69 73 0a 2a 2a 20 20 20 20  caches is.**    
3ae0: 20 20 20 20 20 20 20 61 6c 72 65 61 64 79 20 65         already e
3af0: 71 75 61 6c 20 74 6f 20 6f 72 20 67 72 65 61 74  qual to or great
3b00: 65 72 20 74 68 61 6e 20 74 68 65 20 73 75 6d 20  er than the sum 
3b10: 6f 66 20 6e 4d 61 78 20 66 6f 72 20 61 6c 6c 0a  of nMax for all.
3b20: 2a 2a 20 20 20 20 20 20 20 20 20 20 20 70 75 72  **           pur
3b30: 67 65 61 62 6c 65 20 63 61 63 68 65 73 2c 0a 2a  geable caches,.*
3b40: 2a 0a 2a 2a 20 20 20 20 20 20 74 68 65 6e 20 61  *.**      then a
3b50: 74 74 65 6d 70 74 20 74 6f 20 72 65 63 79 63 6c  ttempt to recycl
3b60: 65 20 61 20 70 61 67 65 20 66 72 6f 6d 20 74 68  e a page from th
3b70: 65 20 4c 52 55 20 6c 69 73 74 2e 20 49 66 20 69  e LRU list. If i
3b80: 74 20 69 73 20 74 68 65 20 72 69 67 68 74 0a 2a  t is the right.*
3b90: 2a 20 20 20 20 20 20 73 69 7a 65 2c 20 72 65 74  *      size, ret
3ba0: 75 72 6e 20 74 68 65 20 72 65 63 79 63 6c 65 64  urn the recycled
3bb0: 20 62 75 66 66 65 72 2e 20 4f 74 68 65 72 77 69   buffer. Otherwi
3bc0: 73 65 2c 20 66 72 65 65 20 74 68 65 20 62 75 66  se, free the buf
3bd0: 66 65 72 20 61 6e 64 0a 2a 2a 20 20 20 20 20 20  fer and.**      
3be0: 70 72 6f 63 65 65 64 20 74 6f 20 73 74 65 70 20  proceed to step 
3bf0: 35 2e 20 0a 2a 2a 0a 2a 2a 20 20 20 35 2e 20 4f  5. .**.**   5. O
3c00: 74 68 65 72 77 69 73 65 2c 20 61 6c 6c 6f 63 61  therwise, alloca
3c10: 74 65 20 61 6e 64 20 72 65 74 75 72 6e 20 61 20  te and return a 
3c20: 6e 65 77 20 70 61 67 65 20 62 75 66 66 65 72 2e  new page buffer.
3c30: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
3c40: 2a 70 63 61 63 68 65 31 46 65 74 63 68 28 73 71  *pcache1Fetch(sq
3c50: 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70 2c  lite3_pcache *p,
3c60: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4b   unsigned int iK
3c70: 65 79 2c 20 69 6e 74 20 63 72 65 61 74 65 46 6c  ey, int createFl
3c80: 61 67 29 7b 0a 20 20 75 6e 73 69 67 6e 65 64 20  ag){.  unsigned 
3c90: 69 6e 74 20 6e 50 69 6e 6e 65 64 3b 0a 20 20 50  int nPinned;.  P
3ca0: 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d  Cache1 *pCache =
3cb0: 20 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20   (PCache1 *)p;. 
3cc0: 20 50 67 48 64 72 31 20 2a 70 50 61 67 65 20 3d   PgHdr1 *pPage =
3cd0: 20 30 3b 0a 0a 20 20 70 63 61 63 68 65 31 45 6e   0;..  pcache1En
3ce0: 74 65 72 4d 75 74 65 78 28 29 3b 0a 20 20 69 66  terMutex();.  if
3cf0: 28 20 63 72 65 61 74 65 46 6c 61 67 3d 3d 31 20  ( createFlag==1 
3d00: 29 20 73 71 6c 69 74 65 33 42 65 67 69 6e 42 65  ) sqlite3BeginBe
3d10: 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 0a 0a 20  nignMalloc();.. 
3d20: 20 2f 2a 20 53 65 61 72 63 68 20 74 68 65 20 68   /* Search the h
3d30: 61 73 68 20 74 61 62 6c 65 20 66 6f 72 20 61 6e  ash table for an
3d40: 20 65 78 69 73 74 69 6e 67 20 65 6e 74 72 79 2e   existing entry.
3d50: 20 2a 2f 0a 20 20 69 66 28 20 70 43 61 63 68 65   */.  if( pCache
3d60: 2d 3e 6e 48 61 73 68 3e 30 20 29 7b 0a 20 20 20  ->nHash>0 ){.   
3d70: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 20   unsigned int h 
3d80: 3d 20 69 4b 65 79 20 25 20 70 43 61 63 68 65 2d  = iKey % pCache-
3d90: 3e 6e 48 61 73 68 3b 0a 20 20 20 20 66 6f 72 28  >nHash;.    for(
3da0: 70 50 61 67 65 3d 70 43 61 63 68 65 2d 3e 61 70  pPage=pCache->ap
3db0: 48 61 73 68 5b 68 5d 3b 20 70 50 61 67 65 26 26  Hash[h]; pPage&&
3dc0: 70 50 61 67 65 2d 3e 69 4b 65 79 21 3d 69 4b 65  pPage->iKey!=iKe
3dd0: 79 3b 20 70 50 61 67 65 3d 70 50 61 67 65 2d 3e  y; pPage=pPage->
3de0: 70 4e 65 78 74 29 3b 0a 20 20 7d 0a 0a 20 20 69  pNext);.  }..  i
3df0: 66 28 20 70 50 61 67 65 20 7c 7c 20 63 72 65 61  f( pPage || crea
3e00: 74 65 46 6c 61 67 3d 3d 30 20 29 7b 0a 20 20 20  teFlag==0 ){.   
3e10: 20 70 63 61 63 68 65 31 50 69 6e 50 61 67 65 28   pcache1PinPage(
3e20: 70 50 61 67 65 29 3b 0a 20 20 20 20 67 6f 74 6f  pPage);.    goto
3e30: 20 66 65 74 63 68 5f 6f 75 74 3b 0a 20 20 7d 0a   fetch_out;.  }.
3e40: 0a 20 20 2f 2a 20 53 74 65 70 20 33 20 6f 66 20  .  /* Step 3 of 
3e50: 68 65 61 64 65 72 20 63 6f 6d 6d 65 6e 74 2e 20  header comment. 
3e60: 2a 2f 0a 20 20 6e 50 69 6e 6e 65 64 20 3d 20 70  */.  nPinned = p
3e70: 43 61 63 68 65 2d 3e 6e 50 61 67 65 20 2d 20 70  Cache->nPage - p
3e80: 43 61 63 68 65 2d 3e 6e 52 65 63 79 63 6c 61 62  Cache->nRecyclab
3e90: 6c 65 3b 0a 20 20 69 66 28 20 63 72 65 61 74 65  le;.  if( create
3ea0: 46 6c 61 67 3d 3d 31 20 26 26 20 70 43 61 63 68  Flag==1 && pCach
3eb0: 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 26 26  e->bPurgeable &&
3ec0: 20 28 0a 20 20 20 20 20 20 20 20 6e 50 69 6e 6e   (.        nPinn
3ed0: 65 64 3e 3d 28 70 63 61 63 68 65 31 2e 6e 4d 61  ed>=(pcache1.nMa
3ee0: 78 50 61 67 65 2b 70 43 61 63 68 65 2d 3e 6e 4d  xPage+pCache->nM
3ef0: 69 6e 2d 70 63 61 63 68 65 31 2e 6e 4d 69 6e 50  in-pcache1.nMinP
3f00: 61 67 65 29 0a 20 20 20 20 20 7c 7c 20 6e 50 69  age).     || nPi
3f10: 6e 6e 65 64 3e 3d 28 70 43 61 63 68 65 2d 3e 6e  nned>=(pCache->n
3f20: 4d 61 78 29 0a 20 20 29 29 7b 0a 20 20 20 20 67  Max).  )){.    g
3f30: 6f 74 6f 20 66 65 74 63 68 5f 6f 75 74 3b 0a 20  oto fetch_out;. 
3f40: 20 7d 0a 0a 20 20 69 66 28 20 70 43 61 63 68 65   }..  if( pCache
3f50: 2d 3e 6e 50 61 67 65 3e 3d 70 43 61 63 68 65 2d  ->nPage>=pCache-
3f60: 3e 6e 48 61 73 68 20 26 26 20 70 63 61 63 68 65  >nHash && pcache
3f70: 31 52 65 73 69 7a 65 48 61 73 68 28 70 43 61 63  1ResizeHash(pCac
3f80: 68 65 29 20 29 7b 0a 20 20 20 20 67 6f 74 6f 20  he) ){.    goto 
3f90: 66 65 74 63 68 5f 6f 75 74 3b 0a 20 20 7d 0a 0a  fetch_out;.  }..
3fa0: 20 20 2f 2a 20 53 74 65 70 20 34 2e 20 54 72 79    /* Step 4. Try
3fb0: 20 74 6f 20 72 65 63 79 63 6c 65 20 61 20 70 61   to recycle a pa
3fc0: 67 65 20 62 75 66 66 65 72 20 69 66 20 61 70 70  ge buffer if app
3fd0: 72 6f 70 72 69 61 74 65 2e 20 2a 2f 0a 20 20 69  ropriate. */.  i
3fe0: 66 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67  f( pCache->bPurg
3ff0: 65 61 62 6c 65 20 26 26 20 70 63 61 63 68 65 31  eable && pcache1
4000: 2e 70 4c 72 75 54 61 69 6c 20 26 26 20 28 0a 20  .pLruTail && (. 
4010: 20 20 20 20 20 70 43 61 63 68 65 2d 3e 6e 50 61       pCache->nPa
4020: 67 65 3e 3d 70 43 61 63 68 65 2d 3e 6e 4d 61 78  ge>=pCache->nMax
4030: 2d 31 20 7c 7c 20 70 63 61 63 68 65 31 2e 6e 43  -1 || pcache1.nC
4040: 75 72 72 65 6e 74 50 61 67 65 3e 3d 70 63 61 63  urrentPage>=pcac
4050: 68 65 31 2e 6e 4d 61 78 50 61 67 65 0a 20 20 29  he1.nMaxPage.  )
4060: 29 7b 0a 20 20 20 20 70 50 61 67 65 20 3d 20 70  ){.    pPage = p
4070: 63 61 63 68 65 31 2e 70 4c 72 75 54 61 69 6c 3b  cache1.pLruTail;
4080: 0a 20 20 20 20 70 63 61 63 68 65 31 52 65 6d 6f  .    pcache1Remo
4090: 76 65 46 72 6f 6d 48 61 73 68 28 70 50 61 67 65  veFromHash(pPage
40a0: 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31 50 69  );.    pcache1Pi
40b0: 6e 50 61 67 65 28 70 50 61 67 65 29 3b 0a 20 20  nPage(pPage);.  
40c0: 20 20 69 66 28 20 70 50 61 67 65 2d 3e 70 43 61    if( pPage->pCa
40d0: 63 68 65 2d 3e 73 7a 50 61 67 65 21 3d 70 43 61  che->szPage!=pCa
40e0: 63 68 65 2d 3e 73 7a 50 61 67 65 20 29 7b 0a 20  che->szPage ){. 
40f0: 20 20 20 20 20 70 63 61 63 68 65 31 46 72 65 65       pcache1Free
4100: 50 61 67 65 28 70 50 61 67 65 29 3b 0a 20 20 20  Page(pPage);.   
4110: 20 20 20 70 50 61 67 65 20 3d 20 30 3b 0a 20 20     pPage = 0;.  
4120: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70    }else{.      p
4130: 63 61 63 68 65 31 2e 6e 43 75 72 72 65 6e 74 50  cache1.nCurrentP
4140: 61 67 65 20 2d 3d 20 28 70 50 61 67 65 2d 3e 70  age -= (pPage->p
4150: 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c  Cache->bPurgeabl
4160: 65 20 2d 20 70 43 61 63 68 65 2d 3e 62 50 75 72  e - pCache->bPur
4170: 67 65 61 62 6c 65 29 3b 0a 20 20 20 20 7d 0a 20  geable);.    }. 
4180: 20 7d 0a 0a 20 20 2f 2a 20 53 74 65 70 20 35 2e   }..  /* Step 5.
4190: 20 49 66 20 61 20 75 73 61 62 6c 65 20 70 61 67   If a usable pag
41a0: 65 20 62 75 66 66 65 72 20 68 61 73 20 73 74 69  e buffer has sti
41b0: 6c 6c 20 6e 6f 74 20 62 65 65 6e 20 66 6f 75 6e  ll not been foun
41c0: 64 2c 20 0a 20 20 2a 2a 20 61 74 74 65 6d 70 74  d, .  ** attempt
41d0: 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e   to allocate a n
41e0: 65 77 20 6f 6e 65 2e 20 0a 20 20 2a 2f 0a 20 20  ew one. .  */.  
41f0: 69 66 28 20 21 70 50 61 67 65 20 29 7b 0a 20 20  if( !pPage ){.  
4200: 20 20 70 50 61 67 65 20 3d 20 70 63 61 63 68 65    pPage = pcache
4210: 31 41 6c 6c 6f 63 50 61 67 65 28 70 43 61 63 68  1AllocPage(pCach
4220: 65 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70  e);.  }..  if( p
4230: 50 61 67 65 20 29 7b 0a 20 20 20 20 75 6e 73 69  Page ){.    unsi
4240: 67 6e 65 64 20 69 6e 74 20 68 20 3d 20 69 4b 65  gned int h = iKe
4250: 79 20 25 20 70 43 61 63 68 65 2d 3e 6e 48 61 73  y % pCache->nHas
4260: 68 3b 0a 20 20 20 20 6d 65 6d 73 65 74 28 70 50  h;.    memset(pP
4270: 61 67 65 2c 20 30 2c 20 70 43 61 63 68 65 2d 3e  age, 0, pCache->
4280: 73 7a 50 61 67 65 20 2b 20 73 69 7a 65 6f 66 28  szPage + sizeof(
4290: 50 67 48 64 72 31 29 29 3b 0a 20 20 20 20 70 43  PgHdr1));.    pC
42a0: 61 63 68 65 2d 3e 6e 50 61 67 65 2b 2b 3b 0a 20  ache->nPage++;. 
42b0: 20 20 20 70 50 61 67 65 2d 3e 69 4b 65 79 20 3d     pPage->iKey =
42c0: 20 69 4b 65 79 3b 0a 20 20 20 20 70 50 61 67 65   iKey;.    pPage
42d0: 2d 3e 70 4e 65 78 74 20 3d 20 70 43 61 63 68 65  ->pNext = pCache
42e0: 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 0a 20 20 20  ->apHash[h];.   
42f0: 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65 20 3d   pPage->pCache =
4300: 20 70 43 61 63 68 65 3b 0a 20 20 20 20 70 43 61   pCache;.    pCa
4310: 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 20 3d  che->apHash[h] =
4320: 20 70 50 61 67 65 3b 0a 20 20 7d 0a 0a 66 65 74   pPage;.  }..fet
4330: 63 68 5f 6f 75 74 3a 0a 20 20 69 66 28 20 63 72  ch_out:.  if( cr
4340: 65 61 74 65 46 6c 61 67 3d 3d 31 20 29 20 73 71  eateFlag==1 ) sq
4350: 6c 69 74 65 33 45 6e 64 42 65 6e 69 67 6e 4d 61  lite3EndBenignMa
4360: 6c 6c 6f 63 28 29 3b 0a 20 20 70 63 61 63 68 65  lloc();.  pcache
4370: 31 4c 65 61 76 65 4d 75 74 65 78 28 29 3b 0a 20  1LeaveMutex();. 
4380: 20 72 65 74 75 72 6e 20 28 70 50 61 67 65 20 3f   return (pPage ?
4390: 20 50 47 48 44 52 31 5f 54 4f 5f 50 41 47 45 28   PGHDR1_TO_PAGE(
43a0: 70 50 61 67 65 29 20 3a 20 30 29 3b 0a 7d 0a 0a  pPage) : 0);.}..
43b0: 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74  ./*.** Implement
43c0: 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c  ation of the sql
43d0: 69 74 65 33 5f 70 63 61 63 68 65 2e 78 55 6e 70  ite3_pcache.xUnp
43e0: 69 6e 20 6d 65 74 68 6f 64 2e 0a 2a 2a 0a 2a 2a  in method..**.**
43f0: 20 4d 61 72 6b 20 61 20 70 61 67 65 20 61 73 20   Mark a page as 
4400: 75 6e 70 69 6e 6e 65 64 20 28 65 6c 69 67 69 62  unpinned (eligib
4410: 6c 65 20 66 6f 72 20 61 73 79 6e 63 68 72 6f 6e  le for asynchron
4420: 6f 75 73 20 72 65 63 79 63 6c 69 6e 67 29 2e 0a  ous recycling)..
4430: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70  */.static void p
4440: 63 61 63 68 65 31 55 6e 70 69 6e 28 73 71 6c 69  cache1Unpin(sqli
4450: 74 65 33 5f 70 63 61 63 68 65 20 2a 70 2c 20 76  te3_pcache *p, v
4460: 6f 69 64 20 2a 70 50 67 2c 20 69 6e 74 20 72 65  oid *pPg, int re
4470: 75 73 65 55 6e 6c 69 6b 65 6c 79 29 7b 0a 20 20  useUnlikely){.  
4480: 50 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 20  PCache1 *pCache 
4490: 3d 20 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a  = (PCache1 *)p;.
44a0: 20 20 50 67 48 64 72 31 20 2a 70 50 61 67 65 20    PgHdr1 *pPage 
44b0: 3d 20 50 41 47 45 5f 54 4f 5f 50 47 48 44 52 31  = PAGE_TO_PGHDR1
44c0: 28 70 50 67 29 3b 0a 0a 20 20 70 63 61 63 68 65  (pPg);..  pcache
44d0: 31 45 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a 0a  1EnterMutex();..
44e0: 20 20 2f 2a 20 49 74 20 69 73 20 61 6e 20 65 72    /* It is an er
44f0: 72 6f 72 20 74 6f 20 63 61 6c 6c 20 74 68 69 73  ror to call this
4500: 20 66 75 6e 63 74 69 6f 6e 20 69 66 20 74 68 65   function if the
4510: 20 70 61 67 65 20 69 73 20 61 6c 72 65 61 64 79   page is already
4520: 20 0a 20 20 2a 2a 20 70 61 72 74 20 6f 66 20 74   .  ** part of t
4530: 68 65 20 67 6c 6f 62 61 6c 20 4c 52 55 20 6c 69  he global LRU li
4540: 73 74 2e 0a 20 20 2a 2f 0a 20 20 61 73 73 65 72  st..  */.  asser
4550: 74 28 20 70 50 61 67 65 2d 3e 70 4c 72 75 50 72  t( pPage->pLruPr
4560: 65 76 3d 3d 30 20 26 26 20 70 50 61 67 65 2d 3e  ev==0 && pPage->
4570: 70 4c 72 75 4e 65 78 74 3d 3d 30 20 29 3b 0a 20  pLruNext==0 );. 
4580: 20 61 73 73 65 72 74 28 20 70 63 61 63 68 65 31   assert( pcache1
4590: 2e 70 4c 72 75 48 65 61 64 21 3d 70 50 61 67 65  .pLruHead!=pPage
45a0: 20 26 26 20 70 63 61 63 68 65 31 2e 70 4c 72 75   && pcache1.pLru
45b0: 54 61 69 6c 21 3d 70 50 61 67 65 20 29 3b 0a 0a  Tail!=pPage );..
45c0: 20 20 69 66 28 20 72 65 75 73 65 55 6e 6c 69 6b    if( reuseUnlik
45d0: 65 6c 79 20 7c 7c 20 70 63 61 63 68 65 31 2e 6e  ely || pcache1.n
45e0: 43 75 72 72 65 6e 74 50 61 67 65 3e 70 63 61 63  CurrentPage>pcac
45f0: 68 65 31 2e 6e 4d 61 78 50 61 67 65 20 29 7b 0a  he1.nMaxPage ){.
4600: 20 20 20 20 70 63 61 63 68 65 31 52 65 6d 6f 76      pcache1Remov
4610: 65 46 72 6f 6d 48 61 73 68 28 70 50 61 67 65 29  eFromHash(pPage)
4620: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 46 72 65  ;.    pcache1Fre
4630: 65 50 61 67 65 28 70 50 61 67 65 29 3b 0a 20 20  ePage(pPage);.  
4640: 7d 65 6c 73 65 7b 0a 20 20 20 20 2f 2a 20 41 64  }else{.    /* Ad
4650: 64 20 74 68 65 20 70 61 67 65 20 74 6f 20 74 68  d the page to th
4660: 65 20 67 6c 6f 62 61 6c 20 4c 52 55 20 6c 69 73  e global LRU lis
4670: 74 2e 20 4e 6f 72 6d 61 6c 6c 79 2c 20 74 68 65  t. Normally, the
4680: 20 70 61 67 65 20 69 73 20 61 64 64 65 64 20 74   page is added t
4690: 6f 0a 20 20 20 20 2a 2a 20 74 68 65 20 68 65 61  o.    ** the hea
46a0: 64 20 6f 66 20 74 68 65 20 6c 69 73 74 20 28 6c  d of the list (l
46b0: 61 73 74 20 70 61 67 65 20 74 6f 20 62 65 20 72  ast page to be r
46c0: 65 63 79 63 6c 65 64 29 2e 20 48 6f 77 65 76 65  ecycled). Howeve
46d0: 72 2c 20 69 66 20 74 68 65 20 0a 20 20 20 20 2a  r, if the .    *
46e0: 2a 20 72 65 75 73 65 55 6e 6c 69 6b 65 6c 79 20  * reuseUnlikely 
46f0: 66 6c 61 67 20 70 61 73 73 65 64 20 74 6f 20 74  flag passed to t
4700: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
4710: 74 72 75 65 2c 20 74 68 65 20 70 61 67 65 20 69  true, the page i
4720: 73 20 61 64 64 65 64 0a 20 20 20 20 2a 2a 20 74  s added.    ** t
4730: 6f 20 74 68 65 20 74 61 69 6c 20 6f 66 20 74 68  o the tail of th
4740: 65 20 6c 69 73 74 20 28 66 69 72 73 74 20 70 61  e list (first pa
4750: 67 65 20 74 6f 20 62 65 20 72 65 63 79 63 6c 65  ge to be recycle
4760: 64 29 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 69  d)..    */.    i
4770: 66 28 20 70 63 61 63 68 65 31 2e 70 4c 72 75 48  f( pcache1.pLruH
4780: 65 61 64 20 29 7b 0a 20 20 20 20 20 20 70 63 61  ead ){.      pca
4790: 63 68 65 31 2e 70 4c 72 75 48 65 61 64 2d 3e 70  che1.pLruHead->p
47a0: 4c 72 75 50 72 65 76 20 3d 20 70 50 61 67 65 3b  LruPrev = pPage;
47b0: 0a 20 20 20 20 20 20 70 50 61 67 65 2d 3e 70 4c  .      pPage->pL
47c0: 72 75 4e 65 78 74 20 3d 20 70 63 61 63 68 65 31  ruNext = pcache1
47d0: 2e 70 4c 72 75 48 65 61 64 3b 0a 20 20 20 20 20  .pLruHead;.     
47e0: 20 70 63 61 63 68 65 31 2e 70 4c 72 75 48 65 61   pcache1.pLruHea
47f0: 64 20 3d 20 70 50 61 67 65 3b 0a 20 20 20 20 7d  d = pPage;.    }
4800: 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 63 61 63  else{.      pcac
4810: 68 65 31 2e 70 4c 72 75 54 61 69 6c 20 3d 20 70  he1.pLruTail = p
4820: 50 61 67 65 3b 0a 20 20 20 20 20 20 70 63 61 63  Page;.      pcac
4830: 68 65 31 2e 70 4c 72 75 48 65 61 64 20 3d 20 70  he1.pLruHead = p
4840: 50 61 67 65 3b 0a 20 20 20 20 7d 0a 20 20 20 20  Page;.    }.    
4850: 70 43 61 63 68 65 2d 3e 6e 52 65 63 79 63 6c 61  pCache->nRecycla
4860: 62 6c 65 2b 2b 3b 0a 20 20 7d 0a 0a 20 20 70 63  ble++;.  }..  pc
4870: 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28  ache1LeaveMutex(
4880: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c  );.}../*.** Impl
4890: 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68  ementation of th
48a0: 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  e sqlite3_pcache
48b0: 2e 78 52 65 6b 65 79 20 6d 65 74 68 6f 64 2e 20  .xRekey method. 
48c0: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
48d0: 70 63 61 63 68 65 31 52 65 6b 65 79 28 0a 20 20  pcache1Rekey(.  
48e0: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a  sqlite3_pcache *
48f0: 70 2c 0a 20 20 76 6f 69 64 20 2a 70 50 67 2c 0a  p,.  void *pPg,.
4900: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69    unsigned int i
4910: 4f 6c 64 2c 0a 20 20 75 6e 73 69 67 6e 65 64 20  Old,.  unsigned 
4920: 69 6e 74 20 69 4e 65 77 0a 29 7b 0a 20 20 50 43  int iNew.){.  PC
4930: 61 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20  ache1 *pCache = 
4940: 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20 20  (PCache1 *)p;.  
4950: 50 67 48 64 72 31 20 2a 70 50 61 67 65 20 3d 20  PgHdr1 *pPage = 
4960: 50 41 47 45 5f 54 4f 5f 50 47 48 44 52 31 28 70  PAGE_TO_PGHDR1(p
4970: 50 67 29 3b 0a 20 20 50 67 48 64 72 31 20 2a 2a  Pg);.  PgHdr1 **
4980: 70 70 3b 0a 20 20 75 6e 73 69 67 6e 65 64 20 69  pp;.  unsigned i
4990: 6e 74 20 68 3b 20 0a 20 20 61 73 73 65 72 74 28  nt h; .  assert(
49a0: 20 70 50 61 67 65 2d 3e 69 4b 65 79 3d 3d 69 4f   pPage->iKey==iO
49b0: 6c 64 20 29 3b 0a 0a 20 20 70 63 61 63 68 65 31  ld );..  pcache1
49c0: 45 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a 0a 20  EnterMutex();.. 
49d0: 20 68 20 3d 20 69 4f 6c 64 25 70 43 61 63 68 65   h = iOld%pCache
49e0: 2d 3e 6e 48 61 73 68 3b 0a 20 20 70 70 20 3d 20  ->nHash;.  pp = 
49f0: 26 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b  &pCache->apHash[
4a00: 68 5d 3b 0a 20 20 77 68 69 6c 65 28 20 28 2a 70  h];.  while( (*p
4a10: 70 29 21 3d 70 50 61 67 65 20 29 7b 0a 20 20 20  p)!=pPage ){.   
4a20: 20 70 70 20 3d 20 26 28 2a 70 70 29 2d 3e 70 4e   pp = &(*pp)->pN
4a30: 65 78 74 3b 0a 20 20 7d 0a 20 20 2a 70 70 20 3d  ext;.  }.  *pp =
4a40: 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 3b 0a 0a   pPage->pNext;..
4a50: 20 20 68 20 3d 20 69 4e 65 77 25 70 43 61 63 68    h = iNew%pCach
4a60: 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 70 50 61 67  e->nHash;.  pPag
4a70: 65 2d 3e 69 4b 65 79 20 3d 20 69 4e 65 77 3b 0a  e->iKey = iNew;.
4a80: 20 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 20 3d    pPage->pNext =
4a90: 20 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b   pCache->apHash[
4aa0: 68 5d 3b 0a 20 20 70 43 61 63 68 65 2d 3e 61 70  h];.  pCache->ap
4ab0: 48 61 73 68 5b 68 5d 20 3d 20 70 50 61 67 65 3b  Hash[h] = pPage;
4ac0: 0a 0a 20 20 70 63 61 63 68 65 31 4c 65 61 76 65  ..  pcache1Leave
4ad0: 4d 75 74 65 78 28 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  Mutex();.}../*.*
4ae0: 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  * Implementation
4af0: 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f   of the sqlite3_
4b00: 70 63 61 63 68 65 2e 78 54 72 75 6e 63 61 74 65  pcache.xTruncate
4b10: 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20   method. .**.** 
4b20: 44 69 73 63 61 72 64 20 61 6c 6c 20 75 6e 70 69  Discard all unpi
4b30: 6e 6e 65 64 20 70 61 67 65 73 20 69 6e 20 74 68  nned pages in th
4b40: 65 20 63 61 63 68 65 20 77 69 74 68 20 61 20 70  e cache with a p
4b50: 61 67 65 20 6e 75 6d 62 65 72 20 65 71 75 61 6c  age number equal
4b60: 20 74 6f 0a 2a 2a 20 6f 72 20 67 72 65 61 74 65   to.** or greate
4b70: 72 20 74 68 61 6e 20 70 61 72 61 6d 65 74 65 72  r than parameter
4b80: 20 69 4c 69 6d 69 74 2e 20 41 6e 79 20 70 69 6e   iLimit. Any pin
4b90: 6e 65 64 20 70 61 67 65 73 20 77 69 74 68 20 61  ned pages with a
4ba0: 20 70 61 67 65 20 6e 75 6d 62 65 72 0a 2a 2a 20   page number.** 
4bb0: 65 71 75 61 6c 20 74 6f 20 6f 72 20 67 72 65 61  equal to or grea
4bc0: 74 65 72 20 74 68 61 6e 20 69 4c 69 6d 69 74 20  ter than iLimit 
4bd0: 61 72 65 20 69 6d 70 6c 69 63 69 74 6c 79 20 75  are implicitly u
4be0: 6e 70 69 6e 6e 65 64 2e 0a 2a 2f 0a 73 74 61 74  npinned..*/.stat
4bf0: 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 31 54  ic void pcache1T
4c00: 72 75 6e 63 61 74 65 28 73 71 6c 69 74 65 33 5f  runcate(sqlite3_
4c10: 70 63 61 63 68 65 20 2a 70 2c 20 75 6e 73 69 67  pcache *p, unsig
4c20: 6e 65 64 20 69 6e 74 20 69 4c 69 6d 69 74 29 7b  ned int iLimit){
4c30: 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63  .  PCache1 *pCac
4c40: 68 65 20 3d 20 28 50 43 61 63 68 65 31 20 2a 29  he = (PCache1 *)
4c50: 70 3b 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65  p;.  pcache1Ente
4c60: 72 4d 75 74 65 78 28 29 3b 0a 20 20 70 63 61 63  rMutex();.  pcac
4c70: 68 65 31 54 72 75 6e 63 61 74 65 55 6e 73 61 66  he1TruncateUnsaf
4c80: 65 28 70 43 61 63 68 65 2c 20 69 4c 69 6d 69 74  e(pCache, iLimit
4c90: 29 3b 0a 20 20 70 63 61 63 68 65 31 4c 65 61 76  );.  pcache1Leav
4ca0: 65 4d 75 74 65 78 28 29 3b 0a 7d 0a 0a 2f 2a 0a  eMutex();.}../*.
4cb0: 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  ** Implementatio
4cc0: 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33  n of the sqlite3
4cd0: 5f 70 63 61 63 68 65 2e 78 44 65 73 74 72 6f 79  _pcache.xDestroy
4ce0: 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20   method. .**.** 
4cf0: 44 65 73 74 72 6f 79 20 61 20 63 61 63 68 65 20  Destroy a cache 
4d00: 61 6c 6c 6f 63 61 74 65 64 20 75 73 69 6e 67 20  allocated using 
4d10: 70 63 61 63 68 65 31 43 72 65 61 74 65 28 29 2e  pcache1Create().
4d20: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
4d30: 70 63 61 63 68 65 31 44 65 73 74 72 6f 79 28 73  pcache1Destroy(s
4d40: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70  qlite3_pcache *p
4d50: 29 7b 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43  ){.  PCache1 *pC
4d60: 61 63 68 65 20 3d 20 28 50 43 61 63 68 65 31 20  ache = (PCache1 
4d70: 2a 29 70 3b 0a 20 20 70 63 61 63 68 65 31 45 6e  *)p;.  pcache1En
4d80: 74 65 72 4d 75 74 65 78 28 29 3b 0a 20 20 70 63  terMutex();.  pc
4d90: 61 63 68 65 31 54 72 75 6e 63 61 74 65 55 6e 73  ache1TruncateUns
4da0: 61 66 65 28 70 43 61 63 68 65 2c 20 30 29 3b 0a  afe(pCache, 0);.
4db0: 20 20 70 63 61 63 68 65 31 2e 6e 4d 61 78 50 61    pcache1.nMaxPa
4dc0: 67 65 20 2d 3d 20 70 43 61 63 68 65 2d 3e 6e 4d  ge -= pCache->nM
4dd0: 61 78 3b 0a 20 20 70 63 61 63 68 65 31 2e 6e 4d  ax;.  pcache1.nM
4de0: 69 6e 50 61 67 65 20 2d 3d 20 70 43 61 63 68 65  inPage -= pCache
4df0: 2d 3e 6e 4d 69 6e 3b 0a 20 20 70 63 61 63 68 65  ->nMin;.  pcache
4e00: 31 45 6e 66 6f 72 63 65 4d 61 78 50 61 67 65 28  1EnforceMaxPage(
4e10: 29 3b 0a 20 20 70 63 61 63 68 65 31 4c 65 61 76  );.  pcache1Leav
4e20: 65 4d 75 74 65 78 28 29 3b 0a 20 20 73 71 6c 69  eMutex();.  sqli
4e30: 74 65 33 5f 66 72 65 65 28 70 43 61 63 68 65 2d  te3_free(pCache-
4e40: 3e 61 70 48 61 73 68 29 3b 0a 20 20 73 71 6c 69  >apHash);.  sqli
4e50: 74 65 33 5f 66 72 65 65 28 70 43 61 63 68 65 29  te3_free(pCache)
4e60: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  ;.}../*.** This 
4e70: 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c  function is call
4e80: 65 64 20 64 75 72 69 6e 67 20 69 6e 69 74 69 61  ed during initia
4e90: 6c 69 7a 61 74 69 6f 6e 20 28 73 71 6c 69 74 65  lization (sqlite
4ea0: 33 5f 69 6e 69 74 69 61 6c 69 7a 65 28 29 29 20  3_initialize()) 
4eb0: 74 6f 0a 2a 2a 20 69 6e 73 74 61 6c 6c 20 74 68  to.** install th
4ec0: 65 20 64 65 66 61 75 6c 74 20 70 6c 75 67 67 61  e default plugga
4ed0: 62 6c 65 20 63 61 63 68 65 20 6d 6f 64 75 6c 65  ble cache module
4ee0: 2c 20 61 73 73 75 6d 69 6e 67 20 74 68 65 20 75  , assuming the u
4ef0: 73 65 72 20 68 61 73 20 6e 6f 74 0a 2a 2a 20 61  ser has not.** a
4f00: 6c 72 65 61 64 79 20 70 72 6f 76 69 64 65 64 20  lready provided 
4f10: 61 6e 20 61 6c 74 65 72 6e 61 74 69 76 65 2e 0a  an alternative..
4f20: 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50  */.void sqlite3P
4f30: 43 61 63 68 65 53 65 74 44 65 66 61 75 6c 74 28  CacheSetDefault(
4f40: 76 6f 69 64 29 7b 0a 20 20 73 74 61 74 69 63 20  void){.  static 
4f50: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 5f 6d  sqlite3_pcache_m
4f60: 65 74 68 6f 64 73 20 64 65 66 61 75 6c 74 4d 65  ethods defaultMe
4f70: 74 68 6f 64 73 20 3d 20 7b 0a 20 20 20 20 30 2c  thods = {.    0,
4f80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4f90: 20 20 20 20 20 20 20 2f 2a 20 70 41 72 67 20 2a         /* pArg *
4fa0: 2f 0a 20 20 20 20 70 63 61 63 68 65 31 49 6e 69  /.    pcache1Ini
4fb0: 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  t,             /
4fc0: 2a 20 78 49 6e 69 74 20 2a 2f 0a 20 20 20 20 70  * xInit */.    p
4fd0: 63 61 63 68 65 31 53 68 75 74 64 6f 77 6e 2c 20  cache1Shutdown, 
4fe0: 20 20 20 20 20 20 20 20 2f 2a 20 78 53 68 75 74          /* xShut
4ff0: 64 6f 77 6e 20 2a 2f 0a 20 20 20 20 70 63 61 63  down */.    pcac
5000: 68 65 31 43 72 65 61 74 65 2c 20 20 20 20 20 20  he1Create,      
5010: 20 20 20 20 20 2f 2a 20 78 43 72 65 61 74 65 20       /* xCreate 
5020: 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31 43 61  */.    pcache1Ca
5030: 63 68 65 73 69 7a 65 2c 20 20 20 20 20 20 20 20  chesize,        
5040: 2f 2a 20 78 43 61 63 68 65 73 69 7a 65 20 2a 2f  /* xCachesize */
5050: 0a 20 20 20 20 70 63 61 63 68 65 31 50 61 67 65  .    pcache1Page
5060: 63 6f 75 6e 74 2c 20 20 20 20 20 20 20 20 2f 2a  count,        /*
5070: 20 78 50 61 67 65 63 6f 75 6e 74 20 2a 2f 0a 20   xPagecount */. 
5080: 20 20 20 70 63 61 63 68 65 31 46 65 74 63 68 2c     pcache1Fetch,
5090: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
50a0: 46 65 74 63 68 20 2a 2f 0a 20 20 20 20 70 63 61  Fetch */.    pca
50b0: 63 68 65 31 55 6e 70 69 6e 2c 20 20 20 20 20 20  che1Unpin,      
50c0: 20 20 20 20 20 20 2f 2a 20 78 55 6e 70 69 6e 20        /* xUnpin 
50d0: 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31 52 65  */.    pcache1Re
50e0: 6b 65 79 2c 20 20 20 20 20 20 20 20 20 20 20 20  key,            
50f0: 2f 2a 20 78 52 65 6b 65 79 20 2a 2f 0a 20 20 20  /* xRekey */.   
5100: 20 70 63 61 63 68 65 31 54 72 75 6e 63 61 74 65   pcache1Truncate
5110: 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 78 54 72  ,         /* xTr
5120: 75 6e 63 61 74 65 20 2a 2f 0a 20 20 20 20 70 63  uncate */.    pc
5130: 61 63 68 65 31 44 65 73 74 72 6f 79 20 20 20 20  ache1Destroy    
5140: 20 20 20 20 20 20 20 2f 2a 20 78 44 65 73 74 72         /* xDestr
5150: 6f 79 20 2a 2f 0a 20 20 7d 3b 0a 20 20 73 71 6c  oy */.  };.  sql
5160: 69 74 65 33 5f 63 6f 6e 66 69 67 28 53 51 4c 49  ite3_config(SQLI
5170: 54 45 5f 43 4f 4e 46 49 47 5f 50 43 41 43 48 45  TE_CONFIG_PCACHE
5180: 2c 20 26 64 65 66 61 75 6c 74 4d 65 74 68 6f 64  , &defaultMethod
5190: 73 29 3b 0a 7d 0a 0a 23 69 66 64 65 66 20 53 51  s);.}..#ifdef SQ
51a0: 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f  LITE_ENABLE_MEMO
51b0: 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 0a 2f 2a  RY_MANAGEMENT./*
51c0: 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
51d0: 6e 20 69 73 20 63 61 6c 6c 65 64 20 74 6f 20 66  n is called to f
51e0: 72 65 65 20 73 75 70 65 72 66 6c 75 6f 75 73 20  ree superfluous 
51f0: 64 79 6e 61 6d 69 63 61 6c 6c 79 20 61 6c 6c 6f  dynamically allo
5200: 63 61 74 65 64 20 6d 65 6d 6f 72 79 0a 2a 2a 20  cated memory.** 
5210: 68 65 6c 64 20 62 79 20 74 68 65 20 70 61 67 65  held by the page
5220: 72 20 73 79 73 74 65 6d 2e 20 4d 65 6d 6f 72 79  r system. Memory
5230: 20 69 6e 20 75 73 65 20 62 79 20 61 6e 79 20 53   in use by any S
5240: 51 4c 69 74 65 20 70 61 67 65 72 20 61 6c 6c 6f  QLite pager allo
5250: 63 61 74 65 64 0a 2a 2a 20 62 79 20 74 68 65 20  cated.** by the 
5260: 63 75 72 72 65 6e 74 20 74 68 72 65 61 64 20 6d  current thread m
5270: 61 79 20 62 65 20 73 71 6c 69 74 65 33 5f 66 72  ay be sqlite3_fr
5280: 65 65 28 29 65 64 2e 0a 2a 2a 0a 2a 2a 20 6e 52  ee()ed..**.** nR
5290: 65 71 20 69 73 20 74 68 65 20 6e 75 6d 62 65 72  eq is the number
52a0: 20 6f 66 20 62 79 74 65 73 20 6f 66 20 6d 65 6d   of bytes of mem
52b0: 6f 72 79 20 72 65 71 75 69 72 65 64 2e 20 4f 6e  ory required. On
52c0: 63 65 20 74 68 69 73 20 6d 75 63 68 20 68 61 73  ce this much has
52d0: 0a 2a 2a 20 62 65 65 6e 20 72 65 6c 65 61 73 65  .** been release
52e0: 64 2c 20 74 68 65 20 66 75 6e 63 74 69 6f 6e 20  d, the function 
52f0: 72 65 74 75 72 6e 73 2e 20 54 68 65 20 72 65 74  returns. The ret
5300: 75 72 6e 20 76 61 6c 75 65 20 69 73 20 74 68 65  urn value is the
5310: 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 0a 2a   total number .*
5320: 2a 20 6f 66 20 62 79 74 65 73 20 6f 66 20 6d 65  * of bytes of me
5330: 6d 6f 72 79 20 72 65 6c 65 61 73 65 64 2e 0a 2a  mory released..*
5340: 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 50 63 61  /.int sqlite3Pca
5350: 63 68 65 52 65 6c 65 61 73 65 4d 65 6d 6f 72 79  cheReleaseMemory
5360: 28 69 6e 74 20 6e 52 65 71 29 7b 0a 20 20 69 6e  (int nReq){.  in
5370: 74 20 6e 46 72 65 65 20 3d 20 30 3b 0a 20 20 69  t nFree = 0;.  i
5380: 66 28 20 70 63 61 63 68 65 31 2e 70 53 74 61 72  f( pcache1.pStar
5390: 74 3d 3d 30 20 29 7b 0a 20 20 20 20 50 67 48 64  t==0 ){.    PgHd
53a0: 72 31 20 2a 70 3b 0a 20 20 20 20 70 63 61 63 68  r1 *p;.    pcach
53b0: 65 31 45 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a  e1EnterMutex();.
53c0: 20 20 20 20 77 68 69 6c 65 28 20 28 6e 52 65 71      while( (nReq
53d0: 3c 30 20 7c 7c 20 6e 46 72 65 65 3c 6e 52 65 71  <0 || nFree<nReq
53e0: 29 20 26 26 20 28 70 3d 70 63 61 63 68 65 31 2e  ) && (p=pcache1.
53f0: 70 4c 72 75 54 61 69 6c 29 20 29 7b 0a 20 20 20  pLruTail) ){.   
5400: 20 20 20 6e 46 72 65 65 20 2b 3d 20 73 71 6c 69     nFree += sqli
5410: 74 65 33 4d 61 6c 6c 6f 63 53 69 7a 65 28 70 29  te3MallocSize(p)
5420: 3b 0a 20 20 20 20 20 20 70 63 61 63 68 65 31 50  ;.      pcache1P
5430: 69 6e 50 61 67 65 28 70 29 3b 0a 20 20 20 20 20  inPage(p);.     
5440: 20 70 63 61 63 68 65 31 52 65 6d 6f 76 65 46 72   pcache1RemoveFr
5450: 6f 6d 48 61 73 68 28 70 29 3b 0a 20 20 20 20 20  omHash(p);.     
5460: 20 70 63 61 63 68 65 31 46 72 65 65 50 61 67 65   pcache1FreePage
5470: 28 70 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70  (p);.    }.    p
5480: 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78  cache1LeaveMutex
5490: 28 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  ();.  }.  return
54a0: 20 6e 46 72 65 65 3b 0a 7d 0a 23 65 6e 64 69 66   nFree;.}.#endif
54b0: 20 2f 2a 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c   /* SQLITE_ENABL
54c0: 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d  E_MEMORY_MANAGEM
54d0: 45 4e 54 20 2a 2f 0a 0a 23 69 66 64 65 66 20 53  ENT */..#ifdef S
54e0: 51 4c 49 54 45 5f 54 45 53 54 0a 2f 2a 0a 2a 2a  QLITE_TEST./*.**
54f0: 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   This function i
5500: 73 20 75 73 65 64 20 62 79 20 74 65 73 74 20 70  s used by test p
5510: 72 6f 63 65 64 75 72 65 73 20 74 6f 20 69 6e 73  rocedures to ins
5520: 70 65 63 74 20 74 68 65 20 69 6e 74 65 72 6e 61  pect the interna
5530: 6c 20 73 74 61 74 65 0a 2a 2a 20 6f 66 20 74 68  l state.** of th
5540: 65 20 67 6c 6f 62 61 6c 20 63 61 63 68 65 2e 0a  e global cache..
5550: 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50  */.void sqlite3P
5560: 63 61 63 68 65 53 74 61 74 73 28 0a 20 20 69 6e  cacheStats(.  in
5570: 74 20 2a 70 6e 43 75 72 72 65 6e 74 2c 20 20 20  t *pnCurrent,   
5580: 20 20 20 2f 2a 20 4f 55 54 3a 20 54 6f 74 61 6c     /* OUT: Total
5590: 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73   number of pages
55a0: 20 63 61 63 68 65 64 20 2a 2f 0a 20 20 69 6e 74   cached */.  int
55b0: 20 2a 70 6e 4d 61 78 2c 20 20 20 20 20 20 20 20   *pnMax,        
55c0: 20 20 2f 2a 20 4f 55 54 3a 20 47 6c 6f 62 61 6c    /* OUT: Global
55d0: 20 6d 61 78 69 6d 75 6d 20 63 61 63 68 65 20 73   maximum cache s
55e0: 69 7a 65 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e  ize */.  int *pn
55f0: 4d 69 6e 2c 20 20 20 20 20 20 20 20 20 20 2f 2a  Min,          /*
5600: 20 4f 55 54 3a 20 53 75 6d 20 6f 66 20 50 43 61   OUT: Sum of PCa
5610: 63 68 65 31 2e 6e 4d 69 6e 20 66 6f 72 20 70 75  che1.nMin for pu
5620: 72 67 65 61 62 6c 65 20 63 61 63 68 65 73 20 2a  rgeable caches *
5630: 2f 0a 20 20 69 6e 74 20 2a 70 6e 52 65 63 79 63  /.  int *pnRecyc
5640: 6c 61 62 6c 65 20 20 20 20 2f 2a 20 4f 55 54 3a  lable    /* OUT:
5650: 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66   Total number of
5660: 20 70 61 67 65 73 20 61 76 61 69 6c 61 62 6c 65   pages available
5670: 20 66 6f 72 20 72 65 63 79 63 6c 69 6e 67 20 2a   for recycling *
5680: 2f 0a 29 7b 0a 20 20 50 67 48 64 72 31 20 2a 70  /.){.  PgHdr1 *p
5690: 3b 0a 20 20 69 6e 74 20 6e 52 65 63 79 63 6c 61  ;.  int nRecycla
56a0: 62 6c 65 20 3d 20 30 3b 0a 20 20 66 6f 72 28 70  ble = 0;.  for(p
56b0: 3d 70 63 61 63 68 65 31 2e 70 4c 72 75 48 65 61  =pcache1.pLruHea
56c0: 64 3b 20 70 3b 20 70 3d 70 2d 3e 70 4c 72 75 4e  d; p; p=p->pLruN
56d0: 65 78 74 29 7b 0a 20 20 20 20 6e 52 65 63 79 63  ext){.    nRecyc
56e0: 6c 61 62 6c 65 2b 2b 3b 0a 20 20 7d 0a 20 20 2a  lable++;.  }.  *
56f0: 70 6e 43 75 72 72 65 6e 74 20 3d 20 70 63 61 63  pnCurrent = pcac
5700: 68 65 31 2e 6e 43 75 72 72 65 6e 74 50 61 67 65  he1.nCurrentPage
5710: 3b 0a 20 20 2a 70 6e 4d 61 78 20 3d 20 70 63 61  ;.  *pnMax = pca
5720: 63 68 65 31 2e 6e 4d 61 78 50 61 67 65 3b 0a 20  che1.nMaxPage;. 
5730: 20 2a 70 6e 4d 69 6e 20 3d 20 70 63 61 63 68 65   *pnMin = pcache
5740: 31 2e 6e 4d 69 6e 50 61 67 65 3b 0a 20 20 2a 70  1.nMinPage;.  *p
5750: 6e 52 65 63 79 63 6c 61 62 6c 65 20 3d 20 6e 52  nRecyclable = nR
5760: 65 63 79 63 6c 61 62 6c 65 3b 0a 7d 0a 23 65 6e  ecyclable;.}.#en
5770: 64 69 66 0a                                      dif.