/ Hex Artifact Content
Login

Artifact 716975564c15eb6679e97f734cec1bfd6c16ac3d4010f05f1f8e509fc7d19880:


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 50 75 72 67 65 61 62 6c 65 3b   int nPurgeable;
18f0: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* 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 6e 64 20 74 68 65 20 70 6e  able) and the pn
1b40: 50 75 72 67 65 61 62 6c 65 20 70 6f 69 6e 74 65  Purgeable pointe
1b50: 72 20 61 72 65 20 61 6c 6c 20 73 65 74 20 77 68  r are all set wh
1b60: 65 6e 20 74 68 65 0a 20 20 2a 2a 20 63 61 63 68  en the.  ** cach
1b70: 65 20 69 73 20 63 72 65 61 74 65 64 20 61 6e 64  e is created and
1b80: 20 61 72 65 20 6e 65 76 65 72 20 63 68 61 6e 67   are never chang
1b90: 65 64 20 74 68 65 72 65 61 66 74 65 72 2e 20 6e  ed thereafter. n
1ba0: 4d 61 78 20 6d 61 79 20 62 65 20 0a 20 20 2a 2a  Max may be .  **
1bb0: 20 6d 6f 64 69 66 69 65 64 20 61 74 20 61 6e 79   modified at any
1bc0: 20 74 69 6d 65 20 62 79 20 61 20 63 61 6c 6c 20   time by a call 
1bd0: 74 6f 20 74 68 65 20 70 63 61 63 68 65 31 43 61  to the pcache1Ca
1be0: 63 68 65 73 69 7a 65 28 29 20 6d 65 74 68 6f 64  chesize() method
1bf0: 2e 0a 20 20 2a 2a 20 54 68 65 20 50 47 72 6f 75  ..  ** The PGrou
1c00: 70 20 6d 75 74 65 78 20 6d 75 73 74 20 62 65 20  p mutex must be 
1c10: 68 65 6c 64 20 77 68 65 6e 20 61 63 63 65 73 73  held when access
1c20: 69 6e 67 20 6e 4d 61 78 2e 0a 20 20 2a 2f 0a 20  ing nMax..  */. 
1c30: 20 50 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 3b   PGroup *pGroup;
1c40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c50: 20 20 20 20 20 2f 2a 20 50 47 72 6f 75 70 20 74       /* PGroup t
1c60: 68 69 73 20 63 61 63 68 65 20 62 65 6c 6f 6e 67  his cache belong
1c70: 73 20 74 6f 20 2a 2f 0a 20 20 75 6e 73 69 67 6e  s to */.  unsign
1c80: 65 64 20 69 6e 74 20 2a 70 6e 50 75 72 67 65 61  ed int *pnPurgea
1c90: 62 6c 65 3b 20 20 20 20 20 20 20 20 20 20 2f 2a  ble;          /*
1ca0: 20 50 6f 69 6e 74 65 72 20 74 6f 20 70 47 72 6f   Pointer to pGro
1cb0: 75 70 2d 3e 6e 50 75 72 67 65 61 62 6c 65 20 2a  up->nPurgeable *
1cc0: 2f 0a 20 20 69 6e 74 20 73 7a 50 61 67 65 3b 20  /.  int szPage; 
1cd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1ce0: 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
1cf0: 6f 66 20 64 61 74 61 62 61 73 65 20 63 6f 6e 74  of database cont
1d00: 65 6e 74 20 73 65 63 74 69 6f 6e 20 2a 2f 0a 20  ent section */. 
1d10: 20 69 6e 74 20 73 7a 45 78 74 72 61 3b 20 20 20   int szExtra;   
1d20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d30: 20 20 20 20 20 2f 2a 20 73 69 7a 65 6f 66 28 4d       /* sizeof(M
1d40: 65 6d 50 61 67 65 29 2b 73 69 7a 65 6f 66 28 50  emPage)+sizeof(P
1d50: 67 48 64 72 29 20 2a 2f 0a 20 20 69 6e 74 20 73  gHdr) */.  int s
1d60: 7a 41 6c 6c 6f 63 3b 20 20 20 20 20 20 20 20 20  zAlloc;         
1d70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1d80: 2a 20 54 6f 74 61 6c 20 73 69 7a 65 20 6f 66 20  * Total size of 
1d90: 6f 6e 65 20 70 63 61 63 68 65 20 6c 69 6e 65 20  one pcache line 
1da0: 2a 2f 0a 20 20 69 6e 74 20 62 50 75 72 67 65 61  */.  int bPurgea
1db0: 62 6c 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  ble;            
1dc0: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
1dd0: 20 69 66 20 63 61 63 68 65 20 69 73 20 70 75 72   if cache is pur
1de0: 67 65 61 62 6c 65 20 2a 2f 0a 20 20 75 6e 73 69  geable */.  unsi
1df0: 67 6e 65 64 20 69 6e 74 20 6e 4d 69 6e 3b 20 20  gned int nMin;  
1e00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1e10: 2f 2a 20 4d 69 6e 69 6d 75 6d 20 6e 75 6d 62 65  /* Minimum numbe
1e20: 72 20 6f 66 20 70 61 67 65 73 20 72 65 73 65 72  r of pages reser
1e30: 76 65 64 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65  ved */.  unsigne
1e40: 64 20 69 6e 74 20 6e 4d 61 78 3b 20 20 20 20 20  d int nMax;     
1e50: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1e60: 43 6f 6e 66 69 67 75 72 65 64 20 22 63 61 63 68  Configured "cach
1e70: 65 5f 73 69 7a 65 22 20 76 61 6c 75 65 20 2a 2f  e_size" value */
1e80: 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  .  unsigned int 
1e90: 6e 39 30 70 63 74 3b 20 20 20 20 20 20 20 20 20  n90pct;         
1ea0: 20 20 20 20 20 20 20 2f 2a 20 6e 4d 61 78 2a 39         /* nMax*9
1eb0: 2f 31 30 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65  /10 */.  unsigne
1ec0: 64 20 69 6e 74 20 69 4d 61 78 4b 65 79 3b 20 20  d int iMaxKey;  
1ed0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1ee0: 4c 61 72 67 65 73 74 20 6b 65 79 20 73 65 65 6e  Largest key seen
1ef0: 20 73 69 6e 63 65 20 78 54 72 75 6e 63 61 74 65   since xTruncate
1f00: 28 29 20 2a 2f 0a 0a 20 20 2f 2a 20 48 61 73 68  () */..  /* Hash
1f10: 20 74 61 62 6c 65 20 6f 66 20 61 6c 6c 20 70 61   table of all pa
1f20: 67 65 73 2e 20 54 68 65 20 66 6f 6c 6c 6f 77 69  ges. The followi
1f30: 6e 67 20 76 61 72 69 61 62 6c 65 73 20 6d 61 79  ng variables may
1f40: 20 6f 6e 6c 79 20 62 65 20 61 63 63 65 73 73 65   only be accesse
1f50: 64 0a 20 20 2a 2a 20 77 68 65 6e 20 74 68 65 20  d.  ** when the 
1f60: 61 63 63 65 73 73 6f 72 20 69 73 20 68 6f 6c 64  accessor is hold
1f70: 69 6e 67 20 74 68 65 20 50 47 72 6f 75 70 20 6d  ing the PGroup m
1f80: 75 74 65 78 2e 0a 20 20 2a 2f 0a 20 20 75 6e 73  utex..  */.  uns
1f90: 69 67 6e 65 64 20 69 6e 74 20 6e 52 65 63 79 63  igned int nRecyc
1fa0: 6c 61 62 6c 65 3b 20 20 20 20 20 20 20 20 20 20  lable;          
1fb0: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 70 61   /* Number of pa
1fc0: 67 65 73 20 69 6e 20 74 68 65 20 4c 52 55 20 6c  ges in the LRU l
1fd0: 69 73 74 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65  ist */.  unsigne
1fe0: 64 20 69 6e 74 20 6e 50 61 67 65 3b 20 20 20 20  d int nPage;    
1ff0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2000: 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20  Total number of 
2010: 70 61 67 65 73 20 69 6e 20 61 70 48 61 73 68 20  pages in apHash 
2020: 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e  */.  unsigned in
2030: 74 20 6e 48 61 73 68 3b 20 20 20 20 20 20 20 20  t nHash;        
2040: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
2050: 65 72 20 6f 66 20 73 6c 6f 74 73 20 69 6e 20 61  er of slots in a
2060: 70 48 61 73 68 5b 5d 20 2a 2f 0a 20 20 50 67 48  pHash[] */.  PgH
2070: 64 72 31 20 2a 2a 61 70 48 61 73 68 3b 20 20 20  dr1 **apHash;   
2080: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2090: 20 2f 2a 20 48 61 73 68 20 74 61 62 6c 65 20 66   /* Hash table f
20a0: 6f 72 20 66 61 73 74 20 6c 6f 6f 6b 75 70 20 62  or fast lookup b
20b0: 79 20 6b 65 79 20 2a 2f 0a 20 20 50 67 48 64 72  y key */.  PgHdr
20c0: 31 20 2a 70 46 72 65 65 3b 20 20 20 20 20 20 20  1 *pFree;       
20d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
20e0: 2a 20 4c 69 73 74 20 6f 66 20 75 6e 75 73 65 64  * List of unused
20f0: 20 70 63 61 63 68 65 2d 6c 6f 63 61 6c 20 70 61   pcache-local pa
2100: 67 65 73 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70  ges */.  void *p
2110: 42 75 6c 6b 3b 20 20 20 20 20 20 20 20 20 20 20  Bulk;           
2120: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2130: 42 75 6c 6b 20 6d 65 6d 6f 72 79 20 75 73 65 64  Bulk memory used
2140: 20 62 79 20 70 63 61 63 68 65 2d 6c 6f 63 61 6c   by pcache-local
2150: 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 46 72   */.};../*.** Fr
2160: 65 65 20 73 6c 6f 74 73 20 69 6e 20 74 68 65 20  ee slots in the 
2170: 61 6c 6c 6f 63 61 74 6f 72 20 75 73 65 64 20 74  allocator used t
2180: 6f 20 64 69 76 69 64 65 20 75 70 20 74 68 65 20  o divide up the 
2190: 67 6c 6f 62 61 6c 20 70 61 67 65 20 63 61 63 68  global page cach
21a0: 65 0a 2a 2a 20 62 75 66 66 65 72 20 70 72 6f 76  e.** buffer prov
21b0: 69 64 65 64 20 75 73 69 6e 67 20 74 68 65 20 53  ided using the S
21c0: 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47  QLITE_CONFIG_PAG
21d0: 45 43 41 43 48 45 20 6d 65 63 68 61 6e 69 73 6d  ECACHE mechanism
21e0: 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 50 67 46 72  ..*/.struct PgFr
21f0: 65 65 73 6c 6f 74 20 7b 0a 20 20 50 67 46 72 65  eeslot {.  PgFre
2200: 65 73 6c 6f 74 20 2a 70 4e 65 78 74 3b 20 20 2f  eslot *pNext;  /
2210: 2a 20 4e 65 78 74 20 66 72 65 65 20 73 6c 6f 74  * Next free slot
2220: 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 47 6c   */.};../*.** Gl
2230: 6f 62 61 6c 20 64 61 74 61 20 75 73 65 64 20 62  obal data used b
2240: 79 20 74 68 69 73 20 63 61 63 68 65 2e 0a 2a 2f  y this cache..*/
2250: 0a 73 74 61 74 69 63 20 53 51 4c 49 54 45 5f 57  .static SQLITE_W
2260: 53 44 20 73 74 72 75 63 74 20 50 43 61 63 68 65  SD struct PCache
2270: 47 6c 6f 62 61 6c 20 7b 0a 20 20 50 47 72 6f 75  Global {.  PGrou
2280: 70 20 67 72 70 3b 20 20 20 20 20 20 20 20 20 20  p grp;          
2290: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65            /* The
22a0: 20 67 6c 6f 62 61 6c 20 50 47 72 6f 75 70 20 66   global PGroup f
22b0: 6f 72 20 6d 6f 64 65 20 28 32 29 20 2a 2f 0a 0a  or mode (2) */..
22c0: 20 20 2f 2a 20 56 61 72 69 61 62 6c 65 73 20 72    /* Variables r
22d0: 65 6c 61 74 65 64 20 74 6f 20 53 51 4c 49 54 45  elated to SQLITE
22e0: 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48  _CONFIG_PAGECACH
22f0: 45 20 73 65 74 74 69 6e 67 73 2e 20 20 54 68 65  E settings.  The
2300: 0a 20 20 2a 2a 20 73 7a 53 6c 6f 74 2c 20 6e 53  .  ** szSlot, nS
2310: 6c 6f 74 2c 20 70 53 74 61 72 74 2c 20 70 45 6e  lot, pStart, pEn
2320: 64 2c 20 6e 52 65 73 65 72 76 65 2c 20 61 6e 64  d, nReserve, and
2330: 20 69 73 49 6e 69 74 20 76 61 6c 75 65 73 20 61   isInit values a
2340: 72 65 20 61 6c 6c 0a 20 20 2a 2a 20 66 69 78 65  re all.  ** fixe
2350: 64 20 61 74 20 73 71 6c 69 74 65 33 5f 69 6e 69  d at sqlite3_ini
2360: 74 69 61 6c 69 7a 65 28 29 20 74 69 6d 65 20 61  tialize() time a
2370: 6e 64 20 64 6f 20 6e 6f 74 20 72 65 71 75 69 72  nd do not requir
2380: 65 20 6d 75 74 65 78 20 70 72 6f 74 65 63 74 69  e mutex protecti
2390: 6f 6e 2e 0a 20 20 2a 2a 20 54 68 65 20 6e 46 72  on..  ** The nFr
23a0: 65 65 53 6c 6f 74 20 61 6e 64 20 70 46 72 65 65  eeSlot and pFree
23b0: 20 76 61 6c 75 65 73 20 64 6f 20 72 65 71 75 69   values do requi
23c0: 72 65 20 6d 75 74 65 78 20 70 72 6f 74 65 63 74  re mutex protect
23d0: 69 6f 6e 2e 0a 20 20 2a 2f 0a 20 20 69 6e 74 20  ion..  */.  int 
23e0: 69 73 49 6e 69 74 3b 20 20 20 20 20 20 20 20 20  isInit;         
23f0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72             /* Tr
2400: 75 65 20 69 66 20 69 6e 69 74 69 61 6c 69 7a 65  ue if initialize
2410: 64 20 2a 2f 0a 20 20 69 6e 74 20 73 65 70 61 72  d */.  int separ
2420: 61 74 65 43 61 63 68 65 3b 20 20 20 20 20 20 20  ateCache;       
2430: 20 20 20 20 20 20 2f 2a 20 55 73 65 20 61 20 6e        /* Use a n
2440: 65 77 20 50 47 72 6f 75 70 20 66 6f 72 20 65 61  ew PGroup for ea
2450: 63 68 20 50 43 61 63 68 65 20 2a 2f 0a 20 20 69  ch PCache */.  i
2460: 6e 74 20 6e 49 6e 69 74 50 61 67 65 3b 20 20 20  nt nInitPage;   
2470: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
2480: 20 49 6e 69 74 69 61 6c 20 62 75 6c 6b 20 61 6c   Initial bulk al
2490: 6c 6f 63 61 74 69 6f 6e 20 73 69 7a 65 20 2a 2f  location size */
24a0: 20 20 20 0a 20 20 69 6e 74 20 73 7a 53 6c 6f 74     .  int szSlot
24b0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
24c0: 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
24d0: 65 61 63 68 20 66 72 65 65 20 73 6c 6f 74 20 2a  each free slot *
24e0: 2f 0a 20 20 69 6e 74 20 6e 53 6c 6f 74 3b 20 20  /.  int nSlot;  
24f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2500: 20 20 20 2f 2a 20 54 68 65 20 6e 75 6d 62 65 72     /* The number
2510: 20 6f 66 20 70 63 61 63 68 65 20 73 6c 6f 74 73   of pcache slots
2520: 20 2a 2f 0a 20 20 69 6e 74 20 6e 52 65 73 65 72   */.  int nReser
2530: 76 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ve;             
2540: 20 20 20 20 20 2f 2a 20 54 72 79 20 74 6f 20 6b       /* Try to k
2550: 65 65 70 20 6e 46 72 65 65 53 6c 6f 74 20 61 62  eep nFreeSlot ab
2560: 6f 76 65 20 74 68 69 73 20 2a 2f 0a 20 20 76 6f  ove this */.  vo
2570: 69 64 20 2a 70 53 74 61 72 74 2c 20 2a 70 45 6e  id *pStart, *pEn
2580: 64 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  d;           /* 
2590: 42 6f 75 6e 64 73 20 6f 66 20 67 6c 6f 62 61 6c  Bounds of global
25a0: 20 70 61 67 65 20 63 61 63 68 65 20 6d 65 6d 6f   page cache memo
25b0: 72 79 20 2a 2f 0a 20 20 2f 2a 20 41 62 6f 76 65  ry */.  /* Above
25c0: 20 72 65 71 75 69 72 65 73 20 6e 6f 20 6d 75 74   requires no mut
25d0: 65 78 2e 20 20 55 73 65 20 6d 75 74 65 78 20 62  ex.  Use mutex b
25e0: 65 6c 6f 77 20 66 6f 72 20 76 61 72 69 61 62 6c  elow for variabl
25f0: 65 20 74 68 61 74 20 66 6f 6c 6c 6f 77 2e 20 2a  e that follow. *
2600: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65  /.  sqlite3_mute
2610: 78 20 2a 6d 75 74 65 78 3b 20 20 20 20 20 20 20  x *mutex;       
2620: 20 20 20 2f 2a 20 4d 75 74 65 78 20 66 6f 72 20     /* Mutex for 
2630: 61 63 63 65 73 73 69 6e 67 20 74 68 65 20 66 6f  accessing the fo
2640: 6c 6c 6f 77 69 6e 67 3a 20 2a 2f 0a 20 20 50 67  llowing: */.  Pg
2650: 46 72 65 65 73 6c 6f 74 20 2a 70 46 72 65 65 3b  Freeslot *pFree;
2660: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2670: 46 72 65 65 20 70 61 67 65 20 62 6c 6f 63 6b 73  Free page blocks
2680: 20 2a 2f 0a 20 20 69 6e 74 20 6e 46 72 65 65 53   */.  int nFreeS
2690: 6c 6f 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  lot;            
26a0: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
26b0: 66 20 75 6e 75 73 65 64 20 70 63 61 63 68 65 20  f unused pcache 
26c0: 73 6c 6f 74 73 20 2a 2f 0a 20 20 2f 2a 20 54 68  slots */.  /* Th
26d0: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 76 61 6c 75  e following valu
26e0: 65 20 72 65 71 75 69 72 65 73 20 61 20 6d 75 74  e requires a mut
26f0: 65 78 20 74 6f 20 63 68 61 6e 67 65 2e 20 20 57  ex to change.  W
2700: 65 20 73 6b 69 70 20 74 68 65 20 6d 75 74 65 78  e skip the mutex
2710: 20 6f 6e 0a 20 20 2a 2a 20 72 65 61 64 69 6e 67   on.  ** reading
2720: 20 62 65 63 61 75 73 65 20 28 31 29 20 6d 6f 73   because (1) mos
2730: 74 20 70 6c 61 74 66 6f 72 6d 73 20 72 65 61 64  t platforms read
2740: 20 61 20 33 32 2d 62 69 74 20 69 6e 74 65 67 65   a 32-bit intege
2750: 72 20 61 74 6f 6d 69 63 61 6c 6c 79 20 61 6e 64  r atomically and
2760: 0a 20 20 2a 2a 20 28 32 29 20 65 76 65 6e 20 69  .  ** (2) even i
2770: 66 20 61 6e 20 69 6e 63 6f 72 72 65 63 74 20 76  f an incorrect v
2780: 61 6c 75 65 20 69 73 20 72 65 61 64 2c 20 6e 6f  alue is read, no
2790: 20 67 72 65 61 74 20 68 61 72 6d 20 69 73 20 64   great harm is d
27a0: 6f 6e 65 20 73 69 6e 63 65 20 74 68 69 73 0a 20  one since this. 
27b0: 20 2a 2a 20 69 73 20 72 65 61 6c 6c 79 20 6a 75   ** is really ju
27c0: 73 74 20 61 6e 20 6f 70 74 69 6d 69 7a 61 74 69  st an optimizati
27d0: 6f 6e 2e 20 2a 2f 0a 20 20 69 6e 74 20 62 55 6e  on. */.  int bUn
27e0: 64 65 72 50 72 65 73 73 75 72 65 3b 20 20 20 20  derPressure;    
27f0: 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20          /* True 
2800: 69 66 20 6c 6f 77 20 6f 6e 20 50 41 47 45 43 41  if low on PAGECA
2810: 43 48 45 20 6d 65 6d 6f 72 79 20 2a 2f 0a 7d 20  CHE memory */.} 
2820: 70 63 61 63 68 65 31 5f 67 3b 0a 0a 2f 2a 0a 2a  pcache1_g;../*.*
2830: 2a 20 41 6c 6c 20 63 6f 64 65 20 69 6e 20 74 68  * All code in th
2840: 69 73 20 66 69 6c 65 20 73 68 6f 75 6c 64 20 61  is file should a
2850: 63 63 65 73 73 20 74 68 65 20 67 6c 6f 62 61 6c  ccess the global
2860: 20 73 74 72 75 63 74 75 72 65 20 61 62 6f 76 65   structure above
2870: 20 76 69 61 20 74 68 65 0a 2a 2a 20 61 6c 69 61   via the.** alia
2880: 73 20 22 70 63 61 63 68 65 31 22 2e 20 54 68 69  s "pcache1". Thi
2890: 73 20 65 6e 73 75 72 65 73 20 74 68 61 74 20 74  s ensures that t
28a0: 68 65 20 57 53 44 20 65 6d 75 6c 61 74 69 6f 6e  he WSD emulation
28b0: 20 69 73 20 75 73 65 64 20 77 68 65 6e 0a 2a 2a   is used when.**
28c0: 20 63 6f 6d 70 69 6c 69 6e 67 20 66 6f 72 20 73   compiling for s
28d0: 79 73 74 65 6d 73 20 74 68 61 74 20 64 6f 20 6e  ystems that do n
28e0: 6f 74 20 73 75 70 70 6f 72 74 20 72 65 61 6c 20  ot support real 
28f0: 57 53 44 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20  WSD..*/.#define 
2900: 70 63 61 63 68 65 31 20 28 47 4c 4f 42 41 4c 28  pcache1 (GLOBAL(
2910: 73 74 72 75 63 74 20 50 43 61 63 68 65 47 6c 6f  struct PCacheGlo
2920: 62 61 6c 2c 20 70 63 61 63 68 65 31 5f 67 29 29  bal, pcache1_g))
2930: 0a 0a 2f 2a 0a 2a 2a 20 4d 61 63 72 6f 73 20 74  ../*.** Macros t
2940: 6f 20 65 6e 74 65 72 20 61 6e 64 20 6c 65 61 76  o enter and leav
2950: 65 20 74 68 65 20 50 43 61 63 68 65 20 4c 52 55  e the PCache LRU
2960: 20 6d 75 74 65 78 2e 0a 2a 2f 0a 23 69 66 20 21   mutex..*/.#if !
2970: 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 45  defined(SQLITE_E
2980: 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e  NABLE_MEMORY_MAN
2990: 41 47 45 4d 45 4e 54 29 20 7c 7c 20 53 51 4c 49  AGEMENT) || SQLI
29a0: 54 45 5f 54 48 52 45 41 44 53 41 46 45 3d 3d 30  TE_THREADSAFE==0
29b0: 0a 23 20 64 65 66 69 6e 65 20 70 63 61 63 68 65  .# define pcache
29c0: 31 45 6e 74 65 72 4d 75 74 65 78 28 58 29 20 20  1EnterMutex(X)  
29d0: 61 73 73 65 72 74 28 28 58 29 2d 3e 6d 75 74 65  assert((X)->mute
29e0: 78 3d 3d 30 29 0a 23 20 64 65 66 69 6e 65 20 70  x==0).# define p
29f0: 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78  cache1LeaveMutex
2a00: 28 58 29 20 20 61 73 73 65 72 74 28 28 58 29 2d  (X)  assert((X)-
2a10: 3e 6d 75 74 65 78 3d 3d 30 29 0a 23 20 64 65 66  >mutex==0).# def
2a20: 69 6e 65 20 50 43 41 43 48 45 31 5f 4d 49 47 48  ine PCACHE1_MIGH
2a30: 54 5f 55 53 45 5f 47 52 4f 55 50 5f 4d 55 54 45  T_USE_GROUP_MUTE
2a40: 58 20 30 0a 23 65 6c 73 65 0a 23 20 64 65 66 69  X 0.#else.# defi
2a50: 6e 65 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d  ne pcache1EnterM
2a60: 75 74 65 78 28 58 29 20 73 71 6c 69 74 65 33 5f  utex(X) sqlite3_
2a70: 6d 75 74 65 78 5f 65 6e 74 65 72 28 28 58 29 2d  mutex_enter((X)-
2a80: 3e 6d 75 74 65 78 29 0a 23 20 64 65 66 69 6e 65  >mutex).# define
2a90: 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74   pcache1LeaveMut
2aa0: 65 78 28 58 29 20 73 71 6c 69 74 65 33 5f 6d 75  ex(X) sqlite3_mu
2ab0: 74 65 78 5f 6c 65 61 76 65 28 28 58 29 2d 3e 6d  tex_leave((X)->m
2ac0: 75 74 65 78 29 0a 23 20 64 65 66 69 6e 65 20 50  utex).# define P
2ad0: 43 41 43 48 45 31 5f 4d 49 47 48 54 5f 55 53 45  CACHE1_MIGHT_USE
2ae0: 5f 47 52 4f 55 50 5f 4d 55 54 45 58 20 31 0a 23  _GROUP_MUTEX 1.#
2af0: 65 6e 64 69 66 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a  endif../********
2b00: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2b10: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2b20: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2b30: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2b40: 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 2a 2a 2a 2a 2a 2a  ******/./*******
2b50: 2a 20 50 61 67 65 20 41 6c 6c 6f 63 61 74 69 6f  * Page Allocatio
2b60: 6e 2f 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f  n/SQLITE_CONFIG_
2b70: 50 43 41 43 48 45 20 52 65 6c 61 74 65 64 20 46  PCACHE Related F
2b80: 75 6e 63 74 69 6f 6e 73 20 2a 2a 2a 2a 2a 2a 2a  unctions *******
2b90: 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 0a 2f 2a 0a 2a 2a  *******/.../*.**
2ba0: 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   This function i
2bb0: 73 20 63 61 6c 6c 65 64 20 64 75 72 69 6e 67 20  s called during 
2bc0: 69 6e 69 74 69 61 6c 69 7a 61 74 69 6f 6e 20 69  initialization i
2bd0: 66 20 61 20 73 74 61 74 69 63 20 62 75 66 66 65  f a static buffe
2be0: 72 20 69 73 20 0a 2a 2a 20 73 75 70 70 6c 69 65  r is .** supplie
2bf0: 64 20 74 6f 20 75 73 65 20 66 6f 72 20 74 68 65  d to use for the
2c00: 20 70 61 67 65 2d 63 61 63 68 65 20 62 79 20 70   page-cache by p
2c10: 61 73 73 69 6e 67 20 74 68 65 20 53 51 4c 49 54  assing the SQLIT
2c20: 45 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41 43  E_CONFIG_PAGECAC
2c30: 48 45 0a 2a 2a 20 76 65 72 62 20 74 6f 20 73 71  HE.** verb to sq
2c40: 6c 69 74 65 33 5f 63 6f 6e 66 69 67 28 29 2e 20  lite3_config(). 
2c50: 50 61 72 61 6d 65 74 65 72 20 70 42 75 66 20 70  Parameter pBuf p
2c60: 6f 69 6e 74 73 20 74 6f 20 61 6e 20 61 6c 6c 6f  oints to an allo
2c70: 63 61 74 69 6f 6e 20 6c 61 72 67 65 0a 2a 2a 20  cation large.** 
2c80: 65 6e 6f 75 67 68 20 74 6f 20 63 6f 6e 74 61 69  enough to contai
2c90: 6e 20 27 6e 27 20 62 75 66 66 65 72 73 20 6f 66  n 'n' buffers of
2ca0: 20 27 73 7a 27 20 62 79 74 65 73 20 65 61 63 68   'sz' bytes each
2cb0: 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75  ..**.** This rou
2cc0: 74 69 6e 65 20 69 73 20 63 61 6c 6c 65 64 20 66  tine is called f
2cd0: 72 6f 6d 20 73 71 6c 69 74 65 33 5f 69 6e 69 74  rom sqlite3_init
2ce0: 69 61 6c 69 7a 65 28 29 20 61 6e 64 20 73 6f 20  ialize() and so 
2cf0: 69 74 20 69 73 20 67 75 61 72 61 6e 74 65 65 64  it is guaranteed
2d00: 0a 2a 2a 20 74 6f 20 62 65 20 73 65 72 69 61 6c  .** to be serial
2d10: 69 7a 65 64 20 61 6c 72 65 61 64 79 2e 20 20 54  ized already.  T
2d20: 68 65 72 65 20 69 73 20 6e 6f 20 6e 65 65 64 20  here is no need 
2d30: 66 6f 72 20 66 75 72 74 68 65 72 20 6d 75 74 65  for further mute
2d40: 78 69 6e 67 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71  xing..*/.void sq
2d50: 6c 69 74 65 33 50 43 61 63 68 65 42 75 66 66 65  lite3PCacheBuffe
2d60: 72 53 65 74 75 70 28 76 6f 69 64 20 2a 70 42 75  rSetup(void *pBu
2d70: 66 2c 20 69 6e 74 20 73 7a 2c 20 69 6e 74 20 6e  f, int sz, int n
2d80: 29 7b 0a 20 20 69 66 28 20 70 63 61 63 68 65 31  ){.  if( pcache1
2d90: 2e 69 73 49 6e 69 74 20 29 7b 0a 20 20 20 20 50  .isInit ){.    P
2da0: 67 46 72 65 65 73 6c 6f 74 20 2a 70 3b 0a 20 20  gFreeslot *p;.  
2db0: 20 20 69 66 28 20 70 42 75 66 3d 3d 30 20 29 20    if( pBuf==0 ) 
2dc0: 73 7a 20 3d 20 6e 20 3d 20 30 3b 0a 20 20 20 20  sz = n = 0;.    
2dd0: 69 66 28 20 6e 3d 3d 30 20 29 20 73 7a 20 3d 20  if( n==0 ) sz = 
2de0: 30 3b 0a 20 20 20 20 73 7a 20 3d 20 52 4f 55 4e  0;.    sz = ROUN
2df0: 44 44 4f 57 4e 38 28 73 7a 29 3b 0a 20 20 20 20  DDOWN8(sz);.    
2e00: 70 63 61 63 68 65 31 2e 73 7a 53 6c 6f 74 20 3d  pcache1.szSlot =
2e10: 20 73 7a 3b 0a 20 20 20 20 70 63 61 63 68 65 31   sz;.    pcache1
2e20: 2e 6e 53 6c 6f 74 20 3d 20 70 63 61 63 68 65 31  .nSlot = pcache1
2e30: 2e 6e 46 72 65 65 53 6c 6f 74 20 3d 20 6e 3b 0a  .nFreeSlot = n;.
2e40: 20 20 20 20 70 63 61 63 68 65 31 2e 6e 52 65 73      pcache1.nRes
2e50: 65 72 76 65 20 3d 20 6e 3e 39 30 20 3f 20 31 30  erve = n>90 ? 10
2e60: 20 3a 20 28 6e 2f 31 30 20 2b 20 31 29 3b 0a 20   : (n/10 + 1);. 
2e70: 20 20 20 70 63 61 63 68 65 31 2e 70 53 74 61 72     pcache1.pStar
2e80: 74 20 3d 20 70 42 75 66 3b 0a 20 20 20 20 70 63  t = pBuf;.    pc
2e90: 61 63 68 65 31 2e 70 46 72 65 65 20 3d 20 30 3b  ache1.pFree = 0;
2ea0: 0a 20 20 20 20 70 63 61 63 68 65 31 2e 62 55 6e  .    pcache1.bUn
2eb0: 64 65 72 50 72 65 73 73 75 72 65 20 3d 20 30 3b  derPressure = 0;
2ec0: 0a 20 20 20 20 77 68 69 6c 65 28 20 6e 2d 2d 20  .    while( n-- 
2ed0: 29 7b 0a 20 20 20 20 20 20 70 20 3d 20 28 50 67  ){.      p = (Pg
2ee0: 46 72 65 65 73 6c 6f 74 2a 29 70 42 75 66 3b 0a  Freeslot*)pBuf;.
2ef0: 20 20 20 20 20 20 70 2d 3e 70 4e 65 78 74 20 3d        p->pNext =
2f00: 20 70 63 61 63 68 65 31 2e 70 46 72 65 65 3b 0a   pcache1.pFree;.
2f10: 20 20 20 20 20 20 70 63 61 63 68 65 31 2e 70 46        pcache1.pF
2f20: 72 65 65 20 3d 20 70 3b 0a 20 20 20 20 20 20 70  ree = p;.      p
2f30: 42 75 66 20 3d 20 28 76 6f 69 64 2a 29 26 28 28  Buf = (void*)&((
2f40: 63 68 61 72 2a 29 70 42 75 66 29 5b 73 7a 5d 3b  char*)pBuf)[sz];
2f50: 0a 20 20 20 20 7d 0a 20 20 20 20 70 63 61 63 68  .    }.    pcach
2f60: 65 31 2e 70 45 6e 64 20 3d 20 70 42 75 66 3b 0a  e1.pEnd = pBuf;.
2f70: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 72 79    }.}../*.** Try
2f80: 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20 74   to initialize t
2f90: 68 65 20 70 43 61 63 68 65 2d 3e 70 46 72 65 65  he pCache->pFree
2fa0: 20 61 6e 64 20 70 43 61 63 68 65 2d 3e 70 42 75   and pCache->pBu
2fb0: 6c 6b 20 66 69 65 6c 64 73 2e 20 20 52 65 74 75  lk fields.  Retu
2fc0: 72 6e 0a 2a 2a 20 74 72 75 65 20 69 66 20 70 43  rn.** true if pC
2fd0: 61 63 68 65 2d 3e 70 46 72 65 65 20 65 6e 64 73  ache->pFree ends
2fe0: 20 75 70 20 63 6f 6e 74 61 69 6e 69 6e 67 20 6f   up containing o
2ff0: 6e 65 20 6f 72 20 6d 6f 72 65 20 66 72 65 65 20  ne or more free 
3000: 70 61 67 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  pages..*/.static
3010: 20 69 6e 74 20 70 63 61 63 68 65 31 49 6e 69 74   int pcache1Init
3020: 42 75 6c 6b 28 50 43 61 63 68 65 31 20 2a 70 43  Bulk(PCache1 *pC
3030: 61 63 68 65 29 7b 0a 20 20 69 36 34 20 73 7a 42  ache){.  i64 szB
3040: 75 6c 6b 3b 0a 20 20 63 68 61 72 20 2a 7a 42 75  ulk;.  char *zBu
3050: 6c 6b 3b 0a 20 20 69 66 28 20 70 63 61 63 68 65  lk;.  if( pcache
3060: 31 2e 6e 49 6e 69 74 50 61 67 65 3d 3d 30 20 29  1.nInitPage==0 )
3070: 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 2f 2a 20   return 0;.  /* 
3080: 44 6f 20 6e 6f 74 20 62 6f 74 68 65 72 20 77 69  Do not bother wi
3090: 74 68 20 61 20 62 75 6c 6b 20 61 6c 6c 6f 63 61  th a bulk alloca
30a0: 74 69 6f 6e 20 69 66 20 74 68 65 20 63 61 63 68  tion if the cach
30b0: 65 20 73 69 7a 65 20 76 65 72 79 20 73 6d 61 6c  e size very smal
30c0: 6c 20 2a 2f 0a 20 20 69 66 28 20 70 43 61 63 68  l */.  if( pCach
30d0: 65 2d 3e 6e 4d 61 78 3c 33 20 29 20 72 65 74 75  e->nMax<3 ) retu
30e0: 72 6e 20 30 3b 0a 20 20 73 71 6c 69 74 65 33 42  rn 0;.  sqlite3B
30f0: 65 67 69 6e 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63  eginBenignMalloc
3100: 28 29 3b 0a 20 20 69 66 28 20 70 63 61 63 68 65  ();.  if( pcache
3110: 31 2e 6e 49 6e 69 74 50 61 67 65 3e 30 20 29 7b  1.nInitPage>0 ){
3120: 0a 20 20 20 20 73 7a 42 75 6c 6b 20 3d 20 70 43  .    szBulk = pC
3130: 61 63 68 65 2d 3e 73 7a 41 6c 6c 6f 63 20 2a 20  ache->szAlloc * 
3140: 28 69 36 34 29 70 63 61 63 68 65 31 2e 6e 49 6e  (i64)pcache1.nIn
3150: 69 74 50 61 67 65 3b 0a 20 20 7d 65 6c 73 65 7b  itPage;.  }else{
3160: 0a 20 20 20 20 73 7a 42 75 6c 6b 20 3d 20 2d 31  .    szBulk = -1
3170: 30 32 34 20 2a 20 28 69 36 34 29 70 63 61 63 68  024 * (i64)pcach
3180: 65 31 2e 6e 49 6e 69 74 50 61 67 65 3b 0a 20 20  e1.nInitPage;.  
3190: 7d 0a 20 20 69 66 28 20 73 7a 42 75 6c 6b 20 3e  }.  if( szBulk >
31a0: 20 70 43 61 63 68 65 2d 3e 73 7a 41 6c 6c 6f 63   pCache->szAlloc
31b0: 2a 28 69 36 34 29 70 43 61 63 68 65 2d 3e 6e 4d  *(i64)pCache->nM
31c0: 61 78 20 29 7b 0a 20 20 20 20 73 7a 42 75 6c 6b  ax ){.    szBulk
31d0: 20 3d 20 70 43 61 63 68 65 2d 3e 73 7a 41 6c 6c   = pCache->szAll
31e0: 6f 63 2a 28 69 36 34 29 70 43 61 63 68 65 2d 3e  oc*(i64)pCache->
31f0: 6e 4d 61 78 3b 0a 20 20 7d 0a 20 20 7a 42 75 6c  nMax;.  }.  zBul
3200: 6b 20 3d 20 70 43 61 63 68 65 2d 3e 70 42 75 6c  k = pCache->pBul
3210: 6b 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f  k = sqlite3Mallo
3220: 63 28 20 73 7a 42 75 6c 6b 20 29 3b 0a 20 20 73  c( szBulk );.  s
3230: 71 6c 69 74 65 33 45 6e 64 42 65 6e 69 67 6e 4d  qlite3EndBenignM
3240: 61 6c 6c 6f 63 28 29 3b 0a 20 20 69 66 28 20 7a  alloc();.  if( z
3250: 42 75 6c 6b 20 29 7b 0a 20 20 20 20 69 6e 74 20  Bulk ){.    int 
3260: 6e 42 75 6c 6b 20 3d 20 73 71 6c 69 74 65 33 4d  nBulk = sqlite3M
3270: 61 6c 6c 6f 63 53 69 7a 65 28 7a 42 75 6c 6b 29  allocSize(zBulk)
3280: 2f 70 43 61 63 68 65 2d 3e 73 7a 41 6c 6c 6f 63  /pCache->szAlloc
3290: 3b 0a 20 20 20 20 64 6f 7b 0a 20 20 20 20 20 20  ;.    do{.      
32a0: 50 67 48 64 72 31 20 2a 70 58 20 3d 20 28 50 67  PgHdr1 *pX = (Pg
32b0: 48 64 72 31 2a 29 26 7a 42 75 6c 6b 5b 70 43 61  Hdr1*)&zBulk[pCa
32c0: 63 68 65 2d 3e 73 7a 50 61 67 65 5d 3b 0a 20 20  che->szPage];.  
32d0: 20 20 20 20 70 58 2d 3e 70 61 67 65 2e 70 42 75      pX->page.pBu
32e0: 66 20 3d 20 7a 42 75 6c 6b 3b 0a 20 20 20 20 20  f = zBulk;.     
32f0: 20 70 58 2d 3e 70 61 67 65 2e 70 45 78 74 72 61   pX->page.pExtra
3300: 20 3d 20 26 70 58 5b 31 5d 3b 0a 20 20 20 20 20   = &pX[1];.     
3310: 20 70 58 2d 3e 69 73 42 75 6c 6b 4c 6f 63 61 6c   pX->isBulkLocal
3320: 20 3d 20 31 3b 0a 20 20 20 20 20 20 70 58 2d 3e   = 1;.      pX->
3330: 69 73 41 6e 63 68 6f 72 20 3d 20 30 3b 0a 20 20  isAnchor = 0;.  
3340: 20 20 20 20 70 58 2d 3e 70 4e 65 78 74 20 3d 20      pX->pNext = 
3350: 70 43 61 63 68 65 2d 3e 70 46 72 65 65 3b 0a 20  pCache->pFree;. 
3360: 20 20 20 20 20 70 43 61 63 68 65 2d 3e 70 46 72       pCache->pFr
3370: 65 65 20 3d 20 70 58 3b 0a 20 20 20 20 20 20 7a  ee = pX;.      z
3380: 42 75 6c 6b 20 2b 3d 20 70 43 61 63 68 65 2d 3e  Bulk += pCache->
3390: 73 7a 41 6c 6c 6f 63 3b 0a 20 20 20 20 7d 77 68  szAlloc;.    }wh
33a0: 69 6c 65 28 20 2d 2d 6e 42 75 6c 6b 20 29 3b 0a  ile( --nBulk );.
33b0: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 70 43 61    }.  return pCa
33c0: 63 68 65 2d 3e 70 46 72 65 65 21 3d 30 3b 0a 7d  che->pFree!=0;.}
33d0: 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6c 6c 6f 63 20 66  ../*.** Malloc f
33e0: 75 6e 63 74 69 6f 6e 20 75 73 65 64 20 77 69 74  unction used wit
33f0: 68 69 6e 20 74 68 69 73 20 66 69 6c 65 20 74 6f  hin this file to
3400: 20 61 6c 6c 6f 63 61 74 65 20 73 70 61 63 65 20   allocate space 
3410: 66 72 6f 6d 20 74 68 65 20 62 75 66 66 65 72 0a  from the buffer.
3420: 2a 2a 20 63 6f 6e 66 69 67 75 72 65 64 20 75 73  ** configured us
3430: 69 6e 67 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66  ing sqlite3_conf
3440: 69 67 28 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47  ig(SQLITE_CONFIG
3450: 5f 50 41 47 45 43 41 43 48 45 29 20 6f 70 74 69  _PAGECACHE) opti
3460: 6f 6e 2e 20 49 66 20 6e 6f 20 0a 2a 2a 20 73 75  on. If no .** su
3470: 63 68 20 62 75 66 66 65 72 20 65 78 69 73 74 73  ch buffer exists
3480: 20 6f 72 20 74 68 65 72 65 20 69 73 20 6e 6f 20   or there is no 
3490: 73 70 61 63 65 20 6c 65 66 74 20 69 6e 20 69 74  space left in it
34a0: 2c 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  , this function 
34b0: 66 61 6c 6c 73 20 0a 2a 2a 20 62 61 63 6b 20 74  falls .** back t
34c0: 6f 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28  o sqlite3Malloc(
34d0: 29 2e 0a 2a 2a 0a 2a 2a 20 4d 75 6c 74 69 70 6c  )..**.** Multipl
34e0: 65 20 74 68 72 65 61 64 73 20 63 61 6e 20 72 75  e threads can ru
34f0: 6e 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 61  n this routine a
3500: 74 20 74 68 65 20 73 61 6d 65 20 74 69 6d 65 2e  t the same time.
3510: 20 20 47 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c    Global variabl
3520: 65 73 0a 2a 2a 20 69 6e 20 70 63 61 63 68 65 31  es.** in pcache1
3530: 20 6e 65 65 64 20 74 6f 20 62 65 20 70 72 6f 74   need to be prot
3540: 65 63 74 65 64 20 76 69 61 20 6d 75 74 65 78 2e  ected via mutex.
3550: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
3560: 2a 70 63 61 63 68 65 31 41 6c 6c 6f 63 28 69 6e  *pcache1Alloc(in
3570: 74 20 6e 42 79 74 65 29 7b 0a 20 20 76 6f 69 64  t nByte){.  void
3580: 20 2a 70 20 3d 20 30 3b 0a 20 20 61 73 73 65 72   *p = 0;.  asser
3590: 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78  t( sqlite3_mutex
35a0: 5f 6e 6f 74 68 65 6c 64 28 70 63 61 63 68 65 31  _notheld(pcache1
35b0: 2e 67 72 70 2e 6d 75 74 65 78 29 20 29 3b 0a 20  .grp.mutex) );. 
35c0: 20 69 66 28 20 6e 42 79 74 65 3c 3d 70 63 61 63   if( nByte<=pcac
35d0: 68 65 31 2e 73 7a 53 6c 6f 74 20 29 7b 0a 20 20  he1.szSlot ){.  
35e0: 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f    sqlite3_mutex_
35f0: 65 6e 74 65 72 28 70 63 61 63 68 65 31 2e 6d 75  enter(pcache1.mu
3600: 74 65 78 29 3b 0a 20 20 20 20 70 20 3d 20 28 50  tex);.    p = (P
3610: 67 48 64 72 31 20 2a 29 70 63 61 63 68 65 31 2e  gHdr1 *)pcache1.
3620: 70 46 72 65 65 3b 0a 20 20 20 20 69 66 28 20 70  pFree;.    if( p
3630: 20 29 7b 0a 20 20 20 20 20 20 70 63 61 63 68 65   ){.      pcache
3640: 31 2e 70 46 72 65 65 20 3d 20 70 63 61 63 68 65  1.pFree = pcache
3650: 31 2e 70 46 72 65 65 2d 3e 70 4e 65 78 74 3b 0a  1.pFree->pNext;.
3660: 20 20 20 20 20 20 70 63 61 63 68 65 31 2e 6e 46        pcache1.nF
3670: 72 65 65 53 6c 6f 74 2d 2d 3b 0a 20 20 20 20 20  reeSlot--;.     
3680: 20 70 63 61 63 68 65 31 2e 62 55 6e 64 65 72 50   pcache1.bUnderP
3690: 72 65 73 73 75 72 65 20 3d 20 70 63 61 63 68 65  ressure = pcache
36a0: 31 2e 6e 46 72 65 65 53 6c 6f 74 3c 70 63 61 63  1.nFreeSlot<pcac
36b0: 68 65 31 2e 6e 52 65 73 65 72 76 65 3b 0a 20 20  he1.nReserve;.  
36c0: 20 20 20 20 61 73 73 65 72 74 28 20 70 63 61 63      assert( pcac
36d0: 68 65 31 2e 6e 46 72 65 65 53 6c 6f 74 3e 3d 30  he1.nFreeSlot>=0
36e0: 20 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65   );.      sqlite
36f0: 33 53 74 61 74 75 73 48 69 67 68 77 61 74 65 72  3StatusHighwater
3700: 28 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50  (SQLITE_STATUS_P
3710: 41 47 45 43 41 43 48 45 5f 53 49 5a 45 2c 20 6e  AGECACHE_SIZE, n
3720: 42 79 74 65 29 3b 0a 20 20 20 20 20 20 73 71 6c  Byte);.      sql
3730: 69 74 65 33 53 74 61 74 75 73 55 70 28 53 51 4c  ite3StatusUp(SQL
3740: 49 54 45 5f 53 54 41 54 55 53 5f 50 41 47 45 43  ITE_STATUS_PAGEC
3750: 41 43 48 45 5f 55 53 45 44 2c 20 31 29 3b 0a 20  ACHE_USED, 1);. 
3760: 20 20 20 7d 0a 20 20 20 20 73 71 6c 69 74 65 33     }.    sqlite3
3770: 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 70 63 61  _mutex_leave(pca
3780: 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a 20 20 7d  che1.mutex);.  }
3790: 0a 20 20 69 66 28 20 70 3d 3d 30 20 29 7b 0a 20  .  if( p==0 ){. 
37a0: 20 20 20 2f 2a 20 4d 65 6d 6f 72 79 20 69 73 20     /* Memory is 
37b0: 6e 6f 74 20 61 76 61 69 6c 61 62 6c 65 20 69 6e  not available in
37c0: 20 74 68 65 20 53 51 4c 49 54 45 5f 43 4f 4e 46   the SQLITE_CONF
37d0: 49 47 5f 50 41 47 45 43 41 43 48 45 20 70 6f 6f  IG_PAGECACHE poo
37e0: 6c 2e 20 20 47 65 74 0a 20 20 20 20 2a 2a 20 69  l.  Get.    ** i
37f0: 74 20 66 72 6f 6d 20 73 71 6c 69 74 65 33 4d 61  t from sqlite3Ma
3800: 6c 6c 6f 63 20 69 6e 73 74 65 61 64 2e 0a 20 20  lloc instead..  
3810: 20 20 2a 2f 0a 20 20 20 20 70 20 3d 20 73 71 6c    */.    p = sql
3820: 69 74 65 33 4d 61 6c 6c 6f 63 28 6e 42 79 74 65  ite3Malloc(nByte
3830: 29 3b 0a 23 69 66 6e 64 65 66 20 53 51 4c 49 54  );.#ifndef SQLIT
3840: 45 5f 44 49 53 41 42 4c 45 5f 50 41 47 45 43 41  E_DISABLE_PAGECA
3850: 43 48 45 5f 4f 56 45 52 46 4c 4f 57 5f 53 54 41  CHE_OVERFLOW_STA
3860: 54 53 0a 20 20 20 20 69 66 28 20 70 20 29 7b 0a  TS.    if( p ){.
3870: 20 20 20 20 20 20 69 6e 74 20 73 7a 20 3d 20 73        int sz = s
3880: 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 53 69 7a 65  qlite3MallocSize
3890: 28 70 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74  (p);.      sqlit
38a0: 65 33 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28 70  e3_mutex_enter(p
38b0: 63 61 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a 20  cache1.mutex);. 
38c0: 20 20 20 20 20 73 71 6c 69 74 65 33 53 74 61 74       sqlite3Stat
38d0: 75 73 48 69 67 68 77 61 74 65 72 28 53 51 4c 49  usHighwater(SQLI
38e0: 54 45 5f 53 54 41 54 55 53 5f 50 41 47 45 43 41  TE_STATUS_PAGECA
38f0: 43 48 45 5f 53 49 5a 45 2c 20 6e 42 79 74 65 29  CHE_SIZE, nByte)
3900: 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 53  ;.      sqlite3S
3910: 74 61 74 75 73 55 70 28 53 51 4c 49 54 45 5f 53  tatusUp(SQLITE_S
3920: 54 41 54 55 53 5f 50 41 47 45 43 41 43 48 45 5f  TATUS_PAGECACHE_
3930: 4f 56 45 52 46 4c 4f 57 2c 20 73 7a 29 3b 0a 20  OVERFLOW, sz);. 
3940: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 75 74       sqlite3_mut
3950: 65 78 5f 6c 65 61 76 65 28 70 63 61 63 68 65 31  ex_leave(pcache1
3960: 2e 6d 75 74 65 78 29 3b 0a 20 20 20 20 7d 0a 23  .mutex);.    }.#
3970: 65 6e 64 69 66 0a 20 20 20 20 73 71 6c 69 74 65  endif.    sqlite
3980: 33 4d 65 6d 64 65 62 75 67 53 65 74 54 79 70 65  3MemdebugSetType
3990: 28 70 2c 20 4d 45 4d 54 59 50 45 5f 50 43 41 43  (p, MEMTYPE_PCAC
39a0: 48 45 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  HE);.  }.  retur
39b0: 6e 20 70 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72  n p;.}../*.** Fr
39c0: 65 65 20 61 6e 20 61 6c 6c 6f 63 61 74 65 64 20  ee an allocated 
39d0: 62 75 66 66 65 72 20 6f 62 74 61 69 6e 65 64 20  buffer obtained 
39e0: 66 72 6f 6d 20 70 63 61 63 68 65 31 41 6c 6c 6f  from pcache1Allo
39f0: 63 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  c()..*/.static v
3a00: 6f 69 64 20 70 63 61 63 68 65 31 46 72 65 65 28  oid pcache1Free(
3a10: 76 6f 69 64 20 2a 70 29 7b 0a 20 20 69 66 28 20  void *p){.  if( 
3a20: 70 3d 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a 20  p==0 ) return;. 
3a30: 20 69 66 28 20 53 51 4c 49 54 45 5f 57 49 54 48   if( SQLITE_WITH
3a40: 49 4e 28 70 2c 20 70 63 61 63 68 65 31 2e 70 53  IN(p, pcache1.pS
3a50: 74 61 72 74 2c 20 70 63 61 63 68 65 31 2e 70 45  tart, pcache1.pE
3a60: 6e 64 29 20 29 7b 0a 20 20 20 20 50 67 46 72 65  nd) ){.    PgFre
3a70: 65 73 6c 6f 74 20 2a 70 53 6c 6f 74 3b 0a 20 20  eslot *pSlot;.  
3a80: 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f    sqlite3_mutex_
3a90: 65 6e 74 65 72 28 70 63 61 63 68 65 31 2e 6d 75  enter(pcache1.mu
3aa0: 74 65 78 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  tex);.    sqlite
3ab0: 33 53 74 61 74 75 73 44 6f 77 6e 28 53 51 4c 49  3StatusDown(SQLI
3ac0: 54 45 5f 53 54 41 54 55 53 5f 50 41 47 45 43 41  TE_STATUS_PAGECA
3ad0: 43 48 45 5f 55 53 45 44 2c 20 31 29 3b 0a 20 20  CHE_USED, 1);.  
3ae0: 20 20 70 53 6c 6f 74 20 3d 20 28 50 67 46 72 65    pSlot = (PgFre
3af0: 65 73 6c 6f 74 2a 29 70 3b 0a 20 20 20 20 70 53  eslot*)p;.    pS
3b00: 6c 6f 74 2d 3e 70 4e 65 78 74 20 3d 20 70 63 61  lot->pNext = pca
3b10: 63 68 65 31 2e 70 46 72 65 65 3b 0a 20 20 20 20  che1.pFree;.    
3b20: 70 63 61 63 68 65 31 2e 70 46 72 65 65 20 3d 20  pcache1.pFree = 
3b30: 70 53 6c 6f 74 3b 0a 20 20 20 20 70 63 61 63 68  pSlot;.    pcach
3b40: 65 31 2e 6e 46 72 65 65 53 6c 6f 74 2b 2b 3b 0a  e1.nFreeSlot++;.
3b50: 20 20 20 20 70 63 61 63 68 65 31 2e 62 55 6e 64      pcache1.bUnd
3b60: 65 72 50 72 65 73 73 75 72 65 20 3d 20 70 63 61  erPressure = pca
3b70: 63 68 65 31 2e 6e 46 72 65 65 53 6c 6f 74 3c 70  che1.nFreeSlot<p
3b80: 63 61 63 68 65 31 2e 6e 52 65 73 65 72 76 65 3b  cache1.nReserve;
3b90: 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 63 61  .    assert( pca
3ba0: 63 68 65 31 2e 6e 46 72 65 65 53 6c 6f 74 3c 3d  che1.nFreeSlot<=
3bb0: 70 63 61 63 68 65 31 2e 6e 53 6c 6f 74 20 29 3b  pcache1.nSlot );
3bc0: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 75 74  .    sqlite3_mut
3bd0: 65 78 5f 6c 65 61 76 65 28 70 63 61 63 68 65 31  ex_leave(pcache1
3be0: 2e 6d 75 74 65 78 29 3b 0a 20 20 7d 65 6c 73 65  .mutex);.  }else
3bf0: 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20 73 71  {.    assert( sq
3c00: 6c 69 74 65 33 4d 65 6d 64 65 62 75 67 48 61 73  lite3MemdebugHas
3c10: 54 79 70 65 28 70 2c 20 4d 45 4d 54 59 50 45 5f  Type(p, MEMTYPE_
3c20: 50 43 41 43 48 45 29 20 29 3b 0a 20 20 20 20 73  PCACHE) );.    s
3c30: 71 6c 69 74 65 33 4d 65 6d 64 65 62 75 67 53 65  qlite3MemdebugSe
3c40: 74 54 79 70 65 28 70 2c 20 4d 45 4d 54 59 50 45  tType(p, MEMTYPE
3c50: 5f 48 45 41 50 29 3b 0a 23 69 66 6e 64 65 66 20  _HEAP);.#ifndef 
3c60: 53 51 4c 49 54 45 5f 44 49 53 41 42 4c 45 5f 50  SQLITE_DISABLE_P
3c70: 41 47 45 43 41 43 48 45 5f 4f 56 45 52 46 4c 4f  AGECACHE_OVERFLO
3c80: 57 5f 53 54 41 54 53 0a 20 20 20 20 7b 0a 20 20  W_STATS.    {.  
3c90: 20 20 20 20 69 6e 74 20 6e 46 72 65 65 64 20 3d      int nFreed =
3ca0: 20 30 3b 0a 20 20 20 20 20 20 6e 46 72 65 65 64   0;.      nFreed
3cb0: 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63   = sqlite3Malloc
3cc0: 53 69 7a 65 28 70 29 3b 0a 20 20 20 20 20 20 73  Size(p);.      s
3cd0: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e 74  qlite3_mutex_ent
3ce0: 65 72 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78  er(pcache1.mutex
3cf0: 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  );.      sqlite3
3d00: 53 74 61 74 75 73 44 6f 77 6e 28 53 51 4c 49 54  StatusDown(SQLIT
3d10: 45 5f 53 54 41 54 55 53 5f 50 41 47 45 43 41 43  E_STATUS_PAGECAC
3d20: 48 45 5f 4f 56 45 52 46 4c 4f 57 2c 20 6e 46 72  HE_OVERFLOW, nFr
3d30: 65 65 64 29 3b 0a 20 20 20 20 20 20 73 71 6c 69  eed);.      sqli
3d40: 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28  te3_mutex_leave(
3d50: 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a  pcache1.mutex);.
3d60: 20 20 20 20 7d 0a 23 65 6e 64 69 66 0a 20 20 20      }.#endif.   
3d70: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 29   sqlite3_free(p)
3d80: 3b 0a 20 20 7d 0a 7d 0a 0a 23 69 66 64 65 66 20  ;.  }.}..#ifdef 
3d90: 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45  SQLITE_ENABLE_ME
3da0: 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 0a  MORY_MANAGEMENT.
3db0: 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65  /*.** Return the
3dc0: 20 73 69 7a 65 20 6f 66 20 61 20 70 63 61 63 68   size of a pcach
3dd0: 65 20 61 6c 6c 6f 63 61 74 69 6f 6e 0a 2a 2f 0a  e allocation.*/.
3de0: 73 74 61 74 69 63 20 69 6e 74 20 70 63 61 63 68  static int pcach
3df0: 65 31 4d 65 6d 53 69 7a 65 28 76 6f 69 64 20 2a  e1MemSize(void *
3e00: 70 29 7b 0a 20 20 69 66 28 20 70 3e 3d 70 63 61  p){.  if( p>=pca
3e10: 63 68 65 31 2e 70 53 74 61 72 74 20 26 26 20 70  che1.pStart && p
3e20: 3c 70 63 61 63 68 65 31 2e 70 45 6e 64 20 29 7b  <pcache1.pEnd ){
3e30: 0a 20 20 20 20 72 65 74 75 72 6e 20 70 63 61 63  .    return pcac
3e40: 68 65 31 2e 73 7a 53 6c 6f 74 3b 0a 20 20 7d 65  he1.szSlot;.  }e
3e50: 6c 73 65 7b 0a 20 20 20 20 69 6e 74 20 69 53 69  lse{.    int iSi
3e60: 7a 65 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20  ze;.    assert( 
3e70: 73 71 6c 69 74 65 33 4d 65 6d 64 65 62 75 67 48  sqlite3MemdebugH
3e80: 61 73 54 79 70 65 28 70 2c 20 4d 45 4d 54 59 50  asType(p, MEMTYP
3e90: 45 5f 50 43 41 43 48 45 29 20 29 3b 0a 20 20 20  E_PCACHE) );.   
3ea0: 20 73 71 6c 69 74 65 33 4d 65 6d 64 65 62 75 67   sqlite3Memdebug
3eb0: 53 65 74 54 79 70 65 28 70 2c 20 4d 45 4d 54 59  SetType(p, MEMTY
3ec0: 50 45 5f 48 45 41 50 29 3b 0a 20 20 20 20 69 53  PE_HEAP);.    iS
3ed0: 69 7a 65 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c  ize = sqlite3Mal
3ee0: 6c 6f 63 53 69 7a 65 28 70 29 3b 0a 20 20 20 20  locSize(p);.    
3ef0: 73 71 6c 69 74 65 33 4d 65 6d 64 65 62 75 67 53  sqlite3MemdebugS
3f00: 65 74 54 79 70 65 28 70 2c 20 4d 45 4d 54 59 50  etType(p, MEMTYP
3f10: 45 5f 50 43 41 43 48 45 29 3b 0a 20 20 20 20 72  E_PCACHE);.    r
3f20: 65 74 75 72 6e 20 69 53 69 7a 65 3b 0a 20 20 7d  eturn iSize;.  }
3f30: 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51 4c  .}.#endif /* SQL
3f40: 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52  ITE_ENABLE_MEMOR
3f50: 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 20 2a 2f 0a  Y_MANAGEMENT */.
3f60: 0a 2f 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65 20  ./*.** Allocate 
3f70: 61 20 6e 65 77 20 70 61 67 65 20 6f 62 6a 65 63  a new page objec
3f80: 74 20 69 6e 69 74 69 61 6c 6c 79 20 61 73 73 6f  t initially asso
3f90: 63 69 61 74 65 64 20 77 69 74 68 20 63 61 63 68  ciated with cach
3fa0: 65 20 70 43 61 63 68 65 2e 0a 2a 2f 0a 73 74 61  e pCache..*/.sta
3fb0: 74 69 63 20 50 67 48 64 72 31 20 2a 70 63 61 63  tic PgHdr1 *pcac
3fc0: 68 65 31 41 6c 6c 6f 63 50 61 67 65 28 50 43 61  he1AllocPage(PCa
3fd0: 63 68 65 31 20 2a 70 43 61 63 68 65 2c 20 69 6e  che1 *pCache, in
3fe0: 74 20 62 65 6e 69 67 6e 4d 61 6c 6c 6f 63 29 7b  t benignMalloc){
3ff0: 0a 20 20 50 67 48 64 72 31 20 2a 70 20 3d 20 30  .  PgHdr1 *p = 0
4000: 3b 0a 20 20 76 6f 69 64 20 2a 70 50 67 3b 0a 0a  ;.  void *pPg;..
4010: 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65    assert( sqlite
4020: 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 43 61  3_mutex_held(pCa
4030: 63 68 65 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75 74  che->pGroup->mut
4040: 65 78 29 20 29 3b 0a 20 20 69 66 28 20 70 43 61  ex) );.  if( pCa
4050: 63 68 65 2d 3e 70 46 72 65 65 20 7c 7c 20 28 70  che->pFree || (p
4060: 43 61 63 68 65 2d 3e 6e 50 61 67 65 3d 3d 30 20  Cache->nPage==0 
4070: 26 26 20 70 63 61 63 68 65 31 49 6e 69 74 42 75  && pcache1InitBu
4080: 6c 6b 28 70 43 61 63 68 65 29 29 20 29 7b 0a 20  lk(pCache)) ){. 
4090: 20 20 20 70 20 3d 20 70 43 61 63 68 65 2d 3e 70     p = pCache->p
40a0: 46 72 65 65 3b 0a 20 20 20 20 70 43 61 63 68 65  Free;.    pCache
40b0: 2d 3e 70 46 72 65 65 20 3d 20 70 2d 3e 70 4e 65  ->pFree = p->pNe
40c0: 78 74 3b 0a 20 20 20 20 70 2d 3e 70 4e 65 78 74  xt;.    p->pNext
40d0: 20 3d 20 30 3b 0a 20 20 7d 65 6c 73 65 7b 0a 23   = 0;.  }else{.#
40e0: 69 66 64 65 66 20 53 51 4c 49 54 45 5f 45 4e 41  ifdef SQLITE_ENA
40f0: 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47  BLE_MEMORY_MANAG
4100: 45 4d 45 4e 54 0a 20 20 20 20 2f 2a 20 54 68 65  EMENT.    /* The
4110: 20 67 72 6f 75 70 20 6d 75 74 65 78 20 6d 75 73   group mutex mus
4120: 74 20 62 65 20 72 65 6c 65 61 73 65 64 20 62 65  t be released be
4130: 66 6f 72 65 20 70 63 61 63 68 65 31 41 6c 6c 6f  fore pcache1Allo
4140: 63 28 29 20 69 73 20 63 61 6c 6c 65 64 2e 20 54  c() is called. T
4150: 68 69 73 0a 20 20 20 20 2a 2a 20 69 73 20 62 65  his.    ** is be
4160: 63 61 75 73 65 20 69 74 20 6d 69 67 68 74 20 63  cause it might c
4170: 61 6c 6c 20 73 71 6c 69 74 65 33 5f 72 65 6c 65  all sqlite3_rele
4180: 61 73 65 5f 6d 65 6d 6f 72 79 28 29 2c 20 77 68  ase_memory(), wh
4190: 69 63 68 20 61 73 73 75 6d 65 73 20 74 68 61 74  ich assumes that
41a0: 20 0a 20 20 20 20 2a 2a 20 74 68 69 73 20 6d 75   .    ** this mu
41b0: 74 65 78 20 69 73 20 6e 6f 74 20 68 65 6c 64 2e  tex is not held.
41c0: 20 2a 2f 0a 20 20 20 20 61 73 73 65 72 74 28 20   */.    assert( 
41d0: 70 63 61 63 68 65 31 2e 73 65 70 61 72 61 74 65  pcache1.separate
41e0: 43 61 63 68 65 3d 3d 30 20 29 3b 0a 20 20 20 20  Cache==0 );.    
41f0: 61 73 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e  assert( pCache->
4200: 70 47 72 6f 75 70 3d 3d 26 70 63 61 63 68 65 31  pGroup==&pcache1
4210: 2e 67 72 70 20 29 3b 0a 20 20 20 20 70 63 61 63  .grp );.    pcac
4220: 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 70 43  he1LeaveMutex(pC
4230: 61 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 23  ache->pGroup);.#
4240: 65 6e 64 69 66 0a 20 20 20 20 69 66 28 20 62 65  endif.    if( be
4250: 6e 69 67 6e 4d 61 6c 6c 6f 63 20 29 7b 20 73 71  nignMalloc ){ sq
4260: 6c 69 74 65 33 42 65 67 69 6e 42 65 6e 69 67 6e  lite3BeginBenign
4270: 4d 61 6c 6c 6f 63 28 29 3b 20 7d 0a 23 69 66 64  Malloc(); }.#ifd
4280: 65 66 20 53 51 4c 49 54 45 5f 50 43 41 43 48 45  ef SQLITE_PCACHE
4290: 5f 53 45 50 41 52 41 54 45 5f 48 45 41 44 45 52  _SEPARATE_HEADER
42a0: 0a 20 20 20 20 70 50 67 20 3d 20 70 63 61 63 68  .    pPg = pcach
42b0: 65 31 41 6c 6c 6f 63 28 70 43 61 63 68 65 2d 3e  e1Alloc(pCache->
42c0: 73 7a 50 61 67 65 29 3b 0a 20 20 20 20 70 20 3d  szPage);.    p =
42d0: 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 73   sqlite3Malloc(s
42e0: 69 7a 65 6f 66 28 50 67 48 64 72 31 29 20 2b 20  izeof(PgHdr1) + 
42f0: 70 43 61 63 68 65 2d 3e 73 7a 45 78 74 72 61 29  pCache->szExtra)
4300: 3b 0a 20 20 20 20 69 66 28 20 21 70 50 67 20 7c  ;.    if( !pPg |
4310: 7c 20 21 70 20 29 7b 0a 20 20 20 20 20 20 70 63  | !p ){.      pc
4320: 61 63 68 65 31 46 72 65 65 28 70 50 67 29 3b 0a  ache1Free(pPg);.
4330: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72        sqlite3_fr
4340: 65 65 28 70 29 3b 0a 20 20 20 20 20 20 70 50 67  ee(p);.      pPg
4350: 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 23 65 6c 73   = 0;.    }.#els
4360: 65 0a 20 20 20 20 70 50 67 20 3d 20 70 63 61 63  e.    pPg = pcac
4370: 68 65 31 41 6c 6c 6f 63 28 70 43 61 63 68 65 2d  he1Alloc(pCache-
4380: 3e 73 7a 41 6c 6c 6f 63 29 3b 0a 20 20 20 20 70  >szAlloc);.    p
4390: 20 3d 20 28 50 67 48 64 72 31 20 2a 29 26 28 28   = (PgHdr1 *)&((
43a0: 75 38 20 2a 29 70 50 67 29 5b 70 43 61 63 68 65  u8 *)pPg)[pCache
43b0: 2d 3e 73 7a 50 61 67 65 5d 3b 0a 23 65 6e 64 69  ->szPage];.#endi
43c0: 66 0a 20 20 20 20 69 66 28 20 62 65 6e 69 67 6e  f.    if( benign
43d0: 4d 61 6c 6c 6f 63 20 29 7b 20 73 71 6c 69 74 65  Malloc ){ sqlite
43e0: 33 45 6e 64 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63  3EndBenignMalloc
43f0: 28 29 3b 20 7d 0a 23 69 66 64 65 66 20 53 51 4c  (); }.#ifdef SQL
4400: 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52  ITE_ENABLE_MEMOR
4410: 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 0a 20 20 20  Y_MANAGEMENT.   
4420: 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74   pcache1EnterMut
4430: 65 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75  ex(pCache->pGrou
4440: 70 29 3b 0a 23 65 6e 64 69 66 0a 20 20 20 20 69  p);.#endif.    i
4450: 66 28 20 70 50 67 3d 3d 30 20 29 20 72 65 74 75  f( pPg==0 ) retu
4460: 72 6e 20 30 3b 0a 20 20 20 20 70 2d 3e 70 61 67  rn 0;.    p->pag
4470: 65 2e 70 42 75 66 20 3d 20 70 50 67 3b 0a 20 20  e.pBuf = pPg;.  
4480: 20 20 70 2d 3e 70 61 67 65 2e 70 45 78 74 72 61    p->page.pExtra
4490: 20 3d 20 26 70 5b 31 5d 3b 0a 20 20 20 20 70 2d   = &p[1];.    p-
44a0: 3e 69 73 42 75 6c 6b 4c 6f 63 61 6c 20 3d 20 30  >isBulkLocal = 0
44b0: 3b 0a 20 20 20 20 70 2d 3e 69 73 41 6e 63 68 6f  ;.    p->isAncho
44c0: 72 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 28 2a 70  r = 0;.  }.  (*p
44d0: 43 61 63 68 65 2d 3e 70 6e 50 75 72 67 65 61 62  Cache->pnPurgeab
44e0: 6c 65 29 2b 2b 3b 0a 20 20 72 65 74 75 72 6e 20  le)++;.  return 
44f0: 70 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65  p;.}../*.** Free
4500: 20 61 20 70 61 67 65 20 6f 62 6a 65 63 74 20 61   a page object a
4510: 6c 6c 6f 63 61 74 65 64 20 62 79 20 70 63 61 63  llocated by pcac
4520: 68 65 31 41 6c 6c 6f 63 50 61 67 65 28 29 2e 0a  he1AllocPage()..
4530: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70  */.static void p
4540: 63 61 63 68 65 31 46 72 65 65 50 61 67 65 28 50  cache1FreePage(P
4550: 67 48 64 72 31 20 2a 70 29 7b 0a 20 20 50 43 61  gHdr1 *p){.  PCa
4560: 63 68 65 31 20 2a 70 43 61 63 68 65 3b 0a 20 20  che1 *pCache;.  
4570: 61 73 73 65 72 74 28 20 70 21 3d 30 20 29 3b 0a  assert( p!=0 );.
4580: 20 20 70 43 61 63 68 65 20 3d 20 70 2d 3e 70 43    pCache = p->pC
4590: 61 63 68 65 3b 0a 20 20 61 73 73 65 72 74 28 20  ache;.  assert( 
45a0: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65  sqlite3_mutex_he
45b0: 6c 64 28 70 2d 3e 70 43 61 63 68 65 2d 3e 70 47  ld(p->pCache->pG
45c0: 72 6f 75 70 2d 3e 6d 75 74 65 78 29 20 29 3b 0a  roup->mutex) );.
45d0: 20 20 69 66 28 20 70 2d 3e 69 73 42 75 6c 6b 4c    if( p->isBulkL
45e0: 6f 63 61 6c 20 29 7b 0a 20 20 20 20 70 2d 3e 70  ocal ){.    p->p
45f0: 4e 65 78 74 20 3d 20 70 43 61 63 68 65 2d 3e 70  Next = pCache->p
4600: 46 72 65 65 3b 0a 20 20 20 20 70 43 61 63 68 65  Free;.    pCache
4610: 2d 3e 70 46 72 65 65 20 3d 20 70 3b 0a 20 20 7d  ->pFree = p;.  }
4620: 65 6c 73 65 7b 0a 20 20 20 20 70 63 61 63 68 65  else{.    pcache
4630: 31 46 72 65 65 28 70 2d 3e 70 61 67 65 2e 70 42  1Free(p->page.pB
4640: 75 66 29 3b 0a 23 69 66 64 65 66 20 53 51 4c 49  uf);.#ifdef SQLI
4650: 54 45 5f 50 43 41 43 48 45 5f 53 45 50 41 52 41  TE_PCACHE_SEPARA
4660: 54 45 5f 48 45 41 44 45 52 0a 20 20 20 20 73 71  TE_HEADER.    sq
4670: 6c 69 74 65 33 5f 66 72 65 65 28 70 29 3b 0a 23  lite3_free(p);.#
4680: 65 6e 64 69 66 0a 20 20 7d 0a 20 20 28 2a 70 43  endif.  }.  (*pC
4690: 61 63 68 65 2d 3e 70 6e 50 75 72 67 65 61 62 6c  ache->pnPurgeabl
46a0: 65 29 2d 2d 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d  e)--;.}../*.** M
46b0: 61 6c 6c 6f 63 20 66 75 6e 63 74 69 6f 6e 20 75  alloc function u
46c0: 73 65 64 20 62 79 20 53 51 4c 69 74 65 20 74 6f  sed by SQLite to
46d0: 20 6f 62 74 61 69 6e 20 73 70 61 63 65 20 66 72   obtain space fr
46e0: 6f 6d 20 74 68 65 20 62 75 66 66 65 72 20 63 6f  om the buffer co
46f0: 6e 66 69 67 75 72 65 64 0a 2a 2a 20 75 73 69 6e  nfigured.** usin
4700: 67 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67  g sqlite3_config
4710: 28 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50  (SQLITE_CONFIG_P
4720: 41 47 45 43 41 43 48 45 29 20 6f 70 74 69 6f 6e  AGECACHE) option
4730: 2e 20 49 66 20 6e 6f 20 73 75 63 68 20 62 75 66  . If no such buf
4740: 66 65 72 0a 2a 2a 20 65 78 69 73 74 73 2c 20 74  fer.** exists, t
4750: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 66 61 6c  his function fal
4760: 6c 73 20 62 61 63 6b 20 74 6f 20 73 71 6c 69 74  ls back to sqlit
4770: 65 33 4d 61 6c 6c 6f 63 28 29 2e 0a 2a 2f 0a 76  e3Malloc()..*/.v
4780: 6f 69 64 20 2a 73 71 6c 69 74 65 33 50 61 67 65  oid *sqlite3Page
4790: 4d 61 6c 6c 6f 63 28 69 6e 74 20 73 7a 29 7b 0a  Malloc(int sz){.
47a0: 20 20 72 65 74 75 72 6e 20 70 63 61 63 68 65 31    return pcache1
47b0: 41 6c 6c 6f 63 28 73 7a 29 3b 0a 7d 0a 0a 2f 2a  Alloc(sz);.}../*
47c0: 0a 2a 2a 20 46 72 65 65 20 61 6e 20 61 6c 6c 6f  .** Free an allo
47d0: 63 61 74 65 64 20 62 75 66 66 65 72 20 6f 62 74  cated buffer obt
47e0: 61 69 6e 65 64 20 66 72 6f 6d 20 73 71 6c 69 74  ained from sqlit
47f0: 65 33 50 61 67 65 4d 61 6c 6c 6f 63 28 29 2e 0a  e3PageMalloc()..
4800: 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50  */.void sqlite3P
4810: 61 67 65 46 72 65 65 28 76 6f 69 64 20 2a 70 29  ageFree(void *p)
4820: 7b 0a 20 20 70 63 61 63 68 65 31 46 72 65 65 28  {.  pcache1Free(
4830: 70 29 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 52 65  p);.}.../*.** Re
4840: 74 75 72 6e 20 74 72 75 65 20 69 66 20 69 74 20  turn true if it 
4850: 64 65 73 69 72 61 62 6c 65 20 74 6f 20 61 76 6f  desirable to avo
4860: 69 64 20 61 6c 6c 6f 63 61 74 69 6e 67 20 61 20  id allocating a 
4870: 6e 65 77 20 70 61 67 65 20 63 61 63 68 65 0a 2a  new page cache.*
4880: 2a 20 65 6e 74 72 79 2e 0a 2a 2a 0a 2a 2a 20 49  * entry..**.** I
4890: 66 20 6d 65 6d 6f 72 79 20 77 61 73 20 61 6c 6c  f memory was all
48a0: 6f 63 61 74 65 64 20 73 70 65 63 69 66 69 63 61  ocated specifica
48b0: 6c 6c 79 20 74 6f 20 74 68 65 20 70 61 67 65 20  lly to the page 
48c0: 63 61 63 68 65 20 75 73 69 6e 67 0a 2a 2a 20 53  cache using.** S
48d0: 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47  QLITE_CONFIG_PAG
48e0: 45 43 41 43 48 45 20 62 75 74 20 74 68 61 74 20  ECACHE but that 
48f0: 6d 65 6d 6f 72 79 20 68 61 73 20 61 6c 6c 20 62  memory has all b
4900: 65 65 6e 20 75 73 65 64 2c 20 74 68 65 6e 0a 2a  een used, then.*
4910: 2a 20 69 74 20 69 73 20 64 65 73 69 72 61 62 6c  * it is desirabl
4920: 65 20 74 6f 20 61 76 6f 69 64 20 61 6c 6c 6f 63  e to avoid alloc
4930: 61 74 69 6e 67 20 61 20 6e 65 77 20 70 61 67 65  ating a new page
4940: 20 63 61 63 68 65 20 65 6e 74 72 79 20 62 65 63   cache entry bec
4950: 61 75 73 65 0a 2a 2a 20 70 72 65 73 75 6d 61 62  ause.** presumab
4960: 6c 79 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47  ly SQLITE_CONFIG
4970: 5f 50 41 47 45 43 41 43 48 45 20 77 61 73 20 73  _PAGECACHE was s
4980: 75 70 70 6f 73 65 20 74 6f 20 62 65 20 73 75 66  uppose to be suf
4990: 66 69 63 69 65 6e 74 0a 2a 2a 20 66 6f 72 20 61  ficient.** for a
49a0: 6c 6c 20 70 61 67 65 20 63 61 63 68 65 20 6e 65  ll page cache ne
49b0: 65 64 73 20 61 6e 64 20 77 65 20 73 68 6f 75 6c  eds and we shoul
49c0: 64 20 6e 6f 74 20 6e 65 65 64 20 74 6f 20 73 70  d not need to sp
49d0: 69 6c 6c 20 74 68 65 0a 2a 2a 20 61 6c 6c 6f 63  ill the.** alloc
49e0: 61 74 69 6f 6e 20 6f 6e 74 6f 20 74 68 65 20 68  ation onto the h
49f0: 65 61 70 2e 0a 2a 2a 0a 2a 2a 20 4f 72 2c 20 74  eap..**.** Or, t
4a00: 68 65 20 68 65 61 70 20 69 73 20 75 73 65 64 20  he heap is used 
4a10: 66 6f 72 20 61 6c 6c 20 70 61 67 65 20 63 61 63  for all page cac
4a20: 68 65 20 6d 65 6d 6f 72 79 20 62 75 74 20 74 68  he memory but th
4a30: 65 20 68 65 61 70 20 69 73 0a 2a 2a 20 75 6e 64  e heap is.** und
4a40: 65 72 20 6d 65 6d 6f 72 79 20 70 72 65 73 73 75  er memory pressu
4a50: 72 65 2c 20 74 68 65 6e 20 61 67 61 69 6e 20 69  re, then again i
4a60: 74 20 69 73 20 64 65 73 69 72 61 62 6c 65 20 74  t is desirable t
4a70: 6f 20 61 76 6f 69 64 0a 2a 2a 20 61 6c 6c 6f 63  o avoid.** alloc
4a80: 61 74 69 6e 67 20 61 20 6e 65 77 20 70 61 67 65  ating a new page
4a90: 20 63 61 63 68 65 20 65 6e 74 72 79 20 69 6e 20   cache entry in 
4aa0: 6f 72 64 65 72 20 74 6f 20 61 76 6f 69 64 20 73  order to avoid s
4ab0: 74 72 65 73 73 69 6e 67 0a 2a 2a 20 74 68 65 20  tressing.** the 
4ac0: 68 65 61 70 20 65 76 65 6e 20 66 75 72 74 68 65  heap even furthe
4ad0: 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  r..*/.static int
4ae0: 20 70 63 61 63 68 65 31 55 6e 64 65 72 4d 65 6d   pcache1UnderMem
4af0: 6f 72 79 50 72 65 73 73 75 72 65 28 50 43 61 63  oryPressure(PCac
4b00: 68 65 31 20 2a 70 43 61 63 68 65 29 7b 0a 20 20  he1 *pCache){.  
4b10: 69 66 28 20 70 63 61 63 68 65 31 2e 6e 53 6c 6f  if( pcache1.nSlo
4b20: 74 20 26 26 20 28 70 43 61 63 68 65 2d 3e 73 7a  t && (pCache->sz
4b30: 50 61 67 65 2b 70 43 61 63 68 65 2d 3e 73 7a 45  Page+pCache->szE
4b40: 78 74 72 61 29 3c 3d 70 63 61 63 68 65 31 2e 73  xtra)<=pcache1.s
4b50: 7a 53 6c 6f 74 20 29 7b 0a 20 20 20 20 72 65 74  zSlot ){.    ret
4b60: 75 72 6e 20 70 63 61 63 68 65 31 2e 62 55 6e 64  urn pcache1.bUnd
4b70: 65 72 50 72 65 73 73 75 72 65 3b 0a 20 20 7d 65  erPressure;.  }e
4b80: 6c 73 65 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  lse{.    return 
4b90: 73 71 6c 69 74 65 33 48 65 61 70 4e 65 61 72 6c  sqlite3HeapNearl
4ba0: 79 46 75 6c 6c 28 29 3b 0a 20 20 7d 0a 7d 0a 0a  yFull();.  }.}..
4bb0: 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  /***************
4bc0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4bd0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
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 2f  ***************/
4c00: 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 20 47 65 6e 65 72  ./******** Gener
4c10: 61 6c 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  al Implementatio
4c20: 6e 20 46 75 6e 63 74 69 6f 6e 73 20 2a 2a 2a 2a  n Functions ****
4c30: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4c40: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4c50: 2f 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75  /../*.** This fu
4c60: 6e 63 74 69 6f 6e 20 69 73 20 75 73 65 64 20 74  nction is used t
4c70: 6f 20 72 65 73 69 7a 65 20 74 68 65 20 68 61 73  o resize the has
4c80: 68 20 74 61 62 6c 65 20 75 73 65 64 20 62 79 20  h table used by 
4c90: 74 68 65 20 63 61 63 68 65 20 70 61 73 73 65 64  the cache passed
4ca0: 0a 2a 2a 20 61 73 20 74 68 65 20 66 69 72 73 74  .** as the first
4cb0: 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a   argument..**.**
4cc0: 20 54 68 65 20 50 43 61 63 68 65 20 6d 75 74 65   The PCache mute
4cd0: 78 20 6d 75 73 74 20 62 65 20 68 65 6c 64 20 77  x must be held w
4ce0: 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f  hen this functio
4cf0: 6e 20 69 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f 0a  n is called..*/.
4d00: 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63  static void pcac
4d10: 68 65 31 52 65 73 69 7a 65 48 61 73 68 28 50 43  he1ResizeHash(PC
4d20: 61 63 68 65 31 20 2a 70 29 7b 0a 20 20 50 67 48  ache1 *p){.  PgH
4d30: 64 72 31 20 2a 2a 61 70 4e 65 77 3b 0a 20 20 75  dr1 **apNew;.  u
4d40: 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 4e 65 77  nsigned int nNew
4d50: 3b 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74  ;.  unsigned int
4d60: 20 69 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 73   i;..  assert( s
4d70: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c  qlite3_mutex_hel
4d80: 64 28 70 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75 74  d(p->pGroup->mut
4d90: 65 78 29 20 29 3b 0a 0a 20 20 6e 4e 65 77 20 3d  ex) );..  nNew =
4da0: 20 70 2d 3e 6e 48 61 73 68 2a 32 3b 0a 20 20 69   p->nHash*2;.  i
4db0: 66 28 20 6e 4e 65 77 3c 32 35 36 20 29 7b 0a 20  f( nNew<256 ){. 
4dc0: 20 20 20 6e 4e 65 77 20 3d 20 32 35 36 3b 0a 20     nNew = 256;. 
4dd0: 20 7d 0a 0a 20 20 70 63 61 63 68 65 31 4c 65 61   }..  pcache1Lea
4de0: 76 65 4d 75 74 65 78 28 70 2d 3e 70 47 72 6f 75  veMutex(p->pGrou
4df0: 70 29 3b 0a 20 20 69 66 28 20 70 2d 3e 6e 48 61  p);.  if( p->nHa
4e00: 73 68 20 29 7b 20 73 71 6c 69 74 65 33 42 65 67  sh ){ sqlite3Beg
4e10: 69 6e 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29  inBenignMalloc()
4e20: 3b 20 7d 0a 20 20 61 70 4e 65 77 20 3d 20 28 50  ; }.  apNew = (P
4e30: 67 48 64 72 31 20 2a 2a 29 73 71 6c 69 74 65 33  gHdr1 **)sqlite3
4e40: 4d 61 6c 6c 6f 63 5a 65 72 6f 28 73 69 7a 65 6f  MallocZero(sizeo
4e50: 66 28 50 67 48 64 72 31 20 2a 29 2a 6e 4e 65 77  f(PgHdr1 *)*nNew
4e60: 29 3b 0a 20 20 69 66 28 20 70 2d 3e 6e 48 61 73  );.  if( p->nHas
4e70: 68 20 29 7b 20 73 71 6c 69 74 65 33 45 6e 64 42  h ){ sqlite3EndB
4e80: 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 20 7d  enignMalloc(); }
4e90: 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d  .  pcache1EnterM
4ea0: 75 74 65 78 28 70 2d 3e 70 47 72 6f 75 70 29 3b  utex(p->pGroup);
4eb0: 0a 20 20 69 66 28 20 61 70 4e 65 77 20 29 7b 0a  .  if( apNew ){.
4ec0: 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70      for(i=0; i<p
4ed0: 2d 3e 6e 48 61 73 68 3b 20 69 2b 2b 29 7b 0a 20  ->nHash; i++){. 
4ee0: 20 20 20 20 20 50 67 48 64 72 31 20 2a 70 50 61       PgHdr1 *pPa
4ef0: 67 65 3b 0a 20 20 20 20 20 20 50 67 48 64 72 31  ge;.      PgHdr1
4f00: 20 2a 70 4e 65 78 74 20 3d 20 70 2d 3e 61 70 48   *pNext = p->apH
4f10: 61 73 68 5b 69 5d 3b 0a 20 20 20 20 20 20 77 68  ash[i];.      wh
4f20: 69 6c 65 28 20 28 70 50 61 67 65 20 3d 20 70 4e  ile( (pPage = pN
4f30: 65 78 74 29 21 3d 30 20 29 7b 0a 20 20 20 20 20  ext)!=0 ){.     
4f40: 20 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20     unsigned int 
4f50: 68 20 3d 20 70 50 61 67 65 2d 3e 69 4b 65 79 20  h = pPage->iKey 
4f60: 25 20 6e 4e 65 77 3b 0a 20 20 20 20 20 20 20 20  % nNew;.        
4f70: 70 4e 65 78 74 20 3d 20 70 50 61 67 65 2d 3e 70  pNext = pPage->p
4f80: 4e 65 78 74 3b 0a 20 20 20 20 20 20 20 20 70 50  Next;.        pP
4f90: 61 67 65 2d 3e 70 4e 65 78 74 20 3d 20 61 70 4e  age->pNext = apN
4fa0: 65 77 5b 68 5d 3b 0a 20 20 20 20 20 20 20 20 61  ew[h];.        a
4fb0: 70 4e 65 77 5b 68 5d 20 3d 20 70 50 61 67 65 3b  pNew[h] = pPage;
4fc0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
4fd0: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
4fe0: 70 2d 3e 61 70 48 61 73 68 29 3b 0a 20 20 20 20  p->apHash);.    
4ff0: 70 2d 3e 61 70 48 61 73 68 20 3d 20 61 70 4e 65  p->apHash = apNe
5000: 77 3b 0a 20 20 20 20 70 2d 3e 6e 48 61 73 68 20  w;.    p->nHash 
5010: 3d 20 6e 4e 65 77 3b 0a 20 20 7d 0a 7d 0a 0a 2f  = nNew;.  }.}../
5020: 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69  *.** This functi
5030: 6f 6e 20 69 73 20 75 73 65 64 20 69 6e 74 65 72  on is used inter
5040: 6e 61 6c 6c 79 20 74 6f 20 72 65 6d 6f 76 65 20  nally to remove 
5050: 74 68 65 20 70 61 67 65 20 70 50 61 67 65 20 66  the page pPage f
5060: 72 6f 6d 20 74 68 65 20 0a 2a 2a 20 50 47 72 6f  rom the .** PGro
5070: 75 70 20 4c 52 55 20 6c 69 73 74 2c 20 69 66 20  up LRU list, if 
5080: 69 73 20 70 61 72 74 20 6f 66 20 69 74 2e 20 49  is part of it. I
5090: 66 20 70 50 61 67 65 20 69 73 20 6e 6f 74 20 70  f pPage is not p
50a0: 61 72 74 20 6f 66 20 74 68 65 20 50 47 72 6f 75  art of the PGrou
50b0: 70 0a 2a 2a 20 4c 52 55 20 6c 69 73 74 2c 20 74  p.** LRU list, t
50c0: 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f  hen this functio
50d0: 6e 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a 2a 2a  n is a no-op..**
50e0: 0a 2a 2a 20 54 68 65 20 50 47 72 6f 75 70 20 6d  .** The PGroup m
50f0: 75 74 65 78 20 6d 75 73 74 20 62 65 20 68 65 6c  utex must be hel
5100: 64 20 77 68 65 6e 20 74 68 69 73 20 66 75 6e 63  d when this func
5110: 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 2e 0a  tion is called..
5120: 2a 2f 0a 73 74 61 74 69 63 20 50 67 48 64 72 31  */.static PgHdr1
5130: 20 2a 70 63 61 63 68 65 31 50 69 6e 50 61 67 65   *pcache1PinPage
5140: 28 50 67 48 64 72 31 20 2a 70 50 61 67 65 29 7b  (PgHdr1 *pPage){
5150: 0a 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65  .  assert( pPage
5160: 21 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28  !=0 );.  assert(
5170: 20 50 41 47 45 5f 49 53 5f 55 4e 50 49 4e 4e 45   PAGE_IS_UNPINNE
5180: 44 28 70 50 61 67 65 29 20 29 3b 0a 20 20 61 73  D(pPage) );.  as
5190: 73 65 72 74 28 20 70 50 61 67 65 2d 3e 70 4c 72  sert( pPage->pLr
51a0: 75 4e 65 78 74 20 29 3b 0a 20 20 61 73 73 65 72  uNext );.  asser
51b0: 74 28 20 70 50 61 67 65 2d 3e 70 4c 72 75 50 72  t( pPage->pLruPr
51c0: 65 76 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  ev );.  assert( 
51d0: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65  sqlite3_mutex_he
51e0: 6c 64 28 70 50 61 67 65 2d 3e 70 43 61 63 68 65  ld(pPage->pCache
51f0: 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78 29  ->pGroup->mutex)
5200: 20 29 3b 0a 20 20 70 50 61 67 65 2d 3e 70 4c 72   );.  pPage->pLr
5210: 75 50 72 65 76 2d 3e 70 4c 72 75 4e 65 78 74 20  uPrev->pLruNext 
5220: 3d 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78  = pPage->pLruNex
5230: 74 3b 0a 20 20 70 50 61 67 65 2d 3e 70 4c 72 75  t;.  pPage->pLru
5240: 4e 65 78 74 2d 3e 70 4c 72 75 50 72 65 76 20 3d  Next->pLruPrev =
5250: 20 70 50 61 67 65 2d 3e 70 4c 72 75 50 72 65 76   pPage->pLruPrev
5260: 3b 0a 20 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e  ;.  pPage->pLruN
5270: 65 78 74 20 3d 20 30 3b 0a 20 20 70 50 61 67 65  ext = 0;.  pPage
5280: 2d 3e 70 4c 72 75 50 72 65 76 20 3d 20 30 3b 0a  ->pLruPrev = 0;.
5290: 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65 2d    assert( pPage-
52a0: 3e 69 73 41 6e 63 68 6f 72 3d 3d 30 20 29 3b 0a  >isAnchor==0 );.
52b0: 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65 2d    assert( pPage-
52c0: 3e 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 2d  >pCache->pGroup-
52d0: 3e 6c 72 75 2e 69 73 41 6e 63 68 6f 72 3d 3d 31  >lru.isAnchor==1
52e0: 20 29 3b 0a 20 20 70 50 61 67 65 2d 3e 70 43 61   );.  pPage->pCa
52f0: 63 68 65 2d 3e 6e 52 65 63 79 63 6c 61 62 6c 65  che->nRecyclable
5300: 2d 2d 3b 0a 20 20 72 65 74 75 72 6e 20 70 50 61  --;.  return pPa
5310: 67 65 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 52 65  ge;.}.../*.** Re
5320: 6d 6f 76 65 20 74 68 65 20 70 61 67 65 20 73 75  move the page su
5330: 70 70 6c 69 65 64 20 61 73 20 61 6e 20 61 72 67  pplied as an arg
5340: 75 6d 65 6e 74 20 66 72 6f 6d 20 74 68 65 20 68  ument from the h
5350: 61 73 68 20 74 61 62 6c 65 20 0a 2a 2a 20 28 50  ash table .** (P
5360: 43 61 63 68 65 31 2e 61 70 48 61 73 68 20 73 74  Cache1.apHash st
5370: 72 75 63 74 75 72 65 29 20 74 68 61 74 20 69 74  ructure) that it
5380: 20 69 73 20 63 75 72 72 65 6e 74 6c 79 20 73 74   is currently st
5390: 6f 72 65 64 20 69 6e 2e 0a 2a 2a 20 41 6c 73 6f  ored in..** Also
53a0: 20 66 72 65 65 20 74 68 65 20 70 61 67 65 20 69   free the page i
53b0: 66 20 66 72 65 65 50 61 67 65 20 69 73 20 74 72  f freePage is tr
53c0: 75 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 50 47  ue..**.** The PG
53d0: 72 6f 75 70 20 6d 75 74 65 78 20 6d 75 73 74 20  roup mutex must 
53e0: 62 65 20 68 65 6c 64 20 77 68 65 6e 20 74 68 69  be held when thi
53f0: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61  s function is ca
5400: 6c 6c 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  lled..*/.static 
5410: 76 6f 69 64 20 70 63 61 63 68 65 31 52 65 6d 6f  void pcache1Remo
5420: 76 65 46 72 6f 6d 48 61 73 68 28 50 67 48 64 72  veFromHash(PgHdr
5430: 31 20 2a 70 50 61 67 65 2c 20 69 6e 74 20 66 72  1 *pPage, int fr
5440: 65 65 46 6c 61 67 29 7b 0a 20 20 75 6e 73 69 67  eeFlag){.  unsig
5450: 6e 65 64 20 69 6e 74 20 68 3b 0a 20 20 50 43 61  ned int h;.  PCa
5460: 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20 70  che1 *pCache = p
5470: 50 61 67 65 2d 3e 70 43 61 63 68 65 3b 0a 20 20  Page->pCache;.  
5480: 50 67 48 64 72 31 20 2a 2a 70 70 3b 0a 0a 20 20  PgHdr1 **pp;..  
5490: 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f  assert( sqlite3_
54a0: 6d 75 74 65 78 5f 68 65 6c 64 28 70 43 61 63 68  mutex_held(pCach
54b0: 65 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78  e->pGroup->mutex
54c0: 29 20 29 3b 0a 20 20 68 20 3d 20 70 50 61 67 65  ) );.  h = pPage
54d0: 2d 3e 69 4b 65 79 20 25 20 70 43 61 63 68 65 2d  ->iKey % pCache-
54e0: 3e 6e 48 61 73 68 3b 0a 20 20 66 6f 72 28 70 70  >nHash;.  for(pp
54f0: 3d 26 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68  =&pCache->apHash
5500: 5b 68 5d 3b 20 28 2a 70 70 29 21 3d 70 50 61 67  [h]; (*pp)!=pPag
5510: 65 3b 20 70 70 3d 26 28 2a 70 70 29 2d 3e 70 4e  e; pp=&(*pp)->pN
5520: 65 78 74 29 3b 0a 20 20 2a 70 70 20 3d 20 28 2a  ext);.  *pp = (*
5530: 70 70 29 2d 3e 70 4e 65 78 74 3b 0a 0a 20 20 70  pp)->pNext;..  p
5540: 43 61 63 68 65 2d 3e 6e 50 61 67 65 2d 2d 3b 0a  Cache->nPage--;.
5550: 20 20 69 66 28 20 66 72 65 65 46 6c 61 67 20 29    if( freeFlag )
5560: 20 70 63 61 63 68 65 31 46 72 65 65 50 61 67 65   pcache1FreePage
5570: 28 70 50 61 67 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  (pPage);.}../*.*
5580: 2a 20 49 66 20 74 68 65 72 65 20 61 72 65 20 63  * If there are c
5590: 75 72 72 65 6e 74 6c 79 20 6d 6f 72 65 20 74 68  urrently more th
55a0: 61 6e 20 6e 4d 61 78 50 61 67 65 20 70 61 67 65  an nMaxPage page
55b0: 73 20 61 6c 6c 6f 63 61 74 65 64 2c 20 74 72 79  s allocated, try
55c0: 0a 2a 2a 20 74 6f 20 72 65 63 79 63 6c 65 20 70  .** to recycle p
55d0: 61 67 65 73 20 74 6f 20 72 65 64 75 63 65 20 74  ages to reduce t
55e0: 68 65 20 6e 75 6d 62 65 72 20 61 6c 6c 6f 63 61  he number alloca
55f0: 74 65 64 20 74 6f 20 6e 4d 61 78 50 61 67 65 2e  ted to nMaxPage.
5600: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
5610: 70 63 61 63 68 65 31 45 6e 66 6f 72 63 65 4d 61  pcache1EnforceMa
5620: 78 50 61 67 65 28 50 43 61 63 68 65 31 20 2a 70  xPage(PCache1 *p
5630: 43 61 63 68 65 29 7b 0a 20 20 50 47 72 6f 75 70  Cache){.  PGroup
5640: 20 2a 70 47 72 6f 75 70 20 3d 20 70 43 61 63 68   *pGroup = pCach
5650: 65 2d 3e 70 47 72 6f 75 70 3b 0a 20 20 50 67 48  e->pGroup;.  PgH
5660: 64 72 31 20 2a 70 3b 0a 20 20 61 73 73 65 72 74  dr1 *p;.  assert
5670: 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f  ( sqlite3_mutex_
5680: 68 65 6c 64 28 70 47 72 6f 75 70 2d 3e 6d 75 74  held(pGroup->mut
5690: 65 78 29 20 29 3b 0a 20 20 77 68 69 6c 65 28 20  ex) );.  while( 
56a0: 70 47 72 6f 75 70 2d 3e 6e 50 75 72 67 65 61 62  pGroup->nPurgeab
56b0: 6c 65 3e 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50  le>pGroup->nMaxP
56c0: 61 67 65 0a 20 20 20 20 20 20 26 26 20 28 70 3d  age.      && (p=
56d0: 70 47 72 6f 75 70 2d 3e 6c 72 75 2e 70 4c 72 75  pGroup->lru.pLru
56e0: 50 72 65 76 29 2d 3e 69 73 41 6e 63 68 6f 72 3d  Prev)->isAnchor=
56f0: 3d 30 0a 20 20 29 7b 0a 20 20 20 20 61 73 73 65  =0.  ){.    asse
5700: 72 74 28 20 70 2d 3e 70 43 61 63 68 65 2d 3e 70  rt( p->pCache->p
5710: 47 72 6f 75 70 3d 3d 70 47 72 6f 75 70 20 29 3b  Group==pGroup );
5720: 0a 20 20 20 20 61 73 73 65 72 74 28 20 50 41 47  .    assert( PAG
5730: 45 5f 49 53 5f 55 4e 50 49 4e 4e 45 44 28 70 29  E_IS_UNPINNED(p)
5740: 20 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31 50   );.    pcache1P
5750: 69 6e 50 61 67 65 28 70 29 3b 0a 20 20 20 20 70  inPage(p);.    p
5760: 63 61 63 68 65 31 52 65 6d 6f 76 65 46 72 6f 6d  cache1RemoveFrom
5770: 48 61 73 68 28 70 2c 20 31 29 3b 0a 20 20 7d 0a  Hash(p, 1);.  }.
5780: 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 6e 50    if( pCache->nP
5790: 61 67 65 3d 3d 30 20 26 26 20 70 43 61 63 68 65  age==0 && pCache
57a0: 2d 3e 70 42 75 6c 6b 20 29 7b 0a 20 20 20 20 73  ->pBulk ){.    s
57b0: 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43 61 63  qlite3_free(pCac
57c0: 68 65 2d 3e 70 42 75 6c 6b 29 3b 0a 20 20 20 20  he->pBulk);.    
57d0: 70 43 61 63 68 65 2d 3e 70 42 75 6c 6b 20 3d 20  pCache->pBulk = 
57e0: 70 43 61 63 68 65 2d 3e 70 46 72 65 65 20 3d 20  pCache->pFree = 
57f0: 30 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  0;.  }.}../*.** 
5800: 44 69 73 63 61 72 64 20 61 6c 6c 20 70 61 67 65  Discard all page
5810: 73 20 66 72 6f 6d 20 63 61 63 68 65 20 70 43 61  s from cache pCa
5820: 63 68 65 20 77 69 74 68 20 61 20 70 61 67 65 20  che with a page 
5830: 6e 75 6d 62 65 72 20 28 6b 65 79 20 76 61 6c 75  number (key valu
5840: 65 29 20 0a 2a 2a 20 67 72 65 61 74 65 72 20 74  e) .** greater t
5850: 68 61 6e 20 6f 72 20 65 71 75 61 6c 20 74 6f 20  han or equal to 
5860: 69 4c 69 6d 69 74 2e 20 41 6e 79 20 70 69 6e 6e  iLimit. Any pinn
5870: 65 64 20 70 61 67 65 73 20 74 68 61 74 20 6d 65  ed pages that me
5880: 65 74 20 74 68 69 73 20 0a 2a 2a 20 63 72 69 74  et this .** crit
5890: 65 72 69 61 20 61 72 65 20 75 6e 70 69 6e 6e 65  eria are unpinne
58a0: 64 20 62 65 66 6f 72 65 20 74 68 65 79 20 61 72  d before they ar
58b0: 65 20 64 69 73 63 61 72 64 65 64 2e 0a 2a 2a 0a  e discarded..**.
58c0: 2a 2a 20 54 68 65 20 50 43 61 63 68 65 20 6d 75  ** The PCache mu
58d0: 74 65 78 20 6d 75 73 74 20 62 65 20 68 65 6c 64  tex must be held
58e0: 20 77 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74   when this funct
58f0: 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 2e 0a 2a  ion is called..*
5900: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63  /.static void pc
5910: 61 63 68 65 31 54 72 75 6e 63 61 74 65 55 6e 73  ache1TruncateUns
5920: 61 66 65 28 0a 20 20 50 43 61 63 68 65 31 20 2a  afe(.  PCache1 *
5930: 70 43 61 63 68 65 2c 20 20 20 20 20 20 20 20 20  pCache,         
5940: 20 20 20 20 2f 2a 20 54 68 65 20 63 61 63 68 65      /* The cache
5950: 20 74 6f 20 74 72 75 6e 63 61 74 65 20 2a 2f 0a   to truncate */.
5960: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69    unsigned int i
5970: 4c 69 6d 69 74 20 20 20 20 20 20 20 20 20 20 2f  Limit          /
5980: 2a 20 44 72 6f 70 20 70 61 67 65 73 20 77 69 74  * Drop pages wit
5990: 68 20 74 68 69 73 20 70 67 6e 6f 20 6f 72 20 6c  h this pgno or l
59a0: 61 72 67 65 72 20 2a 2f 0a 29 7b 0a 20 20 54 45  arger */.){.  TE
59b0: 53 54 4f 4e 4c 59 28 20 69 6e 74 20 6e 50 61 67  STONLY( int nPag
59c0: 65 20 3d 20 30 3b 20 29 20 20 2f 2a 20 54 6f 20  e = 0; )  /* To 
59d0: 61 73 73 65 72 74 20 70 43 61 63 68 65 2d 3e 6e  assert pCache->n
59e0: 50 61 67 65 20 69 73 20 63 6f 72 72 65 63 74 20  Page is correct 
59f0: 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e  */.  unsigned in
5a00: 74 20 68 2c 20 69 53 74 6f 70 3b 0a 20 20 61 73  t h, iStop;.  as
5a10: 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75  sert( sqlite3_mu
5a20: 74 65 78 5f 68 65 6c 64 28 70 43 61 63 68 65 2d  tex_held(pCache-
5a30: 3e 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78 29 20  >pGroup->mutex) 
5a40: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 43 61  );.  assert( pCa
5a50: 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 3e 3d 20  che->iMaxKey >= 
5a60: 69 4c 69 6d 69 74 20 29 3b 0a 20 20 61 73 73 65  iLimit );.  asse
5a70: 72 74 28 20 70 43 61 63 68 65 2d 3e 6e 48 61 73  rt( pCache->nHas
5a80: 68 20 3e 20 30 20 29 3b 0a 20 20 69 66 28 20 70  h > 0 );.  if( p
5a90: 43 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 2d  Cache->iMaxKey -
5aa0: 20 69 4c 69 6d 69 74 20 3c 20 70 43 61 63 68 65   iLimit < pCache
5ab0: 2d 3e 6e 48 61 73 68 20 29 7b 0a 20 20 20 20 2f  ->nHash ){.    /
5ac0: 2a 20 49 66 20 77 65 20 61 72 65 20 6a 75 73 74  * If we are just
5ad0: 20 73 68 61 76 69 6e 67 20 74 68 65 20 6c 61 73   shaving the las
5ae0: 74 20 66 65 77 20 70 61 67 65 73 20 6f 66 66 20  t few pages off 
5af0: 74 68 65 20 65 6e 64 20 6f 66 20 74 68 65 0a 20  the end of the. 
5b00: 20 20 20 2a 2a 20 63 61 63 68 65 2c 20 74 68 65     ** cache, the
5b10: 6e 20 74 68 65 72 65 20 69 73 20 6e 6f 20 70 6f  n there is no po
5b20: 69 6e 74 20 69 6e 20 73 63 61 6e 6e 69 6e 67 20  int in scanning 
5b30: 74 68 65 20 65 6e 74 69 72 65 20 68 61 73 68 20  the entire hash 
5b40: 74 61 62 6c 65 2e 0a 20 20 20 20 2a 2a 20 4f 6e  table..    ** On
5b50: 6c 79 20 73 63 61 6e 20 74 68 6f 73 65 20 68 61  ly scan those ha
5b60: 73 68 20 73 6c 6f 74 73 20 74 68 61 74 20 6d 69  sh slots that mi
5b70: 67 68 74 20 63 6f 6e 74 61 69 6e 20 70 61 67 65  ght contain page
5b80: 73 20 74 68 61 74 20 6e 65 65 64 20 74 6f 0a 20  s that need to. 
5b90: 20 20 20 2a 2a 20 62 65 20 72 65 6d 6f 76 65 64     ** be removed
5ba0: 2e 20 2a 2f 0a 20 20 20 20 68 20 3d 20 69 4c 69  . */.    h = iLi
5bb0: 6d 69 74 20 25 20 70 43 61 63 68 65 2d 3e 6e 48  mit % pCache->nH
5bc0: 61 73 68 3b 0a 20 20 20 20 69 53 74 6f 70 20 3d  ash;.    iStop =
5bd0: 20 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79   pCache->iMaxKey
5be0: 20 25 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68   % pCache->nHash
5bf0: 3b 0a 20 20 20 20 54 45 53 54 4f 4e 4c 59 28 20  ;.    TESTONLY( 
5c00: 6e 50 61 67 65 20 3d 20 2d 31 30 3b 20 29 20 20  nPage = -10; )  
5c10: 2f 2a 20 44 69 73 61 62 6c 65 20 74 68 65 20 70  /* Disable the p
5c20: 43 61 63 68 65 2d 3e 6e 50 61 67 65 20 76 61 6c  Cache->nPage val
5c30: 69 64 69 74 79 20 63 68 65 63 6b 20 2a 2f 0a 20  idity check */. 
5c40: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 2f 2a 20 54   }else{.    /* T
5c50: 68 69 73 20 69 73 20 74 68 65 20 67 65 6e 65 72  his is the gener
5c60: 61 6c 20 63 61 73 65 20 77 68 65 72 65 20 6d 61  al case where ma
5c70: 6e 79 20 70 61 67 65 73 20 61 72 65 20 62 65 69  ny pages are bei
5c80: 6e 67 20 72 65 6d 6f 76 65 64 2e 0a 20 20 20 20  ng removed..    
5c90: 2a 2a 20 49 74 20 69 73 20 6e 65 63 65 73 73 61  ** It is necessa
5ca0: 72 79 20 74 6f 20 73 63 61 6e 20 74 68 65 20 65  ry to scan the e
5cb0: 6e 74 69 72 65 20 68 61 73 68 20 74 61 62 6c 65  ntire hash table
5cc0: 20 2a 2f 0a 20 20 20 20 68 20 3d 20 70 43 61 63   */.    h = pCac
5cd0: 68 65 2d 3e 6e 48 61 73 68 2f 32 3b 0a 20 20 20  he->nHash/2;.   
5ce0: 20 69 53 74 6f 70 20 3d 20 68 20 2d 20 31 3b 0a   iStop = h - 1;.
5cf0: 20 20 7d 0a 20 20 66 6f 72 28 3b 3b 29 7b 0a 20    }.  for(;;){. 
5d00: 20 20 20 50 67 48 64 72 31 20 2a 2a 70 70 3b 0a     PgHdr1 **pp;.
5d10: 20 20 20 20 50 67 48 64 72 31 20 2a 70 50 61 67      PgHdr1 *pPag
5d20: 65 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 68  e;.    assert( h
5d30: 3c 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 20 29  <pCache->nHash )
5d40: 3b 0a 20 20 20 20 70 70 20 3d 20 26 70 43 61 63  ;.    pp = &pCac
5d50: 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 20 0a  he->apHash[h]; .
5d60: 20 20 20 20 77 68 69 6c 65 28 20 28 70 50 61 67      while( (pPag
5d70: 65 20 3d 20 2a 70 70 29 21 3d 30 20 29 7b 0a 20  e = *pp)!=0 ){. 
5d80: 20 20 20 20 20 69 66 28 20 70 50 61 67 65 2d 3e       if( pPage->
5d90: 69 4b 65 79 3e 3d 69 4c 69 6d 69 74 20 29 7b 0a  iKey>=iLimit ){.
5da0: 20 20 20 20 20 20 20 20 70 43 61 63 68 65 2d 3e          pCache->
5db0: 6e 50 61 67 65 2d 2d 3b 0a 20 20 20 20 20 20 20  nPage--;.       
5dc0: 20 2a 70 70 20 3d 20 70 50 61 67 65 2d 3e 70 4e   *pp = pPage->pN
5dd0: 65 78 74 3b 0a 20 20 20 20 20 20 20 20 69 66 28  ext;.        if(
5de0: 20 50 41 47 45 5f 49 53 5f 55 4e 50 49 4e 4e 45   PAGE_IS_UNPINNE
5df0: 44 28 70 50 61 67 65 29 20 29 20 70 63 61 63 68  D(pPage) ) pcach
5e00: 65 31 50 69 6e 50 61 67 65 28 70 50 61 67 65 29  e1PinPage(pPage)
5e10: 3b 0a 20 20 20 20 20 20 20 20 70 63 61 63 68 65  ;.        pcache
5e20: 31 46 72 65 65 50 61 67 65 28 70 50 61 67 65 29  1FreePage(pPage)
5e30: 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20  ;.      }else{. 
5e40: 20 20 20 20 20 20 20 70 70 20 3d 20 26 70 50 61         pp = &pPa
5e50: 67 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20  ge->pNext;.     
5e60: 20 20 20 54 45 53 54 4f 4e 4c 59 28 20 69 66 28     TESTONLY( if(
5e70: 20 6e 50 61 67 65 3e 3d 30 20 29 20 6e 50 61 67   nPage>=0 ) nPag
5e80: 65 2b 2b 3b 20 29 0a 20 20 20 20 20 20 7d 0a 20  e++; ).      }. 
5e90: 20 20 20 7d 0a 20 20 20 20 69 66 28 20 68 3d 3d     }.    if( h==
5ea0: 69 53 74 6f 70 20 29 20 62 72 65 61 6b 3b 0a 20  iStop ) break;. 
5eb0: 20 20 20 68 20 3d 20 28 68 2b 31 29 20 25 20 70     h = (h+1) % p
5ec0: 43 61 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20  Cache->nHash;.  
5ed0: 7d 0a 20 20 61 73 73 65 72 74 28 20 6e 50 61 67  }.  assert( nPag
5ee0: 65 3c 30 20 7c 7c 20 70 43 61 63 68 65 2d 3e 6e  e<0 || pCache->n
5ef0: 50 61 67 65 3d 3d 28 75 6e 73 69 67 6e 65 64 29  Page==(unsigned)
5f00: 6e 50 61 67 65 20 29 3b 0a 7d 0a 0a 2f 2a 2a 2a  nPage );.}../***
5f10: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5f20: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5f30: 2a 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 2f 0a 2f 2a 2a  ***********/./**
5f60: 2a 2a 2a 2a 2a 2a 20 73 71 6c 69 74 65 33 5f 70  ****** sqlite3_p
5f70: 63 61 63 68 65 20 4d 65 74 68 6f 64 73 20 2a 2a  cache Methods **
5f80: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5f90: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5fa0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f  ************/../
5fb0: 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74  *.** Implementat
5fc0: 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74  ion of the sqlit
5fd0: 65 33 5f 70 63 61 63 68 65 2e 78 49 6e 69 74 20  e3_pcache.xInit 
5fe0: 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69  method..*/.stati
5ff0: 63 20 69 6e 74 20 70 63 61 63 68 65 31 49 6e 69  c int pcache1Ini
6000: 74 28 76 6f 69 64 20 2a 4e 6f 74 55 73 65 64 29  t(void *NotUsed)
6010: 7b 0a 20 20 55 4e 55 53 45 44 5f 50 41 52 41 4d  {.  UNUSED_PARAM
6020: 45 54 45 52 28 4e 6f 74 55 73 65 64 29 3b 0a 20  ETER(NotUsed);. 
6030: 20 61 73 73 65 72 74 28 20 70 63 61 63 68 65 31   assert( pcache1
6040: 2e 69 73 49 6e 69 74 3d 3d 30 20 29 3b 0a 20 20  .isInit==0 );.  
6050: 6d 65 6d 73 65 74 28 26 70 63 61 63 68 65 31 2c  memset(&pcache1,
6060: 20 30 2c 20 73 69 7a 65 6f 66 28 70 63 61 63 68   0, sizeof(pcach
6070: 65 31 29 29 3b 0a 0a 0a 20 20 2f 2a 0a 20 20 2a  e1));...  /*.  *
6080: 2a 20 54 68 65 20 70 63 61 63 68 65 31 2e 73 65  * The pcache1.se
6090: 70 61 72 61 74 65 43 61 63 68 65 20 76 61 72 69  parateCache vari
60a0: 61 62 6c 65 20 69 73 20 74 72 75 65 20 69 66 20  able is true if 
60b0: 65 61 63 68 20 50 43 61 63 68 65 20 68 61 73 20  each PCache has 
60c0: 69 74 73 20 6f 77 6e 0a 20 20 2a 2a 20 70 72 69  its own.  ** pri
60d0: 76 61 74 65 20 50 47 72 6f 75 70 20 28 6d 6f 64  vate PGroup (mod
60e0: 65 2d 31 29 2e 20 20 70 63 61 63 68 65 31 2e 73  e-1).  pcache1.s
60f0: 65 70 61 72 61 74 65 43 61 63 68 65 20 69 73 20  eparateCache is 
6100: 66 61 6c 73 65 20 69 66 20 74 68 65 20 73 69 6e  false if the sin
6110: 67 6c 65 0a 20 20 2a 2a 20 50 47 72 6f 75 70 20  gle.  ** PGroup 
6120: 69 6e 20 70 63 61 63 68 65 31 2e 67 72 70 20 69  in pcache1.grp i
6130: 73 20 75 73 65 64 20 66 6f 72 20 61 6c 6c 20 70  s used for all p
6140: 61 67 65 20 63 61 63 68 65 73 20 28 6d 6f 64 65  age caches (mode
6150: 2d 32 29 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20  -2)..  **.  **  
6160: 20 2a 20 20 41 6c 77 61 79 73 20 75 73 65 20 61   *  Always use a
6170: 20 75 6e 69 66 69 65 64 20 63 61 63 68 65 20 28   unified cache (
6180: 6d 6f 64 65 2d 32 29 20 69 66 20 45 4e 41 42 4c  mode-2) if ENABL
6190: 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d  E_MEMORY_MANAGEM
61a0: 45 4e 54 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20  ENT.  **.  **   
61b0: 2a 20 20 55 73 65 20 61 20 75 6e 69 66 69 65 64  *  Use a unified
61c0: 20 63 61 63 68 65 20 69 6e 20 73 69 6e 67 6c 65   cache in single
61d0: 2d 74 68 72 65 61 64 65 64 20 61 70 70 6c 69 63  -threaded applic
61e0: 61 74 69 6f 6e 73 20 74 68 61 74 20 68 61 76 65  ations that have
61f0: 0a 20 20 2a 2a 20 20 20 20 20 20 63 6f 6e 66 69  .  **      confi
6200: 67 75 72 65 64 20 61 20 73 74 61 72 74 2d 74 69  gured a start-ti
6210: 6d 65 20 62 75 66 66 65 72 20 66 6f 72 20 75 73  me buffer for us
6220: 65 20 61 73 20 70 61 67 65 2d 63 61 63 68 65 20  e as page-cache 
6230: 6d 65 6d 6f 72 79 20 75 73 69 6e 67 0a 20 20 2a  memory using.  *
6240: 2a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 63  *      sqlite3_c
6250: 6f 6e 66 69 67 28 53 51 4c 49 54 45 5f 43 4f 4e  onfig(SQLITE_CON
6260: 46 49 47 5f 50 41 47 45 43 41 43 48 45 2c 20 70  FIG_PAGECACHE, p
6270: 42 75 66 2c 20 73 7a 2c 20 4e 29 20 77 69 74 68  Buf, sz, N) with
6280: 20 6e 6f 6e 2d 4e 55 4c 4c 20 0a 20 20 2a 2a 20   non-NULL .  ** 
6290: 20 20 20 20 20 70 42 75 66 20 61 72 67 75 6d 65       pBuf argume
62a0: 6e 74 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20  nt..  **.  **   
62b0: 2a 20 20 4f 74 68 65 72 77 69 73 65 20 75 73 65  *  Otherwise use
62c0: 20 73 65 70 61 72 61 74 65 20 63 61 63 68 65 73   separate caches
62d0: 20 28 6d 6f 64 65 2d 31 29 0a 20 20 2a 2f 0a 23   (mode-1).  */.#
62e0: 69 66 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54  if defined(SQLIT
62f0: 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f  E_ENABLE_MEMORY_
6300: 4d 41 4e 41 47 45 4d 45 4e 54 29 0a 20 20 70 63  MANAGEMENT).  pc
6310: 61 63 68 65 31 2e 73 65 70 61 72 61 74 65 43 61  ache1.separateCa
6320: 63 68 65 20 3d 20 30 3b 0a 23 65 6c 69 66 20 53  che = 0;.#elif S
6330: 51 4c 49 54 45 5f 54 48 52 45 41 44 53 41 46 45  QLITE_THREADSAFE
6340: 0a 20 20 70 63 61 63 68 65 31 2e 73 65 70 61 72  .  pcache1.separ
6350: 61 74 65 43 61 63 68 65 20 3d 20 73 71 6c 69 74  ateCache = sqlit
6360: 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70  e3GlobalConfig.p
6370: 50 61 67 65 3d 3d 30 0a 20 20 20 20 20 20 20 20  Page==0.        
6380: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6390: 20 20 7c 7c 20 73 71 6c 69 74 65 33 47 6c 6f 62    || sqlite3Glob
63a0: 61 6c 43 6f 6e 66 69 67 2e 62 43 6f 72 65 4d 75  alConfig.bCoreMu
63b0: 74 65 78 3e 30 3b 0a 23 65 6c 73 65 0a 20 20 70  tex>0;.#else.  p
63c0: 63 61 63 68 65 31 2e 73 65 70 61 72 61 74 65 43  cache1.separateC
63d0: 61 63 68 65 20 3d 20 73 71 6c 69 74 65 33 47 6c  ache = sqlite3Gl
63e0: 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 50 61 67 65  obalConfig.pPage
63f0: 3d 3d 30 3b 0a 23 65 6e 64 69 66 0a 0a 23 69 66  ==0;.#endif..#if
6400: 20 53 51 4c 49 54 45 5f 54 48 52 45 41 44 53 41   SQLITE_THREADSA
6410: 46 45 0a 20 20 69 66 28 20 73 71 6c 69 74 65 33  FE.  if( sqlite3
6420: 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 62 43 6f  GlobalConfig.bCo
6430: 72 65 4d 75 74 65 78 20 29 7b 0a 20 20 20 20 70  reMutex ){.    p
6440: 63 61 63 68 65 31 2e 67 72 70 2e 6d 75 74 65 78  cache1.grp.mutex
6450: 20 3d 20 73 71 6c 69 74 65 33 4d 75 74 65 78 41   = sqlite3MutexA
6460: 6c 6c 6f 63 28 53 51 4c 49 54 45 5f 4d 55 54 45  lloc(SQLITE_MUTE
6470: 58 5f 53 54 41 54 49 43 5f 4c 52 55 29 3b 0a 20  X_STATIC_LRU);. 
6480: 20 20 20 70 63 61 63 68 65 31 2e 6d 75 74 65 78     pcache1.mutex
6490: 20 3d 20 73 71 6c 69 74 65 33 4d 75 74 65 78 41   = sqlite3MutexA
64a0: 6c 6c 6f 63 28 53 51 4c 49 54 45 5f 4d 55 54 45  lloc(SQLITE_MUTE
64b0: 58 5f 53 54 41 54 49 43 5f 50 4d 45 4d 29 3b 0a  X_STATIC_PMEM);.
64c0: 20 20 7d 0a 23 65 6e 64 69 66 0a 20 20 69 66 28    }.#endif.  if(
64d0: 20 70 63 61 63 68 65 31 2e 73 65 70 61 72 61 74   pcache1.separat
64e0: 65 43 61 63 68 65 0a 20 20 20 26 26 20 73 71 6c  eCache.   && sql
64f0: 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67  ite3GlobalConfig
6500: 2e 6e 50 61 67 65 21 3d 30 0a 20 20 20 26 26 20  .nPage!=0.   && 
6510: 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e  sqlite3GlobalCon
6520: 66 69 67 2e 70 50 61 67 65 3d 3d 30 0a 20 20 29  fig.pPage==0.  )
6530: 7b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 6e 49  {.    pcache1.nI
6540: 6e 69 74 50 61 67 65 20 3d 20 73 71 6c 69 74 65  nitPage = sqlite
6550: 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 6e 50  3GlobalConfig.nP
6560: 61 67 65 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  age;.  }else{.  
6570: 20 20 70 63 61 63 68 65 31 2e 6e 49 6e 69 74 50    pcache1.nInitP
6580: 61 67 65 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 70  age = 0;.  }.  p
6590: 63 61 63 68 65 31 2e 67 72 70 2e 6d 78 50 69 6e  cache1.grp.mxPin
65a0: 6e 65 64 20 3d 20 31 30 3b 0a 20 20 70 63 61 63  ned = 10;.  pcac
65b0: 68 65 31 2e 69 73 49 6e 69 74 20 3d 20 31 3b 0a  he1.isInit = 1;.
65c0: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
65d0: 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70  OK;.}../*.** Imp
65e0: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74  lementation of t
65f0: 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68  he sqlite3_pcach
6600: 65 2e 78 53 68 75 74 64 6f 77 6e 20 6d 65 74 68  e.xShutdown meth
6610: 6f 64 2e 0a 2a 2a 20 4e 6f 74 65 20 74 68 61 74  od..** Note that
6620: 20 74 68 65 20 73 74 61 74 69 63 20 6d 75 74 65   the static mute
6630: 78 20 61 6c 6c 6f 63 61 74 65 64 20 69 6e 20 78  x allocated in x
6640: 49 6e 69 74 20 64 6f 65 73 20 0a 2a 2a 20 6e 6f  Init does .** no
6650: 74 20 6e 65 65 64 20 74 6f 20 62 65 20 66 72 65  t need to be fre
6660: 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ed..*/.static vo
6670: 69 64 20 70 63 61 63 68 65 31 53 68 75 74 64 6f  id pcache1Shutdo
6680: 77 6e 28 76 6f 69 64 20 2a 4e 6f 74 55 73 65 64  wn(void *NotUsed
6690: 29 7b 0a 20 20 55 4e 55 53 45 44 5f 50 41 52 41  ){.  UNUSED_PARA
66a0: 4d 45 54 45 52 28 4e 6f 74 55 73 65 64 29 3b 0a  METER(NotUsed);.
66b0: 20 20 61 73 73 65 72 74 28 20 70 63 61 63 68 65    assert( pcache
66c0: 31 2e 69 73 49 6e 69 74 21 3d 30 20 29 3b 0a 20  1.isInit!=0 );. 
66d0: 20 6d 65 6d 73 65 74 28 26 70 63 61 63 68 65 31   memset(&pcache1
66e0: 2c 20 30 2c 20 73 69 7a 65 6f 66 28 70 63 61 63  , 0, sizeof(pcac
66f0: 68 65 31 29 29 3b 0a 7d 0a 0a 2f 2a 20 66 6f 72  he1));.}../* for
6700: 77 61 72 64 20 64 65 63 6c 61 72 61 74 69 6f 6e  ward declaration
6710: 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20   */.static void 
6720: 70 63 61 63 68 65 31 44 65 73 74 72 6f 79 28 73  pcache1Destroy(s
6730: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70  qlite3_pcache *p
6740: 29 3b 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d  );../*.** Implem
6750: 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20  entation of the 
6760: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78  sqlite3_pcache.x
6770: 43 72 65 61 74 65 20 6d 65 74 68 6f 64 2e 0a 2a  Create method..*
6780: 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65 20 61 20  *.** Allocate a 
6790: 6e 65 77 20 63 61 63 68 65 2e 0a 2a 2f 0a 73 74  new cache..*/.st
67a0: 61 74 69 63 20 73 71 6c 69 74 65 33 5f 70 63 61  atic sqlite3_pca
67b0: 63 68 65 20 2a 70 63 61 63 68 65 31 43 72 65 61  che *pcache1Crea
67c0: 74 65 28 69 6e 74 20 73 7a 50 61 67 65 2c 20 69  te(int szPage, i
67d0: 6e 74 20 73 7a 45 78 74 72 61 2c 20 69 6e 74 20  nt szExtra, int 
67e0: 62 50 75 72 67 65 61 62 6c 65 29 7b 0a 20 20 50  bPurgeable){.  P
67f0: 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 3b 20  Cache1 *pCache; 
6800: 20 20 20 20 20 2f 2a 20 54 68 65 20 6e 65 77 6c       /* The newl
6810: 79 20 63 72 65 61 74 65 64 20 70 61 67 65 20 63  y created page c
6820: 61 63 68 65 20 2a 2f 0a 20 20 50 47 72 6f 75 70  ache */.  PGroup
6830: 20 2a 70 47 72 6f 75 70 3b 20 20 20 20 20 20 20   *pGroup;       
6840: 2f 2a 20 54 68 65 20 67 72 6f 75 70 20 74 68 65  /* The group the
6850: 20 6e 65 77 20 70 61 67 65 20 63 61 63 68 65 20   new page cache 
6860: 77 69 6c 6c 20 62 65 6c 6f 6e 67 20 74 6f 20 2a  will belong to *
6870: 2f 0a 20 20 69 6e 74 20 73 7a 3b 20 20 20 20 20  /.  int sz;     
6880: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74            /* Byt
6890: 65 73 20 6f 66 20 6d 65 6d 6f 72 79 20 72 65 71  es of memory req
68a0: 75 69 72 65 64 20 74 6f 20 61 6c 6c 6f 63 61 74  uired to allocat
68b0: 65 20 74 68 65 20 6e 65 77 20 63 61 63 68 65 20  e the new cache 
68c0: 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 28 73  */..  assert( (s
68d0: 7a 50 61 67 65 20 26 20 28 73 7a 50 61 67 65 2d  zPage & (szPage-
68e0: 31 29 29 3d 3d 30 20 26 26 20 73 7a 50 61 67 65  1))==0 && szPage
68f0: 3e 3d 35 31 32 20 26 26 20 73 7a 50 61 67 65 3c  >=512 && szPage<
6900: 3d 36 35 35 33 36 20 29 3b 0a 20 20 61 73 73 65  =65536 );.  asse
6910: 72 74 28 20 73 7a 45 78 74 72 61 20 3c 20 33 30  rt( szExtra < 30
6920: 30 20 29 3b 0a 0a 20 20 73 7a 20 3d 20 73 69 7a  0 );..  sz = siz
6930: 65 6f 66 28 50 43 61 63 68 65 31 29 20 2b 20 73  eof(PCache1) + s
6940: 69 7a 65 6f 66 28 50 47 72 6f 75 70 29 2a 70 63  izeof(PGroup)*pc
6950: 61 63 68 65 31 2e 73 65 70 61 72 61 74 65 43 61  ache1.separateCa
6960: 63 68 65 3b 0a 20 20 70 43 61 63 68 65 20 3d 20  che;.  pCache = 
6970: 28 50 43 61 63 68 65 31 20 2a 29 73 71 6c 69 74  (PCache1 *)sqlit
6980: 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28 73 7a 29  e3MallocZero(sz)
6990: 3b 0a 20 20 69 66 28 20 70 43 61 63 68 65 20 29  ;.  if( pCache )
69a0: 7b 0a 20 20 20 20 69 66 28 20 70 63 61 63 68 65  {.    if( pcache
69b0: 31 2e 73 65 70 61 72 61 74 65 43 61 63 68 65 20  1.separateCache 
69c0: 29 7b 0a 20 20 20 20 20 20 70 47 72 6f 75 70 20  ){.      pGroup 
69d0: 3d 20 28 50 47 72 6f 75 70 2a 29 26 70 43 61 63  = (PGroup*)&pCac
69e0: 68 65 5b 31 5d 3b 0a 20 20 20 20 20 20 70 47 72  he[1];.      pGr
69f0: 6f 75 70 2d 3e 6d 78 50 69 6e 6e 65 64 20 3d 20  oup->mxPinned = 
6a00: 31 30 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  10;.    }else{. 
6a10: 20 20 20 20 20 70 47 72 6f 75 70 20 3d 20 26 70       pGroup = &p
6a20: 63 61 63 68 65 31 2e 67 72 70 3b 0a 20 20 20 20  cache1.grp;.    
6a30: 7d 0a 20 20 20 20 69 66 28 20 70 47 72 6f 75 70  }.    if( pGroup
6a40: 2d 3e 6c 72 75 2e 69 73 41 6e 63 68 6f 72 3d 3d  ->lru.isAnchor==
6a50: 30 20 29 7b 0a 20 20 20 20 20 20 70 47 72 6f 75  0 ){.      pGrou
6a60: 70 2d 3e 6c 72 75 2e 69 73 41 6e 63 68 6f 72 20  p->lru.isAnchor 
6a70: 3d 20 31 3b 0a 20 20 20 20 20 20 70 47 72 6f 75  = 1;.      pGrou
6a80: 70 2d 3e 6c 72 75 2e 70 4c 72 75 50 72 65 76 20  p->lru.pLruPrev 
6a90: 3d 20 70 47 72 6f 75 70 2d 3e 6c 72 75 2e 70 4c  = pGroup->lru.pL
6aa0: 72 75 4e 65 78 74 20 3d 20 26 70 47 72 6f 75 70  ruNext = &pGroup
6ab0: 2d 3e 6c 72 75 3b 0a 20 20 20 20 7d 0a 20 20 20  ->lru;.    }.   
6ac0: 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 20   pCache->pGroup 
6ad0: 3d 20 70 47 72 6f 75 70 3b 0a 20 20 20 20 70 43  = pGroup;.    pC
6ae0: 61 63 68 65 2d 3e 73 7a 50 61 67 65 20 3d 20 73  ache->szPage = s
6af0: 7a 50 61 67 65 3b 0a 20 20 20 20 70 43 61 63 68  zPage;.    pCach
6b00: 65 2d 3e 73 7a 45 78 74 72 61 20 3d 20 73 7a 45  e->szExtra = szE
6b10: 78 74 72 61 3b 0a 20 20 20 20 70 43 61 63 68 65  xtra;.    pCache
6b20: 2d 3e 73 7a 41 6c 6c 6f 63 20 3d 20 73 7a 50 61  ->szAlloc = szPa
6b30: 67 65 20 2b 20 73 7a 45 78 74 72 61 20 2b 20 52  ge + szExtra + R
6b40: 4f 55 4e 44 38 28 73 69 7a 65 6f 66 28 50 67 48  OUND8(sizeof(PgH
6b50: 64 72 31 29 29 3b 0a 20 20 20 20 70 43 61 63 68  dr1));.    pCach
6b60: 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 3d 20  e->bPurgeable = 
6b70: 28 62 50 75 72 67 65 61 62 6c 65 20 3f 20 31 20  (bPurgeable ? 1 
6b80: 3a 20 30 29 3b 0a 20 20 20 20 70 63 61 63 68 65  : 0);.    pcache
6b90: 31 45 6e 74 65 72 4d 75 74 65 78 28 70 47 72 6f  1EnterMutex(pGro
6ba0: 75 70 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31  up);.    pcache1
6bb0: 52 65 73 69 7a 65 48 61 73 68 28 70 43 61 63 68  ResizeHash(pCach
6bc0: 65 29 3b 0a 20 20 20 20 69 66 28 20 62 50 75 72  e);.    if( bPur
6bd0: 67 65 61 62 6c 65 20 29 7b 0a 20 20 20 20 20 20  geable ){.      
6be0: 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 20 3d 20 31  pCache->nMin = 1
6bf0: 30 3b 0a 20 20 20 20 20 20 70 47 72 6f 75 70 2d  0;.      pGroup-
6c00: 3e 6e 4d 69 6e 50 61 67 65 20 2b 3d 20 70 43 61  >nMinPage += pCa
6c10: 63 68 65 2d 3e 6e 4d 69 6e 3b 0a 20 20 20 20 20  che->nMin;.     
6c20: 20 70 47 72 6f 75 70 2d 3e 6d 78 50 69 6e 6e 65   pGroup->mxPinne
6c30: 64 20 3d 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78  d = pGroup->nMax
6c40: 50 61 67 65 20 2b 20 31 30 20 2d 20 70 47 72 6f  Page + 10 - pGro
6c50: 75 70 2d 3e 6e 4d 69 6e 50 61 67 65 3b 0a 20 20  up->nMinPage;.  
6c60: 20 20 20 20 70 43 61 63 68 65 2d 3e 70 6e 50 75      pCache->pnPu
6c70: 72 67 65 61 62 6c 65 20 3d 20 26 70 47 72 6f 75  rgeable = &pGrou
6c80: 70 2d 3e 6e 50 75 72 67 65 61 62 6c 65 3b 0a 20  p->nPurgeable;. 
6c90: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
6ca0: 73 74 61 74 69 63 20 75 6e 73 69 67 6e 65 64 20  static unsigned 
6cb0: 69 6e 74 20 64 75 6d 6d 79 43 75 72 72 65 6e 74  int dummyCurrent
6cc0: 50 61 67 65 3b 0a 20 20 20 20 20 20 70 43 61 63  Page;.      pCac
6cd0: 68 65 2d 3e 70 6e 50 75 72 67 65 61 62 6c 65 20  he->pnPurgeable 
6ce0: 3d 20 26 64 75 6d 6d 79 43 75 72 72 65 6e 74 50  = &dummyCurrentP
6cf0: 61 67 65 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70  age;.    }.    p
6d00: 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65 78  cache1LeaveMutex
6d10: 28 70 47 72 6f 75 70 29 3b 0a 20 20 20 20 69 66  (pGroup);.    if
6d20: 28 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3d  ( pCache->nHash=
6d30: 3d 30 20 29 7b 0a 20 20 20 20 20 20 70 63 61 63  =0 ){.      pcac
6d40: 68 65 31 44 65 73 74 72 6f 79 28 28 73 71 6c 69  he1Destroy((sqli
6d50: 74 65 33 5f 70 63 61 63 68 65 2a 29 70 43 61 63  te3_pcache*)pCac
6d60: 68 65 29 3b 0a 20 20 20 20 20 20 70 43 61 63 68  he);.      pCach
6d70: 65 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20 7d  e = 0;.    }.  }
6d80: 0a 20 20 72 65 74 75 72 6e 20 28 73 71 6c 69 74  .  return (sqlit
6d90: 65 33 5f 70 63 61 63 68 65 20 2a 29 70 43 61 63  e3_pcache *)pCac
6da0: 68 65 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70  he;.}../*.** Imp
6db0: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74  lementation of t
6dc0: 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68  he sqlite3_pcach
6dd0: 65 2e 78 43 61 63 68 65 73 69 7a 65 20 6d 65 74  e.xCachesize met
6de0: 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20 43 6f 6e 66  hod. .**.** Conf
6df0: 69 67 75 72 65 20 74 68 65 20 63 61 63 68 65 5f  igure the cache_
6e00: 73 69 7a 65 20 6c 69 6d 69 74 20 66 6f 72 20 61  size limit for a
6e10: 20 63 61 63 68 65 2e 0a 2a 2f 0a 73 74 61 74 69   cache..*/.stati
6e20: 63 20 76 6f 69 64 20 70 63 61 63 68 65 31 43 61  c void pcache1Ca
6e30: 63 68 65 73 69 7a 65 28 73 71 6c 69 74 65 33 5f  chesize(sqlite3_
6e40: 70 63 61 63 68 65 20 2a 70 2c 20 69 6e 74 20 6e  pcache *p, int n
6e50: 4d 61 78 29 7b 0a 20 20 50 43 61 63 68 65 31 20  Max){.  PCache1 
6e60: 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61 63 68  *pCache = (PCach
6e70: 65 31 20 2a 29 70 3b 0a 20 20 69 66 28 20 70 43  e1 *)p;.  if( pC
6e80: 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65  ache->bPurgeable
6e90: 20 29 7b 0a 20 20 20 20 50 47 72 6f 75 70 20 2a   ){.    PGroup *
6ea0: 70 47 72 6f 75 70 20 3d 20 70 43 61 63 68 65 2d  pGroup = pCache-
6eb0: 3e 70 47 72 6f 75 70 3b 0a 20 20 20 20 70 63 61  >pGroup;.    pca
6ec0: 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70  che1EnterMutex(p
6ed0: 47 72 6f 75 70 29 3b 0a 20 20 20 20 70 47 72 6f  Group);.    pGro
6ee0: 75 70 2d 3e 6e 4d 61 78 50 61 67 65 20 2b 3d 20  up->nMaxPage += 
6ef0: 28 6e 4d 61 78 20 2d 20 70 43 61 63 68 65 2d 3e  (nMax - pCache->
6f00: 6e 4d 61 78 29 3b 0a 20 20 20 20 70 47 72 6f 75  nMax);.    pGrou
6f10: 70 2d 3e 6d 78 50 69 6e 6e 65 64 20 3d 20 70 47  p->mxPinned = pG
6f20: 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65 20 2b  roup->nMaxPage +
6f30: 20 31 30 20 2d 20 70 47 72 6f 75 70 2d 3e 6e 4d   10 - pGroup->nM
6f40: 69 6e 50 61 67 65 3b 0a 20 20 20 20 70 43 61 63  inPage;.    pCac
6f50: 68 65 2d 3e 6e 4d 61 78 20 3d 20 6e 4d 61 78 3b  he->nMax = nMax;
6f60: 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 6e 39 30  .    pCache->n90
6f70: 70 63 74 20 3d 20 70 43 61 63 68 65 2d 3e 6e 4d  pct = pCache->nM
6f80: 61 78 2a 39 2f 31 30 3b 0a 20 20 20 20 70 63 61  ax*9/10;.    pca
6f90: 63 68 65 31 45 6e 66 6f 72 63 65 4d 61 78 50 61  che1EnforceMaxPa
6fa0: 67 65 28 70 43 61 63 68 65 29 3b 0a 20 20 20 20  ge(pCache);.    
6fb0: 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65  pcache1LeaveMute
6fc0: 78 28 70 47 72 6f 75 70 29 3b 0a 20 20 7d 0a 7d  x(pGroup);.  }.}
6fd0: 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e  ../*.** Implemen
6fe0: 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71  tation of the sq
6ff0: 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78 53 68  lite3_pcache.xSh
7000: 72 69 6e 6b 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a  rink method. .**
7010: 0a 2a 2a 20 46 72 65 65 20 75 70 20 61 73 20 6d  .** Free up as m
7020: 75 63 68 20 6d 65 6d 6f 72 79 20 61 73 20 70 6f  uch memory as po
7030: 73 73 69 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69  ssible..*/.stati
7040: 63 20 76 6f 69 64 20 70 63 61 63 68 65 31 53 68  c void pcache1Sh
7050: 72 69 6e 6b 28 73 71 6c 69 74 65 33 5f 70 63 61  rink(sqlite3_pca
7060: 63 68 65 20 2a 70 29 7b 0a 20 20 50 43 61 63 68  che *p){.  PCach
7070: 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43  e1 *pCache = (PC
7080: 61 63 68 65 31 2a 29 70 3b 0a 20 20 69 66 28 20  ache1*)p;.  if( 
7090: 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62  pCache->bPurgeab
70a0: 6c 65 20 29 7b 0a 20 20 20 20 50 47 72 6f 75 70  le ){.    PGroup
70b0: 20 2a 70 47 72 6f 75 70 20 3d 20 70 43 61 63 68   *pGroup = pCach
70c0: 65 2d 3e 70 47 72 6f 75 70 3b 0a 20 20 20 20 69  e->pGroup;.    i
70d0: 6e 74 20 73 61 76 65 64 4d 61 78 50 61 67 65 3b  nt savedMaxPage;
70e0: 0a 20 20 20 20 70 63 61 63 68 65 31 45 6e 74 65  .    pcache1Ente
70f0: 72 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b 0a  rMutex(pGroup);.
7100: 20 20 20 20 73 61 76 65 64 4d 61 78 50 61 67 65      savedMaxPage
7110: 20 3d 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50   = pGroup->nMaxP
7120: 61 67 65 3b 0a 20 20 20 20 70 47 72 6f 75 70 2d  age;.    pGroup-
7130: 3e 6e 4d 61 78 50 61 67 65 20 3d 20 30 3b 0a 20  >nMaxPage = 0;. 
7140: 20 20 20 70 63 61 63 68 65 31 45 6e 66 6f 72 63     pcache1Enforc
7150: 65 4d 61 78 50 61 67 65 28 70 43 61 63 68 65 29  eMaxPage(pCache)
7160: 3b 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e 6e 4d  ;.    pGroup->nM
7170: 61 78 50 61 67 65 20 3d 20 73 61 76 65 64 4d 61  axPage = savedMa
7180: 78 50 61 67 65 3b 0a 20 20 20 20 70 63 61 63 68  xPage;.    pcach
7190: 65 31 4c 65 61 76 65 4d 75 74 65 78 28 70 47 72  e1LeaveMutex(pGr
71a0: 6f 75 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a  oup);.  }.}../*.
71b0: 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  ** Implementatio
71c0: 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33  n of the sqlite3
71d0: 5f 70 63 61 63 68 65 2e 78 50 61 67 65 63 6f 75  _pcache.xPagecou
71e0: 6e 74 20 6d 65 74 68 6f 64 2e 20 0a 2a 2f 0a 73  nt method. .*/.s
71f0: 74 61 74 69 63 20 69 6e 74 20 70 63 61 63 68 65  tatic int pcache
7200: 31 50 61 67 65 63 6f 75 6e 74 28 73 71 6c 69 74  1Pagecount(sqlit
7210: 65 33 5f 70 63 61 63 68 65 20 2a 70 29 7b 0a 20  e3_pcache *p){. 
7220: 20 69 6e 74 20 6e 3b 0a 20 20 50 43 61 63 68 65   int n;.  PCache
7230: 31 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61  1 *pCache = (PCa
7240: 63 68 65 31 2a 29 70 3b 0a 20 20 70 63 61 63 68  che1*)p;.  pcach
7250: 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70 43 61  e1EnterMutex(pCa
7260: 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 20 20  che->pGroup);.  
7270: 6e 20 3d 20 70 43 61 63 68 65 2d 3e 6e 50 61 67  n = pCache->nPag
7280: 65 3b 0a 20 20 70 63 61 63 68 65 31 4c 65 61 76  e;.  pcache1Leav
7290: 65 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e 70  eMutex(pCache->p
72a0: 47 72 6f 75 70 29 3b 0a 20 20 72 65 74 75 72 6e  Group);.  return
72b0: 20 6e 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 49 6d   n;.}.../*.** Im
72c0: 70 6c 65 6d 65 6e 74 20 73 74 65 70 73 20 33 2c  plement steps 3,
72d0: 20 34 2c 20 61 6e 64 20 35 20 6f 66 20 74 68 65   4, and 5 of the
72e0: 20 70 63 61 63 68 65 31 46 65 74 63 68 28 29 20   pcache1Fetch() 
72f0: 61 6c 67 6f 72 69 74 68 6d 20 64 65 73 63 72 69  algorithm descri
7300: 62 65 64 0a 2a 2a 20 69 6e 20 74 68 65 20 68 65  bed.** in the he
7310: 61 64 65 72 20 6f 66 20 74 68 65 20 70 63 61 63  ader of the pcac
7320: 68 65 31 46 65 74 63 68 28 29 20 70 72 6f 63 65  he1Fetch() proce
7330: 64 75 72 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73  dure..**.** This
7340: 20 73 74 65 70 73 20 61 72 65 20 62 72 6f 6b 65   steps are broke
7350: 6e 20 6f 75 74 20 69 6e 74 6f 20 61 20 73 65 70  n out into a sep
7360: 61 72 61 74 65 20 70 72 6f 63 65 64 75 72 65 20  arate procedure 
7370: 62 65 63 61 75 73 65 20 74 68 65 79 20 61 72 65  because they are
7380: 0a 2a 2a 20 75 73 75 61 6c 6c 79 20 6e 6f 74 20  .** usually not 
7390: 6e 65 65 64 65 64 2c 20 61 6e 64 20 62 79 20 61  needed, and by a
73a0: 76 6f 69 64 69 6e 67 20 74 68 65 20 73 74 61 63  voiding the stac
73b0: 6b 20 69 6e 69 74 69 61 6c 69 7a 61 74 69 6f 6e  k initialization
73c0: 20 72 65 71 75 69 72 65 64 0a 2a 2a 20 66 6f 72   required.** for
73d0: 20 74 68 65 73 65 20 73 74 65 70 73 2c 20 74 68   these steps, th
73e0: 65 20 6d 61 69 6e 20 70 63 61 63 68 65 31 46 65  e main pcache1Fe
73f0: 74 63 68 28 29 20 70 72 6f 63 65 64 75 72 65 20  tch() procedure 
7400: 63 61 6e 20 72 75 6e 20 66 61 73 74 65 72 2e 0a  can run faster..
7410: 2a 2f 0a 73 74 61 74 69 63 20 53 51 4c 49 54 45  */.static SQLITE
7420: 5f 4e 4f 49 4e 4c 49 4e 45 20 50 67 48 64 72 31  _NOINLINE PgHdr1
7430: 20 2a 70 63 61 63 68 65 31 46 65 74 63 68 53 74   *pcache1FetchSt
7440: 61 67 65 32 28 0a 20 20 50 43 61 63 68 65 31 20  age2(.  PCache1 
7450: 2a 70 43 61 63 68 65 2c 20 0a 20 20 75 6e 73 69  *pCache, .  unsi
7460: 67 6e 65 64 20 69 6e 74 20 69 4b 65 79 2c 20 0a  gned int iKey, .
7470: 20 20 69 6e 74 20 63 72 65 61 74 65 46 6c 61 67    int createFlag
7480: 0a 29 7b 0a 20 20 75 6e 73 69 67 6e 65 64 20 69  .){.  unsigned i
7490: 6e 74 20 6e 50 69 6e 6e 65 64 3b 0a 20 20 50 47  nt nPinned;.  PG
74a0: 72 6f 75 70 20 2a 70 47 72 6f 75 70 20 3d 20 70  roup *pGroup = p
74b0: 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b 0a 20  Cache->pGroup;. 
74c0: 20 50 67 48 64 72 31 20 2a 70 50 61 67 65 20 3d   PgHdr1 *pPage =
74d0: 20 30 3b 0a 0a 20 20 2f 2a 20 53 74 65 70 20 33   0;..  /* Step 3
74e0: 3a 20 41 62 6f 72 74 20 69 66 20 63 72 65 61 74  : Abort if creat
74f0: 65 46 6c 61 67 20 69 73 20 31 20 62 75 74 20 74  eFlag is 1 but t
7500: 68 65 20 63 61 63 68 65 20 69 73 20 6e 65 61 72  he cache is near
7510: 6c 79 20 66 75 6c 6c 20 2a 2f 0a 20 20 61 73 73  ly full */.  ass
7520: 65 72 74 28 20 70 43 61 63 68 65 2d 3e 6e 50 61  ert( pCache->nPa
7530: 67 65 20 3e 3d 20 70 43 61 63 68 65 2d 3e 6e 52  ge >= pCache->nR
7540: 65 63 79 63 6c 61 62 6c 65 20 29 3b 0a 20 20 6e  ecyclable );.  n
7550: 50 69 6e 6e 65 64 20 3d 20 70 43 61 63 68 65 2d  Pinned = pCache-
7560: 3e 6e 50 61 67 65 20 2d 20 70 43 61 63 68 65 2d  >nPage - pCache-
7570: 3e 6e 52 65 63 79 63 6c 61 62 6c 65 3b 0a 20 20  >nRecyclable;.  
7580: 61 73 73 65 72 74 28 20 70 47 72 6f 75 70 2d 3e  assert( pGroup->
7590: 6d 78 50 69 6e 6e 65 64 20 3d 3d 20 70 47 72 6f  mxPinned == pGro
75a0: 75 70 2d 3e 6e 4d 61 78 50 61 67 65 20 2b 20 31  up->nMaxPage + 1
75b0: 30 20 2d 20 70 47 72 6f 75 70 2d 3e 6e 4d 69 6e  0 - pGroup->nMin
75c0: 50 61 67 65 20 29 3b 0a 20 20 61 73 73 65 72 74  Page );.  assert
75d0: 28 20 70 43 61 63 68 65 2d 3e 6e 39 30 70 63 74  ( pCache->n90pct
75e0: 20 3d 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78   == pCache->nMax
75f0: 2a 39 2f 31 30 20 29 3b 0a 20 20 69 66 28 20 63  *9/10 );.  if( c
7600: 72 65 61 74 65 46 6c 61 67 3d 3d 31 20 26 26 20  reateFlag==1 && 
7610: 28 0a 20 20 20 20 20 20 20 20 6e 50 69 6e 6e 65  (.        nPinne
7620: 64 3e 3d 70 47 72 6f 75 70 2d 3e 6d 78 50 69 6e  d>=pGroup->mxPin
7630: 6e 65 64 0a 20 20 20 20 20 7c 7c 20 6e 50 69 6e  ned.     || nPin
7640: 6e 65 64 3e 3d 70 43 61 63 68 65 2d 3e 6e 39 30  ned>=pCache->n90
7650: 70 63 74 0a 20 20 20 20 20 7c 7c 20 28 70 63 61  pct.     || (pca
7660: 63 68 65 31 55 6e 64 65 72 4d 65 6d 6f 72 79 50  che1UnderMemoryP
7670: 72 65 73 73 75 72 65 28 70 43 61 63 68 65 29 20  ressure(pCache) 
7680: 26 26 20 70 43 61 63 68 65 2d 3e 6e 52 65 63 79  && pCache->nRecy
7690: 63 6c 61 62 6c 65 3c 6e 50 69 6e 6e 65 64 29 0a  clable<nPinned).
76a0: 20 20 29 29 7b 0a 20 20 20 20 72 65 74 75 72 6e    )){.    return
76b0: 20 30 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70   0;.  }..  if( p
76c0: 43 61 63 68 65 2d 3e 6e 50 61 67 65 3e 3d 70 43  Cache->nPage>=pC
76d0: 61 63 68 65 2d 3e 6e 48 61 73 68 20 29 20 70 63  ache->nHash ) pc
76e0: 61 63 68 65 31 52 65 73 69 7a 65 48 61 73 68 28  ache1ResizeHash(
76f0: 70 43 61 63 68 65 29 3b 0a 20 20 61 73 73 65 72  pCache);.  asser
7700: 74 28 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68  t( pCache->nHash
7710: 3e 30 20 26 26 20 70 43 61 63 68 65 2d 3e 61 70  >0 && pCache->ap
7720: 48 61 73 68 20 29 3b 0a 0a 20 20 2f 2a 20 53 74  Hash );..  /* St
7730: 65 70 20 34 2e 20 54 72 79 20 74 6f 20 72 65 63  ep 4. Try to rec
7740: 79 63 6c 65 20 61 20 70 61 67 65 2e 20 2a 2f 0a  ycle a page. */.
7750: 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 62 50    if( pCache->bP
7760: 75 72 67 65 61 62 6c 65 0a 20 20 20 26 26 20 21  urgeable.   && !
7770: 70 47 72 6f 75 70 2d 3e 6c 72 75 2e 70 4c 72 75  pGroup->lru.pLru
7780: 50 72 65 76 2d 3e 69 73 41 6e 63 68 6f 72 0a 20  Prev->isAnchor. 
7790: 20 20 26 26 20 28 28 70 43 61 63 68 65 2d 3e 6e    && ((pCache->n
77a0: 50 61 67 65 2b 31 3e 3d 70 43 61 63 68 65 2d 3e  Page+1>=pCache->
77b0: 6e 4d 61 78 29 20 7c 7c 20 70 63 61 63 68 65 31  nMax) || pcache1
77c0: 55 6e 64 65 72 4d 65 6d 6f 72 79 50 72 65 73 73  UnderMemoryPress
77d0: 75 72 65 28 70 43 61 63 68 65 29 29 0a 20 20 29  ure(pCache)).  )
77e0: 7b 0a 20 20 20 20 50 43 61 63 68 65 31 20 2a 70  {.    PCache1 *p
77f0: 4f 74 68 65 72 3b 0a 20 20 20 20 70 50 61 67 65  Other;.    pPage
7800: 20 3d 20 70 47 72 6f 75 70 2d 3e 6c 72 75 2e 70   = pGroup->lru.p
7810: 4c 72 75 50 72 65 76 3b 0a 20 20 20 20 61 73 73  LruPrev;.    ass
7820: 65 72 74 28 20 50 41 47 45 5f 49 53 5f 55 4e 50  ert( PAGE_IS_UNP
7830: 49 4e 4e 45 44 28 70 50 61 67 65 29 20 29 3b 0a  INNED(pPage) );.
7840: 20 20 20 20 70 63 61 63 68 65 31 52 65 6d 6f 76      pcache1Remov
7850: 65 46 72 6f 6d 48 61 73 68 28 70 50 61 67 65 2c  eFromHash(pPage,
7860: 20 30 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31   0);.    pcache1
7870: 50 69 6e 50 61 67 65 28 70 50 61 67 65 29 3b 0a  PinPage(pPage);.
7880: 20 20 20 20 70 4f 74 68 65 72 20 3d 20 70 50 61      pOther = pPa
7890: 67 65 2d 3e 70 43 61 63 68 65 3b 0a 20 20 20 20  ge->pCache;.    
78a0: 69 66 28 20 70 4f 74 68 65 72 2d 3e 73 7a 41 6c  if( pOther->szAl
78b0: 6c 6f 63 20 21 3d 20 70 43 61 63 68 65 2d 3e 73  loc != pCache->s
78c0: 7a 41 6c 6c 6f 63 20 29 7b 0a 20 20 20 20 20 20  zAlloc ){.      
78d0: 70 63 61 63 68 65 31 46 72 65 65 50 61 67 65 28  pcache1FreePage(
78e0: 70 50 61 67 65 29 3b 0a 20 20 20 20 20 20 70 50  pPage);.      pP
78f0: 61 67 65 20 3d 20 30 3b 0a 20 20 20 20 7d 65 6c  age = 0;.    }el
7900: 73 65 7b 0a 20 20 20 20 20 20 70 47 72 6f 75 70  se{.      pGroup
7910: 2d 3e 6e 50 75 72 67 65 61 62 6c 65 20 2d 3d 20  ->nPurgeable -= 
7920: 28 70 4f 74 68 65 72 2d 3e 62 50 75 72 67 65 61  (pOther->bPurgea
7930: 62 6c 65 20 2d 20 70 43 61 63 68 65 2d 3e 62 50  ble - pCache->bP
7940: 75 72 67 65 61 62 6c 65 29 3b 0a 20 20 20 20 7d  urgeable);.    }
7950: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53 74 65 70 20  .  }..  /* Step 
7960: 35 2e 20 49 66 20 61 20 75 73 61 62 6c 65 20 70  5. If a usable p
7970: 61 67 65 20 62 75 66 66 65 72 20 68 61 73 20 73  age buffer has s
7980: 74 69 6c 6c 20 6e 6f 74 20 62 65 65 6e 20 66 6f  till not been fo
7990: 75 6e 64 2c 20 0a 20 20 2a 2a 20 61 74 74 65 6d  und, .  ** attem
79a0: 70 74 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 61  pt to allocate a
79b0: 20 6e 65 77 20 6f 6e 65 2e 20 0a 20 20 2a 2f 0a   new one. .  */.
79c0: 20 20 69 66 28 20 21 70 50 61 67 65 20 29 7b 0a    if( !pPage ){.
79d0: 20 20 20 20 70 50 61 67 65 20 3d 20 70 63 61 63      pPage = pcac
79e0: 68 65 31 41 6c 6c 6f 63 50 61 67 65 28 70 43 61  he1AllocPage(pCa
79f0: 63 68 65 2c 20 63 72 65 61 74 65 46 6c 61 67 3d  che, createFlag=
7a00: 3d 31 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20  =1);.  }..  if( 
7a10: 70 50 61 67 65 20 29 7b 0a 20 20 20 20 75 6e 73  pPage ){.    uns
7a20: 69 67 6e 65 64 20 69 6e 74 20 68 20 3d 20 69 4b  igned int h = iK
7a30: 65 79 20 25 20 70 43 61 63 68 65 2d 3e 6e 48 61  ey % pCache->nHa
7a40: 73 68 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e  sh;.    pCache->
7a50: 6e 50 61 67 65 2b 2b 3b 0a 20 20 20 20 70 50 61  nPage++;.    pPa
7a60: 67 65 2d 3e 69 4b 65 79 20 3d 20 69 4b 65 79 3b  ge->iKey = iKey;
7a70: 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 4e 65 78  .    pPage->pNex
7a80: 74 20 3d 20 70 43 61 63 68 65 2d 3e 61 70 48 61  t = pCache->apHa
7a90: 73 68 5b 68 5d 3b 0a 20 20 20 20 70 50 61 67 65  sh[h];.    pPage
7aa0: 2d 3e 70 43 61 63 68 65 20 3d 20 70 43 61 63 68  ->pCache = pCach
7ab0: 65 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 4c  e;.    pPage->pL
7ac0: 72 75 50 72 65 76 20 3d 20 30 3b 0a 20 20 20 20  ruPrev = 0;.    
7ad0: 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 20  pPage->pLruNext 
7ae0: 3d 20 30 3b 0a 20 20 20 20 2a 28 76 6f 69 64 20  = 0;.    *(void 
7af0: 2a 2a 29 70 50 61 67 65 2d 3e 70 61 67 65 2e 70  **)pPage->page.p
7b00: 45 78 74 72 61 20 3d 20 30 3b 0a 20 20 20 20 70  Extra = 0;.    p
7b10: 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68 5d  Cache->apHash[h]
7b20: 20 3d 20 70 50 61 67 65 3b 0a 20 20 20 20 69 66   = pPage;.    if
7b30: 28 20 69 4b 65 79 3e 70 43 61 63 68 65 2d 3e 69  ( iKey>pCache->i
7b40: 4d 61 78 4b 65 79 20 29 7b 0a 20 20 20 20 20 20  MaxKey ){.      
7b50: 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20  pCache->iMaxKey 
7b60: 3d 20 69 4b 65 79 3b 0a 20 20 20 20 7d 0a 20 20  = iKey;.    }.  
7b70: 7d 0a 20 20 72 65 74 75 72 6e 20 70 50 61 67 65  }.  return pPage
7b80: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65  ;.}../*.** Imple
7b90: 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65  mentation of the
7ba0: 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e   sqlite3_pcache.
7bb0: 78 46 65 74 63 68 20 6d 65 74 68 6f 64 2e 20 0a  xFetch method. .
7bc0: 2a 2a 0a 2a 2a 20 46 65 74 63 68 20 61 20 70 61  **.** Fetch a pa
7bd0: 67 65 20 62 79 20 6b 65 79 20 76 61 6c 75 65 2e  ge by key value.
7be0: 0a 2a 2a 0a 2a 2a 20 57 68 65 74 68 65 72 20 6f  .**.** Whether o
7bf0: 72 20 6e 6f 74 20 61 20 6e 65 77 20 70 61 67 65  r not a new page
7c00: 20 6d 61 79 20 62 65 20 61 6c 6c 6f 63 61 74 65   may be allocate
7c10: 64 20 62 79 20 74 68 69 73 20 66 75 6e 63 74 69  d by this functi
7c20: 6f 6e 20 64 65 70 65 6e 64 73 20 6f 6e 0a 2a 2a  on depends on.**
7c30: 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20 74 68   the value of th
7c40: 65 20 63 72 65 61 74 65 46 6c 61 67 20 61 72 67  e createFlag arg
7c50: 75 6d 65 6e 74 2e 20 20 30 20 6d 65 61 6e 73 20  ument.  0 means 
7c60: 64 6f 20 6e 6f 74 20 61 6c 6c 6f 63 61 74 65 20  do not allocate 
7c70: 61 20 6e 65 77 0a 2a 2a 20 70 61 67 65 2e 20 20  a new.** page.  
7c80: 31 20 6d 65 61 6e 73 20 61 6c 6c 6f 63 61 74 65  1 means allocate
7c90: 20 61 20 6e 65 77 20 70 61 67 65 20 69 66 20 73   a new page if s
7ca0: 70 61 63 65 20 69 73 20 65 61 73 69 6c 79 20 61  pace is easily a
7cb0: 76 61 69 6c 61 62 6c 65 2e 20 20 32 20 0a 2a 2a  vailable.  2 .**
7cc0: 20 6d 65 61 6e 73 20 74 6f 20 74 72 79 20 72 65   means to try re
7cd0: 61 6c 6c 79 20 68 61 72 64 20 74 6f 20 61 6c 6c  ally hard to all
7ce0: 6f 63 61 74 65 20 61 20 6e 65 77 20 70 61 67 65  ocate a new page
7cf0: 2e 0a 2a 2a 0a 2a 2a 20 46 6f 72 20 61 20 6e 6f  ..**.** For a no
7d00: 6e 2d 70 75 72 67 65 61 62 6c 65 20 63 61 63 68  n-purgeable cach
7d10: 65 20 28 61 20 63 61 63 68 65 20 75 73 65 64 20  e (a cache used 
7d20: 61 73 20 74 68 65 20 73 74 6f 72 61 67 65 20 66  as the storage f
7d30: 6f 72 20 61 6e 20 69 6e 2d 6d 65 6d 6f 72 79 0a  or an in-memory.
7d40: 2a 2a 20 64 61 74 61 62 61 73 65 29 20 74 68 65  ** database) the
7d50: 72 65 20 69 73 20 72 65 61 6c 6c 79 20 6e 6f 20  re is really no 
7d60: 64 69 66 66 65 72 65 6e 63 65 20 62 65 74 77 65  difference betwe
7d70: 65 6e 20 63 72 65 61 74 65 46 6c 61 67 20 31 20  en createFlag 1 
7d80: 61 6e 64 20 32 2e 20 20 53 6f 0a 2a 2a 20 74 68  and 2.  So.** th
7d90: 65 20 63 61 6c 6c 69 6e 67 20 66 75 6e 63 74 69  e calling functi
7da0: 6f 6e 20 28 70 63 61 63 68 65 2e 63 29 20 77 69  on (pcache.c) wi
7db0: 6c 6c 20 6e 65 76 65 72 20 68 61 76 65 20 61 20  ll never have a 
7dc0: 63 72 65 61 74 65 46 6c 61 67 20 6f 66 20 31 20  createFlag of 1 
7dd0: 6f 6e 0a 2a 2a 20 61 20 6e 6f 6e 2d 70 75 72 67  on.** a non-purg
7de0: 65 61 62 6c 65 20 63 61 63 68 65 2e 0a 2a 2a 0a  eable cache..**.
7df0: 2a 2a 20 54 68 65 72 65 20 61 72 65 20 74 68 72  ** There are thr
7e00: 65 65 20 64 69 66 66 65 72 65 6e 74 20 61 70 70  ee different app
7e10: 72 6f 61 63 68 65 73 20 74 6f 20 6f 62 74 61 69  roaches to obtai
7e20: 6e 69 6e 67 20 73 70 61 63 65 20 66 6f 72 20 61  ning space for a
7e30: 20 70 61 67 65 2c 0a 2a 2a 20 64 65 70 65 6e 64   page,.** depend
7e40: 69 6e 67 20 6f 6e 20 74 68 65 20 76 61 6c 75 65  ing on the value
7e50: 20 6f 66 20 70 61 72 61 6d 65 74 65 72 20 63 72   of parameter cr
7e60: 65 61 74 65 46 6c 61 67 20 28 77 68 69 63 68 20  eateFlag (which 
7e70: 6d 61 79 20 62 65 20 30 2c 20 31 20 6f 72 20 32  may be 0, 1 or 2
7e80: 29 2e 0a 2a 2a 0a 2a 2a 20 20 20 31 2e 20 52 65  )..**.**   1. Re
7e90: 67 61 72 64 6c 65 73 73 20 6f 66 20 74 68 65 20  gardless of the 
7ea0: 76 61 6c 75 65 20 6f 66 20 63 72 65 61 74 65 46  value of createF
7eb0: 6c 61 67 2c 20 74 68 65 20 63 61 63 68 65 20 69  lag, the cache i
7ec0: 73 20 73 65 61 72 63 68 65 64 20 66 6f 72 20 61  s searched for a
7ed0: 20 0a 2a 2a 20 20 20 20 20 20 63 6f 70 79 20 6f   .**      copy o
7ee0: 66 20 74 68 65 20 72 65 71 75 65 73 74 65 64 20  f the requested 
7ef0: 70 61 67 65 2e 20 49 66 20 6f 6e 65 20 69 73 20  page. If one is 
7f00: 66 6f 75 6e 64 2c 20 69 74 20 69 73 20 72 65 74  found, it is ret
7f10: 75 72 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 32  urned..**.**   2
7f20: 2e 20 49 66 20 63 72 65 61 74 65 46 6c 61 67 3d  . If createFlag=
7f30: 3d 30 20 61 6e 64 20 74 68 65 20 70 61 67 65 20  =0 and the page 
7f40: 69 73 20 6e 6f 74 20 61 6c 72 65 61 64 79 20 69  is not already i
7f50: 6e 20 74 68 65 20 63 61 63 68 65 2c 20 4e 55 4c  n the cache, NUL
7f60: 4c 20 69 73 0a 2a 2a 20 20 20 20 20 20 72 65 74  L is.**      ret
7f70: 75 72 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 33  urned..**.**   3
7f80: 2e 20 49 66 20 63 72 65 61 74 65 46 6c 61 67 20  . If createFlag 
7f90: 69 73 20 31 2c 20 61 6e 64 20 74 68 65 20 70 61  is 1, and the pa
7fa0: 67 65 20 69 73 20 6e 6f 74 20 61 6c 72 65 61 64  ge is not alread
7fb0: 79 20 69 6e 20 74 68 65 20 63 61 63 68 65 2c 20  y in the cache, 
7fc0: 74 68 65 6e 0a 2a 2a 20 20 20 20 20 20 72 65 74  then.**      ret
7fd0: 75 72 6e 20 4e 55 4c 4c 20 28 64 6f 20 6e 6f 74  urn NULL (do not
7fe0: 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77 20   allocate a new 
7ff0: 70 61 67 65 29 20 69 66 20 61 6e 79 20 6f 66 20  page) if any of 
8000: 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 0a 2a 2a  the following.**
8010: 20 20 20 20 20 20 63 6f 6e 64 69 74 69 6f 6e 73        conditions
8020: 20 61 72 65 20 74 72 75 65 3a 0a 2a 2a 0a 2a 2a   are true:.**.**
8030: 20 20 20 20 20 20 20 28 61 29 20 74 68 65 20 6e         (a) the n
8040: 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 70  umber of pages p
8050: 69 6e 6e 65 64 20 62 79 20 74 68 65 20 63 61 63  inned by the cac
8060: 68 65 20 69 73 20 67 72 65 61 74 65 72 20 74 68  he is greater th
8070: 61 6e 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20  an.**           
8080: 50 43 61 63 68 65 31 2e 6e 4d 61 78 2c 20 6f 72  PCache1.nMax, or
8090: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 28 62 29  .**.**       (b)
80a0: 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70   the number of p
80b0: 61 67 65 73 20 70 69 6e 6e 65 64 20 62 79 20 74  ages pinned by t
80c0: 68 65 20 63 61 63 68 65 20 69 73 20 67 72 65 61  he cache is grea
80d0: 74 65 72 20 74 68 61 6e 0a 2a 2a 20 20 20 20 20  ter than.**     
80e0: 20 20 20 20 20 20 74 68 65 20 73 75 6d 20 6f 66        the sum of
80f0: 20 6e 4d 61 78 20 66 6f 72 20 61 6c 6c 20 70 75   nMax for all pu
8100: 72 67 65 61 62 6c 65 20 63 61 63 68 65 73 2c 20  rgeable caches, 
8110: 6c 65 73 73 20 74 68 65 20 73 75 6d 20 6f 66 20  less the sum of 
8120: 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 6e 4d  .**           nM
8130: 69 6e 20 66 6f 72 20 61 6c 6c 20 6f 74 68 65 72  in for all other
8140: 20 70 75 72 67 65 61 62 6c 65 20 63 61 63 68 65   purgeable cache
8150: 73 2c 20 6f 72 0a 2a 2a 0a 2a 2a 20 20 20 34 2e  s, or.**.**   4.
8160: 20 49 66 20 6e 6f 6e 65 20 6f 66 20 74 68 65 20   If none of the 
8170: 66 69 72 73 74 20 74 68 72 65 65 20 63 6f 6e 64  first three cond
8180: 69 74 69 6f 6e 73 20 61 70 70 6c 79 20 61 6e 64  itions apply and
8190: 20 74 68 65 20 63 61 63 68 65 20 69 73 20 6d 61   the cache is ma
81a0: 72 6b 65 64 0a 2a 2a 20 20 20 20 20 20 61 73 20  rked.**      as 
81b0: 70 75 72 67 65 61 62 6c 65 2c 20 61 6e 64 20 69  purgeable, and i
81c0: 66 20 6f 6e 65 20 6f 66 20 74 68 65 20 66 6f 6c  f one of the fol
81d0: 6c 6f 77 69 6e 67 20 69 73 20 74 72 75 65 3a 0a  lowing is true:.
81e0: 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 28 61 29 20  **.**       (a) 
81f0: 54 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 61  The number of pa
8200: 67 65 73 20 61 6c 6c 6f 63 61 74 65 64 20 66 6f  ges allocated fo
8210: 72 20 74 68 65 20 63 61 63 68 65 20 69 73 20 61  r the cache is a
8220: 6c 72 65 61 64 79 20 0a 2a 2a 20 20 20 20 20 20  lready .**      
8230: 20 20 20 20 20 50 43 61 63 68 65 31 2e 6e 4d 61       PCache1.nMa
8240: 78 2c 20 6f 72 0a 2a 2a 0a 2a 2a 20 20 20 20 20  x, or.**.**     
8250: 20 20 28 62 29 20 54 68 65 20 6e 75 6d 62 65 72    (b) The number
8260: 20 6f 66 20 70 61 67 65 73 20 61 6c 6c 6f 63 61   of pages alloca
8270: 74 65 64 20 66 6f 72 20 61 6c 6c 20 70 75 72 67  ted for all purg
8280: 65 61 62 6c 65 20 63 61 63 68 65 73 20 69 73 0a  eable caches is.
8290: 2a 2a 20 20 20 20 20 20 20 20 20 20 20 61 6c 72  **           alr
82a0: 65 61 64 79 20 65 71 75 61 6c 20 74 6f 20 6f 72  eady equal to or
82b0: 20 67 72 65 61 74 65 72 20 74 68 61 6e 20 74 68   greater than th
82c0: 65 20 73 75 6d 20 6f 66 20 6e 4d 61 78 20 66 6f  e sum of nMax fo
82d0: 72 20 61 6c 6c 0a 2a 2a 20 20 20 20 20 20 20 20  r all.**        
82e0: 20 20 20 70 75 72 67 65 61 62 6c 65 20 63 61 63     purgeable cac
82f0: 68 65 73 2c 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20  hes,.**.**      
8300: 20 28 63 29 20 54 68 65 20 73 79 73 74 65 6d 20   (c) The system 
8310: 69 73 20 75 6e 64 65 72 20 6d 65 6d 6f 72 79 20  is under memory 
8320: 70 72 65 73 73 75 72 65 20 61 6e 64 20 77 61 6e  pressure and wan
8330: 74 73 20 74 6f 20 61 76 6f 69 64 0a 2a 2a 20 20  ts to avoid.**  
8340: 20 20 20 20 20 20 20 20 20 75 6e 6e 65 63 65 73           unneces
8350: 73 61 72 79 20 70 61 67 65 73 20 63 61 63 68 65  sary pages cache
8360: 20 65 6e 74 72 79 20 61 6c 6c 6f 63 61 74 69 6f   entry allocatio
8370: 6e 73 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 74 68  ns.**.**      th
8380: 65 6e 20 61 74 74 65 6d 70 74 20 74 6f 20 72 65  en attempt to re
8390: 63 79 63 6c 65 20 61 20 70 61 67 65 20 66 72 6f  cycle a page fro
83a0: 6d 20 74 68 65 20 4c 52 55 20 6c 69 73 74 2e 20  m the LRU list. 
83b0: 49 66 20 69 74 20 69 73 20 74 68 65 20 72 69 67  If it is the rig
83c0: 68 74 0a 2a 2a 20 20 20 20 20 20 73 69 7a 65 2c  ht.**      size,
83d0: 20 72 65 74 75 72 6e 20 74 68 65 20 72 65 63 79   return the recy
83e0: 63 6c 65 64 20 62 75 66 66 65 72 2e 20 4f 74 68  cled buffer. Oth
83f0: 65 72 77 69 73 65 2c 20 66 72 65 65 20 74 68 65  erwise, free the
8400: 20 62 75 66 66 65 72 20 61 6e 64 0a 2a 2a 20 20   buffer and.**  
8410: 20 20 20 20 70 72 6f 63 65 65 64 20 74 6f 20 73      proceed to s
8420: 74 65 70 20 35 2e 20 0a 2a 2a 0a 2a 2a 20 20 20  tep 5. .**.**   
8430: 35 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 61 6c  5. Otherwise, al
8440: 6c 6f 63 61 74 65 20 61 6e 64 20 72 65 74 75 72  locate and retur
8450: 6e 20 61 20 6e 65 77 20 70 61 67 65 20 62 75 66  n a new page buf
8460: 66 65 72 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 72 65  fer..**.** There
8470: 20 61 72 65 20 74 77 6f 20 76 65 72 73 69 6f 6e   are two version
8480: 73 20 6f 66 20 74 68 69 73 20 72 6f 75 74 69 6e  s of this routin
8490: 65 2e 20 20 70 63 61 63 68 65 31 46 65 74 63 68  e.  pcache1Fetch
84a0: 57 69 74 68 4d 75 74 65 78 28 29 20 69 73 0a 2a  WithMutex() is.*
84b0: 2a 20 74 68 65 20 67 65 6e 65 72 61 6c 20 63 61  * the general ca
84c0: 73 65 2e 20 20 70 63 61 63 68 65 31 46 65 74 63  se.  pcache1Fetc
84d0: 68 4e 6f 4d 75 74 65 78 28 29 20 69 73 20 61 20  hNoMutex() is a 
84e0: 66 61 73 74 65 72 20 69 6d 70 6c 65 6d 65 6e 74  faster implement
84f0: 61 74 69 6f 6e 20 66 6f 72 0a 2a 2a 20 74 68 65  ation for.** the
8500: 20 63 6f 6d 6d 6f 6e 20 63 61 73 65 20 77 68 65   common case whe
8510: 72 65 20 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78  re pGroup->mutex
8520: 20 69 73 20 4e 55 4c 4c 2e 20 20 54 68 65 20 70   is NULL.  The p
8530: 63 61 63 68 65 31 46 65 74 63 68 28 29 20 77 72  cache1Fetch() wr
8540: 61 70 70 65 72 0a 2a 2a 20 69 6e 76 6f 6b 65 73  apper.** invokes
8550: 20 74 68 65 20 61 70 70 72 6f 70 72 69 61 74 65   the appropriate
8560: 20 72 6f 75 74 69 6e 65 2e 0a 2a 2f 0a 73 74 61   routine..*/.sta
8570: 74 69 63 20 50 67 48 64 72 31 20 2a 70 63 61 63  tic PgHdr1 *pcac
8580: 68 65 31 46 65 74 63 68 4e 6f 4d 75 74 65 78 28  he1FetchNoMutex(
8590: 0a 20 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68  .  sqlite3_pcach
85a0: 65 20 2a 70 2c 20 0a 20 20 75 6e 73 69 67 6e 65  e *p, .  unsigne
85b0: 64 20 69 6e 74 20 69 4b 65 79 2c 20 0a 20 20 69  d int iKey, .  i
85c0: 6e 74 20 63 72 65 61 74 65 46 6c 61 67 0a 29 7b  nt createFlag.){
85d0: 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63  .  PCache1 *pCac
85e0: 68 65 20 3d 20 28 50 43 61 63 68 65 31 20 2a 29  he = (PCache1 *)
85f0: 70 3b 0a 20 20 50 67 48 64 72 31 20 2a 70 50 61  p;.  PgHdr1 *pPa
8600: 67 65 20 3d 20 30 3b 0a 0a 20 20 2f 2a 20 53 74  ge = 0;..  /* St
8610: 65 70 20 31 3a 20 53 65 61 72 63 68 20 74 68 65  ep 1: Search the
8620: 20 68 61 73 68 20 74 61 62 6c 65 20 66 6f 72 20   hash table for 
8630: 61 6e 20 65 78 69 73 74 69 6e 67 20 65 6e 74 72  an existing entr
8640: 79 2e 20 2a 2f 0a 20 20 70 50 61 67 65 20 3d 20  y. */.  pPage = 
8650: 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 69  pCache->apHash[i
8660: 4b 65 79 20 25 20 70 43 61 63 68 65 2d 3e 6e 48  Key % pCache->nH
8670: 61 73 68 5d 3b 0a 20 20 77 68 69 6c 65 28 20 70  ash];.  while( p
8680: 50 61 67 65 20 26 26 20 70 50 61 67 65 2d 3e 69  Page && pPage->i
8690: 4b 65 79 21 3d 69 4b 65 79 20 29 7b 20 70 50 61  Key!=iKey ){ pPa
86a0: 67 65 20 3d 20 70 50 61 67 65 2d 3e 70 4e 65 78  ge = pPage->pNex
86b0: 74 3b 20 7d 0a 0a 20 20 2f 2a 20 53 74 65 70 20  t; }..  /* Step 
86c0: 32 3a 20 49 66 20 74 68 65 20 70 61 67 65 20 77  2: If the page w
86d0: 61 73 20 66 6f 75 6e 64 20 69 6e 20 74 68 65 20  as found in the 
86e0: 68 61 73 68 20 74 61 62 6c 65 2c 20 74 68 65 6e  hash table, then
86f0: 20 72 65 74 75 72 6e 20 69 74 2e 0a 20 20 2a 2a   return it..  **
8700: 20 49 66 20 74 68 65 20 70 61 67 65 20 77 61 73   If the page was
8710: 20 6e 6f 74 20 69 6e 20 74 68 65 20 68 61 73 68   not in the hash
8720: 20 74 61 62 6c 65 20 61 6e 64 20 63 72 65 61 74   table and creat
8730: 65 46 6c 61 67 20 69 73 20 30 2c 20 61 62 6f 72  eFlag is 0, abor
8740: 74 2e 0a 20 20 2a 2a 20 4f 74 68 65 72 77 69 73  t..  ** Otherwis
8750: 65 20 28 70 61 67 65 20 6e 6f 74 20 69 6e 20 68  e (page not in h
8760: 61 73 68 20 61 6e 64 20 63 72 65 61 74 65 46 6c  ash and createFl
8770: 61 67 21 3d 30 29 20 63 6f 6e 74 69 6e 75 65 20  ag!=0) continue 
8780: 77 69 74 68 0a 20 20 2a 2a 20 73 75 62 73 65 71  with.  ** subseq
8790: 75 65 6e 74 20 73 74 65 70 73 20 74 6f 20 74 72  uent steps to tr
87a0: 79 20 74 6f 20 63 72 65 61 74 65 20 74 68 65 20  y to create the 
87b0: 70 61 67 65 2e 20 2a 2f 0a 20 20 69 66 28 20 70  page. */.  if( p
87c0: 50 61 67 65 20 29 7b 0a 20 20 20 20 69 66 28 20  Page ){.    if( 
87d0: 50 41 47 45 5f 49 53 5f 55 4e 50 49 4e 4e 45 44  PAGE_IS_UNPINNED
87e0: 28 70 50 61 67 65 29 20 29 7b 0a 20 20 20 20 20  (pPage) ){.     
87f0: 20 72 65 74 75 72 6e 20 70 63 61 63 68 65 31 50   return pcache1P
8800: 69 6e 50 61 67 65 28 70 50 61 67 65 29 3b 0a 20  inPage(pPage);. 
8810: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
8820: 72 65 74 75 72 6e 20 70 50 61 67 65 3b 0a 20 20  return pPage;.  
8830: 20 20 7d 0a 20 20 7d 65 6c 73 65 20 69 66 28 20    }.  }else if( 
8840: 63 72 65 61 74 65 46 6c 61 67 20 29 7b 0a 20 20  createFlag ){.  
8850: 20 20 2f 2a 20 53 74 65 70 73 20 33 2c 20 34 2c    /* Steps 3, 4,
8860: 20 61 6e 64 20 35 20 69 6d 70 6c 65 6d 65 6e 74   and 5 implement
8870: 65 64 20 62 79 20 74 68 69 73 20 73 75 62 72 6f  ed by this subro
8880: 75 74 69 6e 65 20 2a 2f 0a 20 20 20 20 72 65 74  utine */.    ret
8890: 75 72 6e 20 70 63 61 63 68 65 31 46 65 74 63 68  urn pcache1Fetch
88a0: 53 74 61 67 65 32 28 70 43 61 63 68 65 2c 20 69  Stage2(pCache, i
88b0: 4b 65 79 2c 20 63 72 65 61 74 65 46 6c 61 67 29  Key, createFlag)
88c0: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 72  ;.  }else{.    r
88d0: 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 7d 0a 23  eturn 0;.  }.}.#
88e0: 69 66 20 50 43 41 43 48 45 31 5f 4d 49 47 48 54  if PCACHE1_MIGHT
88f0: 5f 55 53 45 5f 47 52 4f 55 50 5f 4d 55 54 45 58  _USE_GROUP_MUTEX
8900: 0a 73 74 61 74 69 63 20 50 67 48 64 72 31 20 2a  .static PgHdr1 *
8910: 70 63 61 63 68 65 31 46 65 74 63 68 57 69 74 68  pcache1FetchWith
8920: 4d 75 74 65 78 28 0a 20 20 73 71 6c 69 74 65 33  Mutex(.  sqlite3
8930: 5f 70 63 61 63 68 65 20 2a 70 2c 20 0a 20 20 75  _pcache *p, .  u
8940: 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4b 65 79  nsigned int iKey
8950: 2c 20 0a 20 20 69 6e 74 20 63 72 65 61 74 65 46  , .  int createF
8960: 6c 61 67 0a 29 7b 0a 20 20 50 43 61 63 68 65 31  lag.){.  PCache1
8970: 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61 63   *pCache = (PCac
8980: 68 65 31 20 2a 29 70 3b 0a 20 20 50 67 48 64 72  he1 *)p;.  PgHdr
8990: 31 20 2a 70 50 61 67 65 3b 0a 0a 20 20 70 63 61  1 *pPage;..  pca
89a0: 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70  che1EnterMutex(p
89b0: 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a  Cache->pGroup);.
89c0: 20 20 70 50 61 67 65 20 3d 20 70 63 61 63 68 65    pPage = pcache
89d0: 31 46 65 74 63 68 4e 6f 4d 75 74 65 78 28 70 2c  1FetchNoMutex(p,
89e0: 20 69 4b 65 79 2c 20 63 72 65 61 74 65 46 6c 61   iKey, createFla
89f0: 67 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 50  g);.  assert( pP
8a00: 61 67 65 3d 3d 30 20 7c 7c 20 70 43 61 63 68 65  age==0 || pCache
8a10: 2d 3e 69 4d 61 78 4b 65 79 3e 3d 69 4b 65 79 20  ->iMaxKey>=iKey 
8a20: 29 3b 0a 20 20 70 63 61 63 68 65 31 4c 65 61 76  );.  pcache1Leav
8a30: 65 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e 70  eMutex(pCache->p
8a40: 47 72 6f 75 70 29 3b 0a 20 20 72 65 74 75 72 6e  Group);.  return
8a50: 20 70 50 61 67 65 3b 0a 7d 0a 23 65 6e 64 69 66   pPage;.}.#endif
8a60: 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65 33 5f  .static sqlite3_
8a70: 70 63 61 63 68 65 5f 70 61 67 65 20 2a 70 63 61  pcache_page *pca
8a80: 63 68 65 31 46 65 74 63 68 28 0a 20 20 73 71 6c  che1Fetch(.  sql
8a90: 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70 2c 20  ite3_pcache *p, 
8aa0: 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  .  unsigned int 
8ab0: 69 4b 65 79 2c 20 0a 20 20 69 6e 74 20 63 72 65  iKey, .  int cre
8ac0: 61 74 65 46 6c 61 67 0a 29 7b 0a 23 69 66 20 50  ateFlag.){.#if P
8ad0: 43 41 43 48 45 31 5f 4d 49 47 48 54 5f 55 53 45  CACHE1_MIGHT_USE
8ae0: 5f 47 52 4f 55 50 5f 4d 55 54 45 58 20 7c 7c 20  _GROUP_MUTEX || 
8af0: 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 44  defined(SQLITE_D
8b00: 45 42 55 47 29 0a 20 20 50 43 61 63 68 65 31 20  EBUG).  PCache1 
8b10: 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61 63 68  *pCache = (PCach
8b20: 65 31 20 2a 29 70 3b 0a 23 65 6e 64 69 66 0a 0a  e1 *)p;.#endif..
8b30: 20 20 61 73 73 65 72 74 28 20 6f 66 66 73 65 74    assert( offset
8b40: 6f 66 28 50 67 48 64 72 31 2c 70 61 67 65 29 3d  of(PgHdr1,page)=
8b50: 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  =0 );.  assert( 
8b60: 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62  pCache->bPurgeab
8b70: 6c 65 20 7c 7c 20 63 72 65 61 74 65 46 6c 61 67  le || createFlag
8b80: 21 3d 31 20 29 3b 0a 20 20 61 73 73 65 72 74 28  !=1 );.  assert(
8b90: 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61   pCache->bPurgea
8ba0: 62 6c 65 20 7c 7c 20 70 43 61 63 68 65 2d 3e 6e  ble || pCache->n
8bb0: 4d 69 6e 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65  Min==0 );.  asse
8bc0: 72 74 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72  rt( pCache->bPur
8bd0: 67 65 61 62 6c 65 3d 3d 30 20 7c 7c 20 70 43 61  geable==0 || pCa
8be0: 63 68 65 2d 3e 6e 4d 69 6e 3d 3d 31 30 20 29 3b  che->nMin==10 );
8bf0: 0a 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68  .  assert( pCach
8c00: 65 2d 3e 6e 4d 69 6e 3d 3d 30 20 7c 7c 20 70 43  e->nMin==0 || pC
8c10: 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65  ache->bPurgeable
8c20: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 43   );.  assert( pC
8c30: 61 63 68 65 2d 3e 6e 48 61 73 68 3e 30 20 29 3b  ache->nHash>0 );
8c40: 0a 23 69 66 20 50 43 41 43 48 45 31 5f 4d 49 47  .#if PCACHE1_MIG
8c50: 48 54 5f 55 53 45 5f 47 52 4f 55 50 5f 4d 55 54  HT_USE_GROUP_MUT
8c60: 45 58 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d  EX.  if( pCache-
8c70: 3e 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78 20 29  >pGroup->mutex )
8c80: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 28 73 71  {.    return (sq
8c90: 6c 69 74 65 33 5f 70 63 61 63 68 65 5f 70 61 67  lite3_pcache_pag
8ca0: 65 2a 29 70 63 61 63 68 65 31 46 65 74 63 68 57  e*)pcache1FetchW
8cb0: 69 74 68 4d 75 74 65 78 28 70 2c 20 69 4b 65 79  ithMutex(p, iKey
8cc0: 2c 20 63 72 65 61 74 65 46 6c 61 67 29 3b 0a 20  , createFlag);. 
8cd0: 20 7d 65 6c 73 65 0a 23 65 6e 64 69 66 0a 20 20   }else.#endif.  
8ce0: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 28 73 71  {.    return (sq
8cf0: 6c 69 74 65 33 5f 70 63 61 63 68 65 5f 70 61 67  lite3_pcache_pag
8d00: 65 2a 29 70 63 61 63 68 65 31 46 65 74 63 68 4e  e*)pcache1FetchN
8d10: 6f 4d 75 74 65 78 28 70 2c 20 69 4b 65 79 2c 20  oMutex(p, iKey, 
8d20: 63 72 65 61 74 65 46 6c 61 67 29 3b 0a 20 20 7d  createFlag);.  }
8d30: 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65  .}.../*.** Imple
8d40: 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65  mentation of the
8d50: 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e   sqlite3_pcache.
8d60: 78 55 6e 70 69 6e 20 6d 65 74 68 6f 64 2e 0a 2a  xUnpin method..*
8d70: 2a 0a 2a 2a 20 4d 61 72 6b 20 61 20 70 61 67 65  *.** Mark a page
8d80: 20 61 73 20 75 6e 70 69 6e 6e 65 64 20 28 65 6c   as unpinned (el
8d90: 69 67 69 62 6c 65 20 66 6f 72 20 61 73 79 6e 63  igible for async
8da0: 68 72 6f 6e 6f 75 73 20 72 65 63 79 63 6c 69 6e  hronous recyclin
8db0: 67 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  g)..*/.static vo
8dc0: 69 64 20 70 63 61 63 68 65 31 55 6e 70 69 6e 28  id pcache1Unpin(
8dd0: 0a 20 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68  .  sqlite3_pcach
8de0: 65 20 2a 70 2c 20 0a 20 20 73 71 6c 69 74 65 33  e *p, .  sqlite3
8df0: 5f 70 63 61 63 68 65 5f 70 61 67 65 20 2a 70 50  _pcache_page *pP
8e00: 67 2c 20 0a 20 20 69 6e 74 20 72 65 75 73 65 55  g, .  int reuseU
8e10: 6e 6c 69 6b 65 6c 79 0a 29 7b 0a 20 20 50 43 61  nlikely.){.  PCa
8e20: 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28  che1 *pCache = (
8e30: 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20 20 50  PCache1 *)p;.  P
8e40: 67 48 64 72 31 20 2a 70 50 61 67 65 20 3d 20 28  gHdr1 *pPage = (
8e50: 50 67 48 64 72 31 20 2a 29 70 50 67 3b 0a 20 20  PgHdr1 *)pPg;.  
8e60: 50 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 20 3d  PGroup *pGroup =
8e70: 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b   pCache->pGroup;
8e80: 0a 20 0a 20 20 61 73 73 65 72 74 28 20 70 50 61  . .  assert( pPa
8e90: 67 65 2d 3e 70 43 61 63 68 65 3d 3d 70 43 61 63  ge->pCache==pCac
8ea0: 68 65 20 29 3b 0a 20 20 70 63 61 63 68 65 31 45  he );.  pcache1E
8eb0: 6e 74 65 72 4d 75 74 65 78 28 70 47 72 6f 75 70  nterMutex(pGroup
8ec0: 29 3b 0a 0a 20 20 2f 2a 20 49 74 20 69 73 20 61  );..  /* It is a
8ed0: 6e 20 65 72 72 6f 72 20 74 6f 20 63 61 6c 6c 20  n error to call 
8ee0: 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 66  this function if
8ef0: 20 74 68 65 20 70 61 67 65 20 69 73 20 61 6c 72   the page is alr
8f00: 65 61 64 79 20 0a 20 20 2a 2a 20 70 61 72 74 20  eady .  ** part 
8f10: 6f 66 20 74 68 65 20 50 47 72 6f 75 70 20 4c 52  of the PGroup LR
8f20: 55 20 6c 69 73 74 2e 0a 20 20 2a 2f 0a 20 20 61  U list..  */.  a
8f30: 73 73 65 72 74 28 20 70 50 61 67 65 2d 3e 70 4c  ssert( pPage->pL
8f40: 72 75 50 72 65 76 3d 3d 30 20 26 26 20 70 50 61  ruPrev==0 && pPa
8f50: 67 65 2d 3e 70 4c 72 75 4e 65 78 74 3d 3d 30 20  ge->pLruNext==0 
8f60: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 50 41 47  );.  assert( PAG
8f70: 45 5f 49 53 5f 50 49 4e 4e 45 44 28 70 50 61 67  E_IS_PINNED(pPag
8f80: 65 29 20 29 3b 0a 0a 20 20 69 66 28 20 72 65 75  e) );..  if( reu
8f90: 73 65 55 6e 6c 69 6b 65 6c 79 20 7c 7c 20 70 47  seUnlikely || pG
8fa0: 72 6f 75 70 2d 3e 6e 50 75 72 67 65 61 62 6c 65  roup->nPurgeable
8fb0: 3e 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67  >pGroup->nMaxPag
8fc0: 65 20 29 7b 0a 20 20 20 20 70 63 61 63 68 65 31  e ){.    pcache1
8fd0: 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73 68 28 70  RemoveFromHash(p
8fe0: 50 61 67 65 2c 20 31 29 3b 0a 20 20 7d 65 6c 73  Page, 1);.  }els
8ff0: 65 7b 0a 20 20 20 20 2f 2a 20 41 64 64 20 74 68  e{.    /* Add th
9000: 65 20 70 61 67 65 20 74 6f 20 74 68 65 20 50 47  e page to the PG
9010: 72 6f 75 70 20 4c 52 55 20 6c 69 73 74 2e 20 2a  roup LRU list. *
9020: 2f 0a 20 20 20 20 50 67 48 64 72 31 20 2a 2a 70  /.    PgHdr1 **p
9030: 70 46 69 72 73 74 20 3d 20 26 70 47 72 6f 75 70  pFirst = &pGroup
9040: 2d 3e 6c 72 75 2e 70 4c 72 75 4e 65 78 74 3b 0a  ->lru.pLruNext;.
9050: 20 20 20 20 70 50 61 67 65 2d 3e 70 4c 72 75 50      pPage->pLruP
9060: 72 65 76 20 3d 20 26 70 47 72 6f 75 70 2d 3e 6c  rev = &pGroup->l
9070: 72 75 3b 0a 20 20 20 20 28 70 50 61 67 65 2d 3e  ru;.    (pPage->
9080: 70 4c 72 75 4e 65 78 74 20 3d 20 2a 70 70 46 69  pLruNext = *ppFi
9090: 72 73 74 29 2d 3e 70 4c 72 75 50 72 65 76 20 3d  rst)->pLruPrev =
90a0: 20 70 50 61 67 65 3b 0a 20 20 20 20 2a 70 70 46   pPage;.    *ppF
90b0: 69 72 73 74 20 3d 20 70 50 61 67 65 3b 0a 20 20  irst = pPage;.  
90c0: 20 20 70 43 61 63 68 65 2d 3e 6e 52 65 63 79 63    pCache->nRecyc
90d0: 6c 61 62 6c 65 2b 2b 3b 0a 20 20 7d 0a 0a 20 20  lable++;.  }..  
90e0: 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65  pcache1LeaveMute
90f0: 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70  x(pCache->pGroup
9100: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c  );.}../*.** Impl
9110: 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68  ementation of th
9120: 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  e sqlite3_pcache
9130: 2e 78 52 65 6b 65 79 20 6d 65 74 68 6f 64 2e 20  .xRekey method. 
9140: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
9150: 70 63 61 63 68 65 31 52 65 6b 65 79 28 0a 20 20  pcache1Rekey(.  
9160: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a  sqlite3_pcache *
9170: 70 2c 0a 20 20 73 71 6c 69 74 65 33 5f 70 63 61  p,.  sqlite3_pca
9180: 63 68 65 5f 70 61 67 65 20 2a 70 50 67 2c 0a 20  che_page *pPg,. 
9190: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4f   unsigned int iO
91a0: 6c 64 2c 0a 20 20 75 6e 73 69 67 6e 65 64 20 69  ld,.  unsigned i
91b0: 6e 74 20 69 4e 65 77 0a 29 7b 0a 20 20 50 43 61  nt iNew.){.  PCa
91c0: 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28  che1 *pCache = (
91d0: 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20 20 50  PCache1 *)p;.  P
91e0: 67 48 64 72 31 20 2a 70 50 61 67 65 20 3d 20 28  gHdr1 *pPage = (
91f0: 50 67 48 64 72 31 20 2a 29 70 50 67 3b 0a 20 20  PgHdr1 *)pPg;.  
9200: 50 67 48 64 72 31 20 2a 2a 70 70 3b 0a 20 20 75  PgHdr1 **pp;.  u
9210: 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 3b 20 0a  nsigned int h; .
9220: 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65 2d    assert( pPage-
9230: 3e 69 4b 65 79 3d 3d 69 4f 6c 64 20 29 3b 0a 20  >iKey==iOld );. 
9240: 20 61 73 73 65 72 74 28 20 70 50 61 67 65 2d 3e   assert( pPage->
9250: 70 43 61 63 68 65 3d 3d 70 43 61 63 68 65 20 29  pCache==pCache )
9260: 3b 0a 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65  ;..  pcache1Ente
9270: 72 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e 70  rMutex(pCache->p
9280: 47 72 6f 75 70 29 3b 0a 0a 20 20 68 20 3d 20 69  Group);..  h = i
9290: 4f 6c 64 25 70 43 61 63 68 65 2d 3e 6e 48 61 73  Old%pCache->nHas
92a0: 68 3b 0a 20 20 70 70 20 3d 20 26 70 43 61 63 68  h;.  pp = &pCach
92b0: 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 0a 20 20  e->apHash[h];.  
92c0: 77 68 69 6c 65 28 20 28 2a 70 70 29 21 3d 70 50  while( (*pp)!=pP
92d0: 61 67 65 20 29 7b 0a 20 20 20 20 70 70 20 3d 20  age ){.    pp = 
92e0: 26 28 2a 70 70 29 2d 3e 70 4e 65 78 74 3b 0a 20  &(*pp)->pNext;. 
92f0: 20 7d 0a 20 20 2a 70 70 20 3d 20 70 50 61 67 65   }.  *pp = pPage
9300: 2d 3e 70 4e 65 78 74 3b 0a 0a 20 20 68 20 3d 20  ->pNext;..  h = 
9310: 69 4e 65 77 25 70 43 61 63 68 65 2d 3e 6e 48 61  iNew%pCache->nHa
9320: 73 68 3b 0a 20 20 70 50 61 67 65 2d 3e 69 4b 65  sh;.  pPage->iKe
9330: 79 20 3d 20 69 4e 65 77 3b 0a 20 20 70 50 61 67  y = iNew;.  pPag
9340: 65 2d 3e 70 4e 65 78 74 20 3d 20 70 43 61 63 68  e->pNext = pCach
9350: 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 0a 20 20  e->apHash[h];.  
9360: 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68  pCache->apHash[h
9370: 5d 20 3d 20 70 50 61 67 65 3b 0a 20 20 69 66 28  ] = pPage;.  if(
9380: 20 69 4e 65 77 3e 70 43 61 63 68 65 2d 3e 69 4d   iNew>pCache->iM
9390: 61 78 4b 65 79 20 29 7b 0a 20 20 20 20 70 43 61  axKey ){.    pCa
93a0: 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 3d 20 69  che->iMaxKey = i
93b0: 4e 65 77 3b 0a 20 20 7d 0a 0a 20 20 70 63 61 63  New;.  }..  pcac
93c0: 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 70 43  he1LeaveMutex(pC
93d0: 61 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 7d  ache->pGroup);.}
93e0: 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e  ../*.** Implemen
93f0: 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71  tation of the sq
9400: 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78 54 72  lite3_pcache.xTr
9410: 75 6e 63 61 74 65 20 6d 65 74 68 6f 64 2e 20 0a  uncate method. .
9420: 2a 2a 0a 2a 2a 20 44 69 73 63 61 72 64 20 61 6c  **.** Discard al
9430: 6c 20 75 6e 70 69 6e 6e 65 64 20 70 61 67 65 73  l unpinned pages
9440: 20 69 6e 20 74 68 65 20 63 61 63 68 65 20 77 69   in the cache wi
9450: 74 68 20 61 20 70 61 67 65 20 6e 75 6d 62 65 72  th a page number
9460: 20 65 71 75 61 6c 20 74 6f 0a 2a 2a 20 6f 72 20   equal to.** or 
9470: 67 72 65 61 74 65 72 20 74 68 61 6e 20 70 61 72  greater than par
9480: 61 6d 65 74 65 72 20 69 4c 69 6d 69 74 2e 20 41  ameter iLimit. A
9490: 6e 79 20 70 69 6e 6e 65 64 20 70 61 67 65 73 20  ny pinned pages 
94a0: 77 69 74 68 20 61 20 70 61 67 65 20 6e 75 6d 62  with a page numb
94b0: 65 72 0a 2a 2a 20 65 71 75 61 6c 20 74 6f 20 6f  er.** equal to o
94c0: 72 20 67 72 65 61 74 65 72 20 74 68 61 6e 20 69  r greater than i
94d0: 4c 69 6d 69 74 20 61 72 65 20 69 6d 70 6c 69 63  Limit are implic
94e0: 69 74 6c 79 20 75 6e 70 69 6e 6e 65 64 2e 0a 2a  itly unpinned..*
94f0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63  /.static void pc
9500: 61 63 68 65 31 54 72 75 6e 63 61 74 65 28 73 71  ache1Truncate(sq
9510: 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70 2c  lite3_pcache *p,
9520: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4c   unsigned int iL
9530: 69 6d 69 74 29 7b 0a 20 20 50 43 61 63 68 65 31  imit){.  PCache1
9540: 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61 63   *pCache = (PCac
9550: 68 65 31 20 2a 29 70 3b 0a 20 20 70 63 61 63 68  he1 *)p;.  pcach
9560: 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70 43 61  e1EnterMutex(pCa
9570: 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 20 20  che->pGroup);.  
9580: 69 66 28 20 69 4c 69 6d 69 74 3c 3d 70 43 61 63  if( iLimit<=pCac
9590: 68 65 2d 3e 69 4d 61 78 4b 65 79 20 29 7b 0a 20  he->iMaxKey ){. 
95a0: 20 20 20 70 63 61 63 68 65 31 54 72 75 6e 63 61     pcache1Trunca
95b0: 74 65 55 6e 73 61 66 65 28 70 43 61 63 68 65 2c  teUnsafe(pCache,
95c0: 20 69 4c 69 6d 69 74 29 3b 0a 20 20 20 20 70 43   iLimit);.    pC
95d0: 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 3d 20  ache->iMaxKey = 
95e0: 69 4c 69 6d 69 74 2d 31 3b 0a 20 20 7d 0a 20 20  iLimit-1;.  }.  
95f0: 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65  pcache1LeaveMute
9600: 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70  x(pCache->pGroup
9610: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c  );.}../*.** Impl
9620: 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68  ementation of th
9630: 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  e sqlite3_pcache
9640: 2e 78 44 65 73 74 72 6f 79 20 6d 65 74 68 6f 64  .xDestroy method
9650: 2e 20 0a 2a 2a 0a 2a 2a 20 44 65 73 74 72 6f 79  . .**.** Destroy
9660: 20 61 20 63 61 63 68 65 20 61 6c 6c 6f 63 61 74   a cache allocat
9670: 65 64 20 75 73 69 6e 67 20 70 63 61 63 68 65 31  ed using pcache1
9680: 43 72 65 61 74 65 28 29 2e 0a 2a 2f 0a 73 74 61  Create()..*/.sta
9690: 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 31  tic void pcache1
96a0: 44 65 73 74 72 6f 79 28 73 71 6c 69 74 65 33 5f  Destroy(sqlite3_
96b0: 70 63 61 63 68 65 20 2a 70 29 7b 0a 20 20 50 43  pcache *p){.  PC
96c0: 61 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20  ache1 *pCache = 
96d0: 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20 20  (PCache1 *)p;.  
96e0: 50 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 20 3d  PGroup *pGroup =
96f0: 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b   pCache->pGroup;
9700: 0a 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68  .  assert( pCach
9710: 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 7c 7c  e->bPurgeable ||
9720: 20 28 70 43 61 63 68 65 2d 3e 6e 4d 61 78 3d 3d   (pCache->nMax==
9730: 30 20 26 26 20 70 43 61 63 68 65 2d 3e 6e 4d 69  0 && pCache->nMi
9740: 6e 3d 3d 30 29 20 29 3b 0a 20 20 70 63 61 63 68  n==0) );.  pcach
9750: 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70 47 72  e1EnterMutex(pGr
9760: 6f 75 70 29 3b 0a 20 20 69 66 28 20 70 43 61 63  oup);.  if( pCac
9770: 68 65 2d 3e 6e 50 61 67 65 20 29 20 70 63 61 63  he->nPage ) pcac
9780: 68 65 31 54 72 75 6e 63 61 74 65 55 6e 73 61 66  he1TruncateUnsaf
9790: 65 28 70 43 61 63 68 65 2c 20 30 29 3b 0a 20 20  e(pCache, 0);.  
97a0: 61 73 73 65 72 74 28 20 70 47 72 6f 75 70 2d 3e  assert( pGroup->
97b0: 6e 4d 61 78 50 61 67 65 20 3e 3d 20 70 43 61 63  nMaxPage >= pCac
97c0: 68 65 2d 3e 6e 4d 61 78 20 29 3b 0a 20 20 70 47  he->nMax );.  pG
97d0: 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65 20 2d  roup->nMaxPage -
97e0: 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 3b 0a  = pCache->nMax;.
97f0: 20 20 61 73 73 65 72 74 28 20 70 47 72 6f 75 70    assert( pGroup
9800: 2d 3e 6e 4d 69 6e 50 61 67 65 20 3e 3d 20 70 43  ->nMinPage >= pC
9810: 61 63 68 65 2d 3e 6e 4d 69 6e 20 29 3b 0a 20 20  ache->nMin );.  
9820: 70 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67 65  pGroup->nMinPage
9830: 20 2d 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 69 6e   -= pCache->nMin
9840: 3b 0a 20 20 70 47 72 6f 75 70 2d 3e 6d 78 50 69  ;.  pGroup->mxPi
9850: 6e 6e 65 64 20 3d 20 70 47 72 6f 75 70 2d 3e 6e  nned = pGroup->n
9860: 4d 61 78 50 61 67 65 20 2b 20 31 30 20 2d 20 70  MaxPage + 10 - p
9870: 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67 65 3b  Group->nMinPage;
9880: 0a 20 20 70 63 61 63 68 65 31 45 6e 66 6f 72 63  .  pcache1Enforc
9890: 65 4d 61 78 50 61 67 65 28 70 43 61 63 68 65 29  eMaxPage(pCache)
98a0: 3b 0a 20 20 70 63 61 63 68 65 31 4c 65 61 76 65  ;.  pcache1Leave
98b0: 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b 0a 20  Mutex(pGroup);. 
98c0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43   sqlite3_free(pC
98d0: 61 63 68 65 2d 3e 70 42 75 6c 6b 29 3b 0a 20 20  ache->pBulk);.  
98e0: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43 61  sqlite3_free(pCa
98f0: 63 68 65 2d 3e 61 70 48 61 73 68 29 3b 0a 20 20  che->apHash);.  
9900: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43 61  sqlite3_free(pCa
9910: 63 68 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  che);.}../*.** T
9920: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
9930: 63 61 6c 6c 65 64 20 64 75 72 69 6e 67 20 69 6e  called during in
9940: 69 74 69 61 6c 69 7a 61 74 69 6f 6e 20 28 73 71  itialization (sq
9950: 6c 69 74 65 33 5f 69 6e 69 74 69 61 6c 69 7a 65  lite3_initialize
9960: 28 29 29 20 74 6f 0a 2a 2a 20 69 6e 73 74 61 6c  ()) to.** instal
9970: 6c 20 74 68 65 20 64 65 66 61 75 6c 74 20 70 6c  l the default pl
9980: 75 67 67 61 62 6c 65 20 63 61 63 68 65 20 6d 6f  uggable cache mo
9990: 64 75 6c 65 2c 20 61 73 73 75 6d 69 6e 67 20 74  dule, assuming t
99a0: 68 65 20 75 73 65 72 20 68 61 73 20 6e 6f 74 0a  he user has not.
99b0: 2a 2a 20 61 6c 72 65 61 64 79 20 70 72 6f 76 69  ** already provi
99c0: 64 65 64 20 61 6e 20 61 6c 74 65 72 6e 61 74 69  ded an alternati
99d0: 76 65 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69  ve..*/.void sqli
99e0: 74 65 33 50 43 61 63 68 65 53 65 74 44 65 66 61  te3PCacheSetDefa
99f0: 75 6c 74 28 76 6f 69 64 29 7b 0a 20 20 73 74 61  ult(void){.  sta
9a00: 74 69 63 20 63 6f 6e 73 74 20 73 71 6c 69 74 65  tic const sqlite
9a10: 33 5f 70 63 61 63 68 65 5f 6d 65 74 68 6f 64 73  3_pcache_methods
9a20: 32 20 64 65 66 61 75 6c 74 4d 65 74 68 6f 64 73  2 defaultMethods
9a30: 20 3d 20 7b 0a 20 20 20 20 31 2c 20 20 20 20 20   = {.    1,     
9a40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9a50: 20 20 2f 2a 20 69 56 65 72 73 69 6f 6e 20 2a 2f    /* iVersion */
9a60: 0a 20 20 20 20 30 2c 20 20 20 20 20 20 20 20 20  .    0,         
9a70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
9a80: 20 70 41 72 67 20 2a 2f 0a 20 20 20 20 70 63 61   pArg */.    pca
9a90: 63 68 65 31 49 6e 69 74 2c 20 20 20 20 20 20 20  che1Init,       
9aa0: 20 20 20 20 20 20 2f 2a 20 78 49 6e 69 74 20 2a        /* xInit *
9ab0: 2f 0a 20 20 20 20 70 63 61 63 68 65 31 53 68 75  /.    pcache1Shu
9ac0: 74 64 6f 77 6e 2c 20 20 20 20 20 20 20 20 20 2f  tdown,         /
9ad0: 2a 20 78 53 68 75 74 64 6f 77 6e 20 2a 2f 0a 20  * xShutdown */. 
9ae0: 20 20 20 70 63 61 63 68 65 31 43 72 65 61 74 65     pcache1Create
9af0: 2c 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78  ,           /* x
9b00: 43 72 65 61 74 65 20 2a 2f 0a 20 20 20 20 70 63  Create */.    pc
9b10: 61 63 68 65 31 43 61 63 68 65 73 69 7a 65 2c 20  ache1Cachesize, 
9b20: 20 20 20 20 20 20 20 2f 2a 20 78 43 61 63 68 65         /* xCache
9b30: 73 69 7a 65 20 2a 2f 0a 20 20 20 20 70 63 61 63  size */.    pcac
9b40: 68 65 31 50 61 67 65 63 6f 75 6e 74 2c 20 20 20  he1Pagecount,   
9b50: 20 20 20 20 20 2f 2a 20 78 50 61 67 65 63 6f 75       /* xPagecou
9b60: 6e 74 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65  nt */.    pcache
9b70: 31 46 65 74 63 68 2c 20 20 20 20 20 20 20 20 20  1Fetch,         
9b80: 20 20 20 2f 2a 20 78 46 65 74 63 68 20 2a 2f 0a     /* xFetch */.
9b90: 20 20 20 20 70 63 61 63 68 65 31 55 6e 70 69 6e      pcache1Unpin
9ba0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ,            /* 
9bb0: 78 55 6e 70 69 6e 20 2a 2f 0a 20 20 20 20 70 63  xUnpin */.    pc
9bc0: 61 63 68 65 31 52 65 6b 65 79 2c 20 20 20 20 20  ache1Rekey,     
9bd0: 20 20 20 20 20 20 20 2f 2a 20 78 52 65 6b 65 79         /* xRekey
9be0: 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31 54   */.    pcache1T
9bf0: 72 75 6e 63 61 74 65 2c 20 20 20 20 20 20 20 20  runcate,        
9c00: 20 2f 2a 20 78 54 72 75 6e 63 61 74 65 20 2a 2f   /* xTruncate */
9c10: 0a 20 20 20 20 70 63 61 63 68 65 31 44 65 73 74  .    pcache1Dest
9c20: 72 6f 79 2c 20 20 20 20 20 20 20 20 20 20 2f 2a  roy,          /*
9c30: 20 78 44 65 73 74 72 6f 79 20 2a 2f 0a 20 20 20   xDestroy */.   
9c40: 20 70 63 61 63 68 65 31 53 68 72 69 6e 6b 20 20   pcache1Shrink  
9c50: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 53 68            /* xSh
9c60: 72 69 6e 6b 20 2a 2f 0a 20 20 7d 3b 0a 20 20 73  rink */.  };.  s
9c70: 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67 28 53 51  qlite3_config(SQ
9c80: 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 43 41 43  LITE_CONFIG_PCAC
9c90: 48 45 32 2c 20 26 64 65 66 61 75 6c 74 4d 65 74  HE2, &defaultMet
9ca0: 68 6f 64 73 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  hods);.}../*.** 
9cb0: 52 65 74 75 72 6e 20 74 68 65 20 73 69 7a 65 20  Return the size 
9cc0: 6f 66 20 74 68 65 20 68 65 61 64 65 72 20 6f 6e  of the header on
9cd0: 20 65 61 63 68 20 70 61 67 65 20 6f 66 20 74 68   each page of th
9ce0: 69 73 20 50 43 41 43 48 45 20 69 6d 70 6c 65 6d  is PCACHE implem
9cf0: 65 6e 74 61 74 69 6f 6e 2e 0a 2a 2f 0a 69 6e 74  entation..*/.int
9d00: 20 73 71 6c 69 74 65 33 48 65 61 64 65 72 53 69   sqlite3HeaderSi
9d10: 7a 65 50 63 61 63 68 65 31 28 76 6f 69 64 29 7b  zePcache1(void){
9d20: 20 72 65 74 75 72 6e 20 52 4f 55 4e 44 38 28 73   return ROUND8(s
9d30: 69 7a 65 6f 66 28 50 67 48 64 72 31 29 29 3b 20  izeof(PgHdr1)); 
9d40: 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20  }../*.** Return 
9d50: 74 68 65 20 67 6c 6f 62 61 6c 20 6d 75 74 65 78  the global mutex
9d60: 20 75 73 65 64 20 62 79 20 74 68 69 73 20 50 43   used by this PC
9d70: 41 43 48 45 20 69 6d 70 6c 65 6d 65 6e 74 61 74  ACHE implementat
9d80: 69 6f 6e 2e 20 20 54 68 65 0a 2a 2a 20 73 71 6c  ion.  The.** sql
9d90: 69 74 65 33 5f 73 74 61 74 75 73 28 29 20 72 6f  ite3_status() ro
9da0: 75 74 69 6e 65 20 6e 65 65 64 73 20 61 63 63 65  utine needs acce
9db0: 73 73 20 74 6f 20 74 68 69 73 20 6d 75 74 65 78  ss to this mutex
9dc0: 2e 0a 2a 2f 0a 73 71 6c 69 74 65 33 5f 6d 75 74  ..*/.sqlite3_mut
9dd0: 65 78 20 2a 73 71 6c 69 74 65 33 50 63 61 63 68  ex *sqlite3Pcach
9de0: 65 31 4d 75 74 65 78 28 76 6f 69 64 29 7b 0a 20  e1Mutex(void){. 
9df0: 20 72 65 74 75 72 6e 20 70 63 61 63 68 65 31 2e   return pcache1.
9e00: 6d 75 74 65 78 3b 0a 7d 0a 0a 23 69 66 64 65 66  mutex;.}..#ifdef
9e10: 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d   SQLITE_ENABLE_M
9e20: 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54  EMORY_MANAGEMENT
9e30: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  ./*.** This func
9e40: 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 74  tion is called t
9e50: 6f 20 66 72 65 65 20 73 75 70 65 72 66 6c 75 6f  o free superfluo
9e60: 75 73 20 64 79 6e 61 6d 69 63 61 6c 6c 79 20 61  us dynamically a
9e70: 6c 6c 6f 63 61 74 65 64 20 6d 65 6d 6f 72 79 0a  llocated memory.
9e80: 2a 2a 20 68 65 6c 64 20 62 79 20 74 68 65 20 70  ** held by the p
9e90: 61 67 65 72 20 73 79 73 74 65 6d 2e 20 4d 65 6d  ager system. Mem
9ea0: 6f 72 79 20 69 6e 20 75 73 65 20 62 79 20 61 6e  ory in use by an
9eb0: 79 20 53 51 4c 69 74 65 20 70 61 67 65 72 20 61  y SQLite pager a
9ec0: 6c 6c 6f 63 61 74 65 64 0a 2a 2a 20 62 79 20 74  llocated.** by t
9ed0: 68 65 20 63 75 72 72 65 6e 74 20 74 68 72 65 61  he current threa
9ee0: 64 20 6d 61 79 20 62 65 20 73 71 6c 69 74 65 33  d may be sqlite3
9ef0: 5f 66 72 65 65 28 29 65 64 2e 0a 2a 2a 0a 2a 2a  _free()ed..**.**
9f00: 20 6e 52 65 71 20 69 73 20 74 68 65 20 6e 75 6d   nReq is the num
9f10: 62 65 72 20 6f 66 20 62 79 74 65 73 20 6f 66 20  ber of bytes of 
9f20: 6d 65 6d 6f 72 79 20 72 65 71 75 69 72 65 64 2e  memory required.
9f30: 20 4f 6e 63 65 20 74 68 69 73 20 6d 75 63 68 20   Once this much 
9f40: 68 61 73 0a 2a 2a 20 62 65 65 6e 20 72 65 6c 65  has.** been rele
9f50: 61 73 65 64 2c 20 74 68 65 20 66 75 6e 63 74 69  ased, the functi
9f60: 6f 6e 20 72 65 74 75 72 6e 73 2e 20 54 68 65 20  on returns. The 
9f70: 72 65 74 75 72 6e 20 76 61 6c 75 65 20 69 73 20  return value is 
9f80: 74 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72  the total number
9f90: 20 0a 2a 2a 20 6f 66 20 62 79 74 65 73 20 6f 66   .** of bytes of
9fa0: 20 6d 65 6d 6f 72 79 20 72 65 6c 65 61 73 65 64   memory released
9fb0: 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33  ..*/.int sqlite3
9fc0: 50 63 61 63 68 65 52 65 6c 65 61 73 65 4d 65 6d  PcacheReleaseMem
9fd0: 6f 72 79 28 69 6e 74 20 6e 52 65 71 29 7b 0a 20  ory(int nReq){. 
9fe0: 20 69 6e 74 20 6e 46 72 65 65 20 3d 20 30 3b 0a   int nFree = 0;.
9ff0: 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65    assert( sqlite
a000: 33 5f 6d 75 74 65 78 5f 6e 6f 74 68 65 6c 64 28  3_mutex_notheld(
a010: 70 63 61 63 68 65 31 2e 67 72 70 2e 6d 75 74 65  pcache1.grp.mute
a020: 78 29 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  x) );.  assert( 
a030: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6e 6f  sqlite3_mutex_no
a040: 74 68 65 6c 64 28 70 63 61 63 68 65 31 2e 6d 75  theld(pcache1.mu
a050: 74 65 78 29 20 29 3b 0a 20 20 69 66 28 20 73 71  tex) );.  if( sq
a060: 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69  lite3GlobalConfi
a070: 67 2e 70 50 61 67 65 3d 3d 30 20 29 7b 0a 20 20  g.pPage==0 ){.  
a080: 20 20 50 67 48 64 72 31 20 2a 70 3b 0a 20 20 20    PgHdr1 *p;.   
a090: 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74   pcache1EnterMut
a0a0: 65 78 28 26 70 63 61 63 68 65 31 2e 67 72 70 29  ex(&pcache1.grp)
a0b0: 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 28 6e 52  ;.    while( (nR
a0c0: 65 71 3c 30 20 7c 7c 20 6e 46 72 65 65 3c 6e 52  eq<0 || nFree<nR
a0d0: 65 71 29 0a 20 20 20 20 20 20 20 26 26 20 20 28  eq).       &&  (
a0e0: 70 3d 70 63 61 63 68 65 31 2e 67 72 70 2e 6c 72  p=pcache1.grp.lr
a0f0: 75 2e 70 4c 72 75 50 72 65 76 29 21 3d 30 0a 20  u.pLruPrev)!=0. 
a100: 20 20 20 20 20 20 26 26 20 20 70 2d 3e 69 73 41        &&  p->isA
a110: 6e 63 68 6f 72 3d 3d 30 0a 20 20 20 20 29 7b 0a  nchor==0.    ){.
a120: 20 20 20 20 20 20 6e 46 72 65 65 20 2b 3d 20 70        nFree += p
a130: 63 61 63 68 65 31 4d 65 6d 53 69 7a 65 28 70 2d  cache1MemSize(p-
a140: 3e 70 61 67 65 2e 70 42 75 66 29 3b 0a 23 69 66  >page.pBuf);.#if
a150: 64 65 66 20 53 51 4c 49 54 45 5f 50 43 41 43 48  def SQLITE_PCACH
a160: 45 5f 53 45 50 41 52 41 54 45 5f 48 45 41 44 45  E_SEPARATE_HEADE
a170: 52 0a 20 20 20 20 20 20 6e 46 72 65 65 20 2b 3d  R.      nFree +=
a180: 20 73 71 6c 69 74 65 33 4d 65 6d 53 69 7a 65 28   sqlite3MemSize(
a190: 70 29 3b 0a 23 65 6e 64 69 66 0a 20 20 20 20 20  p);.#endif.     
a1a0: 20 61 73 73 65 72 74 28 20 50 41 47 45 5f 49 53   assert( PAGE_IS
a1b0: 5f 55 4e 50 49 4e 4e 45 44 28 70 29 20 29 3b 0a  _UNPINNED(p) );.
a1c0: 20 20 20 20 20 20 70 63 61 63 68 65 31 50 69 6e        pcache1Pin
a1d0: 50 61 67 65 28 70 29 3b 0a 20 20 20 20 20 20 70  Page(p);.      p
a1e0: 63 61 63 68 65 31 52 65 6d 6f 76 65 46 72 6f 6d  cache1RemoveFrom
a1f0: 48 61 73 68 28 70 2c 20 31 29 3b 0a 20 20 20 20  Hash(p, 1);.    
a200: 7d 0a 20 20 20 20 70 63 61 63 68 65 31 4c 65 61  }.    pcache1Lea
a210: 76 65 4d 75 74 65 78 28 26 70 63 61 63 68 65 31  veMutex(&pcache1
a220: 2e 67 72 70 29 3b 0a 20 20 7d 0a 20 20 72 65 74  .grp);.  }.  ret
a230: 75 72 6e 20 6e 46 72 65 65 3b 0a 7d 0a 23 65 6e  urn nFree;.}.#en
a240: 64 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f 45 4e  dif /* SQLITE_EN
a250: 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41  ABLE_MEMORY_MANA
a260: 47 45 4d 45 4e 54 20 2a 2f 0a 0a 23 69 66 64 65  GEMENT */..#ifde
a270: 66 20 53 51 4c 49 54 45 5f 54 45 53 54 0a 2f 2a  f SQLITE_TEST./*
a280: 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
a290: 6e 20 69 73 20 75 73 65 64 20 62 79 20 74 65 73  n is used by tes
a2a0: 74 20 70 72 6f 63 65 64 75 72 65 73 20 74 6f 20  t procedures to 
a2b0: 69 6e 73 70 65 63 74 20 74 68 65 20 69 6e 74 65  inspect the inte
a2c0: 72 6e 61 6c 20 73 74 61 74 65 0a 2a 2a 20 6f 66  rnal state.** of
a2d0: 20 74 68 65 20 67 6c 6f 62 61 6c 20 63 61 63 68   the global cach
a2e0: 65 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74  e..*/.void sqlit
a2f0: 65 33 50 63 61 63 68 65 53 74 61 74 73 28 0a 20  e3PcacheStats(. 
a300: 20 69 6e 74 20 2a 70 6e 43 75 72 72 65 6e 74 2c   int *pnCurrent,
a310: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 54 6f        /* OUT: To
a320: 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 70 61  tal number of pa
a330: 67 65 73 20 63 61 63 68 65 64 20 2a 2f 0a 20 20  ges cached */.  
a340: 69 6e 74 20 2a 70 6e 4d 61 78 2c 20 20 20 20 20  int *pnMax,     
a350: 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 47 6c 6f       /* OUT: Glo
a360: 62 61 6c 20 6d 61 78 69 6d 75 6d 20 63 61 63 68  bal maximum cach
a370: 65 20 73 69 7a 65 20 2a 2f 0a 20 20 69 6e 74 20  e size */.  int 
a380: 2a 70 6e 4d 69 6e 2c 20 20 20 20 20 20 20 20 20  *pnMin,         
a390: 20 2f 2a 20 4f 55 54 3a 20 53 75 6d 20 6f 66 20   /* OUT: Sum of 
a3a0: 50 43 61 63 68 65 31 2e 6e 4d 69 6e 20 66 6f 72  PCache1.nMin for
a3b0: 20 70 75 72 67 65 61 62 6c 65 20 63 61 63 68 65   purgeable cache
a3c0: 73 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 52 65  s */.  int *pnRe
a3d0: 63 79 63 6c 61 62 6c 65 20 20 20 20 2f 2a 20 4f  cyclable    /* O
a3e0: 55 54 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72  UT: Total number
a3f0: 20 6f 66 20 70 61 67 65 73 20 61 76 61 69 6c 61   of pages availa
a400: 62 6c 65 20 66 6f 72 20 72 65 63 79 63 6c 69 6e  ble for recyclin
a410: 67 20 2a 2f 0a 29 7b 0a 20 20 50 67 48 64 72 31  g */.){.  PgHdr1
a420: 20 2a 70 3b 0a 20 20 69 6e 74 20 6e 52 65 63 79   *p;.  int nRecy
a430: 63 6c 61 62 6c 65 20 3d 20 30 3b 0a 20 20 66 6f  clable = 0;.  fo
a440: 72 28 70 3d 70 63 61 63 68 65 31 2e 67 72 70 2e  r(p=pcache1.grp.
a450: 6c 72 75 2e 70 4c 72 75 4e 65 78 74 3b 20 70 20  lru.pLruNext; p 
a460: 26 26 20 21 70 2d 3e 69 73 41 6e 63 68 6f 72 3b  && !p->isAnchor;
a470: 20 70 3d 70 2d 3e 70 4c 72 75 4e 65 78 74 29 7b   p=p->pLruNext){
a480: 0a 20 20 20 20 61 73 73 65 72 74 28 20 50 41 47  .    assert( PAG
a490: 45 5f 49 53 5f 55 4e 50 49 4e 4e 45 44 28 70 29  E_IS_UNPINNED(p)
a4a0: 20 29 3b 0a 20 20 20 20 6e 52 65 63 79 63 6c 61   );.    nRecycla
a4b0: 62 6c 65 2b 2b 3b 0a 20 20 7d 0a 20 20 2a 70 6e  ble++;.  }.  *pn
a4c0: 43 75 72 72 65 6e 74 20 3d 20 70 63 61 63 68 65  Current = pcache
a4d0: 31 2e 67 72 70 2e 6e 50 75 72 67 65 61 62 6c 65  1.grp.nPurgeable
a4e0: 3b 0a 20 20 2a 70 6e 4d 61 78 20 3d 20 28 69 6e  ;.  *pnMax = (in
a4f0: 74 29 70 63 61 63 68 65 31 2e 67 72 70 2e 6e 4d  t)pcache1.grp.nM
a500: 61 78 50 61 67 65 3b 0a 20 20 2a 70 6e 4d 69 6e  axPage;.  *pnMin
a510: 20 3d 20 28 69 6e 74 29 70 63 61 63 68 65 31 2e   = (int)pcache1.
a520: 67 72 70 2e 6e 4d 69 6e 50 61 67 65 3b 0a 20 20  grp.nMinPage;.  
a530: 2a 70 6e 52 65 63 79 63 6c 61 62 6c 65 20 3d 20  *pnRecyclable = 
a540: 6e 52 65 63 79 63 6c 61 62 6c 65 3b 0a 7d 0a 23  nRecyclable;.}.#
a550: 65 6e 64 69 66 0a                                endif.