/ Hex Artifact Content
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Artifact 526fbd54dfef9744506c03308120bb3ec660b8ea17f8c01798fd386859657c69:


0000: 2f 2a 0a 2a 2a 20 32 30 30 38 20 4e 6f 76 65 6d  /*.** 2008 Novem
0010: 62 65 72 20 30 35 0a 2a 2a 0a 2a 2a 20 54 68 65  ber 05.**.** The
0020: 20 61 75 74 68 6f 72 20 64 69 73 63 6c 61 69 6d   author disclaim
0030: 73 20 63 6f 70 79 72 69 67 68 74 20 74 6f 20 74  s copyright to t
0040: 68 69 73 20 73 6f 75 72 63 65 20 63 6f 64 65 2e  his source code.
0050: 20 20 49 6e 20 70 6c 61 63 65 20 6f 66 0a 2a 2a    In place of.**
0060: 20 61 20 6c 65 67 61 6c 20 6e 6f 74 69 63 65 2c   a legal notice,
0070: 20 68 65 72 65 20 69 73 20 61 20 62 6c 65 73 73   here is a bless
0080: 69 6e 67 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 4d 61  ing:.**.**    Ma
0090: 79 20 79 6f 75 20 64 6f 20 67 6f 6f 64 20 61 6e  y you do good an
00a0: 64 20 6e 6f 74 20 65 76 69 6c 2e 0a 2a 2a 20 20  d not evil..**  
00b0: 20 20 4d 61 79 20 79 6f 75 20 66 69 6e 64 20 66    May you find f
00c0: 6f 72 67 69 76 65 6e 65 73 73 20 66 6f 72 20 79  orgiveness for y
00d0: 6f 75 72 73 65 6c 66 20 61 6e 64 20 66 6f 72 67  ourself and forg
00e0: 69 76 65 20 6f 74 68 65 72 73 2e 0a 2a 2a 20 20  ive others..**  
00f0: 20 20 4d 61 79 20 79 6f 75 20 73 68 61 72 65 20    May you share 
0100: 66 72 65 65 6c 79 2c 20 6e 65 76 65 72 20 74 61  freely, never ta
0110: 6b 69 6e 67 20 6d 6f 72 65 20 74 68 61 6e 20 79  king more than y
0120: 6f 75 20 67 69 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a  ou give..**.****
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 2a 2a 2a 2a 2a 0a 2a 2a 0a 2a 2a 20 54 68 69 73  *****.**.** This
0180: 20 66 69 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 73   file implements
0190: 20 74 68 65 20 64 65 66 61 75 6c 74 20 70 61 67   the default pag
01a0: 65 20 63 61 63 68 65 20 69 6d 70 6c 65 6d 65 6e  e cache implemen
01b0: 74 61 74 69 6f 6e 20 28 74 68 65 0a 2a 2a 20 73  tation (the.** s
01c0: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 69 6e  qlite3_pcache in
01d0: 74 65 72 66 61 63 65 29 2e 20 49 74 20 61 6c 73  terface). It als
01e0: 6f 20 63 6f 6e 74 61 69 6e 73 20 70 61 72 74 20  o contains part 
01f0: 6f 66 20 74 68 65 20 69 6d 70 6c 65 6d 65 6e 74  of the implement
0200: 61 74 69 6f 6e 0a 2a 2a 20 6f 66 20 74 68 65 20  ation.** of the 
0210: 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41  SQLITE_CONFIG_PA
0220: 47 45 43 41 43 48 45 20 61 6e 64 20 73 71 6c 69  GECACHE and sqli
0230: 74 65 33 5f 72 65 6c 65 61 73 65 5f 6d 65 6d 6f  te3_release_memo
0240: 72 79 28 29 20 66 65 61 74 75 72 65 73 2e 0a 2a  ry() features..*
0250: 2a 20 49 66 20 74 68 65 20 64 65 66 61 75 6c 74  * If the default
0260: 20 70 61 67 65 20 63 61 63 68 65 20 69 6d 70 6c   page cache impl
0270: 65 6d 65 6e 74 61 74 69 6f 6e 20 69 73 20 6f 76  ementation is ov
0280: 65 72 72 69 64 64 65 6e 2c 20 74 68 65 6e 20 6e  erridden, then n
0290: 65 69 74 68 65 72 20 6f 66 0a 2a 2a 20 74 68 65  either of.** the
02a0: 73 65 20 74 77 6f 20 66 65 61 74 75 72 65 73 20  se two features 
02b0: 61 72 65 20 61 76 61 69 6c 61 62 6c 65 2e 0a 2a  are available..*
02c0: 2a 0a 2a 2a 20 41 20 50 61 67 65 20 63 61 63 68  *.** A Page cach
02d0: 65 20 6c 69 6e 65 20 6c 6f 6f 6b 73 20 6c 69 6b  e line looks lik
02e0: 65 20 74 68 69 73 3a 0a 2a 2a 0a 2a 2a 20 20 2d  e this:.**.**  -
02f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0300: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0310: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0320: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 2a 2a 20  ------------.** 
0330: 20 7c 20 20 64 61 74 61 62 61 73 65 20 70 61 67   |  database pag
0340: 65 20 63 6f 6e 74 65 6e 74 20 20 20 7c 20 20 50  e content   |  P
0350: 67 48 64 72 31 20 20 7c 20 20 4d 65 6d 50 61 67  gHdr1  |  MemPag
0360: 65 20 20 7c 20 20 50 67 48 64 72 20 20 7c 0a 2a  e  |  PgHdr  |.*
0370: 2a 20 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  *  -------------
0380: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0390: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
03a0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
03b0: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 64 61 74 61 62  .**.** The datab
03c0: 61 73 65 20 70 61 67 65 20 63 6f 6e 74 65 6e 74  ase page content
03d0: 20 69 73 20 75 70 20 66 72 6f 6e 74 20 28 73 6f   is up front (so
03e0: 20 74 68 61 74 20 62 75 66 66 65 72 20 6f 76 65   that buffer ove
03f0: 72 72 65 61 64 73 20 74 65 6e 64 20 74 6f 0a 2a  rreads tend to.*
0400: 2a 20 66 6c 6f 77 20 68 61 72 6d 6c 65 73 73 6c  * flow harmlessl
0410: 79 20 69 6e 74 6f 20 74 68 65 20 50 67 48 64 72  y into the PgHdr
0420: 31 2c 20 4d 65 6d 50 61 67 65 2c 20 61 6e 64 20  1, MemPage, and 
0430: 50 67 48 64 72 20 65 78 74 65 6e 73 69 6f 6e 73  PgHdr extensions
0440: 29 2e 20 20 20 4d 65 6d 50 61 67 65 0a 2a 2a 20  ).   MemPage.** 
0450: 69 73 20 74 68 65 20 65 78 74 65 6e 73 69 6f 6e  is the extension
0460: 20 61 64 64 65 64 20 62 79 20 74 68 65 20 62 74   added by the bt
0470: 72 65 65 2e 63 20 6d 6f 64 75 6c 65 20 63 6f 6e  ree.c module con
0480: 74 61 69 6e 69 6e 67 20 69 6e 66 6f 72 6d 61 74  taining informat
0490: 69 6f 6e 20 73 75 63 68 0a 2a 2a 20 61 73 20 74  ion such.** as t
04a0: 68 65 20 64 61 74 61 62 61 73 65 20 70 61 67 65  he database page
04b0: 20 6e 75 6d 62 65 72 20 61 6e 64 20 68 6f 77 20   number and how 
04c0: 74 68 61 74 20 64 61 74 61 62 61 73 65 20 70 61  that database pa
04d0: 67 65 20 69 73 20 75 73 65 64 2e 20 20 50 67 48  ge is used.  PgH
04e0: 64 72 0a 2a 2a 20 69 73 20 61 64 64 65 64 20 62  dr.** is added b
04f0: 79 20 74 68 65 20 70 63 61 63 68 65 2e 63 20 6c  y the pcache.c l
0500: 61 79 65 72 20 61 6e 64 20 63 6f 6e 74 61 69 6e  ayer and contain
0510: 73 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 75 73  s information us
0520: 65 64 20 74 6f 20 6b 65 65 70 20 74 72 61 63 6b  ed to keep track
0530: 0a 2a 2a 20 6f 66 20 77 68 69 63 68 20 70 61 67  .** of which pag
0540: 65 73 20 61 72 65 20 22 64 69 72 74 79 22 2e 20  es are "dirty". 
0550: 20 50 67 48 64 72 31 20 69 73 20 61 6e 20 65 78   PgHdr1 is an ex
0560: 74 65 6e 73 69 6f 6e 20 61 64 64 65 64 20 62 79  tension added by
0570: 20 74 68 69 73 0a 2a 2a 20 6d 6f 64 75 6c 65 20   this.** module 
0580: 28 70 63 61 63 68 65 31 2e 63 29 2e 20 20 54 68  (pcache1.c).  Th
0590: 65 20 50 67 48 64 72 31 20 68 65 61 64 65 72 20  e PgHdr1 header 
05a0: 69 73 20 61 20 73 75 62 63 6c 61 73 73 20 6f 66  is a subclass of
05b0: 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 5f   sqlite3_pcache_
05c0: 70 61 67 65 2e 0a 2a 2a 20 50 67 48 64 72 31 20  page..** PgHdr1 
05d0: 63 6f 6e 74 61 69 6e 73 20 69 6e 66 6f 72 6d 61  contains informa
05e0: 74 69 6f 6e 20 6e 65 65 64 65 64 20 74 6f 20 6c  tion needed to l
05f0: 6f 6f 6b 20 75 70 20 61 20 70 61 67 65 20 62 79  ook up a page by
0600: 20 69 74 73 20 70 61 67 65 20 6e 75 6d 62 65 72   its page number
0610: 2e 0a 2a 2a 20 54 68 65 20 73 75 70 65 72 63 6c  ..** The supercl
0620: 61 73 73 20 73 71 6c 69 74 65 33 5f 70 63 61 63  ass sqlite3_pcac
0630: 68 65 5f 70 61 67 65 2e 70 42 75 66 20 70 6f 69  he_page.pBuf poi
0640: 6e 74 73 20 74 6f 20 74 68 65 20 73 74 61 72 74  nts to the start
0650: 20 6f 66 20 74 68 65 0a 2a 2a 20 64 61 74 61 62   of the.** datab
0660: 61 73 65 20 70 61 67 65 20 63 6f 6e 74 65 6e 74  ase page content
0670: 20 61 6e 64 20 73 71 6c 69 74 65 33 5f 70 63 61   and sqlite3_pca
0680: 63 68 65 5f 70 61 67 65 2e 70 45 78 74 72 61 20  che_page.pExtra 
0690: 70 6f 69 6e 74 73 20 74 6f 20 50 67 48 64 72 2e  points to PgHdr.
06a0: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 73 69 7a 65 20  .**.** The size 
06b0: 6f 66 20 74 68 65 20 65 78 74 65 6e 73 69 6f 6e  of the extension
06c0: 20 28 4d 65 6d 50 61 67 65 2b 50 67 48 64 72 2b   (MemPage+PgHdr+
06d0: 50 67 48 64 72 31 29 20 63 61 6e 20 62 65 20 64  PgHdr1) can be d
06e0: 65 74 65 72 6d 69 6e 65 64 20 61 74 0a 2a 2a 20  etermined at.** 
06f0: 72 75 6e 74 69 6d 65 20 75 73 69 6e 67 20 73 71  runtime using sq
0700: 6c 69 74 65 33 5f 63 6f 6e 66 69 67 28 53 51 4c  lite3_config(SQL
0710: 49 54 45 5f 43 4f 4e 46 49 47 5f 50 43 41 43 48  ITE_CONFIG_PCACH
0720: 45 5f 48 44 52 53 5a 2c 20 26 73 69 7a 65 29 2e  E_HDRSZ, &size).
0730: 20 20 54 68 65 0a 2a 2a 20 73 69 7a 65 73 20 6f    The.** sizes o
0740: 66 20 74 68 65 20 65 78 74 65 6e 73 69 6f 6e 73  f the extensions
0750: 20 73 75 6d 20 74 6f 20 32 37 32 20 62 79 74 65   sum to 272 byte
0760: 73 20 6f 6e 20 78 36 34 20 66 6f 72 20 33 2e 38  s on x64 for 3.8
0770: 2e 31 30 2c 20 62 75 74 20 74 68 69 73 0a 2a 2a  .10, but this.**
0780: 20 73 69 7a 65 20 63 61 6e 20 76 61 72 79 20 61   size can vary a
0790: 63 63 6f 72 64 69 6e 67 20 74 6f 20 61 72 63 68  ccording to arch
07a0: 69 74 65 63 74 75 72 65 2c 20 63 6f 6d 70 69 6c  itecture, compil
07b0: 65 2d 74 69 6d 65 20 6f 70 74 69 6f 6e 73 2c 20  e-time options, 
07c0: 61 6e 64 0a 2a 2a 20 53 51 4c 69 74 65 20 6c 69  and.** SQLite li
07d0: 62 72 61 72 79 20 76 65 72 73 69 6f 6e 20 6e 75  brary version nu
07e0: 6d 62 65 72 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 53  mber..**.** If S
07f0: 51 4c 49 54 45 5f 50 43 41 43 48 45 5f 53 45 50  QLITE_PCACHE_SEP
0800: 41 52 41 54 45 5f 48 45 41 44 45 52 20 69 73 20  ARATE_HEADER is 
0810: 64 65 66 69 6e 65 64 2c 20 74 68 65 6e 20 74 68  defined, then th
0820: 65 20 65 78 74 65 6e 73 69 6f 6e 20 69 73 20 6f  e extension is o
0830: 62 74 61 69 6e 65 64 0a 2a 2a 20 75 73 69 6e 67  btained.** using
0840: 20 61 20 73 65 70 61 72 61 74 65 20 6d 65 6d 6f   a separate memo
0850: 72 79 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 66 72  ry allocation fr
0860: 6f 6d 20 74 68 65 20 64 61 74 61 62 61 73 65 20  om the database 
0870: 70 61 67 65 20 63 6f 6e 74 65 6e 74 2e 20 20 54  page content.  T
0880: 68 69 73 0a 2a 2a 20 73 65 65 6b 73 20 74 6f 20  his.** seeks to 
0890: 6f 76 65 72 63 6f 6d 65 20 74 68 65 20 22 63 6c  overcome the "cl
08a0: 6f 77 6e 73 68 6f 65 22 20 70 72 6f 62 6c 65 6d  ownshoe" problem
08b0: 20 28 61 6c 73 6f 20 63 61 6c 6c 65 64 20 22 69   (also called "i
08c0: 6e 74 65 72 6e 61 6c 0a 2a 2a 20 66 72 61 67 6d  nternal.** fragm
08d0: 65 6e 74 61 74 69 6f 6e 22 20 69 6e 20 61 63 61  entation" in aca
08e0: 64 65 6d 69 63 20 6c 69 74 65 72 61 74 75 72 65  demic literature
08f0: 29 20 6f 66 20 61 6c 6c 6f 63 61 74 69 6e 67 20  ) of allocating 
0900: 61 20 66 65 77 20 62 79 74 65 73 20 6d 6f 72 65  a few bytes more
0910: 0a 2a 2a 20 74 68 61 6e 20 61 20 70 6f 77 65 72  .** than a power
0920: 20 6f 66 20 74 77 6f 20 77 69 74 68 20 74 68 65   of two with the
0930: 20 6d 65 6d 6f 72 79 20 61 6c 6c 6f 63 61 74 6f   memory allocato
0940: 72 20 72 6f 75 6e 64 69 6e 67 20 75 70 20 74 6f  r rounding up to
0950: 20 74 68 65 20 6e 65 78 74 0a 2a 2a 20 70 6f 77   the next.** pow
0960: 65 72 20 6f 66 20 74 77 6f 2c 20 61 6e 64 20 6c  er of two, and l
0970: 65 61 76 69 6e 67 20 74 68 65 20 72 6f 75 6e 64  eaving the round
0980: 65 64 2d 75 70 20 73 70 61 63 65 20 75 6e 75 73  ed-up space unus
0990: 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 6d  ed..**.** This m
09a0: 6f 64 75 6c 65 20 74 72 61 63 6b 73 20 70 6f 69  odule tracks poi
09b0: 6e 74 65 72 73 20 74 6f 20 50 67 48 64 72 31 20  nters to PgHdr1 
09c0: 6f 62 6a 65 63 74 73 2e 20 20 4f 6e 6c 79 20 70  objects.  Only p
09d0: 63 61 63 68 65 2e 63 20 63 6f 6d 6d 75 6e 69 63  cache.c communic
09e0: 61 74 65 73 0a 2a 2a 20 77 69 74 68 20 74 68 69  ates.** with thi
09f0: 73 20 6d 6f 64 75 6c 65 2e 20 20 49 6e 66 6f 72  s module.  Infor
0a00: 6d 61 74 69 6f 6e 20 69 73 20 70 61 73 73 65 64  mation is passed
0a10: 20 62 61 63 6b 20 61 6e 64 20 66 6f 72 74 68 20   back and forth 
0a20: 61 73 20 50 67 48 64 72 31 20 70 6f 69 6e 74 65  as PgHdr1 pointe
0a30: 72 73 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 70 63  rs..**.** The pc
0a40: 61 63 68 65 2e 63 20 61 6e 64 20 70 61 67 65 72  ache.c and pager
0a50: 2e 63 20 6d 6f 64 75 6c 65 73 20 64 65 61 6c 20  .c modules deal 
0a60: 70 6f 69 6e 74 65 72 73 20 74 6f 20 50 67 48 64  pointers to PgHd
0a70: 72 20 6f 62 6a 65 63 74 73 2e 0a 2a 2a 20 54 68  r objects..** Th
0a80: 65 20 62 74 72 65 65 2e 63 20 6d 6f 64 75 6c 65  e btree.c module
0a90: 20 64 65 61 6c 73 20 77 69 74 68 20 70 6f 69 6e   deals with poin
0aa0: 74 65 72 73 20 74 6f 20 4d 65 6d 50 61 67 65 20  ters to MemPage 
0ab0: 6f 62 6a 65 63 74 73 2e 0a 2a 2a 0a 2a 2a 20 53  objects..**.** S
0ac0: 4f 55 52 43 45 20 4f 46 20 50 41 47 45 20 43 41  OURCE OF PAGE CA
0ad0: 43 48 45 20 4d 45 4d 4f 52 59 3a 0a 2a 2a 0a 2a  CHE MEMORY:.**.*
0ae0: 2a 20 4d 65 6d 6f 72 79 20 66 6f 72 20 61 20 70  * Memory for a p
0af0: 61 67 65 20 6d 69 67 68 74 20 63 6f 6d 65 20 66  age might come f
0b00: 72 6f 6d 20 61 6e 79 20 6f 66 20 74 68 72 65 65  rom any of three
0b10: 20 73 6f 75 72 63 65 73 3a 0a 2a 2a 0a 2a 2a 20   sources:.**.** 
0b20: 20 20 20 28 31 29 20 20 54 68 65 20 67 65 6e 65     (1)  The gene
0b30: 72 61 6c 2d 70 75 72 70 6f 73 65 20 6d 65 6d 6f  ral-purpose memo
0b40: 72 79 20 61 6c 6c 6f 63 61 74 6f 72 20 2d 20 73  ry allocator - s
0b50: 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 29 0a 2a  qlite3Malloc().*
0b60: 2a 20 20 20 20 28 32 29 20 20 47 6c 6f 62 61 6c  *    (2)  Global
0b70: 20 70 61 67 65 2d 63 61 63 68 65 20 6d 65 6d 6f   page-cache memo
0b80: 72 79 20 70 72 6f 76 69 64 65 64 20 75 73 69 6e  ry provided usin
0b90: 67 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67  g sqlite3_config
0ba0: 28 29 20 77 69 74 68 0a 2a 2a 20 20 20 20 20 20  () with.**      
0bb0: 20 20 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47     SQLITE_CONFIG
0bc0: 5f 50 41 47 45 43 41 43 48 45 2e 0a 2a 2a 20 20  _PAGECACHE..**  
0bd0: 20 20 28 33 29 20 20 50 43 61 63 68 65 2d 6c 6f    (3)  PCache-lo
0be0: 63 61 6c 20 62 75 6c 6b 20 61 6c 6c 6f 63 61 74  cal bulk allocat
0bf0: 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 74  ion..**.** The t
0c00: 68 69 72 64 20 63 61 73 65 20 69 73 20 61 20 63  hird case is a c
0c10: 68 75 6e 6b 20 6f 66 20 68 65 61 70 20 6d 65 6d  hunk of heap mem
0c20: 6f 72 79 20 28 64 65 66 61 75 6c 74 69 6e 67 20  ory (defaulting 
0c30: 74 6f 20 31 30 30 20 70 61 67 65 73 20 77 6f 72  to 100 pages wor
0c40: 74 68 29 0a 2a 2a 20 74 68 61 74 20 69 73 20 61  th).** that is a
0c50: 6c 6c 6f 63 61 74 65 64 20 77 68 65 6e 20 74 68  llocated when th
0c60: 65 20 70 61 67 65 20 63 61 63 68 65 20 69 73 20  e page cache is 
0c70: 63 72 65 61 74 65 64 2e 20 20 54 68 65 20 73 69  created.  The si
0c80: 7a 65 20 6f 66 20 74 68 65 20 6c 6f 63 61 6c 0a  ze of the local.
0c90: 2a 2a 20 62 75 6c 6b 20 61 6c 6c 6f 63 61 74 69  ** bulk allocati
0ca0: 6f 6e 20 63 61 6e 20 62 65 20 61 64 6a 75 73 74  on can be adjust
0cb0: 65 64 20 75 73 69 6e 67 20 0a 2a 2a 0a 2a 2a 20  ed using .**.** 
0cc0: 20 20 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66      sqlite3_conf
0cd0: 69 67 28 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47  ig(SQLITE_CONFIG
0ce0: 5f 50 41 47 45 43 41 43 48 45 2c 20 28 76 6f 69  _PAGECACHE, (voi
0cf0: 64 2a 29 30 2c 20 30 2c 20 4e 29 2e 0a 2a 2a 0a  d*)0, 0, N)..**.
0d00: 2a 2a 20 49 66 20 4e 20 69 73 20 70 6f 73 69 74  ** If N is posit
0d10: 69 76 65 2c 20 74 68 65 6e 20 4e 20 70 61 67 65  ive, then N page
0d20: 73 20 77 6f 72 74 68 20 6f 66 20 6d 65 6d 6f 72  s worth of memor
0d30: 79 20 61 72 65 20 61 6c 6c 6f 63 61 74 65 64 20  y are allocated 
0d40: 75 73 69 6e 67 20 61 20 73 69 6e 67 6c 65 0a 2a  using a single.*
0d50: 2a 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28  * sqlite3Malloc(
0d60: 29 20 63 61 6c 6c 20 61 6e 64 20 74 68 61 74 20  ) call and that 
0d70: 6d 65 6d 6f 72 79 20 69 73 20 75 73 65 64 20 66  memory is used f
0d80: 6f 72 20 74 68 65 20 66 69 72 73 74 20 4e 20 70  or the first N p
0d90: 61 67 65 73 20 61 6c 6c 6f 63 61 74 65 64 2e 0a  ages allocated..
0da0: 2a 2a 20 4f 72 20 69 66 20 4e 20 69 73 20 6e 65  ** Or if N is ne
0db0: 67 61 74 69 76 65 2c 20 74 68 65 6e 20 2d 31 30  gative, then -10
0dc0: 32 34 2a 4e 20 62 79 74 65 73 20 6f 66 20 6d 65  24*N bytes of me
0dd0: 6d 6f 72 79 20 61 72 65 20 61 6c 6c 6f 63 61 74  mory are allocat
0de0: 65 64 20 61 6e 64 20 75 73 65 64 0a 2a 2a 20 66  ed and used.** f
0df0: 6f 72 20 61 73 20 6d 61 6e 79 20 70 61 67 65 73  or as many pages
0e00: 20 61 73 20 63 61 6e 20 62 65 20 61 63 63 6f 6d   as can be accom
0e10: 6f 64 61 74 65 64 2e 0a 2a 2a 0a 2a 2a 20 4f 6e  odated..**.** On
0e20: 6c 79 20 6f 6e 65 20 6f 66 20 28 32 29 20 6f 72  ly one of (2) or
0e30: 20 28 33 29 20 63 61 6e 20 62 65 20 75 73 65 64   (3) can be used
0e40: 2e 20 20 4f 6e 63 65 20 74 68 65 20 6d 65 6d 6f  .  Once the memo
0e50: 72 79 20 61 76 61 69 6c 61 62 6c 65 20 74 6f 20  ry available to 
0e60: 28 32 29 20 6f 72 0a 2a 2a 20 28 33 29 20 69 73  (2) or.** (3) is
0e70: 20 65 78 68 61 75 73 74 65 64 2c 20 73 75 62 73   exhausted, subs
0e80: 65 71 75 65 6e 74 20 61 6c 6c 6f 63 61 74 69 6f  equent allocatio
0e90: 6e 73 20 66 61 69 6c 20 6f 76 65 72 20 74 6f 20  ns fail over to 
0ea0: 74 68 65 20 67 65 6e 65 72 61 6c 2d 70 75 72 70  the general-purp
0eb0: 6f 73 65 0a 2a 2a 20 6d 65 6d 6f 72 79 20 61 6c  ose.** memory al
0ec0: 6c 6f 63 61 74 6f 72 20 28 31 29 2e 0a 2a 2a 0a  locator (1)..**.
0ed0: 2a 2a 20 45 61 72 6c 69 65 72 20 76 65 72 73 69  ** Earlier versi
0ee0: 6f 6e 73 20 6f 66 20 53 51 4c 69 74 65 20 75 73  ons of SQLite us
0ef0: 65 64 20 6f 6e 6c 79 20 6d 65 74 68 6f 64 73 20  ed only methods 
0f00: 28 31 29 20 61 6e 64 20 28 32 29 2e 20 20 42 75  (1) and (2).  Bu
0f10: 74 20 65 78 70 65 72 69 6d 65 6e 74 73 0a 2a 2a  t experiments.**
0f20: 20 73 68 6f 77 20 74 68 61 74 20 6d 65 74 68 6f   show that metho
0f30: 64 20 28 33 29 20 77 69 74 68 20 4e 3d 3d 31 30  d (3) with N==10
0f40: 30 20 70 72 6f 76 69 64 65 73 20 61 62 6f 75 74  0 provides about
0f50: 20 61 20 35 25 20 70 65 72 66 6f 72 6d 61 6e 63   a 5% performanc
0f60: 65 20 62 6f 6f 73 74 20 66 6f 72 0a 2a 2a 20 63  e boost for.** c
0f70: 6f 6d 6d 6f 6e 20 77 6f 72 6b 6c 6f 61 64 73 2e  ommon workloads.
0f80: 0a 2a 2f 0a 23 69 6e 63 6c 75 64 65 20 22 73 71  .*/.#include "sq
0f90: 6c 69 74 65 49 6e 74 2e 68 22 0a 0a 74 79 70 65  liteInt.h"..type
0fa0: 64 65 66 20 73 74 72 75 63 74 20 50 43 61 63 68  def struct PCach
0fb0: 65 31 20 50 43 61 63 68 65 31 3b 0a 74 79 70 65  e1 PCache1;.type
0fc0: 64 65 66 20 73 74 72 75 63 74 20 50 67 48 64 72  def struct PgHdr
0fd0: 31 20 50 67 48 64 72 31 3b 0a 74 79 70 65 64 65  1 PgHdr1;.typede
0fe0: 66 20 73 74 72 75 63 74 20 50 67 46 72 65 65 73  f struct PgFrees
0ff0: 6c 6f 74 20 50 67 46 72 65 65 73 6c 6f 74 3b 0a  lot PgFreeslot;.
1000: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 50  typedef struct P
1010: 47 72 6f 75 70 20 50 47 72 6f 75 70 3b 0a 0a 2f  Group PGroup;../
1020: 2a 0a 2a 2a 20 45 61 63 68 20 63 61 63 68 65 20  *.** Each cache 
1030: 65 6e 74 72 79 20 69 73 20 72 65 70 72 65 73 65  entry is represe
1040: 6e 74 65 64 20 62 79 20 61 6e 20 69 6e 73 74 61  nted by an insta
1050: 6e 63 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f  nce of the follo
1060: 77 69 6e 67 20 0a 2a 2a 20 73 74 72 75 63 74 75  wing .** structu
1070: 72 65 2e 20 55 6e 6c 65 73 73 20 53 51 4c 49 54  re. Unless SQLIT
1080: 45 5f 50 43 41 43 48 45 5f 53 45 50 41 52 41 54  E_PCACHE_SEPARAT
1090: 45 5f 48 45 41 44 45 52 20 69 73 20 64 65 66 69  E_HEADER is defi
10a0: 6e 65 64 2c 20 61 20 62 75 66 66 65 72 20 6f 66  ned, a buffer of
10b0: 0a 2a 2a 20 50 67 48 64 72 31 2e 70 43 61 63 68  .** PgHdr1.pCach
10c0: 65 2d 3e 73 7a 50 61 67 65 20 62 79 74 65 73 20  e->szPage bytes 
10d0: 69 73 20 61 6c 6c 6f 63 61 74 65 64 20 64 69 72  is allocated dir
10e0: 65 63 74 6c 79 20 62 65 66 6f 72 65 20 74 68 69  ectly before thi
10f0: 73 20 73 74 72 75 63 74 75 72 65 20 0a 2a 2a 20  s structure .** 
1100: 69 6e 20 6d 65 6d 6f 72 79 2e 0a 2a 2f 0a 73 74  in memory..*/.st
1110: 72 75 63 74 20 50 67 48 64 72 31 20 7b 0a 20 20  ruct PgHdr1 {.  
1120: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 5f 70  sqlite3_pcache_p
1130: 61 67 65 20 70 61 67 65 3b 20 20 20 20 20 20 2f  age page;      /
1140: 2a 20 42 61 73 65 20 63 6c 61 73 73 2e 20 4d 75  * Base class. Mu
1150: 73 74 20 62 65 20 66 69 72 73 74 2e 20 70 42 75  st be first. pBu
1160: 66 20 26 20 70 45 78 74 72 61 20 2a 2f 0a 20 20  f & pExtra */.  
1170: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4b 65  unsigned int iKe
1180: 79 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  y;             /
1190: 2a 20 4b 65 79 20 76 61 6c 75 65 20 28 70 61 67  * Key value (pag
11a0: 65 20 6e 75 6d 62 65 72 29 20 2a 2f 0a 20 20 75  e number) */.  u
11b0: 38 20 69 73 42 75 6c 6b 4c 6f 63 61 6c 3b 20 20  8 isBulkLocal;  
11c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
11d0: 20 54 68 69 73 20 70 61 67 65 20 66 72 6f 6d 20   This page from 
11e0: 62 75 6c 6b 20 6c 6f 63 61 6c 20 73 74 6f 72 61  bulk local stora
11f0: 67 65 20 2a 2f 0a 20 20 75 38 20 69 73 41 6e 63  ge */.  u8 isAnc
1200: 68 6f 72 3b 20 20 20 20 20 20 20 20 20 20 20 20  hor;            
1210: 20 20 20 20 20 20 20 2f 2a 20 54 68 69 73 20 69         /* This i
1220: 73 20 74 68 65 20 50 47 72 6f 75 70 2e 6c 72 75  s the PGroup.lru
1230: 20 65 6c 65 6d 65 6e 74 20 2a 2f 0a 20 20 50 67   element */.  Pg
1240: 48 64 72 31 20 2a 70 4e 65 78 74 3b 20 20 20 20  Hdr1 *pNext;    
1250: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1260: 4e 65 78 74 20 69 6e 20 68 61 73 68 20 74 61 62  Next in hash tab
1270: 6c 65 20 63 68 61 69 6e 20 2a 2f 0a 20 20 50 43  le chain */.  PC
1280: 61 63 68 65 31 20 2a 70 43 61 63 68 65 3b 20 20  ache1 *pCache;  
1290: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
12a0: 43 61 63 68 65 20 74 68 61 74 20 63 75 72 72 65  Cache that curre
12b0: 6e 74 6c 79 20 6f 77 6e 73 20 74 68 69 73 20 70  ntly owns this p
12c0: 61 67 65 20 2a 2f 0a 20 20 50 67 48 64 72 31 20  age */.  PgHdr1 
12d0: 2a 70 4c 72 75 4e 65 78 74 3b 20 20 20 20 20 20  *pLruNext;      
12e0: 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20          /* Next 
12f0: 69 6e 20 4c 52 55 20 6c 69 73 74 20 6f 66 20 75  in LRU list of u
1300: 6e 70 69 6e 6e 65 64 20 70 61 67 65 73 20 2a 2f  npinned pages */
1310: 0a 20 20 50 67 48 64 72 31 20 2a 70 4c 72 75 50  .  PgHdr1 *pLruP
1320: 72 65 76 3b 20 20 20 20 20 20 20 20 20 20 20 20  rev;            
1330: 20 20 2f 2a 20 50 72 65 76 69 6f 75 73 20 69 6e    /* Previous in
1340: 20 4c 52 55 20 6c 69 73 74 20 6f 66 20 75 6e 70   LRU list of unp
1350: 69 6e 6e 65 64 20 70 61 67 65 73 20 2a 2f 0a 7d  inned pages */.}
1360: 3b 0a 0a 2f 2a 0a 2a 2a 20 41 20 70 61 67 65 20  ;../*.** A page 
1370: 69 73 20 70 69 6e 6e 65 64 20 69 66 20 69 74 20  is pinned if it 
1380: 69 73 20 6e 6f 74 20 6f 6e 20 74 68 65 20 4c 52  is not on the LR
1390: 55 20 6c 69 73 74 2e 20 20 54 6f 20 62 65 20 22  U list.  To be "
13a0: 70 69 6e 6e 65 64 22 20 6d 65 61 6e 73 0a 2a 2a  pinned" means.**
13b0: 20 74 68 61 74 20 74 68 65 20 70 61 67 65 20 69   that the page i
13c0: 73 20 69 6e 20 61 63 74 69 76 65 20 75 73 65 20  s in active use 
13d0: 61 6e 64 20 6d 75 73 74 20 6e 6f 74 20 62 65 20  and must not be 
13e0: 64 65 61 6c 6c 6f 63 61 74 65 64 2e 0a 2a 2f 0a  deallocated..*/.
13f0: 23 64 65 66 69 6e 65 20 50 41 47 45 5f 49 53 5f  #define PAGE_IS_
1400: 50 49 4e 4e 45 44 28 70 29 20 20 20 20 28 28 70  PINNED(p)    ((p
1410: 29 2d 3e 70 4c 72 75 4e 65 78 74 3d 3d 30 29 0a  )->pLruNext==0).
1420: 23 64 65 66 69 6e 65 20 50 41 47 45 5f 49 53 5f  #define PAGE_IS_
1430: 55 4e 50 49 4e 4e 45 44 28 70 29 20 20 28 28 70  UNPINNED(p)  ((p
1440: 29 2d 3e 70 4c 72 75 4e 65 78 74 21 3d 30 29 0a  )->pLruNext!=0).
1450: 0a 2f 2a 20 45 61 63 68 20 70 61 67 65 20 63 61  ./* Each page ca
1460: 63 68 65 20 28 6f 72 20 50 43 61 63 68 65 29 20  che (or PCache) 
1470: 62 65 6c 6f 6e 67 73 20 74 6f 20 61 20 50 47 72  belongs to a PGr
1480: 6f 75 70 2e 20 20 41 20 50 47 72 6f 75 70 20 69  oup.  A PGroup i
1490: 73 20 61 20 73 65 74 20 0a 2a 2a 20 6f 66 20 6f  s a set .** of o
14a0: 6e 65 20 6f 72 20 6d 6f 72 65 20 50 43 61 63 68  ne or more PCach
14b0: 65 73 20 74 68 61 74 20 61 72 65 20 61 62 6c 65  es that are able
14c0: 20 74 6f 20 72 65 63 79 63 6c 65 20 65 61 63 68   to recycle each
14d0: 20 6f 74 68 65 72 27 73 20 75 6e 70 69 6e 6e 65   other's unpinne
14e0: 64 0a 2a 2a 20 70 61 67 65 73 20 77 68 65 6e 20  d.** pages when 
14f0: 74 68 65 79 20 61 72 65 20 75 6e 64 65 72 20 6d  they are under m
1500: 65 6d 6f 72 79 20 70 72 65 73 73 75 72 65 2e 20  emory pressure. 
1510: 20 41 20 50 47 72 6f 75 70 20 69 73 20 61 6e 20   A PGroup is an 
1520: 69 6e 73 74 61 6e 63 65 20 6f 66 0a 2a 2a 20 74  instance of.** t
1530: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6f 62 6a  he following obj
1540: 65 63 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  ect..**.** This 
1550: 70 61 67 65 20 63 61 63 68 65 20 69 6d 70 6c 65  page cache imple
1560: 6d 65 6e 74 61 74 69 6f 6e 20 77 6f 72 6b 73 20  mentation works 
1570: 69 6e 20 6f 6e 65 20 6f 66 20 74 77 6f 20 6d 6f  in one of two mo
1580: 64 65 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 28 31 29  des:.**.**   (1)
1590: 20 20 45 76 65 72 79 20 50 43 61 63 68 65 20 69    Every PCache i
15a0: 73 20 74 68 65 20 73 6f 6c 65 20 6d 65 6d 62 65  s the sole membe
15b0: 72 20 6f 66 20 69 74 73 20 6f 77 6e 20 50 47 72  r of its own PGr
15c0: 6f 75 70 2e 20 20 54 68 65 72 65 20 69 73 0a 2a  oup.  There is.*
15d0: 2a 20 20 20 20 20 20 20 20 6f 6e 65 20 50 47 72  *        one PGr
15e0: 6f 75 70 20 70 65 72 20 50 43 61 63 68 65 2e 0a  oup per PCache..
15f0: 2a 2a 0a 2a 2a 20 20 20 28 32 29 20 20 54 68 65  **.**   (2)  The
1600: 72 65 20 69 73 20 61 20 73 69 6e 67 6c 65 20 67  re is a single g
1610: 6c 6f 62 61 6c 20 50 47 72 6f 75 70 20 74 68 61  lobal PGroup tha
1620: 74 20 61 6c 6c 20 50 43 61 63 68 65 73 20 61 72  t all PCaches ar
1630: 65 20 61 20 6d 65 6d 62 65 72 0a 2a 2a 20 20 20  e a member.**   
1640: 20 20 20 20 20 6f 66 2e 0a 2a 2a 0a 2a 2a 20 4d       of..**.** M
1650: 6f 64 65 20 31 20 75 73 65 73 20 6d 6f 72 65 20  ode 1 uses more 
1660: 6d 65 6d 6f 72 79 20 28 73 69 6e 63 65 20 50 43  memory (since PC
1670: 61 63 68 65 20 69 6e 73 74 61 6e 63 65 73 20 61  ache instances a
1680: 72 65 20 6e 6f 74 20 61 62 6c 65 20 74 6f 20 72  re not able to r
1690: 6f 62 0a 2a 2a 20 75 6e 75 73 65 64 20 70 61 67  ob.** unused pag
16a0: 65 73 20 66 72 6f 6d 20 6f 74 68 65 72 20 50 43  es from other PC
16b0: 61 63 68 65 73 29 20 62 75 74 20 69 74 20 61 6c  aches) but it al
16c0: 73 6f 20 6f 70 65 72 61 74 65 73 20 77 69 74 68  so operates with
16d0: 6f 75 74 20 61 20 6d 75 74 65 78 2c 0a 2a 2a 20  out a mutex,.** 
16e0: 61 6e 64 20 69 73 20 74 68 65 72 65 66 6f 72 65  and is therefore
16f0: 20 6f 66 74 65 6e 20 66 61 73 74 65 72 2e 20 20   often faster.  
1700: 4d 6f 64 65 20 32 20 72 65 71 75 69 72 65 73 20  Mode 2 requires 
1710: 61 20 6d 75 74 65 78 20 69 6e 20 6f 72 64 65 72  a mutex in order
1720: 20 74 6f 20 62 65 0a 2a 2a 20 74 68 72 65 61 64   to be.** thread
1730: 73 61 66 65 2c 20 62 75 74 20 72 65 63 79 63 6c  safe, but recycl
1740: 65 73 20 70 61 67 65 73 20 6d 6f 72 65 20 65 66  es pages more ef
1750: 66 69 63 69 65 6e 74 6c 79 2e 0a 2a 2a 0a 2a 2a  ficiently..**.**
1760: 20 46 6f 72 20 6d 6f 64 65 20 28 31 29 2c 20 50   For mode (1), P
1770: 47 72 6f 75 70 2e 6d 75 74 65 78 20 69 73 20 4e  Group.mutex is N
1780: 55 4c 4c 2e 20 20 46 6f 72 20 6d 6f 64 65 20 28  ULL.  For mode (
1790: 32 29 20 74 68 65 72 65 20 69 73 20 6f 6e 6c 79  2) there is only
17a0: 20 61 20 73 69 6e 67 6c 65 0a 2a 2a 20 50 47 72   a single.** PGr
17b0: 6f 75 70 20 77 68 69 63 68 20 69 73 20 74 68 65  oup which is the
17c0: 20 70 63 61 63 68 65 31 2e 67 72 70 20 67 6c 6f   pcache1.grp glo
17d0: 62 61 6c 20 76 61 72 69 61 62 6c 65 20 61 6e 64  bal variable and
17e0: 20 69 74 73 20 6d 75 74 65 78 20 69 73 0a 2a 2a   its mutex is.**
17f0: 20 53 51 4c 49 54 45 5f 4d 55 54 45 58 5f 53 54   SQLITE_MUTEX_ST
1800: 41 54 49 43 5f 4c 52 55 2e 0a 2a 2f 0a 73 74 72  ATIC_LRU..*/.str
1810: 75 63 74 20 50 47 72 6f 75 70 20 7b 0a 20 20 73  uct PGroup {.  s
1820: 71 6c 69 74 65 33 5f 6d 75 74 65 78 20 2a 6d 75  qlite3_mutex *mu
1830: 74 65 78 3b 20 20 20 20 20 20 20 20 20 20 2f 2a  tex;          /*
1840: 20 4d 55 54 45 58 5f 53 54 41 54 49 43 5f 4c 52   MUTEX_STATIC_LR
1850: 55 20 6f 72 20 4e 55 4c 4c 20 2a 2f 0a 20 20 75  U or NULL */.  u
1860: 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 4d 61 78  nsigned int nMax
1870: 50 61 67 65 3b 20 20 20 20 20 20 20 20 20 2f 2a  Page;         /*
1880: 20 53 75 6d 20 6f 66 20 6e 4d 61 78 20 66 6f 72   Sum of nMax for
1890: 20 70 75 72 67 65 61 62 6c 65 20 63 61 63 68 65   purgeable cache
18a0: 73 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20  s */.  unsigned 
18b0: 69 6e 74 20 6e 4d 69 6e 50 61 67 65 3b 20 20 20  int nMinPage;   
18c0: 20 20 20 20 20 20 2f 2a 20 53 75 6d 20 6f 66 20        /* Sum of 
18d0: 6e 4d 69 6e 20 66 6f 72 20 70 75 72 67 65 61 62  nMin for purgeab
18e0: 6c 65 20 63 61 63 68 65 73 20 2a 2f 0a 20 20 75  le caches */.  u
18f0: 6e 73 69 67 6e 65 64 20 69 6e 74 20 6d 78 50 69  nsigned int mxPi
1900: 6e 6e 65 64 3b 20 20 20 20 20 20 20 20 20 2f 2a  nned;         /*
1910: 20 6e 4d 61 78 70 61 67 65 20 2b 20 31 30 20 2d   nMaxpage + 10 -
1920: 20 6e 4d 69 6e 50 61 67 65 20 2a 2f 0a 20 20 75   nMinPage */.  u
1930: 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 50 75 72  nsigned int nPur
1940: 67 65 61 62 6c 65 3b 20 20 20 20 20 20 20 2f 2a  geable;       /*
1950: 20 4e 75 6d 62 65 72 20 6f 66 20 70 75 72 67 65   Number of purge
1960: 61 62 6c 65 20 70 61 67 65 73 20 61 6c 6c 6f 63  able pages alloc
1970: 61 74 65 64 20 2a 2f 0a 20 20 50 67 48 64 72 31  ated */.  PgHdr1
1980: 20 6c 72 75 3b 20 20 20 20 20 20 20 20 20 20 20   lru;           
1990: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20           /* The 
19a0: 62 65 67 69 6e 6e 69 6e 67 20 61 6e 64 20 65 6e  beginning and en
19b0: 64 20 6f 66 20 74 68 65 20 4c 52 55 20 6c 69 73  d of the LRU lis
19c0: 74 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 20 45 61 63 68  t */.};../* Each
19d0: 20 70 61 67 65 20 63 61 63 68 65 20 69 73 20 61   page cache is a
19e0: 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68  n instance of th
19f0: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6f 62 6a 65  e following obje
1a00: 63 74 2e 20 20 45 76 65 72 79 0a 2a 2a 20 6f 70  ct.  Every.** op
1a10: 65 6e 20 64 61 74 61 62 61 73 65 20 66 69 6c 65  en database file
1a20: 20 28 69 6e 63 6c 75 64 69 6e 67 20 65 61 63 68   (including each
1a30: 20 69 6e 2d 6d 65 6d 6f 72 79 20 64 61 74 61 62   in-memory datab
1a40: 61 73 65 20 61 6e 64 20 65 61 63 68 0a 2a 2a 20  ase and each.** 
1a50: 74 65 6d 70 6f 72 61 72 79 20 6f 72 20 74 72 61  temporary or tra
1a60: 6e 73 69 65 6e 74 20 64 61 74 61 62 61 73 65 29  nsient database)
1a70: 20 68 61 73 20 61 20 73 69 6e 67 6c 65 20 70 61   has a single pa
1a80: 67 65 20 63 61 63 68 65 20 77 68 69 63 68 0a 2a  ge cache which.*
1a90: 2a 20 69 73 20 61 6e 20 69 6e 73 74 61 6e 63 65  * is an instance
1aa0: 20 6f 66 20 74 68 69 73 20 6f 62 6a 65 63 74 2e   of this object.
1ab0: 0a 2a 2a 0a 2a 2a 20 50 6f 69 6e 74 65 72 73 20  .**.** Pointers 
1ac0: 74 6f 20 73 74 72 75 63 74 75 72 65 73 20 6f 66  to structures of
1ad0: 20 74 68 69 73 20 74 79 70 65 20 61 72 65 20 63   this type are c
1ae0: 61 73 74 20 61 6e 64 20 72 65 74 75 72 6e 65 64  ast and returned
1af0: 20 61 73 20 0a 2a 2a 20 6f 70 61 71 75 65 20 73   as .** opaque s
1b00: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2a 20 68  qlite3_pcache* h
1b10: 61 6e 64 6c 65 73 2e 0a 2a 2f 0a 73 74 72 75 63  andles..*/.struc
1b20: 74 20 50 43 61 63 68 65 31 20 7b 0a 20 20 2f 2a  t PCache1 {.  /*
1b30: 20 43 61 63 68 65 20 63 6f 6e 66 69 67 75 72 61   Cache configura
1b40: 74 69 6f 6e 20 70 61 72 61 6d 65 74 65 72 73 2e  tion parameters.
1b50: 20 50 61 67 65 20 73 69 7a 65 20 28 73 7a 50 61   Page size (szPa
1b60: 67 65 29 20 61 6e 64 20 74 68 65 20 70 75 72 67  ge) and the purg
1b70: 65 61 62 6c 65 0a 20 20 2a 2a 20 66 6c 61 67 20  eable.  ** flag 
1b80: 28 62 50 75 72 67 65 61 62 6c 65 29 20 61 6e 64  (bPurgeable) and
1b90: 20 74 68 65 20 70 6e 50 75 72 67 65 61 62 6c 65   the pnPurgeable
1ba0: 20 70 6f 69 6e 74 65 72 20 61 72 65 20 61 6c 6c   pointer are all
1bb0: 20 73 65 74 20 77 68 65 6e 20 74 68 65 0a 20 20   set when the.  
1bc0: 2a 2a 20 63 61 63 68 65 20 69 73 20 63 72 65 61  ** cache is crea
1bd0: 74 65 64 20 61 6e 64 20 61 72 65 20 6e 65 76 65  ted and are neve
1be0: 72 20 63 68 61 6e 67 65 64 20 74 68 65 72 65 61  r changed therea
1bf0: 66 74 65 72 2e 20 6e 4d 61 78 20 6d 61 79 20 62  fter. nMax may b
1c00: 65 20 0a 20 20 2a 2a 20 6d 6f 64 69 66 69 65 64  e .  ** modified
1c10: 20 61 74 20 61 6e 79 20 74 69 6d 65 20 62 79 20   at any time by 
1c20: 61 20 63 61 6c 6c 20 74 6f 20 74 68 65 20 70 63  a call to the pc
1c30: 61 63 68 65 31 43 61 63 68 65 73 69 7a 65 28 29  ache1Cachesize()
1c40: 20 6d 65 74 68 6f 64 2e 0a 20 20 2a 2a 20 54 68   method..  ** Th
1c50: 65 20 50 47 72 6f 75 70 20 6d 75 74 65 78 20 6d  e PGroup mutex m
1c60: 75 73 74 20 62 65 20 68 65 6c 64 20 77 68 65 6e  ust be held when
1c70: 20 61 63 63 65 73 73 69 6e 67 20 6e 4d 61 78 2e   accessing nMax.
1c80: 0a 20 20 2a 2f 0a 20 20 50 47 72 6f 75 70 20 2a  .  */.  PGroup *
1c90: 70 47 72 6f 75 70 3b 20 20 20 20 20 20 20 20 20  pGroup;         
1ca0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
1cb0: 47 72 6f 75 70 20 74 68 69 73 20 63 61 63 68 65  Group this cache
1cc0: 20 62 65 6c 6f 6e 67 73 20 74 6f 20 2a 2f 0a 20   belongs to */. 
1cd0: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 2a 70   unsigned int *p
1ce0: 6e 50 75 72 67 65 61 62 6c 65 3b 20 20 20 20 20  nPurgeable;     
1cf0: 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20       /* Pointer 
1d00: 74 6f 20 70 47 72 6f 75 70 2d 3e 6e 50 75 72 67  to pGroup->nPurg
1d10: 65 61 62 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 73  eable */.  int s
1d20: 7a 50 61 67 65 3b 20 20 20 20 20 20 20 20 20 20  zPage;          
1d30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1d40: 2a 20 53 69 7a 65 20 6f 66 20 64 61 74 61 62 61  * Size of databa
1d50: 73 65 20 63 6f 6e 74 65 6e 74 20 73 65 63 74 69  se content secti
1d60: 6f 6e 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 45 78  on */.  int szEx
1d70: 74 72 61 3b 20 20 20 20 20 20 20 20 20 20 20 20  tra;            
1d80: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 73              /* s
1d90: 69 7a 65 6f 66 28 4d 65 6d 50 61 67 65 29 2b 73  izeof(MemPage)+s
1da0: 69 7a 65 6f 66 28 50 67 48 64 72 29 20 2a 2f 0a  izeof(PgHdr) */.
1db0: 20 20 69 6e 74 20 73 7a 41 6c 6c 6f 63 3b 20 20    int szAlloc;  
1dc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1dd0: 20 20 20 20 20 20 2f 2a 20 54 6f 74 61 6c 20 73        /* Total s
1de0: 69 7a 65 20 6f 66 20 6f 6e 65 20 70 63 61 63 68  ize of one pcach
1df0: 65 20 6c 69 6e 65 20 2a 2f 0a 20 20 69 6e 74 20  e line */.  int 
1e00: 62 50 75 72 67 65 61 62 6c 65 3b 20 20 20 20 20  bPurgeable;     
1e10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1e20: 2f 2a 20 54 72 75 65 20 69 66 20 63 61 63 68 65  /* True if cache
1e30: 20 69 73 20 70 75 72 67 65 61 62 6c 65 20 2a 2f   is purgeable */
1e40: 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  .  unsigned int 
1e50: 6e 4d 69 6e 3b 20 20 20 20 20 20 20 20 20 20 20  nMin;           
1e60: 20 20 20 20 20 20 20 2f 2a 20 4d 69 6e 69 6d 75         /* Minimu
1e70: 6d 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65  m number of page
1e80: 73 20 72 65 73 65 72 76 65 64 20 2a 2f 0a 20 20  s reserved */.  
1e90: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 4d 61  unsigned int nMa
1ea0: 78 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  x;              
1eb0: 20 20 20 20 2f 2a 20 43 6f 6e 66 69 67 75 72 65      /* Configure
1ec0: 64 20 22 63 61 63 68 65 5f 73 69 7a 65 22 20 76  d "cache_size" v
1ed0: 61 6c 75 65 20 2a 2f 0a 20 20 75 6e 73 69 67 6e  alue */.  unsign
1ee0: 65 64 20 69 6e 74 20 6e 39 30 70 63 74 3b 20 20  ed int n90pct;  
1ef0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1f00: 20 6e 4d 61 78 2a 39 2f 31 30 20 2a 2f 0a 20 20   nMax*9/10 */.  
1f10: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4d 61  unsigned int iMa
1f20: 78 4b 65 79 3b 20 20 20 20 20 20 20 20 20 20 20  xKey;           
1f30: 20 20 20 20 2f 2a 20 4c 61 72 67 65 73 74 20 6b      /* Largest k
1f40: 65 79 20 73 65 65 6e 20 73 69 6e 63 65 20 78 54  ey seen since xT
1f50: 72 75 6e 63 61 74 65 28 29 20 2a 2f 0a 0a 20 20  runcate() */..  
1f60: 2f 2a 20 48 61 73 68 20 74 61 62 6c 65 20 6f 66  /* Hash table of
1f70: 20 61 6c 6c 20 70 61 67 65 73 2e 20 54 68 65 20   all pages. The 
1f80: 66 6f 6c 6c 6f 77 69 6e 67 20 76 61 72 69 61 62  following variab
1f90: 6c 65 73 20 6d 61 79 20 6f 6e 6c 79 20 62 65 20  les may only be 
1fa0: 61 63 63 65 73 73 65 64 0a 20 20 2a 2a 20 77 68  accessed.  ** wh
1fb0: 65 6e 20 74 68 65 20 61 63 63 65 73 73 6f 72 20  en the accessor 
1fc0: 69 73 20 68 6f 6c 64 69 6e 67 20 74 68 65 20 50  is holding the P
1fd0: 47 72 6f 75 70 20 6d 75 74 65 78 2e 0a 20 20 2a  Group mutex..  *
1fe0: 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74  /.  unsigned int
1ff0: 20 6e 52 65 63 79 63 6c 61 62 6c 65 3b 20 20 20   nRecyclable;   
2000: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
2010: 72 20 6f 66 20 70 61 67 65 73 20 69 6e 20 74 68  r of pages in th
2020: 65 20 4c 52 55 20 6c 69 73 74 20 2a 2f 0a 20 20  e LRU list */.  
2030: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 50 61  unsigned int nPa
2040: 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ge;             
2050: 20 20 20 20 2f 2a 20 54 6f 74 61 6c 20 6e 75 6d      /* Total num
2060: 62 65 72 20 6f 66 20 70 61 67 65 73 20 69 6e 20  ber of pages in 
2070: 61 70 48 61 73 68 20 2a 2f 0a 20 20 75 6e 73 69  apHash */.  unsi
2080: 67 6e 65 64 20 69 6e 74 20 6e 48 61 73 68 3b 20  gned int nHash; 
2090: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
20a0: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 73 6c 6f  /* Number of slo
20b0: 74 73 20 69 6e 20 61 70 48 61 73 68 5b 5d 20 2a  ts in apHash[] *
20c0: 2f 0a 20 20 50 67 48 64 72 31 20 2a 2a 61 70 48  /.  PgHdr1 **apH
20d0: 61 73 68 3b 20 20 20 20 20 20 20 20 20 20 20 20  ash;            
20e0: 20 20 20 20 20 20 20 20 2f 2a 20 48 61 73 68 20          /* Hash 
20f0: 74 61 62 6c 65 20 66 6f 72 20 66 61 73 74 20 6c  table for fast l
2100: 6f 6f 6b 75 70 20 62 79 20 6b 65 79 20 2a 2f 0a  ookup by key */.
2110: 20 20 50 67 48 64 72 31 20 2a 70 46 72 65 65 3b    PgHdr1 *pFree;
2120: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2130: 20 20 20 20 20 20 2f 2a 20 4c 69 73 74 20 6f 66        /* List of
2140: 20 75 6e 75 73 65 64 20 70 63 61 63 68 65 2d 6c   unused pcache-l
2150: 6f 63 61 6c 20 70 61 67 65 73 20 2a 2f 0a 20 20  ocal pages */.  
2160: 76 6f 69 64 20 2a 70 42 75 6c 6b 3b 20 20 20 20  void *pBulk;    
2170: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2180: 20 20 20 20 2f 2a 20 42 75 6c 6b 20 6d 65 6d 6f      /* Bulk memo
2190: 72 79 20 75 73 65 64 20 62 79 20 70 63 61 63 68  ry used by pcach
21a0: 65 2d 6c 6f 63 61 6c 20 2a 2f 0a 7d 3b 0a 0a 2f  e-local */.};../
21b0: 2a 0a 2a 2a 20 46 72 65 65 20 73 6c 6f 74 73 20  *.** Free slots 
21c0: 69 6e 20 74 68 65 20 61 6c 6c 6f 63 61 74 6f 72  in the allocator
21d0: 20 75 73 65 64 20 74 6f 20 64 69 76 69 64 65 20   used to divide 
21e0: 75 70 20 74 68 65 20 67 6c 6f 62 61 6c 20 70 61  up the global pa
21f0: 67 65 20 63 61 63 68 65 0a 2a 2a 20 62 75 66 66  ge cache.** buff
2200: 65 72 20 70 72 6f 76 69 64 65 64 20 75 73 69 6e  er provided usin
2210: 67 20 74 68 65 20 53 51 4c 49 54 45 5f 43 4f 4e  g the SQLITE_CON
2220: 46 49 47 5f 50 41 47 45 43 41 43 48 45 20 6d 65  FIG_PAGECACHE me
2230: 63 68 61 6e 69 73 6d 2e 0a 2a 2f 0a 73 74 72 75  chanism..*/.stru
2240: 63 74 20 50 67 46 72 65 65 73 6c 6f 74 20 7b 0a  ct PgFreeslot {.
2250: 20 20 50 67 46 72 65 65 73 6c 6f 74 20 2a 70 4e    PgFreeslot *pN
2260: 65 78 74 3b 20 20 2f 2a 20 4e 65 78 74 20 66 72  ext;  /* Next fr
2270: 65 65 20 73 6c 6f 74 20 2a 2f 0a 7d 3b 0a 0a 2f  ee slot */.};../
2280: 2a 0a 2a 2a 20 47 6c 6f 62 61 6c 20 64 61 74 61  *.** Global data
2290: 20 75 73 65 64 20 62 79 20 74 68 69 73 20 63 61   used by this ca
22a0: 63 68 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 53  che..*/.static S
22b0: 51 4c 49 54 45 5f 57 53 44 20 73 74 72 75 63 74  QLITE_WSD struct
22c0: 20 50 43 61 63 68 65 47 6c 6f 62 61 6c 20 7b 0a   PCacheGlobal {.
22d0: 20 20 50 47 72 6f 75 70 20 67 72 70 3b 20 20 20    PGroup grp;   
22e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
22f0: 20 2f 2a 20 54 68 65 20 67 6c 6f 62 61 6c 20 50   /* The global P
2300: 47 72 6f 75 70 20 66 6f 72 20 6d 6f 64 65 20 28  Group for mode (
2310: 32 29 20 2a 2f 0a 0a 20 20 2f 2a 20 56 61 72 69  2) */..  /* Vari
2320: 61 62 6c 65 73 20 72 65 6c 61 74 65 64 20 74 6f  ables related to
2330: 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50   SQLITE_CONFIG_P
2340: 41 47 45 43 41 43 48 45 20 73 65 74 74 69 6e 67  AGECACHE setting
2350: 73 2e 20 20 54 68 65 0a 20 20 2a 2a 20 73 7a 53  s.  The.  ** szS
2360: 6c 6f 74 2c 20 6e 53 6c 6f 74 2c 20 70 53 74 61  lot, nSlot, pSta
2370: 72 74 2c 20 70 45 6e 64 2c 20 6e 52 65 73 65 72  rt, pEnd, nReser
2380: 76 65 2c 20 61 6e 64 20 69 73 49 6e 69 74 20 76  ve, and isInit v
2390: 61 6c 75 65 73 20 61 72 65 20 61 6c 6c 0a 20 20  alues are all.  
23a0: 2a 2a 20 66 69 78 65 64 20 61 74 20 73 71 6c 69  ** fixed at sqli
23b0: 74 65 33 5f 69 6e 69 74 69 61 6c 69 7a 65 28 29  te3_initialize()
23c0: 20 74 69 6d 65 20 61 6e 64 20 64 6f 20 6e 6f 74   time and do not
23d0: 20 72 65 71 75 69 72 65 20 6d 75 74 65 78 20 70   require mutex p
23e0: 72 6f 74 65 63 74 69 6f 6e 2e 0a 20 20 2a 2a 20  rotection..  ** 
23f0: 54 68 65 20 6e 46 72 65 65 53 6c 6f 74 20 61 6e  The nFreeSlot an
2400: 64 20 70 46 72 65 65 20 76 61 6c 75 65 73 20 64  d pFree values d
2410: 6f 20 72 65 71 75 69 72 65 20 6d 75 74 65 78 20  o require mutex 
2420: 70 72 6f 74 65 63 74 69 6f 6e 2e 0a 20 20 2a 2f  protection..  */
2430: 0a 20 20 69 6e 74 20 69 73 49 6e 69 74 3b 20 20  .  int isInit;  
2440: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2450: 20 20 2f 2a 20 54 72 75 65 20 69 66 20 69 6e 69    /* True if ini
2460: 74 69 61 6c 69 7a 65 64 20 2a 2f 0a 20 20 69 6e  tialized */.  in
2470: 74 20 73 65 70 61 72 61 74 65 43 61 63 68 65 3b  t separateCache;
2480: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2490: 55 73 65 20 61 20 6e 65 77 20 50 47 72 6f 75 70  Use a new PGroup
24a0: 20 66 6f 72 20 65 61 63 68 20 50 43 61 63 68 65   for each PCache
24b0: 20 2a 2f 0a 20 20 69 6e 74 20 6e 49 6e 69 74 50   */.  int nInitP
24c0: 61 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  age;            
24d0: 20 20 20 20 20 2f 2a 20 49 6e 69 74 69 61 6c 20       /* Initial 
24e0: 62 75 6c 6b 20 61 6c 6c 6f 63 61 74 69 6f 6e 20  bulk allocation 
24f0: 73 69 7a 65 20 2a 2f 20 20 20 0a 20 20 69 6e 74  size */   .  int
2500: 20 73 7a 53 6c 6f 74 3b 20 20 20 20 20 20 20 20   szSlot;        
2510: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
2520: 69 7a 65 20 6f 66 20 65 61 63 68 20 66 72 65 65  ize of each free
2530: 20 73 6c 6f 74 20 2a 2f 0a 20 20 69 6e 74 20 6e   slot */.  int n
2540: 53 6c 6f 74 3b 20 20 20 20 20 20 20 20 20 20 20  Slot;           
2550: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65            /* The
2560: 20 6e 75 6d 62 65 72 20 6f 66 20 70 63 61 63 68   number of pcach
2570: 65 20 73 6c 6f 74 73 20 2a 2f 0a 20 20 69 6e 74  e slots */.  int
2580: 20 6e 52 65 73 65 72 76 65 3b 20 20 20 20 20 20   nReserve;      
2590: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
25a0: 72 79 20 74 6f 20 6b 65 65 70 20 6e 46 72 65 65  ry to keep nFree
25b0: 53 6c 6f 74 20 61 62 6f 76 65 20 74 68 69 73 20  Slot above this 
25c0: 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 53 74 61 72  */.  void *pStar
25d0: 74 2c 20 2a 70 45 6e 64 3b 20 20 20 20 20 20 20  t, *pEnd;       
25e0: 20 20 20 20 2f 2a 20 42 6f 75 6e 64 73 20 6f 66      /* Bounds of
25f0: 20 67 6c 6f 62 61 6c 20 70 61 67 65 20 63 61 63   global page cac
2600: 68 65 20 6d 65 6d 6f 72 79 20 2a 2f 0a 20 20 2f  he memory */.  /
2610: 2a 20 41 62 6f 76 65 20 72 65 71 75 69 72 65 73  * Above requires
2620: 20 6e 6f 20 6d 75 74 65 78 2e 20 20 55 73 65 20   no mutex.  Use 
2630: 6d 75 74 65 78 20 62 65 6c 6f 77 20 66 6f 72 20  mutex below for 
2640: 76 61 72 69 61 62 6c 65 20 74 68 61 74 20 66 6f  variable that fo
2650: 6c 6c 6f 77 2e 20 2a 2f 0a 20 20 73 71 6c 69 74  llow. */.  sqlit
2660: 65 33 5f 6d 75 74 65 78 20 2a 6d 75 74 65 78 3b  e3_mutex *mutex;
2670: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 75 74            /* Mut
2680: 65 78 20 66 6f 72 20 61 63 63 65 73 73 69 6e 67  ex for accessing
2690: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 3a 20   the following: 
26a0: 2a 2f 0a 20 20 50 67 46 72 65 65 73 6c 6f 74 20  */.  PgFreeslot 
26b0: 2a 70 46 72 65 65 3b 20 20 20 20 20 20 20 20 20  *pFree;         
26c0: 20 20 20 20 2f 2a 20 46 72 65 65 20 70 61 67 65      /* Free page
26d0: 20 62 6c 6f 63 6b 73 20 2a 2f 0a 20 20 69 6e 74   blocks */.  int
26e0: 20 6e 46 72 65 65 53 6c 6f 74 3b 20 20 20 20 20   nFreeSlot;     
26f0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
2700: 75 6d 62 65 72 20 6f 66 20 75 6e 75 73 65 64 20  umber of unused 
2710: 70 63 61 63 68 65 20 73 6c 6f 74 73 20 2a 2f 0a  pcache slots */.
2720: 20 20 2f 2a 20 54 68 65 20 66 6f 6c 6c 6f 77 69    /* The followi
2730: 6e 67 20 76 61 6c 75 65 20 72 65 71 75 69 72 65  ng value require
2740: 73 20 61 20 6d 75 74 65 78 20 74 6f 20 63 68 61  s a mutex to cha
2750: 6e 67 65 2e 20 20 57 65 20 73 6b 69 70 20 74 68  nge.  We skip th
2760: 65 20 6d 75 74 65 78 20 6f 6e 0a 20 20 2a 2a 20  e mutex on.  ** 
2770: 72 65 61 64 69 6e 67 20 62 65 63 61 75 73 65 20  reading because 
2780: 28 31 29 20 6d 6f 73 74 20 70 6c 61 74 66 6f 72  (1) most platfor
2790: 6d 73 20 72 65 61 64 20 61 20 33 32 2d 62 69 74  ms read a 32-bit
27a0: 20 69 6e 74 65 67 65 72 20 61 74 6f 6d 69 63 61   integer atomica
27b0: 6c 6c 79 20 61 6e 64 0a 20 20 2a 2a 20 28 32 29  lly and.  ** (2)
27c0: 20 65 76 65 6e 20 69 66 20 61 6e 20 69 6e 63 6f   even if an inco
27d0: 72 72 65 63 74 20 76 61 6c 75 65 20 69 73 20 72  rrect value is r
27e0: 65 61 64 2c 20 6e 6f 20 67 72 65 61 74 20 68 61  ead, no great ha
27f0: 72 6d 20 69 73 20 64 6f 6e 65 20 73 69 6e 63 65  rm is done since
2800: 20 74 68 69 73 0a 20 20 2a 2a 20 69 73 20 72 65   this.  ** is re
2810: 61 6c 6c 79 20 6a 75 73 74 20 61 6e 20 6f 70 74  ally just an opt
2820: 69 6d 69 7a 61 74 69 6f 6e 2e 20 2a 2f 0a 20 20  imization. */.  
2830: 69 6e 74 20 62 55 6e 64 65 72 50 72 65 73 73 75  int bUnderPressu
2840: 72 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f  re;            /
2850: 2a 20 54 72 75 65 20 69 66 20 6c 6f 77 20 6f 6e  * True if low on
2860: 20 50 41 47 45 43 41 43 48 45 20 6d 65 6d 6f 72   PAGECACHE memor
2870: 79 20 2a 2f 0a 7d 20 70 63 61 63 68 65 31 5f 67  y */.} pcache1_g
2880: 3b 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c 20 63 6f 64  ;../*.** All cod
2890: 65 20 69 6e 20 74 68 69 73 20 66 69 6c 65 20 73  e in this file s
28a0: 68 6f 75 6c 64 20 61 63 63 65 73 73 20 74 68 65  hould access the
28b0: 20 67 6c 6f 62 61 6c 20 73 74 72 75 63 74 75 72   global structur
28c0: 65 20 61 62 6f 76 65 20 76 69 61 20 74 68 65 0a  e above via the.
28d0: 2a 2a 20 61 6c 69 61 73 20 22 70 63 61 63 68 65  ** alias "pcache
28e0: 31 22 2e 20 54 68 69 73 20 65 6e 73 75 72 65 73  1". This ensures
28f0: 20 74 68 61 74 20 74 68 65 20 57 53 44 20 65 6d   that the WSD em
2900: 75 6c 61 74 69 6f 6e 20 69 73 20 75 73 65 64 20  ulation is used 
2910: 77 68 65 6e 0a 2a 2a 20 63 6f 6d 70 69 6c 69 6e  when.** compilin
2920: 67 20 66 6f 72 20 73 79 73 74 65 6d 73 20 74 68  g for systems th
2930: 61 74 20 64 6f 20 6e 6f 74 20 73 75 70 70 6f 72  at do not suppor
2940: 74 20 72 65 61 6c 20 57 53 44 2e 0a 2a 2f 0a 23  t real WSD..*/.#
2950: 64 65 66 69 6e 65 20 70 63 61 63 68 65 31 20 28  define pcache1 (
2960: 47 4c 4f 42 41 4c 28 73 74 72 75 63 74 20 50 43  GLOBAL(struct PC
2970: 61 63 68 65 47 6c 6f 62 61 6c 2c 20 70 63 61 63  acheGlobal, pcac
2980: 68 65 31 5f 67 29 29 0a 0a 2f 2a 0a 2a 2a 20 4d  he1_g))../*.** M
2990: 61 63 72 6f 73 20 74 6f 20 65 6e 74 65 72 20 61  acros to enter a
29a0: 6e 64 20 6c 65 61 76 65 20 74 68 65 20 50 43 61  nd leave the PCa
29b0: 63 68 65 20 4c 52 55 20 6d 75 74 65 78 2e 0a 2a  che LRU mutex..*
29c0: 2f 0a 23 69 66 20 21 64 65 66 69 6e 65 64 28 53  /.#if !defined(S
29d0: 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d  QLITE_ENABLE_MEM
29e0: 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 29 20  ORY_MANAGEMENT) 
29f0: 7c 7c 20 53 51 4c 49 54 45 5f 54 48 52 45 41 44  || SQLITE_THREAD
2a00: 53 41 46 45 3d 3d 30 0a 23 20 64 65 66 69 6e 65  SAFE==0.# define
2a10: 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74   pcache1EnterMut
2a20: 65 78 28 58 29 20 20 61 73 73 65 72 74 28 28 58  ex(X)  assert((X
2a30: 29 2d 3e 6d 75 74 65 78 3d 3d 30 29 0a 23 20 64  )->mutex==0).# d
2a40: 65 66 69 6e 65 20 70 63 61 63 68 65 31 4c 65 61  efine pcache1Lea
2a50: 76 65 4d 75 74 65 78 28 58 29 20 20 61 73 73 65  veMutex(X)  asse
2a60: 72 74 28 28 58 29 2d 3e 6d 75 74 65 78 3d 3d 30  rt((X)->mutex==0
2a70: 29 0a 23 20 64 65 66 69 6e 65 20 50 43 41 43 48  ).# define PCACH
2a80: 45 31 5f 4d 49 47 48 54 5f 55 53 45 5f 47 52 4f  E1_MIGHT_USE_GRO
2a90: 55 50 5f 4d 55 54 45 58 20 30 0a 23 65 6c 73 65  UP_MUTEX 0.#else
2aa0: 0a 23 20 64 65 66 69 6e 65 20 70 63 61 63 68 65  .# define pcache
2ab0: 31 45 6e 74 65 72 4d 75 74 65 78 28 58 29 20 73  1EnterMutex(X) s
2ac0: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e 74  qlite3_mutex_ent
2ad0: 65 72 28 28 58 29 2d 3e 6d 75 74 65 78 29 0a 23  er((X)->mutex).#
2ae0: 20 64 65 66 69 6e 65 20 70 63 61 63 68 65 31 4c   define pcache1L
2af0: 65 61 76 65 4d 75 74 65 78 28 58 29 20 73 71 6c  eaveMutex(X) sql
2b00: 69 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65  ite3_mutex_leave
2b10: 28 28 58 29 2d 3e 6d 75 74 65 78 29 0a 23 20 64  ((X)->mutex).# d
2b20: 65 66 69 6e 65 20 50 43 41 43 48 45 31 5f 4d 49  efine PCACHE1_MI
2b30: 47 48 54 5f 55 53 45 5f 47 52 4f 55 50 5f 4d 55  GHT_USE_GROUP_MU
2b40: 54 45 58 20 31 0a 23 65 6e 64 69 66 0a 0a 2f 2a  TEX 1.#endif../*
2b50: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2b60: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2b70: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2b80: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2b90: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f  *************/./
2ba0: 2a 2a 2a 2a 2a 2a 2a 2a 20 50 61 67 65 20 41 6c  ******** Page Al
2bb0: 6c 6f 63 61 74 69 6f 6e 2f 53 51 4c 49 54 45 5f  location/SQLITE_
2bc0: 43 4f 4e 46 49 47 5f 50 43 41 43 48 45 20 52 65  CONFIG_PCACHE Re
2bd0: 6c 61 74 65 64 20 46 75 6e 63 74 69 6f 6e 73 20  lated Functions 
2be0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a  **************/.
2bf0: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e  ../*.** This fun
2c00: 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20  ction is called 
2c10: 64 75 72 69 6e 67 20 69 6e 69 74 69 61 6c 69 7a  during initializ
2c20: 61 74 69 6f 6e 20 69 66 20 61 20 73 74 61 74 69  ation if a stati
2c30: 63 20 62 75 66 66 65 72 20 69 73 20 0a 2a 2a 20  c buffer is .** 
2c40: 73 75 70 70 6c 69 65 64 20 74 6f 20 75 73 65 20  supplied to use 
2c50: 66 6f 72 20 74 68 65 20 70 61 67 65 2d 63 61 63  for the page-cac
2c60: 68 65 20 62 79 20 70 61 73 73 69 6e 67 20 74 68  he by passing th
2c70: 65 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f  e SQLITE_CONFIG_
2c80: 50 41 47 45 43 41 43 48 45 0a 2a 2a 20 76 65 72  PAGECACHE.** ver
2c90: 62 20 74 6f 20 73 71 6c 69 74 65 33 5f 63 6f 6e  b to sqlite3_con
2ca0: 66 69 67 28 29 2e 20 50 61 72 61 6d 65 74 65 72  fig(). Parameter
2cb0: 20 70 42 75 66 20 70 6f 69 6e 74 73 20 74 6f 20   pBuf points to 
2cc0: 61 6e 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 6c 61  an allocation la
2cd0: 72 67 65 0a 2a 2a 20 65 6e 6f 75 67 68 20 74 6f  rge.** enough to
2ce0: 20 63 6f 6e 74 61 69 6e 20 27 6e 27 20 62 75 66   contain 'n' buf
2cf0: 66 65 72 73 20 6f 66 20 27 73 7a 27 20 62 79 74  fers of 'sz' byt
2d00: 65 73 20 65 61 63 68 2e 0a 2a 2a 0a 2a 2a 20 54  es each..**.** T
2d10: 68 69 73 20 72 6f 75 74 69 6e 65 20 69 73 20 63  his routine is c
2d20: 61 6c 6c 65 64 20 66 72 6f 6d 20 73 71 6c 69 74  alled from sqlit
2d30: 65 33 5f 69 6e 69 74 69 61 6c 69 7a 65 28 29 20  e3_initialize() 
2d40: 61 6e 64 20 73 6f 20 69 74 20 69 73 20 67 75 61  and so it is gua
2d50: 72 61 6e 74 65 65 64 0a 2a 2a 20 74 6f 20 62 65  ranteed.** to be
2d60: 20 73 65 72 69 61 6c 69 7a 65 64 20 61 6c 72 65   serialized alre
2d70: 61 64 79 2e 20 20 54 68 65 72 65 20 69 73 20 6e  ady.  There is n
2d80: 6f 20 6e 65 65 64 20 66 6f 72 20 66 75 72 74 68  o need for furth
2d90: 65 72 20 6d 75 74 65 78 69 6e 67 2e 0a 2a 2f 0a  er mutexing..*/.
2da0: 76 6f 69 64 20 73 71 6c 69 74 65 33 50 43 61 63  void sqlite3PCac
2db0: 68 65 42 75 66 66 65 72 53 65 74 75 70 28 76 6f  heBufferSetup(vo
2dc0: 69 64 20 2a 70 42 75 66 2c 20 69 6e 74 20 73 7a  id *pBuf, int sz
2dd0: 2c 20 69 6e 74 20 6e 29 7b 0a 20 20 69 66 28 20  , int n){.  if( 
2de0: 70 63 61 63 68 65 31 2e 69 73 49 6e 69 74 20 29  pcache1.isInit )
2df0: 7b 0a 20 20 20 20 50 67 46 72 65 65 73 6c 6f 74  {.    PgFreeslot
2e00: 20 2a 70 3b 0a 20 20 20 20 69 66 28 20 70 42 75   *p;.    if( pBu
2e10: 66 3d 3d 30 20 29 20 73 7a 20 3d 20 6e 20 3d 20  f==0 ) sz = n = 
2e20: 30 3b 0a 20 20 20 20 69 66 28 20 6e 3d 3d 30 20  0;.    if( n==0 
2e30: 29 20 73 7a 20 3d 20 30 3b 0a 20 20 20 20 73 7a  ) sz = 0;.    sz
2e40: 20 3d 20 52 4f 55 4e 44 44 4f 57 4e 38 28 73 7a   = ROUNDDOWN8(sz
2e50: 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 73  );.    pcache1.s
2e60: 7a 53 6c 6f 74 20 3d 20 73 7a 3b 0a 20 20 20 20  zSlot = sz;.    
2e70: 70 63 61 63 68 65 31 2e 6e 53 6c 6f 74 20 3d 20  pcache1.nSlot = 
2e80: 70 63 61 63 68 65 31 2e 6e 46 72 65 65 53 6c 6f  pcache1.nFreeSlo
2e90: 74 20 3d 20 6e 3b 0a 20 20 20 20 70 63 61 63 68  t = n;.    pcach
2ea0: 65 31 2e 6e 52 65 73 65 72 76 65 20 3d 20 6e 3e  e1.nReserve = n>
2eb0: 39 30 20 3f 20 31 30 20 3a 20 28 6e 2f 31 30 20  90 ? 10 : (n/10 
2ec0: 2b 20 31 29 3b 0a 20 20 20 20 70 63 61 63 68 65  + 1);.    pcache
2ed0: 31 2e 70 53 74 61 72 74 20 3d 20 70 42 75 66 3b  1.pStart = pBuf;
2ee0: 0a 20 20 20 20 70 63 61 63 68 65 31 2e 70 46 72  .    pcache1.pFr
2ef0: 65 65 20 3d 20 30 3b 0a 20 20 20 20 70 63 61 63  ee = 0;.    pcac
2f00: 68 65 31 2e 62 55 6e 64 65 72 50 72 65 73 73 75  he1.bUnderPressu
2f10: 72 65 20 3d 20 30 3b 0a 20 20 20 20 77 68 69 6c  re = 0;.    whil
2f20: 65 28 20 6e 2d 2d 20 29 7b 0a 20 20 20 20 20 20  e( n-- ){.      
2f30: 70 20 3d 20 28 50 67 46 72 65 65 73 6c 6f 74 2a  p = (PgFreeslot*
2f40: 29 70 42 75 66 3b 0a 20 20 20 20 20 20 70 2d 3e  )pBuf;.      p->
2f50: 70 4e 65 78 74 20 3d 20 70 63 61 63 68 65 31 2e  pNext = pcache1.
2f60: 70 46 72 65 65 3b 0a 20 20 20 20 20 20 70 63 61  pFree;.      pca
2f70: 63 68 65 31 2e 70 46 72 65 65 20 3d 20 70 3b 0a  che1.pFree = p;.
2f80: 20 20 20 20 20 20 70 42 75 66 20 3d 20 28 76 6f        pBuf = (vo
2f90: 69 64 2a 29 26 28 28 63 68 61 72 2a 29 70 42 75  id*)&((char*)pBu
2fa0: 66 29 5b 73 7a 5d 3b 0a 20 20 20 20 7d 0a 20 20  f)[sz];.    }.  
2fb0: 20 20 70 63 61 63 68 65 31 2e 70 45 6e 64 20 3d    pcache1.pEnd =
2fc0: 20 70 42 75 66 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a   pBuf;.  }.}../*
2fd0: 0a 2a 2a 20 54 72 79 20 74 6f 20 69 6e 69 74 69  .** Try to initi
2fe0: 61 6c 69 7a 65 20 74 68 65 20 70 43 61 63 68 65  alize the pCache
2ff0: 2d 3e 70 46 72 65 65 20 61 6e 64 20 70 43 61 63  ->pFree and pCac
3000: 68 65 2d 3e 70 42 75 6c 6b 20 66 69 65 6c 64 73  he->pBulk fields
3010: 2e 20 20 52 65 74 75 72 6e 0a 2a 2a 20 74 72 75  .  Return.** tru
3020: 65 20 69 66 20 70 43 61 63 68 65 2d 3e 70 46 72  e if pCache->pFr
3030: 65 65 20 65 6e 64 73 20 75 70 20 63 6f 6e 74 61  ee ends up conta
3040: 69 6e 69 6e 67 20 6f 6e 65 20 6f 72 20 6d 6f 72  ining one or mor
3050: 65 20 66 72 65 65 20 70 61 67 65 73 2e 0a 2a 2f  e free pages..*/
3060: 0a 73 74 61 74 69 63 20 69 6e 74 20 70 63 61 63  .static int pcac
3070: 68 65 31 49 6e 69 74 42 75 6c 6b 28 50 43 61 63  he1InitBulk(PCac
3080: 68 65 31 20 2a 70 43 61 63 68 65 29 7b 0a 20 20  he1 *pCache){.  
3090: 69 36 34 20 73 7a 42 75 6c 6b 3b 0a 20 20 63 68  i64 szBulk;.  ch
30a0: 61 72 20 2a 7a 42 75 6c 6b 3b 0a 20 20 69 66 28  ar *zBulk;.  if(
30b0: 20 70 63 61 63 68 65 31 2e 6e 49 6e 69 74 50 61   pcache1.nInitPa
30c0: 67 65 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 30  ge==0 ) return 0
30d0: 3b 0a 20 20 2f 2a 20 44 6f 20 6e 6f 74 20 62 6f  ;.  /* Do not bo
30e0: 74 68 65 72 20 77 69 74 68 20 61 20 62 75 6c 6b  ther with a bulk
30f0: 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 69 66 20 74   allocation if t
3100: 68 65 20 63 61 63 68 65 20 73 69 7a 65 20 76 65  he cache size ve
3110: 72 79 20 73 6d 61 6c 6c 20 2a 2f 0a 20 20 69 66  ry small */.  if
3120: 28 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 3c 33  ( pCache->nMax<3
3130: 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 73   ) return 0;.  s
3140: 71 6c 69 74 65 33 42 65 67 69 6e 42 65 6e 69 67  qlite3BeginBenig
3150: 6e 4d 61 6c 6c 6f 63 28 29 3b 0a 20 20 69 66 28  nMalloc();.  if(
3160: 20 70 63 61 63 68 65 31 2e 6e 49 6e 69 74 50 61   pcache1.nInitPa
3170: 67 65 3e 30 20 29 7b 0a 20 20 20 20 73 7a 42 75  ge>0 ){.    szBu
3180: 6c 6b 20 3d 20 70 43 61 63 68 65 2d 3e 73 7a 41  lk = pCache->szA
3190: 6c 6c 6f 63 20 2a 20 28 69 36 34 29 70 63 61 63  lloc * (i64)pcac
31a0: 68 65 31 2e 6e 49 6e 69 74 50 61 67 65 3b 0a 20  he1.nInitPage;. 
31b0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 73 7a 42 75   }else{.    szBu
31c0: 6c 6b 20 3d 20 2d 31 30 32 34 20 2a 20 28 69 36  lk = -1024 * (i6
31d0: 34 29 70 63 61 63 68 65 31 2e 6e 49 6e 69 74 50  4)pcache1.nInitP
31e0: 61 67 65 3b 0a 20 20 7d 0a 20 20 69 66 28 20 73  age;.  }.  if( s
31f0: 7a 42 75 6c 6b 20 3e 20 70 43 61 63 68 65 2d 3e  zBulk > pCache->
3200: 73 7a 41 6c 6c 6f 63 2a 28 69 36 34 29 70 43 61  szAlloc*(i64)pCa
3210: 63 68 65 2d 3e 6e 4d 61 78 20 29 7b 0a 20 20 20  che->nMax ){.   
3220: 20 73 7a 42 75 6c 6b 20 3d 20 70 43 61 63 68 65   szBulk = pCache
3230: 2d 3e 73 7a 41 6c 6c 6f 63 2a 28 69 36 34 29 70  ->szAlloc*(i64)p
3240: 43 61 63 68 65 2d 3e 6e 4d 61 78 3b 0a 20 20 7d  Cache->nMax;.  }
3250: 0a 20 20 7a 42 75 6c 6b 20 3d 20 70 43 61 63 68  .  zBulk = pCach
3260: 65 2d 3e 70 42 75 6c 6b 20 3d 20 73 71 6c 69 74  e->pBulk = sqlit
3270: 65 33 4d 61 6c 6c 6f 63 28 20 73 7a 42 75 6c 6b  e3Malloc( szBulk
3280: 20 29 3b 0a 20 20 73 71 6c 69 74 65 33 45 6e 64   );.  sqlite3End
3290: 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 0a  BenignMalloc();.
32a0: 20 20 69 66 28 20 7a 42 75 6c 6b 20 29 7b 0a 20    if( zBulk ){. 
32b0: 20 20 20 69 6e 74 20 6e 42 75 6c 6b 20 3d 20 73     int nBulk = s
32c0: 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 53 69 7a 65  qlite3MallocSize
32d0: 28 7a 42 75 6c 6b 29 2f 70 43 61 63 68 65 2d 3e  (zBulk)/pCache->
32e0: 73 7a 41 6c 6c 6f 63 3b 0a 20 20 20 20 64 6f 7b  szAlloc;.    do{
32f0: 0a 20 20 20 20 20 20 50 67 48 64 72 31 20 2a 70  .      PgHdr1 *p
3300: 58 20 3d 20 28 50 67 48 64 72 31 2a 29 26 7a 42  X = (PgHdr1*)&zB
3310: 75 6c 6b 5b 70 43 61 63 68 65 2d 3e 73 7a 50 61  ulk[pCache->szPa
3320: 67 65 5d 3b 0a 20 20 20 20 20 20 70 58 2d 3e 70  ge];.      pX->p
3330: 61 67 65 2e 70 42 75 66 20 3d 20 7a 42 75 6c 6b  age.pBuf = zBulk
3340: 3b 0a 20 20 20 20 20 20 70 58 2d 3e 70 61 67 65  ;.      pX->page
3350: 2e 70 45 78 74 72 61 20 3d 20 26 70 58 5b 31 5d  .pExtra = &pX[1]
3360: 3b 0a 20 20 20 20 20 20 70 58 2d 3e 69 73 42 75  ;.      pX->isBu
3370: 6c 6b 4c 6f 63 61 6c 20 3d 20 31 3b 0a 20 20 20  lkLocal = 1;.   
3380: 20 20 20 70 58 2d 3e 69 73 41 6e 63 68 6f 72 20     pX->isAnchor 
3390: 3d 20 30 3b 0a 20 20 20 20 20 20 70 58 2d 3e 70  = 0;.      pX->p
33a0: 4e 65 78 74 20 3d 20 70 43 61 63 68 65 2d 3e 70  Next = pCache->p
33b0: 46 72 65 65 3b 0a 20 20 20 20 20 20 70 43 61 63  Free;.      pCac
33c0: 68 65 2d 3e 70 46 72 65 65 20 3d 20 70 58 3b 0a  he->pFree = pX;.
33d0: 20 20 20 20 20 20 7a 42 75 6c 6b 20 2b 3d 20 70        zBulk += p
33e0: 43 61 63 68 65 2d 3e 73 7a 41 6c 6c 6f 63 3b 0a  Cache->szAlloc;.
33f0: 20 20 20 20 7d 77 68 69 6c 65 28 20 2d 2d 6e 42      }while( --nB
3400: 75 6c 6b 20 29 3b 0a 20 20 7d 0a 20 20 72 65 74  ulk );.  }.  ret
3410: 75 72 6e 20 70 43 61 63 68 65 2d 3e 70 46 72 65  urn pCache->pFre
3420: 65 21 3d 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d  e!=0;.}../*.** M
3430: 61 6c 6c 6f 63 20 66 75 6e 63 74 69 6f 6e 20 75  alloc function u
3440: 73 65 64 20 77 69 74 68 69 6e 20 74 68 69 73 20  sed within this 
3450: 66 69 6c 65 20 74 6f 20 61 6c 6c 6f 63 61 74 65  file to allocate
3460: 20 73 70 61 63 65 20 66 72 6f 6d 20 74 68 65 20   space from the 
3470: 62 75 66 66 65 72 0a 2a 2a 20 63 6f 6e 66 69 67  buffer.** config
3480: 75 72 65 64 20 75 73 69 6e 67 20 73 71 6c 69 74  ured using sqlit
3490: 65 33 5f 63 6f 6e 66 69 67 28 53 51 4c 49 54 45  e3_config(SQLITE
34a0: 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48  _CONFIG_PAGECACH
34b0: 45 29 20 6f 70 74 69 6f 6e 2e 20 49 66 20 6e 6f  E) option. If no
34c0: 20 0a 2a 2a 20 73 75 63 68 20 62 75 66 66 65 72   .** such buffer
34d0: 20 65 78 69 73 74 73 20 6f 72 20 74 68 65 72 65   exists or there
34e0: 20 69 73 20 6e 6f 20 73 70 61 63 65 20 6c 65 66   is no space lef
34f0: 74 20 69 6e 20 69 74 2c 20 74 68 69 73 20 66 75  t in it, this fu
3500: 6e 63 74 69 6f 6e 20 66 61 6c 6c 73 20 0a 2a 2a  nction falls .**
3510: 20 62 61 63 6b 20 74 6f 20 73 71 6c 69 74 65 33   back to sqlite3
3520: 4d 61 6c 6c 6f 63 28 29 2e 0a 2a 2a 0a 2a 2a 20  Malloc()..**.** 
3530: 4d 75 6c 74 69 70 6c 65 20 74 68 72 65 61 64 73  Multiple threads
3540: 20 63 61 6e 20 72 75 6e 20 74 68 69 73 20 72 6f   can run this ro
3550: 75 74 69 6e 65 20 61 74 20 74 68 65 20 73 61 6d  utine at the sam
3560: 65 20 74 69 6d 65 2e 20 20 47 6c 6f 62 61 6c 20  e time.  Global 
3570: 76 61 72 69 61 62 6c 65 73 0a 2a 2a 20 69 6e 20  variables.** in 
3580: 70 63 61 63 68 65 31 20 6e 65 65 64 20 74 6f 20  pcache1 need to 
3590: 62 65 20 70 72 6f 74 65 63 74 65 64 20 76 69 61  be protected via
35a0: 20 6d 75 74 65 78 2e 0a 2a 2f 0a 73 74 61 74 69   mutex..*/.stati
35b0: 63 20 76 6f 69 64 20 2a 70 63 61 63 68 65 31 41  c void *pcache1A
35c0: 6c 6c 6f 63 28 69 6e 74 20 6e 42 79 74 65 29 7b  lloc(int nByte){
35d0: 0a 20 20 76 6f 69 64 20 2a 70 20 3d 20 30 3b 0a  .  void *p = 0;.
35e0: 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65    assert( sqlite
35f0: 33 5f 6d 75 74 65 78 5f 6e 6f 74 68 65 6c 64 28  3_mutex_notheld(
3600: 70 63 61 63 68 65 31 2e 67 72 70 2e 6d 75 74 65  pcache1.grp.mute
3610: 78 29 20 29 3b 0a 20 20 69 66 28 20 6e 42 79 74  x) );.  if( nByt
3620: 65 3c 3d 70 63 61 63 68 65 31 2e 73 7a 53 6c 6f  e<=pcache1.szSlo
3630: 74 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33  t ){.    sqlite3
3640: 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28 70 63 61  _mutex_enter(pca
3650: 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a 20 20 20  che1.mutex);.   
3660: 20 70 20 3d 20 28 50 67 48 64 72 31 20 2a 29 70   p = (PgHdr1 *)p
3670: 63 61 63 68 65 31 2e 70 46 72 65 65 3b 0a 20 20  cache1.pFree;.  
3680: 20 20 69 66 28 20 70 20 29 7b 0a 20 20 20 20 20    if( p ){.     
3690: 20 70 63 61 63 68 65 31 2e 70 46 72 65 65 20 3d   pcache1.pFree =
36a0: 20 70 63 61 63 68 65 31 2e 70 46 72 65 65 2d 3e   pcache1.pFree->
36b0: 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 70 63 61  pNext;.      pca
36c0: 63 68 65 31 2e 6e 46 72 65 65 53 6c 6f 74 2d 2d  che1.nFreeSlot--
36d0: 3b 0a 20 20 20 20 20 20 70 63 61 63 68 65 31 2e  ;.      pcache1.
36e0: 62 55 6e 64 65 72 50 72 65 73 73 75 72 65 20 3d  bUnderPressure =
36f0: 20 70 63 61 63 68 65 31 2e 6e 46 72 65 65 53 6c   pcache1.nFreeSl
3700: 6f 74 3c 70 63 61 63 68 65 31 2e 6e 52 65 73 65  ot<pcache1.nRese
3710: 72 76 65 3b 0a 20 20 20 20 20 20 61 73 73 65 72  rve;.      asser
3720: 74 28 20 70 63 61 63 68 65 31 2e 6e 46 72 65 65  t( pcache1.nFree
3730: 53 6c 6f 74 3e 3d 30 20 29 3b 0a 20 20 20 20 20  Slot>=0 );.     
3740: 20 73 71 6c 69 74 65 33 53 74 61 74 75 73 48 69   sqlite3StatusHi
3750: 67 68 77 61 74 65 72 28 53 51 4c 49 54 45 5f 53  ghwater(SQLITE_S
3760: 54 41 54 55 53 5f 50 41 47 45 43 41 43 48 45 5f  TATUS_PAGECACHE_
3770: 53 49 5a 45 2c 20 6e 42 79 74 65 29 3b 0a 20 20  SIZE, nByte);.  
3780: 20 20 20 20 73 71 6c 69 74 65 33 53 74 61 74 75      sqlite3Statu
3790: 73 55 70 28 53 51 4c 49 54 45 5f 53 54 41 54 55  sUp(SQLITE_STATU
37a0: 53 5f 50 41 47 45 43 41 43 48 45 5f 55 53 45 44  S_PAGECACHE_USED
37b0: 2c 20 31 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20  , 1);.    }.    
37c0: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6c 65  sqlite3_mutex_le
37d0: 61 76 65 28 70 63 61 63 68 65 31 2e 6d 75 74 65  ave(pcache1.mute
37e0: 78 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 3d  x);.  }.  if( p=
37f0: 3d 30 20 29 7b 0a 20 20 20 20 2f 2a 20 4d 65 6d  =0 ){.    /* Mem
3800: 6f 72 79 20 69 73 20 6e 6f 74 20 61 76 61 69 6c  ory is not avail
3810: 61 62 6c 65 20 69 6e 20 74 68 65 20 53 51 4c 49  able in the SQLI
3820: 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41  TE_CONFIG_PAGECA
3830: 43 48 45 20 70 6f 6f 6c 2e 20 20 47 65 74 0a 20  CHE pool.  Get. 
3840: 20 20 20 2a 2a 20 69 74 20 66 72 6f 6d 20 73 71     ** it from sq
3850: 6c 69 74 65 33 4d 61 6c 6c 6f 63 20 69 6e 73 74  lite3Malloc inst
3860: 65 61 64 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20  ead..    */.    
3870: 70 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f  p = sqlite3Mallo
3880: 63 28 6e 42 79 74 65 29 3b 0a 23 69 66 6e 64 65  c(nByte);.#ifnde
3890: 66 20 53 51 4c 49 54 45 5f 44 49 53 41 42 4c 45  f SQLITE_DISABLE
38a0: 5f 50 41 47 45 43 41 43 48 45 5f 4f 56 45 52 46  _PAGECACHE_OVERF
38b0: 4c 4f 57 5f 53 54 41 54 53 0a 20 20 20 20 69 66  LOW_STATS.    if
38c0: 28 20 70 20 29 7b 0a 20 20 20 20 20 20 69 6e 74  ( p ){.      int
38d0: 20 73 7a 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c   sz = sqlite3Mal
38e0: 6c 6f 63 53 69 7a 65 28 70 29 3b 0a 20 20 20 20  locSize(p);.    
38f0: 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f    sqlite3_mutex_
3900: 65 6e 74 65 72 28 70 63 61 63 68 65 31 2e 6d 75  enter(pcache1.mu
3910: 74 65 78 29 3b 0a 20 20 20 20 20 20 73 71 6c 69  tex);.      sqli
3920: 74 65 33 53 74 61 74 75 73 48 69 67 68 77 61 74  te3StatusHighwat
3930: 65 72 28 53 51 4c 49 54 45 5f 53 54 41 54 55 53  er(SQLITE_STATUS
3940: 5f 50 41 47 45 43 41 43 48 45 5f 53 49 5a 45 2c  _PAGECACHE_SIZE,
3950: 20 6e 42 79 74 65 29 3b 0a 20 20 20 20 20 20 73   nByte);.      s
3960: 71 6c 69 74 65 33 53 74 61 74 75 73 55 70 28 53  qlite3StatusUp(S
3970: 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41 47  QLITE_STATUS_PAG
3980: 45 43 41 43 48 45 5f 4f 56 45 52 46 4c 4f 57 2c  ECACHE_OVERFLOW,
3990: 20 73 7a 29 3b 0a 20 20 20 20 20 20 73 71 6c 69   sz);.      sqli
39a0: 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28  te3_mutex_leave(
39b0: 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a  pcache1.mutex);.
39c0: 20 20 20 20 7d 0a 23 65 6e 64 69 66 0a 20 20 20      }.#endif.   
39d0: 20 73 71 6c 69 74 65 33 4d 65 6d 64 65 62 75 67   sqlite3Memdebug
39e0: 53 65 74 54 79 70 65 28 70 2c 20 4d 45 4d 54 59  SetType(p, MEMTY
39f0: 50 45 5f 50 43 41 43 48 45 29 3b 0a 20 20 7d 0a  PE_PCACHE);.  }.
3a00: 20 20 72 65 74 75 72 6e 20 70 3b 0a 7d 0a 0a 2f    return p;.}../
3a10: 2a 0a 2a 2a 20 46 72 65 65 20 61 6e 20 61 6c 6c  *.** Free an all
3a20: 6f 63 61 74 65 64 20 62 75 66 66 65 72 20 6f 62  ocated buffer ob
3a30: 74 61 69 6e 65 64 20 66 72 6f 6d 20 70 63 61 63  tained from pcac
3a40: 68 65 31 41 6c 6c 6f 63 28 29 2e 0a 2a 2f 0a 73  he1Alloc()..*/.s
3a50: 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68  tatic void pcach
3a60: 65 31 46 72 65 65 28 76 6f 69 64 20 2a 70 29 7b  e1Free(void *p){
3a70: 0a 20 20 69 66 28 20 70 3d 3d 30 20 29 20 72 65  .  if( p==0 ) re
3a80: 74 75 72 6e 3b 0a 20 20 69 66 28 20 53 51 4c 49  turn;.  if( SQLI
3a90: 54 45 5f 57 49 54 48 49 4e 28 70 2c 20 70 63 61  TE_WITHIN(p, pca
3aa0: 63 68 65 31 2e 70 53 74 61 72 74 2c 20 70 63 61  che1.pStart, pca
3ab0: 63 68 65 31 2e 70 45 6e 64 29 20 29 7b 0a 20 20  che1.pEnd) ){.  
3ac0: 20 20 50 67 46 72 65 65 73 6c 6f 74 20 2a 70 53    PgFreeslot *pS
3ad0: 6c 6f 74 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  lot;.    sqlite3
3ae0: 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28 70 63 61  _mutex_enter(pca
3af0: 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a 20 20 20  che1.mutex);.   
3b00: 20 73 71 6c 69 74 65 33 53 74 61 74 75 73 44 6f   sqlite3StatusDo
3b10: 77 6e 28 53 51 4c 49 54 45 5f 53 54 41 54 55 53  wn(SQLITE_STATUS
3b20: 5f 50 41 47 45 43 41 43 48 45 5f 55 53 45 44 2c  _PAGECACHE_USED,
3b30: 20 31 29 3b 0a 20 20 20 20 70 53 6c 6f 74 20 3d   1);.    pSlot =
3b40: 20 28 50 67 46 72 65 65 73 6c 6f 74 2a 29 70 3b   (PgFreeslot*)p;
3b50: 0a 20 20 20 20 70 53 6c 6f 74 2d 3e 70 4e 65 78  .    pSlot->pNex
3b60: 74 20 3d 20 70 63 61 63 68 65 31 2e 70 46 72 65  t = pcache1.pFre
3b70: 65 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 70  e;.    pcache1.p
3b80: 46 72 65 65 20 3d 20 70 53 6c 6f 74 3b 0a 20 20  Free = pSlot;.  
3b90: 20 20 70 63 61 63 68 65 31 2e 6e 46 72 65 65 53    pcache1.nFreeS
3ba0: 6c 6f 74 2b 2b 3b 0a 20 20 20 20 70 63 61 63 68  lot++;.    pcach
3bb0: 65 31 2e 62 55 6e 64 65 72 50 72 65 73 73 75 72  e1.bUnderPressur
3bc0: 65 20 3d 20 70 63 61 63 68 65 31 2e 6e 46 72 65  e = pcache1.nFre
3bd0: 65 53 6c 6f 74 3c 70 63 61 63 68 65 31 2e 6e 52  eSlot<pcache1.nR
3be0: 65 73 65 72 76 65 3b 0a 20 20 20 20 61 73 73 65  eserve;.    asse
3bf0: 72 74 28 20 70 63 61 63 68 65 31 2e 6e 46 72 65  rt( pcache1.nFre
3c00: 65 53 6c 6f 74 3c 3d 70 63 61 63 68 65 31 2e 6e  eSlot<=pcache1.n
3c10: 53 6c 6f 74 20 29 3b 0a 20 20 20 20 73 71 6c 69  Slot );.    sqli
3c20: 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28  te3_mutex_leave(
3c30: 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a  pcache1.mutex);.
3c40: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 61 73 73    }else{.    ass
3c50: 65 72 74 28 20 73 71 6c 69 74 65 33 4d 65 6d 64  ert( sqlite3Memd
3c60: 65 62 75 67 48 61 73 54 79 70 65 28 70 2c 20 4d  ebugHasType(p, M
3c70: 45 4d 54 59 50 45 5f 50 43 41 43 48 45 29 20 29  EMTYPE_PCACHE) )
3c80: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 4d 65 6d  ;.    sqlite3Mem
3c90: 64 65 62 75 67 53 65 74 54 79 70 65 28 70 2c 20  debugSetType(p, 
3ca0: 4d 45 4d 54 59 50 45 5f 48 45 41 50 29 3b 0a 23  MEMTYPE_HEAP);.#
3cb0: 69 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 44 49  ifndef SQLITE_DI
3cc0: 53 41 42 4c 45 5f 50 41 47 45 43 41 43 48 45 5f  SABLE_PAGECACHE_
3cd0: 4f 56 45 52 46 4c 4f 57 5f 53 54 41 54 53 0a 20  OVERFLOW_STATS. 
3ce0: 20 20 20 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e     {.      int n
3cf0: 46 72 65 65 64 20 3d 20 73 71 6c 69 74 65 33 4d  Freed = sqlite3M
3d00: 61 6c 6c 6f 63 53 69 7a 65 28 70 29 3b 0a 20 20  allocSize(p);.  
3d10: 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65      sqlite3_mute
3d20: 78 5f 65 6e 74 65 72 28 70 63 61 63 68 65 31 2e  x_enter(pcache1.
3d30: 6d 75 74 65 78 29 3b 0a 20 20 20 20 20 20 73 71  mutex);.      sq
3d40: 6c 69 74 65 33 53 74 61 74 75 73 44 6f 77 6e 28  lite3StatusDown(
3d50: 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41  SQLITE_STATUS_PA
3d60: 47 45 43 41 43 48 45 5f 4f 56 45 52 46 4c 4f 57  GECACHE_OVERFLOW
3d70: 2c 20 6e 46 72 65 65 64 29 3b 0a 20 20 20 20 20  , nFreed);.     
3d80: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6c   sqlite3_mutex_l
3d90: 65 61 76 65 28 70 63 61 63 68 65 31 2e 6d 75 74  eave(pcache1.mut
3da0: 65 78 29 3b 0a 20 20 20 20 7d 0a 23 65 6e 64 69  ex);.    }.#endi
3db0: 66 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72  f.    sqlite3_fr
3dc0: 65 65 28 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 23 69  ee(p);.  }.}..#i
3dd0: 66 64 65 66 20 53 51 4c 49 54 45 5f 45 4e 41 42  fdef SQLITE_ENAB
3de0: 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47 45  LE_MEMORY_MANAGE
3df0: 4d 45 4e 54 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72  MENT./*.** Retur
3e00: 6e 20 74 68 65 20 73 69 7a 65 20 6f 66 20 61 20  n the size of a 
3e10: 70 63 61 63 68 65 20 61 6c 6c 6f 63 61 74 69 6f  pcache allocatio
3e20: 6e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  n.*/.static int 
3e30: 70 63 61 63 68 65 31 4d 65 6d 53 69 7a 65 28 76  pcache1MemSize(v
3e40: 6f 69 64 20 2a 70 29 7b 0a 20 20 69 66 28 20 70  oid *p){.  if( p
3e50: 3e 3d 70 63 61 63 68 65 31 2e 70 53 74 61 72 74  >=pcache1.pStart
3e60: 20 26 26 20 70 3c 70 63 61 63 68 65 31 2e 70 45   && p<pcache1.pE
3e70: 6e 64 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  nd ){.    return
3e80: 20 70 63 61 63 68 65 31 2e 73 7a 53 6c 6f 74 3b   pcache1.szSlot;
3e90: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 6e  .  }else{.    in
3ea0: 74 20 69 53 69 7a 65 3b 0a 20 20 20 20 61 73 73  t iSize;.    ass
3eb0: 65 72 74 28 20 73 71 6c 69 74 65 33 4d 65 6d 64  ert( sqlite3Memd
3ec0: 65 62 75 67 48 61 73 54 79 70 65 28 70 2c 20 4d  ebugHasType(p, M
3ed0: 45 4d 54 59 50 45 5f 50 43 41 43 48 45 29 20 29  EMTYPE_PCACHE) )
3ee0: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 4d 65 6d  ;.    sqlite3Mem
3ef0: 64 65 62 75 67 53 65 74 54 79 70 65 28 70 2c 20  debugSetType(p, 
3f00: 4d 45 4d 54 59 50 45 5f 48 45 41 50 29 3b 0a 20  MEMTYPE_HEAP);. 
3f10: 20 20 20 69 53 69 7a 65 20 3d 20 73 71 6c 69 74     iSize = sqlit
3f20: 65 33 4d 61 6c 6c 6f 63 53 69 7a 65 28 70 29 3b  e3MallocSize(p);
3f30: 0a 20 20 20 20 73 71 6c 69 74 65 33 4d 65 6d 64  .    sqlite3Memd
3f40: 65 62 75 67 53 65 74 54 79 70 65 28 70 2c 20 4d  ebugSetType(p, M
3f50: 45 4d 54 59 50 45 5f 50 43 41 43 48 45 29 3b 0a  EMTYPE_PCACHE);.
3f60: 20 20 20 20 72 65 74 75 72 6e 20 69 53 69 7a 65      return iSize
3f70: 3b 0a 20 20 7d 0a 7d 0a 23 65 6e 64 69 66 20 2f  ;.  }.}.#endif /
3f80: 2a 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f  * SQLITE_ENABLE_
3f90: 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e  MEMORY_MANAGEMEN
3fa0: 54 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c 6f  T */../*.** Allo
3fb0: 63 61 74 65 20 61 20 6e 65 77 20 70 61 67 65 20  cate a new page 
3fc0: 6f 62 6a 65 63 74 20 69 6e 69 74 69 61 6c 6c 79  object initially
3fd0: 20 61 73 73 6f 63 69 61 74 65 64 20 77 69 74 68   associated with
3fe0: 20 63 61 63 68 65 20 70 43 61 63 68 65 2e 0a 2a   cache pCache..*
3ff0: 2f 0a 73 74 61 74 69 63 20 50 67 48 64 72 31 20  /.static PgHdr1 
4000: 2a 70 63 61 63 68 65 31 41 6c 6c 6f 63 50 61 67  *pcache1AllocPag
4010: 65 28 50 43 61 63 68 65 31 20 2a 70 43 61 63 68  e(PCache1 *pCach
4020: 65 2c 20 69 6e 74 20 62 65 6e 69 67 6e 4d 61 6c  e, int benignMal
4030: 6c 6f 63 29 7b 0a 20 20 50 67 48 64 72 31 20 2a  loc){.  PgHdr1 *
4040: 70 20 3d 20 30 3b 0a 20 20 76 6f 69 64 20 2a 70  p = 0;.  void *p
4050: 50 67 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 73  Pg;..  assert( s
4060: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c  qlite3_mutex_hel
4070: 64 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70  d(pCache->pGroup
4080: 2d 3e 6d 75 74 65 78 29 20 29 3b 0a 20 20 69 66  ->mutex) );.  if
4090: 28 20 70 43 61 63 68 65 2d 3e 70 46 72 65 65 20  ( pCache->pFree 
40a0: 7c 7c 20 28 70 43 61 63 68 65 2d 3e 6e 50 61 67  || (pCache->nPag
40b0: 65 3d 3d 30 20 26 26 20 70 63 61 63 68 65 31 49  e==0 && pcache1I
40c0: 6e 69 74 42 75 6c 6b 28 70 43 61 63 68 65 29 29  nitBulk(pCache))
40d0: 20 29 7b 0a 20 20 20 20 70 20 3d 20 70 43 61 63   ){.    p = pCac
40e0: 68 65 2d 3e 70 46 72 65 65 3b 0a 20 20 20 20 70  he->pFree;.    p
40f0: 43 61 63 68 65 2d 3e 70 46 72 65 65 20 3d 20 70  Cache->pFree = p
4100: 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 70 2d 3e  ->pNext;.    p->
4110: 70 4e 65 78 74 20 3d 20 30 3b 0a 20 20 7d 65 6c  pNext = 0;.  }el
4120: 73 65 7b 0a 23 69 66 64 65 66 20 53 51 4c 49 54  se{.#ifdef SQLIT
4130: 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f  E_ENABLE_MEMORY_
4140: 4d 41 4e 41 47 45 4d 45 4e 54 0a 20 20 20 20 2f  MANAGEMENT.    /
4150: 2a 20 54 68 65 20 67 72 6f 75 70 20 6d 75 74 65  * The group mute
4160: 78 20 6d 75 73 74 20 62 65 20 72 65 6c 65 61 73  x must be releas
4170: 65 64 20 62 65 66 6f 72 65 20 70 63 61 63 68 65  ed before pcache
4180: 31 41 6c 6c 6f 63 28 29 20 69 73 20 63 61 6c 6c  1Alloc() is call
4190: 65 64 2e 20 54 68 69 73 0a 20 20 20 20 2a 2a 20  ed. This.    ** 
41a0: 69 73 20 62 65 63 61 75 73 65 20 69 74 20 6d 69  is because it mi
41b0: 67 68 74 20 63 61 6c 6c 20 73 71 6c 69 74 65 33  ght call sqlite3
41c0: 5f 72 65 6c 65 61 73 65 5f 6d 65 6d 6f 72 79 28  _release_memory(
41d0: 29 2c 20 77 68 69 63 68 20 61 73 73 75 6d 65 73  ), which assumes
41e0: 20 74 68 61 74 20 0a 20 20 20 20 2a 2a 20 74 68   that .    ** th
41f0: 69 73 20 6d 75 74 65 78 20 69 73 20 6e 6f 74 20  is mutex is not 
4200: 68 65 6c 64 2e 20 2a 2f 0a 20 20 20 20 61 73 73  held. */.    ass
4210: 65 72 74 28 20 70 63 61 63 68 65 31 2e 73 65 70  ert( pcache1.sep
4220: 61 72 61 74 65 43 61 63 68 65 3d 3d 30 20 29 3b  arateCache==0 );
4230: 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 43 61  .    assert( pCa
4240: 63 68 65 2d 3e 70 47 72 6f 75 70 3d 3d 26 70 63  che->pGroup==&pc
4250: 61 63 68 65 31 2e 67 72 70 20 29 3b 0a 20 20 20  ache1.grp );.   
4260: 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74   pcache1LeaveMut
4270: 65 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75  ex(pCache->pGrou
4280: 70 29 3b 0a 23 65 6e 64 69 66 0a 20 20 20 20 69  p);.#endif.    i
4290: 66 28 20 62 65 6e 69 67 6e 4d 61 6c 6c 6f 63 20  f( benignMalloc 
42a0: 29 7b 20 73 71 6c 69 74 65 33 42 65 67 69 6e 42  ){ sqlite3BeginB
42b0: 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 20 7d  enignMalloc(); }
42c0: 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 50  .#ifdef SQLITE_P
42d0: 43 41 43 48 45 5f 53 45 50 41 52 41 54 45 5f 48  CACHE_SEPARATE_H
42e0: 45 41 44 45 52 0a 20 20 20 20 70 50 67 20 3d 20  EADER.    pPg = 
42f0: 70 63 61 63 68 65 31 41 6c 6c 6f 63 28 70 43 61  pcache1Alloc(pCa
4300: 63 68 65 2d 3e 73 7a 50 61 67 65 29 3b 0a 20 20  che->szPage);.  
4310: 20 20 70 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c    p = sqlite3Mal
4320: 6c 6f 63 28 73 69 7a 65 6f 66 28 50 67 48 64 72  loc(sizeof(PgHdr
4330: 31 29 20 2b 20 70 43 61 63 68 65 2d 3e 73 7a 45  1) + pCache->szE
4340: 78 74 72 61 29 3b 0a 20 20 20 20 69 66 28 20 21  xtra);.    if( !
4350: 70 50 67 20 7c 7c 20 21 70 20 29 7b 0a 20 20 20  pPg || !p ){.   
4360: 20 20 20 70 63 61 63 68 65 31 46 72 65 65 28 70     pcache1Free(p
4370: 50 67 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74  Pg);.      sqlit
4380: 65 33 5f 66 72 65 65 28 70 29 3b 0a 20 20 20 20  e3_free(p);.    
4390: 20 20 70 50 67 20 3d 20 30 3b 0a 20 20 20 20 7d    pPg = 0;.    }
43a0: 0a 23 65 6c 73 65 0a 20 20 20 20 70 50 67 20 3d  .#else.    pPg =
43b0: 20 70 63 61 63 68 65 31 41 6c 6c 6f 63 28 70 43   pcache1Alloc(pC
43c0: 61 63 68 65 2d 3e 73 7a 41 6c 6c 6f 63 29 3b 0a  ache->szAlloc);.
43d0: 20 20 20 20 70 20 3d 20 28 50 67 48 64 72 31 20      p = (PgHdr1 
43e0: 2a 29 26 28 28 75 38 20 2a 29 70 50 67 29 5b 70  *)&((u8 *)pPg)[p
43f0: 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 5d 3b 0a  Cache->szPage];.
4400: 23 65 6e 64 69 66 0a 20 20 20 20 69 66 28 20 62  #endif.    if( b
4410: 65 6e 69 67 6e 4d 61 6c 6c 6f 63 20 29 7b 20 73  enignMalloc ){ s
4420: 71 6c 69 74 65 33 45 6e 64 42 65 6e 69 67 6e 4d  qlite3EndBenignM
4430: 61 6c 6c 6f 63 28 29 3b 20 7d 0a 23 69 66 64 65  alloc(); }.#ifde
4440: 66 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f  f SQLITE_ENABLE_
4450: 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e  MEMORY_MANAGEMEN
4460: 54 0a 20 20 20 20 70 63 61 63 68 65 31 45 6e 74  T.    pcache1Ent
4470: 65 72 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e  erMutex(pCache->
4480: 70 47 72 6f 75 70 29 3b 0a 23 65 6e 64 69 66 0a  pGroup);.#endif.
4490: 20 20 20 20 69 66 28 20 70 50 67 3d 3d 30 20 29      if( pPg==0 )
44a0: 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 20 20 70   return 0;.    p
44b0: 2d 3e 70 61 67 65 2e 70 42 75 66 20 3d 20 70 50  ->page.pBuf = pP
44c0: 67 3b 0a 20 20 20 20 70 2d 3e 70 61 67 65 2e 70  g;.    p->page.p
44d0: 45 78 74 72 61 20 3d 20 26 70 5b 31 5d 3b 0a 20  Extra = &p[1];. 
44e0: 20 20 20 70 2d 3e 69 73 42 75 6c 6b 4c 6f 63 61     p->isBulkLoca
44f0: 6c 20 3d 20 30 3b 0a 20 20 20 20 70 2d 3e 69 73  l = 0;.    p->is
4500: 41 6e 63 68 6f 72 20 3d 20 30 3b 0a 20 20 7d 0a  Anchor = 0;.  }.
4510: 20 20 28 2a 70 43 61 63 68 65 2d 3e 70 6e 50 75    (*pCache->pnPu
4520: 72 67 65 61 62 6c 65 29 2b 2b 3b 0a 20 20 72 65  rgeable)++;.  re
4530: 74 75 72 6e 20 70 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  turn p;.}../*.**
4540: 20 46 72 65 65 20 61 20 70 61 67 65 20 6f 62 6a   Free a page obj
4550: 65 63 74 20 61 6c 6c 6f 63 61 74 65 64 20 62 79  ect allocated by
4560: 20 70 63 61 63 68 65 31 41 6c 6c 6f 63 50 61 67   pcache1AllocPag
4570: 65 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  e()..*/.static v
4580: 6f 69 64 20 70 63 61 63 68 65 31 46 72 65 65 50  oid pcache1FreeP
4590: 61 67 65 28 50 67 48 64 72 31 20 2a 70 29 7b 0a  age(PgHdr1 *p){.
45a0: 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68    PCache1 *pCach
45b0: 65 3b 0a 20 20 61 73 73 65 72 74 28 20 70 21 3d  e;.  assert( p!=
45c0: 30 20 29 3b 0a 20 20 70 43 61 63 68 65 20 3d 20  0 );.  pCache = 
45d0: 70 2d 3e 70 43 61 63 68 65 3b 0a 20 20 61 73 73  p->pCache;.  ass
45e0: 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74  ert( sqlite3_mut
45f0: 65 78 5f 68 65 6c 64 28 70 2d 3e 70 43 61 63 68  ex_held(p->pCach
4600: 65 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78  e->pGroup->mutex
4610: 29 20 29 3b 0a 20 20 69 66 28 20 70 2d 3e 69 73  ) );.  if( p->is
4620: 42 75 6c 6b 4c 6f 63 61 6c 20 29 7b 0a 20 20 20  BulkLocal ){.   
4630: 20 70 2d 3e 70 4e 65 78 74 20 3d 20 70 43 61 63   p->pNext = pCac
4640: 68 65 2d 3e 70 46 72 65 65 3b 0a 20 20 20 20 70  he->pFree;.    p
4650: 43 61 63 68 65 2d 3e 70 46 72 65 65 20 3d 20 70  Cache->pFree = p
4660: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70  ;.  }else{.    p
4670: 63 61 63 68 65 31 46 72 65 65 28 70 2d 3e 70 61  cache1Free(p->pa
4680: 67 65 2e 70 42 75 66 29 3b 0a 23 69 66 64 65 66  ge.pBuf);.#ifdef
4690: 20 53 51 4c 49 54 45 5f 50 43 41 43 48 45 5f 53   SQLITE_PCACHE_S
46a0: 45 50 41 52 41 54 45 5f 48 45 41 44 45 52 0a 20  EPARATE_HEADER. 
46b0: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
46c0: 70 29 3b 0a 23 65 6e 64 69 66 0a 20 20 7d 0a 20  p);.#endif.  }. 
46d0: 20 28 2a 70 43 61 63 68 65 2d 3e 70 6e 50 75 72   (*pCache->pnPur
46e0: 67 65 61 62 6c 65 29 2d 2d 3b 0a 7d 0a 0a 2f 2a  geable)--;.}../*
46f0: 0a 2a 2a 20 4d 61 6c 6c 6f 63 20 66 75 6e 63 74  .** Malloc funct
4700: 69 6f 6e 20 75 73 65 64 20 62 79 20 53 51 4c 69  ion used by SQLi
4710: 74 65 20 74 6f 20 6f 62 74 61 69 6e 20 73 70 61  te to obtain spa
4720: 63 65 20 66 72 6f 6d 20 74 68 65 20 62 75 66 66  ce from the buff
4730: 65 72 20 63 6f 6e 66 69 67 75 72 65 64 0a 2a 2a  er configured.**
4740: 20 75 73 69 6e 67 20 73 71 6c 69 74 65 33 5f 63   using sqlite3_c
4750: 6f 6e 66 69 67 28 53 51 4c 49 54 45 5f 43 4f 4e  onfig(SQLITE_CON
4760: 46 49 47 5f 50 41 47 45 43 41 43 48 45 29 20 6f  FIG_PAGECACHE) o
4770: 70 74 69 6f 6e 2e 20 49 66 20 6e 6f 20 73 75 63  ption. If no suc
4780: 68 20 62 75 66 66 65 72 0a 2a 2a 20 65 78 69 73  h buffer.** exis
4790: 74 73 2c 20 74 68 69 73 20 66 75 6e 63 74 69 6f  ts, this functio
47a0: 6e 20 66 61 6c 6c 73 20 62 61 63 6b 20 74 6f 20  n falls back to 
47b0: 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 29 2e  sqlite3Malloc().
47c0: 0a 2a 2f 0a 76 6f 69 64 20 2a 73 71 6c 69 74 65  .*/.void *sqlite
47d0: 33 50 61 67 65 4d 61 6c 6c 6f 63 28 69 6e 74 20  3PageMalloc(int 
47e0: 73 7a 29 7b 0a 20 20 72 65 74 75 72 6e 20 70 63  sz){.  return pc
47f0: 61 63 68 65 31 41 6c 6c 6f 63 28 73 7a 29 3b 0a  ache1Alloc(sz);.
4800: 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65 20 61 6e  }../*.** Free an
4810: 20 61 6c 6c 6f 63 61 74 65 64 20 62 75 66 66 65   allocated buffe
4820: 72 20 6f 62 74 61 69 6e 65 64 20 66 72 6f 6d 20  r obtained from 
4830: 73 71 6c 69 74 65 33 50 61 67 65 4d 61 6c 6c 6f  sqlite3PageMallo
4840: 63 28 29 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c  c()..*/.void sql
4850: 69 74 65 33 50 61 67 65 46 72 65 65 28 76 6f 69  ite3PageFree(voi
4860: 64 20 2a 70 29 7b 0a 20 20 70 63 61 63 68 65 31  d *p){.  pcache1
4870: 46 72 65 65 28 70 29 3b 0a 7d 0a 0a 0a 2f 2a 0a  Free(p);.}.../*.
4880: 2a 2a 20 52 65 74 75 72 6e 20 74 72 75 65 20 69  ** Return true i
4890: 66 20 69 74 20 64 65 73 69 72 61 62 6c 65 20 74  f it desirable t
48a0: 6f 20 61 76 6f 69 64 20 61 6c 6c 6f 63 61 74 69  o avoid allocati
48b0: 6e 67 20 61 20 6e 65 77 20 70 61 67 65 20 63 61  ng a new page ca
48c0: 63 68 65 0a 2a 2a 20 65 6e 74 72 79 2e 0a 2a 2a  che.** entry..**
48d0: 0a 2a 2a 20 49 66 20 6d 65 6d 6f 72 79 20 77 61  .** If memory wa
48e0: 73 20 61 6c 6c 6f 63 61 74 65 64 20 73 70 65 63  s allocated spec
48f0: 69 66 69 63 61 6c 6c 79 20 74 6f 20 74 68 65 20  ifically to the 
4900: 70 61 67 65 20 63 61 63 68 65 20 75 73 69 6e 67  page cache using
4910: 0a 2a 2a 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49  .** SQLITE_CONFI
4920: 47 5f 50 41 47 45 43 41 43 48 45 20 62 75 74 20  G_PAGECACHE but 
4930: 74 68 61 74 20 6d 65 6d 6f 72 79 20 68 61 73 20  that memory has 
4940: 61 6c 6c 20 62 65 65 6e 20 75 73 65 64 2c 20 74  all been used, t
4950: 68 65 6e 0a 2a 2a 20 69 74 20 69 73 20 64 65 73  hen.** it is des
4960: 69 72 61 62 6c 65 20 74 6f 20 61 76 6f 69 64 20  irable to avoid 
4970: 61 6c 6c 6f 63 61 74 69 6e 67 20 61 20 6e 65 77  allocating a new
4980: 20 70 61 67 65 20 63 61 63 68 65 20 65 6e 74 72   page cache entr
4990: 79 20 62 65 63 61 75 73 65 0a 2a 2a 20 70 72 65  y because.** pre
49a0: 73 75 6d 61 62 6c 79 20 53 51 4c 49 54 45 5f 43  sumably SQLITE_C
49b0: 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48 45 20  ONFIG_PAGECACHE 
49c0: 77 61 73 20 73 75 70 70 6f 73 65 20 74 6f 20 62  was suppose to b
49d0: 65 20 73 75 66 66 69 63 69 65 6e 74 0a 2a 2a 20  e sufficient.** 
49e0: 66 6f 72 20 61 6c 6c 20 70 61 67 65 20 63 61 63  for all page cac
49f0: 68 65 20 6e 65 65 64 73 20 61 6e 64 20 77 65 20  he needs and we 
4a00: 73 68 6f 75 6c 64 20 6e 6f 74 20 6e 65 65 64 20  should not need 
4a10: 74 6f 20 73 70 69 6c 6c 20 74 68 65 0a 2a 2a 20  to spill the.** 
4a20: 61 6c 6c 6f 63 61 74 69 6f 6e 20 6f 6e 74 6f 20  allocation onto 
4a30: 74 68 65 20 68 65 61 70 2e 0a 2a 2a 0a 2a 2a 20  the heap..**.** 
4a40: 4f 72 2c 20 74 68 65 20 68 65 61 70 20 69 73 20  Or, the heap is 
4a50: 75 73 65 64 20 66 6f 72 20 61 6c 6c 20 70 61 67  used for all pag
4a60: 65 20 63 61 63 68 65 20 6d 65 6d 6f 72 79 20 62  e cache memory b
4a70: 75 74 20 74 68 65 20 68 65 61 70 20 69 73 0a 2a  ut the heap is.*
4a80: 2a 20 75 6e 64 65 72 20 6d 65 6d 6f 72 79 20 70  * under memory p
4a90: 72 65 73 73 75 72 65 2c 20 74 68 65 6e 20 61 67  ressure, then ag
4aa0: 61 69 6e 20 69 74 20 69 73 20 64 65 73 69 72 61  ain it is desira
4ab0: 62 6c 65 20 74 6f 20 61 76 6f 69 64 0a 2a 2a 20  ble to avoid.** 
4ac0: 61 6c 6c 6f 63 61 74 69 6e 67 20 61 20 6e 65 77  allocating a new
4ad0: 20 70 61 67 65 20 63 61 63 68 65 20 65 6e 74 72   page cache entr
4ae0: 79 20 69 6e 20 6f 72 64 65 72 20 74 6f 20 61 76  y in order to av
4af0: 6f 69 64 20 73 74 72 65 73 73 69 6e 67 0a 2a 2a  oid stressing.**
4b00: 20 74 68 65 20 68 65 61 70 20 65 76 65 6e 20 66   the heap even f
4b10: 75 72 74 68 65 72 2e 0a 2a 2f 0a 73 74 61 74 69  urther..*/.stati
4b20: 63 20 69 6e 74 20 70 63 61 63 68 65 31 55 6e 64  c int pcache1Und
4b30: 65 72 4d 65 6d 6f 72 79 50 72 65 73 73 75 72 65  erMemoryPressure
4b40: 28 50 43 61 63 68 65 31 20 2a 70 43 61 63 68 65  (PCache1 *pCache
4b50: 29 7b 0a 20 20 69 66 28 20 70 63 61 63 68 65 31  ){.  if( pcache1
4b60: 2e 6e 53 6c 6f 74 20 26 26 20 28 70 43 61 63 68  .nSlot && (pCach
4b70: 65 2d 3e 73 7a 50 61 67 65 2b 70 43 61 63 68 65  e->szPage+pCache
4b80: 2d 3e 73 7a 45 78 74 72 61 29 3c 3d 70 63 61 63  ->szExtra)<=pcac
4b90: 68 65 31 2e 73 7a 53 6c 6f 74 20 29 7b 0a 20 20  he1.szSlot ){.  
4ba0: 20 20 72 65 74 75 72 6e 20 70 63 61 63 68 65 31    return pcache1
4bb0: 2e 62 55 6e 64 65 72 50 72 65 73 73 75 72 65 3b  .bUnderPressure;
4bc0: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 72 65  .  }else{.    re
4bd0: 74 75 72 6e 20 73 71 6c 69 74 65 33 48 65 61 70  turn sqlite3Heap
4be0: 4e 65 61 72 6c 79 46 75 6c 6c 28 29 3b 0a 20 20  NearlyFull();.  
4bf0: 7d 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  }.}../**********
4c00: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4c10: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4c20: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4c30: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4c40: 2a 2a 2a 2a 2f 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 20  ****/./******** 
4c50: 47 65 6e 65 72 61 6c 20 49 6d 70 6c 65 6d 65 6e  General Implemen
4c60: 74 61 74 69 6f 6e 20 46 75 6e 63 74 69 6f 6e 73  tation Functions
4c70: 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a   ***************
4c80: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4c90: 2a 2a 2a 2a 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 54 68  *****/../*.** Th
4ca0: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 75  is function is u
4cb0: 73 65 64 20 74 6f 20 72 65 73 69 7a 65 20 74 68  sed to resize th
4cc0: 65 20 68 61 73 68 20 74 61 62 6c 65 20 75 73 65  e hash table use
4cd0: 64 20 62 79 20 74 68 65 20 63 61 63 68 65 20 70  d by the cache p
4ce0: 61 73 73 65 64 0a 2a 2a 20 61 73 20 74 68 65 20  assed.** as the 
4cf0: 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74 2e 0a  first argument..
4d00: 2a 2a 0a 2a 2a 20 54 68 65 20 50 43 61 63 68 65  **.** The PCache
4d10: 20 6d 75 74 65 78 20 6d 75 73 74 20 62 65 20 68   mutex must be h
4d20: 65 6c 64 20 77 68 65 6e 20 74 68 69 73 20 66 75  eld when this fu
4d30: 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64  nction is called
4d40: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
4d50: 20 70 63 61 63 68 65 31 52 65 73 69 7a 65 48 61   pcache1ResizeHa
4d60: 73 68 28 50 43 61 63 68 65 31 20 2a 70 29 7b 0a  sh(PCache1 *p){.
4d70: 20 20 50 67 48 64 72 31 20 2a 2a 61 70 4e 65 77    PgHdr1 **apNew
4d80: 3b 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74  ;.  unsigned int
4d90: 20 6e 4e 65 77 3b 0a 20 20 75 6e 73 69 67 6e 65   nNew;.  unsigne
4da0: 64 20 69 6e 74 20 69 3b 0a 0a 20 20 61 73 73 65  d int i;..  asse
4db0: 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74 65  rt( sqlite3_mute
4dc0: 78 5f 68 65 6c 64 28 70 2d 3e 70 47 72 6f 75 70  x_held(p->pGroup
4dd0: 2d 3e 6d 75 74 65 78 29 20 29 3b 0a 0a 20 20 6e  ->mutex) );..  n
4de0: 4e 65 77 20 3d 20 70 2d 3e 6e 48 61 73 68 2a 32  New = p->nHash*2
4df0: 3b 0a 20 20 69 66 28 20 6e 4e 65 77 3c 32 35 36  ;.  if( nNew<256
4e00: 20 29 7b 0a 20 20 20 20 6e 4e 65 77 20 3d 20 32   ){.    nNew = 2
4e10: 35 36 3b 0a 20 20 7d 0a 0a 20 20 70 63 61 63 68  56;.  }..  pcach
4e20: 65 31 4c 65 61 76 65 4d 75 74 65 78 28 70 2d 3e  e1LeaveMutex(p->
4e30: 70 47 72 6f 75 70 29 3b 0a 20 20 69 66 28 20 70  pGroup);.  if( p
4e40: 2d 3e 6e 48 61 73 68 20 29 7b 20 73 71 6c 69 74  ->nHash ){ sqlit
4e50: 65 33 42 65 67 69 6e 42 65 6e 69 67 6e 4d 61 6c  e3BeginBenignMal
4e60: 6c 6f 63 28 29 3b 20 7d 0a 20 20 61 70 4e 65 77  loc(); }.  apNew
4e70: 20 3d 20 28 50 67 48 64 72 31 20 2a 2a 29 73 71   = (PgHdr1 **)sq
4e80: 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28  lite3MallocZero(
4e90: 73 69 7a 65 6f 66 28 50 67 48 64 72 31 20 2a 29  sizeof(PgHdr1 *)
4ea0: 2a 6e 4e 65 77 29 3b 0a 20 20 69 66 28 20 70 2d  *nNew);.  if( p-
4eb0: 3e 6e 48 61 73 68 20 29 7b 20 73 71 6c 69 74 65  >nHash ){ sqlite
4ec0: 33 45 6e 64 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63  3EndBenignMalloc
4ed0: 28 29 3b 20 7d 0a 20 20 70 63 61 63 68 65 31 45  (); }.  pcache1E
4ee0: 6e 74 65 72 4d 75 74 65 78 28 70 2d 3e 70 47 72  nterMutex(p->pGr
4ef0: 6f 75 70 29 3b 0a 20 20 69 66 28 20 61 70 4e 65  oup);.  if( apNe
4f00: 77 20 29 7b 0a 20 20 20 20 66 6f 72 28 69 3d 30  w ){.    for(i=0
4f10: 3b 20 69 3c 70 2d 3e 6e 48 61 73 68 3b 20 69 2b  ; i<p->nHash; i+
4f20: 2b 29 7b 0a 20 20 20 20 20 20 50 67 48 64 72 31  +){.      PgHdr1
4f30: 20 2a 70 50 61 67 65 3b 0a 20 20 20 20 20 20 50   *pPage;.      P
4f40: 67 48 64 72 31 20 2a 70 4e 65 78 74 20 3d 20 70  gHdr1 *pNext = p
4f50: 2d 3e 61 70 48 61 73 68 5b 69 5d 3b 0a 20 20 20  ->apHash[i];.   
4f60: 20 20 20 77 68 69 6c 65 28 20 28 70 50 61 67 65     while( (pPage
4f70: 20 3d 20 70 4e 65 78 74 29 21 3d 30 20 29 7b 0a   = pNext)!=0 ){.
4f80: 20 20 20 20 20 20 20 20 75 6e 73 69 67 6e 65 64          unsigned
4f90: 20 69 6e 74 20 68 20 3d 20 70 50 61 67 65 2d 3e   int h = pPage->
4fa0: 69 4b 65 79 20 25 20 6e 4e 65 77 3b 0a 20 20 20  iKey % nNew;.   
4fb0: 20 20 20 20 20 70 4e 65 78 74 20 3d 20 70 50 61       pNext = pPa
4fc0: 67 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20  ge->pNext;.     
4fd0: 20 20 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 20     pPage->pNext 
4fe0: 3d 20 61 70 4e 65 77 5b 68 5d 3b 0a 20 20 20 20  = apNew[h];.    
4ff0: 20 20 20 20 61 70 4e 65 77 5b 68 5d 20 3d 20 70      apNew[h] = p
5000: 50 61 67 65 3b 0a 20 20 20 20 20 20 7d 0a 20 20  Page;.      }.  
5010: 20 20 7d 0a 20 20 20 20 73 71 6c 69 74 65 33 5f    }.    sqlite3_
5020: 66 72 65 65 28 70 2d 3e 61 70 48 61 73 68 29 3b  free(p->apHash);
5030: 0a 20 20 20 20 70 2d 3e 61 70 48 61 73 68 20 3d  .    p->apHash =
5040: 20 61 70 4e 65 77 3b 0a 20 20 20 20 70 2d 3e 6e   apNew;.    p->n
5050: 48 61 73 68 20 3d 20 6e 4e 65 77 3b 0a 20 20 7d  Hash = nNew;.  }
5060: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66  .}../*.** This f
5070: 75 6e 63 74 69 6f 6e 20 69 73 20 75 73 65 64 20  unction is used 
5080: 69 6e 74 65 72 6e 61 6c 6c 79 20 74 6f 20 72 65  internally to re
5090: 6d 6f 76 65 20 74 68 65 20 70 61 67 65 20 70 50  move the page pP
50a0: 61 67 65 20 66 72 6f 6d 20 74 68 65 20 0a 2a 2a  age from the .**
50b0: 20 50 47 72 6f 75 70 20 4c 52 55 20 6c 69 73 74   PGroup LRU list
50c0: 2c 20 69 66 20 69 73 20 70 61 72 74 20 6f 66 20  , if is part of 
50d0: 69 74 2e 20 49 66 20 70 50 61 67 65 20 69 73 20  it. If pPage is 
50e0: 6e 6f 74 20 70 61 72 74 20 6f 66 20 74 68 65 20  not part of the 
50f0: 50 47 72 6f 75 70 0a 2a 2a 20 4c 52 55 20 6c 69  PGroup.** LRU li
5100: 73 74 2c 20 74 68 65 6e 20 74 68 69 73 20 66 75  st, then this fu
5110: 6e 63 74 69 6f 6e 20 69 73 20 61 20 6e 6f 2d 6f  nction is a no-o
5120: 70 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 50 47 72  p..**.** The PGr
5130: 6f 75 70 20 6d 75 74 65 78 20 6d 75 73 74 20 62  oup mutex must b
5140: 65 20 68 65 6c 64 20 77 68 65 6e 20 74 68 69 73  e held when this
5150: 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c   function is cal
5160: 6c 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 50  led..*/.static P
5170: 67 48 64 72 31 20 2a 70 63 61 63 68 65 31 50 69  gHdr1 *pcache1Pi
5180: 6e 50 61 67 65 28 50 67 48 64 72 31 20 2a 70 50  nPage(PgHdr1 *pP
5190: 61 67 65 29 7b 0a 20 20 61 73 73 65 72 74 28 20  age){.  assert( 
51a0: 70 50 61 67 65 21 3d 30 20 29 3b 0a 20 20 61 73  pPage!=0 );.  as
51b0: 73 65 72 74 28 20 50 41 47 45 5f 49 53 5f 55 4e  sert( PAGE_IS_UN
51c0: 50 49 4e 4e 45 44 28 70 50 61 67 65 29 20 29 3b  PINNED(pPage) );
51d0: 0a 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65  .  assert( pPage
51e0: 2d 3e 70 4c 72 75 4e 65 78 74 20 29 3b 0a 20 20  ->pLruNext );.  
51f0: 61 73 73 65 72 74 28 20 70 50 61 67 65 2d 3e 70  assert( pPage->p
5200: 4c 72 75 50 72 65 76 20 29 3b 0a 20 20 61 73 73  LruPrev );.  ass
5210: 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74  ert( sqlite3_mut
5220: 65 78 5f 68 65 6c 64 28 70 50 61 67 65 2d 3e 70  ex_held(pPage->p
5230: 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 2d 3e 6d  Cache->pGroup->m
5240: 75 74 65 78 29 20 29 3b 0a 20 20 70 50 61 67 65  utex) );.  pPage
5250: 2d 3e 70 4c 72 75 50 72 65 76 2d 3e 70 4c 72 75  ->pLruPrev->pLru
5260: 4e 65 78 74 20 3d 20 70 50 61 67 65 2d 3e 70 4c  Next = pPage->pL
5270: 72 75 4e 65 78 74 3b 0a 20 20 70 50 61 67 65 2d  ruNext;.  pPage-
5280: 3e 70 4c 72 75 4e 65 78 74 2d 3e 70 4c 72 75 50  >pLruNext->pLruP
5290: 72 65 76 20 3d 20 70 50 61 67 65 2d 3e 70 4c 72  rev = pPage->pLr
52a0: 75 50 72 65 76 3b 0a 20 20 70 50 61 67 65 2d 3e  uPrev;.  pPage->
52b0: 70 4c 72 75 4e 65 78 74 20 3d 20 30 3b 0a 20 20  pLruNext = 0;.  
52c0: 70 50 61 67 65 2d 3e 70 4c 72 75 50 72 65 76 20  pPage->pLruPrev 
52d0: 3d 20 30 3b 0a 20 20 61 73 73 65 72 74 28 20 70  = 0;.  assert( p
52e0: 50 61 67 65 2d 3e 69 73 41 6e 63 68 6f 72 3d 3d  Page->isAnchor==
52f0: 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70  0 );.  assert( p
5300: 50 61 67 65 2d 3e 70 43 61 63 68 65 2d 3e 70 47  Page->pCache->pG
5310: 72 6f 75 70 2d 3e 6c 72 75 2e 69 73 41 6e 63 68  roup->lru.isAnch
5320: 6f 72 3d 3d 31 20 29 3b 0a 20 20 70 50 61 67 65  or==1 );.  pPage
5330: 2d 3e 70 43 61 63 68 65 2d 3e 6e 52 65 63 79 63  ->pCache->nRecyc
5340: 6c 61 62 6c 65 2d 2d 3b 0a 20 20 72 65 74 75 72  lable--;.  retur
5350: 6e 20 70 50 61 67 65 3b 0a 7d 0a 0a 0a 2f 2a 0a  n pPage;.}.../*.
5360: 2a 2a 20 52 65 6d 6f 76 65 20 74 68 65 20 70 61  ** Remove the pa
5370: 67 65 20 73 75 70 70 6c 69 65 64 20 61 73 20 61  ge supplied as a
5380: 6e 20 61 72 67 75 6d 65 6e 74 20 66 72 6f 6d 20  n argument from 
5390: 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 20 0a  the hash table .
53a0: 2a 2a 20 28 50 43 61 63 68 65 31 2e 61 70 48 61  ** (PCache1.apHa
53b0: 73 68 20 73 74 72 75 63 74 75 72 65 29 20 74 68  sh structure) th
53c0: 61 74 20 69 74 20 69 73 20 63 75 72 72 65 6e 74  at it is current
53d0: 6c 79 20 73 74 6f 72 65 64 20 69 6e 2e 0a 2a 2a  ly stored in..**
53e0: 20 41 6c 73 6f 20 66 72 65 65 20 74 68 65 20 70   Also free the p
53f0: 61 67 65 20 69 66 20 66 72 65 65 50 61 67 65 20  age if freePage 
5400: 69 73 20 74 72 75 65 2e 0a 2a 2a 0a 2a 2a 20 54  is true..**.** T
5410: 68 65 20 50 47 72 6f 75 70 20 6d 75 74 65 78 20  he PGroup mutex 
5420: 6d 75 73 74 20 62 65 20 68 65 6c 64 20 77 68 65  must be held whe
5430: 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  n this function 
5440: 69 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f 0a 73 74  is called..*/.st
5450: 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65  atic void pcache
5460: 31 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73 68 28  1RemoveFromHash(
5470: 50 67 48 64 72 31 20 2a 70 50 61 67 65 2c 20 69  PgHdr1 *pPage, i
5480: 6e 74 20 66 72 65 65 46 6c 61 67 29 7b 0a 20 20  nt freeFlag){.  
5490: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 3b 0a  unsigned int h;.
54a0: 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68    PCache1 *pCach
54b0: 65 20 3d 20 70 50 61 67 65 2d 3e 70 43 61 63 68  e = pPage->pCach
54c0: 65 3b 0a 20 20 50 67 48 64 72 31 20 2a 2a 70 70  e;.  PgHdr1 **pp
54d0: 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c  ;..  assert( sql
54e0: 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28  ite3_mutex_held(
54f0: 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 2d 3e  pCache->pGroup->
5500: 6d 75 74 65 78 29 20 29 3b 0a 20 20 68 20 3d 20  mutex) );.  h = 
5510: 70 50 61 67 65 2d 3e 69 4b 65 79 20 25 20 70 43  pPage->iKey % pC
5520: 61 63 68 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 66  ache->nHash;.  f
5530: 6f 72 28 70 70 3d 26 70 43 61 63 68 65 2d 3e 61  or(pp=&pCache->a
5540: 70 48 61 73 68 5b 68 5d 3b 20 28 2a 70 70 29 21  pHash[h]; (*pp)!
5550: 3d 70 50 61 67 65 3b 20 70 70 3d 26 28 2a 70 70  =pPage; pp=&(*pp
5560: 29 2d 3e 70 4e 65 78 74 29 3b 0a 20 20 2a 70 70  )->pNext);.  *pp
5570: 20 3d 20 28 2a 70 70 29 2d 3e 70 4e 65 78 74 3b   = (*pp)->pNext;
5580: 0a 0a 20 20 70 43 61 63 68 65 2d 3e 6e 50 61 67  ..  pCache->nPag
5590: 65 2d 2d 3b 0a 20 20 69 66 28 20 66 72 65 65 46  e--;.  if( freeF
55a0: 6c 61 67 20 29 20 70 63 61 63 68 65 31 46 72 65  lag ) pcache1Fre
55b0: 65 50 61 67 65 28 70 50 61 67 65 29 3b 0a 7d 0a  ePage(pPage);.}.
55c0: 0a 2f 2a 0a 2a 2a 20 49 66 20 74 68 65 72 65 20  ./*.** If there 
55d0: 61 72 65 20 63 75 72 72 65 6e 74 6c 79 20 6d 6f  are currently mo
55e0: 72 65 20 74 68 61 6e 20 6e 4d 61 78 50 61 67 65  re than nMaxPage
55f0: 20 70 61 67 65 73 20 61 6c 6c 6f 63 61 74 65 64   pages allocated
5600: 2c 20 74 72 79 0a 2a 2a 20 74 6f 20 72 65 63 79  , try.** to recy
5610: 63 6c 65 20 70 61 67 65 73 20 74 6f 20 72 65 64  cle pages to red
5620: 75 63 65 20 74 68 65 20 6e 75 6d 62 65 72 20 61  uce the number a
5630: 6c 6c 6f 63 61 74 65 64 20 74 6f 20 6e 4d 61 78  llocated to nMax
5640: 50 61 67 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  Page..*/.static 
5650: 76 6f 69 64 20 70 63 61 63 68 65 31 45 6e 66 6f  void pcache1Enfo
5660: 72 63 65 4d 61 78 50 61 67 65 28 50 43 61 63 68  rceMaxPage(PCach
5670: 65 31 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 50  e1 *pCache){.  P
5680: 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 20 3d 20  Group *pGroup = 
5690: 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b 0a  pCache->pGroup;.
56a0: 20 20 50 67 48 64 72 31 20 2a 70 3b 0a 20 20 61    PgHdr1 *p;.  a
56b0: 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d  ssert( sqlite3_m
56c0: 75 74 65 78 5f 68 65 6c 64 28 70 47 72 6f 75 70  utex_held(pGroup
56d0: 2d 3e 6d 75 74 65 78 29 20 29 3b 0a 20 20 77 68  ->mutex) );.  wh
56e0: 69 6c 65 28 20 70 47 72 6f 75 70 2d 3e 6e 50 75  ile( pGroup->nPu
56f0: 72 67 65 61 62 6c 65 3e 70 47 72 6f 75 70 2d 3e  rgeable>pGroup->
5700: 6e 4d 61 78 50 61 67 65 0a 20 20 20 20 20 20 26  nMaxPage.      &
5710: 26 20 28 70 3d 70 47 72 6f 75 70 2d 3e 6c 72 75  & (p=pGroup->lru
5720: 2e 70 4c 72 75 50 72 65 76 29 2d 3e 69 73 41 6e  .pLruPrev)->isAn
5730: 63 68 6f 72 3d 3d 30 0a 20 20 29 7b 0a 20 20 20  chor==0.  ){.   
5740: 20 61 73 73 65 72 74 28 20 70 2d 3e 70 43 61 63   assert( p->pCac
5750: 68 65 2d 3e 70 47 72 6f 75 70 3d 3d 70 47 72 6f  he->pGroup==pGro
5760: 75 70 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74  up );.    assert
5770: 28 20 50 41 47 45 5f 49 53 5f 55 4e 50 49 4e 4e  ( PAGE_IS_UNPINN
5780: 45 44 28 70 29 20 29 3b 0a 20 20 20 20 70 63 61  ED(p) );.    pca
5790: 63 68 65 31 50 69 6e 50 61 67 65 28 70 29 3b 0a  che1PinPage(p);.
57a0: 20 20 20 20 70 63 61 63 68 65 31 52 65 6d 6f 76      pcache1Remov
57b0: 65 46 72 6f 6d 48 61 73 68 28 70 2c 20 31 29 3b  eFromHash(p, 1);
57c0: 0a 20 20 7d 0a 20 20 69 66 28 20 70 43 61 63 68  .  }.  if( pCach
57d0: 65 2d 3e 6e 50 61 67 65 3d 3d 30 20 26 26 20 70  e->nPage==0 && p
57e0: 43 61 63 68 65 2d 3e 70 42 75 6c 6b 20 29 7b 0a  Cache->pBulk ){.
57f0: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
5800: 28 70 43 61 63 68 65 2d 3e 70 42 75 6c 6b 29 3b  (pCache->pBulk);
5810: 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 70 42 75  .    pCache->pBu
5820: 6c 6b 20 3d 20 70 43 61 63 68 65 2d 3e 70 46 72  lk = pCache->pFr
5830: 65 65 20 3d 20 30 3b 0a 20 20 7d 0a 7d 0a 0a 2f  ee = 0;.  }.}../
5840: 2a 0a 2a 2a 20 44 69 73 63 61 72 64 20 61 6c 6c  *.** Discard all
5850: 20 70 61 67 65 73 20 66 72 6f 6d 20 63 61 63 68   pages from cach
5860: 65 20 70 43 61 63 68 65 20 77 69 74 68 20 61 20  e pCache with a 
5870: 70 61 67 65 20 6e 75 6d 62 65 72 20 28 6b 65 79  page number (key
5880: 20 76 61 6c 75 65 29 20 0a 2a 2a 20 67 72 65 61   value) .** grea
5890: 74 65 72 20 74 68 61 6e 20 6f 72 20 65 71 75 61  ter than or equa
58a0: 6c 20 74 6f 20 69 4c 69 6d 69 74 2e 20 41 6e 79  l to iLimit. Any
58b0: 20 70 69 6e 6e 65 64 20 70 61 67 65 73 20 74 68   pinned pages th
58c0: 61 74 20 6d 65 65 74 20 74 68 69 73 20 0a 2a 2a  at meet this .**
58d0: 20 63 72 69 74 65 72 69 61 20 61 72 65 20 75 6e   criteria are un
58e0: 70 69 6e 6e 65 64 20 62 65 66 6f 72 65 20 74 68  pinned before th
58f0: 65 79 20 61 72 65 20 64 69 73 63 61 72 64 65 64  ey are discarded
5900: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 50 43 61 63  ..**.** The PCac
5910: 68 65 20 6d 75 74 65 78 20 6d 75 73 74 20 62 65  he mutex must be
5920: 20 68 65 6c 64 20 77 68 65 6e 20 74 68 69 73 20   held when this 
5930: 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c  function is call
5940: 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ed..*/.static vo
5950: 69 64 20 70 63 61 63 68 65 31 54 72 75 6e 63 61  id pcache1Trunca
5960: 74 65 55 6e 73 61 66 65 28 0a 20 20 50 43 61 63  teUnsafe(.  PCac
5970: 68 65 31 20 2a 70 43 61 63 68 65 2c 20 20 20 20  he1 *pCache,    
5980: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20           /* The 
5990: 63 61 63 68 65 20 74 6f 20 74 72 75 6e 63 61 74  cache to truncat
59a0: 65 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20  e */.  unsigned 
59b0: 69 6e 74 20 69 4c 69 6d 69 74 20 20 20 20 20 20  int iLimit      
59c0: 20 20 20 20 2f 2a 20 44 72 6f 70 20 70 61 67 65      /* Drop page
59d0: 73 20 77 69 74 68 20 74 68 69 73 20 70 67 6e 6f  s with this pgno
59e0: 20 6f 72 20 6c 61 72 67 65 72 20 2a 2f 0a 29 7b   or larger */.){
59f0: 0a 20 20 54 45 53 54 4f 4e 4c 59 28 20 69 6e 74  .  TESTONLY( int
5a00: 20 6e 50 61 67 65 20 3d 20 30 3b 20 29 20 20 2f   nPage = 0; )  /
5a10: 2a 20 54 6f 20 61 73 73 65 72 74 20 70 43 61 63  * To assert pCac
5a20: 68 65 2d 3e 6e 50 61 67 65 20 69 73 20 63 6f 72  he->nPage is cor
5a30: 72 65 63 74 20 2a 2f 0a 20 20 75 6e 73 69 67 6e  rect */.  unsign
5a40: 65 64 20 69 6e 74 20 68 2c 20 69 53 74 6f 70 3b  ed int h, iStop;
5a50: 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74  .  assert( sqlit
5a60: 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 43  e3_mutex_held(pC
5a70: 61 63 68 65 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75  ache->pGroup->mu
5a80: 74 65 78 29 20 29 3b 0a 20 20 61 73 73 65 72 74  tex) );.  assert
5a90: 28 20 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b 65  ( pCache->iMaxKe
5aa0: 79 20 3e 3d 20 69 4c 69 6d 69 74 20 29 3b 0a 20  y >= iLimit );. 
5ab0: 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65 2d   assert( pCache-
5ac0: 3e 6e 48 61 73 68 20 3e 20 30 20 29 3b 0a 20 20  >nHash > 0 );.  
5ad0: 69 66 28 20 70 43 61 63 68 65 2d 3e 69 4d 61 78  if( pCache->iMax
5ae0: 4b 65 79 20 2d 20 69 4c 69 6d 69 74 20 3c 20 70  Key - iLimit < p
5af0: 43 61 63 68 65 2d 3e 6e 48 61 73 68 20 29 7b 0a  Cache->nHash ){.
5b00: 20 20 20 20 2f 2a 20 49 66 20 77 65 20 61 72 65      /* If we are
5b10: 20 6a 75 73 74 20 73 68 61 76 69 6e 67 20 74 68   just shaving th
5b20: 65 20 6c 61 73 74 20 66 65 77 20 70 61 67 65 73  e last few pages
5b30: 20 6f 66 66 20 74 68 65 20 65 6e 64 20 6f 66 20   off the end of 
5b40: 74 68 65 0a 20 20 20 20 2a 2a 20 63 61 63 68 65  the.    ** cache
5b50: 2c 20 74 68 65 6e 20 74 68 65 72 65 20 69 73 20  , then there is 
5b60: 6e 6f 20 70 6f 69 6e 74 20 69 6e 20 73 63 61 6e  no point in scan
5b70: 6e 69 6e 67 20 74 68 65 20 65 6e 74 69 72 65 20  ning the entire 
5b80: 68 61 73 68 20 74 61 62 6c 65 2e 0a 20 20 20 20  hash table..    
5b90: 2a 2a 20 4f 6e 6c 79 20 73 63 61 6e 20 74 68 6f  ** Only scan tho
5ba0: 73 65 20 68 61 73 68 20 73 6c 6f 74 73 20 74 68  se hash slots th
5bb0: 61 74 20 6d 69 67 68 74 20 63 6f 6e 74 61 69 6e  at might contain
5bc0: 20 70 61 67 65 73 20 74 68 61 74 20 6e 65 65 64   pages that need
5bd0: 20 74 6f 0a 20 20 20 20 2a 2a 20 62 65 20 72 65   to.    ** be re
5be0: 6d 6f 76 65 64 2e 20 2a 2f 0a 20 20 20 20 68 20  moved. */.    h 
5bf0: 3d 20 69 4c 69 6d 69 74 20 25 20 70 43 61 63 68  = iLimit % pCach
5c00: 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 20 20 69 53  e->nHash;.    iS
5c10: 74 6f 70 20 3d 20 70 43 61 63 68 65 2d 3e 69 4d  top = pCache->iM
5c20: 61 78 4b 65 79 20 25 20 70 43 61 63 68 65 2d 3e  axKey % pCache->
5c30: 6e 48 61 73 68 3b 0a 20 20 20 20 54 45 53 54 4f  nHash;.    TESTO
5c40: 4e 4c 59 28 20 6e 50 61 67 65 20 3d 20 2d 31 30  NLY( nPage = -10
5c50: 3b 20 29 20 20 2f 2a 20 44 69 73 61 62 6c 65 20  ; )  /* Disable 
5c60: 74 68 65 20 70 43 61 63 68 65 2d 3e 6e 50 61 67  the pCache->nPag
5c70: 65 20 76 61 6c 69 64 69 74 79 20 63 68 65 63 6b  e validity check
5c80: 20 2a 2f 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20   */.  }else{.   
5c90: 20 2f 2a 20 54 68 69 73 20 69 73 20 74 68 65 20   /* This is the 
5ca0: 67 65 6e 65 72 61 6c 20 63 61 73 65 20 77 68 65  general case whe
5cb0: 72 65 20 6d 61 6e 79 20 70 61 67 65 73 20 61 72  re many pages ar
5cc0: 65 20 62 65 69 6e 67 20 72 65 6d 6f 76 65 64 2e  e being removed.
5cd0: 0a 20 20 20 20 2a 2a 20 49 74 20 69 73 20 6e 65  .    ** It is ne
5ce0: 63 65 73 73 61 72 79 20 74 6f 20 73 63 61 6e 20  cessary to scan 
5cf0: 74 68 65 20 65 6e 74 69 72 65 20 68 61 73 68 20  the entire hash 
5d00: 74 61 62 6c 65 20 2a 2f 0a 20 20 20 20 68 20 3d  table */.    h =
5d10: 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 2f 32   pCache->nHash/2
5d20: 3b 0a 20 20 20 20 69 53 74 6f 70 20 3d 20 68 20  ;.    iStop = h 
5d30: 2d 20 31 3b 0a 20 20 7d 0a 20 20 66 6f 72 28 3b  - 1;.  }.  for(;
5d40: 3b 29 7b 0a 20 20 20 20 50 67 48 64 72 31 20 2a  ;){.    PgHdr1 *
5d50: 2a 70 70 3b 0a 20 20 20 20 50 67 48 64 72 31 20  *pp;.    PgHdr1 
5d60: 2a 70 50 61 67 65 3b 0a 20 20 20 20 61 73 73 65  *pPage;.    asse
5d70: 72 74 28 20 68 3c 70 43 61 63 68 65 2d 3e 6e 48  rt( h<pCache->nH
5d80: 61 73 68 20 29 3b 0a 20 20 20 20 70 70 20 3d 20  ash );.    pp = 
5d90: 26 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b  &pCache->apHash[
5da0: 68 5d 3b 20 0a 20 20 20 20 77 68 69 6c 65 28 20  h]; .    while( 
5db0: 28 70 50 61 67 65 20 3d 20 2a 70 70 29 21 3d 30  (pPage = *pp)!=0
5dc0: 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 70 50   ){.      if( pP
5dd0: 61 67 65 2d 3e 69 4b 65 79 3e 3d 69 4c 69 6d 69  age->iKey>=iLimi
5de0: 74 20 29 7b 0a 20 20 20 20 20 20 20 20 70 43 61  t ){.        pCa
5df0: 63 68 65 2d 3e 6e 50 61 67 65 2d 2d 3b 0a 20 20  che->nPage--;.  
5e00: 20 20 20 20 20 20 2a 70 70 20 3d 20 70 50 61 67        *pp = pPag
5e10: 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20  e->pNext;.      
5e20: 20 20 69 66 28 20 50 41 47 45 5f 49 53 5f 55 4e    if( PAGE_IS_UN
5e30: 50 49 4e 4e 45 44 28 70 50 61 67 65 29 20 29 20  PINNED(pPage) ) 
5e40: 70 63 61 63 68 65 31 50 69 6e 50 61 67 65 28 70  pcache1PinPage(p
5e50: 50 61 67 65 29 3b 0a 20 20 20 20 20 20 20 20 70  Page);.        p
5e60: 63 61 63 68 65 31 46 72 65 65 50 61 67 65 28 70  cache1FreePage(p
5e70: 50 61 67 65 29 3b 0a 20 20 20 20 20 20 7d 65 6c  Page);.      }el
5e80: 73 65 7b 0a 20 20 20 20 20 20 20 20 70 70 20 3d  se{.        pp =
5e90: 20 26 70 50 61 67 65 2d 3e 70 4e 65 78 74 3b 0a   &pPage->pNext;.
5ea0: 20 20 20 20 20 20 20 20 54 45 53 54 4f 4e 4c 59          TESTONLY
5eb0: 28 20 69 66 28 20 6e 50 61 67 65 3e 3d 30 20 29  ( if( nPage>=0 )
5ec0: 20 6e 50 61 67 65 2b 2b 3b 20 29 0a 20 20 20 20   nPage++; ).    
5ed0: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66    }.    }.    if
5ee0: 28 20 68 3d 3d 69 53 74 6f 70 20 29 20 62 72 65  ( h==iStop ) bre
5ef0: 61 6b 3b 0a 20 20 20 20 68 20 3d 20 28 68 2b 31  ak;.    h = (h+1
5f00: 29 20 25 20 70 43 61 63 68 65 2d 3e 6e 48 61 73  ) % pCache->nHas
5f10: 68 3b 0a 20 20 7d 0a 20 20 61 73 73 65 72 74 28  h;.  }.  assert(
5f20: 20 6e 50 61 67 65 3c 30 20 7c 7c 20 70 43 61 63   nPage<0 || pCac
5f30: 68 65 2d 3e 6e 50 61 67 65 3d 3d 28 75 6e 73 69  he->nPage==(unsi
5f40: 67 6e 65 64 29 6e 50 61 67 65 20 29 3b 0a 7d 0a  gned)nPage );.}.
5f50: 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ./**************
5f60: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5f70: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5f80: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5f90: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5fa0: 2f 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 20 73 71 6c 69  /./******** sqli
5fb0: 74 65 33 5f 70 63 61 63 68 65 20 4d 65 74 68 6f  te3_pcache Metho
5fc0: 64 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ds *************
5fd0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5fe0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5ff0: 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d  */../*.** Implem
6000: 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20  entation of the 
6010: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78  sqlite3_pcache.x
6020: 49 6e 69 74 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a  Init method..*/.
6030: 73 74 61 74 69 63 20 69 6e 74 20 70 63 61 63 68  static int pcach
6040: 65 31 49 6e 69 74 28 76 6f 69 64 20 2a 4e 6f 74  e1Init(void *Not
6050: 55 73 65 64 29 7b 0a 20 20 55 4e 55 53 45 44 5f  Used){.  UNUSED_
6060: 50 41 52 41 4d 45 54 45 52 28 4e 6f 74 55 73 65  PARAMETER(NotUse
6070: 64 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 63  d);.  assert( pc
6080: 61 63 68 65 31 2e 69 73 49 6e 69 74 3d 3d 30 20  ache1.isInit==0 
6090: 29 3b 0a 20 20 6d 65 6d 73 65 74 28 26 70 63 61  );.  memset(&pca
60a0: 63 68 65 31 2c 20 30 2c 20 73 69 7a 65 6f 66 28  che1, 0, sizeof(
60b0: 70 63 61 63 68 65 31 29 29 3b 0a 0a 0a 20 20 2f  pcache1));...  /
60c0: 2a 0a 20 20 2a 2a 20 54 68 65 20 70 63 61 63 68  *.  ** The pcach
60d0: 65 31 2e 73 65 70 61 72 61 74 65 43 61 63 68 65  e1.separateCache
60e0: 20 76 61 72 69 61 62 6c 65 20 69 73 20 74 72 75   variable is tru
60f0: 65 20 69 66 20 65 61 63 68 20 50 43 61 63 68 65  e if each PCache
6100: 20 68 61 73 20 69 74 73 20 6f 77 6e 0a 20 20 2a   has its own.  *
6110: 2a 20 70 72 69 76 61 74 65 20 50 47 72 6f 75 70  * private PGroup
6120: 20 28 6d 6f 64 65 2d 31 29 2e 20 20 70 63 61 63   (mode-1).  pcac
6130: 68 65 31 2e 73 65 70 61 72 61 74 65 43 61 63 68  he1.separateCach
6140: 65 20 69 73 20 66 61 6c 73 65 20 69 66 20 74 68  e is false if th
6150: 65 20 73 69 6e 67 6c 65 0a 20 20 2a 2a 20 50 47  e single.  ** PG
6160: 72 6f 75 70 20 69 6e 20 70 63 61 63 68 65 31 2e  roup in pcache1.
6170: 67 72 70 20 69 73 20 75 73 65 64 20 66 6f 72 20  grp is used for 
6180: 61 6c 6c 20 70 61 67 65 20 63 61 63 68 65 73 20  all page caches 
6190: 28 6d 6f 64 65 2d 32 29 2e 0a 20 20 2a 2a 0a 20  (mode-2)..  **. 
61a0: 20 2a 2a 20 20 20 2a 20 20 41 6c 77 61 79 73 20   **   *  Always 
61b0: 75 73 65 20 61 20 75 6e 69 66 69 65 64 20 63 61  use a unified ca
61c0: 63 68 65 20 28 6d 6f 64 65 2d 32 29 20 69 66 20  che (mode-2) if 
61d0: 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41  ENABLE_MEMORY_MA
61e0: 4e 41 47 45 4d 45 4e 54 0a 20 20 2a 2a 0a 20 20  NAGEMENT.  **.  
61f0: 2a 2a 20 20 20 2a 20 20 55 73 65 20 61 20 75 6e  **   *  Use a un
6200: 69 66 69 65 64 20 63 61 63 68 65 20 69 6e 20 73  ified cache in s
6210: 69 6e 67 6c 65 2d 74 68 72 65 61 64 65 64 20 61  ingle-threaded a
6220: 70 70 6c 69 63 61 74 69 6f 6e 73 20 74 68 61 74  pplications that
6230: 20 68 61 76 65 0a 20 20 2a 2a 20 20 20 20 20 20   have.  **      
6240: 63 6f 6e 66 69 67 75 72 65 64 20 61 20 73 74 61  configured a sta
6250: 72 74 2d 74 69 6d 65 20 62 75 66 66 65 72 20 66  rt-time buffer f
6260: 6f 72 20 75 73 65 20 61 73 20 70 61 67 65 2d 63  or use as page-c
6270: 61 63 68 65 20 6d 65 6d 6f 72 79 20 75 73 69 6e  ache memory usin
6280: 67 0a 20 20 2a 2a 20 20 20 20 20 20 73 71 6c 69  g.  **      sqli
6290: 74 65 33 5f 63 6f 6e 66 69 67 28 53 51 4c 49 54  te3_config(SQLIT
62a0: 45 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41 43  E_CONFIG_PAGECAC
62b0: 48 45 2c 20 70 42 75 66 2c 20 73 7a 2c 20 4e 29  HE, pBuf, sz, N)
62c0: 20 77 69 74 68 20 6e 6f 6e 2d 4e 55 4c 4c 20 0a   with non-NULL .
62d0: 20 20 2a 2a 20 20 20 20 20 20 70 42 75 66 20 61    **      pBuf a
62e0: 72 67 75 6d 65 6e 74 2e 0a 20 20 2a 2a 0a 20 20  rgument..  **.  
62f0: 2a 2a 20 20 20 2a 20 20 4f 74 68 65 72 77 69 73  **   *  Otherwis
6300: 65 20 75 73 65 20 73 65 70 61 72 61 74 65 20 63  e use separate c
6310: 61 63 68 65 73 20 28 6d 6f 64 65 2d 31 29 0a 20  aches (mode-1). 
6320: 20 2a 2f 0a 23 69 66 20 64 65 66 69 6e 65 64 28   */.#if defined(
6330: 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45  SQLITE_ENABLE_ME
6340: 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 29  MORY_MANAGEMENT)
6350: 0a 20 20 70 63 61 63 68 65 31 2e 73 65 70 61 72  .  pcache1.separ
6360: 61 74 65 43 61 63 68 65 20 3d 20 30 3b 0a 23 65  ateCache = 0;.#e
6370: 6c 69 66 20 53 51 4c 49 54 45 5f 54 48 52 45 41  lif SQLITE_THREA
6380: 44 53 41 46 45 0a 20 20 70 63 61 63 68 65 31 2e  DSAFE.  pcache1.
6390: 73 65 70 61 72 61 74 65 43 61 63 68 65 20 3d 20  separateCache = 
63a0: 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e  sqlite3GlobalCon
63b0: 66 69 67 2e 70 50 61 67 65 3d 3d 30 0a 20 20 20  fig.pPage==0.   
63c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
63d0: 20 20 20 20 20 20 20 7c 7c 20 73 71 6c 69 74 65         || sqlite
63e0: 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 62 43  3GlobalConfig.bC
63f0: 6f 72 65 4d 75 74 65 78 3e 30 3b 0a 23 65 6c 73  oreMutex>0;.#els
6400: 65 0a 20 20 70 63 61 63 68 65 31 2e 73 65 70 61  e.  pcache1.sepa
6410: 72 61 74 65 43 61 63 68 65 20 3d 20 73 71 6c 69  rateCache = sqli
6420: 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e  te3GlobalConfig.
6430: 70 50 61 67 65 3d 3d 30 3b 0a 23 65 6e 64 69 66  pPage==0;.#endif
6440: 0a 0a 23 69 66 20 53 51 4c 49 54 45 5f 54 48 52  ..#if SQLITE_THR
6450: 45 41 44 53 41 46 45 0a 20 20 69 66 28 20 73 71  EADSAFE.  if( sq
6460: 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69  lite3GlobalConfi
6470: 67 2e 62 43 6f 72 65 4d 75 74 65 78 20 29 7b 0a  g.bCoreMutex ){.
6480: 20 20 20 20 70 63 61 63 68 65 31 2e 67 72 70 2e      pcache1.grp.
6490: 6d 75 74 65 78 20 3d 20 73 71 6c 69 74 65 33 4d  mutex = sqlite3M
64a0: 75 74 65 78 41 6c 6c 6f 63 28 53 51 4c 49 54 45  utexAlloc(SQLITE
64b0: 5f 4d 55 54 45 58 5f 53 54 41 54 49 43 5f 4c 52  _MUTEX_STATIC_LR
64c0: 55 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e  U);.    pcache1.
64d0: 6d 75 74 65 78 20 3d 20 73 71 6c 69 74 65 33 4d  mutex = sqlite3M
64e0: 75 74 65 78 41 6c 6c 6f 63 28 53 51 4c 49 54 45  utexAlloc(SQLITE
64f0: 5f 4d 55 54 45 58 5f 53 54 41 54 49 43 5f 50 4d  _MUTEX_STATIC_PM
6500: 45 4d 29 3b 0a 20 20 7d 0a 23 65 6e 64 69 66 0a  EM);.  }.#endif.
6510: 20 20 69 66 28 20 70 63 61 63 68 65 31 2e 73 65    if( pcache1.se
6520: 70 61 72 61 74 65 43 61 63 68 65 0a 20 20 20 26  parateCache.   &
6530: 26 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43  & sqlite3GlobalC
6540: 6f 6e 66 69 67 2e 6e 50 61 67 65 21 3d 30 0a 20  onfig.nPage!=0. 
6550: 20 20 26 26 20 73 71 6c 69 74 65 33 47 6c 6f 62    && sqlite3Glob
6560: 61 6c 43 6f 6e 66 69 67 2e 70 50 61 67 65 3d 3d  alConfig.pPage==
6570: 30 0a 20 20 29 7b 0a 20 20 20 20 70 63 61 63 68  0.  ){.    pcach
6580: 65 31 2e 6e 49 6e 69 74 50 61 67 65 20 3d 20 73  e1.nInitPage = s
6590: 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66  qlite3GlobalConf
65a0: 69 67 2e 6e 50 61 67 65 3b 0a 20 20 7d 65 6c 73  ig.nPage;.  }els
65b0: 65 7b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 6e  e{.    pcache1.n
65c0: 49 6e 69 74 50 61 67 65 20 3d 20 30 3b 0a 20 20  InitPage = 0;.  
65d0: 7d 0a 20 20 70 63 61 63 68 65 31 2e 67 72 70 2e  }.  pcache1.grp.
65e0: 6d 78 50 69 6e 6e 65 64 20 3d 20 31 30 3b 0a 20  mxPinned = 10;. 
65f0: 20 70 63 61 63 68 65 31 2e 69 73 49 6e 69 74 20   pcache1.isInit 
6600: 3d 20 31 3b 0a 20 20 72 65 74 75 72 6e 20 53 51  = 1;.  return SQ
6610: 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a  LITE_OK;.}../*.*
6620: 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  * Implementation
6630: 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f   of the sqlite3_
6640: 70 63 61 63 68 65 2e 78 53 68 75 74 64 6f 77 6e  pcache.xShutdown
6650: 20 6d 65 74 68 6f 64 2e 0a 2a 2a 20 4e 6f 74 65   method..** Note
6660: 20 74 68 61 74 20 74 68 65 20 73 74 61 74 69 63   that the static
6670: 20 6d 75 74 65 78 20 61 6c 6c 6f 63 61 74 65 64   mutex allocated
6680: 20 69 6e 20 78 49 6e 69 74 20 64 6f 65 73 20 0a   in xInit does .
6690: 2a 2a 20 6e 6f 74 20 6e 65 65 64 20 74 6f 20 62  ** not need to b
66a0: 65 20 66 72 65 65 64 2e 0a 2a 2f 0a 73 74 61 74  e freed..*/.stat
66b0: 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 31 53  ic void pcache1S
66c0: 68 75 74 64 6f 77 6e 28 76 6f 69 64 20 2a 4e 6f  hutdown(void *No
66d0: 74 55 73 65 64 29 7b 0a 20 20 55 4e 55 53 45 44  tUsed){.  UNUSED
66e0: 5f 50 41 52 41 4d 45 54 45 52 28 4e 6f 74 55 73  _PARAMETER(NotUs
66f0: 65 64 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70  ed);.  assert( p
6700: 63 61 63 68 65 31 2e 69 73 49 6e 69 74 21 3d 30  cache1.isInit!=0
6710: 20 29 3b 0a 20 20 6d 65 6d 73 65 74 28 26 70 63   );.  memset(&pc
6720: 61 63 68 65 31 2c 20 30 2c 20 73 69 7a 65 6f 66  ache1, 0, sizeof
6730: 28 70 63 61 63 68 65 31 29 29 3b 0a 7d 0a 0a 2f  (pcache1));.}../
6740: 2a 20 66 6f 72 77 61 72 64 20 64 65 63 6c 61 72  * forward declar
6750: 61 74 69 6f 6e 20 2a 2f 0a 73 74 61 74 69 63 20  ation */.static 
6760: 76 6f 69 64 20 70 63 61 63 68 65 31 44 65 73 74  void pcache1Dest
6770: 72 6f 79 28 73 71 6c 69 74 65 33 5f 70 63 61 63  roy(sqlite3_pcac
6780: 68 65 20 2a 70 29 3b 0a 0a 2f 2a 0a 2a 2a 20 49  he *p);../*.** I
6790: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66  mplementation of
67a0: 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61   the sqlite3_pca
67b0: 63 68 65 2e 78 43 72 65 61 74 65 20 6d 65 74 68  che.xCreate meth
67c0: 6f 64 2e 0a 2a 2a 0a 2a 2a 20 41 6c 6c 6f 63 61  od..**.** Alloca
67d0: 74 65 20 61 20 6e 65 77 20 63 61 63 68 65 2e 0a  te a new cache..
67e0: 2a 2f 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65  */.static sqlite
67f0: 33 5f 70 63 61 63 68 65 20 2a 70 63 61 63 68 65  3_pcache *pcache
6800: 31 43 72 65 61 74 65 28 69 6e 74 20 73 7a 50 61  1Create(int szPa
6810: 67 65 2c 20 69 6e 74 20 73 7a 45 78 74 72 61 2c  ge, int szExtra,
6820: 20 69 6e 74 20 62 50 75 72 67 65 61 62 6c 65 29   int bPurgeable)
6830: 7b 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43 61  {.  PCache1 *pCa
6840: 63 68 65 3b 20 20 20 20 20 20 2f 2a 20 54 68 65  che;      /* The
6850: 20 6e 65 77 6c 79 20 63 72 65 61 74 65 64 20 70   newly created p
6860: 61 67 65 20 63 61 63 68 65 20 2a 2f 0a 20 20 50  age cache */.  P
6870: 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 3b 20 20  Group *pGroup;  
6880: 20 20 20 20 20 2f 2a 20 54 68 65 20 67 72 6f 75       /* The grou
6890: 70 20 74 68 65 20 6e 65 77 20 70 61 67 65 20 63  p the new page c
68a0: 61 63 68 65 20 77 69 6c 6c 20 62 65 6c 6f 6e 67  ache will belong
68b0: 20 74 6f 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 3b   to */.  int sz;
68c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
68d0: 2a 20 42 79 74 65 73 20 6f 66 20 6d 65 6d 6f 72  * Bytes of memor
68e0: 79 20 72 65 71 75 69 72 65 64 20 74 6f 20 61 6c  y required to al
68f0: 6c 6f 63 61 74 65 20 74 68 65 20 6e 65 77 20 63  locate the new c
6900: 61 63 68 65 20 2a 2f 0a 0a 20 20 61 73 73 65 72  ache */..  asser
6910: 74 28 20 28 73 7a 50 61 67 65 20 26 20 28 73 7a  t( (szPage & (sz
6920: 50 61 67 65 2d 31 29 29 3d 3d 30 20 26 26 20 73  Page-1))==0 && s
6930: 7a 50 61 67 65 3e 3d 35 31 32 20 26 26 20 73 7a  zPage>=512 && sz
6940: 50 61 67 65 3c 3d 36 35 35 33 36 20 29 3b 0a 20  Page<=65536 );. 
6950: 20 61 73 73 65 72 74 28 20 73 7a 45 78 74 72 61   assert( szExtra
6960: 20 3c 20 33 30 30 20 29 3b 0a 0a 20 20 73 7a 20   < 300 );..  sz 
6970: 3d 20 73 69 7a 65 6f 66 28 50 43 61 63 68 65 31  = sizeof(PCache1
6980: 29 20 2b 20 73 69 7a 65 6f 66 28 50 47 72 6f 75  ) + sizeof(PGrou
6990: 70 29 2a 70 63 61 63 68 65 31 2e 73 65 70 61 72  p)*pcache1.separ
69a0: 61 74 65 43 61 63 68 65 3b 0a 20 20 70 43 61 63  ateCache;.  pCac
69b0: 68 65 20 3d 20 28 50 43 61 63 68 65 31 20 2a 29  he = (PCache1 *)
69c0: 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65 72  sqlite3MallocZer
69d0: 6f 28 73 7a 29 3b 0a 20 20 69 66 28 20 70 43 61  o(sz);.  if( pCa
69e0: 63 68 65 20 29 7b 0a 20 20 20 20 69 66 28 20 70  che ){.    if( p
69f0: 63 61 63 68 65 31 2e 73 65 70 61 72 61 74 65 43  cache1.separateC
6a00: 61 63 68 65 20 29 7b 0a 20 20 20 20 20 20 70 47  ache ){.      pG
6a10: 72 6f 75 70 20 3d 20 28 50 47 72 6f 75 70 2a 29  roup = (PGroup*)
6a20: 26 70 43 61 63 68 65 5b 31 5d 3b 0a 20 20 20 20  &pCache[1];.    
6a30: 20 20 70 47 72 6f 75 70 2d 3e 6d 78 50 69 6e 6e    pGroup->mxPinn
6a40: 65 64 20 3d 20 31 30 3b 0a 20 20 20 20 7d 65 6c  ed = 10;.    }el
6a50: 73 65 7b 0a 20 20 20 20 20 20 70 47 72 6f 75 70  se{.      pGroup
6a60: 20 3d 20 26 70 63 61 63 68 65 31 2e 67 72 70 3b   = &pcache1.grp;
6a70: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70  .    }.    if( p
6a80: 47 72 6f 75 70 2d 3e 6c 72 75 2e 69 73 41 6e 63  Group->lru.isAnc
6a90: 68 6f 72 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  hor==0 ){.      
6aa0: 70 47 72 6f 75 70 2d 3e 6c 72 75 2e 69 73 41 6e  pGroup->lru.isAn
6ab0: 63 68 6f 72 20 3d 20 31 3b 0a 20 20 20 20 20 20  chor = 1;.      
6ac0: 70 47 72 6f 75 70 2d 3e 6c 72 75 2e 70 4c 72 75  pGroup->lru.pLru
6ad0: 50 72 65 76 20 3d 20 70 47 72 6f 75 70 2d 3e 6c  Prev = pGroup->l
6ae0: 72 75 2e 70 4c 72 75 4e 65 78 74 20 3d 20 26 70  ru.pLruNext = &p
6af0: 47 72 6f 75 70 2d 3e 6c 72 75 3b 0a 20 20 20 20  Group->lru;.    
6b00: 7d 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 70 47  }.    pCache->pG
6b10: 72 6f 75 70 20 3d 20 70 47 72 6f 75 70 3b 0a 20  roup = pGroup;. 
6b20: 20 20 20 70 43 61 63 68 65 2d 3e 73 7a 50 61 67     pCache->szPag
6b30: 65 20 3d 20 73 7a 50 61 67 65 3b 0a 20 20 20 20  e = szPage;.    
6b40: 70 43 61 63 68 65 2d 3e 73 7a 45 78 74 72 61 20  pCache->szExtra 
6b50: 3d 20 73 7a 45 78 74 72 61 3b 0a 20 20 20 20 70  = szExtra;.    p
6b60: 43 61 63 68 65 2d 3e 73 7a 41 6c 6c 6f 63 20 3d  Cache->szAlloc =
6b70: 20 73 7a 50 61 67 65 20 2b 20 73 7a 45 78 74 72   szPage + szExtr
6b80: 61 20 2b 20 52 4f 55 4e 44 38 28 73 69 7a 65 6f  a + ROUND8(sizeo
6b90: 66 28 50 67 48 64 72 31 29 29 3b 0a 20 20 20 20  f(PgHdr1));.    
6ba0: 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62  pCache->bPurgeab
6bb0: 6c 65 20 3d 20 28 62 50 75 72 67 65 61 62 6c 65  le = (bPurgeable
6bc0: 20 3f 20 31 20 3a 20 30 29 3b 0a 20 20 20 20 70   ? 1 : 0);.    p
6bd0: 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78  cache1EnterMutex
6be0: 28 70 47 72 6f 75 70 29 3b 0a 20 20 20 20 70 63  (pGroup);.    pc
6bf0: 61 63 68 65 31 52 65 73 69 7a 65 48 61 73 68 28  ache1ResizeHash(
6c00: 70 43 61 63 68 65 29 3b 0a 20 20 20 20 69 66 28  pCache);.    if(
6c10: 20 62 50 75 72 67 65 61 62 6c 65 20 29 7b 0a 20   bPurgeable ){. 
6c20: 20 20 20 20 20 70 43 61 63 68 65 2d 3e 6e 4d 69       pCache->nMi
6c30: 6e 20 3d 20 31 30 3b 0a 20 20 20 20 20 20 70 47  n = 10;.      pG
6c40: 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67 65 20 2b  roup->nMinPage +
6c50: 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 3b 0a  = pCache->nMin;.
6c60: 20 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 6d 78        pGroup->mx
6c70: 50 69 6e 6e 65 64 20 3d 20 70 47 72 6f 75 70 2d  Pinned = pGroup-
6c80: 3e 6e 4d 61 78 50 61 67 65 20 2b 20 31 30 20 2d  >nMaxPage + 10 -
6c90: 20 70 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67   pGroup->nMinPag
6ca0: 65 3b 0a 20 20 20 20 20 20 70 43 61 63 68 65 2d  e;.      pCache-
6cb0: 3e 70 6e 50 75 72 67 65 61 62 6c 65 20 3d 20 26  >pnPurgeable = &
6cc0: 70 47 72 6f 75 70 2d 3e 6e 50 75 72 67 65 61 62  pGroup->nPurgeab
6cd0: 6c 65 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  le;.    }else{. 
6ce0: 20 20 20 20 20 73 74 61 74 69 63 20 75 6e 73 69       static unsi
6cf0: 67 6e 65 64 20 69 6e 74 20 64 75 6d 6d 79 43 75  gned int dummyCu
6d00: 72 72 65 6e 74 50 61 67 65 3b 0a 20 20 20 20 20  rrentPage;.     
6d10: 20 70 43 61 63 68 65 2d 3e 70 6e 50 75 72 67 65   pCache->pnPurge
6d20: 61 62 6c 65 20 3d 20 26 64 75 6d 6d 79 43 75 72  able = &dummyCur
6d30: 72 65 6e 74 50 61 67 65 3b 0a 20 20 20 20 7d 0a  rentPage;.    }.
6d40: 20 20 20 20 70 63 61 63 68 65 31 4c 65 61 76 65      pcache1Leave
6d50: 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b 0a 20  Mutex(pGroup);. 
6d60: 20 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 6e     if( pCache->n
6d70: 48 61 73 68 3d 3d 30 20 29 7b 0a 20 20 20 20 20  Hash==0 ){.     
6d80: 20 70 63 61 63 68 65 31 44 65 73 74 72 6f 79 28   pcache1Destroy(
6d90: 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2a  (sqlite3_pcache*
6da0: 29 70 43 61 63 68 65 29 3b 0a 20 20 20 20 20 20  )pCache);.      
6db0: 70 43 61 63 68 65 20 3d 20 30 3b 0a 20 20 20 20  pCache = 0;.    
6dc0: 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 28  }.  }.  return (
6dd0: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a  sqlite3_pcache *
6de0: 29 70 43 61 63 68 65 3b 0a 7d 0a 0a 2f 2a 0a 2a  )pCache;.}../*.*
6df0: 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  * Implementation
6e00: 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f   of the sqlite3_
6e10: 70 63 61 63 68 65 2e 78 43 61 63 68 65 73 69 7a  pcache.xCachesiz
6e20: 65 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a  e method. .**.**
6e30: 20 43 6f 6e 66 69 67 75 72 65 20 74 68 65 20 63   Configure the c
6e40: 61 63 68 65 5f 73 69 7a 65 20 6c 69 6d 69 74 20  ache_size limit 
6e50: 66 6f 72 20 61 20 63 61 63 68 65 2e 0a 2a 2f 0a  for a cache..*/.
6e60: 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63  static void pcac
6e70: 68 65 31 43 61 63 68 65 73 69 7a 65 28 73 71 6c  he1Cachesize(sql
6e80: 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70 2c 20  ite3_pcache *p, 
6e90: 69 6e 74 20 6e 4d 61 78 29 7b 0a 20 20 50 43 61  int nMax){.  PCa
6ea0: 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28  che1 *pCache = (
6eb0: 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20 20 69  PCache1 *)p;.  i
6ec0: 66 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67  f( pCache->bPurg
6ed0: 65 61 62 6c 65 20 29 7b 0a 20 20 20 20 50 47 72  eable ){.    PGr
6ee0: 6f 75 70 20 2a 70 47 72 6f 75 70 20 3d 20 70 43  oup *pGroup = pC
6ef0: 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b 0a 20 20  ache->pGroup;.  
6f00: 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75    pcache1EnterMu
6f10: 74 65 78 28 70 47 72 6f 75 70 29 3b 0a 20 20 20  tex(pGroup);.   
6f20: 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67   pGroup->nMaxPag
6f30: 65 20 2b 3d 20 28 6e 4d 61 78 20 2d 20 70 43 61  e += (nMax - pCa
6f40: 63 68 65 2d 3e 6e 4d 61 78 29 3b 0a 20 20 20 20  che->nMax);.    
6f50: 70 47 72 6f 75 70 2d 3e 6d 78 50 69 6e 6e 65 64  pGroup->mxPinned
6f60: 20 3d 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50   = pGroup->nMaxP
6f70: 61 67 65 20 2b 20 31 30 20 2d 20 70 47 72 6f 75  age + 10 - pGrou
6f80: 70 2d 3e 6e 4d 69 6e 50 61 67 65 3b 0a 20 20 20  p->nMinPage;.   
6f90: 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 20 3d 20   pCache->nMax = 
6fa0: 6e 4d 61 78 3b 0a 20 20 20 20 70 43 61 63 68 65  nMax;.    pCache
6fb0: 2d 3e 6e 39 30 70 63 74 20 3d 20 70 43 61 63 68  ->n90pct = pCach
6fc0: 65 2d 3e 6e 4d 61 78 2a 39 2f 31 30 3b 0a 20 20  e->nMax*9/10;.  
6fd0: 20 20 70 63 61 63 68 65 31 45 6e 66 6f 72 63 65    pcache1Enforce
6fe0: 4d 61 78 50 61 67 65 28 70 43 61 63 68 65 29 3b  MaxPage(pCache);
6ff0: 0a 20 20 20 20 70 63 61 63 68 65 31 4c 65 61 76  .    pcache1Leav
7000: 65 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b 0a  eMutex(pGroup);.
7010: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70    }.}../*.** Imp
7020: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74  lementation of t
7030: 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68  he sqlite3_pcach
7040: 65 2e 78 53 68 72 69 6e 6b 20 6d 65 74 68 6f 64  e.xShrink method
7050: 2e 20 0a 2a 2a 0a 2a 2a 20 46 72 65 65 20 75 70  . .**.** Free up
7060: 20 61 73 20 6d 75 63 68 20 6d 65 6d 6f 72 79 20   as much memory 
7070: 61 73 20 70 6f 73 73 69 62 6c 65 2e 0a 2a 2f 0a  as possible..*/.
7080: 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63  static void pcac
7090: 68 65 31 53 68 72 69 6e 6b 28 73 71 6c 69 74 65  he1Shrink(sqlite
70a0: 33 5f 70 63 61 63 68 65 20 2a 70 29 7b 0a 20 20  3_pcache *p){.  
70b0: 50 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 20  PCache1 *pCache 
70c0: 3d 20 28 50 43 61 63 68 65 31 2a 29 70 3b 0a 20  = (PCache1*)p;. 
70d0: 20 69 66 28 20 70 43 61 63 68 65 2d 3e 62 50 75   if( pCache->bPu
70e0: 72 67 65 61 62 6c 65 20 29 7b 0a 20 20 20 20 50  rgeable ){.    P
70f0: 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 20 3d 20  Group *pGroup = 
7100: 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b 0a  pCache->pGroup;.
7110: 20 20 20 20 69 6e 74 20 73 61 76 65 64 4d 61 78      int savedMax
7120: 50 61 67 65 3b 0a 20 20 20 20 70 63 61 63 68 65  Page;.    pcache
7130: 31 45 6e 74 65 72 4d 75 74 65 78 28 70 47 72 6f  1EnterMutex(pGro
7140: 75 70 29 3b 0a 20 20 20 20 73 61 76 65 64 4d 61  up);.    savedMa
7150: 78 50 61 67 65 20 3d 20 70 47 72 6f 75 70 2d 3e  xPage = pGroup->
7160: 6e 4d 61 78 50 61 67 65 3b 0a 20 20 20 20 70 47  nMaxPage;.    pG
7170: 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65 20 3d  roup->nMaxPage =
7180: 20 30 3b 0a 20 20 20 20 70 63 61 63 68 65 31 45   0;.    pcache1E
7190: 6e 66 6f 72 63 65 4d 61 78 50 61 67 65 28 70 43  nforceMaxPage(pC
71a0: 61 63 68 65 29 3b 0a 20 20 20 20 70 47 72 6f 75  ache);.    pGrou
71b0: 70 2d 3e 6e 4d 61 78 50 61 67 65 20 3d 20 73 61  p->nMaxPage = sa
71c0: 76 65 64 4d 61 78 50 61 67 65 3b 0a 20 20 20 20  vedMaxPage;.    
71d0: 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65  pcache1LeaveMute
71e0: 78 28 70 47 72 6f 75 70 29 3b 0a 20 20 7d 0a 7d  x(pGroup);.  }.}
71f0: 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e  ../*.** Implemen
7200: 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71  tation of the sq
7210: 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78 50 61  lite3_pcache.xPa
7220: 67 65 63 6f 75 6e 74 20 6d 65 74 68 6f 64 2e 20  gecount method. 
7230: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 70  .*/.static int p
7240: 63 61 63 68 65 31 50 61 67 65 63 6f 75 6e 74 28  cache1Pagecount(
7250: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a  sqlite3_pcache *
7260: 70 29 7b 0a 20 20 69 6e 74 20 6e 3b 0a 20 20 50  p){.  int n;.  P
7270: 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d  Cache1 *pCache =
7280: 20 28 50 43 61 63 68 65 31 2a 29 70 3b 0a 20 20   (PCache1*)p;.  
7290: 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65  pcache1EnterMute
72a0: 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70  x(pCache->pGroup
72b0: 29 3b 0a 20 20 6e 20 3d 20 70 43 61 63 68 65 2d  );.  n = pCache-
72c0: 3e 6e 50 61 67 65 3b 0a 20 20 70 63 61 63 68 65  >nPage;.  pcache
72d0: 31 4c 65 61 76 65 4d 75 74 65 78 28 70 43 61 63  1LeaveMutex(pCac
72e0: 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 20 20 72  he->pGroup);.  r
72f0: 65 74 75 72 6e 20 6e 3b 0a 7d 0a 0a 0a 2f 2a 0a  eturn n;.}.../*.
7300: 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 20 73 74 65  ** Implement ste
7310: 70 73 20 33 2c 20 34 2c 20 61 6e 64 20 35 20 6f  ps 3, 4, and 5 o
7320: 66 20 74 68 65 20 70 63 61 63 68 65 31 46 65 74  f the pcache1Fet
7330: 63 68 28 29 20 61 6c 67 6f 72 69 74 68 6d 20 64  ch() algorithm d
7340: 65 73 63 72 69 62 65 64 0a 2a 2a 20 69 6e 20 74  escribed.** in t
7350: 68 65 20 68 65 61 64 65 72 20 6f 66 20 74 68 65  he header of the
7360: 20 70 63 61 63 68 65 31 46 65 74 63 68 28 29 20   pcache1Fetch() 
7370: 70 72 6f 63 65 64 75 72 65 2e 0a 2a 2a 0a 2a 2a  procedure..**.**
7380: 20 54 68 69 73 20 73 74 65 70 73 20 61 72 65 20   This steps are 
7390: 62 72 6f 6b 65 6e 20 6f 75 74 20 69 6e 74 6f 20  broken out into 
73a0: 61 20 73 65 70 61 72 61 74 65 20 70 72 6f 63 65  a separate proce
73b0: 64 75 72 65 20 62 65 63 61 75 73 65 20 74 68 65  dure because the
73c0: 79 20 61 72 65 0a 2a 2a 20 75 73 75 61 6c 6c 79  y are.** usually
73d0: 20 6e 6f 74 20 6e 65 65 64 65 64 2c 20 61 6e 64   not needed, and
73e0: 20 62 79 20 61 76 6f 69 64 69 6e 67 20 74 68 65   by avoiding the
73f0: 20 73 74 61 63 6b 20 69 6e 69 74 69 61 6c 69 7a   stack initializ
7400: 61 74 69 6f 6e 20 72 65 71 75 69 72 65 64 0a 2a  ation required.*
7410: 2a 20 66 6f 72 20 74 68 65 73 65 20 73 74 65 70  * for these step
7420: 73 2c 20 74 68 65 20 6d 61 69 6e 20 70 63 61 63  s, the main pcac
7430: 68 65 31 46 65 74 63 68 28 29 20 70 72 6f 63 65  he1Fetch() proce
7440: 64 75 72 65 20 63 61 6e 20 72 75 6e 20 66 61 73  dure can run fas
7450: 74 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 53  ter..*/.static S
7460: 51 4c 49 54 45 5f 4e 4f 49 4e 4c 49 4e 45 20 50  QLITE_NOINLINE P
7470: 67 48 64 72 31 20 2a 70 63 61 63 68 65 31 46 65  gHdr1 *pcache1Fe
7480: 74 63 68 53 74 61 67 65 32 28 0a 20 20 50 43 61  tchStage2(.  PCa
7490: 63 68 65 31 20 2a 70 43 61 63 68 65 2c 20 0a 20  che1 *pCache, . 
74a0: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4b   unsigned int iK
74b0: 65 79 2c 20 0a 20 20 69 6e 74 20 63 72 65 61 74  ey, .  int creat
74c0: 65 46 6c 61 67 0a 29 7b 0a 20 20 75 6e 73 69 67  eFlag.){.  unsig
74d0: 6e 65 64 20 69 6e 74 20 6e 50 69 6e 6e 65 64 3b  ned int nPinned;
74e0: 0a 20 20 50 47 72 6f 75 70 20 2a 70 47 72 6f 75  .  PGroup *pGrou
74f0: 70 20 3d 20 70 43 61 63 68 65 2d 3e 70 47 72 6f  p = pCache->pGro
7500: 75 70 3b 0a 20 20 50 67 48 64 72 31 20 2a 70 50  up;.  PgHdr1 *pP
7510: 61 67 65 20 3d 20 30 3b 0a 0a 20 20 2f 2a 20 53  age = 0;..  /* S
7520: 74 65 70 20 33 3a 20 41 62 6f 72 74 20 69 66 20  tep 3: Abort if 
7530: 63 72 65 61 74 65 46 6c 61 67 20 69 73 20 31 20  createFlag is 1 
7540: 62 75 74 20 74 68 65 20 63 61 63 68 65 20 69 73  but the cache is
7550: 20 6e 65 61 72 6c 79 20 66 75 6c 6c 20 2a 2f 0a   nearly full */.
7560: 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65    assert( pCache
7570: 2d 3e 6e 50 61 67 65 20 3e 3d 20 70 43 61 63 68  ->nPage >= pCach
7580: 65 2d 3e 6e 52 65 63 79 63 6c 61 62 6c 65 20 29  e->nRecyclable )
7590: 3b 0a 20 20 6e 50 69 6e 6e 65 64 20 3d 20 70 43  ;.  nPinned = pC
75a0: 61 63 68 65 2d 3e 6e 50 61 67 65 20 2d 20 70 43  ache->nPage - pC
75b0: 61 63 68 65 2d 3e 6e 52 65 63 79 63 6c 61 62 6c  ache->nRecyclabl
75c0: 65 3b 0a 20 20 61 73 73 65 72 74 28 20 70 47 72  e;.  assert( pGr
75d0: 6f 75 70 2d 3e 6d 78 50 69 6e 6e 65 64 20 3d 3d  oup->mxPinned ==
75e0: 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67   pGroup->nMaxPag
75f0: 65 20 2b 20 31 30 20 2d 20 70 47 72 6f 75 70 2d  e + 10 - pGroup-
7600: 3e 6e 4d 69 6e 50 61 67 65 20 29 3b 0a 20 20 61  >nMinPage );.  a
7610: 73 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e 6e  ssert( pCache->n
7620: 39 30 70 63 74 20 3d 3d 20 70 43 61 63 68 65 2d  90pct == pCache-
7630: 3e 6e 4d 61 78 2a 39 2f 31 30 20 29 3b 0a 20 20  >nMax*9/10 );.  
7640: 69 66 28 20 63 72 65 61 74 65 46 6c 61 67 3d 3d  if( createFlag==
7650: 31 20 26 26 20 28 0a 20 20 20 20 20 20 20 20 6e  1 && (.        n
7660: 50 69 6e 6e 65 64 3e 3d 70 47 72 6f 75 70 2d 3e  Pinned>=pGroup->
7670: 6d 78 50 69 6e 6e 65 64 0a 20 20 20 20 20 7c 7c  mxPinned.     ||
7680: 20 6e 50 69 6e 6e 65 64 3e 3d 70 43 61 63 68 65   nPinned>=pCache
7690: 2d 3e 6e 39 30 70 63 74 0a 20 20 20 20 20 7c 7c  ->n90pct.     ||
76a0: 20 28 70 63 61 63 68 65 31 55 6e 64 65 72 4d 65   (pcache1UnderMe
76b0: 6d 6f 72 79 50 72 65 73 73 75 72 65 28 70 43 61  moryPressure(pCa
76c0: 63 68 65 29 20 26 26 20 70 43 61 63 68 65 2d 3e  che) && pCache->
76d0: 6e 52 65 63 79 63 6c 61 62 6c 65 3c 6e 50 69 6e  nRecyclable<nPin
76e0: 6e 65 64 29 0a 20 20 29 29 7b 0a 20 20 20 20 72  ned).  )){.    r
76f0: 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 0a 20 20  eturn 0;.  }..  
7700: 69 66 28 20 70 43 61 63 68 65 2d 3e 6e 50 61 67  if( pCache->nPag
7710: 65 3e 3d 70 43 61 63 68 65 2d 3e 6e 48 61 73 68  e>=pCache->nHash
7720: 20 29 20 70 63 61 63 68 65 31 52 65 73 69 7a 65   ) pcache1Resize
7730: 48 61 73 68 28 70 43 61 63 68 65 29 3b 0a 20 20  Hash(pCache);.  
7740: 61 73 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e  assert( pCache->
7750: 6e 48 61 73 68 3e 30 20 26 26 20 70 43 61 63 68  nHash>0 && pCach
7760: 65 2d 3e 61 70 48 61 73 68 20 29 3b 0a 0a 20 20  e->apHash );..  
7770: 2f 2a 20 53 74 65 70 20 34 2e 20 54 72 79 20 74  /* Step 4. Try t
7780: 6f 20 72 65 63 79 63 6c 65 20 61 20 70 61 67 65  o recycle a page
7790: 2e 20 2a 2f 0a 20 20 69 66 28 20 70 43 61 63 68  . */.  if( pCach
77a0: 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 0a 20 20  e->bPurgeable.  
77b0: 20 26 26 20 21 70 47 72 6f 75 70 2d 3e 6c 72 75   && !pGroup->lru
77c0: 2e 70 4c 72 75 50 72 65 76 2d 3e 69 73 41 6e 63  .pLruPrev->isAnc
77d0: 68 6f 72 0a 20 20 20 26 26 20 28 28 70 43 61 63  hor.   && ((pCac
77e0: 68 65 2d 3e 6e 50 61 67 65 2b 31 3e 3d 70 43 61  he->nPage+1>=pCa
77f0: 63 68 65 2d 3e 6e 4d 61 78 29 20 7c 7c 20 70 63  che->nMax) || pc
7800: 61 63 68 65 31 55 6e 64 65 72 4d 65 6d 6f 72 79  ache1UnderMemory
7810: 50 72 65 73 73 75 72 65 28 70 43 61 63 68 65 29  Pressure(pCache)
7820: 29 0a 20 20 29 7b 0a 20 20 20 20 50 43 61 63 68  ).  ){.    PCach
7830: 65 31 20 2a 70 4f 74 68 65 72 3b 0a 20 20 20 20  e1 *pOther;.    
7840: 70 50 61 67 65 20 3d 20 70 47 72 6f 75 70 2d 3e  pPage = pGroup->
7850: 6c 72 75 2e 70 4c 72 75 50 72 65 76 3b 0a 20 20  lru.pLruPrev;.  
7860: 20 20 61 73 73 65 72 74 28 20 50 41 47 45 5f 49    assert( PAGE_I
7870: 53 5f 55 4e 50 49 4e 4e 45 44 28 70 50 61 67 65  S_UNPINNED(pPage
7880: 29 20 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31  ) );.    pcache1
7890: 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73 68 28 70  RemoveFromHash(p
78a0: 50 61 67 65 2c 20 30 29 3b 0a 20 20 20 20 70 63  Page, 0);.    pc
78b0: 61 63 68 65 31 50 69 6e 50 61 67 65 28 70 50 61  ache1PinPage(pPa
78c0: 67 65 29 3b 0a 20 20 20 20 70 4f 74 68 65 72 20  ge);.    pOther 
78d0: 3d 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65 3b  = pPage->pCache;
78e0: 0a 20 20 20 20 69 66 28 20 70 4f 74 68 65 72 2d  .    if( pOther-
78f0: 3e 73 7a 41 6c 6c 6f 63 20 21 3d 20 70 43 61 63  >szAlloc != pCac
7900: 68 65 2d 3e 73 7a 41 6c 6c 6f 63 20 29 7b 0a 20  he->szAlloc ){. 
7910: 20 20 20 20 20 70 63 61 63 68 65 31 46 72 65 65       pcache1Free
7920: 50 61 67 65 28 70 50 61 67 65 29 3b 0a 20 20 20  Page(pPage);.   
7930: 20 20 20 70 50 61 67 65 20 3d 20 30 3b 0a 20 20     pPage = 0;.  
7940: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70    }else{.      p
7950: 47 72 6f 75 70 2d 3e 6e 50 75 72 67 65 61 62 6c  Group->nPurgeabl
7960: 65 20 2d 3d 20 28 70 4f 74 68 65 72 2d 3e 62 50  e -= (pOther->bP
7970: 75 72 67 65 61 62 6c 65 20 2d 20 70 43 61 63 68  urgeable - pCach
7980: 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 29 3b 0a  e->bPurgeable);.
7990: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20      }.  }..  /* 
79a0: 53 74 65 70 20 35 2e 20 49 66 20 61 20 75 73 61  Step 5. If a usa
79b0: 62 6c 65 20 70 61 67 65 20 62 75 66 66 65 72 20  ble page buffer 
79c0: 68 61 73 20 73 74 69 6c 6c 20 6e 6f 74 20 62 65  has still not be
79d0: 65 6e 20 66 6f 75 6e 64 2c 20 0a 20 20 2a 2a 20  en found, .  ** 
79e0: 61 74 74 65 6d 70 74 20 74 6f 20 61 6c 6c 6f 63  attempt to alloc
79f0: 61 74 65 20 61 20 6e 65 77 20 6f 6e 65 2e 20 0a  ate a new one. .
7a00: 20 20 2a 2f 0a 20 20 69 66 28 20 21 70 50 61 67    */.  if( !pPag
7a10: 65 20 29 7b 0a 20 20 20 20 70 50 61 67 65 20 3d  e ){.    pPage =
7a20: 20 70 63 61 63 68 65 31 41 6c 6c 6f 63 50 61 67   pcache1AllocPag
7a30: 65 28 70 43 61 63 68 65 2c 20 63 72 65 61 74 65  e(pCache, create
7a40: 46 6c 61 67 3d 3d 31 29 3b 0a 20 20 7d 0a 0a 20  Flag==1);.  }.. 
7a50: 20 69 66 28 20 70 50 61 67 65 20 29 7b 0a 20 20   if( pPage ){.  
7a60: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68    unsigned int h
7a70: 20 3d 20 69 4b 65 79 20 25 20 70 43 61 63 68 65   = iKey % pCache
7a80: 2d 3e 6e 48 61 73 68 3b 0a 20 20 20 20 70 43 61  ->nHash;.    pCa
7a90: 63 68 65 2d 3e 6e 50 61 67 65 2b 2b 3b 0a 20 20  che->nPage++;.  
7aa0: 20 20 70 50 61 67 65 2d 3e 69 4b 65 79 20 3d 20    pPage->iKey = 
7ab0: 69 4b 65 79 3b 0a 20 20 20 20 70 50 61 67 65 2d  iKey;.    pPage-
7ac0: 3e 70 4e 65 78 74 20 3d 20 70 43 61 63 68 65 2d  >pNext = pCache-
7ad0: 3e 61 70 48 61 73 68 5b 68 5d 3b 0a 20 20 20 20  >apHash[h];.    
7ae0: 70 50 61 67 65 2d 3e 70 43 61 63 68 65 20 3d 20  pPage->pCache = 
7af0: 70 43 61 63 68 65 3b 0a 20 20 20 20 70 50 61 67  pCache;.    pPag
7b00: 65 2d 3e 70 4c 72 75 50 72 65 76 20 3d 20 30 3b  e->pLruPrev = 0;
7b10: 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 4c 72 75  .    pPage->pLru
7b20: 4e 65 78 74 20 3d 20 30 3b 0a 20 20 20 20 2a 28  Next = 0;.    *(
7b30: 76 6f 69 64 20 2a 2a 29 70 50 61 67 65 2d 3e 70  void **)pPage->p
7b40: 61 67 65 2e 70 45 78 74 72 61 20 3d 20 30 3b 0a  age.pExtra = 0;.
7b50: 20 20 20 20 70 43 61 63 68 65 2d 3e 61 70 48 61      pCache->apHa
7b60: 73 68 5b 68 5d 20 3d 20 70 50 61 67 65 3b 0a 20  sh[h] = pPage;. 
7b70: 20 20 20 69 66 28 20 69 4b 65 79 3e 70 43 61 63     if( iKey>pCac
7b80: 68 65 2d 3e 69 4d 61 78 4b 65 79 20 29 7b 0a 20  he->iMaxKey ){. 
7b90: 20 20 20 20 20 70 43 61 63 68 65 2d 3e 69 4d 61       pCache->iMa
7ba0: 78 4b 65 79 20 3d 20 69 4b 65 79 3b 0a 20 20 20  xKey = iKey;.   
7bb0: 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20   }.  }.  return 
7bc0: 70 50 61 67 65 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  pPage;.}../*.** 
7bd0: 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  Implementation o
7be0: 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63  f the sqlite3_pc
7bf0: 61 63 68 65 2e 78 46 65 74 63 68 20 6d 65 74 68  ache.xFetch meth
7c00: 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20 46 65 74 63 68  od. .**.** Fetch
7c10: 20 61 20 70 61 67 65 20 62 79 20 6b 65 79 20 76   a page by key v
7c20: 61 6c 75 65 2e 0a 2a 2a 0a 2a 2a 20 57 68 65 74  alue..**.** Whet
7c30: 68 65 72 20 6f 72 20 6e 6f 74 20 61 20 6e 65 77  her or not a new
7c40: 20 70 61 67 65 20 6d 61 79 20 62 65 20 61 6c 6c   page may be all
7c50: 6f 63 61 74 65 64 20 62 79 20 74 68 69 73 20 66  ocated by this f
7c60: 75 6e 63 74 69 6f 6e 20 64 65 70 65 6e 64 73 20  unction depends 
7c70: 6f 6e 0a 2a 2a 20 74 68 65 20 76 61 6c 75 65 20  on.** the value 
7c80: 6f 66 20 74 68 65 20 63 72 65 61 74 65 46 6c 61  of the createFla
7c90: 67 20 61 72 67 75 6d 65 6e 74 2e 20 20 30 20 6d  g argument.  0 m
7ca0: 65 61 6e 73 20 64 6f 20 6e 6f 74 20 61 6c 6c 6f  eans do not allo
7cb0: 63 61 74 65 20 61 20 6e 65 77 0a 2a 2a 20 70 61  cate a new.** pa
7cc0: 67 65 2e 20 20 31 20 6d 65 61 6e 73 20 61 6c 6c  ge.  1 means all
7cd0: 6f 63 61 74 65 20 61 20 6e 65 77 20 70 61 67 65  ocate a new page
7ce0: 20 69 66 20 73 70 61 63 65 20 69 73 20 65 61 73   if space is eas
7cf0: 69 6c 79 20 61 76 61 69 6c 61 62 6c 65 2e 20 20  ily available.  
7d00: 32 20 0a 2a 2a 20 6d 65 61 6e 73 20 74 6f 20 74  2 .** means to t
7d10: 72 79 20 72 65 61 6c 6c 79 20 68 61 72 64 20 74  ry really hard t
7d20: 6f 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e 65 77  o allocate a new
7d30: 20 70 61 67 65 2e 0a 2a 2a 0a 2a 2a 20 46 6f 72   page..**.** For
7d40: 20 61 20 6e 6f 6e 2d 70 75 72 67 65 61 62 6c 65   a non-purgeable
7d50: 20 63 61 63 68 65 20 28 61 20 63 61 63 68 65 20   cache (a cache 
7d60: 75 73 65 64 20 61 73 20 74 68 65 20 73 74 6f 72  used as the stor
7d70: 61 67 65 20 66 6f 72 20 61 6e 20 69 6e 2d 6d 65  age for an in-me
7d80: 6d 6f 72 79 0a 2a 2a 20 64 61 74 61 62 61 73 65  mory.** database
7d90: 29 20 74 68 65 72 65 20 69 73 20 72 65 61 6c 6c  ) there is reall
7da0: 79 20 6e 6f 20 64 69 66 66 65 72 65 6e 63 65 20  y no difference 
7db0: 62 65 74 77 65 65 6e 20 63 72 65 61 74 65 46 6c  between createFl
7dc0: 61 67 20 31 20 61 6e 64 20 32 2e 20 20 53 6f 0a  ag 1 and 2.  So.
7dd0: 2a 2a 20 74 68 65 20 63 61 6c 6c 69 6e 67 20 66  ** the calling f
7de0: 75 6e 63 74 69 6f 6e 20 28 70 63 61 63 68 65 2e  unction (pcache.
7df0: 63 29 20 77 69 6c 6c 20 6e 65 76 65 72 20 68 61  c) will never ha
7e00: 76 65 20 61 20 63 72 65 61 74 65 46 6c 61 67 20  ve a createFlag 
7e10: 6f 66 20 31 20 6f 6e 0a 2a 2a 20 61 20 6e 6f 6e  of 1 on.** a non
7e20: 2d 70 75 72 67 65 61 62 6c 65 20 63 61 63 68 65  -purgeable cache
7e30: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 72 65 20 61 72  ..**.** There ar
7e40: 65 20 74 68 72 65 65 20 64 69 66 66 65 72 65 6e  e three differen
7e50: 74 20 61 70 70 72 6f 61 63 68 65 73 20 74 6f 20  t approaches to 
7e60: 6f 62 74 61 69 6e 69 6e 67 20 73 70 61 63 65 20  obtaining space 
7e70: 66 6f 72 20 61 20 70 61 67 65 2c 0a 2a 2a 20 64  for a page,.** d
7e80: 65 70 65 6e 64 69 6e 67 20 6f 6e 20 74 68 65 20  epending on the 
7e90: 76 61 6c 75 65 20 6f 66 20 70 61 72 61 6d 65 74  value of paramet
7ea0: 65 72 20 63 72 65 61 74 65 46 6c 61 67 20 28 77  er createFlag (w
7eb0: 68 69 63 68 20 6d 61 79 20 62 65 20 30 2c 20 31  hich may be 0, 1
7ec0: 20 6f 72 20 32 29 2e 0a 2a 2a 0a 2a 2a 20 20 20   or 2)..**.**   
7ed0: 31 2e 20 52 65 67 61 72 64 6c 65 73 73 20 6f 66  1. Regardless of
7ee0: 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20 63 72   the value of cr
7ef0: 65 61 74 65 46 6c 61 67 2c 20 74 68 65 20 63 61  eateFlag, the ca
7f00: 63 68 65 20 69 73 20 73 65 61 72 63 68 65 64 20  che is searched 
7f10: 66 6f 72 20 61 20 0a 2a 2a 20 20 20 20 20 20 63  for a .**      c
7f20: 6f 70 79 20 6f 66 20 74 68 65 20 72 65 71 75 65  opy of the reque
7f30: 73 74 65 64 20 70 61 67 65 2e 20 49 66 20 6f 6e  sted page. If on
7f40: 65 20 69 73 20 66 6f 75 6e 64 2c 20 69 74 20 69  e is found, it i
7f50: 73 20 72 65 74 75 72 6e 65 64 2e 0a 2a 2a 0a 2a  s returned..**.*
7f60: 2a 20 20 20 32 2e 20 49 66 20 63 72 65 61 74 65  *   2. If create
7f70: 46 6c 61 67 3d 3d 30 20 61 6e 64 20 74 68 65 20  Flag==0 and the 
7f80: 70 61 67 65 20 69 73 20 6e 6f 74 20 61 6c 72 65  page is not alre
7f90: 61 64 79 20 69 6e 20 74 68 65 20 63 61 63 68 65  ady in the cache
7fa0: 2c 20 4e 55 4c 4c 20 69 73 0a 2a 2a 20 20 20 20  , NULL is.**    
7fb0: 20 20 72 65 74 75 72 6e 65 64 2e 0a 2a 2a 0a 2a    returned..**.*
7fc0: 2a 20 20 20 33 2e 20 49 66 20 63 72 65 61 74 65  *   3. If create
7fd0: 46 6c 61 67 20 69 73 20 31 2c 20 61 6e 64 20 74  Flag is 1, and t
7fe0: 68 65 20 70 61 67 65 20 69 73 20 6e 6f 74 20 61  he page is not a
7ff0: 6c 72 65 61 64 79 20 69 6e 20 74 68 65 20 63 61  lready in the ca
8000: 63 68 65 2c 20 74 68 65 6e 0a 2a 2a 20 20 20 20  che, then.**    
8010: 20 20 72 65 74 75 72 6e 20 4e 55 4c 4c 20 28 64    return NULL (d
8020: 6f 20 6e 6f 74 20 61 6c 6c 6f 63 61 74 65 20 61  o not allocate a
8030: 20 6e 65 77 20 70 61 67 65 29 20 69 66 20 61 6e   new page) if an
8040: 79 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69  y of the followi
8050: 6e 67 0a 2a 2a 20 20 20 20 20 20 63 6f 6e 64 69  ng.**      condi
8060: 74 69 6f 6e 73 20 61 72 65 20 74 72 75 65 3a 0a  tions are true:.
8070: 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 28 61 29 20  **.**       (a) 
8080: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 61  the number of pa
8090: 67 65 73 20 70 69 6e 6e 65 64 20 62 79 20 74 68  ges pinned by th
80a0: 65 20 63 61 63 68 65 20 69 73 20 67 72 65 61 74  e cache is great
80b0: 65 72 20 74 68 61 6e 0a 2a 2a 20 20 20 20 20 20  er than.**      
80c0: 20 20 20 20 20 50 43 61 63 68 65 31 2e 6e 4d 61       PCache1.nMa
80d0: 78 2c 20 6f 72 0a 2a 2a 0a 2a 2a 20 20 20 20 20  x, or.**.**     
80e0: 20 20 28 62 29 20 74 68 65 20 6e 75 6d 62 65 72    (b) the number
80f0: 20 6f 66 20 70 61 67 65 73 20 70 69 6e 6e 65 64   of pages pinned
8100: 20 62 79 20 74 68 65 20 63 61 63 68 65 20 69 73   by the cache is
8110: 20 67 72 65 61 74 65 72 20 74 68 61 6e 0a 2a 2a   greater than.**
8120: 20 20 20 20 20 20 20 20 20 20 20 74 68 65 20 73             the s
8130: 75 6d 20 6f 66 20 6e 4d 61 78 20 66 6f 72 20 61  um of nMax for a
8140: 6c 6c 20 70 75 72 67 65 61 62 6c 65 20 63 61 63  ll purgeable cac
8150: 68 65 73 2c 20 6c 65 73 73 20 74 68 65 20 73 75  hes, less the su
8160: 6d 20 6f 66 20 0a 2a 2a 20 20 20 20 20 20 20 20  m of .**        
8170: 20 20 20 6e 4d 69 6e 20 66 6f 72 20 61 6c 6c 20     nMin for all 
8180: 6f 74 68 65 72 20 70 75 72 67 65 61 62 6c 65 20  other purgeable 
8190: 63 61 63 68 65 73 2c 20 6f 72 0a 2a 2a 0a 2a 2a  caches, or.**.**
81a0: 20 20 20 34 2e 20 49 66 20 6e 6f 6e 65 20 6f 66     4. If none of
81b0: 20 74 68 65 20 66 69 72 73 74 20 74 68 72 65 65   the first three
81c0: 20 63 6f 6e 64 69 74 69 6f 6e 73 20 61 70 70 6c   conditions appl
81d0: 79 20 61 6e 64 20 74 68 65 20 63 61 63 68 65 20  y and the cache 
81e0: 69 73 20 6d 61 72 6b 65 64 0a 2a 2a 20 20 20 20  is marked.**    
81f0: 20 20 61 73 20 70 75 72 67 65 61 62 6c 65 2c 20    as purgeable, 
8200: 61 6e 64 20 69 66 20 6f 6e 65 20 6f 66 20 74 68  and if one of th
8210: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 69 73 20 74  e following is t
8220: 72 75 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20  rue:.**.**      
8230: 20 28 61 29 20 54 68 65 20 6e 75 6d 62 65 72 20   (a) The number 
8240: 6f 66 20 70 61 67 65 73 20 61 6c 6c 6f 63 61 74  of pages allocat
8250: 65 64 20 66 6f 72 20 74 68 65 20 63 61 63 68 65  ed for the cache
8260: 20 69 73 20 61 6c 72 65 61 64 79 20 0a 2a 2a 20   is already .** 
8270: 20 20 20 20 20 20 20 20 20 20 50 43 61 63 68 65            PCache
8280: 31 2e 6e 4d 61 78 2c 20 6f 72 0a 2a 2a 0a 2a 2a  1.nMax, or.**.**
8290: 20 20 20 20 20 20 20 28 62 29 20 54 68 65 20 6e         (b) The n
82a0: 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 61  umber of pages a
82b0: 6c 6c 6f 63 61 74 65 64 20 66 6f 72 20 61 6c 6c  llocated for all
82c0: 20 70 75 72 67 65 61 62 6c 65 20 63 61 63 68 65   purgeable cache
82d0: 73 20 69 73 0a 2a 2a 20 20 20 20 20 20 20 20 20  s is.**         
82e0: 20 20 61 6c 72 65 61 64 79 20 65 71 75 61 6c 20    already equal 
82f0: 74 6f 20 6f 72 20 67 72 65 61 74 65 72 20 74 68  to or greater th
8300: 61 6e 20 74 68 65 20 73 75 6d 20 6f 66 20 6e 4d  an the sum of nM
8310: 61 78 20 66 6f 72 20 61 6c 6c 0a 2a 2a 20 20 20  ax for all.**   
8320: 20 20 20 20 20 20 20 20 70 75 72 67 65 61 62 6c          purgeabl
8330: 65 20 63 61 63 68 65 73 2c 0a 2a 2a 0a 2a 2a 20  e caches,.**.** 
8340: 20 20 20 20 20 20 28 63 29 20 54 68 65 20 73 79        (c) The sy
8350: 73 74 65 6d 20 69 73 20 75 6e 64 65 72 20 6d 65  stem is under me
8360: 6d 6f 72 79 20 70 72 65 73 73 75 72 65 20 61 6e  mory pressure an
8370: 64 20 77 61 6e 74 73 20 74 6f 20 61 76 6f 69 64  d wants to avoid
8380: 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 75 6e  .**           un
8390: 6e 65 63 65 73 73 61 72 79 20 70 61 67 65 73 20  necessary pages 
83a0: 63 61 63 68 65 20 65 6e 74 72 79 20 61 6c 6c 6f  cache entry allo
83b0: 63 61 74 69 6f 6e 73 0a 2a 2a 0a 2a 2a 20 20 20  cations.**.**   
83c0: 20 20 20 74 68 65 6e 20 61 74 74 65 6d 70 74 20     then attempt 
83d0: 74 6f 20 72 65 63 79 63 6c 65 20 61 20 70 61 67  to recycle a pag
83e0: 65 20 66 72 6f 6d 20 74 68 65 20 4c 52 55 20 6c  e from the LRU l
83f0: 69 73 74 2e 20 49 66 20 69 74 20 69 73 20 74 68  ist. If it is th
8400: 65 20 72 69 67 68 74 0a 2a 2a 20 20 20 20 20 20  e right.**      
8410: 73 69 7a 65 2c 20 72 65 74 75 72 6e 20 74 68 65  size, return the
8420: 20 72 65 63 79 63 6c 65 64 20 62 75 66 66 65 72   recycled buffer
8430: 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 66 72 65  . Otherwise, fre
8440: 65 20 74 68 65 20 62 75 66 66 65 72 20 61 6e 64  e the buffer and
8450: 0a 2a 2a 20 20 20 20 20 20 70 72 6f 63 65 65 64  .**      proceed
8460: 20 74 6f 20 73 74 65 70 20 35 2e 20 0a 2a 2a 0a   to step 5. .**.
8470: 2a 2a 20 20 20 35 2e 20 4f 74 68 65 72 77 69 73  **   5. Otherwis
8480: 65 2c 20 61 6c 6c 6f 63 61 74 65 20 61 6e 64 20  e, allocate and 
8490: 72 65 74 75 72 6e 20 61 20 6e 65 77 20 70 61 67  return a new pag
84a0: 65 20 62 75 66 66 65 72 2e 0a 2a 2a 0a 2a 2a 20  e buffer..**.** 
84b0: 54 68 65 72 65 20 61 72 65 20 74 77 6f 20 76 65  There are two ve
84c0: 72 73 69 6f 6e 73 20 6f 66 20 74 68 69 73 20 72  rsions of this r
84d0: 6f 75 74 69 6e 65 2e 20 20 70 63 61 63 68 65 31  outine.  pcache1
84e0: 46 65 74 63 68 57 69 74 68 4d 75 74 65 78 28 29  FetchWithMutex()
84f0: 20 69 73 0a 2a 2a 20 74 68 65 20 67 65 6e 65 72   is.** the gener
8500: 61 6c 20 63 61 73 65 2e 20 20 70 63 61 63 68 65  al case.  pcache
8510: 31 46 65 74 63 68 4e 6f 4d 75 74 65 78 28 29 20  1FetchNoMutex() 
8520: 69 73 20 61 20 66 61 73 74 65 72 20 69 6d 70 6c  is a faster impl
8530: 65 6d 65 6e 74 61 74 69 6f 6e 20 66 6f 72 0a 2a  ementation for.*
8540: 2a 20 74 68 65 20 63 6f 6d 6d 6f 6e 20 63 61 73  * the common cas
8550: 65 20 77 68 65 72 65 20 70 47 72 6f 75 70 2d 3e  e where pGroup->
8560: 6d 75 74 65 78 20 69 73 20 4e 55 4c 4c 2e 20 20  mutex is NULL.  
8570: 54 68 65 20 70 63 61 63 68 65 31 46 65 74 63 68  The pcache1Fetch
8580: 28 29 20 77 72 61 70 70 65 72 0a 2a 2a 20 69 6e  () wrapper.** in
8590: 76 6f 6b 65 73 20 74 68 65 20 61 70 70 72 6f 70  vokes the approp
85a0: 72 69 61 74 65 20 72 6f 75 74 69 6e 65 2e 0a 2a  riate routine..*
85b0: 2f 0a 73 74 61 74 69 63 20 50 67 48 64 72 31 20  /.static PgHdr1 
85c0: 2a 70 63 61 63 68 65 31 46 65 74 63 68 4e 6f 4d  *pcache1FetchNoM
85d0: 75 74 65 78 28 0a 20 20 73 71 6c 69 74 65 33 5f  utex(.  sqlite3_
85e0: 70 63 61 63 68 65 20 2a 70 2c 20 0a 20 20 75 6e  pcache *p, .  un
85f0: 73 69 67 6e 65 64 20 69 6e 74 20 69 4b 65 79 2c  signed int iKey,
8600: 20 0a 20 20 69 6e 74 20 63 72 65 61 74 65 46 6c   .  int createFl
8610: 61 67 0a 29 7b 0a 20 20 50 43 61 63 68 65 31 20  ag.){.  PCache1 
8620: 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61 63 68  *pCache = (PCach
8630: 65 31 20 2a 29 70 3b 0a 20 20 50 67 48 64 72 31  e1 *)p;.  PgHdr1
8640: 20 2a 70 50 61 67 65 20 3d 20 30 3b 0a 0a 20 20   *pPage = 0;..  
8650: 2f 2a 20 53 74 65 70 20 31 3a 20 53 65 61 72 63  /* Step 1: Searc
8660: 68 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65  h the hash table
8670: 20 66 6f 72 20 61 6e 20 65 78 69 73 74 69 6e 67   for an existing
8680: 20 65 6e 74 72 79 2e 20 2a 2f 0a 20 20 70 50 61   entry. */.  pPa
8690: 67 65 20 3d 20 70 43 61 63 68 65 2d 3e 61 70 48  ge = pCache->apH
86a0: 61 73 68 5b 69 4b 65 79 20 25 20 70 43 61 63 68  ash[iKey % pCach
86b0: 65 2d 3e 6e 48 61 73 68 5d 3b 0a 20 20 77 68 69  e->nHash];.  whi
86c0: 6c 65 28 20 70 50 61 67 65 20 26 26 20 70 50 61  le( pPage && pPa
86d0: 67 65 2d 3e 69 4b 65 79 21 3d 69 4b 65 79 20 29  ge->iKey!=iKey )
86e0: 7b 20 70 50 61 67 65 20 3d 20 70 50 61 67 65 2d  { pPage = pPage-
86f0: 3e 70 4e 65 78 74 3b 20 7d 0a 0a 20 20 2f 2a 20  >pNext; }..  /* 
8700: 53 74 65 70 20 32 3a 20 49 66 20 74 68 65 20 70  Step 2: If the p
8710: 61 67 65 20 77 61 73 20 66 6f 75 6e 64 20 69 6e  age was found in
8720: 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 2c   the hash table,
8730: 20 74 68 65 6e 20 72 65 74 75 72 6e 20 69 74 2e   then return it.
8740: 0a 20 20 2a 2a 20 49 66 20 74 68 65 20 70 61 67  .  ** If the pag
8750: 65 20 77 61 73 20 6e 6f 74 20 69 6e 20 74 68 65  e was not in the
8760: 20 68 61 73 68 20 74 61 62 6c 65 20 61 6e 64 20   hash table and 
8770: 63 72 65 61 74 65 46 6c 61 67 20 69 73 20 30 2c  createFlag is 0,
8780: 20 61 62 6f 72 74 2e 0a 20 20 2a 2a 20 4f 74 68   abort..  ** Oth
8790: 65 72 77 69 73 65 20 28 70 61 67 65 20 6e 6f 74  erwise (page not
87a0: 20 69 6e 20 68 61 73 68 20 61 6e 64 20 63 72 65   in hash and cre
87b0: 61 74 65 46 6c 61 67 21 3d 30 29 20 63 6f 6e 74  ateFlag!=0) cont
87c0: 69 6e 75 65 20 77 69 74 68 0a 20 20 2a 2a 20 73  inue with.  ** s
87d0: 75 62 73 65 71 75 65 6e 74 20 73 74 65 70 73 20  ubsequent steps 
87e0: 74 6f 20 74 72 79 20 74 6f 20 63 72 65 61 74 65  to try to create
87f0: 20 74 68 65 20 70 61 67 65 2e 20 2a 2f 0a 20 20   the page. */.  
8800: 69 66 28 20 70 50 61 67 65 20 29 7b 0a 20 20 20  if( pPage ){.   
8810: 20 69 66 28 20 50 41 47 45 5f 49 53 5f 55 4e 50   if( PAGE_IS_UNP
8820: 49 4e 4e 45 44 28 70 50 61 67 65 29 20 29 7b 0a  INNED(pPage) ){.
8830: 20 20 20 20 20 20 72 65 74 75 72 6e 20 70 63 61        return pca
8840: 63 68 65 31 50 69 6e 50 61 67 65 28 70 50 61 67  che1PinPage(pPag
8850: 65 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  e);.    }else{. 
8860: 20 20 20 20 20 72 65 74 75 72 6e 20 70 50 61 67       return pPag
8870: 65 3b 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65  e;.    }.  }else
8880: 20 69 66 28 20 63 72 65 61 74 65 46 6c 61 67 20   if( createFlag 
8890: 29 7b 0a 20 20 20 20 2f 2a 20 53 74 65 70 73 20  ){.    /* Steps 
88a0: 33 2c 20 34 2c 20 61 6e 64 20 35 20 69 6d 70 6c  3, 4, and 5 impl
88b0: 65 6d 65 6e 74 65 64 20 62 79 20 74 68 69 73 20  emented by this 
88c0: 73 75 62 72 6f 75 74 69 6e 65 20 2a 2f 0a 20 20  subroutine */.  
88d0: 20 20 72 65 74 75 72 6e 20 70 63 61 63 68 65 31    return pcache1
88e0: 46 65 74 63 68 53 74 61 67 65 32 28 70 43 61 63  FetchStage2(pCac
88f0: 68 65 2c 20 69 4b 65 79 2c 20 63 72 65 61 74 65  he, iKey, create
8900: 46 6c 61 67 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a  Flag);.  }else{.
8910: 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20      return 0;.  
8920: 7d 0a 7d 0a 23 69 66 20 50 43 41 43 48 45 31 5f  }.}.#if PCACHE1_
8930: 4d 49 47 48 54 5f 55 53 45 5f 47 52 4f 55 50 5f  MIGHT_USE_GROUP_
8940: 4d 55 54 45 58 0a 73 74 61 74 69 63 20 50 67 48  MUTEX.static PgH
8950: 64 72 31 20 2a 70 63 61 63 68 65 31 46 65 74 63  dr1 *pcache1Fetc
8960: 68 57 69 74 68 4d 75 74 65 78 28 0a 20 20 73 71  hWithMutex(.  sq
8970: 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70 2c  lite3_pcache *p,
8980: 20 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74   .  unsigned int
8990: 20 69 4b 65 79 2c 20 0a 20 20 69 6e 74 20 63 72   iKey, .  int cr
89a0: 65 61 74 65 46 6c 61 67 0a 29 7b 0a 20 20 50 43  eateFlag.){.  PC
89b0: 61 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20  ache1 *pCache = 
89c0: 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20 20  (PCache1 *)p;.  
89d0: 50 67 48 64 72 31 20 2a 70 50 61 67 65 3b 0a 0a  PgHdr1 *pPage;..
89e0: 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75    pcache1EnterMu
89f0: 74 65 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f  tex(pCache->pGro
8a00: 75 70 29 3b 0a 20 20 70 50 61 67 65 20 3d 20 70  up);.  pPage = p
8a10: 63 61 63 68 65 31 46 65 74 63 68 4e 6f 4d 75 74  cache1FetchNoMut
8a20: 65 78 28 70 2c 20 69 4b 65 79 2c 20 63 72 65 61  ex(p, iKey, crea
8a30: 74 65 46 6c 61 67 29 3b 0a 20 20 61 73 73 65 72  teFlag);.  asser
8a40: 74 28 20 70 50 61 67 65 3d 3d 30 20 7c 7c 20 70  t( pPage==0 || p
8a50: 43 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79 3e 3d  Cache->iMaxKey>=
8a60: 69 4b 65 79 20 29 3b 0a 20 20 70 63 61 63 68 65  iKey );.  pcache
8a70: 31 4c 65 61 76 65 4d 75 74 65 78 28 70 43 61 63  1LeaveMutex(pCac
8a80: 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 20 20 72  he->pGroup);.  r
8a90: 65 74 75 72 6e 20 70 50 61 67 65 3b 0a 7d 0a 23  eturn pPage;.}.#
8aa0: 65 6e 64 69 66 0a 73 74 61 74 69 63 20 73 71 6c  endif.static sql
8ab0: 69 74 65 33 5f 70 63 61 63 68 65 5f 70 61 67 65  ite3_pcache_page
8ac0: 20 2a 70 63 61 63 68 65 31 46 65 74 63 68 28 0a   *pcache1Fetch(.
8ad0: 20 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65    sqlite3_pcache
8ae0: 20 2a 70 2c 20 0a 20 20 75 6e 73 69 67 6e 65 64   *p, .  unsigned
8af0: 20 69 6e 74 20 69 4b 65 79 2c 20 0a 20 20 69 6e   int iKey, .  in
8b00: 74 20 63 72 65 61 74 65 46 6c 61 67 0a 29 7b 0a  t createFlag.){.
8b10: 23 69 66 20 50 43 41 43 48 45 31 5f 4d 49 47 48  #if PCACHE1_MIGH
8b20: 54 5f 55 53 45 5f 47 52 4f 55 50 5f 4d 55 54 45  T_USE_GROUP_MUTE
8b30: 58 20 7c 7c 20 64 65 66 69 6e 65 64 28 53 51 4c  X || defined(SQL
8b40: 49 54 45 5f 44 45 42 55 47 29 0a 20 20 50 43 61  ITE_DEBUG).  PCa
8b50: 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28  che1 *pCache = (
8b60: 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 23 65 6e  PCache1 *)p;.#en
8b70: 64 69 66 0a 0a 20 20 61 73 73 65 72 74 28 20 6f  dif..  assert( o
8b80: 66 66 73 65 74 6f 66 28 50 67 48 64 72 31 2c 70  ffsetof(PgHdr1,p
8b90: 61 67 65 29 3d 3d 30 20 29 3b 0a 20 20 61 73 73  age)==0 );.  ass
8ba0: 65 72 74 28 20 70 43 61 63 68 65 2d 3e 62 50 75  ert( pCache->bPu
8bb0: 72 67 65 61 62 6c 65 20 7c 7c 20 63 72 65 61 74  rgeable || creat
8bc0: 65 46 6c 61 67 21 3d 31 20 29 3b 0a 20 20 61 73  eFlag!=1 );.  as
8bd0: 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e 62 50  sert( pCache->bP
8be0: 75 72 67 65 61 62 6c 65 20 7c 7c 20 70 43 61 63  urgeable || pCac
8bf0: 68 65 2d 3e 6e 4d 69 6e 3d 3d 30 20 29 3b 0a 20  he->nMin==0 );. 
8c00: 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65 2d   assert( pCache-
8c10: 3e 62 50 75 72 67 65 61 62 6c 65 3d 3d 30 20 7c  >bPurgeable==0 |
8c20: 7c 20 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 3d 3d  | pCache->nMin==
8c30: 31 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  10 );.  assert( 
8c40: 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 3d 3d 30 20  pCache->nMin==0 
8c50: 7c 7c 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67  || pCache->bPurg
8c60: 65 61 62 6c 65 20 29 3b 0a 20 20 61 73 73 65 72  eable );.  asser
8c70: 74 28 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68  t( pCache->nHash
8c80: 3e 30 20 29 3b 0a 23 69 66 20 50 43 41 43 48 45  >0 );.#if PCACHE
8c90: 31 5f 4d 49 47 48 54 5f 55 53 45 5f 47 52 4f 55  1_MIGHT_USE_GROU
8ca0: 50 5f 4d 55 54 45 58 0a 20 20 69 66 28 20 70 43  P_MUTEX.  if( pC
8cb0: 61 63 68 65 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75  ache->pGroup->mu
8cc0: 74 65 78 20 29 7b 0a 20 20 20 20 72 65 74 75 72  tex ){.    retur
8cd0: 6e 20 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68  n (sqlite3_pcach
8ce0: 65 5f 70 61 67 65 2a 29 70 63 61 63 68 65 31 46  e_page*)pcache1F
8cf0: 65 74 63 68 57 69 74 68 4d 75 74 65 78 28 70 2c  etchWithMutex(p,
8d00: 20 69 4b 65 79 2c 20 63 72 65 61 74 65 46 6c 61   iKey, createFla
8d10: 67 29 3b 0a 20 20 7d 65 6c 73 65 0a 23 65 6e 64  g);.  }else.#end
8d20: 69 66 0a 20 20 7b 0a 20 20 20 20 72 65 74 75 72  if.  {.    retur
8d30: 6e 20 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68  n (sqlite3_pcach
8d40: 65 5f 70 61 67 65 2a 29 70 63 61 63 68 65 31 46  e_page*)pcache1F
8d50: 65 74 63 68 4e 6f 4d 75 74 65 78 28 70 2c 20 69  etchNoMutex(p, i
8d60: 4b 65 79 2c 20 63 72 65 61 74 65 46 6c 61 67 29  Key, createFlag)
8d70: 3b 0a 20 20 7d 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20  ;.  }.}.../*.** 
8d80: 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  Implementation o
8d90: 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63  f the sqlite3_pc
8da0: 61 63 68 65 2e 78 55 6e 70 69 6e 20 6d 65 74 68  ache.xUnpin meth
8db0: 6f 64 2e 0a 2a 2a 0a 2a 2a 20 4d 61 72 6b 20 61  od..**.** Mark a
8dc0: 20 70 61 67 65 20 61 73 20 75 6e 70 69 6e 6e 65   page as unpinne
8dd0: 64 20 28 65 6c 69 67 69 62 6c 65 20 66 6f 72 20  d (eligible for 
8de0: 61 73 79 6e 63 68 72 6f 6e 6f 75 73 20 72 65 63  asynchronous rec
8df0: 79 63 6c 69 6e 67 29 2e 0a 2a 2f 0a 73 74 61 74  ycling)..*/.stat
8e00: 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 31 55  ic void pcache1U
8e10: 6e 70 69 6e 28 0a 20 20 73 71 6c 69 74 65 33 5f  npin(.  sqlite3_
8e20: 70 63 61 63 68 65 20 2a 70 2c 20 0a 20 20 73 71  pcache *p, .  sq
8e30: 6c 69 74 65 33 5f 70 63 61 63 68 65 5f 70 61 67  lite3_pcache_pag
8e40: 65 20 2a 70 50 67 2c 20 0a 20 20 69 6e 74 20 72  e *pPg, .  int r
8e50: 65 75 73 65 55 6e 6c 69 6b 65 6c 79 0a 29 7b 0a  euseUnlikely.){.
8e60: 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68    PCache1 *pCach
8e70: 65 20 3d 20 28 50 43 61 63 68 65 31 20 2a 29 70  e = (PCache1 *)p
8e80: 3b 0a 20 20 50 67 48 64 72 31 20 2a 70 50 61 67  ;.  PgHdr1 *pPag
8e90: 65 20 3d 20 28 50 67 48 64 72 31 20 2a 29 70 50  e = (PgHdr1 *)pP
8ea0: 67 3b 0a 20 20 50 47 72 6f 75 70 20 2a 70 47 72  g;.  PGroup *pGr
8eb0: 6f 75 70 20 3d 20 70 43 61 63 68 65 2d 3e 70 47  oup = pCache->pG
8ec0: 72 6f 75 70 3b 0a 20 0a 20 20 61 73 73 65 72 74  roup;. .  assert
8ed0: 28 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65 3d  ( pPage->pCache=
8ee0: 3d 70 43 61 63 68 65 20 29 3b 0a 20 20 70 63 61  =pCache );.  pca
8ef0: 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70  che1EnterMutex(p
8f00: 47 72 6f 75 70 29 3b 0a 0a 20 20 2f 2a 20 49 74  Group);..  /* It
8f10: 20 69 73 20 61 6e 20 65 72 72 6f 72 20 74 6f 20   is an error to 
8f20: 63 61 6c 6c 20 74 68 69 73 20 66 75 6e 63 74 69  call this functi
8f30: 6f 6e 20 69 66 20 74 68 65 20 70 61 67 65 20 69  on if the page i
8f40: 73 20 61 6c 72 65 61 64 79 20 0a 20 20 2a 2a 20  s already .  ** 
8f50: 70 61 72 74 20 6f 66 20 74 68 65 20 50 47 72 6f  part of the PGro
8f60: 75 70 20 4c 52 55 20 6c 69 73 74 2e 0a 20 20 2a  up LRU list..  *
8f70: 2f 0a 20 20 61 73 73 65 72 74 28 20 70 50 61 67  /.  assert( pPag
8f80: 65 2d 3e 70 4c 72 75 50 72 65 76 3d 3d 30 20 26  e->pLruPrev==0 &
8f90: 26 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78  & pPage->pLruNex
8fa0: 74 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74  t==0 );.  assert
8fb0: 28 20 50 41 47 45 5f 49 53 5f 50 49 4e 4e 45 44  ( PAGE_IS_PINNED
8fc0: 28 70 50 61 67 65 29 20 29 3b 0a 0a 20 20 69 66  (pPage) );..  if
8fd0: 28 20 72 65 75 73 65 55 6e 6c 69 6b 65 6c 79 20  ( reuseUnlikely 
8fe0: 7c 7c 20 70 47 72 6f 75 70 2d 3e 6e 50 75 72 67  || pGroup->nPurg
8ff0: 65 61 62 6c 65 3e 70 47 72 6f 75 70 2d 3e 6e 4d  eable>pGroup->nM
9000: 61 78 50 61 67 65 20 29 7b 0a 20 20 20 20 70 63  axPage ){.    pc
9010: 61 63 68 65 31 52 65 6d 6f 76 65 46 72 6f 6d 48  ache1RemoveFromH
9020: 61 73 68 28 70 50 61 67 65 2c 20 31 29 3b 0a 20  ash(pPage, 1);. 
9030: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 2f 2a 20 41   }else{.    /* A
9040: 64 64 20 74 68 65 20 70 61 67 65 20 74 6f 20 74  dd the page to t
9050: 68 65 20 50 47 72 6f 75 70 20 4c 52 55 20 6c 69  he PGroup LRU li
9060: 73 74 2e 20 2a 2f 0a 20 20 20 20 50 67 48 64 72  st. */.    PgHdr
9070: 31 20 2a 2a 70 70 46 69 72 73 74 20 3d 20 26 70  1 **ppFirst = &p
9080: 47 72 6f 75 70 2d 3e 6c 72 75 2e 70 4c 72 75 4e  Group->lru.pLruN
9090: 65 78 74 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e  ext;.    pPage->
90a0: 70 4c 72 75 50 72 65 76 20 3d 20 26 70 47 72 6f  pLruPrev = &pGro
90b0: 75 70 2d 3e 6c 72 75 3b 0a 20 20 20 20 28 70 50  up->lru;.    (pP
90c0: 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 20 3d 20  age->pLruNext = 
90d0: 2a 70 70 46 69 72 73 74 29 2d 3e 70 4c 72 75 50  *ppFirst)->pLruP
90e0: 72 65 76 20 3d 20 70 50 61 67 65 3b 0a 20 20 20  rev = pPage;.   
90f0: 20 2a 70 70 46 69 72 73 74 20 3d 20 70 50 61 67   *ppFirst = pPag
9100: 65 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 6e  e;.    pCache->n
9110: 52 65 63 79 63 6c 61 62 6c 65 2b 2b 3b 0a 20 20  Recyclable++;.  
9120: 7d 0a 0a 20 20 70 63 61 63 68 65 31 4c 65 61 76  }..  pcache1Leav
9130: 65 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e 70  eMutex(pCache->p
9140: 47 72 6f 75 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  Group);.}../*.**
9150: 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20   Implementation 
9160: 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70  of the sqlite3_p
9170: 63 61 63 68 65 2e 78 52 65 6b 65 79 20 6d 65 74  cache.xRekey met
9180: 68 6f 64 2e 20 0a 2a 2f 0a 73 74 61 74 69 63 20  hod. .*/.static 
9190: 76 6f 69 64 20 70 63 61 63 68 65 31 52 65 6b 65  void pcache1Reke
91a0: 79 28 0a 20 20 73 71 6c 69 74 65 33 5f 70 63 61  y(.  sqlite3_pca
91b0: 63 68 65 20 2a 70 2c 0a 20 20 73 71 6c 69 74 65  che *p,.  sqlite
91c0: 33 5f 70 63 61 63 68 65 5f 70 61 67 65 20 2a 70  3_pcache_page *p
91d0: 50 67 2c 0a 20 20 75 6e 73 69 67 6e 65 64 20 69  Pg,.  unsigned i
91e0: 6e 74 20 69 4f 6c 64 2c 0a 20 20 75 6e 73 69 67  nt iOld,.  unsig
91f0: 6e 65 64 20 69 6e 74 20 69 4e 65 77 0a 29 7b 0a  ned int iNew.){.
9200: 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68    PCache1 *pCach
9210: 65 20 3d 20 28 50 43 61 63 68 65 31 20 2a 29 70  e = (PCache1 *)p
9220: 3b 0a 20 20 50 67 48 64 72 31 20 2a 70 50 61 67  ;.  PgHdr1 *pPag
9230: 65 20 3d 20 28 50 67 48 64 72 31 20 2a 29 70 50  e = (PgHdr1 *)pP
9240: 67 3b 0a 20 20 50 67 48 64 72 31 20 2a 2a 70 70  g;.  PgHdr1 **pp
9250: 3b 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74  ;.  unsigned int
9260: 20 68 3b 20 0a 20 20 61 73 73 65 72 74 28 20 70   h; .  assert( p
9270: 50 61 67 65 2d 3e 69 4b 65 79 3d 3d 69 4f 6c 64  Page->iKey==iOld
9280: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 50   );.  assert( pP
9290: 61 67 65 2d 3e 70 43 61 63 68 65 3d 3d 70 43 61  age->pCache==pCa
92a0: 63 68 65 20 29 3b 0a 0a 20 20 70 63 61 63 68 65  che );..  pcache
92b0: 31 45 6e 74 65 72 4d 75 74 65 78 28 70 43 61 63  1EnterMutex(pCac
92c0: 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 0a 20 20  he->pGroup);..  
92d0: 68 20 3d 20 69 4f 6c 64 25 70 43 61 63 68 65 2d  h = iOld%pCache-
92e0: 3e 6e 48 61 73 68 3b 0a 20 20 70 70 20 3d 20 26  >nHash;.  pp = &
92f0: 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68  pCache->apHash[h
9300: 5d 3b 0a 20 20 77 68 69 6c 65 28 20 28 2a 70 70  ];.  while( (*pp
9310: 29 21 3d 70 50 61 67 65 20 29 7b 0a 20 20 20 20  )!=pPage ){.    
9320: 70 70 20 3d 20 26 28 2a 70 70 29 2d 3e 70 4e 65  pp = &(*pp)->pNe
9330: 78 74 3b 0a 20 20 7d 0a 20 20 2a 70 70 20 3d 20  xt;.  }.  *pp = 
9340: 70 50 61 67 65 2d 3e 70 4e 65 78 74 3b 0a 0a 20  pPage->pNext;.. 
9350: 20 68 20 3d 20 69 4e 65 77 25 70 43 61 63 68 65   h = iNew%pCache
9360: 2d 3e 6e 48 61 73 68 3b 0a 20 20 70 50 61 67 65  ->nHash;.  pPage
9370: 2d 3e 69 4b 65 79 20 3d 20 69 4e 65 77 3b 0a 20  ->iKey = iNew;. 
9380: 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 20 3d 20   pPage->pNext = 
9390: 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68  pCache->apHash[h
93a0: 5d 3b 0a 20 20 70 43 61 63 68 65 2d 3e 61 70 48  ];.  pCache->apH
93b0: 61 73 68 5b 68 5d 20 3d 20 70 50 61 67 65 3b 0a  ash[h] = pPage;.
93c0: 20 20 69 66 28 20 69 4e 65 77 3e 70 43 61 63 68    if( iNew>pCach
93d0: 65 2d 3e 69 4d 61 78 4b 65 79 20 29 7b 0a 20 20  e->iMaxKey ){.  
93e0: 20 20 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b 65    pCache->iMaxKe
93f0: 79 20 3d 20 69 4e 65 77 3b 0a 20 20 7d 0a 0a 20  y = iNew;.  }.. 
9400: 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74   pcache1LeaveMut
9410: 65 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75  ex(pCache->pGrou
9420: 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70  p);.}../*.** Imp
9430: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74  lementation of t
9440: 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68  he sqlite3_pcach
9450: 65 2e 78 54 72 75 6e 63 61 74 65 20 6d 65 74 68  e.xTruncate meth
9460: 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20 44 69 73 63 61  od. .**.** Disca
9470: 72 64 20 61 6c 6c 20 75 6e 70 69 6e 6e 65 64 20  rd all unpinned 
9480: 70 61 67 65 73 20 69 6e 20 74 68 65 20 63 61 63  pages in the cac
9490: 68 65 20 77 69 74 68 20 61 20 70 61 67 65 20 6e  he with a page n
94a0: 75 6d 62 65 72 20 65 71 75 61 6c 20 74 6f 0a 2a  umber equal to.*
94b0: 2a 20 6f 72 20 67 72 65 61 74 65 72 20 74 68 61  * or greater tha
94c0: 6e 20 70 61 72 61 6d 65 74 65 72 20 69 4c 69 6d  n parameter iLim
94d0: 69 74 2e 20 41 6e 79 20 70 69 6e 6e 65 64 20 70  it. Any pinned p
94e0: 61 67 65 73 20 77 69 74 68 20 61 20 70 61 67 65  ages with a page
94f0: 20 6e 75 6d 62 65 72 0a 2a 2a 20 65 71 75 61 6c   number.** equal
9500: 20 74 6f 20 6f 72 20 67 72 65 61 74 65 72 20 74   to or greater t
9510: 68 61 6e 20 69 4c 69 6d 69 74 20 61 72 65 20 69  han iLimit are i
9520: 6d 70 6c 69 63 69 74 6c 79 20 75 6e 70 69 6e 6e  mplicitly unpinn
9530: 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ed..*/.static vo
9540: 69 64 20 70 63 61 63 68 65 31 54 72 75 6e 63 61  id pcache1Trunca
9550: 74 65 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68  te(sqlite3_pcach
9560: 65 20 2a 70 2c 20 75 6e 73 69 67 6e 65 64 20 69  e *p, unsigned i
9570: 6e 74 20 69 4c 69 6d 69 74 29 7b 0a 20 20 50 43  nt iLimit){.  PC
9580: 61 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20  ache1 *pCache = 
9590: 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20 20  (PCache1 *)p;.  
95a0: 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65  pcache1EnterMute
95b0: 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70  x(pCache->pGroup
95c0: 29 3b 0a 20 20 69 66 28 20 69 4c 69 6d 69 74 3c  );.  if( iLimit<
95d0: 3d 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79  =pCache->iMaxKey
95e0: 20 29 7b 0a 20 20 20 20 70 63 61 63 68 65 31 54   ){.    pcache1T
95f0: 72 75 6e 63 61 74 65 55 6e 73 61 66 65 28 70 43  runcateUnsafe(pC
9600: 61 63 68 65 2c 20 69 4c 69 6d 69 74 29 3b 0a 20  ache, iLimit);. 
9610: 20 20 20 70 43 61 63 68 65 2d 3e 69 4d 61 78 4b     pCache->iMaxK
9620: 65 79 20 3d 20 69 4c 69 6d 69 74 2d 31 3b 0a 20  ey = iLimit-1;. 
9630: 20 7d 0a 20 20 70 63 61 63 68 65 31 4c 65 61 76   }.  pcache1Leav
9640: 65 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e 70  eMutex(pCache->p
9650: 47 72 6f 75 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  Group);.}../*.**
9660: 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20   Implementation 
9670: 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70  of the sqlite3_p
9680: 63 61 63 68 65 2e 78 44 65 73 74 72 6f 79 20 6d  cache.xDestroy m
9690: 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20 44 65  ethod. .**.** De
96a0: 73 74 72 6f 79 20 61 20 63 61 63 68 65 20 61 6c  stroy a cache al
96b0: 6c 6f 63 61 74 65 64 20 75 73 69 6e 67 20 70 63  located using pc
96c0: 61 63 68 65 31 43 72 65 61 74 65 28 29 2e 0a 2a  ache1Create()..*
96d0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63  /.static void pc
96e0: 61 63 68 65 31 44 65 73 74 72 6f 79 28 73 71 6c  ache1Destroy(sql
96f0: 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70 29 7b  ite3_pcache *p){
9700: 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63  .  PCache1 *pCac
9710: 68 65 20 3d 20 28 50 43 61 63 68 65 31 20 2a 29  he = (PCache1 *)
9720: 70 3b 0a 20 20 50 47 72 6f 75 70 20 2a 70 47 72  p;.  PGroup *pGr
9730: 6f 75 70 20 3d 20 70 43 61 63 68 65 2d 3e 70 47  oup = pCache->pG
9740: 72 6f 75 70 3b 0a 20 20 61 73 73 65 72 74 28 20  roup;.  assert( 
9750: 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62  pCache->bPurgeab
9760: 6c 65 20 7c 7c 20 28 70 43 61 63 68 65 2d 3e 6e  le || (pCache->n
9770: 4d 61 78 3d 3d 30 20 26 26 20 70 43 61 63 68 65  Max==0 && pCache
9780: 2d 3e 6e 4d 69 6e 3d 3d 30 29 20 29 3b 0a 20 20  ->nMin==0) );.  
9790: 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65  pcache1EnterMute
97a0: 78 28 70 47 72 6f 75 70 29 3b 0a 20 20 69 66 28  x(pGroup);.  if(
97b0: 20 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 20 29   pCache->nPage )
97c0: 20 70 63 61 63 68 65 31 54 72 75 6e 63 61 74 65   pcache1Truncate
97d0: 55 6e 73 61 66 65 28 70 43 61 63 68 65 2c 20 30  Unsafe(pCache, 0
97e0: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 47 72  );.  assert( pGr
97f0: 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65 20 3e 3d  oup->nMaxPage >=
9800: 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 20 29 3b   pCache->nMax );
9810: 0a 20 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50  .  pGroup->nMaxP
9820: 61 67 65 20 2d 3d 20 70 43 61 63 68 65 2d 3e 6e  age -= pCache->n
9830: 4d 61 78 3b 0a 20 20 61 73 73 65 72 74 28 20 70  Max;.  assert( p
9840: 47 72 6f 75 70 2d 3e 6e 4d 69 6e 50 61 67 65 20  Group->nMinPage 
9850: 3e 3d 20 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 20  >= pCache->nMin 
9860: 29 3b 0a 20 20 70 47 72 6f 75 70 2d 3e 6e 4d 69  );.  pGroup->nMi
9870: 6e 50 61 67 65 20 2d 3d 20 70 43 61 63 68 65 2d  nPage -= pCache-
9880: 3e 6e 4d 69 6e 3b 0a 20 20 70 47 72 6f 75 70 2d  >nMin;.  pGroup-
9890: 3e 6d 78 50 69 6e 6e 65 64 20 3d 20 70 47 72 6f  >mxPinned = pGro
98a0: 75 70 2d 3e 6e 4d 61 78 50 61 67 65 20 2b 20 31  up->nMaxPage + 1
98b0: 30 20 2d 20 70 47 72 6f 75 70 2d 3e 6e 4d 69 6e  0 - pGroup->nMin
98c0: 50 61 67 65 3b 0a 20 20 70 63 61 63 68 65 31 45  Page;.  pcache1E
98d0: 6e 66 6f 72 63 65 4d 61 78 50 61 67 65 28 70 43  nforceMaxPage(pC
98e0: 61 63 68 65 29 3b 0a 20 20 70 63 61 63 68 65 31  ache);.  pcache1
98f0: 4c 65 61 76 65 4d 75 74 65 78 28 70 47 72 6f 75  LeaveMutex(pGrou
9900: 70 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72  p);.  sqlite3_fr
9910: 65 65 28 70 43 61 63 68 65 2d 3e 70 42 75 6c 6b  ee(pCache->pBulk
9920: 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65  );.  sqlite3_fre
9930: 65 28 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68  e(pCache->apHash
9940: 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65  );.  sqlite3_fre
9950: 65 28 70 43 61 63 68 65 29 3b 0a 7d 0a 0a 2f 2a  e(pCache);.}../*
9960: 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
9970: 6e 20 69 73 20 63 61 6c 6c 65 64 20 64 75 72 69  n is called duri
9980: 6e 67 20 69 6e 69 74 69 61 6c 69 7a 61 74 69 6f  ng initializatio
9990: 6e 20 28 73 71 6c 69 74 65 33 5f 69 6e 69 74 69  n (sqlite3_initi
99a0: 61 6c 69 7a 65 28 29 29 20 74 6f 0a 2a 2a 20 69  alize()) to.** i
99b0: 6e 73 74 61 6c 6c 20 74 68 65 20 64 65 66 61 75  nstall the defau
99c0: 6c 74 20 70 6c 75 67 67 61 62 6c 65 20 63 61 63  lt pluggable cac
99d0: 68 65 20 6d 6f 64 75 6c 65 2c 20 61 73 73 75 6d  he module, assum
99e0: 69 6e 67 20 74 68 65 20 75 73 65 72 20 68 61 73  ing the user has
99f0: 20 6e 6f 74 0a 2a 2a 20 61 6c 72 65 61 64 79 20   not.** already 
9a00: 70 72 6f 76 69 64 65 64 20 61 6e 20 61 6c 74 65  provided an alte
9a10: 72 6e 61 74 69 76 65 2e 0a 2a 2f 0a 76 6f 69 64  rnative..*/.void
9a20: 20 73 71 6c 69 74 65 33 50 43 61 63 68 65 53 65   sqlite3PCacheSe
9a30: 74 44 65 66 61 75 6c 74 28 76 6f 69 64 29 7b 0a  tDefault(void){.
9a40: 20 20 73 74 61 74 69 63 20 63 6f 6e 73 74 20 73    static const s
9a50: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 5f 6d 65  qlite3_pcache_me
9a60: 74 68 6f 64 73 32 20 64 65 66 61 75 6c 74 4d 65  thods2 defaultMe
9a70: 74 68 6f 64 73 20 3d 20 7b 0a 20 20 20 20 31 2c  thods = {.    1,
9a80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9a90: 20 20 20 20 20 20 20 2f 2a 20 69 56 65 72 73 69         /* iVersi
9aa0: 6f 6e 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20  on */.    0,    
9ab0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9ac0: 20 20 20 2f 2a 20 70 41 72 67 20 2a 2f 0a 20 20     /* pArg */.  
9ad0: 20 20 70 63 61 63 68 65 31 49 6e 69 74 2c 20 20    pcache1Init,  
9ae0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 49             /* xI
9af0: 6e 69 74 20 2a 2f 0a 20 20 20 20 70 63 61 63 68  nit */.    pcach
9b00: 65 31 53 68 75 74 64 6f 77 6e 2c 20 20 20 20 20  e1Shutdown,     
9b10: 20 20 20 20 2f 2a 20 78 53 68 75 74 64 6f 77 6e      /* xShutdown
9b20: 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31 43   */.    pcache1C
9b30: 72 65 61 74 65 2c 20 20 20 20 20 20 20 20 20 20  reate,          
9b40: 20 2f 2a 20 78 43 72 65 61 74 65 20 2a 2f 0a 20   /* xCreate */. 
9b50: 20 20 20 70 63 61 63 68 65 31 43 61 63 68 65 73     pcache1Caches
9b60: 69 7a 65 2c 20 20 20 20 20 20 20 20 2f 2a 20 78  ize,        /* x
9b70: 43 61 63 68 65 73 69 7a 65 20 2a 2f 0a 20 20 20  Cachesize */.   
9b80: 20 70 63 61 63 68 65 31 50 61 67 65 63 6f 75 6e   pcache1Pagecoun
9b90: 74 2c 20 20 20 20 20 20 20 20 2f 2a 20 78 50 61  t,        /* xPa
9ba0: 67 65 63 6f 75 6e 74 20 2a 2f 0a 20 20 20 20 70  gecount */.    p
9bb0: 63 61 63 68 65 31 46 65 74 63 68 2c 20 20 20 20  cache1Fetch,    
9bc0: 20 20 20 20 20 20 20 20 2f 2a 20 78 46 65 74 63          /* xFetc
9bd0: 68 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31  h */.    pcache1
9be0: 55 6e 70 69 6e 2c 20 20 20 20 20 20 20 20 20 20  Unpin,          
9bf0: 20 20 2f 2a 20 78 55 6e 70 69 6e 20 2a 2f 0a 20    /* xUnpin */. 
9c00: 20 20 20 70 63 61 63 68 65 31 52 65 6b 65 79 2c     pcache1Rekey,
9c10: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
9c20: 52 65 6b 65 79 20 2a 2f 0a 20 20 20 20 70 63 61  Rekey */.    pca
9c30: 63 68 65 31 54 72 75 6e 63 61 74 65 2c 20 20 20  che1Truncate,   
9c40: 20 20 20 20 20 20 2f 2a 20 78 54 72 75 6e 63 61        /* xTrunca
9c50: 74 65 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65  te */.    pcache
9c60: 31 44 65 73 74 72 6f 79 2c 20 20 20 20 20 20 20  1Destroy,       
9c70: 20 20 20 2f 2a 20 78 44 65 73 74 72 6f 79 20 2a     /* xDestroy *
9c80: 2f 0a 20 20 20 20 70 63 61 63 68 65 31 53 68 72  /.    pcache1Shr
9c90: 69 6e 6b 20 20 20 20 20 20 20 20 20 20 20 20 2f  ink            /
9ca0: 2a 20 78 53 68 72 69 6e 6b 20 2a 2f 0a 20 20 7d  * xShrink */.  }
9cb0: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66  ;.  sqlite3_conf
9cc0: 69 67 28 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47  ig(SQLITE_CONFIG
9cd0: 5f 50 43 41 43 48 45 32 2c 20 26 64 65 66 61 75  _PCACHE2, &defau
9ce0: 6c 74 4d 65 74 68 6f 64 73 29 3b 0a 7d 0a 0a 2f  ltMethods);.}../
9cf0: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20  *.** Return the 
9d00: 73 69 7a 65 20 6f 66 20 74 68 65 20 68 65 61 64  size of the head
9d10: 65 72 20 6f 6e 20 65 61 63 68 20 70 61 67 65 20  er on each page 
9d20: 6f 66 20 74 68 69 73 20 50 43 41 43 48 45 20 69  of this PCACHE i
9d30: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 2e 0a 2a  mplementation..*
9d40: 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 48 65 61  /.int sqlite3Hea
9d50: 64 65 72 53 69 7a 65 50 63 61 63 68 65 31 28 76  derSizePcache1(v
9d60: 6f 69 64 29 7b 20 72 65 74 75 72 6e 20 52 4f 55  oid){ return ROU
9d70: 4e 44 38 28 73 69 7a 65 6f 66 28 50 67 48 64 72  ND8(sizeof(PgHdr
9d80: 31 29 29 3b 20 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65  1)); }../*.** Re
9d90: 74 75 72 6e 20 74 68 65 20 67 6c 6f 62 61 6c 20  turn the global 
9da0: 6d 75 74 65 78 20 75 73 65 64 20 62 79 20 74 68  mutex used by th
9db0: 69 73 20 50 43 41 43 48 45 20 69 6d 70 6c 65 6d  is PCACHE implem
9dc0: 65 6e 74 61 74 69 6f 6e 2e 20 20 54 68 65 0a 2a  entation.  The.*
9dd0: 2a 20 73 71 6c 69 74 65 33 5f 73 74 61 74 75 73  * sqlite3_status
9de0: 28 29 20 72 6f 75 74 69 6e 65 20 6e 65 65 64 73  () routine needs
9df0: 20 61 63 63 65 73 73 20 74 6f 20 74 68 69 73 20   access to this 
9e00: 6d 75 74 65 78 2e 0a 2a 2f 0a 73 71 6c 69 74 65  mutex..*/.sqlite
9e10: 33 5f 6d 75 74 65 78 20 2a 73 71 6c 69 74 65 33  3_mutex *sqlite3
9e20: 50 63 61 63 68 65 31 4d 75 74 65 78 28 76 6f 69  Pcache1Mutex(voi
9e30: 64 29 7b 0a 20 20 72 65 74 75 72 6e 20 70 63 61  d){.  return pca
9e40: 63 68 65 31 2e 6d 75 74 65 78 3b 0a 7d 0a 0a 23  che1.mutex;.}..#
9e50: 69 66 64 65 66 20 53 51 4c 49 54 45 5f 45 4e 41  ifdef SQLITE_ENA
9e60: 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47  BLE_MEMORY_MANAG
9e70: 45 4d 45 4e 54 0a 2f 2a 0a 2a 2a 20 54 68 69 73  EMENT./*.** This
9e80: 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c   function is cal
9e90: 6c 65 64 20 74 6f 20 66 72 65 65 20 73 75 70 65  led to free supe
9ea0: 72 66 6c 75 6f 75 73 20 64 79 6e 61 6d 69 63 61  rfluous dynamica
9eb0: 6c 6c 79 20 61 6c 6c 6f 63 61 74 65 64 20 6d 65  lly allocated me
9ec0: 6d 6f 72 79 0a 2a 2a 20 68 65 6c 64 20 62 79 20  mory.** held by 
9ed0: 74 68 65 20 70 61 67 65 72 20 73 79 73 74 65 6d  the pager system
9ee0: 2e 20 4d 65 6d 6f 72 79 20 69 6e 20 75 73 65 20  . Memory in use 
9ef0: 62 79 20 61 6e 79 20 53 51 4c 69 74 65 20 70 61  by any SQLite pa
9f00: 67 65 72 20 61 6c 6c 6f 63 61 74 65 64 0a 2a 2a  ger allocated.**
9f10: 20 62 79 20 74 68 65 20 63 75 72 72 65 6e 74 20   by the current 
9f20: 74 68 72 65 61 64 20 6d 61 79 20 62 65 20 73 71  thread may be sq
9f30: 6c 69 74 65 33 5f 66 72 65 65 28 29 65 64 2e 0a  lite3_free()ed..
9f40: 2a 2a 0a 2a 2a 20 6e 52 65 71 20 69 73 20 74 68  **.** nReq is th
9f50: 65 20 6e 75 6d 62 65 72 20 6f 66 20 62 79 74 65  e number of byte
9f60: 73 20 6f 66 20 6d 65 6d 6f 72 79 20 72 65 71 75  s of memory requ
9f70: 69 72 65 64 2e 20 4f 6e 63 65 20 74 68 69 73 20  ired. Once this 
9f80: 6d 75 63 68 20 68 61 73 0a 2a 2a 20 62 65 65 6e  much has.** been
9f90: 20 72 65 6c 65 61 73 65 64 2c 20 74 68 65 20 66   released, the f
9fa0: 75 6e 63 74 69 6f 6e 20 72 65 74 75 72 6e 73 2e  unction returns.
9fb0: 20 54 68 65 20 72 65 74 75 72 6e 20 76 61 6c 75   The return valu
9fc0: 65 20 69 73 20 74 68 65 20 74 6f 74 61 6c 20 6e  e is the total n
9fd0: 75 6d 62 65 72 20 0a 2a 2a 20 6f 66 20 62 79 74  umber .** of byt
9fe0: 65 73 20 6f 66 20 6d 65 6d 6f 72 79 20 72 65 6c  es of memory rel
9ff0: 65 61 73 65 64 2e 0a 2a 2f 0a 69 6e 74 20 73 71  eased..*/.int sq
a000: 6c 69 74 65 33 50 63 61 63 68 65 52 65 6c 65 61  lite3PcacheRelea
a010: 73 65 4d 65 6d 6f 72 79 28 69 6e 74 20 6e 52 65  seMemory(int nRe
a020: 71 29 7b 0a 20 20 69 6e 74 20 6e 46 72 65 65 20  q){.  int nFree 
a030: 3d 20 30 3b 0a 20 20 61 73 73 65 72 74 28 20 73  = 0;.  assert( s
a040: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6e 6f 74  qlite3_mutex_not
a050: 68 65 6c 64 28 70 63 61 63 68 65 31 2e 67 72 70  held(pcache1.grp
a060: 2e 6d 75 74 65 78 29 20 29 3b 0a 20 20 61 73 73  .mutex) );.  ass
a070: 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75 74  ert( sqlite3_mut
a080: 65 78 5f 6e 6f 74 68 65 6c 64 28 70 63 61 63 68  ex_notheld(pcach
a090: 65 31 2e 6d 75 74 65 78 29 20 29 3b 0a 20 20 69  e1.mutex) );.  i
a0a0: 66 28 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c  f( sqlite3Global
a0b0: 43 6f 6e 66 69 67 2e 70 50 61 67 65 3d 3d 30 20  Config.pPage==0 
a0c0: 29 7b 0a 20 20 20 20 50 67 48 64 72 31 20 2a 70  ){.    PgHdr1 *p
a0d0: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 45 6e 74  ;.    pcache1Ent
a0e0: 65 72 4d 75 74 65 78 28 26 70 63 61 63 68 65 31  erMutex(&pcache1
a0f0: 2e 67 72 70 29 3b 0a 20 20 20 20 77 68 69 6c 65  .grp);.    while
a100: 28 20 28 6e 52 65 71 3c 30 20 7c 7c 20 6e 46 72  ( (nReq<0 || nFr
a110: 65 65 3c 6e 52 65 71 29 0a 20 20 20 20 20 20 20  ee<nReq).       
a120: 26 26 20 20 28 70 3d 70 63 61 63 68 65 31 2e 67  &&  (p=pcache1.g
a130: 72 70 2e 6c 72 75 2e 70 4c 72 75 50 72 65 76 29  rp.lru.pLruPrev)
a140: 21 3d 30 0a 20 20 20 20 20 20 20 26 26 20 20 70  !=0.       &&  p
a150: 2d 3e 69 73 41 6e 63 68 6f 72 3d 3d 30 0a 20 20  ->isAnchor==0.  
a160: 20 20 29 7b 0a 20 20 20 20 20 20 6e 46 72 65 65    ){.      nFree
a170: 20 2b 3d 20 70 63 61 63 68 65 31 4d 65 6d 53 69   += pcache1MemSi
a180: 7a 65 28 70 2d 3e 70 61 67 65 2e 70 42 75 66 29  ze(p->page.pBuf)
a190: 3b 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f  ;.#ifdef SQLITE_
a1a0: 50 43 41 43 48 45 5f 53 45 50 41 52 41 54 45 5f  PCACHE_SEPARATE_
a1b0: 48 45 41 44 45 52 0a 20 20 20 20 20 20 6e 46 72  HEADER.      nFr
a1c0: 65 65 20 2b 3d 20 73 71 6c 69 74 65 33 4d 65 6d  ee += sqlite3Mem
a1d0: 53 69 7a 65 28 70 29 3b 0a 23 65 6e 64 69 66 0a  Size(p);.#endif.
a1e0: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 50 41        assert( PA
a1f0: 47 45 5f 49 53 5f 55 4e 50 49 4e 4e 45 44 28 70  GE_IS_UNPINNED(p
a200: 29 20 29 3b 0a 20 20 20 20 20 20 70 63 61 63 68  ) );.      pcach
a210: 65 31 50 69 6e 50 61 67 65 28 70 29 3b 0a 20 20  e1PinPage(p);.  
a220: 20 20 20 20 70 63 61 63 68 65 31 52 65 6d 6f 76      pcache1Remov
a230: 65 46 72 6f 6d 48 61 73 68 28 70 2c 20 31 29 3b  eFromHash(p, 1);
a240: 0a 20 20 20 20 7d 0a 20 20 20 20 70 63 61 63 68  .    }.    pcach
a250: 65 31 4c 65 61 76 65 4d 75 74 65 78 28 26 70 63  e1LeaveMutex(&pc
a260: 61 63 68 65 31 2e 67 72 70 29 3b 0a 20 20 7d 0a  ache1.grp);.  }.
a270: 20 20 72 65 74 75 72 6e 20 6e 46 72 65 65 3b 0a    return nFree;.
a280: 7d 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49  }.#endif /* SQLI
a290: 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59  TE_ENABLE_MEMORY
a2a0: 5f 4d 41 4e 41 47 45 4d 45 4e 54 20 2a 2f 0a 0a  _MANAGEMENT */..
a2b0: 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 54 45  #ifdef SQLITE_TE
a2c0: 53 54 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75  ST./*.** This fu
a2d0: 6e 63 74 69 6f 6e 20 69 73 20 75 73 65 64 20 62  nction is used b
a2e0: 79 20 74 65 73 74 20 70 72 6f 63 65 64 75 72 65  y test procedure
a2f0: 73 20 74 6f 20 69 6e 73 70 65 63 74 20 74 68 65  s to inspect the
a300: 20 69 6e 74 65 72 6e 61 6c 20 73 74 61 74 65 0a   internal state.
a310: 2a 2a 20 6f 66 20 74 68 65 20 67 6c 6f 62 61 6c  ** of the global
a320: 20 63 61 63 68 65 2e 0a 2a 2f 0a 76 6f 69 64 20   cache..*/.void 
a330: 73 71 6c 69 74 65 33 50 63 61 63 68 65 53 74 61  sqlite3PcacheSta
a340: 74 73 28 0a 20 20 69 6e 74 20 2a 70 6e 43 75 72  ts(.  int *pnCur
a350: 72 65 6e 74 2c 20 20 20 20 20 20 2f 2a 20 4f 55  rent,      /* OU
a360: 54 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20  T: Total number 
a370: 6f 66 20 70 61 67 65 73 20 63 61 63 68 65 64 20  of pages cached 
a380: 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 4d 61 78 2c  */.  int *pnMax,
a390: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
a3a0: 3a 20 47 6c 6f 62 61 6c 20 6d 61 78 69 6d 75 6d  : Global maximum
a3b0: 20 63 61 63 68 65 20 73 69 7a 65 20 2a 2f 0a 20   cache size */. 
a3c0: 20 69 6e 74 20 2a 70 6e 4d 69 6e 2c 20 20 20 20   int *pnMin,    
a3d0: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 53 75        /* OUT: Su
a3e0: 6d 20 6f 66 20 50 43 61 63 68 65 31 2e 6e 4d 69  m of PCache1.nMi
a3f0: 6e 20 66 6f 72 20 70 75 72 67 65 61 62 6c 65 20  n for purgeable 
a400: 63 61 63 68 65 73 20 2a 2f 0a 20 20 69 6e 74 20  caches */.  int 
a410: 2a 70 6e 52 65 63 79 63 6c 61 62 6c 65 20 20 20  *pnRecyclable   
a420: 20 2f 2a 20 4f 55 54 3a 20 54 6f 74 61 6c 20 6e   /* OUT: Total n
a430: 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 61  umber of pages a
a440: 76 61 69 6c 61 62 6c 65 20 66 6f 72 20 72 65 63  vailable for rec
a450: 79 63 6c 69 6e 67 20 2a 2f 0a 29 7b 0a 20 20 50  ycling */.){.  P
a460: 67 48 64 72 31 20 2a 70 3b 0a 20 20 69 6e 74 20  gHdr1 *p;.  int 
a470: 6e 52 65 63 79 63 6c 61 62 6c 65 20 3d 20 30 3b  nRecyclable = 0;
a480: 0a 20 20 66 6f 72 28 70 3d 70 63 61 63 68 65 31  .  for(p=pcache1
a490: 2e 67 72 70 2e 6c 72 75 2e 70 4c 72 75 4e 65 78  .grp.lru.pLruNex
a4a0: 74 3b 20 70 20 26 26 20 21 70 2d 3e 69 73 41 6e  t; p && !p->isAn
a4b0: 63 68 6f 72 3b 20 70 3d 70 2d 3e 70 4c 72 75 4e  chor; p=p->pLruN
a4c0: 65 78 74 29 7b 0a 20 20 20 20 61 73 73 65 72 74  ext){.    assert
a4d0: 28 20 50 41 47 45 5f 49 53 5f 55 4e 50 49 4e 4e  ( PAGE_IS_UNPINN
a4e0: 45 44 28 70 29 20 29 3b 0a 20 20 20 20 6e 52 65  ED(p) );.    nRe
a4f0: 63 79 63 6c 61 62 6c 65 2b 2b 3b 0a 20 20 7d 0a  cyclable++;.  }.
a500: 20 20 2a 70 6e 43 75 72 72 65 6e 74 20 3d 20 70    *pnCurrent = p
a510: 63 61 63 68 65 31 2e 67 72 70 2e 6e 50 75 72 67  cache1.grp.nPurg
a520: 65 61 62 6c 65 3b 0a 20 20 2a 70 6e 4d 61 78 20  eable;.  *pnMax 
a530: 3d 20 28 69 6e 74 29 70 63 61 63 68 65 31 2e 67  = (int)pcache1.g
a540: 72 70 2e 6e 4d 61 78 50 61 67 65 3b 0a 20 20 2a  rp.nMaxPage;.  *
a550: 70 6e 4d 69 6e 20 3d 20 28 69 6e 74 29 70 63 61  pnMin = (int)pca
a560: 63 68 65 31 2e 67 72 70 2e 6e 4d 69 6e 50 61 67  che1.grp.nMinPag
a570: 65 3b 0a 20 20 2a 70 6e 52 65 63 79 63 6c 61 62  e;.  *pnRecyclab
a580: 6c 65 20 3d 20 6e 52 65 63 79 63 6c 61 62 6c 65  le = nRecyclable
a590: 3b 0a 7d 0a 23 65 6e 64 69 66 0a                 ;.}.#endif.