/ Hex Artifact Content
Login

Artifact bf9fcea656dce1cd2cca6b77a1d1d3552050d55a31c98bf0d9f405930a83bc95:


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 64 65 6e 2c 20 74 68 65 6e 20 6e  erridden, then n
0290: 65 69 74 68 65 72 20 6f 66 0a 2a 2a 20 74 68 65  either of.** the
02a0: 73 65 20 74 77 6f 20 66 65 61 74 75 72 65 73 20  se two features 
02b0: 61 72 65 20 61 76 61 69 6c 61 62 6c 65 2e 0a 2a  are available..*
02c0: 2a 0a 2a 2a 20 41 20 50 61 67 65 20 63 61 63 68  *.** A Page cach
02d0: 65 20 6c 69 6e 65 20 6c 6f 6f 6b 73 20 6c 69 6b  e line looks lik
02e0: 65 20 74 68 69 73 3a 0a 2a 2a 0a 2a 2a 20 20 2d  e this:.**.**  -
02f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0300: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0310: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0320: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 2a 2a 20  ------------.** 
0330: 20 7c 20 20 64 61 74 61 62 61 73 65 20 70 61 67   |  database pag
0340: 65 20 63 6f 6e 74 65 6e 74 20 20 20 7c 20 20 50  e content   |  P
0350: 67 48 64 72 31 20 20 7c 20 20 4d 65 6d 50 61 67  gHdr1  |  MemPag
0360: 65 20 20 7c 20 20 50 67 48 64 72 20 20 7c 0a 2a  e  |  PgHdr  |.*
0370: 2a 20 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  *  -------------
0380: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0390: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
03a0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
03b0: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 64 61 74 61 62  .**.** The datab
03c0: 61 73 65 20 70 61 67 65 20 63 6f 6e 74 65 6e 74  ase page content
03d0: 20 69 73 20 75 70 20 66 72 6f 6e 74 20 28 73 6f   is up front (so
03e0: 20 74 68 61 74 20 62 75 66 66 65 72 20 6f 76 65   that buffer ove
03f0: 72 72 65 61 64 73 20 74 65 6e 64 20 74 6f 0a 2a  rreads tend to.*
0400: 2a 20 66 6c 6f 77 20 68 61 72 6d 6c 65 73 73 6c  * flow harmlessl
0410: 79 20 69 6e 74 6f 20 74 68 65 20 50 67 48 64 72  y into the PgHdr
0420: 31 2c 20 4d 65 6d 50 61 67 65 2c 20 61 6e 64 20  1, MemPage, and 
0430: 50 67 48 64 72 20 65 78 74 65 6e 73 69 6f 6e 73  PgHdr extensions
0440: 29 2e 20 20 20 4d 65 6d 50 61 67 65 0a 2a 2a 20  ).   MemPage.** 
0450: 69 73 20 74 68 65 20 65 78 74 65 6e 73 69 6f 6e  is the extension
0460: 20 61 64 64 65 64 20 62 79 20 74 68 65 20 62 74   added by the bt
0470: 72 65 65 2e 63 20 6d 6f 64 75 6c 65 20 63 6f 6e  ree.c module con
0480: 74 61 69 6e 69 6e 67 20 69 6e 66 6f 72 6d 61 74  taining informat
0490: 69 6f 6e 20 73 75 63 68 0a 2a 2a 20 61 73 20 74  ion such.** as t
04a0: 68 65 20 64 61 74 61 62 61 73 65 20 70 61 67 65  he database page
04b0: 20 6e 75 6d 62 65 72 20 61 6e 64 20 68 6f 77 20   number and how 
04c0: 74 68 61 74 20 64 61 74 61 62 61 73 65 20 70 61  that database pa
04d0: 67 65 20 69 73 20 75 73 65 64 2e 20 20 50 67 48  ge is used.  PgH
04e0: 64 72 0a 2a 2a 20 69 73 20 61 64 64 65 64 20 62  dr.** is added b
04f0: 79 20 74 68 65 20 70 63 61 63 68 65 2e 63 20 6c  y the pcache.c l
0500: 61 79 65 72 20 61 6e 64 20 63 6f 6e 74 61 69 6e  ayer and contain
0510: 73 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 75 73  s information us
0520: 65 64 20 74 6f 20 6b 65 65 70 20 74 72 61 63 6b  ed to keep track
0530: 0a 2a 2a 20 6f 66 20 77 68 69 63 68 20 70 61 67  .** of which pag
0540: 65 73 20 61 72 65 20 22 64 69 72 74 79 22 2e 20  es are "dirty". 
0550: 20 50 67 48 64 72 31 20 69 73 20 61 6e 20 65 78   PgHdr1 is an ex
0560: 74 65 6e 73 69 6f 6e 20 61 64 64 65 64 20 62 79  tension added by
0570: 20 74 68 69 73 0a 2a 2a 20 6d 6f 64 75 6c 65 20   this.** module 
0580: 28 70 63 61 63 68 65 31 2e 63 29 2e 20 20 54 68  (pcache1.c).  Th
0590: 65 20 50 67 48 64 72 31 20 68 65 61 64 65 72 20  e PgHdr1 header 
05a0: 69 73 20 61 20 73 75 62 63 6c 61 73 73 20 6f 66  is a subclass of
05b0: 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 5f   sqlite3_pcache_
05c0: 70 61 67 65 2e 0a 2a 2a 20 50 67 48 64 72 31 20  page..** PgHdr1 
05d0: 63 6f 6e 74 61 69 6e 73 20 69 6e 66 6f 72 6d 61  contains informa
05e0: 74 69 6f 6e 20 6e 65 65 64 65 64 20 74 6f 20 6c  tion needed to l
05f0: 6f 6f 6b 20 75 70 20 61 20 70 61 67 65 20 62 79  ook up a page by
0600: 20 69 74 73 20 70 61 67 65 20 6e 75 6d 62 65 72   its page number
0610: 2e 0a 2a 2a 20 54 68 65 20 73 75 70 65 72 63 6c  ..** The supercl
0620: 61 73 73 20 73 71 6c 69 74 65 33 5f 70 63 61 63  ass sqlite3_pcac
0630: 68 65 5f 70 61 67 65 2e 70 42 75 66 20 70 6f 69  he_page.pBuf poi
0640: 6e 74 73 20 74 6f 20 74 68 65 20 73 74 61 72 74  nts to the start
0650: 20 6f 66 20 74 68 65 0a 2a 2a 20 64 61 74 61 62   of the.** datab
0660: 61 73 65 20 70 61 67 65 20 63 6f 6e 74 65 6e 74  ase page content
0670: 20 61 6e 64 20 73 71 6c 69 74 65 33 5f 70 63 61   and sqlite3_pca
0680: 63 68 65 5f 70 61 67 65 2e 70 45 78 74 72 61 20  che_page.pExtra 
0690: 70 6f 69 6e 74 73 20 74 6f 20 50 67 48 64 72 2e  points to PgHdr.
06a0: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 73 69 7a 65 20  .**.** The size 
06b0: 6f 66 20 74 68 65 20 65 78 74 65 6e 73 69 6f 6e  of the extension
06c0: 20 28 4d 65 6d 50 61 67 65 2b 50 67 48 64 72 2b   (MemPage+PgHdr+
06d0: 50 67 48 64 72 31 29 20 63 61 6e 20 62 65 20 64  PgHdr1) can be d
06e0: 65 74 65 72 6d 69 6e 65 64 20 61 74 0a 2a 2a 20  etermined at.** 
06f0: 72 75 6e 74 69 6d 65 20 75 73 69 6e 67 20 73 71  runtime using sq
0700: 6c 69 74 65 33 5f 63 6f 6e 66 69 67 28 53 51 4c  lite3_config(SQL
0710: 49 54 45 5f 43 4f 4e 46 49 47 5f 50 43 41 43 48  ITE_CONFIG_PCACH
0720: 45 5f 48 44 52 53 5a 2c 20 26 73 69 7a 65 29 2e  E_HDRSZ, &size).
0730: 20 20 54 68 65 0a 2a 2a 20 73 69 7a 65 73 20 6f    The.** sizes o
0740: 66 20 74 68 65 20 65 78 74 65 6e 73 69 6f 6e 73  f the extensions
0750: 20 73 75 6d 20 74 6f 20 32 37 32 20 62 79 74 65   sum to 272 byte
0760: 73 20 6f 6e 20 78 36 34 20 66 6f 72 20 33 2e 38  s on x64 for 3.8
0770: 2e 31 30 2c 20 62 75 74 20 74 68 69 73 0a 2a 2a  .10, but this.**
0780: 20 73 69 7a 65 20 63 61 6e 20 76 61 72 79 20 61   size can vary a
0790: 63 63 6f 72 64 69 6e 67 20 74 6f 20 61 72 63 68  ccording to arch
07a0: 69 74 65 63 74 75 72 65 2c 20 63 6f 6d 70 69 6c  itecture, compil
07b0: 65 2d 74 69 6d 65 20 6f 70 74 69 6f 6e 73 2c 20  e-time options, 
07c0: 61 6e 64 0a 2a 2a 20 53 51 4c 69 74 65 20 6c 69  and.** SQLite li
07d0: 62 72 61 72 79 20 76 65 72 73 69 6f 6e 20 6e 75  brary version nu
07e0: 6d 62 65 72 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 53  mber..**.** If S
07f0: 51 4c 49 54 45 5f 50 43 41 43 48 45 5f 53 45 50  QLITE_PCACHE_SEP
0800: 41 52 41 54 45 5f 48 45 41 44 45 52 20 69 73 20  ARATE_HEADER is 
0810: 64 65 66 69 6e 65 64 2c 20 74 68 65 6e 20 74 68  defined, then th
0820: 65 20 65 78 74 65 6e 73 69 6f 6e 20 69 73 20 6f  e extension is o
0830: 62 74 61 69 6e 65 64 0a 2a 2a 20 75 73 69 6e 67  btained.** using
0840: 20 61 20 73 65 70 61 72 61 74 65 20 6d 65 6d 6f   a separate memo
0850: 72 79 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 66 72  ry allocation fr
0860: 6f 6d 20 74 68 65 20 64 61 74 61 62 61 73 65 20  om the database 
0870: 70 61 67 65 20 63 6f 6e 74 65 6e 74 2e 20 20 54  page content.  T
0880: 68 69 73 0a 2a 2a 20 73 65 65 6b 73 20 74 6f 20  his.** seeks to 
0890: 6f 76 65 72 63 6f 6d 65 20 74 68 65 20 22 63 6c  overcome the "cl
08a0: 6f 77 6e 73 68 6f 65 22 20 70 72 6f 62 6c 65 6d  ownshoe" problem
08b0: 20 28 61 6c 73 6f 20 63 61 6c 6c 65 64 20 22 69   (also called "i
08c0: 6e 74 65 72 6e 61 6c 0a 2a 2a 20 66 72 61 67 6d  nternal.** fragm
08d0: 65 6e 74 61 74 69 6f 6e 22 20 69 6e 20 61 63 61  entation" in aca
08e0: 64 65 6d 69 63 20 6c 69 74 65 72 61 74 75 72 65  demic literature
08f0: 29 20 6f 66 20 61 6c 6c 6f 63 61 74 69 6e 67 20  ) of allocating 
0900: 61 20 66 65 77 20 62 79 74 65 73 20 6d 6f 72 65  a few bytes more
0910: 0a 2a 2a 20 74 68 61 6e 20 61 20 70 6f 77 65 72  .** than a power
0920: 20 6f 66 20 74 77 6f 20 77 69 74 68 20 74 68 65   of two with the
0930: 20 6d 65 6d 6f 72 79 20 61 6c 6c 6f 63 61 74 6f   memory allocato
0940: 72 20 72 6f 75 6e 64 69 6e 67 20 75 70 20 74 6f  r rounding up to
0950: 20 74 68 65 20 6e 65 78 74 0a 2a 2a 20 70 6f 77   the next.** pow
0960: 65 72 20 6f 66 20 74 77 6f 2c 20 61 6e 64 20 6c  er of two, and l
0970: 65 61 76 69 6e 67 20 74 68 65 20 72 6f 75 6e 64  eaving the round
0980: 65 64 2d 75 70 20 73 70 61 63 65 20 75 6e 75 73  ed-up space unus
0990: 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 6d  ed..**.** This m
09a0: 6f 64 75 6c 65 20 74 72 61 63 6b 73 20 70 6f 69  odule tracks poi
09b0: 6e 74 65 72 73 20 74 6f 20 50 67 48 64 72 31 20  nters to PgHdr1 
09c0: 6f 62 6a 65 63 74 73 2e 20 20 4f 6e 6c 79 20 70  objects.  Only p
09d0: 63 61 63 68 65 2e 63 20 63 6f 6d 6d 75 6e 69 63  cache.c communic
09e0: 61 74 65 73 0a 2a 2a 20 77 69 74 68 20 74 68 69  ates.** with thi
09f0: 73 20 6d 6f 64 75 6c 65 2e 20 20 49 6e 66 6f 72  s module.  Infor
0a00: 6d 61 74 69 6f 6e 20 69 73 20 70 61 73 73 65 64  mation is passed
0a10: 20 62 61 63 6b 20 61 6e 64 20 66 6f 72 74 68 20   back and forth 
0a20: 61 73 20 50 67 48 64 72 31 20 70 6f 69 6e 74 65  as PgHdr1 pointe
0a30: 72 73 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 70 63  rs..**.** The pc
0a40: 61 63 68 65 2e 63 20 61 6e 64 20 70 61 67 65 72  ache.c and pager
0a50: 2e 63 20 6d 6f 64 75 6c 65 73 20 64 65 61 6c 20  .c modules deal 
0a60: 70 6f 69 6e 74 65 72 73 20 74 6f 20 50 67 48 64  pointers to PgHd
0a70: 72 20 6f 62 6a 65 63 74 73 2e 0a 2a 2a 20 54 68  r objects..** Th
0a80: 65 20 62 74 72 65 65 2e 63 20 6d 6f 64 75 6c 65  e btree.c module
0a90: 20 64 65 61 6c 73 20 77 69 74 68 20 70 6f 69 6e   deals with poin
0aa0: 74 65 72 73 20 74 6f 20 4d 65 6d 50 61 67 65 20  ters to MemPage 
0ab0: 6f 62 6a 65 63 74 73 2e 0a 2a 2a 0a 2a 2a 20 53  objects..**.** S
0ac0: 4f 55 52 43 45 20 4f 46 20 50 41 47 45 20 43 41  OURCE OF PAGE CA
0ad0: 43 48 45 20 4d 45 4d 4f 52 59 3a 0a 2a 2a 0a 2a  CHE MEMORY:.**.*
0ae0: 2a 20 4d 65 6d 6f 72 79 20 66 6f 72 20 61 20 70  * Memory for a p
0af0: 61 67 65 20 6d 69 67 68 74 20 63 6f 6d 65 20 66  age might come f
0b00: 72 6f 6d 20 61 6e 79 20 6f 66 20 74 68 72 65 65  rom any of three
0b10: 20 73 6f 75 72 63 65 73 3a 0a 2a 2a 0a 2a 2a 20   sources:.**.** 
0b20: 20 20 20 28 31 29 20 20 54 68 65 20 67 65 6e 65     (1)  The gene
0b30: 72 61 6c 2d 70 75 72 70 6f 73 65 20 6d 65 6d 6f  ral-purpose memo
0b40: 72 79 20 61 6c 6c 6f 63 61 74 6f 72 20 2d 20 73  ry allocator - s
0b50: 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 29 0a 2a  qlite3Malloc().*
0b60: 2a 20 20 20 20 28 32 29 20 20 47 6c 6f 62 61 6c  *    (2)  Global
0b70: 20 70 61 67 65 2d 63 61 63 68 65 20 6d 65 6d 6f   page-cache memo
0b80: 72 79 20 70 72 6f 76 69 64 65 64 20 75 73 69 6e  ry provided usin
0b90: 67 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67  g sqlite3_config
0ba0: 28 29 20 77 69 74 68 0a 2a 2a 20 20 20 20 20 20  () with.**      
0bb0: 20 20 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47     SQLITE_CONFIG
0bc0: 5f 50 41 47 45 43 41 43 48 45 2e 0a 2a 2a 20 20  _PAGECACHE..**  
0bd0: 20 20 28 33 29 20 20 50 43 61 63 68 65 2d 6c 6f    (3)  PCache-lo
0be0: 63 61 6c 20 62 75 6c 6b 20 61 6c 6c 6f 63 61 74  cal bulk allocat
0bf0: 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 74  ion..**.** The t
0c00: 68 69 72 64 20 63 61 73 65 20 69 73 20 61 20 63  hird case is a c
0c10: 68 75 6e 6b 20 6f 66 20 68 65 61 70 20 6d 65 6d  hunk of heap mem
0c20: 6f 72 79 20 28 64 65 66 61 75 6c 74 69 6e 67 20  ory (defaulting 
0c30: 74 6f 20 31 30 30 20 70 61 67 65 73 20 77 6f 72  to 100 pages wor
0c40: 74 68 29 0a 2a 2a 20 74 68 61 74 20 69 73 20 61  th).** that is a
0c50: 6c 6c 6f 63 61 74 65 64 20 77 68 65 6e 20 74 68  llocated when th
0c60: 65 20 70 61 67 65 20 63 61 63 68 65 20 69 73 20  e page cache is 
0c70: 63 72 65 61 74 65 64 2e 20 20 54 68 65 20 73 69  created.  The si
0c80: 7a 65 20 6f 66 20 74 68 65 20 6c 6f 63 61 6c 0a  ze of the local.
0c90: 2a 2a 20 62 75 6c 6b 20 61 6c 6c 6f 63 61 74 69  ** bulk allocati
0ca0: 6f 6e 20 63 61 6e 20 62 65 20 61 64 6a 75 73 74  on can be adjust
0cb0: 65 64 20 75 73 69 6e 67 20 0a 2a 2a 0a 2a 2a 20  ed using .**.** 
0cc0: 20 20 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66      sqlite3_conf
0cd0: 69 67 28 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47  ig(SQLITE_CONFIG
0ce0: 5f 50 41 47 45 43 41 43 48 45 2c 20 28 76 6f 69  _PAGECACHE, (voi
0cf0: 64 2a 29 30 2c 20 30 2c 20 4e 29 2e 0a 2a 2a 0a  d*)0, 0, N)..**.
0d00: 2a 2a 20 49 66 20 4e 20 69 73 20 70 6f 73 69 74  ** If N is posit
0d10: 69 76 65 2c 20 74 68 65 6e 20 4e 20 70 61 67 65  ive, then N page
0d20: 73 20 77 6f 72 74 68 20 6f 66 20 6d 65 6d 6f 72  s worth of memor
0d30: 79 20 61 72 65 20 61 6c 6c 6f 63 61 74 65 64 20  y are allocated 
0d40: 75 73 69 6e 67 20 61 20 73 69 6e 67 6c 65 0a 2a  using a single.*
0d50: 2a 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28  * sqlite3Malloc(
0d60: 29 20 63 61 6c 6c 20 61 6e 64 20 74 68 61 74 20  ) call and that 
0d70: 6d 65 6d 6f 72 79 20 69 73 20 75 73 65 64 20 66  memory is used f
0d80: 6f 72 20 74 68 65 20 66 69 72 73 74 20 4e 20 70  or the first N p
0d90: 61 67 65 73 20 61 6c 6c 6f 63 61 74 65 64 2e 0a  ages allocated..
0da0: 2a 2a 20 4f 72 20 69 66 20 4e 20 69 73 20 6e 65  ** Or if N is ne
0db0: 67 61 74 69 76 65 2c 20 74 68 65 6e 20 2d 31 30  gative, then -10
0dc0: 32 34 2a 4e 20 62 79 74 65 73 20 6f 66 20 6d 65  24*N bytes of me
0dd0: 6d 6f 72 79 20 61 72 65 20 61 6c 6c 6f 63 61 74  mory are allocat
0de0: 65 64 20 61 6e 64 20 75 73 65 64 0a 2a 2a 20 66  ed and used.** f
0df0: 6f 72 20 61 73 20 6d 61 6e 79 20 70 61 67 65 73  or as many pages
0e00: 20 61 73 20 63 61 6e 20 62 65 20 61 63 63 6f 6d   as can be accom
0e10: 6f 64 61 74 65 64 2e 0a 2a 2a 0a 2a 2a 20 4f 6e  odated..**.** On
0e20: 6c 79 20 6f 6e 65 20 6f 66 20 28 32 29 20 6f 72  ly one of (2) or
0e30: 20 28 33 29 20 63 61 6e 20 62 65 20 75 73 65 64   (3) can be used
0e40: 2e 20 20 4f 6e 63 65 20 74 68 65 20 6d 65 6d 6f  .  Once the memo
0e50: 72 79 20 61 76 61 69 6c 61 62 6c 65 20 74 6f 20  ry available to 
0e60: 28 32 29 20 6f 72 0a 2a 2a 20 28 33 29 20 69 73  (2) or.** (3) is
0e70: 20 65 78 68 61 75 73 74 65 64 2c 20 73 75 62 73   exhausted, subs
0e80: 65 71 75 65 6e 74 20 61 6c 6c 6f 63 61 74 69 6f  equent allocatio
0e90: 6e 73 20 66 61 69 6c 20 6f 76 65 72 20 74 6f 20  ns fail over to 
0ea0: 74 68 65 20 67 65 6e 65 72 61 6c 2d 70 75 72 70  the general-purp
0eb0: 6f 73 65 0a 2a 2a 20 6d 65 6d 6f 72 79 20 61 6c  ose.** memory al
0ec0: 6c 6f 63 61 74 6f 72 20 28 31 29 2e 0a 2a 2a 0a  locator (1)..**.
0ed0: 2a 2a 20 45 61 72 6c 69 65 72 20 76 65 72 73 69  ** Earlier versi
0ee0: 6f 6e 73 20 6f 66 20 53 51 4c 69 74 65 20 75 73  ons of SQLite us
0ef0: 65 64 20 6f 6e 6c 79 20 6d 65 74 68 6f 64 73 20  ed only methods 
0f00: 28 31 29 20 61 6e 64 20 28 32 29 2e 20 20 42 75  (1) and (2).  Bu
0f10: 74 20 65 78 70 65 72 69 6d 65 6e 74 73 0a 2a 2a  t experiments.**
0f20: 20 73 68 6f 77 20 74 68 61 74 20 6d 65 74 68 6f   show that metho
0f30: 64 20 28 33 29 20 77 69 74 68 20 4e 3d 3d 31 30  d (3) with N==10
0f40: 30 20 70 72 6f 76 69 64 65 73 20 61 62 6f 75 74  0 provides about
0f50: 20 61 20 35 25 20 70 65 72 66 6f 72 6d 61 6e 63   a 5% performanc
0f60: 65 20 62 6f 6f 73 74 20 66 6f 72 0a 2a 2a 20 63  e boost for.** c
0f70: 6f 6d 6d 6f 6e 20 77 6f 72 6b 6c 6f 61 64 73 2e  ommon workloads.
0f80: 0a 2a 2f 0a 23 69 6e 63 6c 75 64 65 20 22 73 71  .*/.#include "sq
0f90: 6c 69 74 65 49 6e 74 2e 68 22 0a 0a 74 79 70 65  liteInt.h"..type
0fa0: 64 65 66 20 73 74 72 75 63 74 20 50 43 61 63 68  def struct PCach
0fb0: 65 31 20 50 43 61 63 68 65 31 3b 0a 74 79 70 65  e1 PCache1;.type
0fc0: 64 65 66 20 73 74 72 75 63 74 20 50 67 48 64 72  def struct PgHdr
0fd0: 31 20 50 67 48 64 72 31 3b 0a 74 79 70 65 64 65  1 PgHdr1;.typede
0fe0: 66 20 73 74 72 75 63 74 20 50 67 46 72 65 65 73  f struct PgFrees
0ff0: 6c 6f 74 20 50 67 46 72 65 65 73 6c 6f 74 3b 0a  lot PgFreeslot;.
1000: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 50  typedef struct P
1010: 47 72 6f 75 70 20 50 47 72 6f 75 70 3b 0a 0a 2f  Group PGroup;../
1020: 2a 0a 2a 2a 20 45 61 63 68 20 63 61 63 68 65 20  *.** Each cache 
1030: 65 6e 74 72 79 20 69 73 20 72 65 70 72 65 73 65  entry is represe
1040: 6e 74 65 64 20 62 79 20 61 6e 20 69 6e 73 74 61  nted by an insta
1050: 6e 63 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f  nce of the follo
1060: 77 69 6e 67 20 0a 2a 2a 20 73 74 72 75 63 74 75  wing .** structu
1070: 72 65 2e 20 55 6e 6c 65 73 73 20 53 51 4c 49 54  re. Unless SQLIT
1080: 45 5f 50 43 41 43 48 45 5f 53 45 50 41 52 41 54  E_PCACHE_SEPARAT
1090: 45 5f 48 45 41 44 45 52 20 69 73 20 64 65 66 69  E_HEADER is defi
10a0: 6e 65 64 2c 20 61 20 62 75 66 66 65 72 20 6f 66  ned, a buffer of
10b0: 0a 2a 2a 20 50 67 48 64 72 31 2e 70 43 61 63 68  .** PgHdr1.pCach
10c0: 65 2d 3e 73 7a 50 61 67 65 20 62 79 74 65 73 20  e->szPage bytes 
10d0: 69 73 20 61 6c 6c 6f 63 61 74 65 64 20 64 69 72  is allocated dir
10e0: 65 63 74 6c 79 20 62 65 66 6f 72 65 20 74 68 69  ectly before thi
10f0: 73 20 73 74 72 75 63 74 75 72 65 20 0a 2a 2a 20  s structure .** 
1100: 69 6e 20 6d 65 6d 6f 72 79 2e 0a 2a 2f 0a 73 74  in memory..*/.st
1110: 72 75 63 74 20 50 67 48 64 72 31 20 7b 0a 20 20  ruct PgHdr1 {.  
1120: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 5f 70  sqlite3_pcache_p
1130: 61 67 65 20 70 61 67 65 3b 20 20 20 20 20 20 2f  age page;      /
1140: 2a 20 42 61 73 65 20 63 6c 61 73 73 2e 20 4d 75  * Base class. Mu
1150: 73 74 20 62 65 20 66 69 72 73 74 2e 20 70 42 75  st be first. pBu
1160: 66 20 26 20 70 45 78 74 72 61 20 2a 2f 0a 20 20  f & pExtra */.  
1170: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4b 65  unsigned int iKe
1180: 79 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  y;             /
1190: 2a 20 4b 65 79 20 76 61 6c 75 65 20 28 70 61 67  * Key value (pag
11a0: 65 20 6e 75 6d 62 65 72 29 20 2a 2f 0a 20 20 75  e number) */.  u
11b0: 38 20 69 73 42 75 6c 6b 4c 6f 63 61 6c 3b 20 20  8 isBulkLocal;  
11c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
11d0: 20 54 68 69 73 20 70 61 67 65 20 66 72 6f 6d 20   This page from 
11e0: 62 75 6c 6b 20 6c 6f 63 61 6c 20 73 74 6f 72 61  bulk local stora
11f0: 67 65 20 2a 2f 0a 20 20 75 38 20 69 73 41 6e 63  ge */.  u8 isAnc
1200: 68 6f 72 3b 20 20 20 20 20 20 20 20 20 20 20 20  hor;            
1210: 20 20 20 20 20 20 20 2f 2a 20 54 68 69 73 20 69         /* This i
1220: 73 20 74 68 65 20 50 47 72 6f 75 70 2e 6c 72 75  s the PGroup.lru
1230: 20 65 6c 65 6d 65 6e 74 20 2a 2f 0a 20 20 50 67   element */.  Pg
1240: 48 64 72 31 20 2a 70 4e 65 78 74 3b 20 20 20 20  Hdr1 *pNext;    
1250: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1260: 4e 65 78 74 20 69 6e 20 68 61 73 68 20 74 61 62  Next in hash tab
1270: 6c 65 20 63 68 61 69 6e 20 2a 2f 0a 20 20 50 43  le chain */.  PC
1280: 61 63 68 65 31 20 2a 70 43 61 63 68 65 3b 20 20  ache1 *pCache;  
1290: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
12a0: 43 61 63 68 65 20 74 68 61 74 20 63 75 72 72 65  Cache that curre
12b0: 6e 74 6c 79 20 6f 77 6e 73 20 74 68 69 73 20 70  ntly owns this p
12c0: 61 67 65 20 2a 2f 0a 20 20 50 67 48 64 72 31 20  age */.  PgHdr1 
12d0: 2a 70 4c 72 75 4e 65 78 74 3b 20 20 20 20 20 20  *pLruNext;      
12e0: 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20          /* Next 
12f0: 69 6e 20 4c 52 55 20 6c 69 73 74 20 6f 66 20 75  in LRU list of u
1300: 6e 70 69 6e 6e 65 64 20 70 61 67 65 73 20 2a 2f  npinned pages */
1310: 0a 20 20 50 67 48 64 72 31 20 2a 70 4c 72 75 50  .  PgHdr1 *pLruP
1320: 72 65 76 3b 20 20 20 20 20 20 20 20 20 20 20 20  rev;            
1330: 20 20 2f 2a 20 50 72 65 76 69 6f 75 73 20 69 6e    /* Previous in
1340: 20 4c 52 55 20 6c 69 73 74 20 6f 66 20 75 6e 70   LRU list of unp
1350: 69 6e 6e 65 64 20 70 61 67 65 73 20 2a 2f 0a 7d  inned pages */.}
1360: 3b 0a 0a 2f 2a 0a 2a 2a 20 41 20 70 61 67 65 20  ;../*.** A page 
1370: 69 73 20 70 69 6e 6e 65 64 20 69 66 20 69 74 20  is pinned if it 
1380: 69 73 20 6e 6f 74 20 6f 6e 20 74 68 65 20 4c 52  is not on the LR
1390: 55 20 6c 69 73 74 2e 20 20 54 6f 20 62 65 20 22  U list.  To be "
13a0: 70 69 6e 6e 65 64 22 20 6d 65 61 6e 73 0a 2a 2a  pinned" means.**
13b0: 20 74 68 61 74 20 74 68 65 20 70 61 67 65 20 69   that the page i
13c0: 73 20 69 6e 20 61 63 74 69 76 65 20 75 73 65 20  s in active use 
13d0: 61 6e 64 20 6d 75 73 74 20 6e 6f 74 20 62 65 20  and must not be 
13e0: 64 65 61 6c 6c 6f 63 61 74 65 64 2e 0a 2a 2f 0a  deallocated..*/.
13f0: 23 64 65 66 69 6e 65 20 50 41 47 45 5f 49 53 5f  #define PAGE_IS_
1400: 50 49 4e 4e 45 44 28 70 29 20 20 20 20 28 28 70  PINNED(p)    ((p
1410: 29 2d 3e 70 4c 72 75 4e 65 78 74 3d 3d 30 29 0a  )->pLruNext==0).
1420: 23 64 65 66 69 6e 65 20 50 41 47 45 5f 49 53 5f  #define PAGE_IS_
1430: 55 4e 50 49 4e 4e 45 44 28 70 29 20 20 28 28 70  UNPINNED(p)  ((p
1440: 29 2d 3e 70 4c 72 75 4e 65 78 74 21 3d 30 29 0a  )->pLruNext!=0).
1450: 0a 2f 2a 20 45 61 63 68 20 70 61 67 65 20 63 61  ./* Each page ca
1460: 63 68 65 20 28 6f 72 20 50 43 61 63 68 65 29 20  che (or PCache) 
1470: 62 65 6c 6f 6e 67 73 20 74 6f 20 61 20 50 47 72  belongs to a PGr
1480: 6f 75 70 2e 20 20 41 20 50 47 72 6f 75 70 20 69  oup.  A PGroup i
1490: 73 20 61 20 73 65 74 20 0a 2a 2a 20 6f 66 20 6f  s a set .** of o
14a0: 6e 65 20 6f 72 20 6d 6f 72 65 20 50 43 61 63 68  ne or more PCach
14b0: 65 73 20 74 68 61 74 20 61 72 65 20 61 62 6c 65  es that are able
14c0: 20 74 6f 20 72 65 63 79 63 6c 65 20 65 61 63 68   to recycle each
14d0: 20 6f 74 68 65 72 27 73 20 75 6e 70 69 6e 6e 65   other's unpinne
14e0: 64 0a 2a 2a 20 70 61 67 65 73 20 77 68 65 6e 20  d.** pages when 
14f0: 74 68 65 79 20 61 72 65 20 75 6e 64 65 72 20 6d  they are under m
1500: 65 6d 6f 72 79 20 70 72 65 73 73 75 72 65 2e 20  emory pressure. 
1510: 20 41 20 50 47 72 6f 75 70 20 69 73 20 61 6e 20   A PGroup is an 
1520: 69 6e 73 74 61 6e 63 65 20 6f 66 0a 2a 2a 20 74  instance of.** t
1530: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6f 62 6a  he following obj
1540: 65 63 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  ect..**.** This 
1550: 70 61 67 65 20 63 61 63 68 65 20 69 6d 70 6c 65  page cache imple
1560: 6d 65 6e 74 61 74 69 6f 6e 20 77 6f 72 6b 73 20  mentation works 
1570: 69 6e 20 6f 6e 65 20 6f 66 20 74 77 6f 20 6d 6f  in one of two mo
1580: 64 65 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 28 31 29  des:.**.**   (1)
1590: 20 20 45 76 65 72 79 20 50 43 61 63 68 65 20 69    Every PCache i
15a0: 73 20 74 68 65 20 73 6f 6c 65 20 6d 65 6d 62 65  s the sole membe
15b0: 72 20 6f 66 20 69 74 73 20 6f 77 6e 20 50 47 72  r of its own PGr
15c0: 6f 75 70 2e 20 20 54 68 65 72 65 20 69 73 0a 2a  oup.  There is.*
15d0: 2a 20 20 20 20 20 20 20 20 6f 6e 65 20 50 47 72  *        one PGr
15e0: 6f 75 70 20 70 65 72 20 50 43 61 63 68 65 2e 0a  oup per PCache..
15f0: 2a 2a 0a 2a 2a 20 20 20 28 32 29 20 20 54 68 65  **.**   (2)  The
1600: 72 65 20 69 73 20 61 20 73 69 6e 67 6c 65 20 67  re is a single g
1610: 6c 6f 62 61 6c 20 50 47 72 6f 75 70 20 74 68 61  lobal PGroup tha
1620: 74 20 61 6c 6c 20 50 43 61 63 68 65 73 20 61 72  t all PCaches ar
1630: 65 20 61 20 6d 65 6d 62 65 72 0a 2a 2a 20 20 20  e a member.**   
1640: 20 20 20 20 20 6f 66 2e 0a 2a 2a 0a 2a 2a 20 4d       of..**.** M
1650: 6f 64 65 20 31 20 75 73 65 73 20 6d 6f 72 65 20  ode 1 uses more 
1660: 6d 65 6d 6f 72 79 20 28 73 69 6e 63 65 20 50 43  memory (since PC
1670: 61 63 68 65 20 69 6e 73 74 61 6e 63 65 73 20 61  ache instances a
1680: 72 65 20 6e 6f 74 20 61 62 6c 65 20 74 6f 20 72  re not able to r
1690: 6f 62 0a 2a 2a 20 75 6e 75 73 65 64 20 70 61 67  ob.** unused pag
16a0: 65 73 20 66 72 6f 6d 20 6f 74 68 65 72 20 50 43  es from other PC
16b0: 61 63 68 65 73 29 20 62 75 74 20 69 74 20 61 6c  aches) but it al
16c0: 73 6f 20 6f 70 65 72 61 74 65 73 20 77 69 74 68  so operates with
16d0: 6f 75 74 20 61 20 6d 75 74 65 78 2c 0a 2a 2a 20  out a mutex,.** 
16e0: 61 6e 64 20 69 73 20 74 68 65 72 65 66 6f 72 65  and is therefore
16f0: 20 6f 66 74 65 6e 20 66 61 73 74 65 72 2e 20 20   often faster.  
1700: 4d 6f 64 65 20 32 20 72 65 71 75 69 72 65 73 20  Mode 2 requires 
1710: 61 20 6d 75 74 65 78 20 69 6e 20 6f 72 64 65 72  a mutex in order
1720: 20 74 6f 20 62 65 0a 2a 2a 20 74 68 72 65 61 64   to be.** thread
1730: 73 61 66 65 2c 20 62 75 74 20 72 65 63 79 63 6c  safe, but recycl
1740: 65 73 20 70 61 67 65 73 20 6d 6f 72 65 20 65 66  es pages more ef
1750: 66 69 63 69 65 6e 74 6c 79 2e 0a 2a 2a 0a 2a 2a  ficiently..**.**
1760: 20 46 6f 72 20 6d 6f 64 65 20 28 31 29 2c 20 50   For mode (1), P
1770: 47 72 6f 75 70 2e 6d 75 74 65 78 20 69 73 20 4e  Group.mutex is N
1780: 55 4c 4c 2e 20 20 46 6f 72 20 6d 6f 64 65 20 28  ULL.  For mode (
1790: 32 29 20 74 68 65 72 65 20 69 73 20 6f 6e 6c 79  2) there is only
17a0: 20 61 20 73 69 6e 67 6c 65 0a 2a 2a 20 50 47 72   a single.** PGr
17b0: 6f 75 70 20 77 68 69 63 68 20 69 73 20 74 68 65  oup which is the
17c0: 20 70 63 61 63 68 65 31 2e 67 72 70 20 67 6c 6f   pcache1.grp glo
17d0: 62 61 6c 20 76 61 72 69 61 62 6c 65 20 61 6e 64  bal variable and
17e0: 20 69 74 73 20 6d 75 74 65 78 20 69 73 0a 2a 2a   its mutex is.**
17f0: 20 53 51 4c 49 54 45 5f 4d 55 54 45 58 5f 53 54   SQLITE_MUTEX_ST
1800: 41 54 49 43 5f 4c 52 55 2e 0a 2a 2f 0a 73 74 72  ATIC_LRU..*/.str
1810: 75 63 74 20 50 47 72 6f 75 70 20 7b 0a 20 20 73  uct PGroup {.  s
1820: 71 6c 69 74 65 33 5f 6d 75 74 65 78 20 2a 6d 75  qlite3_mutex *mu
1830: 74 65 78 3b 20 20 20 20 20 20 20 20 20 20 2f 2a  tex;          /*
1840: 20 4d 55 54 45 58 5f 53 54 41 54 49 43 5f 4c 52   MUTEX_STATIC_LR
1850: 55 20 6f 72 20 4e 55 4c 4c 20 2a 2f 0a 20 20 75  U or NULL */.  u
1860: 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 4d 61 78  nsigned int nMax
1870: 50 61 67 65 3b 20 20 20 20 20 20 20 20 20 2f 2a  Page;         /*
1880: 20 53 75 6d 20 6f 66 20 6e 4d 61 78 20 66 6f 72   Sum of nMax for
1890: 20 70 75 72 67 65 61 62 6c 65 20 63 61 63 68 65   purgeable cache
18a0: 73 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20  s */.  unsigned 
18b0: 69 6e 74 20 6e 4d 69 6e 50 61 67 65 3b 20 20 20  int nMinPage;   
18c0: 20 20 20 20 20 20 2f 2a 20 53 75 6d 20 6f 66 20        /* Sum of 
18d0: 6e 4d 69 6e 20 66 6f 72 20 70 75 72 67 65 61 62  nMin for purgeab
18e0: 6c 65 20 63 61 63 68 65 73 20 2a 2f 0a 20 20 75  le caches */.  u
18f0: 6e 73 69 67 6e 65 64 20 69 6e 74 20 6d 78 50 69  nsigned int mxPi
1900: 6e 6e 65 64 3b 20 20 20 20 20 20 20 20 20 2f 2a  nned;         /*
1910: 20 6e 4d 61 78 70 61 67 65 20 2b 20 31 30 20 2d   nMaxpage + 10 -
1920: 20 6e 4d 69 6e 50 61 67 65 20 2a 2f 0a 20 20 75   nMinPage */.  u
1930: 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 50 75 72  nsigned int nPur
1940: 67 65 61 62 6c 65 3b 20 20 20 20 20 20 20 2f 2a  geable;       /*
1950: 20 4e 75 6d 62 65 72 20 6f 66 20 70 75 72 67 65   Number of purge
1960: 61 62 6c 65 20 70 61 67 65 73 20 61 6c 6c 6f 63  able pages alloc
1970: 61 74 65 64 20 2a 2f 0a 20 20 50 67 48 64 72 31  ated */.  PgHdr1
1980: 20 6c 72 75 3b 20 20 20 20 20 20 20 20 20 20 20   lru;           
1990: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20           /* The 
19a0: 62 65 67 69 6e 6e 69 6e 67 20 61 6e 64 20 65 6e  beginning and en
19b0: 64 20 6f 66 20 74 68 65 20 4c 52 55 20 6c 69 73  d of the LRU lis
19c0: 74 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 20 45 61 63 68  t */.};../* Each
19d0: 20 70 61 67 65 20 63 61 63 68 65 20 69 73 20 61   page cache is a
19e0: 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68  n instance of th
19f0: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6f 62 6a 65  e following obje
1a00: 63 74 2e 20 20 45 76 65 72 79 0a 2a 2a 20 6f 70  ct.  Every.** op
1a10: 65 6e 20 64 61 74 61 62 61 73 65 20 66 69 6c 65  en database file
1a20: 20 28 69 6e 63 6c 75 64 69 6e 67 20 65 61 63 68   (including each
1a30: 20 69 6e 2d 6d 65 6d 6f 72 79 20 64 61 74 61 62   in-memory datab
1a40: 61 73 65 20 61 6e 64 20 65 61 63 68 0a 2a 2a 20  ase and each.** 
1a50: 74 65 6d 70 6f 72 61 72 79 20 6f 72 20 74 72 61  temporary or tra
1a60: 6e 73 69 65 6e 74 20 64 61 74 61 62 61 73 65 29  nsient database)
1a70: 20 68 61 73 20 61 20 73 69 6e 67 6c 65 20 70 61   has a single pa
1a80: 67 65 20 63 61 63 68 65 20 77 68 69 63 68 0a 2a  ge cache which.*
1a90: 2a 20 69 73 20 61 6e 20 69 6e 73 74 61 6e 63 65  * is an instance
1aa0: 20 6f 66 20 74 68 69 73 20 6f 62 6a 65 63 74 2e   of this object.
1ab0: 0a 2a 2a 0a 2a 2a 20 50 6f 69 6e 74 65 72 73 20  .**.** Pointers 
1ac0: 74 6f 20 73 74 72 75 63 74 75 72 65 73 20 6f 66  to structures of
1ad0: 20 74 68 69 73 20 74 79 70 65 20 61 72 65 20 63   this type are c
1ae0: 61 73 74 20 61 6e 64 20 72 65 74 75 72 6e 65 64  ast and returned
1af0: 20 61 73 20 0a 2a 2a 20 6f 70 61 71 75 65 20 73   as .** opaque s
1b00: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2a 20 68  qlite3_pcache* h
1b10: 61 6e 64 6c 65 73 2e 0a 2a 2f 0a 73 74 72 75 63  andles..*/.struc
1b20: 74 20 50 43 61 63 68 65 31 20 7b 0a 20 20 2f 2a  t PCache1 {.  /*
1b30: 20 43 61 63 68 65 20 63 6f 6e 66 69 67 75 72 61   Cache configura
1b40: 74 69 6f 6e 20 70 61 72 61 6d 65 74 65 72 73 2e  tion parameters.
1b50: 20 50 61 67 65 20 73 69 7a 65 20 28 73 7a 50 61   Page size (szPa
1b60: 67 65 29 20 61 6e 64 20 74 68 65 20 70 75 72 67  ge) and the purg
1b70: 65 61 62 6c 65 0a 20 20 2a 2a 20 66 6c 61 67 20  eable.  ** flag 
1b80: 28 62 50 75 72 67 65 61 62 6c 65 29 20 61 6e 64  (bPurgeable) and
1b90: 20 74 68 65 20 70 6e 50 75 72 67 65 61 62 6c 65   the pnPurgeable
1ba0: 20 70 6f 69 6e 74 65 72 20 61 72 65 20 61 6c 6c   pointer are all
1bb0: 20 73 65 74 20 77 68 65 6e 20 74 68 65 0a 20 20   set when the.  
1bc0: 2a 2a 20 63 61 63 68 65 20 69 73 20 63 72 65 61  ** cache is crea
1bd0: 74 65 64 20 61 6e 64 20 61 72 65 20 6e 65 76 65  ted and are neve
1be0: 72 20 63 68 61 6e 67 65 64 20 74 68 65 72 65 61  r changed therea
1bf0: 66 74 65 72 2e 20 6e 4d 61 78 20 6d 61 79 20 62  fter. nMax may b
1c00: 65 20 0a 20 20 2a 2a 20 6d 6f 64 69 66 69 65 64  e .  ** modified
1c10: 20 61 74 20 61 6e 79 20 74 69 6d 65 20 62 79 20   at any time by 
1c20: 61 20 63 61 6c 6c 20 74 6f 20 74 68 65 20 70 63  a call to the pc
1c30: 61 63 68 65 31 43 61 63 68 65 73 69 7a 65 28 29  ache1Cachesize()
1c40: 20 6d 65 74 68 6f 64 2e 0a 20 20 2a 2a 20 54 68   method..  ** Th
1c50: 65 20 50 47 72 6f 75 70 20 6d 75 74 65 78 20 6d  e PGroup mutex m
1c60: 75 73 74 20 62 65 20 68 65 6c 64 20 77 68 65 6e  ust be held when
1c70: 20 61 63 63 65 73 73 69 6e 67 20 6e 4d 61 78 2e   accessing nMax.
1c80: 0a 20 20 2a 2f 0a 20 20 50 47 72 6f 75 70 20 2a  .  */.  PGroup *
1c90: 70 47 72 6f 75 70 3b 20 20 20 20 20 20 20 20 20  pGroup;         
1ca0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
1cb0: 47 72 6f 75 70 20 74 68 69 73 20 63 61 63 68 65  Group this cache
1cc0: 20 62 65 6c 6f 6e 67 73 20 74 6f 20 2a 2f 0a 20   belongs to */. 
1cd0: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 2a 70   unsigned int *p
1ce0: 6e 50 75 72 67 65 61 62 6c 65 3b 20 20 20 20 20  nPurgeable;     
1cf0: 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20       /* Pointer 
1d00: 74 6f 20 70 47 72 6f 75 70 2d 3e 6e 50 75 72 67  to pGroup->nPurg
1d10: 65 61 62 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 73  eable */.  int s
1d20: 7a 50 61 67 65 3b 20 20 20 20 20 20 20 20 20 20  zPage;          
1d30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1d40: 2a 20 53 69 7a 65 20 6f 66 20 64 61 74 61 62 61  * Size of databa
1d50: 73 65 20 63 6f 6e 74 65 6e 74 20 73 65 63 74 69  se content secti
1d60: 6f 6e 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 45 78  on */.  int szEx
1d70: 74 72 61 3b 20 20 20 20 20 20 20 20 20 20 20 20  tra;            
1d80: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 73              /* s
1d90: 69 7a 65 6f 66 28 4d 65 6d 50 61 67 65 29 2b 73  izeof(MemPage)+s
1da0: 69 7a 65 6f 66 28 50 67 48 64 72 29 20 2a 2f 0a  izeof(PgHdr) */.
1db0: 20 20 69 6e 74 20 73 7a 41 6c 6c 6f 63 3b 20 20    int szAlloc;  
1dc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1dd0: 20 20 20 20 20 20 2f 2a 20 54 6f 74 61 6c 20 73        /* Total s
1de0: 69 7a 65 20 6f 66 20 6f 6e 65 20 70 63 61 63 68  ize of one pcach
1df0: 65 20 6c 69 6e 65 20 2a 2f 0a 20 20 69 6e 74 20  e line */.  int 
1e00: 62 50 75 72 67 65 61 62 6c 65 3b 20 20 20 20 20  bPurgeable;     
1e10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1e20: 2f 2a 20 54 72 75 65 20 69 66 20 63 61 63 68 65  /* True if cache
1e30: 20 69 73 20 70 75 72 67 65 61 62 6c 65 20 2a 2f   is purgeable */
1e40: 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  .  unsigned int 
1e50: 6e 4d 69 6e 3b 20 20 20 20 20 20 20 20 20 20 20  nMin;           
1e60: 20 20 20 20 20 20 20 2f 2a 20 4d 69 6e 69 6d 75         /* Minimu
1e70: 6d 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65  m number of page
1e80: 73 20 72 65 73 65 72 76 65 64 20 2a 2f 0a 20 20  s reserved */.  
1e90: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 4d 61  unsigned int nMa
1ea0: 78 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  x;              
1eb0: 20 20 20 20 2f 2a 20 43 6f 6e 66 69 67 75 72 65      /* Configure
1ec0: 64 20 22 63 61 63 68 65 5f 73 69 7a 65 22 20 76  d "cache_size" v
1ed0: 61 6c 75 65 20 2a 2f 0a 20 20 75 6e 73 69 67 6e  alue */.  unsign
1ee0: 65 64 20 69 6e 74 20 6e 39 30 70 63 74 3b 20 20  ed int n90pct;  
1ef0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1f00: 20 6e 4d 61 78 2a 39 2f 31 30 20 2a 2f 0a 20 20   nMax*9/10 */.  
1f10: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4d 61  unsigned int iMa
1f20: 78 4b 65 79 3b 20 20 20 20 20 20 20 20 20 20 20  xKey;           
1f30: 20 20 20 20 2f 2a 20 4c 61 72 67 65 73 74 20 6b      /* Largest k
1f40: 65 79 20 73 65 65 6e 20 73 69 6e 63 65 20 78 54  ey seen since xT
1f50: 72 75 6e 63 61 74 65 28 29 20 2a 2f 0a 0a 20 20  runcate() */..  
1f60: 2f 2a 20 48 61 73 68 20 74 61 62 6c 65 20 6f 66  /* Hash table of
1f70: 20 61 6c 6c 20 70 61 67 65 73 2e 20 54 68 65 20   all pages. The 
1f80: 66 6f 6c 6c 6f 77 69 6e 67 20 76 61 72 69 61 62  following variab
1f90: 6c 65 73 20 6d 61 79 20 6f 6e 6c 79 20 62 65 20  les may only be 
1fa0: 61 63 63 65 73 73 65 64 0a 20 20 2a 2a 20 77 68  accessed.  ** wh
1fb0: 65 6e 20 74 68 65 20 61 63 63 65 73 73 6f 72 20  en the accessor 
1fc0: 69 73 20 68 6f 6c 64 69 6e 67 20 74 68 65 20 50  is holding the P
1fd0: 47 72 6f 75 70 20 6d 75 74 65 78 2e 0a 20 20 2a  Group mutex..  *
1fe0: 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74  /.  unsigned int
1ff0: 20 6e 52 65 63 79 63 6c 61 62 6c 65 3b 20 20 20   nRecyclable;   
2000: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
2010: 72 20 6f 66 20 70 61 67 65 73 20 69 6e 20 74 68  r of pages in th
2020: 65 20 4c 52 55 20 6c 69 73 74 20 2a 2f 0a 20 20  e LRU list */.  
2030: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 50 61  unsigned int nPa
2040: 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ge;             
2050: 20 20 20 20 2f 2a 20 54 6f 74 61 6c 20 6e 75 6d      /* Total num
2060: 62 65 72 20 6f 66 20 70 61 67 65 73 20 69 6e 20  ber of pages in 
2070: 61 70 48 61 73 68 20 2a 2f 0a 20 20 75 6e 73 69  apHash */.  unsi
2080: 67 6e 65 64 20 69 6e 74 20 6e 48 61 73 68 3b 20  gned int nHash; 
2090: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
20a0: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 73 6c 6f  /* Number of slo
20b0: 74 73 20 69 6e 20 61 70 48 61 73 68 5b 5d 20 2a  ts in apHash[] *
20c0: 2f 0a 20 20 50 67 48 64 72 31 20 2a 2a 61 70 48  /.  PgHdr1 **apH
20d0: 61 73 68 3b 20 20 20 20 20 20 20 20 20 20 20 20  ash;            
20e0: 20 20 20 20 20 20 20 20 2f 2a 20 48 61 73 68 20          /* Hash 
20f0: 74 61 62 6c 65 20 66 6f 72 20 66 61 73 74 20 6c  table for fast l
2100: 6f 6f 6b 75 70 20 62 79 20 6b 65 79 20 2a 2f 0a  ookup by key */.
2110: 20 20 50 67 48 64 72 31 20 2a 70 46 72 65 65 3b    PgHdr1 *pFree;
2120: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2130: 20 20 20 20 20 20 2f 2a 20 4c 69 73 74 20 6f 66        /* List of
2140: 20 75 6e 75 73 65 64 20 70 63 61 63 68 65 2d 6c   unused pcache-l
2150: 6f 63 61 6c 20 70 61 67 65 73 20 2a 2f 0a 20 20  ocal pages */.  
2160: 76 6f 69 64 20 2a 70 42 75 6c 6b 3b 20 20 20 20  void *pBulk;    
2170: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2180: 20 20 20 20 2f 2a 20 42 75 6c 6b 20 6d 65 6d 6f      /* Bulk memo
2190: 72 79 20 75 73 65 64 20 62 79 20 70 63 61 63 68  ry used by pcach
21a0: 65 2d 6c 6f 63 61 6c 20 2a 2f 0a 7d 3b 0a 0a 2f  e-local */.};../
21b0: 2a 0a 2a 2a 20 46 72 65 65 20 73 6c 6f 74 73 20  *.** Free slots 
21c0: 69 6e 20 74 68 65 20 61 6c 6c 6f 63 61 74 6f 72  in the allocator
21d0: 20 75 73 65 64 20 74 6f 20 64 69 76 69 64 65 20   used to divide 
21e0: 75 70 20 74 68 65 20 67 6c 6f 62 61 6c 20 70 61  up the global pa
21f0: 67 65 20 63 61 63 68 65 0a 2a 2a 20 62 75 66 66  ge cache.** buff
2200: 65 72 20 70 72 6f 76 69 64 65 64 20 75 73 69 6e  er provided usin
2210: 67 20 74 68 65 20 53 51 4c 49 54 45 5f 43 4f 4e  g the SQLITE_CON
2220: 46 49 47 5f 50 41 47 45 43 41 43 48 45 20 6d 65  FIG_PAGECACHE me
2230: 63 68 61 6e 69 73 6d 2e 0a 2a 2f 0a 73 74 72 75  chanism..*/.stru
2240: 63 74 20 50 67 46 72 65 65 73 6c 6f 74 20 7b 0a  ct PgFreeslot {.
2250: 20 20 50 67 46 72 65 65 73 6c 6f 74 20 2a 70 4e    PgFreeslot *pN
2260: 65 78 74 3b 20 20 2f 2a 20 4e 65 78 74 20 66 72  ext;  /* Next fr
2270: 65 65 20 73 6c 6f 74 20 2a 2f 0a 7d 3b 0a 0a 2f  ee slot */.};../
2280: 2a 0a 2a 2a 20 47 6c 6f 62 61 6c 20 64 61 74 61  *.** Global data
2290: 20 75 73 65 64 20 62 79 20 74 68 69 73 20 63 61   used by this ca
22a0: 63 68 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 53  che..*/.static S
22b0: 51 4c 49 54 45 5f 57 53 44 20 73 74 72 75 63 74  QLITE_WSD struct
22c0: 20 50 43 61 63 68 65 47 6c 6f 62 61 6c 20 7b 0a   PCacheGlobal {.
22d0: 20 20 50 47 72 6f 75 70 20 67 72 70 3b 20 20 20    PGroup grp;   
22e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
22f0: 20 2f 2a 20 54 68 65 20 67 6c 6f 62 61 6c 20 50   /* The global P
2300: 47 72 6f 75 70 20 66 6f 72 20 6d 6f 64 65 20 28  Group for mode (
2310: 32 29 20 2a 2f 0a 0a 20 20 2f 2a 20 56 61 72 69  2) */..  /* Vari
2320: 61 62 6c 65 73 20 72 65 6c 61 74 65 64 20 74 6f  ables related to
2330: 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50   SQLITE_CONFIG_P
2340: 41 47 45 43 41 43 48 45 20 73 65 74 74 69 6e 67  AGECACHE setting
2350: 73 2e 20 20 54 68 65 0a 20 20 2a 2a 20 73 7a 53  s.  The.  ** szS
2360: 6c 6f 74 2c 20 6e 53 6c 6f 74 2c 20 70 53 74 61  lot, nSlot, pSta
2370: 72 74 2c 20 70 45 6e 64 2c 20 6e 52 65 73 65 72  rt, pEnd, nReser
2380: 76 65 2c 20 61 6e 64 20 69 73 49 6e 69 74 20 76  ve, and isInit v
2390: 61 6c 75 65 73 20 61 72 65 20 61 6c 6c 0a 20 20  alues are all.  
23a0: 2a 2a 20 66 69 78 65 64 20 61 74 20 73 71 6c 69  ** fixed at sqli
23b0: 74 65 33 5f 69 6e 69 74 69 61 6c 69 7a 65 28 29  te3_initialize()
23c0: 20 74 69 6d 65 20 61 6e 64 20 64 6f 20 6e 6f 74   time and do not
23d0: 20 72 65 71 75 69 72 65 20 6d 75 74 65 78 20 70   require mutex p
23e0: 72 6f 74 65 63 74 69 6f 6e 2e 0a 20 20 2a 2a 20  rotection..  ** 
23f0: 54 68 65 20 6e 46 72 65 65 53 6c 6f 74 20 61 6e  The nFreeSlot an
2400: 64 20 70 46 72 65 65 20 76 61 6c 75 65 73 20 64  d pFree values d
2410: 6f 20 72 65 71 75 69 72 65 20 6d 75 74 65 78 20  o require mutex 
2420: 70 72 6f 74 65 63 74 69 6f 6e 2e 0a 20 20 2a 2f  protection..  */
2430: 0a 20 20 69 6e 74 20 69 73 49 6e 69 74 3b 20 20  .  int isInit;  
2440: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2450: 20 20 2f 2a 20 54 72 75 65 20 69 66 20 69 6e 69    /* True if ini
2460: 74 69 61 6c 69 7a 65 64 20 2a 2f 0a 20 20 69 6e  tialized */.  in
2470: 74 20 73 65 70 61 72 61 74 65 43 61 63 68 65 3b  t separateCache;
2480: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2490: 55 73 65 20 61 20 6e 65 77 20 50 47 72 6f 75 70  Use a new PGroup
24a0: 20 66 6f 72 20 65 61 63 68 20 50 43 61 63 68 65   for each PCache
24b0: 20 2a 2f 0a 20 20 69 6e 74 20 6e 49 6e 69 74 50   */.  int nInitP
24c0: 61 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  age;            
24d0: 20 20 20 20 20 2f 2a 20 49 6e 69 74 69 61 6c 20       /* Initial 
24e0: 62 75 6c 6b 20 61 6c 6c 6f 63 61 74 69 6f 6e 20  bulk allocation 
24f0: 73 69 7a 65 20 2a 2f 20 20 20 0a 20 20 69 6e 74  size */   .  int
2500: 20 73 7a 53 6c 6f 74 3b 20 20 20 20 20 20 20 20   szSlot;        
2510: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
2520: 69 7a 65 20 6f 66 20 65 61 63 68 20 66 72 65 65  ize of each free
2530: 20 73 6c 6f 74 20 2a 2f 0a 20 20 69 6e 74 20 6e   slot */.  int n
2540: 53 6c 6f 74 3b 20 20 20 20 20 20 20 20 20 20 20  Slot;           
2550: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65            /* The
2560: 20 6e 75 6d 62 65 72 20 6f 66 20 70 63 61 63 68   number of pcach
2570: 65 20 73 6c 6f 74 73 20 2a 2f 0a 20 20 69 6e 74  e slots */.  int
2580: 20 6e 52 65 73 65 72 76 65 3b 20 20 20 20 20 20   nReserve;      
2590: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
25a0: 72 79 20 74 6f 20 6b 65 65 70 20 6e 46 72 65 65  ry to keep nFree
25b0: 53 6c 6f 74 20 61 62 6f 76 65 20 74 68 69 73 20  Slot above this 
25c0: 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 53 74 61 72  */.  void *pStar
25d0: 74 2c 20 2a 70 45 6e 64 3b 20 20 20 20 20 20 20  t, *pEnd;       
25e0: 20 20 20 20 2f 2a 20 42 6f 75 6e 64 73 20 6f 66      /* Bounds of
25f0: 20 67 6c 6f 62 61 6c 20 70 61 67 65 20 63 61 63   global page cac
2600: 68 65 20 6d 65 6d 6f 72 79 20 2a 2f 0a 20 20 2f  he memory */.  /
2610: 2a 20 41 62 6f 76 65 20 72 65 71 75 69 72 65 73  * Above requires
2620: 20 6e 6f 20 6d 75 74 65 78 2e 20 20 55 73 65 20   no mutex.  Use 
2630: 6d 75 74 65 78 20 62 65 6c 6f 77 20 66 6f 72 20  mutex below for 
2640: 76 61 72 69 61 62 6c 65 20 74 68 61 74 20 66 6f  variable that fo
2650: 6c 6c 6f 77 2e 20 2a 2f 0a 20 20 73 71 6c 69 74  llow. */.  sqlit
2660: 65 33 5f 6d 75 74 65 78 20 2a 6d 75 74 65 78 3b  e3_mutex *mutex;
2670: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 75 74            /* Mut
2680: 65 78 20 66 6f 72 20 61 63 63 65 73 73 69 6e 67  ex for accessing
2690: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 3a 20   the following: 
26a0: 2a 2f 0a 20 20 50 67 46 72 65 65 73 6c 6f 74 20  */.  PgFreeslot 
26b0: 2a 70 46 72 65 65 3b 20 20 20 20 20 20 20 20 20  *pFree;         
26c0: 20 20 20 20 2f 2a 20 46 72 65 65 20 70 61 67 65      /* Free page
26d0: 20 62 6c 6f 63 6b 73 20 2a 2f 0a 20 20 69 6e 74   blocks */.  int
26e0: 20 6e 46 72 65 65 53 6c 6f 74 3b 20 20 20 20 20   nFreeSlot;     
26f0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
2700: 75 6d 62 65 72 20 6f 66 20 75 6e 75 73 65 64 20  umber of unused 
2710: 70 63 61 63 68 65 20 73 6c 6f 74 73 20 2a 2f 0a  pcache slots */.
2720: 20 20 2f 2a 20 54 68 65 20 66 6f 6c 6c 6f 77 69    /* The followi
2730: 6e 67 20 76 61 6c 75 65 20 72 65 71 75 69 72 65  ng value require
2740: 73 20 61 20 6d 75 74 65 78 20 74 6f 20 63 68 61  s a mutex to cha
2750: 6e 67 65 2e 20 20 57 65 20 73 6b 69 70 20 74 68  nge.  We skip th
2760: 65 20 6d 75 74 65 78 20 6f 6e 0a 20 20 2a 2a 20  e mutex on.  ** 
2770: 72 65 61 64 69 6e 67 20 62 65 63 61 75 73 65 20  reading because 
2780: 28 31 29 20 6d 6f 73 74 20 70 6c 61 74 66 6f 72  (1) most platfor
2790: 6d 73 20 72 65 61 64 20 61 20 33 32 2d 62 69 74  ms read a 32-bit
27a0: 20 69 6e 74 65 67 65 72 20 61 74 6f 6d 69 63 61   integer atomica
27b0: 6c 6c 79 20 61 6e 64 0a 20 20 2a 2a 20 28 32 29  lly and.  ** (2)
27c0: 20 65 76 65 6e 20 69 66 20 61 6e 20 69 6e 63 6f   even if an inco
27d0: 72 72 65 63 74 20 76 61 6c 75 65 20 69 73 20 72  rrect value is r
27e0: 65 61 64 2c 20 6e 6f 20 67 72 65 61 74 20 68 61  ead, no great ha
27f0: 72 6d 20 69 73 20 64 6f 6e 65 20 73 69 6e 63 65  rm is done since
2800: 20 74 68 69 73 0a 20 20 2a 2a 20 69 73 20 72 65   this.  ** is re
2810: 61 6c 6c 79 20 6a 75 73 74 20 61 6e 20 6f 70 74  ally just an opt
2820: 69 6d 69 7a 61 74 69 6f 6e 2e 20 2a 2f 0a 20 20  imization. */.  
2830: 69 6e 74 20 62 55 6e 64 65 72 50 72 65 73 73 75  int bUnderPressu
2840: 72 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f  re;            /
2850: 2a 20 54 72 75 65 20 69 66 20 6c 6f 77 20 6f 6e  * True if low on
2860: 20 50 41 47 45 43 41 43 48 45 20 6d 65 6d 6f 72   PAGECACHE memor
2870: 79 20 2a 2f 0a 7d 20 70 63 61 63 68 65 31 5f 67  y */.} pcache1_g
2880: 3b 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c 20 63 6f 64  ;../*.** All cod
2890: 65 20 69 6e 20 74 68 69 73 20 66 69 6c 65 20 73  e in this file s
28a0: 68 6f 75 6c 64 20 61 63 63 65 73 73 20 74 68 65  hould access the
28b0: 20 67 6c 6f 62 61 6c 20 73 74 72 75 63 74 75 72   global structur
28c0: 65 20 61 62 6f 76 65 20 76 69 61 20 74 68 65 0a  e above via the.
28d0: 2a 2a 20 61 6c 69 61 73 20 22 70 63 61 63 68 65  ** alias "pcache
28e0: 31 22 2e 20 54 68 69 73 20 65 6e 73 75 72 65 73  1". This ensures
28f0: 20 74 68 61 74 20 74 68 65 20 57 53 44 20 65 6d   that the WSD em
2900: 75 6c 61 74 69 6f 6e 20 69 73 20 75 73 65 64 20  ulation is used 
2910: 77 68 65 6e 0a 2a 2a 20 63 6f 6d 70 69 6c 69 6e  when.** compilin
2920: 67 20 66 6f 72 20 73 79 73 74 65 6d 73 20 74 68  g for systems th
2930: 61 74 20 64 6f 20 6e 6f 74 20 73 75 70 70 6f 72  at do not suppor
2940: 74 20 72 65 61 6c 20 57 53 44 2e 0a 2a 2f 0a 23  t real WSD..*/.#
2950: 64 65 66 69 6e 65 20 70 63 61 63 68 65 31 20 28  define pcache1 (
2960: 47 4c 4f 42 41 4c 28 73 74 72 75 63 74 20 50 43  GLOBAL(struct PC
2970: 61 63 68 65 47 6c 6f 62 61 6c 2c 20 70 63 61 63  acheGlobal, pcac
2980: 68 65 31 5f 67 29 29 0a 0a 2f 2a 0a 2a 2a 20 4d  he1_g))../*.** M
2990: 61 63 72 6f 73 20 74 6f 20 65 6e 74 65 72 20 61  acros to enter a
29a0: 6e 64 20 6c 65 61 76 65 20 74 68 65 20 50 43 61  nd leave the PCa
29b0: 63 68 65 20 4c 52 55 20 6d 75 74 65 78 2e 0a 2a  che LRU mutex..*
29c0: 2f 0a 23 69 66 20 21 64 65 66 69 6e 65 64 28 53  /.#if !defined(S
29d0: 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d  QLITE_ENABLE_MEM
29e0: 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 29 20  ORY_MANAGEMENT) 
29f0: 7c 7c 20 53 51 4c 49 54 45 5f 54 48 52 45 41 44  || SQLITE_THREAD
2a00: 53 41 46 45 3d 3d 30 0a 23 20 64 65 66 69 6e 65  SAFE==0.# define
2a10: 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74   pcache1EnterMut
2a20: 65 78 28 58 29 20 20 61 73 73 65 72 74 28 28 58  ex(X)  assert((X
2a30: 29 2d 3e 6d 75 74 65 78 3d 3d 30 29 0a 23 20 64  )->mutex==0).# d
2a40: 65 66 69 6e 65 20 70 63 61 63 68 65 31 4c 65 61  efine pcache1Lea
2a50: 76 65 4d 75 74 65 78 28 58 29 20 20 61 73 73 65  veMutex(X)  asse
2a60: 72 74 28 28 58 29 2d 3e 6d 75 74 65 78 3d 3d 30  rt((X)->mutex==0
2a70: 29 0a 23 20 64 65 66 69 6e 65 20 50 43 41 43 48  ).# define PCACH
2a80: 45 31 5f 4d 49 47 48 54 5f 55 53 45 5f 47 52 4f  E1_MIGHT_USE_GRO
2a90: 55 50 5f 4d 55 54 45 58 20 30 0a 23 65 6c 73 65  UP_MUTEX 0.#else
2aa0: 0a 23 20 64 65 66 69 6e 65 20 70 63 61 63 68 65  .# define pcache
2ab0: 31 45 6e 74 65 72 4d 75 74 65 78 28 58 29 20 73  1EnterMutex(X) s
2ac0: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e 74  qlite3_mutex_ent
2ad0: 65 72 28 28 58 29 2d 3e 6d 75 74 65 78 29 0a 23  er((X)->mutex).#
2ae0: 20 64 65 66 69 6e 65 20 70 63 61 63 68 65 31 4c   define pcache1L
2af0: 65 61 76 65 4d 75 74 65 78 28 58 29 20 73 71 6c  eaveMutex(X) sql
2b00: 69 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65  ite3_mutex_leave
2b10: 28 28 58 29 2d 3e 6d 75 74 65 78 29 0a 23 20 64  ((X)->mutex).# d
2b20: 65 66 69 6e 65 20 50 43 41 43 48 45 31 5f 4d 49  efine PCACHE1_MI
2b30: 47 48 54 5f 55 53 45 5f 47 52 4f 55 50 5f 4d 55  GHT_USE_GROUP_MU
2b40: 54 45 58 20 31 0a 23 65 6e 64 69 66 0a 0a 2f 2a  TEX 1.#endif../*
2b50: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2b60: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2b70: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2b80: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2b90: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f  *************/./
2ba0: 2a 2a 2a 2a 2a 2a 2a 2a 20 50 61 67 65 20 41 6c  ******** Page Al
2bb0: 6c 6f 63 61 74 69 6f 6e 2f 53 51 4c 49 54 45 5f  location/SQLITE_
2bc0: 43 4f 4e 46 49 47 5f 50 43 41 43 48 45 20 52 65  CONFIG_PCACHE Re
2bd0: 6c 61 74 65 64 20 46 75 6e 63 74 69 6f 6e 73 20  lated Functions 
2be0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a  **************/.
2bf0: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e  ../*.** This fun
2c00: 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20  ction is called 
2c10: 64 75 72 69 6e 67 20 69 6e 69 74 69 61 6c 69 7a  during initializ
2c20: 61 74 69 6f 6e 20 69 66 20 61 20 73 74 61 74 69  ation if a stati
2c30: 63 20 62 75 66 66 65 72 20 69 73 20 0a 2a 2a 20  c buffer is .** 
2c40: 73 75 70 70 6c 69 65 64 20 74 6f 20 75 73 65 20  supplied to use 
2c50: 66 6f 72 20 74 68 65 20 70 61 67 65 2d 63 61 63  for the page-cac
2c60: 68 65 20 62 79 20 70 61 73 73 69 6e 67 20 74 68  he by passing th
2c70: 65 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f  e SQLITE_CONFIG_
2c80: 50 41 47 45 43 41 43 48 45 0a 2a 2a 20 76 65 72  PAGECACHE.** ver
2c90: 62 20 74 6f 20 73 71 6c 69 74 65 33 5f 63 6f 6e  b to sqlite3_con
2ca0: 66 69 67 28 29 2e 20 50 61 72 61 6d 65 74 65 72  fig(). Parameter
2cb0: 20 70 42 75 66 20 70 6f 69 6e 74 73 20 74 6f 20   pBuf points to 
2cc0: 61 6e 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 6c 61  an allocation la
2cd0: 72 67 65 0a 2a 2a 20 65 6e 6f 75 67 68 20 74 6f  rge.** enough to
2ce0: 20 63 6f 6e 74 61 69 6e 20 27 6e 27 20 62 75 66   contain 'n' buf
2cf0: 66 65 72 73 20 6f 66 20 27 73 7a 27 20 62 79 74  fers of 'sz' byt
2d00: 65 73 20 65 61 63 68 2e 0a 2a 2a 0a 2a 2a 20 54  es each..**.** T
2d10: 68 69 73 20 72 6f 75 74 69 6e 65 20 69 73 20 63  his routine is c
2d20: 61 6c 6c 65 64 20 66 72 6f 6d 20 73 71 6c 69 74  alled from sqlit
2d30: 65 33 5f 69 6e 69 74 69 61 6c 69 7a 65 28 29 20  e3_initialize() 
2d40: 61 6e 64 20 73 6f 20 69 74 20 69 73 20 67 75 61  and so it is gua
2d50: 72 61 6e 74 65 65 64 0a 2a 2a 20 74 6f 20 62 65  ranteed.** to be
2d60: 20 73 65 72 69 61 6c 69 7a 65 64 20 61 6c 72 65   serialized alre
2d70: 61 64 79 2e 20 20 54 68 65 72 65 20 69 73 20 6e  ady.  There is n
2d80: 6f 20 6e 65 65 64 20 66 6f 72 20 66 75 72 74 68  o need for furth
2d90: 65 72 20 6d 75 74 65 78 69 6e 67 2e 0a 2a 2f 0a  er mutexing..*/.
2da0: 76 6f 69 64 20 73 71 6c 69 74 65 33 50 43 61 63  void sqlite3PCac
2db0: 68 65 42 75 66 66 65 72 53 65 74 75 70 28 76 6f  heBufferSetup(vo
2dc0: 69 64 20 2a 70 42 75 66 2c 20 69 6e 74 20 73 7a  id *pBuf, int sz
2dd0: 2c 20 69 6e 74 20 6e 29 7b 0a 20 20 69 66 28 20  , int n){.  if( 
2de0: 70 63 61 63 68 65 31 2e 69 73 49 6e 69 74 20 29  pcache1.isInit )
2df0: 7b 0a 20 20 20 20 50 67 46 72 65 65 73 6c 6f 74  {.    PgFreeslot
2e00: 20 2a 70 3b 0a 20 20 20 20 69 66 28 20 70 42 75   *p;.    if( pBu
2e10: 66 3d 3d 30 20 29 20 73 7a 20 3d 20 6e 20 3d 20  f==0 ) sz = n = 
2e20: 30 3b 0a 20 20 20 20 69 66 28 20 6e 3d 3d 30 20  0;.    if( n==0 
2e30: 29 20 73 7a 20 3d 20 30 3b 0a 20 20 20 20 73 7a  ) sz = 0;.    sz
2e40: 20 3d 20 52 4f 55 4e 44 44 4f 57 4e 38 28 73 7a   = ROUNDDOWN8(sz
2e50: 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 73  );.    pcache1.s
2e60: 7a 53 6c 6f 74 20 3d 20 73 7a 3b 0a 20 20 20 20  zSlot = sz;.    
2e70: 70 63 61 63 68 65 31 2e 6e 53 6c 6f 74 20 3d 20  pcache1.nSlot = 
2e80: 70 63 61 63 68 65 31 2e 6e 46 72 65 65 53 6c 6f  pcache1.nFreeSlo
2e90: 74 20 3d 20 6e 3b 0a 20 20 20 20 70 63 61 63 68  t = n;.    pcach
2ea0: 65 31 2e 6e 52 65 73 65 72 76 65 20 3d 20 6e 3e  e1.nReserve = n>
2eb0: 39 30 20 3f 20 31 30 20 3a 20 28 6e 2f 31 30 20  90 ? 10 : (n/10 
2ec0: 2b 20 31 29 3b 0a 20 20 20 20 70 63 61 63 68 65  + 1);.    pcache
2ed0: 31 2e 70 53 74 61 72 74 20 3d 20 70 42 75 66 3b  1.pStart = pBuf;
2ee0: 0a 20 20 20 20 70 63 61 63 68 65 31 2e 70 46 72  .    pcache1.pFr
2ef0: 65 65 20 3d 20 30 3b 0a 20 20 20 20 70 63 61 63  ee = 0;.    pcac
2f00: 68 65 31 2e 62 55 6e 64 65 72 50 72 65 73 73 75  he1.bUnderPressu
2f10: 72 65 20 3d 20 30 3b 0a 20 20 20 20 77 68 69 6c  re = 0;.    whil
2f20: 65 28 20 6e 2d 2d 20 29 7b 0a 20 20 20 20 20 20  e( n-- ){.      
2f30: 70 20 3d 20 28 50 67 46 72 65 65 73 6c 6f 74 2a  p = (PgFreeslot*
2f40: 29 70 42 75 66 3b 0a 20 20 20 20 20 20 70 2d 3e  )pBuf;.      p->
2f50: 70 4e 65 78 74 20 3d 20 70 63 61 63 68 65 31 2e  pNext = pcache1.
2f60: 70 46 72 65 65 3b 0a 20 20 20 20 20 20 70 63 61  pFree;.      pca
2f70: 63 68 65 31 2e 70 46 72 65 65 20 3d 20 70 3b 0a  che1.pFree = p;.
2f80: 20 20 20 20 20 20 70 42 75 66 20 3d 20 28 76 6f        pBuf = (vo
2f90: 69 64 2a 29 26 28 28 63 68 61 72 2a 29 70 42 75  id*)&((char*)pBu
2fa0: 66 29 5b 73 7a 5d 3b 0a 20 20 20 20 7d 0a 20 20  f)[sz];.    }.  
2fb0: 20 20 70 63 61 63 68 65 31 2e 70 45 6e 64 20 3d    pcache1.pEnd =
2fc0: 20 70 42 75 66 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a   pBuf;.  }.}../*
2fd0: 0a 2a 2a 20 54 72 79 20 74 6f 20 69 6e 69 74 69  .** Try to initi
2fe0: 61 6c 69 7a 65 20 74 68 65 20 70 43 61 63 68 65  alize the pCache
2ff0: 2d 3e 70 46 72 65 65 20 61 6e 64 20 70 43 61 63  ->pFree and pCac
3000: 68 65 2d 3e 70 42 75 6c 6b 20 66 69 65 6c 64 73  he->pBulk fields
3010: 2e 20 20 52 65 74 75 72 6e 0a 2a 2a 20 74 72 75  .  Return.** tru
3020: 65 20 69 66 20 70 43 61 63 68 65 2d 3e 70 46 72  e if pCache->pFr
3030: 65 65 20 65 6e 64 73 20 75 70 20 63 6f 6e 74 61  ee ends up conta
3040: 69 6e 69 6e 67 20 6f 6e 65 20 6f 72 20 6d 6f 72  ining one or mor
3050: 65 20 66 72 65 65 20 70 61 67 65 73 2e 0a 2a 2f  e free pages..*/
3060: 0a 73 74 61 74 69 63 20 69 6e 74 20 70 63 61 63  .static int pcac
3070: 68 65 31 49 6e 69 74 42 75 6c 6b 28 50 43 61 63  he1InitBulk(PCac
3080: 68 65 31 20 2a 70 43 61 63 68 65 29 7b 0a 20 20  he1 *pCache){.  
3090: 69 36 34 20 73 7a 42 75 6c 6b 3b 0a 20 20 63 68  i64 szBulk;.  ch
30a0: 61 72 20 2a 7a 42 75 6c 6b 3b 0a 20 20 69 66 28  ar *zBulk;.  if(
30b0: 20 70 63 61 63 68 65 31 2e 6e 49 6e 69 74 50 61   pcache1.nInitPa
30c0: 67 65 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 30  ge==0 ) return 0
30d0: 3b 0a 20 20 2f 2a 20 44 6f 20 6e 6f 74 20 62 6f  ;.  /* Do not bo
30e0: 74 68 65 72 20 77 69 74 68 20 61 20 62 75 6c 6b  ther with a bulk
30f0: 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 69 66 20 74   allocation if t
3100: 68 65 20 63 61 63 68 65 20 73 69 7a 65 20 76 65  he cache size ve
3110: 72 79 20 73 6d 61 6c 6c 20 2a 2f 0a 20 20 69 66  ry small */.  if
3120: 28 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 3c 33  ( pCache->nMax<3
3130: 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 73   ) return 0;.  s
3140: 71 6c 69 74 65 33 42 65 67 69 6e 42 65 6e 69 67  qlite3BeginBenig
3150: 6e 4d 61 6c 6c 6f 63 28 29 3b 0a 20 20 69 66 28  nMalloc();.  if(
3160: 20 70 63 61 63 68 65 31 2e 6e 49 6e 69 74 50 61   pcache1.nInitPa
3170: 67 65 3e 30 20 29 7b 0a 20 20 20 20 73 7a 42 75  ge>0 ){.    szBu
3180: 6c 6b 20 3d 20 70 43 61 63 68 65 2d 3e 73 7a 41  lk = pCache->szA
3190: 6c 6c 6f 63 20 2a 20 28 69 36 34 29 70 63 61 63  lloc * (i64)pcac
31a0: 68 65 31 2e 6e 49 6e 69 74 50 61 67 65 3b 0a 20  he1.nInitPage;. 
31b0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 73 7a 42 75   }else{.    szBu
31c0: 6c 6b 20 3d 20 2d 31 30 32 34 20 2a 20 28 69 36  lk = -1024 * (i6
31d0: 34 29 70 63 61 63 68 65 31 2e 6e 49 6e 69 74 50  4)pcache1.nInitP
31e0: 61 67 65 3b 0a 20 20 7d 0a 20 20 69 66 28 20 73  age;.  }.  if( s
31f0: 7a 42 75 6c 6b 20 3e 20 70 43 61 63 68 65 2d 3e  zBulk > pCache->
3200: 73 7a 41 6c 6c 6f 63 2a 28 69 36 34 29 70 43 61  szAlloc*(i64)pCa
3210: 63 68 65 2d 3e 6e 4d 61 78 20 29 7b 0a 20 20 20  che->nMax ){.   
3220: 20 73 7a 42 75 6c 6b 20 3d 20 70 43 61 63 68 65   szBulk = pCache
3230: 2d 3e 73 7a 41 6c 6c 6f 63 2a 28 69 36 34 29 70  ->szAlloc*(i64)p
3240: 43 61 63 68 65 2d 3e 6e 4d 61 78 3b 0a 20 20 7d  Cache->nMax;.  }
3250: 0a 20 20 7a 42 75 6c 6b 20 3d 20 70 43 61 63 68  .  zBulk = pCach
3260: 65 2d 3e 70 42 75 6c 6b 20 3d 20 73 71 6c 69 74  e->pBulk = sqlit
3270: 65 33 4d 61 6c 6c 6f 63 28 20 73 7a 42 75 6c 6b  e3Malloc( szBulk
3280: 20 29 3b 0a 20 20 73 71 6c 69 74 65 33 45 6e 64   );.  sqlite3End
3290: 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 0a  BenignMalloc();.
32a0: 20 20 69 66 28 20 7a 42 75 6c 6b 20 29 7b 0a 20    if( zBulk ){. 
32b0: 20 20 20 69 6e 74 20 6e 42 75 6c 6b 20 3d 20 73     int nBulk = s
32c0: 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 53 69 7a 65  qlite3MallocSize
32d0: 28 7a 42 75 6c 6b 29 2f 70 43 61 63 68 65 2d 3e  (zBulk)/pCache->
32e0: 73 7a 41 6c 6c 6f 63 3b 0a 20 20 20 20 64 6f 7b  szAlloc;.    do{
32f0: 0a 20 20 20 20 20 20 50 67 48 64 72 31 20 2a 70  .      PgHdr1 *p
3300: 58 20 3d 20 28 50 67 48 64 72 31 2a 29 26 7a 42  X = (PgHdr1*)&zB
3310: 75 6c 6b 5b 70 43 61 63 68 65 2d 3e 73 7a 50 61  ulk[pCache->szPa
3320: 67 65 5d 3b 0a 20 20 20 20 20 20 70 58 2d 3e 70  ge];.      pX->p
3330: 61 67 65 2e 70 42 75 66 20 3d 20 7a 42 75 6c 6b  age.pBuf = zBulk
3340: 3b 0a 20 20 20 20 20 20 70 58 2d 3e 70 61 67 65  ;.      pX->page
3350: 2e 70 45 78 74 72 61 20 3d 20 26 70 58 5b 31 5d  .pExtra = &pX[1]
3360: 3b 0a 20 20 20 20 20 20 70 58 2d 3e 69 73 42 75  ;.      pX->isBu
3370: 6c 6b 4c 6f 63 61 6c 20 3d 20 31 3b 0a 20 20 20  lkLocal = 1;.   
3380: 20 20 20 70 58 2d 3e 69 73 41 6e 63 68 6f 72 20     pX->isAnchor 
3390: 3d 20 30 3b 0a 20 20 20 20 20 20 70 58 2d 3e 70  = 0;.      pX->p
33a0: 4e 65 78 74 20 3d 20 70 43 61 63 68 65 2d 3e 70  Next = pCache->p
33b0: 46 72 65 65 3b 0a 20 20 20 20 20 20 70 43 61 63  Free;.      pCac
33c0: 68 65 2d 3e 70 46 72 65 65 20 3d 20 70 58 3b 0a  he->pFree = pX;.
33d0: 20 20 20 20 20 20 7a 42 75 6c 6b 20 2b 3d 20 70        zBulk += p
33e0: 43 61 63 68 65 2d 3e 73 7a 41 6c 6c 6f 63 3b 0a  Cache->szAlloc;.
33f0: 20 20 20 20 7d 77 68 69 6c 65 28 20 2d 2d 6e 42      }while( --nB
3400: 75 6c 6b 20 29 3b 0a 20 20 7d 0a 20 20 72 65 74  ulk );.  }.  ret
3410: 75 72 6e 20 70 43 61 63 68 65 2d 3e 70 46 72 65  urn pCache->pFre
3420: 65 21 3d 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d  e!=0;.}../*.** M
3430: 61 6c 6c 6f 63 20 66 75 6e 63 74 69 6f 6e 20 75  alloc function u
3440: 73 65 64 20 77 69 74 68 69 6e 20 74 68 69 73 20  sed within this 
3450: 66 69 6c 65 20 74 6f 20 61 6c 6c 6f 63 61 74 65  file to allocate
3460: 20 73 70 61 63 65 20 66 72 6f 6d 20 74 68 65 20   space from the 
3470: 62 75 66 66 65 72 0a 2a 2a 20 63 6f 6e 66 69 67  buffer.** config
3480: 75 72 65 64 20 75 73 69 6e 67 20 73 71 6c 69 74  ured using sqlit
3490: 65 33 5f 63 6f 6e 66 69 67 28 53 51 4c 49 54 45  e3_config(SQLITE
34a0: 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48  _CONFIG_PAGECACH
34b0: 45 29 20 6f 70 74 69 6f 6e 2e 20 49 66 20 6e 6f  E) option. If no
34c0: 20 0a 2a 2a 20 73 75 63 68 20 62 75 66 66 65 72   .** such buffer
34d0: 20 65 78 69 73 74 73 20 6f 72 20 74 68 65 72 65   exists or there
34e0: 20 69 73 20 6e 6f 20 73 70 61 63 65 20 6c 65 66   is no space lef
34f0: 74 20 69 6e 20 69 74 2c 20 74 68 69 73 20 66 75  t in it, this fu
3500: 6e 63 74 69 6f 6e 20 66 61 6c 6c 73 20 0a 2a 2a  nction falls .**
3510: 20 62 61 63 6b 20 74 6f 20 73 71 6c 69 74 65 33   back to sqlite3
3520: 4d 61 6c 6c 6f 63 28 29 2e 0a 2a 2a 0a 2a 2a 20  Malloc()..**.** 
3530: 4d 75 6c 74 69 70 6c 65 20 74 68 72 65 61 64 73  Multiple threads
3540: 20 63 61 6e 20 72 75 6e 20 74 68 69 73 20 72 6f   can run this ro
3550: 75 74 69 6e 65 20 61 74 20 74 68 65 20 73 61 6d  utine at the sam
3560: 65 20 74 69 6d 65 2e 20 20 47 6c 6f 62 61 6c 20  e time.  Global 
3570: 76 61 72 69 61 62 6c 65 73 0a 2a 2a 20 69 6e 20  variables.** in 
3580: 70 63 61 63 68 65 31 20 6e 65 65 64 20 74 6f 20  pcache1 need to 
3590: 62 65 20 70 72 6f 74 65 63 74 65 64 20 76 69 61  be protected via
35a0: 20 6d 75 74 65 78 2e 0a 2a 2f 0a 73 74 61 74 69   mutex..*/.stati
35b0: 63 20 76 6f 69 64 20 2a 70 63 61 63 68 65 31 41  c void *pcache1A
35c0: 6c 6c 6f 63 28 69 6e 74 20 6e 42 79 74 65 29 7b  lloc(int nByte){
35d0: 0a 20 20 76 6f 69 64 20 2a 70 20 3d 20 30 3b 0a  .  void *p = 0;.
35e0: 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65    assert( sqlite
35f0: 33 5f 6d 75 74 65 78 5f 6e 6f 74 68 65 6c 64 28  3_mutex_notheld(
3600: 70 63 61 63 68 65 31 2e 67 72 70 2e 6d 75 74 65  pcache1.grp.mute
3610: 78 29 20 29 3b 0a 20 20 69 66 28 20 6e 42 79 74  x) );.  if( nByt
3620: 65 3c 3d 70 63 61 63 68 65 31 2e 73 7a 53 6c 6f  e<=pcache1.szSlo
3630: 74 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33  t ){.    sqlite3
3640: 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28 70 63 61  _mutex_enter(pca
3650: 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a 20 20 20  che1.mutex);.   
3660: 20 70 20 3d 20 28 50 67 48 64 72 31 20 2a 29 70   p = (PgHdr1 *)p
3670: 63 61 63 68 65 31 2e 70 46 72 65 65 3b 0a 20 20  cache1.pFree;.  
3680: 20 20 69 66 28 20 70 20 29 7b 0a 20 20 20 20 20    if( p ){.     
3690: 20 70 63 61 63 68 65 31 2e 70 46 72 65 65 20 3d   pcache1.pFree =
36a0: 20 70 63 61 63 68 65 31 2e 70 46 72 65 65 2d 3e   pcache1.pFree->
36b0: 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 70 63 61  pNext;.      pca
36c0: 63 68 65 31 2e 6e 46 72 65 65 53 6c 6f 74 2d 2d  che1.nFreeSlot--
36d0: 3b 0a 20 20 20 20 20 20 70 63 61 63 68 65 31 2e  ;.      pcache1.
36e0: 62 55 6e 64 65 72 50 72 65 73 73 75 72 65 20 3d  bUnderPressure =
36f0: 20 70 63 61 63 68 65 31 2e 6e 46 72 65 65 53 6c   pcache1.nFreeSl
3700: 6f 74 3c 70 63 61 63 68 65 31 2e 6e 52 65 73 65  ot<pcache1.nRese
3710: 72 76 65 3b 0a 20 20 20 20 20 20 61 73 73 65 72  rve;.      asser
3720: 74 28 20 70 63 61 63 68 65 31 2e 6e 46 72 65 65  t( pcache1.nFree
3730: 53 6c 6f 74 3e 3d 30 20 29 3b 0a 20 20 20 20 20  Slot>=0 );.     
3740: 20 73 71 6c 69 74 65 33 53 74 61 74 75 73 48 69   sqlite3StatusHi
3750: 67 68 77 61 74 65 72 28 53 51 4c 49 54 45 5f 53  ghwater(SQLITE_S
3760: 54 41 54 55 53 5f 50 41 47 45 43 41 43 48 45 5f  TATUS_PAGECACHE_
3770: 53 49 5a 45 2c 20 6e 42 79 74 65 29 3b 0a 20 20  SIZE, nByte);.  
3780: 20 20 20 20 73 71 6c 69 74 65 33 53 74 61 74 75      sqlite3Statu
3790: 73 55 70 28 53 51 4c 49 54 45 5f 53 54 41 54 55  sUp(SQLITE_STATU
37a0: 53 5f 50 41 47 45 43 41 43 48 45 5f 55 53 45 44  S_PAGECACHE_USED
37b0: 2c 20 31 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20  , 1);.    }.    
37c0: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6c 65  sqlite3_mutex_le
37d0: 61 76 65 28 70 63 61 63 68 65 31 2e 6d 75 74 65  ave(pcache1.mute
37e0: 78 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 3d  x);.  }.  if( p=
37f0: 3d 30 20 29 7b 0a 20 20 20 20 2f 2a 20 4d 65 6d  =0 ){.    /* Mem
3800: 6f 72 79 20 69 73 20 6e 6f 74 20 61 76 61 69 6c  ory is not avail
3810: 61 62 6c 65 20 69 6e 20 74 68 65 20 53 51 4c 49  able in the SQLI
3820: 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41  TE_CONFIG_PAGECA
3830: 43 48 45 20 70 6f 6f 6c 2e 20 20 47 65 74 0a 20  CHE pool.  Get. 
3840: 20 20 20 2a 2a 20 69 74 20 66 72 6f 6d 20 73 71     ** it from sq
3850: 6c 69 74 65 33 4d 61 6c 6c 6f 63 20 69 6e 73 74  lite3Malloc inst
3860: 65 61 64 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20  ead..    */.    
3870: 70 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f  p = sqlite3Mallo
3880: 63 28 6e 42 79 74 65 29 3b 0a 23 69 66 6e 64 65  c(nByte);.#ifnde
3890: 66 20 53 51 4c 49 54 45 5f 44 49 53 41 42 4c 45  f SQLITE_DISABLE
38a0: 5f 50 41 47 45 43 41 43 48 45 5f 4f 56 45 52 46  _PAGECACHE_OVERF
38b0: 4c 4f 57 5f 53 54 41 54 53 0a 20 20 20 20 69 66  LOW_STATS.    if
38c0: 28 20 70 20 29 7b 0a 20 20 20 20 20 20 69 6e 74  ( p ){.      int
38d0: 20 73 7a 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c   sz = sqlite3Mal
38e0: 6c 6f 63 53 69 7a 65 28 70 29 3b 0a 20 20 20 20  locSize(p);.    
38f0: 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f    sqlite3_mutex_
3900: 65 6e 74 65 72 28 70 63 61 63 68 65 31 2e 6d 75  enter(pcache1.mu
3910: 74 65 78 29 3b 0a 20 20 20 20 20 20 73 71 6c 69  tex);.      sqli
3920: 74 65 33 53 74 61 74 75 73 48 69 67 68 77 61 74  te3StatusHighwat
3930: 65 72 28 53 51 4c 49 54 45 5f 53 54 41 54 55 53  er(SQLITE_STATUS
3940: 5f 50 41 47 45 43 41 43 48 45 5f 53 49 5a 45 2c  _PAGECACHE_SIZE,
3950: 20 6e 42 79 74 65 29 3b 0a 20 20 20 20 20 20 73   nByte);.      s
3960: 71 6c 69 74 65 33 53 74 61 74 75 73 55 70 28 53  qlite3StatusUp(S
3970: 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41 47  QLITE_STATUS_PAG
3980: 45 43 41 43 48 45 5f 4f 56 45 52 46 4c 4f 57 2c  ECACHE_OVERFLOW,
3990: 20 73 7a 29 3b 0a 20 20 20 20 20 20 73 71 6c 69   sz);.      sqli
39a0: 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28  te3_mutex_leave(
39b0: 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a  pcache1.mutex);.
39c0: 20 20 20 20 7d 0a 23 65 6e 64 69 66 0a 20 20 20      }.#endif.   
39d0: 20 73 71 6c 69 74 65 33 4d 65 6d 64 65 62 75 67   sqlite3Memdebug
39e0: 53 65 74 54 79 70 65 28 70 2c 20 4d 45 4d 54 59  SetType(p, MEMTY
39f0: 50 45 5f 50 43 41 43 48 45 29 3b 0a 20 20 7d 0a  PE_PCACHE);.  }.
3a00: 20 20 72 65 74 75 72 6e 20 70 3b 0a 7d 0a 0a 2f    return p;.}../
3a10: 2a 0a 2a 2a 20 46 72 65 65 20 61 6e 20 61 6c 6c  *.** Free an all
3a20: 6f 63 61 74 65 64 20 62 75 66 66 65 72 20 6f 62  ocated buffer ob
3a30: 74 61 69 6e 65 64 20 66 72 6f 6d 20 70 63 61 63  tained from pcac
3a40: 68 65 31 41 6c 6c 6f 63 28 29 2e 0a 2a 2f 0a 73  he1Alloc()..*/.s
3a50: 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68  tatic void pcach
3a60: 65 31 46 72 65 65 28 76 6f 69 64 20 2a 70 29 7b  e1Free(void *p){
3a70: 0a 20 20 69 66 28 20 70 3d 3d 30 20 29 20 72 65  .  if( p==0 ) re
3a80: 74 75 72 6e 3b 0a 20 20 69 66 28 20 53 51 4c 49  turn;.  if( SQLI
3a90: 54 45 5f 57 49 54 48 49 4e 28 70 2c 20 70 63 61  TE_WITHIN(p, pca
3aa0: 63 68 65 31 2e 70 53 74 61 72 74 2c 20 70 63 61  che1.pStart, pca
3ab0: 63 68 65 31 2e 70 45 6e 64 29 20 29 7b 0a 20 20  che1.pEnd) ){.  
3ac0: 20 20 50 67 46 72 65 65 73 6c 6f 74 20 2a 70 53    PgFreeslot *pS
3ad0: 6c 6f 74 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  lot;.    sqlite3
3ae0: 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28 70 63 61  _mutex_enter(pca
3af0: 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a 20 20 20  che1.mutex);.   
3b00: 20 73 71 6c 69 74 65 33 53 74 61 74 75 73 44 6f   sqlite3StatusDo
3b10: 77 6e 28 53 51 4c 49 54 45 5f 53 54 41 54 55 53  wn(SQLITE_STATUS
3b20: 5f 50 41 47 45 43 41 43 48 45 5f 55 53 45 44 2c  _PAGECACHE_USED,
3b30: 20 31 29 3b 0a 20 20 20 20 70 53 6c 6f 74 20 3d   1);.    pSlot =
3b40: 20 28 50 67 46 72 65 65 73 6c 6f 74 2a 29 70 3b   (PgFreeslot*)p;
3b50: 0a 20 20 20 20 70 53 6c 6f 74 2d 3e 70 4e 65 78  .    pSlot->pNex
3b60: 74 20 3d 20 70 63 61 63 68 65 31 2e 70 46 72 65  t = pcache1.pFre
3b70: 65 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 70  e;.    pcache1.p
3b80: 46 72 65 65 20 3d 20 70 53 6c 6f 74 3b 0a 20 20  Free = pSlot;.  
3b90: 20 20 70 63 61 63 68 65 31 2e 6e 46 72 65 65 53    pcache1.nFreeS
3ba0: 6c 6f 74 2b 2b 3b 0a 20 20 20 20 70 63 61 63 68  lot++;.    pcach
3bb0: 65 31 2e 62 55 6e 64 65 72 50 72 65 73 73 75 72  e1.bUnderPressur
3bc0: 65 20 3d 20 70 63 61 63 68 65 31 2e 6e 46 72 65  e = pcache1.nFre
3bd0: 65 53 6c 6f 74 3c 70 63 61 63 68 65 31 2e 6e 52  eSlot<pcache1.nR
3be0: 65 73 65 72 76 65 3b 0a 20 20 20 20 61 73 73 65  eserve;.    asse
3bf0: 72 74 28 20 70 63 61 63 68 65 31 2e 6e 46 72 65  rt( pcache1.nFre
3c00: 65 53 6c 6f 74 3c 3d 70 63 61 63 68 65 31 2e 6e  eSlot<=pcache1.n
3c10: 53 6c 6f 74 20 29 3b 0a 20 20 20 20 73 71 6c 69  Slot );.    sqli
3c20: 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28  te3_mutex_leave(
3c30: 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a  pcache1.mutex);.
3c40: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 61 73 73    }else{.    ass
3c50: 65 72 74 28 20 73 71 6c 69 74 65 33 4d 65 6d 64  ert( sqlite3Memd
3c60: 65 62 75 67 48 61 73 54 79 70 65 28 70 2c 20 4d  ebugHasType(p, M
3c70: 45 4d 54 59 50 45 5f 50 43 41 43 48 45 29 20 29  EMTYPE_PCACHE) )
3c80: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 4d 65 6d  ;.    sqlite3Mem
3c90: 64 65 62 75 67 53 65 74 54 79 70 65 28 70 2c 20  debugSetType(p, 
3ca0: 4d 45 4d 54 59 50 45 5f 48 45 41 50 29 3b 0a 23  MEMTYPE_HEAP);.#
3cb0: 69 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 44 49  ifndef SQLITE_DI
3cc0: 53 41 42 4c 45 5f 50 41 47 45 43 41 43 48 45 5f  SABLE_PAGECACHE_
3cd0: 4f 56 45 52 46 4c 4f 57 5f 53 54 41 54 53 0a 20  OVERFLOW_STATS. 
3ce0: 20 20 20 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e     {.      int n
3cf0: 46 72 65 65 64 20 3d 20 30 3b 0a 20 20 20 20 20  Freed = 0;.     
3d00: 20 6e 46 72 65 65 64 20 3d 20 73 71 6c 69 74 65   nFreed = sqlite
3d10: 33 4d 61 6c 6c 6f 63 53 69 7a 65 28 70 29 3b 0a  3MallocSize(p);.
3d20: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 75        sqlite3_mu
3d30: 74 65 78 5f 65 6e 74 65 72 28 70 63 61 63 68 65  tex_enter(pcache
3d40: 31 2e 6d 75 74 65 78 29 3b 0a 20 20 20 20 20 20  1.mutex);.      
3d50: 73 71 6c 69 74 65 33 53 74 61 74 75 73 44 6f 77  sqlite3StatusDow
3d60: 6e 28 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f  n(SQLITE_STATUS_
3d70: 50 41 47 45 43 41 43 48 45 5f 4f 56 45 52 46 4c  PAGECACHE_OVERFL
3d80: 4f 57 2c 20 6e 46 72 65 65 64 29 3b 0a 20 20 20  OW, nFreed);.   
3d90: 20 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78     sqlite3_mutex
3da0: 5f 6c 65 61 76 65 28 70 63 61 63 68 65 31 2e 6d  _leave(pcache1.m
3db0: 75 74 65 78 29 3b 0a 20 20 20 20 7d 0a 23 65 6e  utex);.    }.#en
3dc0: 64 69 66 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  dif.    sqlite3_
3dd0: 66 72 65 65 28 70 29 3b 0a 20 20 7d 0a 7d 0a 0a  free(p);.  }.}..
3de0: 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 45 4e  #ifdef SQLITE_EN
3df0: 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41  ABLE_MEMORY_MANA
3e00: 47 45 4d 45 4e 54 0a 2f 2a 0a 2a 2a 20 52 65 74  GEMENT./*.** Ret
3e10: 75 72 6e 20 74 68 65 20 73 69 7a 65 20 6f 66 20  urn the size of 
3e20: 61 20 70 63 61 63 68 65 20 61 6c 6c 6f 63 61 74  a pcache allocat
3e30: 69 6f 6e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ion.*/.static in
3e40: 74 20 70 63 61 63 68 65 31 4d 65 6d 53 69 7a 65  t pcache1MemSize
3e50: 28 76 6f 69 64 20 2a 70 29 7b 0a 20 20 69 66 28  (void *p){.  if(
3e60: 20 70 3e 3d 70 63 61 63 68 65 31 2e 70 53 74 61   p>=pcache1.pSta
3e70: 72 74 20 26 26 20 70 3c 70 63 61 63 68 65 31 2e  rt && p<pcache1.
3e80: 70 45 6e 64 20 29 7b 0a 20 20 20 20 72 65 74 75  pEnd ){.    retu
3e90: 72 6e 20 70 63 61 63 68 65 31 2e 73 7a 53 6c 6f  rn pcache1.szSlo
3ea0: 74 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  t;.  }else{.    
3eb0: 69 6e 74 20 69 53 69 7a 65 3b 0a 20 20 20 20 61  int iSize;.    a
3ec0: 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 4d 65  ssert( sqlite3Me
3ed0: 6d 64 65 62 75 67 48 61 73 54 79 70 65 28 70 2c  mdebugHasType(p,
3ee0: 20 4d 45 4d 54 59 50 45 5f 50 43 41 43 48 45 29   MEMTYPE_PCACHE)
3ef0: 20 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 4d   );.    sqlite3M
3f00: 65 6d 64 65 62 75 67 53 65 74 54 79 70 65 28 70  emdebugSetType(p
3f10: 2c 20 4d 45 4d 54 59 50 45 5f 48 45 41 50 29 3b  , MEMTYPE_HEAP);
3f20: 0a 20 20 20 20 69 53 69 7a 65 20 3d 20 73 71 6c  .    iSize = sql
3f30: 69 74 65 33 4d 61 6c 6c 6f 63 53 69 7a 65 28 70  ite3MallocSize(p
3f40: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 4d 65  );.    sqlite3Me
3f50: 6d 64 65 62 75 67 53 65 74 54 79 70 65 28 70 2c  mdebugSetType(p,
3f60: 20 4d 45 4d 54 59 50 45 5f 50 43 41 43 48 45 29   MEMTYPE_PCACHE)
3f70: 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 69 53 69  ;.    return iSi
3f80: 7a 65 3b 0a 20 20 7d 0a 7d 0a 23 65 6e 64 69 66  ze;.  }.}.#endif
3f90: 20 2f 2a 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c   /* SQLITE_ENABL
3fa0: 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d  E_MEMORY_MANAGEM
3fb0: 45 4e 54 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 41 6c  ENT */../*.** Al
3fc0: 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 70 61 67  locate a new pag
3fd0: 65 20 6f 62 6a 65 63 74 20 69 6e 69 74 69 61 6c  e object initial
3fe0: 6c 79 20 61 73 73 6f 63 69 61 74 65 64 20 77 69  ly associated wi
3ff0: 74 68 20 63 61 63 68 65 20 70 43 61 63 68 65 2e  th cache pCache.
4000: 0a 2a 2f 0a 73 74 61 74 69 63 20 50 67 48 64 72  .*/.static PgHdr
4010: 31 20 2a 70 63 61 63 68 65 31 41 6c 6c 6f 63 50  1 *pcache1AllocP
4020: 61 67 65 28 50 43 61 63 68 65 31 20 2a 70 43 61  age(PCache1 *pCa
4030: 63 68 65 2c 20 69 6e 74 20 62 65 6e 69 67 6e 4d  che, int benignM
4040: 61 6c 6c 6f 63 29 7b 0a 20 20 50 67 48 64 72 31  alloc){.  PgHdr1
4050: 20 2a 70 20 3d 20 30 3b 0a 20 20 76 6f 69 64 20   *p = 0;.  void 
4060: 2a 70 50 67 3b 0a 0a 20 20 61 73 73 65 72 74 28  *pPg;..  assert(
4070: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68   sqlite3_mutex_h
4080: 65 6c 64 28 70 43 61 63 68 65 2d 3e 70 47 72 6f  eld(pCache->pGro
4090: 75 70 2d 3e 6d 75 74 65 78 29 20 29 3b 0a 20 20  up->mutex) );.  
40a0: 69 66 28 20 70 43 61 63 68 65 2d 3e 70 46 72 65  if( pCache->pFre
40b0: 65 20 7c 7c 20 28 70 43 61 63 68 65 2d 3e 6e 50  e || (pCache->nP
40c0: 61 67 65 3d 3d 30 20 26 26 20 70 63 61 63 68 65  age==0 && pcache
40d0: 31 49 6e 69 74 42 75 6c 6b 28 70 43 61 63 68 65  1InitBulk(pCache
40e0: 29 29 20 29 7b 0a 20 20 20 20 70 20 3d 20 70 43  )) ){.    p = pC
40f0: 61 63 68 65 2d 3e 70 46 72 65 65 3b 0a 20 20 20  ache->pFree;.   
4100: 20 70 43 61 63 68 65 2d 3e 70 46 72 65 65 20 3d   pCache->pFree =
4110: 20 70 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 70   p->pNext;.    p
4120: 2d 3e 70 4e 65 78 74 20 3d 20 30 3b 0a 20 20 7d  ->pNext = 0;.  }
4130: 65 6c 73 65 7b 0a 23 69 66 64 65 66 20 53 51 4c  else{.#ifdef SQL
4140: 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52  ITE_ENABLE_MEMOR
4150: 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 0a 20 20 20  Y_MANAGEMENT.   
4160: 20 2f 2a 20 54 68 65 20 67 72 6f 75 70 20 6d 75   /* The group mu
4170: 74 65 78 20 6d 75 73 74 20 62 65 20 72 65 6c 65  tex must be rele
4180: 61 73 65 64 20 62 65 66 6f 72 65 20 70 63 61 63  ased before pcac
4190: 68 65 31 41 6c 6c 6f 63 28 29 20 69 73 20 63 61  he1Alloc() is ca
41a0: 6c 6c 65 64 2e 20 54 68 69 73 0a 20 20 20 20 2a  lled. This.    *
41b0: 2a 20 69 73 20 62 65 63 61 75 73 65 20 69 74 20  * is because it 
41c0: 6d 69 67 68 74 20 63 61 6c 6c 20 73 71 6c 69 74  might call sqlit
41d0: 65 33 5f 72 65 6c 65 61 73 65 5f 6d 65 6d 6f 72  e3_release_memor
41e0: 79 28 29 2c 20 77 68 69 63 68 20 61 73 73 75 6d  y(), which assum
41f0: 65 73 20 74 68 61 74 20 0a 20 20 20 20 2a 2a 20  es that .    ** 
4200: 74 68 69 73 20 6d 75 74 65 78 20 69 73 20 6e 6f  this mutex is no
4210: 74 20 68 65 6c 64 2e 20 2a 2f 0a 20 20 20 20 61  t held. */.    a
4220: 73 73 65 72 74 28 20 70 63 61 63 68 65 31 2e 73  ssert( pcache1.s
4230: 65 70 61 72 61 74 65 43 61 63 68 65 3d 3d 30 20  eparateCache==0 
4240: 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70  );.    assert( p
4250: 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3d 3d 26  Cache->pGroup==&
4260: 70 63 61 63 68 65 31 2e 67 72 70 20 29 3b 0a 20  pcache1.grp );. 
4270: 20 20 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d     pcache1LeaveM
4280: 75 74 65 78 28 70 43 61 63 68 65 2d 3e 70 47 72  utex(pCache->pGr
4290: 6f 75 70 29 3b 0a 23 65 6e 64 69 66 0a 20 20 20  oup);.#endif.   
42a0: 20 69 66 28 20 62 65 6e 69 67 6e 4d 61 6c 6c 6f   if( benignMallo
42b0: 63 20 29 7b 20 73 71 6c 69 74 65 33 42 65 67 69  c ){ sqlite3Begi
42c0: 6e 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b  nBenignMalloc();
42d0: 20 7d 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45   }.#ifdef SQLITE
42e0: 5f 50 43 41 43 48 45 5f 53 45 50 41 52 41 54 45  _PCACHE_SEPARATE
42f0: 5f 48 45 41 44 45 52 0a 20 20 20 20 70 50 67 20  _HEADER.    pPg 
4300: 3d 20 70 63 61 63 68 65 31 41 6c 6c 6f 63 28 70  = pcache1Alloc(p
4310: 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 29 3b 0a  Cache->szPage);.
4320: 20 20 20 20 70 20 3d 20 73 71 6c 69 74 65 33 4d      p = sqlite3M
4330: 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 50 67 48  alloc(sizeof(PgH
4340: 64 72 31 29 20 2b 20 70 43 61 63 68 65 2d 3e 73  dr1) + pCache->s
4350: 7a 45 78 74 72 61 29 3b 0a 20 20 20 20 69 66 28  zExtra);.    if(
4360: 20 21 70 50 67 20 7c 7c 20 21 70 20 29 7b 0a 20   !pPg || !p ){. 
4370: 20 20 20 20 20 70 63 61 63 68 65 31 46 72 65 65       pcache1Free
4380: 28 70 50 67 29 3b 0a 20 20 20 20 20 20 73 71 6c  (pPg);.      sql
4390: 69 74 65 33 5f 66 72 65 65 28 70 29 3b 0a 20 20  ite3_free(p);.  
43a0: 20 20 20 20 70 50 67 20 3d 20 30 3b 0a 20 20 20      pPg = 0;.   
43b0: 20 7d 0a 23 65 6c 73 65 0a 20 20 20 20 70 50 67   }.#else.    pPg
43c0: 20 3d 20 70 63 61 63 68 65 31 41 6c 6c 6f 63 28   = pcache1Alloc(
43d0: 70 43 61 63 68 65 2d 3e 73 7a 41 6c 6c 6f 63 29  pCache->szAlloc)
43e0: 3b 0a 20 20 20 20 70 20 3d 20 28 50 67 48 64 72  ;.    p = (PgHdr
43f0: 31 20 2a 29 26 28 28 75 38 20 2a 29 70 50 67 29  1 *)&((u8 *)pPg)
4400: 5b 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 5d  [pCache->szPage]
4410: 3b 0a 23 65 6e 64 69 66 0a 20 20 20 20 69 66 28  ;.#endif.    if(
4420: 20 62 65 6e 69 67 6e 4d 61 6c 6c 6f 63 20 29 7b   benignMalloc ){
4430: 20 73 71 6c 69 74 65 33 45 6e 64 42 65 6e 69 67   sqlite3EndBenig
4440: 6e 4d 61 6c 6c 6f 63 28 29 3b 20 7d 0a 23 69 66  nMalloc(); }.#if
4450: 64 65 66 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c  def SQLITE_ENABL
4460: 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d  E_MEMORY_MANAGEM
4470: 45 4e 54 0a 20 20 20 20 70 63 61 63 68 65 31 45  ENT.    pcache1E
4480: 6e 74 65 72 4d 75 74 65 78 28 70 43 61 63 68 65  nterMutex(pCache
4490: 2d 3e 70 47 72 6f 75 70 29 3b 0a 23 65 6e 64 69  ->pGroup);.#endi
44a0: 66 0a 20 20 20 20 69 66 28 20 70 50 67 3d 3d 30  f.    if( pPg==0
44b0: 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 20   ) return 0;.   
44c0: 20 70 2d 3e 70 61 67 65 2e 70 42 75 66 20 3d 20   p->page.pBuf = 
44d0: 70 50 67 3b 0a 20 20 20 20 70 2d 3e 70 61 67 65  pPg;.    p->page
44e0: 2e 70 45 78 74 72 61 20 3d 20 26 70 5b 31 5d 3b  .pExtra = &p[1];
44f0: 0a 20 20 20 20 70 2d 3e 69 73 42 75 6c 6b 4c 6f  .    p->isBulkLo
4500: 63 61 6c 20 3d 20 30 3b 0a 20 20 20 20 70 2d 3e  cal = 0;.    p->
4510: 69 73 41 6e 63 68 6f 72 20 3d 20 30 3b 0a 20 20  isAnchor = 0;.  
4520: 7d 0a 20 20 28 2a 70 43 61 63 68 65 2d 3e 70 6e  }.  (*pCache->pn
4530: 50 75 72 67 65 61 62 6c 65 29 2b 2b 3b 0a 20 20  Purgeable)++;.  
4540: 72 65 74 75 72 6e 20 70 3b 0a 7d 0a 0a 2f 2a 0a  return p;.}../*.
4550: 2a 2a 20 46 72 65 65 20 61 20 70 61 67 65 20 6f  ** Free a page o
4560: 62 6a 65 63 74 20 61 6c 6c 6f 63 61 74 65 64 20  bject allocated 
4570: 62 79 20 70 63 61 63 68 65 31 41 6c 6c 6f 63 50  by pcache1AllocP
4580: 61 67 65 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63  age()..*/.static
4590: 20 76 6f 69 64 20 70 63 61 63 68 65 31 46 72 65   void pcache1Fre
45a0: 65 50 61 67 65 28 50 67 48 64 72 31 20 2a 70 29  ePage(PgHdr1 *p)
45b0: 7b 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43 61  {.  PCache1 *pCa
45c0: 63 68 65 3b 0a 20 20 61 73 73 65 72 74 28 20 70  che;.  assert( p
45d0: 21 3d 30 20 29 3b 0a 20 20 70 43 61 63 68 65 20  !=0 );.  pCache 
45e0: 3d 20 70 2d 3e 70 43 61 63 68 65 3b 0a 20 20 61  = p->pCache;.  a
45f0: 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d  ssert( sqlite3_m
4600: 75 74 65 78 5f 68 65 6c 64 28 70 2d 3e 70 43 61  utex_held(p->pCa
4610: 63 68 65 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75 74  che->pGroup->mut
4620: 65 78 29 20 29 3b 0a 20 20 69 66 28 20 70 2d 3e  ex) );.  if( p->
4630: 69 73 42 75 6c 6b 4c 6f 63 61 6c 20 29 7b 0a 20  isBulkLocal ){. 
4640: 20 20 20 70 2d 3e 70 4e 65 78 74 20 3d 20 70 43     p->pNext = pC
4650: 61 63 68 65 2d 3e 70 46 72 65 65 3b 0a 20 20 20  ache->pFree;.   
4660: 20 70 43 61 63 68 65 2d 3e 70 46 72 65 65 20 3d   pCache->pFree =
4670: 20 70 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20   p;.  }else{.   
4680: 20 70 63 61 63 68 65 31 46 72 65 65 28 70 2d 3e   pcache1Free(p->
4690: 70 61 67 65 2e 70 42 75 66 29 3b 0a 23 69 66 64  page.pBuf);.#ifd
46a0: 65 66 20 53 51 4c 49 54 45 5f 50 43 41 43 48 45  ef SQLITE_PCACHE
46b0: 5f 53 45 50 41 52 41 54 45 5f 48 45 41 44 45 52  _SEPARATE_HEADER
46c0: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65  .    sqlite3_fre
46d0: 65 28 70 29 3b 0a 23 65 6e 64 69 66 0a 20 20 7d  e(p);.#endif.  }
46e0: 0a 20 20 28 2a 70 43 61 63 68 65 2d 3e 70 6e 50  .  (*pCache->pnP
46f0: 75 72 67 65 61 62 6c 65 29 2d 2d 3b 0a 7d 0a 0a  urgeable)--;.}..
4700: 2f 2a 0a 2a 2a 20 4d 61 6c 6c 6f 63 20 66 75 6e  /*.** Malloc fun
4710: 63 74 69 6f 6e 20 75 73 65 64 20 62 79 20 53 51  ction used by SQ
4720: 4c 69 74 65 20 74 6f 20 6f 62 74 61 69 6e 20 73  Lite to obtain s
4730: 70 61 63 65 20 66 72 6f 6d 20 74 68 65 20 62 75  pace from the bu
4740: 66 66 65 72 20 63 6f 6e 66 69 67 75 72 65 64 0a  ffer configured.
4750: 2a 2a 20 75 73 69 6e 67 20 73 71 6c 69 74 65 33  ** using sqlite3
4760: 5f 63 6f 6e 66 69 67 28 53 51 4c 49 54 45 5f 43  _config(SQLITE_C
4770: 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48 45 29  ONFIG_PAGECACHE)
4780: 20 6f 70 74 69 6f 6e 2e 20 49 66 20 6e 6f 20 73   option. If no s
4790: 75 63 68 20 62 75 66 66 65 72 0a 2a 2a 20 65 78  uch buffer.** ex
47a0: 69 73 74 73 2c 20 74 68 69 73 20 66 75 6e 63 74  ists, this funct
47b0: 69 6f 6e 20 66 61 6c 6c 73 20 62 61 63 6b 20 74  ion falls back t
47c0: 6f 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28  o sqlite3Malloc(
47d0: 29 2e 0a 2a 2f 0a 76 6f 69 64 20 2a 73 71 6c 69  )..*/.void *sqli
47e0: 74 65 33 50 61 67 65 4d 61 6c 6c 6f 63 28 69 6e  te3PageMalloc(in
47f0: 74 20 73 7a 29 7b 0a 20 20 72 65 74 75 72 6e 20  t sz){.  return 
4800: 70 63 61 63 68 65 31 41 6c 6c 6f 63 28 73 7a 29  pcache1Alloc(sz)
4810: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20  ;.}../*.** Free 
4820: 61 6e 20 61 6c 6c 6f 63 61 74 65 64 20 62 75 66  an allocated buf
4830: 66 65 72 20 6f 62 74 61 69 6e 65 64 20 66 72 6f  fer obtained fro
4840: 6d 20 73 71 6c 69 74 65 33 50 61 67 65 4d 61 6c  m sqlite3PageMal
4850: 6c 6f 63 28 29 2e 0a 2a 2f 0a 76 6f 69 64 20 73  loc()..*/.void s
4860: 71 6c 69 74 65 33 50 61 67 65 46 72 65 65 28 76  qlite3PageFree(v
4870: 6f 69 64 20 2a 70 29 7b 0a 20 20 70 63 61 63 68  oid *p){.  pcach
4880: 65 31 46 72 65 65 28 70 29 3b 0a 7d 0a 0a 0a 2f  e1Free(p);.}.../
4890: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 72 75 65  *.** Return true
48a0: 20 69 66 20 69 74 20 64 65 73 69 72 61 62 6c 65   if it desirable
48b0: 20 74 6f 20 61 76 6f 69 64 20 61 6c 6c 6f 63 61   to avoid alloca
48c0: 74 69 6e 67 20 61 20 6e 65 77 20 70 61 67 65 20  ting a new page 
48d0: 63 61 63 68 65 0a 2a 2a 20 65 6e 74 72 79 2e 0a  cache.** entry..
48e0: 2a 2a 0a 2a 2a 20 49 66 20 6d 65 6d 6f 72 79 20  **.** If memory 
48f0: 77 61 73 20 61 6c 6c 6f 63 61 74 65 64 20 73 70  was allocated sp
4900: 65 63 69 66 69 63 61 6c 6c 79 20 74 6f 20 74 68  ecifically to th
4910: 65 20 70 61 67 65 20 63 61 63 68 65 20 75 73 69  e page cache usi
4920: 6e 67 0a 2a 2a 20 53 51 4c 49 54 45 5f 43 4f 4e  ng.** SQLITE_CON
4930: 46 49 47 5f 50 41 47 45 43 41 43 48 45 20 62 75  FIG_PAGECACHE bu
4940: 74 20 74 68 61 74 20 6d 65 6d 6f 72 79 20 68 61  t that memory ha
4950: 73 20 61 6c 6c 20 62 65 65 6e 20 75 73 65 64 2c  s all been used,
4960: 20 74 68 65 6e 0a 2a 2a 20 69 74 20 69 73 20 64   then.** it is d
4970: 65 73 69 72 61 62 6c 65 20 74 6f 20 61 76 6f 69  esirable to avoi
4980: 64 20 61 6c 6c 6f 63 61 74 69 6e 67 20 61 20 6e  d allocating a n
4990: 65 77 20 70 61 67 65 20 63 61 63 68 65 20 65 6e  ew page cache en
49a0: 74 72 79 20 62 65 63 61 75 73 65 0a 2a 2a 20 70  try because.** p
49b0: 72 65 73 75 6d 61 62 6c 79 20 53 51 4c 49 54 45  resumably SQLITE
49c0: 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48  _CONFIG_PAGECACH
49d0: 45 20 77 61 73 20 73 75 70 70 6f 73 65 20 74 6f  E was suppose to
49e0: 20 62 65 20 73 75 66 66 69 63 69 65 6e 74 0a 2a   be sufficient.*
49f0: 2a 20 66 6f 72 20 61 6c 6c 20 70 61 67 65 20 63  * for all page c
4a00: 61 63 68 65 20 6e 65 65 64 73 20 61 6e 64 20 77  ache needs and w
4a10: 65 20 73 68 6f 75 6c 64 20 6e 6f 74 20 6e 65 65  e should not nee
4a20: 64 20 74 6f 20 73 70 69 6c 6c 20 74 68 65 0a 2a  d to spill the.*
4a30: 2a 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 6f 6e 74  * allocation ont
4a40: 6f 20 74 68 65 20 68 65 61 70 2e 0a 2a 2a 0a 2a  o the heap..**.*
4a50: 2a 20 4f 72 2c 20 74 68 65 20 68 65 61 70 20 69  * Or, the heap i
4a60: 73 20 75 73 65 64 20 66 6f 72 20 61 6c 6c 20 70  s used for all p
4a70: 61 67 65 20 63 61 63 68 65 20 6d 65 6d 6f 72 79  age cache memory
4a80: 20 62 75 74 20 74 68 65 20 68 65 61 70 20 69 73   but the heap is
4a90: 0a 2a 2a 20 75 6e 64 65 72 20 6d 65 6d 6f 72 79  .** under memory
4aa0: 20 70 72 65 73 73 75 72 65 2c 20 74 68 65 6e 20   pressure, then 
4ab0: 61 67 61 69 6e 20 69 74 20 69 73 20 64 65 73 69  again it is desi
4ac0: 72 61 62 6c 65 20 74 6f 20 61 76 6f 69 64 0a 2a  rable to avoid.*
4ad0: 2a 20 61 6c 6c 6f 63 61 74 69 6e 67 20 61 20 6e  * allocating a n
4ae0: 65 77 20 70 61 67 65 20 63 61 63 68 65 20 65 6e  ew page cache en
4af0: 74 72 79 20 69 6e 20 6f 72 64 65 72 20 74 6f 20  try in order to 
4b00: 61 76 6f 69 64 20 73 74 72 65 73 73 69 6e 67 0a  avoid stressing.
4b10: 2a 2a 20 74 68 65 20 68 65 61 70 20 65 76 65 6e  ** the heap even
4b20: 20 66 75 72 74 68 65 72 2e 0a 2a 2f 0a 73 74 61   further..*/.sta
4b30: 74 69 63 20 69 6e 74 20 70 63 61 63 68 65 31 55  tic int pcache1U
4b40: 6e 64 65 72 4d 65 6d 6f 72 79 50 72 65 73 73 75  nderMemoryPressu
4b50: 72 65 28 50 43 61 63 68 65 31 20 2a 70 43 61 63  re(PCache1 *pCac
4b60: 68 65 29 7b 0a 20 20 69 66 28 20 70 63 61 63 68  he){.  if( pcach
4b70: 65 31 2e 6e 53 6c 6f 74 20 26 26 20 28 70 43 61  e1.nSlot && (pCa
4b80: 63 68 65 2d 3e 73 7a 50 61 67 65 2b 70 43 61 63  che->szPage+pCac
4b90: 68 65 2d 3e 73 7a 45 78 74 72 61 29 3c 3d 70 63  he->szExtra)<=pc
4ba0: 61 63 68 65 31 2e 73 7a 53 6c 6f 74 20 29 7b 0a  ache1.szSlot ){.
4bb0: 20 20 20 20 72 65 74 75 72 6e 20 70 63 61 63 68      return pcach
4bc0: 65 31 2e 62 55 6e 64 65 72 50 72 65 73 73 75 72  e1.bUnderPressur
4bd0: 65 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  e;.  }else{.    
4be0: 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 48 65  return sqlite3He
4bf0: 61 70 4e 65 61 72 6c 79 46 75 6c 6c 28 29 3b 0a  apNearlyFull();.
4c00: 20 20 7d 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a    }.}../********
4c10: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4c20: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4c30: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4c40: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4c50: 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 2a 2a 2a 2a 2a 2a  ******/./*******
4c60: 2a 20 47 65 6e 65 72 61 6c 20 49 6d 70 6c 65 6d  * General Implem
4c70: 65 6e 74 61 74 69 6f 6e 20 46 75 6e 63 74 69 6f  entation Functio
4c80: 6e 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ns *************
4c90: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4ca0: 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f 2a 0a 2a 2a 20  *******/../*.** 
4cb0: 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73  This function is
4cc0: 20 75 73 65 64 20 74 6f 20 72 65 73 69 7a 65 20   used to resize 
4cd0: 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 20 75  the hash table u
4ce0: 73 65 64 20 62 79 20 74 68 65 20 63 61 63 68 65  sed by the cache
4cf0: 20 70 61 73 73 65 64 0a 2a 2a 20 61 73 20 74 68   passed.** as th
4d00: 65 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74  e first argument
4d10: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 50 43 61 63  ..**.** The PCac
4d20: 68 65 20 6d 75 74 65 78 20 6d 75 73 74 20 62 65  he mutex must be
4d30: 20 68 65 6c 64 20 77 68 65 6e 20 74 68 69 73 20   held when this 
4d40: 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c  function is call
4d50: 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ed..*/.static vo
4d60: 69 64 20 70 63 61 63 68 65 31 52 65 73 69 7a 65  id pcache1Resize
4d70: 48 61 73 68 28 50 43 61 63 68 65 31 20 2a 70 29  Hash(PCache1 *p)
4d80: 7b 0a 20 20 50 67 48 64 72 31 20 2a 2a 61 70 4e  {.  PgHdr1 **apN
4d90: 65 77 3b 0a 20 20 75 6e 73 69 67 6e 65 64 20 69  ew;.  unsigned i
4da0: 6e 74 20 6e 4e 65 77 3b 0a 20 20 75 6e 73 69 67  nt nNew;.  unsig
4db0: 6e 65 64 20 69 6e 74 20 69 3b 0a 0a 20 20 61 73  ned int i;..  as
4dc0: 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75  sert( sqlite3_mu
4dd0: 74 65 78 5f 68 65 6c 64 28 70 2d 3e 70 47 72 6f  tex_held(p->pGro
4de0: 75 70 2d 3e 6d 75 74 65 78 29 20 29 3b 0a 0a 20  up->mutex) );.. 
4df0: 20 6e 4e 65 77 20 3d 20 70 2d 3e 6e 48 61 73 68   nNew = p->nHash
4e00: 2a 32 3b 0a 20 20 69 66 28 20 6e 4e 65 77 3c 32  *2;.  if( nNew<2
4e10: 35 36 20 29 7b 0a 20 20 20 20 6e 4e 65 77 20 3d  56 ){.    nNew =
4e20: 20 32 35 36 3b 0a 20 20 7d 0a 0a 20 20 70 63 61   256;.  }..  pca
4e30: 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 70  che1LeaveMutex(p
4e40: 2d 3e 70 47 72 6f 75 70 29 3b 0a 20 20 69 66 28  ->pGroup);.  if(
4e50: 20 70 2d 3e 6e 48 61 73 68 20 29 7b 20 73 71 6c   p->nHash ){ sql
4e60: 69 74 65 33 42 65 67 69 6e 42 65 6e 69 67 6e 4d  ite3BeginBenignM
4e70: 61 6c 6c 6f 63 28 29 3b 20 7d 0a 20 20 61 70 4e  alloc(); }.  apN
4e80: 65 77 20 3d 20 28 50 67 48 64 72 31 20 2a 2a 29  ew = (PgHdr1 **)
4e90: 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65 72  sqlite3MallocZer
4ea0: 6f 28 73 69 7a 65 6f 66 28 50 67 48 64 72 31 20  o(sizeof(PgHdr1 
4eb0: 2a 29 2a 6e 4e 65 77 29 3b 0a 20 20 69 66 28 20  *)*nNew);.  if( 
4ec0: 70 2d 3e 6e 48 61 73 68 20 29 7b 20 73 71 6c 69  p->nHash ){ sqli
4ed0: 74 65 33 45 6e 64 42 65 6e 69 67 6e 4d 61 6c 6c  te3EndBenignMall
4ee0: 6f 63 28 29 3b 20 7d 0a 20 20 70 63 61 63 68 65  oc(); }.  pcache
4ef0: 31 45 6e 74 65 72 4d 75 74 65 78 28 70 2d 3e 70  1EnterMutex(p->p
4f00: 47 72 6f 75 70 29 3b 0a 20 20 69 66 28 20 61 70  Group);.  if( ap
4f10: 4e 65 77 20 29 7b 0a 20 20 20 20 66 6f 72 28 69  New ){.    for(i
4f20: 3d 30 3b 20 69 3c 70 2d 3e 6e 48 61 73 68 3b 20  =0; i<p->nHash; 
4f30: 69 2b 2b 29 7b 0a 20 20 20 20 20 20 50 67 48 64  i++){.      PgHd
4f40: 72 31 20 2a 70 50 61 67 65 3b 0a 20 20 20 20 20  r1 *pPage;.     
4f50: 20 50 67 48 64 72 31 20 2a 70 4e 65 78 74 20 3d   PgHdr1 *pNext =
4f60: 20 70 2d 3e 61 70 48 61 73 68 5b 69 5d 3b 0a 20   p->apHash[i];. 
4f70: 20 20 20 20 20 77 68 69 6c 65 28 20 28 70 50 61       while( (pPa
4f80: 67 65 20 3d 20 70 4e 65 78 74 29 21 3d 30 20 29  ge = pNext)!=0 )
4f90: 7b 0a 20 20 20 20 20 20 20 20 75 6e 73 69 67 6e  {.        unsign
4fa0: 65 64 20 69 6e 74 20 68 20 3d 20 70 50 61 67 65  ed int h = pPage
4fb0: 2d 3e 69 4b 65 79 20 25 20 6e 4e 65 77 3b 0a 20  ->iKey % nNew;. 
4fc0: 20 20 20 20 20 20 20 70 4e 65 78 74 20 3d 20 70         pNext = p
4fd0: 50 61 67 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20  Page->pNext;.   
4fe0: 20 20 20 20 20 70 50 61 67 65 2d 3e 70 4e 65 78       pPage->pNex
4ff0: 74 20 3d 20 61 70 4e 65 77 5b 68 5d 3b 0a 20 20  t = apNew[h];.  
5000: 20 20 20 20 20 20 61 70 4e 65 77 5b 68 5d 20 3d        apNew[h] =
5010: 20 70 50 61 67 65 3b 0a 20 20 20 20 20 20 7d 0a   pPage;.      }.
5020: 20 20 20 20 7d 0a 20 20 20 20 73 71 6c 69 74 65      }.    sqlite
5030: 33 5f 66 72 65 65 28 70 2d 3e 61 70 48 61 73 68  3_free(p->apHash
5040: 29 3b 0a 20 20 20 20 70 2d 3e 61 70 48 61 73 68  );.    p->apHash
5050: 20 3d 20 61 70 4e 65 77 3b 0a 20 20 20 20 70 2d   = apNew;.    p-
5060: 3e 6e 48 61 73 68 20 3d 20 6e 4e 65 77 3b 0a 20  >nHash = nNew;. 
5070: 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73   }.}../*.** This
5080: 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 75 73 65   function is use
5090: 64 20 69 6e 74 65 72 6e 61 6c 6c 79 20 74 6f 20  d internally to 
50a0: 72 65 6d 6f 76 65 20 74 68 65 20 70 61 67 65 20  remove the page 
50b0: 70 50 61 67 65 20 66 72 6f 6d 20 74 68 65 20 0a  pPage from the .
50c0: 2a 2a 20 50 47 72 6f 75 70 20 4c 52 55 20 6c 69  ** PGroup LRU li
50d0: 73 74 2c 20 69 66 20 69 73 20 70 61 72 74 20 6f  st, if is part o
50e0: 66 20 69 74 2e 20 49 66 20 70 50 61 67 65 20 69  f it. If pPage i
50f0: 73 20 6e 6f 74 20 70 61 72 74 20 6f 66 20 74 68  s not part of th
5100: 65 20 50 47 72 6f 75 70 0a 2a 2a 20 4c 52 55 20  e PGroup.** LRU 
5110: 6c 69 73 74 2c 20 74 68 65 6e 20 74 68 69 73 20  list, then this 
5120: 66 75 6e 63 74 69 6f 6e 20 69 73 20 61 20 6e 6f  function is a no
5130: 2d 6f 70 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 50  -op..**.** The P
5140: 47 72 6f 75 70 20 6d 75 74 65 78 20 6d 75 73 74  Group mutex must
5150: 20 62 65 20 68 65 6c 64 20 77 68 65 6e 20 74 68   be held when th
5160: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63  is function is c
5170: 61 6c 6c 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63  alled..*/.static
5180: 20 50 67 48 64 72 31 20 2a 70 63 61 63 68 65 31   PgHdr1 *pcache1
5190: 50 69 6e 50 61 67 65 28 50 67 48 64 72 31 20 2a  PinPage(PgHdr1 *
51a0: 70 50 61 67 65 29 7b 0a 20 20 61 73 73 65 72 74  pPage){.  assert
51b0: 28 20 70 50 61 67 65 21 3d 30 20 29 3b 0a 20 20  ( pPage!=0 );.  
51c0: 61 73 73 65 72 74 28 20 50 41 47 45 5f 49 53 5f  assert( PAGE_IS_
51d0: 55 4e 50 49 4e 4e 45 44 28 70 50 61 67 65 29 20  UNPINNED(pPage) 
51e0: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 50 61  );.  assert( pPa
51f0: 67 65 2d 3e 70 4c 72 75 4e 65 78 74 20 29 3b 0a  ge->pLruNext );.
5200: 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65 2d    assert( pPage-
5210: 3e 70 4c 72 75 50 72 65 76 20 29 3b 0a 20 20 61  >pLruPrev );.  a
5220: 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d  ssert( sqlite3_m
5230: 75 74 65 78 5f 68 65 6c 64 28 70 50 61 67 65 2d  utex_held(pPage-
5240: 3e 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 2d  >pCache->pGroup-
5250: 3e 6d 75 74 65 78 29 20 29 3b 0a 20 20 70 50 61  >mutex) );.  pPa
5260: 67 65 2d 3e 70 4c 72 75 50 72 65 76 2d 3e 70 4c  ge->pLruPrev->pL
5270: 72 75 4e 65 78 74 20 3d 20 70 50 61 67 65 2d 3e  ruNext = pPage->
5280: 70 4c 72 75 4e 65 78 74 3b 0a 20 20 70 50 61 67  pLruNext;.  pPag
5290: 65 2d 3e 70 4c 72 75 4e 65 78 74 2d 3e 70 4c 72  e->pLruNext->pLr
52a0: 75 50 72 65 76 20 3d 20 70 50 61 67 65 2d 3e 70  uPrev = pPage->p
52b0: 4c 72 75 50 72 65 76 3b 0a 20 20 70 50 61 67 65  LruPrev;.  pPage
52c0: 2d 3e 70 4c 72 75 4e 65 78 74 20 3d 20 30 3b 0a  ->pLruNext = 0;.
52d0: 20 20 70 50 61 67 65 2d 3e 70 4c 72 75 50 72 65    pPage->pLruPre
52e0: 76 20 3d 20 30 3b 0a 20 20 61 73 73 65 72 74 28  v = 0;.  assert(
52f0: 20 70 50 61 67 65 2d 3e 69 73 41 6e 63 68 6f 72   pPage->isAnchor
5300: 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28  ==0 );.  assert(
5310: 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65 2d 3e   pPage->pCache->
5320: 70 47 72 6f 75 70 2d 3e 6c 72 75 2e 69 73 41 6e  pGroup->lru.isAn
5330: 63 68 6f 72 3d 3d 31 20 29 3b 0a 20 20 70 50 61  chor==1 );.  pPa
5340: 67 65 2d 3e 70 43 61 63 68 65 2d 3e 6e 52 65 63  ge->pCache->nRec
5350: 79 63 6c 61 62 6c 65 2d 2d 3b 0a 20 20 72 65 74  yclable--;.  ret
5360: 75 72 6e 20 70 50 61 67 65 3b 0a 7d 0a 0a 0a 2f  urn pPage;.}.../
5370: 2a 0a 2a 2a 20 52 65 6d 6f 76 65 20 74 68 65 20  *.** Remove the 
5380: 70 61 67 65 20 73 75 70 70 6c 69 65 64 20 61 73  page supplied as
5390: 20 61 6e 20 61 72 67 75 6d 65 6e 74 20 66 72 6f   an argument fro
53a0: 6d 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65  m the hash table
53b0: 20 0a 2a 2a 20 28 50 43 61 63 68 65 31 2e 61 70   .** (PCache1.ap
53c0: 48 61 73 68 20 73 74 72 75 63 74 75 72 65 29 20  Hash structure) 
53d0: 74 68 61 74 20 69 74 20 69 73 20 63 75 72 72 65  that it is curre
53e0: 6e 74 6c 79 20 73 74 6f 72 65 64 20 69 6e 2e 0a  ntly stored in..
53f0: 2a 2a 20 41 6c 73 6f 20 66 72 65 65 20 74 68 65  ** Also free the
5400: 20 70 61 67 65 20 69 66 20 66 72 65 65 50 61 67   page if freePag
5410: 65 20 69 73 20 74 72 75 65 2e 0a 2a 2a 0a 2a 2a  e is true..**.**
5420: 20 54 68 65 20 50 47 72 6f 75 70 20 6d 75 74 65   The PGroup mute
5430: 78 20 6d 75 73 74 20 62 65 20 68 65 6c 64 20 77  x must be held w
5440: 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f  hen this functio
5450: 6e 20 69 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f 0a  n is called..*/.
5460: 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63  static void pcac
5470: 68 65 31 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73  he1RemoveFromHas
5480: 68 28 50 67 48 64 72 31 20 2a 70 50 61 67 65 2c  h(PgHdr1 *pPage,
5490: 20 69 6e 74 20 66 72 65 65 46 6c 61 67 29 7b 0a   int freeFlag){.
54a0: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68    unsigned int h
54b0: 3b 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43 61  ;.  PCache1 *pCa
54c0: 63 68 65 20 3d 20 70 50 61 67 65 2d 3e 70 43 61  che = pPage->pCa
54d0: 63 68 65 3b 0a 20 20 50 67 48 64 72 31 20 2a 2a  che;.  PgHdr1 **
54e0: 70 70 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 73  pp;..  assert( s
54f0: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c  qlite3_mutex_hel
5500: 64 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70  d(pCache->pGroup
5510: 2d 3e 6d 75 74 65 78 29 20 29 3b 0a 20 20 68 20  ->mutex) );.  h 
5520: 3d 20 70 50 61 67 65 2d 3e 69 4b 65 79 20 25 20  = pPage->iKey % 
5530: 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20  pCache->nHash;. 
5540: 20 66 6f 72 28 70 70 3d 26 70 43 61 63 68 65 2d   for(pp=&pCache-
5550: 3e 61 70 48 61 73 68 5b 68 5d 3b 20 28 2a 70 70  >apHash[h]; (*pp
5560: 29 21 3d 70 50 61 67 65 3b 20 70 70 3d 26 28 2a  )!=pPage; pp=&(*
5570: 70 70 29 2d 3e 70 4e 65 78 74 29 3b 0a 20 20 2a  pp)->pNext);.  *
5580: 70 70 20 3d 20 28 2a 70 70 29 2d 3e 70 4e 65 78  pp = (*pp)->pNex
5590: 74 3b 0a 0a 20 20 70 43 61 63 68 65 2d 3e 6e 50  t;..  pCache->nP
55a0: 61 67 65 2d 2d 3b 0a 20 20 69 66 28 20 66 72 65  age--;.  if( fre
55b0: 65 46 6c 61 67 20 29 20 70 63 61 63 68 65 31 46  eFlag ) pcache1F
55c0: 72 65 65 50 61 67 65 28 70 50 61 67 65 29 3b 0a  reePage(pPage);.
55d0: 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 74 68 65 72  }../*.** If ther
55e0: 65 20 61 72 65 20 63 75 72 72 65 6e 74 6c 79 20  e are currently 
55f0: 6d 6f 72 65 20 74 68 61 6e 20 6e 4d 61 78 50 61  more than nMaxPa
5600: 67 65 20 70 61 67 65 73 20 61 6c 6c 6f 63 61 74  ge pages allocat
5610: 65 64 2c 20 74 72 79 0a 2a 2a 20 74 6f 20 72 65  ed, try.** to re
5620: 63 79 63 6c 65 20 70 61 67 65 73 20 74 6f 20 72  cycle pages to r
5630: 65 64 75 63 65 20 74 68 65 20 6e 75 6d 62 65 72  educe the number
5640: 20 61 6c 6c 6f 63 61 74 65 64 20 74 6f 20 6e 4d   allocated to nM
5650: 61 78 50 61 67 65 2e 0a 2a 2f 0a 73 74 61 74 69  axPage..*/.stati
5660: 63 20 76 6f 69 64 20 70 63 61 63 68 65 31 45 6e  c void pcache1En
5670: 66 6f 72 63 65 4d 61 78 50 61 67 65 28 50 43 61  forceMaxPage(PCa
5680: 63 68 65 31 20 2a 70 43 61 63 68 65 29 7b 0a 20  che1 *pCache){. 
5690: 20 50 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 20   PGroup *pGroup 
56a0: 3d 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70  = pCache->pGroup
56b0: 3b 0a 20 20 50 67 48 64 72 31 20 2a 70 3b 0a 20  ;.  PgHdr1 *p;. 
56c0: 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33   assert( sqlite3
56d0: 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 47 72 6f  _mutex_held(pGro
56e0: 75 70 2d 3e 6d 75 74 65 78 29 20 29 3b 0a 20 20  up->mutex) );.  
56f0: 77 68 69 6c 65 28 20 70 47 72 6f 75 70 2d 3e 6e  while( pGroup->n
5700: 50 75 72 67 65 61 62 6c 65 3e 70 47 72 6f 75 70  Purgeable>pGroup
5710: 2d 3e 6e 4d 61 78 50 61 67 65 0a 20 20 20 20 20  ->nMaxPage.     
5720: 20 26 26 20 28 70 3d 70 47 72 6f 75 70 2d 3e 6c   && (p=pGroup->l
5730: 72 75 2e 70 4c 72 75 50 72 65 76 29 2d 3e 69 73  ru.pLruPrev)->is
5740: 41 6e 63 68 6f 72 3d 3d 30 0a 20 20 29 7b 0a 20  Anchor==0.  ){. 
5750: 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e 70 43     assert( p->pC
5760: 61 63 68 65 2d 3e 70 47 72 6f 75 70 3d 3d 70 47  ache->pGroup==pG
5770: 72 6f 75 70 20 29 3b 0a 20 20 20 20 61 73 73 65  roup );.    asse
5780: 72 74 28 20 50 41 47 45 5f 49 53 5f 55 4e 50 49  rt( PAGE_IS_UNPI
5790: 4e 4e 45 44 28 70 29 20 29 3b 0a 20 20 20 20 70  NNED(p) );.    p
57a0: 63 61 63 68 65 31 50 69 6e 50 61 67 65 28 70 29  cache1PinPage(p)
57b0: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 52 65 6d  ;.    pcache1Rem
57c0: 6f 76 65 46 72 6f 6d 48 61 73 68 28 70 2c 20 31  oveFromHash(p, 1
57d0: 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 43 61  );.  }.  if( pCa
57e0: 63 68 65 2d 3e 6e 50 61 67 65 3d 3d 30 20 26 26  che->nPage==0 &&
57f0: 20 70 43 61 63 68 65 2d 3e 70 42 75 6c 6b 20 29   pCache->pBulk )
5800: 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72  {.    sqlite3_fr
5810: 65 65 28 70 43 61 63 68 65 2d 3e 70 42 75 6c 6b  ee(pCache->pBulk
5820: 29 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 70  );.    pCache->p
5830: 42 75 6c 6b 20 3d 20 70 43 61 63 68 65 2d 3e 70  Bulk = pCache->p
5840: 46 72 65 65 20 3d 20 30 3b 0a 20 20 7d 0a 7d 0a  Free = 0;.  }.}.
5850: 0a 2f 2a 0a 2a 2a 20 44 69 73 63 61 72 64 20 61  ./*.** Discard a
5860: 6c 6c 20 70 61 67 65 73 20 66 72 6f 6d 20 63 61  ll pages from ca
5870: 63 68 65 20 70 43 61 63 68 65 20 77 69 74 68 20  che pCache with 
5880: 61 20 70 61 67 65 20 6e 75 6d 62 65 72 20 28 6b  a page number (k
5890: 65 79 20 76 61 6c 75 65 29 20 0a 2a 2a 20 67 72  ey value) .** gr
58a0: 65 61 74 65 72 20 74 68 61 6e 20 6f 72 20 65 71  eater than or eq
58b0: 75 61 6c 20 74 6f 20 69 4c 69 6d 69 74 2e 20 41  ual to iLimit. A
58c0: 6e 79 20 70 69 6e 6e 65 64 20 70 61 67 65 73 20  ny pinned pages 
58d0: 74 68 61 74 20 6d 65 65 74 20 74 68 69 73 20 0a  that meet this .
58e0: 2a 2a 20 63 72 69 74 65 72 69 61 20 61 72 65 20  ** criteria are 
58f0: 75 6e 70 69 6e 6e 65 64 20 62 65 66 6f 72 65 20  unpinned before 
5900: 74 68 65 79 20 61 72 65 20 64 69 73 63 61 72 64  they are discard
5910: 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 50 43  ed..**.** The PC
5920: 61 63 68 65 20 6d 75 74 65 78 20 6d 75 73 74 20  ache mutex must 
5930: 62 65 20 68 65 6c 64 20 77 68 65 6e 20 74 68 69  be held when thi
5940: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61  s function is ca
5950: 6c 6c 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  lled..*/.static 
5960: 76 6f 69 64 20 70 63 61 63 68 65 31 54 72 75 6e  void pcache1Trun
5970: 63 61 74 65 55 6e 73 61 66 65 28 0a 20 20 50 43  cateUnsafe(.  PC
5980: 61 63 68 65 31 20 2a 70 43 61 63 68 65 2c 20 20  ache1 *pCache,  
5990: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68             /* Th
59a0: 65 20 63 61 63 68 65 20 74 6f 20 74 72 75 6e 63  e cache to trunc
59b0: 61 74 65 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65  ate */.  unsigne
59c0: 64 20 69 6e 74 20 69 4c 69 6d 69 74 20 20 20 20  d int iLimit    
59d0: 20 20 20 20 20 20 2f 2a 20 44 72 6f 70 20 70 61        /* Drop pa
59e0: 67 65 73 20 77 69 74 68 20 74 68 69 73 20 70 67  ges with this pg
59f0: 6e 6f 20 6f 72 20 6c 61 72 67 65 72 20 2a 2f 0a  no or larger */.
5a00: 29 7b 0a 20 20 54 45 53 54 4f 4e 4c 59 28 20 69  ){.  TESTONLY( i
5a10: 6e 74 20 6e 50 61 67 65 20 3d 20 30 3b 20 29 20  nt nPage = 0; ) 
5a20: 20 2f 2a 20 54 6f 20 61 73 73 65 72 74 20 70 43   /* To assert pC
5a30: 61 63 68 65 2d 3e 6e 50 61 67 65 20 69 73 20 63  ache->nPage is c
5a40: 6f 72 72 65 63 74 20 2a 2f 0a 20 20 75 6e 73 69  orrect */.  unsi
5a50: 67 6e 65 64 20 69 6e 74 20 68 2c 20 69 53 74 6f  gned int h, iSto
5a60: 70 3b 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c  p;.  assert( sql
5a70: 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28  ite3_mutex_held(
5a80: 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 2d 3e  pCache->pGroup->
5a90: 6d 75 74 65 78 29 20 29 3b 0a 20 20 61 73 73 65  mutex) );.  asse
5aa0: 72 74 28 20 70 43 61 63 68 65 2d 3e 69 4d 61 78  rt( pCache->iMax
5ab0: 4b 65 79 20 3e 3d 20 69 4c 69 6d 69 74 20 29 3b  Key >= iLimit );
5ac0: 0a 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68  .  assert( pCach
5ad0: 65 2d 3e 6e 48 61 73 68 20 3e 20 30 20 29 3b 0a  e->nHash > 0 );.
5ae0: 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 69 4d    if( pCache->iM
5af0: 61 78 4b 65 79 20 2d 20 69 4c 69 6d 69 74 20 3c  axKey - iLimit <
5b00: 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 20 29   pCache->nHash )
5b10: 7b 0a 20 20 20 20 2f 2a 20 49 66 20 77 65 20 61  {.    /* If we a
5b20: 72 65 20 6a 75 73 74 20 73 68 61 76 69 6e 67 20  re just shaving 
5b30: 74 68 65 20 6c 61 73 74 20 66 65 77 20 70 61 67  the last few pag
5b40: 65 73 20 6f 66 66 20 74 68 65 20 65 6e 64 20 6f  es off the end o
5b50: 66 20 74 68 65 0a 20 20 20 20 2a 2a 20 63 61 63  f the.    ** cac
5b60: 68 65 2c 20 74 68 65 6e 20 74 68 65 72 65 20 69  he, then there i
5b70: 73 20 6e 6f 20 70 6f 69 6e 74 20 69 6e 20 73 63  s no point in sc
5b80: 61 6e 6e 69 6e 67 20 74 68 65 20 65 6e 74 69 72  anning the entir
5b90: 65 20 68 61 73 68 20 74 61 62 6c 65 2e 0a 20 20  e hash table..  
5ba0: 20 20 2a 2a 20 4f 6e 6c 79 20 73 63 61 6e 20 74    ** Only scan t
5bb0: 68 6f 73 65 20 68 61 73 68 20 73 6c 6f 74 73 20  hose hash slots 
5bc0: 74 68 61 74 20 6d 69 67 68 74 20 63 6f 6e 74 61  that might conta
5bd0: 69 6e 20 70 61 67 65 73 20 74 68 61 74 20 6e 65  in pages that ne
5be0: 65 64 20 74 6f 0a 20 20 20 20 2a 2a 20 62 65 20  ed to.    ** be 
5bf0: 72 65 6d 6f 76 65 64 2e 20 2a 2f 0a 20 20 20 20  removed. */.    
5c00: 68 20 3d 20 69 4c 69 6d 69 74 20 25 20 70 43 61  h = iLimit % pCa
5c10: 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 20 20  che->nHash;.    
5c20: 69 53 74 6f 70 20 3d 20 70 43 61 63 68 65 2d 3e  iStop = pCache->
5c30: 69 4d 61 78 4b 65 79 20 25 20 70 43 61 63 68 65  iMaxKey % pCache
5c40: 2d 3e 6e 48 61 73 68 3b 0a 20 20 20 20 54 45 53  ->nHash;.    TES
5c50: 54 4f 4e 4c 59 28 20 6e 50 61 67 65 20 3d 20 2d  TONLY( nPage = -
5c60: 31 30 3b 20 29 20 20 2f 2a 20 44 69 73 61 62 6c  10; )  /* Disabl
5c70: 65 20 74 68 65 20 70 43 61 63 68 65 2d 3e 6e 50  e the pCache->nP
5c80: 61 67 65 20 76 61 6c 69 64 69 74 79 20 63 68 65  age validity che
5c90: 63 6b 20 2a 2f 0a 20 20 7d 65 6c 73 65 7b 0a 20  ck */.  }else{. 
5ca0: 20 20 20 2f 2a 20 54 68 69 73 20 69 73 20 74 68     /* This is th
5cb0: 65 20 67 65 6e 65 72 61 6c 20 63 61 73 65 20 77  e general case w
5cc0: 68 65 72 65 20 6d 61 6e 79 20 70 61 67 65 73 20  here many pages 
5cd0: 61 72 65 20 62 65 69 6e 67 20 72 65 6d 6f 76 65  are being remove
5ce0: 64 2e 0a 20 20 20 20 2a 2a 20 49 74 20 69 73 20  d..    ** It is 
5cf0: 6e 65 63 65 73 73 61 72 79 20 74 6f 20 73 63 61  necessary to sca
5d00: 6e 20 74 68 65 20 65 6e 74 69 72 65 20 68 61 73  n the entire has
5d10: 68 20 74 61 62 6c 65 20 2a 2f 0a 20 20 20 20 68  h table */.    h
5d20: 20 3d 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68   = pCache->nHash
5d30: 2f 32 3b 0a 20 20 20 20 69 53 74 6f 70 20 3d 20  /2;.    iStop = 
5d40: 68 20 2d 20 31 3b 0a 20 20 7d 0a 20 20 66 6f 72  h - 1;.  }.  for
5d50: 28 3b 3b 29 7b 0a 20 20 20 20 50 67 48 64 72 31  (;;){.    PgHdr1
5d60: 20 2a 2a 70 70 3b 0a 20 20 20 20 50 67 48 64 72   **pp;.    PgHdr
5d70: 31 20 2a 70 50 61 67 65 3b 0a 20 20 20 20 61 73  1 *pPage;.    as
5d80: 73 65 72 74 28 20 68 3c 70 43 61 63 68 65 2d 3e  sert( h<pCache->
5d90: 6e 48 61 73 68 20 29 3b 0a 20 20 20 20 70 70 20  nHash );.    pp 
5da0: 3d 20 26 70 43 61 63 68 65 2d 3e 61 70 48 61 73  = &pCache->apHas
5db0: 68 5b 68 5d 3b 20 0a 20 20 20 20 77 68 69 6c 65  h[h]; .    while
5dc0: 28 20 28 70 50 61 67 65 20 3d 20 2a 70 70 29 21  ( (pPage = *pp)!
5dd0: 3d 30 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20  =0 ){.      if( 
5de0: 70 50 61 67 65 2d 3e 69 4b 65 79 3e 3d 69 4c 69  pPage->iKey>=iLi
5df0: 6d 69 74 20 29 7b 0a 20 20 20 20 20 20 20 20 70  mit ){.        p
5e00: 43 61 63 68 65 2d 3e 6e 50 61 67 65 2d 2d 3b 0a  Cache->nPage--;.
5e10: 20 20 20 20 20 20 20 20 2a 70 70 20 3d 20 70 50          *pp = pP
5e20: 61 67 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20  age->pNext;.    
5e30: 20 20 20 20 69 66 28 20 50 41 47 45 5f 49 53 5f      if( PAGE_IS_
5e40: 55 4e 50 49 4e 4e 45 44 28 70 50 61 67 65 29 20  UNPINNED(pPage) 
5e50: 29 20 70 63 61 63 68 65 31 50 69 6e 50 61 67 65  ) pcache1PinPage
5e60: 28 70 50 61 67 65 29 3b 0a 20 20 20 20 20 20 20  (pPage);.       
5e70: 20 70 63 61 63 68 65 31 46 72 65 65 50 61 67 65   pcache1FreePage
5e80: 28 70 50 61 67 65 29 3b 0a 20 20 20 20 20 20 7d  (pPage);.      }
5e90: 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 70 70  else{.        pp
5ea0: 20 3d 20 26 70 50 61 67 65 2d 3e 70 4e 65 78 74   = &pPage->pNext
5eb0: 3b 0a 20 20 20 20 20 20 20 20 54 45 53 54 4f 4e  ;.        TESTON
5ec0: 4c 59 28 20 69 66 28 20 6e 50 61 67 65 3e 3d 30  LY( if( nPage>=0
5ed0: 20 29 20 6e 50 61 67 65 2b 2b 3b 20 29 0a 20 20   ) nPage++; ).  
5ee0: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20      }.    }.    
5ef0: 69 66 28 20 68 3d 3d 69 53 74 6f 70 20 29 20 62  if( h==iStop ) b
5f00: 72 65 61 6b 3b 0a 20 20 20 20 68 20 3d 20 28 68  reak;.    h = (h
5f10: 2b 31 29 20 25 20 70 43 61 63 68 65 2d 3e 6e 48  +1) % pCache->nH
5f20: 61 73 68 3b 0a 20 20 7d 0a 20 20 61 73 73 65 72  ash;.  }.  asser
5f30: 74 28 20 6e 50 61 67 65 3c 30 20 7c 7c 20 70 43  t( nPage<0 || pC
5f40: 61 63 68 65 2d 3e 6e 50 61 67 65 3d 3d 28 75 6e  ache->nPage==(un
5f50: 73 69 67 6e 65 64 29 6e 50 61 67 65 20 29 3b 0a  signed)nPage );.
5f60: 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  }../************
5f70: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5f80: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5f90: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5fa0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5fb0: 2a 2a 2f 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 20 73 71  **/./******** sq
5fc0: 6c 69 74 65 33 5f 70 63 61 63 68 65 20 4d 65 74  lite3_pcache Met
5fd0: 68 6f 64 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  hods ***********
5fe0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5ff0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
6000: 2a 2a 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c  ***/../*.** Impl
6010: 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68  ementation of th
6020: 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  e sqlite3_pcache
6030: 2e 78 49 6e 69 74 20 6d 65 74 68 6f 64 2e 0a 2a  .xInit method..*
6040: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 70 63 61  /.static int pca
6050: 63 68 65 31 49 6e 69 74 28 76 6f 69 64 20 2a 4e  che1Init(void *N
6060: 6f 74 55 73 65 64 29 7b 0a 20 20 55 4e 55 53 45  otUsed){.  UNUSE
6070: 44 5f 50 41 52 41 4d 45 54 45 52 28 4e 6f 74 55  D_PARAMETER(NotU
6080: 73 65 64 29 3b 0a 20 20 61 73 73 65 72 74 28 20  sed);.  assert( 
6090: 70 63 61 63 68 65 31 2e 69 73 49 6e 69 74 3d 3d  pcache1.isInit==
60a0: 30 20 29 3b 0a 20 20 6d 65 6d 73 65 74 28 26 70  0 );.  memset(&p
60b0: 63 61 63 68 65 31 2c 20 30 2c 20 73 69 7a 65 6f  cache1, 0, sizeo
60c0: 66 28 70 63 61 63 68 65 31 29 29 3b 0a 0a 0a 20  f(pcache1));... 
60d0: 20 2f 2a 0a 20 20 2a 2a 20 54 68 65 20 70 63 61   /*.  ** The pca
60e0: 63 68 65 31 2e 73 65 70 61 72 61 74 65 43 61 63  che1.separateCac
60f0: 68 65 20 76 61 72 69 61 62 6c 65 20 69 73 20 74  he variable is t
6100: 72 75 65 20 69 66 20 65 61 63 68 20 50 43 61 63  rue if each PCac
6110: 68 65 20 68 61 73 20 69 74 73 20 6f 77 6e 0a 20  he has its own. 
6120: 20 2a 2a 20 70 72 69 76 61 74 65 20 50 47 72 6f   ** private PGro
6130: 75 70 20 28 6d 6f 64 65 2d 31 29 2e 20 20 70 63  up (mode-1).  pc
6140: 61 63 68 65 31 2e 73 65 70 61 72 61 74 65 43 61  ache1.separateCa
6150: 63 68 65 20 69 73 20 66 61 6c 73 65 20 69 66 20  che is false if 
6160: 74 68 65 20 73 69 6e 67 6c 65 0a 20 20 2a 2a 20  the single.  ** 
6170: 50 47 72 6f 75 70 20 69 6e 20 70 63 61 63 68 65  PGroup in pcache
6180: 31 2e 67 72 70 20 69 73 20 75 73 65 64 20 66 6f  1.grp is used fo
6190: 72 20 61 6c 6c 20 70 61 67 65 20 63 61 63 68 65  r all page cache
61a0: 73 20 28 6d 6f 64 65 2d 32 29 2e 0a 20 20 2a 2a  s (mode-2)..  **
61b0: 0a 20 20 2a 2a 20 20 20 2a 20 20 41 6c 77 61 79  .  **   *  Alway
61c0: 73 20 75 73 65 20 61 20 75 6e 69 66 69 65 64 20  s use a unified 
61d0: 63 61 63 68 65 20 28 6d 6f 64 65 2d 32 29 20 69  cache (mode-2) i
61e0: 66 20 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f  f ENABLE_MEMORY_
61f0: 4d 41 4e 41 47 45 4d 45 4e 54 0a 20 20 2a 2a 0a  MANAGEMENT.  **.
6200: 20 20 2a 2a 20 20 20 2a 20 20 55 73 65 20 61 20    **   *  Use a 
6210: 75 6e 69 66 69 65 64 20 63 61 63 68 65 20 69 6e  unified cache in
6220: 20 73 69 6e 67 6c 65 2d 74 68 72 65 61 64 65 64   single-threaded
6230: 20 61 70 70 6c 69 63 61 74 69 6f 6e 73 20 74 68   applications th
6240: 61 74 20 68 61 76 65 0a 20 20 2a 2a 20 20 20 20  at have.  **    
6250: 20 20 63 6f 6e 66 69 67 75 72 65 64 20 61 20 73    configured a s
6260: 74 61 72 74 2d 74 69 6d 65 20 62 75 66 66 65 72  tart-time buffer
6270: 20 66 6f 72 20 75 73 65 20 61 73 20 70 61 67 65   for use as page
6280: 2d 63 61 63 68 65 20 6d 65 6d 6f 72 79 20 75 73  -cache memory us
6290: 69 6e 67 0a 20 20 2a 2a 20 20 20 20 20 20 73 71  ing.  **      sq
62a0: 6c 69 74 65 33 5f 63 6f 6e 66 69 67 28 53 51 4c  lite3_config(SQL
62b0: 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43  ITE_CONFIG_PAGEC
62c0: 41 43 48 45 2c 20 70 42 75 66 2c 20 73 7a 2c 20  ACHE, pBuf, sz, 
62d0: 4e 29 20 77 69 74 68 20 6e 6f 6e 2d 4e 55 4c 4c  N) with non-NULL
62e0: 20 0a 20 20 2a 2a 20 20 20 20 20 20 70 42 75 66   .  **      pBuf
62f0: 20 61 72 67 75 6d 65 6e 74 2e 0a 20 20 2a 2a 0a   argument..  **.
6300: 20 20 2a 2a 20 20 20 2a 20 20 4f 74 68 65 72 77    **   *  Otherw
6310: 69 73 65 20 75 73 65 20 73 65 70 61 72 61 74 65  ise use separate
6320: 20 63 61 63 68 65 73 20 28 6d 6f 64 65 2d 31 29   caches (mode-1)
6330: 0a 20 20 2a 2f 0a 23 69 66 20 64 65 66 69 6e 65  .  */.#if define
6340: 64 28 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f  d(SQLITE_ENABLE_
6350: 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e  MEMORY_MANAGEMEN
6360: 54 29 0a 20 20 70 63 61 63 68 65 31 2e 73 65 70  T).  pcache1.sep
6370: 61 72 61 74 65 43 61 63 68 65 20 3d 20 30 3b 0a  arateCache = 0;.
6380: 23 65 6c 69 66 20 53 51 4c 49 54 45 5f 54 48 52  #elif SQLITE_THR
6390: 45 41 44 53 41 46 45 0a 20 20 70 63 61 63 68 65  EADSAFE.  pcache
63a0: 31 2e 73 65 70 61 72 61 74 65 43 61 63 68 65 20  1.separateCache 
63b0: 3d 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43  = sqlite3GlobalC
63c0: 6f 6e 66 69 67 2e 70 50 61 67 65 3d 3d 30 0a 20  onfig.pPage==0. 
63d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
63e0: 20 20 20 20 20 20 20 20 20 7c 7c 20 73 71 6c 69           || sqli
63f0: 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e  te3GlobalConfig.
6400: 62 43 6f 72 65 4d 75 74 65 78 3e 30 3b 0a 23 65  bCoreMutex>0;.#e
6410: 6c 73 65 0a 20 20 70 63 61 63 68 65 31 2e 73 65  lse.  pcache1.se
6420: 70 61 72 61 74 65 43 61 63 68 65 20 3d 20 73 71  parateCache = sq
6430: 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69  lite3GlobalConfi
6440: 67 2e 70 50 61 67 65 3d 3d 30 3b 0a 23 65 6e 64  g.pPage==0;.#end
6450: 69 66 0a 0a 23 69 66 20 53 51 4c 49 54 45 5f 54  if..#if SQLITE_T
6460: 48 52 45 41 44 53 41 46 45 0a 20 20 69 66 28 20  HREADSAFE.  if( 
6470: 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e  sqlite3GlobalCon
6480: 66 69 67 2e 62 43 6f 72 65 4d 75 74 65 78 20 29  fig.bCoreMutex )
6490: 7b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 67 72  {.    pcache1.gr
64a0: 70 2e 6d 75 74 65 78 20 3d 20 73 71 6c 69 74 65  p.mutex = sqlite
64b0: 33 4d 75 74 65 78 41 6c 6c 6f 63 28 53 51 4c 49  3MutexAlloc(SQLI
64c0: 54 45 5f 4d 55 54 45 58 5f 53 54 41 54 49 43 5f  TE_MUTEX_STATIC_
64d0: 4c 52 55 29 3b 0a 20 20 20 20 70 63 61 63 68 65  LRU);.    pcache
64e0: 31 2e 6d 75 74 65 78 20 3d 20 73 71 6c 69 74 65  1.mutex = sqlite
64f0: 33 4d 75 74 65 78 41 6c 6c 6f 63 28 53 51 4c 49  3MutexAlloc(SQLI
6500: 54 45 5f 4d 55 54 45 58 5f 53 54 41 54 49 43 5f  TE_MUTEX_STATIC_
6510: 50 4d 45 4d 29 3b 0a 20 20 7d 0a 23 65 6e 64 69  PMEM);.  }.#endi
6520: 66 0a 20 20 69 66 28 20 70 63 61 63 68 65 31 2e  f.  if( pcache1.
6530: 73 65 70 61 72 61 74 65 43 61 63 68 65 0a 20 20  separateCache.  
6540: 20 26 26 20 73 71 6c 69 74 65 33 47 6c 6f 62 61   && sqlite3Globa
6550: 6c 43 6f 6e 66 69 67 2e 6e 50 61 67 65 21 3d 30  lConfig.nPage!=0
6560: 0a 20 20 20 26 26 20 73 71 6c 69 74 65 33 47 6c  .   && sqlite3Gl
6570: 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 50 61 67 65  obalConfig.pPage
6580: 3d 3d 30 0a 20 20 29 7b 0a 20 20 20 20 70 63 61  ==0.  ){.    pca
6590: 63 68 65 31 2e 6e 49 6e 69 74 50 61 67 65 20 3d  che1.nInitPage =
65a0: 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f   sqlite3GlobalCo
65b0: 6e 66 69 67 2e 6e 50 61 67 65 3b 0a 20 20 7d 65  nfig.nPage;.  }e
65c0: 6c 73 65 7b 0a 20 20 20 20 70 63 61 63 68 65 31  lse{.    pcache1
65d0: 2e 6e 49 6e 69 74 50 61 67 65 20 3d 20 30 3b 0a  .nInitPage = 0;.
65e0: 20 20 7d 0a 20 20 70 63 61 63 68 65 31 2e 67 72    }.  pcache1.gr
65f0: 70 2e 6d 78 50 69 6e 6e 65 64 20 3d 20 31 30 3b  p.mxPinned = 10;
6600: 0a 20 20 70 63 61 63 68 65 31 2e 69 73 49 6e 69  .  pcache1.isIni
6610: 74 20 3d 20 31 3b 0a 20 20 72 65 74 75 72 6e 20  t = 1;.  return 
6620: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a  SQLITE_OK;.}../*
6630: 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69  .** Implementati
6640: 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65  on of the sqlite
6650: 33 5f 70 63 61 63 68 65 2e 78 53 68 75 74 64 6f  3_pcache.xShutdo
6660: 77 6e 20 6d 65 74 68 6f 64 2e 0a 2a 2a 20 4e 6f  wn method..** No
6670: 74 65 20 74 68 61 74 20 74 68 65 20 73 74 61 74  te that the stat
6680: 69 63 20 6d 75 74 65 78 20 61 6c 6c 6f 63 61 74  ic mutex allocat
6690: 65 64 20 69 6e 20 78 49 6e 69 74 20 64 6f 65 73  ed in xInit does
66a0: 20 0a 2a 2a 20 6e 6f 74 20 6e 65 65 64 20 74 6f   .** not need to
66b0: 20 62 65 20 66 72 65 65 64 2e 0a 2a 2f 0a 73 74   be freed..*/.st
66c0: 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65  atic void pcache
66d0: 31 53 68 75 74 64 6f 77 6e 28 76 6f 69 64 20 2a  1Shutdown(void *
66e0: 4e 6f 74 55 73 65 64 29 7b 0a 20 20 55 4e 55 53  NotUsed){.  UNUS
66f0: 45 44 5f 50 41 52 41 4d 45 54 45 52 28 4e 6f 74  ED_PARAMETER(Not
6700: 55 73 65 64 29 3b 0a 20 20 61 73 73 65 72 74 28  Used);.  assert(
6710: 20 70 63 61 63 68 65 31 2e 69 73 49 6e 69 74 21   pcache1.isInit!
6720: 3d 30 20 29 3b 0a 20 20 6d 65 6d 73 65 74 28 26  =0 );.  memset(&
6730: 70 63 61 63 68 65 31 2c 20 30 2c 20 73 69 7a 65  pcache1, 0, size
6740: 6f 66 28 70 63 61 63 68 65 31 29 29 3b 0a 7d 0a  of(pcache1));.}.
6750: 0a 2f 2a 20 66 6f 72 77 61 72 64 20 64 65 63 6c  ./* forward decl
6760: 61 72 61 74 69 6f 6e 20 2a 2f 0a 73 74 61 74 69  aration */.stati
6770: 63 20 76 6f 69 64 20 70 63 61 63 68 65 31 44 65  c void pcache1De
6780: 73 74 72 6f 79 28 73 71 6c 69 74 65 33 5f 70 63  stroy(sqlite3_pc
6790: 61 63 68 65 20 2a 70 29 3b 0a 0a 2f 2a 0a 2a 2a  ache *p);../*.**
67a0: 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20   Implementation 
67b0: 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70  of the sqlite3_p
67c0: 63 61 63 68 65 2e 78 43 72 65 61 74 65 20 6d 65  cache.xCreate me
67d0: 74 68 6f 64 2e 0a 2a 2a 0a 2a 2a 20 41 6c 6c 6f  thod..**.** Allo
67e0: 63 61 74 65 20 61 20 6e 65 77 20 63 61 63 68 65  cate a new cache
67f0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 73 71 6c 69  ..*/.static sqli
6800: 74 65 33 5f 70 63 61 63 68 65 20 2a 70 63 61 63  te3_pcache *pcac
6810: 68 65 31 43 72 65 61 74 65 28 69 6e 74 20 73 7a  he1Create(int sz
6820: 50 61 67 65 2c 20 69 6e 74 20 73 7a 45 78 74 72  Page, int szExtr
6830: 61 2c 20 69 6e 74 20 62 50 75 72 67 65 61 62 6c  a, int bPurgeabl
6840: 65 29 7b 0a 20 20 50 43 61 63 68 65 31 20 2a 70  e){.  PCache1 *p
6850: 43 61 63 68 65 3b 20 20 20 20 20 20 2f 2a 20 54  Cache;      /* T
6860: 68 65 20 6e 65 77 6c 79 20 63 72 65 61 74 65 64  he newly created
6870: 20 70 61 67 65 20 63 61 63 68 65 20 2a 2f 0a 20   page cache */. 
6880: 20 50 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 3b   PGroup *pGroup;
6890: 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 67 72         /* The gr
68a0: 6f 75 70 20 74 68 65 20 6e 65 77 20 70 61 67 65  oup the new page
68b0: 20 63 61 63 68 65 20 77 69 6c 6c 20 62 65 6c 6f   cache will belo
68c0: 6e 67 20 74 6f 20 2a 2f 0a 20 20 69 6e 74 20 73  ng to */.  int s
68d0: 7a 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  z;              
68e0: 20 2f 2a 20 42 79 74 65 73 20 6f 66 20 6d 65 6d   /* Bytes of mem
68f0: 6f 72 79 20 72 65 71 75 69 72 65 64 20 74 6f 20  ory required to 
6900: 61 6c 6c 6f 63 61 74 65 20 74 68 65 20 6e 65 77  allocate the new
6910: 20 63 61 63 68 65 20 2a 2f 0a 0a 20 20 61 73 73   cache */..  ass
6920: 65 72 74 28 20 28 73 7a 50 61 67 65 20 26 20 28  ert( (szPage & (
6930: 73 7a 50 61 67 65 2d 31 29 29 3d 3d 30 20 26 26  szPage-1))==0 &&
6940: 20 73 7a 50 61 67 65 3e 3d 35 31 32 20 26 26 20   szPage>=512 && 
6950: 73 7a 50 61 67 65 3c 3d 36 35 35 33 36 20 29 3b  szPage<=65536 );
6960: 0a 20 20 61 73 73 65 72 74 28 20 73 7a 45 78 74  .  assert( szExt
6970: 72 61 20 3c 20 33 30 30 20 29 3b 0a 0a 20 20 73  ra < 300 );..  s
6980: 7a 20 3d 20 73 69 7a 65 6f 66 28 50 43 61 63 68  z = sizeof(PCach
6990: 65 31 29 20 2b 20 73 69 7a 65 6f 66 28 50 47 72  e1) + sizeof(PGr
69a0: 6f 75 70 29 2a 70 63 61 63 68 65 31 2e 73 65 70  oup)*pcache1.sep
69b0: 61 72 61 74 65 43 61 63 68 65 3b 0a 20 20 70 43  arateCache;.  pC
69c0: 61 63 68 65 20 3d 20 28 50 43 61 63 68 65 31 20  ache = (PCache1 
69d0: 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a  *)sqlite3MallocZ
69e0: 65 72 6f 28 73 7a 29 3b 0a 20 20 69 66 28 20 70  ero(sz);.  if( p
69f0: 43 61 63 68 65 20 29 7b 0a 20 20 20 20 69 66 28  Cache ){.    if(
6a00: 20 70 63 61 63 68 65 31 2e 73 65 70 61 72 61 74   pcache1.separat
6a10: 65 43 61 63 68 65 20 29 7b 0a 20 20 20 20 20 20  eCache ){.      
6a20: 70 47 72 6f 75 70 20 3d 20 28 50 47 72 6f 75 70  pGroup = (PGroup
6a30: 2a 29 26 70 43 61 63 68 65 5b 31 5d 3b 0a 20 20  *)&pCache[1];.  
6a40: 20 20 20 20 70 47 72 6f 75 70 2d 3e 6d 78 50 69      pGroup->mxPi
6a50: 6e 6e 65 64 20 3d 20 31 30 3b 0a 20 20 20 20 7d  nned = 10;.    }
6a60: 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 47 72 6f  else{.      pGro
6a70: 75 70 20 3d 20 26 70 63 61 63 68 65 31 2e 67 72  up = &pcache1.gr
6a80: 70 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28  p;.    }.    if(
6a90: 20 70 47 72 6f 75 70 2d 3e 6c 72 75 2e 69 73 41   pGroup->lru.isA
6aa0: 6e 63 68 6f 72 3d 3d 30 20 29 7b 0a 20 20 20 20  nchor==0 ){.    
6ab0: 20 20 70 47 72 6f 75 70 2d 3e 6c 72 75 2e 69 73    pGroup->lru.is
6ac0: 41 6e 63 68 6f 72 20 3d 20 31 3b 0a 20 20 20 20  Anchor = 1;.    
6ad0: 20 20 70 47 72 6f 75 70 2d 3e 6c 72 75 2e 70 4c    pGroup->lru.pL
6ae0: 72 75 50 72 65 76 20 3d 20 70 47 72 6f 75 70 2d  ruPrev = pGroup-
6af0: 3e 6c 72 75 2e 70 4c 72 75 4e 65 78 74 20 3d 20  >lru.pLruNext = 
6b00: 26 70 47 72 6f 75 70 2d 3e 6c 72 75 3b 0a 20 20  &pGroup->lru;.  
6b10: 20 20 7d 0a 20 20 20 20 70 43 61 63 68 65 2d 3e    }.    pCache->
6b20: 70 47 72 6f 75 70 20 3d 20 70 47 72 6f 75 70 3b  pGroup = pGroup;
6b30: 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 73 7a 50  .    pCache->szP
6b40: 61 67 65 20 3d 20 73 7a 50 61 67 65 3b 0a 20 20  age = szPage;.  
6b50: 20 20 70 43 61 63 68 65 2d 3e 73 7a 45 78 74 72    pCache->szExtr
6b60: 61 20 3d 20 73 7a 45 78 74 72 61 3b 0a 20 20 20  a = szExtra;.   
6b70: 20 70 43 61 63 68 65 2d 3e 73 7a 41 6c 6c 6f 63   pCache->szAlloc
6b80: 20 3d 20 73 7a 50 61 67 65 20 2b 20 73 7a 45 78   = szPage + szEx
6b90: 74 72 61 20 2b 20 52 4f 55 4e 44 38 28 73 69 7a  tra + ROUND8(siz
6ba0: 65 6f 66 28 50 67 48 64 72 31 29 29 3b 0a 20 20  eof(PgHdr1));.  
6bb0: 20 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65    pCache->bPurge
6bc0: 61 62 6c 65 20 3d 20 28 62 50 75 72 67 65 61 62  able = (bPurgeab
6bd0: 6c 65 20 3f 20 31 20 3a 20 30 29 3b 0a 20 20 20  le ? 1 : 0);.   
6be0: 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74   pcache1EnterMut
6bf0: 65 78 28 70 47 72 6f 75 70 29 3b 0a 20 20 20 20  ex(pGroup);.    
6c00: 70 63 61 63 68 65 31 52 65 73 69 7a 65 48 61 73  pcache1ResizeHas
6c10: 68 28 70 43 61 63 68 65 29 3b 0a 20 20 20 20 69  h(pCache);.    i
6c20: 66 28 20 62 50 75 72 67 65 61 62 6c 65 20 29 7b  f( bPurgeable ){
6c30: 0a 20 20 20 20 20 20 70 43 61 63 68 65 2d 3e 6e  .      pCache->n
6c40: 4d 69 6e 20 3d 20 31 30 3b 0a 20 20 20 20 20 20  Min = 10;.      
6c50: 70 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67 65  pGroup->nMinPage
6c60: 20 2b 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 69 6e   += pCache->nMin
6c70: 3b 0a 20 20 20 20 20 20 70 47 72 6f 75 70 2d 3e  ;.      pGroup->
6c80: 6d 78 50 69 6e 6e 65 64 20 3d 20 70 47 72 6f 75  mxPinned = pGrou
6c90: 70 2d 3e 6e 4d 61 78 50 61 67 65 20 2b 20 31 30  p->nMaxPage + 10
6ca0: 20 2d 20 70 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50   - pGroup->nMinP
6cb0: 61 67 65 3b 0a 20 20 20 20 20 20 70 43 61 63 68  age;.      pCach
6cc0: 65 2d 3e 70 6e 50 75 72 67 65 61 62 6c 65 20 3d  e->pnPurgeable =
6cd0: 20 26 70 47 72 6f 75 70 2d 3e 6e 50 75 72 67 65   &pGroup->nPurge
6ce0: 61 62 6c 65 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  able;.    }else{
6cf0: 0a 20 20 20 20 20 20 73 74 61 74 69 63 20 75 6e  .      static un
6d00: 73 69 67 6e 65 64 20 69 6e 74 20 64 75 6d 6d 79  signed int dummy
6d10: 43 75 72 72 65 6e 74 50 61 67 65 3b 0a 20 20 20  CurrentPage;.   
6d20: 20 20 20 70 43 61 63 68 65 2d 3e 70 6e 50 75 72     pCache->pnPur
6d30: 67 65 61 62 6c 65 20 3d 20 26 64 75 6d 6d 79 43  geable = &dummyC
6d40: 75 72 72 65 6e 74 50 61 67 65 3b 0a 20 20 20 20  urrentPage;.    
6d50: 7d 0a 20 20 20 20 70 63 61 63 68 65 31 4c 65 61  }.    pcache1Lea
6d60: 76 65 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b  veMutex(pGroup);
6d70: 0a 20 20 20 20 69 66 28 20 70 43 61 63 68 65 2d  .    if( pCache-
6d80: 3e 6e 48 61 73 68 3d 3d 30 20 29 7b 0a 20 20 20  >nHash==0 ){.   
6d90: 20 20 20 70 63 61 63 68 65 31 44 65 73 74 72 6f     pcache1Destro
6da0: 79 28 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68  y((sqlite3_pcach
6db0: 65 2a 29 70 43 61 63 68 65 29 3b 0a 20 20 20 20  e*)pCache);.    
6dc0: 20 20 70 43 61 63 68 65 20 3d 20 30 3b 0a 20 20    pCache = 0;.  
6dd0: 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e    }.  }.  return
6de0: 20 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65   (sqlite3_pcache
6df0: 20 2a 29 70 43 61 63 68 65 3b 0a 7d 0a 0a 2f 2a   *)pCache;.}../*
6e00: 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69  .** Implementati
6e10: 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65  on of the sqlite
6e20: 33 5f 70 63 61 63 68 65 2e 78 43 61 63 68 65 73  3_pcache.xCaches
6e30: 69 7a 65 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a  ize method. .**.
6e40: 2a 2a 20 43 6f 6e 66 69 67 75 72 65 20 74 68 65  ** Configure the
6e50: 20 63 61 63 68 65 5f 73 69 7a 65 20 6c 69 6d 69   cache_size limi
6e60: 74 20 66 6f 72 20 61 20 63 61 63 68 65 2e 0a 2a  t for a cache..*
6e70: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63  /.static void pc
6e80: 61 63 68 65 31 43 61 63 68 65 73 69 7a 65 28 73  ache1Cachesize(s
6e90: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70  qlite3_pcache *p
6ea0: 2c 20 69 6e 74 20 6e 4d 61 78 29 7b 0a 20 20 50  , int nMax){.  P
6eb0: 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d  Cache1 *pCache =
6ec0: 20 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20   (PCache1 *)p;. 
6ed0: 20 69 66 28 20 70 43 61 63 68 65 2d 3e 62 50 75   if( pCache->bPu
6ee0: 72 67 65 61 62 6c 65 20 29 7b 0a 20 20 20 20 50  rgeable ){.    P
6ef0: 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 20 3d 20  Group *pGroup = 
6f00: 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b 0a  pCache->pGroup;.
6f10: 20 20 20 20 70 63 61 63 68 65 31 45 6e 74 65 72      pcache1Enter
6f20: 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b 0a 20  Mutex(pGroup);. 
6f30: 20 20 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50     pGroup->nMaxP
6f40: 61 67 65 20 2b 3d 20 28 6e 4d 61 78 20 2d 20 70  age += (nMax - p
6f50: 43 61 63 68 65 2d 3e 6e 4d 61 78 29 3b 0a 20 20  Cache->nMax);.  
6f60: 20 20 70 47 72 6f 75 70 2d 3e 6d 78 50 69 6e 6e    pGroup->mxPinn
6f70: 65 64 20 3d 20 70 47 72 6f 75 70 2d 3e 6e 4d 61  ed = pGroup->nMa
6f80: 78 50 61 67 65 20 2b 20 31 30 20 2d 20 70 47 72  xPage + 10 - pGr
6f90: 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67 65 3b 0a 20  oup->nMinPage;. 
6fa0: 20 20 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 20     pCache->nMax 
6fb0: 3d 20 6e 4d 61 78 3b 0a 20 20 20 20 70 43 61 63  = nMax;.    pCac
6fc0: 68 65 2d 3e 6e 39 30 70 63 74 20 3d 20 70 43 61  he->n90pct = pCa
6fd0: 63 68 65 2d 3e 6e 4d 61 78 2a 39 2f 31 30 3b 0a  che->nMax*9/10;.
6fe0: 20 20 20 20 70 63 61 63 68 65 31 45 6e 66 6f 72      pcache1Enfor
6ff0: 63 65 4d 61 78 50 61 67 65 28 70 43 61 63 68 65  ceMaxPage(pCache
7000: 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31 4c 65  );.    pcache1Le
7010: 61 76 65 4d 75 74 65 78 28 70 47 72 6f 75 70 29  aveMutex(pGroup)
7020: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49  ;.  }.}../*.** I
7030: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66  mplementation of
7040: 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61   the sqlite3_pca
7050: 63 68 65 2e 78 53 68 72 69 6e 6b 20 6d 65 74 68  che.xShrink meth
7060: 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20 46 72 65 65 20  od. .**.** Free 
7070: 75 70 20 61 73 20 6d 75 63 68 20 6d 65 6d 6f 72  up as much memor
7080: 79 20 61 73 20 70 6f 73 73 69 62 6c 65 2e 0a 2a  y as possible..*
7090: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63  /.static void pc
70a0: 61 63 68 65 31 53 68 72 69 6e 6b 28 73 71 6c 69  ache1Shrink(sqli
70b0: 74 65 33 5f 70 63 61 63 68 65 20 2a 70 29 7b 0a  te3_pcache *p){.
70c0: 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68    PCache1 *pCach
70d0: 65 20 3d 20 28 50 43 61 63 68 65 31 2a 29 70 3b  e = (PCache1*)p;
70e0: 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 62  .  if( pCache->b
70f0: 50 75 72 67 65 61 62 6c 65 20 29 7b 0a 20 20 20  Purgeable ){.   
7100: 20 50 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 20   PGroup *pGroup 
7110: 3d 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70  = pCache->pGroup
7120: 3b 0a 20 20 20 20 69 6e 74 20 73 61 76 65 64 4d  ;.    int savedM
7130: 61 78 50 61 67 65 3b 0a 20 20 20 20 70 63 61 63  axPage;.    pcac
7140: 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70 47  he1EnterMutex(pG
7150: 72 6f 75 70 29 3b 0a 20 20 20 20 73 61 76 65 64  roup);.    saved
7160: 4d 61 78 50 61 67 65 20 3d 20 70 47 72 6f 75 70  MaxPage = pGroup
7170: 2d 3e 6e 4d 61 78 50 61 67 65 3b 0a 20 20 20 20  ->nMaxPage;.    
7180: 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65  pGroup->nMaxPage
7190: 20 3d 20 30 3b 0a 20 20 20 20 70 63 61 63 68 65   = 0;.    pcache
71a0: 31 45 6e 66 6f 72 63 65 4d 61 78 50 61 67 65 28  1EnforceMaxPage(
71b0: 70 43 61 63 68 65 29 3b 0a 20 20 20 20 70 47 72  pCache);.    pGr
71c0: 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65 20 3d 20  oup->nMaxPage = 
71d0: 73 61 76 65 64 4d 61 78 50 61 67 65 3b 0a 20 20  savedMaxPage;.  
71e0: 20 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75    pcache1LeaveMu
71f0: 74 65 78 28 70 47 72 6f 75 70 29 3b 0a 20 20 7d  tex(pGroup);.  }
7200: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d  .}../*.** Implem
7210: 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20  entation of the 
7220: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78  sqlite3_pcache.x
7230: 50 61 67 65 63 6f 75 6e 74 20 6d 65 74 68 6f 64  Pagecount method
7240: 2e 20 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  . .*/.static int
7250: 20 70 63 61 63 68 65 31 50 61 67 65 63 6f 75 6e   pcache1Pagecoun
7260: 74 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  t(sqlite3_pcache
7270: 20 2a 70 29 7b 0a 20 20 69 6e 74 20 6e 3b 0a 20   *p){.  int n;. 
7280: 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68 65   PCache1 *pCache
7290: 20 3d 20 28 50 43 61 63 68 65 31 2a 29 70 3b 0a   = (PCache1*)p;.
72a0: 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75    pcache1EnterMu
72b0: 74 65 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f  tex(pCache->pGro
72c0: 75 70 29 3b 0a 20 20 6e 20 3d 20 70 43 61 63 68  up);.  n = pCach
72d0: 65 2d 3e 6e 50 61 67 65 3b 0a 20 20 70 63 61 63  e->nPage;.  pcac
72e0: 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 70 43  he1LeaveMutex(pC
72f0: 61 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 20  ache->pGroup);. 
7300: 20 72 65 74 75 72 6e 20 6e 3b 0a 7d 0a 0a 0a 2f   return n;.}.../
7310: 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 20 73  *.** Implement s
7320: 74 65 70 73 20 33 2c 20 34 2c 20 61 6e 64 20 35  teps 3, 4, and 5
7330: 20 6f 66 20 74 68 65 20 70 63 61 63 68 65 31 46   of the pcache1F
7340: 65 74 63 68 28 29 20 61 6c 67 6f 72 69 74 68 6d  etch() algorithm
7350: 20 64 65 73 63 72 69 62 65 64 0a 2a 2a 20 69 6e   described.** in
7360: 20 74 68 65 20 68 65 61 64 65 72 20 6f 66 20 74   the header of t
7370: 68 65 20 70 63 61 63 68 65 31 46 65 74 63 68 28  he pcache1Fetch(
7380: 29 20 70 72 6f 63 65 64 75 72 65 2e 0a 2a 2a 0a  ) procedure..**.
7390: 2a 2a 20 54 68 69 73 20 73 74 65 70 73 20 61 72  ** This steps ar
73a0: 65 20 62 72 6f 6b 65 6e 20 6f 75 74 20 69 6e 74  e broken out int
73b0: 6f 20 61 20 73 65 70 61 72 61 74 65 20 70 72 6f  o a separate pro
73c0: 63 65 64 75 72 65 20 62 65 63 61 75 73 65 20 74  cedure because t
73d0: 68 65 79 20 61 72 65 0a 2a 2a 20 75 73 75 61 6c  hey are.** usual
73e0: 6c 79 20 6e 6f 74 20 6e 65 65 64 65 64 2c 20 61  ly not needed, a
73f0: 6e 64 20 62 79 20 61 76 6f 69 64 69 6e 67 20 74  nd by avoiding t
7400: 68 65 20 73 74 61 63 6b 20 69 6e 69 74 69 61 6c  he stack initial
7410: 69 7a 61 74 69 6f 6e 20 72 65 71 75 69 72 65 64  ization required
7420: 0a 2a 2a 20 66 6f 72 20 74 68 65 73 65 20 73 74  .** for these st
7430: 65 70 73 2c 20 74 68 65 20 6d 61 69 6e 20 70 63  eps, the main pc
7440: 61 63 68 65 31 46 65 74 63 68 28 29 20 70 72 6f  ache1Fetch() pro
7450: 63 65 64 75 72 65 20 63 61 6e 20 72 75 6e 20 66  cedure can run f
7460: 61 73 74 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63  aster..*/.static
7470: 20 53 51 4c 49 54 45 5f 4e 4f 49 4e 4c 49 4e 45   SQLITE_NOINLINE
7480: 20 50 67 48 64 72 31 20 2a 70 63 61 63 68 65 31   PgHdr1 *pcache1
7490: 46 65 74 63 68 53 74 61 67 65 32 28 0a 20 20 50  FetchStage2(.  P
74a0: 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 2c 20  Cache1 *pCache, 
74b0: 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  .  unsigned int 
74c0: 69 4b 65 79 2c 20 0a 20 20 69 6e 74 20 63 72 65  iKey, .  int cre
74d0: 61 74 65 46 6c 61 67 0a 29 7b 0a 20 20 75 6e 73  ateFlag.){.  uns
74e0: 69 67 6e 65 64 20 69 6e 74 20 6e 50 69 6e 6e 65  igned int nPinne
74f0: 64 3b 0a 20 20 50 47 72 6f 75 70 20 2a 70 47 72  d;.  PGroup *pGr
7500: 6f 75 70 20 3d 20 70 43 61 63 68 65 2d 3e 70 47  oup = pCache->pG
7510: 72 6f 75 70 3b 0a 20 20 50 67 48 64 72 31 20 2a  roup;.  PgHdr1 *
7520: 70 50 61 67 65 20 3d 20 30 3b 0a 0a 20 20 2f 2a  pPage = 0;..  /*
7530: 20 53 74 65 70 20 33 3a 20 41 62 6f 72 74 20 69   Step 3: Abort i
7540: 66 20 63 72 65 61 74 65 46 6c 61 67 20 69 73 20  f createFlag is 
7550: 31 20 62 75 74 20 74 68 65 20 63 61 63 68 65 20  1 but the cache 
7560: 69 73 20 6e 65 61 72 6c 79 20 66 75 6c 6c 20 2a  is nearly full *
7570: 2f 0a 20 20 61 73 73 65 72 74 28 20 70 43 61 63  /.  assert( pCac
7580: 68 65 2d 3e 6e 50 61 67 65 20 3e 3d 20 70 43 61  he->nPage >= pCa
7590: 63 68 65 2d 3e 6e 52 65 63 79 63 6c 61 62 6c 65  che->nRecyclable
75a0: 20 29 3b 0a 20 20 6e 50 69 6e 6e 65 64 20 3d 20   );.  nPinned = 
75b0: 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 20 2d 20  pCache->nPage - 
75c0: 70 43 61 63 68 65 2d 3e 6e 52 65 63 79 63 6c 61  pCache->nRecycla
75d0: 62 6c 65 3b 0a 20 20 61 73 73 65 72 74 28 20 70  ble;.  assert( p
75e0: 47 72 6f 75 70 2d 3e 6d 78 50 69 6e 6e 65 64 20  Group->mxPinned 
75f0: 3d 3d 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50  == pGroup->nMaxP
7600: 61 67 65 20 2b 20 31 30 20 2d 20 70 47 72 6f 75  age + 10 - pGrou
7610: 70 2d 3e 6e 4d 69 6e 50 61 67 65 20 29 3b 0a 20  p->nMinPage );. 
7620: 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65 2d   assert( pCache-
7630: 3e 6e 39 30 70 63 74 20 3d 3d 20 70 43 61 63 68  >n90pct == pCach
7640: 65 2d 3e 6e 4d 61 78 2a 39 2f 31 30 20 29 3b 0a  e->nMax*9/10 );.
7650: 20 20 69 66 28 20 63 72 65 61 74 65 46 6c 61 67    if( createFlag
7660: 3d 3d 31 20 26 26 20 28 0a 20 20 20 20 20 20 20  ==1 && (.       
7670: 20 6e 50 69 6e 6e 65 64 3e 3d 70 47 72 6f 75 70   nPinned>=pGroup
7680: 2d 3e 6d 78 50 69 6e 6e 65 64 0a 20 20 20 20 20  ->mxPinned.     
7690: 7c 7c 20 6e 50 69 6e 6e 65 64 3e 3d 70 43 61 63  || nPinned>=pCac
76a0: 68 65 2d 3e 6e 39 30 70 63 74 0a 20 20 20 20 20  he->n90pct.     
76b0: 7c 7c 20 28 70 63 61 63 68 65 31 55 6e 64 65 72  || (pcache1Under
76c0: 4d 65 6d 6f 72 79 50 72 65 73 73 75 72 65 28 70  MemoryPressure(p
76d0: 43 61 63 68 65 29 20 26 26 20 70 43 61 63 68 65  Cache) && pCache
76e0: 2d 3e 6e 52 65 63 79 63 6c 61 62 6c 65 3c 6e 50  ->nRecyclable<nP
76f0: 69 6e 6e 65 64 29 0a 20 20 29 29 7b 0a 20 20 20  inned).  )){.   
7700: 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 0a   return 0;.  }..
7710: 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 6e 50    if( pCache->nP
7720: 61 67 65 3e 3d 70 43 61 63 68 65 2d 3e 6e 48 61  age>=pCache->nHa
7730: 73 68 20 29 20 70 63 61 63 68 65 31 52 65 73 69  sh ) pcache1Resi
7740: 7a 65 48 61 73 68 28 70 43 61 63 68 65 29 3b 0a  zeHash(pCache);.
7750: 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65    assert( pCache
7760: 2d 3e 6e 48 61 73 68 3e 30 20 26 26 20 70 43 61  ->nHash>0 && pCa
7770: 63 68 65 2d 3e 61 70 48 61 73 68 20 29 3b 0a 0a  che->apHash );..
7780: 20 20 2f 2a 20 53 74 65 70 20 34 2e 20 54 72 79    /* Step 4. Try
7790: 20 74 6f 20 72 65 63 79 63 6c 65 20 61 20 70 61   to recycle a pa
77a0: 67 65 2e 20 2a 2f 0a 20 20 69 66 28 20 70 43 61  ge. */.  if( pCa
77b0: 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 0a  che->bPurgeable.
77c0: 20 20 20 26 26 20 21 70 47 72 6f 75 70 2d 3e 6c     && !pGroup->l
77d0: 72 75 2e 70 4c 72 75 50 72 65 76 2d 3e 69 73 41  ru.pLruPrev->isA
77e0: 6e 63 68 6f 72 0a 20 20 20 26 26 20 28 28 70 43  nchor.   && ((pC
77f0: 61 63 68 65 2d 3e 6e 50 61 67 65 2b 31 3e 3d 70  ache->nPage+1>=p
7800: 43 61 63 68 65 2d 3e 6e 4d 61 78 29 20 7c 7c 20  Cache->nMax) || 
7810: 70 63 61 63 68 65 31 55 6e 64 65 72 4d 65 6d 6f  pcache1UnderMemo
7820: 72 79 50 72 65 73 73 75 72 65 28 70 43 61 63 68  ryPressure(pCach
7830: 65 29 29 0a 20 20 29 7b 0a 20 20 20 20 50 43 61  e)).  ){.    PCa
7840: 63 68 65 31 20 2a 70 4f 74 68 65 72 3b 0a 20 20  che1 *pOther;.  
7850: 20 20 70 50 61 67 65 20 3d 20 70 47 72 6f 75 70    pPage = pGroup
7860: 2d 3e 6c 72 75 2e 70 4c 72 75 50 72 65 76 3b 0a  ->lru.pLruPrev;.
7870: 20 20 20 20 61 73 73 65 72 74 28 20 50 41 47 45      assert( PAGE
7880: 5f 49 53 5f 55 4e 50 49 4e 4e 45 44 28 70 50 61  _IS_UNPINNED(pPa
7890: 67 65 29 20 29 3b 0a 20 20 20 20 70 63 61 63 68  ge) );.    pcach
78a0: 65 31 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73 68  e1RemoveFromHash
78b0: 28 70 50 61 67 65 2c 20 30 29 3b 0a 20 20 20 20  (pPage, 0);.    
78c0: 70 63 61 63 68 65 31 50 69 6e 50 61 67 65 28 70  pcache1PinPage(p
78d0: 50 61 67 65 29 3b 0a 20 20 20 20 70 4f 74 68 65  Page);.    pOthe
78e0: 72 20 3d 20 70 50 61 67 65 2d 3e 70 43 61 63 68  r = pPage->pCach
78f0: 65 3b 0a 20 20 20 20 69 66 28 20 70 4f 74 68 65  e;.    if( pOthe
7900: 72 2d 3e 73 7a 41 6c 6c 6f 63 20 21 3d 20 70 43  r->szAlloc != pC
7910: 61 63 68 65 2d 3e 73 7a 41 6c 6c 6f 63 20 29 7b  ache->szAlloc ){
7920: 0a 20 20 20 20 20 20 70 63 61 63 68 65 31 46 72  .      pcache1Fr
7930: 65 65 50 61 67 65 28 70 50 61 67 65 29 3b 0a 20  eePage(pPage);. 
7940: 20 20 20 20 20 70 50 61 67 65 20 3d 20 30 3b 0a       pPage = 0;.
7950: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
7960: 20 70 47 72 6f 75 70 2d 3e 6e 50 75 72 67 65 61   pGroup->nPurgea
7970: 62 6c 65 20 2d 3d 20 28 70 4f 74 68 65 72 2d 3e  ble -= (pOther->
7980: 62 50 75 72 67 65 61 62 6c 65 20 2d 20 70 43 61  bPurgeable - pCa
7990: 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 29  che->bPurgeable)
79a0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f  ;.    }.  }..  /
79b0: 2a 20 53 74 65 70 20 35 2e 20 49 66 20 61 20 75  * Step 5. If a u
79c0: 73 61 62 6c 65 20 70 61 67 65 20 62 75 66 66 65  sable page buffe
79d0: 72 20 68 61 73 20 73 74 69 6c 6c 20 6e 6f 74 20  r has still not 
79e0: 62 65 65 6e 20 66 6f 75 6e 64 2c 20 0a 20 20 2a  been found, .  *
79f0: 2a 20 61 74 74 65 6d 70 74 20 74 6f 20 61 6c 6c  * attempt to all
7a00: 6f 63 61 74 65 20 61 20 6e 65 77 20 6f 6e 65 2e  ocate a new one.
7a10: 20 0a 20 20 2a 2f 0a 20 20 69 66 28 20 21 70 50   .  */.  if( !pP
7a20: 61 67 65 20 29 7b 0a 20 20 20 20 70 50 61 67 65  age ){.    pPage
7a30: 20 3d 20 70 63 61 63 68 65 31 41 6c 6c 6f 63 50   = pcache1AllocP
7a40: 61 67 65 28 70 43 61 63 68 65 2c 20 63 72 65 61  age(pCache, crea
7a50: 74 65 46 6c 61 67 3d 3d 31 29 3b 0a 20 20 7d 0a  teFlag==1);.  }.
7a60: 0a 20 20 69 66 28 20 70 50 61 67 65 20 29 7b 0a  .  if( pPage ){.
7a70: 20 20 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74      unsigned int
7a80: 20 68 20 3d 20 69 4b 65 79 20 25 20 70 43 61 63   h = iKey % pCac
7a90: 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 20 20 70  he->nHash;.    p
7aa0: 43 61 63 68 65 2d 3e 6e 50 61 67 65 2b 2b 3b 0a  Cache->nPage++;.
7ab0: 20 20 20 20 70 50 61 67 65 2d 3e 69 4b 65 79 20      pPage->iKey 
7ac0: 3d 20 69 4b 65 79 3b 0a 20 20 20 20 70 50 61 67  = iKey;.    pPag
7ad0: 65 2d 3e 70 4e 65 78 74 20 3d 20 70 43 61 63 68  e->pNext = pCach
7ae0: 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 0a 20 20  e->apHash[h];.  
7af0: 20 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65 20    pPage->pCache 
7b00: 3d 20 70 43 61 63 68 65 3b 0a 20 20 20 20 70 50  = pCache;.    pP
7b10: 61 67 65 2d 3e 70 4c 72 75 50 72 65 76 20 3d 20  age->pLruPrev = 
7b20: 30 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 4c  0;.    pPage->pL
7b30: 72 75 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20 20  ruNext = 0;.    
7b40: 2a 28 76 6f 69 64 20 2a 2a 29 70 50 61 67 65 2d  *(void **)pPage-
7b50: 3e 70 61 67 65 2e 70 45 78 74 72 61 20 3d 20 30  >page.pExtra = 0
7b60: 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 61 70  ;.    pCache->ap
7b70: 48 61 73 68 5b 68 5d 20 3d 20 70 50 61 67 65 3b  Hash[h] = pPage;
7b80: 0a 20 20 20 20 69 66 28 20 69 4b 65 79 3e 70 43  .    if( iKey>pC
7b90: 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 29 7b  ache->iMaxKey ){
7ba0: 0a 20 20 20 20 20 20 70 43 61 63 68 65 2d 3e 69  .      pCache->i
7bb0: 4d 61 78 4b 65 79 20 3d 20 69 4b 65 79 3b 0a 20  MaxKey = iKey;. 
7bc0: 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72     }.  }.  retur
7bd0: 6e 20 70 50 61 67 65 3b 0a 7d 0a 0a 2f 2a 0a 2a  n pPage;.}../*.*
7be0: 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  * Implementation
7bf0: 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f   of the sqlite3_
7c00: 70 63 61 63 68 65 2e 78 46 65 74 63 68 20 6d 65  pcache.xFetch me
7c10: 74 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20 46 65 74  thod. .**.** Fet
7c20: 63 68 20 61 20 70 61 67 65 20 62 79 20 6b 65 79  ch a page by key
7c30: 20 76 61 6c 75 65 2e 0a 2a 2a 0a 2a 2a 20 57 68   value..**.** Wh
7c40: 65 74 68 65 72 20 6f 72 20 6e 6f 74 20 61 20 6e  ether or not a n
7c50: 65 77 20 70 61 67 65 20 6d 61 79 20 62 65 20 61  ew page may be a
7c60: 6c 6c 6f 63 61 74 65 64 20 62 79 20 74 68 69 73  llocated by this
7c70: 20 66 75 6e 63 74 69 6f 6e 20 64 65 70 65 6e 64   function depend
7c80: 73 20 6f 6e 0a 2a 2a 20 74 68 65 20 76 61 6c 75  s on.** the valu
7c90: 65 20 6f 66 20 74 68 65 20 63 72 65 61 74 65 46  e of the createF
7ca0: 6c 61 67 20 61 72 67 75 6d 65 6e 74 2e 20 20 30  lag argument.  0
7cb0: 20 6d 65 61 6e 73 20 64 6f 20 6e 6f 74 20 61 6c   means do not al
7cc0: 6c 6f 63 61 74 65 20 61 20 6e 65 77 0a 2a 2a 20  locate a new.** 
7cd0: 70 61 67 65 2e 20 20 31 20 6d 65 61 6e 73 20 61  page.  1 means a
7ce0: 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 70 61  llocate a new pa
7cf0: 67 65 20 69 66 20 73 70 61 63 65 20 69 73 20 65  ge if space is e
7d00: 61 73 69 6c 79 20 61 76 61 69 6c 61 62 6c 65 2e  asily available.
7d10: 20 20 32 20 0a 2a 2a 20 6d 65 61 6e 73 20 74 6f    2 .** means to
7d20: 20 74 72 79 20 72 65 61 6c 6c 79 20 68 61 72 64   try really hard
7d30: 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e   to allocate a n
7d40: 65 77 20 70 61 67 65 2e 0a 2a 2a 0a 2a 2a 20 46  ew page..**.** F
7d50: 6f 72 20 61 20 6e 6f 6e 2d 70 75 72 67 65 61 62  or a non-purgeab
7d60: 6c 65 20 63 61 63 68 65 20 28 61 20 63 61 63 68  le cache (a cach
7d70: 65 20 75 73 65 64 20 61 73 20 74 68 65 20 73 74  e used as the st
7d80: 6f 72 61 67 65 20 66 6f 72 20 61 6e 20 69 6e 2d  orage for an in-
7d90: 6d 65 6d 6f 72 79 0a 2a 2a 20 64 61 74 61 62 61  memory.** databa
7da0: 73 65 29 20 74 68 65 72 65 20 69 73 20 72 65 61  se) there is rea
7db0: 6c 6c 79 20 6e 6f 20 64 69 66 66 65 72 65 6e 63  lly no differenc
7dc0: 65 20 62 65 74 77 65 65 6e 20 63 72 65 61 74 65  e between create
7dd0: 46 6c 61 67 20 31 20 61 6e 64 20 32 2e 20 20 53  Flag 1 and 2.  S
7de0: 6f 0a 2a 2a 20 74 68 65 20 63 61 6c 6c 69 6e 67  o.** the calling
7df0: 20 66 75 6e 63 74 69 6f 6e 20 28 70 63 61 63 68   function (pcach
7e00: 65 2e 63 29 20 77 69 6c 6c 20 6e 65 76 65 72 20  e.c) will never 
7e10: 68 61 76 65 20 61 20 63 72 65 61 74 65 46 6c 61  have a createFla
7e20: 67 20 6f 66 20 31 20 6f 6e 0a 2a 2a 20 61 20 6e  g of 1 on.** a n
7e30: 6f 6e 2d 70 75 72 67 65 61 62 6c 65 20 63 61 63  on-purgeable cac
7e40: 68 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 72 65 20  he..**.** There 
7e50: 61 72 65 20 74 68 72 65 65 20 64 69 66 66 65 72  are three differ
7e60: 65 6e 74 20 61 70 70 72 6f 61 63 68 65 73 20 74  ent approaches t
7e70: 6f 20 6f 62 74 61 69 6e 69 6e 67 20 73 70 61 63  o obtaining spac
7e80: 65 20 66 6f 72 20 61 20 70 61 67 65 2c 0a 2a 2a  e for a page,.**
7e90: 20 64 65 70 65 6e 64 69 6e 67 20 6f 6e 20 74 68   depending on th
7ea0: 65 20 76 61 6c 75 65 20 6f 66 20 70 61 72 61 6d  e value of param
7eb0: 65 74 65 72 20 63 72 65 61 74 65 46 6c 61 67 20  eter createFlag 
7ec0: 28 77 68 69 63 68 20 6d 61 79 20 62 65 20 30 2c  (which may be 0,
7ed0: 20 31 20 6f 72 20 32 29 2e 0a 2a 2a 0a 2a 2a 20   1 or 2)..**.** 
7ee0: 20 20 31 2e 20 52 65 67 61 72 64 6c 65 73 73 20    1. Regardless 
7ef0: 6f 66 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20  of the value of 
7f00: 63 72 65 61 74 65 46 6c 61 67 2c 20 74 68 65 20  createFlag, the 
7f10: 63 61 63 68 65 20 69 73 20 73 65 61 72 63 68 65  cache is searche
7f20: 64 20 66 6f 72 20 61 20 0a 2a 2a 20 20 20 20 20  d for a .**     
7f30: 20 63 6f 70 79 20 6f 66 20 74 68 65 20 72 65 71   copy of the req
7f40: 75 65 73 74 65 64 20 70 61 67 65 2e 20 49 66 20  uested page. If 
7f50: 6f 6e 65 20 69 73 20 66 6f 75 6e 64 2c 20 69 74  one is found, it
7f60: 20 69 73 20 72 65 74 75 72 6e 65 64 2e 0a 2a 2a   is returned..**
7f70: 0a 2a 2a 20 20 20 32 2e 20 49 66 20 63 72 65 61  .**   2. If crea
7f80: 74 65 46 6c 61 67 3d 3d 30 20 61 6e 64 20 74 68  teFlag==0 and th
7f90: 65 20 70 61 67 65 20 69 73 20 6e 6f 74 20 61 6c  e page is not al
7fa0: 72 65 61 64 79 20 69 6e 20 74 68 65 20 63 61 63  ready in the cac
7fb0: 68 65 2c 20 4e 55 4c 4c 20 69 73 0a 2a 2a 20 20  he, NULL is.**  
7fc0: 20 20 20 20 72 65 74 75 72 6e 65 64 2e 0a 2a 2a      returned..**
7fd0: 0a 2a 2a 20 20 20 33 2e 20 49 66 20 63 72 65 61  .**   3. If crea
7fe0: 74 65 46 6c 61 67 20 69 73 20 31 2c 20 61 6e 64  teFlag is 1, and
7ff0: 20 74 68 65 20 70 61 67 65 20 69 73 20 6e 6f 74   the page is not
8000: 20 61 6c 72 65 61 64 79 20 69 6e 20 74 68 65 20   already in the 
8010: 63 61 63 68 65 2c 20 74 68 65 6e 0a 2a 2a 20 20  cache, then.**  
8020: 20 20 20 20 72 65 74 75 72 6e 20 4e 55 4c 4c 20      return NULL 
8030: 28 64 6f 20 6e 6f 74 20 61 6c 6c 6f 63 61 74 65  (do not allocate
8040: 20 61 20 6e 65 77 20 70 61 67 65 29 20 69 66 20   a new page) if 
8050: 61 6e 79 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f  any of the follo
8060: 77 69 6e 67 0a 2a 2a 20 20 20 20 20 20 63 6f 6e  wing.**      con
8070: 64 69 74 69 6f 6e 73 20 61 72 65 20 74 72 75 65  ditions are true
8080: 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 28 61  :.**.**       (a
8090: 29 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  ) the number of 
80a0: 70 61 67 65 73 20 70 69 6e 6e 65 64 20 62 79 20  pages pinned by 
80b0: 74 68 65 20 63 61 63 68 65 20 69 73 20 67 72 65  the cache is gre
80c0: 61 74 65 72 20 74 68 61 6e 0a 2a 2a 20 20 20 20  ater than.**    
80d0: 20 20 20 20 20 20 20 50 43 61 63 68 65 31 2e 6e         PCache1.n
80e0: 4d 61 78 2c 20 6f 72 0a 2a 2a 0a 2a 2a 20 20 20  Max, or.**.**   
80f0: 20 20 20 20 28 62 29 20 74 68 65 20 6e 75 6d 62      (b) the numb
8100: 65 72 20 6f 66 20 70 61 67 65 73 20 70 69 6e 6e  er of pages pinn
8110: 65 64 20 62 79 20 74 68 65 20 63 61 63 68 65 20  ed by the cache 
8120: 69 73 20 67 72 65 61 74 65 72 20 74 68 61 6e 0a  is greater than.
8130: 2a 2a 20 20 20 20 20 20 20 20 20 20 20 74 68 65  **           the
8140: 20 73 75 6d 20 6f 66 20 6e 4d 61 78 20 66 6f 72   sum of nMax for
8150: 20 61 6c 6c 20 70 75 72 67 65 61 62 6c 65 20 63   all purgeable c
8160: 61 63 68 65 73 2c 20 6c 65 73 73 20 74 68 65 20  aches, less the 
8170: 73 75 6d 20 6f 66 20 0a 2a 2a 20 20 20 20 20 20  sum of .**      
8180: 20 20 20 20 20 6e 4d 69 6e 20 66 6f 72 20 61 6c       nMin for al
8190: 6c 20 6f 74 68 65 72 20 70 75 72 67 65 61 62 6c  l other purgeabl
81a0: 65 20 63 61 63 68 65 73 2c 20 6f 72 0a 2a 2a 0a  e caches, or.**.
81b0: 2a 2a 20 20 20 34 2e 20 49 66 20 6e 6f 6e 65 20  **   4. If none 
81c0: 6f 66 20 74 68 65 20 66 69 72 73 74 20 74 68 72  of the first thr
81d0: 65 65 20 63 6f 6e 64 69 74 69 6f 6e 73 20 61 70  ee conditions ap
81e0: 70 6c 79 20 61 6e 64 20 74 68 65 20 63 61 63 68  ply and the cach
81f0: 65 20 69 73 20 6d 61 72 6b 65 64 0a 2a 2a 20 20  e is marked.**  
8200: 20 20 20 20 61 73 20 70 75 72 67 65 61 62 6c 65      as purgeable
8210: 2c 20 61 6e 64 20 69 66 20 6f 6e 65 20 6f 66 20  , and if one of 
8220: 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 69 73  the following is
8230: 20 74 72 75 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20   true:.**.**    
8240: 20 20 20 28 61 29 20 54 68 65 20 6e 75 6d 62 65     (a) The numbe
8250: 72 20 6f 66 20 70 61 67 65 73 20 61 6c 6c 6f 63  r of pages alloc
8260: 61 74 65 64 20 66 6f 72 20 74 68 65 20 63 61 63  ated for the cac
8270: 68 65 20 69 73 20 61 6c 72 65 61 64 79 20 0a 2a  he is already .*
8280: 2a 20 20 20 20 20 20 20 20 20 20 20 50 43 61 63  *           PCac
8290: 68 65 31 2e 6e 4d 61 78 2c 20 6f 72 0a 2a 2a 0a  he1.nMax, or.**.
82a0: 2a 2a 20 20 20 20 20 20 20 28 62 29 20 54 68 65  **       (b) The
82b0: 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73   number of pages
82c0: 20 61 6c 6c 6f 63 61 74 65 64 20 66 6f 72 20 61   allocated for a
82d0: 6c 6c 20 70 75 72 67 65 61 62 6c 65 20 63 61 63  ll purgeable cac
82e0: 68 65 73 20 69 73 0a 2a 2a 20 20 20 20 20 20 20  hes is.**       
82f0: 20 20 20 20 61 6c 72 65 61 64 79 20 65 71 75 61      already equa
8300: 6c 20 74 6f 20 6f 72 20 67 72 65 61 74 65 72 20  l to or greater 
8310: 74 68 61 6e 20 74 68 65 20 73 75 6d 20 6f 66 20  than the sum of 
8320: 6e 4d 61 78 20 66 6f 72 20 61 6c 6c 0a 2a 2a 20  nMax for all.** 
8330: 20 20 20 20 20 20 20 20 20 20 70 75 72 67 65 61            purgea
8340: 62 6c 65 20 63 61 63 68 65 73 2c 0a 2a 2a 0a 2a  ble caches,.**.*
8350: 2a 20 20 20 20 20 20 20 28 63 29 20 54 68 65 20  *       (c) The 
8360: 73 79 73 74 65 6d 20 69 73 20 75 6e 64 65 72 20  system is under 
8370: 6d 65 6d 6f 72 79 20 70 72 65 73 73 75 72 65 20  memory pressure 
8380: 61 6e 64 20 77 61 6e 74 73 20 74 6f 20 61 76 6f  and wants to avo
8390: 69 64 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20  id.**           
83a0: 75 6e 6e 65 63 65 73 73 61 72 79 20 70 61 67 65  unnecessary page
83b0: 73 20 63 61 63 68 65 20 65 6e 74 72 79 20 61 6c  s cache entry al
83c0: 6c 6f 63 61 74 69 6f 6e 73 0a 2a 2a 0a 2a 2a 20  locations.**.** 
83d0: 20 20 20 20 20 74 68 65 6e 20 61 74 74 65 6d 70       then attemp
83e0: 74 20 74 6f 20 72 65 63 79 63 6c 65 20 61 20 70  t to recycle a p
83f0: 61 67 65 20 66 72 6f 6d 20 74 68 65 20 4c 52 55  age from the LRU
8400: 20 6c 69 73 74 2e 20 49 66 20 69 74 20 69 73 20   list. If it is 
8410: 74 68 65 20 72 69 67 68 74 0a 2a 2a 20 20 20 20  the right.**    
8420: 20 20 73 69 7a 65 2c 20 72 65 74 75 72 6e 20 74    size, return t
8430: 68 65 20 72 65 63 79 63 6c 65 64 20 62 75 66 66  he recycled buff
8440: 65 72 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 66  er. Otherwise, f
8450: 72 65 65 20 74 68 65 20 62 75 66 66 65 72 20 61  ree the buffer a
8460: 6e 64 0a 2a 2a 20 20 20 20 20 20 70 72 6f 63 65  nd.**      proce
8470: 65 64 20 74 6f 20 73 74 65 70 20 35 2e 20 0a 2a  ed to step 5. .*
8480: 2a 0a 2a 2a 20 20 20 35 2e 20 4f 74 68 65 72 77  *.**   5. Otherw
8490: 69 73 65 2c 20 61 6c 6c 6f 63 61 74 65 20 61 6e  ise, allocate an
84a0: 64 20 72 65 74 75 72 6e 20 61 20 6e 65 77 20 70  d return a new p
84b0: 61 67 65 20 62 75 66 66 65 72 2e 0a 2a 2a 0a 2a  age buffer..**.*
84c0: 2a 20 54 68 65 72 65 20 61 72 65 20 74 77 6f 20  * There are two 
84d0: 76 65 72 73 69 6f 6e 73 20 6f 66 20 74 68 69 73  versions of this
84e0: 20 72 6f 75 74 69 6e 65 2e 20 20 70 63 61 63 68   routine.  pcach
84f0: 65 31 46 65 74 63 68 57 69 74 68 4d 75 74 65 78  e1FetchWithMutex
8500: 28 29 20 69 73 0a 2a 2a 20 74 68 65 20 67 65 6e  () is.** the gen
8510: 65 72 61 6c 20 63 61 73 65 2e 20 20 70 63 61 63  eral case.  pcac
8520: 68 65 31 46 65 74 63 68 4e 6f 4d 75 74 65 78 28  he1FetchNoMutex(
8530: 29 20 69 73 20 61 20 66 61 73 74 65 72 20 69 6d  ) is a faster im
8540: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 66 6f 72  plementation for
8550: 0a 2a 2a 20 74 68 65 20 63 6f 6d 6d 6f 6e 20 63  .** the common c
8560: 61 73 65 20 77 68 65 72 65 20 70 47 72 6f 75 70  ase where pGroup
8570: 2d 3e 6d 75 74 65 78 20 69 73 20 4e 55 4c 4c 2e  ->mutex is NULL.
8580: 20 20 54 68 65 20 70 63 61 63 68 65 31 46 65 74    The pcache1Fet
8590: 63 68 28 29 20 77 72 61 70 70 65 72 0a 2a 2a 20  ch() wrapper.** 
85a0: 69 6e 76 6f 6b 65 73 20 74 68 65 20 61 70 70 72  invokes the appr
85b0: 6f 70 72 69 61 74 65 20 72 6f 75 74 69 6e 65 2e  opriate routine.
85c0: 0a 2a 2f 0a 73 74 61 74 69 63 20 50 67 48 64 72  .*/.static PgHdr
85d0: 31 20 2a 70 63 61 63 68 65 31 46 65 74 63 68 4e  1 *pcache1FetchN
85e0: 6f 4d 75 74 65 78 28 0a 20 20 73 71 6c 69 74 65  oMutex(.  sqlite
85f0: 33 5f 70 63 61 63 68 65 20 2a 70 2c 20 0a 20 20  3_pcache *p, .  
8600: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4b 65  unsigned int iKe
8610: 79 2c 20 0a 20 20 69 6e 74 20 63 72 65 61 74 65  y, .  int create
8620: 46 6c 61 67 0a 29 7b 0a 20 20 50 43 61 63 68 65  Flag.){.  PCache
8630: 31 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61  1 *pCache = (PCa
8640: 63 68 65 31 20 2a 29 70 3b 0a 20 20 50 67 48 64  che1 *)p;.  PgHd
8650: 72 31 20 2a 70 50 61 67 65 20 3d 20 30 3b 0a 0a  r1 *pPage = 0;..
8660: 20 20 2f 2a 20 53 74 65 70 20 31 3a 20 53 65 61    /* Step 1: Sea
8670: 72 63 68 20 74 68 65 20 68 61 73 68 20 74 61 62  rch the hash tab
8680: 6c 65 20 66 6f 72 20 61 6e 20 65 78 69 73 74 69  le for an existi
8690: 6e 67 20 65 6e 74 72 79 2e 20 2a 2f 0a 20 20 70  ng entry. */.  p
86a0: 50 61 67 65 20 3d 20 70 43 61 63 68 65 2d 3e 61  Page = pCache->a
86b0: 70 48 61 73 68 5b 69 4b 65 79 20 25 20 70 43 61  pHash[iKey % pCa
86c0: 63 68 65 2d 3e 6e 48 61 73 68 5d 3b 0a 20 20 77  che->nHash];.  w
86d0: 68 69 6c 65 28 20 70 50 61 67 65 20 26 26 20 70  hile( pPage && p
86e0: 50 61 67 65 2d 3e 69 4b 65 79 21 3d 69 4b 65 79  Page->iKey!=iKey
86f0: 20 29 7b 20 70 50 61 67 65 20 3d 20 70 50 61 67   ){ pPage = pPag
8700: 65 2d 3e 70 4e 65 78 74 3b 20 7d 0a 0a 20 20 2f  e->pNext; }..  /
8710: 2a 20 53 74 65 70 20 32 3a 20 49 66 20 74 68 65  * Step 2: If the
8720: 20 70 61 67 65 20 77 61 73 20 66 6f 75 6e 64 20   page was found 
8730: 69 6e 20 74 68 65 20 68 61 73 68 20 74 61 62 6c  in the hash tabl
8740: 65 2c 20 74 68 65 6e 20 72 65 74 75 72 6e 20 69  e, then return i
8750: 74 2e 0a 20 20 2a 2a 20 49 66 20 74 68 65 20 70  t..  ** If the p
8760: 61 67 65 20 77 61 73 20 6e 6f 74 20 69 6e 20 74  age was not in t
8770: 68 65 20 68 61 73 68 20 74 61 62 6c 65 20 61 6e  he hash table an
8780: 64 20 63 72 65 61 74 65 46 6c 61 67 20 69 73 20  d createFlag is 
8790: 30 2c 20 61 62 6f 72 74 2e 0a 20 20 2a 2a 20 4f  0, abort..  ** O
87a0: 74 68 65 72 77 69 73 65 20 28 70 61 67 65 20 6e  therwise (page n
87b0: 6f 74 20 69 6e 20 68 61 73 68 20 61 6e 64 20 63  ot in hash and c
87c0: 72 65 61 74 65 46 6c 61 67 21 3d 30 29 20 63 6f  reateFlag!=0) co
87d0: 6e 74 69 6e 75 65 20 77 69 74 68 0a 20 20 2a 2a  ntinue with.  **
87e0: 20 73 75 62 73 65 71 75 65 6e 74 20 73 74 65 70   subsequent step
87f0: 73 20 74 6f 20 74 72 79 20 74 6f 20 63 72 65 61  s to try to crea
8800: 74 65 20 74 68 65 20 70 61 67 65 2e 20 2a 2f 0a  te the page. */.
8810: 20 20 69 66 28 20 70 50 61 67 65 20 29 7b 0a 20    if( pPage ){. 
8820: 20 20 20 69 66 28 20 50 41 47 45 5f 49 53 5f 55     if( PAGE_IS_U
8830: 4e 50 49 4e 4e 45 44 28 70 50 61 67 65 29 20 29  NPINNED(pPage) )
8840: 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 70  {.      return p
8850: 63 61 63 68 65 31 50 69 6e 50 61 67 65 28 70 50  cache1PinPage(pP
8860: 61 67 65 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  age);.    }else{
8870: 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 70 50  .      return pP
8880: 61 67 65 3b 0a 20 20 20 20 7d 0a 20 20 7d 65 6c  age;.    }.  }el
8890: 73 65 20 69 66 28 20 63 72 65 61 74 65 46 6c 61  se if( createFla
88a0: 67 20 29 7b 0a 20 20 20 20 2f 2a 20 53 74 65 70  g ){.    /* Step
88b0: 73 20 33 2c 20 34 2c 20 61 6e 64 20 35 20 69 6d  s 3, 4, and 5 im
88c0: 70 6c 65 6d 65 6e 74 65 64 20 62 79 20 74 68 69  plemented by thi
88d0: 73 20 73 75 62 72 6f 75 74 69 6e 65 20 2a 2f 0a  s subroutine */.
88e0: 20 20 20 20 72 65 74 75 72 6e 20 70 63 61 63 68      return pcach
88f0: 65 31 46 65 74 63 68 53 74 61 67 65 32 28 70 43  e1FetchStage2(pC
8900: 61 63 68 65 2c 20 69 4b 65 79 2c 20 63 72 65 61  ache, iKey, crea
8910: 74 65 46 6c 61 67 29 3b 0a 20 20 7d 65 6c 73 65  teFlag);.  }else
8920: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a  {.    return 0;.
8930: 20 20 7d 0a 7d 0a 23 69 66 20 50 43 41 43 48 45    }.}.#if PCACHE
8940: 31 5f 4d 49 47 48 54 5f 55 53 45 5f 47 52 4f 55  1_MIGHT_USE_GROU
8950: 50 5f 4d 55 54 45 58 0a 73 74 61 74 69 63 20 50  P_MUTEX.static P
8960: 67 48 64 72 31 20 2a 70 63 61 63 68 65 31 46 65  gHdr1 *pcache1Fe
8970: 74 63 68 57 69 74 68 4d 75 74 65 78 28 0a 20 20  tchWithMutex(.  
8980: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a  sqlite3_pcache *
8990: 70 2c 20 0a 20 20 75 6e 73 69 67 6e 65 64 20 69  p, .  unsigned i
89a0: 6e 74 20 69 4b 65 79 2c 20 0a 20 20 69 6e 74 20  nt iKey, .  int 
89b0: 63 72 65 61 74 65 46 6c 61 67 0a 29 7b 0a 20 20  createFlag.){.  
89c0: 50 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 20  PCache1 *pCache 
89d0: 3d 20 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a  = (PCache1 *)p;.
89e0: 20 20 50 67 48 64 72 31 20 2a 70 50 61 67 65 3b    PgHdr1 *pPage;
89f0: 0a 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65 72  ..  pcache1Enter
8a00: 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e 70 47  Mutex(pCache->pG
8a10: 72 6f 75 70 29 3b 0a 20 20 70 50 61 67 65 20 3d  roup);.  pPage =
8a20: 20 70 63 61 63 68 65 31 46 65 74 63 68 4e 6f 4d   pcache1FetchNoM
8a30: 75 74 65 78 28 70 2c 20 69 4b 65 79 2c 20 63 72  utex(p, iKey, cr
8a40: 65 61 74 65 46 6c 61 67 29 3b 0a 20 20 61 73 73  eateFlag);.  ass
8a50: 65 72 74 28 20 70 50 61 67 65 3d 3d 30 20 7c 7c  ert( pPage==0 ||
8a60: 20 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79   pCache->iMaxKey
8a70: 3e 3d 69 4b 65 79 20 29 3b 0a 20 20 70 63 61 63  >=iKey );.  pcac
8a80: 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 70 43  he1LeaveMutex(pC
8a90: 61 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 20  ache->pGroup);. 
8aa0: 20 72 65 74 75 72 6e 20 70 50 61 67 65 3b 0a 7d   return pPage;.}
8ab0: 0a 23 65 6e 64 69 66 0a 73 74 61 74 69 63 20 73  .#endif.static s
8ac0: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 5f 70 61  qlite3_pcache_pa
8ad0: 67 65 20 2a 70 63 61 63 68 65 31 46 65 74 63 68  ge *pcache1Fetch
8ae0: 28 0a 20 20 73 71 6c 69 74 65 33 5f 70 63 61 63  (.  sqlite3_pcac
8af0: 68 65 20 2a 70 2c 20 0a 20 20 75 6e 73 69 67 6e  he *p, .  unsign
8b00: 65 64 20 69 6e 74 20 69 4b 65 79 2c 20 0a 20 20  ed int iKey, .  
8b10: 69 6e 74 20 63 72 65 61 74 65 46 6c 61 67 0a 29  int createFlag.)
8b20: 7b 0a 23 69 66 20 50 43 41 43 48 45 31 5f 4d 49  {.#if PCACHE1_MI
8b30: 47 48 54 5f 55 53 45 5f 47 52 4f 55 50 5f 4d 55  GHT_USE_GROUP_MU
8b40: 54 45 58 20 7c 7c 20 64 65 66 69 6e 65 64 28 53  TEX || defined(S
8b50: 51 4c 49 54 45 5f 44 45 42 55 47 29 0a 20 20 50  QLITE_DEBUG).  P
8b60: 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d  Cache1 *pCache =
8b70: 20 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 23   (PCache1 *)p;.#
8b80: 65 6e 64 69 66 0a 0a 20 20 61 73 73 65 72 74 28  endif..  assert(
8b90: 20 6f 66 66 73 65 74 6f 66 28 50 67 48 64 72 31   offsetof(PgHdr1
8ba0: 2c 70 61 67 65 29 3d 3d 30 20 29 3b 0a 20 20 61  ,page)==0 );.  a
8bb0: 73 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e 62  ssert( pCache->b
8bc0: 50 75 72 67 65 61 62 6c 65 20 7c 7c 20 63 72 65  Purgeable || cre
8bd0: 61 74 65 46 6c 61 67 21 3d 31 20 29 3b 0a 20 20  ateFlag!=1 );.  
8be0: 61 73 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e  assert( pCache->
8bf0: 62 50 75 72 67 65 61 62 6c 65 20 7c 7c 20 70 43  bPurgeable || pC
8c00: 61 63 68 65 2d 3e 6e 4d 69 6e 3d 3d 30 20 29 3b  ache->nMin==0 );
8c10: 0a 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68  .  assert( pCach
8c20: 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 3d 3d 30  e->bPurgeable==0
8c30: 20 7c 7c 20 70 43 61 63 68 65 2d 3e 6e 4d 69 6e   || pCache->nMin
8c40: 3d 3d 31 30 20 29 3b 0a 20 20 61 73 73 65 72 74  ==10 );.  assert
8c50: 28 20 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 3d 3d  ( pCache->nMin==
8c60: 30 20 7c 7c 20 70 43 61 63 68 65 2d 3e 62 50 75  0 || pCache->bPu
8c70: 72 67 65 61 62 6c 65 20 29 3b 0a 20 20 61 73 73  rgeable );.  ass
8c80: 65 72 74 28 20 70 43 61 63 68 65 2d 3e 6e 48 61  ert( pCache->nHa
8c90: 73 68 3e 30 20 29 3b 0a 23 69 66 20 50 43 41 43  sh>0 );.#if PCAC
8ca0: 48 45 31 5f 4d 49 47 48 54 5f 55 53 45 5f 47 52  HE1_MIGHT_USE_GR
8cb0: 4f 55 50 5f 4d 55 54 45 58 0a 20 20 69 66 28 20  OUP_MUTEX.  if( 
8cc0: 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 2d 3e  pCache->pGroup->
8cd0: 6d 75 74 65 78 20 29 7b 0a 20 20 20 20 72 65 74  mutex ){.    ret
8ce0: 75 72 6e 20 28 73 71 6c 69 74 65 33 5f 70 63 61  urn (sqlite3_pca
8cf0: 63 68 65 5f 70 61 67 65 2a 29 70 63 61 63 68 65  che_page*)pcache
8d00: 31 46 65 74 63 68 57 69 74 68 4d 75 74 65 78 28  1FetchWithMutex(
8d10: 70 2c 20 69 4b 65 79 2c 20 63 72 65 61 74 65 46  p, iKey, createF
8d20: 6c 61 67 29 3b 0a 20 20 7d 65 6c 73 65 0a 23 65  lag);.  }else.#e
8d30: 6e 64 69 66 0a 20 20 7b 0a 20 20 20 20 72 65 74  ndif.  {.    ret
8d40: 75 72 6e 20 28 73 71 6c 69 74 65 33 5f 70 63 61  urn (sqlite3_pca
8d50: 63 68 65 5f 70 61 67 65 2a 29 70 63 61 63 68 65  che_page*)pcache
8d60: 31 46 65 74 63 68 4e 6f 4d 75 74 65 78 28 70 2c  1FetchNoMutex(p,
8d70: 20 69 4b 65 79 2c 20 63 72 65 61 74 65 46 6c 61   iKey, createFla
8d80: 67 29 3b 0a 20 20 7d 0a 7d 0a 0a 0a 2f 2a 0a 2a  g);.  }.}.../*.*
8d90: 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  * Implementation
8da0: 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f   of the sqlite3_
8db0: 70 63 61 63 68 65 2e 78 55 6e 70 69 6e 20 6d 65  pcache.xUnpin me
8dc0: 74 68 6f 64 2e 0a 2a 2a 0a 2a 2a 20 4d 61 72 6b  thod..**.** Mark
8dd0: 20 61 20 70 61 67 65 20 61 73 20 75 6e 70 69 6e   a page as unpin
8de0: 6e 65 64 20 28 65 6c 69 67 69 62 6c 65 20 66 6f  ned (eligible fo
8df0: 72 20 61 73 79 6e 63 68 72 6f 6e 6f 75 73 20 72  r asynchronous r
8e00: 65 63 79 63 6c 69 6e 67 29 2e 0a 2a 2f 0a 73 74  ecycling)..*/.st
8e10: 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65  atic void pcache
8e20: 31 55 6e 70 69 6e 28 0a 20 20 73 71 6c 69 74 65  1Unpin(.  sqlite
8e30: 33 5f 70 63 61 63 68 65 20 2a 70 2c 20 0a 20 20  3_pcache *p, .  
8e40: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 5f 70  sqlite3_pcache_p
8e50: 61 67 65 20 2a 70 50 67 2c 20 0a 20 20 69 6e 74  age *pPg, .  int
8e60: 20 72 65 75 73 65 55 6e 6c 69 6b 65 6c 79 0a 29   reuseUnlikely.)
8e70: 7b 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43 61  {.  PCache1 *pCa
8e80: 63 68 65 20 3d 20 28 50 43 61 63 68 65 31 20 2a  che = (PCache1 *
8e90: 29 70 3b 0a 20 20 50 67 48 64 72 31 20 2a 70 50  )p;.  PgHdr1 *pP
8ea0: 61 67 65 20 3d 20 28 50 67 48 64 72 31 20 2a 29  age = (PgHdr1 *)
8eb0: 70 50 67 3b 0a 20 20 50 47 72 6f 75 70 20 2a 70  pPg;.  PGroup *p
8ec0: 47 72 6f 75 70 20 3d 20 70 43 61 63 68 65 2d 3e  Group = pCache->
8ed0: 70 47 72 6f 75 70 3b 0a 20 0a 20 20 61 73 73 65  pGroup;. .  asse
8ee0: 72 74 28 20 70 50 61 67 65 2d 3e 70 43 61 63 68  rt( pPage->pCach
8ef0: 65 3d 3d 70 43 61 63 68 65 20 29 3b 0a 20 20 70  e==pCache );.  p
8f00: 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78  cache1EnterMutex
8f10: 28 70 47 72 6f 75 70 29 3b 0a 0a 20 20 2f 2a 20  (pGroup);..  /* 
8f20: 49 74 20 69 73 20 61 6e 20 65 72 72 6f 72 20 74  It is an error t
8f30: 6f 20 63 61 6c 6c 20 74 68 69 73 20 66 75 6e 63  o call this func
8f40: 74 69 6f 6e 20 69 66 20 74 68 65 20 70 61 67 65  tion if the page
8f50: 20 69 73 20 61 6c 72 65 61 64 79 20 0a 20 20 2a   is already .  *
8f60: 2a 20 70 61 72 74 20 6f 66 20 74 68 65 20 50 47  * part of the PG
8f70: 72 6f 75 70 20 4c 52 55 20 6c 69 73 74 2e 0a 20  roup LRU list.. 
8f80: 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 50   */.  assert( pP
8f90: 61 67 65 2d 3e 70 4c 72 75 50 72 65 76 3d 3d 30  age->pLruPrev==0
8fa0: 20 26 26 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e   && pPage->pLruN
8fb0: 65 78 74 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65  ext==0 );.  asse
8fc0: 72 74 28 20 50 41 47 45 5f 49 53 5f 50 49 4e 4e  rt( PAGE_IS_PINN
8fd0: 45 44 28 70 50 61 67 65 29 20 29 3b 0a 0a 20 20  ED(pPage) );..  
8fe0: 69 66 28 20 72 65 75 73 65 55 6e 6c 69 6b 65 6c  if( reuseUnlikel
8ff0: 79 20 7c 7c 20 70 47 72 6f 75 70 2d 3e 6e 50 75  y || pGroup->nPu
9000: 72 67 65 61 62 6c 65 3e 70 47 72 6f 75 70 2d 3e  rgeable>pGroup->
9010: 6e 4d 61 78 50 61 67 65 20 29 7b 0a 20 20 20 20  nMaxPage ){.    
9020: 70 63 61 63 68 65 31 52 65 6d 6f 76 65 46 72 6f  pcache1RemoveFro
9030: 6d 48 61 73 68 28 70 50 61 67 65 2c 20 31 29 3b  mHash(pPage, 1);
9040: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 2f 2a  .  }else{.    /*
9050: 20 41 64 64 20 74 68 65 20 70 61 67 65 20 74 6f   Add the page to
9060: 20 74 68 65 20 50 47 72 6f 75 70 20 4c 52 55 20   the PGroup LRU 
9070: 6c 69 73 74 2e 20 2a 2f 0a 20 20 20 20 50 67 48  list. */.    PgH
9080: 64 72 31 20 2a 2a 70 70 46 69 72 73 74 20 3d 20  dr1 **ppFirst = 
9090: 26 70 47 72 6f 75 70 2d 3e 6c 72 75 2e 70 4c 72  &pGroup->lru.pLr
90a0: 75 4e 65 78 74 3b 0a 20 20 20 20 70 50 61 67 65  uNext;.    pPage
90b0: 2d 3e 70 4c 72 75 50 72 65 76 20 3d 20 26 70 47  ->pLruPrev = &pG
90c0: 72 6f 75 70 2d 3e 6c 72 75 3b 0a 20 20 20 20 28  roup->lru;.    (
90d0: 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 20  pPage->pLruNext 
90e0: 3d 20 2a 70 70 46 69 72 73 74 29 2d 3e 70 4c 72  = *ppFirst)->pLr
90f0: 75 50 72 65 76 20 3d 20 70 50 61 67 65 3b 0a 20  uPrev = pPage;. 
9100: 20 20 20 2a 70 70 46 69 72 73 74 20 3d 20 70 50     *ppFirst = pP
9110: 61 67 65 3b 0a 20 20 20 20 70 43 61 63 68 65 2d  age;.    pCache-
9120: 3e 6e 52 65 63 79 63 6c 61 62 6c 65 2b 2b 3b 0a  >nRecyclable++;.
9130: 20 20 7d 0a 0a 20 20 70 63 61 63 68 65 31 4c 65    }..  pcache1Le
9140: 61 76 65 4d 75 74 65 78 28 70 43 61 63 68 65 2d  aveMutex(pCache-
9150: 3e 70 47 72 6f 75 70 29 3b 0a 7d 0a 0a 2f 2a 0a  >pGroup);.}../*.
9160: 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  ** Implementatio
9170: 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33  n of the sqlite3
9180: 5f 70 63 61 63 68 65 2e 78 52 65 6b 65 79 20 6d  _pcache.xRekey m
9190: 65 74 68 6f 64 2e 20 0a 2a 2f 0a 73 74 61 74 69  ethod. .*/.stati
91a0: 63 20 76 6f 69 64 20 70 63 61 63 68 65 31 52 65  c void pcache1Re
91b0: 6b 65 79 28 0a 20 20 73 71 6c 69 74 65 33 5f 70  key(.  sqlite3_p
91c0: 63 61 63 68 65 20 2a 70 2c 0a 20 20 73 71 6c 69  cache *p,.  sqli
91d0: 74 65 33 5f 70 63 61 63 68 65 5f 70 61 67 65 20  te3_pcache_page 
91e0: 2a 70 50 67 2c 0a 20 20 75 6e 73 69 67 6e 65 64  *pPg,.  unsigned
91f0: 20 69 6e 74 20 69 4f 6c 64 2c 0a 20 20 75 6e 73   int iOld,.  uns
9200: 69 67 6e 65 64 20 69 6e 74 20 69 4e 65 77 0a 29  igned int iNew.)
9210: 7b 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43 61  {.  PCache1 *pCa
9220: 63 68 65 20 3d 20 28 50 43 61 63 68 65 31 20 2a  che = (PCache1 *
9230: 29 70 3b 0a 20 20 50 67 48 64 72 31 20 2a 70 50  )p;.  PgHdr1 *pP
9240: 61 67 65 20 3d 20 28 50 67 48 64 72 31 20 2a 29  age = (PgHdr1 *)
9250: 70 50 67 3b 0a 20 20 50 67 48 64 72 31 20 2a 2a  pPg;.  PgHdr1 **
9260: 70 70 3b 0a 20 20 75 6e 73 69 67 6e 65 64 20 69  pp;.  unsigned i
9270: 6e 74 20 68 3b 20 0a 20 20 61 73 73 65 72 74 28  nt h; .  assert(
9280: 20 70 50 61 67 65 2d 3e 69 4b 65 79 3d 3d 69 4f   pPage->iKey==iO
9290: 6c 64 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  ld );.  assert( 
92a0: 70 50 61 67 65 2d 3e 70 43 61 63 68 65 3d 3d 70  pPage->pCache==p
92b0: 43 61 63 68 65 20 29 3b 0a 0a 20 20 70 63 61 63  Cache );..  pcac
92c0: 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70 43  he1EnterMutex(pC
92d0: 61 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 0a  ache->pGroup);..
92e0: 20 20 68 20 3d 20 69 4f 6c 64 25 70 43 61 63 68    h = iOld%pCach
92f0: 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 70 70 20 3d  e->nHash;.  pp =
9300: 20 26 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68   &pCache->apHash
9310: 5b 68 5d 3b 0a 20 20 77 68 69 6c 65 28 20 28 2a  [h];.  while( (*
9320: 70 70 29 21 3d 70 50 61 67 65 20 29 7b 0a 20 20  pp)!=pPage ){.  
9330: 20 20 70 70 20 3d 20 26 28 2a 70 70 29 2d 3e 70    pp = &(*pp)->p
9340: 4e 65 78 74 3b 0a 20 20 7d 0a 20 20 2a 70 70 20  Next;.  }.  *pp 
9350: 3d 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 3b 0a  = pPage->pNext;.
9360: 0a 20 20 68 20 3d 20 69 4e 65 77 25 70 43 61 63  .  h = iNew%pCac
9370: 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 70 50 61  he->nHash;.  pPa
9380: 67 65 2d 3e 69 4b 65 79 20 3d 20 69 4e 65 77 3b  ge->iKey = iNew;
9390: 0a 20 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 20  .  pPage->pNext 
93a0: 3d 20 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68  = pCache->apHash
93b0: 5b 68 5d 3b 0a 20 20 70 43 61 63 68 65 2d 3e 61  [h];.  pCache->a
93c0: 70 48 61 73 68 5b 68 5d 20 3d 20 70 50 61 67 65  pHash[h] = pPage
93d0: 3b 0a 20 20 69 66 28 20 69 4e 65 77 3e 70 43 61  ;.  if( iNew>pCa
93e0: 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 29 7b 0a  che->iMaxKey ){.
93f0: 20 20 20 20 70 43 61 63 68 65 2d 3e 69 4d 61 78      pCache->iMax
9400: 4b 65 79 20 3d 20 69 4e 65 77 3b 0a 20 20 7d 0a  Key = iNew;.  }.
9410: 0a 20 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d  .  pcache1LeaveM
9420: 75 74 65 78 28 70 43 61 63 68 65 2d 3e 70 47 72  utex(pCache->pGr
9430: 6f 75 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49  oup);.}../*.** I
9440: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66  mplementation of
9450: 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61   the sqlite3_pca
9460: 63 68 65 2e 78 54 72 75 6e 63 61 74 65 20 6d 65  che.xTruncate me
9470: 74 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20 44 69 73  thod. .**.** Dis
9480: 63 61 72 64 20 61 6c 6c 20 75 6e 70 69 6e 6e 65  card all unpinne
9490: 64 20 70 61 67 65 73 20 69 6e 20 74 68 65 20 63  d pages in the c
94a0: 61 63 68 65 20 77 69 74 68 20 61 20 70 61 67 65  ache with a page
94b0: 20 6e 75 6d 62 65 72 20 65 71 75 61 6c 20 74 6f   number equal to
94c0: 0a 2a 2a 20 6f 72 20 67 72 65 61 74 65 72 20 74  .** or greater t
94d0: 68 61 6e 20 70 61 72 61 6d 65 74 65 72 20 69 4c  han parameter iL
94e0: 69 6d 69 74 2e 20 41 6e 79 20 70 69 6e 6e 65 64  imit. Any pinned
94f0: 20 70 61 67 65 73 20 77 69 74 68 20 61 20 70 61   pages with a pa
9500: 67 65 20 6e 75 6d 62 65 72 0a 2a 2a 20 65 71 75  ge number.** equ
9510: 61 6c 20 74 6f 20 6f 72 20 67 72 65 61 74 65 72  al to or greater
9520: 20 74 68 61 6e 20 69 4c 69 6d 69 74 20 61 72 65   than iLimit are
9530: 20 69 6d 70 6c 69 63 69 74 6c 79 20 75 6e 70 69   implicitly unpi
9540: 6e 6e 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  nned..*/.static 
9550: 76 6f 69 64 20 70 63 61 63 68 65 31 54 72 75 6e  void pcache1Trun
9560: 63 61 74 65 28 73 71 6c 69 74 65 33 5f 70 63 61  cate(sqlite3_pca
9570: 63 68 65 20 2a 70 2c 20 75 6e 73 69 67 6e 65 64  che *p, unsigned
9580: 20 69 6e 74 20 69 4c 69 6d 69 74 29 7b 0a 20 20   int iLimit){.  
9590: 50 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 20  PCache1 *pCache 
95a0: 3d 20 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a  = (PCache1 *)p;.
95b0: 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75    pcache1EnterMu
95c0: 74 65 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f  tex(pCache->pGro
95d0: 75 70 29 3b 0a 20 20 69 66 28 20 69 4c 69 6d 69  up);.  if( iLimi
95e0: 74 3c 3d 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b  t<=pCache->iMaxK
95f0: 65 79 20 29 7b 0a 20 20 20 20 70 63 61 63 68 65  ey ){.    pcache
9600: 31 54 72 75 6e 63 61 74 65 55 6e 73 61 66 65 28  1TruncateUnsafe(
9610: 70 43 61 63 68 65 2c 20 69 4c 69 6d 69 74 29 3b  pCache, iLimit);
9620: 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 69 4d 61  .    pCache->iMa
9630: 78 4b 65 79 20 3d 20 69 4c 69 6d 69 74 2d 31 3b  xKey = iLimit-1;
9640: 0a 20 20 7d 0a 20 20 70 63 61 63 68 65 31 4c 65  .  }.  pcache1Le
9650: 61 76 65 4d 75 74 65 78 28 70 43 61 63 68 65 2d  aveMutex(pCache-
9660: 3e 70 47 72 6f 75 70 29 3b 0a 7d 0a 0a 2f 2a 0a  >pGroup);.}../*.
9670: 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  ** Implementatio
9680: 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33  n of the sqlite3
9690: 5f 70 63 61 63 68 65 2e 78 44 65 73 74 72 6f 79  _pcache.xDestroy
96a0: 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20   method. .**.** 
96b0: 44 65 73 74 72 6f 79 20 61 20 63 61 63 68 65 20  Destroy a cache 
96c0: 61 6c 6c 6f 63 61 74 65 64 20 75 73 69 6e 67 20  allocated using 
96d0: 70 63 61 63 68 65 31 43 72 65 61 74 65 28 29 2e  pcache1Create().
96e0: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
96f0: 70 63 61 63 68 65 31 44 65 73 74 72 6f 79 28 73  pcache1Destroy(s
9700: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70  qlite3_pcache *p
9710: 29 7b 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43  ){.  PCache1 *pC
9720: 61 63 68 65 20 3d 20 28 50 43 61 63 68 65 31 20  ache = (PCache1 
9730: 2a 29 70 3b 0a 20 20 50 47 72 6f 75 70 20 2a 70  *)p;.  PGroup *p
9740: 47 72 6f 75 70 20 3d 20 70 43 61 63 68 65 2d 3e  Group = pCache->
9750: 70 47 72 6f 75 70 3b 0a 20 20 61 73 73 65 72 74  pGroup;.  assert
9760: 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65  ( pCache->bPurge
9770: 61 62 6c 65 20 7c 7c 20 28 70 43 61 63 68 65 2d  able || (pCache-
9780: 3e 6e 4d 61 78 3d 3d 30 20 26 26 20 70 43 61 63  >nMax==0 && pCac
9790: 68 65 2d 3e 6e 4d 69 6e 3d 3d 30 29 20 29 3b 0a  he->nMin==0) );.
97a0: 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75    pcache1EnterMu
97b0: 74 65 78 28 70 47 72 6f 75 70 29 3b 0a 20 20 69  tex(pGroup);.  i
97c0: 66 28 20 70 43 61 63 68 65 2d 3e 6e 50 61 67 65  f( pCache->nPage
97d0: 20 29 20 70 63 61 63 68 65 31 54 72 75 6e 63 61   ) pcache1Trunca
97e0: 74 65 55 6e 73 61 66 65 28 70 43 61 63 68 65 2c  teUnsafe(pCache,
97f0: 20 30 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70   0);.  assert( p
9800: 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65 20  Group->nMaxPage 
9810: 3e 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 20  >= pCache->nMax 
9820: 29 3b 0a 20 20 70 47 72 6f 75 70 2d 3e 6e 4d 61  );.  pGroup->nMa
9830: 78 50 61 67 65 20 2d 3d 20 70 43 61 63 68 65 2d  xPage -= pCache-
9840: 3e 6e 4d 61 78 3b 0a 20 20 61 73 73 65 72 74 28  >nMax;.  assert(
9850: 20 70 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67   pGroup->nMinPag
9860: 65 20 3e 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 69  e >= pCache->nMi
9870: 6e 20 29 3b 0a 20 20 70 47 72 6f 75 70 2d 3e 6e  n );.  pGroup->n
9880: 4d 69 6e 50 61 67 65 20 2d 3d 20 70 43 61 63 68  MinPage -= pCach
9890: 65 2d 3e 6e 4d 69 6e 3b 0a 20 20 70 47 72 6f 75  e->nMin;.  pGrou
98a0: 70 2d 3e 6d 78 50 69 6e 6e 65 64 20 3d 20 70 47  p->mxPinned = pG
98b0: 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65 20 2b  roup->nMaxPage +
98c0: 20 31 30 20 2d 20 70 47 72 6f 75 70 2d 3e 6e 4d   10 - pGroup->nM
98d0: 69 6e 50 61 67 65 3b 0a 20 20 70 63 61 63 68 65  inPage;.  pcache
98e0: 31 45 6e 66 6f 72 63 65 4d 61 78 50 61 67 65 28  1EnforceMaxPage(
98f0: 70 43 61 63 68 65 29 3b 0a 20 20 70 63 61 63 68  pCache);.  pcach
9900: 65 31 4c 65 61 76 65 4d 75 74 65 78 28 70 47 72  e1LeaveMutex(pGr
9910: 6f 75 70 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f  oup);.  sqlite3_
9920: 66 72 65 65 28 70 43 61 63 68 65 2d 3e 70 42 75  free(pCache->pBu
9930: 6c 6b 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66  lk);.  sqlite3_f
9940: 72 65 65 28 70 43 61 63 68 65 2d 3e 61 70 48 61  ree(pCache->apHa
9950: 73 68 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66  sh);.  sqlite3_f
9960: 72 65 65 28 70 43 61 63 68 65 29 3b 0a 7d 0a 0a  ree(pCache);.}..
9970: 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  /*.** This funct
9980: 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 64 75  ion is called du
9990: 72 69 6e 67 20 69 6e 69 74 69 61 6c 69 7a 61 74  ring initializat
99a0: 69 6f 6e 20 28 73 71 6c 69 74 65 33 5f 69 6e 69  ion (sqlite3_ini
99b0: 74 69 61 6c 69 7a 65 28 29 29 20 74 6f 0a 2a 2a  tialize()) to.**
99c0: 20 69 6e 73 74 61 6c 6c 20 74 68 65 20 64 65 66   install the def
99d0: 61 75 6c 74 20 70 6c 75 67 67 61 62 6c 65 20 63  ault pluggable c
99e0: 61 63 68 65 20 6d 6f 64 75 6c 65 2c 20 61 73 73  ache module, ass
99f0: 75 6d 69 6e 67 20 74 68 65 20 75 73 65 72 20 68  uming the user h
9a00: 61 73 20 6e 6f 74 0a 2a 2a 20 61 6c 72 65 61 64  as not.** alread
9a10: 79 20 70 72 6f 76 69 64 65 64 20 61 6e 20 61 6c  y provided an al
9a20: 74 65 72 6e 61 74 69 76 65 2e 0a 2a 2f 0a 76 6f  ternative..*/.vo
9a30: 69 64 20 73 71 6c 69 74 65 33 50 43 61 63 68 65  id sqlite3PCache
9a40: 53 65 74 44 65 66 61 75 6c 74 28 76 6f 69 64 29  SetDefault(void)
9a50: 7b 0a 20 20 73 74 61 74 69 63 20 63 6f 6e 73 74  {.  static const
9a60: 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 5f   sqlite3_pcache_
9a70: 6d 65 74 68 6f 64 73 32 20 64 65 66 61 75 6c 74  methods2 default
9a80: 4d 65 74 68 6f 64 73 20 3d 20 7b 0a 20 20 20 20  Methods = {.    
9a90: 31 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  1,              
9aa0: 20 20 20 20 20 20 20 20 20 2f 2a 20 69 56 65 72           /* iVer
9ab0: 73 69 6f 6e 20 2a 2f 0a 20 20 20 20 30 2c 20 20  sion */.    0,  
9ac0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9ad0: 20 20 20 20 20 2f 2a 20 70 41 72 67 20 2a 2f 0a       /* pArg */.
9ae0: 20 20 20 20 70 63 61 63 68 65 31 49 6e 69 74 2c      pcache1Init,
9af0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
9b00: 78 49 6e 69 74 20 2a 2f 0a 20 20 20 20 70 63 61  xInit */.    pca
9b10: 63 68 65 31 53 68 75 74 64 6f 77 6e 2c 20 20 20  che1Shutdown,   
9b20: 20 20 20 20 20 20 2f 2a 20 78 53 68 75 74 64 6f        /* xShutdo
9b30: 77 6e 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65  wn */.    pcache
9b40: 31 43 72 65 61 74 65 2c 20 20 20 20 20 20 20 20  1Create,        
9b50: 20 20 20 2f 2a 20 78 43 72 65 61 74 65 20 2a 2f     /* xCreate */
9b60: 0a 20 20 20 20 70 63 61 63 68 65 31 43 61 63 68  .    pcache1Cach
9b70: 65 73 69 7a 65 2c 20 20 20 20 20 20 20 20 2f 2a  esize,        /*
9b80: 20 78 43 61 63 68 65 73 69 7a 65 20 2a 2f 0a 20   xCachesize */. 
9b90: 20 20 20 70 63 61 63 68 65 31 50 61 67 65 63 6f     pcache1Pageco
9ba0: 75 6e 74 2c 20 20 20 20 20 20 20 20 2f 2a 20 78  unt,        /* x
9bb0: 50 61 67 65 63 6f 75 6e 74 20 2a 2f 0a 20 20 20  Pagecount */.   
9bc0: 20 70 63 61 63 68 65 31 46 65 74 63 68 2c 20 20   pcache1Fetch,  
9bd0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 46 65            /* xFe
9be0: 74 63 68 20 2a 2f 0a 20 20 20 20 70 63 61 63 68  tch */.    pcach
9bf0: 65 31 55 6e 70 69 6e 2c 20 20 20 20 20 20 20 20  e1Unpin,        
9c00: 20 20 20 20 2f 2a 20 78 55 6e 70 69 6e 20 2a 2f      /* xUnpin */
9c10: 0a 20 20 20 20 70 63 61 63 68 65 31 52 65 6b 65  .    pcache1Reke
9c20: 79 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  y,            /*
9c30: 20 78 52 65 6b 65 79 20 2a 2f 0a 20 20 20 20 70   xRekey */.    p
9c40: 63 61 63 68 65 31 54 72 75 6e 63 61 74 65 2c 20  cache1Truncate, 
9c50: 20 20 20 20 20 20 20 20 2f 2a 20 78 54 72 75 6e          /* xTrun
9c60: 63 61 74 65 20 2a 2f 0a 20 20 20 20 70 63 61 63  cate */.    pcac
9c70: 68 65 31 44 65 73 74 72 6f 79 2c 20 20 20 20 20  he1Destroy,     
9c80: 20 20 20 20 20 2f 2a 20 78 44 65 73 74 72 6f 79       /* xDestroy
9c90: 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31 53   */.    pcache1S
9ca0: 68 72 69 6e 6b 20 20 20 20 20 20 20 20 20 20 20  hrink           
9cb0: 20 2f 2a 20 78 53 68 72 69 6e 6b 20 2a 2f 0a 20   /* xShrink */. 
9cc0: 20 7d 3b 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f   };.  sqlite3_co
9cd0: 6e 66 69 67 28 53 51 4c 49 54 45 5f 43 4f 4e 46  nfig(SQLITE_CONF
9ce0: 49 47 5f 50 43 41 43 48 45 32 2c 20 26 64 65 66  IG_PCACHE2, &def
9cf0: 61 75 6c 74 4d 65 74 68 6f 64 73 29 3b 0a 7d 0a  aultMethods);.}.
9d00: 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68  ./*.** Return th
9d10: 65 20 73 69 7a 65 20 6f 66 20 74 68 65 20 68 65  e size of the he
9d20: 61 64 65 72 20 6f 6e 20 65 61 63 68 20 70 61 67  ader on each pag
9d30: 65 20 6f 66 20 74 68 69 73 20 50 43 41 43 48 45  e of this PCACHE
9d40: 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 2e   implementation.
9d50: 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 48  .*/.int sqlite3H
9d60: 65 61 64 65 72 53 69 7a 65 50 63 61 63 68 65 31  eaderSizePcache1
9d70: 28 76 6f 69 64 29 7b 20 72 65 74 75 72 6e 20 52  (void){ return R
9d80: 4f 55 4e 44 38 28 73 69 7a 65 6f 66 28 50 67 48  OUND8(sizeof(PgH
9d90: 64 72 31 29 29 3b 20 7d 0a 0a 2f 2a 0a 2a 2a 20  dr1)); }../*.** 
9da0: 52 65 74 75 72 6e 20 74 68 65 20 67 6c 6f 62 61  Return the globa
9db0: 6c 20 6d 75 74 65 78 20 75 73 65 64 20 62 79 20  l mutex used by 
9dc0: 74 68 69 73 20 50 43 41 43 48 45 20 69 6d 70 6c  this PCACHE impl
9dd0: 65 6d 65 6e 74 61 74 69 6f 6e 2e 20 20 54 68 65  ementation.  The
9de0: 0a 2a 2a 20 73 71 6c 69 74 65 33 5f 73 74 61 74  .** sqlite3_stat
9df0: 75 73 28 29 20 72 6f 75 74 69 6e 65 20 6e 65 65  us() routine nee
9e00: 64 73 20 61 63 63 65 73 73 20 74 6f 20 74 68 69  ds access to thi
9e10: 73 20 6d 75 74 65 78 2e 0a 2a 2f 0a 73 71 6c 69  s mutex..*/.sqli
9e20: 74 65 33 5f 6d 75 74 65 78 20 2a 73 71 6c 69 74  te3_mutex *sqlit
9e30: 65 33 50 63 61 63 68 65 31 4d 75 74 65 78 28 76  e3Pcache1Mutex(v
9e40: 6f 69 64 29 7b 0a 20 20 72 65 74 75 72 6e 20 70  oid){.  return p
9e50: 63 61 63 68 65 31 2e 6d 75 74 65 78 3b 0a 7d 0a  cache1.mutex;.}.
9e60: 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 45  .#ifdef SQLITE_E
9e70: 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e  NABLE_MEMORY_MAN
9e80: 41 47 45 4d 45 4e 54 0a 2f 2a 0a 2a 2a 20 54 68  AGEMENT./*.** Th
9e90: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63  is function is c
9ea0: 61 6c 6c 65 64 20 74 6f 20 66 72 65 65 20 73 75  alled to free su
9eb0: 70 65 72 66 6c 75 6f 75 73 20 64 79 6e 61 6d 69  perfluous dynami
9ec0: 63 61 6c 6c 79 20 61 6c 6c 6f 63 61 74 65 64 20  cally allocated 
9ed0: 6d 65 6d 6f 72 79 0a 2a 2a 20 68 65 6c 64 20 62  memory.** held b
9ee0: 79 20 74 68 65 20 70 61 67 65 72 20 73 79 73 74  y the pager syst
9ef0: 65 6d 2e 20 4d 65 6d 6f 72 79 20 69 6e 20 75 73  em. Memory in us
9f00: 65 20 62 79 20 61 6e 79 20 53 51 4c 69 74 65 20  e by any SQLite 
9f10: 70 61 67 65 72 20 61 6c 6c 6f 63 61 74 65 64 0a  pager allocated.
9f20: 2a 2a 20 62 79 20 74 68 65 20 63 75 72 72 65 6e  ** by the curren
9f30: 74 20 74 68 72 65 61 64 20 6d 61 79 20 62 65 20  t thread may be 
9f40: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 29 65 64  sqlite3_free()ed
9f50: 2e 0a 2a 2a 0a 2a 2a 20 6e 52 65 71 20 69 73 20  ..**.** nReq is 
9f60: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 62 79  the number of by
9f70: 74 65 73 20 6f 66 20 6d 65 6d 6f 72 79 20 72 65  tes of memory re
9f80: 71 75 69 72 65 64 2e 20 4f 6e 63 65 20 74 68 69  quired. Once thi
9f90: 73 20 6d 75 63 68 20 68 61 73 0a 2a 2a 20 62 65  s much has.** be
9fa0: 65 6e 20 72 65 6c 65 61 73 65 64 2c 20 74 68 65  en released, the
9fb0: 20 66 75 6e 63 74 69 6f 6e 20 72 65 74 75 72 6e   function return
9fc0: 73 2e 20 54 68 65 20 72 65 74 75 72 6e 20 76 61  s. The return va
9fd0: 6c 75 65 20 69 73 20 74 68 65 20 74 6f 74 61 6c  lue is the total
9fe0: 20 6e 75 6d 62 65 72 20 0a 2a 2a 20 6f 66 20 62   number .** of b
9ff0: 79 74 65 73 20 6f 66 20 6d 65 6d 6f 72 79 20 72  ytes of memory r
a000: 65 6c 65 61 73 65 64 2e 0a 2a 2f 0a 69 6e 74 20  eleased..*/.int 
a010: 73 71 6c 69 74 65 33 50 63 61 63 68 65 52 65 6c  sqlite3PcacheRel
a020: 65 61 73 65 4d 65 6d 6f 72 79 28 69 6e 74 20 6e  easeMemory(int n
a030: 52 65 71 29 7b 0a 20 20 69 6e 74 20 6e 46 72 65  Req){.  int nFre
a040: 65 20 3d 20 30 3b 0a 20 20 61 73 73 65 72 74 28  e = 0;.  assert(
a050: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6e   sqlite3_mutex_n
a060: 6f 74 68 65 6c 64 28 70 63 61 63 68 65 31 2e 67  otheld(pcache1.g
a070: 72 70 2e 6d 75 74 65 78 29 20 29 3b 0a 20 20 61  rp.mutex) );.  a
a080: 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d  ssert( sqlite3_m
a090: 75 74 65 78 5f 6e 6f 74 68 65 6c 64 28 70 63 61  utex_notheld(pca
a0a0: 63 68 65 31 2e 6d 75 74 65 78 29 20 29 3b 0a 20  che1.mutex) );. 
a0b0: 20 69 66 28 20 73 71 6c 69 74 65 33 47 6c 6f 62   if( sqlite3Glob
a0c0: 61 6c 43 6f 6e 66 69 67 2e 70 50 61 67 65 3d 3d  alConfig.pPage==
a0d0: 30 20 29 7b 0a 20 20 20 20 50 67 48 64 72 31 20  0 ){.    PgHdr1 
a0e0: 2a 70 3b 0a 20 20 20 20 70 63 61 63 68 65 31 45  *p;.    pcache1E
a0f0: 6e 74 65 72 4d 75 74 65 78 28 26 70 63 61 63 68  nterMutex(&pcach
a100: 65 31 2e 67 72 70 29 3b 0a 20 20 20 20 77 68 69  e1.grp);.    whi
a110: 6c 65 28 20 28 6e 52 65 71 3c 30 20 7c 7c 20 6e  le( (nReq<0 || n
a120: 46 72 65 65 3c 6e 52 65 71 29 0a 20 20 20 20 20  Free<nReq).     
a130: 20 20 26 26 20 20 28 70 3d 70 63 61 63 68 65 31    &&  (p=pcache1
a140: 2e 67 72 70 2e 6c 72 75 2e 70 4c 72 75 50 72 65  .grp.lru.pLruPre
a150: 76 29 21 3d 30 0a 20 20 20 20 20 20 20 26 26 20  v)!=0.       && 
a160: 20 70 2d 3e 69 73 41 6e 63 68 6f 72 3d 3d 30 0a   p->isAnchor==0.
a170: 20 20 20 20 29 7b 0a 20 20 20 20 20 20 6e 46 72      ){.      nFr
a180: 65 65 20 2b 3d 20 70 63 61 63 68 65 31 4d 65 6d  ee += pcache1Mem
a190: 53 69 7a 65 28 70 2d 3e 70 61 67 65 2e 70 42 75  Size(p->page.pBu
a1a0: 66 29 3b 0a 23 69 66 64 65 66 20 53 51 4c 49 54  f);.#ifdef SQLIT
a1b0: 45 5f 50 43 41 43 48 45 5f 53 45 50 41 52 41 54  E_PCACHE_SEPARAT
a1c0: 45 5f 48 45 41 44 45 52 0a 20 20 20 20 20 20 6e  E_HEADER.      n
a1d0: 46 72 65 65 20 2b 3d 20 73 71 6c 69 74 65 33 4d  Free += sqlite3M
a1e0: 65 6d 53 69 7a 65 28 70 29 3b 0a 23 65 6e 64 69  emSize(p);.#endi
a1f0: 66 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20  f.      assert( 
a200: 50 41 47 45 5f 49 53 5f 55 4e 50 49 4e 4e 45 44  PAGE_IS_UNPINNED
a210: 28 70 29 20 29 3b 0a 20 20 20 20 20 20 70 63 61  (p) );.      pca
a220: 63 68 65 31 50 69 6e 50 61 67 65 28 70 29 3b 0a  che1PinPage(p);.
a230: 20 20 20 20 20 20 70 63 61 63 68 65 31 52 65 6d        pcache1Rem
a240: 6f 76 65 46 72 6f 6d 48 61 73 68 28 70 2c 20 31  oveFromHash(p, 1
a250: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 63 61  );.    }.    pca
a260: 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 26  che1LeaveMutex(&
a270: 70 63 61 63 68 65 31 2e 67 72 70 29 3b 0a 20 20  pcache1.grp);.  
a280: 7d 0a 20 20 72 65 74 75 72 6e 20 6e 46 72 65 65  }.  return nFree
a290: 3b 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51  ;.}.#endif /* SQ
a2a0: 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f  LITE_ENABLE_MEMO
a2b0: 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 20 2a 2f  RY_MANAGEMENT */
a2c0: 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f  ..#ifdef SQLITE_
a2d0: 54 45 53 54 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  TEST./*.** This 
a2e0: 66 75 6e 63 74 69 6f 6e 20 69 73 20 75 73 65 64  function is used
a2f0: 20 62 79 20 74 65 73 74 20 70 72 6f 63 65 64 75   by test procedu
a300: 72 65 73 20 74 6f 20 69 6e 73 70 65 63 74 20 74  res to inspect t
a310: 68 65 20 69 6e 74 65 72 6e 61 6c 20 73 74 61 74  he internal stat
a320: 65 0a 2a 2a 20 6f 66 20 74 68 65 20 67 6c 6f 62  e.** of the glob
a330: 61 6c 20 63 61 63 68 65 2e 0a 2a 2f 0a 76 6f 69  al cache..*/.voi
a340: 64 20 73 71 6c 69 74 65 33 50 63 61 63 68 65 53  d sqlite3PcacheS
a350: 74 61 74 73 28 0a 20 20 69 6e 74 20 2a 70 6e 43  tats(.  int *pnC
a360: 75 72 72 65 6e 74 2c 20 20 20 20 20 20 2f 2a 20  urrent,      /* 
a370: 4f 55 54 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65  OUT: Total numbe
a380: 72 20 6f 66 20 70 61 67 65 73 20 63 61 63 68 65  r of pages cache
a390: 64 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 4d 61  d */.  int *pnMa
a3a0: 78 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f  x,          /* O
a3b0: 55 54 3a 20 47 6c 6f 62 61 6c 20 6d 61 78 69 6d  UT: Global maxim
a3c0: 75 6d 20 63 61 63 68 65 20 73 69 7a 65 20 2a 2f  um cache size */
a3d0: 0a 20 20 69 6e 74 20 2a 70 6e 4d 69 6e 2c 20 20  .  int *pnMin,  
a3e0: 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
a3f0: 53 75 6d 20 6f 66 20 50 43 61 63 68 65 31 2e 6e  Sum of PCache1.n
a400: 4d 69 6e 20 66 6f 72 20 70 75 72 67 65 61 62 6c  Min for purgeabl
a410: 65 20 63 61 63 68 65 73 20 2a 2f 0a 20 20 69 6e  e caches */.  in
a420: 74 20 2a 70 6e 52 65 63 79 63 6c 61 62 6c 65 20  t *pnRecyclable 
a430: 20 20 20 2f 2a 20 4f 55 54 3a 20 54 6f 74 61 6c     /* OUT: Total
a440: 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73   number of pages
a450: 20 61 76 61 69 6c 61 62 6c 65 20 66 6f 72 20 72   available for r
a460: 65 63 79 63 6c 69 6e 67 20 2a 2f 0a 29 7b 0a 20  ecycling */.){. 
a470: 20 50 67 48 64 72 31 20 2a 70 3b 0a 20 20 69 6e   PgHdr1 *p;.  in
a480: 74 20 6e 52 65 63 79 63 6c 61 62 6c 65 20 3d 20  t nRecyclable = 
a490: 30 3b 0a 20 20 66 6f 72 28 70 3d 70 63 61 63 68  0;.  for(p=pcach
a4a0: 65 31 2e 67 72 70 2e 6c 72 75 2e 70 4c 72 75 4e  e1.grp.lru.pLruN
a4b0: 65 78 74 3b 20 70 20 26 26 20 21 70 2d 3e 69 73  ext; p && !p->is
a4c0: 41 6e 63 68 6f 72 3b 20 70 3d 70 2d 3e 70 4c 72  Anchor; p=p->pLr
a4d0: 75 4e 65 78 74 29 7b 0a 20 20 20 20 61 73 73 65  uNext){.    asse
a4e0: 72 74 28 20 50 41 47 45 5f 49 53 5f 55 4e 50 49  rt( PAGE_IS_UNPI
a4f0: 4e 4e 45 44 28 70 29 20 29 3b 0a 20 20 20 20 6e  NNED(p) );.    n
a500: 52 65 63 79 63 6c 61 62 6c 65 2b 2b 3b 0a 20 20  Recyclable++;.  
a510: 7d 0a 20 20 2a 70 6e 43 75 72 72 65 6e 74 20 3d  }.  *pnCurrent =
a520: 20 70 63 61 63 68 65 31 2e 67 72 70 2e 6e 50 75   pcache1.grp.nPu
a530: 72 67 65 61 62 6c 65 3b 0a 20 20 2a 70 6e 4d 61  rgeable;.  *pnMa
a540: 78 20 3d 20 28 69 6e 74 29 70 63 61 63 68 65 31  x = (int)pcache1
a550: 2e 67 72 70 2e 6e 4d 61 78 50 61 67 65 3b 0a 20  .grp.nMaxPage;. 
a560: 20 2a 70 6e 4d 69 6e 20 3d 20 28 69 6e 74 29 70   *pnMin = (int)p
a570: 63 61 63 68 65 31 2e 67 72 70 2e 6e 4d 69 6e 50  cache1.grp.nMinP
a580: 61 67 65 3b 0a 20 20 2a 70 6e 52 65 63 79 63 6c  age;.  *pnRecycl
a590: 61 62 6c 65 20 3d 20 6e 52 65 63 79 63 6c 61 62  able = nRecyclab
a5a0: 6c 65 3b 0a 7d 0a 23 65 6e 64 69 66 0a           le;.}.#endif.