/ Hex Artifact Content
Login

Artifact e7114d2e80331daafa6f87f54839ed0563e1273b835d809a911569407c12ebaf:


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 20 6f 6e 20 74 68 65 20 4c 52 55  is no on the LRU
1390: 20 6c 69 73 74 0a 2a 2f 0a 23 64 65 66 69 6e 65   list.*/.#define
13a0: 20 50 41 47 45 5f 49 53 5f 50 49 4e 4e 45 44 28   PAGE_IS_PINNED(
13b0: 70 29 20 20 20 20 28 28 70 29 2d 3e 70 4c 72 75  p)    ((p)->pLru
13c0: 4e 65 78 74 3d 3d 30 29 0a 23 64 65 66 69 6e 65  Next==0).#define
13d0: 20 50 41 47 45 5f 49 53 5f 55 4e 50 49 4e 4e 45   PAGE_IS_UNPINNE
13e0: 44 28 70 29 20 20 28 28 70 29 2d 3e 70 4c 72 75  D(p)  ((p)->pLru
13f0: 4e 65 78 74 21 3d 30 29 0a 0a 2f 2a 20 45 61 63  Next!=0)../* Eac
1400: 68 20 70 61 67 65 20 63 61 63 68 65 20 28 6f 72  h page cache (or
1410: 20 50 43 61 63 68 65 29 20 62 65 6c 6f 6e 67 73   PCache) belongs
1420: 20 74 6f 20 61 20 50 47 72 6f 75 70 2e 20 20 41   to a PGroup.  A
1430: 20 50 47 72 6f 75 70 20 69 73 20 61 20 73 65 74   PGroup is a set
1440: 20 0a 2a 2a 20 6f 66 20 6f 6e 65 20 6f 72 20 6d   .** of one or m
1450: 6f 72 65 20 50 43 61 63 68 65 73 20 74 68 61 74  ore PCaches that
1460: 20 61 72 65 20 61 62 6c 65 20 74 6f 20 72 65 63   are able to rec
1470: 79 63 6c 65 20 65 61 63 68 20 6f 74 68 65 72 27  ycle each other'
1480: 73 20 75 6e 70 69 6e 6e 65 64 0a 2a 2a 20 70 61  s unpinned.** pa
1490: 67 65 73 20 77 68 65 6e 20 74 68 65 79 20 61 72  ges when they ar
14a0: 65 20 75 6e 64 65 72 20 6d 65 6d 6f 72 79 20 70  e under memory p
14b0: 72 65 73 73 75 72 65 2e 20 20 41 20 50 47 72 6f  ressure.  A PGro
14c0: 75 70 20 69 73 20 61 6e 20 69 6e 73 74 61 6e 63  up is an instanc
14d0: 65 20 6f 66 0a 2a 2a 20 74 68 65 20 66 6f 6c 6c  e of.** the foll
14e0: 6f 77 69 6e 67 20 6f 62 6a 65 63 74 2e 0a 2a 2a  owing object..**
14f0: 0a 2a 2a 20 54 68 69 73 20 70 61 67 65 20 63 61  .** This page ca
1500: 63 68 65 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69  che implementati
1510: 6f 6e 20 77 6f 72 6b 73 20 69 6e 20 6f 6e 65 20  on works in one 
1520: 6f 66 20 74 77 6f 20 6d 6f 64 65 73 3a 0a 2a 2a  of two modes:.**
1530: 0a 2a 2a 20 20 20 28 31 29 20 20 45 76 65 72 79  .**   (1)  Every
1540: 20 50 43 61 63 68 65 20 69 73 20 74 68 65 20 73   PCache is the s
1550: 6f 6c 65 20 6d 65 6d 62 65 72 20 6f 66 20 69 74  ole member of it
1560: 73 20 6f 77 6e 20 50 47 72 6f 75 70 2e 20 20 54  s own PGroup.  T
1570: 68 65 72 65 20 69 73 0a 2a 2a 20 20 20 20 20 20  here is.**      
1580: 20 20 6f 6e 65 20 50 47 72 6f 75 70 20 70 65 72    one PGroup per
1590: 20 50 43 61 63 68 65 2e 0a 2a 2a 0a 2a 2a 20 20   PCache..**.**  
15a0: 20 28 32 29 20 20 54 68 65 72 65 20 69 73 20 61   (2)  There is a
15b0: 20 73 69 6e 67 6c 65 20 67 6c 6f 62 61 6c 20 50   single global P
15c0: 47 72 6f 75 70 20 74 68 61 74 20 61 6c 6c 20 50  Group that all P
15d0: 43 61 63 68 65 73 20 61 72 65 20 61 20 6d 65 6d  Caches are a mem
15e0: 62 65 72 0a 2a 2a 20 20 20 20 20 20 20 20 6f 66  ber.**        of
15f0: 2e 0a 2a 2a 0a 2a 2a 20 4d 6f 64 65 20 31 20 75  ..**.** Mode 1 u
1600: 73 65 73 20 6d 6f 72 65 20 6d 65 6d 6f 72 79 20  ses more memory 
1610: 28 73 69 6e 63 65 20 50 43 61 63 68 65 20 69 6e  (since PCache in
1620: 73 74 61 6e 63 65 73 20 61 72 65 20 6e 6f 74 20  stances are not 
1630: 61 62 6c 65 20 74 6f 20 72 6f 62 0a 2a 2a 20 75  able to rob.** u
1640: 6e 75 73 65 64 20 70 61 67 65 73 20 66 72 6f 6d  nused pages from
1650: 20 6f 74 68 65 72 20 50 43 61 63 68 65 73 29 20   other PCaches) 
1660: 62 75 74 20 69 74 20 61 6c 73 6f 20 6f 70 65 72  but it also oper
1670: 61 74 65 73 20 77 69 74 68 6f 75 74 20 61 20 6d  ates without a m
1680: 75 74 65 78 2c 0a 2a 2a 20 61 6e 64 20 69 73 20  utex,.** and is 
1690: 74 68 65 72 65 66 6f 72 65 20 6f 66 74 65 6e 20  therefore often 
16a0: 66 61 73 74 65 72 2e 20 20 4d 6f 64 65 20 32 20  faster.  Mode 2 
16b0: 72 65 71 75 69 72 65 73 20 61 20 6d 75 74 65 78  requires a mutex
16c0: 20 69 6e 20 6f 72 64 65 72 20 74 6f 20 62 65 0a   in order to be.
16d0: 2a 2a 20 74 68 72 65 61 64 73 61 66 65 2c 20 62  ** threadsafe, b
16e0: 75 74 20 72 65 63 79 63 6c 65 73 20 70 61 67 65  ut recycles page
16f0: 73 20 6d 6f 72 65 20 65 66 66 69 63 69 65 6e 74  s more efficient
1700: 6c 79 2e 0a 2a 2a 0a 2a 2a 20 46 6f 72 20 6d 6f  ly..**.** For mo
1710: 64 65 20 28 31 29 2c 20 50 47 72 6f 75 70 2e 6d  de (1), PGroup.m
1720: 75 74 65 78 20 69 73 20 4e 55 4c 4c 2e 20 20 46  utex is NULL.  F
1730: 6f 72 20 6d 6f 64 65 20 28 32 29 20 74 68 65 72  or mode (2) ther
1740: 65 20 69 73 20 6f 6e 6c 79 20 61 20 73 69 6e 67  e is only a sing
1750: 6c 65 0a 2a 2a 20 50 47 72 6f 75 70 20 77 68 69  le.** PGroup whi
1760: 63 68 20 69 73 20 74 68 65 20 70 63 61 63 68 65  ch is the pcache
1770: 31 2e 67 72 70 20 67 6c 6f 62 61 6c 20 76 61 72  1.grp global var
1780: 69 61 62 6c 65 20 61 6e 64 20 69 74 73 20 6d 75  iable and its mu
1790: 74 65 78 20 69 73 0a 2a 2a 20 53 51 4c 49 54 45  tex is.** SQLITE
17a0: 5f 4d 55 54 45 58 5f 53 54 41 54 49 43 5f 4c 52  _MUTEX_STATIC_LR
17b0: 55 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 50 47 72  U..*/.struct PGr
17c0: 6f 75 70 20 7b 0a 20 20 73 71 6c 69 74 65 33 5f  oup {.  sqlite3_
17d0: 6d 75 74 65 78 20 2a 6d 75 74 65 78 3b 20 20 20  mutex *mutex;   
17e0: 20 20 20 20 20 20 20 2f 2a 20 4d 55 54 45 58 5f         /* MUTEX_
17f0: 53 54 41 54 49 43 5f 4c 52 55 20 6f 72 20 4e 55  STATIC_LRU or NU
1800: 4c 4c 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64  LL */.  unsigned
1810: 20 69 6e 74 20 6e 4d 61 78 50 61 67 65 3b 20 20   int nMaxPage;  
1820: 20 20 20 20 20 20 20 2f 2a 20 53 75 6d 20 6f 66         /* Sum of
1830: 20 6e 4d 61 78 20 66 6f 72 20 70 75 72 67 65 61   nMax for purgea
1840: 62 6c 65 20 63 61 63 68 65 73 20 2a 2f 0a 20 20  ble caches */.  
1850: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 4d 69  unsigned int nMi
1860: 6e 50 61 67 65 3b 20 20 20 20 20 20 20 20 20 2f  nPage;         /
1870: 2a 20 53 75 6d 20 6f 66 20 6e 4d 69 6e 20 66 6f  * Sum of nMin fo
1880: 72 20 70 75 72 67 65 61 62 6c 65 20 63 61 63 68  r purgeable cach
1890: 65 73 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64  es */.  unsigned
18a0: 20 69 6e 74 20 6d 78 50 69 6e 6e 65 64 3b 20 20   int mxPinned;  
18b0: 20 20 20 20 20 20 20 2f 2a 20 6e 4d 61 78 70 61         /* nMaxpa
18c0: 67 65 20 2b 20 31 30 20 2d 20 6e 4d 69 6e 50 61  ge + 10 - nMinPa
18d0: 67 65 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64  ge */.  unsigned
18e0: 20 69 6e 74 20 6e 43 75 72 72 65 6e 74 50 61 67   int nCurrentPag
18f0: 65 3b 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72  e;     /* Number
1900: 20 6f 66 20 70 75 72 67 65 61 62 6c 65 20 70 61   of purgeable pa
1910: 67 65 73 20 61 6c 6c 6f 63 61 74 65 64 20 2a 2f  ges allocated */
1920: 0a 20 20 50 67 48 64 72 31 20 6c 72 75 3b 20 20  .  PgHdr1 lru;  
1930: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1940: 20 20 2f 2a 20 54 68 65 20 62 65 67 69 6e 6e 69    /* The beginni
1950: 6e 67 20 61 6e 64 20 65 6e 64 20 6f 66 20 74 68  ng and end of th
1960: 65 20 4c 52 55 20 6c 69 73 74 20 2a 2f 0a 7d 3b  e LRU list */.};
1970: 0a 0a 2f 2a 20 45 61 63 68 20 70 61 67 65 20 63  ../* Each page c
1980: 61 63 68 65 20 69 73 20 61 6e 20 69 6e 73 74 61  ache is an insta
1990: 6e 63 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f  nce of the follo
19a0: 77 69 6e 67 20 6f 62 6a 65 63 74 2e 20 20 45 76  wing object.  Ev
19b0: 65 72 79 0a 2a 2a 20 6f 70 65 6e 20 64 61 74 61  ery.** open data
19c0: 62 61 73 65 20 66 69 6c 65 20 28 69 6e 63 6c 75  base file (inclu
19d0: 64 69 6e 67 20 65 61 63 68 20 69 6e 2d 6d 65 6d  ding each in-mem
19e0: 6f 72 79 20 64 61 74 61 62 61 73 65 20 61 6e 64  ory database and
19f0: 20 65 61 63 68 0a 2a 2a 20 74 65 6d 70 6f 72 61   each.** tempora
1a00: 72 79 20 6f 72 20 74 72 61 6e 73 69 65 6e 74 20  ry or transient 
1a10: 64 61 74 61 62 61 73 65 29 20 68 61 73 20 61 20  database) has a 
1a20: 73 69 6e 67 6c 65 20 70 61 67 65 20 63 61 63 68  single page cach
1a30: 65 20 77 68 69 63 68 0a 2a 2a 20 69 73 20 61 6e  e which.** is an
1a40: 20 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 69   instance of thi
1a50: 73 20 6f 62 6a 65 63 74 2e 0a 2a 2a 0a 2a 2a 20  s object..**.** 
1a60: 50 6f 69 6e 74 65 72 73 20 74 6f 20 73 74 72 75  Pointers to stru
1a70: 63 74 75 72 65 73 20 6f 66 20 74 68 69 73 20 74  ctures of this t
1a80: 79 70 65 20 61 72 65 20 63 61 73 74 20 61 6e 64  ype are cast and
1a90: 20 72 65 74 75 72 6e 65 64 20 61 73 20 0a 2a 2a   returned as .**
1aa0: 20 6f 70 61 71 75 65 20 73 71 6c 69 74 65 33 5f   opaque sqlite3_
1ab0: 70 63 61 63 68 65 2a 20 68 61 6e 64 6c 65 73 2e  pcache* handles.
1ac0: 0a 2a 2f 0a 73 74 72 75 63 74 20 50 43 61 63 68  .*/.struct PCach
1ad0: 65 31 20 7b 0a 20 20 2f 2a 20 43 61 63 68 65 20  e1 {.  /* Cache 
1ae0: 63 6f 6e 66 69 67 75 72 61 74 69 6f 6e 20 70 61  configuration pa
1af0: 72 61 6d 65 74 65 72 73 2e 20 50 61 67 65 20 73  rameters. Page s
1b00: 69 7a 65 20 28 73 7a 50 61 67 65 29 20 61 6e 64  ize (szPage) and
1b10: 20 74 68 65 20 70 75 72 67 65 61 62 6c 65 0a 20   the purgeable. 
1b20: 20 2a 2a 20 66 6c 61 67 20 28 62 50 75 72 67 65   ** flag (bPurge
1b30: 61 62 6c 65 29 20 61 72 65 20 73 65 74 20 77 68  able) are set wh
1b40: 65 6e 20 74 68 65 20 63 61 63 68 65 20 69 73 20  en the cache is 
1b50: 63 72 65 61 74 65 64 2e 20 6e 4d 61 78 20 6d 61  created. nMax ma
1b60: 79 20 62 65 20 0a 20 20 2a 2a 20 6d 6f 64 69 66  y be .  ** modif
1b70: 69 65 64 20 61 74 20 61 6e 79 20 74 69 6d 65 20  ied at any time 
1b80: 62 79 20 61 20 63 61 6c 6c 20 74 6f 20 74 68 65  by a call to the
1b90: 20 70 63 61 63 68 65 31 43 61 63 68 65 73 69 7a   pcache1Cachesiz
1ba0: 65 28 29 20 6d 65 74 68 6f 64 2e 0a 20 20 2a 2a  e() method..  **
1bb0: 20 54 68 65 20 50 47 72 6f 75 70 20 6d 75 74 65   The PGroup mute
1bc0: 78 20 6d 75 73 74 20 62 65 20 68 65 6c 64 20 77  x must be held w
1bd0: 68 65 6e 20 61 63 63 65 73 73 69 6e 67 20 6e 4d  hen accessing nM
1be0: 61 78 2e 0a 20 20 2a 2f 0a 20 20 50 47 72 6f 75  ax..  */.  PGrou
1bf0: 70 20 2a 70 47 72 6f 75 70 3b 20 20 20 20 20 20  p *pGroup;      
1c00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1c10: 2a 20 50 47 72 6f 75 70 20 74 68 69 73 20 63 61  * PGroup this ca
1c20: 63 68 65 20 62 65 6c 6f 6e 67 73 20 74 6f 20 2a  che belongs to *
1c30: 2f 0a 20 20 69 6e 74 20 73 7a 50 61 67 65 3b 20  /.  int szPage; 
1c40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c50: 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
1c60: 6f 66 20 64 61 74 61 62 61 73 65 20 63 6f 6e 74  of database cont
1c70: 65 6e 74 20 73 65 63 74 69 6f 6e 20 2a 2f 0a 20  ent section */. 
1c80: 20 69 6e 74 20 73 7a 45 78 74 72 61 3b 20 20 20   int szExtra;   
1c90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1ca0: 20 20 20 20 20 2f 2a 20 73 69 7a 65 6f 66 28 4d       /* sizeof(M
1cb0: 65 6d 50 61 67 65 29 2b 73 69 7a 65 6f 66 28 50  emPage)+sizeof(P
1cc0: 67 48 64 72 29 20 2a 2f 0a 20 20 69 6e 74 20 73  gHdr) */.  int s
1cd0: 7a 41 6c 6c 6f 63 3b 20 20 20 20 20 20 20 20 20  zAlloc;         
1ce0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1cf0: 2a 20 54 6f 74 61 6c 20 73 69 7a 65 20 6f 66 20  * Total size of 
1d00: 6f 6e 65 20 70 63 61 63 68 65 20 6c 69 6e 65 20  one pcache line 
1d10: 2a 2f 0a 20 20 69 6e 74 20 62 50 75 72 67 65 61  */.  int bPurgea
1d20: 62 6c 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  ble;            
1d30: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
1d40: 20 69 66 20 63 61 63 68 65 20 69 73 20 70 75 72   if cache is pur
1d50: 67 65 61 62 6c 65 20 2a 2f 0a 20 20 75 6e 73 69  geable */.  unsi
1d60: 67 6e 65 64 20 69 6e 74 20 6e 4d 69 6e 3b 20 20  gned int nMin;  
1d70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d80: 2f 2a 20 4d 69 6e 69 6d 75 6d 20 6e 75 6d 62 65  /* Minimum numbe
1d90: 72 20 6f 66 20 70 61 67 65 73 20 72 65 73 65 72  r of pages reser
1da0: 76 65 64 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65  ved */.  unsigne
1db0: 64 20 69 6e 74 20 6e 4d 61 78 3b 20 20 20 20 20  d int nMax;     
1dc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1dd0: 43 6f 6e 66 69 67 75 72 65 64 20 22 63 61 63 68  Configured "cach
1de0: 65 5f 73 69 7a 65 22 20 76 61 6c 75 65 20 2a 2f  e_size" value */
1df0: 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  .  unsigned int 
1e00: 6e 39 30 70 63 74 3b 20 20 20 20 20 20 20 20 20  n90pct;         
1e10: 20 20 20 20 20 20 20 2f 2a 20 6e 4d 61 78 2a 39         /* nMax*9
1e20: 2f 31 30 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65  /10 */.  unsigne
1e30: 64 20 69 6e 74 20 69 4d 61 78 4b 65 79 3b 20 20  d int iMaxKey;  
1e40: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1e50: 4c 61 72 67 65 73 74 20 6b 65 79 20 73 65 65 6e  Largest key seen
1e60: 20 73 69 6e 63 65 20 78 54 72 75 6e 63 61 74 65   since xTruncate
1e70: 28 29 20 2a 2f 0a 0a 20 20 2f 2a 20 48 61 73 68  () */..  /* Hash
1e80: 20 74 61 62 6c 65 20 6f 66 20 61 6c 6c 20 70 61   table of all pa
1e90: 67 65 73 2e 20 54 68 65 20 66 6f 6c 6c 6f 77 69  ges. The followi
1ea0: 6e 67 20 76 61 72 69 61 62 6c 65 73 20 6d 61 79  ng variables may
1eb0: 20 6f 6e 6c 79 20 62 65 20 61 63 63 65 73 73 65   only be accesse
1ec0: 64 0a 20 20 2a 2a 20 77 68 65 6e 20 74 68 65 20  d.  ** when the 
1ed0: 61 63 63 65 73 73 6f 72 20 69 73 20 68 6f 6c 64  accessor is hold
1ee0: 69 6e 67 20 74 68 65 20 50 47 72 6f 75 70 20 6d  ing the PGroup m
1ef0: 75 74 65 78 2e 0a 20 20 2a 2f 0a 20 20 75 6e 73  utex..  */.  uns
1f00: 69 67 6e 65 64 20 69 6e 74 20 6e 52 65 63 79 63  igned int nRecyc
1f10: 6c 61 62 6c 65 3b 20 20 20 20 20 20 20 20 20 20  lable;          
1f20: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 70 61   /* Number of pa
1f30: 67 65 73 20 69 6e 20 74 68 65 20 4c 52 55 20 6c  ges in the LRU l
1f40: 69 73 74 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65  ist */.  unsigne
1f50: 64 20 69 6e 74 20 6e 50 61 67 65 3b 20 20 20 20  d int nPage;    
1f60: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1f70: 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20  Total number of 
1f80: 70 61 67 65 73 20 69 6e 20 61 70 48 61 73 68 20  pages in apHash 
1f90: 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e  */.  unsigned in
1fa0: 74 20 6e 48 61 73 68 3b 20 20 20 20 20 20 20 20  t nHash;        
1fb0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
1fc0: 65 72 20 6f 66 20 73 6c 6f 74 73 20 69 6e 20 61  er of slots in a
1fd0: 70 48 61 73 68 5b 5d 20 2a 2f 0a 20 20 50 67 48  pHash[] */.  PgH
1fe0: 64 72 31 20 2a 2a 61 70 48 61 73 68 3b 20 20 20  dr1 **apHash;   
1ff0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2000: 20 2f 2a 20 48 61 73 68 20 74 61 62 6c 65 20 66   /* Hash table f
2010: 6f 72 20 66 61 73 74 20 6c 6f 6f 6b 75 70 20 62  or fast lookup b
2020: 79 20 6b 65 79 20 2a 2f 0a 20 20 50 67 48 64 72  y key */.  PgHdr
2030: 31 20 2a 70 46 72 65 65 3b 20 20 20 20 20 20 20  1 *pFree;       
2040: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
2050: 2a 20 4c 69 73 74 20 6f 66 20 75 6e 75 73 65 64  * List of unused
2060: 20 70 63 61 63 68 65 2d 6c 6f 63 61 6c 20 70 61   pcache-local pa
2070: 67 65 73 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70  ges */.  void *p
2080: 42 75 6c 6b 3b 20 20 20 20 20 20 20 20 20 20 20  Bulk;           
2090: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
20a0: 42 75 6c 6b 20 6d 65 6d 6f 72 79 20 75 73 65 64  Bulk memory used
20b0: 20 62 79 20 70 63 61 63 68 65 2d 6c 6f 63 61 6c   by pcache-local
20c0: 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 46 72   */.};../*.** Fr
20d0: 65 65 20 73 6c 6f 74 73 20 69 6e 20 74 68 65 20  ee slots in the 
20e0: 61 6c 6c 6f 63 61 74 6f 72 20 75 73 65 64 20 74  allocator used t
20f0: 6f 20 64 69 76 69 64 65 20 75 70 20 74 68 65 20  o divide up the 
2100: 67 6c 6f 62 61 6c 20 70 61 67 65 20 63 61 63 68  global page cach
2110: 65 0a 2a 2a 20 62 75 66 66 65 72 20 70 72 6f 76  e.** buffer prov
2120: 69 64 65 64 20 75 73 69 6e 67 20 74 68 65 20 53  ided using the S
2130: 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47  QLITE_CONFIG_PAG
2140: 45 43 41 43 48 45 20 6d 65 63 68 61 6e 69 73 6d  ECACHE mechanism
2150: 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 50 67 46 72  ..*/.struct PgFr
2160: 65 65 73 6c 6f 74 20 7b 0a 20 20 50 67 46 72 65  eeslot {.  PgFre
2170: 65 73 6c 6f 74 20 2a 70 4e 65 78 74 3b 20 20 2f  eslot *pNext;  /
2180: 2a 20 4e 65 78 74 20 66 72 65 65 20 73 6c 6f 74  * Next free slot
2190: 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 47 6c   */.};../*.** Gl
21a0: 6f 62 61 6c 20 64 61 74 61 20 75 73 65 64 20 62  obal data used b
21b0: 79 20 74 68 69 73 20 63 61 63 68 65 2e 0a 2a 2f  y this cache..*/
21c0: 0a 73 74 61 74 69 63 20 53 51 4c 49 54 45 5f 57  .static SQLITE_W
21d0: 53 44 20 73 74 72 75 63 74 20 50 43 61 63 68 65  SD struct PCache
21e0: 47 6c 6f 62 61 6c 20 7b 0a 20 20 50 47 72 6f 75  Global {.  PGrou
21f0: 70 20 67 72 70 3b 20 20 20 20 20 20 20 20 20 20  p grp;          
2200: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65            /* The
2210: 20 67 6c 6f 62 61 6c 20 50 47 72 6f 75 70 20 66   global PGroup f
2220: 6f 72 20 6d 6f 64 65 20 28 32 29 20 2a 2f 0a 0a  or mode (2) */..
2230: 20 20 2f 2a 20 56 61 72 69 61 62 6c 65 73 20 72    /* Variables r
2240: 65 6c 61 74 65 64 20 74 6f 20 53 51 4c 49 54 45  elated to SQLITE
2250: 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48  _CONFIG_PAGECACH
2260: 45 20 73 65 74 74 69 6e 67 73 2e 20 20 54 68 65  E settings.  The
2270: 0a 20 20 2a 2a 20 73 7a 53 6c 6f 74 2c 20 6e 53  .  ** szSlot, nS
2280: 6c 6f 74 2c 20 70 53 74 61 72 74 2c 20 70 45 6e  lot, pStart, pEn
2290: 64 2c 20 6e 52 65 73 65 72 76 65 2c 20 61 6e 64  d, nReserve, and
22a0: 20 69 73 49 6e 69 74 20 76 61 6c 75 65 73 20 61   isInit values a
22b0: 72 65 20 61 6c 6c 0a 20 20 2a 2a 20 66 69 78 65  re all.  ** fixe
22c0: 64 20 61 74 20 73 71 6c 69 74 65 33 5f 69 6e 69  d at sqlite3_ini
22d0: 74 69 61 6c 69 7a 65 28 29 20 74 69 6d 65 20 61  tialize() time a
22e0: 6e 64 20 64 6f 20 6e 6f 74 20 72 65 71 75 69 72  nd do not requir
22f0: 65 20 6d 75 74 65 78 20 70 72 6f 74 65 63 74 69  e mutex protecti
2300: 6f 6e 2e 0a 20 20 2a 2a 20 54 68 65 20 6e 46 72  on..  ** The nFr
2310: 65 65 53 6c 6f 74 20 61 6e 64 20 70 46 72 65 65  eeSlot and pFree
2320: 20 76 61 6c 75 65 73 20 64 6f 20 72 65 71 75 69   values do requi
2330: 72 65 20 6d 75 74 65 78 20 70 72 6f 74 65 63 74  re mutex protect
2340: 69 6f 6e 2e 0a 20 20 2a 2f 0a 20 20 69 6e 74 20  ion..  */.  int 
2350: 69 73 49 6e 69 74 3b 20 20 20 20 20 20 20 20 20  isInit;         
2360: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72             /* Tr
2370: 75 65 20 69 66 20 69 6e 69 74 69 61 6c 69 7a 65  ue if initialize
2380: 64 20 2a 2f 0a 20 20 69 6e 74 20 73 65 70 61 72  d */.  int separ
2390: 61 74 65 43 61 63 68 65 3b 20 20 20 20 20 20 20  ateCache;       
23a0: 20 20 20 20 20 20 2f 2a 20 55 73 65 20 61 20 6e        /* Use a n
23b0: 65 77 20 50 47 72 6f 75 70 20 66 6f 72 20 65 61  ew PGroup for ea
23c0: 63 68 20 50 43 61 63 68 65 20 2a 2f 0a 20 20 69  ch PCache */.  i
23d0: 6e 74 20 6e 49 6e 69 74 50 61 67 65 3b 20 20 20  nt nInitPage;   
23e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
23f0: 20 49 6e 69 74 69 61 6c 20 62 75 6c 6b 20 61 6c   Initial bulk al
2400: 6c 6f 63 61 74 69 6f 6e 20 73 69 7a 65 20 2a 2f  location size */
2410: 20 20 20 0a 20 20 69 6e 74 20 73 7a 53 6c 6f 74     .  int szSlot
2420: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
2430: 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
2440: 65 61 63 68 20 66 72 65 65 20 73 6c 6f 74 20 2a  each free slot *
2450: 2f 0a 20 20 69 6e 74 20 6e 53 6c 6f 74 3b 20 20  /.  int nSlot;  
2460: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2470: 20 20 20 2f 2a 20 54 68 65 20 6e 75 6d 62 65 72     /* The number
2480: 20 6f 66 20 70 63 61 63 68 65 20 73 6c 6f 74 73   of pcache slots
2490: 20 2a 2f 0a 20 20 69 6e 74 20 6e 52 65 73 65 72   */.  int nReser
24a0: 76 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ve;             
24b0: 20 20 20 20 20 2f 2a 20 54 72 79 20 74 6f 20 6b       /* Try to k
24c0: 65 65 70 20 6e 46 72 65 65 53 6c 6f 74 20 61 62  eep nFreeSlot ab
24d0: 6f 76 65 20 74 68 69 73 20 2a 2f 0a 20 20 76 6f  ove this */.  vo
24e0: 69 64 20 2a 70 53 74 61 72 74 2c 20 2a 70 45 6e  id *pStart, *pEn
24f0: 64 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  d;           /* 
2500: 42 6f 75 6e 64 73 20 6f 66 20 67 6c 6f 62 61 6c  Bounds of global
2510: 20 70 61 67 65 20 63 61 63 68 65 20 6d 65 6d 6f   page cache memo
2520: 72 79 20 2a 2f 0a 20 20 2f 2a 20 41 62 6f 76 65  ry */.  /* Above
2530: 20 72 65 71 75 69 72 65 73 20 6e 6f 20 6d 75 74   requires no mut
2540: 65 78 2e 20 20 55 73 65 20 6d 75 74 65 78 20 62  ex.  Use mutex b
2550: 65 6c 6f 77 20 66 6f 72 20 76 61 72 69 61 62 6c  elow for variabl
2560: 65 20 74 68 61 74 20 66 6f 6c 6c 6f 77 2e 20 2a  e that follow. *
2570: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65  /.  sqlite3_mute
2580: 78 20 2a 6d 75 74 65 78 3b 20 20 20 20 20 20 20  x *mutex;       
2590: 20 20 20 2f 2a 20 4d 75 74 65 78 20 66 6f 72 20     /* Mutex for 
25a0: 61 63 63 65 73 73 69 6e 67 20 74 68 65 20 66 6f  accessing the fo
25b0: 6c 6c 6f 77 69 6e 67 3a 20 2a 2f 0a 20 20 50 67  llowing: */.  Pg
25c0: 46 72 65 65 73 6c 6f 74 20 2a 70 46 72 65 65 3b  Freeslot *pFree;
25d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
25e0: 46 72 65 65 20 70 61 67 65 20 62 6c 6f 63 6b 73  Free page blocks
25f0: 20 2a 2f 0a 20 20 69 6e 74 20 6e 46 72 65 65 53   */.  int nFreeS
2600: 6c 6f 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  lot;            
2610: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
2620: 66 20 75 6e 75 73 65 64 20 70 63 61 63 68 65 20  f unused pcache 
2630: 73 6c 6f 74 73 20 2a 2f 0a 20 20 2f 2a 20 54 68  slots */.  /* Th
2640: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 76 61 6c 75  e following valu
2650: 65 20 72 65 71 75 69 72 65 73 20 61 20 6d 75 74  e requires a mut
2660: 65 78 20 74 6f 20 63 68 61 6e 67 65 2e 20 20 57  ex to change.  W
2670: 65 20 73 6b 69 70 20 74 68 65 20 6d 75 74 65 78  e skip the mutex
2680: 20 6f 6e 0a 20 20 2a 2a 20 72 65 61 64 69 6e 67   on.  ** reading
2690: 20 62 65 63 61 75 73 65 20 28 31 29 20 6d 6f 73   because (1) mos
26a0: 74 20 70 6c 61 74 66 6f 72 6d 73 20 72 65 61 64  t platforms read
26b0: 20 61 20 33 32 2d 62 69 74 20 69 6e 74 65 67 65   a 32-bit intege
26c0: 72 20 61 74 6f 6d 69 63 61 6c 6c 79 20 61 6e 64  r atomically and
26d0: 0a 20 20 2a 2a 20 28 32 29 20 65 76 65 6e 20 69  .  ** (2) even i
26e0: 66 20 61 6e 20 69 6e 63 6f 72 72 65 63 74 20 76  f an incorrect v
26f0: 61 6c 75 65 20 69 73 20 72 65 61 64 2c 20 6e 6f  alue is read, no
2700: 20 67 72 65 61 74 20 68 61 72 6d 20 69 73 20 64   great harm is d
2710: 6f 6e 65 20 73 69 6e 63 65 20 74 68 69 73 0a 20  one since this. 
2720: 20 2a 2a 20 69 73 20 72 65 61 6c 6c 79 20 6a 75   ** is really ju
2730: 73 74 20 61 6e 20 6f 70 74 69 6d 69 7a 61 74 69  st an optimizati
2740: 6f 6e 2e 20 2a 2f 0a 20 20 69 6e 74 20 62 55 6e  on. */.  int bUn
2750: 64 65 72 50 72 65 73 73 75 72 65 3b 20 20 20 20  derPressure;    
2760: 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20          /* True 
2770: 69 66 20 6c 6f 77 20 6f 6e 20 50 41 47 45 43 41  if low on PAGECA
2780: 43 48 45 20 6d 65 6d 6f 72 79 20 2a 2f 0a 7d 20  CHE memory */.} 
2790: 70 63 61 63 68 65 31 5f 67 3b 0a 0a 2f 2a 0a 2a  pcache1_g;../*.*
27a0: 2a 20 41 6c 6c 20 63 6f 64 65 20 69 6e 20 74 68  * All code in th
27b0: 69 73 20 66 69 6c 65 20 73 68 6f 75 6c 64 20 61  is file should a
27c0: 63 63 65 73 73 20 74 68 65 20 67 6c 6f 62 61 6c  ccess the global
27d0: 20 73 74 72 75 63 74 75 72 65 20 61 62 6f 76 65   structure above
27e0: 20 76 69 61 20 74 68 65 0a 2a 2a 20 61 6c 69 61   via the.** alia
27f0: 73 20 22 70 63 61 63 68 65 31 22 2e 20 54 68 69  s "pcache1". Thi
2800: 73 20 65 6e 73 75 72 65 73 20 74 68 61 74 20 74  s ensures that t
2810: 68 65 20 57 53 44 20 65 6d 75 6c 61 74 69 6f 6e  he WSD emulation
2820: 20 69 73 20 75 73 65 64 20 77 68 65 6e 0a 2a 2a   is used when.**
2830: 20 63 6f 6d 70 69 6c 69 6e 67 20 66 6f 72 20 73   compiling for s
2840: 79 73 74 65 6d 73 20 74 68 61 74 20 64 6f 20 6e  ystems that do n
2850: 6f 74 20 73 75 70 70 6f 72 74 20 72 65 61 6c 20  ot support real 
2860: 57 53 44 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20  WSD..*/.#define 
2870: 70 63 61 63 68 65 31 20 28 47 4c 4f 42 41 4c 28  pcache1 (GLOBAL(
2880: 73 74 72 75 63 74 20 50 43 61 63 68 65 47 6c 6f  struct PCacheGlo
2890: 62 61 6c 2c 20 70 63 61 63 68 65 31 5f 67 29 29  bal, pcache1_g))
28a0: 0a 0a 2f 2a 0a 2a 2a 20 4d 61 63 72 6f 73 20 74  ../*.** Macros t
28b0: 6f 20 65 6e 74 65 72 20 61 6e 64 20 6c 65 61 76  o enter and leav
28c0: 65 20 74 68 65 20 50 43 61 63 68 65 20 4c 52 55  e the PCache LRU
28d0: 20 6d 75 74 65 78 2e 0a 2a 2f 0a 23 69 66 20 21   mutex..*/.#if !
28e0: 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 45  defined(SQLITE_E
28f0: 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e  NABLE_MEMORY_MAN
2900: 41 47 45 4d 45 4e 54 29 20 7c 7c 20 53 51 4c 49  AGEMENT) || SQLI
2910: 54 45 5f 54 48 52 45 41 44 53 41 46 45 3d 3d 30  TE_THREADSAFE==0
2920: 0a 23 20 64 65 66 69 6e 65 20 70 63 61 63 68 65  .# define pcache
2930: 31 45 6e 74 65 72 4d 75 74 65 78 28 58 29 20 20  1EnterMutex(X)  
2940: 61 73 73 65 72 74 28 28 58 29 2d 3e 6d 75 74 65  assert((X)->mute
2950: 78 3d 3d 30 29 0a 23 20 64 65 66 69 6e 65 20 70  x==0).# define p
2960: 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78  cache1LeaveMutex
2970: 28 58 29 20 20 61 73 73 65 72 74 28 28 58 29 2d  (X)  assert((X)-
2980: 3e 6d 75 74 65 78 3d 3d 30 29 0a 23 20 64 65 66  >mutex==0).# def
2990: 69 6e 65 20 50 43 41 43 48 45 31 5f 4d 49 47 48  ine PCACHE1_MIGH
29a0: 54 5f 55 53 45 5f 47 52 4f 55 50 5f 4d 55 54 45  T_USE_GROUP_MUTE
29b0: 58 20 30 0a 23 65 6c 73 65 0a 23 20 64 65 66 69  X 0.#else.# defi
29c0: 6e 65 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d  ne pcache1EnterM
29d0: 75 74 65 78 28 58 29 20 73 71 6c 69 74 65 33 5f  utex(X) sqlite3_
29e0: 6d 75 74 65 78 5f 65 6e 74 65 72 28 28 58 29 2d  mutex_enter((X)-
29f0: 3e 6d 75 74 65 78 29 0a 23 20 64 65 66 69 6e 65  >mutex).# define
2a00: 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74   pcache1LeaveMut
2a10: 65 78 28 58 29 20 73 71 6c 69 74 65 33 5f 6d 75  ex(X) sqlite3_mu
2a20: 74 65 78 5f 6c 65 61 76 65 28 28 58 29 2d 3e 6d  tex_leave((X)->m
2a30: 75 74 65 78 29 0a 23 20 64 65 66 69 6e 65 20 50  utex).# define P
2a40: 43 41 43 48 45 31 5f 4d 49 47 48 54 5f 55 53 45  CACHE1_MIGHT_USE
2a50: 5f 47 52 4f 55 50 5f 4d 55 54 45 58 20 31 0a 23  _GROUP_MUTEX 1.#
2a60: 65 6e 64 69 66 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a  endif../********
2a70: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2a80: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2a90: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2aa0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2ab0: 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 2a 2a 2a 2a 2a 2a  ******/./*******
2ac0: 2a 20 50 61 67 65 20 41 6c 6c 6f 63 61 74 69 6f  * Page Allocatio
2ad0: 6e 2f 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f  n/SQLITE_CONFIG_
2ae0: 50 43 41 43 48 45 20 52 65 6c 61 74 65 64 20 46  PCACHE Related F
2af0: 75 6e 63 74 69 6f 6e 73 20 2a 2a 2a 2a 2a 2a 2a  unctions *******
2b00: 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 0a 2f 2a 0a 2a 2a  *******/.../*.**
2b10: 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   This function i
2b20: 73 20 63 61 6c 6c 65 64 20 64 75 72 69 6e 67 20  s called during 
2b30: 69 6e 69 74 69 61 6c 69 7a 61 74 69 6f 6e 20 69  initialization i
2b40: 66 20 61 20 73 74 61 74 69 63 20 62 75 66 66 65  f a static buffe
2b50: 72 20 69 73 20 0a 2a 2a 20 73 75 70 70 6c 69 65  r is .** supplie
2b60: 64 20 74 6f 20 75 73 65 20 66 6f 72 20 74 68 65  d to use for the
2b70: 20 70 61 67 65 2d 63 61 63 68 65 20 62 79 20 70   page-cache by p
2b80: 61 73 73 69 6e 67 20 74 68 65 20 53 51 4c 49 54  assing the SQLIT
2b90: 45 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41 43  E_CONFIG_PAGECAC
2ba0: 48 45 0a 2a 2a 20 76 65 72 62 20 74 6f 20 73 71  HE.** verb to sq
2bb0: 6c 69 74 65 33 5f 63 6f 6e 66 69 67 28 29 2e 20  lite3_config(). 
2bc0: 50 61 72 61 6d 65 74 65 72 20 70 42 75 66 20 70  Parameter pBuf p
2bd0: 6f 69 6e 74 73 20 74 6f 20 61 6e 20 61 6c 6c 6f  oints to an allo
2be0: 63 61 74 69 6f 6e 20 6c 61 72 67 65 0a 2a 2a 20  cation large.** 
2bf0: 65 6e 6f 75 67 68 20 74 6f 20 63 6f 6e 74 61 69  enough to contai
2c00: 6e 20 27 6e 27 20 62 75 66 66 65 72 73 20 6f 66  n 'n' buffers of
2c10: 20 27 73 7a 27 20 62 79 74 65 73 20 65 61 63 68   'sz' bytes each
2c20: 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75  ..**.** This rou
2c30: 74 69 6e 65 20 69 73 20 63 61 6c 6c 65 64 20 66  tine is called f
2c40: 72 6f 6d 20 73 71 6c 69 74 65 33 5f 69 6e 69 74  rom sqlite3_init
2c50: 69 61 6c 69 7a 65 28 29 20 61 6e 64 20 73 6f 20  ialize() and so 
2c60: 69 74 20 69 73 20 67 75 61 72 61 6e 74 65 65 64  it is guaranteed
2c70: 0a 2a 2a 20 74 6f 20 62 65 20 73 65 72 69 61 6c  .** to be serial
2c80: 69 7a 65 64 20 61 6c 72 65 61 64 79 2e 20 20 54  ized already.  T
2c90: 68 65 72 65 20 69 73 20 6e 6f 20 6e 65 65 64 20  here is no need 
2ca0: 66 6f 72 20 66 75 72 74 68 65 72 20 6d 75 74 65  for further mute
2cb0: 78 69 6e 67 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71  xing..*/.void sq
2cc0: 6c 69 74 65 33 50 43 61 63 68 65 42 75 66 66 65  lite3PCacheBuffe
2cd0: 72 53 65 74 75 70 28 76 6f 69 64 20 2a 70 42 75  rSetup(void *pBu
2ce0: 66 2c 20 69 6e 74 20 73 7a 2c 20 69 6e 74 20 6e  f, int sz, int n
2cf0: 29 7b 0a 20 20 69 66 28 20 70 63 61 63 68 65 31  ){.  if( pcache1
2d00: 2e 69 73 49 6e 69 74 20 29 7b 0a 20 20 20 20 50  .isInit ){.    P
2d10: 67 46 72 65 65 73 6c 6f 74 20 2a 70 3b 0a 20 20  gFreeslot *p;.  
2d20: 20 20 69 66 28 20 70 42 75 66 3d 3d 30 20 29 20    if( pBuf==0 ) 
2d30: 73 7a 20 3d 20 6e 20 3d 20 30 3b 0a 20 20 20 20  sz = n = 0;.    
2d40: 73 7a 20 3d 20 52 4f 55 4e 44 44 4f 57 4e 38 28  sz = ROUNDDOWN8(
2d50: 73 7a 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31  sz);.    pcache1
2d60: 2e 73 7a 53 6c 6f 74 20 3d 20 6e 20 3f 20 73 7a  .szSlot = n ? sz
2d70: 20 3a 20 30 3b 0a 20 20 20 20 70 63 61 63 68 65   : 0;.    pcache
2d80: 31 2e 6e 53 6c 6f 74 20 3d 20 70 63 61 63 68 65  1.nSlot = pcache
2d90: 31 2e 6e 46 72 65 65 53 6c 6f 74 20 3d 20 6e 3b  1.nFreeSlot = n;
2da0: 0a 20 20 20 20 70 63 61 63 68 65 31 2e 6e 52 65  .    pcache1.nRe
2db0: 73 65 72 76 65 20 3d 20 6e 3e 39 30 20 3f 20 31  serve = n>90 ? 1
2dc0: 30 20 3a 20 28 6e 2f 31 30 20 2b 20 31 29 3b 0a  0 : (n/10 + 1);.
2dd0: 20 20 20 20 70 63 61 63 68 65 31 2e 70 53 74 61      pcache1.pSta
2de0: 72 74 20 3d 20 70 42 75 66 3b 0a 20 20 20 20 70  rt = pBuf;.    p
2df0: 63 61 63 68 65 31 2e 70 46 72 65 65 20 3d 20 30  cache1.pFree = 0
2e00: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 62 55  ;.    pcache1.bU
2e10: 6e 64 65 72 50 72 65 73 73 75 72 65 20 3d 20 30  nderPressure = 0
2e20: 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 6e 2d 2d  ;.    while( n--
2e30: 20 29 7b 0a 20 20 20 20 20 20 70 20 3d 20 28 50   ){.      p = (P
2e40: 67 46 72 65 65 73 6c 6f 74 2a 29 70 42 75 66 3b  gFreeslot*)pBuf;
2e50: 0a 20 20 20 20 20 20 70 2d 3e 70 4e 65 78 74 20  .      p->pNext 
2e60: 3d 20 70 63 61 63 68 65 31 2e 70 46 72 65 65 3b  = pcache1.pFree;
2e70: 0a 20 20 20 20 20 20 70 63 61 63 68 65 31 2e 70  .      pcache1.p
2e80: 46 72 65 65 20 3d 20 70 3b 0a 20 20 20 20 20 20  Free = p;.      
2e90: 70 42 75 66 20 3d 20 28 76 6f 69 64 2a 29 26 28  pBuf = (void*)&(
2ea0: 28 63 68 61 72 2a 29 70 42 75 66 29 5b 73 7a 5d  (char*)pBuf)[sz]
2eb0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 63 61 63  ;.    }.    pcac
2ec0: 68 65 31 2e 70 45 6e 64 20 3d 20 70 42 75 66 3b  he1.pEnd = pBuf;
2ed0: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 72  .  }.}../*.** Tr
2ee0: 79 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20  y to initialize 
2ef0: 74 68 65 20 70 43 61 63 68 65 2d 3e 70 46 72 65  the pCache->pFre
2f00: 65 20 61 6e 64 20 70 43 61 63 68 65 2d 3e 70 42  e and pCache->pB
2f10: 75 6c 6b 20 66 69 65 6c 64 73 2e 20 20 52 65 74  ulk fields.  Ret
2f20: 75 72 6e 0a 2a 2a 20 74 72 75 65 20 69 66 20 70  urn.** true if p
2f30: 43 61 63 68 65 2d 3e 70 46 72 65 65 20 65 6e 64  Cache->pFree end
2f40: 73 20 75 70 20 63 6f 6e 74 61 69 6e 69 6e 67 20  s up containing 
2f50: 6f 6e 65 20 6f 72 20 6d 6f 72 65 20 66 72 65 65  one or more free
2f60: 20 70 61 67 65 73 2e 0a 2a 2f 0a 73 74 61 74 69   pages..*/.stati
2f70: 63 20 69 6e 74 20 70 63 61 63 68 65 31 49 6e 69  c int pcache1Ini
2f80: 74 42 75 6c 6b 28 50 43 61 63 68 65 31 20 2a 70  tBulk(PCache1 *p
2f90: 43 61 63 68 65 29 7b 0a 20 20 69 36 34 20 73 7a  Cache){.  i64 sz
2fa0: 42 75 6c 6b 3b 0a 20 20 63 68 61 72 20 2a 7a 42  Bulk;.  char *zB
2fb0: 75 6c 6b 3b 0a 20 20 69 66 28 20 70 63 61 63 68  ulk;.  if( pcach
2fc0: 65 31 2e 6e 49 6e 69 74 50 61 67 65 3d 3d 30 20  e1.nInitPage==0 
2fd0: 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 2f 2a  ) return 0;.  /*
2fe0: 20 44 6f 20 6e 6f 74 20 62 6f 74 68 65 72 20 77   Do not bother w
2ff0: 69 74 68 20 61 20 62 75 6c 6b 20 61 6c 6c 6f 63  ith a bulk alloc
3000: 61 74 69 6f 6e 20 69 66 20 74 68 65 20 63 61 63  ation if the cac
3010: 68 65 20 73 69 7a 65 20 76 65 72 79 20 73 6d 61  he size very sma
3020: 6c 6c 20 2a 2f 0a 20 20 69 66 28 20 70 43 61 63  ll */.  if( pCac
3030: 68 65 2d 3e 6e 4d 61 78 3c 33 20 29 20 72 65 74  he->nMax<3 ) ret
3040: 75 72 6e 20 30 3b 0a 20 20 73 71 6c 69 74 65 33  urn 0;.  sqlite3
3050: 42 65 67 69 6e 42 65 6e 69 67 6e 4d 61 6c 6c 6f  BeginBenignMallo
3060: 63 28 29 3b 0a 20 20 69 66 28 20 70 63 61 63 68  c();.  if( pcach
3070: 65 31 2e 6e 49 6e 69 74 50 61 67 65 3e 30 20 29  e1.nInitPage>0 )
3080: 7b 0a 20 20 20 20 73 7a 42 75 6c 6b 20 3d 20 70  {.    szBulk = p
3090: 43 61 63 68 65 2d 3e 73 7a 41 6c 6c 6f 63 20 2a  Cache->szAlloc *
30a0: 20 28 69 36 34 29 70 63 61 63 68 65 31 2e 6e 49   (i64)pcache1.nI
30b0: 6e 69 74 50 61 67 65 3b 0a 20 20 7d 65 6c 73 65  nitPage;.  }else
30c0: 7b 0a 20 20 20 20 73 7a 42 75 6c 6b 20 3d 20 2d  {.    szBulk = -
30d0: 31 30 32 34 20 2a 20 28 69 36 34 29 70 63 61 63  1024 * (i64)pcac
30e0: 68 65 31 2e 6e 49 6e 69 74 50 61 67 65 3b 0a 20  he1.nInitPage;. 
30f0: 20 7d 0a 20 20 69 66 28 20 73 7a 42 75 6c 6b 20   }.  if( szBulk 
3100: 3e 20 70 43 61 63 68 65 2d 3e 73 7a 41 6c 6c 6f  > pCache->szAllo
3110: 63 2a 28 69 36 34 29 70 43 61 63 68 65 2d 3e 6e  c*(i64)pCache->n
3120: 4d 61 78 20 29 7b 0a 20 20 20 20 73 7a 42 75 6c  Max ){.    szBul
3130: 6b 20 3d 20 70 43 61 63 68 65 2d 3e 73 7a 41 6c  k = pCache->szAl
3140: 6c 6f 63 2a 28 69 36 34 29 70 43 61 63 68 65 2d  loc*(i64)pCache-
3150: 3e 6e 4d 61 78 3b 0a 20 20 7d 0a 20 20 7a 42 75  >nMax;.  }.  zBu
3160: 6c 6b 20 3d 20 70 43 61 63 68 65 2d 3e 70 42 75  lk = pCache->pBu
3170: 6c 6b 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c 6c  lk = sqlite3Mall
3180: 6f 63 28 20 73 7a 42 75 6c 6b 20 29 3b 0a 20 20  oc( szBulk );.  
3190: 73 71 6c 69 74 65 33 45 6e 64 42 65 6e 69 67 6e  sqlite3EndBenign
31a0: 4d 61 6c 6c 6f 63 28 29 3b 0a 20 20 69 66 28 20  Malloc();.  if( 
31b0: 7a 42 75 6c 6b 20 29 7b 0a 20 20 20 20 69 6e 74  zBulk ){.    int
31c0: 20 6e 42 75 6c 6b 20 3d 20 73 71 6c 69 74 65 33   nBulk = sqlite3
31d0: 4d 61 6c 6c 6f 63 53 69 7a 65 28 7a 42 75 6c 6b  MallocSize(zBulk
31e0: 29 2f 70 43 61 63 68 65 2d 3e 73 7a 41 6c 6c 6f  )/pCache->szAllo
31f0: 63 3b 0a 20 20 20 20 64 6f 7b 0a 20 20 20 20 20  c;.    do{.     
3200: 20 50 67 48 64 72 31 20 2a 70 58 20 3d 20 28 50   PgHdr1 *pX = (P
3210: 67 48 64 72 31 2a 29 26 7a 42 75 6c 6b 5b 70 43  gHdr1*)&zBulk[pC
3220: 61 63 68 65 2d 3e 73 7a 50 61 67 65 5d 3b 0a 20  ache->szPage];. 
3230: 20 20 20 20 20 70 58 2d 3e 70 61 67 65 2e 70 42       pX->page.pB
3240: 75 66 20 3d 20 7a 42 75 6c 6b 3b 0a 20 20 20 20  uf = zBulk;.    
3250: 20 20 70 58 2d 3e 70 61 67 65 2e 70 45 78 74 72    pX->page.pExtr
3260: 61 20 3d 20 26 70 58 5b 31 5d 3b 0a 20 20 20 20  a = &pX[1];.    
3270: 20 20 70 58 2d 3e 69 73 42 75 6c 6b 4c 6f 63 61    pX->isBulkLoca
3280: 6c 20 3d 20 31 3b 0a 20 20 20 20 20 20 70 58 2d  l = 1;.      pX-
3290: 3e 69 73 41 6e 63 68 6f 72 20 3d 20 30 3b 0a 20  >isAnchor = 0;. 
32a0: 20 20 20 20 20 70 58 2d 3e 70 4e 65 78 74 20 3d       pX->pNext =
32b0: 20 70 43 61 63 68 65 2d 3e 70 46 72 65 65 3b 0a   pCache->pFree;.
32c0: 20 20 20 20 20 20 70 43 61 63 68 65 2d 3e 70 46        pCache->pF
32d0: 72 65 65 20 3d 20 70 58 3b 0a 20 20 20 20 20 20  ree = pX;.      
32e0: 7a 42 75 6c 6b 20 2b 3d 20 70 43 61 63 68 65 2d  zBulk += pCache-
32f0: 3e 73 7a 41 6c 6c 6f 63 3b 0a 20 20 20 20 7d 77  >szAlloc;.    }w
3300: 68 69 6c 65 28 20 2d 2d 6e 42 75 6c 6b 20 29 3b  hile( --nBulk );
3310: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 70 43  .  }.  return pC
3320: 61 63 68 65 2d 3e 70 46 72 65 65 21 3d 30 3b 0a  ache->pFree!=0;.
3330: 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6c 6c 6f 63 20  }../*.** Malloc 
3340: 66 75 6e 63 74 69 6f 6e 20 75 73 65 64 20 77 69  function used wi
3350: 74 68 69 6e 20 74 68 69 73 20 66 69 6c 65 20 74  thin this file t
3360: 6f 20 61 6c 6c 6f 63 61 74 65 20 73 70 61 63 65  o allocate space
3370: 20 66 72 6f 6d 20 74 68 65 20 62 75 66 66 65 72   from the buffer
3380: 0a 2a 2a 20 63 6f 6e 66 69 67 75 72 65 64 20 75  .** configured u
3390: 73 69 6e 67 20 73 71 6c 69 74 65 33 5f 63 6f 6e  sing sqlite3_con
33a0: 66 69 67 28 53 51 4c 49 54 45 5f 43 4f 4e 46 49  fig(SQLITE_CONFI
33b0: 47 5f 50 41 47 45 43 41 43 48 45 29 20 6f 70 74  G_PAGECACHE) opt
33c0: 69 6f 6e 2e 20 49 66 20 6e 6f 20 0a 2a 2a 20 73  ion. If no .** s
33d0: 75 63 68 20 62 75 66 66 65 72 20 65 78 69 73 74  uch buffer exist
33e0: 73 20 6f 72 20 74 68 65 72 65 20 69 73 20 6e 6f  s or there is no
33f0: 20 73 70 61 63 65 20 6c 65 66 74 20 69 6e 20 69   space left in i
3400: 74 2c 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  t, this function
3410: 20 66 61 6c 6c 73 20 0a 2a 2a 20 62 61 63 6b 20   falls .** back 
3420: 74 6f 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63  to sqlite3Malloc
3430: 28 29 2e 0a 2a 2a 0a 2a 2a 20 4d 75 6c 74 69 70  ()..**.** Multip
3440: 6c 65 20 74 68 72 65 61 64 73 20 63 61 6e 20 72  le threads can r
3450: 75 6e 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20  un this routine 
3460: 61 74 20 74 68 65 20 73 61 6d 65 20 74 69 6d 65  at the same time
3470: 2e 20 20 47 6c 6f 62 61 6c 20 76 61 72 69 61 62  .  Global variab
3480: 6c 65 73 0a 2a 2a 20 69 6e 20 70 63 61 63 68 65  les.** in pcache
3490: 31 20 6e 65 65 64 20 74 6f 20 62 65 20 70 72 6f  1 need to be pro
34a0: 74 65 63 74 65 64 20 76 69 61 20 6d 75 74 65 78  tected via mutex
34b0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
34c0: 20 2a 70 63 61 63 68 65 31 41 6c 6c 6f 63 28 69   *pcache1Alloc(i
34d0: 6e 74 20 6e 42 79 74 65 29 7b 0a 20 20 76 6f 69  nt nByte){.  voi
34e0: 64 20 2a 70 20 3d 20 30 3b 0a 20 20 61 73 73 65  d *p = 0;.  asse
34f0: 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65  rt( sqlite3_mute
3500: 78 5f 6e 6f 74 68 65 6c 64 28 70 63 61 63 68 65  x_notheld(pcache
3510: 31 2e 67 72 70 2e 6d 75 74 65 78 29 20 29 3b 0a  1.grp.mutex) );.
3520: 20 20 69 66 28 20 6e 42 79 74 65 3c 3d 70 63 61    if( nByte<=pca
3530: 63 68 65 31 2e 73 7a 53 6c 6f 74 20 29 7b 0a 20  che1.szSlot ){. 
3540: 20 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78     sqlite3_mutex
3550: 5f 65 6e 74 65 72 28 70 63 61 63 68 65 31 2e 6d  _enter(pcache1.m
3560: 75 74 65 78 29 3b 0a 20 20 20 20 70 20 3d 20 28  utex);.    p = (
3570: 50 67 48 64 72 31 20 2a 29 70 63 61 63 68 65 31  PgHdr1 *)pcache1
3580: 2e 70 46 72 65 65 3b 0a 20 20 20 20 69 66 28 20  .pFree;.    if( 
3590: 70 20 29 7b 0a 20 20 20 20 20 20 70 63 61 63 68  p ){.      pcach
35a0: 65 31 2e 70 46 72 65 65 20 3d 20 70 63 61 63 68  e1.pFree = pcach
35b0: 65 31 2e 70 46 72 65 65 2d 3e 70 4e 65 78 74 3b  e1.pFree->pNext;
35c0: 0a 20 20 20 20 20 20 70 63 61 63 68 65 31 2e 6e  .      pcache1.n
35d0: 46 72 65 65 53 6c 6f 74 2d 2d 3b 0a 20 20 20 20  FreeSlot--;.    
35e0: 20 20 70 63 61 63 68 65 31 2e 62 55 6e 64 65 72    pcache1.bUnder
35f0: 50 72 65 73 73 75 72 65 20 3d 20 70 63 61 63 68  Pressure = pcach
3600: 65 31 2e 6e 46 72 65 65 53 6c 6f 74 3c 70 63 61  e1.nFreeSlot<pca
3610: 63 68 65 31 2e 6e 52 65 73 65 72 76 65 3b 0a 20  che1.nReserve;. 
3620: 20 20 20 20 20 61 73 73 65 72 74 28 20 70 63 61       assert( pca
3630: 63 68 65 31 2e 6e 46 72 65 65 53 6c 6f 74 3e 3d  che1.nFreeSlot>=
3640: 30 20 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74  0 );.      sqlit
3650: 65 33 53 74 61 74 75 73 48 69 67 68 77 61 74 65  e3StatusHighwate
3660: 72 28 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f  r(SQLITE_STATUS_
3670: 50 41 47 45 43 41 43 48 45 5f 53 49 5a 45 2c 20  PAGECACHE_SIZE, 
3680: 6e 42 79 74 65 29 3b 0a 20 20 20 20 20 20 73 71  nByte);.      sq
3690: 6c 69 74 65 33 53 74 61 74 75 73 55 70 28 53 51  lite3StatusUp(SQ
36a0: 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41 47 45  LITE_STATUS_PAGE
36b0: 43 41 43 48 45 5f 55 53 45 44 2c 20 31 29 3b 0a  CACHE_USED, 1);.
36c0: 20 20 20 20 7d 0a 20 20 20 20 73 71 6c 69 74 65      }.    sqlite
36d0: 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 70 63  3_mutex_leave(pc
36e0: 61 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a 20 20  ache1.mutex);.  
36f0: 7d 0a 20 20 69 66 28 20 70 3d 3d 30 20 29 7b 0a  }.  if( p==0 ){.
3700: 20 20 20 20 2f 2a 20 4d 65 6d 6f 72 79 20 69 73      /* Memory is
3710: 20 6e 6f 74 20 61 76 61 69 6c 61 62 6c 65 20 69   not available i
3720: 6e 20 74 68 65 20 53 51 4c 49 54 45 5f 43 4f 4e  n the SQLITE_CON
3730: 46 49 47 5f 50 41 47 45 43 41 43 48 45 20 70 6f  FIG_PAGECACHE po
3740: 6f 6c 2e 20 20 47 65 74 0a 20 20 20 20 2a 2a 20  ol.  Get.    ** 
3750: 69 74 20 66 72 6f 6d 20 73 71 6c 69 74 65 33 4d  it from sqlite3M
3760: 61 6c 6c 6f 63 20 69 6e 73 74 65 61 64 2e 0a 20  alloc instead.. 
3770: 20 20 20 2a 2f 0a 20 20 20 20 70 20 3d 20 73 71     */.    p = sq
3780: 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 6e 42 79 74  lite3Malloc(nByt
3790: 65 29 3b 0a 23 69 66 6e 64 65 66 20 53 51 4c 49  e);.#ifndef SQLI
37a0: 54 45 5f 44 49 53 41 42 4c 45 5f 50 41 47 45 43  TE_DISABLE_PAGEC
37b0: 41 43 48 45 5f 4f 56 45 52 46 4c 4f 57 5f 53 54  ACHE_OVERFLOW_ST
37c0: 41 54 53 0a 20 20 20 20 69 66 28 20 70 20 29 7b  ATS.    if( p ){
37d0: 0a 20 20 20 20 20 20 69 6e 74 20 73 7a 20 3d 20  .      int sz = 
37e0: 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 53 69 7a  sqlite3MallocSiz
37f0: 65 28 70 29 3b 0a 20 20 20 20 20 20 73 71 6c 69  e(p);.      sqli
3800: 74 65 33 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28  te3_mutex_enter(
3810: 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a  pcache1.mutex);.
3820: 20 20 20 20 20 20 73 71 6c 69 74 65 33 53 74 61        sqlite3Sta
3830: 74 75 73 48 69 67 68 77 61 74 65 72 28 53 51 4c  tusHighwater(SQL
3840: 49 54 45 5f 53 54 41 54 55 53 5f 50 41 47 45 43  ITE_STATUS_PAGEC
3850: 41 43 48 45 5f 53 49 5a 45 2c 20 6e 42 79 74 65  ACHE_SIZE, nByte
3860: 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  );.      sqlite3
3870: 53 74 61 74 75 73 55 70 28 53 51 4c 49 54 45 5f  StatusUp(SQLITE_
3880: 53 54 41 54 55 53 5f 50 41 47 45 43 41 43 48 45  STATUS_PAGECACHE
3890: 5f 4f 56 45 52 46 4c 4f 57 2c 20 73 7a 29 3b 0a  _OVERFLOW, sz);.
38a0: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 75        sqlite3_mu
38b0: 74 65 78 5f 6c 65 61 76 65 28 70 63 61 63 68 65  tex_leave(pcache
38c0: 31 2e 6d 75 74 65 78 29 3b 0a 20 20 20 20 7d 0a  1.mutex);.    }.
38d0: 23 65 6e 64 69 66 0a 20 20 20 20 73 71 6c 69 74  #endif.    sqlit
38e0: 65 33 4d 65 6d 64 65 62 75 67 53 65 74 54 79 70  e3MemdebugSetTyp
38f0: 65 28 70 2c 20 4d 45 4d 54 59 50 45 5f 50 43 41  e(p, MEMTYPE_PCA
3900: 43 48 45 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75  CHE);.  }.  retu
3910: 72 6e 20 70 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46  rn p;.}../*.** F
3920: 72 65 65 20 61 6e 20 61 6c 6c 6f 63 61 74 65 64  ree an allocated
3930: 20 62 75 66 66 65 72 20 6f 62 74 61 69 6e 65 64   buffer obtained
3940: 20 66 72 6f 6d 20 70 63 61 63 68 65 31 41 6c 6c   from pcache1All
3950: 6f 63 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  oc()..*/.static 
3960: 76 6f 69 64 20 70 63 61 63 68 65 31 46 72 65 65  void pcache1Free
3970: 28 76 6f 69 64 20 2a 70 29 7b 0a 20 20 69 66 28  (void *p){.  if(
3980: 20 70 3d 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a   p==0 ) return;.
3990: 20 20 69 66 28 20 53 51 4c 49 54 45 5f 57 49 54    if( SQLITE_WIT
39a0: 48 49 4e 28 70 2c 20 70 63 61 63 68 65 31 2e 70  HIN(p, pcache1.p
39b0: 53 74 61 72 74 2c 20 70 63 61 63 68 65 31 2e 70  Start, pcache1.p
39c0: 45 6e 64 29 20 29 7b 0a 20 20 20 20 50 67 46 72  End) ){.    PgFr
39d0: 65 65 73 6c 6f 74 20 2a 70 53 6c 6f 74 3b 0a 20  eeslot *pSlot;. 
39e0: 20 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78     sqlite3_mutex
39f0: 5f 65 6e 74 65 72 28 70 63 61 63 68 65 31 2e 6d  _enter(pcache1.m
3a00: 75 74 65 78 29 3b 0a 20 20 20 20 73 71 6c 69 74  utex);.    sqlit
3a10: 65 33 53 74 61 74 75 73 44 6f 77 6e 28 53 51 4c  e3StatusDown(SQL
3a20: 49 54 45 5f 53 54 41 54 55 53 5f 50 41 47 45 43  ITE_STATUS_PAGEC
3a30: 41 43 48 45 5f 55 53 45 44 2c 20 31 29 3b 0a 20  ACHE_USED, 1);. 
3a40: 20 20 20 70 53 6c 6f 74 20 3d 20 28 50 67 46 72     pSlot = (PgFr
3a50: 65 65 73 6c 6f 74 2a 29 70 3b 0a 20 20 20 20 70  eeslot*)p;.    p
3a60: 53 6c 6f 74 2d 3e 70 4e 65 78 74 20 3d 20 70 63  Slot->pNext = pc
3a70: 61 63 68 65 31 2e 70 46 72 65 65 3b 0a 20 20 20  ache1.pFree;.   
3a80: 20 70 63 61 63 68 65 31 2e 70 46 72 65 65 20 3d   pcache1.pFree =
3a90: 20 70 53 6c 6f 74 3b 0a 20 20 20 20 70 63 61 63   pSlot;.    pcac
3aa0: 68 65 31 2e 6e 46 72 65 65 53 6c 6f 74 2b 2b 3b  he1.nFreeSlot++;
3ab0: 0a 20 20 20 20 70 63 61 63 68 65 31 2e 62 55 6e  .    pcache1.bUn
3ac0: 64 65 72 50 72 65 73 73 75 72 65 20 3d 20 70 63  derPressure = pc
3ad0: 61 63 68 65 31 2e 6e 46 72 65 65 53 6c 6f 74 3c  ache1.nFreeSlot<
3ae0: 70 63 61 63 68 65 31 2e 6e 52 65 73 65 72 76 65  pcache1.nReserve
3af0: 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 63  ;.    assert( pc
3b00: 61 63 68 65 31 2e 6e 46 72 65 65 53 6c 6f 74 3c  ache1.nFreeSlot<
3b10: 3d 70 63 61 63 68 65 31 2e 6e 53 6c 6f 74 20 29  =pcache1.nSlot )
3b20: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 75  ;.    sqlite3_mu
3b30: 74 65 78 5f 6c 65 61 76 65 28 70 63 61 63 68 65  tex_leave(pcache
3b40: 31 2e 6d 75 74 65 78 29 3b 0a 20 20 7d 65 6c 73  1.mutex);.  }els
3b50: 65 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20 73  e{.    assert( s
3b60: 71 6c 69 74 65 33 4d 65 6d 64 65 62 75 67 48 61  qlite3MemdebugHa
3b70: 73 54 79 70 65 28 70 2c 20 4d 45 4d 54 59 50 45  sType(p, MEMTYPE
3b80: 5f 50 43 41 43 48 45 29 20 29 3b 0a 20 20 20 20  _PCACHE) );.    
3b90: 73 71 6c 69 74 65 33 4d 65 6d 64 65 62 75 67 53  sqlite3MemdebugS
3ba0: 65 74 54 79 70 65 28 70 2c 20 4d 45 4d 54 59 50  etType(p, MEMTYP
3bb0: 45 5f 48 45 41 50 29 3b 0a 23 69 66 6e 64 65 66  E_HEAP);.#ifndef
3bc0: 20 53 51 4c 49 54 45 5f 44 49 53 41 42 4c 45 5f   SQLITE_DISABLE_
3bd0: 50 41 47 45 43 41 43 48 45 5f 4f 56 45 52 46 4c  PAGECACHE_OVERFL
3be0: 4f 57 5f 53 54 41 54 53 0a 20 20 20 20 7b 0a 20  OW_STATS.    {. 
3bf0: 20 20 20 20 20 69 6e 74 20 6e 46 72 65 65 64 20       int nFreed 
3c00: 3d 20 30 3b 0a 20 20 20 20 20 20 6e 46 72 65 65  = 0;.      nFree
3c10: 64 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f  d = sqlite3Mallo
3c20: 63 53 69 7a 65 28 70 29 3b 0a 20 20 20 20 20 20  cSize(p);.      
3c30: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e  sqlite3_mutex_en
3c40: 74 65 72 28 70 63 61 63 68 65 31 2e 6d 75 74 65  ter(pcache1.mute
3c50: 78 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65  x);.      sqlite
3c60: 33 53 74 61 74 75 73 44 6f 77 6e 28 53 51 4c 49  3StatusDown(SQLI
3c70: 54 45 5f 53 54 41 54 55 53 5f 50 41 47 45 43 41  TE_STATUS_PAGECA
3c80: 43 48 45 5f 4f 56 45 52 46 4c 4f 57 2c 20 6e 46  CHE_OVERFLOW, nF
3c90: 72 65 65 64 29 3b 0a 20 20 20 20 20 20 73 71 6c  reed);.      sql
3ca0: 69 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65  ite3_mutex_leave
3cb0: 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29 3b  (pcache1.mutex);
3cc0: 0a 20 20 20 20 7d 0a 23 65 6e 64 69 66 0a 20 20  .    }.#endif.  
3cd0: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
3ce0: 29 3b 0a 20 20 7d 0a 7d 0a 0a 23 69 66 64 65 66  );.  }.}..#ifdef
3cf0: 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d   SQLITE_ENABLE_M
3d00: 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54  EMORY_MANAGEMENT
3d10: 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68  ./*.** Return th
3d20: 65 20 73 69 7a 65 20 6f 66 20 61 20 70 63 61 63  e size of a pcac
3d30: 68 65 20 61 6c 6c 6f 63 61 74 69 6f 6e 0a 2a 2f  he allocation.*/
3d40: 0a 73 74 61 74 69 63 20 69 6e 74 20 70 63 61 63  .static int pcac
3d50: 68 65 31 4d 65 6d 53 69 7a 65 28 76 6f 69 64 20  he1MemSize(void 
3d60: 2a 70 29 7b 0a 20 20 69 66 28 20 70 3e 3d 70 63  *p){.  if( p>=pc
3d70: 61 63 68 65 31 2e 70 53 74 61 72 74 20 26 26 20  ache1.pStart && 
3d80: 70 3c 70 63 61 63 68 65 31 2e 70 45 6e 64 20 29  p<pcache1.pEnd )
3d90: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 70 63 61  {.    return pca
3da0: 63 68 65 31 2e 73 7a 53 6c 6f 74 3b 0a 20 20 7d  che1.szSlot;.  }
3db0: 65 6c 73 65 7b 0a 20 20 20 20 69 6e 74 20 69 53  else{.    int iS
3dc0: 69 7a 65 3b 0a 20 20 20 20 61 73 73 65 72 74 28  ize;.    assert(
3dd0: 20 73 71 6c 69 74 65 33 4d 65 6d 64 65 62 75 67   sqlite3Memdebug
3de0: 48 61 73 54 79 70 65 28 70 2c 20 4d 45 4d 54 59  HasType(p, MEMTY
3df0: 50 45 5f 50 43 41 43 48 45 29 20 29 3b 0a 20 20  PE_PCACHE) );.  
3e00: 20 20 73 71 6c 69 74 65 33 4d 65 6d 64 65 62 75    sqlite3Memdebu
3e10: 67 53 65 74 54 79 70 65 28 70 2c 20 4d 45 4d 54  gSetType(p, MEMT
3e20: 59 50 45 5f 48 45 41 50 29 3b 0a 20 20 20 20 69  YPE_HEAP);.    i
3e30: 53 69 7a 65 20 3d 20 73 71 6c 69 74 65 33 4d 61  Size = sqlite3Ma
3e40: 6c 6c 6f 63 53 69 7a 65 28 70 29 3b 0a 20 20 20  llocSize(p);.   
3e50: 20 73 71 6c 69 74 65 33 4d 65 6d 64 65 62 75 67   sqlite3Memdebug
3e60: 53 65 74 54 79 70 65 28 70 2c 20 4d 45 4d 54 59  SetType(p, MEMTY
3e70: 50 45 5f 50 43 41 43 48 45 29 3b 0a 20 20 20 20  PE_PCACHE);.    
3e80: 72 65 74 75 72 6e 20 69 53 69 7a 65 3b 0a 20 20  return iSize;.  
3e90: 7d 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51  }.}.#endif /* SQ
3ea0: 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f  LITE_ENABLE_MEMO
3eb0: 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 20 2a 2f  RY_MANAGEMENT */
3ec0: 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65  ../*.** Allocate
3ed0: 20 61 20 6e 65 77 20 70 61 67 65 20 6f 62 6a 65   a new page obje
3ee0: 63 74 20 69 6e 69 74 69 61 6c 6c 79 20 61 73 73  ct initially ass
3ef0: 6f 63 69 61 74 65 64 20 77 69 74 68 20 63 61 63  ociated with cac
3f00: 68 65 20 70 43 61 63 68 65 2e 0a 2a 2f 0a 73 74  he pCache..*/.st
3f10: 61 74 69 63 20 50 67 48 64 72 31 20 2a 70 63 61  atic PgHdr1 *pca
3f20: 63 68 65 31 41 6c 6c 6f 63 50 61 67 65 28 50 43  che1AllocPage(PC
3f30: 61 63 68 65 31 20 2a 70 43 61 63 68 65 2c 20 69  ache1 *pCache, i
3f40: 6e 74 20 62 65 6e 69 67 6e 4d 61 6c 6c 6f 63 29  nt benignMalloc)
3f50: 7b 0a 20 20 50 67 48 64 72 31 20 2a 70 20 3d 20  {.  PgHdr1 *p = 
3f60: 30 3b 0a 20 20 76 6f 69 64 20 2a 70 50 67 3b 0a  0;.  void *pPg;.
3f70: 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74  .  assert( sqlit
3f80: 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 43  e3_mutex_held(pC
3f90: 61 63 68 65 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75  ache->pGroup->mu
3fa0: 74 65 78 29 20 29 3b 0a 20 20 69 66 28 20 70 43  tex) );.  if( pC
3fb0: 61 63 68 65 2d 3e 70 46 72 65 65 20 7c 7c 20 28  ache->pFree || (
3fc0: 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 3d 3d 30  pCache->nPage==0
3fd0: 20 26 26 20 70 63 61 63 68 65 31 49 6e 69 74 42   && pcache1InitB
3fe0: 75 6c 6b 28 70 43 61 63 68 65 29 29 20 29 7b 0a  ulk(pCache)) ){.
3ff0: 20 20 20 20 70 20 3d 20 70 43 61 63 68 65 2d 3e      p = pCache->
4000: 70 46 72 65 65 3b 0a 20 20 20 20 70 43 61 63 68  pFree;.    pCach
4010: 65 2d 3e 70 46 72 65 65 20 3d 20 70 2d 3e 70 4e  e->pFree = p->pN
4020: 65 78 74 3b 0a 20 20 20 20 70 2d 3e 70 4e 65 78  ext;.    p->pNex
4030: 74 20 3d 20 30 3b 0a 20 20 7d 65 6c 73 65 7b 0a  t = 0;.  }else{.
4040: 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 45 4e  #ifdef SQLITE_EN
4050: 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41  ABLE_MEMORY_MANA
4060: 47 45 4d 45 4e 54 0a 20 20 20 20 2f 2a 20 54 68  GEMENT.    /* Th
4070: 65 20 67 72 6f 75 70 20 6d 75 74 65 78 20 6d 75  e group mutex mu
4080: 73 74 20 62 65 20 72 65 6c 65 61 73 65 64 20 62  st be released b
4090: 65 66 6f 72 65 20 70 63 61 63 68 65 31 41 6c 6c  efore pcache1All
40a0: 6f 63 28 29 20 69 73 20 63 61 6c 6c 65 64 2e 20  oc() is called. 
40b0: 54 68 69 73 0a 20 20 20 20 2a 2a 20 69 73 20 62  This.    ** is b
40c0: 65 63 61 75 73 65 20 69 74 20 6d 69 67 68 74 20  ecause it might 
40d0: 63 61 6c 6c 20 73 71 6c 69 74 65 33 5f 72 65 6c  call sqlite3_rel
40e0: 65 61 73 65 5f 6d 65 6d 6f 72 79 28 29 2c 20 77  ease_memory(), w
40f0: 68 69 63 68 20 61 73 73 75 6d 65 73 20 74 68 61  hich assumes tha
4100: 74 20 0a 20 20 20 20 2a 2a 20 74 68 69 73 20 6d  t .    ** this m
4110: 75 74 65 78 20 69 73 20 6e 6f 74 20 68 65 6c 64  utex is not held
4120: 2e 20 2a 2f 0a 20 20 20 20 61 73 73 65 72 74 28  . */.    assert(
4130: 20 70 63 61 63 68 65 31 2e 73 65 70 61 72 61 74   pcache1.separat
4140: 65 43 61 63 68 65 3d 3d 30 20 29 3b 0a 20 20 20  eCache==0 );.   
4150: 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65 2d   assert( pCache-
4160: 3e 70 47 72 6f 75 70 3d 3d 26 70 63 61 63 68 65  >pGroup==&pcache
4170: 31 2e 67 72 70 20 29 3b 0a 20 20 20 20 70 63 61  1.grp );.    pca
4180: 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 70  che1LeaveMutex(p
4190: 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a  Cache->pGroup);.
41a0: 23 65 6e 64 69 66 0a 20 20 20 20 69 66 28 20 62  #endif.    if( b
41b0: 65 6e 69 67 6e 4d 61 6c 6c 6f 63 20 29 7b 20 73  enignMalloc ){ s
41c0: 71 6c 69 74 65 33 42 65 67 69 6e 42 65 6e 69 67  qlite3BeginBenig
41d0: 6e 4d 61 6c 6c 6f 63 28 29 3b 20 7d 0a 23 69 66  nMalloc(); }.#if
41e0: 64 65 66 20 53 51 4c 49 54 45 5f 50 43 41 43 48  def SQLITE_PCACH
41f0: 45 5f 53 45 50 41 52 41 54 45 5f 48 45 41 44 45  E_SEPARATE_HEADE
4200: 52 0a 20 20 20 20 70 50 67 20 3d 20 70 63 61 63  R.    pPg = pcac
4210: 68 65 31 41 6c 6c 6f 63 28 70 43 61 63 68 65 2d  he1Alloc(pCache-
4220: 3e 73 7a 50 61 67 65 29 3b 0a 20 20 20 20 70 20  >szPage);.    p 
4230: 3d 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28  = sqlite3Malloc(
4240: 73 69 7a 65 6f 66 28 50 67 48 64 72 31 29 20 2b  sizeof(PgHdr1) +
4250: 20 70 43 61 63 68 65 2d 3e 73 7a 45 78 74 72 61   pCache->szExtra
4260: 29 3b 0a 20 20 20 20 69 66 28 20 21 70 50 67 20  );.    if( !pPg 
4270: 7c 7c 20 21 70 20 29 7b 0a 20 20 20 20 20 20 70  || !p ){.      p
4280: 63 61 63 68 65 31 46 72 65 65 28 70 50 67 29 3b  cache1Free(pPg);
4290: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66  .      sqlite3_f
42a0: 72 65 65 28 70 29 3b 0a 20 20 20 20 20 20 70 50  ree(p);.      pP
42b0: 67 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 23 65 6c  g = 0;.    }.#el
42c0: 73 65 0a 20 20 20 20 70 50 67 20 3d 20 70 63 61  se.    pPg = pca
42d0: 63 68 65 31 41 6c 6c 6f 63 28 70 43 61 63 68 65  che1Alloc(pCache
42e0: 2d 3e 73 7a 41 6c 6c 6f 63 29 3b 0a 20 20 20 20  ->szAlloc);.    
42f0: 70 20 3d 20 28 50 67 48 64 72 31 20 2a 29 26 28  p = (PgHdr1 *)&(
4300: 28 75 38 20 2a 29 70 50 67 29 5b 70 43 61 63 68  (u8 *)pPg)[pCach
4310: 65 2d 3e 73 7a 50 61 67 65 5d 3b 0a 23 65 6e 64  e->szPage];.#end
4320: 69 66 0a 20 20 20 20 69 66 28 20 62 65 6e 69 67  if.    if( benig
4330: 6e 4d 61 6c 6c 6f 63 20 29 7b 20 73 71 6c 69 74  nMalloc ){ sqlit
4340: 65 33 45 6e 64 42 65 6e 69 67 6e 4d 61 6c 6c 6f  e3EndBenignMallo
4350: 63 28 29 3b 20 7d 0a 23 69 66 64 65 66 20 53 51  c(); }.#ifdef SQ
4360: 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f  LITE_ENABLE_MEMO
4370: 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 0a 20 20  RY_MANAGEMENT.  
4380: 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75    pcache1EnterMu
4390: 74 65 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f  tex(pCache->pGro
43a0: 75 70 29 3b 0a 23 65 6e 64 69 66 0a 20 20 20 20  up);.#endif.    
43b0: 69 66 28 20 70 50 67 3d 3d 30 20 29 20 72 65 74  if( pPg==0 ) ret
43c0: 75 72 6e 20 30 3b 0a 20 20 20 20 70 2d 3e 70 61  urn 0;.    p->pa
43d0: 67 65 2e 70 42 75 66 20 3d 20 70 50 67 3b 0a 20  ge.pBuf = pPg;. 
43e0: 20 20 20 70 2d 3e 70 61 67 65 2e 70 45 78 74 72     p->page.pExtr
43f0: 61 20 3d 20 26 70 5b 31 5d 3b 0a 20 20 20 20 70  a = &p[1];.    p
4400: 2d 3e 69 73 42 75 6c 6b 4c 6f 63 61 6c 20 3d 20  ->isBulkLocal = 
4410: 30 3b 0a 20 20 20 20 70 2d 3e 69 73 41 6e 63 68  0;.    p->isAnch
4420: 6f 72 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 69 66  or = 0;.  }.  if
4430: 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65  ( pCache->bPurge
4440: 61 62 6c 65 20 29 7b 0a 20 20 20 20 70 43 61 63  able ){.    pCac
4450: 68 65 2d 3e 70 47 72 6f 75 70 2d 3e 6e 43 75 72  he->pGroup->nCur
4460: 72 65 6e 74 50 61 67 65 2b 2b 3b 0a 20 20 7d 0a  rentPage++;.  }.
4470: 20 20 72 65 74 75 72 6e 20 70 3b 0a 7d 0a 0a 2f    return p;.}../
4480: 2a 0a 2a 2a 20 46 72 65 65 20 61 20 70 61 67 65  *.** Free a page
4490: 20 6f 62 6a 65 63 74 20 61 6c 6c 6f 63 61 74 65   object allocate
44a0: 64 20 62 79 20 70 63 61 63 68 65 31 41 6c 6c 6f  d by pcache1Allo
44b0: 63 50 61 67 65 28 29 2e 0a 2a 2f 0a 73 74 61 74  cPage()..*/.stat
44c0: 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 31 46  ic void pcache1F
44d0: 72 65 65 50 61 67 65 28 50 67 48 64 72 31 20 2a  reePage(PgHdr1 *
44e0: 70 29 7b 0a 20 20 50 43 61 63 68 65 31 20 2a 70  p){.  PCache1 *p
44f0: 43 61 63 68 65 3b 0a 20 20 61 73 73 65 72 74 28  Cache;.  assert(
4500: 20 70 21 3d 30 20 29 3b 0a 20 20 70 43 61 63 68   p!=0 );.  pCach
4510: 65 20 3d 20 70 2d 3e 70 43 61 63 68 65 3b 0a 20  e = p->pCache;. 
4520: 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33   assert( sqlite3
4530: 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 2d 3e 70  _mutex_held(p->p
4540: 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 2d 3e 6d  Cache->pGroup->m
4550: 75 74 65 78 29 20 29 3b 0a 20 20 69 66 28 20 70  utex) );.  if( p
4560: 2d 3e 69 73 42 75 6c 6b 4c 6f 63 61 6c 20 29 7b  ->isBulkLocal ){
4570: 0a 20 20 20 20 70 2d 3e 70 4e 65 78 74 20 3d 20  .    p->pNext = 
4580: 70 43 61 63 68 65 2d 3e 70 46 72 65 65 3b 0a 20  pCache->pFree;. 
4590: 20 20 20 70 43 61 63 68 65 2d 3e 70 46 72 65 65     pCache->pFree
45a0: 20 3d 20 70 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20   = p;.  }else{. 
45b0: 20 20 20 70 63 61 63 68 65 31 46 72 65 65 28 70     pcache1Free(p
45c0: 2d 3e 70 61 67 65 2e 70 42 75 66 29 3b 0a 23 69  ->page.pBuf);.#i
45d0: 66 64 65 66 20 53 51 4c 49 54 45 5f 50 43 41 43  fdef SQLITE_PCAC
45e0: 48 45 5f 53 45 50 41 52 41 54 45 5f 48 45 41 44  HE_SEPARATE_HEAD
45f0: 45 52 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66  ER.    sqlite3_f
4600: 72 65 65 28 70 29 3b 0a 23 65 6e 64 69 66 0a 20  ree(p);.#endif. 
4610: 20 7d 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d   }.  if( pCache-
4620: 3e 62 50 75 72 67 65 61 62 6c 65 20 29 7b 0a 20  >bPurgeable ){. 
4630: 20 20 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75     pCache->pGrou
4640: 70 2d 3e 6e 43 75 72 72 65 6e 74 50 61 67 65 2d  p->nCurrentPage-
4650: 2d 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  -;.  }.}../*.** 
4660: 4d 61 6c 6c 6f 63 20 66 75 6e 63 74 69 6f 6e 20  Malloc function 
4670: 75 73 65 64 20 62 79 20 53 51 4c 69 74 65 20 74  used by SQLite t
4680: 6f 20 6f 62 74 61 69 6e 20 73 70 61 63 65 20 66  o obtain space f
4690: 72 6f 6d 20 74 68 65 20 62 75 66 66 65 72 20 63  rom the buffer c
46a0: 6f 6e 66 69 67 75 72 65 64 0a 2a 2a 20 75 73 69  onfigured.** usi
46b0: 6e 67 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69  ng sqlite3_confi
46c0: 67 28 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f  g(SQLITE_CONFIG_
46d0: 50 41 47 45 43 41 43 48 45 29 20 6f 70 74 69 6f  PAGECACHE) optio
46e0: 6e 2e 20 49 66 20 6e 6f 20 73 75 63 68 20 62 75  n. If no such bu
46f0: 66 66 65 72 0a 2a 2a 20 65 78 69 73 74 73 2c 20  ffer.** exists, 
4700: 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 66 61  this function fa
4710: 6c 6c 73 20 62 61 63 6b 20 74 6f 20 73 71 6c 69  lls back to sqli
4720: 74 65 33 4d 61 6c 6c 6f 63 28 29 2e 0a 2a 2f 0a  te3Malloc()..*/.
4730: 76 6f 69 64 20 2a 73 71 6c 69 74 65 33 50 61 67  void *sqlite3Pag
4740: 65 4d 61 6c 6c 6f 63 28 69 6e 74 20 73 7a 29 7b  eMalloc(int sz){
4750: 0a 20 20 72 65 74 75 72 6e 20 70 63 61 63 68 65  .  return pcache
4760: 31 41 6c 6c 6f 63 28 73 7a 29 3b 0a 7d 0a 0a 2f  1Alloc(sz);.}../
4770: 2a 0a 2a 2a 20 46 72 65 65 20 61 6e 20 61 6c 6c  *.** Free an all
4780: 6f 63 61 74 65 64 20 62 75 66 66 65 72 20 6f 62  ocated buffer ob
4790: 74 61 69 6e 65 64 20 66 72 6f 6d 20 73 71 6c 69  tained from sqli
47a0: 74 65 33 50 61 67 65 4d 61 6c 6c 6f 63 28 29 2e  te3PageMalloc().
47b0: 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33  .*/.void sqlite3
47c0: 50 61 67 65 46 72 65 65 28 76 6f 69 64 20 2a 70  PageFree(void *p
47d0: 29 7b 0a 20 20 70 63 61 63 68 65 31 46 72 65 65  ){.  pcache1Free
47e0: 28 70 29 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 52  (p);.}.../*.** R
47f0: 65 74 75 72 6e 20 74 72 75 65 20 69 66 20 69 74  eturn true if it
4800: 20 64 65 73 69 72 61 62 6c 65 20 74 6f 20 61 76   desirable to av
4810: 6f 69 64 20 61 6c 6c 6f 63 61 74 69 6e 67 20 61  oid allocating a
4820: 20 6e 65 77 20 70 61 67 65 20 63 61 63 68 65 0a   new page cache.
4830: 2a 2a 20 65 6e 74 72 79 2e 0a 2a 2a 0a 2a 2a 20  ** entry..**.** 
4840: 49 66 20 6d 65 6d 6f 72 79 20 77 61 73 20 61 6c  If memory was al
4850: 6c 6f 63 61 74 65 64 20 73 70 65 63 69 66 69 63  located specific
4860: 61 6c 6c 79 20 74 6f 20 74 68 65 20 70 61 67 65  ally to the page
4870: 20 63 61 63 68 65 20 75 73 69 6e 67 0a 2a 2a 20   cache using.** 
4880: 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41  SQLITE_CONFIG_PA
4890: 47 45 43 41 43 48 45 20 62 75 74 20 74 68 61 74  GECACHE but that
48a0: 20 6d 65 6d 6f 72 79 20 68 61 73 20 61 6c 6c 20   memory has all 
48b0: 62 65 65 6e 20 75 73 65 64 2c 20 74 68 65 6e 0a  been used, then.
48c0: 2a 2a 20 69 74 20 69 73 20 64 65 73 69 72 61 62  ** it is desirab
48d0: 6c 65 20 74 6f 20 61 76 6f 69 64 20 61 6c 6c 6f  le to avoid allo
48e0: 63 61 74 69 6e 67 20 61 20 6e 65 77 20 70 61 67  cating a new pag
48f0: 65 20 63 61 63 68 65 20 65 6e 74 72 79 20 62 65  e cache entry be
4900: 63 61 75 73 65 0a 2a 2a 20 70 72 65 73 75 6d 61  cause.** presuma
4910: 62 6c 79 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49  bly SQLITE_CONFI
4920: 47 5f 50 41 47 45 43 41 43 48 45 20 77 61 73 20  G_PAGECACHE was 
4930: 73 75 70 70 6f 73 65 20 74 6f 20 62 65 20 73 75  suppose to be su
4940: 66 66 69 63 69 65 6e 74 0a 2a 2a 20 66 6f 72 20  fficient.** for 
4950: 61 6c 6c 20 70 61 67 65 20 63 61 63 68 65 20 6e  all page cache n
4960: 65 65 64 73 20 61 6e 64 20 77 65 20 73 68 6f 75  eeds and we shou
4970: 6c 64 20 6e 6f 74 20 6e 65 65 64 20 74 6f 20 73  ld not need to s
4980: 70 69 6c 6c 20 74 68 65 0a 2a 2a 20 61 6c 6c 6f  pill the.** allo
4990: 63 61 74 69 6f 6e 20 6f 6e 74 6f 20 74 68 65 20  cation onto the 
49a0: 68 65 61 70 2e 0a 2a 2a 0a 2a 2a 20 4f 72 2c 20  heap..**.** Or, 
49b0: 74 68 65 20 68 65 61 70 20 69 73 20 75 73 65 64  the heap is used
49c0: 20 66 6f 72 20 61 6c 6c 20 70 61 67 65 20 63 61   for all page ca
49d0: 63 68 65 20 6d 65 6d 6f 72 79 20 62 75 74 20 74  che memory but t
49e0: 68 65 20 68 65 61 70 20 69 73 0a 2a 2a 20 75 6e  he heap is.** un
49f0: 64 65 72 20 6d 65 6d 6f 72 79 20 70 72 65 73 73  der memory press
4a00: 75 72 65 2c 20 74 68 65 6e 20 61 67 61 69 6e 20  ure, then again 
4a10: 69 74 20 69 73 20 64 65 73 69 72 61 62 6c 65 20  it is desirable 
4a20: 74 6f 20 61 76 6f 69 64 0a 2a 2a 20 61 6c 6c 6f  to avoid.** allo
4a30: 63 61 74 69 6e 67 20 61 20 6e 65 77 20 70 61 67  cating a new pag
4a40: 65 20 63 61 63 68 65 20 65 6e 74 72 79 20 69 6e  e cache entry in
4a50: 20 6f 72 64 65 72 20 74 6f 20 61 76 6f 69 64 20   order to avoid 
4a60: 73 74 72 65 73 73 69 6e 67 0a 2a 2a 20 74 68 65  stressing.** the
4a70: 20 68 65 61 70 20 65 76 65 6e 20 66 75 72 74 68   heap even furth
4a80: 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  er..*/.static in
4a90: 74 20 70 63 61 63 68 65 31 55 6e 64 65 72 4d 65  t pcache1UnderMe
4aa0: 6d 6f 72 79 50 72 65 73 73 75 72 65 28 50 43 61  moryPressure(PCa
4ab0: 63 68 65 31 20 2a 70 43 61 63 68 65 29 7b 0a 20  che1 *pCache){. 
4ac0: 20 69 66 28 20 70 63 61 63 68 65 31 2e 6e 53 6c   if( pcache1.nSl
4ad0: 6f 74 20 26 26 20 28 70 43 61 63 68 65 2d 3e 73  ot && (pCache->s
4ae0: 7a 50 61 67 65 2b 70 43 61 63 68 65 2d 3e 73 7a  zPage+pCache->sz
4af0: 45 78 74 72 61 29 3c 3d 70 63 61 63 68 65 31 2e  Extra)<=pcache1.
4b00: 73 7a 53 6c 6f 74 20 29 7b 0a 20 20 20 20 72 65  szSlot ){.    re
4b10: 74 75 72 6e 20 70 63 61 63 68 65 31 2e 62 55 6e  turn pcache1.bUn
4b20: 64 65 72 50 72 65 73 73 75 72 65 3b 0a 20 20 7d  derPressure;.  }
4b30: 65 6c 73 65 7b 0a 20 20 20 20 72 65 74 75 72 6e  else{.    return
4b40: 20 73 71 6c 69 74 65 33 48 65 61 70 4e 65 61 72   sqlite3HeapNear
4b50: 6c 79 46 75 6c 6c 28 29 3b 0a 20 20 7d 0a 7d 0a  lyFull();.  }.}.
4b60: 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ./**************
4b70: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4b80: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4b90: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4ba0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4bb0: 2f 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 20 47 65 6e 65  /./******** Gene
4bc0: 72 61 6c 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69  ral Implementati
4bd0: 6f 6e 20 46 75 6e 63 74 69 6f 6e 73 20 2a 2a 2a  on Functions ***
4be0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4bf0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4c00: 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66  */../*.** This f
4c10: 75 6e 63 74 69 6f 6e 20 69 73 20 75 73 65 64 20  unction is used 
4c20: 74 6f 20 72 65 73 69 7a 65 20 74 68 65 20 68 61  to resize the ha
4c30: 73 68 20 74 61 62 6c 65 20 75 73 65 64 20 62 79  sh table used by
4c40: 20 74 68 65 20 63 61 63 68 65 20 70 61 73 73 65   the cache passe
4c50: 64 0a 2a 2a 20 61 73 20 74 68 65 20 66 69 72 73  d.** as the firs
4c60: 74 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2a 0a 2a  t argument..**.*
4c70: 2a 20 54 68 65 20 50 43 61 63 68 65 20 6d 75 74  * The PCache mut
4c80: 65 78 20 6d 75 73 74 20 62 65 20 68 65 6c 64 20  ex must be held 
4c90: 77 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69  when this functi
4ca0: 6f 6e 20 69 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f  on is called..*/
4cb0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61  .static void pca
4cc0: 63 68 65 31 52 65 73 69 7a 65 48 61 73 68 28 50  che1ResizeHash(P
4cd0: 43 61 63 68 65 31 20 2a 70 29 7b 0a 20 20 50 67  Cache1 *p){.  Pg
4ce0: 48 64 72 31 20 2a 2a 61 70 4e 65 77 3b 0a 20 20  Hdr1 **apNew;.  
4cf0: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 4e 65  unsigned int nNe
4d00: 77 3b 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e  w;.  unsigned in
4d10: 74 20 69 3b 0a 0a 20 20 61 73 73 65 72 74 28 20  t i;..  assert( 
4d20: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65  sqlite3_mutex_he
4d30: 6c 64 28 70 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75  ld(p->pGroup->mu
4d40: 74 65 78 29 20 29 3b 0a 0a 20 20 6e 4e 65 77 20  tex) );..  nNew 
4d50: 3d 20 70 2d 3e 6e 48 61 73 68 2a 32 3b 0a 20 20  = p->nHash*2;.  
4d60: 69 66 28 20 6e 4e 65 77 3c 32 35 36 20 29 7b 0a  if( nNew<256 ){.
4d70: 20 20 20 20 6e 4e 65 77 20 3d 20 32 35 36 3b 0a      nNew = 256;.
4d80: 20 20 7d 0a 0a 20 20 70 63 61 63 68 65 31 4c 65    }..  pcache1Le
4d90: 61 76 65 4d 75 74 65 78 28 70 2d 3e 70 47 72 6f  aveMutex(p->pGro
4da0: 75 70 29 3b 0a 20 20 69 66 28 20 70 2d 3e 6e 48  up);.  if( p->nH
4db0: 61 73 68 20 29 7b 20 73 71 6c 69 74 65 33 42 65  ash ){ sqlite3Be
4dc0: 67 69 6e 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28  ginBenignMalloc(
4dd0: 29 3b 20 7d 0a 20 20 61 70 4e 65 77 20 3d 20 28  ); }.  apNew = (
4de0: 50 67 48 64 72 31 20 2a 2a 29 73 71 6c 69 74 65  PgHdr1 **)sqlite
4df0: 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28 73 69 7a 65  3MallocZero(size
4e00: 6f 66 28 50 67 48 64 72 31 20 2a 29 2a 6e 4e 65  of(PgHdr1 *)*nNe
4e10: 77 29 3b 0a 20 20 69 66 28 20 70 2d 3e 6e 48 61  w);.  if( p->nHa
4e20: 73 68 20 29 7b 20 73 71 6c 69 74 65 33 45 6e 64  sh ){ sqlite3End
4e30: 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 20  BenignMalloc(); 
4e40: 7d 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65 72  }.  pcache1Enter
4e50: 4d 75 74 65 78 28 70 2d 3e 70 47 72 6f 75 70 29  Mutex(p->pGroup)
4e60: 3b 0a 20 20 69 66 28 20 61 70 4e 65 77 20 29 7b  ;.  if( apNew ){
4e70: 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  .    for(i=0; i<
4e80: 70 2d 3e 6e 48 61 73 68 3b 20 69 2b 2b 29 7b 0a  p->nHash; i++){.
4e90: 20 20 20 20 20 20 50 67 48 64 72 31 20 2a 70 50        PgHdr1 *pP
4ea0: 61 67 65 3b 0a 20 20 20 20 20 20 50 67 48 64 72  age;.      PgHdr
4eb0: 31 20 2a 70 4e 65 78 74 20 3d 20 70 2d 3e 61 70  1 *pNext = p->ap
4ec0: 48 61 73 68 5b 69 5d 3b 0a 20 20 20 20 20 20 77  Hash[i];.      w
4ed0: 68 69 6c 65 28 20 28 70 50 61 67 65 20 3d 20 70  hile( (pPage = p
4ee0: 4e 65 78 74 29 21 3d 30 20 29 7b 0a 20 20 20 20  Next)!=0 ){.    
4ef0: 20 20 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74      unsigned int
4f00: 20 68 20 3d 20 70 50 61 67 65 2d 3e 69 4b 65 79   h = pPage->iKey
4f10: 20 25 20 6e 4e 65 77 3b 0a 20 20 20 20 20 20 20   % nNew;.       
4f20: 20 70 4e 65 78 74 20 3d 20 70 50 61 67 65 2d 3e   pNext = pPage->
4f30: 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 20 20 70  pNext;.        p
4f40: 50 61 67 65 2d 3e 70 4e 65 78 74 20 3d 20 61 70  Page->pNext = ap
4f50: 4e 65 77 5b 68 5d 3b 0a 20 20 20 20 20 20 20 20  New[h];.        
4f60: 61 70 4e 65 77 5b 68 5d 20 3d 20 70 50 61 67 65  apNew[h] = pPage
4f70: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
4f80: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
4f90: 28 70 2d 3e 61 70 48 61 73 68 29 3b 0a 20 20 20  (p->apHash);.   
4fa0: 20 70 2d 3e 61 70 48 61 73 68 20 3d 20 61 70 4e   p->apHash = apN
4fb0: 65 77 3b 0a 20 20 20 20 70 2d 3e 6e 48 61 73 68  ew;.    p->nHash
4fc0: 20 3d 20 6e 4e 65 77 3b 0a 20 20 7d 0a 7d 0a 0a   = nNew;.  }.}..
4fd0: 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  /*.** This funct
4fe0: 69 6f 6e 20 69 73 20 75 73 65 64 20 69 6e 74 65  ion is used inte
4ff0: 72 6e 61 6c 6c 79 20 74 6f 20 72 65 6d 6f 76 65  rnally to remove
5000: 20 74 68 65 20 70 61 67 65 20 70 50 61 67 65 20   the page pPage 
5010: 66 72 6f 6d 20 74 68 65 20 0a 2a 2a 20 50 47 72  from the .** PGr
5020: 6f 75 70 20 4c 52 55 20 6c 69 73 74 2c 20 69 66  oup LRU list, if
5030: 20 69 73 20 70 61 72 74 20 6f 66 20 69 74 2e 20   is part of it. 
5040: 49 66 20 70 50 61 67 65 20 69 73 20 6e 6f 74 20  If pPage is not 
5050: 70 61 72 74 20 6f 66 20 74 68 65 20 50 47 72 6f  part of the PGro
5060: 75 70 0a 2a 2a 20 4c 52 55 20 6c 69 73 74 2c 20  up.** LRU list, 
5070: 74 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69  then this functi
5080: 6f 6e 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a 2a  on is a no-op..*
5090: 2a 0a 2a 2a 20 54 68 65 20 50 47 72 6f 75 70 20  *.** The PGroup 
50a0: 6d 75 74 65 78 20 6d 75 73 74 20 62 65 20 68 65  mutex must be he
50b0: 6c 64 20 77 68 65 6e 20 74 68 69 73 20 66 75 6e  ld when this fun
50c0: 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 2e  ction is called.
50d0: 0a 2a 2f 0a 73 74 61 74 69 63 20 50 67 48 64 72  .*/.static PgHdr
50e0: 31 20 2a 70 63 61 63 68 65 31 50 69 6e 50 61 67  1 *pcache1PinPag
50f0: 65 28 50 67 48 64 72 31 20 2a 70 50 61 67 65 29  e(PgHdr1 *pPage)
5100: 7b 0a 20 20 61 73 73 65 72 74 28 20 70 50 61 67  {.  assert( pPag
5110: 65 21 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74  e!=0 );.  assert
5120: 28 20 50 41 47 45 5f 49 53 5f 55 4e 50 49 4e 4e  ( PAGE_IS_UNPINN
5130: 45 44 28 70 50 61 67 65 29 20 29 3b 0a 20 20 61  ED(pPage) );.  a
5140: 73 73 65 72 74 28 20 70 50 61 67 65 2d 3e 70 4c  ssert( pPage->pL
5150: 72 75 4e 65 78 74 20 29 3b 0a 20 20 61 73 73 65  ruNext );.  asse
5160: 72 74 28 20 70 50 61 67 65 2d 3e 70 4c 72 75 50  rt( pPage->pLruP
5170: 72 65 76 20 29 3b 0a 20 20 61 73 73 65 72 74 28  rev );.  assert(
5180: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68   sqlite3_mutex_h
5190: 65 6c 64 28 70 50 61 67 65 2d 3e 70 43 61 63 68  eld(pPage->pCach
51a0: 65 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78  e->pGroup->mutex
51b0: 29 20 29 3b 0a 20 20 70 50 61 67 65 2d 3e 70 4c  ) );.  pPage->pL
51c0: 72 75 50 72 65 76 2d 3e 70 4c 72 75 4e 65 78 74  ruPrev->pLruNext
51d0: 20 3d 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65   = pPage->pLruNe
51e0: 78 74 3b 0a 20 20 70 50 61 67 65 2d 3e 70 4c 72  xt;.  pPage->pLr
51f0: 75 4e 65 78 74 2d 3e 70 4c 72 75 50 72 65 76 20  uNext->pLruPrev 
5200: 3d 20 70 50 61 67 65 2d 3e 70 4c 72 75 50 72 65  = pPage->pLruPre
5210: 76 3b 0a 20 20 70 50 61 67 65 2d 3e 70 4c 72 75  v;.  pPage->pLru
5220: 4e 65 78 74 20 3d 20 30 3b 0a 20 20 70 50 61 67  Next = 0;.  pPag
5230: 65 2d 3e 70 4c 72 75 50 72 65 76 20 3d 20 30 3b  e->pLruPrev = 0;
5240: 0a 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65  .  assert( pPage
5250: 2d 3e 69 73 41 6e 63 68 6f 72 3d 3d 30 20 29 3b  ->isAnchor==0 );
5260: 0a 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65  .  assert( pPage
5270: 2d 3e 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70  ->pCache->pGroup
5280: 2d 3e 6c 72 75 2e 69 73 41 6e 63 68 6f 72 3d 3d  ->lru.isAnchor==
5290: 31 20 29 3b 0a 20 20 70 50 61 67 65 2d 3e 70 43  1 );.  pPage->pC
52a0: 61 63 68 65 2d 3e 6e 52 65 63 79 63 6c 61 62 6c  ache->nRecyclabl
52b0: 65 2d 2d 3b 0a 20 20 72 65 74 75 72 6e 20 70 50  e--;.  return pP
52c0: 61 67 65 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 52  age;.}.../*.** R
52d0: 65 6d 6f 76 65 20 74 68 65 20 70 61 67 65 20 73  emove the page s
52e0: 75 70 70 6c 69 65 64 20 61 73 20 61 6e 20 61 72  upplied as an ar
52f0: 67 75 6d 65 6e 74 20 66 72 6f 6d 20 74 68 65 20  gument from the 
5300: 68 61 73 68 20 74 61 62 6c 65 20 0a 2a 2a 20 28  hash table .** (
5310: 50 43 61 63 68 65 31 2e 61 70 48 61 73 68 20 73  PCache1.apHash s
5320: 74 72 75 63 74 75 72 65 29 20 74 68 61 74 20 69  tructure) that i
5330: 74 20 69 73 20 63 75 72 72 65 6e 74 6c 79 20 73  t is currently s
5340: 74 6f 72 65 64 20 69 6e 2e 0a 2a 2a 20 41 6c 73  tored in..** Als
5350: 6f 20 66 72 65 65 20 74 68 65 20 70 61 67 65 20  o free the page 
5360: 69 66 20 66 72 65 65 50 61 67 65 20 69 73 20 74  if freePage is t
5370: 72 75 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 50  rue..**.** The P
5380: 47 72 6f 75 70 20 6d 75 74 65 78 20 6d 75 73 74  Group mutex must
5390: 20 62 65 20 68 65 6c 64 20 77 68 65 6e 20 74 68   be held when th
53a0: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63  is function is c
53b0: 61 6c 6c 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63  alled..*/.static
53c0: 20 76 6f 69 64 20 70 63 61 63 68 65 31 52 65 6d   void pcache1Rem
53d0: 6f 76 65 46 72 6f 6d 48 61 73 68 28 50 67 48 64  oveFromHash(PgHd
53e0: 72 31 20 2a 70 50 61 67 65 2c 20 69 6e 74 20 66  r1 *pPage, int f
53f0: 72 65 65 46 6c 61 67 29 7b 0a 20 20 75 6e 73 69  reeFlag){.  unsi
5400: 67 6e 65 64 20 69 6e 74 20 68 3b 0a 20 20 50 43  gned int h;.  PC
5410: 61 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20  ache1 *pCache = 
5420: 70 50 61 67 65 2d 3e 70 43 61 63 68 65 3b 0a 20  pPage->pCache;. 
5430: 20 50 67 48 64 72 31 20 2a 2a 70 70 3b 0a 0a 20   PgHdr1 **pp;.. 
5440: 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33   assert( sqlite3
5450: 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 43 61 63  _mutex_held(pCac
5460: 68 65 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75 74 65  he->pGroup->mute
5470: 78 29 20 29 3b 0a 20 20 68 20 3d 20 70 50 61 67  x) );.  h = pPag
5480: 65 2d 3e 69 4b 65 79 20 25 20 70 43 61 63 68 65  e->iKey % pCache
5490: 2d 3e 6e 48 61 73 68 3b 0a 20 20 66 6f 72 28 70  ->nHash;.  for(p
54a0: 70 3d 26 70 43 61 63 68 65 2d 3e 61 70 48 61 73  p=&pCache->apHas
54b0: 68 5b 68 5d 3b 20 28 2a 70 70 29 21 3d 70 50 61  h[h]; (*pp)!=pPa
54c0: 67 65 3b 20 70 70 3d 26 28 2a 70 70 29 2d 3e 70  ge; pp=&(*pp)->p
54d0: 4e 65 78 74 29 3b 0a 20 20 2a 70 70 20 3d 20 28  Next);.  *pp = (
54e0: 2a 70 70 29 2d 3e 70 4e 65 78 74 3b 0a 0a 20 20  *pp)->pNext;..  
54f0: 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 2d 2d 3b  pCache->nPage--;
5500: 0a 20 20 69 66 28 20 66 72 65 65 46 6c 61 67 20  .  if( freeFlag 
5510: 29 20 70 63 61 63 68 65 31 46 72 65 65 50 61 67  ) pcache1FreePag
5520: 65 28 70 50 61 67 65 29 3b 0a 7d 0a 0a 2f 2a 0a  e(pPage);.}../*.
5530: 2a 2a 20 49 66 20 74 68 65 72 65 20 61 72 65 20  ** If there are 
5540: 63 75 72 72 65 6e 74 6c 79 20 6d 6f 72 65 20 74  currently more t
5550: 68 61 6e 20 6e 4d 61 78 50 61 67 65 20 70 61 67  han nMaxPage pag
5560: 65 73 20 61 6c 6c 6f 63 61 74 65 64 2c 20 74 72  es allocated, tr
5570: 79 0a 2a 2a 20 74 6f 20 72 65 63 79 63 6c 65 20  y.** to recycle 
5580: 70 61 67 65 73 20 74 6f 20 72 65 64 75 63 65 20  pages to reduce 
5590: 74 68 65 20 6e 75 6d 62 65 72 20 61 6c 6c 6f 63  the number alloc
55a0: 61 74 65 64 20 74 6f 20 6e 4d 61 78 50 61 67 65  ated to nMaxPage
55b0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
55c0: 20 70 63 61 63 68 65 31 45 6e 66 6f 72 63 65 4d   pcache1EnforceM
55d0: 61 78 50 61 67 65 28 50 43 61 63 68 65 31 20 2a  axPage(PCache1 *
55e0: 70 43 61 63 68 65 29 7b 0a 20 20 50 47 72 6f 75  pCache){.  PGrou
55f0: 70 20 2a 70 47 72 6f 75 70 20 3d 20 70 43 61 63  p *pGroup = pCac
5600: 68 65 2d 3e 70 47 72 6f 75 70 3b 0a 20 20 50 67  he->pGroup;.  Pg
5610: 48 64 72 31 20 2a 70 3b 0a 20 20 61 73 73 65 72  Hdr1 *p;.  asser
5620: 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78  t( sqlite3_mutex
5630: 5f 68 65 6c 64 28 70 47 72 6f 75 70 2d 3e 6d 75  _held(pGroup->mu
5640: 74 65 78 29 20 29 3b 0a 20 20 77 68 69 6c 65 28  tex) );.  while(
5650: 20 70 47 72 6f 75 70 2d 3e 6e 43 75 72 72 65 6e   pGroup->nCurren
5660: 74 50 61 67 65 3e 70 47 72 6f 75 70 2d 3e 6e 4d  tPage>pGroup->nM
5670: 61 78 50 61 67 65 0a 20 20 20 20 20 20 26 26 20  axPage.      && 
5680: 28 70 3d 70 47 72 6f 75 70 2d 3e 6c 72 75 2e 70  (p=pGroup->lru.p
5690: 4c 72 75 50 72 65 76 29 2d 3e 69 73 41 6e 63 68  LruPrev)->isAnch
56a0: 6f 72 3d 3d 30 0a 20 20 29 7b 0a 20 20 20 20 61  or==0.  ){.    a
56b0: 73 73 65 72 74 28 20 70 2d 3e 70 43 61 63 68 65  ssert( p->pCache
56c0: 2d 3e 70 47 72 6f 75 70 3d 3d 70 47 72 6f 75 70  ->pGroup==pGroup
56d0: 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20   );.    assert( 
56e0: 50 41 47 45 5f 49 53 5f 55 4e 50 49 4e 4e 45 44  PAGE_IS_UNPINNED
56f0: 28 70 29 20 29 3b 0a 20 20 20 20 70 63 61 63 68  (p) );.    pcach
5700: 65 31 50 69 6e 50 61 67 65 28 70 29 3b 0a 20 20  e1PinPage(p);.  
5710: 20 20 70 63 61 63 68 65 31 52 65 6d 6f 76 65 46    pcache1RemoveF
5720: 72 6f 6d 48 61 73 68 28 70 2c 20 31 29 3b 0a 20  romHash(p, 1);. 
5730: 20 7d 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d   }.  if( pCache-
5740: 3e 6e 50 61 67 65 3d 3d 30 20 26 26 20 70 43 61  >nPage==0 && pCa
5750: 63 68 65 2d 3e 70 42 75 6c 6b 20 29 7b 0a 20 20  che->pBulk ){.  
5760: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
5770: 43 61 63 68 65 2d 3e 70 42 75 6c 6b 29 3b 0a 20  Cache->pBulk);. 
5780: 20 20 20 70 43 61 63 68 65 2d 3e 70 42 75 6c 6b     pCache->pBulk
5790: 20 3d 20 70 43 61 63 68 65 2d 3e 70 46 72 65 65   = pCache->pFree
57a0: 20 3d 20 30 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a   = 0;.  }.}../*.
57b0: 2a 2a 20 44 69 73 63 61 72 64 20 61 6c 6c 20 70  ** Discard all p
57c0: 61 67 65 73 20 66 72 6f 6d 20 63 61 63 68 65 20  ages from cache 
57d0: 70 43 61 63 68 65 20 77 69 74 68 20 61 20 70 61  pCache with a pa
57e0: 67 65 20 6e 75 6d 62 65 72 20 28 6b 65 79 20 76  ge number (key v
57f0: 61 6c 75 65 29 20 0a 2a 2a 20 67 72 65 61 74 65  alue) .** greate
5800: 72 20 74 68 61 6e 20 6f 72 20 65 71 75 61 6c 20  r than or equal 
5810: 74 6f 20 69 4c 69 6d 69 74 2e 20 41 6e 79 20 70  to iLimit. Any p
5820: 69 6e 6e 65 64 20 70 61 67 65 73 20 74 68 61 74  inned pages that
5830: 20 6d 65 65 74 20 74 68 69 73 20 0a 2a 2a 20 63   meet this .** c
5840: 72 69 74 65 72 69 61 20 61 72 65 20 75 6e 70 69  riteria are unpi
5850: 6e 6e 65 64 20 62 65 66 6f 72 65 20 74 68 65 79  nned before they
5860: 20 61 72 65 20 64 69 73 63 61 72 64 65 64 2e 0a   are discarded..
5870: 2a 2a 0a 2a 2a 20 54 68 65 20 50 43 61 63 68 65  **.** The PCache
5880: 20 6d 75 74 65 78 20 6d 75 73 74 20 62 65 20 68   mutex must be h
5890: 65 6c 64 20 77 68 65 6e 20 74 68 69 73 20 66 75  eld when this fu
58a0: 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64  nction is called
58b0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
58c0: 20 70 63 61 63 68 65 31 54 72 75 6e 63 61 74 65   pcache1Truncate
58d0: 55 6e 73 61 66 65 28 0a 20 20 50 43 61 63 68 65  Unsafe(.  PCache
58e0: 31 20 2a 70 43 61 63 68 65 2c 20 20 20 20 20 20  1 *pCache,      
58f0: 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 63 61         /* The ca
5900: 63 68 65 20 74 6f 20 74 72 75 6e 63 61 74 65 20  che to truncate 
5910: 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e  */.  unsigned in
5920: 74 20 69 4c 69 6d 69 74 20 20 20 20 20 20 20 20  t iLimit        
5930: 20 20 2f 2a 20 44 72 6f 70 20 70 61 67 65 73 20    /* Drop pages 
5940: 77 69 74 68 20 74 68 69 73 20 70 67 6e 6f 20 6f  with this pgno o
5950: 72 20 6c 61 72 67 65 72 20 2a 2f 0a 29 7b 0a 20  r larger */.){. 
5960: 20 54 45 53 54 4f 4e 4c 59 28 20 69 6e 74 20 6e   TESTONLY( int n
5970: 50 61 67 65 20 3d 20 30 3b 20 29 20 20 2f 2a 20  Page = 0; )  /* 
5980: 54 6f 20 61 73 73 65 72 74 20 70 43 61 63 68 65  To assert pCache
5990: 2d 3e 6e 50 61 67 65 20 69 73 20 63 6f 72 72 65  ->nPage is corre
59a0: 63 74 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64  ct */.  unsigned
59b0: 20 69 6e 74 20 68 2c 20 69 53 74 6f 70 3b 0a 20   int h, iStop;. 
59c0: 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33   assert( sqlite3
59d0: 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 43 61 63  _mutex_held(pCac
59e0: 68 65 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75 74 65  he->pGroup->mute
59f0: 78 29 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  x) );.  assert( 
5a00: 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20  pCache->iMaxKey 
5a10: 3e 3d 20 69 4c 69 6d 69 74 20 29 3b 0a 20 20 61  >= iLimit );.  a
5a20: 73 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e 6e  ssert( pCache->n
5a30: 48 61 73 68 20 3e 20 30 20 29 3b 0a 20 20 69 66  Hash > 0 );.  if
5a40: 28 20 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b 65  ( pCache->iMaxKe
5a50: 79 20 2d 20 69 4c 69 6d 69 74 20 3c 20 70 43 61  y - iLimit < pCa
5a60: 63 68 65 2d 3e 6e 48 61 73 68 20 29 7b 0a 20 20  che->nHash ){.  
5a70: 20 20 2f 2a 20 49 66 20 77 65 20 61 72 65 20 6a    /* If we are j
5a80: 75 73 74 20 73 68 61 76 69 6e 67 20 74 68 65 20  ust shaving the 
5a90: 6c 61 73 74 20 66 65 77 20 70 61 67 65 73 20 6f  last few pages o
5aa0: 66 66 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68  ff the end of th
5ab0: 65 0a 20 20 20 20 2a 2a 20 63 61 63 68 65 2c 20  e.    ** cache, 
5ac0: 74 68 65 6e 20 74 68 65 72 65 20 69 73 20 6e 6f  then there is no
5ad0: 20 70 6f 69 6e 74 20 69 6e 20 73 63 61 6e 6e 69   point in scanni
5ae0: 6e 67 20 74 68 65 20 65 6e 74 69 72 65 20 68 61  ng the entire ha
5af0: 73 68 20 74 61 62 6c 65 2e 0a 20 20 20 20 2a 2a  sh table..    **
5b00: 20 4f 6e 6c 79 20 73 63 61 6e 20 74 68 6f 73 65   Only scan those
5b10: 20 68 61 73 68 20 73 6c 6f 74 73 20 74 68 61 74   hash slots that
5b20: 20 6d 69 67 68 74 20 63 6f 6e 74 61 69 6e 20 70   might contain p
5b30: 61 67 65 73 20 74 68 61 74 20 6e 65 65 64 20 74  ages that need t
5b40: 6f 0a 20 20 20 20 2a 2a 20 62 65 20 72 65 6d 6f  o.    ** be remo
5b50: 76 65 64 2e 20 2a 2f 0a 20 20 20 20 68 20 3d 20  ved. */.    h = 
5b60: 69 4c 69 6d 69 74 20 25 20 70 43 61 63 68 65 2d  iLimit % pCache-
5b70: 3e 6e 48 61 73 68 3b 0a 20 20 20 20 69 53 74 6f  >nHash;.    iSto
5b80: 70 20 3d 20 70 43 61 63 68 65 2d 3e 69 4d 61 78  p = pCache->iMax
5b90: 4b 65 79 20 25 20 70 43 61 63 68 65 2d 3e 6e 48  Key % pCache->nH
5ba0: 61 73 68 3b 0a 20 20 20 20 54 45 53 54 4f 4e 4c  ash;.    TESTONL
5bb0: 59 28 20 6e 50 61 67 65 20 3d 20 2d 31 30 3b 20  Y( nPage = -10; 
5bc0: 29 20 20 2f 2a 20 44 69 73 61 62 6c 65 20 74 68  )  /* Disable th
5bd0: 65 20 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 20  e pCache->nPage 
5be0: 76 61 6c 69 64 69 74 79 20 63 68 65 63 6b 20 2a  validity check *
5bf0: 2f 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 2f  /.  }else{.    /
5c00: 2a 20 54 68 69 73 20 69 73 20 74 68 65 20 67 65  * This is the ge
5c10: 6e 65 72 61 6c 20 63 61 73 65 20 77 68 65 72 65  neral case where
5c20: 20 6d 61 6e 79 20 70 61 67 65 73 20 61 72 65 20   many pages are 
5c30: 62 65 69 6e 67 20 72 65 6d 6f 76 65 64 2e 0a 20  being removed.. 
5c40: 20 20 20 2a 2a 20 49 74 20 69 73 20 6e 65 63 65     ** It is nece
5c50: 73 73 61 72 79 20 74 6f 20 73 63 61 6e 20 74 68  ssary to scan th
5c60: 65 20 65 6e 74 69 72 65 20 68 61 73 68 20 74 61  e entire hash ta
5c70: 62 6c 65 20 2a 2f 0a 20 20 20 20 68 20 3d 20 70  ble */.    h = p
5c80: 43 61 63 68 65 2d 3e 6e 48 61 73 68 2f 32 3b 0a  Cache->nHash/2;.
5c90: 20 20 20 20 69 53 74 6f 70 20 3d 20 68 20 2d 20      iStop = h - 
5ca0: 31 3b 0a 20 20 7d 0a 20 20 66 6f 72 28 3b 3b 29  1;.  }.  for(;;)
5cb0: 7b 0a 20 20 20 20 50 67 48 64 72 31 20 2a 2a 70  {.    PgHdr1 **p
5cc0: 70 3b 0a 20 20 20 20 50 67 48 64 72 31 20 2a 70  p;.    PgHdr1 *p
5cd0: 50 61 67 65 3b 0a 20 20 20 20 61 73 73 65 72 74  Page;.    assert
5ce0: 28 20 68 3c 70 43 61 63 68 65 2d 3e 6e 48 61 73  ( h<pCache->nHas
5cf0: 68 20 29 3b 0a 20 20 20 20 70 70 20 3d 20 26 70  h );.    pp = &p
5d00: 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d  Cache->apHash[h]
5d10: 3b 20 0a 20 20 20 20 77 68 69 6c 65 28 20 28 70  ; .    while( (p
5d20: 50 61 67 65 20 3d 20 2a 70 70 29 21 3d 30 20 29  Page = *pp)!=0 )
5d30: 7b 0a 20 20 20 20 20 20 69 66 28 20 70 50 61 67  {.      if( pPag
5d40: 65 2d 3e 69 4b 65 79 3e 3d 69 4c 69 6d 69 74 20  e->iKey>=iLimit 
5d50: 29 7b 0a 20 20 20 20 20 20 20 20 70 43 61 63 68  ){.        pCach
5d60: 65 2d 3e 6e 50 61 67 65 2d 2d 3b 0a 20 20 20 20  e->nPage--;.    
5d70: 20 20 20 20 2a 70 70 20 3d 20 70 50 61 67 65 2d      *pp = pPage-
5d80: 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 20 20  >pNext;.        
5d90: 69 66 28 20 50 41 47 45 5f 49 53 5f 55 4e 50 49  if( PAGE_IS_UNPI
5da0: 4e 4e 45 44 28 70 50 61 67 65 29 20 29 20 70 63  NNED(pPage) ) pc
5db0: 61 63 68 65 31 50 69 6e 50 61 67 65 28 70 50 61  ache1PinPage(pPa
5dc0: 67 65 29 3b 0a 20 20 20 20 20 20 20 20 70 63 61  ge);.        pca
5dd0: 63 68 65 31 46 72 65 65 50 61 67 65 28 70 50 61  che1FreePage(pPa
5de0: 67 65 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65  ge);.      }else
5df0: 7b 0a 20 20 20 20 20 20 20 20 70 70 20 3d 20 26  {.        pp = &
5e00: 70 50 61 67 65 2d 3e 70 4e 65 78 74 3b 0a 20 20  pPage->pNext;.  
5e10: 20 20 20 20 20 20 54 45 53 54 4f 4e 4c 59 28 20        TESTONLY( 
5e20: 69 66 28 20 6e 50 61 67 65 3e 3d 30 20 29 20 6e  if( nPage>=0 ) n
5e30: 50 61 67 65 2b 2b 3b 20 29 0a 20 20 20 20 20 20  Page++; ).      
5e40: 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20  }.    }.    if( 
5e50: 68 3d 3d 69 53 74 6f 70 20 29 20 62 72 65 61 6b  h==iStop ) break
5e60: 3b 0a 20 20 20 20 68 20 3d 20 28 68 2b 31 29 20  ;.    h = (h+1) 
5e70: 25 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3b  % pCache->nHash;
5e80: 0a 20 20 7d 0a 20 20 61 73 73 65 72 74 28 20 6e  .  }.  assert( n
5e90: 50 61 67 65 3c 30 20 7c 7c 20 70 43 61 63 68 65  Page<0 || pCache
5ea0: 2d 3e 6e 50 61 67 65 3d 3d 28 75 6e 73 69 67 6e  ->nPage==(unsign
5eb0: 65 64 29 6e 50 61 67 65 20 29 3b 0a 7d 0a 0a 2f  ed)nPage );.}../
5ec0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5ed0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5ee0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5ef0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5f00: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a  **************/.
5f10: 2f 2a 2a 2a 2a 2a 2a 2a 2a 20 73 71 6c 69 74 65  /******** sqlite
5f20: 33 5f 70 63 61 63 68 65 20 4d 65 74 68 6f 64 73  3_pcache Methods
5f30: 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a   ***************
5f40: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5f50: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f  ***************/
5f60: 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e  ../*.** Implemen
5f70: 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71  tation of the sq
5f80: 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78 49 6e  lite3_pcache.xIn
5f90: 69 74 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74  it method..*/.st
5fa0: 61 74 69 63 20 69 6e 74 20 70 63 61 63 68 65 31  atic int pcache1
5fb0: 49 6e 69 74 28 76 6f 69 64 20 2a 4e 6f 74 55 73  Init(void *NotUs
5fc0: 65 64 29 7b 0a 20 20 55 4e 55 53 45 44 5f 50 41  ed){.  UNUSED_PA
5fd0: 52 41 4d 45 54 45 52 28 4e 6f 74 55 73 65 64 29  RAMETER(NotUsed)
5fe0: 3b 0a 20 20 61 73 73 65 72 74 28 20 70 63 61 63  ;.  assert( pcac
5ff0: 68 65 31 2e 69 73 49 6e 69 74 3d 3d 30 20 29 3b  he1.isInit==0 );
6000: 0a 20 20 6d 65 6d 73 65 74 28 26 70 63 61 63 68  .  memset(&pcach
6010: 65 31 2c 20 30 2c 20 73 69 7a 65 6f 66 28 70 63  e1, 0, sizeof(pc
6020: 61 63 68 65 31 29 29 3b 0a 0a 0a 20 20 2f 2a 0a  ache1));...  /*.
6030: 20 20 2a 2a 20 54 68 65 20 70 63 61 63 68 65 31    ** The pcache1
6040: 2e 73 65 70 61 72 61 74 65 43 61 63 68 65 20 76  .separateCache v
6050: 61 72 69 61 62 6c 65 20 69 73 20 74 72 75 65 20  ariable is true 
6060: 69 66 20 65 61 63 68 20 50 43 61 63 68 65 20 68  if each PCache h
6070: 61 73 20 69 74 73 20 6f 77 6e 0a 20 20 2a 2a 20  as its own.  ** 
6080: 70 72 69 76 61 74 65 20 50 47 72 6f 75 70 20 28  private PGroup (
6090: 6d 6f 64 65 2d 31 29 2e 20 20 70 63 61 63 68 65  mode-1).  pcache
60a0: 31 2e 73 65 70 61 72 61 74 65 43 61 63 68 65 20  1.separateCache 
60b0: 69 73 20 66 61 6c 73 65 20 69 66 20 74 68 65 20  is false if the 
60c0: 73 69 6e 67 6c 65 0a 20 20 2a 2a 20 50 47 72 6f  single.  ** PGro
60d0: 75 70 20 69 6e 20 70 63 61 63 68 65 31 2e 67 72  up in pcache1.gr
60e0: 70 20 69 73 20 75 73 65 64 20 66 6f 72 20 61 6c  p is used for al
60f0: 6c 20 70 61 67 65 20 63 61 63 68 65 73 20 28 6d  l page caches (m
6100: 6f 64 65 2d 32 29 2e 0a 20 20 2a 2a 0a 20 20 2a  ode-2)..  **.  *
6110: 2a 20 20 20 2a 20 20 41 6c 77 61 79 73 20 75 73  *   *  Always us
6120: 65 20 61 20 75 6e 69 66 69 65 64 20 63 61 63 68  e a unified cach
6130: 65 20 28 6d 6f 64 65 2d 32 29 20 69 66 20 45 4e  e (mode-2) if EN
6140: 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41  ABLE_MEMORY_MANA
6150: 47 45 4d 45 4e 54 0a 20 20 2a 2a 0a 20 20 2a 2a  GEMENT.  **.  **
6160: 20 20 20 2a 20 20 55 73 65 20 61 20 75 6e 69 66     *  Use a unif
6170: 69 65 64 20 63 61 63 68 65 20 69 6e 20 73 69 6e  ied cache in sin
6180: 67 6c 65 2d 74 68 72 65 61 64 65 64 20 61 70 70  gle-threaded app
6190: 6c 69 63 61 74 69 6f 6e 73 20 74 68 61 74 20 68  lications that h
61a0: 61 76 65 0a 20 20 2a 2a 20 20 20 20 20 20 63 6f  ave.  **      co
61b0: 6e 66 69 67 75 72 65 64 20 61 20 73 74 61 72 74  nfigured a start
61c0: 2d 74 69 6d 65 20 62 75 66 66 65 72 20 66 6f 72  -time buffer for
61d0: 20 75 73 65 20 61 73 20 70 61 67 65 2d 63 61 63   use as page-cac
61e0: 68 65 20 6d 65 6d 6f 72 79 20 75 73 69 6e 67 0a  he memory using.
61f0: 20 20 2a 2a 20 20 20 20 20 20 73 71 6c 69 74 65    **      sqlite
6200: 33 5f 63 6f 6e 66 69 67 28 53 51 4c 49 54 45 5f  3_config(SQLITE_
6210: 43 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48 45  CONFIG_PAGECACHE
6220: 2c 20 70 42 75 66 2c 20 73 7a 2c 20 4e 29 20 77  , pBuf, sz, N) w
6230: 69 74 68 20 6e 6f 6e 2d 4e 55 4c 4c 20 0a 20 20  ith non-NULL .  
6240: 2a 2a 20 20 20 20 20 20 70 42 75 66 20 61 72 67  **      pBuf arg
6250: 75 6d 65 6e 74 2e 0a 20 20 2a 2a 0a 20 20 2a 2a  ument..  **.  **
6260: 20 20 20 2a 20 20 4f 74 68 65 72 77 69 73 65 20     *  Otherwise 
6270: 75 73 65 20 73 65 70 61 72 61 74 65 20 63 61 63  use separate cac
6280: 68 65 73 20 28 6d 6f 64 65 2d 31 29 0a 20 20 2a  hes (mode-1).  *
6290: 2f 0a 23 69 66 20 64 65 66 69 6e 65 64 28 53 51  /.#if defined(SQ
62a0: 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f  LITE_ENABLE_MEMO
62b0: 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 29 0a 20  RY_MANAGEMENT). 
62c0: 20 70 63 61 63 68 65 31 2e 73 65 70 61 72 61 74   pcache1.separat
62d0: 65 43 61 63 68 65 20 3d 20 30 3b 0a 23 65 6c 69  eCache = 0;.#eli
62e0: 66 20 53 51 4c 49 54 45 5f 54 48 52 45 41 44 53  f SQLITE_THREADS
62f0: 41 46 45 0a 20 20 70 63 61 63 68 65 31 2e 73 65  AFE.  pcache1.se
6300: 70 61 72 61 74 65 43 61 63 68 65 20 3d 20 73 71  parateCache = sq
6310: 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69  lite3GlobalConfi
6320: 67 2e 70 50 61 67 65 3d 3d 30 0a 20 20 20 20 20  g.pPage==0.     
6330: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6340: 20 20 20 20 20 7c 7c 20 73 71 6c 69 74 65 33 47       || sqlite3G
6350: 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 62 43 6f 72  lobalConfig.bCor
6360: 65 4d 75 74 65 78 3e 30 3b 0a 23 65 6c 73 65 0a  eMutex>0;.#else.
6370: 20 20 70 63 61 63 68 65 31 2e 73 65 70 61 72 61    pcache1.separa
6380: 74 65 43 61 63 68 65 20 3d 20 73 71 6c 69 74 65  teCache = sqlite
6390: 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 50  3GlobalConfig.pP
63a0: 61 67 65 3d 3d 30 3b 0a 23 65 6e 64 69 66 0a 0a  age==0;.#endif..
63b0: 23 69 66 20 53 51 4c 49 54 45 5f 54 48 52 45 41  #if SQLITE_THREA
63c0: 44 53 41 46 45 0a 20 20 69 66 28 20 73 71 6c 69  DSAFE.  if( sqli
63d0: 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e  te3GlobalConfig.
63e0: 62 43 6f 72 65 4d 75 74 65 78 20 29 7b 0a 20 20  bCoreMutex ){.  
63f0: 20 20 70 63 61 63 68 65 31 2e 67 72 70 2e 6d 75    pcache1.grp.mu
6400: 74 65 78 20 3d 20 73 71 6c 69 74 65 33 4d 75 74  tex = sqlite3Mut
6410: 65 78 41 6c 6c 6f 63 28 53 51 4c 49 54 45 5f 4d  exAlloc(SQLITE_M
6420: 55 54 45 58 5f 53 54 41 54 49 43 5f 4c 52 55 29  UTEX_STATIC_LRU)
6430: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 6d 75  ;.    pcache1.mu
6440: 74 65 78 20 3d 20 73 71 6c 69 74 65 33 4d 75 74  tex = sqlite3Mut
6450: 65 78 41 6c 6c 6f 63 28 53 51 4c 49 54 45 5f 4d  exAlloc(SQLITE_M
6460: 55 54 45 58 5f 53 54 41 54 49 43 5f 50 4d 45 4d  UTEX_STATIC_PMEM
6470: 29 3b 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 20 20  );.  }.#endif.  
6480: 69 66 28 20 70 63 61 63 68 65 31 2e 73 65 70 61  if( pcache1.sepa
6490: 72 61 74 65 43 61 63 68 65 0a 20 20 20 26 26 20  rateCache.   && 
64a0: 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e  sqlite3GlobalCon
64b0: 66 69 67 2e 6e 50 61 67 65 21 3d 30 0a 20 20 20  fig.nPage!=0.   
64c0: 26 26 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c  && sqlite3Global
64d0: 43 6f 6e 66 69 67 2e 70 50 61 67 65 3d 3d 30 0a  Config.pPage==0.
64e0: 20 20 29 7b 0a 20 20 20 20 70 63 61 63 68 65 31    ){.    pcache1
64f0: 2e 6e 49 6e 69 74 50 61 67 65 20 3d 20 73 71 6c  .nInitPage = sql
6500: 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67  ite3GlobalConfig
6510: 2e 6e 50 61 67 65 3b 0a 20 20 7d 65 6c 73 65 7b  .nPage;.  }else{
6520: 0a 20 20 20 20 70 63 61 63 68 65 31 2e 6e 49 6e  .    pcache1.nIn
6530: 69 74 50 61 67 65 20 3d 20 30 3b 0a 20 20 7d 0a  itPage = 0;.  }.
6540: 20 20 70 63 61 63 68 65 31 2e 67 72 70 2e 6d 78    pcache1.grp.mx
6550: 50 69 6e 6e 65 64 20 3d 20 31 30 3b 0a 20 20 70  Pinned = 10;.  p
6560: 63 61 63 68 65 31 2e 69 73 49 6e 69 74 20 3d 20  cache1.isInit = 
6570: 31 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  1;.  return SQLI
6580: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  TE_OK;.}../*.** 
6590: 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  Implementation o
65a0: 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63  f the sqlite3_pc
65b0: 61 63 68 65 2e 78 53 68 75 74 64 6f 77 6e 20 6d  ache.xShutdown m
65c0: 65 74 68 6f 64 2e 0a 2a 2a 20 4e 6f 74 65 20 74  ethod..** Note t
65d0: 68 61 74 20 74 68 65 20 73 74 61 74 69 63 20 6d  hat the static m
65e0: 75 74 65 78 20 61 6c 6c 6f 63 61 74 65 64 20 69  utex allocated i
65f0: 6e 20 78 49 6e 69 74 20 64 6f 65 73 20 0a 2a 2a  n xInit does .**
6600: 20 6e 6f 74 20 6e 65 65 64 20 74 6f 20 62 65 20   not need to be 
6610: 66 72 65 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63  freed..*/.static
6620: 20 76 6f 69 64 20 70 63 61 63 68 65 31 53 68 75   void pcache1Shu
6630: 74 64 6f 77 6e 28 76 6f 69 64 20 2a 4e 6f 74 55  tdown(void *NotU
6640: 73 65 64 29 7b 0a 20 20 55 4e 55 53 45 44 5f 50  sed){.  UNUSED_P
6650: 41 52 41 4d 45 54 45 52 28 4e 6f 74 55 73 65 64  ARAMETER(NotUsed
6660: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 63 61  );.  assert( pca
6670: 63 68 65 31 2e 69 73 49 6e 69 74 21 3d 30 20 29  che1.isInit!=0 )
6680: 3b 0a 20 20 6d 65 6d 73 65 74 28 26 70 63 61 63  ;.  memset(&pcac
6690: 68 65 31 2c 20 30 2c 20 73 69 7a 65 6f 66 28 70  he1, 0, sizeof(p
66a0: 63 61 63 68 65 31 29 29 3b 0a 7d 0a 0a 2f 2a 20  cache1));.}../* 
66b0: 66 6f 72 77 61 72 64 20 64 65 63 6c 61 72 61 74  forward declarat
66c0: 69 6f 6e 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ion */.static vo
66d0: 69 64 20 70 63 61 63 68 65 31 44 65 73 74 72 6f  id pcache1Destro
66e0: 79 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  y(sqlite3_pcache
66f0: 20 2a 70 29 3b 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70   *p);../*.** Imp
6700: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74  lementation of t
6710: 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68  he sqlite3_pcach
6720: 65 2e 78 43 72 65 61 74 65 20 6d 65 74 68 6f 64  e.xCreate method
6730: 2e 0a 2a 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65  ..**.** Allocate
6740: 20 61 20 6e 65 77 20 63 61 63 68 65 2e 0a 2a 2f   a new cache..*/
6750: 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65 33 5f  .static sqlite3_
6760: 70 63 61 63 68 65 20 2a 70 63 61 63 68 65 31 43  pcache *pcache1C
6770: 72 65 61 74 65 28 69 6e 74 20 73 7a 50 61 67 65  reate(int szPage
6780: 2c 20 69 6e 74 20 73 7a 45 78 74 72 61 2c 20 69  , int szExtra, i
6790: 6e 74 20 62 50 75 72 67 65 61 62 6c 65 29 7b 0a  nt bPurgeable){.
67a0: 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68    PCache1 *pCach
67b0: 65 3b 20 20 20 20 20 20 2f 2a 20 54 68 65 20 6e  e;      /* The n
67c0: 65 77 6c 79 20 63 72 65 61 74 65 64 20 70 61 67  ewly created pag
67d0: 65 20 63 61 63 68 65 20 2a 2f 0a 20 20 50 47 72  e cache */.  PGr
67e0: 6f 75 70 20 2a 70 47 72 6f 75 70 3b 20 20 20 20  oup *pGroup;    
67f0: 20 20 20 2f 2a 20 54 68 65 20 67 72 6f 75 70 20     /* The group 
6800: 74 68 65 20 6e 65 77 20 70 61 67 65 20 63 61 63  the new page cac
6810: 68 65 20 77 69 6c 6c 20 62 65 6c 6f 6e 67 20 74  he will belong t
6820: 6f 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 3b 20 20  o */.  int sz;  
6830: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
6840: 42 79 74 65 73 20 6f 66 20 6d 65 6d 6f 72 79 20  Bytes of memory 
6850: 72 65 71 75 69 72 65 64 20 74 6f 20 61 6c 6c 6f  required to allo
6860: 63 61 74 65 20 74 68 65 20 6e 65 77 20 63 61 63  cate the new cac
6870: 68 65 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28  he */..  assert(
6880: 20 28 73 7a 50 61 67 65 20 26 20 28 73 7a 50 61   (szPage & (szPa
6890: 67 65 2d 31 29 29 3d 3d 30 20 26 26 20 73 7a 50  ge-1))==0 && szP
68a0: 61 67 65 3e 3d 35 31 32 20 26 26 20 73 7a 50 61  age>=512 && szPa
68b0: 67 65 3c 3d 36 35 35 33 36 20 29 3b 0a 20 20 61  ge<=65536 );.  a
68c0: 73 73 65 72 74 28 20 73 7a 45 78 74 72 61 20 3c  ssert( szExtra <
68d0: 20 33 30 30 20 29 3b 0a 0a 20 20 73 7a 20 3d 20   300 );..  sz = 
68e0: 73 69 7a 65 6f 66 28 50 43 61 63 68 65 31 29 20  sizeof(PCache1) 
68f0: 2b 20 73 69 7a 65 6f 66 28 50 47 72 6f 75 70 29  + sizeof(PGroup)
6900: 2a 70 63 61 63 68 65 31 2e 73 65 70 61 72 61 74  *pcache1.separat
6910: 65 43 61 63 68 65 3b 0a 20 20 70 43 61 63 68 65  eCache;.  pCache
6920: 20 3d 20 28 50 43 61 63 68 65 31 20 2a 29 73 71   = (PCache1 *)sq
6930: 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28  lite3MallocZero(
6940: 73 7a 29 3b 0a 20 20 69 66 28 20 70 43 61 63 68  sz);.  if( pCach
6950: 65 20 29 7b 0a 20 20 20 20 69 66 28 20 70 63 61  e ){.    if( pca
6960: 63 68 65 31 2e 73 65 70 61 72 61 74 65 43 61 63  che1.separateCac
6970: 68 65 20 29 7b 0a 20 20 20 20 20 20 70 47 72 6f  he ){.      pGro
6980: 75 70 20 3d 20 28 50 47 72 6f 75 70 2a 29 26 70  up = (PGroup*)&p
6990: 43 61 63 68 65 5b 31 5d 3b 0a 20 20 20 20 20 20  Cache[1];.      
69a0: 70 47 72 6f 75 70 2d 3e 6d 78 50 69 6e 6e 65 64  pGroup->mxPinned
69b0: 20 3d 20 31 30 3b 0a 20 20 20 20 7d 65 6c 73 65   = 10;.    }else
69c0: 7b 0a 20 20 20 20 20 20 70 47 72 6f 75 70 20 3d  {.      pGroup =
69d0: 20 26 70 63 61 63 68 65 31 2e 67 72 70 3b 0a 20   &pcache1.grp;. 
69e0: 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70 47 72     }.    if( pGr
69f0: 6f 75 70 2d 3e 6c 72 75 2e 69 73 41 6e 63 68 6f  oup->lru.isAncho
6a00: 72 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 70 47  r==0 ){.      pG
6a10: 72 6f 75 70 2d 3e 6c 72 75 2e 69 73 41 6e 63 68  roup->lru.isAnch
6a20: 6f 72 20 3d 20 31 3b 0a 20 20 20 20 20 20 70 47  or = 1;.      pG
6a30: 72 6f 75 70 2d 3e 6c 72 75 2e 70 4c 72 75 50 72  roup->lru.pLruPr
6a40: 65 76 20 3d 20 70 47 72 6f 75 70 2d 3e 6c 72 75  ev = pGroup->lru
6a50: 2e 70 4c 72 75 4e 65 78 74 20 3d 20 26 70 47 72  .pLruNext = &pGr
6a60: 6f 75 70 2d 3e 6c 72 75 3b 0a 20 20 20 20 7d 0a  oup->lru;.    }.
6a70: 20 20 20 20 70 43 61 63 68 65 2d 3e 70 47 72 6f      pCache->pGro
6a80: 75 70 20 3d 20 70 47 72 6f 75 70 3b 0a 20 20 20  up = pGroup;.   
6a90: 20 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 20   pCache->szPage 
6aa0: 3d 20 73 7a 50 61 67 65 3b 0a 20 20 20 20 70 43  = szPage;.    pC
6ab0: 61 63 68 65 2d 3e 73 7a 45 78 74 72 61 20 3d 20  ache->szExtra = 
6ac0: 73 7a 45 78 74 72 61 3b 0a 20 20 20 20 70 43 61  szExtra;.    pCa
6ad0: 63 68 65 2d 3e 73 7a 41 6c 6c 6f 63 20 3d 20 73  che->szAlloc = s
6ae0: 7a 50 61 67 65 20 2b 20 73 7a 45 78 74 72 61 20  zPage + szExtra 
6af0: 2b 20 52 4f 55 4e 44 38 28 73 69 7a 65 6f 66 28  + ROUND8(sizeof(
6b00: 50 67 48 64 72 31 29 29 3b 0a 20 20 20 20 70 43  PgHdr1));.    pC
6b10: 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65  ache->bPurgeable
6b20: 20 3d 20 28 62 50 75 72 67 65 61 62 6c 65 20 3f   = (bPurgeable ?
6b30: 20 31 20 3a 20 30 29 3b 0a 20 20 20 20 70 63 61   1 : 0);.    pca
6b40: 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70  che1EnterMutex(p
6b50: 47 72 6f 75 70 29 3b 0a 20 20 20 20 70 63 61 63  Group);.    pcac
6b60: 68 65 31 52 65 73 69 7a 65 48 61 73 68 28 70 43  he1ResizeHash(pC
6b70: 61 63 68 65 29 3b 0a 20 20 20 20 69 66 28 20 62  ache);.    if( b
6b80: 50 75 72 67 65 61 62 6c 65 20 29 7b 0a 20 20 20  Purgeable ){.   
6b90: 20 20 20 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 20     pCache->nMin 
6ba0: 3d 20 31 30 3b 0a 20 20 20 20 20 20 70 47 72 6f  = 10;.      pGro
6bb0: 75 70 2d 3e 6e 4d 69 6e 50 61 67 65 20 2b 3d 20  up->nMinPage += 
6bc0: 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 3b 0a 20 20  pCache->nMin;.  
6bd0: 20 20 20 20 70 47 72 6f 75 70 2d 3e 6d 78 50 69      pGroup->mxPi
6be0: 6e 6e 65 64 20 3d 20 70 47 72 6f 75 70 2d 3e 6e  nned = pGroup->n
6bf0: 4d 61 78 50 61 67 65 20 2b 20 31 30 20 2d 20 70  MaxPage + 10 - p
6c00: 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67 65 3b  Group->nMinPage;
6c10: 0a 20 20 20 20 7d 0a 20 20 20 20 70 63 61 63 68  .    }.    pcach
6c20: 65 31 4c 65 61 76 65 4d 75 74 65 78 28 70 47 72  e1LeaveMutex(pGr
6c30: 6f 75 70 29 3b 0a 20 20 20 20 69 66 28 20 70 43  oup);.    if( pC
6c40: 61 63 68 65 2d 3e 6e 48 61 73 68 3d 3d 30 20 29  ache->nHash==0 )
6c50: 7b 0a 20 20 20 20 20 20 70 63 61 63 68 65 31 44  {.      pcache1D
6c60: 65 73 74 72 6f 79 28 28 73 71 6c 69 74 65 33 5f  estroy((sqlite3_
6c70: 70 63 61 63 68 65 2a 29 70 43 61 63 68 65 29 3b  pcache*)pCache);
6c80: 0a 20 20 20 20 20 20 70 43 61 63 68 65 20 3d 20  .      pCache = 
6c90: 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72  0;.    }.  }.  r
6ca0: 65 74 75 72 6e 20 28 73 71 6c 69 74 65 33 5f 70  eturn (sqlite3_p
6cb0: 63 61 63 68 65 20 2a 29 70 43 61 63 68 65 3b 0a  cache *)pCache;.
6cc0: 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65  }../*.** Impleme
6cd0: 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73  ntation of the s
6ce0: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78 43  qlite3_pcache.xC
6cf0: 61 63 68 65 73 69 7a 65 20 6d 65 74 68 6f 64 2e  achesize method.
6d00: 20 0a 2a 2a 0a 2a 2a 20 43 6f 6e 66 69 67 75 72   .**.** Configur
6d10: 65 20 74 68 65 20 63 61 63 68 65 5f 73 69 7a 65  e the cache_size
6d20: 20 6c 69 6d 69 74 20 66 6f 72 20 61 20 63 61 63   limit for a cac
6d30: 68 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  he..*/.static vo
6d40: 69 64 20 70 63 61 63 68 65 31 43 61 63 68 65 73  id pcache1Caches
6d50: 69 7a 65 28 73 71 6c 69 74 65 33 5f 70 63 61 63  ize(sqlite3_pcac
6d60: 68 65 20 2a 70 2c 20 69 6e 74 20 6e 4d 61 78 29  he *p, int nMax)
6d70: 7b 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43 61  {.  PCache1 *pCa
6d80: 63 68 65 20 3d 20 28 50 43 61 63 68 65 31 20 2a  che = (PCache1 *
6d90: 29 70 3b 0a 20 20 69 66 28 20 70 43 61 63 68 65  )p;.  if( pCache
6da0: 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 29 7b 0a  ->bPurgeable ){.
6db0: 20 20 20 20 50 47 72 6f 75 70 20 2a 70 47 72 6f      PGroup *pGro
6dc0: 75 70 20 3d 20 70 43 61 63 68 65 2d 3e 70 47 72  up = pCache->pGr
6dd0: 6f 75 70 3b 0a 20 20 20 20 70 63 61 63 68 65 31  oup;.    pcache1
6de0: 45 6e 74 65 72 4d 75 74 65 78 28 70 47 72 6f 75  EnterMutex(pGrou
6df0: 70 29 3b 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e  p);.    pGroup->
6e00: 6e 4d 61 78 50 61 67 65 20 2b 3d 20 28 6e 4d 61  nMaxPage += (nMa
6e10: 78 20 2d 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78  x - pCache->nMax
6e20: 29 3b 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e 6d  );.    pGroup->m
6e30: 78 50 69 6e 6e 65 64 20 3d 20 70 47 72 6f 75 70  xPinned = pGroup
6e40: 2d 3e 6e 4d 61 78 50 61 67 65 20 2b 20 31 30 20  ->nMaxPage + 10 
6e50: 2d 20 70 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61  - pGroup->nMinPa
6e60: 67 65 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e  ge;.    pCache->
6e70: 6e 4d 61 78 20 3d 20 6e 4d 61 78 3b 0a 20 20 20  nMax = nMax;.   
6e80: 20 70 43 61 63 68 65 2d 3e 6e 39 30 70 63 74 20   pCache->n90pct 
6e90: 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 2a 39  = pCache->nMax*9
6ea0: 2f 31 30 3b 0a 20 20 20 20 70 63 61 63 68 65 31  /10;.    pcache1
6eb0: 45 6e 66 6f 72 63 65 4d 61 78 50 61 67 65 28 70  EnforceMaxPage(p
6ec0: 43 61 63 68 65 29 3b 0a 20 20 20 20 70 63 61 63  Cache);.    pcac
6ed0: 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 70 47  he1LeaveMutex(pG
6ee0: 72 6f 75 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a  roup);.  }.}../*
6ef0: 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69  .** Implementati
6f00: 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65  on of the sqlite
6f10: 33 5f 70 63 61 63 68 65 2e 78 53 68 72 69 6e 6b  3_pcache.xShrink
6f20: 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20   method. .**.** 
6f30: 46 72 65 65 20 75 70 20 61 73 20 6d 75 63 68 20  Free up as much 
6f40: 6d 65 6d 6f 72 79 20 61 73 20 70 6f 73 73 69 62  memory as possib
6f50: 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  le..*/.static vo
6f60: 69 64 20 70 63 61 63 68 65 31 53 68 72 69 6e 6b  id pcache1Shrink
6f70: 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20  (sqlite3_pcache 
6f80: 2a 70 29 7b 0a 20 20 50 43 61 63 68 65 31 20 2a  *p){.  PCache1 *
6f90: 70 43 61 63 68 65 20 3d 20 28 50 43 61 63 68 65  pCache = (PCache
6fa0: 31 2a 29 70 3b 0a 20 20 69 66 28 20 70 43 61 63  1*)p;.  if( pCac
6fb0: 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 29  he->bPurgeable )
6fc0: 7b 0a 20 20 20 20 50 47 72 6f 75 70 20 2a 70 47  {.    PGroup *pG
6fd0: 72 6f 75 70 20 3d 20 70 43 61 63 68 65 2d 3e 70  roup = pCache->p
6fe0: 47 72 6f 75 70 3b 0a 20 20 20 20 69 6e 74 20 73  Group;.    int s
6ff0: 61 76 65 64 4d 61 78 50 61 67 65 3b 0a 20 20 20  avedMaxPage;.   
7000: 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74   pcache1EnterMut
7010: 65 78 28 70 47 72 6f 75 70 29 3b 0a 20 20 20 20  ex(pGroup);.    
7020: 73 61 76 65 64 4d 61 78 50 61 67 65 20 3d 20 70  savedMaxPage = p
7030: 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65 3b  Group->nMaxPage;
7040: 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e 6e 4d 61  .    pGroup->nMa
7050: 78 50 61 67 65 20 3d 20 30 3b 0a 20 20 20 20 70  xPage = 0;.    p
7060: 63 61 63 68 65 31 45 6e 66 6f 72 63 65 4d 61 78  cache1EnforceMax
7070: 50 61 67 65 28 70 43 61 63 68 65 29 3b 0a 20 20  Page(pCache);.  
7080: 20 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61    pGroup->nMaxPa
7090: 67 65 20 3d 20 73 61 76 65 64 4d 61 78 50 61 67  ge = savedMaxPag
70a0: 65 3b 0a 20 20 20 20 70 63 61 63 68 65 31 4c 65  e;.    pcache1Le
70b0: 61 76 65 4d 75 74 65 78 28 70 47 72 6f 75 70 29  aveMutex(pGroup)
70c0: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49  ;.  }.}../*.** I
70d0: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66  mplementation of
70e0: 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61   the sqlite3_pca
70f0: 63 68 65 2e 78 50 61 67 65 63 6f 75 6e 74 20 6d  che.xPagecount m
7100: 65 74 68 6f 64 2e 20 0a 2a 2f 0a 73 74 61 74 69  ethod. .*/.stati
7110: 63 20 69 6e 74 20 70 63 61 63 68 65 31 50 61 67  c int pcache1Pag
7120: 65 63 6f 75 6e 74 28 73 71 6c 69 74 65 33 5f 70  ecount(sqlite3_p
7130: 63 61 63 68 65 20 2a 70 29 7b 0a 20 20 69 6e 74  cache *p){.  int
7140: 20 6e 3b 0a 20 20 50 43 61 63 68 65 31 20 2a 70   n;.  PCache1 *p
7150: 43 61 63 68 65 20 3d 20 28 50 43 61 63 68 65 31  Cache = (PCache1
7160: 2a 29 70 3b 0a 20 20 70 63 61 63 68 65 31 45 6e  *)p;.  pcache1En
7170: 74 65 72 4d 75 74 65 78 28 70 43 61 63 68 65 2d  terMutex(pCache-
7180: 3e 70 47 72 6f 75 70 29 3b 0a 20 20 6e 20 3d 20  >pGroup);.  n = 
7190: 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 3b 0a 20  pCache->nPage;. 
71a0: 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74   pcache1LeaveMut
71b0: 65 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75  ex(pCache->pGrou
71c0: 70 29 3b 0a 20 20 72 65 74 75 72 6e 20 6e 3b 0a  p);.  return n;.
71d0: 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d  }.../*.** Implem
71e0: 65 6e 74 20 73 74 65 70 73 20 33 2c 20 34 2c 20  ent steps 3, 4, 
71f0: 61 6e 64 20 35 20 6f 66 20 74 68 65 20 70 63 61  and 5 of the pca
7200: 63 68 65 31 46 65 74 63 68 28 29 20 61 6c 67 6f  che1Fetch() algo
7210: 72 69 74 68 6d 20 64 65 73 63 72 69 62 65 64 0a  rithm described.
7220: 2a 2a 20 69 6e 20 74 68 65 20 68 65 61 64 65 72  ** in the header
7230: 20 6f 66 20 74 68 65 20 70 63 61 63 68 65 31 46   of the pcache1F
7240: 65 74 63 68 28 29 20 70 72 6f 63 65 64 75 72 65  etch() procedure
7250: 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 73 74 65  ..**.** This ste
7260: 70 73 20 61 72 65 20 62 72 6f 6b 65 6e 20 6f 75  ps are broken ou
7270: 74 20 69 6e 74 6f 20 61 20 73 65 70 61 72 61 74  t into a separat
7280: 65 20 70 72 6f 63 65 64 75 72 65 20 62 65 63 61  e procedure beca
7290: 75 73 65 20 74 68 65 79 20 61 72 65 0a 2a 2a 20  use they are.** 
72a0: 75 73 75 61 6c 6c 79 20 6e 6f 74 20 6e 65 65 64  usually not need
72b0: 65 64 2c 20 61 6e 64 20 62 79 20 61 76 6f 69 64  ed, and by avoid
72c0: 69 6e 67 20 74 68 65 20 73 74 61 63 6b 20 69 6e  ing the stack in
72d0: 69 74 69 61 6c 69 7a 61 74 69 6f 6e 20 72 65 71  itialization req
72e0: 75 69 72 65 64 0a 2a 2a 20 66 6f 72 20 74 68 65  uired.** for the
72f0: 73 65 20 73 74 65 70 73 2c 20 74 68 65 20 6d 61  se steps, the ma
7300: 69 6e 20 70 63 61 63 68 65 31 46 65 74 63 68 28  in pcache1Fetch(
7310: 29 20 70 72 6f 63 65 64 75 72 65 20 63 61 6e 20  ) procedure can 
7320: 72 75 6e 20 66 61 73 74 65 72 2e 0a 2a 2f 0a 73  run faster..*/.s
7330: 74 61 74 69 63 20 53 51 4c 49 54 45 5f 4e 4f 49  tatic SQLITE_NOI
7340: 4e 4c 49 4e 45 20 50 67 48 64 72 31 20 2a 70 63  NLINE PgHdr1 *pc
7350: 61 63 68 65 31 46 65 74 63 68 53 74 61 67 65 32  ache1FetchStage2
7360: 28 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43 61  (.  PCache1 *pCa
7370: 63 68 65 2c 20 0a 20 20 75 6e 73 69 67 6e 65 64  che, .  unsigned
7380: 20 69 6e 74 20 69 4b 65 79 2c 20 0a 20 20 69 6e   int iKey, .  in
7390: 74 20 63 72 65 61 74 65 46 6c 61 67 0a 29 7b 0a  t createFlag.){.
73a0: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e    unsigned int n
73b0: 50 69 6e 6e 65 64 3b 0a 20 20 50 47 72 6f 75 70  Pinned;.  PGroup
73c0: 20 2a 70 47 72 6f 75 70 20 3d 20 70 43 61 63 68   *pGroup = pCach
73d0: 65 2d 3e 70 47 72 6f 75 70 3b 0a 20 20 50 67 48  e->pGroup;.  PgH
73e0: 64 72 31 20 2a 70 50 61 67 65 20 3d 20 30 3b 0a  dr1 *pPage = 0;.
73f0: 0a 20 20 2f 2a 20 53 74 65 70 20 33 3a 20 41 62  .  /* Step 3: Ab
7400: 6f 72 74 20 69 66 20 63 72 65 61 74 65 46 6c 61  ort if createFla
7410: 67 20 69 73 20 31 20 62 75 74 20 74 68 65 20 63  g is 1 but the c
7420: 61 63 68 65 20 69 73 20 6e 65 61 72 6c 79 20 66  ache is nearly f
7430: 75 6c 6c 20 2a 2f 0a 20 20 61 73 73 65 72 74 28  ull */.  assert(
7440: 20 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 20 3e   pCache->nPage >
7450: 3d 20 70 43 61 63 68 65 2d 3e 6e 52 65 63 79 63  = pCache->nRecyc
7460: 6c 61 62 6c 65 20 29 3b 0a 20 20 6e 50 69 6e 6e  lable );.  nPinn
7470: 65 64 20 3d 20 70 43 61 63 68 65 2d 3e 6e 50 61  ed = pCache->nPa
7480: 67 65 20 2d 20 70 43 61 63 68 65 2d 3e 6e 52 65  ge - pCache->nRe
7490: 63 79 63 6c 61 62 6c 65 3b 0a 20 20 61 73 73 65  cyclable;.  asse
74a0: 72 74 28 20 70 47 72 6f 75 70 2d 3e 6d 78 50 69  rt( pGroup->mxPi
74b0: 6e 6e 65 64 20 3d 3d 20 70 47 72 6f 75 70 2d 3e  nned == pGroup->
74c0: 6e 4d 61 78 50 61 67 65 20 2b 20 31 30 20 2d 20  nMaxPage + 10 - 
74d0: 70 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67 65  pGroup->nMinPage
74e0: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 43   );.  assert( pC
74f0: 61 63 68 65 2d 3e 6e 39 30 70 63 74 20 3d 3d 20  ache->n90pct == 
7500: 70 43 61 63 68 65 2d 3e 6e 4d 61 78 2a 39 2f 31  pCache->nMax*9/1
7510: 30 20 29 3b 0a 20 20 69 66 28 20 63 72 65 61 74  0 );.  if( creat
7520: 65 46 6c 61 67 3d 3d 31 20 26 26 20 28 0a 20 20  eFlag==1 && (.  
7530: 20 20 20 20 20 20 6e 50 69 6e 6e 65 64 3e 3d 70        nPinned>=p
7540: 47 72 6f 75 70 2d 3e 6d 78 50 69 6e 6e 65 64 0a  Group->mxPinned.
7550: 20 20 20 20 20 7c 7c 20 6e 50 69 6e 6e 65 64 3e       || nPinned>
7560: 3d 70 43 61 63 68 65 2d 3e 6e 39 30 70 63 74 0a  =pCache->n90pct.
7570: 20 20 20 20 20 7c 7c 20 28 70 63 61 63 68 65 31       || (pcache1
7580: 55 6e 64 65 72 4d 65 6d 6f 72 79 50 72 65 73 73  UnderMemoryPress
7590: 75 72 65 28 70 43 61 63 68 65 29 20 26 26 20 70  ure(pCache) && p
75a0: 43 61 63 68 65 2d 3e 6e 52 65 63 79 63 6c 61 62  Cache->nRecyclab
75b0: 6c 65 3c 6e 50 69 6e 6e 65 64 29 0a 20 20 29 29  le<nPinned).  ))
75c0: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a  {.    return 0;.
75d0: 20 20 7d 0a 0a 20 20 69 66 28 20 70 43 61 63 68    }..  if( pCach
75e0: 65 2d 3e 6e 50 61 67 65 3e 3d 70 43 61 63 68 65  e->nPage>=pCache
75f0: 2d 3e 6e 48 61 73 68 20 29 20 70 63 61 63 68 65  ->nHash ) pcache
7600: 31 52 65 73 69 7a 65 48 61 73 68 28 70 43 61 63  1ResizeHash(pCac
7610: 68 65 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70  he);.  assert( p
7620: 43 61 63 68 65 2d 3e 6e 48 61 73 68 3e 30 20 26  Cache->nHash>0 &
7630: 26 20 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68  & pCache->apHash
7640: 20 29 3b 0a 0a 20 20 2f 2a 20 53 74 65 70 20 34   );..  /* Step 4
7650: 2e 20 54 72 79 20 74 6f 20 72 65 63 79 63 6c 65  . Try to recycle
7660: 20 61 20 70 61 67 65 2e 20 2a 2f 0a 20 20 69 66   a page. */.  if
7670: 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65  ( pCache->bPurge
7680: 61 62 6c 65 0a 20 20 20 26 26 20 21 70 47 72 6f  able.   && !pGro
7690: 75 70 2d 3e 6c 72 75 2e 70 4c 72 75 50 72 65 76  up->lru.pLruPrev
76a0: 2d 3e 69 73 41 6e 63 68 6f 72 0a 20 20 20 26 26  ->isAnchor.   &&
76b0: 20 28 28 70 43 61 63 68 65 2d 3e 6e 50 61 67 65   ((pCache->nPage
76c0: 2b 31 3e 3d 70 43 61 63 68 65 2d 3e 6e 4d 61 78  +1>=pCache->nMax
76d0: 29 20 7c 7c 20 70 63 61 63 68 65 31 55 6e 64 65  ) || pcache1Unde
76e0: 72 4d 65 6d 6f 72 79 50 72 65 73 73 75 72 65 28  rMemoryPressure(
76f0: 70 43 61 63 68 65 29 29 0a 20 20 29 7b 0a 20 20  pCache)).  ){.  
7700: 20 20 50 43 61 63 68 65 31 20 2a 70 4f 74 68 65    PCache1 *pOthe
7710: 72 3b 0a 20 20 20 20 70 50 61 67 65 20 3d 20 70  r;.    pPage = p
7720: 47 72 6f 75 70 2d 3e 6c 72 75 2e 70 4c 72 75 50  Group->lru.pLruP
7730: 72 65 76 3b 0a 20 20 20 20 61 73 73 65 72 74 28  rev;.    assert(
7740: 20 50 41 47 45 5f 49 53 5f 55 4e 50 49 4e 4e 45   PAGE_IS_UNPINNE
7750: 44 28 70 50 61 67 65 29 20 29 3b 0a 20 20 20 20  D(pPage) );.    
7760: 70 63 61 63 68 65 31 52 65 6d 6f 76 65 46 72 6f  pcache1RemoveFro
7770: 6d 48 61 73 68 28 70 50 61 67 65 2c 20 30 29 3b  mHash(pPage, 0);
7780: 0a 20 20 20 20 70 63 61 63 68 65 31 50 69 6e 50  .    pcache1PinP
7790: 61 67 65 28 70 50 61 67 65 29 3b 0a 20 20 20 20  age(pPage);.    
77a0: 70 4f 74 68 65 72 20 3d 20 70 50 61 67 65 2d 3e  pOther = pPage->
77b0: 70 43 61 63 68 65 3b 0a 20 20 20 20 69 66 28 20  pCache;.    if( 
77c0: 70 4f 74 68 65 72 2d 3e 73 7a 41 6c 6c 6f 63 20  pOther->szAlloc 
77d0: 21 3d 20 70 43 61 63 68 65 2d 3e 73 7a 41 6c 6c  != pCache->szAll
77e0: 6f 63 20 29 7b 0a 20 20 20 20 20 20 70 63 61 63  oc ){.      pcac
77f0: 68 65 31 46 72 65 65 50 61 67 65 28 70 50 61 67  he1FreePage(pPag
7800: 65 29 3b 0a 20 20 20 20 20 20 70 50 61 67 65 20  e);.      pPage 
7810: 3d 20 30 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  = 0;.    }else{.
7820: 20 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 6e 43        pGroup->nC
7830: 75 72 72 65 6e 74 50 61 67 65 20 2d 3d 20 28 70  urrentPage -= (p
7840: 4f 74 68 65 72 2d 3e 62 50 75 72 67 65 61 62 6c  Other->bPurgeabl
7850: 65 20 2d 20 70 43 61 63 68 65 2d 3e 62 50 75 72  e - pCache->bPur
7860: 67 65 61 62 6c 65 29 3b 0a 20 20 20 20 7d 0a 20  geable);.    }. 
7870: 20 7d 0a 0a 20 20 2f 2a 20 53 74 65 70 20 35 2e   }..  /* Step 5.
7880: 20 49 66 20 61 20 75 73 61 62 6c 65 20 70 61 67   If a usable pag
7890: 65 20 62 75 66 66 65 72 20 68 61 73 20 73 74 69  e buffer has sti
78a0: 6c 6c 20 6e 6f 74 20 62 65 65 6e 20 66 6f 75 6e  ll not been foun
78b0: 64 2c 20 0a 20 20 2a 2a 20 61 74 74 65 6d 70 74  d, .  ** attempt
78c0: 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e   to allocate a n
78d0: 65 77 20 6f 6e 65 2e 20 0a 20 20 2a 2f 0a 20 20  ew one. .  */.  
78e0: 69 66 28 20 21 70 50 61 67 65 20 29 7b 0a 20 20  if( !pPage ){.  
78f0: 20 20 70 50 61 67 65 20 3d 20 70 63 61 63 68 65    pPage = pcache
7900: 31 41 6c 6c 6f 63 50 61 67 65 28 70 43 61 63 68  1AllocPage(pCach
7910: 65 2c 20 63 72 65 61 74 65 46 6c 61 67 3d 3d 31  e, createFlag==1
7920: 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 50  );.  }..  if( pP
7930: 61 67 65 20 29 7b 0a 20 20 20 20 75 6e 73 69 67  age ){.    unsig
7940: 6e 65 64 20 69 6e 74 20 68 20 3d 20 69 4b 65 79  ned int h = iKey
7950: 20 25 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68   % pCache->nHash
7960: 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 6e 50  ;.    pCache->nP
7970: 61 67 65 2b 2b 3b 0a 20 20 20 20 70 50 61 67 65  age++;.    pPage
7980: 2d 3e 69 4b 65 79 20 3d 20 69 4b 65 79 3b 0a 20  ->iKey = iKey;. 
7990: 20 20 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 20     pPage->pNext 
79a0: 3d 20 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68  = pCache->apHash
79b0: 5b 68 5d 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e  [h];.    pPage->
79c0: 70 43 61 63 68 65 20 3d 20 70 43 61 63 68 65 3b  pCache = pCache;
79d0: 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 4c 72 75  .    pPage->pLru
79e0: 50 72 65 76 20 3d 20 30 3b 0a 20 20 20 20 70 50  Prev = 0;.    pP
79f0: 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 20 3d 20  age->pLruNext = 
7a00: 30 3b 0a 20 20 20 20 2a 28 76 6f 69 64 20 2a 2a  0;.    *(void **
7a10: 29 70 50 61 67 65 2d 3e 70 61 67 65 2e 70 45 78  )pPage->page.pEx
7a20: 74 72 61 20 3d 20 30 3b 0a 20 20 20 20 70 43 61  tra = 0;.    pCa
7a30: 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 20 3d  che->apHash[h] =
7a40: 20 70 50 61 67 65 3b 0a 20 20 20 20 69 66 28 20   pPage;.    if( 
7a50: 69 4b 65 79 3e 70 43 61 63 68 65 2d 3e 69 4d 61  iKey>pCache->iMa
7a60: 78 4b 65 79 20 29 7b 0a 20 20 20 20 20 20 70 43  xKey ){.      pC
7a70: 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 3d 20  ache->iMaxKey = 
7a80: 69 4b 65 79 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  iKey;.    }.  }.
7a90: 20 20 72 65 74 75 72 6e 20 70 50 61 67 65 3b 0a    return pPage;.
7aa0: 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65  }../*.** Impleme
7ab0: 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73  ntation of the s
7ac0: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78 46  qlite3_pcache.xF
7ad0: 65 74 63 68 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a  etch method. .**
7ae0: 0a 2a 2a 20 46 65 74 63 68 20 61 20 70 61 67 65  .** Fetch a page
7af0: 20 62 79 20 6b 65 79 20 76 61 6c 75 65 2e 0a 2a   by key value..*
7b00: 2a 0a 2a 2a 20 57 68 65 74 68 65 72 20 6f 72 20  *.** Whether or 
7b10: 6e 6f 74 20 61 20 6e 65 77 20 70 61 67 65 20 6d  not a new page m
7b20: 61 79 20 62 65 20 61 6c 6c 6f 63 61 74 65 64 20  ay be allocated 
7b30: 62 79 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  by this function
7b40: 20 64 65 70 65 6e 64 73 20 6f 6e 0a 2a 2a 20 74   depends on.** t
7b50: 68 65 20 76 61 6c 75 65 20 6f 66 20 74 68 65 20  he value of the 
7b60: 63 72 65 61 74 65 46 6c 61 67 20 61 72 67 75 6d  createFlag argum
7b70: 65 6e 74 2e 20 20 30 20 6d 65 61 6e 73 20 64 6f  ent.  0 means do
7b80: 20 6e 6f 74 20 61 6c 6c 6f 63 61 74 65 20 61 20   not allocate a 
7b90: 6e 65 77 0a 2a 2a 20 70 61 67 65 2e 20 20 31 20  new.** page.  1 
7ba0: 6d 65 61 6e 73 20 61 6c 6c 6f 63 61 74 65 20 61  means allocate a
7bb0: 20 6e 65 77 20 70 61 67 65 20 69 66 20 73 70 61   new page if spa
7bc0: 63 65 20 69 73 20 65 61 73 69 6c 79 20 61 76 61  ce is easily ava
7bd0: 69 6c 61 62 6c 65 2e 20 20 32 20 0a 2a 2a 20 6d  ilable.  2 .** m
7be0: 65 61 6e 73 20 74 6f 20 74 72 79 20 72 65 61 6c  eans to try real
7bf0: 6c 79 20 68 61 72 64 20 74 6f 20 61 6c 6c 6f 63  ly hard to alloc
7c00: 61 74 65 20 61 20 6e 65 77 20 70 61 67 65 2e 0a  ate a new page..
7c10: 2a 2a 0a 2a 2a 20 46 6f 72 20 61 20 6e 6f 6e 2d  **.** For a non-
7c20: 70 75 72 67 65 61 62 6c 65 20 63 61 63 68 65 20  purgeable cache 
7c30: 28 61 20 63 61 63 68 65 20 75 73 65 64 20 61 73  (a cache used as
7c40: 20 74 68 65 20 73 74 6f 72 61 67 65 20 66 6f 72   the storage for
7c50: 20 61 6e 20 69 6e 2d 6d 65 6d 6f 72 79 0a 2a 2a   an in-memory.**
7c60: 20 64 61 74 61 62 61 73 65 29 20 74 68 65 72 65   database) there
7c70: 20 69 73 20 72 65 61 6c 6c 79 20 6e 6f 20 64 69   is really no di
7c80: 66 66 65 72 65 6e 63 65 20 62 65 74 77 65 65 6e  fference between
7c90: 20 63 72 65 61 74 65 46 6c 61 67 20 31 20 61 6e   createFlag 1 an
7ca0: 64 20 32 2e 20 20 53 6f 0a 2a 2a 20 74 68 65 20  d 2.  So.** the 
7cb0: 63 61 6c 6c 69 6e 67 20 66 75 6e 63 74 69 6f 6e  calling function
7cc0: 20 28 70 63 61 63 68 65 2e 63 29 20 77 69 6c 6c   (pcache.c) will
7cd0: 20 6e 65 76 65 72 20 68 61 76 65 20 61 20 63 72   never have a cr
7ce0: 65 61 74 65 46 6c 61 67 20 6f 66 20 31 20 6f 6e  eateFlag of 1 on
7cf0: 0a 2a 2a 20 61 20 6e 6f 6e 2d 70 75 72 67 65 61  .** a non-purgea
7d00: 62 6c 65 20 63 61 63 68 65 2e 0a 2a 2a 0a 2a 2a  ble cache..**.**
7d10: 20 54 68 65 72 65 20 61 72 65 20 74 68 72 65 65   There are three
7d20: 20 64 69 66 66 65 72 65 6e 74 20 61 70 70 72 6f   different appro
7d30: 61 63 68 65 73 20 74 6f 20 6f 62 74 61 69 6e 69  aches to obtaini
7d40: 6e 67 20 73 70 61 63 65 20 66 6f 72 20 61 20 70  ng space for a p
7d50: 61 67 65 2c 0a 2a 2a 20 64 65 70 65 6e 64 69 6e  age,.** dependin
7d60: 67 20 6f 6e 20 74 68 65 20 76 61 6c 75 65 20 6f  g on the value o
7d70: 66 20 70 61 72 61 6d 65 74 65 72 20 63 72 65 61  f parameter crea
7d80: 74 65 46 6c 61 67 20 28 77 68 69 63 68 20 6d 61  teFlag (which ma
7d90: 79 20 62 65 20 30 2c 20 31 20 6f 72 20 32 29 2e  y be 0, 1 or 2).
7da0: 0a 2a 2a 0a 2a 2a 20 20 20 31 2e 20 52 65 67 61  .**.**   1. Rega
7db0: 72 64 6c 65 73 73 20 6f 66 20 74 68 65 20 76 61  rdless of the va
7dc0: 6c 75 65 20 6f 66 20 63 72 65 61 74 65 46 6c 61  lue of createFla
7dd0: 67 2c 20 74 68 65 20 63 61 63 68 65 20 69 73 20  g, the cache is 
7de0: 73 65 61 72 63 68 65 64 20 66 6f 72 20 61 20 0a  searched for a .
7df0: 2a 2a 20 20 20 20 20 20 63 6f 70 79 20 6f 66 20  **      copy of 
7e00: 74 68 65 20 72 65 71 75 65 73 74 65 64 20 70 61  the requested pa
7e10: 67 65 2e 20 49 66 20 6f 6e 65 20 69 73 20 66 6f  ge. If one is fo
7e20: 75 6e 64 2c 20 69 74 20 69 73 20 72 65 74 75 72  und, it is retur
7e30: 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 32 2e 20  ned..**.**   2. 
7e40: 49 66 20 63 72 65 61 74 65 46 6c 61 67 3d 3d 30  If createFlag==0
7e50: 20 61 6e 64 20 74 68 65 20 70 61 67 65 20 69 73   and the page is
7e60: 20 6e 6f 74 20 61 6c 72 65 61 64 79 20 69 6e 20   not already in 
7e70: 74 68 65 20 63 61 63 68 65 2c 20 4e 55 4c 4c 20  the cache, NULL 
7e80: 69 73 0a 2a 2a 20 20 20 20 20 20 72 65 74 75 72  is.**      retur
7e90: 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 33 2e 20  ned..**.**   3. 
7ea0: 49 66 20 63 72 65 61 74 65 46 6c 61 67 20 69 73  If createFlag is
7eb0: 20 31 2c 20 61 6e 64 20 74 68 65 20 70 61 67 65   1, and the page
7ec0: 20 69 73 20 6e 6f 74 20 61 6c 72 65 61 64 79 20   is not already 
7ed0: 69 6e 20 74 68 65 20 63 61 63 68 65 2c 20 74 68  in the cache, th
7ee0: 65 6e 0a 2a 2a 20 20 20 20 20 20 72 65 74 75 72  en.**      retur
7ef0: 6e 20 4e 55 4c 4c 20 28 64 6f 20 6e 6f 74 20 61  n NULL (do not a
7f00: 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 70 61  llocate a new pa
7f10: 67 65 29 20 69 66 20 61 6e 79 20 6f 66 20 74 68  ge) if any of th
7f20: 65 20 66 6f 6c 6c 6f 77 69 6e 67 0a 2a 2a 20 20  e following.**  
7f30: 20 20 20 20 63 6f 6e 64 69 74 69 6f 6e 73 20 61      conditions a
7f40: 72 65 20 74 72 75 65 3a 0a 2a 2a 0a 2a 2a 20 20  re true:.**.**  
7f50: 20 20 20 20 20 28 61 29 20 74 68 65 20 6e 75 6d       (a) the num
7f60: 62 65 72 20 6f 66 20 70 61 67 65 73 20 70 69 6e  ber of pages pin
7f70: 6e 65 64 20 62 79 20 74 68 65 20 63 61 63 68 65  ned by the cache
7f80: 20 69 73 20 67 72 65 61 74 65 72 20 74 68 61 6e   is greater than
7f90: 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 50 43  .**           PC
7fa0: 61 63 68 65 31 2e 6e 4d 61 78 2c 20 6f 72 0a 2a  ache1.nMax, or.*
7fb0: 2a 0a 2a 2a 20 20 20 20 20 20 20 28 62 29 20 74  *.**       (b) t
7fc0: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67  he number of pag
7fd0: 65 73 20 70 69 6e 6e 65 64 20 62 79 20 74 68 65  es pinned by the
7fe0: 20 63 61 63 68 65 20 69 73 20 67 72 65 61 74 65   cache is greate
7ff0: 72 20 74 68 61 6e 0a 2a 2a 20 20 20 20 20 20 20  r than.**       
8000: 20 20 20 20 74 68 65 20 73 75 6d 20 6f 66 20 6e      the sum of n
8010: 4d 61 78 20 66 6f 72 20 61 6c 6c 20 70 75 72 67  Max for all purg
8020: 65 61 62 6c 65 20 63 61 63 68 65 73 2c 20 6c 65  eable caches, le
8030: 73 73 20 74 68 65 20 73 75 6d 20 6f 66 20 0a 2a  ss the sum of .*
8040: 2a 20 20 20 20 20 20 20 20 20 20 20 6e 4d 69 6e  *           nMin
8050: 20 66 6f 72 20 61 6c 6c 20 6f 74 68 65 72 20 70   for all other p
8060: 75 72 67 65 61 62 6c 65 20 63 61 63 68 65 73 2c  urgeable caches,
8070: 20 6f 72 0a 2a 2a 0a 2a 2a 20 20 20 34 2e 20 49   or.**.**   4. I
8080: 66 20 6e 6f 6e 65 20 6f 66 20 74 68 65 20 66 69  f none of the fi
8090: 72 73 74 20 74 68 72 65 65 20 63 6f 6e 64 69 74  rst three condit
80a0: 69 6f 6e 73 20 61 70 70 6c 79 20 61 6e 64 20 74  ions apply and t
80b0: 68 65 20 63 61 63 68 65 20 69 73 20 6d 61 72 6b  he cache is mark
80c0: 65 64 0a 2a 2a 20 20 20 20 20 20 61 73 20 70 75  ed.**      as pu
80d0: 72 67 65 61 62 6c 65 2c 20 61 6e 64 20 69 66 20  rgeable, and if 
80e0: 6f 6e 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f  one of the follo
80f0: 77 69 6e 67 20 69 73 20 74 72 75 65 3a 0a 2a 2a  wing is true:.**
8100: 0a 2a 2a 20 20 20 20 20 20 20 28 61 29 20 54 68  .**       (a) Th
8110: 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65  e number of page
8120: 73 20 61 6c 6c 6f 63 61 74 65 64 20 66 6f 72 20  s allocated for 
8130: 74 68 65 20 63 61 63 68 65 20 69 73 20 61 6c 72  the cache is alr
8140: 65 61 64 79 20 0a 2a 2a 20 20 20 20 20 20 20 20  eady .**        
8150: 20 20 20 50 43 61 63 68 65 31 2e 6e 4d 61 78 2c     PCache1.nMax,
8160: 20 6f 72 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20   or.**.**       
8170: 28 62 29 20 54 68 65 20 6e 75 6d 62 65 72 20 6f  (b) The number o
8180: 66 20 70 61 67 65 73 20 61 6c 6c 6f 63 61 74 65  f pages allocate
8190: 64 20 66 6f 72 20 61 6c 6c 20 70 75 72 67 65 61  d for all purgea
81a0: 62 6c 65 20 63 61 63 68 65 73 20 69 73 0a 2a 2a  ble caches is.**
81b0: 20 20 20 20 20 20 20 20 20 20 20 61 6c 72 65 61             alrea
81c0: 64 79 20 65 71 75 61 6c 20 74 6f 20 6f 72 20 67  dy equal to or g
81d0: 72 65 61 74 65 72 20 74 68 61 6e 20 74 68 65 20  reater than the 
81e0: 73 75 6d 20 6f 66 20 6e 4d 61 78 20 66 6f 72 20  sum of nMax for 
81f0: 61 6c 6c 0a 2a 2a 20 20 20 20 20 20 20 20 20 20  all.**          
8200: 20 70 75 72 67 65 61 62 6c 65 20 63 61 63 68 65   purgeable cache
8210: 73 2c 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 28  s,.**.**       (
8220: 63 29 20 54 68 65 20 73 79 73 74 65 6d 20 69 73  c) The system is
8230: 20 75 6e 64 65 72 20 6d 65 6d 6f 72 79 20 70 72   under memory pr
8240: 65 73 73 75 72 65 20 61 6e 64 20 77 61 6e 74 73  essure and wants
8250: 20 74 6f 20 61 76 6f 69 64 0a 2a 2a 20 20 20 20   to avoid.**    
8260: 20 20 20 20 20 20 20 75 6e 6e 65 63 65 73 73 61         unnecessa
8270: 72 79 20 70 61 67 65 73 20 63 61 63 68 65 20 65  ry pages cache e
8280: 6e 74 72 79 20 61 6c 6c 6f 63 61 74 69 6f 6e 73  ntry allocations
8290: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 74 68 65 6e  .**.**      then
82a0: 20 61 74 74 65 6d 70 74 20 74 6f 20 72 65 63 79   attempt to recy
82b0: 63 6c 65 20 61 20 70 61 67 65 20 66 72 6f 6d 20  cle a page from 
82c0: 74 68 65 20 4c 52 55 20 6c 69 73 74 2e 20 49 66  the LRU list. If
82d0: 20 69 74 20 69 73 20 74 68 65 20 72 69 67 68 74   it is the right
82e0: 0a 2a 2a 20 20 20 20 20 20 73 69 7a 65 2c 20 72  .**      size, r
82f0: 65 74 75 72 6e 20 74 68 65 20 72 65 63 79 63 6c  eturn the recycl
8300: 65 64 20 62 75 66 66 65 72 2e 20 4f 74 68 65 72  ed buffer. Other
8310: 77 69 73 65 2c 20 66 72 65 65 20 74 68 65 20 62  wise, free the b
8320: 75 66 66 65 72 20 61 6e 64 0a 2a 2a 20 20 20 20  uffer and.**    
8330: 20 20 70 72 6f 63 65 65 64 20 74 6f 20 73 74 65    proceed to ste
8340: 70 20 35 2e 20 0a 2a 2a 0a 2a 2a 20 20 20 35 2e  p 5. .**.**   5.
8350: 20 4f 74 68 65 72 77 69 73 65 2c 20 61 6c 6c 6f   Otherwise, allo
8360: 63 61 74 65 20 61 6e 64 20 72 65 74 75 72 6e 20  cate and return 
8370: 61 20 6e 65 77 20 70 61 67 65 20 62 75 66 66 65  a new page buffe
8380: 72 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 72 65 20 61  r..**.** There a
8390: 72 65 20 74 77 6f 20 76 65 72 73 69 6f 6e 73 20  re two versions 
83a0: 6f 66 20 74 68 69 73 20 72 6f 75 74 69 6e 65 2e  of this routine.
83b0: 20 20 70 63 61 63 68 65 31 46 65 74 63 68 57 69    pcache1FetchWi
83c0: 74 68 4d 75 74 65 78 28 29 20 69 73 0a 2a 2a 20  thMutex() is.** 
83d0: 74 68 65 20 67 65 6e 65 72 61 6c 20 63 61 73 65  the general case
83e0: 2e 20 20 70 63 61 63 68 65 31 46 65 74 63 68 4e  .  pcache1FetchN
83f0: 6f 4d 75 74 65 78 28 29 20 69 73 20 61 20 66 61  oMutex() is a fa
8400: 73 74 65 72 20 69 6d 70 6c 65 6d 65 6e 74 61 74  ster implementat
8410: 69 6f 6e 20 66 6f 72 0a 2a 2a 20 74 68 65 20 63  ion for.** the c
8420: 6f 6d 6d 6f 6e 20 63 61 73 65 20 77 68 65 72 65  ommon case where
8430: 20 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78 20 69   pGroup->mutex i
8440: 73 20 4e 55 4c 4c 2e 20 20 54 68 65 20 70 63 61  s NULL.  The pca
8450: 63 68 65 31 46 65 74 63 68 28 29 20 77 72 61 70  che1Fetch() wrap
8460: 70 65 72 0a 2a 2a 20 69 6e 76 6f 6b 65 73 20 74  per.** invokes t
8470: 68 65 20 61 70 70 72 6f 70 72 69 61 74 65 20 72  he appropriate r
8480: 6f 75 74 69 6e 65 2e 0a 2a 2f 0a 73 74 61 74 69  outine..*/.stati
8490: 63 20 50 67 48 64 72 31 20 2a 70 63 61 63 68 65  c PgHdr1 *pcache
84a0: 31 46 65 74 63 68 4e 6f 4d 75 74 65 78 28 0a 20  1FetchNoMutex(. 
84b0: 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20   sqlite3_pcache 
84c0: 2a 70 2c 20 0a 20 20 75 6e 73 69 67 6e 65 64 20  *p, .  unsigned 
84d0: 69 6e 74 20 69 4b 65 79 2c 20 0a 20 20 69 6e 74  int iKey, .  int
84e0: 20 63 72 65 61 74 65 46 6c 61 67 0a 29 7b 0a 20   createFlag.){. 
84f0: 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68 65   PCache1 *pCache
8500: 20 3d 20 28 50 43 61 63 68 65 31 20 2a 29 70 3b   = (PCache1 *)p;
8510: 0a 20 20 50 67 48 64 72 31 20 2a 70 50 61 67 65  .  PgHdr1 *pPage
8520: 20 3d 20 30 3b 0a 0a 20 20 2f 2a 20 53 74 65 70   = 0;..  /* Step
8530: 20 31 3a 20 53 65 61 72 63 68 20 74 68 65 20 68   1: Search the h
8540: 61 73 68 20 74 61 62 6c 65 20 66 6f 72 20 61 6e  ash table for an
8550: 20 65 78 69 73 74 69 6e 67 20 65 6e 74 72 79 2e   existing entry.
8560: 20 2a 2f 0a 20 20 70 50 61 67 65 20 3d 20 70 43   */.  pPage = pC
8570: 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 69 4b 65  ache->apHash[iKe
8580: 79 20 25 20 70 43 61 63 68 65 2d 3e 6e 48 61 73  y % pCache->nHas
8590: 68 5d 3b 0a 20 20 77 68 69 6c 65 28 20 70 50 61  h];.  while( pPa
85a0: 67 65 20 26 26 20 70 50 61 67 65 2d 3e 69 4b 65  ge && pPage->iKe
85b0: 79 21 3d 69 4b 65 79 20 29 7b 20 70 50 61 67 65  y!=iKey ){ pPage
85c0: 20 3d 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 3b   = pPage->pNext;
85d0: 20 7d 0a 0a 20 20 2f 2a 20 53 74 65 70 20 32 3a   }..  /* Step 2:
85e0: 20 49 66 20 74 68 65 20 70 61 67 65 20 77 61 73   If the page was
85f0: 20 66 6f 75 6e 64 20 69 6e 20 74 68 65 20 68 61   found in the ha
8600: 73 68 20 74 61 62 6c 65 2c 20 74 68 65 6e 20 72  sh table, then r
8610: 65 74 75 72 6e 20 69 74 2e 0a 20 20 2a 2a 20 49  eturn it..  ** I
8620: 66 20 74 68 65 20 70 61 67 65 20 77 61 73 20 6e  f the page was n
8630: 6f 74 20 69 6e 20 74 68 65 20 68 61 73 68 20 74  ot in the hash t
8640: 61 62 6c 65 20 61 6e 64 20 63 72 65 61 74 65 46  able and createF
8650: 6c 61 67 20 69 73 20 30 2c 20 61 62 6f 72 74 2e  lag is 0, abort.
8660: 0a 20 20 2a 2a 20 4f 74 68 65 72 77 69 73 65 20  .  ** Otherwise 
8670: 28 70 61 67 65 20 6e 6f 74 20 69 6e 20 68 61 73  (page not in has
8680: 68 20 61 6e 64 20 63 72 65 61 74 65 46 6c 61 67  h and createFlag
8690: 21 3d 30 29 20 63 6f 6e 74 69 6e 75 65 20 77 69  !=0) continue wi
86a0: 74 68 0a 20 20 2a 2a 20 73 75 62 73 65 71 75 65  th.  ** subseque
86b0: 6e 74 20 73 74 65 70 73 20 74 6f 20 74 72 79 20  nt steps to try 
86c0: 74 6f 20 63 72 65 61 74 65 20 74 68 65 20 70 61  to create the pa
86d0: 67 65 2e 20 2a 2f 0a 20 20 69 66 28 20 70 50 61  ge. */.  if( pPa
86e0: 67 65 20 29 7b 0a 20 20 20 20 69 66 28 20 50 41  ge ){.    if( PA
86f0: 47 45 5f 49 53 5f 55 4e 50 49 4e 4e 45 44 28 70  GE_IS_UNPINNED(p
8700: 50 61 67 65 29 20 29 7b 0a 20 20 20 20 20 20 72  Page) ){.      r
8710: 65 74 75 72 6e 20 70 63 61 63 68 65 31 50 69 6e  eturn pcache1Pin
8720: 50 61 67 65 28 70 50 61 67 65 29 3b 0a 20 20 20  Page(pPage);.   
8730: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 72 65   }else{.      re
8740: 74 75 72 6e 20 70 50 61 67 65 3b 0a 20 20 20 20  turn pPage;.    
8750: 7d 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 63 72  }.  }else if( cr
8760: 65 61 74 65 46 6c 61 67 20 29 7b 0a 20 20 20 20  eateFlag ){.    
8770: 2f 2a 20 53 74 65 70 73 20 33 2c 20 34 2c 20 61  /* Steps 3, 4, a
8780: 6e 64 20 35 20 69 6d 70 6c 65 6d 65 6e 74 65 64  nd 5 implemented
8790: 20 62 79 20 74 68 69 73 20 73 75 62 72 6f 75 74   by this subrout
87a0: 69 6e 65 20 2a 2f 0a 20 20 20 20 72 65 74 75 72  ine */.    retur
87b0: 6e 20 70 63 61 63 68 65 31 46 65 74 63 68 53 74  n pcache1FetchSt
87c0: 61 67 65 32 28 70 43 61 63 68 65 2c 20 69 4b 65  age2(pCache, iKe
87d0: 79 2c 20 63 72 65 61 74 65 46 6c 61 67 29 3b 0a  y, createFlag);.
87e0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 72 65 74    }else{.    ret
87f0: 75 72 6e 20 30 3b 0a 20 20 7d 0a 7d 0a 23 69 66  urn 0;.  }.}.#if
8800: 20 50 43 41 43 48 45 31 5f 4d 49 47 48 54 5f 55   PCACHE1_MIGHT_U
8810: 53 45 5f 47 52 4f 55 50 5f 4d 55 54 45 58 0a 73  SE_GROUP_MUTEX.s
8820: 74 61 74 69 63 20 50 67 48 64 72 31 20 2a 70 63  tatic PgHdr1 *pc
8830: 61 63 68 65 31 46 65 74 63 68 57 69 74 68 4d 75  ache1FetchWithMu
8840: 74 65 78 28 0a 20 20 73 71 6c 69 74 65 33 5f 70  tex(.  sqlite3_p
8850: 63 61 63 68 65 20 2a 70 2c 20 0a 20 20 75 6e 73  cache *p, .  uns
8860: 69 67 6e 65 64 20 69 6e 74 20 69 4b 65 79 2c 20  igned int iKey, 
8870: 0a 20 20 69 6e 74 20 63 72 65 61 74 65 46 6c 61  .  int createFla
8880: 67 0a 29 7b 0a 20 20 50 43 61 63 68 65 31 20 2a  g.){.  PCache1 *
8890: 70 43 61 63 68 65 20 3d 20 28 50 43 61 63 68 65  pCache = (PCache
88a0: 31 20 2a 29 70 3b 0a 20 20 50 67 48 64 72 31 20  1 *)p;.  PgHdr1 
88b0: 2a 70 50 61 67 65 3b 0a 0a 20 20 70 63 61 63 68  *pPage;..  pcach
88c0: 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70 43 61  e1EnterMutex(pCa
88d0: 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 20 20  che->pGroup);.  
88e0: 70 50 61 67 65 20 3d 20 70 63 61 63 68 65 31 46  pPage = pcache1F
88f0: 65 74 63 68 4e 6f 4d 75 74 65 78 28 70 2c 20 69  etchNoMutex(p, i
8900: 4b 65 79 2c 20 63 72 65 61 74 65 46 6c 61 67 29  Key, createFlag)
8910: 3b 0a 20 20 61 73 73 65 72 74 28 20 70 50 61 67  ;.  assert( pPag
8920: 65 3d 3d 30 20 7c 7c 20 70 43 61 63 68 65 2d 3e  e==0 || pCache->
8930: 69 4d 61 78 4b 65 79 3e 3d 69 4b 65 79 20 29 3b  iMaxKey>=iKey );
8940: 0a 20 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d  .  pcache1LeaveM
8950: 75 74 65 78 28 70 43 61 63 68 65 2d 3e 70 47 72  utex(pCache->pGr
8960: 6f 75 70 29 3b 0a 20 20 72 65 74 75 72 6e 20 70  oup);.  return p
8970: 50 61 67 65 3b 0a 7d 0a 23 65 6e 64 69 66 0a 73  Page;.}.#endif.s
8980: 74 61 74 69 63 20 73 71 6c 69 74 65 33 5f 70 63  tatic sqlite3_pc
8990: 61 63 68 65 5f 70 61 67 65 20 2a 70 63 61 63 68  ache_page *pcach
89a0: 65 31 46 65 74 63 68 28 0a 20 20 73 71 6c 69 74  e1Fetch(.  sqlit
89b0: 65 33 5f 70 63 61 63 68 65 20 2a 70 2c 20 0a 20  e3_pcache *p, . 
89c0: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4b   unsigned int iK
89d0: 65 79 2c 20 0a 20 20 69 6e 74 20 63 72 65 61 74  ey, .  int creat
89e0: 65 46 6c 61 67 0a 29 7b 0a 23 69 66 20 50 43 41  eFlag.){.#if PCA
89f0: 43 48 45 31 5f 4d 49 47 48 54 5f 55 53 45 5f 47  CHE1_MIGHT_USE_G
8a00: 52 4f 55 50 5f 4d 55 54 45 58 20 7c 7c 20 64 65  ROUP_MUTEX || de
8a10: 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 44 45 42  fined(SQLITE_DEB
8a20: 55 47 29 0a 20 20 50 43 61 63 68 65 31 20 2a 70  UG).  PCache1 *p
8a30: 43 61 63 68 65 20 3d 20 28 50 43 61 63 68 65 31  Cache = (PCache1
8a40: 20 2a 29 70 3b 0a 23 65 6e 64 69 66 0a 0a 20 20   *)p;.#endif..  
8a50: 61 73 73 65 72 74 28 20 6f 66 66 73 65 74 6f 66  assert( offsetof
8a60: 28 50 67 48 64 72 31 2c 70 61 67 65 29 3d 3d 30  (PgHdr1,page)==0
8a70: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 43   );.  assert( pC
8a80: 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65  ache->bPurgeable
8a90: 20 7c 7c 20 63 72 65 61 74 65 46 6c 61 67 21 3d   || createFlag!=
8aa0: 31 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70  1 );.  assert( p
8ab0: 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c  Cache->bPurgeabl
8ac0: 65 20 7c 7c 20 70 43 61 63 68 65 2d 3e 6e 4d 69  e || pCache->nMi
8ad0: 6e 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74  n==0 );.  assert
8ae0: 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65  ( pCache->bPurge
8af0: 61 62 6c 65 3d 3d 30 20 7c 7c 20 70 43 61 63 68  able==0 || pCach
8b00: 65 2d 3e 6e 4d 69 6e 3d 3d 31 30 20 29 3b 0a 20  e->nMin==10 );. 
8b10: 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65 2d   assert( pCache-
8b20: 3e 6e 4d 69 6e 3d 3d 30 20 7c 7c 20 70 43 61 63  >nMin==0 || pCac
8b30: 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 29  he->bPurgeable )
8b40: 3b 0a 20 20 61 73 73 65 72 74 28 20 70 43 61 63  ;.  assert( pCac
8b50: 68 65 2d 3e 6e 48 61 73 68 3e 30 20 29 3b 0a 23  he->nHash>0 );.#
8b60: 69 66 20 50 43 41 43 48 45 31 5f 4d 49 47 48 54  if PCACHE1_MIGHT
8b70: 5f 55 53 45 5f 47 52 4f 55 50 5f 4d 55 54 45 58  _USE_GROUP_MUTEX
8b80: 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 70  .  if( pCache->p
8b90: 47 72 6f 75 70 2d 3e 6d 75 74 65 78 20 29 7b 0a  Group->mutex ){.
8ba0: 20 20 20 20 72 65 74 75 72 6e 20 28 73 71 6c 69      return (sqli
8bb0: 74 65 33 5f 70 63 61 63 68 65 5f 70 61 67 65 2a  te3_pcache_page*
8bc0: 29 70 63 61 63 68 65 31 46 65 74 63 68 57 69 74  )pcache1FetchWit
8bd0: 68 4d 75 74 65 78 28 70 2c 20 69 4b 65 79 2c 20  hMutex(p, iKey, 
8be0: 63 72 65 61 74 65 46 6c 61 67 29 3b 0a 20 20 7d  createFlag);.  }
8bf0: 65 6c 73 65 0a 23 65 6e 64 69 66 0a 20 20 7b 0a  else.#endif.  {.
8c00: 20 20 20 20 72 65 74 75 72 6e 20 28 73 71 6c 69      return (sqli
8c10: 74 65 33 5f 70 63 61 63 68 65 5f 70 61 67 65 2a  te3_pcache_page*
8c20: 29 70 63 61 63 68 65 31 46 65 74 63 68 4e 6f 4d  )pcache1FetchNoM
8c30: 75 74 65 78 28 70 2c 20 69 4b 65 79 2c 20 63 72  utex(p, iKey, cr
8c40: 65 61 74 65 46 6c 61 67 29 3b 0a 20 20 7d 0a 7d  eateFlag);.  }.}
8c50: 0a 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65  .../*.** Impleme
8c60: 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73  ntation of the s
8c70: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78 55  qlite3_pcache.xU
8c80: 6e 70 69 6e 20 6d 65 74 68 6f 64 2e 0a 2a 2a 0a  npin method..**.
8c90: 2a 2a 20 4d 61 72 6b 20 61 20 70 61 67 65 20 61  ** Mark a page a
8ca0: 73 20 75 6e 70 69 6e 6e 65 64 20 28 65 6c 69 67  s unpinned (elig
8cb0: 69 62 6c 65 20 66 6f 72 20 61 73 79 6e 63 68 72  ible for asynchr
8cc0: 6f 6e 6f 75 73 20 72 65 63 79 63 6c 69 6e 67 29  onous recycling)
8cd0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
8ce0: 20 70 63 61 63 68 65 31 55 6e 70 69 6e 28 0a 20   pcache1Unpin(. 
8cf0: 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20   sqlite3_pcache 
8d00: 2a 70 2c 20 0a 20 20 73 71 6c 69 74 65 33 5f 70  *p, .  sqlite3_p
8d10: 63 61 63 68 65 5f 70 61 67 65 20 2a 70 50 67 2c  cache_page *pPg,
8d20: 20 0a 20 20 69 6e 74 20 72 65 75 73 65 55 6e 6c   .  int reuseUnl
8d30: 69 6b 65 6c 79 0a 29 7b 0a 20 20 50 43 61 63 68  ikely.){.  PCach
8d40: 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43  e1 *pCache = (PC
8d50: 61 63 68 65 31 20 2a 29 70 3b 0a 20 20 50 67 48  ache1 *)p;.  PgH
8d60: 64 72 31 20 2a 70 50 61 67 65 20 3d 20 28 50 67  dr1 *pPage = (Pg
8d70: 48 64 72 31 20 2a 29 70 50 67 3b 0a 20 20 50 47  Hdr1 *)pPg;.  PG
8d80: 72 6f 75 70 20 2a 70 47 72 6f 75 70 20 3d 20 70  roup *pGroup = p
8d90: 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b 0a 20  Cache->pGroup;. 
8da0: 0a 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65  .  assert( pPage
8db0: 2d 3e 70 43 61 63 68 65 3d 3d 70 43 61 63 68 65  ->pCache==pCache
8dc0: 20 29 3b 0a 20 20 70 63 61 63 68 65 31 45 6e 74   );.  pcache1Ent
8dd0: 65 72 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b  erMutex(pGroup);
8de0: 0a 0a 20 20 2f 2a 20 49 74 20 69 73 20 61 6e 20  ..  /* It is an 
8df0: 65 72 72 6f 72 20 74 6f 20 63 61 6c 6c 20 74 68  error to call th
8e00: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 66 20 74  is function if t
8e10: 68 65 20 70 61 67 65 20 69 73 20 61 6c 72 65 61  he page is alrea
8e20: 64 79 20 0a 20 20 2a 2a 20 70 61 72 74 20 6f 66  dy .  ** part of
8e30: 20 74 68 65 20 50 47 72 6f 75 70 20 4c 52 55 20   the PGroup LRU 
8e40: 6c 69 73 74 2e 0a 20 20 2a 2f 0a 20 20 61 73 73  list..  */.  ass
8e50: 65 72 74 28 20 70 50 61 67 65 2d 3e 70 4c 72 75  ert( pPage->pLru
8e60: 50 72 65 76 3d 3d 30 20 26 26 20 70 50 61 67 65  Prev==0 && pPage
8e70: 2d 3e 70 4c 72 75 4e 65 78 74 3d 3d 30 20 29 3b  ->pLruNext==0 );
8e80: 0a 20 20 61 73 73 65 72 74 28 20 50 41 47 45 5f  .  assert( PAGE_
8e90: 49 53 5f 50 49 4e 4e 45 44 28 70 50 61 67 65 29  IS_PINNED(pPage)
8ea0: 20 29 3b 0a 0a 20 20 69 66 28 20 72 65 75 73 65   );..  if( reuse
8eb0: 55 6e 6c 69 6b 65 6c 79 20 7c 7c 20 70 47 72 6f  Unlikely || pGro
8ec0: 75 70 2d 3e 6e 43 75 72 72 65 6e 74 50 61 67 65  up->nCurrentPage
8ed0: 3e 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67  >pGroup->nMaxPag
8ee0: 65 20 29 7b 0a 20 20 20 20 70 63 61 63 68 65 31  e ){.    pcache1
8ef0: 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73 68 28 70  RemoveFromHash(p
8f00: 50 61 67 65 2c 20 31 29 3b 0a 20 20 7d 65 6c 73  Page, 1);.  }els
8f10: 65 7b 0a 20 20 20 20 2f 2a 20 41 64 64 20 74 68  e{.    /* Add th
8f20: 65 20 70 61 67 65 20 74 6f 20 74 68 65 20 50 47  e page to the PG
8f30: 72 6f 75 70 20 4c 52 55 20 6c 69 73 74 2e 20 2a  roup LRU list. *
8f40: 2f 0a 20 20 20 20 50 67 48 64 72 31 20 2a 2a 70  /.    PgHdr1 **p
8f50: 70 46 69 72 73 74 20 3d 20 26 70 47 72 6f 75 70  pFirst = &pGroup
8f60: 2d 3e 6c 72 75 2e 70 4c 72 75 4e 65 78 74 3b 0a  ->lru.pLruNext;.
8f70: 20 20 20 20 70 50 61 67 65 2d 3e 70 4c 72 75 50      pPage->pLruP
8f80: 72 65 76 20 3d 20 26 70 47 72 6f 75 70 2d 3e 6c  rev = &pGroup->l
8f90: 72 75 3b 0a 20 20 20 20 28 70 50 61 67 65 2d 3e  ru;.    (pPage->
8fa0: 70 4c 72 75 4e 65 78 74 20 3d 20 2a 70 70 46 69  pLruNext = *ppFi
8fb0: 72 73 74 29 2d 3e 70 4c 72 75 50 72 65 76 20 3d  rst)->pLruPrev =
8fc0: 20 70 50 61 67 65 3b 0a 20 20 20 20 2a 70 70 46   pPage;.    *ppF
8fd0: 69 72 73 74 20 3d 20 70 50 61 67 65 3b 0a 20 20  irst = pPage;.  
8fe0: 20 20 70 43 61 63 68 65 2d 3e 6e 52 65 63 79 63    pCache->nRecyc
8ff0: 6c 61 62 6c 65 2b 2b 3b 0a 20 20 7d 0a 0a 20 20  lable++;.  }..  
9000: 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65  pcache1LeaveMute
9010: 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70  x(pCache->pGroup
9020: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c  );.}../*.** Impl
9030: 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68  ementation of th
9040: 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  e sqlite3_pcache
9050: 2e 78 52 65 6b 65 79 20 6d 65 74 68 6f 64 2e 20  .xRekey method. 
9060: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
9070: 70 63 61 63 68 65 31 52 65 6b 65 79 28 0a 20 20  pcache1Rekey(.  
9080: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a  sqlite3_pcache *
9090: 70 2c 0a 20 20 73 71 6c 69 74 65 33 5f 70 63 61  p,.  sqlite3_pca
90a0: 63 68 65 5f 70 61 67 65 20 2a 70 50 67 2c 0a 20  che_page *pPg,. 
90b0: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4f   unsigned int iO
90c0: 6c 64 2c 0a 20 20 75 6e 73 69 67 6e 65 64 20 69  ld,.  unsigned i
90d0: 6e 74 20 69 4e 65 77 0a 29 7b 0a 20 20 50 43 61  nt iNew.){.  PCa
90e0: 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28  che1 *pCache = (
90f0: 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20 20 50  PCache1 *)p;.  P
9100: 67 48 64 72 31 20 2a 70 50 61 67 65 20 3d 20 28  gHdr1 *pPage = (
9110: 50 67 48 64 72 31 20 2a 29 70 50 67 3b 0a 20 20  PgHdr1 *)pPg;.  
9120: 50 67 48 64 72 31 20 2a 2a 70 70 3b 0a 20 20 75  PgHdr1 **pp;.  u
9130: 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 3b 20 0a  nsigned int h; .
9140: 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65 2d    assert( pPage-
9150: 3e 69 4b 65 79 3d 3d 69 4f 6c 64 20 29 3b 0a 20  >iKey==iOld );. 
9160: 20 61 73 73 65 72 74 28 20 70 50 61 67 65 2d 3e   assert( pPage->
9170: 70 43 61 63 68 65 3d 3d 70 43 61 63 68 65 20 29  pCache==pCache )
9180: 3b 0a 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65  ;..  pcache1Ente
9190: 72 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e 70  rMutex(pCache->p
91a0: 47 72 6f 75 70 29 3b 0a 0a 20 20 68 20 3d 20 69  Group);..  h = i
91b0: 4f 6c 64 25 70 43 61 63 68 65 2d 3e 6e 48 61 73  Old%pCache->nHas
91c0: 68 3b 0a 20 20 70 70 20 3d 20 26 70 43 61 63 68  h;.  pp = &pCach
91d0: 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 0a 20 20  e->apHash[h];.  
91e0: 77 68 69 6c 65 28 20 28 2a 70 70 29 21 3d 70 50  while( (*pp)!=pP
91f0: 61 67 65 20 29 7b 0a 20 20 20 20 70 70 20 3d 20  age ){.    pp = 
9200: 26 28 2a 70 70 29 2d 3e 70 4e 65 78 74 3b 0a 20  &(*pp)->pNext;. 
9210: 20 7d 0a 20 20 2a 70 70 20 3d 20 70 50 61 67 65   }.  *pp = pPage
9220: 2d 3e 70 4e 65 78 74 3b 0a 0a 20 20 68 20 3d 20  ->pNext;..  h = 
9230: 69 4e 65 77 25 70 43 61 63 68 65 2d 3e 6e 48 61  iNew%pCache->nHa
9240: 73 68 3b 0a 20 20 70 50 61 67 65 2d 3e 69 4b 65  sh;.  pPage->iKe
9250: 79 20 3d 20 69 4e 65 77 3b 0a 20 20 70 50 61 67  y = iNew;.  pPag
9260: 65 2d 3e 70 4e 65 78 74 20 3d 20 70 43 61 63 68  e->pNext = pCach
9270: 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 0a 20 20  e->apHash[h];.  
9280: 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68  pCache->apHash[h
9290: 5d 20 3d 20 70 50 61 67 65 3b 0a 20 20 69 66 28  ] = pPage;.  if(
92a0: 20 69 4e 65 77 3e 70 43 61 63 68 65 2d 3e 69 4d   iNew>pCache->iM
92b0: 61 78 4b 65 79 20 29 7b 0a 20 20 20 20 70 43 61  axKey ){.    pCa
92c0: 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 3d 20 69  che->iMaxKey = i
92d0: 4e 65 77 3b 0a 20 20 7d 0a 0a 20 20 70 63 61 63  New;.  }..  pcac
92e0: 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 70 43  he1LeaveMutex(pC
92f0: 61 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 7d  ache->pGroup);.}
9300: 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e  ../*.** Implemen
9310: 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71  tation of the sq
9320: 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78 54 72  lite3_pcache.xTr
9330: 75 6e 63 61 74 65 20 6d 65 74 68 6f 64 2e 20 0a  uncate method. .
9340: 2a 2a 0a 2a 2a 20 44 69 73 63 61 72 64 20 61 6c  **.** Discard al
9350: 6c 20 75 6e 70 69 6e 6e 65 64 20 70 61 67 65 73  l unpinned pages
9360: 20 69 6e 20 74 68 65 20 63 61 63 68 65 20 77 69   in the cache wi
9370: 74 68 20 61 20 70 61 67 65 20 6e 75 6d 62 65 72  th a page number
9380: 20 65 71 75 61 6c 20 74 6f 0a 2a 2a 20 6f 72 20   equal to.** or 
9390: 67 72 65 61 74 65 72 20 74 68 61 6e 20 70 61 72  greater than par
93a0: 61 6d 65 74 65 72 20 69 4c 69 6d 69 74 2e 20 41  ameter iLimit. A
93b0: 6e 79 20 70 69 6e 6e 65 64 20 70 61 67 65 73 20  ny pinned pages 
93c0: 77 69 74 68 20 61 20 70 61 67 65 20 6e 75 6d 62  with a page numb
93d0: 65 72 0a 2a 2a 20 65 71 75 61 6c 20 74 6f 20 6f  er.** equal to o
93e0: 72 20 67 72 65 61 74 65 72 20 74 68 61 6e 20 69  r greater than i
93f0: 4c 69 6d 69 74 20 61 72 65 20 69 6d 70 6c 69 63  Limit are implic
9400: 69 74 6c 79 20 75 6e 70 69 6e 6e 65 64 2e 0a 2a  itly unpinned..*
9410: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63  /.static void pc
9420: 61 63 68 65 31 54 72 75 6e 63 61 74 65 28 73 71  ache1Truncate(sq
9430: 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70 2c  lite3_pcache *p,
9440: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4c   unsigned int iL
9450: 69 6d 69 74 29 7b 0a 20 20 50 43 61 63 68 65 31  imit){.  PCache1
9460: 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61 63   *pCache = (PCac
9470: 68 65 31 20 2a 29 70 3b 0a 20 20 70 63 61 63 68  he1 *)p;.  pcach
9480: 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70 43 61  e1EnterMutex(pCa
9490: 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 20 20  che->pGroup);.  
94a0: 69 66 28 20 69 4c 69 6d 69 74 3c 3d 70 43 61 63  if( iLimit<=pCac
94b0: 68 65 2d 3e 69 4d 61 78 4b 65 79 20 29 7b 0a 20  he->iMaxKey ){. 
94c0: 20 20 20 70 63 61 63 68 65 31 54 72 75 6e 63 61     pcache1Trunca
94d0: 74 65 55 6e 73 61 66 65 28 70 43 61 63 68 65 2c  teUnsafe(pCache,
94e0: 20 69 4c 69 6d 69 74 29 3b 0a 20 20 20 20 70 43   iLimit);.    pC
94f0: 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 3d 20  ache->iMaxKey = 
9500: 69 4c 69 6d 69 74 2d 31 3b 0a 20 20 7d 0a 20 20  iLimit-1;.  }.  
9510: 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65  pcache1LeaveMute
9520: 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70  x(pCache->pGroup
9530: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c  );.}../*.** Impl
9540: 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68  ementation of th
9550: 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  e sqlite3_pcache
9560: 2e 78 44 65 73 74 72 6f 79 20 6d 65 74 68 6f 64  .xDestroy method
9570: 2e 20 0a 2a 2a 0a 2a 2a 20 44 65 73 74 72 6f 79  . .**.** Destroy
9580: 20 61 20 63 61 63 68 65 20 61 6c 6c 6f 63 61 74   a cache allocat
9590: 65 64 20 75 73 69 6e 67 20 70 63 61 63 68 65 31  ed using pcache1
95a0: 43 72 65 61 74 65 28 29 2e 0a 2a 2f 0a 73 74 61  Create()..*/.sta
95b0: 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 31  tic void pcache1
95c0: 44 65 73 74 72 6f 79 28 73 71 6c 69 74 65 33 5f  Destroy(sqlite3_
95d0: 70 63 61 63 68 65 20 2a 70 29 7b 0a 20 20 50 43  pcache *p){.  PC
95e0: 61 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20  ache1 *pCache = 
95f0: 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20 20  (PCache1 *)p;.  
9600: 50 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 20 3d  PGroup *pGroup =
9610: 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b   pCache->pGroup;
9620: 0a 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68  .  assert( pCach
9630: 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 7c 7c  e->bPurgeable ||
9640: 20 28 70 43 61 63 68 65 2d 3e 6e 4d 61 78 3d 3d   (pCache->nMax==
9650: 30 20 26 26 20 70 43 61 63 68 65 2d 3e 6e 4d 69  0 && pCache->nMi
9660: 6e 3d 3d 30 29 20 29 3b 0a 20 20 70 63 61 63 68  n==0) );.  pcach
9670: 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70 47 72  e1EnterMutex(pGr
9680: 6f 75 70 29 3b 0a 20 20 69 66 28 20 70 43 61 63  oup);.  if( pCac
9690: 68 65 2d 3e 6e 50 61 67 65 20 29 20 70 63 61 63  he->nPage ) pcac
96a0: 68 65 31 54 72 75 6e 63 61 74 65 55 6e 73 61 66  he1TruncateUnsaf
96b0: 65 28 70 43 61 63 68 65 2c 20 30 29 3b 0a 20 20  e(pCache, 0);.  
96c0: 61 73 73 65 72 74 28 20 70 47 72 6f 75 70 2d 3e  assert( pGroup->
96d0: 6e 4d 61 78 50 61 67 65 20 3e 3d 20 70 43 61 63  nMaxPage >= pCac
96e0: 68 65 2d 3e 6e 4d 61 78 20 29 3b 0a 20 20 70 47  he->nMax );.  pG
96f0: 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65 20 2d  roup->nMaxPage -
9700: 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 3b 0a  = pCache->nMax;.
9710: 20 20 61 73 73 65 72 74 28 20 70 47 72 6f 75 70    assert( pGroup
9720: 2d 3e 6e 4d 69 6e 50 61 67 65 20 3e 3d 20 70 43  ->nMinPage >= pC
9730: 61 63 68 65 2d 3e 6e 4d 69 6e 20 29 3b 0a 20 20  ache->nMin );.  
9740: 70 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67 65  pGroup->nMinPage
9750: 20 2d 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 69 6e   -= pCache->nMin
9760: 3b 0a 20 20 70 47 72 6f 75 70 2d 3e 6d 78 50 69  ;.  pGroup->mxPi
9770: 6e 6e 65 64 20 3d 20 70 47 72 6f 75 70 2d 3e 6e  nned = pGroup->n
9780: 4d 61 78 50 61 67 65 20 2b 20 31 30 20 2d 20 70  MaxPage + 10 - p
9790: 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67 65 3b  Group->nMinPage;
97a0: 0a 20 20 70 63 61 63 68 65 31 45 6e 66 6f 72 63  .  pcache1Enforc
97b0: 65 4d 61 78 50 61 67 65 28 70 43 61 63 68 65 29  eMaxPage(pCache)
97c0: 3b 0a 20 20 70 63 61 63 68 65 31 4c 65 61 76 65  ;.  pcache1Leave
97d0: 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b 0a 20  Mutex(pGroup);. 
97e0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43   sqlite3_free(pC
97f0: 61 63 68 65 2d 3e 70 42 75 6c 6b 29 3b 0a 20 20  ache->pBulk);.  
9800: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43 61  sqlite3_free(pCa
9810: 63 68 65 2d 3e 61 70 48 61 73 68 29 3b 0a 20 20  che->apHash);.  
9820: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43 61  sqlite3_free(pCa
9830: 63 68 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  che);.}../*.** T
9840: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
9850: 63 61 6c 6c 65 64 20 64 75 72 69 6e 67 20 69 6e  called during in
9860: 69 74 69 61 6c 69 7a 61 74 69 6f 6e 20 28 73 71  itialization (sq
9870: 6c 69 74 65 33 5f 69 6e 69 74 69 61 6c 69 7a 65  lite3_initialize
9880: 28 29 29 20 74 6f 0a 2a 2a 20 69 6e 73 74 61 6c  ()) to.** instal
9890: 6c 20 74 68 65 20 64 65 66 61 75 6c 74 20 70 6c  l the default pl
98a0: 75 67 67 61 62 6c 65 20 63 61 63 68 65 20 6d 6f  uggable cache mo
98b0: 64 75 6c 65 2c 20 61 73 73 75 6d 69 6e 67 20 74  dule, assuming t
98c0: 68 65 20 75 73 65 72 20 68 61 73 20 6e 6f 74 0a  he user has not.
98d0: 2a 2a 20 61 6c 72 65 61 64 79 20 70 72 6f 76 69  ** already provi
98e0: 64 65 64 20 61 6e 20 61 6c 74 65 72 6e 61 74 69  ded an alternati
98f0: 76 65 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69  ve..*/.void sqli
9900: 74 65 33 50 43 61 63 68 65 53 65 74 44 65 66 61  te3PCacheSetDefa
9910: 75 6c 74 28 76 6f 69 64 29 7b 0a 20 20 73 74 61  ult(void){.  sta
9920: 74 69 63 20 63 6f 6e 73 74 20 73 71 6c 69 74 65  tic const sqlite
9930: 33 5f 70 63 61 63 68 65 5f 6d 65 74 68 6f 64 73  3_pcache_methods
9940: 32 20 64 65 66 61 75 6c 74 4d 65 74 68 6f 64 73  2 defaultMethods
9950: 20 3d 20 7b 0a 20 20 20 20 31 2c 20 20 20 20 20   = {.    1,     
9960: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9970: 20 20 2f 2a 20 69 56 65 72 73 69 6f 6e 20 2a 2f    /* iVersion */
9980: 0a 20 20 20 20 30 2c 20 20 20 20 20 20 20 20 20  .    0,         
9990: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
99a0: 20 70 41 72 67 20 2a 2f 0a 20 20 20 20 70 63 61   pArg */.    pca
99b0: 63 68 65 31 49 6e 69 74 2c 20 20 20 20 20 20 20  che1Init,       
99c0: 20 20 20 20 20 20 2f 2a 20 78 49 6e 69 74 20 2a        /* xInit *
99d0: 2f 0a 20 20 20 20 70 63 61 63 68 65 31 53 68 75  /.    pcache1Shu
99e0: 74 64 6f 77 6e 2c 20 20 20 20 20 20 20 20 20 2f  tdown,         /
99f0: 2a 20 78 53 68 75 74 64 6f 77 6e 20 2a 2f 0a 20  * xShutdown */. 
9a00: 20 20 20 70 63 61 63 68 65 31 43 72 65 61 74 65     pcache1Create
9a10: 2c 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78  ,           /* x
9a20: 43 72 65 61 74 65 20 2a 2f 0a 20 20 20 20 70 63  Create */.    pc
9a30: 61 63 68 65 31 43 61 63 68 65 73 69 7a 65 2c 20  ache1Cachesize, 
9a40: 20 20 20 20 20 20 20 2f 2a 20 78 43 61 63 68 65         /* xCache
9a50: 73 69 7a 65 20 2a 2f 0a 20 20 20 20 70 63 61 63  size */.    pcac
9a60: 68 65 31 50 61 67 65 63 6f 75 6e 74 2c 20 20 20  he1Pagecount,   
9a70: 20 20 20 20 20 2f 2a 20 78 50 61 67 65 63 6f 75       /* xPagecou
9a80: 6e 74 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65  nt */.    pcache
9a90: 31 46 65 74 63 68 2c 20 20 20 20 20 20 20 20 20  1Fetch,         
9aa0: 20 20 20 2f 2a 20 78 46 65 74 63 68 20 2a 2f 0a     /* xFetch */.
9ab0: 20 20 20 20 70 63 61 63 68 65 31 55 6e 70 69 6e      pcache1Unpin
9ac0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ,            /* 
9ad0: 78 55 6e 70 69 6e 20 2a 2f 0a 20 20 20 20 70 63  xUnpin */.    pc
9ae0: 61 63 68 65 31 52 65 6b 65 79 2c 20 20 20 20 20  ache1Rekey,     
9af0: 20 20 20 20 20 20 20 2f 2a 20 78 52 65 6b 65 79         /* xRekey
9b00: 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31 54   */.    pcache1T
9b10: 72 75 6e 63 61 74 65 2c 20 20 20 20 20 20 20 20  runcate,        
9b20: 20 2f 2a 20 78 54 72 75 6e 63 61 74 65 20 2a 2f   /* xTruncate */
9b30: 0a 20 20 20 20 70 63 61 63 68 65 31 44 65 73 74  .    pcache1Dest
9b40: 72 6f 79 2c 20 20 20 20 20 20 20 20 20 20 2f 2a  roy,          /*
9b50: 20 78 44 65 73 74 72 6f 79 20 2a 2f 0a 20 20 20   xDestroy */.   
9b60: 20 70 63 61 63 68 65 31 53 68 72 69 6e 6b 20 20   pcache1Shrink  
9b70: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 53 68            /* xSh
9b80: 72 69 6e 6b 20 2a 2f 0a 20 20 7d 3b 0a 20 20 73  rink */.  };.  s
9b90: 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67 28 53 51  qlite3_config(SQ
9ba0: 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 43 41 43  LITE_CONFIG_PCAC
9bb0: 48 45 32 2c 20 26 64 65 66 61 75 6c 74 4d 65 74  HE2, &defaultMet
9bc0: 68 6f 64 73 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  hods);.}../*.** 
9bd0: 52 65 74 75 72 6e 20 74 68 65 20 73 69 7a 65 20  Return the size 
9be0: 6f 66 20 74 68 65 20 68 65 61 64 65 72 20 6f 6e  of the header on
9bf0: 20 65 61 63 68 20 70 61 67 65 20 6f 66 20 74 68   each page of th
9c00: 69 73 20 50 43 41 43 48 45 20 69 6d 70 6c 65 6d  is PCACHE implem
9c10: 65 6e 74 61 74 69 6f 6e 2e 0a 2a 2f 0a 69 6e 74  entation..*/.int
9c20: 20 73 71 6c 69 74 65 33 48 65 61 64 65 72 53 69   sqlite3HeaderSi
9c30: 7a 65 50 63 61 63 68 65 31 28 76 6f 69 64 29 7b  zePcache1(void){
9c40: 20 72 65 74 75 72 6e 20 52 4f 55 4e 44 38 28 73   return ROUND8(s
9c50: 69 7a 65 6f 66 28 50 67 48 64 72 31 29 29 3b 20  izeof(PgHdr1)); 
9c60: 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20  }../*.** Return 
9c70: 74 68 65 20 67 6c 6f 62 61 6c 20 6d 75 74 65 78  the global mutex
9c80: 20 75 73 65 64 20 62 79 20 74 68 69 73 20 50 43   used by this PC
9c90: 41 43 48 45 20 69 6d 70 6c 65 6d 65 6e 74 61 74  ACHE implementat
9ca0: 69 6f 6e 2e 20 20 54 68 65 0a 2a 2a 20 73 71 6c  ion.  The.** sql
9cb0: 69 74 65 33 5f 73 74 61 74 75 73 28 29 20 72 6f  ite3_status() ro
9cc0: 75 74 69 6e 65 20 6e 65 65 64 73 20 61 63 63 65  utine needs acce
9cd0: 73 73 20 74 6f 20 74 68 69 73 20 6d 75 74 65 78  ss to this mutex
9ce0: 2e 0a 2a 2f 0a 73 71 6c 69 74 65 33 5f 6d 75 74  ..*/.sqlite3_mut
9cf0: 65 78 20 2a 73 71 6c 69 74 65 33 50 63 61 63 68  ex *sqlite3Pcach
9d00: 65 31 4d 75 74 65 78 28 76 6f 69 64 29 7b 0a 20  e1Mutex(void){. 
9d10: 20 72 65 74 75 72 6e 20 70 63 61 63 68 65 31 2e   return pcache1.
9d20: 6d 75 74 65 78 3b 0a 7d 0a 0a 23 69 66 64 65 66  mutex;.}..#ifdef
9d30: 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d   SQLITE_ENABLE_M
9d40: 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54  EMORY_MANAGEMENT
9d50: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  ./*.** This func
9d60: 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 74  tion is called t
9d70: 6f 20 66 72 65 65 20 73 75 70 65 72 66 6c 75 6f  o free superfluo
9d80: 75 73 20 64 79 6e 61 6d 69 63 61 6c 6c 79 20 61  us dynamically a
9d90: 6c 6c 6f 63 61 74 65 64 20 6d 65 6d 6f 72 79 0a  llocated memory.
9da0: 2a 2a 20 68 65 6c 64 20 62 79 20 74 68 65 20 70  ** held by the p
9db0: 61 67 65 72 20 73 79 73 74 65 6d 2e 20 4d 65 6d  ager system. Mem
9dc0: 6f 72 79 20 69 6e 20 75 73 65 20 62 79 20 61 6e  ory in use by an
9dd0: 79 20 53 51 4c 69 74 65 20 70 61 67 65 72 20 61  y SQLite pager a
9de0: 6c 6c 6f 63 61 74 65 64 0a 2a 2a 20 62 79 20 74  llocated.** by t
9df0: 68 65 20 63 75 72 72 65 6e 74 20 74 68 72 65 61  he current threa
9e00: 64 20 6d 61 79 20 62 65 20 73 71 6c 69 74 65 33  d may be sqlite3
9e10: 5f 66 72 65 65 28 29 65 64 2e 0a 2a 2a 0a 2a 2a  _free()ed..**.**
9e20: 20 6e 52 65 71 20 69 73 20 74 68 65 20 6e 75 6d   nReq is the num
9e30: 62 65 72 20 6f 66 20 62 79 74 65 73 20 6f 66 20  ber of bytes of 
9e40: 6d 65 6d 6f 72 79 20 72 65 71 75 69 72 65 64 2e  memory required.
9e50: 20 4f 6e 63 65 20 74 68 69 73 20 6d 75 63 68 20   Once this much 
9e60: 68 61 73 0a 2a 2a 20 62 65 65 6e 20 72 65 6c 65  has.** been rele
9e70: 61 73 65 64 2c 20 74 68 65 20 66 75 6e 63 74 69  ased, the functi
9e80: 6f 6e 20 72 65 74 75 72 6e 73 2e 20 54 68 65 20  on returns. The 
9e90: 72 65 74 75 72 6e 20 76 61 6c 75 65 20 69 73 20  return value is 
9ea0: 74 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72  the total number
9eb0: 20 0a 2a 2a 20 6f 66 20 62 79 74 65 73 20 6f 66   .** of bytes of
9ec0: 20 6d 65 6d 6f 72 79 20 72 65 6c 65 61 73 65 64   memory released
9ed0: 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33  ..*/.int sqlite3
9ee0: 50 63 61 63 68 65 52 65 6c 65 61 73 65 4d 65 6d  PcacheReleaseMem
9ef0: 6f 72 79 28 69 6e 74 20 6e 52 65 71 29 7b 0a 20  ory(int nReq){. 
9f00: 20 69 6e 74 20 6e 46 72 65 65 20 3d 20 30 3b 0a   int nFree = 0;.
9f10: 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65    assert( sqlite
9f20: 33 5f 6d 75 74 65 78 5f 6e 6f 74 68 65 6c 64 28  3_mutex_notheld(
9f30: 70 63 61 63 68 65 31 2e 67 72 70 2e 6d 75 74 65  pcache1.grp.mute
9f40: 78 29 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  x) );.  assert( 
9f50: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6e 6f  sqlite3_mutex_no
9f60: 74 68 65 6c 64 28 70 63 61 63 68 65 31 2e 6d 75  theld(pcache1.mu
9f70: 74 65 78 29 20 29 3b 0a 20 20 69 66 28 20 73 71  tex) );.  if( sq
9f80: 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69  lite3GlobalConfi
9f90: 67 2e 70 50 61 67 65 3d 3d 30 20 29 7b 0a 20 20  g.pPage==0 ){.  
9fa0: 20 20 50 67 48 64 72 31 20 2a 70 3b 0a 20 20 20    PgHdr1 *p;.   
9fb0: 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74   pcache1EnterMut
9fc0: 65 78 28 26 70 63 61 63 68 65 31 2e 67 72 70 29  ex(&pcache1.grp)
9fd0: 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 28 6e 52  ;.    while( (nR
9fe0: 65 71 3c 30 20 7c 7c 20 6e 46 72 65 65 3c 6e 52  eq<0 || nFree<nR
9ff0: 65 71 29 0a 20 20 20 20 20 20 20 26 26 20 20 28  eq).       &&  (
a000: 70 3d 70 63 61 63 68 65 31 2e 67 72 70 2e 6c 72  p=pcache1.grp.lr
a010: 75 2e 70 4c 72 75 50 72 65 76 29 21 3d 30 0a 20  u.pLruPrev)!=0. 
a020: 20 20 20 20 20 20 26 26 20 20 70 2d 3e 69 73 41        &&  p->isA
a030: 6e 63 68 6f 72 3d 3d 30 0a 20 20 20 20 29 7b 0a  nchor==0.    ){.
a040: 20 20 20 20 20 20 6e 46 72 65 65 20 2b 3d 20 70        nFree += p
a050: 63 61 63 68 65 31 4d 65 6d 53 69 7a 65 28 70 2d  cache1MemSize(p-
a060: 3e 70 61 67 65 2e 70 42 75 66 29 3b 0a 23 69 66  >page.pBuf);.#if
a070: 64 65 66 20 53 51 4c 49 54 45 5f 50 43 41 43 48  def SQLITE_PCACH
a080: 45 5f 53 45 50 41 52 41 54 45 5f 48 45 41 44 45  E_SEPARATE_HEADE
a090: 52 0a 20 20 20 20 20 20 6e 46 72 65 65 20 2b 3d  R.      nFree +=
a0a0: 20 73 71 6c 69 74 65 33 4d 65 6d 53 69 7a 65 28   sqlite3MemSize(
a0b0: 70 29 3b 0a 23 65 6e 64 69 66 0a 20 20 20 20 20  p);.#endif.     
a0c0: 20 61 73 73 65 72 74 28 20 50 41 47 45 5f 49 53   assert( PAGE_IS
a0d0: 5f 55 4e 50 49 4e 4e 45 44 28 70 29 20 29 3b 0a  _UNPINNED(p) );.
a0e0: 20 20 20 20 20 20 70 63 61 63 68 65 31 50 69 6e        pcache1Pin
a0f0: 50 61 67 65 28 70 29 3b 0a 20 20 20 20 20 20 70  Page(p);.      p
a100: 63 61 63 68 65 31 52 65 6d 6f 76 65 46 72 6f 6d  cache1RemoveFrom
a110: 48 61 73 68 28 70 2c 20 31 29 3b 0a 20 20 20 20  Hash(p, 1);.    
a120: 7d 0a 20 20 20 20 70 63 61 63 68 65 31 4c 65 61  }.    pcache1Lea
a130: 76 65 4d 75 74 65 78 28 26 70 63 61 63 68 65 31  veMutex(&pcache1
a140: 2e 67 72 70 29 3b 0a 20 20 7d 0a 20 20 72 65 74  .grp);.  }.  ret
a150: 75 72 6e 20 6e 46 72 65 65 3b 0a 7d 0a 23 65 6e  urn nFree;.}.#en
a160: 64 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f 45 4e  dif /* SQLITE_EN
a170: 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41  ABLE_MEMORY_MANA
a180: 47 45 4d 45 4e 54 20 2a 2f 0a 0a 23 69 66 64 65  GEMENT */..#ifde
a190: 66 20 53 51 4c 49 54 45 5f 54 45 53 54 0a 2f 2a  f SQLITE_TEST./*
a1a0: 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
a1b0: 6e 20 69 73 20 75 73 65 64 20 62 79 20 74 65 73  n is used by tes
a1c0: 74 20 70 72 6f 63 65 64 75 72 65 73 20 74 6f 20  t procedures to 
a1d0: 69 6e 73 70 65 63 74 20 74 68 65 20 69 6e 74 65  inspect the inte
a1e0: 72 6e 61 6c 20 73 74 61 74 65 0a 2a 2a 20 6f 66  rnal state.** of
a1f0: 20 74 68 65 20 67 6c 6f 62 61 6c 20 63 61 63 68   the global cach
a200: 65 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74  e..*/.void sqlit
a210: 65 33 50 63 61 63 68 65 53 74 61 74 73 28 0a 20  e3PcacheStats(. 
a220: 20 69 6e 74 20 2a 70 6e 43 75 72 72 65 6e 74 2c   int *pnCurrent,
a230: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 54 6f        /* OUT: To
a240: 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 70 61  tal number of pa
a250: 67 65 73 20 63 61 63 68 65 64 20 2a 2f 0a 20 20  ges cached */.  
a260: 69 6e 74 20 2a 70 6e 4d 61 78 2c 20 20 20 20 20  int *pnMax,     
a270: 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 47 6c 6f       /* OUT: Glo
a280: 62 61 6c 20 6d 61 78 69 6d 75 6d 20 63 61 63 68  bal maximum cach
a290: 65 20 73 69 7a 65 20 2a 2f 0a 20 20 69 6e 74 20  e size */.  int 
a2a0: 2a 70 6e 4d 69 6e 2c 20 20 20 20 20 20 20 20 20  *pnMin,         
a2b0: 20 2f 2a 20 4f 55 54 3a 20 53 75 6d 20 6f 66 20   /* OUT: Sum of 
a2c0: 50 43 61 63 68 65 31 2e 6e 4d 69 6e 20 66 6f 72  PCache1.nMin for
a2d0: 20 70 75 72 67 65 61 62 6c 65 20 63 61 63 68 65   purgeable cache
a2e0: 73 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 52 65  s */.  int *pnRe
a2f0: 63 79 63 6c 61 62 6c 65 20 20 20 20 2f 2a 20 4f  cyclable    /* O
a300: 55 54 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72  UT: Total number
a310: 20 6f 66 20 70 61 67 65 73 20 61 76 61 69 6c 61   of pages availa
a320: 62 6c 65 20 66 6f 72 20 72 65 63 79 63 6c 69 6e  ble for recyclin
a330: 67 20 2a 2f 0a 29 7b 0a 20 20 50 67 48 64 72 31  g */.){.  PgHdr1
a340: 20 2a 70 3b 0a 20 20 69 6e 74 20 6e 52 65 63 79   *p;.  int nRecy
a350: 63 6c 61 62 6c 65 20 3d 20 30 3b 0a 20 20 66 6f  clable = 0;.  fo
a360: 72 28 70 3d 70 63 61 63 68 65 31 2e 67 72 70 2e  r(p=pcache1.grp.
a370: 6c 72 75 2e 70 4c 72 75 4e 65 78 74 3b 20 70 20  lru.pLruNext; p 
a380: 26 26 20 21 70 2d 3e 69 73 41 6e 63 68 6f 72 3b  && !p->isAnchor;
a390: 20 70 3d 70 2d 3e 70 4c 72 75 4e 65 78 74 29 7b   p=p->pLruNext){
a3a0: 0a 20 20 20 20 61 73 73 65 72 74 28 20 50 41 47  .    assert( PAG
a3b0: 45 5f 49 53 5f 55 4e 50 49 4e 4e 45 44 28 70 29  E_IS_UNPINNED(p)
a3c0: 20 29 3b 0a 20 20 20 20 6e 52 65 63 79 63 6c 61   );.    nRecycla
a3d0: 62 6c 65 2b 2b 3b 0a 20 20 7d 0a 20 20 2a 70 6e  ble++;.  }.  *pn
a3e0: 43 75 72 72 65 6e 74 20 3d 20 70 63 61 63 68 65  Current = pcache
a3f0: 31 2e 67 72 70 2e 6e 43 75 72 72 65 6e 74 50 61  1.grp.nCurrentPa
a400: 67 65 3b 0a 20 20 2a 70 6e 4d 61 78 20 3d 20 28  ge;.  *pnMax = (
a410: 69 6e 74 29 70 63 61 63 68 65 31 2e 67 72 70 2e  int)pcache1.grp.
a420: 6e 4d 61 78 50 61 67 65 3b 0a 20 20 2a 70 6e 4d  nMaxPage;.  *pnM
a430: 69 6e 20 3d 20 28 69 6e 74 29 70 63 61 63 68 65  in = (int)pcache
a440: 31 2e 67 72 70 2e 6e 4d 69 6e 50 61 67 65 3b 0a  1.grp.nMinPage;.
a450: 20 20 2a 70 6e 52 65 63 79 63 6c 61 62 6c 65 20    *pnRecyclable 
a460: 3d 20 6e 52 65 63 79 63 6c 61 62 6c 65 3b 0a 7d  = nRecyclable;.}
a470: 0a 23 65 6e 64 69 66 0a                          .#endif.