/ Hex Artifact Content
Login

Artifact a6138ee57da3259149ca5254e0156d9b624db850:


0000: 2f 2a 0a 2a 2a 20 32 30 30 38 20 4e 6f 76 65 6d  /*.** 2008 Novem
0010: 62 65 72 20 30 35 0a 2a 2a 0a 2a 2a 20 54 68 65  ber 05.**.** The
0020: 20 61 75 74 68 6f 72 20 64 69 73 63 6c 61 69 6d   author disclaim
0030: 73 20 63 6f 70 79 72 69 67 68 74 20 74 6f 20 74  s copyright to t
0040: 68 69 73 20 73 6f 75 72 63 65 20 63 6f 64 65 2e  his source code.
0050: 20 20 49 6e 20 70 6c 61 63 65 20 6f 66 0a 2a 2a    In place of.**
0060: 20 61 20 6c 65 67 61 6c 20 6e 6f 74 69 63 65 2c   a legal notice,
0070: 20 68 65 72 65 20 69 73 20 61 20 62 6c 65 73 73   here is a bless
0080: 69 6e 67 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 4d 61  ing:.**.**    Ma
0090: 79 20 79 6f 75 20 64 6f 20 67 6f 6f 64 20 61 6e  y you do good an
00a0: 64 20 6e 6f 74 20 65 76 69 6c 2e 0a 2a 2a 20 20  d not evil..**  
00b0: 20 20 4d 61 79 20 79 6f 75 20 66 69 6e 64 20 66    May you find f
00c0: 6f 72 67 69 76 65 6e 65 73 73 20 66 6f 72 20 79  orgiveness for y
00d0: 6f 75 72 73 65 6c 66 20 61 6e 64 20 66 6f 72 67  ourself and forg
00e0: 69 76 65 20 6f 74 68 65 72 73 2e 0a 2a 2a 20 20  ive others..**  
00f0: 20 20 4d 61 79 20 79 6f 75 20 73 68 61 72 65 20    May you share 
0100: 66 72 65 65 6c 79 2c 20 6e 65 76 65 72 20 74 61  freely, never ta
0110: 6b 69 6e 67 20 6d 6f 72 65 20 74 68 61 6e 20 79  king more than y
0120: 6f 75 20 67 69 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a  ou give..**.****
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 2a 2a 2a 2a 2a 0a 2a 2a 0a 2a 2a 20 54 68 69 73  *****.**.** This
0180: 20 66 69 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 73   file implements
0190: 20 74 68 65 20 64 65 66 61 75 6c 74 20 70 61 67   the default pag
01a0: 65 20 63 61 63 68 65 20 69 6d 70 6c 65 6d 65 6e  e cache implemen
01b0: 74 61 74 69 6f 6e 20 28 74 68 65 0a 2a 2a 20 73  tation (the.** s
01c0: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 69 6e  qlite3_pcache in
01d0: 74 65 72 66 61 63 65 29 2e 20 49 74 20 61 6c 73  terface). It als
01e0: 6f 20 63 6f 6e 74 61 69 6e 73 20 70 61 72 74 20  o contains part 
01f0: 6f 66 20 74 68 65 20 69 6d 70 6c 65 6d 65 6e 74  of the implement
0200: 61 74 69 6f 6e 0a 2a 2a 20 6f 66 20 74 68 65 20  ation.** of the 
0210: 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41  SQLITE_CONFIG_PA
0220: 47 45 43 41 43 48 45 20 61 6e 64 20 73 71 6c 69  GECACHE and sqli
0230: 74 65 33 5f 72 65 6c 65 61 73 65 5f 6d 65 6d 6f  te3_release_memo
0240: 72 79 28 29 20 66 65 61 74 75 72 65 73 2e 0a 2a  ry() features..*
0250: 2a 20 49 66 20 74 68 65 20 64 65 66 61 75 6c 74  * If the default
0260: 20 70 61 67 65 20 63 61 63 68 65 20 69 6d 70 6c   page cache impl
0270: 65 6d 65 6e 74 61 74 69 6f 6e 20 69 73 20 6f 76  ementation is ov
0280: 65 72 72 69 64 65 6e 2c 20 74 68 65 6e 20 6e 65  erriden, then ne
0290: 69 74 68 65 72 20 6f 66 0a 2a 2a 20 74 68 65 73  ither of.** thes
02a0: 65 20 74 77 6f 20 66 65 61 74 75 72 65 73 20 61  e two features a
02b0: 72 65 20 61 76 61 69 6c 61 62 6c 65 2e 0a 2a 2a  re available..**
02c0: 0a 2a 2a 20 40 28 23 29 20 24 49 64 3a 20 70 63  .** @(#) $Id: pc
02d0: 61 63 68 65 31 2e 63 2c 76 20 31 2e 31 32 20 32  ache1.c,v 1.12 2
02e0: 30 30 39 2f 30 35 2f 30 38 20 30 36 3a 35 32 3a  009/05/08 06:52:
02f0: 34 38 20 64 61 6e 69 65 6c 6b 31 39 37 37 20 45  48 danielk1977 E
0300: 78 70 20 24 0a 2a 2f 0a 0a 23 69 6e 63 6c 75 64  xp $.*/..#includ
0310: 65 20 22 73 71 6c 69 74 65 49 6e 74 2e 68 22 0a  e "sqliteInt.h".
0320: 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20  .typedef struct 
0330: 50 43 61 63 68 65 31 20 50 43 61 63 68 65 31 3b  PCache1 PCache1;
0340: 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20  .typedef struct 
0350: 50 67 48 64 72 31 20 50 67 48 64 72 31 3b 0a 74  PgHdr1 PgHdr1;.t
0360: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 50 67  ypedef struct Pg
0370: 46 72 65 65 73 6c 6f 74 20 50 67 46 72 65 65 73  Freeslot PgFrees
0380: 6c 6f 74 3b 0a 0a 2f 2a 20 50 6f 69 6e 74 65 72  lot;../* Pointer
0390: 73 20 74 6f 20 73 74 72 75 63 74 75 72 65 73 20  s to structures 
03a0: 6f 66 20 74 68 69 73 20 74 79 70 65 20 61 72 65  of this type are
03b0: 20 63 61 73 74 20 61 6e 64 20 72 65 74 75 72 6e   cast and return
03c0: 65 64 20 61 73 20 0a 2a 2a 20 6f 70 61 71 75 65  ed as .** opaque
03d0: 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2a   sqlite3_pcache*
03e0: 20 68 61 6e 64 6c 65 73 0a 2a 2f 0a 73 74 72 75   handles.*/.stru
03f0: 63 74 20 50 43 61 63 68 65 31 20 7b 0a 20 20 2f  ct PCache1 {.  /
0400: 2a 20 43 61 63 68 65 20 63 6f 6e 66 69 67 75 72  * Cache configur
0410: 61 74 69 6f 6e 20 70 61 72 61 6d 65 74 65 72 73  ation parameters
0420: 2e 20 50 61 67 65 20 73 69 7a 65 20 28 73 7a 50  . Page size (szP
0430: 61 67 65 29 20 61 6e 64 20 74 68 65 20 70 75 72  age) and the pur
0440: 67 65 61 62 6c 65 0a 20 20 2a 2a 20 66 6c 61 67  geable.  ** flag
0450: 20 28 62 50 75 72 67 65 61 62 6c 65 29 20 61 72   (bPurgeable) ar
0460: 65 20 73 65 74 20 77 68 65 6e 20 74 68 65 20 63  e set when the c
0470: 61 63 68 65 20 69 73 20 63 72 65 61 74 65 64 2e  ache is created.
0480: 20 6e 4d 61 78 20 6d 61 79 20 62 65 20 0a 20 20   nMax may be .  
0490: 2a 2a 20 6d 6f 64 69 66 69 65 64 20 61 74 20 61  ** modified at a
04a0: 6e 79 20 74 69 6d 65 20 62 79 20 61 20 63 61 6c  ny time by a cal
04b0: 6c 20 74 6f 20 74 68 65 20 70 63 61 63 68 65 31  l to the pcache1
04c0: 43 61 63 68 65 53 69 7a 65 28 29 20 6d 65 74 68  CacheSize() meth
04d0: 6f 64 2e 0a 20 20 2a 2a 20 54 68 65 20 67 6c 6f  od..  ** The glo
04e0: 62 61 6c 20 6d 75 74 65 78 20 6d 75 73 74 20 62  bal mutex must b
04f0: 65 20 68 65 6c 64 20 77 68 65 6e 20 61 63 63 65  e held when acce
0500: 73 73 69 6e 67 20 6e 4d 61 78 2e 0a 20 20 2a 2f  ssing nMax..  */
0510: 0a 20 20 69 6e 74 20 73 7a 50 61 67 65 3b 20 20  .  int szPage;  
0520: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0530: 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
0540: 66 20 61 6c 6c 6f 63 61 74 65 64 20 70 61 67 65  f allocated page
0550: 73 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20  s in bytes */.  
0560: 69 6e 74 20 62 50 75 72 67 65 61 62 6c 65 3b 20  int bPurgeable; 
0570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0580: 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 63      /* True if c
0590: 61 63 68 65 20 69 73 20 70 75 72 67 65 61 62 6c  ache is purgeabl
05a0: 65 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20  e */.  unsigned 
05b0: 69 6e 74 20 6e 4d 69 6e 3b 20 20 20 20 20 20 20  int nMin;       
05c0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 69             /* Mi
05d0: 6e 69 6d 75 6d 20 6e 75 6d 62 65 72 20 6f 66 20  nimum number of 
05e0: 70 61 67 65 73 20 72 65 73 65 72 76 65 64 20 2a  pages reserved *
05f0: 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74  /.  unsigned int
0600: 20 6e 4d 61 78 3b 20 20 20 20 20 20 20 20 20 20   nMax;          
0610: 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6e 66 69          /* Confi
0620: 67 75 72 65 64 20 22 63 61 63 68 65 5f 73 69 7a  gured "cache_siz
0630: 65 22 20 76 61 6c 75 65 20 2a 2f 0a 0a 20 20 2f  e" value */..  /
0640: 2a 20 48 61 73 68 20 74 61 62 6c 65 20 6f 66 20  * Hash table of 
0650: 61 6c 6c 20 70 61 67 65 73 2e 20 54 68 65 20 66  all pages. The f
0660: 6f 6c 6c 6f 77 69 6e 67 20 76 61 72 69 61 62 6c  ollowing variabl
0670: 65 73 20 6d 61 79 20 6f 6e 6c 79 20 62 65 20 61  es may only be a
0680: 63 63 65 73 73 65 64 0a 20 20 2a 2a 20 77 68 65  ccessed.  ** whe
0690: 6e 20 74 68 65 20 61 63 63 65 73 73 6f 72 20 69  n the accessor i
06a0: 73 20 68 6f 6c 64 69 6e 67 20 74 68 65 20 67 6c  s holding the gl
06b0: 6f 62 61 6c 20 6d 75 74 65 78 20 28 73 65 65 20  obal mutex (see 
06c0: 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65  pcache1EnterMute
06d0: 78 28 29 20 0a 20 20 2a 2a 20 61 6e 64 20 70 63  x() .  ** and pc
06e0: 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28  ache1LeaveMutex(
06f0: 29 29 2e 0a 20 20 2a 2f 0a 20 20 75 6e 73 69 67  ))..  */.  unsig
0700: 6e 65 64 20 69 6e 74 20 6e 52 65 63 79 63 6c 61  ned int nRecycla
0710: 62 6c 65 3b 20 20 20 20 20 20 20 20 20 20 20 2f  ble;           /
0720: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 70 61 67 65  * Number of page
0730: 73 20 69 6e 20 74 68 65 20 4c 52 55 20 6c 69 73  s in the LRU lis
0740: 74 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20  t */.  unsigned 
0750: 69 6e 74 20 6e 50 61 67 65 3b 20 20 20 20 20 20  int nPage;      
0760: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 6f             /* To
0770: 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 70 61  tal number of pa
0780: 67 65 73 20 69 6e 20 61 70 48 61 73 68 20 2a 2f  ges in apHash */
0790: 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  .  unsigned int 
07a0: 6e 48 61 73 68 3b 20 20 20 20 20 20 20 20 20 20  nHash;          
07b0: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
07c0: 20 6f 66 20 73 6c 6f 74 73 20 69 6e 20 61 70 48   of slots in apH
07d0: 61 73 68 5b 5d 20 2a 2f 0a 20 20 50 67 48 64 72  ash[] */.  PgHdr
07e0: 31 20 2a 2a 61 70 48 61 73 68 3b 20 20 20 20 20  1 **apHash;     
07f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0800: 2a 20 48 61 73 68 20 74 61 62 6c 65 20 66 6f 72  * Hash table for
0810: 20 66 61 73 74 20 6c 6f 6f 6b 75 70 20 62 79 20   fast lookup by 
0820: 6b 65 79 20 2a 2f 0a 0a 20 20 75 6e 73 69 67 6e  key */..  unsign
0830: 65 64 20 69 6e 74 20 69 4d 61 78 4b 65 79 3b 20  ed int iMaxKey; 
0840: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0850: 20 4c 61 72 67 65 73 74 20 6b 65 79 20 73 65 65   Largest key see
0860: 6e 20 73 69 6e 63 65 20 78 54 72 75 6e 63 61 74  n since xTruncat
0870: 65 28 29 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a  e() */.};../*.**
0880: 20 45 61 63 68 20 63 61 63 68 65 20 65 6e 74 72   Each cache entr
0890: 79 20 69 73 20 72 65 70 72 65 73 65 6e 74 65 64  y is represented
08a0: 20 62 79 20 61 6e 20 69 6e 73 74 61 6e 63 65 20   by an instance 
08b0: 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  of the following
08c0: 20 0a 2a 2a 20 73 74 72 75 63 74 75 72 65 2e 20   .** structure. 
08d0: 41 20 62 75 66 66 65 72 20 6f 66 20 50 67 48 64  A buffer of PgHd
08e0: 72 31 2e 70 43 61 63 68 65 2d 3e 73 7a 50 61 67  r1.pCache->szPag
08f0: 65 20 62 79 74 65 73 20 69 73 20 61 6c 6c 6f 63  e bytes is alloc
0900: 61 74 65 64 20 0a 2a 2a 20 64 69 72 65 63 74 6c  ated .** directl
0910: 79 20 61 66 74 65 72 20 74 68 65 20 73 74 72 75  y after the stru
0920: 63 74 75 72 65 20 69 6e 20 6d 65 6d 6f 72 79 20  cture in memory 
0930: 28 73 65 65 20 74 68 65 20 50 47 48 44 52 31 5f  (see the PGHDR1_
0940: 54 4f 5f 50 41 47 45 28 29 20 0a 2a 2a 20 6d 61  TO_PAGE() .** ma
0950: 63 72 6f 20 62 65 6c 6f 77 29 2e 0a 2a 2f 0a 73  cro below)..*/.s
0960: 74 72 75 63 74 20 50 67 48 64 72 31 20 7b 0a 20  truct PgHdr1 {. 
0970: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4b   unsigned int iK
0980: 65 79 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ey;             
0990: 2f 2a 20 4b 65 79 20 76 61 6c 75 65 20 28 70 61  /* Key value (pa
09a0: 67 65 20 6e 75 6d 62 65 72 29 20 2a 2f 0a 20 20  ge number) */.  
09b0: 50 67 48 64 72 31 20 2a 70 4e 65 78 74 3b 20 20  PgHdr1 *pNext;  
09c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
09d0: 2a 20 4e 65 78 74 20 69 6e 20 68 61 73 68 20 74  * Next in hash t
09e0: 61 62 6c 65 20 63 68 61 69 6e 20 2a 2f 0a 20 20  able chain */.  
09f0: 50 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 3b  PCache1 *pCache;
0a00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0a10: 2a 20 43 61 63 68 65 20 74 68 61 74 20 63 75 72  * Cache that cur
0a20: 72 65 6e 74 6c 79 20 6f 77 6e 73 20 74 68 69 73  rently owns this
0a30: 20 70 61 67 65 20 2a 2f 0a 20 20 50 67 48 64 72   page */.  PgHdr
0a40: 31 20 2a 70 4c 72 75 4e 65 78 74 3b 20 20 20 20  1 *pLruNext;    
0a50: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78            /* Nex
0a60: 74 20 69 6e 20 4c 52 55 20 6c 69 73 74 20 6f 66  t in LRU list of
0a70: 20 75 6e 70 69 6e 6e 65 64 20 70 61 67 65 73 20   unpinned pages 
0a80: 2a 2f 0a 20 20 50 67 48 64 72 31 20 2a 70 4c 72  */.  PgHdr1 *pLr
0a90: 75 50 72 65 76 3b 20 20 20 20 20 20 20 20 20 20  uPrev;          
0aa0: 20 20 20 20 2f 2a 20 50 72 65 76 69 6f 75 73 20      /* Previous 
0ab0: 69 6e 20 4c 52 55 20 6c 69 73 74 20 6f 66 20 75  in LRU list of u
0ac0: 6e 70 69 6e 6e 65 64 20 70 61 67 65 73 20 2a 2f  npinned pages */
0ad0: 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20  .};../*.** Free 
0ae0: 73 6c 6f 74 73 20 69 6e 20 74 68 65 20 61 6c 6c  slots in the all
0af0: 6f 63 61 74 6f 72 20 75 73 65 64 20 74 6f 20 64  ocator used to d
0b00: 69 76 69 64 65 20 75 70 20 74 68 65 20 62 75 66  ivide up the buf
0b10: 66 65 72 20 70 72 6f 76 69 64 65 64 20 75 73 69  fer provided usi
0b20: 6e 67 0a 2a 2a 20 74 68 65 20 53 51 4c 49 54 45  ng.** the SQLITE
0b30: 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48  _CONFIG_PAGECACH
0b40: 45 20 6d 65 63 68 61 6e 69 73 6d 2e 0a 2a 2f 0a  E mechanism..*/.
0b50: 73 74 72 75 63 74 20 50 67 46 72 65 65 73 6c 6f  struct PgFreeslo
0b60: 74 20 7b 0a 20 20 50 67 46 72 65 65 73 6c 6f 74  t {.  PgFreeslot
0b70: 20 2a 70 4e 65 78 74 3b 20 20 2f 2a 20 4e 65 78   *pNext;  /* Nex
0b80: 74 20 66 72 65 65 20 73 6c 6f 74 20 2a 2f 0a 7d  t free slot */.}
0b90: 3b 0a 0a 2f 2a 0a 2a 2a 20 47 6c 6f 62 61 6c 20  ;../*.** Global 
0ba0: 64 61 74 61 20 75 73 65 64 20 62 79 20 74 68 69  data used by thi
0bb0: 73 20 63 61 63 68 65 2e 0a 2a 2f 0a 73 74 61 74  s cache..*/.stat
0bc0: 69 63 20 53 51 4c 49 54 45 5f 57 53 44 20 73 74  ic SQLITE_WSD st
0bd0: 72 75 63 74 20 50 43 61 63 68 65 47 6c 6f 62 61  ruct PCacheGloba
0be0: 6c 20 7b 0a 20 20 73 71 6c 69 74 65 33 5f 6d 75  l {.  sqlite3_mu
0bf0: 74 65 78 20 2a 6d 75 74 65 78 3b 20 20 20 20 20  tex *mutex;     
0c00: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 73 74 61            /* sta
0c10: 74 69 63 20 6d 75 74 65 78 20 4d 55 54 45 58 5f  tic mutex MUTEX_
0c20: 53 54 41 54 49 43 5f 4c 52 55 20 2a 2f 0a 0a 20  STATIC_LRU */.. 
0c30: 20 69 6e 74 20 6e 4d 61 78 50 61 67 65 3b 20 20   int nMaxPage;  
0c40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c50: 20 20 20 20 20 2f 2a 20 53 75 6d 20 6f 66 20 6e       /* Sum of n
0c60: 4d 61 78 50 61 67 65 20 66 6f 72 20 70 75 72 67  MaxPage for purg
0c70: 65 61 62 6c 65 20 63 61 63 68 65 73 20 2a 2f 0a  eable caches */.
0c80: 20 20 69 6e 74 20 6e 4d 69 6e 50 61 67 65 3b 20    int nMinPage; 
0c90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ca0: 20 20 20 20 20 20 2f 2a 20 53 75 6d 20 6f 66 20        /* Sum of 
0cb0: 6e 4d 69 6e 50 61 67 65 20 66 6f 72 20 70 75 72  nMinPage for pur
0cc0: 67 65 61 62 6c 65 20 63 61 63 68 65 73 20 2a 2f  geable caches */
0cd0: 0a 20 20 69 6e 74 20 6e 43 75 72 72 65 6e 74 50  .  int nCurrentP
0ce0: 61 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  age;            
0cf0: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
0d00: 20 6f 66 20 70 75 72 67 65 61 62 6c 65 20 70 61   of purgeable pa
0d10: 67 65 73 20 61 6c 6c 6f 63 61 74 65 64 20 2a 2f  ges allocated */
0d20: 0a 20 20 50 67 48 64 72 31 20 2a 70 4c 72 75 48  .  PgHdr1 *pLruH
0d30: 65 61 64 2c 20 2a 70 4c 72 75 54 61 69 6c 3b 20  ead, *pLruTail; 
0d40: 20 20 20 20 20 20 20 2f 2a 20 4c 52 55 20 6c 69         /* LRU li
0d50: 73 74 20 6f 66 20 75 6e 70 69 6e 6e 65 64 20 70  st of unpinned p
0d60: 61 67 65 73 20 2a 2f 0a 0a 20 20 2f 2a 20 56 61  ages */..  /* Va
0d70: 72 69 61 62 6c 65 73 20 72 65 6c 61 74 65 64 20  riables related 
0d80: 74 6f 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47  to SQLITE_CONFIG
0d90: 5f 50 41 47 45 43 41 43 48 45 20 73 65 74 74 69  _PAGECACHE setti
0da0: 6e 67 73 2e 20 2a 2f 0a 20 20 69 6e 74 20 73 7a  ngs. */.  int sz
0db0: 53 6c 6f 74 3b 20 20 20 20 20 20 20 20 20 20 20  Slot;           
0dc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0dd0: 20 53 69 7a 65 20 6f 66 20 65 61 63 68 20 66 72   Size of each fr
0de0: 65 65 20 73 6c 6f 74 20 2a 2f 0a 20 20 76 6f 69  ee slot */.  voi
0df0: 64 20 2a 70 53 74 61 72 74 2c 20 2a 70 45 6e 64  d *pStart, *pEnd
0e00: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
0e10: 20 2f 2a 20 42 6f 75 6e 64 73 20 6f 66 20 70 61   /* Bounds of pa
0e20: 67 65 63 61 63 68 65 20 6d 61 6c 6c 6f 63 20 72  gecache malloc r
0e30: 61 6e 67 65 20 2a 2f 0a 20 20 50 67 46 72 65 65  ange */.  PgFree
0e40: 73 6c 6f 74 20 2a 70 46 72 65 65 3b 20 20 20 20  slot *pFree;    
0e50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0e60: 20 46 72 65 65 20 70 61 67 65 20 62 6c 6f 63 6b   Free page block
0e70: 73 20 2a 2f 0a 7d 20 70 63 61 63 68 65 31 5f 67  s */.} pcache1_g
0e80: 3b 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c 20 63 6f 64  ;../*.** All cod
0e90: 65 20 69 6e 20 74 68 69 73 20 66 69 6c 65 20 73  e in this file s
0ea0: 68 6f 75 6c 64 20 61 63 63 65 73 73 20 74 68 65  hould access the
0eb0: 20 67 6c 6f 62 61 6c 20 73 74 72 75 63 74 75 72   global structur
0ec0: 65 20 61 62 6f 76 65 20 76 69 61 20 74 68 65 0a  e above via the.
0ed0: 2a 2a 20 61 6c 69 61 73 20 22 70 63 61 63 68 65  ** alias "pcache
0ee0: 31 22 2e 20 54 68 69 73 20 65 6e 73 75 72 65 73  1". This ensures
0ef0: 20 74 68 61 74 20 74 68 65 20 57 53 44 20 65 6d   that the WSD em
0f00: 75 6c 61 74 69 6f 6e 20 69 73 20 75 73 65 64 20  ulation is used 
0f10: 77 68 65 6e 0a 2a 2a 20 63 6f 6d 70 69 6c 69 6e  when.** compilin
0f20: 67 20 66 6f 72 20 73 79 73 74 65 6d 73 20 74 68  g for systems th
0f30: 61 74 20 64 6f 20 6e 6f 74 20 73 75 70 70 6f 72  at do not suppor
0f40: 74 20 72 65 61 6c 20 57 53 44 2e 0a 2a 2f 0a 23  t real WSD..*/.#
0f50: 64 65 66 69 6e 65 20 70 63 61 63 68 65 31 20 28  define pcache1 (
0f60: 47 4c 4f 42 41 4c 28 73 74 72 75 63 74 20 50 43  GLOBAL(struct PC
0f70: 61 63 68 65 47 6c 6f 62 61 6c 2c 20 70 63 61 63  acheGlobal, pcac
0f80: 68 65 31 5f 67 29 29 0a 0a 2f 2a 0a 2a 2a 20 57  he1_g))../*.** W
0f90: 68 65 6e 20 61 20 50 67 48 64 72 31 20 73 74 72  hen a PgHdr1 str
0fa0: 75 63 74 75 72 65 20 69 73 20 61 6c 6c 6f 63 61  ucture is alloca
0fb0: 74 65 64 2c 20 74 68 65 20 61 73 73 6f 63 69 61  ted, the associa
0fc0: 74 65 64 20 50 43 61 63 68 65 31 2e 73 7a 50 61  ted PCache1.szPa
0fd0: 67 65 0a 2a 2a 20 62 79 74 65 73 20 6f 66 20 64  ge.** bytes of d
0fe0: 61 74 61 20 61 72 65 20 6c 6f 63 61 74 65 64 20  ata are located 
0ff0: 64 69 72 65 63 74 6c 79 20 61 66 74 65 72 20 69  directly after i
1000: 74 20 69 6e 20 6d 65 6d 6f 72 79 20 28 69 2e 65  t in memory (i.e
1010: 2e 20 74 68 65 20 74 6f 74 61 6c 0a 2a 2a 20 73  . the total.** s
1020: 69 7a 65 20 6f 66 20 74 68 65 20 61 6c 6c 6f 63  ize of the alloc
1030: 61 74 69 6f 6e 20 69 73 20 73 69 7a 65 6f 66 28  ation is sizeof(
1040: 50 67 48 64 72 31 29 2b 50 43 61 63 68 65 31 2e  PgHdr1)+PCache1.
1050: 73 7a 50 61 67 65 20 62 79 74 65 29 2e 20 54 68  szPage byte). Th
1060: 65 0a 2a 2a 20 50 47 48 44 52 31 5f 54 4f 5f 50  e.** PGHDR1_TO_P
1070: 41 47 45 28 29 20 6d 61 63 72 6f 20 74 61 6b 65  AGE() macro take
1080: 73 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 61  s a pointer to a
1090: 20 50 67 48 64 72 31 20 73 74 72 75 63 74 75 72   PgHdr1 structur
10a0: 65 20 61 73 0a 2a 2a 20 61 6e 20 61 72 67 75 6d  e as.** an argum
10b0: 65 6e 74 20 61 6e 64 20 72 65 74 75 72 6e 73 20  ent and returns 
10c0: 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65  a pointer to the
10d0: 20 61 73 73 6f 63 69 61 74 65 64 20 62 6c 6f 63   associated bloc
10e0: 6b 20 6f 66 20 73 7a 50 61 67 65 0a 2a 2a 20 62  k of szPage.** b
10f0: 79 74 65 73 2e 20 54 68 65 20 50 41 47 45 5f 54  ytes. The PAGE_T
1100: 4f 5f 50 47 48 44 52 31 28 29 20 6d 61 63 72 6f  O_PGHDR1() macro
1110: 20 64 6f 65 73 20 74 68 65 20 6f 70 70 6f 73 69   does the opposi
1120: 74 65 3a 20 69 74 73 20 61 72 67 75 6d 65 6e 74  te: its argument
1130: 20 69 73 0a 2a 2a 20 61 20 70 6f 69 6e 74 65 72   is.** a pointer
1140: 20 74 6f 20 61 20 62 6c 6f 63 6b 20 6f 66 20 73   to a block of s
1150: 7a 50 61 67 65 20 62 79 74 65 73 20 6f 66 20 64  zPage bytes of d
1160: 61 74 61 20 61 6e 64 20 74 68 65 20 72 65 74 75  ata and the retu
1170: 72 6e 20 76 61 6c 75 65 20 69 73 0a 2a 2a 20 61  rn value is.** a
1180: 20 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20   pointer to the 
1190: 61 73 73 6f 63 69 61 74 65 64 20 50 67 48 64 72  associated PgHdr
11a0: 31 20 73 74 72 75 63 74 75 72 65 2e 0a 2a 2a 0a  1 structure..**.
11b0: 2a 2a 20 20 20 61 73 73 65 72 74 28 20 50 47 48  **   assert( PGH
11c0: 44 52 31 5f 54 4f 5f 50 41 47 45 28 50 41 47 45  DR1_TO_PAGE(PAGE
11d0: 5f 54 4f 5f 50 47 48 44 52 31 28 58 29 29 3d 3d  _TO_PGHDR1(X))==
11e0: 58 20 29 3b 0a 2a 2f 0a 23 64 65 66 69 6e 65 20  X );.*/.#define 
11f0: 50 47 48 44 52 31 5f 54 4f 5f 50 41 47 45 28 70  PGHDR1_TO_PAGE(p
1200: 29 20 28 76 6f 69 64 20 2a 29 28 26 28 28 75 6e  ) (void *)(&((un
1210: 73 69 67 6e 65 64 20 63 68 61 72 20 2a 29 70 29  signed char *)p)
1220: 5b 73 69 7a 65 6f 66 28 50 67 48 64 72 31 29 5d  [sizeof(PgHdr1)]
1230: 29 0a 23 64 65 66 69 6e 65 20 50 41 47 45 5f 54  ).#define PAGE_T
1240: 4f 5f 50 47 48 44 52 31 28 70 29 20 28 50 67 48  O_PGHDR1(p) (PgH
1250: 64 72 31 20 2a 29 28 26 28 28 75 6e 73 69 67 6e  dr1 *)(&((unsign
1260: 65 64 20 63 68 61 72 20 2a 29 70 29 5b 2d 31 2a  ed char *)p)[-1*
1270: 28 69 6e 74 29 73 69 7a 65 6f 66 28 50 67 48 64  (int)sizeof(PgHd
1280: 72 31 29 5d 29 0a 0a 2f 2a 0a 2a 2a 20 4d 61 63  r1)])../*.** Mac
1290: 72 6f 73 20 74 6f 20 65 6e 74 65 72 20 61 6e 64  ros to enter and
12a0: 20 6c 65 61 76 65 20 74 68 65 20 67 6c 6f 62 61   leave the globa
12b0: 6c 20 4c 52 55 20 6d 75 74 65 78 2e 0a 2a 2f 0a  l LRU mutex..*/.
12c0: 23 64 65 66 69 6e 65 20 70 63 61 63 68 65 31 45  #define pcache1E
12d0: 6e 74 65 72 4d 75 74 65 78 28 29 20 73 71 6c 69  nterMutex() sqli
12e0: 74 65 33 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28  te3_mutex_enter(
12f0: 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29 0a 23  pcache1.mutex).#
1300: 64 65 66 69 6e 65 20 70 63 61 63 68 65 31 4c 65  define pcache1Le
1310: 61 76 65 4d 75 74 65 78 28 29 20 73 71 6c 69 74  aveMutex() sqlit
1320: 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 70  e3_mutex_leave(p
1330: 63 61 63 68 65 31 2e 6d 75 74 65 78 29 0a 0a 2f  cache1.mutex)../
1340: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1350: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1360: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1370: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1380: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a  **************/.
1390: 2f 2a 2a 2a 2a 2a 2a 2a 2a 20 50 61 67 65 20 41  /******** Page A
13a0: 6c 6c 6f 63 61 74 69 6f 6e 2f 53 51 4c 49 54 45  llocation/SQLITE
13b0: 5f 43 4f 4e 46 49 47 5f 50 43 41 43 48 45 20 52  _CONFIG_PCACHE R
13c0: 65 6c 61 74 65 64 20 46 75 6e 63 74 69 6f 6e 73  elated Functions
13d0: 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f   **************/
13e0: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e  ../*.** This fun
13f0: 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20  ction is called 
1400: 64 75 72 69 6e 67 20 69 6e 69 74 69 61 6c 69 7a  during initializ
1410: 61 74 69 6f 6e 20 69 66 20 61 20 73 74 61 74 69  ation if a stati
1420: 63 20 62 75 66 66 65 72 20 69 73 20 0a 2a 2a 20  c buffer is .** 
1430: 73 75 70 70 6c 69 65 64 20 74 6f 20 75 73 65 20  supplied to use 
1440: 66 6f 72 20 74 68 65 20 70 61 67 65 2d 63 61 63  for the page-cac
1450: 68 65 20 62 79 20 70 61 73 73 69 6e 67 20 74 68  he by passing th
1460: 65 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f  e SQLITE_CONFIG_
1470: 50 41 47 45 43 41 43 48 45 0a 2a 2a 20 76 65 72  PAGECACHE.** ver
1480: 62 20 74 6f 20 73 71 6c 69 74 65 33 5f 63 6f 6e  b to sqlite3_con
1490: 66 69 67 28 29 2e 20 50 61 72 61 6d 65 74 65 72  fig(). Parameter
14a0: 20 70 42 75 66 20 70 6f 69 6e 74 73 20 74 6f 20   pBuf points to 
14b0: 61 6e 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 6c 61  an allocation la
14c0: 72 67 65 0a 2a 2a 20 65 6e 6f 75 67 68 20 74 6f  rge.** enough to
14d0: 20 63 6f 6e 74 61 69 6e 20 27 6e 27 20 62 75 66   contain 'n' buf
14e0: 66 65 72 73 20 6f 66 20 27 73 7a 27 20 62 79 74  fers of 'sz' byt
14f0: 65 73 20 65 61 63 68 2e 0a 2a 2f 0a 76 6f 69 64  es each..*/.void
1500: 20 73 71 6c 69 74 65 33 50 43 61 63 68 65 42 75   sqlite3PCacheBu
1510: 66 66 65 72 53 65 74 75 70 28 76 6f 69 64 20 2a  fferSetup(void *
1520: 70 42 75 66 2c 20 69 6e 74 20 73 7a 2c 20 69 6e  pBuf, int sz, in
1530: 74 20 6e 29 7b 0a 20 20 50 67 46 72 65 65 73 6c  t n){.  PgFreesl
1540: 6f 74 20 2a 70 3b 0a 20 20 73 7a 20 3d 20 52 4f  ot *p;.  sz = RO
1550: 55 4e 44 44 4f 57 4e 38 28 73 7a 29 3b 0a 20 20  UNDDOWN8(sz);.  
1560: 70 63 61 63 68 65 31 2e 73 7a 53 6c 6f 74 20 3d  pcache1.szSlot =
1570: 20 73 7a 3b 0a 20 20 70 63 61 63 68 65 31 2e 70   sz;.  pcache1.p
1580: 53 74 61 72 74 20 3d 20 70 42 75 66 3b 0a 20 20  Start = pBuf;.  
1590: 70 63 61 63 68 65 31 2e 70 46 72 65 65 20 3d 20  pcache1.pFree = 
15a0: 30 3b 0a 20 20 77 68 69 6c 65 28 20 6e 2d 2d 20  0;.  while( n-- 
15b0: 29 7b 0a 20 20 20 20 70 20 3d 20 28 50 67 46 72  ){.    p = (PgFr
15c0: 65 65 73 6c 6f 74 2a 29 70 42 75 66 3b 0a 20 20  eeslot*)pBuf;.  
15d0: 20 20 70 2d 3e 70 4e 65 78 74 20 3d 20 70 63 61    p->pNext = pca
15e0: 63 68 65 31 2e 70 46 72 65 65 3b 0a 20 20 20 20  che1.pFree;.    
15f0: 70 63 61 63 68 65 31 2e 70 46 72 65 65 20 3d 20  pcache1.pFree = 
1600: 70 3b 0a 20 20 20 20 70 42 75 66 20 3d 20 28 76  p;.    pBuf = (v
1610: 6f 69 64 2a 29 26 28 28 63 68 61 72 2a 29 70 42  oid*)&((char*)pB
1620: 75 66 29 5b 73 7a 5d 3b 0a 20 20 7d 0a 20 20 70  uf)[sz];.  }.  p
1630: 63 61 63 68 65 31 2e 70 45 6e 64 20 3d 20 70 42  cache1.pEnd = pB
1640: 75 66 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6c  uf;.}../*.** Mal
1650: 6c 6f 63 20 66 75 6e 63 74 69 6f 6e 20 75 73 65  loc function use
1660: 64 20 77 69 74 68 69 6e 20 74 68 69 73 20 66 69  d within this fi
1670: 6c 65 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 73  le to allocate s
1680: 70 61 63 65 20 66 72 6f 6d 20 74 68 65 20 62 75  pace from the bu
1690: 66 66 65 72 0a 2a 2a 20 63 6f 6e 66 69 67 75 72  ffer.** configur
16a0: 65 64 20 75 73 69 6e 67 20 73 71 6c 69 74 65 33  ed using sqlite3
16b0: 5f 63 6f 6e 66 69 67 28 53 51 4c 49 54 45 5f 43  _config(SQLITE_C
16c0: 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48 45 29  ONFIG_PAGECACHE)
16d0: 20 6f 70 74 69 6f 6e 2e 20 49 66 20 6e 6f 20 0a   option. If no .
16e0: 2a 2a 20 73 75 63 68 20 62 75 66 66 65 72 20 65  ** such buffer e
16f0: 78 69 73 74 73 20 6f 72 20 74 68 65 72 65 20 69  xists or there i
1700: 73 20 6e 6f 20 73 70 61 63 65 20 6c 65 66 74 20  s no space left 
1710: 69 6e 20 69 74 2c 20 74 68 69 73 20 66 75 6e 63  in it, this func
1720: 74 69 6f 6e 20 66 61 6c 6c 73 20 0a 2a 2a 20 62  tion falls .** b
1730: 61 63 6b 20 74 6f 20 73 71 6c 69 74 65 33 4d 61  ack to sqlite3Ma
1740: 6c 6c 6f 63 28 29 2e 0a 2a 2f 0a 73 74 61 74 69  lloc()..*/.stati
1750: 63 20 76 6f 69 64 20 2a 70 63 61 63 68 65 31 41  c void *pcache1A
1760: 6c 6c 6f 63 28 69 6e 74 20 6e 42 79 74 65 29 7b  lloc(int nByte){
1770: 0a 20 20 76 6f 69 64 20 2a 70 3b 0a 20 20 61 73  .  void *p;.  as
1780: 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75  sert( sqlite3_mu
1790: 74 65 78 5f 68 65 6c 64 28 70 63 61 63 68 65 31  tex_held(pcache1
17a0: 2e 6d 75 74 65 78 29 20 29 3b 0a 20 20 69 66 28  .mutex) );.  if(
17b0: 20 6e 42 79 74 65 3c 3d 70 63 61 63 68 65 31 2e   nByte<=pcache1.
17c0: 73 7a 53 6c 6f 74 20 26 26 20 70 63 61 63 68 65  szSlot && pcache
17d0: 31 2e 70 46 72 65 65 20 29 7b 0a 20 20 20 20 70  1.pFree ){.    p
17e0: 20 3d 20 28 50 67 48 64 72 31 20 2a 29 70 63 61   = (PgHdr1 *)pca
17f0: 63 68 65 31 2e 70 46 72 65 65 3b 0a 20 20 20 20  che1.pFree;.    
1800: 70 63 61 63 68 65 31 2e 70 46 72 65 65 20 3d 20  pcache1.pFree = 
1810: 70 63 61 63 68 65 31 2e 70 46 72 65 65 2d 3e 70  pcache1.pFree->p
1820: 4e 65 78 74 3b 0a 20 20 20 20 73 71 6c 69 74 65  Next;.    sqlite
1830: 33 53 74 61 74 75 73 53 65 74 28 53 51 4c 49 54  3StatusSet(SQLIT
1840: 45 5f 53 54 41 54 55 53 5f 50 41 47 45 43 41 43  E_STATUS_PAGECAC
1850: 48 45 5f 53 49 5a 45 2c 20 6e 42 79 74 65 29 3b  HE_SIZE, nByte);
1860: 0a 20 20 20 20 73 71 6c 69 74 65 33 53 74 61 74  .    sqlite3Stat
1870: 75 73 41 64 64 28 53 51 4c 49 54 45 5f 53 54 41  usAdd(SQLITE_STA
1880: 54 55 53 5f 50 41 47 45 43 41 43 48 45 5f 55 53  TUS_PAGECACHE_US
1890: 45 44 2c 20 31 29 3b 0a 20 20 7d 65 6c 73 65 7b  ED, 1);.  }else{
18a0: 0a 0a 20 20 20 20 2f 2a 20 41 6c 6c 6f 63 61 74  ..    /* Allocat
18b0: 65 20 61 20 6e 65 77 20 62 75 66 66 65 72 20 75  e a new buffer u
18c0: 73 69 6e 67 20 73 71 6c 69 74 65 33 4d 61 6c 6c  sing sqlite3Mall
18d0: 6f 63 2e 20 42 65 66 6f 72 65 20 64 6f 69 6e 67  oc. Before doing
18e0: 20 73 6f 2c 20 65 78 69 74 20 74 68 65 0a 20 20   so, exit the.  
18f0: 20 20 2a 2a 20 67 6c 6f 62 61 6c 20 70 63 61 63    ** global pcac
1900: 68 65 20 6d 75 74 65 78 20 61 6e 64 20 75 6e 6c  he mutex and unl
1910: 6f 63 6b 20 74 68 65 20 70 61 67 65 72 2d 63 61  ock the pager-ca
1920: 63 68 65 20 6f 62 6a 65 63 74 20 70 43 61 63 68  che object pCach
1930: 65 2e 20 54 68 69 73 20 69 73 20 0a 20 20 20 20  e. This is .    
1940: 2a 2a 20 73 6f 20 74 68 61 74 20 69 66 20 74 68  ** so that if th
1950: 65 20 61 74 74 65 6d 70 74 20 74 6f 20 61 6c 6c  e attempt to all
1960: 6f 63 61 74 65 20 61 20 6e 65 77 20 62 75 66 66  ocate a new buff
1970: 65 72 20 63 61 75 73 65 73 20 74 68 65 20 74 68  er causes the th
1980: 65 20 0a 20 20 20 20 2a 2a 20 63 6f 6e 66 69 67  e .    ** config
1990: 75 72 65 64 20 73 6f 66 74 2d 68 65 61 70 2d 6c  ured soft-heap-l
19a0: 69 6d 69 74 20 74 6f 20 62 65 20 62 72 65 61 63  imit to be breac
19b0: 68 65 64 2c 20 69 74 20 77 69 6c 6c 20 62 65 20  hed, it will be 
19c0: 70 6f 73 73 69 62 6c 65 20 74 6f 0a 20 20 20 20  possible to.    
19d0: 2a 2a 20 72 65 63 6c 61 69 6d 20 6d 65 6d 6f 72  ** reclaim memor
19e0: 79 20 66 72 6f 6d 20 74 68 69 73 20 70 61 67 65  y from this page
19f0: 72 2d 63 61 63 68 65 2e 0a 20 20 20 20 2a 2f 0a  r-cache..    */.
1a00: 20 20 20 20 70 63 61 63 68 65 31 4c 65 61 76 65      pcache1Leave
1a10: 4d 75 74 65 78 28 29 3b 0a 20 20 20 20 70 20 3d  Mutex();.    p =
1a20: 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 6e   sqlite3Malloc(n
1a30: 42 79 74 65 29 3b 0a 20 20 20 20 70 63 61 63 68  Byte);.    pcach
1a40: 65 31 45 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a  e1EnterMutex();.
1a50: 20 20 20 20 69 66 28 20 70 20 29 7b 0a 20 20 20      if( p ){.   
1a60: 20 20 20 69 6e 74 20 73 7a 20 3d 20 73 71 6c 69     int sz = sqli
1a70: 74 65 33 4d 61 6c 6c 6f 63 53 69 7a 65 28 70 29  te3MallocSize(p)
1a80: 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 53  ;.      sqlite3S
1a90: 74 61 74 75 73 41 64 64 28 53 51 4c 49 54 45 5f  tatusAdd(SQLITE_
1aa0: 53 54 41 54 55 53 5f 50 41 47 45 43 41 43 48 45  STATUS_PAGECACHE
1ab0: 5f 4f 56 45 52 46 4c 4f 57 2c 20 73 7a 29 3b 0a  _OVERFLOW, sz);.
1ac0: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75      }.  }.  retu
1ad0: 72 6e 20 70 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46  rn p;.}../*.** F
1ae0: 72 65 65 20 61 6e 20 61 6c 6c 6f 63 61 74 65 64  ree an allocated
1af0: 20 62 75 66 66 65 72 20 6f 62 74 61 69 6e 65 64   buffer obtained
1b00: 20 66 72 6f 6d 20 70 63 61 63 68 65 31 41 6c 6c   from pcache1All
1b10: 6f 63 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  oc()..*/.static 
1b20: 76 6f 69 64 20 70 63 61 63 68 65 31 46 72 65 65  void pcache1Free
1b30: 28 76 6f 69 64 20 2a 70 29 7b 0a 20 20 61 73 73  (void *p){.  ass
1b40: 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74  ert( sqlite3_mut
1b50: 65 78 5f 68 65 6c 64 28 70 63 61 63 68 65 31 2e  ex_held(pcache1.
1b60: 6d 75 74 65 78 29 20 29 3b 0a 20 20 69 66 28 20  mutex) );.  if( 
1b70: 70 3d 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a 20  p==0 ) return;. 
1b80: 20 69 66 28 20 70 3e 3d 70 63 61 63 68 65 31 2e   if( p>=pcache1.
1b90: 70 53 74 61 72 74 20 26 26 20 70 3c 70 63 61 63  pStart && p<pcac
1ba0: 68 65 31 2e 70 45 6e 64 20 29 7b 0a 20 20 20 20  he1.pEnd ){.    
1bb0: 50 67 46 72 65 65 73 6c 6f 74 20 2a 70 53 6c 6f  PgFreeslot *pSlo
1bc0: 74 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 53 74  t;.    sqlite3St
1bd0: 61 74 75 73 41 64 64 28 53 51 4c 49 54 45 5f 53  atusAdd(SQLITE_S
1be0: 54 41 54 55 53 5f 50 41 47 45 43 41 43 48 45 5f  TATUS_PAGECACHE_
1bf0: 55 53 45 44 2c 20 2d 31 29 3b 0a 20 20 20 20 70  USED, -1);.    p
1c00: 53 6c 6f 74 20 3d 20 28 50 67 46 72 65 65 73 6c  Slot = (PgFreesl
1c10: 6f 74 2a 29 70 3b 0a 20 20 20 20 70 53 6c 6f 74  ot*)p;.    pSlot
1c20: 2d 3e 70 4e 65 78 74 20 3d 20 70 63 61 63 68 65  ->pNext = pcache
1c30: 31 2e 70 46 72 65 65 3b 0a 20 20 20 20 70 63 61  1.pFree;.    pca
1c40: 63 68 65 31 2e 70 46 72 65 65 20 3d 20 70 53 6c  che1.pFree = pSl
1c50: 6f 74 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ot;.  }else{.   
1c60: 20 69 6e 74 20 69 53 69 7a 65 20 3d 20 73 71 6c   int iSize = sql
1c70: 69 74 65 33 4d 61 6c 6c 6f 63 53 69 7a 65 28 70  ite3MallocSize(p
1c80: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 53 74  );.    sqlite3St
1c90: 61 74 75 73 41 64 64 28 53 51 4c 49 54 45 5f 53  atusAdd(SQLITE_S
1ca0: 54 41 54 55 53 5f 50 41 47 45 43 41 43 48 45 5f  TATUS_PAGECACHE_
1cb0: 4f 56 45 52 46 4c 4f 57 2c 20 2d 69 53 69 7a 65  OVERFLOW, -iSize
1cc0: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66  );.    sqlite3_f
1cd0: 72 65 65 28 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f  ree(p);.  }.}../
1ce0: 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65 20 61 20  *.** Allocate a 
1cf0: 6e 65 77 20 70 61 67 65 20 6f 62 6a 65 63 74 20  new page object 
1d00: 69 6e 69 74 69 61 6c 6c 79 20 61 73 73 6f 63 69  initially associ
1d10: 61 74 65 64 20 77 69 74 68 20 63 61 63 68 65 20  ated with cache 
1d20: 70 43 61 63 68 65 2e 0a 2a 2f 0a 73 74 61 74 69  pCache..*/.stati
1d30: 63 20 50 67 48 64 72 31 20 2a 70 63 61 63 68 65  c PgHdr1 *pcache
1d40: 31 41 6c 6c 6f 63 50 61 67 65 28 50 43 61 63 68  1AllocPage(PCach
1d50: 65 31 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 69  e1 *pCache){.  i
1d60: 6e 74 20 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f  nt nByte = sizeo
1d70: 66 28 50 67 48 64 72 31 29 20 2b 20 70 43 61 63  f(PgHdr1) + pCac
1d80: 68 65 2d 3e 73 7a 50 61 67 65 3b 0a 20 20 50 67  he->szPage;.  Pg
1d90: 48 64 72 31 20 2a 70 20 3d 20 28 50 67 48 64 72  Hdr1 *p = (PgHdr
1da0: 31 20 2a 29 70 63 61 63 68 65 31 41 6c 6c 6f 63  1 *)pcache1Alloc
1db0: 28 6e 42 79 74 65 29 3b 0a 20 20 69 66 28 20 70  (nByte);.  if( p
1dc0: 20 29 7b 0a 20 20 20 20 69 66 28 20 70 43 61 63   ){.    if( pCac
1dd0: 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 29  he->bPurgeable )
1de0: 7b 0a 20 20 20 20 20 20 70 63 61 63 68 65 31 2e  {.      pcache1.
1df0: 6e 43 75 72 72 65 6e 74 50 61 67 65 2b 2b 3b 0a  nCurrentPage++;.
1e00: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75      }.  }.  retu
1e10: 72 6e 20 70 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46  rn p;.}../*.** F
1e20: 72 65 65 20 61 20 70 61 67 65 20 6f 62 6a 65 63  ree a page objec
1e30: 74 20 61 6c 6c 6f 63 61 74 65 64 20 62 79 20 70  t allocated by p
1e40: 63 61 63 68 65 31 41 6c 6c 6f 63 50 61 67 65 28  cache1AllocPage(
1e50: 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  )..*/.static voi
1e60: 64 20 70 63 61 63 68 65 31 46 72 65 65 50 61 67  d pcache1FreePag
1e70: 65 28 50 67 48 64 72 31 20 2a 70 29 7b 0a 20 20  e(PgHdr1 *p){.  
1e80: 69 66 28 20 70 20 29 7b 0a 20 20 20 20 69 66 28  if( p ){.    if(
1e90: 20 70 2d 3e 70 43 61 63 68 65 2d 3e 62 50 75 72   p->pCache->bPur
1ea0: 67 65 61 62 6c 65 20 29 7b 0a 20 20 20 20 20 20  geable ){.      
1eb0: 70 63 61 63 68 65 31 2e 6e 43 75 72 72 65 6e 74  pcache1.nCurrent
1ec0: 50 61 67 65 2d 2d 3b 0a 20 20 20 20 7d 0a 20 20  Page--;.    }.  
1ed0: 20 20 70 63 61 63 68 65 31 46 72 65 65 28 70 29    pcache1Free(p)
1ee0: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d  ;.  }.}../*.** M
1ef0: 61 6c 6c 6f 63 20 66 75 6e 63 74 69 6f 6e 20 75  alloc function u
1f00: 73 65 64 20 62 79 20 53 51 4c 69 74 65 20 74 6f  sed by SQLite to
1f10: 20 6f 62 74 61 69 6e 20 73 70 61 63 65 20 66 72   obtain space fr
1f20: 6f 6d 20 74 68 65 20 62 75 66 66 65 72 20 63 6f  om the buffer co
1f30: 6e 66 69 67 75 72 65 64 0a 2a 2a 20 75 73 69 6e  nfigured.** usin
1f40: 67 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67  g sqlite3_config
1f50: 28 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50  (SQLITE_CONFIG_P
1f60: 41 47 45 43 41 43 48 45 29 20 6f 70 74 69 6f 6e  AGECACHE) option
1f70: 2e 20 49 66 20 6e 6f 20 73 75 63 68 20 62 75 66  . If no such buf
1f80: 66 65 72 0a 2a 2a 20 65 78 69 73 74 73 2c 20 74  fer.** exists, t
1f90: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 66 61 6c  his function fal
1fa0: 6c 73 20 62 61 63 6b 20 74 6f 20 73 71 6c 69 74  ls back to sqlit
1fb0: 65 33 4d 61 6c 6c 6f 63 28 29 2e 0a 2a 2f 0a 76  e3Malloc()..*/.v
1fc0: 6f 69 64 20 2a 73 71 6c 69 74 65 33 50 61 67 65  oid *sqlite3Page
1fd0: 4d 61 6c 6c 6f 63 28 69 6e 74 20 73 7a 29 7b 0a  Malloc(int sz){.
1fe0: 20 20 76 6f 69 64 20 2a 70 3b 0a 20 20 70 63 61    void *p;.  pca
1ff0: 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 29  che1EnterMutex()
2000: 3b 0a 20 20 70 20 3d 20 70 63 61 63 68 65 31 41  ;.  p = pcache1A
2010: 6c 6c 6f 63 28 73 7a 29 3b 0a 20 20 70 63 61 63  lloc(sz);.  pcac
2020: 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 29 3b  he1LeaveMutex();
2030: 0a 20 20 72 65 74 75 72 6e 20 70 3b 0a 7d 0a 0a  .  return p;.}..
2040: 2f 2a 0a 2a 2a 20 46 72 65 65 20 61 6e 20 61 6c  /*.** Free an al
2050: 6c 6f 63 61 74 65 64 20 62 75 66 66 65 72 20 6f  located buffer o
2060: 62 74 61 69 6e 65 64 20 66 72 6f 6d 20 73 71 6c  btained from sql
2070: 69 74 65 33 50 61 67 65 4d 61 6c 6c 6f 63 28 29  ite3PageMalloc()
2080: 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
2090: 33 50 61 67 65 46 72 65 65 28 76 6f 69 64 20 2a  3PageFree(void *
20a0: 70 29 7b 0a 20 20 70 63 61 63 68 65 31 45 6e 74  p){.  pcache1Ent
20b0: 65 72 4d 75 74 65 78 28 29 3b 0a 20 20 70 63 61  erMutex();.  pca
20c0: 63 68 65 31 46 72 65 65 28 70 29 3b 0a 20 20 70  che1Free(p);.  p
20d0: 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78  cache1LeaveMutex
20e0: 28 29 3b 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a  ();.}../********
20f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2100: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2110: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2120: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2130: 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 2a 2a 2a 2a 2a 2a  ******/./*******
2140: 2a 20 47 65 6e 65 72 61 6c 20 49 6d 70 6c 65 6d  * General Implem
2150: 65 6e 74 61 74 69 6f 6e 20 46 75 6e 63 74 69 6f  entation Functio
2160: 6e 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ns *************
2170: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2180: 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f 2a 0a 2a 2a 20  *******/../*.** 
2190: 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73  This function is
21a0: 20 75 73 65 64 20 74 6f 20 72 65 73 69 7a 65 20   used to resize 
21b0: 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 20 75  the hash table u
21c0: 73 65 64 20 62 79 20 74 68 65 20 63 61 63 68 65  sed by the cache
21d0: 20 70 61 73 73 65 64 0a 2a 2a 20 61 73 20 74 68   passed.** as th
21e0: 65 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74  e first argument
21f0: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 67 6c 6f 62  ..**.** The glob
2200: 61 6c 20 6d 75 74 65 78 20 6d 75 73 74 20 62 65  al mutex must be
2210: 20 68 65 6c 64 20 77 68 65 6e 20 74 68 69 73 20   held when this 
2220: 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c  function is call
2230: 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ed..*/.static in
2240: 74 20 70 63 61 63 68 65 31 52 65 73 69 7a 65 48  t pcache1ResizeH
2250: 61 73 68 28 50 43 61 63 68 65 31 20 2a 70 29 7b  ash(PCache1 *p){
2260: 0a 20 20 50 67 48 64 72 31 20 2a 2a 61 70 4e 65  .  PgHdr1 **apNe
2270: 77 3b 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e  w;.  unsigned in
2280: 74 20 6e 4e 65 77 3b 0a 20 20 75 6e 73 69 67 6e  t nNew;.  unsign
2290: 65 64 20 69 6e 74 20 69 3b 0a 0a 20 20 61 73 73  ed int i;..  ass
22a0: 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74  ert( sqlite3_mut
22b0: 65 78 5f 68 65 6c 64 28 70 63 61 63 68 65 31 2e  ex_held(pcache1.
22c0: 6d 75 74 65 78 29 20 29 3b 0a 0a 20 20 6e 4e 65  mutex) );..  nNe
22d0: 77 20 3d 20 70 2d 3e 6e 48 61 73 68 2a 32 3b 0a  w = p->nHash*2;.
22e0: 20 20 69 66 28 20 6e 4e 65 77 3c 32 35 36 20 29    if( nNew<256 )
22f0: 7b 0a 20 20 20 20 6e 4e 65 77 20 3d 20 32 35 36  {.    nNew = 256
2300: 3b 0a 20 20 7d 0a 0a 20 20 70 63 61 63 68 65 31  ;.  }..  pcache1
2310: 4c 65 61 76 65 4d 75 74 65 78 28 29 3b 0a 20 20  LeaveMutex();.  
2320: 69 66 28 20 70 2d 3e 6e 48 61 73 68 20 29 7b 20  if( p->nHash ){ 
2330: 73 71 6c 69 74 65 33 42 65 67 69 6e 42 65 6e 69  sqlite3BeginBeni
2340: 67 6e 4d 61 6c 6c 6f 63 28 29 3b 20 7d 0a 20 20  gnMalloc(); }.  
2350: 61 70 4e 65 77 20 3d 20 28 50 67 48 64 72 31 20  apNew = (PgHdr1 
2360: 2a 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f  **)sqlite3_mallo
2370: 63 28 73 69 7a 65 6f 66 28 50 67 48 64 72 31 20  c(sizeof(PgHdr1 
2380: 2a 29 2a 6e 4e 65 77 29 3b 0a 20 20 69 66 28 20  *)*nNew);.  if( 
2390: 70 2d 3e 6e 48 61 73 68 20 29 7b 20 73 71 6c 69  p->nHash ){ sqli
23a0: 74 65 33 45 6e 64 42 65 6e 69 67 6e 4d 61 6c 6c  te3EndBenignMall
23b0: 6f 63 28 29 3b 20 7d 0a 20 20 70 63 61 63 68 65  oc(); }.  pcache
23c0: 31 45 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a 20  1EnterMutex();. 
23d0: 20 69 66 28 20 61 70 4e 65 77 20 29 7b 0a 20 20   if( apNew ){.  
23e0: 20 20 6d 65 6d 73 65 74 28 61 70 4e 65 77 2c 20    memset(apNew, 
23f0: 30 2c 20 73 69 7a 65 6f 66 28 50 67 48 64 72 31  0, sizeof(PgHdr1
2400: 20 2a 29 2a 6e 4e 65 77 29 3b 0a 20 20 20 20 66   *)*nNew);.    f
2410: 6f 72 28 69 3d 30 3b 20 69 3c 70 2d 3e 6e 48 61  or(i=0; i<p->nHa
2420: 73 68 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  sh; i++){.      
2430: 50 67 48 64 72 31 20 2a 70 50 61 67 65 3b 0a 20  PgHdr1 *pPage;. 
2440: 20 20 20 20 20 50 67 48 64 72 31 20 2a 70 4e 65       PgHdr1 *pNe
2450: 78 74 20 3d 20 70 2d 3e 61 70 48 61 73 68 5b 69  xt = p->apHash[i
2460: 5d 3b 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20  ];.      while( 
2470: 28 70 50 61 67 65 20 3d 20 70 4e 65 78 74 29 21  (pPage = pNext)!
2480: 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 75 6e  =0 ){.        un
2490: 73 69 67 6e 65 64 20 69 6e 74 20 68 20 3d 20 70  signed int h = p
24a0: 50 61 67 65 2d 3e 69 4b 65 79 20 25 20 6e 4e 65  Page->iKey % nNe
24b0: 77 3b 0a 20 20 20 20 20 20 20 20 70 4e 65 78 74  w;.        pNext
24c0: 20 3d 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 3b   = pPage->pNext;
24d0: 0a 20 20 20 20 20 20 20 20 70 50 61 67 65 2d 3e  .        pPage->
24e0: 70 4e 65 78 74 20 3d 20 61 70 4e 65 77 5b 68 5d  pNext = apNew[h]
24f0: 3b 0a 20 20 20 20 20 20 20 20 61 70 4e 65 77 5b  ;.        apNew[
2500: 68 5d 20 3d 20 70 50 61 67 65 3b 0a 20 20 20 20  h] = pPage;.    
2510: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 73 71    }.    }.    sq
2520: 6c 69 74 65 33 5f 66 72 65 65 28 70 2d 3e 61 70  lite3_free(p->ap
2530: 48 61 73 68 29 3b 0a 20 20 20 20 70 2d 3e 61 70  Hash);.    p->ap
2540: 48 61 73 68 20 3d 20 61 70 4e 65 77 3b 0a 20 20  Hash = apNew;.  
2550: 20 20 70 2d 3e 6e 48 61 73 68 20 3d 20 6e 4e 65    p->nHash = nNe
2560: 77 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e  w;.  }..  return
2570: 20 28 70 2d 3e 61 70 48 61 73 68 20 3f 20 53 51   (p->apHash ? SQ
2580: 4c 49 54 45 5f 4f 4b 20 3a 20 53 51 4c 49 54 45  LITE_OK : SQLITE
2590: 5f 4e 4f 4d 45 4d 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  _NOMEM);.}../*.*
25a0: 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  * This function 
25b0: 69 73 20 75 73 65 64 20 69 6e 74 65 72 6e 61 6c  is used internal
25c0: 6c 79 20 74 6f 20 72 65 6d 6f 76 65 20 74 68 65  ly to remove the
25d0: 20 70 61 67 65 20 70 50 61 67 65 20 66 72 6f 6d   page pPage from
25e0: 20 74 68 65 20 0a 2a 2a 20 67 6c 6f 62 61 6c 20   the .** global 
25f0: 4c 52 55 20 6c 69 73 74 2c 20 69 66 20 69 73 20  LRU list, if is 
2600: 70 61 72 74 20 6f 66 20 69 74 2e 20 49 66 20 70  part of it. If p
2610: 50 61 67 65 20 69 73 20 6e 6f 74 20 70 61 72 74  Page is not part
2620: 20 6f 66 20 74 68 65 20 67 6c 6f 62 61 6c 0a 2a   of the global.*
2630: 2a 20 4c 52 55 20 6c 69 73 74 2c 20 74 68 65 6e  * LRU list, then
2640: 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   this function i
2650: 73 20 61 20 6e 6f 2d 6f 70 2e 0a 2a 2a 0a 2a 2a  s a no-op..**.**
2660: 20 54 68 65 20 67 6c 6f 62 61 6c 20 6d 75 74 65   The global mute
2670: 78 20 6d 75 73 74 20 62 65 20 68 65 6c 64 20 77  x must be held w
2680: 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f  hen this functio
2690: 6e 20 69 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f 0a  n is called..*/.
26a0: 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63  static void pcac
26b0: 68 65 31 50 69 6e 50 61 67 65 28 50 67 48 64 72  he1PinPage(PgHdr
26c0: 31 20 2a 70 50 61 67 65 29 7b 0a 20 20 61 73 73  1 *pPage){.  ass
26d0: 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74  ert( sqlite3_mut
26e0: 65 78 5f 68 65 6c 64 28 70 63 61 63 68 65 31 2e  ex_held(pcache1.
26f0: 6d 75 74 65 78 29 20 29 3b 0a 20 20 69 66 28 20  mutex) );.  if( 
2700: 70 50 61 67 65 20 26 26 20 28 70 50 61 67 65 2d  pPage && (pPage-
2710: 3e 70 4c 72 75 4e 65 78 74 20 7c 7c 20 70 50 61  >pLruNext || pPa
2720: 67 65 3d 3d 70 63 61 63 68 65 31 2e 70 4c 72 75  ge==pcache1.pLru
2730: 54 61 69 6c 29 20 29 7b 0a 20 20 20 20 69 66 28  Tail) ){.    if(
2740: 20 70 50 61 67 65 2d 3e 70 4c 72 75 50 72 65 76   pPage->pLruPrev
2750: 20 29 7b 0a 20 20 20 20 20 20 70 50 61 67 65 2d   ){.      pPage-
2760: 3e 70 4c 72 75 50 72 65 76 2d 3e 70 4c 72 75 4e  >pLruPrev->pLruN
2770: 65 78 74 20 3d 20 70 50 61 67 65 2d 3e 70 4c 72  ext = pPage->pLr
2780: 75 4e 65 78 74 3b 0a 20 20 20 20 7d 0a 20 20 20  uNext;.    }.   
2790: 20 69 66 28 20 70 50 61 67 65 2d 3e 70 4c 72 75   if( pPage->pLru
27a0: 4e 65 78 74 20 29 7b 0a 20 20 20 20 20 20 70 50  Next ){.      pP
27b0: 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 2d 3e 70  age->pLruNext->p
27c0: 4c 72 75 50 72 65 76 20 3d 20 70 50 61 67 65 2d  LruPrev = pPage-
27d0: 3e 70 4c 72 75 50 72 65 76 3b 0a 20 20 20 20 7d  >pLruPrev;.    }
27e0: 0a 20 20 20 20 69 66 28 20 70 63 61 63 68 65 31  .    if( pcache1
27f0: 2e 70 4c 72 75 48 65 61 64 3d 3d 70 50 61 67 65  .pLruHead==pPage
2800: 20 29 7b 0a 20 20 20 20 20 20 70 63 61 63 68 65   ){.      pcache
2810: 31 2e 70 4c 72 75 48 65 61 64 20 3d 20 70 50 61  1.pLruHead = pPa
2820: 67 65 2d 3e 70 4c 72 75 4e 65 78 74 3b 0a 20 20  ge->pLruNext;.  
2830: 20 20 7d 0a 20 20 20 20 69 66 28 20 70 63 61 63    }.    if( pcac
2840: 68 65 31 2e 70 4c 72 75 54 61 69 6c 3d 3d 70 50  he1.pLruTail==pP
2850: 61 67 65 20 29 7b 0a 20 20 20 20 20 20 70 63 61  age ){.      pca
2860: 63 68 65 31 2e 70 4c 72 75 54 61 69 6c 20 3d 20  che1.pLruTail = 
2870: 70 50 61 67 65 2d 3e 70 4c 72 75 50 72 65 76 3b  pPage->pLruPrev;
2880: 0a 20 20 20 20 7d 0a 20 20 20 20 70 50 61 67 65  .    }.    pPage
2890: 2d 3e 70 4c 72 75 4e 65 78 74 20 3d 20 30 3b 0a  ->pLruNext = 0;.
28a0: 20 20 20 20 70 50 61 67 65 2d 3e 70 4c 72 75 50      pPage->pLruP
28b0: 72 65 76 20 3d 20 30 3b 0a 20 20 20 20 70 50 61  rev = 0;.    pPa
28c0: 67 65 2d 3e 70 43 61 63 68 65 2d 3e 6e 52 65 63  ge->pCache->nRec
28d0: 79 63 6c 61 62 6c 65 2d 2d 3b 0a 20 20 7d 0a 7d  yclable--;.  }.}
28e0: 0a 0a 0a 2f 2a 0a 2a 2a 20 52 65 6d 6f 76 65 20  .../*.** Remove 
28f0: 74 68 65 20 70 61 67 65 20 73 75 70 70 6c 69 65  the page supplie
2900: 64 20 61 73 20 61 6e 20 61 72 67 75 6d 65 6e 74  d as an argument
2910: 20 66 72 6f 6d 20 74 68 65 20 68 61 73 68 20 74   from the hash t
2920: 61 62 6c 65 20 0a 2a 2a 20 28 50 43 61 63 68 65  able .** (PCache
2930: 31 2e 61 70 48 61 73 68 20 73 74 72 75 63 74 75  1.apHash structu
2940: 72 65 29 20 74 68 61 74 20 69 74 20 69 73 20 63  re) that it is c
2950: 75 72 72 65 6e 74 6c 79 20 73 74 6f 72 65 64 20  urrently stored 
2960: 69 6e 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 67 6c  in..**.** The gl
2970: 6f 62 61 6c 20 6d 75 74 65 78 20 6d 75 73 74 20  obal mutex must 
2980: 62 65 20 68 65 6c 64 20 77 68 65 6e 20 74 68 69  be held when thi
2990: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61  s function is ca
29a0: 6c 6c 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  lled..*/.static 
29b0: 76 6f 69 64 20 70 63 61 63 68 65 31 52 65 6d 6f  void pcache1Remo
29c0: 76 65 46 72 6f 6d 48 61 73 68 28 50 67 48 64 72  veFromHash(PgHdr
29d0: 31 20 2a 70 50 61 67 65 29 7b 0a 20 20 75 6e 73  1 *pPage){.  uns
29e0: 69 67 6e 65 64 20 69 6e 74 20 68 3b 0a 20 20 50  igned int h;.  P
29f0: 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d  Cache1 *pCache =
2a00: 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65 3b 0a   pPage->pCache;.
2a10: 20 20 50 67 48 64 72 31 20 2a 2a 70 70 3b 0a 0a    PgHdr1 **pp;..
2a20: 20 20 68 20 3d 20 70 50 61 67 65 2d 3e 69 4b 65    h = pPage->iKe
2a30: 79 20 25 20 70 43 61 63 68 65 2d 3e 6e 48 61 73  y % pCache->nHas
2a40: 68 3b 0a 20 20 66 6f 72 28 70 70 3d 26 70 43 61  h;.  for(pp=&pCa
2a50: 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 20  che->apHash[h]; 
2a60: 28 2a 70 70 29 21 3d 70 50 61 67 65 3b 20 70 70  (*pp)!=pPage; pp
2a70: 3d 26 28 2a 70 70 29 2d 3e 70 4e 65 78 74 29 3b  =&(*pp)->pNext);
2a80: 0a 20 20 2a 70 70 20 3d 20 28 2a 70 70 29 2d 3e  .  *pp = (*pp)->
2a90: 70 4e 65 78 74 3b 0a 0a 20 20 70 43 61 63 68 65  pNext;..  pCache
2aa0: 2d 3e 6e 50 61 67 65 2d 2d 3b 0a 7d 0a 0a 2f 2a  ->nPage--;.}../*
2ab0: 0a 2a 2a 20 49 66 20 74 68 65 72 65 20 61 72 65  .** If there are
2ac0: 20 63 75 72 72 65 6e 74 6c 79 20 6d 6f 72 65 20   currently more 
2ad0: 74 68 61 6e 20 70 63 61 63 68 65 2e 6e 4d 61 78  than pcache.nMax
2ae0: 50 61 67 65 20 70 61 67 65 73 20 61 6c 6c 6f 63  Page pages alloc
2af0: 61 74 65 64 2c 20 74 72 79 0a 2a 2a 20 74 6f 20  ated, try.** to 
2b00: 72 65 63 79 63 6c 65 20 70 61 67 65 73 20 74 6f  recycle pages to
2b10: 20 72 65 64 75 63 65 20 74 68 65 20 6e 75 6d 62   reduce the numb
2b20: 65 72 20 61 6c 6c 6f 63 61 74 65 64 20 74 6f 20  er allocated to 
2b30: 70 63 61 63 68 65 2e 6e 4d 61 78 50 61 67 65 2e  pcache.nMaxPage.
2b40: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
2b50: 70 63 61 63 68 65 31 45 6e 66 6f 72 63 65 4d 61  pcache1EnforceMa
2b60: 78 50 61 67 65 28 76 6f 69 64 29 7b 0a 20 20 61  xPage(void){.  a
2b70: 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d  ssert( sqlite3_m
2b80: 75 74 65 78 5f 68 65 6c 64 28 70 63 61 63 68 65  utex_held(pcache
2b90: 31 2e 6d 75 74 65 78 29 20 29 3b 0a 20 20 77 68  1.mutex) );.  wh
2ba0: 69 6c 65 28 20 70 63 61 63 68 65 31 2e 6e 43 75  ile( pcache1.nCu
2bb0: 72 72 65 6e 74 50 61 67 65 3e 70 63 61 63 68 65  rrentPage>pcache
2bc0: 31 2e 6e 4d 61 78 50 61 67 65 20 26 26 20 70 63  1.nMaxPage && pc
2bd0: 61 63 68 65 31 2e 70 4c 72 75 54 61 69 6c 20 29  ache1.pLruTail )
2be0: 7b 0a 20 20 20 20 50 67 48 64 72 31 20 2a 70 20  {.    PgHdr1 *p 
2bf0: 3d 20 70 63 61 63 68 65 31 2e 70 4c 72 75 54 61  = pcache1.pLruTa
2c00: 69 6c 3b 0a 20 20 20 20 70 63 61 63 68 65 31 50  il;.    pcache1P
2c10: 69 6e 50 61 67 65 28 70 29 3b 0a 20 20 20 20 70  inPage(p);.    p
2c20: 63 61 63 68 65 31 52 65 6d 6f 76 65 46 72 6f 6d  cache1RemoveFrom
2c30: 48 61 73 68 28 70 29 3b 0a 20 20 20 20 70 63 61  Hash(p);.    pca
2c40: 63 68 65 31 46 72 65 65 50 61 67 65 28 70 29 3b  che1FreePage(p);
2c50: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 69  .  }.}../*.** Di
2c60: 73 63 61 72 64 20 61 6c 6c 20 70 61 67 65 73 20  scard all pages 
2c70: 66 72 6f 6d 20 63 61 63 68 65 20 70 43 61 63 68  from cache pCach
2c80: 65 20 77 69 74 68 20 61 20 70 61 67 65 20 6e 75  e with a page nu
2c90: 6d 62 65 72 20 28 6b 65 79 20 76 61 6c 75 65 29  mber (key value)
2ca0: 20 0a 2a 2a 20 67 72 65 61 74 65 72 20 74 68 61   .** greater tha
2cb0: 6e 20 6f 72 20 65 71 75 61 6c 20 74 6f 20 69 4c  n or equal to iL
2cc0: 69 6d 69 74 2e 20 41 6e 79 20 70 69 6e 6e 65 64  imit. Any pinned
2cd0: 20 70 61 67 65 73 20 74 68 61 74 20 6d 65 65 74   pages that meet
2ce0: 20 74 68 69 73 20 0a 2a 2a 20 63 72 69 74 65 72   this .** criter
2cf0: 69 61 20 61 72 65 20 75 6e 70 69 6e 6e 65 64 20  ia are unpinned 
2d00: 62 65 66 6f 72 65 20 74 68 65 79 20 61 72 65 20  before they are 
2d10: 64 69 73 63 61 72 64 65 64 2e 0a 2a 2a 0a 2a 2a  discarded..**.**
2d20: 20 54 68 65 20 67 6c 6f 62 61 6c 20 6d 75 74 65   The global mute
2d30: 78 20 6d 75 73 74 20 62 65 20 68 65 6c 64 20 77  x must be held w
2d40: 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f  hen this functio
2d50: 6e 20 69 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f 0a  n is called..*/.
2d60: 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63  static void pcac
2d70: 68 65 31 54 72 75 6e 63 61 74 65 55 6e 73 61 66  he1TruncateUnsaf
2d80: 65 28 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43  e(.  PCache1 *pC
2d90: 61 63 68 65 2c 20 0a 20 20 75 6e 73 69 67 6e 65  ache, .  unsigne
2da0: 64 20 69 6e 74 20 69 4c 69 6d 69 74 20 0a 29 7b  d int iLimit .){
2db0: 0a 20 20 54 45 53 54 4f 4e 4c 59 28 20 69 6e 74  .  TESTONLY( int
2dc0: 20 6e 50 61 67 65 20 3d 20 30 3b 20 29 20 20 20   nPage = 0; )   
2dd0: 20 20 20 2f 2a 20 55 73 65 64 20 74 6f 20 61 73     /* Used to as
2de0: 73 65 72 74 20 70 43 61 63 68 65 2d 3e 6e 50 61  sert pCache->nPa
2df0: 67 65 20 69 73 20 63 6f 72 72 65 63 74 20 2a 2f  ge is correct */
2e00: 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  .  unsigned int 
2e10: 68 3b 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c  h;.  assert( sql
2e20: 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28  ite3_mutex_held(
2e30: 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29 20 29  pcache1.mutex) )
2e40: 3b 0a 20 20 66 6f 72 28 68 3d 30 3b 20 68 3c 70  ;.  for(h=0; h<p
2e50: 43 61 63 68 65 2d 3e 6e 48 61 73 68 3b 20 68 2b  Cache->nHash; h+
2e60: 2b 29 7b 0a 20 20 20 20 50 67 48 64 72 31 20 2a  +){.    PgHdr1 *
2e70: 2a 70 70 20 3d 20 26 70 43 61 63 68 65 2d 3e 61  *pp = &pCache->a
2e80: 70 48 61 73 68 5b 68 5d 3b 20 0a 20 20 20 20 50  pHash[h]; .    P
2e90: 67 48 64 72 31 20 2a 70 50 61 67 65 3b 0a 20 20  gHdr1 *pPage;.  
2ea0: 20 20 77 68 69 6c 65 28 20 28 70 50 61 67 65 20    while( (pPage 
2eb0: 3d 20 2a 70 70 29 21 3d 30 20 29 7b 0a 20 20 20  = *pp)!=0 ){.   
2ec0: 20 20 20 69 66 28 20 70 50 61 67 65 2d 3e 69 4b     if( pPage->iK
2ed0: 65 79 3e 3d 69 4c 69 6d 69 74 20 29 7b 0a 20 20  ey>=iLimit ){.  
2ee0: 20 20 20 20 20 20 70 43 61 63 68 65 2d 3e 6e 50        pCache->nP
2ef0: 61 67 65 2d 2d 3b 0a 20 20 20 20 20 20 20 20 2a  age--;.        *
2f00: 70 70 20 3d 20 70 50 61 67 65 2d 3e 70 4e 65 78  pp = pPage->pNex
2f10: 74 3b 0a 20 20 20 20 20 20 20 20 70 63 61 63 68  t;.        pcach
2f20: 65 31 50 69 6e 50 61 67 65 28 70 50 61 67 65 29  e1PinPage(pPage)
2f30: 3b 0a 20 20 20 20 20 20 20 20 70 63 61 63 68 65  ;.        pcache
2f40: 31 46 72 65 65 50 61 67 65 28 70 50 61 67 65 29  1FreePage(pPage)
2f50: 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20  ;.      }else{. 
2f60: 20 20 20 20 20 20 20 70 70 20 3d 20 26 70 50 61         pp = &pPa
2f70: 67 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20  ge->pNext;.     
2f80: 20 20 20 54 45 53 54 4f 4e 4c 59 28 20 6e 50 61     TESTONLY( nPa
2f90: 67 65 2b 2b 3b 20 29 0a 20 20 20 20 20 20 7d 0a  ge++; ).      }.
2fa0: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 61 73 73 65      }.  }.  asse
2fb0: 72 74 28 20 70 43 61 63 68 65 2d 3e 6e 50 61 67  rt( pCache->nPag
2fc0: 65 3d 3d 6e 50 61 67 65 20 29 3b 0a 7d 0a 0a 2f  e==nPage );.}../
2fd0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2fe0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2ff0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3000: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3010: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a  **************/.
3020: 2f 2a 2a 2a 2a 2a 2a 2a 2a 20 73 71 6c 69 74 65  /******** sqlite
3030: 33 5f 70 63 61 63 68 65 20 4d 65 74 68 6f 64 73  3_pcache Methods
3040: 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a   ***************
3050: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3060: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f  ***************/
3070: 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e  ../*.** Implemen
3080: 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71  tation of the sq
3090: 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78 49 6e  lite3_pcache.xIn
30a0: 69 74 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74  it method..*/.st
30b0: 61 74 69 63 20 69 6e 74 20 70 63 61 63 68 65 31  atic int pcache1
30c0: 49 6e 69 74 28 76 6f 69 64 20 2a 4e 6f 74 55 73  Init(void *NotUs
30d0: 65 64 29 7b 0a 20 20 55 4e 55 53 45 44 5f 50 41  ed){.  UNUSED_PA
30e0: 52 41 4d 45 54 45 52 28 4e 6f 74 55 73 65 64 29  RAMETER(NotUsed)
30f0: 3b 0a 20 20 6d 65 6d 73 65 74 28 26 70 63 61 63  ;.  memset(&pcac
3100: 68 65 31 2c 20 30 2c 20 73 69 7a 65 6f 66 28 70  he1, 0, sizeof(p
3110: 63 61 63 68 65 31 29 29 3b 0a 20 20 69 66 28 20  cache1));.  if( 
3120: 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e  sqlite3GlobalCon
3130: 66 69 67 2e 62 43 6f 72 65 4d 75 74 65 78 20 29  fig.bCoreMutex )
3140: 7b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 6d 75  {.    pcache1.mu
3150: 74 65 78 20 3d 20 73 71 6c 69 74 65 33 5f 6d 75  tex = sqlite3_mu
3160: 74 65 78 5f 61 6c 6c 6f 63 28 53 51 4c 49 54 45  tex_alloc(SQLITE
3170: 5f 4d 55 54 45 58 5f 53 54 41 54 49 43 5f 4c 52  _MUTEX_STATIC_LR
3180: 55 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  U);.  }.  return
3190: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f   SQLITE_OK;.}../
31a0: 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74  *.** Implementat
31b0: 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74  ion of the sqlit
31c0: 65 33 5f 70 63 61 63 68 65 2e 78 53 68 75 74 64  e3_pcache.xShutd
31d0: 6f 77 6e 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73  own method..*/.s
31e0: 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68  tatic void pcach
31f0: 65 31 53 68 75 74 64 6f 77 6e 28 76 6f 69 64 20  e1Shutdown(void 
3200: 2a 4e 6f 74 55 73 65 64 29 7b 0a 20 20 55 4e 55  *NotUsed){.  UNU
3210: 53 45 44 5f 50 41 52 41 4d 45 54 45 52 28 4e 6f  SED_PARAMETER(No
3220: 74 55 73 65 64 29 3b 0a 20 20 2f 2a 20 6e 6f 2d  tUsed);.  /* no-
3230: 6f 70 20 2a 2f 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49  op */.}../*.** I
3240: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66  mplementation of
3250: 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61   the sqlite3_pca
3260: 63 68 65 2e 78 43 72 65 61 74 65 20 6d 65 74 68  che.xCreate meth
3270: 6f 64 2e 0a 2a 2a 0a 2a 2a 20 41 6c 6c 6f 63 61  od..**.** Alloca
3280: 74 65 20 61 20 6e 65 77 20 63 61 63 68 65 2e 0a  te a new cache..
3290: 2a 2f 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65  */.static sqlite
32a0: 33 5f 70 63 61 63 68 65 20 2a 70 63 61 63 68 65  3_pcache *pcache
32b0: 31 43 72 65 61 74 65 28 69 6e 74 20 73 7a 50 61  1Create(int szPa
32c0: 67 65 2c 20 69 6e 74 20 62 50 75 72 67 65 61 62  ge, int bPurgeab
32d0: 6c 65 29 7b 0a 20 20 50 43 61 63 68 65 31 20 2a  le){.  PCache1 *
32e0: 70 43 61 63 68 65 3b 0a 0a 20 20 70 43 61 63 68  pCache;..  pCach
32f0: 65 20 3d 20 28 50 43 61 63 68 65 31 20 2a 29 73  e = (PCache1 *)s
3300: 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69  qlite3_malloc(si
3310: 7a 65 6f 66 28 50 43 61 63 68 65 31 29 29 3b 0a  zeof(PCache1));.
3320: 20 20 69 66 28 20 70 43 61 63 68 65 20 29 7b 0a    if( pCache ){.
3330: 20 20 20 20 6d 65 6d 73 65 74 28 70 43 61 63 68      memset(pCach
3340: 65 2c 20 30 2c 20 73 69 7a 65 6f 66 28 50 43 61  e, 0, sizeof(PCa
3350: 63 68 65 31 29 29 3b 0a 20 20 20 20 70 43 61 63  che1));.    pCac
3360: 68 65 2d 3e 73 7a 50 61 67 65 20 3d 20 73 7a 50  he->szPage = szP
3370: 61 67 65 3b 0a 20 20 20 20 70 43 61 63 68 65 2d  age;.    pCache-
3380: 3e 62 50 75 72 67 65 61 62 6c 65 20 3d 20 28 62  >bPurgeable = (b
3390: 50 75 72 67 65 61 62 6c 65 20 3f 20 31 20 3a 20  Purgeable ? 1 : 
33a0: 30 29 3b 0a 20 20 20 20 69 66 28 20 62 50 75 72  0);.    if( bPur
33b0: 67 65 61 62 6c 65 20 29 7b 0a 20 20 20 20 20 20  geable ){.      
33c0: 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 20 3d 20 31  pCache->nMin = 1
33d0: 30 3b 0a 20 20 20 20 20 20 70 63 61 63 68 65 31  0;.      pcache1
33e0: 45 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a 20 20  EnterMutex();.  
33f0: 20 20 20 20 70 63 61 63 68 65 31 2e 6e 4d 69 6e      pcache1.nMin
3400: 50 61 67 65 20 2b 3d 20 70 43 61 63 68 65 2d 3e  Page += pCache->
3410: 6e 4d 69 6e 3b 0a 20 20 20 20 20 20 70 63 61 63  nMin;.      pcac
3420: 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 29 3b  he1LeaveMutex();
3430: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74  .    }.  }.  ret
3440: 75 72 6e 20 28 73 71 6c 69 74 65 33 5f 70 63 61  urn (sqlite3_pca
3450: 63 68 65 20 2a 29 70 43 61 63 68 65 3b 0a 7d 0a  che *)pCache;.}.
3460: 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74  ./*.** Implement
3470: 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c  ation of the sql
3480: 69 74 65 33 5f 70 63 61 63 68 65 2e 78 43 61 63  ite3_pcache.xCac
3490: 68 65 73 69 7a 65 20 6d 65 74 68 6f 64 2e 20 0a  hesize method. .
34a0: 2a 2a 0a 2a 2a 20 43 6f 6e 66 69 67 75 72 65 20  **.** Configure 
34b0: 74 68 65 20 63 61 63 68 65 5f 73 69 7a 65 20 6c  the cache_size l
34c0: 69 6d 69 74 20 66 6f 72 20 61 20 63 61 63 68 65  imit for a cache
34d0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
34e0: 20 70 63 61 63 68 65 31 43 61 63 68 65 73 69 7a   pcache1Cachesiz
34f0: 65 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  e(sqlite3_pcache
3500: 20 2a 70 2c 20 69 6e 74 20 6e 4d 61 78 29 7b 0a   *p, int nMax){.
3510: 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68    PCache1 *pCach
3520: 65 20 3d 20 28 50 43 61 63 68 65 31 20 2a 29 70  e = (PCache1 *)p
3530: 3b 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e  ;.  if( pCache->
3540: 62 50 75 72 67 65 61 62 6c 65 20 29 7b 0a 20 20  bPurgeable ){.  
3550: 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75    pcache1EnterMu
3560: 74 65 78 28 29 3b 0a 20 20 20 20 70 63 61 63 68  tex();.    pcach
3570: 65 31 2e 6e 4d 61 78 50 61 67 65 20 2b 3d 20 28  e1.nMaxPage += (
3580: 6e 4d 61 78 20 2d 20 70 43 61 63 68 65 2d 3e 6e  nMax - pCache->n
3590: 4d 61 78 29 3b 0a 20 20 20 20 70 43 61 63 68 65  Max);.    pCache
35a0: 2d 3e 6e 4d 61 78 20 3d 20 6e 4d 61 78 3b 0a 20  ->nMax = nMax;. 
35b0: 20 20 20 70 63 61 63 68 65 31 45 6e 66 6f 72 63     pcache1Enforc
35c0: 65 4d 61 78 50 61 67 65 28 29 3b 0a 20 20 20 20  eMaxPage();.    
35d0: 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65  pcache1LeaveMute
35e0: 78 28 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a  x();.  }.}../*.*
35f0: 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  * Implementation
3600: 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f   of the sqlite3_
3610: 70 63 61 63 68 65 2e 78 50 61 67 65 63 6f 75 6e  pcache.xPagecoun
3620: 74 20 6d 65 74 68 6f 64 2e 20 0a 2a 2f 0a 73 74  t method. .*/.st
3630: 61 74 69 63 20 69 6e 74 20 70 63 61 63 68 65 31  atic int pcache1
3640: 50 61 67 65 63 6f 75 6e 74 28 73 71 6c 69 74 65  Pagecount(sqlite
3650: 33 5f 70 63 61 63 68 65 20 2a 70 29 7b 0a 20 20  3_pcache *p){.  
3660: 69 6e 74 20 6e 3b 0a 20 20 70 63 61 63 68 65 31  int n;.  pcache1
3670: 45 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a 20 20  EnterMutex();.  
3680: 6e 20 3d 20 28 28 50 43 61 63 68 65 31 20 2a 29  n = ((PCache1 *)
3690: 70 29 2d 3e 6e 50 61 67 65 3b 0a 20 20 70 63 61  p)->nPage;.  pca
36a0: 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 29  che1LeaveMutex()
36b0: 3b 0a 20 20 72 65 74 75 72 6e 20 6e 3b 0a 7d 0a  ;.  return n;.}.
36c0: 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74  ./*.** Implement
36d0: 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c  ation of the sql
36e0: 69 74 65 33 5f 70 63 61 63 68 65 2e 78 46 65 74  ite3_pcache.xFet
36f0: 63 68 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a  ch method. .**.*
3700: 2a 20 46 65 74 63 68 20 61 20 70 61 67 65 20 62  * Fetch a page b
3710: 79 20 6b 65 79 20 76 61 6c 75 65 2e 0a 2a 2a 0a  y key value..**.
3720: 2a 2a 20 57 68 65 74 68 65 72 20 6f 72 20 6e 6f  ** Whether or no
3730: 74 20 61 20 6e 65 77 20 70 61 67 65 20 6d 61 79  t a new page may
3740: 20 62 65 20 61 6c 6c 6f 63 61 74 65 64 20 62 79   be allocated by
3750: 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 64   this function d
3760: 65 70 65 6e 64 73 20 6f 6e 0a 2a 2a 20 74 68 65  epends on.** the
3770: 20 76 61 6c 75 65 20 6f 66 20 74 68 65 20 63 72   value of the cr
3780: 65 61 74 65 46 6c 61 67 20 61 72 67 75 6d 65 6e  eateFlag argumen
3790: 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 72 65 20 61  t..**.** There a
37a0: 72 65 20 74 68 72 65 65 20 64 69 66 66 65 72 65  re three differe
37b0: 6e 74 20 61 70 70 72 6f 61 63 68 65 73 20 74 6f  nt approaches to
37c0: 20 6f 62 74 61 69 6e 69 6e 67 20 73 70 61 63 65   obtaining space
37d0: 20 66 6f 72 20 61 20 70 61 67 65 2c 0a 2a 2a 20   for a page,.** 
37e0: 64 65 70 65 6e 64 69 6e 67 20 6f 6e 20 74 68 65  depending on the
37f0: 20 76 61 6c 75 65 20 6f 66 20 70 61 72 61 6d 65   value of parame
3800: 74 65 72 20 63 72 65 61 74 65 46 6c 61 67 20 28  ter createFlag (
3810: 77 68 69 63 68 20 6d 61 79 20 62 65 20 30 2c 20  which may be 0, 
3820: 31 20 6f 72 20 32 29 2e 0a 2a 2a 0a 2a 2a 20 20  1 or 2)..**.**  
3830: 20 31 2e 20 52 65 67 61 72 64 6c 65 73 73 20 6f   1. Regardless o
3840: 66 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20 63  f the value of c
3850: 72 65 61 74 65 46 6c 61 67 2c 20 74 68 65 20 63  reateFlag, the c
3860: 61 63 68 65 20 69 73 20 73 65 61 72 63 68 65 64  ache is searched
3870: 20 66 6f 72 20 61 20 0a 2a 2a 20 20 20 20 20 20   for a .**      
3880: 63 6f 70 79 20 6f 66 20 74 68 65 20 72 65 71 75  copy of the requ
3890: 65 73 74 65 64 20 70 61 67 65 2e 20 49 66 20 6f  ested page. If o
38a0: 6e 65 20 69 73 20 66 6f 75 6e 64 2c 20 69 74 20  ne is found, it 
38b0: 69 73 20 72 65 74 75 72 6e 65 64 2e 0a 2a 2a 0a  is returned..**.
38c0: 2a 2a 20 20 20 32 2e 20 49 66 20 63 72 65 61 74  **   2. If creat
38d0: 65 46 6c 61 67 3d 3d 30 20 61 6e 64 20 74 68 65  eFlag==0 and the
38e0: 20 70 61 67 65 20 69 73 20 6e 6f 74 20 61 6c 72   page is not alr
38f0: 65 61 64 79 20 69 6e 20 74 68 65 20 63 61 63 68  eady in the cach
3900: 65 2c 20 4e 55 4c 4c 20 69 73 0a 2a 2a 20 20 20  e, NULL is.**   
3910: 20 20 20 72 65 74 75 72 6e 65 64 2e 0a 2a 2a 0a     returned..**.
3920: 2a 2a 20 20 20 33 2e 20 49 66 20 63 72 65 61 74  **   3. If creat
3930: 65 46 6c 61 67 20 69 73 20 31 2c 20 74 68 65 20  eFlag is 1, the 
3940: 63 61 63 68 65 20 69 73 20 6d 61 72 6b 65 64 20  cache is marked 
3950: 61 73 20 70 75 72 67 65 61 62 6c 65 20 61 6e 64  as purgeable and
3960: 20 74 68 65 20 70 61 67 65 20 69 73 20 0a 2a 2a   the page is .**
3970: 20 20 20 20 20 20 6e 6f 74 20 61 6c 72 65 61 64        not alread
3980: 79 20 69 6e 20 74 68 65 20 63 61 63 68 65 2c 20  y in the cache, 
3990: 61 6e 64 20 69 66 20 65 69 74 68 65 72 20 6f 66  and if either of
39a0: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 61   the following a
39b0: 72 65 20 74 72 75 65 2c 20 0a 2a 2a 20 20 20 20  re true, .**    
39c0: 20 20 72 65 74 75 72 6e 20 4e 55 4c 4c 3a 0a 2a    return NULL:.*
39d0: 2a 0a 2a 2a 20 20 20 20 20 20 20 28 61 29 20 74  *.**       (a) t
39e0: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67  he number of pag
39f0: 65 73 20 70 69 6e 6e 65 64 20 62 79 20 74 68 65  es pinned by the
3a00: 20 63 61 63 68 65 20 69 73 20 67 72 65 61 74 65   cache is greate
3a10: 72 20 74 68 61 6e 0a 2a 2a 20 20 20 20 20 20 20  r than.**       
3a20: 20 20 20 20 50 43 61 63 68 65 31 2e 6e 4d 61 78      PCache1.nMax
3a30: 2c 20 6f 72 0a 2a 2a 20 20 20 20 20 20 20 28 62  , or.**       (b
3a40: 29 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  ) the number of 
3a50: 70 61 67 65 73 20 70 69 6e 6e 65 64 20 62 79 20  pages pinned by 
3a60: 74 68 65 20 63 61 63 68 65 20 69 73 20 67 72 65  the cache is gre
3a70: 61 74 65 72 20 74 68 61 6e 0a 2a 2a 20 20 20 20  ater than.**    
3a80: 20 20 20 20 20 20 20 74 68 65 20 73 75 6d 20 6f         the sum o
3a90: 66 20 6e 4d 61 78 20 66 6f 72 20 61 6c 6c 20 70  f nMax for all p
3aa0: 75 72 67 65 61 62 6c 65 20 63 61 63 68 65 73 2c  urgeable caches,
3ab0: 20 6c 65 73 73 20 74 68 65 20 73 75 6d 20 6f 66   less the sum of
3ac0: 20 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 6e   .**           n
3ad0: 4d 69 6e 20 66 6f 72 20 61 6c 6c 20 6f 74 68 65  Min for all othe
3ae0: 72 20 70 75 72 67 65 61 62 6c 65 20 63 61 63 68  r purgeable cach
3af0: 65 73 2e 20 0a 2a 2a 0a 2a 2a 20 20 20 34 2e 20  es. .**.**   4. 
3b00: 49 66 20 6e 6f 6e 65 20 6f 66 20 74 68 65 20 66  If none of the f
3b10: 69 72 73 74 20 74 68 72 65 65 20 63 6f 6e 64 69  irst three condi
3b20: 74 69 6f 6e 73 20 61 70 70 6c 79 20 61 6e 64 20  tions apply and 
3b30: 74 68 65 20 63 61 63 68 65 20 69 73 20 6d 61 72  the cache is mar
3b40: 6b 65 64 0a 2a 2a 20 20 20 20 20 20 61 73 20 70  ked.**      as p
3b50: 75 72 67 65 61 62 6c 65 2c 20 61 6e 64 20 69 66  urgeable, and if
3b60: 20 6f 6e 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c   one of the foll
3b70: 6f 77 69 6e 67 20 69 73 20 74 72 75 65 3a 0a 2a  owing is true:.*
3b80: 2a 0a 2a 2a 20 20 20 20 20 20 20 28 61 29 20 54  *.**       (a) T
3b90: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67  he number of pag
3ba0: 65 73 20 61 6c 6c 6f 63 61 74 65 64 20 66 6f 72  es allocated for
3bb0: 20 74 68 65 20 63 61 63 68 65 20 69 73 20 61 6c   the cache is al
3bc0: 72 65 61 64 79 20 0a 2a 2a 20 20 20 20 20 20 20  ready .**       
3bd0: 20 20 20 20 50 43 61 63 68 65 31 2e 6e 4d 61 78      PCache1.nMax
3be0: 2c 20 6f 72 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20  , or.**.**      
3bf0: 20 28 62 29 20 54 68 65 20 6e 75 6d 62 65 72 20   (b) The number 
3c00: 6f 66 20 70 61 67 65 73 20 61 6c 6c 6f 63 61 74  of pages allocat
3c10: 65 64 20 66 6f 72 20 61 6c 6c 20 70 75 72 67 65  ed for all purge
3c20: 61 62 6c 65 20 63 61 63 68 65 73 20 69 73 0a 2a  able caches is.*
3c30: 2a 20 20 20 20 20 20 20 20 20 20 20 61 6c 72 65  *           alre
3c40: 61 64 79 20 65 71 75 61 6c 20 74 6f 20 6f 72 20  ady equal to or 
3c50: 67 72 65 61 74 65 72 20 74 68 61 6e 20 74 68 65  greater than the
3c60: 20 73 75 6d 20 6f 66 20 6e 4d 61 78 20 66 6f 72   sum of nMax for
3c70: 20 61 6c 6c 0a 2a 2a 20 20 20 20 20 20 20 20 20   all.**         
3c80: 20 20 70 75 72 67 65 61 62 6c 65 20 63 61 63 68    purgeable cach
3c90: 65 73 2c 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 74  es,.**.**      t
3ca0: 68 65 6e 20 61 74 74 65 6d 70 74 20 74 6f 20 72  hen attempt to r
3cb0: 65 63 79 63 6c 65 20 61 20 70 61 67 65 20 66 72  ecycle a page fr
3cc0: 6f 6d 20 74 68 65 20 4c 52 55 20 6c 69 73 74 2e  om the LRU list.
3cd0: 20 49 66 20 69 74 20 69 73 20 74 68 65 20 72 69   If it is the ri
3ce0: 67 68 74 0a 2a 2a 20 20 20 20 20 20 73 69 7a 65  ght.**      size
3cf0: 2c 20 72 65 74 75 72 6e 20 74 68 65 20 72 65 63  , return the rec
3d00: 79 63 6c 65 64 20 62 75 66 66 65 72 2e 20 4f 74  ycled buffer. Ot
3d10: 68 65 72 77 69 73 65 2c 20 66 72 65 65 20 74 68  herwise, free th
3d20: 65 20 62 75 66 66 65 72 20 61 6e 64 0a 2a 2a 20  e buffer and.** 
3d30: 20 20 20 20 20 70 72 6f 63 65 65 64 20 74 6f 20       proceed to 
3d40: 73 74 65 70 20 35 2e 20 0a 2a 2a 0a 2a 2a 20 20  step 5. .**.**  
3d50: 20 35 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 61   5. Otherwise, a
3d60: 6c 6c 6f 63 61 74 65 20 61 6e 64 20 72 65 74 75  llocate and retu
3d70: 72 6e 20 61 20 6e 65 77 20 70 61 67 65 20 62 75  rn a new page bu
3d80: 66 66 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ffer..*/.static 
3d90: 76 6f 69 64 20 2a 70 63 61 63 68 65 31 46 65 74  void *pcache1Fet
3da0: 63 68 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68  ch(sqlite3_pcach
3db0: 65 20 2a 70 2c 20 75 6e 73 69 67 6e 65 64 20 69  e *p, unsigned i
3dc0: 6e 74 20 69 4b 65 79 2c 20 69 6e 74 20 63 72 65  nt iKey, int cre
3dd0: 61 74 65 46 6c 61 67 29 7b 0a 20 20 75 6e 73 69  ateFlag){.  unsi
3de0: 67 6e 65 64 20 69 6e 74 20 6e 50 69 6e 6e 65 64  gned int nPinned
3df0: 3b 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43 61  ;.  PCache1 *pCa
3e00: 63 68 65 20 3d 20 28 50 43 61 63 68 65 31 20 2a  che = (PCache1 *
3e10: 29 70 3b 0a 20 20 50 67 48 64 72 31 20 2a 70 50  )p;.  PgHdr1 *pP
3e20: 61 67 65 20 3d 20 30 3b 0a 0a 20 20 70 63 61 63  age = 0;..  pcac
3e30: 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 29 3b  he1EnterMutex();
3e40: 0a 20 20 69 66 28 20 63 72 65 61 74 65 46 6c 61  .  if( createFla
3e50: 67 3d 3d 31 20 29 20 73 71 6c 69 74 65 33 42 65  g==1 ) sqlite3Be
3e60: 67 69 6e 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28  ginBenignMalloc(
3e70: 29 3b 0a 0a 20 20 2f 2a 20 53 65 61 72 63 68 20  );..  /* Search 
3e80: 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 20 66  the hash table f
3e90: 6f 72 20 61 6e 20 65 78 69 73 74 69 6e 67 20 65  or an existing e
3ea0: 6e 74 72 79 2e 20 2a 2f 0a 20 20 69 66 28 20 70  ntry. */.  if( p
3eb0: 43 61 63 68 65 2d 3e 6e 48 61 73 68 3e 30 20 29  Cache->nHash>0 )
3ec0: 7b 0a 20 20 20 20 75 6e 73 69 67 6e 65 64 20 69  {.    unsigned i
3ed0: 6e 74 20 68 20 3d 20 69 4b 65 79 20 25 20 70 43  nt h = iKey % pC
3ee0: 61 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 20  ache->nHash;.   
3ef0: 20 66 6f 72 28 70 50 61 67 65 3d 70 43 61 63 68   for(pPage=pCach
3f00: 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 20 70 50  e->apHash[h]; pP
3f10: 61 67 65 26 26 70 50 61 67 65 2d 3e 69 4b 65 79  age&&pPage->iKey
3f20: 21 3d 69 4b 65 79 3b 20 70 50 61 67 65 3d 70 50  !=iKey; pPage=pP
3f30: 61 67 65 2d 3e 70 4e 65 78 74 29 3b 0a 20 20 7d  age->pNext);.  }
3f40: 0a 0a 20 20 69 66 28 20 70 50 61 67 65 20 7c 7c  ..  if( pPage ||
3f50: 20 63 72 65 61 74 65 46 6c 61 67 3d 3d 30 20 29   createFlag==0 )
3f60: 7b 0a 20 20 20 20 70 63 61 63 68 65 31 50 69 6e  {.    pcache1Pin
3f70: 50 61 67 65 28 70 50 61 67 65 29 3b 0a 20 20 20  Page(pPage);.   
3f80: 20 67 6f 74 6f 20 66 65 74 63 68 5f 6f 75 74 3b   goto fetch_out;
3f90: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53 74 65 70 20  .  }..  /* Step 
3fa0: 33 20 6f 66 20 68 65 61 64 65 72 20 63 6f 6d 6d  3 of header comm
3fb0: 65 6e 74 2e 20 2a 2f 0a 20 20 6e 50 69 6e 6e 65  ent. */.  nPinne
3fc0: 64 20 3d 20 70 43 61 63 68 65 2d 3e 6e 50 61 67  d = pCache->nPag
3fd0: 65 20 2d 20 70 43 61 63 68 65 2d 3e 6e 52 65 63  e - pCache->nRec
3fe0: 79 63 6c 61 62 6c 65 3b 0a 20 20 69 66 28 20 63  yclable;.  if( c
3ff0: 72 65 61 74 65 46 6c 61 67 3d 3d 31 20 26 26 20  reateFlag==1 && 
4000: 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62  pCache->bPurgeab
4010: 6c 65 20 26 26 20 28 0a 20 20 20 20 20 20 20 20  le && (.        
4020: 6e 50 69 6e 6e 65 64 3e 3d 28 70 63 61 63 68 65  nPinned>=(pcache
4030: 31 2e 6e 4d 61 78 50 61 67 65 2b 70 43 61 63 68  1.nMaxPage+pCach
4040: 65 2d 3e 6e 4d 69 6e 2d 70 63 61 63 68 65 31 2e  e->nMin-pcache1.
4050: 6e 4d 69 6e 50 61 67 65 29 0a 20 20 20 20 20 7c  nMinPage).     |
4060: 7c 20 6e 50 69 6e 6e 65 64 3e 3d 28 70 43 61 63  | nPinned>=(pCac
4070: 68 65 2d 3e 6e 4d 61 78 20 2a 20 39 20 2f 20 31  he->nMax * 9 / 1
4080: 30 29 0a 20 20 29 29 7b 0a 20 20 20 20 67 6f 74  0).  )){.    got
4090: 6f 20 66 65 74 63 68 5f 6f 75 74 3b 0a 20 20 7d  o fetch_out;.  }
40a0: 0a 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e  ..  if( pCache->
40b0: 6e 50 61 67 65 3e 3d 70 43 61 63 68 65 2d 3e 6e  nPage>=pCache->n
40c0: 48 61 73 68 20 26 26 20 70 63 61 63 68 65 31 52  Hash && pcache1R
40d0: 65 73 69 7a 65 48 61 73 68 28 70 43 61 63 68 65  esizeHash(pCache
40e0: 29 20 29 7b 0a 20 20 20 20 67 6f 74 6f 20 66 65  ) ){.    goto fe
40f0: 74 63 68 5f 6f 75 74 3b 0a 20 20 7d 0a 0a 20 20  tch_out;.  }..  
4100: 2f 2a 20 53 74 65 70 20 34 2e 20 54 72 79 20 74  /* Step 4. Try t
4110: 6f 20 72 65 63 79 63 6c 65 20 61 20 70 61 67 65  o recycle a page
4120: 20 62 75 66 66 65 72 20 69 66 20 61 70 70 72 6f   buffer if appro
4130: 70 72 69 61 74 65 2e 20 2a 2f 0a 20 20 69 66 28  priate. */.  if(
4140: 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61   pCache->bPurgea
4150: 62 6c 65 20 26 26 20 70 63 61 63 68 65 31 2e 70  ble && pcache1.p
4160: 4c 72 75 54 61 69 6c 20 26 26 20 28 0a 20 20 20  LruTail && (.   
4170: 20 20 28 70 43 61 63 68 65 2d 3e 6e 50 61 67 65    (pCache->nPage
4180: 2b 31 3e 3d 70 43 61 63 68 65 2d 3e 6e 4d 61 78  +1>=pCache->nMax
4190: 29 20 7c 7c 20 70 63 61 63 68 65 31 2e 6e 43 75  ) || pcache1.nCu
41a0: 72 72 65 6e 74 50 61 67 65 3e 3d 70 63 61 63 68  rrentPage>=pcach
41b0: 65 31 2e 6e 4d 61 78 50 61 67 65 0a 20 20 29 29  e1.nMaxPage.  ))
41c0: 7b 0a 20 20 20 20 70 50 61 67 65 20 3d 20 70 63  {.    pPage = pc
41d0: 61 63 68 65 31 2e 70 4c 72 75 54 61 69 6c 3b 0a  ache1.pLruTail;.
41e0: 20 20 20 20 70 63 61 63 68 65 31 52 65 6d 6f 76      pcache1Remov
41f0: 65 46 72 6f 6d 48 61 73 68 28 70 50 61 67 65 29  eFromHash(pPage)
4200: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 50 69 6e  ;.    pcache1Pin
4210: 50 61 67 65 28 70 50 61 67 65 29 3b 0a 20 20 20  Page(pPage);.   
4220: 20 69 66 28 20 70 50 61 67 65 2d 3e 70 43 61 63   if( pPage->pCac
4230: 68 65 2d 3e 73 7a 50 61 67 65 21 3d 70 43 61 63  he->szPage!=pCac
4240: 68 65 2d 3e 73 7a 50 61 67 65 20 29 7b 0a 20 20  he->szPage ){.  
4250: 20 20 20 20 70 63 61 63 68 65 31 46 72 65 65 50      pcache1FreeP
4260: 61 67 65 28 70 50 61 67 65 29 3b 0a 20 20 20 20  age(pPage);.    
4270: 20 20 70 50 61 67 65 20 3d 20 30 3b 0a 20 20 20    pPage = 0;.   
4280: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 63   }else{.      pc
4290: 61 63 68 65 31 2e 6e 43 75 72 72 65 6e 74 50 61  ache1.nCurrentPa
42a0: 67 65 20 2d 3d 20 28 70 50 61 67 65 2d 3e 70 43  ge -= (pPage->pC
42b0: 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65  ache->bPurgeable
42c0: 20 2d 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67   - pCache->bPurg
42d0: 65 61 62 6c 65 29 3b 0a 20 20 20 20 7d 0a 20 20  eable);.    }.  
42e0: 7d 0a 0a 20 20 2f 2a 20 53 74 65 70 20 35 2e 20  }..  /* Step 5. 
42f0: 49 66 20 61 20 75 73 61 62 6c 65 20 70 61 67 65  If a usable page
4300: 20 62 75 66 66 65 72 20 68 61 73 20 73 74 69 6c   buffer has stil
4310: 6c 20 6e 6f 74 20 62 65 65 6e 20 66 6f 75 6e 64  l not been found
4320: 2c 20 0a 20 20 2a 2a 20 61 74 74 65 6d 70 74 20  , .  ** attempt 
4330: 74 6f 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e 65  to allocate a ne
4340: 77 20 6f 6e 65 2e 20 0a 20 20 2a 2f 0a 20 20 69  w one. .  */.  i
4350: 66 28 20 21 70 50 61 67 65 20 29 7b 0a 20 20 20  f( !pPage ){.   
4360: 20 70 50 61 67 65 20 3d 20 70 63 61 63 68 65 31   pPage = pcache1
4370: 41 6c 6c 6f 63 50 61 67 65 28 70 43 61 63 68 65  AllocPage(pCache
4380: 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 50  );.  }..  if( pP
4390: 61 67 65 20 29 7b 0a 20 20 20 20 75 6e 73 69 67  age ){.    unsig
43a0: 6e 65 64 20 69 6e 74 20 68 20 3d 20 69 4b 65 79  ned int h = iKey
43b0: 20 25 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68   % pCache->nHash
43c0: 3b 0a 20 20 20 20 2a 28 76 6f 69 64 20 2a 2a 29  ;.    *(void **)
43d0: 28 50 47 48 44 52 31 5f 54 4f 5f 50 41 47 45 28  (PGHDR1_TO_PAGE(
43e0: 70 50 61 67 65 29 29 20 3d 20 30 3b 0a 20 20 20  pPage)) = 0;.   
43f0: 20 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 2b 2b   pCache->nPage++
4400: 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 69 4b 65  ;.    pPage->iKe
4410: 79 20 3d 20 69 4b 65 79 3b 0a 20 20 20 20 70 50  y = iKey;.    pP
4420: 61 67 65 2d 3e 70 4e 65 78 74 20 3d 20 70 43 61  age->pNext = pCa
4430: 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 0a  che->apHash[h];.
4440: 20 20 20 20 70 50 61 67 65 2d 3e 70 43 61 63 68      pPage->pCach
4450: 65 20 3d 20 70 43 61 63 68 65 3b 0a 20 20 20 20  e = pCache;.    
4460: 70 50 61 67 65 2d 3e 70 4c 72 75 50 72 65 76 20  pPage->pLruPrev 
4470: 3d 20 30 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e  = 0;.    pPage->
4480: 70 4c 72 75 4e 65 78 74 20 3d 20 30 3b 0a 20 20  pLruNext = 0;.  
4490: 20 20 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68    pCache->apHash
44a0: 5b 68 5d 20 3d 20 70 50 61 67 65 3b 0a 20 20 7d  [h] = pPage;.  }
44b0: 0a 0a 66 65 74 63 68 5f 6f 75 74 3a 0a 20 20 69  ..fetch_out:.  i
44c0: 66 28 20 70 50 61 67 65 20 26 26 20 69 4b 65 79  f( pPage && iKey
44d0: 3e 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79  >pCache->iMaxKey
44e0: 20 29 7b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e   ){.    pCache->
44f0: 69 4d 61 78 4b 65 79 20 3d 20 69 4b 65 79 3b 0a  iMaxKey = iKey;.
4500: 20 20 7d 0a 20 20 69 66 28 20 63 72 65 61 74 65    }.  if( create
4510: 46 6c 61 67 3d 3d 31 20 29 20 73 71 6c 69 74 65  Flag==1 ) sqlite
4520: 33 45 6e 64 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63  3EndBenignMalloc
4530: 28 29 3b 0a 20 20 70 63 61 63 68 65 31 4c 65 61  ();.  pcache1Lea
4540: 76 65 4d 75 74 65 78 28 29 3b 0a 20 20 72 65 74  veMutex();.  ret
4550: 75 72 6e 20 28 70 50 61 67 65 20 3f 20 50 47 48  urn (pPage ? PGH
4560: 44 52 31 5f 54 4f 5f 50 41 47 45 28 70 50 61 67  DR1_TO_PAGE(pPag
4570: 65 29 20 3a 20 30 29 3b 0a 7d 0a 0a 0a 2f 2a 0a  e) : 0);.}.../*.
4580: 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  ** Implementatio
4590: 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33  n of the sqlite3
45a0: 5f 70 63 61 63 68 65 2e 78 55 6e 70 69 6e 20 6d  _pcache.xUnpin m
45b0: 65 74 68 6f 64 2e 0a 2a 2a 0a 2a 2a 20 4d 61 72  ethod..**.** Mar
45c0: 6b 20 61 20 70 61 67 65 20 61 73 20 75 6e 70 69  k a page as unpi
45d0: 6e 6e 65 64 20 28 65 6c 69 67 69 62 6c 65 20 66  nned (eligible f
45e0: 6f 72 20 61 73 79 6e 63 68 72 6f 6e 6f 75 73 20  or asynchronous 
45f0: 72 65 63 79 63 6c 69 6e 67 29 2e 0a 2a 2f 0a 73  recycling)..*/.s
4600: 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68  tatic void pcach
4610: 65 31 55 6e 70 69 6e 28 73 71 6c 69 74 65 33 5f  e1Unpin(sqlite3_
4620: 70 63 61 63 68 65 20 2a 70 2c 20 76 6f 69 64 20  pcache *p, void 
4630: 2a 70 50 67 2c 20 69 6e 74 20 72 65 75 73 65 55  *pPg, int reuseU
4640: 6e 6c 69 6b 65 6c 79 29 7b 0a 20 20 50 43 61 63  nlikely){.  PCac
4650: 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28 50  he1 *pCache = (P
4660: 43 61 63 68 65 31 20 2a 29 70 3b 0a 20 20 50 67  Cache1 *)p;.  Pg
4670: 48 64 72 31 20 2a 70 50 61 67 65 20 3d 20 50 41  Hdr1 *pPage = PA
4680: 47 45 5f 54 4f 5f 50 47 48 44 52 31 28 70 50 67  GE_TO_PGHDR1(pPg
4690: 29 3b 0a 0a 20 20 70 63 61 63 68 65 31 45 6e 74  );..  pcache1Ent
46a0: 65 72 4d 75 74 65 78 28 29 3b 0a 0a 20 20 2f 2a  erMutex();..  /*
46b0: 20 49 74 20 69 73 20 61 6e 20 65 72 72 6f 72 20   It is an error 
46c0: 74 6f 20 63 61 6c 6c 20 74 68 69 73 20 66 75 6e  to call this fun
46d0: 63 74 69 6f 6e 20 69 66 20 74 68 65 20 70 61 67  ction if the pag
46e0: 65 20 69 73 20 61 6c 72 65 61 64 79 20 0a 20 20  e is already .  
46f0: 2a 2a 20 70 61 72 74 20 6f 66 20 74 68 65 20 67  ** part of the g
4700: 6c 6f 62 61 6c 20 4c 52 55 20 6c 69 73 74 2e 0a  lobal LRU list..
4710: 20 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70    */.  assert( p
4720: 50 61 67 65 2d 3e 70 4c 72 75 50 72 65 76 3d 3d  Page->pLruPrev==
4730: 30 20 26 26 20 70 50 61 67 65 2d 3e 70 4c 72 75  0 && pPage->pLru
4740: 4e 65 78 74 3d 3d 30 20 29 3b 0a 20 20 61 73 73  Next==0 );.  ass
4750: 65 72 74 28 20 70 63 61 63 68 65 31 2e 70 4c 72  ert( pcache1.pLr
4760: 75 48 65 61 64 21 3d 70 50 61 67 65 20 26 26 20  uHead!=pPage && 
4770: 70 63 61 63 68 65 31 2e 70 4c 72 75 54 61 69 6c  pcache1.pLruTail
4780: 21 3d 70 50 61 67 65 20 29 3b 0a 0a 20 20 69 66  !=pPage );..  if
4790: 28 20 72 65 75 73 65 55 6e 6c 69 6b 65 6c 79 20  ( reuseUnlikely 
47a0: 7c 7c 20 70 63 61 63 68 65 31 2e 6e 43 75 72 72  || pcache1.nCurr
47b0: 65 6e 74 50 61 67 65 3e 70 63 61 63 68 65 31 2e  entPage>pcache1.
47c0: 6e 4d 61 78 50 61 67 65 20 29 7b 0a 20 20 20 20  nMaxPage ){.    
47d0: 70 63 61 63 68 65 31 52 65 6d 6f 76 65 46 72 6f  pcache1RemoveFro
47e0: 6d 48 61 73 68 28 70 50 61 67 65 29 3b 0a 20 20  mHash(pPage);.  
47f0: 20 20 70 63 61 63 68 65 31 46 72 65 65 50 61 67    pcache1FreePag
4800: 65 28 70 50 61 67 65 29 3b 0a 20 20 7d 65 6c 73  e(pPage);.  }els
4810: 65 7b 0a 20 20 20 20 2f 2a 20 41 64 64 20 74 68  e{.    /* Add th
4820: 65 20 70 61 67 65 20 74 6f 20 74 68 65 20 67 6c  e page to the gl
4830: 6f 62 61 6c 20 4c 52 55 20 6c 69 73 74 2e 20 4e  obal LRU list. N
4840: 6f 72 6d 61 6c 6c 79 2c 20 74 68 65 20 70 61 67  ormally, the pag
4850: 65 20 69 73 20 61 64 64 65 64 20 74 6f 0a 20 20  e is added to.  
4860: 20 20 2a 2a 20 74 68 65 20 68 65 61 64 20 6f 66    ** the head of
4870: 20 74 68 65 20 6c 69 73 74 20 28 6c 61 73 74 20   the list (last 
4880: 70 61 67 65 20 74 6f 20 62 65 20 72 65 63 79 63  page to be recyc
4890: 6c 65 64 29 2e 20 48 6f 77 65 76 65 72 2c 20 69  led). However, i
48a0: 66 20 74 68 65 20 0a 20 20 20 20 2a 2a 20 72 65  f the .    ** re
48b0: 75 73 65 55 6e 6c 69 6b 65 6c 79 20 66 6c 61 67  useUnlikely flag
48c0: 20 70 61 73 73 65 64 20 74 6f 20 74 68 69 73 20   passed to this 
48d0: 66 75 6e 63 74 69 6f 6e 20 69 73 20 74 72 75 65  function is true
48e0: 2c 20 74 68 65 20 70 61 67 65 20 69 73 20 61 64  , the page is ad
48f0: 64 65 64 0a 20 20 20 20 2a 2a 20 74 6f 20 74 68  ded.    ** to th
4900: 65 20 74 61 69 6c 20 6f 66 20 74 68 65 20 6c 69  e tail of the li
4910: 73 74 20 28 66 69 72 73 74 20 70 61 67 65 20 74  st (first page t
4920: 6f 20 62 65 20 72 65 63 79 63 6c 65 64 29 2e 0a  o be recycled)..
4930: 20 20 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 70      */.    if( p
4940: 63 61 63 68 65 31 2e 70 4c 72 75 48 65 61 64 20  cache1.pLruHead 
4950: 29 7b 0a 20 20 20 20 20 20 70 63 61 63 68 65 31  ){.      pcache1
4960: 2e 70 4c 72 75 48 65 61 64 2d 3e 70 4c 72 75 50  .pLruHead->pLruP
4970: 72 65 76 20 3d 20 70 50 61 67 65 3b 0a 20 20 20  rev = pPage;.   
4980: 20 20 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65     pPage->pLruNe
4990: 78 74 20 3d 20 70 63 61 63 68 65 31 2e 70 4c 72  xt = pcache1.pLr
49a0: 75 48 65 61 64 3b 0a 20 20 20 20 20 20 70 63 61  uHead;.      pca
49b0: 63 68 65 31 2e 70 4c 72 75 48 65 61 64 20 3d 20  che1.pLruHead = 
49c0: 70 50 61 67 65 3b 0a 20 20 20 20 7d 65 6c 73 65  pPage;.    }else
49d0: 7b 0a 20 20 20 20 20 20 70 63 61 63 68 65 31 2e  {.      pcache1.
49e0: 70 4c 72 75 54 61 69 6c 20 3d 20 70 50 61 67 65  pLruTail = pPage
49f0: 3b 0a 20 20 20 20 20 20 70 63 61 63 68 65 31 2e  ;.      pcache1.
4a00: 70 4c 72 75 48 65 61 64 20 3d 20 70 50 61 67 65  pLruHead = pPage
4a10: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 43 61 63  ;.    }.    pCac
4a20: 68 65 2d 3e 6e 52 65 63 79 63 6c 61 62 6c 65 2b  he->nRecyclable+
4a30: 2b 3b 0a 20 20 7d 0a 0a 20 20 70 63 61 63 68 65  +;.  }..  pcache
4a40: 31 4c 65 61 76 65 4d 75 74 65 78 28 29 3b 0a 7d  1LeaveMutex();.}
4a50: 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e  ../*.** Implemen
4a60: 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71  tation of the sq
4a70: 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78 52 65  lite3_pcache.xRe
4a80: 6b 65 79 20 6d 65 74 68 6f 64 2e 20 0a 2a 2f 0a  key method. .*/.
4a90: 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63  static void pcac
4aa0: 68 65 31 52 65 6b 65 79 28 0a 20 20 73 71 6c 69  he1Rekey(.  sqli
4ab0: 74 65 33 5f 70 63 61 63 68 65 20 2a 70 2c 0a 20  te3_pcache *p,. 
4ac0: 20 76 6f 69 64 20 2a 70 50 67 2c 0a 20 20 75 6e   void *pPg,.  un
4ad0: 73 69 67 6e 65 64 20 69 6e 74 20 69 4f 6c 64 2c  signed int iOld,
4ae0: 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  .  unsigned int 
4af0: 69 4e 65 77 0a 29 7b 0a 20 20 50 43 61 63 68 65  iNew.){.  PCache
4b00: 31 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61  1 *pCache = (PCa
4b10: 63 68 65 31 20 2a 29 70 3b 0a 20 20 50 67 48 64  che1 *)p;.  PgHd
4b20: 72 31 20 2a 70 50 61 67 65 20 3d 20 50 41 47 45  r1 *pPage = PAGE
4b30: 5f 54 4f 5f 50 47 48 44 52 31 28 70 50 67 29 3b  _TO_PGHDR1(pPg);
4b40: 0a 20 20 50 67 48 64 72 31 20 2a 2a 70 70 3b 0a  .  PgHdr1 **pp;.
4b50: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68    unsigned int h
4b60: 3b 20 0a 20 20 61 73 73 65 72 74 28 20 70 50 61  ; .  assert( pPa
4b70: 67 65 2d 3e 69 4b 65 79 3d 3d 69 4f 6c 64 20 29  ge->iKey==iOld )
4b80: 3b 0a 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65  ;..  pcache1Ente
4b90: 72 4d 75 74 65 78 28 29 3b 0a 0a 20 20 68 20 3d  rMutex();..  h =
4ba0: 20 69 4f 6c 64 25 70 43 61 63 68 65 2d 3e 6e 48   iOld%pCache->nH
4bb0: 61 73 68 3b 0a 20 20 70 70 20 3d 20 26 70 43 61  ash;.  pp = &pCa
4bc0: 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 0a  che->apHash[h];.
4bd0: 20 20 77 68 69 6c 65 28 20 28 2a 70 70 29 21 3d    while( (*pp)!=
4be0: 70 50 61 67 65 20 29 7b 0a 20 20 20 20 70 70 20  pPage ){.    pp 
4bf0: 3d 20 26 28 2a 70 70 29 2d 3e 70 4e 65 78 74 3b  = &(*pp)->pNext;
4c00: 0a 20 20 7d 0a 20 20 2a 70 70 20 3d 20 70 50 61  .  }.  *pp = pPa
4c10: 67 65 2d 3e 70 4e 65 78 74 3b 0a 0a 20 20 68 20  ge->pNext;..  h 
4c20: 3d 20 69 4e 65 77 25 70 43 61 63 68 65 2d 3e 6e  = iNew%pCache->n
4c30: 48 61 73 68 3b 0a 20 20 70 50 61 67 65 2d 3e 69  Hash;.  pPage->i
4c40: 4b 65 79 20 3d 20 69 4e 65 77 3b 0a 20 20 70 50  Key = iNew;.  pP
4c50: 61 67 65 2d 3e 70 4e 65 78 74 20 3d 20 70 43 61  age->pNext = pCa
4c60: 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 0a  che->apHash[h];.
4c70: 20 20 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68    pCache->apHash
4c80: 5b 68 5d 20 3d 20 70 50 61 67 65 3b 0a 0a 20 20  [h] = pPage;..  
4c90: 69 66 28 20 69 4e 65 77 3e 70 43 61 63 68 65 2d  if( iNew>pCache-
4ca0: 3e 69 4d 61 78 4b 65 79 20 29 7b 0a 20 20 20 20  >iMaxKey ){.    
4cb0: 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20  pCache->iMaxKey 
4cc0: 3d 20 69 4e 65 77 3b 0a 20 20 7d 0a 0a 20 20 70  = iNew;.  }..  p
4cd0: 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78  cache1LeaveMutex
4ce0: 28 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70  ();.}../*.** Imp
4cf0: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74  lementation of t
4d00: 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68  he sqlite3_pcach
4d10: 65 2e 78 54 72 75 6e 63 61 74 65 20 6d 65 74 68  e.xTruncate meth
4d20: 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20 44 69 73 63 61  od. .**.** Disca
4d30: 72 64 20 61 6c 6c 20 75 6e 70 69 6e 6e 65 64 20  rd all unpinned 
4d40: 70 61 67 65 73 20 69 6e 20 74 68 65 20 63 61 63  pages in the cac
4d50: 68 65 20 77 69 74 68 20 61 20 70 61 67 65 20 6e  he with a page n
4d60: 75 6d 62 65 72 20 65 71 75 61 6c 20 74 6f 0a 2a  umber equal to.*
4d70: 2a 20 6f 72 20 67 72 65 61 74 65 72 20 74 68 61  * or greater tha
4d80: 6e 20 70 61 72 61 6d 65 74 65 72 20 69 4c 69 6d  n parameter iLim
4d90: 69 74 2e 20 41 6e 79 20 70 69 6e 6e 65 64 20 70  it. Any pinned p
4da0: 61 67 65 73 20 77 69 74 68 20 61 20 70 61 67 65  ages with a page
4db0: 20 6e 75 6d 62 65 72 0a 2a 2a 20 65 71 75 61 6c   number.** equal
4dc0: 20 74 6f 20 6f 72 20 67 72 65 61 74 65 72 20 74   to or greater t
4dd0: 68 61 6e 20 69 4c 69 6d 69 74 20 61 72 65 20 69  han iLimit are i
4de0: 6d 70 6c 69 63 69 74 6c 79 20 75 6e 70 69 6e 6e  mplicitly unpinn
4df0: 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ed..*/.static vo
4e00: 69 64 20 70 63 61 63 68 65 31 54 72 75 6e 63 61  id pcache1Trunca
4e10: 74 65 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68  te(sqlite3_pcach
4e20: 65 20 2a 70 2c 20 75 6e 73 69 67 6e 65 64 20 69  e *p, unsigned i
4e30: 6e 74 20 69 4c 69 6d 69 74 29 7b 0a 20 20 50 43  nt iLimit){.  PC
4e40: 61 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20  ache1 *pCache = 
4e50: 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20 20  (PCache1 *)p;.  
4e60: 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65  pcache1EnterMute
4e70: 78 28 29 3b 0a 20 20 69 66 28 20 69 4c 69 6d 69  x();.  if( iLimi
4e80: 74 3c 3d 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b  t<=pCache->iMaxK
4e90: 65 79 20 29 7b 0a 20 20 20 20 70 63 61 63 68 65  ey ){.    pcache
4ea0: 31 54 72 75 6e 63 61 74 65 55 6e 73 61 66 65 28  1TruncateUnsafe(
4eb0: 70 43 61 63 68 65 2c 20 69 4c 69 6d 69 74 29 3b  pCache, iLimit);
4ec0: 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 69 4d 61  .    pCache->iMa
4ed0: 78 4b 65 79 20 3d 20 69 4c 69 6d 69 74 2d 31 3b  xKey = iLimit-1;
4ee0: 0a 20 20 7d 0a 20 20 70 63 61 63 68 65 31 4c 65  .  }.  pcache1Le
4ef0: 61 76 65 4d 75 74 65 78 28 29 3b 0a 7d 0a 0a 2f  aveMutex();.}../
4f00: 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74  *.** Implementat
4f10: 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74  ion of the sqlit
4f20: 65 33 5f 70 63 61 63 68 65 2e 78 44 65 73 74 72  e3_pcache.xDestr
4f30: 6f 79 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a  oy method. .**.*
4f40: 2a 20 44 65 73 74 72 6f 79 20 61 20 63 61 63 68  * Destroy a cach
4f50: 65 20 61 6c 6c 6f 63 61 74 65 64 20 75 73 69 6e  e allocated usin
4f60: 67 20 70 63 61 63 68 65 31 43 72 65 61 74 65 28  g pcache1Create(
4f70: 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  )..*/.static voi
4f80: 64 20 70 63 61 63 68 65 31 44 65 73 74 72 6f 79  d pcache1Destroy
4f90: 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20  (sqlite3_pcache 
4fa0: 2a 70 29 7b 0a 20 20 50 43 61 63 68 65 31 20 2a  *p){.  PCache1 *
4fb0: 70 43 61 63 68 65 20 3d 20 28 50 43 61 63 68 65  pCache = (PCache
4fc0: 31 20 2a 29 70 3b 0a 20 20 70 63 61 63 68 65 31  1 *)p;.  pcache1
4fd0: 45 6e 74 65 72 4d 75 74 65 78 28 29 3b 0a 20 20  EnterMutex();.  
4fe0: 70 63 61 63 68 65 31 54 72 75 6e 63 61 74 65 55  pcache1TruncateU
4ff0: 6e 73 61 66 65 28 70 43 61 63 68 65 2c 20 30 29  nsafe(pCache, 0)
5000: 3b 0a 20 20 70 63 61 63 68 65 31 2e 6e 4d 61 78  ;.  pcache1.nMax
5010: 50 61 67 65 20 2d 3d 20 70 43 61 63 68 65 2d 3e  Page -= pCache->
5020: 6e 4d 61 78 3b 0a 20 20 70 63 61 63 68 65 31 2e  nMax;.  pcache1.
5030: 6e 4d 69 6e 50 61 67 65 20 2d 3d 20 70 43 61 63  nMinPage -= pCac
5040: 68 65 2d 3e 6e 4d 69 6e 3b 0a 20 20 70 63 61 63  he->nMin;.  pcac
5050: 68 65 31 45 6e 66 6f 72 63 65 4d 61 78 50 61 67  he1EnforceMaxPag
5060: 65 28 29 3b 0a 20 20 70 63 61 63 68 65 31 4c 65  e();.  pcache1Le
5070: 61 76 65 4d 75 74 65 78 28 29 3b 0a 20 20 73 71  aveMutex();.  sq
5080: 6c 69 74 65 33 5f 66 72 65 65 28 70 43 61 63 68  lite3_free(pCach
5090: 65 2d 3e 61 70 48 61 73 68 29 3b 0a 20 20 73 71  e->apHash);.  sq
50a0: 6c 69 74 65 33 5f 66 72 65 65 28 70 43 61 63 68  lite3_free(pCach
50b0: 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69  e);.}../*.** Thi
50c0: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61  s function is ca
50d0: 6c 6c 65 64 20 64 75 72 69 6e 67 20 69 6e 69 74  lled during init
50e0: 69 61 6c 69 7a 61 74 69 6f 6e 20 28 73 71 6c 69  ialization (sqli
50f0: 74 65 33 5f 69 6e 69 74 69 61 6c 69 7a 65 28 29  te3_initialize()
5100: 29 20 74 6f 0a 2a 2a 20 69 6e 73 74 61 6c 6c 20  ) to.** install 
5110: 74 68 65 20 64 65 66 61 75 6c 74 20 70 6c 75 67  the default plug
5120: 67 61 62 6c 65 20 63 61 63 68 65 20 6d 6f 64 75  gable cache modu
5130: 6c 65 2c 20 61 73 73 75 6d 69 6e 67 20 74 68 65  le, assuming the
5140: 20 75 73 65 72 20 68 61 73 20 6e 6f 74 0a 2a 2a   user has not.**
5150: 20 61 6c 72 65 61 64 79 20 70 72 6f 76 69 64 65   already provide
5160: 64 20 61 6e 20 61 6c 74 65 72 6e 61 74 69 76 65  d an alternative
5170: 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
5180: 33 50 43 61 63 68 65 53 65 74 44 65 66 61 75 6c  3PCacheSetDefaul
5190: 74 28 76 6f 69 64 29 7b 0a 20 20 73 74 61 74 69  t(void){.  stati
51a0: 63 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  c sqlite3_pcache
51b0: 5f 6d 65 74 68 6f 64 73 20 64 65 66 61 75 6c 74  _methods default
51c0: 4d 65 74 68 6f 64 73 20 3d 20 7b 0a 20 20 20 20  Methods = {.    
51d0: 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0,              
51e0: 20 20 20 20 20 20 20 20 20 2f 2a 20 70 41 72 67           /* pArg
51f0: 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31 49   */.    pcache1I
5200: 6e 69 74 2c 20 20 20 20 20 20 20 20 20 20 20 20  nit,            
5210: 20 2f 2a 20 78 49 6e 69 74 20 2a 2f 0a 20 20 20   /* xInit */.   
5220: 20 70 63 61 63 68 65 31 53 68 75 74 64 6f 77 6e   pcache1Shutdown
5230: 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 78 53 68  ,         /* xSh
5240: 75 74 64 6f 77 6e 20 2a 2f 0a 20 20 20 20 70 63  utdown */.    pc
5250: 61 63 68 65 31 43 72 65 61 74 65 2c 20 20 20 20  ache1Create,    
5260: 20 20 20 20 20 20 20 2f 2a 20 78 43 72 65 61 74         /* xCreat
5270: 65 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31  e */.    pcache1
5280: 43 61 63 68 65 73 69 7a 65 2c 20 20 20 20 20 20  Cachesize,      
5290: 20 20 2f 2a 20 78 43 61 63 68 65 73 69 7a 65 20    /* xCachesize 
52a0: 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31 50 61  */.    pcache1Pa
52b0: 67 65 63 6f 75 6e 74 2c 20 20 20 20 20 20 20 20  gecount,        
52c0: 2f 2a 20 78 50 61 67 65 63 6f 75 6e 74 20 2a 2f  /* xPagecount */
52d0: 0a 20 20 20 20 70 63 61 63 68 65 31 46 65 74 63  .    pcache1Fetc
52e0: 68 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  h,            /*
52f0: 20 78 46 65 74 63 68 20 2a 2f 0a 20 20 20 20 70   xFetch */.    p
5300: 63 61 63 68 65 31 55 6e 70 69 6e 2c 20 20 20 20  cache1Unpin,    
5310: 20 20 20 20 20 20 20 20 2f 2a 20 78 55 6e 70 69          /* xUnpi
5320: 6e 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31  n */.    pcache1
5330: 52 65 6b 65 79 2c 20 20 20 20 20 20 20 20 20 20  Rekey,          
5340: 20 20 2f 2a 20 78 52 65 6b 65 79 20 2a 2f 0a 20    /* xRekey */. 
5350: 20 20 20 70 63 61 63 68 65 31 54 72 75 6e 63 61     pcache1Trunca
5360: 74 65 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 78  te,         /* x
5370: 54 72 75 6e 63 61 74 65 20 2a 2f 0a 20 20 20 20  Truncate */.    
5380: 70 63 61 63 68 65 31 44 65 73 74 72 6f 79 20 20  pcache1Destroy  
5390: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 65 73           /* xDes
53a0: 74 72 6f 79 20 2a 2f 0a 20 20 7d 3b 0a 20 20 73  troy */.  };.  s
53b0: 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67 28 53 51  qlite3_config(SQ
53c0: 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 43 41 43  LITE_CONFIG_PCAC
53d0: 48 45 2c 20 26 64 65 66 61 75 6c 74 4d 65 74 68  HE, &defaultMeth
53e0: 6f 64 73 29 3b 0a 7d 0a 0a 23 69 66 64 65 66 20  ods);.}..#ifdef 
53f0: 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45  SQLITE_ENABLE_ME
5400: 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 0a  MORY_MANAGEMENT.
5410: 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  /*.** This funct
5420: 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 74 6f  ion is called to
5430: 20 66 72 65 65 20 73 75 70 65 72 66 6c 75 6f 75   free superfluou
5440: 73 20 64 79 6e 61 6d 69 63 61 6c 6c 79 20 61 6c  s dynamically al
5450: 6c 6f 63 61 74 65 64 20 6d 65 6d 6f 72 79 0a 2a  located memory.*
5460: 2a 20 68 65 6c 64 20 62 79 20 74 68 65 20 70 61  * held by the pa
5470: 67 65 72 20 73 79 73 74 65 6d 2e 20 4d 65 6d 6f  ger system. Memo
5480: 72 79 20 69 6e 20 75 73 65 20 62 79 20 61 6e 79  ry in use by any
5490: 20 53 51 4c 69 74 65 20 70 61 67 65 72 20 61 6c   SQLite pager al
54a0: 6c 6f 63 61 74 65 64 0a 2a 2a 20 62 79 20 74 68  located.** by th
54b0: 65 20 63 75 72 72 65 6e 74 20 74 68 72 65 61 64  e current thread
54c0: 20 6d 61 79 20 62 65 20 73 71 6c 69 74 65 33 5f   may be sqlite3_
54d0: 66 72 65 65 28 29 65 64 2e 0a 2a 2a 0a 2a 2a 20  free()ed..**.** 
54e0: 6e 52 65 71 20 69 73 20 74 68 65 20 6e 75 6d 62  nReq is the numb
54f0: 65 72 20 6f 66 20 62 79 74 65 73 20 6f 66 20 6d  er of bytes of m
5500: 65 6d 6f 72 79 20 72 65 71 75 69 72 65 64 2e 20  emory required. 
5510: 4f 6e 63 65 20 74 68 69 73 20 6d 75 63 68 20 68  Once this much h
5520: 61 73 0a 2a 2a 20 62 65 65 6e 20 72 65 6c 65 61  as.** been relea
5530: 73 65 64 2c 20 74 68 65 20 66 75 6e 63 74 69 6f  sed, the functio
5540: 6e 20 72 65 74 75 72 6e 73 2e 20 54 68 65 20 72  n returns. The r
5550: 65 74 75 72 6e 20 76 61 6c 75 65 20 69 73 20 74  eturn value is t
5560: 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20  he total number 
5570: 0a 2a 2a 20 6f 66 20 62 79 74 65 73 20 6f 66 20  .** of bytes of 
5580: 6d 65 6d 6f 72 79 20 72 65 6c 65 61 73 65 64 2e  memory released.
5590: 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 50  .*/.int sqlite3P
55a0: 63 61 63 68 65 52 65 6c 65 61 73 65 4d 65 6d 6f  cacheReleaseMemo
55b0: 72 79 28 69 6e 74 20 6e 52 65 71 29 7b 0a 20 20  ry(int nReq){.  
55c0: 69 6e 74 20 6e 46 72 65 65 20 3d 20 30 3b 0a 20  int nFree = 0;. 
55d0: 20 69 66 28 20 70 63 61 63 68 65 31 2e 70 53 74   if( pcache1.pSt
55e0: 61 72 74 3d 3d 30 20 29 7b 0a 20 20 20 20 50 67  art==0 ){.    Pg
55f0: 48 64 72 31 20 2a 70 3b 0a 20 20 20 20 70 63 61  Hdr1 *p;.    pca
5600: 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 29  che1EnterMutex()
5610: 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 28 6e 52  ;.    while( (nR
5620: 65 71 3c 30 20 7c 7c 20 6e 46 72 65 65 3c 6e 52  eq<0 || nFree<nR
5630: 65 71 29 20 26 26 20 28 70 3d 70 63 61 63 68 65  eq) && (p=pcache
5640: 31 2e 70 4c 72 75 54 61 69 6c 29 20 29 7b 0a 20  1.pLruTail) ){. 
5650: 20 20 20 20 20 6e 46 72 65 65 20 2b 3d 20 73 71       nFree += sq
5660: 6c 69 74 65 33 4d 61 6c 6c 6f 63 53 69 7a 65 28  lite3MallocSize(
5670: 70 29 3b 0a 20 20 20 20 20 20 70 63 61 63 68 65  p);.      pcache
5680: 31 50 69 6e 50 61 67 65 28 70 29 3b 0a 20 20 20  1PinPage(p);.   
5690: 20 20 20 70 63 61 63 68 65 31 52 65 6d 6f 76 65     pcache1Remove
56a0: 46 72 6f 6d 48 61 73 68 28 70 29 3b 0a 20 20 20  FromHash(p);.   
56b0: 20 20 20 70 63 61 63 68 65 31 46 72 65 65 50 61     pcache1FreePa
56c0: 67 65 28 70 29 3b 0a 20 20 20 20 7d 0a 20 20 20  ge(p);.    }.   
56d0: 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74   pcache1LeaveMut
56e0: 65 78 28 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75  ex();.  }.  retu
56f0: 72 6e 20 6e 46 72 65 65 3b 0a 7d 0a 23 65 6e 64  rn nFree;.}.#end
5700: 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f 45 4e 41  if /* SQLITE_ENA
5710: 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47  BLE_MEMORY_MANAG
5720: 45 4d 45 4e 54 20 2a 2f 0a 0a 23 69 66 64 65 66  EMENT */..#ifdef
5730: 20 53 51 4c 49 54 45 5f 54 45 53 54 0a 2f 2a 0a   SQLITE_TEST./*.
5740: 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
5750: 20 69 73 20 75 73 65 64 20 62 79 20 74 65 73 74   is used by test
5760: 20 70 72 6f 63 65 64 75 72 65 73 20 74 6f 20 69   procedures to i
5770: 6e 73 70 65 63 74 20 74 68 65 20 69 6e 74 65 72  nspect the inter
5780: 6e 61 6c 20 73 74 61 74 65 0a 2a 2a 20 6f 66 20  nal state.** of 
5790: 74 68 65 20 67 6c 6f 62 61 6c 20 63 61 63 68 65  the global cache
57a0: 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
57b0: 33 50 63 61 63 68 65 53 74 61 74 73 28 0a 20 20  3PcacheStats(.  
57c0: 69 6e 74 20 2a 70 6e 43 75 72 72 65 6e 74 2c 20  int *pnCurrent, 
57d0: 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 54 6f 74       /* OUT: Tot
57e0: 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67  al number of pag
57f0: 65 73 20 63 61 63 68 65 64 20 2a 2f 0a 20 20 69  es cached */.  i
5800: 6e 74 20 2a 70 6e 4d 61 78 2c 20 20 20 20 20 20  nt *pnMax,      
5810: 20 20 20 20 2f 2a 20 4f 55 54 3a 20 47 6c 6f 62      /* OUT: Glob
5820: 61 6c 20 6d 61 78 69 6d 75 6d 20 63 61 63 68 65  al maximum cache
5830: 20 73 69 7a 65 20 2a 2f 0a 20 20 69 6e 74 20 2a   size */.  int *
5840: 70 6e 4d 69 6e 2c 20 20 20 20 20 20 20 20 20 20  pnMin,          
5850: 2f 2a 20 4f 55 54 3a 20 53 75 6d 20 6f 66 20 50  /* OUT: Sum of P
5860: 43 61 63 68 65 31 2e 6e 4d 69 6e 20 66 6f 72 20  Cache1.nMin for 
5870: 70 75 72 67 65 61 62 6c 65 20 63 61 63 68 65 73  purgeable caches
5880: 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 52 65 63   */.  int *pnRec
5890: 79 63 6c 61 62 6c 65 20 20 20 20 2f 2a 20 4f 55  yclable    /* OU
58a0: 54 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20  T: Total number 
58b0: 6f 66 20 70 61 67 65 73 20 61 76 61 69 6c 61 62  of pages availab
58c0: 6c 65 20 66 6f 72 20 72 65 63 79 63 6c 69 6e 67  le for recycling
58d0: 20 2a 2f 0a 29 7b 0a 20 20 50 67 48 64 72 31 20   */.){.  PgHdr1 
58e0: 2a 70 3b 0a 20 20 69 6e 74 20 6e 52 65 63 79 63  *p;.  int nRecyc
58f0: 6c 61 62 6c 65 20 3d 20 30 3b 0a 20 20 66 6f 72  lable = 0;.  for
5900: 28 70 3d 70 63 61 63 68 65 31 2e 70 4c 72 75 48  (p=pcache1.pLruH
5910: 65 61 64 3b 20 70 3b 20 70 3d 70 2d 3e 70 4c 72  ead; p; p=p->pLr
5920: 75 4e 65 78 74 29 7b 0a 20 20 20 20 6e 52 65 63  uNext){.    nRec
5930: 79 63 6c 61 62 6c 65 2b 2b 3b 0a 20 20 7d 0a 20  yclable++;.  }. 
5940: 20 2a 70 6e 43 75 72 72 65 6e 74 20 3d 20 70 63   *pnCurrent = pc
5950: 61 63 68 65 31 2e 6e 43 75 72 72 65 6e 74 50 61  ache1.nCurrentPa
5960: 67 65 3b 0a 20 20 2a 70 6e 4d 61 78 20 3d 20 70  ge;.  *pnMax = p
5970: 63 61 63 68 65 31 2e 6e 4d 61 78 50 61 67 65 3b  cache1.nMaxPage;
5980: 0a 20 20 2a 70 6e 4d 69 6e 20 3d 20 70 63 61 63  .  *pnMin = pcac
5990: 68 65 31 2e 6e 4d 69 6e 50 61 67 65 3b 0a 20 20  he1.nMinPage;.  
59a0: 2a 70 6e 52 65 63 79 63 6c 61 62 6c 65 20 3d 20  *pnRecyclable = 
59b0: 6e 52 65 63 79 63 6c 61 62 6c 65 3b 0a 7d 0a 23  nRecyclable;.}.#
59c0: 65 6e 64 69 66 0a                                endif.