/ Hex Artifact Content
Login

Artifact 533b18aa2456b0f135e376289443e0a342e0c456:


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 36 20 32 30  ache1.c,v 1.6 20
02e0: 30 38 2f 31 32 2f 31 30 20 31 38 3a 30 33 3a 34  08/12/10 18:03:4
02f0: 36 20 64 72 68 20 45 78 70 20 24 0a 2a 2f 0a 0a  6 drh Exp $.*/..
0300: 23 69 6e 63 6c 75 64 65 20 22 73 71 6c 69 74 65  #include "sqlite
0310: 49 6e 74 2e 68 22 0a 0a 74 79 70 65 64 65 66 20  Int.h"..typedef 
0320: 73 74 72 75 63 74 20 50 43 61 63 68 65 31 20 50  struct PCache1 P
0330: 43 61 63 68 65 31 3b 0a 74 79 70 65 64 65 66 20  Cache1;.typedef 
0340: 73 74 72 75 63 74 20 50 67 48 64 72 31 20 50 67  struct PgHdr1 Pg
0350: 48 64 72 31 3b 0a 74 79 70 65 64 65 66 20 73 74  Hdr1;.typedef st
0360: 72 75 63 74 20 50 67 46 72 65 65 73 6c 6f 74 20  ruct PgFreeslot 
0370: 50 67 46 72 65 65 73 6c 6f 74 3b 0a 0a 2f 2a 20  PgFreeslot;../* 
0380: 50 6f 69 6e 74 65 72 73 20 74 6f 20 73 74 72 75  Pointers to stru
0390: 63 74 75 72 65 73 20 6f 66 20 74 68 69 73 20 74  ctures of this t
03a0: 79 70 65 20 61 72 65 20 63 61 73 74 20 61 6e 64  ype are cast and
03b0: 20 72 65 74 75 72 6e 65 64 20 61 73 20 0a 2a 2a   returned as .**
03c0: 20 6f 70 61 71 75 65 20 73 71 6c 69 74 65 33 5f   opaque sqlite3_
03d0: 70 63 61 63 68 65 2a 20 68 61 6e 64 6c 65 73 0a  pcache* handles.
03e0: 2a 2f 0a 73 74 72 75 63 74 20 50 43 61 63 68 65  */.struct PCache
03f0: 31 20 7b 0a 20 20 2f 2a 20 43 61 63 68 65 20 63  1 {.  /* Cache c
0400: 6f 6e 66 69 67 75 72 61 74 69 6f 6e 20 70 61 72  onfiguration par
0410: 61 6d 65 74 65 72 73 2e 20 50 61 67 65 20 73 69  ameters. Page si
0420: 7a 65 20 28 73 7a 50 61 67 65 29 20 61 6e 64 20  ze (szPage) and 
0430: 74 68 65 20 70 75 72 67 65 61 62 6c 65 0a 20 20  the purgeable.  
0440: 2a 2a 20 66 6c 61 67 20 28 62 50 75 72 67 65 61  ** flag (bPurgea
0450: 62 6c 65 29 20 61 72 65 20 73 65 74 20 77 68 65  ble) are set whe
0460: 6e 20 74 68 65 20 63 61 63 68 65 20 69 73 20 63  n the cache is c
0470: 72 65 61 74 65 64 2e 20 6e 4d 61 78 20 6d 61 79  reated. nMax may
0480: 20 62 65 20 0a 20 20 2a 2a 20 6d 6f 64 69 66 69   be .  ** modifi
0490: 65 64 20 61 74 20 61 6e 79 20 74 69 6d 65 20 62  ed at any time b
04a0: 79 20 61 20 63 61 6c 6c 20 74 6f 20 74 68 65 20  y a call to the 
04b0: 70 63 61 63 68 65 31 43 61 63 68 65 53 69 7a 65  pcache1CacheSize
04c0: 28 29 20 6d 65 74 68 6f 64 2e 0a 20 20 2a 2a 20  () method..  ** 
04d0: 54 68 65 20 67 6c 6f 62 61 6c 20 6d 75 74 65 78  The global mutex
04e0: 20 6d 75 73 74 20 62 65 20 68 65 6c 64 20 77 68   must be held wh
04f0: 65 6e 20 61 63 63 65 73 73 69 6e 67 20 6e 4d 61  en accessing nMa
0500: 78 2e 0a 20 20 2a 2f 0a 20 20 69 6e 74 20 73 7a  x..  */.  int sz
0510: 50 61 67 65 3b 20 20 20 20 20 20 20 20 20 20 20  Page;           
0520: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0530: 20 53 69 7a 65 20 6f 66 20 61 6c 6c 6f 63 61 74   Size of allocat
0540: 65 64 20 70 61 67 65 73 20 69 6e 20 62 79 74 65  ed pages in byte
0550: 73 20 2a 2f 0a 20 20 69 6e 74 20 62 50 75 72 67  s */.  int bPurg
0560: 65 61 62 6c 65 3b 20 20 20 20 20 20 20 20 20 20  eable;          
0570: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72             /* Tr
0580: 75 65 20 69 66 20 63 61 63 68 65 20 69 73 20 70  ue if cache is p
0590: 75 72 67 65 61 62 6c 65 20 2a 2f 0a 20 20 75 6e  urgeable */.  un
05a0: 73 69 67 6e 65 64 20 69 6e 74 20 6e 4d 69 6e 3b  signed int nMin;
05b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
05c0: 20 20 2f 2a 20 4d 69 6e 69 6d 75 6d 20 6e 75 6d    /* Minimum num
05d0: 62 65 72 20 6f 66 20 70 61 67 65 73 20 72 65 73  ber of pages res
05e0: 65 72 76 65 64 20 2a 2f 0a 20 20 75 6e 73 69 67  erved */.  unsig
05f0: 6e 65 64 20 69 6e 74 20 6e 4d 61 78 3b 20 20 20  ned int nMax;   
0600: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0610: 2a 20 43 6f 6e 66 69 67 75 72 65 64 20 22 63 61  * Configured "ca
0620: 63 68 65 5f 73 69 7a 65 22 20 76 61 6c 75 65 20  che_size" value 
0630: 2a 2f 0a 0a 20 20 2f 2a 20 48 61 73 68 20 74 61  */..  /* Hash ta
0640: 62 6c 65 20 6f 66 20 61 6c 6c 20 70 61 67 65 73  ble of all pages
0650: 2e 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20  . The following 
0660: 76 61 72 69 61 62 6c 65 73 20 6d 61 79 20 6f 6e  variables may on
0670: 6c 79 20 62 65 20 61 63 63 65 73 73 65 64 0a 20  ly be accessed. 
0680: 20 2a 2a 20 77 68 65 6e 20 74 68 65 20 61 63 63   ** when the acc
0690: 65 73 73 6f 72 20 69 73 20 68 6f 6c 64 69 6e 67  essor is holding
06a0: 20 74 68 65 20 67 6c 6f 62 61 6c 20 6d 75 74 65   the global mute
06b0: 78 20 28 73 65 65 20 70 63 61 63 68 65 31 45 6e  x (see pcache1En
06c0: 74 65 72 4d 75 74 65 78 28 29 20 0a 20 20 2a 2a  terMutex() .  **
06d0: 20 61 6e 64 20 70 63 61 63 68 65 31 4c 65 61 76   and pcache1Leav
06e0: 65 4d 75 74 65 78 28 29 29 2e 0a 20 20 2a 2f 0a  eMutex())..  */.
06f0: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e    unsigned int n
0700: 52 65 63 79 63 6c 61 62 6c 65 3b 20 20 20 20 20  Recyclable;     
0710: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
0720: 6f 66 20 70 61 67 65 73 20 69 6e 20 74 68 65 20  of pages in the 
0730: 4c 52 55 20 6c 69 73 74 20 2a 2f 0a 20 20 75 6e  LRU list */.  un
0740: 73 69 67 6e 65 64 20 69 6e 74 20 6e 50 61 67 65  signed int nPage
0750: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
0760: 20 20 2f 2a 20 54 6f 74 61 6c 20 6e 75 6d 62 65    /* Total numbe
0770: 72 20 6f 66 20 70 61 67 65 73 20 69 6e 20 61 70  r of pages in ap
0780: 48 61 73 68 20 2a 2f 0a 20 20 75 6e 73 69 67 6e  Hash */.  unsign
0790: 65 64 20 69 6e 74 20 6e 48 61 73 68 3b 20 20 20  ed int nHash;   
07a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
07b0: 20 4e 75 6d 62 65 72 20 6f 66 20 73 6c 6f 74 73   Number of slots
07c0: 20 69 6e 20 61 70 48 61 73 68 5b 5d 20 2a 2f 0a   in apHash[] */.
07d0: 20 20 50 67 48 64 72 31 20 2a 2a 61 70 48 61 73    PgHdr1 **apHas
07e0: 68 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  h;              
07f0: 20 20 20 20 20 20 2f 2a 20 48 61 73 68 20 74 61        /* Hash ta
0800: 62 6c 65 20 66 6f 72 20 66 61 73 74 20 6c 6f 6f  ble for fast loo
0810: 6b 75 70 20 62 79 20 6b 65 79 20 2a 2f 0a 7d 3b  kup by key */.};
0820: 0a 0a 2f 2a 0a 2a 2a 20 45 61 63 68 20 63 61 63  ../*.** Each cac
0830: 68 65 20 65 6e 74 72 79 20 69 73 20 72 65 70 72  he entry is repr
0840: 65 73 65 6e 74 65 64 20 62 79 20 61 6e 20 69 6e  esented by an in
0850: 73 74 61 6e 63 65 20 6f 66 20 74 68 65 20 66 6f  stance of the fo
0860: 6c 6c 6f 77 69 6e 67 20 0a 2a 2a 20 73 74 72 75  llowing .** stru
0870: 63 74 75 72 65 2e 20 41 20 62 75 66 66 65 72 20  cture. A buffer 
0880: 6f 66 20 50 67 48 64 72 31 2e 70 43 61 63 68 65  of PgHdr1.pCache
0890: 2d 3e 73 7a 50 61 67 65 20 62 79 74 65 73 20 69  ->szPage bytes i
08a0: 73 20 61 6c 6c 6f 63 61 74 65 64 20 0a 2a 2a 20  s allocated .** 
08b0: 64 69 72 65 63 74 6c 79 20 61 66 74 65 72 20 74  directly after t
08c0: 68 65 20 73 74 72 75 63 74 75 72 65 20 69 6e 20  he structure in 
08d0: 6d 65 6d 6f 72 79 20 28 73 65 65 20 74 68 65 20  memory (see the 
08e0: 50 47 48 44 52 31 5f 54 4f 5f 50 41 47 45 28 29  PGHDR1_TO_PAGE()
08f0: 20 0a 2a 2a 20 6d 61 63 72 6f 20 62 65 6c 6f 77   .** macro below
0900: 29 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 50 67 48  )..*/.struct PgH
0910: 64 72 31 20 7b 0a 20 20 75 6e 73 69 67 6e 65 64  dr1 {.  unsigned
0920: 20 69 6e 74 20 69 4b 65 79 3b 20 20 20 20 20 20   int iKey;      
0930: 20 20 20 20 20 20 20 2f 2a 20 4b 65 79 20 76 61         /* Key va
0940: 6c 75 65 20 28 70 61 67 65 20 6e 75 6d 62 65 72  lue (page number
0950: 29 20 2a 2f 0a 20 20 50 67 48 64 72 31 20 2a 70  ) */.  PgHdr1 *p
0960: 4e 65 78 74 3b 20 20 20 20 20 20 20 20 20 20 20  Next;           
0970: 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 69 6e        /* Next in
0980: 20 68 61 73 68 20 74 61 62 6c 65 20 63 68 61 69   hash table chai
0990: 6e 20 2a 2f 0a 20 20 50 43 61 63 68 65 31 20 2a  n */.  PCache1 *
09a0: 70 43 61 63 68 65 3b 20 20 20 20 20 20 20 20 20  pCache;         
09b0: 20 20 20 20 20 20 2f 2a 20 43 61 63 68 65 20 74        /* Cache t
09c0: 68 61 74 20 63 75 72 72 65 6e 74 6c 79 20 6f 77  hat currently ow
09d0: 6e 73 20 74 68 69 73 20 70 61 67 65 20 2a 2f 0a  ns this page */.
09e0: 20 20 50 67 48 64 72 31 20 2a 70 4c 72 75 4e 65    PgHdr1 *pLruNe
09f0: 78 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  xt;             
0a00: 20 2f 2a 20 4e 65 78 74 20 69 6e 20 4c 52 55 20   /* Next in LRU 
0a10: 6c 69 73 74 20 6f 66 20 75 6e 70 69 6e 6e 65 64  list of unpinned
0a20: 20 70 61 67 65 73 20 2a 2f 0a 20 20 50 67 48 64   pages */.  PgHd
0a30: 72 31 20 2a 70 4c 72 75 50 72 65 76 3b 20 20 20  r1 *pLruPrev;   
0a40: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 72             /* Pr
0a50: 65 76 69 6f 75 73 20 69 6e 20 4c 52 55 20 6c 69  evious in LRU li
0a60: 73 74 20 6f 66 20 75 6e 70 69 6e 6e 65 64 20 70  st of unpinned p
0a70: 61 67 65 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a  ages */.};../*.*
0a80: 2a 20 46 72 65 65 20 73 6c 6f 74 73 20 69 6e 20  * Free slots in 
0a90: 74 68 65 20 61 6c 6c 6f 63 61 74 6f 72 20 75 73  the allocator us
0aa0: 65 64 20 74 6f 20 64 69 76 69 64 65 20 75 70 20  ed to divide up 
0ab0: 74 68 65 20 62 75 66 66 65 72 20 70 72 6f 76 69  the buffer provi
0ac0: 64 65 64 20 75 73 69 6e 67 0a 2a 2a 20 74 68 65  ded using.** the
0ad0: 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50   SQLITE_CONFIG_P
0ae0: 41 47 45 43 41 43 48 45 20 6d 65 63 68 61 6e 69  AGECACHE mechani
0af0: 73 6d 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 50 67  sm..*/.struct Pg
0b00: 46 72 65 65 73 6c 6f 74 20 7b 0a 20 20 50 67 46  Freeslot {.  PgF
0b10: 72 65 65 73 6c 6f 74 20 2a 70 4e 65 78 74 3b 20  reeslot *pNext; 
0b20: 20 2f 2a 20 4e 65 78 74 20 66 72 65 65 20 73 6c   /* Next free sl
0b30: 6f 74 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20  ot */.};../*.** 
0b40: 47 6c 6f 62 61 6c 20 64 61 74 61 20 75 73 65 64  Global data used
0b50: 20 62 79 20 74 68 69 73 20 63 61 63 68 65 2e 0a   by this cache..
0b60: 2a 2f 0a 73 74 61 74 69 63 20 53 51 4c 49 54 45  */.static SQLITE
0b70: 5f 57 53 44 20 73 74 72 75 63 74 20 50 43 61 63  _WSD struct PCac
0b80: 68 65 47 6c 6f 62 61 6c 20 7b 0a 20 20 73 71 6c  heGlobal {.  sql
0b90: 69 74 65 33 5f 6d 75 74 65 78 20 2a 6d 75 74 65  ite3_mutex *mute
0ba0: 78 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  x;              
0bb0: 20 2f 2a 20 73 74 61 74 69 63 20 6d 75 74 65 78   /* static mutex
0bc0: 20 4d 55 54 45 58 5f 53 54 41 54 49 43 5f 4c 52   MUTEX_STATIC_LR
0bd0: 55 20 2a 2f 0a 0a 20 20 69 6e 74 20 6e 4d 61 78  U */..  int nMax
0be0: 50 61 67 65 3b 20 20 20 20 20 20 20 20 20 20 20  Page;           
0bf0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
0c00: 75 6d 20 6f 66 20 6e 4d 61 78 50 61 67 65 20 66  um of nMaxPage f
0c10: 6f 72 20 70 75 72 67 65 61 62 6c 65 20 63 61 63  or purgeable cac
0c20: 68 65 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 4d 69  hes */.  int nMi
0c30: 6e 50 61 67 65 3b 20 20 20 20 20 20 20 20 20 20  nPage;          
0c40: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0c50: 53 75 6d 20 6f 66 20 6e 4d 69 6e 50 61 67 65 20  Sum of nMinPage 
0c60: 66 6f 72 20 70 75 72 67 65 61 62 6c 65 20 63 61  for purgeable ca
0c70: 63 68 65 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 43  ches */.  int nC
0c80: 75 72 72 65 6e 74 50 61 67 65 3b 20 20 20 20 20  urrentPage;     
0c90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0ca0: 20 4e 75 6d 62 65 72 20 6f 66 20 70 75 72 67 65   Number of purge
0cb0: 61 62 6c 65 20 70 61 67 65 73 20 61 6c 6c 6f 63  able pages alloc
0cc0: 61 74 65 64 20 2a 2f 0a 20 20 50 67 48 64 72 31  ated */.  PgHdr1
0cd0: 20 2a 70 4c 72 75 48 65 61 64 2c 20 2a 70 4c 72   *pLruHead, *pLr
0ce0: 75 54 61 69 6c 3b 20 20 20 20 20 20 20 20 2f 2a  uTail;        /*
0cf0: 20 4c 52 55 20 6c 69 73 74 20 6f 66 20 75 6e 70   LRU list of unp
0d00: 69 6e 6e 65 64 20 70 61 67 65 73 20 2a 2f 0a 0a  inned pages */..
0d10: 20 20 2f 2a 20 56 61 72 69 61 62 6c 65 73 20 72    /* Variables r
0d20: 65 6c 61 74 65 64 20 74 6f 20 53 51 4c 49 54 45  elated to SQLITE
0d30: 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48  _CONFIG_PAGECACH
0d40: 45 20 73 65 74 74 69 6e 67 73 2e 20 2a 2f 0a 20  E settings. */. 
0d50: 20 69 6e 74 20 73 7a 53 6c 6f 74 3b 20 20 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 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
0d80: 65 61 63 68 20 66 72 65 65 20 73 6c 6f 74 20 2a  each free slot *
0d90: 2f 0a 20 20 76 6f 69 64 20 2a 70 53 74 61 72 74  /.  void *pStart
0da0: 2c 20 2a 70 45 6e 64 3b 20 20 20 20 20 20 20 20  , *pEnd;        
0db0: 20 20 20 20 20 20 20 20 2f 2a 20 42 6f 75 6e 64          /* Bound
0dc0: 73 20 6f 66 20 70 61 67 65 63 61 63 68 65 20 6d  s of pagecache m
0dd0: 61 6c 6c 6f 63 20 72 61 6e 67 65 20 2a 2f 0a 20  alloc range */. 
0de0: 20 50 67 46 72 65 65 73 6c 6f 74 20 2a 70 46 72   PgFreeslot *pFr
0df0: 65 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ee;             
0e00: 20 20 20 20 20 2f 2a 20 46 72 65 65 20 70 61 67       /* Free pag
0e10: 65 20 62 6c 6f 63 6b 73 20 2a 2f 0a 7d 20 70 63  e blocks */.} pc
0e20: 61 63 68 65 31 5f 67 3b 0a 0a 2f 2a 0a 2a 2a 20  ache1_g;../*.** 
0e30: 41 6c 6c 20 63 6f 64 65 20 69 6e 20 74 68 69 73  All code in this
0e40: 20 66 69 6c 65 20 73 68 6f 75 6c 64 20 61 63 63   file should acc
0e50: 65 73 73 20 74 68 65 20 67 6c 6f 62 61 6c 20 73  ess the global s
0e60: 74 72 75 63 74 75 72 65 20 61 62 6f 76 65 20 76  tructure above v
0e70: 69 61 20 74 68 65 0a 2a 2a 20 61 6c 69 61 73 20  ia the.** alias 
0e80: 22 70 63 61 63 68 65 31 22 2e 20 54 68 69 73 20  "pcache1". This 
0e90: 65 6e 73 75 72 65 73 20 74 68 61 74 20 74 68 65  ensures that the
0ea0: 20 57 53 44 20 65 6d 75 6c 61 74 69 6f 6e 20 69   WSD emulation i
0eb0: 73 20 75 73 65 64 20 77 68 65 6e 0a 2a 2a 20 63  s used when.** c
0ec0: 6f 6d 70 69 6c 69 6e 67 20 66 6f 72 20 73 79 73  ompiling for sys
0ed0: 74 65 6d 73 20 74 68 61 74 20 64 6f 20 6e 6f 74  tems that do not
0ee0: 20 73 75 70 70 6f 72 74 20 72 65 61 6c 20 57 53   support real WS
0ef0: 44 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 70 63  D..*/.#define pc
0f00: 61 63 68 65 31 20 28 47 4c 4f 42 41 4c 28 73 74  ache1 (GLOBAL(st
0f10: 72 75 63 74 20 50 43 61 63 68 65 47 6c 6f 62 61  ruct PCacheGloba
0f20: 6c 2c 20 70 63 61 63 68 65 31 5f 67 29 29 0a 0a  l, pcache1_g))..
0f30: 2f 2a 0a 2a 2a 20 57 68 65 6e 20 61 20 50 67 48  /*.** When a PgH
0f40: 64 72 31 20 73 74 72 75 63 74 75 72 65 20 69 73  dr1 structure is
0f50: 20 61 6c 6c 6f 63 61 74 65 64 2c 20 74 68 65 20   allocated, the 
0f60: 61 73 73 6f 63 69 61 74 65 64 20 50 43 61 63 68  associated PCach
0f70: 65 31 2e 73 7a 50 61 67 65 0a 2a 2a 20 62 79 74  e1.szPage.** byt
0f80: 65 73 20 6f 66 20 64 61 74 61 20 61 72 65 20 6c  es of data are l
0f90: 6f 63 61 74 65 64 20 64 69 72 65 63 74 6c 79 20  ocated directly 
0fa0: 61 66 74 65 72 20 69 74 20 69 6e 20 6d 65 6d 6f  after it in memo
0fb0: 72 79 20 28 69 2e 65 2e 20 74 68 65 20 74 6f 74  ry (i.e. the tot
0fc0: 61 6c 0a 2a 2a 20 73 69 7a 65 20 6f 66 20 74 68  al.** size of th
0fd0: 65 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 69 73 20  e allocation is 
0fe0: 73 69 7a 65 6f 66 28 50 67 48 64 72 31 29 2b 50  sizeof(PgHdr1)+P
0ff0: 43 61 63 68 65 31 2e 73 7a 50 61 67 65 20 62 79  Cache1.szPage by
1000: 74 65 29 2e 20 54 68 65 0a 2a 2a 20 50 47 48 44  te). The.** PGHD
1010: 52 31 5f 54 4f 5f 50 41 47 45 28 29 20 6d 61 63  R1_TO_PAGE() mac
1020: 72 6f 20 74 61 6b 65 73 20 61 20 70 6f 69 6e 74  ro takes a point
1030: 65 72 20 74 6f 20 61 20 50 67 48 64 72 31 20 73  er to a PgHdr1 s
1040: 74 72 75 63 74 75 72 65 20 61 73 0a 2a 2a 20 61  tructure as.** a
1050: 6e 20 61 72 67 75 6d 65 6e 74 20 61 6e 64 20 72  n argument and r
1060: 65 74 75 72 6e 73 20 61 20 70 6f 69 6e 74 65 72  eturns a pointer
1070: 20 74 6f 20 74 68 65 20 61 73 73 6f 63 69 61 74   to the associat
1080: 65 64 20 62 6c 6f 63 6b 20 6f 66 20 73 7a 50 61  ed block of szPa
1090: 67 65 0a 2a 2a 20 62 79 74 65 73 2e 20 54 68 65  ge.** bytes. The
10a0: 20 50 41 47 45 5f 54 4f 5f 50 47 48 44 52 31 28   PAGE_TO_PGHDR1(
10b0: 29 20 6d 61 63 72 6f 20 64 6f 65 73 20 74 68 65  ) macro does the
10c0: 20 6f 70 70 6f 73 69 74 65 3a 20 69 74 73 20 61   opposite: its a
10d0: 72 67 75 6d 65 6e 74 20 69 73 0a 2a 2a 20 61 20  rgument is.** a 
10e0: 70 6f 69 6e 74 65 72 20 74 6f 20 61 20 62 6c 6f  pointer to a blo
10f0: 63 6b 20 6f 66 20 73 7a 50 61 67 65 20 62 79 74  ck of szPage byt
1100: 65 73 20 6f 66 20 64 61 74 61 20 61 6e 64 20 74  es of data and t
1110: 68 65 20 72 65 74 75 72 6e 20 76 61 6c 75 65 20  he return value 
1120: 69 73 0a 2a 2a 20 61 20 70 6f 69 6e 74 65 72 20  is.** a pointer 
1130: 74 6f 20 74 68 65 20 61 73 73 6f 63 69 61 74 65  to the associate
1140: 64 20 50 67 48 64 72 31 20 73 74 72 75 63 74 75  d PgHdr1 structu
1150: 72 65 2e 0a 2a 2a 0a 2a 2a 20 20 20 61 73 73 65  re..**.**   asse
1160: 72 74 28 20 50 47 48 44 52 31 5f 54 4f 5f 50 41  rt( PGHDR1_TO_PA
1170: 47 45 28 50 41 47 45 5f 54 4f 5f 50 47 48 44 52  GE(PAGE_TO_PGHDR
1180: 31 28 58 29 29 3d 3d 58 20 29 3b 0a 2a 2f 0a 23  1(X))==X );.*/.#
1190: 64 65 66 69 6e 65 20 50 47 48 44 52 31 5f 54 4f  define PGHDR1_TO
11a0: 5f 50 41 47 45 28 70 29 20 28 76 6f 69 64 20 2a  _PAGE(p) (void *
11b0: 29 28 26 28 28 75 6e 73 69 67 6e 65 64 20 63 68  )(&((unsigned ch
11c0: 61 72 20 2a 29 70 29 5b 73 69 7a 65 6f 66 28 50  ar *)p)[sizeof(P
11d0: 67 48 64 72 31 29 5d 29 0a 23 64 65 66 69 6e 65  gHdr1)]).#define
11e0: 20 50 41 47 45 5f 54 4f 5f 50 47 48 44 52 31 28   PAGE_TO_PGHDR1(
11f0: 70 29 20 28 50 67 48 64 72 31 20 2a 29 28 26 28  p) (PgHdr1 *)(&(
1200: 28 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a  (unsigned char *
1210: 29 70 29 5b 2d 31 2a 28 69 6e 74 29 73 69 7a 65  )p)[-1*(int)size
1220: 6f 66 28 50 67 48 64 72 31 29 5d 29 0a 0a 2f 2a  of(PgHdr1)])../*
1230: 0a 2a 2a 20 4d 61 63 72 6f 73 20 74 6f 20 65 6e  .** Macros to en
1240: 74 65 72 20 61 6e 64 20 6c 65 61 76 65 20 74 68  ter and leave th
1250: 65 20 67 6c 6f 62 61 6c 20 4c 52 55 20 6d 75 74  e global LRU mut
1260: 65 78 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 70  ex..*/.#define p
1270: 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78  cache1EnterMutex
1280: 28 29 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78  () sqlite3_mutex
1290: 5f 65 6e 74 65 72 28 70 63 61 63 68 65 31 2e 6d  _enter(pcache1.m
12a0: 75 74 65 78 29 0a 23 64 65 66 69 6e 65 20 70 63  utex).#define pc
12b0: 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28  ache1LeaveMutex(
12c0: 29 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f  ) sqlite3_mutex_
12d0: 6c 65 61 76 65 28 70 63 61 63 68 65 31 2e 6d 75  leave(pcache1.mu
12e0: 74 65 78 29 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a  tex)../*********
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 2f 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a  *****/./********
1340: 20 50 61 67 65 20 41 6c 6c 6f 63 61 74 69 6f 6e   Page Allocation
1350: 2f 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50  /SQLITE_CONFIG_P
1360: 43 41 43 48 45 20 52 65 6c 61 74 65 64 20 46 75  CACHE Related Fu
1370: 6e 63 74 69 6f 6e 73 20 2a 2a 2a 2a 2a 2a 2a 2a  nctions ********
1380: 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 54  ******/../*.** T
1390: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
13a0: 63 61 6c 6c 65 64 20 64 75 72 69 6e 67 20 69 6e  called during in
13b0: 69 74 69 61 6c 69 7a 61 74 69 6f 6e 20 69 66 20  itialization if 
13c0: 61 20 73 74 61 74 69 63 20 62 75 66 66 65 72 20  a static buffer 
13d0: 69 73 20 0a 2a 2a 20 73 75 70 70 6c 69 65 64 20  is .** supplied 
13e0: 74 6f 20 75 73 65 20 66 6f 72 20 74 68 65 20 70  to use for the p
13f0: 61 67 65 2d 63 61 63 68 65 20 62 79 20 70 61 73  age-cache by pas
1400: 73 69 6e 67 20 74 68 65 20 53 51 4c 49 54 45 5f  sing the SQLITE_
1410: 43 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48 45  CONFIG_PAGECACHE
1420: 0a 2a 2a 20 76 65 72 62 20 74 6f 20 73 71 6c 69  .** verb to sqli
1430: 74 65 33 5f 63 6f 6e 66 69 67 28 29 2e 20 50 61  te3_config(). Pa
1440: 72 61 6d 65 74 65 72 20 70 42 75 66 20 70 6f 69  rameter pBuf poi
1450: 6e 74 73 20 74 6f 20 61 6e 20 61 6c 6c 6f 63 61  nts to an alloca
1460: 74 69 6f 6e 20 6c 61 72 67 65 0a 2a 2a 20 65 6e  tion large.** en
1470: 6f 75 67 68 20 74 6f 20 63 6f 6e 74 61 69 6e 20  ough to contain 
1480: 27 6e 27 20 62 75 66 66 65 72 73 20 6f 66 20 27  'n' buffers of '
1490: 73 7a 27 20 62 79 74 65 73 20 65 61 63 68 2e 0a  sz' bytes each..
14a0: 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50  */.void sqlite3P
14b0: 43 61 63 68 65 42 75 66 66 65 72 53 65 74 75 70  CacheBufferSetup
14c0: 28 76 6f 69 64 20 2a 70 42 75 66 2c 20 69 6e 74  (void *pBuf, int
14d0: 20 73 7a 2c 20 69 6e 74 20 6e 29 7b 0a 20 20 50   sz, int n){.  P
14e0: 67 46 72 65 65 73 6c 6f 74 20 2a 70 3b 0a 20 20  gFreeslot *p;.  
14f0: 73 7a 20 26 3d 20 7e 37 3b 0a 20 20 70 63 61 63  sz &= ~7;.  pcac
1500: 68 65 31 2e 73 7a 53 6c 6f 74 20 3d 20 73 7a 3b  he1.szSlot = sz;
1510: 0a 20 20 70 63 61 63 68 65 31 2e 70 53 74 61 72  .  pcache1.pStar
1520: 74 20 3d 20 70 42 75 66 3b 0a 20 20 70 63 61 63  t = pBuf;.  pcac
1530: 68 65 31 2e 70 46 72 65 65 20 3d 20 30 3b 0a 20  he1.pFree = 0;. 
1540: 20 77 68 69 6c 65 28 20 6e 2d 2d 20 29 7b 0a 20   while( n-- ){. 
1550: 20 20 20 70 20 3d 20 28 50 67 46 72 65 65 73 6c     p = (PgFreesl
1560: 6f 74 2a 29 70 42 75 66 3b 0a 20 20 20 20 70 2d  ot*)pBuf;.    p-
1570: 3e 70 4e 65 78 74 20 3d 20 70 63 61 63 68 65 31  >pNext = pcache1
1580: 2e 70 46 72 65 65 3b 0a 20 20 20 20 70 63 61 63  .pFree;.    pcac
1590: 68 65 31 2e 70 46 72 65 65 20 3d 20 70 3b 0a 20  he1.pFree = p;. 
15a0: 20 20 20 70 42 75 66 20 3d 20 28 76 6f 69 64 2a     pBuf = (void*
15b0: 29 26 28 28 63 68 61 72 2a 29 70 42 75 66 29 5b  )&((char*)pBuf)[
15c0: 73 7a 5d 3b 0a 20 20 7d 0a 20 20 70 63 61 63 68  sz];.  }.  pcach
15d0: 65 31 2e 70 45 6e 64 20 3d 20 70 42 75 66 3b 0a  e1.pEnd = pBuf;.
15e0: 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6c 6c 6f 63 20  }../*.** Malloc 
15f0: 66 75 6e 63 74 69 6f 6e 20 75 73 65 64 20 77 69  function used wi
1600: 74 68 69 6e 20 74 68 69 73 20 66 69 6c 65 20 74  thin this file t
1610: 6f 20 61 6c 6c 6f 63 61 74 65 20 73 70 61 63 65  o allocate space
1620: 20 66 72 6f 6d 20 74 68 65 20 62 75 66 66 65 72   from the buffer
1630: 0a 2a 2a 20 63 6f 6e 66 69 67 75 72 65 64 20 75  .** configured u
1640: 73 69 6e 67 20 73 71 6c 69 74 65 33 5f 63 6f 6e  sing sqlite3_con
1650: 66 69 67 28 53 51 4c 49 54 45 5f 43 4f 4e 46 49  fig(SQLITE_CONFI
1660: 47 5f 50 41 47 45 43 41 43 48 45 29 20 6f 70 74  G_PAGECACHE) opt
1670: 69 6f 6e 2e 20 49 66 20 6e 6f 20 0a 2a 2a 20 73  ion. If no .** s
1680: 75 63 68 20 62 75 66 66 65 72 20 65 78 69 73 74  uch buffer exist
1690: 73 20 6f 72 20 74 68 65 72 65 20 69 73 20 6e 6f  s or there is no
16a0: 20 73 70 61 63 65 20 6c 65 66 74 20 69 6e 20 69   space left in i
16b0: 74 2c 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  t, this function
16c0: 20 66 61 6c 6c 73 20 0a 2a 2a 20 62 61 63 6b 20   falls .** back 
16d0: 74 6f 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63  to sqlite3Malloc
16e0: 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ()..*/.static vo
16f0: 69 64 20 2a 70 63 61 63 68 65 31 41 6c 6c 6f 63  id *pcache1Alloc
1700: 28 69 6e 74 20 6e 42 79 74 65 29 7b 0a 20 20 76  (int nByte){.  v
1710: 6f 69 64 20 2a 70 3b 0a 20 20 61 73 73 65 72 74  oid *p;.  assert
1720: 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f  ( sqlite3_mutex_
1730: 68 65 6c 64 28 70 63 61 63 68 65 31 2e 6d 75 74  held(pcache1.mut
1740: 65 78 29 20 29 3b 0a 20 20 69 66 28 20 6e 42 79  ex) );.  if( nBy
1750: 74 65 3c 3d 70 63 61 63 68 65 31 2e 73 7a 53 6c  te<=pcache1.szSl
1760: 6f 74 20 26 26 20 70 63 61 63 68 65 31 2e 70 46  ot && pcache1.pF
1770: 72 65 65 20 29 7b 0a 20 20 20 20 70 20 3d 20 28  ree ){.    p = (
1780: 50 67 48 64 72 31 20 2a 29 70 63 61 63 68 65 31  PgHdr1 *)pcache1
1790: 2e 70 46 72 65 65 3b 0a 20 20 20 20 70 63 61 63  .pFree;.    pcac
17a0: 68 65 31 2e 70 46 72 65 65 20 3d 20 70 63 61 63  he1.pFree = pcac
17b0: 68 65 31 2e 70 46 72 65 65 2d 3e 70 4e 65 78 74  he1.pFree->pNext
17c0: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 53 74 61  ;.    sqlite3Sta
17d0: 74 75 73 53 65 74 28 53 51 4c 49 54 45 5f 53 54  tusSet(SQLITE_ST
17e0: 41 54 55 53 5f 50 41 47 45 43 41 43 48 45 5f 53  ATUS_PAGECACHE_S
17f0: 49 5a 45 2c 20 6e 42 79 74 65 29 3b 0a 20 20 20  IZE, nByte);.   
1800: 20 73 71 6c 69 74 65 33 53 74 61 74 75 73 41 64   sqlite3StatusAd
1810: 64 28 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f  d(SQLITE_STATUS_
1820: 50 41 47 45 43 41 43 48 45 5f 55 53 45 44 2c 20  PAGECACHE_USED, 
1830: 31 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 0a 20 20  1);.  }else{..  
1840: 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 61 20    /* Allocate a 
1850: 6e 65 77 20 62 75 66 66 65 72 20 75 73 69 6e 67  new buffer using
1860: 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 2e 20   sqlite3Malloc. 
1870: 42 65 66 6f 72 65 20 64 6f 69 6e 67 20 73 6f 2c  Before doing so,
1880: 20 65 78 69 74 20 74 68 65 0a 20 20 20 20 2a 2a   exit the.    **
1890: 20 67 6c 6f 62 61 6c 20 70 63 61 63 68 65 20 6d   global pcache m
18a0: 75 74 65 78 20 61 6e 64 20 75 6e 6c 6f 63 6b 20  utex and unlock 
18b0: 74 68 65 20 70 61 67 65 72 2d 63 61 63 68 65 20  the pager-cache 
18c0: 6f 62 6a 65 63 74 20 70 43 61 63 68 65 2e 20 54  object pCache. T
18d0: 68 69 73 20 69 73 20 0a 20 20 20 20 2a 2a 20 73  his is .    ** s
18e0: 6f 20 74 68 61 74 20 69 66 20 74 68 65 20 61 74  o that if the at
18f0: 74 65 6d 70 74 20 74 6f 20 61 6c 6c 6f 63 61 74  tempt to allocat
1900: 65 20 61 20 6e 65 77 20 62 75 66 66 65 72 20 63  e a new buffer c
1910: 61 75 73 65 73 20 74 68 65 20 74 68 65 20 0a 20  auses the the . 
1920: 20 20 20 2a 2a 20 63 6f 6e 66 69 67 75 72 65 64     ** configured
1930: 20 73 6f 66 74 2d 68 65 61 70 2d 6c 69 6d 69 74   soft-heap-limit
1940: 20 74 6f 20 62 65 20 62 72 65 61 63 68 65 64 2c   to be breached,
1950: 20 69 74 20 77 69 6c 6c 20 62 65 20 70 6f 73 73   it will be poss
1960: 69 62 6c 65 20 74 6f 0a 20 20 20 20 2a 2a 20 72  ible to.    ** r
1970: 65 63 6c 61 69 6d 20 6d 65 6d 6f 72 79 20 66 72  eclaim memory fr
1980: 6f 6d 20 74 68 69 73 20 70 61 67 65 72 2d 63 61  om this pager-ca
1990: 63 68 65 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20  che..    */.    
19a0: 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65  pcache1LeaveMute
19b0: 78 28 29 3b 0a 20 20 20 20 70 20 3d 20 73 71 6c  x();.    p = sql
19c0: 69 74 65 33 4d 61 6c 6c 6f 63 28 6e 42 79 74 65  ite3Malloc(nByte
19d0: 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31 45 6e  );.    pcache1En
19e0: 74 65 72 4d 75 74 65 78 28 29 3b 0a 20 20 20 20  terMutex();.    
19f0: 69 66 28 20 70 20 29 7b 0a 20 20 20 20 20 20 69  if( p ){.      i
1a00: 6e 74 20 73 7a 20 3d 20 73 71 6c 69 74 65 33 4d  nt sz = sqlite3M
1a10: 61 6c 6c 6f 63 53 69 7a 65 28 70 29 3b 0a 20 20  allocSize(p);.  
1a20: 20 20 20 20 73 71 6c 69 74 65 33 53 74 61 74 75      sqlite3Statu
1a30: 73 41 64 64 28 53 51 4c 49 54 45 5f 53 54 41 54  sAdd(SQLITE_STAT
1a40: 55 53 5f 50 41 47 45 43 41 43 48 45 5f 4f 56 45  US_PAGECACHE_OVE
1a50: 52 46 4c 4f 57 2c 20 73 7a 29 3b 0a 20 20 20 20  RFLOW, sz);.    
1a60: 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 70  }.  }.  return p
1a70: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20  ;.}../*.** Free 
1a80: 61 6e 20 61 6c 6c 6f 63 61 74 65 64 20 62 75 66  an allocated buf
1a90: 66 65 72 20 6f 62 74 61 69 6e 65 64 20 66 72 6f  fer obtained fro
1aa0: 6d 20 70 63 61 63 68 65 31 41 6c 6c 6f 63 28 29  m pcache1Alloc()
1ab0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
1ac0: 20 70 63 61 63 68 65 31 46 72 65 65 28 76 6f 69   pcache1Free(voi
1ad0: 64 20 2a 70 29 7b 0a 20 20 61 73 73 65 72 74 28  d *p){.  assert(
1ae0: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68   sqlite3_mutex_h
1af0: 65 6c 64 28 70 63 61 63 68 65 31 2e 6d 75 74 65  eld(pcache1.mute
1b00: 78 29 20 29 3b 0a 20 20 69 66 28 20 70 3d 3d 30  x) );.  if( p==0
1b10: 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 69 66 28   ) return;.  if(
1b20: 20 70 3e 3d 70 63 61 63 68 65 31 2e 70 53 74 61   p>=pcache1.pSta
1b30: 72 74 20 26 26 20 70 3c 70 63 61 63 68 65 31 2e  rt && p<pcache1.
1b40: 70 45 6e 64 20 29 7b 0a 20 20 20 20 50 67 46 72  pEnd ){.    PgFr
1b50: 65 65 73 6c 6f 74 20 2a 70 53 6c 6f 74 3b 0a 20  eeslot *pSlot;. 
1b60: 20 20 20 73 71 6c 69 74 65 33 53 74 61 74 75 73     sqlite3Status
1b70: 41 64 64 28 53 51 4c 49 54 45 5f 53 54 41 54 55  Add(SQLITE_STATU
1b80: 53 5f 50 41 47 45 43 41 43 48 45 5f 55 53 45 44  S_PAGECACHE_USED
1b90: 2c 20 2d 31 29 3b 0a 20 20 20 20 70 53 6c 6f 74  , -1);.    pSlot
1ba0: 20 3d 20 28 50 67 46 72 65 65 73 6c 6f 74 2a 29   = (PgFreeslot*)
1bb0: 70 3b 0a 20 20 20 20 70 53 6c 6f 74 2d 3e 70 4e  p;.    pSlot->pN
1bc0: 65 78 74 20 3d 20 70 63 61 63 68 65 31 2e 70 46  ext = pcache1.pF
1bd0: 72 65 65 3b 0a 20 20 20 20 70 63 61 63 68 65 31  ree;.    pcache1
1be0: 2e 70 46 72 65 65 20 3d 20 70 53 6c 6f 74 3b 0a  .pFree = pSlot;.
1bf0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 6e 74    }else{.    int
1c00: 20 69 53 69 7a 65 20 3d 20 73 71 6c 69 74 65 33   iSize = sqlite3
1c10: 4d 61 6c 6c 6f 63 53 69 7a 65 28 70 29 3b 0a 20  MallocSize(p);. 
1c20: 20 20 20 73 71 6c 69 74 65 33 53 74 61 74 75 73     sqlite3Status
1c30: 41 64 64 28 53 51 4c 49 54 45 5f 53 54 41 54 55  Add(SQLITE_STATU
1c40: 53 5f 50 41 47 45 43 41 43 48 45 5f 4f 56 45 52  S_PAGECACHE_OVER
1c50: 46 4c 4f 57 2c 20 2d 69 53 69 7a 65 29 3b 0a 20  FLOW, -iSize);. 
1c60: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
1c70: 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a  p);.  }.}../*.**
1c80: 20 41 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20   Allocate a new 
1c90: 70 61 67 65 20 6f 62 6a 65 63 74 20 69 6e 69 74  page object init
1ca0: 69 61 6c 6c 79 20 61 73 73 6f 63 69 61 74 65 64  ially associated
1cb0: 20 77 69 74 68 20 63 61 63 68 65 20 70 43 61 63   with cache pCac
1cc0: 68 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 50 67  he..*/.static Pg
1cd0: 48 64 72 31 20 2a 70 63 61 63 68 65 31 41 6c 6c  Hdr1 *pcache1All
1ce0: 6f 63 50 61 67 65 28 50 43 61 63 68 65 31 20 2a  ocPage(PCache1 *
1cf0: 70 43 61 63 68 65 29 7b 0a 20 20 69 6e 74 20 6e  pCache){.  int n
1d00: 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 50 67  Byte = sizeof(Pg
1d10: 48 64 72 31 29 20 2b 20 70 43 61 63 68 65 2d 3e  Hdr1) + pCache->
1d20: 73 7a 50 61 67 65 3b 0a 20 20 50 67 48 64 72 31  szPage;.  PgHdr1
1d30: 20 2a 70 20 3d 20 28 50 67 48 64 72 31 20 2a 29   *p = (PgHdr1 *)
1d40: 70 63 61 63 68 65 31 41 6c 6c 6f 63 28 6e 42 79  pcache1Alloc(nBy
1d50: 74 65 29 3b 0a 20 20 69 66 28 20 70 20 29 7b 0a  te);.  if( p ){.
1d60: 20 20 20 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c      memset(p, 0,
1d70: 20 6e 42 79 74 65 29 3b 0a 20 20 20 20 69 66 28   nByte);.    if(
1d80: 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61   pCache->bPurgea
1d90: 62 6c 65 20 29 7b 0a 20 20 20 20 20 20 70 63 61  ble ){.      pca
1da0: 63 68 65 31 2e 6e 43 75 72 72 65 6e 74 50 61 67  che1.nCurrentPag
1db0: 65 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  e++;.    }.  }. 
1dc0: 20 72 65 74 75 72 6e 20 70 3b 0a 7d 0a 0a 2f 2a   return p;.}../*
1dd0: 0a 2a 2a 20 46 72 65 65 20 61 20 70 61 67 65 20  .** Free a page 
1de0: 6f 62 6a 65 63 74 20 61 6c 6c 6f 63 61 74 65 64  object allocated
1df0: 20 62 79 20 70 63 61 63 68 65 31 41 6c 6c 6f 63   by pcache1Alloc
1e00: 50 61 67 65 28 29 2e 0a 2a 2f 0a 73 74 61 74 69  Page()..*/.stati
1e10: 63 20 76 6f 69 64 20 70 63 61 63 68 65 31 46 72  c void pcache1Fr
1e20: 65 65 50 61 67 65 28 50 67 48 64 72 31 20 2a 70  eePage(PgHdr1 *p
1e30: 29 7b 0a 20 20 69 66 28 20 70 20 29 7b 0a 20 20  ){.  if( p ){.  
1e40: 20 20 69 66 28 20 70 2d 3e 70 43 61 63 68 65 2d    if( p->pCache-
1e50: 3e 62 50 75 72 67 65 61 62 6c 65 20 29 7b 0a 20  >bPurgeable ){. 
1e60: 20 20 20 20 20 70 63 61 63 68 65 31 2e 6e 43 75       pcache1.nCu
1e70: 72 72 65 6e 74 50 61 67 65 2d 2d 3b 0a 20 20 20  rrentPage--;.   
1e80: 20 7d 0a 20 20 20 20 70 63 61 63 68 65 31 46 72   }.    pcache1Fr
1e90: 65 65 28 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a  ee(p);.  }.}../*
1ea0: 0a 2a 2a 20 4d 61 6c 6c 6f 63 20 66 75 6e 63 74  .** Malloc funct
1eb0: 69 6f 6e 20 75 73 65 64 20 62 79 20 53 51 4c 69  ion used by SQLi
1ec0: 74 65 20 74 6f 20 6f 62 74 61 69 6e 20 73 70 61  te to obtain spa
1ed0: 63 65 20 66 72 6f 6d 20 74 68 65 20 62 75 66 66  ce from the buff
1ee0: 65 72 20 63 6f 6e 66 69 67 75 72 65 64 0a 2a 2a  er configured.**
1ef0: 20 75 73 69 6e 67 20 73 71 6c 69 74 65 33 5f 63   using sqlite3_c
1f00: 6f 6e 66 69 67 28 53 51 4c 49 54 45 5f 43 4f 4e  onfig(SQLITE_CON
1f10: 46 49 47 5f 50 41 47 45 43 41 43 48 45 29 20 6f  FIG_PAGECACHE) o
1f20: 70 74 69 6f 6e 2e 20 49 66 20 6e 6f 20 73 75 63  ption. If no suc
1f30: 68 20 62 75 66 66 65 72 0a 2a 2a 20 65 78 69 73  h buffer.** exis
1f40: 74 73 2c 20 74 68 69 73 20 66 75 6e 63 74 69 6f  ts, this functio
1f50: 6e 20 66 61 6c 6c 73 20 62 61 63 6b 20 74 6f 20  n falls back to 
1f60: 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 29 2e  sqlite3Malloc().
1f70: 0a 2a 2f 0a 76 6f 69 64 20 2a 73 71 6c 69 74 65  .*/.void *sqlite
1f80: 33 50 61 67 65 4d 61 6c 6c 6f 63 28 69 6e 74 20  3PageMalloc(int 
1f90: 73 7a 29 7b 0a 20 20 76 6f 69 64 20 2a 70 3b 0a  sz){.  void *p;.
1fa0: 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75    pcache1EnterMu
1fb0: 74 65 78 28 29 3b 0a 20 20 70 20 3d 20 70 63 61  tex();.  p = pca
1fc0: 63 68 65 31 41 6c 6c 6f 63 28 73 7a 29 3b 0a 20  che1Alloc(sz);. 
1fd0: 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74   pcache1LeaveMut
1fe0: 65 78 28 29 3b 0a 20 20 72 65 74 75 72 6e 20 70  ex();.  return p
1ff0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20  ;.}../*.** Free 
2000: 61 6e 20 61 6c 6c 6f 63 61 74 65 64 20 62 75 66  an allocated buf
2010: 66 65 72 20 6f 62 74 61 69 6e 65 64 20 66 72 6f  fer obtained fro
2020: 6d 20 73 71 6c 69 74 65 33 50 61 67 65 4d 61 6c  m sqlite3PageMal
2030: 6c 6f 63 28 29 2e 0a 2a 2f 0a 76 6f 69 64 20 73  loc()..*/.void s
2040: 71 6c 69 74 65 33 50 61 67 65 46 72 65 65 28 76  qlite3PageFree(v
2050: 6f 69 64 20 2a 70 29 7b 0a 20 20 70 63 61 63 68  oid *p){.  pcach
2060: 65 31 45 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a  e1EnterMutex();.
2070: 20 20 70 63 61 63 68 65 31 46 72 65 65 28 70 29    pcache1Free(p)
2080: 3b 0a 20 20 70 63 61 63 68 65 31 4c 65 61 76 65  ;.  pcache1Leave
2090: 4d 75 74 65 78 28 29 3b 0a 7d 0a 0a 2f 2a 2a 2a  Mutex();.}../***
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 2f 0a 2f 2a 2a  ***********/./**
20f0: 2a 2a 2a 2a 2a 2a 20 47 65 6e 65 72 61 6c 20 49  ****** General I
2100: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 46 75  mplementation Fu
2110: 6e 63 74 69 6f 6e 73 20 2a 2a 2a 2a 2a 2a 2a 2a  nctions ********
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 2f 0a 0a 2f  ************/../
2140: 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69  *.** This functi
2150: 6f 6e 20 69 73 20 75 73 65 64 20 74 6f 20 72 65  on is used to re
2160: 73 69 7a 65 20 74 68 65 20 68 61 73 68 20 74 61  size the hash ta
2170: 62 6c 65 20 75 73 65 64 20 62 79 20 74 68 65 20  ble used by the 
2180: 63 61 63 68 65 20 70 61 73 73 65 64 0a 2a 2a 20  cache passed.** 
2190: 61 73 20 74 68 65 20 66 69 72 73 74 20 61 72 67  as the first arg
21a0: 75 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65  ument..**.** The
21b0: 20 67 6c 6f 62 61 6c 20 6d 75 74 65 78 20 6d 75   global mutex mu
21c0: 73 74 20 62 65 20 68 65 6c 64 20 77 68 65 6e 20  st be held when 
21d0: 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73  this function is
21e0: 20 63 61 6c 6c 65 64 2e 0a 2a 2f 0a 73 74 61 74   called..*/.stat
21f0: 69 63 20 69 6e 74 20 70 63 61 63 68 65 31 52 65  ic int pcache1Re
2200: 73 69 7a 65 48 61 73 68 28 50 43 61 63 68 65 31  sizeHash(PCache1
2210: 20 2a 70 29 7b 0a 20 20 50 67 48 64 72 31 20 2a   *p){.  PgHdr1 *
2220: 2a 61 70 4e 65 77 3b 0a 20 20 75 6e 73 69 67 6e  *apNew;.  unsign
2230: 65 64 20 69 6e 74 20 6e 4e 65 77 3b 0a 20 20 75  ed int nNew;.  u
2240: 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 3b 0a 0a  nsigned int i;..
2250: 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65    assert( sqlite
2260: 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 63 61  3_mutex_held(pca
2270: 63 68 65 31 2e 6d 75 74 65 78 29 20 29 3b 0a 0a  che1.mutex) );..
2280: 20 20 6e 4e 65 77 20 3d 20 70 2d 3e 6e 48 61 73    nNew = p->nHas
2290: 68 2a 32 3b 0a 20 20 69 66 28 20 6e 4e 65 77 3c  h*2;.  if( nNew<
22a0: 32 35 36 20 29 7b 0a 20 20 20 20 6e 4e 65 77 20  256 ){.    nNew 
22b0: 3d 20 32 35 36 3b 0a 20 20 7d 0a 0a 20 20 70 63  = 256;.  }..  pc
22c0: 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28  ache1LeaveMutex(
22d0: 29 3b 0a 20 20 69 66 28 20 70 2d 3e 6e 48 61 73  );.  if( p->nHas
22e0: 68 20 29 7b 20 73 71 6c 69 74 65 33 42 65 67 69  h ){ sqlite3Begi
22f0: 6e 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b  nBenignMalloc();
2300: 20 7d 0a 20 20 61 70 4e 65 77 20 3d 20 28 50 67   }.  apNew = (Pg
2310: 48 64 72 31 20 2a 2a 29 73 71 6c 69 74 65 33 5f  Hdr1 **)sqlite3_
2320: 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 50 67  malloc(sizeof(Pg
2330: 48 64 72 31 20 2a 29 2a 6e 4e 65 77 29 3b 0a 20  Hdr1 *)*nNew);. 
2340: 20 69 66 28 20 70 2d 3e 6e 48 61 73 68 20 29 7b   if( p->nHash ){
2350: 20 73 71 6c 69 74 65 33 45 6e 64 42 65 6e 69 67   sqlite3EndBenig
2360: 6e 4d 61 6c 6c 6f 63 28 29 3b 20 7d 0a 20 20 70  nMalloc(); }.  p
2370: 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78  cache1EnterMutex
2380: 28 29 3b 0a 20 20 69 66 28 20 61 70 4e 65 77 20  ();.  if( apNew 
2390: 29 7b 0a 20 20 20 20 6d 65 6d 73 65 74 28 61 70  ){.    memset(ap
23a0: 4e 65 77 2c 20 30 2c 20 73 69 7a 65 6f 66 28 50  New, 0, sizeof(P
23b0: 67 48 64 72 31 20 2a 29 2a 6e 4e 65 77 29 3b 0a  gHdr1 *)*nNew);.
23c0: 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70      for(i=0; i<p
23d0: 2d 3e 6e 48 61 73 68 3b 20 69 2b 2b 29 7b 0a 20  ->nHash; i++){. 
23e0: 20 20 20 20 20 50 67 48 64 72 31 20 2a 70 50 61       PgHdr1 *pPa
23f0: 67 65 3b 0a 20 20 20 20 20 20 50 67 48 64 72 31  ge;.      PgHdr1
2400: 20 2a 70 4e 65 78 74 20 3d 20 70 2d 3e 61 70 48   *pNext = p->apH
2410: 61 73 68 5b 69 5d 3b 0a 20 20 20 20 20 20 77 68  ash[i];.      wh
2420: 69 6c 65 28 20 28 70 50 61 67 65 20 3d 20 70 4e  ile( (pPage = pN
2430: 65 78 74 29 21 3d 30 20 29 7b 0a 20 20 20 20 20  ext)!=0 ){.     
2440: 20 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20     unsigned int 
2450: 68 20 3d 20 70 50 61 67 65 2d 3e 69 4b 65 79 20  h = pPage->iKey 
2460: 25 20 6e 4e 65 77 3b 0a 20 20 20 20 20 20 20 20  % nNew;.        
2470: 70 4e 65 78 74 20 3d 20 70 50 61 67 65 2d 3e 70  pNext = pPage->p
2480: 4e 65 78 74 3b 0a 20 20 20 20 20 20 20 20 70 50  Next;.        pP
2490: 61 67 65 2d 3e 70 4e 65 78 74 20 3d 20 61 70 4e  age->pNext = apN
24a0: 65 77 5b 68 5d 3b 0a 20 20 20 20 20 20 20 20 61  ew[h];.        a
24b0: 70 4e 65 77 5b 68 5d 20 3d 20 70 50 61 67 65 3b  pNew[h] = pPage;
24c0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
24d0: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
24e0: 70 2d 3e 61 70 48 61 73 68 29 3b 0a 20 20 20 20  p->apHash);.    
24f0: 70 2d 3e 61 70 48 61 73 68 20 3d 20 61 70 4e 65  p->apHash = apNe
2500: 77 3b 0a 20 20 20 20 70 2d 3e 6e 48 61 73 68 20  w;.    p->nHash 
2510: 3d 20 6e 4e 65 77 3b 0a 20 20 7d 0a 0a 20 20 72  = nNew;.  }..  r
2520: 65 74 75 72 6e 20 28 70 2d 3e 61 70 48 61 73 68  eturn (p->apHash
2530: 20 3f 20 53 51 4c 49 54 45 5f 4f 4b 20 3a 20 53   ? SQLITE_OK : S
2540: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 29 3b 0a 7d 0a  QLITE_NOMEM);.}.
2550: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  ./*.** This func
2560: 74 69 6f 6e 20 69 73 20 75 73 65 64 20 69 6e 74  tion is used int
2570: 65 72 6e 61 6c 6c 79 20 74 6f 20 72 65 6d 6f 76  ernally to remov
2580: 65 20 74 68 65 20 70 61 67 65 20 70 50 61 67 65  e the page pPage
2590: 20 66 72 6f 6d 20 74 68 65 20 0a 2a 2a 20 67 6c   from the .** gl
25a0: 6f 62 61 6c 20 4c 52 55 20 6c 69 73 74 2c 20 69  obal LRU list, i
25b0: 66 20 69 73 20 70 61 72 74 20 6f 66 20 69 74 2e  f is part of it.
25c0: 20 49 66 20 70 50 61 67 65 20 69 73 20 6e 6f 74   If pPage is not
25d0: 20 70 61 72 74 20 6f 66 20 74 68 65 20 67 6c 6f   part of the glo
25e0: 62 61 6c 0a 2a 2a 20 4c 52 55 20 6c 69 73 74 2c  bal.** LRU list,
25f0: 20 74 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74   then this funct
2600: 69 6f 6e 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a  ion is a no-op..
2610: 2a 2a 0a 2a 2a 20 54 68 65 20 67 6c 6f 62 61 6c  **.** The global
2620: 20 6d 75 74 65 78 20 6d 75 73 74 20 62 65 20 68   mutex must be h
2630: 65 6c 64 20 77 68 65 6e 20 74 68 69 73 20 66 75  eld when this fu
2640: 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64  nction is called
2650: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
2660: 20 70 63 61 63 68 65 31 50 69 6e 50 61 67 65 28   pcache1PinPage(
2670: 50 67 48 64 72 31 20 2a 70 50 61 67 65 29 7b 0a  PgHdr1 *pPage){.
2680: 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65    assert( sqlite
2690: 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 63 61  3_mutex_held(pca
26a0: 63 68 65 31 2e 6d 75 74 65 78 29 20 29 3b 0a 20  che1.mutex) );. 
26b0: 20 69 66 28 20 70 50 61 67 65 20 26 26 20 28 70   if( pPage && (p
26c0: 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 20 7c  Page->pLruNext |
26d0: 7c 20 70 50 61 67 65 3d 3d 70 63 61 63 68 65 31  | pPage==pcache1
26e0: 2e 70 4c 72 75 54 61 69 6c 29 20 29 7b 0a 20 20  .pLruTail) ){.  
26f0: 20 20 69 66 28 20 70 50 61 67 65 2d 3e 70 4c 72    if( pPage->pLr
2700: 75 50 72 65 76 20 29 7b 0a 20 20 20 20 20 20 70  uPrev ){.      p
2710: 50 61 67 65 2d 3e 70 4c 72 75 50 72 65 76 2d 3e  Page->pLruPrev->
2720: 70 4c 72 75 4e 65 78 74 20 3d 20 70 50 61 67 65  pLruNext = pPage
2730: 2d 3e 70 4c 72 75 4e 65 78 74 3b 0a 20 20 20 20  ->pLruNext;.    
2740: 7d 0a 20 20 20 20 69 66 28 20 70 50 61 67 65 2d  }.    if( pPage-
2750: 3e 70 4c 72 75 4e 65 78 74 20 29 7b 0a 20 20 20  >pLruNext ){.   
2760: 20 20 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65     pPage->pLruNe
2770: 78 74 2d 3e 70 4c 72 75 50 72 65 76 20 3d 20 70  xt->pLruPrev = p
2780: 50 61 67 65 2d 3e 70 4c 72 75 50 72 65 76 3b 0a  Page->pLruPrev;.
2790: 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70 63      }.    if( pc
27a0: 61 63 68 65 31 2e 70 4c 72 75 48 65 61 64 3d 3d  ache1.pLruHead==
27b0: 70 50 61 67 65 20 29 7b 0a 20 20 20 20 20 20 70  pPage ){.      p
27c0: 63 61 63 68 65 31 2e 70 4c 72 75 48 65 61 64 20  cache1.pLruHead 
27d0: 3d 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78  = pPage->pLruNex
27e0: 74 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28  t;.    }.    if(
27f0: 20 70 63 61 63 68 65 31 2e 70 4c 72 75 54 61 69   pcache1.pLruTai
2800: 6c 3d 3d 70 50 61 67 65 20 29 7b 0a 20 20 20 20  l==pPage ){.    
2810: 20 20 70 63 61 63 68 65 31 2e 70 4c 72 75 54 61    pcache1.pLruTa
2820: 69 6c 20 3d 20 70 50 61 67 65 2d 3e 70 4c 72 75  il = pPage->pLru
2830: 50 72 65 76 3b 0a 20 20 20 20 7d 0a 20 20 20 20  Prev;.    }.    
2840: 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 20  pPage->pLruNext 
2850: 3d 20 30 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e  = 0;.    pPage->
2860: 70 4c 72 75 50 72 65 76 20 3d 20 30 3b 0a 20 20  pLruPrev = 0;.  
2870: 20 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65 2d    pPage->pCache-
2880: 3e 6e 52 65 63 79 63 6c 61 62 6c 65 2d 2d 3b 0a  >nRecyclable--;.
2890: 20 20 7d 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 52 65    }.}.../*.** Re
28a0: 6d 6f 76 65 20 74 68 65 20 70 61 67 65 20 73 75  move the page su
28b0: 70 70 6c 69 65 64 20 61 73 20 61 6e 20 61 72 67  pplied as an arg
28c0: 75 6d 65 6e 74 20 66 72 6f 6d 20 74 68 65 20 68  ument from the h
28d0: 61 73 68 20 74 61 62 6c 65 20 0a 2a 2a 20 28 50  ash table .** (P
28e0: 43 61 63 68 65 31 2e 61 70 48 61 73 68 20 73 74  Cache1.apHash st
28f0: 72 75 63 74 75 72 65 29 20 74 68 61 74 20 69 74  ructure) that it
2900: 20 69 73 20 63 75 72 72 65 6e 74 6c 79 20 73 74   is currently st
2910: 6f 72 65 64 20 69 6e 2e 0a 2a 2a 0a 2a 2a 20 54  ored in..**.** T
2920: 68 65 20 67 6c 6f 62 61 6c 20 6d 75 74 65 78 20  he global mutex 
2930: 6d 75 73 74 20 62 65 20 68 65 6c 64 20 77 68 65  must be held whe
2940: 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  n this function 
2950: 69 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f 0a 73 74  is called..*/.st
2960: 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65  atic void pcache
2970: 31 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73 68 28  1RemoveFromHash(
2980: 50 67 48 64 72 31 20 2a 70 50 61 67 65 29 7b 0a  PgHdr1 *pPage){.
2990: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68    unsigned int h
29a0: 3b 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43 61  ;.  PCache1 *pCa
29b0: 63 68 65 20 3d 20 70 50 61 67 65 2d 3e 70 43 61  che = pPage->pCa
29c0: 63 68 65 3b 0a 20 20 50 67 48 64 72 31 20 2a 2a  che;.  PgHdr1 **
29d0: 70 70 3b 0a 0a 20 20 68 20 3d 20 70 50 61 67 65  pp;..  h = pPage
29e0: 2d 3e 69 4b 65 79 20 25 20 70 43 61 63 68 65 2d  ->iKey % pCache-
29f0: 3e 6e 48 61 73 68 3b 0a 20 20 66 6f 72 28 70 70  >nHash;.  for(pp
2a00: 3d 26 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68  =&pCache->apHash
2a10: 5b 68 5d 3b 20 28 2a 70 70 29 21 3d 70 50 61 67  [h]; (*pp)!=pPag
2a20: 65 3b 20 70 70 3d 26 28 2a 70 70 29 2d 3e 70 4e  e; pp=&(*pp)->pN
2a30: 65 78 74 29 3b 0a 20 20 2a 70 70 20 3d 20 28 2a  ext);.  *pp = (*
2a40: 70 70 29 2d 3e 70 4e 65 78 74 3b 0a 0a 20 20 70  pp)->pNext;..  p
2a50: 43 61 63 68 65 2d 3e 6e 50 61 67 65 2d 2d 3b 0a  Cache->nPage--;.
2a60: 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 74 68 65 72  }../*.** If ther
2a70: 65 20 61 72 65 20 63 75 72 72 65 6e 74 6c 79 20  e are currently 
2a80: 6d 6f 72 65 20 74 68 61 6e 20 70 63 61 63 68 65  more than pcache
2a90: 2e 6e 4d 61 78 50 61 67 65 20 70 61 67 65 73 20  .nMaxPage pages 
2aa0: 61 6c 6c 6f 63 61 74 65 64 2c 20 74 72 79 0a 2a  allocated, try.*
2ab0: 2a 20 74 6f 20 72 65 63 79 63 6c 65 20 70 61 67  * to recycle pag
2ac0: 65 73 20 74 6f 20 72 65 64 75 63 65 20 74 68 65  es to reduce the
2ad0: 20 6e 75 6d 62 65 72 20 61 6c 6c 6f 63 61 74 65   number allocate
2ae0: 64 20 74 6f 20 70 63 61 63 68 65 2e 6e 4d 61 78  d to pcache.nMax
2af0: 50 61 67 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  Page..*/.static 
2b00: 76 6f 69 64 20 70 63 61 63 68 65 31 45 6e 66 6f  void pcache1Enfo
2b10: 72 63 65 4d 61 78 50 61 67 65 28 76 6f 69 64 29  rceMaxPage(void)
2b20: 7b 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c 69  {.  assert( sqli
2b30: 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70  te3_mutex_held(p
2b40: 63 61 63 68 65 31 2e 6d 75 74 65 78 29 20 29 3b  cache1.mutex) );
2b50: 0a 20 20 77 68 69 6c 65 28 20 70 63 61 63 68 65  .  while( pcache
2b60: 31 2e 6e 43 75 72 72 65 6e 74 50 61 67 65 3e 70  1.nCurrentPage>p
2b70: 63 61 63 68 65 31 2e 6e 4d 61 78 50 61 67 65 20  cache1.nMaxPage 
2b80: 26 26 20 70 63 61 63 68 65 31 2e 70 4c 72 75 54  && pcache1.pLruT
2b90: 61 69 6c 20 29 7b 0a 20 20 20 20 50 67 48 64 72  ail ){.    PgHdr
2ba0: 31 20 2a 70 20 3d 20 70 63 61 63 68 65 31 2e 70  1 *p = pcache1.p
2bb0: 4c 72 75 54 61 69 6c 3b 0a 20 20 20 20 70 63 61  LruTail;.    pca
2bc0: 63 68 65 31 50 69 6e 50 61 67 65 28 70 29 3b 0a  che1PinPage(p);.
2bd0: 20 20 20 20 70 63 61 63 68 65 31 52 65 6d 6f 76      pcache1Remov
2be0: 65 46 72 6f 6d 48 61 73 68 28 70 29 3b 0a 20 20  eFromHash(p);.  
2bf0: 20 20 70 63 61 63 68 65 31 46 72 65 65 50 61 67    pcache1FreePag
2c00: 65 28 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a  e(p);.  }.}../*.
2c10: 2a 2a 20 44 69 73 63 61 72 64 20 61 6c 6c 20 70  ** Discard all p
2c20: 61 67 65 73 20 66 72 6f 6d 20 63 61 63 68 65 20  ages from cache 
2c30: 70 43 61 63 68 65 20 77 69 74 68 20 61 20 70 61  pCache with a pa
2c40: 67 65 20 6e 75 6d 62 65 72 20 28 6b 65 79 20 76  ge number (key v
2c50: 61 6c 75 65 29 20 0a 2a 2a 20 67 72 65 61 74 65  alue) .** greate
2c60: 72 20 74 68 61 6e 20 6f 72 20 65 71 75 61 6c 20  r than or equal 
2c70: 74 6f 20 69 4c 69 6d 69 74 2e 20 41 6e 79 20 70  to iLimit. Any p
2c80: 69 6e 6e 65 64 20 70 61 67 65 73 20 74 68 61 74  inned pages that
2c90: 20 6d 65 65 74 20 74 68 69 73 20 0a 2a 2a 20 63   meet this .** c
2ca0: 72 69 74 65 72 69 61 20 61 72 65 20 75 6e 70 69  riteria are unpi
2cb0: 6e 6e 65 64 20 62 65 66 6f 72 65 20 74 68 65 79  nned before they
2cc0: 20 61 72 65 20 64 69 73 63 61 72 64 65 64 2e 0a   are discarded..
2cd0: 2a 2a 0a 2a 2a 20 54 68 65 20 67 6c 6f 62 61 6c  **.** The global
2ce0: 20 6d 75 74 65 78 20 6d 75 73 74 20 62 65 20 68   mutex must be h
2cf0: 65 6c 64 20 77 68 65 6e 20 74 68 69 73 20 66 75  eld when this fu
2d00: 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64  nction is called
2d10: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
2d20: 20 70 63 61 63 68 65 31 54 72 75 6e 63 61 74 65   pcache1Truncate
2d30: 55 6e 73 61 66 65 28 0a 20 20 50 43 61 63 68 65  Unsafe(.  PCache
2d40: 31 20 2a 70 43 61 63 68 65 2c 20 0a 20 20 75 6e  1 *pCache, .  un
2d50: 73 69 67 6e 65 64 20 69 6e 74 20 69 4c 69 6d 69  signed int iLimi
2d60: 74 20 0a 29 7b 0a 20 20 75 6e 73 69 67 6e 65 64  t .){.  unsigned
2d70: 20 69 6e 74 20 68 3b 0a 20 20 61 73 73 65 72 74   int h;.  assert
2d80: 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f  ( sqlite3_mutex_
2d90: 68 65 6c 64 28 70 63 61 63 68 65 31 2e 6d 75 74  held(pcache1.mut
2da0: 65 78 29 20 29 3b 0a 20 20 66 6f 72 28 68 3d 30  ex) );.  for(h=0
2db0: 3b 20 68 3c 70 43 61 63 68 65 2d 3e 6e 48 61 73  ; h<pCache->nHas
2dc0: 68 3b 20 68 2b 2b 29 7b 0a 20 20 20 20 50 67 48  h; h++){.    PgH
2dd0: 64 72 31 20 2a 2a 70 70 20 3d 20 26 70 43 61 63  dr1 **pp = &pCac
2de0: 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 20 0a  he->apHash[h]; .
2df0: 20 20 20 20 50 67 48 64 72 31 20 2a 70 50 61 67      PgHdr1 *pPag
2e00: 65 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 28 70  e;.    while( (p
2e10: 50 61 67 65 20 3d 20 2a 70 70 29 21 3d 30 20 29  Page = *pp)!=0 )
2e20: 7b 0a 20 20 20 20 20 20 69 66 28 20 70 50 61 67  {.      if( pPag
2e30: 65 2d 3e 69 4b 65 79 3e 3d 69 4c 69 6d 69 74 20  e->iKey>=iLimit 
2e40: 29 7b 0a 20 20 20 20 20 20 20 20 70 63 61 63 68  ){.        pcach
2e50: 65 31 50 69 6e 50 61 67 65 28 70 50 61 67 65 29  e1PinPage(pPage)
2e60: 3b 0a 20 20 20 20 20 20 20 20 2a 70 70 20 3d 20  ;.        *pp = 
2e70: 70 50 61 67 65 2d 3e 70 4e 65 78 74 3b 0a 20 20  pPage->pNext;.  
2e80: 20 20 20 20 20 20 70 63 61 63 68 65 31 46 72 65        pcache1Fre
2e90: 65 50 61 67 65 28 70 50 61 67 65 29 3b 0a 20 20  ePage(pPage);.  
2ea0: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
2eb0: 20 20 20 70 70 20 3d 20 26 70 50 61 67 65 2d 3e     pp = &pPage->
2ec0: 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 7d 0a 20  pNext;.      }. 
2ed0: 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 2a 2a     }.  }.}../***
2ee0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
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 2a 2a 2a 2a 2a 2a  ****************
2f20: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 2a  ***********/./**
2f30: 2a 2a 2a 2a 2a 2a 20 73 71 6c 69 74 65 33 5f 70  ****** sqlite3_p
2f40: 63 61 63 68 65 20 4d 65 74 68 6f 64 73 20 2a 2a  cache Methods **
2f50: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2f60: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2f70: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f  ************/../
2f80: 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74  *.** Implementat
2f90: 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74  ion of the sqlit
2fa0: 65 33 5f 70 63 61 63 68 65 2e 78 49 6e 69 74 20  e3_pcache.xInit 
2fb0: 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69  method..*/.stati
2fc0: 63 20 69 6e 74 20 70 63 61 63 68 65 31 49 6e 69  c int pcache1Ini
2fd0: 74 28 76 6f 69 64 20 2a 4e 6f 74 55 73 65 64 29  t(void *NotUsed)
2fe0: 7b 0a 20 20 55 4e 55 53 45 44 5f 50 41 52 41 4d  {.  UNUSED_PARAM
2ff0: 45 54 45 52 28 4e 6f 74 55 73 65 64 29 3b 0a 20  ETER(NotUsed);. 
3000: 20 6d 65 6d 73 65 74 28 26 70 63 61 63 68 65 31   memset(&pcache1
3010: 2c 20 30 2c 20 73 69 7a 65 6f 66 28 70 63 61 63  , 0, sizeof(pcac
3020: 68 65 31 29 29 3b 0a 20 20 69 66 28 20 73 71 6c  he1));.  if( sql
3030: 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67  ite3GlobalConfig
3040: 2e 62 43 6f 72 65 4d 75 74 65 78 20 29 7b 0a 20  .bCoreMutex ){. 
3050: 20 20 20 70 63 61 63 68 65 31 2e 6d 75 74 65 78     pcache1.mutex
3060: 20 3d 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78   = sqlite3_mutex
3070: 5f 61 6c 6c 6f 63 28 53 51 4c 49 54 45 5f 4d 55  _alloc(SQLITE_MU
3080: 54 45 58 5f 53 54 41 54 49 43 5f 4c 52 55 29 3b  TEX_STATIC_LRU);
3090: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 53 51  .  }.  return SQ
30a0: 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a  LITE_OK;.}../*.*
30b0: 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  * Implementation
30c0: 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f   of the sqlite3_
30d0: 70 63 61 63 68 65 2e 78 53 68 75 74 64 6f 77 6e  pcache.xShutdown
30e0: 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74   method..*/.stat
30f0: 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 31 53  ic void pcache1S
3100: 68 75 74 64 6f 77 6e 28 76 6f 69 64 20 2a 4e 6f  hutdown(void *No
3110: 74 55 73 65 64 29 7b 0a 20 20 55 4e 55 53 45 44  tUsed){.  UNUSED
3120: 5f 50 41 52 41 4d 45 54 45 52 28 4e 6f 74 55 73  _PARAMETER(NotUs
3130: 65 64 29 3b 0a 20 20 2f 2a 20 6e 6f 2d 6f 70 20  ed);.  /* no-op 
3140: 2a 2f 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c  */.}../*.** Impl
3150: 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68  ementation of th
3160: 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  e sqlite3_pcache
3170: 2e 78 43 72 65 61 74 65 20 6d 65 74 68 6f 64 2e  .xCreate method.
3180: 0a 2a 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65 20  .**.** Allocate 
3190: 61 20 6e 65 77 20 63 61 63 68 65 2e 0a 2a 2f 0a  a new cache..*/.
31a0: 73 74 61 74 69 63 20 73 71 6c 69 74 65 33 5f 70  static sqlite3_p
31b0: 63 61 63 68 65 20 2a 70 63 61 63 68 65 31 43 72  cache *pcache1Cr
31c0: 65 61 74 65 28 69 6e 74 20 73 7a 50 61 67 65 2c  eate(int szPage,
31d0: 20 69 6e 74 20 62 50 75 72 67 65 61 62 6c 65 29   int bPurgeable)
31e0: 7b 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43 61  {.  PCache1 *pCa
31f0: 63 68 65 3b 0a 0a 20 20 70 43 61 63 68 65 20 3d  che;..  pCache =
3200: 20 28 50 43 61 63 68 65 31 20 2a 29 73 71 6c 69   (PCache1 *)sqli
3210: 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f  te3_malloc(sizeo
3220: 66 28 50 43 61 63 68 65 31 29 29 3b 0a 20 20 69  f(PCache1));.  i
3230: 66 28 20 70 43 61 63 68 65 20 29 7b 0a 20 20 20  f( pCache ){.   
3240: 20 6d 65 6d 73 65 74 28 70 43 61 63 68 65 2c 20   memset(pCache, 
3250: 30 2c 20 73 69 7a 65 6f 66 28 50 43 61 63 68 65  0, sizeof(PCache
3260: 31 29 29 3b 0a 20 20 20 20 70 43 61 63 68 65 2d  1));.    pCache-
3270: 3e 73 7a 50 61 67 65 20 3d 20 73 7a 50 61 67 65  >szPage = szPage
3280: 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 62 50  ;.    pCache->bP
3290: 75 72 67 65 61 62 6c 65 20 3d 20 28 62 50 75 72  urgeable = (bPur
32a0: 67 65 61 62 6c 65 20 3f 20 31 20 3a 20 30 29 3b  geable ? 1 : 0);
32b0: 0a 20 20 20 20 69 66 28 20 62 50 75 72 67 65 61  .    if( bPurgea
32c0: 62 6c 65 20 29 7b 0a 20 20 20 20 20 20 70 43 61  ble ){.      pCa
32d0: 63 68 65 2d 3e 6e 4d 69 6e 20 3d 20 31 30 3b 0a  che->nMin = 10;.
32e0: 20 20 20 20 20 20 70 63 61 63 68 65 31 45 6e 74        pcache1Ent
32f0: 65 72 4d 75 74 65 78 28 29 3b 0a 20 20 20 20 20  erMutex();.     
3300: 20 70 63 61 63 68 65 31 2e 6e 4d 69 6e 50 61 67   pcache1.nMinPag
3310: 65 20 2b 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 69  e += pCache->nMi
3320: 6e 3b 0a 20 20 20 20 20 20 70 63 61 63 68 65 31  n;.      pcache1
3330: 4c 65 61 76 65 4d 75 74 65 78 28 29 3b 0a 20 20  LeaveMutex();.  
3340: 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e    }.  }.  return
3350: 20 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65   (sqlite3_pcache
3360: 20 2a 29 70 43 61 63 68 65 3b 0a 7d 0a 0a 2f 2a   *)pCache;.}../*
3370: 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69  .** Implementati
3380: 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65  on of the sqlite
3390: 33 5f 70 63 61 63 68 65 2e 78 43 61 63 68 65 73  3_pcache.xCaches
33a0: 69 7a 65 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a  ize method. .**.
33b0: 2a 2a 20 43 6f 6e 66 69 67 75 72 65 20 74 68 65  ** Configure the
33c0: 20 63 61 63 68 65 5f 73 69 7a 65 20 6c 69 6d 69   cache_size limi
33d0: 74 20 66 6f 72 20 61 20 63 61 63 68 65 2e 0a 2a  t for a cache..*
33e0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63  /.static void pc
33f0: 61 63 68 65 31 43 61 63 68 65 73 69 7a 65 28 73  ache1Cachesize(s
3400: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70  qlite3_pcache *p
3410: 2c 20 69 6e 74 20 6e 4d 61 78 29 7b 0a 20 20 50  , int nMax){.  P
3420: 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d  Cache1 *pCache =
3430: 20 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20   (PCache1 *)p;. 
3440: 20 69 66 28 20 70 43 61 63 68 65 2d 3e 62 50 75   if( pCache->bPu
3450: 72 67 65 61 62 6c 65 20 29 7b 0a 20 20 20 20 70  rgeable ){.    p
3460: 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78  cache1EnterMutex
3470: 28 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e  ();.    pcache1.
3480: 6e 4d 61 78 50 61 67 65 20 2b 3d 20 28 6e 4d 61  nMaxPage += (nMa
3490: 78 20 2d 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78  x - pCache->nMax
34a0: 29 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 6e  );.    pCache->n
34b0: 4d 61 78 20 3d 20 6e 4d 61 78 3b 0a 20 20 20 20  Max = nMax;.    
34c0: 70 63 61 63 68 65 31 45 6e 66 6f 72 63 65 4d 61  pcache1EnforceMa
34d0: 78 50 61 67 65 28 29 3b 0a 20 20 20 20 70 63 61  xPage();.    pca
34e0: 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 29  che1LeaveMutex()
34f0: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49  ;.  }.}../*.** I
3500: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66  mplementation of
3510: 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61   the sqlite3_pca
3520: 63 68 65 2e 78 50 61 67 65 63 6f 75 6e 74 20 6d  che.xPagecount m
3530: 65 74 68 6f 64 2e 20 0a 2a 2f 0a 73 74 61 74 69  ethod. .*/.stati
3540: 63 20 69 6e 74 20 70 63 61 63 68 65 31 50 61 67  c int pcache1Pag
3550: 65 63 6f 75 6e 74 28 73 71 6c 69 74 65 33 5f 70  ecount(sqlite3_p
3560: 63 61 63 68 65 20 2a 70 29 7b 0a 20 20 69 6e 74  cache *p){.  int
3570: 20 6e 3b 0a 20 20 70 63 61 63 68 65 31 45 6e 74   n;.  pcache1Ent
3580: 65 72 4d 75 74 65 78 28 29 3b 0a 20 20 6e 20 3d  erMutex();.  n =
3590: 20 28 28 50 43 61 63 68 65 31 20 2a 29 70 29 2d   ((PCache1 *)p)-
35a0: 3e 6e 50 61 67 65 3b 0a 20 20 70 63 61 63 68 65  >nPage;.  pcache
35b0: 31 4c 65 61 76 65 4d 75 74 65 78 28 29 3b 0a 20  1LeaveMutex();. 
35c0: 20 72 65 74 75 72 6e 20 6e 3b 0a 7d 0a 0a 2f 2a   return n;.}../*
35d0: 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69  .** Implementati
35e0: 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65  on of the sqlite
35f0: 33 5f 70 63 61 63 68 65 2e 78 46 65 74 63 68 20  3_pcache.xFetch 
3600: 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20 46  method. .**.** F
3610: 65 74 63 68 20 61 20 70 61 67 65 20 62 79 20 6b  etch a page by k
3620: 65 79 20 76 61 6c 75 65 2e 0a 2a 2a 0a 2a 2a 20  ey value..**.** 
3630: 57 68 65 74 68 65 72 20 6f 72 20 6e 6f 74 20 61  Whether or not a
3640: 20 6e 65 77 20 70 61 67 65 20 6d 61 79 20 62 65   new page may be
3650: 20 61 6c 6c 6f 63 61 74 65 64 20 62 79 20 74 68   allocated by th
3660: 69 73 20 66 75 6e 63 74 69 6f 6e 20 64 65 70 65  is function depe
3670: 6e 64 73 20 6f 6e 0a 2a 2a 20 74 68 65 20 76 61  nds on.** the va
3680: 6c 75 65 20 6f 66 20 74 68 65 20 63 72 65 61 74  lue of the creat
3690: 65 46 6c 61 67 20 61 72 67 75 6d 65 6e 74 2e 0a  eFlag argument..
36a0: 2a 2a 0a 2a 2a 20 54 68 65 72 65 20 61 72 65 20  **.** There are 
36b0: 74 68 72 65 65 20 64 69 66 66 65 72 65 6e 74 20  three different 
36c0: 61 70 70 72 6f 61 63 68 65 73 20 74 6f 20 6f 62  approaches to ob
36d0: 74 61 69 6e 69 6e 67 20 73 70 61 63 65 20 66 6f  taining space fo
36e0: 72 20 61 20 70 61 67 65 2c 0a 2a 2a 20 64 65 70  r a page,.** dep
36f0: 65 6e 64 69 6e 67 20 6f 6e 20 74 68 65 20 76 61  ending on the va
3700: 6c 75 65 20 6f 66 20 70 61 72 61 6d 65 74 65 72  lue of parameter
3710: 20 63 72 65 61 74 65 46 6c 61 67 20 28 77 68 69   createFlag (whi
3720: 63 68 20 6d 61 79 20 62 65 20 30 2c 20 31 20 6f  ch may be 0, 1 o
3730: 72 20 32 29 2e 0a 2a 2a 0a 2a 2a 20 20 20 31 2e  r 2)..**.**   1.
3740: 20 52 65 67 61 72 64 6c 65 73 73 20 6f 66 20 74   Regardless of t
3750: 68 65 20 76 61 6c 75 65 20 6f 66 20 63 72 65 61  he value of crea
3760: 74 65 46 6c 61 67 2c 20 74 68 65 20 63 61 63 68  teFlag, the cach
3770: 65 20 69 73 20 73 65 61 72 63 68 65 64 20 66 6f  e is searched fo
3780: 72 20 61 20 0a 2a 2a 20 20 20 20 20 20 63 6f 70  r a .**      cop
3790: 79 20 6f 66 20 74 68 65 20 72 65 71 75 65 73 74  y of the request
37a0: 65 64 20 70 61 67 65 2e 20 49 66 20 6f 6e 65 20  ed page. If one 
37b0: 69 73 20 66 6f 75 6e 64 2c 20 69 74 20 69 73 20  is found, it is 
37c0: 72 65 74 75 72 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20  returned..**.** 
37d0: 20 20 32 2e 20 49 66 20 63 72 65 61 74 65 46 6c    2. If createFl
37e0: 61 67 3d 3d 30 20 61 6e 64 20 74 68 65 20 70 61  ag==0 and the pa
37f0: 67 65 20 69 73 20 6e 6f 74 20 61 6c 72 65 61 64  ge is not alread
3800: 79 20 69 6e 20 74 68 65 20 63 61 63 68 65 2c 20  y in the cache, 
3810: 4e 55 4c 4c 20 69 73 0a 2a 2a 20 20 20 20 20 20  NULL is.**      
3820: 72 65 74 75 72 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20  returned..**.** 
3830: 20 20 33 2e 20 49 66 20 63 72 65 61 74 65 46 6c    3. If createFl
3840: 61 67 20 69 73 20 31 2c 20 74 68 65 20 63 61 63  ag is 1, the cac
3850: 68 65 20 69 73 20 6d 61 72 6b 65 64 20 61 73 20  he is marked as 
3860: 70 75 72 67 65 61 62 6c 65 20 61 6e 64 20 74 68  purgeable and th
3870: 65 20 70 61 67 65 20 69 73 20 0a 2a 2a 20 20 20  e page is .**   
3880: 20 20 20 6e 6f 74 20 61 6c 72 65 61 64 79 20 69     not already i
3890: 6e 20 74 68 65 20 63 61 63 68 65 2c 20 61 6e 64  n the cache, and
38a0: 20 69 66 20 65 69 74 68 65 72 20 6f 66 20 74 68   if either of th
38b0: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 61 72 65 20  e following are 
38c0: 74 72 75 65 2c 20 0a 2a 2a 20 20 20 20 20 20 72  true, .**      r
38d0: 65 74 75 72 6e 20 4e 55 4c 4c 3a 0a 2a 2a 0a 2a  eturn NULL:.**.*
38e0: 2a 20 20 20 20 20 20 20 28 61 29 20 74 68 65 20  *       (a) the 
38f0: 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20  number of pages 
3900: 70 69 6e 6e 65 64 20 62 79 20 74 68 65 20 63 61  pinned by the ca
3910: 63 68 65 20 69 73 20 67 72 65 61 74 65 72 20 74  che is greater t
3920: 68 61 6e 0a 2a 2a 20 20 20 20 20 20 20 20 20 20  han.**          
3930: 20 50 43 61 63 68 65 31 2e 6e 4d 61 78 2c 20 6f   PCache1.nMax, o
3940: 72 0a 2a 2a 20 20 20 20 20 20 20 28 62 29 20 74  r.**       (b) t
3950: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67  he number of pag
3960: 65 73 20 70 69 6e 6e 65 64 20 62 79 20 74 68 65  es pinned by the
3970: 20 63 61 63 68 65 20 69 73 20 67 72 65 61 74 65   cache is greate
3980: 72 20 74 68 61 6e 0a 2a 2a 20 20 20 20 20 20 20  r than.**       
3990: 20 20 20 20 74 68 65 20 73 75 6d 20 6f 66 20 6e      the sum of n
39a0: 4d 61 78 20 66 6f 72 20 61 6c 6c 20 70 75 72 67  Max for all purg
39b0: 65 61 62 6c 65 20 63 61 63 68 65 73 2c 20 6c 65  eable caches, le
39c0: 73 73 20 74 68 65 20 73 75 6d 20 6f 66 20 0a 2a  ss the sum of .*
39d0: 2a 20 20 20 20 20 20 20 20 20 20 20 6e 4d 69 6e  *           nMin
39e0: 20 66 6f 72 20 61 6c 6c 20 6f 74 68 65 72 20 70   for all other p
39f0: 75 72 67 65 61 62 6c 65 20 63 61 63 68 65 73 2e  urgeable caches.
3a00: 20 0a 2a 2a 0a 2a 2a 20 20 20 34 2e 20 49 66 20   .**.**   4. If 
3a10: 6e 6f 6e 65 20 6f 66 20 74 68 65 20 66 69 72 73  none of the firs
3a20: 74 20 74 68 72 65 65 20 63 6f 6e 64 69 74 69 6f  t three conditio
3a30: 6e 73 20 61 70 70 6c 79 20 61 6e 64 20 74 68 65  ns apply and the
3a40: 20 63 61 63 68 65 20 69 73 20 6d 61 72 6b 65 64   cache is marked
3a50: 0a 2a 2a 20 20 20 20 20 20 61 73 20 70 75 72 67  .**      as purg
3a60: 65 61 62 6c 65 2c 20 61 6e 64 20 69 66 20 6f 6e  eable, and if on
3a70: 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69  e of the followi
3a80: 6e 67 20 69 73 20 74 72 75 65 3a 0a 2a 2a 0a 2a  ng is true:.**.*
3a90: 2a 20 20 20 20 20 20 20 28 61 29 20 54 68 65 20  *       (a) The 
3aa0: 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20  number of pages 
3ab0: 61 6c 6c 6f 63 61 74 65 64 20 66 6f 72 20 74 68  allocated for th
3ac0: 65 20 63 61 63 68 65 20 69 73 20 61 6c 72 65 61  e cache is alrea
3ad0: 64 79 20 0a 2a 2a 20 20 20 20 20 20 20 20 20 20  dy .**          
3ae0: 20 50 43 61 63 68 65 31 2e 6e 4d 61 78 2c 20 6f   PCache1.nMax, o
3af0: 72 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 28 62  r.**.**       (b
3b00: 29 20 54 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  ) The number of 
3b10: 70 61 67 65 73 20 61 6c 6c 6f 63 61 74 65 64 20  pages allocated 
3b20: 66 6f 72 20 61 6c 6c 20 70 75 72 67 65 61 62 6c  for all purgeabl
3b30: 65 20 63 61 63 68 65 73 20 69 73 0a 2a 2a 20 20  e caches is.**  
3b40: 20 20 20 20 20 20 20 20 20 61 6c 72 65 61 64 79           already
3b50: 20 65 71 75 61 6c 20 74 6f 20 6f 72 20 67 72 65   equal to or gre
3b60: 61 74 65 72 20 74 68 61 6e 20 74 68 65 20 73 75  ater than the su
3b70: 6d 20 6f 66 20 6e 4d 61 78 20 66 6f 72 20 61 6c  m of nMax for al
3b80: 6c 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 70  l.**           p
3b90: 75 72 67 65 61 62 6c 65 20 63 61 63 68 65 73 2c  urgeable caches,
3ba0: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 74 68 65 6e  .**.**      then
3bb0: 20 61 74 74 65 6d 70 74 20 74 6f 20 72 65 63 79   attempt to recy
3bc0: 63 6c 65 20 61 20 70 61 67 65 20 66 72 6f 6d 20  cle a page from 
3bd0: 74 68 65 20 4c 52 55 20 6c 69 73 74 2e 20 49 66  the LRU list. If
3be0: 20 69 74 20 69 73 20 74 68 65 20 72 69 67 68 74   it is the right
3bf0: 0a 2a 2a 20 20 20 20 20 20 73 69 7a 65 2c 20 72  .**      size, r
3c00: 65 74 75 72 6e 20 74 68 65 20 72 65 63 79 63 6c  eturn the recycl
3c10: 65 64 20 62 75 66 66 65 72 2e 20 4f 74 68 65 72  ed buffer. Other
3c20: 77 69 73 65 2c 20 66 72 65 65 20 74 68 65 20 62  wise, free the b
3c30: 75 66 66 65 72 20 61 6e 64 0a 2a 2a 20 20 20 20  uffer and.**    
3c40: 20 20 70 72 6f 63 65 65 64 20 74 6f 20 73 74 65    proceed to ste
3c50: 70 20 35 2e 20 0a 2a 2a 0a 2a 2a 20 20 20 35 2e  p 5. .**.**   5.
3c60: 20 4f 74 68 65 72 77 69 73 65 2c 20 61 6c 6c 6f   Otherwise, allo
3c70: 63 61 74 65 20 61 6e 64 20 72 65 74 75 72 6e 20  cate and return 
3c80: 61 20 6e 65 77 20 70 61 67 65 20 62 75 66 66 65  a new page buffe
3c90: 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  r..*/.static voi
3ca0: 64 20 2a 70 63 61 63 68 65 31 46 65 74 63 68 28  d *pcache1Fetch(
3cb0: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a  sqlite3_pcache *
3cc0: 70 2c 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  p, unsigned int 
3cd0: 69 4b 65 79 2c 20 69 6e 74 20 63 72 65 61 74 65  iKey, int create
3ce0: 46 6c 61 67 29 7b 0a 20 20 75 6e 73 69 67 6e 65  Flag){.  unsigne
3cf0: 64 20 69 6e 74 20 6e 50 69 6e 6e 65 64 3b 0a 20  d int nPinned;. 
3d00: 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68 65   PCache1 *pCache
3d10: 20 3d 20 28 50 43 61 63 68 65 31 20 2a 29 70 3b   = (PCache1 *)p;
3d20: 0a 20 20 50 67 48 64 72 31 20 2a 70 50 61 67 65  .  PgHdr1 *pPage
3d30: 20 3d 20 30 3b 0a 0a 20 20 70 63 61 63 68 65 31   = 0;..  pcache1
3d40: 45 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a 20 20  EnterMutex();.  
3d50: 69 66 28 20 63 72 65 61 74 65 46 6c 61 67 3d 3d  if( createFlag==
3d60: 31 20 29 20 73 71 6c 69 74 65 33 42 65 67 69 6e  1 ) sqlite3Begin
3d70: 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 0a  BenignMalloc();.
3d80: 0a 20 20 2f 2a 20 53 65 61 72 63 68 20 74 68 65  .  /* Search the
3d90: 20 68 61 73 68 20 74 61 62 6c 65 20 66 6f 72 20   hash table for 
3da0: 61 6e 20 65 78 69 73 74 69 6e 67 20 65 6e 74 72  an existing entr
3db0: 79 2e 20 2a 2f 0a 20 20 69 66 28 20 70 43 61 63  y. */.  if( pCac
3dc0: 68 65 2d 3e 6e 48 61 73 68 3e 30 20 29 7b 0a 20  he->nHash>0 ){. 
3dd0: 20 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20     unsigned int 
3de0: 68 20 3d 20 69 4b 65 79 20 25 20 70 43 61 63 68  h = iKey % pCach
3df0: 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 20 20 66 6f  e->nHash;.    fo
3e00: 72 28 70 50 61 67 65 3d 70 43 61 63 68 65 2d 3e  r(pPage=pCache->
3e10: 61 70 48 61 73 68 5b 68 5d 3b 20 70 50 61 67 65  apHash[h]; pPage
3e20: 26 26 70 50 61 67 65 2d 3e 69 4b 65 79 21 3d 69  &&pPage->iKey!=i
3e30: 4b 65 79 3b 20 70 50 61 67 65 3d 70 50 61 67 65  Key; pPage=pPage
3e40: 2d 3e 70 4e 65 78 74 29 3b 0a 20 20 7d 0a 0a 20  ->pNext);.  }.. 
3e50: 20 69 66 28 20 70 50 61 67 65 20 7c 7c 20 63 72   if( pPage || cr
3e60: 65 61 74 65 46 6c 61 67 3d 3d 30 20 29 7b 0a 20  eateFlag==0 ){. 
3e70: 20 20 20 70 63 61 63 68 65 31 50 69 6e 50 61 67     pcache1PinPag
3e80: 65 28 70 50 61 67 65 29 3b 0a 20 20 20 20 67 6f  e(pPage);.    go
3e90: 74 6f 20 66 65 74 63 68 5f 6f 75 74 3b 0a 20 20  to fetch_out;.  
3ea0: 7d 0a 0a 20 20 2f 2a 20 53 74 65 70 20 33 20 6f  }..  /* Step 3 o
3eb0: 66 20 68 65 61 64 65 72 20 63 6f 6d 6d 65 6e 74  f header comment
3ec0: 2e 20 2a 2f 0a 20 20 6e 50 69 6e 6e 65 64 20 3d  . */.  nPinned =
3ed0: 20 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 20 2d   pCache->nPage -
3ee0: 20 70 43 61 63 68 65 2d 3e 6e 52 65 63 79 63 6c   pCache->nRecycl
3ef0: 61 62 6c 65 3b 0a 20 20 69 66 28 20 63 72 65 61  able;.  if( crea
3f00: 74 65 46 6c 61 67 3d 3d 31 20 26 26 20 70 43 61  teFlag==1 && pCa
3f10: 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20  che->bPurgeable 
3f20: 26 26 20 28 0a 20 20 20 20 20 20 20 20 6e 50 69  && (.        nPi
3f30: 6e 6e 65 64 3e 3d 28 70 63 61 63 68 65 31 2e 6e  nned>=(pcache1.n
3f40: 4d 61 78 50 61 67 65 2b 70 43 61 63 68 65 2d 3e  MaxPage+pCache->
3f50: 6e 4d 69 6e 2d 70 63 61 63 68 65 31 2e 6e 4d 69  nMin-pcache1.nMi
3f60: 6e 50 61 67 65 29 0a 20 20 20 20 20 7c 7c 20 6e  nPage).     || n
3f70: 50 69 6e 6e 65 64 3e 3d 28 70 43 61 63 68 65 2d  Pinned>=(pCache-
3f80: 3e 6e 4d 61 78 29 0a 20 20 29 29 7b 0a 20 20 20  >nMax).  )){.   
3f90: 20 67 6f 74 6f 20 66 65 74 63 68 5f 6f 75 74 3b   goto fetch_out;
3fa0: 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 43 61 63  .  }..  if( pCac
3fb0: 68 65 2d 3e 6e 50 61 67 65 3e 3d 70 43 61 63 68  he->nPage>=pCach
3fc0: 65 2d 3e 6e 48 61 73 68 20 26 26 20 70 63 61 63  e->nHash && pcac
3fd0: 68 65 31 52 65 73 69 7a 65 48 61 73 68 28 70 43  he1ResizeHash(pC
3fe0: 61 63 68 65 29 20 29 7b 0a 20 20 20 20 67 6f 74  ache) ){.    got
3ff0: 6f 20 66 65 74 63 68 5f 6f 75 74 3b 0a 20 20 7d  o fetch_out;.  }
4000: 0a 0a 20 20 2f 2a 20 53 74 65 70 20 34 2e 20 54  ..  /* Step 4. T
4010: 72 79 20 74 6f 20 72 65 63 79 63 6c 65 20 61 20  ry to recycle a 
4020: 70 61 67 65 20 62 75 66 66 65 72 20 69 66 20 61  page buffer if a
4030: 70 70 72 6f 70 72 69 61 74 65 2e 20 2a 2f 0a 20  ppropriate. */. 
4040: 20 69 66 28 20 70 43 61 63 68 65 2d 3e 62 50 75   if( pCache->bPu
4050: 72 67 65 61 62 6c 65 20 26 26 20 70 63 61 63 68  rgeable && pcach
4060: 65 31 2e 70 4c 72 75 54 61 69 6c 20 26 26 20 28  e1.pLruTail && (
4070: 0a 20 20 20 20 20 20 70 43 61 63 68 65 2d 3e 6e  .      pCache->n
4080: 50 61 67 65 3e 3d 70 43 61 63 68 65 2d 3e 6e 4d  Page>=pCache->nM
4090: 61 78 2d 31 20 7c 7c 20 70 63 61 63 68 65 31 2e  ax-1 || pcache1.
40a0: 6e 43 75 72 72 65 6e 74 50 61 67 65 3e 3d 70 63  nCurrentPage>=pc
40b0: 61 63 68 65 31 2e 6e 4d 61 78 50 61 67 65 0a 20  ache1.nMaxPage. 
40c0: 20 29 29 7b 0a 20 20 20 20 70 50 61 67 65 20 3d   )){.    pPage =
40d0: 20 70 63 61 63 68 65 31 2e 70 4c 72 75 54 61 69   pcache1.pLruTai
40e0: 6c 3b 0a 20 20 20 20 70 63 61 63 68 65 31 52 65  l;.    pcache1Re
40f0: 6d 6f 76 65 46 72 6f 6d 48 61 73 68 28 70 50 61  moveFromHash(pPa
4100: 67 65 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31  ge);.    pcache1
4110: 50 69 6e 50 61 67 65 28 70 50 61 67 65 29 3b 0a  PinPage(pPage);.
4120: 20 20 20 20 69 66 28 20 70 50 61 67 65 2d 3e 70      if( pPage->p
4130: 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 21 3d 70  Cache->szPage!=p
4140: 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 20 29 7b  Cache->szPage ){
4150: 0a 20 20 20 20 20 20 70 63 61 63 68 65 31 46 72  .      pcache1Fr
4160: 65 65 50 61 67 65 28 70 50 61 67 65 29 3b 0a 20  eePage(pPage);. 
4170: 20 20 20 20 20 70 50 61 67 65 20 3d 20 30 3b 0a       pPage = 0;.
4180: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
4190: 20 70 63 61 63 68 65 31 2e 6e 43 75 72 72 65 6e   pcache1.nCurren
41a0: 74 50 61 67 65 20 2d 3d 20 28 70 50 61 67 65 2d  tPage -= (pPage-
41b0: 3e 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61  >pCache->bPurgea
41c0: 62 6c 65 20 2d 20 70 43 61 63 68 65 2d 3e 62 50  ble - pCache->bP
41d0: 75 72 67 65 61 62 6c 65 29 3b 0a 20 20 20 20 7d  urgeable);.    }
41e0: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53 74 65 70 20  .  }..  /* Step 
41f0: 35 2e 20 49 66 20 61 20 75 73 61 62 6c 65 20 70  5. If a usable p
4200: 61 67 65 20 62 75 66 66 65 72 20 68 61 73 20 73  age buffer has s
4210: 74 69 6c 6c 20 6e 6f 74 20 62 65 65 6e 20 66 6f  till not been fo
4220: 75 6e 64 2c 20 0a 20 20 2a 2a 20 61 74 74 65 6d  und, .  ** attem
4230: 70 74 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 61  pt to allocate a
4240: 20 6e 65 77 20 6f 6e 65 2e 20 0a 20 20 2a 2f 0a   new one. .  */.
4250: 20 20 69 66 28 20 21 70 50 61 67 65 20 29 7b 0a    if( !pPage ){.
4260: 20 20 20 20 70 50 61 67 65 20 3d 20 70 63 61 63      pPage = pcac
4270: 68 65 31 41 6c 6c 6f 63 50 61 67 65 28 70 43 61  he1AllocPage(pCa
4280: 63 68 65 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28  che);.  }..  if(
4290: 20 70 50 61 67 65 20 29 7b 0a 20 20 20 20 75 6e   pPage ){.    un
42a0: 73 69 67 6e 65 64 20 69 6e 74 20 68 20 3d 20 69  signed int h = i
42b0: 4b 65 79 20 25 20 70 43 61 63 68 65 2d 3e 6e 48  Key % pCache->nH
42c0: 61 73 68 3b 0a 20 20 20 20 6d 65 6d 73 65 74 28  ash;.    memset(
42d0: 70 50 61 67 65 2c 20 30 2c 20 70 43 61 63 68 65  pPage, 0, pCache
42e0: 2d 3e 73 7a 50 61 67 65 20 2b 20 73 69 7a 65 6f  ->szPage + sizeo
42f0: 66 28 50 67 48 64 72 31 29 29 3b 0a 20 20 20 20  f(PgHdr1));.    
4300: 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 2b 2b 3b  pCache->nPage++;
4310: 0a 20 20 20 20 70 50 61 67 65 2d 3e 69 4b 65 79  .    pPage->iKey
4320: 20 3d 20 69 4b 65 79 3b 0a 20 20 20 20 70 50 61   = iKey;.    pPa
4330: 67 65 2d 3e 70 4e 65 78 74 20 3d 20 70 43 61 63  ge->pNext = pCac
4340: 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 0a 20  he->apHash[h];. 
4350: 20 20 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65     pPage->pCache
4360: 20 3d 20 70 43 61 63 68 65 3b 0a 20 20 20 20 70   = pCache;.    p
4370: 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d  Cache->apHash[h]
4380: 20 3d 20 70 50 61 67 65 3b 0a 20 20 7d 0a 0a 66   = pPage;.  }..f
4390: 65 74 63 68 5f 6f 75 74 3a 0a 20 20 69 66 28 20  etch_out:.  if( 
43a0: 63 72 65 61 74 65 46 6c 61 67 3d 3d 31 20 29 20  createFlag==1 ) 
43b0: 73 71 6c 69 74 65 33 45 6e 64 42 65 6e 69 67 6e  sqlite3EndBenign
43c0: 4d 61 6c 6c 6f 63 28 29 3b 0a 20 20 70 63 61 63  Malloc();.  pcac
43d0: 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 29 3b  he1LeaveMutex();
43e0: 0a 20 20 72 65 74 75 72 6e 20 28 70 50 61 67 65  .  return (pPage
43f0: 20 3f 20 50 47 48 44 52 31 5f 54 4f 5f 50 41 47   ? PGHDR1_TO_PAG
4400: 45 28 70 50 61 67 65 29 20 3a 20 30 29 3b 0a 7d  E(pPage) : 0);.}
4410: 0a 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65  .../*.** Impleme
4420: 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73  ntation of the s
4430: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78 55  qlite3_pcache.xU
4440: 6e 70 69 6e 20 6d 65 74 68 6f 64 2e 0a 2a 2a 0a  npin method..**.
4450: 2a 2a 20 4d 61 72 6b 20 61 20 70 61 67 65 20 61  ** Mark a page a
4460: 73 20 75 6e 70 69 6e 6e 65 64 20 28 65 6c 69 67  s unpinned (elig
4470: 69 62 6c 65 20 66 6f 72 20 61 73 79 6e 63 68 72  ible for asynchr
4480: 6f 6e 6f 75 73 20 72 65 63 79 63 6c 69 6e 67 29  onous recycling)
4490: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
44a0: 20 70 63 61 63 68 65 31 55 6e 70 69 6e 28 73 71   pcache1Unpin(sq
44b0: 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70 2c  lite3_pcache *p,
44c0: 20 76 6f 69 64 20 2a 70 50 67 2c 20 69 6e 74 20   void *pPg, int 
44d0: 72 65 75 73 65 55 6e 6c 69 6b 65 6c 79 29 7b 0a  reuseUnlikely){.
44e0: 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68    PCache1 *pCach
44f0: 65 20 3d 20 28 50 43 61 63 68 65 31 20 2a 29 70  e = (PCache1 *)p
4500: 3b 0a 20 20 50 67 48 64 72 31 20 2a 70 50 61 67  ;.  PgHdr1 *pPag
4510: 65 20 3d 20 50 41 47 45 5f 54 4f 5f 50 47 48 44  e = PAGE_TO_PGHD
4520: 52 31 28 70 50 67 29 3b 0a 0a 20 20 70 63 61 63  R1(pPg);..  pcac
4530: 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 29 3b  he1EnterMutex();
4540: 0a 0a 20 20 2f 2a 20 49 74 20 69 73 20 61 6e 20  ..  /* It is an 
4550: 65 72 72 6f 72 20 74 6f 20 63 61 6c 6c 20 74 68  error to call th
4560: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 66 20 74  is function if t
4570: 68 65 20 70 61 67 65 20 69 73 20 61 6c 72 65 61  he page is alrea
4580: 64 79 20 0a 20 20 2a 2a 20 70 61 72 74 20 6f 66  dy .  ** part of
4590: 20 74 68 65 20 67 6c 6f 62 61 6c 20 4c 52 55 20   the global LRU 
45a0: 6c 69 73 74 2e 0a 20 20 2a 2f 0a 20 20 61 73 73  list..  */.  ass
45b0: 65 72 74 28 20 70 50 61 67 65 2d 3e 70 4c 72 75  ert( pPage->pLru
45c0: 50 72 65 76 3d 3d 30 20 26 26 20 70 50 61 67 65  Prev==0 && pPage
45d0: 2d 3e 70 4c 72 75 4e 65 78 74 3d 3d 30 20 29 3b  ->pLruNext==0 );
45e0: 0a 20 20 61 73 73 65 72 74 28 20 70 63 61 63 68  .  assert( pcach
45f0: 65 31 2e 70 4c 72 75 48 65 61 64 21 3d 70 50 61  e1.pLruHead!=pPa
4600: 67 65 20 26 26 20 70 63 61 63 68 65 31 2e 70 4c  ge && pcache1.pL
4610: 72 75 54 61 69 6c 21 3d 70 50 61 67 65 20 29 3b  ruTail!=pPage );
4620: 0a 0a 20 20 69 66 28 20 72 65 75 73 65 55 6e 6c  ..  if( reuseUnl
4630: 69 6b 65 6c 79 20 7c 7c 20 70 63 61 63 68 65 31  ikely || pcache1
4640: 2e 6e 43 75 72 72 65 6e 74 50 61 67 65 3e 70 63  .nCurrentPage>pc
4650: 61 63 68 65 31 2e 6e 4d 61 78 50 61 67 65 20 29  ache1.nMaxPage )
4660: 7b 0a 20 20 20 20 70 63 61 63 68 65 31 52 65 6d  {.    pcache1Rem
4670: 6f 76 65 46 72 6f 6d 48 61 73 68 28 70 50 61 67  oveFromHash(pPag
4680: 65 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31 46  e);.    pcache1F
4690: 72 65 65 50 61 67 65 28 70 50 61 67 65 29 3b 0a  reePage(pPage);.
46a0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 2f 2a 20    }else{.    /* 
46b0: 41 64 64 20 74 68 65 20 70 61 67 65 20 74 6f 20  Add the page to 
46c0: 74 68 65 20 67 6c 6f 62 61 6c 20 4c 52 55 20 6c  the global LRU l
46d0: 69 73 74 2e 20 4e 6f 72 6d 61 6c 6c 79 2c 20 74  ist. Normally, t
46e0: 68 65 20 70 61 67 65 20 69 73 20 61 64 64 65 64  he page is added
46f0: 20 74 6f 0a 20 20 20 20 2a 2a 20 74 68 65 20 68   to.    ** the h
4700: 65 61 64 20 6f 66 20 74 68 65 20 6c 69 73 74 20  ead of the list 
4710: 28 6c 61 73 74 20 70 61 67 65 20 74 6f 20 62 65  (last page to be
4720: 20 72 65 63 79 63 6c 65 64 29 2e 20 48 6f 77 65   recycled). Howe
4730: 76 65 72 2c 20 69 66 20 74 68 65 20 0a 20 20 20  ver, if the .   
4740: 20 2a 2a 20 72 65 75 73 65 55 6e 6c 69 6b 65 6c   ** reuseUnlikel
4750: 79 20 66 6c 61 67 20 70 61 73 73 65 64 20 74 6f  y flag passed to
4760: 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   this function i
4770: 73 20 74 72 75 65 2c 20 74 68 65 20 70 61 67 65  s true, the page
4780: 20 69 73 20 61 64 64 65 64 0a 20 20 20 20 2a 2a   is added.    **
4790: 20 74 6f 20 74 68 65 20 74 61 69 6c 20 6f 66 20   to the tail of 
47a0: 74 68 65 20 6c 69 73 74 20 28 66 69 72 73 74 20  the list (first 
47b0: 70 61 67 65 20 74 6f 20 62 65 20 72 65 63 79 63  page to be recyc
47c0: 6c 65 64 29 2e 0a 20 20 20 20 2a 2f 0a 20 20 20  led)..    */.   
47d0: 20 69 66 28 20 70 63 61 63 68 65 31 2e 70 4c 72   if( pcache1.pLr
47e0: 75 48 65 61 64 20 29 7b 0a 20 20 20 20 20 20 70  uHead ){.      p
47f0: 63 61 63 68 65 31 2e 70 4c 72 75 48 65 61 64 2d  cache1.pLruHead-
4800: 3e 70 4c 72 75 50 72 65 76 20 3d 20 70 50 61 67  >pLruPrev = pPag
4810: 65 3b 0a 20 20 20 20 20 20 70 50 61 67 65 2d 3e  e;.      pPage->
4820: 70 4c 72 75 4e 65 78 74 20 3d 20 70 63 61 63 68  pLruNext = pcach
4830: 65 31 2e 70 4c 72 75 48 65 61 64 3b 0a 20 20 20  e1.pLruHead;.   
4840: 20 20 20 70 63 61 63 68 65 31 2e 70 4c 72 75 48     pcache1.pLruH
4850: 65 61 64 20 3d 20 70 50 61 67 65 3b 0a 20 20 20  ead = pPage;.   
4860: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 63   }else{.      pc
4870: 61 63 68 65 31 2e 70 4c 72 75 54 61 69 6c 20 3d  ache1.pLruTail =
4880: 20 70 50 61 67 65 3b 0a 20 20 20 20 20 20 70 63   pPage;.      pc
4890: 61 63 68 65 31 2e 70 4c 72 75 48 65 61 64 20 3d  ache1.pLruHead =
48a0: 20 70 50 61 67 65 3b 0a 20 20 20 20 7d 0a 20 20   pPage;.    }.  
48b0: 20 20 70 43 61 63 68 65 2d 3e 6e 52 65 63 79 63    pCache->nRecyc
48c0: 6c 61 62 6c 65 2b 2b 3b 0a 20 20 7d 0a 0a 20 20  lable++;.  }..  
48d0: 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65  pcache1LeaveMute
48e0: 78 28 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d  x();.}../*.** Im
48f0: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20  plementation of 
4900: 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63  the sqlite3_pcac
4910: 68 65 2e 78 52 65 6b 65 79 20 6d 65 74 68 6f 64  he.xRekey method
4920: 2e 20 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  . .*/.static voi
4930: 64 20 70 63 61 63 68 65 31 52 65 6b 65 79 28 0a  d pcache1Rekey(.
4940: 20 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65    sqlite3_pcache
4950: 20 2a 70 2c 0a 20 20 76 6f 69 64 20 2a 70 50 67   *p,.  void *pPg
4960: 2c 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74  ,.  unsigned int
4970: 20 69 4f 6c 64 2c 0a 20 20 75 6e 73 69 67 6e 65   iOld,.  unsigne
4980: 64 20 69 6e 74 20 69 4e 65 77 0a 29 7b 0a 20 20  d int iNew.){.  
4990: 50 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 20  PCache1 *pCache 
49a0: 3d 20 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a  = (PCache1 *)p;.
49b0: 20 20 50 67 48 64 72 31 20 2a 70 50 61 67 65 20    PgHdr1 *pPage 
49c0: 3d 20 50 41 47 45 5f 54 4f 5f 50 47 48 44 52 31  = PAGE_TO_PGHDR1
49d0: 28 70 50 67 29 3b 0a 20 20 50 67 48 64 72 31 20  (pPg);.  PgHdr1 
49e0: 2a 2a 70 70 3b 0a 20 20 75 6e 73 69 67 6e 65 64  **pp;.  unsigned
49f0: 20 69 6e 74 20 68 3b 20 0a 20 20 61 73 73 65 72   int h; .  asser
4a00: 74 28 20 70 50 61 67 65 2d 3e 69 4b 65 79 3d 3d  t( pPage->iKey==
4a10: 69 4f 6c 64 20 29 3b 0a 0a 20 20 70 63 61 63 68  iOld );..  pcach
4a20: 65 31 45 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a  e1EnterMutex();.
4a30: 0a 20 20 68 20 3d 20 69 4f 6c 64 25 70 43 61 63  .  h = iOld%pCac
4a40: 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 70 70 20  he->nHash;.  pp 
4a50: 3d 20 26 70 43 61 63 68 65 2d 3e 61 70 48 61 73  = &pCache->apHas
4a60: 68 5b 68 5d 3b 0a 20 20 77 68 69 6c 65 28 20 28  h[h];.  while( (
4a70: 2a 70 70 29 21 3d 70 50 61 67 65 20 29 7b 0a 20  *pp)!=pPage ){. 
4a80: 20 20 20 70 70 20 3d 20 26 28 2a 70 70 29 2d 3e     pp = &(*pp)->
4a90: 70 4e 65 78 74 3b 0a 20 20 7d 0a 20 20 2a 70 70  pNext;.  }.  *pp
4aa0: 20 3d 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 3b   = pPage->pNext;
4ab0: 0a 0a 20 20 68 20 3d 20 69 4e 65 77 25 70 43 61  ..  h = iNew%pCa
4ac0: 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 70 50  che->nHash;.  pP
4ad0: 61 67 65 2d 3e 69 4b 65 79 20 3d 20 69 4e 65 77  age->iKey = iNew
4ae0: 3b 0a 20 20 70 50 61 67 65 2d 3e 70 4e 65 78 74  ;.  pPage->pNext
4af0: 20 3d 20 70 43 61 63 68 65 2d 3e 61 70 48 61 73   = pCache->apHas
4b00: 68 5b 68 5d 3b 0a 20 20 70 43 61 63 68 65 2d 3e  h[h];.  pCache->
4b10: 61 70 48 61 73 68 5b 68 5d 20 3d 20 70 50 61 67  apHash[h] = pPag
4b20: 65 3b 0a 0a 20 20 70 63 61 63 68 65 31 4c 65 61  e;..  pcache1Lea
4b30: 76 65 4d 75 74 65 78 28 29 3b 0a 7d 0a 0a 2f 2a  veMutex();.}../*
4b40: 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69  .** Implementati
4b50: 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65  on of the sqlite
4b60: 33 5f 70 63 61 63 68 65 2e 78 54 72 75 6e 63 61  3_pcache.xTrunca
4b70: 74 65 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a  te method. .**.*
4b80: 2a 20 44 69 73 63 61 72 64 20 61 6c 6c 20 75 6e  * Discard all un
4b90: 70 69 6e 6e 65 64 20 70 61 67 65 73 20 69 6e 20  pinned pages in 
4ba0: 74 68 65 20 63 61 63 68 65 20 77 69 74 68 20 61  the cache with a
4bb0: 20 70 61 67 65 20 6e 75 6d 62 65 72 20 65 71 75   page number equ
4bc0: 61 6c 20 74 6f 0a 2a 2a 20 6f 72 20 67 72 65 61  al to.** or grea
4bd0: 74 65 72 20 74 68 61 6e 20 70 61 72 61 6d 65 74  ter than paramet
4be0: 65 72 20 69 4c 69 6d 69 74 2e 20 41 6e 79 20 70  er iLimit. Any p
4bf0: 69 6e 6e 65 64 20 70 61 67 65 73 20 77 69 74 68  inned pages with
4c00: 20 61 20 70 61 67 65 20 6e 75 6d 62 65 72 0a 2a   a page number.*
4c10: 2a 20 65 71 75 61 6c 20 74 6f 20 6f 72 20 67 72  * equal to or gr
4c20: 65 61 74 65 72 20 74 68 61 6e 20 69 4c 69 6d 69  eater than iLimi
4c30: 74 20 61 72 65 20 69 6d 70 6c 69 63 69 74 6c 79  t are implicitly
4c40: 20 75 6e 70 69 6e 6e 65 64 2e 0a 2a 2f 0a 73 74   unpinned..*/.st
4c50: 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65  atic void pcache
4c60: 31 54 72 75 6e 63 61 74 65 28 73 71 6c 69 74 65  1Truncate(sqlite
4c70: 33 5f 70 63 61 63 68 65 20 2a 70 2c 20 75 6e 73  3_pcache *p, uns
4c80: 69 67 6e 65 64 20 69 6e 74 20 69 4c 69 6d 69 74  igned int iLimit
4c90: 29 7b 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43  ){.  PCache1 *pC
4ca0: 61 63 68 65 20 3d 20 28 50 43 61 63 68 65 31 20  ache = (PCache1 
4cb0: 2a 29 70 3b 0a 20 20 70 63 61 63 68 65 31 45 6e  *)p;.  pcache1En
4cc0: 74 65 72 4d 75 74 65 78 28 29 3b 0a 20 20 70 63  terMutex();.  pc
4cd0: 61 63 68 65 31 54 72 75 6e 63 61 74 65 55 6e 73  ache1TruncateUns
4ce0: 61 66 65 28 70 43 61 63 68 65 2c 20 69 4c 69 6d  afe(pCache, iLim
4cf0: 69 74 29 3b 0a 20 20 70 63 61 63 68 65 31 4c 65  it);.  pcache1Le
4d00: 61 76 65 4d 75 74 65 78 28 29 3b 0a 7d 0a 0a 2f  aveMutex();.}../
4d10: 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74  *.** Implementat
4d20: 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74  ion of the sqlit
4d30: 65 33 5f 70 63 61 63 68 65 2e 78 44 65 73 74 72  e3_pcache.xDestr
4d40: 6f 79 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a  oy method. .**.*
4d50: 2a 20 44 65 73 74 72 6f 79 20 61 20 63 61 63 68  * Destroy a cach
4d60: 65 20 61 6c 6c 6f 63 61 74 65 64 20 75 73 69 6e  e allocated usin
4d70: 67 20 70 63 61 63 68 65 31 43 72 65 61 74 65 28  g pcache1Create(
4d80: 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  )..*/.static voi
4d90: 64 20 70 63 61 63 68 65 31 44 65 73 74 72 6f 79  d pcache1Destroy
4da0: 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20  (sqlite3_pcache 
4db0: 2a 70 29 7b 0a 20 20 50 43 61 63 68 65 31 20 2a  *p){.  PCache1 *
4dc0: 70 43 61 63 68 65 20 3d 20 28 50 43 61 63 68 65  pCache = (PCache
4dd0: 31 20 2a 29 70 3b 0a 20 20 70 63 61 63 68 65 31  1 *)p;.  pcache1
4de0: 45 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a 20 20  EnterMutex();.  
4df0: 70 63 61 63 68 65 31 54 72 75 6e 63 61 74 65 55  pcache1TruncateU
4e00: 6e 73 61 66 65 28 70 43 61 63 68 65 2c 20 30 29  nsafe(pCache, 0)
4e10: 3b 0a 20 20 70 63 61 63 68 65 31 2e 6e 4d 61 78  ;.  pcache1.nMax
4e20: 50 61 67 65 20 2d 3d 20 70 43 61 63 68 65 2d 3e  Page -= pCache->
4e30: 6e 4d 61 78 3b 0a 20 20 70 63 61 63 68 65 31 2e  nMax;.  pcache1.
4e40: 6e 4d 69 6e 50 61 67 65 20 2d 3d 20 70 43 61 63  nMinPage -= pCac
4e50: 68 65 2d 3e 6e 4d 69 6e 3b 0a 20 20 70 63 61 63  he->nMin;.  pcac
4e60: 68 65 31 45 6e 66 6f 72 63 65 4d 61 78 50 61 67  he1EnforceMaxPag
4e70: 65 28 29 3b 0a 20 20 70 63 61 63 68 65 31 4c 65  e();.  pcache1Le
4e80: 61 76 65 4d 75 74 65 78 28 29 3b 0a 20 20 73 71  aveMutex();.  sq
4e90: 6c 69 74 65 33 5f 66 72 65 65 28 70 43 61 63 68  lite3_free(pCach
4ea0: 65 2d 3e 61 70 48 61 73 68 29 3b 0a 20 20 73 71  e->apHash);.  sq
4eb0: 6c 69 74 65 33 5f 66 72 65 65 28 70 43 61 63 68  lite3_free(pCach
4ec0: 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69  e);.}../*.** Thi
4ed0: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61  s function is ca
4ee0: 6c 6c 65 64 20 64 75 72 69 6e 67 20 69 6e 69 74  lled during init
4ef0: 69 61 6c 69 7a 61 74 69 6f 6e 20 28 73 71 6c 69  ialization (sqli
4f00: 74 65 33 5f 69 6e 69 74 69 61 6c 69 7a 65 28 29  te3_initialize()
4f10: 29 20 74 6f 0a 2a 2a 20 69 6e 73 74 61 6c 6c 20  ) to.** install 
4f20: 74 68 65 20 64 65 66 61 75 6c 74 20 70 6c 75 67  the default plug
4f30: 67 61 62 6c 65 20 63 61 63 68 65 20 6d 6f 64 75  gable cache modu
4f40: 6c 65 2c 20 61 73 73 75 6d 69 6e 67 20 74 68 65  le, assuming the
4f50: 20 75 73 65 72 20 68 61 73 20 6e 6f 74 0a 2a 2a   user has not.**
4f60: 20 61 6c 72 65 61 64 79 20 70 72 6f 76 69 64 65   already provide
4f70: 64 20 61 6e 20 61 6c 74 65 72 6e 61 74 69 76 65  d an alternative
4f80: 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
4f90: 33 50 43 61 63 68 65 53 65 74 44 65 66 61 75 6c  3PCacheSetDefaul
4fa0: 74 28 76 6f 69 64 29 7b 0a 20 20 73 74 61 74 69  t(void){.  stati
4fb0: 63 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  c sqlite3_pcache
4fc0: 5f 6d 65 74 68 6f 64 73 20 64 65 66 61 75 6c 74  _methods default
4fd0: 4d 65 74 68 6f 64 73 20 3d 20 7b 0a 20 20 20 20  Methods = {.    
4fe0: 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0,              
4ff0: 20 20 20 20 20 20 20 20 20 2f 2a 20 70 41 72 67           /* pArg
5000: 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31 49   */.    pcache1I
5010: 6e 69 74 2c 20 20 20 20 20 20 20 20 20 20 20 20  nit,            
5020: 20 2f 2a 20 78 49 6e 69 74 20 2a 2f 0a 20 20 20   /* xInit */.   
5030: 20 70 63 61 63 68 65 31 53 68 75 74 64 6f 77 6e   pcache1Shutdown
5040: 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 78 53 68  ,         /* xSh
5050: 75 74 64 6f 77 6e 20 2a 2f 0a 20 20 20 20 70 63  utdown */.    pc
5060: 61 63 68 65 31 43 72 65 61 74 65 2c 20 20 20 20  ache1Create,    
5070: 20 20 20 20 20 20 20 2f 2a 20 78 43 72 65 61 74         /* xCreat
5080: 65 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31  e */.    pcache1
5090: 43 61 63 68 65 73 69 7a 65 2c 20 20 20 20 20 20  Cachesize,      
50a0: 20 20 2f 2a 20 78 43 61 63 68 65 73 69 7a 65 20    /* xCachesize 
50b0: 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31 50 61  */.    pcache1Pa
50c0: 67 65 63 6f 75 6e 74 2c 20 20 20 20 20 20 20 20  gecount,        
50d0: 2f 2a 20 78 50 61 67 65 63 6f 75 6e 74 20 2a 2f  /* xPagecount */
50e0: 0a 20 20 20 20 70 63 61 63 68 65 31 46 65 74 63  .    pcache1Fetc
50f0: 68 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  h,            /*
5100: 20 78 46 65 74 63 68 20 2a 2f 0a 20 20 20 20 70   xFetch */.    p
5110: 63 61 63 68 65 31 55 6e 70 69 6e 2c 20 20 20 20  cache1Unpin,    
5120: 20 20 20 20 20 20 20 20 2f 2a 20 78 55 6e 70 69          /* xUnpi
5130: 6e 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31  n */.    pcache1
5140: 52 65 6b 65 79 2c 20 20 20 20 20 20 20 20 20 20  Rekey,          
5150: 20 20 2f 2a 20 78 52 65 6b 65 79 20 2a 2f 0a 20    /* xRekey */. 
5160: 20 20 20 70 63 61 63 68 65 31 54 72 75 6e 63 61     pcache1Trunca
5170: 74 65 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 78  te,         /* x
5180: 54 72 75 6e 63 61 74 65 20 2a 2f 0a 20 20 20 20  Truncate */.    
5190: 70 63 61 63 68 65 31 44 65 73 74 72 6f 79 20 20  pcache1Destroy  
51a0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 65 73           /* xDes
51b0: 74 72 6f 79 20 2a 2f 0a 20 20 7d 3b 0a 20 20 73  troy */.  };.  s
51c0: 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67 28 53 51  qlite3_config(SQ
51d0: 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 43 41 43  LITE_CONFIG_PCAC
51e0: 48 45 2c 20 26 64 65 66 61 75 6c 74 4d 65 74 68  HE, &defaultMeth
51f0: 6f 64 73 29 3b 0a 7d 0a 0a 23 69 66 64 65 66 20  ods);.}..#ifdef 
5200: 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45  SQLITE_ENABLE_ME
5210: 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 0a  MORY_MANAGEMENT.
5220: 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  /*.** This funct
5230: 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 74 6f  ion is called to
5240: 20 66 72 65 65 20 73 75 70 65 72 66 6c 75 6f 75   free superfluou
5250: 73 20 64 79 6e 61 6d 69 63 61 6c 6c 79 20 61 6c  s dynamically al
5260: 6c 6f 63 61 74 65 64 20 6d 65 6d 6f 72 79 0a 2a  located memory.*
5270: 2a 20 68 65 6c 64 20 62 79 20 74 68 65 20 70 61  * held by the pa
5280: 67 65 72 20 73 79 73 74 65 6d 2e 20 4d 65 6d 6f  ger system. Memo
5290: 72 79 20 69 6e 20 75 73 65 20 62 79 20 61 6e 79  ry in use by any
52a0: 20 53 51 4c 69 74 65 20 70 61 67 65 72 20 61 6c   SQLite pager al
52b0: 6c 6f 63 61 74 65 64 0a 2a 2a 20 62 79 20 74 68  located.** by th
52c0: 65 20 63 75 72 72 65 6e 74 20 74 68 72 65 61 64  e current thread
52d0: 20 6d 61 79 20 62 65 20 73 71 6c 69 74 65 33 5f   may be sqlite3_
52e0: 66 72 65 65 28 29 65 64 2e 0a 2a 2a 0a 2a 2a 20  free()ed..**.** 
52f0: 6e 52 65 71 20 69 73 20 74 68 65 20 6e 75 6d 62  nReq is the numb
5300: 65 72 20 6f 66 20 62 79 74 65 73 20 6f 66 20 6d  er of bytes of m
5310: 65 6d 6f 72 79 20 72 65 71 75 69 72 65 64 2e 20  emory required. 
5320: 4f 6e 63 65 20 74 68 69 73 20 6d 75 63 68 20 68  Once this much h
5330: 61 73 0a 2a 2a 20 62 65 65 6e 20 72 65 6c 65 61  as.** been relea
5340: 73 65 64 2c 20 74 68 65 20 66 75 6e 63 74 69 6f  sed, the functio
5350: 6e 20 72 65 74 75 72 6e 73 2e 20 54 68 65 20 72  n returns. The r
5360: 65 74 75 72 6e 20 76 61 6c 75 65 20 69 73 20 74  eturn value is t
5370: 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20  he total number 
5380: 0a 2a 2a 20 6f 66 20 62 79 74 65 73 20 6f 66 20  .** of bytes of 
5390: 6d 65 6d 6f 72 79 20 72 65 6c 65 61 73 65 64 2e  memory released.
53a0: 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 50  .*/.int sqlite3P
53b0: 63 61 63 68 65 52 65 6c 65 61 73 65 4d 65 6d 6f  cacheReleaseMemo
53c0: 72 79 28 69 6e 74 20 6e 52 65 71 29 7b 0a 20 20  ry(int nReq){.  
53d0: 69 6e 74 20 6e 46 72 65 65 20 3d 20 30 3b 0a 20  int nFree = 0;. 
53e0: 20 69 66 28 20 70 63 61 63 68 65 31 2e 70 53 74   if( pcache1.pSt
53f0: 61 72 74 3d 3d 30 20 29 7b 0a 20 20 20 20 50 67  art==0 ){.    Pg
5400: 48 64 72 31 20 2a 70 3b 0a 20 20 20 20 70 63 61  Hdr1 *p;.    pca
5410: 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 29  che1EnterMutex()
5420: 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 28 6e 52  ;.    while( (nR
5430: 65 71 3c 30 20 7c 7c 20 6e 46 72 65 65 3c 6e 52  eq<0 || nFree<nR
5440: 65 71 29 20 26 26 20 28 70 3d 70 63 61 63 68 65  eq) && (p=pcache
5450: 31 2e 70 4c 72 75 54 61 69 6c 29 20 29 7b 0a 20  1.pLruTail) ){. 
5460: 20 20 20 20 20 6e 46 72 65 65 20 2b 3d 20 73 71       nFree += sq
5470: 6c 69 74 65 33 4d 61 6c 6c 6f 63 53 69 7a 65 28  lite3MallocSize(
5480: 70 29 3b 0a 20 20 20 20 20 20 70 63 61 63 68 65  p);.      pcache
5490: 31 50 69 6e 50 61 67 65 28 70 29 3b 0a 20 20 20  1PinPage(p);.   
54a0: 20 20 20 70 63 61 63 68 65 31 52 65 6d 6f 76 65     pcache1Remove
54b0: 46 72 6f 6d 48 61 73 68 28 70 29 3b 0a 20 20 20  FromHash(p);.   
54c0: 20 20 20 70 63 61 63 68 65 31 46 72 65 65 50 61     pcache1FreePa
54d0: 67 65 28 70 29 3b 0a 20 20 20 20 7d 0a 20 20 20  ge(p);.    }.   
54e0: 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74   pcache1LeaveMut
54f0: 65 78 28 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75  ex();.  }.  retu
5500: 72 6e 20 6e 46 72 65 65 3b 0a 7d 0a 23 65 6e 64  rn nFree;.}.#end
5510: 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f 45 4e 41  if /* SQLITE_ENA
5520: 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47  BLE_MEMORY_MANAG
5530: 45 4d 45 4e 54 20 2a 2f 0a 0a 23 69 66 64 65 66  EMENT */..#ifdef
5540: 20 53 51 4c 49 54 45 5f 54 45 53 54 0a 2f 2a 0a   SQLITE_TEST./*.
5550: 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
5560: 20 69 73 20 75 73 65 64 20 62 79 20 74 65 73 74   is used by test
5570: 20 70 72 6f 63 65 64 75 72 65 73 20 74 6f 20 69   procedures to i
5580: 6e 73 70 65 63 74 20 74 68 65 20 69 6e 74 65 72  nspect the inter
5590: 6e 61 6c 20 73 74 61 74 65 0a 2a 2a 20 6f 66 20  nal state.** of 
55a0: 74 68 65 20 67 6c 6f 62 61 6c 20 63 61 63 68 65  the global cache
55b0: 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
55c0: 33 50 63 61 63 68 65 53 74 61 74 73 28 0a 20 20  3PcacheStats(.  
55d0: 69 6e 74 20 2a 70 6e 43 75 72 72 65 6e 74 2c 20  int *pnCurrent, 
55e0: 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 54 6f 74       /* OUT: Tot
55f0: 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67  al number of pag
5600: 65 73 20 63 61 63 68 65 64 20 2a 2f 0a 20 20 69  es cached */.  i
5610: 6e 74 20 2a 70 6e 4d 61 78 2c 20 20 20 20 20 20  nt *pnMax,      
5620: 20 20 20 20 2f 2a 20 4f 55 54 3a 20 47 6c 6f 62      /* OUT: Glob
5630: 61 6c 20 6d 61 78 69 6d 75 6d 20 63 61 63 68 65  al maximum cache
5640: 20 73 69 7a 65 20 2a 2f 0a 20 20 69 6e 74 20 2a   size */.  int *
5650: 70 6e 4d 69 6e 2c 20 20 20 20 20 20 20 20 20 20  pnMin,          
5660: 2f 2a 20 4f 55 54 3a 20 53 75 6d 20 6f 66 20 50  /* OUT: Sum of P
5670: 43 61 63 68 65 31 2e 6e 4d 69 6e 20 66 6f 72 20  Cache1.nMin for 
5680: 70 75 72 67 65 61 62 6c 65 20 63 61 63 68 65 73  purgeable caches
5690: 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 52 65 63   */.  int *pnRec
56a0: 79 63 6c 61 62 6c 65 20 20 20 20 2f 2a 20 4f 55  yclable    /* OU
56b0: 54 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20  T: Total number 
56c0: 6f 66 20 70 61 67 65 73 20 61 76 61 69 6c 61 62  of pages availab
56d0: 6c 65 20 66 6f 72 20 72 65 63 79 63 6c 69 6e 67  le for recycling
56e0: 20 2a 2f 0a 29 7b 0a 20 20 50 67 48 64 72 31 20   */.){.  PgHdr1 
56f0: 2a 70 3b 0a 20 20 69 6e 74 20 6e 52 65 63 79 63  *p;.  int nRecyc
5700: 6c 61 62 6c 65 20 3d 20 30 3b 0a 20 20 66 6f 72  lable = 0;.  for
5710: 28 70 3d 70 63 61 63 68 65 31 2e 70 4c 72 75 48  (p=pcache1.pLruH
5720: 65 61 64 3b 20 70 3b 20 70 3d 70 2d 3e 70 4c 72  ead; p; p=p->pLr
5730: 75 4e 65 78 74 29 7b 0a 20 20 20 20 6e 52 65 63  uNext){.    nRec
5740: 79 63 6c 61 62 6c 65 2b 2b 3b 0a 20 20 7d 0a 20  yclable++;.  }. 
5750: 20 2a 70 6e 43 75 72 72 65 6e 74 20 3d 20 70 63   *pnCurrent = pc
5760: 61 63 68 65 31 2e 6e 43 75 72 72 65 6e 74 50 61  ache1.nCurrentPa
5770: 67 65 3b 0a 20 20 2a 70 6e 4d 61 78 20 3d 20 70  ge;.  *pnMax = p
5780: 63 61 63 68 65 31 2e 6e 4d 61 78 50 61 67 65 3b  cache1.nMaxPage;
5790: 0a 20 20 2a 70 6e 4d 69 6e 20 3d 20 70 63 61 63  .  *pnMin = pcac
57a0: 68 65 31 2e 6e 4d 69 6e 50 61 67 65 3b 0a 20 20  he1.nMinPage;.  
57b0: 2a 70 6e 52 65 63 79 63 6c 61 62 6c 65 20 3d 20  *pnRecyclable = 
57c0: 6e 52 65 63 79 63 6c 61 62 6c 65 3b 0a 7d 0a 23  nRecyclable;.}.#
57d0: 65 6e 64 69 66 0a                                endif.